aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAman Kumar <145339995+amankumarsingh77@users.noreply.github.com>2026-10-11 23:33:25 +0530
committerGitHub <noreply@github.com>2026-10-11 23:33:25 +0530
commit0fe64593bcc3379032840b35833ea39f23aa9322 (patch)
treef01055f53a8a3d92a244b7fc7ecb0b88b6bf252b /src
parent7833e2ecd5dc5fd9d7e63322680711d341d885ee (diff)
fix(daemon): stop importing typebox in the daemon process (#38)
pi installs packages with dev and peer dependencies omitted and supplies typebox only to the extension host. The daemon is a separate Node process whose import graph reached typebox via src/cdp/discovery.ts, so from a pi-managed install it crashed with "Cannot find module 'typebox'" before binding its socket. Parse /json/version with the package's own guards, and add a test that keeps every package reachable from the daemon a runtime dependency. Fixes #34 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Diffstat (limited to 'src')
-rw-r--r--src/cdp/discovery.ts27
1 files changed, 15 insertions, 12 deletions
diff --git a/src/cdp/discovery.ts b/src/cdp/discovery.ts
index 60fb14f..3de6e97 100644
--- a/src/cdp/discovery.ts
+++ b/src/cdp/discovery.ts
@@ -2,23 +2,27 @@ import { readFile, stat } from "node:fs/promises";
import { join } from "node:path";
import { connect as netConnect } from "node:net";
import { request as httpRequest } from "node:http";
-import { Type } from "typebox";
-import { Compile } from "typebox/compile";
-import { parseJson } from "../schemas/parse";
import { type Result, err, ok } from "../util/result";
import { userDataDirCandidates } from "../profile/paths";
import { type CdpError, cdpError } from "./errors";
-import { errnoCode } from "../util/guards";
+import { asString, errnoCode, isRecord } from "../util/guards";
const PORT_PROBE_DEADLINE_MS = 30_000;
const PORT_PROBE_INTERVAL_MS = 1_000;
-const VersionResponse = Type.Object(
- { webSocketDebuggerUrl: Type.Optional(Type.String()) },
- { additionalProperties: true },
-);
-
-const versionValidator = Compile(VersionResponse);
+// Hand-rolled on purpose: this file runs inside the daemon, a separate Node process that pi does not
+// supply host-provided packages (typebox) to. Everything the daemon imports must be a runtime
+// dependency or a builtin; test/daemon/entry-imports-test.ts enforces that.
+export const parseVersionResponse = (raw: string): string | null => {
+ let parsed: unknown;
+ try {
+ parsed = JSON.parse(raw);
+ } catch {
+ return null;
+ }
+ if (!isRecord(parsed)) return null;
+ return asString(parsed["webSocketDebuggerUrl"]) ?? null;
+};
export type CdpEndpoint = {
readonly wsUrl: string;
@@ -72,8 +76,7 @@ const queryLiveWsUrl = (port: number, timeoutMs = 1_500): Promise<string | null>
const chunks: Buffer[] = [];
res.on("data", (c: Buffer) => chunks.push(c));
res.on("end", () => {
- const parsed = parseJson(Buffer.concat(chunks).toString("utf8"), versionValidator);
- resolve(parsed.success ? parsed.data.webSocketDebuggerUrl ?? null : null);
+ resolve(parseVersionResponse(Buffer.concat(chunks).toString("utf8")));
});
},
);