maestro-flow 0.3.8 → 0.3.9

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 (211) hide show
  1. package/.claude/commands/learn-decompose.md +3 -3
  2. package/.claude/commands/learn-follow.md +5 -5
  3. package/.claude/commands/learn-investigate.md +3 -3
  4. package/.claude/commands/learn-retro.md +6 -6
  5. package/.claude/commands/learn-second-opinion.md +3 -3
  6. package/.claude/commands/maestro-analyze.md +123 -99
  7. package/.claude/commands/maestro-brainstorm.md +2 -2
  8. package/.claude/commands/maestro-execute.md +137 -97
  9. package/.claude/commands/maestro-fork.md +111 -0
  10. package/.claude/commands/maestro-init.md +6 -6
  11. package/.claude/commands/maestro-merge.md +77 -0
  12. package/.claude/commands/maestro-milestone-audit.md +72 -60
  13. package/.claude/commands/maestro-milestone-complete.md +67 -59
  14. package/.claude/commands/maestro-milestone-release.md +6 -6
  15. package/.claude/commands/maestro-plan.md +151 -130
  16. package/.claude/commands/maestro-quick.md +4 -4
  17. package/.claude/commands/maestro-roadmap.md +5 -5
  18. package/.claude/commands/maestro-spec-generate.md +5 -5
  19. package/.claude/commands/maestro-ui-design.md +3 -3
  20. package/.claude/commands/maestro-verify.md +106 -87
  21. package/.claude/commands/maestro.md +10 -4
  22. package/.claude/commands/manage-codebase-rebuild.md +4 -4
  23. package/.claude/commands/manage-codebase-refresh.md +1 -1
  24. package/.claude/commands/manage-harvest.md +5 -5
  25. package/.claude/commands/manage-issue-discover.md +1 -1
  26. package/.claude/commands/manage-issue-execute.md +6 -6
  27. package/.claude/commands/manage-issue.md +6 -6
  28. package/.claude/commands/manage-learn.md +2 -2
  29. package/.claude/commands/manage-memory-capture.md +4 -4
  30. package/.claude/commands/manage-memory.md +2 -2
  31. package/.claude/commands/manage-status.md +24 -24
  32. package/.claude/commands/quality-business-test.md +5 -5
  33. package/.claude/commands/quality-debug.md +4 -4
  34. package/.claude/commands/quality-integration-test.md +4 -4
  35. package/.claude/commands/quality-refactor.md +3 -3
  36. package/.claude/commands/quality-retrospective.md +2 -2
  37. package/.claude/commands/quality-review.md +4 -4
  38. package/.claude/commands/quality-sync.md +3 -3
  39. package/.claude/commands/quality-test-gen.md +4 -4
  40. package/.claude/commands/quality-test.md +9 -9
  41. package/.claude/commands/spec-add.md +2 -2
  42. package/.claude/commands/spec-load.md +1 -1
  43. package/.claude/commands/spec-setup.md +5 -5
  44. package/.claude/commands/wiki-connect.md +3 -3
  45. package/.claude/commands/wiki-digest.md +4 -4
  46. package/.codex/skills/maestro-analyze/SKILL.md +52 -14
  47. package/.codex/skills/maestro-execute/SKILL.md +27 -26
  48. package/.codex/skills/maestro-milestone-audit/SKILL.md +103 -209
  49. package/.codex/skills/maestro-milestone-complete/SKILL.md +149 -158
  50. package/.codex/skills/maestro-plan/SKILL.md +47 -17
  51. package/.codex/skills/maestro-roadmap/SKILL.md +3 -2
  52. package/.codex/skills/team-coordinate/roles/coordinator/commands/monitor.md +2 -2
  53. package/.codex/skills/team-executor/roles/executor/commands/monitor.md +1 -1
  54. package/.codex/skills/team-lifecycle-v4/roles/coordinator/commands/monitor.md +2 -2
  55. package/.codex/skills/team-lifecycle-v4/specs/knowledge-transfer.md +2 -2
  56. package/.codex/skills/team-quality-assurance/roles/coordinator/commands/monitor.md +1 -1
  57. package/.codex/skills/team-review/roles/coordinator/commands/monitor.md +1 -1
  58. package/.codex/skills/team-tech-debt/roles/coordinator/commands/monitor.md +1 -1
  59. package/.codex/skills/team-testing/roles/coordinator/commands/monitor.md +1 -1
  60. package/README.md +19 -14
  61. package/README.zh-CN.md +16 -12
  62. package/bin/maestro-mcp.js +1 -1
  63. package/chains/_intent-map.json +21 -9
  64. package/chains/_router.json +30 -77
  65. package/chains/brainstorm-driven.json +17 -6
  66. package/chains/full-lifecycle.json +22 -23
  67. package/chains/milestone-close.json +20 -7
  68. package/chains/milestone-fork-merge.json +50 -0
  69. package/chains/roadmap-driven.json +17 -6
  70. package/chains/spec-driven.json +17 -6
  71. package/dashboard/dist/assets/{ArtifactsPage-BmPOu8sO.js → ArtifactsPage-DZNCi6tn.js} +12 -7
  72. package/dashboard/dist/assets/ChatInput-Bvr-FeEq.js +49 -0
  73. package/dashboard/dist/assets/ChatPage-D9zTkJZo.js +22 -0
  74. package/dashboard/dist/assets/CollabPage-B4NAHXS2.js +1 -0
  75. package/dashboard/dist/assets/ExecutionPanel-CFt4LJyq.js +1 -0
  76. package/dashboard/dist/assets/KanbanPage-C8USth6H.js +21 -0
  77. package/dashboard/dist/assets/{MarkdownRenderer-BjZ43aSa.js → MarkdownRenderer-X4af_WNb.js} +1 -1
  78. package/dashboard/dist/assets/McpPage-BKfCVIyU.js +21 -0
  79. package/dashboard/dist/assets/OutputPanel-BlBQFJSW.js +1 -0
  80. package/dashboard/dist/assets/ProblemsPanel-De3DLvoI.js +1 -0
  81. package/dashboard/dist/assets/{RequirementBoardPage-B7yRL0s_.js → RequirementBoardPage-Bf1trzqs.js} +2 -2
  82. package/dashboard/dist/assets/{RequirementPage-D8J_-b6O.js → RequirementPage-Bllxe2XI.js} +10 -5
  83. package/dashboard/dist/assets/{SpecsPage-6lO8v8_C.js → SpecsPage-9lwxKT27.js} +2 -2
  84. package/dashboard/dist/assets/{SupervisorPage-Ds5N378a.js → SupervisorPage-SusdfHFq.js} +1 -1
  85. package/dashboard/dist/assets/{TeamsPage-DrkKr17T.js → TeamsPage-DsuM6OwC.js} +2 -2
  86. package/dashboard/dist/assets/TreeBrowser-Q12qobZs.js +6 -0
  87. package/dashboard/dist/assets/WorkflowPage-D_Fzdy3_.js +6 -0
  88. package/dashboard/dist/assets/{arrow-left-CadP5YgU.js → arrow-left-Bqtb2hle.js} +1 -1
  89. package/dashboard/dist/assets/{check-5xufDzS8.js → check-u6fGOwQO.js} +1 -1
  90. package/dashboard/dist/assets/{chevron-right-CYbpR4ev.js → chevron-right-Csu22t58.js} +1 -1
  91. package/dashboard/dist/assets/{circle-Bm-5Q-Yh.js → circle-CMrkbRNg.js} +1 -1
  92. package/dashboard/dist/assets/{circle-alert-BqcYuT7x.js → circle-alert-c3tH1P4z.js} +1 -1
  93. package/dashboard/dist/assets/{circle-check-big-yyzAFysU.js → circle-check-big-TDSeWstm.js} +1 -1
  94. package/dashboard/dist/assets/{circle-check-DEVzW_lm.js → circle-check-gYxxSYuH.js} +1 -1
  95. package/dashboard/dist/assets/{code-BBdC8Wmw.js → code-CFN2uX9V.js} +1 -1
  96. package/dashboard/dist/assets/{columns-3-CQ9Trztr.js → columns-3-38xIDlzy.js} +1 -1
  97. package/dashboard/dist/assets/{download-DayuF-sn.js → download-DC7KkKyP.js} +1 -1
  98. package/dashboard/dist/assets/{folder-CqXeSKeC.js → folder-CWq_lAnf.js} +1 -1
  99. package/dashboard/dist/assets/index-DWG-WrzT.js +231 -0
  100. package/dashboard/dist/assets/{index-Dru5HYy0.js → index-Do71weNR.js} +1 -1
  101. package/dashboard/dist/assets/index-GUNJodSR.css +1 -0
  102. package/dashboard/dist/assets/{list-DBOD6IUt.js → list-CgIP_2A-.js} +1 -1
  103. package/dashboard/dist/assets/{minus-fQI1Syn2.js → minus-DYoN5UGk.js} +1 -1
  104. package/dashboard/dist/assets/{pen-line-Bkbbngl5.js → pen-line-Bh_WKYHm.js} +1 -1
  105. package/dashboard/dist/assets/{proxy-teW12DdZ.js → proxy-BKxDAKTj.js} +1 -1
  106. package/dashboard/dist/assets/{search-Bq3ygFUW.js → search-SieXnOgr.js} +1 -1
  107. package/dashboard/dist/assets/{shallow-22ZN8sFt.js → shallow-Bme1JY57.js} +1 -1
  108. package/dashboard/dist/assets/{table-BEYtdWc4.js → table-llyEtj-7.js} +1 -1
  109. package/dashboard/dist/assets/terminal-BB3Xfuv5.js +6 -0
  110. package/dashboard/dist/assets/{trash-2-DMqGBgcF.js → trash-2-C8f4vFFM.js} +1 -1
  111. package/dashboard/dist/assets/{zap-9DVkGVtt.js → zap-4uwlzVm0.js} +1 -1
  112. package/dashboard/dist/index.html +2 -2
  113. package/dashboard/dist-server/dashboard/src/server/agents/claude-code-adapter.js +8 -4
  114. package/dashboard/dist-server/dashboard/src/server/agents/claude-code-adapter.js.map +1 -1
  115. package/dashboard/dist-server/dashboard/src/server/agents/entry-normalizer.d.ts +1 -0
  116. package/dashboard/dist-server/dashboard/src/server/agents/entry-normalizer.js +2 -1
  117. package/dashboard/dist-server/dashboard/src/server/agents/entry-normalizer.js.map +1 -1
  118. package/dashboard/dist-server/dashboard/src/server/agents/stream-json-adapter.js +20 -10
  119. package/dashboard/dist-server/dashboard/src/server/agents/stream-json-adapter.js.map +1 -1
  120. package/dashboard/dist-server/dashboard/src/server/routes/git.d.ts +2 -0
  121. package/dashboard/dist-server/dashboard/src/server/routes/git.js +79 -0
  122. package/dashboard/dist-server/dashboard/src/server/routes/git.js.map +1 -0
  123. package/dashboard/dist-server/dashboard/src/server/routes/index.js +3 -0
  124. package/dashboard/dist-server/dashboard/src/server/routes/index.js.map +1 -1
  125. package/dashboard/dist-server/dashboard/src/server/routes/workspace.js +43 -0
  126. package/dashboard/dist-server/dashboard/src/server/routes/workspace.js.map +1 -1
  127. package/dashboard/dist-server/dashboard/src/server/state/state-manager.js +43 -3
  128. package/dashboard/dist-server/dashboard/src/server/state/state-manager.js.map +1 -1
  129. package/dashboard/package.json +59 -59
  130. package/dist/src/cli.js +3 -1
  131. package/dist/src/cli.js.map +1 -1
  132. package/dist/src/commands/{team.d.ts → collab.d.ts} +2 -2
  133. package/dist/src/commands/collab.d.ts.map +1 -0
  134. package/dist/src/commands/{team.js → collab.js} +391 -24
  135. package/dist/src/commands/collab.js.map +1 -0
  136. package/dist/src/commands/msg.d.ts.map +1 -1
  137. package/dist/src/commands/msg.js +4 -3
  138. package/dist/src/commands/msg.js.map +1 -1
  139. package/dist/src/hooks/team-monitor.d.ts.map +1 -1
  140. package/dist/src/hooks/team-monitor.js +16 -0
  141. package/dist/src/hooks/team-monitor.js.map +1 -1
  142. package/dist/src/tools/collab-adapter.d.ts +85 -0
  143. package/dist/src/tools/collab-adapter.d.ts.map +1 -0
  144. package/dist/src/tools/collab-adapter.js +320 -0
  145. package/dist/src/tools/collab-adapter.js.map +1 -0
  146. package/dist/src/tools/namespace-guard.d.ts +2 -0
  147. package/dist/src/tools/namespace-guard.d.ts.map +1 -1
  148. package/dist/src/tools/namespace-guard.js +12 -0
  149. package/dist/src/tools/namespace-guard.js.map +1 -1
  150. package/dist/src/tools/phase-gate-evaluator.d.ts +45 -0
  151. package/dist/src/tools/phase-gate-evaluator.d.ts.map +1 -0
  152. package/dist/src/tools/phase-gate-evaluator.js +42 -0
  153. package/dist/src/tools/phase-gate-evaluator.js.map +1 -0
  154. package/dist/src/tools/team-members.d.ts +18 -0
  155. package/dist/src/tools/team-members.d.ts.map +1 -1
  156. package/dist/src/tools/team-members.js +50 -0
  157. package/dist/src/tools/team-members.js.map +1 -1
  158. package/dist/src/tools/team-tasks.d.ts +120 -0
  159. package/dist/src/tools/team-tasks.d.ts.map +1 -0
  160. package/dist/src/tools/team-tasks.js +365 -0
  161. package/dist/src/tools/team-tasks.js.map +1 -0
  162. package/dist/src/tools/transition-recorder.d.ts +3 -0
  163. package/dist/src/tools/transition-recorder.d.ts.map +1 -1
  164. package/dist/src/tools/transition-recorder.js +52 -1
  165. package/dist/src/tools/transition-recorder.js.map +1 -1
  166. package/dist/src/utils/get-version.d.ts.map +1 -1
  167. package/dist/src/utils/get-version.js +15 -4
  168. package/dist/src/utils/get-version.js.map +1 -1
  169. package/package.json +1 -1
  170. package/templates/config.json +7 -0
  171. package/templates/worktree-scope.json +10 -0
  172. package/templates/worktrees.json +27 -0
  173. package/workflows/analyze.md +86 -36
  174. package/workflows/brainstorm.md +17 -37
  175. package/workflows/execute.md +94 -28
  176. package/workflows/fork.md +309 -0
  177. package/workflows/init.md +10 -1
  178. package/workflows/issue.md +66 -7
  179. package/workflows/maestro-coordinate.md +23 -16
  180. package/workflows/maestro.md +52 -35
  181. package/workflows/merge.md +285 -0
  182. package/workflows/milestone-audit.md +89 -70
  183. package/workflows/milestone-complete.md +89 -156
  184. package/workflows/plan.md +122 -17
  185. package/workflows/retrospective.md +3 -3
  186. package/workflows/roadmap.md +11 -3
  187. package/workflows/spec-generate.md +9 -0
  188. package/workflows/status.md +76 -27
  189. package/workflows/ui-design.md +14 -12
  190. package/workflows/verify.md +44 -8
  191. package/.claude/commands/maestro-phase-add.md +0 -63
  192. package/.claude/commands/maestro-phase-transition.md +0 -75
  193. package/.codex/skills/maestro-phase-add/SKILL.md +0 -154
  194. package/.codex/skills/maestro-phase-transition/SKILL.md +0 -173
  195. package/chains/singles/phase-add.json +0 -31
  196. package/chains/singles/phase-transition.json +0 -23
  197. package/dashboard/dist/assets/ChatInput-CL8YDfOU.js +0 -67
  198. package/dashboard/dist/assets/ChatPage-CT-ozBK2.js +0 -8
  199. package/dashboard/dist/assets/CollabPage-C0rWMden.js +0 -1
  200. package/dashboard/dist/assets/KanbanPage-C6WbAlwI.js +0 -16
  201. package/dashboard/dist/assets/McpPage-BPIXADQi.js +0 -16
  202. package/dashboard/dist/assets/TreeBrowser-g_QUKemL.js +0 -11
  203. package/dashboard/dist/assets/WorkflowPage-X8aNkDEr.js +0 -6
  204. package/dashboard/dist/assets/git-branch-SqFf4Ru5.js +0 -6
  205. package/dashboard/dist/assets/index-D2Mtyw7I.css +0 -1
  206. package/dashboard/dist/assets/index-nufWop4p.js +0 -231
  207. package/dashboard/dist/assets/wrench-B84-zdLI.js +0 -11
  208. package/dist/src/commands/team.d.ts.map +0 -1
  209. package/dist/src/commands/team.js.map +0 -1
  210. package/workflows/phase-add.md +0 -252
  211. package/workflows/phase-transition.md +0 -399
