Skip to content

功能规格说明:支持计划模式 ​

创建日期:2026-01-19

用户场景与测试 (必填) ​

用户故事:切换到计划模式(优先级:P1) ​

作为用户,我希望将系统切换到"计划模式",以便我可以让 LLM 分析代码库并提出计划,而不会意外修改任何文件。

为什么是这个优先级:这是功能的核心,允许用户安全地探索和规划复杂更改。

独立测试:可以通过按 Shift+Tab 并验证系统进入计划模式且新计划文件被创建来测试。

验收场景:

  1. 假设系统处于 "default" 模式,当用户按下 Shift+Tab 时,则系统切换到 "acceptEdits" 模式。
  2. 假设系统处于 "acceptEdits" 模式,当用户按下 Shift+Tab 时,则系统切换到 "plan" 模式。
  3. 假设系统处于 "plan" 模式,当用户按下 Shift+Tab 时,则系统切换到 "bypassPermissions" 模式。
  4. 假设系统处于 "bypassPermissions" 模式,当用户按下 Shift+Tab 时,则系统切换回 "default" 模式(完整循环为 default → acceptEdits → plan → bypassPermissions → default,与 CLI 循环及 GUI 模式菜单的选项顺序一致)。
  5. 假设系统切换到 "plan" 模式,当模式活动时,则在 ~/.wave/plans/ 中确定带有随机英文名称的计划文件路径。
  6. 假设系统处于 "plan" 模式,当 LLM 在指定计划文件上使用 Write 或 Edit 工具时,则操作被允许。
  7. 假设系统处于 "plan" 模式,当用户查看 UI 时,则有清晰的视觉指示器表明计划模式已激活。

用户故事:计划模式中的规划和限制(优先级:P1) ​

作为用户,我希望 LLM 在计划模式下只能编辑计划文件,以便我的代码库在规划阶段保持不变。该限制只对未获得会话级绕过授权的会话生效;启动时已处于 bypassPermissions 的会话在 plan 模式下不经过权限层(见「计划模式继承会话的绕过授权」)。

为什么是这个优先级:这确保规划过程中代码库的安全性和完整性。

独立测试:在未获得绕过授权的会话中进入计划模式,尝试编辑非计划文件并验证它被阻止。

验收场景:

  1. 假设系统处于 "plan" 模式且该会话未获得绕过授权,当 LLM 尝试读取文件时,则操作被允许。
  2. 假设系统处于 "plan" 模式且该会话未获得绕过授权,当 LLM 尝试编辑指定计划文件以外的文件时,则操作被阻止。
  3. 假设系统处于 "plan" 模式且该会话未获得绕过授权,当 LLM 尝试执行 bash 命令时,则该命令不被 plan 模式拒绝,而是走常规权限流程(命中 allow 规则或安全区自动放行则静默执行,否则弹出确认)。
  4. 假设系统处于 "plan" 模式,当 LLM 编辑计划文件时,则操作被允许(与该会话是否获得绕过授权无关)。

用户故事:计划模式继承会话的绕过授权(优先级:P1) ​

作为启动时已授权绕过权限的用户(permissions.defaultMode: "bypassPermissions",或 CLI --dangerously-skip-permissions / --permission-mode bypassPermissions),我希望切到计划模式做探索时不再被逐条权限确认打断,以便计划模式的行为与我在该会话中已授权的"不要问我"一致(对齐 Claude Code 的 isBypassPermissionsModeAvailable:plan 模式下该位为真时权限检查直接放行)。

为什么是这个优先级:用户已在会话级明确授权,plan 模式不应把它变成"恢复逐条询问";实测中 plan 模式下的 bash 调用有 69/76 次弹窗,其中 50 次是只读命令仅因路径落在安全区之外被拦。

独立测试:以 permissions.defaultMode: "bypassPermissions" 启动会话,切到计划模式并让模型执行一条未命中任何 allow 规则、且不在安全区内的 bash 命令,验证不出现确认提示;再以 defaultMode: "default" 启动同样会话,验证出现确认提示。

