@deepseek-ai/dsh-plan-mode 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/plan/plan-mode/README.md
5
- README.md: 3eabe2cb3f04b434b7f908f7beca869f1022a59e
6
- README.zh.md: b3548da880af5d0cacfebba4486294d9d5085626
5
+ README.md: e768a19c67b2973ff32aa0fe29e51d1b90ea96c9
6
+ README.zh.md: 9d2b1ed6e1eebee6f3e9cd27fcc8ebad2c626a89
package/README.md CHANGED
@@ -1,51 +1,135 @@
1
+ ---
2
+ description: "Plan mode for users and maintainers choosing, configuring, or debugging the per-agent planning feature with deployment guidance, a /plan command, and a user-reviewed exit."
3
+ kind: "package-reference"
4
+ ---
5
+
1
6
  # @deepseek-ai/dsh-plan-mode
2
7
 
3
8
  English | [中文](README.zh.md)
4
9
 
5
- Logged, per-agent plan collaboration state with deployment-owned guidance, direct `/plan [message]` entry and `/plan off` exit commands, and the reviewed `exit_plan_mode` exit. Plan mode is soft guidance; sandbox mode and approval policy enforce restrictions independently and do not read or write plan state.
6
-
7
- ## Durable state
10
+ ## Summary
8
11
 
9
- `plan/mode` (`{ active: boolean }`) is a log-only, whole-value-replace `SessionEventMap` member. `foldPlanMode(events)` returns the last logged value or `false`, so resume, fork, and compaction recover plan state directly from the session log. UIs observe committed flips through `session/event`.
12
+ `dsh-plan-mode` adds plan mode to the agent: while it is active, the agent explores and designs before executing, guided by instructions the deployment writes, and presents the finished plan for your approval before carrying it out. You enter plan mode with `/plan` (optionally with a message or images) and leave it with `/plan off`; the finished plan arrives as a review where you can approve it or send the agent back to keep planning. Plan mode is guidance, not enforcement: every tool stays available, so sandbox mode and approval prompts remain the way to impose limits. Choose it when the agent should think before acting, and plan mode carries over when a session resumes or forks.
10
13
 
11
- `ctx.planMode.set(agent, active)` appends the standalone `plan/mode` event immediately when the agent is idle, because no in-turn pre-step runs before the next prompt. While the agent is running, it holds a pending selection for the next accepted in-turn pre-step. It returns which happened (`committed`/`queued`), a `cancelled` reversal, or a `noop`. `get(agent)` returns `{ active, pending? }`, separating the logged state used to assemble the current step from a user's mid-turn selection. Initial and continuation pre-steps both apply pending selections; a same-step request-recovery retry reuses its frozen assembly and leaves the selection pending for the next pre-step. A changed user selection contributes one plugin-sourced `user/message` notice when the last logged request header described the other state (both commit paths).
14
+ ## Table of Contents
12
15
 
13
- ## Model and human interactions
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)
14
22
 
15
- While active, `plan:policy` renders the configured `section`. The plugin always registers `exit_plan_mode`, keeping tool schemas stable across the transition; its execute path accepts only active plan mode and leaves it only after an exact user approval through `ctx.userQuestions`.
23
+ -----
16
24
 
17
- The review question declares the `plan-review` presentation intent, naming `Approve` as the label that approves it, so a capable UI presents the plan as a decision instead of a generic question; the answer the tool reads is the same either way. A dismissed review — the user closing the request to speak instead — is reported to the model as such, telling it to stay in plan mode and wait for the message; every other review failure keeps the seam's own message.
25
+ <a id="use-this-package"></a>
26
+ ## Use this package
18
27
 
19
- When `ctx.commands` is composed, the package registers `/plan [message]` and reserves the exact argument `off` for direct exit. Bare `/plan` selects plan mode; any other non-empty argument selects it first and is then submitted through `agent.steer()`, so it becomes the next step's ordinary logged user message under plan guidance. `/plan off` selects inactive without sending model input; it also cancels a pending entry before plan mode reaches a request. The command declares `input.images`: composer image attachments ride the steered message ahead of its text block. Bare `/plan` with images steers an image-only user message, while `/plan off` with images returns a direct error before any mode change so the composer keeps them.
28
+ When plan mode is active, the agent works under your instructions and presents its plan for review instead of executing right away. The common path: configure the guidance text, enter plan mode with `/plan`, and review the finished plan when the agent calls `exit_plan_mode`.
20
29
 
21
- The Web client consumes the plugin-owned `/plan` command; other entry points may drive the same service directly without defining a second mode vocabulary.
30
+ ### When to choose it
22
31
 
23
- ## Session projection
32
+ Choose plan mode when the agent should explore and design before executing and you want to approve the plan first. It does not restrict the agent: every tool stays callable, so use sandbox mode and approval prompts when you need enforced limits. Skip it when the agent should act on your requests immediately, without a planning phase.
24
33
 
