maestro-flow 0.3.12 → 0.3.13
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.
- package/.claude/CLAUDE.md +7 -0
- package/.claude/agents/workflow-analyzer.md +0 -1
- package/.claude/agents/workflow-collab-planner.md +0 -1
- package/.claude/agents/workflow-debugger.md +0 -1
- package/.claude/agents/workflow-integration-checker.md +2 -2
- package/.claude/agents/workflow-nyquist-auditor.md +0 -1
- package/.claude/agents/workflow-phase-researcher.md +2 -2
- package/.claude/agents/workflow-plan-checker.md +1 -1
- package/.claude/agents/workflow-planner.md +1 -2
- package/.claude/agents/workflow-roadmapper.md +1 -1
- package/.claude/agents/workflow-verifier.md +0 -1
- package/.claude/commands/learn-retro.md +2 -2
- package/.claude/commands/learn-second-opinion.md +2 -2
- package/.claude/commands/maestro-analyze.md +10 -2
- package/.claude/commands/maestro-brainstorm.md +1 -1
- package/.claude/commands/maestro-execute.md +21 -4
- package/.claude/commands/maestro-milestone-complete.md +14 -0
- package/.claude/commands/maestro-plan.md +12 -6
- package/.claude/commands/maestro-roadmap.md +1 -1
- package/.claude/commands/maestro-ui-design.md +7 -7
- package/.claude/commands/maestro-update.md +176 -0
- package/.claude/commands/maestro-verify.md +18 -3
- package/.claude/commands/manage-codebase-rebuild.md +0 -1
- package/.claude/commands/manage-harvest.md +1 -1
- package/.claude/commands/manage-learn.md +5 -5
- package/.claude/commands/manage-memory-capture.md +4 -4
- package/.claude/commands/manage-memory.md +1 -1
- package/.claude/commands/manage-wiki.md +62 -0
- package/.claude/commands/quality-business-test.md +2 -2
- package/.claude/commands/quality-debug.md +53 -7
- package/.claude/commands/quality-retrospective.md +5 -5
- package/.claude/commands/quality-review.md +39 -7
- package/.claude/commands/quality-sync.md +1 -1
- package/.claude/commands/quality-test-gen.md +1 -1
- package/.claude/commands/quality-test.md +45 -12
- package/.claude/commands/spec-remove.md +51 -0
- package/.claude/commands/spec-setup.md +1 -3
- package/.claude/commands/wiki-connect.md +9 -5
- package/.claude/commands/wiki-digest.md +6 -3
- package/.codex/skills/maestro/SKILL.md +2 -2
- package/.codex/skills/maestro-analyze/SKILL.md +4 -4
- package/.codex/skills/maestro-brainstorm/SKILL.md +4 -4
- package/.codex/skills/maestro-coordinate/SKILL.md +2 -2
- package/.codex/skills/maestro-execute/SKILL.md +15 -5
- package/.codex/skills/maestro-init/SKILL.md +1 -1
- package/.codex/skills/maestro-milestone-complete/SKILL.md +18 -1
- package/.codex/skills/maestro-plan/SKILL.md +6 -6
- package/.codex/skills/maestro-roadmap/SKILL.md +3 -4
- package/.codex/skills/maestro-spec-generate/SKILL.md +2 -2
- package/.codex/skills/maestro-ui-design/SKILL.md +6 -6
- package/.codex/skills/maestro-verify/SKILL.md +20 -11
- package/.codex/skills/manage-codebase-rebuild/SKILL.md +4 -4
- package/.codex/skills/manage-harvest/SKILL.md +10 -1
- package/.codex/skills/manage-issue-discover/SKILL.md +3 -3
- package/.codex/skills/manage-learn/SKILL.md +3 -2
- package/.codex/skills/manage-memory/SKILL.md +3 -3
- package/.codex/skills/manage-memory-capture/SKILL.md +8 -14
- package/.codex/skills/manage-status/SKILL.md +9 -4
- package/.codex/skills/manage-wiki/SKILL.md +55 -0
- package/.codex/skills/quality-business-test/SKILL.md +8 -6
- package/.codex/skills/quality-debug/SKILL.md +22 -9
- package/.codex/skills/quality-integration-test/SKILL.md +11 -7
- package/.codex/skills/quality-retrospective/SKILL.md +45 -26
- package/.codex/skills/quality-review/SKILL.md +10 -7
- package/.codex/skills/quality-test/SKILL.md +9 -4
- package/.codex/skills/quality-test-gen/SKILL.md +13 -9
- package/.codex/skills/spec-add/SKILL.md +11 -3
- package/.codex/skills/spec-load/SKILL.md +7 -0
- package/.codex/skills/spec-map/SKILL.md +2 -2
- package/.codex/skills/spec-remove/SKILL.md +101 -0
- package/.codex/skills/spec-setup/SKILL.md +4 -8
- package/.codex/skills/wiki-connect/SKILL.md +6 -5
- package/.codex/skills/wiki-digest/SKILL.md +2 -2
- package/dashboard/dist-server/dashboard/src/server/agents/claude-code-adapter.d.ts +9 -0
- package/dashboard/dist-server/dashboard/src/server/agents/claude-code-adapter.js +109 -9
- package/dashboard/dist-server/dashboard/src/server/agents/claude-code-adapter.js.map +1 -1
- package/dashboard/dist-server/dashboard/src/server/agents/claude-code-adapter.test.js +49 -0
- package/dashboard/dist-server/dashboard/src/server/agents/claude-code-adapter.test.js.map +1 -1
- package/dashboard/dist-server/dashboard/src/server/routes/index.js +5 -4
- package/dashboard/dist-server/dashboard/src/server/routes/index.js.map +1 -1
- package/dashboard/dist-server/dashboard/src/server/routes/specs.d.ts +5 -13
- package/dashboard/dist-server/dashboard/src/server/routes/specs.js +97 -155
- package/dashboard/dist-server/dashboard/src/server/routes/specs.js.map +1 -1
- package/dashboard/dist-server/dashboard/src/server/routes/wiki.d.ts +11 -1
- package/dashboard/dist-server/dashboard/src/server/routes/wiki.integration.test.js +27 -6
- package/dashboard/dist-server/dashboard/src/server/routes/wiki.integration.test.js.map +1 -1
- package/dashboard/dist-server/dashboard/src/server/routes/wiki.js +25 -7
- package/dashboard/dist-server/dashboard/src/server/routes/wiki.js.map +1 -1
- package/dashboard/dist-server/dashboard/src/server/wiki/graph-analysis.js +8 -0
- package/dashboard/dist-server/dashboard/src/server/wiki/graph-analysis.js.map +1 -1
- package/dashboard/dist-server/dashboard/src/server/wiki/search.js +1 -0
- package/dashboard/dist-server/dashboard/src/server/wiki/search.js.map +1 -1
- package/dashboard/dist-server/dashboard/src/server/wiki/spec-entry-parser.d.ts +29 -0
- package/dashboard/dist-server/dashboard/src/server/wiki/spec-entry-parser.js +148 -0
- package/dashboard/dist-server/dashboard/src/server/wiki/spec-entry-parser.js.map +1 -0
- package/dashboard/dist-server/dashboard/src/server/wiki/stress.test.js +4 -2
- package/dashboard/dist-server/dashboard/src/server/wiki/stress.test.js.map +1 -1
- package/dashboard/dist-server/dashboard/src/server/wiki/virtual-wiki-adapters.js +8 -2
- package/dashboard/dist-server/dashboard/src/server/wiki/virtual-wiki-adapters.js.map +1 -1
- package/dashboard/dist-server/dashboard/src/server/wiki/wiki-indexer.d.ts +5 -0
- package/dashboard/dist-server/dashboard/src/server/wiki/wiki-indexer.js +80 -38
- package/dashboard/dist-server/dashboard/src/server/wiki/wiki-indexer.js.map +1 -1
- package/dashboard/dist-server/dashboard/src/server/wiki/wiki-indexer.test.js +8 -6
- package/dashboard/dist-server/dashboard/src/server/wiki/wiki-indexer.test.js.map +1 -1
- package/dashboard/dist-server/dashboard/src/server/wiki/wiki-types.d.ts +40 -5
- package/dashboard/dist-server/dashboard/src/server/wiki/writer-stress.test.js +21 -23
- package/dashboard/dist-server/dashboard/src/server/wiki/writer-stress.test.js.map +1 -1
- package/dashboard/dist-server/dashboard/src/server/wiki/writer.d.ts +33 -3
- package/dashboard/dist-server/dashboard/src/server/wiki/writer.js +184 -12
- package/dashboard/dist-server/dashboard/src/server/wiki/writer.js.map +1 -1
- package/dashboard/dist-server/src/commands/delegate.js +26 -0
- package/dashboard/dist-server/src/commands/delegate.js.map +1 -1
- package/dashboard/dist-server/src/coordinator/graph-types.d.ts +11 -1
- package/dashboard/dist-server/src/coordinator/graph-walker.js +29 -2
- package/dashboard/dist-server/src/coordinator/graph-walker.js.map +1 -1
- package/dashboard/dist-server/src/coordinator/prompt-assembler.js +3 -2
- package/dashboard/dist-server/src/coordinator/prompt-assembler.js.map +1 -1
- package/dashboard/dist-server/src/hooks/constants.d.ts +29 -60
- package/dashboard/dist-server/src/hooks/constants.js +105 -82
- package/dashboard/dist-server/src/hooks/constants.js.map +1 -1
- package/dashboard/dist-server/src/types/index.d.ts +2 -1
- package/dist/src/commands/delegate.d.ts.map +1 -1
- package/dist/src/commands/delegate.js +26 -0
- package/dist/src/commands/delegate.js.map +1 -1
- package/dist/src/commands/hooks.d.ts +2 -4
- package/dist/src/commands/hooks.d.ts.map +1 -1
- package/dist/src/commands/hooks.js +4 -7
- package/dist/src/commands/hooks.js.map +1 -1
- package/dist/src/commands/install-ui/InstallConfirm.d.ts +2 -3
- package/dist/src/commands/install-ui/InstallConfirm.d.ts.map +1 -1
- package/dist/src/commands/install-ui/InstallConfirm.js +1 -1
- package/dist/src/commands/install-ui/InstallConfirm.js.map +1 -1
- package/dist/src/commands/install-ui/InstallExecution.d.ts.map +1 -1
- package/dist/src/commands/install-ui/InstallExecution.js +1 -2
- package/dist/src/commands/install-ui/InstallExecution.js.map +1 -1
- package/dist/src/commands/install-ui/InstallFlow.d.ts.map +1 -1
- package/dist/src/commands/install-ui/InstallFlow.js +5 -7
- package/dist/src/commands/install-ui/InstallFlow.js.map +1 -1
- package/dist/src/commands/install-ui/StatuslineConfig.d.ts +3 -6
- package/dist/src/commands/install-ui/StatuslineConfig.d.ts.map +1 -1
- package/dist/src/commands/install-ui/StatuslineConfig.js +21 -17
- package/dist/src/commands/install-ui/StatuslineConfig.js.map +1 -1
- package/dist/src/commands/update.d.ts.map +1 -1
- package/dist/src/commands/update.js +95 -0
- package/dist/src/commands/update.js.map +1 -1
- package/dist/src/commands/wiki.d.ts.map +1 -1
- package/dist/src/commands/wiki.js +75 -11
- package/dist/src/commands/wiki.js.map +1 -1
- package/dist/src/coordinator/graph-types.d.ts +11 -1
- package/dist/src/coordinator/graph-types.d.ts.map +1 -1
- package/dist/src/coordinator/graph-walker.d.ts.map +1 -1
- package/dist/src/coordinator/graph-walker.js +29 -2
- package/dist/src/coordinator/graph-walker.js.map +1 -1
- package/dist/src/coordinator/prompt-assembler.d.ts.map +1 -1
- package/dist/src/coordinator/prompt-assembler.js +3 -2
- package/dist/src/coordinator/prompt-assembler.js.map +1 -1
- package/dist/src/hooks/__tests__/statusline-visual-test.d.ts +4 -1
- package/dist/src/hooks/__tests__/statusline-visual-test.d.ts.map +1 -1
- package/dist/src/hooks/__tests__/statusline-visual-test.js +55 -174
- package/dist/src/hooks/__tests__/statusline-visual-test.js.map +1 -1
- package/dist/src/hooks/constants.d.ts +29 -60
- package/dist/src/hooks/constants.d.ts.map +1 -1
- package/dist/src/hooks/constants.js +105 -82
- package/dist/src/hooks/constants.js.map +1 -1
- package/dist/src/hooks/skill-context.d.ts.map +1 -1
- package/dist/src/hooks/skill-context.js +54 -6
- package/dist/src/hooks/skill-context.js.map +1 -1
- package/dist/src/hooks/statusline.d.ts +11 -8
- package/dist/src/hooks/statusline.d.ts.map +1 -1
- package/dist/src/hooks/statusline.js +284 -182
- package/dist/src/hooks/statusline.js.map +1 -1
- package/dist/src/hooks/workspace.d.ts.map +1 -1
- package/dist/src/hooks/workspace.js +2 -1
- package/dist/src/hooks/workspace.js.map +1 -1
- package/dist/src/migrations/_template.d.ts +12 -0
- package/dist/src/migrations/_template.d.ts.map +1 -0
- package/dist/src/migrations/_template.js +55 -0
- package/dist/src/migrations/_template.js.map +1 -0
- package/dist/src/migrations/index.d.ts +14 -0
- package/dist/src/migrations/index.d.ts.map +1 -0
- package/dist/src/migrations/index.js +20 -0
- package/dist/src/migrations/index.js.map +1 -0
- package/dist/src/migrations/run.d.ts +12 -0
- package/dist/src/migrations/run.d.ts.map +1 -0
- package/dist/src/migrations/run.js +119 -0
- package/dist/src/migrations/run.js.map +1 -0
- package/dist/src/migrations/v1-to-v2.d.ts +10 -0
- package/dist/src/migrations/v1-to-v2.d.ts.map +1 -0
- package/dist/src/migrations/v1-to-v2.js +71 -0
- package/dist/src/migrations/v1-to-v2.js.map +1 -0
- package/dist/src/tools/team-activity.d.ts.map +1 -1
- package/dist/src/tools/team-activity.js +22 -0
- package/dist/src/tools/team-activity.js.map +1 -1
- package/dist/src/tools/transition-recorder.d.ts +2 -17
- package/dist/src/tools/transition-recorder.d.ts.map +1 -1
- package/dist/src/tools/transition-recorder.js +6 -3
- package/dist/src/tools/transition-recorder.js.map +1 -1
- package/dist/src/types/index.d.ts +2 -1
- package/dist/src/types/index.d.ts.map +1 -1
- package/dist/src/utils/migration-registry.d.ts +65 -0
- package/dist/src/utils/migration-registry.d.ts.map +1 -0
- package/dist/src/utils/migration-registry.js +117 -0
- package/dist/src/utils/migration-registry.js.map +1 -0
- package/dist/src/utils/state-schema.d.ts +153 -0
- package/dist/src/utils/state-schema.d.ts.map +1 -0
- package/dist/src/utils/state-schema.js +329 -0
- package/dist/src/utils/state-schema.js.map +1 -0
- package/package.json +1 -1
- package/templates/state.json +17 -39
- package/workflows/brainstorm.md +3 -3
- package/workflows/codebase-rebuild.md +2 -12
- package/workflows/debug.md +7 -8
- package/workflows/execute.md +18 -4
- package/workflows/fork.md +37 -86
- package/workflows/init.md +1 -4
- package/workflows/integration-test.md +4 -5
- package/workflows/issue.md +3 -9
- package/workflows/learn.md +20 -19
- package/workflows/maestro.codex.md +8 -1
- package/workflows/maestro.md +12 -3
- package/workflows/memory.md +26 -71
- package/workflows/merge.md +45 -107
- package/workflows/milestone-complete.md +24 -7
- package/workflows/retrospective.md +77 -109
- package/workflows/review.md +5 -12
- package/workflows/specs-remove.md +115 -0
- package/workflows/specs-setup.md +10 -32
- package/workflows/status.md +291 -290
- package/workflows/sync.md +5 -5
- package/workflows/test.md +4 -5
- package/workflows/ui-style.md +3 -4
- package/workflows/verify.md +2 -2
- package/workflows/wiki-connect.md +188 -0
- package/workflows/wiki-digest.md +221 -0
- package/workflows/wiki-manage.md +204 -0
package/workflows/merge.md
CHANGED
|
@@ -106,28 +106,15 @@ incompletePhases = []
|
|
|
106
106
|
// Read worktree state for artifact registry check
|
|
107
107
|
Read {target.path}/.workflow/state.json → wtState (if exists)
|
|
108
108
|
wtArtifacts = wtState?.artifacts ?? []
|
|
109
|
-
useArtifactRegistry = wtArtifacts.length > 0
|
|
110
|
-
|
|
111
|
-
IF useArtifactRegistry:
|
|
112
|
-
// Check phase completeness via artifact registry
|
|
113
|
-
for (phaseNum of target.owned_phases):
|
|
114
|
-
execArtifacts = wtArtifacts.filter(a => a.type === 'execute' && a.phase === phaseNum)
|
|
115
|
-
IF execArtifacts.some(a => a.status === 'completed'):
|
|
116
|
-
completedPhases.push({ phase: phaseNum })
|
|
117
|
-
ELSE:
|
|
118
|
-
status = execArtifacts.length > 0 ? execArtifacts[0].status : 'no_execute_artifact'
|
|
119
|
-
incompletePhases.push({ phase: phaseNum, status })
|
|
120
|
-
ELSE:
|
|
121
|
-
// Legacy: check phases/ directory
|
|
122
|
-
for (phaseNum of target.owned_phases):
|
|
123
|
-
NN = String(phaseNum).padStart(2, '0')
|
|
124
|
-
Glob: {target.path}/.workflow/phases/{NN}-*/index.json
|
|
125
|
-
Read → wtIndex
|
|
126
109
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
110
|
+
// Check phase completeness via artifact registry
|
|
111
|
+
for (phaseNum of target.owned_phases):
|
|
112
|
+
execArtifacts = wtArtifacts.filter(a => a.type === 'execute' && a.phase === phaseNum)
|
|
113
|
+
IF execArtifacts.some(a => a.status === 'completed'):
|
|
114
|
+
completedPhases.push({ phase: phaseNum })
|
|
115
|
+
ELSE:
|
|
116
|
+
status = execArtifacts.length > 0 ? execArtifacts[0].status : 'no_execute_artifact'
|
|
117
|
+
incompletePhases.push({ phase: phaseNum, status })
|
|
131
118
|
|
|
132
119
|
IF incompletePhases.length > 0 AND NOT force:
|
|
133
120
|
WARN W002: "M{target.milestone_num} ({target.milestone}) has incomplete phases:"
|
|
@@ -199,88 +186,42 @@ Display "Syncing workflow artifacts for M{target.milestone_num} ({target.milesto
|
|
|
199
186
|
|
|
200
187
|
Read .workflow/state.json → mainState
|
|
201
188
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
ELSE:
|
|
239
|
-
// Legacy: copy phase directories from worktree to main
|
|
240
|
-
// 7a: Copy all owned phase directories
|
|
241
|
-
for (phaseNum of target.owned_phases):
|
|
242
|
-
NN = String(phaseNum).padStart(2, '0')
|
|
243
|
-
Glob: {target.path}/.workflow/phases/{NN}-*/
|
|
244
|
-
phaseDir = matched directory name
|
|
245
|
-
|
|
246
|
-
srcDir = target.path + "/.workflow/phases/" + phaseDir + "/"
|
|
247
|
-
dstDir = ".workflow/phases/" + phaseDir + "/"
|
|
248
|
-
|
|
249
|
-
Bash("cp -r {srcDir}* {dstDir}")
|
|
250
|
-
|
|
251
|
-
// 7b: Update phase summaries
|
|
252
|
-
for (phaseNum of target.owned_phases):
|
|
253
|
-
NN = String(phaseNum).padStart(2, '0')
|
|
254
|
-
Glob: .workflow/phases/{NN}-*/index.json
|
|
255
|
-
Read → phaseIndex
|
|
256
|
-
|
|
257
|
-
IF phaseIndex.status === "completed":
|
|
258
|
-
mainState.phases_summary.completed += 1
|
|
259
|
-
mainState.phases_summary.pending -= 1
|
|
260
|
-
IF mainState.phases_summary.pending < 0:
|
|
261
|
-
mainState.phases_summary.pending = 0
|
|
262
|
-
|
|
263
|
-
mainState.transition_history = mainState.transition_history ?? []
|
|
264
|
-
mainState.transition_history.push({
|
|
265
|
-
milestone_num: target.milestone_num,
|
|
266
|
-
milestone: target.milestone,
|
|
267
|
-
phase: phaseNum,
|
|
268
|
-
action: "worktree_merge",
|
|
269
|
-
completed_at: phaseIndex.completed_at ?? getUtc8ISOString(),
|
|
270
|
-
branch: target.branch
|
|
271
|
-
})
|
|
272
|
-
ELSE IF phaseIndex.status !== "forked":
|
|
273
|
-
mainState.phases_summary.in_progress += 1
|
|
274
|
-
mainState.phases_summary.pending -= 1
|
|
275
|
-
IF mainState.phases_summary.pending < 0:
|
|
276
|
-
mainState.phases_summary.pending = 0
|
|
277
|
-
|
|
278
|
-
phaseIndex.updated_at = getUtc8ISOString()
|
|
279
|
-
Write .workflow/phases/{NN}-{slug}/index.json: phaseIndex
|
|
280
|
-
|
|
281
|
-
// Merge accumulated context from worktree (both paths)
|
|
282
|
-
IF NOT useArtifactRegistry:
|
|
283
|
-
Read target.path + "/.workflow/state.json" → wtState (if exists)
|
|
189
|
+
// 7a: Copy scratch dirs from worktree to main
|
|
190
|
+
Read {target.path}/.workflow/state.json → wtState
|
|
191
|
+
wtArtifacts = wtState?.artifacts ?? []
|
|
192
|
+
milestoneArtifacts = wtArtifacts.filter(a =>
|
|
193
|
+
a.path && (a.milestone === target.milestone || target.owned_phases.includes(a.phase))
|
|
194
|
+
)
|
|
195
|
+
for (art of milestoneArtifacts):
|
|
196
|
+
srcDir = target.path + "/.workflow/" + art.path
|
|
197
|
+
dstDir = ".workflow/" + art.path
|
|
198
|
+
IF directory_exists(srcDir):
|
|
199
|
+
Bash("mkdir -p {dstDir} && cp -r {srcDir}/* {dstDir}/")
|
|
200
|
+
|
|
201
|
+
// 7b: Merge artifact registries
|
|
202
|
+
mainArtifacts = mainState.artifacts ?? []
|
|
203
|
+
existingIds = new Set(mainArtifacts.map(a => a.id))
|
|
204
|
+
for (art of wtArtifacts):
|
|
205
|
+
IF existingIds.has(art.id):
|
|
206
|
+
// Update existing artifact status
|
|
207
|
+
idx = mainArtifacts.findIndex(a => a.id === art.id)
|
|
208
|
+
mainArtifacts[idx] = art
|
|
209
|
+
ELSE:
|
|
210
|
+
mainArtifacts.push(art)
|
|
211
|
+
mainState.artifacts = mainArtifacts
|
|
212
|
+
|
|
213
|
+
// Record merge in transition history
|
|
214
|
+
mainState.transition_history = mainState.transition_history ?? []
|
|
215
|
+
mainState.transition_history.push({
|
|
216
|
+
milestone_num: target.milestone_num,
|
|
217
|
+
milestone: target.milestone,
|
|
218
|
+
action: "worktree_merge",
|
|
219
|
+
completed_at: getUtc8ISOString(),
|
|
220
|
+
branch: target.branch,
|
|
221
|
+
phases: target.owned_phases
|
|
222
|
+
})
|
|
223
|
+
|
|
224
|
+
// Merge accumulated context from worktree
|
|
284
225
|
IF wtState?.accumulated_context:
|
|
285
226
|
for (decision of (wtState.accumulated_context.key_decisions ?? [])):
|
|
286
227
|
IF NOT mainState.accumulated_context.key_decisions.includes(decision):
|
|
@@ -294,10 +235,7 @@ Write .workflow/state.json: mainState
|
|
|
294
235
|
// 7c: Update roadmap.md (mark completed phases)
|
|
295
236
|
Read .workflow/roadmap.md → roadmap
|
|
296
237
|
for (phaseNum of target.owned_phases):
|
|
297
|
-
|
|
298
|
-
isCompleted = completedPhases.some(p => p.phase === phaseNum)
|
|
299
|
-
ELSE:
|
|
300
|
-
Read phase index → isCompleted = (status === "completed")
|
|
238
|
+
isCompleted = completedPhases.some(p => p.phase === phaseNum)
|
|
301
239
|
IF isCompleted:
|
|
302
240
|
Append " ✅ COMPLETED" to phase title line in roadmap
|
|
303
241
|
Write .workflow/roadmap.md: roadmap
|
|
@@ -66,24 +66,41 @@ Check existing entries to avoid duplicates when appending in Step 3.
|
|
|
66
66
|
- Extract patterns discovered
|
|
67
67
|
- Extract pitfalls encountered
|
|
68
68
|
|
|
69
|
-
2. Aggregate learnings and append to `.workflow/specs/learnings.md
|
|
69
|
+
2. Aggregate learnings and append to `.workflow/specs/learnings.md` using `<spec-entry>` closed-tag format:
|
|
70
70
|
```
|
|
71
71
|
For each strategy adjustment:
|
|
72
|
-
|
|
72
|
+
<spec-entry category="learning" keywords="{auto-extracted}" date="{YYYY-MM-DD}" source="milestone-complete">
|
|
73
|
+
|
|
74
|
+
### {summary}
|
|
75
|
+
|
|
73
76
|
{content}
|
|
74
|
-
Milestone: {milestone}
|
|
77
|
+
Milestone: {milestone}
|
|
78
|
+
|
|
79
|
+
</spec-entry>
|
|
75
80
|
|
|
76
81
|
For each pattern:
|
|
77
|
-
|
|
82
|
+
<spec-entry category="learning" keywords="{auto-extracted}" date="{YYYY-MM-DD}" source="milestone-complete">
|
|
83
|
+
|
|
84
|
+
### {summary}
|
|
85
|
+
|
|
78
86
|
{content}
|
|
79
|
-
Milestone: {milestone}
|
|
87
|
+
Milestone: {milestone}
|
|
88
|
+
|
|
89
|
+
</spec-entry>
|
|
80
90
|
|
|
81
91
|
For each pitfall:
|
|
82
|
-
|
|
92
|
+
<spec-entry category="learning" keywords="{auto-extracted}" date="{YYYY-MM-DD}" source="milestone-complete">
|
|
93
|
+
|
|
94
|
+
### {summary}
|
|
95
|
+
|
|
83
96
|
{content}
|
|
84
|
-
Milestone: {milestone}
|
|
97
|
+
Milestone: {milestone}
|
|
98
|
+
|
|
99
|
+
</spec-entry>
|
|
85
100
|
```
|
|
86
101
|
|
|
102
|
+
**Keyword extraction**: Extract 3-5 domain-specific terms from the content (same rules as `spec-add`).
|
|
103
|
+
|
|
87
104
|
---
|
|
88
105
|
|
|
89
106
|
## Step 4: Update State
|
|
@@ -9,7 +9,7 @@ This is a **post-execution analysis** workflow. It reads only — until the rout
|
|
|
9
9
|
## Prerequisites
|
|
10
10
|
|
|
11
11
|
- `.workflow/` initialized (`.workflow/state.json` exists)
|
|
12
|
-
- At least one completed phase (via artifact registry in state.json
|
|
12
|
+
- At least one completed phase (via artifact registry in state.json)
|
|
13
13
|
- Target phase has been executed (has `.task/` and `.summaries/`)
|
|
14
14
|
- `maestro delegate` available (used for the four lens analyses via Agent calls)
|
|
15
15
|
|
|
@@ -64,43 +64,24 @@ candidates = []
|
|
|
64
64
|
|
|
65
65
|
Read .workflow/state.json → state
|
|
66
66
|
artifacts = state.artifacts ?? []
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
review_verdict: "—"
|
|
86
|
-
})
|
|
87
|
-
ELSE:
|
|
88
|
-
// Legacy: scan phases/ directory
|
|
89
|
-
FOR each .workflow/phases/{NN}-{slug}/index.json:
|
|
90
|
-
Read index.json
|
|
91
|
-
IF index.json.status == "completed":
|
|
92
|
-
phase_dir = ".workflow/phases/{NN}-{slug}"
|
|
93
|
-
has_retro = file exists at "{phase_dir}/retrospective.json"
|
|
94
|
-
candidates.push({
|
|
95
|
-
number: NN,
|
|
96
|
-
slug: slug,
|
|
97
|
-
title: index.json.title or slug,
|
|
98
|
-
completed_at: index.json.completed_at,
|
|
99
|
-
has_retro: has_retro,
|
|
100
|
-
phase_dir: phase_dir,
|
|
101
|
-
gaps: index.json.verification?.gaps?.length or 0,
|
|
102
|
-
review_verdict: index.json.review?.verdict or "—"
|
|
103
|
-
})
|
|
67
|
+
|
|
68
|
+
// Resolve completed phases from artifact registry
|
|
69
|
+
phaseNums = [...new Set(artifacts.map(a => a.phase).filter(Boolean))]
|
|
70
|
+
FOR each phaseNum in phaseNums:
|
|
71
|
+
execArt = artifacts.find(a => a.type === 'execute' && a.phase === phaseNum && a.status === 'completed')
|
|
72
|
+
IF execArt:
|
|
73
|
+
artifact_dir = ".workflow/" + execArt.path
|
|
74
|
+
has_retro = file exists at "{artifact_dir}/retrospective.json"
|
|
75
|
+
candidates.push({
|
|
76
|
+
number: phaseNum,
|
|
77
|
+
slug: execArt.slug ?? "phase-" + phaseNum,
|
|
78
|
+
title: execArt.title ?? execArt.slug ?? "Phase " + phaseNum,
|
|
79
|
+
completed_at: execArt.completed_at,
|
|
80
|
+
has_retro: has_retro,
|
|
81
|
+
phase_dir: artifact_dir,
|
|
82
|
+
gaps: 0,
|
|
83
|
+
review_verdict: "—"
|
|
84
|
+
})
|
|
104
85
|
```
|
|
105
86
|
|
|
106
87
|
### Display backlog
|
|
@@ -130,7 +111,7 @@ ELSE:
|
|
|
130
111
|
|
|
131
112
|
If overwriting existing retrospective.json:
|
|
132
113
|
```
|
|
133
|
-
mkdir -p "{candidate.phase_dir}/.history"
|
|
114
|
+
mkdir -p "{candidate.phase_dir}/.history" // phase_dir is artifact_dir from registry
|
|
134
115
|
TIMESTAMP = format(now(), "YYYY-MM-DDTHH-mm-ss")
|
|
135
116
|
mv "{candidate.phase_dir}/retrospective.json" "{candidate.phase_dir}/.history/retrospective-{TIMESTAMP}.json"
|
|
136
117
|
mv "{candidate.phase_dir}/retrospective.md" "{candidate.phase_dir}/.history/retrospective-{TIMESTAMP}.md"
|
|
@@ -143,20 +124,20 @@ mv "{candidate.phase_dir}/retrospective.md" "{candidate.phase_dir}/.history/re
|
|
|
143
124
|
For each selected phase (using `candidate.phase_dir` resolved in Stage 2), build the in-memory artifacts bundle:
|
|
144
125
|
|
|
145
126
|
```
|
|
146
|
-
phase_dir = candidate.phase_dir // already resolved
|
|
127
|
+
phase_dir = candidate.phase_dir // already resolved from artifact registry (e.g. .workflow/scratch/plan-auth-2026-04-20)
|
|
147
128
|
|
|
148
129
|
artifacts = {
|
|
149
130
|
phase_num: NN,
|
|
150
131
|
phase_slug: slug,
|
|
151
|
-
|
|
152
|
-
index: read "{
|
|
132
|
+
artifact_dir: artifact_dir,
|
|
133
|
+
index: read "{artifact_dir}/index.json" or null,
|
|
153
134
|
state: read .workflow/state.json,
|
|
154
|
-
plan: read "{
|
|
155
|
-
verification: read "{
|
|
156
|
-
review: read "{
|
|
157
|
-
uat: read "{
|
|
158
|
-
task_summaries: read all "{
|
|
159
|
-
task_jsons: read all "{
|
|
135
|
+
plan: read "{artifact_dir}/plan.json" or null,
|
|
136
|
+
verification: read "{artifact_dir}/verification.json" or null,
|
|
137
|
+
review: read "{artifact_dir}/review.json" or null,
|
|
138
|
+
uat: read "{artifact_dir}/uat.md" or null,
|
|
139
|
+
task_summaries: read all "{artifact_dir}/.summaries/TASK-*-summary.md",
|
|
140
|
+
task_jsons: read all "{artifact_dir}/.task/TASK-*.json",
|
|
160
141
|
phase_issues: filter ".workflow/issues/issues.jsonl" + ".workflow/issues/issue-history.jsonl"
|
|
161
142
|
where issue.phase_ref == phase_slug or issue.phase_ref == NN,
|
|
162
143
|
prior_retro: null
|
|
@@ -164,12 +145,9 @@ artifacts = {
|
|
|
164
145
|
|
|
165
146
|
// Resolve --compare target
|
|
166
147
|
IF --compare M:
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
artifacts.prior_retro = read ".workflow/" + compareArt.path + "/retrospective.json"
|
|
171
|
-
ELSE:
|
|
172
|
-
artifacts.prior_retro = read .workflow/phases/{MM}-*/retrospective.json
|
|
148
|
+
compareArt = state.artifacts.find(a => a.type === 'execute' && a.phase === M)
|
|
149
|
+
IF compareArt:
|
|
150
|
+
artifacts.prior_retro = read ".workflow/" + compareArt.path + "/retrospective.json"
|
|
173
151
|
}
|
|
174
152
|
```
|
|
175
153
|
|
|
@@ -245,12 +223,12 @@ the project's spec / note / issue stores.
|
|
|
245
223
|
- Completed at: {index.completed_at}
|
|
246
224
|
|
|
247
225
|
## Artifacts (read these from disk)
|
|
248
|
-
- Plan: {
|
|
249
|
-
- Verification: {
|
|
250
|
-
- Review: {
|
|
251
|
-
- UAT notes: {
|
|
252
|
-
- Task summaries: {
|
|
253
|
-
- Task JSONs: {
|
|
226
|
+
- Plan: {artifact_dir}/plan.json
|
|
227
|
+
- Verification: {artifact_dir}/verification.json
|
|
228
|
+
- Review: {artifact_dir}/review.json
|
|
229
|
+
- UAT notes: {artifact_dir}/uat.md
|
|
230
|
+
- Task summaries: {artifact_dir}/.summaries/
|
|
231
|
+
- Task JSONs: {artifact_dir}/.task/
|
|
254
232
|
- Phase issues: .workflow/issues/issues.jsonl (filter phase_ref == "{phase_slug}")
|
|
255
233
|
- Project state: .workflow/state.json (decisions, deferred)
|
|
256
234
|
|
|
@@ -287,7 +265,7 @@ Return ONLY a single JSON object, no prose, matching this schema:
|
|
|
287
265
|
"title": "Short imperative title",
|
|
288
266
|
"summary": "1–3 sentences a future planner can act on",
|
|
289
267
|
"confidence": "high|medium|low",
|
|
290
|
-
"evidence_refs": ["{
|
|
268
|
+
"evidence_refs": ["{artifact_dir}/verification.json#gaps[2]", "..."],
|
|
291
269
|
"routed_to": "spec|note|issue|none",
|
|
292
270
|
"tags": ["..."]
|
|
293
271
|
}
|
|
@@ -463,8 +441,8 @@ retrospective = {
|
|
|
463
441
|
|
|
464
442
|
Write both files (phase_dir already resolved in Stage 2):
|
|
465
443
|
```
|
|
466
|
-
Write "{
|
|
467
|
-
Write "{
|
|
444
|
+
Write "{artifact_dir}/retrospective.json"
|
|
445
|
+
Write "{artifact_dir}/retrospective.md"
|
|
468
446
|
```
|
|
469
447
|
|
|
470
448
|
---
|
|
@@ -493,46 +471,31 @@ Accept all? [Y/n/i for individual]
|
|
|
493
471
|
|
|
494
472
|
#### Target: spec
|
|
495
473
|
|
|
496
|
-
|
|
474
|
+
Route spec-routed insights as `<spec-entry>` entries into the appropriate category file. Map insight type to category:
|
|
475
|
+
- `pattern` / `convention` → `coding`
|
|
476
|
+
- `adr-candidate` / architecture → `arch`
|
|
477
|
+
- quality-related → `quality`
|
|
497
478
|
|
|
498
479
|
```
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
spec_file = ".workflow/specs/SPEC-retro-{phase_num}-{INS_id}-{slug}.md"
|
|
502
|
-
|
|
503
|
-
Write spec_file:
|
|
504
|
-
---
|
|
505
|
-
status: draft
|
|
506
|
-
type: pattern | convention | adr-candidate
|
|
507
|
-
source: retrospective
|
|
508
|
-
source_phase: {NN}
|
|
509
|
-
source_insight: {INS_id}
|
|
510
|
-
created_at: {now ISO}
|
|
511
|
-
tags: {insight.tags}
|
|
512
|
-
confidence: {insight.confidence}
|
|
513
|
-
---
|
|
514
|
-
|
|
515
|
-
# {insight.title}
|
|
480
|
+
category = map_insight_to_category(insight.type)
|
|
481
|
+
target_file = category_to_file(category) # e.g., coding → coding-conventions.md
|
|
516
482
|
|
|
517
|
-
|
|
483
|
+
keywords = extract_keywords(insight.title + insight.summary) # 3-5 domain-specific terms
|
|
518
484
|
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
into a full spec via `/maestro-spec-generate` if it warrants project-wide adoption.
|
|
485
|
+
Append to .workflow/specs/{target_file}:
|
|
486
|
+
<spec-entry category="{category}" keywords="{keywords}" date="{YYYY-MM-DD}" source="retrospective">
|
|
522
487
|
|
|
523
|
-
|
|
488
|
+
### {insight.title}
|
|
524
489
|
|
|
525
|
-
{insight.summary}
|
|
490
|
+
{insight.summary}
|
|
526
491
|
|
|
527
|
-
|
|
492
|
+
**Evidence:** {FOR ref in evidence_refs:} `{ref}` {END FOR}
|
|
493
|
+
**Phase:** {NN} ({phase_slug}) | **Lens:** {lens} | **Insight:** {INS_id} | **Confidence:** {insight.confidence}
|
|
528
494
|
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
## Open Questions
|
|
495
|
+
</spec-entry>
|
|
496
|
+
```
|
|
532
497
|
|
|
533
|
-
|
|
534
|
-
- Should existing code be migrated to this pattern, or is it forward-only?
|
|
535
|
-
- What is the failure mode if this pattern is violated?
|
|
498
|
+
If the target file does not exist, create it with category frontmatter first (same as `spec-add` on-demand creation).
|
|
536
499
|
|
|
537
500
|
## Routing trail
|
|
538
501
|
|
|
@@ -541,7 +504,7 @@ into a full spec via `/maestro-spec-generate` if it warrants project-wide adopti
|
|
|
541
504
|
- Insight: {INS_id}
|
|
542
505
|
- Confidence: {confidence}
|
|
543
506
|
|
|
544
|
-
insight.routed_id = "
|
|
507
|
+
insight.routed_id = "{category_file}#INS-{INS_id}" # e.g., coding-conventions.md#INS-a1b2c3d4
|
|
545
508
|
```
|
|
546
509
|
|
|
547
510
|
#### Target: note
|
|
@@ -561,7 +524,7 @@ Capture the returned TIP-{id} from the skill output.
|
|
|
561
524
|
insight.routed_id = "TIP-{captured_id}"
|
|
562
525
|
```
|
|
563
526
|
|
|
564
|
-
If the skill call cannot be intercepted to capture the ID, fall back to writing the tip file directly using the schema in `workflows/memory.md` Part B Step 3 (Tip mode), and update `
|
|
527
|
+
If the skill call cannot be intercepted to capture the ID, fall back to writing the tip file directly using the schema in `workflows/memory.md` Part B Step 3 (Tip mode), and update `wiki-index.json` per Step 4.
|
|
565
528
|
|
|
566
529
|
#### Target: issue
|
|
567
530
|
|
|
@@ -706,19 +669,24 @@ Write .workflow/learning/learning-index.json
|
|
|
706
669
|
|
|
707
670
|
### Backward-compat append to specs/learnings.md
|
|
708
671
|
|
|
709
|
-
Append learnings to `.workflow/specs/learnings.md` (shared with milestone-complete's learning extraction)
|
|
672
|
+
Append learnings to `.workflow/specs/learnings.md` (shared with milestone-complete's learning extraction) using `<spec-entry>` closed-tag format:
|
|
710
673
|
|
|
711
674
|
```
|
|
712
675
|
IF .workflow/specs/learnings.md exists:
|
|
713
676
|
FOR each insight:
|
|
714
|
-
|
|
715
|
-
|
|
677
|
+
keywords = extract_keywords(insight.title + insight.summary) # 3-5 domain-specific terms
|
|
678
|
+
Append:
|
|
679
|
+
<spec-entry category="learning" keywords="{keywords}" date="{YYYY-MM-DD}" source="retrospective">
|
|
680
|
+
|
|
681
|
+
### {title}
|
|
716
682
|
|
|
717
683
|
{summary}
|
|
718
|
-
Phase: {NN} |
|
|
684
|
+
Phase: {NN} | Lens: {lens} | Insight: {INS_id}
|
|
685
|
+
|
|
686
|
+
</spec-entry>
|
|
719
687
|
```
|
|
720
688
|
|
|
721
|
-
If the file does not exist, create it with a `## Entries` header.
|
|
689
|
+
If the file does not exist, create it with category frontmatter and a `## Entries` header.
|
|
722
690
|
|
|
723
691
|
---
|
|
724
692
|
|
|
@@ -733,14 +701,14 @@ Lenses run: {lenses joined by ", "}
|
|
|
733
701
|
Insights: {count}
|
|
734
702
|
|
|
735
703
|
Routing summary:
|
|
736
|
-
|
|
704
|
+
Spec entries: {N} → .workflow/specs/{category-file}.md
|
|
737
705
|
Notes saved: {N} → .workflow/memory/TIP-*
|
|
738
706
|
Issues opened: {N} → .workflow/issues/issues.jsonl
|
|
739
707
|
Lessons logged: {N} → .workflow/learning/lessons.jsonl
|
|
740
708
|
|
|
741
709
|
Files:
|
|
742
|
-
{
|
|
743
|
-
{
|
|
710
|
+
{artifact_dir}/retrospective.md
|
|
711
|
+
{artifact_dir}/retrospective.json
|
|
744
712
|
|
|
745
713
|
Next steps (suggested):
|
|
746
714
|
Skill({ skill: "manage-status" }) — Review project state
|
|
@@ -809,12 +777,12 @@ Total issues: {sum}
|
|
|
809
777
|
"summary": "Refresh-on-use prevents replay attacks. Implemented in src/auth/refresh.ts; should become a project-wide convention.",
|
|
810
778
|
"confidence": "high",
|
|
811
779
|
"evidence_refs": [
|
|
812
|
-
".workflow/
|
|
813
|
-
".workflow/
|
|
780
|
+
".workflow/scratch/plan-auth-2026-04-15/verification.json#gaps[2]",
|
|
781
|
+
".workflow/scratch/plan-auth-2026-04-15/.summaries/TASK-005-summary.md:42"
|
|
814
782
|
],
|
|
815
783
|
"tags": ["auth", "jwt", "security"],
|
|
816
784
|
"routed_to": "spec",
|
|
817
|
-
"routed_id": "
|
|
785
|
+
"routed_id": "coding-conventions.md#INS-a1b2c3d4"
|
|
818
786
|
}
|
|
819
787
|
],
|
|
820
788
|
"routing_recommendations": [
|
|
@@ -829,7 +797,7 @@ Total issues: {sum}
|
|
|
829
797
|
One JSON object per line:
|
|
830
798
|
|
|
831
799
|
```json
|
|
832
|
-
{"id":"INS-a1b2c3d4","phase":1,"phase_slug":"01-auth","lens":"technical","category":"pattern","title":"JWT refresh tokens must rotate on every use","summary":"...","confidence":"high","tags":["auth","jwt","security"],"evidence_refs":["..."],"routed_to":"spec","routed_id":"
|
|
800
|
+
{"id":"INS-a1b2c3d4","phase":1,"phase_slug":"01-auth","lens":"technical","category":"pattern","title":"JWT refresh tokens must rotate on every use","summary":"...","confidence":"high","tags":["auth","jwt","security"],"evidence_refs":["..."],"routed_to":"spec","routed_id":"coding-conventions.md#INS-a1b2c3d4","source":"retrospective","captured_at":"2026-04-11T10:00:00Z"}
|
|
833
801
|
```
|
|
834
802
|
|
|
835
803
|
### learning-index.json
|
|
@@ -850,7 +818,7 @@ One JSON object per line:
|
|
|
850
818
|
"phase_slug": "01-auth",
|
|
851
819
|
"confidence": "high",
|
|
852
820
|
"routed_to": "spec",
|
|
853
|
-
"routed_id": "
|
|
821
|
+
"routed_id": "coding-conventions.md#INS-a1b2c3d4"
|
|
854
822
|
}
|
|
855
823
|
],
|
|
856
824
|
"_metadata": {
|
package/workflows/review.md
CHANGED
|
@@ -18,18 +18,11 @@ Input: <phase> argument (number or slug)
|
|
|
18
18
|
|
|
19
19
|
Read .workflow/state.json → state
|
|
20
20
|
artifacts = state.artifacts ?? []
|
|
21
|
-
useArtifactRegistry = artifacts.length > 0
|
|
22
21
|
|
|
23
|
-
IF
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
ELSE: ERROR "Phase not found in artifact registry"
|
|
28
|
-
ELSE:
|
|
29
|
-
// Legacy: resolve from phases/ directory
|
|
30
|
-
IF number: find .workflow/phases/{NN}-*/index.json
|
|
31
|
-
IF slug: find .workflow/phases/*-{slug}/index.json
|
|
32
|
-
PHASE_DIR = resolved path
|
|
22
|
+
IF number: art = artifacts.find(a => a.type === 'execute' && a.phase === number)
|
|
23
|
+
IF slug: art = artifacts.find(a => a.type === 'execute' && a.slug?.includes(slug))
|
|
24
|
+
IF art: PHASE_DIR = ".workflow/" + art.path
|
|
25
|
+
ELSE: ERROR "Phase not found in artifact registry"
|
|
33
26
|
|
|
34
27
|
Validate execution has occurred (tasks_completed > 0 or .task/ exists)
|
|
35
28
|
```
|
|
@@ -587,7 +580,7 @@ Verdict: {PASS | WARN | BLOCK}
|
|
|
587
580
|
Issues Created: {count}
|
|
588
581
|
|
|
589
582
|
Files:
|
|
590
|
-
{
|
|
583
|
+
{artifact_dir}/review.json
|
|
591
584
|
|
|
592
585
|
Next steps:
|
|
593
586
|
{suggested_next_command}
|