dsh-worktodo 0.0.0-stage → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,141 @@
1
+ # 更新日志
2
+
3
+ > 本文提到的 `tools/`、`docs/` 等路径都在**仓库**里,不在 npm 发布包内:<https://github.com/olimc2016/dsh-worktodo>
4
+
5
+ ## 0.1.3
6
+
7
+ ### 新增
8
+
9
+ - **排序模式**:面板顶部新增「手动 / 优先级 / 创建时间」三档排序(`worktodo_list` 也开放了同样的 `sort` 参数)。
10
+ - `manual`(默认):尊重你拖动过的顺序;**没拖过的条目自动退回**优先级 → 截止日期 → 创建时间,所以一上手看到的顺序依然合理;
11
+ - `priority`:高优先级在前,同优先级按截止日期,无日期垫底;
12
+ - `created`:最近添加的在前。
13
+ 三种模式都保持「已完成永远沉底」。
14
+ - **拖动排序**:按住任意一行拖到目标位置即可调整顺序。拖动时会**自动切到手动模式**(否则松手后看起来"没生效");
15
+ 落序由宿主在校验后写盘(`POST /worktodo/reorder`,收到完整 id 顺序,只写真正变了的记录);
16
+ 传了不存在的 id 会**显式失败**(`not-found`),不会静默改一半。
17
+
18
+ ### 测试
19
+
20
+ - `verify-records` 新增 2 例:三种排序模式的顺序、`applyManualOrder` 的纯函数语义(含"没拖过的垫后");
21
+ - `smoke-host` 新增 2 例:`/list?sort=created` 的顺序、`POST /reorder` 落盘并在 manual 模式生效(含坏 id 的显式失败)。
22
+
23
+ ## 0.1.2
24
+
25
+ ### 新增
26
+
27
+ - **按项目管理待办**:面板顶部新增「**按截止 / 按项目**」视图切换。
28
+ 「按项目」视图里每个项目是一个可折叠分组,标题显示「未完成/总数 · 逾期 N」;
29
+ 没写项目的记录归入「未归类」并**永远排在最后**。
30
+ 排序规则:未完成多的项目在前 → 未完成里最早截止日期更早的在前 → 名字字典序。
31
+ 宿主侧 `/worktodo/list` 新增 `projectGroups` 字段(`groupByProject`),且**不受 `project` 参数收窄**——
32
+ 这样面板一次就能拿到全部项目用于切换。
33
+
34
+ ### AI 友好
35
+
36
+ - **给模型的用法指引**:通过官方 `ctx.systemPrompt.section()` 贡献一段提示(段名 `worktodo:guidance`,
37
+ `order` 取 3050——官方内置工具段是 1000–3000、`MCP_SERVERS` 是 3100,插在两者之间)。
38
+ 内容讲清三件事:什么时候该用(用户说出承诺/截止日期,或发现超出本会话、仍需人跟进的待办)、
39
+ 什么时候**不该**用(当前任务的步骤拆解属于会话内的 `todo_write`,两者互补)、
40
+ 以及「加之前先查重」「做完用 `worktodo_done`」「标题写成祈使句」等约定。
41
+ - **批量登记**:新增 `worktodo_add_many`,一次调用登记多条;某条不合法只跳过那一条并把原因回传,
42
+ 不影响其余条目(用户一口气说好几件事时省调用)。
43
+
44
+ ### 测试
45
+
46
+ - `verify-records` 新增 4 例覆盖 `groupByProject`(未归类最后、未完成多者在前、桶内 total/open/overdue、空输入);
47
+ - `smoke-host` 新增 1 例断言 `/list` 载荷确实带 `projectGroups` 且形状正确。
48
+
49
+ ## 0.1.1
50
+
51
+ ### 修复(重要)
52
+
53
+ - **装出来的插件根本无法启动**:0.1.0 把运行期真正 import 的三个官方平台包(`@deepseek-ai/dsh-tools`、
54
+ `@deepseek-ai/dsh-storage-domain`、`@deepseek-ai/dsh-home-paths`)只声明为 `peerDependencies`,
55
+ 于是从 npm / GitHub 装出来的包**没有任何可解析的平台包**,DSH 启动时该插件直接加载失败
56
+ (实测:工具全部消失,`worktodo_list` 报 `unknown tool`)。现在改为 `dependencies`——
57
+ 实测从 GitHub 安装后,从插件自身位置三个包都能解析。
58
+ - **npm 包页面没有 README**:0.1.0 是经「暂存发布」(staged publishing)上线的,而实测那条路径**不会写入 registry 的 `readme` 字段**
59
+ (同机对照:普通 `publish` 的包 `readme` 有 8193 字符,本包 0 字符),于是包页面没有 README。
60
+ 本版改为**直接发布**——OIDC 下同样不需要人类 2FA,所以并没有牺牲自动化。
61
+
62
+ ### 文档
63
+
64
+ - 三份文档(README 中英、CHANGELOG)里补了**绝对仓库地址**的说明:提到 `docs/`、`tools/` 等目录时指向仓库
65
+ (这些文件不在 npm 包内)。npm 页面上的读者因此能找到出处,而不会撞上够不着的路径。
66
+ - `publish.yml` 的默认发布方式改为**直接发布**,同时保留手动「暂存 + 网页批准」入口。
67
+
68
+ ## 0.1.0
69
+
70
+ 首个可用版本。
71
+
72
+ ### 核心
73
+
74
+ - **人机共享的工作待办**:一份逻辑(`src/service.mjs`)同时供侧栏面板与 agent 工具调用,
75
+ 所以「面板点完成」和「agent 调 `worktodo_done`」在数据上的行为完全一致。
76
+ - **富字段**:优先级(高/普通/低)、截止日期、项目、备注——补上官方 `todo_write`
77
+ 只有「内容 + 三态」的空缺。
78
+ - **逐项编辑**:按 id、完整标题或唯一标题前缀定位单条修改,不像 `todo_write` 那样整表替换。
79
+ - **跨会话持久**:数据不属于任何会话,重启、换会话、换项目都还在。
80
+ - **分组视图**:逾期 / 今天 / 本周 / 以后 / 已完成,含统计(未完成 / 逾期 / 今天 / 进行中 / 今日完成)。
81
+
82
+ ### agent 工具
83
+
84
+ - `worktodo_add` / `worktodo_list` / `worktodo_update` / `worktodo_done` / `worktodo_remove`
85
+ - `worktodo_adopt`:把本会话 `todo_write` 的条目提升为工作待办(按标题去重),
86
+ 桥接官方会话计划与人的长期列表。
87
+
88
+ ### 存储
89
+
90
+ - 优先官方 `ctx.storageDomain`(`$DSH_HOME/storages`):跨重启保留但不进会话事件日志。
91
+ - 回退 JSON 文件(`$DSH_HOME/worktodo/todos.json`):**原子写**(临时文件 + rename)、
92
+ 写入串行化、坏文件不静默清空、单条坏记录跳过;文件是人能直接打开手改、能进 git 的形态。
93
+ - 支持 `storePath` 配置固定位置;`~` 会展开。
94
+
95
+ ### 兼容与降级
96
+
97
+ - 目标 **DSH 0.2.x**(0.2.0-rc.2 实测),Node ≥ 22.19.0,`dependencies` 为空。
98
+ - 平台包全部声明为**可选 peer**:`tools` 或 `webServer` 缺失时,插件以「少一半能力」的形态继续工作;
99
+ `@deepseek-ai/dsh-tools` 解析不到时只失去工具能力,面板照常可用(日志写明原因)。
100
+
101
+ ### 修复(发布前真机回归发现)
102
+
103
+ - **工具返回值必须是 lossless JSON**:`worktodo_add` 在不传截止日期时返回了
104
+ `due: undefined`,被 DSH 的返回值校验判为无效,**整次调用被拒**——而「加一条没有截止日期的
105
+ 待办」正是最常见的用法(`worktodo_update` 清空截止日期后同理)。已改为可选字段缺席时**删键**
106
+ 而不是留 `undefined`。真机重试后暴露的第二个现象见 `docs/verification.md`:
107
+ 以 `link:` 安装的插件,源码改动需要**重启**才会换模块 generation。
108
+ - 新增可观测性:`/worktodo/health` 现在报告运行中的实际 `version` 与
109
+ `tools: { status, registered, names, error }`——工具静默没注册这类问题不用再翻日志猜。
110
+
111
+ ### 测试(172 例,均不需要启动 DSH)
112
+
113
+ - `tools/verify-records.mjs`(22):日期归一化与相对日期、状态/优先级同义词、完成时间维护、
114
+ 引用解析(id / 标题 / 前缀 / 歧义)、分组边界(本周日 vs 下周一)、统计口径、筛选、坏记录修复。
115
+ - `tools/verify-store.mjs`(11):官方 `defineDomain` 契约、领域名合法、记录 schema 与官方读取路径一致、
116
+ domain 后端增删改查、文件后端原子写与并发写、坏文件与坏记录容忍、`~` 展开。
117
+ - `tools/verify-service.mjs`(18):显式状态(`empty-title` / `not-found` / `ambiguous-ref` /
118
+ `empty-patch` / `store-unreadable` / `store-write-failed`)、完成与取消完成的 `completedAt` 语义、
119
+ 统计不随筛选变化、提升去重、变更通知。
120
+ - `tools/smoke-host.mjs`(26):假 ctx 里跑通 `apply` → 7 条路由 → 服务 → 存储的完整增删改查,
121
+ 方法围栏与 `connection` 准入,失败路径(空标题、坏 JSON、未知 filter),health 自检字段,
122
+ 7 个工具经**官方 `defineTool`** 校验注册并真实执行,以及 5 条「工具返回值必须无损」的断言——
123
+ 判定用的是 **DSH 自己的校验器** `snapshotJsonValue`(来自 `@deepseek-ai/dsh-util-values`,
124
+ 就是 `@deepseek-ai/dsh-tools` 报 "value is not lossless JSON" 时用的那一个函数),
125
+ 并有一条专门断言「旧写法 `due: undefined` 必须被它拒绝」,用来证明这条守卫确实有牙齿。
126
+ - `tools/smoke-contract.mjs`(12):**客户端 ↔ 宿主契约**。从 `src/client/index.js` 静态提取它实际请求的
127
+ 路径与字段名,与宿主真实注册的路由、真正消费的字段比对——防「字段名打错 → 那个功能永远静默失效」
128
+ (例如截止日期永远存不上,而没有任何红灯);再用客户端字面上的报文形状打真实路由,验证两处清空约定
129
+ (create 用 `due: null`,行内编辑用 `due: ''` / `project: ''`)以及 toggle / adopt / remove / list 的字段完整性。
130
+ 已做变异验证:路径改成 `/statuss` 会红 3 条,字段 `due` 改成 `duedate` 会红 1 条。
131
+ - `tools/smoke-client.mjs`(14):客户端 bundle 的模块加载器格式(id 必须等于包名)、
132
+ bundle 只允许 require react(官方规范禁止依赖 Harness 客户端包)、侧栏与主面板注册到正确的 slot
133
+ 且 id/key 同名、locale 字典 zh/en 键一一对应、**首屏渲染不抛异常**(白屏是最致命的失败模式)、
134
+ 挂载后确实发起 `/worktodo/list` 请求、`useProjection` 缺失或返回空值时安全。
135
+ - `tools/verify-submission.mjs`(13):**收录 PR 的本地门禁**。上游(deepseek1024.com 的目录仓)
136
+ 会对提交的 `catalog/plugins/*.json` 跑静态审查并**读仓库核对**,所以先在本地把这些规则跑一遍,
137
+ 免得提一个必被拒的 PR:字段集合与 schema 一致、id 与文件名派生规则、`repository`/`name` 与
138
+ `package.json` 一致、`category` 在 11 个法定分类内、`added` 是合法日期、描述里没有最上级措辞。
139
+ 另外两条只在 **GitHub 分发路径**下才致命、npm 发布看不出来的检查:`main` / `cordis.patch.yml` /
140
+ `lib/client.js` 等**必须都在 `git ls-files` 里**(git 安装只拿跟踪文件、且不跑构建),
141
+ 以及 patch 里那一行的 `name` **必须等于包名**(否则新用户装上去 Loader 解析不到插件)。
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 oli20
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.en.md ADDED
@@ -0,0 +1,111 @@
1
+ # Work Todo · dsh-worktodo
2
+
3
+
4
+ **A work todo list that belongs to you, not to a session.** A dedicated DSH sidebar panel, plus `worktodo_*` tools so the agent reads and writes **the same** list you do.
5
+
6
+ > Works with **DSH 0.2.x** (tested on 0.2.0-rc.2) · runtime deps are **3 official platform packages only** (no third-party deps) · community plugin, unofficial
7
+
8
+ > **About the paths in this file**: references to `docs/`, `tools/` and similar point into the **repository** —
9
+ > those files are not part of the npm package. Repository: <https://github.com/olimc2016/dsh-worktodo>
10
+
11
+ ## The gap it fills
12
+
13
+ DSH ships `todo_write`: the plan of **one agent session**. It replaces the whole list every call, has only `pending / in_progress / completed`, and — quoting the official docs — "the list belongs to the one agent session that created it… there is no way to share a list across agents". No priority, no due date, no project, no per-item edit. Close the session and the plan is gone.
14
+
15
+ So the things that actually need to survive — waiting on a reply, waiting on review, shipping next week — have nowhere to live.
16
+
17
+ **This list is for the human.** Priorities, due dates, projects, notes. It persists across sessions and projects. The agent can read and write it, but the source of truth is yours.
18
+
19
+ | | official `todo_write` | **dsh-worktodo** |
20
+ |---|---|---|
21
+ | Owned by | one agent session | **you** (cross-session, cross-project) |
22
+ | Update | whole-list replacement | **per-item create / edit / delete** |
23
+ | Fields | content + 3 states | content + **priority + due date + project + notes** |
24
+ | Shared across agents | ❌ not supported | ✅ one list, human and agent both read/write |
25
+ | Views | in-session checklist | **overdue / today / this week / later / done** + stats |
26
+ | Storage | session event log | `$DSH_HOME/storages` (official storage) or `~/.dsh/worktodo/todos.json` |
27
+
28
+ The two are complementary: `worktodo_adopt` promotes the entries worth keeping from this session's `todo_write` into your work list.
29
+
30
+ ## Install
31
+
32
+ **Option 1: straight from GitHub** (no npm package needed; restart DSH afterwards)
33
+
34
+ ```bash
35
+ dsh plugin --profile desktop add github:olimc2016/dsh-worktodo
36
+ ```
37
+
38
+ This path is verified (see `docs/verification.md`): the browser half's build output `lib/client.js` is committed,
39
+ and the package declares no `prepare`/`install` build script, so a git install needs **no build authorization**
40
+ measurement (install from GitHub): **1 top-level package** plus the 3 official platform packages, about **12 MB** installed
41
+ (~8 MB of that is zod, pulled in by the official `@deepseek-ai/dsh-tools`), and no development dependencies.
42
+ no nested `node_modules`, and the installed tree matches the npm tarball file for file.
43
+
44
+ **Option 2: from npm** (once the package is published)
45
+
46
+ ```bash
47
+ dsh plugin --profile desktop add dsh-worktodo
48
+ ```
49
+
50
+ **Option 3**: use the DSH sidebar — **Plugins → Add plugin** — and enter `dsh-worktodo` or the repository URL.
51
+
52
+ ## Usage
53
+
54
+ **Panel**: stats on top (open / overdue / today / in progress / completed today), a quick-add box (title + due date + priority, Enter to save), then the grouped list. Each row can be checked off, edited inline by clicking the title, or deleted (with a second-click confirmation).
55
+
56
+ **Agent tools**: the model can file, query, advance and archive your work todos without you relaying anything.
57
+
58
+ | Tool | Purpose |
59
+ |---|---|
60
+ | `worktodo_add` | File a task (optional due date, priority, project, notes) |
61
+ | `worktodo_list` | List with `open` / `today` / `overdue` / `week` / `doing` / `completed` / `all`, filterable by project or keyword |
62
+ | `worktodo_update` | Edit one item without touching the rest |
63
+ | `worktodo_done` | Mark done, or back to in-progress / pending |
64
+ | `worktodo_remove` | Delete (use `worktodo_done` to keep the record instead) |
65
+ | `worktodo_adopt` | Promote this session's `todo_write` entries, de-duplicated by title |
66
+
67
+ One sentence is enough:
68
+
69
+ > "File the three things I need to follow up today into my work todos, and mark tomorrow morning's as high priority."
70
+
71
+ ## Where the data lives
72
+
73
+ Chosen automatically; the actual location is reported by `/worktodo/health` and shown at the bottom of the panel:
74
+
75
+ 1. **Official storage** (`ctx.storageDomain`, mounted by DSH by default) — data lands in `$DSH_HOME/storages`. This is the documented place for plugin-owned state that must survive restarts without becoming session events; a few dozen todos do not belong in the session history.
76
+ 2. **JSON file fallback** — `$DSH_HOME/worktodo/todos.json`, used automatically in minimal compositions without the storage service. That file is meant to be opened, hand-edited and committed to git; a corrupted file is never silently wiped, and a single bad record is skipped rather than losing the list.
77
+
78
+ Pin your own path in `cordis.patch.yml`:
79
+
80
+ ```yaml
81
+ - id: worktodo
82
+ name: 'dsh-worktodo'
83
+ config:
84
+ storePath: /Users/me/notes/worktodo.json
85
+ ```
86
+
87
+ ## Compatibility
88
+
89
+ - **DSH 0.2.x** (tested against 0.2.0-rc.2 APIs; DSH's version gate rejects plugins pinned to older lines)
90
+ - **Node ≥ 22.19.0**
91
+ - No runtime npm dependencies. Platform packages (`@deepseek-ai/dsh-tools`, `dsh-storage-domain`, `dsh-home-paths`) are **optional peers** resolved from the DSH installation; if one genuinely cannot be resolved the plugin degrades to panel-only instead of failing to load, and logs the reason.
92
+
93
+ ## Development
94
+
95
+ ```bash
96
+ pnpm install # esbuild ships a prebuilt binary; no approve-builds needed
97
+ pnpm run build # build lib/client.js (browser half)
98
+ pnpm test # 172 cases: data model / storage / service / host wiring and tools / client contract / client bundle / CI contract / privacy gate / catalog gate
99
+ pnpm run watch # incremental client build
100
+ ```
101
+
102
+ Release flow (trusted publishing + staged approval) is documented in `docs/releasing.md`:
103
+
104
+ ```bash
105
+ ```
106
+
107
+ No DSH instance is needed to run the suite: `verify-records` (pure data), `verify-store` (real file IO plus a genuine **official `defineDomain` contract check**), `verify-service` (explicit statuses and boundaries), `smoke-host` (apply → routes → service → storage in a fake context, plus tool registration and execution with schemas validated by the **official `defineTool`**), `smoke-contract` (extracts the paths and field names the client actually sends and checks them against the host's real routes — catching silent failures where a mistyped field means, for instance, that due dates never save), `smoke-client` (bundle format, slot registration, and a first render that must not throw), and `verify-submission` (a local gate for the catalog PR: fields, filename, category and date, plus checks that only matter on the GitHub distribution path, such as whether every file a git install needs is actually tracked).
108
+
109
+ ## License
110
+
111
+ MIT © 2026 oli20
package/README.md CHANGED
@@ -1,3 +1,130 @@
1
- # Temporary Holding Version
1
+ # 工作待办 · dsh-worktodo
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ **归你所有、跨会话持久的工作待办。** DSH 侧栏一个独立面板,agent 通过 `worktodo_*` 工具读写**同一份**列表。
4
+
5
+ > 兼容 **DSH 0.2.x**(0.2.0-rc.2 实测)· 运行期只依赖 **3 个官方平台包**(无任何第三方依赖)· 社区插件,非官方
6
+
7
+ > **关于本文里的路径**:提到 `docs/`、`tools/` 等目录时,指的是**仓库**里的文件——它们不在 npm 发布包内。
8
+ > 仓库地址:<https://github.com/olimc2016/dsh-worktodo>
9
+
10
+ ---
11
+
12
+ ## 它解决什么问题
13
+
14
+ DSH 自带的 `todo_write` 是**当前这个 agent 会话**的计划:整表替换、只有 `pending / in_progress / completed` 三态、**只属于那一个会话**。官方文档写得很直白——「任务列表属于创建它的那一个 agent 会话……不存在跨 agent 共享列表的方式」,而且**没有优先级、没有截止日期、没有项目、没有逐项编辑**。会话一关,那份计划就翻篇了。
15
+
16
+ 于是真实工作里那些「明天还得接着办」的事没有地方放:等对方回复、等评审、下周要交的东西、这个月要跟的活。
17
+
18
+ **这份列表是给人的**:有优先级、截止日期、项目和备注,跨会话、跨项目一直在;agent 能读能写,但真源在你手里。
19
+
20
+ | | 官方 `todo_write` | **dsh-worktodo** |
21
+ |---|---|---|
22
+ | 归属 | 单个 agent 会话 | **你**(跨会话、跨项目) |
23
+ | 更新方式 | 整表替换 | **逐项增删改** |
24
+ | 字段 | 内容 + 三态 | 内容 + **优先级 + 截止日期 + 项目 + 备注** |
25
+ | 跨 agent 共享 | ❌ 官方明确不支持 | ✅ 同一份列表,人与 agent 都读写 |
26
+ | 视图 | 会话内清单 | **逾期 / 今天 / 本周 / 以后 / 已完成** 分组 + 统计 |
27
+ | 数据位置 | 会话事件日志 | `$DSH_HOME/storages`(官方 storage)或 `~/.dsh/worktodo/todos.json` |
28
+
29
+ 两者不冲突:`worktodo_adopt` 可以把你这个会话的 `todo_write` 里值得留下的条目**一键提升**成工作待办。
30
+
31
+ ## 安装
32
+
33
+ **方式一:直接从 GitHub 装**(不依赖 npm 上的包;装完重启 DSH)
34
+
35
+ ```bash
36
+ dsh plugin --profile desktop add github:olimc2016/dsh-worktodo
37
+ ```
38
+
39
+ 这条路是实测过的(见 `docs/verification.md`):仓库里提交了浏览器半侧的构建产物 `lib/client.js`,
40
+ 包内没有 `prepare`/`install` 这类构建脚本,所以 **git 安装不需要任何构建授权**,也不会把开发依赖装进来
41
+ ——实测(从 GitHub 安装):顶层解析 **1 个包** + 3 个官方平台包,安装约 **12 MB**(其中约 8 MB 是官方 `@deepseek-ai/dsh-tools` 依赖的 zod),
42
+ 包内含已构建的 `lib/client.js`,**无需构建授权**。
43
+
44
+ > **为什么平台包必须是 `dependencies` 而不是 peer**:0.1.0 曾只声明 peer,结果从 npm/GitHub 装出来的包里
45
+ > **没有任何可解析的平台包**,DSH 启动时该插件直接加载失败(工具全部消失)。0.1.1 起改为 `dependencies`——
46
+ > 实测安装后从插件自身位置三个包都能解析。
47
+ (注意:DSH 的插件安装器会额外在包目录里装一次开发依赖,本机观察到 22 MB;那是安装器行为、与包本身无关,
48
+ 删掉不影响运行——见 `docs/verification.md`。)
49
+
50
+ **方式二:从 npm 装**(包发布后可用)
51
+
52
+ ```bash
53
+ dsh plugin --profile desktop add dsh-worktodo
54
+ ```
55
+
56
+ **方式三**:在 DSH 侧栏「插件 → 添加插件」里填 `dsh-worktodo` 或仓库地址。
57
+
58
+ 装好后侧栏会多一个**「待办」**入口,设置 → 插件里也能看到它。
59
+
60
+ ## 用起来
61
+
62
+ **面板**:顶部是统计(未完成 / 逾期 / 今天 / 进行中 / 今日完成),中间是快速添加框(标题 + 截止日期 + 优先级,回车即存),下面是分组列表。每行可以直接勾完成、点标题行内改、删除(二次确认)。
63
+
64
+ **agent 工具**:模型可以自己登记、查询、推进和归档工作待办,不需要你转述。
65
+
66
+ | 工具 | 用途 |
67
+ |---|---|
68
+ | `worktodo_add` | 登记一件事(可带截止日期、优先级、项目、备注) |
69
+ | `worktodo_list` | 查列表:`open` / `today` / `overdue` / `week` / `doing` / `completed` / `all`,可按项目或关键词过滤 |
70
+ | `worktodo_update` | 逐项修改(不会像整表替换那样动到别的条目) |
71
+ | `worktodo_done` | 标完成,或标回进行中 / 待办 |
72
+ | `worktodo_remove` | 删除(做完的事请用 `worktodo_done` 留痕) |
73
+ | `worktodo_adopt` | 把本会话 `todo_write` 的条目提升为工作待办,按标题去重 |
74
+
75
+ 给 agent 的一句话就能用起来:
76
+
77
+ > 「把今天要跟进的三件事记到工作待办里,明天上午的标高优先级。」
78
+
79
+ ## 数据存在哪
80
+
81
+ 按优先级自动选择,`/worktodo/health` 与面板底部都会显示当前实际位置:
82
+
83
+ 1. **官方 storage**(`ctx.storageDomain`,DSH 默认挂载)——数据落在 `$DSH_HOME/storages`。
84
+ 这是官方给「插件自有、跨重启保留、不进会话事件」的数据指定位置:几十条待办不必变成会话历史。
85
+ 2. **JSON 文件回退**——`$DSH_HOME/worktodo/todos.json`。storage 服务缺失的精简组合里自动走这条路;
86
+ 这个文件**是人能直接打开、手改、进 git** 的形态,写坏了也不会被静默清空(单条坏记录跳过,其余照常读出)。
87
+
88
+ 想在 `cordis.patch.yml` 里固定路径(例如放进自己的笔记仓库):
89
+
90
+ ```yaml
91
+ - id: worktodo
92
+ name: 'dsh-worktodo'
93
+ config:
94
+ storePath: /Users/me/notes/worktodo.json
95
+ ```
96
+
97
+ ## 兼容
98
+
99
+ - **DSH 0.2.x**(官方版本闸门会把锁在旧版本的插件拒掉,本插件按 0.2.0-rc.2 的 API 编写并实测)
100
+ - **Node ≥ 22.19.0**
101
+ - `dependencies` 为空:不装任何运行期 npm 包。平台包(`@deepseek-ai/dsh-tools`、
102
+ `dsh-storage-domain`、`dsh-home-paths`)都声明为**可选 peer**——DSH 自带这些包,从安装目录解析;
103
+ 真解析不到时插件会降级成「只有面板」而不是加载失败(日志里会写一行原因)。
104
+
105
+ ## 开发
106
+
107
+ ```bash
108
+ pnpm install # esbuild 用预编译二进制,无需 approve-builds
109
+ pnpm run build # 打 lib/client.js(浏览器半侧)
110
+ pnpm test # 155 个用例:数据模型 / 存储 / 服务 / 宿主接线与工具 / 客户端↔宿主契约 / 客户端 bundle / CI 契约 / 隐私门禁 / 收录门禁
111
+ pnpm run watch # 改客户端时增量构建
112
+ ```
113
+
114
+ 发版流程(Trusted Publishing + 暂存批准)见仓库里的 `docs/releasing.md`:
115
+
116
+ ```bash
117
+ ```
118
+
119
+ 测试策略:不用启动 DSH 就能跑完——
120
+ `verify-records`(纯数据)、`verify-store`(真实文件 IO + **官方 `defineDomain` 契约校验**)、
121
+ `verify-service`(显式状态与边界)、`smoke-host`(假 ctx 里跑通 apply → 路由 → 服务 → 存储,
122
+ 以及工具注册与执行,工具 schema 由**官方 `defineTool`** 校验)、
123
+ `smoke-contract`(从客户端源码提取它实际发的路径与字段,与宿主真实路由比对——防字段名打错导致的
124
+ 静默失效,例如截止日期永远存不上)、`smoke-client`(bundle 格式、slot 注册、首屏渲染不抛异常)、`verify-submission`
125
+ (收录 PR 的本地门禁:字段/文件名/分类/日期 + 「git 安装必需的文件是否都已入库」这类只在 GitHub
126
+ 分发路径下才致命的检查)。
127
+
128
+ ## License
129
+
130
+ MIT © 2026 oli20
@@ -0,0 +1,16 @@
1
+ # worktodo bundle patch:把自己插进 DSH 的 profile 层栈。
2
+ # 宿主半侧(Node)由 Loader 按 `name` 加载 lib/index.js;
3
+ # 浏览器半侧由 package.json 的 dsh.client 声明并组合成 bundle。
4
+ #
5
+ # row id 必须唯一:这里用 `worktodo`(与包名短名一致,也用于面板 slot id 与 /worktodo 路由前缀)。
6
+ # 官方 @deepseek-ai/dsh-tool-todo 占的是 `tool-todo`,不冲突——两者互补:
7
+ # 官方那份是单个 agent 会话的计划(整表替换、三态),本插件是人的跨会话工作待办。
8
+ - insert:
9
+ - id: worktodo
10
+ name: 'dsh-worktodo'
11
+ config:
12
+ # 留空即用默认值:优先官方 storage($DSH_HOME/storages),
13
+ # storage 不可用时回退 $DSH_HOME/worktodo/todos.json。
14
+ # 想固定存到自己的路径(例如放进 git 仓库)就写 storePath:
15
+ # storePath: /Users/me/notes/worktodo.json
16
+ {}
package/icon.svg ADDED
@@ -0,0 +1,13 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="48" height="48" role="img" aria-label="工作待办">
2
+ <!-- 底色用实心圆角块:任何主题(深/浅)下都能看清,不依赖宿主背景色 -->
3
+ <rect x="2" y="2" width="44" height="44" rx="12" fill="#2563EB"/>
4
+ <!-- 第一行:已勾选的事(勾 + 删除线感的短线) -->
5
+ <path d="M12.5 16.5l3.2 3.2 6.3-6.8" fill="none" stroke="#FFFFFF" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>
6
+ <rect x="26" y="14.5" width="10" height="3" rx="1.5" fill="#FFFFFF" opacity="0.75"/>
7
+ <!-- 第二行:进行中的事(空心圈) -->
8
+ <circle cx="14.2" cy="27.5" r="3.4" fill="none" stroke="#FFFFFF" stroke-width="2.4"/>
9
+ <rect x="26" y="26" width="10" height="3" rx="1.5" fill="#FFFFFF" opacity="0.75"/>
10
+ <!-- 第三行:还没开始的事(空心圈,更淡) -->
11
+ <circle cx="14.2" cy="37.5" r="3.4" fill="none" stroke="#FFFFFF" stroke-width="2.4" opacity="0.6"/>
12
+ <rect x="26" y="36" width="7" height="3" rx="1.5" fill="#FFFFFF" opacity="0.55"/>
13
+ </svg>