evOo-local/apps/web/vite.config.ts.bak-before-pr7
Ingo Wagner a570e9e71b feat: complete onboarding redesign + major file splits
Onboarding: emoji-first flow with shape/color selection, user preferences,
language setup (9 locales), and bot creation with avatarValue persistence.

executor.ts: split 4928→4159 lines into 8 modules (completion, computer,
effects, model, utils, tools, attachments, types).

pi-runtime.ts: split 1726→561 lines into 2 modules (model-config, tool-utils).

E2E: new onboarding-emoji-first tests + updated completeOnboarding helper.
2026-09-21 22:52:04 +00:00

297 lines
10 KiB
Plaintext

import { timingSafeEqual } from "node:crypto";
import type { ClientRequest, IncomingMessage } from "node:http";
import http from "node:http";
import https from "node:https";
import net from "node:net";
import path from "node:path";
import tls from "node:tls";
import { lingui } from "@lingui/vite-plugin";
import type { DesktopStackProbeResponse } from "@rakazo/contracts";
import {
safeScreenProxyResponseHeaders,
stripSensitiveHandshakeHeaders,
} from "@rakazo/core/node/screen-proxy-response";
import babel from "@rolldown/plugin-babel";
import tailwindcss from "@tailwindcss/vite";
import react from "@vitejs/plugin-react";
import type { PreviewServer, ViteDevServer } from "vite";
import { defineConfig, loadEnv } from "vite";
import { resolveScreenProxySecret } from "../../packages/core/src/secrets-guard.ts";
import {
resolveNovncTarget,
safeProxyHeaders,
watchScreenAuthorization,
} from "./src/screen-proxy.js";
const webPort = Number(process.env.WEB_PORT ?? 5173);
const DESKTOP_STACK_PROBE_PATH = "/.well-known/rakazo-desktop-stack";
const DESKTOP_STACK_TOKEN_HEADER = "x-rakazo-desktop-stack-token";
function equalStackToken(expected: string, supplied: string | string[] | undefined) {
if (expected === "" || typeof supplied !== "string") return false;
const expectedBytes = Buffer.from(expected);
const suppliedBytes = Buffer.from(supplied);
return (
expectedBytes.byteLength === suppliedBytes.byteLength &&
timingSafeEqual(expectedBytes, suppliedBytes)
);
}
function attachDesktopStackProbe(
server: ViteDevServer | PreviewServer,
token: string,
imageTag: string,
) {
server.middlewares.use((req, res, next) => {
if (req.url?.split("?", 1)[0] !== DESKTOP_STACK_PROBE_PATH) {
next();
return;
}
if (!equalStackToken(token, req.headers[DESKTOP_STACK_TOKEN_HEADER])) {
res.statusCode = 404;
res.end("Not found");
return;
}
const body: DesktopStackProbeResponse = { ok: true, imageTag };
res.statusCode = 200;
res.setHeader("cache-control", "no-store");
res.setHeader("content-type", "application/json; charset=utf-8");
res.end(JSON.stringify(body));
});
}
function attachNovncProxy(server: ViteDevServer | PreviewServer, secret: string, api: string) {
server.middlewares.use(async (req, res, next) => {
if (!req.url?.startsWith("/novnc/")) {
next();
return;
}
const target = await resolveNovncTarget(req.url, secret, api);
if (res.destroyed) return;
if (!target) {
res.statusCode = 403;
res.end("Invalid or expired screen capability");
return;
}
const headers = {
...safeProxyHeaders(req.headers),
host: `${target.hostname}:${target.port}`,
};
const transport = target.protocol === "https:" ? https : http;
let upstream: ClientRequest | undefined;
let retries = 0;
let retryPending = false;
let stopChecking: () => void = () => undefined;
const retryable = req.method === "GET";
const scheduleRetry = (incoming?: IncomingMessage) => {
if (!retryable || retryPending || retries >= 3 || res.destroyed) return false;
retryPending = true;
retries += 1;
const delayMs = 50 * retries;
const retry = () => {
setTimeout(() => {
retryPending = false;
if (!res.destroyed) requestUpstream();
}, delayMs);
};
if (incoming && !incoming.destroyed) {
incoming.once("close", retry);
incoming.destroy();
} else {
retry();
}
return true;
};
function requestUpstream() {
if (res.destroyed) return;
upstream = transport.request(
{
hostname: target.hostname,
port: target.port,
path: target.path,
method: req.method,
headers,
...(target.protocol === "https:" ? { servername: target.hostname } : {}),
},
(incoming) => {
if ((incoming.statusCode ?? 502) >= 500 && scheduleRetry(incoming)) {
return;
}
res.writeHead(
incoming.statusCode ?? 502,
safeScreenProxyResponseHeaders(incoming.headers),
);
incoming.pipe(res);
},
);
upstream.on("error", () => {
if (retryable && !res.headersSent && !res.destroyed && (retryPending || scheduleRetry())) {
return;
}
stopChecking();
if (res.headersSent) {
res.destroy();
return;
}
res.statusCode = 502;
res.end("Screen unavailable");
});
if (req.method === "GET" || req.readableEnded) upstream.end();
else req.pipe(upstream);
}
stopChecking = watchScreenAuthorization(
async () => Boolean(await resolveNovncTarget(req.url, secret, api)),
() => {
upstream?.destroy();
res.destroy();
},
);
res.once("close", () => {
stopChecking();
upstream?.destroy();
});
requestUpstream();
});
server.httpServer?.on("upgrade", async (req, socket, head) => {
if (!req.url?.startsWith("/novnc/")) return;
const target = await resolveNovncTarget(req.url, secret, api);
if (socket.destroyed) return;
if (!target) {
socket.destroy();
return;
}
const upstream =
target.protocol === "https:"
? tls.connect({ port: target.port, host: target.hostname, servername: target.hostname })
: net.connect(target.port, target.hostname);
const stopChecking = watchScreenAuthorization(
async () => Boolean(await resolveNovncTarget(req.url, secret, api)),
() => {
socket.destroy();
upstream.destroy();
},
);
socket.once("close", () => {
stopChecking();
upstream.destroy();
});
upstream.once("close", () => {
stopChecking();
socket.destroy();
});
upstream.once(target.protocol === "https:" ? "secureConnect" : "connect", () => {
const headerLines = [
`${req.method ?? "GET"} ${target.path} HTTP/1.1`,
`Host: ${target.hostname}:${target.port}`,
];
for (const [key, value] of Object.entries(safeProxyHeaders(req.headers))) {
headerLines.push(`${key}: ${Array.isArray(value) ? value.join(",") : value}`);
}
upstream.write(`${headerLines.join("\r\n")}\r\n\r\n`);
if (head.length) upstream.write(head);
socket.pipe(upstream);
const responseChunks: Buffer[] = [];
let responseSize = 0;
let responseTail = Buffer.alloc(0);
const forwardHandshake = (chunk: Buffer) => {
responseChunks.push(chunk);
responseSize += chunk.length;
if (responseSize > 64 * 1024) {
socket.destroy();
upstream.destroy();
return;
}
const boundarySearch = Buffer.concat([responseTail, chunk]);
if (boundarySearch.indexOf("\r\n\r\n") < 0) {
responseTail = Buffer.from(boundarySearch.subarray(-3));
return;
}
const responseHead = Buffer.concat(responseChunks, responseSize);
const safe = stripSensitiveHandshakeHeaders(responseHead);
if (!safe) {
socket.destroy();
upstream.destroy();
return;
}
upstream.off("data", forwardHandshake);
socket.write(safe);
upstream.pipe(socket);
};
upstream.on("data", forwardHandshake);
});
upstream.on("error", () => socket.destroy());
socket.on("error", () => upstream.destroy());
});
}
export default defineConfig(({ mode }) => {
const rootEnv = loadEnv(mode, path.resolve(import.meta.dirname, "../.."), "");
const api = process.env.API_PROXY_TARGET ?? rootEnv.API_PROXY_TARGET ?? "http://127.0.0.1:3100";
const previewHost = process.env.RAKAZO_HOST ?? rootEnv.RAKAZO_HOST ?? "localhost";
const screenProxySecret = () =>
resolveScreenProxySecret({
...process.env,
SCREEN_PROXY_SECRET: process.env.SCREEN_PROXY_SECRET ?? rootEnv.SCREEN_PROXY_SECRET,
SANDBOX_SUPERVISOR_TOKEN:
process.env.SANDBOX_SUPERVISOR_TOKEN ?? rootEnv.SANDBOX_SUPERVISOR_TOKEN,
BETTER_AUTH_SECRET: process.env.BETTER_AUTH_SECRET ?? rootEnv.BETTER_AUTH_SECRET,
});
const performanceAssetDelayMs = Number(process.env.RAKAZO_PERFORMANCE_ASSET_DELAY_MS ?? 0);
const desktopStackToken =
process.env.RAKAZO_DESKTOP_STACK_TOKEN ?? rootEnv.RAKAZO_DESKTOP_STACK_TOKEN ?? "";
const imageTag = process.env.RAKAZO_IMAGE_TAG ?? rootEnv.RAKAZO_IMAGE_TAG ?? "edge";
return {
plugins: [
react(),
babel({ plugins: ["@lingui/babel-plugin-lingui-macro"] }),
lingui(),
tailwindcss(),
{
name: "rakazo-desktop-stack-probe",
configureServer: (server) => attachDesktopStackProbe(server, desktopStackToken, imageTag),
configurePreviewServer: (server) =>
attachDesktopStackProbe(server, desktopStackToken, imageTag),
},
{
name: "rakazo-performance-asset-delay",
configurePreviewServer(server) {
if (!Number.isFinite(performanceAssetDelayMs) || performanceAssetDelayMs <= 0) return;
server.middlewares.use((req, _res, next) => {
const pathname = req.url?.split("?", 1)[0] ?? "/";
if (["/api", "/rpc", "/novnc"].some((prefix) => pathname.startsWith(prefix))) {
next();
return;
}
setTimeout(next, performanceAssetDelayMs);
});
},
},
{
name: "rakazo-novnc-proxy",
configureServer: (server) => attachNovncProxy(server, screenProxySecret(), api),
configurePreviewServer: (server) => attachNovncProxy(server, screenProxySecret(), api),
},
],
server: {
host: "0.0.0.0",
port: webPort,
strictPort: true,
allowedHosts: true,
proxy: {
"/api": { target: api, changeOrigin: true },
"/rpc": { target: api, changeOrigin: true },
},
},
preview: {
host: "0.0.0.0",
port: Number(process.env.WEB_PORT ?? 5173),
allowedHosts: [previewHost],
proxy: {
"/api": { target: api, changeOrigin: true },
"/rpc": { target: api, changeOrigin: true },
},
},
};
});