issue-flow 0.12.0 → 0.14.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-OX3KPHE4.js +30 -0
- package/dist/{analyze-OEET7KGE.js → analyze-WIND2SEB.js} +31 -16
- package/dist/analyze-WIND2SEB.js.map +1 -0
- package/dist/{apply-ZIA3C52S.js → apply-JNOI2LR4.js} +18 -7
- package/dist/{apply-ZIA3C52S.js.map → apply-JNOI2LR4.js.map} +1 -1
- package/dist/bench-B4VZON7E.js +910 -0
- package/dist/bench-B4VZON7E.js.map +1 -0
- package/dist/{chunk-FADTCQGM.js → chunk-2IQ6M4ZE.js} +94 -32
- package/dist/chunk-2IQ6M4ZE.js.map +1 -0
- package/dist/chunk-3BWZO4YI.js +141 -0
- package/dist/chunk-3BWZO4YI.js.map +1 -0
- package/dist/chunk-3WFZETIM.js +163 -0
- package/dist/chunk-3WFZETIM.js.map +1 -0
- package/dist/chunk-67YIU2VB.js +362 -0
- package/dist/chunk-67YIU2VB.js.map +1 -0
- package/dist/{chunk-QCPGHBSZ.js → chunk-6BENHR2I.js} +63 -21
- package/dist/chunk-6BENHR2I.js.map +1 -0
- package/dist/{chunk-BYZDPR7N.js → chunk-6QYMSNVA.js} +194 -235
- package/dist/chunk-6QYMSNVA.js.map +1 -0
- package/dist/{chunk-Y5ZDJ4PJ.js → chunk-76MMPJ53.js} +20 -10
- package/dist/chunk-76MMPJ53.js.map +1 -0
- package/dist/chunk-7Z4Y3VKM.js +26 -0
- package/dist/chunk-7Z4Y3VKM.js.map +1 -0
- package/dist/{chunk-3QHK4YQA.js → chunk-B72RQZBV.js} +346 -119
- package/dist/chunk-B72RQZBV.js.map +1 -0
- package/dist/chunk-BEZ5BA5U.js +625 -0
- package/dist/chunk-BEZ5BA5U.js.map +1 -0
- package/dist/chunk-BRCNQXYQ.js +74 -0
- package/dist/chunk-BRCNQXYQ.js.map +1 -0
- package/dist/chunk-CGKLE6WR.js +1203 -0
- package/dist/chunk-CGKLE6WR.js.map +1 -0
- package/dist/chunk-CRGIQFUQ.js +83 -0
- package/dist/chunk-CRGIQFUQ.js.map +1 -0
- package/dist/{chunk-NS6R37II.js → chunk-F6TOYSYY.js} +141 -12
- package/dist/chunk-F6TOYSYY.js.map +1 -0
- package/dist/chunk-G5EK2XRN.js +25 -0
- package/dist/chunk-G5EK2XRN.js.map +1 -0
- package/dist/chunk-HAKDLR6N.js +134 -0
- package/dist/chunk-HAKDLR6N.js.map +1 -0
- package/dist/chunk-J3SOTUVI.js +298 -0
- package/dist/chunk-J3SOTUVI.js.map +1 -0
- package/dist/chunk-JN6D3MY6.js +30 -0
- package/dist/chunk-JN6D3MY6.js.map +1 -0
- package/dist/{chunk-LAFNLLQP.js → chunk-KMRFRXIT.js} +5 -5
- package/dist/chunk-KT7JKOXB.js +72 -0
- package/dist/chunk-KT7JKOXB.js.map +1 -0
- package/dist/chunk-L6HSKTQE.js +77 -0
- package/dist/chunk-L6HSKTQE.js.map +1 -0
- package/dist/chunk-LBGHI4S2.js +1264 -0
- package/dist/chunk-LBGHI4S2.js.map +1 -0
- package/dist/chunk-LEW4QM74.js +180 -0
- package/dist/chunk-LEW4QM74.js.map +1 -0
- package/dist/{chunk-FJP3UQGD.js → chunk-LFEQIZLB.js} +115 -20
- package/dist/chunk-LFEQIZLB.js.map +1 -0
- package/dist/chunk-OOVG2KBY.js +77 -0
- package/dist/chunk-OOVG2KBY.js.map +1 -0
- package/dist/{chunk-56KS3TFQ.js → chunk-OR43364P.js} +115 -160
- package/dist/chunk-OR43364P.js.map +1 -0
- package/dist/chunk-P3LRUNC6.js +16 -0
- package/dist/chunk-P3LRUNC6.js.map +1 -0
- package/dist/{chunk-TSOLWK7Y.js → chunk-PBTA3QQX.js} +8 -7
- package/dist/{chunk-TSOLWK7Y.js.map → chunk-PBTA3QQX.js.map} +1 -1
- package/dist/{chunk-MJULIKQU.js → chunk-PHW2YV6N.js} +23 -47
- package/dist/chunk-PHW2YV6N.js.map +1 -0
- package/dist/{chunk-73ATPIYX.js → chunk-PZTWU277.js} +36 -71
- package/dist/chunk-PZTWU277.js.map +1 -0
- package/dist/{chunk-M5UCXTIT.js → chunk-QD4VOILZ.js} +22 -18
- package/dist/chunk-QD4VOILZ.js.map +1 -0
- package/dist/chunk-QJ5UZAH5.js +2718 -0
- package/dist/chunk-QJ5UZAH5.js.map +1 -0
- package/dist/chunk-QK7WUO7A.js +283 -0
- package/dist/chunk-QK7WUO7A.js.map +1 -0
- package/dist/{chunk-A4SLHOW7.js → chunk-QZVKRDJY.js} +27 -19
- package/dist/chunk-QZVKRDJY.js.map +1 -0
- package/dist/chunk-REO3PXXO.js +71 -0
- package/dist/chunk-REO3PXXO.js.map +1 -0
- package/dist/{chunk-EZATO3DW.js → chunk-RVO7L4FX.js} +594 -17
- package/dist/chunk-RVO7L4FX.js.map +1 -0
- package/dist/{chunk-XQUSIEKA.js → chunk-SZMHCEYV.js} +63 -14
- package/dist/chunk-SZMHCEYV.js.map +1 -0
- package/dist/chunk-TYRNTSPJ.js +243 -0
- package/dist/chunk-TYRNTSPJ.js.map +1 -0
- package/dist/chunk-UJ3L2MS7.js +238 -0
- package/dist/chunk-UJ3L2MS7.js.map +1 -0
- package/dist/chunk-V7MO5EDS.js +120 -0
- package/dist/chunk-V7MO5EDS.js.map +1 -0
- package/dist/chunk-WB2X37MO.js +415 -0
- package/dist/chunk-WB2X37MO.js.map +1 -0
- package/dist/{chunk-NTMMF5UD.js → chunk-X44FKNKP.js} +525 -252
- package/dist/chunk-X44FKNKP.js.map +1 -0
- package/dist/chunk-XEYH6ZZI.js +289 -0
- package/dist/chunk-XEYH6ZZI.js.map +1 -0
- package/dist/cli.js +267 -44
- package/dist/cli.js.map +1 -1
- package/dist/{config-PRJGWW7J.js → config-HMFMCY2M.js} +31 -5
- package/dist/contract-JH2WBIO6.js +8 -0
- package/dist/conventions-NJF2OPVQ.js +146 -0
- package/dist/conventions-NJF2OPVQ.js.map +1 -0
- package/dist/diagnostics-THH42ZMP.js +23 -0
- package/dist/execute-KFNNZZHI.js +35 -0
- package/dist/{generate-EGB4KV2B.js → generate-FW5C6NP7.js} +37 -20
- package/dist/{generate-EGB4KV2B.js.map → generate-FW5C6NP7.js.map} +1 -1
- package/dist/git-W72QQ6GT.js +33 -0
- package/dist/init-HTN4V67Q.js +24 -0
- package/dist/{operations-BYT626KQ.js → operations-BCFOBH42.js} +27 -15
- package/dist/{operations-BYT626KQ.js.map → operations-BCFOBH42.js.map} +1 -1
- package/dist/permissions-4AKNQZHK.js +18 -0
- package/dist/plan-SIZLGA4V.js +34 -0
- package/dist/{policy-6S4GFC76.js → policy-DT6Q6ZVM.js} +20 -6
- package/dist/policy-DT6Q6ZVM.js.map +1 -0
- package/dist/pr-OMWCGUOW.js +39 -0
- package/dist/pr-review-N24CZPKR.js +32 -0
- package/dist/pr-review-N24CZPKR.js.map +1 -0
- package/dist/prd-5OFTZAHJ.js +33 -0
- package/dist/prd-5OFTZAHJ.js.map +1 -0
- package/dist/ps-RFORTCUD.js +93 -0
- package/dist/ps-RFORTCUD.js.map +1 -0
- package/dist/recorder-KCCPMKQG.js +32 -0
- package/dist/recorder-KCCPMKQG.js.map +1 -0
- package/dist/registry-GLPXOMFG.js +15 -0
- package/dist/registry-GLPXOMFG.js.map +1 -0
- package/dist/{resume-PPCNQVVV.js → resume-M5RLKP4I.js} +55 -34
- package/dist/{resume-PPCNQVVV.js.map → resume-M5RLKP4I.js.map} +1 -1
- package/dist/review-YM4JAABY.js +35 -0
- package/dist/review-YM4JAABY.js.map +1 -0
- package/dist/routing-NNT5WKGX.js +94 -0
- package/dist/routing-NNT5WKGX.js.map +1 -0
- package/dist/run-PZUKHPQK.js +54 -0
- package/dist/run-PZUKHPQK.js.map +1 -0
- package/dist/session-publisher-T7EI3CIP.js +11 -0
- package/dist/session-publisher-T7EI3CIP.js.map +1 -0
- package/dist/{state-manager-2EDVDBAR.js → state-manager-GQH32C44.js} +4 -2
- package/dist/state-manager-GQH32C44.js.map +1 -0
- package/dist/usage-V2CHE5PY.js +177 -0
- package/dist/usage-V2CHE5PY.js.map +1 -0
- package/dist/{web-EF5WIIGG.js → web-EA3KGNFN.js} +45 -30
- package/dist/web-EA3KGNFN.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 +152 -13
- package/web/public/app.css +380 -109
- package/web/public/app.js +525 -25
- package/web/public/index.html +68 -1
- 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/{config-PRJGWW7J.js.map → agent-OX3KPHE4.js.map} +0 -0
- /package/dist/{chunk-LAFNLLQP.js.map → chunk-KMRFRXIT.js.map} +0 -0
- /package/dist/{execute-XBNVL753.js.map → config-HMFMCY2M.js.map} +0 -0
- /package/dist/{init-AJHCXJBP.js.map → contract-JH2WBIO6.js.map} +0 -0
- /package/dist/{plan-QOZ3RIO6.js.map → diagnostics-THH42ZMP.js.map} +0 -0
- /package/dist/{pr-EBBHD2ZX.js.map → execute-KFNNZZHI.js.map} +0 -0
- /package/dist/{pr-review-VVMW5PO4.js.map → git-W72QQ6GT.js.map} +0 -0
- /package/dist/{prd-JQSZF7PR.js.map → init-HTN4V67Q.js.map} +0 -0
- /package/dist/{review-3F6MARWH.js.map → permissions-4AKNQZHK.js.map} +0 -0
- /package/dist/{run-RXE5GDQO.js.map → plan-SIZLGA4V.js.map} +0 -0
- /package/dist/{state-manager-2EDVDBAR.js.map → pr-OMWCGUOW.js.map} +0 -0
|
@@ -1,48 +1,53 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
|
-
|
|
4
|
-
} from "./chunk-
|
|
3
|
+
ensureWebMonitor
|
|
4
|
+
} from "./chunk-LFEQIZLB.js";
|
|
5
5
|
import {
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
applyAcceptanceToPlan,
|
|
7
|
+
resolveIssueDir,
|
|
8
|
+
runAcceptanceGate
|
|
9
|
+
} from "./chunk-BRCNQXYQ.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-PHW2YV6N.js";
|
|
17
22
|
import {
|
|
18
23
|
applyPlaceholders,
|
|
19
24
|
loadPrompt
|
|
20
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-KMRFRXIT.js";
|
|
21
26
|
import {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
+
invokeSelectedAgent
|
|
28
|
+
} from "./chunk-CGKLE6WR.js";
|
|
29
|
+
import {
|
|
30
|
+
archiveFolderName,
|
|
31
|
+
commitMessage
|
|
32
|
+
} from "./chunk-RVO7L4FX.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-QJ5UZAH5.js";
|
|
32
43
|
import {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
fixedBackoffPolicy,
|
|
36
|
-
getBaseBranch,
|
|
37
|
-
isWorkingTreeClean,
|
|
38
|
-
withRetry
|
|
39
|
-
} from "./chunk-DIDUVL6O.js";
|
|
44
|
+
resolveIssuePaths
|
|
45
|
+
} from "./chunk-QK7WUO7A.js";
|
|
40
46
|
import {
|
|
41
47
|
formatDuration,
|
|
42
48
|
getIcons,
|
|
43
49
|
getInactivityTimeout,
|
|
44
50
|
getOutputCallback,
|
|
45
|
-
getSessionPublisher,
|
|
46
51
|
getStoryStageCallback,
|
|
47
52
|
getStoryUpdateCallback,
|
|
48
53
|
getTermWidth,
|
|
@@ -54,7 +59,21 @@ import {
|
|
|
54
59
|
printWarning,
|
|
55
60
|
useColor,
|
|
56
61
|
useUnicode
|
|
57
|
-
} from "./chunk-
|
|
62
|
+
} from "./chunk-TYRNTSPJ.js";
|
|
63
|
+
import {
|
|
64
|
+
FilePublisher,
|
|
65
|
+
NullPublisher,
|
|
66
|
+
getSessionPublisher,
|
|
67
|
+
setSessionPublisher
|
|
68
|
+
} from "./chunk-6QYMSNVA.js";
|
|
69
|
+
import {
|
|
70
|
+
committedStoryIds,
|
|
71
|
+
fixedBackoffPolicy,
|
|
72
|
+
getBaseBranch,
|
|
73
|
+
isWorkingTreeClean,
|
|
74
|
+
resolvePolicy,
|
|
75
|
+
withRetry
|
|
76
|
+
} from "./chunk-BEZ5BA5U.js";
|
|
58
77
|
import {
|
|
59
78
|
allStoriesPass,
|
|
60
79
|
applyStoryMetrics,
|
|
@@ -71,7 +90,13 @@ import {
|
|
|
71
90
|
selectActiveStory,
|
|
72
91
|
setLastError,
|
|
73
92
|
trimErrorMessage
|
|
74
|
-
} from "./chunk-
|
|
93
|
+
} from "./chunk-J3SOTUVI.js";
|
|
94
|
+
import {
|
|
95
|
+
classify
|
|
96
|
+
} from "./chunk-XEYH6ZZI.js";
|
|
97
|
+
|
|
98
|
+
// src/commands/execute.ts
|
|
99
|
+
import { randomUUID } from "crypto";
|
|
75
100
|
|
|
76
101
|
// src/core/engine.ts
|
|
77
102
|
import { existsSync } from "fs";
|
|
@@ -188,7 +213,7 @@ function printBox(lines) {
|
|
|
188
213
|
}
|
|
189
214
|
console.log(blue(`${bl}${hrule}${br}`));
|
|
190
215
|
}
|
|
191
|
-
function printStartupHeader(config, plan) {
|
|
216
|
+
function printStartupHeader(config, plan, agent) {
|
|
192
217
|
const icons = getIcons();
|
|
193
218
|
const storiesTotal = plan.userStories.length;
|
|
194
219
|
const storiesPassing = plan.userStories.filter((s) => s.passes).length;
|
|
@@ -196,7 +221,7 @@ function printStartupHeader(config, plan) {
|
|
|
196
221
|
const issueLabel = config.issueNumber ? `Issue #${config.issueNumber}` : "Standalone mode";
|
|
197
222
|
const maxIterLabel = config.maxIterations !== void 0 ? String(config.maxIterations) : "unlimited";
|
|
198
223
|
const retryLabel = config.retryForever ? "unlimited retries" : `${config.retryLimit} consecutive retries`;
|
|
199
|
-
|
|
224
|
+
const lines = [
|
|
200
225
|
`${icons.start} Issue Flow`,
|
|
201
226
|
"---",
|
|
202
227
|
`Issue: ${issueLabel}`,
|
|
@@ -204,9 +229,22 @@ function printStartupHeader(config, plan) {
|
|
|
204
229
|
`Stories: ${storiesPassing}/${storiesTotal} passing`,
|
|
205
230
|
`Iterations: ${maxIterLabel}`,
|
|
206
231
|
`Retries: ${retryLabel}`
|
|
207
|
-
]
|
|
232
|
+
];
|
|
233
|
+
const remaining = storiesTotal - storiesPassing;
|
|
234
|
+
if (remaining > 0) {
|
|
235
|
+
const p50ExecuteSeconds = 518;
|
|
236
|
+
lines.push(
|
|
237
|
+
`Estimate: ~${formatDuration(remaining * p50ExecuteSeconds)} (${remaining} \xD7 p50 execute)`
|
|
238
|
+
);
|
|
239
|
+
}
|
|
240
|
+
if (agent) {
|
|
241
|
+
const model = agent.model ? ` \xB7 ${agent.model}` : "";
|
|
242
|
+
const detail = agent.detail ? ` (${agent.detail})` : "";
|
|
243
|
+
lines.push(`Agent: ${agent.provider}${model}${detail}`);
|
|
244
|
+
}
|
|
245
|
+
printBox(lines);
|
|
208
246
|
}
|
|
209
|
-
function printSummaryBox(status, iterations, totalRetries, elapsedSeconds, plan, extraInfo, usage) {
|
|
247
|
+
function printSummaryBox(status, iterations, totalRetries, elapsedSeconds, plan, extraInfo, usage, usageByAgent) {
|
|
210
248
|
const icons = getIcons();
|
|
211
249
|
const storiesTotal = plan.userStories.length;
|
|
212
250
|
const storiesPassing = plan.userStories.filter((s) => s.passes).length;
|
|
@@ -235,10 +273,8 @@ function printSummaryBox(status, iterations, totalRetries, elapsedSeconds, plan,
|
|
|
235
273
|
`Iterations: ${iterations}`,
|
|
236
274
|
`Duration: ${duration}`
|
|
237
275
|
];
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
boxLines.push(`Tokens: ${tokens}`);
|
|
241
|
-
}
|
|
276
|
+
boxLines.push(...tokenBoxLines(usage, usageByAgent));
|
|
277
|
+
boxLines.push(...executionCostLines(plan));
|
|
242
278
|
boxLines.push(`Retries: ${totalRetries}`);
|
|
243
279
|
if (extraInfo) {
|
|
244
280
|
boxLines.push("---");
|
|
@@ -247,19 +283,79 @@ function printSummaryBox(status, iterations, totalRetries, elapsedSeconds, plan,
|
|
|
247
283
|
console.log("");
|
|
248
284
|
printBox(boxLines);
|
|
249
285
|
}
|
|
286
|
+
function executionCostLines(plan, prefix = "Cost: ") {
|
|
287
|
+
const records = plan.executions ?? [];
|
|
288
|
+
if (records.length === 0) return [];
|
|
289
|
+
const lines = [];
|
|
290
|
+
const groups = groupBy(records, "harness");
|
|
291
|
+
let index = 0;
|
|
292
|
+
const pad = " ".repeat(prefix.length);
|
|
293
|
+
for (const [harness, summary] of groups) {
|
|
294
|
+
const parts = [];
|
|
295
|
+
if (summary.totalCost.reported > 0) {
|
|
296
|
+
parts.push(`$${summary.totalCost.reported.toFixed(4)} reported`);
|
|
297
|
+
}
|
|
298
|
+
if (summary.totalCost.estimated > 0) {
|
|
299
|
+
parts.push(`$${summary.totalCost.estimated.toFixed(4)} estimated`);
|
|
300
|
+
}
|
|
301
|
+
if (summary.totalCost.unknownExecutions > 0) {
|
|
302
|
+
parts.push(`${summary.totalCost.unknownExecutions} unknown`);
|
|
303
|
+
}
|
|
304
|
+
if (parts.length === 0) {
|
|
305
|
+
const totals = summarize(records).totalCost;
|
|
306
|
+
if (totals.reported === 0 && totals.estimated === 0) {
|
|
307
|
+
parts.push("not reported");
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
if (parts.length === 0) continue;
|
|
311
|
+
lines.push(`${index === 0 ? prefix : pad}${harness} \xB7 ${parts.join(" \xB7 ")}`);
|
|
312
|
+
index += 1;
|
|
313
|
+
}
|
|
314
|
+
return lines;
|
|
315
|
+
}
|
|
316
|
+
function tokenBoxLines(usage, usageByAgent) {
|
|
317
|
+
const agents = usageByAgent ? Object.keys(usageByAgent) : [];
|
|
318
|
+
if (agents.length > 1) {
|
|
319
|
+
const lines = [];
|
|
320
|
+
for (const [index, id] of agents.entries()) {
|
|
321
|
+
const tokens2 = formatTokens(usageByAgent?.[id]);
|
|
322
|
+
if (tokens2 === "") continue;
|
|
323
|
+
lines.push(index === 0 ? `Tokens: ${id} \xB7 ${tokens2}` : ` ${id} \xB7 ${tokens2}`);
|
|
324
|
+
}
|
|
325
|
+
return lines;
|
|
326
|
+
}
|
|
327
|
+
const tokens = formatTokens(usage);
|
|
328
|
+
return tokens === "" ? [] : [`Tokens: ${tokens}`];
|
|
329
|
+
}
|
|
330
|
+
function tokenSummaryLines(usage, usageByAgent, prefix = " Tokens: ") {
|
|
331
|
+
const agents = usageByAgent ? Object.keys(usageByAgent) : [];
|
|
332
|
+
if (agents.length > 1) {
|
|
333
|
+
const pad = " ".repeat(prefix.length);
|
|
334
|
+
const lines = [];
|
|
335
|
+
for (const [index, id] of agents.entries()) {
|
|
336
|
+
const tokens2 = formatTokens(usageByAgent?.[id]);
|
|
337
|
+
if (tokens2 === "") continue;
|
|
338
|
+
lines.push(`${index === 0 ? prefix : pad}${id} \xB7 ${tokens2}`);
|
|
339
|
+
}
|
|
340
|
+
return lines;
|
|
341
|
+
}
|
|
342
|
+
const tokens = formatTokens(usage);
|
|
343
|
+
return tokens === "" ? [] : [`${prefix}${tokens}`];
|
|
344
|
+
}
|
|
250
345
|
function buildRunSummaryLines(info) {
|
|
251
346
|
const lines = [
|
|
252
347
|
` Branch: ${info.branchName}${info.noBranch ? " (current)" : ""}`,
|
|
253
348
|
` Stories: ${info.storyCount}`,
|
|
254
349
|
` Duration: ${formatDuration(info.elapsedSeconds)}`
|
|
255
350
|
];
|
|
256
|
-
|
|
257
|
-
if (tokens !== "") {
|
|
258
|
-
lines.push(` Tokens: ${tokens}`);
|
|
259
|
-
}
|
|
351
|
+
lines.push(...tokenSummaryLines(info.usage, info.usageByAgent));
|
|
260
352
|
if (!info.noBranch) {
|
|
261
353
|
lines.push(` PR: ${info.prUrl}`);
|
|
262
354
|
}
|
|
355
|
+
if (info.verification != null) {
|
|
356
|
+
const label = info.verification.verdict === "passed" ? "passed" : info.verification.verdict === "failed" ? "failed" : "unverified";
|
|
357
|
+
lines.push(` Contract: ${label}`);
|
|
358
|
+
}
|
|
263
359
|
const review = info.prReview;
|
|
264
360
|
if (review) {
|
|
265
361
|
const verdict = review.recommendation ?? (review.requestedChanges ? "REQUEST_CHANGES" : "unknown");
|
|
@@ -320,6 +416,14 @@ function printRunSummary(info) {
|
|
|
320
416
|
printWarning(
|
|
321
417
|
`Pipeline finished for issue #${info.issueNumber}, but the PR review requested changes.`
|
|
322
418
|
);
|
|
419
|
+
} else if (info.verification?.verdict === "unverified") {
|
|
420
|
+
printWarning(
|
|
421
|
+
`Pipeline finished for issue #${info.issueNumber}, but the acceptance contract is unverified.`
|
|
422
|
+
);
|
|
423
|
+
} else if (info.verification?.verdict === "failed") {
|
|
424
|
+
printWarning(
|
|
425
|
+
`Pipeline finished for issue #${info.issueNumber}, but the acceptance contract failed.`
|
|
426
|
+
);
|
|
323
427
|
} else {
|
|
324
428
|
printSuccess(`Pipeline complete for issue #${info.issueNumber}!`);
|
|
325
429
|
}
|
|
@@ -328,81 +432,68 @@ function printRunSummary(info) {
|
|
|
328
432
|
}
|
|
329
433
|
}
|
|
330
434
|
|
|
435
|
+
// src/ui/text.ts
|
|
436
|
+
function stripMarkdown(text) {
|
|
437
|
+
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();
|
|
438
|
+
}
|
|
439
|
+
function failureExcerpt(output, limit = 8) {
|
|
440
|
+
return output.split("\n").map((line) => stripMarkdown(line)).filter((line) => line.length > 0).slice(-limit);
|
|
441
|
+
}
|
|
442
|
+
|
|
331
443
|
// src/core/executor.ts
|
|
332
|
-
import { execa } from "execa";
|
|
333
444
|
async function executeClaude(prompt, options = {}) {
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
reject: false,
|
|
445
|
+
let selected;
|
|
446
|
+
try {
|
|
447
|
+
selected = await invokeSelectedAgent({
|
|
448
|
+
prompt,
|
|
449
|
+
phase: "execute",
|
|
340
450
|
timeout: 0,
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
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) {
|
|
451
|
+
permission: "autonomous",
|
|
452
|
+
inactivityTimeoutMs: options.inactivityTimeoutMs,
|
|
453
|
+
iteration: options.iteration,
|
|
454
|
+
correctionCycle: options.correctionCycle,
|
|
455
|
+
storyIds: options.storyIds
|
|
456
|
+
});
|
|
457
|
+
} catch (err) {
|
|
383
458
|
return {
|
|
384
|
-
exitCode:
|
|
385
|
-
output:
|
|
459
|
+
exitCode: 1,
|
|
460
|
+
output: err instanceof Error ? err.message : String(err),
|
|
386
461
|
cost: null
|
|
387
462
|
};
|
|
388
463
|
}
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
onOutput(trimmed);
|
|
398
|
-
}
|
|
464
|
+
const { run } = selected;
|
|
465
|
+
let output;
|
|
466
|
+
let cost = run.usage;
|
|
467
|
+
if (!run.success || run.exitCode !== 0) {
|
|
468
|
+
output = run.rawOutput || run.error || "";
|
|
469
|
+
cost = null;
|
|
470
|
+
} else {
|
|
471
|
+
output = run.result || run.rawOutput;
|
|
399
472
|
}
|
|
473
|
+
emitAgentOutput(output, !(run.success && run.exitCode === 0));
|
|
400
474
|
return {
|
|
401
|
-
exitCode,
|
|
475
|
+
exitCode: run.exitCode === 0 && run.success ? 0 : run.exitCode === 0 ? 1 : run.exitCode,
|
|
402
476
|
output,
|
|
403
477
|
cost
|
|
404
478
|
};
|
|
405
479
|
}
|
|
480
|
+
function emitAgentOutput(output, failed) {
|
|
481
|
+
const onOutput = getOutputCallback();
|
|
482
|
+
if (!onOutput) return;
|
|
483
|
+
const trimmed = output.trim();
|
|
484
|
+
if (!trimmed) return;
|
|
485
|
+
if (isVerbose()) {
|
|
486
|
+
for (const line of trimmed.split("\n")) {
|
|
487
|
+
if (line.trim()) onOutput(line);
|
|
488
|
+
}
|
|
489
|
+
return;
|
|
490
|
+
}
|
|
491
|
+
if (failed) {
|
|
492
|
+
for (const line of failureExcerpt(trimmed)) {
|
|
493
|
+
onOutput(line);
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
}
|
|
406
497
|
|
|
407
498
|
// src/core/engine.ts
|
|
408
499
|
function emitLog(message) {
|
|
@@ -427,12 +518,50 @@ function newlyCompletedStoryIds(before, after) {
|
|
|
427
518
|
const wasPassing = new Map(before.map((story) => [story.id, story.passes]));
|
|
428
519
|
return after.filter((story) => story.passes && wasPassing.get(story.id) === false).map((story) => story.id);
|
|
429
520
|
}
|
|
430
|
-
function
|
|
431
|
-
|
|
521
|
+
function numericIssue(value) {
|
|
522
|
+
if (value === void 0 || value === null || value === "") return void 0;
|
|
523
|
+
const parsed = typeof value === "number" ? value : Number(value);
|
|
524
|
+
return Number.isInteger(parsed) && parsed > 0 ? parsed : void 0;
|
|
525
|
+
}
|
|
526
|
+
function commitPlaceholders(scope, convention, options) {
|
|
432
527
|
const declared = convention !== void 0 && convention !== null && convention !== "";
|
|
528
|
+
const type = options?.type ?? "feat";
|
|
529
|
+
const issueNumber = numericIssue(options?.issueNumber);
|
|
530
|
+
const resolvedScope = scope === void 0 || scope === "" ? void 0 : scope;
|
|
531
|
+
if (declared && options?.type === void 0) {
|
|
532
|
+
const suffix = resolvedScope === void 0 ? "" : `(${resolvedScope})`;
|
|
533
|
+
return {
|
|
534
|
+
__COMMIT_MESSAGE__: commitMessage({
|
|
535
|
+
type,
|
|
536
|
+
scope: resolvedScope,
|
|
537
|
+
subject: "[Story ID] - [Story Title]",
|
|
538
|
+
issueNumber,
|
|
539
|
+
signoff: options?.signoff
|
|
540
|
+
}).replace(`${type}${suffix}:`, `<type>${suffix}:`),
|
|
541
|
+
__FIX_COMMIT_MESSAGE__: commitMessage({
|
|
542
|
+
type: "fix",
|
|
543
|
+
scope: resolvedScope,
|
|
544
|
+
subject: "address review findings",
|
|
545
|
+
issueNumber,
|
|
546
|
+
signoff: options?.signoff
|
|
547
|
+
})
|
|
548
|
+
};
|
|
549
|
+
}
|
|
433
550
|
return {
|
|
434
|
-
__COMMIT_MESSAGE__:
|
|
435
|
-
|
|
551
|
+
__COMMIT_MESSAGE__: commitMessage({
|
|
552
|
+
type,
|
|
553
|
+
scope: resolvedScope,
|
|
554
|
+
subject: "[Story ID] - [Story Title]",
|
|
555
|
+
issueNumber,
|
|
556
|
+
signoff: options?.signoff
|
|
557
|
+
}),
|
|
558
|
+
__FIX_COMMIT_MESSAGE__: commitMessage({
|
|
559
|
+
type: "fix",
|
|
560
|
+
scope: resolvedScope,
|
|
561
|
+
subject: "address review findings",
|
|
562
|
+
issueNumber,
|
|
563
|
+
signoff: options?.signoff
|
|
564
|
+
})
|
|
436
565
|
};
|
|
437
566
|
}
|
|
438
567
|
function inactivityOptions() {
|
|
@@ -482,7 +611,7 @@ async function archiveIfBranchChanged(plan, paths) {
|
|
|
482
611
|
}
|
|
483
612
|
if (currentBranch && lastBranch && currentBranch !== lastBranch) {
|
|
484
613
|
const dateStr = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
485
|
-
const folderName = lastBranch
|
|
614
|
+
const folderName = archiveFolderName(lastBranch);
|
|
486
615
|
const archiveFolder = join(archiveDir, `${dateStr}-${folderName}`);
|
|
487
616
|
printInfo(`Archiving previous run: ${lastBranch}`);
|
|
488
617
|
await mkdir(archiveFolder, { recursive: true });
|
|
@@ -541,14 +670,20 @@ async function runEngine(config, paths) {
|
|
|
541
670
|
emitLog("All user stories already pass. Marking issue as completed.");
|
|
542
671
|
plan = markIssueCompleted(plan);
|
|
543
672
|
await saveTaskPlan(paths.prdFile, plan);
|
|
544
|
-
return
|
|
673
|
+
return finishWithAcceptance(config, paths, plan);
|
|
545
674
|
}
|
|
546
675
|
await archiveIfBranchChanged(plan, paths);
|
|
547
676
|
await trackBranch(plan, paths.lastBranchFile);
|
|
548
677
|
await ensureProgressFile(paths.progressFile);
|
|
549
678
|
const promptTemplate = await loadPrompt("execute", { projectRoot: paths.projectRoot });
|
|
550
679
|
const policy = await resolvePolicyPlaceholders({ root: paths.projectRoot });
|
|
551
|
-
|
|
680
|
+
const signoff = (await loadGlobalConfig()).commit?.signoff === true;
|
|
681
|
+
const executeAgent = await resolveAgentFor("execute");
|
|
682
|
+
printStartupHeader(config, plan, {
|
|
683
|
+
provider: executeAgent.provider,
|
|
684
|
+
model: executeAgent.model,
|
|
685
|
+
...executeAgent.codex.reasoningEffort ? { detail: executeAgent.codex.reasoningEffort } : {}
|
|
686
|
+
});
|
|
552
687
|
const startTime = Date.now();
|
|
553
688
|
let i = 0;
|
|
554
689
|
let totalRetryCount = 0;
|
|
@@ -570,6 +705,13 @@ async function runEngine(config, paths) {
|
|
|
570
705
|
const attempted = await withRetry(
|
|
571
706
|
async () => {
|
|
572
707
|
plan = await loadTaskPlan(paths.prdFile);
|
|
708
|
+
if (plan.userStories.length > 0) {
|
|
709
|
+
getSessionPublisher().publish({
|
|
710
|
+
type: "stories:update",
|
|
711
|
+
at: isoNow(),
|
|
712
|
+
stories: plan.userStories
|
|
713
|
+
});
|
|
714
|
+
}
|
|
573
715
|
const storiesBefore = plan.userStories;
|
|
574
716
|
const activeStoryId = selectActiveStory(plan.userStories)?.id;
|
|
575
717
|
getSessionPublisher().publish({
|
|
@@ -588,13 +730,22 @@ async function runEngine(config, paths) {
|
|
|
588
730
|
...policy,
|
|
589
731
|
// The convention comes off the projection above rather than from a second
|
|
590
732
|
// discovery: one resolution per run is the whole point of the cache.
|
|
591
|
-
...commitPlaceholders(config.commitScope, policy.__COMMIT_CONVENTION__
|
|
733
|
+
...commitPlaceholders(config.commitScope, policy.__COMMIT_CONVENTION__, {
|
|
734
|
+
issueNumber: plan.issueNumber,
|
|
735
|
+
signoff
|
|
736
|
+
}),
|
|
737
|
+
__STORIES_PER_ITERATION__: String(config.storiesPerIteration ?? 1)
|
|
592
738
|
});
|
|
593
739
|
const startedAt = isoNow();
|
|
594
740
|
plan = markIssueInProgress(plan, startedAt);
|
|
595
741
|
await saveTaskPlan(paths.prdFile, plan);
|
|
596
742
|
const startedAtMs = Date.now();
|
|
597
|
-
const result2 = await executeClaude(prompt,
|
|
743
|
+
const result2 = await executeClaude(prompt, {
|
|
744
|
+
...inactivityOptions(),
|
|
745
|
+
iteration: i,
|
|
746
|
+
correctionCycle: plan.correctionCycle,
|
|
747
|
+
...activeStoryId === void 0 ? {} : { storyIds: [activeStoryId] }
|
|
748
|
+
});
|
|
598
749
|
const seconds = elapsedSecondsSince(startedAtMs);
|
|
599
750
|
if (result2.exitCode !== 0) {
|
|
600
751
|
publishIterationMetrics(i, result2.cost, seconds);
|
|
@@ -617,6 +768,19 @@ async function runEngine(config, paths) {
|
|
|
617
768
|
if (!failure.retryable) {
|
|
618
769
|
plan = await loadTaskPlan(paths.prdFile);
|
|
619
770
|
plan = setLastError(plan, "fatal_claude_failure", errorMessage);
|
|
771
|
+
if (resolvePolicy(failure.kind, getActiveResilienceConfig()).onExhausted === "block") {
|
|
772
|
+
plan = {
|
|
773
|
+
...plan,
|
|
774
|
+
runState: {
|
|
775
|
+
currentPhase: "execute",
|
|
776
|
+
attempt,
|
|
777
|
+
owner: plan.runState?.owner ?? null,
|
|
778
|
+
status: "blocked",
|
|
779
|
+
blockedReason: errorMessage,
|
|
780
|
+
lastHeartbeatAt: isoNow()
|
|
781
|
+
}
|
|
782
|
+
};
|
|
783
|
+
}
|
|
620
784
|
await saveTaskPlan(paths.prdFile, plan);
|
|
621
785
|
return;
|
|
622
786
|
}
|
|
@@ -691,7 +855,6 @@ async function runEngine(config, paths) {
|
|
|
691
855
|
}
|
|
692
856
|
getSessionPublisher().publish({ type: "iteration:end", at: isoNow(), iteration: i });
|
|
693
857
|
publishIterationMetrics(i, result.cost, iterationSeconds);
|
|
694
|
-
await publishGitState(getSessionPublisher());
|
|
695
858
|
if (result.output.includes("<promise>COMPLETE</promise>")) {
|
|
696
859
|
plan = await loadTaskPlan(paths.prdFile);
|
|
697
860
|
if (allStoriesPass(plan) && !hasPendingCorrection(plan)) {
|
|
@@ -707,7 +870,7 @@ async function runEngine(config, paths) {
|
|
|
707
870
|
void 0,
|
|
708
871
|
getPhaseUsageTotals(EXECUTE_PHASE)
|
|
709
872
|
);
|
|
710
|
-
return
|
|
873
|
+
return finishWithAcceptance(config, paths, plan);
|
|
711
874
|
}
|
|
712
875
|
plan = setLastError(
|
|
713
876
|
plan,
|
|
@@ -723,7 +886,6 @@ async function runEngine(config, paths) {
|
|
|
723
886
|
if (isVerbose()) {
|
|
724
887
|
printSuccess(`Iteration ${i} complete. Continuing...`);
|
|
725
888
|
}
|
|
726
|
-
await sleep(2);
|
|
727
889
|
}
|
|
728
890
|
const elapsed = Math.floor((Date.now() - startTime) / 1e3);
|
|
729
891
|
plan = await loadTaskPlan(paths.prdFile);
|
|
@@ -738,6 +900,21 @@ async function runEngine(config, paths) {
|
|
|
738
900
|
);
|
|
739
901
|
return 1;
|
|
740
902
|
}
|
|
903
|
+
async function finishWithAcceptance(config, paths, plan) {
|
|
904
|
+
const issueDir = resolveIssueDir(config, paths);
|
|
905
|
+
const outcome = await runAcceptanceGate({
|
|
906
|
+
issueDir,
|
|
907
|
+
cwd: paths.projectRoot,
|
|
908
|
+
addDirs: config.issueNumber === void 0 ? void 0 : [issueDir],
|
|
909
|
+
skipReviewer: true
|
|
910
|
+
});
|
|
911
|
+
const applied = applyAcceptanceToPlan(plan, outcome);
|
|
912
|
+
if (applied.failed) {
|
|
913
|
+
await saveTaskPlan(paths.prdFile, applied.plan);
|
|
914
|
+
return 1;
|
|
915
|
+
}
|
|
916
|
+
return 0;
|
|
917
|
+
}
|
|
741
918
|
|
|
742
919
|
// src/commands/execute.ts
|
|
743
920
|
async function runExecute(positionalMaxIter, options) {
|
|
@@ -758,23 +935,73 @@ async function runExecute(positionalMaxIter, options) {
|
|
|
758
935
|
commitScope: options.commitScope
|
|
759
936
|
});
|
|
760
937
|
const paths = await resolvePaths(config);
|
|
761
|
-
const
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
938
|
+
const webConfig = await loadWebConfig();
|
|
939
|
+
const inheritedPublisher = getSessionPublisher();
|
|
940
|
+
let standalonePublisher = null;
|
|
941
|
+
if (webConfig.enabled && config.issueNumber !== void 0 && inheritedPublisher instanceof NullPublisher) {
|
|
942
|
+
const issuePaths = await resolveIssuePaths(config.issueNumber, {
|
|
943
|
+
projectRoot: paths.projectRoot
|
|
944
|
+
});
|
|
945
|
+
standalonePublisher = new FilePublisher(issuePaths.sessionFile, {
|
|
946
|
+
logLimit: webConfig.logLimit,
|
|
947
|
+
includeLogs: webConfig.includeLogs
|
|
948
|
+
});
|
|
949
|
+
setSessionPublisher(standalonePublisher);
|
|
950
|
+
const numericIssue2 = /^\d+$/.test(config.issueNumber) ? Number(config.issueNumber) : null;
|
|
951
|
+
standalonePublisher.publish({
|
|
952
|
+
type: "session:start",
|
|
953
|
+
at: isoNow(),
|
|
954
|
+
sessionId: randomUUID(),
|
|
955
|
+
issueNumber: numericIssue2,
|
|
956
|
+
phases: ["execute"]
|
|
957
|
+
});
|
|
958
|
+
standalonePublisher.publish({ type: "phase:start", at: isoNow(), phase: "execute" });
|
|
959
|
+
await ensureWebMonitor({
|
|
960
|
+
publisher: standalonePublisher,
|
|
961
|
+
port: webConfig.port,
|
|
962
|
+
host: webConfig.host,
|
|
963
|
+
refreshSeconds: webConfig.refreshSeconds
|
|
964
|
+
});
|
|
965
|
+
}
|
|
966
|
+
let exitCode = null;
|
|
967
|
+
try {
|
|
968
|
+
exitCode = await runEngine(config, paths);
|
|
969
|
+
if (exitCode === 0 && config.issueNumber) {
|
|
970
|
+
try {
|
|
971
|
+
const plan = await loadTaskPlan(paths.prdFile);
|
|
972
|
+
if (allStoriesPass(plan)) {
|
|
973
|
+
plan.pipeline.executionCompleted = true;
|
|
974
|
+
await saveTaskPlan(paths.prdFile, plan);
|
|
975
|
+
}
|
|
976
|
+
} catch {
|
|
768
977
|
}
|
|
769
|
-
}
|
|
978
|
+
}
|
|
979
|
+
return exitCode;
|
|
980
|
+
} finally {
|
|
981
|
+
if (standalonePublisher !== null) {
|
|
982
|
+
const success = exitCode === 0;
|
|
983
|
+
standalonePublisher.publish({
|
|
984
|
+
type: "phase:end",
|
|
985
|
+
at: isoNow(),
|
|
986
|
+
phase: "execute",
|
|
987
|
+
success,
|
|
988
|
+
...success ? {} : { error: "Execute phase failed" }
|
|
989
|
+
});
|
|
990
|
+
standalonePublisher.publish({
|
|
991
|
+
type: "session:end",
|
|
992
|
+
at: isoNow(),
|
|
993
|
+
status: success ? "completed" : "failed"
|
|
994
|
+
});
|
|
995
|
+
await standalonePublisher.close();
|
|
996
|
+
setSessionPublisher(void 0);
|
|
770
997
|
}
|
|
771
998
|
}
|
|
772
|
-
return exitCode;
|
|
773
999
|
}
|
|
774
1000
|
|
|
775
1001
|
export {
|
|
1002
|
+
stripMarkdown,
|
|
776
1003
|
printQueueSummary,
|
|
777
1004
|
printRunSummary,
|
|
778
1005
|
runExecute
|
|
779
1006
|
};
|
|
780
|
-
//# sourceMappingURL=chunk-
|
|
1007
|
+
//# sourceMappingURL=chunk-B72RQZBV.js.map
|