@devcxl/opencode-cabbage 0.2.1 → 0.3.1

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 (75) hide show
  1. package/assets/agents/dev-lifecycle.md +23 -19
  2. package/assets/agents/team/architect.md +14 -0
  3. package/assets/agents/team/backend.md +14 -0
  4. package/assets/agents/team/frontend.md +14 -0
  5. package/assets/agents/team/goal-verify.md +54 -0
  6. package/assets/agents/team/reviewer.md +10 -0
  7. package/assets/skills/flow-code/SKILL.md +13 -0
  8. package/assets/skills/flow-review/SKILL.md +7 -0
  9. package/assets/skills/flow-tasks/SKILL.md +42 -0
  10. package/assets/skills/flow-tdd/SKILL.md +208 -0
  11. package/dist/flowrun/adapter.d.ts +49 -0
  12. package/dist/flowrun/adapter.js +293 -0
  13. package/dist/flowrun/adapter.js.map +1 -0
  14. package/dist/flowrun/ci.d.ts +64 -0
  15. package/dist/flowrun/ci.js +184 -0
  16. package/dist/flowrun/ci.js.map +1 -0
  17. package/dist/flowrun/coverage.d.ts +70 -0
  18. package/dist/flowrun/coverage.js +207 -0
  19. package/dist/flowrun/coverage.js.map +1 -0
  20. package/dist/flowrun/digest.d.ts +17 -0
  21. package/dist/flowrun/digest.js +301 -0
  22. package/dist/flowrun/digest.js.map +1 -0
  23. package/dist/flowrun/evaluator.d.ts +38 -0
  24. package/dist/flowrun/evaluator.js +185 -0
  25. package/dist/flowrun/evaluator.js.map +1 -0
  26. package/dist/flowrun/gate.d.ts +10 -0
  27. package/dist/flowrun/gate.js +12 -3
  28. package/dist/flowrun/gate.js.map +1 -1
  29. package/dist/flowrun/github.d.ts +13 -9
  30. package/dist/flowrun/github.js +46 -26
  31. package/dist/flowrun/github.js.map +1 -1
  32. package/dist/flowrun/index.d.ts +10 -3
  33. package/dist/flowrun/index.js +9 -2
  34. package/dist/flowrun/index.js.map +1 -1
  35. package/dist/flowrun/merge.d.ts +35 -2
  36. package/dist/flowrun/merge.js +72 -8
  37. package/dist/flowrun/merge.js.map +1 -1
  38. package/dist/flowrun/migration.d.ts +11 -0
  39. package/dist/flowrun/migration.js +276 -0
  40. package/dist/flowrun/migration.js.map +1 -0
  41. package/dist/flowrun/state.d.ts +79 -0
  42. package/dist/flowrun/state.js +363 -0
  43. package/dist/flowrun/state.js.map +1 -0
  44. package/dist/flowrun/transitions.d.ts +66 -0
  45. package/dist/flowrun/transitions.js +168 -0
  46. package/dist/flowrun/transitions.js.map +1 -0
  47. package/dist/flowrun/types.d.ts +279 -4
  48. package/dist/flowrun/types.js +2 -1
  49. package/dist/flowrun/types.js.map +1 -1
  50. package/dist/flowrun/validator.d.ts +15 -5
  51. package/dist/flowrun/validator.js +117 -5
  52. package/dist/flowrun/validator.js.map +1 -1
  53. package/dist/plugin/agents.d.ts +4 -0
  54. package/dist/plugin/agents.js +19 -0
  55. package/dist/plugin/agents.js.map +1 -1
  56. package/dist/plugin/broker.d.ts +73 -0
  57. package/dist/plugin/broker.js +140 -0
  58. package/dist/plugin/broker.js.map +1 -0
  59. package/dist/plugin/goal.d.ts +39 -1
  60. package/dist/plugin/goal.js +80 -1
  61. package/dist/plugin/goal.js.map +1 -1
  62. package/dist/plugin/prompt-lint.js +129 -0
  63. package/dist/plugin/prompt-lint.js.map +1 -1
  64. package/dist/plugin/server.js +241 -11
  65. package/dist/plugin/server.js.map +1 -1
  66. package/dist/plugin/shell.d.ts +37 -0
  67. package/dist/plugin/shell.js +144 -0
  68. package/dist/plugin/shell.js.map +1 -0
  69. package/dist/plugin/tdd-tool.d.ts +62 -0
  70. package/dist/plugin/tdd-tool.js +336 -0
  71. package/dist/plugin/tdd-tool.js.map +1 -0
  72. package/dist/util/gh.d.ts +8 -1
  73. package/dist/util/gh.js +10 -2
  74. package/dist/util/gh.js.map +1 -1
  75. package/package.json +2 -1
