all repos — sz-chrome-remote-cdp @ 792336dfef913291358f2312cd82c55944d18199

pi-browser-harness, patched to drive a Chrome on another host over CDP, with castle_cdp_search web search

feat(prompt): say which Chrome browser_* drives

The prompt told the model it drives "the user's running instance". With this
fork's default that is wrong: it is castle's shared Chrome, signed out of every
account. It now matters which is which, because pi-chrome's chrome_* tools
drive the user's signed-in Brave, and the model has to route between the two.

getBrowserSystemPrompt() takes the resolved target and describes it: castle's
shared browser for the built-in default, the user's own Chrome for local, the
endpoint otherwise.
Igor Soarez igor@soarez.org
Sun, 13 Sep 2026 18:30:51 +0100
commit

792336dfef913291358f2312cd82c55944d18199

parent

c8fd7b7078da841d5537aee9334291887445889f

2 files changed, 21 insertions(+), 3 deletions(-)

jump to
M src/index.ts → src/index.ts

@@ -261,8 +261,9 @@ persister.markPersisted(state);

}); pi.on("before_agent_start", async (event) => { + const target = resolveCdpTarget(process.env, await readTarget()); return { - systemPrompt: event.systemPrompt + getBrowserSystemPrompt(client?.status().alive ?? false), + systemPrompt: event.systemPrompt + getBrowserSystemPrompt(client?.status().alive ?? false, target), }; }); }
M src/prompt.ts → src/prompt.ts

@@ -1,11 +1,28 @@

-export function getBrowserSystemPrompt(connected = true): string { +import { type CdpTarget, DEFAULT_REMOTE_CDP } from "./cdp/endpoint"; + +/** + * FORK: which Chrome browser_* drives. Upstream always means "the user's own + * Chrome"; here the default is castle's shared one, signed out of everything, + * and pi-chrome's chrome_* tools drive a signed-in Brave - so the model has to + * be told which is which to route between them. + */ +const describeChrome = (target?: CdpTarget): string => { + if (!target || target.kind === "invalid") return "a real Chrome (not headless)"; + if (target.kind === "local") return "a real Chrome (the user's own, on this machine)"; + if (`${target.host}:${target.port}` === DEFAULT_REMOTE_CDP) { + return "a real Chrome (castle's shared browser on the wire network, signed out of every account — not the user's own browser)"; + } + return `a real Chrome (the one at ${target.host}:${target.port})`; +}; + +export function getBrowserSystemPrompt(connected = true, target?: CdpTarget): string { const connectionNotice = connected ? "" : "Browser is not connected. Run browser_setup or /browser-setup to connect.\n\n"; return ` ## Browser Control -${connectionNotice}You control the user's running Chrome through \`browser_*\` tools alongside the +${connectionNotice}You control ${describeChrome(target)} through \`browser_*\` tools alongside the standard pi tools. Per-tool usage lives in tool descriptions, parameter schemas, and tool-specific guidelines.