Skip to content

Global command palette (⌘K / Ctrl+K) to search and run any command #41

Description

@DragonnZhang

Problem or Motivation

Every comparable desktop app ships a command palette — a single keyboard-driven
overlay (⌘K / Ctrl+K in Linear/Vercel/Raycast, ⌘⇧P in VS Code / Codex desktop, ⌘K
in Claude's desktop app) that lets you search for and run any command without
hunting through menus. It is the fastest way to discover and trigger app actions.

OpenWork already has all the ingredients but no palette that ties them together:

  • A centralized action registry (apps/electron/src/renderer/actions/) with 26
    actions carrying label, category, defaultHotkey, and — crucially — an
    execute(actionId) method that runs the first enabled handler.
  • The cmdk command primitives (components/ui/command.tsx) — currently only
    consumed by the in-input slash-command menu.
  • Translated action labels (shortcuts.action.*) and category headings
    (shortcuts.category.*) already in every locale.

Today the action registry is surfaced only in read-only reference views (the
Keyboard Shortcuts dialog and the Settings → Shortcuts page). There is no way to
run an action by searching for it. Discovering an action means opening Settings
and scrolling, or memorizing a hotkey.

Proposed Solution

Add a global command palette opened with ⌘K / Ctrl+K (and from the App
menu). It:

  • Lists every registry action, grouped by category, with its hotkey shown on the
    right.
  • Filters as you type (cmdk's built-in fuzzy match over the translated label).
  • Shows a "No results found" empty state when nothing matches.
  • On select, closes and calls the registry's execute(actionId) — so "Settings",
    "Toggle Theme", "New Chat", etc. run exactly as if their hotkey were pressed.
  • Closes on Esc / selection (integrated with the existing modal stack).

This is a frontend-only change:

  • It reuses the existing action registry (useActionRegistry().execute), the cmdk
    primitives, and the existing hotkey/label infrastructure — no backend, no
    qwen-code change.
  • It introduces no new i18n keys: the input placeholder reuses
    commands.searchCommands, the empty state reuses common.noResultsFound, labels
    reuse shortcuts.action.*, and group headings reuse shortcuts.category.*.

Alternatives Considered

  • Keyboard Shortcuts dialog / Settings → Shortcuts page already exist, but they
    are reference surfaces — you can read a shortcut, not run the action. A palette
    is the run surface every comparable app pairs with the reference.
  • Slash-command menu (/) exists inside the chat input, but it is scoped to
    chat commands and the message composer, not global app actions.

Additional Context

Feasibility: frontend-only / doable. Verified against apps/electron — the
registry already exposes execute(), actions carry all needed display metadata,
and cmdk is already a dependency.

Acceptance criteria (CDP e2e assertion)

A new e2e/assertions/command-palette.assert.ts drives the real built app over CDP
and asserts the full path:

  1. Pressing ⌘K / Ctrl+K opens the palette; it renders and lists more than
    one
    action row.
  2. Typing a query (theme) narrows the list — every visible row contains the
    query and the row count shrinks — and the known Toggle Theme action is
    present.
  3. A no-match query (zzqqxxnomatchzzqqxx) shows the empty state and hides every
    row.
  4. Clearing the query restores the full list.
  5. Selecting Toggle Theme closes the palette and flips the app theme
    (documentElement darklight class), proving the palette actually executes
    the action rather than merely displaying it.

Part of the autonomous desktop-feature loop (loop-bot).

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions