Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
74 commits
Select commit Hold shift + click to select a range
304bfae
feat(session): add isolated browser evidence primitives
alvarohulse Aug 15, 2026
60597c9
feat(cli): support concurrent proof sessions
alvarohulse Aug 15, 2026
c59c401
test(session): cover concurrent private evidence
alvarohulse Aug 15, 2026
44c92e5
feat(browser): contain sessions to target domains
alvarohulse Aug 15, 2026
f579895
test(browser): verify per-session domain containment
alvarohulse Aug 15, 2026
bc1916c
test(session): refuse force cleanup of live ownership
alvarohulse Aug 15, 2026
acbcc3e
test(evidence): cover redaction and network summaries
alvarohulse Aug 15, 2026
742a909
fix(exec): refuse commands without an active proof session
alvarohulse Aug 15, 2026
d57e028
test(session): cover stale force recovery and inventory
alvarohulse Aug 15, 2026
cae305a
fix(evidence): reject synthetic DOM proof
alvarohulse Aug 15, 2026
d1ecdc8
test(evidence): cover diagnostic-only DOM mutation
alvarohulse Aug 15, 2026
4604489
fix(evidence): redact sensitive browser results
alvarohulse Aug 15, 2026
a894923
test(evidence): cover private result redaction
alvarohulse Aug 15, 2026
2d50148
refactor(session): remove singleton control state
alvarohulse Aug 15, 2026
513d8bf
test(session): align state coverage with registry control
alvarohulse Aug 15, 2026
27a7b92
fix(evidence): flush HAR after request inventory failure
alvarohulse Aug 15, 2026
4f6323b
test(evidence): cover HAR flush fallback
alvarohulse Aug 15, 2026
a2170de
refactor(session): isolate action-log persistence
alvarohulse Aug 15, 2026
9bc639e
fix(evidence): mark interrupted actions incomplete
alvarohulse Aug 15, 2026
b9943e7
test(evidence): cover interrupted action receipts
alvarohulse Aug 15, 2026
f207bae
test(session): preserve isolation across interrupted exec
alvarohulse Aug 15, 2026
c02c0b0
fix(session): serialize lifecycle operations
alvarohulse Aug 15, 2026
80a32e4
fix(session): ignore stale implicit targets
alvarohulse Aug 15, 2026
4ae5c24
fix(evidence): sanitize nested browser actions
alvarohulse Aug 15, 2026
e11c162
test(evidence): cover nested action redaction
alvarohulse Aug 15, 2026
4862d33
fix(evidence): finalize HAR capture atomically
alvarohulse Aug 15, 2026
26eee69
test(evidence): cover interrupted HAR recovery
alvarohulse Aug 15, 2026
4a0aabb
fix(browser): enforce isolated 0.34 runtime
alvarohulse Aug 15, 2026
31552f9
test(browser): cover runtime isolation
alvarohulse Aug 15, 2026
928cf8f
chore(browser): pin agent-browser 0.34.0
alvarohulse Aug 15, 2026
b08594d
docs(workflow): define exploration-to-proof flow
alvarohulse Aug 15, 2026
d84665c
fix(skills): align inline proof workflow
alvarohulse Aug 15, 2026
bf4f55d
fix(browser): Harden action provenance parsing
alvarohulse Aug 15, 2026
039ba1d
fix(browser): Reject plugin configuration
alvarohulse Aug 15, 2026
c6f31b7
fix(browser): Pin verified executable per session
alvarohulse Aug 15, 2026
2383d0e
fix(evidence): Preserve retryable network capture
alvarohulse Aug 15, 2026
b5bdb48
fix(browser): Anchor exact runtime verification
alvarohulse Aug 15, 2026
ff3a2ff
fix(browser): Redact inline secret flags
alvarohulse Aug 15, 2026
e8b3aa4
fix(evidence): Retain delayed HAR recovery
alvarohulse Aug 15, 2026
119a865
fix(browser): Backfill legacy runtime pins
alvarohulse Aug 15, 2026
81c72c3
fix(browser): Classify default find clicks
alvarohulse Aug 15, 2026
a22354b
fix(browser): Reject containment overrides
alvarohulse Aug 15, 2026
6634997
fix(browser): Pin runtime file identity per session
alvarohulse Aug 15, 2026
5929f48
fix(evidence): Finalize unavailable stale network capture
alvarohulse Aug 15, 2026
46c0cd2
fix(browser): Reserve proof capture lifecycle commands
alvarohulse Aug 15, 2026
0436bb2
fix(browser): Fail closed on unsafe commands
alvarohulse Aug 15, 2026
b03fa7f
fix(evidence): Sanitize browser command output
alvarohulse Aug 15, 2026
e93f46f
fix(browser): Refuse cleanup of live legacy sessions
alvarohulse Aug 16, 2026
f6feae8
fix(evidence): Keep output directories private
alvarohulse Aug 16, 2026
57f6c53
fix(browser): Execute agent-browser with argv
alvarohulse Aug 16, 2026
aeade88
fix(evidence): Enforce private raw evidence boundary
alvarohulse Aug 16, 2026
844a619
fix(evidence): Finalize unavailable HAR capture
alvarohulse Aug 16, 2026
0022808
fix(provenance): Retain exact browser runtime receipt
alvarohulse Aug 16, 2026
1ca2b22
chore(runtime): Require Node 24 and agent-browser 0.34.0
alvarohulse Aug 16, 2026
0905c6b
fix(evidence): Redact authentication path tokens
alvarohulse Aug 16, 2026
16354f7
fix(evidence): close secret redaction gaps
alvarohulse Aug 16, 2026
6a3b836
fix(browser): reject inherited JSON output mode
alvarohulse Aug 16, 2026
38983fc
fix(server): reject concurrent port race losers
alvarohulse Aug 16, 2026
89c209d
fix(artifacts): refuse unsafe existing output directories
alvarohulse Aug 16, 2026
0c2fd0c
fix(browser): Close remaining evidence isolation gaps
alvarohulse Aug 16, 2026
58cdcf4
fix(browser): Preserve complete diagnostic secret redaction
alvarohulse Aug 16, 2026
525dce5
fix(server): Verify dev server listener ownership
alvarohulse Aug 16, 2026
594eeba
fix(evidence): Redact free-form secret fields
alvarohulse Aug 16, 2026
0db24d0
fix(evidence): Redact folded secret fields
alvarohulse Aug 16, 2026
6d6e27d
fix(evidence): Redact blank-line continuations
alvarohulse Aug 16, 2026
005bbf1
fix(browser): Unify secret redaction policy
alvarohulse Aug 16, 2026
ecfe7f3
fix(server): Make listener inspection reliable
alvarohulse Aug 16, 2026
47a78db
fix(browser): Redact mixed-case URLs and plural secrets
alvarohulse Aug 16, 2026
efe115e
fix(browser): Redact fused secrets and sensitive attributes
alvarohulse Aug 16, 2026
9f4533b
fix(artifacts): Reject unsafe output path ancestors
alvarohulse Aug 16, 2026
05c0fa1
fix(browser): Recognize conventional fused secret fields
alvarohulse Aug 16, 2026
8e21525
fix(browser): Complete fused secret field grammar
alvarohulse Aug 16, 2026
09684a1
fix(browser): Redact fused secret key fields
alvarohulse Aug 16, 2026
c4dcf97
fix(artifacts): Anchor output directory creation
alvarohulse Aug 16, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "20.x"
node-version: "24.x"
cache: npm

