pi-agent-browser-native 0.6.10 → 0.6.12
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 +43 -0
- package/README.md +50 -7
- package/dist/extensions/agent-browser/index.js +416 -430
- package/dist/extensions/agent-browser/lib/argv-grammar.js +1 -1
- package/dist/extensions/agent-browser/lib/command-policy.js +41 -2
- package/dist/extensions/agent-browser/lib/input-modes/job.js +7 -7
- package/dist/extensions/agent-browser/lib/input-modes/params.js +1 -1
- package/dist/extensions/agent-browser/lib/input-modes/script.js +3 -2
- package/dist/extensions/agent-browser/lib/managed-session-restore.js +40 -10
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/diagnostics.js +3 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/final-result.js +8 -2
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/index.js +1 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare/wait-timeouts.js +3 -2
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare.js +25 -14
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output.js +56 -10
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/recording-recovery.js +161 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/session-state.js +3 -3
- package/dist/extensions/agent-browser/lib/orchestration/input-plan.js +2 -4
- package/dist/extensions/agent-browser/lib/orchestration/native-session-defaults.js +68 -0
- package/dist/extensions/agent-browser/lib/orchestration/output-file.js +41 -6
- package/dist/extensions/agent-browser/lib/page-target-validation.js +9 -5
- package/dist/extensions/agent-browser/lib/playbook.js +10 -9
- package/dist/extensions/agent-browser/lib/process-environment.js +26 -8
- package/dist/extensions/agent-browser/lib/process.js +8 -5
- package/dist/extensions/agent-browser/lib/read-confirmation.js +59 -0
- package/dist/extensions/agent-browser/lib/recording-reservations.js +11 -1
- package/dist/extensions/agent-browser/lib/results/action-recommendations.js +8 -0
- package/dist/extensions/agent-browser/lib/results/artifact-manifest.js +6 -5
- package/dist/extensions/agent-browser/lib/results/categories.js +4 -2
- package/dist/extensions/agent-browser/lib/results/presentation/artifacts.js +60 -29
- package/dist/extensions/agent-browser/lib/results/presentation/batch.js +19 -8
- package/dist/extensions/agent-browser/lib/results/presentation/common.js +0 -20
- package/dist/extensions/agent-browser/lib/results/presentation/diagnostics.js +40 -38
- package/dist/extensions/agent-browser/lib/results/presentation/errors.js +1 -0
- package/dist/extensions/agent-browser/lib/results/presentation/navigation.js +3 -3
- package/dist/extensions/agent-browser/lib/results/presentation.js +38 -9
- package/dist/extensions/agent-browser/lib/results/recording.js +50 -0
- package/dist/extensions/agent-browser/lib/runtime.js +72 -20
- package/dist/extensions/agent-browser/lib/session-page-state.js +23 -7
- package/dist/extensions/agent-browser/lib/temp.js +4 -0
- package/docs/ARCHITECTURE.md +27 -11
- package/docs/COMMAND_REFERENCE.md +37 -17
- package/docs/RELEASE.md +3 -1
- package/docs/SUPPORT_MATRIX.md +10 -4
- package/docs/TOOL_CONTRACT.md +87 -25
- package/docs/platform-smoke.md +9 -1
- package/package.json +1 -1
- package/scripts/prepare.mjs +2 -4
|
@@ -16,6 +16,8 @@ This project intentionally blocks normal `agent-browser` bash usage in most agen
|
|
|
16
16
|
|
|
17
17
|
After updating `pi-agent-browser-native`, fully quit and restart Pi before using the updated tools. `/reload` can retain previously loaded compiled JavaScript even after `dist/` is rebuilt, so it is not a reliable way to pick up package updates.
|
|
18
18
|
|
|
19
|
+
SDK hosts can supply an awaited [`beforeExecute` callback](TOOL_CONTRACT.md#host-execution-hook) to save host state before ordinary or script-inner browser dispatch. This is a factory option, not a tool argument; normal installations do not need it.
|
|
20
|
+
|
|
19
21
|
## Upstream baseline
|
|
20
22
|
|
|
21
23
|
<!-- agent-browser-capability-baseline:start upstream-baseline -->
|
|
@@ -213,10 +215,11 @@ Tool parameters (use exactly one of `script`, `args`, `semanticAction`, `job`, `
|
|
|
213
215
|
- `networkSourceLookup`: **EXPERIMENTAL — candidates only** for failed request-to-source hints; compiles to generated `batch`, reports `details.compiledNetworkSourceLookup` and `details.networkSourceLookup`, and never assigns blame or edits files.
|
|
214
216
|
- `electron`: optional Electron desktop-app shorthand. `list`, `status`, `cleanup`, and `probe` are wrapper-owned host/session helpers; `launch` starts a wrapper-owned isolated Electron profile and attaches through upstream `connect`.
|
|
215
217
|
- `stdin`: top-level stdin is only for `batch`, `eval --stdin`, and `auth save --password-stdin`; other combinations are rejected before `agent-browser` is launched. `script` puts inner stdin on `browser({ stdin })`; `job`, `qa`, `sourceLookup`, `networkSourceLookup`, and `electron` generate or manage their own input.
|
|
216
|
-
- `outputPath`: optional wrapper-owned local file sink for successful results. Use it for durable `eval`, `get`, `snapshot`, or diagnostic outputs, not as the destination for screenshots, downloads, recordings, or other browser artifacts; if the paths resolve to the same file, the browser artifact is preserved and the result-data write fails validation. If presentation compacted a large direct result, a result row, or the whole `batch`, the writer copies each full command-redacted pre-compaction value only from its matching live wrapper-manifest spill; if any required spill is unavailable or untrusted, it fails without writing compact metadata. `details.outputFile` reports the saved path and byte count. If caller argv includes upstream `--json`, the visible JSON content stays parseable and the save notice is only in `details.outputFile`.
|
|
218
|
+
- `outputPath`: optional wrapper-owned local file sink for successful results and recording receipts, including failed, pending, timed-out or recovered stops. Recording exports preserve an envelope with original attempt status and native receipt/verification (`details.outputFile.source: "recording-receipt"`); unrelated failed extractions remain unwritten. Use it for durable `eval`, `get`, `snapshot`, or diagnostic outputs, not as the destination for screenshots, downloads, recordings, or other browser artifacts; if the paths resolve to the same file, the browser artifact is preserved and the result-data write fails validation. If presentation compacted a large direct result, a result row, or the whole `batch`, the writer copies each full command-redacted pre-compaction value only from its matching live wrapper-manifest spill; if any required spill is unavailable or untrusted, it fails without writing compact metadata. `details.outputFile` reports the saved path and byte count. If caller argv includes upstream `--json`, the visible JSON content stays parseable and the save notice is only in `details.outputFile`.
|
|
217
219
|
- `timeoutMs`: optional per-call wrapper subprocess watchdog override in milliseconds for the requested browser CLI process. Managed-session policy inspection can independently consume up to 35 seconds before that process; this preflight is intentionally not shortened by `timeoutMs` because a busy but valid daemon must remain distinguishable from an unverifiable one.
|
|
218
220
|
- `sessionMode`:
|
|
219
|
-
- `
|
|
221
|
+
- Native configured `session` / `AGENT_BROWSER_SESSION` defaults select a caller-owned shared browser for ordinary calls, just like explicit `--session`, without requiring repeated flags. Such a selection wins over both modes and is not closed on Pi quit. See [shared browser defaults](../README.md#shared-browser-defaults).
|
|
222
|
+
- `"auto"` reuses the extension-managed session when no native session is selected.
|
|
220
223
|
- `"fresh"` rotates that managed session to a fresh upstream launch so launch-scoped flags (`--allowed-domains`, `--auto-connect`, `--args`, `--ca-cert`, `--no-ca-cert`, `--cdp`, `--enable`, `--executable-path`, `--webgpu`, `--init-script`, `--idle-timeout`, `--user-agent`, `--headed`, `--device`, `--namespace`, `--profile`, `--provider`, `-p`, `--restore`, `--restore-save`, `--restore-check-url`, `--restore-check-text`, `--restore-check-fn`, `--session-name`, `--state`) apply.
|
|
221
224
|
- If a fresh launch fails or times out, read `details.managedSessionOutcome` for `preserved` vs `abandoned` (and related fields). A model-visible `Managed session outcome: …` line is appended for failing calls that used `sessionMode: "fresh"` and when automatic close of a replaced session fails; `"auto"` failures can still populate the struct without that extra line. If you explicitly close the current wrapper-managed session with `--session <name> close`, later default auto calls rotate to a new wrapper-generated session instead of reusing the closed name; repeated closes and branch restores keep those generated names monotonic.
|
|
222
225
|
|
|
@@ -232,7 +235,7 @@ Use `script` when a loop, an optional page branch, or multi-page aggregation wou
|
|
|
232
235
|
|
|
233
236
|
The wrapper serializes inner calls, caps them at 25, caps source/final JSON at 64 KiB, defaults the whole script to 120 seconds, and rejects more than 300 seconds. Final data is redacted, compact-serialized, and byte-checked again before presentation so nesting cannot amplify small JSON into unbounded prose. Inner summaries/text are bounded, complete envelopes are checked against the IPC cap, and script-visible browser `nextActions` retain only policy-compatible calls after the isolated identity prefix is removed. It launches a separate permissioned Node child with no imports, process, filesystem, network, timers, dynamic code generation, or host object/function references. `Promise.all` is allowed for local orchestration but does not make browser calls concurrent. Pi approval covers the one visible top-level input and may therefore authorize all 25 inner calls. The collapsed Pi tool row shows a bounded terminal-safe source preview with line breaks marked as `↵`; expand the row to inspect the full terminal-safe source before approval. JavaScript CR/U+2028/U+2029 line terminators remain visible newlines, and removed terminal/directional/zero-width controls become visible markers.
|
|
234
237
|
|
|
235
|
-
A script invocation uses a unique `piab-script-<uuid>` browser identity in an empty namespace with managed restore disabled. It cannot name or attach to sessions, use profiles/providers/state/restore/raw launch mutation, issue lifecycle/sessionless/local commands, or nest `batch` or another top-level input mode. Every inner helper and cleanup process also clears ambient `AGENT_BROWSER_*` and standard proxy variables before the wrapper reapplies its
|
|
238
|
+
A script invocation uses a unique `piab-script-<uuid>` browser identity in an empty namespace with managed restore disabled. It cannot name or attach to sessions, pass `--config`, use profiles/providers/state/restore/raw launch mutation, issue lifecycle/sessionless/local commands, or nest `batch` or another top-level input mode. Every inner helper and cleanup process also clears ambient `AGENT_BROWSER_*` and standard proxy variables and uses an empty temporary native config to bypass HOME/project profile defaults before the wrapper reapplies its namespace, timeout, and compatibility values. It never replaces the implicit conversation browser and always closes its isolated session. Use ordinary `args` with a requested profile/attachment for authenticated state.
|
|
236
239
|
|
|
237
240
|
Pi persistence is required because the extension appends a strict model-invisible cleanup lease before the first inner browser launch. Pi branch changes, quit, and reload abort the script and await normal isolated-session cleanup before state restoration continues. A failed close is retried on the active branch after restart and returns `failureCategory: "cleanup-failed"` plus exact `details.scriptSession.closeCommandArgs` / `close-script-session-after-cleanup-failure`. Any rejected inner policy/validation call fails the top-level result even if source consumes its envelope. See [`TOOL_CONTRACT.md`](TOOL_CONTRACT.md#script) for the full schema, limits, result fields, rejected controls, and recovery semantics.
|
|
238
241
|
|
|
@@ -361,7 +364,7 @@ Successful `snapshot -i` results can also surface `Possible overlay blockers` wh
|
|
|
361
364
|
{ "args": ["eval", "--stdin"], "stdin": "document.title" }
|
|
362
365
|
```
|
|
363
366
|
|
|
364
|
-
Use `read [url]` for documentation and other unstructured text. `read <url> --raw` preserves the response body, `read <url> --require-md` requires `text/markdown`, `read <url> --llms <index|full>` reads the nearest ancestor llms index/full file, `read <url> --outline` emits headings, `read <url> --filter <text>` narrows matching sections/headings/links, and `read <url> --timeout <ms>` changes the request timeout. Explicit URL reads prefer markdown, try a `.md` path and nearby `llms.txt` links, then fall back to readable HTML without requiring a Chrome page. The wrapper
|
|
367
|
+
Use `read [url]` for documentation and other unstructured text. `read <url> --raw` preserves the response body, `read <url> --require-md` requires `text/markdown`, `read <url> --llms <index|full>` reads the nearest ancestor llms index/full file, `read <url> --outline` emits headings, `read <url> --filter <text>` narrows matching sections/headings/links, and `read <url> --timeout <ms>` changes the request timeout. Explicit URL reads prefer markdown, try a `.md` path and nearby `llms.txt` links, then fall back to readable HTML without requiring a Chrome page. The wrapper does not allocate or replace a managed browser for an explicit URL read or all-read batch. It skips page verification, tab/ref changes and timeout page probes; malformed read arguments go to native validation without falling back to a DOM preflight. Caller config and flags remain native-owned. `Read execution` reports source, CLI start and native launch evidence without treating the HTTP read as proof of shared-browser liveness. Use `session info` for that. Native no-browser-effects behavior requires the companion upstream fix; older supported binaries do not guarantee it merely because the wrapper skips helpers. Omit the URL to read rendered active-tab DOM, including current browser auth and client-side state; `--llms` / `--require-md` without a URL instead fetch from the active tab URL. The wrapper renders `data.content` first, retains source/content-type/status/final-URL metadata in `details.data`, keeps fetched URLs from replacing the active browser tab target, and extends its subprocess watchdog for explicit long read timeouts.
|
|
365
368
|
|
|
366
369
|
When you already know several visible refs or selectors, extract them in one `batch` call instead of many serial getter calls. When a prior snapshot and session are available and the same-page freshness checks apply, ref-consuming calls add one extra `snapshot -i` preflight per top-level call or batch. Batching shares that probe across rows; it does not remove it:
|
|
367
370
|
|
|
@@ -436,9 +439,9 @@ On app pages that expose a native dropdown, add a `select` step such as `{ "acti
|
|
|
436
439
|
|
|
437
440
|
Use raw `args: ["batch"]` with `stdin` when you need arbitrary upstream commands, flags, or batch failure policies outside the constrained schema. Do not pass `stdin` with `job`, `qa`, `sourceLookup`, `networkSourceLookup`, or `electron`; those modes generate or manage their own input.
|
|
438
441
|
|
|
439
|
-
For quick smoke/QA checks, use top-level `qa`. It clears enabled network/console buffers and snapshots any page-error residue after the unreliable upstream clear, then opens the target URL and gives immediate post-load console/page-error callbacks a bounded 150 ms settle, waits for page readiness, checks expected text/selector, then inspects fresh network requests, console messages, and page errors only if preceding assertions pass, and can capture an evidence screenshot. Successful reset rows are labeled as reset-scoped diagnostic output.
|
|
442
|
+
For quick smoke/QA checks, use top-level `qa`. It clears enabled network/console buffers and snapshots any page-error residue after the unreliable upstream clear, then opens the target URL and gives immediate post-load console/page-error callbacks a bounded 150 ms settle, waits for page readiness, checks expected text/selector, then inspects fresh network requests, console messages, and page errors only if preceding assertions pass, and can capture an evidence screenshot. Successful reset rows are labeled as reset-scoped diagnostic output. If final page-error rows match a nonempty post-clear baseline, QA is non-pass with “page-error check could not be verified”: identical new errors can replace old rows in the native FIFO buffer without changing the result. Those matches are not proof of new application errors. Definitely new rows, including errors after an empty baseline, count separately as page errors; a clean final buffer can pass. Explicit `checkErrors: false` omits this check for a more limited smoke test. The preset compiles to `batch --bail` so a missing text/selector assertion fails crisply instead of letting slower diagnostics burn the wrapper watchdog. Expected text compiles to bounded visible-text `wait --fn … --timeout 5000` predicates after load so dense pages can pass on visible headings/copy without dumping `body` text; missing text reports a crisp QA failure. The readiness wait defaults to `loadState: "domcontentloaded"`; set `loadState` to `"load"` or `"networkidle"` only when that stricter state is useful and the site is not expected to keep background requests alive. QA network diagnostics classify failed requests by likely impact and list failed rows first in the network preview: actionable document/script/API-style failures fail the preset, while common low-impact browser icon misses such as `favicon.ico` are surfaced as warnings (`qaPreset.warnings`) so they do not fail an otherwise healthy page. Successful QA with no failed checks returns compact model-visible prose (page URL/title when known, checks run, optional screenshot verification) while keeping the full step matrix in `details.qaPreset` and `details.batchSteps`. Failed QA presets report `details.resultCategory: "failure"`, `failureCategory: "qa-failure"`, show compact failure reasons with the full matrix in `details.batchSteps`, and real Pi sessions treat the diagnostic as a failed tool result. Prose output also gets a model-visible result-category line including `Pi tool isError: true`; caller-requested `--json` output keeps the JSON string parseable and relies on the patched `isError` plus `details` fields.
|
|
440
443
|
|
|
441
|
-
The same classification drives plain `network requests` presentation: when any row counts as failed (HTTP status ≥ 400, `failed: true`, or a string `error`), model-facing text starts with a line like `Network failure summary: 0 actionable, 1 benign low-impact (1 total).`, and each preview line can end with an impact tag such as `[benign: low-impact browser icon asset]` or `[actionable: document, script, API, or non-benign request failure]`. When safe request IDs are present, `details.nextActions` adds bounded read-only follow-ups such as `network request <id>`, `networkSourceLookup` for actionable failed rows, `network requests --filter <path>`, `network requests --clear` before a repro, and `network har start`; prefer those payloads over rebuilding request-id commands from prose. For aggregate buffers, the wrapper accepts `network requests --current-page` / `--current-origin` to render only rows matching the active page origin, or `--current-url` for exact active document URL matching; it strips those wrapper-only flags before upstream spawn and reports counts in `details.networkRequestsPageFilter`. If the wrapper has seen a prior `network route` in the same session, matching failed, pending, or CORS-looking fetch/XHR rows add `details.networkRouteDiagnostics` plus executable route-mock follow-ups (`inspect-routed-network-request` and `start-network-har-capture-for-route-mock`) so agents do not mistake an unfulfilled mock for a fulfilled mock; same-origin/CORS fixture retry guidance stays in visible prose. `network requests` also hides `data:image` screenshot/artifact noise from the compact preview by default while preserving raw rows in `details.data.requests`. Rules live in `classifyNetworkRequestFailure` / `summarizeNetworkFailures` in `extensions/agent-browser/lib/results/network.ts`; QA aggregation is `analyzeQaPresetResults` in `extensions/agent-browser/
|
|
444
|
+
The same classification drives plain `network requests` presentation: when any row counts as failed (HTTP status ≥ 400, `failed: true`, or a string `error`), model-facing text starts with a line like `Network failure summary: 0 actionable, 1 benign low-impact (1 total).`, and each preview line can end with an impact tag such as `[benign: low-impact browser icon asset]` or `[actionable: document, script, API, or non-benign request failure]`. When safe request IDs are present, `details.nextActions` adds bounded read-only follow-ups such as `network request <id>`, `networkSourceLookup` for actionable failed rows, `network requests --filter <path>`, `network requests --clear` before a repro, and `network har start`; prefer those payloads over rebuilding request-id commands from prose. For aggregate buffers, the wrapper accepts `network requests --current-page` / `--current-origin` to render only rows matching the active page origin, or `--current-url` for exact active document URL matching; it strips those wrapper-only flags before upstream spawn and reports counts in `details.networkRequestsPageFilter`. If the wrapper has seen a prior `network route` in the same session, matching failed, pending, or CORS-looking fetch/XHR rows add `details.networkRouteDiagnostics` plus executable route-mock follow-ups (`inspect-routed-network-request` and `start-network-har-capture-for-route-mock`) so agents do not mistake an unfulfilled mock for a fulfilled mock; same-origin/CORS fixture retry guidance stays in visible prose. `network requests` also hides `data:image` screenshot/artifact noise from the compact preview by default while preserving raw rows in `details.data.requests`. Rules live in `classifyNetworkRequestFailure` / `summarizeNetworkFailures` in `extensions/agent-browser/lib/results/network.ts`; QA aggregation is `analyzeQaPresetResults` in `extensions/agent-browser/lib/input-modes/job.ts`.
|
|
442
445
|
|
|
443
446
|
```json
|
|
444
447
|
{ "qa": { "url": "https://example.com", "expectedText": "Example Domain", "screenshotPath": ".dogfood/qa-example.png" } }
|
|
@@ -551,8 +554,8 @@ For evidence-only screenshots, QA captures, or audit artifacts, save to an expli
|
|
|
551
554
|
Wrapper result rendering is metadata-first for saved files. Image MIME types come from a bounded header read for PNG, JPEG, GIF and WebP, never from a filename suffix; missing, unreadable, unknown or truncated headers omit `mediaType`. This identifies a format, not full image validity. Inline screenshots use the same byte check and existing size limit, so a PNG saved as `.webm` still attaches as `image/png`; other artifact kinds are not auto-inlined. An artifact-producing command fails as `artifact-missing` with artifact `status: "stale"` when the reported path's `mtimeMs` falls outside the command's bounded start/end window (with two seconds of filesystem precision tolerance), including a previous recording that `record restart` claims to finalize; clearly old or future-dated evidence is never accepted as a fresh capture. A batch, whether supplied through stdin arrays or argument command strings, must use distinct explicit artifact destinations; preflight canonicalizes existing path ancestry, compares existing file identities to catch hardlinks, and applies full Unicode plus platform case folding on macOS/Windows so aliases cannot satisfy another step's verification. The same preflight prevents `outputPath` from aliasing a same-call browser artifact, follows upstream's forward option consumption and final effective `-o` / `--output` for `diff screenshot`, and treats the optional path on `network har stop` as an artifact destination; upstream ignores positional paths on `network har start`. Outer CLI artifact parsing removes upstream global flags, so direct forms such as `record --json start <path>` and `pdf --quiet <path>` retain their native destinations. Native batch rows do not run that cleanup: `pdf --quick ignored.pdf` writes to the literal path `--quick`, and `download #link --quiet ignored.bin` writes to `--quiet`. Preflight, directory preparation, presentation, and timeout evidence use those same operands, not the ignored trailing tokens. Screenshot destination parsing mirrors upstream's exact flag matching and `[selector] [path]` positional order: `--` is positional, `true` / `false` after screenshot-only `--full` / `-f` remain positional, extra positionals are ignored after the path slot, selector-prefixed (`.`, `#`, `@`) or uppercase-extension single arguments remain selectors, and lowercase image extensions or slash-bearing arguments are paths. The wrapper deliberately keeps its existing slash-bearing hidden-workspace path normalization (for example `.dogfood/run/foo.png`) before launch. `wait --download` is observational and may verify a download that completed just before the wait began, so it is exempt from the command-window mtime gate; an explicit wait destination, in long `--download <path>` or short `-d <path>` form (including `wait --download --timeout 30000 capture.csv`), still participates in active-recording reservation preflight; the path is the next retained operand after the first timeout pair is removed; unsupported `--download=<path>` fails with split-argument guidance:
|
|
552
555
|
- screenshots return a saved-path summary, visible artifact metadata, structured `details.artifacts` metadata, and an inline image attachment when safe; the visible block includes artifact type, requested path, absolute path, existence, size, cwd, session, and repair/copy status when applicable
|
|
553
556
|
- downloads, PDFs, `wait --download` files, `state save` state files, diff screenshot output images, traces, CPU profiles, completed video recordings from `record stop`, and path-bearing HAR captures return concise saved-path summaries plus structured `details.artifacts` metadata without inlining large files
|
|
554
|
-
- `record start <path>` and `record restart <path>` report `successCategory: "artifact-pending"` and that output will be written on `record stop`; dispatched `record start` and URL-bearing `record restart` attempts append one `Page state:` warning on success or failure, describing conservative ref invalidation rather than an observed page change; explicit `--json` puts that warning in `warnings`. Only reached batch rows qualify, not preflight failures, missing binaries, help calls or unconfirmed planned rows — the wrapper invalidates the session’s prior ref snapshot (direct calls and batch steps alike, and even when the start fails with `Recording already active`, to protect older supported natives that can swap the page before that check), so old `@e…` refs fail as `stale-ref` until a fresh `snapshot -i` succeeds; `record restart <path> <url>` navigates the current page and invalidates refs the same way, while a restart without a URL, including FPS-only options, keeps the current page and refs; `details.artifacts` / `details.artifactVerification` mark that future file as `pending` with `recordingState: "openRecording"` and `willExistOnStop: true`, and `details.nextActions` includes exact `stop-pending-recording` args. When `record restart`
|
|
555
|
-
- `batch` keeps each step's artifacts in `details.batchSteps[].artifacts`; top-level `details.artifacts` and `details.artifactManifest` coalesce an earlier pending recording into the later saved, missing, or stale terminal result for the same namespace/session identity; a successful later close
|
|
557
|
+
- `record start <path>` and `record restart <path>` report `successCategory: "artifact-pending"` and that output will be written on `record stop`; dispatched `record start` and URL-bearing `record restart` attempts append one `Page state:` warning on success or failure, describing conservative ref invalidation rather than an observed page change; explicit `--json` puts that warning in `warnings`. Only reached batch rows qualify, not preflight failures, missing binaries, help calls or unconfirmed planned rows — the wrapper invalidates the session’s prior ref snapshot (direct calls and batch steps alike, and even when the start fails with `Recording already active`, to protect older supported natives that can swap the page before that check), so old `@e…` refs fail as `stale-ref` until a fresh `snapshot -i` succeeds; `record restart <path> <url>` navigates the current page and invalidates refs the same way, while a restart without a URL, including FPS-only options, keeps the current page and refs; `details.artifacts` / `details.artifactVerification` mark that future file as `pending` with `recordingState: "openRecording"` and `willExistOnStop: true`, and `details.nextActions` includes exact `stop-pending-recording` args. When `record restart` returns a native `previousRecording`, that receipt's outcome and capture window control the previous artifact's verification; a legacy file without a terminal native receipt remains unverified, not saved; a missing or stale prior file fails as `artifact-missing` while the new recording remains visible as pending and the prior manifest row is retired. Within one Pi extension process, an unbounded transcript-backed index reserves active recording destinations independently of the bounded artifact manifest. Artifact lifecycle calls and result `outputPath` writes serialize around that global check; reservations use canonical namespace/session identity, survive manifest eviction and branch replay, and retire after direct, ordered nested-batch, fresh-replacement, script, Electron, or shutdown close; the newest pending row per identity is authoritative. Legacy batch replay retires a pending manifest only when the ordered close lifecycle leaves recording closed; a later successful browser reactivation plus `record start` keeps the new pending reservation. Lexical, hardlink, existing/dangling symlink, full Unicode-fold, and macOS/Windows case aliases are rejected, so `record restart` must use a distinct new path. Do not place `record start` or `record restart` after `close` / `quit` / `exit` in one batch: wrapper preflight rejects it because upstream can report success without starting a recording; split the close and recording into separate calls. A `No recording in progress` stop failure checks the matching native receipt once and preserves checked file metadata instead of assuming the path is missing; a later successful batch recording row opens its new pending path normally. Recovery offers an exact status query, and a stop only when the matching take is still current and pending. The target remains unverified until recording stops. Native 0.37 checks `ffmpeg` before starting; older supported natives may defer failure. If a successful start/restart reports pending output without `ffmpeg`, the wrapper appends `Recording dependency warning: ffmpeg not found on PATH` and `details.recordingDependencyWarning`; stop, check the result, then install the dependency before starting a new recording.
|
|
558
|
+
- `batch` keeps each step's artifacts in `details.batchSteps[].artifacts`; top-level `details.artifacts` and `details.artifactManifest` coalesce an earlier pending recording into the later saved, missing, or stale terminal result for the same namespace/session identity; a successful later close retires an unfinalized recording as `close-abandoned`, uses `missing` only after a filesystem check proves absence (otherwise unverified), removes its stop action, and resets earlier ref/page/network-route batch state; a later successful `record stop` replaces that intermediate abandoned row with its verified saved artifact, and later rows—including failed rows—whose lifecycle reports a browser launch may rebuild state without triggering stale pre-close `about:blank` recovery; failed-step `batchSteps[]` retains only the bounded `lifecycle.effectiveLaunch.browserLaunched` boolean for replay, explicitly non-launching diagnostics leave the close terminal, missing lifecycle evidence remains conservatively active even on the first managed call, every successful close clears wrapper trace/profiler ownership before ordered later successful rows can rebuild it, namespace-scoped `close --all` clears all matching managed/attached/page/ref/route/trace/recording ownership, and any later same-session failure before recording stops keeps exact `stop-pending-recording` args alongside its normal recovery
|
|
556
559
|
|
|
557
560
|
`diff screenshot` follows the file-artifact path above for the **diff** image: model-visible text and `details.artifacts` focus on that output, while baseline paths stay out of the artifact summary block, and Pi does **not** auto-inline the diff the way it inlines trusted `screenshot` captures. `state load` may print the loaded path in prose but does not add a saved-file artifact entry the way `state save` does.
|
|
558
561
|
|
|
@@ -564,6 +567,19 @@ For annotated screenshots in `batch`, put `--annotate` in top-level args instead
|
|
|
564
567
|
{ "args": ["--annotate", "batch"], "stdin": "[[\"screenshot\",\"/tmp/page.png\"]]" }
|
|
565
568
|
```
|
|
566
569
|
|
|
570
|
+
#### Recording quality and receipts
|
|
571
|
+
|
|
572
|
+
```json
|
|
573
|
+
{ "args": ["record", "start", "captures/demo.webm", "--fps", "30"] }
|
|
574
|
+
{ "args": ["record", "stop"], "outputPath": "captures/demo-receipt.json" }
|
|
575
|
+
```
|
|
576
|
+
|
|
577
|
+
Inspect `details.artifacts[].recording`: native capture start/end and first/last frame timestamps, wall duration, captured-frame rate, received frames, encoded/written/held/dropped/skipped counts, and separate output duration/FPS. Received frames are not pixel-unique. Repeated/static or late/final-only frames cannot establish smoothness. Missing metrics stay unknown; nominal FPS and `frames / fps` are not wall-clock capture evidence.
|
|
578
|
+
|
|
579
|
+
A stop timeout or `No recording in progress` result triggers one two-second native `session info` query, not another stop. `details.recordingRecovery` keeps the original failed attempt and requires matching session/namespace, recording ID/path (or an effective planned start window), terminal native encoder success and a verified file before recovering success. Same-path older receipts cannot verify a newer take. A timed-out batch may yield a verified recording while other steps remain unproven; unrelated failed-step repair actions remain available. Failed or unverified receipts still export safely to a distinct `outputPath`, with error/attempt provenance and parseable JSON. Follow the returned status/stop actions, not blind mutation retries or longer timeouts.
|
|
580
|
+
|
|
581
|
+
Detailed receipt/live-browser fields and browser-independent native read/confirm handling require companion upstream support not yet present in the current recommended release. Older supported versions remain usable with unknown metrics. Native receipt lookup lasts only while that daemon retains its memory; transcript metadata is not post-exit native recovery. See [the full receipt contract](TOOL_CONTRACT.md#recording-receipts-and-recovery).
|
|
582
|
+
|
|
567
583
|
#### Artifact retention and dogfood-heavy QA runs
|
|
568
584
|
|
|
569
585
|
The wrapper keeps a bounded, metadata-only `details.artifactManifest` of recent artifacts so long sessions do not grow unbounded. The default recent window is 100 entries and can be raised for screenshot/video-heavy QA sessions with `PI_AGENT_BROWSER_SESSION_ARTIFACT_MANIFEST_MAX_ENTRIES=<count>`.
|
|
@@ -572,7 +588,7 @@ This manifest cap controls what appears in `details.artifactManifest` and in sum
|
|
|
572
588
|
|
|
573
589
|
Browser close commands (`close`, `quit`, or `exit`) are also not file cleanup. If `details.artifactManifest` is present with a non-empty `entries` list, a successful close command appends a compact `Artifact lifecycle` note and reports `details.artifactCleanup` with the current retention summary and the same host-owned cleanup `note` as the contract (`extensions/agent-browser/lib/orchestration/browser-run/diagnostics.ts`, `getArtifactCleanupGuidance`). Up to ten distinct user-chosen paths that still exist on disk appear in `explicitArtifactPaths` when matching `explicit-path` manifest rows exist in the recent window; deleted/stale paths are skipped. Otherwise that array is empty and the visible text stays compact while the structured detail still reminds you that close commands do not delete saved files. Delete any paths you care about with host file tools after inspection; the native browser tool intentionally does not remove arbitrary user-chosen filesystem paths.
|
|
574
590
|
|
|
575
|
-
Oversized snapshots and oversized generic outputs are different: when a persisted pi session is available, their wrapper-managed spill files are stored under the private session artifact directory and are governed by the byte budget `PI_AGENT_BROWSER_SESSION_ARTIFACT_MAX_BYTES` (default 32 MiB). Raise that byte budget as
|
|
591
|
+
Oversized snapshots and oversized generic outputs are different: when a persisted pi session is available, their wrapper-managed spill files are stored under the private session artifact directory and are governed by the byte budget `PI_AGENT_BROWSER_SESSION_ARTIFACT_MAX_BYTES` (default 32 MiB). Raise that byte budget for longer retention, or set `PI_AGENT_BROWSER_SESSION_ARTIFACT_MAX_BYTES=0` to disable automatic eviction of persistent spill files. Zero leaves existing files in place as new spills are written; it does not recover files already evicted or change temporary subprocess spill cleanup.
|
|
576
592
|
|
|
577
593
|
### Switch from an already-active implicit session to a fresh profiled or alternate-browser launch
|
|
578
594
|
|
|
@@ -617,7 +633,9 @@ If the result says `Pending confirmation id: c_8f3a1234`, choose one follow-up:
|
|
|
617
633
|
{ "args": ["deny", "c_8f3a1234"] }
|
|
618
634
|
```
|
|
619
635
|
|
|
620
|
-
|
|
636
|
+
For a policy-required explicit URL read, use the returned actions: they name the actual native namespace/session, including `default`, and this routing survives resume/branch replay. The wrapper skips page helpers on matching confirm/deny only when the native read response also advertises `capabilities.readRequiresConfirmation: true`, which includes strict native ID matching. Legacy read prompts retain correct routing but normal page checks; DOM or page-content-shaped prompts never gain the exemption. Explicit caller identities and script isolation still win.
|
|
637
|
+
|
|
638
|
+
Confirmation context may be redacted when it contains credentials, tokens, cookies, or auth-bearing URLs. Replacements are marked `[REDACTED]` (URL-encoded in parsed URLs); ordinary technical phrases such as `bearer token` and `bearer authentication` stay intact outside credential fields and headers. URL scrubbing covers `code`, SAMLRequest, SAMLResponse, RelayState, `authorization_session_id`, and auth-context `state` / `nonce` while retaining ordinary non-auth query values and the spelling of URLs needing no redaction. Visible text, structured details, persisted spills, and `outputPath` exports use the same redaction; exact internal page-target URLs remain available to browser state logic. Use the id exactly as printed.
|
|
621
639
|
|
|
622
640
|
### Use stateful browser-context commands safely
|
|
623
641
|
|
|
@@ -735,7 +753,7 @@ Comboboxes vary by app. For native `<select>` controls, prefer raw `select <sele
|
|
|
735
753
|
| `state rename <old-name> <new-name>` | Rename a saved state file. |
|
|
736
754
|
| `state clear [session-name] [--all]` | Clear saved states for one name or all names; `state clear -a` is the upstream short alias for clearing all names. |
|
|
737
755
|
| `session id --scope worktree --prefix <name>` | Generate a stable session id for agent/worktree-scoped browser state. |
|
|
738
|
-
| `session info --json` |
|
|
756
|
+
| `session info --json` | One read-only preflight: daemon activity/PID versus native browser liveness, Chrome PID, exact profile, tabs and launched/attached ownership, plus separate Pi cleanup ownership. Missing native fields remain unknown; no browser launch or tab changes. |
|
|
739
757
|
| `state clean --older-than <days>` | Delete expired saved-state files. |
|
|
740
758
|
| `frame <selector|main>` | Switch iframe context by selector/ref/name/URL, or return to the main frame. |
|
|
741
759
|
| `dialog accept [text]` | Accept an alert, confirm, or prompt dialog, optionally supplying prompt text. |
|
|
@@ -850,7 +868,7 @@ Current upstream still does not parse `wait <selector> --state hidden` / `wait <
|
|
|
850
868
|
| `trace start`, `trace stop [path]` | Record a Chrome DevTools trace. |
|
|
851
869
|
| `profiler start|stop [path]` | Record a Chrome DevTools profile. |
|
|
852
870
|
| `record start <path> [url]` | Record the active page; an optional URL navigates first. Use `.webm` or `.mp4` and optional `--fps <n>` (1–60, default 30); native validates startup and requires `ffmpeg` on `PATH`. Verify output after `record stop`. |
|
|
853
|
-
| `record stop` |
|
|
871
|
+
| `record stop` | Finalize video and inspect its native receipt plus wrapper file verification. A failed or recovered stop retains original attempt evidence; use a distinct top-level `outputPath` to save its receipt. |
|
|
854
872
|
| `record restart <path> [url]` | Stop any current recording and start a new video. Supports the same formats and `--fps` option; without a URL it keeps the page and refs. |
|
|
855
873
|
| `console [--clear]` | View or clear console logs. |
|
|
856
874
|
| `errors [--clear]` | View or clear page errors. |
|
|
@@ -1006,7 +1024,7 @@ Browser default config is conservative: it adds agent guidance for signed-in/acc
|
|
|
1006
1024
|
`agent-browser` 0.35.0 and newer require separate argv tokens for global flag values (for example, `--args <args>` and `--user-agent <ua>`). The explicit exception is `--restore=<key>`, which is supported when an optional restore key could otherwise be confused with a command word. The wrapper rejects other global `--flag=value` forms before normal command dispatch, including when they trail the command. Plain `--help`, `-h`, `--version`, and `-V` inspection preserves exact caller argv because upstream accepts those top-level inspection shapes. Global flags for `batch` belong before `batch` in top-level `args`; row-local equals forms are rejected without the help/version or `--restore=<key>` exceptions.
|
|
1007
1025
|
|
|
1008
1026
|
- `--profile <name|path>`: reuse Chrome profile login state by directory name from `profiles`, or use a persistent custom profile/profile-directory path when upstream accepts it. Environment: `AGENT_BROWSER_PROFILE`.
|
|
1009
|
-
- `--session <name>`: use an isolated session. Environment: `AGENT_BROWSER_SESSION`.
|
|
1027
|
+
- `--session <name>`: use an isolated session. Environment: `AGENT_BROWSER_SESSION`. Native session names may begin with a hyphen; they remain values, not extra flags, including when selected through config or environment.
|
|
1010
1028
|
- `--restore [name]`: auto-save/restore cookies, local storage, and session storage; bare `--restore` uses `--session` as the key. Environment: `AGENT_BROWSER_RESTORE`. Wrapper-owned implicit sessions set a transcript- and checkout-scoped restore key automatically unless disabled with `PI_AGENT_BROWSER_MANAGED_SESSION_RESTORE=0` or suppressed by incompatible caller launch choices. Explicit restore/state/session/config choices pass through unchanged and remain visible in results. Automatic restore validates only its own checkout/storage identity and coordinates same-daemon reuse so wrapper restore pools cannot mix.
|
|
1011
1029
|
- `--restore-save <policy>` (`auto`, `always`, or `never`): restore auto-save policy. Environment: `AGENT_BROWSER_RESTORE_SAVE`. Restore-enabled sessions also save periodically while open; `AGENT_BROWSER_AUTOSAVE_INTERVAL_MS` sets the minimum interval in milliseconds (`30000` by default, `0` disables periodic saves but not save-on-close).
|
|
1012
1030
|
- `--restore-check-url <glob>`, `--restore-check-text <txt>`, `--restore-check-fn <js>`: validate restored state before auto-save. Environments: `AGENT_BROWSER_RESTORE_CHECK_URL`, `AGENT_BROWSER_RESTORE_CHECK_TEXT`, `AGENT_BROWSER_RESTORE_CHECK_FN`.
|
|
@@ -1043,7 +1061,7 @@ Browser default config is conservative: it adds agent guidance for signed-in/acc
|
|
|
1043
1061
|
On Android/Termux, follow the README setup to install the packaged Linux-musl arm64 upstream binary, install Termux's `which`, and expose its launcher as `$PREFIX/bin/chromium`. Prefer that upstream system-browser discovery over ambient `AGENT_BROWSER_EXECUTABLE_PATH`: it survives isolated `HOME` values, works for ordinary calls and top-level `script`, and preserves the script security boundary that clears ambient launch controls and rejects inner `--executable-path` flags. Wrapper-generated Android managed identities use a compact 80-bit digest so ordinary namespaces and fresh rotations fit upstream's Unix socket path.
|
|
1044
1062
|
|
|
1045
1063
|
- `--no-auto-dialog`: disable automatic dismissal of alert/beforeunload dialogs. Environment: `AGENT_BROWSER_NO_AUTO_DIALOG`.
|
|
1046
|
-
- `--idle-timeout <ms>`:
|
|
1064
|
+
- `--idle-timeout <ms>`: native background browser lifecycle setting (also accepts `10s`, `3m`, `1h`). Caller-owned sessions retain native idle policy; an explicit flag is carried to every helper in that call. Keep it consistent between calls to avoid a native daemon restart. Only wrapper-owned sessions receive the implicit timeout and numeric mismatch check against `PI_AGENT_BROWSER_IMPLICIT_SESSION_IDLE_TIMEOUT_MS`.
|
|
1047
1065
|
|
|
1048
1066
|
### Output, provider, policy, and AI flags
|
|
1049
1067
|
|
|
@@ -1077,6 +1095,8 @@ Standalone `agent-browser` looks for `agent-browser.json` in these locations, fr
|
|
|
1077
1095
|
3. Environment variables, including `AGENT_BROWSER_CONFIG`.
|
|
1078
1096
|
4. CLI flags.
|
|
1079
1097
|
|
|
1098
|
+
Native `session` and `namespace` defaults are honored by ordinary tool calls before implicit-session generation; `sessionName` is only a legacy restore key. Per-call flags override environment, which overrides project/user JSON. `--config` or `AGENT_BROWSER_CONFIG` selects one file instead of merging the discovered files; per-call config also reaches helper subprocesses. Caller-owned native `AGENT_BROWSER_SOCKET_DIR` is honored unless the wrapper-specific socket override is set. Script alone bypasses these defaults with an empty temporary config.
|
|
1099
|
+
|
|
1080
1100
|
Use separated `--config <path>` to load a specific upstream config; upstream 0.33.2 does not recognize `--config=<path>` as the global selector. Browser-backed and sessionless native calls preserve `--config`, `AGENT_BROWSER_CONFIG`, passive project/user config, and other upstream environment exactly as supplied. The Pi-scoped package config under `.pi/config/pi-agent-browser-native/` remains separate. Boolean flags accept optional `true` or `false` values, such as `--headed false`, `--webgpu false`, or `--no-webmcp false`, to override config. Browser extensions from user and project configs are merged rather than replaced.
|
|
1081
1101
|
|
|
1082
1102
|
Other useful environment variables include `AGENT_BROWSER_DEFAULT_TIMEOUT`, `AGENT_BROWSER_AUTOSAVE_INTERVAL_MS`, `AGENT_BROWSER_STREAM_PORT`, `AGENT_BROWSER_STREAM_QUALITY`, `AGENT_BROWSER_STREAM_MAX_WIDTH`, `AGENT_BROWSER_STREAM_MAX_HEIGHT`, `AGENT_BROWSER_IDLE_TIMEOUT_MS`, `AGENT_BROWSER_ENCRYPTION_KEY`, `AGENT_BROWSER_STATE_EXPIRE_DAYS`, `AGENT_BROWSER_IOS_DEVICE`, `AGENT_BROWSER_IOS_UDID`, `AI_GATEWAY_URL`, `AI_GATEWAY_API_KEY`, provider credential names, and AWS credential names when using AgentCore. The upstream child receives the parent environment plus wrapper overrides such as the managed socket directory, clamped default operation timeout, canonical owned-session namespace (including empty default), and Pi-transcript- plus Git-checkout-generation-scoped `AGENT_BROWSER_RESTORE` for wrapper-owned managed sessions (`buildAgentBrowserProcessEnv` in `extensions/agent-browser/lib/process.ts`, ownership carried by the wrapper's typed process options and call-scoped managed-session context). Model-facing output still redacts recognized secret values.
|
|
@@ -1089,14 +1109,14 @@ Other useful environment variables include `AGENT_BROWSER_DEFAULT_TIMEOUT`, `AGE
|
|
|
1089
1109
|
<!-- agent-browser-playbook:start wrapper-tab-recovery -->
|
|
1090
1110
|
<!-- Generated from extensions/agent-browser/lib/playbook.ts. Run `npm run docs -- playbook write` to update. -->
|
|
1091
1111
|
- After open/goto/navigate calls with --profile, --restore, --session-name, or --state, agent_browser best-effort re-selects the tab whose URL matches the returned page when restored tabs steal focus during launch or reconnect.
|
|
1092
|
-
- After confirmed shutdown of an automatically restored managed session, the wrapper retains its complete recorded URL, including the fragment, until the first current-page operation (including get url and reload). Non-page calls such as tab list
|
|
1112
|
+
- After confirmed shutdown of an automatically restored managed session, the wrapper retains its complete recorded URL, including the fragment, until the first current-page operation (including get url and reload). Non-page calls such as tab list may start a daemon without fulfilling that reopen; explicit URL reads leave the managed browser and pending reopen untouched. The wrapper uses native open once, verifies the observed tab, and discards old refs/frame scope; it does not restore unsaved forms, JavaScript memory, or history. Explicit navigation, caller-owned/attached sessions, and restore-disabled sessions are not auto-reopened.
|
|
1093
1113
|
- For a still-live browser after tab drift or resume, the wrapper verifies/selects the intended tab before ref/semantic helpers and page commands; failed selection stops the call without navigating. Local commands, read <url>, URL a11y/vitals, diff url, window new, and explicit tab/navigation/connection/state recovery do not require the prior tab. Batch checks follow effective rows past non-page prefixes and stop at explicit context changes, preserving caller argv/stdin and continue-on-error behavior. Same-tab reselection is avoided because it clears refs. Use exact batch --bail for fail-fast, not --bail=<value>. Routine same-session calls skip tab-list preflights.
|
|
1094
1114
|
- For sessions with observed tab-drift risk, after a successful command on a known target tab, agent_browser also best-effort restores that intended tab if a restored/background tab steals focus after the command completes. Routine same-session commands skip this post-command tab-list probe.
|
|
1095
1115
|
- If a known session target unexpectedly reports about:blank, agent_browser best-effort re-selects the prior intended target when it still exists; if recovery fails, it records the observed about:blank target and reports exact recovery guidance instead of treating the prior page as active.
|
|
1096
1116
|
- If upstream reports tab_gone, the pinned bound tab is gone; use details.nextActions (tab list / tab new) instead of assuming another tab is yours.
|
|
1097
1117
|
<!-- agent-browser-playbook:end wrapper-tab-recovery -->
|
|
1098
|
-
- Wrapper-spawned commands clamp `AGENT_BROWSER_DEFAULT_TIMEOUT` to the upstream documented 25-second default and use a 35-second child-process watchdog (`PI_AGENT_BROWSER_PROCESS_TIMEOUT_MS` overrides the default 35s budget; top-level `timeoutMs` overrides it per browser CLI call). Explicit `wait <ms>`, `wait --timeout <ms>`, and WebMCP `invoke` / `result --timeout <ms>` calls can exceed that default; when top-level `timeoutMs` is omitted, the wrapper derives a subprocess watchdog from the requested command duration plus a small grace window. Batch budgeting and timeout recovery read the same effective source as upstream: raw command strings when present, otherwise stdin rows. Dialog commands are additionally bounded to 5 seconds (`PI_AGENT_BROWSER_DIALOG_PROCESS_TIMEOUT_MS`), and click/tap/find refs or tokens plus `eval --stdin` snippets that look like alert/confirm/prompt/dialog triggers are bounded to 8 seconds (`PI_AGENT_BROWSER_DIALOG_TRIGGER_PROCESS_TIMEOUT_MS`). When
|
|
1099
|
-
- Oversized snapshots and oversized generic outputs may be compacted in tool content, with the full redacted output written to a spill file path shown directly in the tool result. Recent artifact metadata is bounded by `PI_AGENT_BROWSER_SESSION_ARTIFACT_MANIFEST_MAX_ENTRIES` (default 100); persisted spill files
|
|
1118
|
+
- Wrapper-spawned commands clamp `AGENT_BROWSER_DEFAULT_TIMEOUT` to the upstream documented 25-second default and use a 35-second child-process watchdog (`PI_AGENT_BROWSER_PROCESS_TIMEOUT_MS` overrides the default 35s budget; top-level `timeoutMs` overrides it per browser CLI call). Explicit `wait <ms>`, `wait --timeout <ms>`, and WebMCP `invoke` / `result --timeout <ms>` calls can exceed that default; when top-level `timeoutMs` is omitted, the wrapper derives a subprocess watchdog from the requested command duration plus a small grace window. Batch budgeting and timeout recovery read the same effective source as upstream: raw command strings when present, otherwise stdin rows. Dialog commands are additionally bounded to 5 seconds (`PI_AGENT_BROWSER_DIALOG_PROCESS_TIMEOUT_MS`), and click/tap/find refs or tokens plus `eval --stdin` snippets that look like alert/confirm/prompt/dialog triggers are bounded to 8 seconds (`PI_AGENT_BROWSER_DIALOG_TRIGGER_PROCESS_TIMEOUT_MS`). A `session info` timeout returns only an exact-session `retry-session-info` status action, without page probes, liveness claims, or changes to existing page/ref state. When a browser-operation watchdog fires, `details.timeoutPartialProgress` may include a planned step list with per-step status (including `generatedFrom` labels for wrapper-inserted rows such as `open.loadState`) and a `retry-timeout-step` next action with a one-row native batch (`args: ["batch"]` plus `stdin`) only when the first incomplete step is read-only or idempotent, or `inspect-current-page-after-timeout` when the target is already verified but the incomplete step may be mutating and should not be blindly retried. If the target is unknown, standalone snapshots are removed and visible failure text plus `details.nextActions` show `verify-page-target-after-timeout`, including its session-scoped `batch --bail` args and short stdin for fail-fast `get url` then `snapshot -i`; dialog status/accept/dismiss actions remain allowed for blocking-dialog recovery. It also includes current page URL from best-effort session `get url`, followed by `get title` only after a URL is recovered (or a planned URL inferred from the step list when the session cannot answer), an `openedButPostOpenTimedOut` classification only when a live page URL was recovered before a later step hung, and declared artifact paths such as `screenshot`, `pdf`, `download`, or `wait --download` outputs with existence/state checks; the same evidence is appended under `Timeout partial progress` in visible text with URL/path redaction.
|
|
1119
|
+
- Oversized snapshots and oversized generic outputs may be compacted in tool content, with the full redacted output written to a spill file path shown directly in the tool result. Recent artifact metadata is bounded by `PI_AGENT_BROWSER_SESSION_ARTIFACT_MANIFEST_MAX_ENTRIES` (default 100); persisted spill files have a separate `PI_AGENT_BROWSER_SESSION_ARTIFACT_MAX_BYTES` budget (default 32 MiB; `0` disables automatic eviction).
|
|
1100
1120
|
- The wrapper keeps `--help` and `--version` stateless so they do not consume the implicit managed-session slot.
|
|
1101
1121
|
|
|
1102
1122
|
## Generated capability baseline
|
package/docs/RELEASE.md
CHANGED
|
@@ -47,6 +47,8 @@ npm run verify -- pre-pr
|
|
|
47
47
|
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
|
|
48
48
|
4. `npm run smoke:platform:doctor` and the full Crabbox matrix from [`platform-smoke.md`](platform-smoke.md): macOS SSH, Ubuntu local-container, and native Windows Parallels targets running fast target-local `platform-build` plus `browser-dogfood-smoke`
|
|
49
49
|
|
|
50
|
+
The 0.6.12 release uses the documented [local macOS and hosted native-Windows alternatives](platform-smoke.md#alternate-native-transports) instead of SSH and Parallels. Run and inspect those target-local suites separately alongside the remaining release checks. The default composed gate is unchanged; alternate evidence must not be labeled a passing Crabbox matrix.
|
|
51
|
+
|
|
50
52
|
`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.
|
|
51
53
|
|
|
52
54
|
`prepublishOnly` intentionally does **not** run the standalone host-only `npm run verify -- startup-profile`, `npm run verify -- real-upstream`, `npm run verify -- dogfood` modes; those remain separate `npm run verify` modes in [`scripts/project.mjs`](https://github.com/fitchmultz/pi-agent-browser-native/blob/main/scripts/project.mjs). The platform matrix includes its own fast target-local build/package gate and browser dogfood suite, and is automated through the `release` slice.
|
|
@@ -289,7 +291,7 @@ For a root-check change, run the identical final test against both the pre-fix a
|
|
|
289
291
|
|
|
290
292
|
- **Focused and broad cases:** `test/agent-browser.real-upstream-contract.test.ts` keeps the broad command matrix in one 180-second case and separate 60-second cold-reopen, duplicate-name click-mutation, navigation-availability/tab-setup, and sessionless-plugin cases. The `real-upstream` facade's `contract suite matches` selection includes the broad matrix, cold reopen, click mutation, and navigation setup. The click case uses two native DOM buttons to prove a stale duplicate ordinal cannot contradict trusted target events, while exact XPath probes still detect missing events and native clicks remain dispatch-only evidence.
|
|
291
293
|
- **Output-shape locking:** Expected `details` / `data` keys per step live in `test/fixtures/agent-browser-real-output-shapes.json`, keyed by logical groups (`version`, `rootHelp`, `commandHelp`, `skillsList`, `skillsGetFull`, `skillsPath`, `open`, `eval`, `snapshot`, `coreCommand`, `coreSubcommand`, `coreFileArtifact`, `batch`, `pushstate`, `vitals`, `networkRoute`, `nonCoreStatus`, `nonCoreArtifact`, `diffScreenshotArtifact`, `streamControl`, `streamStatus`, `cookiesCurl`, `reactMissingRenderer`, `waitDownload`). Keep `targetVersion` in that file aligned with `scripts/agent-browser-capability-baseline.mjs`, and extend entries whenever the suite starts asserting on new presentation fields.
|
|
292
|
-
- **Isolation:** The harness
|
|
294
|
+
- **Isolation:** The harness uses a throwaway HOME and screenshot directory, and pairs `PI_AGENT_BROWSER_SOCKET_DIR` with `AGENT_BROWSER_SOCKET_DIR` in a short private socket directory. This keeps owned commands and native policy probes on the same daemon without exceeding Unix socket path limits. Raw click/FPS helpers retain owned-session context; cold-resume observers use the registered tool so they do not restart the browser they are measuring. The harness serves loopback fixtures, closes its sessions and removes only its own directories; it does not reuse your normal profile or socket locations.
|
|
293
295
|
- **React DevTools branch:** After the core matrix, the suite performs another `open` with `--enable react-devtools` and `sessionMode: "fresh"`, then expects `react tree` to fail with a missing-renderer style error on the same non-React contract page. The following download fixture + `wait --download` assertions run against whichever managed session is current after that fresh `open` (typically the React DevTools session), not the original pre-matrix session name.
|
|
294
296
|
|
|
295
297
|
**Troubleshooting**
|
package/docs/SUPPORT_MATRIX.md
CHANGED
|
@@ -57,17 +57,21 @@ Current summary:
|
|
|
57
57
|
| RQ-0139 | Upstream `agent-browser 0.33.2` rebaseline documents daemon idle timeout, streaming controls, and tab recovery. Wrapper-owned implicit sessions add transcript/checkout-scoped automatic restore with current v3 ticket-claim daemon coordination, verified snapshot retention, and page-target verification after ambiguous transitions. Explicit sessions, state/restore paths, config, file access, launch environment, local pages, output paths, and close arguments pass through unchanged; session/state lists keep all rows and identifiers visible. | [`docs/COMMAND_REFERENCE.md`](COMMAND_REFERENCE.md#upstream-0332-rebaseline), [`docs/ARCHITECTURE.md`](ARCHITECTURE.md) |
|
|
58
58
|
| RQ-0140 | Successful CDP/auto-connect and Electron sessions preserve one attached browser across native-tool follow-ups and cleanup by omitting wrapper local-launch defaults, with environment support, branch replay, first-use content blocking, live URL gates against external drift, and close cleanup. | [`docs/ARCHITECTURE.md`](ARCHITECTURE.md), [`docs/TOOL_CONTRACT.md`](TOOL_CONTRACT.md), `test/agent-browser.extension-passthrough-validation.test.ts` |
|
|
59
59
|
| RQ-0141 | Headed managed sessions avoid upstream 0.33.2 visible autosave targets by default and retain that daemon environment across helpers, still-owned off-current follow-ups, failed-replacement ownership, Electron cleanup, and reload/resume; slow daemon-policy inspection uses a 35-second budget; headed mode is launch-scoped; the effective launch interval persists across resume and changes in either direction require close plus a fresh daemon; and bare, review-only, fenced-reference, conditional, directly negated, or reference attachment paths do not become close-blocking output requirements while explicit contiguous output path lists, per-clause availability, duplicate precedence, and Markdown destinations are handled conservatively and linearly. | [`docs/ARCHITECTURE.md`](ARCHITECTURE.md), [`docs/TOOL_CONTRACT.md`](TOOL_CONTRACT.md), `test/agent-browser.managed-session-daemon-policy.test.ts`, `test/agent-browser.process.test.ts`, `test/agent-browser.prompt-policy.test.ts` |
|
|
60
|
-
| RQ-0142 | Top-level `script` provides bounded one-shot JavaScript loops, branches, and multi-page aggregation through the complete ordinary browser executor. A permissioned child exposes only null-prototype `browser` / `emit` task functions, receives no user-visible host capabilities, serializes at most 25 calls, and uses a unique restore-disabled wrapper session with a durable pre-spawn Pi lease, finally-close, active branch/shutdown abort-and-wait cleanup (including upstream-version preflight), and exact lease recovery. Script-owned helpers/cleanup case-insensitively clear ambient upstream launch/profile/restore/attachment and proxy controls; final data is compact-serialized with a second post-redaction byte/depth guard; rehydrated spills reserve IPC-envelope headroom, inner summary/text are bounded, complete response envelopes are size-checked, and script-visible next actions are policy-compatible after isolated identity removal; malformed bridge calls and missing workers fail structurally; policy-rejection and dispatched-failure counters are disjoint. The collapsed Pi call row shows a bounded terminal-safe source preview with visible line-break markers and its expanded state shows the full terminal-safe source with JavaScript line terminators preserved and removed controls marked. It requires persisted Pi sessions, classifies uncaught source exceptions as `script-error`, confirms successful cleanup in compact prose, and deliberately has no named recipe/import/shared-state surface. The same dogfood pass compacted common/QA output, made failure `nextActions` model-visible and exact-namespace/session-stable (including explicit empty namespace overrides), limited close cleanup guidance to existing explicit artifacts, clarified raw batch stdin, normalized empty semantic names, and added bounded timeout/navigation recovery actions. | [`docs/TOOL_CONTRACT.md`](TOOL_CONTRACT.md#script), [`docs/ARCHITECTURE.md`](ARCHITECTURE.md#one-shot-script-isolation), [`docs/COMMAND_REFERENCE.md`](COMMAND_REFERENCE.md#one-shot-code-mode), `test/agent-browser.script.test.ts` |
|
|
60
|
+
| RQ-0142 | An optional host [`beforeExecute` callback](TOOL_CONTRACT.md#host-execution-hook) uses Pi sequential scheduling and the existing inner-call queue to save state before dispatch, retaining the outer tool-call ID and per-dispatch cancellation (`test/agent-browser.pi-pipeline.test.ts`). Top-level `script` provides bounded one-shot JavaScript loops, branches, and multi-page aggregation through the complete ordinary browser executor. A permissioned child exposes only null-prototype `browser` / `emit` task functions, receives no user-visible host capabilities, serializes at most 25 calls, and uses a unique restore-disabled wrapper session with a durable pre-spawn Pi lease, finally-close, active branch/shutdown abort-and-wait cleanup (including upstream-version preflight), and exact lease recovery. Script-owned helpers/cleanup case-insensitively clear ambient upstream launch/profile/restore/attachment and proxy controls and bypass user/project config; inner `--config` is rejected before dispatch while ordinary `args` retains it; final data is compact-serialized with a second post-redaction byte/depth guard; rehydrated spills reserve IPC-envelope headroom, inner summary/text are bounded, complete response envelopes are size-checked, and script-visible next actions are policy-compatible after isolated identity removal; malformed bridge calls and missing workers fail structurally; policy-rejection and dispatched-failure counters are disjoint. The collapsed Pi call row shows a bounded terminal-safe source preview with visible line-break markers and its expanded state shows the full terminal-safe source with JavaScript line terminators preserved and removed controls marked. It requires persisted Pi sessions, classifies uncaught source exceptions as `script-error`, confirms successful cleanup in compact prose, and deliberately has no named recipe/import/shared-state surface. The same dogfood pass compacted common/QA output, made failure `nextActions` model-visible and exact-namespace/session-stable (including explicit empty namespace overrides), limited close cleanup guidance to existing explicit artifacts, clarified raw batch stdin, normalized empty semantic names, and added bounded timeout/navigation recovery actions. | [`docs/TOOL_CONTRACT.md`](TOOL_CONTRACT.md#script), [`docs/ARCHITECTURE.md`](ARCHITECTURE.md#one-shot-script-isolation), [`docs/COMMAND_REFERENCE.md`](COMMAND_REFERENCE.md#one-shot-code-mode), `test/agent-browser.script.test.ts` |
|
|
61
61
|
| RQ-0143 | Browser-backed calls require a stable upstream version at or above the configured 0.35.0 floor, report minimum/observed version mismatch before launch, and keep stateless/local diagnostics available; the recommended target and minimum are shared by runtime, docs verification, and package contents. | [`scripts/agent-browser-target.mjs`](../scripts/agent-browser-target.mjs), [`docs/COMMAND_REFERENCE.md`](COMMAND_REFERENCE.md#upstream-0360-rebaseline), `test/agent-browser.upstream-version.test.ts` |
|
|
62
62
|
| RQ-0144 | Managed restore keys are scoped to both checkout generation and Pi transcript so upstream 0.33.2's newest-file-wins loading cannot let concurrent chats clobber or inherit cookies/storage. Fresh rotations, reload, restart, and `/resume` of one transcript retain continuity; after a confirmed inactive daemon, a branch-restored compatible owned session retains its pending reopen through daemon-starting non-page calls and transcript replay, then reopens the complete recorded URL (including its fragment) before current-page operations such as `get url` or `reload`, verifies the actual target and invalidates old refs. This reloads a URL, not forms, JavaScript memory, or history; live wrong-tab recovery never auto-navigates. Passive and explicit upstream configs pass through, while explicit config selection suppresses the wrapper's automatic restore injection. | [`docs/ARCHITECTURE.md`](ARCHITECTURE.md), [`docs/TOOL_CONTRACT.md`](TOOL_CONTRACT.md), `test/agent-browser.managed-session-restore.test.ts`, `test/agent-browser.real-upstream-contract.test.ts` |
|
|
63
|
-
| RQ-0145 | Mega-dogfood correctness closes false-positive success paths: URL QA
|
|
63
|
+
| RQ-0145 | Mega-dogfood correctness closes false-positive success paths: URL QA makes matched post-clear page-error evidence non-pass as unverified, counts definitely new errors separately, and waits 150 ms for immediate post-load diagnostics, stale pre-existing artifacts and missing/stale recordings finalized by restart fail verification, aliased destinations (including dangling symlinks, full macOS/Windows Unicode folds, final short/long diff output flags, and same-call `outputPath` aliases) and active recording-path reuse through artifacts, path-bearing HAR stops, long/short or reordered explicit download waits, interspersed-global command forms, Electron cleanup output, or normalized output writes is rejected through an atomic process-wide, transcript-backed namespace/session reservation index independent of bounded manifest eviction; cross-branch close tombstones survive reload and each direct or ordered nested close retires exact identity at that lifecycle point while terminal closes clear attached/ref/page/route state, later lifecycle-proven browser launches—including failed post-close rows and `record stop`—can reactivate/rebuild it without stale pre-close `about:blank` recovery while bounded launch evidence survives failed-step presentation and transcript replay, explicitly non-launching diagnostics preserve the close, missing evidence stays conservatively active even on the first managed call, every successful direct/nested close clears wrapper trace/profiler ownership before later successful rows can rebuild it, and namespace-scoped `close --all` clears all matching managed/attached/page/ref/route/trace/recording ownership, only the newest pending recording path remains authoritative even across same-timestamp restart rows, current recording transitions replay directly without artifact-manifest compatibility inference, definitive direct/batch no-recording stop failures retire stale state at their ordered step, recording starts after nested close are rejected, pending rows coalesce into terminal batch outcomes without retaining an intermediate close-abandoned duplicate after a later saved stop, and any later same-session failure retains exact cleanup actions, same-page getter refs are refreshed, locator select resolves exact current native controls, no-movement scroll fails honestly, and script cleanup always attempts fail-closed close. | [`docs/TOOL_CONTRACT.md`](TOOL_CONTRACT.md#details), [`docs/COMMAND_REFERENCE.md`](COMMAND_REFERENCE.md), `test/agent-browser.extension-input-modes.test.ts`, `test/agent-browser.extension-ref-guards.test.ts`, `test/agent-browser.presentation.test.ts`, `test/agent-browser.presentation-artifacts-batch.test.ts`, `test/agent-browser.recording-reservations.test.ts`, `test/agent-browser.extension-validation.test.ts`, `test/agent-browser.script.test.ts` |
|
|
64
64
|
| RQ-0146 | Upstream `agent-browser 0.34.0` rebaseline adds sticky `--pin-tab` / `--no-pin-tab` (`AGENT_BROWSER_PIN_TAB`) for shared CDP/auto-connect sessions, CDP target ids as tab refs, and `tab_gone` recovery data (`data.targetId`, optional `data.lastUrl`). The wrapper parses those flags as optional global booleans rather than launch-scoped, classifies `tab_gone` as `failureCategory: "tab-gone"` with `list-tabs-after-tab-gone` / `open-tab-after-tab-gone`, and shows `targetId` in `tab list` presentation. | [`docs/COMMAND_REFERENCE.md`](COMMAND_REFERENCE.md#upstream-0340-rebaseline), [`docs/TOOL_CONTRACT.md`](TOOL_CONTRACT.md#details), `test/agent-browser.results.test.ts`, `test/agent-browser.runtime.test.ts` |
|
|
65
65
|
| RQ-0147 | Native follow-ups preserve profiled and other launch-configured browser pages by omitting wrapper compatibility launch arguments while the daemon is active; daemon inspection reapplies the retained compatibility user agent only when relaunch is required. Caller `--args`, config, file access, and local navigation pass through unchanged, and cancellation wins over policy validation before spawn. | [`docs/ARCHITECTURE.md`](ARCHITECTURE.md), [`docs/TOOL_CONTRACT.md`](TOOL_CONTRACT.md), `test/agent-browser.runtime.test.ts`, `test/agent-browser.process.test.ts`, `test/agent-browser.real-upstream-contract.test.ts` |
|
|
66
66
|
| RQ-0148 | Upstream 0.35.0 adds Linux Chromium private CA trust and the `protected-vercel-deployments` skill. The wrapper parses CA set/clear globals, requires fresh managed launches, suppresses automatic managed restore for CA-enabled sessions, passes caller certificate paths upstream unchanged, and uses 0.35.0 as its runtime floor. | [`docs/COMMAND_REFERENCE.md`](COMMAND_REFERENCE.md#upstream-0350-rebaseline), [`docs/TOOL_CONTRACT.md`](TOOL_CONTRACT.md), `test/agent-browser.runtime.test.ts`, `test/agent-browser.managed-session-restore.test.ts`, `test/agent-browser.page-target-validation.test.ts` |
|
|
67
67
|
| RQ-0149 | Upstream 0.35.1 fixes snapshot-diff ref lifecycle, active-main-frame stream URL updates, and Windows ARM64 launcher selection without adding commands or flags. The wrapper preserves the 0.35.0 stable floor and accepts newer stable versions without version-specific shims. | [`docs/COMMAND_REFERENCE.md`](COMMAND_REFERENCE.md#upstream-0351-rebaseline), [`scripts/agent-browser-target.mjs`](../scripts/agent-browser-target.mjs), `test/agent-browser.upstream-version.test.ts`, `test/agent-browser.real-upstream-contract.test.ts` |
|
|
68
68
|
| RQ-0150 | Upstream 0.35.2 hardens standalone dashboard origin access and fixes root remote CDP WebSocket query URLs. The wrapper parses `--allowed-origins` as a value and keeps explicit or implicit dashboard-start lifecycle calls sessionless; upstream owns origin validation, tokens, and the CDP fix. | [`docs/COMMAND_REFERENCE.md`](COMMAND_REFERENCE.md#upstream-0352-rebaseline), [`docs/TOOL_CONTRACT.md`](TOOL_CONTRACT.md#dashboard-reverse-proxy-origins), `test/agent-browser.runtime.test.ts` |
|
|
69
69
|
| RQ-0151 | Upstream 0.36.0 adds experimental WebMCP page tools, default local-Chrome enablement with launch-scoped `--no-webmcp`, an opt-in MCP profile, and the `webmcp-gen` skill. The wrapper passes list/invoke/result/cancel through, preserves params/frame/detach/timeout arguments, derives watchdogs from effective direct/raw/stdin commands, keeps pending detached targets unverified, and restores batch target/ref state only after URL verification and a fresh snapshot, while keeping 0.35.0 as the stable floor. | [`docs/COMMAND_REFERENCE.md`](COMMAND_REFERENCE.md#upstream-0360-rebaseline), [`docs/TOOL_CONTRACT.md`](TOOL_CONTRACT.md#experimental-webmcp), `test/agent-browser.runtime.test.ts`, `test/agent-browser.wait-timeouts.test.ts`, `test/agent-browser.process.test.ts`, `test/agent-browser.page-target-validation.test.ts`, `test/agent-browser.extension-ref-guards.test.ts`, `test/agent-browser.real-upstream-contract.test.ts` |
|
|
70
|
-
| 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 selection/close live-verifies URL/fresh titles and retains deliberate 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;
|
|
70
|
+
| 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 selection/close live-verifies URL/fresh titles and retains deliberate 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` |
|
|
71
|
+
|
|
72
|
+
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.
|
|
73
|
+
|
|
74
|
+
Browser evidence (RQ-0152) is covered by `test/agent-browser.browser-evidence.test.ts`, `test/agent-browser.read-confirmation.test.ts`, `test/agent-browser.recording-receipts.test.ts` and `test/agent-browser.recording-recovery.test.ts`, alongside existing presentation, reservation/replay and lifecycle checks. They cover cold/shared/unknown/invalid/timeout reads, native-default and shared confirmation routing, capability absence and script identity boundaries, separate daemon/browser/Pi identity, sparse/legacy capture metrics, native failure retention, stale/same-path mismatches, one-query stop recovery, error exports and artifact aliases. Full live identity, receipt lookup and browser-independent native read/confirm handling require companion upstream fixes; missing fields remain unknown, and native receipts do not survive daemon exit. These source checks do not replace paired native/Pi runtime verification.
|
|
71
75
|
|
|
72
76
|
Contributor fixes #133/#152 remove unused prompt suffix entries without changing runtime guidance and diagnose bare `--no-sandbox` only in the command slot or navigation option positions. Native `--args` values and literal operands remain intact; batch checks use raw effective rows without treating row-local `--args` as a launch setting. `test/agent-browser.chromium-args.test.ts` covers pre-dispatch rejection, literal/flag-value controls, inspection, raw/stdin batch precedence and dispatcher outcomes. Existing prompt/grammar checks remain; source checks do not replace native-product gates.
|
|
73
77
|
|
|
@@ -77,7 +81,7 @@ Artifact diagnostics (#124/#127) use a shared pre-dispatch mkdir-error boundary,
|
|
|
77
81
|
|
|
78
82
|
Upstream 0.37 recording compatibility uses one command-local path/URL reader around numeric `--fps` pairs; direct, raw-batch and stdin-batch preflight reject destination collisions before native dispatch. FPS-only calls keep the intended pinned tab, and FPS-only restarts keep refs. Every dispatched start still requires fresh refs to protect older supported natives. `test/agent-browser.artifact-diagnostics.test.ts`, `test/agent-browser.batch-fidelity.test.ts` and presentation tests cover these boundaries. The native contract also checks positive/absent WebMCP hints and first-load header inheritance/clearing without custom tab setup. Short/cold native Ubuntu captures can fail to encode; the FPS fixture explicitly logs 12-second captures and verifies output rather than treating an empty file as a frame.
|
|
79
83
|
|
|
80
|
-
Artifact argv and timeout recovery (#119, RQ-0076) use native operand positions, retain literal global-looking tokens inside batch rows, and select raw batch commands instead of ignored stdin. Executable timeout retries preserve the original row in a one-row batch. Interleaved `wait --download` / `-d` timeout pairs keep the next retained path and its original index. Runtime, artifact-diagnostics, and timeout tests cover extraction, reservation, preparation, and presentation; `test/agent-browser.batch-fidelity.test.ts` adds real native saved-file, missing wait-download, reservation, and watchdog evidence under `npm run verify -- real-upstream`. Getter batching amortizes one extra ref-freshness snapshot per top-level call or batch when the existing checks apply.
|
|
84
|
+
Artifact argv and timeout recovery (#119, RQ-0076) use native operand positions, retain literal global-looking tokens inside batch rows, and select raw batch commands instead of ignored stdin. Executable timeout retries preserve the original row in a one-row batch. Interleaved `wait --download` / `-d` timeout pairs keep the next retained path and its original index. Runtime, artifact-diagnostics, and timeout tests cover extraction, reservation, preparation, and presentation; `test/agent-browser.batch-fidelity.test.ts` adds real native saved-file, missing wait-download, reservation, and watchdog evidence under `npm run verify -- real-upstream`. Getter batching amortizes one extra ref-freshness snapshot per top-level call or batch when the existing checks apply. Direct `session info` timeouts stay status-only (`retry-session-info`), preserving page/ref/reopen state; cold-boundary and result tests cover this.
|
|
81
85
|
|
|
82
86
|
Cold URL reopen is covered by `test/agent-browser.cold-resume.test.ts`, the daemon/page-boundary regressions in `test/agent-browser.cold-boundaries.test.ts`, and the opt-in `contract suite matches cold URL reopen after quit` case in `test/agent-browser.real-upstream-contract.test.ts`. Deterministic boundary tests cover non-page prefixes, fragment routes, history commands, explicit destinations, transcript replay, unreached navigation and unchanged native batch/error order. `test/agent-browser.destination-cancel.test.ts` covers direct/native-batch new-window and URL-diff follow-ups, redirected/unknown targets (including blank redirects with a remembered duplicate tab), ordered ref invalidation, reached versus unreached rows, and cancellation before or after a cold-reopen attempt with replay and process cleanup. Release acceptance requires the first page operation after confirmed shutdown to observe the remembered non-root URL with both empty and origin storage, including after non-page calls and on hash-routed pages, before any explicit open, with refreshed refs. Focused native Mac evidence does not replace actual Ubuntu, real Pi lifecycle, checkout, live-site, or final release gates.
|
|
83
87
|
|
|
@@ -85,6 +89,8 @@ Batch/ref fidelity (#122/#123/#125/#126): tab recovery uses verified native sele
|
|
|
85
89
|
|
|
86
90
|
Overlay recovery (RQ-0073, #147) recommends only `inspect-overlay-state` after an upstream covered-click rejection, preserving `upstream-error` and the exact session/namespace. Direct, semantic, raw `find` (including `nth` and default-click), and failed batch/job paths share the matcher; hover and generic errors do not qualify. `test/agent-browser.overlay-click-recovery.test.ts` covers presentation and error envelopes, `test/agent-browser.pi-pipeline.test.ts` covers persisted errors and parseable JSON, and the opt-in `test/agent-browser.overlay-real-upstream.test.ts` checks actual covered clicks, executable inspection, and unchanged target/blocker click counters. This is not a fix for silent input dispatch (#62).
|
|
87
91
|
|
|
92
|
+
Shared native defaults are covered by `test/agent-browser.shared-defaults.test.ts`: environment/file/argv precedence, caller-owned reuse across independent Pi contexts, quit ownership, native helper idle settings, unchanged implicit cleanup, and an opt-in real local-profile fixture proving shared state and disposable-script separation. `test/agent-browser.script.test.ts` checks empty native config on helpers and cleanup; the local Electron handoff regression in `test/agent-browser.extension-electron-lifecycle.test.ts` keeps generated launch ownership despite a native session environment default; native config validation uses upstream rather than a second schema. See [shared browser defaults](../README.md#shared-browser-defaults). These tests do not promise permanent third-party authentication.
|
|
93
|
+
|
|
88
94
|
## Verification evidence
|
|
89
95
|
|
|
90
96
|
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.37.0 candidate. 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. Current source qualification uses direct macOS and actual Ubuntu with official Pi 0.85.1; native Windows is unrun under a task-specific waiver, not reported as passed. Release-only model/lifecycle and publication gates remain separate.
|