Skip to content

Commit ce52c6d

Browse files
committed
wire embedded web UI back into CLI for compiled binaries
1 parent 756a904 commit ce52c6d

2 files changed

Lines changed: 35 additions & 3 deletions

File tree

‎apps/cli/src/main.ts‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ import * as Cause from "effect/Cause";
3030
import { ExecutorApi } from "@executor/api";
3131
import { startServer, runMcpStdioServer, getExecutor } from "@executor/local";
3232

33+
// Embedded web UI — baked into compiled binaries via `with { type: "file" }`
34+
import embeddedWebUI from "./embedded-web-ui.gen";
35+
3336
// ---------------------------------------------------------------------------
3437
// Constants
3538
// ---------------------------------------------------------------------------
@@ -115,7 +118,9 @@ const makeApiClient = (baseUrl: string) =>
115118

116119
const runForegroundSession = (input: { port: number }) =>
117120
Effect.gen(function* () {
118-
const server = yield* Effect.promise(() => startServer({ port: input.port }));
121+
const server = yield* Effect.promise(() =>
122+
startServer({ port: input.port, embeddedWebUI }),
123+
);
119124

120125
const baseUrl = `http://localhost:${server.port}`;
121126
console.log(`Executor is ready.`);

‎apps/local/src/serve.ts‎

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,30 @@ function collectStaticRoutes(dir: string, prefix = ""): Record<string, ReturnTyp
4444
return routes;
4545
}
4646

47+
/**
48+
* Convert an embedded web UI map (path → bunfs path) into Bun.serve routes.
49+
* The embedded map is generated by the CLI build step using `with { type: "file" }`.
50+
*/
51+
function embeddedToStaticRoutes(
52+
embedded: Record<string, string>,
53+
): Record<string, ReturnType<typeof Bun.file>> {
54+
const routes: Record<string, ReturnType<typeof Bun.file>> = {};
55+
for (const [key, bunfsPath] of Object.entries(embedded)) {
56+
routes[`/${key}`] = Bun.file(bunfsPath);
57+
}
58+
return routes;
59+
}
60+
4761
// ---------------------------------------------------------------------------
4862
// Server
4963
// ---------------------------------------------------------------------------
5064

5165
export interface StartServerOptions {
5266
port?: number;
67+
/** Directory containing built client assets (for dev/disk serving). */
5368
clientDir?: string;
69+
/** Embedded web UI map from compiled binary (path → bunfs path). Overrides clientDir. */
70+
embeddedWebUI?: Record<string, string> | null;
5471
}
5572

5673
export interface ServerInstance {
@@ -63,8 +80,18 @@ export async function startServer(opts: StartServerOptions = {}): Promise<Server
6380
const clientDir = opts.clientDir ?? resolve(import.meta.dirname, "../dist");
6481

6582
const handlers = await getServerHandlers();
66-
const staticRoutes = collectStaticRoutes(clientDir);
67-
const indexHtml = Bun.file(join(clientDir, "index.html"));
83+
84+
// Build static routes from either embedded assets or disk
85+
let staticRoutes: Record<string, ReturnType<typeof Bun.file>>;
86+
let indexHtml: ReturnType<typeof Bun.file>;
87+
88+
if (opts.embeddedWebUI) {
89+
staticRoutes = embeddedToStaticRoutes(opts.embeddedWebUI);
90+
indexHtml = staticRoutes["/index.html"] ?? Bun.file(join(clientDir, "index.html"));
91+
} else {
92+
staticRoutes = collectStaticRoutes(clientDir);
93+
indexHtml = Bun.file(join(clientDir, "index.html"));
94+
}
6895

6996
const server = Bun.serve({
7097
port,

0 commit comments

Comments
 (0)