- name: Install system test dependencies
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "20.x"
node-version: "24.x"
cache: "npm"

- name: Install dependencies
Expand Down Expand Up @@ -63,7 +63,7 @@ jobs:
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "20.x"
node-version: "24.x"
cache: "npm"
registry-url: "https://registry.npmjs.org"

Expand Down
20 changes: 12 additions & 8 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ src/
├── commands/ # One file per CLI command (install, start, stop, exec, diff, pr, clean)
├── browser/ # agent-browser CLI wrappers (session, capture, interact, navigate)
├── server/ # Dev server detection, startup, port waiting
├── session/state.ts # .session.json lifecycle (save/load/clear)
├── session/ # Global registry, per-session leases, selection, manifests
├── session/metadata.ts # Persistent per-session metadata (branch, commit) for PR matching
├── artifacts/ # Output generation (viewer.html, SUMMARY.md, PR format)
└── utils/ # Config, exec helpers, port utils, error patterns, GitHub API
Expand All @@ -30,16 +30,16 @@ src/

- **ESM only** — all imports MUST use `.js` extensions: `import { foo } from '../utils/config.js'`
- **Build before test** — CLI runs from `dist/`, always `npm run build` after code changes
- **agent-browser** — external peer dependency (Rust CLI + Node daemon). All browser commands go through `ab()` in `utils/exec.ts` which calls `agent-browser <command>` via `execSync`
- **Session state** — `start` writes `.session.json`, `exec` and `stop` read it. `stop` clears it. Don't assume session exists without checking
- **agent-browser** — exact 0.34.0 runtime dependency. ProofShot preflights version/capabilities and uses a dedicated Node 24 launcher without changing the project's runtime
- **Session state** — registry files live under the user state directory; every session has an immutable ID, private browser namespace, evidence directory, and operation lease. `exec`/`stop` auto-select only one live match or require `--session`
- **Session metadata** — `start` writes `metadata.json` inside each session folder with git branch/commit. This persists after `stop` and is used by `pr` to match sessions to branches
- **Per-session subfolders** — artifacts go in `proofshot-artifacts/YYYY-MM-DD_HH-mm-ss_slug/`

## Command lifecycle

1. `proofshot start` — spawns dev server, opens browser, starts recording, saves session state + writes `metadata.json` with git branch/commit
2. `proofshot exec <args>` — logs action to `session-log.json`, forwards to `agent-browser`
3. `proofshot stop` — collects errors, stops recording, trims video, generates SUMMARY.md + viewer.html, clears session
1. `proofshot start` — validates a local isolated browser, claims a start lease, opens a unique agent-browser namespace, starts recording/network capture, and writes metadata
2. `proofshot exec [--session ID] <args>` — claims an exec lease, logs sanitized provenance/private structured output, and forwards to the exact browser
3. `proofshot stop [--session ID]` — claims a stop lease, atomically finalizes private evidence, performs exact cleanup, and generates canonical artifacts
4. `proofshot pr [number]` — finds sessions for current branch, uploads artifacts to GitHub, posts PR comment

## Adding a new command
Expand Down Expand Up @@ -69,8 +69,10 @@ Edit `src/utils/error-patterns.ts` — add a new entry to the `PATTERNS` array:
| `metadata.json` | `start` | Git branch, commit SHA, timestamp (persists after stop) |
| `session.mp4` | `stop` | Finalized H.264 recording (`start` captures temporary `session.webm`) |
| `session-log.json` | `exec` (appended each call) | Action timeline with relative timestamps |
| `server.log` | `start` (piped stdout+stderr) | All dev server output |
| `console-output.log` | `stop` | Browser console output |
| `private/server.log` | `start` (piped stdout+stderr) | Private raw dev server output |
| `private/browser/console-output.log` | `stop` | Private raw browser console output |
| `network-summary.json` | `stop` | Sanitized endpoint/method/status/timing/error metadata |
| `private/agent-browser/` | `exec` / `stop` | User-only raw JSON/HAR; excluded from manifests and publication |
| `step-*.png` | `exec screenshot` | Screenshots at key moments |
| `SUMMARY.md` | `stop` | Markdown report with errors and screenshots |
| `viewer.html` | `stop` | Standalone HTML viewer with video + timeline |
Expand All @@ -90,6 +92,8 @@ Edit `src/utils/error-patterns.ts` — add a new entry to the `PATTERNS` array:
## Gotchas

- `proofshot exec` has special shell quoting logic (`buildShellCommand` in exec.ts) — `eval` commands get single-quoted, args with special chars get auto-quoted
- Direct DOM mutation is diagnostic only; synthetic actions force `INCOMPLETE`. Preserve category/redaction behavior when adding commands
- Every browser subprocess strips provider/CDP/profile/state/session/proxy inheritance and uses the persisted private config, namespace, allowlist, and socket root
- Video trimming adjusts session-log.json timestamps to match the trimmed video (see `trimOffsetSec` in stop.ts)
- Server log capture only works when proofshot starts the server itself — if the port is already occupied, we skip spawning and get no server logs
- The `consoleErrors`/`consoleOutput` from agent-browser are point-in-time snapshots collected at stop time
34 changes: 13 additions & 21 deletions PROOFSHOT.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,18 @@
# ProofShot Visual Verification
# ProofShot visual verification