package/workflows/plan.md CHANGED
@@ -4,34 +4,61 @@
4
4
 
5
5
  Produces two-layer plan output: `plan.json` (overview with task_ids[] and waves[]) + `.task/TASK-{NNN}.json` (individual task definitions).
6
6
 
7
+ All output goes to `.workflow/scratch/plan-{slug}-{date}/`.
8
+
7
9
  ---
8
10
 
9
11
  ## Prerequisites
10
12
 
11
- - `.workflow/` directory initialized (`/workflow:init` completed)
12
- - Phase directory exists at `.workflow/phases/{NN}-{slug}/` OR `--dir` specifies a scratch directory
13
- - `index.json` present in target directory
13
+ - None for standalone operation (state.json auto-bootstraps)
14
+ - For milestone/phase scope: init + roadmap required
14
15
 
15
16
  ---
16
17
 
17
- ## Phase Resolution
18
+ ## Scope Resolution
18
19
 
19
20
  ```
20
- Input: <phase> argument (number or slug) OR --dir <path>
21
+ Input: [phase] argument OR --dir <path>
22
+
23
+ # Worktree scope check
24
+ IF file_exists(".workflow/worktree-scope.json"):
25
+ scope = read(".workflow/worktree-scope.json")
26
+ IF <phase> is a number AND <phase> NOT IN scope.owned_phases:
27
+ ERROR "Phase {phase} not owned by this worktree. Owned: {scope.owned_phases}"
28
+ EXIT
29
+
30
+ # Auto-bootstrap state.json if missing
31
+ IF NOT file_exists(".workflow/state.json"):
32
+ mkdir -p .workflow/scratch/
33
+ Write minimal state.json: { project: null, status: "active", current_milestone: null,
34
+ current_task_id: null, milestones: [], artifacts: [], last_updated: now() }
21
35
 
22
36
  IF --dir <path> is provided:
23
- 1. Set PHASE_DIR = <path> (absolute or relative to project root)
24
- 2. Validate directory exists and contains index.json
25
- 3. Set SCRATCH_MODE = true (skip roadmap validation, phase transition)
37
+ 1. Set CONTEXT_DIR = <path> (absolute or relative to .workflow/)
38
+ 2. Validate directory exists (context.md or conclusions.json present)
39
+ 3. Determine scope from parent artifact in state.json (if registered), else "standalone"
26
40
  4. Set PHASE_NUM = null, PHASE_SLUG = directory basename
27
41
 
28
- ELSE (standard phase resolution):
29
- 1. If number: find .workflow/phases/{NN}-*/index.json
30
- 2. If slug: find .workflow/phases/*-{slug}/index.json
31
- 3. Validate phase exists and status is not "completed"
32
- 4. Set PHASE_DIR = resolved path
33
- 5. Set PHASE_NUM and PHASE_SLUG from directory name
34
- 6. Set SCRATCH_MODE = false
42
+ ELSE IF no arguments:
43
+ IF state.json.current_milestone AND roadmap.md exists:
44
+ scope = "milestone"
45
+ milestone_slug = slugify(current_milestone name)
46
+ CONTEXT_DIR = find latest analyze artifact for this milestone from state.json.artifacts[]
47
+ ELSE:
48
+ ERROR E001 "No args and no roadmap — provide phase number or create roadmap"
49
+
50
+ ELSE IF argument is a number:
51
+ IF state.json.current_milestone AND roadmap.md exists:
52
+ scope = "phase"
53
+ PHASE_NUM = parsed number
54
+ PHASE_SLUG = resolve from roadmap.md
55
+ CONTEXT_DIR = find latest analyze artifact for this phase from state.json.artifacts[]
56
+ ELSE:
57
+ ERROR "Phase number requires init + roadmap"
58
+
59
+ # Output directory (always scratch)
60
+ OUTPUT_DIR = .workflow/scratch/plan-{PHASE_SLUG or milestone_slug}-{date}/
61
+ mkdir -p {OUTPUT_DIR}/.task/
35
62
  ```
