maestro-flow 0.3.12 → 0.3.14

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 (251) hide show
  1. package/.claude/CLAUDE.md +7 -0
  2. package/.claude/agents/workflow-analyzer.md +0 -1
  3. package/.claude/agents/workflow-collab-planner.md +0 -1
  4. package/.claude/agents/workflow-debugger.md +0 -1
  5. package/.claude/agents/workflow-integration-checker.md +2 -2
  6. package/.claude/agents/workflow-nyquist-auditor.md +0 -1
  7. package/.claude/agents/workflow-phase-researcher.md +2 -2
  8. package/.claude/agents/workflow-plan-checker.md +1 -1
  9. package/.claude/agents/workflow-planner.md +1 -2
  10. package/.claude/agents/workflow-roadmapper.md +1 -1
  11. package/.claude/agents/workflow-verifier.md +0 -1
  12. package/.claude/commands/learn-retro.md +2 -2
  13. package/.claude/commands/learn-second-opinion.md +2 -2
  14. package/.claude/commands/maestro-analyze.md +10 -2
  15. package/.claude/commands/maestro-brainstorm.md +1 -1
  16. package/.claude/commands/maestro-execute.md +21 -4
  17. package/.claude/commands/maestro-milestone-complete.md +14 -0
  18. package/.claude/commands/maestro-plan.md +12 -6
  19. package/.claude/commands/maestro-roadmap.md +1 -1
  20. package/.claude/commands/maestro-ui-design.md +7 -7
  21. package/.claude/commands/maestro-update.md +176 -0
  22. package/.claude/commands/maestro-verify.md +18 -3
  23. package/.claude/commands/manage-codebase-rebuild.md +0 -1
  24. package/.claude/commands/manage-harvest.md +1 -1
  25. package/.claude/commands/manage-learn.md +5 -5
  26. package/.claude/commands/manage-memory-capture.md +4 -4
  27. package/.claude/commands/manage-memory.md +1 -1
  28. package/.claude/commands/manage-wiki.md +62 -0
  29. package/.claude/commands/quality-business-test.md +2 -2
  30. package/.claude/commands/quality-debug.md +53 -7
  31. package/.claude/commands/quality-retrospective.md +5 -5
  32. package/.claude/commands/quality-review.md +39 -7
  33. package/.claude/commands/quality-sync.md +1 -1
  34. package/.claude/commands/quality-test-gen.md +1 -1
  35. package/.claude/commands/quality-test.md +45 -12
  36. package/.claude/commands/spec-remove.md +51 -0
  37. package/.claude/commands/spec-setup.md +1 -3
  38. package/.claude/commands/wiki-connect.md +9 -5
  39. package/.claude/commands/wiki-digest.md +6 -3
  40. package/.codex/skills/maestro/SKILL.md +2 -2
  41. package/.codex/skills/maestro-analyze/SKILL.md +4 -4
  42. package/.codex/skills/maestro-brainstorm/SKILL.md +4 -4
  43. package/.codex/skills/maestro-coordinate/SKILL.md +2 -2
  44. package/.codex/skills/maestro-execute/SKILL.md +15 -5
  45. package/.codex/skills/maestro-init/SKILL.md +1 -1
  46. package/.codex/skills/maestro-link-coordinate/SKILL.md +430 -224
  47. package/.codex/skills/maestro-milestone-complete/SKILL.md +18 -1
  48. package/.codex/skills/maestro-plan/SKILL.md +6 -6
  49. package/.codex/skills/maestro-roadmap/SKILL.md +3 -4
  50. package/.codex/skills/maestro-spec-generate/SKILL.md +2 -2
  51. package/.codex/skills/maestro-ui-design/SKILL.md +6 -6
  52. package/.codex/skills/maestro-verify/SKILL.md +20 -11
  53. package/.codex/skills/manage-codebase-rebuild/SKILL.md +4 -4
  54. package/.codex/skills/manage-harvest/SKILL.md +10 -1
  55. package/.codex/skills/manage-issue-discover/SKILL.md +3 -3
  56. package/.codex/skills/manage-learn/SKILL.md +3 -2
  57. package/.codex/skills/manage-memory/SKILL.md +3 -3
  58. package/.codex/skills/manage-memory-capture/SKILL.md +8 -14
  59. package/.codex/skills/manage-status/SKILL.md +9 -4
  60. package/.codex/skills/manage-wiki/SKILL.md +55 -0
  61. package/.codex/skills/quality-business-test/SKILL.md +8 -6
  62. package/.codex/skills/quality-debug/SKILL.md +22 -9
  63. package/.codex/skills/quality-integration-test/SKILL.md +11 -7
  64. package/.codex/skills/quality-retrospective/SKILL.md +45 -26
  65. package/.codex/skills/quality-review/SKILL.md +10 -7
  66. package/.codex/skills/quality-test/SKILL.md +9 -4
  67. package/.codex/skills/quality-test-gen/SKILL.md +13 -9
  68. package/.codex/skills/spec-add/SKILL.md +11 -3
  69. package/.codex/skills/spec-load/SKILL.md +7 -0
  70. package/.codex/skills/spec-map/SKILL.md +2 -2
  71. package/.codex/skills/spec-remove/SKILL.md +101 -0
  72. package/.codex/skills/spec-setup/SKILL.md +4 -8
  73. package/.codex/skills/wiki-connect/SKILL.md +6 -5
  74. package/.codex/skills/wiki-digest/SKILL.md +2 -2
  75. package/chains/milestone-fork-merge.json +6 -6
  76. package/dashboard/dist-server/dashboard/src/server/agents/claude-code-adapter.d.ts +9 -0
  77. package/dashboard/dist-server/dashboard/src/server/agents/claude-code-adapter.js +109 -9
  78. package/dashboard/dist-server/dashboard/src/server/agents/claude-code-adapter.js.map +1 -1
  79. package/dashboard/dist-server/dashboard/src/server/agents/claude-code-adapter.test.js +49 -0
  80. package/dashboard/dist-server/dashboard/src/server/agents/claude-code-adapter.test.js.map +1 -1
  81. package/dashboard/dist-server/dashboard/src/server/routes/index.js +5 -4
  82. package/dashboard/dist-server/dashboard/src/server/routes/index.js.map +1 -1
  83. package/dashboard/dist-server/dashboard/src/server/routes/specs.d.ts +5 -13
  84. package/dashboard/dist-server/dashboard/src/server/routes/specs.js +97 -155
  85. package/dashboard/dist-server/dashboard/src/server/routes/specs.js.map +1 -1
  86. package/dashboard/dist-server/dashboard/src/server/routes/wiki.d.ts +11 -1
  87. package/dashboard/dist-server/dashboard/src/server/routes/wiki.integration.test.js +27 -6
  88. package/dashboard/dist-server/dashboard/src/server/routes/wiki.integration.test.js.map +1 -1
  89. package/dashboard/dist-server/dashboard/src/server/routes/wiki.js +25 -7
  90. package/dashboard/dist-server/dashboard/src/server/routes/wiki.js.map +1 -1
  91. package/dashboard/dist-server/dashboard/src/server/wiki/graph-analysis.js +8 -0
  92. package/dashboard/dist-server/dashboard/src/server/wiki/graph-analysis.js.map +1 -1
  93. package/dashboard/dist-server/dashboard/src/server/wiki/search.js +1 -0
  94. package/dashboard/dist-server/dashboard/src/server/wiki/search.js.map +1 -1
  95. package/dashboard/dist-server/dashboard/src/server/wiki/spec-entry-parser.d.ts +29 -0
  96. package/dashboard/dist-server/dashboard/src/server/wiki/spec-entry-parser.js +148 -0
  97. package/dashboard/dist-server/dashboard/src/server/wiki/spec-entry-parser.js.map +1 -0
  98. package/dashboard/dist-server/dashboard/src/server/wiki/stress.test.js +4 -2
  99. package/dashboard/dist-server/dashboard/src/server/wiki/stress.test.js.map +1 -1
  100. package/dashboard/dist-server/dashboard/src/server/wiki/virtual-wiki-adapters.js +8 -2
  101. package/dashboard/dist-server/dashboard/src/server/wiki/virtual-wiki-adapters.js.map +1 -1
  102. package/dashboard/dist-server/dashboard/src/server/wiki/wiki-indexer.d.ts +5 -0
  103. package/dashboard/dist-server/dashboard/src/server/wiki/wiki-indexer.js +80 -38
  104. package/dashboard/dist-server/dashboard/src/server/wiki/wiki-indexer.js.map +1 -1
  105. package/dashboard/dist-server/dashboard/src/server/wiki/wiki-indexer.test.js +8 -6
  106. package/dashboard/dist-server/dashboard/src/server/wiki/wiki-indexer.test.js.map +1 -1
  107. package/dashboard/dist-server/dashboard/src/server/wiki/wiki-types.d.ts +40 -5
  108. package/dashboard/dist-server/dashboard/src/server/wiki/writer-stress.test.js +21 -23
  109. package/dashboard/dist-server/dashboard/src/server/wiki/writer-stress.test.js.map +1 -1
  110. package/dashboard/dist-server/dashboard/src/server/wiki/writer.d.ts +33 -3
  111. package/dashboard/dist-server/dashboard/src/server/wiki/writer.js +184 -12
  112. package/dashboard/dist-server/dashboard/src/server/wiki/writer.js.map +1 -1
  113. package/dashboard/dist-server/src/commands/delegate.js +26 -0
  114. package/dashboard/dist-server/src/commands/delegate.js.map +1 -1
  115. package/dashboard/dist-server/src/coordinator/graph-types.d.ts +11 -1
  116. package/dashboard/dist-server/src/coordinator/graph-walker.js +29 -2
  117. package/dashboard/dist-server/src/coordinator/graph-walker.js.map +1 -1
  118. package/dashboard/dist-server/src/coordinator/prompt-assembler.js +3 -2
  119. package/dashboard/dist-server/src/coordinator/prompt-assembler.js.map +1 -1
  120. package/dashboard/dist-server/src/hooks/constants.d.ts +29 -60
  121. package/dashboard/dist-server/src/hooks/constants.js +105 -82
  122. package/dashboard/dist-server/src/hooks/constants.js.map +1 -1
  123. package/dashboard/dist-server/src/types/index.d.ts +2 -1
  124. package/dist/src/commands/delegate.d.ts.map +1 -1
  125. package/dist/src/commands/delegate.js +26 -0
  126. package/dist/src/commands/delegate.js.map +1 -1
  127. package/dist/src/commands/hooks.d.ts +2 -4
  128. package/dist/src/commands/hooks.d.ts.map +1 -1
  129. package/dist/src/commands/hooks.js +4 -7
  130. package/dist/src/commands/hooks.js.map +1 -1
  131. package/dist/src/commands/install-ui/InstallConfirm.d.ts +2 -3
  132. package/dist/src/commands/install-ui/InstallConfirm.d.ts.map +1 -1
  133. package/dist/src/commands/install-ui/InstallConfirm.js +1 -1
  134. package/dist/src/commands/install-ui/InstallConfirm.js.map +1 -1
  135. package/dist/src/commands/install-ui/InstallExecution.d.ts.map +1 -1
  136. package/dist/src/commands/install-ui/InstallExecution.js +1 -2
  137. package/dist/src/commands/install-ui/InstallExecution.js.map +1 -1
  138. package/dist/src/commands/install-ui/InstallFlow.d.ts.map +1 -1
  139. package/dist/src/commands/install-ui/InstallFlow.js +5 -7
  140. package/dist/src/commands/install-ui/InstallFlow.js.map +1 -1
  141. package/dist/src/commands/install-ui/StatuslineConfig.d.ts +3 -6
  142. package/dist/src/commands/install-ui/StatuslineConfig.d.ts.map +1 -1
  143. package/dist/src/commands/install-ui/StatuslineConfig.js +21 -17
  144. package/dist/src/commands/install-ui/StatuslineConfig.js.map +1 -1
  145. package/dist/src/commands/update.d.ts.map +1 -1
  146. package/dist/src/commands/update.js +95 -0
  147. package/dist/src/commands/update.js.map +1 -1
  148. package/dist/src/commands/wiki.d.ts.map +1 -1
  149. package/dist/src/commands/wiki.js +75 -11
  150. package/dist/src/commands/wiki.js.map +1 -1
  151. package/dist/src/coordinator/graph-types.d.ts +11 -1
  152. package/dist/src/coordinator/graph-types.d.ts.map +1 -1
  153. package/dist/src/coordinator/graph-walker.d.ts.map +1 -1
  154. package/dist/src/coordinator/graph-walker.js +29 -2
  155. package/dist/src/coordinator/graph-walker.js.map +1 -1
  156. package/dist/src/coordinator/prompt-assembler.d.ts.map +1 -1
  157. package/dist/src/coordinator/prompt-assembler.js +3 -2
  158. package/dist/src/coordinator/prompt-assembler.js.map +1 -1
  159. package/dist/src/hooks/__tests__/statusline-visual-test.d.ts +4 -1
  160. package/dist/src/hooks/__tests__/statusline-visual-test.d.ts.map +1 -1
  161. package/dist/src/hooks/__tests__/statusline-visual-test.js +55 -174
  162. package/dist/src/hooks/__tests__/statusline-visual-test.js.map +1 -1
  163. package/dist/src/hooks/auto-mode.d.ts +18 -0
  164. package/dist/src/hooks/auto-mode.d.ts.map +1 -0
  165. package/dist/src/hooks/auto-mode.js +28 -0
  166. package/dist/src/hooks/auto-mode.js.map +1 -0
  167. package/dist/src/hooks/constants.d.ts +29 -60
  168. package/dist/src/hooks/constants.d.ts.map +1 -1
  169. package/dist/src/hooks/constants.js +105 -82
  170. package/dist/src/hooks/constants.js.map +1 -1
  171. package/dist/src/hooks/context-monitor.d.ts.map +1 -1
  172. package/dist/src/hooks/context-monitor.js +14 -3
  173. package/dist/src/hooks/context-monitor.js.map +1 -1
  174. package/dist/src/hooks/coordinator-tracker.d.ts +1 -0
  175. package/dist/src/hooks/coordinator-tracker.d.ts.map +1 -1
  176. package/dist/src/hooks/coordinator-tracker.js +19 -9
  177. package/dist/src/hooks/coordinator-tracker.js.map +1 -1
  178. package/dist/src/hooks/skill-context.d.ts.map +1 -1
  179. package/dist/src/hooks/skill-context.js +54 -6
  180. package/dist/src/hooks/skill-context.js.map +1 -1
  181. package/dist/src/hooks/statusline.d.ts +11 -8
  182. package/dist/src/hooks/statusline.d.ts.map +1 -1
  183. package/dist/src/hooks/statusline.js +284 -182
  184. package/dist/src/hooks/statusline.js.map +1 -1
  185. package/dist/src/hooks/workspace.d.ts.map +1 -1
  186. package/dist/src/hooks/workspace.js +2 -1
  187. package/dist/src/hooks/workspace.js.map +1 -1
  188. package/dist/src/migrations/_template.d.ts +12 -0
  189. package/dist/src/migrations/_template.d.ts.map +1 -0
  190. package/dist/src/migrations/_template.js +55 -0
  191. package/dist/src/migrations/_template.js.map +1 -0
  192. package/dist/src/migrations/index.d.ts +14 -0
  193. package/dist/src/migrations/index.d.ts.map +1 -0
  194. package/dist/src/migrations/index.js +20 -0
  195. package/dist/src/migrations/index.js.map +1 -0
  196. package/dist/src/migrations/run.d.ts +12 -0
  197. package/dist/src/migrations/run.d.ts.map +1 -0
  198. package/dist/src/migrations/run.js +119 -0
  199. package/dist/src/migrations/run.js.map +1 -0
  200. package/dist/src/migrations/v1-to-v2.d.ts +10 -0
  201. package/dist/src/migrations/v1-to-v2.d.ts.map +1 -0
  202. package/dist/src/migrations/v1-to-v2.js +71 -0
  203. package/dist/src/migrations/v1-to-v2.js.map +1 -0
  204. package/dist/src/tools/team-activity.d.ts.map +1 -1
  205. package/dist/src/tools/team-activity.js +22 -0
  206. package/dist/src/tools/team-activity.js.map +1 -1
  207. package/dist/src/tools/transition-recorder.d.ts +2 -17
  208. package/dist/src/tools/transition-recorder.d.ts.map +1 -1
  209. package/dist/src/tools/transition-recorder.js +6 -3
  210. package/dist/src/tools/transition-recorder.js.map +1 -1
  211. package/dist/src/types/index.d.ts +2 -1
  212. package/dist/src/types/index.d.ts.map +1 -1
  213. package/dist/src/utils/migration-registry.d.ts +65 -0
  214. package/dist/src/utils/migration-registry.d.ts.map +1 -0
  215. package/dist/src/utils/migration-registry.js +117 -0
  216. package/dist/src/utils/migration-registry.js.map +1 -0
  217. package/dist/src/utils/state-schema.d.ts +153 -0
  218. package/dist/src/utils/state-schema.d.ts.map +1 -0
  219. package/dist/src/utils/state-schema.js +329 -0
  220. package/dist/src/utils/state-schema.js.map +1 -0
  221. package/package.json +1 -1
  222. package/templates/state.json +17 -39
  223. package/workflows/brainstorm.md +3 -3
  224. package/workflows/codebase-rebuild.md +2 -12
  225. package/workflows/debug.md +7 -8
  226. package/workflows/execute.md +18 -4
  227. package/workflows/fork.md +37 -86
  228. package/workflows/init.md +1 -4
  229. package/workflows/integration-test.md +4 -5
  230. package/workflows/issue.md +3 -9
  231. package/workflows/learn.md +20 -19
  232. package/workflows/maestro-coordinate.codex.md +9 -9
  233. package/workflows/maestro-coordinate.md +9 -9
  234. package/workflows/maestro.codex.md +8 -1
  235. package/workflows/maestro.md +14 -5
  236. package/workflows/memory.md +26 -71
  237. package/workflows/merge.md +45 -107
  238. package/workflows/milestone-complete.md +24 -7
  239. package/workflows/retrospective.md +77 -109
  240. package/workflows/review.md +5 -12
  241. package/workflows/specs-remove.md +115 -0
  242. package/workflows/specs-setup.md +10 -32
  243. package/workflows/status.md +291 -290
  244. package/workflows/sync.md +5 -5
  245. package/workflows/test.md +4 -5
  246. package/workflows/ui-style.md +3 -4
  247. package/workflows/verify.md +2 -2
  248. package/workflows/wiki-connect.md +188 -0
  249. package/workflows/wiki-digest.md +221 -0
  250. package/workflows/wiki-manage.md +204 -0
  251. package/.codex/skills/maestro-chain/SKILL.md +0 -233