验收场景:

  1. 假设会话创建时解析出的有效权限模式为 bypassPermissions(来自 permissions.defaultMode 或 CLI 指定),当该会话创建时,则获得"绕过授权",且该状态在会话生命周期内保持不变。
  2. 假设会话创建时解析出的有效权限模式不是 bypassPermissions(如 default/acceptEdits/plan/dontAsk),当该会话创建时,则不具有绕过授权;之后用户通过 Shift+Tab 或模式菜单切到 bypassPermissions 也不会获得(授权只在创建时定格)。
  3. 假设会话具有绕过授权且系统处于 "plan" 模式,当 LLM 执行一条未命中任何 allow 规则、且不在安全区内的 Bash 命令时,则不出现确认提示。
  4. 假设会话具有绕过授权且系统处于 "plan" 模式,当 LLM 尝试 Edit 或 Write 计划文件以外的文件时,则不出现确认提示(该会话不再受「只能编辑计划文件」限制)。
  5. 假设会话不具有绕过授权且系统处于 "plan" 模式,当 LLM 执行未命中 allow 规则的 Bash 命令或编辑计划文件以外的文件时,则行为与现状一致(bash 弹确认、非计划文件编辑被阻止)。
  6. 假设会话具有绕过授权且系统处于 "plan" 模式,当 LLM 调用的工具命中 permissions.deny 或实例 deny 规则时,则仍然被拒绝(deny 优先于绕过授权,对齐 Claude Code 的判定步骤顺序)。
  7. 假设会话具有绕过授权、系统处于 "plan" 模式且会话位于某 worktree 内,当 LLM 尝试修改主仓库(worktree 之外)的文件时,则仍被拒绝,绕过授权不豁免 worktree 越界保护。
  8. 假设会话具有绕过授权且系统处于 "plan" 模式,当 LLM 调用 AskUserQuestion 时,则仍然向用户提问(该工具需要用户交互,任何模式下都不被绕过)。
  9. 假设会话具有绕过授权,当系统处于 default/acceptEdits/dontAsk 模式时,则行为与现状一致:绕过授权只改变 "plan" 模式的判定,不改变其他模式。
  10. 假设具有绕过授权的会话处于 "plan" 模式,当它派生子 agent 时,则子 agent 继承该会话的绕过授权(子 agent 的权限模式取自父会话的当前模式,若在子 agent 创建时重新推导会得到错误结果)。
  11. 假设会话具有绕过授权且系统处于 "plan" 模式,当 LLM 调用 ExitPlanMode 时,则仍然向用户请求计划批准(展示计划内容与确认选项),用户批准后才退出计划模式;绕过授权不豁免该确认(该工具需要用户交互,与 AskUserQuestion 同属对齐 Claude Code requiresUserInteraction 的例外,也是此类会话中计划模式仅剩的约束之一)。

用户故事:系统提示引导(优先级:P2) ​

作为用户,我希望 LLM 被明确告知在计划模式下如何行为,以便它有效地使用计划文件。

为什么是这个优先级:确保 LLM 理解其约束和预期工作流。

独立测试:可以通过检查计划模式活动时发送给 LLM 的系统提示来测试。

验收场景:

  1. 假设系统处于 "plan" 模式,当消息发送到主 agent 时,则提醒包含计划文件信息并指示 agent 通过写入或编辑计划文件来增量构建计划。
  2. 假设系统处于 "plan" 模式,当消息发送到子 agent 时,则提醒告诉子 agent 以文本输出形式返回发现,并且不指示它写入或编辑计划文件(因为子 agent 缺少 Write/Edit 工具)。

用户故事:通过 ExitPlanMode 批准计划(优先级:P1) ​

作为计划模式中的 agent,我希望在完成将计划写入指定计划文件后使用 ExitPlanMode 工具,以便用户可以审查该文件中的计划内容并提供批准或反馈。

为什么是这个优先级:这是请求的核心功能。它基于实际计划文件内容,在用户监督下实现从规划到执行的过渡。

独立测试:可以通过将 agent 置于计划模式、将计划写入文件、调用 ExitPlanMode 并验证用户看到计划文件内容并被提示确认来测试。

验收场景:

  1. 假设 agent 处于计划模式并已写入计划到指定文件,当 agent 调用 ExitPlanMode 时,则用户看到计划文件的内容,并通过标准 canUseTool 机制被提示确认,提供三个选项(可通过方向键导航)。
  2. 假设用户正在审查文件中的计划,当用户选择 "Default" 时,则工具成功,agent 退出计划模式进入默认执行状态。
  3. 假设用户正在审查文件中的计划,当用户选择 "Accept Edits" 时,则工具成功,agent 退出计划模式进入后续编辑自动接受的状态。
  4. 假设用户正在审查文件中的计划,当用户选择 "Tell agent what to do" 时,则用户提供反馈,工具将此反馈返回给 agent,agent 保持在计划模式中以优化计划。

