cc-devflow 4.5.10 → 4.5.12

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 (187) hide show
  1. package/.claude/skills/cc-act/CHANGELOG.md +23 -0
  2. package/.claude/skills/cc-act/PLAYBOOK.md +17 -269
  3. package/.claude/skills/cc-act/SKILL.md +38 -418
  4. package/.claude/skills/cc-act/assets/PROJECT_POSTMORTEM_INDEX_TEMPLATE.md +2 -13
  5. package/.claude/skills/cc-act/assets/PROJECT_POSTMORTEM_TEMPLATE.md +1 -9
  6. package/.claude/skills/cc-act/assets/PR_BRIEF_TEMPLATE.md +21 -177
  7. package/.claude/skills/cc-act/references/closure-contract.md +12 -63
  8. package/.claude/skills/cc-act/references/git-commit-guidelines.md +5 -5
  9. package/.claude/skills/cc-act/scripts/cc-act-common.sh +5 -322
  10. package/.claude/skills/cc-act/scripts/detect-ship-target.sh +11 -2
  11. package/.claude/skills/cc-act/scripts/inspect-git-index.sh +58 -0
  12. package/.claude/skills/cc-act/scripts/render-pr-brief.sh +40 -440
  13. package/.claude/skills/cc-act/scripts/verify-act-gate.sh +10 -50
  14. package/.claude/skills/cc-check/CHANGELOG.md +24 -0
  15. package/.claude/skills/cc-check/PLAYBOOK.md +19 -273
  16. package/.claude/skills/cc-check/SKILL.md +33 -454
  17. package/.claude/skills/cc-check/references/review-contract.md +12 -147
  18. package/.claude/skills/cc-dev/CHANGELOG.md +20 -0
  19. package/.claude/skills/cc-dev/PLAYBOOK.md +1 -1
  20. package/.claude/skills/cc-dev/SKILL.md +52 -130
  21. package/.claude/skills/cc-dev/scripts/resolve-cc-devflow.sh +181 -0
  22. package/.claude/skills/cc-do/CHANGELOG.md +17 -0
  23. package/.claude/skills/cc-do/PLAYBOOK.md +19 -113
  24. package/.claude/skills/cc-do/SKILL.md +39 -236
  25. package/.claude/skills/cc-do/references/execution-recovery.md +15 -109
  26. package/.claude/skills/cc-do/scripts/cc-do-common.sh +5 -57
  27. package/.claude/skills/cc-do/scripts/check-task-status.sh +35 -65
  28. package/.claude/skills/cc-do/scripts/mark-task-complete.sh +9 -46
  29. package/.claude/skills/cc-do/scripts/select-ready-tasks.sh +29 -97
  30. package/.claude/skills/cc-investigate/CHANGELOG.md +23 -0
  31. package/.claude/skills/cc-investigate/PLAYBOOK.md +20 -180
  32. package/.claude/skills/cc-investigate/SKILL.md +65 -513
  33. package/.claude/skills/cc-investigate/assets/TASKS_TEMPLATE.md +48 -95
  34. package/.claude/skills/cc-investigate/references/investigation-contract.md +14 -217
  35. package/.claude/skills/cc-next/CHANGELOG.md +6 -0
  36. package/.claude/skills/cc-next/PLAYBOOK.md +12 -8
  37. package/.claude/skills/cc-next/SKILL.md +34 -140
  38. package/.claude/skills/cc-plan/CHANGELOG.md +29 -0
  39. package/.claude/skills/cc-plan/PLAYBOOK.md +22 -161
  40. package/.claude/skills/cc-plan/SKILL.md +47 -640
  41. package/.claude/skills/cc-plan/assets/TASKS_TEMPLATE.md +30 -225
  42. package/.claude/skills/cc-plan/references/planning-contract.md +24 -160
  43. package/.claude/skills/cc-plan/scripts/next-change-key.sh +8 -44
  44. package/.claude/skills/cc-plan/scripts/parse-task-dependencies.js +2 -2
  45. package/.claude/skills/cc-plan/scripts/validate-scope.sh +1 -1
  46. package/.claude/skills/cc-pr-land/SKILL.md +14 -114
  47. package/.claude/skills/cc-pr-review/CHANGELOG.md +4 -0
  48. package/.claude/skills/cc-pr-review/SKILL.md +20 -103
  49. package/.claude/skills/cc-review/CHANGELOG.md +17 -0
  50. package/.claude/skills/cc-review/PLAYBOOK.md +13 -86
  51. package/.claude/skills/cc-review/SKILL.md +53 -241
  52. package/.claude/skills/cc-review/references/e2e-and-plugin-verification.md +2 -2
  53. package/.claude/skills/cc-review/references/implementation-review-branch.md +7 -147
  54. package/.claude/skills/cc-review/references/plan-review-branch.md +5 -147
  55. package/.claude/skills/cc-review/references/review-methods.md +10 -218
  56. package/.claude/skills/cc-review/scripts/collect-review-context.sh +4 -63
  57. package/.claude/skills/cc-roadmap/PLAYBOOK.md +1 -1
  58. package/.claude/skills/cc-roadmap/SKILL.md +3 -3
  59. package/.claude/skills/cc-simplify/CHANGELOG.md +7 -0
  60. package/.claude/skills/cc-simplify/SKILL.md +26 -21
  61. package/.claude/skills/cc-spec-init/PLAYBOOK.md +12 -48
  62. package/.claude/skills/cc-spec-init/SKILL.md +29 -132
  63. package/.claude/skills/cc-spec-init/references/spec-contract.md +8 -17
  64. package/CHANGELOG.md +27 -0
  65. package/README.md +5 -3
  66. package/README.zh-CN.md +5 -3
  67. package/bin/cc-devflow-cli.js +20 -260
  68. package/bin/cc-devflow.js +44 -7
  69. package/docs/commands/README.md +1 -1
  70. package/docs/commands/README.zh-CN.md +1 -1
  71. package/docs/examples/README.md +1 -1
  72. package/docs/examples/START-HERE.md +14 -14
  73. package/docs/examples/example-bindings.json +11 -11
  74. package/docs/examples/full-design-blocked/README.md +4 -6
  75. package/docs/examples/full-design-blocked/changes/REQ-002-bulk-invite-import/{planning/tasks.md → task.md} +20 -15
  76. package/docs/examples/local-handoff/README.md +8 -11
  77. package/docs/examples/local-handoff/changes/REQ-003-audit-log-export/handoff/pr-brief.md +31 -0
  78. package/docs/examples/local-handoff/changes/REQ-003-audit-log-export/{planning/tasks.md → task.md} +18 -13
  79. package/docs/examples/pdca-loop/README.md +6 -9
  80. package/docs/examples/pdca-loop/changes/REQ-001-copy-invite-link/handoff/pr-brief.md +9 -11
  81. package/docs/examples/pdca-loop/changes/REQ-001-copy-invite-link/{planning/tasks.md → task.md} +18 -13
  82. package/docs/examples/scripts/check-example-bindings.sh +11 -62
  83. package/docs/guides/artifact-contract.md +10 -36
  84. package/docs/guides/getting-started.md +8 -7
  85. package/docs/guides/getting-started.zh-CN.md +8 -7
  86. package/docs/guides/minimize-artifacts.md +16 -116
  87. package/docs/guides/project-postmortem.md +14 -71
  88. package/lib/compiler/__tests__/skills-registry.test.js +9 -8
  89. package/lib/compiler/resource-copier.js +29 -0
  90. package/lib/skill-runtime/__tests__/archive-change.test.js +2 -2
  91. package/lib/skill-runtime/__tests__/benchmark-skills.test.js +109 -0
  92. package/lib/skill-runtime/__tests__/cli-bootstrap.integration.test.js +14 -4
  93. package/lib/skill-runtime/errors.js +3 -3
  94. package/lib/skill-runtime/index.js +5 -23
  95. package/lib/skill-runtime/paths.js +5 -52
  96. package/lib/skill-runtime/query-registry.js +4 -4
  97. package/lib/skill-runtime/query.js +89 -201
  98. package/lib/skill-runtime/store.js +4 -40
  99. package/lib/skill-runtime/trace.js +2 -2
  100. package/package.json +5 -7
  101. package/.claude/skills/cc-act/assets/PROJECT_POSTMORTEM_PRINCIPLES_TEMPLATE.md +0 -29
  102. package/.claude/skills/cc-act/assets/RELEASE_NOTE_TEMPLATE.md +0 -54
  103. package/.claude/skills/cc-act/scripts/generate-status-report.sh +0 -92
  104. package/.claude/skills/cc-act/scripts/sync-act-docs.sh +0 -355
  105. package/.claude/skills/cc-check/assets/REPORT_CARD_TEMPLATE.json +0 -234
  106. package/.claude/skills/cc-check/scripts/render-report-card.js +0 -438
  107. package/.claude/skills/cc-check/scripts/verify-gate.sh +0 -85
  108. package/.claude/skills/cc-do/scripts/build-task-context.sh +0 -175
  109. package/.claude/skills/cc-do/scripts/record-review-decision.sh +0 -88
  110. package/.claude/skills/cc-do/scripts/recover-workflow.sh +0 -82
  111. package/.claude/skills/cc-do/scripts/run-problem-analysis.sh +0 -70
  112. package/.claude/skills/cc-do/scripts/verify-task-gates.sh +0 -109
  113. package/.claude/skills/cc-do/scripts/write-task-checkpoint.sh +0 -92
  114. package/.claude/skills/cc-investigate/assets/TASK_MANIFEST_TEMPLATE.json +0 -225
  115. package/.claude/skills/cc-plan/assets/TASK_MANIFEST_TEMPLATE.json +0 -179
  116. package/.claude/skills/cc-spec-init/assets/CHANGE_META_TEMPLATE.json +0 -28
  117. package/.claude/skills/cc-spec-init/scripts/validate-spec-links.sh +0 -45
  118. package/docs/examples/full-design-blocked/changes/REQ-002-bulk-invite-import/planning/design.md +0 -234
  119. package/docs/examples/full-design-blocked/changes/REQ-002-bulk-invite-import/planning/task-manifest.json +0 -488
  120. package/docs/examples/full-design-blocked/changes/REQ-002-bulk-invite-import/review/report-card.json +0 -189
  121. package/docs/examples/local-handoff/changes/REQ-003-audit-log-export/handoff/resume-index.md +0 -39
  122. package/docs/examples/local-handoff/changes/REQ-003-audit-log-export/handoff/status.md +0 -29
  123. package/docs/examples/local-handoff/changes/REQ-003-audit-log-export/planning/design.md +0 -123
  124. package/docs/examples/local-handoff/changes/REQ-003-audit-log-export/planning/task-manifest.json +0 -292
  125. package/docs/examples/local-handoff/changes/REQ-003-audit-log-export/review/report-card.json +0 -136
  126. package/docs/examples/pdca-loop/changes/REQ-001-copy-invite-link/handoff/status.md +0 -29
  127. package/docs/examples/pdca-loop/changes/REQ-001-copy-invite-link/planning/design.md +0 -124
  128. package/docs/examples/pdca-loop/changes/REQ-001-copy-invite-link/planning/task-manifest.json +0 -292
  129. package/docs/examples/pdca-loop/changes/REQ-001-copy-invite-link/review/report-card.json +0 -136
  130. package/docs/get-shit-done-strategy-audit.md +0 -518
  131. package/docs/skill-runtime-migration.md +0 -46
  132. package/lib/skill-runtime/__tests__/approve.test.js +0 -92
  133. package/lib/skill-runtime/__tests__/autopilot.test.js +0 -253
  134. package/lib/skill-runtime/__tests__/benchmark-artifacts.test.js +0 -165
  135. package/lib/skill-runtime/__tests__/delegation.test.js +0 -97
  136. package/lib/skill-runtime/__tests__/dispatch.test.js +0 -237
  137. package/lib/skill-runtime/__tests__/intent.test.js +0 -203
  138. package/lib/skill-runtime/__tests__/lifecycle.test.js +0 -169
  139. package/lib/skill-runtime/__tests__/planner.tdd.test.js +0 -331
  140. package/lib/skill-runtime/__tests__/prepare-pr.test.js +0 -126
  141. package/lib/skill-runtime/__tests__/query.test.js +0 -860
  142. package/lib/skill-runtime/__tests__/readiness.test.js +0 -53
  143. package/lib/skill-runtime/__tests__/release.test.js +0 -85
  144. package/lib/skill-runtime/__tests__/review-check-integration.test.js +0 -148
  145. package/lib/skill-runtime/__tests__/review-records.test.js +0 -619
  146. package/lib/skill-runtime/__tests__/runtime.integration.test.js +0 -351
  147. package/lib/skill-runtime/__tests__/schemas.test.js +0 -337
  148. package/lib/skill-runtime/__tests__/task-contract-migrate.test.js +0 -137
  149. package/lib/skill-runtime/__tests__/task-contract.test.js +0 -783
  150. package/lib/skill-runtime/__tests__/team-state.test.js +0 -51
  151. package/lib/skill-runtime/__tests__/verify-artifacts.test.js +0 -203
  152. package/lib/skill-runtime/__tests__/worker-run.test.js +0 -275
  153. package/lib/skill-runtime/__tests__/worker.test.js +0 -56
  154. package/lib/skill-runtime/__tests__/workflow-context-legacy-fallback.test.js +0 -31
  155. package/lib/skill-runtime/__tests__/workflow-context.test.js +0 -98
  156. package/lib/skill-runtime/artifacts.js +0 -88
  157. package/lib/skill-runtime/context-index.js +0 -545
  158. package/lib/skill-runtime/delegation.js +0 -533
  159. package/lib/skill-runtime/intent.js +0 -309
  160. package/lib/skill-runtime/lifecycle.js +0 -294
  161. package/lib/skill-runtime/operations/CLAUDE.md +0 -19
  162. package/lib/skill-runtime/operations/approve.js +0 -81
  163. package/lib/skill-runtime/operations/autopilot-core.js +0 -337
  164. package/lib/skill-runtime/operations/autopilot-execution.js +0 -307
  165. package/lib/skill-runtime/operations/autopilot-shared.js +0 -48
  166. package/lib/skill-runtime/operations/autopilot.js +0 -163
  167. package/lib/skill-runtime/operations/dispatch.js +0 -416
  168. package/lib/skill-runtime/operations/init.js +0 -60
  169. package/lib/skill-runtime/operations/janitor.js +0 -61
  170. package/lib/skill-runtime/operations/plan.js +0 -59
  171. package/lib/skill-runtime/operations/prepare-pr.js +0 -25
  172. package/lib/skill-runtime/operations/release.js +0 -99
  173. package/lib/skill-runtime/operations/resume.js +0 -126
  174. package/lib/skill-runtime/operations/review-records.js +0 -265
  175. package/lib/skill-runtime/operations/snapshot.js +0 -45
  176. package/lib/skill-runtime/operations/task-contract.js +0 -524
  177. package/lib/skill-runtime/operations/verify.js +0 -170
  178. package/lib/skill-runtime/operations/worker-run.js +0 -531
  179. package/lib/skill-runtime/operations/worker.js +0 -33
  180. package/lib/skill-runtime/planner.js +0 -539
  181. package/lib/skill-runtime/readiness.js +0 -84
  182. package/lib/skill-runtime/review-records.js +0 -123
  183. package/lib/skill-runtime/review.js +0 -855
  184. package/lib/skill-runtime/schemas.js +0 -746
  185. package/lib/skill-runtime/task-contract.js +0 -187
  186. package/lib/skill-runtime/team-state.js +0 -122
  187. package/lib/skill-runtime/workflow-context.js +0 -748