36
63
 
37
64
  ---
@@ -56,8 +83,10 @@ ELSE (standard phase resolution):
56
83
 
57
84
  1. **Load user decisions**
58
85
  ```
59
- Read ${PHASE_DIR}/context.md
60
- -> If missing: warn "No context.md found. Run /maestro-analyze -q first or proceed with defaults."
86
+ IF CONTEXT_DIR exists:
87
+ Read ${CONTEXT_DIR}/context.md
88
+ ELSE:
89
+ warn "No upstream analyze found. Run /maestro-analyze first or proceed with defaults."
61
90
  ```
62
91
 
63
92
  2. **Load spec reference** (if `--spec` flag or index.json has spec_ref)
@@ -415,6 +444,53 @@ Build plan.json with gap-fix tasks
415
444
 
416
445
  ---
417
446
 
447
+ ## P4.5: Collision Detection
448
+
449
+ **Purpose:** Warn if this plan's files overlap with existing plans in the same milestone.
450
+
451
+ **Skip if:** scope == "standalone" (no milestone context to compare against)
452
+
453
+ ```
454
+ // 1. Collect existing plan file sets
455
+ existing_plans = state.json.artifacts
456
+ .filter(a => a.milestone == current_milestone
457
+ && a.type == "plan"
458
+ && a.status == "completed")
459
+
460
+ existing_files = {} // { file_path: [plan_id, ...] }
461
+ FOR each plan IN existing_plans:
462
+ tasks = load_all_tasks(plan.path + "/.task/")
463
+ FOR each task IN tasks:
464
+ FOR each file IN task.files:
465
+ existing_files[file].push(plan.id)
466
+
467
+ // 2. Collect new plan's file set
468
+ new_tasks = load_all_tasks(OUTPUT_DIR + "/.task/")
469
+ new_files = Set()
470
+ FOR each task IN new_tasks:
471
+ FOR each file IN task.files:
472
+ new_files.add(file)
473
+
474
+ // 3. Check intersection
475
+ collisions = []
476
+ FOR each file IN new_files:
477
+ IF file IN existing_files:
478
+ collisions.push({ file, existing_plans: existing_files[file] })
479
+
480
+ // 4. Report (non-blocking)
481
+ IF collisions.length > 0:
482
+ WARN: "碰撞检测发现 {collisions.length} 个文件重叠:"
483
+ FOR each c IN collisions:
484
+ " {c.file} ← 已在 {c.existing_plans.join(', ')} 中规划"
485
+ "建议: 确认是否有意覆盖,或调整 task 范围"
486
+ ELSE:
487
+ "碰撞检测通过: 无文件重叠"
488
+ ```
489
+
490
+ **Note:** Only checks `task.files[]` (write targets). `task.read_first[]` (read-only references) are excluded.
491
+
492
+ ---
493
+
418
494
  ## P5: Confirmation
