maestro-flow 0.3.7 → 0.3.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (254) hide show
  1. package/.claude/commands/learn-decompose.md +3 -3
  2. package/.claude/commands/learn-follow.md +5 -5
  3. package/.claude/commands/learn-investigate.md +3 -3
  4. package/.claude/commands/learn-retro.md +303 -0
  5. package/.claude/commands/learn-second-opinion.md +3 -3
  6. package/.claude/commands/maestro-analyze.md +123 -99
  7. package/.claude/commands/maestro-brainstorm.md +2 -2
  8. package/.claude/commands/maestro-execute.md +137 -96
  9. package/.claude/commands/maestro-fork.md +111 -0
  10. package/.claude/commands/maestro-init.md +6 -6
  11. package/.claude/commands/maestro-learn.md +74 -298
  12. package/.claude/commands/maestro-merge.md +77 -0
  13. package/.claude/commands/maestro-milestone-audit.md +72 -60
  14. package/.claude/commands/maestro-milestone-complete.md +67 -59
  15. package/.claude/commands/maestro-milestone-release.md +6 -6
  16. package/.claude/commands/maestro-plan.md +151 -130
  17. package/.claude/commands/maestro-quick.md +4 -4
  18. package/.claude/commands/maestro-roadmap.md +5 -5
  19. package/.claude/commands/maestro-spec-generate.md +5 -5
  20. package/.claude/commands/maestro-ui-design.md +3 -3
  21. package/.claude/commands/maestro-verify.md +106 -87
  22. package/.claude/commands/maestro.md +10 -4
  23. package/.claude/commands/manage-codebase-rebuild.md +4 -4
  24. package/.claude/commands/manage-codebase-refresh.md +1 -1
  25. package/.claude/commands/manage-harvest.md +5 -5
  26. package/.claude/commands/manage-issue-discover.md +1 -1
  27. package/.claude/commands/manage-issue-execute.md +6 -6
  28. package/.claude/commands/manage-issue.md +6 -6
  29. package/.claude/commands/manage-learn.md +23 -17
  30. package/.claude/commands/manage-memory-capture.md +15 -17
  31. package/.claude/commands/manage-memory.md +3 -3
  32. package/.claude/commands/manage-status.md +24 -24
  33. package/.claude/commands/quality-business-test.md +5 -5
  34. package/.claude/commands/quality-debug.md +4 -4
  35. package/.claude/commands/quality-integration-test.md +4 -4
  36. package/.claude/commands/quality-refactor.md +3 -3
  37. package/.claude/commands/quality-retrospective.md +7 -7
  38. package/.claude/commands/quality-review.md +4 -4
  39. package/.claude/commands/quality-sync.md +3 -3
  40. package/.claude/commands/quality-test-gen.md +4 -4
  41. package/.claude/commands/quality-test.md +9 -9
  42. package/.claude/commands/spec-add.md +2 -2
  43. package/.claude/commands/spec-load.md +8 -3
  44. package/.claude/commands/spec-setup.md +5 -5
  45. package/.claude/commands/wiki-connect.md +3 -3
  46. package/.claude/commands/wiki-digest.md +30 -5
  47. package/.codex/skills/maestro-analyze/SKILL.md +52 -14
  48. package/.codex/skills/maestro-execute/SKILL.md +27 -26
  49. package/.codex/skills/maestro-milestone-audit/SKILL.md +103 -209
  50. package/.codex/skills/maestro-milestone-complete/SKILL.md +149 -158
  51. package/.codex/skills/maestro-plan/SKILL.md +47 -17
  52. package/.codex/skills/maestro-roadmap/SKILL.md +3 -2
  53. package/.codex/skills/team-coordinate/roles/coordinator/commands/monitor.md +2 -2
  54. package/.codex/skills/team-executor/roles/executor/commands/monitor.md +1 -1
  55. package/.codex/skills/team-lifecycle-v4/roles/coordinator/commands/monitor.md +2 -2
  56. package/.codex/skills/team-lifecycle-v4/specs/knowledge-transfer.md +2 -2
  57. package/.codex/skills/team-quality-assurance/roles/coordinator/commands/monitor.md +1 -1
  58. package/.codex/skills/team-review/roles/coordinator/commands/monitor.md +1 -1
  59. package/.codex/skills/team-tech-debt/roles/coordinator/commands/monitor.md +1 -1
  60. package/.codex/skills/team-testing/roles/coordinator/commands/monitor.md +1 -1
  61. package/README.md +115 -227
  62. package/README.zh-CN.md +169 -187
  63. package/bin/maestro-mcp.js +1 -1
  64. package/chains/_intent-map.json +21 -9
  65. package/chains/_router.json +30 -77
  66. package/chains/brainstorm-driven.json +17 -6
  67. package/chains/full-lifecycle.json +22 -23
  68. package/chains/milestone-close.json +20 -7
  69. package/chains/milestone-fork-merge.json +50 -0
  70. package/chains/roadmap-driven.json +17 -6
  71. package/chains/spec-driven.json +17 -6
  72. package/dashboard/dist/assets/{ArtifactsPage-A9yzYtpj.js → ArtifactsPage-DZNCi6tn.js} +12 -7
  73. package/dashboard/dist/assets/ChatInput-Bvr-FeEq.js +49 -0
  74. package/dashboard/dist/assets/ChatPage-D9zTkJZo.js +22 -0
  75. package/dashboard/dist/assets/CollabPage-B4NAHXS2.js +1 -0
  76. package/dashboard/dist/assets/ExecutionPanel-CFt4LJyq.js +1 -0
  77. package/dashboard/dist/assets/KanbanPage-C8USth6H.js +21 -0
  78. package/dashboard/dist/assets/{MarkdownRenderer-CCXHaut3.js → MarkdownRenderer-X4af_WNb.js} +1 -1
  79. package/dashboard/dist/assets/McpPage-BKfCVIyU.js +21 -0
  80. package/dashboard/dist/assets/OutputPanel-BlBQFJSW.js +1 -0
  81. package/dashboard/dist/assets/ProblemsPanel-De3DLvoI.js +1 -0
  82. package/dashboard/dist/assets/{RequirementBoardPage-CEOvppGn.js → RequirementBoardPage-Bf1trzqs.js} +2 -2
  83. package/dashboard/dist/assets/{RequirementPage-DpnbTEqY.js → RequirementPage-Bllxe2XI.js} +10 -5
  84. package/dashboard/dist/assets/{SpecsPage-CYqOfFkB.js → SpecsPage-9lwxKT27.js} +2 -2
  85. package/dashboard/dist/assets/{SupervisorPage-B2sZwkq8.js → SupervisorPage-SusdfHFq.js} +1 -1
  86. package/dashboard/dist/assets/{TeamsPage-CkZdCAVZ.js → TeamsPage-DsuM6OwC.js} +2 -2
  87. package/dashboard/dist/assets/TreeBrowser-Q12qobZs.js +6 -0
  88. package/dashboard/dist/assets/WorkflowPage-D_Fzdy3_.js +6 -0
  89. package/dashboard/dist/assets/{arrow-left-6fktHyjN.js → arrow-left-Bqtb2hle.js} +1 -1
  90. package/dashboard/dist/assets/{check-Cbxq2l1-.js → check-u6fGOwQO.js} +1 -1
  91. package/dashboard/dist/assets/{chevron-right-Yts3bi8p.js → chevron-right-Csu22t58.js} +1 -1
  92. package/dashboard/dist/assets/{circle-4Ci4Xolf.js → circle-CMrkbRNg.js} +1 -1
  93. package/dashboard/dist/assets/{circle-alert-B25g9BTL.js → circle-alert-c3tH1P4z.js} +1 -1
  94. package/dashboard/dist/assets/{circle-check-big-DzO2BlL7.js → circle-check-big-TDSeWstm.js} +1 -1
  95. package/dashboard/dist/assets/{circle-check-BA5_XqeV.js → circle-check-gYxxSYuH.js} +1 -1
  96. package/dashboard/dist/assets/{code-zxwuybO8.js → code-CFN2uX9V.js} +1 -1
  97. package/dashboard/dist/assets/{columns-3-DV4oeCfU.js → columns-3-38xIDlzy.js} +1 -1
  98. package/dashboard/dist/assets/{download-CXCyQw8M.js → download-DC7KkKyP.js} +1 -1
  99. package/dashboard/dist/assets/{folder-Bvjj8Vn9.js → folder-CWq_lAnf.js} +1 -1
  100. package/dashboard/dist/assets/index-DWG-WrzT.js +231 -0
  101. package/dashboard/dist/assets/{index-BvScJmJM.js → index-Do71weNR.js} +1 -1
  102. package/dashboard/dist/assets/index-GUNJodSR.css +1 -0
  103. package/dashboard/dist/assets/{list-Dj4i9N75.js → list-CgIP_2A-.js} +1 -1
  104. package/dashboard/dist/assets/{minus-DwlFabsT.js → minus-DYoN5UGk.js} +1 -1
  105. package/dashboard/dist/assets/{pen-line-D7UzECt6.js → pen-line-Bh_WKYHm.js} +1 -1
  106. package/dashboard/dist/assets/{proxy-B9XRqHD9.js → proxy-BKxDAKTj.js} +1 -1
  107. package/dashboard/dist/assets/{search-BQbBTIYl.js → search-SieXnOgr.js} +1 -1
  108. package/dashboard/dist/assets/{shallow-Clb1Lyd_.js → shallow-Bme1JY57.js} +1 -1
  109. package/dashboard/dist/assets/{table-BqxCXid2.js → table-llyEtj-7.js} +1 -1
  110. package/dashboard/dist/assets/terminal-BB3Xfuv5.js +6 -0
  111. package/dashboard/dist/assets/{trash-2-6rN9B-EQ.js → trash-2-C8f4vFFM.js} +1 -1
  112. package/dashboard/dist/assets/{zap-DxUhG-gk.js → zap-4uwlzVm0.js} +1 -1
  113. package/dashboard/dist/index.html +2 -2
  114. package/dashboard/dist-server/dashboard/src/server/agents/agent-sdk-adapter.d.ts +1 -1
  115. package/dashboard/dist-server/dashboard/src/server/agents/agent-sdk-adapter.js +5 -4
  116. package/dashboard/dist-server/dashboard/src/server/agents/agent-sdk-adapter.js.map +1 -1
  117. package/dashboard/dist-server/dashboard/src/server/agents/claude-code-adapter.js +8 -4
  118. package/dashboard/dist-server/dashboard/src/server/agents/claude-code-adapter.js.map +1 -1
  119. package/dashboard/dist-server/dashboard/src/server/agents/entry-normalizer.d.ts +1 -0
  120. package/dashboard/dist-server/dashboard/src/server/agents/entry-normalizer.js +2 -1
  121. package/dashboard/dist-server/dashboard/src/server/agents/entry-normalizer.js.map +1 -1
  122. package/dashboard/dist-server/dashboard/src/server/agents/stream-json-adapter.js +20 -10
  123. package/dashboard/dist-server/dashboard/src/server/agents/stream-json-adapter.js.map +1 -1
  124. package/dashboard/dist-server/dashboard/src/server/agents/tools/issue-mcp-server.d.ts +1 -1
  125. package/dashboard/dist-server/dashboard/src/server/agents/tools/issue-mcp-server.js +3 -4
  126. package/dashboard/dist-server/dashboard/src/server/agents/tools/issue-mcp-server.js.map +1 -1
  127. package/dashboard/dist-server/dashboard/src/server/agents/tools/issue-mcp-server.test.js +4 -4
  128. package/dashboard/dist-server/dashboard/src/server/agents/tools/issue-mcp-server.test.js.map +1 -1
  129. package/dashboard/dist-server/dashboard/src/server/commander/commander-agent.js +4 -3
  130. package/dashboard/dist-server/dashboard/src/server/commander/commander-agent.js.map +1 -1
  131. package/dashboard/dist-server/dashboard/src/server/commander/commander-agent.test.js +20 -7
  132. package/dashboard/dist-server/dashboard/src/server/commander/commander-agent.test.js.map +1 -1
  133. package/dashboard/dist-server/dashboard/src/server/execution/wave-executor.d.ts +1 -1
  134. package/dashboard/dist-server/dashboard/src/server/execution/wave-executor.js +4 -4
  135. package/dashboard/dist-server/dashboard/src/server/execution/wave-executor.js.map +1 -1
  136. package/dashboard/dist-server/dashboard/src/server/index.js +2 -1
  137. package/dashboard/dist-server/dashboard/src/server/index.js.map +1 -1
  138. package/dashboard/dist-server/dashboard/src/server/routes/git.d.ts +2 -0
  139. package/dashboard/dist-server/dashboard/src/server/routes/git.js +79 -0
  140. package/dashboard/dist-server/dashboard/src/server/routes/git.js.map +1 -0
  141. package/dashboard/dist-server/dashboard/src/server/routes/index.js +3 -0
  142. package/dashboard/dist-server/dashboard/src/server/routes/index.js.map +1 -1
  143. package/dashboard/dist-server/dashboard/src/server/routes/issues.js +14 -14
  144. package/dashboard/dist-server/dashboard/src/server/routes/issues.js.map +1 -1
  145. package/dashboard/dist-server/dashboard/src/server/routes/linear.js +7 -5
  146. package/dashboard/dist-server/dashboard/src/server/routes/linear.js.map +1 -1
  147. package/dashboard/dist-server/dashboard/src/server/routes/workspace.js +43 -0
  148. package/dashboard/dist-server/dashboard/src/server/routes/workspace.js.map +1 -1
  149. package/dashboard/dist-server/dashboard/src/server/state/state-manager.js +186 -25
  150. package/dashboard/dist-server/dashboard/src/server/state/state-manager.js.map +1 -1
  151. package/dashboard/dist-server/dashboard/src/server/utils/issue-store.d.ts +6 -0
  152. package/dashboard/dist-server/dashboard/src/server/utils/issue-store.js +24 -2
  153. package/dashboard/dist-server/dashboard/src/server/utils/issue-store.js.map +1 -1
  154. package/dashboard/dist-server/dashboard/src/server/ws/handlers/execution-handler.js +4 -7
  155. package/dashboard/dist-server/dashboard/src/server/ws/handlers/execution-handler.js.map +1 -1
  156. package/dashboard/dist-server/dashboard/src/shared/constants.js +2 -1
  157. package/dashboard/dist-server/dashboard/src/shared/constants.js.map +1 -1
  158. package/dashboard/dist-server/dashboard/src/shared/constants.test.js +5 -5
  159. package/dashboard/dist-server/dashboard/src/shared/constants.test.js.map +1 -1
  160. package/dashboard/dist-server/dashboard/src/shared/issue-types.test.js +4 -4
  161. package/dashboard/dist-server/dashboard/src/shared/issue-types.test.js.map +1 -1
  162. package/dashboard/dist-server/src/commands/delegate.js +7 -1
  163. package/dashboard/dist-server/src/commands/delegate.js.map +1 -1
  164. package/dashboard/package.json +59 -59
  165. package/dist/src/cli.js +3 -1
  166. package/dist/src/cli.js.map +1 -1
  167. package/dist/src/commands/{team.d.ts → collab.d.ts} +2 -2
  168. package/dist/src/commands/collab.d.ts.map +1 -0
  169. package/dist/src/commands/{team.js → collab.js} +391 -24
  170. package/dist/src/commands/collab.js.map +1 -0
  171. package/dist/src/commands/delegate.d.ts.map +1 -1
  172. package/dist/src/commands/delegate.js +7 -1
  173. package/dist/src/commands/delegate.js.map +1 -1
  174. package/dist/src/commands/msg.d.ts.map +1 -1
  175. package/dist/src/commands/msg.js +4 -3
  176. package/dist/src/commands/msg.js.map +1 -1
  177. package/dist/src/hooks/team-monitor.d.ts.map +1 -1
  178. package/dist/src/hooks/team-monitor.js +16 -0
  179. package/dist/src/hooks/team-monitor.js.map +1 -1
  180. package/dist/src/tools/collab-adapter.d.ts +85 -0
  181. package/dist/src/tools/collab-adapter.d.ts.map +1 -0
  182. package/dist/src/tools/collab-adapter.js +320 -0
  183. package/dist/src/tools/collab-adapter.js.map +1 -0
  184. package/dist/src/tools/namespace-guard.d.ts +2 -0
  185. package/dist/src/tools/namespace-guard.d.ts.map +1 -1
  186. package/dist/src/tools/namespace-guard.js +12 -0
  187. package/dist/src/tools/namespace-guard.js.map +1 -1
  188. package/dist/src/tools/phase-gate-evaluator.d.ts +45 -0
  189. package/dist/src/tools/phase-gate-evaluator.d.ts.map +1 -0
  190. package/dist/src/tools/phase-gate-evaluator.js +42 -0
  191. package/dist/src/tools/phase-gate-evaluator.js.map +1 -0
  192. package/dist/src/tools/team-members.d.ts +18 -0
  193. package/dist/src/tools/team-members.d.ts.map +1 -1
  194. package/dist/src/tools/team-members.js +50 -0
  195. package/dist/src/tools/team-members.js.map +1 -1
  196. package/dist/src/tools/team-tasks.d.ts +120 -0
  197. package/dist/src/tools/team-tasks.d.ts.map +1 -0
  198. package/dist/src/tools/team-tasks.js +365 -0
  199. package/dist/src/tools/team-tasks.js.map +1 -0
  200. package/dist/src/tools/transition-recorder.d.ts +3 -0
  201. package/dist/src/tools/transition-recorder.d.ts.map +1 -1
  202. package/dist/src/tools/transition-recorder.js +52 -1
  203. package/dist/src/tools/transition-recorder.js.map +1 -1
  204. package/dist/src/utils/get-version.d.ts.map +1 -1
  205. package/dist/src/utils/get-version.js +15 -4
  206. package/dist/src/utils/get-version.js.map +1 -1
  207. package/package.json +1 -1
  208. package/templates/config.json +7 -0
  209. package/templates/worktree-scope.json +10 -0
  210. package/templates/worktrees.json +27 -0
  211. package/workflows/analyze.md +86 -36
  212. package/workflows/brainstorm.md +17 -37
  213. package/workflows/delegate-usage.md +39 -41
  214. package/workflows/execute.md +247 -61
  215. package/workflows/fork.md +309 -0
  216. package/workflows/init.md +11 -2
  217. package/workflows/issue.md +66 -7
  218. package/workflows/maestro-coordinate.codex.md +1 -1
  219. package/workflows/maestro-coordinate.md +24 -17
  220. package/workflows/maestro.md +54 -37
  221. package/workflows/memory.md +2 -1
  222. package/workflows/merge.md +285 -0
  223. package/workflows/milestone-audit.md +89 -70
  224. package/workflows/milestone-complete.md +89 -156
  225. package/workflows/plan.md +131 -19
  226. package/workflows/retrospective.md +5 -5
  227. package/workflows/roadmap.md +12 -4
  228. package/workflows/spec-generate.md +9 -0
  229. package/workflows/status.md +76 -27
  230. package/workflows/ui-design.md +14 -12
  231. package/workflows/verify.md +44 -8
  232. package/.claude/commands/learn-retro-decision.md +0 -198
  233. package/.claude/commands/learn-retro-git.md +0 -160
  234. package/.claude/commands/maestro-phase-add.md +0 -63
  235. package/.claude/commands/maestro-phase-transition.md +0 -75
  236. package/.codex/skills/maestro-phase-add/SKILL.md +0 -154
  237. package/.codex/skills/maestro-phase-transition/SKILL.md +0 -173
  238. package/chains/singles/phase-add.json +0 -31
  239. package/chains/singles/phase-transition.json +0 -23
  240. package/dashboard/dist/assets/ChatInput-PuCvZZ3y.js +0 -67
  241. package/dashboard/dist/assets/ChatPage-v19GURYH.js +0 -8
  242. package/dashboard/dist/assets/CollabPage-I5k_mCbG.js +0 -1
  243. package/dashboard/dist/assets/KanbanPage-PDDBv5-9.js +0 -16
  244. package/dashboard/dist/assets/McpPage-CiqXpCHg.js +0 -16
  245. package/dashboard/dist/assets/TreeBrowser-0VIMWclo.js +0 -11
  246. package/dashboard/dist/assets/WorkflowPage-Csm23wUS.js +0 -6
  247. package/dashboard/dist/assets/git-branch-DL8p9kVC.js +0 -6
  248. package/dashboard/dist/assets/index-11DuhKhc.js +0 -231
  249. package/dashboard/dist/assets/index-D2Mtyw7I.css +0 -1
  250. package/dashboard/dist/assets/wrench-BScEJFqC.js +0 -11
  251. package/dist/src/commands/team.d.ts.map +0 -1
  252. package/dist/src/commands/team.js.map +0 -1
  253. package/workflows/phase-add.md +0 -252
  254. package/workflows/phase-transition.md +0 -399
