pan-wizard 2.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.
Files changed (164) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +772 -0
  3. package/agents/pan-debugger.md +1246 -0
  4. package/agents/pan-document_code.md +965 -0
  5. package/agents/pan-executor.md +469 -0
  6. package/agents/pan-integration-checker.md +443 -0
  7. package/agents/pan-phase-researcher.md +572 -0
  8. package/agents/pan-plan-checker.md +763 -0
  9. package/agents/pan-planner.md +1297 -0
  10. package/agents/pan-project-researcher.md +647 -0
  11. package/agents/pan-research-synthesizer.md +239 -0
  12. package/agents/pan-reviewer.md +112 -0
  13. package/agents/pan-roadmapper.md +642 -0
  14. package/agents/pan-verifier.md +672 -0
  15. package/assets/pan-logo-2000-transparent.svg +30 -0
  16. package/assets/pan-logo-2000.svg +43 -0
  17. package/assets/terminal.svg +119 -0
  18. package/bin/install-lib.cjs +616 -0
  19. package/bin/install.js +1936 -0
  20. package/commands/pan/add-phase.md +44 -0
  21. package/commands/pan/assumptions.md +47 -0
  22. package/commands/pan/audit-deployment.md +378 -0
  23. package/commands/pan/debug.md +168 -0
  24. package/commands/pan/discord.md +19 -0
  25. package/commands/pan/discuss-phase.md +84 -0
  26. package/commands/pan/exec-phase.md +45 -0
  27. package/commands/pan/focus-auto.md +323 -0
  28. package/commands/pan/focus-design.md +816 -0
  29. package/commands/pan/focus-exec.md +316 -0
  30. package/commands/pan/focus-plan.md +101 -0
  31. package/commands/pan/focus-scan.md +272 -0
  32. package/commands/pan/focus-sync.md +104 -0
  33. package/commands/pan/health.md +23 -0
  34. package/commands/pan/help.md +23 -0
  35. package/commands/pan/insert-phase.md +33 -0
  36. package/commands/pan/map-codebase.md +72 -0
  37. package/commands/pan/milestone-audit.md +37 -0
  38. package/commands/pan/milestone-cleanup.md +19 -0
  39. package/commands/pan/milestone-done.md +137 -0
  40. package/commands/pan/milestone-gaps.md +35 -0
  41. package/commands/pan/milestone-new.md +45 -0
  42. package/commands/pan/new-project.md +43 -0
  43. package/commands/pan/patches.md +110 -0
  44. package/commands/pan/pause.md +39 -0
  45. package/commands/pan/phase-budget.md +23 -0
  46. package/commands/pan/phase-tests.md +42 -0
  47. package/commands/pan/plan-phase.md +46 -0
  48. package/commands/pan/profile.md +36 -0
  49. package/commands/pan/progress.md +25 -0
  50. package/commands/pan/quick.md +42 -0
  51. package/commands/pan/remove-phase.md +32 -0
  52. package/commands/pan/research-phase.md +190 -0
  53. package/commands/pan/resume.md +41 -0
  54. package/commands/pan/retro.md +33 -0
  55. package/commands/pan/settings.md +37 -0
  56. package/commands/pan/todo-add.md +48 -0
  57. package/commands/pan/todo-check.md +46 -0
  58. package/commands/pan/update.md +38 -0
  59. package/commands/pan/verify-phase.md +39 -0
  60. package/hooks/dist/pan-check-update.js +62 -0
  61. package/hooks/dist/pan-context-monitor.js +122 -0
  62. package/hooks/dist/pan-statusline.js +108 -0
  63. package/package.json +66 -0
  64. package/pan-wizard-core/bin/lib/codebase.cjs +746 -0
  65. package/pan-wizard-core/bin/lib/commands.cjs +1435 -0
  66. package/pan-wizard-core/bin/lib/config.cjs +611 -0
  67. package/pan-wizard-core/bin/lib/constants.cjs +696 -0
  68. package/pan-wizard-core/bin/lib/context-budget.cjs +150 -0
  69. package/pan-wizard-core/bin/lib/core.cjs +650 -0
  70. package/pan-wizard-core/bin/lib/focus.cjs +900 -0
  71. package/pan-wizard-core/bin/lib/frontmatter.cjs +442 -0
  72. package/pan-wizard-core/bin/lib/init.cjs +881 -0
  73. package/pan-wizard-core/bin/lib/milestone.cjs +276 -0
  74. package/pan-wizard-core/bin/lib/phase.cjs +1212 -0
  75. package/pan-wizard-core/bin/lib/roadmap.cjs +470 -0
  76. package/pan-wizard-core/bin/lib/state.cjs +1029 -0
  77. package/pan-wizard-core/bin/lib/template.cjs +314 -0
  78. package/pan-wizard-core/bin/lib/utils.cjs +171 -0
  79. package/pan-wizard-core/bin/lib/verify.cjs +1808 -0
  80. package/pan-wizard-core/bin/pan-tools.cjs +773 -0
  81. package/pan-wizard-core/references/checkpoints.md +776 -0
  82. package/pan-wizard-core/references/continuation-format.md +249 -0
  83. package/pan-wizard-core/references/decimal-phase-calculation.md +65 -0
  84. package/pan-wizard-core/references/git-integration.md +248 -0
  85. package/pan-wizard-core/references/git-planning-commit.md +38 -0
  86. package/pan-wizard-core/references/model-profile-resolution.md +34 -0
  87. package/pan-wizard-core/references/model-profiles.md +111 -0
  88. package/pan-wizard-core/references/phase-argument-parsing.md +61 -0
  89. package/pan-wizard-core/references/planning-config.md +196 -0
  90. package/pan-wizard-core/references/questioning.md +145 -0
  91. package/pan-wizard-core/references/tdd.md +263 -0
  92. package/pan-wizard-core/references/ui-brand.md +160 -0
  93. package/pan-wizard-core/references/verification-patterns.md +612 -0
  94. package/pan-wizard-core/templates/codebase/architecture.md +283 -0
  95. package/pan-wizard-core/templates/codebase/best-practices.md +133 -0
  96. package/pan-wizard-core/templates/codebase/concerns.md +325 -0
  97. package/pan-wizard-core/templates/codebase/conventions.md +307 -0
  98. package/pan-wizard-core/templates/codebase/integrations.md +305 -0
  99. package/pan-wizard-core/templates/codebase/relationships.md +124 -0
  100. package/pan-wizard-core/templates/codebase/stack.md +199 -0
  101. package/pan-wizard-core/templates/codebase/structure.md +298 -0
  102. package/pan-wizard-core/templates/codebase/testing.md +480 -0
  103. package/pan-wizard-core/templates/config.json +37 -0
  104. package/pan-wizard-core/templates/context.md +283 -0
  105. package/pan-wizard-core/templates/continue-here.md +78 -0
  106. package/pan-wizard-core/templates/debug-subagent-prompt.md +91 -0
  107. package/pan-wizard-core/templates/debug.md +164 -0
  108. package/pan-wizard-core/templates/discovery.md +146 -0
  109. package/pan-wizard-core/templates/milestone-archive.md +123 -0
  110. package/pan-wizard-core/templates/milestone.md +115 -0
  111. package/pan-wizard-core/templates/phase-prompt.md +593 -0
  112. package/pan-wizard-core/templates/planner-subagent-prompt.md +117 -0
  113. package/pan-wizard-core/templates/project.md +184 -0
  114. package/pan-wizard-core/templates/requirements.md +231 -0
  115. package/pan-wizard-core/templates/research-project/architecture.md +204 -0
  116. package/pan-wizard-core/templates/research-project/features.md +147 -0
  117. package/pan-wizard-core/templates/research-project/pitfalls.md +200 -0
  118. package/pan-wizard-core/templates/research-project/stack.md +120 -0
  119. package/pan-wizard-core/templates/research-project/summary.md +170 -0
  120. package/pan-wizard-core/templates/research.md +552 -0
  121. package/pan-wizard-core/templates/retrospective.md +54 -0
  122. package/pan-wizard-core/templates/roadmap.md +202 -0
  123. package/pan-wizard-core/templates/standards.md +24 -0
  124. package/pan-wizard-core/templates/state.md +176 -0
  125. package/pan-wizard-core/templates/summary-complex.md +59 -0
  126. package/pan-wizard-core/templates/summary-minimal.md +41 -0
  127. package/pan-wizard-core/templates/summary-standard.md +49 -0
  128. package/pan-wizard-core/templates/summary.md +249 -0
  129. package/pan-wizard-core/templates/uat.md +247 -0
  130. package/pan-wizard-core/templates/user-setup.md +311 -0
  131. package/pan-wizard-core/templates/validation.md +76 -0
  132. package/pan-wizard-core/templates/verification-report.md +322 -0
  133. package/pan-wizard-core/workflows/add-phase.md +111 -0
  134. package/pan-wizard-core/workflows/assumptions.md +178 -0
  135. package/pan-wizard-core/workflows/diagnose-issues.md +219 -0
  136. package/pan-wizard-core/workflows/discuss-phase.md +542 -0
  137. package/pan-wizard-core/workflows/exec-phase.md +572 -0
  138. package/pan-wizard-core/workflows/execute-plan.md +448 -0
  139. package/pan-wizard-core/workflows/health.md +156 -0
  140. package/pan-wizard-core/workflows/help.md +431 -0
  141. package/pan-wizard-core/workflows/insert-phase.md +129 -0
  142. package/pan-wizard-core/workflows/map-codebase.md +401 -0
  143. package/pan-wizard-core/workflows/milestone-audit.md +297 -0
  144. package/pan-wizard-core/workflows/milestone-cleanup.md +152 -0
  145. package/pan-wizard-core/workflows/milestone-gaps.md +274 -0
  146. package/pan-wizard-core/workflows/milestone-new.md +382 -0
  147. package/pan-wizard-core/workflows/new-project.md +1178 -0
  148. package/pan-wizard-core/workflows/pause.md +122 -0
  149. package/pan-wizard-core/workflows/phase-tests.md +388 -0
  150. package/pan-wizard-core/workflows/plan-phase.md +569 -0
  151. package/pan-wizard-core/workflows/profile.md +115 -0
  152. package/pan-wizard-core/workflows/progress.md +381 -0
  153. package/pan-wizard-core/workflows/quick.md +453 -0
  154. package/pan-wizard-core/workflows/remove-phase.md +154 -0
  155. package/pan-wizard-core/workflows/research-phase.md +73 -0
  156. package/pan-wizard-core/workflows/resume-project.md +306 -0
  157. package/pan-wizard-core/workflows/retro.md +121 -0
  158. package/pan-wizard-core/workflows/settings.md +213 -0
  159. package/pan-wizard-core/workflows/todo-add.md +157 -0
  160. package/pan-wizard-core/workflows/todo-check.md +176 -0
  161. package/pan-wizard-core/workflows/transition.md +544 -0
  162. package/pan-wizard-core/workflows/update.md +219 -0
  163. package/pan-wizard-core/workflows/verify-phase.md +301 -0
  164. package/scripts/build-hooks.js +43 -0
