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,264 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ importProjectArtifacts,
4
+ printError,
5
+ printInfo,
6
+ resolveProjectPaths
7
+ } from "./chunk-J6VJ5M2U.js";
8
+ import "./chunk-7CMVL4X6.js";
9
+ import "./chunk-DIMDAYZS.js";
10
+ import "./chunk-HEHHQU4G.js";
11
+ import "./chunk-PRGPSNGA.js";
12
+ import "./chunk-P3LRUNC6.js";
13
+ import "./chunk-LYC57OXF.js";
14
+ import "./chunk-GD7JZMSJ.js";
15
+ import "./chunk-NP47HRX2.js";
16
+ import {
17
+ executionPlanSchema
18
+ } from "./chunk-IMB6FA2F.js";
19
+ import {
20
+ exportStoredState,
21
+ getDatabasePath,
22
+ loadStoredPlan,
23
+ loadStoredQueue,
24
+ openIssueFlowDatabase
25
+ } from "./chunk-7MJGYPHF.js";
26
+ import {
27
+ taskPlanSchema
28
+ } from "./chunk-XNK5UN2D.js";
29
+ import {
30
+ ISSUES_DIR_NAME,
31
+ QUEUES_DIR_NAME
32
+ } from "./chunk-MAJ6QDRL.js";
33
+ import {
34
+ getProjectRoot,
35
+ getRemoteUrl
36
+ } from "./chunk-TJVX42KY.js";
37
+ import "./chunk-PFWHHYEO.js";
38
+
39
+ // src/commands/db.ts
40
+ import { existsSync } from "node:fs";
41
+ import { writeFile } from "node:fs/promises";
42
+ import { join as join2 } from "node:path";
43
+
44
+ // src/storage/db/verify.ts
45
+ import { readdir, readFile } from "node:fs/promises";
46
+ import { join } from "node:path";
47
+ import { isDeepStrictEqual } from "node:util";
48
+ async function canonicalIds(input) {
49
+ const database = await openIssueFlowDatabase(input.databaseOptions);
50
+ try {
51
+ return {
52
+ issues: database.prepare("SELECT issue_id FROM pipelines WHERE project_id = ?").all(input.projectId).map((row) => row.issue_id),
53
+ queues: database.prepare("SELECT id FROM queues WHERE project_id = ?").all(input.projectId).map((row) => row.id)
54
+ };
55
+ } finally {
56
+ database.close();
57
+ }
58
+ }
59
+ async function verifyProjectProjections(input) {
60
+ let checked = 0;
61
+ const divergences = [];
62
+ const canonical = await canonicalIds(input);
63
+ const issuesDir = join(input.projectDir, ISSUES_DIR_NAME);
64
+ const issueIds = /* @__PURE__ */ new Set([...await readdir(issuesDir).catch(() => []), ...canonical.issues]);
65
+ for (const issueId of [...issueIds].sort()) {
66
+ const tasksPath = join(issuesDir, issueId, "tasks.json");
67
+ let projection;
68
+ try {
69
+ projection = taskPlanSchema.parse(JSON.parse(await readFile(tasksPath, "utf-8")));
70
+ } catch {
71
+ if (canonical.issues.includes(issueId)) {
72
+ checked++;
73
+ divergences.push(`issues/${issueId}/tasks.json (missing or invalid projection)`);
74
+ }
75
+ continue;
76
+ }
77
+ checked++;
78
+ try {
79
+ const stored = taskPlanSchema.parse(
80
+ await loadStoredPlan({
81
+ tasksPath,
82
+ projectId: input.projectId,
83
+ issueId,
84
+ projectRoot: input.projectRoot,
85
+ databaseOptions: input.databaseOptions
86
+ })
87
+ );
88
+ if (!isDeepStrictEqual(projection, stored)) divergences.push(`issues/${issueId}/tasks.json`);
89
+ } catch {
90
+ divergences.push(`issues/${issueId}/tasks.json (missing from SQLite)`);
91
+ }
92
+ }
93
+ const queuesDir = join(input.projectDir, QUEUES_DIR_NAME);
94
+ const queueIds = /* @__PURE__ */ new Set([...await readdir(queuesDir).catch(() => []), ...canonical.queues]);
95
+ for (const queueId of [...queueIds].sort()) {
96
+ const planFile = join(queuesDir, queueId, "execution-plan.json");
97
+ let projection;
98
+ try {
99
+ projection = executionPlanSchema.parse(JSON.parse(await readFile(planFile, "utf-8")));
100
+ } catch {
101
+ if (canonical.queues.includes(queueId)) {
102
+ checked++;
103
+ divergences.push(`queues/${queueId}/execution-plan.json (missing or invalid projection)`);
104
+ }
105
+ continue;
106
+ }
107
+ checked++;
108
+ const storedValue = await loadStoredQueue({
109
+ planFile,
110
+ projectId: input.projectId,
111
+ projectRoot: input.projectRoot,
112
+ databaseOptions: input.databaseOptions
113
+ });
114
+ const stored = storedValue === null ? null : executionPlanSchema.parse(storedValue);
115
+ if (stored === null || !isDeepStrictEqual(projection, stored)) {
116
+ divergences.push(`queues/${queueId}/execution-plan.json`);
117
+ }
118
+ }
119
+ return { checked, divergences };
120
+ }
121
+
122
+ // src/commands/db.ts
123
+ function failure(action, error) {
124
+ const message = error instanceof Error ? error.message : String(error);
125
+ printError(`Database ${action} failed: ${message}`);
126
+ return 1;
127
+ }
128
+ async function runDbCheck() {
129
+ try {
130
+ const project = await resolveProjectPaths();
131
+ const database = await openIssueFlowDatabase(project.databaseOptions);
132
+ try {
133
+ const result = database.integrityCheck();
134
+ if (result !== "ok") {
135
+ printError(
136
+ `Database integrity check failed: ${result}. Restore a backup or re-import the preserved JSON state.`
137
+ );
138
+ return 1;
139
+ }
140
+ printInfo(`Database is healthy: ${getDatabasePath(project.databaseOptions)}`);
141
+ return 0;
142
+ } finally {
143
+ database.close();
144
+ }
145
+ } catch (error) {
146
+ return failure("check", error);
147
+ }
148
+ }
149
+ async function runDbBackup(destination) {
150
+ try {
151
+ const project = await resolveProjectPaths();
152
+ const target = destination ?? join2(project.projectDir, "backups", `issue-flow-${Date.now()}.db`);
153
+ const database = await openIssueFlowDatabase(project.databaseOptions);
154
+ try {
155
+ database.backup(target);
156
+ printInfo(`Database backup created: ${target}`);
157
+ return 0;
158
+ } finally {
159
+ database.close();
160
+ }
161
+ } catch (error) {
162
+ return failure("backup", error);
163
+ }
164
+ }
165
+ async function runDbVacuum() {
166
+ try {
167
+ const project = await resolveProjectPaths();
168
+ const database = await openIssueFlowDatabase(project.databaseOptions);
169
+ try {
170
+ database.vacuum();
171
+ printInfo(`Database vacuum completed: ${getDatabasePath(project.databaseOptions)}`);
172
+ return 0;
173
+ } finally {
174
+ database.close();
175
+ }
176
+ } catch (error) {
177
+ return failure("vacuum", error);
178
+ }
179
+ }
180
+ async function runDbExport(destination) {
181
+ try {
182
+ const project = await resolveProjectPaths();
183
+ const payload = JSON.stringify(
184
+ {
185
+ schemaVersion: 1,
186
+ exportedAt: (/* @__PURE__ */ new Date()).toISOString(),
187
+ database: getDatabasePath(project.databaseOptions),
188
+ tables: await exportStoredState(project.databaseOptions)
189
+ },
190
+ null,
191
+ 2
192
+ );
193
+ if (destination === void 0) {
194
+ printInfo(payload);
195
+ } else {
196
+ await writeFile(destination, `${payload}
197
+ `, "utf-8");
198
+ printInfo(`Database export written: ${destination}`);
199
+ }
200
+ return 0;
201
+ } catch (error) {
202
+ return failure("export", error);
203
+ }
204
+ }
205
+ async function runDbVerify() {
206
+ try {
207
+ const project = await resolveProjectPaths();
208
+ if (project.storageDriver !== "sqlite") {
209
+ printError("Database verification requires storage.driver=sqlite.");
210
+ return 1;
211
+ }
212
+ const projectRoot = await getProjectRoot();
213
+ const result = await verifyProjectProjections({
214
+ projectId: project.projectId,
215
+ projectDir: project.projectDir,
216
+ projectRoot,
217
+ databaseOptions: project.databaseOptions
218
+ });
219
+ if (result.divergences.length > 0) {
220
+ printError(`Database verification found ${result.divergences.length} divergence(s):`);
221
+ for (const divergence of result.divergences) printError(` ${divergence}`);
222
+ return 1;
223
+ }
224
+ printInfo(`Database verification passed: ${result.checked} projection(s) match SQLite.`);
225
+ return 0;
226
+ } catch (error) {
227
+ return failure("verification", error);
228
+ }
229
+ }
230
+ async function runDbImport(options = {}) {
231
+ try {
232
+ const project = await resolveProjectPaths();
233
+ const projectRoot = await getProjectRoot();
234
+ const result = await importProjectArtifacts({
235
+ projectId: project.projectId,
236
+ projectDir: project.projectDir,
237
+ projectRoot,
238
+ remoteUrl: await getRemoteUrl(projectRoot),
239
+ ...project.databaseOptions,
240
+ withEvents: options.withEvents === true,
241
+ onWarning: printInfo
242
+ });
243
+ if (result.failed) return 1;
244
+ printInfo(
245
+ `Database import completed: ${result.imported} artifact(s) imported, ${result.skipped} unchanged.`
246
+ );
247
+ return 0;
248
+ } catch (error) {
249
+ return failure("import", error);
250
+ }
251
+ }
252
+ function databaseExists(options = {}) {
253
+ return existsSync(getDatabasePath(options));
254
+ }
255
+ export {
256
+ databaseExists,
257
+ runDbBackup,
258
+ runDbCheck,
259
+ runDbExport,
260
+ runDbImport,
261
+ runDbVacuum,
262
+ runDbVerify
263
+ };
264
+ //# sourceMappingURL=db-5NU77PJA.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/db.ts","../src/storage/db/verify.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\nimport { writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { importProjectArtifacts } from '../storage/db/import.js';\nimport { getDatabasePath, openIssueFlowDatabase } from '../storage/db/index.js';\nimport { exportStoredState } from '../storage/db/repository.js';\nimport { verifyProjectProjections } from '../storage/db/verify.js';\nimport { resolveProjectPaths } from '../storage/resolve.js';\nimport { printError, printInfo } from '../ui/logger.js';\nimport { getProjectRoot, getRemoteUrl } from '../utils/git.js';\n\nfunction failure(action: string, error: unknown): number {\n const message = error instanceof Error ? error.message : String(error);\n printError(`Database ${action} failed: ${message}`);\n return 1;\n}\n\nexport async function runDbCheck(): Promise<number> {\n try {\n const project = await resolveProjectPaths();\n const database = await openIssueFlowDatabase(project.databaseOptions);\n try {\n const result = database.integrityCheck();\n if (result !== 'ok') {\n printError(\n `Database integrity check failed: ${result}. Restore a backup or re-import the preserved JSON state.`,\n );\n return 1;\n }\n printInfo(`Database is healthy: ${getDatabasePath(project.databaseOptions)}`);\n return 0;\n } finally {\n database.close();\n }\n } catch (error) {\n return failure('check', error);\n }\n}\n\nexport async function runDbBackup(destination?: string): Promise<number> {\n try {\n const project = await resolveProjectPaths();\n const target =\n destination ?? join(project.projectDir, 'backups', `issue-flow-${Date.now()}.db`);\n const database = await openIssueFlowDatabase(project.databaseOptions);\n try {\n database.backup(target);\n printInfo(`Database backup created: ${target}`);\n return 0;\n } finally {\n database.close();\n }\n } catch (error) {\n return failure('backup', error);\n }\n}\n\nexport async function runDbVacuum(): Promise<number> {\n try {\n const project = await resolveProjectPaths();\n const database = await openIssueFlowDatabase(project.databaseOptions);\n try {\n database.vacuum();\n printInfo(`Database vacuum completed: ${getDatabasePath(project.databaseOptions)}`);\n return 0;\n } finally {\n database.close();\n }\n } catch (error) {\n return failure('vacuum', error);\n }\n}\n\n/** Export the relational state as portable, readable JSON for diagnostics. */\nexport async function runDbExport(destination?: string): Promise<number> {\n try {\n const project = await resolveProjectPaths();\n const payload = JSON.stringify(\n {\n schemaVersion: 1,\n exportedAt: new Date().toISOString(),\n database: getDatabasePath(project.databaseOptions),\n tables: await exportStoredState(project.databaseOptions),\n },\n null,\n 2,\n );\n if (destination === undefined) {\n printInfo(payload);\n } else {\n await writeFile(destination, `${payload}\\n`, 'utf-8');\n printInfo(`Database export written: ${destination}`);\n }\n return 0;\n } catch (error) {\n return failure('export', error);\n }\n}\n\nexport async function runDbVerify(): Promise<number> {\n try {\n const project = await resolveProjectPaths();\n if (project.storageDriver !== 'sqlite') {\n printError('Database verification requires storage.driver=sqlite.');\n return 1;\n }\n const projectRoot = await getProjectRoot();\n const result = await verifyProjectProjections({\n projectId: project.projectId,\n projectDir: project.projectDir,\n projectRoot,\n databaseOptions: project.databaseOptions,\n });\n if (result.divergences.length > 0) {\n printError(`Database verification found ${result.divergences.length} divergence(s):`);\n for (const divergence of result.divergences) printError(` ${divergence}`);\n return 1;\n }\n printInfo(`Database verification passed: ${result.checked} projection(s) match SQLite.`);\n return 0;\n } catch (error) {\n return failure('verification', error);\n }\n}\n\nexport async function runDbImport(options: { withEvents?: boolean } = {}): Promise<number> {\n try {\n const project = await resolveProjectPaths();\n const projectRoot = await getProjectRoot();\n const result = await importProjectArtifacts({\n projectId: project.projectId,\n projectDir: project.projectDir,\n projectRoot,\n remoteUrl: await getRemoteUrl(projectRoot),\n ...project.databaseOptions,\n withEvents: options.withEvents === true,\n onWarning: printInfo,\n });\n if (result.failed) return 1;\n printInfo(\n `Database import completed: ${result.imported} artifact(s) imported, ${result.skipped} unchanged.`,\n );\n return 0;\n } catch (error) {\n return failure('import', error);\n }\n}\n\nexport function databaseExists(options: Parameters<typeof getDatabasePath>[0] = {}): boolean {\n return existsSync(getDatabasePath(options));\n}\n","import { readdir, readFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { isDeepStrictEqual } from 'node:util';\nimport type { ExecutionPlan } from '../../execution/types.js';\nimport { taskPlanSchema } from '../../schemas.js';\nimport type { TaskPlan } from '../../types.js';\nimport { ISSUES_DIR_NAME, QUEUES_DIR_NAME } from '../paths.js';\nimport { executionPlanSchema } from '../schemas.js';\nimport { type OpenIssueFlowDatabaseOptions, openIssueFlowDatabase } from './index.js';\nimport { loadStoredPlan, loadStoredQueue } from './repository.js';\n\nexport interface VerifyProjectInput {\n projectId: string;\n projectDir: string;\n projectRoot: string;\n databaseOptions?: OpenIssueFlowDatabaseOptions;\n}\n\nexport interface VerifyProjectResult {\n checked: number;\n divergences: string[];\n}\n\nasync function canonicalIds(\n input: VerifyProjectInput,\n): Promise<{ issues: string[]; queues: string[] }> {\n const database = await openIssueFlowDatabase(input.databaseOptions);\n try {\n return {\n issues: database\n .prepare('SELECT issue_id FROM pipelines WHERE project_id = ?')\n .all<{ issue_id: string }>(input.projectId)\n .map((row) => row.issue_id),\n queues: database\n .prepare('SELECT id FROM queues WHERE project_id = ?')\n .all<{ id: string }>(input.projectId)\n .map((row) => row.id),\n };\n } finally {\n database.close();\n }\n}\n\n/** Compare readable plan/queue projections with their canonical relational state. */\nexport async function verifyProjectProjections(\n input: VerifyProjectInput,\n): Promise<VerifyProjectResult> {\n let checked = 0;\n const divergences: string[] = [];\n const canonical = await canonicalIds(input);\n const issuesDir = join(input.projectDir, ISSUES_DIR_NAME);\n const issueIds = new Set([...(await readdir(issuesDir).catch(() => [])), ...canonical.issues]);\n for (const issueId of [...issueIds].sort()) {\n const tasksPath = join(issuesDir, issueId, 'tasks.json');\n let projection: TaskPlan;\n try {\n projection = taskPlanSchema.parse(JSON.parse(await readFile(tasksPath, 'utf-8'))) as TaskPlan;\n } catch {\n if (canonical.issues.includes(issueId)) {\n checked++;\n divergences.push(`issues/${issueId}/tasks.json (missing or invalid projection)`);\n }\n continue;\n }\n checked++;\n try {\n const stored = taskPlanSchema.parse(\n await loadStoredPlan({\n tasksPath,\n projectId: input.projectId,\n issueId,\n projectRoot: input.projectRoot,\n databaseOptions: input.databaseOptions,\n }),\n );\n if (!isDeepStrictEqual(projection, stored)) divergences.push(`issues/${issueId}/tasks.json`);\n } catch {\n divergences.push(`issues/${issueId}/tasks.json (missing from SQLite)`);\n }\n }\n\n const queuesDir = join(input.projectDir, QUEUES_DIR_NAME);\n const queueIds = new Set([...(await readdir(queuesDir).catch(() => [])), ...canonical.queues]);\n for (const queueId of [...queueIds].sort()) {\n const planFile = join(queuesDir, queueId, 'execution-plan.json');\n let projection: ExecutionPlan;\n try {\n projection = executionPlanSchema.parse(JSON.parse(await readFile(planFile, 'utf-8')));\n } catch {\n if (canonical.queues.includes(queueId)) {\n checked++;\n divergences.push(`queues/${queueId}/execution-plan.json (missing or invalid projection)`);\n }\n continue;\n }\n checked++;\n const storedValue = await loadStoredQueue({\n planFile,\n projectId: input.projectId,\n projectRoot: input.projectRoot,\n databaseOptions: input.databaseOptions,\n });\n const stored = storedValue === null ? null : executionPlanSchema.parse(storedValue);\n if (stored === null || !isDeepStrictEqual(projection, stored)) {\n divergences.push(`queues/${queueId}/execution-plan.json`);\n }\n }\n return { checked, divergences };\n}\n"],"mappings":"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","names":["join","join"]}
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ bindDiagnosticContext,
4
+ flushDiagnostics,
5
+ readDiagnostics,
6
+ resetDiagnosticsState,
7
+ writeDiagnostic
8
+ } from "./chunk-7CMVL4X6.js";
9
+ import "./chunk-PRGPSNGA.js";
10
+ import "./chunk-GD7JZMSJ.js";
11
+ import "./chunk-NP47HRX2.js";
12
+ import "./chunk-IMB6FA2F.js";
13
+ import "./chunk-7MJGYPHF.js";
14
+ import "./chunk-XNK5UN2D.js";
15
+ import "./chunk-MAJ6QDRL.js";
16
+ import "./chunk-TJVX42KY.js";
17
+ import "./chunk-PFWHHYEO.js";
18
+ export {
19
+ bindDiagnosticContext,
20
+ flushDiagnostics,
21
+ readDiagnostics,
22
+ resetDiagnosticsState,
23
+ writeDiagnostic
24
+ };
25
+ //# sourceMappingURL=diagnostics-UCTS2VUF.js.map
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ runExecute
4
+ } from "./chunk-XHCP6ZNO.js";
5
+ import "./chunk-PHPAK2L6.js";
6
+ import "./chunk-E2H3JV2E.js";
7
+ import "./chunk-IQYXXFRC.js";
8
+ import "./chunk-HWWB22HC.js";
9
+ import "./chunk-W7LZLJAF.js";
10
+ import "./chunk-P7ZYOC23.js";
11
+ import "./chunk-WB2FVIUS.js";
12
+ import "./chunk-XKR3VD2Z.js";
13
+ import "./chunk-MQTVMB7W.js";
14
+ import "./chunk-2Q6PG3MT.js";
15
+ import "./chunk-DXH4TQRB.js";
16
+ import "./chunk-UDRAD7MF.js";
17
+ import "./chunk-F2NFJ27Z.js";
18
+ import "./chunk-2YM2VH6R.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
+ runExecute
37
+ };
38
+ //# sourceMappingURL=execute-R7AVOLNG.js.map
@@ -1,60 +1,59 @@
1
1
  #!/usr/bin/env node
