Skip to content

feat(extension): optional visible agent cursor - #27

Merged
compnew2006 merged 4 commits into
mainfrom
claude/clever-ritchie-i1dhcb
Oct 9, 2026
Merged

compnew2006 merged 4 commits into
mainfrom
claude/clever-ritchie-i1dhcb

Conversation

@compnew2006

Copy link
Copy Markdown
Owner

What

An optional on-page cursor that shows where the agent's mouse goes. Switch it on in the popup → Settings → Show agent cursor (first item). It is off by default.

When it is on:

  • A blue pointer glides to the target before the input lands.
  • A ripple marks each click (one ring per click for double and triple clicks).
  • The arrow presses in while dragging.
  • Hover and wheel-at-point move the cursor too.
  • It covers browser_click, browser_hover, browser_scroll (x/y), browser_drag, browser_click_text, the click fallback of browser_type, and browser_act click/hover.

Why it is opt-in

The glide holds each mouse action ~200–350 ms on a visible tab. With the switch off, every pointer action runs exactly as before: no cursor page work, no wait, no extra measurement. Hidden tabs and prefers-reduced-motion never wait.

Safety details

  • Click accuracy: after the glide the target is measured again before clicking, so a layout shift can't make the click miss. A target that disappears during the glide is reported, not clicked.
  • Cosmetic only: pointer-events:none, isolated from page CSS with all:initial, never throws, and stays above the agent-control frame.
  • Screenshots: hidden from the agent's own screenshots. The hide is bounded and skipped on frozen tabs.
  • Already-open tabs: a page still holding the older page runtime (no cursor) gets it reinstalled.
  • Popup layout: the Settings panel now scrolls in a short popup.

Verification

  • npm run lint passes.
  • vitest: 452 tests pass, 6 of them new. The coverage gate passes.
  • Real Chromium with the unpacked extension:
    • Clicks, double clicks, hover, wheel, drag and browser_act land exactly as before, including on a page with CSS that targets svg, path and div.
    • The popup switch: off by default, on takes effect on the next action, the setting is remembered, and off restores the original speed.

🤖 Generated with Claude Code

https://claude.ai/code/session_018sCpqZejX6CYitZhwAf2BB


Generated by Claude Code

claude added 4 commits October 9, 2026 15:12
… drags

A person watching a tab could not see where the agent's real (CDP) mouse
input landed. Every pointer action now draws a blue arrow that glides to
its target before the input fires, ripples on each click (one ring per
click for double/triple-click), and presses in while dragging.

- page-dom.js: cursor renderer in the shared page runtime (v2). Purely
  cosmetic: pointer-events:none, isolated from page CSS, never throws,
  stays above the control frame, fades after 4 s idle. Returns the glide
  duration; 0 in hidden tabs or with reduced motion (no added delay).
- trusted-input.js: locatePointer glides, waits, then measures the
  target again so a layout shift during the animation can't make the
  click miss (a target gone meanwhile is reported, not clicked).
  pointInfo waits for the glide before x/y input.
- drag: the cursor presses at the start and its glide to the end is
  paced by the clock with the real mouse moves.
- screenshots hide the cursor (bounded, skipped on frozen tabs) so it
  never covers what the agent is looking at.

Verified in real Chromium with the unpacked extension: clicks, double
clicks, hover, wheel and drag still land as trusted events, including on
a page whose CSS targets svg/path/div.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018sCpqZejX6CYitZhwAf2BB
The cursor's glide holds every mouse action ~200–350 ms on a visible tab,
so it is now off by default and switched on from the popup (Settings →
"Show agent cursor"). Off, every pointer action runs exactly as before:
no cursor page work, no wait, no second measurement, no screenshot
hide/restore.

- overlay.js: agentCursorEnabled() reads chrome.storage.local
  "agentCursor" per action, so the switch applies to the next action.
- trusted-input.js / tabs.js: locatePointer, pointInfo, cursorTo and the
  screenshot hide are gated on it.
- popup: a switch row in Settings, persisted in chrome.storage.local.

Verified in real Chromium with the unpacked extension and its popup:
off by default (clicks ~15–25 ms, no cursor), switching on takes effect
on the next click, the popup remembers it, switching off restores the
original speed; every click landed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018sCpqZejX6CYitZhwAf2BB
…open tabs

With the switch on, the cursor still never appeared in two common cases:

- browser_act (the Observe → Act loop the tool guidance recommends)
  dispatches its click/hover inside the page and never reached the
  cursor code. handleAct now makes sure the shared page runtime is
  current and PAGE_ACT_V2 glides the cursor to the target's centre
  before dispatching (the events go to the element itself, so only a
  target that detaches during the glide is refused, with STALE_STATE).
- Page functions only checked that a runtime existed, so a page still
  holding the pre-cursor runtime never got one. A cursor request now
  asks for a reinstall when the runtime lacks it.

Reproduced both in real Chromium against the previous commit (switch
on, no cursor) and verified the fix (cursor shown, all clicks land).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018sCpqZejX6CYitZhwAf2BB
The Settings panel did not scroll, so in a popup resized below ~420 px
(the size is remembered) the new switch, last in the panel, was cut off
with no way to reach it. It now sits first in Settings, and the panel
scrolls when its fields don't fit (verified at the 380 px minimum).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018sCpqZejX6CYitZhwAf2BB
@compnew2006
compnew2006 merged commit b423801 into main Oct 9, 2026
2 of 4 checks passed
@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 Oct 9, 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: e45132bf-a702-4f6c-ae73-36cfa187d974

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

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.

2 participants