@@ -0,0 +1,773 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * PAN Tools — CLI utility for PAN workflow operations
5
+ *
6
+ * Replaces repetitive inline bash patterns across ~50 PAN command/workflow/agent files.
7
+ * Centralizes: config parsing, model resolution, phase lookup, git commits, summary verification.
8
+ *
9
+ * Usage: node pan-tools.cjs <command> [args] [--raw] [--verbose]
10
+ *
11
+ * Atomic Commands:
12
+ * state load Load project config + state
13
+ * state json Output state.md frontmatter as JSON
14
+ * state update <field> <value> Update a state.md field
15
+ * state get [section] Get state.md content or section
16
+ * state patch --field val ... Batch update state.md fields
17
+ * resolve-model <agent-type> Get model for agent based on profile
18
+ * find-phase <phase> Find phase directory by number
19
+ * commit <message> [--files f1 f2] Commit planning docs
20
+ * verify-summary <path> Verify a summary.md file
21
+ * generate-slug <text> Convert text to URL-safe slug
22
+ * current-timestamp [format] Get timestamp (full|date|filename)
23
+ * list-todos [area] Count and enumerate pending todos
24
+ * verify-path-exists <path> Check file/directory existence
25
+ * config-ensure-section Initialize .planning/config.json
26
+ * config-set <key> <value> Set a config.json key
27
+ * config-get <key> Get a config.json value
28
+ * history-digest Aggregate all summary.md data
29
+ * summary-extract <path> [--fields] Extract structured data from summary.md
30
+ * state-snapshot Structured parse of state.md
31
+ * phase-plan-index <phase> Index plans with waves and status
32
+ * websearch <query> Search web via Brave API (if configured)
33
+ * [--limit N] [--freshness day|week|month]
34
+ *
35
+ * Phase Listing:
36
+ * phases list [--type plan|summary] List phases with optional type filter
37
+ * [--phase N] [--include-archived]
38
+ *
39
+ * Phase Operations:
40
+ * phase next-decimal <phase> Calculate next decimal phase number
41
+ * phase add <description> Append new phase to roadmap + create dir
42
+ * phase insert <after> <description> Insert decimal phase after existing
43
+ * phase remove <phase> [--force] Remove phase, renumber all subsequent
44
+ * phase complete <phase> Mark phase done, update state + roadmap
45
+ *
46
+ * Roadmap Operations:
47
+ * roadmap get-phase <phase> Extract phase section from roadmap.md
48
+ * roadmap analyze Full roadmap parse with disk status
49
+ * roadmap update-plan-progress <N> Update progress table row from disk (PLAN vs SUMMARY counts)
50
+ *
51
+ * Requirements Operations:
52
+ * requirements mark-complete <ids> Mark requirement IDs as complete in requirements.md
53
+ * Accepts: REQ-01,REQ-02 or REQ-01 REQ-02 or [REQ-01, REQ-02]
54
+ *
55
+ * Milestone Operations:
56
+ * milestone complete <version> Archive milestone, create milestones.md
57
+ * [--name <name>]
58
+ * [--archive-phases] Move phase dirs to milestones/vX.Y-phases/
59
+ *
60
+ * Validation:
61
+ * validate consistency Check phase numbering, disk/roadmap sync
62
+ * validate health [--repair] [--full] Check .planning/ integrity, optionally repair or run tests+build
63
+ *
64
+ * Progress:
65
+ * progress [json|table|bar|health] Render progress in various formats
66
+ * context-budget Estimate context utilization for current phase
67
+ *
68
+ * Todos:
69
+ * todo complete <filename> Move todo from pending to completed
70
+ *
71
+ * Scaffolding:
72
+ * scaffold context --phase <N> Create context.md template
73
+ * scaffold uat --phase <N> Create uat.md template
74
+ * scaffold verification --phase <N> Create verification.md template
75
+ * scaffold phase-dir --phase <N> Create phase directory
76
+ * --name <name>
77
+ *
78
+ * Frontmatter CRUD:
79
+ * frontmatter get <file> [--field k] Extract frontmatter as JSON
80
+ * frontmatter set <file> --field k Update single frontmatter field
81
+ * --value jsonVal
82
+ * frontmatter merge <file> Merge JSON into frontmatter
83
+ * --data '{json}'
84
+ * frontmatter validate <file> Validate required fields
85
+ * --schema plan|summary|verification
86
+ *
87
+ * Verification Suite:
88
+ * verify plan-structure <file> Check plan.md structure + tasks
89
+ * verify phase-completeness <phase> Check all plans have summaries
90
+ * verify references <file> Check @-refs + paths resolve
91
+ * verify commits <h1> [h2] ... Batch verify commit hashes
92
+ * verify artifacts <plan-file> Check must_haves.artifacts
93
+ * verify key-links <plan-file> Check must_haves.key_links
94
+ *
95
+ * Template Fill:
96
+ * template fill summary --phase N Create pre-filled summary.md
97
+ * [--plan M] [--name "..."]
98
+ * [--fields '{json}']
99
+ * template fill plan --phase N Create pre-filled plan.md
100
+ * [--plan M] [--type execute|tdd]
101
+ * [--wave N] [--fields '{json}']
102
+ * template fill verification Create pre-filled verification.md
103
+ * --phase N [--fields '{json}']
104
+ *
105
+ * State Progression:
106
+ * state advance-plan Increment plan counter
107
+ * state record-metric --phase N Record execution metrics
108
+ * --plan M --duration Xmin
109
+ * [--tasks N] [--files N]
110
+ * state update-progress Recalculate progress bar
111
+ * state add-decision --summary "..." Add decision to state.md
112
+ * [--phase N] [--rationale "..."]
113
+ * [--summary-file path] [--rationale-file path]
114
+ * state add-blocker --text "..." Add blocker
115
+ * [--text-file path]
116
+ * state resolve-blocker --text "..." Remove blocker
117
+ * state record-session Update session continuity
118
+ * --stopped-at "..."
119
+ * [--resume-file path]
120
+ *
121
+ * Compound Commands (workflow-specific initialization):
122
+ * init execute-phase <phase> All context for execute-phase workflow
123
+ * init plan-phase <phase> All context for plan-phase workflow
124
+ * init new-project All context for new-project workflow
125
+ * init new-milestone All context for new-milestone workflow
126
+ * init quick <description> All context for quick workflow
127
+ * init resume All context for resume-project workflow
128
+ * init verify-work <phase> All context for verify-work workflow
129
+ * init phase-op <phase> Generic phase operation context
130
+ * init todos [area] All context for todo workflows
131
+ * init milestone-op All context for milestone operations
132
+ * init map-codebase All context for map-codebase workflow
133
+ * init progress All context for progress workflow
134
+ *
135
+ * Focus (Strategic Project Management):
136
+ * focus scan [--lean] Collect, classify, and prioritize work items
137
+ * focus plan [--budget N] Create capacity-budgeted execution batch
138
+ * [--mode bugfix|balanced|features|full]
139
+ * [--priority P0-P6] [--lean]
140
+ * focus sync [--check-only] Check documentation staleness
141
+ * focus exec [--dry-run] Load and classify batch for execution
142
+ * focus auto [--category CAT] Auto-runner: init, status, update, stop
143
+ * [--mode MODE] [--budget N] [--max-cycles N] [--total-budget N]
144
+ * [--status] [--stop] [--update] [--continue] [--dry-run]
145
+ * focus design Route to 10-phase investigation workflow
146
+ *
147
+ * Pre-Flight & Dashboard:
148
+ * preflight [phase|batch] Validate execution prerequisites
149
+ * dashboard Aggregated project status overview
150
+ *
151
+ * Session Learnings:
152
+ * learnings extract Extract patterns from session data
153
+ * learnings list List accumulated learnings
154
+ * learnings prune [--days N] [--id] Remove stale learnings
155
+ *
156
+ * Dependency Validation:
157
+ * deps validate Cross-reference roadmap vs reality
158
+ *
159
+ * Standards (Industry Standards Integration):
160
+ * standards list [--category <cat>] List available standards catalog
161
+ * standards select <id> Add a standard to the project
162
+ * standards remove <id> Remove a standard from the project
163
+ * standards status Report compliance status
164
+ * standards recommend Recommend standards based on project.md
165
+ * standards phase-track <phase> Show standards relevant to a phase
166
+ * standards tools [id] List external scanning tools for standards
167
+ */
168
+
169
+ const fs = require('fs');
170
+ const path = require('path');
171
+ const { error, output } = require('./lib/core.cjs');
172
+ const state = require('./lib/state.cjs');
173
+ const phase = require('./lib/phase.cjs');
174
+ const roadmap = require('./lib/roadmap.cjs');
175
+ const verify = require('./lib/verify.cjs');
176
+ const config = require('./lib/config.cjs');
177
+ const template = require('./lib/template.cjs');
178
+ const milestone = require('./lib/milestone.cjs');
179
+ const commands = require('./lib/commands.cjs');
180
+ const init = require('./lib/init.cjs');
181
+ const frontmatter = require('./lib/frontmatter.cjs');
182
+ const contextBudget = require('./lib/context-budget.cjs');
183
+ const focus = require('./lib/focus.cjs');
184
+ const codebase = require('./lib/codebase.cjs');
185
+
186
+ /**
187
+ * Get the value following a flag in the args array.
188
+ * @param {string[]} args - CLI arguments
189
+ * @param {string} flag - Flag name (e.g., '--phase')
190
+ * @param {*} [defaultVal=null] - Default if flag missing or no value follows
191
+ * @returns {string|null} The value after the flag, or defaultVal
192
+ */
193
+ function getArgValue(args, flag, defaultVal = null) {
194
+ const idx = args.indexOf(flag);
195
+ if (idx === -1 || idx + 1 >= args.length) return defaultVal;
196
+ return args[idx + 1];
197
+ }
198
+
199
+ /**
200
+ * Parse JSON string or call error() with a descriptive message.
201
+ * @param {string} raw - Raw JSON string
202
+ * @param {string} flagName - Flag name for error reporting
203
+ * @returns {*} Parsed JSON value
204
+ */
205
+ function parseJsonOrError(raw, flagName) {
206
+ try { return JSON.parse(raw); } catch (e) { error(`Invalid JSON for ${flagName}: ${e.message}`); }
207
+ }
208
+
209
+ // ─── CLI Router ───────────────────────────────────────────────────────────────
210
+
211
+ async function main() {
212
+ const args = process.argv.slice(2);
213
+
214
+ // Optional cwd override for sandboxed subagents running outside project root.
215
+ let cwd = process.cwd();
216
+ const cwdEqArg = args.find(arg => arg.startsWith('--cwd='));
217
+ const cwdIdx = args.indexOf('--cwd');
218
+ if (cwdEqArg) {
219
+ const value = cwdEqArg.slice('--cwd='.length).trim();
220
+ if (!value) error('Missing value for --cwd');
221
+ args.splice(args.indexOf(cwdEqArg), 1);
222
+ cwd = path.resolve(value);
223
+ } else if (cwdIdx !== -1) {
224
+ const value = args[cwdIdx + 1];
225
+ if (!value || value.startsWith('--')) error('Missing value for --cwd');
226
+ args.splice(cwdIdx, 2);
227
+ cwd = path.resolve(value);
228
+ }
229
+
230
+ try {
231
+ if (!fs.statSync(cwd).isDirectory()) error(`Invalid --cwd: ${cwd} is not a directory`);
232
+ } catch {
233
+ error(`Invalid --cwd: ${cwd}`);
234
+ }
235
+
236
+ const rawIndex = args.indexOf('--raw');
237
+ const raw = rawIndex !== -1;
238
+ if (rawIndex !== -1) args.splice(rawIndex, 1);
239
+
240
+ const verboseIndex = args.indexOf('--verbose');
241
+ if (verboseIndex !== -1) {
242
+ args.splice(verboseIndex, 1);
243
+ process.env.PAN_VERBOSE = '1';
244
+ }
245
+
246
+ const command = args[0];
247
+
248
+ if (!command) {
249
+ error('Usage: pan-tools <command> [args] [--raw] [--cwd <path>]\nCommands: state, state-snapshot, resolve-model, find-phase, commit, verify-summary, verify, frontmatter, template, generate-slug, current-timestamp, list-todos, verify-path-exists, config-ensure-section, config-set, config-get, history-digest, phases, roadmap, requirements, phase, milestone, validate, progress, context-budget, todo, scaffold, init, phase-plan-index, summary-extract, rollback-snapshot, websearch, focus, preflight, dashboard, learnings, deps, standards');
250
+ }
251
+
252
+ switch (command) {
253
+ case 'state': {
254
+ const subcommand = args[1];
255
+ if (subcommand === 'json') {
256
+ state.cmdStateJson(cwd, raw);
257
+ } else if (subcommand === 'update') {
258
+ state.cmdStateUpdate(cwd, args[2], args[3]);
259
+ } else if (subcommand === 'get') {
260
+ state.cmdStateGet(cwd, args[2], raw);
261
+ } else if (subcommand === 'patch') {
262
+ const patches = {};
263
+ for (let i = 2; i < args.length; i += 2) {
264
+ const key = args[i].replace(/^--/, '');
265
+ const value = args[i + 1];
266
+ if (key && value !== undefined) {
267
+ patches[key] = value;
268
+ }
269
+ }
270
+ state.cmdStatePatch(cwd, patches, raw);
271
+ } else if (subcommand === 'advance-plan') {
272
+ state.cmdStateAdvancePlan(cwd, raw);
273
+ } else if (subcommand === 'record-metric') {
274
+ state.cmdStateRecordMetric(cwd, {
275
+ phase: getArgValue(args, '--phase'),
276
+ plan: getArgValue(args, '--plan'),
277
+ duration: getArgValue(args, '--duration'),
278
+ tasks: getArgValue(args, '--tasks'),
279
+ files: getArgValue(args, '--files'),
280
+ }, raw);
281
+ } else if (subcommand === 'update-progress') {
282
+ state.cmdStateUpdateProgress(cwd, raw);
283
+ } else if (subcommand === 'add-decision') {
284
+ state.cmdStateAddDecision(cwd, {
285
+ phase: getArgValue(args, '--phase'),
286
+ summary: getArgValue(args, '--summary'),
287
+ summary_file: getArgValue(args, '--summary-file'),
288
+ rationale: getArgValue(args, '--rationale', ''),
289
+ rationale_file: getArgValue(args, '--rationale-file'),
290
+ }, raw);
291
+ } else if (subcommand === 'add-blocker') {
292
+ state.cmdStateAddBlocker(cwd, {
293
+ text: getArgValue(args, '--text'),
294
+ text_file: getArgValue(args, '--text-file'),
295
+ }, raw);
296
+ } else if (subcommand === 'resolve-blocker') {
297
+ state.cmdStateResolveBlocker(cwd, getArgValue(args, '--text'), raw);
298
+ } else if (subcommand === 'record-session') {
299
+ state.cmdStateRecordSession(cwd, {
300
+ stopped_at: getArgValue(args, '--stopped-at'),
301
+ resume_file: getArgValue(args, '--resume-file', 'None'),
302
+ }, raw);
303
+ } else if (subcommand === 'load' || !subcommand) {
304
+ state.cmdStateLoad(cwd, raw);
305
+ } else {
306
+ error(`Unknown state subcommand: ${subcommand}. Available: json, update, get, patch, advance-plan, record-metric, update-progress, add-decision, add-blocker, resolve-blocker, record-session, load`);
307
+ }
308
+ break;
309
+ }
310
+
311
+ case 'resolve-model': {
312
+ commands.cmdResolveModel(cwd, args[1], raw);
313
+ break;
314
+ }
315
+
316
+ case 'find-phase': {
317
+ if (!args[1]) error('find-phase requires a phase number');
318
+ phase.cmdFindPhase(cwd, args[1], raw);
319
+ break;
320
+ }
321
+
322
+ case 'commit': {
323
+ const amend = args.includes('--amend');
324
+ const force = args.includes('--force');
325
+ const message = args[1] && !args[1].startsWith('--') ? args[1] : null;
326
+ // Parse --files flag (collect args after --files, stopping at other flags)
327
+ const filesIndex = args.indexOf('--files');
328
+ const files = filesIndex !== -1 ? args.slice(filesIndex + 1).filter(a => !a.startsWith('--')) : [];
329
+ const commitType = getArgValue(args, '--type');
330
+ commands.cmdCommit(cwd, message, files, raw, amend, { type: commitType, force });
331
+ break;
332
+ }
333
+
334
+ case 'verify-summary': {
335
+ const summaryPath = args[1];
336
+ const checkCount = Math.max(1, Math.min(parseInt(getArgValue(args, '--check-count', '2'), 10) || 2, 20));
337
+ verify.cmdVerifySummary(cwd, summaryPath, checkCount, raw);
338
+ break;
339
+ }
340
+
341
+ case 'template': {
342
+ const subcommand = args[1];
343
+ if (subcommand === 'select') {
344
+ template.cmdTemplateSelect(cwd, args[2], raw);
345
+ } else if (subcommand === 'fill') {
346
+ const templateType = args[2];
347
+ const fieldsRaw = getArgValue(args, '--fields');
348
+ template.cmdTemplateFill(cwd, templateType, {
349
+ phase: getArgValue(args, '--phase'),
350
+ plan: getArgValue(args, '--plan'),
351
+ name: getArgValue(args, '--name'),
352
+ type: getArgValue(args, '--type', 'execute'),
353
+ wave: getArgValue(args, '--wave', '1'),
354
+ fields: fieldsRaw ? parseJsonOrError(fieldsRaw, '--fields') : {},
355
+ }, raw);
356
+ } else {
357
+ error('Unknown template subcommand. Available: select, fill');
358
+ }
359
+ break;
360
+ }
361
+
362
+ case 'frontmatter': {
363
+ const subcommand = args[1];
364
+ const file = args[2];
365
+ if (subcommand === 'get') {
366
+ frontmatter.cmdFrontmatterGet(cwd, file, getArgValue(args, '--field'), raw);
367
+ } else if (subcommand === 'set') {
368
+ frontmatter.cmdFrontmatterSet(cwd, file, getArgValue(args, '--field'), getArgValue(args, '--value') ?? undefined, raw);
369
+ } else if (subcommand === 'merge') {
370
+ frontmatter.cmdFrontmatterMerge(cwd, file, getArgValue(args, '--data'), raw);
371
+ } else if (subcommand === 'validate') {
372
+ frontmatter.cmdFrontmatterValidate(cwd, file, getArgValue(args, '--schema'), raw);
373
+ } else {
374
+ error('Unknown frontmatter subcommand. Available: get, set, merge, validate');
375
+ }
376
+ break;
377
+ }
378
+
379
+ case 'verify': {
380
+ const subcommand = args[1];
381
+ if (subcommand === 'plan-structure') {
382
+ verify.cmdVerifyPlanStructure(cwd, args[2], raw);
383
+ } else if (subcommand === 'phase-completeness') {
384
+ verify.cmdVerifyPhaseCompleteness(cwd, args[2], raw);
385
+ } else if (subcommand === 'references') {
386
+ verify.cmdVerifyReferences(cwd, args[2], raw);
387
+ } else if (subcommand === 'commits') {
388
+ verify.cmdVerifyCommits(cwd, args.slice(2), raw);
389
+ } else if (subcommand === 'artifacts') {
390
+ verify.cmdVerifyArtifacts(cwd, args[2], raw);
391
+ } else if (subcommand === 'key-links') {
392
+ verify.cmdVerifyKeyLinks(cwd, args[2], raw);
393
+ } else {
394
+ error('Unknown verify subcommand. Available: plan-structure, phase-completeness, references, commits, artifacts, key-links');
395
+ }
396
+ break;
397
+ }
398
+
399
+ case 'generate-slug': {
400
+ commands.cmdGenerateSlug(args[1], raw);
401
+ break;
402
+ }
403
+
404
+ case 'current-timestamp': {
405
+ commands.cmdCurrentTimestamp(args[1] || 'full', raw);
406
+ break;
407
+ }
408
+
409
+ case 'list-todos': {
410
+ commands.cmdListTodos(cwd, args[1], raw);
411
+ break;
412
+ }
413
+
414
+ case 'verify-path-exists': {
415
+ commands.cmdVerifyPathExists(cwd, args[1], raw);
416
+ break;
417
+ }
418
+
419
+ case 'config-ensure-section': {
420
+ config.cmdConfigEnsureSection(cwd, raw);
421
+ break;
422
+ }
423
+
424
+ case 'config-set': {
425
+ config.cmdConfigSet(cwd, args[1], args[2], raw);
426
+ break;
427
+ }
428
+
429
+ case 'config-get': {
430
+ config.cmdConfigGet(cwd, args[1], raw);
431
+ break;
432
+ }
433
+
434
+ case 'history-digest': {
435
+ commands.cmdHistoryDigest(cwd, raw);
436
+ break;
437
+ }
438
+
439
+ case 'phases': {
440
+ const subcommand = args[1];
441
+ if (subcommand === 'list') {
442
+ const options = {
443
+ type: getArgValue(args, '--type'),
444
+ phase: getArgValue(args, '--phase'),
445
+ includeArchived: args.includes('--include-archived'),
446
+ };
447
+ phase.cmdPhasesList(cwd, options, raw);
448
+ } else {
449
+ error('Unknown phases subcommand. Available: list');
450
+ }
451
+ break;
452
+ }
453
+
454
+ case 'roadmap': {
455
+ const subcommand = args[1];
456
+ if (subcommand === 'get-phase') {
457
+ if (!args[2]) error('roadmap get-phase requires a phase number');
458
+ roadmap.cmdRoadmapGetPhase(cwd, args[2], raw);
459
+ } else if (subcommand === 'analyze') {
460
+ roadmap.cmdRoadmapAnalyze(cwd, raw);
461
+ } else if (subcommand === 'update-plan-progress') {
462
+ if (!args[2]) error('roadmap update-plan-progress requires a phase number');
463
+ roadmap.cmdRoadmapUpdatePlanProgress(cwd, args[2], raw);
464
+ } else {
465
+ error('Unknown roadmap subcommand. Available: get-phase, analyze, update-plan-progress');
466
+ }
467
+ break;
468
+ }
469
+
470
+ case 'requirements': {
471
+ const subcommand = args[1];
472
+ if (subcommand === 'mark-complete') {
473
+ milestone.cmdRequirementsMarkComplete(cwd, args.slice(2), raw);
474
+ } else {
475
+ error('Unknown requirements subcommand. Available: mark-complete');
476
+ }
477
+ break;
478
+ }
479
+
480
+ case 'phase': {
481
+ const subcommand = args[1];
482
+ if (subcommand === 'next-decimal') {
483
+ if (!args[2]) error('phase next-decimal requires a base phase number');
484
+ phase.cmdPhaseNextDecimal(cwd, args[2], raw);
485
+ } else if (subcommand === 'add') {
486
+ phase.cmdPhaseAdd(cwd, args.slice(2).join(' '), raw);
487
+ } else if (subcommand === 'insert') {
488
+ if (!args[2]) error('phase insert requires a phase number');
489
+ phase.cmdPhaseInsert(cwd, args[2], args.slice(3).join(' '), raw);
490
+ } else if (subcommand === 'remove') {
491
+ if (!args[2]) error('phase remove requires a phase number');
492
+ const forceFlag = args.includes('--force');
493
+ phase.cmdPhaseRemove(cwd, args[2], { force: forceFlag }, raw);
494
+ } else if (subcommand === 'complete') {
495
+ if (!args[2]) error('phase complete requires a phase number');
496
+ const noCommit = args.includes('--no-commit');
497
+ phase.cmdPhaseComplete(cwd, args[2], raw, { noCommit });
498
+ } else {
499
+ error('Unknown phase subcommand. Available: next-decimal, add, insert, remove, complete');
500
+ }
501
+ break;
502
+ }
503
+
504
+ case 'milestone': {
505
+ const subcommand = args[1];
506
+ if (subcommand === 'complete') {
507
+ const nameIndex = args.indexOf('--name');
508
+ const archivePhases = args.includes('--archive-phases');
509
+ // Collect --name value (everything after --name until next flag or end)
510
+ let milestoneName = null;
511
+ if (nameIndex !== -1) {
512
+ const nameArgs = [];
513
+ for (let i = nameIndex + 1; i < args.length; i++) {
514
+ if (args[i].startsWith('--')) break;
515
+ nameArgs.push(args[i]);
516
+ }
517
+ milestoneName = nameArgs.join(' ') || null;
518
+ }
519
+ const noCommitMilestone = args.includes('--no-commit');
520
+ milestone.cmdMilestoneComplete(cwd, args[2], { name: milestoneName, archivePhases, noCommit: noCommitMilestone }, raw);
521
+ } else {
522
+ error('Unknown milestone subcommand. Available: complete');
523
+ }
524
+ break;
525
+ }
526
+
527
+ case 'validate': {
528
+ const subcommand = args[1];
529
+ if (subcommand === 'consistency') {
530
+ verify.cmdValidateConsistency(cwd, raw);
531
+ } else if (subcommand === 'health') {
532
+ const repairFlag = args.includes('--repair');
533
+ const standardsFlag = args.includes('--standards');
534
+ const fullFlag = args.includes('--full');
535
+ const driftFlag = args.includes('--drift');
536
+ verify.cmdValidateHealth(cwd, { repair: repairFlag, standards: standardsFlag, full: fullFlag, drift: driftFlag }, raw);
537
+ } else {
538
+ error('Unknown validate subcommand. Available: consistency, health');
539
+ }
540
+ break;
541
+ }
542
+
543
+ case 'progress': {
544
+ const subcommand = args[1] || 'json';
545
+ commands.cmdProgressRender(cwd, subcommand, raw);
546
+ break;
547
+ }
548
+
549
+ case 'context-budget': {
550
+ contextBudget.cmdContextBudget(cwd, raw);
551
+ break;
552
+ }
553
+
554
+ case 'todo': {
555
+ const subcommand = args[1];
556
+ if (subcommand === 'complete') {
557
+ commands.cmdTodoComplete(cwd, args[2], raw);
558
+ } else {
559
+ error('Unknown todo subcommand. Available: complete');
560
+ }
561
+ break;
562
+ }
563
+
564
+ case 'scaffold': {
565
+ const scaffoldType = args[1];
566
+ const nameIndex = args.indexOf('--name');
567
+ const scaffoldOptions = {
568
+ phase: getArgValue(args, '--phase'),
569
+ name: nameIndex !== -1 ? args.slice(nameIndex + 1).filter(a => !a.startsWith('--')).join(' ') : null,
570
+ };
571
+ commands.cmdScaffold(cwd, scaffoldType, scaffoldOptions, raw);
572
+ break;
573
+ }
574
+
575
+ case 'init': {
576
+ const workflow = args[1];
577
+ switch (workflow) {
578
+ case 'execute-phase': {
579
+ const dryRun = args.includes('--dry-run');
580
+ init.cmdInitExecutePhase(cwd, args[2], raw, { dry_run: dryRun, budget: getArgValue(args, '--budget') ?? undefined });
581
+ break;
582
+ }
583
+ case 'plan-phase':
584
+ init.cmdInitPlanPhase(cwd, args[2], raw);
585
+ break;
586
+ case 'new-project':
587
+ init.cmdInitNewProject(cwd, raw);
588
+ break;
589
+ case 'new-milestone':
590
+ init.cmdInitNewMilestone(cwd, raw);
591
+ break;
592
+ case 'quick':
593
+ init.cmdInitQuick(cwd, args.slice(2).join(' '), raw);
594
+ break;
595
+ case 'resume':
596
+ init.cmdInitResume(cwd, raw);
597
+ break;
598
+ case 'verify-work':
599
+ init.cmdInitVerifyWork(cwd, args[2], raw);
600
+ break;
601
+ case 'phase-op':
602
+ init.cmdInitPhaseOp(cwd, args[2], raw);
603
+ break;
604
+ case 'todos':
605
+ init.cmdInitTodos(cwd, args[2], raw);
606
+ break;
607
+ case 'milestone-op':
608
+ init.cmdInitMilestoneOp(cwd, raw);
609
+ break;
610
+ case 'map-codebase':
611
+ init.cmdInitMapCodebase(cwd, raw);
612
+ break;
613
+ case 'progress':
614
+ init.cmdInitProgress(cwd, raw);
615
+ break;
616
+ default:
617
+ error(`Unknown init workflow: ${workflow}\nAvailable: execute-phase, plan-phase, new-project, new-milestone, quick, resume, verify-work, phase-op, todos, milestone-op, map-codebase, progress`);
618
+ }
619
+ break;
620
+ }
621
+
622
+ case 'phase-plan-index': {
623
+ phase.cmdPhasePlanIndex(cwd, args[1], raw);
624
+ break;
625
+ }
626
+
627
+ case 'state-snapshot': {
628
+ state.cmdStateSnapshot(cwd, raw);
629
+ break;
630
+ }
631
+
632
+ case 'summary-extract': {
633
+ const summaryPath = args[1];
634
+ const fieldsIndex = args.indexOf('--fields');
635
+ const fields = fieldsIndex !== -1 ? args.slice(fieldsIndex + 1).filter(a => !a.startsWith('--')).flatMap(a => a.split(',')) : null;
636
+ commands.cmdSummaryExtract(cwd, summaryPath, fields, raw);
637
+ break;
638
+ }
639
+
640
+ case 'rollback-snapshot': {
641
+ commands.cmdRollbackSnapshot(cwd, args[1], raw);
642
+ break;
643
+ }
644
+
645
+ case 'batch-commit': {
646
+ const itemsJson = args[1];
647
+ let items = [];
648
+ try { items = JSON.parse(itemsJson); } catch { /* empty */ }
649
+ commands.cmdBatchCommit(cwd, items, raw);
650
+ break;
651
+ }
652
+
653
+ case 'websearch': {
654
+ const query = args[1];
655
+ await commands.cmdWebsearch(query, {
656
+ limit: parseInt(getArgValue(args, '--limit', '10'), 10),
657
+ freshness: getArgValue(args, '--freshness'),
658
+ }, raw);
659
+ break;
660
+ }
661
+
662
+ case 'focus': {
663
+ const subcommand = args[1];
664
+ if (subcommand === 'scan') {
665
+ focus.cmdFocusScan(cwd, raw, ...args.slice(2));
666
+ } else if (subcommand === 'plan') {
667
+ focus.cmdFocusPlan(cwd, raw, ...args.slice(2));
668
+ } else if (subcommand === 'sync') {
669
+ focus.cmdFocusSync(cwd, raw, ...args.slice(2));
670
+ } else if (subcommand === 'exec') {
671
+ focus.cmdFocusExec(cwd, raw, ...args.slice(2));
672
+ } else if (subcommand === 'auto') {
673
+ focus.cmdFocusAuto(cwd, raw, ...args.slice(2));
674
+ } else if (subcommand === 'design') {
675
+ // design is a workflow-only command (no core function)
676
+ // The AI reads commands/pan/focus-design.md directly
677
+ output({ command: 'focus-design', type: 'workflow', message: 'Use /pan:focus-design to invoke the 10-phase investigation pipeline' }, raw);
678
+ } else {
679
+ error('Unknown focus subcommand. Available: scan, plan, sync, exec, auto, design');
680
+ }
681
+ break;
682
+ }
683
+
684
+ case 'preflight': {
685
+ verify.cmdPreflight(cwd, args[1] || null, raw);
686
+ break;
687
+ }
688
+
689
+ case 'dashboard': {
690
+ state.cmdDashboard(cwd, raw);
691
+ break;
692
+ }
693
+
694
+ case 'learnings': {
695
+ const subcommand = args[1];
696
+ if (subcommand === 'extract') {
697
+ commands.cmdLearningsExtract(cwd, raw);
698
+ } else if (subcommand === 'list') {
699
+ commands.cmdLearningsList(cwd, raw);
700
+ } else if (subcommand === 'prune') {
701
+ const daysRaw = getArgValue(args, '--days');
702
+ commands.cmdLearningsPrune(cwd, {
703
+ days: daysRaw !== null ? parseInt(daysRaw, 10) : null,
704
+ id: getArgValue(args, '--id'),
705
+ }, raw);
706
+ } else {
707
+ error('Unknown learnings subcommand. Available: extract, list, prune');
708
+ }
709
+ break;
710
+ }
711
+
712
+ case 'deps': {
713
+ const subcommand = args[1];
714
+ if (subcommand === 'validate') {
715
+ verify.cmdDepsValidate(cwd, raw);
716
+ } else {
717
+ error('Unknown deps subcommand. Available: validate');
718
+ }
719
+ break;
720
+ }
721
+
722
+ case 'drift-check': {
723
+ verify.cmdDriftCheck(cwd, raw, args);
724
+ break;
725
+ }
726
+
727
+ case 'retro': {
728
+ verify.cmdRetro(cwd, raw);
729
+ break;
730
+ }
731
+
732
+ case 'codebase': {
733
+ const subcommand = args[1];
734
+ if (subcommand === 'analyze-imports') {
735
+ codebase.cmdAnalyzeImports(cwd, raw, args);
736
+ } else if (subcommand === 'detect-languages') {
737
+ codebase.cmdDetectLanguages(cwd, raw);
738
+ } else if (subcommand === 'best-practices') {
739
+ codebase.cmdBestPractices(cwd, raw);
740
+ } else {
741
+ error('Unknown codebase subcommand. Available: analyze-imports, detect-languages, best-practices');
742
+ }
743
+ break;
744
+ }
745
+
746
+ case 'standards': {
747
+ const subcommand = args[1];
748
+ if (subcommand === 'list') {
749
+ config.cmdStandardsList(cwd, getArgValue(args, '--category'), raw);
750
+ } else if (subcommand === 'select') {
751
+ config.cmdStandardsSelect(cwd, args[2], raw);
752
+ } else if (subcommand === 'remove') {
753
+ config.cmdStandardsRemove(cwd, args[2], raw);
754
+ } else if (subcommand === 'status') {
755
+ config.cmdStandardsStatus(cwd, raw);
756
+ } else if (subcommand === 'recommend') {
757
+ config.cmdStandardsRecommend(cwd, raw);
758
+ } else if (subcommand === 'phase-track') {
759
+ config.cmdStandardsPhaseTrack(cwd, args[2], raw);
760
+ } else if (subcommand === 'tools') {
761
+ config.cmdStandardsTools(cwd, args[2], raw);
762
+ } else {
763
+ error('Unknown standards subcommand. Available: list, select, remove, status, recommend, phase-track, tools');
764
+ }
765
+ break;
766
+ }
767
+
768
+ default:
769
+ error(`Unknown command: ${command}. Run pan-tools without arguments to see available commands.`);
770
+ }
771
+ }
772
+
773
+ main();