@bluewombat/implementer 0.1.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 (55) hide show
  1. package/README.md +91 -0
  2. package/SPECS.md +349 -0
  3. package/dist/args/parse-args.d.ts +6 -0
  4. package/dist/args/parse-args.d.ts.map +1 -0
  5. package/dist/args/parse-args.js +330 -0
  6. package/dist/args/parse-args.js.map +1 -0
  7. package/dist/child/parse-child-output.d.ts +11 -0
  8. package/dist/child/parse-child-output.d.ts.map +1 -0
  9. package/dist/child/parse-child-output.js +49 -0
  10. package/dist/child/parse-child-output.js.map +1 -0
  11. package/dist/child/run-builder.d.ts +24 -0
  12. package/dist/child/run-builder.d.ts.map +1 -0
  13. package/dist/child/run-builder.js +92 -0
  14. package/dist/child/run-builder.js.map +1 -0
  15. package/dist/child/run-child.d.ts +36 -0
  16. package/dist/child/run-child.d.ts.map +1 -0
  17. package/dist/child/run-child.js +141 -0
  18. package/dist/child/run-child.js.map +1 -0
  19. package/dist/child/run-gate.d.ts +14 -0
  20. package/dist/child/run-gate.d.ts.map +1 -0
  21. package/dist/child/run-gate.js +72 -0
  22. package/dist/child/run-gate.js.map +1 -0
  23. package/dist/cli.d.ts +3 -0
  24. package/dist/cli.d.ts.map +1 -0
  25. package/dist/cli.js +44 -0
  26. package/dist/cli.js.map +1 -0
  27. package/dist/index.d.ts +12 -0
  28. package/dist/index.d.ts.map +1 -0
  29. package/dist/index.js +9 -0
  30. package/dist/index.js.map +1 -0
  31. package/dist/loop/decide-after-attempt.d.ts +23 -0
  32. package/dist/loop/decide-after-attempt.d.ts.map +1 -0
  33. package/dist/loop/decide-after-attempt.js +26 -0
  34. package/dist/loop/decide-after-attempt.js.map +1 -0
  35. package/dist/progress/emit.d.ts +5 -0
  36. package/dist/progress/emit.d.ts.map +1 -0
  37. package/dist/progress/emit.js +24 -0
  38. package/dist/progress/emit.js.map +1 -0
  39. package/dist/run/run-implementer.d.ts +23 -0
  40. package/dist/run/run-implementer.d.ts.map +1 -0
  41. package/dist/run/run-implementer.js +274 -0
  42. package/dist/run/run-implementer.js.map +1 -0
  43. package/dist/status/announce.d.ts +14 -0
  44. package/dist/status/announce.d.ts.map +1 -0
  45. package/dist/status/announce.js +40 -0
  46. package/dist/status/announce.js.map +1 -0
  47. package/dist/status/make-status.d.ts +9 -0
  48. package/dist/status/make-status.d.ts.map +1 -0
  49. package/dist/status/make-status.js +38 -0
  50. package/dist/status/make-status.js.map +1 -0
  51. package/dist/types.d.ts +119 -0
  52. package/dist/types.d.ts.map +1 -0
  53. package/dist/types.js +3 -0
  54. package/dist/types.js.map +1 -0
  55. package/package.json +46 -0
