maxsimcli 2.5.5 → 3.0.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.
Files changed (137) hide show
  1. package/README.md +4 -0
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/adapters/base.d.ts +34 -0
  4. package/dist/adapters/base.d.ts.map +1 -0
  5. package/dist/adapters/base.js +116 -0
  6. package/dist/adapters/base.js.map +1 -0
  7. package/dist/adapters/claude.d.ts +21 -0
  8. package/dist/adapters/claude.d.ts.map +1 -0
  9. package/dist/adapters/claude.js +104 -0
  10. package/dist/adapters/claude.js.map +1 -0
  11. package/dist/adapters/codex.d.ts +19 -0
  12. package/dist/adapters/codex.d.ts.map +1 -0
  13. package/dist/adapters/codex.js +94 -0
  14. package/dist/adapters/codex.js.map +1 -0
  15. package/dist/adapters/gemini.d.ts +19 -0
  16. package/dist/adapters/gemini.d.ts.map +1 -0
  17. package/dist/adapters/gemini.js +96 -0
  18. package/dist/adapters/gemini.js.map +1 -0
  19. package/dist/adapters/index.d.ts +20 -0
  20. package/dist/adapters/index.d.ts.map +1 -0
  21. package/dist/adapters/index.js +56 -0
  22. package/dist/adapters/index.js.map +1 -0
  23. package/dist/adapters/opencode.d.ts +17 -0
  24. package/dist/adapters/opencode.d.ts.map +1 -0
  25. package/dist/adapters/opencode.js +111 -0
  26. package/dist/adapters/opencode.js.map +1 -0
  27. package/dist/adapters/transforms/content.d.ts +39 -0
  28. package/dist/adapters/transforms/content.d.ts.map +1 -0
  29. package/dist/adapters/transforms/content.js +125 -0
  30. package/dist/adapters/transforms/content.js.map +1 -0
  31. package/dist/adapters/transforms/frontmatter.d.ts +42 -0
  32. package/dist/adapters/transforms/frontmatter.d.ts.map +1 -0
  33. package/dist/adapters/transforms/frontmatter.js +204 -0
  34. package/dist/adapters/transforms/frontmatter.js.map +1 -0
  35. package/dist/adapters/transforms/tool-maps.d.ts +20 -0
  36. package/dist/adapters/transforms/tool-maps.d.ts.map +1 -0
  37. package/dist/adapters/transforms/tool-maps.js +64 -0
  38. package/dist/adapters/transforms/tool-maps.js.map +1 -0
  39. package/dist/adapters/types.d.ts +10 -0
  40. package/dist/adapters/types.d.ts.map +1 -0
  41. package/dist/adapters/types.js +6 -0
  42. package/dist/adapters/types.js.map +1 -0
  43. package/dist/assets/CHANGELOG.md +26 -0
  44. package/dist/assets/dashboard/server.js +27731 -12035
  45. package/dist/assets/hooks/maxsim-check-update.cjs +2 -2
  46. package/dist/assets/hooks/maxsim-check-update.cjs.map +1 -0
  47. package/dist/assets/hooks/maxsim-context-monitor.cjs +2 -2
  48. package/dist/assets/hooks/maxsim-context-monitor.cjs.map +1 -0
  49. package/dist/assets/hooks/maxsim-statusline.cjs +2 -2
  50. package/dist/assets/hooks/maxsim-statusline.cjs.map +1 -0
  51. package/dist/cli.cjs +15316 -5348
  52. package/dist/cli.cjs.map +1 -1
  53. package/dist/cli.d.ts +0 -6
  54. package/dist/cli.d.ts.map +1 -1
  55. package/dist/cli.js +282 -443
  56. package/dist/cli.js.map +1 -1
  57. package/dist/core/commands.d.ts +19 -0
  58. package/dist/core/commands.d.ts.map +1 -0
  59. package/dist/core/commands.js +560 -0
  60. package/dist/core/commands.js.map +1 -0
  61. package/dist/core/config.d.ts +9 -0
  62. package/dist/core/config.d.ts.map +1 -0
  63. package/dist/core/config.js +147 -0
  64. package/dist/core/config.js.map +1 -0
  65. package/dist/core/core.d.ts +39 -0
  66. package/dist/core/core.d.ts.map +1 -0
  67. package/dist/core/core.js +411 -0
  68. package/dist/core/core.js.map +1 -0
  69. package/dist/core/frontmatter.d.ts +33 -0
  70. package/dist/core/frontmatter.d.ts.map +1 -0
  71. package/dist/core/frontmatter.js +192 -0
  72. package/dist/core/frontmatter.js.map +1 -0
  73. package/dist/core/index.d.ts +20 -0
  74. package/dist/core/index.d.ts.map +1 -0
  75. package/dist/core/index.js +126 -0
  76. package/dist/core/index.js.map +1 -0
  77. package/dist/core/init.d.ts +252 -0
  78. package/dist/core/init.d.ts.map +1 -0
  79. package/dist/core/init.js +578 -0
  80. package/dist/core/init.js.map +1 -0
  81. package/dist/core/milestone.d.ts +9 -0
  82. package/dist/core/milestone.d.ts.map +1 -0
  83. package/dist/core/milestone.js +191 -0
  84. package/dist/core/milestone.js.map +1 -0
  85. package/dist/core/phase.d.ts +17 -0
  86. package/dist/core/phase.d.ts.map +1 -0
  87. package/dist/core/phase.js +610 -0
  88. package/dist/core/phase.js.map +1 -0
  89. package/dist/core/roadmap.d.ts +9 -0
  90. package/dist/core/roadmap.d.ts.map +1 -0
  91. package/dist/core/roadmap.js +228 -0
  92. package/dist/core/roadmap.js.map +1 -0
  93. package/dist/core/state.d.ts +21 -0
  94. package/dist/core/state.d.ts.map +1 -0
  95. package/dist/core/state.js +507 -0
  96. package/dist/core/state.js.map +1 -0
  97. package/dist/core/template.d.ts +30 -0
  98. package/dist/core/template.d.ts.map +1 -0
  99. package/dist/core/template.js +225 -0
  100. package/dist/core/template.js.map +1 -0
  101. package/dist/core/types.d.ts +374 -0
  102. package/dist/core/types.d.ts.map +1 -0
  103. package/dist/core/types.js +53 -0
  104. package/dist/core/types.js.map +1 -0
  105. package/dist/core/verify.d.ts +127 -0
  106. package/dist/core/verify.d.ts.map +1 -0
  107. package/dist/core/verify.js +783 -0
  108. package/dist/core/verify.js.map +1 -0
  109. package/dist/hooks/index.d.ts +11 -0
  110. package/dist/hooks/index.d.ts.map +1 -0
  111. package/dist/hooks/index.js +18 -0
  112. package/dist/hooks/index.js.map +1 -0
  113. package/dist/hooks/maxsim-check-update.d.ts +17 -0
  114. package/dist/hooks/maxsim-check-update.d.ts.map +1 -0
  115. package/dist/hooks/maxsim-check-update.js +101 -0
  116. package/dist/hooks/maxsim-check-update.js.map +1 -0
  117. package/dist/hooks/maxsim-context-monitor.d.ts +21 -0
  118. package/dist/hooks/maxsim-context-monitor.d.ts.map +1 -0
  119. package/dist/hooks/maxsim-context-monitor.js +131 -0
  120. package/dist/hooks/maxsim-context-monitor.js.map +1 -0
  121. package/dist/hooks/maxsim-statusline.d.ts +19 -0
  122. package/dist/hooks/maxsim-statusline.d.ts.map +1 -0
  123. package/dist/hooks/maxsim-statusline.js +146 -0
  124. package/dist/hooks/maxsim-statusline.js.map +1 -0
  125. package/dist/hooks/shared.d.ts +11 -0
  126. package/dist/hooks/shared.d.ts.map +1 -0
  127. package/dist/hooks/shared.js +29 -0
  128. package/dist/hooks/shared.js.map +1 -0
  129. package/dist/install.cjs +2807 -1211
  130. package/dist/install.cjs.map +1 -1
  131. package/dist/install.js +34 -85
  132. package/dist/install.js.map +1 -1
  133. package/package.json +10 -7
  134. package/dist/assets/hooks/index.cjs +0 -239
  135. package/dist/assets/templates/CLAUDE.md +0 -22
  136. package/dist/assets/templates/package.json +0 -5
  137. package/dist/assets/templates/project.json +0 -5
