issue-flow 0.17.0 → 0.19.1
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 +34 -100
- package/dist/agent-EWKA7357.js +32 -0
- package/dist/{analyze-6M3KEOX7.js → analyze-Z7ODC27F.js} +42 -41
- package/dist/analyze-Z7ODC27F.js.map +1 -0
- package/dist/{apply-ADB3ZK7W.js → apply-VNSWQS6O.js} +22 -24
- package/dist/apply-VNSWQS6O.js.map +1 -0
- package/dist/artifacts-AMJQJFFV.js +82 -0
- package/dist/artifacts-AMJQJFFV.js.map +1 -0
- package/dist/{bench-FM7I7EIV.js → bench-ZJEIACUK.js} +42 -42
- package/dist/{chunk-RYOUZ6EK.js → chunk-23VHVVKW.js} +3 -3
- package/dist/chunk-2EYLOS5I.js +99 -0
- package/dist/chunk-2EYLOS5I.js.map +1 -0
- package/dist/{chunk-ANI2NTR4.js → chunk-2EZW4X57.js} +28 -25
- package/dist/chunk-2EZW4X57.js.map +1 -0
- package/dist/{chunk-E6KXCV3T.js → chunk-2Q6PG3MT.js} +15 -15
- package/dist/chunk-2Q6PG3MT.js.map +1 -0
- package/dist/{chunk-C5TL7T4V.js → chunk-2YM2VH6R.js} +2 -2
- package/dist/{chunk-LPWPFIIB.js → chunk-2YYP7AE6.js} +14 -16
- package/dist/{chunk-LPWPFIIB.js.map → chunk-2YYP7AE6.js.map} +1 -1
- package/dist/chunk-3JD25HHJ.js +278 -0
- package/dist/chunk-3JD25HHJ.js.map +1 -0
- package/dist/{chunk-ISZ54SVE.js → chunk-46S7APLQ.js} +41 -17
- package/dist/chunk-46S7APLQ.js.map +1 -0
- package/dist/chunk-6AOZCWN2.js +21 -0
- package/dist/chunk-6AOZCWN2.js.map +1 -0
- package/dist/{chunk-QPGEFLMY.js → chunk-7CMVL4X6.js} +7 -7
- package/dist/chunk-7MJGYPHF.js +1571 -0
- package/dist/chunk-7MJGYPHF.js.map +1 -0
- package/dist/chunk-7ZZUSMBJ.js +35 -0
- package/dist/chunk-7ZZUSMBJ.js.map +1 -0
- package/dist/{chunk-DUS5ZNKL.js → chunk-DIMDAYZS.js} +7 -6
- package/dist/{chunk-DGRTJD5R.js → chunk-DXH4TQRB.js} +7 -7
- package/dist/{chunk-CRGIQFUQ.js → chunk-E2H3JV2E.js} +3 -1
- package/dist/chunk-E2H3JV2E.js.map +1 -0
- package/dist/{chunk-YUNBOUQH.js → chunk-ERAG5IQB.js} +8 -8
- package/dist/{chunk-D6ZBGJ3L.js → chunk-F2NFJ27Z.js} +130 -36
- package/dist/chunk-F2NFJ27Z.js.map +1 -0
- package/dist/{chunk-SOM4QA6C.js → chunk-GD7JZMSJ.js} +93 -18
- package/dist/chunk-GD7JZMSJ.js.map +1 -0
- package/dist/{chunk-YII4U7ZD.js → chunk-HEHHQU4G.js} +70 -81
- package/dist/chunk-HEHHQU4G.js.map +1 -0
- package/dist/{chunk-KZ5EY5XX.js → chunk-HHXWAWU6.js} +159 -114
- package/dist/chunk-HHXWAWU6.js.map +1 -0
- package/dist/{chunk-SGTTR4XW.js → chunk-HWWB22HC.js} +152 -100
- package/dist/chunk-HWWB22HC.js.map +1 -0
- package/dist/chunk-IMB6FA2F.js +673 -0
- package/dist/chunk-IMB6FA2F.js.map +1 -0
- package/dist/{chunk-6YQT3SSM.js → chunk-IQYXXFRC.js} +22 -6
- package/dist/chunk-IQYXXFRC.js.map +1 -0
- package/dist/chunk-J6VJ5M2U.js +1201 -0
- package/dist/chunk-J6VJ5M2U.js.map +1 -0
- package/dist/{chunk-B3TSS7BT.js → chunk-KDQRNVBZ.js} +3 -3
- package/dist/{chunk-A4H7P7T7.js → chunk-LRWIP7QS.js} +41 -26
- package/dist/chunk-LRWIP7QS.js.map +1 -0
- package/dist/{chunk-DV7HUC4Z.js → chunk-LYC57OXF.js} +20 -117
- package/dist/chunk-LYC57OXF.js.map +1 -0
- package/dist/{chunk-HAKDLR6N.js → chunk-MAJ6QDRL.js} +65 -78
- package/dist/chunk-MAJ6QDRL.js.map +1 -0
- package/dist/{chunk-HJBF4WD2.js → chunk-MHA7Q3KU.js} +288 -108
- package/dist/chunk-MHA7Q3KU.js.map +1 -0
- package/dist/{chunk-UK4E2FUA.js → chunk-MQTVMB7W.js} +103 -76
- package/dist/chunk-MQTVMB7W.js.map +1 -0
- package/dist/chunk-NP47HRX2.js +136 -0
- package/dist/chunk-NP47HRX2.js.map +1 -0
- package/dist/{chunk-MI5TREN3.js → chunk-NYDAHE3Y.js} +52 -46
- package/dist/chunk-NYDAHE3Y.js.map +1 -0
- package/dist/{chunk-UWDCIFTP.js → chunk-P7ZYOC23.js} +41 -57
- package/dist/chunk-P7ZYOC23.js.map +1 -0
- package/dist/{chunk-3R27MJ5R.js → chunk-PFWHHYEO.js} +3 -3
- package/dist/{chunk-2SUFAE6X.js → chunk-PHPAK2L6.js} +44 -33
- package/dist/{chunk-2SUFAE6X.js.map → chunk-PHPAK2L6.js.map} +1 -1
- package/dist/{chunk-PPZ3K4YM.js → chunk-PRGPSNGA.js} +2 -2
- package/dist/{chunk-32JSYXEK.js → chunk-RGFMQFX7.js} +9 -23
- package/dist/{chunk-32JSYXEK.js.map → chunk-RGFMQFX7.js.map} +1 -1
- package/dist/{chunk-YVPZUN6X.js → chunk-TJVX42KY.js} +335 -38
- package/dist/chunk-TJVX42KY.js.map +1 -0
- package/dist/{chunk-RCZJQUTC.js → chunk-UDRAD7MF.js} +60 -27
- package/dist/chunk-UDRAD7MF.js.map +1 -0
- package/dist/{chunk-HY5HLFDU.js → chunk-UHDXXLYH.js} +148 -135
- package/dist/chunk-UHDXXLYH.js.map +1 -0
- package/dist/{chunk-RNFUVKC3.js → chunk-UPAAZU4W.js} +30 -13
- package/dist/chunk-UPAAZU4W.js.map +1 -0
- package/dist/{chunk-L6HSKTQE.js → chunk-W7LZLJAF.js} +4 -4
- package/dist/{chunk-HLAPOUEM.js → chunk-WB2FVIUS.js} +44 -12
- package/dist/chunk-WB2FVIUS.js.map +1 -0
- package/dist/{chunk-VE3IYNDN.js → chunk-WPHC6JBR.js} +9 -9
- package/dist/chunk-WPHC6JBR.js.map +1 -0
- package/dist/{chunk-KZXQWC7U.js → chunk-XHCP6ZNO.js} +201 -64
- package/dist/chunk-XHCP6ZNO.js.map +1 -0
- package/dist/{chunk-7F7LGMVO.js → chunk-XKR3VD2Z.js} +12 -12
- package/dist/{chunk-7F7LGMVO.js.map → chunk-XKR3VD2Z.js.map} +1 -1
- package/dist/{chunk-ICM463EO.js → chunk-XNK5UN2D.js} +5 -649
- package/dist/chunk-XNK5UN2D.js.map +1 -0
- package/dist/{chunk-Z5O2XBWA.js → chunk-XQLNZW7I.js} +40 -30
- package/dist/chunk-XQLNZW7I.js.map +1 -0
- package/dist/{chunk-QMIQR7EE.js → chunk-ZAYATXJD.js} +32 -316
- package/dist/chunk-ZAYATXJD.js.map +1 -0
- package/dist/cli.js +128 -60
- package/dist/cli.js.map +1 -1
- package/dist/compat-YPDZB34U.js +24 -0
- package/dist/{config-KGZUPAUP.js → config-56B4OHZE.js} +20 -17
- package/dist/{contract-JH2WBIO6.js → contract-HWLFFL3F.js} +2 -2
- package/dist/{conventions-RYN7OXJN.js → conventions-DW2CM5I3.js} +20 -16
- package/dist/{conventions-RYN7OXJN.js.map → conventions-DW2CM5I3.js.map} +1 -1
- package/dist/db-5NU77PJA.js +264 -0
- package/dist/db-5NU77PJA.js.map +1 -0
- package/dist/diagnostics-UCTS2VUF.js +25 -0
- package/dist/execute-R7AVOLNG.js +38 -0
- package/dist/{generate-CX6KNHZS.js → generate-O7GUXLN4.js} +46 -43
- package/dist/generate-O7GUXLN4.js.map +1 -0
- package/dist/{git-A2IP32PQ.js → git-LCG45YXD.js} +2 -3
- package/dist/history-6GSURU3H.js +101 -0
- package/dist/history-6GSURU3H.js.map +1 -0
- package/dist/init-DD6DBRC5.js +28 -0
- package/dist/{operations-CAKIT2BO.js → operations-HU5ZFEBA.js} +78 -52
- package/dist/operations-HU5ZFEBA.js.map +1 -0
- package/dist/{permissions-G4XCAESF.js → permissions-NNNSRC4P.js} +5 -6
- package/dist/plan-XR6B7EM3.js +38 -0
- package/dist/{policy-WX6O2JID.js → policy-RFJOJQL6.js} +17 -15
- package/dist/{policy-WX6O2JID.js.map → policy-RFJOJQL6.js.map} +1 -1
- package/dist/pr-OSCNJCOO.js +42 -0
- package/dist/pr-review-IKIYHFBO.js +33 -0
- package/dist/prd-HFDZJJQR.js +37 -0
- package/dist/{ps-76L6ZAZL.js → ps-AKRHGPSR.js} +26 -15
- package/dist/ps-AKRHGPSR.js.map +1 -0
- package/dist/{recorder-N7U66HCO.js → recorder-T7426CKV.js} +11 -7
- package/dist/registry-DWRKD65A.js +17 -0
- package/dist/repository-TABBRW2C.js +80 -0
- package/dist/resume-GDXKK5XP.js +278 -0
- package/dist/resume-GDXKK5XP.js.map +1 -0
- package/dist/review-JJHMQA2O.js +38 -0
- package/dist/routing-FPNUVE7T.js +35 -0
- package/dist/run-RLCURLLL.js +61 -0
- package/dist/{session-publisher-KAJQRHNZ.js → session-publisher-Q5TNEZPX.js} +3 -3
- package/dist/session-publisher-Q5TNEZPX.js.map +1 -0
- package/dist/{state-manager-UPHO2EA2.js → state-manager-IGNTD4AB.js} +9 -4
- package/dist/state-manager-IGNTD4AB.js.map +1 -0
- package/dist/{usage-U7QNGCPK.js → usage-XW27AL5K.js} +69 -63
- package/dist/usage-XW27AL5K.js.map +1 -0
- package/dist/web-NCDBVZ5Y.js +205 -0
- package/dist/web-NCDBVZ5Y.js.map +1 -0
- package/package.json +20 -7
- package/prompts/analyze.md +16 -19
- package/prompts/execute.md +73 -144
- package/prompts/generate.md +23 -10
- package/prompts/plan.md +32 -60
- package/prompts/pr-review.md +58 -40
- package/prompts/pr.md +50 -16
- package/prompts/prd.md +26 -19
- package/prompts/review.md +41 -18
- package/web/AGENTS.md +115 -7
- package/web/public/app.css +393 -245
- package/web/public/app.js +212 -143
- package/web/public/index.html +106 -78
- package/dist/agent-TB6W7PT7.js +0 -30
- package/dist/analyze-6M3KEOX7.js.map +0 -1
- package/dist/apply-ADB3ZK7W.js.map +0 -1
- package/dist/chunk-6YQT3SSM.js.map +0 -1
- package/dist/chunk-A4H7P7T7.js.map +0 -1
- package/dist/chunk-ANI2NTR4.js.map +0 -1
- package/dist/chunk-CRGIQFUQ.js.map +0 -1
- package/dist/chunk-D6ZBGJ3L.js.map +0 -1
- package/dist/chunk-DV7HUC4Z.js.map +0 -1
- package/dist/chunk-E6KXCV3T.js.map +0 -1
- package/dist/chunk-HAKDLR6N.js.map +0 -1
- package/dist/chunk-HJBF4WD2.js.map +0 -1
- package/dist/chunk-HLAPOUEM.js.map +0 -1
- package/dist/chunk-HY5HLFDU.js.map +0 -1
- package/dist/chunk-ICM463EO.js.map +0 -1
- package/dist/chunk-ISZ54SVE.js.map +0 -1
- package/dist/chunk-KZ5EY5XX.js.map +0 -1
- package/dist/chunk-KZXQWC7U.js.map +0 -1
- package/dist/chunk-MI5TREN3.js.map +0 -1
- package/dist/chunk-QMIQR7EE.js.map +0 -1
- package/dist/chunk-RCZJQUTC.js.map +0 -1
- package/dist/chunk-RNFUVKC3.js.map +0 -1
- package/dist/chunk-SGTTR4XW.js.map +0 -1
- package/dist/chunk-SOM4QA6C.js.map +0 -1
- package/dist/chunk-UK4E2FUA.js.map +0 -1
- package/dist/chunk-UWDCIFTP.js.map +0 -1
- package/dist/chunk-VE3IYNDN.js.map +0 -1
- package/dist/chunk-WCCZJL7W.js +0 -141
- package/dist/chunk-WCCZJL7W.js.map +0 -1
- package/dist/chunk-XEYH6ZZI.js +0 -289
- package/dist/chunk-XEYH6ZZI.js.map +0 -1
- package/dist/chunk-XZUEFTUP.js +0 -243
- package/dist/chunk-XZUEFTUP.js.map +0 -1
- package/dist/chunk-YII4U7ZD.js.map +0 -1
- package/dist/chunk-YVPZUN6X.js.map +0 -1
- package/dist/chunk-Z5O2XBWA.js.map +0 -1
- package/dist/diagnostics-HTCWF7F4.js +0 -23
- package/dist/execute-QL3ZQIAP.js +0 -37
- package/dist/generate-CX6KNHZS.js.map +0 -1
- package/dist/init-PDVQDRS6.js +0 -24
- package/dist/operations-CAKIT2BO.js.map +0 -1
- package/dist/plan-PRORGS3L.js +0 -34
- package/dist/pr-27RMQI5F.js +0 -39
- package/dist/pr-review-VNESMAMT.js +0 -32
- package/dist/prd-ZNC4T5BS.js +0 -33
- package/dist/ps-76L6ZAZL.js.map +0 -1
- package/dist/registry-XLHHYLTR.js +0 -15
- package/dist/resume-VLWIE264.js +0 -244
- package/dist/resume-VLWIE264.js.map +0 -1
- package/dist/review-7CREJDKB.js +0 -35
- package/dist/routing-VCDYHSXA.js +0 -33
- package/dist/run-3MPORLF5.js +0 -56
- package/dist/usage-U7QNGCPK.js.map +0 -1
- package/dist/web-HUNDHCJ4.js +0 -172
- package/dist/web-HUNDHCJ4.js.map +0 -1
- /package/dist/{agent-TB6W7PT7.js.map → agent-EWKA7357.js.map} +0 -0
- /package/dist/{bench-FM7I7EIV.js.map → bench-ZJEIACUK.js.map} +0 -0
- /package/dist/{chunk-RYOUZ6EK.js.map → chunk-23VHVVKW.js.map} +0 -0
- /package/dist/{chunk-C5TL7T4V.js.map → chunk-2YM2VH6R.js.map} +0 -0
- /package/dist/{chunk-QPGEFLMY.js.map → chunk-7CMVL4X6.js.map} +0 -0
- /package/dist/{chunk-DUS5ZNKL.js.map → chunk-DIMDAYZS.js.map} +0 -0
- /package/dist/{chunk-DGRTJD5R.js.map → chunk-DXH4TQRB.js.map} +0 -0
- /package/dist/{chunk-YUNBOUQH.js.map → chunk-ERAG5IQB.js.map} +0 -0
- /package/dist/{chunk-B3TSS7BT.js.map → chunk-KDQRNVBZ.js.map} +0 -0
- /package/dist/{chunk-3R27MJ5R.js.map → chunk-PFWHHYEO.js.map} +0 -0
- /package/dist/{chunk-PPZ3K4YM.js.map → chunk-PRGPSNGA.js.map} +0 -0
- /package/dist/{chunk-L6HSKTQE.js.map → chunk-W7LZLJAF.js.map} +0 -0
- /package/dist/{config-KGZUPAUP.js.map → compat-YPDZB34U.js.map} +0 -0
- /package/dist/{contract-JH2WBIO6.js.map → config-56B4OHZE.js.map} +0 -0
- /package/dist/{diagnostics-HTCWF7F4.js.map → contract-HWLFFL3F.js.map} +0 -0
- /package/dist/{execute-QL3ZQIAP.js.map → diagnostics-UCTS2VUF.js.map} +0 -0
- /package/dist/{git-A2IP32PQ.js.map → execute-R7AVOLNG.js.map} +0 -0
- /package/dist/{init-PDVQDRS6.js.map → git-LCG45YXD.js.map} +0 -0
- /package/dist/{permissions-G4XCAESF.js.map → init-DD6DBRC5.js.map} +0 -0
- /package/dist/{plan-PRORGS3L.js.map → permissions-NNNSRC4P.js.map} +0 -0
- /package/dist/{pr-27RMQI5F.js.map → plan-XR6B7EM3.js.map} +0 -0
- /package/dist/{pr-review-VNESMAMT.js.map → pr-OSCNJCOO.js.map} +0 -0
- /package/dist/{prd-ZNC4T5BS.js.map → pr-review-IKIYHFBO.js.map} +0 -0
- /package/dist/{recorder-N7U66HCO.js.map → prd-HFDZJJQR.js.map} +0 -0
- /package/dist/{registry-XLHHYLTR.js.map → recorder-T7426CKV.js.map} +0 -0
- /package/dist/{review-7CREJDKB.js.map → registry-DWRKD65A.js.map} +0 -0
- /package/dist/{routing-VCDYHSXA.js.map → repository-TABBRW2C.js.map} +0 -0
- /package/dist/{run-3MPORLF5.js.map → review-JJHMQA2O.js.map} +0 -0
- /package/dist/{session-publisher-KAJQRHNZ.js.map → routing-FPNUVE7T.js.map} +0 -0
- /package/dist/{state-manager-UPHO2EA2.js.map → run-RLCURLLL.js.map} +0 -0
package/dist/chunk-XEYH6ZZI.js
DELETED
|
@@ -1,289 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
// src/resilience/errors.ts
|
|
4
|
-
var RETRYABLE_KINDS = /* @__PURE__ */ new Set([
|
|
5
|
-
"network",
|
|
6
|
-
"timeout",
|
|
7
|
-
"stalled",
|
|
8
|
-
"rate_limit",
|
|
9
|
-
"provider_down",
|
|
10
|
-
"provider_crash"
|
|
11
|
-
]);
|
|
12
|
-
var HUMAN_ACTION_KINDS = /* @__PURE__ */ new Set([
|
|
13
|
-
"authentication",
|
|
14
|
-
"configuration",
|
|
15
|
-
"repository_state",
|
|
16
|
-
"task_execution"
|
|
17
|
-
]);
|
|
18
|
-
function isRetryableKind(kind) {
|
|
19
|
-
return RETRYABLE_KINDS.has(kind);
|
|
20
|
-
}
|
|
21
|
-
function requiresHumanAction(kind) {
|
|
22
|
-
return HUMAN_ACTION_KINDS.has(kind);
|
|
23
|
-
}
|
|
24
|
-
var ClassifiedError = class extends Error {
|
|
25
|
-
failure;
|
|
26
|
-
action;
|
|
27
|
-
constructor(message, failure, action) {
|
|
28
|
-
super(message);
|
|
29
|
-
this.name = "ClassifiedError";
|
|
30
|
-
this.failure = failure;
|
|
31
|
-
this.action = action;
|
|
32
|
-
}
|
|
33
|
-
};
|
|
34
|
-
function failureOf(error) {
|
|
35
|
-
return error instanceof ClassifiedError ? error.failure : null;
|
|
36
|
-
}
|
|
37
|
-
function actionOf(error) {
|
|
38
|
-
return error instanceof ClassifiedError ? error.action ?? null : null;
|
|
39
|
-
}
|
|
40
|
-
var ERRNO_KINDS = {
|
|
41
|
-
ENOTFOUND: "network",
|
|
42
|
-
EAI_AGAIN: "network",
|
|
43
|
-
ECONNRESET: "network",
|
|
44
|
-
ECONNREFUSED: "network",
|
|
45
|
-
ECONNABORTED: "network",
|
|
46
|
-
EHOSTUNREACH: "network",
|
|
47
|
-
ENETUNREACH: "network",
|
|
48
|
-
ENETDOWN: "network",
|
|
49
|
-
EPIPE: "network",
|
|
50
|
-
ETIMEDOUT: "timeout",
|
|
51
|
-
ENOENT: "configuration",
|
|
52
|
-
EACCES: "configuration",
|
|
53
|
-
EPERM: "configuration"
|
|
54
|
-
};
|
|
55
|
-
function kindFromErrno(errno) {
|
|
56
|
-
if (!errno) return void 0;
|
|
57
|
-
return ERRNO_KINDS[errno.toUpperCase()];
|
|
58
|
-
}
|
|
59
|
-
function kindFromHttpStatus(status, lowered) {
|
|
60
|
-
if (status === void 0 || status < 400) return void 0;
|
|
61
|
-
if (status === 429) return "rate_limit";
|
|
62
|
-
if (status === 401) return "authentication";
|
|
63
|
-
if (status === 403)
|
|
64
|
-
return matchesAny(lowered, RATE_LIMIT_PATTERNS) ? "rate_limit" : "authentication";
|
|
65
|
-
if (status === 408) return "timeout";
|
|
66
|
-
if (status >= 500) return "provider_down";
|
|
67
|
-
return "configuration";
|
|
68
|
-
}
|
|
69
|
-
var CRASH_SIGNALS = /* @__PURE__ */ new Set(["SIGKILL", "SIGABRT", "SIGSEGV", "SIGBUS"]);
|
|
70
|
-
function kindFromTermination(signal) {
|
|
71
|
-
if (signal.stalled === true) return "stalled";
|
|
72
|
-
if (signal.timedOut === true) return "timeout";
|
|
73
|
-
const name = signal.signal?.toUpperCase();
|
|
74
|
-
if (!name) return void 0;
|
|
75
|
-
if (name === "SIGTERM") return "timeout";
|
|
76
|
-
if (CRASH_SIGNALS.has(name)) return "provider_crash";
|
|
77
|
-
return void 0;
|
|
78
|
-
}
|
|
79
|
-
var EXIT_CODE_KINDS = {
|
|
80
|
-
75: "provider_down",
|
|
81
|
-
// EX_TEMPFAIL
|
|
82
|
-
126: "configuration",
|
|
83
|
-
// found, not executable
|
|
84
|
-
127: "configuration",
|
|
85
|
-
// command not found
|
|
86
|
-
137: "provider_crash",
|
|
87
|
-
// 128 + SIGKILL, typically the OOM killer
|
|
88
|
-
139: "provider_crash"
|
|
89
|
-
// 128 + SIGSEGV
|
|
90
|
-
};
|
|
91
|
-
function kindFromExitCode(exitCode) {
|
|
92
|
-
if (exitCode === null || exitCode === void 0) return void 0;
|
|
93
|
-
return EXIT_CODE_KINDS[exitCode];
|
|
94
|
-
}
|
|
95
|
-
var RATE_LIMIT_PATTERNS = [
|
|
96
|
-
"rate limit",
|
|
97
|
-
"rate-limit",
|
|
98
|
-
"ratelimit",
|
|
99
|
-
"too many requests",
|
|
100
|
-
"http 429"
|
|
101
|
-
];
|
|
102
|
-
var TEXT_RULES = [
|
|
103
|
-
{ kind: "rate_limit", patterns: RATE_LIMIT_PATTERNS },
|
|
104
|
-
{
|
|
105
|
-
kind: "authentication",
|
|
106
|
-
patterns: [
|
|
107
|
-
"authentication failed",
|
|
108
|
-
"authentication_error",
|
|
109
|
-
"gh auth login",
|
|
110
|
-
"not logged into",
|
|
111
|
-
"bad credentials",
|
|
112
|
-
"invalid api key",
|
|
113
|
-
"invalid_api_key",
|
|
114
|
-
"token expired",
|
|
115
|
-
"expired token",
|
|
116
|
-
"unauthorized",
|
|
117
|
-
"http 401",
|
|
118
|
-
"http 403"
|
|
119
|
-
]
|
|
120
|
-
},
|
|
121
|
-
{
|
|
122
|
-
kind: "network",
|
|
123
|
-
patterns: [
|
|
124
|
-
"connection reset",
|
|
125
|
-
"connection refused",
|
|
126
|
-
"connection aborted",
|
|
127
|
-
"network error",
|
|
128
|
-
"network unavailable",
|
|
129
|
-
"temporary failure",
|
|
130
|
-
"econnreset",
|
|
131
|
-
"econnrefused",
|
|
132
|
-
"enotfound",
|
|
133
|
-
"eai_again",
|
|
134
|
-
"socket hang up",
|
|
135
|
-
// What Go prints, and therefore what `gh` prints: its network errors
|
|
136
|
-
// never mention "connection reset", they mention the resolver.
|
|
137
|
-
"no such host",
|
|
138
|
-
"dial tcp",
|
|
139
|
-
"i/o timeout",
|
|
140
|
-
"tls handshake timeout",
|
|
141
|
-
"server misbehaving",
|
|
142
|
-
"error connecting to"
|
|
143
|
-
]
|
|
144
|
-
},
|
|
145
|
-
// Before the timeout rule: a stall *is* a kind of timeout, and the specific
|
|
146
|
-
// reading is the useful one — it has its own budget and its own escalation.
|
|
147
|
-
{ kind: "stalled", patterns: ["produced no output for", "(stalled)"] },
|
|
148
|
-
{ kind: "timeout", patterns: ["timed out", "timeout", "etimedout"] },
|
|
149
|
-
{
|
|
150
|
-
kind: "provider_down",
|
|
151
|
-
patterns: [
|
|
152
|
-
"service unavailable",
|
|
153
|
-
"temporarily unavailable",
|
|
154
|
-
"overloaded",
|
|
155
|
-
"bad gateway",
|
|
156
|
-
"gateway timeout",
|
|
157
|
-
"internal server error",
|
|
158
|
-
"http 500",
|
|
159
|
-
"http 502",
|
|
160
|
-
"http 503",
|
|
161
|
-
"http 504"
|
|
162
|
-
]
|
|
163
|
-
},
|
|
164
|
-
{
|
|
165
|
-
kind: "provider_crash",
|
|
166
|
-
patterns: ["segmentation fault", "core dumped", "out of memory", "killed by signal"]
|
|
167
|
-
},
|
|
168
|
-
{
|
|
169
|
-
kind: "repository_state",
|
|
170
|
-
patterns: [
|
|
171
|
-
"unmerged paths",
|
|
172
|
-
"needs merge",
|
|
173
|
-
"automatic merge failed",
|
|
174
|
-
"rebase in progress",
|
|
175
|
-
"you are in the middle of",
|
|
176
|
-
"cherry-pick is in progress",
|
|
177
|
-
"not a git repository"
|
|
178
|
-
]
|
|
179
|
-
},
|
|
180
|
-
{
|
|
181
|
-
kind: "configuration",
|
|
182
|
-
patterns: [
|
|
183
|
-
"command not found",
|
|
184
|
-
"unknown flag",
|
|
185
|
-
"unknown option",
|
|
186
|
-
"no such file or directory",
|
|
187
|
-
"permission check failed",
|
|
188
|
-
"user denied permission",
|
|
189
|
-
"waiting for human input",
|
|
190
|
-
"status: waiting",
|
|
191
|
-
"below the minimum",
|
|
192
|
-
"prompt exceeds",
|
|
193
|
-
"nativetimeout",
|
|
194
|
-
"agy is not installed"
|
|
195
|
-
]
|
|
196
|
-
},
|
|
197
|
-
{
|
|
198
|
-
kind: "task_execution",
|
|
199
|
-
patterns: [
|
|
200
|
-
"test failed",
|
|
201
|
-
"tests failed",
|
|
202
|
-
"failed tests",
|
|
203
|
-
"failing test",
|
|
204
|
-
"assertion failed",
|
|
205
|
-
"assertionerror",
|
|
206
|
-
"expect(received)",
|
|
207
|
-
"typecheck failed",
|
|
208
|
-
"npm err! test failed",
|
|
209
|
-
"lint failed",
|
|
210
|
-
"build failed",
|
|
211
|
-
"compilation failed",
|
|
212
|
-
"syntaxerror",
|
|
213
|
-
"typeerror",
|
|
214
|
-
"referenceerror",
|
|
215
|
-
// What a runner actually prints: "Tests 3 failed | 41 passed",
|
|
216
|
-
// "Test Files 1 failed (12)", "Tests: 2 failed, 8 total".
|
|
217
|
-
/\b\d+\s+failed\b/
|
|
218
|
-
]
|
|
219
|
-
}
|
|
220
|
-
];
|
|
221
|
-
function matchesAny(lowered, patterns) {
|
|
222
|
-
return patterns.some(
|
|
223
|
-
(pattern) => typeof pattern === "string" ? lowered.includes(pattern) : pattern.test(lowered)
|
|
224
|
-
);
|
|
225
|
-
}
|
|
226
|
-
function kindFromText(lowered) {
|
|
227
|
-
if (!lowered) return void 0;
|
|
228
|
-
for (const rule of TEXT_RULES) {
|
|
229
|
-
if (matchesAny(lowered, rule.patterns)) return rule.kind;
|
|
230
|
-
}
|
|
231
|
-
return void 0;
|
|
232
|
-
}
|
|
233
|
-
var RETRY_AFTER_IN_TEXT = /retry[\s-]?after:?\s*(\d+)/i;
|
|
234
|
-
function parseRetryAfter(value, now) {
|
|
235
|
-
if (value === void 0) return void 0;
|
|
236
|
-
if (typeof value === "number")
|
|
237
|
-
return Number.isFinite(value) && value >= 0 ? value * 1e3 : void 0;
|
|
238
|
-
const trimmed = value.trim();
|
|
239
|
-
if (trimmed === "") return void 0;
|
|
240
|
-
if (/^\d+$/.test(trimmed)) return Number(trimmed) * 1e3;
|
|
241
|
-
const at = Date.parse(trimmed);
|
|
242
|
-
if (Number.isNaN(at)) return void 0;
|
|
243
|
-
return at > now ? at - now : void 0;
|
|
244
|
-
}
|
|
245
|
-
function resolveRetryAfterMs(signal, text, now) {
|
|
246
|
-
const explicit = parseRetryAfter(signal.retryAfter, now);
|
|
247
|
-
if (explicit !== void 0) return explicit;
|
|
248
|
-
const inText = RETRY_AFTER_IN_TEXT.exec(text);
|
|
249
|
-
return inText ? Number(inText[1]) * 1e3 : void 0;
|
|
250
|
-
}
|
|
251
|
-
function combineOutput(signal) {
|
|
252
|
-
return [signal.stderr, signal.stdout].filter((part) => part && part.trim() !== "").join("\n");
|
|
253
|
-
}
|
|
254
|
-
function describe(signal, text) {
|
|
255
|
-
const trimmed = text.trim();
|
|
256
|
-
if (trimmed !== "") return trimmed;
|
|
257
|
-
if (signal.errno) return `${signal.source} failed with ${signal.errno}`;
|
|
258
|
-
if (signal.httpStatus !== void 0)
|
|
259
|
-
return `${signal.source} responded HTTP ${signal.httpStatus}`;
|
|
260
|
-
if (signal.timedOut === true) return `${signal.source} timed out`;
|
|
261
|
-
if (signal.signal) return `${signal.source} was terminated by ${signal.signal}`;
|
|
262
|
-
if (signal.exitCode !== null && signal.exitCode !== void 0) {
|
|
263
|
-
return `${signal.source} exited with code ${signal.exitCode}`;
|
|
264
|
-
}
|
|
265
|
-
return `${signal.source} failed for an unreported reason`;
|
|
266
|
-
}
|
|
267
|
-
function classify(signal, options = {}) {
|
|
268
|
-
const now = options.now?.() ?? Date.now();
|
|
269
|
-
const text = combineOutput(signal);
|
|
270
|
-
const lowered = text.toLowerCase();
|
|
271
|
-
const kind = kindFromErrno(signal.errno) ?? kindFromHttpStatus(signal.httpStatus, lowered) ?? kindFromTermination(signal) ?? kindFromExitCode(signal.exitCode) ?? kindFromText(lowered) ?? "unknown";
|
|
272
|
-
const retryAfterMs = resolveRetryAfterMs(signal, text, now);
|
|
273
|
-
return {
|
|
274
|
-
kind,
|
|
275
|
-
message: describe(signal, text),
|
|
276
|
-
retryable: isRetryableKind(kind),
|
|
277
|
-
source: signal.source,
|
|
278
|
-
...retryAfterMs === void 0 ? {} : { retryAfterMs }
|
|
279
|
-
};
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
export {
|
|
283
|
-
requiresHumanAction,
|
|
284
|
-
ClassifiedError,
|
|
285
|
-
failureOf,
|
|
286
|
-
actionOf,
|
|
287
|
-
classify
|
|
288
|
-
};
|
|
289
|
-
//# sourceMappingURL=chunk-XEYH6ZZI.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/resilience/errors.ts"],"sourcesContent":["/**\n * Failure taxonomy.\n *\n * Every failure the pipeline reacts to is classified here, from a structured\n * `FailureSignal`, into one `FailureKind`. The point is that the decision to\n * retry stops depending on `String.includes` over an error message: text is the\n * last resort of `classify()`, not its first move.\n *\n * The invariants of this layer — above all, that `task_execution` is never\n * retried here — are in `src/resilience/AGENTS.md`.\n */\n\n/** What went wrong, in the terms the retry policy is written in. */\nexport type FailureKind =\n | 'network'\n | 'timeout'\n | 'stalled'\n | 'rate_limit'\n | 'provider_down'\n | 'provider_crash'\n | 'authentication'\n | 'configuration'\n | 'repository_state'\n | 'task_execution'\n | 'internal'\n | 'unknown';\n\n/** Which subsystem produced the failure. */\nexport type FailureSource = 'agent' | 'github' | 'git' | 'filesystem' | 'internal';\n\n/**\n * The raw evidence of a failure, as the caller observed it.\n *\n * Everything is optional but `source`: a caller hands over what it actually\n * has. `execa` supplies `exitCode`, `signal`, `timedOut` and — on the thrown\n * error — `errno`; an HTTP client supplies `httpStatus` and `retryAfter`.\n */\nexport interface FailureSignal {\n source: FailureSource;\n exitCode?: number | null;\n /** POSIX signal name that terminated the process (`SIGTERM`, `SIGKILL`). */\n signal?: string | null;\n /** `execa`'s own verdict that it killed the child on the configured limit. */\n timedOut?: boolean;\n stdout?: string;\n stderr?: string;\n /** `ENOTFOUND`, `ECONNRESET`, `ETIMEDOUT`, `EAI_AGAIN`… */\n errno?: string;\n httpStatus?: number;\n /** A server's `Retry-After` header: delay in seconds, or an HTTP date. */\n retryAfter?: string | number;\n /** Set by the watchdog when a child produced no output for too long. */\n stalled?: boolean;\n}\n\n/** The verdict. `retryable` is advice; the attempt budget belongs to the policy. */\nexport interface ClassifiedFailure {\n kind: FailureKind;\n message: string;\n retryable: boolean;\n source: FailureSource;\n /** Present only when the server told us how long to wait. */\n retryAfterMs?: number;\n}\n\n/**\n * Kinds worth another attempt: the cause is outside the work being done and is\n * expected to pass on its own.\n */\nconst RETRYABLE_KINDS: ReadonlySet<FailureKind> = new Set<FailureKind>([\n 'network',\n 'timeout',\n 'stalled',\n 'rate_limit',\n 'provider_down',\n 'provider_crash',\n]);\n\n/**\n * Kinds that no configuration may retry. Waiting cannot fix any of them: they\n * need a human, or they belong to a different loop entirely (`task_execution`\n * is the pipeline's own correction cycle — see `AGENTS.md` here).\n */\nconst HUMAN_ACTION_KINDS: ReadonlySet<FailureKind> = new Set<FailureKind>([\n 'authentication',\n 'configuration',\n 'repository_state',\n 'task_execution',\n]);\n\n/** Whether this layer considers `kind` worth retrying at all. */\nexport function isRetryableKind(kind: FailureKind): boolean {\n return RETRYABLE_KINDS.has(kind);\n}\n\n/** Whether `kind` escalates to a human instead of being retried, ever. */\nexport function requiresHumanAction(kind: FailureKind): boolean {\n return HUMAN_ACTION_KINDS.has(kind);\n}\n\n/* ── carrying a verdict through a throw ─────────────────────────────────── */\n\n/**\n * An `Error` that carries its own classification.\n *\n * A `catch` normally flattens a failure back into a string, which is exactly\n * the loss this layer exists to prevent: the caller that has to decide between\n * \"retry\" and \"escalate to a human\" then has nothing but a message again. Any\n * boundary that must throw — a provider, a phase — throws this instead.\n *\n * `action` is what a human has to do, and it is only ever set for a kind that\n * needs one (`gh auth login` for `authentication`). It is written at the throw\n * site because only that site knows which CLI is involved.\n */\nexport class ClassifiedError extends Error {\n readonly failure: ClassifiedFailure;\n readonly action: string | undefined;\n\n constructor(message: string, failure: ClassifiedFailure, action?: string) {\n super(message);\n this.name = 'ClassifiedError';\n this.failure = failure;\n this.action = action;\n }\n}\n\n/** The verdict an error carries, or `null` when it carries none. */\nexport function failureOf(error: unknown): ClassifiedFailure | null {\n return error instanceof ClassifiedError ? error.failure : null;\n}\n\n/** The human action an error asks for, or `null`. */\nexport function actionOf(error: unknown): string | null {\n return error instanceof ClassifiedError ? (error.action ?? null) : null;\n}\n\n/* ── step 1: errno ──────────────────────────────────────────────────────── */\n\nconst ERRNO_KINDS: Readonly<Record<string, FailureKind>> = {\n ENOTFOUND: 'network',\n EAI_AGAIN: 'network',\n ECONNRESET: 'network',\n ECONNREFUSED: 'network',\n ECONNABORTED: 'network',\n EHOSTUNREACH: 'network',\n ENETUNREACH: 'network',\n ENETDOWN: 'network',\n EPIPE: 'network',\n ETIMEDOUT: 'timeout',\n ENOENT: 'configuration',\n EACCES: 'configuration',\n EPERM: 'configuration',\n};\n\nfunction kindFromErrno(errno: string | undefined): FailureKind | undefined {\n if (!errno) return undefined;\n return ERRNO_KINDS[errno.toUpperCase()];\n}\n\n/* ── step 2: HTTP status ────────────────────────────────────────────────── */\n\n/**\n * GitHub reports a secondary rate limit as `403`, not `429`, so the text is\n * consulted before calling a `403` an authentication failure. Everywhere else\n * the status alone decides.\n */\nfunction kindFromHttpStatus(status: number | undefined, lowered: string): FailureKind | undefined {\n if (status === undefined || status < 400) return undefined;\n if (status === 429) return 'rate_limit';\n if (status === 401) return 'authentication';\n if (status === 403)\n return matchesAny(lowered, RATE_LIMIT_PATTERNS) ? 'rate_limit' : 'authentication';\n if (status === 408) return 'timeout';\n if (status >= 500) return 'provider_down';\n return 'configuration';\n}\n\n/* ── step 3: how the process ended ──────────────────────────────────────── */\n\nconst CRASH_SIGNALS: ReadonlySet<string> = new Set(['SIGKILL', 'SIGABRT', 'SIGSEGV', 'SIGBUS']);\n\nfunction kindFromTermination(signal: FailureSignal): FailureKind | undefined {\n if (signal.stalled === true) return 'stalled';\n if (signal.timedOut === true) return 'timeout';\n const name = signal.signal?.toUpperCase();\n if (!name) return undefined;\n if (name === 'SIGTERM') return 'timeout';\n if (CRASH_SIGNALS.has(name)) return 'provider_crash';\n return undefined;\n}\n\n/* ── step 4: exit codes we know the meaning of ──────────────────────────── */\n\n/**\n * Only codes whose meaning is unambiguous. `143` (SIGTERM) is deliberately\n * absent: the Claude CLI handles the signal itself and exits `143` for a\n * user's Ctrl+C just as it does for our timeout, so it decides nothing on its\n * own — `timedOut` or `signal` is what tells the two apart.\n */\nconst EXIT_CODE_KINDS: Readonly<Record<number, FailureKind>> = {\n 75: 'provider_down', // EX_TEMPFAIL\n 126: 'configuration', // found, not executable\n 127: 'configuration', // command not found\n 137: 'provider_crash', // 128 + SIGKILL, typically the OOM killer\n 139: 'provider_crash', // 128 + SIGSEGV\n};\n\nfunction kindFromExitCode(exitCode: number | null | undefined): FailureKind | undefined {\n if (exitCode === null || exitCode === undefined) return undefined;\n return EXIT_CODE_KINDS[exitCode];\n}\n\n/* ── step 5: text, and only as a last resort ────────────────────────────── */\n\nconst RATE_LIMIT_PATTERNS = [\n 'rate limit',\n 'rate-limit',\n 'ratelimit',\n 'too many requests',\n 'http 429',\n] as const;\n\n/**\n * Ordered on purpose. A message is scanned rule by rule and the first hit\n * wins, so the specific causes (rate limit, credentials) are consulted before\n * the generic ones, and `task_execution` comes last: an infrastructure failure\n * surfacing inside a test run is still an infrastructure failure.\n */\ntype TextPattern = string | RegExp;\n\nconst TEXT_RULES: readonly { kind: FailureKind; patterns: readonly TextPattern[] }[] = [\n { kind: 'rate_limit', patterns: RATE_LIMIT_PATTERNS },\n {\n kind: 'authentication',\n patterns: [\n 'authentication failed',\n 'authentication_error',\n 'gh auth login',\n 'not logged into',\n 'bad credentials',\n 'invalid api key',\n 'invalid_api_key',\n 'token expired',\n 'expired token',\n 'unauthorized',\n 'http 401',\n 'http 403',\n ],\n },\n {\n kind: 'network',\n patterns: [\n 'connection reset',\n 'connection refused',\n 'connection aborted',\n 'network error',\n 'network unavailable',\n 'temporary failure',\n 'econnreset',\n 'econnrefused',\n 'enotfound',\n 'eai_again',\n 'socket hang up',\n // What Go prints, and therefore what `gh` prints: its network errors\n // never mention \"connection reset\", they mention the resolver.\n 'no such host',\n 'dial tcp',\n 'i/o timeout',\n 'tls handshake timeout',\n 'server misbehaving',\n 'error connecting to',\n ],\n },\n // Before the timeout rule: a stall *is* a kind of timeout, and the specific\n // reading is the useful one — it has its own budget and its own escalation.\n { kind: 'stalled', patterns: ['produced no output for', '(stalled)'] },\n { kind: 'timeout', patterns: ['timed out', 'timeout', 'etimedout'] },\n {\n kind: 'provider_down',\n patterns: [\n 'service unavailable',\n 'temporarily unavailable',\n 'overloaded',\n 'bad gateway',\n 'gateway timeout',\n 'internal server error',\n 'http 500',\n 'http 502',\n 'http 503',\n 'http 504',\n ],\n },\n {\n kind: 'provider_crash',\n patterns: ['segmentation fault', 'core dumped', 'out of memory', 'killed by signal'],\n },\n {\n kind: 'repository_state',\n patterns: [\n 'unmerged paths',\n 'needs merge',\n 'automatic merge failed',\n 'rebase in progress',\n 'you are in the middle of',\n 'cherry-pick is in progress',\n 'not a git repository',\n ],\n },\n {\n kind: 'configuration',\n patterns: [\n 'command not found',\n 'unknown flag',\n 'unknown option',\n 'no such file or directory',\n 'permission check failed',\n 'user denied permission',\n 'waiting for human input',\n 'status: waiting',\n 'below the minimum',\n 'prompt exceeds',\n 'nativetimeout',\n 'agy is not installed',\n ],\n },\n {\n kind: 'task_execution',\n patterns: [\n 'test failed',\n 'tests failed',\n 'failed tests',\n 'failing test',\n 'assertion failed',\n 'assertionerror',\n 'expect(received)',\n 'typecheck failed',\n 'npm err! test failed',\n 'lint failed',\n 'build failed',\n 'compilation failed',\n 'syntaxerror',\n 'typeerror',\n 'referenceerror',\n // What a runner actually prints: \"Tests 3 failed | 41 passed\",\n // \"Test Files 1 failed (12)\", \"Tests: 2 failed, 8 total\".\n /\\b\\d+\\s+failed\\b/,\n ],\n },\n];\n\nfunction matchesAny(lowered: string, patterns: readonly TextPattern[]): boolean {\n return patterns.some((pattern) =>\n typeof pattern === 'string' ? lowered.includes(pattern) : pattern.test(lowered),\n );\n}\n\nfunction kindFromText(lowered: string): FailureKind | undefined {\n if (!lowered) return undefined;\n for (const rule of TEXT_RULES) {\n if (matchesAny(lowered, rule.patterns)) return rule.kind;\n }\n return undefined;\n}\n\n/* ── Retry-After ────────────────────────────────────────────────────────── */\n\nconst RETRY_AFTER_IN_TEXT = /retry[\\s-]?after:?\\s*(\\d+)/i;\n\n/**\n * `Retry-After` is either a delay in seconds or an HTTP date. Both are\n * accepted; anything else, and a date already in the past, yields nothing\n * rather than a bogus zero.\n */\nfunction parseRetryAfter(value: string | number | undefined, now: number): number | undefined {\n if (value === undefined) return undefined;\n if (typeof value === 'number')\n return Number.isFinite(value) && value >= 0 ? value * 1000 : undefined;\n\n const trimmed = value.trim();\n if (trimmed === '') return undefined;\n if (/^\\d+$/.test(trimmed)) return Number(trimmed) * 1000;\n\n const at = Date.parse(trimmed);\n if (Number.isNaN(at)) return undefined;\n return at > now ? at - now : undefined;\n}\n\nfunction resolveRetryAfterMs(signal: FailureSignal, text: string, now: number): number | undefined {\n const explicit = parseRetryAfter(signal.retryAfter, now);\n if (explicit !== undefined) return explicit;\n\n const inText = RETRY_AFTER_IN_TEXT.exec(text);\n return inText ? Number(inText[1]) * 1000 : undefined;\n}\n\n/* ── message ────────────────────────────────────────────────────────────── */\n\nfunction combineOutput(signal: FailureSignal): string {\n return [signal.stderr, signal.stdout].filter((part) => part && part.trim() !== '').join('\\n');\n}\n\n/** The output verbatim when there is any, and a synthesised line when there is not. */\nfunction describe(signal: FailureSignal, text: string): string {\n const trimmed = text.trim();\n if (trimmed !== '') return trimmed;\n if (signal.errno) return `${signal.source} failed with ${signal.errno}`;\n if (signal.httpStatus !== undefined)\n return `${signal.source} responded HTTP ${signal.httpStatus}`;\n if (signal.timedOut === true) return `${signal.source} timed out`;\n if (signal.signal) return `${signal.source} was terminated by ${signal.signal}`;\n if (signal.exitCode !== null && signal.exitCode !== undefined) {\n return `${signal.source} exited with code ${signal.exitCode}`;\n }\n return `${signal.source} failed for an unreported reason`;\n}\n\n/* ── the classifier ─────────────────────────────────────────────────────── */\n\nexport interface ClassifyOptions {\n /** Injectable clock, so an HTTP-date `Retry-After` is testable. */\n now?: () => number;\n}\n\n/**\n * Classify a failure by precedence: errno and HTTP status first (a machine\n * told us), then how the process ended, then an exit code we know the meaning\n * of, and only then the text — which is a heuristic and is treated as one.\n */\nexport function classify(signal: FailureSignal, options: ClassifyOptions = {}): ClassifiedFailure {\n const now = options.now?.() ?? Date.now();\n const text = combineOutput(signal);\n const lowered = text.toLowerCase();\n\n const kind =\n kindFromErrno(signal.errno) ??\n kindFromHttpStatus(signal.httpStatus, lowered) ??\n kindFromTermination(signal) ??\n kindFromExitCode(signal.exitCode) ??\n kindFromText(lowered) ??\n 'unknown';\n\n const retryAfterMs = resolveRetryAfterMs(signal, text, now);\n\n return {\n kind,\n message: describe(signal, text),\n retryable: isRetryableKind(kind),\n source: signal.source,\n ...(retryAfterMs === undefined ? {} : { retryAfterMs }),\n };\n}\n"],"mappings":"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","names":[]}
|
package/dist/chunk-XZUEFTUP.js
DELETED
|
@@ -1,243 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
writeDiagnostic
|
|
4
|
-
} from "./chunk-QPGEFLMY.js";
|
|
5
|
-
import {
|
|
6
|
-
getSessionPublisher
|
|
7
|
-
} from "./chunk-DUS5ZNKL.js";
|
|
8
|
-
import {
|
|
9
|
-
isoNow
|
|
10
|
-
} from "./chunk-SOM4QA6C.js";
|
|
11
|
-
|
|
12
|
-
// src/core/verbose.ts
|
|
13
|
-
var _verbose = false;
|
|
14
|
-
function setVerbose(enabled) {
|
|
15
|
-
_verbose = enabled;
|
|
16
|
-
}
|
|
17
|
-
function isVerbose() {
|
|
18
|
-
return _verbose;
|
|
19
|
-
}
|
|
20
|
-
var _onOutput;
|
|
21
|
-
function setOutputCallback(callback) {
|
|
22
|
-
_onOutput = callback;
|
|
23
|
-
}
|
|
24
|
-
function getOutputCallback() {
|
|
25
|
-
return _onOutput;
|
|
26
|
-
}
|
|
27
|
-
var _onStoryUpdate;
|
|
28
|
-
function setStoryUpdateCallback(callback) {
|
|
29
|
-
_onStoryUpdate = callback;
|
|
30
|
-
}
|
|
31
|
-
function getStoryUpdateCallback() {
|
|
32
|
-
return _onStoryUpdate;
|
|
33
|
-
}
|
|
34
|
-
var _onStoryStage;
|
|
35
|
-
function setStoryStageCallback(callback) {
|
|
36
|
-
_onStoryStage = callback;
|
|
37
|
-
}
|
|
38
|
-
function getStoryStageCallback() {
|
|
39
|
-
return _onStoryStage;
|
|
40
|
-
}
|
|
41
|
-
var _onActivity;
|
|
42
|
-
function setActivityCallback(callback) {
|
|
43
|
-
_onActivity = callback;
|
|
44
|
-
}
|
|
45
|
-
function getActivityCallback() {
|
|
46
|
-
return _onActivity;
|
|
47
|
-
}
|
|
48
|
-
var _globalTimeout;
|
|
49
|
-
function setGlobalTimeout(ms) {
|
|
50
|
-
_globalTimeout = ms;
|
|
51
|
-
}
|
|
52
|
-
function getGlobalTimeout() {
|
|
53
|
-
return _globalTimeout;
|
|
54
|
-
}
|
|
55
|
-
var _inactivityTimeout;
|
|
56
|
-
function setInactivityTimeout(ms) {
|
|
57
|
-
_inactivityTimeout = ms;
|
|
58
|
-
}
|
|
59
|
-
function getInactivityTimeout() {
|
|
60
|
-
return _inactivityTimeout;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// src/ui/logger.ts
|
|
64
|
-
import chalk from "chalk";
|
|
65
|
-
import ora from "ora";
|
|
66
|
-
function useUnicode() {
|
|
67
|
-
if (process.env.NO_COLOR != null && process.env.NO_COLOR !== "") return false;
|
|
68
|
-
if (!process.stdout.isTTY) return false;
|
|
69
|
-
return true;
|
|
70
|
-
}
|
|
71
|
-
function useColor() {
|
|
72
|
-
if (process.env.NO_COLOR != null && process.env.NO_COLOR !== "") return false;
|
|
73
|
-
if (!process.stdout.isTTY) return false;
|
|
74
|
-
return true;
|
|
75
|
-
}
|
|
76
|
-
function getIcons() {
|
|
77
|
-
if (useUnicode()) {
|
|
78
|
-
return {
|
|
79
|
-
success: "\u2713",
|
|
80
|
-
fail: "\u2717",
|
|
81
|
-
pending: "\u23F3",
|
|
82
|
-
retry: "\u21BB",
|
|
83
|
-
warn: "\u26A0",
|
|
84
|
-
start: "\u25B6",
|
|
85
|
-
end: "\u25A0",
|
|
86
|
-
notReached: "\u25CB",
|
|
87
|
-
tool: "\u25B8",
|
|
88
|
-
connector: "\u2502",
|
|
89
|
-
info: "\xB7"
|
|
90
|
-
};
|
|
91
|
-
}
|
|
92
|
-
return {
|
|
93
|
-
success: "[OK]",
|
|
94
|
-
fail: "[FAIL]",
|
|
95
|
-
pending: "[...]",
|
|
96
|
-
retry: "[RETRY]",
|
|
97
|
-
warn: "[WARN]",
|
|
98
|
-
start: "[START]",
|
|
99
|
-
end: "[END]",
|
|
100
|
-
notReached: "[ ]",
|
|
101
|
-
tool: ">",
|
|
102
|
-
connector: "|",
|
|
103
|
-
info: "-"
|
|
104
|
-
};
|
|
105
|
-
}
|
|
106
|
-
function getTermWidth() {
|
|
107
|
-
return process.stdout.columns ?? 80;
|
|
108
|
-
}
|
|
109
|
-
function emit(line, level = "info") {
|
|
110
|
-
getSessionPublisher().publish({ type: "log", at: isoNow(), level, message: line });
|
|
111
|
-
writeDiagnostic({
|
|
112
|
-
level: level === "warn" ? "warning" : level,
|
|
113
|
-
message: line
|
|
114
|
-
});
|
|
115
|
-
const cb = getOutputCallback();
|
|
116
|
-
if (cb) {
|
|
117
|
-
cb(line);
|
|
118
|
-
} else {
|
|
119
|
-
console.log(line);
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
function printSuccess(message) {
|
|
123
|
-
const icons = getIcons();
|
|
124
|
-
if (useColor()) {
|
|
125
|
-
emit(chalk.green(`${icons.success} ${message}`));
|
|
126
|
-
} else {
|
|
127
|
-
emit(`${icons.success} ${message}`);
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
function printError(message) {
|
|
131
|
-
const icons = getIcons();
|
|
132
|
-
if (useColor()) {
|
|
133
|
-
emit(chalk.red(`${icons.fail} ${message}`), "error");
|
|
134
|
-
} else {
|
|
135
|
-
emit(`${icons.fail} ${message}`, "error");
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
function printWarning(message) {
|
|
139
|
-
const icons = getIcons();
|
|
140
|
-
if (useColor()) {
|
|
141
|
-
emit(chalk.yellow(`${icons.warn} ${message}`), "warn");
|
|
142
|
-
} else {
|
|
143
|
-
emit(`${icons.warn} ${message}`, "warn");
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
function printRetry(message) {
|
|
147
|
-
const icons = getIcons();
|
|
148
|
-
if (useColor()) {
|
|
149
|
-
emit(chalk.yellow(`${icons.retry} ${message}`), "warn");
|
|
150
|
-
} else {
|
|
151
|
-
emit(`${icons.retry} ${message}`, "warn");
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
function printInfo(message) {
|
|
155
|
-
const icons = getIcons();
|
|
156
|
-
if (useColor()) {
|
|
157
|
-
emit(chalk.blue(`${icons.info} ${message}`));
|
|
158
|
-
} else {
|
|
159
|
-
emit(`${icons.info} ${message}`);
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
function createSpinner(message) {
|
|
163
|
-
return ora({
|
|
164
|
-
text: message,
|
|
165
|
-
color: "blue",
|
|
166
|
-
spinner: "dots"
|
|
167
|
-
});
|
|
168
|
-
}
|
|
169
|
-
function formatDuration(totalSeconds) {
|
|
170
|
-
const hours = Math.floor(totalSeconds / 3600);
|
|
171
|
-
const mins = Math.floor(totalSeconds % 3600 / 60);
|
|
172
|
-
const secs = totalSeconds % 60;
|
|
173
|
-
if (hours > 0) {
|
|
174
|
-
return `${hours}h ${mins}m ${secs}s`;
|
|
175
|
-
}
|
|
176
|
-
if (mins > 0) {
|
|
177
|
-
return `${mins}m ${secs}s`;
|
|
178
|
-
}
|
|
179
|
-
return `${secs}s`;
|
|
180
|
-
}
|
|
181
|
-
var ElapsedTimer = class {
|
|
182
|
-
constructor(onTick) {
|
|
183
|
-
this.onTick = onTick;
|
|
184
|
-
this.startTime = Date.now();
|
|
185
|
-
}
|
|
186
|
-
onTick;
|
|
187
|
-
startTime;
|
|
188
|
-
intervalId = null;
|
|
189
|
-
cleanup = () => this.stop();
|
|
190
|
-
start() {
|
|
191
|
-
this.startTime = Date.now();
|
|
192
|
-
this.intervalId = setInterval(() => {
|
|
193
|
-
const seconds = Math.floor((Date.now() - this.startTime) / 1e3);
|
|
194
|
-
this.onTick(formatDuration(seconds));
|
|
195
|
-
}, 1e3);
|
|
196
|
-
if (this.intervalId && typeof this.intervalId === "object" && "unref" in this.intervalId) {
|
|
197
|
-
this.intervalId.unref();
|
|
198
|
-
}
|
|
199
|
-
process.on("exit", this.cleanup);
|
|
200
|
-
return this;
|
|
201
|
-
}
|
|
202
|
-
getElapsedSeconds() {
|
|
203
|
-
return Math.floor((Date.now() - this.startTime) / 1e3);
|
|
204
|
-
}
|
|
205
|
-
stop() {
|
|
206
|
-
if (this.intervalId) {
|
|
207
|
-
clearInterval(this.intervalId);
|
|
208
|
-
this.intervalId = null;
|
|
209
|
-
}
|
|
210
|
-
process.removeListener("exit", this.cleanup);
|
|
211
|
-
return this.getElapsedSeconds();
|
|
212
|
-
}
|
|
213
|
-
};
|
|
214
|
-
|
|
215
|
-
export {
|
|
216
|
-
setVerbose,
|
|
217
|
-
isVerbose,
|
|
218
|
-
setOutputCallback,
|
|
219
|
-
getOutputCallback,
|
|
220
|
-
setStoryUpdateCallback,
|
|
221
|
-
getStoryUpdateCallback,
|
|
222
|
-
setStoryStageCallback,
|
|
223
|
-
getStoryStageCallback,
|
|
224
|
-
setActivityCallback,
|
|
225
|
-
getActivityCallback,
|
|
226
|
-
setGlobalTimeout,
|
|
227
|
-
getGlobalTimeout,
|
|
228
|
-
setInactivityTimeout,
|
|
229
|
-
getInactivityTimeout,
|
|
230
|
-
useUnicode,
|
|
231
|
-
useColor,
|
|
232
|
-
getIcons,
|
|
233
|
-
getTermWidth,
|
|
234
|
-
printSuccess,
|
|
235
|
-
printError,
|
|
236
|
-
printWarning,
|
|
237
|
-
printRetry,
|
|
238
|
-
printInfo,
|
|
239
|
-
createSpinner,
|
|
240
|
-
formatDuration,
|
|
241
|
-
ElapsedTimer
|
|
242
|
-
};
|
|
243
|
-
//# sourceMappingURL=chunk-XZUEFTUP.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core/verbose.ts","../src/ui/logger.ts"],"sourcesContent":["let _verbose = false;\n\nexport function setVerbose(enabled: boolean): void {\n _verbose = enabled;\n}\n\nexport function isVerbose(): boolean {\n return _verbose;\n}\n\nlet _onOutput: ((line: string) => void) | undefined;\n\n/**\n * Set a global output callback for routing verbose output (e.g., through listr2 task.output).\n * Pass undefined to clear and fall back to direct stderr writes.\n */\nexport function setOutputCallback(callback: ((line: string) => void) | undefined): void {\n _onOutput = callback;\n}\n\nexport function getOutputCallback(): ((line: string) => void) | undefined {\n return _onOutput;\n}\n\nlet _onStoryUpdate: ((stories: import('../types.js').UserStory[]) => void) | undefined;\n\n/**\n * Set a global callback for story progress updates during engine execution.\n * Called after each iteration with the latest user stories state.\n * Pass undefined to clear.\n */\nexport function setStoryUpdateCallback(\n callback: ((stories: import('../types.js').UserStory[]) => void) | undefined,\n): void {\n _onStoryUpdate = callback;\n}\n\nexport function getStoryUpdateCallback():\n | ((stories: import('../types.js').UserStory[]) => void)\n | undefined {\n return _onStoryUpdate;\n}\n\nlet _onStoryStage: ((storyId: string | undefined) => void) | undefined;\n\n/**\n * Set a global callback for the active story of the current `execute`\n * iteration. Called by `core/engine.ts` alongside every `iteration:start`\n * publication, with the same `storyId` (or `undefined` once every story\n * already passes) — the terminal renderer's only source for \"who is\n * executing right now\", never a second, independently computed heuristic.\n * Pass `undefined` to clear.\n */\nexport function setStoryStageCallback(\n callback: ((storyId: string | undefined) => void) | undefined,\n): void {\n _onStoryStage = callback;\n}\n\nexport function getStoryStageCallback(): ((storyId: string | undefined) => void) | undefined {\n return _onStoryStage;\n}\n\nexport interface ActivityNotice {\n tool: string;\n detail?: string;\n}\n\nlet _onActivity: ((notice: ActivityNotice) => void) | undefined;\n\n/**\n * Live tool activity for the clean terminal view. Published in every mode,\n * including non-verbose — the snapshot's `currentActivity` and the dashboard\n * both read the same event.\n */\nexport function setActivityCallback(\n callback: ((notice: ActivityNotice) => void) | undefined,\n): void {\n _onActivity = callback;\n}\n\nexport function getActivityCallback(): ((notice: ActivityNotice) => void) | undefined {\n return _onActivity;\n}\n\nlet _globalTimeout: number | undefined;\n\nexport function setGlobalTimeout(ms: number): void {\n _globalTimeout = ms;\n}\n\nexport function getGlobalTimeout(): number | undefined {\n return _globalTimeout;\n}\n\n/**\n * Silence tolerated before an agent is considered stuck, in milliseconds.\n *\n * Global for the same reason the timeout is: every phase invokes the CLI\n * through the same two functions, and threading it through each one of them\n * would be a parameter with a single value per process. `undefined` leaves the\n * default; `0` turns the watchdog off.\n */\nlet _inactivityTimeout: number | undefined;\n\nexport function setInactivityTimeout(ms: number): void {\n _inactivityTimeout = ms;\n}\n\nexport function getInactivityTimeout(): number | undefined {\n return _inactivityTimeout;\n}\n","import chalk from 'chalk';\nimport ora, { type Ora } from 'ora';\nimport { getSessionPublisher } from '../core/session-publisher.js';\nimport type { SessionLogLevel } from '../core/session-state.js';\nimport { isoNow } from '../core/state-manager.js';\nimport { getOutputCallback } from '../core/verbose.js';\nimport { writeDiagnostic } from '../storage/diagnostics.js';\n\n/**\n * Detect if unicode output is supported.\n */\nexport function useUnicode(): boolean {\n if (process.env.NO_COLOR != null && process.env.NO_COLOR !== '') return false;\n if (!process.stdout.isTTY) return false;\n return true;\n}\n\n/**\n * Detect if color output is supported.\n */\nexport function useColor(): boolean {\n if (process.env.NO_COLOR != null && process.env.NO_COLOR !== '') return false;\n if (!process.stdout.isTTY) return false;\n return true;\n}\n\nexport interface Icons {\n success: string;\n fail: string;\n pending: string;\n retry: string;\n warn: string;\n start: string;\n end: string;\n notReached: string;\n tool: string;\n connector: string;\n info: string;\n}\n\nexport function getIcons(): Icons {\n if (useUnicode()) {\n return {\n success: '\\u2713',\n fail: '\\u2717',\n pending: '\\u23F3',\n retry: '\\u21BB',\n warn: '\\u26A0',\n start: '\\u25B6',\n end: '\\u25A0',\n notReached: '\\u25CB',\n tool: '\\u25B8',\n connector: '\\u2502',\n info: '\\u00B7',\n };\n }\n return {\n success: '[OK]',\n fail: '[FAIL]',\n pending: '[...]',\n retry: '[RETRY]',\n warn: '[WARN]',\n start: '[START]',\n end: '[END]',\n notReached: '[ ]',\n tool: '>',\n connector: '|',\n info: '-',\n };\n}\n\n/**\n * Get the terminal width.\n */\nexport function getTermWidth(): number {\n return process.stdout.columns ?? 80;\n}\n\n/**\n * Emit a line of output. Routes through the global output callback when\n * running inside a listr2 task context, otherwise falls back to console.log.\n *\n * Also forwards the line to the session publisher with its structured level;\n * ANSI codes are stripped by the reducer, so terminal output stays untouched.\n */\nfunction emit(line: string, level: SessionLogLevel = 'info'): void {\n getSessionPublisher().publish({ type: 'log', at: isoNow(), level, message: line });\n writeDiagnostic({\n level: level === 'warn' ? 'warning' : level,\n message: line,\n });\n const cb = getOutputCallback();\n if (cb) {\n cb(line);\n } else {\n console.log(line);\n }\n}\n\nexport function printSuccess(message: string): void {\n const icons = getIcons();\n if (useColor()) {\n emit(chalk.green(`${icons.success} ${message}`));\n } else {\n emit(`${icons.success} ${message}`);\n }\n}\n\nexport function printError(message: string): void {\n const icons = getIcons();\n if (useColor()) {\n emit(chalk.red(`${icons.fail} ${message}`), 'error');\n } else {\n emit(`${icons.fail} ${message}`, 'error');\n }\n}\n\nexport function printWarning(message: string): void {\n const icons = getIcons();\n if (useColor()) {\n emit(chalk.yellow(`${icons.warn} ${message}`), 'warn');\n } else {\n emit(`${icons.warn} ${message}`, 'warn');\n }\n}\n\nexport function printRetry(message: string): void {\n const icons = getIcons();\n if (useColor()) {\n emit(chalk.yellow(`${icons.retry} ${message}`), 'warn');\n } else {\n emit(`${icons.retry} ${message}`, 'warn');\n }\n}\n\nexport function printInfo(message: string): void {\n const icons = getIcons();\n if (useColor()) {\n emit(chalk.blue(`${icons.info} ${message}`));\n } else {\n emit(`${icons.info} ${message}`);\n }\n}\n\n/**\n * Create an ora spinner with consistent styling.\n */\nexport function createSpinner(message: string): Ora {\n return ora({\n text: message,\n color: 'blue',\n spinner: 'dots',\n });\n}\n\n/**\n * Format a duration in seconds to a human-readable string.\n */\nexport function formatDuration(totalSeconds: number): string {\n const hours = Math.floor(totalSeconds / 3600);\n const mins = Math.floor((totalSeconds % 3600) / 60);\n const secs = totalSeconds % 60;\n\n if (hours > 0) {\n return `${hours}h ${mins}m ${secs}s`;\n }\n if (mins > 0) {\n return `${mins}m ${secs}s`;\n }\n return `${secs}s`;\n}\n\n/**\n * Timer that calls a callback every second with the formatted elapsed time.\n */\nexport class ElapsedTimer {\n private startTime: number;\n private intervalId: ReturnType<typeof setInterval> | null = null;\n private cleanup = () => this.stop();\n\n constructor(private onTick: (elapsed: string) => void) {\n this.startTime = Date.now();\n }\n\n start(): this {\n this.startTime = Date.now();\n this.intervalId = setInterval(() => {\n const seconds = Math.floor((Date.now() - this.startTime) / 1000);\n this.onTick(formatDuration(seconds));\n }, 1_000);\n // Prevent the timer from keeping the process alive\n if (this.intervalId && typeof this.intervalId === 'object' && 'unref' in this.intervalId) {\n this.intervalId.unref();\n }\n process.on('exit', this.cleanup);\n return this;\n }\n\n getElapsedSeconds(): number {\n return Math.floor((Date.now() - this.startTime) / 1000);\n }\n\n stop(): number {\n if (this.intervalId) {\n clearInterval(this.intervalId);\n this.intervalId = null;\n }\n process.removeListener('exit', this.cleanup);\n return this.getElapsedSeconds();\n }\n}\n"],"mappings":"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","names":[]}
|