Skip to content

feat(shortcuts): global keyboard shortcuts + help directory#4126

Merged
senamakel merged 16 commits into
tinyhumansai:mainfrom
senamakel:feat/keyboard-shortcuts
Jun 25, 2026
Merged

feat(shortcuts): global keyboard shortcuts + help directory#4126
senamakel merged 16 commits into
tinyhumansai:mainfrom
senamakel:feat/keyboard-shortcuts

Conversation

@senamakel

@senamakel senamakel commented Jun 25, 2026

Copy link
Copy Markdown
Member

Summary

  • Adds a global keyboard-shortcut layer on top of the existing command/hotkey infrastructure (hotkeyManager + command registry).
  • New shortcuts: New Chat (⌘N), Toggle Sidebar (⌘B), Command Palette (⌘K / ⌘P), and a Keyboard Shortcuts help directory (? / ⌘/).
  • Navigation tabs move to the Control key (ctrl+1..5 on macOS, folding to mod+1..5 on Win/Linux); profile switches (⌘1..4) are wired but hidden until the profiles feature exists.
  • A registry-driven help directory surfaces in two places that can't drift from the real bindings: a ?/⌘/ modal overlay and Settings → Keyboard Shortcuts.
  • Replaces the sidebar/top-bar wallet quick-access icon with a keyboard-shortcuts icon (wallet balances remains under Settings → Data) and gives the Settings entry its own glyph.

Problem

The app already had a command palette (⌘K) and a few nav shortcuts, but no discoverable map of what's available — the palette even advertised "Press ? for all shortcuts" with no handler behind it. Users had no fast way to start a new chat, toggle the sidebar, or learn the shortcut set.

Solution

  • globalActions.ts is the single declarative source of truth (label, group, primary shortcut, alias keys, per-combo allowInInput, enabled/visibility) feeding the palette, the help directory, and the actual key bindings.
  • mod+/ is allowed while inputs are focused (so it can replace the palette mid-search); the bare ? is not, so typing "?" in chat never hijacks it. Palette and help overlay are mutually exclusive.
  • CommandProvider wires the side-effecting handlers through a ref so the hotkey frame registers once and never tears down on navigation.
  • New Chat (⌘N) uses a dedicated useNewChat hook that always selects/creates a blank thread regardless of route (a review caught that reusing the Home-nav path would reopen the persisted conversation from non-chat routes).
  • Cross-platform modifier split: our matcher treats a bare ctrl+N as macOS-only (physical Control), so nav uses ctrl on macOS and mod elsewhere — Ctrl+N physically on every OS. Profile shortcuts (mod+N = ⌘N on macOS) are registered bound-but-disabled and hidden behind a PROFILES_ENABLED flag, ready to light up when profiles land.
  • The shortcuts-help files use standard white/neutral ModalShell styling, so they live in components/shortcuts/ (outside components/commands/, whose cmd-*-token lint forbids neutral colours).

Submission Checklist

  • Tests added or updated (happy path + at least one failure / edge case) per Testing Strategy
  • Diff coverage ≥ 80% — changed lines covered by Vitest unit + WDIO E2E (globalActions, CommandProvider overlays, shortcutsView grouping, useNewChat, shell button swaps, command-palette.spec.ts). CI coverage-gate verifies.
  • Coverage matrix updated — added section 13.6 Keyboard Shortcuts & Command Surface in docs/TEST-COVERAGE-MATRIX.md
  • All affected feature IDs from the matrix are listed in the PR description under ## Related
  • No new external network dependencies introduced (mock backend used per Testing Strategy)
  • N/A: Manual smoke checklist not updated — UI shortcut layer only; no release-cut smoke surface changed (wallet balances still reachable via Settings → Data).
  • N/A: No tracking issue — feature request came directly from the maintainer; nothing to Closes.

Impact

  • Desktop (primary): new global hotkeys + a help overlay and Settings page; the sidebar/collapsed-rail wallet icon is replaced by a shortcuts icon. No backend, RPC, or migration changes. No new dependencies.
  • macOS nav shortcuts move from ⌘1..5 to Control+1..5; Win/Linux behaviour (Ctrl+1..5) is unchanged.
  • ⌘N may occasionally be intercepted by an OS/CEF "new window" accelerator on some platforms; can be remapped to ⌘⇧N if it proves flaky.

Related

  • Coverage feature IDs: 13.6.1 (Command Palette), 13.6.2 (Keyboard Shortcuts help directory), 13.6.3 (Global shortcut map).
  • Closes:
  • Follow-up PR(s)/TODOs: activate profile-switch shortcuts (⌘1..4) when the profiles feature ships (flip PROFILES_ENABLED).