419
495
 
420
496
  **Purpose:** Present plan to user and determine next action.
@@ -464,6 +540,35 @@ Build plan.json with gap-fix tasks
464
540
  Hand off to /workflow:execute with executionContext in memory
465
541
  ```
466
542
 
543
+ 4. **Register artifact in state.json**
544
+ ```
545
+ Read .workflow/state.json
546
+ // Find upstream analyze artifact
547
+ upstream_analyze = state.json.artifacts
548
+ .filter(a => a.type == "analyze" && a.path == CONTEXT_DIR relative path)
549
+ .last() // most recent
550
+
551
+ next_id = max(artifacts.filter(a => a.type == "plan").map(a => parseInt(a.id.replace("PLN-","")))) + 1
552
+
553
+ artifact = {
554
+ id: "PLN-{next_id padded to 3}",
555
+ type: "plan",
556
+ milestone: state.json.current_milestone,
557
+ phase: PHASE_NUM,
558
+ scope: scope,
559
+ path: OUTPUT_DIR relative to .workflow/,
560
+ status: "completed",
561
+ depends_on: upstream_analyze?.id || null,
562
+ harvested: false,
563
+ created_at: plan_start_time,
564
+ completed_at: now()
565
+ }
566
+
567
+ state.json.artifacts.push(artifact)
568
+ state.json.last_updated = now()
569
+ Write state.json (atomic: write tmp + rename)
570
+ ```
571
+
467
572
  ---
468
573
 
469
574
  ## Error Handling
@@ -667,7 +667,7 @@ Write .workflow/learning/learning-index.json
667
667
 
668
668
  ### Backward-compat append to specs/learnings.md
669
669
 
670
- `phase-transition` Step 5e already writes free-form learnings to `.workflow/specs/learnings.md`. To stay backward-compatible (so phase-transition's reader can still find retrospective output), append a one-line summary per insight:
670
+ Append learnings to `.workflow/specs/learnings.md` (shared with milestone-complete's learning extraction). Append a one-line summary per insight:
671
671
 
672
672
  ```