25
- When the composition mounts `ctx.sessionProjections` ([`@deepseek-ai/dsh-session-projection`](../../session/session-projection/README.md)), this package registers the `plan` projection unit under an injected child. A `command/run` record named `plan` with recorded `args` starts a candidate target (`off` → inactive, anything else → active); its paired `command/done` retains a successful selection and drops an error; `plan/mode` commits the logged state and clears the retained selection. Every other event returns the same state reference. `view` derives `{ active, pending }`, where `pending` is true only while an unsettled or successful selection differs from the logged state. This remains a pure replay quantity, so host restarts, other tabs, and cold reads recover it from the log alone, and a rejected `/plan off` with images cannot leave a pending exit. The key merges into `SessionProjectionMap` from `src/types.ts` (served to host consumers via `./types` and client aggregates via `./client`); 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.
34
+ ### Minimal configuration
26
35
 
27
- ## Configuration
36
+ The only required configuration is the guidance text the agent follows while planning; anything else you add fails at load.
28
37
 
29
38
  ```yaml
30
- - id: plan-mode
31
- name: '@deepseek-ai/dsh-plan-mode'
39
+ - name: '@deepseek-ai/dsh-plan-mode'
32
40
  config:
33
41
  section: |
34
42
  You are in plan mode. Explore and design before presenting the complete
35
43
  plan through exit_plan_mode.
36
44
  ```
37
45
 
