aboutsummaryrefslogtreecommitdiff
path: root/src/daemon/server.ts
AgeCommit message (Collapse)Author
2026-08-02refactor: daemon internals, and fix a leak the merge exposedamankumarsingh77
IdMultiplexer and EventRouter were the only classes in src/; they are now createIdMultiplexer/createEventRouter closures like every other factory here. The multiplexer kept {clientId, localId} per daemon id while the bridge kept {send, clientId, localId, timer, isAttach} under the same key — two maps of overlapping data, and mux.resolve()'s return value was discarded at three of four call sites. One map now holds the union. That merge fixes a real leak: removeClient cleared the multiplexer but never the callbacks map, so a disconnected client's timers stayed armed and later fired a response at a socket that was gone. clearClient now cancels them, and a test pins it. handleRequest polled every 250ms for up to 15s per request when Chrome was down; N queued requests now await one connect signal. server.ts uses its own protocol's serialize/deserialize instead of hand-rolled JSON, and broadcast no longer routes through `this` — the only `this` in the codebase, and the one thing that breaks when the server object is destructured. cdp/event-queue.ts held two unrelated concerns; the request/timeout half moves to cdp/pending-requests.ts. cdp/daemon-transport.ts is the client half of the daemon protocol, so it moves to daemon/transport.ts. test/daemon/ needs adding to the test glob to run at all — there was no daemon test directory before because none of this was reachable without live Chrome. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-02refactor: delete exports and knobs that nothing callsamankumarsingh77
isInternalUrl, SPECIAL_KEYS, andThen and mapErr had no callers in src or test. BrowserState.remoteBrowserId was parsed on restore and never written — the field that is actually read lives on DaemonStatus. IpcServer.disconnectClient and IpcServer.clients() were unreachable, as was EventRouter.allClients and a write-only lineCount counter. DAEMON_STALE_SOCKET_CLEANUP was a hardcoded true with an if around it, so the unlink now runs unconditionally. CdpBridge.isAlive and getSessionOwner look equally dead from src/ alone, but test/manual/bridge-test.ts drives both — they are the only seams that suite has, so they stay. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-02refactor: tidy the whitespace the comment removal left behindamankumarsingh77
Drops leading blank lines where a file header was removed, collapses double blank lines, and closes the empty catch/handler blocks whose only content had been a comment. Whitespace only. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-02refactor(daemon): strip comment noiseamankumarsingh77
Removes module banners, section dividers, reference lists, and comments restating the code. Keeps one-line notes for the Windows named-pipe endpoint, the Windows unlink no-op, the do-not-unlink-on-rejection rule, the `.cmd` shell requirement, shell-quoting of spaced paths, and the in-place client promotion. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-06-21release: v0.6.0 — per-tab isolation, Unix socket daemon, on-demand init (#6)Aman Kumar
* feat: Unix socket daemon with auto-reconnect for persistent Chrome CDP Eliminates the 'Allow Remote Debugging' Chrome prompt that appeared on every pi session by multiplexing pi instances through a single persistent daemon process. Key additions: - Unix socket IPC (net.createServer + readline JSON framing) - CdpBridge with ID multiplexer + event router - DaemonTransport implementing CdpTransport interface - Auto-spawn with ensureDaemon() (lazy, checks socket) Fixes since initial implementation: - Bridge auto-reconnects to Chrome with exponential backoff (1s-60s). Previously the bridge tried once at startup and permanently failed if Chrome wasn't ready — causing 'Chrome not connected' on every browser tool call. - Daemon spawn uses project-local tsx binary instead of global --import flag, fixing silent spawn failure (ERR_MODULE_NOT_FOUND). - Stale ctx crash: persistState in onOwnershipChange wrapped in try/catch to prevent CDP event consumer crashes. 49 test assertions across 4 test files. Zero TypeScript errors. * feat: on-demand browser initialization Browser daemon no longer auto-starts on session_start. Instead: - session_start creates the client lazily but does NOT connect or spawn the daemon. Zero Chrome prompts for non-browser pi sessions. - Browser tool wrapper checks for daemon socket before each call. Socket missing → clear error: 'Run /browser-setup first'. Socket exists → proceeds silently (daemon already running). - /browser-setup is the explicit, one-time init point. It spawns the daemon and connects to Chrome only when the user opts in. - SKILL.md updated with Connection Setup instructions telling agents to direct users to /browser-setup when socket is missing. * fix: checkChromeRunning on macOS — match by substring not exact ps -A -o comm= returns full executable paths on modern macOS (e.g. /Applications/Google Chrome.app/Contents/MacOS/Google Chrome), not the basename. The old exact-match check (browserProcesses.includes(l)) never matched, causing false 'No browser instance running' errors. Changed to substring includes() with helper/renderer/crashpad filtering. * feat: browser_setup as agent-callable tool The agent can now self-recover from 'Browser harness not initialized' errors by calling browser_setup directly — no user mediation needed. - Extracted shared performSetup() from the slash command into setup.ts - Created src/domains/setup.ts with ensureAlive:false to bypass the socket guard (this tool IS the setup, can't require itself) - Registered browser_setup in the tool registry - Updated SKILL.md: agent calls browser_setup directly, not ask user - Removed stale test/manual/spawn-test.ts * release: v0.6.0 — per-tab isolation, Unix socket daemon, on-demand init