package/dist/cli.js CHANGED
@@ -2,13 +2,7 @@
2
2
  /**
3
3
  * MAXSIM Tools — CLI utility for MAXSIM workflow operations
4
4
  *
5
- * Replaces repetitive inline bash patterns across ~50 MAXSIM command/workflow/agent files.
6
- * Centralizes: config parsing, model resolution, phase lookup, git commits, summary verification.
7
- *
8
5
  * Usage: node maxsim-tools.cjs <command> [args] [--raw]
9
- *
10
- * This is a direct TypeScript port of maxsim/bin/maxsim-tools.cjs.
11
- * All imports resolve through @maxsim/core barrel export.
12
6
  */
13
7
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
14
8
  if (k2 === undefined) k2 = k;
@@ -49,24 +43,281 @@ const path = __importStar(require("node:path"));
49
43
  const os = __importStar(require("node:os"));
50
44
  const node_child_process_1 = require("node:child_process");
51
45
  const node_module_1 = require("node:module");
52
- const core_1 = require("@maxsim/core");
53
- /** Helper: extract a named flag's value from args, returning null if absent */
46
+ const index_js_1 = require("./core/index.js");
47
+ // ─── Arg parsing utilities ───────────────────────────────────────────────────
48
+ /** Extract a single named flag's value from args */
54
49
  function getFlag(args, flag) {
55
50
  const idx = args.indexOf(flag);
56
- return idx !== -1 ? args[idx + 1] : null;
51
+ return idx !== -1 ? args[idx + 1] ?? null : null;
52
+ }
53
+ /** Extract multiple named flags at once. Keys are flag names without -- prefix. */
54
+ function getFlags(args, ...flags) {
55
+ const result = {};
56
+ for (const flag of flags) {
57
+ const idx = args.indexOf(`--${flag}`);
58
+ result[flag] = idx !== -1 ? args[idx + 1] ?? null : null;
59
+ }
60
+ return result;
57
61
  }
