maxsimcli 4.0.2 → 4.2.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 (127) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/assets/CHANGELOG.md +16 -0
  3. package/dist/assets/dashboard/client/assets/{index-C_eAetZJ.js → index-BcRHShXD.js} +59 -59
  4. package/dist/assets/dashboard/client/assets/index-C199D4Eb.css +32 -0
  5. package/dist/assets/dashboard/client/index.html +2 -2
  6. package/dist/assets/dashboard/server.js +26 -11
  7. package/dist/assets/templates/agents/AGENTS.md +18 -69
  8. package/dist/assets/templates/agents/maxsim-code-reviewer.md +17 -92
  9. package/dist/assets/templates/agents/maxsim-codebase-mapper.md +57 -694
  10. package/dist/assets/templates/agents/maxsim-debugger.md +80 -925
  11. package/dist/assets/templates/agents/maxsim-executor.md +94 -431
  12. package/dist/assets/templates/agents/maxsim-integration-checker.md +51 -319
  13. package/dist/assets/templates/agents/maxsim-phase-researcher.md +63 -429
  14. package/dist/assets/templates/agents/maxsim-plan-checker.md +79 -568
  15. package/dist/assets/templates/agents/maxsim-planner.md +125 -855
  16. package/dist/assets/templates/agents/maxsim-project-researcher.md +32 -472
  17. package/dist/assets/templates/agents/maxsim-research-synthesizer.md +25 -134
  18. package/dist/assets/templates/agents/maxsim-roadmapper.md +66 -480
  19. package/dist/assets/templates/agents/maxsim-spec-reviewer.md +13 -55
  20. package/dist/assets/templates/agents/maxsim-verifier.md +95 -450
  21. package/dist/assets/templates/commands/maxsim/artefakte.md +122 -0
  22. package/dist/assets/templates/commands/maxsim/batch.md +42 -0
  23. package/dist/assets/templates/commands/maxsim/check-todos.md +1 -0
  24. package/dist/assets/templates/commands/maxsim/sdd.md +39 -0
  25. package/dist/assets/templates/references/thinking-partner.md +33 -0
  26. package/dist/assets/templates/workflows/batch.md +420 -0
  27. package/dist/assets/templates/workflows/check-todos.md +85 -1
  28. package/dist/assets/templates/workflows/discuss-phase.md +31 -0
  29. package/dist/assets/templates/workflows/execute-plan.md +96 -27
  30. package/dist/assets/templates/workflows/help.md +47 -0
  31. package/dist/assets/templates/workflows/sdd.md +426 -0
  32. package/dist/backend/index.d.ts +4 -0
  33. package/dist/backend/index.d.ts.map +1 -0
  34. package/dist/backend/index.js +12 -0
  35. package/dist/backend/index.js.map +1 -0
  36. package/dist/backend/lifecycle.d.ts +13 -0
  37. package/dist/backend/lifecycle.d.ts.map +1 -0
  38. package/dist/backend/lifecycle.js +168 -0
  39. package/dist/backend/lifecycle.js.map +1 -0
  40. package/dist/backend/server.d.ts +13 -0
  41. package/dist/backend/server.d.ts.map +1 -0
  42. package/dist/backend/server.js +1013 -0
  43. package/dist/backend/server.js.map +1 -0
  44. package/dist/backend/terminal.d.ts +49 -0
  45. package/dist/backend/terminal.d.ts.map +1 -0
  46. package/dist/backend/terminal.js +209 -0
  47. package/dist/backend/terminal.js.map +1 -0
  48. package/dist/backend/types.d.ts +77 -0
  49. package/dist/backend/types.d.ts.map +1 -0
  50. package/dist/backend/types.js +6 -0
  51. package/dist/backend/types.js.map +1 -0
  52. package/dist/backend-server.cjs +80636 -0
  53. package/dist/backend-server.cjs.map +1 -0
  54. package/dist/backend-server.d.cts +2 -0
  55. package/dist/backend-server.d.ts +11 -0
  56. package/dist/backend-server.d.ts.map +1 -0
  57. package/dist/backend-server.js +43 -0
  58. package/dist/backend-server.js.map +1 -0
  59. package/dist/cli.cjs +378 -172
  60. package/dist/cli.cjs.map +1 -1
  61. package/dist/cli.js +28 -8
  62. package/dist/cli.js.map +1 -1
  63. package/dist/core/artefakte.d.ts.map +1 -1
  64. package/dist/core/artefakte.js +16 -0
  65. package/dist/core/artefakte.js.map +1 -1
  66. package/dist/core/context-loader.d.ts +1 -0
  67. package/dist/core/context-loader.d.ts.map +1 -1
  68. package/dist/core/context-loader.js +58 -0
  69. package/dist/core/context-loader.js.map +1 -1
  70. package/dist/core/core.d.ts +6 -0
  71. package/dist/core/core.d.ts.map +1 -1
  72. package/dist/core/core.js +238 -0
  73. package/dist/core/core.js.map +1 -1
  74. package/dist/core/index.d.ts +1 -1
  75. package/dist/core/index.d.ts.map +1 -1
  76. package/dist/core/index.js +5 -3
  77. package/dist/core/index.js.map +1 -1
  78. package/dist/core/phase.d.ts +11 -11
  79. package/dist/core/phase.d.ts.map +1 -1
  80. package/dist/core/phase.js +88 -73
  81. package/dist/core/phase.js.map +1 -1
  82. package/dist/core/roadmap.d.ts +2 -2
  83. package/dist/core/roadmap.d.ts.map +1 -1
  84. package/dist/core/roadmap.js +11 -10
  85. package/dist/core/roadmap.js.map +1 -1
  86. package/dist/core/skills.d.ts +4 -3
  87. package/dist/core/skills.d.ts.map +1 -1
  88. package/dist/core/skills.js +14 -15
  89. package/dist/core/skills.js.map +1 -1
  90. package/dist/core/state.d.ts +11 -11
  91. package/dist/core/state.d.ts.map +1 -1
  92. package/dist/core/state.js +60 -54
  93. package/dist/core/state.js.map +1 -1
  94. package/dist/{core-TFSlUjV1.cjs → core-RRjCSt0G.cjs} +1 -9
  95. package/dist/{core-TFSlUjV1.cjs.map → core-RRjCSt0G.cjs.map} +1 -1
  96. package/dist/esm-iIOBzmdz.cjs +1561 -0
  97. package/dist/esm-iIOBzmdz.cjs.map +1 -0
  98. package/dist/install.cjs +2 -2
  99. package/dist/lifecycle-0M4VqOMm.cjs +136 -0
  100. package/dist/lifecycle-0M4VqOMm.cjs.map +1 -0
  101. package/dist/mcp/config-tools.d.ts +13 -0
  102. package/dist/mcp/config-tools.d.ts.map +1 -0
  103. package/dist/mcp/config-tools.js +66 -0
  104. package/dist/mcp/config-tools.js.map +1 -0
  105. package/dist/mcp/context-tools.d.ts +13 -0
  106. package/dist/mcp/context-tools.d.ts.map +1 -0
  107. package/dist/mcp/context-tools.js +176 -0
  108. package/dist/mcp/context-tools.js.map +1 -0
  109. package/dist/mcp/index.d.ts +0 -1
  110. package/dist/mcp/index.d.ts.map +1 -1
  111. package/dist/mcp/index.js +6 -1
  112. package/dist/mcp/index.js.map +1 -1
  113. package/dist/mcp/phase-tools.js +3 -3
  114. package/dist/mcp/phase-tools.js.map +1 -1
  115. package/dist/mcp/roadmap-tools.d.ts +13 -0
  116. package/dist/mcp/roadmap-tools.d.ts.map +1 -0
  117. package/dist/mcp/roadmap-tools.js +79 -0
  118. package/dist/mcp/roadmap-tools.js.map +1 -0
  119. package/dist/mcp-server.cjs +799 -38
  120. package/dist/mcp-server.cjs.map +1 -1
  121. package/dist/server-G1MIg_Oe.cjs +2980 -0
  122. package/dist/server-G1MIg_Oe.cjs.map +1 -0
  123. package/dist/{skills-BOSxYUzf.cjs → skills-MYlMkYNt.cjs} +41 -29
  124. package/dist/skills-MYlMkYNt.cjs.map +1 -0
  125. package/package.json +7 -1
  126. package/dist/assets/dashboard/client/assets/index-CmiJKqOU.css +0 -32
  127. package/dist/skills-BOSxYUzf.cjs.map +0 -1
