diff options
| author | Igor Soarez <igor@soarez.org> | 2026-08-04 15:08:47 +0100 |
|---|---|---|
| committer | Igor Soarez <igor@soarez.org> | 2026-08-04 15:08:47 +0100 |
| commit | bd03d3b8fff9ed18d3cdb104c55908ba5be6c424 (patch) | |
| tree | 659afa1dd7e80c7ac97fb9c142026bf43c1ef8a0 /castle-search/src/paths.ts | |
| parent | 08c0c3a8b4fe755f7fe65ea8d258d77971503882 (diff) | |
Write up what AI answer blocks would cost before building one
Google, Bing and Brave all put a generated answer above their results now,
and none of it is being read. Investigated against castle's Chrome; nothing
in src/ changed, because the cost turned out to be worth deciding on rather
than absorbing.
Two things make it expensive. Google's AI Overview exists only on the
classic layout — udm=14 is the "Web" tab, and having no overview is part of
what that tab is — so enabling it means giving back the clean page the
extractor was built around. And all three stream in after the results are
already parseable: Google settles ~2.3s in, Brave was still growing at 5s,
against an extractor that returns at ~0.5s. The wait is often wasted, since
the blocks are query-dependent — no Google overview for "how does postgres
MVCC vacuum work" after 15s, no Bing answer for "who founded anthropic".
Selectors, the traps behind them (#m-x-content briefly holds ~29k
characters of unrelated page; Google's "Show more" hides only the
disclaimer), the measured timings, three possible designs and their
tradeoffs are all in the doc, so this does not have to be re-measured if
the answer turns out to be yes.
Diffstat (limited to 'castle-search/src/paths.ts')
| -rw-r--r-- | castle-search/src/paths.ts | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/castle-search/src/paths.ts b/castle-search/src/paths.ts new file mode 100644 index 0000000..b008f4f --- /dev/null +++ b/castle-search/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"); |
