Skip to content

Harden CLI so browser automation works without manual recovery - #24

Merged
macieju-opera merged 3 commits into
mainfrom
harden-cli-reliability
Aug 19, 2026
Merged

Harden CLI so browser automation works without manual recovery#24
macieju-opera merged 3 commits into
mainfrom
harden-cli-reliability

Conversation

@macieju-opera

Copy link
Copy Markdown
Contributor

Summary

Hardens the CLI so browser automation works without manual recovery, and stops the CLI from reporting fake success when the browser it points at is actually unreachable.

Changes

  • Self-healing bridge (3 commits, 12d57aca9fd83f): bridge restarts itself on version skew, crash, or dropped connection; falls back to another port if one is taken; and detects a wedged bridge (up but pointed at a dead browser) by probing the attach URL on /health, so findUsableBridge stops reusing it and rebuilds against the current target.
  • Fake-success elimination: open (and unreachable-browser recovery in callTool) now fail loudly with BROWSER_ERROR (exit 3) instead of emitting a fake refs:0 page when the browser is running without a debug port or the bridge points at a browser that has closed.
  • Conflict reconciliation runs even when a bridge is alive: the takeover / separate-profile prompt fires instead of being silently skipped (previously the CLI kept driving a stale headless/separate-profile browser).
  • Condensed SKILL.md with the ask-the-user rule for browsers that can't be automated.

Testing

  • New preflight, bridge-recovery, bridge-lifecycle, bridge-startup, browser-target, and exit-codes suites, plus a stub-MCP fixture for unreachable-browser recovery.
  • Full suite: 24 files, 455 passing; tsc --noEmit clean.

Notes

Resolves the behaviour described in specs/robustness-hardening.md.

The bridge, the browser, and first-run setup each had failure modes that
left the user to diagnose and repair by hand. Each is now detected and
resolved automatically, or reported with the command that fixes it.

Bridge lifecycle:
- /health carries package version, pid and boot id; a bridge running
  pre-upgrade code is replaced instead of looking healthy forever
- never signal a pid that has not been identified as ours (a recycled pid
  after reboot could previously be SIGTERMed)
- exclusive start lock and a port range, so concurrent commands start
  exactly one bridge and a taken port is not a hard error
- READY/FAILED handshake surfaces a dead child in milliseconds rather than
  a 30s blind poll, with the bridge log tail in the error
- dropped connections restart and retry once; Opera AI tools are never
  silently replayed
- add restart/status; stop escalates to SIGKILL and clears stale pid files

Browser conflicts:
- detect a profile held by a running browser via SingletonLock
- attach automatically when it exposes a debug port (DevToolsActivePort)
- otherwise offer to restart it (TTY, or --takeover); never quit a
  browser unprompted, and never SIGKILL one
- add attach and launch-args

First run:
- detect and configure on first use instead of hinting at `setup`
- setup gains non-interactive flags and no longer requires a TTY
- headed when an Opera binary is configured, since AI sign-in needs a
  window; headless machines keep the old default

Caller contract:
- exit codes distinguish bad arguments, environment, auth, timeout and
  stale page state; new AUTH_REQUIRED code
- add login; doctor gains --fix and MCP/profile/browser checks
- logs gains --follow and --errors

Plan and rationale in specs/robustness-hardening.md.
Detect a wedged bridged (up but pointed at a dead browser) by probing the
attach URL on /health, so findUsableBridge stops reusing it and the next
command rebuilds against the current target. open now fails loudly (exit 3)
instead of faking success. Condense SKILL.md and keep the ask-the-user rule.
@macieju-opera
macieju-opera merged commit 08cfe57 into main Aug 19, 2026
2 checks passed
@macieju-opera
macieju-opera deleted the harden-cli-reliability branch August 19, 2026 10:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant