DeepSeek Harness Plugin Hub

发布与管理完整 Harness Profiles,发现适合你的插件。

探索

插件目录环境预设文档中心动态

社区

发布插件联系我们报告问题

相关链接

Plugin Hub GitHubDeepSeek Harness 官方项目系统状态隐私说明
© 2026 DeepSeek Harness Plugin HubPowered byPaxTech

独立、非官方社区项目,与 DeepSeek 官方无隶属、授权或背书关系。

Todo Assistant — DeepSeek Harness 插件(DSH Plugin)
DeepSeek Harness Plugin Hub
ProfilesPlugins分类动态文档登录管理 Profiles
ProfilesPlugins分类动态文档登录
← Plugins
T

todo-assistant

Todo Assistant

DSH 插件:跨会话的旁支任务工作台——把会话里「先不做但别忘」的事记成卡片,之后单独开会话处理。A DSH plugin: a cross-session workspace for side tasks found mid-session.

插件会安装到这里;不确定时保持 web。

npx -y @deepseek-ai/dsh plugin --profile web add github:zangoose335/dsh-todo-assistant#cc59cf4229eebd7703810337b9d49735732a2f25
README兼容性版本

兼容性与来源证明

Todo Assistant 以 todo-assistant 发布,当前版本为 0.1.0。Plugin Hub 会校验它的 manifest,并保存精确安装来源,便于复现安装结果。

DSH 兼容范围
*
运行环境
web
发布来源
github
Registry 更新时间
2026/10/17

版本

0.1.0stable
2026/10/17

相关插件

正在加载相关插件…

最新版
0.1.0
DSH
*
HMR
重启进程
Tree shaking
未声明可安全裁剪
解包体积
未提供
文件数
未提供
Surface
web
许可证
MIT
发布源
github
GitHub
★ 0
周下载
0
最近提交
2026/10/19
查看源码 ↗
README Badge

点击下方 Badge 复制 Markdown,粘贴到 README 即可。

这是你的 Plugin?认领权益 · 优先安全扫描

验证 package.json 声明的 GitHub 仓库,即可管理这个公开页面。认领后,Hub 会优先安排当前版本的安全扫描,并在通过后公开展示结果。

认领这个 Plugin →
报告问题

相关插件

继续浏览 productivity-workflow 分类下经过校验的插件。

Acp App@deepseek-ai/dsh-acp-appdsh ACP 配置文件包:基于 dsh-base 的仅限自动化的 JSON-RPC stdio 和进程生命周期管理Experimental Schedule Bundle@deepseek-ai/dsh-experimental-schedule-bundle为 Web 组合添加 Schedule、其任务页面和时间上下文的可选捆绑包Web All@linxin666/dsh-web-allDSH Web UI 全家桶聚合插件:一键安装全部功能插件(task-board / git-graph / pet / remote-web-ui / web-ui-settings / skin-center / community-plugins / compat shim)。compat 桥接层已并入本包(src/client),无需独立 compat npm 包。Ab Ocrdsh-ab-ocr--- description: "外部 ocr 工具:逐页识别扫描的 PDF 或图像,仅在处理完最后一页后按顺序合并页面,并使用模型确定的标题级别保存为一个 Markdown 文档。" kind: "package-reference" ---

README

中文 | English

待办助理 (todo-assistant)

跨会话的旁支任务工作台:把会话里"先不做但别忘"的事记成卡片,之后单独开会话处理。 设计见 docs/DESIGN.md。安装见 安装,许可见 LICENSE(MIT)。

当前功能:

  • 右栏 tab:五个视图(未完成 / 待修复 / 待添加 / 已完成 / 全部)、卡片 CRUD、详情展开、按工作区范围过滤(跟随当前会话);
  • 捕获:todo_add(完整 schema + git 坐标 + mustRead/park + 开发者原话 + 路径归一化)、去重拦截、 #DB … #/db / #MEMO … #/memo 标记、AI 回复上的「记录待办」段落面板、输入框 #db 补全与 # 引用框;
  • 读取:todo_read / todo_note / todo_status / todo_list / todo_recall(两段式原文回读);
  • 提醒:每步零模型的路径相关性检测 + 下一步一行提醒 + 右栏「相关」角标;
  • 交接:卡片「开始任务」→ 新会话以卡片开场 / 插入当前会话;工作区级通用规则随新会话带上。

结构

