dsh-composer-keys
Verifieddsh-composer-keys · v0.1.1 · MIT · Web UI
为 DeepSeek Harness Web 的聊天输入框自定义发送与换行键位:Enter / Ctrl+Enter / Shift+Enter / 任意自定义组合键可自由分配给「发送」或「换行」,默认保持 DSH 原生行为;忙碌时的排队/转向语义仍由原生「繁忙时 Enter 键行为」设置决定。Customizable send & newline key bindings for the DeepSeek Harness web composer: assign Enter, Ctrl+Enter, S
Install
dsh plugin add dsh-composer-keys Confirm the layer applied with dsh --profile default --dump-config — see the install guide.
Source
Tags
Creators
Readme
dsh-composer-keys
⚠️ AI 生成声明 / AI-Generated Notice 本项目(代码、文档、测试)由 AI 助手(DeepSeek Harness 智能体) 生成,经人工在真实环境中测试验收。 This project (code, docs, tests) was generated by an AI assistant (a DeepSeek Harness agent) and manually verified against a live environment.
把「发送」和「换行」分配给你顺手的键 / Assign send & newline to the keys you like
中文 | English below
dsh-composer-keys 是 DeepSeek Harness Web 前端的输入框按键自定义插件:把 Enter、Ctrl/Cmd+Enter、Shift+Enter 或任意自定义组合键(如 Ctrl+S、Alt+Enter)自由分配给「发送」「换行」「打断」三个动作。
默认保持 DSH 原生行为——装上插件后一切照旧,只有你主动改绑才会变化。
效果图