673
673
  IF .workflow/specs/learnings.md exists:
@@ -679,7 +679,7 @@ IF .workflow/specs/learnings.md exists:
679
679
  Phase: {NN} | Source: retrospective | Insight: {INS_id} | Lens: {lens}
680
680
  ```
681
681
 
682
- If the file does not exist, do not create it (phase-transition owns its lifecycle).
682
+ If the file does not exist, create it with a `## Entries` header.
683
683
 
684
684
  ---
685
685
 
@@ -707,7 +707,7 @@ Next steps (suggested):
707
707
  Skill({ skill: "manage-status" }) — Review project state
708
708
  Skill({ skill: "manage-issue", args: "list --source retrospective" }) — Triage created issues
709
709
  Skill({ skill: "manage-learn", args: "list" }) — Browse the lessons library
710
- Skill({ skill: "maestro-phase-transition" }) Close the phase if not yet transitioned
710
+ Skill({ skill: "maestro-milestone-audit" }) Audit milestone if all phases done
711
711
  ```
712
712
 
713
713
  If `mode == "range"` or `--all`, loop Stages 3–8 per phase, then print an aggregate summary at the end:
@@ -4,6 +4,15 @@ Interactive roadmap creation with iterative refinement. Lightweight path from re
4
4
 
5
5
  ---
6
6
 
7
+ ## Worktree Guard
8
+
9
+ ```
10
+ # Block in worktree
11
+ IF file_exists(".workflow/worktree-scope.json"):
12
+ ERROR "Cannot run maestro-roadmap inside a worktree. Run from the main worktree."
13
+ EXIT
14
+ ```
15
+
7
16
  ## Step 1: Session Initialization
8
17
 
9
18
  ```javascript
@@ -302,10 +311,9 @@ Phase directories use `{NN}-{slug}` format (e.g., `01-auth`, `02-api`).
302
311
 
303
312
  **Requirements traceability**: Cross-check that every Active requirement from project.md maps to exactly one phase. Surface unmapped requirements as gaps.
304
313
 
305
- 2. **Create phase directories**: `.workflow/phases/{NN}-{slug}/` for each phase
306
- - Create empty `index.json` in each
314
+ 2. **Ensure scratch directory**: `mkdir -p .workflow/scratch/`
307
315
 
308
- 3. **Update state.json** (if exists): set `current_phase: 1`
316
+ 3. **Update state.json** (if exists): set milestones from roadmap, set `current_milestone` to first milestone
309
317
 
310
318
  ---
311
319
 
@@ -2,6 +2,15 @@
2
2
 
3
3
  Specification document chain producing a complete specification package (Product Brief, PRD, Architecture, Epics, Roadmap) through 7 sequential phases with multi-CLI analysis and interactive refinement. Pure documentation — no code generation.
4
4
 
5
+ ## Worktree Guard
6
+
7
+ ```
8
+ # Block in worktree
9
+ IF file_exists(".workflow/worktree-scope.json"):
10
+ ERROR "Cannot run maestro-spec-generate inside a worktree. Run from the main worktree."
11
+ EXIT
12
+ ```
13
+
5
14
  ## Pipeline Position
6
15
 
7
16
  ```
@@ -44,43 +44,57 @@ Status dashboard with intelligent routing.
44
44
 
45
45
  ---
46
46
 
47
- ## Step 2: Load Phase Details
47
+ ## Step 2: Build Virtual Phase View from Artifact Registry
48
48
 
49
- For each phase directory in `.workflow/phases/*/`:
49
+ Derive phase progress from `state.json.artifacts[]`:
50
50
 
51
- 1. Read `index.json` if exists:
52
- - Extract: phase number, slug, title, status, goal
53
- - Extract: plan (task_count, tasks_completed), execution progress
54
- - Extract: verification status, validation status, uat status
55
-
56
- 2. Build phase summary array:
57
- ```
58
- phases[] = {
59
- number, slug, title, status,
60
- tasks_total, tasks_completed,
61
- verification_status, validation_status
62
- }
63
- ```
51
+ ```
52
+ // Group artifacts by phase for current milestone
53
+ milestone_artifacts = state.json.artifacts.filter(a => a.milestone == current_milestone)
54
+
55
+ // Build phase view from roadmap + artifact registry
56
+ phases_from_roadmap = parse roadmap.md list of { number, slug, title }
57
+
58
+ FOR each phase IN phases_from_roadmap:
59
+ phase_artifacts = milestone_artifacts.filter(a => a.phase == phase.number)
60
+ has_analyze = phase_artifacts.some(a => a.type == "analyze" && a.status == "completed")
61
+ has_plan = phase_artifacts.some(a => a.type == "plan" && a.status == "completed")
62
+ has_execute = phase_artifacts.some(a => a.type == "execute" && a.status == "completed")
63
+ has_verify = phase_artifacts.some(a => a.type == "verify" && a.status == "completed")
64
+
65
+ // Derive status from artifact chain
66
+ status = has_verify ? "verified" :
67
+ has_execute ? "executed" :
68
+ has_plan ? "planned" :
69
+ has_analyze ? "analyzed" :
70
+ "pending"
71
+
72
+ // Get task counts from plan artifacts
73
+ plan_artifact = phase_artifacts.find(a => a.type == "plan" && a.status == "completed")
74
+ IF plan_artifact:
75
+ plan_json = read .workflow/{plan_artifact.path}/plan.json
76
+ tasks_total = plan_json.task_ids.length
77
+ tasks_completed = count .task/TASK-*.json where status == "completed"
78
+
79
+ phases[] = { number, slug, title, status, tasks_total, tasks_completed, has_verify }
80
+
81
+ // Also show adhoc artifacts
82
+ adhoc_artifacts = milestone_artifacts.filter(a => a.scope == "adhoc")
83
+ ```
64
84
 
65
85
  ---
66
86
 
67
- ## Step 2.5: Roadmap State Consistency Check
68
-
69
- Verify that `roadmap.md` and `state.json` agree on phase structure:
87
+ ## Step 2.5: Artifact Registry Consistency Check
70
88
 
71
89
  ```
72
90
  IF .workflow/roadmap.md exists:
73
91
  roadmap_phases = parse phase headings from roadmap.md (count "### Phase N:" entries)
74
- state_total = state.json.phases_summary.total
75
- actual_dirs = count .workflow/phases/*/ directories
92
+ artifact_phases = unique phase numbers from milestone_artifacts
76
93
 
77
- IF roadmap_phases != state_total OR roadmap_phases != actual_dirs:
78
- Display WARNING:
79
- ⚠️ STATE SYNC WARNING
80
- Roadmap phases: {roadmap_phases}
81
- State total: {state_total}
82
- Phase dirs: {actual_dirs}
83
- Run /maestro-roadmap or /maestro-phase-add to reconcile.
94
+ // Check for unregistered work (artifacts without matching roadmap phases)
95
+ orphan_artifacts = milestone_artifacts.filter(a => a.phase && !roadmap_phases.includes(a.phase))
96
+ IF orphan_artifacts.length > 0:
97
+ Display WARNING: "Artifacts reference phases not in roadmap"
84
98
 
85
99
  ELSE IF NOT .workflow/roadmap.md exists AND state.json.phases_summary.total > 0:
86
100
  Display WARNING:
@@ -175,6 +189,41 @@ Status icons:
175
189
  - `[ ]` pending
176
190
  - `[!]` blocked
177
191
 
192
+ ### Step 4.2: Render Worktree Status
193
+
194
+ ```
195
+ IF file_exists(".workflow/worktree-scope.json"):
196
+ // Running inside a worktree
197
+ Read .workflow/worktree-scope.json → scope
198
+ Display:
199
+ ┌─────────────────────────────────────────┐
200
+ │ WORKTREE MODE │
201
+ ├─────────────────────────────────────────┤
202
+ │ Milestone: {scope.milestone} │
203
+ │ Branch: {scope.branch} │
204
+ │ Phases: {scope.owned_phases} │
205
+ │ Main: {scope.main_worktree} │
206
+ └─────────────────────────────────────────┘
207
+
208
+ ELSE IF file_exists(".workflow/worktrees.json"):
209
+ // Running in main worktree with active worktrees
210
+ Read .workflow/worktrees.json → registry
211
+ activeWorktrees = registry.worktrees.filter(w => w.status === "active")
212
+
213
+ IF activeWorktrees.length > 0:
214
+ Display:
215
+ ┌─────────────────────────────────────────┐
216
+ │ ACTIVE WORKTREES │
217
+ ├─────────────────────────────────────────┤
218
+ {for each wt in activeWorktrees}
219
+ │ {wt.milestone} | {wt.branch} | {wt.path} │
220
+ {/for}
221
+ │ │
222
+ │ Sync: /maestro-fork <milestone> --sync │
223
+ │ Merge: /maestro-merge <milestone> │
224
+ └─────────────────────────────────────────┘
225
+ ```
226
+
178
227
  ---
