pi-agent-browser-native 0.8.1 → 0.8.3
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 +33 -0
- package/README.md +16 -7
- package/dist/extensions/agent-browser/index.js +440 -163
- package/dist/extensions/agent-browser/lib/browser-journal.js +418 -0
- package/dist/extensions/agent-browser/lib/browser-session-conversion.js +381 -0
- package/dist/extensions/agent-browser/lib/browser-transcript.js +119 -19
- package/dist/extensions/agent-browser/lib/input-modes/job.js +49 -2
- package/dist/extensions/agent-browser/lib/input-modes/params.js +32 -35
- package/dist/extensions/agent-browser/lib/managed-session-policy-lock.js +25 -5
- package/dist/extensions/agent-browser/lib/managed-session-restore.js +20 -5
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/managed-session-daemon-policy.js +97 -78
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare.js +23 -2
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output.js +52 -17
- package/dist/extensions/agent-browser/lib/orchestration/electron-host/index.js +1 -1
- package/dist/extensions/agent-browser/lib/orchestration/script-mode.js +13 -8
- package/dist/extensions/agent-browser/lib/playbook.js +9 -2
- package/dist/extensions/agent-browser/lib/prompt-policy.js +0 -14
- package/dist/extensions/agent-browser/lib/results/presentation/large-output.js +2 -1
- package/dist/extensions/agent-browser/lib/session-page-state.js +95 -157
- package/dist/extensions/agent-browser/lib/temp.js +14 -6
- package/dist/extensions/agent-browser/lib/tool-surface.js +15 -11
- package/dist/extensions/agent-browser/lib/web-search.js +0 -8
- package/docs/ARCHITECTURE.md +15 -9
- package/docs/COMMAND_REFERENCE.md +10 -6
- package/docs/RELEASE.md +3 -3
- package/docs/REQUIREMENTS.md +1 -1
- package/docs/SESSION_STORAGE.md +60 -0
- package/docs/SUPPORT_MATRIX.md +8 -5
- package/docs/TOOL_CONTRACT.md +19 -14
- package/package.json +9 -5
- package/scripts/build.mjs +4 -3
- package/scripts/convert-browser-session.mjs +22 -0
package/docs/ARCHITECTURE.md
CHANGED
|
@@ -23,6 +23,10 @@ The package install path is the primary product path. Local checkout development
|
|
|
23
23
|
|
|
24
24
|
Optional `agent_browser_web_search` remains separately credential/config gated and independent of browser state.
|
|
25
25
|
|
|
26
|
+
The extension factory subscribes synchronously to the public `pi:instruction-groups` bus and registers `browser` with its direct/code/loader, advanced, and conditional web-search names. `fullInstructions(ctx)` is the sole delivery source: project rules, trusted runtime config, full shared playbook, tab recovery, every advanced guideline, and conditional web-search guidance. The callback reads current config rather than retaining startup-only guidance.
|
|
27
|
+
|
|
28
|
+
The collector's dynamic `isManaged()` decides ownership. Managed Pi delivers full text on group enable and repairs it after compaction; `before_agent_start` adds no duplicate browser section. Without management, including stock Pi or disabled discovery, that hook eagerly supplies the same full text in the named `agent_browser` section on every prompt. No `ToolDefinition.discovery`, `sectionTools` detection, keyword gate, or full system-prompt replacement remains. Registration and group enablement do not change callable permissions, tool names/namespaces, startup selection, or the separate advanced loader.
|
|
29
|
+
|
|
26
30
|
### Direct subprocess execution
|
|
27
31
|
|
|
28
32
|
The extension should:
|
|
@@ -42,7 +46,7 @@ The extension should:
|
|
|
42
46
|
|
|
43
47
|
The child has an empty environment, Node permission mode without host capability allowlists, a 64 MiB heap ceiling, and a VM with string/WebAssembly code generation disabled. Null-prototype `browser`, `emit`, and `emitImage` functions use JSON-only IPC; parent promises/objects/functions are not exposed. There are no imports or host filesystem/network/process/timer APIs. Node's VM alone is not a security boundary. The retained child isolation is distinct from the selected browser's persistent authentication and native capabilities; no QuickJS, broker, second driver, or provider payload injection is involved.
|
|
44
48
|
|
|
45
|
-
Limits are 25 attempted calls, 64 KiB source/final JSON, 1 MiB per IPC message, 8 MiB cumulative IPC, and a 120-second default/300-second maximum deadline. `browser()` returns a canonical observation. `emit` selects JSON; `emitImage` selects a cell-local verified image handle, with file identity rechecks and normal inline limits. `lib/orchestration/script-mode.ts` aggregates selected output, failures, and artifact receipts;
|
|
49
|
+
Limits are 25 attempted calls, 64 KiB source/final JSON, 1 MiB per IPC message, 8 MiB cumulative IPC, and a 120-second default/300-second maximum deadline. `browser()` returns a canonical observation. `emit` selects JSON; `emitImage` selects a cell-local verified image handle, with file identity rechecks and normal inline limits. `lib/orchestration/script-mode.ts` aggregates selected output, failures, and artifact receipts; retired isolated-session leases are normalized by the offline converter into UUID-owned cleanup facts.
|
|
46
50
|
|
|
47
51
|
### Ordered transitions and shared execution
|
|
48
52
|
|
|
@@ -50,7 +54,9 @@ Limits are 25 attempted calls, 64 KiB source/final JSON, 1 MiB per IPC message,
|
|
|
50
54
|
|
|
51
55
|
All participating Pi processes must restart with the updated package. The lock is not a browser transaction, rollback, or a guarantee against humans, third-party native clients, older extensions, or separately named sessions attached to one external Chrome. Separate tool calls still need workflow coordination.
|
|
52
56
|
|
|
53
|
-
`lib/browser-transcript.ts`
|
|
57
|
+
`lib/browser-transcript.ts` defines one canonical `data.event` format and optional once-stored `data.snapshot`. Direct, advanced, code and Electron host operations record begin/finish receipts before dispatch and after observed effects, using outer tool-call ID plus inner index and a unique operation ID. The shared page reducer retains an inaccessible candidate during unresolved work and requires explicit reuse/replace/invalidate/unknown disposition. Ordinary results omit unchanged maps and unrelated artifact receipts; journal events carry redacted artifact-row changes in commit order. Final rendering queues actual spill writes and manifest publication, allowing unrelated small observations to finish while another namespace holds its artifact/lifecycle operation. Native lifecycle evidence is retained before presentation/export. Failed begin blocks dispatch; failed finish stops dependent work and requires inspection without mutation replay. A named persistent journal requires actual publication even before Pi's first conversation. Disabled/no-file sessions use the native current in-memory ancestry for direct browser work without claiming durability; code still requires a published intent journal. Observation-only artifact receipts are optional without a published journal, so sessionless local results retain complete redacted private spills and selected files. Code lifecycle joins include outer finalization, and the shared generation guard keeps prior-branch observation spills process-private and prevents their artifact publication onto the new branch. JavaScript variables are never persisted.
|
|
58
|
+
|
|
59
|
+
`lib/browser-journal.ts` token-projects published envelopes and ancestry through public Pi file/header/leaf APIs, loading only winning snapshot definitions. It captures the selected leaf before asynchronous reads and validates that same branch through optional native metadata. Fork metadata APIs are optional; official Pi uses the same read-only format/reducer. Stock official 0.99.2 still eagerly loads native history before extension startup. Legacy adapters live only in `lib/browser-session-conversion.ts`, which publishes a validated stopped separate copy while retaining the source. Native generation checks use PID/start and socket identity, never saved URL or delta revision alone. Filtered/helper captures share this check. Small owner-qualified launch receipts retain observed restore-key provenance; restart verifies the current native generation and key before treating that provenance as live. Full storage, migration and consumer-memory boundaries are documented in [`SESSION_STORAGE.md`](SESSION_STORAGE.md).
|
|
54
60
|
|
|
55
61
|
### Canonical observations and image geometry
|
|
56
62
|
|
|
@@ -87,9 +93,9 @@ Global/override package profile names with `policy: "always"` and executable def
|
|
|
87
93
|
|
|
88
94
|
Use Pi-native `promptGuidelines`, tool declarations, and named `systemPromptOptions.sections` contributions. Do not return a replacement full system prompt from `before_agent_start`: it breaks additive declaration anchoring. Official Pi 0.87 and the fork use this same composition; optional fork checkpoint hooks do not make hosted programmatic tool calling, async provider lifecycle, image-detail overrides, or model-specific payload edits package dependencies. Prefix stability is not proof of a cache hit.
|
|
89
95
|
|
|
90
|
-
|
|
96
|
+
Browser instructions come from one full source assembled from `lib/playbook.ts` and current trusted config. Shared rules and all advanced tool guidelines are delivered together, rather than maintaining a short eager summary beside a hidden manual. Managed hosts defer this full group; stock hosts receive it eagerly. Tool registrations retain concise descriptions and schemas without duplicate `promptGuidelines`.
|
|
91
97
|
|
|
92
|
-
|
|
98
|
+
Keep operating rules in the canonical playbook arrays and regenerate their documentation mirrors. Absolute installed-package documentation paths remain available for detailed examples and command inventories; they do not substitute for delivering the full browser guidance.
|
|
93
99
|
|
|
94
100
|
### No reusable recipe layer yet
|
|
95
101
|
|
|
@@ -171,12 +177,12 @@ Practical policy:
|
|
|
171
177
|
- close the active extension-managed session when the originating `pi` process quits, while leaving explicit caller-provided sessions alone
|
|
172
178
|
- after branch restore, use the existing locked daemon inspection to distinguish a confirmed inactive wrapper-owned daemon from a live, unknown, or unavailable one. For compatible automatic managed restore only, keep the pending reopen in ordered session page state and persist it as `sessionTabReopenPending`. Non-page calls such as `tab list` can start a daemon without fulfilling it; explicit HTTP reads leave the managed browser and pending reopen untouched, including across branch/reload replay. Before the first current-page operation (`get url`, history commands and relative `pushstate` included), reopen the complete recorded URL with native `open`, invalidate old refs with the existing `page-transition` state, and verify the actual tab. Explicit URL reads and all-read batches skip managed ownership changes and browser helpers entirely; native owns their HTTP fetch and validation. Native `open` resets frame scope. Consume the obligation on that attempt or an executed explicit context/navigation/close command, not an unreached batch row; a failed open does not permit repeated navigation of a now-live browser. After the reopen CLI starts, cancellation returns a structured `aborted` result through the ordinary result path with the exact namespace/session, consumed marker and ref invalidation; it does not throw away replay state or run later browser helpers. Cancellation before the CLI starts does not consume the pending reopen. Internal URLs retain their fragments while tab/ref comparisons remain fragment-insensitive and presentation keeps normal redaction. Older transcripts cannot recover a fragment they did not record. Caller-owned/attached browsers and restore-disabled sessions do not take this path; live wrong-tab recovery still only selects an existing target. Reopening reloads the URL, not unsaved forms, JavaScript memory, or history. There is no second restore store or lifecycle lock.
|
|
173
179
|
- set an idle timeout on extension-managed sessions as a backstop for abnormal exits or cleanup failures, and apply that same `AGENT_BROWSER_IDLE_TIMEOUT_MS` value to every subprocess targeting that owned session (including wrapper helper snapshots, tab lists, and navigation-summary reads); caller-owned sessions instead retain native config/environment idle policy because changing the launch environment between calls can make upstream restart the background browser, discard the active tab, and invalidate fresh refs
|
|
174
|
-
- for wrapper-owned implicit sessions only, set a transcript- and checkout-scoped `AGENT_BROWSER_RESTORE` key on compatible calls so cookies and web storage can survive idle shutdown, reload, and resume. Explicit caller sessions, restore/state choices, profiles, upstream config, file access, launch arguments, environment variables, local pages, output paths, and close arguments remain upstream-owned and pass through unchanged. `piab-*` names are not reserved; session/state lists and restore identifiers are not filtered or redacted. The wrapper validates only its automatic restore checkout/storage identity and coordinates same-daemon reuse so its own restore pools cannot mix. Ambiguous page-target transitions still require live `get url` verification before content calls. The current
|
|
180
|
+
- for wrapper-owned implicit sessions only, set a transcript- and checkout-scoped `AGENT_BROWSER_RESTORE` key on compatible calls so cookies and web storage can survive idle shutdown, reload, and resume. Explicit caller sessions, restore/state choices, profiles, upstream config, file access, launch arguments, environment variables, local pages, output paths, and close arguments remain upstream-owned and pass through unchanged. `piab-*` names are not reserved; session/state lists and restore identifiers are not filtered or redacted. The wrapper validates only its automatic restore checkout/storage identity and coordinates same-daemon reuse so its own restore pools cannot mix. Ambiguous page-target transitions still require live `get url` verification before content calls. The current v4 set-valued ticket-claim lock is the only managed-daemon coordination protocol; no earlier lock bridge or compatibility path remains. Successful lock acquisition opportunistically inspects at most eight current-protocol candidates/removal artifacts/claims under the existing acquisition deadline (single-attempt `timeoutMs: 0` probes retain their existing no-deadline behavior). Published claims must be at least 30 minutes old, valid, and owned by a proven-dead process before rename/revalidation removal; contention still immediately reclaims proven-dead overlapping claims. Legacy or ambiguous claims remain untouched. Secure-temp allocation similarly inspects at most eight roots per call, retaining the 24-hour lease floor, dead-owner proof and protected Electron children. A randomized first window avoids a fixed retained prefix across short-lived processes; subsequent calls rotate in process. Cross-process progress is probabilistic, not a guaranteed number of calls. Listing/sorting still covers the whole directory; these are work-count bounds, not hard wall-clock deadlines.
|
|
175
181
|
- redact snapshot spill payloads before writing them, clean up process-private temp spill artifacts on shutdown, and keep persisted-session spill files in a private session-scoped artifact directory for `details.fullOutputPath` after reload/resume, with a 32 MiB per-session budget by default; `PI_AGENT_BROWSER_SESSION_ARTIFACT_MAX_BYTES=0` skips persistent-spill enumeration and eviction without changing temporary spill cleanup
|
|
176
|
-
- keep explicit screenshots, downloads, PDFs, traces, HAR captures, and recordings written to caller-chosen paths on disk after a successful upstream close command (`close`, `quit`, or `exit`); before artifact-producing commands run, create missing parent directories for requested host paths, while native download always owns the click and download, including loopback links, generated Blob exports, and redirects; never substitute an anchor-href fetch. When the
|
|
177
|
-
- reconstruct the current branch-visible extension-managed session, every transcript-proven still-active wrapper-owned managed identity, page-scoped refs,
|
|
182
|
+
- keep explicit screenshots, downloads, PDFs, traces, HAR captures, and recordings written to caller-chosen paths on disk after a successful upstream close command (`close`, `quit`, or `exit`); before artifact-producing commands run, create missing parent directories for requested host paths, while native download always owns the click and download, including loopback links, generated Blob exports, and redirects; never substitute an anchor-href fetch. When the internal recent artifact view has entries, successful close commands also surface `details.artifactCleanup` and a compact `Artifact lifecycle` note pointing to structured explicit paths so operators remove files with normal host tools—the native tool does not delete arbitrary user paths (`extensions/agent-browser/lib/orchestration/browser-run/diagnostics.ts`, `getArtifactCleanupGuidance`); contract in [`TOOL_CONTRACT.md`](TOOL_CONTRACT.md#details), checklist `RQ-0079` in [`SUPPORT_MATRIX.md`](SUPPORT_MATRIX.md)
|
|
183
|
+
- reconstruct the current branch-visible extension-managed session, every transcript-proven still-active wrapper-owned managed identity, page-scoped refs, journal-ordered artifact-row changes, unbounded active-recording reservation events, and Electron launch records from the active transcript branch on `session_start` and `session_tree` so later default and explicit off-current calls keep following owned browsers after resume/reload or branch switching; restore also honors successful explicit `--session <wrapper-owned> close` rows, terminal nested-batch close outcomes even when aggregate artifact verification failed, and `electron.cleanup` managed-session steps so closed wrapper-owned sessions are not resurrected; a nested close invalidates the pre-close page target so a lifecycle-proven relaunch at `about:blank` is not treated as stale focus drift; explicit lifecycle evidence that a later diagnostic did not launch a browser preserves the terminal close, while any later row—including a failed row—whose lifecycle reports a browser launch keeps active/attached provenance; failed-step presentation persists only that bounded launch boolean so transcript replay reaches the same decision, missing lifecycle evidence remains conservatively active even on the first managed call, successful closes clear 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 recording starts after close are rejected before spawn
|
|
178
184
|
- keep active recording destination reservations separate from the bounded metadata-only artifact manifest. The same journal retains native recording IDs and start windows; native receipts, including failures, flow through existing artifact metadata and verification. A stop timeout/no-recording result gets one two-second native `session info` query matching namespace/session, ID/path or effective batch start window. Recovery needs terminal native encoder success plus a matching verified file; filesystem presence alone is insufficient, old same-path receipts cannot verify a new take, and freshness starts at capture rather than status-query time. Original attempts and unrelated batch failures remain visible. No second ledger, recorder, sidecar or runtime ffprobe is added. The process-wide map is keyed by canonical namespace/session identity, rebuilt from append-only branch events, and retained for still-live process-owned recordings across branch switches. Shutdown/reload appends both terminal tombstones and still-live reservations onto the current branch so restart cannot resurrect a cross-branch close or lose a live-daemon reservation. One artifact lifecycle/output queue makes global destination preflight and reservation updates atomic across otherwise-concurrent caller-owned session queues. Every successful direct, ordered nested-batch, managed replacement, code, Electron, or shutdown close retires its exact identity at that lifecycle point; only the newest pending recording path remains authoritative across current transition replay (including same-timestamp restart rows), and recording starts after a nested close are rejected because upstream can falsely report success. Existing and dangling symlink ancestry, hardlink inode identity, full Unicode/platform case folding, and same-call `outputPath` comparison prevent alias reuse. One shared command-token projection mirrors upstream's full-argv global cleanup before artifact, recording, and presentation parsing; wait-download detection removes only the first timeout pair, follows upstream long/short mode precedence, and accepts both `--download` and `-d` wherever download mode wins; screenshot destinations use upstream's exact-flag, selector-prefix, case-sensitive extension, slash-path, and second-positional rules, while retaining the wrapper's intentional slash-bearing hidden-workspace path normalization. Recording path/URL consumers share a command-local reader that skips complete numeric `--fps` pairs, cursor/contact-sheet switches, and contact-sheet threshold values without rewriting argv or treating them as outer globals; native owns rate, format and extra-argument validation. Current recording transitions are replayed directly; artifact manifests are not treated as reservation events
|
|
179
|
-
- keep process-owned cleanup registries for extension-managed sessions and wrapper-launched Electron records separate from the current branch-visible view; `session_tree` restore and wrapper-owned browser commands are serialized with managed-session work, while caller-owned explicit-session commands use local queues and shared execution locks keyed to actual socket context and effective canonical namespace/session across prepare helpers (explicit namespace argv overrides inherited `AGENT_BROWSER_NAMESPACE`, including an explicit empty default) and main execution. macOS and Windows additionally normalize and case-fold namespace and session components to match case-insensitive daemon identity. Different caller-owned identities remain concurrent, except namespace-scoped `close --all` drains and exclusively barriers managed plus matching caller-owned work before clearing global namespace state; nested helpers never re-enter the outer queue, policy/route/artifact deltas merge across unrelated managed-state commits, and a separate branch-restore generation guard prevents stale completions from overwriting newer branch-visible state;
|
|
185
|
+
- keep process-owned cleanup registries for extension-managed sessions and wrapper-launched Electron records separate from the current branch-visible view; `session_tree` restore and wrapper-owned browser commands are serialized with managed-session work, while caller-owned explicit-session commands use local queues and shared execution locks keyed to actual socket context and effective canonical namespace/session across prepare helpers (explicit namespace argv overrides inherited `AGENT_BROWSER_NAMESPACE`, including an explicit empty default) and main execution. macOS and Windows additionally normalize and case-fold namespace and session components to match case-insensitive daemon identity. Different caller-owned identities remain concurrent, except namespace-scoped `close --all` drains and exclusively barriers managed plus matching caller-owned work before clearing global namespace state; nested helpers never re-enter the outer queue, policy/route/artifact deltas merge across unrelated managed-state commits, and a separate branch-restore generation guard prevents stale completions from overwriting newer branch-visible state; artifact-row changes use the existing artifact queue and journal order so replay retains concurrently completed entries. Branch switches still must not drop resources the current Pi process owns and must keep fresh-session allocation monotonic
|
|
180
186
|
- record successful `connect`, `--cdp`, enabled `--auto-connect`, environment-configured CDP/auto-connect, and wrapper Electron attachment identities in branch-visible state. First-use and later content-bearing calls live-check `get url` because attached targets can drift outside Pi. Caller config, file access, launch arguments, and environment pass through unchanged; only wrapper-injected compatibility launch arguments are omitted on active attachments. A terminal successful close removes the marker; a close followed by a later step whose lifecycle reports a browser launch preserves it, while a non-launching diagnostic such as `stream status` leaves the close terminal
|
|
181
187
|
- when a successful close targets the current extension-managed session, including an explicit `--session <current> close` or an `electron.cleanup` managed-session step, clear page/ref state, mark that session inactive, untrack cleanup ownership, and rotate the next default auto call to a fresh wrapper-generated session name rather than reusing the closed name
|
|
182
188
|
- on non-quit shutdown such as `/reload`, close off-branch owned managed sessions and off-branch owned Electron launches before clearing process-local ownership, but preserve the current branch-visible active managed session and Electron launch plus that launch's isolated `userDataDir` so reload continuity still works from the active transcript branch. First reuse of a restored Electron attachment checks the recorded namespace/session, live PID/profile presence, and exact browser WebSocket identity against current CDP metadata, then uses upstream `get cdp-url` to verify that the named daemon still targets that browser or one of its current pages. The metadata probe cannot commit daemon provenance merely by spawning; only a matching result permits the existing policy to record it. Ordinary calls, status, and probe share this path under the existing lock. Generic restore-disabled sessions, mismatched connections, quit, and off-branch cleanup are unchanged
|
|
@@ -188,7 +194,7 @@ Practical policy:
|
|
|
188
194
|
- once the wrapper observes tab-drift risk for a session (profile restore correction, overlapping stale opens, or restored session state), later active-tab commands verify the intended tab under the existing session queue before semantic/ref helpers and user commands. Targets retain native CDP `targetId` across transcript replay; exact identity distinguishes duplicate URL/title tabs, while older targets without an ID keep URL-based matching. A cold managed reopen replaces the old ID. Native selection runs only when the intended tab is not already active, because upstream selection clears refs and frame scope even on same-tab reselection. Missing targets, failed selection, and post-selection target mismatches fail before user commands. Caller argv/stdin and native `--pin-tab` / `--no-pin-tab` preferences remain unchanged. Local commands, live `get url`, explicit HTTP `read <url>` (including its flags), URL `a11y`/`vitals`/`web-vitals`, `diff url`, `window new`, URL-bearing recording commands, and explicit tab/navigation/`connect`/`state load` recovery do not require the old target; history back/forward/reload, `pushstate`, and page-content operations still do. The same classifier scans effective batch rows past non-page prefixes until a page dependency or explicit context change, without rewriting user rows or changing bail behavior. For `window new` and `diff url`, observe the resulting URL instead of retaining the old target or treating the requested second URL as redirect evidence. Fold only reached native batch rows when available, discard targets before failed navigation/context transitions and live-verify the final page, discard observations and refs from before window/diff transitions, and let later successful snapshots rebuild refs even when another batch row fails. Retain an observed blank destination after either command instead of recovering the old page; if no final target is observed, use the existing unknown-target state. Caller batch arguments, stdin and bail behavior stay unchanged. Successful batches containing navigation-observable actions use the same final live page/identity observation as direct actions, so same-address popup tabs replace the pre-batch target before later pinning. Terminal batch closes do not trigger a page probe, and pending WebMCP targets remain unknown. Routine same-session commands avoid `tab list` preflights
|
|
189
195
|
- for sessions with observed tab-drift risk, after a successful command on a known tab target, the wrapper may best-effort restore that same target again if restored/background tabs steal focus after the command returns; routine same-session commands skip focus correction, while observed pages without a returned native ID use `tab list` to establish current identity rather than inheriting an earlier tab's ID
|
|
190
196
|
- after successful tab creation, selection, or close, including dispatched native batch rows, read the now-active URL and fresh non-blank title—even when two tabs share a URL—before updating per-session page state; retain the deliberate blank target instead of treating it as accidental drift
|
|
191
|
-
- keep a per-session `refSnapshot` aligned with the last successful `snapshot` (including refs merged from a successful `batch` by taking the last successful `snapshot` step in batch result order): restore
|
|
197
|
+
- keep a per-session `refSnapshot` aligned with the last successful `snapshot` (including refs merged from a successful `batch` by taking the last successful `snapshot` step in batch result order): restore its once-stored ancestral definition when reloading, resuming, or moving to a different Pi session-tree branch, retain full membership and accessible metadata from that capture for wrapper-side diagnostics, drop it on successful close commands (`close`, `quit`, or `exit`), replace it with a persisted `page-transition` invalidation after any upstream-executed `record start` attempt (direct or batch; older supported natives can swap the page before their already-active check, so failed starts count; the warning and persisted summary explicitly describe conservative ref invalidation, not an observed page change), a `record restart` with a URL operand, `window new`, `diff url`, or WebMCP `invoke` / `result` / `cancel` (these page-provided tools can mutate, rerender, or navigate; when a spawned `batch` yields no parseable result rows, for example after a wrapper timeout, planned transition steps still record the invalidation), or after a failed transition command (`eval`, `back`, `forward`, `reload`, `connect`, `state load`, `tab` selection), including reached batch transitions and failed batch `open` rows whose live URL re-verification probe observed the page (a failed transition can still have mutated or replaced the document before throwing, so keeping the verified URL must not keep the prior refs; transcript replay preserves the persisted invalidation summary), and refuse page-scoped `@e…` argv before spawn when the active tab URL no longer matches the snapshot URL, when a ref id was never in that snapshot, when the snapshot state is invalidated, or when a `batch` step would reuse `@e…` on a guarded getter or mutation step after an earlier invalidating step (including `record start`, URL-bearing `record restart`, and WebMCP `invoke` / `result` / `cancel`) without a later `snapshot` step in the same plan; batch steps come from the source upstream actually executes (raw batch argument strings exclusively when any exist — filtering only the exact `--bail` token like upstream — stdin only otherwise, via `getUpstreamEffectiveBatchSteps` in `extensions/agent-browser/lib/orchestration/batch-stdin.ts`); tab recovery (which leaves user argv/stdin and continue-on-error control flow unchanged), artifact/recording preflight, batch screenshot path preparation (parent directories are created for effective raw rows too, without rewriting raw strings), and stale-ref echo args use that same selection so pinning and preflights cannot act on upstream-ignored stdin, while the pre-spawn state-policy validator deliberately keeps scanning parseable stdin alongside argv as a fail-closed content superset and treats stdin parse failures as fatal only when upstream would actually read stdin (its raw-token filter also uses the exact `--bail` token only). Same-snapshot `fill @e…` rows are guarded but do not themselves set that invalidation latch, so ordinary form fills can precede a click/submit row in one batch—see [`TOOL_CONTRACT.md`](TOOL_CONTRACT.md#details) for the agent-visible contract and failure text; typed per-session tab/ref/pinning state lives in `extensions/agent-browser/lib/session-page-state.ts` and is updated from `extensions/agent-browser/index.ts` after each tool result
|
|
192
198
|
- native 0.37 owns first-document setup inheritance for new tabs; the wrapper does not copy headers, user agents or other browser setup itself. The page-summary formatter displays native positive WebMCP availability while retaining raw details; it adds no discovery probe
|
|
193
199
|
- when a direct or batched WebMCP call returns `status: "pending"`, or `result` / `cancel` fails while that target is unknown, keep its tab target unknown and discard same-call snapshot evidence instead of treating an immediate post-dispatch URL probe as stable; `webmcp result` / `cancel`, `get url`, and explicit navigation remain available while unknown; replace the generic blocked snapshot action with `verify-page-target-after-pending-webmcp` (`get url`), and let a completed `batch --bail` use that verification before `snapshot -i` to re-establish both target and refs
|
|
194
200
|
- for top-level non-Electron direct `click` commands with an eligible target, install a bounded in-page target-specific event probe before upstream runs; if upstream reports success but no trusted pointer/mouse/click event reached the resolved target, fail the tool and report `details.clickDispatch` with explicit retry/inspect next actions (the wrapper does not replay clicks in-page). The probe covers `xpath=` targets and current `@e…` / `ref=` refs whose latest stored `refSnapshot.refs` role is `button`, `checkbox`, `menuitem`, `radio`, `switch`, or `tab`; it requires a unique role/name in the saved snapshot and the live candidates instead of taking a fresh pre-click snapshot that could recycle upstream refs. Ref and XPath candidates must additionally prove identity through a per-probe temporary DOM attribute read back by native `get attr <original-selector> <marker>`. Missing or mismatched identity, including XPath/frame scope mismatches, cleans up the probe and lets native click run without dispatch verification; candidate naming heuristics alone are never proof. Duplicate-name refs pass through without a probe: their old ordinal is not target identity. The probe is intentionally skipped for CSS selector clicks, unresolved `find … click` locators, and `batch`/`qa` click steps
|
|
@@ -230,12 +230,14 @@ Call `agent_browser_tools {}` for inventory, then enable required capabilities:
|
|
|
230
230
|
{ "enable": ["action", "qa", "electron", "source", "network"] }
|
|
231
231
|
```
|
|
232
232
|
|
|
233
|
+
On hosts supporting instruction groups, first enable `browser` with `discover_tools` to receive full browser and advanced guidance and reveal selected declarations. The extension registers its own group through `pi:instruction-groups`; this step changes neither callable permissions nor advanced-tool selection. Official Pi receives the same full guidance eagerly without this discovery step. The separate advanced loader below retains its activation semantics.
|
|
234
|
+
|
|
233
235
|
Activation is additive and uses native Pi selected-tool history. Omit CLI `--tools` for normal lazy activation, or include desired advanced tools in that explicit selection; excluded tools remain unavailable. The tools take flat input:
|
|
234
236
|
|
|
235
237
|
| Tool | Example |
|
|
236
238
|
| --- | --- |
|
|
237
239
|
| `agent_browser_action` | `{ "action": "select", "locator": "role", "role": "combobox", "name": "Flavor", "value": "chocolate" }` |
|
|
238
|
-
| `agent_browser_qa` | `{ "url": "https://example.com", "expectedText": "
|
|
240
|
+
| `agent_browser_qa` | `{ "url": "https://example.com", "expectedText": "Learn more" }` |
|
|
239
241
|
| `agent_browser_electron` | `{ "action": "list", "query": "code" }` |
|
|
240
242
|
| `agent_browser_source` | `{ "selector": "#save", "componentName": "SaveButton" }` |
|
|
241
243
|
| `agent_browser_network_source` | `{ "requestId": "req-1", "url": "/api/fail" }` |
|
|
@@ -400,10 +402,12 @@ For longer text, code can construct the rows and call native batch; keep the for
|
|
|
400
402
|
|
|
401
403
|
For quick smoke/QA checks, enable `qa` and call `agent_browser_qa` with flat fields. 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.
|
|
402
404
|
|
|
405
|
+
For failed QA, inspect `details.qaPreset.failedChecks` separately from `notRunChecks`: a reported fail-fast error leaves later checks not run, rather than proving their assertions failed. Failure prose leads with the redacted cause and reports received execution coverage; missing timeout receipts mean an unknown executed count. Incomplete receipts without a reported failure are unverified, never proof of a pass or of unreached checks.
|
|
406
|
+
|
|
403
407
|
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>`, `agent_browser_network_source` 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`. Filtered data receives the same credential redaction as ordinary network diagnostics before entering `details.data` or an `outputPath` export. 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`.
|
|
404
408
|
|
|
405
409
|
```json
|
|
406
|
-
{ "url": "https://example.com", "expectedText": "
|
|
410
|
+
{ "url": "https://example.com", "expectedText": "Learn more", "screenshotPath": ".dogfood/qa-example.png" }
|
|
407
411
|
```
|
|
408
412
|
|
|
409
413
|
Optional `loadState`, `checkNetwork`, `checkConsole`, and `checkErrors` default to `"domcontentloaded"`, `true`, `true`, and `true` for URL-opening QA; set a check to `false` to skip that diagnostic. For `qa.attached`, the diagnostic checks default to `false` because upstream buffers may predate the current check; opt in with `checkNetwork`, `checkConsole`, or `checkErrors` when preserved-buffer failures are desired. Omit `expectedText` and `expectedSelector` when you only need load plus diagnostics.
|
|
@@ -455,7 +459,7 @@ Manual path for externally launched apps: if you started the Electron app yourse
|
|
|
455
459
|
|
|
456
460
|
A successful raw `connect` means the debug endpoint accepted the session, not that the app has an active ready page. Prefer `details.nextActions` when present: `verify-connected-session-url` performs the only page read allowed while the attached target is unverified, and `list-connected-session-tabs` runs session-scoped tab inspection. A verified HTTP(S)/app target clears the guard; otherwise navigate explicitly to a safe URL. After the read-only tab list, select or confirm the stable `t<N>` target, verify it with `get url`, and run `snapshot -i` explicitly before trusting refs. If a `snapshot -i` says `No active page`, the wrapper clears any prior refs for that session; follow `list-tabs-after-no-active-page`, select the stable `t<N>` surface, then use a condition wait or retry `snapshot -i` before trusting refs.
|
|
457
461
|
|
|
458
|
-
For current-session smoke checks after either path, use `qa.attached`; for compact state instead of separate title/url/focus/tab/snapshot calls, use `electron.probe`. `electron.probe.timeoutMs` bounds each underlying read subprocess; `electron.probe.launchId` ties the probe to a wrapper launch and can surface session or target mismatch guidance before you trust page refs. Electron status target reads and probe reads use the same daemon-policy lock and owned restore decision as ordinary managed commands. A probe reads and validates the live URL before title, focus, tab, or snapshot helpers. Electron `launch` snapshot/tabs handoff likewise validates the URL before tab/snapshot reads; handoff failure or cancellation closes the new managed session and host process/profile. Current-managed probe
|
|
462
|
+
For current-session smoke checks after either path, use `qa.attached`; for compact state instead of separate title/url/focus/tab/snapshot calls, use `electron.probe`. `electron.probe.timeoutMs` bounds each underlying read subprocess; `electron.probe.launchId` ties the probe to a wrapper launch and can surface session or target mismatch guidance before you trust page refs. Electron status target reads and probe reads use the same daemon-policy lock and owned restore decision as ordinary managed commands. A probe reads and validates the live URL before title, focus, tab, or snapshot helpers. Electron `launch` snapshot/tabs handoff likewise validates the URL before tab/snapshot reads; handoff failure or cancellation closes the new managed session and host process/profile. Current-managed probe events persist namespace, tab target and a once-stored ref definition so Pi reload/branch replay restores the same page identity after native-generation verification. For VS Code-style quick inputs, treat a successful `fill` as tentative: the wrapper may append `details.fillVerification` if `get value` still reads empty or different, and Electron `@e…` mutations can append `refresh-electron-refs-after-rerender` because same-URL UI rerenders commonly churn refs.
|
|
459
463
|
|
|
460
464
|
For local app debugging, enable `source`; `agent_browser_source` can gather candidate component/file locations for a visible element from selector DOM hints, React DevTools inspection, and a bounded workspace component-name search rooted at the captured execution directory (`maxWorkspaceFiles` defaults to 2000 and cannot exceed 5000; the scan records at most ten `workspace-search` candidates). With a `selector`, the wrapper runs `is visible` and, unless `includeDomHints` is `false`, `get html` so DOM data attributes and embedded source-like paths can become `dom-attribute` candidates. It reports evidence and confidence in `details.sourceLookup` instead of claiming a guaranteed source file. React hints require a session opened with `--enable react-devtools`. The `details.sourceLookup.status` field reads `unsupported` only when no candidates were collected **and** a `react` batch step failed (inspect errors, missing renderer, and similar); it reads `no-candidates` when the batch succeeded but nothing matched. If selector or workspace hints still yield candidates, `status` remains `candidates-found` even when React inspection failed. Unlike `qa`, the wrapper does not downgrade a **fully successful** upstream batch to `isError` solely because those statuses appear—though failed batch steps still produce normal tool errors. For wrapper-tracked packaged Electron sessions with no candidates, `details.sourceLookup.workspaceRoot` and optional `details.sourceLookup.electronContext` explain that the scan only covered the captured execution directory; installed app resources or `app.asar` bundles are outside that scan and are not unpacked. Those results may add `snapshot-electron-session`, `probe-electron-launch`, and `list-electron-tabs` next actions so you can inspect the live packaged app before deciding whether to change the workspace or app bundle.
|
|
461
465
|
|
|
@@ -545,11 +549,11 @@ Detailed receipt/live-browser fields and browser-independent native read/confirm
|
|
|
545
549
|
|
|
546
550
|
#### Artifact retention and dogfood-heavy QA runs
|
|
547
551
|
|
|
548
|
-
The wrapper
|
|
552
|
+
The wrapper's internal recent artifact view defaults to 100 metadata rows, configurable with `PI_AGENT_BROWSER_SESSION_ARTIFACT_MANIFEST_MAX_ENTRIES=<count>`. That cap bounds the current view, not append-only history. Journal events store row changes; `details.artifactManifest` contains changed or referenced receipts for this invocation rather than the unchanged history. Complete reference captures are likewise defined once, with small reuse/invalidation events. See [browser session storage and stopped-copy conversion](SESSION_STORAGE.md).
|
|
549
553
|
|
|
550
|
-
This
|
|
554
|
+
This cap controls the internal recent view and summaries such as `Session artifacts: 42 live, 0 evicted (42/100 recent)`. It does not delete explicit files that upstream saved to paths you chose, such as screenshots, PDFs, downloads, traces, HAR files, or WebM recordings.
|
|
551
555
|
|
|
552
|
-
Browser close commands (`close`, `quit`, or `exit`) are also not file cleanup.
|
|
556
|
+
Browser close commands (`close`, `quit`, or `exit`) are also not file cleanup. When the internal recent view contains explicit artifacts, 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.
|
|
553
557
|
|
|
554
558
|
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.
|
|
555
559
|
|
package/docs/RELEASE.md
CHANGED
|
@@ -324,11 +324,11 @@ node --test test/agent-browser.checkpoint-native.test.mjs
|
|
|
324
324
|
|
|
325
325
|
#### Routine GitHub PR checks
|
|
326
326
|
|
|
327
|
-
[`.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` and manual dispatch. Independent Ubuntu jobs qualify the locked official Pi graph and the
|
|
327
|
+
[`.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` and manual dispatch. Independent Ubuntu jobs qualify the locked official Pi graph and the maintained fork's current `main` as a complete installed 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 checks the packed Pi load without repeating the full suite. When the candidate official version differs from the supported Pi floor, that macOS job also selects the actual floor graph for a focused type/package smoke. The host selector uses the pinned `fitchmultz/.github` automation scripts without changing them. There are no cross-job host artifacts or persistent caches.
|
|
328
328
|
|
|
329
|
-
[`.github/workflows/native-checkpoint.yml`](https://github.com/fitchmultz/pi-agent-browser-native/blob/main/.github/workflows/native-checkpoint.yml) independently checks out the PR head and runs on the same PR/manual triggers. Its CI-only [`ci-native-checkpoint.sh`](https://github.com/fitchmultz/pi-agent-browser-native/blob/main/scripts/ci-native-checkpoint.sh) builds the
|
|
329
|
+
[`.github/workflows/native-checkpoint.yml`](https://github.com/fitchmultz/pi-agent-browser-native/blob/main/.github/workflows/native-checkpoint.yml) independently checks out the PR head and runs on the same PR/manual triggers. Its CI-only [`ci-native-checkpoint.sh`](https://github.com/fitchmultz/pi-agent-browser-native/blob/main/scripts/ci-native-checkpoint.sh) builds the maintained fork's current `main` and compiled extension on Node **24.21.0**, installs stock **agent-browser 0.38.1** and Chrome for Testing, checks generated playbook and live command-reference drift, then requires **13 passed, zero failed/cancelled/skipped/todo** real-browser checkpoints. 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. No personal profile, credentials, or model calls are involved.
|
|
330
330
|
|
|
331
|
-
CI writes setup, provenance, command-reference, and native TAP results to the job log instead of uploading artifacts. 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 sleep/resume qualification.
|
|
331
|
+
Each fork workflow resolves `main` once at checkout and uses that exact commit for its build and provenance checks. CI writes setup, provenance, command-reference, and native TAP results to the job log instead of uploading artifacts. 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 sleep/resume qualification.
|
|
332
332
|
|
|
333
333
|
### Native Linux socket-root regression
|
|
334
334
|
|
package/docs/REQUIREMENTS.md
CHANGED
|
@@ -70,7 +70,7 @@ Define the product requirements and constraints for `pi-agent-browser-native`.
|
|
|
70
70
|
- Preserve unique visible accessible dropdown selection, semantic/ref recovery, truthful QA verdicts (including ambiguous error-buffer residue), attached diagnostic preservation/defaults, Electron process/profile ownership, and bounded source scans. Raw diagnostic-read success is not a QA verdict, and source hints remain candidates rather than authoritative blame.
|
|
71
71
|
- Code runs in a fresh permissioned Node child with no host APIs/imports, null-prototype task globals, JSON-only bounded IPC, serial native calls, and explicit JSON/image output. Keep current source/output/call/deadline limits. Browser/authentication persists under existing native ownership and configuration; JavaScript variables do not. Allow ordinary native commands including batch/auth/profile/state/connect/close, but prevent changes to the fixed parent-selected identity and namespace-wide close within a cell.
|
|
72
72
|
- Hold a cooperating-process execution lock keyed by actual socket context, canonical namespace, and session across direct helper/action work or the entire code cell. Use ordered multi-identity acquisition for replacement/cleanup and a namespace barrier for direct close-all. This does not coordinate humans, third-party clients, or older versions, guarantee atomic browser actions, or provide rollback.
|
|
73
|
-
- Persist
|
|
73
|
+
- Persist one canonical begin/finish event format for direct/code/host work through native Pi custom entries and a shared reducer. Define full captures once, preserve exact targets/native identity, and persist artifact-row changes rather than unchanged views. Interrupted outcomes remain unknown until inspection; failed begin blocks dispatch and failed finish stops dependent work without mutation retry. Require actual journal publication before browser dispatch. Legacy browser/lease decoders belong only to validated offline stopped-copy conversion; preserve original bytes, all ancestry and owner UUIDs. A fork must never acquire its parent's cleanup rights. Bound extension replay with token projection and winning definitions on both hosts, while disclosing stock official Pi's eager native loader and individual-value memory ceilings; see [`SESSION_STORAGE.md`](SESSION_STORAGE.md).
|
|
74
74
|
- Use one canonical model-visible observation for JSON/prose/code with success/data/error, exact recovery, artifact receipts, and image observations. Details is audit/replay metadata, not the sole source of actionable failures. Inner calls avoid full model rendering/spills/image encoding. Bound outer output and name a complete redacted observation spill rather than truncating executable payloads.
|
|
75
75
|
- Attach only verified real images; code selects current-cell image handles explicitly. Report pixel dimensions and CSS viewport/DPR/crop/scroll/frame evidence conservatively. Unknown geometry remains unknown; neither full-page nor element captures are assumed viewport coordinates. Do not inject model-specific image-detail/provider payload changes.
|
|
76
76
|
- Direct upstream capability remains available: explicit sessions, state/restore paths, profiles, config, file access, launch arguments, environment, local pages, output paths, and close arguments pass through under ordinary native semantics. Keep all session/state rows visible. Wrapper validation concerns input shape, lifecycle integrity, and truthful evidence, not authorization of resources.
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Browser session storage
|
|
2
|
+
|
|
3
|
+
Pi's native JSONL journal owns conversation history and branch ancestry. Browser replay uses small ordered `agent-browser-transition` entries in that journal; it has no separate database or snapshot sidecar.
|
|
4
|
+
|
|
5
|
+
## Events and snapshots
|
|
6
|
+
|
|
7
|
+
Every browser-affecting direct, code, or Electron host operation records a begin before dispatch and a finish after observing its effects. With a journal, each record requires confirmed publication. Direct browser use in a disabled/no-file session (`--no-session`) uses Pi's current in-memory ancestry without claiming persistence. Code still requires a published intent journal; a named but not-yet-published persistent conversation also refuses browser dispatch. Sessionless local inspections and browser-independent reads remain available before publication, including full redacted private spills and caller-selected output files. Their observation-only artifact receipts do not require a journal; browser effects, page changes and native confirmations retain their required records. `data.event` version 1 correlates them with an operation ID, the outer tool-call ID and inner command index. The same reducer applies committed live events and replays the selected branch.
|
|
8
|
+
|
|
9
|
+
A finish explicitly reuses, replaces, invalidates, or leaves refs unknown. Each complete capture defines one `data.snapshot`: an ID, keyed ref membership and accessible metadata, exact private target, and verified native daemon generation when available. Ordinary completions name the ancestral definition instead of copying its map. Dedicated snapshot results and requested structured exports still retain their full data. Native delta baselines remain native; a Pi snapshot ID cannot restore them.
|
|
10
|
+
|
|
11
|
+
An unfinished begin retains the old snapshot only as an inaccessible candidate. Failed begin publication prevents dispatch. Failed finish publication means changes may already have happened: dependent code calls stop and recovery requires inspection, without repeating the mutation. URL inspection alone cannot revive those refs. Presentation or file-export failure does not erase observed native launch, close, or page effects. Publication verifies the matching native entry through bounded JSONL framing, including native recovery that flushes older accepted entries or replaces the journal. These are synchronous journal receipts, not power-loss-atomic browser transactions.
|
|
12
|
+
|
|
13
|
+
A saved URL or map cannot prove the native browser survived. Reuse checks native PID/start identity and socket context; a changed or unverifiable generation invalidates refs until a complete new snapshot succeeds. Cold managed reopen keeps the exact remembered URL, including its fragment, under the existing native restore policy. An unverifiable generation invalidates refs without authorizing navigation over a live tab. Filtered and helper captures use the same native generation check as ordinary snapshots. A wrapper-owned launch also retains a small daemon receipt with the observed restore key and PID/start/socket generation. Restart may reuse that launch provenance only for the same Pi owner after native inspection matches both fields; a replacement daemon cannot inherit it.
|
|
14
|
+
|
|
15
|
+
## Reading and retention
|
|
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 optional native ancestry validation, so concurrent appends cannot change the branch being replayed. It token-validates complete newline-terminated records with unpacked discarded strings, projects envelopes, follows ancestry, and reads only winning snapshot bodies. An incomplete live tail remains uncommitted. Optional public metadata APIs and `getEntry()` provide structural ancestry and selected snapshot access on the maintained fork. No writable manager or private core storage is used.
|
|
18
|
+
|
|
19
|
+
Official Pi 0.99.2 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
|
+
|
|
21
|
+
Artifact events persist row upserts/removals in journal order. The internal recent view defaults to 100 rows; it is separate from cumulative journal size and the independent recording reservation/tombstone journal. Artifact upserts are credential-redacted before persistence. Tool `details.artifactManifest` contains only changed or referenced receipts for that invocation, including evictions observed during that call. Retention summaries and close cleanup guidance can describe the internal recent view without copying it into every result.
|
|
22
|
+
|
|
23
|
+
Required replay snapshots stay in retained journal ancestry, outside observation-spill eviction. Caller-selected files remain caller-owned. Redacted persistent spills retain their existing byte budget; process-private files retain their existing cleanup. A receipt does not make external bytes immutable or include them in an export/checkpoint. Preserve referenced files in the matching archive layout when needed.
|
|
24
|
+
|
|
25
|
+
Tree changes join code execution through its complete observation finalization before restoring branch-visible state. Interrupted results retain complete caller observations in process-private spills without publishing their artifact state onto the newly selected branch. Tree changes do not roll back the real browser; process-owned cleanup and recording facts remain separate. An ordinary fork has a new native Pi UUID and cannot acquire its parent's managed/Electron/script cleanup rights. Wrapper-owned begins retain their selected socket root and owner UUID even if the launch finish is lost; restart can inspect or clean that original identity without declaring the launch successful. Owned follow-ups, code and cleanup keep that root when process defaults change; unrelated caller sessions retain native routing. Optional checkpoints refuse live or unverified resources and never close browsers to manufacture readiness.
|
|
26
|
+
|
|
27
|
+
## Converting a retained legacy journal
|
|
28
|
+
|
|
29
|
+
Legacy repeated maps/manifests and retired isolated-script leases are decoded only by the offline converter. Normal runtime replay requires the canonical event format and reports a conversion requirement rather than keeping a permanent second replay engine.
|
|
30
|
+
|
|
31
|
+
1. Stop or quiesce the exact writer through its owner. Do not convert an active journal or relaunch work merely to repair storage.
|
|
32
|
+
2. Keep the original journal and choose a distinct private destination outside automatic session discovery.
|
|
33
|
+
3. Run the packaged command:
|
|
34
|
+
|
|
35
|
+
```sh
|
|
36
|
+
npm exec --package pi-agent-browser-native -- pi-agent-browser-convert \
|
|
37
|
+
--source /archive/original.jsonl \
|
|
38
|
+
--output /private-converted/copy.jsonl --confirm-stopped \
|
|
39
|
+
--receipt /private-converted/conversion-receipt.json
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
From a built checkout, use `node scripts/convert-browser-session.mjs` with the same arguments. The command never starts Pi, tools, providers, or browsers.
|
|
43
|
+
|
|
44
|
+
Conversion preserves the native header UUID, every entry ID/parent/timestamp, branches, labels, settings, usage, message content/images and explicit result data. It normalizes repeated browser state along each entry's actual ancestry, defines captures once on reachable ancestors, preserves unfinished outcomes and source cleanup ownership, and emits source checksum/byte-range provenance for transformed fields. Already-modern observations remain observations: their explicit data is preserved, and an invocation-only manifest cannot overwrite canonical replay state. Original audit bytes remain available in the retained source.
|
|
45
|
+
|
|
46
|
+
The source is opened read-only. Conversion validates UTF-8/JSON, rejects malformed records, missing/forward parents and duplicate IDs, and accepts a sealed valid unterminated final record without repairing the source. A private staged file is synced and published exclusively; occupied outputs, source aliases/symlinks and source changes are refused. The receipt records both locators, the unchanged native UUID, checksums, byte counts and conversion counts. A successful conversion always prints its receipt before attempting the optional exclusive receipt-file write. If that write fails, the command reports the error and exits unsuccessfully, while the published copy and printed receipt remain available; it never overwrites the occupied receipt or destination. Keep the receipt with the retained source and destination.
|
|
47
|
+
|
|
48
|
+
Select the converted locator explicitly through the native session/worker owner. Copies share a UUID, so do not leave both to arbitrary automatic lookup. Do not resume the original at an older boundary after newer effects. Conversion cannot recover evicted files, unstored credentials or an unrecorded mutation outcome; those remain unavailable or unknown.
|
|
49
|
+
|
|
50
|
+
## Verification
|
|
51
|
+
|
|
52
|
+
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.
|
|
53
|
+
|
|
54
|
+
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 and repeated legacy maps, through conversion and selected replay under a constrained V8 heap:
|
|
55
|
+
|
|
56
|
+
```sh
|
|
57
|
+
node --max-old-space-size=128 test/helpers/large-browser-journal.mjs
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
The printed receipt reports the actual heap limit and peak RSS separately; a V8 old-space cap is not a total-memory cap. Ordinary package, official/fork host, native platform and CI qualification remain separate checks.
|
package/docs/SUPPORT_MATRIX.md
CHANGED
|
@@ -33,14 +33,14 @@ The compact direct/code/loader surface replaces public multimode inputs while re
|
|
|
33
33
|
| Area | Contract and verification target |
|
|
34
34
|
| --- | --- |
|
|
35
35
|
| RQ-0064 fixed workflows | Public job DSL removed; native `batch --bail` preserves fixed ordering, waits, explicit assertions, paced keyboard/wait rows, and timeout partial progress. Code handles branches/loops. |
|
|
36
|
-
| RQ-0065 QA | Flat `agent_browser_qa` preserves visible assertions, attached-buffer scope, diagnostic residue ambiguity, actionable/benign classification, and actual pass/fail. |
|
|
36
|
+
| RQ-0065 QA | Flat `agent_browser_qa` preserves visible assertions, attached-buffer scope, diagnostic residue ambiguity, actionable/benign classification, and actual pass/fail. Fail-fast receipts separate failed checks from later `notRunChecks`; incomplete/timeout evidence stays unverified and execution counts without receipts remain unknown. |
|
|
37
37
|
| RQ-0066 / RQ-0067 source | Flat source/network tools retain bounded host scans and candidates-only semantics even in browser-only hosts. |
|
|
38
38
|
| RQ-0068 recipes | No recipe registry, persistent JavaScript, second driver, or interpreter dependency. |
|
|
39
39
|
| RQ-0096 Electron | Flat lifecycle tool preserves app/process/profile ownership and cancellation; native browser/code operations reuse its returned session. |
|
|
40
40
|
| RQ-0142 code | Fresh permissioned Node child over persistent parent-selected browser; explicit JSON/current-cell image output, visible failures/counts, ordinary auth/config/environment, ordered Pi intent/completion transitions, child cancellation/reaping, no legacy public execution. |
|
|
41
41
|
| Shared ordering | Actual socket/namespace/session lock spans helper/action or entire cell; sorted identity sets for replacement/cleanup and namespace barrier for direct close-all. Requires every participating Pi to run the updated package; no human/third-party/older-version guarantee or transaction. |
|
|
42
42
|
| Observation and geometry | Canonical bounded JSON/prose/code observations expose exact recovery and receipts; complete observation spills preserve large output. Image dimensions/CSS viewport/DPR/crop/scroll/frame evidence is measured or explicitly unknown; no viewport-coordinate assumptions for full-page/element images. |
|
|
43
|
-
| Pi integration | Native additive activation/history
|
|
43
|
+
| Pi integration | Native additive activation/history on independently qualified official Pi 0.87 and fork; public `pi:instruction-groups` registration supplies one full `browser` instruction source. Managed hosts own deferred delivery; unmanaged/stock hosts receive identical full eager guidance even for generic prompts. No permission widening or legacy discovery metadata. `test/agent-browser.discovery.test.ts` covers full-text parity, dynamic ownership, and startup/late registration; tool-surface tests preserve host selections, with pipeline coverage in `test/agent-browser.pi-pipeline.test.ts`. Optional checkpoint hooks, no provider payload/image-detail overrides. |
|
|
44
44
|
|
|
45
45
|
See [migration](TOOL_CONTRACT.md#07-migration), [canonical observations](TOOL_CONTRACT.md#canonical-observation), and [release qualification/rollback](RELEASE.md#07-upgrade-and-rollback). Routine GitHub Actions runs official/fork Linux compatibility, a macOS packed-Pi smoke, and native Linux checkpoints on PRs to `main`; Windows CI is excluded. Release/platform evidence and review remain separate from these focused checks.
|
|
46
46
|
|
|
@@ -74,7 +74,7 @@ Current summary:
|
|
|
74
74
|
| RQ-0136 | Wrapper regression fix keeps helper subprocess launch environments stable, refreshes active tab state after `tab close`, and makes ordinary document-direction scrolling deterministic before upstream fallback. | [`docs/ARCHITECTURE.md`](ARCHITECTURE.md), [`docs/TOOL_CONTRACT.md`](TOOL_CONTRACT.md#details) |
|
|
75
75
|
| RQ-0137 | Upstream `agent-browser 0.32.4` rebaseline adds HAR `--content` body modes, the `derive-client` skill, and fixed `find role` implicit-ARIA/name matching with locator-detail misses; wrapper classifier/argv/docs cover those surfaces. | [`docs/COMMAND_REFERENCE.md`](COMMAND_REFERENCE.md#upstream-0330-rebaseline) |
|
|
76
76
|
| RQ-0138 | Upstream `agent-browser 0.33.0` rebaseline adds `a11y` axe-core audits and discarded-tab revival on tab switch; wrapper documents/presents `a11y` and samples the new help surface. | [`docs/COMMAND_REFERENCE.md`](COMMAND_REFERENCE.md#upstream-0330-rebaseline) |
|
|
77
|
-
| 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
|
|
77
|
+
| 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 v4 set-valued ticket-claim daemon coordination, eight-candidate opportunistic cleanup with randomized first windows and in-process rotation, 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) |
|
|
78
78
|
| 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` |
|
|
79
79
|
| 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` |
|
|
80
80
|
| RQ-0142 | Persistent `agent_browser_code` uses the retained permissioned child and the same native executor as direct calls. Browser/auth state persists; JS state resets. Selected JSON/images, handled-failure receipts/counts, bounded IPC/deadline, shared whole-cell ordering, and ordered Pi transition replay replace isolated finally-close execution. The optional host `beforeExecute` callback retains outer call identity and serial dispatch. Strict old lease readers exist only for upgrade cleanup. | [`TOOL_CONTRACT.md`](TOOL_CONTRACT.md#agent_browser_code), [`ARCHITECTURE.md`](ARCHITECTURE.md#persistent-browser-code), `test/agent-browser.script.test.ts`, `test/agent-browser.tool-surface.test.ts`, `test/agent-browser.execution-lock.test.ts`, `test/agent-browser.execution-order.test.ts` |
|
|
@@ -87,8 +87,11 @@ Current summary:
|
|
|
87
87
|
| 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` |
|
|
88
88
|
| 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` |
|
|
89
89
|
| 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` |
|
|
90
|
+
| RQ-0153 | Browser storage retains native JSONL authority, once-stored ancestral ref definitions, small correlated begin/finish events, explicit uncertainty/reuse and native-generation validation, invocation-only artifact receipts and ordered row changes. Failed persistence never retries effects; ordinary forks retain facts without acquiring parent cleanup rights. Read-only token replay and stopped separate-copy conversion preserve all ancestry, explicit observations and original audit bytes. | [`docs/SESSION_STORAGE.md`](SESSION_STORAGE.md), `lib/browser-transcript.ts`, `lib/browser-journal.ts`, `lib/browser-session-conversion.ts`, `test/agent-browser.storage-growth.test.ts`, `test/agent-browser.storage-recovery.test.ts`, existing script/ref/confirmation/Electron lifecycle tests |
|
|
90
91
|
| RQ-0152 | Agent feedback closes recovery and evidence gaps without a new runtime layer: unknown-target timeouts return a visibly executable `get url` → `snapshot -i` fail-fast action while dialog recovery remains allowed; successful tab creation/selection/close, including dispatched batch rows, live-verifies URL/fresh titles and retains new, selected, and post-close blank tabs; compacted direct or batched `outputPath` writes use only full command-redacted live wrapper spills and fail rather than save metadata; explicit URL reads/all-read batches avoid browser helpers and managed replacement, while proven native read confirmations preserve exact session routing and capability-gated browser independence; single session-info preflights distinguish daemon/browser/native/Pi ownership; native recording receipts expose capture versus encoded measurements and survive failure/timeout exports, with bounded identity-matched recovery and no file-only success; direct or batched first/fresh local headed launches expose an unverified `browserWindow` handoff while attachments do not; snapshot spills and SAML/OAuth URL values are redacted at model/persistence boundaries; unsupported direct/batch `scrollintoview text=...` fails before upstream false success with visible native recovery payloads while help passes through; and web search sends Exa primary/version guidance, removes exact normalized-URL duplicates without overfetch, and labels provider page dates without claiming crawl/version proof. | [`docs/TOOL_CONTRACT.md`](TOOL_CONTRACT.md), [`docs/COMMAND_REFERENCE.md`](COMMAND_REFERENCE.md), [`docs/ARCHITECTURE.md`](ARCHITECTURE.md), `test/agent-browser.extension-errors-artifacts.test.ts`, `test/agent-browser.extension-tabs.test.ts`, `test/agent-browser.extension-validation.test.ts`, `test/agent-browser.page-target-validation.test.ts`, `test/agent-browser.runtime.test.ts`, `test/agent-browser.snapshot-presentation.test.ts`, `test/agent-browser.web-search.test.ts`, `test/agent-browser.real-upstream-contract.test.ts` |
|
|
91
92
|
|
|
93
|
+
Browser journal storage (RQ-0153) uses one canonical small event/reducer, once-stored complete captures and journal-ordered artifact changes. `test/agent-browser.storage-growth.test.ts` protects the incident-sized map and ordinary-code growth; `test/agent-browser.storage-recovery.test.ts` covers actual append-fault dispatch counts, concurrent publication during captured-branch replay, unpublished selected-leaf refusal, unknown prefixes, same-URL generation replacement, branch conversion and strict token validation. Existing tab/ref, read-confirmation, recording, artifact and Electron lifecycle suites retain their contracts. The opt-in `test/helpers/large-browser-journal.mjs` exercises a >1 GiB original with a giant ignored value under a constrained V8 heap; it reports actual RSS separately. Official and fork load/restart qualification remains independent, and stock official 0.99.2's native eager loader is not repaired by the extension alone. Conversion is offline and source-retaining; see [`SESSION_STORAGE.md`](SESSION_STORAGE.md).
|
|
94
|
+
|
|
92
95
|
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.
|
|
93
96
|
|
|
94
97
|
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.
|
|
@@ -144,10 +147,10 @@ Re-run the gates below before each release. Dated outcomes in this table are his
|
|
|
144
147
|
| Android/Termux local bring-up | Non-release-blocking source validation uses Termux system Chromium through upstream's Linux `which chromium` discovery, the packaged Linux-musl arm64 CLI, real Pi managed-session smoke, deterministic dogfood, and the default unit/package gate. Electron desktop lifecycle is not applicable. | **Historical 0.6 local evidence (not 0.7 code qualification):** Android 17 / arm64 Termux passed implicit, explicit, and namespaced fresh sessions, managed restore, script, QA, semantic action, job, click, eval/batch stdin, screenshot attachment, recording dependencies, and cleanup; Android is not yet a Crabbox release target. |
|
|
145
148
|
| Crabbox platform smoke | `npm run check:platform-smoke` syntax-checks the harness and cheap invariants. `npm run smoke:platform:ubuntu-image` builds the project-owned Linux image, `npm run smoke:platform:doctor` checks Crabbox 0.26.0+ and local target readiness, and `npm run smoke:platform:all` runs doctor first, then fast target-local `platform-build` (`npm run verify -- platform-target`, pack, clean Pi install) plus `browser-dogfood-smoke` on Crabbox `macos`, `ubuntu`, and `windows-native`; see [`platform-smoke.md`](platform-smoke.md). Target artifacts include Crabbox/provider/work-root metadata, and release review also checks provider-specific `crabbox list` commands for leftover leases/clones. | **Earlier 0.36.0 / package 0.6.2 / Pi 0.84.4:** Ubuntu `platform-build` and `browser-dogfood-smoke` passed with 11/11 assertions each on 2026-09-01, including complete artifact manifests and lease cleanup. Under explicit GitHub-only release waivers, macOS SSH and native Windows were not run because localhost SSH and `prlctl` were unavailable. |
|
|
146
149
|
| `verify -- release` / `prepublishOnly` | `npm run verify -- release` chains the default gate with the configured-source lifecycle harness, packaged Pi smoke, and the release-blocking Crabbox platform matrix (`verifySteps` `release` in [`scripts/project.mjs`](https://github.com/fitchmultz/pi-agent-browser-native/blob/main/scripts/project.mjs)). `package.json` `prepublishOnly` runs that compose before `npm pack --dry-run` during `npm publish`. It intentionally omits standalone real-upstream and host-only dogfood modes—see [`RELEASE.md`](RELEASE.md#pre-release-checks). | **Package 0.6.2:** on 2026-09-01 the default, lifecycle, package-Pi, startup, real-upstream, deterministic dogfood, harness, Ubuntu image, and Ubuntu target gates passed individually. The canonical full composition was not reported as passed because macOS SSH and native Windows were explicitly waived after doctor confirmed localhost SSH and `prlctl` were unavailable. That historical release created GitHub artifacts only; it did not authorize npm publishing. |
|
|
147
|
-
| Configured-source lifecycle | `npm run verify -- lifecycle` (`scripts/verify-lifecycle.mjs`) drives `/reload`, closes and relaunches Pi with the same exact `--session-id`, checks the JSONL session header id, session continuity, slash-command sentinel tokens (`v1` before reload and `v2` after full relaunch
|
|
150
|
+
| Configured-source lifecycle | `npm run verify -- lifecycle` (`scripts/verify-lifecycle.mjs`) drives `/reload`, closes and relaunches Pi with the same exact `--session-id`, checks the JSONL session header id, session continuity, slash-command sentinel tokens (`v1` before reload and `v2` after full relaunch), persisted spill reachability, and real Pi `tool_result` failure-patch semantics for a QA reclassification with a fake upstream on `PATH`. Default Pi model is `zai/glm-5.2`; default per-step wait is **180000 ms** (`DEFAULT_TIMEOUT_MS`); override model with `--model <id>` and waits with `--timeout-ms <ms>`. Passthrough flags in [`scripts/project.mjs`](https://github.com/fitchmultz/pi-agent-browser-native/blob/main/scripts/project.mjs): `--keep-artifacts`, `--model`, `--verbose`, and `--timeout-ms` plus a value (for example `npm run verify -- lifecycle --model openai-codex/gpt-5.5:minimal --keep-artifacts --verbose --timeout-ms 600000`). | **Pi 0.84.4 on 2026-09-01:** pass; `/reload`, exact-session relaunch, managed continuity, persisted spill reachability, and Pi failure-patch behavior all verified. |
|
|
148
151
|
| Quick isolated Pi smoke | `pi --approve --no-extensions --no-skills -e .` from trusted repo root; checkout-native browser tools only. | **Earlier 0.36.0 / package 0.6.2 / Pi 0.84.4:** isolated checkout tmux smoke passed on 2026-09-01; native `agent_browser` completed version, localhost open, WebMCP list/invoke, visible-text verification, and close. |
|
|
149
152
|
|
|
150
|
-
Runtime floor note: package metadata requires Node 24.21.0 or newer, keeps optional Pi core package peer ranges wildcard per installed Pi package docs, pins direct Pi validation dependencies to 0.
|
|
153
|
+
Runtime floor note: package metadata requires Node 24.21.0 or newer, keeps optional Pi core package peer ranges wildcard per installed Pi package docs, pins direct Pi validation dependencies to 0.99.2, and makes `pi --version` below 0.87.0 a setup failure through `pi-agent-browser-doctor` / `npm run doctor`. The Pi floor follows the native tool-history/prompt APIs and includes no older-host compatibility shim.
|
|
151
154
|
|
|
152
155
|
## Baseline checklist by inventory section
|
|
153
156
|
|