DeepSeek Harness Plugin Hub

发布与管理完整 Harness Profiles,发现适合你的插件。

探索

插件目录环境预设文档中心动态

社区

发布插件联系我们报告问题

相关链接

Plugin Hub GitHubDeepSeek Harness 官方项目系统状态隐私说明
© 2026 DeepSeek Harness Plugin HubPowered byPaxTech

独立、非官方社区项目,与 DeepSeek 官方无隶属、授权或背书关系。

Keys Setting — DeepSeek Harness 插件(DSH Plugin)
DeepSeek Harness Plugin Hub
ProfilesPlugins分类动态文档登录管理 Profiles
ProfilesPlugins分类动态文档登录
← Plugins
K

dsh-keys-setting

Keys Setting

DeepSeek Harness 插件:在“设置”窗口的“常规”页面中,选择 Enter、Shift+Enter 和 Ctrl/Cmd+Enter 是发送消息还是插入换行符。

插件会安装到这里;不确定时保持 web。

npx -y @deepseek-ai/dsh plugin --profile web add github:itchenshi/dsh-keys-setting#304366ffe148406ba463412617b4806ce84cdce3
README兼容性版本

兼容性与来源证明

Keys Setting 以 dsh-keys-setting 发布,当前版本为 0.2.0。Plugin Hub 会校验它的 manifest,并保存精确安装来源,便于复现安装结果。

DSH 兼容范围
*
运行环境
web
发布来源
github
Registry 更新时间
2026/9/21

版本

0.2.0stable
2026/9/21

相关插件

正在加载相关插件…

最新版
0.2.0
DSH
*
HMR
重启进程
Tree shaking
未声明可安全裁剪
解包体积
未提供
文件数
未提供
Surface
web
许可证
MIT
发布源
github
GitHub
★ 0
周下载
0
最近提交
2026/9/25
查看源码 ↗
README Badge

点击下方 Badge 复制 Markdown,粘贴到 README 即可。

这是你的 Plugin?认领权益 · 优先安全扫描

验证 package.json 声明的 GitHub 仓库,即可管理这个公开页面。认领后,Hub 会优先安排当前版本的安全扫描,并在通过后公开展示结果。

认领这个 Plugin →
报告问题

相关插件

继续浏览 productivity-workflow 分类下经过校验的插件。

Acp App@deepseek-ai/dsh-acp-appdsh ACP 配置文件包:基于 dsh-base 的仅限自动化的 JSON-RPC stdio 和进程生命周期管理Web All@linxin666/dsh-web-allDSH Web UI 全家桶聚合插件:一键安装全部功能插件(task-board / git-graph / pet / remote-web-ui / web-ui-settings / skin-center / community-plugins / compat shim)。compat 桥接层已并入本包(src/client),无需独立 compat npm 包。Codex Ui@michengai/dsh-codex-uiDSH Codex UI — 为 DeepSeek Harness Web 提供 Codex 风格侧栏、工作区会话树、全局搜索和轮次导航Univer Officedsh-univer-officeDSH × Univer 集成,内置协作 Gateway 和 Viewer:内联预览、实时浮动 Worktree 窗口,以及 DeepSeek Harness 中的会话结束审查操作。

README

dsh-keys-setting

在 DSH 设置窗口 → 通用 里配置输入框的快捷键:Enter / Shift+Enter / Ctrl+Enter(macOS 为 ⌘) 各自设为「发送消息」或「换行」。

设置 → 通用
  ┌──────────────────────────────────────────────────────────┐
  │ 按键设置                                                  │
  │ 设置 Enter / Shift+Enter / Ctrl+Enter 是发送消息还是换行   │
  │                                    Enter       [发送消息 ▾] │
  │                                    Shift+Enter [换行     ▾] │
  │                                    Ctrl+Enter  [发送消息 ▾] │
  └──────────────────────────────────────────────────────────┘

默认值 = 引擎原生行为

未改动时插件的干预次数为 0,行为与不装插件完全一致:

手势引擎原生本插件默认
Enter发送发送
Shift+Enter换行换行
Ctrl/Cmd+Enter发送发送

