issue-flow 0.12.0 → 0.13.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.
- package/README.md +79 -274
- package/dist/agent-BXRIEKVM.js +238 -0
- package/dist/agent-BXRIEKVM.js.map +1 -0
- package/dist/{analyze-OEET7KGE.js → analyze-WS47UYGN.js} +28 -16
- package/dist/analyze-WS47UYGN.js.map +1 -0
- package/dist/{apply-ZIA3C52S.js → apply-OS62UWRN.js} +15 -7
- package/dist/{apply-ZIA3C52S.js.map → apply-OS62UWRN.js.map} +1 -1
- package/dist/bench-SA3BOME5.js +906 -0
- package/dist/bench-SA3BOME5.js.map +1 -0
- package/dist/chunk-37N2RJW2.js +120 -0
- package/dist/chunk-37N2RJW2.js.map +1 -0
- package/dist/chunk-3XLCNVMD.js +180 -0
- package/dist/chunk-3XLCNVMD.js.map +1 -0
- package/dist/chunk-5TB6KLC2.js +72 -0
- package/dist/chunk-5TB6KLC2.js.map +1 -0
- package/dist/{chunk-MJULIKQU.js → chunk-664Y3NDX.js} +23 -47
- package/dist/chunk-664Y3NDX.js.map +1 -0
- package/dist/chunk-6FDFRNXZ.js +357 -0
- package/dist/chunk-6FDFRNXZ.js.map +1 -0
- package/dist/{chunk-56KS3TFQ.js → chunk-7KD66LIM.js} +115 -160
- package/dist/chunk-7KD66LIM.js.map +1 -0
- package/dist/chunk-7Z4Y3VKM.js +26 -0
- package/dist/chunk-7Z4Y3VKM.js.map +1 -0
- package/dist/chunk-ARFVHC2F.js +1111 -0
- package/dist/chunk-ARFVHC2F.js.map +1 -0
- package/dist/{chunk-NS6R37II.js → chunk-BHJCGWQX.js} +141 -12
- package/dist/chunk-BHJCGWQX.js.map +1 -0
- package/dist/chunk-BQDQTIM7.js +74 -0
- package/dist/chunk-BQDQTIM7.js.map +1 -0
- package/dist/chunk-CNBYCMSU.js +2709 -0
- package/dist/chunk-CNBYCMSU.js.map +1 -0
- package/dist/chunk-CRGIQFUQ.js +83 -0
- package/dist/chunk-CRGIQFUQ.js.map +1 -0
- package/dist/chunk-DIG5XKQQ.js +298 -0
- package/dist/chunk-DIG5XKQQ.js.map +1 -0
- package/dist/chunk-FZDR7CGH.js +71 -0
- package/dist/chunk-FZDR7CGH.js.map +1 -0
- package/dist/chunk-HEF2RMKN.js +413 -0
- package/dist/chunk-HEF2RMKN.js.map +1 -0
- package/dist/{chunk-M5UCXTIT.js → chunk-HJGGNLWI.js} +22 -18
- package/dist/chunk-HJGGNLWI.js.map +1 -0
- package/dist/chunk-HQAHNIAR.js +283 -0
- package/dist/chunk-HQAHNIAR.js.map +1 -0
- package/dist/{chunk-FJP3UQGD.js → chunk-IHIEXUTC.js} +39 -19
- package/dist/chunk-IHIEXUTC.js.map +1 -0
- package/dist/{chunk-Y5ZDJ4PJ.js → chunk-IV5SS4JN.js} +18 -10
- package/dist/chunk-IV5SS4JN.js.map +1 -0
- package/dist/{chunk-BYZDPR7N.js → chunk-IYV6KNVF.js} +146 -13
- package/dist/chunk-IYV6KNVF.js.map +1 -0
- package/dist/{chunk-TSOLWK7Y.js → chunk-J62QSVP6.js} +8 -8
- package/dist/chunk-KQHB7ZT3.js +559 -0
- package/dist/chunk-KQHB7ZT3.js.map +1 -0
- package/dist/chunk-L6HSKTQE.js +77 -0
- package/dist/chunk-L6HSKTQE.js.map +1 -0
- package/dist/{chunk-3QHK4YQA.js → chunk-LZ6GFQAG.js} +334 -117
- package/dist/chunk-LZ6GFQAG.js.map +1 -0
- package/dist/{chunk-LAFNLLQP.js → chunk-MIVHK5YI.js} +5 -5
- package/dist/chunk-NEZZ6KDR.js +1217 -0
- package/dist/chunk-NEZZ6KDR.js.map +1 -0
- package/dist/{chunk-NTMMF5UD.js → chunk-OPNGPUKJ.js} +436 -254
- package/dist/chunk-OPNGPUKJ.js.map +1 -0
- package/dist/chunk-P3LRUNC6.js +16 -0
- package/dist/chunk-P3LRUNC6.js.map +1 -0
- package/dist/{chunk-FADTCQGM.js → chunk-PIVGJM6K.js} +94 -32
- package/dist/chunk-PIVGJM6K.js.map +1 -0
- package/dist/{chunk-73ATPIYX.js → chunk-PV4OX5TC.js} +36 -71
- package/dist/chunk-PV4OX5TC.js.map +1 -0
- package/dist/chunk-QCXPNSEL.js +141 -0
- package/dist/chunk-QCXPNSEL.js.map +1 -0
- package/dist/{chunk-XQUSIEKA.js → chunk-QXDNBYQF.js} +52 -14
- package/dist/chunk-QXDNBYQF.js.map +1 -0
- package/dist/chunk-SNTTOQAD.js +30 -0
- package/dist/chunk-SNTTOQAD.js.map +1 -0
- package/dist/{chunk-QCPGHBSZ.js → chunk-TM67EHSV.js} +63 -21
- package/dist/chunk-TM67EHSV.js.map +1 -0
- package/dist/chunk-TVN2JVOF.js +77 -0
- package/dist/chunk-TVN2JVOF.js.map +1 -0
- package/dist/chunk-TX5WIVYP.js +129 -0
- package/dist/chunk-TX5WIVYP.js.map +1 -0
- package/dist/{chunk-A4SLHOW7.js → chunk-UJ7XWK7J.js} +24 -18
- package/dist/chunk-UJ7XWK7J.js.map +1 -0
- package/dist/{chunk-EZATO3DW.js → chunk-UOCPC2Y2.js} +594 -17
- package/dist/chunk-UOCPC2Y2.js.map +1 -0
- package/dist/chunk-XEYH6ZZI.js +289 -0
- package/dist/chunk-XEYH6ZZI.js.map +1 -0
- package/dist/cli.js +264 -44
- package/dist/cli.js.map +1 -1
- package/dist/{config-PRJGWW7J.js → config-MEM2IWWN.js} +28 -5
- package/dist/contract-JH2WBIO6.js +8 -0
- package/dist/conventions-WV4NDXGH.js +143 -0
- package/dist/conventions-WV4NDXGH.js.map +1 -0
- package/dist/execute-NITIHHCK.js +31 -0
- package/dist/{generate-EGB4KV2B.js → generate-MVQI7A45.js} +34 -20
- package/dist/{generate-EGB4KV2B.js.map → generate-MVQI7A45.js.map} +1 -1
- package/dist/git-YRVRUN3C.js +31 -0
- package/dist/init-OKWEC3EV.js +21 -0
- package/dist/{operations-BYT626KQ.js → operations-LU6JA3BX.js} +24 -15
- package/dist/{operations-BYT626KQ.js.map → operations-LU6JA3BX.js.map} +1 -1
- package/dist/permissions-7NMDFU27.js +18 -0
- package/dist/plan-LEJJF3DE.js +31 -0
- package/dist/{policy-6S4GFC76.js → policy-JSYEK5B2.js} +17 -6
- package/dist/policy-JSYEK5B2.js.map +1 -0
- package/dist/pr-HPVUZ7S3.js +36 -0
- package/dist/pr-review-R2QZBT3F.js +29 -0
- package/dist/prd-5O6GYCC6.js +30 -0
- package/dist/ps-TNE44R5V.js +90 -0
- package/dist/ps-TNE44R5V.js.map +1 -0
- package/dist/recorder-XGF55WXI.js +31 -0
- package/dist/recorder-XGF55WXI.js.map +1 -0
- package/dist/registry-LGPE53QD.js +15 -0
- package/dist/registry-LGPE53QD.js.map +1 -0
- package/dist/{resume-PPCNQVVV.js → resume-QMEPMSZW.js} +51 -34
- package/dist/{resume-PPCNQVVV.js.map → resume-QMEPMSZW.js.map} +1 -1
- package/dist/review-YKWD6SNN.js +32 -0
- package/dist/review-YKWD6SNN.js.map +1 -0
- package/dist/routing-2ZUMZPJB.js +91 -0
- package/dist/routing-2ZUMZPJB.js.map +1 -0
- package/dist/run-YU4TR62R.js +50 -0
- package/dist/run-YU4TR62R.js.map +1 -0
- package/dist/{state-manager-2EDVDBAR.js → state-manager-X3PT3FGT.js} +4 -2
- package/dist/state-manager-X3PT3FGT.js.map +1 -0
- package/dist/usage-VCFLDA5Y.js +174 -0
- package/dist/usage-VCFLDA5Y.js.map +1 -0
- package/dist/{web-EF5WIIGG.js → web-XVHLX62B.js} +41 -30
- package/dist/web-XVHLX62B.js.map +1 -0
- package/package.json +6 -2
- package/prompts/execute.md +7 -8
- package/prompts/plan.md +4 -5
- package/prompts/pr.md +2 -2
- package/web/AGENTS.md +3 -3
- package/web/public/app.css +38 -0
- package/web/public/app.js +121 -11
- package/web/public/index.html +24 -0
- package/dist/analyze-OEET7KGE.js.map +0 -1
- package/dist/chunk-3QHK4YQA.js.map +0 -1
- package/dist/chunk-42PJFMAR.js +0 -605
- package/dist/chunk-42PJFMAR.js.map +0 -1
- package/dist/chunk-4JSOYE4G.js +0 -368
- package/dist/chunk-4JSOYE4G.js.map +0 -1
- package/dist/chunk-56KS3TFQ.js.map +0 -1
- package/dist/chunk-73ATPIYX.js.map +0 -1
- package/dist/chunk-A4SLHOW7.js.map +0 -1
- package/dist/chunk-BAUPQXPE.js +0 -173
- package/dist/chunk-BAUPQXPE.js.map +0 -1
- package/dist/chunk-BYZDPR7N.js.map +0 -1
- package/dist/chunk-CD5ULRVC.js +0 -615
- package/dist/chunk-CD5ULRVC.js.map +0 -1
- package/dist/chunk-DIDUVL6O.js +0 -1365
- package/dist/chunk-DIDUVL6O.js.map +0 -1
- package/dist/chunk-EZATO3DW.js.map +0 -1
- package/dist/chunk-FADTCQGM.js.map +0 -1
- package/dist/chunk-FJP3UQGD.js.map +0 -1
- package/dist/chunk-LWRSMTTZ.js +0 -18
- package/dist/chunk-LWRSMTTZ.js.map +0 -1
- package/dist/chunk-M5UCXTIT.js.map +0 -1
- package/dist/chunk-M66SJHQQ.js +0 -206
- package/dist/chunk-M66SJHQQ.js.map +0 -1
- package/dist/chunk-MJULIKQU.js.map +0 -1
- package/dist/chunk-NS6R37II.js.map +0 -1
- package/dist/chunk-NTMMF5UD.js.map +0 -1
- package/dist/chunk-QCPGHBSZ.js.map +0 -1
- package/dist/chunk-XQUSIEKA.js.map +0 -1
- package/dist/chunk-Y5ZDJ4PJ.js.map +0 -1
- package/dist/execute-XBNVL753.js +0 -18
- package/dist/init-AJHCXJBP.js +0 -10
- package/dist/plan-QOZ3RIO6.js +0 -21
- package/dist/policy-6S4GFC76.js.map +0 -1
- package/dist/pr-EBBHD2ZX.js +0 -26
- package/dist/pr-review-VVMW5PO4.js +0 -20
- package/dist/prd-JQSZF7PR.js +0 -21
- package/dist/review-3F6MARWH.js +0 -19
- package/dist/run-RXE5GDQO.js +0 -36
- package/dist/web-EF5WIIGG.js.map +0 -1
- /package/dist/{chunk-TSOLWK7Y.js.map → chunk-J62QSVP6.js.map} +0 -0
- /package/dist/{chunk-LAFNLLQP.js.map → chunk-MIVHK5YI.js.map} +0 -0
- /package/dist/{config-PRJGWW7J.js.map → config-MEM2IWWN.js.map} +0 -0
- /package/dist/{execute-XBNVL753.js.map → contract-JH2WBIO6.js.map} +0 -0
- /package/dist/{init-AJHCXJBP.js.map → execute-NITIHHCK.js.map} +0 -0
- /package/dist/{plan-QOZ3RIO6.js.map → git-YRVRUN3C.js.map} +0 -0
- /package/dist/{pr-EBBHD2ZX.js.map → init-OKWEC3EV.js.map} +0 -0
- /package/dist/{pr-review-VVMW5PO4.js.map → permissions-7NMDFU27.js.map} +0 -0
- /package/dist/{prd-JQSZF7PR.js.map → plan-LEJJF3DE.js.map} +0 -0
- /package/dist/{review-3F6MARWH.js.map → pr-HPVUZ7S3.js.map} +0 -0
- /package/dist/{run-RXE5GDQO.js.map → pr-review-R2QZBT3F.js.map} +0 -0
- /package/dist/{state-manager-2EDVDBAR.js.map → prd-5O6GYCC6.js.map} +0 -0
|
@@ -1,43 +1,51 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
|
-
|
|
4
|
-
} from "./chunk-
|
|
3
|
+
ensureWebMonitor
|
|
4
|
+
} from "./chunk-IHIEXUTC.js";
|
|
5
5
|
import {
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
applyAcceptanceToPlan,
|
|
7
|
+
resolveIssueDir,
|
|
8
|
+
runAcceptanceGate
|
|
9
|
+
} from "./chunk-BQDQTIM7.js";
|
|
10
|
+
import {
|
|
11
|
+
groupBy,
|
|
12
|
+
summarize
|
|
13
|
+
} from "./chunk-CRGIQFUQ.js";
|
|
8
14
|
import {
|
|
9
15
|
EXECUTE_PHASE,
|
|
10
16
|
elapsedSecondsSince,
|
|
11
17
|
getPhaseUsageTotals,
|
|
12
18
|
publishIterationMetrics,
|
|
13
19
|
publishStoryMetrics,
|
|
14
|
-
readClaudeStream,
|
|
15
20
|
resolvePolicyPlaceholders
|
|
16
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-664Y3NDX.js";
|
|
17
22
|
import {
|
|
18
23
|
applyPlaceholders,
|
|
19
24
|
loadPrompt
|
|
20
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-MIVHK5YI.js";
|
|
21
26
|
import {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
+
invokeSelectedAgent
|
|
28
|
+
} from "./chunk-ARFVHC2F.js";
|
|
29
|
+
import {
|
|
30
|
+
archiveFolderName,
|
|
31
|
+
commitMessage
|
|
32
|
+
} from "./chunk-UOCPC2Y2.js";
|
|
27
33
|
import {
|
|
28
34
|
createConfig,
|
|
35
|
+
getActiveResilienceConfig,
|
|
36
|
+
getShutdownSignal,
|
|
37
|
+
loadGlobalConfig,
|
|
38
|
+
loadWebConfig,
|
|
39
|
+
resolveAgentFor,
|
|
29
40
|
resolvePaths,
|
|
30
41
|
validateDependencies
|
|
31
|
-
} from "./chunk-
|
|
42
|
+
} from "./chunk-CNBYCMSU.js";
|
|
32
43
|
import {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
fixedBackoffPolicy,
|
|
36
|
-
getBaseBranch,
|
|
37
|
-
isWorkingTreeClean,
|
|
38
|
-
withRetry
|
|
39
|
-
} from "./chunk-DIDUVL6O.js";
|
|
44
|
+
resolveIssuePaths
|
|
45
|
+
} from "./chunk-HQAHNIAR.js";
|
|
40
46
|
import {
|
|
47
|
+
FilePublisher,
|
|
48
|
+
NullPublisher,
|
|
41
49
|
formatDuration,
|
|
42
50
|
getIcons,
|
|
43
51
|
getInactivityTimeout,
|
|
@@ -52,9 +60,10 @@ import {
|
|
|
52
60
|
printRetry,
|
|
53
61
|
printSuccess,
|
|
54
62
|
printWarning,
|
|
63
|
+
setSessionPublisher,
|
|
55
64
|
useColor,
|
|
56
65
|
useUnicode
|
|
57
|
-
} from "./chunk-
|
|
66
|
+
} from "./chunk-IYV6KNVF.js";
|
|
58
67
|
import {
|
|
59
68
|
allStoriesPass,
|
|
60
69
|
applyStoryMetrics,
|
|
@@ -71,7 +80,21 @@ import {
|
|
|
71
80
|
selectActiveStory,
|
|
72
81
|
setLastError,
|
|
73
82
|
trimErrorMessage
|
|
74
|
-
} from "./chunk-
|
|
83
|
+
} from "./chunk-DIG5XKQQ.js";
|
|
84
|
+
import {
|
|
85
|
+
committedStoryIds,
|
|
86
|
+
fixedBackoffPolicy,
|
|
87
|
+
getBaseBranch,
|
|
88
|
+
isWorkingTreeClean,
|
|
89
|
+
resolvePolicy,
|
|
90
|
+
withRetry
|
|
91
|
+
} from "./chunk-KQHB7ZT3.js";
|
|
92
|
+
import {
|
|
93
|
+
classify
|
|
94
|
+
} from "./chunk-XEYH6ZZI.js";
|
|
95
|
+
|
|
96
|
+
// src/commands/execute.ts
|
|
97
|
+
import { randomUUID } from "crypto";
|
|
75
98
|
|
|
76
99
|
// src/core/engine.ts
|
|
77
100
|
import { existsSync } from "fs";
|
|
@@ -188,7 +211,7 @@ function printBox(lines) {
|
|
|
188
211
|
}
|
|
189
212
|
console.log(blue(`${bl}${hrule}${br}`));
|
|
190
213
|
}
|
|
191
|
-
function printStartupHeader(config, plan) {
|
|
214
|
+
function printStartupHeader(config, plan, agent) {
|
|
192
215
|
const icons = getIcons();
|
|
193
216
|
const storiesTotal = plan.userStories.length;
|
|
194
217
|
const storiesPassing = plan.userStories.filter((s) => s.passes).length;
|
|
@@ -196,7 +219,7 @@ function printStartupHeader(config, plan) {
|
|
|
196
219
|
const issueLabel = config.issueNumber ? `Issue #${config.issueNumber}` : "Standalone mode";
|
|
197
220
|
const maxIterLabel = config.maxIterations !== void 0 ? String(config.maxIterations) : "unlimited";
|
|
198
221
|
const retryLabel = config.retryForever ? "unlimited retries" : `${config.retryLimit} consecutive retries`;
|
|
199
|
-
|
|
222
|
+
const lines = [
|
|
200
223
|
`${icons.start} Issue Flow`,
|
|
201
224
|
"---",
|
|
202
225
|
`Issue: ${issueLabel}`,
|
|
@@ -204,9 +227,22 @@ function printStartupHeader(config, plan) {
|
|
|
204
227
|
`Stories: ${storiesPassing}/${storiesTotal} passing`,
|
|
205
228
|
`Iterations: ${maxIterLabel}`,
|
|
206
229
|
`Retries: ${retryLabel}`
|
|
207
|
-
]
|
|
230
|
+
];
|
|
231
|
+
const remaining = storiesTotal - storiesPassing;
|
|
232
|
+
if (remaining > 0) {
|
|
233
|
+
const p50ExecuteSeconds = 518;
|
|
234
|
+
lines.push(
|
|
235
|
+
`Estimate: ~${formatDuration(remaining * p50ExecuteSeconds)} (${remaining} \xD7 p50 execute)`
|
|
236
|
+
);
|
|
237
|
+
}
|
|
238
|
+
if (agent) {
|
|
239
|
+
const model = agent.model ? ` \xB7 ${agent.model}` : "";
|
|
240
|
+
const detail = agent.detail ? ` (${agent.detail})` : "";
|
|
241
|
+
lines.push(`Agent: ${agent.provider}${model}${detail}`);
|
|
242
|
+
}
|
|
243
|
+
printBox(lines);
|
|
208
244
|
}
|
|
209
|
-
function printSummaryBox(status, iterations, totalRetries, elapsedSeconds, plan, extraInfo, usage) {
|
|
245
|
+
function printSummaryBox(status, iterations, totalRetries, elapsedSeconds, plan, extraInfo, usage, usageByAgent) {
|
|
210
246
|
const icons = getIcons();
|
|
211
247
|
const storiesTotal = plan.userStories.length;
|
|
212
248
|
const storiesPassing = plan.userStories.filter((s) => s.passes).length;
|
|
@@ -235,10 +271,8 @@ function printSummaryBox(status, iterations, totalRetries, elapsedSeconds, plan,
|
|
|
235
271
|
`Iterations: ${iterations}`,
|
|
236
272
|
`Duration: ${duration}`
|
|
237
273
|
];
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
boxLines.push(`Tokens: ${tokens}`);
|
|
241
|
-
}
|
|
274
|
+
boxLines.push(...tokenBoxLines(usage, usageByAgent));
|
|
275
|
+
boxLines.push(...executionCostLines(plan));
|
|
242
276
|
boxLines.push(`Retries: ${totalRetries}`);
|
|
243
277
|
if (extraInfo) {
|
|
244
278
|
boxLines.push("---");
|
|
@@ -247,19 +281,79 @@ function printSummaryBox(status, iterations, totalRetries, elapsedSeconds, plan,
|
|
|
247
281
|
console.log("");
|
|
248
282
|
printBox(boxLines);
|
|
249
283
|
}
|
|
284
|
+
function executionCostLines(plan, prefix = "Cost: ") {
|
|
285
|
+
const records = plan.executions ?? [];
|
|
286
|
+
if (records.length === 0) return [];
|
|
287
|
+
const lines = [];
|
|
288
|
+
const groups = groupBy(records, "harness");
|
|
289
|
+
let index = 0;
|
|
290
|
+
const pad = " ".repeat(prefix.length);
|
|
291
|
+
for (const [harness, summary] of groups) {
|
|
292
|
+
const parts = [];
|
|
293
|
+
if (summary.totalCost.reported > 0) {
|
|
294
|
+
parts.push(`$${summary.totalCost.reported.toFixed(4)} reported`);
|
|
295
|
+
}
|
|
296
|
+
if (summary.totalCost.estimated > 0) {
|
|
297
|
+
parts.push(`$${summary.totalCost.estimated.toFixed(4)} estimated`);
|
|
298
|
+
}
|
|
299
|
+
if (summary.totalCost.unknownExecutions > 0) {
|
|
300
|
+
parts.push(`${summary.totalCost.unknownExecutions} unknown`);
|
|
301
|
+
}
|
|
302
|
+
if (parts.length === 0) {
|
|
303
|
+
const totals = summarize(records).totalCost;
|
|
304
|
+
if (totals.reported === 0 && totals.estimated === 0) {
|
|
305
|
+
parts.push("not reported");
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
if (parts.length === 0) continue;
|
|
309
|
+
lines.push(`${index === 0 ? prefix : pad}${harness} \xB7 ${parts.join(" \xB7 ")}`);
|
|
310
|
+
index += 1;
|
|
311
|
+
}
|
|
312
|
+
return lines;
|
|
313
|
+
}
|
|
314
|
+
function tokenBoxLines(usage, usageByAgent) {
|
|
315
|
+
const agents = usageByAgent ? Object.keys(usageByAgent) : [];
|
|
316
|
+
if (agents.length > 1) {
|
|
317
|
+
const lines = [];
|
|
318
|
+
for (const [index, id] of agents.entries()) {
|
|
319
|
+
const tokens2 = formatTokens(usageByAgent?.[id]);
|
|
320
|
+
if (tokens2 === "") continue;
|
|
321
|
+
lines.push(index === 0 ? `Tokens: ${id} \xB7 ${tokens2}` : ` ${id} \xB7 ${tokens2}`);
|
|
322
|
+
}
|
|
323
|
+
return lines;
|
|
324
|
+
}
|
|
325
|
+
const tokens = formatTokens(usage);
|
|
326
|
+
return tokens === "" ? [] : [`Tokens: ${tokens}`];
|
|
327
|
+
}
|
|
328
|
+
function tokenSummaryLines(usage, usageByAgent, prefix = " Tokens: ") {
|
|
329
|
+
const agents = usageByAgent ? Object.keys(usageByAgent) : [];
|
|
330
|
+
if (agents.length > 1) {
|
|
331
|
+
const pad = " ".repeat(prefix.length);
|
|
332
|
+
const lines = [];
|
|
333
|
+
for (const [index, id] of agents.entries()) {
|
|
334
|
+
const tokens2 = formatTokens(usageByAgent?.[id]);
|
|
335
|
+
if (tokens2 === "") continue;
|
|
336
|
+
lines.push(`${index === 0 ? prefix : pad}${id} \xB7 ${tokens2}`);
|
|
337
|
+
}
|
|
338
|
+
return lines;
|
|
339
|
+
}
|
|
340
|
+
const tokens = formatTokens(usage);
|
|
341
|
+
return tokens === "" ? [] : [`${prefix}${tokens}`];
|
|
342
|
+
}
|
|
250
343
|
function buildRunSummaryLines(info) {
|
|
251
344
|
const lines = [
|
|
252
345
|
` Branch: ${info.branchName}${info.noBranch ? " (current)" : ""}`,
|
|
253
346
|
` Stories: ${info.storyCount}`,
|
|
254
347
|
` Duration: ${formatDuration(info.elapsedSeconds)}`
|
|
255
348
|
];
|
|
256
|
-
|
|
257
|
-
if (tokens !== "") {
|
|
258
|
-
lines.push(` Tokens: ${tokens}`);
|
|
259
|
-
}
|
|
349
|
+
lines.push(...tokenSummaryLines(info.usage, info.usageByAgent));
|
|
260
350
|
if (!info.noBranch) {
|
|
261
351
|
lines.push(` PR: ${info.prUrl}`);
|
|
262
352
|
}
|
|
353
|
+
if (info.verification != null) {
|
|
354
|
+
const label = info.verification.verdict === "passed" ? "passed" : info.verification.verdict === "failed" ? "failed" : "unverified";
|
|
355
|
+
lines.push(` Contract: ${label}`);
|
|
356
|
+
}
|
|
263
357
|
const review = info.prReview;
|
|
264
358
|
if (review) {
|
|
265
359
|
const verdict = review.recommendation ?? (review.requestedChanges ? "REQUEST_CHANGES" : "unknown");
|
|
@@ -320,6 +414,14 @@ function printRunSummary(info) {
|
|
|
320
414
|
printWarning(
|
|
321
415
|
`Pipeline finished for issue #${info.issueNumber}, but the PR review requested changes.`
|
|
322
416
|
);
|
|
417
|
+
} else if (info.verification?.verdict === "unverified") {
|
|
418
|
+
printWarning(
|
|
419
|
+
`Pipeline finished for issue #${info.issueNumber}, but the acceptance contract is unverified.`
|
|
420
|
+
);
|
|
421
|
+
} else if (info.verification?.verdict === "failed") {
|
|
422
|
+
printWarning(
|
|
423
|
+
`Pipeline finished for issue #${info.issueNumber}, but the acceptance contract failed.`
|
|
424
|
+
);
|
|
323
425
|
} else {
|
|
324
426
|
printSuccess(`Pipeline complete for issue #${info.issueNumber}!`);
|
|
325
427
|
}
|
|
@@ -328,81 +430,65 @@ function printRunSummary(info) {
|
|
|
328
430
|
}
|
|
329
431
|
}
|
|
330
432
|
|
|
433
|
+
// src/ui/text.ts
|
|
434
|
+
function stripMarkdown(text) {
|
|
435
|
+
return text.replace(/```[\s\S]*?```/g, " ").replace(/`([^`]+)`/g, "$1").replace(/\*\*([^*]+)\*\*/g, "$1").replace(/__([^_]+)__/g, "$1").replace(/(?<!\*)\*([^*]+)\*(?!\*)/g, "$1").replace(/^#{1,6}\s+/gm, "").replace(/^\s*[-*+]\s+/gm, "").replace(/\[([^\]]+)\]\([^)]+\)/g, "$1").replace(/[ \t]{2,}/g, " ").trim();
|
|
436
|
+
}
|
|
437
|
+
function failureExcerpt(output, limit = 8) {
|
|
438
|
+
return output.split("\n").map((line) => stripMarkdown(line)).filter((line) => line.length > 0).slice(-limit);
|
|
439
|
+
}
|
|
440
|
+
|
|
331
441
|
// src/core/executor.ts
|
|
332
|
-
import { execa } from "execa";
|
|
333
442
|
async function executeClaude(prompt, options = {}) {
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
reject: false,
|
|
443
|
+
let selected;
|
|
444
|
+
try {
|
|
445
|
+
selected = await invokeSelectedAgent({
|
|
446
|
+
prompt,
|
|
447
|
+
phase: "execute",
|
|
340
448
|
timeout: 0,
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
}
|
|
344
|
-
)
|
|
345
|
-
const unregisterChild = registerChild({
|
|
346
|
-
kill: (signal) => subprocess.kill(signal),
|
|
347
|
-
done: subprocess.then(
|
|
348
|
-
() => void 0,
|
|
349
|
-
() => void 0
|
|
350
|
-
)
|
|
351
|
-
});
|
|
352
|
-
const watchdog = createWatchdog({
|
|
353
|
-
...options.inactivityTimeoutMs === void 0 ? {} : { inactivityTimeoutMs: options.inactivityTimeoutMs },
|
|
354
|
-
child: {
|
|
355
|
-
kill: (signal) => subprocess.kill(signal),
|
|
356
|
-
done: subprocess.then(
|
|
357
|
-
() => void 0,
|
|
358
|
-
() => void 0
|
|
359
|
-
)
|
|
360
|
-
}
|
|
361
|
-
});
|
|
362
|
-
let streamed = {
|
|
363
|
-
result: "",
|
|
364
|
-
isError: false,
|
|
365
|
-
usage: null,
|
|
366
|
-
events: 0,
|
|
367
|
-
raw: ""
|
|
368
|
-
};
|
|
369
|
-
if (subprocess.stdout) {
|
|
370
|
-
streamed = await readClaudeStream(subprocess.stdout, { onLine: () => watchdog.beat() });
|
|
371
|
-
}
|
|
372
|
-
const result = await subprocess;
|
|
373
|
-
watchdog.stop();
|
|
374
|
-
unregisterChild();
|
|
375
|
-
const stdout = result.stdout?.toString() ?? "";
|
|
376
|
-
const stderr = result.stderr?.toString() ?? "";
|
|
377
|
-
const exitCode = result.exitCode ?? 1;
|
|
378
|
-
const printed = streamed.raw === "" ? stdout : streamed.raw;
|
|
379
|
-
let output = printed + (stderr ? `
|
|
380
|
-
${stderr}` : "");
|
|
381
|
-
let cost = null;
|
|
382
|
-
if (watchdog.stalled) {
|
|
449
|
+
permission: "autonomous",
|
|
450
|
+
inactivityTimeoutMs: options.inactivityTimeoutMs
|
|
451
|
+
});
|
|
452
|
+
} catch (err) {
|
|
383
453
|
return {
|
|
384
|
-
exitCode:
|
|
385
|
-
output:
|
|
454
|
+
exitCode: 1,
|
|
455
|
+
output: err instanceof Error ? err.message : String(err),
|
|
386
456
|
cost: null
|
|
387
457
|
};
|
|
388
458
|
}
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
onOutput(trimmed);
|
|
398
|
-
}
|
|
459
|
+
const { run } = selected;
|
|
460
|
+
let output;
|
|
461
|
+
let cost = run.usage;
|
|
462
|
+
if (!run.success || run.exitCode !== 0) {
|
|
463
|
+
output = run.rawOutput || run.error || "";
|
|
464
|
+
cost = null;
|
|
465
|
+
} else {
|
|
466
|
+
output = run.result || run.rawOutput;
|
|
399
467
|
}
|
|
468
|
+
emitAgentOutput(output, !(run.success && run.exitCode === 0));
|
|
400
469
|
return {
|
|
401
|
-
exitCode,
|
|
470
|
+
exitCode: run.exitCode === 0 && run.success ? 0 : run.exitCode === 0 ? 1 : run.exitCode,
|
|
402
471
|
output,
|
|
403
472
|
cost
|
|
404
473
|
};
|
|
405
474
|
}
|
|
475
|
+
function emitAgentOutput(output, failed) {
|
|
476
|
+
const onOutput = getOutputCallback();
|
|
477
|
+
if (!onOutput) return;
|
|
478
|
+
const trimmed = output.trim();
|
|
479
|
+
if (!trimmed) return;
|
|
480
|
+
if (isVerbose()) {
|
|
481
|
+
for (const line of trimmed.split("\n")) {
|
|
482
|
+
if (line.trim()) onOutput(line);
|
|
483
|
+
}
|
|
484
|
+
return;
|
|
485
|
+
}
|
|
486
|
+
if (failed) {
|
|
487
|
+
for (const line of failureExcerpt(trimmed)) {
|
|
488
|
+
onOutput(line);
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
}
|
|
406
492
|
|
|
407
493
|
// src/core/engine.ts
|
|
408
494
|
function emitLog(message) {
|
|
@@ -427,12 +513,50 @@ function newlyCompletedStoryIds(before, after) {
|
|
|
427
513
|
const wasPassing = new Map(before.map((story) => [story.id, story.passes]));
|
|
428
514
|
return after.filter((story) => story.passes && wasPassing.get(story.id) === false).map((story) => story.id);
|
|
429
515
|
}
|
|
430
|
-
function
|
|
431
|
-
|
|
516
|
+
function numericIssue(value) {
|
|
517
|
+
if (value === void 0 || value === null || value === "") return void 0;
|
|
518
|
+
const parsed = typeof value === "number" ? value : Number(value);
|
|
519
|
+
return Number.isInteger(parsed) && parsed > 0 ? parsed : void 0;
|
|
520
|
+
}
|
|
521
|
+
function commitPlaceholders(scope, convention, options) {
|
|
432
522
|
const declared = convention !== void 0 && convention !== null && convention !== "";
|
|
523
|
+
const type = options?.type ?? "feat";
|
|
524
|
+
const issueNumber = numericIssue(options?.issueNumber);
|
|
525
|
+
const resolvedScope = scope === void 0 || scope === "" ? void 0 : scope;
|
|
526
|
+
if (declared && options?.type === void 0) {
|
|
527
|
+
const suffix = resolvedScope === void 0 ? "" : `(${resolvedScope})`;
|
|
528
|
+
return {
|
|
529
|
+
__COMMIT_MESSAGE__: commitMessage({
|
|
530
|
+
type,
|
|
531
|
+
scope: resolvedScope,
|
|
532
|
+
subject: "[Story ID] - [Story Title]",
|
|
533
|
+
issueNumber,
|
|
534
|
+
signoff: options?.signoff
|
|
535
|
+
}).replace(`${type}${suffix}:`, `<type>${suffix}:`),
|
|
536
|
+
__FIX_COMMIT_MESSAGE__: commitMessage({
|
|
537
|
+
type: "fix",
|
|
538
|
+
scope: resolvedScope,
|
|
539
|
+
subject: "address review findings",
|
|
540
|
+
issueNumber,
|
|
541
|
+
signoff: options?.signoff
|
|
542
|
+
})
|
|
543
|
+
};
|
|
544
|
+
}
|
|
433
545
|
return {
|
|
434
|
-
__COMMIT_MESSAGE__:
|
|
435
|
-
|
|
546
|
+
__COMMIT_MESSAGE__: commitMessage({
|
|
547
|
+
type,
|
|
548
|
+
scope: resolvedScope,
|
|
549
|
+
subject: "[Story ID] - [Story Title]",
|
|
550
|
+
issueNumber,
|
|
551
|
+
signoff: options?.signoff
|
|
552
|
+
}),
|
|
553
|
+
__FIX_COMMIT_MESSAGE__: commitMessage({
|
|
554
|
+
type: "fix",
|
|
555
|
+
scope: resolvedScope,
|
|
556
|
+
subject: "address review findings",
|
|
557
|
+
issueNumber,
|
|
558
|
+
signoff: options?.signoff
|
|
559
|
+
})
|
|
436
560
|
};
|
|
437
561
|
}
|
|
438
562
|
function inactivityOptions() {
|
|
@@ -482,7 +606,7 @@ async function archiveIfBranchChanged(plan, paths) {
|
|
|
482
606
|
}
|
|
483
607
|
if (currentBranch && lastBranch && currentBranch !== lastBranch) {
|
|
484
608
|
const dateStr = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
485
|
-
const folderName = lastBranch
|
|
609
|
+
const folderName = archiveFolderName(lastBranch);
|
|
486
610
|
const archiveFolder = join(archiveDir, `${dateStr}-${folderName}`);
|
|
487
611
|
printInfo(`Archiving previous run: ${lastBranch}`);
|
|
488
612
|
await mkdir(archiveFolder, { recursive: true });
|
|
@@ -541,14 +665,20 @@ async function runEngine(config, paths) {
|
|
|
541
665
|
emitLog("All user stories already pass. Marking issue as completed.");
|
|
542
666
|
plan = markIssueCompleted(plan);
|
|
543
667
|
await saveTaskPlan(paths.prdFile, plan);
|
|
544
|
-
return
|
|
668
|
+
return finishWithAcceptance(config, paths, plan);
|
|
545
669
|
}
|
|
546
670
|
await archiveIfBranchChanged(plan, paths);
|
|
547
671
|
await trackBranch(plan, paths.lastBranchFile);
|
|
548
672
|
await ensureProgressFile(paths.progressFile);
|
|
549
673
|
const promptTemplate = await loadPrompt("execute", { projectRoot: paths.projectRoot });
|
|
550
674
|
const policy = await resolvePolicyPlaceholders({ root: paths.projectRoot });
|
|
551
|
-
|
|
675
|
+
const signoff = (await loadGlobalConfig()).commit?.signoff === true;
|
|
676
|
+
const executeAgent = await resolveAgentFor("execute");
|
|
677
|
+
printStartupHeader(config, plan, {
|
|
678
|
+
provider: executeAgent.provider,
|
|
679
|
+
model: executeAgent.model,
|
|
680
|
+
...executeAgent.codex.reasoningEffort ? { detail: executeAgent.codex.reasoningEffort } : {}
|
|
681
|
+
});
|
|
552
682
|
const startTime = Date.now();
|
|
553
683
|
let i = 0;
|
|
554
684
|
let totalRetryCount = 0;
|
|
@@ -570,6 +700,13 @@ async function runEngine(config, paths) {
|
|
|
570
700
|
const attempted = await withRetry(
|
|
571
701
|
async () => {
|
|
572
702
|
plan = await loadTaskPlan(paths.prdFile);
|
|
703
|
+
if (plan.userStories.length > 0) {
|
|
704
|
+
getSessionPublisher().publish({
|
|
705
|
+
type: "stories:update",
|
|
706
|
+
at: isoNow(),
|
|
707
|
+
stories: plan.userStories
|
|
708
|
+
});
|
|
709
|
+
}
|
|
573
710
|
const storiesBefore = plan.userStories;
|
|
574
711
|
const activeStoryId = selectActiveStory(plan.userStories)?.id;
|
|
575
712
|
getSessionPublisher().publish({
|
|
@@ -588,7 +725,11 @@ async function runEngine(config, paths) {
|
|
|
588
725
|
...policy,
|
|
589
726
|
// The convention comes off the projection above rather than from a second
|
|
590
727
|
// discovery: one resolution per run is the whole point of the cache.
|
|
591
|
-
...commitPlaceholders(config.commitScope, policy.__COMMIT_CONVENTION__
|
|
728
|
+
...commitPlaceholders(config.commitScope, policy.__COMMIT_CONVENTION__, {
|
|
729
|
+
issueNumber: plan.issueNumber,
|
|
730
|
+
signoff
|
|
731
|
+
}),
|
|
732
|
+
__STORIES_PER_ITERATION__: String(config.storiesPerIteration ?? 1)
|
|
592
733
|
});
|
|
593
734
|
const startedAt = isoNow();
|
|
594
735
|
plan = markIssueInProgress(plan, startedAt);
|
|
@@ -617,6 +758,19 @@ async function runEngine(config, paths) {
|
|
|
617
758
|
if (!failure.retryable) {
|
|
618
759
|
plan = await loadTaskPlan(paths.prdFile);
|
|
619
760
|
plan = setLastError(plan, "fatal_claude_failure", errorMessage);
|
|
761
|
+
if (resolvePolicy(failure.kind, getActiveResilienceConfig()).onExhausted === "block") {
|
|
762
|
+
plan = {
|
|
763
|
+
...plan,
|
|
764
|
+
runState: {
|
|
765
|
+
currentPhase: "execute",
|
|
766
|
+
attempt,
|
|
767
|
+
owner: plan.runState?.owner ?? null,
|
|
768
|
+
status: "blocked",
|
|
769
|
+
blockedReason: errorMessage,
|
|
770
|
+
lastHeartbeatAt: isoNow()
|
|
771
|
+
}
|
|
772
|
+
};
|
|
773
|
+
}
|
|
620
774
|
await saveTaskPlan(paths.prdFile, plan);
|
|
621
775
|
return;
|
|
622
776
|
}
|
|
@@ -691,7 +845,6 @@ async function runEngine(config, paths) {
|
|
|
691
845
|
}
|
|
692
846
|
getSessionPublisher().publish({ type: "iteration:end", at: isoNow(), iteration: i });
|
|
693
847
|
publishIterationMetrics(i, result.cost, iterationSeconds);
|
|
694
|
-
await publishGitState(getSessionPublisher());
|
|
695
848
|
if (result.output.includes("<promise>COMPLETE</promise>")) {
|
|
696
849
|
plan = await loadTaskPlan(paths.prdFile);
|
|
697
850
|
if (allStoriesPass(plan) && !hasPendingCorrection(plan)) {
|
|
@@ -707,7 +860,7 @@ async function runEngine(config, paths) {
|
|
|
707
860
|
void 0,
|
|
708
861
|
getPhaseUsageTotals(EXECUTE_PHASE)
|
|
709
862
|
);
|
|
710
|
-
return
|
|
863
|
+
return finishWithAcceptance(config, paths, plan);
|
|
711
864
|
}
|
|
712
865
|
plan = setLastError(
|
|
713
866
|
plan,
|
|
@@ -723,7 +876,6 @@ async function runEngine(config, paths) {
|
|
|
723
876
|
if (isVerbose()) {
|
|
724
877
|
printSuccess(`Iteration ${i} complete. Continuing...`);
|
|
725
878
|
}
|
|
726
|
-
await sleep(2);
|
|
727
879
|
}
|
|
728
880
|
const elapsed = Math.floor((Date.now() - startTime) / 1e3);
|
|
729
881
|
plan = await loadTaskPlan(paths.prdFile);
|
|
@@ -738,6 +890,21 @@ async function runEngine(config, paths) {
|
|
|
738
890
|
);
|
|
739
891
|
return 1;
|
|
740
892
|
}
|
|
893
|
+
async function finishWithAcceptance(config, paths, plan) {
|
|
894
|
+
const issueDir = resolveIssueDir(config, paths);
|
|
895
|
+
const outcome = await runAcceptanceGate({
|
|
896
|
+
issueDir,
|
|
897
|
+
cwd: paths.projectRoot,
|
|
898
|
+
addDirs: config.issueNumber === void 0 ? void 0 : [issueDir],
|
|
899
|
+
skipReviewer: true
|
|
900
|
+
});
|
|
901
|
+
const applied = applyAcceptanceToPlan(plan, outcome);
|
|
902
|
+
if (applied.failed) {
|
|
903
|
+
await saveTaskPlan(paths.prdFile, applied.plan);
|
|
904
|
+
return 1;
|
|
905
|
+
}
|
|
906
|
+
return 0;
|
|
907
|
+
}
|
|
741
908
|
|
|
742
909
|
// src/commands/execute.ts
|
|
743
910
|
async function runExecute(positionalMaxIter, options) {
|
|
@@ -758,23 +925,73 @@ async function runExecute(positionalMaxIter, options) {
|
|
|
758
925
|
commitScope: options.commitScope
|
|
759
926
|
});
|
|
760
927
|
const paths = await resolvePaths(config);
|
|
761
|
-
const
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
928
|
+
const webConfig = await loadWebConfig();
|
|
929
|
+
const inheritedPublisher = getSessionPublisher();
|
|
930
|
+
let standalonePublisher = null;
|
|
931
|
+
if (webConfig.enabled && config.issueNumber !== void 0 && inheritedPublisher instanceof NullPublisher) {
|
|
932
|
+
const issuePaths = await resolveIssuePaths(config.issueNumber, {
|
|
933
|
+
projectRoot: paths.projectRoot
|
|
934
|
+
});
|
|
935
|
+
standalonePublisher = new FilePublisher(issuePaths.sessionFile, {
|
|
936
|
+
logLimit: webConfig.logLimit,
|
|
937
|
+
includeLogs: webConfig.includeLogs
|
|
938
|
+
});
|
|
939
|
+
setSessionPublisher(standalonePublisher);
|
|
940
|
+
const numericIssue2 = /^\d+$/.test(config.issueNumber) ? Number(config.issueNumber) : null;
|
|
941
|
+
standalonePublisher.publish({
|
|
942
|
+
type: "session:start",
|
|
943
|
+
at: isoNow(),
|
|
944
|
+
sessionId: randomUUID(),
|
|
945
|
+
issueNumber: numericIssue2,
|
|
946
|
+
phases: ["execute"]
|
|
947
|
+
});
|
|
948
|
+
standalonePublisher.publish({ type: "phase:start", at: isoNow(), phase: "execute" });
|
|
949
|
+
await ensureWebMonitor({
|
|
950
|
+
publisher: standalonePublisher,
|
|
951
|
+
port: webConfig.port,
|
|
952
|
+
host: webConfig.host,
|
|
953
|
+
refreshSeconds: webConfig.refreshSeconds
|
|
954
|
+
});
|
|
955
|
+
}
|
|
956
|
+
let exitCode = null;
|
|
957
|
+
try {
|
|
958
|
+
exitCode = await runEngine(config, paths);
|
|
959
|
+
if (exitCode === 0 && config.issueNumber) {
|
|
960
|
+
try {
|
|
961
|
+
const plan = await loadTaskPlan(paths.prdFile);
|
|
962
|
+
if (allStoriesPass(plan)) {
|
|
963
|
+
plan.pipeline.executionCompleted = true;
|
|
964
|
+
await saveTaskPlan(paths.prdFile, plan);
|
|
965
|
+
}
|
|
966
|
+
} catch {
|
|
768
967
|
}
|
|
769
|
-
}
|
|
968
|
+
}
|
|
969
|
+
return exitCode;
|
|
970
|
+
} finally {
|
|
971
|
+
if (standalonePublisher !== null) {
|
|
972
|
+
const success = exitCode === 0;
|
|
973
|
+
standalonePublisher.publish({
|
|
974
|
+
type: "phase:end",
|
|
975
|
+
at: isoNow(),
|
|
976
|
+
phase: "execute",
|
|
977
|
+
success,
|
|
978
|
+
...success ? {} : { error: "Execute phase failed" }
|
|
979
|
+
});
|
|
980
|
+
standalonePublisher.publish({
|
|
981
|
+
type: "session:end",
|
|
982
|
+
at: isoNow(),
|
|
983
|
+
status: success ? "completed" : "failed"
|
|
984
|
+
});
|
|
985
|
+
await standalonePublisher.close();
|
|
986
|
+
setSessionPublisher(void 0);
|
|
770
987
|
}
|
|
771
988
|
}
|
|
772
|
-
return exitCode;
|
|
773
989
|
}
|
|
774
990
|
|
|
775
991
|
export {
|
|
992
|
+
stripMarkdown,
|
|
776
993
|
printQueueSummary,
|
|
777
994
|
printRunSummary,
|
|
778
995
|
runExecute
|
|
779
996
|
};
|
|
780
|
-
//# sourceMappingURL=chunk-
|
|
997
|
+
//# sourceMappingURL=chunk-LZ6GFQAG.js.map
|