pi-browser-harness 0.14.0 → 0.14.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,12 @@
2
2
 
3
3
  All notable changes to pi-browser-harness will be documented in this file.
4
4
 
5
+ ## 0.14.1 — 2026-11-07
6
+
7
+ ### Fixed
8
+
9
+ - **Browser tools load in every session, not just the first.** pi builds a fresh tool list for each session it starts in a running process (`/new`, resume, fork, and in-process subagents), but the harness remembered which tools it had registered for the whole process and skipped them all. Those sessions had no `browser_*` tools while the prompt still said they were available. The harness now registers its tools with each new session.
10
+
5
11
  ## 0.14.0 — 2026-11-01
6
12
 
7
13
  ### Added
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-browser-harness",
3
- "version": "0.14.0",
3
+ "version": "0.14.1",
4
4
  "description": "Browser control extension for pi — navigate, click, type, screenshot, and extract data from real Chrome via CDP",
5
5
  "keywords": [
6
6
  "pi-package",
package/src/registry.ts CHANGED
@@ -92,8 +92,9 @@ export type ToolRegistry = {
92
92
  // Append a batch atomically: a name clash anywhere in it (with the registry or within the batch)
93
93
  // rejects the whole call and leaves the registry untouched.
94
94
  readonly addAll: (tools: ReadonlyArray<BrowserTool>) => Result<void, RegistryError>;
95
- // Register every tool that has not been registered with pi yet. Safe to call on every
96
- // session_start: tools added after an earlier call land on the next one.
95
+ // Register every tool that has not been registered with this pi instance yet. Safe to call on
96
+ // every session_start: tools added after an earlier call land on the next one, and a fresh pi
97
+ // instance (pi builds one per session but reuses this cached module) gets every tool again.
97
98
  readonly register: (pi: ToolRegistrar, client: BrowserClient) => void;
98
99
  };
99
100
 
@@ -105,7 +106,9 @@ const duplicateName = (name: string): RegistryError => ({
105
106
  export const createToolRegistry = (initial: ReadonlyArray<BrowserTool> = ALL_TOOLS): ToolRegistry => {
106
107
  const tools: BrowserTool[] = [];
107
108
  const names = new Set<string>();
108
- const registered = new Set<string>();
109
+ // Keyed by pi instance: a process-wide set made every session after the first start with no
110
+ // browser tools, because pi hands each session an empty tool list.
111
+ const registeredByPi = new WeakMap<ToolRegistrar, Set<string>>();
109
112
 
110
113
  const addAll = (batch: ReadonlyArray<BrowserTool>): Result<void, RegistryError> => {
111
114
  const seen = new Set<string>();
@@ -129,6 +132,8 @@ export const createToolRegistry = (initial: ReadonlyArray<BrowserTool> = ALL_TOO
129
132
  add,
130
133
  addAll,
131
134
  register: (pi, client) => {
135
+ const registered = registeredByPi.get(pi) ?? new Set<string>();
136
+ registeredByPi.set(pi, registered);
132
137
  for (const tool of tools) {
133
138
  if (registered.has(tool.name)) continue;
134
139
  tool.register(pi, client);