Bundle
dsh-shutup
Shutup · 打断提示:模型思考/输出时按下快捷键立即打断当前生成并弹出输入框,载入你的修正提示(steer 注入当前回合),像 Claude Code 的 Tell Claude。快捷键可在 设置 → 通用 中录制修改。
- Source
- DosterBool
- License
- MIT
- Updated
- Updated 2 days ago
Readme
# dsh-shutup · 打断提示(Tell DeepSeek)
DeepSeek Harness 插件:模型思考/输出时按下快捷键——弹出纠偏输入框(输入才暂停),输入纠偏提示(二次确认)或空确认继续;**继续时的思考链回填以"可折叠上下文行"呈现,不占界面**。像 Claude Code 的 Tell Claude 一样。
## 使用
1. 模型思考/输出中(状态条会显示快捷键小提示 `⌨ 打断 Ctrl+Shift+Q`)
2. 按下快捷键(默认 **Ctrl+Shift+Q**,用物理键匹配、CapsLock 不影响,且避开空格键——Shift+空格=中文输入法全半角切换会被 IME 层拦截)→ 弹出输入框(**未输入不暂停**,模型继续想)
3. 三种操作:
- **开始输入** → 瞬间暂停当前生成;点「载入纠偏」→ 按钮变红「确认载入纠偏?」→ 再点一次才真正发送(steer 中止运行中的回合并注入为新一步,自动加前缀「[打断提示/纠偏]:」,4 秒不点自动还原)
- **空输入确认** → 从未输入过:直接关闭、模型从未被打断;输入过又删空:发送一句「[继续]」,思考链回填以**折叠的上下文行**注入(折叠=一行,展开=全文),模型拿到完整上下文
- **取消 / Esc / 点空白处** → 未输入过:直接关闭零干扰;输入过:同上发送「[继续]」并关闭弹窗
其他时间(模型未运行)快捷键自动禁用,用户可以正常在输入框打字。
### 输入法(IME)兼容
- 中文输入法激活时也能正常触发:匹配只用 `e.code` 物理键 + 修饰键(IME 下 keydown 的 key/229 不影响触发)
- 输入法组合期的回车/Esc 全部交给输入法:拼音输入中按回车确认候选词**不会**误触发发送,按 Esc 取消候选**不会**误关弹窗
- CapsLock/大小写状态不影响触发
- **防误触只在"正在连续打字"时生效**:仅当 1.5s 内刚在输入框敲过字才把快捷键当作普通输入;发送消息后焦点停留在输入框、或只是点开过输入框没打字,快捷键都照常触发——不会再出现"时不时失效"
## 修改快捷键
设置 → 通用 → **打断提示 (Shutup)**:
- 点「修改快捷键」→ 直接按下新组合键(按下即捕获,录制 `e.code` 物理键)
- **快捷键必须包含 Ctrl / Alt / Meta 至少一个**:纯 Shift+字母(如 Shift+A)与正常打字结构性冲突(聊天时输入大写字母既是快捷键又是打字),录制时会拒绝;已存的无修饰键配置自动回退默认
- 「恢复默认」恢复 Ctrl+Shift+Q
- 配置存浏览器 localStorage(`dsh-shutup-config`,旧版单快捷键/含空格配置自动迁移)
## 实现机制
- 客户端 + 最小宿主(`/shutup/backfill` 一次性上下文注入)
- **输入才暂停**:弹窗内输入第一个非空字符时调用 `session.cancel()`——与界面停止按钮相同的 RPC,宿主对活动回合执行 Abort 取消;已生成的截断内容保留在会话中、待处理队列 FIFO 续跑,**不会清空或丢弃**;按快捷键但未输入则完全不打断
- **载入纠偏(打断并注入)**:`session.prompt([{ type: 'text', text: '[打断提示/纠偏]:' + hint }], 'steer')`——`steer` 的官方语义本身就是"中止运行中的回合并把这条消息作为新一步",**打断由 steer 自身完成,无需单独调用 cancel**;自动拼接纠偏前缀
- **继续 + 可折叠回填(方案 A,v1.1 宿主侧)**:双源摘取被打断回合的思考/输出末尾——优先 `interrupted === true` 的 legacy 节点,回合未收敛时兜底读 `snapshot.partial.blocks`(最新快照 + 6×500ms 重试,最长 2.5s,绝不拿上一个回合充数),先 POST 到宿主 `/shutup/backfill`(60s TTL、一次性、20K 字符上限),再发送一句话 `[继续] 继续你刚才的思考与工作。`;宿主经 `systemPrompt.context` 把回填注入**下一次提示词组装的运行时上下文**——官方机制物化为会话里的持久化上下文消息,**聊天 UI 折叠显示一行摘要、点击展开全文**,模型下一步完整读到回填;三级退化:POST 失败 → 全文直发(内容优先);摘不到 → 裸 `[继续]` 指令
- **二级确认**:纠偏按钮第一次点击进入红色确认态(4s 自动还原),第二次点击才真正发送
- **会话接口懒解析**:`sessions` 服务在每次调用时通过 apply 暂存的 ctx 重新 `get`(apply 时点拿不到也能兜底),`binding()` 调用全程 try/catch;载入失败会在弹窗内显示错误并保留输入,不再静默关闭
- **快捷键状态机防护**:
- 严格作用域绑定:仅当会话处于 running(generating/thinking)且弹窗关闭时才**挂载**全局监听,其余时间彻底解绑(不是常驻监听+惰性忽略)
- 防冲突:仅在"1.5s 内刚在输入框敲过字"(正在连续打字)时把快捷键当作普通输入;焦点停留输入框但未打字时正常触发
- 运行状态:挂在 `conversation.composer.dock`(会话作用域槽位)读取 `ConversationSnapshot.running`
- 快捷键监听用捕获阶段,抢在页面其他处理之前;弹窗用 `createPortal` 挂到 `document.body`,全屏遮罩浮在 UI 之上
## 目录结构
```
dsh-shutup/
├── package.json # dsh.bundle.patch + dsh.client 声明(bundle 形态)
├── cordis.patch.yml # 挂载声明:insert entry shutup
├── lib/
│ ├── index.js # 宿主半侧:/shutup/backfill 一次性上下文回填(systemPrompt.context 注入)
│ └── client.js # 浏览器半侧:快捷键 + 打断弹窗 + 思考链摘取 + 设置录制
└── README.md
```
## 更新日志
### v1.3.0(2026-08-22)
- **思考链回填升级(方案 A 权威源)**:新增宿主接口 `GET /shutup/interrupted?sessionId=`,直接读会话日志里最后一条 `interrupted: true` 的 assistant/message(0.1.1 官方中断落盘 = 权威源)——回填内容**完整无截断**(reasoning/text/usage 全量),不再依赖 UI 快照的 1500/500 字符裁剪
- **双源退化链**:权威源 → UI 快照兜底(旧路径保留,宿主升级日志格式变化时可用)→ 裸 [继续] 警告二次确认;三种来源逐级降级,任何一层失败都不丢上下文
- 客户端仍走"回填投递 → 折叠上下文行 → 一句话 [继续]"的路径,UI 占用不变
### v1.2.0(2026-08-16)
- **快捷键防护**:录制时拒绝无 Ctrl / Alt / Meta 的裸键组合(如 Shift+A——与正常打字结构性冲突,聊天时输入大写字母既是快捷键又是打字);`matchCombo` 增加同规则防御纵深;已存的无修饰键配置自动回退默认 Ctrl+Shift+Q
- **思考链保护**:修复 v1.1 的 getSnapshot 死代码(SessionFace 并无此方法,重试循环从未真正执行、读的是陈旧快照)——改为 latest-value ref 模式,每次重试读当下渲染的最新快照,被打断回合落定后必然命中;摘取失败时**不再静默发裸 [继续]**,弹窗重开并警告,二次确认才允许不带上下文继续
### v1.1(2026-08-16)
- 宿主侧一次性上下文回填(`/shutup/backfill` + `systemPrompt.context`):继续时的思考链以可折叠上下文行呈现
- 双源摘取(`interrupted` 节点 + `partial.blocks` 兜底)、三级退化链(折叠回填 → 全文直发 → 裸 [继续])
- 输入才暂停、纠偏二级确认、失败提示可重试
Install
dsh plugin --profile web add github:DosterBool/dsh-shutup#6b76e7cff0f7256d703d6997eabb86f77005c6ab
Profile: web
With the hub plugin installed, ask your agent to install it by name — it resolves the same plan shown here.
dsh plugin --profile web add github:stvlynn/dsh.fish#path:packages/dsh-plugin-hub
install dsh-shutup from the hub