@deepseek-ai/dsh-tool-todo 0.1.1-rc.1 → 0.1.2-alpha.2

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/README.i18n.yaml CHANGED
@@ -2,5 +2,5 @@
2
2
  # side as of the last confirmed-consistent state. Both languages carry equal authority;
3
3
  # after editing either side, bring the other along and re-record with:
4
4
  # pnpm run verify-translation-pairing --write packages/todo/tool-todo/README.md
5
- README.md: 4848758dd8f2049221901744e5d09cef2dd31591
6
- README.zh.md: 3c79ca6bba9bb0ffd7e1960dae7000bdb525bdfb
5
+ README.md: 144f3476c36cb9054b7a21df11e78e3a70a1aed2
6
+ README.zh.md: 0ebda11ac08a245f4b07eda32c69d062cb79d0a9
package/README.md CHANGED
@@ -1,52 +1,137 @@
1
+ ---
2
+ description: "The model-facing todo_write tool over the DeepSeek Harness session log: whole-list replacement, per-session ownership, and the todos projection, for users and maintainers choosing, configuring, or debugging the tool."
3
+ kind: "package-reference"
4
+ ---
5
+
1
6
  # @deepseek-ai/dsh-tool-todo
2
7
 
3
8
  English | [中文](README.zh.md)
4
9
 
