maxsimcli 3.11.0 → 4.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 (197) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/adapters/index.d.ts +0 -11
  3. package/dist/adapters/index.d.ts.map +1 -1
  4. package/dist/adapters/index.js +4 -40
  5. package/dist/adapters/index.js.map +1 -1
  6. package/dist/assets/CHANGELOG.md +36 -0
  7. package/dist/assets/dashboard/client/assets/{index-CZ8WC97G.js → index-C_eAetZJ.js} +66 -66
  8. package/dist/assets/dashboard/client/assets/index-CmiJKqOU.css +32 -0
  9. package/dist/assets/dashboard/client/index.html +2 -2
  10. package/dist/assets/dashboard/server.js +467 -271
  11. package/dist/assets/templates/agents/AGENTS.md +94 -0
  12. package/dist/assets/templates/agents/maxsim-debugger.md +2 -2
  13. package/dist/assets/templates/agents/maxsim-executor.md +5 -5
  14. package/dist/assets/templates/agents/maxsim-phase-researcher.md +2 -2
  15. package/dist/assets/templates/agents/maxsim-plan-checker.md +2 -2
  16. package/dist/assets/templates/agents/maxsim-planner.md +3 -3
  17. package/dist/assets/templates/commands/maxsim/add-todo.md +15 -5
  18. package/dist/assets/templates/commands/maxsim/discuss-phase.md +1 -0
  19. package/dist/assets/templates/commands/maxsim/init-existing.md +4 -0
  20. package/dist/assets/templates/commands/maxsim/new-project.md +4 -0
  21. package/dist/assets/templates/commands/maxsim/settings.md +1 -1
  22. package/dist/assets/templates/references/thinking-partner.md +41 -0
  23. package/dist/assets/templates/skills/batch-worktree/SKILL.md +137 -0
  24. package/dist/assets/templates/skills/brainstorming/SKILL.md +159 -0
  25. package/dist/assets/templates/skills/code-review/SKILL.md +151 -0
  26. package/dist/assets/templates/skills/memory-management/SKILL.md +174 -0
  27. package/dist/assets/templates/skills/roadmap-writing/SKILL.md +198 -0
  28. package/dist/assets/templates/skills/sdd/SKILL.md +175 -0
  29. package/dist/assets/templates/skills/simplify/SKILL.md +185 -0
  30. package/dist/assets/templates/skills/using-maxsim/SKILL.md +120 -0
  31. package/dist/assets/templates/templates/acceptance-criteria.md +10 -0
  32. package/dist/assets/templates/templates/config.json +1 -1
  33. package/dist/assets/templates/templates/decisions.md +10 -0
  34. package/dist/assets/templates/templates/no-gos.md +9 -0
  35. package/dist/assets/templates/workflows/add-tests.md +3 -3
  36. package/dist/assets/templates/workflows/add-todo.md +89 -0
  37. package/dist/assets/templates/workflows/complete-milestone.md +1 -1
  38. package/dist/assets/templates/workflows/discuss-phase.md +85 -1
  39. package/dist/assets/templates/workflows/execute-phase.md +26 -16
  40. package/dist/assets/templates/workflows/execute-plan.md +166 -0
  41. package/dist/assets/templates/workflows/init-existing.md +123 -3
  42. package/dist/assets/templates/workflows/new-milestone.md +4 -0
  43. package/dist/assets/templates/workflows/new-project.md +111 -3
  44. package/dist/assets/templates/workflows/plan-phase.md +5 -5
  45. package/dist/assets/templates/workflows/quick.md +2 -2
  46. package/dist/assets/templates/workflows/settings.md +8 -4
  47. package/dist/assets/templates/workflows/verify-work.md +1 -1
  48. package/dist/cli.cjs +1512 -1026
  49. package/dist/cli.cjs.map +1 -1
  50. package/dist/cli.js +170 -278
  51. package/dist/cli.js.map +1 -1
  52. package/dist/core/artefakte.d.ts +12 -0
  53. package/dist/core/artefakte.d.ts.map +1 -0
  54. package/dist/core/artefakte.js +136 -0
  55. package/dist/core/artefakte.js.map +1 -0
  56. package/dist/core/commands.d.ts +13 -13
  57. package/dist/core/commands.d.ts.map +1 -1
  58. package/dist/core/commands.js +48 -58
  59. package/dist/core/commands.js.map +1 -1
  60. package/dist/core/config.d.ts +4 -3
  61. package/dist/core/config.d.ts.map +1 -1
  62. package/dist/core/config.js +14 -18
  63. package/dist/core/config.js.map +1 -1
  64. package/dist/core/context-loader.d.ts +20 -0
  65. package/dist/core/context-loader.d.ts.map +1 -0
  66. package/dist/core/context-loader.js +154 -0
  67. package/dist/core/context-loader.js.map +1 -0
  68. package/dist/core/core.d.ts +26 -2
  69. package/dist/core/core.d.ts.map +1 -1
  70. package/dist/core/core.js +90 -24
  71. package/dist/core/core.js.map +1 -1
  72. package/dist/core/dashboard-launcher.d.ts +56 -0
  73. package/dist/core/dashboard-launcher.d.ts.map +1 -0
  74. package/dist/core/dashboard-launcher.js +246 -0
  75. package/dist/core/dashboard-launcher.js.map +1 -0
  76. package/dist/core/frontmatter.d.ts +5 -5
  77. package/dist/core/frontmatter.d.ts.map +1 -1
  78. package/dist/core/frontmatter.js +21 -26
  79. package/dist/core/frontmatter.js.map +1 -1
  80. package/dist/core/index.d.ts +10 -3
  81. package/dist/core/index.d.ts.map +1 -1
  82. package/dist/core/index.js +40 -2
  83. package/dist/core/index.js.map +1 -1
  84. package/dist/core/init.d.ts +14 -15
  85. package/dist/core/init.d.ts.map +1 -1
  86. package/dist/core/init.js +93 -155
  87. package/dist/core/init.js.map +1 -1
  88. package/dist/core/milestone.d.ts +3 -3
  89. package/dist/core/milestone.d.ts.map +1 -1
  90. package/dist/core/milestone.js +9 -9
  91. package/dist/core/milestone.js.map +1 -1
  92. package/dist/core/phase.d.ts +9 -9
  93. package/dist/core/phase.d.ts.map +1 -1
  94. package/dist/core/phase.js +65 -63
  95. package/dist/core/phase.js.map +1 -1
  96. package/dist/core/roadmap.d.ts +4 -3
  97. package/dist/core/roadmap.d.ts.map +1 -1
  98. package/dist/core/roadmap.js +46 -108
  99. package/dist/core/roadmap.js.map +1 -1
  100. package/dist/core/skills.d.ts +19 -0
  101. package/dist/core/skills.d.ts.map +1 -0
  102. package/dist/core/skills.js +145 -0
  103. package/dist/core/skills.js.map +1 -0
  104. package/dist/core/start.d.ts +15 -0
  105. package/dist/core/start.d.ts.map +1 -0
  106. package/dist/core/start.js +80 -0
  107. package/dist/core/start.js.map +1 -0
  108. package/dist/core/state.d.ts +13 -13
  109. package/dist/core/state.d.ts.map +1 -1
  110. package/dist/core/state.js +125 -130
  111. package/dist/core/state.js.map +1 -1
  112. package/dist/core/template.d.ts +3 -3
  113. package/dist/core/template.d.ts.map +1 -1
  114. package/dist/core/template.js +12 -14
  115. package/dist/core/template.js.map +1 -1
  116. package/dist/core/types.d.ts +15 -4
  117. package/dist/core/types.d.ts.map +1 -1
  118. package/dist/core/types.js +9 -2
  119. package/dist/core/types.js.map +1 -1
  120. package/dist/core/verify.d.ts +10 -9
  121. package/dist/core/verify.d.ts.map +1 -1
  122. package/dist/core/verify.js +38 -48
  123. package/dist/core/verify.js.map +1 -1
  124. package/dist/core-TFSlUjV1.cjs +4312 -0
  125. package/dist/core-TFSlUjV1.cjs.map +1 -0
  126. package/dist/install/adapters.d.ts +6 -0
  127. package/dist/install/adapters.d.ts.map +1 -0
  128. package/dist/install/adapters.js +65 -0
  129. package/dist/install/adapters.js.map +1 -0
  130. package/dist/install/copy.d.ts +6 -0
  131. package/dist/install/copy.d.ts.map +1 -0
  132. package/dist/install/copy.js +71 -0
  133. package/dist/install/copy.js.map +1 -0
  134. package/dist/install/dashboard.d.ts +16 -0
  135. package/dist/install/dashboard.d.ts.map +1 -0
  136. package/dist/install/dashboard.js +273 -0
  137. package/dist/install/dashboard.js.map +1 -0
  138. package/dist/install/hooks.d.ts +31 -0
  139. package/dist/install/hooks.d.ts.map +1 -0
  140. package/dist/install/hooks.js +260 -0
  141. package/dist/install/hooks.js.map +1 -0
  142. package/dist/install/index.d.ts +2 -0
  143. package/dist/install/index.d.ts.map +1 -0
  144. package/dist/install/index.js +535 -0
  145. package/dist/install/index.js.map +1 -0
  146. package/dist/install/manifest.d.ts +23 -0
  147. package/dist/install/manifest.d.ts.map +1 -0
  148. package/dist/install/manifest.js +129 -0
  149. package/dist/install/manifest.js.map +1 -0
  150. package/dist/install/patches.d.ts +10 -0
  151. package/dist/install/patches.d.ts.map +1 -0
  152. package/dist/install/patches.js +124 -0
  153. package/dist/install/patches.js.map +1 -0
  154. package/dist/install/shared.d.ts +56 -0
  155. package/dist/install/shared.d.ts.map +1 -0
  156. package/dist/install/shared.js +172 -0
  157. package/dist/install/shared.js.map +1 -0
  158. package/dist/install/uninstall.d.ts +5 -0
  159. package/dist/install/uninstall.d.ts.map +1 -0
  160. package/dist/install/uninstall.js +222 -0
  161. package/dist/install/uninstall.js.map +1 -0
  162. package/dist/install.cjs +793 -1648
  163. package/dist/install.cjs.map +1 -1
  164. package/dist/mcp-server.cjs +38 -14
  165. package/dist/mcp-server.cjs.map +1 -1
  166. package/dist/skills-BOSxYUzf.cjs +6812 -0
  167. package/dist/skills-BOSxYUzf.cjs.map +1 -0
  168. package/package.json +1 -1
  169. package/dist/adapters/codex.d.ts +0 -19
  170. package/dist/adapters/codex.d.ts.map +0 -1
  171. package/dist/adapters/codex.js +0 -94
  172. package/dist/adapters/codex.js.map +0 -1
  173. package/dist/adapters/gemini.d.ts +0 -19
  174. package/dist/adapters/gemini.d.ts.map +0 -1
  175. package/dist/adapters/gemini.js +0 -96
  176. package/dist/adapters/gemini.js.map +0 -1
  177. package/dist/adapters/opencode.d.ts +0 -17
  178. package/dist/adapters/opencode.d.ts.map +0 -1
  179. package/dist/adapters/opencode.js +0 -111
  180. package/dist/adapters/opencode.js.map +0 -1
  181. package/dist/adapters/transforms/content.d.ts +0 -39
  182. package/dist/adapters/transforms/content.d.ts.map +0 -1
  183. package/dist/adapters/transforms/content.js +0 -125
  184. package/dist/adapters/transforms/content.js.map +0 -1
  185. package/dist/adapters/transforms/frontmatter.d.ts +0 -42
  186. package/dist/adapters/transforms/frontmatter.d.ts.map +0 -1
  187. package/dist/adapters/transforms/frontmatter.js +0 -204
  188. package/dist/adapters/transforms/frontmatter.js.map +0 -1
  189. package/dist/adapters/transforms/tool-maps.d.ts +0 -20
  190. package/dist/adapters/transforms/tool-maps.d.ts.map +0 -1
  191. package/dist/adapters/transforms/tool-maps.js +0 -64
  192. package/dist/adapters/transforms/tool-maps.js.map +0 -1
  193. package/dist/assets/dashboard/client/assets/index-DzJChB-D.css +0 -32
  194. package/dist/install.d.ts +0 -2
  195. package/dist/install.d.ts.map +0 -1
  196. package/dist/install.js +0 -1841
  197. package/dist/install.js.map +0 -1
