@devcxl/opencode-cabbage 0.2.0 → 0.3.0

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 (84) hide show
  1. package/README.md +57 -54
  2. package/README.zh.md +91 -0
  3. package/assets/agents/dev-lifecycle.md +28 -22
  4. package/assets/agents/team/architect.md +14 -0
  5. package/assets/agents/team/backend.md +14 -0
  6. package/assets/agents/team/frontend.md +14 -0
  7. package/assets/agents/team/goal-verify.md +54 -0
  8. package/assets/agents/team/reviewer.md +10 -0
  9. package/assets/skills/flow-code/SKILL.md +13 -0
  10. package/assets/skills/flow-review/SKILL.md +7 -0
  11. package/assets/skills/flow-tasks/SKILL.md +42 -0
  12. package/assets/skills/flow-tdd/SKILL.md +208 -0
  13. package/dist/flowrun/adapter.d.ts +49 -0
  14. package/dist/flowrun/adapter.js +293 -0
  15. package/dist/flowrun/adapter.js.map +1 -0
  16. package/dist/flowrun/ci.d.ts +64 -0
  17. package/dist/flowrun/ci.js +184 -0
  18. package/dist/flowrun/ci.js.map +1 -0
  19. package/dist/flowrun/coverage.d.ts +70 -0
  20. package/dist/flowrun/coverage.js +207 -0
  21. package/dist/flowrun/coverage.js.map +1 -0
  22. package/dist/flowrun/digest.d.ts +17 -0
  23. package/dist/flowrun/digest.js +301 -0
  24. package/dist/flowrun/digest.js.map +1 -0
  25. package/dist/flowrun/evaluator.d.ts +38 -0
  26. package/dist/flowrun/evaluator.js +185 -0
  27. package/dist/flowrun/evaluator.js.map +1 -0
  28. package/dist/flowrun/gate.d.ts +20 -0
  29. package/dist/flowrun/gate.js +40 -3
  30. package/dist/flowrun/gate.js.map +1 -1
  31. package/dist/flowrun/github.d.ts +13 -9
  32. package/dist/flowrun/github.js +46 -26
  33. package/dist/flowrun/github.js.map +1 -1
  34. package/dist/flowrun/index.d.ts +12 -4
  35. package/dist/flowrun/index.js +11 -3
  36. package/dist/flowrun/index.js.map +1 -1
  37. package/dist/flowrun/merge.d.ts +35 -2
  38. package/dist/flowrun/merge.js +72 -8
  39. package/dist/flowrun/merge.js.map +1 -1
  40. package/dist/flowrun/migration.d.ts +11 -0
  41. package/dist/flowrun/migration.js +276 -0
  42. package/dist/flowrun/migration.js.map +1 -0
  43. package/dist/flowrun/pr.d.ts +132 -0
  44. package/dist/flowrun/pr.js +343 -0
  45. package/dist/flowrun/pr.js.map +1 -0
  46. package/dist/flowrun/state.d.ts +79 -0
  47. package/dist/flowrun/state.js +363 -0
  48. package/dist/flowrun/state.js.map +1 -0
  49. package/dist/flowrun/transitions.d.ts +66 -0
  50. package/dist/flowrun/transitions.js +168 -0
  51. package/dist/flowrun/transitions.js.map +1 -0
  52. package/dist/flowrun/types.d.ts +279 -4
  53. package/dist/flowrun/types.js +2 -1
  54. package/dist/flowrun/types.js.map +1 -1
  55. package/dist/flowrun/validator.d.ts +15 -5
  56. package/dist/flowrun/validator.js +117 -5
  57. package/dist/flowrun/validator.js.map +1 -1
  58. package/dist/plugin/agents.d.ts +4 -0
  59. package/dist/plugin/agents.js +19 -0
  60. package/dist/plugin/agents.js.map +1 -1
  61. package/dist/plugin/broker.d.ts +73 -0
  62. package/dist/plugin/broker.js +140 -0
  63. package/dist/plugin/broker.js.map +1 -0
  64. package/dist/plugin/flow-pr-tool.d.ts +37 -0
  65. package/dist/plugin/flow-pr-tool.js +176 -0
  66. package/dist/plugin/flow-pr-tool.js.map +1 -0
  67. package/dist/plugin/goal.d.ts +39 -1
  68. package/dist/plugin/goal.js +80 -1
  69. package/dist/plugin/goal.js.map +1 -1
  70. package/dist/plugin/prompt-lint.js +129 -0
  71. package/dist/plugin/prompt-lint.js.map +1 -1
  72. package/dist/plugin/server.d.ts +8 -0
  73. package/dist/plugin/server.js +306 -11
  74. package/dist/plugin/server.js.map +1 -1
  75. package/dist/plugin/shell.d.ts +37 -0
  76. package/dist/plugin/shell.js +144 -0
  77. package/dist/plugin/shell.js.map +1 -0
  78. package/dist/plugin/tdd-tool.d.ts +62 -0
  79. package/dist/plugin/tdd-tool.js +336 -0
  80. package/dist/plugin/tdd-tool.js.map +1 -0
  81. package/dist/util/gh.d.ts +8 -1
  82. package/dist/util/gh.js +10 -2
  83. package/dist/util/gh.js.map +1 -1
  84. package/package.json +2 -1