AI Authored PR Metadata (required for Codex/Linear PRs)

Linear Issue

  • Key: N/A
  • URL: N/A

Commit & Branch

  • Branch: feat/keyboard-shortcuts
  • Commit SHA: 23450c2

Validation Run

  • pnpm --filter openhuman-app format:check
  • pnpm typecheck
  • Focused tests: globalActions, CommandProvider, shortcutsView, useNewChat, SidebarHeader, CollapsedNavRail; E2E spec added (command-palette.spec.ts) — runs in CI.
  • N/A: Rust fmt/check — no Rust changed (pre-push rust:check hook passed).
  • N/A: Tauri fmt/check — no Tauri shell changed.

Validation Blocked

  • command: N/A
  • error: N/A
  • impact: N/A

Behavior Changes

  • Intended behavior change: add global keyboard shortcuts + a discoverable help directory; move nav tabs to Control (macOS); replace top-bar wallet icon with a shortcuts icon.
  • User-visible effect: new hotkeys (⌘N, ⌘B, ?, ⌘/), a shortcuts overlay + Settings page, and a keyboard icon in place of the wallet icon.

Parity Contract

  • Legacy behavior preserved: ⌘K palette, existing nav destinations, and Win/Linux Ctrl+1..5 nav unchanged; wallet balances still reachable via Settings → Data.
  • Guard/fallback/dispatch parity checks: profile shortcuts disabled+hidden until PROFILES_ENABLED; ? gated out of text inputs; palette/help mutually exclusive.

Duplicate / Superseded PR Handling

  • Duplicate PR(s): N/A
  • Canonical PR: this PR
  • Resolution: N/A

Summary by CodeRabbit

  • New Features
    • Added a Keyboard Shortcuts modal with a grouped, localized shortcuts list (including shortcut group labels and a help hint).
    • Added a new Settings page/route for Keyboard Shortcuts and a corresponding shortcuts panel.
    • Added “keyboard shortcuts” actions to the sidebar/header and collapsed nav rail, plus icon support in navigation.
  • Bug Fixes
    • Improved Settings navigation active-state for wallet-related subpages.
    • Enforced mutual exclusivity between the command palette and the keyboard shortcuts overlay.
    • Prevented incorrect thread reuse by accounting for send/streaming/pending signals.
  • Tests
    • Expanded unit and E2E coverage for the keyboard shortcuts and command surface.

…elp directory

Add a Hermes-inspired global shortcut layer and a discoverable help directory.

Shortcuts (mod = ⌘ on macOS / Ctrl elsewhere), on top of the existing
mod+1..5 / mod+, navigation and mod+K palette:
- New Chat        — mod+N      (reuses useHomeNav)
- Toggle Sidebar  — mod+B      (layoutSlice.toggleSidebar on the app shell)
- Command Palette — mod+K, mod+P
- Keyboard Shortcuts — mod+/ and ?

globalActions becomes the single declarative source of truth (label, group,
shortcut, alias keys, allow-in-input) for the palette, the help directory, and
the real key bindings. CommandProvider wires the side-effecting handlers via a
ref (mount-once) and renders the new help overlay; the palette and help overlay
are mutually exclusive.

Help directory lives in two places, both driven live from the command registry
so they can never drift from the real bindings:
- a ?/⌘/ modal overlay (KeyboardShortcutsModal)
- Settings → Keyboard Shortcuts (KeyboardShortcutsPanel)

Tests: globalActions handler/alias/dispose coverage, CommandProvider overlay +
mutual-exclusion (re-enabling the previously-stubbed help tests), and
shortcutsView grouping/ordering/empty state. test-utils gains the thread
reducer so CommandProvider (via useHomeNav) renders under the shared store.
…ches

Hermes-style modifier split for the numbered shortcuts:
- Navigation tabs move to the Control key — `ctrl+1..5` on macOS (physical
  Control, distinct from ⌘), folding to `mod+1..5` on Windows/Linux (our matcher
  treats a bare `ctrl+N` as unreachable there), i.e. Ctrl+N physically on every
  OS. Settings keeps the conventional ⌘, .
- Profile switches (⌘1..4 on macOS) are wired but inert: registered
  bound-but-disabled and hidden from the palette/help directory behind a
  PROFILES_ENABLED flag, ready to light up when the profiles feature lands.

