dsh-chat-actions
English
单独显示或隐藏 DeepSeek Harness 每条助手回答底部的按钮,并把隐藏掉的按钮收进一个 ⋯,点一下就能用。
管哪些按钮
DSH 自带按钮在设置页里的措辞(开关按回答底部实际出现的按钮生成):
| 开关 | 对应按钮 |
|---|---|
| 复制 | 复制回答全文 |
| 好评 | 标记为「好的回答」 |
| 差评 | 标记为「有问题的回答」 |
| 分支 | 在新对话里从这条回答继续 |
| 用量 | 本轮 token 用量明细(仅当这颗芯片没有文字、只能按位置认时) |
按住设置页里的任意一行拖动可以调整它在回答底部的顺序,松手即保存,对每条回答都生效。时间戳也算一项:它不能点击,但同样可以隐藏、可以排序。
代码块右上角的复制按钮属于编辑器,不在这一行里,本插件不会动它。
设置页列的是回答底部真实出现的按钮:先让一条助手回答渲染出来,它带着哪几个按钮,设置页就长哪几个开关(官方那五个用下面这套中文措辞,其余的按按钮自己的名字)。所以不会出现「没用、管不到东西」的开关,也不会把同一个按钮列两次——例如用量那颗芯片本来就带文字,它只会作为自己名字出现一次,不再额外多一个「用量」。
收进「⋯」
设置页第一个开关,默认开启:
- 开 — 被关掉的按钮从行动行消失,收进
⋯按钮下面的小弹出层。鼠标移到弹出层里的按钮上仍然会显示名字:弹出层在⋯下方时用官方那颗标签气泡,在⋯上方时(最后一条回答贴着输入框,只能往上翻)把同样的字画在图标上方——这样弹出层就能紧贴⋯,不必为气泡留大空档。 - 关 — 关掉的按钮就直接消失,连
⋯也不出现。 - 所有按钮都可见时这个开关是禁用的:没有东西可收,聊天里也不会渲染
⋯。
设置在设置抽屉里独立一项:设置 → dsh-chat-actions。状态存在 $DSH_HOME/dsh-chat-actions.json(默认 ~/.dsh/dsh-chat-actions.json),不用 localStorage——Web GUI 每次启动换端口,按 origin 存的开关活不过一次重启。
安装
需要会加载插件包(package.json 里的 dsh.bundle)的 DeepSeek Harness。
在本目录下的 agent 会话里执行:
plugin_manager action=install_bundle target=/绝对路径/dsh-chat-actions
Harness 会把这个目录以 link: 方式链进当前 profile,所以改的是本目录源码,不是拷贝。装好后在「插件」页能看到这个 bundle,设置里也会多出对应的一项。
改动生效方式:
client.js和locale/*每次打开页面都会重新加载——刷新 GUI 即可(⌘R / Ctrl+R)。index.js是宿主那一半,只在插件启动时运行——把 bundle 关掉再打开(plugin_manager action=set_bundle target=dsh-chat-actions enabled=false,再enabled=true),或者重启 Harness。
卸载:plugin_manager action=remove_bundle target=dsh-chat-actions,或在「插件」页里移除。
自检
npm test
tests/self-check.mjs 用假的模块加载器和 fetch 跑一遍客户端代码,检查生成的样式表(每个关掉的按钮一条隐藏规则、⋯ 的展开规则与格子位置)、sanitize() 会丢掉未知字段,以及两个 slot 的注册。
已知限制
- 按钮先按名字认(
aria-label→title→ 文字),认出来的每个按钮打上data-dca-key,样式表只认这个属性,所以官方在行里插按钮、顺序怎么变都不会错位。只有完全没名字的图标按钮才退回位置匹配(行内第一个/最后一个直属按钮、唯一带aria-haspopup="dialog"的、反馈槽里前两个),client.js里用shortcut:注释标了这段兜底。 - 认按钮发生在渲染那一帧之前(MutationObserver 回调里先打标、再写样式表),新加的按钮不会先闪一下再消失;设置页里要等一条回答渲染过一次才会列出开关(没渲染过时页面上是一行提示)。
- 名字里的数字归一化(
Usage 129K tok→Usage #K tok),所以实时计数不会每变一次就多一个开关;代价是名字只差数字的两个按钮算同一个开关,名字完全相同的两个按钮也共用一个。 - 某个按钮以后不再出现时,它的旧状态仍留在
$DSH_HOME/dsh-chat-actions.json的extra里(最多 24 个),但不会再出现在设置页,因为开关列表来自当前渲染出来的按钮。 ⋯弹出层是按实测坐标摆的(格子 24px、卡片 32px)。格子里的文字会被裁掉只留图标,名字在 hover 时照常显示。- 排序只展平行的直属包装层。用量芯片外面还有一层自带盒子,宿主自带的用量弹层正是量这个盒子来定位的,所以它必须保留原样:
order落在"行里真正的那个 flex 项"上(data-dca-slot),而不是按钮本身。 - 带自己弹层的按钮(用量芯片)不参与收纳:它被关掉就是直接消失。宿主的用量弹层量的是芯片自己那个盒子,一旦被搬进
⋯里的格子,位置就只剩左上角那一格。 - 用量芯片和时间戳共用一个包装层,所以这两项在排序里是一个整体:以先出现的那一项为准。