From 495de0d5283dd3e4a6ef715b596c4a2892e95915 Mon Sep 17 00:00:00 2001 From: Igor Soarez Date: Mon, 3 Aug 2026 21:18:02 +0100 Subject: Web search for pi through an existing Chrome over CDP MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Attaches to a browser that is already running — never launches one — using the same endpoint configuration as pi-browser-harness, so a single /browser-target choice governs both packages. One tool, castle_cdp_search, deliberately not named web_search so it coexists with pi-web-access rather than shadowing it. Notes from validating against castle's Chrome: - tbs=qdr:*, the parameter Google's own Tools menu writes, renders an empty page on this profile; the older as_qdr=* works. Any date filter combined with udm=14 is also empty, so recency drops udm. - Target.createTarget must not be raced against the abort signal: raceAbort abandons the promise but cannot cancel the command, and the command's side effect is a tab nothing is left holding. - A search cancelled while queued has to be removed from the semaphore queue, or the slot handed to it later is never counted back. - A decaying rate-limit block stops serving /sorry/ and returns an empty results page instead, indistinguishable from a genuine zero-hit search. --- src/paths.ts | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 src/paths.ts (limited to 'src/paths.ts') diff --git a/src/paths.ts b/src/paths.ts new file mode 100644 index 0000000..b008f4f --- /dev/null +++ b/src/paths.ts @@ -0,0 +1,41 @@ +/** + * pi's agent config directory, and the file pi-browser-harness stores its + * `/browser-target` choice in. + * + * This extension reads that file so a single `/browser-target` decision governs + * both packages. It never writes it — the harness owns that setting, and two + * writers of one file is a bug waiting to happen. + * + * pi exports `getAgentDir()`, but resolving it here would be a *runtime* import + * of the host package from an installed extension's own tree. Every other pi + * import in this codebase is `import type` and erased at build time, so the + * three lines are replicated instead (pi's dist/config.js: `PI_CODING_AGENT_DIR`, + * CONFIG_DIR_NAME `.pi`). Same reasoning as pi-browser-harness/src/profile/paths.ts. + */ + +import { homedir } from "node:os"; +import { join } from "node:path"; + +/** pi's env override for the agent dir (APP_NAME.toUpperCase() + "_CODING_AGENT_DIR"). */ +const ENV_AGENT_DIR = "PI_CODING_AGENT_DIR"; + +/** + * Expand a leading `~` exactly as pi's expandTildePath does — `~` and `~/…` + * only, never `~\…`, on every platform. Being more lenient here would look in a + * different directory than pi resolves from the same variable. + */ +const expandTildePiCompatible = (path: string): string => { + if (path === "~") return homedir(); + if (path.startsWith("~/")) return homedir() + path.slice(1); + return path; +}; + +/** pi's agent config directory — `$PI_CODING_AGENT_DIR` or `~/.pi/agent`. */ +export const agentDir = (): string => { + const fromEnv = process.env[ENV_AGENT_DIR]; + if (fromEnv) return expandTildePiCompatible(fromEnv); + return join(homedir(), ".pi", "agent"); +}; + +/** Where pi-browser-harness persists the `/browser-target` choice. */ +export const targetFilePath = (): string => join(agentDir(), "browser-target.json"); -- cgit v1.3.1