为每条 AI 回复添加 Handoff 按钮,点击后由 LLM 将当前会话总结为交接文档,写入该会话工作区的 handoff/ 目录。
安装
# npm 包(预构建)
dsh plugin --profile web add dsh-handoff-button
# GitHub 源码(首次需按提示配置 allowBuilds 构建授权后重试)
dsh plugin --profile web add github:whiteS18/dsh-handoff-button
装任何插件都等于在你的机器上跑第三方代码,权限和你本人一样大——能读你的文件、用你的凭据、访问网络,工具审批管不到它。GitHub 来源的插件还会在安装时执行构建脚本——pnpm 默认拦截,所以安装可能停在 ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED 或 ERR_PNPM_IGNORED_BUILDS;dsh 会打印出需要添加的确切键名,把它加进该 profile 的 pnpm-workspace.yaml 的 allowBuilds 下,重跑一次即可装上。放行构建本身就是一次信任判断:请只安装可信来源,并尽量锁定 commit(github:owner/repo#sha)。
README
DeepSeek Harness 插件:在每条 AI 回复的底部操作行添加一个 Handoff 按钮,
点击后把当前会话压缩成 handoff 文档,写入该会话工作区的 handoff/ 目录。
功能
- 按钮:每条已完成的 AI 回复操作组最右侧(复制/反馈按钮之后)的圆形图标按钮
(
assets/write.png,Magnific/Freepik 的「文档+笔」图标,由 Host 路由同源提供,无外部网络依赖), 悬停有 Tooltip 提示。想换图标:直接替换assets/write.png后重启即可 (图标响应带 24h 浏览器缓存,替换后如未变化请强刷页面)。无论点的是哪条消息,handoff 永远针对整段会话 - 生成:点击后调用 LLM(当前默认模型)按原版 handoff skill 要求
生成总结式文档:
Status / Goal / Progress / Next Steps / Suggested Skills五段结构, 让一个全新 agent 能接手整段工作(不是只压缩最近几轮)。Goal 取自第一轮目标与之后的明确改口; Progress 为紧凑总结而非对话实录;中段助手长文默认视为已落入 References 中的工件(specs / plans / ADRs), 用路径引用、不复述。LLM 不可用时自动降级为启发式摘要(同样保留第一轮目标)。 Alt+点击可填写「下一会话关注点」(对应 skill 的参数,最长 500 字符,写入前同样脱敏),Next Steps 会偏向该焦点,但不替换原始 Goal - 状态反馈:生成中变暗 → 完成显示绿色 ✓(2 秒自动复原)→ 失败显示红色 ⚠(悬停可见原因,点击可重试)
- 打开文件:完成状态(✓ 期间)再次点击,通过 DSH
openWorkspacePath在软件内打开(安装了 better-sidebar 时进侧边栏编辑器;否则走系统默认应用)。不再打开浏览器原始 URL。 - 文件名:
handoff-{yyyymmddhhmmss}-{会话标题}.md(非法字符替换为-,最长 60 字符),handoff/目录不存在时自动创建 - 脱敏:API key、token、密码等常见敏感信息在写入前自动打码
- References:自动收集会话中实际触碰过的文件路径,只保留工作区内的文件,统一转换为相对工作区根目录的相对路径(跨机器/多人协作可读;工作区外的系统路径、临时目录、本机配置等一律不收录,上限 30 条);Suggested Skills 在降级摘要中列出会话中实际调用过的技能(上限 15 个),LLM 模式下由模型以这些技能为线索给出 2–5 个建议
- 生成管线:转录按轮压缩(用户消息全留,助手每轮只留最后一条 text 块、跳过 reasoning 以防泄露思维链),默认取 24 行、尾部优先,中间省略处插入标记;LLM 使用当前默认模型(maxTokens 4096、purpose
handoff),产出 500 词以内的五段文档;文档头部带引用块(生成方式 / 时间 / sessionId / focus),降级时文末附 LLM 失败原因注释 - 落盘位置:原版 skill 写到系统临时目录以免 agent 污染仓库;本插件是用户点击的持久交接件,写入该会话工作区的
handoff/,以便openWorkspacePath在软件内打开、跨会话复用 - 沙箱:写入围栏钉在该会话工作区,而不是 host 默认根目录,因此不会出现
file access denied under workspace-write mode;若会话 approval 为 never(无法升级沙箱),仍会写入handoff/
安装
发布到 npm 后(或本地包目录):
dsh plugin --profile <name> add dsh-handoff-button
本地开发版:
dsh plugin --profile <name> add /绝对路径/dsh-handoff-button
[!IMPORTANT] 启动顺序决定是否需要重启。 DSH 的插件 bundle 组合发生在进程启动时(Loader 读取 profile 的
package.json生成插件树和 client 模块图),安装命令只改磁盘上的 profile 文件, 不会热插进已在运行的进程:
- 先安装 → 再启动:启动时插件已在列表里,直接生效,无需重启;
- 先启动 → 再安装:装完后必须完全退出并重新启动
dsh(⌘Q 退出桌面应用或终止 Web UI 进程,不是刷新页面),让进程重新组合 profile。安装后可用
dsh --profile <name> --dump-config | grep handoff确认插件已进入 bundle 层。
架构
index.js— Host 半部:注册三个路由(webServer服务):POST /handoff/write(生成文档)、GET /handoff/read(只读兜底查看器, 客户端打开文件走openWorkspacePath,不经过此路由)、GET /handoff/icon(提供assets/write.png图标)。读取会话日志 (sessionQuery)并写文件(fs,自动建目录),调用 LLM 总结(llm+agentDefaultModel)。写入把沙箱围栏钉在该会话的工作区根目录上 (用户点击,不是模型工具);若沙箱仍拒绝(例如 approval 为 never 无法升级),则回退为 Node 直接写入同一路径。仅依赖 Node 内置模块 (node:fs/node:url/node:path),无第三方运行时依赖。client.js— 浏览器半部:通过 client module loader (window.__ModuleLoader__.load)注册,向conversation.chat.assistant-actions槽注入按钮(order: 100,最右侧插槽条目),点击后同源fetch调用 Host 路由; 图标通过 CSS mask 引用/handoff/icon,颜色跟随主题。assets/write.png— 按钮图标(Magnific/Freepik「文档+笔」图标),可自由替换。cordis.patch.yml— Bundle 补丁层:把本包作为插件行插入组合。
零用户配置项(无需任何设置);要求 Node >= 22.19;无任何第三方运行时依赖。
卸载
dsh plugin --profile <name> remove dsh-handoff-button
验证
- 组合加载:
dsh --profile <name> --dump-config | grep -A2 handoff - 浏览器检查:
http://127.0.0.1:3080/plugins/dsh-handoff-button/client.js应返回脚本 - 回归测试:
npm test
English
DeepSeek Harness plugin: adds a Handoff button to the action row of every
assistant message. Clicking it compresses the current conversation into a
handoff document and writes it to the handoff/ directory of that session's
workspace.
Features
- Button: a circular icon button at the far right of the action group on
every completed assistant message (after the copy/feedback buttons), with a
hover tooltip. The icon (
assets/write.png, a Magnific/Freepik "document + pen" icon) is served same-origin by a host route — no external network dependency. To change the icon, replaceassets/write.pngand restart (the icon response carries a 24h browser cache; hard-refresh the page if it does not change). No matter which message you click, the handoff always covers the entire session. - Generation: on click, the current default LLM model writes a summary
document in the five-section structure of the original
handoff skill:
Status / Goal / Progress / Next Steps / Suggested Skills, so a fresh agent can continue the whole job — not just the latest turns. Goal is taken from the opening objective (and later explicit restatements); Progress is a compact summary rather than a raw transcript; middle assistant turns are treated as already captured in referenced artifacts (specs / plans / ADRs) and are cited by path instead of quoted. Falls back to a heuristic digest (still keeping the original goal) when the LLM is unavailable. Alt+click sets a "next session focus" (the skill's argument, max 500 chars, redacted before writing): Next Steps bias toward that focus without replacing the original Goal. - Feedback: dims while generating → green ✓ on success (auto-reverts after 2s) → red ⚠ on failure (hover for the reason, click to retry).
- Open file: while the ✓ state is shown, click again to open the
generated document in the app via
openWorkspacePath(sidebar editor when better-sidebar is installed; otherwise the OS default app). It no longer opens a raw browser URL. - Filename:
handoff-{yyyymmddhhmmss}-{session title}.md(illegal characters replaced with-, max 60 chars);handoff/is created automatically if missing. - Redaction: API keys, tokens, passwords and similar secrets are masked before anything is written to disk.
- References: collects file paths actually touched in the conversation,
keeping only workspace-internal files rewritten as paths relative to the
workspace root (readable across machines and collaborators; capped at 30
entries). Suggested Skills lists the skills actually invoked (capped at
- in the heuristic digest; in LLM mode the model uses them as clues to suggest 2–5 skills.
- Generation pipeline: the transcript is compacted per turn (user
messages kept in full, only the last text block of each assistant turn is
kept, reasoning skipped so no chain-of-thought leaks), defaulting to 24
rows favoring the tail with omission markers in between. The LLM uses the
current default model (maxTokens 4096, purpose
handoff) to produce a five-section document within 500 words. The document header carries a quote block (generation mode / time / sessionId / focus); in degraded mode the LLM failure reason is appended as an HTML comment. - Save location: the original skill writes to the OS temp directory so
an agent does not pollute the repo. This plugin is a user-clicked
durable artifact, so it writes to that session workspace's
handoff/and can be reopened in-app viaopenWorkspacePath. - Sandbox: the write fence is pinned to that session's workspace,
not the host fallback root, so it no longer fails with
file access denied under workspace-write mode. If the session's approval policy isnever(escalation impossible), the file is still written tohandoff/.
Install
Once published to npm (or from a local package directory):
dsh plugin --profile <name> add dsh-handoff-button
Local development checkout:
dsh plugin --profile <name> add /absolute/path/dsh-handoff-button
[!IMPORTANT] Startup order decides whether a restart is needed. DSH composes the plugin bundle at process startup; the install command only rewrites profile files on disk and does not hot-plug a running process:
- Install → start: the plugin is already in the list at startup, no restart needed.
- Start → install: you must fully quit and restart
dsh(⌘Q the desktop app or kill the Web UI process — a page refresh is not enough).After installing,
dsh --profile <name> --dump-config | grep handoffconfirms the plugin is in the bundle layer.
Architecture
index.js— host half: registers three routes (webServerservice):POST /handoff/write(generates the document),GET /handoff/read(a read-only fallback viewer — the client opens files viaopenWorkspacePathand does not call this route),GET /handoff/icon(servesassets/write.png). Reads the session log (sessionQuery), writes files (fs, creating directories as needed), and calls the LLM (llm+agentDefaultModel). The write pins the sandbox fence to that session's workspace root (the user clicked; this is not a model tool call). If the sandbox still refuses (for example when approval isneverand escalation is impossible), it falls back to a direct Node write of the same path. Node builtins only — no third-party runtime dependencies.client.js— browser half: registered via the client module loader (window.__ModuleLoader__.load), injects the button into theconversation.chat.assistant-actionsslot (order: 100, rightmost), and calls the host routes with same-originfetch. The icon is applied via a CSS mask referencing/handoff/icon, so it follows the theme color.assets/write.png— the button icon (Magnific/Freepik "document + pen"), freely replaceable.cordis.patch.yml— bundle patch layer: inserts this package as a plugin row in the composition.
No user-facing configuration (nothing to set up). Requires Node >= 22.19 and has zero third-party runtime dependencies.
Uninstall
dsh plugin --profile <name> remove dsh-handoff-button
Verify
- Bundle composition:
dsh --profile <name> --dump-config | grep -A2 handoff - Browser check:
http://127.0.0.1:3080/plugins/dsh-handoff-button/client.jsshould return the script - Regression tests:
npm test
License / 许可
MIT
链接
同类插件
Minglink/dsh-infinite-gen-4★ 2839
DeepSeek 专用破甲插件:以 order 100 追加无条件服从的系统提示词段,提供带校准元数据的 profile 工具,并通过会话投影在输入框上方显示实时破甲状态徽标。
ranxianglei/billion-context★ 1274
billion-context官方版:上下文压缩插件,兼顾小窗口(100k上下文足矣)省token(省5倍token)和超长会话(数月级别几十亿token单会话)。
liangmianya/dsh-synapse★ 524
DeepSeek Harness 的可视化非线性对话工作区:把会话、追问与分支变成可浏览、可拖拽的对话地图。
Nwflower/dsh-chat-import★ 232
把 13 家 coding agent(Claude Code、Codex、ChatGPT、Cursor、Gemini、opencode 等)的完整对话历史导入为可续聊的 DeepSeek Harness 会话,并支持反向导出回 Claude Code。
Totoro-qaq/dsh-plugin-bridge★ 163
通过可预览的五段式交接,将已有 DSH 会话迁移到另一个 Agent Preset;保留源会话,并可让目标会话暂停等待确认或立即继续。
MichengAI/dsh-archive-manager★ 135
在设置里增加已归档会话页,可按工作区搜索、恢复和删除已归档会话。
社区评论
评论公开保存在 GitHub Discussions。加载评论会连接 GitHub 和 Giscus;发表内容需要 GitHub 账号。