用户故事:计划内容在编辑器区域预览(三端统一,优先级:P2) ​

作为 Wave 用户,我希望 ExitPlanMode 的完整计划内容显示在编辑器区域(而非确认对话框内部),以便我在查看确认对话框的同时并排对照计划与代码,确认对话框本身保持简洁(对齐 CC 的 claudeVSCodePanel + claudePlanPreview 相邻两列)。

为什么是这个优先级:计划内容是批准流程的核心信息。三端将计划移出对话框、放入编辑器区域的承载位(JB 独立计划标签页 / VSCE createWebviewPanel 计划预览面板 / 桌面端 Plan 面板)后,用户可在对话框确认的同时对照代码审查计划,对话框更紧凑友好。共享 webview 统一移除对话框内联的计划全文渲染,各端自行承载计划内容。

独立测试:在任一前端触发 ExitPlanMode 权限确认,验证计划内容渲染在编辑器区域的承载位(markdown),且确认对话框不再显示计划全文。

验收场景:

  1. 假设任一前端中 agent 调用 ExitPlanMode 触发权限确认,当确认对话框显示时,则对话框内不显示计划全文,仅保留确认选项,对话框更小、更友好(三端统一,共享 webview 不再内联渲染 planContent)。
  2. 假设 JetBrains 插件中 ExitPlanMode 确认触发,当确认对话框显示时,则完整计划内容以 markdown 渲染在独立的计划标签页中(编辑器区域标签页,对齐 VS Code 的 createWebviewPanel 计划预览面板),聊天界面保持侧边栏位置不变。
  3. 假设 JetBrains 插件同一会话中 agent 再次调用 ExitPlanMode(计划更新后重新请求确认),当新的确认请求到达时,则复用该会话已有的计划标签页:内容更新为最新计划,而非新建标签页。
  4. 假设计划标签页已显示(JB),当用户在确认对话框中选择批准或拒绝时,则计划标签页保留,由用户手动关闭。
  5. 假设 VS Code 扩展中 ExitPlanMode 确认触发,当确认对话框显示时,则完整计划内容以 markdown 渲染在聊天 webview 面板相邻的计划预览面板中(createWebviewPanel,对齐 CC 的 claudePlanPreview)。
  6. 假设 VS Code 扩展同一会话中 agent 再次调用 ExitPlanMode,当新的确认请求到达时,则复用已有的计划预览面板:内容更新为最新计划,而非新建面板。
  7. 假设 VS Code 扩展计划预览面板已显示,当用户在确认对话框中选择批准或拒绝时,则预览面板保留,由用户手动关闭。
  8. 假设桌面应用中 ExitPlanMode 确认触发,当确认对话框显示时,则完整计划内容以 markdown 渲染在新增的 Plan 面板中(现有面板系统新增 plan 面板类型),面板自动打开。
  9. 假设桌面应用同一会话中 agent 再次调用 ExitPlanMode,当新的确认请求到达时,则复用已有的 Plan 面板:内容更新为最新计划。
  10. 假设桌面应用 Plan 面板已显示,当用户在确认对话框中选择批准或拒绝时,则 Plan 面板保留(内容不自动清空),由用户手动关闭。
  11. 假设多个会话并行,当各会话分别触发 ExitPlanMode 时,则每个会话拥有独立的计划承载位,互不覆盖。
  12. 假设非 ExitPlanMode 工具(如 Bash)触发权限确认,当确认对话框显示时,则行为与现状一致,不受计划承载改动影响。

用户故事:聊天会话在侧边栏工具窗口(JB 端,优先级:P2) ​

作为 JetBrains IDE 中的用户,我希望 Wave 聊天会话渲染在侧边栏工具窗口(而非编辑器区域标签页),以便聊天界面固定可见、不占用代码编辑区,与代码标签页清晰分离(对齐 VS Code 扩展的侧边栏 webview 面板形态;仅 ExitPlanMode 的计划内容在独立标签页预览)。

