Skip to content

feat: v2.3.0 — trusted CDP input, browser_batch, REPL evaluate, CDP screenshots - #18

Merged
compnew2006 merged 8 commits into
mainfrom
feat/cic-parity
Sep 29, 2026
Merged

compnew2006 merged 8 commits into
mainfrom
feat/cic-parity

Conversation

@compnew2006

Copy link
Copy Markdown
Owner

Summary

Brings Browser Controller to parity with Claude in Chrome on hard legacy UIs (tested on an ASP.NET ERP journal-voucher grid). Version 2.3.0; includes the 2.2.1 navigate back/forward fix.

Trusted input (click / type / press_key / hover)

  • Real isTrusted mouse/key events over CDP instead of synthetic dispatchEvent: focus really moves, default actions run (Tab traversal, Enter submit, autocomplete menus), focus/blur fire even in background windows (Emulation.setFocusEmulationEnabled).
  • One shared debugger session per tab (lib/cdp-session.js), idle-detached after 30s; run_action/upload/dialog/drag reuse it (no more "already attached").
  • Never-shown background tabs have a 0×0 viewport → sized to their window.
  • Lock shield lets the agent's own trusted input through for a short window.
  • press_key accepts "ctrl+a" combos; type returns the field value; punctuation carries real key codes (numeric masks dropped .).
  • trusted:false opts out; synthetic events remain the automatic fallback.

browser_batch

  • Up to 200 tool calls in one round-trip, in order, stops at the first failure (continueOnError optional).
  • output: "last" | "errors" keeps long batches cheap; pure delays run locally; steps rejected by the daemon rate limit are waited out and resent.

browser_evaluate

  • CDP Runtime.evaluate in REPL mode: top-level await, last expression returned, not blocked by CSP, DOM nodes/cycles serialized readably, timeout up to 120s. mode:"scripting" keeps the banner-free path.

browser_screenshot

  • CDP capture with scale / maxWidth / fullPage; the agent's blue frame is never in the picture; hidden tabs (which Chrome doesn't paint) are shown for a moment and the user's tab restored.

Results (26-line journal voucher, not saved)

v2.2 Claude in Chrome v2.3
agent tool calls ~63 11 ~5 (clean run)
hand-fired page events every field none (JS value setting) none — real typing

Test plan

  • npm test: all new suites pass (trusted-input, cdp-evaluate, screenshot-cdp, batch). Pre-existing daemon IPC suites fail the same way on main on Windows while a live daemon owns the named pipe.
  • Live on Windows / Chrome: event log page (trusted focus/blur/change/submit in a background tab, under lock), REPL evaluate cases, screenshots, and the full ERP voucher entry matching 26/26 lines.

🤖 Generated with Claude Code

noiemany and others added 8 commits September 29, 2026 17:59
Synthetic DOM events are isTrusted:false, never move real focus, skip
default actions (Tab traversal, Enter submit) and never fire focus/blur
while the window is in the background, which broke legacy grids and
lookup widgets. The write tools now drive the page over CDP like a user:

- lib/cdp-session.js: one debugger session per tab, reused and detached
  after 30s idle; enables focus emulation and sizes never-shown
  background tabs (0x0 viewport) to their window.
- lib/trusted-input.js: locate in page (iframe offsets, occlusion hint),
  real mouse/key events, key definitions, per-key typing.
- click/type/press_key/hover use it by default (`trusted:false` opts
  out) and fall back to synthetic events when CDP can't attach.
- press_key accepts "ctrl+a" combos; type returns the field value.
- Lock shield lets the agent's own trusted input through for a short
  window; run_action/upload/dialog/drag share the tab session instead of
  attaching their own (which collided with "already attached").

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Steps run in order in the MCP process, each validated and executed
exactly like a standalone call (same schemas, timeouts, error payloads).
Stops at the first failing step unless continueOnError; a top-level
tabId is applied to steps that don't set one. Nested batches and the
meta tool are rejected. Guidance/preamble updated for trusted input.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…alue)

browser_evaluate now runs Runtime.evaluate in replMode through the tab's
shared debugger session: top-level await, statement lists whose last
expression is the result, let/const redeclaration across calls, not
blocked by page CSP. Objects are serialized page-side (DOM nodes as
readable descriptions, cycles/functions/bigint/Map/Set handled) instead
of coming back as {}. New `timeout` (default 30s, max 120s) races awaited
promises; `mode:"scripting"` keeps the banner-free chrome.scripting path,
which is also the fallback when the debugger can't attach. Sessions are
no longer idle-detached while a long withCdp() call is running.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ift guard

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
browser_screenshot now uses Page.captureScreenshot through the tab's
shared debugger session:
- scale / maxWidth / jpeg quality shrink the image (fewer tokens);
- fullPage captures the whole scrollable content;
- the agent's blue control frame is hidden for every capture (it is
  shown during every action, not only while locked, and used to end up
  in the picture);
- a background tab doesn't paint (captureScreenshot hangs, also with
  fromSurface:false), so it is shown for a moment, captured over CDP and
  the user's tab is switched straight back;
- captureVisibleTab remains the fallback, reporting why (cdpFallback).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ch, REPL evaluate, CDP screenshots

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Typing 3036.65 into a masked amount field produced 303665: the "." key
press carried keyCode 0 and the mask plugin dropped it. Printable
punctuation now sends its US-layout code and Windows virtual key code.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…retry

Found entering a 26-line journal voucher (16 steps per line):
- the 50-step cap split the job into many calls: raised to 200;
- echoing every step's result wasted tokens: output "last" / "errors";
- a pure browser_wait delay now sleeps in the MCP process instead of
  costing a daemon call;
- the daemon's 120 calls/min per-session limit stopped long batches: a
  rejected step never ran, so the batch waits out the window and resends.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@qodo-code-review

Copy link
Copy Markdown

ⓘ Qodo reviews are paused because the subscription is no longer active. Ask your workspace admin to reactivate the subscription to resume reviews. Manage billing

@coderabbitai

coderabbitai Bot commented Sep 29, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Advanced

Run ID: ddd4d6a4-b58d-4747-9c60-e8202c400a18


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@compnew2006
compnew2006 merged commit 9787b77 into main Sep 29, 2026
4 of 6 checks passed
@compnew2006
compnew2006 deleted the feat/cic-parity branch September 29, 2026 22:24
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