38
- `section` is required and non-empty. Unknown keys fail at load. The package does not accept arbitrary named modes, tool filters, sandbox settings, or approval policy.
46
+ | Field | Default | Meaning |
47
+ |---|---|---|
48
+ | `section` | required | Guidance rendered as the `plan:policy` prompt section while plan mode is active |
49
+
50
+ The generated [configuration catalog](../../../docs/config-catalog.md#deepseek-aidsh-plan-mode) is the exhaustive source for every accepted field and its JSDoc.
51
+
52
+ <a id="model-and-human-interactions"></a>
53
+ ### Entering and leaving plan mode
54
+
55
+ Type `/plan` to enter plan mode, or `/plan <message>` to enter with an instruction — the message becomes your next request under plan guidance. Type `/plan off` to leave plan mode directly; it also cancels a plan-mode entry that has not taken effect yet.
56
+
57
+ You can attach images to a `/plan` message, and they are included with your instruction. `/plan off` with images is rejected so the images are not lost. The `/plan` command is available wherever slash commands are supported, such as the Web client.
58
+
59
+ ### The reviewed exit
60
+
61
+ When the agent has a finished plan, it calls `exit_plan_mode` with the plan written as markdown and starting with a heading. You review that exact plan and choose `Approve` to leave plan mode, or `Keep planning` to send the agent back with feedback.
62
+
63
+ Choosing `Keep planning` (optionally with free-text feedback) sends the agent back to revise the plan; closing the review to type a message instead tells the agent to wait for your next message. If no interactive review is available, `exit_plan_mode` cannot run and you can still leave plan mode with `/plan off`.
64
+
65
+ ### Observing plan state
66
+
67
+ Interfaces can show whether plan mode is active and whether a mode change you requested is still waiting to take effect. The state is the same in every tab and survives restarts.
68
+
69
+ -----
70
+
71
+ <a id="understand-the-implementation"></a>
72
+ ## Understand the implementation
73
+
74
+ <details>
75
+ <summary>Implementation internals — click to expand</summary>
76
+
77
+ This section explains the design decisions behind the package and points at the code that realizes them; the observable behavior is fully covered in [Use this package](#use-this-package).
78
+
79
+ ### Design philosophy
80
+
81
+ Plan mode is a product package, not a capability seam: there is no swappable backend, so the state, guidance, command, and exit tool live in one place. The durable stance is one log-only whole-value-replace event, never a live mirror, so resume, fork, and compaction recover it by folding the log. Guidance is a soft layer — the package registers one prompt section and one tool, and restrains through text rather than filtering capabilities.
82
+
83
+ ### Durable state and step-boundary appends
84
+
85
+ The package persists one log-only whole-value event, `plan/mode`, and the last logged value is the state. A mode change appends immediately when no turn is open; during an open turn it stays pending until the next accepted in-turn pre-step — the only append point while an agent runs — and an append failure cannot block the turn. The `set`/`get` service methods and their exact return states live in [`src/index.ts`](src/index.ts) and read the registered `plan` projection; the first dependent access fails explicitly when the registry or key is absent.
86
+
87
+ ### The `/plan` command
88
+
89
+ The command child activates only when a commands service is composed. It maps bare `/plan` to active, the exact argument `off` to inactive without model input, and any other non-empty argument to active plus the trimmed text submitted through `agent.steer()` as the next step's ordinary logged user message; image attachments ride the steered message, and `/plan off` with images fails before any mode change. Entry points other than the command may drive `ctx.planMode` directly; the exact branch handling is in [`src/index.ts`](src/index.ts).
39
90
 
40
- Design: [plan-specific collaboration state](../../../.agents/notes/implemented/simplification/2026-07-22-plan-specific-collaboration-state.md).
91
+ ### The exit tool
41
92
 
93
+ `exit_plan_mode` stays registered while plan mode is inactive, so entering or leaving changes only the prompt section, never the request tool catalog. An approved review records a silent pending exit that the next accepted in-turn pre-step appends, keeping plan guidance for the rest of the current tool batch. Without a user-questions channel, or after a service reload while the review is pending, the call fails closed and `/plan off` remains the manual escape.
94
+
95
+ ### Session projection unit
96
+
97
+ When `ctx.sessionProjections` is composed, the package registers the `plan` unit through optional injection. The unit turns logged `/plan` command runs into a candidate target, commits the logged state on `plan/mode`, and derives `{ active, pending }` for `view`, where `pending` is true only while an unsettled or successful selection differs from the logged state — a pure replay quantity recoverable from the log alone. The key merges into `SessionProjectionMap` from [`src/types.ts`](src/types.ts); the framework drives the unit, and unloading the plugin fiber unregisters the key. Plan-mode reads require this unit and the `turnBoundary` unit, and fail explicitly if the registry or either key is absent.
98
+
99
+ ### Source map
100
+
101
+ | File | Role |
102
+ |---|---|
103
+ | [`src/index.ts`](src/index.ts) | Plugin entry: `Config` schema, the `ctx.planMode` service, `plan:policy` section, `/plan` command, `exit_plan_mode` tool |
104
+ | [`src/types.ts`](src/types.ts) | The `plan` projection-key declaration and `PlanProjection` wire value |
105
+ | [`src/client.ts`](src/client.ts) | Client-namespace re-export of the types outlet |
106
+ | [`src/invariant.ts`](src/invariant.ts) | Invariant companion: validates the `plan/mode` payload shape |
107
+
108
+ </details>
109
+
110
+ -----
111
+
112
+ <a id="further-exploration"></a>
113
+ ## Further Exploration
114
+
115
+ Read these pages when the package-level contract is not enough. They move from the subsystem semantics to the generated catalogs and the design decision.
116
+
117
+ - [Plan mode subsystem reference](../../../docs/subsystems/plan.md) — how plan mode behaves, its configuration, and the exit tool's contract.
118
+ - [plan/ package map](../README.md) — the group and its single package.
119
+ - [exit_plan_mode tool catalog entry](../../../docs/tool-catalog.md#deepseek-aidsh-plan-mode) — the exact schema the model receives.
120
+ - [Generated configuration catalog](../../../docs/config-catalog.md#deepseek-aidsh-plan-mode) — every accepted config field and its meaning.
121
+ - [Plan-specific collaboration state](../../../.agents/notes/implemented/simplification/2026-07-22-plan-specific-collaboration-state.md) — the design decision behind plan mode.
122
+
123
+ -----
124
+
125
+ <a id="model-experience"></a>
42
126
  ## Model Experience
43
127
 
44
128
  ### Plan policy system prompt
45
129
 
46
130
  #### What the model sees
47
131
 
48
- While plan mode is active, the model sees the deployment's exact `section` text at prompt order 50; inactive mode contributes no text.
132
+ While plan mode is active, the model sees the deployment's exact `section` text at first-party prompt order 500; inactive mode contributes no text.
49
133
 
50
134
  ##### Configuration example
51
135
 
@@ -59,7 +143,7 @@ Inactive mode adds no tokens; active mode adds the configured section to every r
59
143
 
60
144
  #### KV Cache effect
61
145
 
62
- The section is stable within plan mode, but entering or leaving changes the system prompt from order 50 onward.
146
+ The section is stable within plan mode, but entering or leaving changes the system prompt from first-party order 500 onward.
63
147
 
64
148
  ### Human command
65
149
 
@@ -91,8 +175,27 @@ Mode transitions do not change the tool catalog; plan arguments and review resul
91
175
 
92
176
  ## Known Limitations and Deferred Work
93
177
 
94
- - Plan mode guides rather than enforces; deployments that need enforced restrictions must configure sandbox and approval controls independently.
95
- - A selection made after the turn's final accepted pre-step is lost if the process exits before another accepted in-turn pre-step, so the UI must reapply it.
96
- - Forked agents inherit logged plan state, while newly spawned agents begin inactive; there is no creation-time plan option.
97
- - A live child owned by another agent cannot open the `exit_plan_mode` review. The failed call tells the child to include the unresolved decision in its final result; durable fork lineage alone does not prevent a session resumed as a runtime root from opening the review.
98
- - Only the Web UI has a specialized `plan-review` renderer; another interaction provider may present the same request through its generic option flow.
178
+ <a id="known-limitations-and-deferred-work"></a>
179
+
180
+
181
+ These limits describe when plan mode does not behave as you might expect or needs extra care. They are current package constraints, not a roadmap.
182
+
183
+ - **Guidance, not enforcement** — plan mode restrains through text only; deployments that need enforced restrictions configure sandbox mode and approval policy independently.
184
+ - **Pending selections are process-local** — a selection made after the turn's final accepted pre-step is lost if the process exits before another accepted in-turn pre-step; the UI must reapply it.
185
+ - **No creation-time plan option** — forked agents inherit logged plan state, while newly spawned agents begin inactive.
186
+ - **Live children cannot open the review** — a child owned by another live agent fails the `exit_plan_mode` call and is told to include the unresolved decision in its final result; durable fork lineage alone does not prevent a session resumed as a runtime root from opening the review.
187
+ - **One specialized review renderer** — only the Web UI has a `plan-review` presentation; another interaction provider presents the same request through its generic option flow.
188
+
189
+ <a id="dev-note"></a>
190
+ ### Dev Note
191
+
192
+ <details>
193
+ <summary>Working context for maintainers — click to expand</summary>
194
+
195
+ This Dev Note is working context for maintainers: open design 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 Note.
196
+
197
+ #### Future: a second collaboration mode
198
+
199
+ The design note rejected a generic named-mode registry because the product shipped only `plan`; a future collaboration state would establish a shared seam only from two concrete cases, and any extraction must keep `plan/mode`'s log-only fold, the boundary append, and the reviewed exit intact.
200
+
201
+ </details>
package/README.zh.md CHANGED
@@ -1,53 +1,135 @@
1
+ ---
2
+ description: "面向用户与维护者的计划模式说明:用于选择、配置或排查带部署引导、/plan 命令与经用户评审退出的逐 agent 规划功能。"
3
+ kind: "package-reference"
4
+ ---
5
+
1
6
  # @deepseek-ai/dsh-plan-mode
2
7
 
3
8
  [English](README.md) | 中文
4
9
 
5
- 按 agent(智能体)分别记录到日志的 plan 协作状态,提供由部署方配置的引导内容、用于直接进入的 `/plan [message]` 命令、用于直接退出的 `/plan off` 命令,以及经用户评审的 `exit_plan_mode` 退出方式。Plan mode 是软引导;沙箱模式和批准策略各自强制执行限制,且不读写 plan 状态。
6
-
7
- ## 持久状态
8
-
9
- `plan/mode`(`{ active: boolean }`)是一个仅存在于日志中、每次以完整值替换的 `SessionEventMap` 成员。`foldPlanMode(events)` 返回最后记录的值,如果没有则返回 `false`,因此恢复、fork 和压缩(compaction)都能直接从会话日志恢复 plan 状态。UI 通过 `session/event` 观察已提交的切换。
10
+ ## 概述
10
11
 
11
- `ctx.planMode.set(agent, active)` 会在 agent 空闲时立即追加独立的 `plan/mode` 事件,因为下一个提示词之前不会运行轮内 pre-step。agent 运行时,该方法会保留待生效选择,直到下一个被接受的轮内 pre-step。返回值区分 `committed`、`queued`、表示反转的 `cancelled` 和 `noop`。`get(agent)` 返回 `{ active, pending? }`,将用于组装当前步骤的日志状态与用户的轮中选择分开。初始与续步 pre-step 都会应用待生效选择;同一步骤的请求恢复重试会复用已冻结的 assembly,并将该选择保留到下一个被接受的轮内 pre-step。当最后记录的请求头描述了另一状态时,用户选择的变更会贡献一条插件来源的 `user/message` 通知(两条提交路径皆然)。
12
+ `dsh-plan-mode` 为 agent(智能体)提供计划模式:激活期间,agent 先探索和设计再执行,遵循你的部署所写的引导行事,并在执行前把完成的计划呈交你批准。你可以用 `/plan`(可附带消息或图片)进入计划模式,用 `/plan off` 离开;完成的计划会以评审形式呈现,你可以批准它,或让 agent 回去继续规划。计划模式是引导而非强制:每个工具仍然可用,因此沙箱模式与审批提示仍是施加限制的方式。当希望 agent 先思考再行动时选择它;会话恢复或 fork 后计划模式依然保持。
12
13
 
13
- <a id="model-and-human-interactions"></a>
14
+ ## 目录
14
15
 
15
- ## 模型与人类交互
16
+ - [使用本包](#use-this-package)
17
+ - [理解实现](#understand-the-implementation)
18
+ - [进一步探索](#further-exploration)
19
+ - [模型体验](#model-experience)
20
+ - [已知限制与延期工作](#known-limitations-and-deferred-work)
21
+ - [开发备注](#dev-note)
16
22
 
17
- 激活时,`plan:policy` 会渲染已配置的 `section`。插件始终注册 `exit_plan_mode`,使工具 schema 在转换期间保持稳定;其 execute 路径只接受已激活的 plan mode,且只有通过 `ctx.userQuestions` 获得用户明确批准后才退出。
23
+ -----
18
24
 
19
- 评审问题声明 `plan-review` 呈现意图,并指名 `Approve` 为表示批准的标签,因此有能力的 UI 会把计划呈现为一次决定而非通用问题;两种情况下该工具读到的回答完全相同。放弃审阅——用户关闭请求,转而发言——会如实报告给模型,要求它留在 plan mode 中等待那条消息;其余每一种评审失败都保留 seam 自身的消息。
25
+ <a id="use-this-package"></a>
26
+ ## 使用本包
20
27
 
21
- 组合 `ctx.commands` 时,该包会注册 `/plan [message]`,并将参数恰好为 `off` 的情况保留给直接退出。不带参数的 `/plan` 会启用 plan mode;任何其他非空参数都会先启用 plan mode,再通过 `agent.steer()` 提交,因此它会在 plan 引导下成为下一步骤的常规已记录用户消息。`/plan off` 会选择停用状态,不发送模型输入;它还可以在启用 plan mode 的待处理选择由轮内 pre-step 追加之前将其取消。该命令声明了 `input.images`:composer 图片附件会随被 steer 的消息一起提交,位于文本块之前。不带参数的 `/plan` 若附有图片,会 steer 一条只含图片的用户消息;`/plan off` 若附有图片,会在任何模式变更前直接返回错误,composer 保留图片。
28
+ 计划模式激活时,agent 会按你的指令行事,并先呈交计划供评审,而不是立即执行。常用路径:配置引导文本,用 `/plan` 进入计划模式,agent 调用 `exit_plan_mode` 时评审完成的计划。
22
29
 
23
- Web 客户端使用该插件提供的 `/plan` 命令;其他入口可以直接驱动同一服务,无需定义第二套 mode 词汇。
30
+ ### 何时选择
24
31
 
25
- ## 会话投影
32
+ 当希望 agent 先探索和设计再执行、并且想先批准计划时,选择计划模式。它不限制 agent:每个工具仍可调用,因此需要强制限制时请使用沙箱模式与审批提示。当 agent 应立即按你的请求行事、无需规划阶段时,跳过它。
26
33
 
27
- 当组合挂载 `ctx.sessionProjections`([`@deepseek-ai/dsh-session-projection`](../../session/session-projection/README.zh.md))时,本包会在一个注入的子插件中注册 `plan` 投影单元。名为 `plan` 且携带已记录 `args` 的 `command/run` 记录会开始一个候选目标(`off` → 未激活,其余 → 激活);与它配对的 `command/done` 保留成功选择并丢弃错误选择;`plan/mode` 提交已记录状态并清除已保留的选择。其他任何事件都返回同一个状态引用。`view` 推导 `{ active, pending }`,其中 `pending` 仅在未结算或已成功的选择与已记录状态不同时为 true。该值仍完全由日志回放得出,因此 host 重启、其他标签页和冷读都能仅凭日志恢复它,被拒绝的带图 `/plan off` 也不会留下待退出状态。key 由 `src/types.ts` 通过声明合并加入 `SessionProjectionMap`:host 消费方经 `./types` 获取,client 聚合经 `./client` 获取。框架负责驱动该单元,载体通过历史尾页和 `session/projection` 推送帧提供其值。未挂载注册表的组合不受影响。
34
+ ### 最小配置
28
35
 
29
- ## 配置
36
+ 唯一必需的配置是 agent 规划期间遵循的引导文本;添加任何其他内容都会在加载时失败。
30
37
 
31
38
  ```yaml
32
- - id: plan-mode
33
- name: '@deepseek-ai/dsh-plan-mode'
39
+ - name: '@deepseek-ai/dsh-plan-mode'
34
40
  config:
35
41
  section: |
36
42
  You are in plan mode. Explore and design before presenting the complete
37
43
  plan through exit_plan_mode.
38
44
  ```
39
45
 
40
- `section` 必填且非空。出现未知键时,插件会加载失败。该包不接受任意命名的 mode、工具过滤器、沙箱设置或批准策略。
46
+ | 字段 | 默认值 | 含义 |
47
+ |---|---|---|
48
+ | `section` | 必填 | 计划模式激活时作为 `plan:policy` 提示词段落渲染的引导 |
49
+
50
+ 生成的[配置目录](../../../docs/config-catalog.zh.md#deepseek-aidsh-plan-mode)是每个受支持字段及其 JSDoc 的穷尽式真源。
51
+
52
+ <a id="model-and-human-interactions"></a>
53
+ ### 进入与离开计划模式
54
+
55
+ 输入 `/plan` 进入计划模式,或输入 `/plan <message>` 连同一条指令一起进入——该消息会成为你在计划引导下的下一条请求。输入 `/plan off` 直接离开计划模式;它还会取消尚未生效的计划模式进入。
56
+
57
+ 你可以在 `/plan` 消息中附带图片,图片会随你的指令一起提交。带图片的 `/plan off` 会被拒绝,因此图片不会丢失。`/plan` 命令在支持斜杠命令的界面中可用,例如 Web 客户端。
58
+
59
+ ### 经评审的退出
60
+
61
+ agent 完成计划后,会以 markdown 形式、从标题开头书写计划并调用 `exit_plan_mode`。你评审该计划的原文,选择 `Approve` 离开计划模式,或选择 `Keep planning` 带反馈把 agent 送回去。
62
+
63
+ 选择 `Keep planning`(可附自由文本反馈)会让 agent 回去修订计划;关闭评审改为发言,则告知 agent 等待你的下一条消息。若没有可用的交互评审,`exit_plan_mode` 无法运行,你仍可用 `/plan off` 离开计划模式。
64
+
65
+ ### 观察计划状态
66
+
67
+ 界面可以显示计划模式是否激活,以及你请求的模式变更是否仍在等待生效。该状态在每个标签页中一致,并能在重启后保留。
68
+
69
+ -----
70
+
71
+ <a id="understand-the-implementation"></a>
72
+ ## 理解实现
73
+
74
+ <details>
75
+ <summary>实现细节——点击展开</summary>
76
+
77
+ 本节解释本包背后的设计决策并指出实现它们的代码位置;可观察行为已在[使用本包](#use-this-package)中完整说明。
78
+
79
+ ### 设计理念
80
+
81
+ 计划模式是产品包,而不是能力 seam:没有可替换的后端,因此状态、引导、命令与退出工具都集中在一处。持久姿态是单一仅记日志、整值替换的事件,绝不是实时镜像,因此恢复、fork 与压缩(compaction)都通过折叠日志复原它。引导是软性层——本包注册一个提示词段落和一个工具,通过文本而非过滤能力来约束。
82
+
83
+ ### 持久状态与步骤边界追加
84
+
85
+ 本包持久化一条仅记日志、整值替换的事件 `plan/mode`,最后一条已记录值即为状态。没有轮次开启时,模式变更会立即追加;轮次开启期间,它保持待生效,直到下一个被接受的轮内 pre-step——agent 运行时唯一的追加点——且追加失败不能阻塞轮次。`set`/`get` 服务方法及其确切返回状态见 [`src/index.ts`](src/index.ts),并读取已注册的 `plan` 投影;注册表或 key 缺失时,第一次依赖它们的访问会显式失败。
41
86
 
42
- 设计:[plan 专用协作状态](../../../.agents/notes/implemented/simplification/2026-07-22-plan-specific-collaboration-state.zh.md)。
87
+ ### `/plan` 命令
43
88
 
89
+ 命令子插件只在组合了命令服务时激活。它把不带参数的 `/plan` 映射为激活,把恰好为 `off` 的参数映射为未激活且不发送模型输入,把其他非空参数映射为激活并把去除首尾空白的文本通过 `agent.steer()` 作为下一步骤的普通已记录用户消息提交;图片附件随被 steer 的消息一起提交,带图片的 `/plan off` 会在任何模式变更前失败。命令以外的入口可以直接驱动 `ctx.planMode`;确切的分支处理见 [`src/index.ts`](src/index.ts)。
90
+
91
+ ### 退出工具
92
+
93
+ `exit_plan_mode` 在计划模式未激活时仍保持注册,因此进入或离开只改变提示词段落,绝不改变请求的工具目录。经批准的评审会记录一个静默的待生效退出,由下一个被接受的轮内 pre-step 追加,当前这批工具调用剩余部分仍保留计划引导。缺少用户交互通道,或评审等待期间服务重载,调用都会失败关闭,`/plan off` 仍是手动退路。
94
+
95
+ ### 会话投影单元
96
+
97
+ 组合了 `ctx.sessionProjections` 时,本包通过可选注入注册 `plan` 单元。该单元把已记录的 `/plan` 命令运行转为候选目标,在 `plan/mode` 上提交已记录状态,并为 `view` 推导 `{ active, pending }`,其中 `pending` 仅在未结算或已成功的选择与已记录状态不同时为 true——这是仅凭日志即可恢复的纯回放量。key 由 [`src/types.ts`](src/types.ts) 的声明合并加入 `SessionProjectionMap`;框架负责驱动该单元,卸载插件 fiber 会注销该 key。plan-mode 读取要求该单元与 `turnBoundary` 单元存在;注册表或任一 key 缺失时都会显式失败。
98
+
99
+ ### 源码地图
100
+
101
+ | 文件 | 职责 |
102
+ |---|---|
103
+ | [`src/index.ts`](src/index.ts) | 插件入口:`Config` schema、`ctx.planMode` 服务、`plan:policy` 段落、`/plan` 命令、`exit_plan_mode` 工具 |
104
+ | [`src/types.ts`](src/types.ts) | `plan` 投影 key 声明与 `PlanProjection` 协议值 |
105
+ | [`src/client.ts`](src/client.ts) | types 出口的客户端命名空间再导出 |
106
+ | [`src/invariant.ts`](src/invariant.ts) | 不变式伴生插件:校验 `plan/mode` 载荷结构 |
107
+
108
+ </details>
109
+
110
+ -----
111
+
112
+ <a id="further-exploration"></a>
113
+ ## 进一步探索
114
+
115
+ 当包级约定不够用时阅读以下页面。它们从子系统语义逐步进入生成的目录与设计决策。
116
+
117
+ - [计划模式子系统参考](../../../docs/subsystems/plan.zh.md)——计划模式的行为、配置与退出工具的约定。
118
+ - [plan/ 包映射](../README.zh.md)——本组及其唯一的包。
119
+ - [`exit_plan_mode` 工具目录条目](../../../docs/tool-catalog.zh.md#deepseek-aidsh-plan-mode)——模型收到的确切 schema。
120
+ - [生成的配置目录](../../../docs/config-catalog.zh.md#deepseek-aidsh-plan-mode)——每个受支持配置字段及其含义。
121
+ - [plan 专用协作状态](../../../.agents/notes/implemented/simplification/2026-07-22-plan-specific-collaboration-state.zh.md)——计划模式背后的设计决策。
122
+
123
+ -----
124
+
125
+ <a id="model-experience"></a>
44
126
  ## 模型体验
45
127
 
46
128
  ### Plan 策略系统提示词
47
129
 
48
- #### 模型所见内容
130
+ #### 模型看到什么
49
131
 
50
- Plan mode 激活时,模型会在提示词顺序 50 处看到部署方提供的原样 `section` 文本;未激活 mode 不贡献文本。
132
+ 计划模式激活时,模型会在 first-party 提示词顺序 500 处看到部署方提供的原样 `section` 文本;未激活模式不贡献任何文本。
51
133
 
52
134
  ##### 配置示例
53
135
 
@@ -57,46 +139,63 @@ You are in plan mode. Explore and design before presenting the complete plan thr
57
139
 
58
140
  #### Token 影响
59
141
 
60
- 未激活 mode 不增加 token;mode 激活时,每个请求都会加入已配置的段落。
142
+ 未激活模式不增加 token;激活模式把已配置的段落加入每个请求。
61
143
 
62
144
  #### KV Cache 影响
63
145
 
64
- 该段在 plan mode 内稳定,但进入或退出会从顺序 50 开始改变系统提示词。
146
+ 该段落在计划模式内保持稳定,但进入或离开会从 first-party 顺序 500 起改变系统提示词。
65
147
 
66
148
  ### 人类命令
67
149
 
68
- #### 模型所见内容
150
+ #### 模型看到什么
69
151
 
70
- `/plan`、`/plan off` 及其终端结果留在模型历史之外。除恰好为 `off` 以外的非空后缀会在选择 plan mode 后,通过 `agent.steer()` 成为一条用户消息:任何已准入的图片附件作为前置图片块,之后是已去除首尾空白的文本块。不带参数的 `/plan` 若带有已准入图片,会 steer 一条只含这些图片块的用户消息。plan mode 已激活时,选择 `/plan off` 只会在最后一个请求头描述了 plan mode 的情况下追加标准的已记录用户切换通知;取消待生效进入不会贡献通知,因为没有请求观测到它。
152
+ `/plan`、`/plan off` 及其终端结果留在模型历史之外。除恰好为 `off` 以外的非空后缀会在选择计划模式后,通过 `agent.steer()` 成为一条用户消息:任何已准入的图片附件作为前置图片块,之后是去除首尾空白的文本块。不带参数的 `/plan` 若带有已准入图片,会 steer 一条只含这些图片块的用户消息。计划模式已激活时选择 `/plan off`,只会在最后记录的请求头描述了计划模式的情况下追加标准的已记录用户切换通知;取消待生效条目不贡献通知,因为没有请求观测到它。
71
153
 
72
154
  #### Token 影响
73
155
 
74
- 可选消息的历史 token 成本与单独提交该内容相同。不带图片和参数的 `/plan` 与 `/plan off` 不增加 token;不带参数但带图的 `/plan` 产生常规图片提示词成本。一次带有切换通知的已激活状态退出会追加一条简短且会保留的通知。
156
+ 可选消息的历史 token 成本与单独提交该内容相同。不带图片的 `/plan` 与 `/plan off` 不增加 token;带图片的 `/plan` 产生常规图片提示词成本。一次带叙述的激活状态退出会追加一条简短且会保留的切换通知。
75
157
 
76
158
  #### KV Cache 影响
77
159
 
78
- 用户块是仅追加的对话增长。进入或退出 plan mode 会改变更早的策略段;退出转换的记录通知会追加在可复用请求前缀之后。
160
+ 用户块是仅追加的对话增长。进入或离开计划模式会改变更早的策略段落;带叙述的退出通知追加在可复用请求前缀之后。
79
161
 
80
162
  ### 退出工具 schema 与评审交互
81
163
 
82
- #### 模型所见内容
164
+ #### 模型看到什么
83
165
 
84
- [`exit_plan_mode` schema](../../../docs/tool-catalog.zh.md#deepseek-aidsh-plan-mode) 在两种状态下均可用;在 plan mode 外执行会失败,而 plan mode 内经批准的评审会返回规范的 `{ approved: true }` 值,并渲染既有的确认文本。拒绝仍是携带评审反馈的失败调用,放弃审阅则是一次指明用户接手的失败调用。
166
+ [`exit_plan_mode` schema](../../../docs/tool-catalog.zh.md#deepseek-aidsh-plan-mode) 在两种状态下均可用;在计划模式之外执行会失败,而计划模式内经批准的评审返回规范的 `{ approved: true }` 值,并渲染既有的确认文本。拒绝仍是携带评审反馈的失败调用,放弃评审则是一次指明用户接手的失败调用。
85
167
 
86
168
  #### Token 影响
87
169
 
88
- 稳定 schema 的成本取决于 ToolRuntime mode,每次传入的 plan 参数和评审结果都会保留在对话历史中。
170
+ 稳定 schema 的成本取决于 ToolRuntime mode,每次传入的 plan 参数与评审结果都会保留在对话历史中。
89
171
 
90
172
  #### KV Cache 影响
91
173
 
92
- mode 转换不改变工具目录;plan 参数与评审结果按常规方式扩展对话。
174
+ 模式转换不改变工具目录;plan 参数与评审结果按常规方式扩展对话。
175
+
176
+ ## 已知限制与延期工作
93
177
 
94
178
  <a id="known-limitations-and-deferred-work"></a>
95
179
 
96
- ## 已知限制与暂缓事项
97
180
 
98
- - Plan mode 只进行引导,而不强制执行;需要强制限制的部署必须分别配置沙箱与批准控制。
99
- - 如果进程在另一个被接受的轮内 pre-step 之前退出,某轮最后一个被接受的 pre-step 之后作出的选择会丢失,因此 UI 必须重新应用它。
100
- - Fork 的 agent 会继承已记录的 plan 状态,新 spawn 的 agent 则从未激活状态开始;不存在创建时 plan 选项。
101
- - 由另一个 agent 所有的存活子级无法打开 `exit_plan_mode` 审阅。该调用失败时会提示子级在最终结果中包含尚未解决的决策;仅有持久化 fork 谱系并不会阻止恢复为运行时根的会话打开该审阅。
102
- - 只有 Web UI 具备专用的 `plan-review` 渲染器;其他交互提供方可以通过通用选项流程呈现同一请求。
181
+ 这些限制描述计划模式在哪些情况下不符合你的预期,或需要额外的注意。它们是当前包约束,不是路线图。
182
+
183
+ - **引导而非强制**——计划模式只通过文本约束;需要强制限制的部署要分别配置沙箱模式与审批策略。
184
+ - **待生效选择只存在于进程内**——某轮最后一个被接受的 pre-step 之后作出的选择,若进程在另一个被接受的轮内 pre-step 之前退出就会丢失;UI 必须重新应用它。
185
+ - **没有创建时 plan 选项**——fork 的 agent 继承已记录的计划状态,新 spawn 的 agent 则从未激活开始。
186
+ - **存活的子级无法打开评审**——由另一个存活 agent 所有的子级调用 `exit_plan_mode` 会失败,并被要求把尚未解决的决策包含进最终结果;仅有持久化 fork 谱系并不能阻止恢复为运行时根的会话打开该评审。
187
+ - **只有一个专用评审渲染器**——只有 Web UI 具备 `plan-review` 呈现;其他交互提供方通过其通用选项流程呈现同一请求。
188
+
189
+ <a id="dev-note"></a>
190
+ ### 开发备注
191
+
192
+ <details>
193
+ <summary>维护者的工作上下文——点击展开</summary>
194
+
195
+ 本开发备注是维护者的工作上下文:开放的设计问题与尚未决定的探索方向。它明确不具权威性——已交付的行为、限制与既定理由以上文、包代码和相关 Agent Note 为准。
196
+
197
+ #### 未来:第二种协作模式
198
+
199
+ 设计说明拒绝了通用命名模式注册表,因为产品只交付了 `plan`;未来的协作状态只应在出现两个具体用例后建立共享 seam,任何抽取都必须保持 `plan/mode` 的仅记日志折叠、边界追加与经评审的退出不变。
200
+
201
+ </details>