Ctrl+Shift+Enter 归入 Shift 手势(引擎键位表里 Shift 规则先匹配)。

实现方式(要点)

  • 只在「你的选择 ≠ 引擎原生」时才拦截:捕获阶段监听 composer 的 keydown, 命中时 preventDefault + 重新派发引擎自己的另一种手势(合成 Shift+Enter 或合成 Enter)。 换行/发送的语义仍由引擎决定,插件不碰编辑器内容。
  • 识别 composer 用引擎的语义属性 data-composer-input="true"(不是哈希类名,也不是「任意 contenteditable」), 所以不会误伤侧边栏插件自己的编辑器。
  • 绝不干扰输入法:isComposing 或 keyCode === 229 的事件直接放行。
  • Alt+Enter 完全放行(那是引擎自己的加速手势)。

合成的(isTrusted: false)键盘事件确实能驱动引擎的 composer —— 这一点在真实页面上 用 CDP 对照验证过:可信的 Shift+Enter 与合成的 Shift+Enter 产生了完全相同的 DOM 变化 (插入 <br data-lexical-managed-linebreak="true">),合成的 Enter 也真实提交了消息。

两半

半边文件运行在职责
宿主lib/index.jsNode用引擎设置服务注册 composer-keys 命名空间(值落在 settings.yaml,随数据目录走),并对外开放 GET/POST /composer-keys
页面client/client.js浏览器注册「设置 → 通用」那一行 + 捕获阶段做键位重映射

路由受引擎的信任围栏保护(Host 白名单 + 浏览器会话 cookie):它既读也写这份偏好, 所以不带 cookie 的裸 curl 会得到 401 unauthorized。同源页面请求自动带 cookie;手工调用 需先换一次会话 cookie(示例见 dsh-gui-last-session/README.md)。围栏实现在无依赖的 lib/shared.js(rejectUntrusted),有单测覆盖 fail-closed 与 401/403 映射。

为什么要宿主半边:页面来自每次启动都变化的随机端口(外壳用 dsh web --port 0), 浏览器存储等于每次换源、存不住;而引擎的设置文档才是持久且随数据目录迁移的地方。 页面半边拿不到插件自有命名空间(设置 RPC 域只对配置客户端提供固定命名空间), 所以由宿主路由转交——与第三方侧边栏插件为自身偏好所用的方式一致。

配置

偏好存在 $DSH_HOME/settings.yaml 的 composer-keys 段,可以直接手改:

composer-keys:
  enter: newline       # Enter 换行
  shiftEnter: newline  # Shift+Enter 换行(默认)
  ctrlEnter: send      # Ctrl+Enter 发送(默认)

手改文件后切回 Harness 窗口即生效(插件在窗口重新获焦时重读),无需刷新页面; 在设置窗口里改则立即生效。

插件行的开关(可选,写在 cordis.patch.yml 的行 config 里):

- insert:
    - id: composer-keys        # 行 id 与包名解耦,刻意保持不变(见下)
      name: dsh-keys-setting
      config:
        enabled: true    # false 时完全不加载(既不注册路由也不加设置行)

安装

dsh plugin --profile web add dsh-keys-setting

装完重启 dsh web(或重开 DSH GUI),设置窗口「通用」页最下方即可看到 「按键设置」。在 DSH GUI 里也可以在「设置窗口 → 第三方插件」里勾选同一个包。

关于包名:本插件最初叫 dsh-composer-keys,但那个名字在 npm 上已被其他作者 占用,现在的包名是 dsh-keys-setting。

行 id 与设置命名空间仍是 composer-keys,这是刻意的:补丁层的禁用行、市场 state.json 里的开关,以及 settings.yaml 里你保存的键位都记在这个名字下。 包名只是安装时用的标识,改它不该让你已有的键位设置或启用/禁用选择失效。

升级由 DSH GUI 的启动维护自动完成(旧包名会被摘掉、禁用选择会被搬到新包上)。

权限、依赖与失败边界