为什么是这个优先级:聊天主界面在侧边栏是跨端一致的形态(VS Code 面板 / 桌面分屏 / JB 工具窗口);编辑器区域仅用于承载计划预览(见「计划内容在编辑器区域预览」用户故事),聊天不随之挪动。

独立测试:在 JB IDE 中打开 Wave 聊天,验证其出现在侧边栏工具窗口;新建多个会话,验证每个会话独立、可切换。

验收场景:

  1. 假设用户触发打开 Wave(Tools 菜单 / 编辑器右键 "New Wave Chat"),当操作执行时,则聊天会话在侧边栏工具窗口打开(而非编辑器区域标签页)。
  2. 假设聊天会话已打开,当用户发送第一条消息后,则会话标题更新为该消息摘要(首个用户消息,30 字截断)。
  3. 假设多个聊天会话已打开,当用户切换会话时,则"Add to Wave" 等 IDE 动作作用于当前选中的会话。
  4. 假设聊天会话已打开,当用户关闭该工具窗口时,则会话被销毁(agent 终止、stdio 资源释放),不影响其他会话。
  5. 假设聊天会话已关闭,当用户再次打开 Wave 时,则打开一个新的聊天会话。
  6. 假设聊天会话已打开,当用户在 webview 内按 Ctrl/Cmd+R(刷新)时,则快捷操作转发到 webview(现有行为保持),IDE 的 Refresh 动作不被误触发。
  7. 假设聊天会话在侧边栏打开且 ExitPlanMode 确认触发,当确认对话框显示时,则聊天界面保持侧边栏位置不变,计划内容在独立编辑器标签页渲染(见「计划内容在编辑器区域预览」验收场景 2)。

边界情况 ​

  • 目录创建:如果 ~/.wave/plans 不存在,系统应该自动创建。
  • 名称冲突:随机英文名称生成器应该最小化冲突的可能性,但如果文件已存在,应该处理(如生成新名称)。
  • 会话持久化:如果会话重启或消息被压缩,系统必须重用现有的计划文件路径。这通过使用 rootSessionId(链中第一个会话的 ID)作为确定性名称生成的种子来实现。
  • ExitPlanMode 在计划模式外被调用怎么办? ExitPlanMode 工具始终在工具列表中可见。当 agent 不在计划模式时,工具通过运行时守卫返回错误信息。
  • 系统如何处理多次调用 ExitPlanMode? 如果已在退出中或第一次调用待处理,后续调用应该被优雅地处理(如忽略或返回为待处理)。
  • 获得绕过授权的会话里,plan 的约束由谁执行? 权限层不再拦截(Bash 与 Edit/Write 都不弹窗),约束只剩两处:注入的系统提示词要求模型只规划、不改代码;以及 ExitPlanMode 需要用户批准才离开计划模式。这是该设计的已知代价,与 Claude Code 在 isBypassPermissionsModeAvailable 为真时的行为一致。
  • 绕过授权与 dontAsk 的优先级:绕过授权只作用于 "plan" 模式的判定,不改变 dontAsk 的自动拒绝行为。
  • 计划承载位刷新的驱动范围:承载位刷新只由 agent 的 Write/Edit 工具调用命中计划文件时触发(不引入文件系统监听);用户直接编辑 ~/.wave/plans/ 下的计划文件、或 agent 退出计划模式后的改动都不刷新承载位。
  • 计划文件被写空:agent 把计划文件写为空内容时,已打开的承载位同步清空(回落空态),不保留上一次的计划内容。
  • CLI 无常驻承载位:CLI 的 /plan 是一次性 Ink 弹层,不存在常驻计划面板,故不受本机制影响。

用户故事:计划模式重新进入引导(优先级:P1) ​

作为之前已退出计划模式的用户,我希望系统在我重新进入计划模式时能够识别,以便 agent 知道现有计划文件并可以决定继续还是重新开始。

为什么是这个优先级:没有重新进入引导,agent 可能忽略现有计划文件或假设它仍然相关,导致工作浪费或计划不正确。

独立测试:进入计划模式,写入计划,批准 ExitPlanMode,重新进入计划模式,验证 agent 收到关于现有计划文件的重新进入提醒。

