Skip to content

[feat] Make the playground's keyboard shortcuts discoverable - #6373

Merged
mmabrouk merged 12 commits into
release/v0.114.4from
feat/playground-shortcut-hints
Aug 31, 2026
Merged

[feat] Make the playground's keyboard shortcuts discoverable#6373
mmabrouk merged 12 commits into
release/v0.114.4from
feat/playground-shortcut-hints

Conversation

@mmabrouk

@mmabrouk mmabrouk commented Aug 29, 2026

Copy link
Copy Markdown
Member

Context

The agent playground binds 43 keyboard shortcuts across six files. Six of them name a key on screen. The rest were unreachable unless you read the source, and eleven of them answer no control at all, so no amount of tooltips could ever surface them. Alt+1…9 and the Alt+Z / Alt+X pair switch sessions, and there is no button anywhere to hang a hint on.

Two of the nine Alt letters also sat on keys the browser claims. Alt+F opens the menu in Chrome and Edge and the File menu in Firefox, and Alt+B opens Firefox's Bookmarks menu. Search and the configuration panel were unreliable on Windows and Linux.

Changes

One registry owns every binding. web/packages/agenta-shared/src/utils/shortcuts.ts holds all 45 entries with their keys, labels and conditions. Tooltips, keycaps, the sheet and every aria-keyshortcuts value read from it, so a label cannot drift away from the handler.

Keys appear on the control that already does the job. The approval card's Approve and Deny buttons carry keycaps. Both side panel carets name their key in the tooltip: the » that shows the configuration and the « that shows the files pane.

A shortcuts sheet covers the rest. It opens on ? and from a keyboard button at the right edge of the playground top bar. The hotkey matches the produced character, so it works where ? is Shift+ß or Shift+comma, and it is ignored while the caret is in any text field.

Three Alt letters moved, and one shortcut is new.

Action Was Now Why
Search sessions Alt+F Alt+K Alt+F opens the browser menu. K is the search key across the industry.
Configuration panel Alt+B Alt+C Alt+B opens Firefox's Bookmarks menu. C reads as Configuration.
New session Alt+C Alt+N N reads as New, and it frees C for the panel above.
Files pane none Alt+O It had no shortcut at all.

A unit test now fails if any browser menu letter is ever bound again. docs/design/playground-shortcut-discoverability/decisions.md records why each letter is what it is, so the next person does not undo it.

A bug this PR would otherwise have shipped. Radix's dismissable layer cancels Escape in the capture phase but never stops it propagating, and it does not touch Cmd/Ctrl+Enter at all. Adding a dialog the product tells you to open at any time made that reachable:

  • Park a tool call. Press ?, then Escape to close the sheet. The gate was denied, silently.
  • Press Cmd/Ctrl+Enter with the sheet open. The gate was approved, unseen.
  • Open the top bar's settings menu with a gate parked and press Escape. The gate was denied.

isOverlayOpen() now has one home in @agenta/shared instead of two copies, and the approval card, connection dock and recording bar all guard on event.defaultPrevented || isOverlayOpen(). Both halves earn their place: Radix cancels the key for a menu the overlay check cannot see, and an antd modal cancels nothing.

The last case was already broken before this branch. The dropdown and the approval card have coexisted for a while.

Tests

  • ApprovalCard.test.tsx (11): two new cases cover the overlay leak. I removed each half of the guard in turn and confirmed that its test, and only its test, failed.
  • shortcuts.test.ts (13, new): the registry has unique ids, every entry sits in a titled group, and every aria-keyshortcuts value uses only ARIA modifier names.
  • useSessionShortcuts.test.ts (22): includes the new "binds no letter a browser menu already claims".
  • Suite totals: @agenta/shared 440, @agenta/chat 568, web/oss AgentChatSlice 287. Type-checks and package lints clean.
  • Storybook builds clean. All eight stories render in light and dark with no page errors.
  • Verified on the live EE dev stack in Chrome: the button is the last control in the top bar, ? opens the sheet from the page and stays shut in the composer, the sheet is three columns with no scrollbar on a 15 inch screen, and Alt+C collapses and restores the configuration panel.

Scope and risk