58
- // Namespace groupings for readability (mirrors original CJS structure)
59
- const state = { cmdStateLoad: core_1.cmdStateLoad, cmdStateGet: core_1.cmdStateGet, cmdStatePatch: core_1.cmdStatePatch, cmdStateUpdate: core_1.cmdStateUpdate, cmdStateAdvancePlan: core_1.cmdStateAdvancePlan, cmdStateRecordMetric: core_1.cmdStateRecordMetric, cmdStateUpdateProgress: core_1.cmdStateUpdateProgress, cmdStateAddDecision: core_1.cmdStateAddDecision, cmdStateAddBlocker: core_1.cmdStateAddBlocker, cmdStateResolveBlocker: core_1.cmdStateResolveBlocker, cmdStateRecordSession: core_1.cmdStateRecordSession, cmdStateSnapshot: core_1.cmdStateSnapshot, stateExtractField: core_1.stateExtractField, stateReplaceField: core_1.stateReplaceField };
60
- const phase = { cmdPhasesList: core_1.cmdPhasesList, cmdPhaseNextDecimal: core_1.cmdPhaseNextDecimal, cmdFindPhase: core_1.cmdFindPhase, cmdPhasePlanIndex: core_1.cmdPhasePlanIndex, cmdPhaseAdd: core_1.cmdPhaseAdd, cmdPhaseInsert: core_1.cmdPhaseInsert, cmdPhaseRemove: core_1.cmdPhaseRemove, cmdPhaseComplete: core_1.cmdPhaseComplete };
61
- const roadmap = { cmdRoadmapGetPhase: core_1.cmdRoadmapGetPhase, cmdRoadmapAnalyze: core_1.cmdRoadmapAnalyze, cmdRoadmapUpdatePlanProgress: core_1.cmdRoadmapUpdatePlanProgress };
62
- const verify = { cmdVerifySummary: core_1.cmdVerifySummary, cmdVerifyPlanStructure: core_1.cmdVerifyPlanStructure, cmdVerifyPhaseCompleteness: core_1.cmdVerifyPhaseCompleteness, cmdVerifyReferences: core_1.cmdVerifyReferences, cmdVerifyCommits: core_1.cmdVerifyCommits, cmdVerifyArtifacts: core_1.cmdVerifyArtifacts, cmdVerifyKeyLinks: core_1.cmdVerifyKeyLinks, cmdValidateConsistency: core_1.cmdValidateConsistency, cmdValidateHealth: core_1.cmdValidateHealth };
63
- const config = { cmdConfigEnsureSection: core_1.cmdConfigEnsureSection, cmdConfigSet: core_1.cmdConfigSet, cmdConfigGet: core_1.cmdConfigGet };
64
- const template = { cmdTemplateSelect: core_1.cmdTemplateSelect, cmdTemplateFill: core_1.cmdTemplateFill };
65
- const milestone = { cmdRequirementsMarkComplete: core_1.cmdRequirementsMarkComplete, cmdMilestoneComplete: core_1.cmdMilestoneComplete };
66
- const commands = { cmdGenerateSlug: core_1.cmdGenerateSlug, cmdCurrentTimestamp: core_1.cmdCurrentTimestamp, cmdListTodos: core_1.cmdListTodos, cmdVerifyPathExists: core_1.cmdVerifyPathExists, cmdHistoryDigest: core_1.cmdHistoryDigest, cmdResolveModel: core_1.cmdResolveModel, cmdCommit: core_1.cmdCommit, cmdSummaryExtract: core_1.cmdSummaryExtract, cmdWebsearch: core_1.cmdWebsearch, cmdProgressRender: core_1.cmdProgressRender, cmdTodoComplete: core_1.cmdTodoComplete, cmdScaffold: core_1.cmdScaffold };
67
- const init = { cmdInitExecutePhase: core_1.cmdInitExecutePhase, cmdInitPlanPhase: core_1.cmdInitPlanPhase, cmdInitNewProject: core_1.cmdInitNewProject, cmdInitNewMilestone: core_1.cmdInitNewMilestone, cmdInitQuick: core_1.cmdInitQuick, cmdInitResume: core_1.cmdInitResume, cmdInitVerifyWork: core_1.cmdInitVerifyWork, cmdInitPhaseOp: core_1.cmdInitPhaseOp, cmdInitTodos: core_1.cmdInitTodos, cmdInitMilestoneOp: core_1.cmdInitMilestoneOp, cmdInitMapCodebase: core_1.cmdInitMapCodebase, cmdInitProgress: core_1.cmdInitProgress };
68
- const frontmatter = { cmdFrontmatterGet: core_1.cmdFrontmatterGet, cmdFrontmatterSet: core_1.cmdFrontmatterSet, cmdFrontmatterMerge: core_1.cmdFrontmatterMerge, cmdFrontmatterValidate: core_1.cmdFrontmatterValidate, extractFrontmatter: core_1.extractFrontmatter, reconstructFrontmatter: core_1.reconstructFrontmatter, spliceFrontmatter: core_1.spliceFrontmatter, parseMustHavesBlock: core_1.parseMustHavesBlock, FRONTMATTER_SCHEMAS: core_1.FRONTMATTER_SCHEMAS };
69
- // ─── CLI Router ───────────────────────────────────────────────────────────────
62
+ /** Check if a boolean flag is present */
63
+ function hasFlag(args, flag) {
64
+ return args.includes(`--${flag}`);
65
+ }
66
+ // ─── Subcommand handlers ─────────────────────────────────────────────────────
67
+ const handleState = (args, cwd, raw) => {
68
+ const sub = args[1];
69
+ const handlers = {
70
+ 'update': () => (0, index_js_1.cmdStateUpdate)(cwd, args[2], args[3]),
71
+ 'get': () => (0, index_js_1.cmdStateGet)(cwd, args[2], raw),
72
+ 'patch': () => {
73
+ const patches = {};
74
+ for (let i = 2; i < args.length; i += 2) {
75
+ const key = args[i].replace(/^--/, '');
76
+ const value = args[i + 1];
77
+ if (key && value !== undefined)
78
+ patches[key] = value;
79
+ }
80
+ (0, index_js_1.cmdStatePatch)(cwd, patches, raw);
81
+ },
82
+ 'advance-plan': () => (0, index_js_1.cmdStateAdvancePlan)(cwd, raw),
83
+ 'record-metric': () => {
84
+ const f = getFlags(args, 'phase', 'plan', 'duration', 'tasks', 'files');
85
+ (0, index_js_1.cmdStateRecordMetric)(cwd, {
86
+ phase: f.phase ?? '', plan: f.plan ?? '', duration: f.duration ?? '',
87
+ tasks: f.tasks ?? undefined, files: f.files ?? undefined,
88
+ }, raw);
89
+ },
90
+ 'update-progress': () => (0, index_js_1.cmdStateUpdateProgress)(cwd, raw),
91
+ 'add-decision': () => {
92
+ const f = getFlags(args, 'phase', 'summary', 'summary-file', 'rationale', 'rationale-file');
93
+ (0, index_js_1.cmdStateAddDecision)(cwd, {
94
+ phase: f.phase ?? undefined, summary: f.summary ?? undefined,
95
+ summary_file: f['summary-file'] ?? undefined,
96
+ rationale: f.rationale ?? '', rationale_file: f['rationale-file'] ?? undefined,
97
+ }, raw);
98
+ },
99
+ 'add-blocker': () => {
100
+ const f = getFlags(args, 'text', 'text-file');
101
+ (0, index_js_1.cmdStateAddBlocker)(cwd, { text: f.text ?? undefined, text_file: f['text-file'] ?? undefined }, raw);
102
+ },
103
+ 'resolve-blocker': () => (0, index_js_1.cmdStateResolveBlocker)(cwd, getFlag(args, '--text'), raw),
104
+ 'record-session': () => {
105
+ const f = getFlags(args, 'stopped-at', 'resume-file');
106
+ (0, index_js_1.cmdStateRecordSession)(cwd, {
107
+ stopped_at: f['stopped-at'] ?? undefined,
108
+ resume_file: f['resume-file'] ?? 'None',
109
+ }, raw);
110
+ },
111
+ };
112
+ const handler = sub ? handlers[sub] : undefined;
113
+ if (handler)
114
+ return handler();
115
+ (0, index_js_1.cmdStateLoad)(cwd, raw);
116
+ };
117
+ const handleTemplate = (args, cwd, raw) => {
118
+ const sub = args[1];
119
+ if (sub === 'select') {
120
+ (0, index_js_1.cmdTemplateSelect)(cwd, args[2], raw);
121
+ }
122
+ else if (sub === 'fill') {
123
+ const f = getFlags(args, 'phase', 'plan', 'name', 'type', 'wave', 'fields');
124
+ (0, index_js_1.cmdTemplateFill)(cwd, args[2], {
125
+ phase: f.phase ?? '', plan: f.plan ?? undefined, name: f.name ?? undefined,
126
+ type: f.type ?? 'execute', wave: f.wave ?? '1',
127
+ fields: f.fields ? JSON.parse(f.fields) : {},
128
+ }, raw);
129
+ }
130
+ else {
131
+ (0, index_js_1.error)('Unknown template subcommand. Available: select, fill');
132
+ }
133
+ };
134
+ const handleFrontmatter = (args, cwd, raw) => {
135
+ const sub = args[1];
136
+ const file = args[2];
137
+ const handlers = {
138
+ 'get': () => (0, index_js_1.cmdFrontmatterGet)(cwd, file, getFlag(args, '--field'), raw),
139
+ 'set': () => (0, index_js_1.cmdFrontmatterSet)(cwd, file, getFlag(args, '--field'), getFlag(args, '--value') ?? undefined, raw),
140
+ 'merge': () => (0, index_js_1.cmdFrontmatterMerge)(cwd, file, getFlag(args, '--data'), raw),
141
+ 'validate': () => (0, index_js_1.cmdFrontmatterValidate)(cwd, file, getFlag(args, '--schema'), raw),
142
+ };
143
+ const handler = sub ? handlers[sub] : undefined;
144
+ if (handler)
145
+ return handler();
146
+ (0, index_js_1.error)('Unknown frontmatter subcommand. Available: get, set, merge, validate');
147
+ };
148
+ const handleVerify = async (args, cwd, raw) => {
149
+ const sub = args[1];
150
+ const handlers = {
151
+ 'plan-structure': () => (0, index_js_1.cmdVerifyPlanStructure)(cwd, args[2], raw),
152
+ 'phase-completeness': () => (0, index_js_1.cmdVerifyPhaseCompleteness)(cwd, args[2], raw),
153
+ 'references': () => (0, index_js_1.cmdVerifyReferences)(cwd, args[2], raw),
154
+ 'commits': () => (0, index_js_1.cmdVerifyCommits)(cwd, args.slice(2), raw),
155
+ 'artifacts': () => (0, index_js_1.cmdVerifyArtifacts)(cwd, args[2], raw),
156
+ 'key-links': () => (0, index_js_1.cmdVerifyKeyLinks)(cwd, args[2], raw),
157
+ };
158
+ const handler = sub ? handlers[sub] : undefined;
159
+ if (handler)
160
+ return handler();
161
+ (0, index_js_1.error)('Unknown verify subcommand. Available: plan-structure, phase-completeness, references, commits, artifacts, key-links');
162
+ };
163
+ const handlePhases = (args, cwd, raw) => {
164
+ const sub = args[1];
165
+ if (sub === 'list') {
166
+ const f = getFlags(args, 'type', 'phase');
167
+ (0, index_js_1.cmdPhasesList)(cwd, { type: f.type, phase: f.phase, includeArchived: hasFlag(args, 'include-archived') }, raw);
168
+ }
169
+ else {
170
+ (0, index_js_1.error)('Unknown phases subcommand. Available: list');
171
+ }
172
+ };
173
+ const handleRoadmap = (args, cwd, raw) => {
174
+ const sub = args[1];
175
+ const handlers = {
176
+ 'get-phase': () => (0, index_js_1.cmdRoadmapGetPhase)(cwd, args[2], raw),
177
+ 'analyze': () => (0, index_js_1.cmdRoadmapAnalyze)(cwd, raw),
178
+ 'update-plan-progress': () => (0, index_js_1.cmdRoadmapUpdatePlanProgress)(cwd, args[2], raw),
179
+ };
180
+ const handler = sub ? handlers[sub] : undefined;
181
+ if (handler)
182
+ return handler();
183
+ (0, index_js_1.error)('Unknown roadmap subcommand. Available: get-phase, analyze, update-plan-progress');
184
+ };
185
+ const handlePhase = (args, cwd, raw) => {
186
+ const sub = args[1];
187
+ const handlers = {
188
+ 'next-decimal': () => (0, index_js_1.cmdPhaseNextDecimal)(cwd, args[2], raw),
189
+ 'add': () => (0, index_js_1.cmdPhaseAdd)(cwd, args.slice(2).join(' '), raw),
190
+ 'insert': () => (0, index_js_1.cmdPhaseInsert)(cwd, args[2], args.slice(3).join(' '), raw),
191
+ 'remove': () => (0, index_js_1.cmdPhaseRemove)(cwd, args[2], { force: hasFlag(args, 'force') }, raw),
192
+ 'complete': () => (0, index_js_1.cmdPhaseComplete)(cwd, args[2], raw),
193
+ };
194
+ const handler = sub ? handlers[sub] : undefined;
195
+ if (handler)
196
+ return handler();
197
+ (0, index_js_1.error)('Unknown phase subcommand. Available: next-decimal, add, insert, remove, complete');
198
+ };
199
+ const handleMilestone = (args, cwd, raw) => {
200
+ const sub = args[1];
201
+ if (sub === 'complete') {
202
+ const nameIndex = args.indexOf('--name');
203
+ let milestoneName = null;
204
+ if (nameIndex !== -1) {
205
+ const nameArgs = [];
206
+ for (let i = nameIndex + 1; i < args.length; i++) {
207
+ if (args[i].startsWith('--'))
208
+ break;
209
+ nameArgs.push(args[i]);
210
+ }
211
+ milestoneName = nameArgs.join(' ') || null;
212
+ }
213
+ (0, index_js_1.cmdMilestoneComplete)(cwd, args[2], {
214
+ name: milestoneName ?? undefined,
215
+ archivePhases: hasFlag(args, 'archive-phases'),
216
+ }, raw);
217
+ }
218
+ else {
219
+ (0, index_js_1.error)('Unknown milestone subcommand. Available: complete');
220
+ }
221
+ };
222
+ const handleValidate = (args, cwd, raw) => {
223
+ const sub = args[1];
224
+ const handlers = {
225
+ 'consistency': () => (0, index_js_1.cmdValidateConsistency)(cwd, raw),
226
+ 'health': () => (0, index_js_1.cmdValidateHealth)(cwd, { repair: hasFlag(args, 'repair') }, raw),
227
+ };
228
+ const handler = sub ? handlers[sub] : undefined;
229
+ if (handler)
230
+ return handler();
231
+ (0, index_js_1.error)('Unknown validate subcommand. Available: consistency, health');
232
+ };
233
+ const handleInit = (args, cwd, raw) => {
234
+ const workflow = args[1];
235
+ const handlers = {
236
+ 'execute-phase': () => (0, index_js_1.cmdInitExecutePhase)(cwd, args[2], raw),
237
+ 'plan-phase': () => (0, index_js_1.cmdInitPlanPhase)(cwd, args[2], raw),
238
+ 'new-project': () => (0, index_js_1.cmdInitNewProject)(cwd, raw),
239
+ 'new-milestone': () => (0, index_js_1.cmdInitNewMilestone)(cwd, raw),
240
+ 'quick': () => (0, index_js_1.cmdInitQuick)(cwd, args.slice(2).join(' '), raw),
241
+ 'resume': () => (0, index_js_1.cmdInitResume)(cwd, raw),
242
+ 'verify-work': () => (0, index_js_1.cmdInitVerifyWork)(cwd, args[2], raw),
243
+ 'phase-op': () => (0, index_js_1.cmdInitPhaseOp)(cwd, args[2], raw),
244
+ 'todos': () => (0, index_js_1.cmdInitTodos)(cwd, args[2], raw),
245
+ 'milestone-op': () => (0, index_js_1.cmdInitMilestoneOp)(cwd, raw),
246
+ 'map-codebase': () => (0, index_js_1.cmdInitMapCodebase)(cwd, raw),
247
+ 'progress': () => (0, index_js_1.cmdInitProgress)(cwd, raw),
248
+ };
249
+ const handler = workflow ? handlers[workflow] : undefined;
250
+ if (handler)
251
+ return handler();
252
+ (0, index_js_1.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`);
253
+ };
254
+ // ─── Command registry ────────────────────────────────────────────────────────
255
+ const COMMANDS = {
256
+ 'state': handleState,
257
+ 'resolve-model': (args, cwd, raw) => (0, index_js_1.cmdResolveModel)(cwd, args[1], raw),
258
+ 'find-phase': (args, cwd, raw) => (0, index_js_1.cmdFindPhase)(cwd, args[1], raw),
259
+ 'commit': async (args, cwd, raw) => {
260
+ const files = args.indexOf('--files') !== -1
261
+ ? args.slice(args.indexOf('--files') + 1).filter(a => !a.startsWith('--'))
262
+ : [];
263
+ await (0, index_js_1.cmdCommit)(cwd, args[1], files, raw, hasFlag(args, 'amend'));
264
+ },
265
+ 'verify-summary': async (args, cwd, raw) => {
266
+ const countIndex = args.indexOf('--check-count');
267
+ const checkCount = countIndex !== -1 ? parseInt(args[countIndex + 1], 10) : 2;
268
+ await (0, index_js_1.cmdVerifySummary)(cwd, args[1], checkCount, raw);
269
+ },
270
+ 'template': handleTemplate,
271
+ 'frontmatter': handleFrontmatter,
272
+ 'verify': handleVerify,
273
+ 'generate-slug': (args, _cwd, raw) => (0, index_js_1.cmdGenerateSlug)(args[1], raw),
274
+ 'current-timestamp': (args, _cwd, raw) => (0, index_js_1.cmdCurrentTimestamp)((args[1] || 'full'), raw),
275
+ 'list-todos': (args, cwd, raw) => (0, index_js_1.cmdListTodos)(cwd, args[1], raw),
276
+ 'verify-path-exists': (args, cwd, raw) => (0, index_js_1.cmdVerifyPathExists)(cwd, args[1], raw),
277
+ 'config-ensure-section': (_args, cwd, raw) => (0, index_js_1.cmdConfigEnsureSection)(cwd, raw),
278
+ 'config-set': (args, cwd, raw) => (0, index_js_1.cmdConfigSet)(cwd, args[1], args[2], raw),
279
+ 'config-get': (args, cwd, raw) => (0, index_js_1.cmdConfigGet)(cwd, args[1], raw),
280
+ 'history-digest': (_args, cwd, raw) => (0, index_js_1.cmdHistoryDigest)(cwd, raw),
281
+ 'phases': handlePhases,
282
+ 'roadmap': handleRoadmap,
283
+ 'requirements': (args, cwd, raw) => {
284
+ if (args[1] === 'mark-complete')
285
+ (0, index_js_1.cmdRequirementsMarkComplete)(cwd, args.slice(2), raw);
286
+ else
287
+ (0, index_js_1.error)('Unknown requirements subcommand. Available: mark-complete');
288
+ },
289
+ 'phase': handlePhase,
290
+ 'milestone': handleMilestone,
291
+ 'validate': handleValidate,
292
+ 'progress': (args, cwd, raw) => (0, index_js_1.cmdProgressRender)(cwd, args[1] || 'json', raw),
293
+ 'todo': (args, cwd, raw) => {
294
+ if (args[1] === 'complete')
295
+ (0, index_js_1.cmdTodoComplete)(cwd, args[2], raw);
296
+ else
297
+ (0, index_js_1.error)('Unknown todo subcommand. Available: complete');
298
+ },
299
+ 'scaffold': (args, cwd, raw) => {
300
+ const f = getFlags(args, 'phase', 'name');
301
+ (0, index_js_1.cmdScaffold)(cwd, args[1], { phase: f.phase, name: f.name ? args.slice(args.indexOf('--name') + 1).join(' ') : null }, raw);
302
+ },
303
+ 'init': handleInit,
304
+ 'phase-plan-index': (args, cwd, raw) => (0, index_js_1.cmdPhasePlanIndex)(cwd, args[1], raw),
305
+ 'state-snapshot': (_args, cwd, raw) => (0, index_js_1.cmdStateSnapshot)(cwd, raw),
306
+ 'summary-extract': (args, cwd, raw) => {
307
+ const fieldsIndex = args.indexOf('--fields');
308
+ const fields = fieldsIndex !== -1 ? args[fieldsIndex + 1].split(',') : null;
309
+ (0, index_js_1.cmdSummaryExtract)(cwd, args[1], fields, raw);
310
+ },
311
+ 'websearch': async (args, _cwd, raw) => {
312
+ const f = getFlags(args, 'limit', 'freshness');
313
+ await (0, index_js_1.cmdWebsearch)(args[1], {
314
+ limit: f.limit ? parseInt(f.limit, 10) : 10,
315
+ freshness: f.freshness ?? undefined,
316
+ }, raw);
317
+ },
318
+ 'dashboard': (args) => handleDashboard(args.slice(1)),
319
+ };
320
+ // ─── Main ────────────────────────────────────────────────────────────────────
70
321
  async function main() {
71
322
  const args = process.argv.slice(2);
72
323
  // Optional cwd override for sandboxed subagents running outside project root.
@@ -76,19 +327,19 @@ async function main() {
76
327
  if (cwdEqArg) {
77
328
  const value = cwdEqArg.slice('--cwd='.length).trim();
78
329
  if (!value)
79
- (0, core_1.error)('Missing value for --cwd');
330
+ (0, index_js_1.error)('Missing value for --cwd');
80
331
  args.splice(args.indexOf(cwdEqArg), 1);
81
332
  cwd = path.resolve(value);
82
333
  }
83
334
  else if (cwdIdx !== -1) {
84
335
  const value = args[cwdIdx + 1];
85
336
  if (!value || value.startsWith('--'))
86
- (0, core_1.error)('Missing value for --cwd');
337
+ (0, index_js_1.error)('Missing value for --cwd');
87
338
  args.splice(cwdIdx, 2);
88
339
  cwd = path.resolve(value);
89
340
  }
90
341
  if (!fs.existsSync(cwd) || !fs.statSync(cwd).isDirectory()) {
91
- (0, core_1.error)(`Invalid --cwd: ${cwd}`);
342
+ (0, index_js_1.error)(`Invalid --cwd: ${cwd}`);
92
343
  }
93
344
  const rawIndex = args.indexOf('--raw');
94
345
  const raw = rawIndex !== -1;
@@ -96,422 +347,15 @@ async function main() {
96
347
  args.splice(rawIndex, 1);
97
348
  const command = args[0];
98
349
  if (!command) {
99
- (0, core_1.error)('Usage: maxsim-tools <command> [args] [--raw] [--cwd <path>]\nCommands: state, resolve-model, find-phase, commit, verify-summary, verify, frontmatter, template, generate-slug, current-timestamp, list-todos, verify-path-exists, config-ensure-section, init');
350
+ (0, index_js_1.error)(`Usage: maxsim-tools <command> [args] [--raw] [--cwd <path>]\nCommands: ${Object.keys(COMMANDS).join(', ')}`);
100
351
  }
101
- switch (command) {
102
- case 'state': {
103
- const subcommand = args[1];
104
- if (subcommand === 'update') {
105
- state.cmdStateUpdate(cwd, args[2], args[3]);
106
- }
107
- else if (subcommand === 'get') {
108
- state.cmdStateGet(cwd, args[2], raw);
109
- }
110
- else if (subcommand === 'patch') {
111
- const patches = {};
112
- for (let i = 2; i < args.length; i += 2) {
113
- const key = args[i].replace(/^--/, '');
114
- const value = args[i + 1];
115
- if (key && value !== undefined) {
116
- patches[key] = value;
117
- }
118
- }
119
- state.cmdStatePatch(cwd, patches, raw);
120
- }
121
- else if (subcommand === 'advance-plan') {
122
- state.cmdStateAdvancePlan(cwd, raw);
123
- }
124
- else if (subcommand === 'record-metric') {
125
- const phaseIdx = args.indexOf('--phase');
126
- const planIdx = args.indexOf('--plan');
127
- const durationIdx = args.indexOf('--duration');
128
- const tasksIdx = args.indexOf('--tasks');
129
- const filesIdx = args.indexOf('--files');
130
- state.cmdStateRecordMetric(cwd, {
131
- phase: phaseIdx !== -1 ? args[phaseIdx + 1] : '',
132
- plan: planIdx !== -1 ? args[planIdx + 1] : '',
133
- duration: durationIdx !== -1 ? args[durationIdx + 1] : '',
134
- tasks: tasksIdx !== -1 ? args[tasksIdx + 1] : undefined,
135
- files: filesIdx !== -1 ? args[filesIdx + 1] : undefined,
136
- }, raw);
137
- }
138
- else if (subcommand === 'update-progress') {
139
- state.cmdStateUpdateProgress(cwd, raw);
140
- }
141
- else if (subcommand === 'add-decision') {
142
- const phaseIdx = args.indexOf('--phase');
143
- const summaryIdx = args.indexOf('--summary');
144
- const summaryFileIdx = args.indexOf('--summary-file');
145
- const rationaleIdx = args.indexOf('--rationale');
146
- const rationaleFileIdx = args.indexOf('--rationale-file');
147
- state.cmdStateAddDecision(cwd, {
148
- phase: phaseIdx !== -1 ? args[phaseIdx + 1] : undefined,
149
- summary: summaryIdx !== -1 ? args[summaryIdx + 1] : undefined,
150
- summary_file: summaryFileIdx !== -1 ? args[summaryFileIdx + 1] : undefined,
151
- rationale: rationaleIdx !== -1 ? args[rationaleIdx + 1] : '',
152
- rationale_file: rationaleFileIdx !== -1 ? args[rationaleFileIdx + 1] : undefined,
153
- }, raw);
154
- }
155
- else if (subcommand === 'add-blocker') {
156
- const textIdx = args.indexOf('--text');
157
- const textFileIdx = args.indexOf('--text-file');
158
- state.cmdStateAddBlocker(cwd, {
159
- text: textIdx !== -1 ? args[textIdx + 1] : undefined,
160
- text_file: textFileIdx !== -1 ? args[textFileIdx + 1] : undefined,
161
- }, raw);
162
- }
163
- else if (subcommand === 'resolve-blocker') {
164
- const textIdx = args.indexOf('--text');
165
- state.cmdStateResolveBlocker(cwd, textIdx !== -1 ? args[textIdx + 1] : null, raw);
166
- }
167
- else if (subcommand === 'record-session') {
168
- const stoppedIdx = args.indexOf('--stopped-at');
169
- const resumeIdx = args.indexOf('--resume-file');
170
- state.cmdStateRecordSession(cwd, {
171
- stopped_at: stoppedIdx !== -1 ? args[stoppedIdx + 1] : undefined,
172
- resume_file: resumeIdx !== -1 ? args[resumeIdx + 1] : 'None',
173
- }, raw);
174
- }
175
- else {
176
- state.cmdStateLoad(cwd, raw);
177
- }
178
- break;
179
- }
180
- case 'resolve-model': {
181
- commands.cmdResolveModel(cwd, args[1], raw);
182
- break;
183
- }
184
- case 'find-phase': {
185
- phase.cmdFindPhase(cwd, args[1], raw);
186
- break;
187
- }
188
- case 'commit': {
189
- const amend = args.includes('--amend');
190
- const message = args[1];
191
- // Parse --files flag (collect args after --files, stopping at other flags)
192
- const filesIndex = args.indexOf('--files');
193
- const files = filesIndex !== -1 ? args.slice(filesIndex + 1).filter(a => !a.startsWith('--')) : [];
194
- commands.cmdCommit(cwd, message, files, raw, amend);
195
- break;
196
- }
197
- case 'verify-summary': {
198
- const summaryPath = args[1];
199
- const countIndex = args.indexOf('--check-count');
200
- const checkCount = countIndex !== -1 ? parseInt(args[countIndex + 1], 10) : 2;
201
- verify.cmdVerifySummary(cwd, summaryPath, checkCount, raw);
202
- break;
203
- }
204
- case 'template': {
205
- const subcommand = args[1];
206
- if (subcommand === 'select') {
207
- template.cmdTemplateSelect(cwd, args[2], raw);
208
- }
209
- else if (subcommand === 'fill') {
210
- const templateType = args[2];
211
- const phaseIdx = args.indexOf('--phase');
212
- const planIdx = args.indexOf('--plan');
213
- const nameIdx = args.indexOf('--name');
214
- const typeIdx = args.indexOf('--type');
215
- const waveIdx = args.indexOf('--wave');
216
- const fieldsIdx = args.indexOf('--fields');
217
- template.cmdTemplateFill(cwd, templateType, {
218
- phase: phaseIdx !== -1 ? args[phaseIdx + 1] : '',
219
- plan: planIdx !== -1 ? args[planIdx + 1] : undefined,
220
- name: nameIdx !== -1 ? args[nameIdx + 1] : undefined,
221
- type: typeIdx !== -1 ? args[typeIdx + 1] : 'execute',
222
- wave: waveIdx !== -1 ? args[waveIdx + 1] : '1',
223
- fields: fieldsIdx !== -1 ? JSON.parse(args[fieldsIdx + 1]) : {},
224
- }, raw);
225
- }
226
- else {
227
- (0, core_1.error)('Unknown template subcommand. Available: select, fill');
228
- }
229
- break;
230
- }
231
- case 'frontmatter': {
232
- const subcommand = args[1];
233
- const file = args[2];
234
- if (subcommand === 'get') {
235
- const fieldIdx = args.indexOf('--field');
236
- frontmatter.cmdFrontmatterGet(cwd, file, getFlag(args, '--field'), raw);
237
- }
238
- else if (subcommand === 'set') {
239
- frontmatter.cmdFrontmatterSet(cwd, file, getFlag(args, '--field'), getFlag(args, '--value') ?? undefined, raw);
240
- }
241
- else if (subcommand === 'merge') {
242
- frontmatter.cmdFrontmatterMerge(cwd, file, getFlag(args, '--data'), raw);
243
- }
244
- else if (subcommand === 'validate') {
245
- frontmatter.cmdFrontmatterValidate(cwd, file, getFlag(args, '--schema'), raw);
246
- }
247
- else {
248
- (0, core_1.error)('Unknown frontmatter subcommand. Available: get, set, merge, validate');
249
- }
250
- break;
251
- }
252
- case 'verify': {
253
- const subcommand = args[1];
254
- if (subcommand === 'plan-structure') {
255
- verify.cmdVerifyPlanStructure(cwd, args[2], raw);
256
- }
257
- else if (subcommand === 'phase-completeness') {
258
- verify.cmdVerifyPhaseCompleteness(cwd, args[2], raw);
259
- }
260
- else if (subcommand === 'references') {
261
- verify.cmdVerifyReferences(cwd, args[2], raw);
262
- }
263
- else if (subcommand === 'commits') {
264
- verify.cmdVerifyCommits(cwd, args.slice(2), raw);
265
- }
266
- else if (subcommand === 'artifacts') {
267
- verify.cmdVerifyArtifacts(cwd, args[2], raw);
268
- }
269
- else if (subcommand === 'key-links') {
270
- verify.cmdVerifyKeyLinks(cwd, args[2], raw);
271
- }
272
- else {
273
- (0, core_1.error)('Unknown verify subcommand. Available: plan-structure, phase-completeness, references, commits, artifacts, key-links');
274
- }
275
- break;
276
- }
277
- case 'generate-slug': {
278
- commands.cmdGenerateSlug(args[1], raw);
279
- break;
280
- }
281
- case 'current-timestamp': {
282
- commands.cmdCurrentTimestamp((args[1] || 'full'), raw);
283
- break;
284
- }
285
- case 'list-todos': {
286
- commands.cmdListTodos(cwd, args[1], raw);
287
- break;
288
- }
289
- case 'verify-path-exists': {
290
- commands.cmdVerifyPathExists(cwd, args[1], raw);
291
- break;
292
- }
293
- case 'config-ensure-section': {
294
- config.cmdConfigEnsureSection(cwd, raw);
295
- break;
296
- }
297
- case 'config-set': {
298
- config.cmdConfigSet(cwd, args[1], args[2], raw);
299
- break;
300
- }
301
- case 'config-get': {
302
- config.cmdConfigGet(cwd, args[1], raw);
303
- break;
304
- }
305
- case 'history-digest': {
306
- commands.cmdHistoryDigest(cwd, raw);
307
- break;
308
- }
309
- case 'phases': {
310
- const subcommand = args[1];
311
- if (subcommand === 'list') {
312
- const typeIndex = args.indexOf('--type');
313
- const phaseIndex = args.indexOf('--phase');
314
- const options = {
315
- type: typeIndex !== -1 ? args[typeIndex + 1] : null,
316
- phase: phaseIndex !== -1 ? args[phaseIndex + 1] : null,
317
- includeArchived: args.includes('--include-archived'),
318
- };
319
- phase.cmdPhasesList(cwd, options, raw);
320
- }
321
- else {
322
- (0, core_1.error)('Unknown phases subcommand. Available: list');
323
- }
324
- break;
325
- }
326
- case 'roadmap': {
327
- const subcommand = args[1];
328
- if (subcommand === 'get-phase') {
329
- roadmap.cmdRoadmapGetPhase(cwd, args[2], raw);
330
- }
331
- else if (subcommand === 'analyze') {
332
- roadmap.cmdRoadmapAnalyze(cwd, raw);
333
- }
334
- else if (subcommand === 'update-plan-progress') {
335
- roadmap.cmdRoadmapUpdatePlanProgress(cwd, args[2], raw);
336
- }
337
- else {
338
- (0, core_1.error)('Unknown roadmap subcommand. Available: get-phase, analyze, update-plan-progress');
339
- }
340
- break;
341
- }
342
- case 'requirements': {
343
- const subcommand = args[1];
344
- if (subcommand === 'mark-complete') {
345
- milestone.cmdRequirementsMarkComplete(cwd, args.slice(2), raw);
346
- }
347
- else {
348
- (0, core_1.error)('Unknown requirements subcommand. Available: mark-complete');
349
- }
350
- break;
351
- }
352
- case 'phase': {
353
- const subcommand = args[1];
354
- if (subcommand === 'next-decimal') {
355
- phase.cmdPhaseNextDecimal(cwd, args[2], raw);
356
- }
357
- else if (subcommand === 'add') {
358
- phase.cmdPhaseAdd(cwd, args.slice(2).join(' '), raw);
359
- }
360
- else if (subcommand === 'insert') {
361
- phase.cmdPhaseInsert(cwd, args[2], args.slice(3).join(' '), raw);
362
- }
363
- else if (subcommand === 'remove') {
364
- const forceFlag = args.includes('--force');
365
- phase.cmdPhaseRemove(cwd, args[2], { force: forceFlag }, raw);
366
- }
367
- else if (subcommand === 'complete') {
368
- phase.cmdPhaseComplete(cwd, args[2], raw);
369
- }
370
- else {
371
- (0, core_1.error)('Unknown phase subcommand. Available: next-decimal, add, insert, remove, complete');
372
- }
373
- break;
374
- }
375
- case 'milestone': {
376
- const subcommand = args[1];
377
- if (subcommand === 'complete') {
378
- const nameIndex = args.indexOf('--name');
379
- const archivePhases = args.includes('--archive-phases');
380
- // Collect --name value (everything after --name until next flag or end)
381
- let milestoneName = null;
382
- if (nameIndex !== -1) {
383
- const nameArgs = [];
384
- for (let i = nameIndex + 1; i < args.length; i++) {
385
- if (args[i].startsWith('--'))
386
- break;
387
- nameArgs.push(args[i]);
388
- }
389
- milestoneName = nameArgs.join(' ') || null;
390
- }
391
- milestone.cmdMilestoneComplete(cwd, args[2], { name: milestoneName ?? undefined, archivePhases }, raw);
392
- }
393
- else {
394
- (0, core_1.error)('Unknown milestone subcommand. Available: complete');
395
- }
396
- break;
397
- }
398
- case 'validate': {
399
- const subcommand = args[1];
400
- if (subcommand === 'consistency') {
401
- verify.cmdValidateConsistency(cwd, raw);
402
- }
403
- else if (subcommand === 'health') {
404
- const repairFlag = args.includes('--repair');
405
- verify.cmdValidateHealth(cwd, { repair: repairFlag }, raw);
406
- }
407
- else {
408
- (0, core_1.error)('Unknown validate subcommand. Available: consistency, health');
409
- }
410
- break;
411
- }
412
- case 'progress': {
413
- const subcommand = args[1] || 'json';
414
- commands.cmdProgressRender(cwd, subcommand, raw);
415
- break;
416
- }
417
- case 'todo': {
418
- const subcommand = args[1];
419
- if (subcommand === 'complete') {
420
- commands.cmdTodoComplete(cwd, args[2], raw);
421
- }
422
- else {
423
- (0, core_1.error)('Unknown todo subcommand. Available: complete');
424
- }
425
- break;
426
- }
427
- case 'scaffold': {
428
- const scaffoldType = args[1];
429
- const phaseIndex = args.indexOf('--phase');
430
- const nameIndex = args.indexOf('--name');
431
- const scaffoldOptions = {
432
- phase: phaseIndex !== -1 ? args[phaseIndex + 1] : null,
433
- name: nameIndex !== -1 ? args.slice(nameIndex + 1).join(' ') : null,
434
- };
435
- commands.cmdScaffold(cwd, scaffoldType, scaffoldOptions, raw);
436
- break;
437
- }
438
- case 'init': {
439
- const workflow = args[1];
440
- switch (workflow) {
441
- case 'execute-phase':
442
- init.cmdInitExecutePhase(cwd, args[2], raw);
443
- break;
444
- case 'plan-phase':
445
- init.cmdInitPlanPhase(cwd, args[2], raw);
446
- break;
447
- case 'new-project':
448
- init.cmdInitNewProject(cwd, raw);
449
- break;
450
- case 'new-milestone':
451
- init.cmdInitNewMilestone(cwd, raw);
452
- break;
453
- case 'quick':
454
- init.cmdInitQuick(cwd, args.slice(2).join(' '), raw);
455
- break;
456
- case 'resume':
457
- init.cmdInitResume(cwd, raw);
458
- break;
459
- case 'verify-work':
460
- init.cmdInitVerifyWork(cwd, args[2], raw);
461
- break;
462
- case 'phase-op':
463
- init.cmdInitPhaseOp(cwd, args[2], raw);
464
- break;
465
- case 'todos':
466
- init.cmdInitTodos(cwd, args[2], raw);
467
- break;
468
- case 'milestone-op':
469
- init.cmdInitMilestoneOp(cwd, raw);
470
- break;
471
- case 'map-codebase':
472
- init.cmdInitMapCodebase(cwd, raw);
473
- break;
474
- case 'progress':
475
- init.cmdInitProgress(cwd, raw);
476
- break;
477
- default:
478
- (0, core_1.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`);
479
- }
480
- break;
481
- }
482
- case 'phase-plan-index': {
483
- phase.cmdPhasePlanIndex(cwd, args[1], raw);
484
- break;
485
- }
486
- case 'state-snapshot': {
487
- state.cmdStateSnapshot(cwd, raw);
488
- break;
489
- }
490
- case 'summary-extract': {
491
- const summaryPath = args[1];
492
- const fieldsIndex = args.indexOf('--fields');
493
- const fields = fieldsIndex !== -1 ? args[fieldsIndex + 1].split(',') : null;
494
- commands.cmdSummaryExtract(cwd, summaryPath, fields, raw);
495
- break;
496
- }
497
- case 'websearch': {
498
- const query = args[1];
499
- const limitIdx = args.indexOf('--limit');
500
- const freshnessIdx = args.indexOf('--freshness');
501
- await commands.cmdWebsearch(query, {
502
- limit: limitIdx !== -1 ? parseInt(args[limitIdx + 1], 10) : 10,
503
- freshness: freshnessIdx !== -1 ? args[freshnessIdx + 1] : undefined,
504
- }, raw);
505
- break;
506
- }
507
- case 'dashboard': {
508
- await handleDashboard(args.slice(1));
509
- break;
510
- }
511
- default:
512
- (0, core_1.error)(`Unknown command: ${command}`);
352
+ const handler = COMMANDS[command];
353
+ if (!handler) {
354
+ (0, index_js_1.error)(`Unknown command: ${command}`);
513
355
  }
356
+ await handler(args, cwd, raw);
514
357
  }
358
+ // ─── Dashboard ───────────────────────────────────────────────────────────────
515
359
  /**
516
360
  * Dashboard launch command.
517
361
  *
@@ -529,11 +373,8 @@ async function handleDashboard(args) {
529
373
  const running = await checkHealth(port, HEALTH_TIMEOUT_MS);
530
374
  if (running) {
531
375
  console.log(`Dashboard found on port ${port} — sending shutdown...`);
532
- // Try to reach a shutdown endpoint, or just inform user
533
376
  console.log(`Dashboard at http://localhost:${port} is running.`);
534
377
  console.log(`To stop it, close the browser tab or kill the process on port ${port}.`);
535
- // On Windows: netstat -ano | findstr :PORT, then taskkill /PID
536
- // On Unix: lsof -i :PORT | awk 'NR>1 {print $2}' | xargs kill
537
378
  try {
538
379
  if (process.platform === 'win32') {
539
380
  const result = (0, node_child_process_1.execSync)(`netstat -ano | findstr :${port} | findstr LISTENING`, { encoding: 'utf-8' }).trim();
@@ -586,7 +427,7 @@ async function handleDashboard(args) {
586
427
  }
587
428
  // Determine runner: if .ts file, use tsx; if .js file, use node
588
429
  const isTsFile = serverPath.endsWith('.ts');
589
- const runner = isTsFile ? 'node' : 'node';
430
+ const runner = 'node';
590
431
  const runnerArgs = isTsFile ? ['--import', 'tsx', serverPath] : [serverPath];
591
432
  // Standalone server must run from its own directory to find .next/
592
433
  const serverDir = path.dirname(serverPath);
@@ -684,11 +525,9 @@ function resolveDashboardServer() {
684
525
  const require_ = (0, node_module_1.createRequire)(import.meta.url);
685
526
  const pkgPath = require_.resolve('@maxsim/dashboard/package.json');
686
527
  const pkgDir = path.dirname(pkgPath);
687
- // Prefer built server.js for production
688
528
  const serverJs = path.join(pkgDir, 'server.js');
689
529
  if (fs.existsSync(serverJs))
690
530
  return serverJs;
691
- // Fall back to source server.ts for dev (requires tsx)
692
531
  const serverTs = path.join(pkgDir, 'server.ts');
693
532
  if (fs.existsSync(serverTs))
694
533
  return serverTs;