验收场景:

  1. 假设 agent 已退出计划模式且计划文件存在,当用户重新进入计划模式时,则注入重新进入 <system-reminder>,指示模型读取现有计划、评估任务是否相同或不同,并在 ExitPlanMode 之前始终编辑计划文件。
  2. 假设 agent 已退出计划模式但没有计划文件存在,当重新进入计划模式时,则不注入重新进入提醒(视为首次进入)。
  3. 假设重新进入提醒已注入一次,当计划模式中后续轮次发生时,则重新进入提醒不再被注入(仅一次)。

用户故事:模式转换意识(优先级:P1) ​

作为在对话中途从 default/acceptEdits 模式切换到计划模式的用户,我希望 agent 立即理解它必须停止编辑并切换到规划,即使对话历史包含最近的 Edit/Write 工具调用。

为什么是这个优先级:没有模式边界意识,模型可能基于最近的工具调用历史继续编辑,忽略计划模式约束。

独立测试:进行包含 Edit/Write 调用的对话,然后进入计划模式,验证计划模式提醒作为最后一条指令出现,带有明确的覆盖语言。

验收场景:

  1. 假设对话包含最近的 Edit/Write 工具调用且用户进入计划模式,当下一次 API 调用发生时,则计划模式 <system-reminder> 作为模型看到的最后一条指令注入(在所有先前的工具调用之后),明确声明 "This supercedes any other instructions you have received."
  2. 假设 agent 处于计划模式且该会话未获得绕过授权,当 agent 尝试在计划文件以外的任何文件上使用 Edit 或 Write 时,则权限系统在运行时阻止该操作。

用户故事:计划模式退出通知(优先级:P2) ​

作为刚刚批准计划的用户,我希望 agent 被明确告知已退出计划模式并可以执行操作,以便对模式转换没有混淆。

为什么是这个优先级:防止 agent 在批准后继续表现得像仍在计划模式中。

独立测试:批准 ExitPlanMode 并验证"已退出计划模式"的 system-reminder 出现在下一个轮次。

验收场景:

  1. 假设 ExitPlanMode 被批准,当下一个 API 轮次开始时,则注入"已退出计划模式"的 <system-reminder> 作为一次性消息。
  2. 假设退出通知已注入,当后续轮次开始时,则退出通知不再被注入(仅一次)。

用户故事:一次性计划进入提醒(优先级:P2) ​

作为进入计划模式的用户,我希望 agent 在进入计划模式并发送消息时恰好收到一次计划模式指令,以便 token 不会浪费在重复提醒上。

为什么是这个优先级:之前的节流机制(扫描消息中的元提醒)已损坏——提醒是临时的,从未存储,所以节流从未触发,每次 AI 调用都注入完整的约 90 行提醒。简化方法在每次计划模式进入时恰好触发一次提醒。

独立测试:进入计划模式,发送消息,验证提醒出现。发送另一条消息,验证没有提醒。退出并重新进入计划模式,验证提醒再次出现。

验收场景:

  1. 假设用户进入计划模式,当第一条消息发送时,则注入完整的计划模式 <system-reminder>(包括 5 阶段工作流)。
  2. 假设计划进入提醒已注入,当同一计划模式会话中发送后续消息时,则不注入计划模式提醒。
  3. 假设用户退出计划模式并重新进入,当下一条消息发送时,则注入重新进入提醒(关于读取现有计划文件的小提醒)。

用户故事:通过 EnterPlanMode 工具进入计划模式(优先级:P1) ​

作为 AI agent,我希望在判断任务较为复杂时主动请求进入计划模式,以便在修改多文件、开发新功能或修复复杂 bug 之前先制定计划。

为什么是这个优先级:允许 agent 自主判断何时需要规划,提升复杂任务的处理质量,同时通过用户确认保持人类监督。

独立测试:在对话中让 agent 判断任务复杂性,验证其调用 EnterPlanMode 工具后触发用户确认,批准后进入计划模式。

