Skip to content

v0.4.1 — cross-session state, recording lifecycle, and batch-selection fixes

Choose a tag to compare

@fitchmultz fitchmultz released this 11 Aug 11:16
· 140 commits to main since this release

pi-agent-browser-native 0.4.1 isolates managed browser restore state per Pi transcript and hardens QA, artifact, recording, and session lifecycle behavior found during parallel real-browser dogfood.

Highlights

  • Scopes upstream restore keys to both checkout generation and the full hashed Pi transcript. Concurrent chats no longer overwrite or inherit each other’s cookies or storage, while one transcript keeps continuity across fresh rotation, reload, restart, and /resume.
  • Makes URL QA trustworthy by clearing diagnostics, sampling post-clear page-error residue, and waiting briefly for immediate post-load errors.
  • Keeps a successful nested close terminal through later explicitly non-launching diagnostics, while failed/unknown post-close rows remain tracked unless lifecycle proves no relaunch; namespace-scoped close --all exclusively drains matching work and clears every managed/attached/page/ref/route/trace/recording owner.
  • Rejects stale/future artifacts and missing/stale restart recordings. A transcript-backed namespace/session reservation index serializes explicit artifact destinations, follows lexical/symlink/hardlink/full-Unicode/platform-case aliases, mirrors upstream global cleanup, screenshot positional rules, wait precedence, final diff output, and HAR-stop paths, prevents same-call outputPath and Electron-cleanup ordering bypasses, rejects recording starts after nested close, persists close tombstones, and reconciles direct, batch, failed-stop, script, Electron, replacement, and shutdown transitions across live state and replay.
  • Preserves exact stop-pending-recording recovery with visible guidance when any later same-session call fails during an active recording. Same-millisecond lifecycle order survives inner and concurrent outer manifest merges, replay, and a one-entry recent window.
  • Prevents namespace-wide close --all from deadlocking against a late same-session arrival while retaining exclusive cleanup ordering.
  • Warns that upstream record start switches to a fresh active page whose prior DOM and JavaScript state does not carry over, then tells agents to take a fresh snapshot; the wrapper also invalidates the session's prior page-scoped @e… refs (direct calls and batch steps) with a persisted page-transition invalidation, so stale refs fail as stale-ref until a fresh snapshot succeeds and batch stdin cannot reuse old refs after a record start step. Invalidation is attempt-scoped — upstream swaps the page before its already-active check, so a failed record start still invalidates — and record restart with a URL operand invalidates the same way while a plain restart keeps the page and refs. Upstream ref-resolving reads and captures (is, screenshot, highlight, scroll, frame, diff) now pass the same stale-ref guards as mutations, while literal @e…-looking operands (wait --text @e1, find text @e1 click, values of value-taking flags such as --baseline) pass through unguarded and refs after boolean flags (click --new-tab @e1, screenshot --full @e1) stay guarded; a batch that times out or returns unparseable output after executing still records the recording page-swap invalidation from its planned steps (raw batch arguments exclusively when present, stdin only otherwise, matching upstream); the stale-ref preflight and intra-batch latch scan that same upstream-exclusive step source, so raw argument-mode batches (batch "click @e1") are guarded after a recording page swap and stdin refs are not falsely rejected when raw arguments exist, and the managed-restore docs state the fail-closed truth that a checkout rename or different working directory starts a fresh restore key. Tab-pinned batch rewrites dispatch those same upstream-effective steps (never resurrecting ignored caller stdin), artifact/recording preflight and batch screenshot preparation skip upstream-ignored stdin rows, and raw-argument filtering matches upstream's exact --bail token so --bail=true stays a raw command. Pinned rewrites re-emit the caller's exact --bail so fail-fast batches stay fail-fast under tab pinning, and parent directories are prepared for effective raw artifact rows without rewriting raw strings.
  • Improves semantic select, same-page batch ref handling, no-op scroll truthfulness, Windows argv behavior, Unix socket diagnostics, passive-config isolation, exact upstream version checks, and namespaced Electron probe/cleanup replay.
  • Includes the reload compatibility fix from @coreyallen in #96 and the packaged build-script fix from @selimerunkut in #100 with credit.

Validation

The exact PR head d6cde09af8d7757bbfba5a4ffaf83381bb392683 passed:

  • npm run verify -- pre-pr: 765 tests passed, two opt-in tests skipped, 130 packed files
  • npm run verify -- real-upstream: 2/2, including same-transcript continuity, distinct-transcript isolation, passive-config precedence, and pre-spawn nested close/record rejection
  • deterministic real-browser dogfood, packaged Pi smoke, and startup profiling (62.3 ms median, 68.6 ms maximum, below the 250 ms budget)
  • rebuilt-checkout remediation smoke: open/snapshot passed; duplicate sentinel screenshot, extra-positional screenshot reuse, and reordered/repeated-timeout wait reuse failed in preflight; record stop verified a 49,775-byte WebM before clean close
  • exact-head fresh-process recording smoke: controlled tab evidence proved record start switches from t1 with Count: 1 to a new active t2 with Count: 0; the final build made that context reset and fresh-snapshot instruction visible, then saved a verified 44,661-byte WebM and closed cleanly
  • exact-head recording page-swap matrix smoke (final head): failed already-active record start still invalidated old refs, plain record restart preserved them, URL-bearing record restart invalidated them, recovery snapshots restored refs, and all recordings saved before a clean close
  • exact-head stale-ref invalidation smoke: after record start, a click on the pre-recording @e1 failed pre-spawn as stale-ref with the exact page-transition message, a fresh snapshot -i restored refs, the fresh-ref click succeeded, and record stop saved a verified 72,078-byte WebM before a clean close
  • exact-head Electron smoke: wrapper-owned isolated Linear launch, status, probe, explicit-session title read, cleanup, and dead/not-attached tombstone status all passed; an already-running Claude singleton failed safely with precise diagnostics and no residue
  • exact-head nested lifecycle regression smoke: record start → wait → close → record stop succeeded in one native batch, produced one verified 15,406-byte WebM with no abandoned duplicate, kept the same managed session active, returned expected about:blank without stale pre-close mismatch guidance, then closed cleanly
  • prior-candidate as-shipped Pi git-source install at its immutable SHA plus an exact-clone, direct-OpenAI agent sweep: open/snapshot/interact, verified 16,882-byte screenshot, 2,621-byte HAR, and 29-byte download artifacts, profile and doctor diagnostics, validation/stale-ref/selector recovery, recording-reservation replay through /reload with a verified 440,642-byte WebM stop, terminal [["close"],["stream","status"]] lifecycle and session rotation, and clean session shutdown all passed
  • Ubuntu Crabbox platform-build and browser-dogfood-smoke from the release branch; the second suite reused the first suite’s dependency install

A Cloudflare AI Gateway attempt exposed upstream Pi issue #7896, where omitted strict: false made every optional tool-schema field required; direct OpenAI on the same checkout/prompt passed, so this is external and non-blocking. The configured-source lifecycle harness remained environment-blocked by missing model credentials in its isolated Pi home. The full platform doctor remained blocked by macOS SSH setup and unavailable Parallels prlctl; Ubuntu passed. These are setup blocks, not skips.

Full details: PR #108, CHANGELOG.md, and the v0.4.0...v0.4.1 comparison.

This is a GitHub release only. The npm package was not published from this machine.