Serve the web client from the daemon (#1635)

* Serve the web client from the daemon

Keep the bundled browser UI opt-in and exclude it from desktop packaging so desktop builds do not ship a duplicate renderer.

* Escape daemon web UI bootstrap hint

* Fix bundled web UI dist path
This commit is contained in:
Mohamed Boudra
2026-06-26 12:00:11 +08:00
committed by GitHub
parent 3d6b4adc68
commit 4e2c06ec71
24 changed files with 1302 additions and 6 deletions
@@ -11,7 +11,9 @@ import { useSessionStore, type Agent } from "@/stores/session-store";
import {
HostRuntimeController,
HostRuntimeStore,
readInitialDaemonConnectionHint,
type HostRuntimeControllerDeps,
type HostRuntimeStorage,
} from "./host-runtime";
class FakeDaemonClient {
@@ -122,6 +124,8 @@ class FakeDaemonClient {
afterEach(() => {
vi.useRealTimers();
delete (globalThis as Record<string, unknown>).__PASEO_INITIAL_DAEMON_CONNECTION__;
delete (globalThis as { window?: unknown }).window;
});
function useHostRuntimeClock(): void {
@@ -312,6 +316,32 @@ function makeConnectedProbeClient(latencyMs: number): FakeDaemonClient {
return client;
}
function createMemoryHostRuntimeStorage(entries: Record<string, string> = {}): HostRuntimeStorage {
const values = new Map(Object.entries(entries));
return {
getItem: async (key) => values.get(key) ?? null,
setItem: async (key, value) => {
values.set(key, value);
},
};
}
function onceHostListMatches(store: HostRuntimeStore, predicate: () => boolean): Promise<void> {
if (predicate()) {
return Promise.resolve();
}
return new Promise((resolve) => {
let unsubscribe = (): void => {};
unsubscribe = store.subscribeHostList(() => {
if (!predicate()) {
return;
}
unsubscribe();
resolve();
});
});
}
describe("HostRuntimeController", () => {
it("replaces the active relay client when re-pairing changes the daemon public key", async () => {
const oldRelay: HostConnection = {
@@ -1885,3 +1915,111 @@ describe("HostRuntimeStore", () => {
store.syncHosts([]);
});
});
describe("readInitialDaemonConnectionHint", () => {
it("returns null when no hint is present", () => {
expect(readInitialDaemonConnectionHint({ isWebRuntime: true })).toBeNull();
});
it("parses a valid listen-only hint", () => {
(globalThis as Record<string, unknown>).__PASEO_INITIAL_DAEMON_CONNECTION__ = {
listen: "localhost:6767",
};
expect(readInitialDaemonConnectionHint({ isWebRuntime: true })).toEqual({
listen: "localhost:6767",
useTls: false,
});
});
it("preserves useTls when explicitly true", () => {
(globalThis as Record<string, unknown>).__PASEO_INITIAL_DAEMON_CONNECTION__ = {
listen: "paseo.example.com:443",
useTls: true,
};
expect(readInitialDaemonConnectionHint({ isWebRuntime: true })).toEqual({
listen: "paseo.example.com:443",
useTls: true,
});
});
it("ignores invalid shapes", () => {
(globalThis as Record<string, unknown>).__PASEO_INITIAL_DAEMON_CONNECTION__ = "localhost:6767";
expect(readInitialDaemonConnectionHint({ isWebRuntime: true })).toBeNull();
(globalThis as Record<string, unknown>).__PASEO_INITIAL_DAEMON_CONNECTION__ = {
useTls: true,
};
expect(readInitialDaemonConnectionHint({ isWebRuntime: true })).toBeNull();
});
});
describe("HostRuntimeStore initial connection hint bootstrap", () => {
it("attempts the explicit initial connection hint before default localhost bootstrap", async () => {
const seenProbes: { endpoint: string; useTls?: boolean }[] = [];
const store = new HostRuntimeStore({
deps: {
createClient: () => new FakeDaemonClient() as unknown as DaemonClient,
connectToDaemon: async ({ connection }) => {
if (connection.type === "directTcp") {
seenProbes.push({ endpoint: connection.endpoint, useTls: connection.useTls });
}
return {
client: makeConnectedProbeClient(5) as unknown as DaemonClient,
serverId: "srv_hint",
hostname: "hint host",
};
},
getClientId: async () => "cid_test_runtime",
readInitialConnectionHint: () => ({
listen: "daemon-origin:6767",
useTls: true,
}),
},
storage: createMemoryHostRuntimeStorage(),
});
const hostAdded = onceHostListMatches(store, () => store.getHosts().length > 0);
store.boot();
await hostAdded;
expect(seenProbes).toContainEqual({ endpoint: "daemon-origin:6767", useTls: true });
const host = store.getHosts()[0];
expect(host?.serverId).toBe("srv_hint");
expect(host?.connections).toEqual(
expect.arrayContaining([
expect.objectContaining({ endpoint: "daemon-origin:6767", useTls: true }),
]),
);
store.syncHosts([]);
});
it("does not infer window.location.host when no explicit hint is present", async () => {
const seenProbes: { endpoint: string; useTls?: boolean }[] = [];
const firstProbe = createDeferred<void>();
const store = new HostRuntimeStore({
deps: {
createClient: () => new FakeDaemonClient() as unknown as DaemonClient,
connectToDaemon: async ({ connection }) => {
if (connection.type === "directTcp") {
seenProbes.push({ endpoint: connection.endpoint, useTls: connection.useTls });
}
firstProbe.resolve();
throw new Error("probe unavailable");
},
getClientId: async () => "cid_test_runtime",
readInitialConnectionHint: () => null,
},
storage: createMemoryHostRuntimeStorage(),
});
(globalThis as { window?: unknown }).window = {
location: { host: "metro-host:8081", protocol: "http:" },
};
store.boot();
await firstProbe.promise;
expect(seenProbes).not.toContainEqual(expect.objectContaining({ endpoint: "metro-host:8081" }));
expect(store.getHosts()).toHaveLength(0);
});
});