@@ -0,0 +1,330 @@
1
+ import { existsSync, statSync } from "node:fs";
2
+ import { isAbsolute } from "node:path";
3
+ const IMPLEMENTER_FLAGS = new Set([
4
+ "--id",
5
+ "--intention",
6
+ "--definition-of-done",
7
+ "--report",
8
+ "--report-from",
9
+ "--context",
10
+ "--stage",
11
+ "--workspace",
12
+ "--builder",
13
+ "--builder-timeout-ms",
14
+ "--repair-builder",
15
+ "--repair-builder-timeout-ms",
16
+ "--gate",
17
+ "--gate-timeout-ms",
18
+ "--max-attempts",
19
+ "--on-status",
20
+ ]);
21
+ function isImplementerFlag(token) {
22
+ return IMPLEMENTER_FLAGS.has(token);
23
+ }
24
+ function takeValue(argv, index) {
25
+ const value = argv[index + 1];
26
+ if (value === undefined || value.startsWith("--")) {
27
+ return null;
28
+ }
29
+ return { value, next: index + 2 };
30
+ }
31
+ function takeCommandArgv(argv, start) {
32
+ if (argv[start] !== "--") {
33
+ return null;
34
+ }
35
+ const command = [];
36
+ let i = start + 1;
37
+ while (i < argv.length) {
38
+ const token = argv[i];
39
+ if (token !== undefined && isImplementerFlag(token)) {
40
+ break;
41
+ }
42
+ if (token !== undefined) {
43
+ command.push(token);
44
+ }
45
+ i += 1;
46
+ }
47
+ if (command.length === 0) {
48
+ return null;
49
+ }
50
+ return { command, next: i };
51
+ }
52
+ function parsePositiveInt(raw) {
53
+ if (!/^\d+$/.test(raw)) {
54
+ return null;
55
+ }
56
+ const value = Number(raw);
57
+ if (!Number.isSafeInteger(value) || value < 1) {
58
+ return null;
59
+ }
60
+ return value;
61
+ }
62
+ /**
63
+ * Parse Implementer CLI argv (without node/script). Malformed input → not ok.
64
+ */
65
+ export function parseArgs(argv) {
66
+ let id;
67
+ let intention;
68
+ let definitionOfDone;
69
+ let report;
70
+ let reportFrom;
71
+ let context;
72
+ let stage;
73
+ let workspace;
74
+ let builderArgv;
75
+ let repairArgv;
76
+ let builderTimeoutMs;
77
+ let repairTimeoutMs;
78
+ const gates = [];
79
+ const seenGateIds = new Set();
80
+ let maxAttempts;
81
+ let gateTimeoutMs;
82
+ let onStatusArgv;
83
+ let i = 0;
84
+ while (i < argv.length) {
85
+ const token = argv[i];
86
+ if (token === undefined) {
87
+ break;
88
+ }
89
+ if (token === "--id") {
90
+ const taken = takeValue(argv, i);
91
+ if (!taken) {
92
+ return { ok: false, reason: "Missing value for --id." };
93
+ }
94
+ id = taken.value;
95
+ i = taken.next;
96
+ continue;
97
+ }
98
+ if (token === "--intention") {
99
+ const taken = takeValue(argv, i);
100
+ if (!taken) {
101
+ return { ok: false, reason: "Missing value for --intention." };
102
+ }
103
+ intention = taken.value;
104
+ i = taken.next;
105
+ continue;
106
+ }
107
+ if (token === "--definition-of-done") {
108
+ const taken = takeValue(argv, i);
109
+ if (!taken) {
110
+ return { ok: false, reason: "Missing value for --definition-of-done." };
111
+ }
112
+ definitionOfDone = taken.value;
113
+ i = taken.next;
114
+ continue;
115
+ }
116
+ if (token === "--report") {
117
+ const taken = takeValue(argv, i);
118
+ if (!taken) {
119
+ return { ok: false, reason: "Missing value for --report." };
120
+ }
121
+ report = taken.value;
122
+ i = taken.next;
123
+ continue;
124
+ }
125
+ if (token === "--report-from") {
126
+ const taken = takeValue(argv, i);
127
+ if (!taken) {
128
+ return { ok: false, reason: "Missing value for --report-from." };
129
+ }
130
+ reportFrom = taken.value;
131
+ i = taken.next;
132
+ continue;
133
+ }
134
+ if (token === "--stage") {
135
+ const taken = takeValue(argv, i);
136
+ if (!taken) {
137
+ return { ok: false, reason: "Missing value for --stage." };
138
+ }
139
+ if (taken.value !== "unit" && taken.value !== "assembly") {
140
+ return { ok: false, reason: `--stage is unit or assembly, not "${taken.value}".` };
141
+ }
142
+ stage = taken.value;
143
+ i = taken.next;
144
+ continue;
145
+ }
146
+ if (token === "--context") {
147
+ const taken = takeValue(argv, i);
148
+ if (!taken) {
149
+ return { ok: false, reason: "Missing value for --context." };
150
+ }
151
+ context = taken.value;
152
+ i = taken.next;
153
+ continue;
154
+ }
155
+ if (token === "--workspace") {
156
+ const taken = takeValue(argv, i);
157
+ if (!taken) {
158
+ return { ok: false, reason: "Missing value for --workspace." };
159
+ }
160
+ workspace = taken.value;
161
+ i = taken.next;
162
+ continue;
163
+ }
164
+ if (token === "--builder") {
165
+ const command = takeCommandArgv(argv, i + 1);
166
+ if (!command) {
167
+ return { ok: false, reason: "Missing non-empty Builder command after --builder --." };
168
+ }
169
+ builderArgv = command.command;
170
+ i = command.next;
171
+ continue;
172
+ }
173
+ if (token === "--gate") {
174
+ const idTaken = takeValue(argv, i);
175
+ if (!idTaken) {
176
+ return { ok: false, reason: "Missing Gate id after --gate." };
177
+ }
178
+ const gateId = idTaken.value;
179
+ if (seenGateIds.has(gateId)) {
180
+ return { ok: false, reason: `Duplicate Gate id "${gateId}".` };
181
+ }
182
+ const command = takeCommandArgv(argv, idTaken.next);
183
+ if (!command) {
184
+ return {
185
+ ok: false,
186
+ reason: `Missing non-empty Gate command after --gate ${gateId} --.`,
187
+ };
188
+ }
189
+ if (gateTimeoutMs === undefined) {
190
+ return {
191
+ ok: false,
192
+ reason: `Gate "${gateId}" has no --gate-timeout-ms. Nothing else would bound it.`,
193
+ };
194
+ }
195
+ seenGateIds.add(gateId);
196
+ gates.push({ id: gateId, argv: command.command, timeoutMs: gateTimeoutMs });
197
+ gateTimeoutMs = undefined;
198
+ i = command.next;
199
+ continue;
200
+ }
201
+ if (token === "--gate-timeout-ms") {
202
+ const taken = takeValue(argv, i);
203
+ if (!taken) {
204
+ return { ok: false, reason: "Missing value for --gate-timeout-ms." };
205
+ }
206
+ const value = parsePositiveInt(taken.value);
207
+ if (value === null) {
208
+ return { ok: false, reason: "--gate-timeout-ms must be a positive integer." };
209
+ }
210
+ // Applies to the next --gate, so one ceiling per Gate is one flag.
211
+ gateTimeoutMs = value;
212
+ i = taken.next;
213
+ continue;
214
+ }
215
+ if (token === "--max-attempts") {
216
+ const taken = takeValue(argv, i);
217
+ if (!taken) {
218
+ return { ok: false, reason: "Missing value for --max-attempts." };
219
+ }
220
+ const value = parsePositiveInt(taken.value);
221
+ if (value === null) {
222
+ return { ok: false, reason: "--max-attempts must be a positive integer." };
223
+ }
224
+ maxAttempts = value;
225
+ i = taken.next;
226
+ continue;
227
+ }
228
+ if (token === "--builder-timeout-ms" || token === "--repair-builder-timeout-ms") {
229
+ const taken = takeValue(argv, i);
230
+ if (!taken) {
231
+ return { ok: false, reason: `Missing value for ${token}.` };
232
+ }
233
+ const value = parsePositiveInt(taken.value);
234
+ if (value === null) {
235
+ return { ok: false, reason: `${token} must be a positive integer.` };
236
+ }
237
+ if (token === "--builder-timeout-ms") {
238
+ builderTimeoutMs = value;
239
+ }
240
+ else {
241
+ repairTimeoutMs = value;
242
+ }
243
+ i = taken.next;
244
+ continue;
245
+ }
246
+ if (token === "--repair-builder") {
247
+ const command = takeCommandArgv(argv, i + 1);
248
+ if (!command) {
249
+ return { ok: false, reason: "Missing non-empty command after --repair-builder --." };
250
+ }
251
+ repairArgv = command.command;
252
+ i = command.next;
253
+ continue;
254
+ }
255
+ if (token === "--on-status") {
256
+ const command = takeCommandArgv(argv, i + 1);
257
+ if (!command) {
258
+ return { ok: false, reason: "Missing non-empty command after --on-status --." };
259
+ }
260
+ onStatusArgv = command.command;
261
+ i = command.next;
262
+ continue;
263
+ }
264
+ return { ok: false, reason: `Unknown argument "${token}".` };
265
+ }
266
+ if (id === undefined) {
267
+ return { ok: false, reason: "Missing required --id." };
268
+ }
269
+ if (intention === undefined) {
270
+ return { ok: false, reason: "Missing required --intention." };
271
+ }
272
+ if (definitionOfDone === undefined) {
273
+ return { ok: false, reason: "Missing required --definition-of-done." };
274
+ }
275
+ if (workspace === undefined) {
276
+ return { ok: false, reason: "Missing required --workspace." };
277
+ }
278
+ if (maxAttempts === undefined) {
279
+ return { ok: false, reason: "Missing required --max-attempts." };
280
+ }
281
+ if (builderTimeoutMs === undefined) {
282
+ return { ok: false, reason: "Missing required --builder-timeout-ms." };
283
+ }
284
+ if (repairArgv !== undefined && builderArgv === undefined) {
285
+ return { ok: false, reason: "--repair-builder needs a --builder to fall back to." };
286
+ }
287
+ if (!isAbsolute(workspace)) {
288
+ return { ok: false, reason: "--workspace must be an absolute path." };
289
+ }
290
+ if (!existsSync(workspace)) {
291
+ return { ok: false, reason: `--workspace does not exist: ${workspace}` };
292
+ }
293
+ try {
294
+ if (!statSync(workspace).isDirectory()) {
295
+ return { ok: false, reason: `--workspace is not a directory: ${workspace}` };
296
+ }
297
+ }
298
+ catch {
299
+ return { ok: false, reason: `--workspace is not usable: ${workspace}` };
300
+ }
301
+ const invocation = {
302
+ id,
303
+ intention,
304
+ definitionOfDone,
305
+ workspace,
306
+ ...(builderArgv === undefined ? {} : { builderArgv }),
307
+ ...(repairArgv === undefined ? {} : { repairArgv }),
308
+ gates,
309
+ maxAttempts,
310
+ builderTimeoutMs,
311
+ ...(repairTimeoutMs === undefined ? {} : { repairTimeoutMs }),
312
+ };
313
+ if (report !== undefined) {
314
+ invocation.report = report;
315
+ }
316
+ if (reportFrom !== undefined) {
317
+ invocation.reportFrom = reportFrom;
318
+ }
319
+ if (context !== undefined) {
320
+ invocation.context = context;
321
+ }
322
+ if (stage !== undefined) {
323
+ invocation.stage = stage;
324
+ }
325
+ if (onStatusArgv !== undefined) {
326
+ invocation.onStatusArgv = onStatusArgv;
327
+ }
328
+ return { ok: true, invocation };
329
+ }
330
+ //# sourceMappingURL=parse-args.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse-args.js","sourceRoot":"","sources":["../../src/args/parse-args.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ export type BuilderFailureJson = {
2
+ outcome: "fail-retryable" | "fail-blocking";
3
+ report: string;
4
+ };
5
+ export type GateVerdictJson = {
6
+ verdict: "pass" | "fail-retryable" | "fail-blocking";
7
+ report: string;
8
+ };
9
+ export declare function parseBuilderFailureJson(stdout: string): BuilderFailureJson | null;
10
+ export declare function parseGateVerdictJson(stdout: string): GateVerdictJson | null;
11
+ //# sourceMappingURL=parse-child-output.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse-child-output.d.ts","sourceRoot":"","sources":["../../src/child/parse-child-output.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,kBAAkB,GAAG;IAC/B,OAAO,EAAE,gBAAgB,GAAG,eAAe,CAAC;IAC5C,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,OAAO,EAAE,MAAM,GAAG,gBAAgB,GAAG,eAAe,CAAC;IACrD,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAwBF,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,MAAM,GAAG,kBAAkB,GAAG,IAAI,CAYjF;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CAW3E"}
@@ -0,0 +1,49 @@
1
+ function firstJsonObject(text) {
2
+ const trimmed = text.trim();
3
+ if (trimmed.length === 0) {
4
+ return null;
5
+ }
6
+ // Prefer the last non-empty line (children may log before the JSON object).
7
+ const lines = trimmed.split(/\r?\n/).filter((line) => line.trim().length > 0);
8
+ const candidate = lines.length > 0 ? lines[lines.length - 1] : trimmed;
9
+ if (candidate === undefined) {
10
+ return null;
11
+ }
12
+ try {
13
+ return JSON.parse(candidate);
14
+ }
15
+ catch {
16
+ try {
17
+ return JSON.parse(trimmed);
18
+ }
19
+ catch {
20
+ return null;
21
+ }
22
+ }
23
+ }
24
+ export function parseBuilderFailureJson(stdout) {
25
+ const value = firstJsonObject(stdout);
26
+ if (value === null || typeof value !== "object" || value === null) {
27
+ return null;
28
+ }
29
+ const record = value;
30
+ const outcome = record.outcome;
31
+ if (outcome !== "fail-retryable" && outcome !== "fail-blocking") {
32
+ return null;
33
+ }
34
+ const report = typeof record.report === "string" ? record.report : "";
35
+ return { outcome, report };
36
+ }
37
+ export function parseGateVerdictJson(stdout) {
38
+ const value = firstJsonObject(stdout);
39
+ if (value === null || typeof value !== "object") {
40
+ return null;
41
+ }
42
+ const record = value;
43
+ const verdict = record.verdict;
44
+ if (verdict !== "pass" && verdict !== "fail-retryable" && verdict !== "fail-blocking") {
45
+ return null;
46
+ }
47
+ return { verdict, report: typeof record.report === "string" ? record.report : "" };
48
+ }
49
+ //# sourceMappingURL=parse-child-output.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse-child-output.js","sourceRoot":"","sources":["../../src/child/parse-child-output.ts"],"names":[],"mappings":"AAUA,SAAS,eAAe,CAAC,IAAY;IACnC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IAC5B,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,4EAA4E;IAC5E,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC9E,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;IACvE,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAC5B,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,SAAS,CAAY,CAAC;IAC1C,CAAC;IAAC,MAAM,CAAC;QACP,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAY,CAAC;QACxC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;AACH,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,MAAc;IACpD,MAAM,KAAK,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;IACtC,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QAClE,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,MAAM,GAAG,KAAgC,CAAC;IAChD,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;IAC/B,IAAI,OAAO,KAAK,gBAAgB,IAAI,OAAO,KAAK,eAAe,EAAE,CAAC;QAChE,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,MAAM,GAAG,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IACtE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;AAC7B,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,MAAc;IACjD,MAAM,KAAK,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;IACtC,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAChD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,MAAM,GAAG,KAAgC,CAAC;IAChD,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;IAC/B,IAAI,OAAO,KAAK,MAAM,IAAI,OAAO,KAAK,gBAAgB,IAAI,OAAO,KAAK,eAAe,EAAE,CAAC;QACtF,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;AACrF,CAAC"}
@@ -0,0 +1,24 @@
1
+ import type { BuilderResult, Invocation } from "../types.js";
2
+ export type BuilderRunResult = {
3
+ result: BuilderResult;
4
+ /** Report for the next Builder, if this Attempt fails retryably. */
5
+ reportForRetry?: string;
6
+ /** Attempt ended without running Gates. */
7
+ attemptEnded?: "fail-retryable" | "fail-blocking" | "interrupted";
8
+ };
9
+ export declare function runBuilder(input: {
10
+ invocation: Invocation;
11
+ /**
12
+ * The producer for this pass. Chosen by the loop, not read off the
13
+ * invocation: which of the two commands runs depends on whether there is
14
+ * something to resolve, and only the loop knows that.
15
+ */
16
+ producerArgv: string[];
17
+ attempt: number;
18
+ previousReport: string | undefined;
19
+ /** Which Gate refused, when one did. Absent when the producer itself failed. */
20
+ previousRefusedBy: string | undefined;
21
+ timeoutMs: number;
22
+ shouldInterrupt: () => boolean;
23
+ }): Promise<BuilderRunResult>;
24
+ //# sourceMappingURL=run-builder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-builder.d.ts","sourceRoot":"","sources":["../../src/child/run-builder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAI7D,MAAM,MAAM,gBAAgB,GAAG;IAC7B,MAAM,EAAE,aAAa,CAAC;IACtB,oEAAoE;IACpE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,2CAA2C;IAC3C,YAAY,CAAC,EAAE,gBAAgB,GAAG,eAAe,GAAG,aAAa,CAAC;CACnE,CAAC;AAEF,wBAAsB,UAAU,CAAC,KAAK,EAAE;IACtC,UAAU,EAAE,UAAU,CAAC;IACvB;;;;OAIG;IACH,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,gFAAgF;IAChF,iBAAiB,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,OAAO,CAAC;CAChC,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAwC5B"}
@@ -0,0 +1,92 @@
1
+ import { parseBuilderFailureJson } from "./parse-child-output.js";
2
+ import { combinedOutput, runChild } from "./run-child.js";
3
+ export async function runBuilder(input) {
4
+ const { invocation, producerArgv, attempt, previousReport, previousRefusedBy, timeoutMs, shouldInterrupt, } = input;
5
+ const argv = [
6
+ ...producerArgv,
7
+ "--id",
8
+ invocation.id,
9
+ "--attempt",
10
+ String(attempt),
11
+ "--intention",
12
+ invocation.intention,
13
+ "--definition-of-done",
14
+ invocation.definitionOfDone,
15
+ ];
16
+ if (previousReport !== undefined) {
17
+ argv.push("--report", previousReport);
18
+ }
19
+ if (previousRefusedBy !== undefined) {
20
+ argv.push("--report-from", previousRefusedBy);
21
+ }
22
+ if (invocation.context !== undefined) {
23
+ argv.push("--context", invocation.context);
24
+ }
25
+ const outcome = await runChild({
26
+ argv,
27
+ cwd: invocation.workspace,
28
+ timeoutMs,
29
+ shouldInterrupt,
30
+ });
31
+ return interpretBuilderOutcome(outcome, timeoutMs);
32
+ }
33
+ function interpretBuilderOutcome(outcome, timeoutMs) {
34
+ if (outcome.kind === "spawn_error") {
35
+ return {
36
+ result: {
37
+ kind: "refused",
38
+ outcome: "fail-blocking",
39
+ detail: outcome.detail,
40
+ },
41
+ reportForRetry: outcome.detail,
42
+ attemptEnded: "fail-blocking",
43
+ };
44
+ }
45
+ if (outcome.kind === "interrupted") {
46
+ return {
47
+ result: { kind: "interrupted", detail: "stop signal" },
48
+ attemptEnded: "interrupted",
49
+ };
50
+ }
51
+ if (outcome.kind === "timed_out") {
52
+ const detail = `killed after ${timeoutMs}ms, its own ceiling`;
53
+ return {
54
+ result: {
55
+ kind: "timed_out",
56
+ outcome: "fail-retryable",
57
+ detail,
58
+ },
59
+ reportForRetry: detail,
60
+ attemptEnded: "fail-retryable",
61
+ };
62
+ }
63
+ // exited
64
+ if (outcome.exitCode === 0) {
65
+ return {
66
+ result: { kind: "completed" },
67
+ };
68
+ }
69
+ const failure = parseBuilderFailureJson(outcome.stdout);
70
+ if (failure) {
71
+ return {
72
+ result: {
73
+ kind: "failed",
74
+ outcome: failure.outcome,
75
+ detail: failure.report,
76
+ },
77
+ reportForRetry: failure.report,
78
+ attemptEnded: failure.outcome,
79
+ };
80
+ }
81
+ const detail = combinedOutput(outcome.stdout, outcome.stderr) || `exit ${outcome.exitCode}`;
82
+ return {
83
+ result: {
84
+ kind: "failed",
85
+ outcome: "fail-retryable",
86
+ detail,
87
+ },
88
+ reportForRetry: detail,
89
+ attemptEnded: "fail-retryable",
90
+ };
91
+ }
92
+ //# sourceMappingURL=run-builder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-builder.js","sourceRoot":"","sources":["../../src/child/run-builder.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ export type SpawnRequest = {
2
+ argv: string[];
3
+ /** Undefined lets the child inherit the caller's directory. */
4
+ cwd?: string | undefined;
5
+ /** Wall-clock budget for this child (ms). */
6
+ timeoutMs: number;
7
+ /** When true, treat kill as interrupted (stop signal). */
8
+ shouldInterrupt: () => boolean;
9
+ /** Undefined lets the child inherit the caller's environment. */
10
+ env?: NodeJS.ProcessEnv | undefined;
11
+ };
12
+ export type SpawnOutcome = {
13
+ kind: "exited";
14
+ exitCode: number | null;
15
+ signal: NodeJS.Signals | null;
16
+ stdout: string;
17
+ stderr: string;
18
+ } | {
19
+ kind: "timed_out";
20
+ stdout: string;
21
+ stderr: string;
22
+ } | {
23
+ kind: "interrupted";
24
+ stdout: string;
25
+ stderr: string;
26
+ } | {
27
+ kind: "spawn_error";
28
+ detail: string;
29
+ };
30
+ /**
31
+ * Run one child with a wall-clock timeout. Does not inherit Implementer stdin.
32
+ */
33
+ export declare function runChild(request: SpawnRequest): Promise<SpawnOutcome>;
34
+ /** The fallback report of a child that left no contract line: its last words. */
35
+ export declare function combinedOutput(stdout: string, stderr: string): string;
36
+ //# sourceMappingURL=run-child.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-child.d.ts","sourceRoot":"","sources":["../../src/child/run-child.ts"],"names":[],"mappings":"AAaA,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,+DAA+D;IAC/D,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,6CAA6C;IAC7C,SAAS,EAAE,MAAM,CAAC;IAClB,0DAA0D;IAC1D,eAAe,EAAE,MAAM,OAAO,CAAC;IAC/B,iEAAiE;IACjE,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,GAAG,SAAS,CAAC;CACrC,CAAC;AAEF,MAAM,MAAM,YAAY,GACpB;IACE,IAAI,EAAE,QAAQ,CAAC;IACf,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB,GACD;IACE,IAAI,EAAE,WAAW,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB,GACD;IACE,IAAI,EAAE,aAAa,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB,GACD;IACE,IAAI,EAAE,aAAa,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAiBN;;GAEG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC,CAsHrE;AAED,iFAAiF;AACjF,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAGrE"}