会把仓库固定到某个 commit 再审查的商城(DSH STORE 之类)会对运行时代码做静态扫描, 并按检测到的信号给出权限结论。这里把事实一次写清,免得被推断:

  • 运行依赖:schemastery(纯 JS 的 schema 校验库,无原生制品、无安装脚本)。 宿主半边用它向引擎的设置服务注册本插件命名空间的 schema。这是本插件唯一的 dependencies。
  • 文件:本插件不直接读写任何文件。 偏好值通过引擎自己的设置服务落到 $DSH_HOME/settings.yaml —— 源码里没有 node:fs。扫描器报的「files 信号」 来自这个经由 settings 服务的间接写入(以及代码注释里对 settings.yaml 的说明), 不是直接的磁盘操作。
  • 本机路由:有,一条。 宿主半边注册 GET/POST /composer-keys,供页面半边读写偏好 —— 页面拿不到插件私有的设置命名空间(设置 RPC 域只服务固定命名空间),这是唯一的 通道。该路由走引擎自己的信任围栏(Host 白名单 + 浏览器会话 cookie),拿不到围栏时 fail-closed。
  • 出站网络:无。 页面半边的 fetch 只打上面那条同源路由。
  • 凭据 / 命令 / 原生制品 / 生命周期脚本:无。
  • 失败边界:路由或 settings 服务不可用时,键盘引擎仍然工作(只是失去持久化或 设置入口)——属于降级而不是崩溃。卸载后 settings.yaml 里的 composer-keys 命名空间会留下,重建插件即恢复原设置。

设置行样式(沿用通用页)

字体、颜色、间距与选择框都逐条沿用通用页其它行的声明:

  • 行外壳与排版取自引擎的 settings.general.item 行(.row/.rowText/.title/.desc/.selector);
  • 选择框与「对话显示」那一行的控件完全一致——同样是 <button> 胶囊 + 箭头 SVG + 弹层, 而不是原生 <select>(原生控件会画自己的箭头与内边距,怎么调都对不上,所以第一版被替换掉了);
  • 弹层取自引擎 Menu 组件(._list_/._portal_/._item_/._itemLabel_/._check_):圆角 20px、内缩 4px、 最小宽 218px、position:fixed、z-index:1100,条目 40px 高 / 8px 10px 内边距 / 圆角 10px, 选中项用对勾图标标记。
元素声明
标题14px / 400 / var(--dsw-alias-label-primary),行高 22px
描述12px / var(--dsw-alias-label-tertiary),行高 18px
行容器padding:16px 0,底部 0.5px solid var(--dsw-alias-border-l2)
胶囊选择框height:36px、border-radius:18px、padding:0 14px、gap:12px、background:var(--dsw-alias-bg-module-platform)、悬停 --dsw-alias-interactive-bg-hover
弹层面板var(--dsw-alias-bg-base)、圆角 20px、内缩 4px、最小宽 218px

全部颜色走引擎主题变量,深浅色主题自动跟随。

实测(真实设置弹窗内取计算样式):胶囊的高度 / 圆角 / 背景 / 内边距 / 字号 / 行高 / 间距 / 颜色 8 项与「对话显示」的控件逐项相等;弹层的圆角、内缩、最小宽、定位、层级与条目尺寸也全部一致; 点选后配置确实写回(settings.yaml 的 composer-keys 段)。

底部分隔线实测不显示,这是引擎自己的规则: ._WvWnq_section > [data-slot="settings.general.item"] > :last-child { border-bottom: medium } 会去掉该列表最后一行的分隔线;本行 order=21 排在引擎 composer-Enter 行(order=20)之后,因此被同等对待。

刻意不 import 引擎的 UI primitives(那样能直接用同一个 Menu 组件):在 dsh.client.inject 里声明 引擎客户端包会让整批 bundle 重复注册(仓库里已记录过这个坑),模块加载器也会拒绝在它启动前请求的外部模块。 因此这里按引擎的 CSS 声明重写了一份等价控件。

开发

node --check lib/index.js
node --check client/client.js
npm test        # 本地行为测试(无网络、无引擎、无 DOM)

tests/test.mjs 覆盖:手势识别(含 Ctrl+Shift 折叠、Alt 放行)、 三种手势 × 两种动作的干预判定、输入法放行、非法偏好值不干预、 以及「默认值不干预」这一关键性质。

License

MIT