2
- import {
3
- localIssueRef
4
- } from "./chunk-VE3IYNDN.js";
5
2
  import {
6
3
  ensureProvidersRegistered,
7
4
  getProvider
8
- } from "./chunk-QMIQR7EE.js";
5
+ } from "./chunk-ZAYATXJD.js";
6
+ import "./chunk-7ZZUSMBJ.js";
9
7
  import "./chunk-KMMASOA6.js";
10
8
  import {
11
9
  publishPhaseMetrics,
12
10
  resolvePolicyPlaceholders
13
- } from "./chunk-HLAPOUEM.js";
11
+ } from "./chunk-WB2FVIUS.js";
14
12
  import {
15
13
  applyPlaceholders,
16
14
  loadPrompt
17
- } from "./chunk-7F7LGMVO.js";
15
+ } from "./chunk-XKR3VD2Z.js";
18
16
  import {
19
17
  DEFAULT_HEADLESS_TIMEOUT_MS,
20
18
  runHeadless
21
- } from "./chunk-UK4E2FUA.js";
22
- import "./chunk-WCCZJL7W.js";
23
- import "./chunk-DGRTJD5R.js";
24
- import "./chunk-D6ZBGJ3L.js";
19
+ } from "./chunk-MQTVMB7W.js";
25
20
  import "./chunk-3D4A4B46.js";