验收场景:

  1. 假设 agent 判断当前任务较为复杂(多文件更改、新功能、复杂 bug 修复),当 agent 调用 EnterPlanMode 工具时,则系统通过 canUseTool 机制向用户显示确认请求,用户批准后系统进入计划模式。
  2. 假设 agent 调用 EnterPlanMode,当用户拒绝确认请求时,则agent 收到 "User declined to enter plan mode. Proceed in current mode." 的返回信息,继续在当前模式中执行。
  3. 假设 agent 已在计划模式中,当 agent 调用 EnterPlanMode 时,则工具返回错误信息 "Already in plan mode",不重复进入。
  4. 假设 agent 调用 EnterPlanMode 触发用户确认,当确认对话框显示时,则不得显示"始终允许"选项(hidePersistentOption = true)。

用户故事:通过 /plan 斜杠命令进入计划模式(优先级:P1) ​

作为用户,我希望输入 /plan 斜杠命令直接进入计划模式,以便无需通过 Shift+Tab 循环多个模式即可开始规划(对齐 Claude Code 的 /plan 命令入口)。

为什么是这个优先级:/plan 是与 Shift+Tab、--permission-mode plan 并列的第三入口,用户显式输入即授权,无需确认对话框;/plan <描述> 更进一步把「进入计划模式」和「立即开始规划」合并为一条命令,是用户发起规划的最短路径。命令注册在各宿主侧(CLI 内置命令列表 + 三端 GUI 的本地命令列表),不进入 SDK 的 SlashCommandManager——/plan 的动作依赖宿主各自的展示能力(编辑器标签页 / 面板 / Ink 弹层),由宿主处理而非 SDK。

独立测试:在非 plan 模式下输入 /plan 验证直接进入计划模式(无确认对话框);输入 /plan <描述> 验证进入计划模式且描述作为用户消息触发一次 AI 查询,模型收到计划模式提醒并开始规划;验证命令出现在命令选择器与帮助视图中。

验收场景:

  1. 假设系统处于非 plan 模式(default/acceptEdits/bypassPermissions),当用户输入 /plan 时,则系统直接切换到 plan 模式,不显示确认对话框(用户显式输入即授权),并完成完整模式过渡(plan 文件路径生成、onPermissionModeChange 回调、状态栏模式指示更新)。
  2. 假设系统处于非 plan 模式,当用户输入 /plan <描述> 时,则系统切换到 plan 模式,并将 <描述> 作为用户消息立即触发一次 AI 查询;模型在计划模式提醒(含 plan 文件路径)下开始规划。
  3. 假设 /plan <描述> 已触发模式切换,当 AI 查询发起时,则plan 文件路径已生成完毕并注入提醒(路径生成必须先于查询触发,避免模型收不到 plan 文件位置的竞态)。
  4. 假设系统已处于 plan 模式,当用户输入 /plan <描述> 时,则系统不重复进入 plan 模式,也不触发新查询(按「查看当前计划」处理,忽略描述参数)。
  5. 假设用户输入 /plan(无参数),当系统切换成功时,则仅进入 plan 模式,不触发 AI 查询。
  6. 假设用户输入 / 打开命令选择器,当浏览命令列表时,则/plan 命令可见(描述:启用计划模式或查看当前计划);CLI /help 帮助视图、GUI 命令弹窗中同样可见。
  7. 假设用户输入 /plan open,当命令被执行时,则不打开任何外部编辑器(三端均不支持该子命令),open 被视为普通描述或忽略,行为与 /plan 一致。

用户故事:通过 /plan 查看当前计划(优先级:P2) ​

作为处于计划模式中的用户,我希望输入 /plan 查看当前计划的完整内容,以便在不通过 ExitPlanMode 确认流程的情况下审查计划(对齐 Claude Code 的 /plan 查看入口)。

为什么是这个优先级:查看是计划流程的便利能力,核心路径(写入 → ExitPlanMode → 确认)不依赖它;但缺少它会迫使审查只能走确认对话框。三端展示动作复用 ExitPlanMode 已有的计划承载位,不新增展示形态。

独立测试:进入计划模式并写入计划后输入 /plan,验证在宿主各自的计划承载位显示当前计划内容与文件路径;无内容时验证给出提示。

