@xdevops/issue-auto-finish 1.0.87 → 1.0.89
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/dist/{AIRunnerRegistry-II3WWSFN.js → AIRunnerRegistry-CFDNWSXC.js} +6 -3
- package/dist/{LockNote-Z2CLDZNN.js → LockNote-W2JNVMW7.js} +3 -3
- package/dist/PtyRunner-NYASBTRP.js +33 -0
- package/dist/SdkRunner-U2OTOMZU.js +9 -0
- package/dist/ai-runner/AIRunner.d.ts +19 -1
- package/dist/ai-runner/AIRunner.d.ts.map +1 -1
- package/dist/ai-runner/AIRunnerRegistry.d.ts +8 -0
- package/dist/ai-runner/AIRunnerRegistry.d.ts.map +1 -1
- package/dist/ai-runner/PlanFileResolver.d.ts +53 -0
- package/dist/ai-runner/PlanFileResolver.d.ts.map +1 -0
- package/dist/ai-runner/PtyRunner.d.ts +45 -4
- package/dist/ai-runner/PtyRunner.d.ts.map +1 -1
- package/dist/ai-runner/SdkRunner.d.ts +22 -0
- package/dist/ai-runner/SdkRunner.d.ts.map +1 -0
- package/dist/ai-runner/index.d.ts +5 -2
- package/dist/ai-runner/index.d.ts.map +1 -1
- package/dist/ai-runner/sdk/ClaudeCodeSDK.d.ts +37 -0
- package/dist/ai-runner/sdk/ClaudeCodeSDK.d.ts.map +1 -0
- package/dist/ai-runner/sdk/Stream.d.ts +22 -0
- package/dist/ai-runner/sdk/Stream.d.ts.map +1 -0
- package/dist/ai-runner/sdk/types.d.ts +146 -0
- package/dist/ai-runner/sdk/types.d.ts.map +1 -0
- package/dist/{ai-runner-HLA44WI6.js → ai-runner-TOHVJJ76.js} +14 -5
- package/dist/{analyze-ZIXNC5GN.js → analyze-DBH4K3J7.js} +8 -6
- package/dist/{analyze-ZIXNC5GN.js.map → analyze-DBH4K3J7.js.map} +1 -1
- package/dist/{braindump-56WAY2RD.js → braindump-RYI4BGMG.js} +11 -9
- package/dist/{braindump-56WAY2RD.js.map → braindump-RYI4BGMG.js.map} +1 -1
- package/dist/{chunk-AVGZH64A.js → chunk-2RWGZPNF.js} +4 -1
- package/dist/chunk-2RWGZPNF.js.map +1 -0
- package/dist/chunk-4XMYOXGZ.js +1153 -0
- package/dist/chunk-4XMYOXGZ.js.map +1 -0
- package/dist/{chunk-UBQLXQ7I.js → chunk-5JBADEKR.js} +7 -7
- package/dist/{chunk-M5C2WILQ.js → chunk-5M5SB6ZA.js} +7 -5
- package/dist/{chunk-M5C2WILQ.js.map → chunk-5M5SB6ZA.js.map} +1 -1
- package/dist/{chunk-HDFNMVRQ.js → chunk-DVNAH2GV.js} +2 -2
- package/dist/{chunk-GXFG4JU6.js → chunk-EU4XFZ2T.js} +2 -2
- package/dist/{chunk-NZHKAPU6.js → chunk-FJTZKAJA.js} +9 -3
- package/dist/chunk-FJTZKAJA.js.map +1 -0
- package/dist/chunk-G7QI5WDI.js +14 -0
- package/dist/chunk-G7QI5WDI.js.map +1 -0
- package/dist/{chunk-2YQHKXLL.js → chunk-GPZX4DSY.js} +22 -6
- package/dist/chunk-GPZX4DSY.js.map +1 -0
- package/dist/{chunk-IP3QTP5A.js → chunk-IWSMQXBL.js} +189 -48
- package/dist/chunk-IWSMQXBL.js.map +1 -0
- package/dist/{chunk-O3WEV5W3.js → chunk-JMACM7AJ.js} +47 -9
- package/dist/chunk-JMACM7AJ.js.map +1 -0
- package/dist/chunk-MSL7ROVK.js +1 -0
- package/dist/{chunk-YCYVNRLF.js → chunk-OBGEEGQ3.js} +61 -19
- package/dist/chunk-OBGEEGQ3.js.map +1 -0
- package/dist/chunk-R32Q3RGK.js +666 -0
- package/dist/chunk-R32Q3RGK.js.map +1 -0
- package/dist/{chunk-SAMTXC4A.js → chunk-TFEPHOVE.js} +12 -17
- package/dist/chunk-TFEPHOVE.js.map +1 -0
- package/dist/{chunk-QZZGIZWC.js → chunk-XSX3PGQW.js} +63 -20
- package/dist/chunk-XSX3PGQW.js.map +1 -0
- package/dist/{chunk-2MESXJEZ.js → chunk-YNRKPQLS.js} +3 -3
- package/dist/cli/setup/PreflightChecker.d.ts +1 -0
- package/dist/cli/setup/PreflightChecker.d.ts.map +1 -1
- package/dist/cli/setup/env-metadata.d.ts.map +1 -1
- package/dist/cli.js +10 -9
- package/dist/cli.js.map +1 -1
- package/dist/{config-WTRSZLOC.js → config-23TBYFP5.js} +5 -4
- package/dist/config-schema.d.ts +6 -0
- package/dist/config-schema.d.ts.map +1 -1
- package/dist/config.d.ts +6 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/{doctor-37JNBGDN.js → doctor-ZG3DO7J5.js} +3 -3
- package/dist/errors/AIExecutionError.d.ts +3 -0
- package/dist/errors/AIExecutionError.d.ts.map +1 -1
- package/dist/{errors-S3BWYA4I.js → errors-J3ZRP66W.js} +2 -2
- package/dist/events/EventBus.d.ts +1 -1
- package/dist/events/EventBus.d.ts.map +1 -1
- package/dist/i18n/locales/en.d.ts.map +1 -1
- package/dist/i18n/locales/zh-CN.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +16 -14
- package/dist/{init-QQDXGTPB.js → init-37DLQ5AJ.js} +9 -8
- package/dist/{init-QQDXGTPB.js.map → init-37DLQ5AJ.js.map} +1 -1
- package/dist/lib.js +10 -8
- package/dist/lib.js.map +1 -1
- package/dist/orchestrator/PendingDialogStore.d.ts +12 -0
- package/dist/orchestrator/PendingDialogStore.d.ts.map +1 -0
- package/dist/orchestrator/steps/FailureHandler.d.ts.map +1 -1
- package/dist/orchestrator/steps/PhaseLoopStep.d.ts.map +1 -1
- package/dist/persistence/PlanPersistence.d.ts +5 -0
- package/dist/persistence/PlanPersistence.d.ts.map +1 -1
- package/dist/persistence/TodolistExtractor.d.ts +31 -0
- package/dist/persistence/TodolistExtractor.d.ts.map +1 -0
- package/dist/phases/BasePhase.d.ts.map +1 -1
- package/dist/phases/PhaseOutcome.d.ts +2 -0
- package/dist/phases/PhaseOutcome.d.ts.map +1 -1
- package/dist/phases/PlanPhase.d.ts.map +1 -1
- package/dist/prompts/templates.d.ts +2 -2
- package/dist/prompts/templates.d.ts.map +1 -1
- package/dist/{restart-BMILTP5X.js → restart-C7QBXT44.js} +9 -8
- package/dist/{restart-BMILTP5X.js.map → restart-C7QBXT44.js.map} +1 -1
- package/dist/run.js +16 -14
- package/dist/run.js.map +1 -1
- package/dist/start-66JO56AW.js +16 -0
- package/dist/start-66JO56AW.js.map +1 -0
- package/dist/tracker/IssueTracker.d.ts +6 -0
- package/dist/tracker/IssueTracker.d.ts.map +1 -1
- package/dist/web/routes/api.d.ts.map +1 -1
- package/package.json +5 -1
- package/src/web/frontend/dist/assets/index-DJzC2saL.css +1 -0
- package/src/web/frontend/dist/assets/{index-D_oTMuJU.js → index-Mnu8M3ww.js} +57 -57
- package/src/web/frontend/dist/index.html +2 -2
- package/dist/PtyRunner-6UGI5STW.js +0 -22
- package/dist/chunk-2YQHKXLL.js.map +0 -1
- package/dist/chunk-AVGZH64A.js.map +0 -1
- package/dist/chunk-IP3QTP5A.js.map +0 -1
- package/dist/chunk-NZHKAPU6.js.map +0 -1
- package/dist/chunk-O3WEV5W3.js.map +0 -1
- package/dist/chunk-QZZGIZWC.js.map +0 -1
- package/dist/chunk-SAMTXC4A.js.map +0 -1
- package/dist/chunk-U237JSLB.js +0 -1
- package/dist/chunk-U6GWFTKA.js +0 -657
- package/dist/chunk-U6GWFTKA.js.map +0 -1
- package/dist/chunk-YCYVNRLF.js.map +0 -1
- package/dist/start-6QRW6IJI.js +0 -15
- package/src/web/frontend/dist/assets/index-COYziOhv.css +0 -1
- /package/dist/{AIRunnerRegistry-II3WWSFN.js.map → AIRunnerRegistry-CFDNWSXC.js.map} +0 -0
- /package/dist/{LockNote-Z2CLDZNN.js.map → LockNote-W2JNVMW7.js.map} +0 -0
- /package/dist/{PtyRunner-6UGI5STW.js.map → PtyRunner-NYASBTRP.js.map} +0 -0
- /package/dist/{ai-runner-HLA44WI6.js.map → SdkRunner-U2OTOMZU.js.map} +0 -0
- /package/dist/{chunk-U237JSLB.js.map → ai-runner-TOHVJJ76.js.map} +0 -0
- /package/dist/{chunk-UBQLXQ7I.js.map → chunk-5JBADEKR.js.map} +0 -0
- /package/dist/{chunk-HDFNMVRQ.js.map → chunk-DVNAH2GV.js.map} +0 -0
- /package/dist/{chunk-GXFG4JU6.js.map → chunk-EU4XFZ2T.js.map} +0 -0
- /package/dist/{config-WTRSZLOC.js.map → chunk-MSL7ROVK.js.map} +0 -0
- /package/dist/{chunk-2MESXJEZ.js.map → chunk-YNRKPQLS.js.map} +0 -0
- /package/dist/{errors-S3BWYA4I.js.map → config-23TBYFP5.js.map} +0 -0
- /package/dist/{doctor-37JNBGDN.js.map → doctor-ZG3DO7J5.js.map} +0 -0
- /package/dist/{start-6QRW6IJI.js.map → errors-J3ZRP66W.js.map} +0 -0
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
planPrompt,
|
|
18
18
|
rePlanPrompt,
|
|
19
19
|
verifyPrompt
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-GPZX4DSY.js";
|
|
21
21
|
import {
|
|
22
22
|
getProjectKnowledge
|
|
23
23
|
} from "./chunk-ACVOOHAR.js";
|
|
@@ -26,7 +26,7 @@ import {
|
|
|
26
26
|
} from "./chunk-B7TVVODN.js";
|
|
27
27
|
import {
|
|
28
28
|
t
|
|
29
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-OBGEEGQ3.js";
|
|
30
30
|
import {
|
|
31
31
|
getLocalIP
|
|
32
32
|
} from "./chunk-AKXDQH25.js";
|
|
@@ -36,8 +36,11 @@ import {
|
|
|
36
36
|
import {
|
|
37
37
|
createAIRunner,
|
|
38
38
|
getRunnerCapabilities,
|
|
39
|
+
usesDeterministicPlanCopy
|
|
40
|
+
} from "./chunk-TFEPHOVE.js";
|
|
41
|
+
import {
|
|
39
42
|
isShuttingDown
|
|
40
|
-
} from "./chunk-
|
|
43
|
+
} from "./chunk-G7QI5WDI.js";
|
|
41
44
|
import {
|
|
42
45
|
AIExecutionError,
|
|
43
46
|
GongfengApiError,
|
|
@@ -51,7 +54,7 @@ import {
|
|
|
51
54
|
PortExhaustionError,
|
|
52
55
|
ServiceShutdownError,
|
|
53
56
|
UnregisteredPhasesError
|
|
54
|
-
} from "./chunk-
|
|
57
|
+
} from "./chunk-2RWGZPNF.js";
|
|
55
58
|
import {
|
|
56
59
|
logger,
|
|
57
60
|
runWithIssueContext
|
|
@@ -1082,6 +1085,28 @@ var IssueTracker = class _IssueTracker extends BaseTracker {
|
|
|
1082
1085
|
logger5.warn("Issue marked as failed", { issueIid, error, failedAtState, attempts: record.attempts, isRetryable });
|
|
1083
1086
|
eventBus.emitTyped("issue:failed", { issueIid, error, failedAtState, record });
|
|
1084
1087
|
}
|
|
1088
|
+
/**
|
|
1089
|
+
* Mark as failed WITHOUT incrementing attempts. Used when the agent was still
|
|
1090
|
+
* actively producing output at timeout — a slow-but-progressing run should not
|
|
1091
|
+
* consume the retry budget.
|
|
1092
|
+
*/
|
|
1093
|
+
markFailedSoft(issueIid, error, failedAtState) {
|
|
1094
|
+
const record = this.collection[this.key(issueIid)];
|
|
1095
|
+
if (!record) return;
|
|
1096
|
+
record.state = "failed" /* Failed */;
|
|
1097
|
+
record.lastError = error;
|
|
1098
|
+
record.failedAtState = failedAtState;
|
|
1099
|
+
record.lastErrorRetryable = true;
|
|
1100
|
+
record.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
1101
|
+
this.save();
|
|
1102
|
+
logger5.warn("Issue marked as failed (soft \u2014 no attempt increment)", {
|
|
1103
|
+
issueIid,
|
|
1104
|
+
error,
|
|
1105
|
+
failedAtState,
|
|
1106
|
+
attempts: record.attempts
|
|
1107
|
+
});
|
|
1108
|
+
eventBus.emitTyped("issue:failed", { issueIid, error, failedAtState, record });
|
|
1109
|
+
}
|
|
1085
1110
|
pauseIssue(issueIid, currentPhase) {
|
|
1086
1111
|
const record = this.collection[this.key(issueIid)];
|
|
1087
1112
|
if (!record) return;
|
|
@@ -1593,6 +1618,31 @@ var PlanPersistence = class _PlanPersistence {
|
|
|
1593
1618
|
this.ensureDir();
|
|
1594
1619
|
fs2.writeFileSync(path2.join(this.planDir, filename), content, "utf-8");
|
|
1595
1620
|
}
|
|
1621
|
+
/**
|
|
1622
|
+
* Copy a plan file from an external source (e.g. ~/.claude/plans/) into planDir.
|
|
1623
|
+
* Returns the destination path, or null if the source is empty/unreadable.
|
|
1624
|
+
*/
|
|
1625
|
+
copyPlanFromExternal(sourcePath, targetFilename = "01-plan.md") {
|
|
1626
|
+
try {
|
|
1627
|
+
const content = fs2.readFileSync(sourcePath, "utf-8");
|
|
1628
|
+
if (content.trim().length === 0) {
|
|
1629
|
+
logger6.warn("External plan file is empty", { sourcePath });
|
|
1630
|
+
return null;
|
|
1631
|
+
}
|
|
1632
|
+
this.ensureDir();
|
|
1633
|
+
const destPath = path2.join(this.planDir, targetFilename);
|
|
1634
|
+
fs2.writeFileSync(destPath, content, "utf-8");
|
|
1635
|
+
logger6.info("Plan copied from external source", {
|
|
1636
|
+
source: sourcePath,
|
|
1637
|
+
dest: destPath,
|
|
1638
|
+
size: content.length
|
|
1639
|
+
});
|
|
1640
|
+
return destPath;
|
|
1641
|
+
} catch (err) {
|
|
1642
|
+
logger6.error("Failed to copy plan from external source", { sourcePath, err });
|
|
1643
|
+
return null;
|
|
1644
|
+
}
|
|
1645
|
+
}
|
|
1596
1646
|
};
|
|
1597
1647
|
|
|
1598
1648
|
// src/phases/BasePhase.ts
|
|
@@ -1776,7 +1826,8 @@ ${t("basePhase.rulesSection", { rules })}`;
|
|
|
1776
1826
|
error: {
|
|
1777
1827
|
message: (result.errorMessage || result.output).slice(0, 500),
|
|
1778
1828
|
isRetryable: this.classifyRetryable(result),
|
|
1779
|
-
rawOutput: result.output
|
|
1829
|
+
rawOutput: result.output,
|
|
1830
|
+
wasActiveAtTimeout: result.wasActiveAtTimeout
|
|
1780
1831
|
}
|
|
1781
1832
|
};
|
|
1782
1833
|
}
|
|
@@ -1843,6 +1894,9 @@ ${t("basePhase.rulesSection", { rules })}`;
|
|
|
1843
1894
|
workDir: this.resolveAIWorkDir(ctx),
|
|
1844
1895
|
timeoutMs: this.config.ai.phaseTimeoutMs,
|
|
1845
1896
|
idleTimeoutMs: this.config.ai.idleTimeoutMs,
|
|
1897
|
+
timeoutGraceMs: this.config.ai.timeoutGraceMs,
|
|
1898
|
+
timeoutExtensionMs: this.config.ai.timeoutExtensionMs,
|
|
1899
|
+
timeoutMaxExtensions: this.config.ai.timeoutMaxExtensions,
|
|
1846
1900
|
mode: this.getRunMode(),
|
|
1847
1901
|
phaseName: this.phaseName,
|
|
1848
1902
|
artifactCheck,
|
|
@@ -2122,6 +2176,7 @@ var PlanPhase = class extends BasePhase {
|
|
|
2122
2176
|
buildPrompt(ctx) {
|
|
2123
2177
|
const pc = demandToPromptContext(ctx.demand);
|
|
2124
2178
|
const history = this.plan.readReviewHistory();
|
|
2179
|
+
const detCopy = usesDeterministicPlanCopy(this.config.ai.mode);
|
|
2125
2180
|
const promptCtx = {
|
|
2126
2181
|
issueTitle: pc.title,
|
|
2127
2182
|
issueDescription: pc.description,
|
|
@@ -2131,13 +2186,14 @@ var PlanPhase = class extends BasePhase {
|
|
|
2131
2186
|
};
|
|
2132
2187
|
let basePrompt;
|
|
2133
2188
|
if (history.length > 0) {
|
|
2134
|
-
basePrompt = rePlanPrompt(promptCtx, history);
|
|
2189
|
+
basePrompt = rePlanPrompt(promptCtx, history, detCopy);
|
|
2135
2190
|
} else {
|
|
2136
|
-
basePrompt = planPrompt(promptCtx);
|
|
2191
|
+
basePrompt = planPrompt(promptCtx, detCopy);
|
|
2137
2192
|
}
|
|
2138
2193
|
const caps = getRunnerCapabilities(this.config.ai.mode);
|
|
2139
2194
|
if (!caps?.nativePlanMode) {
|
|
2140
|
-
|
|
2195
|
+
const preambleKey = detCopy ? "prompt.planModeNative" : "prompt.planModeFallback";
|
|
2196
|
+
basePrompt = `${t(preambleKey)}
|
|
2141
2197
|
|
|
2142
2198
|
${basePrompt}`;
|
|
2143
2199
|
}
|
|
@@ -3804,6 +3860,18 @@ function buildNoteSyncComment(phaseName, phaseLabel, docUrl, dashboardUrl, summa
|
|
|
3804
3860
|
].join("\n");
|
|
3805
3861
|
}
|
|
3806
3862
|
|
|
3863
|
+
// src/orchestrator/PendingDialogStore.ts
|
|
3864
|
+
var store = /* @__PURE__ */ new Map();
|
|
3865
|
+
function setPendingDialog(info) {
|
|
3866
|
+
store.set(info.issueIid, info);
|
|
3867
|
+
}
|
|
3868
|
+
function getPendingDialog(issueIid) {
|
|
3869
|
+
return store.get(issueIid);
|
|
3870
|
+
}
|
|
3871
|
+
function clearPendingDialog(issueIid) {
|
|
3872
|
+
store.delete(issueIid);
|
|
3873
|
+
}
|
|
3874
|
+
|
|
3807
3875
|
// src/orchestrator/steps/PhaseLoopStep.ts
|
|
3808
3876
|
var logger15 = logger.child("PhaseLoopStep");
|
|
3809
3877
|
function resolveVerifyRunner(deps) {
|
|
@@ -3878,41 +3946,95 @@ async function syncResultToIssue(phase, ctx, displayId, phaseName, deps, issueId
|
|
|
3878
3946
|
await safeComment(deps, issueId, issueProgressComment(phaseName, "completed"));
|
|
3879
3947
|
}
|
|
3880
3948
|
}
|
|
3881
|
-
function
|
|
3882
|
-
|
|
3949
|
+
function buildInputHandler(displayId, phaseName, deps) {
|
|
3950
|
+
const useAcpGate = deps.config.ai.codebuddyAcpAutoApprove === false;
|
|
3883
3951
|
return (request) => {
|
|
3884
|
-
if (request.type
|
|
3885
|
-
return
|
|
3952
|
+
if (request.type === "interactive-dialog") {
|
|
3953
|
+
return handleInteractiveDialog(displayId, phaseName, deps, request);
|
|
3886
3954
|
}
|
|
3887
|
-
|
|
3888
|
-
|
|
3889
|
-
|
|
3890
|
-
|
|
3891
|
-
deps.eventBus.emitTyped("review:requested", { issueIid: displayId });
|
|
3892
|
-
return new Promise((resolve) => {
|
|
3893
|
-
const onApproved = (payload) => {
|
|
3894
|
-
const data = payload.data;
|
|
3895
|
-
if (data.issueIid !== displayId) return;
|
|
3896
|
-
cleanup();
|
|
3897
|
-
logger15.info("ACP plan-approval approved via review gate", { issueIid: displayId });
|
|
3898
|
-
resolve("allow");
|
|
3899
|
-
};
|
|
3900
|
-
const onRejected = (payload) => {
|
|
3901
|
-
const data = payload.data;
|
|
3902
|
-
if (data.issueIid !== displayId) return;
|
|
3903
|
-
cleanup();
|
|
3904
|
-
logger15.info("ACP plan-approval rejected via review gate", { issueIid: displayId });
|
|
3905
|
-
resolve("reject");
|
|
3906
|
-
};
|
|
3907
|
-
const cleanup = () => {
|
|
3908
|
-
deps.eventBus.removeListener("review:approved", onApproved);
|
|
3909
|
-
deps.eventBus.removeListener("review:rejected", onRejected);
|
|
3910
|
-
};
|
|
3911
|
-
deps.eventBus.on("review:approved", onApproved);
|
|
3912
|
-
deps.eventBus.on("review:rejected", onRejected);
|
|
3913
|
-
});
|
|
3955
|
+
if (request.type === "plan-approval" && useAcpGate) {
|
|
3956
|
+
return handlePlanApproval(displayId, phaseName, deps);
|
|
3957
|
+
}
|
|
3958
|
+
return Promise.resolve("allow");
|
|
3914
3959
|
};
|
|
3915
3960
|
}
|
|
3961
|
+
function handlePlanApproval(displayId, phaseName, deps) {
|
|
3962
|
+
logger15.info("ACP plan-approval requested, delegating to review gate", {
|
|
3963
|
+
issueIid: displayId,
|
|
3964
|
+
phase: phaseName
|
|
3965
|
+
});
|
|
3966
|
+
deps.eventBus.emitTyped("review:requested", { issueIid: displayId });
|
|
3967
|
+
return new Promise((resolve) => {
|
|
3968
|
+
const onApproved = (payload) => {
|
|
3969
|
+
const data = payload.data;
|
|
3970
|
+
if (data.issueIid !== displayId) return;
|
|
3971
|
+
cleanup();
|
|
3972
|
+
logger15.info("ACP plan-approval approved via review gate", { issueIid: displayId });
|
|
3973
|
+
resolve("allow");
|
|
3974
|
+
};
|
|
3975
|
+
const onRejected = (payload) => {
|
|
3976
|
+
const data = payload.data;
|
|
3977
|
+
if (data.issueIid !== displayId) return;
|
|
3978
|
+
cleanup();
|
|
3979
|
+
logger15.info("ACP plan-approval rejected via review gate", { issueIid: displayId });
|
|
3980
|
+
resolve("reject");
|
|
3981
|
+
};
|
|
3982
|
+
const cleanup = () => {
|
|
3983
|
+
deps.eventBus.removeListener("review:approved", onApproved);
|
|
3984
|
+
deps.eventBus.removeListener("review:rejected", onRejected);
|
|
3985
|
+
};
|
|
3986
|
+
deps.eventBus.on("review:approved", onApproved);
|
|
3987
|
+
deps.eventBus.on("review:rejected", onRejected);
|
|
3988
|
+
});
|
|
3989
|
+
}
|
|
3990
|
+
function handleInteractiveDialog(displayId, phaseName, deps, request) {
|
|
3991
|
+
logger15.info("Interactive dialog forwarded to frontend", {
|
|
3992
|
+
issueIid: displayId,
|
|
3993
|
+
phase: phaseName,
|
|
3994
|
+
question: request.content.slice(0, 80),
|
|
3995
|
+
optionCount: request.options?.length
|
|
3996
|
+
});
|
|
3997
|
+
const options = request.options ?? [];
|
|
3998
|
+
setPendingDialog({
|
|
3999
|
+
issueIid: displayId,
|
|
4000
|
+
question: request.content,
|
|
4001
|
+
options,
|
|
4002
|
+
phase: phaseName,
|
|
4003
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
4004
|
+
});
|
|
4005
|
+
deps.eventBus.emitTyped("agent:inputRequired", {
|
|
4006
|
+
issueIid: displayId,
|
|
4007
|
+
phase: phaseName,
|
|
4008
|
+
question: request.content,
|
|
4009
|
+
options
|
|
4010
|
+
});
|
|
4011
|
+
return new Promise((resolve) => {
|
|
4012
|
+
const cleanup = () => {
|
|
4013
|
+
deps.eventBus.removeListener("agent:inputResponse", onResponse);
|
|
4014
|
+
deps.eventBus.removeListener("agent:dialogDismissed", onDismiss);
|
|
4015
|
+
};
|
|
4016
|
+
const onResponse = (payload) => {
|
|
4017
|
+
const data = payload.data;
|
|
4018
|
+
if (data.issueIid !== displayId) return;
|
|
4019
|
+
cleanup();
|
|
4020
|
+
clearPendingDialog(displayId);
|
|
4021
|
+
logger15.info("Interactive dialog response received from frontend", {
|
|
4022
|
+
issueIid: displayId,
|
|
4023
|
+
response: data.response
|
|
4024
|
+
});
|
|
4025
|
+
resolve(data.response ?? "1");
|
|
4026
|
+
};
|
|
4027
|
+
const onDismiss = (payload) => {
|
|
4028
|
+
const data = payload.data;
|
|
4029
|
+
if (data.issueIid !== displayId) return;
|
|
4030
|
+
cleanup();
|
|
4031
|
+
logger15.info("Interactive dialog dismissed by user (false positive)", { issueIid: displayId });
|
|
4032
|
+
resolve("");
|
|
4033
|
+
};
|
|
4034
|
+
deps.eventBus.on("agent:inputResponse", onResponse);
|
|
4035
|
+
deps.eventBus.on("agent:dialogDismissed", onDismiss);
|
|
4036
|
+
});
|
|
4037
|
+
}
|
|
3916
4038
|
async function safeComment(deps, issueId, message) {
|
|
3917
4039
|
try {
|
|
3918
4040
|
await deps.gongfeng.createIssueNote(issueId, message);
|
|
@@ -3941,7 +4063,7 @@ async function runPhaseWithLifecycle(phase, phaseCtx, spec, ctx, deps, wtGit, wt
|
|
|
3941
4063
|
phase: spec.name,
|
|
3942
4064
|
event
|
|
3943
4065
|
}),
|
|
3944
|
-
onInputRequired:
|
|
4066
|
+
onInputRequired: buildInputHandler(displayId, spec.name, deps)
|
|
3945
4067
|
};
|
|
3946
4068
|
const outcome = await phase.run(phaseCtx, callbacks);
|
|
3947
4069
|
if (outcome.sessionId) wtPlan.updatePhaseSessionId(spec.name, outcome.sessionId);
|
|
@@ -3961,14 +4083,20 @@ async function runPhaseWithLifecycle(phase, phaseCtx, spec, ctx, deps, wtGit, wt
|
|
|
3961
4083
|
}
|
|
3962
4084
|
const errMsg = outcome.error?.message ?? "Unknown error";
|
|
3963
4085
|
const shortErr = errMsg.slice(0, 200);
|
|
4086
|
+
const wasActive = outcome.error?.wasActiveAtTimeout ?? false;
|
|
3964
4087
|
wtPlan.updatePhaseProgress(spec.name, "failed", errMsg);
|
|
3965
4088
|
deps.tracker.updatePhaseProgress(displayId, spec.name, { status: "failed" });
|
|
3966
|
-
|
|
4089
|
+
if (wasActive) {
|
|
4090
|
+
deps.tracker.markFailedSoft(displayId, errMsg, "phase_running" /* PhaseRunning */);
|
|
4091
|
+
} else {
|
|
4092
|
+
deps.tracker.markFailed(displayId, errMsg, "phase_running" /* PhaseRunning */);
|
|
4093
|
+
}
|
|
3967
4094
|
await safeComment(deps, issue.id, issueProgressComment(spec.name, "failed", shortErr));
|
|
3968
4095
|
throw new AIExecutionError(spec.name, `Phase ${spec.name} failed: ${shortErr}`, {
|
|
3969
4096
|
output: outcome.error?.rawOutput ?? outcome.output,
|
|
3970
4097
|
exitCode: outcome.exitCode ?? 1,
|
|
3971
|
-
isRetryable: outcome.error?.isRetryable
|
|
4098
|
+
isRetryable: outcome.error?.isRetryable,
|
|
4099
|
+
wasActiveAtTimeout: wasActive
|
|
3972
4100
|
});
|
|
3973
4101
|
}
|
|
3974
4102
|
async function executePhaseLoop(ctx, deps, wtGit, wtPlan, wtGitMap) {
|
|
@@ -4185,14 +4313,20 @@ async function awaitAsyncPhase(outcome, spec, ctx, deps, wtGit, wtPlan, wtGitMap
|
|
|
4185
4313
|
}
|
|
4186
4314
|
const errMsg = finalOutcome.error?.message ?? "Unknown error";
|
|
4187
4315
|
const shortErr = errMsg.slice(0, 200);
|
|
4316
|
+
const wasActive = finalOutcome.error?.wasActiveAtTimeout ?? false;
|
|
4188
4317
|
wtPlan.updatePhaseProgress(spec.name, "failed", errMsg);
|
|
4189
4318
|
deps.tracker.updatePhaseProgress(displayId, spec.name, { status: "failed" });
|
|
4190
|
-
|
|
4319
|
+
if (wasActive) {
|
|
4320
|
+
deps.tracker.markFailedSoft(displayId, errMsg, "phase_running" /* PhaseRunning */);
|
|
4321
|
+
} else {
|
|
4322
|
+
deps.tracker.markFailed(displayId, errMsg, "phase_running" /* PhaseRunning */);
|
|
4323
|
+
}
|
|
4191
4324
|
await safeComment(deps, issue.id, issueProgressComment(spec.name, "failed", shortErr));
|
|
4192
4325
|
throw new AIExecutionError(spec.name, `Phase ${spec.name} failed: ${shortErr}`, {
|
|
4193
4326
|
output: finalOutcome.error?.rawOutput ?? finalOutcome.output,
|
|
4194
4327
|
exitCode: finalOutcome.exitCode ?? 1,
|
|
4195
|
-
isRetryable: finalOutcome.error?.isRetryable
|
|
4328
|
+
isRetryable: finalOutcome.error?.isRetryable,
|
|
4329
|
+
wasActiveAtTimeout: wasActive
|
|
4196
4330
|
});
|
|
4197
4331
|
}
|
|
4198
4332
|
function findPreviousAiPhaseIndex(phases, currentIdx) {
|
|
@@ -4417,13 +4551,18 @@ var logger17 = logger.child("FailureHandler");
|
|
|
4417
4551
|
async function handleFailure(err, issue, wtCtx, deps) {
|
|
4418
4552
|
const errorMsg = err.message;
|
|
4419
4553
|
const isRetryable = err instanceof AIExecutionError ? err.isRetryable : true;
|
|
4420
|
-
|
|
4554
|
+
const wasActiveAtTimeout = err instanceof AIExecutionError && err.wasActiveAtTimeout;
|
|
4555
|
+
logger17.error("Issue processing failed", { iid: issue.iid, error: errorMsg, isRetryable, wasActiveAtTimeout });
|
|
4421
4556
|
metrics.incCounter("iaf_issues_failed_total");
|
|
4422
4557
|
const currentRecord = deps.tracker.get(issue.iid);
|
|
4423
4558
|
const failedAtState = currentRecord?.state || "pending" /* Pending */;
|
|
4424
4559
|
const wasReset = failedAtState === "pending" /* Pending */ && currentRecord?.attempts === 0;
|
|
4425
4560
|
if (failedAtState !== "failed" /* Failed */ && !wasReset) {
|
|
4426
|
-
|
|
4561
|
+
if (wasActiveAtTimeout) {
|
|
4562
|
+
deps.tracker.markFailedSoft(issue.iid, errorMsg.slice(0, 500), failedAtState);
|
|
4563
|
+
} else {
|
|
4564
|
+
deps.tracker.markFailed(issue.iid, errorMsg.slice(0, 500), failedAtState, isRetryable);
|
|
4565
|
+
}
|
|
4427
4566
|
}
|
|
4428
4567
|
if (wasReset) {
|
|
4429
4568
|
logger17.info("Issue was reset during processing, skipping failure marking", { iid: issue.iid });
|
|
@@ -5363,7 +5502,7 @@ E2E \u6D4B\u8BD5\u5C06\u5C1D\u8BD5\u4F7F\u7528 config.json \u4E2D\u7684\u9ED8\u8
|
|
|
5363
5502
|
const verifyOutcome = await verifyPhase.run(verifyCtx);
|
|
5364
5503
|
if (verifyOutcome.status === "failed") {
|
|
5365
5504
|
const errMsg = verifyOutcome.error?.message ?? "Verification failed after conflict resolution";
|
|
5366
|
-
throw new (await import("./errors-
|
|
5505
|
+
throw new (await import("./errors-J3ZRP66W.js")).AIExecutionError("verify", errMsg, {
|
|
5367
5506
|
output: verifyOutcome.error?.rawOutput ?? verifyOutcome.output,
|
|
5368
5507
|
exitCode: verifyOutcome.exitCode ?? 1
|
|
5369
5508
|
});
|
|
@@ -5674,7 +5813,9 @@ export {
|
|
|
5674
5813
|
getNoteSyncEnabled,
|
|
5675
5814
|
setNoteSyncOverride,
|
|
5676
5815
|
isNoteSyncEnabledForIssue,
|
|
5816
|
+
getPendingDialog,
|
|
5817
|
+
clearPendingDialog,
|
|
5677
5818
|
PipelineOrchestrator,
|
|
5678
5819
|
BrainstormService
|
|
5679
5820
|
};
|
|
5680
|
-
//# sourceMappingURL=chunk-
|
|
5821
|
+
//# sourceMappingURL=chunk-IWSMQXBL.js.map
|