文件作用
host.jsHost 插件入口:打开 todo_assistant storage domain,注册 /api 路由与 todo_add 工具
domain.js领域声明(zod record schema)与纯逻辑:建卡、捕获校验、改卡、ID、L0 投影
api.js数据操作与线协议:list / create / patch / remove / note.add / note.remove
tool.js六个工具定义:todo_add / todo_read / todo_note / todo_status / todo_list / todo_recall
git.js写卡时的代码坐标:git rev-parse(subprocess)优先,.git 文件读取兜底
detect.js检测规则:工具调用 → 路径 → 卡片匹配 → 提醒行 / 角标集合
recall.jsL2 回读:原始日志 → 目录(seq/轮次/角色/首行/token)→ 指定 slice 的正文
dedupe.js近似重复:同工作区 + 共享触及文件 + 标题相似度
client.js浏览器 half:右栏页签类型 + 卡片 UI(无构建步骤,只用 baseline react)
scripts/verify-domain.mjs无头验证:用安装里的真实 storage 栈打开 domain 并跑完整个线协议

domain.js / api.js 刻意不写任何包导入,测试脚本可以脱离 profile 直接驱动它们; 真实依赖由 index.js 注入 createTodoSpec({ z, defineDomain, domainTable })。

#DB 标记(输入即同意)

在消息里写:

#DB 导出 CSV 时表头重复
第二行也算待办内容
#/db
  • 开始标记 #DB / #db,或英文的 #MEMO / #memo(两者等价,同一捕获链路);结束标记 #/db / #/memo 可省略(省略时到消息结尾),两种结束标记可互换;
  • 跳过围栏代码块与行内代码 —— 否则一条"讲解这个语法"的消息会把自己记成待办;
  • host 在 user/message(只认人打的,source.kind === 'user')上扫描,命中就排进该会话的队列;
  • 下一次装配会注入一条一次性指令:告诉 AI「这段被标了 #DB,标记就是明确同意,用 todo_add 原样记下,不要再问」;
  • 开发者原话(含标记本身)仍会逐字存进卡片的 request。

识别点在 host 侧(agent/inbox/claimed,早于 prompt 装配),所以不依赖 composer 的提交钩子;也不改发送流程。

输入框里有轻量补全:打 #db 会变成 #DB #/DB,打 #memo 会变成 #MEMO #/MEMO,光标停在两个空格之间。实现只用公开的 useInput + inputActions(先插 #/db、再把 #db 替换成 #DB ),不碰编辑器内部与 DOM。

面板内的使用说明

