blue-a11y/dsh-client-shortcuts ↗★ 1
@blue-a11y/dsh-client-shortcuts
Global keyboard shortcuts plugin for the DeepSeek Harness web GUI: ctx.shortcuts registry service plus mod+l / mod+k / mod+shift+c default bindings
AI 分析
核心用途是提升 Web 端的键盘操作效率。适合重度键盘依赖者、希望通过快捷键快速切换会话或清屏的效率工具爱好者。
インストール
npx -p @deepseek-ai/dsh dsh plugin --profile web add github:blue-a11y/dsh-client-shortcutsドキュメント
README 全文を読む ↗@blue-a11y/dsh-client-shortcuts
Global keyboard shortcuts plugin for the dsh web GUI. ShortcutRegistry (the ctx.shortcuts service) owns one capture-phase keydown listener on window and fires registered combo handlers, releasing the event while focus sits in a text field unless a binding opts in. A 快捷键 settings page (registered into settings.section, built from @deepseek-ai/dsh-client-ui-primitives) lists every bindable action with record/reset rebinding and conflict detection. The node half is deliberately empty — the whole feature is browser UI.
mod matches Cmd on macOS and Ctrl elsewhere (e.metaKey || e.ctrlKey), the same convention the composer uses. The UI and README spell combos cmd-friendly (cmd+l ≡ mod+l).
Bindable actions
| Action | Default | Text-field scope |
|---|---|---|
| Focus composer | cmd+l | — |
| New session | cmd+shift+k | allowed |
| Stop generation | cmd+. | allowed |
| Toggle sidebar | cmd+b | allowed |
| Open details panel | cmd+shift+e | allowed |
| Close details panel | unbound | — |
| Previous session | cmd+[ | allowed |
| Next session | cmd+] | allowed |
| Toggle theme | unbound | — |
| Scroll to top | unbound | — |
| Scroll to bottom | unbound | — |
| Fork session | unbound | — |
Actions without a safe default ship unbound; record a combo in the settings page to activate one, and reset clears it back to unbound. Defaults deliberately avoid browser-reserved combos (cmd+n/t/w, cmd+shift+n/t/w/i/j/c, cmd+alt+i/j/u): those trigger the browser's own behavior before any page listener can preventDefault, so a web plugin can never bind them (desktop apps like Codex can — which is why its keymap cannot be copied verbatim). Option/Alt is likewise unusable for letters and brackets on macOS: it rewrites the produced character (cmd+alt+c yields ç), so event.key no longer matches the registered key.
Settings page
Open Settings → 快捷键. Each row shows the action, its current combo, and a hit counter. The record control pauses registry dispatch (so the pressed combo is captured, not fired), validates conflicts against existing bindings, and rejects malformed combos. Rebindings live for the plugin fiber only — a page reload restores the defaults (persistent storage is a deferred phase).
Install
The package is a bundle (declares dsh.bundle), so installing it also activates its layer:
# published tarball / npm package
dsh plugin --profile web add @blue-a11y/dsh-client-shortcuts
# or a local checkout / packed tarball
dsh plugin --profile web add ./dsh-client-shortcuts
Restart dsh web once after adding (plugin-row discovery is cached per boot); later source rebuilds hot-reload through the client HMR path.
Develop
pnpm install
pnpm run build # tsc (lib/types) + tsdown (lib/index.js, lib/invariant.js, lib/client.js)
pnpm test
The client bundle externalizes react and @deepseek-ai/dsh-client-ui-primitives — both resolve from the shell's module table at runtime. prepare runs the same build, so git-hosted installs (dsh plugin add github:...) build from source — pnpm ≥ 10 asks the profile to allow this build once via allowBuilds in its pnpm-workspace.yaml.
Model Experience
None, as the shortcuts service only relays browser keyboard gestures into UI actions; nothing here reaches a model request.
Known Limitations and Deferred Work
- Rebindings are not persisted — they live for the plugin fiber and reset on reload; a
settingsNamespaceschema is the planned home for durable bindings. - Composer focus finds the textarea by
[data-phase]— a DOM query rather than a service edge, because no composer exposes a focus service; if the composer gains one, migrate. - Stop only targets the current session — the
conversation.cancelservice is per-session scoped; a whole-queue steer is not reachable from a global listener.