DeepSeek Harness plugin

btw4DeepseekHarness

Claude Code-style /btw side question (fork, no tools, single turn) + /remember session memory for DeepSeek Harness

Jump to install

Source facts

Repository
wensincai/btw4DeepseekHarness
Latest update
Aug 15, 2026
Category
Memory
GitHub stars
1
Format
plugin
Catalog evidence
Upstream dsh.bundle evidence
Evidence path
package.json#dsh.bundle
Checked against
0.1.0-rc.8
Upstream check date
2026-08-20

This evidence comes from the upstream catalog. This site has not installed, run, or security-reviewed the plugin.

Install

Start with a prompt that asks an agent to review the GitHub repository and source. Switch to the command if you want to install it yourself.

Copy this prompt into DSH, Codex, or another agent and ask it to review the GitHub repository and source first.

Do not install or run any commands yet. Read this plugin's GitHub repository, README, and relevant source code. Then answer the questions below clearly and directly so I can decide whether it fits my needs:

1. What is this plugin, and what problem does it solve?
2. Who is it for, and what are its typical use cases?
3. How is it used after installation? Include one minimal example.
4. What known limitations or privacy, security, compatibility, or maintenance risks does it have?
5. Give a clear recommendation: recommend, conditionally recommend, or do not recommend, with reasons.

Distinguish statements documented by the repository, inferences from source code, and unknowns. If evidence is insufficient, say so explicitly. Do not guess or simply repeat the README.

GitHub: https://github.com/wensincai/btw4DeepseekHarness
Plugin: btw4DeepseekHarness
Author: wensincai

Check the source files

Read the README and other files from this plugin directory before installing.

File explorer3 files
README.mdSource · read only

dsh-btw — 给 DeepSeek Harness 加 Claude Code 原版 /btw 侧边提问 + /remember 会话备忘

一个零依赖的 dsh 插件包(bundle),为你的 profile 注册两个斜杠命令:

  • /btw <问题> —— Claude Code 原版形态的侧边提问(side question):fork 一个禁工具的轻量子代理、用当前会话上下文回答、答案作为命令结果显示,不打断主线、不进主对话历史、不落盘
  • /remember <备忘> —— 原来的备忘功能整体搬到这里:记录一条 by-the-way 笔记,让模型在本次会话里一直记得它(steer 即时回应 + 每次请求注入 + 磁盘持久化)。
/btw 刚才那个配置文件叫什么来着?   → 子代理在后台回答,主线不中断
/btw                                → 提示用法(必须带问题)

/remember 用户姓张,称呼"张工"      → 记录备忘,模型本轮之后一直记得
/remember                           → 列出本会话已记录的备忘
/remember clear                     → 清空本会话备忘
/remember forget 2                  → 删除第 2 条备忘

---

1. Claude Code 原版 /btw 是什么

Claude Code 2.0 引入的 /btw 命令,官方描述是 "Ask a quick side question without interrupting the main conversation"——侧边提问(side question),不是记笔记。从源码(commands/btw/btw.tsxutils/sideQuestion.tsutils/forkedAgent.ts;第三方源码分析见 Claude Code 的 /btw 为什么很妙不打断主线的旁路提问)看,它的机制是:

