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.
- package/.claude/commands/learn-decompose.md +3 -3
- package/.claude/commands/learn-follow.md +5 -5
- package/.claude/commands/learn-investigate.md +3 -3
- package/.claude/commands/learn-retro.md +6 -6
- package/.claude/commands/learn-second-opinion.md +3 -3
- package/.claude/commands/maestro-analyze.md +123 -99
- package/.claude/commands/maestro-brainstorm.md +2 -2
- package/.claude/commands/maestro-execute.md +137 -97
- package/.claude/commands/maestro-fork.md +111 -0
- package/.claude/commands/maestro-init.md +6 -6
- package/.claude/commands/maestro-merge.md +77 -0
- package/.claude/commands/maestro-milestone-audit.md +72 -60
- package/.claude/commands/maestro-milestone-complete.md +67 -59
- package/.claude/commands/maestro-milestone-release.md +6 -6
- package/.claude/commands/maestro-plan.md +151 -130
- package/.claude/commands/maestro-quick.md +4 -4
- package/.claude/commands/maestro-roadmap.md +5 -5
- package/.claude/commands/maestro-spec-generate.md +5 -5
- package/.claude/commands/maestro-ui-design.md +3 -3
- package/.claude/commands/maestro-verify.md +106 -87
- package/.claude/commands/maestro.md +10 -4
- package/.claude/commands/manage-codebase-rebuild.md +4 -4
- package/.claude/commands/manage-codebase-refresh.md +1 -1
- package/.claude/commands/manage-harvest.md +5 -5
- package/.claude/commands/manage-issue-discover.md +1 -1
- package/.claude/commands/manage-issue-execute.md +6 -6
- package/.claude/commands/manage-issue.md +6 -6
- package/.claude/commands/manage-learn.md +2 -2
- package/.claude/commands/manage-memory-capture.md +4 -4
- package/.claude/commands/manage-memory.md +2 -2
- package/.claude/commands/manage-status.md +24 -24
- package/.claude/commands/quality-business-test.md +5 -5
- package/.claude/commands/quality-debug.md +4 -4
- package/.claude/commands/quality-integration-test.md +4 -4
- package/.claude/commands/quality-refactor.md +3 -3
- package/.claude/commands/quality-retrospective.md +2 -2
- package/.claude/commands/quality-review.md +4 -4
- package/.claude/commands/quality-sync.md +3 -3
- package/.claude/commands/quality-test-gen.md +4 -4
- package/.claude/commands/quality-test.md +9 -9
- package/.claude/commands/spec-add.md +2 -2
- package/.claude/commands/spec-load.md +1 -1
- package/.claude/commands/spec-setup.md +5 -5
- package/.claude/commands/wiki-connect.md +3 -3
- package/.claude/commands/wiki-digest.md +4 -4
- package/.codex/skills/maestro-analyze/SKILL.md +52 -14
- package/.codex/skills/maestro-execute/SKILL.md +27 -26
- package/.codex/skills/maestro-milestone-audit/SKILL.md +103 -209
- package/.codex/skills/maestro-milestone-complete/SKILL.md +149 -158
- package/.codex/skills/maestro-plan/SKILL.md +47 -17
- package/.codex/skills/maestro-roadmap/SKILL.md +3 -2
- package/.codex/skills/team-coordinate/roles/coordinator/commands/monitor.md +2 -2
- package/.codex/skills/team-executor/roles/executor/commands/monitor.md +1 -1
- package/.codex/skills/team-lifecycle-v4/roles/coordinator/commands/monitor.md +2 -2
- package/.codex/skills/team-lifecycle-v4/specs/knowledge-transfer.md +2 -2
- package/.codex/skills/team-quality-assurance/roles/coordinator/commands/monitor.md +1 -1
- package/.codex/skills/team-review/roles/coordinator/commands/monitor.md +1 -1
- package/.codex/skills/team-tech-debt/roles/coordinator/commands/monitor.md +1 -1
- package/.codex/skills/team-testing/roles/coordinator/commands/monitor.md +1 -1
- package/README.md +19 -14
- package/README.zh-CN.md +16 -12
- package/bin/maestro-mcp.js +1 -1
- package/chains/_intent-map.json +21 -9
- package/chains/_router.json +30 -77
- package/chains/brainstorm-driven.json +17 -6
- package/chains/full-lifecycle.json +22 -23
- package/chains/milestone-close.json +20 -7
- package/chains/milestone-fork-merge.json +50 -0
- package/chains/roadmap-driven.json +17 -6
- package/chains/spec-driven.json +17 -6
- package/dashboard/dist/assets/{ArtifactsPage-BmPOu8sO.js → ArtifactsPage-DZNCi6tn.js} +12 -7
- package/dashboard/dist/assets/ChatInput-Bvr-FeEq.js +49 -0
- package/dashboard/dist/assets/ChatPage-D9zTkJZo.js +22 -0
- package/dashboard/dist/assets/CollabPage-B4NAHXS2.js +1 -0
- package/dashboard/dist/assets/ExecutionPanel-CFt4LJyq.js +1 -0
- package/dashboard/dist/assets/KanbanPage-C8USth6H.js +21 -0
- package/dashboard/dist/assets/{MarkdownRenderer-BjZ43aSa.js → MarkdownRenderer-X4af_WNb.js} +1 -1
- package/dashboard/dist/assets/McpPage-BKfCVIyU.js +21 -0
- package/dashboard/dist/assets/OutputPanel-BlBQFJSW.js +1 -0
- package/dashboard/dist/assets/ProblemsPanel-De3DLvoI.js +1 -0
- package/dashboard/dist/assets/{RequirementBoardPage-B7yRL0s_.js → RequirementBoardPage-Bf1trzqs.js} +2 -2
- package/dashboard/dist/assets/{RequirementPage-D8J_-b6O.js → RequirementPage-Bllxe2XI.js} +10 -5
- package/dashboard/dist/assets/{SpecsPage-6lO8v8_C.js → SpecsPage-9lwxKT27.js} +2 -2
- package/dashboard/dist/assets/{SupervisorPage-Ds5N378a.js → SupervisorPage-SusdfHFq.js} +1 -1
- package/dashboard/dist/assets/{TeamsPage-DrkKr17T.js → TeamsPage-DsuM6OwC.js} +2 -2
- package/dashboard/dist/assets/TreeBrowser-Q12qobZs.js +6 -0
- package/dashboard/dist/assets/WorkflowPage-D_Fzdy3_.js +6 -0
- package/dashboard/dist/assets/{arrow-left-CadP5YgU.js → arrow-left-Bqtb2hle.js} +1 -1
- package/dashboard/dist/assets/{check-5xufDzS8.js → check-u6fGOwQO.js} +1 -1
- package/dashboard/dist/assets/{chevron-right-CYbpR4ev.js → chevron-right-Csu22t58.js} +1 -1
- package/dashboard/dist/assets/{circle-Bm-5Q-Yh.js → circle-CMrkbRNg.js} +1 -1
- package/dashboard/dist/assets/{circle-alert-BqcYuT7x.js → circle-alert-c3tH1P4z.js} +1 -1
- package/dashboard/dist/assets/{circle-check-big-yyzAFysU.js → circle-check-big-TDSeWstm.js} +1 -1
- package/dashboard/dist/assets/{circle-check-DEVzW_lm.js → circle-check-gYxxSYuH.js} +1 -1
- package/dashboard/dist/assets/{code-BBdC8Wmw.js → code-CFN2uX9V.js} +1 -1
- package/dashboard/dist/assets/{columns-3-CQ9Trztr.js → columns-3-38xIDlzy.js} +1 -1
- package/dashboard/dist/assets/{download-DayuF-sn.js → download-DC7KkKyP.js} +1 -1
- package/dashboard/dist/assets/{folder-CqXeSKeC.js → folder-CWq_lAnf.js} +1 -1
- package/dashboard/dist/assets/index-DWG-WrzT.js +231 -0
- package/dashboard/dist/assets/{index-Dru5HYy0.js → index-Do71weNR.js} +1 -1
- package/dashboard/dist/assets/index-GUNJodSR.css +1 -0
- package/dashboard/dist/assets/{list-DBOD6IUt.js → list-CgIP_2A-.js} +1 -1
- package/dashboard/dist/assets/{minus-fQI1Syn2.js → minus-DYoN5UGk.js} +1 -1
- package/dashboard/dist/assets/{pen-line-Bkbbngl5.js → pen-line-Bh_WKYHm.js} +1 -1
- package/dashboard/dist/assets/{proxy-teW12DdZ.js → proxy-BKxDAKTj.js} +1 -1
- package/dashboard/dist/assets/{search-Bq3ygFUW.js → search-SieXnOgr.js} +1 -1
- package/dashboard/dist/assets/{shallow-22ZN8sFt.js → shallow-Bme1JY57.js} +1 -1
- package/dashboard/dist/assets/{table-BEYtdWc4.js → table-llyEtj-7.js} +1 -1
- package/dashboard/dist/assets/terminal-BB3Xfuv5.js +6 -0
- package/dashboard/dist/assets/{trash-2-DMqGBgcF.js → trash-2-C8f4vFFM.js} +1 -1
- package/dashboard/dist/assets/{zap-9DVkGVtt.js → zap-4uwlzVm0.js} +1 -1
- package/dashboard/dist/index.html +2 -2
- package/dashboard/dist-server/dashboard/src/server/agents/claude-code-adapter.js +8 -4
- package/dashboard/dist-server/dashboard/src/server/agents/claude-code-adapter.js.map +1 -1
- package/dashboard/dist-server/dashboard/src/server/agents/entry-normalizer.d.ts +1 -0
- package/dashboard/dist-server/dashboard/src/server/agents/entry-normalizer.js +2 -1
- package/dashboard/dist-server/dashboard/src/server/agents/entry-normalizer.js.map +1 -1
- package/dashboard/dist-server/dashboard/src/server/agents/stream-json-adapter.js +20 -10
- package/dashboard/dist-server/dashboard/src/server/agents/stream-json-adapter.js.map +1 -1
- package/dashboard/dist-server/dashboard/src/server/routes/git.d.ts +2 -0
- package/dashboard/dist-server/dashboard/src/server/routes/git.js +79 -0
- package/dashboard/dist-server/dashboard/src/server/routes/git.js.map +1 -0
- package/dashboard/dist-server/dashboard/src/server/routes/index.js +3 -0
- package/dashboard/dist-server/dashboard/src/server/routes/index.js.map +1 -1
- package/dashboard/dist-server/dashboard/src/server/routes/workspace.js +43 -0
- package/dashboard/dist-server/dashboard/src/server/routes/workspace.js.map +1 -1
- package/dashboard/dist-server/dashboard/src/server/state/state-manager.js +43 -3
- package/dashboard/dist-server/dashboard/src/server/state/state-manager.js.map +1 -1
- package/dashboard/package.json +59 -59
- package/dist/src/cli.js +3 -1
- package/dist/src/cli.js.map +1 -1
- package/dist/src/commands/{team.d.ts → collab.d.ts} +2 -2
- package/dist/src/commands/collab.d.ts.map +1 -0
- package/dist/src/commands/{team.js → collab.js} +391 -24
- package/dist/src/commands/collab.js.map +1 -0
- package/dist/src/commands/msg.d.ts.map +1 -1
- package/dist/src/commands/msg.js +4 -3
- package/dist/src/commands/msg.js.map +1 -1
- package/dist/src/hooks/team-monitor.d.ts.map +1 -1
- package/dist/src/hooks/team-monitor.js +16 -0
- package/dist/src/hooks/team-monitor.js.map +1 -1
- package/dist/src/tools/collab-adapter.d.ts +85 -0
- package/dist/src/tools/collab-adapter.d.ts.map +1 -0
- package/dist/src/tools/collab-adapter.js +320 -0
- package/dist/src/tools/collab-adapter.js.map +1 -0
- package/dist/src/tools/namespace-guard.d.ts +2 -0
- package/dist/src/tools/namespace-guard.d.ts.map +1 -1
- package/dist/src/tools/namespace-guard.js +12 -0
- package/dist/src/tools/namespace-guard.js.map +1 -1
- package/dist/src/tools/phase-gate-evaluator.d.ts +45 -0
- package/dist/src/tools/phase-gate-evaluator.d.ts.map +1 -0
- package/dist/src/tools/phase-gate-evaluator.js +42 -0
- package/dist/src/tools/phase-gate-evaluator.js.map +1 -0
- package/dist/src/tools/team-members.d.ts +18 -0
- package/dist/src/tools/team-members.d.ts.map +1 -1
- package/dist/src/tools/team-members.js +50 -0
- package/dist/src/tools/team-members.js.map +1 -1
- package/dist/src/tools/team-tasks.d.ts +120 -0
- package/dist/src/tools/team-tasks.d.ts.map +1 -0
- package/dist/src/tools/team-tasks.js +365 -0
- package/dist/src/tools/team-tasks.js.map +1 -0
- package/dist/src/tools/transition-recorder.d.ts +3 -0
- package/dist/src/tools/transition-recorder.d.ts.map +1 -1
- package/dist/src/tools/transition-recorder.js +52 -1
- package/dist/src/tools/transition-recorder.js.map +1 -1
- package/dist/src/utils/get-version.d.ts.map +1 -1
- package/dist/src/utils/get-version.js +15 -4
- package/dist/src/utils/get-version.js.map +1 -1
- package/package.json +1 -1
- package/templates/config.json +7 -0
- package/templates/worktree-scope.json +10 -0
- package/templates/worktrees.json +27 -0
- package/workflows/analyze.md +86 -36
- package/workflows/brainstorm.md +17 -37
- package/workflows/execute.md +94 -28
- package/workflows/fork.md +309 -0
- package/workflows/init.md +10 -1
- package/workflows/issue.md +66 -7
- package/workflows/maestro-coordinate.md +23 -16
- package/workflows/maestro.md +52 -35
- package/workflows/merge.md +285 -0
- package/workflows/milestone-audit.md +89 -70
- package/workflows/milestone-complete.md +89 -156
- package/workflows/plan.md +122 -17
- package/workflows/retrospective.md +3 -3
- package/workflows/roadmap.md +11 -3
- package/workflows/spec-generate.md +9 -0
- package/workflows/status.md +76 -27
- package/workflows/ui-design.md +14 -12
- package/workflows/verify.md +44 -8
- package/.claude/commands/maestro-phase-add.md +0 -63
- package/.claude/commands/maestro-phase-transition.md +0 -75
- package/.codex/skills/maestro-phase-add/SKILL.md +0 -154
- package/.codex/skills/maestro-phase-transition/SKILL.md +0 -173
- package/chains/singles/phase-add.json +0 -31
- package/chains/singles/phase-transition.json +0 -23
- package/dashboard/dist/assets/ChatInput-CL8YDfOU.js +0 -67
- package/dashboard/dist/assets/ChatPage-CT-ozBK2.js +0 -8
- package/dashboard/dist/assets/CollabPage-C0rWMden.js +0 -1
- package/dashboard/dist/assets/KanbanPage-C6WbAlwI.js +0 -16
- package/dashboard/dist/assets/McpPage-BPIXADQi.js +0 -16
- package/dashboard/dist/assets/TreeBrowser-g_QUKemL.js +0 -11
- package/dashboard/dist/assets/WorkflowPage-X8aNkDEr.js +0 -6
- package/dashboard/dist/assets/git-branch-SqFf4Ru5.js +0 -6
- package/dashboard/dist/assets/index-D2Mtyw7I.css +0 -1
- package/dashboard/dist/assets/index-nufWop4p.js +0 -231
- package/dashboard/dist/assets/wrench-B84-zdLI.js +0 -11
- package/dist/src/commands/team.d.ts.map +0 -1
- package/dist/src/commands/team.js.map +0 -1
- package/workflows/phase-add.md +0 -252
- package/workflows/phase-transition.md +0 -399
package/workflows/maestro.md
CHANGED
|
@@ -56,31 +56,26 @@ test -f .workflow/state.json && echo "exists" || echo "missing"
|
|
|
56
56
|
```
|
|
57
57
|
|
|
58
58
|
**If `.workflow/state.json` exists:**
|
|
59
|
-
1. Read `state.json` → extract `current_milestone`, `
|
|
59
|
+
1. Read `state.json` → extract `current_milestone`, `status`, `milestones[]`, `artifacts[]`, `accumulated_context`
|
|
60
60
|
2. Read `.workflow/roadmap.md` → extract phase list with titles
|
|
61
|
-
3.
|
|
62
|
-
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
```
|
|
67
|
-
5. Build `$PROJECT_STATE`:
|
|
61
|
+
3. Derive progress from artifact registry:
|
|
62
|
+
- Group `artifacts[]` by phase for current milestone
|
|
63
|
+
- For each phase: determine furthest artifact type (analyze→plan→execute→verify)
|
|
64
|
+
- Identify which phases have pending plans (plan artifact without execute artifact)
|
|
65
|
+
4. Build `$PROJECT_STATE`:
|
|
68
66
|
```json
|
|
69
67
|
{
|
|
70
68
|
"initialized": true,
|
|
71
|
-
"
|
|
72
|
-
"
|
|
73
|
-
"
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
"
|
|
77
|
-
"
|
|
69
|
+
"current_milestone": "M1",
|
|
70
|
+
"milestone_name": "MVP Auth",
|
|
71
|
+
"milestone_progress": {
|
|
72
|
+
"phases_total": 3,
|
|
73
|
+
"phases_with_execute": 1,
|
|
74
|
+
"phases_with_plan": 2,
|
|
75
|
+
"adhoc_count": 0
|
|
78
76
|
},
|
|
79
|
-
"
|
|
80
|
-
"
|
|
81
|
-
"uat_status": "pending",
|
|
82
|
-
"phases_total": 3,
|
|
83
|
-
"phases_completed": 0,
|
|
77
|
+
"latest_artifact": { "id": "PLN-002", "type": "plan", "phase": 2 },
|
|
78
|
+
"pending_actions": ["execute phase 2", "analyze phase 3"],
|
|
84
79
|
"has_blockers": false,
|
|
85
80
|
"suggested_next": null
|
|
86
81
|
}
|
|
@@ -95,7 +90,7 @@ test -f .workflow/state.json && echo "exists" || echo "missing"
|
|
|
95
90
|
### Step 3: Analyze Intent
|
|
96
91
|
|
|
97
92
|
**If `$FORCED_CHAIN` is set:**
|
|
98
|
-
- Validate against known chains: `full-lifecycle`, `spec-driven`, `brainstorm-driven`, `ui-design-driven`, `analyze-plan-execute`, `execute-verify`, `quality-loop`, `milestone-close`, `next-milestone`, `quick`, `review`, `issue-full`, `issue-quick`
|
|
93
|
+
- Validate against known chains: `full-lifecycle`, `spec-driven`, `brainstorm-driven`, `ui-design-driven`, `analyze-plan-execute`, `execute-verify`, `quality-loop`, `milestone-close`, `next-milestone`, `quick`, `review`, `issue-full`, `issue-quick`, `fork`, `merge`
|
|
99
94
|
- If valid: skip intent analysis, jump to **Step 5**
|
|
100
95
|
- If invalid: display valid chains, ask user to choose
|
|
101
96
|
|
|
@@ -152,6 +147,8 @@ Instead of regex pattern matching, extract a structured intent tuple from the us
|
|
|
152
147
|
| `transition` | Move to next phase/milestone — next phase, advance, complete milestone |
|
|
153
148
|
| `continue` | Resume work — continue, next, go on, 继续 |
|
|
154
149
|
| `sync` | Update docs/state — sync, refresh, update docs, 同步 |
|
|
150
|
+
| `fork` | Create worktree for parallel milestone — fork, worktree, parallel, 分叉, 并行 |
|
|
151
|
+
| `merge` | Merge worktree back — merge worktree, merge milestone, 合并工作树 |
|
|
155
152
|
| `learn` | Capture insights — learn, capture insight, eureka, 记录洞察 |
|
|
156
153
|
| `retrospect` | Post-mortem review — retrospective, retro, 复盘, post-mortem |
|
|
157
154
|
|
|
@@ -260,7 +257,7 @@ function routeIntent(intent, projectState) {
|
|
|
260
257
|
'manage': {
|
|
261
258
|
'issue': 'issue',
|
|
262
259
|
'milestone': 'milestone_audit',
|
|
263
|
-
'phase': '
|
|
260
|
+
'phase': 'milestone_close',
|
|
264
261
|
'memory': 'memory',
|
|
265
262
|
'doc': 'sync',
|
|
266
263
|
'codebase': 'codebase_refresh',
|
|
@@ -269,9 +266,9 @@ function routeIntent(intent, projectState) {
|
|
|
269
266
|
'_default': 'status',
|
|
270
267
|
},
|
|
271
268
|
'transition': {
|
|
272
|
-
'phase': '
|
|
269
|
+
'phase': 'milestone_close',
|
|
273
270
|
'milestone': 'milestone_complete',
|
|
274
|
-
'_default': '
|
|
271
|
+
'_default': 'milestone_close',
|
|
275
272
|
},
|
|
276
273
|
'continue': { '_default': 'state_continue' },
|
|
277
274
|
'sync': {
|
|
@@ -279,6 +276,8 @@ function routeIntent(intent, projectState) {
|
|
|
279
276
|
'codebase': 'codebase_refresh',
|
|
280
277
|
'_default': 'sync',
|
|
281
278
|
},
|
|
279
|
+
'fork': { '_default': 'fork' },
|
|
280
|
+
'merge': { '_default': 'merge' },
|
|
282
281
|
'learn': { '_default': 'learn' },
|
|
283
282
|
'retrospect': { '_default': 'retrospective' },
|
|
284
283
|
};
|
|
@@ -455,7 +454,7 @@ function detectNextAction(state) {
|
|
|
455
454
|
if (rev === 'BLOCK') return { chain: 'review-fix', steps: ['maestro-plan --gaps', 'maestro-execute', 'quality-review'] };
|
|
456
455
|
// Review passed or warned — proceed to UAT
|
|
457
456
|
if (uat === 'pending') return { chain: 'test', steps: ['quality-test'] };
|
|
458
|
-
if (uat === 'passed') return { chain: '
|
|
457
|
+
if (uat === 'passed') return { chain: 'milestone-close', steps: ['maestro-milestone-audit', 'maestro-milestone-complete'] };
|
|
459
458
|
if (uat === 'failed') return { chain: 'debug', steps: ['quality-debug --from-uat {phase}'] };
|
|
460
459
|
if (uat === 'in_progress') return { chain: 'test', steps: ['quality-test'] };
|
|
461
460
|
return { chain: 'test', steps: ['quality-test'] };
|
|
@@ -466,7 +465,7 @@ function detectNextAction(state) {
|
|
|
466
465
|
|
|
467
466
|
// Testing
|
|
468
467
|
if (ps === 'testing') {
|
|
469
|
-
if (uat === 'passed') return { chain: '
|
|
468
|
+
if (uat === 'passed') return { chain: 'milestone-close', steps: ['maestro-milestone-audit', 'maestro-milestone-complete'] };
|
|
470
469
|
return { chain: 'debug', steps: ['quality-debug --from-uat {phase}'] };
|
|
471
470
|
}
|
|
472
471
|
|
|
@@ -474,7 +473,16 @@ function detectNextAction(state) {
|
|
|
474
473
|
if (ps === 'completed') {
|
|
475
474
|
if (state.phases_completed >= state.phases_total)
|
|
476
475
|
return { chain: 'milestone-close', steps: ['maestro-milestone-audit', 'maestro-milestone-complete'] };
|
|
477
|
-
return { chain: '
|
|
476
|
+
return { chain: 'milestone-close', steps: ['maestro-milestone-audit', 'maestro-milestone-complete'] };
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
// Phase forked (developed in a worktree)
|
|
480
|
+
if (ps === 'forked') {
|
|
481
|
+
// Check if worktree is complete — suggest merge
|
|
482
|
+
if (fileExists('.workflow/worktrees.json')) {
|
|
483
|
+
return { chain: 'merge', steps: ['maestro-merge'] };
|
|
484
|
+
}
|
|
485
|
+
return { chain: 'status', steps: ['manage-status'] };
|
|
478
486
|
}
|
|
479
487
|
|
|
480
488
|
// Blocked
|
|
@@ -511,8 +519,7 @@ const chainMap = {
|
|
|
511
519
|
'retrospective': [{ cmd: 'quality-retrospective', args: '{phase}' }],
|
|
512
520
|
'learn': [{ cmd: 'manage-learn', args: '"{description}"' }],
|
|
513
521
|
'sync': [{ cmd: 'quality-sync', args: '{phase}' }],
|
|
514
|
-
'
|
|
515
|
-
'phase_add': [{ cmd: 'maestro-phase-add', args: '"{description}"' }],
|
|
522
|
+
'milestone_close': [{ cmd: 'maestro-milestone-audit' }, { cmd: 'maestro-milestone-complete' }],
|
|
516
523
|
'milestone_audit': [{ cmd: 'maestro-milestone-audit' }],
|
|
517
524
|
'milestone_complete': [{ cmd: 'maestro-milestone-complete' }],
|
|
518
525
|
'codebase_rebuild': [{ cmd: 'manage-codebase-rebuild' }],
|
|
@@ -529,6 +536,8 @@ const chainMap = {
|
|
|
529
536
|
'issue_execute': [{ cmd: 'manage-issue-execute', args: '"{description}"' }],
|
|
530
537
|
'memory': [{ cmd: 'manage-memory', args: '"{description}"' }],
|
|
531
538
|
'quick': [{ cmd: 'maestro-quick', args: '"{description}"' }],
|
|
539
|
+
'fork': [{ cmd: 'maestro-fork', args: '-m {milestone_num}' }],
|
|
540
|
+
'merge': [{ cmd: 'maestro-merge', args: '-m {milestone_num}' }],
|
|
532
541
|
|
|
533
542
|
// Team skills (independent, single-step)
|
|
534
543
|
'team_lifecycle': [{ cmd: 'team-lifecycle-v4', args: '"{description}"' }],
|
|
@@ -547,7 +556,7 @@ const chainMap = {
|
|
|
547
556
|
{ cmd: 'maestro-verify', args: '{phase}' },
|
|
548
557
|
{ cmd: 'quality-review', args: '{phase}' },
|
|
549
558
|
{ cmd: 'quality-test', args: '{phase}' },
|
|
550
|
-
{ cmd: 'maestro-
|
|
559
|
+
{ cmd: 'maestro-milestone-audit' }
|
|
551
560
|
],
|
|
552
561
|
'spec-driven': [
|
|
553
562
|
{ cmd: 'maestro-init' },
|
|
@@ -637,7 +646,7 @@ Cross-validate intent against project state:
|
|
|
637
646
|
- Intent says `execute` but phase has no plan → warn, prepend `maestro-plan`
|
|
638
647
|
- Intent says `verify` but phase not executed → warn, prepend `maestro-execute`
|
|
639
648
|
- Intent says `test` but phase not verified → warn, prepend `maestro-verify`
|
|
640
|
-
- Intent says `
|
|
649
|
+
- Intent says `milestone_close` but not all phases executed → warn, suggest completing execution first
|
|
641
650
|
|
|
642
651
|
Display warning but let user override.
|
|
643
652
|
|
|
@@ -661,10 +670,10 @@ function resolvePhase(intent_analysis, project_state) {
|
|
|
661
670
|
// 5. Chain doesn't need phase (init, status, memory, issue, etc.)
|
|
662
671
|
const noPhaseCommands = ['manage-status', 'manage-issue', 'manage-issue-discover',
|
|
663
672
|
'manage-issue-analyze', 'manage-issue-plan', 'manage-issue-execute',
|
|
664
|
-
'maestro-init', 'maestro-spec-generate',
|
|
673
|
+
'maestro-init', 'maestro-spec-generate', 'maestro-fork', 'maestro-merge',
|
|
665
674
|
'maestro-roadmap', 'spec-setup', 'manage-memory', 'manage-memory-capture', 'manage-learn',
|
|
666
675
|
'manage-codebase-rebuild', 'manage-codebase-refresh', 'maestro-milestone-audit',
|
|
667
|
-
'maestro-milestone-complete', 'maestro-
|
|
676
|
+
'maestro-milestone-complete', 'maestro-milestone-audit'];
|
|
668
677
|
if (chain.every(s => noPhaseCommands.includes(s.cmd))) return null;
|
|
669
678
|
|
|
670
679
|
// 6. Ask user
|
|
@@ -819,6 +828,14 @@ function assembleArgs(step, context) {
|
|
|
819
828
|
Args: {assembled_args}
|
|
820
829
|
```
|
|
821
830
|
|
|
831
|
+
**7a-1. Context cleanup hint (after step 3+):**
|
|
832
|
+
|
|
833
|
+
If `i >= 3` and not `$AUTO_MODE`:
|
|
834
|
+
```
|
|
835
|
+
⚡ 已执行 {i} 步,上下文较重。可随时 /maestro -c 在新上下文中恢复。
|
|
836
|
+
```
|
|
837
|
+
If `$AUTO_MODE` and `i >= 4`: log one-line warning to status.json, continue.
|
|
838
|
+
|
|
822
839
|
**7b. Update status.json:** Set step status = `"running"`, started_at = now.
|
|
823
840
|
|
|
824
841
|
**7c. Execute via Skill():**
|
|
@@ -886,7 +903,7 @@ Display completion report:
|
|
|
886
903
|
|
|
887
904
|
| Chain | Steps | Use Case |
|
|
888
905
|
|-------|-------|----------|
|
|
889
|
-
| `full-lifecycle` | plan → execute → verify → review → test →
|
|
906
|
+
| `full-lifecycle` | plan → execute → verify → review → test → milestone-audit → milestone-complete | Full milestone completion |
|
|
890
907
|
| `spec-driven` | init → spec-generate → plan → execute → verify | Start from idea/requirements (heavy path) |
|
|
891
908
|
| `roadmap-driven` | init → maestro-roadmap → plan → execute → verify | Start from requirements (light path) |
|
|
892
909
|
| `brainstorm-driven` | brainstorm → plan → execute → verify | Start from exploration |
|
|
@@ -931,7 +948,7 @@ Shows how structured extraction routes common inputs — especially cases where
|
|
|
931
948
|
| `"复盘 phase 2"` | `{retrospect, phase}` | retrospective | quality-retrospective |
|
|
932
949
|
| `"team review code"` | `{review, team}` | team_review | team-review |
|
|
933
950
|
| `"team qa full scan"` | `{analyze, team}` | team_qa | team-quality-assurance |
|
|
934
|
-
| `"next phase"` | `{transition,
|
|
951
|
+
| `"next phase"` | `{transition, milestone}` | milestone_close | maestro-milestone-audit → milestone-complete |
|
|
935
952
|
| `"milestone audit"` | `{manage, milestone}` | milestone_audit | maestro-milestone-audit |
|
|
936
953
|
| `-y "implement feature X"` | `{execute, feature}` | execute | maestro-execute (auto mode) |
|
|
937
954
|
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
# Workflow: merge
|
|
2
|
+
|
|
3
|
+
Two-phase merge of a completed milestone worktree branch back into main. Phase 1: git merge (source code). Phase 2: artifact sync (workflow state). Artifact sync only proceeds after successful git merge.
|
|
4
|
+
|
|
5
|
+
Merges operate at the **milestone level** — one worktree per milestone, all phases merged together.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Step 1: Parse Arguments and Flags
|
|
10
|
+
|
|
11
|
+
```javascript
|
|
12
|
+
const getUtc8ISOString = () => new Date(Date.now() + 8 * 60 * 60 * 1000).toISOString()
|
|
13
|
+
|
|
14
|
+
const force = $ARGUMENTS.includes('--force')
|
|
15
|
+
const dryRun = $ARGUMENTS.includes('--dry-run')
|
|
16
|
+
const noCleanup = $ARGUMENTS.includes('--no-cleanup')
|
|
17
|
+
const continueMode = $ARGUMENTS.includes('--continue')
|
|
18
|
+
|
|
19
|
+
// Parse milestone number: -m <N> or bare <N>
|
|
20
|
+
const mFlagMatch = $ARGUMENTS.match(/-m\s+(\d+)/)
|
|
21
|
+
const cleaned = $ARGUMENTS
|
|
22
|
+
.replace(/--force|--dry-run|--no-cleanup|--continue|-m\s+\d+/g, '')
|
|
23
|
+
.trim()
|
|
24
|
+
const bareNumMatch = cleaned.match(/^(\d+)$/)
|
|
25
|
+
const milestoneNum = mFlagMatch
|
|
26
|
+
? parseInt(mFlagMatch[1])
|
|
27
|
+
: bareNumMatch
|
|
28
|
+
? parseInt(bareNumMatch[1])
|
|
29
|
+
: null
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Step 2: Validate Context
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
IF file_exists(".workflow/worktree-scope.json"):
|
|
38
|
+
ERROR E001: "Cannot merge from inside a worktree. Run from the main worktree."
|
|
39
|
+
EXIT
|
|
40
|
+
|
|
41
|
+
IF NOT file_exists(".workflow/worktrees.json"):
|
|
42
|
+
ERROR E002: "No worktree registry found. Nothing to merge."
|
|
43
|
+
EXIT
|
|
44
|
+
|
|
45
|
+
Read .workflow/worktrees.json → registry
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Step 3: Registry Health Check
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
staleEntries = []
|
|
54
|
+
for (entry of registry.worktrees):
|
|
55
|
+
IF NOT directory_exists(entry.path):
|
|
56
|
+
staleEntries.push(entry)
|
|
57
|
+
|
|
58
|
+
IF staleEntries.length > 0:
|
|
59
|
+
WARN W001: "Found {staleEntries.length} stale worktree entries (directories missing):"
|
|
60
|
+
for (entry of staleEntries):
|
|
61
|
+
Display " M{entry.milestone_num} ({entry.milestone}): {entry.path} — MISSING"
|
|
62
|
+
registry.worktrees = registry.worktrees.filter(w => !staleEntries.includes(w))
|
|
63
|
+
Write .workflow/worktrees.json: registry
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## Step 4: Resolve Merge Target
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
IF continueMode:
|
|
72
|
+
IF NOT file_exists(".workflow/.merge-state.json"):
|
|
73
|
+
ERROR E003: "--continue but no merge state found. Start a fresh merge."
|
|
74
|
+
EXIT
|
|
75
|
+
Read .workflow/.merge-state.json → mergeState
|
|
76
|
+
target = mergeState.target
|
|
77
|
+
GOTO Step_7
|
|
78
|
+
|
|
79
|
+
ELSE IF milestoneNum !== null:
|
|
80
|
+
target = registry.worktrees.find(w =>
|
|
81
|
+
w.milestone_num === milestoneNum && w.status === "active"
|
|
82
|
+
)
|
|
83
|
+
ELSE:
|
|
84
|
+
ERROR E004: "Milestone number required. Usage: maestro-merge -m <number>"
|
|
85
|
+
EXIT
|
|
86
|
+
|
|
87
|
+
IF NOT target:
|
|
88
|
+
activeList = registry.worktrees
|
|
89
|
+
.filter(w => w.status === "active")
|
|
90
|
+
.map(w => " M" + w.milestone_num + ": " + w.milestone + " (" + w.path + ")")
|
|
91
|
+
.join("\n")
|
|
92
|
+
Display "No active worktree for milestone {milestoneNum}."
|
|
93
|
+
IF activeList:
|
|
94
|
+
Display "Active worktrees:\n{activeList}"
|
|
95
|
+
EXIT
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## Step 5: Validate Readiness
|
|
101
|
+
|
|
102
|
+
```
|
|
103
|
+
completedPhases = []
|
|
104
|
+
incompletePhases = []
|
|
105
|
+
|
|
106
|
+
for (phaseNum of target.owned_phases):
|
|
107
|
+
NN = String(phaseNum).padStart(2, '0')
|
|
108
|
+
Glob: {target.path}/.workflow/phases/{NN}-*/index.json
|
|
109
|
+
Read → wtIndex
|
|
110
|
+
|
|
111
|
+
IF wtIndex.status === "completed":
|
|
112
|
+
completedPhases.push({ phase: phaseNum, index: wtIndex })
|
|
113
|
+
ELSE:
|
|
114
|
+
incompletePhases.push({ phase: phaseNum, status: wtIndex.status })
|
|
115
|
+
|
|
116
|
+
IF incompletePhases.length > 0 AND NOT force:
|
|
117
|
+
WARN W002: "M{target.milestone_num} ({target.milestone}) has incomplete phases:"
|
|
118
|
+
for (p of incompletePhases):
|
|
119
|
+
Display " Phase {p.phase}: {p.status}"
|
|
120
|
+
IF NOT dryRun:
|
|
121
|
+
AskUserQuestion: "Merge anyway? (y/n, or use --force)"
|
|
122
|
+
IF response !== 'y': EXIT
|
|
123
|
+
|
|
124
|
+
IF dryRun:
|
|
125
|
+
Display "=== DRY RUN ==="
|
|
126
|
+
Display " Would merge: {target.branch} → current branch"
|
|
127
|
+
Display " Milestone: M{target.milestone_num} ({target.milestone})"
|
|
128
|
+
Display " Completed: {completedPhases.map(p => p.phase).join(', ')}"
|
|
129
|
+
Display " Incomplete: {incompletePhases.map(p => p.phase + '(' + p.status + ')').join(', ')}"
|
|
130
|
+
EXIT
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## Step 6: Phase 1 — Git Merge
|
|
136
|
+
|
|
137
|
+
```
|
|
138
|
+
Display "=== Merging M{target.milestone_num}: {target.milestone} ==="
|
|
139
|
+
|
|
140
|
+
// 6a: Pre-merge rebase
|
|
141
|
+
Display "Pulling main into worktree branch..."
|
|
142
|
+
rebaseResult = Bash("cd {target.path} && git merge main --no-edit 2>&1")
|
|
143
|
+
|
|
144
|
+
IF rebaseResult.exitCode !== 0:
|
|
145
|
+
WARN W003: "Conflict pulling main into worktree. Resolve in {target.path} first."
|
|
146
|
+
Display rebaseResult.output
|
|
147
|
+
Display "After resolving: cd {target.path} && git merge --continue"
|
|
148
|
+
Display "Then retry: /maestro-merge -m {target.milestone_num}"
|
|
149
|
+
EXIT
|
|
150
|
+
|
|
151
|
+
// 6b: Merge worktree branch into main
|
|
152
|
+
Display "Merging {target.branch} into current branch..."
|
|
153
|
+
mergeResult = Bash("git merge {target.branch} --no-ff -m 'merge: M{target.milestone_num} {target.milestone}' 2>&1")
|
|
154
|
+
|
|
155
|
+
IF mergeResult.exitCode !== 0:
|
|
156
|
+
Display "MERGE CONFLICT detected."
|
|
157
|
+
Display mergeResult.output
|
|
158
|
+
|
|
159
|
+
Write .workflow/.merge-state.json:
|
|
160
|
+
{
|
|
161
|
+
"target": target,
|
|
162
|
+
"phase": "git_merge_conflict",
|
|
163
|
+
"created_at": getUtc8ISOString()
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
Display ""
|
|
167
|
+
Display "Resolve conflicts, then:"
|
|
168
|
+
Display " git add <resolved-files> && git merge --continue"
|
|
169
|
+
Display " /maestro-merge --continue"
|
|
170
|
+
EXIT
|
|
171
|
+
|
|
172
|
+
Display "Git merge successful."
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
---
|
|
176
|
+
|
|
177
|
+
## Step 7: Phase 2 — Artifact Sync
|
|
178
|
+
|
|
179
|
+
```
|
|
180
|
+
Step_7:
|
|
181
|
+
|
|
182
|
+
Display "Syncing workflow artifacts for M{target.milestone_num} ({target.milestone})..."
|
|
183
|
+
|
|
184
|
+
// 7a: Copy all owned phase directories from worktree to main
|
|
185
|
+
for (phaseNum of target.owned_phases):
|
|
186
|
+
NN = String(phaseNum).padStart(2, '0')
|
|
187
|
+
Glob: {target.path}/.workflow/phases/{NN}-*/
|
|
188
|
+
phaseDir = matched directory name
|
|
189
|
+
|
|
190
|
+
srcDir = target.path + "/.workflow/phases/" + phaseDir + "/"
|
|
191
|
+
dstDir = ".workflow/phases/" + phaseDir + "/"
|
|
192
|
+
|
|
193
|
+
Bash("cp -r {srcDir}* {dstDir}")
|
|
194
|
+
|
|
195
|
+
// 7b: Atomic state reconciliation
|
|
196
|
+
Read .workflow/state.json → mainState
|
|
197
|
+
|
|
198
|
+
for (phaseNum of target.owned_phases):
|
|
199
|
+
NN = String(phaseNum).padStart(2, '0')
|
|
200
|
+
Glob: .workflow/phases/{NN}-*/index.json
|
|
201
|
+
Read → phaseIndex
|
|
202
|
+
|
|
203
|
+
IF phaseIndex.status === "completed":
|
|
204
|
+
mainState.phases_summary.completed += 1
|
|
205
|
+
mainState.phases_summary.pending -= 1
|
|
206
|
+
IF mainState.phases_summary.pending < 0:
|
|
207
|
+
mainState.phases_summary.pending = 0
|
|
208
|
+
|
|
209
|
+
mainState.transition_history = mainState.transition_history ?? []
|
|
210
|
+
mainState.transition_history.push({
|
|
211
|
+
milestone_num: target.milestone_num,
|
|
212
|
+
milestone: target.milestone,
|
|
213
|
+
phase: phaseNum,
|
|
214
|
+
action: "worktree_merge",
|
|
215
|
+
completed_at: phaseIndex.completed_at ?? getUtc8ISOString(),
|
|
216
|
+
branch: target.branch
|
|
217
|
+
})
|
|
218
|
+
ELSE IF phaseIndex.status !== "forked":
|
|
219
|
+
mainState.phases_summary.in_progress += 1
|
|
220
|
+
mainState.phases_summary.pending -= 1
|
|
221
|
+
IF mainState.phases_summary.pending < 0:
|
|
222
|
+
mainState.phases_summary.pending = 0
|
|
223
|
+
|
|
224
|
+
phaseIndex.updated_at = getUtc8ISOString()
|
|
225
|
+
Write .workflow/phases/{NN}-{slug}/index.json: phaseIndex
|
|
226
|
+
|
|
227
|
+
// Merge accumulated context from worktree
|
|
228
|
+
Read target.path + "/.workflow/state.json" → wtState (if exists)
|
|
229
|
+
IF wtState?.accumulated_context:
|
|
230
|
+
for (decision of (wtState.accumulated_context.key_decisions ?? [])):
|
|
231
|
+
IF NOT mainState.accumulated_context.key_decisions.includes(decision):
|
|
232
|
+
mainState.accumulated_context.key_decisions.push(decision)
|
|
233
|
+
for (deferred of (wtState.accumulated_context.deferred ?? [])):
|
|
234
|
+
mainState.accumulated_context.deferred.push(deferred)
|
|
235
|
+
|
|
236
|
+
mainState.last_updated = getUtc8ISOString()
|
|
237
|
+
Write .workflow/state.json: mainState
|
|
238
|
+
|
|
239
|
+
// 7c: Update roadmap.md
|
|
240
|
+
Read .workflow/roadmap.md → roadmap
|
|
241
|
+
for (phaseNum of target.owned_phases):
|
|
242
|
+
Read phase index → check if completed
|
|
243
|
+
IF completed:
|
|
244
|
+
Append " ✅ COMPLETED" to phase title line
|
|
245
|
+
Write .workflow/roadmap.md: roadmap
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
---
|
|
249
|
+
|
|
250
|
+
## Step 8: Cleanup
|
|
251
|
+
|
|
252
|
+
```
|
|
253
|
+
IF NOT noCleanup:
|
|
254
|
+
Display "Cleaning up worktree..."
|
|
255
|
+
Bash("git worktree remove --force {target.path}")
|
|
256
|
+
Bash("git branch -D {target.branch}")
|
|
257
|
+
|
|
258
|
+
registry.worktrees = registry.worktrees.filter(w =>
|
|
259
|
+
!(w.milestone_num === target.milestone_num && w.branch === target.branch)
|
|
260
|
+
)
|
|
261
|
+
Write .workflow/worktrees.json: registry
|
|
262
|
+
|
|
263
|
+
IF file_exists(".workflow/.merge-state.json"):
|
|
264
|
+
Bash("rm .workflow/.merge-state.json")
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
---
|
|
268
|
+
|
|
269
|
+
## Step 9: Summary
|
|
270
|
+
|
|
271
|
+
```
|
|
272
|
+
Display:
|
|
273
|
+
=== MERGE COMPLETE ===
|
|
274
|
+
Milestone: M{target.milestone_num} — {target.milestone}
|
|
275
|
+
Branch: {target.branch}
|
|
276
|
+
Phases: {target.owned_phases.join(', ')}
|
|
277
|
+
Completed: {completedPhases.length}/{target.owned_phases.length}
|
|
278
|
+
|
|
279
|
+
State: .workflow/state.json updated
|
|
280
|
+
Roadmap: .workflow/roadmap.md updated
|
|
281
|
+
|
|
282
|
+
Next steps:
|
|
283
|
+
Skill({ skill: "manage-status" }) -- View dashboard
|
|
284
|
+
Skill({ skill: "maestro-milestone-audit" }) -- Audit merged milestone
|
|
285
|
+
```
|