omp packages

@wbline/pi-plan-build0.0.6

Plan/Build dual-mode for the Pi coding agent: read-only planning, explicit approval, step-wise execution.

wongbin Published 16 hours ago MIT ~907 downloads/mo

Untested on omp

This is a pi package. No one has reported whether it works on omp yet. If you try it, add your result below.

Did it work for you?

Result

One report per person. A new report replaces your old one.

Reports 0

No reports yet.

Readme

pi-plan-build

让 agent 先规划、经你审批、再动手。为 Pi coding agent 设计的 plan/build 双模式工作流扩展。

只读规划 → 显式审批 → 分步/整段实现 → 验证闭环。 规划期间 agent 改不了你的项目;审批之前没有实现;每一步的完成与验证都有据可查。

plan 模式(只读)            审批(三选一)              build 模式
调研讨论 → 写计划文件 ──▶ plan_exit ──▶ 本会话 / 分步 / 留在 plan ──▶ 实现 → 验证 → plan_complete
        ▲ 守卫:只许写计划文件                              ▲ 守卫:计划文件只读

快速开始

pi install npm:@wbline/pi-plan-build

零配置,装上即用。计划文件自动落在当前项目 .pi/agent/plans/(<创建时刻>-<标题>.md,随项目走)。30 秒体验完整闭环:

  1. Alt+M 切到 plan 模式:只读调研讨论,agent 的文件写入被守卫拦截
  2. 让 agent 规划:plan_task new 建计划(你未明确要求规划时,会先弹窗确认:创建计划还是直接执行)→ 写完整计划文件(含验证小节与实现步骤)→ plan_exit 提请审批
  3. 你三选一:本会话连续实现 / 分步实现 / 留在 plan——选择之前 agent 劫不了代码
  4. build 模式实现:计划文件受保护;分步模式默认每步等点头,说「剩下的都做完」可授权连跑
  5. 验证闭环:能自动验证的当场跑;只能你验证的(登录、硬件、线上效果)记为 awaiting_validation,你下一条消息时主动弹窗确认,通过才收尾

它解决什么问题

没有 plan-build 有了 plan-build
agent 听完需求直接开改 规划期只读,写文件被守卫拦截
"方案同意了"就等于开写 审批是显式的三选一,选择前零改动
计划与实现混在一个上下文里 双模式状态机,计划随会话持久化、可恢复
"做完了"全靠 agent 自述 验证策略内置,必需的用户验证主动发问

核心机制

  • 🔒 双模式权限守卫:tool_call 前拦截,路径归一化(@/~/相对路径)+ symlink 解析。plan 模式只许写计划文件,无路径或波及面无法验证(未知工具、语义重命名)一律阻断——宁可误拦不可放行
  • 🏷️ 动态工具分类:不写死工具名单,按配置覆盖 > 注解(readOnlyHint)> 方法后缀 > 动词约定(写动词优先)分类;新增 IDE 变更工具不再漏拦
  • ⏱️ 时序硬闸:plan_task 生命周期转移未收尾时,依赖它的文件变更与生命周期工具一律先等——把"转移先于依赖动作"从提示词约束升级为硬拦截
  • 🚪 全链路显式决策:plan_task new 先问「创建计划还是直接执行」(明确要求规划可传参跳过),plan_exit 后问「本会话/分步/留下」;build 模式建计划、build 中途修订计划(plan_task revise)、plan 模式被守卫拦截时各有一道确认门——每次模式转换都由用户一键拍板
  • 📒 事后对账:放行波及面无法验证的工具(IDE 终端命令、shell)前记录计划文件基线,回合结束时文件被改动即警告核对
  • 🪜 分步执行:计划里的实现步骤逐个就绪,你说"继续"才开工,说「剩下的都做完」即授权连跑自动推进;侧栏实时显示 [待办]/[就绪]/[进行]/[完成]/[跳过] 进度
  • ✅ 验证闭环:awaiting_validation 结算后,在你下一条消息时确认一次「必需验证通过了吗?」,通过才收尾,否则计划保持开放——不会在你还没开始验证时就弹窗
  • 🌐 中英双语提示词与工具描述:菜单一键切换;7 个工具全模式常驻(稳定工具目录),模式切换不抖动工具列表,prompt cache 持续命中

