English · 简体中文

dsh-keyboard-manager 像素风控制室:将 Ctrl+Q、Ctrl+E、Ctrl+S 路由到原生或插件面板。

CI 状态 许可证:MIT

为 [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness)(`dsh`)Web UI 提供快捷键 —— 一个监听器,三个聚焦的快捷键,并且会根据当前实际存在的右侧面板选择原生路径或插件路径。 ## 快捷键 | 按键 | 功能 | |---|---| | `Ctrl+Q` | 切换 DSH 原生左侧栏 | | `Ctrl+E` | 切换右侧栏:安装了 [dsh-better-sidebar](https://github.com/omdsh-dev/DSH-better-sidebar) 时控制 Files / git / terminal / browser 等插件面板,否则控制原生会话详情栏 | | `Ctrl+S` | 打开 / 关闭设置面板 | ### 行为边界 - **只匹配严格组合键**:必须是单独的 `Ctrl`,带 `Cmd` / `Shift` / `Alt` 时不触发;`Cmd` 组合保留给浏览器或操作系统。 - **不抢页面事件**:IME 输入、按键自动重复、已经被其他监听器消费的事件都会让路。 - **`Ctrl+S` 让给 better-sidebar 编辑器**:焦点位于插件面板内时,交给它自己的 `Ctrl/Cmd+S` 保存逻辑。 - **`Ctrl+E` 需要已选中会话**:插件面板和原生详情栏都是会话级界面。

三个快捷键经过同一个捕获阶段监听器,分别路由到原生布局服务、可选插件面板或原生详情栏回退,以及设置面板按钮。

## 安装 默认是 `Ctrl+Q` / `Ctrl+E` / `Ctrl+S`。物理键码可在 profile 补丁里覆盖,见下方「快捷键配置」。 ```sh dsh plugin --profile web add github:Aafff623/dsh-keyboard-manager ``` 安装后硬刷新浏览器(`Ctrl+Shift+R`)。`dsh.bundle.patch` 会把插件加入 profile bundle,不需要改 profile 文件。 `lib/` 是有意提交入库的:git 安装无需构建。改 `src/` 后执行 `npm run build`,并把刷新后的 `lib/` 一起提交;CI 会检查是否过期。 ## 它是怎么工作的 DSH 的 layout service 提供了动作,但不提供状态读取;设置模态框的开关状态也只存在于组件内部。因此插件使用**稳定的 DOM 标记和界面自身的按钮**,不碰 React 内部状态,也不依赖哈希 CSS 类名。标记不存在时会静默 no-op,不会误触发。

一个捕获阶段 keydown 监听器校验严格 Ctrl 快捷键,检测当前面板,并调用原生服务或插件自己的按钮。

- **`Ctrl+Q`**:直接调用 `ctx.layout.toggleSidebar()`。 - **`Ctrl+E`**:检测到 dsh-better-sidebar 时,点击 `[data-dsh-toggle-cluster]` 里的右侧栏开关(优先 `aria-label` / `data-panel` 含 `right` 的按钮,否则用最后一个);没有插件时,调用 `ctx.layout.openDetails()/closeDetails()`,并通过 `[data-shell-overlay]` 读取 `data-details-collapsed` 判断方向。 - **`Ctrl+S`**:打开时点击侧栏设置按钮;关闭时派发带 `code: Escape` 的 document 级别 `Escape`,复用设置面板自己的关闭路径。 ### 快捷键配置 默认绑定为 `KeyQ`、`KeyE`、`KeyS`。三个物理键码都可通过插件配置覆盖: ```yaml # ~/.dsh/profiles/web/cordis.patch.yml(profile 自己的补丁层) - id: dsh-keyboard-manager config: sidebar: KeyQ rightPanel: KeyE settings: KeyS ``` 配置会校验键码格式(`/^[A-Z][A-Za-z0-9]+$/`),并拒绝重复键码;无效配置回落到默认值。改完重启 `dsh` 并刷新页面生效。 **配置如何到达浏览器**:DSH 的 web 启动流程挂载客户端半区时不传插件配置(`loader.create({ name })`),浏览器端 `apply` 的第二个参数永远是 `undefined`。因此 node 半边把配置以 JSON 形式挂在 `/plugin-config/dsh-keyboard-manager` 路由上,浏览器半边激活后拉取一次并热更新绑定;拉取失败或无头 profile 下保持默认键位,不影响使用。 ### DOM 合约 插件只依赖以下集中登记的稳定标记(均已对照 `dsh-client-ui-layout` 与 `dsh-better-sidebar` 源码核实): | 标记 | 来源 | 用途 | |---|---|---| | `[data-dsh-toggle-cluster]` | dsh-better-sidebar | 右侧栏按钮组 | | `[data-dsh-panel-host]` | dsh-better-sidebar | Ctrl+S 让路给编辑器的范围 | | `[data-shell-overlay]` | dsh-client-ui-layout | 原生 AppFrame 锚点 | | `data-details-collapsed` | dsh-client-ui-layout | 原生详情栏当前折叠状态 | | `button[aria-haspopup="dialog"]` | dsh-client-ui-settings-general | 设置按钮 | ## 开发 ```sh npm install npm run typecheck # tsc --noEmit npm run build # esbuild → lib/index.js + lib/client.js(ModuleLoader wrapper) npm test # node:test,vm 隔离的 fake-DOM 测试 ``` 插件采用 DSH 标准双半结构: - `src/index.ts`:node / host 半边(把插件配置挂成 JSON 路由,供浏览器半边拉取) - `src/client/index.ts`:浏览器半边(全部快捷键逻辑) - `lib/client.js`:包在 `window.__ModuleLoader__.load()` 工厂形态里的浏览器产物 - `cordis.patch.yml`:把插件插入 bundle 的配置 不安装到 profile,直接用当前 checkout 做开发覆盖: ```sh dsh web --patch D:/code/dsh-plugin/dsh-keyboard-manager/cordis.dev.yml ``` ## 兼容性 - 需要 DSH Web UI 和 `@deepseek-ai/cordis ^4.0.2`。 - `dsh-better-sidebar` 是**可选插件**:不安装时,Ctrl+E 自动回落到原生详情栏。 - `Ctrl+S` 的保存让路依赖 better-sidebar 编辑器;在其他界面中仍按全局设置快捷键处理。 ## 许可证 [MIT](LICENSE)