package/workflows/fork.md CHANGED
@@ -121,25 +121,17 @@ IF syncMode:
121
121
  ## Step 5: Validate & Confirm
122
122
 
123
123
  ```
124
- // Load phase status artifact registry first, fallback to legacy phases/
124
+ // Load phase status from artifact registry
125
125
  phaseList = []
126
126
  artifacts = projectState.artifacts ?? []
127
- useArtifactRegistry = artifacts.length > 0
128
-
129
- IF useArtifactRegistry:
130
- // Derive phase status from artifact registry
131
- for (phaseNum of milestonePhases):
132
- execArtifacts = artifacts.filter(a => a.type === 'execute' && a.phase === phaseNum)
133
- status = execArtifacts.some(a => a.status === 'completed') ? 'completed'
134
- : execArtifacts.length > 0 ? 'in_progress'
135
- : 'pending'
136
- phaseList.push({ phase: phaseNum, title: "Phase " + phaseNum, status })
137
- ELSE:
138
- // Legacy: load from phases/ directory
139
- for (phaseNum of milestonePhases):
140
- Glob: .workflow/phases/{NN}-*/index.json where NN matches phaseNum
141
- Read index.json → phaseIndex
142
- phaseList.push(phaseIndex)
127
+
128
+ // Derive phase status from artifact registry
129
+ for (phaseNum of milestonePhases):
130
+ execArtifacts = artifacts.filter(a => a.type === 'execute' && a.phase === phaseNum)
131
+ status = execArtifacts.some(a => a.status === 'completed') ? 'completed'
132
+ : execArtifacts.length > 0 ? 'in_progress'
133
+ : 'pending'
134
+ phaseList.push({ phase: phaseNum, title: "Phase " + phaseNum, status })
143
135
 
144
136
  // Validate: milestone should have at least one non-completed phase
145
137
  nonCompleted = phaseList.filter(p => p.status !== "completed")
@@ -198,63 +190,35 @@ IF directory_exists(".workflow/specs"):
198
190
  // 6e: Copy milestone artifacts to worktree
199
191
  ownedPhaseNumbers = milestonePhases.slice() // all phases in this milestone
200
192
 
201
- IF useArtifactRegistry:
202
- // Copy scratch dirs for this milestone's artifacts
203
- milestoneArtifacts = artifacts.filter(a =>
204
- a.milestone === milestoneName && a.path
205
- )
206
- for (art of milestoneArtifacts):
207
- IF directory_exists(".workflow/" + art.path):
208
- Copy .workflow/{art.path}/ → {wtPath}/.workflow/{art.path}/
209
- ELSE:
210
- // Legacy: copy phase directories
211
- Bash("mkdir -p {wtPath}/.workflow/phases")
212
- for (p of phaseList):
213
- NN = String(p.phase).padStart(2, '0')
214
- Copy .workflow/phases/{NN}-{p.slug}/ → {wtPath}/.workflow/phases/{NN}-{p.slug}/
193
+ // Copy scratch dirs for this milestone's artifacts
194
+ milestoneArtifacts = artifacts.filter(a =>
195
+ a.milestone === milestoneName && a.path
196
+ )
197
+ for (art of milestoneArtifacts):
198
+ IF directory_exists(".workflow/" + art.path):
199
+ Copy .workflow/{art.path}/ {wtPath}/.workflow/{art.path}/
215
200
 
216
201
  // 6f: Copy dependency artifacts (phases outside this milestone)
217
- IF useArtifactRegistry:
218
- // Collect dependency phases from roadmap milestone entry
219
- // (cross-milestone dependencies are defined in milestoneEntry.depends_on or roadmap)
220
- depPhases = new Set()
221
- IF milestoneEntry.depends_on:
222
- for (dep of milestoneEntry.depends_on):
223
- IF NOT ownedPhaseNumbers.includes(dep):
224
- depPhases.add(dep)
225
- // Copy dependency artifacts from main
226
- for (dep of depPhases):
227
- depArtifacts = artifacts.filter(a => a.phase === dep && a.path)
228
- for (art of depArtifacts):
229
- IF directory_exists(".workflow/" + art.path):
230
- Copy .workflow/{art.path}/ → {wtPath}/.workflow/{art.path}/
231
- ELSE:
232
- // Legacy: copy completed dependency phase dirs
233
- allDeps = new Set()
234
- for (p of phaseList):
235
- IF p.depends_on:
236
- for (dep of p.depends_on):
237
- IF NOT ownedPhaseNumbers.includes(dep):
238
- allDeps.add(dep)
239
- for (dep of allDeps):
240
- depNN = String(dep).padStart(2, '0')
241
- Glob: .workflow/phases/{depNN}-*/index.json
242
- Read → depIndex
243
- Copy .workflow/phases/{depNN}-{depIndex.slug}/ → {wtPath}/.workflow/phases/{depNN}-{depIndex.slug}/
202
+ // Collect dependency phases from roadmap milestone entry
203
+ // (cross-milestone dependencies are defined in milestoneEntry.depends_on or roadmap)
204
+ depPhases = new Set()
205
+ IF milestoneEntry.depends_on:
206
+ for (dep of milestoneEntry.depends_on):
207
+ IF NOT ownedPhaseNumbers.includes(dep):
208
+ depPhases.add(dep)
209
+ // Copy dependency artifacts from main
210
+ for (dep of depPhases):
211
+ depArtifacts = artifacts.filter(a => a.phase === dep && a.path)
212
+ for (art of depArtifacts):
213
+ IF directory_exists(".workflow/" + art.path):
214
+ Copy .workflow/{art.path}/ {wtPath}/.workflow/{art.path}/
244
215
 
245
216
  // 6g: Build phase_dependencies map for worktree-scope
246
217
  phaseDeps = {}
247
- IF useArtifactRegistry:
248
- IF milestoneEntry.depends_on:
249
- for (phaseNum of ownedPhaseNumbers):
250
- phaseDeps[String(phaseNum)] = milestoneEntry.depends_on
251
- .filter(d => !ownedPhaseNumbers.includes(d))
252
- ELSE:
253
- for (p of phaseList):
254
- IF p.depends_on:
255
- externalDeps = p.depends_on.filter(d => !ownedPhaseNumbers.includes(d))
256
- IF externalDeps.length > 0:
257
- phaseDeps[String(p.phase)] = externalDeps
218
+ IF milestoneEntry.depends_on:
219
+ for (phaseNum of ownedPhaseNumbers):
220
+ phaseDeps[String(phaseNum)] = milestoneEntry.depends_on
221
+ .filter(d => !ownedPhaseNumbers.includes(d))
258
222
 
259
223
  // 6h: Write worktree-scope.json
260
224
  Write {wtPath}/.workflow/worktree-scope.json:
@@ -275,12 +239,9 @@ Read .workflow/state.json → mainState
275
239
  firstPending = phaseList.find(p => p.status !== "completed")
276
240
  scopedState = {
277
241
  ...mainState,
278
- current_phase: firstPending?.phase ?? phaseList[0].phase,
279
242
  current_milestone: milestoneName,
280
243
  // Carry over milestone-scoped artifacts to worktree
281
- artifacts: useArtifactRegistry
282
- ? artifacts.filter(a => a.milestone === milestoneName || ownedPhaseNumbers.includes(a.phase))
283
- : []
244
+ artifacts: artifacts.filter(a => a.milestone === milestoneName || ownedPhaseNumbers.includes(a.phase))
284
245
  }
285
246
  Write {wtPath}/.workflow/state.json: scopedState
286
247
  ```