26
21
  import {
27
22
  loadRepositoryPolicy
28
- } from "./chunk-E6KXCV3T.js";
23
+ } from "./chunk-2Q6PG3MT.js";
24
+ import "./chunk-DXH4TQRB.js";
25
+ import "./chunk-F2NFJ27Z.js";
29
26
  import {
30
27
  loadIssuesConfig,
31
28
  loadPolicyConfig
32
- } from "./chunk-HY5HLFDU.js";
33
- import {
34
- resolveProjectPaths
35
- } from "./chunk-DV7HUC4Z.js";
29
+ } from "./chunk-UHDXXLYH.js";
36
30
  import {
37
31
  getGlobalTimeout,
38
32
  printError,
39
33
  printInfo,
40
34
  printSuccess,
41
- printWarning
42
- } from "./chunk-XZUEFTUP.js";
43
- import "./chunk-QPGEFLMY.js";
44
- import "./chunk-HAKDLR6N.js";
45
- import {
46
- run
47
- } from "./chunk-YVPZUN6X.js";
48
- import "./chunk-DUS5ZNKL.js";
49
- import "./chunk-YII4U7ZD.js";
50
- import "./chunk-PPZ3K4YM.js";
35
+ printWarning,
36
+ resolveIssuePaths,
37
+ resolveProjectPaths
38
+ } from "./chunk-J6VJ5M2U.js";
39
+ import "./chunk-7CMVL4X6.js";
40
+ import "./chunk-DIMDAYZS.js";
41
+ import "./chunk-HEHHQU4G.js";
42
+ import "./chunk-PRGPSNGA.js";
43
+ import "./chunk-P3LRUNC6.js";
44
+ import "./chunk-LYC57OXF.js";
51
45
  import {
52
46
  isoNow
53
- } from "./chunk-SOM4QA6C.js";
54
- import "./chunk-ICM463EO.js";
55
- import "./chunk-XEYH6ZZI.js";
56
- import "./chunk-P3LRUNC6.js";
57
- import "./chunk-3R27MJ5R.js";
47
+ } from "./chunk-GD7JZMSJ.js";
48
+ import "./chunk-NP47HRX2.js";
49
+ import "./chunk-IMB6FA2F.js";
50
+ import "./chunk-7MJGYPHF.js";
51
+ import "./chunk-XNK5UN2D.js";
52
+ import "./chunk-MAJ6QDRL.js";
53
+ import {
54
+ run
55
+ } from "./chunk-TJVX42KY.js";
56
+ import "./chunk-PFWHHYEO.js";
58
57
 
