pan-wizard 3.25.0 → 3.27.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 +1 -1
- package/bin/install-lib.cjs +283 -1
- package/bin/install.js +127 -0
- package/commands/pan/hygiene.md +14 -8
- package/commands/pan/milestone-audit.md +10 -4
- package/hooks/dist/pan-cost-logger.js +69 -5
- package/hooks/dist/pan-stop-guard.js +32 -1
- package/hooks/dist/pan-trace-logger.js +35 -2
- package/package.json +3 -2
- package/pan-wizard-core/bin/lib/bridge.cjs +0 -1
- package/pan-wizard-core/bin/lib/bus.cjs +0 -1
- package/pan-wizard-core/bin/lib/campaign.cjs +3 -2
- package/pan-wizard-core/bin/lib/commands-learnings.cjs +8 -8
- package/pan-wizard-core/bin/lib/commands.cjs +15 -14
- package/pan-wizard-core/bin/lib/config.cjs +5 -5
- package/pan-wizard-core/bin/lib/constants.cjs +27 -0
- package/pan-wizard-core/bin/lib/context-budget.cjs +28 -0
- package/pan-wizard-core/bin/lib/core.cjs +190 -26
- package/pan-wizard-core/bin/lib/cost.cjs +0 -1
- package/pan-wizard-core/bin/lib/distill.cjs +3 -3
- package/pan-wizard-core/bin/lib/focus.cjs +16 -16
- package/pan-wizard-core/bin/lib/hud.cjs +1 -1
- package/pan-wizard-core/bin/lib/hygiene.cjs +397 -37
- package/pan-wizard-core/bin/lib/init.cjs +90 -13
- package/pan-wizard-core/bin/lib/knowledge.cjs +0 -1
- package/pan-wizard-core/bin/lib/memory.cjs +1 -1
- package/pan-wizard-core/bin/lib/milestone.cjs +3 -3
- package/pan-wizard-core/bin/lib/optimize.cjs +3 -3
- package/pan-wizard-core/bin/lib/phase.cjs +4 -4
- package/pan-wizard-core/bin/lib/planning-root.cjs +327 -0
- package/pan-wizard-core/bin/lib/preview.cjs +0 -1
- package/pan-wizard-core/bin/lib/review-deep.cjs +0 -1
- package/pan-wizard-core/bin/lib/roadmap.cjs +1 -1
- package/pan-wizard-core/bin/lib/state-compact.cjs +339 -0
- package/pan-wizard-core/bin/lib/state.cjs +0 -1
- package/pan-wizard-core/bin/lib/suggest.cjs +141 -0
- package/pan-wizard-core/bin/lib/template.cjs +1 -1
- package/pan-wizard-core/bin/lib/utils.cjs +39 -11
- package/pan-wizard-core/bin/lib/verify-deploy.cjs +113 -2
- package/pan-wizard-core/bin/lib/verify.cjs +4 -3
- package/pan-wizard-core/bin/lib/whatif.cjs +0 -1
- package/pan-wizard-core/bin/pan-tools.cjs +97 -7
- package/pan-wizard-core/mcp/native-tools.cjs +159 -0
- package/pan-wizard-core/mcp/orchestrator.cjs +179 -0
- package/{pan-zcode → pan-wizard-core}/mcp/server.cjs +35 -6
- package/{pan-zcode → pan-wizard-core}/mcp/tool-registry.cjs +60 -3
- package/pan-wizard-core/workflows/milestone-audit.md +35 -6
- package/pan-wizard-core/workflows/verify-phase.md +25 -6
- package/pan-zcode/README.md +17 -9
- package/pan-zcode/bin/install-zcode.js +4 -1
- package/scripts/build-plugin.js +35 -3
- package/scripts/deprecate-old-versions.js +225 -0
- package/scripts/plugin-path.js +84 -0
- package/pan-wizard-core/learnings/internal/.gitkeep +0 -2
- package/pan-wizard-core/learnings/internal/experiment-runner.md +0 -81
- package/pan-wizard-core/learnings/internal/external-research.md +0 -105
- package/pan-wizard-core/learnings/internal/loop-design.md +0 -33
- package/pan-wizard-core/learnings/internal/pan-dev-bugs.md +0 -181
- package/pan-zcode/mcp/native-tools.cjs +0 -63
- package/pan-zcode/mcp/orchestrator.cjs +0 -66
- /package/{pan-zcode → pan-wizard-core}/mcp/merge-gate.cjs +0 -0
|
@@ -1,181 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
topic: pan-dev-bugs
|
|
3
|
-
last_updated: 2026-04-27T14:36:56.341Z
|
|
4
|
-
patterns:
|
|
5
|
-
- id: P-101
|
|
6
|
-
summary: experiment.cjs newExperiment does not persist status='ready' update after installer success
|
|
7
|
-
promoted_at: 2026-04-27T09:26:39.526Z
|
|
8
|
-
source_experiments: [whooo]
|
|
9
|
-
- id: P-102
|
|
10
|
-
summary: runner.cjs spawnSync fails on Windows for CLI tools without explicit .cmd resolution
|
|
11
|
-
promoted_at: 2026-04-27T09:26:39.618Z
|
|
12
|
-
source_experiments: [whooo]
|
|
13
|
-
- id: P-301
|
|
14
|
-
summary: PAN's commands/pan/*.md has 9 real frontmatter consistency bugs surfaced by the whooo dogfood gate
|
|
15
|
-
promoted_at: 2026-04-27T09:49:20.847Z
|
|
16
|
-
source_experiments: [whooo]
|
|
17
|
-
- id: P-1301
|
|
18
|
-
summary: /pan:new-project --auto workflow invokes AskUserQuestion for depth/execution/git-tracking despite --auto, blocking autonomous runs
|
|
19
|
-
promoted_at: 2026-04-27T11:21:36.615Z
|
|
20
|
-
source_experiments: [panloop]
|
|
21
|
-
- id: P-1302
|
|
22
|
-
summary: runner.cjs claude adapter must include --dangerously-skip-permissions for autonomous runs
|
|
23
|
-
promoted_at: 2026-04-27T11:21:36.712Z
|
|
24
|
-
source_experiments: [panloop]
|
|
25
|
-
- id: P-1304
|
|
26
|
-
summary: runner.cjs spawnSync with shell:true on Windows doesn't quote multi-word args; cmd.exe re-splits them
|
|
27
|
-
promoted_at: 2026-04-27T11:38:25.897Z
|
|
28
|
-
source_experiments: [panloop]
|
|
29
|
-
- id: P-1401
|
|
30
|
-
summary: Lightweight phases (scaffolding-only, single plan) over-ceremonialize: 5 commits + 5-7 min for trivial work
|
|
31
|
-
promoted_at: 2026-04-27T12:01:14.083Z
|
|
32
|
-
source_experiments: [panloop]
|
|
33
|
-
- id: P-1402
|
|
34
|
-
summary: Per-phase researcher re-derives material already covered by project-level research
|
|
35
|
-
promoted_at: 2026-04-27T12:01:14.179Z
|
|
36
|
-
source_experiments: [panloop]
|
|
37
|
-
- id: P-1404
|
|
38
|
-
summary: Auto-trace SubagentStop hook covers only some agents — pan-roadmapper logged but pan-planner/executor/verifier did not
|
|
39
|
-
promoted_at: 2026-04-27T12:01:14.367Z
|
|
40
|
-
source_experiments: [panloop]
|
|
41
|
-
- id: P-1501
|
|
42
|
-
summary: claude -p autonomous session exits after Phase 0 setup; multi-step workflows don't drive headless mode forward without explicit tool calls
|
|
43
|
-
promoted_at: 2026-04-27T12:11:40.314Z
|
|
44
|
-
source_experiments: [panloop2]
|
|
45
|
-
superseded_by: P-1501-r3
|
|
46
|
-
supersession_note: Original P-1501 hypothesis (workflows don't drive headless forward) was refined by P-1501-r2 (no-TTY root cause) and again by P-1501-r3 (TTY chain inheritance, stdio:'inherit' insufficient). Latest current rule lives at P-1501-r3.
|
|
47
|
-
- id: P-1502
|
|
48
|
-
summary: runner.cjs exit_code=0 is too coarse — should validate milestone-completion before declaring success
|
|
49
|
-
promoted_at: 2026-04-27T12:11:40.408Z
|
|
50
|
-
source_experiments: [panloop2]
|
|
51
|
-
- id: P-1701
|
|
52
|
-
summary: Multi-phase (3+) autonomous workflows exit at phase boundaries with /clear-and-rerun instructions; loop is autonomous WITHIN a phase, not across phases
|
|
53
|
-
promoted_at: 2026-04-27T12:43:48.397Z
|
|
54
|
-
source_experiments: [panmd2]
|
|
55
|
-
- id: P-1501-r2
|
|
56
|
-
summary: P-1501 root cause refined: runner.cjs spawnSync({stdio:[ignore,pipe,pipe]}) lacks TTY; manual bash invocation has TTY; claude -p detects no-TTY and exits after first response loop
|
|
57
|
-
promoted_at: 2026-04-27T12:43:48.469Z
|
|
58
|
-
source_experiments: [panmd2]
|
|
59
|
-
superseded_by: P-1501-r3
|
|
60
|
-
supersession_note: stdio:'inherit' fix proposed here turned out to be insufficient when the grandparent itself lacks TTY — see P-1501-r3.
|
|
61
|
-
- id: P-1501-r3
|
|
62
|
-
summary: P-1501 stdio:'inherit' fix is INSUFFICIENT when the grandparent (script/CI/tool) has no TTY itself
|
|
63
|
-
promoted_at: 2026-04-27T14:36:56.341Z
|
|
64
|
-
source_experiments: [panmd3]
|
|
65
|
-
---
|
|
66
|
-
|
|
67
|
-
# Pan Dev Bugs (AI-derived)
|
|
68
|
-
|
|
69
|
-
> Auto-maintained by `pan-tools learn promote`. Each pattern was extracted from one or more experiment runs (see source_experiments). Patterns are **advisory** — orchestrators should weight them against current context.
|
|
70
|
-
|
|
71
|
-
## P-101 — experiment.cjs newExperiment does not persist status='ready' update after installer success
|
|
72
|
-
|
|
73
|
-
**Evidence:** whooo experiment: after successful installer run, in-memory manifest had status='ready' but the file write in newExperiment skipped the persistence. On-disk experiment.json shows status='scaffolded'.
|
|
74
|
-
|
|
75
|
-
**Rule:** In experiment.cjs newExperiment: after manifest.status='ready' assignment (line ~155 in v3.7.0), add fs.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2)) to persist the success status. 3-line fix; ship as v3.7.1.
|
|
76
|
-
|
|
77
|
-
**Applies in:** experiment.cjs maintenance, v3.7.x patches
|
|
78
|
-
|
|
79
|
-
## P-102 — runner.cjs spawnSync fails on Windows for CLI tools without explicit .cmd resolution
|
|
80
|
-
|
|
81
|
-
**Evidence:** whooo experiment: tried to spawn node via runtime-override; got ENOENT on Windows because spawnSync with shell:false doesn't resolve .cmd shims. Forced fallback to direct build instead of subprocess invocation.
|
|
82
|
-
|
|
83
|
-
**Rule:** In runner.cjs runExperiment: on Windows, either set shell:true OR resolve adapter.bin to its .cmd/.exe equivalent before spawnSync. Currently the runner is unusable on Windows for any CLI tool that ships only as .cmd (claude, gemini, codex via npx, etc.).
|
|
84
|
-
|
|
85
|
-
**Applies in:** runner.cjs cross-platform fix; v3.7.x patches
|
|
86
|
-
|
|
87
|
-
## P-301 — PAN's commands/pan/*.md has 9 real frontmatter consistency bugs surfaced by the whooo dogfood gate
|
|
88
|
-
|
|
89
|
-
**Evidence:** whooo dogfood final report (51ms across 52 files): optimize.md missing frontmatter; patches.md missing name field plus description as array; phase-tests.md uses multi-line block-scalar values; todo-add.md and todo-check.md have description as array (should be string). Reproducible via: node bin/whooo.js lint --dir d:/PanWizard/commands/pan --schema test/fixtures/pan-cmd.schema.yml
|
|
90
|
-
|
|
91
|
-
**Rule:** Ship a v3.7.x patch fixing the 9 known consistency issues in PAN's commands/pan/. Vendor whooo (or write equivalent) and add pan-tools doc-lint to the /pan:check flow so future drift is caught at author time, not by users at install.
|
|
92
|
-
|
|
93
|
-
**Applies in:** v3.7.x patch planning; /pan:check workflow extension; commands/pan/ maintenance
|
|
94
|
-
|
|
95
|
-
## P-1301 — /pan:new-project --auto workflow invokes AskUserQuestion for depth/execution/git-tracking despite --auto, blocking autonomous runs
|
|
96
|
-
|
|
97
|
-
**Evidence:** panloop sess-real-loop-2026-04-27 11:17:45Z error (critical): claude -p result includes permission_denials with tool_name=AskUserQuestion + 3 questions (Depth, Execution, Git Tracking). Workflow stalled after 5 turns / 910 output tokens / $0.33. The first real autonomous loop run (the loop's own design hypothesis) is blocked by this.
|
|
98
|
-
|
|
99
|
-
**Rule:** Audit pan-wizard-core/workflows/new-project.md auto-mode handling. When --auto is set, AskUserQuestion calls must be replaced with: (a) defaults from config.json, (b) overrides from idea.md frontmatter (e.g. planning_depth: quick), or (c) inferred values from idea content. Same audit applies to any other PAN workflow with an --auto/--yes/--non-interactive flag (plan-phase, milestone-new, etc.). Ship as v3.7.2 patch — this blocks the v3.7.0 self-improvement loop's own design intent.
|
|
100
|
-
|
|
101
|
-
**Applies in:** pan-wizard-core/workflows/new-project.md auto-mode block; v3.7.2 patch planning; audit of all --auto-flagged workflows
|
|
102
|
-
|
|
103
|
-
## P-1302 — runner.cjs claude adapter must include --dangerously-skip-permissions for autonomous runs
|
|
104
|
-
|
|
105
|
-
**Evidence:** panloop sess-real-loop-2026-04-27: claude -p WITHOUT this flag prompts for tool permissions, can't be answered in headless mode, exits 1 silently. Manual reproduction with the flag added: workflow proceeds to AskUserQuestion (separate finding P-1301)
|
|
106
|
-
|
|
107
|
-
**Rule:** In pan-wizard-core/bin/lib/runner.cjs RUNTIME_RUNNERS, add extraArgs: ['--dangerously-skip-permissions'] to the claude adapter (and equivalent flags for codex/gemini/opencode). The runner's purpose is autonomous execution — defaulting to interactive permission prompts contradicts the runner's design. Optionally gate behind opts.skipPermissions=true for paranoid users, but default ON for headless production. Document trade-off in adapter comment + ADR-0026 update.
|
|
108
|
-
|
|
109
|
-
**Applies in:** v3.7.2 patch — runner.cjs adapters
|
|
110
|
-
|
|
111
|
-
## P-1304 — runner.cjs spawnSync with shell:true on Windows doesn't quote multi-word args; cmd.exe re-splits them
|
|
112
|
-
|
|
113
|
-
**Evidence:** panloop second autonomous run (post-P-1302 fix): claude -p exited 1 in 538ms because the prompt /pan:new-project --auto @.planning/idea.md was passed as 4 args but Node joined them with spaces under shell:true without quoting, so cmd.exe re-split it into 6 args. Manual reproduction with the prompt quoted worked fine (10+ min real autonomous workflow ran).
|
|
114
|
-
|
|
115
|
-
**Rule:** When passing args to spawnSync({shell:true}), Node joins them with spaces and the shell re-parses. Multi-word args (prompts, paths with spaces) MUST be quoted by the caller. Fix in runner.cjs: when useShell is true, wrap any arg containing whitespace in double-quotes and double any embedded double-quote (cmd.exe convention). Apply same fix in any other place pan-wizard-core uses spawnSync({shell:true}).
|
|
116
|
-
|
|
117
|
-
**Applies in:** v3.7.2 patch — runner.cjs runExperiment, audit other shell:true call sites
|
|
118
|
-
|
|
119
|
-
## P-1401 — Lightweight phases (scaffolding-only, single plan) over-ceremonialize: 5 commits + 5-7 min for trivial work
|
|
120
|
-
|
|
121
|
-
**Evidence:** panloop run: Phase 1 (project setup — package.json + dirs + CLI stub, ~10 LOC of work) went through full context+research+plan+execute+summary+close. 5 commits, ~5-7 min wall clock.
|
|
122
|
-
|
|
123
|
-
**Rule:** PAN should detect 'phase has 1 plan with simple feat/chore-class work' and skip per-phase research + plan-checker stages, deferring directly from context to execute. Save ~3 commits and ~5 min per trivial phase. Heuristic: if plan count == 1 AND plan tasks count <= 3 AND no architectural changes mentioned in idea, treat as lightweight.
|
|
124
|
-
|
|
125
|
-
**Applies in:** v3.7.x patch — workflows/exec-phase.md, workflows/plan-phase.md
|
|
126
|
-
|
|
127
|
-
## P-1402 — Per-phase researcher re-derives material already covered by project-level research
|
|
128
|
-
|
|
129
|
-
**Evidence:** panloop: phase 1 research and phase 2 research both touched ESM scaffolding territory already covered by project-level research/architecture.md, features.md, stack.md. Wasted tokens.
|
|
130
|
-
|
|
131
|
-
**Rule:** pan-phase-researcher agent prompt should require reading research/architecture.md, features.md, stack.md as context, AND emit only deltas/specifics not in project-level research. Audit agents/pan-phase-researcher.md.
|
|
132
|
-
|
|
133
|
-
**Applies in:** v3.7.x patch — agents/pan-phase-researcher.md prompt
|
|
134
|
-
|
|
135
|
-
## P-1404 — Auto-trace SubagentStop hook covers only some agents — pan-roadmapper logged but pan-planner/executor/verifier did not
|
|
136
|
-
|
|
137
|
-
**Evidence:** panloop run had ~25 agent invocations across the lifecycle (researcher×2, roadmapper, context, planner×2, executor×3, verifier×2, etc.). Only 14 trace events captured across 4 sub-sessions. Hook coverage gap means /pan:learn analysis is working from incomplete data.
|
|
138
|
-
|
|
139
|
-
**Rule:** Audit hooks/pan-trace-logger.js to verify SubagentStop fires for ALL Task-spawned agent types, not just a known list. Either: (a) regex-match agent names broadly, (b) document expected agents and warn if hook payloads come from unknown ones, (c) add a 'fallback' trace event when an agent commits but no trace was captured (would require git-hook integration).
|
|
140
|
-
|
|
141
|
-
**Applies in:** v3.7.x patch — hooks/pan-trace-logger.js audit
|
|
142
|
-
|
|
143
|
-
## P-1501 — claude -p autonomous session exits after Phase 0 setup; multi-step workflows don't drive headless mode forward without explicit tool calls
|
|
144
|
-
|
|
145
|
-
**Evidence:** panloop2 v3.7.3 validation run via patched runner.cjs: status=done, exit_code=0, elapsed=48s, BUT only config.json was written. No project.md, no roadmap, no research, no subagent spawns. The auto-mode workflow block applies defaults then says 'proceed' — model interprets that as completion and exits. Original panloop 29-min success was via MANUAL interactive claude -p, not via runner-spawned.
|
|
146
|
-
|
|
147
|
-
**Rule:** Workflow auto-mode blocks must END with an explicit tool call that drives the next step (e.g., Write call to create project.md, or Task call to spawn pan-discusser). 'Proceed' as text instruction is insufficient in headless mode — claude -p exits when the assistant's text response has no pending tool calls. Audit all --auto-flagged workflow paths for this gap. Possible v3.7.4 patch: auto-mode workflow steps explicitly chain via tool invocation, not prose continuation.
|
|
148
|
-
|
|
149
|
-
**Applies in:** v3.7.4+ patch — workflows/new-project.md auto-mode chain audit
|
|
150
|
-
|
|
151
|
-
## P-1502 — runner.cjs exit_code=0 is too coarse — should validate milestone-completion before declaring success
|
|
152
|
-
|
|
153
|
-
**Evidence:** panloop2: runner returned status=done, stop_reason=success, exit_code=0 even though only config.json was written and the workflow halted at Phase 0. Exit code only reflects 'claude -p exited cleanly' — not 'autonomous build completed'.
|
|
154
|
-
|
|
155
|
-
**Rule:** After spawnSync returns exit_code=0, runner.cjs runExperiment should also check whether <experiment>/.planning/state.md status field is 'completed' (or whether milestone summary exists). If the workflow never reached milestone-done, set stop_reason='incomplete' or 'partial' even with clean exit. Caller can then act differently (e.g., mark for re-run, alert).
|
|
156
|
-
|
|
157
|
-
**Applies in:** v3.7.4 — runner.cjs runExperiment success criteria audit
|
|
158
|
-
|
|
159
|
-
## P-1701 — Multi-phase (3+) autonomous workflows exit at phase boundaries with /clear-and-rerun instructions; loop is autonomous WITHIN a phase, not across phases
|
|
160
|
-
|
|
161
|
-
**Evidence:** panmd2 manual claude -p run on a 5-phase project: completed Phase 1 with 13 commits + 20/20 tests passing, then exited cleanly with final assistant message: 'Next Up: Phase 2: Rule Infrastructure — /pan:discuss-phase 2 --auto. /clear first → fresh context window'. Compare panloop (2 phases) which auto-chained both phases without exit. The auto-mode workflow has phase-handoff logic that emits a /clear instruction between phases for context-budget reasons.
|
|
162
|
-
|
|
163
|
-
**Rule:** Audit pan-wizard-core/workflows/new-project.md and exec-phase.md for phase-handoff logic. The 'between phases /clear' approach prevents true multi-phase autonomous runs. v3.7.4+ options: (a) detect 'this is the last phase' and skip /clear instruction, (b) provide a '--multi-phase' mode that chains all phases in one session (high token cost, large context), (c) have the runner DETECT 'next up' style exits and auto-spawn next phase via /pan:plan-phase --auto. (c) is most scalable.
|
|
164
|
-
|
|
165
|
-
**Applies in:** v3.7.4+ — workflows/new-project.md phase-handoff, runner.cjs continuation logic
|
|
166
|
-
|
|
167
|
-
## P-1501-r2 — P-1501 root cause refined: runner.cjs spawnSync({stdio:[ignore,pipe,pipe]}) lacks TTY; manual bash invocation has TTY; claude -p detects no-TTY and exits after first response loop
|
|
168
|
-
|
|
169
|
-
**Evidence:** Isolation tests: (1) Manual bash invocation 'claude -p --dangerously-skip-permissions <prompt>' (NO --output-format json, exact same flags as runner) → 13 commits, Phase 1 complete, exit 0. (2) Runner-spawned 'claude -p --dangerously-skip-permissions <prompt>' via spawnSync({stdio:[ignore,pipe,pipe], shell:'win32'}) → 0 commits, only config.json written, exit 0 in ~45s. The ONLY difference is the spawn environment. claude -p likely detects isatty(stdin)=false and exits after first complete response, treating the absence of TTY as 'scripted single-shot' instead of 'autonomous loop'.
|
|
170
|
-
|
|
171
|
-
**Rule:** Fix in runner.cjs: either (a) allocate a pseudo-tty using node-pty (requires runtime dep), (b) pipe a 'continue' prompt to keep claude alive across iterations, or (c) wrap claude -p in a script that allocates a TTY (e.g., via 'script -q' on Unix, ConPTY on Windows). Document the environment requirement in runner adapter comment.
|
|
172
|
-
|
|
173
|
-
**Applies in:** v3.7.4 — runner.cjs spawn environment fix
|
|
174
|
-
|
|
175
|
-
## P-1501-r3 — P-1501 stdio:'inherit' fix is INSUFFICIENT when the grandparent (script/CI/tool) has no TTY itself
|
|
176
|
-
|
|
177
|
-
**Evidence:** panmd3 v3.7.4 validation run via patched runner with stdio:[inherit, pipe, pipe]: still 48s, 0 commits, status=incomplete (P-1502 caught the regression honestly). Root cause: 'inherit' inherits from parent (node), which inherits from Bash tool wrapper, which has no TTY. Chain: no-TTY-grandparent → no-TTY-parent → claude sees no-TTY → exits early.
|
|
178
|
-
|
|
179
|
-
**Rule:** Real fix for P-1501 requires either: (a) explicit pty allocation via node-pty (would be PAN's first runtime dependency — meaningful trade-off), (b) wrap claude invocation in a TTY-allocating tool (Windows: winpty/ConPTY API, Unix: script -q). Document the current limitation: pan-tools experiment run autonomous claude path WORKS only when invoked from a real terminal (where the entire ancestry chain has a TTY). When invoked from Bash-tool/CI/script wrappers, the run will return status=incomplete (P-1502 reports honestly). For v3.7.4: ship with this limitation documented; v3.8 may bring node-pty integration.
|
|
180
|
-
|
|
181
|
-
**Applies in:** v3.8 — runner.cjs pty allocation; v3.7.4 — documentation in commands/pan/experiment.md
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* PAN-Z M2 — native MCP tools whose logic lives in-process (not a pan-tools spawn).
|
|
5
|
-
*
|
|
6
|
-
* These are the deterministic grafts the review demanded: the orchestrator's
|
|
7
|
-
* `next-action` state machine and the two-step merge gate. A native tool declares a
|
|
8
|
-
* `handler({ cwd, input, env, gitImpl }) -> { json | text, isError? }` instead of a
|
|
9
|
-
* `verb`; a thrown Error is surfaced as JSON-RPC -32602 (invalid params) by the server.
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
const mergeGate = require('./merge-gate.cjs');
|
|
13
|
-
const orchestrator = require('./orchestrator.cjs');
|
|
14
|
-
|
|
15
|
-
const NATIVE_TOOLS = [
|
|
16
|
-
{
|
|
17
|
-
name: 'pan_next_action',
|
|
18
|
-
title: 'Next deterministic action',
|
|
19
|
-
description: 'Given the current phase/run snapshot, return the next step the primary agent should take (plan/execute/verify/request_merge/await_approval/stop). Enforces the safety caps and the regression circuit-breaker.',
|
|
20
|
-
readOnly: true, destructive: false,
|
|
21
|
-
inputSchema: {
|
|
22
|
-
type: 'object', additionalProperties: false, required: ['state'],
|
|
23
|
-
properties: { state: { type: 'object' }, caps: { type: 'object' } },
|
|
24
|
-
},
|
|
25
|
-
handler: ({ input }) => {
|
|
26
|
-
if (!input.state || typeof input.state !== 'object') throw new Error('Invalid "state": an object snapshot is required');
|
|
27
|
-
return { json: orchestrator.nextAction(input.state, input.caps) };
|
|
28
|
-
},
|
|
29
|
-
},
|
|
30
|
-
{
|
|
31
|
-
name: 'pan_request_merge',
|
|
32
|
-
title: 'Request a gated merge',
|
|
33
|
-
description: 'Stage a squash-merge request for a branch and mark it awaiting human approval. Records intent only — does NOT merge.',
|
|
34
|
-
readOnly: false, destructive: false,
|
|
35
|
-
inputSchema: {
|
|
36
|
-
type: 'object', additionalProperties: false, required: ['branch'],
|
|
37
|
-
properties: { branch: { type: 'string' }, ci_green: { type: 'boolean' }, verify_pass: { type: 'boolean' } },
|
|
38
|
-
},
|
|
39
|
-
handler: ({ cwd, input }) => ({
|
|
40
|
-
json: mergeGate.requestMerge(cwd, { branch: input.branch, ci_green: input.ci_green, verify_pass: input.verify_pass }),
|
|
41
|
-
}),
|
|
42
|
-
},
|
|
43
|
-
{
|
|
44
|
-
name: 'pan_confirm_merge',
|
|
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\'s approval_token) is present. Any agent-supplied approval is ignored; never force-pushes or rewrites history.',
|
|
47
|
-
readOnly: false, destructive: true,
|
|
48
|
-
inputSchema: {
|
|
49
|
-
type: 'object', additionalProperties: false, required: ['branch'],
|
|
50
|
-
properties: { branch: { type: 'string' } },
|
|
51
|
-
},
|
|
52
|
-
handler: ({ cwd, input, env, gitImpl }) => {
|
|
53
|
-
const res = mergeGate.confirmMerge(cwd, { branch: input.branch }, env, gitImpl);
|
|
54
|
-
// A refused gate (missing approval / CI / verify) is a normal, non-error result the
|
|
55
|
-
// agent should read; only a real git failure is flagged isError.
|
|
56
|
-
const gitFailed = !res.merged && Array.isArray(res.reasons)
|
|
57
|
-
&& res.reasons.some((r) => r === 'git_merge_failed' || r === 'git_commit_failed');
|
|
58
|
-
return { json: res, isError: gitFailed };
|
|
59
|
-
},
|
|
60
|
-
},
|
|
61
|
-
];
|
|
62
|
-
|
|
63
|
-
module.exports = { NATIVE_TOOLS };
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* PAN-Z M2 — the deterministic orchestrator ("next-action" state machine).
|
|
5
|
-
*
|
|
6
|
-
* ZCode has no workflow engine and cannot machine-intercept a subagent spawn, so
|
|
7
|
-
* PAN's sequencing + safety harness (waves, regression circuit-breaker, spawn/budget
|
|
8
|
-
* caps, the human merge gate) cannot live in agent prose or a pre-spawn hook. The
|
|
9
|
-
* review's fix: relocate the state machine here and expose ONE `next-action` tool the
|
|
10
|
-
* primary Agent polls before each step. Enforcement then happens at the (gateable)
|
|
11
|
-
* MCP-tool-call boundary, not at the (un-gateable) spawn event.
|
|
12
|
-
*
|
|
13
|
-
* `nextAction` is a PURE function of a snapshot the caller assembles from PAN's own
|
|
14
|
-
* state (via the pan-mcp resources) — so it is fully unit-testable and its decisions
|
|
15
|
-
* are reproducible.
|
|
16
|
-
*/
|
|
17
|
-
|
|
18
|
-
// Budget is advisory by default (enforceBudget:false) — it never stops the loop
|
|
19
|
-
// unless the caller opts in. maxCycles remains a hard safety stop.
|
|
20
|
-
const DEFAULT_CAPS = { maxCycles: 25, budget: Infinity, enforceBudget: false };
|
|
21
|
-
const PHASE_NEXT = {
|
|
22
|
-
none: 'plan',
|
|
23
|
-
researched: 'plan',
|
|
24
|
-
planned: 'execute',
|
|
25
|
-
executed: 'verify',
|
|
26
|
-
verified: 'request_merge',
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Decide the next deterministic action.
|
|
31
|
-
* @param {Object} state snapshot:
|
|
32
|
-
* { phases:[{number,status}], cycles?, points_used?, tests_before?, tests_after?,
|
|
33
|
-
* awaiting_approval?:boolean, aborted?:boolean }
|
|
34
|
-
* @param {Object} [caps] { maxCycles, budget }
|
|
35
|
-
* @returns {{action:string, args?:Object, reason:string, done:boolean}}
|
|
36
|
-
* action ∈ plan | execute | verify | request_merge | await_approval | stop
|
|
37
|
-
*/
|
|
38
|
-
function nextAction(state, caps) {
|
|
39
|
-
const c = Object.assign({}, DEFAULT_CAPS, caps || {});
|
|
40
|
-
state = state || {};
|
|
41
|
-
|
|
42
|
-
// Hard stops first — safety caps and the circuit-breaker outrank all progress.
|
|
43
|
-
if (state.aborted) return { action: 'stop', reason: 'aborted', done: true };
|
|
44
|
-
if (
|
|
45
|
-
typeof state.tests_before === 'number' &&
|
|
46
|
-
typeof state.tests_after === 'number' &&
|
|
47
|
-
state.tests_after < state.tests_before
|
|
48
|
-
) {
|
|
49
|
-
return { action: 'stop', reason: 'regression', done: true };
|
|
50
|
-
}
|
|
51
|
-
if ((state.cycles || 0) >= c.maxCycles) return { action: 'stop', reason: 'max_cycles', done: true };
|
|
52
|
-
if (c.enforceBudget && (state.points_used || 0) >= c.budget) return { action: 'stop', reason: 'budget_cap', done: true };
|
|
53
|
-
|
|
54
|
-
// The human merge gate is a barrier: while a merge awaits approval, do nothing else.
|
|
55
|
-
if (state.awaiting_approval) return { action: 'await_approval', reason: 'human_gate', done: false };
|
|
56
|
-
|
|
57
|
-
// Advance the first phase that isn't complete.
|
|
58
|
-
const phases = Array.isArray(state.phases) ? state.phases : [];
|
|
59
|
-
const phase = phases.find((p) => p && p.status !== 'complete');
|
|
60
|
-
if (!phase) return { action: 'stop', reason: 'all_complete', done: true };
|
|
61
|
-
|
|
62
|
-
const action = PHASE_NEXT[phase.status] || 'plan';
|
|
63
|
-
return { action, args: { phase: phase.number }, reason: `phase_${phase.status}`, done: false };
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
module.exports = { nextAction, DEFAULT_CAPS, PHASE_NEXT };
|
|
File without changes
|