@@ -1,5 +1,15 @@
1
- import { canMerge } from "./gate.js";
2
- import { gh } from "../util/gh.js";
1
+ let mergeGhExecutor = null;
2
+ export function setMergeGhExecutor(fn) {
3
+ mergeGhExecutor = fn;
4
+ }
5
+ async function gh(args) {
6
+ if (mergeGhExecutor) {
7
+ return mergeGhExecutor(args);
8
+ }
9
+ const mod = await import("../util/gh.js");
10
+ return mod.gh(args);
11
+ }
12
+ // ─── Branch Protection ───
3
13
  export async function checkBranchProtection(owner, repo) {
4
14
  try {
5
15
  const { stdout } = await gh(`api repos/${owner}/${repo}/branches/main/protection`);
@@ -26,6 +36,7 @@ export async function checkBranchProtection(owner, repo) {
26
36
  };
27
37
  }
28
38
  }
39
+ // ─── Checkpoint 验证 ───
29
40
  export function validateCheckpoint(cp) {
30
41
  if (cp.status === "pass")
31
42
  return "pass";
@@ -63,24 +74,51 @@ export function validatePRCheckpoints(checkpoints) {
63
74
  }
64
75
  return { allowed: true, checkpointResults: results };
65
76
  }
66
- export function canAutoMergeTask(flowRun, task, protection) {
67
- const flowGate = canMerge(flowRun);
68
- if (!flowGate.allowed) {
69
- return { allowed: false, reason: flowGate.reason, checkpointResults: {} };
70
- }
77
+ // ─── Task-local Merge Gate ───
78
+ /**
79
+ * Task-local merge gate(不依赖全局 canMerge)。
80
+ *
81
+ * 检查条件(按顺序):
82
+ * 1. Task 状态为 "reviewing"
83
+ * 2. 存在 PR Checkpoints
84
+ * 3. 所有 checkpoint 状态为 pass
85
+ * 4. TDD compliance 为 pass / waived / null(无 TDD 要求)
86
+ * 5. Branch Protection 已启用
87
+ *
88
+ * 不要求全局 review Stage 为 pass。
89
+ */
90
+ export function canMergeTaskPR(task, hasBranchProtection) {
91
+ // 1. Task 状态检查
71
92
  if (task.status === "merged") {
72
93
  return { allowed: false, reason: "Task already merged", checkpointResults: {} };
73
94
  }
74
95
  if (task.status !== "reviewing") {
75
96
  return { allowed: false, reason: `Task status is ${task.status}, expected reviewing`, checkpointResults: {} };
76
97
  }
98
+ // 2. PR Checkpoints 存在性
77
99
  if (!task.prCheckpoints) {
78
100
  return { allowed: false, reason: "No PR checkpoints recorded", checkpointResults: {} };
79
101
  }
102
+ // 3. 标准 checkpoint 验证
80
103
  const prResult = validatePRCheckpoints(task.prCheckpoints);
81
104
  if (!prResult.allowed)
82
105
  return prResult;
83
- if (!protection.exists) {
106
+ // 4. TDD compliance 验证
107
+ const tdd = task.prCheckpoints.tddCompliance;
108
+ if (tdd !== null && tdd.status === "fail") {
109
+ prResult.checkpointResults["tddCompliance"] = "fail";
110
+ return {
111
+ allowed: false,
112
+ reason: `TDD compliance failed: ${tdd.summary}`,
113
+ checkpointResults: prResult.checkpointResults,
114
+ };
115
+ }
116
+ // tdd === null → 无 TDD 要求,视为通过
117
+ // tdd.status === "pass" / "waived" → 通过
118
+ prResult.checkpointResults["tddCompliance"] =
119
+ tdd === null ? "skipped" : tdd.status;
120
+ // 5. Branch Protection
121
+ if (!hasBranchProtection) {
84
122
  prResult.checkpointResults.branchProtection = "fail";
85
123
  return {
86
124
  allowed: false,
@@ -91,6 +129,10 @@ export function canAutoMergeTask(flowRun, task, protection) {
91
129
  prResult.checkpointResults.branchProtection = "pass";
92
130
  return prResult;
93
131
  }
132
+ // ─── PR 合并操作 ───
133
+ /**
134
+ * 标准化合并 PR(无安全检查,向后兼容)。
135
+ */
94
136
  export async function mergePR(prNumber) {
95
137
  try {
96
138
  await gh(`pr merge ${prNumber} --squash --delete-branch`);
@@ -100,6 +142,28 @@ export async function mergePR(prNumber) {
100
142
  return { success: false, error: String(err) };
101
143
  }
102
144
  }
145
+ /**
146
+ * Task-local PR 合并(带 --match-head-commit 安全检查)。
147
+ *
148
+ * 步骤:
149
+ * 1. 验证 verifiedSha 非空
150
+ * 2. 使用 gh pr merge --squash --delete-branch --match-head-commit <verifiedSha>
151
+ * 3. 失败时返回错误
152
+ */
153
+ export async function mergeTaskPR(prNumber, verifiedSha) {
154
+ if (!verifiedSha) {
155
+ return { success: false, error: "verifiedSha is required for merge --match-head-commit" };
156
+ }
157
+ try {
158
+ // --match-head-commit 确保只有 verified 的 commit 才会被合并
159
+ await gh(`pr merge ${prNumber} --squash --delete-branch --match-head-commit ${verifiedSha}`);
160
+ return { success: true };
161
+ }
162
+ catch (err) {
163
+ return { success: false, error: String(err) };
164
+ }
165
+ }
166
+ // ─── Revert ───
103
167
  export async function createRevertPR(prNumber, reason) {
104
168
  try {
105
169
  const { stdout } = await gh(`pr view ${prNumber} --json headRefName,headRepository,body,title`);
@@ -1 +1 @@
1
- {"version":3,"file":"merge.js","sourceRoot":"","sources":["../../src/flowrun/merge.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AACpC,OAAO,EAAE,EAAE,EAAE,MAAM,eAAe,CAAA;AAelC,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,KAAa,EAAE,IAAY;IACrE,IAAI,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,aAAa,KAAK,IAAI,IAAI,2BAA2B,CAAC,CAAA;QAClF,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;QAE/B,MAAM,MAAM,GAAa,EAAE,CAAA;QAC3B,MAAM,aAAa,GAAG,IAAI,EAAE,6BAA6B,IAAI,IAAI,CAAA;QACjE,MAAM,cAAc,GAAG,IAAI,EAAE,sBAAsB,EAAE,MAAM,IAAI,EAAE,CAAA;QAEjE,KAAK,MAAM,CAAC,IAAI,cAAc,EAAE,CAAC;YAC/B,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAA;QACxB,CAAC;QAED,OAAO;YACL,MAAM,EAAE,IAAI;YACZ,cAAc,EAAE,MAAM;YACtB,UAAU,EAAE,CAAC,CAAC,aAAa;YAC3B,cAAc,EAAE,aAAa,EAAE,qBAAqB,IAAI,KAAK;SAC9D,CAAA;IACH,CAAC;IAAC,MAAM,CAAC;QACP,OAAO;YACL,MAAM,EAAE,KAAK;YACb,cAAc,EAAE,EAAE;YAClB,UAAU,EAAE,KAAK;YACjB,cAAc,EAAE,KAAK;SACtB,CAAA;IACH,CAAC;AACH,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,EAAc;IAC/C,IAAI,EAAE,CAAC,MAAM,KAAK,MAAM;QAAE,OAAO,MAAM,CAAA;IACvC,IAAI,EAAE,CAAC,MAAM,KAAK,MAAM;QAAE,OAAO,MAAM,CAAA;IACvC,OAAO,SAAS,CAAA;AAClB,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,WAA0B;IAC9D,MAAM,KAAK,GAA+B;QACxC,WAAW,EAAE,WAAW,CAAC,WAAW;QACpC,QAAQ,EAAE,WAAW,CAAC,QAAQ;QAC9B,gBAAgB,EAAE,WAAW,CAAC,gBAAgB;QAC9C,gBAAgB,EAAE,WAAW,CAAC,gBAAgB;QAC9C,gBAAgB,EAAE,WAAW,CAAC,gBAAgB;KAC/C,CAAA;IAED,MAAM,OAAO,GAA4D,EAAE,CAAA;IAE3E,KAAK,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAC/C,OAAO,CAAC,IAAI,CAAC,GAAG,kBAAkB,CAAC,EAAE,CAAC,CAAA;IACxC,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,MAAM,KAAK,MAAM,CAAC,CAAA;IAChF,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,OAAO;YACL,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,uBAAuB,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;YACpE,iBAAiB,EAAE,OAAO;SAC3B,CAAA;IACH,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,MAAM,KAAK,SAAS,CAAC,CAAA;IAClF,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,OAAO;YACL,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,wBAAwB,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;YACpE,iBAAiB,EAAE,OAAO;SAC3B,CAAA;IACH,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,iBAAiB,EAAE,OAAO,EAAE,CAAA;AACtD,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,OAAgB,EAAE,IAAe,EAAE,UAAkC;IACpG,MAAM,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAA;IAClC,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;QACtB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,iBAAiB,EAAE,EAAE,EAAE,CAAA;IAC3E,CAAC;IAED,IAAI,IAAI,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC7B,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,EAAE,EAAE,CAAA;IACjF,CAAC;IAED,IAAI,IAAI,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;QAChC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,kBAAkB,IAAI,CAAC,MAAM,sBAAsB,EAAE,iBAAiB,EAAE,EAAE,EAAE,CAAA;IAC/G,CAAC;IAED,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;QACxB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,4BAA4B,EAAE,iBAAiB,EAAE,EAAE,EAAE,CAAA;IACxF,CAAC;IAED,MAAM,QAAQ,GAAG,qBAAqB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAA;IAC1D,IAAI,CAAC,QAAQ,CAAC,OAAO;QAAE,OAAO,QAAQ,CAAA;IAEtC,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC;QACvB,QAAQ,CAAC,iBAAiB,CAAC,gBAAgB,GAAG,MAAM,CAAA;QACpD,OAAO;YACL,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,uCAAuC;YAC/C,iBAAiB,EAAE,QAAQ,CAAC,iBAAiB;SAC9C,CAAA;IACH,CAAC;IAED,QAAQ,CAAC,iBAAiB,CAAC,gBAAgB,GAAG,MAAM,CAAA;IACpD,OAAO,QAAQ,CAAA;AACjB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,QAAgB;IAC5C,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,YAAY,QAAQ,2BAA2B,CAAC,CAAA;QACzD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAA;IAC1B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAA;IAC/C,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,QAAgB,EAAE,MAAc;IACnE,IAAI,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,WAAW,QAAQ,+CAA+C,CAAC,CAAA;QAC/F,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;QAE7B,MAAM,WAAW,GAAG,WAAW,EAAE,CAAC,KAAK,EAAE,CAAA;QACzC,MAAM,UAAU,GAAG,YAAY,QAAQ,eAAe,MAAM,yCAAyC,CAAA;QAErG,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,EAAE,CAAC,sBAAsB,WAAW,aAAa,UAAU,2BAA2B,CAAC,CAAA;QACvH,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,GAAG,EAAE,EAAE,CAAC,EAAE,CAAA;IACzE,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAA;IAC/B,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"merge.js","sourceRoot":"","sources":["../../src/flowrun/merge.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { FlowRunReadResult } from "./types.js";
2
+ /**
3
+ * v1→v2 幂等迁移器
4
+ *
5
+ * 纯函数:输入 v1 FlowRun (unknown),输出 FlowRunReadResult。
6
+ * - 如果输入已经是 v2 格式 → 直接返回(幂等)
7
+ * - 如果 schemaVersion > 2 → 返回 UNSUPPORTED_SCHEMA
8
+ * - 如果 schemaVersion 缺失/非整数/< 1 → 返回 VALIDATION_FAILED
9
+ * - 如果 schemaVersion === 1 → 执行迁移
10
+ */
11
+ export declare function migrateV1ToV2(flowRun: unknown): FlowRunReadResult;
@@ -0,0 +1,276 @@
1
+ import { CURRENT_SCHEMA_VERSION } from "./types.js";
2
+ /**
3
+ * v1→v2 幂等迁移器
4
+ *
5
+ * 纯函数:输入 v1 FlowRun (unknown),输出 FlowRunReadResult。
6
+ * - 如果输入已经是 v2 格式 → 直接返回(幂等)
7
+ * - 如果 schemaVersion > 2 → 返回 UNSUPPORTED_SCHEMA
8
+ * - 如果 schemaVersion 缺失/非整数/< 1 → 返回 VALIDATION_FAILED
9
+ * - 如果 schemaVersion === 1 → 执行迁移
10
+ */
11
+ export function migrateV1ToV2(flowRun) {
12
+ if (!flowRun || typeof flowRun !== "object") {
13
+ return { ok: false, code: "INVALID_JSON", errors: [{ path: "", message: "FlowRun must be a non-null object" }] };
14
+ }
15
+ const obj = flowRun;
16
+ const version = obj.schemaVersion;
17
+ if (typeof version !== "number" || !Number.isInteger(version) || version < 1) {
18
+ return {
19
+ ok: false,
20
+ code: "VALIDATION_FAILED",
21
+ errors: [{ path: "schemaVersion", message: `Must be a positive integer, got: ${version}` }],
22
+ };
23
+ }
24
+ if (version > CURRENT_SCHEMA_VERSION) {
25
+ return {
26
+ ok: false,
27
+ code: "UNSUPPORTED_SCHEMA",
28
+ errors: [{ path: "schemaVersion", message: `Schema version ${version} is not supported (current: ${CURRENT_SCHEMA_VERSION})` }],
29
+ };
30
+ }
31
+ // 已经是 v2,直接返回
32
+ if (version === CURRENT_SCHEMA_VERSION) {
33
+ return { ok: true, data: obj, migrated: false };
34
+ }
35
+ // v1 → v2 迁移
36
+ try {
37
+ const migrated = doMigrateV1ToV2(obj);
38
+ return { ok: true, data: migrated, migrated: true };
39
+ }
40
+ catch (err) {
41
+ return {
42
+ ok: false,
43
+ code: "MIGRATION_FAILED",
44
+ errors: [{ path: "", message: `Migration failed: ${String(err)}` }],
45
+ };
46
+ }
47
+ }
48
+ function doMigrateV1ToV2(v1) {
49
+ const tasks = {};
50
+ if (v1.tasks && typeof v1.tasks === "object") {
51
+ const v1Tasks = v1.tasks;
52
+ for (const [key, v1Task] of Object.entries(v1Tasks)) {
53
+ tasks[key] = migrateTaskV1ToV2(v1Task, key);
54
+ }
55
+ }
56
+ // v1 PR checkpoints 有旧的 PR 字段,需要补充 v2 的新字段
57
+ // 这些在 migrateTaskV1ToV2 中处理
58
+ return {
59
+ flowRunId: String(v1.flowRunId ?? ""),
60
+ repo: String(v1.repo ?? ""),
61
+ parentIssueNumber: Number(v1.parentIssueNumber ?? 0),
62
+ status: String(v1.status ?? "planned"),
63
+ schemaVersion: CURRENT_SCHEMA_VERSION,
64
+ revision: Number(v1.revision ?? 0),
65
+ stages: migrateStages(v1.stages),
66
+ tasks,
67
+ startedAt: typeof v1.startedAt === "string" ? v1.startedAt : null,
68
+ lastTickAt: typeof v1.lastTickAt === "string" ? v1.lastTickAt : null,
69
+ nextTickAfter: typeof v1.nextTickAfter === "string" ? v1.nextTickAfter : null,
70
+ maxRuntime: Number(v1.maxRuntime ?? 86_400_000),
71
+ completedAt: typeof v1.completedAt === "string" ? v1.completedAt : null,
72
+ repositoryQualityPolicy: { mode: "off", requiredChecks: [] },
73
+ };
74
+ }
75
+ function migrateStages(stages) {
76
+ function defaultStage() {
77
+ return {
78
+ status: "pending",
79
+ requiredArtifacts: [],
80
+ checks: [],
81
+ completedAt: null,
82
+ evidence: [],
83
+ };
84
+ }
85
+ if (!stages || typeof stages !== "object") {
86
+ return {
87
+ requirements: defaultStage(),
88
+ design: defaultStage(),
89
+ tasks: defaultStage(),
90
+ code: defaultStage(),
91
+ test: defaultStage(),
92
+ review: defaultStage(),
93
+ merge: defaultStage(),
94
+ };
95
+ }
96
+ const s = stages;
97
+ const stageKeys = ["requirements", "design", "tasks", "code", "test", "review", "merge"];
98
+ const result = {};
99
+ for (const key of stageKeys) {
100
+ const val = s[key];
101
+ if (val && typeof val === "object") {
102
+ const v = val;
103
+ result[key] = {
104
+ status: (typeof v.status === "string" && ["pending", "running", "pass", "failed", "blocked"].includes(v.status))
105
+ ? v.status
106
+ : "pending",
107
+ requiredArtifacts: Array.isArray(v.requiredArtifacts) ? v.requiredArtifacts : [],
108
+ checks: Array.isArray(v.checks) ? v.checks : [],
109
+ completedAt: typeof v.completedAt === "string" ? v.completedAt : null,
110
+ evidence: Array.isArray(v.evidence) ? v.evidence : [],
111
+ };
112
+ }
113
+ else {
114
+ result[key] = defaultStage();
115
+ }
116
+ }
117
+ return result;
118
+ }
119
+ /**
120
+ * 将单个 v1 Task 迁移为 v2 TaskState
121
+ */
122
+ function migrateTaskV1ToV2(v1Task, recordKey) {
123
+ const hasTestCommands = Array.isArray(v1Task.testCommands) && v1Task.testCommands.length > 0;
124
+ // 迁移 testCommands: string[] → TaskCommand[]
125
+ const testCommands = hasTestCommands
126
+ ? v1Task.testCommands.map(cmd => ({
127
+ command: cmd,
128
+ cwd: ".",
129
+ timeoutMs: 120_000,
130
+ env: {},
131
+ }))
132
+ : [];
133
+ // 迁移 acceptance → acceptanceCriteria
134
+ const v1Acceptance = typeof v1Task.acceptance === "string" ? v1Task.acceptance : "";
135
+ const acceptanceCriteria = [
136
+ {
137
+ id: "legacy-1",
138
+ description: v1Acceptance || "历史任务验收条件(v1 迁移)",
139
+ verification: hasTestCommands ? "regression" : "manual",
140
+ },
141
+ ];
142
+ // 构造 TDD policy(按 spec 10.2)
143
+ const tddPolicy = {
144
+ mode: hasTestCommands ? "relaxed" : "bypass",
145
+ enforcement: "advisory",
146
+ runner: null,
147
+ testFilePatterns: [],
148
+ implementationFilePatterns: [],
149
+ generatedArtifactPatterns: [],
150
+ exception: {
151
+ reason: "legacy schema v1 migration",
152
+ alternativeValidation: hasTestCommands
153
+ ? testCommands.map((cmd, i) => ({
154
+ validationId: `legacy-alt-${i + 1}`,
155
+ kind: "command",
156
+ command: cmd,
157
+ }))
158
+ : [{
159
+ validationId: "legacy-alt-1",
160
+ kind: "manual",
161
+ description: "历史任务未记录自动验证",
162
+ }],
163
+ approval: {
164
+ kind: "legacy-migration",
165
+ fromSchemaVersion: 1,
166
+ },
167
+ },
168
+ source: {
169
+ manifestPath: "legacy:v1",
170
+ revisionSha: "migration:v1",
171
+ },
172
+ };
173
+ // 构造 TDD evidence(完整默认对象)
174
+ const tddEvidence = {
175
+ revision: 0,
176
+ reworkRevision: 0,
177
+ status: "not-recorded",
178
+ taskStart: makeDefaultTaskStart(),
179
+ cycles: [],
180
+ regression: makeDefaultRegression(),
181
+ verification: makeDefaultVerification(),
182
+ alternativeValidation: [],
183
+ reworks: [],
184
+ warnings: ["legacy schema v1 migration: evidence not recorded"],
185
+ updatedAt: null,
186
+ };
187
+ // 迁移 PR checkpoints(保留旧字段 + 新增 null)
188
+ const v1PR = v1Task.prCheckpoints;
189
+ const prCheckpoints = v1PR && typeof v1PR === "object"
190
+ ? migratePRCheckpoints(v1PR)
191
+ : null;
192
+ return {
193
+ id: String(v1Task.id ?? recordKey),
194
+ name: String(v1Task.name ?? recordKey),
195
+ status: (typeof v1Task.status === "string" ? v1Task.status : "pending"),
196
+ dependsOn: Array.isArray(v1Task.dependsOn) ? v1Task.dependsOn : [],
197
+ area: String(v1Task.area ?? ""),
198
+ expectedFiles: Array.isArray(v1Task.expectedFiles) ? v1Task.expectedFiles : [],
199
+ parallelSafe: Boolean(v1Task.parallelSafe ?? false),
200
+ prNumber: typeof v1Task.prNumber === "number" ? v1Task.prNumber : null,
201
+ prCheckpoints,
202
+ blockedReason: typeof v1Task.blockedReason === "string" ? v1Task.blockedReason : null,
203
+ startedAt: typeof v1Task.startedAt === "string" ? v1Task.startedAt : null,
204
+ // v2 新字段
205
+ acceptanceCriteria,
206
+ testCommands,
207
+ verifyCommands: [],
208
+ executionBinding: null,
209
+ tddPolicy,
210
+ tddEvidence,
211
+ coveragePolicy: null,
212
+ };
213
+ }
214
+ function migratePRCheckpoints(v1PR) {
215
+ function makeCheckpoint(name) {
216
+ return {
217
+ name,
218
+ status: "pending",
219
+ evidence: [],
220
+ };
221
+ }
222
+ const getCheckpoint = (key) => {
223
+ const cp = v1PR[key];
224
+ if (cp && typeof cp === "object") {
225
+ const c = cp;
226
+ return {
227
+ name: String(c.name ?? key),
228
+ status: (typeof c.status === "string" && ["pending", "pass", "fail"].includes(c.status))
229
+ ? c.status
230
+ : "pending",
231
+ evidence: Array.isArray(c.evidence) ? c.evidence : [],
232
+ };
233
+ }
234
+ return makeCheckpoint(key);
235
+ };
236
+ return {
237
+ prNumber: Number(v1PR.prNumber ?? 0),
238
+ localChecks: getCheckpoint("localChecks"),
239
+ ciChecks: getCheckpoint("ciChecks"),
240
+ reviewerApproval: getCheckpoint("reviewerApproval"),
241
+ goalVerification: getCheckpoint("goalVerification"),
242
+ branchProtection: getCheckpoint("branchProtection"),
243
+ mergeResult: getCheckpoint("mergeResult"),
244
+ // v2 新增
245
+ tddCompliance: null,
246
+ verification: null,
247
+ coverage: null,
248
+ qualityContractDigest: null,
249
+ };
250
+ }
251
+ function makeDefaultTaskStart() {
252
+ return {
253
+ status: "pending",
254
+ headSha: null,
255
+ treeSha: null,
256
+ startedAt: null,
257
+ };
258
+ }
259
+ function makeDefaultRegression() {
260
+ return {
261
+ status: "pending",
262
+ headSha: null,
263
+ treeSha: null,
264
+ reworkRevision: 0,
265
+ runs: [],
266
+ };
267
+ }
268
+ function makeDefaultVerification() {
269
+ return {
270
+ status: "pending",
271
+ headSha: null,
272
+ treeSha: null,
273
+ runs: [],
274
+ };
275
+ }
276
+ //# sourceMappingURL=migration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migration.js","sourceRoot":"","sources":["../../src/flowrun/migration.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,79 @@
1
+ import type { TddEvidence, TddCycleEvidence, TddCommandEvidence, AcceptanceCriterion, VersionedDigest } from "./types.js";
2
+ export interface StateError {
3
+ code: string;
4
+ message: string;
5
+ }
6
+ export type StateResult<T> = {
7
+ ok: true;
8
+ value: T;
9
+ } | {
10
+ ok: false;
11
+ error: StateError;
12
+ };
13
+ /**
14
+ * 创建初始 TddEvidence(status=not-recorded, revision=0)。
15
+ */
16
+ export declare function createTaskEvidence(): TddEvidence;
17
+ /**
18
+ * 启动一个新的 TDD cycle。
19
+ *
20
+ * 验证:
21
+ * - criterion 存在且 verification=tdd
22
+ * - testPaths 匹配 testFilePatterns
23
+ * - 同 cycleId + 同 workspace digest → 幂等返回原 evidence
24
+ * - 同 cycleId + 不同 workspace digest → CYCLE_CONFLICT
25
+ */
26
+ export declare function startCycle(evidence: TddEvidence, cycleId: string, criterionId: string, testPaths: string[], testSelector: string, workspaceDigest: VersionedDigest, acceptanceCriteria: AcceptanceCriterion[], testFilePatterns: string[]): StateResult<{
27
+ evidence: TddEvidence;
28
+ cycle: TddCycleEvidence;
29
+ }>;
30
+ /**
31
+ * 记录 RED 尝试。
32
+ *
33
+ * 验证:
34
+ * - cycle 存在且 status ∈ {started, red}
35
+ * - failureKind 为 assertion 或 missing-behavior(有效 RED)
36
+ * - 幂等:相同 outputDigest → 返回原结果
37
+ */
38
+ export declare function recordRed(evidence: TddEvidence, cycleId: string, redEvidence: TddCommandEvidence): StateResult<{
39
+ evidence: TddEvidence;
40
+ cycle: TddCycleEvidence;
41
+ }>;
42
+ /**
43
+ * 记录 GREEN 尝试。
44
+ *
45
+ * 验证:
46
+ * - cycle 存在且已有有效 RED(redTestDigest !== null)
47
+ * - GREEN exitCode === 0
48
+ * - implementation files 有变化
49
+ * - 幂等:相同 outputDigest → 返回原结果
50
+ */
51
+ export declare function recordGreen(evidence: TddEvidence, cycleId: string, greenEvidence: TddCommandEvidence, implementationFilesChanged: boolean): StateResult<{
52
+ evidence: TddEvidence;
53
+ cycle: TddCycleEvidence;
54
+ }>;
55
+ /**
56
+ * 记录最终 regression 结果。
57
+ *
58
+ * 验证:
59
+ * - runs 非空
60
+ * - 所有 run exitCode === 0 且无 timeout 则 pass,否则 fail
61
+ */
62
+ export declare function recordFinalRegression(evidence: TddEvidence, headSha: string, treeSha: string, runs: TddCommandEvidence[]): StateResult<TddEvidence>;
63
+ /**
64
+ * 记录最终 verification 结果。
65
+ *
66
+ * 规则:
67
+ * - runs 为空 → pass(未配置 verifyCommands)
68
+ * - 所有 run exitCode === 0 则 pass,否则 fail
69
+ */
70
+ export declare function recordFinalVerification(evidence: TddEvidence, headSha: string, treeSha: string, runs: TddCommandEvidence[]): StateResult<TddEvidence>;
71
+ /**
72
+ * 放弃一个 cycle。
73
+ *
74
+ * 规则:
75
+ * - cycle 必须存在
76
+ * - cycle 状态不能是 "pass"(已通过的 cycle 不能放弃)
77
+ * - 保留审计记录,reason 写入 warnings
78
+ */
79
+ export declare function abandonCycle(evidence: TddEvidence, cycleId: string, reason: string): StateResult<TddEvidence>;