Adds a Profiles group to GROUP_ORDER / the help display order, and drops the now
unnecessary exhaustive-deps disable in CommandProvider.
…r wallet button

- Add a keyboard glyph for the Settings → Keyboard Shortcuts entry
  (settingsNavIcons) and a reusable `keyboard` NavIcon for the collapsed rail.
- Replace the wallet quick-access button in the sidebar header and collapsed rail
  with a keyboard-shortcuts button that opens the help directory via
  registry.runAction('meta.keyboard-shortcuts'). Wallet balances remains
  reachable from Settings → Data.
- Simplify CollapsedNavRail's settingsActive now that the wallet rail item is
  gone (Settings lights up on /settings/* including the wallet sub-page).
- Update shell tests for the wallet→shortcuts swap.
Extend command-palette.spec.ts: open the help directory via mod+/ (asserting the
live grouped list renders the new global actions) and via the bare ? key, with
Esc close in both.
The keyboard-shortcuts help overlay + shared list use the standard white/neutral
modal styling (ModalShell), which the commands/ directory's cmd-token lint
(lint:commands-tokens) forbids. Relocate shortcutsView + KeyboardShortcutsModal
(and their test) to components/shortcuts/ and repoint imports; Kbd stays in
commands/ and is imported across.
@senamakel senamakel requested a review from a team June 25, 2026 18:15
@coderabbitai

coderabbitai Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@senamakel, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 46 minutes and 50 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 05d1a855-e68a-4488-9d08-01108361ed56

📥 Commits

Reviewing files that changed from the base of the PR and between b2da69b and c6ac895.

📒 Files selected for processing (2)
  • app/src/components/layout/shell/useNewChat.test.tsx
  • app/src/components/layout/shell/useNewChat.ts
📝 Walkthrough

Walkthrough

This PR adds a handler-driven global command system, a reusable new-chat hook, keyboard-shortcuts list and modal UI, shell entry points for shortcuts, and a settings page for keyboard shortcuts. It also updates translations, tests, and coverage docs.

Changes

Keyboard shortcuts command surface

Layer / File(s) Summary
Global actions and hotkeys
app/src/lib/commands/globalActions.ts, app/src/lib/commands/__tests__/globalActions.test.tsx
Global action registration now includes chat, view, general, and profile entries, with shortcut binding, aliases, cleanup, and tests for the expanded action map.
New chat hook
app/src/components/layout/shell/useNewChat.ts, app/src/components/layout/shell/useNewChat.test.tsx, app/src/test/test-utils.tsx
useNewChat switches accounts, reuses empty threads when present, creates new threads when needed, and the test store now includes the thread slice.
Shortcut list and modal
app/src/components/shortcuts/*, app/src/lib/i18n/*, app/test/e2e/specs/command-palette.spec.ts, docs/TEST-COVERAGE-MATRIX.md
The live shortcuts list, modal, locale strings, e2e coverage, and test matrix entries add the keyboard-shortcuts overlay and its grouped shortcut display.
Command provider wiring
app/src/components/commands/CommandProvider.tsx, app/src/components/commands/__tests__/CommandProvider.test.tsx
CommandProvider registers global actions on mount, tracks palette and shortcuts overlay state, and renders the shortcuts modal alongside the command palette.
Shell shortcut entry points
app/src/components/layout/shell/RootShellLayout.tsx, app/src/components/layout/shell/SidebarHeader.tsx, app/src/components/layout/shell/SidebarHeader.test.tsx, app/src/components/layout/shell/CollapsedNavRail.tsx, app/src/components/layout/shell/CollapsedNavRail.test.tsx, app/src/components/layout/shell/navIcons.tsx, app/src/components/settings/layout/settingsNavIcons.tsx
The shell adds keyboard-shortcuts buttons in the header and collapsed rail, updates Settings active matching, and exports the shell layout ID.
Settings shortcuts page
app/src/components/settings/panels/KeyboardShortcutsPanel.tsx, app/src/components/settings/settingsRouteElements.tsx, app/src/components/settings/settingsRouteRegistry.ts
The settings UI adds a keyboard-shortcuts panel, route entry, and registry metadata.

Sequence Diagram(s)

sequenceDiagram
  participant CommandProvider
  participant registerGlobalActions
  participant registry
  participant hotkeyManager
  participant KeyboardShortcutsModal
  CommandProvider->>registerGlobalActions: stable handlers from handlersRef
  registerGlobalActions->>registry: register action handlers
  registerGlobalActions->>hotkeyManager: bind command shortcuts
  hotkeyManager->>CommandProvider: invoke shortcut handler
  CommandProvider->>KeyboardShortcutsModal: set shortcutsOpen true
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested labels

feature, working

Suggested reviewers

  • oxoxDev
  • sanil-23

Poem

🐰 I tapped the keys and out came light,
Shortcuts hopped in left and right.
A palette winked, a sidebar swayed,
The bunny’s command map stayed well-laid.
Now every ? knows where to hide.

🚥 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 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly reflects the main feature: global keyboard shortcuts and the new help directory.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


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

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 099aa287ad

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread app/src/components/commands/CommandProvider.tsx
The New Chat shortcut used useHomeNav(), whose off-chat branch only navigates to
/chat and lets Conversations own blank-thread landing — but that restores the
persisted selectedThreadId first, so from a non-chat route ⌘N reopened the
previous conversation instead of starting fresh (flagged in PR review).

Add a dedicated useNewChat() hook that always selects/creates a blank thread
(reusing an existing empty one, else creating) and navigates straight to it,
regardless of route. CommandProvider's newChat handler now uses it. Covered by
useNewChat.test.tsx.
@senamakel senamakel changed the title feat(shortcuts): Hermes-style keyboard shortcuts + help directory feat(shortcuts): global keyboard shortcuts + help directory Jun 25, 2026
@coderabbitai coderabbitai Bot added docs Docs-only change; used by PR automation. feature Net-new user-facing capability or product behavior. labels Jun 25, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 23450c2773

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread app/src/components/layout/shell/useNewChat.ts Outdated
Comment thread app/src/lib/commands/globalActions.ts
… hint key

- useNewChat: a thread counts as empty only when it has neither a server
  messageCount nor cached messages. Right after the first send, addMessageLocal
  populates messagesByThreadId while messageCount can still read 0, so the old
  count-only check could reuse (and reopen) that now-occupied conversation.
- CommandPalette footer: advertise ⌘/ (allowed while the search box is focused)
  via <Kbd>, instead of "Press ? for all shortcuts" — `?` is intentionally
  skipped inside inputs, so it never worked from the focused palette. Reuses the
  shared shortcuts.title string.

@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 (2)
app/src/components/shortcuts/shortcutsView.tsx (1)

86-104: 🔒 Security & Privacy | 🔵 Trivial

Translate shortcut labels and headings via useT()

group and action.label come from app/src/lib/commands/globalActions.ts as hard-coded English strings, so this view still bypasses i18n. Store translation keys in the registry or translate these values at render time.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/src/components/shortcuts/shortcutsView.tsx` around lines 86 - 104, The
shortcuts view still renders hard-coded English values for the section heading
and action label; update ShortcutsView to use useT() when displaying group and
action.label, or switch the globalActions registry to store translation keys
instead of raw strings. Locate the rendering in shortcutsView.tsx around the
groups.map and items.map blocks, and ensure both the group header and each
action row resolve through the translation function so the UI is fully
localized.

Source: Coding guidelines

app/test/e2e/specs/command-palette.spec.ts (1)

208-214: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Exercise the actual focused-input contract in these shortcut tests.

Right now both cases fire from whatever focus state the page happens to have, so they can still pass if allowInInput regresses. The contract in app/src/lib/commands/globalActions.ts is specifically that mod+/ should open from a focused input while bare ? should not, so these tests should first focus a real editable field and assert that behavior explicitly.

Also applies to: 245-249

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/test/e2e/specs/command-palette.spec.ts` around lines 208 - 214, Update
the keyboard-shortcuts e2e specs to exercise the focused-input behavior
explicitly: in the command-palette tests, first focus a real editable input
before triggering the shortcuts, then assert that `globalActions` allows `mod+/`
to open the help from that focused state while bare `?` does not. Use the
existing `dispatchKey` helper and the keyboard-shortcuts/help list selectors in
`command-palette.spec.ts` so the tests verify the `allowInInput` contract rather
than relying on the page’s default focus.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@app/src/components/commands/CommandProvider.tsx`:
- Around line 57-77: The CommandProvider effect is synchronously calling
setGlobalFrame inside useEffect, which violates the
react-hooks/set-state-in-effect rule. Move the frame derivation out of the
effect and derive it during render or via a memoized value, then keep the effect
in CommandProvider focused only on registering and disposing global actions with
stableHandlers, registerGlobalActions, and hotkeyManager cleanup.

In `@app/src/components/layout/shell/useNewChat.ts`:
- Around line 45-52: The New Chat flow in useNewChat currently swallows
createNewThread failures in an empty catch, so the rejection is invisible.
Update the createNewThread().unwrap() chain to handle errors by surfacing them
through the app’s existing error/logging path or dispatching a user-visible
failure state, and keep the behavior tied to createNewThread, setSelectedThread,
and loadThreadMessages so the failure is no longer silently ignored.

In `@app/src/lib/commands/globalActions.ts`:
- Line 8: The command palette and shortcuts directory are exposing hardcoded
English group headings and label strings, so move these UI texts behind
translation keys and resolve them through the existing useT-backed i18n layer
before registration. Update GROUP_ORDER and the related label definitions in
globalActions to use locale-driven keys, then add the new entries to en.ts and
every locale catalog so the shortcut surface is fully localized.

In `@app/test/e2e/specs/command-palette.spec.ts`:
- Around line 233-238: The Escape fallback in the command palette test is
dispatched on the wrong target, so the ModalShell useEscapeKey listener on
document will not receive it. Update the fallback path in
command-palette.spec.ts around the browser.keys('Escape') try/catch to send
dispatchKey('Escape') to document instead of window, using the existing
dispatchKey helper so the overlay closes reliably.

---

Nitpick comments:
In `@app/src/components/shortcuts/shortcutsView.tsx`:
- Around line 86-104: The shortcuts view still renders hard-coded English values
for the section heading and action label; update ShortcutsView to use useT()
when displaying group and action.label, or switch the globalActions registry to
store translation keys instead of raw strings. Locate the rendering in
shortcutsView.tsx around the groups.map and items.map blocks, and ensure both
the group header and each action row resolve through the translation function so
the UI is fully localized.

In `@app/test/e2e/specs/command-palette.spec.ts`:
- Around line 208-214: Update the keyboard-shortcuts e2e specs to exercise the
focused-input behavior explicitly: in the command-palette tests, first focus a
real editable input before triggering the shortcuts, then assert that
`globalActions` allows `mod+/` to open the help from that focused state while
bare `?` does not. Use the existing `dispatchKey` helper and the
keyboard-shortcuts/help list selectors in `command-palette.spec.ts` so the tests
verify the `allowInInput` contract rather than relying on the page’s default
focus.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: a65d6d1d-2e6f-4204-985b-e60ab4cb243c

📥 Commits

Reviewing files that changed from the base of the PR and between 5984083 and 23450c2.

📒 Files selected for processing (36)
  • app/src/components/commands/CommandProvider.tsx
  • app/src/components/commands/__tests__/CommandProvider.test.tsx
  • app/src/components/layout/shell/CollapsedNavRail.test.tsx
  • app/src/components/layout/shell/CollapsedNavRail.tsx
  • app/src/components/layout/shell/RootShellLayout.tsx
  • app/src/components/layout/shell/SidebarHeader.test.tsx
  • app/src/components/layout/shell/SidebarHeader.tsx
  • app/src/components/layout/shell/navIcons.tsx
  • app/src/components/layout/shell/useNewChat.test.tsx
  • app/src/components/layout/shell/useNewChat.ts
  • app/src/components/settings/layout/settingsNavIcons.tsx
  • app/src/components/settings/panels/KeyboardShortcutsPanel.tsx
  • app/src/components/settings/settingsRouteElements.tsx
  • app/src/components/settings/settingsRouteRegistry.ts
  • app/src/components/shortcuts/KeyboardShortcutsModal.tsx
  • app/src/components/shortcuts/__tests__/shortcutsView.test.tsx
  • app/src/components/shortcuts/shortcutsView.tsx
  • app/src/lib/commands/__tests__/globalActions.test.tsx
  • app/src/lib/commands/globalActions.ts
  • app/src/lib/i18n/ar.ts
  • app/src/lib/i18n/bn.ts
  • app/src/lib/i18n/de.ts
  • app/src/lib/i18n/en.ts
  • app/src/lib/i18n/es.ts
  • app/src/lib/i18n/fr.ts
  • app/src/lib/i18n/hi.ts
  • app/src/lib/i18n/id.ts
  • app/src/lib/i18n/it.ts
  • app/src/lib/i18n/ko.ts
  • app/src/lib/i18n/pl.ts
  • app/src/lib/i18n/pt.ts
  • app/src/lib/i18n/ru.ts
  • app/src/lib/i18n/zh-CN.ts
  • app/src/test/test-utils.tsx
  • app/test/e2e/specs/command-palette.spec.ts
  • docs/TEST-COVERAGE-MATRIX.md

Comment thread app/src/components/commands/CommandProvider.tsx
Comment thread app/src/components/layout/shell/useNewChat.ts Outdated
Comment thread app/src/lib/commands/globalActions.ts
Comment thread app/test/e2e/specs/command-palette.spec.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 539f66638b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread app/src/components/layout/shell/useNewChat.ts Outdated
- useNewChat: log createNewThread rejections instead of swallowing them in an
  empty catch, so the primary New Chat path is diagnosable (review feedback).
- command-palette.spec.ts: extract closeOverlayWithEscape() with a
  document-targeted synthetic-Escape last resort — ModalShell's useEscapeKey
  binds to document, so a window-dispatched fallback would miss it.
Route the command palette / shortcuts-directory action labels and group headings
through useT() instead of shipping hardcoded English (project i18n guideline).

- Action gains an optional labelKey resolved at display time (English `label`
  kept as fallback + for cmdk search); globalActions registers a labelKey per
  action and exports a GROUP_LABEL_KEYS map for the headings.
- CommandPalette + ShortcutsList resolve labelKey/group via t().
- Add shortcuts.action.* and shortcuts.group.* keys to en.ts and all 13 locale
  catalogs (parity check passes).
coderabbitai[bot]
coderabbitai Bot previously approved these changes Jun 25, 2026
Extend useNewChat's empty-thread guard to also exclude the currently-selected
thread. An in-flight first send is tracked only locally on the active
conversation (count still 0, not yet in messagesByThreadId), so without this the
shortcut could reopen the conversation the user is sending in. Skipping the
selected thread + the cache check closes that pre-fulfillment window.
coderabbitai[bot]
coderabbitai Bot previously approved these changes Jun 25, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f863f41fc5

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread app/src/components/layout/shell/useNewChat.ts Outdated
…Chat

Replace the blanket "exclude the selected thread" guard with an occupancy check:
a thread is reusable when it has no message count, no cached messages, and no
in-flight assistant turn (chatRuntime.streamingAssistantByThread, whose
`started` lifecycle is set the moment the user sends). This reuses a
genuinely-blank current chat instead of piling up empties, while still never
reopening a conversation with a send in flight — reconciling both review rounds.
coderabbitai[bot]
coderabbitai Bot previously approved these changes Jun 25, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b102af5cea

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread app/src/lib/commands/globalActions.ts
Comment thread app/src/components/layout/shell/useNewChat.ts Outdated
…g send

Two review fixes:
- chat.new (⌘N/Ctrl+N) gains allowInInput: true so it fires while the chat
  composer textarea is focused (the normal state when starting fresh) and
  preventDefault stops the OS "new window" accelerator swallowing it.
- Lift the optimistic-send signal into Redux: chatRuntimeSlice gains
  pendingSendThreadIds with mark/clear reducers, set synchronously the instant a
  user sends (mirrored from Conversations' existing pending-send helpers, before
  addMessageLocal is awaited). useNewChat now also excludes pending-send threads,
  closing the earliest window where messageCount, messagesByThreadId and
  streamingAssistantByThread are all still empty.
@coderabbitai coderabbitai Bot added working A PR that is being worked on by the team. and removed docs Docs-only change; used by PR automation. labels Jun 25, 2026
coderabbitai[bot]
coderabbitai Bot previously approved these changes Jun 25, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b2da69bb72

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread app/src/components/layout/shell/useNewChat.ts
Apply the same isThreadVisibleInTab(thread, GENERAL_TAB_VALUE) filter the /chat
landing uses before treating a thread as reusable, so ⌘N/Ctrl+N from Settings or
another route never lands on a hidden blank task/subconscious/parented session
instead of opening a fresh general chat. New regression test covers it.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c6ac89506b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +77 to +78
void dispatch(createNewThread())
.unwrap()

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Guard New Chat against duplicate creates

When there is no reusable blank thread and the user invokes New Chat twice before the first createNewThread().unwrap() settles (for example double-tapping Cmd/Ctrl+N while the core is slow), this branch dispatches another create because no in-flight create is recorded. Both thunks can create and then select/navigate to their own fresh threads, leaving an extra blank conversation despite the hook's blank-thread reuse contract; add a local/Redux pending-create guard or optimistic placeholder before dispatching.

Useful? React with 👍 / 👎.

@senamakel senamakel merged commit a29878e into tinyhumansai:main Jun 25, 2026
23 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature Net-new user-facing capability or product behavior. working A PR that is being worked on by the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant