pi-plans 0.6.0 → 0.8.0
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/AGENTS.md +58 -0
- package/CONTRIBUTING.md +8 -15
- package/README.md +39 -37
- package/agents/execution-reviewer.md +40 -0
- package/agents/reviewer.md +12 -3
- package/index.ts +55 -58
- package/package.json +2 -1
- package/references/pi-planning-workflow.md +50 -60
- package/references/plan-artifact-template.md +81 -60
- package/references/state-and-config.md +60 -44
- package/scripts/bench/pi-adapter/pi_plans_bench.py +33 -22
- package/scripts/bench/pi-adapter/rpc_driver.mjs +4 -4
- package/scripts/run-tests.ts +12 -1
- package/scripts/validate.ts +39 -11
- package/skills/debug-and-plan/SKILL.md +3 -3
- package/skills/plan-big/SKILL.md +3 -3
- package/skills/plan-normal/SKILL.md +3 -3
- package/skills/plan-small/SKILL.md +4 -4
- package/skills/plan-with-refs/SKILL.md +6 -6
- package/skills/planning/SKILL.md +1 -1
- package/src/ask-form.ts +4 -4
- package/src/auditor.ts +227 -0
- package/src/auto-approve.ts +1 -1
- package/src/autocomplete.ts +19 -17
- package/src/code-graph/commands.ts +8 -3
- package/src/code-graph/community.ts +1 -1
- package/src/code-graph/paths.ts +1 -1
- package/src/code-graph/watch.ts +2 -2
- package/src/compaction.ts +3 -3
- package/src/config-command.ts +146 -73
- package/src/dashboard.ts +303 -0
- package/src/exec.ts +1185 -924
- package/src/global-state.ts +304 -0
- package/src/guard.ts +18 -19
- package/src/messaging.ts +44 -0
- package/src/plan.ts +421 -112
- package/src/query-hook.ts +4 -4
- package/src/refine-prompts.ts +12 -70
- package/src/refine-ui-helpers.ts +24 -5
- package/src/refine-ui-state.ts +1 -1
- package/src/refine-ui.ts +19 -3
- package/src/resume-command.ts +45 -129
- package/src/resume.ts +5 -1
- package/src/role-panels.ts +542 -0
- package/src/run-context.ts +3 -10
- package/src/staleness.ts +53 -0
- package/src/state.ts +273 -72
- package/src/subagent.ts +19 -29
- package/src/task-tool.ts +100 -0
- package/src/tasks.ts +223 -0
- package/src/thinking-levels.ts +67 -0
- package/src/ui-language.ts +7 -54
- package/src/workflow-state.ts +76 -58
- package/tests/analyze-refs.test.ts +35 -18
- package/tests/ask-choice-schema.test.ts +0 -12
- package/tests/ask-choice.test.ts +2 -49
- package/tests/ask-form-tool.test.ts +4 -5
- package/tests/ask-form.test.ts +2 -2
- package/tests/auditor.test.ts +210 -0
- package/tests/auto-approve.test.ts +7 -10
- package/tests/autocomplete.test.ts +8 -11
- package/tests/code-graph-apply-action.test.ts +2 -2
- package/tests/code-graph-commands.test.ts +2 -2
- package/tests/code-graph-index.test.ts +2 -2
- package/tests/code-graph-loop.e2e.test.ts +1 -1
- package/tests/code-graph-mutations.test.ts +1 -1
- package/tests/code-graph-rollback.test.ts +1 -1
- package/tests/code-graph-v05.test.ts +2 -2
- package/tests/compaction.test.ts +1 -1
- package/tests/config-command.test.ts +103 -100
- package/tests/dashboard.test.ts +402 -0
- package/tests/exec-lifecycle.test.ts +181 -115
- package/tests/exec-panel-lifecycle.test.ts +106 -251
- package/tests/exec-review-loop.test.ts +331 -0
- package/tests/exec.test.ts +771 -1706
- package/tests/execute-plan.test.ts +44 -19
- package/tests/extension-load.test.ts +48 -0
- package/tests/global-state.test.ts +371 -0
- package/tests/graph-aware-file-tools.test.ts +5 -5
- package/tests/guard.test.ts +1 -1
- package/tests/multi-run.test.ts +3 -103
- package/tests/plan.test.ts +139 -62
- package/tests/plans.test.ts +7 -79
- package/tests/refine-prompts.test.ts +20 -71
- package/tests/refine-resume.test.ts +27 -22
- package/tests/refine-ui.test.ts +6 -15
- package/tests/resume-lifecycle.test.ts +41 -22
- package/tests/resume.test.ts +39 -81
- package/tests/role-panels.test.ts +391 -0
- package/tests/run-context.test.ts +1 -1
- package/tests/run-ownership.test.ts +1 -1
- package/tests/stale-ctx.test.ts +218 -0
- package/tests/staleness.test.ts +76 -0
- package/tests/state.test.ts +155 -32
- package/tests/subagent-thinking.test.ts +65 -0
- package/tests/subagent-usage.test.ts +1 -1
- package/tests/task-tool.test.ts +61 -0
- package/tests/tasks.test.ts +142 -0
- package/tests/thinking-levels.test.ts +77 -0
- package/tests/ui-language.test.ts +2 -17
- package/tests/workflow-state.test.ts +73 -90
- package/tools/analyze-refs.ts +67 -32
- package/tools/ask-choice.ts +7 -53
- package/tools/code-graph.ts +2 -2
- package/tools/execute-plan.ts +55 -99
- package/tools/graph-aware-file-tools.ts +4 -10
- package/tools/plans.ts +41 -67
- package/tools/refine.ts +101 -164
- package/agents/criticizer.md +0 -18
- package/agents/executor.md +0 -26
- package/scripts/bench/pi-adapter/__pycache__/pi_plans_bench.cpython-312.pyc +0 -0
- package/src/panel.ts +0 -473
- package/src/termination-prompt.ts +0 -73
- package/tests/goal-wait.test.ts +0 -269
- package/tests/panel-i-zero.test.ts +0 -420
- package/tests/panel.test.ts +0 -355
package/tools/plans.ts
CHANGED
|
@@ -8,9 +8,6 @@ import { lintPlanIntoNotices } from "../src/state.ts";
|
|
|
8
8
|
import { getExecution, markPrePlanCompactPending, refreshUiLanguage } from "../src/exec.ts";
|
|
9
9
|
import { loadVccSettings, scaffoldVccSettings } from "../src/compaction.ts";
|
|
10
10
|
import {
|
|
11
|
-
applyCompleted,
|
|
12
|
-
applyImplementationReviewConfigured,
|
|
13
|
-
applyImplementationRoundFinished,
|
|
14
11
|
applyPlanWritten,
|
|
15
12
|
applyReviewConsolidated,
|
|
16
13
|
createCheckpoint,
|
|
@@ -43,11 +40,12 @@ import {
|
|
|
43
40
|
setRefsRoot,
|
|
44
41
|
setRunStatus,
|
|
45
42
|
setRole,
|
|
46
|
-
|
|
43
|
+
showStateView,
|
|
47
44
|
startRun,
|
|
48
45
|
StateError,
|
|
49
46
|
VALID_RUN_STATUSES,
|
|
50
47
|
} from "../src/state.ts";
|
|
48
|
+
import { messaging } from "../src/messaging.ts";
|
|
51
49
|
|
|
52
50
|
const PlansParams = Type.Object({
|
|
53
51
|
action: StringEnum(
|
|
@@ -77,25 +75,31 @@ const PlansParams = Type.Object({
|
|
|
77
75
|
requestText: Type.Optional(Type.String({ description: "start-run: original user request text" })),
|
|
78
76
|
tag: Type.Optional(Type.String({ description: "set-language: BCP47 tag, e.g. zh-Hans, en" })),
|
|
79
77
|
languageSource: Type.Optional(StringEnum(["user", "auto"] as const)),
|
|
80
|
-
artifactRoot: Type.Optional(Type.String({ description: "set-artifact-root: planning docs root, e.g.
|
|
78
|
+
artifactRoot: Type.Optional(Type.String({ description: "set-artifact-root: planning docs root, e.g. ./.git/pi-plans/plans" })),
|
|
81
79
|
artifactRootSource: Type.Optional(StringEnum(["user", "auto"] as const)),
|
|
82
80
|
refsRoot: Type.Optional(Type.String({ description: "set-refs-root: reference downloads root, e.g. .git/pi-plans/refs" })),
|
|
83
81
|
refsRootSource: Type.Optional(StringEnum(["user", "auto"] as const)),
|
|
84
82
|
enabled: Type.Optional(Type.Boolean({ description: "set-graph-enabled: enable/disable the code graph" })),
|
|
85
83
|
message: Type.Optional(Type.String({ description: "final-commit: commit message body" })),
|
|
86
|
-
role: Type.Optional(StringEnum(["reviewer"
|
|
84
|
+
role: Type.Optional(StringEnum(["reviewer"] as const)),
|
|
87
85
|
mode: Type.Optional(StringEnum(["delegated-subagent", "current-session"] as const)),
|
|
88
86
|
modelSelector: Type.Optional(
|
|
89
|
-
Type.String({ description: "set-role: exact provider/model selector
|
|
87
|
+
Type.String({ description: "set-role: exact provider/model selector; 'inherit' resets BOTH the selector and the confirmation" }),
|
|
88
|
+
),
|
|
89
|
+
thinkingLevel: Type.Optional(
|
|
90
|
+
StringEnum(["default", "off", "minimal", "low", "medium", "high", "xhigh", "max"] as const, {
|
|
91
|
+
description:
|
|
92
|
+
"set-role: reviewer subagent thinking level in the GLOBAL config; 'default' (null) omits --thinking so the child pi resolves its own default chain; changing modelSelector without this resets the level",
|
|
93
|
+
}),
|
|
90
94
|
),
|
|
91
95
|
confirmed: Type.Optional(
|
|
92
|
-
Type.Boolean({ description: "set-role: stamp confirmed_at=now
|
|
96
|
+
Type.Boolean({ description: "set-role: stamp confirmed_at=now; requires an exact selector for delegated-subagent" }),
|
|
93
97
|
),
|
|
94
98
|
resetConfirmation: Type.Optional(Type.Boolean({ description: "set-role: clear confirmed_at to re-ask" })),
|
|
95
99
|
runId: Type.Optional(Type.String()),
|
|
96
100
|
status: Type.Optional(
|
|
97
101
|
StringEnum(
|
|
98
|
-
["planning", "accepted", "executing", "stopped", "abandoned", "done"] as const,
|
|
102
|
+
["planning", "accepted", "executing", "verifying", "stopped", "abandoned", "done"] as const,
|
|
99
103
|
{ description: "set-status: run lifecycle status" },
|
|
100
104
|
),
|
|
101
105
|
),
|
|
@@ -121,7 +125,7 @@ const PlansParams = Type.Object({
|
|
|
121
125
|
),
|
|
122
126
|
subagent: Type.Optional(
|
|
123
127
|
Type.Object({
|
|
124
|
-
role: StringEnum(["reviewer", "
|
|
128
|
+
role: StringEnum(["reviewer", "ref-analyst"] as const),
|
|
125
129
|
name: Type.String(),
|
|
126
130
|
model: Type.Optional(Type.String()),
|
|
127
131
|
sessionDir: Type.Optional(Type.String()),
|
|
@@ -130,41 +134,16 @@ const PlansParams = Type.Object({
|
|
|
130
134
|
checkpoint: Type.Optional(
|
|
131
135
|
Type.Object({
|
|
132
136
|
/** Whitelisted semantic transition (I-003). State-machine validated; approval cannot be forged here. */
|
|
133
|
-
transition: StringEnum(
|
|
134
|
-
[
|
|
135
|
-
"plan-written",
|
|
136
|
-
"review-consolidated",
|
|
137
|
-
"implementation-review-configured",
|
|
138
|
-
"implementation-round-finished",
|
|
139
|
-
"completed",
|
|
140
|
-
] as const,
|
|
141
|
-
),
|
|
137
|
+
transition: StringEnum(["plan-written", "review-consolidated"] as const),
|
|
142
138
|
/** plan-written: absolute or workdir-relative PLAN_vN.md path. */
|
|
143
139
|
planPath: Type.Optional(Type.String()),
|
|
144
140
|
/** review-consolidated: round id + optional disposition artifact (run-dir relative). */
|
|
145
141
|
roundId: Type.Optional(Type.String()),
|
|
146
142
|
dispositionArtifact: Type.Optional(Type.String()),
|
|
147
|
-
/** implementation-review-configured: the serialized termination condition chosen by the user. */
|
|
148
|
-
terminationCondition: Type.Optional(Type.String()),
|
|
149
|
-
/** implementation-review-configured: concurrent reviewers per round (1-3);
|
|
150
|
-
* omit to keep the skill-level default (plan-big / plan-with-refs → 3, others → 1). */
|
|
151
|
-
reviewerCount: Type.Optional(Type.Integer({ minimum: 1, maximum: 3 })),
|
|
152
|
-
/** completed: non-empty evidence that the termination condition is satisfied. */
|
|
153
|
-
evidence: Type.Optional(Type.String()),
|
|
154
143
|
}),
|
|
155
144
|
),
|
|
156
145
|
});
|
|
157
146
|
|
|
158
|
-
// Module-level reference so the start-run action can append a session entry
|
|
159
|
-
// (pi-plans-run-start) at the moment the planning run begins. The ExtensionAPI
|
|
160
|
-
// itself is not in scope for `startRun`, mirroring `setCurrentApi` in
|
|
161
|
-
// tools/execute-plan.ts.
|
|
162
|
-
let runStartAppender: ((runId: string, artifactDir: string) => void) | null = null;
|
|
163
|
-
|
|
164
|
-
export function setRunStartAppender(appender: ((runId: string, artifactDir: string) => void) | null): void {
|
|
165
|
-
runStartAppender = appender;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
147
|
/** plans action final-commit: gate on code-graph drift (zero pending +
|
|
169
148
|
* invariants (a)/(b) clean), then `git add -A` and commit the plan delivery.
|
|
170
149
|
* A clean tree is a safe no-op. Returns a machine-readable result. */
|
|
@@ -238,13 +217,10 @@ export function recordCheckpointTransition(
|
|
|
238
217
|
workdir: string,
|
|
239
218
|
runIdArg: string | undefined,
|
|
240
219
|
checkpoint: {
|
|
241
|
-
transition: "plan-written" | "review-consolidated"
|
|
220
|
+
transition: "plan-written" | "review-consolidated";
|
|
242
221
|
planPath?: string;
|
|
243
222
|
roundId?: string;
|
|
244
223
|
dispositionArtifact?: string;
|
|
245
|
-
terminationCondition?: string;
|
|
246
|
-
reviewerCount?: number;
|
|
247
|
-
evidence?: string;
|
|
248
224
|
},
|
|
249
225
|
): WorkflowCheckpoint {
|
|
250
226
|
const runId =
|
|
@@ -270,33 +246,15 @@ export function recordCheckpointTransition(
|
|
|
270
246
|
applyReviewConsolidated(cp, checkpoint.roundId!, checkpoint.dispositionArtifact),
|
|
271
247
|
);
|
|
272
248
|
}
|
|
273
|
-
case "implementation-review-configured": {
|
|
274
|
-
if (!checkpoint.terminationCondition) {
|
|
275
|
-
throw new StateError("implementation-review-configured requires terminationCondition");
|
|
276
|
-
}
|
|
277
|
-
return mutateCheckpoint(workdir, runId, (cp) =>
|
|
278
|
-
applyImplementationReviewConfigured(cp, checkpoint.terminationCondition!, checkpoint.reviewerCount),
|
|
279
|
-
);
|
|
280
|
-
}
|
|
281
|
-
case "implementation-round-finished": {
|
|
282
|
-
return mutateCheckpoint(workdir, runId, (cp) => applyImplementationRoundFinished(cp));
|
|
283
|
-
}
|
|
284
|
-
case "completed": {
|
|
285
|
-
if (!checkpoint.evidence) throw new StateError("completed requires evidence");
|
|
286
|
-
return mutateCheckpoint(workdir, runId, (cp) => applyCompleted(cp, checkpoint.evidence!));
|
|
287
|
-
}
|
|
288
249
|
}
|
|
289
250
|
}
|
|
290
251
|
|
|
291
|
-
export function registerPlansTool(
|
|
292
|
-
|
|
293
|
-
pi.appendEntry("pi-plans-run-start", { runId, artifactDir });
|
|
294
|
-
});
|
|
295
|
-
pi.registerTool({
|
|
252
|
+
export function registerPlansTool(ext: ExtensionAPI): void {
|
|
253
|
+
ext.registerTool({
|
|
296
254
|
name: "plans",
|
|
297
255
|
label: "Plans",
|
|
298
256
|
description:
|
|
299
|
-
"Manage pi-plans planning state in the target workspace: init/show config, set language and planning docs root plus reviewer
|
|
257
|
+
"Manage pi-plans planning state in the target workspace: init/show config, set language and planning docs root plus the reviewer role and the code-graph enabled flag, start planning runs, record decisions/refs/subagents, and update run status. Multiple concurrent runs per workdir are supported (registry-derived from runs/; sessions bind to their run). State lives in .git/pi-plans/ inside the resolved git common dir. Actions: init, show, set-language, set-artifact-root, set-refs-root, set-graph-enabled, set-role, start-run, set-status, final-commit, record-decision, record-ref, record-subagent.",
|
|
300
258
|
promptSnippet: "Manage pi-plans planning state, runs, and ledgers",
|
|
301
259
|
parameters: PlansParams,
|
|
302
260
|
|
|
@@ -317,10 +275,15 @@ export function registerPlansTool(pi: ExtensionAPI): void {
|
|
|
317
275
|
break;
|
|
318
276
|
}
|
|
319
277
|
case "show": {
|
|
320
|
-
const
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
278
|
+
const view = showStateView(workdir);
|
|
279
|
+
result = {
|
|
280
|
+
config: view.config,
|
|
281
|
+
stateRoot: view.stateRoot,
|
|
282
|
+
reviewer: view.reviewer,
|
|
283
|
+
globalConfigPath: view.globalConfigPath,
|
|
284
|
+
notices: view.notices,
|
|
285
|
+
};
|
|
286
|
+
if (view.config.graph_enabled === null) {
|
|
324
287
|
result = {
|
|
325
288
|
...(result as Record<string, unknown>),
|
|
326
289
|
hint: "graph_enabled is null (never asked). Ask the user once via ask_choice, then persist with plans (action: set-graph-enabled, enabled: true|false).",
|
|
@@ -369,10 +332,17 @@ export function registerPlansTool(pi: ExtensionAPI): void {
|
|
|
369
332
|
role: params.role,
|
|
370
333
|
mode: params.mode,
|
|
371
334
|
modelSelector: params.modelSelector,
|
|
335
|
+
thinkingLevel: params.thinkingLevel,
|
|
372
336
|
confirmed: params.confirmed,
|
|
373
337
|
resetConfirmation: params.resetConfirmation,
|
|
374
338
|
});
|
|
375
|
-
result = {
|
|
339
|
+
result = {
|
|
340
|
+
global: updated.global,
|
|
341
|
+
globalRoot: updated.globalRoot,
|
|
342
|
+
notices: updated.notices,
|
|
343
|
+
config: updated.config,
|
|
344
|
+
stateRoot: updated.stateRoot,
|
|
345
|
+
};
|
|
376
346
|
break;
|
|
377
347
|
}
|
|
378
348
|
case "start-run": {
|
|
@@ -383,8 +353,11 @@ export function registerPlansTool(pi: ExtensionAPI): void {
|
|
|
383
353
|
topic: params.topic,
|
|
384
354
|
skill: params.skill,
|
|
385
355
|
requestText: params.requestText,
|
|
356
|
+
// Append the run-start session entry with this call's ctx —
|
|
357
|
+
// never a registration-time capture (stale after session
|
|
358
|
+
// replacement).
|
|
386
359
|
onStart: (run) => {
|
|
387
|
-
|
|
360
|
+
messaging().appendEntry("pi-plans-run-start", { runId: run.run_id, artifactDir: run.artifact_dir });
|
|
388
361
|
},
|
|
389
362
|
});
|
|
390
363
|
// I-002: attribute this session's work to the run it started.
|
|
@@ -454,3 +427,4 @@ export function registerPlansTool(pi: ExtensionAPI): void {
|
|
|
454
427
|
},
|
|
455
428
|
});
|
|
456
429
|
}
|
|
430
|
+
|