命令

命令 / 快捷键 说明
/plan-build 交互菜单:切换模式 / 查看状态 / 标记完成 / 放弃计划(原因必填,文件保留)/ 语言切换 / 设置文件
/plan /build 直切模式;IDE(ACP)桥接层按命令名调用,JetBrains AI 聊天的模式选择器依赖这两个命令
Alt+M 直接切换模式;新会话默认模式由设置 defaultMode 决定

状态栏徽标(📋 plan / 🔨 build + 计划标题与进度)显示在底部;分步执行时步骤列表 widget 同步显示。

工具

工具 说明
plan_task 任务生命周期:new 建计划(plan 模式)、revise 请求切回 plan 修订当前计划(弹窗确认,build 中途修计划的专用通道)、include 追加用户批准的范围、update 改名、exclude 记录排除、abandon、list/show。所有转移必须带 expectedAttached 做乐观并发(new 传 null,其余传当前 seq),不匹配即拒。new 内置入口询问:用户未明确要求规划(传 planningRequested: true 可跳过)时,先弹窗让用户选「创建计划 / 直接执行」,选直接执行即自动切 build、不建计划;build 模式调用 new 会先弹窗确认切到 plan。new 支持 fromFile 恢复既有计划文件(plans 目录内原地接管,外部文件复制并在原文件标记「已接管」;换会话后接着干);list 附带 plans 目录历史计划与归档结局
plan_exit plan 模式终点。要求计划文件已写盘,然后弹出审批:本会话连续实现 / 分步实现 / 留在 plan 模式。取消对话框 ≠ 主动留下(模型会向你询问意图);无交互 UI(print/json)时跳过审批门自动选本会话连续实现
plan_step_control 分步执行:start 批准就绪步(advance: "all" 一次授权连跑剩余步骤,遇阻塞才停)、acknowledge 指认用户声明的已完成步(无需先 start)、skip、revise 修订未完成步(同步改文件)、pause/resume、cancel。一次只许一个转移
plan_step_complete 完成当前进行中的步(摘要必填),立即生效不等待验收;最后一步完成即自动收尾整计划
plan_complete 标记整计划完成——仅在全部工作与必需检查通过,或用户明确指示时。收尾时在计划文件文末写入状态块(> **状态:已完成**(日期) + 摘要),放弃同理(含原因),历史计划单看文件即可知结局
plan_set_outcome 记录未完成结局并保持计划开放:awaiting_validation(必填精确的 userAction)/ blocked / waiting_for_input / still_working
plan_question 结构化选择题,收集决策;无交互 UI 时自动降级为文本提问

设置

~/.pi/agent/pi-plan-build.json,全部可省略:

字段 默认 说明
lang "zh" 提示词语言:"zh" / "en"
defaultMode "build" 新会话默认模式(startup/new 生效;resume 尊重恢复出的状态)
protectPlanFile true build 模式是否保护计划文件(关闭后对账一并停用)
toolGuard — 工具分类强制覆盖:{ "readonly": [], "mutating": [] },列出的工具名优先级最高

权限边界