@@ -0,0 +1,365 @@
1
+ /**
2
+ * Human-team task management (team-lite collaboration, Wave 2).
3
+ *
4
+ * Owns `.workflow/collab/tasks/{id}.json` -- per-file task records.
5
+ *
6
+ * Strict namespace separation: this module belongs to the HUMAN collaboration
7
+ * domain (`.workflow/collab/`). It must NEVER touch `.workflow/.team/` which
8
+ * is the agent pipeline message bus owned by `src/tools/team-msg.ts`.
9
+ *
10
+ * Per-file layout is deliberate: each task is a standalone JSON file so that
11
+ * concurrent edits on different machines can merge cleanly via git.
12
+ */
13
+ import { existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync, unlinkSync, } from 'node:fs';
14
+ import { join } from 'node:path';
15
+ import { getProjectRoot } from '../utils/path-validator.js';
16
+ import { resolveSelf } from './team-members.js';
17
+ import { reportActivity } from './team-activity.js';
18
+ import { notifyAdapters } from './collab-adapter.js';
19
+ // ---------------------------------------------------------------------------
20
+ // Constants
21
+ // ---------------------------------------------------------------------------
22
+ const VALID_TRANSITIONS = {
23
+ 'open': ['assigned', 'closed'],
24
+ 'assigned': ['in_progress', 'open', 'closed'],
25
+ 'in_progress': ['pending_review', 'assigned', 'closed'],
26
+ 'pending_review': ['done', 'in_progress', 'closed'],
27
+ 'done': ['closed', 'pending_review'],
28
+ 'closed': ['open'], // reopen
29
+ };
30
+ // ---------------------------------------------------------------------------
31
+ // Path helpers
32
+ // ---------------------------------------------------------------------------
33
+ /** Absolute path to the human-collab tasks directory. */
34
+ export function getTasksDir() {
35
+ const dir = join(getProjectRoot(), '.workflow', 'collab', 'tasks');
36
+ if (!existsSync(dir))
37
+ mkdirSync(dir, { recursive: true });
38
+ return dir;
39
+ }
40
+ /** Absolute path to a specific task JSON file. */
41
+ export function getTaskFilePath(id) {
42
+ return join(getTasksDir(), `${id}.json`);
43
+ }
44
+ /** Absolute path to the auto-increment counter file. */
45
+ function getCounterFilePath() {
46
+ return join(getTasksDir(), '.counter');
47
+ }
48
+ // ---------------------------------------------------------------------------
49
+ // Counter / ID generation
50
+ // ---------------------------------------------------------------------------
51
+ /**
52
+ * Atomically read and increment the counter file, returning the next
53
+ * `TASK-XXX` formatted id. Creates the counter file at `1` if absent.
54
+ */
55
+ export function getNextTaskId() {
56
+ const counterPath = getCounterFilePath();
57
+ let next = 1;
58
+ if (existsSync(counterPath)) {
59
+ const raw = readFileSync(counterPath, 'utf-8').trim();
60
+ const parsed = parseInt(raw, 10);
61
+ if (!Number.isNaN(parsed)) {
62
+ next = parsed;
63
+ }
64
+ }
65
+ const id = `TASK-${String(next).padStart(3, '0')}`;
66
+ writeFileSync(counterPath, String(next + 1), 'utf-8');
67
+ return id;
68
+ }
69
+ // ---------------------------------------------------------------------------
70
+ // Internal read/write
71
+ // ---------------------------------------------------------------------------
72
+ /**
73
+ * Read and validate a task JSON file. Returns null if the file is missing,
74
+ * unparseable, or does not match the CollabTask shape.
75
+ */
76
+ export function readTaskFile(filePath) {
77
+ if (!existsSync(filePath))
78
+ return null;
79
+ try {
80
+ const raw = readFileSync(filePath, 'utf-8');
81
+ const parsed = JSON.parse(raw);
82
+ if (typeof parsed.id === 'string' &&
83
+ typeof parsed.title === 'string' &&
84
+ typeof parsed.description === 'string' &&
85
+ typeof parsed.status === 'string' &&
86
+ typeof parsed.priority === 'string' &&
87
+ typeof parsed.reporter === 'string' &&
88
+ Array.isArray(parsed.check_log) &&
89
+ typeof parsed.created_at === 'string' &&
90
+ typeof parsed.updated_at === 'string' &&
91
+ typeof parsed.updated_by === 'string') {
92
+ return parsed;
93
+ }
94
+ return null;
95
+ }
96
+ catch {
97
+ return null;
98
+ }
99
+ }
100
+ /**
101
+ * Atomic write of a task JSON file with pretty-printing.
102
+ */
103
+ export function writeTaskFile(filePath, task) {
104
+ writeFileSync(filePath, JSON.stringify(task, null, 2), 'utf-8');
105
+ }
106
+ // ---------------------------------------------------------------------------
107
+ // CRUD operations
108
+ // ---------------------------------------------------------------------------
109
+ /**
110
+ * Create a new task. Generates the id via auto-increment counter, sets
111
+ * defaults (status=open, timestamps), and writes the JSON file.
112
+ */
113
+ export function createTask(opts) {
114
+ const id = getNextTaskId();
115
+ const now = new Date().toISOString();
116
+ const task = {
117
+ id,
118
+ title: opts.title,
119
+ description: opts.description ?? '',
120
+ status: 'open',
121
+ priority: opts.priority ?? 'medium',
122
+ reporter: opts.reporter,
123
+ check_log: [],
124
+ ...(opts.tags && opts.tags.length > 0 ? { tags: opts.tags } : {}),
125
+ ...(opts.external_refs && opts.external_refs.length > 0 ? { external_refs: opts.external_refs } : {}),
126
+ created_at: now,
127
+ updated_at: now,
128
+ updated_by: opts.reporter,
129
+ };
130
+ writeTaskFile(getTaskFilePath(id), task);
131
+ try {
132
+ notifyAdapters({
133
+ type: 'task.created',
134
+ payload: { id: task.id, title: task.title, priority: task.priority, reporter: task.reporter },
135
+ });
136
+ }
137
+ catch { /* fire-and-forget: never block */ }
138
+ return task;
139
+ }
140
+ /**
141
+ * Read a single task by id. Returns null if the task does not exist or the
142
+ * file is invalid.
143
+ */
144
+ export function getTask(id) {
145
+ const filePath = getTaskFilePath(id);
146
+ return readTaskFile(filePath);
147
+ }
148
+ /**
149
+ * Update a task by merging partial fields. Validates status transition if
150
+ * the `status` field is being changed. Throws if the task does not exist or
151
+ * the transition is invalid.
152
+ */
153
+ export function updateTask(id, partial) {
154
+ const task = getTask(id);
155
+ if (!task) {
156
+ throw new Error(`Task not found: ${id}`);
157
+ }
158
+ // Validate status transition if status is being changed.
159
+ if (partial.status !== undefined && partial.status !== task.status) {
160
+ if (!validateStatusTransition(task.status, partial.status)) {
161
+ throw new Error(`Invalid status transition: ${task.status} -> ${partial.status}`);
162
+ }
163
+ }
164
+ const now = new Date().toISOString();
165
+ const updated = {
166
+ ...task,
167
+ ...partial,
168
+ id: task.id, // id is immutable
169
+ created_at: task.created_at, // created_at is immutable
170
+ updated_at: now,
171
+ };
172
+ writeTaskFile(getTaskFilePath(id), updated);
173
+ return updated;
174
+ }
175
+ /**
176
+ * List all tasks, optionally filtered by status, assignee, reporter, or
177
+ * priority. Returns tasks sorted by id ascending.
178
+ */
179
+ export function listTasks(filters) {
180
+ const dir = getTasksDir();
181
+ let entries;
182
+ try {
183
+ entries = readdirSync(dir);
184
+ }
185
+ catch {
186
+ return [];
187
+ }
188
+ const out = [];
189
+ for (const entry of entries) {
190
+ if (!entry.endsWith('.json'))
191
+ continue;
192
+ const task = readTaskFile(join(dir, entry));
193
+ if (!task)
194
+ continue;
195
+ if (filters) {
196
+ if (filters.status !== undefined && task.status !== filters.status)
197
+ continue;
198
+ if (filters.assignee !== undefined && task.assignee !== filters.assignee)
199
+ continue;
200
+ if (filters.reporter !== undefined && task.reporter !== filters.reporter)
201
+ continue;
202
+ if (filters.priority !== undefined && task.priority !== filters.priority)
203
+ continue;
204
+ }
205
+ out.push(task);
206
+ }
207
+ // Sort by id ascending (TASK-001 before TASK-002).
208
+ out.sort((a, b) => a.id.localeCompare(b.id));
209
+ return out;
210
+ }
211
+ /**
212
+ * Delete a task file. Throws if the task does not exist.
213
+ */
214
+ export function deleteTask(id) {
215
+ const filePath = getTaskFilePath(id);
216
+ if (!existsSync(filePath)) {
217
+ throw new Error(`Task not found: ${id}`);
218
+ }
219
+ unlinkSync(filePath);
220
+ }
221
+ // ---------------------------------------------------------------------------
222
+ // Task operations
223
+ // ---------------------------------------------------------------------------
224
+ /**
225
+ * Assign a task to a member. If the task is currently `open`, automatically
226
+ * transitions to `assigned`.
227
+ */
228
+ export function assignTask(id, uid) {
229
+ const task = getTask(id);
230
+ if (!task) {
231
+ throw new Error(`Task not found: ${id}`);
232
+ }
233
+ const newStatus = task.status === 'open' ? 'assigned' : task.status;
234
+ const now = new Date().toISOString();
235
+ const updated = {
236
+ ...task,
237
+ assignee: uid,
238
+ status: newStatus,
239
+ updated_at: now,
240
+ updated_by: uid,
241
+ };
242
+ writeTaskFile(getTaskFilePath(id), updated);
243
+ try {
244
+ const self = resolveSelf();
245
+ if (self) {
246
+ reportActivity({
247
+ user: self.uid,
248
+ host: self.host,
249
+ action: 'task.assigned',
250
+ task_id: task.id,
251
+ target: uid,
252
+ });
253
+ }
254
+ }
255
+ catch { /* hot-path: never throw */ }
256
+ try {
257
+ notifyAdapters({
258
+ type: 'task.assigned',
259
+ payload: { id: task.id, assignee: uid },
260
+ recipients: [uid],
261
+ });
262
+ }
263
+ catch { /* fire-and-forget: never block */ }
264
+ return updated;
265
+ }
266
+ /**
267
+ * Update task status with transition validation. Throws if the transition is
268
+ * not allowed by VALID_TRANSITIONS.
269
+ */
270
+ export function updateTaskStatus(id, newStatus, updatedBy) {
271
+ const task = getTask(id);
272
+ if (!task) {
273
+ throw new Error(`Task not found: ${id}`);
274
+ }
275
+ if (!validateStatusTransition(task.status, newStatus)) {
276
+ throw new Error(`Invalid status transition: ${task.status} -> ${newStatus}`);
277
+ }
278
+ const oldStatus = task.status;
279
+ const now = new Date().toISOString();
280
+ const updated = {
281
+ ...task,
282
+ status: newStatus,
283
+ updated_at: now,
284
+ updated_by: updatedBy,
285
+ };
286
+ writeTaskFile(getTaskFilePath(id), updated);
287
+ try {
288
+ const self = resolveSelf();
289
+ if (self) {
290
+ reportActivity({
291
+ user: self.uid,
292
+ host: self.host,
293
+ action: 'task.status_changed',
294
+ task_id: task.id,
295
+ target: `${oldStatus}->${newStatus}`,
296
+ });
297
+ }
298
+ }
299
+ catch { /* hot-path: never throw */ }
300
+ try {
301
+ notifyAdapters({
302
+ type: 'task.status_changed',
303
+ payload: { id: task.id, from: oldStatus, to: newStatus },
304
+ });
305
+ }
306
+ catch { /* fire-and-forget: never block */ }
307
+ return updated;
308
+ }
309
+ /**
310
+ * Append a check entry to a task's check_log. The timestamp is auto-generated.
311
+ * Existing entries are never modified or removed (append-only).
312
+ */
313
+ export function addCheckEntry(id, entry) {
314
+ const task = getTask(id);
315
+ if (!task) {
316
+ throw new Error(`Task not found: ${id}`);
317
+ }
318
+ const fullEntry = {
319
+ ...entry,
320
+ ts: new Date().toISOString(),
321
+ };
322
+ const now = new Date().toISOString();
323
+ const updated = {
324
+ ...task,
325
+ check_log: [...task.check_log, fullEntry],
326
+ updated_at: now,
327
+ updated_by: entry.uid,
328
+ };
329
+ writeTaskFile(getTaskFilePath(id), updated);
330
+ try {
331
+ const self = resolveSelf();
332
+ if (self) {
333
+ reportActivity({
334
+ user: self.uid,
335
+ host: self.host,
336
+ action: 'task.checked',
337
+ task_id: task.id,
338
+ target: entry.action,
339
+ });
340
+ }
341
+ }
342
+ catch { /* hot-path: never throw */ }
343
+ try {
344
+ notifyAdapters({
345
+ type: 'task.checked',
346
+ payload: { id: task.id, action: entry.action, uid: entry.uid },
347
+ });
348
+ }
349
+ catch { /* fire-and-forget: never block */ }
350
+ return updated;
351
+ }
352
+ // ---------------------------------------------------------------------------
353
+ // Validation
354
+ // ---------------------------------------------------------------------------
355
+ /**
356
+ * Validate that a status transition is allowed by VALID_TRANSITIONS.
357
+ * A transition from a status to itself is always allowed (no-op).
358
+ */
359
+ export function validateStatusTransition(from, to) {
360
+ if (from === to)
361
+ return true;
362
+ const allowed = VALID_TRANSITIONS[from];
363
+ return allowed ? allowed.includes(to) : false;
364
+ }
365
+ //# sourceMappingURL=team-tasks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"team-tasks.js","sourceRoot":"","sources":["../../../src/tools/team-tasks.ts"],"names":[],"mappings":"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"}
@@ -42,6 +42,9 @@ export declare function buildTransitionEntry(opts: BuildTransitionOpts): Transit
42
42
  /**
43
43
  * Append a transition entry to state.json's transition_history[].
44
44
  * Creates the array if it doesn't exist.
45
+ *
46
+ * For phase-completion transitions, evaluates the phase gate first.
47
+ * Throws if the gate blocks and force is false.
45
48
  */
