cc-devflow 4.5.11 → 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.
- package/.claude/skills/cc-act/CHANGELOG.md +18 -0
- package/.claude/skills/cc-act/PLAYBOOK.md +17 -269
- package/.claude/skills/cc-act/SKILL.md +38 -425
- package/.claude/skills/cc-act/assets/PROJECT_POSTMORTEM_INDEX_TEMPLATE.md +2 -13
- package/.claude/skills/cc-act/assets/PROJECT_POSTMORTEM_TEMPLATE.md +1 -9
- package/.claude/skills/cc-act/assets/PR_BRIEF_TEMPLATE.md +21 -177
- package/.claude/skills/cc-act/references/closure-contract.md +12 -63
- package/.claude/skills/cc-act/references/git-commit-guidelines.md +5 -5
- package/.claude/skills/cc-act/scripts/cc-act-common.sh +5 -322
- package/.claude/skills/cc-act/scripts/detect-ship-target.sh +11 -2
- package/.claude/skills/cc-act/scripts/inspect-git-index.sh +58 -0
- package/.claude/skills/cc-act/scripts/render-pr-brief.sh +40 -440
- package/.claude/skills/cc-act/scripts/verify-act-gate.sh +10 -50
- package/.claude/skills/cc-check/CHANGELOG.md +18 -0
- package/.claude/skills/cc-check/PLAYBOOK.md +19 -273
- package/.claude/skills/cc-check/SKILL.md +33 -456
- package/.claude/skills/cc-check/references/review-contract.md +12 -147
- package/.claude/skills/cc-dev/CHANGELOG.md +15 -0
- package/.claude/skills/cc-dev/PLAYBOOK.md +1 -1
- package/.claude/skills/cc-dev/SKILL.md +52 -137
- package/.claude/skills/cc-dev/scripts/resolve-cc-devflow.sh +181 -0
- package/.claude/skills/cc-do/CHANGELOG.md +11 -0
- package/.claude/skills/cc-do/PLAYBOOK.md +19 -113
- package/.claude/skills/cc-do/SKILL.md +39 -245
- package/.claude/skills/cc-do/references/execution-recovery.md +15 -109
- package/.claude/skills/cc-do/scripts/cc-do-common.sh +5 -57
- package/.claude/skills/cc-do/scripts/check-task-status.sh +35 -65
- package/.claude/skills/cc-do/scripts/mark-task-complete.sh +9 -46
- package/.claude/skills/cc-do/scripts/select-ready-tasks.sh +29 -97
- package/.claude/skills/cc-investigate/CHANGELOG.md +16 -0
- package/.claude/skills/cc-investigate/PLAYBOOK.md +20 -180
- package/.claude/skills/cc-investigate/SKILL.md +64 -246
- package/.claude/skills/cc-investigate/assets/TASKS_TEMPLATE.md +48 -98
- package/.claude/skills/cc-investigate/references/investigation-contract.md +14 -218
- package/.claude/skills/cc-next/CHANGELOG.md +6 -0
- package/.claude/skills/cc-next/PLAYBOOK.md +12 -8
- package/.claude/skills/cc-next/SKILL.md +34 -140
- package/.claude/skills/cc-plan/CHANGELOG.md +16 -0
- package/.claude/skills/cc-plan/PLAYBOOK.md +22 -161
- package/.claude/skills/cc-plan/SKILL.md +45 -295
- package/.claude/skills/cc-plan/assets/TASKS_TEMPLATE.md +30 -228
- package/.claude/skills/cc-plan/references/planning-contract.md +24 -161
- package/.claude/skills/cc-plan/scripts/next-change-key.sh +8 -44
- package/.claude/skills/cc-plan/scripts/parse-task-dependencies.js +2 -2
- package/.claude/skills/cc-plan/scripts/validate-scope.sh +1 -1
- package/.claude/skills/cc-pr-land/SKILL.md +14 -114
- package/.claude/skills/cc-pr-review/CHANGELOG.md +4 -0
- package/.claude/skills/cc-pr-review/SKILL.md +20 -103
- package/.claude/skills/cc-review/CHANGELOG.md +17 -0
- package/.claude/skills/cc-review/PLAYBOOK.md +13 -86
- package/.claude/skills/cc-review/SKILL.md +53 -241
- package/.claude/skills/cc-review/references/e2e-and-plugin-verification.md +2 -2
- package/.claude/skills/cc-review/references/implementation-review-branch.md +7 -147
- package/.claude/skills/cc-review/references/plan-review-branch.md +5 -147
- package/.claude/skills/cc-review/references/review-methods.md +10 -218
- package/.claude/skills/cc-review/scripts/collect-review-context.sh +4 -63
- package/.claude/skills/cc-roadmap/PLAYBOOK.md +1 -1
- package/.claude/skills/cc-roadmap/SKILL.md +3 -3
- package/.claude/skills/cc-simplify/CHANGELOG.md +7 -0
- package/.claude/skills/cc-simplify/SKILL.md +26 -21
- package/.claude/skills/cc-spec-init/PLAYBOOK.md +12 -48
- package/.claude/skills/cc-spec-init/SKILL.md +29 -132
- package/.claude/skills/cc-spec-init/references/spec-contract.md +8 -17
- package/CHANGELOG.md +13 -0
- package/bin/cc-devflow-cli.js +20 -260
- package/bin/cc-devflow.js +44 -7
- package/docs/commands/README.md +1 -1
- package/docs/commands/README.zh-CN.md +1 -1
- package/docs/examples/README.md +1 -1
- package/docs/examples/START-HERE.md +14 -15
- package/docs/examples/example-bindings.json +11 -11
- package/docs/examples/full-design-blocked/README.md +4 -6
- package/docs/examples/full-design-blocked/changes/REQ-002-bulk-invite-import/{planning/tasks.md → task.md} +20 -15
- package/docs/examples/local-handoff/README.md +8 -11
- package/docs/examples/local-handoff/changes/REQ-003-audit-log-export/handoff/pr-brief.md +31 -0
- package/docs/examples/local-handoff/changes/REQ-003-audit-log-export/{planning/tasks.md → task.md} +18 -13
- package/docs/examples/pdca-loop/README.md +6 -9
- package/docs/examples/pdca-loop/changes/REQ-001-copy-invite-link/handoff/pr-brief.md +9 -11
- package/docs/examples/pdca-loop/changes/REQ-001-copy-invite-link/{planning/tasks.md → task.md} +18 -13
- package/docs/examples/scripts/check-example-bindings.sh +11 -62
- package/docs/guides/artifact-contract.md +10 -40
- package/docs/guides/getting-started.md +8 -8
- package/docs/guides/getting-started.zh-CN.md +8 -8
- package/docs/guides/minimize-artifacts.md +16 -130
- package/docs/guides/project-postmortem.md +14 -71
- package/lib/compiler/__tests__/skills-registry.test.js +9 -8
- package/lib/compiler/resource-copier.js +29 -0
- package/lib/skill-runtime/__tests__/archive-change.test.js +2 -2
- package/lib/skill-runtime/__tests__/benchmark-skills.test.js +3 -3
- package/lib/skill-runtime/__tests__/cli-bootstrap.integration.test.js +14 -4
- package/lib/skill-runtime/errors.js +3 -3
- package/lib/skill-runtime/index.js +5 -23
- package/lib/skill-runtime/paths.js +5 -52
- package/lib/skill-runtime/query-registry.js +4 -4
- package/lib/skill-runtime/query.js +89 -201
- package/lib/skill-runtime/store.js +4 -40
- package/lib/skill-runtime/trace.js +2 -2
- package/package.json +2 -5
- package/.claude/skills/cc-act/assets/PROJECT_POSTMORTEM_PRINCIPLES_TEMPLATE.md +0 -29
- package/.claude/skills/cc-act/assets/RELEASE_NOTE_TEMPLATE.md +0 -54
- package/.claude/skills/cc-act/scripts/generate-status-report.sh +0 -92
- package/.claude/skills/cc-act/scripts/sync-act-docs.sh +0 -355
- package/.claude/skills/cc-check/assets/REPORT_CARD_TEMPLATE.json +0 -234
- package/.claude/skills/cc-check/scripts/render-report-card.js +0 -438
- package/.claude/skills/cc-check/scripts/verify-gate.sh +0 -85
- package/.claude/skills/cc-do/scripts/build-task-context.sh +0 -175
- package/.claude/skills/cc-do/scripts/record-review-decision.sh +0 -88
- package/.claude/skills/cc-do/scripts/recover-workflow.sh +0 -82
- package/.claude/skills/cc-do/scripts/run-problem-analysis.sh +0 -70
- package/.claude/skills/cc-do/scripts/verify-task-gates.sh +0 -109
- package/.claude/skills/cc-do/scripts/write-task-checkpoint.sh +0 -92
- package/.claude/skills/cc-investigate/assets/TASK_MANIFEST_TEMPLATE.json +0 -224
- package/.claude/skills/cc-plan/assets/TASK_MANIFEST_TEMPLATE.json +0 -178
- package/.claude/skills/cc-spec-init/assets/CHANGE_META_TEMPLATE.json +0 -28
- package/.claude/skills/cc-spec-init/scripts/validate-spec-links.sh +0 -45
- package/docs/examples/full-design-blocked/changes/REQ-002-bulk-invite-import/planning/design.md +0 -234
- package/docs/examples/full-design-blocked/changes/REQ-002-bulk-invite-import/planning/task-manifest.json +0 -488
- package/docs/examples/full-design-blocked/changes/REQ-002-bulk-invite-import/review/report-card.json +0 -189
- package/docs/examples/local-handoff/changes/REQ-003-audit-log-export/handoff/resume-index.md +0 -39
- package/docs/examples/local-handoff/changes/REQ-003-audit-log-export/handoff/status.md +0 -29
- package/docs/examples/local-handoff/changes/REQ-003-audit-log-export/planning/design.md +0 -123
- package/docs/examples/local-handoff/changes/REQ-003-audit-log-export/planning/task-manifest.json +0 -292
- package/docs/examples/local-handoff/changes/REQ-003-audit-log-export/review/report-card.json +0 -136
- package/docs/examples/pdca-loop/changes/REQ-001-copy-invite-link/handoff/status.md +0 -29
- package/docs/examples/pdca-loop/changes/REQ-001-copy-invite-link/planning/design.md +0 -124
- package/docs/examples/pdca-loop/changes/REQ-001-copy-invite-link/planning/task-manifest.json +0 -292
- package/docs/examples/pdca-loop/changes/REQ-001-copy-invite-link/review/report-card.json +0 -136
- package/docs/get-shit-done-strategy-audit.md +0 -518
- package/docs/skill-runtime-migration.md +0 -46
- package/lib/skill-runtime/__tests__/approve.test.js +0 -92
- package/lib/skill-runtime/__tests__/autopilot.test.js +0 -253
- package/lib/skill-runtime/__tests__/benchmark-artifacts.test.js +0 -165
- package/lib/skill-runtime/__tests__/delegation.test.js +0 -97
- package/lib/skill-runtime/__tests__/dispatch.test.js +0 -237
- package/lib/skill-runtime/__tests__/intent.test.js +0 -203
- package/lib/skill-runtime/__tests__/lifecycle.test.js +0 -169
- package/lib/skill-runtime/__tests__/planner.tdd.test.js +0 -331
- package/lib/skill-runtime/__tests__/prepare-pr.test.js +0 -126
- package/lib/skill-runtime/__tests__/query.test.js +0 -860
- package/lib/skill-runtime/__tests__/readiness.test.js +0 -53
- package/lib/skill-runtime/__tests__/release.test.js +0 -85
- package/lib/skill-runtime/__tests__/review-check-integration.test.js +0 -148
- package/lib/skill-runtime/__tests__/review-records.test.js +0 -619
- package/lib/skill-runtime/__tests__/runtime.integration.test.js +0 -351
- package/lib/skill-runtime/__tests__/schemas.test.js +0 -337
- package/lib/skill-runtime/__tests__/task-contract-migrate.test.js +0 -137
- package/lib/skill-runtime/__tests__/task-contract.test.js +0 -874
- package/lib/skill-runtime/__tests__/team-state.test.js +0 -51
- package/lib/skill-runtime/__tests__/verify-artifacts.test.js +0 -203
- package/lib/skill-runtime/__tests__/worker-run.test.js +0 -275
- package/lib/skill-runtime/__tests__/worker.test.js +0 -56
- package/lib/skill-runtime/__tests__/workflow-context-legacy-fallback.test.js +0 -31
- package/lib/skill-runtime/__tests__/workflow-context.test.js +0 -98
- package/lib/skill-runtime/artifacts.js +0 -88
- package/lib/skill-runtime/context-index.js +0 -545
- package/lib/skill-runtime/delegation.js +0 -533
- package/lib/skill-runtime/intent.js +0 -309
- package/lib/skill-runtime/lifecycle.js +0 -294
- package/lib/skill-runtime/operations/CLAUDE.md +0 -19
- package/lib/skill-runtime/operations/approve.js +0 -81
- package/lib/skill-runtime/operations/autopilot-core.js +0 -337
- package/lib/skill-runtime/operations/autopilot-execution.js +0 -307
- package/lib/skill-runtime/operations/autopilot-shared.js +0 -48
- package/lib/skill-runtime/operations/autopilot.js +0 -163
- package/lib/skill-runtime/operations/dispatch.js +0 -416
- package/lib/skill-runtime/operations/init.js +0 -60
- package/lib/skill-runtime/operations/janitor.js +0 -61
- package/lib/skill-runtime/operations/plan.js +0 -59
- package/lib/skill-runtime/operations/prepare-pr.js +0 -25
- package/lib/skill-runtime/operations/release.js +0 -99
- package/lib/skill-runtime/operations/resume.js +0 -126
- package/lib/skill-runtime/operations/review-records.js +0 -265
- package/lib/skill-runtime/operations/snapshot.js +0 -45
- package/lib/skill-runtime/operations/task-contract.js +0 -593
- package/lib/skill-runtime/operations/verify.js +0 -170
- package/lib/skill-runtime/operations/worker-run.js +0 -531
- package/lib/skill-runtime/operations/worker.js +0 -33
- package/lib/skill-runtime/planner.js +0 -539
- package/lib/skill-runtime/readiness.js +0 -84
- package/lib/skill-runtime/review-records.js +0 -123
- package/lib/skill-runtime/review.js +0 -855
- package/lib/skill-runtime/schemas.js +0 -746
- package/lib/skill-runtime/task-contract.js +0 -188
- package/lib/skill-runtime/team-state.js +0 -122
- package/lib/skill-runtime/workflow-context.js +0 -748
|
@@ -428,6 +428,7 @@ async function mirrorDirectoryRecursive(sourceDir, targetDir, options = {}) {
|
|
|
428
428
|
|
|
429
429
|
if (!dryRun) {
|
|
430
430
|
await fs.promises.mkdir(targetDir, { recursive: true, mode: 0o755 });
|
|
431
|
+
await pruneMirroredDirectoryRecursive(sourceDir, targetDir, options);
|
|
431
432
|
}
|
|
432
433
|
|
|
433
434
|
for (const entry of entries) {
|
|
@@ -473,6 +474,34 @@ async function mirrorDirectoryRecursive(sourceDir, targetDir, options = {}) {
|
|
|
473
474
|
return result;
|
|
474
475
|
}
|
|
475
476
|
|
|
477
|
+
async function pruneMirroredDirectoryRecursive(sourceDir, targetDir, options = {}) {
|
|
478
|
+
const { verbose = false } = options;
|
|
479
|
+
|
|
480
|
+
if (!fs.existsSync(targetDir)) {
|
|
481
|
+
return;
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
const targetEntries = await fs.promises.readdir(targetDir, { withFileTypes: true });
|
|
485
|
+
await Promise.all(
|
|
486
|
+
targetEntries.map(async (entry) => {
|
|
487
|
+
const sourcePath = path.join(sourceDir, entry.name);
|
|
488
|
+
const targetPath = path.join(targetDir, entry.name);
|
|
489
|
+
|
|
490
|
+
if (!fs.existsSync(sourcePath)) {
|
|
491
|
+
await fs.promises.rm(targetPath, { recursive: true, force: true });
|
|
492
|
+
if (verbose) {
|
|
493
|
+
console.log(`Pruned stale skill file: ${path.relative(process.cwd(), targetPath)}`);
|
|
494
|
+
}
|
|
495
|
+
return;
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
if (entry.isDirectory()) {
|
|
499
|
+
await pruneMirroredDirectoryRecursive(sourcePath, targetPath, options);
|
|
500
|
+
}
|
|
501
|
+
})
|
|
502
|
+
);
|
|
503
|
+
}
|
|
504
|
+
|
|
476
505
|
// ============================================================
|
|
477
506
|
// clearResourceCache - 清除资源缓存(用于测试)
|
|
478
507
|
// ============================================================
|
|
@@ -61,13 +61,13 @@ describe('restoreChange', () => {
|
|
|
61
61
|
const repoRoot = makeTempRepo();
|
|
62
62
|
const archivedDir = path.join(repoRoot, 'devflow', 'changes', 'archive', '2026-04', 'REQ-002-restored');
|
|
63
63
|
fs.mkdirSync(archivedDir, { recursive: true });
|
|
64
|
-
fs.writeFileSync(path.join(archivedDir, '
|
|
64
|
+
fs.writeFileSync(path.join(archivedDir, 'task.md'), '- [ ] task');
|
|
65
65
|
|
|
66
66
|
const result = restoreChange(repoRoot, archivedDir);
|
|
67
67
|
|
|
68
68
|
expect(result.changeKey).toBe('REQ-002-restored');
|
|
69
69
|
expect(fs.existsSync(result.restored)).toBe(true);
|
|
70
|
-
expect(fs.existsSync(path.join(result.restored, '
|
|
70
|
+
expect(fs.existsSync(path.join(result.restored, 'task.md'))).toBe(true);
|
|
71
71
|
expect(fs.existsSync(archivedDir)).toBe(false);
|
|
72
72
|
|
|
73
73
|
fs.rmSync(repoRoot, { recursive: true, force: true });
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* [INPUT]: 依赖 scripts/benchmark-skills.js 导出的 runBenchmarkSkills 和临时 skill fixture。
|
|
3
|
-
* [OUTPUT]: 验证 benchmark:skills 对 SKILL.md 入口体积执行 byte/line 预算。
|
|
3
|
+
* [OUTPUT]: 验证 benchmark:skills 对 SKILL.md 入口体积执行 byte/line advisory 预算。
|
|
4
4
|
* [POS]: skill 入口瘦身基准的 Red/Green 证据。
|
|
5
5
|
* [PROTOCOL]: 变更时更新此头部,然后检查 CLAUDE.md
|
|
6
6
|
*/
|
|
@@ -78,12 +78,12 @@ describe('benchmark:skills', () => {
|
|
|
78
78
|
});
|
|
79
79
|
});
|
|
80
80
|
|
|
81
|
-
test('
|
|
81
|
+
test('reports advisory failure without blocking when cc-plan grows past the byte budget', () => {
|
|
82
82
|
writeSkill(repoRoot, 'cc-plan', skillBody({ filler: 'x'.repeat(17000) }));
|
|
83
83
|
|
|
84
84
|
const result = runBenchmarkSkills(repoRoot);
|
|
85
85
|
|
|
86
|
-
expect(result.code).toBe(
|
|
86
|
+
expect(result.code).toBe(0);
|
|
87
87
|
expect(result.rows[0]).toMatchObject({
|
|
88
88
|
skill: 'cc-plan',
|
|
89
89
|
correctness_pass: false,
|
|
@@ -108,7 +108,8 @@ describe('cc-devflow cli distribution bootstrap', () => {
|
|
|
108
108
|
|
|
109
109
|
expect(skillContent).not.toContain('<!-- CC-DEVFLOW OUTPUT POLICY START -->');
|
|
110
110
|
expect(skillContent).not.toContain('文档语言: zh-CN');
|
|
111
|
-
expect(skillContent).toContain('cc-devflow
|
|
111
|
+
expect(skillContent).toContain('resolve-cc-devflow.sh');
|
|
112
|
+
expect(skillContent).toContain('bash "$DEVFLOW" config resolve --format policy');
|
|
112
113
|
expect(fs.readFileSync(path.join(customSkillDir, 'SKILL.md'), 'utf8')).toBe('# Custom Skill\n');
|
|
113
114
|
});
|
|
114
115
|
|
|
@@ -177,7 +178,10 @@ describe('cc-devflow cli distribution bootstrap', () => {
|
|
|
177
178
|
expect(runCli(['init', '--dir', repoRoot], repoRoot).status).toBe(0);
|
|
178
179
|
|
|
179
180
|
const targetSkill = path.join(repoRoot, '.claude', 'skills', 'cc-roadmap', 'SKILL.md');
|
|
181
|
+
const staleManagedFile = path.join(repoRoot, '.claude', 'skills', 'cc-act', 'assets', 'STALE.md');
|
|
182
|
+
fs.mkdirSync(path.dirname(staleManagedFile), { recursive: true });
|
|
180
183
|
fs.writeFileSync(targetSkill, '# local override\n');
|
|
184
|
+
fs.writeFileSync(staleManagedFile, '# stale\n');
|
|
181
185
|
|
|
182
186
|
const result = runCli(['init', '--dir', repoRoot, '--force'], repoRoot);
|
|
183
187
|
expect(result.status).toBe(0);
|
|
@@ -186,10 +190,14 @@ describe('cc-devflow cli distribution bootstrap', () => {
|
|
|
186
190
|
fs.readFileSync(path.join(TEMPLATE_ROOT, 'skills', 'cc-roadmap', 'SKILL.md'), 'utf8')
|
|
187
191
|
);
|
|
188
192
|
expect(fs.existsSync(`${targetSkill}.new`)).toBe(false);
|
|
193
|
+
expect(fs.existsSync(staleManagedFile)).toBe(false);
|
|
189
194
|
});
|
|
190
195
|
|
|
191
196
|
test('adapt mirrors public skills into .codex/skills for Codex', () => {
|
|
192
197
|
expect(runCli(['init', '--dir', repoRoot], repoRoot).status).toBe(0);
|
|
198
|
+
const staleCodexAsset = path.join(repoRoot, '.codex', 'skills', 'cc-act', 'assets', 'STALE.md');
|
|
199
|
+
fs.mkdirSync(path.dirname(staleCodexAsset), { recursive: true });
|
|
200
|
+
fs.writeFileSync(staleCodexAsset, '# stale\n');
|
|
193
201
|
|
|
194
202
|
const result = runCli(['adapt', '--cwd', repoRoot, '--platform', 'codex'], repoRoot);
|
|
195
203
|
expect(result.status).toBe(0);
|
|
@@ -202,6 +210,7 @@ describe('cc-devflow cli distribution bootstrap', () => {
|
|
|
202
210
|
expect(fs.existsSync(path.join(repoRoot, '.codex', 'skills', 'cc-review', 'SKILL.md'))).toBe(true);
|
|
203
211
|
expect(fs.existsSync(path.join(repoRoot, '.codex', 'skills', 'cc-check', 'SKILL.md'))).toBe(true);
|
|
204
212
|
expect(fs.existsSync(path.join(repoRoot, '.codex', 'skills', 'cc-act', 'SKILL.md'))).toBe(true);
|
|
213
|
+
expect(fs.existsSync(staleCodexAsset)).toBe(false);
|
|
205
214
|
|
|
206
215
|
const codexInvestigateSkill = fs.readFileSync(
|
|
207
216
|
path.join(repoRoot, '.codex', 'skills', 'cc-investigate', 'SKILL.md'),
|
|
@@ -217,9 +226,9 @@ describe('cc-devflow cli distribution bootstrap', () => {
|
|
|
217
226
|
expect(codexDoSkill.data.writes).toEqual(
|
|
218
227
|
expect.arrayContaining([
|
|
219
228
|
expect.objectContaining({
|
|
220
|
-
path: 'devflow/changes/<change-key>/
|
|
229
|
+
path: 'devflow/changes/<change-key>/task.md',
|
|
221
230
|
durability: 'durable',
|
|
222
|
-
required:
|
|
231
|
+
required: true
|
|
223
232
|
})
|
|
224
233
|
])
|
|
225
234
|
);
|
|
@@ -277,7 +286,8 @@ describe('cc-devflow cli distribution bootstrap', () => {
|
|
|
277
286
|
);
|
|
278
287
|
expect(codexPlanSkill).not.toContain('<!-- CC-DEVFLOW OUTPUT POLICY START -->');
|
|
279
288
|
expect(codexPlanSkill).not.toContain('文档语言: zh-CN');
|
|
280
|
-
expect(codexPlanSkill).toContain('cc-devflow
|
|
289
|
+
expect(codexPlanSkill).toContain('resolve-cc-devflow.sh');
|
|
290
|
+
expect(codexPlanSkill).toContain('bash "$DEVFLOW" config resolve --format policy');
|
|
281
291
|
});
|
|
282
292
|
|
|
283
293
|
test('adapt preserves pre-existing non-public Codex skills and does not mirror new private ones', () => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* [INPUT]: 接收 runtime/query/compiler 边界抛出的错误或失败字段。
|
|
3
|
-
* [OUTPUT]: 生成可序列化 named error,保留
|
|
3
|
+
* [OUTPUT]: 生成可序列化 named error,保留 refs 与 rescue action。
|
|
4
4
|
* [POS]: skill runtime 的失败语义层,避免用 null/false/string 表达可恢复失败。
|
|
5
5
|
* [PROTOCOL]: 变更时更新此头部,然后检查 CLAUDE.md
|
|
6
6
|
*/
|
|
@@ -10,7 +10,7 @@ class SkillRuntimeError extends Error {
|
|
|
10
10
|
super(message);
|
|
11
11
|
this.name = name;
|
|
12
12
|
this.artifactRefs = options.artifactRefs || [];
|
|
13
|
-
this.rescueAction = options.rescueAction || 'inspect-
|
|
13
|
+
this.rescueAction = options.rescueAction || 'inspect-task-md-and-git-history';
|
|
14
14
|
this.details = options.details || {};
|
|
15
15
|
}
|
|
16
16
|
}
|
|
@@ -27,7 +27,7 @@ function serializeError(error, fallbackName = 'SkillRuntimeError') {
|
|
|
27
27
|
name,
|
|
28
28
|
message,
|
|
29
29
|
artifactRefs: error?.artifactRefs || [],
|
|
30
|
-
rescueAction: error?.rescueAction || 'inspect-
|
|
30
|
+
rescueAction: error?.rescueAction || 'inspect-task-md-and-git-history',
|
|
31
31
|
details: error?.details || {}
|
|
32
32
|
};
|
|
33
33
|
}
|
|
@@ -1,44 +1,26 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* [INPUT]: 依赖 skill runtime
|
|
3
|
-
* [OUTPUT]: 统一导出
|
|
4
|
-
* [POS]: skill runtime
|
|
2
|
+
* [INPUT]: 依赖 skill runtime 基础模块。
|
|
3
|
+
* [OUTPUT]: 统一导出 config/path/store/query helpers。
|
|
4
|
+
* [POS]: skill runtime 模块聚合出口,只保留 CLI 仍需的轻量能力。
|
|
5
5
|
* [PROTOCOL]: 变更时更新此头部,然后检查 CLAUDE.md
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
const store = require('./store');
|
|
9
|
-
const schemas = require('./schemas');
|
|
10
|
-
const planner = require('./planner');
|
|
11
9
|
const query = require('./query');
|
|
12
10
|
const queryRegistry = require('./query-registry');
|
|
13
11
|
const errors = require('./errors');
|
|
14
12
|
const trace = require('./trace');
|
|
15
|
-
const readiness = require('./readiness');
|
|
16
|
-
const intent = require('./intent');
|
|
17
|
-
const artifacts = require('./artifacts');
|
|
18
|
-
const lifecycle = require('./lifecycle');
|
|
19
|
-
const teamState = require('./team-state');
|
|
20
|
-
const delegation = require('./delegation');
|
|
21
13
|
const paths = require('./paths');
|
|
22
14
|
const config = require('./config');
|
|
23
|
-
const
|
|
24
|
-
const workerRun = require('./operations/worker-run');
|
|
15
|
+
const archiveChange = require('./archive-change');
|
|
25
16
|
|
|
26
17
|
module.exports = {
|
|
27
18
|
...store,
|
|
28
|
-
...schemas,
|
|
29
|
-
...planner,
|
|
30
19
|
...query,
|
|
31
20
|
...queryRegistry,
|
|
32
21
|
...errors,
|
|
33
22
|
...trace,
|
|
34
|
-
...readiness,
|
|
35
|
-
...artifacts,
|
|
36
|
-
...intent,
|
|
37
|
-
...lifecycle,
|
|
38
|
-
...teamState,
|
|
39
|
-
...delegation,
|
|
40
23
|
...paths,
|
|
41
24
|
...config,
|
|
42
|
-
...
|
|
43
|
-
...workerRun
|
|
25
|
+
...archiveChange
|
|
44
26
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* [INPUT]: 依赖 fs/path,接收 repoRoot/changeId
|
|
3
|
-
* [OUTPUT]: 对外提供 devflow canonical layout 的唯一路径解析能力。
|
|
2
|
+
* [INPUT]: 依赖 fs/path,接收 repoRoot/changeId 等定位参数。
|
|
3
|
+
* [OUTPUT]: 对外提供 devflow canonical change layout 的唯一路径解析能力。
|
|
4
4
|
* [POS]: skill runtime 的路径真相源,完整 change key 才是目录身份。
|
|
5
5
|
* [PROTOCOL]: 变更时更新此头部,然后检查 CLAUDE.md
|
|
6
6
|
*/
|
|
@@ -70,10 +70,6 @@ function getChangesRoot(repoRoot) {
|
|
|
70
70
|
return path.join(getDevflowRoot(repoRoot), 'changes');
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
function getWorkspacesRoot(repoRoot) {
|
|
74
|
-
return path.join(getDevflowRoot(repoRoot), 'workspaces');
|
|
75
|
-
}
|
|
76
|
-
|
|
77
73
|
function listChangeKeys(repoRoot) {
|
|
78
74
|
const changesRoot = getChangesRoot(repoRoot);
|
|
79
75
|
if (!fs.existsSync(changesRoot)) {
|
|
@@ -196,56 +192,15 @@ function nextChangeKey(repoRoot, prefix, description) {
|
|
|
196
192
|
function getChangePaths(repoRoot, changeId, options = {}) {
|
|
197
193
|
const changeKey = resolveChangeKey(repoRoot, changeId, options);
|
|
198
194
|
const changeDir = path.join(getChangesRoot(repoRoot), changeKey);
|
|
199
|
-
const metaDir = path.join(changeDir, 'meta');
|
|
200
|
-
const planningDir = path.join(changeDir, 'planning');
|
|
201
|
-
const executionDir = path.join(changeDir, 'execution');
|
|
202
|
-
const reviewDir = path.join(changeDir, 'review');
|
|
203
195
|
const handoffDir = path.join(changeDir, 'handoff');
|
|
204
196
|
|
|
205
197
|
return {
|
|
206
198
|
changeId,
|
|
207
199
|
changeKey,
|
|
208
200
|
changeDir,
|
|
209
|
-
metaDir,
|
|
210
|
-
planningDir,
|
|
211
|
-
executionDir,
|
|
212
|
-
reviewDir,
|
|
213
201
|
handoffDir,
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
workspacesDir: path.join(getWorkspacesRoot(repoRoot), changeKey)
|
|
217
|
-
};
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
function getTaskPaths(repoRoot, changeId, taskId, options = {}) {
|
|
221
|
-
const change = getChangePaths(repoRoot, changeId, options);
|
|
222
|
-
const taskDir = path.join(change.tasksDir, taskId);
|
|
223
|
-
|
|
224
|
-
return {
|
|
225
|
-
...change,
|
|
226
|
-
taskId,
|
|
227
|
-
taskDir,
|
|
228
|
-
eventsPath: path.join(taskDir, 'events.jsonl')
|
|
229
|
-
};
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
function getWorkerPaths(repoRoot, changeId, workerId, options = {}) {
|
|
233
|
-
const change = getChangePaths(repoRoot, changeId, options);
|
|
234
|
-
const workspacePath = path.join(change.workspacesDir, workerId);
|
|
235
|
-
const workerDir = path.join(workspacePath, '.runtime');
|
|
236
|
-
|
|
237
|
-
return {
|
|
238
|
-
...change,
|
|
239
|
-
workerId,
|
|
240
|
-
workerDir,
|
|
241
|
-
sharedRuntimeDir: path.join(change.workspacesDir, '.runtime'),
|
|
242
|
-
assignmentPath: path.join(workerDir, 'assignment.md'),
|
|
243
|
-
promptPath: path.join(workerDir, 'prompt.md'),
|
|
244
|
-
launchPath: path.join(workerDir, 'launch.md'),
|
|
245
|
-
statePath: path.join(workerDir, 'state.md'),
|
|
246
|
-
journalPath: path.join(workerDir, 'journal.md'),
|
|
247
|
-
sessionLogPath: path.join(workerDir, 'session.log'),
|
|
248
|
-
workspacePath
|
|
202
|
+
taskPath: path.join(changeDir, 'task.md'),
|
|
203
|
+
prBriefPath: path.join(handoffDir, 'pr-brief.md')
|
|
249
204
|
};
|
|
250
205
|
}
|
|
251
206
|
|
|
@@ -256,11 +211,9 @@ module.exports = {
|
|
|
256
211
|
getChangeSlug,
|
|
257
212
|
getDevflowRoot,
|
|
258
213
|
getChangesRoot,
|
|
259
|
-
getWorkspacesRoot,
|
|
260
214
|
nextChangeKey,
|
|
261
215
|
resolveChangeKey,
|
|
262
216
|
buildChangeKey,
|
|
263
217
|
getChangePaths,
|
|
264
|
-
|
|
265
|
-
getWorkerPaths
|
|
218
|
+
assertChangeId
|
|
266
219
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* [INPUT]: 接收 query id、repoRoot/changeId 与只读 handler registry。
|
|
3
|
-
* [OUTPUT]: 返回 typed query result:ok/data 或 named error,并附
|
|
4
|
-
* [POS]: skill runtime
|
|
3
|
+
* [OUTPUT]: 返回 typed query result:ok/data 或 named error,并附 trace。
|
|
4
|
+
* [POS]: skill runtime 的查询分发表,只读派生 task.md 与 Git 语义。
|
|
5
5
|
* [PROTOCOL]: 变更时更新此头部,然后检查 CLAUDE.md
|
|
6
6
|
*/
|
|
7
7
|
|
|
@@ -59,7 +59,7 @@ function createQueryRegistry(entries) {
|
|
|
59
59
|
`Missing required query artifact: ${missingRefs.join(', ')}`,
|
|
60
60
|
{
|
|
61
61
|
artifactRefs: missingRefs,
|
|
62
|
-
rescueAction: 'create
|
|
62
|
+
rescueAction: 'create task.md before running this query'
|
|
63
63
|
}
|
|
64
64
|
);
|
|
65
65
|
}
|
|
@@ -84,7 +84,7 @@ function createQueryRegistry(entries) {
|
|
|
84
84
|
event: `query.${queryId}.failed`,
|
|
85
85
|
changeId: context.changeId,
|
|
86
86
|
artifactRefs,
|
|
87
|
-
nextAction: error.rescueAction || 'inspect-
|
|
87
|
+
nextAction: error.rescueAction || 'inspect-task-md-and-git-history'
|
|
88
88
|
})
|
|
89
89
|
};
|
|
90
90
|
}
|
|
@@ -1,238 +1,126 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* [INPUT]: 依赖
|
|
3
|
-
* [OUTPUT]:
|
|
4
|
-
* [POS]:
|
|
2
|
+
* [INPUT]: 依赖 task.md、handoff/pr-brief.md 与 Git 状态。
|
|
3
|
+
* [OUTPUT]: 提供 Git-first workflow-context 查询,不读取流程 JSON。
|
|
4
|
+
* [POS]: cc-devflow CLI 的只读上下文层;Git 是历史真相,task.md 是任务真相。
|
|
5
5
|
* [PROTOCOL]: 变更时更新此头部,然后检查 CLAUDE.md
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
getReportCardPath,
|
|
12
|
-
exists,
|
|
13
|
-
readJson
|
|
14
|
-
} = require('./store');
|
|
15
|
-
const { getIntentPrBriefPath } = require('./artifacts');
|
|
16
|
-
const { deriveManifestExecutionState } = require('./planner');
|
|
17
|
-
const {
|
|
18
|
-
getApprovalState,
|
|
19
|
-
deriveLifecycleStage,
|
|
20
|
-
deriveTaskProgress,
|
|
21
|
-
isTaskCompletedStatus
|
|
22
|
-
} = require('./lifecycle');
|
|
8
|
+
const fs = require('fs');
|
|
9
|
+
const path = require('path');
|
|
10
|
+
const { spawnSync } = require('child_process');
|
|
23
11
|
const { createQueryRegistry } = require('./query-registry');
|
|
24
|
-
const {
|
|
25
|
-
const {
|
|
26
|
-
const {
|
|
27
|
-
getWorkflowContext,
|
|
28
|
-
getWorkflowContextArtifactRefs,
|
|
29
|
-
getWorkflowContextRequiredArtifactRefs
|
|
30
|
-
} = require('./workflow-context');
|
|
31
|
-
|
|
32
|
-
async function readQueryArtifact(filePath, { required = true } = {}) {
|
|
33
|
-
try {
|
|
34
|
-
const value = await readJson(filePath, null);
|
|
35
|
-
|
|
36
|
-
if (required && value === null) {
|
|
37
|
-
throw namedError(
|
|
38
|
-
'MissingQueryArtifactError',
|
|
39
|
-
`Missing required query artifact: ${filePath}`,
|
|
40
|
-
{
|
|
41
|
-
artifactRefs: [filePath],
|
|
42
|
-
rescueAction: 'create required workflow artifacts before running this query'
|
|
43
|
-
}
|
|
44
|
-
);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
return value;
|
|
48
|
-
} catch (error) {
|
|
49
|
-
if (error.name === 'MissingQueryArtifactError') {
|
|
50
|
-
throw error;
|
|
51
|
-
}
|
|
12
|
+
const { getChangePaths } = require('./paths');
|
|
13
|
+
const { createTrace } = require('./trace');
|
|
52
14
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
`Invalid query artifact ${filePath}: ${error.message}`,
|
|
56
|
-
{
|
|
57
|
-
artifactRefs: [filePath],
|
|
58
|
-
rescueAction: 'repair or regenerate the invalid workflow artifact before running this query',
|
|
59
|
-
details: {
|
|
60
|
-
cause: error.name || 'Error'
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
);
|
|
64
|
-
}
|
|
15
|
+
function readTextIfExists(filePath) {
|
|
16
|
+
return fs.existsSync(filePath) ? fs.readFileSync(filePath, 'utf8') : null;
|
|
65
17
|
}
|
|
66
18
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
*/
|
|
73
|
-
async function getProgress(repoRoot, changeId, options = {}) {
|
|
74
|
-
const manifestPath = getTaskManifestPath(repoRoot, changeId, options);
|
|
75
|
-
const manifest = await readQueryArtifact(manifestPath);
|
|
76
|
-
return deriveTaskProgress(manifest.tasks || []);
|
|
77
|
-
}
|
|
19
|
+
function runGit(repoRoot, args) {
|
|
20
|
+
const result = spawnSync('git', args, {
|
|
21
|
+
cwd: repoRoot,
|
|
22
|
+
encoding: 'utf8'
|
|
23
|
+
});
|
|
78
24
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
* @param {string} repoRoot - 仓库根目录
|
|
82
|
-
* @param {string} changeId - 需求 ID
|
|
83
|
-
* @returns {Promise<Object|null>} 下一个任务对象或 null
|
|
84
|
-
*/
|
|
85
|
-
async function getNextTask(repoRoot, changeId, options = {}) {
|
|
86
|
-
const manifestPath = getTaskManifestPath(repoRoot, changeId, options);
|
|
87
|
-
const manifest = await readQueryArtifact(manifestPath);
|
|
88
|
-
const executionState = deriveManifestExecutionState(manifest.tasks || []);
|
|
89
|
-
const activePhase = executionState.activePhase;
|
|
90
|
-
const completedIds = new Set(
|
|
91
|
-
(manifest.tasks || [])
|
|
92
|
-
.filter((task) => isTaskCompletedStatus(task.status))
|
|
93
|
-
.map((task) => task.id)
|
|
94
|
-
);
|
|
95
|
-
const currentTaskId = manifest.currentTaskId ?? executionState.currentTaskId;
|
|
96
|
-
|
|
97
|
-
if (currentTaskId) {
|
|
98
|
-
const currentTask = manifest.tasks.find((task) => task.id === currentTaskId);
|
|
99
|
-
if (currentTask && currentTask.status === 'pending') {
|
|
100
|
-
return currentTask;
|
|
101
|
-
}
|
|
25
|
+
if (result.status !== 0) {
|
|
26
|
+
return null;
|
|
102
27
|
}
|
|
103
28
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
return false;
|
|
107
|
-
}
|
|
29
|
+
return result.stdout.trim();
|
|
30
|
+
}
|
|
108
31
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
32
|
+
function parseTaskSummary(markdown) {
|
|
33
|
+
const lines = String(markdown || '').split(/\r?\n/);
|
|
34
|
+
const tasks = [];
|
|
112
35
|
|
|
113
|
-
|
|
114
|
-
|
|
36
|
+
for (const line of lines) {
|
|
37
|
+
const match = line.match(/^\s*-\s+\[( |x|X)\]\s+((?:T\d+|[A-Z]+-\d+)[^:\n]*)(?::\s*)?(.*)$/);
|
|
38
|
+
if (!match) continue;
|
|
115
39
|
|
|
116
|
-
|
|
117
|
-
|
|
40
|
+
tasks.push({
|
|
41
|
+
id: match[2].trim().split(/\s+/)[0],
|
|
42
|
+
title: (match[3] || match[2]).trim(),
|
|
43
|
+
status: match[1].toLowerCase() === 'x' ? 'done' : 'pending'
|
|
44
|
+
});
|
|
45
|
+
}
|
|
118
46
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
* @param {string} repoRoot - 仓库根目录
|
|
122
|
-
* @param {string} changeId - 需求 ID
|
|
123
|
-
* @returns {Promise<Object>} 完整状态对象
|
|
124
|
-
*/
|
|
125
|
-
async function getFullState(repoRoot, changeId, options = {}) {
|
|
126
|
-
const statePath = getRuntimeStatePath(repoRoot, changeId, options);
|
|
127
|
-
const reportPath = getReportCardPath(repoRoot, changeId, options);
|
|
128
|
-
const prBriefPath = getIntentPrBriefPath(repoRoot, changeId, options);
|
|
129
|
-
|
|
130
|
-
const [state, manifest, hasPrBrief] = await Promise.all([
|
|
131
|
-
readQueryArtifact(statePath),
|
|
132
|
-
readQueryArtifact(getTaskManifestPath(repoRoot, changeId, options)),
|
|
133
|
-
exists(prBriefPath)
|
|
134
|
-
]);
|
|
135
|
-
const progress = await getProgress(repoRoot, changeId, options);
|
|
136
|
-
const nextTask = await getNextTask(repoRoot, changeId, options);
|
|
137
|
-
const report = await readQueryArtifact(reportPath, { required: false });
|
|
47
|
+
const completed = tasks.filter((task) => task.status === 'done').length;
|
|
48
|
+
const next = tasks.find((task) => task.status === 'pending') || null;
|
|
138
49
|
|
|
139
50
|
return {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
initializedAt: state.initializedAt,
|
|
145
|
-
plannedAt: state.plannedAt,
|
|
146
|
-
verifiedAt: state.verifiedAt,
|
|
147
|
-
releasedAt: state.releasedAt,
|
|
148
|
-
updatedAt: state.updatedAt,
|
|
149
|
-
stage: deriveLifecycleStage({ state, manifest, report, hasPrBrief }),
|
|
150
|
-
approval: getApprovalState(state, manifest)
|
|
151
|
-
},
|
|
152
|
-
progress,
|
|
153
|
-
nextTask,
|
|
154
|
-
delivery: {
|
|
155
|
-
prBriefPath: hasPrBrief ? prBriefPath : null
|
|
156
|
-
},
|
|
157
|
-
quality: report ? {
|
|
158
|
-
overall: report.overall,
|
|
159
|
-
verdict: report.verdict || (report.overall === 'pass' ? 'pass' : 'fail'),
|
|
160
|
-
reviewStatus: report.review?.status || 'skipped',
|
|
161
|
-
reviewFindings: (report.review?.findings || []).length,
|
|
162
|
-
blockingFindings: report.blockingFindings,
|
|
163
|
-
timestamp: report.timestamp
|
|
164
|
-
} : null
|
|
51
|
+
total: tasks.length,
|
|
52
|
+
completed,
|
|
53
|
+
pending: tasks.length - completed,
|
|
54
|
+
next
|
|
165
55
|
};
|
|
166
56
|
}
|
|
167
57
|
|
|
168
|
-
|
|
169
|
-
const
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
`Missing report card for ${changeId}`,
|
|
176
|
-
{
|
|
177
|
-
artifactRefs: [reportPath],
|
|
178
|
-
rescueAction: 'run cc-check and create review/report-card.json before cc-act'
|
|
179
|
-
}
|
|
180
|
-
);
|
|
181
|
-
}
|
|
58
|
+
function getWorkflowContextArtifactRefs(repoRoot, changeId, options = {}) {
|
|
59
|
+
const change = getChangePaths(repoRoot, changeId, options);
|
|
60
|
+
return [
|
|
61
|
+
path.join(change.changeDir, 'task.md'),
|
|
62
|
+
path.join(change.handoffDir, 'pr-brief.md')
|
|
63
|
+
];
|
|
64
|
+
}
|
|
182
65
|
|
|
183
|
-
|
|
66
|
+
function getWorkflowContextRequiredArtifactRefs(repoRoot, changeId, options = {}) {
|
|
67
|
+
const change = getChangePaths(repoRoot, changeId, options);
|
|
68
|
+
return [path.join(change.changeDir, 'task.md')];
|
|
184
69
|
}
|
|
185
70
|
|
|
186
|
-
function
|
|
187
|
-
const
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
};
|
|
71
|
+
async function getWorkflowContext(repoRoot, changeId, options = {}) {
|
|
72
|
+
const change = getChangePaths(repoRoot, changeId, options);
|
|
73
|
+
const taskPath = path.join(change.changeDir, 'task.md');
|
|
74
|
+
const prBriefPath = path.join(change.handoffDir, 'pr-brief.md');
|
|
75
|
+
const taskMarkdown = readTextIfExists(taskPath) || '';
|
|
76
|
+
const taskSummary = parseTaskSummary(taskMarkdown);
|
|
193
77
|
|
|
194
|
-
|
|
78
|
+
const branch = runGit(repoRoot, ['branch', '--show-current']) || '';
|
|
79
|
+
const head = runGit(repoRoot, ['rev-parse', '--short', 'HEAD']) || '';
|
|
80
|
+
const status = runGit(repoRoot, ['status', '--short']) || '';
|
|
81
|
+
const recentCommits = runGit(repoRoot, ['log', '--oneline', '-5']) || '';
|
|
82
|
+
|
|
83
|
+
return {
|
|
84
|
+
changeId,
|
|
85
|
+
changeKey: change.changeKey,
|
|
86
|
+
nextAction: {
|
|
87
|
+
skill: taskSummary.next ? 'cc-do' : 'cc-check',
|
|
88
|
+
taskId: taskSummary.next ? taskSummary.next.id : null
|
|
89
|
+
},
|
|
90
|
+
files: {
|
|
91
|
+
task: taskPath,
|
|
92
|
+
prBrief: fs.existsSync(prBriefPath) ? prBriefPath : null
|
|
93
|
+
},
|
|
94
|
+
taskSummary,
|
|
95
|
+
git: {
|
|
96
|
+
branch,
|
|
97
|
+
head,
|
|
98
|
+
dirty: status.length > 0,
|
|
99
|
+
status: status ? status.split(/\r?\n/) : [],
|
|
100
|
+
recentCommits: recentCommits ? recentCommits.split(/\r?\n/) : []
|
|
101
|
+
}
|
|
102
|
+
};
|
|
195
103
|
}
|
|
196
104
|
|
|
197
105
|
const registry = createQueryRegistry([
|
|
198
|
-
{
|
|
199
|
-
id: 'progress',
|
|
200
|
-
artifactRefs: ({ repoRoot, changeId, changeKey }) => queryArtifactRefs(repoRoot, changeId, ['manifest'], { changeKey }),
|
|
201
|
-
requiredArtifactRefs: ({ repoRoot, changeId, changeKey }) => queryArtifactRefs(repoRoot, changeId, ['manifest'], { changeKey }),
|
|
202
|
-
handler: ({ repoRoot, changeId, changeKey }) => getProgress(repoRoot, changeId, { changeKey })
|
|
203
|
-
},
|
|
204
|
-
{
|
|
205
|
-
id: 'next-task',
|
|
206
|
-
artifactRefs: ({ repoRoot, changeId, changeKey }) => queryArtifactRefs(repoRoot, changeId, ['manifest'], { changeKey }),
|
|
207
|
-
requiredArtifactRefs: ({ repoRoot, changeId, changeKey }) => queryArtifactRefs(repoRoot, changeId, ['manifest'], { changeKey }),
|
|
208
|
-
handler: ({ repoRoot, changeId, changeKey }) => getNextTask(repoRoot, changeId, { changeKey })
|
|
209
|
-
},
|
|
210
|
-
{
|
|
211
|
-
id: 'full-state',
|
|
212
|
-
artifactRefs: ({ repoRoot, changeId, changeKey }) => queryArtifactRefs(repoRoot, changeId, ['state', 'manifest', 'report', 'prBrief'], { changeKey }),
|
|
213
|
-
requiredArtifactRefs: ({ repoRoot, changeId, changeKey }) => queryArtifactRefs(repoRoot, changeId, ['state', 'manifest'], { changeKey }),
|
|
214
|
-
handler: ({ repoRoot, changeId, changeKey }) => getFullState(repoRoot, changeId, { changeKey })
|
|
215
|
-
},
|
|
216
|
-
{
|
|
217
|
-
id: 'ship-readiness',
|
|
218
|
-
artifactRefs: ({ repoRoot, changeId, changeKey }) => queryArtifactRefs(repoRoot, changeId, ['report'], { changeKey }),
|
|
219
|
-
handler: ({ repoRoot, changeId, changeKey }) => getShipReadiness(repoRoot, changeId, { changeKey })
|
|
220
|
-
},
|
|
221
106
|
{
|
|
222
107
|
id: 'workflow-context',
|
|
223
|
-
artifactRefs: ({ repoRoot, changeId, changeKey }) =>
|
|
224
|
-
|
|
225
|
-
|
|
108
|
+
artifactRefs: ({ repoRoot, changeId, changeKey }) => (
|
|
109
|
+
getWorkflowContextArtifactRefs(repoRoot, changeId, { changeKey })
|
|
110
|
+
),
|
|
111
|
+
requiredArtifactRefs: ({ repoRoot, changeId, changeKey }) => (
|
|
112
|
+
getWorkflowContextRequiredArtifactRefs(repoRoot, changeId, { changeKey })
|
|
113
|
+
),
|
|
114
|
+
nextAction: 'read-task-md-and-git-history',
|
|
226
115
|
handler: ({ repoRoot, changeId, changeKey }) => getWorkflowContext(repoRoot, changeId, { changeKey })
|
|
227
116
|
}
|
|
228
117
|
]);
|
|
229
118
|
|
|
230
119
|
module.exports = {
|
|
231
|
-
getProgress,
|
|
232
|
-
getNextTask,
|
|
233
|
-
getFullState,
|
|
234
|
-
getShipReadiness,
|
|
235
120
|
getWorkflowContext,
|
|
121
|
+
getWorkflowContextArtifactRefs,
|
|
122
|
+
getWorkflowContextRequiredArtifactRefs,
|
|
236
123
|
listQueryIds: registry.listQueryIds,
|
|
237
|
-
runQuery: registry.runQuery
|
|
124
|
+
runQuery: registry.runQuery,
|
|
125
|
+
createTrace
|
|
238
126
|
};
|