You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Salvages the foundation of #380 by @gjermundgaraba — the original PR sat
6 weeks waiting for review and was closed by the author. This lands the
engine, scope data, and auto-generated marketing docs page, deferring
per-component handler migration to follow-up PRs.
Layout:
- packages/ui/shortcuts/{core,runtime,index}.ts — engine + barrel
- packages/ui/shortcuts/plan-review/* — scopes for plan editor surfaces
- packages/ui/shortcuts/code-review/* — scopes for review editor surfaces
- packages/{editor,review-editor}/shortcuts.ts — per-app surface composition
- apps/marketing/src/{components,lib} — auto-generated docs page
App behavior is unchanged: existing ad-hoc keydown handlers keep running.
The registry is plumbing waiting for migration PRs to wire to it.
Co-authored-by: Gjermund Garaba <gjermund@garaba.net>
│ ├── dock/ # Dockview center panel infrastructure
68
78
│ ├── demoData.ts # Demo diff for standalone mode
@@ -380,6 +390,20 @@ interface Block {
380
390
381
391
Text highlighting uses `web-highlighter` library. Code blocks use manual `<mark>` wrapping (web-highlighter can't select inside `<pre>`).
382
392
393
+
## Keyboard Shortcuts
394
+
395
+
**Location:**`packages/ui/shortcuts/` (engine + scope data), `packages/editor/shortcuts.ts` and `packages/review-editor/shortcuts.ts` (per-app surfaces).
396
+
397
+
The shortcut system has three layers:
398
+
399
+
1.**Engine** (`packages/ui/shortcuts/{core,runtime}.ts`) — parser for declarative bindings (`Mod+Enter`, `Alt Alt` double-tap, `Alt hold`), dispatcher, platform-aware formatter (mac glyphs vs. `Ctrl`), validator, and the `useShortcutScope` / `useDoubleTapShortcuts` React hooks. Truly shared — both apps use it as-is.
400
+
2.**Scopes** — `defineShortcutScope({ id, title, shortcuts: { actionId: { bindings, description, section, ... } } })`. One scope per UI surface (annotation toolbar, comment popover, file tree, etc.). Lives in `packages/ui/shortcuts/{plan-review,code-review}/` — **the subfolder names which app's UI the scope serves**. Components/Apps wire handlers to a scope via `useShortcutScope({ scope, handlers: { actionId: () => ... } })`.
401
+
3.**Surfaces** (`packages/editor/shortcuts.ts`, `packages/review-editor/shortcuts.ts`) — each app composes its scopes into a `ShortcutSurface` (`planReviewSurface`, `annotateSurface`, `codeReviewSurface`). Surfaces feed both the in-app help modal and the marketing site's auto-generated docs page.
402
+
403
+
**Convention for adding new shortcuts:** define the action in the relevant scope file under the right subfolder (`plan-review/` or `code-review/`), declare the binding(s) and description, then wire a handler at the call site with `useShortcutScope`. The marketing docs page picks it up automatically at next build. Unit tests in `packages/ui/shortcuts.test.ts` enforce normalized binding tokens (`Mod`, `Shift`, `Alt`, `A-Z`, `1-0`, named keys, `F1`–`F12`) and unique scope ids.
404
+
405
+
**Marketing docs auto-generation:**`apps/marketing/src/lib/shortcutReference.ts` reads the three surfaces and `apps/marketing/src/components/ShortcutReference.astro` renders them as tables. The `/docs/reference/keyboard-shortcuts` page is special-cased in `apps/marketing/src/pages/docs/[...slug].astro` to render the component instead of the markdown body.
@@ -482,6 +506,8 @@ Running only `build:opencode` will copy stale HTML files.
482
506
483
507
`apps/marketing/` is the plannotator.ai website — landing page, documentation, and blog. Built with Astro 5 (static output, zero client JS except a theme toggle island). Docs are markdown files in `src/content/docs/`, blog posts in `src/content/blog/`, both using Astro content collections. Tailwind CSS v4 via `@tailwindcss/vite`. Deploys to S3/CloudFront via GitHub Actions on push to main.
484
508
509
+
The `/docs/reference/keyboard-shortcuts` page is auto-generated from the shortcut registry at build time — see the Keyboard Shortcuts section above. Editing the markdown body has no effect; update the scope files instead.
0 commit comments