package/dist/cli.js CHANGED
@@ -40,9 +40,7 @@ var __importStar = (this && this.__importStar) || (function () {
40
40
  Object.defineProperty(exports, "__esModule", { value: true });
41
41
  const fs = __importStar(require("node:fs"));
42
42
  const path = __importStar(require("node:path"));
43
- const os = __importStar(require("node:os"));
44
43
  const node_child_process_1 = require("node:child_process");
45
- const node_module_1 = require("node:module");
46
44
  const index_js_1 = require("./core/index.js");
47
45
  // ─── Arg parsing utilities ───────────────────────────────────────────────────
48
46
  /** Extract a single named flag's value from args */
@@ -63,8 +61,16 @@ function getFlags(args, ...flags) {
63
61
  function hasFlag(args, flag) {
64
62
  return args.includes(`--${flag}`);
65
63
  }
64
+ // ─── Result dispatcher ───────────────────────────────────────────────────────
65
+ /** Convert a CmdResult into the appropriate output()/error() call. */
66
+ function handleResult(r, raw) {
67
+ if (r.ok)
68
+ (0, index_js_1.output)(r.result, raw, r.rawValue);
69
+ else
70
+ (0, index_js_1.error)(r.error);
71
+ }
66
72
  // ─── Subcommand handlers ─────────────────────────────────────────────────────
67
- const handleState = (args, cwd, raw) => {
73
+ const handleState = async (args, cwd, raw) => {
68
74
  const sub = args[1];
69
75
  const handlers = {
70
76
  'update': () => (0, index_js_1.cmdStateUpdate)(cwd, args[2], args[3]),
@@ -77,12 +83,12 @@ const handleState = (args, cwd, raw) => {
77
83
  if (key && value !== undefined)
78
84
  patches[key] = value;
79
85
  }
80
- (0, index_js_1.cmdStatePatch)(cwd, patches, raw);
86
+ return (0, index_js_1.cmdStatePatch)(cwd, patches, raw);
81
87
  },
82
88
  'advance-plan': () => (0, index_js_1.cmdStateAdvancePlan)(cwd, raw),
83
89
  'record-metric': () => {
84
90
  const f = getFlags(args, 'phase', 'plan', 'duration', 'tasks', 'files');
85
- (0, index_js_1.cmdStateRecordMetric)(cwd, {
91
+ return (0, index_js_1.cmdStateRecordMetric)(cwd, {
86
92
  phase: f.phase ?? '', plan: f.plan ?? '', duration: f.duration ?? '',
87
93
  tasks: f.tasks ?? undefined, files: f.files ?? undefined,
88
94
  }, raw);
@@ -90,7 +96,7 @@ const handleState = (args, cwd, raw) => {
90
96
  'update-progress': () => (0, index_js_1.cmdStateUpdateProgress)(cwd, raw),
91
97
  'add-decision': () => {
92
98
  const f = getFlags(args, 'phase', 'summary', 'summary-file', 'rationale', 'rationale-file');
93
- (0, index_js_1.cmdStateAddDecision)(cwd, {
99
+ return (0, index_js_1.cmdStateAddDecision)(cwd, {
94
100
  phase: f.phase ?? undefined, summary: f.summary ?? undefined,
95
101
  summary_file: f['summary-file'] ?? undefined,
96
102
  rationale: f.rationale ?? '', rationale_file: f['rationale-file'] ?? undefined,
@@ -98,12 +104,12 @@ const handleState = (args, cwd, raw) => {
98
104
  },
99
105
  'add-blocker': () => {
100
106
  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);
107
+ return (0, index_js_1.cmdStateAddBlocker)(cwd, { text: f.text ?? undefined, text_file: f['text-file'] ?? undefined }, raw);
102
108
  },
103
109
  'resolve-blocker': () => (0, index_js_1.cmdStateResolveBlocker)(cwd, getFlag(args, '--text'), raw),
104
110
  'record-session': () => {
105
111
  const f = getFlags(args, 'stopped-at', 'resume-file');
106
- (0, index_js_1.cmdStateRecordSession)(cwd, {
112
+ return (0, index_js_1.cmdStateRecordSession)(cwd, {
107
113
  stopped_at: f['stopped-at'] ?? undefined,
108
114
  resume_file: f['resume-file'] ?? 'None',
109
115
  }, raw);
@@ -111,21 +117,21 @@ const handleState = (args, cwd, raw) => {
111
117
  };
112
118
  const handler = sub ? handlers[sub] : undefined;
113
119
  if (handler)
114
- return handler();
115
- (0, index_js_1.cmdStateLoad)(cwd, raw);
120
+ return handleResult(await handler(), raw);
121
+ return handleResult(await (0, index_js_1.cmdStateLoad)(cwd, raw), raw);
116
122
  };
117
123
  const handleTemplate = (args, cwd, raw) => {
118
124
  const sub = args[1];
119
125
  if (sub === 'select') {
120
- (0, index_js_1.cmdTemplateSelect)(cwd, args[2], raw);
126
+ handleResult((0, index_js_1.cmdTemplateSelect)(cwd, args[2]), raw);
121
127
  }
122
128
  else if (sub === 'fill') {
123
129
  const f = getFlags(args, 'phase', 'plan', 'name', 'type', 'wave', 'fields');
124
- (0, index_js_1.cmdTemplateFill)(cwd, args[2], {
130
+ handleResult((0, index_js_1.cmdTemplateFill)(cwd, args[2], {
125
131
  phase: f.phase ?? '', plan: f.plan ?? undefined, name: f.name ?? undefined,
126
132
  type: f.type ?? 'execute', wave: f.wave ?? '1',
127
133
  fields: f.fields ? JSON.parse(f.fields) : {},
128
- }, raw);
134
+ }), raw);
129
135
  }
130
136
  else {
131
137
  (0, index_js_1.error)('Unknown template subcommand. Available: select, fill');
@@ -135,10 +141,10 @@ const handleFrontmatter = (args, cwd, raw) => {
135
141
  const sub = args[1];
136
142
  const file = args[2];
137
143
  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),
144
+ 'get': () => handleResult((0, index_js_1.cmdFrontmatterGet)(cwd, file, getFlag(args, '--field')), raw),
145
+ 'set': () => handleResult((0, index_js_1.cmdFrontmatterSet)(cwd, file, getFlag(args, '--field'), getFlag(args, '--value') ?? undefined), raw),
146
+ 'merge': () => handleResult((0, index_js_1.cmdFrontmatterMerge)(cwd, file, getFlag(args, '--data')), raw),
147
+ 'validate': () => handleResult((0, index_js_1.cmdFrontmatterValidate)(cwd, file, getFlag(args, '--schema')), raw),
142
148
  };
143
149
  const handler = sub ? handlers[sub] : undefined;
144
150
  if (handler)
@@ -148,52 +154,58 @@ const handleFrontmatter = (args, cwd, raw) => {
148
154
  const handleVerify = async (args, cwd, raw) => {
149
155
  const sub = args[1];
150
156
  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
+ 'plan-structure': () => handleResult((0, index_js_1.cmdVerifyPlanStructure)(cwd, args[2]), raw),
158
+ 'phase-completeness': () => handleResult((0, index_js_1.cmdVerifyPhaseCompleteness)(cwd, args[2]), raw),
159
+ 'references': () => handleResult((0, index_js_1.cmdVerifyReferences)(cwd, args[2]), raw),
160
+ 'commits': async () => handleResult(await (0, index_js_1.cmdVerifyCommits)(cwd, args.slice(2)), raw),
161
+ 'artifacts': () => handleResult((0, index_js_1.cmdVerifyArtifacts)(cwd, args[2]), raw),
162
+ 'key-links': () => handleResult((0, index_js_1.cmdVerifyKeyLinks)(cwd, args[2]), raw),
157
163
  };
158
164
  const handler = sub ? handlers[sub] : undefined;
159
165
  if (handler)
160
166
  return handler();
161
167
  (0, index_js_1.error)('Unknown verify subcommand. Available: plan-structure, phase-completeness, references, commits, artifacts, key-links');
162
168
  };
163
- const handlePhases = (args, cwd, raw) => {
169
+ const handlePhases = async (args, cwd, raw) => {
164
170
  const sub = args[1];
165
171
  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);
172
+ const f = getFlags(args, 'type', 'phase', 'offset', 'limit');
173
+ handleResult(await (0, index_js_1.cmdPhasesList)(cwd, {
174
+ type: f.type,
175
+ phase: f.phase,
176
+ includeArchived: hasFlag(args, 'include-archived'),
177
+ offset: f.offset !== null ? parseInt(f.offset, 10) : undefined,
178
+ limit: f.limit !== null ? parseInt(f.limit, 10) : undefined,
179
+ }), raw);
168
180
  }
169
181
  else {
170
182
  (0, index_js_1.error)('Unknown phases subcommand. Available: list');
171
183
  }
172
184
  };
173
- const handleRoadmap = (args, cwd, raw) => {
185
+ const handleRoadmap = async (args, cwd, raw) => {
174
186
  const sub = args[1];
175
187
  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),
188
+ 'get-phase': () => (0, index_js_1.cmdRoadmapGetPhase)(cwd, args[2]),
189
+ 'analyze': () => (0, index_js_1.cmdRoadmapAnalyze)(cwd),
190
+ 'update-plan-progress': () => (0, index_js_1.cmdRoadmapUpdatePlanProgress)(cwd, args[2]),
179
191
  };
180
192
  const handler = sub ? handlers[sub] : undefined;
181
193
  if (handler)
182
- return handler();
194
+ return handleResult(await handler(), raw);
183
195
  (0, index_js_1.error)('Unknown roadmap subcommand. Available: get-phase, analyze, update-plan-progress');
184
196
  };
185
197
  const handlePhase = (args, cwd, raw) => {
186
198
  const sub = args[1];
187
199
  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),
200
+ 'next-decimal': () => (0, index_js_1.cmdPhaseNextDecimal)(cwd, args[2]),
201
+ 'add': () => (0, index_js_1.cmdPhaseAdd)(cwd, args.slice(2).join(' ')),
202
+ 'insert': () => (0, index_js_1.cmdPhaseInsert)(cwd, args[2], args.slice(3).join(' ')),
203
+ 'remove': () => (0, index_js_1.cmdPhaseRemove)(cwd, args[2], { force: hasFlag(args, 'force') }),
204
+ 'complete': () => (0, index_js_1.cmdPhaseComplete)(cwd, args[2]),
193
205
  };
194
206
  const handler = sub ? handlers[sub] : undefined;
195
207
  if (handler)
196
- return handler();
208
+ return handleResult(handler(), raw);
197
209
  (0, index_js_1.error)('Unknown phase subcommand. Available: next-decimal, add, insert, remove, complete');
198
210
  };
199
211
  const handleMilestone = (args, cwd, raw) => {
@@ -210,10 +222,10 @@ const handleMilestone = (args, cwd, raw) => {
210
222
  }
211
223
  milestoneName = nameArgs.join(' ') || null;
212
224
  }
213
- (0, index_js_1.cmdMilestoneComplete)(cwd, args[2], {
225
+ handleResult((0, index_js_1.cmdMilestoneComplete)(cwd, args[2], {
214
226
  name: milestoneName ?? undefined,
215
227
  archivePhases: hasFlag(args, 'archive-phases'),
216
- }, raw);
228
+ }), raw);
217
229
  }
218
230
  else {
219
231
  (0, index_js_1.error)('Unknown milestone subcommand. Available: complete');
@@ -222,8 +234,8 @@ const handleMilestone = (args, cwd, raw) => {
222
234
  const handleValidate = (args, cwd, raw) => {
223
235
  const sub = args[1];
224
236
  const handlers = {
225
- 'consistency': () => (0, index_js_1.cmdValidateConsistency)(cwd, raw),
226
- 'health': () => (0, index_js_1.cmdValidateHealth)(cwd, { repair: hasFlag(args, 'repair') }, raw),
237
+ 'consistency': () => handleResult((0, index_js_1.cmdValidateConsistency)(cwd), raw),
238
+ 'health': () => handleResult((0, index_js_1.cmdValidateHealth)(cwd, { repair: hasFlag(args, 'repair') }), raw),
227
239
  };
228
240
  const handler = sub ? handlers[sub] : undefined;
229
241
  if (handler)
@@ -233,89 +245,98 @@ const handleValidate = (args, cwd, raw) => {
233
245
  const handleInit = (args, cwd, raw) => {
234
246
  const workflow = args[1];
235
247
  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
- 'init-existing': () => (0, index_js_1.cmdInitExisting)(cwd, raw),
248
- 'progress': () => (0, index_js_1.cmdInitProgress)(cwd, raw),
248
+ 'execute-phase': () => (0, index_js_1.cmdInitExecutePhase)(cwd, args[2]),
249
+ 'plan-phase': () => (0, index_js_1.cmdInitPlanPhase)(cwd, args[2]),
250
+ 'new-project': () => (0, index_js_1.cmdInitNewProject)(cwd),
251
+ 'new-milestone': () => (0, index_js_1.cmdInitNewMilestone)(cwd),
252
+ 'quick': () => (0, index_js_1.cmdInitQuick)(cwd, args.slice(2).join(' ')),
253
+ 'resume': () => (0, index_js_1.cmdInitResume)(cwd),
254
+ 'verify-work': () => (0, index_js_1.cmdInitVerifyWork)(cwd, args[2]),
255
+ 'phase-op': () => (0, index_js_1.cmdInitPhaseOp)(cwd, args[2]),
256
+ 'todos': () => (0, index_js_1.cmdInitTodos)(cwd, args[2]),
257
+ 'milestone-op': () => (0, index_js_1.cmdInitMilestoneOp)(cwd),
258
+ 'map-codebase': () => (0, index_js_1.cmdInitMapCodebase)(cwd),
259
+ 'init-existing': () => (0, index_js_1.cmdInitExisting)(cwd),
260
+ 'progress': () => (0, index_js_1.cmdInitProgress)(cwd),
249
261
  };
250
262
  const handler = workflow ? handlers[workflow] : undefined;
251
263
  if (handler)
252
- return handler();
264
+ return handleResult(handler(), raw);
253
265
  (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, init-existing, progress`);
254
266
  };
255
267
  // ─── Command registry ────────────────────────────────────────────────────────
256
268
  const COMMANDS = {
257
269
  'state': handleState,
258
- 'resolve-model': (args, cwd, raw) => (0, index_js_1.cmdResolveModel)(cwd, args[1], raw),
259
- 'find-phase': (args, cwd, raw) => (0, index_js_1.cmdFindPhase)(cwd, args[1], raw),
270
+ 'resolve-model': (args, cwd, raw) => handleResult((0, index_js_1.cmdResolveModel)(cwd, args[1], raw), raw),
271
+ 'find-phase': (args, cwd, raw) => handleResult((0, index_js_1.cmdFindPhase)(cwd, args[1]), raw),
260
272
  'commit': async (args, cwd, raw) => {
261
273
  const files = args.indexOf('--files') !== -1
262
274
  ? args.slice(args.indexOf('--files') + 1).filter(a => !a.startsWith('--'))
263
275
  : [];
264
- await (0, index_js_1.cmdCommit)(cwd, args[1], files, raw, hasFlag(args, 'amend'));
276
+ handleResult(await (0, index_js_1.cmdCommit)(cwd, args[1], files, raw, hasFlag(args, 'amend')), raw);
265
277
  },
266
278
  'verify-summary': async (args, cwd, raw) => {
267
279
  const countIndex = args.indexOf('--check-count');
268
280
  const checkCount = countIndex !== -1 ? parseInt(args[countIndex + 1], 10) : 2;
269
- await (0, index_js_1.cmdVerifySummary)(cwd, args[1], checkCount, raw);
281
+ handleResult(await (0, index_js_1.cmdVerifySummary)(cwd, args[1], checkCount), raw);
270
282
  },
271
283
  'template': handleTemplate,
272
284
  'frontmatter': handleFrontmatter,
273
285
  'verify': handleVerify,
274
- 'generate-slug': (args, _cwd, raw) => (0, index_js_1.cmdGenerateSlug)(args[1], raw),
275
- 'current-timestamp': (args, _cwd, raw) => (0, index_js_1.cmdCurrentTimestamp)((args[1] || 'full'), raw),
276
- 'list-todos': (args, cwd, raw) => (0, index_js_1.cmdListTodos)(cwd, args[1], raw),
277
- 'verify-path-exists': (args, cwd, raw) => (0, index_js_1.cmdVerifyPathExists)(cwd, args[1], raw),
278
- 'config-ensure-section': (_args, cwd, raw) => (0, index_js_1.cmdConfigEnsureSection)(cwd, raw),
279
- 'config-set': (args, cwd, raw) => (0, index_js_1.cmdConfigSet)(cwd, args[1], args[2], raw),
280
- 'config-get': (args, cwd, raw) => (0, index_js_1.cmdConfigGet)(cwd, args[1], raw),
281
- 'history-digest': (_args, cwd, raw) => (0, index_js_1.cmdHistoryDigest)(cwd, raw),
286
+ 'generate-slug': (args, _cwd, raw) => handleResult((0, index_js_1.cmdGenerateSlug)(args[1], raw), raw),
287
+ 'current-timestamp': (args, _cwd, raw) => handleResult((0, index_js_1.cmdCurrentTimestamp)((args[1] || 'full'), raw), raw),
288
+ 'list-todos': (args, cwd, raw) => handleResult((0, index_js_1.cmdListTodos)(cwd, args[1], raw), raw),
289
+ 'verify-path-exists': (args, cwd, raw) => handleResult((0, index_js_1.cmdVerifyPathExists)(cwd, args[1], raw), raw),
290
+ 'config-ensure-section': (_args, cwd, raw) => handleResult((0, index_js_1.cmdConfigEnsureSection)(cwd, raw), raw),
291
+ 'config-set': (args, cwd, raw) => handleResult((0, index_js_1.cmdConfigSet)(cwd, args[1], args[2], raw), raw),
292
+ 'config-get': (args, cwd, raw) => handleResult((0, index_js_1.cmdConfigGet)(cwd, args[1], raw), raw),
293
+ 'history-digest': (_args, cwd, raw) => handleResult((0, index_js_1.cmdHistoryDigest)(cwd, raw), raw),
282
294
  'phases': handlePhases,
283
295
  'roadmap': handleRoadmap,
284
296
  'requirements': (args, cwd, raw) => {
285
297
  if (args[1] === 'mark-complete')
286
- (0, index_js_1.cmdRequirementsMarkComplete)(cwd, args.slice(2), raw);
298
+ handleResult((0, index_js_1.cmdRequirementsMarkComplete)(cwd, args.slice(2)), raw);
287
299
  else
288
300
  (0, index_js_1.error)('Unknown requirements subcommand. Available: mark-complete');
289
301
  },
290
302
  'phase': handlePhase,
291
303
  'milestone': handleMilestone,
292
304
  'validate': handleValidate,
293
- 'progress': (args, cwd, raw) => (0, index_js_1.cmdProgressRender)(cwd, args[1] || 'json', raw),
305
+ 'progress': (args, cwd, raw) => handleResult((0, index_js_1.cmdProgressRender)(cwd, args[1] || 'json', raw), raw),
294
306
  'todo': (args, cwd, raw) => {
295
307
  if (args[1] === 'complete')
296
- (0, index_js_1.cmdTodoComplete)(cwd, args[2], raw);
308
+ handleResult((0, index_js_1.cmdTodoComplete)(cwd, args[2], raw), raw);
297
309
  else
298
310
  (0, index_js_1.error)('Unknown todo subcommand. Available: complete');
299
311
  },
300
312
  'scaffold': (args, cwd, raw) => {
301
313
  const f = getFlags(args, 'phase', 'name');
302
- (0, index_js_1.cmdScaffold)(cwd, args[1], { phase: f.phase, name: f.name ? args.slice(args.indexOf('--name') + 1).join(' ') : null }, raw);
314
+ handleResult((0, index_js_1.cmdScaffold)(cwd, args[1], { phase: f.phase, name: f.name ? args.slice(args.indexOf('--name') + 1).join(' ') : null }, raw), raw);
303
315
  },
304
316
  'init': handleInit,
305
- 'phase-plan-index': (args, cwd, raw) => (0, index_js_1.cmdPhasePlanIndex)(cwd, args[1], raw),
306
- 'state-snapshot': (_args, cwd, raw) => (0, index_js_1.cmdStateSnapshot)(cwd, raw),
317
+ 'phase-plan-index': (args, cwd, raw) => handleResult((0, index_js_1.cmdPhasePlanIndex)(cwd, args[1]), raw),
318
+ 'state-snapshot': (_args, cwd, raw) => handleResult((0, index_js_1.cmdStateSnapshot)(cwd, raw), raw),
307
319
  'summary-extract': (args, cwd, raw) => {
308
320
  const fieldsIndex = args.indexOf('--fields');
309
321
  const fields = fieldsIndex !== -1 ? args[fieldsIndex + 1].split(',') : null;
310
- (0, index_js_1.cmdSummaryExtract)(cwd, args[1], fields, raw);
322
+ handleResult((0, index_js_1.cmdSummaryExtract)(cwd, args[1], fields, raw), raw);
311
323
  },
312
324
  'websearch': async (args, _cwd, raw) => {
313
325
  const f = getFlags(args, 'limit', 'freshness');
314
- await (0, index_js_1.cmdWebsearch)(args[1], {
326
+ handleResult(await (0, index_js_1.cmdWebsearch)(args[1], {
315
327
  limit: f.limit ? parseInt(f.limit, 10) : 10,
316
328
  freshness: f.freshness ?? undefined,
317
- }, raw);
329
+ }, raw), raw);
318
330
  },
331
+ 'artefakte-read': (args, cwd, raw) => handleResult((0, index_js_1.cmdArtefakteRead)(cwd, args[1], getFlag(args, '--phase') ?? undefined, raw), raw),
332
+ 'artefakte-write': (args, cwd, raw) => handleResult((0, index_js_1.cmdArtefakteWrite)(cwd, args[1], getFlag(args, '--content') ?? undefined, getFlag(args, '--phase') ?? undefined, raw), raw),
333
+ 'artefakte-append': (args, cwd, raw) => handleResult((0, index_js_1.cmdArtefakteAppend)(cwd, args[1], getFlag(args, '--entry') ?? undefined, getFlag(args, '--phase') ?? undefined, raw), raw),
334
+ 'artefakte-list': (args, cwd, raw) => handleResult((0, index_js_1.cmdArtefakteList)(cwd, getFlag(args, '--phase') ?? undefined, raw), raw),
335
+ 'context-load': (args, cwd, raw) => handleResult((0, index_js_1.cmdContextLoad)(cwd, getFlag(args, '--phase') ?? undefined, getFlag(args, '--topic') ?? undefined, hasFlag(args, 'include-history')), raw),
336
+ 'skill-list': (_args, cwd, raw) => (0, index_js_1.cmdSkillList)(cwd, raw),
337
+ 'skill-install': (args, cwd, raw) => (0, index_js_1.cmdSkillInstall)(cwd, args[1], raw),
338
+ 'skill-update': (args, cwd, raw) => (0, index_js_1.cmdSkillUpdate)(cwd, args[1], raw),
339
+ 'start': async (args, cwd, raw) => handleResult(await (0, index_js_1.cmdStart)(cwd, { noBrowser: hasFlag(args, 'no-browser'), networkMode: hasFlag(args, 'network') }), raw),
319
340
  'dashboard': (args) => handleDashboard(args.slice(1)),
320
341
  'start-server': async () => {
321
342
  const serverPath = path.join(__dirname, 'mcp-server.cjs');
@@ -325,43 +346,58 @@ const COMMANDS = {
325
346
  };
326
347
  // ─── Main ────────────────────────────────────────────────────────────────────
327
348
  async function main() {
328
- const args = process.argv.slice(2);
329
- // Optional cwd override for sandboxed subagents running outside project root.
330
- let cwd = process.cwd();
331
- const cwdEqArg = args.find(arg => arg.startsWith('--cwd='));
332
- const cwdIdx = args.indexOf('--cwd');
333
- if (cwdEqArg) {
334
- const value = cwdEqArg.slice('--cwd='.length).trim();
335
- if (!value)
336
- (0, index_js_1.error)('Missing value for --cwd');
337
- args.splice(args.indexOf(cwdEqArg), 1);
338
- cwd = path.resolve(value);
339
- }
340
- else if (cwdIdx !== -1) {
341
- const value = args[cwdIdx + 1];
342
- if (!value || value.startsWith('--'))
343
- (0, index_js_1.error)('Missing value for --cwd');
344
- args.splice(cwdIdx, 2);
345
- cwd = path.resolve(value);
346
- }
347
- if (!fs.existsSync(cwd) || !fs.statSync(cwd).isDirectory()) {
348
- (0, index_js_1.error)(`Invalid --cwd: ${cwd}`);
349
- }
350
- const rawIndex = args.indexOf('--raw');
351
- const raw = rawIndex !== -1;
352
- if (rawIndex !== -1)
353
- args.splice(rawIndex, 1);
354
- const command = args[0];
355
- if (!command) {
356
- (0, index_js_1.error)(`Usage: maxsim-tools <command> [args] [--raw] [--cwd <path>]\nCommands: ${Object.keys(COMMANDS).join(', ')}`);
349
+ try {
350
+ const args = process.argv.slice(2);
351
+ // Optional cwd override for sandboxed subagents running outside project root.
352
+ let cwd = process.cwd();
353
+ const cwdEqArg = args.find(arg => arg.startsWith('--cwd='));
354
+ const cwdIdx = args.indexOf('--cwd');
355
+ if (cwdEqArg) {
356
+ const value = cwdEqArg.slice('--cwd='.length).trim();
357
+ if (!value)
358
+ (0, index_js_1.error)('Missing value for --cwd');
359
+ args.splice(args.indexOf(cwdEqArg), 1);
360
+ cwd = path.resolve(value);
361
+ }
362
+ else if (cwdIdx !== -1) {
363
+ const value = args[cwdIdx + 1];
364
+ if (!value || value.startsWith('--'))
365
+ (0, index_js_1.error)('Missing value for --cwd');
366
+ args.splice(cwdIdx, 2);
367
+ cwd = path.resolve(value);
368
+ }
369
+ if (!fs.existsSync(cwd) || !fs.statSync(cwd).isDirectory()) {
370
+ (0, index_js_1.error)(`Invalid --cwd: ${cwd}`);
371
+ }
372
+ const rawIndex = args.indexOf('--raw');
373
+ const raw = rawIndex !== -1;
374
+ if (rawIndex !== -1)
375
+ args.splice(rawIndex, 1);
376
+ const command = args[0];
377
+ if (!command) {
378
+ (0, index_js_1.error)(`Usage: maxsim-tools <command> [args] [--raw] [--cwd <path>]\nCommands: ${Object.keys(COMMANDS).join(', ')}`);
379
+ }
380
+ const handler = COMMANDS[command];
381
+ if (!handler) {
382
+ (0, index_js_1.error)(`Unknown command: ${command}`);
383
+ }
384
+ await handler(args, cwd, raw);
357
385
  }
358
- const handler = COMMANDS[command];
359
- if (!handler) {
360
- (0, index_js_1.error)(`Unknown command: ${command}`);
386
+ catch (thrown) {
387
+ if (thrown instanceof index_js_1.CliOutput) {
388
+ (0, index_js_1.writeOutput)(thrown);
389
+ process.exit(0);
390
+ }
391
+ if (thrown instanceof index_js_1.CliError) {
392
+ process.stderr.write('Error: ' + thrown.message + '\n');
393
+ process.exit(1);
394
+ }
395
+ // Re-throw unexpected errors
396
+ throw thrown;
361
397
  }
362
- await handler(args, cwd, raw);
363
398
  }
364
399
  // ─── Dashboard ───────────────────────────────────────────────────────────────
400
+ const dashboard_launcher_js_1 = require("./core/dashboard-launcher.js");
365
401
  /**
366
402
  * Dashboard launch command.
367
403
  *
@@ -370,47 +406,15 @@ async function main() {
370
406
  * Supports --stop to kill a running instance.
371
407
  */
372
408
  async function handleDashboard(args) {
373
- const DEFAULT_PORT = 3333;
374
- const PORT_RANGE_END = 3343;
375
- const HEALTH_TIMEOUT_MS = 1500;
376
409
  const networkMode = args.includes('--network');
377
410
  // Handle --stop flag
378
411
  if (args.includes('--stop')) {
379
- for (let port = DEFAULT_PORT; port <= PORT_RANGE_END; port++) {
380
- const running = await checkHealth(port, HEALTH_TIMEOUT_MS);
412
+ for (let port = dashboard_launcher_js_1.DEFAULT_PORT; port <= dashboard_launcher_js_1.PORT_RANGE_END; port++) {
413
+ const running = await (0, dashboard_launcher_js_1.checkHealth)(port);
381
414
  if (running) {
382
- console.log(`Dashboard found on port ${port} — sending shutdown...`);
383
- console.log(`Dashboard at http://localhost:${port} is running.`);
384
- console.log(`To stop it, close the browser tab or kill the process on port ${port}.`);
385
- try {
386
- if (process.platform === 'win32') {
387
- const result = (0, node_child_process_1.execSync)(`netstat -ano | findstr :${port} | findstr LISTENING`, { encoding: 'utf-8' }).trim();
388
- const lines = result.split('\n');
389
- const pids = new Set();
390
- for (const line of lines) {
391
- const parts = line.trim().split(/\s+/);
392
- const pid = parts[parts.length - 1];
393
- if (pid && pid !== '0')
394
- pids.add(pid);
395
- }
396
- for (const pid of pids) {
397
- try {
398
- (0, node_child_process_1.execSync)(`taskkill /PID ${pid} /F`, { stdio: 'ignore' });
399
- console.log(`Killed process ${pid}`);
400
- }
401
- catch {
402
- // Process may have already exited
403
- }
404
- }
405
- }
406
- else {
407
- (0, node_child_process_1.execSync)(`lsof -i :${port} -t | xargs kill -SIGTERM 2>/dev/null`, { stdio: 'ignore' });
408
- }
409
- console.log('Dashboard stopped.');
410
- }
411
- catch {
412
- console.log('Could not automatically stop the dashboard. Kill the process manually.');
413
- }
415
+ console.log(`Dashboard found on port ${port} — stopping...`);
416
+ (0, dashboard_launcher_js_1.killProcessOnPort)(port);
417
+ console.log('Dashboard stopped.');
414
418
  return;
415
419
  }
416
420
  }
@@ -418,152 +422,40 @@ async function handleDashboard(args) {
418
422
  return;
419
423
  }
420
424
  // Check if dashboard is already running
421
- for (let port = DEFAULT_PORT; port <= PORT_RANGE_END; port++) {
422
- const running = await checkHealth(port, HEALTH_TIMEOUT_MS);
423
- if (running) {
424
- console.log(`Dashboard already running at http://localhost:${port}`);
425
- return;
426
- }
425
+ const runningPort = await (0, dashboard_launcher_js_1.findRunningDashboard)();
426
+ if (runningPort) {
427
+ console.log(`Dashboard already running at http://localhost:${runningPort}`);
428
+ return;
427
429
  }
428
430
  // Resolve the dashboard server entry point
429
- const serverPath = resolveDashboardServer();
431
+ const serverPath = (0, dashboard_launcher_js_1.resolveDashboardServer)();
430
432
  if (!serverPath) {
431
433
  console.error('Could not find @maxsim/dashboard server entry point.');
432
434
  console.error('Ensure @maxsim/dashboard is installed and built.');
433
435
  process.exit(1);
434
436
  }
435
- // Determine runner: if .ts file, use tsx; if .js file, use node
436
- const isTsFile = serverPath.endsWith('.ts');
437
- const runner = 'node';
438
- const runnerArgs = isTsFile ? ['--import', 'tsx', serverPath] : [serverPath];
439
- // Standalone server must run from its own directory to find .next/
440
437
  const serverDir = path.dirname(serverPath);
441
- // Read dashboard.json for projectCwd (one level up from dashboard/ dir)
442
- let projectCwd = process.cwd();
443
- const dashboardConfigPath = path.join(path.dirname(serverDir), 'dashboard.json');
444
- if (fs.existsSync(dashboardConfigPath)) {
445
- try {
446
- const config = JSON.parse(fs.readFileSync(dashboardConfigPath, 'utf8'));
447
- if (config.projectCwd) {
448
- projectCwd = config.projectCwd;
449
- }
450
- }
451
- catch {
452
- // Use default cwd
453
- }
454
- }
455
- // node-pty is a native addon that must be installed in the dashboard directory.
456
- // Auto-install it if missing so the terminal works out of the box.
457
- const ptyModulePath = path.join(serverDir, 'node_modules', 'node-pty');
458
- if (!fs.existsSync(ptyModulePath)) {
459
- console.log('Installing node-pty for terminal support...');
460
- try {
461
- (0, node_child_process_1.execSync)('npm install node-pty --save-optional --no-audit --no-fund --loglevel=error', {
462
- cwd: serverDir,
463
- stdio: 'inherit',
464
- timeout: 120_000,
465
- });
466
- }
467
- catch {
468
- console.warn('node-pty installation failed — terminal will be unavailable.');
469
- }
438
+ const dashConfig = (0, dashboard_launcher_js_1.readDashboardConfig)(serverPath);
439
+ // Auto-install node-pty if missing
440
+ console.log('Installing node-pty for terminal support...');
441
+ if (!(0, dashboard_launcher_js_1.ensureNodePty)(serverDir)) {
442
+ console.warn('node-pty installation failed — terminal will be unavailable.');
470
443
  }
471
444
  console.log('Dashboard starting...');
472
- const child = (0, node_child_process_1.spawn)(runner, runnerArgs, {
473
- cwd: serverDir,
474
- detached: true,
475
- stdio: 'ignore',
476
- env: {
477
- ...process.env,
478
- MAXSIM_PROJECT_CWD: projectCwd,
479
- NODE_ENV: isTsFile ? 'development' : 'production',
480
- ...(networkMode ? { MAXSIM_NETWORK_MODE: '1' } : {}),
481
- },
482
- // On Windows, use shell to ensure detached works correctly
483
- ...(process.platform === 'win32' ? { shell: true } : {}),
445
+ const pid = (0, dashboard_launcher_js_1.spawnDashboard)({
446
+ serverPath,
447
+ projectCwd: dashConfig.projectCwd,
448
+ networkMode,
484
449
  });
485
- child.unref();
486
450
  // Wait briefly for the server to start, then check health
487
451
  await new Promise((resolve) => setTimeout(resolve, 3000));
488
- for (let port = DEFAULT_PORT; port <= PORT_RANGE_END; port++) {
489
- const running = await checkHealth(port, HEALTH_TIMEOUT_MS);
490
- if (running) {
491
- console.log(`Dashboard ready at http://localhost:${port}`);
492
- return;
493
- }
494
- }
495
- console.log(`Dashboard spawned (PID ${child.pid}). It may take a moment to start.`);
496
- console.log(`Check http://localhost:${DEFAULT_PORT} once ready.`);
497
- }
498
- /**
499
- * Check if a dashboard health endpoint is responding on the given port.
500
- */
501
- async function checkHealth(port, timeoutMs) {
502
- try {
503
- const controller = new AbortController();
504
- const timer = setTimeout(() => controller.abort(), timeoutMs);
505
- const res = await fetch(`http://localhost:${port}/api/health`, {
506
- signal: controller.signal,
507
- });
508
- clearTimeout(timer);
509
- if (res.ok) {
510
- const data = await res.json();
511
- return data.status === 'ok';
512
- }
513
- return false;
514
- }
515
- catch {
516
- return false;
517
- }
518
- }
519
- /**
520
- * Resolve the dashboard server entry point path.
521
- * Tries: built server.js first, then source server.ts for dev mode.
522
- */
523
- function resolveDashboardServer() {
524
- // Strategy 0: Installed standalone build (production path)
525
- const localDashboard = path.join(process.cwd(), '.claude', 'dashboard', 'server.js');
526
- if (fs.existsSync(localDashboard))
527
- return localDashboard;
528
- const globalDashboard = path.join(os.homedir(), '.claude', 'dashboard', 'server.js');
529
- if (fs.existsSync(globalDashboard))
530
- return globalDashboard;
531
- // Strategy 1: Resolve from @maxsim/dashboard package
532
- try {
533
- const require_ = (0, node_module_1.createRequire)(import.meta.url);
534
- const pkgPath = require_.resolve('@maxsim/dashboard/package.json');
535
- const pkgDir = path.dirname(pkgPath);
536
- const serverJs = path.join(pkgDir, 'server.js');
537
- if (fs.existsSync(serverJs))
538
- return serverJs;
539
- const serverTs = path.join(pkgDir, 'server.ts');
540
- if (fs.existsSync(serverTs))
541
- return serverTs;
542
- }
543
- catch {
544
- // @maxsim/dashboard not resolvable
545
- }
546
- // Strategy 2: Walk up from this file to find the monorepo root
547
- try {
548
- let dir = path.dirname(new URL(import.meta.url).pathname);
549
- // On Windows, remove leading / from /C:/...
550
- if (process.platform === 'win32' && dir.startsWith('/')) {
551
- dir = dir.slice(1);
552
- }
553
- for (let i = 0; i < 5; i++) {
554
- const candidate = path.join(dir, 'packages', 'dashboard', 'server.ts');
555
- if (fs.existsSync(candidate))
556
- return candidate;
557
- const candidateJs = path.join(dir, 'packages', 'dashboard', 'server.js');
558
- if (fs.existsSync(candidateJs))
559
- return candidateJs;
560
- dir = path.dirname(dir);
561
- }
562
- }
563
- catch {
564
- // Fallback walk failed
452
+ const readyPort = await (0, dashboard_launcher_js_1.findRunningDashboard)();
453
+ if (readyPort) {
454
+ console.log(`Dashboard ready at http://localhost:${readyPort}`);
455
+ return;
565
456
  }
566
- return null;
457
+ console.log(`Dashboard spawned (PID ${pid}). It may take a moment to start.`);
458
+ console.log(`Check http://localhost:${dashboard_launcher_js_1.DEFAULT_PORT} once ready.`);
567
459
  }
568
460
  main();
569
461
  //# sourceMappingURL=cli.js.map