右上角的圆形 (i) 按钮展开「待办助理使用说明」:插件定位、为什么值得用(记卡带现场、读卡省 token、主线不断、重复提醒、规则写一次)、按场景的用法(问 AI 记卡 / 事后 #x.y 接着做 / 一次多条 / #db 输入即记录 / # 引用 / 开始任务收尾 / 通用规则),以及 #x.y 编号含义。文案在中英两份 i18n 里,改措辞直接改 client.js 的 help.body。

段落捕获面板

点 AI 回复上的「记录待办」后:

  • 面板列出该条回复的段落,关键词/路径命中的预选;
  • 「插入到对话框」把选中的段落拼成同一条消息放进输入框(不发送),适合一次补多条;
  • 「发送给 AI」直接作为一条用户消息入队,由 Agent 调 todo_add;
  • 面板材质与官方弹层一致(mask + layer-2 + --dsw-radius-panel + --dsw-elevation-prominent)。

开发者原话

todo_add 落卡时,host 会把当前轮里人打的用户消息(source.kind === 'user',跳过文件变更/技能等系统注入)逐字存进卡片的 request.text(上限 8000 字,超了标 truncated),模型完全不参与这段文本。

  • 右栏详情第一块就是「开发者原话」,卡片元信息里也会出现「原话」标记;
  • todo_read 默认输出里带 developer request (verbatim);
  • 新会话的种子把它作为「开发者原话」一节带上,接手会话的 AI 直接看到你的措辞。

如果消息里带了 #DB … #/db,只记对应那一段,标记本身不入库;一条消息里多个标记时按出现顺序各记一段(request.block 记序号)。识别点允许标记紧跟在中文标点后(两条:#db …),但贴在单词里(abc#db)不算。

这样 AI 的理解有偏差时,你能对着原话立刻纠正;它也永远不会被"总结"掉。

工作区通用规则

右栏面板里有一块可折叠的「通用规则」,按工作区保存:

  • 存在 todo_assistant 域的 rules 表里,key = 工作区路径(rules.get / rules.set 两个端点);
  • 点「处理 → 新会话中立即执行」时,会把该卡所在工作区的规则拼进开场种子(放在卡片内容之前);
  • 留空即删除该工作区的规则;
  • 只作用于插件自己创建的新会话;你手动新建的会话不会带上(要全局生效得挂系统提示词,那是另一种取舍)。

完成闭环

  • AI 侧新增 todo_status(id, status):唯一能改状态的工具(open / doing / done / dropped),描述里写死必须先得到开发者确认;
  • 新会话种子与「插入当前会话」的提示词里都带了这句: 「改完后主动问开发者是否把 #x.y 标记为完成,确认后再调 todo_status」;
  • 于是接手一张卡后,AI 会在收尾时问一次,得到肯定回答才落 done,不需要你自己去右栏改。

编号

每张卡有一个短标签 #3.2,与内部 id(td_x7k2)并存:

  • major(点前)= 第几个会话:同一根会话共用一个 major,在该会话第一张卡时分配(全局最大 major + 1);
  • minor(点后)= 会话内第几张:组内最大 minor + 1;
  • 子会话不算新会话:沿 header.parentSession 上溯到根,卡片归到根的组;
  • 没有会话的卡:每张新开一个 major、minor 固定 0(x.0);
  • 创建时定号并写进记录:之后删除不重排;只有删掉组内最高 minor 后,同组下一张才会复用该号(已接受);
  • 老卡片迁移:本方案之前的卡一次性变成 1.<旧编号>(1.1…1.N);迁移后旧会话再进新卡会另开 major —— 历史桶不吸收新卡;
  • 右栏、工具输出、提醒行都用 #x.y;入参接受 3.2、#3.2 和 td_x7k2。

数据落在哪

  • domain 名是 todo_assistant(下划线):storage 层强制 UNIT_NAME_RE = /^[a-z][a-z0-9_]*$/, 连字符会被 defineDomain 直接拒绝。
  • 走 storage-domain 的默认 json backend,所以卡片落在 ~/.dsh/storages/todo_assistant.json(单文件 layout)。
  • workspace 存会话所属工作区的规范化路径;不属于任何仓库的卡放 inbox。

捕获(M2)

todo_add 是表单,不是自由写总结:

  • 参数固定为 title / kind / nextStep / touchedFiles / mustRead(必填)+ symptom / cause / intent / park / symbols(可选);
  • 硬约束在 handler 里二次校验,超限直接报错让模型重写:title ≤40、mustRead ≤3 条且每条 ≤200、park.label ≤30、park.why ≤60;touchedFiles 为空只警告不拦截;
  • 工具描述写死三条行为约束:必须先得到开发者明确同意、只写与本待办相关的部分、已压缩内容不得自行回读;
  • touchedFiles 在写入时归一化:绝对路径按工作区剥成相对路径、去掉 ./ 与目录尾斜杠、反斜杠转正斜杠、去重;工作区之外的绝对路径保持原样。所以模型写 /Users/.../src/a.ts 也能参与路径提醒与去重(两者都按归一化后的形式比较)。
  • origin(sessionId / turn / seqRange / cwd)与 code(commit / branch,来自 git rev-parse,subprocess 不可用时读 .git/HEAD + refs / packed-refs)全部由 host 填,模型不产出;
  • workspace 由 session cwd 经 workspaceRegistry.resolveByPath 归一化,和右栏的工作区过滤对齐。

读取(M3)

  • todo_list(workspace?, status?):只有索引(id / 标题 / 状态 / 类型),默认看本会话工作区里 open+doing 的卡;workspace: '*' 跨工作区。
  • todo_read(id, part?):无参返回卡片本体(core + mustRead 正文 + park 的 label/why + 坐标 + 触及文件 + note 数);part: 'notes' 给补充历史;part: 'park:n' 给该条备查指针(含 where,正文留给 M6 的 recall)。
    • 说明:mustRead 每条本来就 ≤200 字,是"必读材料",所以放在默认返回里;park 只给 label/why,正文按设计不主动加载。
  • todo_note(id, text, kind?):追加,text ≤300 字,kind = supplement / evidence / status;先校验再落库,不重写卡片。

右栏卡片右上角的 ⌄ 展开详情(同一份数据走 POST /api/todo-assistant/detail),可直接删补充。

检测与提醒(M4)

零模型调用,全部在 host 侧算:

  • 信号:session/event 里的 tool/call 参数(read/write/edit/read_image 的 file_path,grep/glob 的 path),按会话 + 轮累积;
  • 范围:只看本会话创建、状态 open/doing 的卡(origin.sessionId 匹配);
  • 命中条件(默认):精确文件路径相同,或共享目录前缀 ≥ 2 段(src/auth/router.ts vs src/auth/token.ts 命中;src/a.ts vs src/b.ts 不命中);
  • 每轮每个卡片最多提醒一次:step/end 触发检测,turn/start 重置本轮预算,已提醒的卡不会在同轮重复;
  • 注入:ctx.systemPrompt.context({ name: 'todo-assistant/reminder', order: 130, text }),在下一次装配(同轮下一步)给一行: A file touched this step (src/auth/router.ts) relates to todo #td_x7k2「…」; call todo_note if there is evidence worth keeping. 装配即消耗,下一轮之前不会再出现;
  • 角标:list 请求带上 sessionId,命中卡在 L0 上带 hit: true,右栏显示「相关」并描边;turn/start 重置。

未接的信号(DESIGN §7 已决定不做):commit 变化、从触及文件反推符号。两者也是零模型调用,问题在质量——卡的 code.symbols 常为空、符号名是通用词易误报、commit 多是陈旧性信号;路径信号已覆盖"同一个地方又动了"这一主场景,漏的是"文件移动/改名、只改符号、按符号 grep"三类。

原文回读(M6)

todo_recall(id, slice?) 是 L2,两段式,最贵的一次读取(正文会永久留在上下文里、每步重复计费):

  1. 不给 slice → 目录:卡片 origin.seqRange 里每条消息的 seq / 轮次 / 角色 / 首行 40 字 / token 估算,外加总量;
  2. 给 slice: [from, to] → 只返回这一段正文(每条消息截 2000 字、整次上限 12000 字,超了标注 truncated)。

数据来自 ctx.sessionQuery.readSession(id) 的原始日志(不是当前 surface),所以即使那段历史已被压缩替换,也能读回原貌;token 估算优先用 ctx.tokenMeter.estimateMessage,没有就按 ~4 字符/token 粗估。

工具描述里写死了硬规矩:不得自行 recall,必须先征得开发者同意;先给目录,再由开发者选段。

这条约束是指令而非强制(没有 UI 审批拦着)。两次行为探针("早期轮次已压缩,需要知道当时为什么排除方案 A")里模型都是先 todo_read、再停下来请求批准,日志里未授权调用为 0;据此决定不加机械审批,真出现一次漏网再加(DESIGN §6.4)。

手工建的卡 origin.seqRange 是 [0,0],没有可回读区间,会返回 unavailable。

去重(M7)

todo_add 落库前先算一遍"这是不是同一张卡"(§6.5):

  • 候选范围:同 workspace、状态 open/doing 的卡;
  • 命中条件:至少 1 个 touchedFiles 精确相同 且 标题相似度 ≥ 0.55(字符 bigram Dice,忽略大小写/空白/标点);
  • 命中时不建新卡,返回 status: 'duplicate' + 候选 id/标题/相似度/共享文件,让模型去问开发者;开发者同意后用 todo_note 把新事实追加到那张卡;
  • touchedFiles 为空的捕获不参与去重(只靠标题太容易误判)。

误判代价是模型多问一句,比"同一件事两张卡"便宜。

处理(M5)

卡片上的「处理」展开两个动作(DESIGN §3.11):

  • 新会话中立即执行(菜单里的第一个动作,原文案「新开会话」):ctx.remote.session.create({ workspaceId | cwd }) → .prompt({ mode: 'queue', content: [{type:'text', text: seed}] }) → ctx.uiWorkspace.openSession(sessionId)。 seed 是卡片的 L1:标题、现象/原因/意图、下一步、触及文件、必读(含正文)、备查 label/why、写卡时的 commit、补充条数。新会话从一开始就知道自己在处理哪张卡。
  • 插入当前会话:用 inputActions.captureInsertion() + insertText() 往当前输入框里插一句 现在切到待办 #1.3「…」:先用 todo_read 读它,再按里面的「下一步」继续;改完后问我是否标记完成。 只预填、不自动发送 —— 不替人发消息,也不打断正在跑的轮次;回车由开发者按。

两种方式都会在卡片上记 handling: { sessionId, at }(POST /api/todo-assistant/handle), 列表与详情都不再显示处理标记(2026-10 移除):会话接手只创建/发送种子,不写 handling。 字段仍保留在数据模型里以兼容旧卡,todo_read 也还能读到,但 UI 不写入、不展示。

关联改动:卡片的状态不再用下拉菜单——编号左侧的 radio 直接标完成/取消,× 菜单给「删除 / 归档 / 取消」, kind 标签移到左下角,× 移到右上角。

与设计的一处偏差:设计里「处理」是卡片上的 [处理 ▾] 菜单;这里同样是点一下展开两个选项, 只是菜单行内展开而不是浮层。

客户端 → Host 写通道

形态:/api 通道上的 exact Fetch 路由。不是 @Remote,不是 rpc.handle,也不是自建 webServer 路由。

  • Host:ctx.connection.fetch.register({ path: '/api/todo-assistant/<endpoint>', methods: ['POST'], requestBody: 'buffered', fetch })。路由挂在 Connection 已有的 /api 前缀下,Host/Origin 信任围栏与浏览器 cookie 鉴权在进入 handler 之前就生效(无 cookie → 401)。
  • Client:同源 fetch('api/todo-assistant/<endpoint>')(document-relative,兼容挂载前缀)。
  • 不用 @Remote:那些 namespace 由 TypeScript 装饰器在构建期生成,再由应用自己的 ctx.remote 装配挂载;纯 JS 插件没有这条构建链。
  • 不用 ctx.connection.rpc.handle():它挂路由时读的是 Connection 服务自己的 fiber (get rpc() 里 const owner = this.ctx),那条 fiber 只 inject 了 webRuntime,必然抛 cannot get property "webServer" without inject。intercept('/api', …) 不碰 webServer,但 /api 的中继已被 API Gateway 独占。

线协议(裸 JSON,不套 Gateway 信封):

POST /api/todo-assistant/<endpoint>
{ ...payload }
→ { "ok": true, "value": ... }
→ { "ok": false, "error": { "code": "todo/title-required", "message": "...", "details": {} } }

验证

离线(不需要启动 GUI,不动 profile):

node scripts/verify-domain.mjs

它用本地 dsh 安装里的真实 storage / storage-json / storage-domain 打开本插件的 domain, 跑完增删改查与 note 追加/删除,最后关闭再重开,确认记录跨重启存活。

安装后(当前 profile):

# 1. 已激活
#    在会话里 cordis_inspect_query → Slots.listSubTree(root: "sidebar.right.pane.tab")
#    应看到 key = "todo-assistant" 的 occupant
# 2. 冒烟调用(需要浏览器 session cookie,见下;无 cookie 应返回 401)
curl -sS -X POST "http://127.0.0.1:3080/api/todo-assistant/list" \
  -H 'content-type: application/json' \
  -H 'Host: 127.0.0.1:3080' -H 'Origin: http://127.0.0.1:3080' \
  -b "$COOKIE" \
  --data '{"all":true}'

cookie 就是浏览器里那份 dsh-auth-*(签名密钥在 ~/.dsh/.credentials.yaml 的 client-connection/browser-session 记录里;签名 key 要先 base64url 解码)。

安装

三种方式,任选一种。都需要在 DSH 里调用 plugin_manager install_bundle(需要审批),装完重启 dsh。

1. 从本地目录(开发用) —— 源码留在这里,不要放进 ~/.dsh:

plugin_manager install_bundle  target = <本仓库绝对路径>

2. 从 GitHub 直接装 —— 不用先 clone:

plugin_manager install_bundle  target = https://github.com/zangoose335/dsh-todo-assistant.git

想锁版本就在地址后加 #<commit>,例如 ...#77215f3。

3. 从 npm(发布后):

plugin_manager install_bundle  target = todo-assistant@0.1.0

install_bundle 要求 PATH 里有 pnpm(本机通过 corepack enable pnpm 提供)。 方式 1 装完后 profile 里是一个符号链接:

~/.dsh/profiles/web/node_modules/todo-assistant -> <本仓库绝对路径>

不同方式装的是同一个包名,切换前先 remove_bundle 掉旧的那份。

必须重启 dsh 才会加载 host half:linked 包的安装内导入(zod、@deepseek-ai/dsh-storage-domain) 依赖启动时建立的 profile 解析表,运行中的进程不会在安装后重建它。之后每次改 host 代码都要重启; 只改 client.js 刷新页面即可。

打开 tab

右栏 → 顶部 +(Add)打开 guide → 点「待办助理」。页签布局按会话记在 localStorage,重开仍在。

许可证

MIT © 2026 黑桃伍