@@ -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":"AAMA,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAA;AAKnD;;;;;;;;GAQG;AACH,MAAM,UAAU,aAAa,CAAC,OAAgB;IAC5C,IAAI,CAAC,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;QAC5C,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,OAAO,EAAE,mCAAmC,EAAE,CAAC,EAAE,CAAA;IAClH,CAAC;IAED,MAAM,GAAG,GAAG,OAAkC,CAAA;IAE9C,MAAM,OAAO,GAAG,GAAG,CAAC,aAAa,CAAA;IACjC,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC;QAC7E,OAAO;YACL,EAAE,EAAE,KAAK;YACT,IAAI,EAAE,mBAAmB;YACzB,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,oCAAoC,OAAO,EAAE,EAAE,CAAC;SAC5F,CAAA;IACH,CAAC;IAED,IAAI,OAAO,GAAG,sBAAsB,EAAE,CAAC;QACrC,OAAO;YACL,EAAE,EAAE,KAAK;YACT,IAAI,EAAE,oBAAoB;YAC1B,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,kBAAkB,OAAO,+BAA+B,sBAAsB,GAAG,EAAE,CAAC;SAChI,CAAA;IACH,CAAC;IAED,cAAc;IACd,IAAI,OAAO,KAAK,sBAAsB,EAAE,CAAC;QACvC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,GAAyB,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAA;IACvE,CAAC;IAED,aAAa;IACb,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,eAAe,CAAC,GAAG,CAAC,CAAA;QACrC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAA;IACrD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO;YACL,EAAE,EAAE,KAAK;YACT,IAAI,EAAE,kBAAkB;YACxB,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,OAAO,EAAE,qBAAqB,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;SACpE,CAAA;IACH,CAAC;AACH,CAAC;AAED,SAAS,eAAe,CAAC,EAAa;IACpC,MAAM,KAAK,GAA8B,EAAE,CAAA;IAE3C,IAAI,EAAE,CAAC,KAAK,IAAI,OAAO,EAAE,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC7C,MAAM,OAAO,GAAG,EAAE,CAAC,KAA+B,CAAA;QAClD,KAAK,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;YACpD,KAAK,CAAC,GAAG,CAAC,GAAG,iBAAiB,CAAC,MAAgB,EAAE,GAAG,CAAC,CAAA;QACvD,CAAC;IACH,CAAC;IAED,2CAA2C;IAC3C,4BAA4B;IAE5B,OAAO;QACL,SAAS,EAAE,MAAM,CAAC,EAAE,CAAC,SAAS,IAAI,EAAE,CAAC;QACrC,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC;QAC3B,iBAAiB,EAAE,MAAM,CAAC,EAAE,CAAC,iBAAiB,IAAI,CAAC,CAAC;QACpD,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,IAAI,SAAS,CAAsB;QAC3D,aAAa,EAAE,sBAAsB;QACrC,QAAQ,EAAE,MAAM,CAAC,EAAE,CAAC,QAAQ,IAAI,CAAC,CAAC;QAClC,MAAM,EAAE,aAAa,CAAC,EAAE,CAAC,MAAM,CAAC;QAChC,KAAK;QACL,SAAS,EAAE,OAAO,EAAE,CAAC,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI;QACjE,UAAU,EAAE,OAAO,EAAE,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI;QACpE,aAAa,EAAE,OAAO,EAAE,CAAC,aAAa,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI;QAC7E,UAAU,EAAE,MAAM,CAAC,EAAE,CAAC,UAAU,IAAI,UAAU,CAAC;QAC/C,WAAW,EAAE,OAAO,EAAE,CAAC,WAAW,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI;QACvE,uBAAuB,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,cAAc,EAAE,EAAE,EAAE;KAClD,CAAA;AACd,CAAC;AAED,SAAS,aAAa,CAAC,MAAe;IACpC,SAAS,YAAY;QACnB,OAAO;YACL,MAAM,EAAE,SAAS;YACjB,iBAAiB,EAAE,EAAE;YACrB,MAAM,EAAE,EAAE;YACV,WAAW,EAAE,IAAI;YACjB,QAAQ,EAAE,EAAE;SACb,CAAA;IACH,CAAC;IAED,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC1C,OAAO;YACL,YAAY,EAAE,YAAY,EAAE;YAC5B,MAAM,EAAE,YAAY,EAAE;YACtB,KAAK,EAAE,YAAY,EAAE;YACrB,IAAI,EAAE,YAAY,EAAE;YACpB,IAAI,EAAE,YAAY,EAAE;YACpB,MAAM,EAAE,YAAY,EAAE;YACtB,KAAK,EAAE,YAAY,EAAE;SACtB,CAAA;IACH,CAAC;IAED,MAAM,CAAC,GAAG,MAAiC,CAAA;IAC3C,MAAM,SAAS,GAAG,CAAC,cAAc,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAA;IAExF,MAAM,MAAM,GAA+B,EAAE,CAAA;IAC7C,KAAK,MAAM,GAAG,IAAI,SAAS,EAAE,CAAC;QAC5B,MAAM,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAA;QAClB,IAAI,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;YACnC,MAAM,CAAC,GAAG,GAA8B,CAAA;YACxC,MAAM,CAAC,GAAG,CAAC,GAAG;gBACZ,MAAM,EAAE,CAAC,OAAO,CAAC,CAAC,MAAM,KAAK,QAAQ,IAAI,CAAC,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;oBAC9G,CAAC,CAAC,CAAC,CAAC,MAA8B;oBAClC,CAAC,CAAC,SAAS;gBACb,iBAAiB,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,iBAA6B,CAAC,CAAC,CAAC,EAAE;gBAC5F,MAAM,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAsB,CAAC,CAAC,CAAC,EAAE;gBAC/D,WAAW,EAAE,OAAO,CAAC,CAAC,WAAW,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI;gBACrE,QAAQ,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAA2B,CAAC,CAAC,CAAC,EAAE;aACzE,CAAA;QACH,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,GAAG,CAAC,GAAG,YAAY,EAAE,CAAA;QAC9B,CAAC;IACH,CAAC;IAED,OAAO,MAA2B,CAAA;AACpC,CAAC;AAED;;GAEG;AACH,SAAS,iBAAiB,CAAC,MAAc,EAAE,SAAiB;IAC1D,MAAM,eAAe,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,MAAM,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,CAAA;IAE5F,4CAA4C;IAC5C,MAAM,YAAY,GAAkB,eAAe;QACjD,CAAC,CAAE,MAAM,CAAC,YAAyB,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAC5C,OAAO,EAAE,GAAG;YACZ,GAAG,EAAE,GAAG;YACR,SAAS,EAAE,OAAO;YAClB,GAAG,EAAE,EAAE;SACR,CAAC,CAAC;QACL,CAAC,CAAC,EAAE,CAAA;IAEN,qCAAqC;IACrC,MAAM,YAAY,GAAG,OAAO,MAAM,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAA;IACnF,MAAM,kBAAkB,GAA0B;QAChD;YACE,EAAE,EAAE,UAAU;YACd,WAAW,EAAE,YAAY,IAAI,iBAAiB;YAC9C,YAAY,EAAE,eAAe,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ;SACxD;KACF,CAAA;IAED,6BAA6B;IAC7B,MAAM,SAAS,GAAc;QAC3B,IAAI,EAAE,eAAe,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ;QAC5C,WAAW,EAAE,UAAU;QACvB,MAAM,EAAE,IAAI;QACZ,gBAAgB,EAAE,EAAE;QACpB,0BAA0B,EAAE,EAAE;QAC9B,yBAAyB,EAAE,EAAE;QAC7B,SAAS,EAAE;YACT,MAAM,EAAE,4BAA4B;YACpC,qBAAqB,EAAE,eAAe;gBACpC,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;oBAC5B,YAAY,EAAE,cAAc,CAAC,GAAG,CAAC,EAAE;oBACnC,IAAI,EAAE,SAAkB;oBACxB,OAAO,EAAE,GAAG;iBACb,CAAC,CAAC;gBACL,CAAC,CAAC,CAAC;wBACC,YAAY,EAAE,cAAc;wBAC5B,IAAI,EAAE,QAAiB;wBACvB,WAAW,EAAE,aAAa;qBAC3B,CAAC;YACN,QAAQ,EAAE;gBACR,IAAI,EAAE,kBAAkB;gBACxB,iBAAiB,EAAE,CAAC;aACrB;SACF;QACD,MAAM,EAAE;YACN,YAAY,EAAE,WAAW;YACzB,WAAW,EAAE,cAAc;SAC5B;KACF,CAAA;IAED,0BAA0B;IAC1B,MAAM,WAAW,GAAgB;QAC/B,QAAQ,EAAE,CAAC;QACX,cAAc,EAAE,CAAC;QACjB,MAAM,EAAE,cAAc;QACtB,SAAS,EAAE,oBAAoB,EAAE;QACjC,MAAM,EAAE,EAAE;QACV,UAAU,EAAE,qBAAqB,EAAE;QACnC,YAAY,EAAE,uBAAuB,EAAE;QACvC,qBAAqB,EAAE,EAAqC;QAC5D,OAAO,EAAE,EAAyB;QAClC,QAAQ,EAAE,CAAC,mDAAmD,CAAC;QAC/D,SAAS,EAAE,IAAI;KAChB,CAAA;IAED,qCAAqC;IACrC,MAAM,IAAI,GAAG,MAAM,CAAC,aAAa,CAAA;IACjC,MAAM,aAAa,GAAG,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ;QACpD,CAAC,CAAC,oBAAoB,CAAC,IAA+B,CAAC;QACvD,CAAC,CAAC,IAAI,CAAA;IAER,OAAO;QACL,EAAE,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,SAAS,CAAC;QAClC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,IAAI,SAAS,CAAC;QACtC,MAAM,EAAE,CAAC,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAwB;QAC9F,SAAS,EAAE,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,SAAqB,CAAC,CAAC,CAAC,EAAE;QAC9E,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QAC/B,aAAa,EAAE,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,aAAyB,CAAC,CAAC,CAAC,EAAE;QAC1F,YAAY,EAAE,OAAO,CAAC,MAAM,CAAC,YAAY,IAAI,KAAK,CAAC;QACnD,QAAQ,EAAE,OAAO,MAAM,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI;QACtE,aAAa;QACb,aAAa,EAAE,OAAO,MAAM,CAAC,aAAa,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI;QACrF,SAAS,EAAE,OAAO,MAAM,CAAC,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI;QACzE,SAAS;QACT,kBAAkB;QAClB,YAAY;QACZ,cAAc,EAAE,EAAE;QAClB,gBAAgB,EAAE,IAAI;QACtB,SAAS;QACT,WAAW;QACX,cAAc,EAAE,IAAI;KACrB,CAAA;AACH,CAAC;AAED,SAAS,oBAAoB,CAAC,IAA6B;IACzD,SAAS,cAAc,CAAC,IAAY;QAClC,OAAO;YACL,IAAI;YACJ,MAAM,EAAE,SAAS;YACjB,QAAQ,EAAE,EAAE;SACb,CAAA;IACH,CAAC;IAED,MAAM,aAAa,GAAG,CAAC,GAAW,EAAc,EAAE;QAChD,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAA;QACpB,IAAI,EAAE,IAAI,OAAO,EAAE,KAAK,QAAQ,EAAE,CAAC;YACjC,MAAM,CAAC,GAAG,EAA6B,CAAA;YACvC,OAAO;gBACL,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,IAAI,GAAG,CAAC;gBAC3B,MAAM,EAAE,CAAC,OAAO,CAAC,CAAC,MAAM,KAAK,QAAQ,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;oBACtF,CAAC,CAAC,CAAC,CAAC,MAA8B;oBAClC,CAAC,CAAC,SAAS;gBACb,QAAQ,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAA2B,CAAC,CAAC,CAAC,EAAE;aACzE,CAAA;QACH,CAAC;QACD,OAAO,cAAc,CAAC,GAAG,CAAC,CAAA;IAC5B,CAAC,CAAA;IAED,OAAO;QACL,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,CAAC;QACpC,WAAW,EAAE,aAAa,CAAC,aAAa,CAAC;QACzC,QAAQ,EAAE,aAAa,CAAC,UAAU,CAAC;QACnC,gBAAgB,EAAE,aAAa,CAAC,kBAAkB,CAAC;QACnD,gBAAgB,EAAE,aAAa,CAAC,kBAAkB,CAAC;QACnD,gBAAgB,EAAE,aAAa,CAAC,kBAAkB,CAAC;QACnD,WAAW,EAAE,aAAa,CAAC,aAAa,CAAC;QACzC,QAAQ;QACR,aAAa,EAAE,IAAI;QACnB,YAAY,EAAE,IAAI;QAClB,QAAQ,EAAE,IAAI;QACd,qBAAqB,EAAE,IAAI;KAC5B,CAAA;AACH,CAAC;AAED,SAAS,oBAAoB;IAC3B,OAAO;QACL,MAAM,EAAE,SAAS;QACjB,OAAO,EAAE,IAAI;QACb,OAAO,EAAE,IAAI;QACb,SAAS,EAAE,IAAI;KAChB,CAAA;AACH,CAAC;AAED,SAAS,qBAAqB;IAC5B,OAAO;QACL,MAAM,EAAE,SAAS;QACjB,OAAO,EAAE,IAAI;QACb,OAAO,EAAE,IAAI;QACb,cAAc,EAAE,CAAC;QACjB,IAAI,EAAE,EAAE;KACT,CAAA;AACH,CAAC;AAED,SAAS,uBAAuB;IAC9B,OAAO;QACL,MAAM,EAAE,SAAS;QACjB,OAAO,EAAE,IAAI;QACb,OAAO,EAAE,IAAI;QACb,IAAI,EAAE,EAAE;KACT,CAAA;AACH,CAAC"}
@@ -0,0 +1,132 @@
1
+ import type { TaskState } from "./types.js";
2
+ export interface CreatePRParams {
3
+ repo: string;
4
+ headBranch: string;
5
+ baseBranch: string;
6
+ title: string;
7
+ body: string;
8
+ }
9
+ export interface CreatePRResult {
10
+ prNumber: number;
11
+ prUrl: string;
12
+ created: boolean;
13
+ }
14
+ export type PreflightResult = {
15
+ ok: true;
16
+ } | {
17
+ ok: false;
18
+ code: string;
19
+ message: string;
20
+ };
21
+ export interface ReworkInput {
22
+ kind: "behavior" | "refactor";
23
+ affectedCriterionIds: string[];
24
+ startHeadSha: string;
25
+ }
26
+ export type ReworkResult = {
27
+ ok: true;
28
+ task: TaskState;
29
+ } | {
30
+ ok: false;
31
+ code: string;
32
+ message: string;
33
+ };
34
+ export interface CompleteReworkInput {
35
+ committedHeadSha: string;
36
+ }
37
+ export type CompleteReworkResult = {
38
+ ok: true;
39
+ task: TaskState;
40
+ } | {
41
+ ok: false;
42
+ code: string;
43
+ message: string;
44
+ };
45
+ export interface RemotePRHead {
46
+ headSha: string;
47
+ treeSha: string;
48
+ }
49
+ export type FetchRemoteHeadResult = {
50
+ ok: true;
51
+ head: RemotePRHead;
52
+ } | {
53
+ ok: false;
54
+ code: string;
55
+ message: string;
56
+ };
57
+ export type RevalidateResult = {
58
+ ok: true;
59
+ action: "revalidate";
60
+ summary: string;
61
+ } | {
62
+ ok: false;
63
+ action: "rework-needed";
64
+ summary: string;
65
+ };
66
+ type GhFn = (args: string) => Promise<{
67
+ stdout: string;
68
+ stderr: string;
69
+ }>;
70
+ export declare function setGhExecutor(fn: GhFn): void;
71
+ /**
72
+ * 执行 PR 创建前的前置条件检查(无副作用)。
73
+ *
74
+ * 规则:
75
+ * 1. Task 状态为 running
76
+ * 2. committed-head regression.status === "pass"
77
+ * 3. committed-head verification.status === "pass"
78
+ * 4. evidence headSha 与当前 head 一致
79
+ */
80
+ export declare function preflightPRCreate(task: TaskState, currentHeadSha: string): PreflightResult;
81
+ /**
82
+ * 创建或复用 PR。
83
+ *
84
+ * 流程:
85
+ * 1. 查询已有 open PR(按 head branch)
86
+ * 2. 已有 → 复用(created: false)
87
+ * 3. 无 → 创建新 PR(created: true)
88
+ *
89
+ * @throws 如果 gh CLI 执行失败
90
+ */
91
+ export declare function createOrReusePR(params: CreatePRParams): Promise<CreatePRResult>;
92
+ /**
93
+ * 发起 rework。
94
+ *
95
+ * behavior rework:
96
+ * - 声明 affected criterionIds,增加 reworkRevision
97
+ * - 重置 regression 和 verification 为 pending
98
+ * - 旧 cycle 保持不变(不重新绑定)
99
+ *
100
+ * refactor rework:
101
+ * - 不要求 RED,但必须重跑 regression + 审批
102
+ * - 同样增加 reworkRevision,重置 evidence
103
+ *
104
+ * 要求:Task 状态为 reviewing 且已有 PR。
105
+ */
106
+ export declare function initiateRework(task: TaskState, input: ReworkInput): ReworkResult;
107
+ /**
108
+ * 完成 rework,验证后恢复 Task 为 reviewing。
109
+ *
110
+ * 检查:
111
+ * 1. 当前有激活的 rework(evidence.status === "in-progress")
112
+ * 2. regression 和 verification 均已 pass
113
+ * 3. evidence head SHA 与 committed head 一致
114
+ */
115
+ export declare function completeRework(task: TaskState, input: CompleteReworkInput): CompleteReworkResult;
116
+ /**
117
+ * 查询 remote PR 的 head commit SHA 和 tree SHA。
118
+ *
119
+ * 步骤:
120
+ * 1. `gh pr view --json headRefOid` 获取完整 JSON,自行解析提取 headRefOid
121
+ * 2. `gh api repos/{owner}/{repo}/git/commits/{sha} --jq '.tree.sha'` 获取 tree SHA
122
+ */
123
+ export declare function fetchRemotePRHead(repo: string, prNumber: number): Promise<FetchRemoteHeadResult>;
124
+ /**
125
+ * 重新验证 remote head。
126
+ *
127
+ * 比较 task.tddEvidence.verification.treeSha 与 remote tree SHA:
128
+ * - 相同 tree SHA:可以重新绑定 new head(重跑 regression/verification)
129
+ * - 不同 tree SHA:需要先执行 rework
130
+ */
131
+ export declare function revalidateRemoteHead(task: TaskState, remoteHead: RemotePRHead): RevalidateResult;
132
+ export {};