1. fork 一个轻量子代理runSideQuestion → runForkedAgent)回答你的问题,主线程完全不动——问答不进入主对话历史,关掉浮层即消失(官方 issue #37582 确认它是 ephemeral); 2. 有完整上下文,但禁用一切工具:只能基于当前对话里已有的信息回答,不能读文件、不能执行命令、不能搜索; 3. 强制单轮maxTurns = 1,一问一答,不支持追问; 4. 复用主线程的 prompt cache:额外成本压到最低,问答本身也不消耗上下文窗口; 5. 答案以浮层显示,Space / Enter / Esc 关闭,不落盘、不可恢复。

一句话:共享上下文但不共享控制权,共享缓存但不污染主线。

2. 本插件与 Claude Code 原版的对应关系

v0.2.0 起,插件按原版形态重做:

Claude Code 原版dsh-btw(本插件)
/btw <问题>:fork 子代理、禁工具、单轮、答案不进历史/btw <问题>(原版形态)ctx.subagents fork provider、toolFilter: { allow: [] } 全禁工具、in-process driver 天然单轮、答案作为命令结果(log-only,永不进模型上下文)、不落盘
——(原版没有对应物)/remember <备忘>:原 /btw 的备忘语义,steer 即时回应 + system-prompt 每次注入 + $DSH_HOME/btw/notes.json 持久化

两套机制在 dsh 里的具体差异:

维度/btw 侧边提问/remember 会话备忘
本质提问 → 一次性答案记录 → 会话级记忆
执行体fork 出的轻量子代理(sidecar)主线程本身(agent.steer + system-prompt 注入)
工具完全禁用toolFilter: { allow: [] }注入主线后,后续轮次有全部工具
是否进历史不进(command/run·command/done 是 log-only,永不进模型上下文)(先作为一条 user message,之后每次请求都注入)
轮次单轮(in-process driver 一次 turn 一个 result)持续生效,直到 /remember forget / /remember clear
成本子代理一次请求(继承父上下文前缀)每轮多注入一段 section(上限 20 条、单条 500 字符)
持久化$DSH_HOME/btw/notes.json,resume 可恢复
管理命令无(一问一答)/remember 列表、/remember clear/remember forget <n>

3. dsh 原本有没有类似的命令?

没有内置 /btw 我在 dsh 源码(packages/interaction/commands)和 dsh-cc-tui 里全文检索过 btw,没有任何实现。dsh 的斜杠命令体系是插件注册制:任何插件用 ctx.commands.register({ name, description, input, handler }) 就能挂一个 /命令,Web 端输入框敲 / 会弹出命令菜单(ui-input-trigger 的 slash 菜单)。

当前 web profile 里实际可用的内置命令(逐包核对源码):

| 命令 | 作用 | 注册包 | |---|---|---| | /compact | 压缩旧对话历史 | @deepseek-ai/dsh-command-compact | | /goal | 查看/设置长任务目标 | @deepseek-ai/dsh-command-goal | | /plan [off\|message] | 进入/退出计划模式 | @deepseek-ai/dsh-plan-mode | | /feedback <text> | 记录反馈 | @deepseek-ai/dsh-command-feedback | | /permission <preset> | 切换权限预设 | @deepseek-ai/dsh-permission-presets | | /export | 导出会话日志 ZIP | @deepseek-ai/dsh-session-log-export |

最接近的官方替代品:

  • /goal <目标> —— "让模型记住一件事"的持久语义最接近(跨多轮自动延续),但它是任务目标,不是随手笔记;
  • ~/.dsh/AGENTS.md(用户级全局指令)—— 会被注入每一个会话(dsh-agent-instructionsuser-global 作用域),适合"永远记住";要改文件、要重启,不是运行时命令。

本插件补上的是"运行时、会话级、不换任务"两块空缺:/btw 管"顺手问一句",/remember 管"顺手记一笔"。

4. /btw 侧边提问的工作原理(源码层面)

/btw <问题> 的执行链路(executeSideQuestion):

1. 解析:整段输入就是问题,空输入返回用法错误;超过 2000 字符截断(parseSideQuestion); 2. 取服务ctx.get('subagents') 惰性解析(可选服务,不在 inject 里声明)——profile 没有 subagents 服务或没有 fork provider 时返回明确的错误,/remember 不受影响; 3. fork 子代理subagents.start('fork', { label: 'btw', prompt, parent: agent, signal, toolFilter: { allow: [] } }): - fork provider(packages/subagent/subagent-fork-in-process)会把父会话已完成的 turn 前缀作为 seed 注入子会话——子代理"有完整上下文"; - toolFilter: { allow: [] } —— allow 语义是"只保留列出的工具",空数组 = 全部工具消失且拒绝执行(fork 支持 toolFilter 能力); - 单轮由 subagent-in-process-driver 保证("owns exactly one turn with one result"); - prompt 文本(renderSideQuestionPrompt)带固定指令:这是 side question、直接简洁回答、不要调用任何工具、不要承诺采取行动(对应 Claude Code 的 system reminder); 4. 取结果run.result 给出 { output, stopReason }completed → 提取 text block 作为成功答案;aborted(用户取消/信号触发)→ "Side question cancelled.";refusal → 拒绝回答;max-tokens/error → 报错并保留部分回答; 5. 收尾:无论成败都 await run.dispose()(释放子代理);结果作为命令结果返回——command/run/command/donelog-only 事件,永不进模型上下文,所以问答不污染主线packages/interaction/commands/src/types.ts 明确标注 "Log-only (never model surface)"); 6. 取消:命令 invocation 的 signal 直接传给子代理,UI 请求中止时子代理同步取消。