Not touched: the composer's own Enter behaviour, the elicitation dock's key handling, the push-to-talk chord, and every Cmd/Ctrl+Enter binding. The registry documents them; none of their code changed.

Worth a reviewer's eye:

  • isOverlayOpen() moved from the app layer into @agenta/shared. Six callers now import it. The workflow revision drawer is antd's Drawer, which renders role="dialog" with no data-state, so the guard deliberately does not fire there. That is why the Alt shortcuts still work inside that drawer, and it must stay that way.
  • AgentChatPanel.tsx moves the useSessionFilesPane call above useSessionShortcuts, because the new files-pane toggle needs it. Hook order changed; nothing is conditional.
  • The keycaps changed the approval buttons' text content. They are aria-hidden and the buttons carry aria-keyshortcuts, so the accessible names stay "Approve" and "Deny". Two existing tests that matched the button text exactly now match by prefix.

Still open, and not verifiable from a Linux box: on Linux a window manager can claim an Alt chord before the browser sees it. Pressing the ten Alt chords once on a Linux desktop and once on Windows would close that out.

What to QA

  • Open any agent playground. The keyboard icon is the last control in the top bar. Hover it: the tooltip shows ?.
  • Press ? with the page focused. The sheet opens, three columns, no scrollbar on a normal laptop screen.
  • Click into the composer and type a question mark. It types a ?; the sheet does not open.
  • Press Alt+C. The configuration panel collapses. Press it again; it comes back. Hover the » caret: the tooltip names Alt+C.
  • Press Alt+O. The files pane opens and closes. Hover the « caret: the tooltip names Alt+O.
  • Press Alt+K. The session search box takes focus. Press Alt+N for a new session, then Alt+Z and Alt+X to step between sessions.
  • The regression to watch: ask the agent to do something that needs approval. With the gate waiting, press ? and then Escape. The sheet must close and the gate must stay open. Then open the settings menu in the top bar and press Escape. Same: the menu closes, the gate stays.
  • Then answer the gate from the keyboard. Cmd/Ctrl+Enter approves, Escape denies.

https://claude.ai/code/session_01TqiMMWEa63QRi6XqEXwwUi

Closes #6391

…heet

The playground binds 41 keyboard shortcuts across six files. Seven of them
name a key on screen. Nothing else does, so the rest are unreachable unless
you read the source.

Add one registry in @agenta/shared that owns every binding's keys and label,
a ShortcutKeys component that prints them the way the reader's own keyboard
is labelled, and a KeyboardShortcutsSheet on '?' for the eleven bindings that
answer no control. Give ApprovalCard a shortcutHints prop so the three ways
to show approve and deny can be compared side by side in Storybook.

No handler changes. Every key printed here is one the code already binds.
…el and help shortcuts

Chrome and Edge open their menu on Alt+F, Firefox opens a menu on
Alt+F/E/V/S/B/T/H, and both focus the address bar on Alt+D. Two of the
playground's nine Alt letters sat on those keys, so search and the config
panel were unreliable on Windows and Linux.

Search moves from Alt+F to Alt+K, the config panel from Alt+B to Alt+C, and
new session from Alt+C to Alt+N so C reads as Configuration. The files pane
gains Alt+O, which it never had. A test now fails if any browser menu letter
is ever bound again.

Both panel carets name their key in the tooltip. A keyboard button in the
session bar opens the shortcuts sheet, and owns the ? hotkey, which is
ignored while the caret is in a text field. The approval card keeps its
keycaps on the buttons; the other two variants are gone.
Radix's dismissable layer cancels Escape in the capture phase but never stops
it propagating, and it does not touch Cmd/Ctrl+Enter at all. Adding a dialog
the product tells you to open at any time made that reachable: closing the
shortcuts sheet with Escape also denied a parked tool call, and Cmd+Enter
approved one the user could not see. Opening the top bar's settings menu and
pressing Escape denied a gate the same way.

isOverlayOpen now has one home in @agenta/shared instead of two copies, and
the approval card, connection dock and recording bar all guard on
'event.defaultPrevented || isOverlayOpen()'. Both halves are load-bearing:
Radix cancels the key for a menu the overlay check cannot see, and an antd
modal cancels nothing. Two regression tests cover the two halves.