5
- The model-facing `todo_write` tool: the agent's whole task list, replaced wholesale on each call.
10
+ ## Summary
11
+
12
+ `dsh-tool-todo` gives the agent a structured task list to plan with: break multi-step work into concrete tasks, mark the task you are working on, and check tasks off as they finish. The list survives across turns and reopened sessions, so the agent and the UI always see the latest plan. One configuration flag decides whether several tasks may be in progress at once, for agents that run work in parallel. Use it wherever an agent should keep a visible task list; each update replaces the whole list, and only the owning agent session can change it.
13
+
14
+ ## Table of Contents
15
+
16
+ - [Use this package](#use-this-package)
17
+ - [Understand the implementation](#understand-the-implementation)
18
+ - [Further Exploration](#further-exploration)
19
+ - [Model Experience](#model-experience)
20
+ - [Known Limitations and Deferred Work](#known-limitations-and-deferred-work)
21
+ - [Dev Note](#dev-note)
22
+
23
+ -----
24
+
25
+ <a id="use-this-package"></a>
26
+ ## Use this package
27
+
28
+ Use this package when you want the agent to maintain a visible task list while it works: plan multi-step work, show what is active, and record completion. Mounting it with the parallelism flag is the only setup; the agent then updates the list through its own planning tool whenever the plan changes.
29
+
30
+ ### When to choose it
31
+
32
+ Choose it when one agent session should own the task list and whole-list updates are fine — the common shape for planning tools. Avoid it when several agents must share one list or when you need per-item edits: the list belongs to one agent and every update replaces the whole list. It needs an agent session to exist at all; automation-only surfaces that never run an agent cannot use it.
33
+
34
+ ### Minimal configuration
35
+
36
+ `allowParallelInProgress` is required with no default: a composition that omits it fails at load, and a non-boolean value is rejected. Set `true` for agents that may run work concurrently (subagents, background commands, workflow fan-out) and `false` for the single-active discipline.
37
+
38
+ ```yaml
39
+ - name: '@deepseek-ai/dsh-tool-todo'
40
+ config:
41
+ allowParallelInProgress: true
42
+ ```
43
+
44
+ | Field | Default | Meaning |
45
+ |---|---|---|
46
+ | `allowParallelInProgress` | required | Whether several todos may be `in_progress` at once; also selects the active-status clause of the model description |
47
+
48
+ The generated [configuration catalog](../../../docs/config-catalog.md#deepseek-aidsh-tool-todo) is the exhaustive source for the accepted field.
49
+
50
+ ### What each call does
51
+
52
+ The agent sends the ENTIRE list on every update; the new list replaces the previous one, so there are no partial updates or per-item edits. Each item is a short task description plus a status of `pending`, `in_progress`, or `completed`. A successful update returns the new counts — `Updated todo list: <pending> pending, <inProgress> in progress, <completed> completed.` — and the UI shows the new plan. Updates fail visibly when a task description is empty or duplicated, when an item carries fields beyond the description and status, or — when parallel work is disabled — when more than one task is marked in progress.
53
+
54
+ ### Single owner
55
+
56
+ The task list belongs to the one agent session that created it — subagents and other agents each keep their own list, and there is no way to share a list between agents. A call from outside an agent session is rejected, so the agent learns the update failed instead of silently writing nowhere. If you need a list shared across agents, this package does not provide it.
6
57
 
7
- ## What it does
58
+ -----
8
59
 
9
- Registers one tool, `todo_write(todos: [{ content, status }])`, on `ctx.tools`. The model sends the ENTIRE list every call — there are no partial updates or per-item edits. Each call appends a `todo/write` event (the full list snapshot) to the calling agent's session log via `agent.session.append('todo/write', { todos })`; the current list is the most recent such event (last-write-wins on replay).
60
+ <a id="understand-the-implementation"></a>
61
+ ## Understand the implementation
10
62
 
11
- `status` is one of `pending`, `in_progress`, or `completed`.
63
+ <details>
64
+ <summary>Implementation internals — click to expand</summary>
12
65
 
13
- ## Single owner
66
+ This section explains the design decisions behind the tool and points at the code that realizes them; the observable behavior is fully covered in [Use this package](#use-this-package).
14
67
 
15
- The list belongs to the ONE agent session that called the tool. There is no subagent/shared/swarm scope: a non-agent caller (no `exec.agent`) has nowhere to write the list and is rejected. This is a deliberate scope limit — see the Agent Note.
68
+ ### Design philosophy
16
69
 
17
- ## Configuration
70
+ The tool is built on four commitments:
18
71
 
19
- `allowParallelInProgress` is required: every composition must choose whether several todos may be `in_progress` at once. It is a deployment choice, not a fixed rule: whether concurrent active tasks are legitimate depends on runtime concurrency the tool cannot observe. Use `true` for agents that may fan out work and `false` to enforce the single-active discipline.
72
+ - **Whole-list replace, log-backed state.** The model resends the entire list; the `todo/write` snapshot lives on the event-sourced session log, so durability, replay, and resume reconstruction come from the log rather than a service.
73
+ - **Single owner.** The list belongs to the calling agent session; there is no shared or swarm scope, and non-agent callers are rejected.
74
+ - **Deployment policy, not a coded rule.** `allowParallelInProgress` is a required composition choice because the tool cannot observe runtime concurrency; the durable-log invariant deliberately stays silent on the active count so a log written under one policy still replays under another.
75
+ - **Validation keeps the logged snapshot honest.** Schema-level rejection of unknown keys and `execute`-level rejection of empty or duplicate content keep the durable snapshot equal to what the model believes it wrote.
20
76
 
21
- The flag moves the model-facing instruction and the accepted input together — `true` asks the model to mark every actively worked task and accepts any number, `false` asks for exactly one and rejects a call marking more with `Error: invalid todos: at most one task may be in_progress (got <n>)`. The durable-log invariant does NOT follow it: a log written while parallel work was allowed must still replay after a deployment tightens the policy, so the invariant stays silent on the active count.
77
+ The [todo_write tool Agent Note](../../../.agents/notes/implemented/feature/2026-06-29-todo-write-tool.md) records the original design and alternatives; the [parallel in-progress Agent Note](../../../.agents/notes/implemented/feature/2026-07-26-todo-parallel-in-progress.md) records the policy decision.
22
78
 
23
- ## Validation
79
+ ### Source map
24
80
 
25
- Beyond the schema's type/required/enum checks, `execute` rejects an empty or duplicate `content`, and any item key beyond `content`/`status` — an extended item shape (ids, nesting) fails loud instead of silently flattening, keeping the logged snapshot equal to what the model believes it wrote. How many tasks may be `in_progress` at once is the deployment's call (§ Configuration): a composition that chooses `true` permits parallel work (concurrent subagents, background commands) to mark several tasks simultaneously. Ordering and the discipline of keeping the list current are left to the model via the tool description.
81
+ | File | Role |
82
+ |---|---|
83
+ | [`src/index.ts`](src/index.ts) | Plugin entry: `Config` schema, tool registration, `todos` projection unit |
84
+ | [`src/types.ts`](src/types.ts) | The one home of the `todos` projection-key declaration and its payload types |
85
+ | [`src/client.ts`](src/client.ts) | Client-namespace re-export of the types outlet |
86
+ | [`src/invariant.ts`](src/invariant.ts) | Invariant companion: validates durable whole-list snapshots and open-turn ownership |
26
87
 
27
- ## Rendering
88
+ ### Export shape
28
89
 
29
- The canonical result is `{ todos, counts: { pending, inProgress, completed } }`; its Native renderer returns the compact update acknowledgement. The tool also writes the full `todo/write` session event. UIs subscribe to the event stream and render that durable list themselves: the [web client](../../client/ui-conversation) shows a plan strip plus a dedicated tool row off the standing plan — latest `todo/write` with no later `turn/start` ([display](../../../.agents/notes/implemented/feature/2026-07-23-web-todo-display.md), [lifetime](../../../.agents/notes/implemented/feature/2026-07-28-todo-plan-clears-on-next-turn.md)).
90
+ The plugin is a function/namespace plugin: it exports `name` / `inject` / `apply` and no default export. A stray `export default` would make the Loader's `unwrapExports` collapse the module and drop `inject` (see [postmortem 0001](../../../docs/postmortem/0001-acp-default-export-drops-inject.md)).
30
91
 
31
- ## Session projection
92
+ ### Session projection
32
93
 
33
- When the composition mounts `ctx.sessionProjections` ([`@deepseek-ai/dsh-session-projection`](../../session/session-projection/README.md)), this package registers the `todos` projection unit under an injected child: `init` = `null` (no write yet), `apply` = take the whole list from each `todo/write` and clear to `null` on each `turn/start` (standing plan; `turn/end` keeps the finished checklist; every other event returns the same state reference), `view` = identity, `stateVersion` = 2. The key merges into `SessionProjectionMap` here (via the Service Definition package's `/types` outlet); the framework drives the unit and carriers serve the value on the history tail page and the `session/projection` push frame. Compositions without the registry are unaffected. Lifetime rationale: [todo plan clears on next turn](../../../.agents/notes/implemented/feature/2026-07-28-todo-plan-clears-on-next-turn.md).
94
+ When the composition mounts `ctx.sessionProjections` ([`@deepseek-ai/dsh-session-projection`](../../session/session-projection/README.md)), this package registers the `todos` unit on an injected child: the projection is the standing plan — the latest whole `todo/write` list, `null` before the first write, cleared when the next turn starts while `turn/end` keeps the finished checklist visible. The key merges into `SessionProjectionMap` here; carriers serve the value on the history tail page and the `session/projection` push frame. Compositions without the registry are unaffected; see [src/index.ts](src/index.ts) for the unit registration. The lifetime rationale lives in the [todo plan clears on next turn Agent Note](../../../.agents/notes/implemented/feature/2026-07-28-todo-plan-clears-on-next-turn.md).
34
95
 
35
- ## Export shape
96
+ ### Durable-log invariant
36
97
 
37
- A function/namespace plugin: it exports `name` / `inject` / `apply` and NO default. A stray `export default` would collapse the module via the Loader's `unwrapExports` and drop `inject` (see [docs/postmortem/0001](../../../docs/postmortem/0001-acp-default-export-drops-inject.md)).
98
+ The invariant companion registers on `ctx.invariants`, validates existing and newly announced sessions once, and then advances a committed per-session turn trace for live appends. It rejects malformed entries, empty or duplicated content, unknown statuses, and any durable `todo/write` outside an open turn; core session treats declaration-merged events generically, while this producing package owns todo-specific rules. It deliberately says nothing about how many items are `in_progress`, because that is the tool's per-deployment policy, not a durable-data rule ([event ownership](../../../.agents/notes/implemented/architecture/2026-07-20-todo-event-ownership.md)).
38
99
 
100
+ ### Call mechanics
101
+
102
+ Each call validates the submitted list against the schema, rejects incoherent input, and on success appends the full snapshot as a `todo/write` session event and returns the new counts; the current list is always the most recent `todo/write` in the log (last-write-wins on replay). See [src/index.ts](src/index.ts) for the exact validation and append steps.
103
+
104
+ </details>
105
+
106
+ -----
107
+
108
+ <a id="further-exploration"></a>
109
+ ## Further Exploration
110
+
111
+ Read these pages when the package-level contract is not enough. They move from the session subsystem to the generated catalogs and the decision records behind the tool.
112
+
113
+ - [Todo subsystem](../../../docs/subsystems/todo.md) — the `todo/write` event payload, ownership rules, and `TodoItem`.
114
+ - [todo group map](../README.md) — the sibling group page and its package table.
115
+ - [Generated tool catalog](../../../docs/tool-catalog.md#deepseek-aidsh-tool-todo) — the `todo_write` schema the model receives.
116
+ - [Generated configuration catalog](../../../docs/config-catalog.md#deepseek-aidsh-tool-todo) — every accepted config field and its source declaration.
117
+ - [todo_write tool Agent Note](../../../.agents/notes/implemented/feature/2026-06-29-todo-write-tool.md) — the original design, alternatives, and dropped fields.
118
+ - [parallel in-progress Agent Note](../../../.agents/notes/implemented/feature/2026-07-26-todo-parallel-in-progress.md) — why the active-count cap is a deployment policy.
119
+ - [todo plan clears on next turn Agent Note](../../../.agents/notes/implemented/feature/2026-07-28-todo-plan-clears-on-next-turn.md) — the projection's standing-plan lifetime.
120
+
121
+ -----
122
+
123
+ <a id="model-experience"></a>
39
124
  ## Model Experience
40
125
 
41
126
  ### Tool schema
42
127
 
43
128
  #### What the model sees
44
129
 
45
- The model sees the generated [`todo_write` schema](../../../docs/tool-catalog.md#deepseek-aidsh-tool-todo).
130
+ The model sees the generated [`todo_write` schema](../../../docs/tool-catalog.md#deepseek-aidsh-tool-todo): an object with one required `todos` array of `{ content, status }` items, where `status` is `pending`, `in_progress`, or `completed`. The description is the composed whole-list instruction whose active-status clause follows `allowParallelInProgress`.
46
131
 
47
132
  #### Token effect
48
133
 
49
- Fixed schema cost on every request where the tool is visible.
134
+ Fixed schema cost on every request where the tool is visible; the description and schema are stable for a given configuration.
50
135
 
51
136
  #### KV Cache effect
52
137
 
@@ -68,6 +153,25 @@ Append-only; newly visible content follows the reusable request prefix and does
68
153
 
69
154
  ## Known Limitations and Deferred Work
70
155
 
71
- - **Single-owner scope only** — the list belongs to the one calling agent session; subagent/shared/swarm scopes are a deliberate cut (see § Single owner), and a non-agent caller is rejected.
156
+ <a id="known-limitations-and-deferred-work"></a>
157
+
158
+
159
+ These limits define when the tool is a poor fit. They are current package constraints, not a task backlog.
160
+
161
+ - **Single-owner scope only** — the list belongs to the one calling agent session; subagent, shared, and swarm scopes are a deliberate cut, and a non-agent caller is rejected.
72
162
  - **The item shape is deliberately minimal** — `content` plus three-state `status`; whole-list replacement needs no stable id, priority, or active-form fields.
73
- - **Whole-list replacement is the only operation** — no partial updates, no read-back tool; the model must resend the entire list each call.
163
+ - **Whole-list replacement is the only operation** — no partial updates, no read-back tool, and no per-item edits; the model must resend the entire list each call.
164
+
165
+ <a id="dev-note"></a>
166
+ ### Dev Note
167
+
168
+ <details>
169
+ <summary>Working context for maintainers — click to expand</summary>
170
+
171
+ This Dev Note is working context for maintainers: open questions and directions that are not decided. It is explicitly non-authoritative — shipped behavior, limits, and accepted rationale live in the sections above, the package code, and the linked Agent Notes.
172
+
173
+ #### Future: cross-agent and shared lists
174
+
175
+ The single-owner scope is a deliberate cut, and cross-agent or shared lists remain a separate future design: they would need per-item log deltas and explicit scope selection, and would change the model-visible contract. No design exists yet.
176
+
177
+ </details>
package/README.zh.md CHANGED
@@ -1,73 +1,177 @@
1
+ ---
2
+ description: "面向 DeepSeek Harness 会话日志的模型侧 todo_write 工具:整表替换、单一会话归属与 todos 投影,供选择、配置或排查该工具的用户与维护者阅读。"
3
+ kind: "package-reference"
4
+ ---
5
+
1
6
  # @deepseek-ai/dsh-tool-todo
2
7
 
3
8
  [English](README.md) | 中文
4
9
 
5
- 面向模型的 `todo_write` 工具:agent(智能体)的完整任务列表,每次调用都会整体替换。
10
+ ## 概述
11
+
12
+ `dsh-tool-todo` 为 agent 提供一份可用于规划的结构化任务列表:把多步工作拆成具体任务、标记正在进行的任务、完成后逐项勾掉。列表跨轮次、跨重新打开的会话持续存在,agent 与 UI 始终看到最新计划。一个配置开关决定是否允许多个任务同时处于进行中,适用于并行开展工作的 agent。凡是希望 agent 维护可见任务列表的场景都可以使用它;每次更新整体替换列表,只有拥有该列表的 agent 会话才能修改。
13
+
14
+ ## 目录
15
+
16
+ - [使用本包](#use-this-package)
17
+ - [理解实现](#understand-the-implementation)
18
+ - [进一步探索](#further-exploration)
19
+ - [模型体验](#model-experience)
20
+ - [已知限制与延期工作](#known-limitations-and-deferred-work)
21
+ - [开发备注](#dev-note)
22
+
23
+ -----
24
+
25
+ <a id="use-this-package"></a>
26
+ ## 使用本包
27
+
28
+ 当你希望 agent 在工作时维护一份可见的任务列表时使用本包:规划多步工作、展示当前进行中的任务、记录完成情况。挂载它并设置并行开关是唯一的配置步骤;此后每次计划变化,agent 都会通过它自己的规划工具更新列表。
29
+
30
+ ### 何时选择
31
+
32
+ 当某个 agent 会话应当拥有任务列表、且整表更新即可满足需求时选择它——这是规划工具的常见形态。当多个 agent 必须共享同一份列表、或需要逐项编辑时,请避开:列表只属于一个 agent,每次更新都会替换整个列表。它要求环境中确实存在 agent 会话;从不运行 agent 的纯自动化表面无法使用它。
33
+
34
+ ### 最小配置
35
+
36
+ `allowParallelInProgress` 是必填项、没有默认值:省略它的组合会在加载时失败,非布尔值也会被拒绝。可能并发运行工作的 agent(subagent、后台命令、workflow 扇出)设为 `true`,需要单活跃项纪律的设为 `false`。
37
+
38
+ ```yaml
39
+ - name: '@deepseek-ai/dsh-tool-todo'
40
+ config:
41
+ allowParallelInProgress: true
42
+ ```
43
+
44
+ | 字段 | 默认值 | 含义 |
45
+ |---|---|---|
46
+ | `allowParallelInProgress` | 必填 | 是否允许多个 todo 同时处于 `in_progress`;同时选择模型描述中的活跃状态条款 |
47
+
48
+ 生成的[配置目录](../../../docs/config-catalog.zh.md#deepseek-aidsh-tool-todo)是每个受支持字段的穷尽式真源。
49
+
50
+ ### 每次调用做什么
51
+
52
+ agent 每次更新都发送完整列表;新列表替换旧列表,因此没有部分更新或逐项编辑。每个条目是一句简短的任务描述,外加 `pending`、`in_progress` 或 `completed` 状态。成功的更新会返回新的计数——`Updated todo list: <pending> pending, <inProgress> in progress, <completed> completed.`——UI 随即展示新计划。任务描述为空或重复、条目带有描述与状态之外的字段、或(禁用并行时)多个任务被标记为进行中,这些情况下更新都会明确失败。
53
+
54
+ ### 单一所有者
55
+
56
+ 任务列表属于创建它的那一个 agent 会话——subagent 与其他 agent 各自维护自己的列表,不存在跨 agent 共享列表的方式。来自 agent 会话之外的调用会被拒绝,因此 agent 会得知更新失败,而不是被静默丢弃。如果你需要多个 agent 共享同一份列表,本包不提供该能力。
6
57
 
7
- ## 功能
58
+ -----
8
59
 
9
- 注册一个工具 `todo_write(todos: [{ content, status }])` 到 `ctx.tools`。模型每次调用都会发送完整列表,不存在部分更新或单项编辑。每次调用都会向调用 agent 的会话日志追加 `todo/write` 事件(完整列表快照),具体调用 `agent.session.append('todo/write', { todos })`;当前列表是最新的该类事件(回放时后写覆盖先写)。
60
+ <a id="understand-the-implementation"></a>
61
+ ## 理解实现
10
62
 
11
- `status` 是 `pending`、`in_progress` 或 `completed` 之一。
63
+ <details>
64
+ <summary>实现细节——点击展开</summary>
12
65
 
13
- ## 单一所有者
66
+ 本节解释工具背后的设计决策,并指出实现它们的代码位置;可观察行为已在[使用本包](#use-this-package)中完整说明。
14
67
 
15
- 该列表属于调用工具的唯一 agent 会话。不存在 subagent/共享/swarm scope:非 agent 调用方(没有 `exec.agent`)无处写入列表,因此会被拒绝。这是有意设置的 scope 限制,详见 Agent Note。
68
+ ### 设计理念
16
69
 
17
- ## 配置
70
+ 本工具建立在四项承诺之上:
18
71
 
19
- `allowParallelInProgress` 是必填项:每个组合都必须选择是否允许多个 todo 同时处于 `in_progress`。这是部署层的选择而非固定规则:并发的活跃任务是否合理,取决于工具无法观测的运行时并发情况。可能并行展开工作的 agent 使用 `true`,`false` 则强制执行单活跃项纪律。
72
+ - **整表替换、日志承载状态。** 模型重新发送整个列表;`todo/write` 快照存放在事件溯源的会话日志上,持久性、回放与恢复重建都来自日志而非服务。
73
+ - **单一所有者。** 列表属于调用 agent 会话;不存在共享或 swarm 作用域,非 agent 调用方会被拒绝。
74
+ - **部署策略,而非编码规则。** `allowParallelInProgress` 是必填组合选择,因为工具无法观测运行时并发;持久日志不变式刻意不跟随它,因此一种策略下写入的日志在部署收紧另一种策略后仍可回放。
75
+ - **校验让落库快照保持诚实。** schema 层拒绝未知键、`execute` 层拒绝空或重复 content,使持久快照与模型自认为写入的内容一致。
20
76
 
21
- 该开关会同时改变面向模型的指令与接受的输入——`true` 要求模型标记每个正在推进的任务并接受任意数量;`false` 要求恰好一个,并以 `Error: invalid todos: at most one task may be in_progress (got <n>)` 拒绝标记更多的调用。持久日志不变式**不**跟随它:在允许并行时写下的日志,在部署收紧策略之后仍必须可回放,因此不变式对活跃数量保持沉默。
77
+ [todo_write 工具 Agent Note](../../../.agents/notes/implemented/feature/2026-06-29-todo-write-tool.zh.md) 记录原始设计与备选方案;[并行 in-progress Agent Note](../../../.agents/notes/implemented/feature/2026-07-26-todo-parallel-in-progress.zh.md) 记录该策略决策。
22
78
 
23
- ## 验证
79
+ ### 源码地图
24
80
 
25
- 除 schema 的类型/必填/枚举检查外,`execute` 还会拒绝空或重复的 `content`,以及 `content`/`status` 之外的任何条目键——扩展条目形状(id、嵌套)会明确报错而不是被静默压平,保证落日志的快照与模型自认为写入的内容一致。同时可以有多少任务处于 `in_progress` 由部署决定(见 § 配置):选择 `true` 的组合允许并行工作(并发 subagent、后台命令)同时将多个任务标记为 `in_progress`。列表的顺序及及时更新由模型依照工具描述负责。
81
+ | 文件 | 职责 |
82
+ |---|---|
83
+ | [`src/index.ts`](src/index.ts) | 插件入口:`Config` schema、工具注册、`todos` 投影单元 |
84
+ | [`src/types.ts`](src/types.ts) | `todos` 投影键声明及其载荷类型的唯一归属地 |
85
+ | [`src/client.ts`](src/client.ts) | 客户端命名空间对类型出口的再导出 |
86
+ | [`src/invariant.ts`](src/invariant.ts) | 不变式伴生插件:校验持久整表快照与开放轮次归属 |
26
87
 
27
- ## 渲染
88
+ ### 导出形状
28
89
 
29
- 规范结果为 `{ todos, counts: { pending, inProgress, completed } }`;其 Native 渲染器返回精简的更新确认。工具还会写入完整 `todo/write` 会话事件。UI 订阅事件流,并自行渲染该持久化列表:[web 客户端](../../client/ui-conversation)基于当前有效计划(其后没有更晚 `turn/start` 的最近一次 `todo/write`)显示计划条和专属工具行([展示](../../../.agents/notes/implemented/feature/2026-07-23-web-todo-display.zh.md)、[生命周期](../../../.agents/notes/implemented/feature/2026-07-28-todo-plan-clears-on-next-turn.zh.md))。
90
+ 本插件是函数/命名空间插件:导出 `name` / `inject` / `apply`,没有默认导出。多余的 `export default` 会让 Loader 的 `unwrapExports` 折叠模块并丢弃 `inject`(参见 [postmortem 0001](../../../docs/postmortem/0001-acp-default-export-drops-inject.zh.md))。
30
91
 
31
- ## 会话投影
92
+ ### 会话投影
32
93
 
33
- 当组合挂载了 `ctx.sessionProjections`([`@deepseek-ai/dsh-session-projection`](../../session/session-projection/README.zh.md))时,本包在一个注入的子插件中注册 `todos` 投影单元:`init` = `null`(尚无写入)、`apply` = 从每个 `todo/write` 取整表,并在每个 `turn/start` 清为 `null`(当前有效计划;`turn/end` 保留刚完成的清单;其余事件都返回同一个状态引用)、`view` = 恒等、`stateVersion` = 2。该键在本包中合并进 `SessionProjectionMap`(经 Service Definition 包的 `/types` 出口);框架驱动该单元,载体通过历史尾页与 `session/projection` 推送帧提供该值。未挂载注册表的组合不受影响。生命周期理由见 [在下一轮次清空 todo 计划](../../../.agents/notes/implemented/feature/2026-07-28-todo-plan-clears-on-next-turn.zh.md)。
94
+ 当组合挂载 `ctx.sessionProjections`([`@deepseek-ai/dsh-session-projection`](../../session/session-projection/README.zh.md))时,本包在注入的子插件中注册 `todos` 单元:投影即有效计划——最新的整份 `todo/write` 列表,首次写入前为 `null`,下一轮次开始时清空,而 `turn/end` 保留刚完成的清单。该键在此处合并进 `SessionProjectionMap`;载体通过历史尾页与 `session/projection` 推送帧提供该值。未挂载注册表的组合不受影响;单元注册见 [src/index.ts](src/index.ts)。生命周期理由见 [todo 计划在下一轮次清空 Agent Note](../../../.agents/notes/implemented/feature/2026-07-28-todo-plan-clears-on-next-turn.zh.md)。
34
95
 
35
- ## 导出形状
96
+ ### 持久日志不变式
36
97
 
37
- 函数/命名空间插件:导出 `name`/`inject`/`apply`,不提供默认导出。意外的 `export default` 会被 Loader 的 `unwrapExports` 折叠为默认导出,并导致 `inject` 丢失(参见 [docs/postmortem/0001](../../../docs/postmortem/0001-acp-default-export-drops-inject.zh.md))。
98
+ 不变式伴生插件注册到 `ctx.invariants`,先分别校验既有会话与新公布会话一次,再为实时追加推进按会话提交的轮次轨迹。它会拒绝畸形条目、空或重复 content、未知状态,以及开放轮次之外的持久 `todo/write`;核心 session 通用处理声明合并事件,而本生产包拥有 todo 专用规则。它刻意不约束有多少条目处于 `in_progress`,因为那是工具按部署制定的策略,而非持久数据规则(见[事件归属](../../../.agents/notes/implemented/architecture/2026-07-20-todo-event-ownership.zh.md))。
38
99
 
100
+ ### 调用机制
101
+
102
+ 每次调用都会先校验提交的列表是否符合 schema,拒绝不一致的输入,成功后把完整快照作为 `todo/write` 会话事件追加并返回新的计数;当前列表始终是日志中最近一次 `todo/write`(回放时后写覆盖先写)。确切的校验与追加步骤见 [src/index.ts](src/index.ts)。
103
+
104
+ </details>
105
+
106
+ -----
107
+
108
+ <a id="further-exploration"></a>
109
+ ## 进一步探索
110
+
111
+ 当包级约定不够用时阅读以下页面。它们从会话子系统逐步进入生成的目录,以及工具背后的决策记录。
112
+
113
+ - [Todo 子系统](../../../docs/subsystems/todo.zh.md)——`todo/write` 事件载荷、归属规则与 `TodoItem`。
114
+ - [todo 组映射](../README.zh.md)——同级组页面及其包表格。
115
+ - [生成的工具目录](../../../docs/tool-catalog.zh.md#deepseek-aidsh-tool-todo)——模型接收的 `todo_write` schema。
116
+ - [生成的配置目录](../../../docs/config-catalog.zh.md#deepseek-aidsh-tool-todo)——每个受支持配置字段及其源声明。
117
+ - [todo_write 工具 Agent Note](../../../.agents/notes/implemented/feature/2026-06-29-todo-write-tool.zh.md)——原始设计、备选方案与砍掉的字段。
118
+ - [并行 in-progress Agent Note](../../../.agents/notes/implemented/feature/2026-07-26-todo-parallel-in-progress.zh.md)——为何活跃计数上限成为部署策略。
119
+ - [todo 计划在下一轮次清空 Agent Note](../../../.agents/notes/implemented/feature/2026-07-28-todo-plan-clears-on-next-turn.zh.md)——投影的有效计划生命周期。
120
+
121
+ -----
122
+
123
+ <a id="model-experience"></a>
39
124
  ## 模型体验
40
125
 
41
126
  ### 工具 schema
42
127
 
43
- #### 模型看到的内容
128
+ #### 模型看到什么
44
129
 
45
- 模型会看到生成的 [`todo_write` schema](../../../docs/tool-catalog.zh.md#deepseek-aidsh-tool-todo)。
130
+ 模型会看到生成的 [`todo_write` schema](../../../docs/tool-catalog.zh.md#deepseek-aidsh-tool-todo):一个对象,含一个必填的 `todos` 数组,元素为 `{ content, status }`,其中 `status` 为 `pending`、`in_progress` 或 `completed`。描述是组合后的整表指令,其活跃状态条款跟随 `allowParallelInProgress`。
46
131
 
47
132
  #### Token 影响
48
133
 
49
- 工具可见的每个请求都有固定的 schema token 开销。
134
+ 工具可见的每个请求都有固定 schema 开销;在给定配置下描述与 schema 保持稳定。
50
135
 
51
136
  #### KV Cache 影响
52
137
 
53
- 只要定义和可见性不变,前缀就保持稳定。插件生命周期或 scope 限制可能会使从此 schema 起的缓存复用失效。
138
+ 定义与可见性不变时前缀保持稳定。插件生命周期或作用域限制可能使从此 schema 起的复用失效。
54
139
 
55
140
  ### 工具调用历史与结果
56
141
 
57
- #### 模型看到的内容
142
+ #### 模型看到什么
58
143
 
59
- 每个 assistant 工具调用都会在参数中保留整个替换列表。成功时原样返回 `Updated todo list: <pending> pending, <inProgress> in progress, <completed> completed.`。稳定失败文本为 ``Error: invalid todo: `content` must be a non-empty string``、`Error: invalid todos: duplicate content "<content>"`、`Error: todo_write requires an owning agent session`,以及——仅在部署设置了 `allowParallelInProgress: false` 时——`Error: invalid todos: at most one task may be in_progress (got <n>)`。完整 `todo/write` 会话事件是 UI 与回放状态,而非第二条模型消息。
144
+ 每次 assistant 工具调用都会在参数中保留整个替换列表。成功时原样返回 `Updated todo list: <pending> pending, <inProgress> in progress, <completed> completed.`。稳定失败文本为 ``Error: invalid todo: `content` must be a non-empty string``、`Error: invalid todos: duplicate content "<content>"`、`Error: todo_write requires an owning agent session`,以及——仅在部署设置 `allowParallelInProgress: false` 时——`Error: invalid todos: at most one task may be in_progress (got <n>)`。完整的 `todo/write` 会话事件是 UI 与回放状态,而非第二条模型消息。
60
145
 
61
146
  #### Token 影响
62
147
 
63
- token 用量会随模型每次提交的完整列表增长,且这些调用参数会保留到压缩(compaction)。结果本身很小,且形状固定。
148
+ token 用量随模型每次提交的完整列表增长,这些调用参数会保留到压缩(compaction)。结果本身很小且形状固定。
64
149
 
65
150
  #### KV Cache 影响
66
151
 
67
- 仅追加;新可见内容位于可复用请求前缀之后,不会使现有 KV-cache 条目失效。
152
+ 仅追加;新可见内容位于可复用请求前缀之后,不会使既有 KV-cache 条目失效。
153
+
154
+ ## 已知限制与延期工作
155
+
156
+ <a id="known-limitations-and-deferred-work"></a>
157
+
158
+
159
+ 这些限制说明工具何时不合适。它们是当前包约束,不是任务积压。
160
+
161
+ - **仅单一所有者作用域**——列表属于唯一调用 agent 会话;subagent、共享与 swarm 作用域是有意砍掉的部分,非 agent 调用方会被拒绝。
162
+ - **条目形状刻意保持最小**——`content` 加三态 `status`;整表替换不需要稳定 id、优先级或 active-form 字段。
163
+ - **整表替换是唯一操作**——没有部分更新、没有回读工具、没有逐项编辑;模型每次调用都必须重新发送完整列表。
164
+
165
+ <a id="dev-note"></a>
166
+ ### 开发备注
167
+
168
+ <details>
169
+ <summary>维护者的工作上下文——点击展开</summary>
170
+
171
+ 本开发备注是维护者的工作上下文:未决问题与尚未决定的方向。它明确不具权威性——已交付行为、限制与既定理由以上文、包代码和相关 Agent Note 为准。
172
+
173
+ #### 未来:跨 agent 与共享列表
68
174
 
69
- ## 已知限制与暂缓事项
175
+ 单一所有者作用域是有意砍掉的部分,跨 agent 或共享列表仍是独立的未来设计:它们需要逐项日志增量与显式作用域选择,并会改变模型可见约定。目前尚不存在设计。
70
176
 
71
- - **仅单一所有者 scope**:列表属于唯一调用 agent 会话;subagent/共享/swarm scope 是有意设置的限制(参见「单一所有者」一节),非 agent 调用方会被拒绝。
72
- - **条目形状有意保持最小**:`content` 加三态 `status`;整表替换不需要稳定 id、优先级或 active-form 字段。
73
- - **整表替换是唯一操作**:没有部分更新,也没有回读工具;模型每次调用都必须重新发送完整列表。
177
+ </details>
package/lib/index.js CHANGED
@@ -9,7 +9,7 @@ import { defineTool } from "@deepseek-ai/dsh-tools";
9
9
  * @module @deepseek-ai/dsh-tool-todo
10
10
  */
11
11
  const name = "tool-todo";
12
- const inject = ["tools"];
12
+ const inject = ["tools", "sessionProjections"];
13
13
  /** The valid {@link TodoItem} statuses, as a runtime set for input narrowing. */
14
14
  const STATUSES = [
15
15
  "pending",
@@ -70,29 +70,27 @@ const todosProjectionSchema = z$1.union([z$1.array(z$1.object({
70
70
  ])
71
71
  })), z$1.null()]);
72
72
  /**
73
- * Register the `todo_write` tool on `ctx.tools` and, when the session-projection seam is composed,
74
- * the `todos` unit.
75
- * @param ctx - registrant context carrying the tool registry.
73
+ * Register the `todo_write` tool on `ctx.tools` and the `todos` unit on
74
+ * `ctx.sessionProjections`.
75
+ * @param ctx - registrant context carrying the tool and session-projection registries.
76
76
  * @param config - deployment's explicit todo policy.
77
77
  */
78
78
  function apply(ctx, config) {
79
79
  const allowParallel = config.allowParallelInProgress;
80
- ctx.inject(["sessionProjections"], (projectionCtx) => {
81
- projectionCtx.sessionProjections.register({
82
- key: "todos",
83
- stateSchema: todosProjectionSchema,
84
- init: () => null,
85
- apply: (state, event) => {
86
- if (event.type === "todo/write") return event.data.todos;
87
- if (event.type === "turn/start") return null;
88
- return state;
89
- },
90
- wire: {
91
- viewSchema: todosProjectionSchema,
92
- view: (state) => state
93
- },
94
- stateVersion: 2
95
- });
80
+ ctx.sessionProjections.register({
81
+ key: "todos",
82
+ stateSchema: todosProjectionSchema,
83
+ init: () => null,
84
+ apply: (state, event) => {
85
+ if (event.type === "todo/write") return event.data.todos;
86
+ if (event.type === "turn/start") return null;
87
+ return state;
88
+ },
89
+ wire: {
90
+ viewSchema: todosProjectionSchema,
91
+ view: (state) => state
92
+ },
93
+ stateVersion: 2
96
94
  });
97
95
  ctx.tools.register(defineTool({
98
96
  name: "todo_write",
package/lib/invariant.js CHANGED
@@ -31,17 +31,51 @@ function validateTodos(value, fail) {
31
31
  if (typeof status !== "string" || !TODO_STATUSES.has(status)) fail(`todo/write carries unknown status ${JSON.stringify(status)}`);
32
32
  }
33
33
  }
34
- /** Validate the package-owned event fields and ignore unrelated events. */
35
- function validateEvent(event, fail) {
36
- if (event.type === "todo/write") validateTodos(event.data.todos, fail);
34
+ /** Advance the trace after one event has committed. */
35
+ function advanceTrace(trace, event) {
36
+ if (event.type === "turn/start") trace.open = true;
37
+ if (event.type === "turn/end") trace.open = false;
38
+ }
39
+ /** Validate one package-owned event against the preceding committed trace. */
40
+ function validateEvent(event, trace, fail) {
41
+ if (event.type !== "todo/write") return;
42
+ validateTodos(event.data.todos, fail);
43
+ if (!trace.open) fail("todo/write appended outside any open turn");
44
+ }
45
+ /** Validate one existing log in a single pass and return its tail trace. */
46
+ function seedTrace(session, fail) {
47
+ const trace = { open: false };
48
+ for (const event of session.events) {
49
+ validateEvent(event, trace, fail);
50
+ advanceTrace(trace, event);
51
+ }
52
+ return trace;
37
53
  }
38
54
  /** Install validation for loaded and newly appended whole-list todo snapshots. */
39
55
  const install = Object.assign((ctx, fail) => {
40
- for (const session of ctx.sessions.list()) for (const event of session.events) validateEvent(event, fail);
56
+ const traces = /* @__PURE__ */ new WeakMap();
57
+ const seed = (session) => {
58
+ traces.set(session, seedTrace(session, fail));
59
+ };
60
+ const traceFor = (session) => {
61
+ let trace = traces.get(session);
62
+ if (trace === void 0) {
63
+ trace = seedTrace(session, fail);
64
+ traces.set(session, trace);
65
+ }
66
+ return trace;
67
+ };
68
+ for (const session of ctx.sessions.list()) seed(session);
69
+ ctx.on("session/created", (session) => {
70
+ seed(session);
71
+ }, { global: true });
41
72
  ctx.on("internal/dispatch", (_mode, eventName, args) => {
42
73
  if (eventName !== "session/event") return;
43
- const event = args[1];
44
- validateEvent(event, fail);
74
+ const [session, event] = args;
75
+ validateEvent(event, traceFor(session), fail);
76
+ }, { global: true });
77
+ ctx.on("session/event", (session, event) => {
78
+ advanceTrace(traceFor(session), event);
45
79
  }, { global: true });
46
80
  }, { inject: ["sessions"] });
47
81
  /**
@@ -23,9 +23,9 @@ export interface Config {
23
23
  /** Schemastery configuration for the todo tool consumer. */
24
24
  export declare const Config: z<Config>;
25
25
  /**
26
- * Register the `todo_write` tool on `ctx.tools` and, when the session-projection seam is composed,
27
- * the `todos` unit.
28
- * @param ctx - registrant context carrying the tool registry.
26
+ * Register the `todo_write` tool on `ctx.tools` and the `todos` unit on
27
+ * `ctx.sessionProjections`.
28
+ * @param ctx - registrant context carrying the tool and session-projection registries.
29
29
  * @param config - deployment's explicit todo policy.
30
30
  */
31
31
  export declare function apply(ctx: Context, config: Config): void;
@@ -8,7 +8,7 @@ import z from '@deepseek-ai/schemastery';
8
8
  import { z as zod } from 'zod';
9
9
  import { defineTool } from '@deepseek-ai/dsh-tools';
10
10
  export const name = 'tool-todo';
11
- export const inject = ['tools'];
11
+ export const inject = ['tools', 'sessionProjections'];
12
12
  /** The valid {@link TodoItem} statuses, as a runtime set for input narrowing. */
13
13
  const STATUSES = ['pending', 'in_progress', 'completed'];
14
14
  /** Schemastery configuration for the todo tool consumer. */
@@ -83,33 +83,30 @@ const todosProjectionSchema = zod.union([
83
83
  zod.null(),
84
84
  ]);
85
85
  /**
86
- * Register the `todo_write` tool on `ctx.tools` and, when the session-projection seam is composed,
87
- * the `todos` unit.
88
- * @param ctx - registrant context carrying the tool registry.
86
+ * Register the `todo_write` tool on `ctx.tools` and the `todos` unit on
87
+ * `ctx.sessionProjections`.
88
+ * @param ctx - registrant context carrying the tool and session-projection registries.
89
89
  * @param config - deployment's explicit todo policy.
90
90
  */
91
91
  export function apply(ctx, config) {
92
92
  const allowParallel = config.allowParallelInProgress;
93
- // The unit child activates only when a projection registry is composed
94
- // (headless assemblies without the seam stay unaffected). Standing-plan fold:
95
- // latest whole todo/write list, cleared by the next turn/start (turn/end keeps
96
- // the finished checklist visible); null before the first write or after a
97
- // later turn begins; every other event returns the same state reference.
98
- ctx.inject(['sessionProjections'], (projectionCtx) => {
99
- projectionCtx.sessionProjections.register({
100
- key: 'todos',
101
- stateSchema: todosProjectionSchema,
102
- init: () => null,
103
- apply: (state, event) => {
104
- if (event.type === 'todo/write')
105
- return event.data.todos;
106
- if (event.type === 'turn/start')
107
- return null;
108
- return state;
109
- },
110
- wire: { viewSchema: todosProjectionSchema, view: state => state },
111
- stateVersion: 2,
112
- });
93
+ // Standing-plan fold: latest whole todo/write list, cleared by the next
94
+ // turn/start (turn/end keeps the finished checklist visible); null before the
95
+ // first write or after a later turn begins; every other event returns the
96
+ // same state reference.
97
+ ctx.sessionProjections.register({
98
+ key: 'todos',
99
+ stateSchema: todosProjectionSchema,
100
+ init: () => null,
101
+ apply: (state, event) => {
102
+ if (event.type === 'todo/write')
103
+ return event.data.todos;
104
+ if (event.type === 'turn/start')
105
+ return null;
106
+ return state;
107
+ },
108
+ wire: { viewSchema: todosProjectionSchema, view: state => state },
109
+ stateVersion: 2,
113
110
  });
114
111
  ctx.tools.register(defineTool({
115
112
  name: 'todo_write',
@@ -33,23 +33,55 @@ function validateTodos(value, fail) {
33
33
  }
34
34
  }
35
35
  }
36
- /* jscpd:ignore-start -- package companions share replay and dispatch plumbing */
37
- /** Validate the package-owned event fields and ignore unrelated events. */
38
- function validateEvent(event, fail) {
39
- if (event.type === 'todo/write')
40
- validateTodos(event.data.todos, fail);
36
+ /** Advance the trace after one event has committed. */
37
+ function advanceTrace(trace, event) {
38
+ if (event.type === 'turn/start')
39
+ trace.open = true;
40
+ if (event.type === 'turn/end')
41
+ trace.open = false;
42
+ }
43
+ /** Validate one package-owned event against the preceding committed trace. */
44
+ function validateEvent(event, trace, fail) {
45
+ if (event.type !== 'todo/write')
46
+ return;
47
+ validateTodos(event.data.todos, fail);
48
+ if (!trace.open)
49
+ fail('todo/write appended outside any open turn');
50
+ }
51
+ /** Validate one existing log in a single pass and return its tail trace. */
52
+ function seedTrace(session, fail) {
53
+ const trace = { open: false };
54
+ for (const event of session.events) {
55
+ validateEvent(event, trace, fail);
56
+ advanceTrace(trace, event);
57
+ }
58
+ return trace;
41
59
  }
42
60
  /** Install validation for loaded and newly appended whole-list todo snapshots. */
43
61
  const install = Object.assign((ctx, fail) => {
44
- for (const session of ctx.sessions.list()) {
45
- for (const event of session.events)
46
- validateEvent(event, fail);
47
- }
62
+ const traces = new WeakMap();
63
+ const seed = (session) => {
64
+ traces.set(session, seedTrace(session, fail));
65
+ };
66
+ const traceFor = (session) => {
67
+ let trace = traces.get(session);
68
+ if (trace === undefined) {
69
+ trace = seedTrace(session, fail);
70
+ traces.set(session, trace);
71
+ }
72
+ return trace;
73
+ };
74
+ for (const session of ctx.sessions.list())
75
+ seed(session);
76
+ ctx.on('session/created', (session) => { seed(session); }, { global: true });
48
77
  ctx.on('internal/dispatch', (_mode, eventName, args) => {
49
78
  if (eventName !== 'session/event')
50
79
  return;
51
- const event = args[1];
52
- validateEvent(event, fail);
80
+ const [session, event] = args;
81
+ validateEvent(event, traceFor(session), fail);
82
+ }, { global: true });
83
+ ctx.on('session/event', (session, event) => {
84
+ advanceTrace(traceFor(session), event);
53
85
  }, { global: true });
54
86
  }, { inject: ['sessions'] });
55
87
  /* jscpd:ignore-end */
@@ -7,8 +7,30 @@
7
7
  *
8
8
  * @module @deepseek-ai/dsh-tool-todo/types
9
9
  */
10
- import type { TodoItem } from '@deepseek-ai/dsh-session/types';
11
- export type { TodoItem } from '@deepseek-ai/dsh-session/types';
10
+ /**
11
+ * One entry in an agent's todo list — the unit of the `todo/write`
12
+ * whole-list snapshot declared by this package.
13
+ *
14
+ * Deliberately minimal: a human-readable `content` line and a three-state
15
+ * `status`. No id, priority, or `activeForm` — the list is replaced wholesale
16
+ * on every write (last-write-wins), so entries need no stable identity. The
17
+ * three statuses describe the complete portable lifecycle needed by model and
18
+ * UI consumers.
19
+ */
20
+ export interface TodoItem {
21
+ /** What this task is — a short imperative line shown in the UI. */
22
+ content: string;
23
+ /** Lifecycle state. `in_progress` marks a task being worked now; parallel work may mark several. */
24
+ status: 'pending' | 'in_progress' | 'completed';
25
+ }
26
+ declare module '@deepseek-ai/dsh-session/types' {
27
+ interface SessionEventMap {
28
+ /** Whole-list snapshot; latest write wins on replay. Log-only UI state; never derived history. */
29
+ 'todo/write': {
30
+ todos: TodoItem[];
31
+ };
32
+ }
33
+ }
12
34
  declare module '@deepseek-ai/dsh-session-projection/types' {
13
35
  interface SessionProjectionStateMap {
14
36
  todos: TodoItem[] | null;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@deepseek-ai/dsh-tool-todo",
3
3
  "description": "Model-facing todo_write tool over the DeepSeek Harness event-sourced session log",
4
- "version": "0.1.1-rc.1",
4
+ "version": "0.1.2-alpha.2",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -38,30 +38,29 @@
38
38
  "license": "MIT",
39
39
  "dependencies": {
40
40
  "zod": "^4.4.3",
41
- "@deepseek-ai/schemastery": "^3.18.1"
41
+ "@deepseek-ai/schemastery": "^3.18.2"
42
42
  },
43
43
  "peerDependencies": {
44
- "@deepseek-ai/dsh-agent": "^0.1.1-rc.1",
45
- "@deepseek-ai/dsh-session": "^0.1.1-rc.1",
46
- "@deepseek-ai/dsh-invariants": "^0.1.1-rc.1",
47
- "@deepseek-ai/dsh-tools": "^0.1.1-rc.1",
48
- "@deepseek-ai/cordis": "^4.0.1",
49
- "@deepseek-ai/dsh-session-projection": "^0.1.1-rc.1"
44
+ "@deepseek-ai/dsh-agent": "^0.1.2-alpha.2",
45
+ "@deepseek-ai/dsh-invariants": "^0.1.2-alpha.2",
46
+ "@deepseek-ai/dsh-session": "^0.1.2-alpha.2",
47
+ "@deepseek-ai/dsh-session-projection": "^0.1.2-alpha.2",
48
+ "@deepseek-ai/dsh-tools": "^0.1.2-alpha.2",
49
+ "@deepseek-ai/cordis": "^4.0.2"
50
50
  },
51
51
  "devDependencies": {
52
- "@deepseek-ai/cordis-plugin-include": "^1.0.6",
53
- "@deepseek-ai/cordis-plugin-loader": "^1.0.2",
54
- "@deepseek-ai/dsh-agent": "^0.1.1-rc.1",
55
- "@deepseek-ai/dsh-agent-loop-testkit": "^0.1.1-rc.1",
56
- "@deepseek-ai/dsh-agent-loop": "^0.1.1-rc.1",
57
- "@deepseek-ai/dsh-invariants": "^0.1.1-rc.1",
58
- "@deepseek-ai/dsh-host-apiproxy": "^0.1.1-rc.1",
59
- "@deepseek-ai/dsh-llm": "^0.1.1-rc.1",
60
- "@deepseek-ai/dsh-session": "^0.1.1-rc.1",
61
- "@deepseek-ai/dsh-session-projection": "^0.1.1-rc.1",
62
- "@deepseek-ai/dsh-system-prompt": "^0.1.1-rc.1",
63
- "@deepseek-ai/dsh-tools": "^0.1.1-rc.1",
64
- "@deepseek-ai/dsh-user-questions": "^0.1.1-rc.1",
65
- "@deepseek-ai/cordis": "^4.0.1"
52
+ "@deepseek-ai/cordis-plugin-include": "^1.0.7",
53
+ "@deepseek-ai/cordis-plugin-loader": "^1.0.3",
54
+ "@deepseek-ai/dsh-agent": "^0.1.2-alpha.2",
55
+ "@deepseek-ai/dsh-agent-loop": "^0.1.2-alpha.2",
56
+ "@deepseek-ai/dsh-agent-loop-testkit": "^0.1.2-alpha.2",
57
+ "@deepseek-ai/dsh-invariants": "^0.1.2-alpha.2",
58
+ "@deepseek-ai/dsh-session": "^0.1.2-alpha.2",
59
+ "@deepseek-ai/dsh-session-projection": "^0.1.2-alpha.2",
60
+ "@deepseek-ai/dsh-system-prompt": "^0.1.2-alpha.2",
61
+ "@deepseek-ai/dsh-llm": "^0.1.2-alpha.2",
62
+ "@deepseek-ai/dsh-tools": "^0.1.2-alpha.2",
63
+ "@deepseek-ai/dsh-user-questions": "^0.1.2-alpha.2",
64
+ "@deepseek-ai/cordis": "^4.0.2"
66
65
  }
67
66
  }