179
228
 
180
229
  ## Step 5: Route Next Step
@@ -14,28 +14,30 @@ Pipeline position: analyze -> **ui-design** -> plan -> execute -> verify
14
14
 
15
15
  ## Prerequisites
16
16
 
17
- - `.workflow/` directory initialized
18
- - Phase directory exists at `.workflow/phases/{NN}-{slug}/` — OR scratch mode for standalone
17
+ - `.workflow/` directory initialized (or auto-bootstrap)
19
18
  - Python 3 available (required by ui-ux-pro-max skill)
20
19
  - ui-ux-pro-max skill installed (search.py available)
21
20
 
22
21
  ---
23
22
 
24
- ## Phase Resolution
23
+ ## Scope Resolution
25
24
 
26
25
  ```
27
- Input: <phase> argument (number or slug) OR topic text
26
+ Input: <phase> argument (number) OR topic text
28
27
 
29
- IF argument is a number or matches phase pattern:
30
- 1. Find .workflow/phases/{NN}-*/index.json
31
- 2. Set PHASE_DIR = resolved path, SCRATCH_MODE = false
28
+ All output goes to scratch: .workflow/scratch/ui-design-{slug}-{date}/
32
29
 
33
- ELSE (topic text scratch mode):
30
+ IF argument is a number:
31
+ 1. Resolve phase slug from roadmap.md
32
+ 2. OUTPUT_DIR = .workflow/scratch/ui-design-{phase-slug}-{date}
33
+ 3. scope = "phase", register artifact with phase number
34
+
35
+ ELSE (topic text):
34
36
  1. slug = slugify(topic)
35
- 2. PHASE_DIR = .workflow/scratch/ui-design-{slug}-{YYYYMMDD}
36
- 3. mkdir -p ${PHASE_DIR}
37
- 4. Create minimal index.json (type="ui-design", goal=topic)
38
- 5. Set SCRATCH_MODE = true
37
+ 2. OUTPUT_DIR = .workflow/scratch/ui-design-{slug}-{date}
38
+ 3. scope = state.json.current_milestone ? "adhoc" : "standalone"
39
+
40
+ mkdir -p ${OUTPUT_DIR}
39
41
  ```
40
42
 
41
43
  ---
@@ -12,14 +12,50 @@ Dual verification: Goal-Backward structural verification + Nyquist test coverage
12
12
 
13
13
  ---
14
14
 