59
58
  // src/issues/draft.ts
60
59
  var DRAFT_TAG = "issue-draft";
@@ -141,16 +140,18 @@ async function createMissingLabels(names, warn) {
141
140
  }
142
141
 
143
142
  // src/commands/generate.ts
144
- function issueLocation(issue) {
145
- return issue.remoteRef ?? localIssueRef(issue.id);
143
+ async function issueLocation(issue) {
144
+ return issue.remoteRef ?? (await resolveIssuePaths(issue.id)).issueFile;
146
145
  }
147
- async function draftIssue(promptText) {
146
+ async function draftIssue(promptText, destination) {
148
147
  const { issuesDir } = await resolveProjectPaths();
149
148
  const template = await loadPrompt("generate");
150
149
  const prompt = applyPlaceholders(template, {
151
150
  // The repository's own conventions. Empty when it declares none, which is
152
151
  // what keeps the rendered prompt identical to the pre-policy one.
153
- ...await resolvePolicyPlaceholders(),
152
+ ...await resolvePolicyPlaceholders({ remote: destination !== "local" }),
153
+ __REMOTE_DISCOVERY__: destination === "local" ? "" : "enabled",
154
+ __DESTINATION__: destination,
154
155
  __USER_PROMPT__: promptText,
155
156
  __LOCAL_ISSUES_DIR__: issuesDir
156
157
  });
@@ -193,7 +194,7 @@ async function createBoth(draft) {
193
194
  } catch (err) {
194
195
  const message = err instanceof Error ? err.message : String(err);
195
196
  throw new Error(
196
- `GitHub issue created at ${issueLocation(remote)}, but the local mirror was not written: ${message}. Nothing else was persisted; re-run with --local to create the mirror.`
197
+ `GitHub issue created at ${await issueLocation(remote)}, but the local mirror was not written: ${message}. Nothing else was persisted; re-run with --local to create the mirror.`
197
198
  );
198
199
  }
199
200
  }
@@ -201,16 +202,18 @@ async function createIssues(target, draft) {
201
202
  if (target === "both") {
202
203
  return createBoth(draft);
203
204
  }
204
- return [await getProvider(target).create(draft)];
205
+ return [
206
+ await getProvider(target).create(draft, ...target === "local" ? [{ localOnly: true }] : [])
207
+ ];
205
208
  }
206
- async function applyLabelPolicy(draft) {
209
+ async function applyLabelPolicy(draft, localOnly) {
207
210
  let known;
208
211
  let allowCreation;
209
212
  try {
210
- const policy = await loadRepositoryPolicy();
213
+ const policy = await loadRepositoryPolicy({ remote: !localOnly });
211
214
  known = policy.issues.labels;
212
215
  const config = await loadPolicyConfig({ projectRoot: policy.root });
213
- allowCreation = config.issues.allowLabelCreation ?? false;
216
+ allowCreation = !localOnly && (config.issues.allowLabelCreation ?? false);
214
217
  } catch {
215
218
  return draft;
216
219
  }
@@ -233,7 +236,7 @@ async function runGenerate(promptText, target) {
233
236
  ensureProvidersRegistered();
234
237
  let draft;
235
238
  try {
236
- draft = await draftIssue(promptText);
239
+ draft = await draftIssue(promptText, destination);
237
240
  } catch (err) {
238
241
  if (err instanceof IssueDraftParseError) {
239
242
  printError(`Could not read the generated Issue draft: ${err.message}`);
@@ -242,7 +245,7 @@ async function runGenerate(promptText, target) {
242
245
  }
243
246
  return 1;
244
247
  }
245
- const finalDraft = await applyLabelPolicy(draft);
248
+ const finalDraft = await applyLabelPolicy(draft, destination === "local");
246
249
  if (finalDraft.template !== void 0) {
247
250
  printInfo(`Following the repository's Issue Template: ${finalDraft.template}`);
248
251
  }
@@ -257,11 +260,11 @@ async function runGenerate(promptText, target) {
257
260
  return 1;
258
261
  }
259
262
  for (const issue of created) {
260
- printSuccess(`Issue created (${issue.source}): ${issueLocation(issue)}`);
263
+ printSuccess(`Issue created (${issue.source}): ${await issueLocation(issue)}`);
261
264
  }
262
265
  return 0;
263
266
  }
264
267
  export {
265
268
  runGenerate
266
269
  };
267
- //# sourceMappingURL=generate-CX6KNHZS.js.map
270
+ //# sourceMappingURL=generate-O7GUXLN4.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/issues/draft.ts","../src/issues/label-policy.ts","../src/commands/generate.ts"],"sourcesContent":["import type { IssueDraft } from './types.js';\n\n/**\n * Structured Issue draft emitted by the `generate` prompt.\n *\n * The agent no longer creates the Issue itself: it returns the content and the\n * providers persist it, so the same draft can reach GitHub, the local files, or\n * both. Capturing the result therefore has to be exact — the old approach of\n * fishing an issue URL out of free-form prose only ever worked for GitHub.\n *\n * The block mirrors the `<issue-body>` convention already used by the phase\n * templates, which keeps a multi-line markdown body readable and free of the\n * escaping a JSON payload would demand.\n */\n\n/** Wrapper the agent must emit around the draft. */\nexport const DRAFT_TAG = 'issue-draft';\n\n/** Failure to capture a draft from the agent output. */\nexport class IssueDraftParseError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'IssueDraftParseError';\n }\n}\n\n/**\n * Last occurrence of `<tag>...</tag>` in `source`, or `null`.\n *\n * The last one wins: an agent that shows the format before filling it in (or\n * restates the draft after a correction) would otherwise have its first,\n * throwaway attempt captured. The closing tag is searched from the end for the\n * same reason a body may legitimately quote one.\n */\nfunction extractTag(source: string, tag: string): string | null {\n const open = `<${tag}>`;\n const close = `</${tag}>`;\n\n const start = source.lastIndexOf(open);\n if (start === -1) return null;\n\n const end = source.lastIndexOf(close);\n if (end === -1 || end < start) return null;\n\n return source.slice(start + open.length, end);\n}\n\nfunction parseLabels(raw: string | null): string[] {\n if (raw === null) return [];\n return raw\n .split(',')\n .map((label) => label.trim())\n .filter((label) => label.length > 0 && label.toLowerCase() !== '(none)');\n}\n\n/**\n * Read the draft the agent produced.\n *\n * @throws IssueDraftParseError when the block is absent or has no usable\n * title/body, so a malformed answer fails loudly instead of creating an empty\n * Issue.\n */\nexport function parseIssueDraft(output: string): IssueDraft {\n const normalized = output.replace(/\\r\\n?/g, '\\n');\n const block = extractTag(normalized, DRAFT_TAG);\n\n if (block === null) {\n throw new IssueDraftParseError(\n `The agent did not emit an <${DRAFT_TAG}> block, so there is no Issue to create. ` +\n `Output was: ${normalized.trim().slice(0, 300) || '(empty)'}`,\n );\n }\n\n const title = (extractTag(block, 'title') ?? '').trim();\n const body = (extractTag(block, 'body') ?? '').trim();\n\n if (title.length === 0) {\n throw new IssueDraftParseError(`The <${DRAFT_TAG}> block has no <title>.`);\n }\n if (body.length === 0) {\n throw new IssueDraftParseError(`The <${DRAFT_TAG}> block has no <body>.`);\n }\n\n // Optional, and deliberately so: a repository with no Issue Types and no\n // templates emits neither, and the draft is exactly what it was before.\n const type = (extractTag(block, 'type') ?? '').trim();\n const template = (extractTag(block, 'template') ?? '').trim();\n\n return {\n title,\n body,\n labels: parseLabels(extractTag(block, 'labels')),\n ...(type === '' || type.toLowerCase() === '(none)' ? {} : { type }),\n ...(template === '' || template.toLowerCase() === '(none)' ? {} : { template }),\n };\n}\n","import type { LabelDefinition } from '../policy/types.js';\nimport { run } from '../utils/shell.js';\n\n/**\n * Reconciling the labels an agent suggested with the ones the repository\n * actually has.\n *\n * A workflow tool has no business changing a repository's taxonomy. Labels are\n * governance: a team that deleted `high`/`medium`/`low` in favour of a native\n * priority field, or `bug`/`enhancement` in favour of Issue Types, made a\n * decision — and a generator that silently recreates them undoes it, quietly and\n * repository-wide.\n *\n * So the default is to **validate, never create**. `policy.issues.allowLabelCreation`\n * restores the old behaviour for repositories that want it.\n */\n\nexport interface LabelReconciliation {\n /** Labels to apply, in the repository's own casing. */\n labels: string[];\n /** Suggested labels the repository does not have. */\n missing: string[];\n}\n\n/**\n * Intersect the suggested labels with the repository's real ones.\n *\n * Matching is case-insensitive and the result carries the **repository's**\n * casing: `gh issue create --label Bug` fails on a repository whose label is\n * `bug`, and an agent has no way to know which one it is.\n *\n * An empty `known` means the labels could not be read at all — no policy, no\n * `gh`, no network. That is not evidence the labels do not exist, so the\n * suggestions pass through untouched and the behaviour is the one that shipped\n * before this layer. Refusing to label an issue because discovery was offline\n * would be the wrong failure.\n */\nexport function reconcileLabels(\n suggested: string[],\n known: LabelDefinition[],\n): LabelReconciliation {\n if (known.length === 0) {\n return { labels: [...suggested], missing: [] };\n }\n\n const canonical = new Map(known.map((label) => [label.name.toLowerCase(), label.name]));\n\n const labels: string[] = [];\n const missing: string[] = [];\n for (const suggestion of suggested) {\n const match = canonical.get(suggestion.trim().toLowerCase());\n if (match === undefined) {\n if (!missing.includes(suggestion)) missing.push(suggestion);\n continue;\n }\n if (!labels.includes(match)) labels.push(match);\n }\n\n return { labels, missing };\n}\n\n/**\n * Create the labels the repository is missing, for\n * `policy.issues.allowLabelCreation: true`.\n *\n * Best-effort per label: one that cannot be created is reported and skipped, so\n * a single failure does not cost the Issue. Returns the labels that now exist.\n */\nexport async function createMissingLabels(\n names: string[],\n warn: (message: string) => void,\n): Promise<string[]> {\n const created: string[] = [];\n\n for (const name of names) {\n const result = await run('gh', ['label', 'create', name]);\n if (result.exitCode === 0) {\n created.push(name);\n continue;\n }\n // gh answers \"already exists\" when a label was created between the\n // discovery and now, which is a success for our purposes.\n const detail = (result.stderr || result.stdout).trim();\n if (/already exists/i.test(detail)) {\n created.push(name);\n continue;\n }\n warn(`Could not create label \"${name}\": ${detail || 'gh label create failed'}`);\n }\n\n return created;\n}\n","import { loadIssuesConfig, loadPolicyConfig } from '../config.js';\nimport { DEFAULT_HEADLESS_TIMEOUT_MS, runHeadless } from '../core/headless.js';\nimport { applyPlaceholders, loadPrompt } from '../core/prompt-resolver.js';\nimport { publishPhaseMetrics } from '../core/session-metrics.js';\nimport { isoNow } from '../core/state-manager.js';\nimport { getGlobalTimeout } from '../core/verbose.js';\nimport { ensureProvidersRegistered } from '../issues/bootstrap.js';\nimport { IssueDraftParseError, parseIssueDraft } from '../issues/draft.js';\nimport { createMissingLabels, reconcileLabels } from '../issues/label-policy.js';\nimport { getProvider } from '../issues/registry.js';\nimport type { Issue, IssueDraft, IssueGenerateTarget } from '../issues/types.js';\nimport { loadRepositoryPolicy } from '../policy/index.js';\nimport { resolvePolicyPlaceholders } from '../policy/placeholders.js';\nimport { resolveIssuePaths, resolveProjectPaths } from '../storage/resolve.js';\nimport { printError, printInfo, printSuccess, printWarning } from '../ui/logger.js';\n\n/** Human-readable pointer to a created Issue. */\nasync function issueLocation(issue: Issue): Promise<string> {\n return issue.remoteRef ?? (await resolveIssuePaths(issue.id)).issueFile;\n}\n\n/**\n * Ask the agent for the Issue content.\n *\n * The agent only drafts: creation belongs to the providers, so the same draft\n * can be persisted to GitHub, to the local files, or to both.\n */\nasync function draftIssue(\n promptText: string,\n destination: IssueGenerateTarget,\n): Promise<IssueDraft> {\n // The duplicate check reads the local issues, which live in the global\n // storage: the path has to be handed over (and allowed) explicitly, since it\n // is outside the working directory the agent is started in.\n const { issuesDir } = await resolveProjectPaths();\n\n const template = await loadPrompt('generate');\n const prompt = applyPlaceholders(template, {\n // The repository's own conventions. Empty when it declares none, which is\n // what keeps the rendered prompt identical to the pre-policy one.\n ...(await resolvePolicyPlaceholders({ remote: destination !== 'local' })),\n __REMOTE_DISCOVERY__: destination === 'local' ? '' : 'enabled',\n __DESTINATION__: destination,\n __USER_PROMPT__: promptText,\n __LOCAL_ISSUES_DIR__: issuesDir,\n });\n\n const startedAtMs = Date.now();\n const result = await runHeadless({\n prompt,\n maxTurns: 15,\n timeout: getGlobalTimeout() ?? DEFAULT_HEADLESS_TIMEOUT_MS,\n // json (not text) so the CLI reports usage: the envelope's `result` field\n // carries the same assistant text parseIssueDraft() already consumed.\n outputFormat: 'json',\n allowedTools: ['Bash', 'Read', 'Glob', 'Grep'],\n addDirs: [issuesDir],\n statusMessage: 'Drafting issue...',\n phase: 'generate',\n permission: 'workspace',\n });\n // Before the success check: the tokens were spent either way.\n publishPhaseMetrics('generate', result.cost, startedAtMs, result.agent?.provider);\n\n if (!result.success) {\n throw new Error(`Issue creation failed: ${result.error}`);\n }\n\n return parseIssueDraft(result.result);\n}\n\n/**\n * Create the GitHub Issue and mirror it locally.\n *\n * The remote comes first on purpose: it owns the identifier, and the mirror has\n * to reuse it so both copies describe one demand. A remote failure therefore\n * leaves nothing behind, and a mirror failure is reported with the remote\n * reference that already exists.\n */\nasync function createBoth(draft: IssueDraft): Promise<Issue[]> {\n const remote = await getProvider('github').create(draft);\n\n try {\n const mirror = await getProvider('local').create({\n ...draft,\n id: remote.id,\n ...(remote.remoteRef\n ? {\n remote: {\n provider: 'github' as const,\n ref: remote.remoteRef,\n syncedAt: isoNow(),\n syncedContentHash: remote.contentHash,\n },\n }\n : {}),\n });\n return [remote, mirror];\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n throw new Error(\n `GitHub issue created at ${await issueLocation(remote)}, but the local mirror was not written: ` +\n `${message}. Nothing else was persisted; re-run with --local to create the mirror.`,\n );\n }\n}\n\nasync function createIssues(target: IssueGenerateTarget, draft: IssueDraft): Promise<Issue[]> {\n if (target === 'both') {\n return createBoth(draft);\n }\n return [\n await getProvider(target).create(draft, ...(target === 'local' ? [{ localOnly: true }] : [])),\n ];\n}\n\n/**\n * Reconcile the draft's labels with the ones the repository really has.\n *\n * Two failures are being prevented here, and only one of them is cosmetic.\n * GitHub rejects an issue whose label does not exist, so an invented label costs\n * the whole Issue. And a tool that creates the label instead rewrites a taxonomy\n * the team may have curated deliberately — which is worse, because it succeeds.\n *\n * Never throws: a policy that could not be resolved leaves the draft untouched.\n */\nasync function applyLabelPolicy(draft: IssueDraft, localOnly: boolean): Promise<IssueDraft> {\n let known: Awaited<ReturnType<typeof loadRepositoryPolicy>>['issues']['labels'];\n let allowCreation: boolean;\n try {\n const policy = await loadRepositoryPolicy({ remote: !localOnly });\n known = policy.issues.labels;\n const config = await loadPolicyConfig({ projectRoot: policy.root });\n allowCreation = !localOnly && (config.issues.allowLabelCreation ?? false);\n } catch {\n return draft;\n }\n\n const { labels, missing } = reconcileLabels(draft.labels, known);\n if (missing.length === 0) {\n return { ...draft, labels };\n }\n\n if (!allowCreation) {\n printWarning(\n `Dropping ${missing.length} label(s) this repository does not have: ${missing.join(', ')}. ` +\n 'Issue Flow does not create labels; set policy.issues.allowLabelCreation to change that.',\n );\n return { ...draft, labels };\n }\n\n const created = await createMissingLabels(missing, printWarning);\n return { ...draft, labels: [...labels, ...created] };\n}\n\nexport async function runGenerate(\n promptText: string,\n target?: IssueGenerateTarget,\n): Promise<number> {\n const config = await loadIssuesConfig();\n const destination = target ?? config.defaultGenerateTarget;\n\n ensureProvidersRegistered();\n\n let draft: IssueDraft;\n try {\n draft = await draftIssue(promptText, destination);\n } catch (err) {\n if (err instanceof IssueDraftParseError) {\n printError(`Could not read the generated Issue draft: ${err.message}`);\n } else {\n printError(err instanceof Error ? err.message : String(err));\n }\n return 1;\n }\n\n const finalDraft = await applyLabelPolicy(draft, destination === 'local');\n if (finalDraft.template !== undefined) {\n printInfo(`Following the repository's Issue Template: ${finalDraft.template}`);\n }\n if (finalDraft.type !== undefined) {\n printInfo(`Issue Type: ${finalDraft.type}`);\n }\n\n let created: Issue[];\n try {\n created = await createIssues(destination, finalDraft);\n } catch (err) {\n printError(err instanceof Error ? err.message : String(err));\n return 1;\n }\n\n for (const issue of created) {\n printSuccess(`Issue created (${issue.source}): ${await issueLocation(issue)}`);\n }\n return 0;\n}\n"],"mappings":"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","names":[]}
@@ -13,8 +13,7 @@ import {
13
13
  normalizeRemoteUrl,
14
14
  preflightRepository,
15
15
  stripRemoteUrlCredentials
16
- } from "./chunk-YVPZUN6X.js";
17
- import "./chunk-XEYH6ZZI.js";
16
+ } from "./chunk-TJVX42KY.js";
18
17
  export {
19
18
  committedStoryIds,
20
19
  describePreflight,
@@ -30,4 +29,4 @@ export {
30
29
  preflightRepository,
31
30
  stripRemoteUrlCredentials
32
31
  };
33
- //# sourceMappingURL=git-A2IP32PQ.js.map
32
+ //# sourceMappingURL=git-LCG45YXD.js.map