@@ -0,0 +1,426 @@
1
+ <sanity_check>
2
+ Before executing any step in this workflow, verify:
3
+ 1. The current directory contains a `.planning/` folder — if not, stop and tell the user to run `/maxsim:new-project` first.
4
+ 2. `.planning/ROADMAP.md` exists — if not, stop and tell the user to initialize the project.
5
+ </sanity_check>
6
+
7
+ <purpose>
8
+ Execute phase plans sequentially using fresh-context subagents with mandatory 2-stage review between every task. Each task agent receives only the minimum context it needs. Review is a hard gate — no task starts until the previous task passes both review stages.
9
+ </purpose>
10
+
11
+ <core_principle>
12
+ Fresh context per task. No context bleeding between tasks. Review is mandatory, never skippable. Previous task's full diff and conversation are NEVER passed to the next task agent.
13
+ </core_principle>
14
+
15
+ <required_reading>
16
+ Read STATE.md before any operation to load project context.
17
+
18
+ @./references/dashboard-bridge.md
19
+ </required_reading>
20
+
21
+ <process>
22
+
23
+ <step name="initialize" priority="first">
24
+ Reuse the execute-phase init to load phase directory, plans, and model configuration:
25
+
26
+ ```bash
27
+ INIT=$(node ~/.claude/maxsim/bin/maxsim-tools.cjs init execute-phase "${PHASE_ARG}")
28
+ ```
29
+
30
+ Parse JSON for: `executor_model`, `verifier_model`, `commit_docs`, `phase_found`, `phase_dir`, `phase_number`, `phase_name`, `phase_slug`, `plans`, `incomplete_plans`, `plan_count`, `incomplete_count`, `state_exists`, `roadmap_exists`, `phase_req_ids`.
31
+
32
+ **If `phase_found` is false:** Error — phase directory not found.
33
+ **If `plan_count` is 0:** Error — no plans found in phase.
34
+ </step>
35
+
36
+ <step name="discover_plans">
37
+ Find incomplete plans — skip any plan that already has a matching SUMMARY.md:
38
+
39
+ ```bash
40
+ PLAN_INDEX=$(node ~/.claude/maxsim/bin/maxsim-tools.cjs phase-plan-index "${PHASE_NUMBER}")
41
+ ```
42
+
43
+ Parse JSON for: `plans[]` (each with `id`, `objective`, `files_modified`, `task_count`, `has_summary`), `incomplete`.
44
+
45
+ **Filtering:** Skip plans where `has_summary: true`. If all plans complete: "All plans in phase already have summaries" — exit.
46
+
47
+ Report:
48
+ ```
49
+ ## SDD Execution Plan
50
+
51
+ **Phase {X}: {Name}** — {incomplete_count} plans to execute
52
+
53
+ | Plan | Tasks | Objective |
54
+ |------|-------|-----------|
55
+ | 01-01 | 5 | {from plan objective, 5-10 words} |
56
+ | 01-02 | 3 | ... |
57
+
58
+ **Mode:** Spec-Driven Dispatch — fresh agent per task, 2-stage review between tasks
59
+ ```
60
+ </step>
61
+
62
+ <step name="load_plan">
63
+ For each incomplete plan, read the plan file and extract the ordered task list:
64
+
65
+ ```bash
66
+ cat ${PHASE_DIR}/${PLAN_FILE}
67
+ ```
68
+
69
+ Extract for each task:
70
+ - **Task number** (sequential order in plan)
71
+ - **Task name**
72
+ - **Description** (what to implement)
73
+ - **Acceptance criteria** (done criteria from plan)
74
+ - **Relevant files** (files to read and/or modify)
75
+ - **Done criteria** (verification steps)
76
+
77
+ Store as structured task list for the dispatch loop.
78
+ </step>
79
+
80
+ <step name="dispatch_loop">
81
+ For each task in order within the current plan:
82
+
83
+ **4a — Assemble Context**
84
+
85
+ Build minimal context for the task agent. Include ONLY:
86
+ - Task description and acceptance criteria
87
+ - Relevant files list (files to read and modify)
88
+ - Previous task commit hashes and files modified (NOT full diffs, NOT previous agent conversations)
89
+ - Project CLAUDE.md (if exists) for coding conventions
90
+ - .skills/ SKILL.md files (if exist) for relevant project rules
91
+
92
+ Context table (SDD principle):
93
+ | Item | Include? |
94
+ |------|----------|
95
+ | Task description + acceptance criteria | ALWAYS |
96
+ | Relevant files list | ALWAYS |
97
+ | Project CLAUDE.md | ALWAYS (if exists) |
98
+ | Previous task commit hash + files modified | YES (minimal summary only) |
99
+ | Previous task full diff | NEVER |
100
+ | Previous agent conversation | NEVER |
101
+ | Full plan file | NO (only current task extracted) |
102
+
103
+ **4b — Spawn Executor**
104
+
105
+ Fresh `maxsim-executor` agent with minimal context:
106
+
107
+ ```
108
+ Task(
109
+ subagent_type="maxsim-executor",
110
+ model="{executor_model}",
111
+ prompt="
112
+ <objective>
113
+ Execute task {task_number} of plan {plan_id} in phase {phase_number}-{phase_name}.
114
+ Commit atomically when done.
115
+ </objective>
116
+
117
+ <task>
118
+ Name: {task_name}
119
+ Description: {task_description}
120
+ Acceptance criteria: {acceptance_criteria}
121
+ Done criteria: {done_criteria}
122
+ </task>
123
+
124
+ <files_to_read>
125
+ Read these files at execution start using the Read tool:
126
+ - {relevant_files list}
127
+ - ./CLAUDE.md (Project instructions, if exists — follow coding conventions)
128
+ - .skills/ (Project skills, if exists — read SKILL.md for each, follow relevant rules)
129
+ </files_to_read>
130
+
131
+ <previous_task_context>
132
+ {If first task: 'This is the first task in the plan.'}
133
+ {If not first: 'Previous task committed as {commit_hash}. Files modified: {file_list}. Do NOT re-read or re-implement previous work.'}
134
+ </previous_task_context>
135
+
136
+ <commit_protocol>
137
+ After implementation:
138
+ 1. Run tests relevant to changed files
139
+ 2. Stage files individually (NEVER git add . or git add -A)
140
+ 3. Commit: {type}({phase}-{plan}): {description}
141
+ 4. Report: commit hash, files modified, tests run
142
+ </commit_protocol>
143
+
144
+ <success_criteria>
145
+ - [ ] All acceptance criteria met
146
+ - [ ] Done criteria verified
147
+ - [ ] Tests pass
148
+ - [ ] Atomic commit created
149
+ </success_criteria>
150
+ "
151
+ )
152
+ ```
153
+
154
+ Record the commit hash from the executor's output.
155
+
156
+ **4c — Review Stage 1: Spec Compliance**
157
+
158
+ Spawn `maxsim-spec-reviewer` to verify implementation matches task spec:
159
+
160
+ ```
161
+ Task(
162
+ subagent_type="maxsim-spec-reviewer",
163
+ model="{executor_model}",
164
+ prompt="
165
+ <objective>
166
+ Review task {task_number} of plan {plan_id} for spec compliance.
167
+ </objective>
168
+
169
+ <task_spec>
170
+ Name: {task_name}
171
+ Description: {task_description}
172
+ Acceptance criteria: {acceptance_criteria}
173
+ Done criteria: {done_criteria}
174
+ Relevant files: {relevant_files}
175
+ </task_spec>
176
+
177
+ <commit>
178
+ Commit hash: {task_commit_hash}
179
+ </commit>
180
+
181
+ <instructions>
182
+ 1. Read each file in the relevant files list
183
+ 2. Verify every acceptance criterion is met in the implementation
184
+ 3. Verify done criteria pass
185
+ 4. Check that ONLY specified files were modified (run: git diff --name-only {task_commit_hash}^..{task_commit_hash})
186
+ 5. Report verdict: PASS or FAIL
187
+ 6. If FAIL: list each unmet criterion with specific details
188
+ </instructions>
189
+ "
190
+ )
191
+ ```
192
+
193
+ **4d — Review Stage 2: Code Quality**
194
+
195
+ Spawn `maxsim-code-reviewer` to check for bugs, edge cases, and conventions:
196
+
197
+ ```
198
+ Task(
199
+ subagent_type="maxsim-code-reviewer",
200
+ model="{executor_model}",
201
+ prompt="
202
+ <objective>
203
+ Review task {task_number} of plan {plan_id} for code quality.
204
+ Spec compliance already verified.
205
+ </objective>
206
+
207
+ <commit>
208
+ Commit hash: {task_commit_hash}
209
+ Files modified: {files_from_commit}
210
+ </commit>
211
+
212
+ <instructions>
213
+ 1. Read CLAUDE.md for project conventions
214
+ 2. Read each modified file
215
+ 3. Check for: bugs, unhandled edge cases, missing error handling, convention violations, security issues
216
+ 4. Categorize: BLOCKER (must fix) or ADVISORY (note for later)
217
+ 5. Report verdict: PASS (no blockers) or FAIL (list blocking issues)
218
+ </instructions>
219
+ "
220
+ )
221
+ ```
222
+
223
+ **4e — Handle Failure**
224
+
225
+ If EITHER review stage returns FAIL:
226
+
227
+ 1. Spawn a NEW fresh executor agent with:
228
+ - Original task spec (description + acceptance criteria)
229
+ - Review feedback (specific failures from reviewer)
230
+ - Current file state (files to read, NOT previous agent conversation)
231
+ - Instruction: fix ONLY the review issues, do NOT add new features
232
+
233
+ ```
234
+ Task(
235
+ subagent_type="maxsim-executor",
236
+ model="{executor_model}",
237
+ prompt="
238
+ <objective>
239
+ Fix review failures for task {task_number} of plan {plan_id}.
240
+ Fix ONLY the issues listed below. Do NOT add new features or refactor beyond what is required.
241
+ </objective>
242
+
243
+ <original_task>
244
+ Name: {task_name}
245
+ Description: {task_description}
246
+ Acceptance criteria: {acceptance_criteria}
247
+ </original_task>
248
+
249
+ <review_failures>
250
+ {spec_review_failures if any}
251
+ {code_review_failures if any}
252
+ </review_failures>
253
+
254
+ <files_to_read>
255
+ {files modified by previous attempt — read current state}
256
+ </files_to_read>
257
+
258
+ <commit_protocol>
259
+ Stage and commit fixes: fix({phase}-{plan}): address review feedback for task {task_number}
260
+ </commit_protocol>
261
+ "
262
+ )
263
+ ```
264
+
265
+ 2. Re-run BOTH review stages (4c and 4d) on the fix commit
266
+ 3. **Cap at 3 fix attempts.** If still failing after 3 attempts: STOP and escalate to user.
267
+
268
+ ```
269
+ ## TASK BLOCKED — Review Failed After 3 Fix Attempts
270
+
271
+ **Task:** {task_number} - {task_name}
272
+ **Plan:** {plan_id}
273
+ **Phase:** {phase_number} - {phase_name}
274
+
275
+ ### Unresolved Review Failures
276
+ {remaining failures from last review}
277
+
278
+ ### Fix Attempt History
279
+ | Attempt | Spec Review | Code Review | Commit |
280
+ |---------|-------------|-------------|--------|
281
+ | 1 | {PASS/FAIL} | {PASS/FAIL} | {hash} |
282
+ | 2 | {PASS/FAIL} | {PASS/FAIL} | {hash} |
283
+ | 3 | {PASS/FAIL} | {PASS/FAIL} | {hash} |
284
+
285
+ Options:
286
+ - "fix manually" — You fix the issues, then resume
287
+ - "skip task" — Mark incomplete, continue to next task
288
+ - "stop" — Halt SDD execution
289
+ ```
290
+
291
+ **4f — Advance**
292
+
293
+ After both reviews PASS, record task completion:
294
+ - Commit hash
295
+ - Files modified
296
+
297
+ Pass ONLY this minimal summary to the next task context. Do NOT pass:
298
+ - Full diff output
299
+ - Review conversation content
300
+ - Previous agent's reasoning or approach
301
+
302
+ **4g — Report Task**
303
+
304
+ Display task completion:
305
+
306
+ ```
307
+ ---
308
+ ## Task {N}/{total}: {task_name} — COMPLETE
309
+
310
+ **Commit:** {commit_hash}
311
+ **Files:** {files_modified_count} modified
312
+ **Spec Review:** PASS
313
+ **Code Review:** PASS
314
+ {If fix iterations > 0: **Fix Iterations:** {count}}
315
+
316
+ {If more tasks: Dispatching next task...}
317
+ ---
318
+ ```
319
+ </step>
320
+
321
+ <step name="create_summary">
322
+ After all tasks in a plan complete, create SUMMARY.md:
323
+
324
+ ```bash
325
+ # Get the summary template
326
+ cat ~/.claude/maxsim/templates/summary.md
327
+ ```
328
+
329
+ Create `{phase}-{plan}-SUMMARY.md` in the phase directory. Include:
330
+
331
+ **Frontmatter:** phase, plan, subsystem, tags, requires/provides/affects, tech-stack, key-files.created/modified, key-decisions, requirements-completed (copy from PLAN.md frontmatter), duration, completed date.
332
+
333
+ **Body:**
334
+ - One-liner: substantive description of what was built
335
+ - Per-task status table:
336
+
337
+ ```markdown
338
+ ## Task Execution (SDD)
339
+
340
+ | Task | Name | Status | Commit | Fix Iterations |
341
+ |------|------|--------|--------|----------------|
342
+ | 1 | {name} | PASS | {hash} | 0 |
343
+ | 2 | {name} | PASS | {hash} | 1 |
344
+ | 3 | {name} | PASS | {hash} | 0 |
345
+
346
+ **Execution mode:** Spec-Driven Dispatch (fresh agent per task, 2-stage review)
347
+ ```
348
+
349
+ - Review summary per task
350
+ - Deviations (if any)
351
+ - Issues encountered
352
+
353
+ Use `node ~/.claude/maxsim/bin/maxsim-tools.cjs` for template operations as needed.
354
+
355
+ Self-check:
356
+ - Verify first 2 files from `key-files.created` exist on disk
357
+ - Check `git log --oneline --all --grep="{phase}-{plan}"` returns commits
358
+ - Append `## Self-Check: PASSED` or `## Self-Check: FAILED`
359
+ </step>
360
+
361
+ <step name="update_state">
362
+ Standard state updates after plan completion:
363
+
364
+ ```bash
365
+ # Advance plan counter
366
+ node ~/.claude/maxsim/bin/maxsim-tools.cjs state advance-plan
367
+
368
+ # Recalculate progress
369
+ node ~/.claude/maxsim/bin/maxsim-tools.cjs state update-progress
370
+
371
+ # Record execution metrics
372
+ node ~/.claude/maxsim/bin/maxsim-tools.cjs state record-metric \
373
+ --phase "${PHASE}" --plan "${PLAN}" --duration "${DURATION}" \
374
+ --tasks "${TASK_COUNT}" --files "${FILE_COUNT}"
375
+
376
+ # Record session
377
+ node ~/.claude/maxsim/bin/maxsim-tools.cjs state record-session \
378
+ --stopped-at "Completed ${PHASE}-${PLAN}-PLAN.md (SDD)" \
379
+ --resume-file "None"
380
+
381
+ # Update roadmap progress
382
+ node ~/.claude/maxsim/bin/maxsim-tools.cjs roadmap update-plan-progress "${PHASE}"
383
+
384
+ # Mark requirements complete (if plan has requirements field)
385
+ node ~/.claude/maxsim/bin/maxsim-tools.cjs requirements mark-complete ${REQ_IDS}
386
+ ```
387
+ </step>
388
+
389
+ <step name="git_commit_metadata">
390
+ Task code already committed per-task. Commit planning artifacts:
391
+
392
+ ```bash
393
+ node ~/.claude/maxsim/bin/maxsim-tools.cjs commit "docs({phase}-{plan}): complete SDD execution" --files .planning/phases/${PHASE_DIR_NAME}/${PHASE}-${PLAN}-SUMMARY.md .planning/STATE.md .planning/ROADMAP.md .planning/REQUIREMENTS.md
394
+ ```
395
+ </step>
396
+
397
+ <step name="offer_next">
398
+ After all plans in the phase are processed:
399
+
400
+ ```bash
401
+ ls -1 .planning/phases/${PHASE_DIR_NAME}/*-PLAN.md 2>/dev/null | wc -l
402
+ ls -1 .planning/phases/${PHASE_DIR_NAME}/*-SUMMARY.md 2>/dev/null | wc -l
403
+ ```
404
+
405
+ | Condition | Route | Action |
406
+ |-----------|-------|--------|
407
+ | summaries < plans | **A: More plans** | Find next incomplete plan. Show next plan, suggest `/maxsim:sdd {phase}` to continue. |
408
+ | summaries = plans, more phases exist | **B: Phase done** | Show completion, suggest `/maxsim:verify-work {phase}` then `/maxsim:plan-phase {next}`. |
409
+ | summaries = plans, last phase | **C: Milestone done** | Show banner, suggest `/maxsim:complete-milestone` + `/maxsim:verify-work`. |
410
+
411
+ All routes: recommend `/clear` first for fresh context.
412
+ </step>
413
+
414
+ </process>
415
+
416
+ <failure_handling>
417
+ - **Task agent fails (no commit):** Report failure, ask user: retry task or skip
418
+ - **Review agent fails to return verdict:** Treat as FAIL, re-run review
419
+ - **3 fix attempts exhausted:** Hard stop on task, escalate to user with full history
420
+ - **classifyHandoffIfNeeded bug:** If agent reports "failed" with `classifyHandoffIfNeeded is not defined` — Claude Code runtime bug. Spot-check (commit exists, files modified) — if pass, treat as success
421
+ - **All tasks in plan blocked:** Stop plan, report to user, suggest manual intervention
422
+ </failure_handling>
423
+
424
+ <resumption>
425
+ Re-run `/maxsim:sdd {phase}` — discover_plans finds completed SUMMARYs, skips them, resumes from first incomplete plan. Within a plan, completed tasks (those with commits matching the plan pattern) can be detected and skipped.
426
+ </resumption>
@@ -0,0 +1,4 @@
1
+ export type { BackendConfig, BackendStatus, BackendLockFile, WSMessage, BackendServer, PendingQuestion, LifecycleEvent, } from './types.js';
2
+ export { createBackendServer } from './server.js';
3
+ export { startBackend, stopBackend, getBackendStatus, isBackendRunning, findBackendPort, } from './lifecycle.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/backend/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,aAAa,EACb,aAAa,EACb,eAAe,EACf,SAAS,EACT,aAAa,EACb,eAAe,EACf,cAAc,GACf,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EACL,YAAY,EACZ,WAAW,EACX,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,GAChB,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.findBackendPort = exports.isBackendRunning = exports.getBackendStatus = exports.stopBackend = exports.startBackend = exports.createBackendServer = void 0;
4
+ var server_js_1 = require("./server.js");
5
+ Object.defineProperty(exports, "createBackendServer", { enumerable: true, get: function () { return server_js_1.createBackendServer; } });
6
+ var lifecycle_js_1 = require("./lifecycle.js");
7
+ Object.defineProperty(exports, "startBackend", { enumerable: true, get: function () { return lifecycle_js_1.startBackend; } });
8
+ Object.defineProperty(exports, "stopBackend", { enumerable: true, get: function () { return lifecycle_js_1.stopBackend; } });
9
+ Object.defineProperty(exports, "getBackendStatus", { enumerable: true, get: function () { return lifecycle_js_1.getBackendStatus; } });
10
+ Object.defineProperty(exports, "isBackendRunning", { enumerable: true, get: function () { return lifecycle_js_1.isBackendRunning; } });
11
+ Object.defineProperty(exports, "findBackendPort", { enumerable: true, get: function () { return lifecycle_js_1.findBackendPort; } });
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/backend/index.ts"],"names":[],"mappings":";;;AASA,yCAAkD;AAAzC,gHAAA,mBAAmB,OAAA;AAC5B,+CAMwB;AALtB,4GAAA,YAAY,OAAA;AACZ,2GAAA,WAAW,OAAA;AACX,gHAAA,gBAAgB,OAAA;AAChB,gHAAA,gBAAgB,OAAA;AAChB,+GAAA,eAAe,OAAA"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Backend Lifecycle — Start, stop, health check, discovery
3
+ */
4
+ import type { BackendLockFile, BackendStatus } from './types.js';
5
+ export declare function startBackend(projectCwd: string, opts?: {
6
+ port?: number;
7
+ background?: boolean;
8
+ }): Promise<BackendLockFile>;
9
+ export declare function stopBackend(projectCwd: string): Promise<boolean>;
10
+ export declare function getBackendStatus(projectCwd: string): Promise<BackendStatus | null>;
11
+ export declare function isBackendRunning(projectCwd: string): Promise<boolean>;
12
+ export declare function findBackendPort(projectCwd: string): number | null;
13
+ //# sourceMappingURL=lifecycle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lifecycle.d.ts","sourceRoot":"","sources":["../../src/backend/lifecycle.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAgEjE,wBAAsB,YAAY,CAChC,UAAU,EAAE,MAAM,EAClB,IAAI,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE,GAC7C,OAAO,CAAC,eAAe,CAAC,CA6D1B;AAED,wBAAsB,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAoBtE;AAED,wBAAsB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAYxF;AAED,wBAAsB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAG3E;AAED,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGjE"}
@@ -0,0 +1,168 @@
1
+ "use strict";
2
+ /**
3
+ * Backend Lifecycle — Start, stop, health check, discovery
4
+ */
5
+ var __importDefault = (this && this.__importDefault) || function (mod) {
6
+ return (mod && mod.__esModule) ? mod : { "default": mod };
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.startBackend = startBackend;
10
+ exports.stopBackend = stopBackend;
11
+ exports.getBackendStatus = getBackendStatus;
12
+ exports.isBackendRunning = isBackendRunning;
13
+ exports.findBackendPort = findBackendPort;
14
+ const node_fs_1 = __importDefault(require("node:fs"));
15
+ const node_path_1 = __importDefault(require("node:path"));
16
+ const node_child_process_1 = require("node:child_process");
17
+ const LOCK_FILE = '.planning/.backend-lock';
18
+ /**
19
+ * Derive a deterministic port for a project path (range 3100-3199).
20
+ * Simple hash mapped to 100-port range.
21
+ */
22
+ function projectPort(projectCwd) {
23
+ let hash = 0;
24
+ for (const ch of projectCwd) {
25
+ hash = ((hash << 5) - hash + ch.charCodeAt(0)) | 0;
26
+ }
27
+ return 3100 + (Math.abs(hash) % 100);
28
+ }
29
+ function lockFilePath(projectCwd) {
30
+ return node_path_1.default.join(projectCwd, LOCK_FILE);
31
+ }
32
+ function readLockFile(projectCwd) {
33
+ try {
34
+ return JSON.parse(node_fs_1.default.readFileSync(lockFilePath(projectCwd), 'utf-8'));
35
+ }
36
+ catch {
37
+ return null;
38
+ }
39
+ }
40
+ function writeLockFile(projectCwd, data) {
41
+ const lockPath = lockFilePath(projectCwd);
42
+ node_fs_1.default.mkdirSync(node_path_1.default.dirname(lockPath), { recursive: true });
43
+ node_fs_1.default.writeFileSync(lockPath, JSON.stringify(data, null, 2), 'utf-8');
44
+ }
45
+ function removeLockFile(projectCwd) {
46
+ const lockPath = lockFilePath(projectCwd);
47
+ try {
48
+ node_fs_1.default.unlinkSync(lockPath);
49
+ }
50
+ catch {
51
+ // may not exist
52
+ }
53
+ }
54
+ /**
55
+ * Make an HTTP request and return the parsed JSON body.
56
+ * Uses native fetch (Node 22+).
57
+ */
58
+ async function httpJson(method, url, timeoutMs = 5000) {
59
+ try {
60
+ const res = await fetch(url, {
61
+ method,
62
+ signal: AbortSignal.timeout(timeoutMs),
63
+ });
64
+ if (!res.ok)
65
+ return null;
66
+ return await res.json();
67
+ }
68
+ catch {
69
+ return null;
70
+ }
71
+ }
72
+ async function startBackend(projectCwd, opts) {
73
+ // 1. Check if already running
74
+ const existing = await getBackendStatus(projectCwd);
75
+ if (existing && existing.status === 'ok') {
76
+ return readLockFile(projectCwd);
77
+ }
78
+ // 2. Choose port
79
+ const port = opts?.port ?? projectPort(projectCwd);
80
+ const background = opts?.background ?? true;
81
+ if (background) {
82
+ // Spawn detached child process running backend-server.cjs
83
+ const serverScript = node_path_1.default.join(__dirname, 'backend-server.cjs');
84
+ const child = (0, node_child_process_1.spawn)(process.execPath, [serverScript], {
85
+ cwd: projectCwd,
86
+ detached: true,
87
+ stdio: 'ignore',
88
+ env: {
89
+ ...process.env,
90
+ MAXSIM_PORT: String(port),
91
+ MAXSIM_PROJECT_CWD: projectCwd,
92
+ },
93
+ ...(process.platform === 'win32' ? { shell: true } : {}),
94
+ });
95
+ child.unref();
96
+ const lockData = {
97
+ pid: child.pid ?? 0,
98
+ port,
99
+ startedAt: Date.now(),
100
+ cwd: projectCwd,
101
+ };
102
+ writeLockFile(projectCwd, lockData);
103
+ return lockData;
104
+ }
105
+ else {
106
+ // Foreground mode — import and start directly
107
+ const { createBackendServer } = await import('./server.js');
108
+ const server = createBackendServer({
109
+ port,
110
+ host: '127.0.0.1',
111
+ projectCwd,
112
+ enableTerminal: true,
113
+ enableFileWatcher: true,
114
+ enableMcp: true,
115
+ logDir: node_path_1.default.join(projectCwd, '.planning', 'logs'),
116
+ });
117
+ await server.start();
118
+ const lockData = {
119
+ pid: process.pid,
120
+ port: server.getPort(),
121
+ startedAt: Date.now(),
122
+ cwd: projectCwd,
123
+ };
124
+ writeLockFile(projectCwd, lockData);
125
+ return lockData;
126
+ }
127
+ }
128
+ async function stopBackend(projectCwd) {
129
+ const lock = readLockFile(projectCwd);
130
+ if (!lock)
131
+ return false;
132
+ // Try graceful shutdown via HTTP
133
+ const result = await httpJson('POST', `http://127.0.0.1:${lock.port}/api/shutdown`);
134
+ if (result) {
135
+ removeLockFile(projectCwd);
136
+ return true;
137
+ }
138
+ // Fallback: kill by PID
139
+ try {
140
+ process.kill(lock.pid, 'SIGTERM');
141
+ }
142
+ catch {
143
+ // Process may already be dead
144
+ }
145
+ removeLockFile(projectCwd);
146
+ return true;
147
+ }
148
+ async function getBackendStatus(projectCwd) {
149
+ const lock = readLockFile(projectCwd);
150
+ if (!lock)
151
+ return null;
152
+ const data = await httpJson('GET', `http://127.0.0.1:${lock.port}/api/health`);
153
+ if (!data || data.status !== 'ok') {
154
+ // Stale lock file — clean up
155
+ removeLockFile(projectCwd);
156
+ return null;
157
+ }
158
+ return data;
159
+ }
160
+ async function isBackendRunning(projectCwd) {
161
+ const status = await getBackendStatus(projectCwd);
162
+ return status !== null && status.status === 'ok';
163
+ }
164
+ function findBackendPort(projectCwd) {
165
+ const lock = readLockFile(projectCwd);
166
+ return lock ? lock.port : null;
167
+ }
168
+ //# sourceMappingURL=lifecycle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../../src/backend/lifecycle.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * MAXSIM Backend Server — Unified persistent backend service
3
+ *
4
+ * Consolidates HTTP API, WebSocket, MCP endpoint, terminal management,
5
+ * and file watching into a single per-project process.
6
+ *
7
+ * CRITICAL: Never import output() or error() from core — they call process.exit().
8
+ * CRITICAL: Never write to stdout directly — stdout may be reserved for protocol use.
9
+ * All logging must go to stderr via console.error().
10
+ */
11
+ import type { BackendConfig, BackendServer } from './types.js';
12
+ export declare function createBackendServer(config: BackendConfig): BackendServer;
13
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/backend/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAkCH,OAAO,KAAK,EACV,aAAa,EAEb,aAAa,EAEd,MAAM,YAAY,CAAC;AAmYpB,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,aAAa,GAAG,aAAa,CAqsBxE"}