验收场景:

  1. 假设系统处于 plan 模式且 plan 文件已写入内容,当用户输入 /plan 时,则 CLI 在 Ink 弹层中显示当前计划("Current Plan":计划文件路径 + 完整内容),弹层高度固定为终端约 50-60%,内容超出高度时支持 PgUp/PgDn/Ctrl+u/Ctrl+d 滚动并显示 ↑↓ more 指示器,Esc 关闭。
  2. 假设系统处于 plan 模式且 plan 文件已写入内容(JetBrains 插件),当用户输入 /plan 时,则完整计划内容以 markdown 渲染在该会话已有的计划标签页中(复用 ExitPlanMode 的编辑器区域标签页,不新建)。
  3. 假设系统处于 plan 模式且 plan 文件已写入内容(VS Code 扩展),当用户输入 /plan 时,则完整计划内容渲染在该会话已有的计划预览面板中(createWebviewPanel,与 ExitPlanMode 共用同一面板)。
  4. 假设系统处于 plan 模式且 plan 文件已写入内容(桌面应用),当用户输入 /plan 时,则完整计划内容以 markdown 渲染在 Plan 面板中(复用 ExitPlanMode 的面板,未打开时自动打开)。
  5. 假设系统处于 plan 模式但 plan 文件尚无内容,当用户输入 /plan 时,则提示 "No plan written yet."(对齐 Claude Code 文案),不打开空承载位。
  6. 假设 CLI 中 plan 内容超过弹层可视行数,当用户按下 PgDn / Ctrl+d 时,则内容向下翻页并显示剩余行数指示;滚动到底后 PgDn 不再移动。
  7. 假设 CLI 的 /plan 弹层已打开,当用户按下 Esc 时,则弹层关闭,返回输入框,模式不变。

用户故事:计划文件更新后刷新计划面板(优先级:P2) ​

作为在计划模式下查看计划面板的用户,我希望模型每次修改计划文件后计划面板就显示最新内容,以便我在规划过程中看到的是当前计划,而不是停留在上一次 ExitPlanMode 或 /plan 时的旧快照。

为什么是这个优先级:模型以增量方式构建计划(先 Write 创建、再多次 Edit/Write 补充),而计划承载位此前只在 ExitPlanMode 确认与 /plan 查看两个时点刷新,规划过程中展示的内容会持续滞后。承载位应始终反映计划文件的当前内容。

独立测试:进入计划模式并打开计划承载位(桌面 Plan 面板 / VS Code 计划预览面板 / JetBrains 计划标签页),让模型写入计划文件,再让它修改一次,验证承载位内容随之更新为最新计划;关闭承载位后再修改文件,验证承载位不会被自动重新打开。

验收场景:

  1. 假设 agent 处于计划模式且计划承载位已打开,当 agent 用 Write 或 Edit 工具修改指定的计划文件后,则承载位内容更新为该文件的最新完整内容(等效于此刻执行一次「查看当前计划」)。
  2. 假设 agent 在同一计划模式会话中连续多次修改计划文件(Write 整体覆盖或 Edit 增量修改),当每次修改完成时,则承载位每次都更新为最新内容,无需等待下一次 ExitPlanMode 或 /plan。
  3. 假设桌面应用中计划文件被 agent 修改且 Plan 面板已打开,当修改完成时,则 Plan 面板内的 markdown 更新为最新计划,面板的打开状态与位置不变。
  4. 假设 VS Code 扩展中计划文件被 agent 修改且计划预览面板已打开,当修改完成时,则该面板内容更新为最新计划,不新建面板。
  5. 假设 JetBrains 插件中计划文件被 agent 修改且计划标签页已打开,当修改完成时,则该标签页内容更新为最新计划,不新建标签页。
  6. 假设计划承载位尚未打开(本会话还未通过 ExitPlanMode 或 /plan 触发过),当 agent 修改计划文件时,则不自动打开承载位;下一次由 ExitPlanMode 或 /plan 打开时展示该文件的最新内容。
  7. 假设 agent 修改的文件不是当前计划文件(代码或其它文件),当工具执行完成时,则计划承载位不受影响。
  8. 假设 agent 修改计划文件后随即调用 ExitPlanMode,当确认对话框显示时,则承载位展示的内容与计划文件的当前内容一致(刷新不产生重复内容或过期快照)。
  9. 假设多个会话并行、各自持有独立的计划承载位,当其中一个会话修改自己的计划文件时,则只有该会话的承载位更新,其它会话不受影响。
  10. 假设 agent 已退出计划模式,或用户直接编辑 ~/.wave/plans/ 下的计划文件,当计划文件内容变化时,则承载位不刷新(本期刷新只由 agent 的 Write/Edit 工具调用驱动)。