15
- ## Phase Resolution
16
-
17
- ```
18
- Input: <phase> argument (number or slug)
19
- 1. If number: find .workflow/phases/{NN}-*/index.json
20
- 2. If slug: find .workflow/phases/*-{slug}/index.json
21
- 3. Validate execution has occurred (index.json.execution.tasks_completed > 0)
22
- 4. Set PHASE_DIR = resolved path
15
+ ## Scope Resolution
16
+
17
+ ```
18
+ Input: [phase] argument OR --dir <path>
19
+
20
+ # Worktree scope check
21
+ IF file_exists(".workflow/worktree-scope.json"):
22
+ scope = read(".workflow/worktree-scope.json")
23
+ IF <phase> is a number AND <phase> NOT IN scope.owned_phases:
24
+ ERROR "Phase {phase} not owned by this worktree. Owned: {scope.owned_phases}"
25
+ EXIT
26
+
27
+ IF --dir <path> is provided:
28
+ // Single plan verification
29
+ PLAN_DIRS = [<path>]
30
+ VERIFY_MODE = "single"
31
+ VERIFY_OUTPUT_DIR = <path> // verification.json written into plan dir
32
+
33
+ ELSE IF no arguments:
34
+ // Milestone-level verification
35
+ Read state.json.artifacts
36
+ PLAN_DIRS = artifacts.filter(a =>
37
+ a.milestone == current_milestone &&
38
+ a.type == "execute" &&
39
+ a.status == "completed"
40
+ ).map(a => a.path)
41
+ IF PLAN_DIRS is empty: ERROR E001
42
+ VERIFY_MODE = "milestone"
43
+ milestone_slug = slugify(current_milestone name)
44
+ VERIFY_OUTPUT_DIR = .workflow/scratch/verify-{milestone_slug}-{date}/
45
+ mkdir -p VERIFY_OUTPUT_DIR
46
+
47
+ ELSE IF argument is a number:
48
+ // Phase-level verification
49
+ Read state.json.artifacts
50
+ PLAN_DIRS = artifacts.filter(a =>
51
+ a.milestone == current_milestone &&
52
+ a.type == "execute" &&
53
+ a.phase == arg &&
54
+ a.status == "completed"
55
+ ).map(a => a.path)
56
+ IF PLAN_DIRS is empty: ERROR E001
57
+ VERIFY_MODE = "phase"
58
+ VERIFY_OUTPUT_DIR = first plan dir // single plan → write there
23
59
  ```
24
60
 
25
61
  ---
@@ -1,63 +0,0 @@
1
- ---
2
- name: maestro-phase-add
3
- description: Add or insert a new phase into the project roadmap with automatic renumbering
4
- argument-hint: "<slug> <title> [--after N]"
5
- allowed-tools:
6
- - Read
7
- - Write
8
- - Edit
9
- - Bash
10
- - Glob
11
- - Grep
12
- - Agent
13
- - AskUserQuestion
14
- ---
15
-
16
- <purpose>
17
- Add a new phase to the project roadmap, either appending it at the end or inserting it after a specified phase number. Handles automatic renumbering of subsequent phase directories, updates roadmap.md with the new entry, and initializes the phase directory with an index.json so it is ready for planning.
18
- </purpose>
19
-
20
- <required_reading>
21
- @~/.maestro/workflows/phase-add.md
22
- </required_reading>
23
-
24
- <deferred_reading>
25
- - [index.json](~/.maestro/templates/index.json) — read when creating new phase index
26
- </deferred_reading>
27
-
28
- <context>
29
- $ARGUMENTS -- phase slug and title (required), optional --after N flag.
30
-
31
- **Flags:**
32
- - `--after N` -- Insert after phase N (renumbers subsequent phases). If omitted, appends at end.
33
-
34
- **State files:**
35
- - `.workflow/roadmap.md` -- milestone and phase structure
36
- - `.workflow/state.json` -- project-level state
37
- - `.workflow/phases/` -- existing phase directories
38
- </context>
39
-
40
- <execution>
41
- Follow '~/.maestro/workflows/phase-add.md' completely.
42
-
43
- **Next-step routing on completion:**
44
- - Plan the new phase → Skill({ skill: "maestro-plan", args: "{new_phase_number}" })
45
- - Analyze before planning → Skill({ skill: "maestro-analyze", args: "{new_phase_number}" })
46
- - View updated roadmap → Skill({ skill: "manage-status" })
47
- </execution>
48
-
49
- <error_codes>
50
- | Code | Meaning |
51
- |------|----------------------------------|
52
- | E001 | Phase name/slug required |
53
- | E002 | roadmap.md not found |
54
- | E003 | Duplicate phase name/slug exists |
55
- </error_codes>
56
-
57
- <success_criteria>
58
- - [ ] Phase directory created with NN-slug format
59
- - [ ] roadmap.md updated with new phase entry at correct position
60
- - [ ] index.json initialized in new phase directory with status = "pending"
61
- - [ ] Subsequent phases renumbered correctly (if --after N used)
62
- - [ ] state.json updated if renumbering affected tracked phases
63
- </success_criteria>
@@ -1,75 +0,0 @@
1
- ---
2
- name: maestro-phase-transition
3
- description: Mark current or specified phase as complete, extract learnings, advance to next phase
4
- argument-hint: "[phase-number] [--force]"
5
- allowed-tools:
6
- - Read
7
- - Write
8
- - Edit
9
- - Bash
10
- - Glob
11
- - Grep
12
- - Agent
13
- - AskUserQuestion
14
- ---
15
-
16
- <purpose>
17
- Transition from one phase to the next after verification passes. Validates that the current phase meets all completion criteria (tasks done, verification passed, no unresolved gaps), marks it complete in the phase index, and advances the project state to the next phase. If the next phase directory does not exist, it is created and initialized.
18
- </purpose>
19
-
20
- <required_reading>
21
- @~/.maestro/workflows/phase-transition.md
22
- </required_reading>
23
-
24
- <deferred_reading>
25
- - [state.json](~/.maestro/templates/state.json) — read when updating project state
26
- - [index.json](~/.maestro/templates/index.json) — read when updating phase index
27
- </deferred_reading>
28
-
29
- <context>
30
- $ARGUMENTS -- phase number to transition from (optional, defaults to current_phase from state.json).
31
-
32
- **Flags:**
33
- - `--force` -- Skip gap check and force transition even with warnings
34
-
35
- **State files:**
36
- - `.workflow/state.json` -- project-level state (current_phase, milestones)
37
- - `.workflow/phases/{NN}-{slug}/index.json` -- phase metadata and status
38
- - `.workflow/phases/{NN}-{slug}/verification.json` -- verification results
39
- - `.workflow/phases/{NN}-{slug}/review.json` -- code review results (if exists)
40
- </context>
41
-
42
- <execution>
43
- Follow '~/.maestro/workflows/phase-transition.md' completely.
44
-
45
- **Next-step routing on completion:**
46
- - Next phase exists, ready to plan → Skill({ skill: "maestro-plan", args: "{next_phase}" })
47
- - Next phase needs analysis first → Skill({ skill: "maestro-analyze", args: "{next_phase}" })
48
- - Next phase needs UI design → Skill({ skill: "maestro-ui-design", args: "{next_phase}" })
49
- - All phases in milestone complete → Skill({ skill: "maestro-milestone-audit" })
50
- - View updated dashboard → Skill({ skill: "manage-status" })
51
- </execution>
52
-
53
- <error_codes>
54
- | Code | Meaning |
55
- |------|--------------------------------------------|
56
- | E001 | Phase number required (could not determine) |
57
- | E002 | Phase has not passed verification |
58
- | E003 | Phase has unresolved critical gaps |
59
- | W001 | Phase has warnings but no blockers |
60
- | W002 | UAT test failures exist (quality-test) — review recommended before transition |
61
- | W003 | Code review verdict is BLOCK — Skill({ skill: "quality-review" }) findings should be fixed first |
62
- | W004 | Code review not yet run — Skill({ skill: "quality-review" }) recommended before transition |
63
- | W005 | Orphan specs found in wiki — consider linking or removing before transition |
64
- </error_codes>
65
-
66
- <success_criteria>
67
- - [ ] Current phase index.json marked status = "complete" with completed_at timestamp
68
- - [ ] Next phase directory created (if not already existing)
69
- - [ ] Next phase index.json initialized with status = "pending"
70
- - [ ] state.json current_phase updated to next phase number
71
- - [ ] Wiki health score reported — warnings emitted if orphan specs found
72
- - [ ] Learnings extracted and appended to specs/learnings.md
73
- - [ ] project.md requirements moved Active → Validated for completed phase
74
- - [ ] roadmap.md phase marked as ✅ COMPLETED
75
- </success_criteria>