Also in this pass: the shortcuts button moves to the right edge of the
playground top bar, the sheet widens to three columns so the full list fits a
15 inch screen without scrolling, aria-keyshortcuts on every shortcut-bearing
button is computed from the registry rather than hand-written, the / menu and
the permission picker become separate groups because they bind different keys,
and docs/design/playground-shortcut-discoverability records why each Alt letter
is what it is.
Every other story title in web/storybook is namespaced by the package that
owns the component, and the file name matches the title's last segment. These
two were not: one was titled Playground/Keyboard shortcuts and the other sat
outside the Presentational sub-folders.

They are now @agenta/ui/Domain/KeyboardShortcuts and
@agenta/ui/Presentational/Labels/ShortcutKeys, the domain file is renamed to
match, both metas name their component and set layout padded, and both carry
the 'Used in' note and the per-story doc comments the neighbouring stories use.

Also records in status.md what was verified, including the live pass on the
dev stack.
@dosubot dosubot Bot added the size:XXL This PR changes 1000+ lines, ignoring generated files. label Aug 29, 2026
@vercel

vercel Bot commented Aug 29, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
agenta-documentation Ready Ready Preview Aug 30, 2026 12:40pm

Request Review

@dosubot dosubot Bot added enhancement New feature or request frontend ux labels Aug 29, 2026
@github-actions

github-actions Bot commented Aug 29, 2026

Copy link
Copy Markdown
Contributor

📘 Docs preview

Status ✅ Ready
Preview https://pr-6373-agenta-docs-preview.mahmoud-637.workers.dev/docs
Inspect Actions run
Commit e8b30ff46d3a8d524f1d9e6f23abf76c40128ca2

This comment updates in place on every push.

@coderabbitai

coderabbitai Bot commented Aug 29, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Summary by CodeRabbit

  • New Features
    • Added a keyboard shortcuts help button and grouped shortcuts sheet, accessible with ?.
    • Displayed shortcut keycaps, tooltips, and accessibility metadata on relevant playground controls.
    • Added a files-panel shortcut and updated session and panel key bindings.
    • Added shortcut indicators to approval actions and stream controls.
  • Bug Fixes
    • Prevented keyboard actions from triggering while dialogs, menus, or popovers control focus.
    • Avoided conflicts with browser-reserved shortcuts on Windows and Linux.
  • Documentation
    • Added design, research, decision, planning, and status documentation for shortcut discoverability.

Walkthrough

The change centralizes playground shortcuts, adds platform-aware keycaps and a shortcuts sheet, exposes shortcuts on controls, updates session bindings, prevents overlay keystroke leakage, and adds tests, Storybook stories, and design documentation.

Changes

Playground shortcut discoverability

