dsh-global-todo 0.10.0 → 0.11.0

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 CHANGED
@@ -1,3 +1,25 @@
1
+ ## [0.11.0] — 2026-10-20
2
+
3
+ Documentation and demo, treated as part of the product.
4
+
5
+ - **A standalone landing page** at `docs/index.html` (GitHub Pages): hero with the install line and
6
+ a 24-second captioned tour, the three claims with evidence, a five-step strip through the real
7
+ screenshots, an honest comparison against `todo_write` and kanban boards, a 3×3 grid of every
8
+ conditional state, and a footer with the data path. One file, inline CSS, no CDN, bilingual
9
+ toggle, 15 images all verified to decode.
10
+ - **`docs/screenshots/demo.mp4`** — a 24s captioned tour built from the same real renders by
11
+ `ffmpeg` (not a screen recording, and the page says so), plus the existing GIF for places that
12
+ cannot autoplay video.
13
+ - **`docs/QUICKSTART.md`** (five minutes, click by click) and **`docs/FAQ.md`** (14 real questions
14
+ answered against the code), and `docs/screenshots/README.md` indexing what each baseline shows
15
+ and what a static image cannot prove.
16
+ - **READMEs explain 0.7–0.10 at last**: steps, evidence, read-back, review, Markdown, weekly report.
17
+ English and Chinese kept as mirror images; stale claims (`21 routes`, `100+ tests`, `@0.4.0`)
18
+ corrected to 24 / 257 / 0.10.0.
19
+ - **Fixed the two mismatches the docs pass found**: the capture prompt said 200 characters where
20
+ `LIMITS.evidence` is 300, and `package.json` did not publish the new docs (so their links would
21
+ have 404'd on npm).
22
+
1
23
  ## [0.10.0] — 2026-10-20
2
24
 
3
25
  The two remaining high-value items, plus the layout bug written down.
package/README.md CHANGED
@@ -18,7 +18,7 @@ Three things it does that a session-local plan cannot:
18
18
  dsh plugin add dsh-global-todo
19
19
  ```
20
20
 
21
- [中文说明](README.zh.md) · [Every state has a baseline image](#screenshots) · [Design notes](docs/DESIGN.md)
21
+ [中文说明](README.zh.md) · [5-minute quickstart](docs/QUICKSTART.md) · [FAQ](docs/FAQ.md) · [Every state has a baseline image](#screenshots) · [Design notes](docs/DESIGN.md)
22
22
 
23
23
  ---
24
24
 
@@ -39,6 +39,93 @@ one record:
39
39
  | Hand-off | — | **one click: reuse the bound conversation or open a session** |
40
40
  | Storage | session event log | one JSON file you can `cat`, edit, diff and back up |
41
41
 
42
+ ## What 0.9 and 0.10 added (and the two just before)
43
+
44
+ Six surfaces these READMEs had never explained. Session read-back and evidence came in 0.9;
45
+ Markdown and the weekly report in 0.10; steps in 0.8 and the review mark in 0.7, which until now
46
+ only existed in the changelog. Each changes what a record can carry, or what you can do with it
47
+ after the fact.
48
+
49
+ ### Steps: a plan inside the todo
50
+
51
+ A todo can carry up to 20 steps of 200 characters (`LIMITS` in `lib/model.js`). A step is
52
+ `{ text, done }` — a line inside one unit of work, not a subtask with its own id and status.
53
+
54
+ - **Add them** in "More fields" → Steps, one per line.
55
+ - **Tick them** in the detail panel; the row shows `steps 2/5`.
56
+ - **Hand off** and the dispatch prompt numbers them, prefixing finished ones with `[已完成]`.
57
+ - **Export** and Markdown writes them as nested `- [ ]` lines; import reads them back.
58
+
59
+ ### Evidence: the sentence it came from
60
+
61
+ `evidence` is the sentence a captured todo came from, quoted verbatim, up to 300 characters.
62
+ `global_todo_capture` asks the model for it, `global_todo_add` accepts it, and the detail panel
63
+ shows it as a blockquote under **In the author's words**. A todo you typed yourself has none.
64
+
65
+ The field exists for one reason: a capture without its source reads as an opinion later. It is
66
+ also in the Markdown export (`原话:`).
67
+
68
+ ### Session read-back
69
+
70
+ A hand-off starts work in another conversation, so the detail panel answers "what did it say"
71
+ without switching away. `GET /api/global-todo/session?id=` returns `alive`, `dir` and a `tail`
72
+ of the last assistant message; the panel shows **Session read-back** with running / dormant, the
73
+ last sentence, and a button that opens that conversation.
74
+
75
+ The tail is bounded and in memory: 200 conversations, 400 characters each, filled from every
76
+ `assistant/message`. Nothing is written to disk, so a Host restart forgets it. A missing tail is
77
+ normal — this process has not seen that conversation speak.
78
+
79
+ ### Review: "done" is a claim
80
+
81
+ When an agent finishes (`global_todo_done`, or the watcher on a clean turn), the record becomes
82
+ done **and** carries `review: { pending: true }`. The row gets a **Needs review** badge and the
83
+ header a **Review** chip with the count.
84
+
85
+ | Answer | Effect |
86
+ |---|---|
87
+ | **Confirm done** | stays done, the mark is dropped, the activity trail records who confirmed |
88
+ | **Send back** | back to `open`; `doneAt` and the completion record are cleared; a `reopened` activity entry is added |
89
+
90
+ Both answers are recorded as the person's action. Sending back deletes nothing: title,
91
+ description, steps, attachments and progress notes stay.
92
+
93
+ ### Markdown in and out
94
+
95
+ The JSON export is the round-trip format. Markdown is the one you read, diff and edit by hand:
96
+
97
+ ```text
98
+ - [ ] 标题
99
+ 优先级: 高 · 截止: 2026-10-21T18:00 · 标签: 发布, 文档
100
+ 原话: …
101
+ 描述: 第一行
102
+ - [x] 一步
103
+ ```
104
+
105
+ | Direction | Where | Behaviour |
106
+ |---|---|---|
107
+ | Out | **More actions → Export Markdown**, or `GET /export?format=md` | Grouped 未完成 / 已完成 / 已归档; metadata indented under each task |
108
+ | In | **More actions → Import** (a `.md` file), or `POST /import { markdown }` | Creates new todos through `create`; Markdown has no ids, so it never overwrites an existing record |
109
+
110
+ Tolerant by design: unknown lines are ignored, an unparseable date is dropped, and a file with no
111
+ `- [ ]` line is refused with a reason. Field labels are Chinese (`优先级 / 截止 / 标签 / 原话 /
112
+ 描述 / 附件 / #`), and import reads the same set.
113
+
114
+ ### Weekly report
115
+
116
+ **More actions → This week** (`GET /report?days=7`) answers "what moved, and did any of it land
117
+ in code". Everything is derived from completion records; nothing is stored.
118
+
119
+ | Field | Meaning |
120
+ |---|---|
121
+ | `finished` | completions in the window, newest first, with the actor and the summary |
122
+ | `sessions` | distinct conversations those completions came from |
123
+ | `created` | todos added in the window |
124
+ | `pendingReview` | done items still waiting for an answer |
125
+ | `files` | file artifacts touched, most frequent first — 12 listed, `fileCount` total |
126
+
127
+ `days` above 90 is clamped to 90; a missing or non-positive value falls back to 7.
128
+
42
129
  ## Screenshots
43
130
 
44
131
  ![The panel: count chips, grouped list, urgent rows marked](docs/screenshots/panel.png)
@@ -64,6 +151,9 @@ half is rendered to static HTML with no Host and no dependencies, then photograp
64
151
  into `docs/screenshots/`. Playwright is not a dependency — the tool borrows the copy a DSH
65
152
  profile already installed, or whatever `DSH_PLAYWRIGHT` points at.
66
153
 
154
+ What each file shows, and when it is regenerated, is indexed in
155
+ [docs/screenshots/README.md](docs/screenshots/README.md).
156
+
67
157
  ## Requirements
68
158
 
69
159
  - DeepSeek Harness `0.2.x` (developed and verified against `0.2.1-rc.2`; `engines.dsh` is
@@ -90,7 +180,7 @@ The plugin is a Loader row, not a hot-loaded script: **restart the host** (`dsh
90
180
  after installing, then refresh the page. A "待办 / Todos" entry appears in the sidebar.
91
181
 
92
182
  The npm package is the source of truth. A community catalog can lag behind it or point at an
93
- older release; pin the version you want (`dsh plugin --profile web add dsh-global-todo@0.4.0`)
183
+ older release; pin the version you want (`dsh plugin --profile web add dsh-global-todo@0.10.0`)
94
184
  when it matters.
95
185
 
96
186
  To roll back:
@@ -118,8 +208,8 @@ Your list is not touched by install or uninstall: it lives outside the plugin, a
118
208
  documents and addresses (with 打开 / 复制路径 on each); read the activity trail.
119
209
  - **Undo a delete** — deleting keeps the record for eight seconds and offers 撤销, which
120
210
  restores it verbatim: same id, same creation time, same attachments.
121
- - **Keyboard** — `/` focuses search, `n` focuses the new-todo field, `Esc` collapses the
122
- open detail. Row actions appear on hover or keyboard focus.
211
+ - **Keyboard** — `/` focuses search, `n` focuses the new-todo field while the add form is
212
+ open, `Esc` collapses the open detail. Row actions appear on hover or keyboard focus.
123
213
  - **Reachable from the LAN and from a tunnel** — the routes defer to the Host's connection fence
124
214
  (which honours `--trusted-host`); the plugin's own loopback check is only the fallback for a
125
215
  Host without that service. `/health` reports `fence` so you can see which one is in force.
@@ -253,12 +343,12 @@ produces noise, and a noisy list is worse than an empty one:
253
343
  The boundary: it **records, it never starts work**. The list belongs to the human, and
254
344
  starting a task stays a human decision (see the non-goals in [ROADMAP](docs/ROADMAP.md)).
255
345
 
256
-
257
346
  Capture is not allowed to become noise. Before an item is written, the same normalized title
258
347
  (full-width, case, spacing and punctuation folded away), a close paraphrase within the last 72
259
348
  hours (Dice similarity over character bigrams, 0.8), and the same errand finished in the last 7
260
349
  days are all refused with a reason on the record; archived and cancelled rows do not block a
261
350
  new one. The rules live in `lib/capture.js` and are tested on their own.
351
+
262
352
  ### HTTP API
263
353
 
264
354
  The panel talks to the host over these routes. They are fenced by the host connection
@@ -272,6 +362,7 @@ fence when that service is present, and by a strict loopback check otherwise.
272
362
  | GET | `/api/global-todo/export` | — (the store's own JSON document; `?format=md` gives a Markdown task list) |
273
363
  | POST | `/api/global-todo/import` | `{ doc, mode?: replace\|merge, dryRun? }` — `replace` is an exact round trip, `merge` updates by id and appends (what the panel sends); `dryRun` returns `wouldCreate` / `wouldUpdate` and writes nothing |
274
364
  | POST | `/api/global-todo/reminders/ack` | `{ ids }` — stop listing these passed deadlines as due |
365
+ | POST | `/api/global-todo/note` | `{ id, text }` — append a progress note |
275
366
  | POST | `/api/global-todo/capture` | `{ sessionId? }` — ask the current conversation to collect its follow-ups |
276
367
  | POST | `/api/global-todo/bulk` | `{ ids, status?, addTags?, removeTags? }` — one change across a selection; a stale id lands in `unmatched` instead of failing the batch |
277
368
  | POST | `/api/global-todo/ingest` | `{ items: [{ title, source: { kind }, confidence }], dryRun? }` with `Authorization: Bearer <settings.ingestToken>` — external items; below `ingestConfirmBelow` they wait in the inbox |
@@ -349,7 +440,7 @@ and [docs/ROADMAP.md](docs/ROADMAP.md) for what could come next.
349
440
  npm run check # parse every file, assert the shipping shape, and — when a DSH
350
441
  # profile is present — validate every tool schema against the
351
442
  # Host's own validator
352
- npm test # 100+ unit, contract and bundle tests, zero dependencies
443
+ npm test # 257 unit, contract and bundle tests, zero dependencies
353
444
  npm run verify # both
354
445
  npm run check:matrix # the running dsh against engines.dsh, then the manifest,
355
446
  # bundle and tool-schema contracts (no preview writes)
@@ -366,6 +457,7 @@ page refresh; host-half edits need a host restart.
366
457
  ```sh
367
458
  npm run preview # render the panel to preview/panel.html (+ detail and selection variants)
368
459
  npm run screenshots # re-photograph those previews into docs/screenshots/, 1280×720
460
+ npm run tour # rebuild docs/screenshots/tour.gif from those PNGs (needs ffmpeg)
369
461
  ```
370
462
 
371
463
  The PNGs under `docs/screenshots/` ship with the package and are embedded in both
@@ -373,20 +465,30 @@ READMEs, so re-run `npm run screenshots` whenever the panel UI changes.
373
465
 
374
466
  ```text
375
467
  lib/
376
- index.js host entry: store + service + dispatcher + the three surfaces
377
- store.js one JSON file: atomic writes, serialized updates, tolerant loads
378
- model.js the todo entity: validation, patches, status, attachments, activity
379
- links.js attachment rules (pure: no filesystem access)
380
- service.js the single write path, filters and sorting
381
- routes.js the HTTP surface for the panel
382
- tools.js the ten agent tools
383
- dispatch.js handing a todo to an agent session
384
- errors.js typed failures with stable machine codes
385
- client.js the browser half (panel + sidebar entry)
386
- test/ unit, service, tool, route, dispatch, bundle and manifest tests
387
- tools/ preview.mjs — render the panel to static HTML without a Host
388
- screenshot.mjs — photograph those previews (borrows the profile's Playwright)
389
- docs/ DESIGN.md (data model and rejected alternatives), ROADMAP.md
468
+ index.js host entry: store + service + dispatcher + the optional surfaces
469
+ store.js one JSON file: atomic writes, serialized updates, tolerant loads
470
+ model.js the todo entity: validation, patches, status, attachments, steps, review, notes
471
+ links.js attachment rules (pure: no filesystem access)
472
+ service.js the single write path, filters, sorting and the dispatch prompt
473
+ routes.js the HTTP surface for the panel
474
+ tools.js the ten agent tools
475
+ dispatch.js handing a todo to an agent session (auto / bound / new / current)
476
+ completion.js the clean-turn watcher behind automatic completion
477
+ capture.js the capture duplicate gate (title, paraphrase, recent done)
478
+ ingest.js the external door and its inbox rules
479
+ markdown.js Markdown export and tolerant import
480
+ report.js the weekly aggregate over completion records
481
+ reminders.js the due rule behind the reminder strip
482
+ settings.js host-side switches and the automatic-collect policy
483
+ metrics.js in-memory counters reported by /health
484
+ diagnostics.js the bounded client error log
485
+ errors.js typed failures with stable machine codes
486
+ client.js the browser half (panel + sidebar entry)
487
+ test/ unit, service, tool, route, dispatch, bundle and manifest tests
488
+ tools/ preview.mjs — render the panel to static HTML without a Host
489
+ screenshot.mjs — photograph those previews (borrows the profile's Playwright)
490
+ tour.mjs — assemble the README tour GIF from those PNGs
491
+ docs/ DESIGN.md (data model and rejected alternatives), ROADMAP.md
390
492
  ```
391
493
 
392
494
  Contributions are welcome — read [CONTRIBUTING.md](CONTRIBUTING.md) first.
@@ -397,6 +499,7 @@ Questions, bug reports and ideas go to [Discussions](https://github.com/LUgABeEE
397
499
  When reporting a bug, include the DSH version, the plugin version from the panel footer, your OS and
398
500
  the steps that reproduce it; a screenshot of the notice is worth more than a paragraph. Security
399
501
  issues go through [SECURITY.md](SECURITY.md) instead, not the discussion board.
502
+
400
503
  ## Security
401
504
 
402
505
  The HTTP surface is local-only, the list is a local file, and no credential is ever stored.
package/README.zh.md CHANGED
@@ -14,7 +14,7 @@
14
14
  dsh plugin add dsh-global-todo
15
15
  ```
16
16
 
17
- [English](README.md) · [每个条件状态都有基线图](#截图) · [设计说明](docs/DESIGN.md)
17
+ [English](README.md) · [5 分钟上手](docs/QUICKSTART.md) · [常见问题](docs/FAQ.md) · [每个条件状态都有基线图](#截图) · [设计说明](docs/DESIGN.md)
18
18
 
19
19
  ---
20
20
 
@@ -33,6 +33,85 @@ DSH 自带的 `todo_write` 属于**某一个 agent 会话**:整表替换、三
33
33
  | 交给 Agent | 无 | **一键:复用已绑定会话,或新开一个** |
34
34
  | 存储 | 会话事件日志 | 一个 JSON 文件,能 `cat`、能手改、能 diff、能备份 |
35
35
 
36
+ ## 0.9 / 0.10 补了什么(以及再往前两版)
37
+
38
+ 六个这两份 README 一直没讲的能力:会话回读与原话是 0.9 的,Markdown 与本周报告是 0.10 的,
39
+ 步骤是 0.8 的,待确认标记是 0.7 的——后两个此前只写在 CHANGELOG 里。每一个都改变了记录能装什么,
40
+ 或者改变了事后能拿它做什么。
41
+
42
+ ### 步骤:待办里的一份计划
43
+
44
+ 一条待办最多 20 个步骤、每步 200 字(`lib/model.js` 的 `LIMITS`)。步骤是 `{ text, done }`——
45
+ 一条工作里的一行,不是有自己 id 和状态的子任务。
46
+
47
+ - **加**:新增表单的「更多字段」→ 步骤,一行一步。
48
+ - **勾**:详情里每步一个勾选框;行上显示「步骤 2/5」。
49
+ - **交出去**:派发提示词会把步骤编号,已完成的加 `[已完成]` 前缀。
50
+ - **导出**:Markdown 里写成缩进的 `- [ ]`,导入时读回来。
51
+
52
+ ### 原话:这条是从哪句话来的
53
+
54
+ `evidence` 是抓取时那条待办**来自的原话**,逐字引用,最多 300 字。`global_todo_capture` 会向模型要它,
55
+ `global_todo_add` 也收,详情里以引用块显示在「原话」下面;你自己敲的条目没有这一项。
56
+
57
+ 它只为一件事存在:没有出处的一次抓取,过几天看起来就像一句观点。Markdown 导出里也有这一行(`原话:`)。
58
+
59
+ ### 会话回读
60
+
61
+ 派发是在**另一个对话**里开工,所以详情要能回答「它说了什么」,不用切过去。
62
+ `GET /api/global-todo/session?id=` 返回 `alive`、`dir` 和最后一条 assistant 消息的 `tail`;
63
+ 详情里就是「会话回读」:在跑 / 已休眠、最后一句,以及一个打开该对话的按钮。
64
+
65
+ tail 有上限、只在内存里:200 个会话、每个 400 字,来自每条 `assistant/message`。不落盘,宿主一重启就忘。
66
+ 查不到 tail 是正常情况——这个进程没见那个对话说过话。
67
+
68
+ ### 待确认:Agent 的「做完了」只是声明
69
+
70
+ Agent 收尾时(`global_todo_done`,或干净一轮后的自动收尾),记录会变成已完成,**同时**带上
71
+ `review: { pending: true }`。行上有「待确认」徽标,顶部多一个带计数的「待确认」筛选。
72
+
73
+ | 你的回答 | 结果 |
74
+ |---|---|
75
+ | **确认完成** | 保持已完成,标记清除,动态里记下是谁确认的 |
76
+ | **退回清单** | 回到 `open`,`doneAt` 与完成记录清空,动态里加一条 `reopened` |
77
+
78
+ 两个回答都按**人**的动作记录。退回不删除任何东西:标题、描述、步骤、附件、进展记录都还在。
79
+
80
+ ### Markdown 进与出
81
+
82
+ JSON 导出是往返格式;Markdown 是拿来读、diff、手改的那份:
83
+
84
+ ```text
85
+ - [ ] 标题
86
+ 优先级: 高 · 截止: 2026-10-21T18:00 · 标签: 发布, 文档
87
+ 原话: …
88
+ 描述: 第一行
89
+ - [x] 一步
90
+ ```
91
+
92
+ | 方向 | 入口 | 行为 |
93
+ |---|---|---|
94
+ | 出 | **更多操作 → 导出 Markdown**,或 `GET /export?format=md` | 按「未完成 / 已完成 / 已归档」分组,元数据缩进在每条下面 |
95
+ | 入 | **更多操作 → 导入**(选 `.md`),或 `POST /import { markdown }` | 走正常 `create` 新建;Markdown 没有 id,所以**永远不会覆盖**已有记录 |
96
+
97
+ 解析是容错的:不认识的行直接忽略,日期解析失败就丢掉那一项,整份文件里没有一行 `- [ ]` 会明确报错。
98
+ 字段标注固定是中文(`优先级 / 截止 / 标签 / 原话 / 描述 / 附件 / #`),导入按同一套读。
99
+
100
+ ### 本周报告
101
+
102
+ **更多操作 → 本周报告**(`GET /report?days=7`)回答「这一周动了什么、有没有落到代码上」。
103
+ 全部从完成记录推出来,不存任何东西。
104
+
105
+ | 字段 | 含义 |
106
+ |---|---|
107
+ | `finished` | 窗口内完成的条目,最新在前,带完成者和说明 |
108
+ | `sessions` | 这些完成来自多少个不同的对话 |
109
+ | `created` | 窗口内新增的条数 |
110
+ | `pendingReview` | 已完成但还没人回答的条数 |
111
+ | `files` | 触及的文件,按次数排序——列 12 个,`fileCount` 是总数 |
112
+
113
+ `days` 超过 90 会被压到 90;缺省或非正数按 7 算。
114
+
36
115
  ## 截图
37
116
 
38
117
  ![面板:统计胶囊、按紧迫度分组、逾期行有强调](docs/screenshots/panel.png)
@@ -56,6 +135,8 @@ DSH 自带的 `todo_write` 属于**某一个 agent 会话**:整表替换、三
56
135
  HTML(不依赖宿主、零依赖),再以 1280×720 拍进 `docs/screenshots/`。Playwright 不是依赖——工具
57
136
  借的是 DSH profile 里已经装好的那份,或 `DSH_PLAYWRIGHT` 指向的那份。
58
137
 
138
+ 每张图显示什么状态、什么时候重新生成,见 [docs/screenshots/README.md](docs/screenshots/README.md)。
139
+
59
140
  ## 环境要求
60
141
 
61
142
  - DeepSeek Harness `0.2.x`(按 `0.2.1-rc.2` 开发与验证;`engines.dsh` 是 `>=0.2.0-rc.1 <0.3.0`,
@@ -80,7 +161,7 @@ dsh plugin --profile web add /绝对路径/dsh-global-todo
80
161
  再刷新页面。侧栏会出现「待办」入口。
81
162
 
82
163
  npm 上的包才是事实来源。社区目录可能落后于 npm、或指向某个旧 release;需要确定版本时
83
- 直接钉版本(`dsh plugin --profile web add dsh-global-todo@0.4.0`)。
164
+ 直接钉版本(`dsh plugin --profile web add dsh-global-todo@0.10.0`)。
84
165
 
85
166
  回滚:
86
167
 
@@ -105,7 +186,7 @@ dsh plugin --profile web remove dsh-global-todo
105
186
  - **详情**:就地改标题/描述/优先级/截止;挂上或摘掉文档与地址(每条都带「打开 / 复制路径」);
106
187
  查看动态(谁在什么时候做了什么)。
107
188
  - **删除可撤销**:删掉的记录保留 8 秒,点「撤销」原样恢复——同一个 id、同一个加入时间、同样的附件。
108
- - **键盘**:`/` 聚焦搜索,`n` 聚焦新建,`Esc` 收起详情;行内操作在悬停或键盘聚焦时出现。
189
+ - **键盘**:`/` 聚焦搜索;新增输入框展开后,`n` 聚焦它;`Esc` 收起详情。行内操作在悬停或键盘聚焦时出现。
109
190
  - **访问地址**:面板可以正常从宿主的**本机**、**受信任的局域网地址**(`--trusted-host` 里那些,如 `192.168.1.10:3080`)以及隧道访问——路由会交给宿主的连接围栏判断;只有宿主的围栏**不存在**时才退回「只接受本机请求」的保守检查。`/health` 里的 `fence` 会告诉你当前实际是哪一种。
110
191
  - **自动获取(可关,默认关)**:面板上的「自动获取」开关。打开后——你在某个对话里**正常收完一轮**、那个对话**安静满 30 分钟**、且**你人就在那个对话里**(不是派发目标/子 Agent/后台任务),插件才会自动问它一次「有没有要跟进的事」。中断/失败的轮次不问。**它问过之后,只有你在那个对话里再说一句话才会重新问**——因为那条提问本身就是对话里的一条消息,会重置安静计时、并让它自己的回答收尾成一轮,曾经正是这一点让同一个对话整夜追着自己反复问;冷却只是次要的阻尼。开关是**宿主状态**(面板关着也生效,`/health` 可见),关掉就完全靠你和 Agent 手动记。另外每个对话分组旁边有一个**「豁免」**按钮:点一下就把**该对话所在的工作区**整个排除在自动获取之外(再点一下取消)。这是给由机器驱动的对话准备的——比如微信机器人所在的聊天区,它们的会话重启后会换新 id,所以豁免**记在目录上而不是某一条对话上**,才不会悄悄失效。
111
192
  - **主动记**:插件会往 system prompt 里注入一段引导,列出该主动记的具体情形(跨会话的跟进、「先做 X 再 Y」、一轮收尾时发现还有一步),并明确写上「问用户要不要记是错的,直接记」。
@@ -148,8 +229,29 @@ dsh plugin --profile web remove dsh-global-todo
148
229
  | `global_todo_reopen` | 把**被误标完成**的一条标回未完成(只做 `done` / `cancelled` → `open`);本来就未完成的会被拒绝,动作按 agent 记进活动轨迹 |
149
230
  | `global_todo_remove` | 永久删除(做完的请标记,不要删) |
150
231
 
151
- 系统提示词里会注入一小段用法指引,让模型知道这份清单存在、以及它和内建 `todo_write`
152
- 的区别。不想要就把 `guidance` 设成 `false`。
232
+ ### 实际联通检查
233
+
234
+ 测试用的是替身;`npm run check:live` 检查的是**真正接上线的**宿主:面板实际会调的路由、它实际读的清单,
235
+ 以及一条「删掉再撤销」之后仍然完整的记录。它会临时建一条记录,往返后逐字段比对(id、加入时间、附件、
236
+ 标签、级别、截止、描述),确认绑定记录带 `sessionAlive` / `sessionDir`,最后即使失败也会删掉这条临时记录。
237
+ 它需要一个在跑的宿主,所以不在 `verify` 里。
238
+
239
+ ### 主动抓取
240
+
241
+ 插件会往 system prompt 里注入一段引导(用 `guidance: false` 关掉)。它把两侧都写清楚:只写「记得记事」的
242
+ 提示词只会制造噪音,而吵闹的清单比空清单更糟。
243
+
244
+ - **主动记**:用户提到需要跨会话跟进的事(等对方回复、下周要交、待确认的决定、答应别人的事)、
245
+ 一轮结束时还有一步不该在本会话继续、或用户说「记一下 / 别忘了 / 回头办」;
246
+ - **不要记**:你这一步就能做完的、本会话内的计划、纯闲聊;
247
+ - 记完用**一句话**说明记了什么,别复述整条描述;
248
+ - 用户说**「抓一下待办」**,就扫最近对话,用 `global_todo_capture` 一次登记,再回一句汇总。
249
+
250
+ 边界是:它**只负责记,从不擅自开工**。清单属于人,开不开工是人决定的(见 [ROADMAP](docs/ROADMAP.md) 里的非目标)。
251
+
252
+ 抓取不能变成噪音。写进去之前,同一个规范化标题(全半角、大小写、空格、标点都折叠掉)、
253
+ 最近 72 小时内意思很接近的转述(按字符二元组的 Dice 相似度,0.8),以及 7 天内刚做完的同一件事,
254
+ 都会被拒绝,并在记录上写出原因;已归档和已取消的条目不挡新条目。规则在 `lib/capture.js`,单独测试。
153
255
 
154
256
  ### HTTP 接口
155
257
 
@@ -237,7 +339,7 @@ epoch 与 ISO,派发提示词也带上它。因为「这事什么时候落到
237
339
  ```sh
238
340
  npm run check # 解析全部文件、校验发布形态;本机有 DSH profile 时,还会用宿主
239
341
  # 自己的校验器逐条验证工具 schema
240
- npm test # 100+ 单元/契约/bundle 测试,零依赖
342
+ npm test # 257 单元/契约/bundle 测试,零依赖
241
343
  npm run verify # 两者都跑
242
344
  npm run check:matrix # 当前 dsh 与 engines.dsh 的实际匹配,再跑 manifest/bundle/
243
345
  # 工具 schema 三类契约(不写 preview)
@@ -253,6 +355,7 @@ CI 里也没有构建产物。改 `lib/client.js` 刷新页面即生效;改宿
253
355
  ```sh
254
356
  npm run preview # 把面板渲染成 preview/panel.html(另附详情态与选择态)
255
357
  npm run screenshots # 把这些预览重新拍成 docs/screenshots/,1280×720
358
+ npm run tour # 用这些 PNG 重新拼 docs/screenshots/tour.gif(需要 ffmpeg)
256
359
  ```
257
360
 
258
361
  `docs/screenshots/` 下那几张 PNG 会随包发布、并嵌在两份 README 里,所以面板 UI 一改就要重跑
@@ -260,20 +363,30 @@ npm run screenshots # 把这些预览重新拍成 docs/screenshots/,1280×72
260
363
 
261
364
  ```text
262
365
  lib/
263
- index.js 宿主入口:store + service + dispatcher + 三个挂载面
264
- store.js 一个 JSON 文件:原子写、串行更新、容错读取
265
- model.js 待办实体:校验、补丁、状态、附件、动态
266
- links.js 附件规则(纯函数,不碰文件系统)
267
- service.js 唯一写入路径、筛选与排序
268
- routes.js 面板用的 HTTP 接口
269
- tools.js 十个 Agent 工具
270
- dispatch.js 把待办交给 agent 会话
271
- errors.js 带机器码的类型化失败
272
- client.js 浏览器半区(面板 + 侧栏入口)
273
- test/ 单元、service、工具、路由、派发、bundle、manifest 测试
274
- tools/ preview.mjs —— 不依赖宿主,把面板渲染成静态 HTML
275
- screenshot.mjs —— 把预览拍成 PNG(借 profile 里的 Playwright)
276
- docs/ DESIGN.md(数据模型与取舍)、ROADMAP.md
366
+ index.js 宿主入口:store + service + dispatcher + 可选挂载面
367
+ store.js 一个 JSON 文件:原子写、串行更新、容错读取
368
+ model.js 待办实体:校验、补丁、状态、附件、步骤、待确认、进展
369
+ links.js 附件规则(纯函数,不碰文件系统)
370
+ service.js 唯一写入路径、筛选、排序与派发提示词
371
+ routes.js 面板用的 HTTP 接口
372
+ tools.js 十个 Agent 工具
373
+ dispatch.js 把待办交给 agent 会话(auto / bound / new / current)
374
+ completion.js 干净一轮之后的自动收尾观察者
375
+ capture.js 抓取去重闸门(同名、近义转述、刚完成)
376
+ ingest.js 外部写入入口与收件箱规则
377
+ markdown.js Markdown 导出与容错导入
378
+ report.js 从完成记录推出来的周报
379
+ reminders.js 到点提醒的判定规则
380
+ settings.js 宿主侧开关与自动获取策略
381
+ metrics.js /health 里的进程内计数
382
+ diagnostics.js 有上限的面板错误日志
383
+ errors.js 带机器码的类型化失败
384
+ client.js 浏览器半区(面板 + 侧栏入口)
385
+ test/ 单元、service、工具、路由、派发、bundle、manifest 测试
386
+ tools/ preview.mjs —— 不依赖宿主,把面板渲染成静态 HTML
387
+ screenshot.mjs —— 把预览拍成 PNG(借 profile 里的 Playwright)
388
+ tour.mjs —— 用这些 PNG 拼 README 里的 tour.gif
389
+ docs/ DESIGN.md(数据模型与取舍)、ROADMAP.md
277
390
  ```
278
391
 
279
392
  欢迎贡献,先读 [CONTRIBUTING.md](CONTRIBUTING.md)。
@@ -283,6 +396,7 @@ docs/ DESIGN.md(数据模型与取舍)、ROADMAP.md
283
396
  问题、bug 和想法都发到 [Discussions](https://github.com/LUgABeEEE/dsh-global-todo/discussions)。
284
397
  报 bug 时带上 DSH 版本、面板页脚里的插件版本、系统,以及能复现的步骤;提示语截图比一段描述更有用。
285
398
  安全问题请走 [SECURITY.md](SECURITY.md),不要发在讨论区。
399
+
286
400
  ## 安全
287
401
 
288
402
  HTTP 接口只服务本机,清单是本地文件,任何凭据都不会被存储。
package/docs/FAQ.md ADDED
@@ -0,0 +1,159 @@
1
+ # 常见问题
2
+
3
+ 14 个真问题,答案都能在代码里核对。文中路径相对仓库根;`$DSH_HOME` 默认是 `~/.dsh`。
4
+
5
+ ## 1. 我的数据到底存在哪?卸载会删掉吗?
6
+
7
+ 默认 `$DSH_HOME/global-todo/todos.json`,可以用插件配置的 `storePath` 指到任意绝对路径
8
+ (`lib/store.js` 的 `resolveStorePath`)。同一个目录里还有 `settings.json`(宿主侧开关)和
9
+ `client-errors.log`(面板错误日志,有上限)。
10
+
11
+ 安装和卸载都**不碰**这些文件。卸载后手动 `rm -r` 那个目录才会彻底清掉。
12
+
13
+ ## 2. 两台机器之间会同步吗?
14
+
15
+ 不会。插件没有账号、没有同步服务,也不发网络请求——它只读写那一个文件。
16
+
17
+ 跨机使用靠你自己:把 `storePath` 指到同步盘或版本库里的同一份文件,同步交给 Dropbox / Syncthing /
18
+ git 那套工具。另一个进程改了文件,本进程下一次读会通过 `mtime:size` 发现,面板提示
19
+ 「清单在别处被改过,已载入最新内容」。
20
+
21
+ 注意:**没有合并逻辑**。两边同时改,最后落盘的那份赢,另一边那次改动丢失(见第 9 题)。
22
+
23
+ ## 3. Agent 把一条标成完成之后会发生什么?
24
+
25
+ 记录变成 `done`,同时带上 `review: { pending: true }`(`lib/model.js` 的 `completeTodo`)。
26
+ 清单里两处可见:行上的「待确认」徽标,顶部的「待确认」筛选与计数。
27
+
28
+ | 你的回答 | 结果 |
29
+ |---|---|
30
+ | 确认完成 | 保持已完成,标记清除,动态里记下是谁确认的 |
31
+ | 退回清单 | 回到 `open`;`doneAt` 和完成记录清空;动态里加一条 `reopened` |
32
+
33
+ 派发出去的会话干净结束时,自动收尾也走同一条规则——自动完成同样是「agent 的声明」,一样要人回答。
34
+
35
+ ## 4. 已经有 steps 了,为什么不做子任务?
36
+
37
+ 因为子任务就是另一条待办:要有自己的 id、状态、加入时间、附件、派发目标和完成记录。真做出来,
38
+ 「一份清单」就变成了「一堆互相嵌套的清单」。
39
+
40
+ `steps` 明确是**一条工作里的计划**:扁平、最多 20 步、每步只有 `text` 和 `done`,派发时作为编号
41
+ 计划原样交出去。需要各自派发的,就拆成多条待办——那才是清单该有的粒度。
42
+
43
+ ## 5. evidence(原话)是什么?为什么有的条目没有?
44
+
45
+ 抓取时逐字引用的那一句用户原话,最多 300 字(`lib/model.js` 的 `LIMITS.evidence`)。
46
+ `global_todo_capture` 会要求模型带上,`global_todo_add` 也收。
47
+
48
+ 面板详情里显示在「原话」下;Markdown 导出里是 `原话:` 一行。你在面板里手敲的条目没有这一项——
49
+ 它只服务于「抓来的东西有没有听错」这件事。
50
+
51
+ ## 6. 怎么从别的工具导进来?
52
+
53
+ 三个门,按需要选:
54
+
55
+ | 入口 | 形状 | 行为 |
56
+ |---|---|---|
57
+ | JSON 文档 | `{ "version": 1, "todos": [...] }` | 面板「更多操作 → 导入」,或 `POST /api/global-todo/import`;面板用 merge(同 id 覆盖、新 id 追加),`dryRun: true` 只返回 `wouldCreate` / `wouldUpdate` |
58
+ | Markdown | `- [ ] 标题` 任务列表,缩进标注 `优先级 / 截止 / 标签 / 原话 / 描述 / 附件 / #` | 同上,选 `.md` 文件;按 `create` **新建**,没有 id 所以不会覆盖任何记录 |
59
+ | 外部写入 | `POST /api/global-todo/ingest`,带 `Authorization: Bearer <settings.ingestToken>` | 来源只接受 `mail / notification / announcement`;一次最多 100 条;置信度低于 `ingestConfirmBelow`(默认 0.8)的进收件箱 |
60
+
61
+ CSV 没有直接入口:先转成 JSON 或 Markdown。Markdown 解析是容错的——不认识的行忽略,日期解析失败
62
+ 就丢掉那一项,整份文件里一行任务都没有才会报错。
63
+
64
+ ## 7. 不用 Agent 也能用吗?
65
+
66
+ 能。面板只依赖宿主的 web server 和那个 JSON 文件:增删改查、标签、优先级、截止、步骤、附件、
67
+ 筛选、搜索、导出导入、提醒都不需要 Agent。`global_todo_*` 工具只是可选挂载面。
68
+
69
+ 没有 Agent 参与时用不上的只有四件事:抓取、派发、Agent 的完成声明、会话回读。
70
+
71
+ ## 8. 哪些事它明确不做?
72
+
73
+ | 不做 | 现状 |
74
+ |---|---|
75
+ | 看板 / 日历视图 | 只有列表,加三种分组(对话 / 时间 / 级别);没有拖拽看板,没有日历 |
76
+ | 重复任务 | `dueAt` 是单个时间点,没有 recurrence 字段;同一截止只提醒一次,改了时间才会重新提醒 |
77
+ | 子任务树 | 只有扁平的 `steps`,最多 20 条 |
78
+ | 上传附件 | 只存引用(绝对路径或 URL),不复制字节 |
79
+ | 多清单 / 项目 | 只有一份全局清单(ROADMAP 的 Later) |
80
+ | 自动开工 | 明确不计划:那是任务队列,不是个人清单(ROADMAP 的 Explicitly not planned) |
81
+ | 桌面端面板 | 只有 Web 客户端 |
82
+ | 账号 / 多用户 | 没有;只有一个本机(或受信网络)可访问的 HTTP 面 |
83
+
84
+ ## 9. 两个进程同时写这个文件会怎样?
85
+
86
+ 同一个进程里,所有写都走 `store.update` 这条串行链,人和 Agent 的编辑不会互相覆盖。
87
+
88
+ 跨进程**没有文件锁**。每次改动是「读整份 → 改 → 原子 rename 写回」,所以:
89
+
90
+ - 读者永远不会看到半截文件(rename 是原子的)。
91
+ - 两个进程同时改时,后写的那份覆盖先写的,基于旧内容的那次改动静默丢失。
92
+ - 下次读会发现 `mtime:size` 变了,面板提示清单在别处被改过。
93
+
94
+ 结论:**别让两个宿主进程共用同一个 `storePath`**。要并行,就各自一份文件,再用导出/导入合并。
95
+
96
+ ## 10. 提醒是怎么工作的?
97
+
98
+ 宿主每 30 秒扫一次(`lib/index.js` 的 reminder tick):状态是 `open` / `doing`、`dueAt` 已过、
99
+ 且这个 `id → dueAt` 还没报过的条目,进 `/health` 的 `reminders.due`,面板顶部显示成一条提醒条。
100
+
101
+ | 设置 | 默认 | 作用 |
102
+ |---|---|---|
103
+ | `remindersEnabled` | 开 | 关掉就不再扫、不再显示 |
104
+ | `reminderLeadMinutes` | 0 | 提前几分钟报;0 = 到点才报 |
105
+
106
+ 点「知道了」调 `POST /api/global-todo/reminders/ack`,只从**当前进程**的提醒列表里移除。
107
+ 「报过了」的记忆也在内存里,所以重启宿主后,仍然到点且未完成的条目会再报一次。
108
+ 浏览器通知是可选的:面板里点「开启系统通知」授权后,到点的条目会发一条系统通知。
109
+
110
+ ## 11. 怎么关掉自动获取(auto-collect)?
111
+
112
+ 先分清三件不同的事:
113
+
114
+ | 开关 | 默认 | 管什么 | 怎么关 |
115
+ |---|---|---|---|
116
+ | `autoCollect` | **关** | 插件自动去问一个安静了 30 分钟的对话「有没有要跟进的事」 | 面板设置里的「自动获取」开关,或 `POST /api/global-todo/settings { autoCollect: false }` |
117
+ | `guidance` | 开 | 往 system prompt 里注入「主动记」的引导 | 插件配置 `guidance: false` |
118
+ | 对话分组上的「豁免」 | 无 | 把某个**工作目录**整个排除在自动获取之外 | 再点一次取消 |
119
+
120
+ 「抓一下待办」/「从本对话抓取」不在此列:那是你手动触发的,永远听你的。
121
+
122
+ ## 12. 怎么干净卸载?
123
+
124
+ ```sh
125
+ dsh plugin --profile web remove dsh-global-todo
126
+ ```
127
+
128
+ 然后重启宿主、刷新页面,侧栏入口消失。清单和设置都还在原处——这是刻意的。
129
+
130
+ 要彻底清掉(先确认里面的 `todos.json` 你不要了):
131
+
132
+ ```sh
133
+ rm -r "$DSH_HOME/global-todo"
134
+ ```
135
+
136
+ 更稳的顺序:先导出 JSON 或 Markdown,再删目录。重新装回来后,把导出的 JSON 用「更多操作 → 导入」
137
+ 就能接着用。
138
+
139
+ ## 13. 收件箱和「待确认」有什么区别?
140
+
141
+ | | 收件箱(Inbox) | 待确认(Review) |
142
+ |---|---|---|
143
+ | 谁产生的 | 外部写入(`/ingest`),置信度低于阈值 | Agent 的完成声明(工具或自动收尾) |
144
+ | 问题是什么 | 「这条要不要收下」 | 「这活是不是真做完了」 |
145
+ | 两个动作 | 确认(去掉 `inbox` 标签进清单)/ 丢弃(归档并去掉标签) | 确认完成 / 退回清单 |
146
+ | 不处理会怎样 | 超过 7 天自动归档(宿主每 6 小时扫一次) | 一直挂着,行上一直有「待确认」 |
147
+
148
+ ## 14. 派发失败最常见的原因?
149
+
150
+ | 原因 | 表现与处理 |
151
+ |---|---|
152
+ | 没有工作目录 | 明确报错,因为没有目录的会话里 agent 做不了事;改用「开新对话」,或先选目录 |
153
+ | 目标对话已归档 | 选择器里标「(已归档)」;换一个,或新开 |
154
+ | 宿主没有 agents 服务 | `agents-unavailable`:精简组合里没有能接活的 agent |
155
+ | `bound` 模式但没绑定 | 直接告诉你没有绑定会话,并建议改用 `auto` |
156
+
157
+ 失败一定带原因,也记在详情的「最近派发」里;不会静默什么都不做。
158
+
159
+
@@ -0,0 +1,100 @@
1
+ # 5 分钟上手
2
+
3
+ 第一次装 dsh-global-todo 的完整路径:装上、打开面板、写第一条带步骤的待办、交给一个对话、弄清
4
+ 「待确认」是什么,最后知道数据在哪、怎么备份。不解释设计,只说每一步点哪里。
5
+
6
+ ## 0. 前提
7
+
8
+ | 需要 | 检查 |
9
+ |---|---|
10
+ | DSH `0.2.x`(`engines.dsh` 是 `>=0.2.0-rc.1 <0.3.0`) | `dsh --version` |
11
+ | Node.js `>= 22.19.0` | `node -v` |
12
+ | Web 客户端(面板由宿主 web server 提供) | 浏览器打开 `dsh web` 给出的地址 |
13
+
14
+ headless / ACP / SDK 组合里没有面板,只剩 Agent 工具。
15
+
16
+ ## 1. 安装
17
+
18
+ ```sh
19
+ dsh plugin --profile web add dsh-global-todo
20
+ ```
21
+
22
+ 装完**重启宿主**(`dsh web`),再**刷新页面**。插件是 Loader 里的一行,不是热加载脚本。
23
+
24
+ 验证:侧栏出现「待办」入口。
25
+
26
+ ## 2. 打开面板
27
+
28
+ 点侧栏的「待办」。这是**全局面板**:不绑定某个会话,切到别的对话、关掉再开,清单还是同一份。
29
+ 入口是插件注册到侧栏的固定项(`order: 86`),装好就在,不需要再单独「固定」;侧栏收起时,
30
+ 用它的展开按钮打开即可。
31
+
32
+ 第一眼应该看到:顶部计数胶囊(全部 / 未完成 / 逾期 / 待确认 / 收件箱…)、工具条、列表。
33
+
34
+ ## 3. 加第一条(带步骤)
35
+
36
+ 1. 点工具条的「添加」,出现输入框;写一句标题,回车(或点「添加」)保存。
37
+ 2. 点输入框旁的「更多字段」,展开描述、附件、步骤、标签、优先级、截止时间。
38
+ 3. 在「步骤」里一行写一步,最多 20 步、每步 200 字。这一步就是交出去时那份编号计划。
39
+ 4. 有文档就贴**绝对路径**(一行一个),有网页就贴 URL;带用户名密码的 URL 会被拒绝。
40
+ 5. 保存。
41
+
42
+ 之后在详情里勾掉做完的步骤;行上显示「步骤 1/5」。
43
+
44
+ ## 4. 交给一个对话
45
+
46
+ 1. 先在工具条的 `交给:` 下拉里选目标:
47
+ - 默认是**当前对话**(你最近在里面写过消息的那个);
48
+ - `自动`:先看这条待办已绑定的会话,其次当前对话,最后才新开;
49
+ - `+ 开一个新对话`:总是新开,工作区跟着写这条待办时的对话。
50
+ 2. 鼠标移到那一行,点「交给 Agent」。
51
+ 3. 面板会回执交给了哪个对话,并给一个「打开那个对话」的按钮;详情里的「最近派发」记着结果和原因。
52
+ 4. 想知道那边进展:详情里的「会话回读」显示**会话在跑 / 已休眠**和它最后说的一句话,带一个打开按钮。
53
+
54
+ 找不到可用对话时派发会**明确失败并说明原因**(比如没有工作目录),不会悄悄开一个。
55
+
56
+ ## 5. 「待确认」是什么
57
+
58
+ Agent 说做完了,不等于你做完了:
59
+
60
+ - 那一行变成已完成,同时挂上「待确认」徽标;顶部出现带计数的「待确认」筛选。
61
+ - 点「确认完成」:保持已完成,标记消失。
62
+ - 点「退回清单」:回到未完成,完成记录清空,事情继续留在清单里。
63
+
64
+ 自动收尾(派发出去的会话干净结束)也走同一条规则,所以「一份干砸的活显示成已完成」不会发生。
65
+
66
+ ## 6. 数据在哪,怎么备份
67
+
68
+ | 东西 | 位置 |
69
+ |---|---|
70
+ | 清单 | `$DSH_HOME/global-todo/todos.json`(默认 `~/.dsh/global-todo/todos.json`) |
71
+ | 宿主侧设置 | 同目录的 `settings.json` |
72
+ | 面板错误日志 | 同目录的 `client-errors.log` |
73
+
74
+ 写入是「临时文件 + rename」,所以**直接复制这个文件**拿到的一定是一份完整 JSON:要么旧版,
75
+ 要么新版,不会是半截。
76
+
77
+ | 方式 | 怎么做 | 适合 |
78
+ |---|---|---|
79
+ | 复制文件 | `cp "$DSH_HOME/global-todo/todos.json" ~/backup/todos.json` | 快照、放进同步盘或版本库 |
80
+ | 导出 JSON | 面板「更多操作 → 导出」 | 需要导回去:面板导入用 merge(同 id 覆盖、新 id 追加),API 传 `mode: 'replace'` 是精确还原 |
81
+ | 导出 Markdown | 面板「更多操作 → 导出 Markdown」 | 要读、要 diff、要贴进笔记(导入时只新增,不覆盖) |
82
+
83
+ 换机器:把新环境的 `storePath` 指向同步盘里的同一个文件,或者把上面两个文件复制过去:
84
+
85
+ ```yaml
86
+ # profile 的 cordis.patch.yml
87
+ - id: global-todo
88
+ config:
89
+ storePath: /home/me/sync/global-todos.json
90
+ ```
91
+
92
+ ## 7. 接下来
93
+
94
+ - **让对话自己记**:点面板上的「从本对话抓取」,或直接对 Agent 说「抓一下待办」。
95
+ - **到点提醒**:设置里勾「开启到点提醒」,可设「提前(分钟)」并「开启系统通知」。
96
+ - **一周回顾**:「更多操作 → 本周报告」。
97
+ - **收件箱**:外部写入、置信度低于阈值的条目先进收件箱;确认后才进清单,超过 7 天没人确认会被归档
98
+ (宿主每 6 小时扫一次)。
99
+
100
+ 更多问题见 [FAQ](FAQ.md);数据模型和被否掉的方案见 [DESIGN.md](DESIGN.md)。
@@ -0,0 +1,39 @@
1
+ # 面板基线截图
2
+
3
+ `docs/screenshots/` 下的图不是手拍的。`npm run screenshots` 先跑 `npm run preview`,把真实的客户端
4
+ 半区渲染成静态 HTML(不依赖宿主、零依赖),再由 `tools/screenshot.mjs` 以 1280×720 拍下来。
5
+ 这些图随包发布,也嵌在两份 README 里,所以面板 UI 一改就要重跑。
6
+
7
+ ## 图与状态
8
+
9
+ | 文件 | 显示的状态 | 重新生成 |
10
+ |---|---|---|
11
+ | [`panel.png`](panel.png) | 默认列表:计数胶囊、按对话分组、级别与逾期标记 | `npm run screenshots` |
12
+ | [`panel-detail.png`](panel-detail.png) | 展开一条:就地编辑、附件(含失效标记)、步骤与勾选、进展记录、会话状态、动态 | `npm run screenshots` |
13
+ | [`panel-select.png`](panel-select.png) | 批量选择:勾选标记、选择条、批量动作 | `npm run screenshots` |
14
+ | [`panel-settings.png`](panel-settings.png) | 设置:分组字段、每项说明、保存行 | `npm run screenshots` |
15
+ | [`panel-empty.png`](panel-empty.png) | 空清单 | `npm run screenshots` |
16
+ | [`panel-filtered.png`](panel-filtered.png) | 筛选无结果 | `npm run screenshots` |
17
+ | [`panel-inbox.png`](panel-inbox.png) | 收件箱:等确认的外部条目 | `npm run screenshots` |
18
+ | [`panel-review.png`](panel-review.png) | 待确认:Agent 已完成、等人回答 | `npm run screenshots` |
19
+ | [`panel-reminders.png`](panel-reminders.png) | 到点提醒条 | `npm run screenshots` |
20
+ | [`tour.gif`](tour.gif) | 十帧幻灯片(列表 → 详情 → 列表 → 待确认 → 列表 → 收件箱 → 列表 → 提醒 → 列表 → 选择),2 秒一帧 | `npm run tour`(需要 ffmpeg;没有就跳过) |
21
+
22
+ `npm run screenshots` 会重写九张 PNG(顺序见 `tools/screenshot.mjs` 的 `SHOTS`);`npm run tour` 只重做
23
+ gif,并要求 PNG 已经存在。
24
+
25
+ ## 这些图证明不了什么
26
+
27
+ 它们是**服务端渲染的静态基线**,不是浏览器里真的会话:
28
+
29
+ - **不能滚动**:只覆盖 1280×720 的第一屏。滚动后的样子、以及滚动本身有没有坏,都不在图里。
30
+ - **不能聚焦 / 悬停**:键盘焦点环、悬停才出现的行内操作、展开的下拉菜单都不在图里。
31
+ - **不能证明交互**:点击、拖拽、动画、真实网络请求(预览里用的是桩数据)都没有经过。
32
+
33
+ `npm run check:render` 补上了一部分:它断言渲染结果里的结构事实(分组合并、徽标、选择模式、步骤进度,
34
+ 以及面板裁剪 / 列可收缩 / 列表可滚这三条布局契约)。其余仍要在真实页面里看。
35
+
36
+ ## 两个不在生成列表里的文件
37
+
38
+ `panel-dark.png` 与 `detail-dark.png` 不在 `tools/screenshot.mjs` 的 `SHOTS` 里,任何脚本都不会重新生成
39
+ 它们,当前也没有文档引用。当作历史文件处理,别拿它们当主题基线。
package/lib/client.js CHANGED
@@ -50,7 +50,7 @@ window.__ModuleLoader__.load({
50
50
  * different mechanisms (restart vs. hot reload), so "which one am I looking
51
51
  * at" needs an answer that the bundle itself carries.
52
52
  */
53
- const UI_REV = 'ui50'
53
+ const UI_REV = 'ui51'
54
54
  /** Last language resolved for the shell; module-level so a fetch failure can be worded too. */
55
55
  let activeLang = 'zh'
56
56
 
package/lib/index.js CHANGED
@@ -36,7 +36,7 @@ import { createStore, resolveStorePath } from './store.js'
36
36
  import { createTools } from './tools.js'
37
37
 
38
38
  /** Must equal `package.json`'s version; `npm run check` enforces that. */
39
- export const VERSION = '0.10.0'
39
+ export const VERSION = '0.11.0'
40
40
 
41
41
  /** Plugin id. Also the Loader row id in `cordis.patch.yml`. */
42
42
  export const name = 'dsh-global-todo'
package/lib/service.js CHANGED
@@ -617,7 +617,7 @@ export function createService(options) {
617
617
  '该记的:等对方回复、待确认的决定、答应别人的事、还没收尾且需要另开一个会话继续的一步。',
618
618
  '每条必要时补描述、挂上相关文档**绝对路径**或网址,并标级别(P0 紧急 / P1 高 / P2 常规 / P3 低)。',
619
619
  '',
620
- '**带上原话**(重要):每条用 `evidence` 逐字引用用户说的那一句(最多 200 字,不要改写、不要总结)。',
620
+ '**带上原话**(重要):每条用 `evidence` 逐字引用用户说的那一句(最多 ' + LIMITS.evidence + ' 字,不要改写、不要总结)。',
621
621
  '以后看到这条待办的人,要能一眼核对「有没有听错」;没有原话的抓取,只是一条无从核对的转述。',
622
622
  '',
623
623
  '记完用**一句话**汇总(例如「记了 2 条:X 与 Y」),不要逐条复述。',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-global-todo",
3
- "version": "0.10.0",
3
+ "version": "0.11.0",
4
4
  "icon": "./docs/icon.svg",
5
5
  "description": "Global, cross-session todos for DeepSeek Harness: one list owned by the human and the agent together, with creation time, attached documents and links, and one-click hand-off to an agent session. 全局待办:跨会话一份清单,记录加入时间,可挂文档与地址,可一键交给 Agent 继续干。",
6
6
  "type": "module",
@@ -42,8 +42,12 @@
42
42
  "cordis.patch.yml",
43
43
  "docs/DESIGN.md",
44
44
  "docs/ROADMAP.md",
45
+ "docs/QUICKSTART.md",
46
+ "docs/FAQ.md",
45
47
  "docs/icon.svg",
46
48
  "docs/screenshots",
49
+ "!docs/screenshots/demo.mp4",
50
+ "!docs/index.html",
47
51
  "LICENSE",
48
52
  "README.md",
49
53
  "README.zh.md",