pi-agent-browser-native 0.8.3 → 0.9.0
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 +13 -1
- package/README.md +11 -11
- package/dist/extensions/agent-browser/index.js +93 -213
- package/dist/extensions/agent-browser/lib/browser-journal.js +33 -12
- package/dist/extensions/agent-browser/lib/execution-cwd.js +0 -16
- package/dist/extensions/agent-browser/lib/native-output.js +46 -0
- package/dist/extensions/agent-browser/lib/pi-tool-rendering.js +30 -16
- package/dist/extensions/agent-browser/lib/prompt-policy.js +16 -12
- package/dist/extensions/agent-browser/lib/results/presentation/content.js +4 -0
- package/dist/extensions/agent-browser/lib/results/presentation/large-output.js +15 -8
- package/dist/extensions/agent-browser/lib/tool-surface.js +39 -11
- package/dist/extensions/agent-browser/lib/web-search.js +85 -64
- package/docs/ARCHITECTURE.md +13 -15
- package/docs/COMMAND_REFERENCE.md +4 -2
- package/docs/RELEASE.md +25 -19
- package/docs/REQUIREMENTS.md +5 -5
- package/docs/SESSION_STORAGE.md +4 -4
- package/docs/SUPPORT_MATRIX.md +12 -10
- package/docs/TOOL_CONTRACT.md +9 -5
- package/package.json +4 -4
- package/scripts/doctor.mjs +2 -2
package/docs/SESSION_STORAGE.md
CHANGED
|
@@ -14,15 +14,15 @@ A saved URL or map cannot prove the native browser survived. Reuse checks native
|
|
|
14
14
|
|
|
15
15
|
## Reading and retention
|
|
16
16
|
|
|
17
|
-
Replay locates the journal through Pi's public session file, UUID and selected leaf. It captures that leaf before asynchronous reads and uses the same boundary for file and
|
|
17
|
+
Replay locates the journal through Pi's public session file, UUID and selected leaf. It captures that leaf before asynchronous reads and uses the same boundary for file and public native ancestry validation, so concurrent appends cannot change the branch being replayed. It token-validates complete newline-terminated records with unpacked discarded strings, projects envelopes, follows ancestry, and reads only winning snapshot bodies. An incomplete live tail remains uncommitted. Public `getEntry()` supplies structural ancestry checks on both supported hosts. Capture-local admission validates ancestry through the root, then reuses that append-only prefix after indexed endpoint identity/parent checks. New suffixes still reject missing/cyclic ancestry and unrelated branches; session/generation changes invalidate admission. Behind-host mutation of an old ancestor without native reseed/generation change is outside this append-only contract. Durable replay/append proofs remain independent: prefix reuse does not replace publication receipts or trust an unpublished selected leaf. No writable manager or private core storage is used.
|
|
18
18
|
|
|
19
|
-
Official Pi 0.
|
|
19
|
+
Official Pi 1.0.0 eagerly loads its own native journal before extension startup. This extension reduces browser write duplication and bounds extension recovery on that host; complete heap-independent host loading requires adoption of the native core repair. A caller-requested individual snapshot/result still must fit its consumer's memory. This is not an unlimited model-context or single-value API.
|
|
20
20
|
|
|
21
21
|
Artifact events persist row upserts/removals in journal order. The internal recent view defaults to 100 rows; it is separate from cumulative journal size and the independent recording reservation/tombstone journal. Artifact upserts are credential-redacted before persistence. Tool `details.artifactManifest` contains only changed or referenced receipts for that invocation, including evictions observed during that call. Retention summaries and close cleanup guidance can describe the internal recent view without copying it into every result.
|
|
22
22
|
|
|
23
|
-
Required replay snapshots stay in retained journal ancestry, outside observation-spill eviction. Caller-selected files remain caller-owned. Redacted persistent spills retain their existing byte budget; process-private files retain their existing cleanup. A receipt does not make external bytes immutable or include them in an export
|
|
23
|
+
Required replay snapshots stay in retained journal ancestry, outside observation-spill eviction. Caller-selected files remain caller-owned. Redacted persistent spills retain their existing byte budget; process-private files retain their existing cleanup. A receipt does not make external bytes immutable or include them in an export. Preserve referenced files in the matching archive layout when needed.
|
|
24
24
|
|
|
25
|
-
Tree changes join code execution through its complete observation finalization before restoring branch-visible state. Interrupted results retain complete caller observations in process-private spills without publishing their artifact state onto the newly selected branch. Tree changes do not roll back the real browser; process-owned cleanup and recording facts remain separate. An ordinary fork has a new native Pi UUID and cannot acquire its parent's managed/Electron/script cleanup rights. Wrapper-owned begins retain their selected socket root and owner UUID even if the launch finish is lost; restart can inspect or clean that original identity without declaring the launch successful. Owned follow-ups, code and cleanup keep that root when process defaults change; unrelated caller sessions retain native routing.
|
|
25
|
+
Startup and tree changes serialize branch restore with managed/artifact work, reusing one captured replay for state and cleanup-lease recovery. Launch configuration is folded once per session during that replay. Tree changes join code execution through its complete observation finalization before restoring branch-visible state. Interrupted results retain complete caller observations in process-private spills without publishing their artifact state onto the newly selected branch. Tree changes do not roll back the real browser; process-owned cleanup and recording facts remain separate. An ordinary fork has a new native Pi UUID and cannot acquire its parent's managed/Electron/script cleanup rights. Wrapper-owned begins retain their selected socket root and owner UUID even if the launch finish is lost; restart can inspect or clean that original identity without declaring the launch successful. Owned follow-ups, code and cleanup keep that root when process defaults change; unrelated caller sessions retain native routing.
|
|
26
26
|
|
|
27
27
|
## Converting a retained legacy journal
|
|
28
28
|
|
package/docs/SUPPORT_MATRIX.md
CHANGED
|
@@ -26,9 +26,9 @@ When upstream ships a new `agent-browser` or the inventory changes:
|
|
|
26
26
|
4. Update the **Baseline checklist by inventory section** table below so each `CAPABILITY_BASELINE.inventorySections[].id` row still points at the right docs, code, tests, and status notes.
|
|
27
27
|
5. Re-run the gates in **Verification evidence** on a machine that matches release expectations (`pi`, `tmux`, model config for lifecycle) and replace the dated status cells with fresh outcomes.
|
|
28
28
|
|
|
29
|
-
##
|
|
29
|
+
## Current browser contract
|
|
30
30
|
|
|
31
|
-
The compact direct/code/loader surface replaces public multimode inputs while retaining native commands and advanced outcomes. This section describes the implementation contract; dated
|
|
31
|
+
The compact direct/code/loader surface replaces public multimode inputs while retaining native commands and advanced outcomes. This section describes the implementation contract; dated evidence below does not qualify new Pi 1.0 code.
|
|
32
32
|
|
|
33
33
|
| Area | Contract and verification target |
|
|
34
34
|
| --- | --- |
|
|
@@ -38,11 +38,12 @@ The compact direct/code/loader surface replaces public multimode inputs while re
|
|
|
38
38
|
| RQ-0068 recipes | No recipe registry, persistent JavaScript, second driver, or interpreter dependency. |
|
|
39
39
|
| RQ-0096 Electron | Flat lifecycle tool preserves app/process/profile ownership and cancellation; native browser/code operations reuse its returned session. |
|
|
40
40
|
| RQ-0142 code | Fresh permissioned Node child over persistent parent-selected browser; explicit JSON/current-cell image output, visible failures/counts, ordinary auth/config/environment, ordered Pi intent/completion transitions, child cancellation/reaping, no legacy public execution. |
|
|
41
|
+
| Hotpath boundaries | Unrelated tools/harmless Bash return before prompt policy. Latest raw user intent is seeded on start/tree, updated by `message_end` and refreshed after native content replacement. Captured admission uses a validated append-only prefix; one queued replay restores branch/lease state and folds per-session launch settings once. Per-row renderer memoization skips unchanged formatting. No broad config/trust/history cache, new wait/timer or budget increase. |
|
|
41
42
|
| Shared ordering | Actual socket/namespace/session lock spans helper/action or entire cell; sorted identity sets for replacement/cleanup and namespace barrier for direct close-all. Requires every participating Pi to run the updated package; no human/third-party/older-version guarantee or transaction. |
|
|
42
|
-
| Observation and geometry | Canonical bounded JSON/prose/code observations expose exact recovery and receipts
|
|
43
|
-
| Pi integration |
|
|
43
|
+
| Observation and geometry | Canonical bounded JSON/prose/code/native `structuredContent` observations expose exact recovery and receipts, with native namespace/output-schema metadata and canonical returned `isError`; complete observation spills preserve large output. Image dimensions/CSS viewport/DPR/crop/scroll/frame evidence is measured or explicitly unknown; no viewport-coordinate assumptions for full-page/element images. |
|
|
44
|
+
| Pi integration | Pi 1.0 floor with independently qualified official/fork graphs. Five advanced direct tools use native `defaultActive: false`; a narrow additive initial-resume fallback preserves available transcript selections without overriding explicit/defaultTools/filtered host selection. Loader/tree/reload retain native history; public `pi:instruction-groups` registration supplies one full `browser` instruction source. Managed hosts own deferred delivery; unmanaged/stock hosts receive identical full eager guidance even for generic prompts. No permission widening or legacy discovery metadata. `test/agent-browser.discovery.test.ts` covers full-text parity, dynamic ownership, and startup/late registration; tool-surface tests preserve host selections, with pipeline coverage in `test/agent-browser.pi-pipeline.test.ts`. No checkpoint or fork metadata/revision APIs, provider payload edits or image-detail overrides. |
|
|
44
45
|
|
|
45
|
-
See [migration](TOOL_CONTRACT.md#07-migration), [canonical observations](TOOL_CONTRACT.md#canonical-observation), and [release qualification/rollback](RELEASE.md#07-upgrade-and-rollback). Routine GitHub Actions runs official/fork Linux compatibility, a macOS packed-Pi smoke, and
|
|
46
|
+
See [migration](TOOL_CONTRACT.md#07-migration), [canonical observations](TOOL_CONTRACT.md#canonical-observation), and [release qualification/rollback](RELEASE.md#07-upgrade-and-rollback). Routine GitHub Actions runs official/fork Linux compatibility, a macOS packed-Pi smoke, and Native lifecycle Linux qualification on PRs to `main`; Windows CI is excluded. Release/platform evidence and review remain separate from these focused checks.
|
|
46
47
|
|
|
47
48
|
## Audit result
|
|
48
49
|
|
|
@@ -90,7 +91,7 @@ Current summary:
|
|
|
90
91
|
| RQ-0153 | Browser storage retains native JSONL authority, once-stored ancestral ref definitions, small correlated begin/finish events, explicit uncertainty/reuse and native-generation validation, invocation-only artifact receipts and ordered row changes. Failed persistence never retries effects; ordinary forks retain facts without acquiring parent cleanup rights. Read-only token replay and stopped separate-copy conversion preserve all ancestry, explicit observations and original audit bytes. | [`docs/SESSION_STORAGE.md`](SESSION_STORAGE.md), `lib/browser-transcript.ts`, `lib/browser-journal.ts`, `lib/browser-session-conversion.ts`, `test/agent-browser.storage-growth.test.ts`, `test/agent-browser.storage-recovery.test.ts`, existing script/ref/confirmation/Electron lifecycle tests |
|
|
91
92
|
| RQ-0152 | Agent feedback closes recovery and evidence gaps without a new runtime layer: unknown-target timeouts return a visibly executable `get url` → `snapshot -i` fail-fast action while dialog recovery remains allowed; successful tab creation/selection/close, including dispatched batch rows, live-verifies URL/fresh titles and retains new, selected, and post-close blank tabs; compacted direct or batched `outputPath` writes use only full command-redacted live wrapper spills and fail rather than save metadata; explicit URL reads/all-read batches avoid browser helpers and managed replacement, while proven native read confirmations preserve exact session routing and capability-gated browser independence; single session-info preflights distinguish daemon/browser/native/Pi ownership; native recording receipts expose capture versus encoded measurements and survive failure/timeout exports, with bounded identity-matched recovery and no file-only success; direct or batched first/fresh local headed launches expose an unverified `browserWindow` handoff while attachments do not; snapshot spills and SAML/OAuth URL values are redacted at model/persistence boundaries; unsupported direct/batch `scrollintoview text=...` fails before upstream false success with visible native recovery payloads while help passes through; and web search sends Exa primary/version guidance, removes exact normalized-URL duplicates without overfetch, and labels provider page dates without claiming crawl/version proof. | [`docs/TOOL_CONTRACT.md`](TOOL_CONTRACT.md), [`docs/COMMAND_REFERENCE.md`](COMMAND_REFERENCE.md), [`docs/ARCHITECTURE.md`](ARCHITECTURE.md), `test/agent-browser.extension-errors-artifacts.test.ts`, `test/agent-browser.extension-tabs.test.ts`, `test/agent-browser.extension-validation.test.ts`, `test/agent-browser.page-target-validation.test.ts`, `test/agent-browser.runtime.test.ts`, `test/agent-browser.snapshot-presentation.test.ts`, `test/agent-browser.web-search.test.ts`, `test/agent-browser.real-upstream-contract.test.ts` |
|
|
92
93
|
|
|
93
|
-
Browser journal storage (RQ-0153) uses one canonical small event/reducer, once-stored complete captures and journal-ordered artifact changes. `test/agent-browser.storage-growth.test.ts` protects the incident-sized map and ordinary-code growth; `test/agent-browser.storage-recovery.test.ts` covers actual append-fault dispatch counts, concurrent publication during captured-branch replay, unpublished selected-leaf refusal, unknown prefixes, same-URL generation replacement, branch conversion and strict token validation. Existing tab/ref, read-confirmation, recording, artifact and Electron lifecycle suites retain their contracts. The opt-in `test/helpers/large-browser-journal.mjs` exercises a >1 GiB original with a giant ignored value under a constrained V8 heap; it reports actual RSS separately. Official and fork load/restart qualification remains independent, and stock official 0.
|
|
94
|
+
Browser journal storage (RQ-0153) uses one canonical small event/reducer, once-stored complete captures and journal-ordered artifact changes. `test/agent-browser.storage-growth.test.ts` protects the incident-sized map and ordinary-code growth; `test/agent-browser.storage-recovery.test.ts` covers actual append-fault dispatch counts, concurrent publication during captured-branch replay, unpublished selected-leaf refusal, unknown prefixes, same-URL generation replacement, branch conversion and strict token validation. Existing tab/ref, read-confirmation, recording, artifact and Electron lifecycle suites retain their contracts. The opt-in `test/helpers/large-browser-journal.mjs` exercises a >1 GiB original with a giant ignored value under a constrained V8 heap; it reports actual RSS separately. Official and fork load/restart qualification remains independent, and stock official 1.0.0's native eager loader is not repaired by the extension alone. Conversion is offline and source-retaining; see [`SESSION_STORAGE.md`](SESSION_STORAGE.md).
|
|
94
95
|
|
|
95
96
|
QA truthfulness (#121, RQ-0145) is covered by the registered-tool controls in `test/agent-browser.extension-input-modes.test.ts` and the strict `contract suite matches QA non-pass after same-URL error-buffer rollover` case in `test/agent-browser.real-upstream-contract.test.ts`. The real fixture fills the native error FIFO with identical rows, then verifies that a new document actually throws again at the same URL and that QA is always non-pass. Matched rows fail as an unverified check, not an application-error assertion. Empty/cleared and explicit `checkErrors: false` controls preserve valid passes; the wrapper does not fix upstream `errors --clear` or accept a warning-only pass as resolution.
|
|
96
97
|
|
|
@@ -126,16 +127,17 @@ At runtime source `3a9adf490883149e7f79ee070d1900877e17b891`, PR compatibility p
|
|
|
126
127
|
|
|
127
128
|
Fresh precommit evidence for that runtime passed real Pi checkout/live-site and supported disposable Electron smoke, configured-source lifecycle, packaged runtime-only SDK/CLI loading, real-upstream checks, native macOS and the canonical named Ubuntu target (Debian 12). Local macOS is the documented alternate, not an SSH pass. Docs/workflow-only delivery may reuse this runtime evidence only after all 104 rebuilt runtime files match the checked artifact; changed published docs require a newly checked retained tarball. No additional paid/live gate is implied by an otherwise byte-identical runtime.
|
|
128
129
|
|
|
129
|
-
Linux/macOS, declared Node floors, official/fork host identities, required consumer artifacts and Native
|
|
130
|
+
Linux/macOS, declared Node floors, official/fork host identities, required consumer artifacts and Native lifecycle Linux remain required. Routine GitHub Actions is enabled for PRs to `main` and manual dispatch; its focused results do not substitute for the release and platform gates. Retain all three final reviewer approvals before merge/release/activation. The unchanged composed `release`/`prepublishOnly` command still includes Windows and is not reported as passed under this waiver; see [release guidance](RELEASE.md#current-0616-rollout-waiver).
|
|
130
131
|
|
|
131
132
|
## Verification evidence
|
|
132
133
|
|
|
133
134
|
**0.38.1 PR evidence (2026-09-17, local macOS):** the full unit/fake suite passed 1,146 tests with 27 opt-in skips; the final review fixes then passed typecheck and 64 affected tests. Generated docs, live command-reference sampling, and the 132-file packaged Pi smoke passed. The real-upstream contract and 75 native batch/fidelity checks passed, as did all eight deterministic dogfood flows. Interactive compiled-checkout Pi smoke covered example.com and react.dev, delta/ref follow-ups, conditional screenshots, and a recording batch whose persisted result had two verified artifacts and no pending artifacts. Separate native probes confirmed helper-consumed WebMCP catalog updates remain visible. These checks do not qualify release-only platform/lifecycle gates; the hosted native-Windows result is recorded on the PR.
|
|
134
135
|
|
|
135
|
-
Re-run the gates below before each release. Dated outcomes in this table are historical evidence for their named source/version, not qualification of the current 0
|
|
136
|
+
Re-run the gates below before each release. Dated outcomes in this table are historical evidence for their named source/version, not qualification of the current Pi 1.0 implementation. The earlier 0.36.0 rebaseline passed local pre-PR, real-upstream and deterministic dogfood on 2026-09-01; the 0.35.0 floor was last validated locally on 2026-08-26. The historical 0.38.1 PR qualification used local macOS and the hosted native-Windows gate. Current explicit owner waivers take precedence; neither historical passes nor failures qualify the new candidate. Release-only cross-platform/model/lifecycle and publication gates remain separate.
|
|
136
137
|
|
|
137
138
|
| Gate | Evidence | Status |
|
|
138
139
|
| --- | --- | --- |
|
|
140
|
+
| Native lifecycle Linux | Portable public SDK/native-browser lifecycle gate covers branch/reload, ordered code cancellation, ownership/routing, journal-begin failure and root save/reopen; see [native qualification](RELEASE.md#native-lifecycle-qualification). | Requalify the exact final source and host graph; no Pi 1.0 candidate pass is claimed by historical evidence below. |
|
|
139
141
|
| Default local gate | `npm run verify` checks generated playbook drift, clean-builds generated `dist/`, runs `tsc --noEmit`, unit/fake tests, generated command-reference blocks, and live command-reference sampling. | **Earlier 0.36.0:** pass on 2026-09-01; 779 tests passed, two opt-in real-upstream tests skipped, and build/typecheck/docs/live command-reference gates passed. |
|
|
140
142
|
| Pre-PR local gate | `npm run verify -- pre-pr` composes the default gate with package-content verification. Use before larger local handoffs or PR-ready claims when lifecycle/platform/live dogfood cost is not warranted. | **Earlier 0.36.0 / package 0.6.2:** pass on 2026-09-01; 779 tests passed, two opt-in tests skipped, and the 127-file tarball verified. |
|
|
141
143
|
| Windows argument transport (#102/#131/#141) | `test/agent-browser.windows-argv.test.ts` exercises actual host argv, empty values, quotes, Unicode/spaces, stdin, custom shims and failure outcomes. `test/agent-browser.windows-stock-launcher.test.ts` covers the recognized global npm CMD template's direct-native path, command selection, fallback, literal LF/CRLF and cancellation. Custom or unrecognized batch launchers retain their existing newline limitation. POSIX keeps Node `spawn`. | Native Windows focused qualification on 2026-09-21 passed all seven stock-launcher controls, all 29 Chromium cases and 33 process/argv cases (two existing platform skips). Actual upstream Rust received all 12 expected operands; the original CMD path lost all four newline-bearing operands. These focused results do not replace full-suite, managed-browser, package or release gates. |
|
|
@@ -147,10 +149,10 @@ Re-run the gates below before each release. Dated outcomes in this table are his
|
|
|
147
149
|
| Android/Termux local bring-up | Non-release-blocking source validation uses Termux system Chromium through upstream's Linux `which chromium` discovery, the packaged Linux-musl arm64 CLI, real Pi managed-session smoke, deterministic dogfood, and the default unit/package gate. Electron desktop lifecycle is not applicable. | **Historical 0.6 local evidence (not 0.7 code qualification):** Android 17 / arm64 Termux passed implicit, explicit, and namespaced fresh sessions, managed restore, script, QA, semantic action, job, click, eval/batch stdin, screenshot attachment, recording dependencies, and cleanup; Android is not yet a Crabbox release target. |
|
|
148
150
|
| Crabbox platform smoke | `npm run check:platform-smoke` syntax-checks the harness and cheap invariants. `npm run smoke:platform:ubuntu-image` builds the project-owned Linux image, `npm run smoke:platform:doctor` checks Crabbox 0.26.0+ and local target readiness, and `npm run smoke:platform:all` runs doctor first, then fast target-local `platform-build` (`npm run verify -- platform-target`, pack, clean Pi install) plus `browser-dogfood-smoke` on Crabbox `macos`, `ubuntu`, and `windows-native`; see [`platform-smoke.md`](platform-smoke.md). Target artifacts include Crabbox/provider/work-root metadata, and release review also checks provider-specific `crabbox list` commands for leftover leases/clones. | **Earlier 0.36.0 / package 0.6.2 / Pi 0.84.4:** Ubuntu `platform-build` and `browser-dogfood-smoke` passed with 11/11 assertions each on 2026-09-01, including complete artifact manifests and lease cleanup. Under explicit GitHub-only release waivers, macOS SSH and native Windows were not run because localhost SSH and `prlctl` were unavailable. |
|
|
149
151
|
| `verify -- release` / `prepublishOnly` | `npm run verify -- release` chains the default gate with the configured-source lifecycle harness, packaged Pi smoke, and the release-blocking Crabbox platform matrix (`verifySteps` `release` in [`scripts/project.mjs`](https://github.com/fitchmultz/pi-agent-browser-native/blob/main/scripts/project.mjs)). `package.json` `prepublishOnly` runs that compose before `npm pack --dry-run` during `npm publish`. It intentionally omits standalone real-upstream and host-only dogfood modes—see [`RELEASE.md`](RELEASE.md#pre-release-checks). | **Package 0.6.2:** on 2026-09-01 the default, lifecycle, package-Pi, startup, real-upstream, deterministic dogfood, harness, Ubuntu image, and Ubuntu target gates passed individually. The canonical full composition was not reported as passed because macOS SSH and native Windows were explicitly waived after doctor confirmed localhost SSH and `prlctl` were unavailable. That historical release created GitHub artifacts only; it did not authorize npm publishing. |
|
|
150
|
-
| Configured-source lifecycle | `npm run verify -- lifecycle` (`scripts/verify-lifecycle.mjs`) drives `/reload`, closes and relaunches Pi with the same exact `--session-id`, checks the JSONL session header id, session continuity, slash-command sentinel tokens (`v1` before reload and `v2` after full relaunch), persisted spill reachability, and
|
|
152
|
+
| Configured-source lifecycle | `npm run verify -- lifecycle` (`scripts/verify-lifecycle.mjs`) drives `/reload`, closes and relaunches Pi with the same exact `--session-id`, checks the JSONL session header id, session continuity, slash-command sentinel tokens (`v1` before reload and `v2` after full relaunch), persisted spill reachability, and native returned failure status and JSON preservation for a QA reclassification with a fake upstream on `PATH`. Default Pi model is `zai/glm-5.2`; default per-step wait is **180000 ms** (`DEFAULT_TIMEOUT_MS`); override model with `--model <id>` and waits with `--timeout-ms <ms>`. Passthrough flags in [`scripts/project.mjs`](https://github.com/fitchmultz/pi-agent-browser-native/blob/main/scripts/project.mjs): `--keep-artifacts`, `--model`, `--verbose`, and `--timeout-ms` plus a value (for example `npm run verify -- lifecycle --model openai-codex/gpt-5.5:minimal --keep-artifacts --verbose --timeout-ms 600000`). | **Pi 0.84.4 on 2026-09-01:** pass; `/reload`, exact-session relaunch, managed continuity, persisted spill reachability, and Pi failure status all verified. |
|
|
151
153
|
| Quick isolated Pi smoke | `pi --approve --no-extensions --no-skills -e .` from trusted repo root; checkout-native browser tools only. | **Earlier 0.36.0 / package 0.6.2 / Pi 0.84.4:** isolated checkout tmux smoke passed on 2026-09-01; native `agent_browser` completed version, localhost open, WebMCP list/invoke, visible-text verification, and close. |
|
|
152
154
|
|
|
153
|
-
Runtime floor note: package metadata requires Node 24.21.0 or newer, keeps optional Pi core package peer ranges wildcard per installed Pi package docs, pins direct Pi validation dependencies to 0.
|
|
155
|
+
Runtime floor note: package metadata requires Node 24.21.0 or newer, keeps optional Pi core package peer ranges wildcard per installed Pi package docs, pins direct Pi validation dependencies to 1.0.0, and makes `pi --version` below 1.0.0 a setup failure through `pi-agent-browser-doctor` / `npm run doctor`. The Pi floor follows the native tool-history/prompt APIs and includes no older-host compatibility shim.
|
|
154
156
|
|
|
155
157
|
## Baseline checklist by inventory section
|
|
156
158
|
|
package/docs/TOOL_CONTRACT.md
CHANGED
|
@@ -16,7 +16,9 @@ The extension synchronously registers a `browser` instruction group through the
|
|
|
16
16
|
|
|
17
17
|
Group enablement reveals selected declarations and instructions, not callable permissions. `agent_browser_tools` remains the separate advanced-tool activation path. Existing host selections, exclusions, namespaces, and restored tool history are unchanged.
|
|
18
18
|
|
|
19
|
-
Pi 0.
|
|
19
|
+
Pi 1.0.0 or newer is required; official and fork qualification is independent. Five specialized direct tools declare native `defaultActive: false`: `agent_browser_action`, `agent_browser_qa`, `agent_browser_electron`, `agent_browser_source`, and `agent_browser_network_source`. They require activation unless selected by the host; they are not deferred tools. Explicit CLI allowlists, SDK selections/defaultTools, loader activation, restored tool history, tree navigation and reload are respected. Omit CLI `--tools` for lazy activation, or include every desired advanced tool in its allowlist; the loader reports excluded tools as unavailable rather than bypassing host selection.
|
|
20
|
+
|
|
21
|
+
Official Pi 1.0's initial SDK resume supplies an initial tool selection that bypasses native transcript restoration. The extension retains a narrow additive resume fallback for available advanced tools; it never deactivates host-selected tools or bypasses an explicit allowlist/filtered catalog. Remove that fallback only when the minimum supported official host restores this state natively.
|
|
20
22
|
|
|
21
23
|
## Why this tool shape
|
|
22
24
|
|
|
@@ -55,7 +57,7 @@ Supplying the callback registers `agent_browser` with Pi's native `executionMode
|
|
|
55
57
|
|
|
56
58
|
## Optional companion web search
|
|
57
59
|
|
|
58
|
-
`agent_browser_web_search` is a separate custom tool, not an `agent_browser` input mode. It is available when the extension can see at least one configured/resolvable Exa or Brave credential source from `~/.pi/config/pi-agent-browser-native/config.json`, `.pi/config/pi-agent-browser-native/config.json`, `PI_AGENT_BROWSER_CONFIG`, or the `EXA_API_KEY` / `BRAVE_API_KEY` environment fallbacks, and runtime execution still checks that the final available merged config has not set `webSearch.enabled` to `false`. Config layers merge global → project → `PI_AGENT_BROWSER_CONFIG` override;
|
|
60
|
+
`agent_browser_web_search` is a separate custom tool, not an `agent_browser` input mode. It is available when the extension can see at least one configured/resolvable Exa or Brave credential source from `~/.pi/config/pi-agent-browser-native/config.json`, `.pi/config/pi-agent-browser-native/config.json`, `PI_AGENT_BROWSER_CONFIG`, or the `EXA_API_KEY` / `BRAVE_API_KEY` environment fallbacks, and runtime execution still checks that the final available merged config has not set `webSearch.enabled` to `false`. Config layers merge global → project → `PI_AGENT_BROWSER_CONFIG` override; globally installed and CLI-loaded copies read `.pi/config/...` when Pi trust allows that project layer, and they skip the project layer when Pi reports the project is untrusted or when launched with `--no-approve`. Disable scope is explicit: a global disable is a normal user default, a project disable applies to one repo, and an override file with `webSearch.enabled: false` is the highest-priority hard disable for that run. Credential sources may be plaintext, `$ENV_VAR` / `${ENV_VAR}` interpolation, escaped literals, or command sources such as `"!op read 'op://Private/Exa/API Key'"` from any loaded config layer; they make the tool available without exposing the value in status text, and command values resolve when the tool executes. Browser profile/executable config uses the same paths and emits prompt guidance from the highest-priority loaded layer, including project config when that layer is loaded.
|
|
59
61
|
|
|
60
62
|
Prefer it for live/current external web facts, current docs/news, and candidate URLs. Prefer it over browser-driving public search-engine forms such as Google: headless typing flows may be redirected to anti-bot or CAPTCHA pages, and agents should use search API results, then `agent_browser` on a target URL, instead of attempting CAPTCHA bypass. Use `agent_browser` when the task needs browser interaction, screenshots, authenticated/profile content, page inspection, or DOM work. The search tool is namespaced to avoid colliding with generic `web_search`, chooses Exa or Brave automatically from available credentials, defaults to Exa when both are available (unless `webSearch.preferredProvider` is set), and must not expose resolved API keys in content, details, errors, status output, docs examples, logs, or PR artifacts.
|
|
61
63
|
|
|
@@ -132,7 +134,7 @@ Result details:
|
|
|
132
134
|
}
|
|
133
135
|
```
|
|
134
136
|
|
|
135
|
-
For Exa, `details.searchType` is the effective requested type even when the provider response does not echo it. `requestId` is included when Exa returns one. Brave omits both fields. `pageDate` comes from Exa `publishedDate` (an estimated page creation date) or Brave `page_age`; Brave may separately return `age`. These provider fields are not crawl/retrieval age or proof that a result matches a requested version. For version-sensitive work, inspect the result, constrain one follow-up to the primary domain (`includeDomains` for Exa or `site:` in a Brave query), and read the primary page.
|
|
137
|
+
For Exa, `details.searchType` is the effective requested type even when the provider response does not echo it. `requestId` is included when Exa returns one. Brave omits both fields. `pageDate` comes from Exa `publishedDate` (an estimated page creation date) or Brave `page_age`; Brave may separately return `age`. These provider fields are not crawl/retrieval age or proof that a result matches a requested version. For version-sensitive work, inspect the result, constrain one follow-up to the primary domain (`includeDomains` for Exa or `site:` in a Brave query), and read the primary page. Failures return structured results: local config/validation problems (invalid config, disabled tool, missing credential, blank query, Exa-only filters resolved to Brave) are `validation-error`; provider/network failures are `upstream-error`; both keep `isError` and redacted messages.
|
|
136
138
|
|
|
137
139
|
## Input mode chooser
|
|
138
140
|
|
|
@@ -528,7 +530,9 @@ These calls return plain text and stay stateless: the extension does not inject
|
|
|
528
530
|
|
|
529
531
|
### Canonical observation
|
|
530
532
|
|
|
531
|
-
Direct and advanced results expose the same decision-relevant observation in model-visible JSON or prose; code receives it as data without rendering/reparsing prose. The base is `{ success, resultCategory, data?, error?, summary?, successCategory?, failureCategory? }
|
|
533
|
+
Direct and advanced results expose the same decision-relevant observation in model-visible JSON or prose; code receives it as data without rendering/reparsing prose. The base is `{ success, resultCategory, data?, error?, summary?, successCategory?, failureCategory? }`; `summary` is omitted when it is byte-identical to `error` so large failure text is not counted twice. Optional fields include exact `nextActions`, warnings, session/namespace, artifact verification, image observations, page-change evidence, timeout partial progress, and QA/source/diagnostic results. Batch observations retain per-step outcomes. Native help/version remains plain text.
|
|
534
|
+
|
|
535
|
+
Tool declarations share native Browser namespace metadata and an `outputSchema`. Returned `structuredContent` exposes the same bounded redacted projection, including failed/preparation/cancelled results, rather than raw internal `details`. Oversized observations use the existing compact object and complete redacted spill path. The loader returns `{ inventory, added }`; optional search returns its normalized provider data in the observation's `data`. This supports host-selected native codemode without auto-enabling it, changing advanced activation, or replacing the Browser code VM. Structured image paths/handles are metadata, not native `image()` input; retain verified Pi image blocks and current-cell `emitImage` semantics.
|
|
532
536
|
|
|
533
537
|
`details` retains audit, process, ownership, and replay metadata; it is not the sole channel for actionable failures. JSON remains parseable, including early preparation failures and filters. Prose retains useful command output and appends canonical observation metadata. Final visible text is bounded to 16,000 characters. If necessary, the complete redacted observation is spilled and the result names `observationPath` plus retrieval instructions. Exact recovery objects are either included whole or remain in that complete observation; truncated argv/stdin is never presented as executable recovery. An unavailable spill is reported honestly.
|
|
534
538
|
|
|
@@ -600,7 +604,7 @@ These categories are intentionally bounded and stable so agents can branch on th
|
|
|
600
604
|
|
|
601
605
|
For argv-supplied `--allowed-domains`, the wrapper treats domain containment as launch-scoped. Upstream owns request, worker, popup, and WebRTC containment plus incompatible-mode rejection; the wrapper passes the setting and upstream result through unchanged.
|
|
602
606
|
|
|
603
|
-
|
|
607
|
+
Final public results return canonical `isError: true` when `resultCategory` is `failure`; Pi 1.0 honors that return without a `tool_result` repair hook. For normal prose, finalization appends `Result category: failure; failureCategory: …; Pi tool isError: true.` to model-visible text. Explicit parseable JSON remains unchanged, including code JSON and preparation failures; invalid/non-JSON text retains the notice. The TUI also shows the category at the top of failed rendered results so collapsed rows keep the outcome visible. Shared finalization lives in `lib/native-output.ts` and `finalizeAgentBrowserFailure` in `lib/pi-tool-rendering.ts`. This keeps transcript, UI and structured outcomes aligned after wrapper-side reclassification such as `qa-failure` or `artifact-missing`.
|
|
604
608
|
|
|
605
609
|
For `batch`, top-level `details` still carries `resultCategory` plus `successCategory` or `failureCategory` for the **aggregate** tool outcome: if any step fails, the overall result is a failure (`resultCategory: "failure"`) even when later steps succeed—inspect `batchSteps[]` for per-step outcomes. Each `batchSteps[]` entry includes its own `resultCategory` and either `successCategory` or `failureCategory` for that step. When upstream reports it, successful and failed rows also expose a dedicated `lifecycle` field containing only the bounded `effectiveLaunch.browserLaunched` boolean; on failed rows this preserves launch evidence even though the ordinary result payload is omitted. Live state and transcript replay use that evidence to distinguish a terminal nested close from a post-close browser launch. `batchFailure.failedStep` duplicates the first failing step’s details, including its `failureCategory`, bounded lifecycle evidence, and any `nextActions`.
|
|
606
610
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-agent-browser-native",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "pi extension that exposes agent-browser as a native tool for browser automation",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": "Mitch Fultz (https://github.com/fitchmultz)",
|
|
@@ -68,9 +68,9 @@
|
|
|
68
68
|
"typebox": "*"
|
|
69
69
|
},
|
|
70
70
|
"devDependencies": {
|
|
71
|
-
"@earendil-works/pi-ai": "0.
|
|
72
|
-
"@earendil-works/pi-coding-agent": "0.
|
|
73
|
-
"@earendil-works/pi-tui": "0.
|
|
71
|
+
"@earendil-works/pi-ai": "1.0.0",
|
|
72
|
+
"@earendil-works/pi-coding-agent": "1.0.0",
|
|
73
|
+
"@earendil-works/pi-tui": "1.0.0",
|
|
74
74
|
"@types/cross-spawn": "6.0.6",
|
|
75
75
|
"@types/node": "24.19.0",
|
|
76
76
|
"@types/which": "2.0.2",
|
package/scripts/doctor.mjs
CHANGED
|
@@ -26,7 +26,7 @@ const EXTENSION_ENTRYPOINTS = Object.freeze([
|
|
|
26
26
|
"dist/extensions/agent-browser/index.js",
|
|
27
27
|
]);
|
|
28
28
|
const RECOMMENDED_VERSION = TARGET_AGENT_BROWSER_VERSION;
|
|
29
|
-
export const MINIMUM_PI_VERSION = "0.
|
|
29
|
+
export const MINIMUM_PI_VERSION = "1.0.0";
|
|
30
30
|
const DEFAULT_AGENT_DIR = resolve(homedir(), ".pi/agent");
|
|
31
31
|
const THIS_PACKAGE_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), "..");
|
|
32
32
|
|
|
@@ -44,7 +44,7 @@ function parseVersionParts(version) {
|
|
|
44
44
|
return match.slice(1).map((part) => Number.parseInt(part, 10));
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
function versionAtLeast(actual, minimum) {
|
|
47
|
+
export function versionAtLeast(actual, minimum) {
|
|
48
48
|
const actualParts = parseVersionParts(actual);
|
|
49
49
|
const minimumParts = parseVersionParts(minimum);
|
|
50
50
|
if (!actualParts || !minimumParts) return undefined;
|