前言¶
DeepSeek Harness 的内置 todo_write 只在当前会话有效,关闭会话就清空,不适合跨会话、跨工作区复用任务清单。CrabTodo 把待办持久化到 JSON 文件,模型可以通过工具增删改查,侧边栏提供完整的任务管理页面。
这是什么¶
CrabTodo 是一个为 DeepSeek Harness 设计的持久化待办插件,由开发者 yixing233 维护。它提供两套能力:一是给模型暴露的 6 个工具,二是 Web 界面右侧栏的一个任务标签页。数据存储在 $DSH_HOME/storage/crabtodo/todos.json,重启、切换工作区不会丢失。
核心功能¶
模型工具¶
插件注册了以下 6 个工具:
crabtodo_add:新增任务,参数包括标题、备注、状态、优先级、标签、范围、置顶。crabtodo_list:查询任务,支持按范围、状态、标签、关键词过滤,返回结果按置顶、状态、优先级、创建时间排序。crabtodo_update:更新任务任意字段,支持在项目/全局间移动、置顶、手动排序;状态改为 done 时自动记录完成时间。crabtodo_done:一键完成任务。crabtodo_remove:删除单个任务,走软删除进入回收站,支持恢复。crabtodo_clear:清除所有已完成任务(永久),未完成的不动。
两级范围¶
任务分为项目(project)和全局(global)两种范围:
- 项目任务归属于某个工作区根目录,随仓库走,在某个工作区里新建时的默认范围。
- 全局任务跨所有项目共享,显式指定或当前没有工作区时产生。
内置 todo_write 已经覆盖了会话级临时清单,CrabTodo 不再重复建模这一层。
Web 侧边栏页面¶
CrabTodo 在右侧栏以标签页形式呈现,默认宽度可通过配置调整。页面功能包括:
- 底部卡片新建任务,展开可填备注、优先级、状态、标签,展开方向朝上。
- 每行悬停可编辑、置顶、标记进行中、删除(二次确认后软删除,提示条可一键撤销)。
- 整行可拖拽排序,拖拽重排当前视图;任务行可拖进对话框,以引用块形式写入输入框。
- 状态筛选用官方 SegmentedTabs,下方是搜索框,支持按标题、备注、标签关键词即时过滤。
- 标签体系受管理,可在设置页增删,表单中点选芯片或自由输入自动入库。
- 页面提供「清理已完成」批量整理,仅在已完成标签页显示。
- 右上角「回收站」按钮进入回收站,可逐条恢复或彻底删除;设置页可调整强调色、字体大小、备注预览行数、删除确认开关、动画开关、右栏默认宽度(% 数值)、启动时默认范围/状态。
悬浮模式¶
侧栏顶栏的浮窗按钮可将面板取出为可拖动、可调大小的磨砂玻璃悬浮窗。悬浮窗挂在宿主的 shell.overlay 全局悬浮层上,切换会话不消失。窗口位置和折叠状态保存在 dsh 存储中,重启后仍在原处。悬浮窗内同样支持「添加到对话」。
添加到对话¶
每条任务悬停后的第二个按钮会把任务写入当前会话输入框,采用显式字段格式,并标明来自 dsh-crabtodo 插件,列出可用工具。模型据此可按任务 ID 调用工具查询或操作任务。写入采用 inputActions.setDraft(),追加模式,不会覆盖已有内容。
数据与存储¶
任务数据以 JSON 格式存储,结构如下:
{
"version": 1,
"updatedAt": 1792468933856,
"tasks": [
{
"id": "ct_9adbfaac",
"title": "写文档",
"notes": "",
"status": "pending",
"priority": "normal",
"scope": "project",
"project": "C:/code/my-app",
"tags": ["docs"],
"createdAt": 1792468905576,
"updatedAt": 1792468905576,
"completedAt": null,
"deletedAt": null,
"pinned": false,
"order": null,
"source": "model"
}
]
}
- status:pending / in_progress / done
- priority:low / normal / high / urgent
- scope:project / global(全局任务 project 为 null)
- deletedAt:软删除时间戳,非 null 表示在回收站中
- pinned:置顶标记,置顶项恒排最前
- order:手动排序序号,为 null 时走自动阶梯排序
旧版数据(没有 scope 字段)会被当作 global 读取。
写入采用「临时文件 + rename」的原子替换,并发工具调用不会互相覆盖。文件损坏时插件会退化为空列表继续可写。
HTTP API¶
侧边栏页面通过以下 API 与插件通信,写操作要求同源,跨站写入返回 403:
- GET /crabtodo/api/tasks:获取整份快照
- POST /crabtodo/api/tasks:新增任务
- PATCH /crabtodo/api/tasks/
:局部更新,{“deleted”: false} 可恢复回收站任务 - DELETE /crabtodo/api/tasks/
:删除(软删除),?purge=1 彻底删除 - POST /crabtodo/api/clear-completed:清除已完成(永久)
- POST /crabtodo/api/purge-deleted:清空回收站(永久)
- GET /crabtodo/api/events:SSE,每次提交后发一条 change
安装与启用¶
从 npm 安装:
dsh plugin --profile web add dsh-crabtodo
或在 Web 界面「插件 → 添加插件」中输入包名 dsh-crabtodo。
从本地目录安装:
dsh plugin --profile web add ./dsh-crabtodo
安装后 dsh plugin 会把包名写进该 profile 的 dsh.profile.bundles,重启 dsh web 生效。
卸载:
dsh plugin --profile web remove dsh-crabtodo
配置¶
插件在 cordis.patch.yml 中自带默认行,可在 profile 的 cordis.patch.yml 里按 id: crabtodo 覆盖:
| 字段 | 默认值 | 含义 |
|---|---|---|
dataFile |
~/.dsh/storage/crabtodo/todos.json |
JSON 存储路径 |
exposeTools |
true |
是否注册 crabtodo_* 工具 |
exposeHttp |
true |
是否为侧边栏页面提供 /crabtodo API |
toolHint |
一句说明 | 追加到每个工具描述的提示语 |
projectKey |
空 | 无工作区根时的项目键兜底 |
示例——改用工作区内的文件:
- id: crabtodo
name: dsh-crabtodo
config:
dataFile: ./todos.json
典型用法¶
用工具管理任务¶
在会话中让模型调用工具:
dsh --profile <your-profile> "Call crabtodo_add once with title 'probe'. Then call crabtodo_list and report the count."
判读结果的两条硬证据:终端里出现真实工具往返,且落盘数据里该任务的 source 为 "model"。
用页面管理任务¶
在右侧栏打开 CrabTodo 标签页,新建任务、筛选、排序、拖拽整理。悬停任务点击第二个按钮,将任务引用写入当前会话输入框,模型可据此操作。
用悬浮窗快速查看¶
点击侧栏顶栏的浮窗按钮,任务面板以悬浮窗形式显示,可拖动、折叠。切换会话时悬浮窗不消失,便于持续查看任务全貌。
适用场景与注意¶
适合需要跨会话、跨工作区复用任务清单的场景,特别是开发过程中需要模型参与任务管理的环境。
插件以当前 DSH 进程权限运行,安装前应检查源码与许可证。数据存储在本地文件,注意备份和权限。
结尾¶
CrabTodo 为 DeepSeek Harness 提供了持久化、模型可操作的待办能力,配合 Web 侧边栏和悬浮窗,方便在会话内外统一管理任务。相关资料可查看插件目录页与 GitHub 仓库。