pan-wizard 3.22.0 → 3.24.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/README.md +38 -24
- package/agents/pan-conductor.md +3 -3
- package/agents/pan-design-checker.md +83 -0
- package/agents/pan-designer.md +67 -0
- package/agents/pan-document_code.md +3 -2
- package/agents/pan-executor.md +2 -2
- package/agents/pan-plan-checker.md +19 -6
- package/agents/pan-planner.md +4 -1
- package/agents/pan-previewer.md +1 -1
- package/agents/pan-roadmapper.md +3 -1
- package/agents/pan-verifier.md +10 -10
- package/bin/install-lib.cjs +128 -17
- package/bin/install.js +480 -74
- package/commands/pan/army.md +20 -14
- package/commands/pan/audit-deployment.md +17 -14
- package/commands/pan/cost.md +2 -2
- package/commands/pan/debug.md +1 -1
- package/commands/pan/design-phase.md +77 -0
- package/commands/pan/exec-phase.md +2 -2
- package/commands/pan/experiment.md +18 -14
- package/commands/pan/focus-auto.md +5 -5
- package/commands/pan/focus-design.md +13 -1
- package/commands/pan/focus-exec.md +1 -1
- package/commands/pan/learn.md +1 -1
- package/commands/pan/links.md +3 -1
- package/commands/pan/map-codebase.md +4 -4
- package/commands/pan/mcp-bridge.md +1 -1
- package/commands/pan/milestone-new.md +3 -1
- package/commands/pan/optimize.md +2 -2
- package/commands/pan/patches.md +1 -1
- package/commands/pan/plan-phase.md +3 -1
- package/commands/pan/preview.md +3 -3
- package/commands/pan/profile.md +3 -3
- package/commands/pan/research-phase.md +1 -1
- package/commands/pan/retro.md +4 -1
- package/commands/pan/review-deep.md +1 -1
- package/commands/pan/settings.md +2 -2
- package/commands/pan/what-if.md +1 -1
- package/hooks/dist/pan-check-update.js +149 -38
- package/hooks/dist/pan-context-monitor.js +155 -81
- package/hooks/dist/pan-cost-logger.js +288 -13
- package/hooks/dist/pan-statusline.js +24 -8
- package/hooks/dist/pan-stop-guard.js +160 -0
- package/hooks/dist/pan-trace-logger.js +261 -19
- package/package.json +2 -2
- package/pan-wizard-core/bin/lib/bridge.cjs +1 -1
- package/pan-wizard-core/bin/lib/bus.cjs +19 -4
- package/pan-wizard-core/bin/lib/campaign.cjs +8 -3
- package/pan-wizard-core/bin/lib/codebase.cjs +15 -5
- package/pan-wizard-core/bin/lib/commands.cjs +88 -6
- package/pan-wizard-core/bin/lib/config.cjs +27 -2
- package/pan-wizard-core/bin/lib/constants.cjs +1 -0
- package/pan-wizard-core/bin/lib/core.cjs +113 -8
- package/pan-wizard-core/bin/lib/cost.cjs +61 -24
- package/pan-wizard-core/bin/lib/distill.cjs +22 -4
- package/pan-wizard-core/bin/lib/doc-lint.cjs +25 -7
- package/pan-wizard-core/bin/lib/experiment.cjs +25 -1
- package/pan-wizard-core/bin/lib/focus.cjs +42 -7
- package/pan-wizard-core/bin/lib/frontmatter.cjs +62 -31
- package/pan-wizard-core/bin/lib/git.cjs +51 -16
- package/pan-wizard-core/bin/lib/hud.cjs +17 -2
- package/pan-wizard-core/bin/lib/init.cjs +2 -5
- package/pan-wizard-core/bin/lib/knowledge.cjs +20 -1
- package/pan-wizard-core/bin/lib/learn-lint.cjs +50 -0
- package/pan-wizard-core/bin/lib/links.cjs +9 -6
- package/pan-wizard-core/bin/lib/lock.cjs +23 -4
- package/pan-wizard-core/bin/lib/memory-optimize.cjs +11 -6
- package/pan-wizard-core/bin/lib/milestone.cjs +11 -5
- package/pan-wizard-core/bin/lib/optimize.cjs +18 -7
- package/pan-wizard-core/bin/lib/phase-remove.cjs +41 -2
- package/pan-wizard-core/bin/lib/phase.cjs +82 -11
- package/pan-wizard-core/bin/lib/preview.cjs +23 -4
- package/pan-wizard-core/bin/lib/review-deep.cjs +14 -6
- package/pan-wizard-core/bin/lib/roadmap.cjs +6 -2
- package/pan-wizard-core/bin/lib/runner.cjs +17 -7
- package/pan-wizard-core/bin/lib/squads.cjs +43 -11
- package/pan-wizard-core/bin/lib/state.cjs +32 -11
- package/pan-wizard-core/bin/lib/template.cjs +8 -3
- package/pan-wizard-core/bin/lib/verify-deploy.cjs +14 -2
- package/pan-wizard-core/bin/lib/verify-drift.cjs +15 -1
- package/pan-wizard-core/bin/lib/verify-preflight.cjs +9 -3
- package/pan-wizard-core/bin/lib/verify.cjs +84 -39
- package/pan-wizard-core/bin/lib/whatif.cjs +8 -1
- package/pan-wizard-core/bin/pan-tools.cjs +42 -19
- package/pan-wizard-core/learnings/index.json +7 -7
- package/pan-wizard-core/learnings/universal/autonomous-loop.md +5 -3
- package/pan-wizard-core/learnings/universal/concurrency.md +1 -1
- package/pan-wizard-core/references/design-methodology.md +94 -0
- package/pan-wizard-core/references/git-integration.md +9 -9
- package/pan-wizard-core/references/guardrails.md +4 -1
- package/pan-wizard-core/references/model-profile-resolution.md +1 -1
- package/pan-wizard-core/references/model-profiles.md +44 -34
- package/pan-wizard-core/references/planning-config.md +5 -5
- package/pan-wizard-core/references/verification-patterns.md +67 -0
- package/pan-wizard-core/templates/codebase/architecture.md +1 -1
- package/pan-wizard-core/templates/codebase/concerns.md +1 -1
- package/pan-wizard-core/templates/codebase/conventions.md +1 -1
- package/pan-wizard-core/templates/codebase/integrations.md +1 -1
- package/pan-wizard-core/templates/codebase/stack.md +1 -1
- package/pan-wizard-core/templates/codebase/structure.md +1 -1
- package/pan-wizard-core/templates/codebase/testing.md +1 -1
- package/pan-wizard-core/templates/design.md +146 -0
- package/pan-wizard-core/templates/discovery.md +3 -3
- package/pan-wizard-core/templates/milestone-archive.md +2 -2
- package/pan-wizard-core/templates/playbook.md +1 -1
- package/pan-wizard-core/templates/uat.md +1 -1
- package/pan-wizard-core/workflows/diagnose-issues.md +9 -7
- package/pan-wizard-core/workflows/exec-phase.md +28 -8
- package/pan-wizard-core/workflows/execute-plan.md +2 -3
- package/pan-wizard-core/workflows/health.md +24 -1
- package/pan-wizard-core/workflows/help.md +5 -4
- package/pan-wizard-core/workflows/learn.md +5 -5
- package/pan-wizard-core/workflows/map-codebase.md +1 -1
- package/pan-wizard-core/workflows/milestone-audit.md +1 -1
- package/pan-wizard-core/workflows/milestone-new.md +4 -4
- package/pan-wizard-core/workflows/new-project.md +47 -32
- package/pan-wizard-core/workflows/optimize.md +8 -8
- package/pan-wizard-core/workflows/pause.md +1 -1
- package/pan-wizard-core/workflows/phase-tests.md +2 -2
- package/pan-wizard-core/workflows/plan-phase.md +4 -0
- package/pan-wizard-core/workflows/profile.md +13 -10
- package/pan-wizard-core/workflows/research-phase.md +1 -1
- package/pan-wizard-core/workflows/resume-project.md +1 -1
- package/pan-wizard-core/workflows/settings.md +9 -9
- package/pan-wizard-core/workflows/transition.md +24 -8
- package/pan-wizard-core/workflows/update.md +23 -20
- package/pan-wizard-core/workflows/verify-phase.md +7 -2
- package/pan-zcode/README.md +12 -2
- package/pan-zcode/bin/install-zcode.js +1 -1
- package/pan-zcode/mcp/native-tools.cjs +1 -1
- package/pan-zcode/mcp/server.cjs +76 -14
- package/scripts/build-hooks.js +2 -1
- package/scripts/generate-skills-docs.py +0 -4
- package/scripts/run-tests.cjs +11 -4
|
@@ -47,7 +47,7 @@ Exit.
|
|
|
47
47
|
|
|
48
48
|
Read the phase artifacts (in order of priority):
|
|
49
49
|
1. `${phase_dir}/*-summary.md` — what was implemented, files changed
|
|
50
|
-
2. `${phase_dir}
|
|
50
|
+
2. `${phase_dir}/*-context.md` — acceptance criteria, decisions
|
|
51
51
|
3. `${phase_dir}/*-verification.md` — user-verified scenarios (if UAT was done)
|
|
52
52
|
|
|
53
53
|
If no summary.md exists:
|
|
@@ -341,7 +341,7 @@ If there are passing tests to commit:
|
|
|
341
341
|
|
|
342
342
|
```bash
|
|
343
343
|
git add {test files}
|
|
344
|
-
git commit -m "test(phase-${phase_number}): add unit and E2E tests from
|
|
344
|
+
git commit -m "test(phase-${phase_number}): add unit and E2E tests from phase-tests command"
|
|
345
345
|
```
|
|
346
346
|
|
|
347
347
|
Present next steps:
|
|
@@ -542,6 +542,10 @@ Check for auto-advance trigger:
|
|
|
542
542
|
```bash
|
|
543
543
|
AUTO_CFG=$(node ~/.claude/pan-wizard-core/bin/pan-tools.cjs config-get workflow.auto_advance 2>/dev/null || echo "false")
|
|
544
544
|
```
|
|
545
|
+
3. **If `--auto` flag present AND `AUTO_CFG` is not true — persist it** (same as discuss-phase's auto_advance step), so the rest of the chain and the P-1809 stop guard see the run as autonomous on disk (P-1810):
|
|
546
|
+
```bash
|
|
547
|
+
node ~/.claude/pan-wizard-core/bin/pan-tools.cjs config-set workflow.auto_advance true
|
|
548
|
+
```
|
|
545
549
|
|
|
546
550
|
**If `--auto` flag present OR `AUTO_CFG` is true:**
|
|
547
551
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<purpose>
|
|
2
|
-
Switch the model profile used by PAN agents. Controls which
|
|
2
|
+
Switch the model profile used by PAN agents. Controls which model tier each agent uses, balancing quality vs token spend.
|
|
3
3
|
</purpose>
|
|
4
4
|
|
|
5
5
|
<required_reading>
|
|
@@ -88,20 +88,23 @@ Agents will now use:
|
|
|
88
88
|
|
|
89
89
|
[Show table from MODEL_PROFILES in pan-tools.cjs for selected profile]
|
|
90
90
|
|
|
91
|
-
Example
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
| pan-
|
|
96
|
-
| pan-
|
|
91
|
+
Example (`budget` — the only profile that steps agents below the reasoning
|
|
92
|
+
tier; `quality` and `balanced` put every agent on `reasoning`):
|
|
93
|
+
| Agent | Tier |
|
|
94
|
+
|-------|------|
|
|
95
|
+
| pan-planner | mid |
|
|
96
|
+
| pan-executor | mid |
|
|
97
|
+
| pan-verifier | fast |
|
|
97
98
|
| ... | ... |
|
|
98
99
|
|
|
99
100
|
Cost estimate:
|
|
100
101
|
[Run: node ~/.claude/pan-wizard-core/bin/pan-tools.cjs estimate-cost]
|
|
101
102
|
Show the average cost multiplier for each profile (quality/balanced/budget)
|
|
102
|
-
and highlight the selected profile
|
|
103
|
-
|
|
104
|
-
|
|
103
|
+
and highlight the selected profile — read the numbers from the command output,
|
|
104
|
+
don't hardcode them (`quality` and `balanced` report the same multiplier).
|
|
105
|
+
Example shape:
|
|
106
|
+
quality: <n>× avg | balanced: <n>× avg | budget: <n>× avg
|
|
107
|
+
^^^^^^^^^^^^^^^^ selected
|
|
105
108
|
|
|
106
109
|
Next spawned agents will use the new profile.
|
|
107
110
|
```
|
|
@@ -26,7 +26,7 @@ If `found` is false: Error and exit.
|
|
|
26
26
|
## Step 2: Check Existing Research
|
|
27
27
|
|
|
28
28
|
```bash
|
|
29
|
-
ls .planning/phases
|
|
29
|
+
ls .planning/phases/*/*-research.md 2>/dev/null | grep -E "/0*${PHASE}-[^/]*/"
|
|
30
30
|
```
|
|
31
31
|
|
|
32
32
|
If exists: Offer update/view/skip options.
|
|
@@ -67,7 +67,7 @@ ls .planning/phases/*/.continue-here*.md 2>/dev/null
|
|
|
67
67
|
|
|
68
68
|
# Check for plans without summaries (incomplete execution)
|
|
69
69
|
for plan in .planning/phases/*/*-plan.md; do
|
|
70
|
-
summary="${plan
|
|
70
|
+
summary="${plan%-plan.md}-summary.md"
|
|
71
71
|
[ ! -f "$summary" ] && echo "Incomplete: $plan"
|
|
72
72
|
done 2>/dev/null
|
|
73
73
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<purpose>
|
|
2
|
-
Interactive configuration of PAN workflow agents (research, plan_check, verifier) and model profile selection via multi-question prompt. Updates .planning/config.json with user preferences. Optionally saves settings as global defaults (~/.pan-wizard
|
|
2
|
+
Interactive configuration of PAN workflow agents (research, plan_check, verifier) and model profile selection via multi-question prompt. Updates .planning/config.json with user preferences. Optionally saves settings as global defaults (~/.pan-wizard/defaults.json) for future projects.
|
|
3
3
|
</purpose>
|
|
4
4
|
|
|
5
5
|
<required_reading>
|
|
@@ -44,9 +44,9 @@ AskUserQuestion([
|
|
|
44
44
|
header: "Model",
|
|
45
45
|
multiSelect: false,
|
|
46
46
|
options: [
|
|
47
|
-
{ label: "Quality", description: "
|
|
48
|
-
{ label: "Balanced (Recommended)", description: "
|
|
49
|
-
{ label: "Budget", description: "
|
|
47
|
+
{ label: "Quality", description: "reasoning tier for every agent — identical to balanced, so switching between the two changes nothing" },
|
|
48
|
+
{ label: "Balanced (Recommended)", description: "reasoning tier for every agent (quality and balanced are identical post-COST-RESET); use budget to step down" },
|
|
49
|
+
{ label: "Budget", description: "mid tier for writing, fast tier for research/verification (lowest cost)" }
|
|
50
50
|
]
|
|
51
51
|
},
|
|
52
52
|
{
|
|
@@ -153,20 +153,20 @@ AskUserQuestion([
|
|
|
153
153
|
header: "Defaults",
|
|
154
154
|
multiSelect: false,
|
|
155
155
|
options: [
|
|
156
|
-
{ label: "Yes", description: "New projects start with these settings (saved to ~/.pan-wizard
|
|
156
|
+
{ label: "Yes", description: "New projects start with these settings (saved to ~/.pan-wizard/defaults.json)" },
|
|
157
157
|
{ label: "No", description: "Only apply to this project" }
|
|
158
158
|
]
|
|
159
159
|
}
|
|
160
160
|
])
|
|
161
161
|
```
|
|
162
162
|
|
|
163
|
-
If "Yes": write the same config object (minus project-specific fields like `brave_search`) to `~/.pan-wizard
|
|
163
|
+
If "Yes": write the same config object (minus project-specific fields like `brave_search`) to `~/.pan-wizard/defaults.json`:
|
|
164
164
|
|
|
165
165
|
```bash
|
|
166
|
-
mkdir -p ~/.
|
|
166
|
+
mkdir -p ~/.pan-wizard
|
|
167
167
|
```
|
|
168
168
|
|
|
169
|
-
Write `~/.pan-wizard
|
|
169
|
+
Write `~/.pan-wizard/defaults.json` with:
|
|
170
170
|
```json
|
|
171
171
|
{
|
|
172
172
|
"mode": <current>,
|
|
@@ -222,6 +222,6 @@ Quick commands:
|
|
|
222
222
|
- [ ] Current config read
|
|
223
223
|
- [ ] User presented with 7 settings (profile + 5 workflow toggles + git branching)
|
|
224
224
|
- [ ] Config updated with model_profile, workflow, and git sections
|
|
225
|
-
- [ ] User offered to save as global defaults (~/.pan-wizard
|
|
225
|
+
- [ ] User offered to save as global defaults (~/.pan-wizard/defaults.json)
|
|
226
226
|
- [ ] Changes confirmed to user
|
|
227
227
|
</success_criteria>
|
|
@@ -76,9 +76,20 @@ cat .planning/config.json 2>/dev/null
|
|
|
76
76
|
|
|
77
77
|
</config-check>
|
|
78
78
|
|
|
79
|
+
**Detect AUTO mode (P-1807 — gate parity with the rest of the chain):**
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
HAS_AUTO_FLAG=$(echo "$ARGUMENTS" | grep -c -- '--auto' || true)
|
|
83
|
+
AUTO_CFG=$(node ~/.claude/pan-wizard-core/bin/pan-tools.cjs config-get workflow.auto_advance 2>/dev/null || echo "false")
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
**AUTO is active** when `HAS_AUTO_FLAG` > 0 (the `--auto` flag exec-phase passes through), OR `AUTO_CFG` is `true`, OR config `mode` is `yolo`. Every `<if auto>` gate in this workflow keys on this condition — the same trigger `exec-phase.md` (offer_next), `plan-phase.md` (step 14) and `discuss-phase.md` (auto_advance) use.
|
|
87
|
+
|
|
88
|
+
**P-1807 (2026-08, PanLoop finding 0):** these gates were previously `mode: yolo` alone. This file never read `--auto` or `workflow.auto_advance`, so on the template-default `mode: interactive`, exec-phase would announce "AUTO-ADVANCING → TRANSITION", this workflow would update state to the next phase, then route to the interactive "Next Up" menu and exit cleanly — the P-1801 Task spawn below was unreachable, and every autonomous run built exactly one phase while reporting success. Do not narrow these gates back to `mode` alone.
|
|
89
|
+
|
|
79
90
|
**If all plans complete:**
|
|
80
91
|
|
|
81
|
-
<if mode
|
|
92
|
+
<if auto (HAS_AUTO_FLAG > 0, or AUTO_CFG true, or mode yolo)>
|
|
82
93
|
|
|
83
94
|
```
|
|
84
95
|
⚡ Auto-approved: Transition Phase [X] → Phase [X+1]
|
|
@@ -91,7 +102,7 @@ Proceed directly to cleanup_handoff step.
|
|
|
91
102
|
|
|
92
103
|
</if>
|
|
93
104
|
|
|
94
|
-
<if mode="interactive" OR="custom with gates.confirm_transition true">
|
|
105
|
+
<if NOT auto — mode="interactive" OR="custom with gates.confirm_transition true">
|
|
95
106
|
|
|
96
107
|
Ask: "Phase [X] complete — all [Y] plans finished. Ready to mark done and move to Phase [X+1]?"
|
|
97
108
|
|
|
@@ -157,8 +168,9 @@ Extract from result: `completed_phase`, `plans_executed`, `next_phase`, `next_ph
|
|
|
157
168
|
|
|
158
169
|
<step name="archive_prompts">
|
|
159
170
|
|
|
160
|
-
If prompts were generated for the phase, they stay in place
|
|
161
|
-
|
|
171
|
+
If prompts were generated for the phase, they stay in place — plans and
|
|
172
|
+
summaries remain in the phase directory as the durable record. No separate
|
|
173
|
+
archival step is performed.
|
|
162
174
|
|
|
163
175
|
</step>
|
|
164
176
|
|
|
@@ -361,6 +373,8 @@ Resume file: None
|
|
|
361
373
|
|
|
362
374
|
<step name="offer_next_phase">
|
|
363
375
|
|
|
376
|
+
**AUTO-mode terminal contract (P-1807):** when AUTO is active (the condition from `verify_completion`), this step has exactly two valid endings — **Route A ends with a `Task(...)` call actually issued** (not described, not deferred: issued), or **Route B reaches the milestone boundary**. Updating state.md and presenting a "Next Up" menu is NOT a valid AUTO ending — field runs (PanLoop, 2026-08-08) show that exact exit four times in five even with the gates fixed. If you notice you are composing a menu while AUTO is active, stop and execute the Route A spawn. Do not end your turn between the state update and the spawn.
|
|
377
|
+
|
|
364
378
|
**MANDATORY: Verify milestone status before presenting next steps.**
|
|
365
379
|
|
|
366
380
|
**Use the transition result from `pan-tools phase complete`:**
|
|
@@ -392,10 +406,12 @@ ls .planning/phases/*[X+1]*/*-context.md 2>/dev/null
|
|
|
392
406
|
|
|
393
407
|
**If next phase exists:**
|
|
394
408
|
|
|
395
|
-
<if mode
|
|
409
|
+
<if auto (HAS_AUTO_FLAG > 0, or AUTO_CFG true, or mode yolo — the P-1807 condition from verify_completion)>
|
|
396
410
|
|
|
397
411
|
**P-1801 fix (v3.7.6):** In auto mode, **spawn the next phase as a Task subagent** — same pattern as `plan-phase.md`'s auto-advance to exec-phase. Prose-based "DO NOT exit. Read X" instructions (the v3.7.4 P-1701 attempt) were not behaviorally binding: the orchestrator returned from sub-agent calls and exited cleanly at the phase boundary. A `Task(...)` invocation is a tool call the orchestrator cannot ignore — control flow is forced into the next phase's workflow.
|
|
398
412
|
|
|
413
|
+
**P-1807 (2026-08):** this gate was `mode: yolo` alone, which made the P-1801 spawn unreachable for `--auto` / `workflow.auto_advance` runs on interactive-mode projects — the exact symptom P-1801 fixed, reintroduced one gate higher. If exec-phase announced AUTO-ADVANCING, this branch MUST run and MUST end in the `Task(...)` call below; exiting after the state update is the regression.
|
|
414
|
+
|
|
399
415
|
Cost trade-off: each Task spawn restarts context (loses the cumulative cache reads from the previous phase). Acceptable because: (1) cross-phase cache value is low — phase N's plan/research is mostly irrelevant to phase N+1's executor — and (2) reliability beats marginal cost optimization for autonomous runs.
|
|
400
416
|
|
|
401
417
|
**If context.md exists for the next phase:**
|
|
@@ -489,7 +505,7 @@ Task(
|
|
|
489
505
|
|
|
490
506
|
</if>
|
|
491
507
|
|
|
492
|
-
<if mode="interactive" OR="custom with gates.confirm_transition true">
|
|
508
|
+
<if NOT auto — mode="interactive" OR="custom with gates.confirm_transition true">
|
|
493
509
|
|
|
494
510
|
**If context.md does NOT exist:**
|
|
495
511
|
|
|
@@ -551,7 +567,7 @@ Task(
|
|
|
551
567
|
node ~/.claude/pan-wizard-core/bin/pan-tools.cjs config-set workflow.auto_advance false
|
|
552
568
|
```
|
|
553
569
|
|
|
554
|
-
<if mode
|
|
570
|
+
<if auto (HAS_AUTO_FLAG > 0, or AUTO_CFG true, or mode yolo — the P-1807 condition from verify_completion)>
|
|
555
571
|
|
|
556
572
|
```
|
|
557
573
|
Phase {X} marked complete.
|
|
@@ -565,7 +581,7 @@ Exit skill and invoke SlashCommand("/pan:milestone-done {version}")
|
|
|
565
581
|
|
|
566
582
|
</if>
|
|
567
583
|
|
|
568
|
-
<if mode="interactive" OR="custom with gates.confirm_transition true">
|
|
584
|
+
<if NOT auto — mode="interactive" OR="custom with gates.confirm_transition true">
|
|
569
585
|
|
|
570
586
|
```
|
|
571
587
|
## ✓ Phase {X}: {Phase Name} Complete
|
|
@@ -12,28 +12,31 @@ Read all files referenced by the invoking prompt's execution_context before star
|
|
|
12
12
|
Detect whether PAN is installed locally or globally by checking both locations and validating install integrity:
|
|
13
13
|
|
|
14
14
|
```bash
|
|
15
|
-
#
|
|
16
|
-
#
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
15
|
+
# There is ONE install location per install. The installer templates the
|
|
16
|
+
# canonical ~/.claude/ prefix to this install's real path, and the SHAPE of that
|
|
17
|
+
# templated prefix reveals the scope: a --local install is cwd-relative ("./…"),
|
|
18
|
+
# a --global install is an absolute path. Deriving scope from the single
|
|
19
|
+
# templated path avoids the collapsed dual-path detection that mis-ran every
|
|
20
|
+
# global update as --local (N2 regression fix, ADR audit 2026-08).
|
|
21
|
+
VERSION_FILE="~/.claude/pan-wizard-core/VERSION"
|
|
22
|
+
MARKER_FILE="~/.claude/pan-wizard-core/workflows/update.md"
|
|
23
|
+
case "$VERSION_FILE" in
|
|
24
|
+
./*) SCOPE="LOCAL" ;;
|
|
25
|
+
*) SCOPE="GLOBAL" ;;
|
|
26
|
+
esac
|
|
27
|
+
|
|
28
|
+
if [ -f "$VERSION_FILE" ] && [ -f "$MARKER_FILE" ] && grep -Eq '^[0-9]+\.[0-9]+\.[0-9]+' "$VERSION_FILE"; then
|
|
29
|
+
cat "$VERSION_FILE"
|
|
30
|
+
echo "$SCOPE"
|
|
28
31
|
else
|
|
29
32
|
echo "UNKNOWN"
|
|
30
33
|
fi
|
|
31
34
|
```
|
|
32
35
|
|
|
33
|
-
Parse output:
|
|
34
|
-
- If last line is "LOCAL":
|
|
35
|
-
- If last line is "GLOBAL":
|
|
36
|
-
- If "UNKNOWN": proceed to install step (treat as version 0.0.0)
|
|
36
|
+
Parse output (there is ONE install; scope is derived from the shape of the single templated prefix):
|
|
37
|
+
- If last line is "LOCAL": this install is local-scoped (templated prefix is `./`-relative); installed version is first line; use `--local`
|
|
38
|
+
- If last line is "GLOBAL": this install is global-scoped (templated prefix is an absolute path); installed version is first line; use `--global`
|
|
39
|
+
- If "UNKNOWN": the VERSION/marker files are missing or invalid; proceed to install step (treat as version 0.0.0)
|
|
37
40
|
|
|
38
41
|
**If VERSION file missing:**
|
|
39
42
|
```
|
|
@@ -166,7 +169,7 @@ Clear the update cache so statusline indicator disappears:
|
|
|
166
169
|
|
|
167
170
|
**If LOCAL install:**
|
|
168
171
|
```bash
|
|
169
|
-
rm -f
|
|
172
|
+
rm -f ~/.claude/cache/pan-update-check.json
|
|
170
173
|
```
|
|
171
174
|
|
|
172
175
|
**If GLOBAL install:**
|
|
@@ -184,9 +187,9 @@ Format completion message (changelog was already shown in confirmation step):
|
|
|
184
187
|
║ PAN Updated: v1.5.10 → v1.5.15 ║
|
|
185
188
|
╚═══════════════════════════════════════════════════════════╝
|
|
186
189
|
|
|
187
|
-
⚠️ Restart
|
|
190
|
+
⚠️ Restart your AI coding tool to pick up the new commands.
|
|
188
191
|
|
|
189
|
-
[View full changelog](https://github.com/
|
|
192
|
+
[View full changelog](https://github.com/oharms/PanWizard/blob/main/CHANGELOG.md)
|
|
190
193
|
```
|
|
191
194
|
</step>
|
|
192
195
|
|
|
@@ -50,7 +50,7 @@ Extract from init JSON: `phase_dir`, `phase_number`, `phase_name`, `has_plans`,
|
|
|
50
50
|
Then load phase details and list plans/summaries:
|
|
51
51
|
```bash
|
|
52
52
|
node ~/.claude/pan-wizard-core/bin/pan-tools.cjs roadmap get-phase "${phase_number}"
|
|
53
|
-
grep -E "^|
|
|
53
|
+
grep -E "^\|[^|]*\| *Phase +${phase_number} " .planning/requirements.md 2>/dev/null
|
|
54
54
|
ls "$phase_dir"/*-summary.md "$phase_dir"/*-plan.md 2>/dev/null
|
|
55
55
|
```
|
|
56
56
|
|
|
@@ -63,7 +63,12 @@ Extract **phase goal** from roadmap.md (the outcome to verify, not tasks) and **
|
|
|
63
63
|
If `phase_number` > 1:
|
|
64
64
|
```bash
|
|
65
65
|
PREV=$((phase_number - 1))
|
|
66
|
-
|
|
66
|
+
# Resolve the previous phase's directory via find-phase (handles zero-padding
|
|
67
|
+
# and the .planning/phases/ layout), like exec-phase does — do NOT glob
|
|
68
|
+
# .planning/phase-N*/ (wrong dir, unpadded, matches nothing). With --raw,
|
|
69
|
+
# find-phase prints the resolved directory path (empty if not found).
|
|
70
|
+
PREV_DIR=$(node ~/.claude/pan-wizard-core/bin/pan-tools.cjs find-phase "${PREV}" --raw 2>/dev/null)
|
|
71
|
+
PREV_VERIF=$([ -n "$PREV_DIR" ] && ls "$PREV_DIR"/*-verification.md 2>/dev/null | head -1)
|
|
67
72
|
```
|
|
68
73
|
|
|
69
74
|
If `PREV_VERIF` is empty:
|
package/pan-zcode/README.md
CHANGED
|
@@ -28,8 +28,11 @@ pan-wizard-core (reused as-is) the deterministic engine; .planning/ stays the
|
|
|
28
28
|
- **M1 — bridge core.** `mcp/tool-registry.cjs` (pure verb→tool/resource map, with a hard
|
|
29
29
|
guardrail against exposing a force/reset/rebase/push verb) + `mcp/server.cjs` (a
|
|
30
30
|
**zero-dependency** JSON-RPC 2.0 stdio MCP server; reads → resources, actions → tools with
|
|
31
|
-
accurate hints; shell-less `execFile` spawn; `@file:` overflow protocol;
|
|
32
|
-
|
|
31
|
+
accurate hints; shell-less `execFile` spawn; `@file:` overflow protocol; strict per-arg
|
|
32
|
+
validation). **Dual-era** per the MCP 2026-07-28 stateless spec (ADR-0041): legacy clients
|
|
33
|
+
use the `initialize` handshake; modern clients declare their protocol version in each
|
|
34
|
+
request's `_meta`, probe `server/discover`, and get `UnsupportedProtocolVersionError`
|
|
35
|
+
(`-32022`) on a version mismatch.
|
|
33
36
|
- **M2 — determinism grafts.** `mcp/merge-gate.cjs` (two-step, model-proof merge: a human-origin
|
|
34
37
|
env token that ignores agent-supplied approval; never force/reset/push) + `mcp/orchestrator.cjs`
|
|
35
38
|
(the deterministic `next-action` state machine with safety caps + regression circuit-breaker),
|
|
@@ -52,6 +55,13 @@ Two go/no-go facts can only be settled empirically: **can a subagent call MCP to
|
|
|
52
55
|
local stdio MCP calls metered?** Both have folded-in fallbacks (see `KNOWN-BETA-RISKS.md`), so the
|
|
53
56
|
design holds either way — but confirm them before relying on the richer paths.
|
|
54
57
|
|
|
58
|
+
A third M0 checkpoint (added 2026-08): **which protocol era does the real ZCode client speak?**
|
|
59
|
+
The bridge is now dual-era (ADR-0041), so it answers both a legacy `initialize` handshake and a
|
|
60
|
+
modern `server/discover` probe. Confirm on a real install which path ZCode takes and that the
|
|
61
|
+
version it declares is in our supported list; if ZCode ever declares a revision newer than
|
|
62
|
+
`2026-07-28`, add it to `SUPPORTED_VERSIONS_LIST` in `mcp/server.cjs` once its method shapes are
|
|
63
|
+
implemented.
|
|
64
|
+
|
|
55
65
|
## Zero dependencies
|
|
56
66
|
|
|
57
67
|
Like the rest of PAN, this subsystem ships **no runtime dependencies**. The MCP protocol is
|
|
@@ -48,7 +48,7 @@ PAN-Z bridges PAN's engine to ZCode over MCP. Finish setup inside ZCode:
|
|
|
48
48
|
3. **Protect your branches.** The merge gate (\`pan_confirm_merge\`) is one lock; the
|
|
49
49
|
real, non-bypassable one is **server-side branch protection** on your remote. Enable
|
|
50
50
|
required reviews so a raw push under Full Access cannot merge. Approve a staged merge
|
|
51
|
-
by setting \`PAN_MERGE_APPROVAL=<
|
|
51
|
+
by setting \`PAN_MERGE_APPROVAL=<approval_token>\` in the MCP server's environment.
|
|
52
52
|
|
|
53
53
|
4. **Never run the install/import step in ZCode Full Access mode.**
|
|
54
54
|
|
|
@@ -43,7 +43,7 @@ const NATIVE_TOOLS = [
|
|
|
43
43
|
{
|
|
44
44
|
name: 'pan_confirm_merge',
|
|
45
45
|
title: 'Confirm a human-approved merge',
|
|
46
|
-
description: 'Perform a squash-merge ONLY if CI is green, verify passed, and a human-origin approval token (env PAN_MERGE_APPROVAL equal to the request
|
|
46
|
+
description: 'Perform a squash-merge ONLY if CI is green, verify passed, and a human-origin approval token (env PAN_MERGE_APPROVAL equal to the request\'s approval_token) is present. Any agent-supplied approval is ignored; never force-pushes or rewrites history.',
|
|
47
47
|
readOnly: false, destructive: true,
|
|
48
48
|
inputSchema: {
|
|
49
49
|
type: 'object', additionalProperties: false, required: ['branch'],
|
package/pan-zcode/mcp/server.cjs
CHANGED
|
@@ -4,8 +4,12 @@
|
|
|
4
4
|
* PAN-Z MCP bridge server (M1).
|
|
5
5
|
*
|
|
6
6
|
* A dependency-free JSON-RPC 2.0 server over stdio implementing the small MCP
|
|
7
|
-
* surface ZCode needs: initialize / tools/list / tools/call /
|
|
8
|
-
* resources/read / ping.
|
|
7
|
+
* surface ZCode needs: server/discover / initialize / tools/list / tools/call /
|
|
8
|
+
* resources/list / resources/read / ping. It is a DUAL-ERA server (see the MCP
|
|
9
|
+
* 2026-07-28 versioning spec): legacy clients open with the `initialize`
|
|
10
|
+
* handshake; modern clients (2026-07-28+) declare their protocol version in each
|
|
11
|
+
* request's `_meta` and MAY probe `server/discover` first. Each pan-tools verb is
|
|
12
|
+
* reached by spawning
|
|
9
13
|
* node <pan-tools.cjs> <verb> [args] --raw --cwd <root>
|
|
10
14
|
* and returning its JSON — the CLI's JSON contract IS the tool contract, so the
|
|
11
15
|
* PAN engine (pan-wizard-core) is reused byte-for-byte with no refactor.
|
|
@@ -26,11 +30,21 @@ const os = require('os');
|
|
|
26
30
|
const path = require('path');
|
|
27
31
|
const reg = require('./tool-registry.cjs');
|
|
28
32
|
|
|
33
|
+
// Legacy `initialize` default: when a handshake-era client omits protocolVersion
|
|
34
|
+
// we answer with this (never a modern version — a legacy client can't speak it).
|
|
29
35
|
const PROTOCOL_VERSION = '2025-06-18';
|
|
30
|
-
//
|
|
31
|
-
|
|
32
|
-
//
|
|
33
|
-
const
|
|
36
|
+
// The modern (per-request `_meta`, stateless) revision this bridge speaks.
|
|
37
|
+
const MODERN_PROTOCOL_VERSION = '2026-07-28';
|
|
38
|
+
// `_meta` key a modern client uses to declare its protocol version per request.
|
|
39
|
+
const META_PROTOCOL_VERSION_KEY = 'io.modelcontextprotocol/protocolVersion';
|
|
40
|
+
// `_meta` key under which a server identifies itself in modern results.
|
|
41
|
+
const META_SERVER_INFO_KEY = 'io.modelcontextprotocol/serverInfo';
|
|
42
|
+
// Every version whose method shapes this server actually implements — the modern
|
|
43
|
+
// revision plus the legacy handshake revisions. Used both for the legacy
|
|
44
|
+
// `initialize` echo and for modern per-request version negotiation; we never
|
|
45
|
+
// claim to speak a version we don't. Newest first (the `server/discover` order).
|
|
46
|
+
const SUPPORTED_VERSIONS_LIST = [MODERN_PROTOCOL_VERSION, '2025-06-18', '2025-03-26', '2024-11-05'];
|
|
47
|
+
const SUPPORTED_PROTOCOL_VERSIONS = new Set(SUPPORTED_VERSIONS_LIST);
|
|
34
48
|
const SERVER_INFO = { name: 'pan-mcp', version: '0.1.0' };
|
|
35
49
|
|
|
36
50
|
/** Default engine location: pan-wizard-core is a sibling of pan-zcode/. */
|
|
@@ -77,7 +91,11 @@ function resolveOverflow(stdout) {
|
|
|
77
91
|
}
|
|
78
92
|
|
|
79
93
|
function rpcResult(id, result) { return { jsonrpc: '2.0', id, result }; }
|
|
80
|
-
function rpcError(id, code, message
|
|
94
|
+
function rpcError(id, code, message, data) {
|
|
95
|
+
const error = { code, message };
|
|
96
|
+
if (data !== undefined) error.data = data;
|
|
97
|
+
return { jsonrpc: '2.0', id, error };
|
|
98
|
+
}
|
|
81
99
|
|
|
82
100
|
function toMcpTool(t) {
|
|
83
101
|
return {
|
|
@@ -173,26 +191,67 @@ function createServer(opts = {}) {
|
|
|
173
191
|
// the dispatch — this also stops any request-method sent id-less from emitting
|
|
174
192
|
// an id-less response frame.
|
|
175
193
|
if (id === undefined || id === null) return null;
|
|
194
|
+
|
|
195
|
+
// Era detection: a modern client (2026-07-28+) declares its protocol version
|
|
196
|
+
// in `_meta` on every request; a legacy client uses the `initialize` handshake
|
|
197
|
+
// and carries no such field. Gating modern behavior on this presence keeps the
|
|
198
|
+
// legacy path byte-for-byte unchanged.
|
|
199
|
+
const requestedVersion = params && params._meta && params._meta[META_PROTOCOL_VERSION_KEY];
|
|
200
|
+
const isModern = typeof requestedVersion === 'string';
|
|
201
|
+
|
|
202
|
+
// Stateless per-request version negotiation: if a modern client asks for a
|
|
203
|
+
// version we don't implement, answer with UnsupportedProtocolVersionError
|
|
204
|
+
// listing what we do support, so it can retry on a mutually-supported version.
|
|
205
|
+
if (isModern && !SUPPORTED_PROTOCOL_VERSIONS.has(requestedVersion)) {
|
|
206
|
+
return rpcError(id, -32022, 'Unsupported protocol version',
|
|
207
|
+
{ supported: SUPPORTED_VERSIONS_LIST, requested: requestedVersion });
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// Modern results MUST carry a `resultType`; legacy results MUST NOT change
|
|
211
|
+
// shape (clients treat an absent resultType as "complete"). Stamp it only on
|
|
212
|
+
// the modern path.
|
|
213
|
+
const reply = (result) => rpcResult(id,
|
|
214
|
+
isModern && result && typeof result === 'object' && result.resultType === undefined
|
|
215
|
+
? { resultType: 'complete', ...result }
|
|
216
|
+
: result);
|
|
217
|
+
|
|
176
218
|
switch (method) {
|
|
219
|
+
// Modern stateless discovery probe (MUST be implemented). Also the stdio
|
|
220
|
+
// backward-compat probe: a dual-era client sends this first; a real
|
|
221
|
+
// DiscoverResult identifies us as modern-capable, and its supportedVersions
|
|
222
|
+
// let the client pick a version before issuing any tools/resources call.
|
|
223
|
+
case 'server/discover':
|
|
224
|
+
return rpcResult(id, {
|
|
225
|
+
resultType: 'complete',
|
|
226
|
+
supportedVersions: SUPPORTED_VERSIONS_LIST,
|
|
227
|
+
capabilities: { tools: {}, resources: {} },
|
|
228
|
+
instructions: 'PAN Wizard engine bridge: planning, verification, and orchestration tools backed by the pan-tools CLI. All tools are read-only except the gated pan_confirm_merge.',
|
|
229
|
+
ttlMs: 3600000,
|
|
230
|
+
cacheScope: 'public',
|
|
231
|
+
_meta: { [META_SERVER_INFO_KEY]: SERVER_INFO },
|
|
232
|
+
});
|
|
177
233
|
case 'initialize': {
|
|
178
234
|
const requested = params && params.protocolVersion;
|
|
179
|
-
|
|
235
|
+
// A legacy handshake must not negotiate a modern (per-request `_meta`)
|
|
236
|
+
// revision, so only echo legacy versions; anything else falls back.
|
|
237
|
+
const negotiated = (requested && requested !== MODERN_PROTOCOL_VERSION
|
|
238
|
+
&& SUPPORTED_PROTOCOL_VERSIONS.has(requested)) ? requested : PROTOCOL_VERSION;
|
|
180
239
|
return rpcResult(id, { protocolVersion: negotiated, capabilities: { tools: {}, resources: {} }, serverInfo: SERVER_INFO });
|
|
181
240
|
}
|
|
182
241
|
case 'ping':
|
|
183
|
-
return
|
|
242
|
+
return reply({});
|
|
184
243
|
case 'tools/list':
|
|
185
|
-
return
|
|
244
|
+
return reply({ tools: reg.TOOLS.map(toMcpTool) });
|
|
186
245
|
case 'resources/list':
|
|
187
|
-
return
|
|
246
|
+
return reply({ resources: reg.RESOURCES.map(toMcpResource) });
|
|
188
247
|
case 'tools/call': {
|
|
189
248
|
const out = callTool(params && params.name, params && params.arguments);
|
|
190
|
-
return out.error ? rpcError(id, out.error.code, out.error.message) :
|
|
249
|
+
return out.error ? rpcError(id, out.error.code, out.error.message) : reply(out.result);
|
|
191
250
|
}
|
|
192
251
|
case 'resources/read': {
|
|
193
252
|
const out = readResource(params && params.uri);
|
|
194
253
|
if (out.unknown) return rpcError(id, -32602, `Unknown resource: ${params && params.uri}`);
|
|
195
|
-
return out.error ? rpcError(id, out.error.code, out.error.message) :
|
|
254
|
+
return out.error ? rpcError(id, out.error.code, out.error.message) : reply(out.result);
|
|
196
255
|
}
|
|
197
256
|
default:
|
|
198
257
|
return rpcError(id, -32601, `Method not found: ${method}`);
|
|
@@ -226,4 +285,7 @@ function main() {
|
|
|
226
285
|
|
|
227
286
|
if (require.main === module) main();
|
|
228
287
|
|
|
229
|
-
module.exports = {
|
|
288
|
+
module.exports = {
|
|
289
|
+
createServer, defaultPanToolsPath, defaultSpawn, SERVER_INFO, toMcpTool, toMcpResource,
|
|
290
|
+
PROTOCOL_VERSION, MODERN_PROTOCOL_VERSION, SUPPORTED_VERSIONS_LIST, META_PROTOCOL_VERSION_KEY,
|
|
291
|
+
};
|
package/scripts/build-hooks.js
CHANGED
|
@@ -232,8 +232,6 @@ def generate_full_text(shipped: list[Skill], dev: list[Skill], version: str) ->
|
|
|
232
232
|
w("Every skill (slash command) available in PAN Wizard, reproduced in full.")
|
|
233
233
|
w("This is the actual prompt text that Claude receives when a skill is invoked.")
|
|
234
234
|
w("")
|
|
235
|
-
w(f"**Version:** {version}")
|
|
236
|
-
w("")
|
|
237
235
|
w("> Auto-generated by `scripts/generate-skills-docs.py` — do not edit manually.")
|
|
238
236
|
w("> For canonical counts (commands / agents / modules / etc.), see `CLAUDE.md`.")
|
|
239
237
|
w("")
|
|
@@ -330,8 +328,6 @@ def generate_reference(shipped: list[Skill], dev: list[Skill], version: str) ->
|
|
|
330
328
|
w("Complete catalog of every skill (slash command) available in PAN Wizard, organized by purpose.")
|
|
331
329
|
w("Each entry shows the command, what it does, what tools it uses, and when to reach for it.")
|
|
332
330
|
w("")
|
|
333
|
-
w(f"**Version:** {version}")
|
|
334
|
-
w("")
|
|
335
331
|
w("> Auto-generated by `scripts/generate-skills-docs.py` — do not edit manually.")
|
|
336
332
|
w("> For canonical counts (commands / agents / modules / etc.), see `CLAUDE.md`.")
|
|
337
333
|
w("")
|
package/scripts/run-tests.cjs
CHANGED
|
@@ -6,18 +6,24 @@
|
|
|
6
6
|
* literal pattern "tests/*.test.cjs" matches no file and the run exits 1.
|
|
7
7
|
* This script expands the pattern deterministically on every platform.
|
|
8
8
|
*
|
|
9
|
-
* Usage: node scripts/run-tests.cjs <dir> [<dir> ...]
|
|
9
|
+
* Usage: node scripts/run-tests.cjs [--watch] <dir> [<dir> ...]
|
|
10
10
|
* Runs every *.test.cjs DIRECTLY inside each listed directory (no recursion,
|
|
11
11
|
* so `tests` and `tests/scenarios` stay separately addressable).
|
|
12
|
+
* --watch re-runs on change. It must go through this script too: since Node 21
|
|
13
|
+
* a bare `node --test --watch tests/` treats `tests/` as a glob pattern, fails
|
|
14
|
+
* to match the directory as a file, and crashes having run nothing (audit L36 /
|
|
15
|
+
* N8) — so the same deterministic expansion has to feed --watch.
|
|
12
16
|
*/
|
|
13
17
|
|
|
14
18
|
const { spawnSync } = require('child_process');
|
|
15
19
|
const fs = require('fs');
|
|
16
20
|
const path = require('path');
|
|
17
21
|
|
|
18
|
-
const
|
|
22
|
+
const argv = process.argv.slice(2);
|
|
23
|
+
const watch = argv[0] === '--watch';
|
|
24
|
+
const dirs = watch ? argv.slice(1) : argv;
|
|
19
25
|
if (dirs.length === 0) {
|
|
20
|
-
console.error('Usage: node scripts/run-tests.cjs <dir> [<dir> ...]');
|
|
26
|
+
console.error('Usage: node scripts/run-tests.cjs [--watch] <dir> [<dir> ...]');
|
|
21
27
|
process.exit(1);
|
|
22
28
|
}
|
|
23
29
|
|
|
@@ -40,5 +46,6 @@ if (files.length === 0) {
|
|
|
40
46
|
process.exit(1);
|
|
41
47
|
}
|
|
42
48
|
|
|
43
|
-
const
|
|
49
|
+
const nodeArgs = watch ? ['--test', '--watch', ...files] : ['--test', ...files];
|
|
50
|
+
const result = spawnSync(process.execPath, nodeArgs, { stdio: 'inherit' });
|
|
44
51
|
process.exit(result.status ?? 1);
|