pi-agent-browser-native 0.9.6 → 0.9.7
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 +95 -1
- package/README.md +14 -6
- package/dist/extensions/agent-browser/index.js +1276 -350
- package/dist/packaged/lib/browser-session-conversion.js +157 -21
- package/dist/packaged/lib/playbook.js +42 -8
- package/dist/packaged/lib/results/snapshot.js +140 -11
- package/dist/packaged/lib/runtime.js +58 -10
- package/docs/ARCHITECTURE.md +19 -10
- package/docs/CODE_QUALITY.md +21 -5
- package/docs/COMMAND_REFERENCE.md +154 -38
- package/docs/ELECTRON.md +1 -1
- package/docs/PERFORMANCE.md +12 -3
- package/docs/REFERENCE.md +14 -14
- package/docs/RELEASE.md +41 -18
- package/docs/REQUIREMENTS.md +6 -0
- package/docs/SESSION_STORAGE.md +3 -3
- package/docs/SUPPORT_MATRIX.md +25 -23
- package/docs/TOOL_CONTRACT.md +37 -14
- package/docs/platform-smoke.md +18 -14
- package/package.json +6 -3
- package/platform-smoke.config.mjs +3 -2
- package/scripts/agent-browser-capability-baseline.mjs +16 -2
- package/scripts/agent-browser-target.mjs +1 -1
- package/scripts/capability-options.mjs +20 -0
- package/scripts/capability-samples.mjs +23 -10
- package/scripts/platform-smoke/commands.mjs +30 -4
- package/scripts/platform-smoke/doctor-support.mjs +11 -2
- package/scripts/platform-smoke/doctor-windows.mjs +1 -1
- package/scripts/platform-smoke/doctor.mjs +26 -11
- package/scripts/platform-smoke/linux-image/Dockerfile +6 -3
- package/scripts/platform-smoke/platform-build-windows.ps1 +23 -3
- package/scripts/platform-smoke/suite-checks.mjs +11 -1
- package/scripts/platform-smoke/targets.mjs +4 -3
- package/scripts/platform-smoke.mjs +68 -25
package/docs/PERFORMANCE.md
CHANGED
|
@@ -166,9 +166,11 @@ launch time. See [the proof contract](REFERENCE.md#proof-and-verification).
|
|
|
166
166
|
### Journal and artifact storage
|
|
167
167
|
|
|
168
168
|
Journal projection uses the installed streaming parser's raw tokenizer instead of
|
|
169
|
-
building a Node stream pipeline for each record.
|
|
170
|
-
|
|
171
|
-
|
|
169
|
+
building a Node stream pipeline for each record. Live replay applies the same
|
|
170
|
+
native-or-token selection as its metadata scan to retained-size records; larger
|
|
171
|
+
records still use the tokenizer. Both paths validate UTF-8 and complete JSON,
|
|
172
|
+
including discarded values. The streaming path retains its explicit end-of-input
|
|
173
|
+
flush, and the parser is still loaded lazily.
|
|
172
174
|
|
|
173
175
|
Both offline converters retain a branch projection only until its last source
|
|
174
176
|
child consumes it. Linear histories no longer retain every historical state map;
|
|
@@ -197,6 +199,13 @@ not a cross-call cache. Replacement and unknown-generation checks remain
|
|
|
197
199
|
fail-closed; capture still obtains its distinct post-operation generation receipt.
|
|
198
200
|
Calls with no redundant observation keep their existing probes.
|
|
199
201
|
|
|
202
|
+
A call waiting for another Pi process's browser operation no longer starts a
|
|
203
|
+
process-identity query every 10 ms while that holder is confirmed alive. It sleeps
|
|
204
|
+
on the holder's owner-lifetime socket and re-runs normal arbitration when the
|
|
205
|
+
socket closes on release or exit. Unverifiable and still-choosing claims,
|
|
206
|
+
unavailable endpoints (including socket paths over the platform limit) and
|
|
207
|
+
native Windows keep polling. See [execution coordination](ARCHITECTURE.md).
|
|
208
|
+
|
|
200
209
|
Independent timeout-artifact retry windows now overlap. Each declared path still
|
|
201
210
|
gets up to three checks, 25 ms apart; results retain native plan order and page
|
|
202
211
|
inspection starts afterward. A file finishing after **its own** window may remain
|
package/docs/REFERENCE.md
CHANGED
|
@@ -8,7 +8,7 @@ It is for Pi users who want agents to browse sites, inspect pages, click through
|
|
|
8
8
|
|
|
9
9
|
## Pi release qualification
|
|
10
10
|
|
|
11
|
-
CI qualifies the latest stable official Pi and latest maintained fork `main`, resolving their version/commit once per run and retaining SDK/CLI identity evidence. Locked development dependencies are reproducible build snapshots, not qualification targets; runtime peers remain wildcard. `npm run check:compat` checks the installed candidate SDK/CLI identity, typechecks, runs the existing offline tests (including the native Pi pipeline with a controlled provider and fake browser), and tests a packed runtime-only installation through both the SDK and the actual bundled RPC CLI. It does not substitute a fork SDK while leaving official types or child CLI installed.
|
|
11
|
+
CI qualifies the latest stable official Pi and latest maintained fork `main`, resolving their version/commit once per run and retaining SDK/CLI identity evidence. Locked development dependencies are reproducible build snapshots, not qualification targets; runtime peers remain wildcard. The development snapshot overrides Undici to exact 8.12.3 because official Pi 1.0.2 through 1.4.0 pins exact Undici 8.10.2, which has the high/moderate advisories GHSA-xjj6-f33q-929c, GHSA-4qv8-2p9j-2685 and GHSA-f72v-6w45-q472; remove the override once the official development SDK depends on 8.12.2 or later. npm applies root overrides only where this repository is the npm root project: checkouts and Git-source installs, whose build-time development tree resolves 8.12.3. Published npm-package consumers never receive it, the extension does not import Undici at runtime, and qualified official Pi hosts keep their own Undici 8.10.2. `npm run check:compat` checks the installed candidate SDK/CLI identity, typechecks, runs the existing offline tests (including the native Pi pipeline with a controlled provider and fake browser), and tests a packed runtime-only installation through both the SDK and the actual bundled RPC CLI. It does not substitute a fork SDK while leaving official types or child CLI installed.
|
|
12
12
|
|
|
13
13
|
Run in an empty HOME with a **short** TMPDIR outside your real home. Long temporary paths can exceed macOS's 103-byte Unix socket limit; keep the fixture's socket safety checks intact. Native lifecycle controls, live upstream help sampling, lifecycle dogfood, and platform qualification remain the separate gates documented below. A Pi-only compatibility run uses no live browser profiles, credentials, or agent-browser fork, and does not certify those external integrations.
|
|
14
14
|
|
|
@@ -96,7 +96,7 @@ The result is optimized for agent work:
|
|
|
96
96
|
| Dashboard scroll commands can look successful while nothing moves | Handles standard `scroll <dir> [px]` against the document first (including pages whose smooth-scroll CSS defeats upstream wheel timing), falls back upstream when the document cannot move, and samples viewport/containers around the fallback; explicit CSS-container scrolling uses instant movement so smooth-scroll CSS cannot cause a premature no-movement failure; unchanged positions fail as `upstream-error` with `details.scrollNoop`, visible recovery guidance, and exact snapshot/screenshot checks. Unsupported `scrollintoview text=...` fails before dispatch, including inside effective batch rows, and shows exact native `find text ... hover` and snapshot/ref recovery payloads; help remains native pass-through. | [`docs/TOOL_CONTRACT.md`](TOOL_CONTRACT.md#details), [`docs/COMMAND_REFERENCE.md`](COMMAND_REFERENCE.md#core-page-and-element-commands), `test/agent-browser.extension-validation.test.ts` |
|
|
97
97
|
| Dropdown/combobox clicks can focus or hit native option box-model errors | Adds first-class `select <selector> <value...>` paths through native `args` and `agent_browser_action`; semantic role/name or label select resolves exactly one current visible combobox/listbox ref before action. Custom combobox clicks still detect focused controls with explicit `aria-expanded` state but no visible options and return `details.comboboxFocus` plus exact recovery `nextActions` | [`docs/TOOL_CONTRACT.md`](TOOL_CONTRACT.md#details), [`docs/COMMAND_REFERENCE.md`](COMMAND_REFERENCE.md#core-page-and-element-commands), `extensions/agent-browser/lib/input-modes/semantic-action.ts`, `test/agent-browser.extension-input-modes.test.ts`, `test/agent-browser.extension-validation.test.ts` |
|
|
98
98
|
| Recording workflows fail late when `ffmpeg` is missing or report stale lifecycle state | After successful `record start` / `record restart`, reports `successCategory: "artifact-pending"`, returns an exact `stop-pending-recording` action, warns when older natives report pending output without `ffmpeg`, and conservatively invalidates prior page-scoped `@e…` refs on every executed start attempt and URL-bearing restart to protect older supported natives. This is not evidence of a page change: 0.37 records the active page unless a URL is supplied; FPS-only calls keep the intended tab; an unbounded transcript-backed namespace/session index reserves active destinations across aliases, serializes artifact lifecycle and explicit wait/output writes, persists cross-branch close tombstones, retires every successful close path (including every matching namespace owner for `close --all`), rejects missing/stale restart output, coalesces terminal batch state, keeps only the newest pending path per identity, rejects recording starts after a nested close, folds Unicode path aliases, and retains exact cleanup actions with visible guidance on any later same-session failure | [`docs/TOOL_CONTRACT.md`](TOOL_CONTRACT.md#details), [`docs/COMMAND_REFERENCE.md`](COMMAND_REFERENCE.md#diff-debug-and-streaming), `test/agent-browser.extension-validation.test.ts`, `test/agent-browser.presentation-artifacts-batch.test.ts` |
|
|
99
|
-
| Upstream CLI drift can silently invalidate wrapper behavior | Publishes a repo-readable command reference, verifies it against the recommended 0.
|
|
99
|
+
| Upstream CLI drift can silently invalidate wrapper behavior | Publishes a repo-readable command reference, verifies it against the recommended 0.41.0 target, and probes browser-backed calls once per cwd/PATH so stable versions below the 0.35.0 floor fail before browser launch with installed/expected version evidence | `npm run verify` |
|
|
100
100
|
| Pages can expose structured workflows through experimental WebMCP | Shows native positive WebMCP availability in navigation summaries and passes through `webmcp list`, `invoke`, detached `result` / `cancel`, params/frame/timeout options, and the bundled `webmcp-gen` skill; treats `--no-webmcp` as launch-scoped, keeps pending or unsuccessfully settled targets unverified with an actionable `get url` follow-up, invalidates stale refs after page tools run, and budgets effective raw or stdin batch timeouts | [`docs/COMMAND_REFERENCE.md`](COMMAND_REFERENCE.md#webmcp-page-tools), `test/agent-browser.extension-ref-guards.test.ts`, `test/agent-browser.wait-timeouts.test.ts`, `test/agent-browser.real-upstream-contract.test.ts` |
|
|
101
101
|
| Desktop Electron apps need discovery, CDP attach, and safe teardown | `agent_browser_electron` runs host `list` / isolated `launch` (temp profile, OS-chosen debug port) / `status` / `probe` / `cleanup`, merges `launchId` plus managed `sessionName`, supports `handoff` `snapshot` / `tabs` / `connect`, and surfaces mismatch and post-command health guidance; wrapper cleanup applies only to launches it created | `extensions/agent-browser/lib/electron/discovery.ts`, `launch.ts`, `cleanup.ts`, [`docs/TOOL_CONTRACT.md`](TOOL_CONTRACT.md#agent_browser_electron), [`docs/COMMAND_REFERENCE.md`](COMMAND_REFERENCE.md#electron-desktop-apps) |
|
|
102
102
|
| Agents need bundled `skills` text and local setup/status commands without touching the live session | Treats `skills list/get/path`, local auth/profile/setup commands, `session list`, and local state lifecycle commands as sessionless reads/actions when upstream does not need a live page. Session/state rows and targets remain visible, and supported upstream state/config/path operations pass through unchanged. Browser-backed workflows still receive an implicit session only when the caller did not choose one. | [`docs/COMMAND_REFERENCE.md`](COMMAND_REFERENCE.md#built-in-skills), `extensions/agent-browser/lib/command-policy.ts`, `extensions/agent-browser/lib/runtime.ts` |
|
|
@@ -119,9 +119,9 @@ Optional external tools unlock the full command surface:
|
|
|
119
119
|
| `agent-browser` | All browser automation through this extension | See upstream install docs |
|
|
120
120
|
| `ffmpeg` | Recording WebM (libvpx) or MP4 (libx264); install before `record start` / `record restart` | `brew install ffmpeg` or `brew install ffmpeg-full` |
|
|
121
121
|
|
|
122
|
-
Keep both binaries on `PATH`. This package recommends `agent-browser 0.
|
|
122
|
+
Keep both binaries on `PATH`. This package recommends `agent-browser 0.41.0` and accepts stable versions at or above the 0.35.0 floor; browser-backed calls fail fast below that floor while local inspection/setup commands remain available for diagnosis. Native 0.37 validates `ffmpeg`, the output extension and FPS before recording; older supported natives may defer failures until stop. Use `record start <path.webm|path.mp4> [url] [--fps <n>]` (1–60 fps, default 30), then verify the completed file after `record stop`. Native `doctor` checks the recording dependency and encoders.
|
|
123
123
|
|
|
124
|
-
On 0.38
|
|
124
|
+
On 0.38+, use `snapshot --delta` for native full/unchanged/changed revisions and `snapshot --delta --full` to reset its baseline. Surviving DOM nodes keep their refs, but navigation/replaced nodes still require fresh refs. The wrapper preserves native revisions and refreshes complete refs internally for partial results. `screenshot --if-changed` (or `--threshold 0.01`) skips unchanged images without creating an artifact. `--input-mode instant|smooth|human` controls native session pointer movement; `click ... --human`, `drag ... --human`, and timed `mouse move` remain ordinary `args`. Recordings accept `--cursor` and `--contact-sheet`; the latter produces a timestamped PNG verified after stop. `auth login <name> --no-navigate` fills a prepared login page after upstream checks its origin. See the [command reference](COMMAND_REFERENCE.md#upstream-0381-rebaseline) for examples and limits.
|
|
125
125
|
|
|
126
126
|
### Android / Termux
|
|
127
127
|
|
|
@@ -203,7 +203,7 @@ npm run doctor
|
|
|
203
203
|
The doctor checks:
|
|
204
204
|
|
|
205
205
|
- upstream `agent-browser` exists on `PATH`
|
|
206
|
-
- the installed upstream is a stable version at or above the supported 0.35.0 floor; 0.
|
|
206
|
+
- the installed upstream is a stable version at or above the supported 0.35.0 floor; 0.41.0 remains the recommended baseline
|
|
207
207
|
- `pi --version` meets the minimum Pi runtime floor for this release; older Pi versions are setup failures
|
|
208
208
|
- Pi settings do not point at multiple active `pi-agent-browser-native` sources
|
|
209
209
|
|
|
@@ -554,7 +554,7 @@ Ordinary native config discovery stays at the project or current managed browser
|
|
|
554
554
|
|
|
555
555
|
### Shared browser defaults
|
|
556
556
|
|
|
557
|
-
Ordinary browser calls use one native named browser per **root Pi session**. A parent and its subagents share that browser; unrelated roots get different names and can browse concurrently. `pi-subagents`
|
|
557
|
+
Ordinary browser calls use one native named browser per **root Pi session**. A parent and its subagents share that browser; unrelated roots get different names and can browse concurrently. Current `pi-subagents` launches each child with equal `PI_INTERCOM_ROOT_SESSION_ID` and `PI_INTERCOM_PARENT_SESSION_ID` values naming its main session, including fresh and forked delegated runs; older releases supplied `PI_SUBAGENT_CHILD` with `PI_SUBAGENT_ROOT_SESSION_ID`, which remains supported. Ordinary Pi new/fork/clone sessions get their own root identity; resuming the same root or changing its cwd keeps its browser name.
|
|
558
558
|
|
|
559
559
|
Cooperating updated Pi processes share a cross-process lock keyed by the actual socket context, canonical namespace, and session. It covers a direct call's helpers and action, or an entire code call; different identities can run independently. Coordinate navigation across separate tool calls with existing subagent/intercom tools. This is ordering, not rollback or protection against human navigation, external CLI clients, or older extension versions. Parent or child exit does not close the group browser. Native idle policy applies; explicitly close only your group's browser when the group is finished.
|
|
560
560
|
|
|
@@ -709,7 +709,7 @@ The opt-in real-upstream suite is separate because it drives a real browser inst
|
|
|
709
709
|
npm run verify -- real-upstream
|
|
710
710
|
```
|
|
711
711
|
|
|
712
|
-
That mode sets `PI_AGENT_BROWSER_REAL_UPSTREAM=1` and runs `test/agent-browser.real-upstream-contract.test.ts` against the real `agent-browser` on `PATH` (the stable version must meet the 0.35.0 floor; current command-reference validation targets the recommended 0.
|
|
712
|
+
That mode sets `PI_AGENT_BROWSER_REAL_UPSTREAM=1` and runs `test/agent-browser.real-upstream-contract.test.ts` against the real `agent-browser` on `PATH` (the stable version must meet the 0.35.0 floor; current command-reference validation targets the recommended 0.41.0 capability baseline), selecting the sessionless plugin probe separately and then all remaining declarations, including explicit native text. It also runs `test/agent-browser.batch-fidelity.test.ts` and `test/agent-browser.overlay-real-upstream.test.ts` with the same opt-in environment. It covers inspection, skills, experimental WebMCP list/invoke/result/cancel plus `--no-webmcp`, and a broad core interaction and navigation matrix on localhost fixtures (including off-viewport click, frame-scoped selector/wait/click behavior, form command fixes, `batch` stdin, and `pushstate`), plus `vitals`, network route/requests/HAR, diff snapshot/screenshot/url, trace/profiler, console/errors/highlight, stream enable/status/disable, `cookies set --curl`, a `react tree` missing-renderer path, and `wait --download` with the on-disk caveat documented in release notes. The harness uses a throwaway temp `HOME` and dedicated socket/screenshot directories so the run does not touch your normal browser profile paths. Browser-opening or credential-dependent families such as `inspect`, `dashboard`, `chat`, provider clouds, and OS clipboard flows stay in fake-upstream or manual validation unless a safe deterministic fixture is added. For prerequisites, isolation details, and troubleshooting, see [`docs/RELEASE.md`](RELEASE.md#real-upstream-contract-validation).
|
|
713
713
|
|
|
714
714
|
A deterministic host-only live-browser wrapper smoke is available without an LLM choosing tool calls:
|
|
715
715
|
|
|
@@ -729,7 +729,7 @@ npm run smoke:platform:doctor
|
|
|
729
729
|
npm run verify -- release
|
|
730
730
|
```
|
|
731
731
|
|
|
732
|
-
`npm run verify -- release` includes the default verification gate, packaged Pi smoke coverage, and the release-blocking Crabbox platform matrix (the same matrix `npm run smoke:platform:all` runs standalone). For the full maintainer release flow, follow [`docs/RELEASE.md`](RELEASE.md). The package also has a `prepublishOnly` hook that runs the same release gate and `npm pack --dry-run` during `npm publish`.
|
|
732
|
+
`npm run verify -- release` includes the default verification gate, the configured-source lifecycle harness, packaged Pi smoke coverage, and the release-blocking Crabbox platform matrix (the same matrix `npm run smoke:platform:all` runs standalone). For the full maintainer release flow, follow [`docs/RELEASE.md`](RELEASE.md). The package also has a `prepublishOnly` hook that runs the same release gate and `npm pack --dry-run` during `npm publish`.
|
|
733
733
|
|
|
734
734
|
## How it works
|
|
735
735
|
|
|
@@ -742,12 +742,12 @@ npm run verify -- release
|
|
|
742
742
|
5. Screenshots, downloads, recordings, traces, profiles, and spill files are normalized as Pi-visible artifacts where possible.
|
|
743
743
|
6. Generated playbook text in docs and browser instructions stays aligned with `extensions/agent-browser/lib/playbook.ts`.
|
|
744
744
|
|
|
745
|
-
The upstream browser engine remains [`agent-browser`](https://agent-browser.dev/). This package does not bundle it. The recommended baseline is 0.
|
|
745
|
+
The upstream browser engine remains [`agent-browser`](https://agent-browser.dev/). This package does not bundle it. The recommended baseline is 0.41.0 and the stable runtime floor is 0.35.0; newer stable versions are accepted without version-specific compatibility shims.
|
|
746
746
|
|
|
747
747
|
## Current limits
|
|
748
748
|
|
|
749
749
|
- Published pre-1.0 package.
|
|
750
|
-
- Recommends upstream `agent-browser` 0.
|
|
750
|
+
- Recommends upstream `agent-browser` 0.41.0 and accepts stable runtimes at or above 0.35.0.
|
|
751
751
|
- Does not bundle `agent-browser`; users install it separately.
|
|
752
752
|
- Does not provide a human browser UI inside Pi; the primary UX is agent-invoked tool calls. `--headed` asks upstream to show a browser window, but the wrapper cannot yet prove that the window is visible on the user's desktop.
|
|
753
753
|
- Localhost means the browser host's loopback, not necessarily the shell/Pi host. If `http://localhost:<port>` or `http://127.0.0.1:<port>` fails with errors such as `ERR_EMPTY_RESPONSE`, use an environment-specific host-reachable HTTP(S) address. A `file://` fixture is supported when upstream browser launch settings allow it; use HTTP(S) only when the browser environment cannot reach the local file.
|
|
@@ -757,11 +757,11 @@ The upstream browser engine remains [`agent-browser`](https://agent-browser.dev/
|
|
|
757
757
|
|
|
758
758
|
## Automatic npm releases (maintainers)
|
|
759
759
|
|
|
760
|
-
|
|
760
|
+
The [shared release procedure](https://github.com/fitchmultz/.github#automatic-npm-releases) creates a reviewed patch-version PR after changes merge to `main`, then publishes the same version on npm and GitHub using the exact qualified candidate tarball.
|
|
761
761
|
|
|
762
|
-
|
|
762
|
+
Check the final source and candidate against [the existing release gates](RELEASE.md#pre-release-checks), including required lifecycle/live-site evidence and artifact checks. Complete enabled reviews and resolve their findings. Apply the documented Windows waiver without claiming a Windows or full composed-gate pass. Workflow validation is not evidence that publication completed on either service.
|
|
763
763
|
|
|
764
|
-
|
|
764
|
+
Set repository variable `NPM_RELEASE_ENABLED` to anything other than `true` to stop new version and release plans; cancel pending runs separately when needed. Follow the shared procedure to retry an unpublished candidate.
|
|
765
765
|
|
|
766
766
|
## Local development
|
|
767
767
|
|
|
@@ -789,7 +789,7 @@ Configured-source lifecycle validation:
|
|
|
789
789
|
npm run verify -- lifecycle
|
|
790
790
|
```
|
|
791
791
|
|
|
792
|
-
The harness defaults to Pi model `zai/glm-5.2` and **180000 ms** per-step tmux waits; pass `--model <id>` and/or `--timeout-ms <ms>` after `lifecycle` when you need different settings (see [Configured-source lifecycle validation](RELEASE.md#configured-source-lifecycle-validation) in `docs/RELEASE.md`). It launches the supported Pi runtime with `--approve` and a deterministic `--session-id`, drives `/reload`, closes Pi, relaunches the exact same session, asserts the JSONL header id, and checks managed-session continuity, compiled-entrypoint pickup after process restart, persisted spill reachability, and native returned failure status and JSON preservation.
|
|
792
|
+
The harness defaults to Pi model `zai/glm-5.2` and **180000 ms** per-step tmux waits; pass `--model <id>` and/or `--timeout-ms <ms>` after `lifecycle` (or after `release`, which forwards them only to its lifecycle step) when you need different settings (see [Configured-source lifecycle validation](RELEASE.md#configured-source-lifecycle-validation) in `docs/RELEASE.md`). It launches the supported Pi runtime with `--approve` and a deterministic `--session-id`, drives `/reload`, closes Pi, relaunches the exact same session, asserts the JSONL header id, and checks managed-session continuity, compiled-entrypoint pickup after process restart, persisted spill reachability, and native returned failure status and JSON preservation.
|
|
793
793
|
|
|
794
794
|
Use lifecycle validation when testing `/reload`, exact-session relaunch, `/resume`, managed-session continuity, or persisted artifact behavior. Branch-backed state and `session_tree` cleanup ownership are covered by focused extension harness tests. Maintainers must run the lifecycle harness before every publish; see [Pre-release checks](RELEASE.md#pre-release-checks).
|
|
795
795
|
|
package/docs/RELEASE.md
CHANGED
|
@@ -18,11 +18,21 @@ Related docs:
|
|
|
18
18
|
|
|
19
19
|
Provide one concrete maintainer workflow for validating repo state, package contents, and install guidance before publishing `pi-agent-browser-native`.
|
|
20
20
|
|
|
21
|
+
## Native Windows: best-effort
|
|
22
|
+
|
|
23
|
+
The owner explicitly decided on 2026-10-22: **“Make native Windows explicitly a best effort.”** This supersedes [#191](https://github.com/fitchmultz/pi-agent-browser-native/issues/191) / PR291's restored blocking policy, not its failure evidence. Native Windows is not a first-class required PR, scheduled-default, or release qualification target. Known process-lock and restored Electron cleanup failures remain unresolved; no runtime repair is claimed.
|
|
24
|
+
|
|
25
|
+
Routine Pi compatibility retains one latest-official-host Windows build/import/process-transport smoke with job-level `continue-on-error: true`. Its failed steps, TAP and artifacts remain failed evidence, not a pass inferred from overall workflow success. It does not run `check:compat`, full unit/serial or consumer suites, build the corrected checker, or invoke models. Broader official/fork native Windows qualification is available only from manual Pi compatibility dispatch with `windows-qualification=true`; those job-level best-effort lanes retain their existing environment self-check, full contracts, Git/npm consumers and failed artifacts. Release callers cannot opt into these deep lanes. Missing or skipped evidence is not passed.
|
|
26
|
+
|
|
27
|
+
Required macOS/Linux, latest official/fork host/API/consumer qualification, Native lifecycle Linux, quality, Node floors, assertion/deadline/generation/ownership/security contracts remain unchanged. Local release/prepublish and default platform doctor/run select configured required macOS/Ubuntu targets only; optional Windows/Parallels setup cannot block that path. Explicit `windows-native` commands remain strict and nonzero on failure. Branch-protection/settings changes are separate and are not made by this PR.
|
|
28
|
+
|
|
29
|
+
Windows contract-test children enable only `NODE_DEBUG=pi-agent-browser-policy` inside the repository-owned `scripts/project.mjs` launcher used by `npm test` and the default/quality verification gates. This assignment happens **after** the pinned qualifier creates its isolated base environment; setting `NODE_DEBUG` or `NODE_OPTIONS` only on the outer workflow would be stripped and is not evidence that diagnostics ran. Build/preparation stages and ordinary runtime consumers do not enable the channel. The `npm test` gate retains complete parallel TAP and single-worker serial TAP stages, ordered and fail-blocking. Failed Windows jobs print at most 400 exact `PI-AGENT-BROWSER-POLICY <pid>:` stderr matches (including TAP-wrapped child stderr), report total/shown/omitted counts, and retain the complete `qualification.log` alongside the unchanged bounded failed-TAP diagnostics. Neither collection nor debug enablement changes coordination behavior, retries, test selection, or budgets.
|
|
30
|
+
|
|
21
31
|
## Current 0.6.16 rollout waiver
|
|
22
32
|
|
|
23
|
-
The owner's 2026-09-21 **“waive windows”** instruction
|
|
33
|
+
This heading retains historical links. The owner's 2026-09-21 **“waive windows”** instruction made Windows qualification nonblocking for that rollout, even with available runners. It did not establish a Windows pass. The later [#191](https://github.com/fitchmultz/pi-agent-browser-native/issues/191) restoration replaced that CI exception at the time. The current best-effort support decision above now supersedes that restoration policy; neither decision erases failures. Do not reuse the September waiver as current authority. Known policy-lock/restored Electron failures and bounded repeat results remain recorded in the [support matrix](SUPPORT_MATRIX.md#current-0616-rollout).
|
|
24
34
|
|
|
25
|
-
Linux/macOS, declared Node floors, official/fork host and consumer-artifact checks,
|
|
35
|
+
Linux/macOS, declared Node floors, official/fork host and consumer-artifact checks, Native lifecycle Linux, and the composed `release`/`prepublishOnly` scripts remain required. Retain all failed attempts. A hosted Windows contract pass is not a native browser dogfood or complete release-matrix pass.
|
|
26
36
|
|
|
27
37
|
Docs/workflow-only changes may reuse prior live/platform evidence when the complete compiled runtime, runtime dependencies and relevant tests are unchanged. Changed published files require a new retained tarball checked by `verify-package.mjs --smoke-pi`, including runtime-only SDK and actual CLI loading. Publish those exact checked bytes without repacking.
|
|
28
38
|
|
|
@@ -30,7 +40,7 @@ Docs/workflow-only changes may reuse prior live/platform evidence when the compl
|
|
|
30
40
|
|
|
31
41
|
This contract requires Pi 1.0.0. Do not install or activate it in running pre-1.0 sessions; coordinate the runtime cutover and restart participating agents first. Keep runtime activation separate from isolated checkout/SDK qualification. Preserve auth/profile/state files, explicit artifacts and Pi journals when updating or rolling back; browser mutations are not reversible through a package rollback.
|
|
32
42
|
|
|
33
|
-
Qualify the exact official and fork host graphs independently, including SDK and actual CLI loading, explicit/defaultTools/loader/initial-resume/tree/reload selections, structured success/failure/redaction and unchanged JSON. Inspect regular and fullscreen native TUI results, including failures and images. Keep the existing 250 ms import/factory and 1,000 ms lock budgets; synthetic research timings are not final-source release evidence or universal performance guarantees. Apply normal release gates
|
|
43
|
+
Qualify the exact official and fork host graphs independently, including SDK and actual CLI loading, explicit/defaultTools/loader/initial-resume/tree/reload selections, structured success/failure/redaction and unchanged JSON. Inspect regular and fullscreen native TUI results, including failures and images. Keep the existing 250 ms import/factory and 1,000 ms lock budgets; synthetic research timings are not final-source release evidence or universal performance guarantees. Apply normal required macOS/Linux release gates; Windows is separately labeled best-effort. Host identity and actual supported APIs, not a version label alone, determine qualification.
|
|
34
44
|
|
|
35
45
|
## 0.7 upgrade and rollback
|
|
36
46
|
|
|
@@ -46,7 +56,7 @@ The minimum Pi runtime is 1.0.0, matching the native APIs used by the new tool c
|
|
|
46
56
|
|
|
47
57
|
Qualify official Pi 1.0 and the fork independently with the existing host/package/lifecycle infrastructure. Required evidence for the redesign includes compact schema and additive activation/history, native prompt sections, shared direct/code auth continuity, fresh JavaScript globals, selected real images and conservative geometry, visible handled failures/exact recovery, real cross-process helper/action and whole-cell ordering, cancellation/reaping, and ordered transition replay after interruption/branch changes. Retain native batch and advanced action/QA/Electron/source outcome coverage. Small synthetic timing comparisons are not universal performance claims or sandbox certification.
|
|
48
58
|
|
|
49
|
-
|
|
59
|
+
Routine GitHub PR and release-call checks include a nonblocking Windows build/import/process smoke; deep official/fork Windows qualification and its environment self-check are manual-only. Retain every failed attempt, including historical waived diagnostics, without claiming a Windows pass from an aggregate that ignored failures. These focused checks complement, rather than replace, the local release and publication gates.
|
|
50
60
|
|
|
51
61
|
## Pre-release checks
|
|
52
62
|
|
|
@@ -76,9 +86,22 @@ npm run verify -- pre-pr
|
|
|
76
86
|
1. `npm run verify` for generated playbook drift, TypeScript, unit/fake coverage, command-reference generated-block drift, and live command-reference verification against the targeted upstream on `PATH`
|
|
77
87
|
2. `npm run verify -- lifecycle`, which launches the configured-source lifecycle harness for `/reload`, exact `--session-id` relaunch, managed-session continuity, persisted spill reachability, and native returned-failure behavior
|
|
78
88
|
3. `npm run verify -- package-pi`, which first validates package contents via `npm pack --json --dry-run` and then smoke-loads the packed package in Pi isolation
|
|
79
|
-
4. `npm run smoke:platform:doctor` and the
|
|
89
|
+
4. `npm run smoke:platform:doctor` and the required Crabbox matrix from [`platform-smoke.md`](platform-smoke.md): macOS SSH and Ubuntu local-container targets running fast target-local `platform-build` plus `browser-dogfood-smoke`
|
|
90
|
+
|
|
91
|
+
Lifecycle options can follow `release`: `--model <id>`, `--timeout-ms <ms>`, `--verbose`, and `--keep-artifacts` reach only step 2. Other options and invalid lifecycle values fail before any step runs. For example, `npm run verify -- release --model <provider>/<model>` runs the complete gate with the lifecycle prompts on that model. Without options, step 2 keeps the lifecycle defaults.
|
|
92
|
+
|
|
93
|
+
When release automation has already prepared a candidate, supply its retained tarball to the same complete gate:
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
PI_AGENT_BROWSER_RELEASE_TARBALL=/absolute/path/to/candidate.tgz \
|
|
97
|
+
npm run verify -- release --keep-artifacts --verbose
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Package verification inspects the supplied archive and its packaged Markdown, checks its name, version, and integrity, and installs a private copy of those same bytes for the isolated Pi smoke. The configured-source lifecycle installs a private copy of the candidate and adds its test-only sentinel to that copy's compiled entrypoint for reload/relaunch checks. The required platform-build suites still pack their target-local checkout, then install the supplied candidate and check its SHA-256 before and after installation on each target. The verifier does not rebuild or delete the supplied file. The caller must compare the candidate with the shared preparation receipt before and after qualification and publish those verified bytes.
|
|
101
|
+
|
|
102
|
+
The reusable `release-qualification.yml` runs the same candidate against the selected official and fork Pi hosts. It runs the default verification and package/lifecycle checks, plus `scripts/verify-live-sites.mjs`: an interactive Pi session visits CERN and React documentation, navigates an observed ref, verifies a screenshot delivered to a vision model, reloads, and closes its owned browser. The hosted checks use `zai/glm-5.3-flash` with `ZAI_API_KEY` from the main-only `release` environment. The macOS SSH and Ubuntu container Crabbox jobs run both required suites on separate native runners, each checking the candidate identity before and after. Windows remains best-effort.
|
|
80
103
|
|
|
81
|
-
When using the documented, maintainer-approved [local macOS alternative](platform-smoke.md#alternate-native-transports), run and inspect that target-local suite separately alongside the remaining release checks. The default
|
|
104
|
+
When using the documented, maintainer-approved [local macOS alternative](platform-smoke.md#alternate-native-transports), run and inspect that target-local suite separately alongside the remaining release checks. The default composition still requires macOS/Ubuntu; alternate evidence must not be labeled a passing Crabbox matrix.
|
|
82
105
|
|
|
83
106
|
`npm publish` runs npm’s `prepublishOnly` script from `package.json`, which executes the same `npm run verify -- release` gate and then `npm pack --dry-run`. That concatenated gate is everything in the default `npm run verify` step (generated playbook drift, clean `dist/` build, TypeScript, the unit/fake suite, generated command-reference blocks, and live upstream command-reference sampling against the targeted `agent-browser` on `PATH`), the configured-source lifecycle harness, the packaged Pi smoke in `package-pi`, and the release-blocking Crabbox platform matrix. Using `npm publish --ignore-scripts` skips that contract intentionally.
|
|
84
107
|
|
|
@@ -252,7 +275,7 @@ Run the automated harness for deterministic configured-source lifecycle regressi
|
|
|
252
275
|
npm run verify -- lifecycle
|
|
253
276
|
```
|
|
254
277
|
|
|
255
|
-
The harness creates an isolated `PI_CODING_AGENT_DIR`, writes settings with exactly one temporary configured package source, runs `pi`
|
|
278
|
+
The harness creates an isolated `PI_CODING_AGENT_DIR`, writes settings with exactly one temporary configured package source, runs `pi` on its own `tmux` server with `--approve`, default model **`zai/glm-5.2`**, and a deterministic `--session-id`, so Pi inherits the verify process environment (the isolated agent directory stores no credentials; export the selected model's provider credentials before running the harness), puts a deterministic fake `agent-browser` first on `PATH`, starts an explicit `sessionMode: "fresh"` managed browser, drives `/reload`, closes Pi, and relaunches with the same exact session id instead of typing `/resume`. It also asserts the JSONL session header id, same-page managed-session continuity, compiled JS code pickup after full process relaunch, persisted spill reachability, and native returned `isError` and JSON-preservation semantics for a QA reclassification. Per-step tmux waits default to **180000 ms** (three minutes) in [`scripts/verify-lifecycle.mjs`](https://github.com/fitchmultz/pi-agent-browser-native/blob/main/scripts/verify-lifecycle.mjs) (`DEFAULT_TIMEOUT_MS`); override with `--timeout-ms <ms>` when slower models or cold starts need more headroom. Override the model when needed:
|
|
256
279
|
|
|
257
280
|
```bash
|
|
258
281
|
npm run verify -- lifecycle --model openai-codex/gpt-5.5:minimal
|
|
@@ -279,7 +302,7 @@ These show up often in cloud dev boxes and scripted smokes; they are maintainer
|
|
|
279
302
|
| **`pi -p` / print mode** | Non-interactive `pi -p` may hang or emit no stdout for long real-browser smokes without a TTY. | Use **tmux**-driven interactive `pi` for release evidence and checkout smokes; reserve `-p` for short, non-browser checks. |
|
|
280
303
|
| **Real-browser cleanup** | `real-upstream`, Sauce Demo, and live-site runs can leave defunct Chrome/`agent-browser` children if a session aborts mid-flow. | Close only test-owned browsers via `agent_browser` / `agent-browser` `close`, stop this run's tmux sessions, and remove its disposable screenshots/HARs. Preserve unrelated resources and retained evidence. |
|
|
281
304
|
| **Automated prompt driving** | Grepping tmux pane text for words that also appear in the **user** prompt (`PASS`, `FAIL`, `checkout overview`, `Smoke result:`) can false-complete before the agent finishes. | Wait for pane idle (no `Working…`), `agent_browser close` / `Artifact lifecycle`, or JSONL tool results—not instruction phrases copied from the prompt. |
|
|
282
|
-
| **Lifecycle verify flags** | `npm run verify -- lifecycle
|
|
305
|
+
| **Lifecycle verify flags** | `npm run verify -- lifecycle` or `release` exits with a usage error before any step runs when `--model` or `--timeout-ms` lacks a value or the timeout is not a positive integer; the facade uses `scripts/verify-lifecycle.mjs`'s parser. | Always pair flags with values (`--model openai-codex/gpt-5.5:minimal`, `--timeout-ms 600000`) or omit `--model` / `--timeout-ms` to keep the harness defaults (`zai/glm-5.2`, **180000 ms** per-step waits). |
|
|
283
306
|
|
|
284
307
|
Manual validation remains useful for release confidence and installed-package checks:
|
|
285
308
|
|
|
@@ -290,7 +313,7 @@ Manual validation remains useful for release confidence and installed-package ch
|
|
|
290
313
|
|
|
291
314
|
### Real upstream contract validation
|
|
292
315
|
|
|
293
|
-
The default `npm test` and `npm run verify` paths use deterministic tests and fake binaries in two stages: `tsx --test "test/**/!(*.serial).test.ts"` at Node's default file concurrency, then `tsx --test --test-concurrency=1 "test/**/*.serial.test.ts"` for strict timing budgets and shared policy-collector fixtures. The browser harness isolates each process's socket root; build/pack fixtures use disposable source trees so parallel consumers retain immutable checkout `dist/`. For a focused single-file rerun, use `npx tsx --test test/<file>.test.ts`; `npm test
|
|
316
|
+
The default `npm test` and `npm run verify` paths use deterministic tests and fake binaries in two stages: `tsx --test "test/**/!(*.serial).test.ts"` at Node's default file concurrency, then `tsx --test --test-concurrency=1 "test/**/*.serial.test.ts"` for strict timing budgets and shared policy-collector fixtures. The browser harness isolates each process's socket root; build/pack fixtures use disposable source trees so parallel consumers retain immutable checkout `dist/`. For a focused single-file rerun, use `npx tsx --test test/<file>.test.ts`; `npm test` rejects extra paths and options so the complete gate cannot silently become a filtered run. When a change touches upstream command planning, result presentation, managed-session behavior, or the canonical capability baseline, also run the opt-in real-upstream contract suite:
|
|
294
317
|
|
|
295
318
|
```bash
|
|
296
319
|
npm run verify -- real-upstream
|
|
@@ -300,9 +323,9 @@ That npm script sets `PI_AGENT_BROWSER_REAL_UPSTREAM=1`, runs the sessionless pl
|
|
|
300
323
|
|
|
301
324
|
This suite requires the installed stable `agent-browser --version` to meet the minimum in `scripts/agent-browser-target.mjs`; the output-shape fixture and command-reference verifier remain aligned to the current recommended baseline. It serves fixture pages from localhost and checks stable `details`/`data` keys via `test/fixtures/agent-browser-real-output-shapes.json`. Coverage groups:
|
|
302
325
|
|
|
303
|
-
- **Inspection and skills (stateless JSON):** `--version`, `--help`, `snapshot --help`, `skills list`, `skills get … --full` (including `webmcp-gen` on the 0.
|
|
326
|
+
- **Inspection and skills (stateless JSON):** `--version`, `--help`, `snapshot --help`, `skills list`, `skills get … --full` (including `webmcp-gen` on the 0.41.0 target), `skills path …` (no managed `sessionName` / `usedImplicitSession`).
|
|
304
327
|
- **Native 0.38 observation/recording:** full/unchanged delta snapshots, persistent refs, partial batch ref follow-ups, conditional screenshot suppression, sticky pointer mode and timed mouse movement, cursor recording and verified contact-sheet output. These options are skipped when explicitly validating the older stable floor.
|
|
305
|
-
- **WebMCP target contract:** on the 0.
|
|
328
|
+
- **WebMCP target contract:** on the 0.41.0 target, `webmcp list`, `invoke` with params/frame selection, detached `result` / `cancel`, ref invalidation after page tools, and a separate fresh launch with `--no-webmcp` returning an empty list.
|
|
306
329
|
- **Navigation metadata and native tab setup:** plain pages stay quiet; a page with tools retains positive native `data.webmcp` and shows the `webmcp list` hint. New tabs inherit configured headers before their first request, and clearing headers removes them on the next tab. No wrapper inheritance code is involved.
|
|
307
330
|
- **Recording FPS paths and pinning:** the opt-in `test/agent-browser.batch-fidelity.test.ts` native case checks direct/raw/stdin preflight before dispatch, actual start/restart destinations and pinned targets with leading `--fps`, conservative start-ref protection, FPS-only restart continuity, and valid 12-fps WebM output after explicitly logged 12-second fixture captures. Run it with `PI_AGENT_BROWSER_REAL_UPSTREAM=1`; it requires native 0.37 or newer. Keep focused older-native controls for fresh-page starts and the start-then-ref batch latch when changing that policy.
|
|
308
331
|
- **Managed session core and safe diagnostic matrix:** fresh `open` on the contract fixture, then implicit reuse across `eval --stdin`, `snapshot -i`, interaction commands (`click`, `dblclick`, `fill`, `type`, `type --clear --delay`, `focus`, `keyboard` with `type` / `inserttext`, `press`, `hover`, `check`, `uncheck`, `select`, failed `select` no-match, `upload`, `drag`, `mouse`, `scroll`, off-viewport click, `scrollintoview`, `wait` on selectors in the main frame and a selected iframe), extraction (`get` variants, `is` variants, `find label … fill` via native `<label>`, `aria-label`, and `aria-labelledby`, inline `eval`), file outputs (`screenshot`, `pdf`), navigation (`back`, `forward`, `reload`, `tab list`, another `open` to the same fixture), `batch` stdin, `pushstate`, `vitals … --json`, network route/requests/HAR, diff snapshot/screenshot/url, trace/profiler, console/errors/highlight, stream enable/status/disable, and `cookies set --curl`.
|
|
@@ -310,7 +333,7 @@ This suite requires the installed stable `agent-browser --version` to meet the m
|
|
|
310
333
|
- **Confirmation continuity:** the focused `contract suite matches confirmation launch policy surviving native nextActions` case follows exact confirm/deny actions without policy argv, checks a useful compound audit across resume followed immediately by title/body reads without a repairing URL getter, retains the native daemon PID on bare getters, and preserves an active recording and destination sentinel after denying restart. The nested recording-restart/navigation subcase requires the pinned native recording-policy patch; stock 0.38.1 skips only that subcase. With that patched binary first on `PATH`, run `PI_AGENT_BROWSER_REAL_UPSTREAM=1 PI_AGENT_BROWSER_NATIVE_COMPOUND_POLICY=1 node --import tsx --test --test-force-exit --test-name-pattern 'confirmation launch policy' test/agent-browser.real-upstream-contract.test.ts`. Both variables are test selectors, not runtime configuration. Focused read-confirmation, cold-resume, session-page-state and managed-daemon-policy owners additionally cover exact generic/native-read provenance, forged/foreign controls, completed click/tab and failed-inner action reconciliation, confirmed-close replay, definite unestablished policy requests and pending cold helper exposure. Qualify actual SDK resume plus immediate title/body follow-ups without a repairing getter; helpers must not replace the original native pending slot.
|
|
311
334
|
- **Cold first-read continuity:** the focused `contract suite matches cold URL reopen after quit` case starts an explicit `sessionMode: "fresh"` managed browser, runs actual quit cleanup, waits for the exact old daemon to exit, reloads the saved branch, and requests `snapshot -i` before any explicit navigation. Empty storage and origin storage must both reach their remembered non-root URL, report fresh refs in the main frame, and retain storage without pretending to retain unsaved forms or JavaScript memory. Separate deterministic cold-resume/boundary tests cover first `get url` and history commands, non-page daemon-starting calls and batch prefixes, hash routes, pending-state transcript replay, live missing tabs versus explicit URL destinations, close retirement, and caller-owned/attached/restore-disabled boundaries. Those fake-upstream checks do not replace native-browser or real Pi lifecycle qualification of the complete candidate.
|
|
312
335
|
- **Failure shape:** `react tree` on a page opened with `--enable react-devtools` but without a React app (expects a clear missing-renderer error with session-bound `details`).
|
|
313
|
-
- **Async download:** `open` on the `/download` fixture, anchor-triggered export, then `wait --download <path>`
|
|
336
|
+
- **Async download:** `open` on the `/download` fixture, anchor-triggered export, then `wait --download <path>` with version-specific assertions: native 0.39.4+ must save the exact bytes with verified wrapper artifacts, while supported 0.35.0–0.39.3 natives only report the requested path and must fail closed as `artifact-missing`. The batch operand owner also covers `--download` / `-d` after interleaved timeout flags. Missing-file failures remain covered independently by the artifact-presentation owner.
|
|
314
337
|
|
|
315
338
|
The default unit suite also runs `agentBrowserExtension passes through core command coverage fallback matrix` in [`test/agent-browser.extension-passthrough-native-commands.test.ts`](https://github.com/fitchmultz/pi-agent-browser-native/blob/main/test/agent-browser.extension-passthrough-native-commands.test.ts): a fake upstream records argv so explicit `--session connector connect 9222`, plus `download` with a selector and path, `get url`, `snapshot --compact`, and `tab new` / `tab t1` / `tab close` on implicit managed sessions, still prove `--json` and session ordering without a browser. A second fake-upstream matrix in [`test/agent-browser.extension-passthrough-debug-providers.test.ts`](https://github.com/fitchmultz/pi-agent-browser-native/blob/main/test/agent-browser.extension-passthrough-debug-providers.test.ts) (`agentBrowserExtension passes through non-core network debug diff stream dashboard and chat families`) pins representative `network`, `diff`, `trace` / `profiler` / `record`, `console` / `errors` / `highlight` / `inspect` / `clipboard`, `stream`, `dashboard`, and `chat` JSON shapes plus redacted `details.data` and argv echoes without a browser. Its `agentBrowserExtension passes through provider workflows` matrix asserts provider `open` argv shapes still receive `--json` plus implicit `--session` and provider credential env vars are forwarded into the fake upstream log, while `agentBrowserExtension keeps skills inspection flows stateless and useful` in the native-commands file keeps read-only `skills get …` stateless (no managed session fields). Extend those matrices when adding passthrough coverage that should stay out of the slow real-upstream loop.
|
|
316
339
|
|
|
@@ -332,13 +355,13 @@ node --test test/agent-browser.native-lifecycle.test.mjs
|
|
|
332
355
|
|
|
333
356
|
#### Routine GitHub PR checks
|
|
334
357
|
|
|
335
|
-
[`.github/workflows/pi-compatibility.yml`](https://github.com/fitchmultz/pi-agent-browser-native/blob/main/.github/workflows/pi-compatibility.yml) runs on PRs to `main`, manual dispatch, and release workflow calls. It resolves the latest stable official Pi version and latest maintained fork `main` commit once, or accepts those exact identities from the enclosing release run. Independent required Ubuntu jobs qualify each selected host's complete installed dependency graph on Node 24.21.0. Each runs `check:compat` once: host identity, typecheck, the full offline suite, and packed SDK/CLI loading. A parallel macOS Node 24.21.0 job typechecks and checks the packed Pi load against the same latest official graph without repeating the full suite. The host selector uses the immutable, reviewed `fitchmultz/.github` automation scripts; that automation pin is not a Pi qualification target. Locked development snapshots and the support floor are not validation lanes, and neither host is skipped based on a floor comparison.
|
|
358
|
+
[`.github/workflows/pi-compatibility.yml`](https://github.com/fitchmultz/pi-agent-browser-native/blob/main/.github/workflows/pi-compatibility.yml) runs on PRs to `main`, manual dispatch, and release workflow calls. It resolves the latest stable official Pi version and latest maintained fork `main` commit once, or accepts those exact identities from the enclosing release run. Independent required Ubuntu jobs qualify each selected host's complete installed dependency graph on Node 24.21.0. Each runs `check:compat` once: host identity, typecheck, the full offline suite, and packed SDK/CLI loading. A parallel macOS Node 24.21.0 job typechecks and checks the packed Pi load against the same latest official graph without repeating the full suite. One job-level nonblocking `windows-latest` lane builds/imports the compiled extension and runs the existing process-transport test on the resolved official host. It has a 15-minute job bound and a 10-minute smoke-step bound; there is no checker build or full contract/consumer campaign. A single Ubuntu fork-package build still supplies verified artifacts to required Linux and explicitly selected deep Windows qualification. The host selector uses the immutable, reviewed `fitchmultz/.github` automation scripts; that automation pin is not a Pi qualification target. Locked development snapshots and the support floor are not validation lanes, and neither host is skipped based on a floor comparison.
|
|
336
359
|
|
|
337
|
-
For native startup and consumer qualification, dispatch Pi compatibility with `native-qualification=true`. This runs the repository's entry in the pinned shared `fleet.json
|
|
360
|
+
For native startup and consumer qualification, dispatch Pi compatibility with `native-qualification=true`. This runs the repository's entry in the pinned shared `fleet.json` for official/fork hosts on latest Node 24.x across `ubuntu-latest` and `macos-latest`, instead of repeating the routine package jobs. `waived-platforms: false` excludes the shared workflow's Windows diagnostics. To select this repository's separate best-effort full Windows matrix, explicitly set `windows-qualification=true` on manual dispatch; otherwise deep Windows lanes are not run. `official-version` and `fork-ref` optionally select exact hosts; blank values resolve current stable/main once. The source is the dispatch commit. The native qualification lanes retain full contracts and actual Git/npm SDK/CLI consumers; the separately labeled routine Windows smoke does not. On-demand full Windows enables Git long paths on its disposable runner so isolated checker-source/submodule checkouts are not cut off at MAX_PATH. Repository attributes keep reviewed checker patches in canonical LF form even with native Git CRLF conversion; patch application is not relaxed. It additionally requires the pinned native process-identity environment self-check before contract dispatch, preserving its existing PID/start-time and timing assertions.
|
|
338
361
|
|
|
339
|
-
[`.github/workflows/native-lifecycle.yml`](https://github.com/fitchmultz/pi-agent-browser-native/blob/main/.github/workflows/native-lifecycle.yml) runs the separate **Native lifecycle Linux** gate through [`scripts/ci-native-lifecycle.sh`](https://github.com/fitchmultz/pi-agent-browser-native/blob/main/scripts/ci-native-lifecycle.sh). It independently checks out the PR head, selects the latest official graph using its once-resolved version (or the exact version supplied by the enclosing release run), builds the compiled extension on Node **24.21.0**, and runs portable native SDK lifecycle checks against isolated loopback browser fixtures. It replaces the fork-only checkpoint gate and requires all
|
|
362
|
+
[`.github/workflows/native-lifecycle.yml`](https://github.com/fitchmultz/pi-agent-browser-native/blob/main/.github/workflows/native-lifecycle.yml) runs the separate **Native lifecycle Linux** gate through [`scripts/ci-native-lifecycle.sh`](https://github.com/fitchmultz/pi-agent-browser-native/blob/main/scripts/ci-native-lifecycle.sh). It independently checks out the PR head, selects the latest official graph using its once-resolved version (or the exact version supplied by the enclosing release run), builds the compiled extension on Node **24.21.0**, and runs portable native SDK lifecycle checks against isolated loopback browser fixtures. It replaces the fork-only checkpoint gate and requires all 13 checks to pass with no failure, cancellation or skip. It does not repeat the official full suite. Sources use a private `/tmp` root, sanitized environment, non-root execution, and a loopback-only network namespace. Only official host metadata preparation receives the job's read-only GitHub token; setup unsets it before extension build and browser installation. Lifecycle verification receives no token and uses no personal profile, personal credentials, or model calls.
|
|
340
363
|
|
|
341
|
-
Routine checks write setup, provenance, command-reference, and native TAP results to the job log and upload short-lived evidence: `official-host`, `fork-host`, and `macos-host` contain exact selected host receipts; `native-lifecycle` contains the host receipt, native TAP results and lifecycle transcripts. Each routine artifact is retained for three days, with no persistent caches. Native manual qualification uses the shared workflow's npm and fork-package caches; its fork-host artifact is retained for seven days and per-lane qualification evidence for fourteen days. The checks cover their exact source, host, and synthetic browser paths; they do not replace release/manual-publication gates, real-site authentication, or full personal-workspace restore qualification.
|
|
364
|
+
Routine checks write setup, provenance, command-reference, and native TAP results to the job log and upload short-lived evidence: `official-host`, `fork-host`, and `macos-host` contain exact selected host receipts; `native-lifecycle` contains the host receipt, native TAP results and lifecycle transcripts. Each routine Linux/macOS artifact is retained for three days, with no persistent caches. Windows smoke retains `windows-best-effort-smoke` for fourteen days with source/host/tool inputs, the selected host receipt when reached, and the complete smoke log. A failed or incomplete smoke is not full Windows qualification. Explicit deep Windows retains `windows-qualification-official` and `windows-qualification-fork` for fourteen days, including exact input receipts, environment TAP, complete qualification logs, and the shared qualifier's provenance, package hashes and SDK/CLI probes when reached. Uploads run even after failure. The Windows console retains the final 1,000 qualification lines and, on failure, separately prints all failed TAP test names plus the first 1,600 lines of their diagnostics, with an explicit truncation notice when needed; complete diagnostics remain in `qualification.log`. An absent qualification receipt or skipped contract is not a pass. The resolved fork-package artifact is retained for seven days. Native manual qualification uses the shared workflow's npm and fork-package caches; its fork-host artifact is retained for seven days and per-lane qualification evidence for fourteen days. The checks cover their exact source, host, and synthetic browser paths; they do not replace release/manual-publication gates, real-site authentication, or full personal-workspace restore qualification.
|
|
342
365
|
|
|
343
366
|
### Native Linux socket-root regression
|
|
344
367
|
|
|
@@ -359,7 +382,7 @@ For a root-check change, run the identical final test against both the pre-fix a
|
|
|
359
382
|
- **Missing or extra `details` / `data` keys:** Update `test/fixtures/agent-browser-real-output-shapes.json` in the same change as the wrapper or presentation code that shifts those keys.
|
|
360
383
|
- **Timeouts:** The broad matrix has a 180-second bound; the focused cold-reopen, click-mutation, and plugin cases each have a 60-second bound. Repeated timeouts usually mean a hung browser, blocked loopback, or an environment preventing headful/headless launch—check upstream logs and local security tooling before loosening timeouts.
|
|
361
384
|
|
|
362
|
-
|
|
385
|
+
Native 0.39.4 fixes already-completed downloads and requested-path persistence ([upstream change](https://github.com/vercel-labs/agent-browser/releases/tag/v0.39.4)); the recommended 0.41.0 contract requires the fixture's actual bytes at the requested destination and verified wrapper artifacts. Older supported natives (0.35.0–0.39.3) report the requested path without moving the file, so the same contract requires the wrapper's fail-closed `artifact-missing` result there. Native only moves downloads from a browser it launched, not attached/remote CDP paths. `details.savedFilePath` alone remains metadata: require `details.artifactVerification` and `details.artifacts[].exists`, and retain the artifact-presentation tests that fail reported-but-missing outputs. This fixture refresh is not a wrapper runtime download fix. If the suite fails because JSON/detail keys drifted, update the wrapper behavior or refresh `test/fixtures/agent-browser-real-output-shapes.json` together with the presentation work that consumes those shapes.
|
|
363
386
|
|
|
364
387
|
Example smoke prompt:
|
|
365
388
|
|
|
@@ -410,7 +433,7 @@ Before publishing:
|
|
|
410
433
|
- run `npm run verify -- real-upstream` for upstream runtime, result-presentation, or managed-session changes
|
|
411
434
|
- confirm both local-checkout modes still work for pre-release validation: isolated `pi --approve --no-extensions -e .` smoke testing for general trusted checkout loading (add `--no-skills` for extension-focused bounded smokes; omit `--approve` only to test the trust prompt) and configured-source lifecycle validation
|
|
412
435
|
- complete interactive `tmux` live-site extension smoke with `pi --approve --no-extensions --no-skills -e .` and the native `agent_browser` tool (at least one simple static site and one real documentation/product site; include advanced QA, code, or native batch when those surfaces changed; use the [public Grafana stress checklist](#public-grafana-stress-checklist) when dashboard/diagnostic/artifact behavior changed; close sessions and remove screenshots/temp artifacts; record evidence). Run separate skill-enabled dogfood only when validating skill routing/report-generation behavior—see [Pre-release checks](#pre-release-checks); automated gates are not a substitute
|
|
413
|
-
- satisfy the approved release checks and current owner waivers; record individual platform evidence and never label
|
|
436
|
+
- satisfy the approved release checks and current owner waivers; record individual platform evidence and never label best-effort, failed, or not-run Windows evidence passed from the required non-Windows aggregate
|
|
414
437
|
- run `npm run verify -- lifecycle` for configured-source `/reload`, exact `--session-id` relaunch, managed-session continuity, persisted-spill, and Pi failure-patch regression coverage (required before publish; see [Pre-release checks](#pre-release-checks))
|
|
415
438
|
- confirm [`SUPPORT_MATRIX.md`](SUPPORT_MATRIX.md) still maps every current baseline inventory section to docs, runtime handling, tests, and validation status
|
|
416
439
|
- manually exercise real-browser `/reload` and full restart plus exact `--session-id` relaunch or `/resume` continuity when release risk warrants browser-level confidence beyond the fake upstream harness
|
package/docs/REQUIREMENTS.md
CHANGED
|
@@ -13,6 +13,12 @@ Related docs:
|
|
|
13
13
|
|
|
14
14
|
Define the product requirements and constraints for `pi-agent-browser-native`.
|
|
15
15
|
|
|
16
|
+
## Runtime requirements
|
|
17
|
+
|
|
18
|
+
- Node.js 24.21.0 or newer.
|
|
19
|
+
- Pi 1.0.0 or newer.
|
|
20
|
+
- A separate stable `agent-browser` installation, version 0.35.0 or newer, available on `PATH`.
|
|
21
|
+
|
|
16
22
|
## Product requirements
|
|
17
23
|
|
|
18
24
|
### Dependency model
|
package/docs/SESSION_STORAGE.md
CHANGED
|
@@ -14,7 +14,7 @@ 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 public native ancestry validation, so concurrent appends cannot change the branch being replayed. It
|
|
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 validates complete newline-terminated records. A record up to 1 MiB with nesting within 1024 levels and at most 64 Ki structural bytes (`{`, `[`, `,` or `:` outside strings) uses native JSON, which briefly holds that record's text and parsed value, a few MiB at most. Larger or denser records and any native rejection use the token projector with unpacked discarded strings, fed in the same 64 KiB chunks as file reads, so both paths accept the same records and report the same first error. A cold restore frames and validates the whole journal. Subsequent restores on the same native manager retain only complete-record structural metadata: an unchanged file reuses that index, and an append scans from the last complete record, including any previously incomplete tail. Locator/header-object changes, rotation, truncation, same-size timestamp changes and failed reads or replay discard the index and use the full validating scanner. The index follows Pi's documented append-only entry contract; native reseeding replaces its header object even when the UUID stays the same. External prefix rewrites must be reopened through Pi rather than disguised as appends to its live journal. This is not an adversarial file-integrity guarantee. Each restore still projects selected envelopes, follows ancestry and rereads winning snapshot bodies; it never caches refs or browser outcomes. 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
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
|
|
|
@@ -57,9 +57,9 @@ Select the converted locator explicitly through the native session/worker owner.
|
|
|
57
57
|
|
|
58
58
|
## Verification
|
|
59
59
|
|
|
60
|
-
Focused storage tests exercise incident-sized refs, small-event growth, begin/finish append faults with actual dispatch counts, interruption, branch projections and native generation replacement. Existing tab/ref, confirmation, recording, artifact and lifecycle suites retain their behavior checks.
|
|
60
|
+
Focused storage tests exercise incident-sized refs, small-event growth, a dense record's per-record heap reserve under a capped heap, begin/finish append faults with actual dispatch counts, interruption, branch projections and native generation replacement. Existing tab/ref, confirmation, recording, artifact and lifecycle suites retain their behavior checks.
|
|
61
61
|
|
|
62
|
-
After `npm run build`, the opt-in model-free proof runs a journal above 1 GiB, including an ignored individual string above Node's string ceiling, repeated legacy maps, and 4,000 distinct session identities, through conversion and selected replay under a constrained V8 heap:
|
|
62
|
+
After `npm run build`, the opt-in model-free proof runs a journal above 1 GiB, including an ignored individual string above Node's string ceiling, repeated legacy maps, dense records at the 1 MiB native-parse boundary, and 4,000 distinct session identities, through conversion and selected replay under a constrained V8 heap:
|
|
63
63
|
|
|
64
64
|
```sh
|
|
65
65
|
node --max-old-space-size=128 test/helpers/large-browser-journal.mjs
|