特性
- 自由分配:「发送」「换行」「打断」各自绑定任意一组组合键;同一按键不能同时属于多个动作(录制时自动迁移,优先级:发送 > 换行 > 打断)。
- 任务打断:「打断」中断当前打开会话正在运行的任务,等同于输入框的停止按钮——走同一条原生取消管线(含子代理地址路由)。任务运行时在页面任意位置生效;对话框/菜单打开、输入法组合中自动让路;空闲时按下不吞键、零副作用。默认无绑定。
- 快速预设:
DSH 原生(Enter=发送 / Shift+Enter=换行 / Ctrl+Enter=加速提交)与微信风格(Ctrl+Enter=发送 / Enter 或 Shift+Enter=换行)一键切换。 - 两处入口:Settings → General 的「输入框按键」一行;聊天输入框工具行右侧的小键盘按钮。两者打开同一个配置面板。
- 持久化:键位存入 DSH 用户设置文档的
composer-keys命名空间——与主题、语言等原生偏好同一条通道,重启保留、跨设备跟随用户文档。 - 深浅色自适应:面板样式全部引用 DSH 官方语义 token,随主题自动切换。
- 即时生效:改绑后无需刷新页面。
与原生「繁忙时 Enter 键行为」设置的关系
两层机制正交,互不冲突:
| 层 | 归属 | 管什么 |
|---|---|---|
| 手势 → 动作 | 本插件 | 哪个键触发「发送」、哪个键触发「换行」 |
| 动作 → 忙碌语义 | DSH 原生 | 智能体忙碌时提交是「排队」还是「转向」(即原生的 busy-Enter 设置) |
具体衔接规则:
- 命中「发送」的手势会被重放为一个合成的普通 Enter 键事件,由 DSH 原生的提交管线完成发送——斜杠菜单仲裁、空草稿防抖、忙碌时的排队/转向判断全部保持原生逻辑;
- 只要键位偏离出厂默认,所有发送键(含 Ctrl/Cmd+Enter)统一遵循原生设置的「本值」行为——忙碌时按主设置排队或转向,不再保留 Ctrl/Cmd+Enter 的"另一行为"反向特性;
- 仅当键位保持出厂默认时,插件完全不介入,一切手势(含 Ctrl/Cmd+Enter 的反向特性)保持纯原生。
一句话总结:插件决定"哪个键发送",原生设置决定"忙碌时发送意味着什么"。
安全与边界
- 零干预默认:键位等于出厂默认时,所有原生手势直接放行,插件对页面没有任何行为影响;一旦改绑(含预设),全部已绑定手势统一接管并按普通 Enter 重放。
- 输入法安全:中文/日文等 IME 组合输入期间的 Enter(选字)永远不会被拦截。
- 范围最小:只作用于主聊天输入框(依赖其稳定的 DOM 锚点
[data-input-scroll]);审批面板、会话重命名框等其他输入区域不受影响。无活动会话的首屏(hero 界面)不渲染工具按钮属正常行为。 - 无循环风险:插件自己重放的合成事件通过
isTrusted=false识别并放行。 - 优雅降级:settings 或 slots 服务不可用时,键盘引擎仍然工作(仅失去持久化或 UI 入口)。
安装
从本地 clone 安装:
dsh plugin --profile web add /path/to/dsh-composer-keys
Git Bash / MSYS 下请使用正斜杠路径(如
D:/net/GitHub/dsh-composer-keys),反斜杠会被转义吞掉。
重启 dsh web 后生效。卸载:
dsh plugin --profile web remove dsh-composer-keys
已在 DSH 0.1.1-rc.2(Node 26, Windows 11, pnpm 11 hoisted profile)上验证。
使用
- 打开 Settings → General 找到「输入框按键」行(或点击输入框右下角的小键盘图标),点「配置…」;
- 在「发送」「换行」「打断」区块点「+ 录制按键」,然后按下想要的组合键(Esc 取消;录制打断键时按 Esc 即绑定 Esc,取消改为再点一次按钮);
- 点击已录制的键位标签上的 × 可移除;清空「发送」的全部键位后只能通过发送按钮发送(面板会提示);
- 底部预设一键回到「DSH 原生」或切换「微信风格」。
工作原理
- 浏览器半件是手写的 lazy-CJS bundle(
window.__ModuleLoader__.load({id, factory})),无构建步骤; - 宿主半件只做一件事:向 Host 设置服务注册
composer-keys命名空间 schema,让浏览器半件的ctx.settingsScope.bind()可以读写持久化配置(apiproxy 对所有注册命名空间一视同仁地提供给 Web 端); - 客户端插件的 inject 契约:工厂必须返回
{ apply, inject: ['locale', 'slots', 'settingsScope'] }——vendored cordis 对未声明服务的属性访问会直接抛cannot get property X without inject,导致整个 entry 引导失败(页面横幅 "Failed to load plugins")。这是本插件踩过的坑,写在这里给其他插件作者参考; - 「发送」=重放合成普通 Enter(见上文两层语义);「换行」=在 DSH ≥0.1.5 的 Lexical 编辑器中,从当前编辑器的命令注册表取出
INSERT_LINE_BREAK_COMMAND对象本身并 dispatch,保持草稿、选区及撤销历史同步;旧 textarea 仍使用原生编辑和 value setter 回退。命令按对象身份匹配,不能传命令名字符串,也不能用另一份 Lexical 导入的同名对象; - 面板样式仅引用真实存在的 DSH token(
--dsw-alias-bg-layer-*、--dsw-alias-border-l*、--dsw-alias-label-*、--dsw-alias-interactive-bg-hover、--dsw-alias-brand-primary、--dsw-alias-bg-mask-1)。
已知限制
- DSH 大版本升级若改变输入框 DOM 结构(目前锚点是
[data-input-scroll])或调整语义 token 名,拦截/配色可能失效。Lexical 换行适配依赖__lexicalEditor、_commands与命令的type标签:若宿主不再提供这些字段或命令拒绝处理,插件会阻止已绑定的换行键并输出控制台警告(避免 Enter 意外发送草稿),不会绕过编辑器直接修改 DOM; - 极端自定义主题下对比度可能欠佳(token 兜底为浅色值)。
English
A DeepSeek Harness web-composer plugin that assigns any chord — Enter, Ctrl/Cmd+Enter, Shift+Enter, or custom ones like Ctrl+S — to the Send, Newline, or Interrupt actions. Ships with native behavior by default; nothing changes until you rebind.
- Two presets: DSH native and Chat style (Ctrl+Enter sends; Enter/Shift+Enter newline), plus free per-action recording with automatic cross-action migration.
- Interrupt aborts the open session's running task through the same native cancel pipeline as the composer stop button (subagent-address routing included). Works anywhere on the page while a task runs; yields to dialogs/menus/IME; idle presses pass untouched. Unbound by default.
- Bindings persist in the user-settings document (
composer-keysnamespace); two entries into one panel (Settings → General row + composer toolbar keyboard button). - While busy, queue-vs-steer follows the native "Busy Enter behavior" setting uniformly for every bound send key once bindings deviate from defaults.
- Theme-aware styling via official DSW semantic tokens; zero-intervention while bindings stay pristine; synthetic replays are
isTrusted=false; IME composition never intercepted.
Install: dsh plugin --profile web add /path/to/dsh-composer-keys, then restart dsh web.
AI-generated notice: this project was generated by an AI assistant and verified manually in a live environment.
开发 / Development
npm test
测试用 Node 内置测试运行器直接评估 client.js 的真实源码(提取其中的纯手势引擎与换行路径),无需构建、无第三方依赖。覆盖:手势归一化、绑定解析(含 mod 别名)、动作解析、零干预判定、互斥迁移、脏数据清洗、显示格式化,以及 Lexical 命令对象身份匹配、不可用时防误发送、IME/合成事件放行。
本地浏览器回归(本地工具,不写入 package.json):playwright-core 从本地安装 / $PLAYWRIGHT_CORE_PATH / npm 全局目录自动解析,浏览器自动探测系统 Chrome/Edge(CHROME_PATH 可显式指定):
node test/newline-regression.mjs '<本地 dsh-client-ui-conversation/lib/client.js 的绝对路径>'
该脚本针对本地 DSH bundle 的 Lexical 和原生 composer keymap 建立隔离页面,以真实浏览器按键验证换行、发送回调、选区替换和撤销/重做;不启动 DSH 服务、不改用户设置、不发起模型请求,不等同于完整在线 GUI 部署验证。
新版换行兼容修复(DSH ≥0.1.5)
修复了 DSH 0.1.6-alpha.1 中自定义换行失效:旧实现用字符串 dispatch Lexical 命令(Lexical 按对象身份匹配命令,字符串永远失配),且 DOM 编辑回退可能不同步编辑器状态。新实现使用当前编辑器注册的命令对象;命令不可用时阻止已绑定的换行键,避免 Enter 意外发送草稿。已在 DSH 0.1.6-alpha.1(Node 26, Windows 11, pnpm 11 hoisted profile)上验证。更新插件后重启加载该插件的 dsh web 并刷新浏览器即可;此插件为手写浏览器 bundle,无需额外编译。