@@ -320,19 +281,9 @@ registry.fork_sessions.push({
320
281
  Write .workflow/worktrees.json: registry
321
282
 
322
283
  // Mark milestone phases as "forked"
323
- IF useArtifactRegistry:
324
- // In artifact registry model, worktrees.json tracks forked state.
325
- // No per-phase marking needed the registry entry signals ownership.
326
- // (worktrees.json already updated above with owned_phases)
327
- ELSE:
328
- // Legacy: mark phase index.json as forked
329
- for (p of phaseList):
330
- IF p.status !== "completed":
331
- NN = String(p.phase).padStart(2, '0')
332
- Read .workflow/phases/{NN}-{p.slug}/index.json → idx
333
- idx.status = "forked"
334
- idx.updated_at = getUtc8ISOString()
335
- Write .workflow/phases/{NN}-{p.slug}/index.json: idx
284
+ // In artifact registry model, worktrees.json tracks forked state.
285
+ // No per-phase marking needed the registry entry signals ownership.
286
+ // (worktrees.json already updated above with owned_phases)
336
287
 
337
288
  mainState.last_updated = getUtc8ISOString()
338
289
  Write .workflow/state.json: mainState
package/workflows/init.md CHANGED
@@ -88,7 +88,7 @@ CHECK .workflow/state.json exists?
88
88
 
89
89
  5. **Create project files:**
90
90
  - `.workflow/project.md` from @templates/project.md + user answers (include Core Value, Requirements, Key Decisions)
91
- - `.workflow/state.json` from template (status: "idle", current_phase: null)
91
+ - `.workflow/state.json` from template (status: "idle")
92
92
  - `.workflow/config.json` already created in step 2
93
93
 
94
94
  ### Path B: Brownfield (has code, no .workflow/)
@@ -119,14 +119,12 @@ If `.workflow/specs/` does not exist:
119
119
  1. Create `.workflow/specs/` directory
120
120
  2. Auto-trigger `/workflow:specs-setup` — **MUST follow `specs-setup.md` templates exactly**:
121
121
  - Scan codebase for conventions
122
- - Generate `project-tech.json`
123
122
  - Generate `specs/coding-conventions.md`
124
123
  - Generate `specs/architecture-constraints.md`
125
124
  - Generate `specs/quality-rules.md`
126
125
  - Generate `specs/debug-notes.md`
127
126
  - Generate `specs/test-conventions.md`
128
127
  - Generate `specs/review-standards.md`
129
- - Generate `specs/validation-rules.md`
130
128
  - Create empty `specs/learnings.md`
131
129
 
132
130
 
@@ -143,7 +141,6 @@ Verify all required directories and files exist:
143
141
  config.json ✓
144
142
  specs/ ✓
145
143
  research/ ✓ (if research enabled)
146
- phases/ ✓ (create empty)
147
144
  scratch/ ✓ (create empty)
148
145
  milestones/ ✓ (create empty)
149
146
  codebase/ ✓ (create empty)
@@ -15,7 +15,7 @@ L0-L3 progressive layers: Static Analysis -> Unit -> Integration -> E2E
15
15
  | Input | Result |
16
16
  |-------|--------|
17
17
  | No arguments | Error E001 |
18
- | Phase number | Resolve phase dir (artifact registry or legacy `.workflow/phases/{NN}-{slug}/`) |
18
+ | Phase number | Resolve phase dir from artifact registry |
19
19
  | `--max-iter N` | Set MAX_ITER = N (default 5) |
20
20
  | `--layer L2` | Start from L2 layer |
21
21
 
@@ -23,12 +23,11 @@ L0-L3 progressive layers: Static Analysis -> Unit -> Integration -> E2E
23
23
  ```
24
24
  Read .workflow/state.json → state
25
25
  artifacts = state.artifacts ?? []
26
- IF artifacts.length > 0:
27
- art = artifacts.find(a => a.type === 'execute' && a.phase === phaseNum)
26
+ art = artifacts.find(a => a.type === 'execute' && a.phase === phaseNum)
27
+ IF art:
28
28
  PHASE_DIR = ".workflow/" + art.path
29
29
  ELSE:
30
- Glob: .workflow/phases/{NN}-*/
31
- PHASE_DIR = resolved path
30
+ ERROR "Phase {phaseNum} not found in artifact registry"
32
31
  ```
33
32
 
34
33
  Check for existing integration test session:
@@ -180,11 +180,8 @@ Cross-milestone conflict check (for supplement issues):
180
180
  b. Identify phases belonging to OTHER milestones (not milestone_ref)
181
181
  c. For each other-milestone phase, resolve phase dir and check if plan.json exists:
182
182
  Read .workflow/state.json → state; artifacts = state.artifacts ?? []
183
- IF artifacts.length > 0:
184
- art = artifacts.find(a => a.type === 'plan' && a.phase === phaseNum)
185
- IF art: Read .workflow/{art.path}/plan.json (if exists)
186
- ELSE:
187
- Read .workflow/phases/{NN}-{slug}/plan.json (if exists)
183
+ art = artifacts.find(a => a.type === 'plan' && a.phase === phaseNum)
184
+ IF art: Read .workflow/{art.path}/plan.json (if exists)
188
185
  Collect files_to_create[] as planned_files
189
186
  d. IF affected_components in the new issue overlap with planned_files:
190
187
  WARNING: "Conflict detected: this supplement issue affects components planned in milestone {other_milestone}"
@@ -456,10 +453,7 @@ Process bidirectional link:
456
453
  2. Locate task file:
457
454
  - Read .workflow/state.json → state
458
455
  - artifacts = state.artifacts ?? []
459
- - IF artifacts.length > 0:
460
- Search .workflow/scratch/*/.task/{TASK_ID}.json (artifact registry scratch paths)
461
- ELSE:
462
- Search .workflow/phases/*/.task/{TASK_ID}.json (legacy)
456
+ - Search artifact registry paths: .workflow/{artifact.path}/.task/{TASK_ID}.json
463
457
  - Also search .workflow/scratch/*/.task/{TASK_ID}.json (standalone scratch tasks)
464
458
  - If still not found → error: "Task {TASK_ID} not found"
465
459
 
@@ -4,7 +4,7 @@ Atomic insight capture, search, and retrieval. Lightweight gstack-style "eureka
4
4
 
5
5
  Storage:
6
6
  - `.workflow/learning/lessons.jsonl` — append-only JSONL row per insight (shared with retrospective output)
7
- - `.workflow/learning/learning-index.json` — searchable index (mirrors `memory-index.json` schema)
7
+ - `.workflow/learning/learning-index.json` — searchable index (searchable index)
8
8
 
9
9
  This workflow does NOT spawn agents or call CLI tools. It is a thin file operation: parse → infer → append → confirm.
10
10
 
@@ -83,17 +83,21 @@ phase_slug = null
83
83
 
84
84
  IF .workflow/state.json exists:
85
85
  state = read JSON
86
- IF state.current_phase is not null:
87
- phase = state.current_phase
86
+ artifacts = state.artifacts ?? []
87
+
88
+ # Derive current phase from artifacts (first phase with in_progress, or first without completed execute)
89
+ phase = null
90
+ inProgressArt = artifacts.find(a => a.type === 'execute' && a.status === 'in_progress')
91
+ IF inProgressArt:
92
+ phase = inProgressArt.phase
93
+ ELSE:
94
+ phaseNums = [...new Set(artifacts.map(a => a.phase).filter(Boolean))].sort()
95
+ phase = phaseNums.find(p => !artifacts.some(a => a.phase === p && a.type === 'execute' && a.status === 'completed'))
88
96
 
89
- # Resolve slug artifact registry first, fallback to legacy phases/
90
- artifacts = state.artifacts ?? []
91
- IF artifacts.length > 0:
92
- art = artifacts.find(a => a.phase === phase)
93
- phase_slug = art?.slug ?? "phase-" + phase
94
- ELSE:
95
- Glob ".workflow/phases/{NN}-*/" where NN == phase
96
- phase_slug = matched directory basename (e.g. "01-auth")
97
+ IF phase is not null:
98
+ # Resolve slug from artifact registry
99
+ art = artifacts.find(a => a.phase === phase)
100
+ phase_slug = art?.slug ?? "phase-" + phase
97
101
  ```
98
102
 
99
103
  If `--phase 0` is passed, force `phase = null, phase_slug = null` regardless.
@@ -304,15 +308,12 @@ IF row is null → error E004: "Insight {target_id} not found"
304
308
  ```
305
309
  phase_context = null
306
310
  IF row.phase_slug is not null:
307
- // Resolve phase dir artifact registry first, fallback to legacy phases/
311
+ // Resolve phase dir from artifact registry
308
312
  Read .workflow/state.json → state
309
313
  artifacts = state.artifacts ?? []
310
314
  phase_dir = null
311
- IF artifacts.length > 0:
312
- art = artifacts.find(a => a.phase === row.phase && a.path)
313
- IF art: phase_dir = ".workflow/" + art.path
314
- ELSE:
315
- phase_dir = ".workflow/phases/" + row.phase_slug
315
+ art = artifacts.find(a => a.phase === row.phase && a.path)
316
+ IF art: phase_dir = ".workflow/" + art.path
316
317
 
317
318
  IF phase_dir AND directory exists:
318
319
  phase_context = {
@@ -382,7 +383,7 @@ PHASE CONTEXT:
382
383
  | E002 | error | Unknown `--category` (allowed: pattern, antipattern, decision, tool, gotcha, technique) |
383
384
  | E003 | error | `show` mode requires an INS-id argument |
384
385
  | E004 | error | Insight id not found in lessons.jsonl |
385
- | W001 | warning | Auto-phase detection found a current_phase but no matching directory; phase set to null |
386
+ | W001 | warning | Auto-phase detection found no matching artifact in registry; phase set to null |
386
387
  | W002 | warning | learning-index.json out of sync with lessons.jsonl (different row count); offer to rebuild |
387
388
 
388
389
  ---
@@ -392,7 +393,7 @@ PHASE CONTEXT:
392
393
  - [ ] Mode correctly routed (capture / list / search / show)
393
394
  - [ ] Capture mode: `lessons.jsonl` row appended, valid JSON, all required fields present
394
395
  - [ ] Capture mode: `learning-index.json` updated with matching entry
395
- - [ ] Capture mode: phase auto-link resolves correctly when state.json has current_phase
396
+ - [ ] Capture mode: phase auto-link resolves correctly from artifact registry
396
397
  - [ ] Capture mode: category inference produces a sensible default when --category absent
397
398
  - [ ] List mode: filters apply; output sorted newest-first
398
399
  - [ ] Search mode: results ranked by title > tags > summary match
@@ -22,7 +22,7 @@ const intent = args
22
22
  ```
23
23
 
24
24
  **If resumeMode:**
25
- 1. Find latest `state.json` in `.workflow/.maestro-coordinate/`
25
+ 1. Find latest `status.json` in `.workflow/.maestro-coordinate/`
26
26
  2. Load state → set `current_step` to first non-completed step
27
27
  3. Jump to **Step 6**
28
28
 
@@ -305,11 +305,11 @@ const state = {
305
305
  gemini_session_id: null,
306
306
  step_analyses: [],
307
307
  steps: chain.map((s, i) => ({
308
- index: i, cmd: s.cmd, args: s.args || '',
308
+ index: i, skill: s.cmd, args: s.args || '',
309
309
  status: 'pending', exec_id: null, analysis: null
310
310
  }))
311
311
  };
312
- Write(`${sessionDir}/state.json`, JSON.stringify(state, null, 2));
312
+ Write(`${sessionDir}/status.json`, JSON.stringify(state, null, 2));
313
313
 
314
314
  const context = { resolved_phase: resolvedPhase, user_intent: intent, issue_id: resolvedIssueId, spec_session_id: null };
315
315
  ```
@@ -385,7 +385,7 @@ const prompt = template
385
385
  ```javascript
386
386
  state.steps[state.current_step].status = 'running';
387
387
  state.steps[state.current_step].started_at = new Date().toISOString();
388
- Write(`${sessionDir}/state.json`, JSON.stringify(state, null, 2));
388
+ Write(`${sessionDir}/status.json`, JSON.stringify(state, null, 2));
389
389
 
390
390
  Bash({
391
391
  command: `codex delegate ${escapeForShell(prompt)} --to ${state.tool} --mode write`,
@@ -429,7 +429,7 @@ if (!failed) {
429
429
 
430
430
  // Save output for analysis
431
431
  Write(`${sessionDir}/step-${stepIdx + 1}-output.txt`, output);
432
- Write(`${sessionDir}/state.json`, JSON.stringify(state, null, 2));
432
+ Write(`${sessionDir}/status.json`, JSON.stringify(state, null, 2));
433
433
 
434
434
  // → Step 7b: Gemini analysis (skip if step failed/skipped or single-step chain)
435
435
  if (step.status === 'completed' && state.steps.length > 1) {
@@ -437,7 +437,7 @@ if (step.status === 'completed' && state.steps.length > 1) {
437
437
  } else {
438
438
  // Skip analysis, advance directly
439
439
  state.current_step = stepIdx + 1;
440
- Write(`${sessionDir}/state.json`, JSON.stringify(state, null, 2));
440
+ Write(`${sessionDir}/status.json`, JSON.stringify(state, null, 2));
441
441
  if (state.current_step < state.steps.length) { /* → Step 6 */ }
442
442
  else { /* → Step 8 */ }
443
443
  }
@@ -511,7 +511,7 @@ Write(`${sessionDir}/step-${stepIdx + 1}-analysis.json`, JSON.stringify(analysis
511
511
 
512
512
  // Advance
513
513
  state.current_step = stepIdx + 1;
514
- Write(`${sessionDir}/state.json`, JSON.stringify(state, null, 2));
514
+ Write(`${sessionDir}/status.json`, JSON.stringify(state, null, 2));
515
515
 
516
516
  if (state.current_step < state.steps.length) {
517
517
  // → Back to Step 6
@@ -528,7 +528,7 @@ if (state.current_step < state.steps.length) {
528
528
  const done = state.steps.filter(s => s.status === 'completed').length;
529
529
  state.status = state.steps.some(s => s.status === 'failed') ? 'completed_with_errors' : 'completed';
530
530
  state.completed_at = new Date().toISOString();
531
- Write(`${sessionDir}/state.json`, JSON.stringify(state, null, 2));
531
+ Write(`${sessionDir}/status.json`, JSON.stringify(state, null, 2));
532
532
  ```
533
533
 
534
534
  ```
@@ -560,7 +560,7 @@ Write(`${sessionDir}/state.json`, JSON.stringify(state, null, 2));
560
560
  6. **Quality gates** — issue chains auto-include review; `issue-full` is default for issue execution
561
561
  7. **Tool fallback** — if `codex delegate` fails: retry with same tool once, then try `gemini` → `qwen`
562
562
  8. **Auto-confirm injection** — `{{AUTO_DIRECTIVE}}` in template prevents blocking during background execution
563
- 9. **Resumable** — `-c` reads `state.json`, jumps to first pending step
563
+ 9. **Resumable** — `-c` reads `status.json`, jumps to first pending step
564
564
  10. **Gemini analysis after each step** — evaluate output quality via `codex delegate --to gemini --mode analysis`, chained via `--resume`. Analysis generates `next_step_hints` injected into next step's prompt as `{{ANALYSIS_HINTS}}`
565
565
  11. **Session capture** — after each gemini callback, capture exec_id → `gemini_session_id` for resume chain
566
566
  12. **Analysis skip conditions** — skip gemini analysis for: failed/skipped steps, single-step chains
@@ -20,7 +20,7 @@ const intent = args
20
20
  ```
21
21
 
22
22
  **If resumeMode:**
23
- 1. Find latest `state.json` in `.workflow/.maestro-coordinate/`
23
+ 1. Find latest `status.json` in `.workflow/.maestro-coordinate/`
24
24
  2. Load state → set `current_step` to first non-completed step
25
25
  3. Jump to **Step 6**
26
26
 
@@ -321,11 +321,11 @@ const state = {
321
321
  gemini_session_id: null,
322
322
  step_analyses: [],
323
323
  steps: chain.map((s, i) => ({
324
- index: i, cmd: s.cmd, args: s.args || '',
324
+ index: i, skill: s.cmd, args: s.args || '',
325
325
  status: 'pending', exec_id: null, analysis: null
326
326
  }))
327
327
  };
328
- Write(`${sessionDir}/state.json`, JSON.stringify(state, null, 2));
328
+ Write(`${sessionDir}/status.json`, JSON.stringify(state, null, 2));
329
329
 
330
330
  const context = { resolved_phase: resolvedPhase, user_intent: intent, issue_id: resolvedIssueId, spec_session_id: null };
331
331
  ```
@@ -401,7 +401,7 @@ const prompt = template
401
401
  ```javascript
402
402
  state.steps[state.current_step].status = 'running';
403
403
  state.steps[state.current_step].started_at = new Date().toISOString();
404
- Write(`${sessionDir}/state.json`, JSON.stringify(state, null, 2));
404
+ Write(`${sessionDir}/status.json`, JSON.stringify(state, null, 2));
405
405
 
406
406
  Bash({
407
407
  command: `maestro delegate ${escapeForShell(prompt)} --to ${state.tool} --mode write`,
@@ -445,7 +445,7 @@ if (!failed) {
445
445
 
446
446
  // Save output for analysis
447
447
  Write(`${sessionDir}/step-${stepIdx + 1}-output.txt`, output);
448
- Write(`${sessionDir}/state.json`, JSON.stringify(state, null, 2));
448
+ Write(`${sessionDir}/status.json`, JSON.stringify(state, null, 2));
449
449
 
450
450
  // → Step 7b: Gemini analysis (skip if step failed/skipped or single-step chain)
451
451
  if (step.status === 'completed' && state.steps.length > 1) {
@@ -453,7 +453,7 @@ if (step.status === 'completed' && state.steps.length > 1) {
453
453
  } else {
454
454
  // Skip analysis, advance directly
455
455
  state.current_step = stepIdx + 1;
456
- Write(`${sessionDir}/state.json`, JSON.stringify(state, null, 2));
456
+ Write(`${sessionDir}/status.json`, JSON.stringify(state, null, 2));
457
457
  if (state.current_step < state.steps.length) { /* → Step 6 */ }
458
458
  else { /* → Step 8 */ }
459
459
  }
@@ -527,7 +527,7 @@ Write(`${sessionDir}/step-${stepIdx + 1}-analysis.json`, JSON.stringify(analysis
527
527
 
528
528
  // Advance
529
529
  state.current_step = stepIdx + 1;
530
- Write(`${sessionDir}/state.json`, JSON.stringify(state, null, 2));
530
+ Write(`${sessionDir}/status.json`, JSON.stringify(state, null, 2));
531
531
 
532
532
  if (state.current_step < state.steps.length) {
533
533
  // → Back to Step 6
@@ -544,7 +544,7 @@ if (state.current_step < state.steps.length) {
544
544
  const done = state.steps.filter(s => s.status === 'completed').length;
545
545
  state.status = state.steps.some(s => s.status === 'failed') ? 'completed_with_errors' : 'completed';
546
546
  state.completed_at = new Date().toISOString();
547
- Write(`${sessionDir}/state.json`, JSON.stringify(state, null, 2));
547
+ Write(`${sessionDir}/status.json`, JSON.stringify(state, null, 2));
548
548
  ```
549
549
 
550
550
  ```
@@ -576,7 +576,7 @@ Write(`${sessionDir}/state.json`, JSON.stringify(state, null, 2));
576
576
  6. **Quality gates** — issue chains auto-include review; `issue-full` is default for issue execution
577
577
  7. **Tool fallback** — if `maestro delegate` fails: retry with same tool once, then try `gemini` → `qwen`
578
578
  8. **Auto-confirm injection** — `{{AUTO_DIRECTIVE}}` in template prevents blocking during background execution
579
- 9. **Resumable** — `-c` reads `state.json`, jumps to first pending step
579
+ 9. **Resumable** — `-c` reads `status.json`, jumps to first pending step
580
580
  10. **Gemini analysis after each step** — evaluate output quality via `maestro delegate --to gemini --mode analysis`, chained via `--resume`. Analysis generates `next_step_hints` injected into next step's prompt as `{{ANALYSIS_HINTS}}`
581
581
  11. **Session capture** — after each gemini callback, capture exec_id → `gemini_session_id` for resume chain
582
582
  12. **Analysis skip conditions** — skip gemini analysis for: failed/skipped steps, single-step chains
@@ -37,7 +37,14 @@ if (fileExists(stateFile)) {
37
37
  const raw = JSON.parse(Read(stateFile));
38
38
  projectState = {
39
39
  initialized: true,
40
- current_phase: raw.current_phase,
40
+ // Derive current_phase from artifacts (first in_progress execute, or first without completed execute)
41
+ current_phase: (() => {
42
+ const arts = raw.artifacts ?? [];
43
+ const ip = arts.find(a => a.type === 'execute' && a.status === 'in_progress');
44
+ if (ip) return ip.phase;
45
+ const phases = [...new Set(arts.map(a => a.phase).filter(Boolean))].sort((a,b) => a - b);
46
+ return phases.find(p => !arts.some(a => a.phase === p && a.type === 'execute' && a.status === 'completed')) ?? raw.current_phase ?? null;
47
+ })(),
41
48
  phase_slug: raw.phase_slug,
42
49
  phase_status: raw.phase_status, // pending|exploring|planning|executing|verifying|testing|completed|blocked
43
50
  phase_artifacts: raw.phase_artifacts ?? {},
@@ -661,8 +661,17 @@ function resolvePhase(intent_analysis, project_state) {
661
661
  const phaseMatch = intent.match(/phase\s*(\d+)|^(\d+)$/);
662
662
  if (phaseMatch) return phaseMatch[1] || phaseMatch[2];
663
663
 
664
- // 3. From project state
665
- if (project_state.initialized) return project_state.current_phase;
664
+ // 3. From project state — derive from artifacts
665
+ if (project_state.initialized) {
666
+ // Derive current phase: first phase with in_progress execute, or first without completed execute
667
+ const arts = project_state.artifacts ?? [];
668
+ const inProgress = arts.find(a => a.type === 'execute' && a.status === 'in_progress');
669
+ if (inProgress) return inProgress.phase;
670
+ const phases = [...new Set(arts.map(a => a.phase).filter(Boolean))].sort((a,b) => a - b);
671
+ const current = phases.find(p => !arts.some(a => a.phase === p && a.type === 'execute' && a.status === 'completed'));
672
+ if (current) return current;
673
+ return project_state.latest_artifact?.phase ?? null;
674
+ }
666
675
 
667
676
  // 4. Scratch mode chains use {scratch_dir} instead of {phase}
668
677
  if (chainName === 'analyze-plan-execute') return null;
@@ -751,8 +760,8 @@ mkdir -p "${SESSION_DIR}"
751
760
  "intent": "{original_intent}",
752
761
  "task_type": "{task_type}",
753
762
  "chain_name": "{chain_name}",
754
- "phase": "{resolved_phase}",
755
- "auto_mode": "{autoYes}",
763
+ "phase": {resolved_phase},
764
+ "auto_mode": {autoYes},
756
765
  "steps": [
757
766
  {
758
767
  "index": 0,
@@ -775,7 +784,7 @@ mkdir -p "${SESSION_DIR}"
775
784
  **Initialize execution context:**
776
785
  ```javascript
777
786
  const context = {
778
- current_phase: resolvedPhase,
787
+ current_phase: resolvedPhase, // derived from artifacts
779
788
  user_intent: intent,
780
789
  issue_id: resolvedIssueId,
781
790
  spec_session_id: null,