@@ -1,187 +0,0 @@
1
- /**
2
- * [INPUT]: 接收 tasks.md 原始 Markdown 字符串;无文件 IO、无全局状态。
3
- * [OUTPUT]: 对外暴露 extractTasksContractSummary / extractTasksRootCauseContract → {found, content, fields}。
4
- * [POS]: REQ-003 task-contract 纯函数层;后续 compile / validate / migrate 复用本文件的解析 engine。
5
- * [PROTOCOL]: 变更时更新此头部,然后检查 CLAUDE.md
6
- */
7
-
8
- // ============================================================================
9
- // Section field schema
10
- // ============================================================================
11
-
12
- const CONTRACT_FIELD_MAP = {
13
- 'Change': 'change',
14
- 'Mode': 'mode',
15
- 'Profile': 'profile',
16
- 'Approval': 'approval',
17
- 'Goal': 'goal',
18
- 'Do Not Do': 'doNotDo',
19
- 'Approved Direction': 'approvedDirection',
20
- 'Acceptance': 'acceptance',
21
- 'Verification': 'verification',
22
- 'Risk / Escalate If': 'risk'
23
- };
24
-
25
- const CONTRACT_SINGLE_LINE = new Set(['change', 'mode', 'profile', 'approval']);
26
- const CONTRACT_LIST = new Set(['goal', 'doNotDo', 'approvedDirection', 'acceptance', 'risk']);
27
- const CONTRACT_VERIFICATION = new Set(['verification']);
28
-
29
- const ROOT_CAUSE_FIELD_MAP = {
30
- 'Change': 'change',
31
- 'Mode': 'mode',
32
- 'Profile': 'profile',
33
- 'Diagnosis': 'diagnosis',
34
- 'Symptom': 'symptom',
35
- 'Reproduction': 'reproduction',
36
- 'Expected': 'expected',
37
- 'Actual': 'actual',
38
- 'Root Cause': 'rootCause',
39
- 'Evidence Chain': 'evidenceChain',
40
- 'Repair Boundary': 'repairBoundary',
41
- 'Prevention': 'prevention',
42
- 'Risk / Escalate If': 'risk'
43
- };
44
-
45
- const ROOT_CAUSE_SINGLE_LINE = new Set(['change', 'mode', 'profile', 'diagnosis']);
46
- const ROOT_CAUSE_LIST = new Set([
47
- 'symptom',
48
- 'reproduction',
49
- 'expected',
50
- 'actual',
51
- 'rootCause',
52
- 'evidenceChain',
53
- 'repairBoundary',
54
- 'prevention',
55
- 'risk'
56
- ]);
57
- const ROOT_CAUSE_VERIFICATION = new Set();
58
-
59
- // ============================================================================
60
- // Heading block extraction (shared engine)
61
- // ============================================================================
62
-
63
- function extractHeadingBlock(text, heading) {
64
- if (typeof text !== 'string') {
65
- throw new TypeError('task-contract parser expects a string input');
66
- }
67
- const escaped = heading.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
68
- const pattern = new RegExp(`(^|\\n)(${escaped}\\r?\\n?)`);
69
- const match = text.match(pattern);
70
- if (!match) {
71
- return { found: false, content: '', body: '' };
72
- }
73
- const headingStart = match.index + match[1].length;
74
- const headingLineEnd = headingStart + match[2].length;
75
- const rest = text.slice(headingLineEnd);
76
- const nextIdx = rest.search(/\n## /);
77
- const blockEnd = nextIdx === -1 ? text.length : headingLineEnd + nextIdx;
78
- return {
79
- found: true,
80
- content: text.slice(headingStart, blockEnd),
81
- body: text.slice(headingLineEnd, blockEnd)
82
- };
83
- }
84
-
85
- // ============================================================================
86
- // Generic section parser
87
- // ============================================================================
88
-
89
- function parseSectionFields(body, schema) {
90
- const { fieldMap, singleLineKeys, listKeys, verificationKeys } = schema;
91
- const lines = body.split('\n');
92
- const fields = {};
93
- let currentLabel = null;
94
- let currentInline = null;
95
- let currentLines = [];
96
-
97
- const flush = () => {
98
- if (!currentLabel) return;
99
- const key = fieldMap[currentLabel];
100
- if (key) {
101
- const value = finalizeFieldValue(key, currentInline, currentLines, singleLineKeys, listKeys, verificationKeys);
102
- if (value !== undefined) fields[key] = value;
103
- }
104
- currentLabel = null;
105
- currentInline = null;
106
- currentLines = [];
107
- };
108
-
109
- for (const line of lines) {
110
- const kv = line.match(/^([A-Z][A-Za-z /]+?):\s*(.*)$/);
111
- if (kv && Object.prototype.hasOwnProperty.call(fieldMap, kv[1])) {
112
- flush();
113
- currentLabel = kv[1];
114
- currentInline = kv[2].length > 0 ? kv[2].trim() : null;
115
- } else if (currentLabel) {
116
- currentLines.push(line);
117
- }
118
- }
119
- flush();
120
- return fields;
121
- }
122
-
123
- function finalizeFieldValue(key, inline, lines, singleLineKeys, listKeys, verificationKeys) {
124
- if (singleLineKeys.has(key)) {
125
- return inline !== null ? inline : undefined;
126
- }
127
- if (listKeys.has(key)) {
128
- const items = lines
129
- .map(line => line.match(/^\s*-\s+(.*)$/))
130
- .filter(Boolean)
131
- .map(match => match[1].trim());
132
- if (items.length > 0) return items;
133
- return inline !== null ? inline : undefined;
134
- }
135
- if (verificationKeys.has(key)) {
136
- const joined = lines.join('\n');
137
- const fenceMatch = joined.match(/```[^\n]*\n([\s\S]*?)```/);
138
- if (fenceMatch) return fenceMatch[1].replace(/^\n+|\n+$/g, '');
139
- const trimmed = joined.replace(/^\n+|\n+$/g, '');
140
- if (trimmed.length > 0) return trimmed;
141
- return inline !== null ? inline : undefined;
142
- }
143
- return undefined;
144
- }
145
-
146
- // ============================================================================
147
- // Public parsers
148
- // ============================================================================
149
-
150
- function extractTasksContractSummary(text) {
151
- const block = extractHeadingBlock(text, '## Contract Summary');
152
- if (!block.found) {
153
- return { found: false, content: '', fields: {} };
154
- }
155
- return {
156
- found: true,
157
- content: block.content,
158
- fields: parseSectionFields(block.body, {
159
- fieldMap: CONTRACT_FIELD_MAP,
160
- singleLineKeys: CONTRACT_SINGLE_LINE,
161
- listKeys: CONTRACT_LIST,
162
- verificationKeys: CONTRACT_VERIFICATION
163
- })
164
- };
165
- }
166
-
167
- function extractTasksRootCauseContract(text) {
168
- const block = extractHeadingBlock(text, '## Root Cause Contract');
169
- if (!block.found) {
170
- return { found: false, content: '', fields: {} };
171
- }
172
- return {
173
- found: true,
174
- content: block.content,
175
- fields: parseSectionFields(block.body, {
176
- fieldMap: ROOT_CAUSE_FIELD_MAP,
177
- singleLineKeys: ROOT_CAUSE_SINGLE_LINE,
178
- listKeys: ROOT_CAUSE_LIST,
179
- verificationKeys: ROOT_CAUSE_VERIFICATION
180
- })
181
- };
182
- }
183
-
184
- module.exports = {
185
- extractTasksContractSummary,
186
- extractTasksRootCauseContract
187
- };
@@ -1,122 +0,0 @@
1
- /**
2
- * [INPUT]: 依赖 canonical path/store 的文件读写能力,接收 repoRoot/changeId 以维护 Team 真相源。
3
- * [OUTPUT]: 对外提供 Team state 真相源路径与读写能力。
4
- * [POS]: skill runtime 的 Team 状态桥接层,让 delegate/team runtime 统一落到 devflow/changes。
5
- * [PROTOCOL]: 变更时更新此头部,然后检查 CLAUDE.md
6
- */
7
-
8
- const fs = require('fs');
9
- const path = require('path');
10
- const { ensureDir, readJson, writeJson, nowIso } = require('./store');
11
- const { getChangePaths } = require('./paths');
12
-
13
- function getTeamStatePath(repoRoot, changeId) {
14
- return path.join(getChangePaths(repoRoot, changeId).executionDir, 'team-state.json');
15
- }
16
-
17
- function normalizeTeamState(changeId, payload = {}) {
18
- return {
19
- changeId,
20
- status: payload.status || 'delegated',
21
- phase: payload.phase || 'delegate',
22
- branch: payload.branch || 'unknown',
23
- updatedAt: payload.updatedAt || nowIso(),
24
- planVersion: payload.planVersion || 1,
25
- source: payload.source || {
26
- kind: 'skill-runtime-autopilot',
27
- derivedFrom: 'devflow/changes'
28
- },
29
- team: payload.team || null,
30
- ralphLoop: payload.ralphLoop || undefined
31
- };
32
- }
33
-
34
- async function readTeamState(repoRoot, changeId) {
35
- const truth = await readJson(getTeamStatePath(repoRoot, changeId), null);
36
- return truth?.team ? normalizeTeamState(changeId, truth) : null;
37
- }
38
-
39
- async function writeTeamState(repoRoot, changeId, payload) {
40
- const next = normalizeTeamState(changeId, payload);
41
- const truthPath = getTeamStatePath(repoRoot, changeId);
42
- await ensureDir(path.dirname(truthPath));
43
- await writeJson(truthPath, next);
44
-
45
- return next;
46
- }
47
-
48
- async function updateTeamState(repoRoot, changeId, updater) {
49
- const current = (await readTeamState(repoRoot, changeId)) || normalizeTeamState(changeId, {});
50
- const nextPayload = await updater(current);
51
- if (!nextPayload) {
52
- return current;
53
- }
54
- return writeTeamState(repoRoot, changeId, nextPayload);
55
- }
56
-
57
- function buildInitialTeamState(changeId, manifest, assignments, branch) {
58
- const delegateAssignments = assignments.filter((item) => item.route !== 'direct');
59
- const uniqueWorkers = Array.from(
60
- delegateAssignments.reduce((map, item) => {
61
- if (!map.has(item.workerId)) {
62
- map.set(item.workerId, {
63
- id: item.workerId,
64
- role: item.role,
65
- status: 'idle',
66
- currentTask: null,
67
- completedTasks: [],
68
- lastActiveAt: nowIso()
69
- });
70
- }
71
- return map;
72
- }, new Map()).values()
73
- );
74
-
75
- return normalizeTeamState(changeId, {
76
- status: 'delegated',
77
- phase: 'delegate',
78
- branch,
79
- planVersion: manifest.metadata?.planVersion || 1,
80
- source: {
81
- kind: 'skill-runtime-autopilot',
82
- derivedFrom: 'devflow/changes'
83
- },
84
- team: {
85
- mode: delegateAssignments.some((item) => item.route === 'team') ? 'parallel' : 'sequential',
86
- lead: 'main-agent',
87
- teammates: uniqueWorkers,
88
- taskAssignments: Object.fromEntries(delegateAssignments.map((item) => [item.taskId, item.workerId])),
89
- createdAt: nowIso(),
90
- updatedAt: nowIso()
91
- }
92
- });
93
- }
94
-
95
- function findLatestTeamStatePath(repoRoot) {
96
- const changesRoot = path.join(repoRoot, 'devflow', 'changes');
97
- if (!fs.existsSync(changesRoot)) {
98
- return null;
99
- }
100
-
101
- const candidates = fs.readdirSync(changesRoot)
102
- .map((name) => ({
103
- path: path.join(changesRoot, name, 'execution', 'team-state.json'),
104
- mtime: fs.existsSync(path.join(changesRoot, name))
105
- ? fs.statSync(path.join(changesRoot, name)).mtime.getTime()
106
- : 0
107
- }))
108
- .filter((item) => fs.existsSync(item.path))
109
- .sort((a, b) => b.mtime - a.mtime);
110
-
111
- return candidates[0]?.path || null;
112
- }
113
-
114
- module.exports = {
115
- getTeamStatePath,
116
- normalizeTeamState,
117
- readTeamState,
118
- writeTeamState,
119
- updateTeamState,
120
- buildInitialTeamState,
121
- findLatestTeamStatePath
122
- };