pi-plans 0.1.0 → 0.1.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.md +47 -22
- package/docs/assets/pi-plans-logo.svg +2 -2
- package/index.ts +116 -28
- package/package.json +1 -1
- package/references/pi-planning-workflow.md +11 -17
- package/references/plan-artifact-template.md +1 -1
- package/references/state-and-config.md +1 -1
- package/skills/debug-and-plan/SKILL.md +1 -1
- package/skills/plan-big/SKILL.md +1 -1
- package/skills/plan-normal/SKILL.md +1 -1
- package/skills/plan-small/SKILL.md +1 -1
- package/skills/plan-with-refs/SKILL.md +1 -1
- package/src/exec.ts +861 -28
- package/src/execution-panel.ts +159 -23
- package/src/plan.ts +106 -0
- package/src/state.ts +36 -0
- package/tests/exec.test.ts +919 -44
- package/tests/execution-panel.test.ts +44 -8
- package/tests/plan.test.ts +84 -1
- package/tests/plans.test.ts +36 -0
- package/tests/state.test.ts +60 -0
- package/tools/execute-plan.ts +46 -6
- package/tools/plans.ts +34 -1
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
<h1 align="center"
|
|
1
|
+
<h1 align="center">π-plans</h1>
|
|
2
2
|
|
|
3
3
|
<p align="center">
|
|
4
|
-
<img src="docs/assets/pi-plans-logo.svg?v=
|
|
4
|
+
<img src="docs/assets/pi-plans-logo.svg?v=4" alt="pi-plans: Plan. Review. Execute." width="640" />
|
|
5
5
|
</p>
|
|
6
6
|
|
|
7
7
|
<h2 align="center"><b>Plan. Review. Execute.</b></h2>
|
|
@@ -13,9 +13,11 @@
|
|
|
13
13
|
<p align="center">
|
|
14
14
|
<a href="https://github.com/MaxInGaussian/pi-plans/stargazers"><img alt="GitHub stars" src="https://img.shields.io/github/stars/MaxInGaussian/pi-plans?style=square" /></a>
|
|
15
15
|
<a href="https://hits.sh/github.com/MaxInGaussian/pi-plans/"><img alt="Repo views" src="https://hits.sh/github.com/MaxInGaussian/pi-plans.svg?label=repo%20views" /></a>
|
|
16
|
-
<a href="
|
|
17
|
-
<img alt="
|
|
18
|
-
<img alt="
|
|
16
|
+
<a href="https://www.npmjs.com/package/pi-plans"><img alt="npm downloads" src="https://img.shields.io/npm/dt/pi-plans?color=38bdf8" /></a>
|
|
17
|
+
<a href="https://www.npmjs.com/package/pi-plans"><img alt="npm version" src="https://img.shields.io/npm/v/pi-plans?color=60a5fa" /></a>
|
|
18
|
+
<a href="https://github.com/earendil-works/pi"><img alt="Pi package" src="https://img.shields.io/badge/Pi-package-fbbf24" /></a>
|
|
19
|
+
<a href="./LICENSE"><img alt="License" src="https://img.shields.io/npm/l/pi-plans?color=22c55e" /></a>
|
|
20
|
+
<a href="https://github.com/MaxInGaussian/pi-plans/actions/workflows/ci.yml"><img alt="CI" src="https://github.com/MaxInGaussian/pi-plans/actions/workflows/ci.yml/badge.svg" /></a>
|
|
19
21
|
</p>
|
|
20
22
|
|
|
21
23
|
---
|
|
@@ -58,8 +60,9 @@ A rough change request becomes a versioned Markdown plan instead of a surprise d
|
|
|
58
60
|
=============================================== write guard OFF
|
|
59
61
|
|
|
|
60
62
|
tracked execution loop
|
|
63
|
+
fused AGENTS.md × Ponytail executor rules
|
|
61
64
|
checklist injected each turn, [DONE:VC-xxx]
|
|
62
|
-
markers tracked
|
|
65
|
+
markers tracked via bottom status bar + detail panel
|
|
63
66
|
|
|
|
64
67
|
v
|
|
65
68
|
run status: done
|
|
@@ -93,17 +96,13 @@ Pi: Wrote ./docs/pi-plans/2026-08-26-split-execution-loop/PLAN_v1.md
|
|
|
93
96
|
- [ ] `VC-001` covers `I-001`; pass condition: `npm test` passes;
|
|
94
97
|
evidence: test output; metric: zero failing tests.
|
|
95
98
|
|
|
96
|
-
Pi:
|
|
97
|
-
1.
|
|
98
|
-
2.
|
|
99
|
-
3.
|
|
99
|
+
Pi: Accept the plan and execute it now?
|
|
100
|
+
1. ✓ Accept plan and execute now (recommended)
|
|
101
|
+
2. Accept plan, don't execute yet
|
|
102
|
+
3. Run another round: Reviewer
|
|
100
103
|
...
|
|
101
104
|
|
|
102
|
-
You:
|
|
103
|
-
|
|
104
|
-
Pi: Execute this plan now?
|
|
105
|
-
1. Execute this plan now (recommended)
|
|
106
|
-
2. Stop after planning
|
|
105
|
+
You: 1 — accept and execute.
|
|
107
106
|
```
|
|
108
107
|
|
|
109
108
|
Planning artifacts live under `./docs/pi-plans/YYYY-MM-DD-<topic>/` by default (public, committed). Prefer `.git/pi_plans/plans` if you want them private to the repository.
|
|
@@ -116,22 +115,44 @@ Planning artifacts live under `./docs/pi-plans/YYYY-MM-DD-<topic>/` by default (
|
|
|
116
115
|
| Choice prompts | `ask_choice`: recommended option first, answers auto-recorded per run |
|
|
117
116
|
| Refinement rounds | Read-only reviewer/criticizer Pi subagents consolidate findings into the next plan version |
|
|
118
117
|
| Workspace state | Config, runs, decisions, refs, and subagent ledgers in `.git/pi_plans/` (git common dir) |
|
|
119
|
-
| Tracked execution | Checklist injected each turn; `[DONE:VC-xxx]` markers drive progress |
|
|
118
|
+
| Tracked execution | Checklist injected each turn; `[DONE:VC-xxx]` markers drive completion; implementation items report progress with `[I-xxx:implemented]` / `[I-xxx:validating]` markers; `plans-list` groups work by I-item with `[Pending/Implementing/Implemented/Validating/VC passed]` states (passed items struck through); the collapsed footer and expanded panel share the same progress projection, so `x/y` updates in real time in both views |
|
|
119
|
+
| Execution model | With `plans set-execution-model <provider/model[:thinking]>`, the main session switches to it at handoff and restores the planning model + thinking level on stop/complete/abandon; when unset, the first execution handoff prompts for one and recommends inheriting the current session model |
|
|
120
|
+
| Execution-phase compaction | Pi core owns threshold, overflow, and manual compaction scheduling; pi-plans only supplies a plan-aware `session_before_compact` summary and queues one hidden continuation when Pi reports `willRetry: false`, while preserving the raw execution tail and `previousSummary` chaining |
|
|
121
|
+
| Planning-phase auto compaction | In active planning runs (run.status=planning, no execution), context usage >=100% triggers a plan-aware compaction too: pre-plan history compresses, Q&A during planning stays in a dedicated section, the latest `PLAN_vN.md` and later conversation stay raw; cooldown + resume guard prevent ping-pong, and manual `/compact` follows the same rules |
|
|
122
|
+
| Efficient executor prompt | Each turn, the executor is steered by a fused rule set — Marcos Hernanz's AGENTS.md principles × Ponytail minimalism: layered growth, simplest implementation, long-term architecture (no stopgaps), library discipline — so plans finish in fewer tokens and fewer detours |
|
|
120
123
|
| Write guard | `edit`/`write` blocked outside planning artifacts while a run is active |
|
|
121
124
|
|
|
122
125
|
## Interface overview
|
|
123
126
|
|
|
124
127
|
| Tool / Command | Purpose |
|
|
125
128
|
|---|---|
|
|
126
|
-
| `plans` | State CLI: `init`, `show`, `set-language`, `set-artifact-root`, `set-role`, `start-run`, `set-status`, `record-decision`, `record-ref`, `record-subagent` |
|
|
127
|
-
| `ask_choice` | Numbered choice prompt; `autoComplete: false` for
|
|
129
|
+
| `plans` | State CLI: `init`, `show`, `set-language`, `set-artifact-root`, `set-execution-model`, `set-role`, `start-run`, `set-status`, `record-decision`, `record-ref`, `record-subagent` |
|
|
130
|
+
| `ask_choice` | Numbered choice prompt; `autoComplete: false` for the merged accept/execute question and external-state questions |
|
|
128
131
|
| `refine` | Reviewer/criticizer round via read-only subagents (`--tools read,grep,find,ls`); `reviewers: 3` for big plans; enforces role/model confirmation gates |
|
|
129
|
-
| `execute_plan` | Execution handoff: re-confirms with the user, enters extension-managed execution mode |
|
|
130
|
-
| `/plans` | Show config, active run, execution progress |
|
|
131
|
-
| `/plans-
|
|
132
|
+
| `execute_plan` | Execution handoff: re-confirms with the user, prompts for an execution model if needed, and enters extension-managed execution mode |
|
|
133
|
+
| `/plans` | Show config, active run, and execution progress |
|
|
134
|
+
| `/plans-list` | Toggle the execution checklist panel |
|
|
135
|
+
| `/plans-execute [plan.md]` | Manual execution handoff (defaults to highest `PLAN_vN.md`; prompts for an execution model if unset) |
|
|
132
136
|
| `/update-plan [plan.md] [reason…]` | Interrupt-and-refine: stops execution (if any), returns the run to planning, and directs the agent to revise the plan into `PLAN_vN+1.md` while preserving verified work |
|
|
133
137
|
| `/plans-stop` | Stop execution mode |
|
|
134
138
|
| `/plans-abandon` | Abandon the active run (lifts the write guard; artifacts stay) |
|
|
139
|
+
| Status bar (lifecycle) | 💬 Q&A → 📝 draft written (planning sub-phases) → ⌛ executing `x/y · spent · in/out-toks` in the collapsed footer or expanded panel → ⛔ stopped / 🎯 done / 🚫 abandoned |
|
|
140
|
+
|
|
141
|
+
## The execution rules
|
|
142
|
+
|
|
143
|
+
Once you approve the handoff, every turn injects a compact rule set that fuses Marcos Hernanz's AGENTS.md seven principles with Ponytail minimalism — so the executor finishes plans in fewer tokens and fewer detours:
|
|
144
|
+
|
|
145
|
+
<details>
|
|
146
|
+
<summary>The four fused rules (click to expand)</summary>
|
|
147
|
+
|
|
148
|
+
1. **Grow in layers** — smallest end-to-end slice first, then stack each new capability on top of what already works.
|
|
149
|
+
2. **Simplest implementation** — no speculative abstractions, configuration, or indirection; modular components with clearly separated concerns.
|
|
150
|
+
3. **Long-term architecture, no stopgaps** — no backward-compatibility layers, fallbacks, or migrations; remove the obsolete paths a change obsoletes.
|
|
151
|
+
4. **Library discipline** — prefer established, well-maintained libraries; check the project's existing dependencies (docs and types) before writing your own or adding a package.
|
|
152
|
+
|
|
153
|
+
</details>
|
|
154
|
+
|
|
155
|
+
The rules cost four lines per turn and buy back far more: fewer wrong turns, shorter implementation paths, plans that finish in fewer tokens.
|
|
135
156
|
|
|
136
157
|
## Skills
|
|
137
158
|
|
|
@@ -198,7 +219,7 @@ Both run on Node ≥ 22.6 via `--experimental-strip-types`; no npm dependencies.
|
|
|
198
219
|
|
|
199
220
|
**Why do I have to approve before any code changes?**
|
|
200
221
|
|
|
201
|
-
The plan is the contract. Refinement converges on scope while nothing is writable yet; the
|
|
222
|
+
The plan is the contract. Refinement converges on scope while nothing is writable yet; the merged accept/execute question is an explicit, never-auto-completed approval that also lifts the write guard. You always see — and can veto — what will happen before it happens.
|
|
202
223
|
|
|
203
224
|
**What can Auto-complete decide on my behalf?**
|
|
204
225
|
|
|
@@ -212,6 +233,10 @@ Preferences and run ledgers in `.git/pi_plans/` inside your workspace's git dire
|
|
|
212
233
|
|
|
213
234
|
Prompts produce one-shot diffs with no recorded reasoning. pi-plans produces versioned artifacts — decisions, references, reviewer findings, dispositions, a verifier checklist — that are auditable, resumable across sessions, and enforced by tooling rather than goodwill.
|
|
214
235
|
|
|
236
|
+
**Doesn't injecting execution rules every turn cost extra tokens?**
|
|
237
|
+
|
|
238
|
+
The injected rule set is four compressed lines. It buys back more than it costs: the executor stops re-deriving discipline (no speculative abstractions, no compatibility detours, no reinvented helpers), so finished items converge in fewer turns and fewer tokens overall.
|
|
239
|
+
|
|
215
240
|
## License
|
|
216
241
|
|
|
217
242
|
MIT.
|
|
@@ -32,8 +32,8 @@
|
|
|
32
32
|
</g>
|
|
33
33
|
|
|
34
34
|
<!-- wordmark -->
|
|
35
|
-
<text x="150" y="96" font-family="-apple-system,'Segoe UI',Helvetica,Arial,sans-serif" font-size="60" font-weight="700" fill="#ffffff"
|
|
36
|
-
<rect x="153" y="110" width="
|
|
35
|
+
<text x="150" y="96" font-family="-apple-system,'Segoe UI',Helvetica,Arial,sans-serif" font-size="60" font-weight="700" fill="#ffffff">π-plans</text>
|
|
36
|
+
<rect x="153" y="110" width="210" height="6" rx="3" fill="url(#bar)"/>
|
|
37
37
|
<text x="151" y="147" font-family="'SF Mono',Menlo,Consolas,monospace" font-size="16" letter-spacing="4" fill="#ddd6fe">PLAN·REVIEW·EXECUTE</text>
|
|
38
38
|
|
|
39
39
|
<!-- pipeline: plan -> review -> execute -->
|
package/index.ts
CHANGED
|
@@ -19,19 +19,31 @@ import * as path from "node:path";
|
|
|
19
19
|
import { dirname, join } from "node:path";
|
|
20
20
|
import { fileURLToPath } from "node:url";
|
|
21
21
|
import {
|
|
22
|
-
applyDoneMarkers,
|
|
23
|
-
completeExecution,
|
|
24
22
|
consumePendingPanelSync,
|
|
23
|
+
consumePlanningCompactionResumeGuard,
|
|
24
|
+
drainExecutionFlush,
|
|
25
25
|
executionContextMessage,
|
|
26
|
+
filterExecutionResumeMessages,
|
|
27
|
+
filterPlanningResumeMessages,
|
|
26
28
|
getExecution,
|
|
27
|
-
|
|
28
|
-
|
|
29
|
+
handleExecutionBeforeCompact,
|
|
30
|
+
handleExecutionCompact,
|
|
31
|
+
handleExecutionCompactFailed,
|
|
32
|
+
handlePlanningBeforeCompact,
|
|
33
|
+
handlePlanningCompact,
|
|
34
|
+
handlePlanningCompactFailed,
|
|
35
|
+
PLANNING_PLAN_WRITTEN_CUSTOM_TYPE,
|
|
36
|
+
registerExecutionTurnHandlers,
|
|
29
37
|
recordTouchedPaths,
|
|
38
|
+
refreshPlanningCompactionCooldown,
|
|
39
|
+
requestPlanningCompaction,
|
|
30
40
|
restoreFromSession,
|
|
41
|
+
ensureExecutionModelActive,
|
|
31
42
|
stopExecution,
|
|
32
43
|
syncExecutionPanel,
|
|
33
44
|
toggleExecutionPanelView,
|
|
34
45
|
updateStatusWidget,
|
|
46
|
+
shouldTriggerPlanningCompaction,
|
|
35
47
|
} from "./src/exec.ts";
|
|
36
48
|
import { planningWriteBlockReason } from "./src/guard.ts";
|
|
37
49
|
import { latestPlanVersion, nextPlanVersionPath } from "./src/plan.ts";
|
|
@@ -43,6 +55,31 @@ import { registerRefineTool } from "./tools/refine.ts";
|
|
|
43
55
|
|
|
44
56
|
const baseDir = dirname(fileURLToPath(import.meta.url));
|
|
45
57
|
|
|
58
|
+
// When THIS copy of the extension was imported into the running pi process.
|
|
59
|
+
// /plans compares it against the newest source-file mtime so a stale instance
|
|
60
|
+
// (code on disk newer than the loaded copy) is immediately visible.
|
|
61
|
+
const extensionLoadedAt = new Date();
|
|
62
|
+
|
|
63
|
+
function extensionStalenessLine(): string {
|
|
64
|
+
try {
|
|
65
|
+
const dirs = [baseDir, path.join(baseDir, "src"), path.join(baseDir, "tools")];
|
|
66
|
+
let newest = 0;
|
|
67
|
+
for (const dir of dirs) {
|
|
68
|
+
for (const name of fs.readdirSync(dir)) {
|
|
69
|
+
if (!name.endsWith(".ts")) continue;
|
|
70
|
+
const mtime = fs.statSync(path.join(dir, name)).mtimeMs;
|
|
71
|
+
if (mtime > newest) newest = mtime;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
if (newest > extensionLoadedAt.getTime() + 2000) {
|
|
75
|
+
return `⚠ extension code on disk is newer than the loaded copy (loaded ${extensionLoadedAt.toISOString()}); run /reload to pick it up`;
|
|
76
|
+
}
|
|
77
|
+
return `Extension loaded: ${extensionLoadedAt.toISOString()} (up to date)`;
|
|
78
|
+
} catch {
|
|
79
|
+
return `Extension loaded: ${extensionLoadedAt.toISOString()}`;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
46
83
|
function extractPathsFromBash(command: string): string[] {
|
|
47
84
|
const values = new Set<string>();
|
|
48
85
|
for (const token of command.split(/\s+/)) {
|
|
@@ -120,16 +157,67 @@ export default function piPlansExtension(pi: ExtensionAPI): void {
|
|
|
120
157
|
const rawPath = String((event.input as { path?: string }).path ?? "");
|
|
121
158
|
if (!rawPath) return;
|
|
122
159
|
const reason = planningWriteBlockReason({ workdir: ctx.cwd, toolName: event.toolName, rawPath });
|
|
123
|
-
if (
|
|
124
|
-
|
|
160
|
+
if (reason) return { block: true, reason };
|
|
161
|
+
// Allowed write: if it lands exactly on the run's latest plan file, drop a
|
|
162
|
+
// marker entry so planning-phase compaction can anchor its cut point there.
|
|
163
|
+
if (event.toolName === "write") {
|
|
164
|
+
const active = readActive(ctx.cwd);
|
|
165
|
+
if (active) {
|
|
166
|
+
const latest = latestPlanVersion(active.artifact_dir);
|
|
167
|
+
if (latest && path.resolve(ctx.cwd, rawPath) === path.resolve(ctx.cwd, latest.path)) {
|
|
168
|
+
pi.appendEntry(PLANNING_PLAN_WRITTEN_CUSTOM_TYPE, {
|
|
169
|
+
runId: active.run_id,
|
|
170
|
+
planPath: latest.path,
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
return;
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
pi.on("context", (event) => {
|
|
179
|
+
const filteredExecution = filterExecutionResumeMessages(event.messages as Array<{ customType?: string }>);
|
|
180
|
+
const messages = filterPlanningResumeMessages(filteredExecution);
|
|
181
|
+
if (messages.length !== event.messages.length) {
|
|
182
|
+
return { messages };
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
pi.on("session_before_compact", async (event, ctx) => {
|
|
187
|
+
const executionResult = await handleExecutionBeforeCompact(pi, ctx, event);
|
|
188
|
+
if (executionResult) return executionResult;
|
|
189
|
+
return handlePlanningBeforeCompact(pi, ctx, event);
|
|
190
|
+
});
|
|
191
|
+
pi.on("session_compact", async (event, ctx) => {
|
|
192
|
+
handleExecutionCompact(pi, ctx, event);
|
|
193
|
+
handlePlanningCompact(pi, ctx, event);
|
|
194
|
+
});
|
|
195
|
+
pi.on("session_compact_failed", async (event, ctx) => {
|
|
196
|
+
handleExecutionCompactFailed(pi, ctx, event);
|
|
197
|
+
handlePlanningCompactFailed(pi, ctx, event);
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
// Flush points for deferred execution-loop writes: primary drain when the
|
|
201
|
+
// agent run fully settles, backstop drain at the next run's start (covers
|
|
202
|
+
// continuation paths that might not emit agent_settled), plus the forced
|
|
203
|
+
// synchronous flush inside stop/complete.
|
|
204
|
+
pi.on("agent_settled", async (_event, ctx) => {
|
|
205
|
+
drainExecutionFlush(pi, ctx);
|
|
125
206
|
});
|
|
126
207
|
|
|
127
208
|
// -----------------------------------------------------------------------
|
|
128
209
|
// Execution loop: inject remaining checklist each turn, track markers.
|
|
129
210
|
// -----------------------------------------------------------------------
|
|
130
|
-
pi.on("before_agent_start", async () => {
|
|
211
|
+
pi.on("before_agent_start", async (_event, ctx) => {
|
|
212
|
+
drainExecutionFlush(pi, ctx);
|
|
213
|
+
await ensureExecutionModelActive(pi, ctx);
|
|
131
214
|
const content = executionContextMessage();
|
|
132
|
-
if (!content)
|
|
215
|
+
if (!content) {
|
|
216
|
+
if (!getExecution() && shouldTriggerPlanningCompaction(ctx)) {
|
|
217
|
+
requestPlanningCompaction(ctx);
|
|
218
|
+
}
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
133
221
|
return {
|
|
134
222
|
message: {
|
|
135
223
|
customType: "pi-plans-exec-context",
|
|
@@ -139,22 +227,17 @@ export default function piPlansExtension(pi: ExtensionAPI): void {
|
|
|
139
227
|
};
|
|
140
228
|
});
|
|
141
229
|
|
|
142
|
-
pi
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
if (changedIds.length > 0) {
|
|
154
|
-
recordExecutionCompletion(pi, ctx, changedIds);
|
|
155
|
-
}
|
|
156
|
-
if (getExecution() && isExecutionComplete()) {
|
|
157
|
-
completeExecution(pi, ctx);
|
|
230
|
+
registerExecutionTurnHandlers(pi, async (ctx) => {
|
|
231
|
+
if (!getExecution()) {
|
|
232
|
+
refreshPlanningCompactionCooldown(ctx);
|
|
233
|
+
if (consumePlanningCompactionResumeGuard(ctx)) {
|
|
234
|
+
if (consumePendingPanelSync()) syncExecutionPanel(ctx);
|
|
235
|
+
updateStatusWidget(ctx);
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
if (shouldTriggerPlanningCompaction(ctx)) {
|
|
239
|
+
requestPlanningCompaction(ctx);
|
|
240
|
+
}
|
|
158
241
|
}
|
|
159
242
|
// A busy-toggle during the previous turn deferred its re-render; the
|
|
160
243
|
// turn just ended, so this is the safe point to apply it.
|
|
@@ -200,6 +283,7 @@ export default function piPlansExtension(pi: ExtensionAPI): void {
|
|
|
200
283
|
lines.push(` ${item.done ? "☑" : "☐"} ${item.id}`);
|
|
201
284
|
}
|
|
202
285
|
}
|
|
286
|
+
lines.push(extensionStalenessLine());
|
|
203
287
|
ctx.ui.notify(lines.join("\n"), "info");
|
|
204
288
|
},
|
|
205
289
|
});
|
|
@@ -277,7 +361,7 @@ export default function piPlansExtension(pi: ExtensionAPI): void {
|
|
|
277
361
|
`${doneIds.length}/${execution.items.length} verifier item(s) already verified; their work stays. Remaining items return to planning.`,
|
|
278
362
|
);
|
|
279
363
|
if (!ok) return;
|
|
280
|
-
stopExecution(pi, ctx, "interrupted by /update-plan");
|
|
364
|
+
await stopExecution(pi, ctx, "interrupted by /update-plan");
|
|
281
365
|
}
|
|
282
366
|
|
|
283
367
|
// Return the run to planning so refinement rules and guards apply again.
|
|
@@ -322,7 +406,7 @@ export default function piPlansExtension(pi: ExtensionAPI): void {
|
|
|
322
406
|
if (focus) lines.push(`User-reported problems / refocus: ${focus}`);
|
|
323
407
|
lines.push(
|
|
324
408
|
"",
|
|
325
|
-
"Follow the original planning-skill contract for revisions: collect needed clarifications via ask_choice (one question at a time, recorded), apply evidence-based revisions only, then ask the next
|
|
409
|
+
"Follow the original planning-skill contract for revisions: collect needed clarifications via ask_choice (one question at a time, recorded), apply evidence-based revisions only, then ask the next merged accept/execute question (autoComplete: false — ✓ Accept & execute now / Accept, don't execute yet / another round) and call execute_plan pointing at the new version on accept.",
|
|
326
410
|
);
|
|
327
411
|
|
|
328
412
|
await pi.sendUserMessage(lines.join("\n"));
|
|
@@ -338,7 +422,7 @@ export default function piPlansExtension(pi: ExtensionAPI): void {
|
|
|
338
422
|
}
|
|
339
423
|
const ok = await ctx.ui.confirm("Stop execution?", "Remaining verifier items will be left unfinished.");
|
|
340
424
|
if (!ok) return;
|
|
341
|
-
stopExecution(pi, ctx, "stopped by user via /plans-stop");
|
|
425
|
+
await stopExecution(pi, ctx, "stopped by user via /plans-stop");
|
|
342
426
|
ctx.ui.notify("Execution stopped.", "info");
|
|
343
427
|
},
|
|
344
428
|
});
|
|
@@ -356,6 +440,10 @@ export default function piPlansExtension(pi: ExtensionAPI): void {
|
|
|
356
440
|
`${active.run_id}\nThe read-only guard lifts; committed artifacts stay in place.`,
|
|
357
441
|
);
|
|
358
442
|
if (!ok) return;
|
|
443
|
+
// Abandon must end execution first so the planning model is restored.
|
|
444
|
+
if (getExecution()) {
|
|
445
|
+
await stopExecution(pi, ctx, "run abandoned via /plans-abandon");
|
|
446
|
+
}
|
|
359
447
|
try {
|
|
360
448
|
setRunStatus(ctx.cwd, active.run_id, "abandoned");
|
|
361
449
|
ctx.ui.notify(`Run ${active.run_id} abandoned.`, "info");
|
|
@@ -370,6 +458,6 @@ export default function piPlansExtension(pi: ExtensionAPI): void {
|
|
|
370
458
|
// Session lifecycle
|
|
371
459
|
// -----------------------------------------------------------------------
|
|
372
460
|
pi.on("session_start", async (_event, ctx) => {
|
|
373
|
-
restoreFromSession(pi, ctx, ctx.sessionManager.getEntries() as unknown as Parameters<typeof restoreFromSession>[2]);
|
|
461
|
+
await restoreFromSession(pi, ctx, ctx.sessionManager.getEntries() as unknown as Parameters<typeof restoreFromSession>[2]);
|
|
374
462
|
});
|
|
375
463
|
}
|
package/package.json
CHANGED
|
@@ -59,7 +59,7 @@ Every user-facing planning or refinement question goes through the `ask_choice`
|
|
|
59
59
|
|
|
60
60
|
- `options`: ordered options, recommended option first with `recommended: true` (exactly one), each with the tradeoff that matters in `description`;
|
|
61
61
|
- do not add `Other` or `Auto-complete` yourself — the tool appends `Other…` second-last and `Auto-complete` last;
|
|
62
|
-
- pass `autoComplete: false` for the execution
|
|
62
|
+
- pass `autoComplete: false` for the merged accept/execute question — it contains the execution approval, so Auto-complete never appears there — and for any install waiver, publishing, deployment, merge, push, credential, or external-state question. Auto-complete may choose the recommended planning or refinement option only.
|
|
63
63
|
|
|
64
64
|
Answers are recorded automatically in the active run's `decisions.jsonl`. You must still maintain `DECISIONS.md` in the artifact directory (summary table of questions, options, answers, answer sources, open assumptions).
|
|
65
65
|
|
|
@@ -100,13 +100,13 @@ The execution loop parses `- [ ] \`VC-###\`` items and tracks `[DONE:VC-###]` ma
|
|
|
100
100
|
|
|
101
101
|
## Refinement
|
|
102
102
|
|
|
103
|
-
After each plan version, ask one
|
|
103
|
+
After each plan version, ask one merged accept/execute question via `ask_choice` with `autoComplete: false` — it contains the execution approval, so Auto-complete never appears. Options:
|
|
104
104
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
105
|
+
1. `✓ Accept PLAN_vN and execute it now` — mark the plan accepted (`plans set-status accepted`), then call the `execute_plan` tool.
|
|
106
|
+
2. `Accept PLAN_vN, don't execute yet` — mark accepted; resume later via `/plans-execute`.
|
|
107
|
+
3. `Run another round: <the level's default next refine mode>` — only while the level's default sequence is unfinished.
|
|
108
108
|
|
|
109
|
-
|
|
109
|
+
The recommended option follows the skill level's default sequence: while the default rounds are unfinished it is option 3's default next mode (`plan-small`: `Criticizer`; `plan-normal`: `Reviewer` then `Criticizer`; `plan-big`: three concurrent reviewers (`refine` with `reviewers: 3`) then `Criticizer`); once the default sequence is complete it is option 1.
|
|
110
110
|
|
|
111
111
|
If the user selects `Reviewer` or `Criticizer`, run the `refine` tool with the plan path and any focus. Reviewer output consolidates into `PLAN_vN_reviewer_comments.md` with findings IDs, severity, affected plan IDs, evidence, impact, recommended fix, and disposition. Revise the next plan only for findings accepted on evidence.
|
|
112
112
|
|
|
@@ -120,19 +120,13 @@ Present each criticizer question with `ask_choice` (one call per question, in th
|
|
|
120
120
|
|
|
121
121
|
### Round Lifecycle
|
|
122
122
|
|
|
123
|
-
A refinement round is complete when all reviewer outputs have returned or all criticizer questions have answers. In the same turn: consolidate, accept or reject each finding on evidence (the user may override any disposition), revise to `PLAN_v(N+1).md` when accepted items require it (copy, edit only the new version, update the revision ledger and verifier checklist), then immediately ask the next
|
|
123
|
+
A refinement round is complete when all reviewer outputs have returned or all criticizer questions have answers. In the same turn: consolidate, accept or reject each finding on evidence (the user may override any disposition), revise to `PLAN_v(N+1).md` when accepted items require it (copy, edit only the new version, update the revision ledger and verifier checklist), then immediately ask the next merged accept/execute question. Never end a turn merely because a round completed.
|
|
124
124
|
|
|
125
125
|
## Execution Handoff
|
|
126
126
|
|
|
127
|
-
|
|
127
|
+
When the user picks `✓ Accept PLAN_vN and execute it now` in the merged question, mark the plan accepted and call the `execute_plan` tool (or the user runs `/plans-execute`). It re-confirms with the user, then the extension enters execution mode:
|
|
128
128
|
|
|
129
|
-
|
|
130
|
-
2. `Stop after planning` — keep the plan artifact only.
|
|
131
|
-
3. `Other`.
|
|
132
|
-
|
|
133
|
-
On approval, call the `execute_plan` tool (or the user runs `/plans-execute`). It re-confirms with the user, then the extension enters execution mode:
|
|
134
|
-
|
|
135
|
-
- every agent turn is injected with the remaining verifier checklist and execution rules (ponytail discipline, minimum tests);
|
|
129
|
+
- every agent turn is injected with the remaining verifier checklist and execution rules (layered simplest implementation, no stopgaps, dependency and library discipline, minimum tests);
|
|
136
130
|
- the read-only guard lifts: full write access returns;
|
|
137
131
|
- the run status moves to `executing`, then `done` when the last `[DONE:VC-xxx]` marker lands;
|
|
138
132
|
- `/plans-stop` stops execution; `/plans` shows progress.
|
|
@@ -144,8 +138,8 @@ If the user declines, stay in planning (or stop, per their choice). Never start
|
|
|
144
138
|
Stop and return to the workflow if any of these happen:
|
|
145
139
|
|
|
146
140
|
- implementing before the approved execution handoff;
|
|
147
|
-
- running `refine` without first asking the
|
|
148
|
-
- ending a turn after a completed refinement round without asking the next
|
|
141
|
+
- running `refine` without first asking the merged accept/execute question, or before the role gates pass;
|
|
142
|
+
- ending a turn after a completed refinement round without asking the next merged accept/execute question;
|
|
149
143
|
- storing planning settings outside the target workspace's `.git/pi_plans/` state directory;
|
|
150
144
|
- asking multiple planning questions in one message, or asking them outside `ask_choice`;
|
|
151
145
|
- writing `PLAN_v1.md` before final scope confirmation;
|
|
@@ -70,7 +70,7 @@ Summarize the user's request in one paragraph.
|
|
|
70
70
|
|
|
71
71
|
## Execution Handoff Notes
|
|
72
72
|
|
|
73
|
-
State anything the executor should know, including order of work, files to avoid, and verification commands. The
|
|
73
|
+
State anything the executor should know, including order of work, files to avoid, and verification commands. The merged accept/execute question still requires explicit user approval (ask_choice with `autoComplete: false`, then the `execute_plan` tool) and must never be auto-completed. Once approved, the extension-managed execution loop injects the remaining checklist every turn and completes when every `[DONE:VC-xxx]` marker has landed — keep this section concise enough to serve as the executor's brief.
|
|
74
74
|
|
|
75
75
|
## Revision Ledger
|
|
76
76
|
|
|
@@ -126,7 +126,7 @@ When `mode` is `delegated-subagent`, the `refine` tool spawns a read-only `pi` s
|
|
|
126
126
|
- receives the full plan text and a review/criticism brief;
|
|
127
127
|
- returns its findings as the tool result (recorded in `subagents.jsonl` with name and model).
|
|
128
128
|
|
|
129
|
-
The main agent consolidates the results, records dispositions, revises the plan, and asks the next
|
|
129
|
+
The main agent consolidates the results, records dispositions, revises the plan, and asks the next merged accept/execute question — all in the same turn.
|
|
130
130
|
|
|
131
131
|
## Run State
|
|
132
132
|
|
|
@@ -20,7 +20,7 @@ Read `../../references/pi-planning-workflow.md` and `../../references/state-and-
|
|
|
20
20
|
2. `Stop after RCA` — keep the diagnosis only.
|
|
21
21
|
3. `Other` / 4. `Auto-complete` are added by the tool.
|
|
22
22
|
4. On opt-out, stop after the summary; do not write `PROBLEM_ANALYSIS.md`.
|
|
23
|
-
5. On opt-in (or `Auto-complete` choosing the recommendation), select the smallest fitting planning skill and follow that skill exactly: first-turn planning question, final scope confirmation, `PLAN_v1.md`, refinement, and the
|
|
23
|
+
5. On opt-in (or `Auto-complete` choosing the recommendation), select the smallest fitting planning skill and follow that skill exactly: first-turn planning question, final scope confirmation, `PLAN_v1.md`, refinement, and the merged accept/execute question (ask_choice with `autoComplete: false`) before calling the `execute_plan` tool.
|
|
24
24
|
|
|
25
25
|
## Level Selection
|
|
26
26
|
|
package/skills/plan-big/SKILL.md
CHANGED
|
@@ -17,7 +17,7 @@ Read `../../references/pi-planning-workflow.md` and `../../references/state-and-
|
|
|
17
17
|
- Ask at least 10 planning questions, one at a time; no maximum — stop only when the decision tree is genuinely resolved. Each via `ask_choice` (recommended option first; the tool adds `Other` second-last and `Auto-complete` last).
|
|
18
18
|
- Use web research during both brainstorming and refinement when outside facts, patterns, or ecosystem constraints matter, and cite sources in the plan.
|
|
19
19
|
- Ask the final scope confirmation, then write `PLAN_v1.md` per `../../references/plan-artifact-template.md`.
|
|
20
|
-
- After each plan version, ask the
|
|
20
|
+
- After each plan version, ask the merged accept/execute question via `ask_choice` with `autoComplete: false` — never run `refine` unless the user picked another round at that question. Default sequence: one `Reviewer` round as three concurrent independent reviewers (`refine` with `reviewers: 3`, consolidated by the main agent per the shared workflow), then one `Criticizer` round; afterwards the recommended option is `✓ Accept & execute now` in the merged accept/execute question. Beyond the default sequence, refine until convergence on high-priority findings, unresolved questions, or evidence gaps; surface at most five per round. Then the merged accept/execute question (ask_choice with `autoComplete: false`: ✓ Accept & execute now / Accept, don't execute yet / another round) and the `execute_plan` tool.
|
|
21
21
|
|
|
22
22
|
## Fit
|
|
23
23
|
|
|
@@ -17,7 +17,7 @@ Read `../../references/pi-planning-workflow.md` and `../../references/state-and-
|
|
|
17
17
|
- Ask 5 to 10 planning questions, one at a time, each via `ask_choice` (recommended option first; the tool adds `Other` second-last and `Auto-complete` last).
|
|
18
18
|
- Use web research whenever outside library behavior, ecosystem precedent, UX convention, protocol semantics, or compatibility affects the recommendation (websearch skill when installed; otherwise `curl`/`gh` via bash), and cite sources in the plan.
|
|
19
19
|
- Ask the final scope confirmation, then write `PLAN_v1.md` per `../../references/plan-artifact-template.md`.
|
|
20
|
-
- After each plan version, ask the
|
|
20
|
+
- After each plan version, ask the merged accept/execute question via `ask_choice` with `autoComplete: false` — never run `refine` unless the user picked another round at that question. Default sequence: one `Reviewer` round, then one `Criticizer` round; afterwards the recommended option is `✓ Accept & execute now` in the merged accept/execute question. Up to five rounds total, continuing only for high-priority findings or unresolved criticizer questions; surface at most five per round. Then the merged accept/execute question (ask_choice with `autoComplete: false`: ✓ Accept & execute now / Accept, don't execute yet / another round) and the `execute_plan` tool.
|
|
21
21
|
|
|
22
22
|
## Fit
|
|
23
23
|
|
|
@@ -16,7 +16,7 @@ Read `../../references/pi-planning-workflow.md` and `../../references/state-and-
|
|
|
16
16
|
- Inspect the target Git repo read-only before the first product question.
|
|
17
17
|
- Ask 1 to 3 planning questions, one at a time, each via `ask_choice` (recommended option first; the tool adds `Other` second-last and `Auto-complete` last).
|
|
18
18
|
- Ask the final scope confirmation, then write `PLAN_v1.md` under the artifact root (normally the configured workspace root, default `./docs/pi-plans/YYYY-MM-DD-topic/`) per `../../references/plan-artifact-template.md`.
|
|
19
|
-
- After each plan version, ask the
|
|
19
|
+
- After each plan version, ask the merged accept/execute question via `ask_choice` with `autoComplete: false` — never run `refine` unless the user picked another round at that question. Default: exactly one round, recommended mode `Criticizer`; afterwards the recommended option is `✓ Accept & execute now` in the merged accept/execute question (ask_choice with `autoComplete: false`: ✓ Accept & execute now / Accept, don't execute yet / another round), then the `execute_plan` tool.
|
|
20
20
|
|
|
21
21
|
## Fit
|
|
22
22
|
|
|
@@ -21,7 +21,7 @@ Read `../../references/pi-planning-workflow.md` and `../../references/state-and-
|
|
|
21
21
|
6. For every reference, produce a structured analysis artifact (manual structured read recorded in `REF_ANALYSIS.md`) before asking adoption questions.
|
|
22
22
|
7. For every reference after analysis, ask at least 3 ref-specific adoption questions via `ask_choice` before using its ideas in `PLAN_v1.md`; each based on downloaded content, recommended option first, `Other` second-last, `Auto-complete` last (the tool appends both).
|
|
23
23
|
8. Block rather than pad if fewer than 3 credible references exist, unless the user explicitly narrows the topic or waives the minimum. `Auto-complete` cannot grant this waiver.
|
|
24
|
-
9. Continue with big-plan depth: at least 10 planning questions, required web research during brainstorming and refinement (`refine` `reviewers: 3` reviewer round, then a criticizer round), no refinement limit, at most five high-priority comments or questions per refinement round. Then the
|
|
24
|
+
9. Continue with big-plan depth: at least 10 planning questions, required web research during brainstorming and refinement (`refine` `reviewers: 3` reviewer round, then a criticizer round), no refinement limit, at most five high-priority comments or questions per refinement round. Then the merged accept/execute question (ask_choice with `autoComplete: false`: ✓ Accept & execute now / Accept, don't execute yet / another round) and the `execute_plan` tool.
|
|
25
25
|
|
|
26
26
|
## REF_ANALYSIS.md
|
|
27
27
|
|