fix(browser): R3 — restore fs cat root, daemon lane capture, grep hyphen guard
Address @yuh-yang's three R3 blockers on PR #308. All three land in this PR;
the grep parser issue (blocker 3) takes Path B — Python-side rejection with
a clear error message — while the real parseArgs `--` work goes upstream to
a future DOMShell release.
1. fs cat at root no longer raises Python ValueError before reaching
DOMShell. The absolute-root guard added in round 5 was overreaching —
it converted DOMShell's standard "Usage: cat <name>" error into a
Python exception. Guard removed; cat '' now reaches the kernel and
surfaces DOMShell's own error string, restoring pre-migration
behavior. Stale "should raise" tests flipped to "should not raise +
return parseable error result".
2. Daemon-mode/no-session lane handling is now consistent across daemon-
alive and daemon-dead paths. The previous "shared" branch (commit
99d1182) claimed per-connection-default stickiness that doesn't hold
when _daemon_session is None and each call spawns a fresh
ClientSession. Replaced with a module-level _daemon_lane_id captured
on the first daemon-no-session call and reused on every subsequent
call. Works in both paths: alive daemon reuses the id on its
persistent connection; dead daemon's fresh spawns swapToAgentLane()
into the existing Chrome tab-group by id (groups persist across
MCP session boundaries). Stale-lane failure mode (user closes the
group manually) propagates DOMShell's own error — same shape as the
session-bearing path. Replaces the previous-round "shared" test
with first-call-captures + subsequent-calls-reuse tests.
3. Hyphen-prefixed grep patterns now raise a clear Python-side
ValueError instead of silently failing at DOMShell. The current
DOMShell parseArgs treats any arg starting with "-" as a flag —
no "--" separator, no -e <pattern> form — so `grep -r -- -foo`
and `grep -r -e -foo` both fail at the kernel. Tracked upstream as
a parser-limitation issue; the real fix ships with the next
DOMShell release that already justifies a Chrome Web Store
submission. Until then, the wrapper rejects the input with
guidance instead of letting it silently fall through.
191 passing locally (was 189 + 4 new tests - 1 deleted shared-lane test -
1 old cat-root test replaced).
Cc @yuh-yang
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> A
apireno committed
57906517ab51052413e6780e42925ab87270c471
Parent: b684732