fix(browser): isolate timed-out snippets
Problem
browser_execute runs snippets in-process. Timing out the Effect fiber does not preempt the JavaScript Promise, so abandoned code could reconnect and send CDP commands after the caller received a timeout. Same-session tool calls may also execute concurrently.
Change
- Permanently invalidate the exact Session object used by a timed-out snippet and remove it by identity from
SessionStore. - Reject pending/future transport work, close active and connecting sockets, and stop profile polling promptly on invalidation.
- Serialize
browser_executeper session ID so a timeout cannot invalidate a healthy concurrent call; queued calls resolve the fresh Session after acquiring the lock. - Count queue wait against the configured timeout. A waiter that expires runs no code and does not invalidate the active Session.
- Return recent console progress in the timeout error, capped to 8 KiB of valid UTF-8 with a truncation marker.
- Stop console capture and
onChunkupdates after timeout. - Document the 60s default, 600s maximum, top-level timeout, and small logged batches in one guardrail.
Reproduction
Synthetic CDP tests cover a timed-out snippet that sleeps and later attempts Runtime.evaluate. The server receives no late command. A concurrently queued call then receives a fresh Session, reconnects, and executes successfully.
A separate queue-boundary test puts a 10ms call behind a 50ms same-session call. The queued call expires without running its snippet or invalidating the active Session; the first and a later call both complete normally. Additional tests cover pending waiters, connecting sockets, prompt cancellation of profile polling, UTF-8 byte capping, and stopped post-timeout capture.
Validation
- Focused
browser-execute.test.ts: 8 pass, 6 environment-gated skips - Full
packages/bcode-browsersuite: 27 pass, 8 environment-gated skips - Package typecheck passed
- Pre-push filtered typecheck: 13/13 packages passed
git diff --checkpassed
This PR is stacked on #112 (session-recovery).