- translate daemon socket `ECONNREFUSED` and `ENOENT` failures into a
human-readable error
- print the exact `browse open` command that restarts the requested
session
- document that API keys are forwarded to an already-running daemon and
that `browse stop` is idempotent
- preserve regression coverage for late environment variables and
exit-code-zero cleanup
The daemon client passed raw Unix socket errors through to users when
the daemon disappeared between the readiness check and the request.
Agents received `ECONNREFUSED` without a recovery command.
Agents now get an actionable `daemon_not_running` failure with the exact
command needed to restart the session. Recovery command arguments are
shell-quoted, and a daemon disappearing between status and stop is
treated as an already-stopped session. Cleanup synchronizes with daemon
startup so it preserves a replacement daemon that starts during the stop
race. The bundled SKILL.md also makes the already-fixed env timing and
stop behavior explicit.
| Command / flow | Observed output | Confidence / sufficiency |
| --- | --- | --- |
| `pnpm --filter browse build` | TypeScript compilation and oclif
manifest generation completed successfully. | Proves the exact local CLI
code under review builds; does not exercise a live browser. |
| `pnpm --filter browse test:cli` | 25 test files passed; 366/366 tests
passed. This includes deterministic daemon disappearance/restart races,
adversarial recovery-command shell quoting, malformed CDP log payloads,
and the complete CLI contract suite. | Proves the full CLI suite passes
against the completed local build on macOS; GitHub CI provides the
Ubuntu/Windows matrix. |
| `BROWSE_DAEMON_DIR=<temp dir> node packages/cli/bin/run.js stop
--session no-daemon-smoke` | Exited `0` and printed `{ "stopped": false,
"session": "no-daemon-smoke" }`. | Exercises the built CLI's real
absent-daemon stop path and confirms its documented successful no-op
behavior. |
| `pnpm --filter browse lint` | Full-package Prettier, ESLint, and
TypeScript checks completed successfully. | Reproduces the CI lint
pipeline locally and verifies the daemon changes, log reducer, tests,
and inherited CLI lint baseline. |
Linear:
[GRO-1908](https://linear.app/browserbase/issue/GRO-1908/cli-namespace-2027-dev-suggested-docs-updates)
<!-- This is an auto-generated description by cubic. -->
---
Replaces raw socket errors with a clear `daemon_not_running` message and
prints the exact, shell-quoted `browse open` recovery command. `browse
stop` now treats a missing daemon as already stopped, validates
ownership before cleanup, and avoids tearing down a daemon that restarts
mid-race. Addresses Linear:
https://linear.app/browserbase/issue/GRO-1908/cli-namespace-2027-dev-suggested-docs-updates.
- **Bug Fixes**
- Map `ECONNREFUSED`/`ENOENT` to `daemon_not_running` and show the
precise, session-aware recovery command.
- Make `browse stop` idempotent and safe: if the daemon vanished (no
`--force`), return `{ stopped: false }`; acquire a lock and verify
daemon ownership before removing pid/socket/lock; preserve a replacement
daemon started during the stop race (handles PID reuse).
- Harden CDP log reduction: stricter parsing, ignore malformed payloads,
and require numeric response statuses.
- Docs: clarify `BROWSERBASE_API_KEY` is forwarded on every command and
`browse stop` is idempotent; add troubleshooting for the new error.
- Tests: cover the error message and shell-quoted recovery command
(round-tripped through `/bin/sh`), stop race cleanup and restart
preservation, PID reuse, and reduce-logs edge cases.
<sup>Written for commit 030c02a.
Summary will update on new commits.</sup>
<a
href="https://cubic.dev/pr/browserbase/stagehand/pull/2356?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
---------
Co-authored-by: Shrey Pandya <shrey@browserbase.com>
Summary
stagehand-v3@3.7.1alias so this baseline compiles and tests before any V4 migration beginsbrowse@0.9.6behavior, changelog, bundled skill, and versionReview boundary
This is the mechanical integration baseline. It intentionally preserves V3 runtime behavior. Child pull requests migrate one V4 concern at a time.
Refreshed on 2026-08-10 against the current parent and
v4-spikecommitd7556e9a.E2E Test Matrix
pnpm buildpassed 6/6 tasks;pnpm checkpassed 11/11 tasks with 0 errors; the fullpnpm testgraph exited 0, including 17/17 protocol browser tests and 15/15 local SDK browser testsv4-spiked7556e9aacross build, static checks, unit tests, and real-browser suites.example.com, produced a snapshot, clicked through to IANA, filled an injected input, and read backpublished-v4-okcorepack pnpm --filter browse test:uniton this branchcorepack pnpm buildon this branchcorepack pnpm checkon this branchbrowse@0.9.6--help, and version0.9.6No changeset is included because this pull request integrates already-published CLI behavior and preserves the runtime contract.
Final release validation (2026-08-10)
At the cumulative stack tip:
browsechangesetsbrowse0.9.7, Stagehand 4.0.1, extension 1.0.1, and Go 4.0.1workspace:*to exact Stagehand 4.0.1