46
49
  export declare function appendTransition(statePath: string, entry: TransitionEntry): void;
47
50
  //# sourceMappingURL=transition-recorder.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"transition-recorder.d.ts","sourceRoot":"","sources":["../../../src/tools/transition-recorder.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAQH,MAAM,WAAW,kBAAkB;IACjC,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,OAAO,GAAG,WAAW,CAAC;IAC5B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,EAAE,kBAAkB,CAAC;CAC9B;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,OAAO,GAAG,WAAW,CAAC;IAC5B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;IACf,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,cAAc,EAAE,MAAM,CAAC;CACxB;AAMD;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,mBAAmB,GAAG,eAAe,CAiB/E;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,GAAG,IAAI,CAUhF"}
1
+ {"version":3,"file":"transition-recorder.d.ts","sourceRoot":"","sources":["../../../src/tools/transition-recorder.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAWH,MAAM,WAAW,kBAAkB;IACjC,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,OAAO,GAAG,WAAW,CAAC;IAC5B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,EAAE,kBAAkB,CAAC;CAC9B;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,OAAO,GAAG,WAAW,CAAC;IAC5B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;IACf,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,cAAc,EAAE,MAAM,CAAC;CACxB;AAMD;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,mBAAmB,GAAG,eAAe,CAiB/E;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,GAAG,IAAI,CA+BhF"}
@@ -4,7 +4,9 @@
4
4
  * Provides pure functions for building transition entries and appending
5
5
  * them to the transition_history array in .workflow/state.json.
6
6
  */
7
- import { readFileSync, writeFileSync, existsSync } from 'node:fs';
7
+ import { readFileSync, writeFileSync, existsSync, readdirSync } from 'node:fs';
8
+ import { join, dirname } from 'node:path';
9
+ import { evaluatePhaseGate } from './phase-gate-evaluator.js';
8
10
  // ---------------------------------------------------------------------------
9
11
  // Public API
10
12
  // ---------------------------------------------------------------------------
@@ -33,10 +35,31 @@ export function buildTransitionEntry(opts) {
33
35
  /**
34
36
  * Append a transition entry to state.json's transition_history[].
35
37
  * Creates the array if it doesn't exist.
38
+ *
39
+ * For phase-completion transitions, evaluates the phase gate first.
40
+ * Throws if the gate blocks and force is false.
36
41
  */
37
42
  export function appendTransition(statePath, entry) {
38
43
  if (!existsSync(statePath))
39
44
  return;
45
+ // Gate check: validate phase readiness before allowing completion
46
+ if (entry.type === 'phase' && entry.from_phase != null) {
47
+ const phaseIndex = loadPhaseIndex(statePath, entry.from_phase);
48
+ if (phaseIndex) {
49
+ const gate = evaluatePhaseGate(phaseIndex);
50
+ if (!gate.allowed) {
51
+ if (!gate.overridable || !entry.force) {
52
+ const tag = gate.overridable ? '[GATE_BLOCKED]' : '[GATE_HARD_BLOCK]';
53
+ throw new Error(`${tag} Phase ${entry.from_phase} cannot be completed:\n` +
54
+ gate.reasons.map((r) => ` - ${r}`).join('\n') +
55
+ (gate.overridable ? '\nUse force=true to override soft blocks.' : '\nResolve BLOCK verdict before completing.'));
56
+ }
57
+ // Force override — record the reasons in snapshot for audit
58
+ entry.snapshot.verification_status =
59
+ `force_override: ${gate.reasons.join('; ')}`;
60
+ }
61
+ }
62
+ }
40
63
  const state = JSON.parse(readFileSync(statePath, 'utf8'));
41
64
  if (!Array.isArray(state.transition_history)) {
42
65
  state.transition_history = [];
@@ -45,4 +68,32 @@ export function appendTransition(statePath, entry) {
45
68
  state.last_updated = new Date().toISOString();
46
69
  writeFileSync(statePath, JSON.stringify(state, null, 2));
47
70
  }
71
+ // ---------------------------------------------------------------------------
72
+ // Internal helpers
73
+ // ---------------------------------------------------------------------------
74
+ /**
75
+ * Load phase index.json from the phases directory sibling to state.json.
76
+ * Returns null if not found.
77
+ */
78
+ function loadPhaseIndex(statePath, phaseNum) {
79
+ const workflowDir = dirname(statePath);
80
+ const phasesDir = join(workflowDir, 'phases');
81
+ if (!existsSync(phasesDir))
82
+ return null;
83
+ // Find directory starting with the phase number prefix (e.g. "01-")
84
+ try {
85
+ const prefix = String(phaseNum).padStart(2, '0') + '-';
86
+ const entries = readdirSync(phasesDir);
87
+ const phaseSlug = entries.find((e) => e.startsWith(prefix));
88
+ if (!phaseSlug)
89
+ return null;
90
+ const indexPath = join(phasesDir, phaseSlug, 'index.json');
91
+ if (!existsSync(indexPath))
92
+ return null;
93
+ return JSON.parse(readFileSync(indexPath, 'utf8'));
94
+ }
95
+ catch {
96
+ return null;
97
+ }
98
+ }
48
99
  //# sourceMappingURL=transition-recorder.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"transition-recorder.js","sourceRoot":"","sources":["../../../src/tools/transition-recorder.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAuClE,8EAA8E;AAC9E,aAAa;AACb,8EAA8E;AAE9E;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAAC,IAAyB;IAC5D,OAAO;QACL,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,UAAU,EAAE,IAAI,CAAC,SAAS;QAC1B,QAAQ,EAAE,IAAI,CAAC,OAAO;QACtB,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,eAAe,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACzC,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,QAAQ,EAAE;YACR,gBAAgB,EAAE,IAAI,CAAC,eAAe;YACtC,YAAY,EAAE,IAAI,CAAC,WAAW;YAC9B,cAAc,EAAE,IAAI,CAAC,aAAa;YAClC,mBAAmB,EAAE,IAAI,CAAC,kBAAkB;YAC5C,eAAe,EAAE,IAAI,CAAC,cAAc;SACrC;KACF,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,SAAiB,EAAE,KAAsB;IACxE,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC;QAAE,OAAO;IAEnC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC;IAC1D,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,kBAAkB,CAAC,EAAE,CAAC;QAC7C,KAAK,CAAC,kBAAkB,GAAG,EAAE,CAAC;IAChC,CAAC;IACD,KAAK,CAAC,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACrC,KAAK,CAAC,YAAY,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC9C,aAAa,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAC3D,CAAC"}
1
+ {"version":3,"file":"transition-recorder.js","sourceRoot":"","sources":["../../../src/tools/transition-recorder.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"get-version.d.ts","sourceRoot":"","sources":["../../../src/utils/get-version.ts"],"names":[],"mappings":"AAUA;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAO1C"}
1
+ {"version":3,"file":"get-version.d.ts","sourceRoot":"","sources":["../../../src/utils/get-version.ts"],"names":[],"mappings":"AAUA;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAiB1C"}
@@ -12,10 +12,21 @@ let cached = null;
12
12
  export function getPackageVersion() {
13
13
  if (cached)
14
14
  return cached;
15
- // Compiled JS lives at dist/src/utils/get-version.js 4 levels up to project root
16
- const pkgRoot = resolve(fileURLToPath(import.meta.url), '..', '..', '..', '..');
17
- const pkg = JSON.parse(readFileSync(resolve(pkgRoot, 'package.json'), 'utf-8'));
18
- cached = pkg.version ?? '0.0.0';
15
+ // Walk up from this file until we find a package.json with "maestro" in it
16
+ let dir = resolve(fileURLToPath(import.meta.url), '..');
17
+ for (let i = 0; i < 8; i++) {
18
+ const pkgPath = resolve(dir, 'package.json');
19
+ try {
20
+ const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
21
+ if (pkg.name === 'maestro-flow' || pkg.name === 'maestro') {
22
+ cached = pkg.version ?? '0.0.0';
23
+ return cached;
24
+ }
25
+ }
26
+ catch { /* not found, keep going up */ }
27
+ dir = resolve(dir, '..');
28
+ }
29
+ cached = '0.0.0';
19
30
  return cached;
20
31
  }
21
32
  //# sourceMappingURL=get-version.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"get-version.js","sourceRoot":"","sources":["../../../src/utils/get-version.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,0EAA0E;AAC1E,8EAA8E;AAE9E,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,IAAI,MAAM,GAAkB,IAAI,CAAC;AAEjC;;;GAGG;AACH,MAAM,UAAU,iBAAiB;IAC/B,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAC1B,mFAAmF;IACnF,MAAM,OAAO,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IAChF,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,CAAC,OAAO,EAAE,cAAc,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;IAChF,MAAM,GAAI,GAAG,CAAC,OAAkB,IAAI,OAAO,CAAC;IAC5C,OAAO,MAAM,CAAC;AAChB,CAAC"}
1
+ {"version":3,"file":"get-version.js","sourceRoot":"","sources":["../../../src/utils/get-version.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,0EAA0E;AAC1E,8EAA8E;AAE9E,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,IAAI,MAAM,GAAkB,IAAI,CAAC;AAEjC;;;GAGG;AACH,MAAM,UAAU,iBAAiB;IAC/B,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAC1B,2EAA2E;IAC3E,IAAI,GAAG,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC;IACxD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3B,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;QAC7C,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;YACvD,IAAI,GAAG,CAAC,IAAI,KAAK,cAAc,IAAI,GAAG,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;gBAC1D,MAAM,GAAI,GAAG,CAAC,OAAkB,IAAI,OAAO,CAAC;gBAC5C,OAAO,MAAM,CAAC;YAChB,CAAC;QACH,CAAC;QAAC,MAAM,CAAC,CAAC,8BAA8B,CAAC,CAAC;QAC1C,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAC3B,CAAC;IACD,MAAM,GAAG,OAAO,CAAC;IACjB,OAAO,MAAM,CAAC;AAChB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "maestro-flow",
3
- "version": "0.3.7",
3
+ "version": "0.3.9",
4
4
  "description": "Workflow orchestration CLI with MCP endpoint support and extensible architecture",
5
5
  "type": "module",
6
6
  "imports": {
@@ -49,5 +49,12 @@
49
49
  "doc_index": true,
50
50
  "auto_sync_after_execute": true,
51
51
  "action_log": true
52
+ },
53
+
54
+ "worktree": {
55
+ "enabled": true,
56
+ "root": ".worktrees",
57
+ "branch_prefix": "milestone/",
58
+ "auto_cleanup": true
52
59
  }
53
60
  }
@@ -0,0 +1,10 @@
1
+ {
2
+ "worktree": true,
3
+ "milestone_num": "{{MILESTONE_NUMBER}}",
4
+ "milestone": "{{MILESTONE_NAME}}",
5
+ "owned_phases": [],
6
+ "main_worktree": "{{MAIN_WORKTREE_PATH}}",
7
+ "branch": "milestone/{{MILESTONE_SLUG}}",
8
+ "base_commit": "{{BASE_COMMIT}}",
9
+ "created_at": "{{TIMESTAMP}}"
10
+ }
@@ -0,0 +1,27 @@
1
+ {
2
+ "version": "1.0",
3
+ "worktrees": [
4
+ {
5
+ "milestone_num": "{{MILESTONE_NUMBER}}",
6
+ "milestone": "{{MILESTONE_NAME}}",
7
+ "slug": "{{MILESTONE_SLUG}}",
8
+ "branch": "milestone/{{MILESTONE_SLUG}}",
9
+ "path": "{{WORKTREE_ROOT}}/m{{MILESTONE_NUMBER}}-{{MILESTONE_SLUG}}",
10
+ "base_commit": "{{BASE_COMMIT}}",
11
+ "status": "active",
12
+ "created_at": "{{TIMESTAMP}}",
13
+ "owned_phases": [],
14
+ "fork_session": "{{FORK_SESSION_ID}}"
15
+ }
16
+ ],
17
+ "fork_sessions": [
18
+ {
19
+ "session_id": "fork-{{TIMESTAMP_SHORT}}",
20
+ "created_at": "{{TIMESTAMP}}",
21
+ "milestone_num": "{{MILESTONE_NUMBER}}",
22
+ "milestone": "{{MILESTONE_NAME}}",
23
+ "base_branch": "{{BASE_BRANCH}}",
24
+ "base_commit": "{{BASE_COMMIT}}"
25
+ }
26
+ ]
27
+ }