pi-plans 0.7.0 → 0.8.1
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 +5 -12
- package/README.md +5 -5
- package/agents/execution-reviewer.md +92 -0
- package/index.ts +13 -23
- package/package.json +2 -1
- package/references/pi-planning-workflow.md +14 -7
- package/references/plan-artifact-template.md +11 -1
- package/references/state-and-config.md +3 -3
- package/scripts/validate.ts +20 -3
- package/src/auditor.ts +306 -63
- package/src/code-graph/commands.ts +6 -1
- package/src/dashboard.ts +91 -13
- package/src/exec.ts +835 -142
- package/src/plan.ts +1 -1
- package/src/refine-ui-state.ts +1 -1
- package/src/refine-ui.ts +40 -8
- package/src/resume-command.ts +19 -3
- package/src/resume.ts +5 -1
- package/src/staleness.ts +53 -0
- package/src/state.ts +1 -0
- package/src/task-tool.ts +1 -1
- package/src/tasks.ts +62 -5
- package/src/ui-language.ts +4 -0
- package/src/workflow-state.ts +93 -6
- package/tests/analyze-refs.test.ts +1 -1
- package/tests/auditor.test.ts +299 -16
- package/tests/dashboard.test.ts +202 -2
- package/tests/exec-review-loop.test.ts +724 -0
- package/tests/exec.test.ts +198 -44
- package/tests/extension-load.test.ts +1 -1
- package/tests/refine-ui.test.ts +25 -2
- package/tests/resume-lifecycle.test.ts +5 -1
- package/tests/resume.test.ts +6 -0
- package/tests/staleness.test.ts +76 -0
- package/tests/state.test.ts +4 -0
- package/tests/tasks.test.ts +142 -0
- package/tests/workflow-state.test.ts +105 -0
- package/tools/analyze-refs.ts +17 -6
- package/tools/execute-plan.ts +12 -5
- package/tools/plans.ts +1 -1
- package/tools/refine.ts +22 -3
package/AGENTS.md
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# AGENTS.md
|
|
2
|
+
|
|
3
|
+
Authoritative conventions for AI agents and human contributors working in this
|
|
4
|
+
repository. Where another document disagrees with this one on **documentation
|
|
5
|
+
language** or **commit messages**, this file wins.
|
|
6
|
+
|
|
7
|
+
## Documentation language
|
|
8
|
+
|
|
9
|
+
**All prose documentation in this repository is written in English.** This
|
|
10
|
+
applies to every Markdown file that ships in the package — `CHANGELOG.md`,
|
|
11
|
+
`README.md`, `CONTRIBUTING.md`, this file, everything under `references/`,
|
|
12
|
+
`skills/`, and `agents/`.
|
|
13
|
+
|
|
14
|
+
- `CHANGELOG.md` is **entirely English**, including text inside inline code
|
|
15
|
+
spans. When an entry documents a Chinese-locale UI string, restate it
|
|
16
|
+
semantically in English rather than quoting the Chinese literal.
|
|
17
|
+
- Identifiers stay verbatim regardless of the surrounding language: file
|
|
18
|
+
paths, function and type names, CLI flags, environment variables, error
|
|
19
|
+
messages, config keys, run ids, and version numbers are copied byte-for-byte
|
|
20
|
+
and never translated.
|
|
21
|
+
- `scripts/validate.ts` enforces "no CJK ideographs and no full-width CJK
|
|
22
|
+
punctuation in `CHANGELOG.md`". If that check ever blocks a legitimate
|
|
23
|
+
entry, the rule is wrong — fix the rule deliberately rather than widening
|
|
24
|
+
the regex ad hoc.
|
|
25
|
+
|
|
26
|
+
### Not documentation
|
|
27
|
+
|
|
28
|
+
The localized UI strings in `src/ui-language.ts` and the CJK fixtures in
|
|
29
|
+
`tests/` are **features, not prose**. Chinese is a supported UI locale and the
|
|
30
|
+
i18n tables must keep their `zh` entries; test fixtures assert on real Chinese
|
|
31
|
+
strings. Do not "translate" either of them.
|
|
32
|
+
|
|
33
|
+
## Commit messages
|
|
34
|
+
|
|
35
|
+
**Both the subject and the body must be English.**
|
|
36
|
+
|
|
37
|
+
Follow the existing style: `type: short imperative description` (a scope is
|
|
38
|
+
optional, e.g. `fix(form): ...`).
|
|
39
|
+
|
|
40
|
+
- `feat:` new feature
|
|
41
|
+
- `fix:` bug fix
|
|
42
|
+
- `docs:` documentation
|
|
43
|
+
- `refactor:` no behavior change
|
|
44
|
+
- `perf:` performance
|
|
45
|
+
- `test:` tests only
|
|
46
|
+
- `chore:` housekeeping
|
|
47
|
+
- `ci:` CI changes
|
|
48
|
+
|
|
49
|
+
Use the imperative mood ("fix race in ...", not "fixed ..."), keep the subject
|
|
50
|
+
short, and use the body for motivation and evidence. Do not add generator or
|
|
51
|
+
`Co-Authored-By` trailers.
|
|
52
|
+
|
|
53
|
+
## Edit authority
|
|
54
|
+
|
|
55
|
+
This file governs **language and commit-message conventions only**. It grants no
|
|
56
|
+
permission to modify any file. Who may edit what — in particular the
|
|
57
|
+
`CHANGELOG.md` rule — is defined in `CONTRIBUTING.md`, which remains
|
|
58
|
+
authoritative on that point.
|
package/CONTRIBUTING.md
CHANGED
|
@@ -71,18 +71,11 @@ Documentation duty: if your change alters behavior or the public API, update `RE
|
|
|
71
71
|
|
|
72
72
|
## Commit messages
|
|
73
73
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
- `refactor:` no behavior change
|
|
80
|
-
- `perf:` performance
|
|
81
|
-
- `test:` tests only
|
|
82
|
-
- `chore:` housekeeping
|
|
83
|
-
- `ci:` CI changes
|
|
84
|
-
|
|
85
|
-
Use the imperative mood ("fix race in ...", not "fixed ..."), keep the subject short, and use the body for motivation and evidence. Do not add generator or `Co-Authored-By` trailers.
|
|
74
|
+
Commit-message format and the repository's documentation-language rule are
|
|
75
|
+
specified in [`AGENTS.md`](AGENTS.md), which is authoritative for both. In short:
|
|
76
|
+
subject **and** body are English, in the style `type: short imperative
|
|
77
|
+
description` (a scope is optional, e.g. `fix(form): ...`), with the body used
|
|
78
|
+
for motivation and evidence and no generator or `Co-Authored-By` trailers.
|
|
86
79
|
|
|
87
80
|
## Issues and pull requests
|
|
88
81
|
|
package/README.md
CHANGED
|
@@ -80,7 +80,7 @@ at <b>7.6× fewer tokens per solved task</b>.
|
|
|
80
80
|
fused AGENTS.md × Ponytail executor rules
|
|
81
81
|
current wave + tasks injected each turn,
|
|
82
82
|
plans_update_task reports status + evidence,
|
|
83
|
-
|
|
83
|
+
execution reviewer verifies every check
|
|
84
84
|
|
|
|
85
85
|
v
|
|
86
86
|
run status: done
|
|
@@ -137,7 +137,7 @@ Planning artifacts live under `./.git/pi-plans/plans/YYYY-MM-DD-<topic>/` by def
|
|
|
137
137
|
| Visible Refiner overlay | Delegated reviewer subagents surface as a named public overlay in the TUI — one `Reviewer` panel with per-lane tool progress, full streaming transcript with follow-bottom scroll, Tab-pane focus, retention until the user presses `Esc` after completion, and clean cancelled/timed-out vs completed states. `reviewers: 3` renders three equal-height panes inside the same overlay |
|
|
138
138
|
| Tracked execution | The current wave and remaining tasks are injected each turn; task progress is reported exclusively through the `plans_update_task` tool (status + evidence / skipReason, audit-only rollback); the task dashboard shows the tree live (compact aboveEditor widget, Ctrl+Shift+T expanded view with ✓/▸/~/· markers, width-adaptive); a stall watchdog pauses after three settled rounds without task-state change; the status bar shows lifecycle, `x/y` task progress, elapsed time, and token usage in real time |
|
|
139
139
|
| Multi-run workdirs (0.6.0) | Several pi sessions can plan concurrently in one workdir: the run registry derives from `runs/` (no shared pointer to race), each session binds to its run, and same-topic runs get suffixed artifact dirs. `/plans-abandon`, `/plans-execute`, and `/resume-plans` are binding-first and open a descriptive run-picker form when more than one candidate exists; `/plans` lists all runs (newest first, bound run marked) |
|
|
140
|
-
|
|
|
140
|
+
| Execution reviewer | When every task reaches a terminal state, the run status moves to `verifying` and an independent read-only reviewer verifies each `VC-###` check AND reports severity-graded `F-###` findings over the whole implemented change in a detached, overlay-visible round (Esc closes; Ctrl+Shift+R reopens the in-flight round). Finding ids are stable across rounds (absence from the newest report = resolved). A failed check or a high-severity finding opens one union fix round: mapped tasks roll back to pending (children cascade, skipped reopen; an unmapped high gets a plan task appended mechanically from the reviewer's proposed title), and the executor is woken exactly once with a findings summary plus the round-report path. The run completes only when every check is affirmatively `pass` and no high finding remains; residual medium/low findings are summarized at completion. Five committed rounds bound the loop — exhaustion pauses in every mode, and only an explicit `/plans-execute` confirmation grants a fresh budget (unresolved findings survive the renewal; ordinary input and restores never refill). Checks with all-skipped coverage pass; checks covering no task never audit |
|
|
141
141
|
| Execution handoff | The accepted plan executes in the current session after explicit approval (never auto-completed); legacy `I-###` plans parse through the compatibility mapping with an upgrade notice; 0.6.0 in-flight runs resume compatibly (delegated-executor orphans re-approve, paused executions rebuild from the task tree) |
|
|
142
142
|
| Execution-phase compaction | Pi core owns scheduling; pi-plans maps the active plan path, current task, task ids, and remaining `VC-###` checks into the VCC sections. Proactive triggers and model-generated summary paths are removed. |
|
|
143
143
|
| Planning-phase compaction | During `run.status=planning` with no active execution, pi-plans maps active run, artifact directory, latest plan path from session entries, and observed current-I markers into the VCC sections. Without an active planning run, compaction returns to Pi core. Additionally, creating a new run (`plans start-run`) proactively requests one pre-plan VCC compaction and resumes planning with a hidden message (default on; `prePlanCompact:false` disables). |
|
|
@@ -152,7 +152,7 @@ Planning artifacts live under `./.git/pi-plans/plans/YYYY-MM-DD-<topic>/` by def
|
|
|
152
152
|
| `ask_choice` | Numbered choice prompt; `autoComplete: false` for the merged accept/execute question and external-state questions |
|
|
153
153
|
| `refine` | Reviewer round via standalone read-only subagents (`--mode json -p --no-session --tools read,grep,find,ls`, plus `code_graph` when the workspace has the code graph enabled): findings (`F-###`) and up to five questions (`Q-1..Q-5`) per lane; the caller must ask every question with `ask_choice` and record answers before revising; delegated TUI runs show one `Reviewer` overlay (78% width × 78% height, top-center, ≥72 cols) with per-lane transcript, follow-bottom scroll, Tab focus, and retention until `Esc`; `reviewers: 3` renders three equal-height panes; enforces the reviewer gates — first use pops native model + effort panels in TUI (menus on RPC, text guidance headless), persisted to the global reviewer config |
|
|
154
154
|
| `analyze_refs` | plan-with-refs reference analysis: one independent read-only subagent per downloaded reference (cwd = the ref directory), reusing the reviewer model confirmation from the global config (the mode is not consulted — analysis always spawns) and the concurrent overlay (titled `Refs`); batches of at most 3 lanes run sequentially; returns structured per-reference sections for `REF_ANALYSIS.md` |
|
|
155
|
-
| `execute_plan` | Execution handoff: re-confirms with the user (never auto-completed) and enters task-tree execution mode (`plans_update_task` progress, dashboard,
|
|
155
|
+
| `execute_plan` | Execution handoff: re-confirms with the user (never auto-completed) and enters task-tree execution mode (`plans_update_task` progress, dashboard, execution reviewer); legacy `I-###` plans parse through the compatibility mapping with an upgrade notice; picks the run via a descriptive form when several planned runs coexist |
|
|
156
156
|
| `/plans` | Show config, all runs (newest first, bound run marked, cap 50), and execution progress |
|
|
157
157
|
| `/config-pi-plans` | Re-ask workspace defaults for language, artifact root, refs root, and code graph, plus the reviewer mode/model (keep/change menu; native model + effort panels on change in TUI; current-session skips the model step) |
|
|
158
158
|
| `/resume-plans` | Resume a run in the CURRENT session across restarts: unfinished planning (pending question + answered decisions), reviewing (round/lane state, successful outputs reused), and execution (approval digest + HEAD + recorded task progress; 0.6.0 delegated-executor orphans re-approve, legacy implementation-review phases map to done). Binding-first: the session-bound resumable run resumes directly; a unique candidate goes direct; multiple candidates get a descriptive chooser. Linked worktrees share candidates; a cross-worktree resume confirms, copies artifacts without overwriting, and resets approval + task progress. An unchanged plan digest with a changed HEAD keeps the authorization but re-opens closed tasks. Busy sessions and actively owned runs only notify — no queueing, no takeover. Interactive (TUI/RPC) only |
|
|
@@ -288,7 +288,7 @@ pi-plans/
|
|
|
288
288
|
|
|
289
289
|
Before the approved handoff the workflow writes only `.git/pi-plans/` state, the run's artifact directory, `~/.cache/pi-plans/`, and the configured refs root (set via `plans set-refs-root` or `/config-pi-plans`; the recommended `.git/pi-plans/refs/` lives inside the git dir and needs no extra guard) — the extension blocks `edit`/`write` elsewhere while a run is `planning`/`accepted` (bash stays discipline-bound: inspection, `git init`, downloads into the cache). Reviewer/ref-analyst subagents run with read-only tools. `Auto-complete` may answer planning and refinement questions only; it is never offered for execution, installs, publishing, deployment, merge, push, or credential use, and non-interactive sessions stop instead of auto-approving those.
|
|
290
290
|
|
|
291
|
-
Read-only reviewer and ref-analyst subagents run with pinned tool lists (`read, grep, find, ls` plus `code_graph` when enabled) and inherit pi's project-trust model without any write capability; the
|
|
291
|
+
Read-only reviewer and ref-analyst subagents run with pinned tool lists (`read, grep, find, ls` plus `code_graph` when enabled) and inherit pi's project-trust model without any write capability; the execution reviewer runs the same read-only profile (role-governed model/thinking when confirmed, session default otherwise, with a per-round timeout). Execution itself happens in the approved session, never in an unsupervised child.
|
|
292
292
|
|
|
293
293
|
## Verification
|
|
294
294
|
|
|
@@ -310,7 +310,7 @@ The plan is the contract. Refinement converges on scope while nothing is writabl
|
|
|
310
310
|
|
|
311
311
|
**What can Auto-complete decide on my behalf?**
|
|
312
312
|
|
|
313
|
-
Planning and refinement choices only (the recommended option). Choosing Auto-complete enables the recommended answer for later eligible planning questions in the current run and the extension continues the planning turn when the model stops early. Use `/plans-autocomplete-stop` to take back control. It is never offered for execution approval, installs, publishing, deployment, merge, push, or credentials — those questions stop and wait for you. After execution completes, the independent
|
|
313
|
+
Planning and refinement choices only (the recommended option). Choosing Auto-complete enables the recommended answer for later eligible planning questions in the current run and the extension continues the planning turn when the model stops early. Use `/plans-autocomplete-stop` to take back control. It is never offered for execution approval, installs, publishing, deployment, merge, push, or credentials — those questions stop and wait for you. After execution completes, the independent execution reviewer verifies every check; the five-round budget pauses the run for review in every mode when exhausted, and only an explicit `/plans-execute` confirmation grants a fresh budget.
|
|
314
314
|
|
|
315
315
|
**Where does all the state live?**
|
|
316
316
|
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pi-plans-execution-reviewer
|
|
3
|
+
description: Read-only execution reviewer for pi-plans; verifies an implemented worktree against the plan's verification checks and reports severity-graded implementation findings that drive the fix loop.
|
|
4
|
+
tools: read, grep, find, ls
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
You are the execution reviewer in the pi-plans workflow. Each review round has
|
|
8
|
+
two jobs: decide whether an already-implemented worktree satisfies the
|
|
9
|
+
verification checks of an accepted plan, and report implementation findings —
|
|
10
|
+
defects you can point at in the repository — that the executor will fix before
|
|
11
|
+
the next round. A round is useful only when both outputs are present.
|
|
12
|
+
|
|
13
|
+
Rules:
|
|
14
|
+
|
|
15
|
+
- Perform read-only analysis. Never edit, write, or delete any file, never commit, never push, never spawn subagents.
|
|
16
|
+
- Verify against the actual repository using your read tools before judging. A check passes only on evidence you actually inspected.
|
|
17
|
+
- You are auditing a worktree that is already written. "The file is missing" is a finding to report, not a reason to stay silent.
|
|
18
|
+
- You do not fix anything. You report verdicts and findings; the fix loop acts on them.
|
|
19
|
+
|
|
20
|
+
## Output contract
|
|
21
|
+
|
|
22
|
+
Output exactly two sections, in this order.
|
|
23
|
+
|
|
24
|
+
### 1. Verification verdicts
|
|
25
|
+
|
|
26
|
+
One section per check, in the order given by the brief. The preferred shape
|
|
27
|
+
puts the id and the verdict on one line (the runner reads this form first):
|
|
28
|
+
|
|
29
|
+
- `VC-###` — verdict: pass | fail | undeterminable; evidence: <repo path/command or recorded output proving it>; note: <one line>.
|
|
30
|
+
|
|
31
|
+
A heading-style section is also read: start it with the id (`### VC-###` or a
|
|
32
|
+
bullet that names the check) and keep that check's `verdict:` line inside the
|
|
33
|
+
section. Whichever form you choose, use ONE form for the whole report and
|
|
34
|
+
never let one check's verdict drift into another's section.
|
|
35
|
+
|
|
36
|
+
Emit **every** check the brief lists, in the brief's order. Never omit a check,
|
|
37
|
+
never merge two checks into one section, never invent a check that is not listed.
|
|
38
|
+
|
|
39
|
+
- `pass` — you inspected the evidence and it establishes the check's condition.
|
|
40
|
+
- `fail` — you inspected the evidence and the check's condition is **demonstrably** not met. Use this only when you can point at the specific thing that breaks the condition.
|
|
41
|
+
- `undeterminable` — you could **not** reach a conclusion. Use this whenever the evidence is missing, unreadable, ambiguous, or beyond what your read-only tools can reach.
|
|
42
|
+
|
|
43
|
+
`undeterminable` is a legitimate and expected answer. It is never a failure of
|
|
44
|
+
yours, and reporting it honestly is strictly better than guessing.
|
|
45
|
+
|
|
46
|
+
**Never report `fail` for want of evidence.** "I could not find it" is
|
|
47
|
+
`undeterminable`, not `fail`. Collapsing the two turns a tooling gap into an
|
|
48
|
+
accusation of incorrect work, and the runner acts on that accusation — it rolls
|
|
49
|
+
the covered tasks back and reopens work that may be perfectly fine.
|
|
50
|
+
|
|
51
|
+
### 2. Implementation findings
|
|
52
|
+
|
|
53
|
+
Report defects anywhere in the implemented work — not only what the checks
|
|
54
|
+
cover. Scope is the whole change the plan drove, judged against the plan's
|
|
55
|
+
intent. If you find nothing worth reporting, emit exactly `- none.` under the
|
|
56
|
+
heading and stop.
|
|
57
|
+
|
|
58
|
+
One bullet per finding, exact line grammar (field order is fixed; fields are
|
|
59
|
+
separated by `; `):
|
|
60
|
+
|
|
61
|
+
- `F-###` — severity: high | medium | low; tasks: Task-N, Task-M | none; proposed-task: <imperative one-line title>; note: <one line>; evidence: <repo path or command output proving it>
|
|
62
|
+
|
|
63
|
+
Rules for the fields:
|
|
64
|
+
|
|
65
|
+
- `F-###` — a stable id. The brief lists the previous round's unresolved
|
|
66
|
+
findings: when a listed problem is still present, **reuse its id verbatim**
|
|
67
|
+
and do not renumber. A problem is resolved only by no longer reporting it.
|
|
68
|
+
Brand-new problems take the next unused number after the highest id you have
|
|
69
|
+
seen (in the brief or in this report).
|
|
70
|
+
- `severity` — `high` blocks completion and wakes the executor for a fix
|
|
71
|
+
round; `medium` and `low` are recorded and summarized at completion. Grade
|
|
72
|
+
by consequence: `high` = correctness, data loss, security, broken promised
|
|
73
|
+
behavior, or a verification check that is demonstrably unmet. `medium` =
|
|
74
|
+
should be fixed, but the plan's promised behavior still holds without it.
|
|
75
|
+
`low` = polish, naming, comments, minor drift. Do not inflate; do not
|
|
76
|
+
downgrade a real `high` to avoid waking the executor.
|
|
77
|
+
- `tasks` — the task id(s) whose work is defective, comma-separated, or
|
|
78
|
+
`none` when no existing task owns the defect. Only use ids from the brief's
|
|
79
|
+
task list. A `high` finding with `tasks: none` must carry a
|
|
80
|
+
`proposed-task:` field (below); the runner appends that task to the plan
|
|
81
|
+
mechanically, so write it as a self-contained imperative title (e.g.
|
|
82
|
+
`cap retry backoff at 60s in src/client.ts`). Omit `proposed-task:` for
|
|
83
|
+
mapped findings and for `medium`/`low`.
|
|
84
|
+
- `note` — one line: what is wrong and what breaks.
|
|
85
|
+
- `evidence` — a repository path (with line anchor when useful) or a short
|
|
86
|
+
quoted excerpt that an executor with read tools can re-inspect. A source
|
|
87
|
+
path plus a defect argument is sufficient; you have no execution tools, so
|
|
88
|
+
never fabricate command output.
|
|
89
|
+
|
|
90
|
+
Every reported defect must have a bullet. Never fold two defects into one
|
|
91
|
+
bullet; never mention a defect in prose without a bullet — findings outside
|
|
92
|
+
the grammar are invisible to the runner.
|
package/index.ts
CHANGED
|
@@ -88,6 +88,7 @@ import { registerPlansTool } from "./tools/plans.ts";
|
|
|
88
88
|
import { registerRefineTool } from "./tools/refine.ts";
|
|
89
89
|
import { registerAnalyzeRefsTool } from "./tools/analyze-refs.ts";
|
|
90
90
|
import { messaging, setMessagingApi } from "./src/messaging.ts";
|
|
91
|
+
import { stalenessLine } from "./src/staleness.ts";
|
|
91
92
|
|
|
92
93
|
const baseDir = dirname(fileURLToPath(import.meta.url));
|
|
93
94
|
|
|
@@ -96,29 +97,11 @@ const baseDir = dirname(fileURLToPath(import.meta.url));
|
|
|
96
97
|
// (code on disk newer than the loaded copy) is immediately visible.
|
|
97
98
|
const extensionLoadedAt = new Date();
|
|
98
99
|
|
|
100
|
+
// The probe itself lives in src/staleness.ts so the execution reviewer can ask
|
|
101
|
+
// the same question when it cannot read a verdict (see exec.ts) without
|
|
102
|
+
// importing index.ts, which already imports exec.ts.
|
|
99
103
|
function extensionStalenessLine(): string {
|
|
100
|
-
|
|
101
|
-
const dirs = [baseDir, path.join(baseDir, "src"), path.join(baseDir, "tools")];
|
|
102
|
-
const stack: string[] = [...dirs];
|
|
103
|
-
let newest = 0;
|
|
104
|
-
while (stack.length) {
|
|
105
|
-
const dir = stack.pop()!;
|
|
106
|
-
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
107
|
-
const full = path.join(dir, entry.name);
|
|
108
|
-
if (entry.isDirectory()) stack.push(full);
|
|
109
|
-
else if (entry.isFile() && entry.name.endsWith(".ts")) {
|
|
110
|
-
const mtime = fs.statSync(full).mtimeMs;
|
|
111
|
-
if (mtime > newest) newest = mtime;
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
if (newest > extensionLoadedAt.getTime() + 2000) {
|
|
116
|
-
return `⚠ extension code on disk is newer than the loaded copy (loaded ${extensionLoadedAt.toISOString()}); run /reload to pick it up`;
|
|
117
|
-
}
|
|
118
|
-
return `Extension loaded: ${extensionLoadedAt.toISOString()} (up to date)`;
|
|
119
|
-
} catch {
|
|
120
|
-
return `Extension loaded: ${extensionLoadedAt.toISOString()}`;
|
|
121
|
-
}
|
|
104
|
+
return stalenessLine(baseDir, extensionLoadedAt);
|
|
122
105
|
}
|
|
123
106
|
|
|
124
107
|
function hasActivePlanningWorkflow(ctx: Parameters<typeof updateStatusWidget>[0]): boolean {
|
|
@@ -126,7 +109,7 @@ function hasActivePlanningWorkflow(ctx: Parameters<typeof updateStatusWidget>[0]
|
|
|
126
109
|
const active = resolveActiveRun(ctx.sessionManager, ctx.cwd);
|
|
127
110
|
if (!active) return false;
|
|
128
111
|
const status = getRun(ctx.cwd, active.run_id)?.status;
|
|
129
|
-
return status === "planning" || status === "accepted" || status === "executing";
|
|
112
|
+
return status === "planning" || status === "accepted" || status === "executing" || status === "verifying";
|
|
130
113
|
}
|
|
131
114
|
|
|
132
115
|
export default function piPlansExtension(pi: ExtensionAPI): void {
|
|
@@ -141,6 +124,13 @@ export default function piPlansExtension(pi: ExtensionAPI): void {
|
|
|
141
124
|
description: "Expand/collapse the pi-plans task dashboard",
|
|
142
125
|
handler: (ctx) => toggleDashboardExpanded(ctx),
|
|
143
126
|
});
|
|
127
|
+
// v0.8: reopen the in-flight execution-review overlay after ESC (the
|
|
128
|
+
// controller is one-shot; the engine re-seeds a fresh one from its held
|
|
129
|
+
// lane state). Inert when no round is in flight.
|
|
130
|
+
pi.registerShortcut("ctrl+shift+r", {
|
|
131
|
+
description: "Reopen the pi-plans execution-review overlay",
|
|
132
|
+
handler: (ctx) => reopenReviewOverlay(ctx),
|
|
133
|
+
});
|
|
144
134
|
registerQueryInterviewHooks(pi, hasActivePlanningWorkflow);
|
|
145
135
|
registerCodeGraphTool(pi);
|
|
146
136
|
registerGraphAwareFileTools(pi);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-plans",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.1",
|
|
4
4
|
"description": "Human-in-the-loop planning extension for the Pi coding agent: researched, refined Markdown plans before any code changes.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -41,6 +41,7 @@
|
|
|
41
41
|
"README.md",
|
|
42
42
|
"LICENSE",
|
|
43
43
|
"CONTRIBUTING.md",
|
|
44
|
+
"AGENTS.md",
|
|
44
45
|
"index.ts",
|
|
45
46
|
"agents/",
|
|
46
47
|
"docs/assets",
|
|
@@ -11,7 +11,7 @@ This skill set is written for the Pi coding agent's documented behavior:
|
|
|
11
11
|
- Planning and reference analysis run with the extension tools `plans`, `ask_choice`, `refine`, `analyze_refs`, and `execute_plan`;
|
|
12
12
|
- `refine` spawns read-only Pi subagents (`pi --mode json -p --no-session --tools read,grep,find,ls`, plus `code_graph` when workspace `graph_enabled` is true) with isolated context; delegated reviewer runs show a standalone aggregate overlay titled `Reviewer` (78% × 78% top-center, ≥72 cols, no input row), stream assistant/thinking/tool events into per-lane transcripts with follow-bottom scroll, dismiss on `Esc` (close-only — the refiner child keeps running and its result still flows back as tool output), replace any retained finished overlay when a new round begins, and return conclusions to the main session as tool output; `analyze_refs` spawns one read-only subagent per downloaded reference (cwd = that ref's directory) reusing the reviewer role gates, shows the same overlay titled `Refs` in batches of at most 3 lanes, and returns structured per-reference sections for `REF_ANALYSIS.md`;
|
|
13
13
|
- when graph mode is enabled, graph-aware `read`/`edit` overrides are active for indexed source files: `read` returns a capped function digest (≤50 lines, synthetic anonymous entries folded) by default — drill in via `offset/limit` or `code_graph get-function`, and `full: true` is the only whole-file exit (small/zero-function files return full text; safety truncation matches native read); `write`/`edit` stage DB-first mutations until materialized via the `code_graph` tool's `apply` action (same planning/accepted gate as /apply-graph; refused for read-only refiner subagents via the PI_PLANS_REFINER marker; returns a per-file report with counts and a post-apply drift summary, and never changes run status); unexpected fallbacks (`not indexed` / `runtime unavailable` / `config read failed`) are marked at the top of the result while flag-off fallbacks stay unmarked;
|
|
14
|
-
- the execution loop is extension-managed and task-tree driven: the current wave and remaining tasks are injected each turn, progress is reported exclusively through the `plans_update_task` tool (status + evidence / skipReason), the task dashboard tracks every task (compact widget; Ctrl+Shift+T expands the tree), and an independent
|
|
14
|
+
- the execution loop is extension-managed and task-tree driven: the current wave and remaining tasks are injected each turn, progress is reported exclusively through the `plans_update_task` tool (status + evidence / skipReason), the task dashboard tracks every task (compact widget; Ctrl+Shift+T expands the tree), and an independent execution reviewer verifies the verification checks before the run completes;
|
|
15
15
|
- execution and planning compaction keep Pi's SessionManager as the history owner; during active pi-plans runs, `session_before_compact` uses a deterministic no-LLM VCC-style summary with `[Session Goal]`, `[Files And Changes]`, `[Commits]`, `[Outstanding Context]`, `[User Preferences]`, and a ranked brief transcript; Pi core owns manual `/compact`, threshold, and overflow scheduling, while pi-plans handles smart tail keep, `keep:N`, stats, and phase-specific run/plan/current-I/checklist context; in addition, creating a new planning run (`plans start-run`) proactively requests one pre-plan VCC compaction before the first planning question and resumes the planning turn with a hidden message (default on, `prePlanCompact` in `pi-vcc-config.json`);
|
|
16
16
|
|
|
17
17
|
## Planning Boundary
|
|
@@ -99,7 +99,7 @@ Every plan version's body is exactly two sections — `## Tasks` and `## Verific
|
|
|
99
99
|
- [ ] `VC-001` covers `Task-1`; pass condition: ...; evidence: ...; metric: <threshold or reason not quantified>.
|
|
100
100
|
```
|
|
101
101
|
|
|
102
|
-
The execution loop parses `- [ ] \`VC-###\`` checks and the task tree, so keep IDs on the checkbox line and the task grammar exact; task progress flows through `plans_update_task` and the
|
|
102
|
+
The execution loop parses `- [ ] \`VC-###\`` checks and the task tree, so keep IDs on the checkbox line and the task grammar exact; task progress flows through `plans_update_task` and the execution reviewer reads these checks. Use `references/plan-artifact-template.md` when drafting.
|
|
103
103
|
|
|
104
104
|
## Refinement
|
|
105
105
|
|
|
@@ -131,12 +131,19 @@ When the user picks `✓ Accept PLAN_vN and execute it now` in the merged questi
|
|
|
131
131
|
|
|
132
132
|
- every agent turn is injected with the current wave's open tasks, the remaining task list, verification-check summary, and execution rules (wave order, `plans_update_task` reporting with status + evidence / skipReason, subprocess polling backoff 5s -> 10s -> 20s -> 40s -> 80s then keep polling at 80s, no stopgaps, dependency and library discipline, minimum tests);
|
|
133
133
|
- task progress flows exclusively through the `plans_update_task` tool: one call per task closing it as `complete` (with evidence) or `skipped` (with skipReason); closed statuses are immutable outside the audit-authorized rollback channel; subtasks close before their parent;
|
|
134
|
-
- the task dashboard tracks the whole tree live: a compact aboveEditor widget (current task ▸, progress bar, ✓/· counts, VC pass count, wave indicator, pause state, audit-
|
|
135
|
-
- a stall watchdog pauses execution after three consecutive settled rounds without any task-status change (genuine user input or `/plans-execute` resumes without losing progress);
|
|
136
|
-
- when every task reaches a terminal state,
|
|
134
|
+
- the task dashboard tracks the whole tree live: a compact aboveEditor widget (current task ▸, progress bar, ✓/· counts, VC pass count, wave indicator, pause state, audit-outcome line, unresolved-findings line visible in both the repairing and verifying phases) and the Ctrl+Shift+T expanded tree view (✓/▸/~/·/↺ markers, current-task anchor, VC list with audit state, width-adaptive layout). `↺` marks a task that was completed and then rolled back by a failed audit: it is open again but still shows the evidence from its previous attempt;
|
|
135
|
+
- a stall watchdog pauses execution after three consecutive settled rounds without any task-status change (genuine user input or `/plans-execute` resumes without losing progress). A round in which the agent ran successful tool calls counts as progress even with no status change, so investigating the codebase is never mistaken for a dead agent;
|
|
136
|
+
- when every task reaches a terminal state, the run status moves to `verifying` and an independent read-only execution reviewer (`agents/execution-reviewer.md`) verifies each check against the worktree in a detached round whose progress renders in a dedicated overlay (Esc closes it; Ctrl+Shift+R reopens the in-flight round). Each check gets one of three verdicts:
|
|
137
|
+
- `pass` — the evidence establishes the check's condition;
|
|
138
|
+
- `fail` — the condition is demonstrably not met; the covered tasks roll back to pending (children cascade, skipped tasks reopen, the `evidence` of the previous attempt is retained while `skipReason` is cleared) and the audit report is injected;
|
|
139
|
+
- `undeterminable` — the reviewer could not reach a conclusion. This is never a failure and never a completion: nothing rolls back, the loop self-schedules the retry (no agent wake), and each retry counts toward the five-round budget. An all-undeterminable round that also reports a high-severity finding still wakes the executor — a finding is actionable independent of verdict evidence;
|
|
140
|
+
- `F-###` findings — every round also reports severity-graded implementation findings (`high | medium | low`) over the whole implemented change, not just what the checks cover. Ids are stable: the brief lists the previous round's unresolved findings and the reviewer reuses their ids verbatim while the problem persists; absence from the newest round's report is the resolution signal. A `high` finding (or a `fail` verdict) opens ONE union fix round: mapped tasks roll back to pending exactly like a failed check's coverage (children cascade, evidence retained), and a `high` whose `tasks: none` names no owner gets a plan task appended mechanically from the reviewer's `proposed-task` title — the reviewer itself stays read-only. The executor is woken exactly once with a findings summary plus the round-report path. A pure finding-driven rollback deliberately keeps earlier VC passes (the findings channel re-examines the repaired work next round); only a `fail`-driven rollback invalidates the checks covering the reopened tasks. Unresolved findings persist across checkpoint restores, session restores, and fresh budget grants.
|
|
141
|
+
|
|
142
|
+
The run completes only when every pending check is affirmatively `pass` AND the newest round reports no high-severity finding; residual `medium`/`low` findings are summarized in the completion message and stay recorded in the round reports. A partial round credits the checks that passed and leaves the rest for the next round. Checks whose covered tasks are all skipped pass as skipped-pass; checks covering no task never enter the audit; checks already satisfied in an earlier round are neither re-briefed nor re-judged;
|
|
143
|
+
- the round budget is five COMMITTED rounds (pass, fail, or undeterminable; discarded fingerprint-mismatch attempts and cancellations burn nothing; two consecutive discards commit as one undeterminable round). Exhaustion pauses the run in EVERY mode — interactive and auto-approve/headless alike — with an in-band `pi-plans-review-paused` message; ordinary user input and session restores never lift the pause or refill the budget. The only fresh-budget surface is `/plans-execute`, whose explicit confirmation grants five more rounds. The watchdog counter is rebased by real tool activity;
|
|
137
144
|
- execution-phase compaction is handled only when Pi core emits manual `/compact`, threshold, or overflow events; summaries are deterministic VCC-style summaries, include session-derived plan/current-task/checklist context, use smart tail keep and `keep:N`, and never call a model;
|
|
138
145
|
- the read-only guard lifts: full write access returns;
|
|
139
|
-
- the run status moves to `executing`, then `done` when the
|
|
146
|
+
- the run status moves to `executing`, then `verifying` while the review loop owns the run, then `done` when every check passes (a failed round rolls its tasks back and returns the run to `executing` for repair);
|
|
140
147
|
- `/plans-stop` stops execution; `/plans` shows progress.
|
|
141
148
|
|
|
142
149
|
If the user declines, stay in planning (or stop, per their choice). Never start implementation without the approved handoff.
|
|
@@ -164,7 +171,7 @@ use RPC for persistent headless execution.
|
|
|
164
171
|
|
|
165
172
|
After a restart or in a fresh session, `/resume-plans` (interactive only) restores the repository's working plan in the current session: the unfinished active run wins; otherwise a unique candidate resumes directly and multiple candidates get a chooser. It resumes unfinished planning (re-asks the pending question with the same `questionId`, never re-asks answered decisions), reviewing (resumes interrupted rounds via `refine resumeRoundId`, consolidates completed ones), and execution (durable approval: unchanged plan digest keeps the authorization — a changed HEAD re-opens previously closed tasks for re-verification; an unverifiable approval HEAD behaves the same; legacy runs without checkpoints must re-approve; v0.6.0 delegated-executor orphans require a fresh handoff approval; a legacy `implementation-review` phase maps to done — its historical acceptance stands). Linked worktrees share candidates; cross-worktree resumes confirm, copy artifacts without overwriting, reset approval and VC validity, and restart round counts. Record semantic boundaries with `plans record-checkpoint` (`plan-written`, `review-consolidated`, `completed` with evidence).
|
|
166
173
|
|
|
167
|
-
`refine` reviews the plan text (the v0.6.0 `target: "implementation"` post-execution loop is gone; the independent
|
|
174
|
+
`refine` reviews the plan text (the v0.6.0 `target: "implementation"` post-execution loop is gone; the independent execution reviewer now gates delivery).
|
|
168
175
|
|
|
169
176
|
## Red Flags
|
|
170
177
|
|
|
@@ -30,7 +30,7 @@ One paragraph summarizing the user's request.
|
|
|
30
30
|
|
|
31
31
|
## Execution Handoff Notes
|
|
32
32
|
|
|
33
|
-
Ordering, files to avoid, verification commands, and anything the executor must know. The handoff still requires explicit user approval (`ask_choice` with `autoComplete: false`, then the `execute_plan` tool) and is never auto-completed. Once approved, execution mode tracks every task through the `plans_update_task` tool (status + evidence); when all tasks are terminal, the independent
|
|
33
|
+
Ordering, files to avoid, verification commands, and anything the executor must know. The handoff still requires explicit user approval (`ask_choice` with `autoComplete: false`, then the `execute_plan` tool) and is never auto-completed. Once approved, execution mode tracks every task through the `plans_update_task` tool (status + evidence); when all tasks are terminal, the independent execution reviewer verifies each check above before the run completes.
|
|
34
34
|
|
|
35
35
|
## Revision Ledger
|
|
36
36
|
|
|
@@ -70,6 +70,16 @@ review rounds, refs), not in the plan file. `## Execution Handoff Notes` and
|
|
|
70
70
|
- `covers` accepts multiple targets and `Task-N.M` subtask ids; the clause ends
|
|
71
71
|
at the first `;`. Checks covering zero tasks never enter the completion
|
|
72
72
|
audit; a check whose covered tasks are ALL skipped passes as skipped-pass.
|
|
73
|
+
- Write each check so its condition can be judged from the worktree alone: a
|
|
74
|
+
check whose evidence is not reachable with read-only tools comes back
|
|
75
|
+
`undeterminable`, not `pass`, and an unreadable round never completes the run.
|
|
76
|
+
- A check that fails the audit rolls its covered tasks back to pending. The
|
|
77
|
+
tasks keep the `evidence` from the attempt that was rolled back (re-reporting
|
|
78
|
+
overwrites it), so evidence is the record of what was already tried — do not
|
|
79
|
+
expect a clean slate, and do not re-report a rolled-back task until you have
|
|
80
|
+
actually changed something. `skipReason` is cleared, because the audit
|
|
81
|
+
overturned the skip. A rollback also clears the satisfied state of any other
|
|
82
|
+
check covering the reopened work.
|
|
73
83
|
|
|
74
84
|
### Lint and compatibility
|
|
75
85
|
|
|
@@ -93,7 +93,7 @@ Rules:
|
|
|
93
93
|
- `confirmed_at` is stamped only by a real confirmation. `reviewerReady(role)` = current-session, or delegated with `confirmed_at` set AND a concrete `model_selector` — a confirmed null selector can never pass (the old confirmed-inherit state is unreachable).
|
|
94
94
|
- A corrupt or wrong-schema global file yields defaults plus a notice and is NEVER clobbered by reads.
|
|
95
95
|
- Migration (Q-1=A): the first mutating pi-plans call in a workspace with a legacy intent block (`confirmed_at` set, an explicit selector, or a non-default mode) seeds the global file once — first touched workspace wins; other workspaces get a one-time "ignored" notice. A confirmed-inherit block seeds with the selector null and NO confirmation, so the next `refine` re-asks once via the native panel. Scaffold-only blocks are dropped silently.
|
|
96
|
-
- The
|
|
96
|
+
- The execution reviewer's spawn IS governed by this role when it is confirmed: the round pins the configured model and thinking level and labels its overlay with the role. An unconfirmed or `current-session` role inherits the session default (labeled `session default`) — a detached round never opens the interactive first-use panel. Rounds are timeout-bounded (minutes, not the subagent default), so a hung child surfaces as a spawn-failure round instead of parking the run.
|
|
97
97
|
|
|
98
98
|
## VCC Compact Config
|
|
99
99
|
|
|
@@ -203,11 +203,11 @@ One run directory per planning request: `<git-common-dir>/pi-plans/runs/<YYYYMMD
|
|
|
203
203
|
|
|
204
204
|
## Workflow Checkpoints (`/resume-plans`)
|
|
205
205
|
|
|
206
|
-
Each run may carry a `checkpoint.json` — the durable, cross-session workflow state that `/resume-plans` restores in the current session. It records: logical `phase` (`planning | reviewing | executing | completed`; the legacy 0.6.0 `implementation-review` phase is read-tolerated and maps to done), `nextAction`, the exact plan identity (path + version + SHA-256), pending/answered questions (stable `questionId`), review rounds with per-lane status and result-file references, execution approval evidence (plan digest, worktree, `git
|
|
206
|
+
Each run may carry a `checkpoint.json` — the durable, cross-session workflow state that `/resume-plans` restores in the current session. It records: logical `phase` (`planning | reviewing | executing | completed`; the legacy 0.6.0 `implementation-review` phase is read-tolerated and maps to done), `nextAction`, the exact plan identity (path + version + SHA-256), pending/answered questions (stable `questionId`), review rounds with per-lane status and result-file references, execution approval evidence (plan digest, worktree, `git revparse HEAD` at approval, task progress map, audit rounds with the failed and undeterminable check sets plus the unresolved findings of the newest committed round, the watchdog budget counter, verified VC set, usage), and ownership metadata. Full review outputs live in separate `reviews/` files; the checkpoint keeps only validated references.
|
|
207
207
|
|
|
208
208
|
Rules:
|
|
209
209
|
|
|
210
|
-
- Validation is explicit: unknown schema versions, malformed shapes, and unexpected keys are rejected; missing and corrupt checkpoints are distinct, and corrupt files are never silently overwritten.
|
|
210
|
+
- Validation is explicit: unknown schema versions, malformed shapes, and unexpected keys are rejected; missing and corrupt checkpoints are distinct, and corrupt files are never silently overwritten. Keys added by a later version (`execution.stallRounds`, `execution.audit.undeterminable`, `execution.audit.findings`, `execution.planAmended`) are optional on read, so checkpoints written before them keep loading. `execution.planAmended` is set when the review loop mechanically appended finding tasks to the approved plan; the checkpoint's plan identity was re-stamped to the amended digest at that moment while the approval record keeps the original.
|
|
211
211
|
- Writes are atomic with monotonic revisions; writers may require ownership (token + generation) or an expected revision.
|
|
212
212
|
- Model-driven boundaries (plan written, review consolidated, termination condition recorded, implementation round finished, completed) go through the whitelisted `plans record-checkpoint` action, which enforces state-machine preconditions — it cannot set execution approval, mark VCs passed, or forge terminal states.
|
|
213
213
|
- `ask_choice` accepts `questionId`/`purpose`; a pending question is durable before the panel opens and the answer before it returns. When a crash leaves a question both answered (ledger) and pending (checkpoint), the answered entry wins.
|
package/scripts/validate.ts
CHANGED
|
@@ -17,7 +17,12 @@ const EXPECTED_SKILLS = new Set([
|
|
|
17
17
|
"debug-and-plan",
|
|
18
18
|
]);
|
|
19
19
|
const REQUIRED_REFERENCES = ["pi-planning-workflow.md", "plan-artifact-template.md", "state-and-config.md"];
|
|
20
|
-
const REQUIRED_AGENTS = ["reviewer.md"];
|
|
20
|
+
const REQUIRED_AGENTS = ["reviewer.md", "execution-reviewer.md"];
|
|
21
|
+
// Root-level docs that must exist and must be entirely English (see AGENTS.md).
|
|
22
|
+
const REQUIRED_ROOT_DOCS = ["AGENTS.md", "CHANGELOG.md"];
|
|
23
|
+
// CJK ideographs plus full-width CJK punctuation. Ideographs alone are not
|
|
24
|
+
// enough: a file can read untranslated while carrying full-width punctuation.
|
|
25
|
+
const CJK_RE = /[ -〿一-鿿-]/;
|
|
21
26
|
const REQUIRED_TOOL_FILES = [
|
|
22
27
|
"tools/plans.ts",
|
|
23
28
|
"tools/ask-choice.ts",
|
|
@@ -142,7 +147,7 @@ function validatePackageMetadata(): void {
|
|
|
142
147
|
if (!skills.has("./skills")) fail("package.json: pi.skills must include ./skills");
|
|
143
148
|
|
|
144
149
|
const files = new Set((pkg.files ?? []).map(normalizePackageEntry));
|
|
145
|
-
for (const required of ["README.md", "LICENSE", "CONTRIBUTING.md", "index.ts", "agents", "references", "scripts", "skills", "src", "tests", "tools"]) {
|
|
150
|
+
for (const required of ["README.md", "LICENSE", "CONTRIBUTING.md", "AGENTS.md", "index.ts", "agents", "references", "scripts", "skills", "src", "tests", "tools"]) {
|
|
146
151
|
if (!files.has(required)) fail(`package.json: files must include ${required}`);
|
|
147
152
|
}
|
|
148
153
|
for (const excluded of ["!scripts/bench/vendor", "!scripts/bench/results"]) {
|
|
@@ -165,6 +170,7 @@ const REQUIRED_PACK_ENTRIES = [
|
|
|
165
170
|
"README.md",
|
|
166
171
|
"LICENSE",
|
|
167
172
|
"CONTRIBUTING.md",
|
|
173
|
+
"AGENTS.md",
|
|
168
174
|
"index.ts",
|
|
169
175
|
"package.json",
|
|
170
176
|
"agents/reviewer.md",
|
|
@@ -263,13 +269,24 @@ function main(): void {
|
|
|
263
269
|
if (!fs.existsSync(path.join(ROOT, tool))) fail(`missing ${tool}`);
|
|
264
270
|
}
|
|
265
271
|
|
|
272
|
+
for (const doc of REQUIRED_ROOT_DOCS) {
|
|
273
|
+
const file = path.join(ROOT, doc);
|
|
274
|
+
if (!fs.existsSync(file)) {
|
|
275
|
+
fail(`missing root doc ${doc}`);
|
|
276
|
+
continue;
|
|
277
|
+
}
|
|
278
|
+
if (CJK_RE.test(fs.readFileSync(file, "utf8"))) {
|
|
279
|
+
fail(`${doc}: must be entirely English (no CJK ideographs or full-width CJK punctuation)`);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
266
283
|
if (!fs.existsSync(path.join(ROOT, "index.ts"))) fail("missing index.ts");
|
|
267
284
|
|
|
268
285
|
validateDefaultConfig();
|
|
269
286
|
validatePlansTool();
|
|
270
287
|
validatePackageMetadata();
|
|
271
288
|
validatePackageArtifact();
|
|
272
|
-
console.log(`validated ${EXPECTED_SKILLS.size} skills, ${REQUIRED_REFERENCES.length} references, ${REQUIRED_AGENTS.length} agents, ${REQUIRED_TOOL_FILES.length} tools`);
|
|
289
|
+
console.log(`validated ${EXPECTED_SKILLS.size} skills, ${REQUIRED_REFERENCES.length} references, ${REQUIRED_AGENTS.length} agents, ${REQUIRED_TOOL_FILES.length} tools, ${REQUIRED_ROOT_DOCS.length} docs`);
|
|
273
290
|
}
|
|
274
291
|
|
|
275
292
|
main();
|