diff options
| author | Aman Kumar <145339995+amankumarsingh77@users.noreply.github.com> | 2026-10-11 23:33:25 +0530 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-10-11 23:33:25 +0530 |
| commit | 0fe64593bcc3379032840b35833ea39f23aa9322 (patch) | |
| tree | f01055f53a8a3d92a244b7fc7ecb0b88b6bf252b /src/cdp | |
| parent | 7833e2ecd5dc5fd9d7e63322680711d341d885ee (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/cdp')
| -rw-r--r-- | src/cdp/discovery.ts | 27 |
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"))); }); }, ); |