5. /remember 会话备忘的工作原理(源码层面)

/remember <note> 一次做三件事:

行为机制效果
① 即时响应把笔记作为一条用户消息注入会话(agent.steer模型下一轮就会回应它
② 会话记忆笔记注入本会话每一次模型请求的 system prompt(ctx.systemPrompt.section,name remember:notes,order 60)模型在本会话持续"记得",不靠上下文里的偶然提及
③ 跨重启持久写入 $DSH_HOME/btw/notes.json(按 session id 分桶)resume 会话后笔记还在

> ② 的 section 文本同时带行为引导:笔记是"背景上下文,不是指令"——无关时不要复述、被用户点名时简短回应不展开。这是对"顺手记一条却换来长篇大论"这类模型行为的抑制杠杆(插件无法强制模型,但每轮注入的引导能显著压低这种倾向)。

命令语法

/remember                列出本会话已记录的备忘(1-based 编号;超过 50 条只显示前 50 并提示其余)
/remember <note>         记录备忘 + 注入给模型;超过 500 字符截断
/remember clear          清空本会话全部备忘
/remember forget <n>     删除第 n 条备忘

clear / forget精确匹配的控制词:/remember clear the cache 会被当作一条普通备忘(与 /goal 的解析规则一致)。

6. 兼容性

  • 零运行时依赖:只 import node:*,通过注入的 commands/systemPrompt 服务和惰性的 ctx.get('subagents') 与 harness 交互——web profile 的 node_modules 里没有 @deepseek-ai/* 包,任何带 @deepseek-ai/* import 的插件都会 ERR_MODULE_NOT_FOUND;本插件任何 profile 都能直接加载;
  • /btw 需要 profile 提供 subagents 服务 + fork provider(dsh-base bundle 自带),缺失时该命令报错、/remember 照常工作;
  • peerDependencies 范围为 >=0.1.0-rc.5 <0.2.0(含 @deepseek-ai/dsh-subagent),全部标记 optional(运行时零 import,声明仅作文档用途);
  • Web、TUI、headless 等一切带命令注册表的 profile 都可用(dsh-cc-tui 会把注册表命令合并进它的 / 菜单)。

7. 目录结构

D:\dsh\btw\
├── package.json        # dsh.bundle.patch → cordis.patch.yml;零依赖
├── cordis.patch.yml    # bundle 补丁:insert 一行 { id: btw, name: dsh-btw }
├── src\
│   └── index.js        # 插件本体(纯 ESM + JSDoc,零构建;两个命令 + section)
├── test\
│   └── btw.test.mjs    # node:test 单测 + 桩 ctx 集成测试(零依赖,31 个用例)
└── README.md

8. 安装(web profile)

dsh 源码仓库根目录D:\dsh\deepseek-harness)执行:

cd D:\dsh\deepseek-harness
pnpm dsh plugin --profile web add "link:D:\dsh\btw"
  • link:链接安装:改 D:\dsh\btw 源码即生效(重启后),适合迭代;想要拷贝一份独立安装可改用 file:D:\dsh\btw
  • 纯本地路径,不需要网络、不需要 git/SSH(避开你环境里 github 连不上的问题);
  • 该命令会在 profile 的 package.json 加上 dsh-btw 依赖,并自动把它并入 dsh.profile.bundles

验证:

pnpm dsh --profile web --dump-config   # 应看到 # == dsh-btw 层

然后重启客户端(bundle 层在启动时组装,package.json / 插件源码变更不会热重载)。重启后在输入框敲 /,命令菜单里应出现 btwremember

> 不想重启的替代法:手动 pnpm add 该包后,把 - id: btw / name: dsh-btw 这两行写进 profile 的 cordis.patch.yml——profile 自己的补丁层支持热重载(watchUserPatches)。

9. 使用示例

你: /btw 刚才那个配置文件叫什么来着?
dsh: (子代理在后台用当前会话上下文回答)
     配置文件是 src/config.ts,第 12 行导出 CONFIG 对象。
     (主线继续干活,这段问答不进主对话、不落盘)

你: /remember 用户姓张,称呼"张工"
dsh: Noted (1 by-the-way note this session).
模型: 好的,记下了——后续涉及称呼我会用"张工"。

你: /remember
dsh: By-the-way notes (2):
1. 用户姓张,称呼"张工"
2. 测试环境地址是 http://10.0.0.5:8080

你: /remember forget 2
dsh: Forgot note 2.

10. 测试

cd D:\dsh\btw
node --test        # 31 个用例:侧问解析/提示/子代理流(含取消/拒绝/部分回答/失败兜底/始终 dispose)、
                   # 备忘语法、存储/持久化/损坏回退、渲染上限、apply() 装配、steer 失败兜底

11. 卸载

pnpm dsh plugin --profile web remove dsh-btw

(同时会从 dsh.profile.bundles 移除该层;如需清理数据,删除 C:\Users\hukou\.dsh\btw\ 目录。)

12. 限制与已知问题

  • /btw 的上下文是"上一个已完成 turn":fork provider 的 seed 截止到父会话最后一次 turn/end(当前进行中的 tool-call turn 无法回放为合法子会话)。主线正在干活时提问,子代理看到的是最近一个完整回合的上下文——与 Claude Code"每轮结束后快照"的取舍一致;
  • /btw 不做 prompt cache 复用:dsh 的 fork 子代理是独立的一次请求(继承了上下文前缀,但不会像 Claude Code 那样保证与主线程字节级一致的 cache key),成本低于开新会话但高于纯缓存命中;子代理自身的请求不写回主线上下文窗口
  • /btw 答案的呈现:作为命令结果行显示(相当于浮层),关闭/翻页即不可恢复;想要保留就复制,或用 /remember 记下来;
  • /remember 注入每次模型请求:带备忘的会话每个请求都会携带 section 文本,有 token 成本;maxNotes(默认 20 条)和单条 500 字符上限约束它。想彻底清空用 /remember clear
  • 持久化是进程内快照 + JSON 文件:并发写多个会话时以最后一次 save() 为准;$DSH_HOME/btw/notes.json 可手工编辑,但建议通过命令操作;
  • 数据存明文notes.json$DSH_HOME 下,别往里写密钥;
  • TUI 注意dsh-cc-tui 自带一套本地命令(/clear/cost 等)且需要 TTY——你的 client 是无 TTY 的 Web 会话,用的是本插件的 registry 命令,两者不冲突。

13. 版本历史

  • 0.2.0(本次重构):/btw 改为 Claude Code 原版形态的侧边提问(fork 子代理 → 禁工具 → 单轮 → 答案作为命令结果,不进主对话、不落盘,需要 profile 提供 subagents + fork provider);原备忘功能整体迁移到 /remember(存储文件路径不变,旧笔记无缝延续;prompt section 更名 remember:notes)。新增 12 个侧问相关测试用例(共 31 个)。
  • 0.1.1:优化备忘提示词("背景上下文,非指令,点名时简短回应")+ 列表上限 LIST_CAP=50
  • 0.1.0:首个可用版本,/btw 为"会话备忘"形态(steer + system-prompt 注入 + 持久化)。

14. 参考资料