ProofShot is an open-source, agent-agnostic CLI that lets any AI coding agent verify its own work in a real browser — no vendor lock-in required.
Explore UI behavior with the approved local agent-browser launcher, maintain User Stories/Use Cases/User Flows and iteration feedback under the task's persistent `~/data` directory, then record one fresh ProofShot session per finalized Use Case.

After building or modifying UI features, verify with this workflow:
```bash
proofshot start --run "your-dev-command" --port PORT --description "UC-ID: behavior"
proofshot exec snapshot -i
proofshot exec click @e3
proofshot exec assert-visible "#expected-result"
proofshot exec screenshot step-result.png
proofshot stop
```

1. Start: `proofshot start --run "your-dev-command" --port PORT --description "what you are verifying"`
If the server is already running, omit --run.
2. Test: Use `proofshot exec` to navigate, click, fill forms, take screenshots
3. Stop: `proofshot stop` — bundles video, screenshots, and error report
With multiple sessions, pass the printed ID to `proofshot exec --session ID ...` and `proofshot stop --session ID`. Prefer pointer/keyboard actions, disclose hybrid input, and treat synthetic DOM mutation as diagnostic only. `FAIL`, `INCOMPLETE`, and `BLOCKED` are unsuccessful.

ProofShot keeps all `proofshot exec` commands inside the same isolated `agent-browser` session that was created by `proofshot start`, so recording, screenshots, and browser actions stay aligned.
Keep raw JSON, HAR, response bodies, credentials, and customer data private under the task's `~/data` evidence root. Report the local path without copying raw artifacts into prompts, scratch, PRs, or uploads. Copy only exercised final flows into PR User Testing instructions, then dry-run ordered explicit publication with repeated `--session` flags.

Use `--url` on `start` when verification must begin on a specific target. In an isolated HOME, ProofShot discovers executable-only Chrome/Chromium installs from system/account locations; use `--browser-executable /absolute/path/to/chrome` to select one explicitly.

Key proofshot exec commands:
- `proofshot exec snapshot -i` — see interactive elements
- `proofshot exec click @e3` — click an element
- `proofshot exec fill @e2 "text"` — fill a form field
- `proofshot exec screenshot step.png` — capture a moment

Artifacts saved to ./proofshot-artifacts/ including video, screenshots, errors, and summary.
Custom `--output` paths do not move active control state, so a separate `proofshot stop` still finds the session. `stop` is idempotent; after `stop --no-close`, run a later plain `stop` to close that exact retained browser without rebundling.
You can customize browser launch behavior in `proofshot.config.json`, including HTTPS error ignoring, a custom browser executable path, and a project-specific `agent-browser` config path.

Use `proofshot doctor` when the local setup looks wrong. It prints the current config path, browser mode, viewport, installed binaries, and any active ProofShot session.
Browser tooling requires agent-browser 0.34.0 through its Node 24 launcher; project commands continue to honor the repository runtime. Recover with `proofshot session list` and `proofshot session clean --session ID`, never broad process cleanup.
27 changes: 18 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,9 @@ npm install -g proofshot
proofshot install
```

The first command installs the CLI and [agent-browser](https://github.com/vercel-labs/agent-browser) (with headless Chromium). The second detects your AI coding tools and installs the ProofShot skill at user level — works across all your projects automatically.
The first command installs the CLI and the exact agent-browser 0.34.0 package. agent-browser requires Node 24; managed environments should expose it through a dedicated Node 24 launcher so project servers can continue using their repository runtime (for example, Node 22 from `.nvmrc`). The second command installs the ProofShot skill at user level.

Starting a dev server with `--run` also requires `lsof` on Linux/macOS; Windows uses PowerShell's `Get-NetTCPConnection`. Run `proofshot doctor` to verify the listener-inspection prerequisite.

## How It Works

Expand Down Expand Up @@ -102,11 +104,12 @@ Each session produces a timestamped folder in `./proofshot-artifacts/`:
| `SUMMARY.md` | Markdown report with errors, screenshots, and video |
| `step-*.png` | Screenshots captured at key moments |
| `session-log.json` | Action timeline with timestamps and element data |
| `server.log` | Dev server stdout/stderr (when using `--run`) |
| `console-output.log` | Browser console output |
| `evidence.json` | Canonical browser/environment events, incidents, source integrity, and media timing |
| `verdict.json` | Structured `PASS`, `FAIL`, `INCOMPLETE`, or `BLOCKED` verdict |
| `artifact-manifest.json` | Finalized repository/commit provenance and ordered artifact hashes |
| `artifact-manifest.json` | Finalized repository/commit/runtime provenance and ordered artifact hashes |
| `network-summary.json` | Sanitized request method/status/timing/error metadata |

Raw agent-browser JSON, HAR, browser-console, and ProofShot-owned server evidence stays under the session's `private/` directory with user-only permissions. It is excluded from manifests and publication; only curated media and sanitized summaries are reviewable artifacts.

<p align="center">
<img src="brand-assets/screenshots/artifacts-folder.png" alt="ProofShot artifacts folder" width="480" />
Expand Down Expand Up @@ -161,18 +164,21 @@ You can also configure browser launch behavior in `proofshot.config.json`:
}
```