Layer / File(s) Summary
Shortcut registry and shared utilities
web/packages/agenta-shared/src/utils/*, web/packages/agenta-shared/tests/unit/shortcuts.test.ts
Defines shortcut metadata, grouping, platform formatting, ARIA output, lookup helpers, and shared overlay detection.
Shortcut keycaps and help sheet
web/packages/agenta-ui/src/shortcuts/*, web/packages/agenta-ui/package.json
Adds reusable keycaps, the grouped shortcuts sheet, the ? hotkey, and the help button.
Shortcut placement and files-pane wiring
web/oss/src/components/AgentChatSlice/*, web/oss/src/components/Playground/*, web/packages/agenta-chat/src/components/ApprovalCard.tsx, web/packages/agenta-entity-ui/src/drive/DriveHeader.tsx, web/packages/agenta-sessions-ui/src/SessionTabStrip.tsx, web/packages/agenta-ui/src/RichChatInput/plugins/SendButton.tsx
Adds shortcut metadata to controls, places the help button in the playground header, displays approval keycaps, and wires Alt+O to the files pane.
Binding changes and overlay-safe handlers
web/oss/src/components/AgentChatSlice/hooks/*, web/packages/agenta-chat/src/components/{ConnectionDock,RecordingBar}.tsx, web/packages/agenta-chat/src/hooks/usePushToTalk.ts, related tests
Moves session bindings to Alt+N, Alt+K, Alt+C, and Alt+O. Keyboard handlers now ignore prevented events and open overlays. Tests cover the new bindings and guards.
Documentation and Storybook validation
docs/design/playground-shortcut-discoverability/*, web/storybook/stories/*, web/storybook/package.json
Adds design records and Storybook stories for the registry, keycap variants, approval controls, shortcut placements, and the shortcuts sheet.

Estimated code review effort: 4 (Complex) | ~45 minutes

Merge Risk: 🟡 Moderate · up to 2a4d6

The PR adds discoverable global shortcuts and changes several bindings, but a remaining keyboard-ownership gap can let Cmd/Ctrl+Enter approve a pending action while a menu or unsupported overlay is open. Smaller shortcut-display, empty-session, documentation, and accessibility inconsistencies also remain, so merge should wait for these issues to be fixed or explicitly accepted.

Sequence Diagram(s)

sequenceDiagram
  participant PlaygroundHeader
  participant ShortcutsHelpButton
  participant KeyboardShortcutsSheet
  participant shortcutGroups
  participant ShortcutKeys

  PlaygroundHeader->>ShortcutsHelpButton: Render help button
  ShortcutsHelpButton->>KeyboardShortcutsSheet: Open sheet
  KeyboardShortcutsSheet->>shortcutGroups: Read grouped registry entries
  shortcutGroups-->>KeyboardShortcutsSheet: Return shortcut metadata
  KeyboardShortcutsSheet->>ShortcutKeys: Render platform-specific keycaps
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 60.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 4 functions across 28 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description check ✅ Passed The description directly explains the shortcut registry, discoverability changes, browser-menu fixes, overlay handling, tests, scope, and QA steps.
Linked Issues check ✅ Passed The pull request description links the change to issue #6391 with Closes #6391``.
Out of Scope Changes check ✅ Passed The listed changes stay within shortcut discoverability, shortcut safety, accessibility, overlay handling, tests, Storybook coverage, and related documentation. The description also identifies exclude…
Title check ✅ Passed The title clearly and concisely describes the main change: making the playground's keyboard shortcuts discoverable.
Full details: Out of Scope Changes check

Explanation

The listed changes stay within shortcut discoverability, shortcut safety, accessibility, overlay handling, tests, Storybook coverage, and related documentation. The description also identifies excluded areas.

  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/playground-shortcut-hints

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.

The Placements story rendered a tooltip row and a session tab menu key column
that are not in this change. Anyone judging the proposal by eye would have read
four shipped placements where there are two, which is the opposite of what a
story is for. Both frames are cut and the story is renamed PanelTooltips after
what it actually shows. The follow-up placements stay listed in status.md.

Adds a Decorative story for the new aria-hidden prop. Inside a button the label
already names the action, so the caps are hidden and the key travels as
aria-keyshortcuts; in the sheet the caps are the content and stay announced.
Neither state is reachable by clicking, which is the bar web/AGENTS.md sets for
a story.

Completes both metas against the house pattern in CellRenderers.stories.tsx:
component plus subcomponents, and the Used in note.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (1)
web/oss/src/components/AgentChatSlice/AgentChatPanel.tsx (1)

247-249: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Apply the one-line comment rule to all changed source comments.

Split each block into short one-line comments or reduce it to one line.

  • web/oss/src/components/AgentChatSlice/AgentChatPanel.tsx#L247-L249: shorten the Files pane comment.
  • web/packages/agenta-chat/src/components/ApprovalCard.tsx#L134-L135: shorten the keycap comment.
  • web/packages/agenta-chat/src/components/ApprovalCard.tsx#L160-L162: shorten the overlay comment.
  • web/packages/agenta-chat/src/components/ConnectionDock.tsx#L503-L505: shorten the overlay comment.
  • web/packages/agenta-chat/src/components/RecordingBar.tsx#L57-L59: shorten the overlay comment.
  • web/oss/src/components/AgentChatSlice/hooks/useSessionShortcuts.ts#L48-L61: shorten the shortcut documentation block.

As per coding guidelines, Hard rule. At most ONE short line per comment.

Source: Coding guidelines


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 46f0e2ef-e3a1-4beb-86c5-6d5dfd879609

📥 Commits

Reviewing files that changed from the base of the PR and between 4b474bf and b40a91b.

⛔ Files ignored due to path filters (1)
  • web/pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (30)
  • docs/design/playground-shortcut-discoverability/README.md
  • docs/design/playground-shortcut-discoverability/context.md
  • docs/design/playground-shortcut-discoverability/decisions.md
  • docs/design/playground-shortcut-discoverability/plan.md
  • docs/design/playground-shortcut-discoverability/research.md
  • docs/design/playground-shortcut-discoverability/status.md
  • web/oss/src/components/AgentChatSlice/AgentChatPanel.tsx
  • web/oss/src/components/AgentChatSlice/AgentConversation.tsx
  • web/oss/src/components/AgentChatSlice/components/OpenFilesPaneButton.tsx
  • web/oss/src/components/AgentChatSlice/components/ShowConfigPanelButton.tsx
  • web/oss/src/components/AgentChatSlice/hooks/useSessionShortcuts.test.ts
  • web/oss/src/components/AgentChatSlice/hooks/useSessionShortcuts.ts
  • web/oss/src/components/Playground/Components/PlaygroundHeader/index.tsx
  • web/packages/agenta-chat/src/components/ApprovalCard.tsx
  • web/packages/agenta-chat/src/components/ConnectionDock.tsx
  • web/packages/agenta-chat/src/components/RecordingBar.tsx
  • web/packages/agenta-chat/src/hooks/usePushToTalk.ts
  • web/packages/agenta-chat/tests/unit/ApprovalCard.test.tsx
  • web/packages/agenta-shared/src/utils/index.ts
  • web/packages/agenta-shared/src/utils/overlay.ts
  • web/packages/agenta-shared/src/utils/shortcuts.ts
  • web/packages/agenta-shared/tests/unit/shortcuts.test.ts
  • web/packages/agenta-ui/package.json
  • web/packages/agenta-ui/src/shortcuts/KeyboardShortcutsSheet.tsx
  • web/packages/agenta-ui/src/shortcuts/ShortcutKeys.tsx
  • web/packages/agenta-ui/src/shortcuts/ShortcutsHelpButton.tsx
  • web/packages/agenta-ui/src/shortcuts/index.ts
  • web/storybook/package.json
  • web/storybook/stories/domain/KeyboardShortcuts.stories.tsx
  • web/storybook/stories/presentational/ShortcutKeys.stories.tsx

Included review availability: Your plan provides up to 8 included reviews per hour; 6 remain after this review.

Comment thread docs/design/playground-shortcut-discoverability/context.md Outdated
Comment thread web/packages/agenta-ui/src/shortcuts/useSessionShortcuts.ts
Comment thread web/packages/agenta-chat/src/components/ApprovalCard.tsx
Comment thread web/packages/agenta-ui/src/shortcuts/ShortcutKeys.tsx Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 180eef91-2d3f-4e38-955c-13619f2cdd60

📥 Commits

Reviewing files that changed from the base of the PR and between b40a91b and 4aef677.

📒 Files selected for processing (2)
  • web/storybook/stories/domain/KeyboardShortcuts.stories.tsx
  • web/storybook/stories/presentational/ShortcutKeys.stories.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • web/storybook/stories/presentational/ShortcutKeys.stories.tsx

Included review availability: Your plan provides up to 8 included reviews per hour; 5 remain after this review.

Comment thread web/storybook/stories/domain/KeyboardShortcuts.stories.tsx
@mmabrouk
mmabrouk marked this pull request as draft August 30, 2026 09:24
@mmabrouk
mmabrouk marked this pull request as ready for review August 30, 2026 09:24
Each side panel has two controls, one to open it and one to close it, and only
the open one named its key. Both panels start open, so the control you see by
default was the one with no hint. Hovering the configuration panel's collapse
caret showed 'Hide configuration' and nothing else, and the files pane's caret
did the same.

Both collapse controls now name their key, so the pair matches whichever way
the panel is sitting. The session tab's right-click menu gains a right-aligned
key column on Rename, Archive and Close. The + button names Alt+N, the session
search box names Alt+K in its placeholder, and the stop button carries Esc as
aria-keyshortcuts.

The key column decorates only the menu this component renders. The shared
menuItems is left alone, because the sessions list page renders the same rows
and none of these keys work there.

Restores the session tab menu to the Placements story. It was cut when it was
only a proposal; it ships now.
Three visual defects, all mine.

The menu key column was not right-aligned. The wrapper span did not grow inside
the menu item's own flex row, so the keycap sat against the label instead of at
the edge. It looked right in Storybook only because that mock built its own row
rather than mirroring the real ContextMenuItem. The mock now copies the real
item's classes, so the two cannot drift apart again.

The sheet's first column started lower than the others. Every group heading
carries a default top margin, which is kept at the top of column one and dropped
at each column break. The heading now sets mt-0.

The sheet hid two whole groups. A multi-column box with a fixed height overflows
sideways into extra columns instead of growing downward, so on a laptop-height
window 'Renaming a session' and 'Help' sat in a fourth column past the right
edge, reachable only by scrolling sideways. The height cap and the scrolling move
to a wrapper, leaving the column box at auto height. My earlier check measured
only the vertical axis, which is why I missed it.

Measured after the fix at 760, 1024, 1440 and 1512 wide: the columns share one
top, nothing sits off screen, and nothing scrolls sideways.
The mobile app renders the same ApprovalCard with touch set, and the keycaps
are gated on that flag. Nobody can reach the state by clicking on a desktop, so
a regression there would ship a keycap to every mobile user before anyone saw
it. The story pins it: zero keycaps on touch, three on desktop.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: b8b8d35d-0e04-45b6-ab78-ca8b8ae7fbfd

📥 Commits

Reviewing files that changed from the base of the PR and between 798770b and 2a4d6da.

📒 Files selected for processing (1)
  • web/storybook/stories/domain/KeyboardShortcuts.stories.tsx

Included review availability: Your plan provides up to 8 included reviews per hour; 7 remain after this review.

Comment thread web/storybook/stories/domain/KeyboardShortcuts.stories.tsx Outdated

@mmabrouk mmabrouk left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review summary

  • Risky: web/oss/src/components/AgentChatSlice/AgentConversation.tsx:450 - pressing Escape to close a Radix menu can also stop the active agent run.
  • Missing tests: the run-level Escape handler has no regression test for an event cancelled during capture and allowed to propagate.

I recommend fixing this before merge. I reviewed head 2a4d6dad2be0ec4f230da3028a34e996d8881e21. The focused shortcut tests passed locally: shared 13, approval card 11, and session shortcuts 22. Shared, chat, and UI type checks passed. Storybook lint passed. A full local Storybook build exceeded the available 4 GB heap.

Comment thread web/oss/src/components/AgentChatSlice/AgentConversation.tsx
Review found that the overlay guard watched only role=dialog. Radix gives a
dropdown, a context menu, a popover and a select the SAME dismissable layer, so
all of them let a keystroke keep propagating. With the top bar's settings menu
open, Cmd+Enter still reached the approval card behind it and approved a gate
nobody could see. Escape was covered only because Radix cancels that one key.

isOverlayOpen now matches any open dialog, alertdialog, menu or listbox. A role
with no data-state still does not match, which is what keeps the Alt shortcuts
working inside the antd revision drawer.

Also from the review:

- The run-level Escape checked only the overlay, so a menu closing also stopped
  the agent. It now checks defaultPrevented too.
- Alt+O toggled a per-session pane even with no active session, where the panel
  renders none. It returns early instead.
- ShortcutKeys borrowed the registry's mirror chord when a caller passed an
  explicit chord, printing a key that chord never named.
- The ? hotkey opened a second layer on top of an open one. Found while testing
  the above, not in the review.
- The counts disagreed across the workspace and the story. Every mention now
  states both numbers: forty-three already shipped, forty-five in the registry.
- The story promised aria-keyshortcuts on two mock buttons that did not carry
  it, and one doc comment ran past the one-line rule.

Eight new tests pin the widened guard, one pins the no-session case, and one
pins Cmd+Enter under a menu, which defaultPrevented alone cannot catch.
…reuse it

The plan is for /m to become the whole app, not just the phone surface. Four of
the five shortcut pieces already sat in packages /m depends on. The hook did
not: it lived in web/oss, even though it imports only React and
@agenta/shared/utils and takes every action as a callback. Nothing about it was
desktop-specific.

It moves to @agenta/ui/shortcuts beside the keycaps, the sheet and the help
button, so a mobile host wires the same callbacks rather than reimplementing
anything. A phone never sends an Alt chord, so mounting it on a touch surface is
inert.

The old test covered two things at once, the hook and an app-layer rename
consumer that needs OSS atoms. It splits: the hook half moves to the package
(20 tests), the rename half stays in web/oss as useInlineRenameRequest.test.ts.

Storybook gains an On mobile story showing the approval card at phone width and
beside its desktop twin, so a keycap leaking onto touch is caught by looking.

Also fixes a story that threw at render. shortcutAria was used without its
import, which neither tsc nor eslint catches here: SWC transpiles stories
without type checking, so it built clean and failed only in the browser. My
regression sweep missed it too, because a thrown story renders Storybook's error
boundary as ordinary text. The sweep now reads that text. 60 renders, ten pages
across two themes and three widths, all clean.
Five findings, all real.

One keystroke answered gates you could not see. Every visited session stays
mounted behind display:none, so two parallel runs both parking a gate meant one
Cmd+Enter approved the hidden one too. A new isOnScreen helper gates the card's
window listener, and a test mounts two cards with one hidden.

The overlay guard saw only Radix. antd sets no data-state and leaves its popups
mounted after they close, so a dropdown, select or popover on screen still let
Cmd+Enter through to a parked gate. The guard now matches those by class and
filters by visibility, using checkVisibility where the browser has it and an
ancestor walk where it does not. A tooltip stays excluded: it is passive.

Alt+N was the macOS tilde dead key. I moved New session onto it yesterday, which
would have stopped every Mac user typing 'n'-with-tilde in the composer. It is
now the + key, matching the button in the tab strip, which no browser and no
layout claims. decisions.md now lists all five macOS dead keys so this cannot
happen again.

aria-keyshortcuts told two lies. The help button claimed a standalone ? key,
which is Shift+/ on a US layout and Shift+ss on a German one, and shortcutAria
returned an empty string that React rendered as an empty attribute. It now
returns undefined, and refuses any key it cannot express honestly.

decisions.md claimed the Alt letters were safe. They are safe in ENGLISH
Firefox. German Firefox reserves Alt+A, Alt+C and Alt+X for Ansicht, Chronik and
Extras, which collide with archive, configuration and next session. The document
now says so plainly, and status.md carries the open question of whether Alt plus
a letter can work at all across locales.

Suites: agenta-shared 459, agenta-chat 574, agenta-ui 168, oss AgentChatSlice
268. Verified live that an antd dropdown silences Alt+C, a closed one does not,
and nothing on a resting page matches the guard.
Codex showed the safe-letter list only holds for English Firefox. status.md now
carries the choice for a human: keep Alt plus a letter and accept the collision
for non-English Firefox users, or move to a three-key chord the way Linear does
and pay in ergonomics. The AZERTY legend mismatch is recorded beside it.
@mmabrouk

Copy link
Copy Markdown
Member Author
CleanShot 2026-08-31 at 12 01 35@2x CleanShot 2026-08-31 at 12 01 32@2x CleanShot 2026-08-31 at 12 01 27@2x CleanShot 2026-08-31 at 12 01 23@2x

@mmabrouk
mmabrouk changed the base branch from main to release/v0.114.4 August 31, 2026 10:03
@ashrafchowdury

Copy link
Copy Markdown
Contributor

Awesome, thank you @mmabrouk

@mmabrouk
mmabrouk merged commit 5d3b7cc into release/v0.114.4 Aug 31, 2026
80 of 82 checks passed
@mmabrouk mmabrouk mentioned this pull request Aug 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request frontend size:XXL This PR changes 1000+ lines, ignoring generated files. ux

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants