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.
Files changed (239) hide show
  1. package/README.md +34 -100
  2. package/dist/agent-EWKA7357.js +32 -0
  3. package/dist/{analyze-6M3KEOX7.js → analyze-Z7ODC27F.js} +42 -41
  4. package/dist/analyze-Z7ODC27F.js.map +1 -0
  5. package/dist/{apply-ADB3ZK7W.js → apply-VNSWQS6O.js} +22 -24
  6. package/dist/apply-VNSWQS6O.js.map +1 -0
  7. package/dist/artifacts-AMJQJFFV.js +82 -0
  8. package/dist/artifacts-AMJQJFFV.js.map +1 -0
  9. package/dist/{bench-FM7I7EIV.js → bench-ZJEIACUK.js} +42 -42
  10. package/dist/{chunk-RYOUZ6EK.js → chunk-23VHVVKW.js} +3 -3
  11. package/dist/chunk-2EYLOS5I.js +99 -0
  12. package/dist/chunk-2EYLOS5I.js.map +1 -0
  13. package/dist/{chunk-ANI2NTR4.js → chunk-2EZW4X57.js} +28 -25
  14. package/dist/chunk-2EZW4X57.js.map +1 -0
  15. package/dist/{chunk-E6KXCV3T.js → chunk-2Q6PG3MT.js} +15 -15
  16. package/dist/chunk-2Q6PG3MT.js.map +1 -0
  17. package/dist/{chunk-C5TL7T4V.js → chunk-2YM2VH6R.js} +2 -2
  18. package/dist/{chunk-LPWPFIIB.js → chunk-2YYP7AE6.js} +14 -16
  19. package/dist/{chunk-LPWPFIIB.js.map → chunk-2YYP7AE6.js.map} +1 -1
  20. package/dist/chunk-3JD25HHJ.js +278 -0
  21. package/dist/chunk-3JD25HHJ.js.map +1 -0
  22. package/dist/{chunk-ISZ54SVE.js → chunk-46S7APLQ.js} +41 -17
  23. package/dist/chunk-46S7APLQ.js.map +1 -0
  24. package/dist/chunk-6AOZCWN2.js +21 -0
  25. package/dist/chunk-6AOZCWN2.js.map +1 -0
  26. package/dist/{chunk-QPGEFLMY.js → chunk-7CMVL4X6.js} +7 -7
  27. package/dist/chunk-7MJGYPHF.js +1571 -0
  28. package/dist/chunk-7MJGYPHF.js.map +1 -0
  29. package/dist/chunk-7ZZUSMBJ.js +35 -0
  30. package/dist/chunk-7ZZUSMBJ.js.map +1 -0
  31. package/dist/{chunk-DUS5ZNKL.js → chunk-DIMDAYZS.js} +7 -6
  32. package/dist/{chunk-DGRTJD5R.js → chunk-DXH4TQRB.js} +7 -7
  33. package/dist/{chunk-CRGIQFUQ.js → chunk-E2H3JV2E.js} +3 -1
  34. package/dist/chunk-E2H3JV2E.js.map +1 -0
  35. package/dist/{chunk-YUNBOUQH.js → chunk-ERAG5IQB.js} +8 -8
  36. package/dist/{chunk-D6ZBGJ3L.js → chunk-F2NFJ27Z.js} +130 -36
  37. package/dist/chunk-F2NFJ27Z.js.map +1 -0
  38. package/dist/{chunk-SOM4QA6C.js → chunk-GD7JZMSJ.js} +93 -18
  39. package/dist/chunk-GD7JZMSJ.js.map +1 -0
  40. package/dist/{chunk-YII4U7ZD.js → chunk-HEHHQU4G.js} +70 -81
  41. package/dist/chunk-HEHHQU4G.js.map +1 -0
  42. package/dist/{chunk-KZ5EY5XX.js → chunk-HHXWAWU6.js} +159 -114
  43. package/dist/chunk-HHXWAWU6.js.map +1 -0
  44. package/dist/{chunk-SGTTR4XW.js → chunk-HWWB22HC.js} +152 -100
  45. package/dist/chunk-HWWB22HC.js.map +1 -0
  46. package/dist/chunk-IMB6FA2F.js +673 -0
  47. package/dist/chunk-IMB6FA2F.js.map +1 -0
  48. package/dist/{chunk-6YQT3SSM.js → chunk-IQYXXFRC.js} +22 -6
  49. package/dist/chunk-IQYXXFRC.js.map +1 -0
  50. package/dist/chunk-J6VJ5M2U.js +1201 -0
  51. package/dist/chunk-J6VJ5M2U.js.map +1 -0
  52. package/dist/{chunk-B3TSS7BT.js → chunk-KDQRNVBZ.js} +3 -3
  53. package/dist/{chunk-A4H7P7T7.js → chunk-LRWIP7QS.js} +41 -26
  54. package/dist/chunk-LRWIP7QS.js.map +1 -0
  55. package/dist/{chunk-DV7HUC4Z.js → chunk-LYC57OXF.js} +20 -117
  56. package/dist/chunk-LYC57OXF.js.map +1 -0
  57. package/dist/{chunk-HAKDLR6N.js → chunk-MAJ6QDRL.js} +65 -78
  58. package/dist/chunk-MAJ6QDRL.js.map +1 -0
  59. package/dist/{chunk-HJBF4WD2.js → chunk-MHA7Q3KU.js} +288 -108
  60. package/dist/chunk-MHA7Q3KU.js.map +1 -0
  61. package/dist/{chunk-UK4E2FUA.js → chunk-MQTVMB7W.js} +103 -76
  62. package/dist/chunk-MQTVMB7W.js.map +1 -0
  63. package/dist/chunk-NP47HRX2.js +136 -0
  64. package/dist/chunk-NP47HRX2.js.map +1 -0
  65. package/dist/{chunk-MI5TREN3.js → chunk-NYDAHE3Y.js} +52 -46
  66. package/dist/chunk-NYDAHE3Y.js.map +1 -0
  67. package/dist/{chunk-UWDCIFTP.js → chunk-P7ZYOC23.js} +41 -57
  68. package/dist/chunk-P7ZYOC23.js.map +1 -0
  69. package/dist/{chunk-3R27MJ5R.js → chunk-PFWHHYEO.js} +3 -3
  70. package/dist/{chunk-2SUFAE6X.js → chunk-PHPAK2L6.js} +44 -33
  71. package/dist/{chunk-2SUFAE6X.js.map → chunk-PHPAK2L6.js.map} +1 -1
  72. package/dist/{chunk-PPZ3K4YM.js → chunk-PRGPSNGA.js} +2 -2
  73. package/dist/{chunk-32JSYXEK.js → chunk-RGFMQFX7.js} +9 -23
  74. package/dist/{chunk-32JSYXEK.js.map → chunk-RGFMQFX7.js.map} +1 -1
  75. package/dist/{chunk-YVPZUN6X.js → chunk-TJVX42KY.js} +335 -38
  76. package/dist/chunk-TJVX42KY.js.map +1 -0
  77. package/dist/{chunk-RCZJQUTC.js → chunk-UDRAD7MF.js} +60 -27
  78. package/dist/chunk-UDRAD7MF.js.map +1 -0
  79. package/dist/{chunk-HY5HLFDU.js → chunk-UHDXXLYH.js} +148 -135
  80. package/dist/chunk-UHDXXLYH.js.map +1 -0
  81. package/dist/{chunk-RNFUVKC3.js → chunk-UPAAZU4W.js} +30 -13
  82. package/dist/chunk-UPAAZU4W.js.map +1 -0
  83. package/dist/{chunk-L6HSKTQE.js → chunk-W7LZLJAF.js} +4 -4
  84. package/dist/{chunk-HLAPOUEM.js → chunk-WB2FVIUS.js} +44 -12
  85. package/dist/chunk-WB2FVIUS.js.map +1 -0
  86. package/dist/{chunk-VE3IYNDN.js → chunk-WPHC6JBR.js} +9 -9
  87. package/dist/chunk-WPHC6JBR.js.map +1 -0
  88. package/dist/{chunk-KZXQWC7U.js → chunk-XHCP6ZNO.js} +201 -64
  89. package/dist/chunk-XHCP6ZNO.js.map +1 -0
  90. package/dist/{chunk-7F7LGMVO.js → chunk-XKR3VD2Z.js} +12 -12
  91. package/dist/{chunk-7F7LGMVO.js.map → chunk-XKR3VD2Z.js.map} +1 -1
  92. package/dist/{chunk-ICM463EO.js → chunk-XNK5UN2D.js} +5 -649
  93. package/dist/chunk-XNK5UN2D.js.map +1 -0
  94. package/dist/{chunk-Z5O2XBWA.js → chunk-XQLNZW7I.js} +40 -30
  95. package/dist/chunk-XQLNZW7I.js.map +1 -0
  96. package/dist/{chunk-QMIQR7EE.js → chunk-ZAYATXJD.js} +32 -316
  97. package/dist/chunk-ZAYATXJD.js.map +1 -0
  98. package/dist/cli.js +128 -60
  99. package/dist/cli.js.map +1 -1
  100. package/dist/compat-YPDZB34U.js +24 -0
  101. package/dist/{config-KGZUPAUP.js → config-56B4OHZE.js} +20 -17
  102. package/dist/{contract-JH2WBIO6.js → contract-HWLFFL3F.js} +2 -2
  103. package/dist/{conventions-RYN7OXJN.js → conventions-DW2CM5I3.js} +20 -16
  104. package/dist/{conventions-RYN7OXJN.js.map → conventions-DW2CM5I3.js.map} +1 -1
  105. package/dist/db-5NU77PJA.js +264 -0
  106. package/dist/db-5NU77PJA.js.map +1 -0
  107. package/dist/diagnostics-UCTS2VUF.js +25 -0
  108. package/dist/execute-R7AVOLNG.js +38 -0
  109. package/dist/{generate-CX6KNHZS.js → generate-O7GUXLN4.js} +46 -43
  110. package/dist/generate-O7GUXLN4.js.map +1 -0
  111. package/dist/{git-A2IP32PQ.js → git-LCG45YXD.js} +2 -3
  112. package/dist/history-6GSURU3H.js +101 -0
  113. package/dist/history-6GSURU3H.js.map +1 -0
  114. package/dist/init-DD6DBRC5.js +28 -0
  115. package/dist/{operations-CAKIT2BO.js → operations-HU5ZFEBA.js} +78 -52
  116. package/dist/operations-HU5ZFEBA.js.map +1 -0
  117. package/dist/{permissions-G4XCAESF.js → permissions-NNNSRC4P.js} +5 -6
  118. package/dist/plan-XR6B7EM3.js +38 -0
  119. package/dist/{policy-WX6O2JID.js → policy-RFJOJQL6.js} +17 -15
  120. package/dist/{policy-WX6O2JID.js.map → policy-RFJOJQL6.js.map} +1 -1
  121. package/dist/pr-OSCNJCOO.js +42 -0
  122. package/dist/pr-review-IKIYHFBO.js +33 -0
  123. package/dist/prd-HFDZJJQR.js +37 -0
  124. package/dist/{ps-76L6ZAZL.js → ps-AKRHGPSR.js} +26 -15
  125. package/dist/ps-AKRHGPSR.js.map +1 -0
  126. package/dist/{recorder-N7U66HCO.js → recorder-T7426CKV.js} +11 -7
  127. package/dist/registry-DWRKD65A.js +17 -0
  128. package/dist/repository-TABBRW2C.js +80 -0
  129. package/dist/resume-GDXKK5XP.js +278 -0
  130. package/dist/resume-GDXKK5XP.js.map +1 -0
  131. package/dist/review-JJHMQA2O.js +38 -0
  132. package/dist/routing-FPNUVE7T.js +35 -0
  133. package/dist/run-RLCURLLL.js +61 -0
  134. package/dist/{session-publisher-KAJQRHNZ.js → session-publisher-Q5TNEZPX.js} +3 -3
  135. package/dist/session-publisher-Q5TNEZPX.js.map +1 -0
  136. package/dist/{state-manager-UPHO2EA2.js → state-manager-IGNTD4AB.js} +9 -4
  137. package/dist/state-manager-IGNTD4AB.js.map +1 -0
  138. package/dist/{usage-U7QNGCPK.js → usage-XW27AL5K.js} +69 -63
  139. package/dist/usage-XW27AL5K.js.map +1 -0
  140. package/dist/web-NCDBVZ5Y.js +205 -0
  141. package/dist/web-NCDBVZ5Y.js.map +1 -0
  142. package/package.json +20 -7
  143. package/prompts/analyze.md +16 -19
  144. package/prompts/execute.md +73 -144
  145. package/prompts/generate.md +23 -10
  146. package/prompts/plan.md +32 -60
  147. package/prompts/pr-review.md +58 -40
  148. package/prompts/pr.md +50 -16
  149. package/prompts/prd.md +26 -19
  150. package/prompts/review.md +41 -18
  151. package/web/AGENTS.md +115 -7
  152. package/web/public/app.css +393 -245
  153. package/web/public/app.js +212 -143
  154. package/web/public/index.html +106 -78
  155. package/dist/agent-TB6W7PT7.js +0 -30
  156. package/dist/analyze-6M3KEOX7.js.map +0 -1
  157. package/dist/apply-ADB3ZK7W.js.map +0 -1
  158. package/dist/chunk-6YQT3SSM.js.map +0 -1
  159. package/dist/chunk-A4H7P7T7.js.map +0 -1
  160. package/dist/chunk-ANI2NTR4.js.map +0 -1
  161. package/dist/chunk-CRGIQFUQ.js.map +0 -1
  162. package/dist/chunk-D6ZBGJ3L.js.map +0 -1
  163. package/dist/chunk-DV7HUC4Z.js.map +0 -1
  164. package/dist/chunk-E6KXCV3T.js.map +0 -1
  165. package/dist/chunk-HAKDLR6N.js.map +0 -1
  166. package/dist/chunk-HJBF4WD2.js.map +0 -1
  167. package/dist/chunk-HLAPOUEM.js.map +0 -1
  168. package/dist/chunk-HY5HLFDU.js.map +0 -1
  169. package/dist/chunk-ICM463EO.js.map +0 -1
  170. package/dist/chunk-ISZ54SVE.js.map +0 -1
  171. package/dist/chunk-KZ5EY5XX.js.map +0 -1
  172. package/dist/chunk-KZXQWC7U.js.map +0 -1
  173. package/dist/chunk-MI5TREN3.js.map +0 -1
  174. package/dist/chunk-QMIQR7EE.js.map +0 -1
  175. package/dist/chunk-RCZJQUTC.js.map +0 -1
  176. package/dist/chunk-RNFUVKC3.js.map +0 -1
  177. package/dist/chunk-SGTTR4XW.js.map +0 -1
  178. package/dist/chunk-SOM4QA6C.js.map +0 -1
  179. package/dist/chunk-UK4E2FUA.js.map +0 -1
  180. package/dist/chunk-UWDCIFTP.js.map +0 -1
  181. package/dist/chunk-VE3IYNDN.js.map +0 -1
  182. package/dist/chunk-WCCZJL7W.js +0 -141
  183. package/dist/chunk-WCCZJL7W.js.map +0 -1
  184. package/dist/chunk-XEYH6ZZI.js +0 -289
  185. package/dist/chunk-XEYH6ZZI.js.map +0 -1
  186. package/dist/chunk-XZUEFTUP.js +0 -243
  187. package/dist/chunk-XZUEFTUP.js.map +0 -1
  188. package/dist/chunk-YII4U7ZD.js.map +0 -1
  189. package/dist/chunk-YVPZUN6X.js.map +0 -1
  190. package/dist/chunk-Z5O2XBWA.js.map +0 -1
  191. package/dist/diagnostics-HTCWF7F4.js +0 -23
  192. package/dist/execute-QL3ZQIAP.js +0 -37
  193. package/dist/generate-CX6KNHZS.js.map +0 -1
  194. package/dist/init-PDVQDRS6.js +0 -24
  195. package/dist/operations-CAKIT2BO.js.map +0 -1
  196. package/dist/plan-PRORGS3L.js +0 -34
  197. package/dist/pr-27RMQI5F.js +0 -39
  198. package/dist/pr-review-VNESMAMT.js +0 -32
  199. package/dist/prd-ZNC4T5BS.js +0 -33
  200. package/dist/ps-76L6ZAZL.js.map +0 -1
  201. package/dist/registry-XLHHYLTR.js +0 -15
  202. package/dist/resume-VLWIE264.js +0 -244
  203. package/dist/resume-VLWIE264.js.map +0 -1
  204. package/dist/review-7CREJDKB.js +0 -35
  205. package/dist/routing-VCDYHSXA.js +0 -33
  206. package/dist/run-3MPORLF5.js +0 -56
  207. package/dist/usage-U7QNGCPK.js.map +0 -1
  208. package/dist/web-HUNDHCJ4.js +0 -172
  209. package/dist/web-HUNDHCJ4.js.map +0 -1
  210. /package/dist/{agent-TB6W7PT7.js.map → agent-EWKA7357.js.map} +0 -0
  211. /package/dist/{bench-FM7I7EIV.js.map → bench-ZJEIACUK.js.map} +0 -0
  212. /package/dist/{chunk-RYOUZ6EK.js.map → chunk-23VHVVKW.js.map} +0 -0
  213. /package/dist/{chunk-C5TL7T4V.js.map → chunk-2YM2VH6R.js.map} +0 -0
  214. /package/dist/{chunk-QPGEFLMY.js.map → chunk-7CMVL4X6.js.map} +0 -0
  215. /package/dist/{chunk-DUS5ZNKL.js.map → chunk-DIMDAYZS.js.map} +0 -0
  216. /package/dist/{chunk-DGRTJD5R.js.map → chunk-DXH4TQRB.js.map} +0 -0
  217. /package/dist/{chunk-YUNBOUQH.js.map → chunk-ERAG5IQB.js.map} +0 -0
  218. /package/dist/{chunk-B3TSS7BT.js.map → chunk-KDQRNVBZ.js.map} +0 -0
  219. /package/dist/{chunk-3R27MJ5R.js.map → chunk-PFWHHYEO.js.map} +0 -0
  220. /package/dist/{chunk-PPZ3K4YM.js.map → chunk-PRGPSNGA.js.map} +0 -0
  221. /package/dist/{chunk-L6HSKTQE.js.map → chunk-W7LZLJAF.js.map} +0 -0
  222. /package/dist/{config-KGZUPAUP.js.map → compat-YPDZB34U.js.map} +0 -0
  223. /package/dist/{contract-JH2WBIO6.js.map → config-56B4OHZE.js.map} +0 -0
  224. /package/dist/{diagnostics-HTCWF7F4.js.map → contract-HWLFFL3F.js.map} +0 -0
  225. /package/dist/{execute-QL3ZQIAP.js.map → diagnostics-UCTS2VUF.js.map} +0 -0
  226. /package/dist/{git-A2IP32PQ.js.map → execute-R7AVOLNG.js.map} +0 -0
  227. /package/dist/{init-PDVQDRS6.js.map → git-LCG45YXD.js.map} +0 -0
  228. /package/dist/{permissions-G4XCAESF.js.map → init-DD6DBRC5.js.map} +0 -0
  229. /package/dist/{plan-PRORGS3L.js.map → permissions-NNNSRC4P.js.map} +0 -0
  230. /package/dist/{pr-27RMQI5F.js.map → plan-XR6B7EM3.js.map} +0 -0
  231. /package/dist/{pr-review-VNESMAMT.js.map → pr-OSCNJCOO.js.map} +0 -0
  232. /package/dist/{prd-ZNC4T5BS.js.map → pr-review-IKIYHFBO.js.map} +0 -0
  233. /package/dist/{recorder-N7U66HCO.js.map → prd-HFDZJJQR.js.map} +0 -0
  234. /package/dist/{registry-XLHHYLTR.js.map → recorder-T7426CKV.js.map} +0 -0
  235. /package/dist/{review-7CREJDKB.js.map → registry-DWRKD65A.js.map} +0 -0
  236. /package/dist/{routing-VCDYHSXA.js.map → repository-TABBRW2C.js.map} +0 -0
  237. /package/dist/{run-3MPORLF5.js.map → review-JJHMQA2O.js.map} +0 -0
  238. /package/dist/{session-publisher-KAJQRHNZ.js.map → routing-FPNUVE7T.js.map} +0 -0
  239. /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-A4H7P7T7.js";
7
- import "./chunk-KMMASOA6.js";
8
- import {
9
- parseJournal
10
- } from "./chunk-WCCZJL7W.js";
6
+ } from "./chunk-LRWIP7QS.js";
11
7
  import {
12
- resolveProjectPaths
13
- } from "./chunk-DV7HUC4Z.js";
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
- } from "./chunk-XZUEFTUP.js";
19
- import "./chunk-QPGEFLMY.js";
20
- import {
21
- QUEUES_DIR_NAME,
22
- getIssuePaths
23
- } from "./chunk-HAKDLR6N.js";
24
- import "./chunk-YVPZUN6X.js";
25
- import "./chunk-DUS5ZNKL.js";
26
- import "./chunk-YII4U7ZD.js";
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-SOM4QA6C.js";
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-ICM463EO.js";
36
- import "./chunk-XEYH6ZZI.js";
37
- import "./chunk-P3LRUNC6.js";
38
- import "./chunk-3R27MJ5R.js";
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
- printError(`Not inside a usable project: ${err instanceof Error ? err.message : String(err)}`);
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(projectId, id) {
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.projectId, id);
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.projectId, issue)].filter(
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
- printInfo(
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 render = (content, limit) => {
250
- const entries = parseJournal(content).filter(
251
- (entry) => kinds.size === 0 || kinds.has(entry.event.type)
252
- );
253
- const slice = limit === null ? entries : entries.slice(-limit);
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 readAll = async () => `${await readIfPresent(issuePaths.rotatedEventsFile)}${await readIfPresent(issuePaths.eventsFile)}`;
261
- const initial = await readAll();
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
- render(initial, tail);
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
- render(await readAll(), null);
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.projectId, target);
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-UPHO2EA2.js");
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-CAKIT2BO.js.map
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-DGRTJD5R.js";
8
- import "./chunk-HAKDLR6N.js";
9
- import "./chunk-YVPZUN6X.js";
10
- import "./chunk-XEYH6ZZI.js";
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-G4XCAESF.js.map
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-E6KXCV3T.js";
6
- import "./chunk-HY5HLFDU.js";
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-XZUEFTUP.js";
13
- import "./chunk-QPGEFLMY.js";
14
- import "./chunk-HAKDLR6N.js";
15
- import "./chunk-YVPZUN6X.js";
16
- import "./chunk-DUS5ZNKL.js";
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-3R27MJ5R.js";
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-WX6O2JID.js.map
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":"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","names":[]}
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