feat(peek): in-page action feedback — visual cue when peek acts#90
Conversation
…ctor Signed-off-by: harry-harish <22562634+harry-harish@users.noreply.github.com>
Signed-off-by: harry-harish <22562634+harry-harish@users.noreply.github.com>
Signed-off-by: harry-harish <22562634+harry-harish@users.noreply.github.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: harry-harish <22562634+harry-harish@users.noreply.github.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: harry-harish <22562634+harry-harish@users.noreply.github.com>
Before peek mutates an element (click / type / dblclick / enter), call
bringIntoView() — a nested helper inlined inside dispatchAction so it
survives MAIN-world executeScript serialisation. Only scrolls when the
target is not already fully visible in the viewport; no-ops for on-screen
elements to avoid gratuitous re-centering on every action.
Also aligns the explicit `scroll` verb to use the same
{ block: 'center', inline: 'nearest' } options for consistency.
Adds 3 new dispatcher tests (42 total); full-suite 554/554 green.
Signed-off-by: harry-harish <22562634+harry-harish@users.noreply.github.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: harry-harish <22562634+harry-harish@users.noreply.github.com>
Signed-off-by: harry-harish <22562634+harry-harish@users.noreply.github.com>
Signed-off-by: harry-harish <22562634+harry-harish@users.noreply.github.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughIntroduces in-page visual action feedback (element ripple/ring and page-level toast) injected via ChangesIn-Page Action Feedback
Sequence Diagram(s)sequenceDiagram
participant BackgroundWorker
participant dispatchInMainWorld
participant emitActionFeedback
participant getShowActionFeedback
participant scheduleActionToast
participant chrome.scripting
BackgroundWorker->>dispatchInMainWorld: execute action
dispatchInMainWorld->>dispatchInMainWorld: await MAIN-world dispatch → finalResult
dispatchInMainWorld->>emitActionFeedback: fire-and-forget (action, tabId)
emitActionFeedback->>getShowActionFeedback: read chrome.storage.sync
alt feedback disabled
emitActionFeedback-->>emitActionFeedback: return
else element verb (click/type/dblclick/enter/scroll)
emitActionFeedback->>chrome.scripting: executeScript(showElementFeedback, args)
else page verb (navigate/reload/back/forward)
emitActionFeedback->>scheduleActionToast: schedule(tabId, plan)
scheduleActionToast->>scheduleActionToast: wait for tab.status === complete
scheduleActionToast->>chrome.scripting: executeScript(showPageToast, args)
end
dispatchInMainWorld-->>BackgroundWorker: return finalResult
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
harish-captain
left a comment
There was a problem hiding this comment.
Approving.
- CI green:
ci,ci-windows,dco,e2e-peek,e2e-wdioall pass. - CodeRabbit: approved, no actionable comments.
- Full unit suite (554) + e2e green; adversarial whole-feature review found no correctness/security issues.
- Closed-shadow cues confirmed rrweb-invisible; egress-safe (geometry only); fire-and-forget (never blocks the act).
Non-blocking: CodeRabbit docstring-coverage advisory (76.47% vs 80%). Branch is BEHIND main — Update branch before merge.
Exercises showElementFeedback/showPageToast in real Chromium (closed shadow root, display:contents host, real-timer self-removal, missing-target no-op) — the invariants jsdom can't observe. Converts the plan's deferred e2e item into a CI regression guard. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: harry-harish <22562634+harry-harish@users.noreply.github.com>
harish-captain
left a comment
There was a problem hiding this comment.
Re-approving on 4e960e4 (added the real-browser Playwright e2e for the closed-shadow cues).
- All CI green on this commit:
ci,ci-windows,dco,e2e-peek(now runs the newaction-feedback.spec.ts— closed-shadow render, display:contents host, real-timer self-removal),e2e-wdio. - CodeRabbit re-reviewed: no actionable comments.
- Verified working in real Chromium before merge.
Branch is BEHIND main — Update branch before merge.
Summary
Closes a UX gap in peek's act write-path: when
execute_actionmutates a page (fill/click/etc.), there was no on-page indication — and at Level 4 (auto-allow) not even a confirm banner, so actions landed silently. This adds an automatic, transient, per-verb visual cue so a human can see where peek acted and what it did.type/fill → green ring;click→ indigo ripple;enter→ amber ripple;dblclick→ double ripple;scroll→element → ring + pulse;navigate/reload/back/forward→ corner toast on the destination page.data-peek-fxhost is inRECORDER_BLOCK_SELECTOR, so cues never appear in recordings and leave no placeholder box.Show action feedbackside-panel toggle (peek:showActionFeedback); honorsprefers-reduced-motion(static cue) and@media print.No new MCP tool, no
action-schema/permission change. Extension isprivate:true→ no changeset.How it works
dispatchInMainWorld(SW) injectsdispatchAction(now withbringIntoView) into the page MAIN world, returns the result to the agent, then firesemitActionFeedback:getShowActionFeedback()gate →elementFeedbackFor/pageToastFordecision → injectsshowElementFeedback/ (post-load)showPageToast(src/permissions/action-feedback.ts). Mirrors the existinghighlight.ts/shield/view.tsclosed-shadow idiom.9 commits, built via subagent-driven TDD (each: implement → spec review → code-quality review). Design + plan:
rrweb-stack-private/docs/specs/2026-06-16-peek-action-feedback-{design,plan}.md.Test plan
pnpm --filter @peekdev/extension test— 554 tests green (incl. closed-shadow construction, per-verb nodes, egress invariant, self-removal, MAIN-world serialization boundary, scroll-in gating, decision helpers)tsc --noEmitclean;wxt build+assert:recorder-iifepasstype/click/navigateat Level 3/4 → confirm cue appears, scrolls off-screen targets into view, fades; confirm cues are absent from the recorded replay (no placeholder box); toggle off → no cue; reduced-motion → static cue.Notes
suggesthighlight (.__peek_highlight__, light-DOM) to a closed-shadow host. The design suggested also adding it toRECORDER_BLOCK_SELECTOR, but blocking a visible element leaves a frozen placeholder box on replay — so its proper fix (closed-shadow migration) is deferred; the new action-feedback cues are fully invisible. Also deferred: automated Playwright e2e for the visual + capture-absence, real click coordinates.c818aab;origin/mainhas since advanced (Windows hardening), andbackground.tschanged on both sides — may need a rebase to resolvebackground.ts(Windows guards + feedback wiring should coexist).🤖 Generated with Claude Code
Summary by CodeRabbit
Release Notes