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
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
getStoredIssueHistory
|
|
4
|
+
} from "./chunk-2EYLOS5I.js";
|
|
5
|
+
import {
|
|
6
|
+
parseJournal,
|
|
7
|
+
printError,
|
|
8
|
+
printInfo,
|
|
9
|
+
resolveIssuePaths,
|
|
10
|
+
resolveProjectPaths
|
|
11
|
+
} from "./chunk-J6VJ5M2U.js";
|
|
12
|
+
import "./chunk-7CMVL4X6.js";
|
|
13
|
+
import "./chunk-DIMDAYZS.js";
|
|
14
|
+
import "./chunk-HEHHQU4G.js";
|
|
15
|
+
import "./chunk-PRGPSNGA.js";
|
|
16
|
+
import "./chunk-P3LRUNC6.js";
|
|
17
|
+
import "./chunk-LYC57OXF.js";
|
|
18
|
+
import {
|
|
19
|
+
loadTaskPlan
|
|
20
|
+
} from "./chunk-GD7JZMSJ.js";
|
|
21
|
+
import "./chunk-NP47HRX2.js";
|
|
22
|
+
import "./chunk-IMB6FA2F.js";
|
|
23
|
+
import "./chunk-7MJGYPHF.js";
|
|
24
|
+
import "./chunk-XNK5UN2D.js";
|
|
25
|
+
import "./chunk-MAJ6QDRL.js";
|
|
26
|
+
import "./chunk-TJVX42KY.js";
|
|
27
|
+
import "./chunk-PFWHHYEO.js";
|
|
28
|
+
|
|
29
|
+
// src/commands/history.ts
|
|
30
|
+
import { readFile } from "node:fs/promises";
|
|
31
|
+
async function readJson(path) {
|
|
32
|
+
try {
|
|
33
|
+
return JSON.parse(await readFile(path, "utf-8"));
|
|
34
|
+
} catch {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
async function jsonHistory(issueId) {
|
|
39
|
+
const paths = await resolveIssuePaths(issueId);
|
|
40
|
+
const plan = await loadTaskPlan(paths.tasksFile);
|
|
41
|
+
const content = `${await readFile(paths.rotatedEventsFile, "utf-8").catch(() => "")}${await readFile(paths.eventsFile, "utf-8").catch(() => "")}`;
|
|
42
|
+
const phases = parseJournal(content).filter(({ event }) => event.type === "phase:start" || event.type === "phase:end").map(({ event }) => event);
|
|
43
|
+
const evidence = await readJson(paths.verifyFile);
|
|
44
|
+
return {
|
|
45
|
+
issueId,
|
|
46
|
+
runs: [],
|
|
47
|
+
phases,
|
|
48
|
+
executions: plan.executions ?? [],
|
|
49
|
+
verifications: evidence === null ? [] : [evidence],
|
|
50
|
+
reviews: plan.prReview === void 0 ? [] : [plan.prReview]
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
async function runHistory(issueId, options = {}) {
|
|
54
|
+
try {
|
|
55
|
+
const project = await resolveProjectPaths();
|
|
56
|
+
const history = project.storageDriver === "sqlite" ? await getStoredIssueHistory({ projectId: project.projectId, issueId }) : await jsonHistory(issueId);
|
|
57
|
+
if (options.json === true) {
|
|
58
|
+
printInfo(JSON.stringify({ schemaVersion: 1, ...history }, null, 2));
|
|
59
|
+
return 0;
|
|
60
|
+
}
|
|
61
|
+
printInfo(`History for issue #${issueId}`);
|
|
62
|
+
for (const run of history.runs) {
|
|
63
|
+
printInfo(
|
|
64
|
+
`run ${String(run.id)} \xB7 ${String(run.status)} \xB7 ${String(run.started_at)}${run.finished_at == null ? "" : ` \u2192 ${String(run.finished_at)}`}`
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
for (const phase of history.phases) {
|
|
68
|
+
printInfo(
|
|
69
|
+
`phase ${String(phase.name ?? phase.phase)} \xB7 ${String(phase.status ?? (phase.success === false ? "failed" : "completed"))}`
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
for (const execution of history.executions) {
|
|
73
|
+
printInfo(
|
|
74
|
+
`execution ${execution.purpose} \xB7 attempt ${execution.attempt} \xB7 ${execution.trigger} \xB7 ${execution.status} \xB7 ${execution.agent.harness}`
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
for (const verification of history.verifications) {
|
|
78
|
+
printInfo(
|
|
79
|
+
`verification \xB7 ${String(verification.verdict ?? verification.status ?? "unknown")}`
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
for (const review of history.reviews) {
|
|
83
|
+
printInfo(
|
|
84
|
+
`review \xB7 ${String(review.lastRecommendation ?? review.recommendation ?? review.status ?? "unknown")}`
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
if (history.runs.length + history.phases.length + history.executions.length + history.verifications.length + history.reviews.length === 0) {
|
|
88
|
+
printInfo("No history recorded yet.");
|
|
89
|
+
}
|
|
90
|
+
return 0;
|
|
91
|
+
} catch (error) {
|
|
92
|
+
printError(
|
|
93
|
+
`Could not read history for issue #${issueId}: ${error instanceof Error ? error.message : String(error)}`
|
|
94
|
+
);
|
|
95
|
+
return 1;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
export {
|
|
99
|
+
runHistory
|
|
100
|
+
};
|
|
101
|
+
//# sourceMappingURL=history-6GSURU3H.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/history.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\nimport { parseJournal } from '../core/journal.js';\nimport { loadTaskPlan } from '../core/state-manager.js';\nimport { getStoredIssueHistory, type StoredIssueHistory } from '../storage/db/queries.js';\nimport { resolveIssuePaths, resolveProjectPaths } from '../storage/resolve.js';\nimport { printError, printInfo } from '../ui/logger.js';\n\nexport interface HistoryOptions {\n json?: boolean;\n}\n\nasync function readJson(path: string): Promise<Record<string, unknown> | null> {\n try {\n return JSON.parse(await readFile(path, 'utf-8')) as Record<string, unknown>;\n } catch {\n return null;\n }\n}\n\nasync function jsonHistory(issueId: string): Promise<StoredIssueHistory> {\n const paths = await resolveIssuePaths(issueId);\n const plan = await loadTaskPlan(paths.tasksFile);\n const content = `${await readFile(paths.rotatedEventsFile, 'utf-8').catch(() => '')}${await readFile(paths.eventsFile, 'utf-8').catch(() => '')}`;\n const phases = parseJournal(content)\n .filter(({ event }) => event.type === 'phase:start' || event.type === 'phase:end')\n .map(({ event }) => event as unknown as Record<string, unknown>);\n const evidence = await readJson(paths.verifyFile);\n return {\n issueId,\n runs: [],\n phases,\n executions: plan.executions ?? [],\n verifications: evidence === null ? [] : [evidence],\n reviews:\n plan.prReview === undefined ? [] : [plan.prReview as unknown as Record<string, unknown>],\n };\n}\n\nexport async function runHistory(issueId: string, options: HistoryOptions = {}): Promise<number> {\n try {\n const project = await resolveProjectPaths();\n const history =\n project.storageDriver === 'sqlite'\n ? await getStoredIssueHistory({ projectId: project.projectId, issueId })\n : await jsonHistory(issueId);\n\n if (options.json === true) {\n printInfo(JSON.stringify({ schemaVersion: 1, ...history }, null, 2));\n return 0;\n }\n\n printInfo(`History for issue #${issueId}`);\n for (const run of history.runs) {\n printInfo(\n `run ${String(run.id)} · ${String(run.status)} · ${String(run.started_at)}${run.finished_at == null ? '' : ` → ${String(run.finished_at)}`}`,\n );\n }\n for (const phase of history.phases) {\n printInfo(\n `phase ${String(phase.name ?? phase.phase)} · ${String(phase.status ?? (phase.success === false ? 'failed' : 'completed'))}`,\n );\n }\n for (const execution of history.executions) {\n printInfo(\n `execution ${execution.purpose} · attempt ${execution.attempt} · ${execution.trigger} · ${execution.status} · ${execution.agent.harness}`,\n );\n }\n for (const verification of history.verifications) {\n printInfo(\n `verification · ${String(verification.verdict ?? verification.status ?? 'unknown')}`,\n );\n }\n for (const review of history.reviews) {\n printInfo(\n `review · ${String(review.lastRecommendation ?? review.recommendation ?? review.status ?? 'unknown')}`,\n );\n }\n if (\n history.runs.length +\n history.phases.length +\n history.executions.length +\n history.verifications.length +\n history.reviews.length ===\n 0\n ) {\n printInfo('No history recorded yet.');\n }\n return 0;\n } catch (error) {\n printError(\n `Could not read history for issue #${issueId}: ${error instanceof Error ? error.message : String(error)}`,\n );\n return 1;\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
runInit,
|
|
4
|
+
shouldOfferAgentPrompt,
|
|
5
|
+
summarizePreflight
|
|
6
|
+
} from "./chunk-46S7APLQ.js";
|
|
7
|
+
import "./chunk-UHDXXLYH.js";
|
|
8
|
+
import "./chunk-J6VJ5M2U.js";
|
|
9
|
+
import "./chunk-7CMVL4X6.js";
|
|
10
|
+
import "./chunk-DIMDAYZS.js";
|
|
11
|
+
import "./chunk-HEHHQU4G.js";
|
|
12
|
+
import "./chunk-PRGPSNGA.js";
|
|
13
|
+
import "./chunk-P3LRUNC6.js";
|
|
14
|
+
import "./chunk-LYC57OXF.js";
|
|
15
|
+
import "./chunk-GD7JZMSJ.js";
|
|
16
|
+
import "./chunk-NP47HRX2.js";
|
|
17
|
+
import "./chunk-IMB6FA2F.js";
|
|
18
|
+
import "./chunk-7MJGYPHF.js";
|
|
19
|
+
import "./chunk-XNK5UN2D.js";
|
|
20
|
+
import "./chunk-MAJ6QDRL.js";
|
|
21
|
+
import "./chunk-TJVX42KY.js";
|
|
22
|
+
import "./chunk-PFWHHYEO.js";
|
|
23
|
+
export {
|
|
24
|
+
runInit,
|
|
25
|
+
shouldOfferAgentPrompt,
|
|
26
|
+
summarizePreflight
|
|
27
|
+
};
|
|
28
|
+
//# sourceMappingURL=init-DD6DBRC5.js.map
|
|
@@ -3,48 +3,66 @@ import {
|
|
|
3
3
|
PIPELINE_PHASES,
|
|
4
4
|
PipelineManager,
|
|
5
5
|
loadExecutionPlan
|
|
6
|
-
} from "./chunk-
|
|
7
|
-
import "./chunk-KMMASOA6.js";
|
|
8
|
-
import {
|
|
9
|
-
parseJournal
|
|
10
|
-
} from "./chunk-WCCZJL7W.js";
|
|
6
|
+
} from "./chunk-LRWIP7QS.js";
|
|
11
7
|
import {
|
|
12
|
-
|
|
13
|
-
|
|
8
|
+
latestStoredIssueSnapshot,
|
|
9
|
+
listStoredIssueEvents,
|
|
10
|
+
listStoredIssueIds,
|
|
11
|
+
listStoredQueues
|
|
12
|
+
} from "./chunk-2EYLOS5I.js";
|
|
13
|
+
import "./chunk-KMMASOA6.js";
|
|
14
14
|
import {
|
|
15
|
+
parseJournal,
|
|
15
16
|
printError,
|
|
16
17
|
printInfo,
|
|
17
|
-
printWarning
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
import "./chunk-
|
|
25
|
-
import "./chunk-
|
|
26
|
-
import "./chunk-
|
|
27
|
-
import "./chunk-PPZ3K4YM.js";
|
|
18
|
+
printWarning,
|
|
19
|
+
resolveIssuePaths,
|
|
20
|
+
resolveProjectPaths
|
|
21
|
+
} from "./chunk-J6VJ5M2U.js";
|
|
22
|
+
import "./chunk-7CMVL4X6.js";
|
|
23
|
+
import "./chunk-DIMDAYZS.js";
|
|
24
|
+
import "./chunk-HEHHQU4G.js";
|
|
25
|
+
import "./chunk-PRGPSNGA.js";
|
|
26
|
+
import "./chunk-P3LRUNC6.js";
|
|
27
|
+
import "./chunk-LYC57OXF.js";
|
|
28
28
|
import {
|
|
29
29
|
loadTaskPlan
|
|
30
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-GD7JZMSJ.js";
|
|
31
|
+
import "./chunk-NP47HRX2.js";
|
|
31
32
|
import {
|
|
32
33
|
describeRunLockOwner,
|
|
33
34
|
isRunLockStale,
|
|
34
35
|
readRunLock
|
|
35
|
-
} from "./chunk-
|
|
36
|
-
import "./chunk-
|
|
37
|
-
import "./chunk-
|
|
38
|
-
import
|
|
36
|
+
} from "./chunk-IMB6FA2F.js";
|
|
37
|
+
import "./chunk-7MJGYPHF.js";
|
|
38
|
+
import "./chunk-XNK5UN2D.js";
|
|
39
|
+
import {
|
|
40
|
+
QUEUES_DIR_NAME,
|
|
41
|
+
getIssuePaths
|
|
42
|
+
} from "./chunk-MAJ6QDRL.js";
|
|
43
|
+
import "./chunk-TJVX42KY.js";
|
|
44
|
+
import "./chunk-PFWHHYEO.js";
|
|
39
45
|
|
|
40
46
|
// src/commands/operations.ts
|
|
41
|
-
import { readdir, readFile } from "fs/promises";
|
|
42
|
-
import { join } from "path";
|
|
43
|
-
async function project() {
|
|
47
|
+
import { readdir, readFile } from "node:fs/promises";
|
|
48
|
+
import { join } from "node:path";
|
|
49
|
+
async function project(json = false) {
|
|
44
50
|
try {
|
|
45
|
-
return await resolveProjectPaths();
|
|
51
|
+
return await resolveProjectPaths(json ? { notice: console.error } : {});
|
|
46
52
|
} catch (err) {
|
|
47
|
-
|
|
53
|
+
const message = `Not inside a usable project: ${err instanceof Error ? err.message : String(err)}`;
|
|
54
|
+
if (json)
|
|
55
|
+
console.log(
|
|
56
|
+
JSON.stringify({
|
|
57
|
+
schemaVersion: 1,
|
|
58
|
+
error: { code: "project_unavailable", message },
|
|
59
|
+
owner: null,
|
|
60
|
+
ownerStale: null,
|
|
61
|
+
issues: [],
|
|
62
|
+
queues: []
|
|
63
|
+
})
|
|
64
|
+
);
|
|
65
|
+
else printError(message);
|
|
48
66
|
return null;
|
|
49
67
|
}
|
|
50
68
|
}
|
|
@@ -55,10 +73,10 @@ async function readJson(path) {
|
|
|
55
73
|
return null;
|
|
56
74
|
}
|
|
57
75
|
}
|
|
58
|
-
async function loadIssueState(
|
|
76
|
+
async function loadIssueState(project2, id) {
|
|
59
77
|
let paths;
|
|
60
78
|
try {
|
|
61
|
-
paths = getIssuePaths(projectId, id);
|
|
79
|
+
paths = project2.storageDriver === "sqlite" ? await resolveIssuePaths(id) : getIssuePaths(project2.projectId, id);
|
|
62
80
|
} catch {
|
|
63
81
|
return null;
|
|
64
82
|
}
|
|
@@ -69,7 +87,7 @@ async function loadIssueState(projectId, id) {
|
|
|
69
87
|
plan = null;
|
|
70
88
|
}
|
|
71
89
|
if (plan === null) return null;
|
|
72
|
-
const snapshot = await readJson(paths.sessionFile);
|
|
90
|
+
const snapshot = project2.storageDriver === "sqlite" ? await latestStoredIssueSnapshot({ projectId: project2.projectId, issueId: id }) : await readJson(paths.sessionFile);
|
|
73
91
|
const phases = plan.noBranch === true ? PIPELINE_PHASES.filter((phase) => phase !== "pr") : [...PIPELINE_PHASES];
|
|
74
92
|
if (plan.prReview?.enabled === true) phases.push("pr-review");
|
|
75
93
|
return {
|
|
@@ -83,13 +101,13 @@ async function loadIssueState(projectId, id) {
|
|
|
83
101
|
async function allIssues(paths) {
|
|
84
102
|
let ids;
|
|
85
103
|
try {
|
|
86
|
-
ids = await readdir(paths.issuesDir);
|
|
104
|
+
ids = paths.storageDriver === "sqlite" ? await listStoredIssueIds({ projectId: paths.projectId }) : await readdir(paths.issuesDir);
|
|
87
105
|
} catch {
|
|
88
106
|
return [];
|
|
89
107
|
}
|
|
90
108
|
const states = [];
|
|
91
109
|
for (const id of ids) {
|
|
92
|
-
const state = await loadIssueState(paths
|
|
110
|
+
const state = await loadIssueState(paths, id);
|
|
93
111
|
if (state !== null) states.push(state);
|
|
94
112
|
}
|
|
95
113
|
return states.sort((a, b) => attemptedAt(b.plan) - attemptedAt(a.plan));
|
|
@@ -99,6 +117,9 @@ function attemptedAt(plan) {
|
|
|
99
117
|
return Number.isNaN(at) ? 0 : at;
|
|
100
118
|
}
|
|
101
119
|
async function allQueues(paths) {
|
|
120
|
+
if (paths.storageDriver === "sqlite") {
|
|
121
|
+
return listStoredQueues({ projectId: paths.projectId });
|
|
122
|
+
}
|
|
102
123
|
const dir = join(paths.projectDir, QUEUES_DIR_NAME);
|
|
103
124
|
let entries;
|
|
104
125
|
try {
|
|
@@ -127,17 +148,16 @@ function formatSeconds(total) {
|
|
|
127
148
|
return `${hours}h ${minutes % 60}m`;
|
|
128
149
|
}
|
|
129
150
|
async function runStatus(issue, options = {}) {
|
|
130
|
-
const paths = await project();
|
|
151
|
+
const paths = await project(options.json);
|
|
131
152
|
if (paths === null) return 1;
|
|
132
153
|
const lock = await readRunLock(paths.runLockFile);
|
|
133
|
-
const issues = issue === void 0 ? await allIssues(paths) : [await loadIssueState(paths
|
|
134
|
-
(state) => state !== null
|
|
135
|
-
);
|
|
154
|
+
const issues = issue === void 0 ? await allIssues(paths) : [await loadIssueState(paths, issue)].filter((state) => state !== null);
|
|
136
155
|
const queues = await allQueues(paths);
|
|
137
156
|
if (options.json === true) {
|
|
138
|
-
|
|
157
|
+
console.log(
|
|
139
158
|
JSON.stringify(
|
|
140
159
|
{
|
|
160
|
+
schemaVersion: 1,
|
|
141
161
|
owner: lock,
|
|
142
162
|
ownerStale: lock === null ? null : isRunLockStale(lock),
|
|
143
163
|
issues: issues.map((state) => ({
|
|
@@ -242,37 +262,43 @@ async function runLogs(issue, options = {}) {
|
|
|
242
262
|
printInfo("No issue in this project has a journal yet.");
|
|
243
263
|
return 0;
|
|
244
264
|
}
|
|
245
|
-
const issuePaths = getIssuePaths(paths.projectId, target);
|
|
246
265
|
const kinds = new Set(options.kind ?? []);
|
|
247
266
|
const tail = options.tail ?? DEFAULT_TAIL;
|
|
248
267
|
const shown = /* @__PURE__ */ new Set();
|
|
249
|
-
const
|
|
250
|
-
|
|
251
|
-
(
|
|
252
|
-
|
|
253
|
-
|
|
268
|
+
const readEntries = async () => {
|
|
269
|
+
if (paths.storageDriver === "sqlite") {
|
|
270
|
+
return (await listStoredIssueEvents({ projectId: paths.projectId, issueId: target })).map(
|
|
271
|
+
({ seq, event }) => ({ seq, event })
|
|
272
|
+
);
|
|
273
|
+
}
|
|
274
|
+
const issuePaths = getIssuePaths(paths.projectId, target);
|
|
275
|
+
const content = `${await readIfPresent(issuePaths.rotatedEventsFile)}${await readIfPresent(issuePaths.eventsFile)}`;
|
|
276
|
+
return parseJournal(content);
|
|
277
|
+
};
|
|
278
|
+
const renderEntries = (entries, limit) => {
|
|
279
|
+
const filtered = entries.filter((entry) => kinds.size === 0 || kinds.has(entry.event.type));
|
|
280
|
+
const slice = limit === null ? filtered : filtered.slice(-limit);
|
|
254
281
|
for (const entry of slice) {
|
|
255
282
|
if (shown.has(entry.seq)) continue;
|
|
256
283
|
shown.add(entry.seq);
|
|
257
284
|
printInfo(formatEvent(entry.seq, entry.event));
|
|
258
285
|
}
|
|
259
286
|
};
|
|
260
|
-
const
|
|
261
|
-
|
|
262
|
-
if (initial === "") {
|
|
287
|
+
const initial = await readEntries();
|
|
288
|
+
if (initial.length === 0) {
|
|
263
289
|
printInfo(
|
|
264
290
|
`Issue #${target} has no journal. Enable it with resilience.journal.enabled or --continuous.`
|
|
265
291
|
);
|
|
266
292
|
return 0;
|
|
267
293
|
}
|
|
268
|
-
|
|
294
|
+
renderEntries(initial, tail);
|
|
269
295
|
if (options.follow !== true) return 0;
|
|
270
296
|
const poll = options.pollMs ?? FOLLOW_POLL_MS;
|
|
271
297
|
const signal = options.signal;
|
|
272
298
|
while (signal === void 0 || !signal.aborted) {
|
|
273
299
|
await sleep(poll, signal);
|
|
274
300
|
if (signal?.aborted === true) break;
|
|
275
|
-
|
|
301
|
+
renderEntries(await readEntries(), null);
|
|
276
302
|
}
|
|
277
303
|
return 0;
|
|
278
304
|
}
|
|
@@ -324,9 +350,9 @@ async function runCancel(issue, options = {}) {
|
|
|
324
350
|
if (paths === null) return 1;
|
|
325
351
|
const target = issue ?? (await allIssues(paths))[0]?.id;
|
|
326
352
|
if (target === void 0) return 0;
|
|
327
|
-
const state = await loadIssueState(paths
|
|
353
|
+
const state = await loadIssueState(paths, target);
|
|
328
354
|
if (state === null || state.plan === null) return 0;
|
|
329
|
-
const { saveTaskPlan, isoNow } = await import("./state-manager-
|
|
355
|
+
const { saveTaskPlan, isoNow } = await import("./state-manager-IGNTD4AB.js");
|
|
330
356
|
await saveTaskPlan(state.paths.tasksFile, {
|
|
331
357
|
...state.plan,
|
|
332
358
|
runState: {
|
|
@@ -374,4 +400,4 @@ export {
|
|
|
374
400
|
runRuns,
|
|
375
401
|
runStatus
|
|
376
402
|
};
|
|
377
|
-
//# sourceMappingURL=operations-
|
|
403
|
+
//# sourceMappingURL=operations-HU5ZFEBA.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/operations.ts"],"sourcesContent":["import { readdir, readFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { parseJournal } from '../core/journal.js';\nimport { PIPELINE_PHASES, PipelineManager, type PipelinePhase } from '../core/pipeline.js';\nimport type { SessionEvent, SessionSnapshot } from '../core/session-state.js';\nimport { loadTaskPlan } from '../core/state-manager.js';\nimport { loadExecutionPlan } from '../execution/plan.js';\nimport type { ExecutionPlan } from '../execution/types.js';\nimport {\n latestStoredIssueSnapshot,\n listStoredIssueEvents,\n listStoredIssueIds,\n listStoredQueues,\n} from '../storage/db/queries.js';\nimport { describeRunLockOwner, isRunLockStale, readRunLock } from '../storage/lock.js';\nimport { getIssuePaths, QUEUES_DIR_NAME } from '../storage/paths.js';\nimport { resolveIssuePaths, resolveProjectPaths } from '../storage/resolve.js';\nimport type { RunLock } from '../storage/schemas.js';\nimport type { TaskPlan } from '../types.js';\nimport { printError, printInfo, printWarning } from '../ui/logger.js';\n\n/**\n * The operation surface of a long run: `status`, `runs`, `logs`, `pause`,\n * `cancel`.\n *\n * The CLI declared thirteen commands and not one of them answered \"what is\n * running\", \"what failed\", or \"stop what you are doing\". During a six-hour\n * unattended execution the only way to find out was to read JSON by hand, and\n * the only way to stop it was to find the pid.\n *\n * Everything here **reads state that already exists** — `run.lock`,\n * `tasks.json`, `session.json`, `execution-plan.json`, `events.jsonl` — and\n * writes nothing except the two control commands, which do the one thing a\n * person cannot do from outside: ask the owner to stop, gracefully.\n */\n\ninterface ProjectPaths {\n projectId: string;\n storageDriver: 'sqlite' | 'json';\n projectDir: string;\n issuesDir: string;\n runLockFile: string;\n}\n\n/** One issue's state, assembled from every artifact that knows part of it. */\ninterface IssueState {\n id: string;\n plan: TaskPlan | null;\n snapshot: SessionSnapshot | null;\n nextPhase: PipelinePhase | null;\n paths: ReturnType<typeof getIssuePaths>;\n}\n\nasync function project(json = false): Promise<ProjectPaths | null> {\n try {\n return await resolveProjectPaths(json ? { notice: console.error } : {});\n } catch (err) {\n const message = `Not inside a usable project: ${err instanceof Error ? err.message : String(err)}`;\n if (json)\n console.log(\n JSON.stringify({\n schemaVersion: 1,\n error: { code: 'project_unavailable', message },\n owner: null,\n ownerStale: null,\n issues: [],\n queues: [],\n }),\n );\n else printError(message);\n return null;\n }\n}\n\nasync function readJson<T>(path: string): Promise<T | null> {\n try {\n return JSON.parse(await readFile(path, 'utf-8')) as T;\n } catch {\n return null;\n }\n}\n\nasync function loadIssueState(project: ProjectPaths, id: string): Promise<IssueState | null> {\n let paths: ReturnType<typeof getIssuePaths>;\n try {\n paths =\n project.storageDriver === 'sqlite'\n ? await resolveIssuePaths(id)\n : getIssuePaths(project.projectId, id);\n } catch {\n return null;\n }\n\n let plan: TaskPlan | null = null;\n try {\n plan = await loadTaskPlan(paths.tasksFile);\n } catch {\n plan = null;\n }\n if (plan === null) return null;\n\n const snapshot =\n project.storageDriver === 'sqlite'\n ? await latestStoredIssueSnapshot({ projectId: project.projectId, issueId: id })\n : await readJson<SessionSnapshot>(paths.sessionFile);\n const phases: PipelinePhase[] =\n plan.noBranch === true\n ? PIPELINE_PHASES.filter((phase) => phase !== 'pr')\n : [...PIPELINE_PHASES];\n if (plan.prReview?.enabled === true) phases.push('pr-review');\n\n return {\n id,\n plan,\n snapshot,\n nextPhase: new PipelineManager(plan, paths.tasksFile, phases).getNextPhase(),\n paths,\n };\n}\n\n/** Every issue this project has state for, newest attempt first. */\nasync function allIssues(paths: ProjectPaths): Promise<IssueState[]> {\n let ids: string[];\n try {\n ids =\n paths.storageDriver === 'sqlite'\n ? await listStoredIssueIds({ projectId: paths.projectId })\n : await readdir(paths.issuesDir);\n } catch {\n return [];\n }\n\n const states: IssueState[] = [];\n for (const id of ids) {\n const state = await loadIssueState(paths, id);\n if (state !== null) states.push(state);\n }\n return states.sort((a, b) => attemptedAt(b.plan) - attemptedAt(a.plan));\n}\n\nfunction attemptedAt(plan: TaskPlan | null): number {\n const at = Date.parse(plan?.lastAttemptAt ?? '');\n return Number.isNaN(at) ? 0 : at;\n}\n\n/** Every queue plan of the project. */\nasync function allQueues(paths: ProjectPaths): Promise<ExecutionPlan[]> {\n if (paths.storageDriver === 'sqlite') {\n return listStoredQueues({ projectId: paths.projectId });\n }\n const dir = join(paths.projectDir, QUEUES_DIR_NAME);\n let entries: string[];\n try {\n entries = await readdir(dir);\n } catch {\n return [];\n }\n\n const plans: ExecutionPlan[] = [];\n for (const entry of entries) {\n const plan = await loadExecutionPlan(join(dir, entry, 'execution-plan.json'));\n if (plan !== null) plans.push(plan);\n }\n return plans;\n}\n\n/** `2m 13s ago`, or `never`. */\nfunction since(at: string | null | undefined, now = Date.now()): string {\n if (at === null || at === undefined || at === '') return 'never';\n const parsed = Date.parse(at);\n if (Number.isNaN(parsed)) return 'unknown';\n return `${formatSeconds(Math.max(0, Math.round((now - parsed) / 1000)))} ago`;\n}\n\nfunction formatSeconds(total: number): string {\n if (total < 60) return `${total}s`;\n const minutes = Math.floor(total / 60);\n if (minutes < 60) return `${minutes}m ${total % 60}s`;\n const hours = Math.floor(minutes / 60);\n return `${hours}h ${minutes % 60}m`;\n}\n\n/* ── status ─────────────────────────────────────────────────────────────── */\n\nexport interface StatusOptions {\n /** Emit the assembled state as JSON instead of a screen. */\n json?: boolean;\n}\n\n/**\n * One screen answering \"what is happening right now\".\n *\n * The three artifacts each know part of it and none knows all of it: the lock\n * knows *who* and *how long since it last said anything*, the task plan knows\n * *which phase and which attempt*, and the queue plan knows *where in the\n * queue*. Reading them together is the whole command.\n */\nexport async function runStatus(issue?: string, options: StatusOptions = {}): Promise<number> {\n const paths = await project(options.json);\n if (paths === null) return 1;\n\n const lock = await readRunLock(paths.runLockFile);\n const issues =\n issue === undefined\n ? await allIssues(paths)\n : [await loadIssueState(paths, issue)].filter((state): state is IssueState => state !== null);\n const queues = await allQueues(paths);\n\n if (options.json === true) {\n console.log(\n JSON.stringify(\n {\n schemaVersion: 1,\n owner: lock,\n ownerStale: lock === null ? null : isRunLockStale(lock),\n issues: issues.map((state) => ({\n id: state.id,\n issueStatus: state.plan?.issueStatus ?? null,\n runState: state.plan?.runState ?? null,\n nextPhase: state.nextPhase,\n branch: state.plan?.branchName ?? null,\n lastActivityAt: state.snapshot?.updatedAt ?? state.plan?.lastAttemptAt ?? null,\n retries: state.snapshot?.execution.retries ?? null,\n })),\n queues: queues.map((plan) => ({\n id: plan.id,\n status: plan.status,\n issues: plan.issues.map((entry) => ({\n id: entry.id,\n status: entry.status,\n attempts: entry.attempts,\n blockedReason: entry.blockedReason,\n })),\n })),\n },\n null,\n 2,\n ),\n );\n return 0;\n }\n\n printOwner(lock);\n\n if (issues.length === 0) {\n printInfo('No issue in this project has any state yet.');\n return 0;\n }\n\n for (const state of issues.slice(0, issue === undefined ? 5 : 1)) {\n printIssueLine(state);\n }\n\n for (const plan of queues) {\n if (plan.status === 'completed') continue;\n printInfo(`Queue ${plan.id} — ${plan.status}`);\n for (const entry of plan.issues) {\n const attempts = entry.attempts > 0 ? `, ${entry.attempts} attempt(s)` : '';\n const blocked = entry.blockedReason === null ? '' : ` — ${entry.blockedReason}`;\n printInfo(` #${entry.id} ${entry.status}${attempts}${blocked}`);\n }\n }\n\n return 0;\n}\n\nfunction printOwner(lock: RunLock | null): void {\n if (lock === null) {\n printInfo('Nothing is running in this project (no run.lock).');\n return;\n }\n if (isRunLockStale(lock)) {\n printWarning(`A stale lock is left behind: ${describeRunLockOwner(lock)}.`);\n printInfo('It will be taken over by the next run or resume.');\n return;\n }\n printInfo(`Running: ${describeRunLockOwner(lock)}`);\n printInfo(`Last heartbeat ${since(lock.lastHeartbeatAt)}.`);\n}\n\nfunction printIssueLine(state: IssueState): void {\n const plan = state.plan;\n const run = plan?.runState;\n const phase = run?.currentPhase ?? state.nextPhase ?? '—';\n const attempt = run !== undefined && run.attempt > 0 ? `, attempt ${run.attempt}` : '';\n const retries = state.snapshot?.execution.retries;\n const retryLine = retries === undefined || retries === 0 ? '' : `, ${retries} retry(ies)`;\n const activity = since(state.snapshot?.updatedAt ?? plan?.lastAttemptAt);\n\n printInfo(\n `#${state.id} ${plan?.issueStatus ?? 'unknown'}${run === undefined ? '' : ` / ${run.status}`}` +\n ` — phase ${phase}${attempt}${retryLine}; last activity ${activity}`,\n );\n if (run?.blockedReason !== null && run?.blockedReason !== undefined) {\n printWarning(` Blocked: ${run.blockedReason}`);\n }\n}\n\n/* ── runs ───────────────────────────────────────────────────────────────── */\n\n/**\n * The history: what has been run in this project, how it ended, and why.\n *\n * Deliberately built from the same artifacts `status` reads rather than from a\n * separate history file — a second record of the truth is a second thing that\n * can be wrong.\n */\nexport async function runRuns(): Promise<number> {\n const paths = await project();\n if (paths === null) return 1;\n\n const issues = await allIssues(paths);\n if (issues.length === 0) {\n printInfo('No runs recorded for this project yet.');\n return 0;\n }\n\n for (const state of issues) {\n const plan = state.plan;\n if (plan === null) continue;\n const duration =\n state.snapshot?.elapsedSeconds === null || state.snapshot?.elapsedSeconds === undefined\n ? '—'\n : formatSeconds(state.snapshot.elapsedSeconds);\n const cause =\n plan.lastError === null ? '' : ` — ${plan.lastError.message.split('\\n')[0] ?? ''}`;\n\n printInfo(\n `#${state.id.padEnd(6)} ${plan.issueStatus.padEnd(12)} ${duration.padEnd(10)} ` +\n `last attempt ${since(plan.lastAttemptAt)}${cause}`,\n );\n }\n return 0;\n}\n\n/* ── logs ───────────────────────────────────────────────────────────────── */\n\nexport interface LogsOptions {\n /** Only these event types (`retry`, `phase:end`, …). Empty means all. */\n kind?: string[];\n /** Keep reading as the journal grows. */\n follow?: boolean;\n /** How many entries to show before following. */\n tail?: number;\n /** Polling interval of `--follow`, for tests. */\n pollMs?: number;\n /** Stops `--follow`. */\n signal?: AbortSignal;\n}\n\nconst DEFAULT_TAIL = 50;\nconst FOLLOW_POLL_MS = 1000;\n\n/**\n * Read the journal, filtered and readable.\n *\n * The journal is the only record that keeps *what happened in which order* —\n * the snapshot folded it away — so this is the command that answers \"what was\n * it doing at 3am\". `--kind retry,failover` is the filter that matters most:\n * on a six-hour run those are a handful of lines among thousands.\n */\nexport async function runLogs(issue?: string, options: LogsOptions = {}): Promise<number> {\n const paths = await project();\n if (paths === null) return 1;\n\n const target = issue ?? (await allIssues(paths))[0]?.id;\n if (target === undefined) {\n printInfo('No issue in this project has a journal yet.');\n return 0;\n }\n\n const kinds = new Set(options.kind ?? []);\n const tail = options.tail ?? DEFAULT_TAIL;\n\n const shown = new Set<number>();\n const readEntries = async (): Promise<Array<{ seq: number; event: SessionEvent }>> => {\n if (paths.storageDriver === 'sqlite') {\n return (await listStoredIssueEvents({ projectId: paths.projectId, issueId: target })).map(\n ({ seq, event }) => ({ seq, event: event as SessionEvent }),\n );\n }\n const issuePaths = getIssuePaths(paths.projectId, target);\n const content = `${await readIfPresent(issuePaths.rotatedEventsFile)}${await readIfPresent(issuePaths.eventsFile)}`;\n return parseJournal(content);\n };\n\n const renderEntries = (\n entries: Array<{ seq: number; event: SessionEvent }>,\n limit: number | null,\n ) => {\n const filtered = entries.filter((entry) => kinds.size === 0 || kinds.has(entry.event.type));\n const slice = limit === null ? filtered : filtered.slice(-limit);\n for (const entry of slice) {\n if (shown.has(entry.seq)) continue;\n shown.add(entry.seq);\n printInfo(formatEvent(entry.seq, entry.event));\n }\n };\n\n const initial = await readEntries();\n if (initial.length === 0) {\n printInfo(\n `Issue #${target} has no journal. Enable it with resilience.journal.enabled or --continuous.`,\n );\n return 0;\n }\n renderEntries(initial, tail);\n\n if (options.follow !== true) return 0;\n\n const poll = options.pollMs ?? FOLLOW_POLL_MS;\n const signal = options.signal;\n while (signal === undefined || !signal.aborted) {\n await sleep(poll, signal);\n if (signal?.aborted === true) break;\n renderEntries(await readEntries(), null);\n }\n return 0;\n}\n\nfunction formatEvent(seq: number, event: SessionEvent): string {\n const at = 'at' in event ? event.at : '';\n const detail = describeEvent(event);\n return `${String(seq).padStart(5)} ${at} ${event.type}${detail === '' ? '' : ` — ${detail}`}`;\n}\n\nfunction describeEvent(event: SessionEvent): string {\n switch (event.type) {\n case 'phase:start':\n return event.phase;\n case 'phase:end':\n return `${event.phase} ${event.success ? 'ok' : `failed: ${event.error ?? ''}`}`;\n case 'retry':\n return `attempt ${event.attempt}, ${event.delaySeconds}s — ${event.reason}`;\n case 'log':\n return `${event.level}: ${event.message}`;\n case 'session:end':\n return event.status;\n default:\n return '';\n }\n}\n\nasync function readIfPresent(path: string): Promise<string> {\n try {\n return await readFile(path, 'utf-8');\n } catch {\n return '';\n }\n}\n\nfunction sleep(ms: number, signal?: AbortSignal): Promise<void> {\n return new Promise((resolve) => {\n const timer = setTimeout(resolve, ms);\n timer.unref?.();\n signal?.addEventListener('abort', () => {\n clearTimeout(timer);\n resolve();\n });\n });\n}\n\n/* ── pause and cancel ───────────────────────────────────────────────────── */\n\nexport interface ControlOptions {\n /** Injectable signaller, so a test never signals a real process. */\n signalProcess?: (pid: number, signal: NodeJS.Signals) => void;\n}\n\n/**\n * Ask the running owner to stop, gracefully.\n *\n * `SIGTERM` is the whole implementation, and deliberately so: the owner already\n * knows how to stop well (`core/shutdown.ts` writes the checkpoint, stops the\n * agent with a grace period and closes the journal). Reimplementing any of that\n * from outside the process would be a second, worse version of it.\n */\nexport async function runPause(options: ControlOptions = {}): Promise<number> {\n return stopOwner('paused', options);\n}\n\n/**\n * Stop the run and mark it so a later `resume` does not pick it up silently.\n *\n * The difference from `pause` is not in how the process ends — it ends the same\n * way — but in what the state says afterwards: a paused run is meant to be\n * resumed, a cancelled one is not.\n */\nexport async function runCancel(issue?: string, options: ControlOptions = {}): Promise<number> {\n const code = await stopOwner('cancelled', options);\n if (code !== 0) return code;\n\n const paths = await project();\n if (paths === null) return 1;\n\n const target = issue ?? (await allIssues(paths))[0]?.id;\n if (target === undefined) return 0;\n\n const state = await loadIssueState(paths, target);\n if (state === null || state.plan === null) return 0;\n\n const { saveTaskPlan, isoNow } = await import('../core/state-manager.js');\n await saveTaskPlan(state.paths.tasksFile, {\n ...state.plan,\n runState: {\n currentPhase: state.plan.runState?.currentPhase ?? null,\n attempt: state.plan.runState?.attempt ?? 0,\n owner: null,\n status: 'blocked',\n blockedReason: 'Cancelled by the user',\n lastHeartbeatAt: isoNow(),\n },\n });\n printInfo(`Issue #${target} is marked cancelled. A resume will report it instead of running it.`);\n return 0;\n}\n\nasync function stopOwner(intent: string, options: ControlOptions): Promise<number> {\n const paths = await project();\n if (paths === null) return 1;\n\n const lock = await readRunLock(paths.runLockFile);\n if (lock === null) {\n printInfo('Nothing is running in this project.');\n return 0;\n }\n if (isRunLockStale(lock)) {\n printWarning(`The lock is stale (${describeRunLockOwner(lock)}); nothing to stop.`);\n return 0;\n }\n\n const send =\n options.signalProcess ?? ((pid: number, signal: NodeJS.Signals) => process.kill(pid, signal));\n try {\n send(lock.pid, 'SIGTERM');\n } catch (err) {\n printError(\n `Could not signal pid ${lock.pid}: ${err instanceof Error ? err.message : String(err)}`,\n );\n return 1;\n }\n\n printInfo(\n `Asked pid ${lock.pid} to stop (${intent}). It writes a checkpoint, stops the agent and closes its journal before exiting.`,\n );\n return 0;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,SAAS,SAAS,gBAAgB;AAClC,SAAS,YAAY;AAoDrB,eAAe,QAAQ,OAAO,OAAqC;AACjE,MAAI;AACF,WAAO,MAAM,oBAAoB,OAAO,EAAE,QAAQ,QAAQ,MAAM,IAAI,CAAC,CAAC;AAAA,EACxE,SAAS,KAAK;AACZ,UAAM,UAAU,gCAAgC,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAChG,QAAI;AACF,cAAQ;AAAA,QACN,KAAK,UAAU;AAAA,UACb,eAAe;AAAA,UACf,OAAO,EAAE,MAAM,uBAAuB,QAAQ;AAAA,UAC9C,OAAO;AAAA,UACP,YAAY;AAAA,UACZ,QAAQ,CAAC;AAAA,UACT,QAAQ,CAAC;AAAA,QACX,CAAC;AAAA,MACH;AAAA,QACG,YAAW,OAAO;AACvB,WAAO;AAAA,EACT;AACF;AAEA,eAAe,SAAY,MAAiC;AAC1D,MAAI;AACF,WAAO,KAAK,MAAM,MAAM,SAAS,MAAM,OAAO,CAAC;AAAA,EACjD,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,eAAe,eAAeA,UAAuB,IAAwC;AAC3F,MAAI;AACJ,MAAI;AACF,YACEA,SAAQ,kBAAkB,WACtB,MAAM,kBAAkB,EAAE,IAC1B,cAAcA,SAAQ,WAAW,EAAE;AAAA,EAC3C,QAAQ;AACN,WAAO;AAAA,EACT;AAEA,MAAI,OAAwB;AAC5B,MAAI;AACF,WAAO,MAAM,aAAa,MAAM,SAAS;AAAA,EAC3C,QAAQ;AACN,WAAO;AAAA,EACT;AACA,MAAI,SAAS,KAAM,QAAO;AAE1B,QAAM,WACJA,SAAQ,kBAAkB,WACtB,MAAM,0BAA0B,EAAE,WAAWA,SAAQ,WAAW,SAAS,GAAG,CAAC,IAC7E,MAAM,SAA0B,MAAM,WAAW;AACvD,QAAM,SACJ,KAAK,aAAa,OACd,gBAAgB,OAAO,CAAC,UAAU,UAAU,IAAI,IAChD,CAAC,GAAG,eAAe;AACzB,MAAI,KAAK,UAAU,YAAY,KAAM,QAAO,KAAK,WAAW;AAE5D,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW,IAAI,gBAAgB,MAAM,MAAM,WAAW,MAAM,EAAE,aAAa;AAAA,IAC3E;AAAA,EACF;AACF;AAGA,eAAe,UAAU,OAA4C;AACnE,MAAI;AACJ,MAAI;AACF,UACE,MAAM,kBAAkB,WACpB,MAAM,mBAAmB,EAAE,WAAW,MAAM,UAAU,CAAC,IACvD,MAAM,QAAQ,MAAM,SAAS;AAAA,EACrC,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,SAAuB,CAAC;AAC9B,aAAW,MAAM,KAAK;AACpB,UAAM,QAAQ,MAAM,eAAe,OAAO,EAAE;AAC5C,QAAI,UAAU,KAAM,QAAO,KAAK,KAAK;AAAA,EACvC;AACA,SAAO,OAAO,KAAK,CAAC,GAAG,MAAM,YAAY,EAAE,IAAI,IAAI,YAAY,EAAE,IAAI,CAAC;AACxE;AAEA,SAAS,YAAY,MAA+B;AAClD,QAAM,KAAK,KAAK,MAAM,MAAM,iBAAiB,EAAE;AAC/C,SAAO,OAAO,MAAM,EAAE,IAAI,IAAI;AAChC;AAGA,eAAe,UAAU,OAA+C;AACtE,MAAI,MAAM,kBAAkB,UAAU;AACpC,WAAO,iBAAiB,EAAE,WAAW,MAAM,UAAU,CAAC;AAAA,EACxD;AACA,QAAM,MAAM,KAAK,MAAM,YAAY,eAAe;AAClD,MAAI;AACJ,MAAI;AACF,cAAU,MAAM,QAAQ,GAAG;AAAA,EAC7B,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,QAAyB,CAAC;AAChC,aAAW,SAAS,SAAS;AAC3B,UAAM,OAAO,MAAM,kBAAkB,KAAK,KAAK,OAAO,qBAAqB,CAAC;AAC5E,QAAI,SAAS,KAAM,OAAM,KAAK,IAAI;AAAA,EACpC;AACA,SAAO;AACT;AAGA,SAAS,MAAM,IAA+B,MAAM,KAAK,IAAI,GAAW;AACtE,MAAI,OAAO,QAAQ,OAAO,UAAa,OAAO,GAAI,QAAO;AACzD,QAAM,SAAS,KAAK,MAAM,EAAE;AAC5B,MAAI,OAAO,MAAM,MAAM,EAAG,QAAO;AACjC,SAAO,GAAG,cAAc,KAAK,IAAI,GAAG,KAAK,OAAO,MAAM,UAAU,GAAI,CAAC,CAAC,CAAC;AACzE;AAEA,SAAS,cAAc,OAAuB;AAC5C,MAAI,QAAQ,GAAI,QAAO,GAAG,KAAK;AAC/B,QAAM,UAAU,KAAK,MAAM,QAAQ,EAAE;AACrC,MAAI,UAAU,GAAI,QAAO,GAAG,OAAO,KAAK,QAAQ,EAAE;AAClD,QAAM,QAAQ,KAAK,MAAM,UAAU,EAAE;AACrC,SAAO,GAAG,KAAK,KAAK,UAAU,EAAE;AAClC;AAiBA,eAAsB,UAAU,OAAgB,UAAyB,CAAC,GAAoB;AAC5F,QAAM,QAAQ,MAAM,QAAQ,QAAQ,IAAI;AACxC,MAAI,UAAU,KAAM,QAAO;AAE3B,QAAM,OAAO,MAAM,YAAY,MAAM,WAAW;AAChD,QAAM,SACJ,UAAU,SACN,MAAM,UAAU,KAAK,IACrB,CAAC,MAAM,eAAe,OAAO,KAAK,CAAC,EAAE,OAAO,CAAC,UAA+B,UAAU,IAAI;AAChG,QAAM,SAAS,MAAM,UAAU,KAAK;AAEpC,MAAI,QAAQ,SAAS,MAAM;AACzB,YAAQ;AAAA,MACN,KAAK;AAAA,QACH;AAAA,UACE,eAAe;AAAA,UACf,OAAO;AAAA,UACP,YAAY,SAAS,OAAO,OAAO,eAAe,IAAI;AAAA,UACtD,QAAQ,OAAO,IAAI,CAAC,WAAW;AAAA,YAC7B,IAAI,MAAM;AAAA,YACV,aAAa,MAAM,MAAM,eAAe;AAAA,YACxC,UAAU,MAAM,MAAM,YAAY;AAAA,YAClC,WAAW,MAAM;AAAA,YACjB,QAAQ,MAAM,MAAM,cAAc;AAAA,YAClC,gBAAgB,MAAM,UAAU,aAAa,MAAM,MAAM,iBAAiB;AAAA,YAC1E,SAAS,MAAM,UAAU,UAAU,WAAW;AAAA,UAChD,EAAE;AAAA,UACF,QAAQ,OAAO,IAAI,CAAC,UAAU;AAAA,YAC5B,IAAI,KAAK;AAAA,YACT,QAAQ,KAAK;AAAA,YACb,QAAQ,KAAK,OAAO,IAAI,CAAC,WAAW;AAAA,cAClC,IAAI,MAAM;AAAA,cACV,QAAQ,MAAM;AAAA,cACd,UAAU,MAAM;AAAA,cAChB,eAAe,MAAM;AAAA,YACvB,EAAE;AAAA,UACJ,EAAE;AAAA,QACJ;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAEA,aAAW,IAAI;AAEf,MAAI,OAAO,WAAW,GAAG;AACvB,cAAU,6CAA6C;AACvD,WAAO;AAAA,EACT;AAEA,aAAW,SAAS,OAAO,MAAM,GAAG,UAAU,SAAY,IAAI,CAAC,GAAG;AAChE,mBAAe,KAAK;AAAA,EACtB;AAEA,aAAW,QAAQ,QAAQ;AACzB,QAAI,KAAK,WAAW,YAAa;AACjC,cAAU,SAAS,KAAK,EAAE,WAAM,KAAK,MAAM,EAAE;AAC7C,eAAW,SAAS,KAAK,QAAQ;AAC/B,YAAM,WAAW,MAAM,WAAW,IAAI,KAAK,MAAM,QAAQ,gBAAgB;AACzE,YAAM,UAAU,MAAM,kBAAkB,OAAO,KAAK,WAAM,MAAM,aAAa;AAC7E,gBAAU,MAAM,MAAM,EAAE,IAAI,MAAM,MAAM,GAAG,QAAQ,GAAG,OAAO,EAAE;AAAA,IACjE;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,WAAW,MAA4B;AAC9C,MAAI,SAAS,MAAM;AACjB,cAAU,mDAAmD;AAC7D;AAAA,EACF;AACA,MAAI,eAAe,IAAI,GAAG;AACxB,iBAAa,gCAAgC,qBAAqB,IAAI,CAAC,GAAG;AAC1E,cAAU,kDAAkD;AAC5D;AAAA,EACF;AACA,YAAU,YAAY,qBAAqB,IAAI,CAAC,EAAE;AAClD,YAAU,kBAAkB,MAAM,KAAK,eAAe,CAAC,GAAG;AAC5D;AAEA,SAAS,eAAe,OAAyB;AAC/C,QAAM,OAAO,MAAM;AACnB,QAAM,MAAM,MAAM;AAClB,QAAM,QAAQ,KAAK,gBAAgB,MAAM,aAAa;AACtD,QAAM,UAAU,QAAQ,UAAa,IAAI,UAAU,IAAI,aAAa,IAAI,OAAO,KAAK;AACpF,QAAM,UAAU,MAAM,UAAU,UAAU;AAC1C,QAAM,YAAY,YAAY,UAAa,YAAY,IAAI,KAAK,KAAK,OAAO;AAC5E,QAAM,WAAW,MAAM,MAAM,UAAU,aAAa,MAAM,aAAa;AAEvE;AAAA,IACE,IAAI,MAAM,EAAE,IAAI,MAAM,eAAe,SAAS,GAAG,QAAQ,SAAY,KAAK,MAAM,IAAI,MAAM,EAAE,iBAC9E,KAAK,GAAG,OAAO,GAAG,SAAS,mBAAmB,QAAQ;AAAA,EACtE;AACA,MAAI,KAAK,kBAAkB,QAAQ,KAAK,kBAAkB,QAAW;AACnE,iBAAa,cAAc,IAAI,aAAa,EAAE;AAAA,EAChD;AACF;AAWA,eAAsB,UAA2B;AAC/C,QAAM,QAAQ,MAAM,QAAQ;AAC5B,MAAI,UAAU,KAAM,QAAO;AAE3B,QAAM,SAAS,MAAM,UAAU,KAAK;AACpC,MAAI,OAAO,WAAW,GAAG;AACvB,cAAU,wCAAwC;AAClD,WAAO;AAAA,EACT;AAEA,aAAW,SAAS,QAAQ;AAC1B,UAAM,OAAO,MAAM;AACnB,QAAI,SAAS,KAAM;AACnB,UAAM,WACJ,MAAM,UAAU,mBAAmB,QAAQ,MAAM,UAAU,mBAAmB,SAC1E,WACA,cAAc,MAAM,SAAS,cAAc;AACjD,UAAM,QACJ,KAAK,cAAc,OAAO,KAAK,WAAM,KAAK,UAAU,QAAQ,MAAM,IAAI,EAAE,CAAC,KAAK,EAAE;AAElF;AAAA,MACE,IAAI,MAAM,GAAG,OAAO,CAAC,CAAC,IAAI,KAAK,YAAY,OAAO,EAAE,CAAC,IAAI,SAAS,OAAO,EAAE,CAAC,iBAC1D,MAAM,KAAK,aAAa,CAAC,GAAG,KAAK;AAAA,IACrD;AAAA,EACF;AACA,SAAO;AACT;AAiBA,IAAM,eAAe;AACrB,IAAM,iBAAiB;AAUvB,eAAsB,QAAQ,OAAgB,UAAuB,CAAC,GAAoB;AACxF,QAAM,QAAQ,MAAM,QAAQ;AAC5B,MAAI,UAAU,KAAM,QAAO;AAE3B,QAAM,SAAS,UAAU,MAAM,UAAU,KAAK,GAAG,CAAC,GAAG;AACrD,MAAI,WAAW,QAAW;AACxB,cAAU,6CAA6C;AACvD,WAAO;AAAA,EACT;AAEA,QAAM,QAAQ,IAAI,IAAI,QAAQ,QAAQ,CAAC,CAAC;AACxC,QAAM,OAAO,QAAQ,QAAQ;AAE7B,QAAM,QAAQ,oBAAI,IAAY;AAC9B,QAAM,cAAc,YAAkE;AACpF,QAAI,MAAM,kBAAkB,UAAU;AACpC,cAAQ,MAAM,sBAAsB,EAAE,WAAW,MAAM,WAAW,SAAS,OAAO,CAAC,GAAG;AAAA,QACpF,CAAC,EAAE,KAAK,MAAM,OAAO,EAAE,KAAK,MAA6B;AAAA,MAC3D;AAAA,IACF;AACA,UAAM,aAAa,cAAc,MAAM,WAAW,MAAM;AACxD,UAAM,UAAU,GAAG,MAAM,cAAc,WAAW,iBAAiB,CAAC,GAAG,MAAM,cAAc,WAAW,UAAU,CAAC;AACjH,WAAO,aAAa,OAAO;AAAA,EAC7B;AAEA,QAAM,gBAAgB,CACpB,SACA,UACG;AACH,UAAM,WAAW,QAAQ,OAAO,CAAC,UAAU,MAAM,SAAS,KAAK,MAAM,IAAI,MAAM,MAAM,IAAI,CAAC;AAC1F,UAAM,QAAQ,UAAU,OAAO,WAAW,SAAS,MAAM,CAAC,KAAK;AAC/D,eAAW,SAAS,OAAO;AACzB,UAAI,MAAM,IAAI,MAAM,GAAG,EAAG;AAC1B,YAAM,IAAI,MAAM,GAAG;AACnB,gBAAU,YAAY,MAAM,KAAK,MAAM,KAAK,CAAC;AAAA,IAC/C;AAAA,EACF;AAEA,QAAM,UAAU,MAAM,YAAY;AAClC,MAAI,QAAQ,WAAW,GAAG;AACxB;AAAA,MACE,UAAU,MAAM;AAAA,IAClB;AACA,WAAO;AAAA,EACT;AACA,gBAAc,SAAS,IAAI;AAE3B,MAAI,QAAQ,WAAW,KAAM,QAAO;AAEpC,QAAM,OAAO,QAAQ,UAAU;AAC/B,QAAM,SAAS,QAAQ;AACvB,SAAO,WAAW,UAAa,CAAC,OAAO,SAAS;AAC9C,UAAM,MAAM,MAAM,MAAM;AACxB,QAAI,QAAQ,YAAY,KAAM;AAC9B,kBAAc,MAAM,YAAY,GAAG,IAAI;AAAA,EACzC;AACA,SAAO;AACT;AAEA,SAAS,YAAY,KAAa,OAA6B;AAC7D,QAAM,KAAK,QAAQ,QAAQ,MAAM,KAAK;AACtC,QAAM,SAAS,cAAc,KAAK;AAClC,SAAO,GAAG,OAAO,GAAG,EAAE,SAAS,CAAC,CAAC,IAAI,EAAE,IAAI,MAAM,IAAI,GAAG,WAAW,KAAK,KAAK,WAAM,MAAM,EAAE;AAC7F;AAEA,SAAS,cAAc,OAA6B;AAClD,UAAQ,MAAM,MAAM;AAAA,IAClB,KAAK;AACH,aAAO,MAAM;AAAA,IACf,KAAK;AACH,aAAO,GAAG,MAAM,KAAK,IAAI,MAAM,UAAU,OAAO,WAAW,MAAM,SAAS,EAAE,EAAE;AAAA,IAChF,KAAK;AACH,aAAO,WAAW,MAAM,OAAO,KAAK,MAAM,YAAY,YAAO,MAAM,MAAM;AAAA,IAC3E,KAAK;AACH,aAAO,GAAG,MAAM,KAAK,KAAK,MAAM,OAAO;AAAA,IACzC,KAAK;AACH,aAAO,MAAM;AAAA,IACf;AACE,aAAO;AAAA,EACX;AACF;AAEA,eAAe,cAAc,MAA+B;AAC1D,MAAI;AACF,WAAO,MAAM,SAAS,MAAM,OAAO;AAAA,EACrC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,MAAM,IAAY,QAAqC;AAC9D,SAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,UAAM,QAAQ,WAAW,SAAS,EAAE;AACpC,UAAM,QAAQ;AACd,YAAQ,iBAAiB,SAAS,MAAM;AACtC,mBAAa,KAAK;AAClB,cAAQ;AAAA,IACV,CAAC;AAAA,EACH,CAAC;AACH;AAiBA,eAAsB,SAAS,UAA0B,CAAC,GAAoB;AAC5E,SAAO,UAAU,UAAU,OAAO;AACpC;AASA,eAAsB,UAAU,OAAgB,UAA0B,CAAC,GAAoB;AAC7F,QAAM,OAAO,MAAM,UAAU,aAAa,OAAO;AACjD,MAAI,SAAS,EAAG,QAAO;AAEvB,QAAM,QAAQ,MAAM,QAAQ;AAC5B,MAAI,UAAU,KAAM,QAAO;AAE3B,QAAM,SAAS,UAAU,MAAM,UAAU,KAAK,GAAG,CAAC,GAAG;AACrD,MAAI,WAAW,OAAW,QAAO;AAEjC,QAAM,QAAQ,MAAM,eAAe,OAAO,MAAM;AAChD,MAAI,UAAU,QAAQ,MAAM,SAAS,KAAM,QAAO;AAElD,QAAM,EAAE,cAAc,OAAO,IAAI,MAAM,OAAO,6BAA0B;AACxE,QAAM,aAAa,MAAM,MAAM,WAAW;AAAA,IACxC,GAAG,MAAM;AAAA,IACT,UAAU;AAAA,MACR,cAAc,MAAM,KAAK,UAAU,gBAAgB;AAAA,MACnD,SAAS,MAAM,KAAK,UAAU,WAAW;AAAA,MACzC,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,eAAe;AAAA,MACf,iBAAiB,OAAO;AAAA,IAC1B;AAAA,EACF,CAAC;AACD,YAAU,UAAU,MAAM,sEAAsE;AAChG,SAAO;AACT;AAEA,eAAe,UAAU,QAAgB,SAA0C;AACjF,QAAM,QAAQ,MAAM,QAAQ;AAC5B,MAAI,UAAU,KAAM,QAAO;AAE3B,QAAM,OAAO,MAAM,YAAY,MAAM,WAAW;AAChD,MAAI,SAAS,MAAM;AACjB,cAAU,qCAAqC;AAC/C,WAAO;AAAA,EACT;AACA,MAAI,eAAe,IAAI,GAAG;AACxB,iBAAa,sBAAsB,qBAAqB,IAAI,CAAC,qBAAqB;AAClF,WAAO;AAAA,EACT;AAEA,QAAM,OACJ,QAAQ,kBAAkB,CAAC,KAAa,WAA2B,QAAQ,KAAK,KAAK,MAAM;AAC7F,MAAI;AACF,SAAK,KAAK,KAAK,SAAS;AAAA,EAC1B,SAAS,KAAK;AACZ;AAAA,MACE,wBAAwB,KAAK,GAAG,KAAK,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,IACvF;AACA,WAAO;AAAA,EACT;AAEA;AAAA,IACE,aAAa,KAAK,GAAG,aAAa,MAAM;AAAA,EAC1C;AACA,SAAO;AACT;","names":["project"]}
|
|
@@ -4,15 +4,14 @@ import {
|
|
|
4
4
|
cursorPermissionsPath,
|
|
5
5
|
cursorStorageGranted,
|
|
6
6
|
ensureCursorStorageGrant
|
|
7
|
-
} from "./chunk-
|
|
8
|
-
import "./chunk-
|
|
9
|
-
import "./chunk-
|
|
10
|
-
import "./chunk-
|
|
11
|
-
import "./chunk-3R27MJ5R.js";
|
|
7
|
+
} from "./chunk-DXH4TQRB.js";
|
|
8
|
+
import "./chunk-MAJ6QDRL.js";
|
|
9
|
+
import "./chunk-TJVX42KY.js";
|
|
10
|
+
import "./chunk-PFWHHYEO.js";
|
|
12
11
|
export {
|
|
13
12
|
MANAGED_MARKER,
|
|
14
13
|
cursorPermissionsPath,
|
|
15
14
|
cursorStorageGranted,
|
|
16
15
|
ensureCursorStorageGrant
|
|
17
16
|
};
|
|
18
|
-
//# sourceMappingURL=permissions-
|
|
17
|
+
//# sourceMappingURL=permissions-NNNSRC4P.js.map
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
runPlan
|
|
4
|
+
} from "./chunk-HHXWAWU6.js";
|
|
5
|
+
import "./chunk-6AOZCWN2.js";
|
|
6
|
+
import "./chunk-RGFMQFX7.js";
|
|
7
|
+
import "./chunk-WPHC6JBR.js";
|
|
8
|
+
import "./chunk-3JD25HHJ.js";
|
|
9
|
+
import "./chunk-ZAYATXJD.js";
|
|
10
|
+
import "./chunk-7ZZUSMBJ.js";
|
|
11
|
+
import "./chunk-KMMASOA6.js";
|
|
12
|
+
import "./chunk-WB2FVIUS.js";
|
|
13
|
+
import "./chunk-XKR3VD2Z.js";
|
|
14
|
+
import "./chunk-MQTVMB7W.js";
|
|
15
|
+
import "./chunk-3D4A4B46.js";
|
|
16
|
+
import "./chunk-2Q6PG3MT.js";
|
|
17
|
+
import "./chunk-DXH4TQRB.js";
|
|
18
|
+
import "./chunk-F2NFJ27Z.js";
|
|
19
|
+
import "./chunk-UHDXXLYH.js";
|
|
20
|
+
import "./chunk-J6VJ5M2U.js";
|
|
21
|
+
import "./chunk-7CMVL4X6.js";
|
|
22
|
+
import "./chunk-DIMDAYZS.js";
|
|
23
|
+
import "./chunk-HEHHQU4G.js";
|
|
24
|
+
import "./chunk-PRGPSNGA.js";
|
|
25
|
+
import "./chunk-P3LRUNC6.js";
|
|
26
|
+
import "./chunk-LYC57OXF.js";
|
|
27
|
+
import "./chunk-GD7JZMSJ.js";
|
|
28
|
+
import "./chunk-NP47HRX2.js";
|
|
29
|
+
import "./chunk-IMB6FA2F.js";
|
|
30
|
+
import "./chunk-7MJGYPHF.js";
|
|
31
|
+
import "./chunk-XNK5UN2D.js";
|
|
32
|
+
import "./chunk-MAJ6QDRL.js";
|
|
33
|
+
import "./chunk-TJVX42KY.js";
|
|
34
|
+
import "./chunk-PFWHHYEO.js";
|
|
35
|
+
export {
|
|
36
|
+
runPlan
|
|
37
|
+
};
|
|
38
|
+
//# sourceMappingURL=plan-XR6B7EM3.js.map
|
|
@@ -2,25 +2,27 @@
|
|
|
2
2
|
import "./chunk-3D4A4B46.js";
|
|
3
3
|
import {
|
|
4
4
|
loadRepositoryPolicy
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import "./chunk-
|
|
7
|
-
import "./chunk-DV7HUC4Z.js";
|
|
5
|
+
} from "./chunk-2Q6PG3MT.js";
|
|
6
|
+
import "./chunk-UHDXXLYH.js";
|
|
8
7
|
import {
|
|
9
8
|
printError,
|
|
10
9
|
printInfo,
|
|
11
10
|
printWarning
|
|
12
|
-
} from "./chunk-
|
|
13
|
-
import "./chunk-
|
|
14
|
-
import "./chunk-
|
|
15
|
-
import "./chunk-
|
|
16
|
-
import "./chunk-
|
|
17
|
-
import "./chunk-YII4U7ZD.js";
|
|
18
|
-
import "./chunk-PPZ3K4YM.js";
|
|
19
|
-
import "./chunk-SOM4QA6C.js";
|
|
20
|
-
import "./chunk-ICM463EO.js";
|
|
21
|
-
import "./chunk-XEYH6ZZI.js";
|
|
11
|
+
} from "./chunk-J6VJ5M2U.js";
|
|
12
|
+
import "./chunk-7CMVL4X6.js";
|
|
13
|
+
import "./chunk-DIMDAYZS.js";
|
|
14
|
+
import "./chunk-HEHHQU4G.js";
|
|
15
|
+
import "./chunk-PRGPSNGA.js";
|
|
22
16
|
import "./chunk-P3LRUNC6.js";
|
|
23
|
-
import "./chunk-
|
|
17
|
+
import "./chunk-LYC57OXF.js";
|
|
18
|
+
import "./chunk-GD7JZMSJ.js";
|
|
19
|
+
import "./chunk-NP47HRX2.js";
|
|
20
|
+
import "./chunk-IMB6FA2F.js";
|
|
21
|
+
import "./chunk-7MJGYPHF.js";
|
|
22
|
+
import "./chunk-XNK5UN2D.js";
|
|
23
|
+
import "./chunk-MAJ6QDRL.js";
|
|
24
|
+
import "./chunk-TJVX42KY.js";
|
|
25
|
+
import "./chunk-PFWHHYEO.js";
|
|
24
26
|
|
|
25
27
|
// src/commands/policy.ts
|
|
26
28
|
function groupSources(sources) {
|
|
@@ -130,4 +132,4 @@ async function runPolicy(options = {}) {
|
|
|
130
132
|
export {
|
|
131
133
|
runPolicy
|
|
132
134
|
};
|
|
133
|
-
//# sourceMappingURL=policy-
|
|
135
|
+
//# sourceMappingURL=policy-RFJOJQL6.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/commands/policy.ts"],"sourcesContent":["import type { PolicySource, RepositoryPolicy } from '../policy/index.js';\nimport { loadRepositoryPolicy } from '../policy/index.js';\nimport { printError, printInfo, printWarning } from '../ui/logger.js';\n\n/**\n * `issue-flow policy [--scope <dir>] [--json]`.\n *\n * The inspection surface of the policy layer, and the only one for now: this\n * issue delivers the foundation, so no prompt and no skill consumes\n * `loadRepositoryPolicy()` yet.\n *\n * It exists for two audiences. A human debugging a wrong discovery reads the\n * default output, where every section names the files it came from. The Agent\n * Skills read `--json`: they are markdown and cannot import TypeScript, so a\n * versioned JSON document on stdout is the only bridge available to them —\n * which is why `schemaVersion` is part of the payload rather than of the CLI.\n *\n * That makes `--json` a **published contract**, not a debugging convenience.\n * `skills/_shared/repository-policy.md` documents the payload, and\n * `policy-parity.test.ts` pins the fields the skills read: renaming or dropping\n * one silently makes every skill fall back to its defaults, and nothing would\n * fail — the two paths would simply start deciding differently. Adding a field\n * is safe (readers ignore what they do not know); removing or renaming one\n * bumps `schemaVersion`.\n */\n\nexport interface PolicyCommandOptions {\n scope?: string;\n json?: boolean;\n}\n\n/** Group the provenance entries by kind, preserving discovery order. */\nfunction groupSources(sources: PolicySource[]): Map<PolicySource['kind'], PolicySource[]> {\n const grouped = new Map<PolicySource['kind'], PolicySource[]>();\n for (const source of sources) {\n const bucket = grouped.get(source.kind);\n if (bucket === undefined) {\n grouped.set(source.kind, [source]);\n } else {\n bucket.push(source);\n }\n }\n return grouped;\n}\n\nfunction describeSource(source: PolicySource): string {\n const where = source.path ?? source.origin;\n const detail = source.detail === null ? '' : ` — ${source.detail}`;\n return `${source.status === 'found' ? '' : `[${source.status}] `}${where}${detail}`;\n}\n\n/**\n * Human-readable rendering.\n *\n * Content is deliberately never printed: a resolved policy carries whole\n * `AGENTS.md` and template bodies, and dumping them would bury the one thing\n * this view is for — which file each value came from. `--json` is where the\n * content lives.\n */\nfunction render(policy: RepositoryPolicy): void {\n const lines: string[] = [];\n const push = (line = ''): void => {\n lines.push(line);\n };\n\n push(`Repository: ${policy.root}`);\n push(`Scope: ${policy.scope ?? '(root)'}`);\n if (!policy.enabled) {\n push();\n push('Policy discovery is disabled (policy.enabled = false).');\n console.log(lines.join('\\n'));\n return;\n }\n\n push();\n push('Issues');\n push(` templates: ${policy.issues.templates.length}`);\n for (const template of policy.issues.templates) {\n const labels = template.labels.length > 0 ? ` labels=[${template.labels.join(', ')}]` : '';\n const type = template.type === null ? '' : ` type=${template.type}`;\n push(` - ${template.path} (${template.format}, ${template.origin})${type}${labels}`);\n }\n push(` types: ${policy.issues.types.length > 0 ? policy.issues.types.join(', ') : '(none)'}`);\n push(` labels: ${policy.issues.labels.length}`);\n for (const label of policy.issues.labels) {\n push(` - ${label.name}${label.description === null ? '' : ` — ${label.description}`}`);\n }\n push(` titleConvention: ${policy.issues.titleConvention ?? '(none)'}`);\n\n push();\n push('Pull Requests');\n push(` template: ${policy.pullRequests.templates[0]?.path ?? '(none)'}`);\n for (const template of policy.pullRequests.templates.slice(1)) {\n push(` - ${template.path}`);\n }\n push(` baseBranch: ${policy.pullRequests.baseBranch ?? '(none)'}`);\n push(` titleConvention: ${policy.pullRequests.titleConvention ?? '(none)'}`);\n\n push();\n push('Git');\n push(` branchConvention: ${policy.git.branchConvention ?? '(none)'}`);\n push(` commitConvention: ${policy.git.commitConvention ?? '(none)'}`);\n push(` pullRequestTitleConvention: ${policy.git.pullRequestTitleConvention ?? '(none)'}`);\n push(` issueReference: ${policy.git.issueReference ?? '(none)'}`);\n push(` allowedTypes: ${policy.git.allowedTypes?.join(', ') ?? '(none)'}`);\n push(` scopes: ${policy.git.scopes?.join(', ') ?? '(none)'}`);\n\n push();\n push(`Documents: ${policy.docs.length}`);\n for (const doc of policy.docs) {\n const scope = doc.scope === '' ? 'root' : doc.scope;\n const from = doc.referencedFrom === null ? '' : ` ← ${doc.referencedFrom}`;\n push(` - ${doc.path} (${doc.kind}, scope=${scope})${from}`);\n }\n\n push();\n push(`CODEOWNERS: ${policy.codeowners === null ? '(none)' : 'found'}`);\n\n push();\n push('Sources');\n for (const [kind, entries] of groupSources(policy.sources)) {\n push(` ${kind}`);\n for (const entry of entries) {\n push(` - ${describeSource(entry)}`);\n }\n }\n\n console.log(lines.join('\\n'));\n}\n\n/**\n * Resolve and print the repository policy. Returns the process exit code.\n *\n * Only a repository that cannot be located at all is a failure: an empty policy\n * is a legitimate — and common — answer, printed like any other.\n */\nexport async function runPolicy(options: PolicyCommandOptions = {}): Promise<number> {\n let policy: RepositoryPolicy;\n try {\n policy = await loadRepositoryPolicy({ scope: options.scope ?? null });\n } catch (err) {\n printError(err instanceof Error ? err.message : String(err));\n return 1;\n }\n\n if (options.json === true) {\n console.log(JSON.stringify(policy, null, 2));\n return 0;\n }\n\n render(policy);\n\n const unavailable = policy.sources.filter((source) => source.status === 'unavailable');\n if (unavailable.length > 0) {\n console.log('');\n printWarning(\n `${unavailable.length} source(s) could not be consulted; the policy above is incomplete.`,\n );\n } else if (policy.sources.length === 0) {\n console.log('');\n printInfo('This repository declares no policy sources; Issue Flow defaults apply.');\n }\n\n return 0;\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../src/commands/policy.ts"],"sourcesContent":["import type { PolicySource, RepositoryPolicy } from '../policy/index.js';\nimport { loadRepositoryPolicy } from '../policy/index.js';\nimport { printError, printInfo, printWarning } from '../ui/logger.js';\n\n/**\n * `issue-flow policy [--scope <dir>] [--json]`.\n *\n * The inspection surface of the policy layer, and the only one for now: this\n * issue delivers the foundation, so no prompt and no skill consumes\n * `loadRepositoryPolicy()` yet.\n *\n * It exists for two audiences. A human debugging a wrong discovery reads the\n * default output, where every section names the files it came from. The Agent\n * Skills read `--json`: they are markdown and cannot import TypeScript, so a\n * versioned JSON document on stdout is the only bridge available to them —\n * which is why `schemaVersion` is part of the payload rather than of the CLI.\n *\n * That makes `--json` a **published contract**, not a debugging convenience.\n * `skills/_shared/repository-policy.md` documents the payload, and\n * `policy-parity.test.ts` pins the fields the skills read: renaming or dropping\n * one silently makes every skill fall back to its defaults, and nothing would\n * fail — the two paths would simply start deciding differently. Adding a field\n * is safe (readers ignore what they do not know); removing or renaming one\n * bumps `schemaVersion`.\n */\n\nexport interface PolicyCommandOptions {\n scope?: string;\n json?: boolean;\n}\n\n/** Group the provenance entries by kind, preserving discovery order. */\nfunction groupSources(sources: PolicySource[]): Map<PolicySource['kind'], PolicySource[]> {\n const grouped = new Map<PolicySource['kind'], PolicySource[]>();\n for (const source of sources) {\n const bucket = grouped.get(source.kind);\n if (bucket === undefined) {\n grouped.set(source.kind, [source]);\n } else {\n bucket.push(source);\n }\n }\n return grouped;\n}\n\nfunction describeSource(source: PolicySource): string {\n const where = source.path ?? source.origin;\n const detail = source.detail === null ? '' : ` — ${source.detail}`;\n return `${source.status === 'found' ? '' : `[${source.status}] `}${where}${detail}`;\n}\n\n/**\n * Human-readable rendering.\n *\n * Content is deliberately never printed: a resolved policy carries whole\n * `AGENTS.md` and template bodies, and dumping them would bury the one thing\n * this view is for — which file each value came from. `--json` is where the\n * content lives.\n */\nfunction render(policy: RepositoryPolicy): void {\n const lines: string[] = [];\n const push = (line = ''): void => {\n lines.push(line);\n };\n\n push(`Repository: ${policy.root}`);\n push(`Scope: ${policy.scope ?? '(root)'}`);\n if (!policy.enabled) {\n push();\n push('Policy discovery is disabled (policy.enabled = false).');\n console.log(lines.join('\\n'));\n return;\n }\n\n push();\n push('Issues');\n push(` templates: ${policy.issues.templates.length}`);\n for (const template of policy.issues.templates) {\n const labels = template.labels.length > 0 ? ` labels=[${template.labels.join(', ')}]` : '';\n const type = template.type === null ? '' : ` type=${template.type}`;\n push(` - ${template.path} (${template.format}, ${template.origin})${type}${labels}`);\n }\n push(` types: ${policy.issues.types.length > 0 ? policy.issues.types.join(', ') : '(none)'}`);\n push(` labels: ${policy.issues.labels.length}`);\n for (const label of policy.issues.labels) {\n push(` - ${label.name}${label.description === null ? '' : ` — ${label.description}`}`);\n }\n push(` titleConvention: ${policy.issues.titleConvention ?? '(none)'}`);\n\n push();\n push('Pull Requests');\n push(` template: ${policy.pullRequests.templates[0]?.path ?? '(none)'}`);\n for (const template of policy.pullRequests.templates.slice(1)) {\n push(` - ${template.path}`);\n }\n push(` baseBranch: ${policy.pullRequests.baseBranch ?? '(none)'}`);\n push(` titleConvention: ${policy.pullRequests.titleConvention ?? '(none)'}`);\n\n push();\n push('Git');\n push(` branchConvention: ${policy.git.branchConvention ?? '(none)'}`);\n push(` commitConvention: ${policy.git.commitConvention ?? '(none)'}`);\n push(` pullRequestTitleConvention: ${policy.git.pullRequestTitleConvention ?? '(none)'}`);\n push(` issueReference: ${policy.git.issueReference ?? '(none)'}`);\n push(` allowedTypes: ${policy.git.allowedTypes?.join(', ') ?? '(none)'}`);\n push(` scopes: ${policy.git.scopes?.join(', ') ?? '(none)'}`);\n\n push();\n push(`Documents: ${policy.docs.length}`);\n for (const doc of policy.docs) {\n const scope = doc.scope === '' ? 'root' : doc.scope;\n const from = doc.referencedFrom === null ? '' : ` ← ${doc.referencedFrom}`;\n push(` - ${doc.path} (${doc.kind}, scope=${scope})${from}`);\n }\n\n push();\n push(`CODEOWNERS: ${policy.codeowners === null ? '(none)' : 'found'}`);\n\n push();\n push('Sources');\n for (const [kind, entries] of groupSources(policy.sources)) {\n push(` ${kind}`);\n for (const entry of entries) {\n push(` - ${describeSource(entry)}`);\n }\n }\n\n console.log(lines.join('\\n'));\n}\n\n/**\n * Resolve and print the repository policy. Returns the process exit code.\n *\n * Only a repository that cannot be located at all is a failure: an empty policy\n * is a legitimate — and common — answer, printed like any other.\n */\nexport async function runPolicy(options: PolicyCommandOptions = {}): Promise<number> {\n let policy: RepositoryPolicy;\n try {\n policy = await loadRepositoryPolicy({ scope: options.scope ?? null });\n } catch (err) {\n printError(err instanceof Error ? err.message : String(err));\n return 1;\n }\n\n if (options.json === true) {\n console.log(JSON.stringify(policy, null, 2));\n return 0;\n }\n\n render(policy);\n\n const unavailable = policy.sources.filter((source) => source.status === 'unavailable');\n if (unavailable.length > 0) {\n console.log('');\n printWarning(\n `${unavailable.length} source(s) could not be consulted; the policy above is incomplete.`,\n );\n } else if (policy.sources.length === 0) {\n console.log('');\n printInfo('This repository declares no policy sources; Issue Flow defaults apply.');\n }\n\n return 0;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
issueClosesLines,
|
|
4
|
+
multiIssueContext,
|
|
5
|
+
runPr
|
|
6
|
+
} from "./chunk-2YYP7AE6.js";
|
|
7
|
+
import "./chunk-ERAG5IQB.js";
|
|
8
|
+
import "./chunk-RGFMQFX7.js";
|
|
9
|
+
import "./chunk-WPHC6JBR.js";
|
|
10
|
+
import "./chunk-3JD25HHJ.js";
|
|
11
|
+
import "./chunk-ZAYATXJD.js";
|
|
12
|
+
import "./chunk-7ZZUSMBJ.js";
|
|
13
|
+
import "./chunk-KMMASOA6.js";
|
|
14
|
+
import "./chunk-WB2FVIUS.js";
|
|
15
|
+
import "./chunk-XKR3VD2Z.js";
|
|
16
|
+
import "./chunk-MQTVMB7W.js";
|
|
17
|
+
import "./chunk-3D4A4B46.js";
|
|
18
|
+
import "./chunk-2Q6PG3MT.js";
|
|
19
|
+
import "./chunk-DXH4TQRB.js";
|
|
20
|
+
import "./chunk-F2NFJ27Z.js";
|
|
21
|
+
import "./chunk-UHDXXLYH.js";
|
|
22
|
+
import "./chunk-J6VJ5M2U.js";
|
|
23
|
+
import "./chunk-7CMVL4X6.js";
|
|
24
|
+
import "./chunk-DIMDAYZS.js";
|
|
25
|
+
import "./chunk-HEHHQU4G.js";
|
|
26
|
+
import "./chunk-PRGPSNGA.js";
|
|
27
|
+
import "./chunk-P3LRUNC6.js";
|
|
28
|
+
import "./chunk-LYC57OXF.js";
|
|
29
|
+
import "./chunk-GD7JZMSJ.js";
|
|
30
|
+
import "./chunk-NP47HRX2.js";
|
|
31
|
+
import "./chunk-IMB6FA2F.js";
|
|
32
|
+
import "./chunk-7MJGYPHF.js";
|
|
33
|
+
import "./chunk-XNK5UN2D.js";
|
|
34
|
+
import "./chunk-MAJ6QDRL.js";
|
|
35
|
+
import "./chunk-TJVX42KY.js";
|
|
36
|
+
import "./chunk-PFWHHYEO.js";
|
|
37
|
+
export {
|
|
38
|
+
issueClosesLines,
|
|
39
|
+
multiIssueContext,
|
|
40
|
+
runPr
|
|
41
|
+
};
|
|
42
|
+
//# sourceMappingURL=pr-OSCNJCOO.js.map
|