dsh-todo-editor:清单由你写,模型照着执行

前言

在 DSH 里做长任务,常见的协作方式是「模型出计划、人在上面看进度」。这个模式有两个具体问题。

一是计划永远由模型拟定。Harness 自带的任务面板是只读的,数据来自会话投影 todos,你只能看,不能改。二是新会话里根本没有入口:todos 投影为空时,那个组件直接 return null,模型写下第一条任务之前,面板压根不存在。

lmk2215/dsh-todo-editor 就是冲着这两点来的。它把方向反过来——你下清单,模型执行。

这是什么

一个给 DeepSeek Harness 客户端装的可编辑任务流程面板,维护者 lmk2215,package.json 版本 0.1.0,许可证 MIT,社区目录里归在「工作流」分类。

它做的事:把清单入口挂到会话头部,你在里面写节点、改状态,点保存后直接把清单写进会话,输入框上方的原生任务面板立刻更新——不产生用户消息,不走模型回合,不消耗 token。之后你正常发材料,模型按清单逐个节点执行。

核心功能

以下能力均来自 README。

  • 头部按钮加未完成数量角标,空列表也能打开(入口常驻在 conversation.session.header.actions slot)。
  • 逐行改文字、+ 追加、× 删除。
  • 点状态标签在「待处理 → 进行中 → 已完成」之间循环,同时只允许一个进行中,与宿主默认策略一致。
  • 保存走宿主命令 /todo-apply,直接写会话,没有模型回合。
  • 双端校验:空内容、重复条目、非法状态在进入会话日志之前就被挡掉。
  • 降级路径:命令通道缺失时(例如宿主半边没重启),保存自动回退成发一条 [任务流程] 消息,功能不中断。

安装与启用

环境要求:DeepSeek Harness >= 0.2.0(依赖客户端 slot 注册表和 dsh-commands),需要 @deepseek-ai/dsh-client-ui-conversation 提供的 conversation.session.header.actions slot。插件无需构建——lib/client.js 是手写 bundle,只从宿主模块表取 react 和 react-dom。

方式 A,有 pnpm 的环境用插件管理器:

dsh plugin --profile desktop add dsh-todo-editor

方式 B,手动挂载。DSH 的 profile 就是普通目录,本地包可以手工链进去。

  1. 把仓库放到固定位置,例如 ~/.dsh/local-plugins/dsh-todo-editor。

  2. 链接进 profile 的 node_modules:

   # Windows:junction 不需要管理员权限
   cmd /c mklink /J "%USERPROFILE%\.dsh\profiles\desktop\node_modules\dsh-todo-editor" ^
     "%USERPROFILE%\.dsh\local-plugins\dsh-todo-editor"
   # macOS / Linux
   ln -s ~/.dsh/local-plugins/dsh-todo-editor ~/.dsh/profiles/desktop/node_modules/dsh-todo-editor
  1. 在 ~/.dsh/profiles/desktop/package.json 里登记:dsh.profile.bundles 追加 "dsh-todo-editor";dependencies 追加 "dsh-todo-editor": "link:<本仓库绝对路径>"。

  2. 重启 Harness。注意刷新页面不够——客户端 bundle 在宿主启动时快照。

上面这一整套也有脚本:

node scripts/install.mjs            # 安装 / 修复
node scripts/install.mjs --revert   # 卸载

默认值和你的目录结构不匹配时,用 --profile <dir> 或 --dsh <app/dsh 目录> 指定。卸载命令会一并撤销 profile 里的链接、package.json 的两处登记和宿主补丁(从 .bak-todoeditor-* 备份还原),之后同样需要重启。

典型用法

  1. 点会话头部的清单图标。
  2. 写节点,点状态标签切状态。
  3. 点保存——输入框上方的任务面板立刻变成你这份清单。
  4. 把材料发出去,模型按清单逐个节点执行并更新状态。

按钮角标显示还有多少条未完成。

可选:配套宿主补丁

@deepseek-ai/dsh-tool-todo 的 todos 投影会在每次 turn/start 清空。这意味着你定好的清单,发出下一句话就会消失,等模型重写一次才回来。

patches/tool-todo-survive-turn-start.md 记录了一行改动:有未完成节点就跨轮保留,全部完成后仍然清空,避免陈旧进度常驻。scripts/install.mjs 会带时间戳备份地应用它,--revert 从备份还原。不打补丁插件照样能用,只是面板会先闪空、等模型重发。

实现结构

命令 handler 直接跑在接收 agent 上、不产生模型消息,这是保存即时且静默的原因;recordInput: false 让编码后的载荷不落进会话日志。

层 位置 作用
客户端 lib/client.js 注册 slot conversation.session.header.actions(id: todo-editor,order: 5),用 react-dom portal 渲染浮层
客户端 getTodosFace 读 session.projections.faceOf("todos") 并订阅变化
客户端 applyTodos 调 session.command("/todo-apply <encodeURIComponent(JSON)>")
宿主 lib/index.js 注册 /todo-apply,handler 执行 agent.session.append("todo/write", { todos }),返回不含 text 的 { kind: "success" }
宿主 @deepseek-ai/dsh-tool-todo 持有 todos 投影,面板实际渲染它

适用场景与注意

适合想把计划权拿在自己手里、任务又能拆成有序节点的场景:先写好清单再让模型执行,模型负责执行和更新状态,而不是替你立项。

已知限制,来自 README:

  • 保存不是锁:模型一次 todo_write 会整表替换,包括你改过的内容。
  • 状态标签在命令路径下按你设定的状态原样写入;只有回退路径才经由提示文本表达。
  • 浮层是 fixed 定位的 portal,锚定按钮,容器滚动不重算位置(头部本身不滚动)。
  • 不支持拖动排序,行内编辑、末尾追加。

安装前建议做两件事:确认版本与 >= 0.2.0 的宿主匹配;通读源码。插件以当前 dsh 进程的权限运行,能力边界取决于它注册的命令和你的环境。许可证是 MIT。

结尾

它的价值很具体:把「计划由谁定」这个问题从模型侧挪回人侧,同时不占用任何模型回合。如果你习惯先列清单再派活,这是目前最贴近这个习惯的做法。

目录页:https://www.skillhub.cn/plugins/lmk2215/dsh-todo-editor

代码与文档:https://github.com/lmk2215/dsh-todo-editor

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