守卫在 tool_call 前拦截,路径先归一化再做 symlink 解析,不存在的文件解析最远存在父目录:

  • 管辖范围:只守卫 pi 内置工具与 JetBrains IDE 桥接工具(ide_ 前缀)——内置 8 个全量显式分类(edit/write 变更、bash/powershell 执行面、read/find/grep/ls 只读),ide_* 动态分类;其它扩展/MCP 工具不守卫(codemode 的嵌套调用走 pi 同一 tool_call 管线,仍受守卫约束)
  • plan 模式:文件变更通道(原生 edit/write 与 IDE 桥接工具)只许目标为当前计划文件。IDE 工具动态分类不写死名单;无路径或波及面无法验证(未知变更工具、语义重命名)的调用一律阻断——宁可误拦不可放行;有 UI 时拦截会弹确认门,用户确认即切 build 放行本次修改,拒绝则本回合只拦不再问(回合结束重置)
  • 时序硬闸:最近一条 assistant 消息里 plan_task 结构转移(new/revise/include/update/exclude/abandon 等非只读动作)未收尾时,文件变更与生命周期工具一律先等转移收尾(list/show 只读动作不拦)
  • 事后对账:build 模式放行波及面无法验证的变更工具前记录计划文件内容基线,结算(agent_settled)时发现文件被改动即警告提示核对;bash/powershell 与 IDE 执行面工具改写计划文件同样纳入
  • 模式边界:plan_task new 仅限 plan 模式(build 下创建的计划无法走 plan_exit 审批);分步执行进行中禁止切回 plan 模式(避免"只读 + 实现第 N 步"的矛盾注入);plan 模式且无计划时,new 先弹窗询问「创建计划 / 直接执行」(用户明确要求规划可跳过),选直接执行自动切 build;build 模式调用 new 也会弹窗确认切到 plan(拒绝则保持 build);build 中途修订计划走 plan_task revise(弹窗确认切回 plan)——所有模式转换都由用户拍板
  • build 模式:已写盘的计划文件受保护(protectPlanFile: false 可关);修订计划调用 plan_task revise(确认门切回 plan)或由用户 /plan;未列入的 IDE 变更工具同样过守卫(无法验证目标时放行)
  • bash/powershell 与 IDE 执行面工具不做分类沙箱:终端命令、运行配置、构建、SQL 执行、inspection KTS 的目标不可提取且能力与 shell 等价——plan 模式为提示词约束,build 模式放行并纳入事后对账;诚实标注而非冒充沙箱
  • 扩展自身对计划文件的修订(步骤 revise、终态状态块)不经 tool_call 守卫(守卫只拦模型调用),但受同一状态机校验并在计划文件上留痕;终态归档 append-only,文件为空或写失败则静默跳过

设计取舍

  • 集中状态机而非分散闭包:全部状态收敛为一个不可变 State(mode + plan + execution),唯一 transition() 入口,纯函数单测全覆盖。代价是新增行为必须先定义转移事件——换来任何状态变化都有唯一出处
  • 原生 UI 而非接管 composer:只用 setStatus / setWidget / ui.custom / ui.select,不碰编辑器与消息栏——与任何其它扩展零冲突
  • 砍掉干净会话交接:跨会话 transfer/reconcile 的多段状态机收益低、分支爆炸,不做。换会话后用 plan_task new fromFile 恢复既有计划文件接着干(list 可查历史计划与结局)
  • 宽容步骤解析:编号 / checkbox / 短横线都接受,重复步骤去重;解析失败不报错,而是返回一段模型可执行的修复指引
  • 上下文锚定注入:计划块作为 user 消息插在最后一条真实用户消息之前,位置与内容稳定——前缀缓存持续命中
  • 验证问询等下一条消息:awaiting_validation 结算后不在回合刚结束时弹窗(那时你还没验证),而在你下一次发消息时确认一次;未通过不自动重问,重新结算才重置——比误重问的选择框更安静
  • 无 UI 跳过审批门:print/json 模式没有可交互的用户,入口询问与 plan_exit 审批门一致跳过(后者自动选本会话连续实现)——不会出现"计划建了却永远拿不到实现授权"的死锁

开发

npm install       # 安装开发依赖(含 pi 1.3.0 类型)
npm run check     # biome + tsc 双检查
npm test          # 26 个纯函数单测:状态机 / 步骤解析 / 路径守卫 / 持久化解码
npm run smoke     # 装配冒烟:stub ExtensionAPI 走完整流程(注册、守卫、菜单、注入)

历史更新见 CHANGELOG.md(Keep a Changelog 格式,随版本发布维护)。

License

MIT