Add global keyboard EventRouter and unify publish (M6, §01D)

One module owns the document keydown listener and dispatches the shortcut map
(Cmd/Ctrl+Shift+N / +K / +S / +, / Escape), platform-aware, via the single-source
focus-utils interactive-context gate. Escape and Cmd/Ctrl+S run before the gate so
save works while editing; the rest are suppressed mid-typing. Publish + its toast
move into services/snippet-actions so the button and Cmd/Ctrl+S behave identically.
Removes the ad-hoc keydown handler from App and Monaco's Cmd+S command.
This commit is contained in:
2026-06-07 17:18:55 +03:00
parent f365258fcc
commit 807d3c8e3c
12 changed files with 401 additions and 48 deletions
@@ -65,6 +65,13 @@ nature of the message, not by convenience.
_inline on the control_ ("Copied") with a polite `aria-live` announcement for assistive
tech, never a toast-per-copy. This refines the spec's earlier blanket "every action
toasts" (spec §01F/§02/§05, reconciled).
- **An action's confirmation belongs with the action, not its call site.** When an action is
reachable from more than one trigger (e.g. publish is both a toolbar button _and_
Cmd/Ctrl+S), pair the store mutation and its toast in **one `services/` helper**
(`publishActiveSnippet`) that every trigger calls — otherwise the toast rides one path and
the other publishes silently (the exact inconsistency this rule prevents). The shortcut is
owned globally by the EventRouter (arch 04), so the helper is the only place the outcome is
confirmed.
- **The same failure can light up two channels.** An unrenderable spec shows the _same_
message inline in both the editor (§03E) and the preview (§04) — one producer
(`PreviewStore`), two subscribers. That's intentional, not duplication.