Set `browser.configPath` when you need ProofShot to run `agent-browser` against a project-specific config instead of inheriting `~/.agent-browser/config.json`. Relative paths are resolved from the directory that contains `proofshot.config.json`.
Set `browser.configPath` for a project-specific agent-browser config. ProofShot validates it, rejects provider/CDP/profile/state/proxy and default JSON-output modes, and copies it into private per-session state. Without this option, ProofShot uses an empty per-session config instead of inheriting user or project agent-browser defaults.

ProofShot rejects inherited `AGENT_BROWSER_JSON` at session preflight and strips it from every agent-browser subprocess. ProofShot enables JSON only for individual internal calls whose structured output it parses; a global JSON mode would change normal command output and break evidence capture.

ProofShot discovers system and account-level Chrome/Chromium installs even when the command runs with an isolated `HOME`. If no runnable browser is found, `start` prints the exact `agent-browser install` action. An explicit `--browser-executable` takes precedence for one run.
ProofShot requires agent-browser 0.34.0, a local Chrome/Chromium executable, an explicit target-domain allowlist, and a fresh isolated session. Cloud providers, shared CDP browsers, persistent profiles/state, and auto-connect are refused. If no runnable browser is found, `start` prints the exact `agent-browser install` action. An explicit `--browser-executable` takes precedence for one run.

`--output` changes only where evidence is written. Active control state stays in the configured/default output directory, so later `proofshot exec` and `proofshot stop` processes can find the same session.
`--output` changes only where evidence is written. Registry-backed control state remains discoverable across processes. Concurrent sessions in one worktree are supported; commands resolve a single live session automatically and require `--session <id>` when several live sessions match. `--force` recovers proven stale state only and refuses live processes or lifecycle operations.

### `proofshot stop`

Stop recording, collect errors, generate proof artifacts.

```bash
proofshot stop # Stop session and close browser
proofshot stop --session ID # Stop one exact session
proofshot stop --no-close # Stop but keep browser open
```

Expand All @@ -186,11 +192,13 @@ When a ProofShot session is active, `proofshot exec` reuses the same isolated `a

```bash
proofshot exec click @e3
proofshot exec --session ID click @e3
proofshot exec assert-visible "#checkout-complete"
proofshot exec screenshot step-checkout.png
```

Failed `assert-visible` checks are recorded in `session-log.json` and contribute to the structured verdict.
Action receipts include sanitized intent, interaction category, timing, outcome, and page context. Synthetic DOM actions make final proof incomplete; they remain useful only for diagnosis.

### `proofshot diff`

Expand Down Expand Up @@ -227,6 +235,7 @@ Inspect and clean durable recovery records after an interrupted or incomplete cl
```bash
proofshot session list
proofshot session clean --session <session-id>
proofshot session clean --all
```

Cleanup validates persisted process identities and never widens to a name-, port-, or default-socket kill.
Expand All @@ -239,11 +248,11 @@ Remove the `./proofshot-artifacts/` directory.
proofshot clean
```

`clean` refuses while active or retained session control state exists. Run `proofshot stop` first so ProofShot does not discard exact process ownership metadata.
`clean` refuses while any matching registry state exists, including stale, starting, stopping, or recovery records. Run `proofshot stop` or `proofshot session clean` first so ProofShot does not discard evidence or exact process ownership metadata.

### `proofshot doctor`

Print the current ProofShot environment, including config path, browser mode, viewport, installed binaries, and any active session.
Print the current ProofShot environment, including config path, browser mode, viewport, installed binaries, TCP listener-inspection support, and any active session.

```bash
proofshot doctor
Expand Down
37 changes: 19 additions & 18 deletions content/docs/concepts/how-it-works.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -47,41 +47,42 @@ ProofShot uses a three-phase model.
1. Check if the port is available (fail fast on conflicts)
2. Spawn an isolated dev-server process session if `--run` is provided, pipe timestamped output to `server.log`, and persist its immutable PID/process-group identity
3. Wait for the port to respond (polls every 500ms, 30s timeout)
4. Open the requested URL in a short, collision-safe agent-browser session and persist its daemon identity
5. Start video recording
6. Write `.session.json` to the configured/default control directory and `metadata.json` beside the evidence (git branch/commit, persists after stop)
4. Verify agent-browser 0.34.0, reject inherited provider/CDP/profile/state modes, and copy a safe config into private per-session state
5. Open the requested URL in a unique namespace with a target-domain allowlist and persist the daemon identity
6. Start private HAR capture and video recording
7. Register the immutable session ID and operation lease under the user state directory; write `metadata.json` beside the evidence

Recording is mandatory. If it fails after 3 retries, the session aborts.

### Phase 2: Exec (repeated)

Each `proofshot exec` call:

1. Loads `.session.json` and validates the session is active
2. For `click`/`fill`/`type` targeting `@eN` refs: captures the element's bounding box and label *before* execution
3. Appends an entry to `session-log.json` with a relative timestamp
4. Forwards the command to agent-browser
5. Returns the output
1. Selects the single addressable recording or requires `--session <id>` when several live sessions match
2. Claims an immutable exec lease
3. Captures pre-action page context and element data where available
4. Appends sanitized intent, interaction category, timing, and outcome to `session-log.json`; raw structured output stays private
5. Forwards the command to the exact agent-browser namespace and releases the lease

### Phase 3: Stop

`proofshot stop` collects and bundles everything:

1. Collects browser console errors and output (point-in-time snapshot)
2. Stops video recording
3. Closes the exact owned browser session
4. Stops only the dev-server process session created by this run
5. Trims video dead time using ffmpeg (5s buffer before first action, 3s after last), converts the finalized recording to H.264 `session.mp4`, and adjusts all `session-log.json` timestamps by the trim offset.
6. Scans `server.log` with multi-language regex patterns for errors
7. Generates `SUMMARY.md` and `viewer.html`
8. Clears `.session.json` (or retains exact browser ownership after `--no-close`)
1. Claims a stop lease and collects console evidence
2. Atomically finalizes private HAR evidence and writes a metadata-only network summary
3. Stops video recording and closes only the exact owned browser/environment/server processes
4. Trims video dead time using ffmpeg, converts to H.264 `session.mp4`, and adjusts action timestamps
5. Generates canonical evidence, verdict, summary, viewer, and provenance manifest
6. Unregisters completed ownership, or retains the exact browser record after `--no-close`

## Design principles

**Graceful degradation.** Missing ffmpeg? Video trimming and MP4 conversion are skipped, preserving the original `session.webm`. Element data capture fails? Overlays are skipped. Browser already closed? Silent catch. Non-critical failures never abort a session.

**Minimal dependencies.** Three production dependencies: `commander`, `chalk`, `detect-port`. agent-browser is an optional peer dependency. Small install, small supply chain.
**Pinned browser contract.** ProofShot pins agent-browser 0.34.0 and fails before launch on older versions. Managed launchers keep its Node 24 runtime separate from project runtimes.

**Session isolation.** Each project keeps control state in its configured/default output directory. A CLI-only custom evidence path cannot hide the session from a later process, while different projects still run independently.
**Session isolation.** Registry-backed immutable IDs, namespaces, sockets, operation leases, and evidence directories allow concurrent sessions in one worktree without cross-session cleanup.

**Private evidence boundary.** Raw JSON, HAR, response bodies, credentials, and customer data remain in a user-only private directory excluded from manifests and publication.

**ESM-only.** All imports use explicit `.js` extensions for correct resolution after TypeScript compilation.
Loading
Loading