One entry per command — stable id, plain-language label, key chord, run() — replacing the ad-hoc keydown listeners in main.ts, catalog.ts, debug.ts and attach.ts and the parallel SHORTCUTS constant in help.ts. The `?` overlay now renders the registry, so a binding and its documentation cannot disagree. Keys are canonicalised the way the TUI's `InputKey::canonical` spells them, and chords resolve like its `ChordState`: hold while the sequence is a strict prefix, otherwise dispatch. That gives the web a leader, `ctrl-a` by default like `[tui].leader`, held as a partial chord and `preventDefault`ed so it stops being select-all — the escape hatch in docs/COMMAND-BAR.md needs somewhere to land (#149). The leader stays out of real form fields, where select-all is still what the operator wants. Same keys, same effects: plain single-key bindings remain deaf inside form fields and the terminal's hidden textarea, chorded ones do not. Refs #148 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
42 lines
1.4 KiB
TypeScript
42 lines
1.4 KiB
TypeScript
// Debug-HUD toggle (#20). Off by default; persisted in localStorage so it
|
|
// survives reloads, flipped by a keybind (Ctrl+Shift+D), and force-enabled by
|
|
// `?hud` in dev. A `maestro-hud-toggle` event lets the HUD re-render on change.
|
|
|
|
import { CommandSet, defineCommands } from "./commands.js";
|
|
|
|
const STORAGE_KEY = "maestro:hud";
|
|
export const HUD_TOGGLE_EVENT = "maestro-hud-toggle";
|
|
|
|
/** Whether the debug HUD should be shown. */
|
|
export function isHudEnabled(): boolean {
|
|
if (import.meta.env.DEV && location.search.includes("hud")) return true;
|
|
try {
|
|
return localStorage.getItem(STORAGE_KEY) === "1";
|
|
} catch {
|
|
// Private-mode / storage-disabled: HUD just stays off.
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/** Persist the HUD on/off state and notify listeners. */
|
|
export function setHudEnabled(on: boolean): void {
|
|
try {
|
|
if (on) localStorage.setItem(STORAGE_KEY, "1");
|
|
else localStorage.removeItem(STORAGE_KEY);
|
|
} catch {
|
|
// ignore storage failures — the event still drives the in-memory HUD
|
|
}
|
|
window.dispatchEvent(new CustomEvent(HUD_TOGGLE_EVENT));
|
|
}
|
|
|
|
export function toggleHud(): void {
|
|
setHudEnabled(!isHudEnabled());
|
|
}
|
|
|
|
const hudKeys = new CommandSet(defineCommands({ "debug.toggleHud": () => toggleHud() }));
|
|
|
|
/** Global keybind: Ctrl+Shift+D toggles the debug HUD. */
|
|
export function installHudKeybind(): void {
|
|
window.addEventListener("keydown", (e) => hudKeys.handle(e));
|
|
}
|