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 @@
1
+ {"version":3,"sources":["../src/core/task-plan.ts"],"sourcesContent":["import { taskPlanSchema } from '../schemas.js';\nimport type { TaskPlan, UserStory } from '../types.js';\n\n/** Facts needed by the current iteration; never a replacement for the mutable plan. */\nexport function executionContext(plan: TaskPlan) {\n const ready = eligibleStories(plan.userStories);\n const active = plan.lastReviewFindings ? undefined : ready[0];\n return {\n objective: plan.description,\n branchName: plan.branchName,\n noBranch: plan.noBranch ?? false,\n counts: {\n total: plan.userStories.length,\n passed: plan.userStories.filter((s) => s.passes).length,\n },\n remainingStoryIds: plan.userStories.filter((s) => !s.passes).map((s) => s.id),\n activeStory: active\n ? {\n id: active.id,\n title: active.title,\n description: active.description,\n acceptanceCriteria: active.acceptanceCriteria,\n notes: active.notes,\n dependencies: (active.dependencies ?? []).map((id) => ({\n id,\n passes: plan.userStories.find((story) => story.id === id)?.passes ?? false,\n })),\n }\n : null,\n lastReviewFindings: plan.lastReviewFindings ?? null,\n lastError: plan.lastError,\n correctionCycle: plan.correctionCycle,\n maxCorrectionCycles: plan.maxCorrectionCycles,\n };\n}\n\nexport interface ArtifactError {\n code: string;\n path: string;\n message: string;\n}\n\n/** Structural dependencies are deliberately never inferred from story prose. */\nexport function validateStoryDependencies(stories: readonly UserStory[]): ArtifactError[] {\n const errors: ArtifactError[] = [];\n const byId = new Map<string, UserStory>();\n for (const [index, story] of stories.entries()) {\n if (byId.has(story.id)) {\n errors.push({\n code: 'duplicate_story',\n path: `userStories.${index}.id`,\n message: `Duplicate story ID: ${story.id}`,\n });\n }\n byId.set(story.id, story);\n for (const id of story.dependencies ?? []) {\n if (id === story.id || !stories.some((candidate) => candidate.id === id)) {\n errors.push({\n code: id === story.id ? 'self_dependency' : 'missing_dependency',\n path: `userStories.${index}.dependencies`,\n message: `${story.id} depends on ${id}`,\n });\n }\n }\n }\n const visited = new Set<string>();\n const active = new Set<string>();\n function visit(id: string, chain: string[]): void {\n if (active.has(id)) {\n errors.push({\n code: 'dependency_cycle',\n path: 'userStories',\n message: `Dependency cycle: ${[...chain, id].join(' -> ')}`,\n });\n return;\n }\n if (visited.has(id) || !byId.has(id)) return;\n active.add(id);\n for (const dependency of byId.get(id)?.dependencies ?? []) visit(dependency, [...chain, id]);\n active.delete(id);\n visited.add(id);\n }\n for (const id of byId.keys()) visit(id, []);\n return errors;\n}\n\nexport function eligibleStories(stories: readonly UserStory[]): UserStory[] {\n const passed = new Set(stories.filter((story) => story.passes).map((story) => story.id));\n return stories\n .filter((story) => !story.passes && (story.dependencies ?? []).every((id) => passed.has(id)))\n .sort((a, b) => a.priority - b.priority);\n}\n\n/** A bounded projection for inspection, never a replacement for the source plan. */\nexport function inspectTaskPlan(value: unknown) {\n const parsed = taskPlanSchema.safeParse(value);\n if (!parsed.success) {\n return {\n schemaVersion: 1 as const,\n ok: false as const,\n data: null,\n errors: parsed.error.issues.map((issue) => ({\n code: 'schema',\n path: issue.path.join('.'),\n message: issue.message,\n })),\n };\n }\n const plan = parsed.data;\n const errors = validateStoryDependencies(plan.userStories);\n if (errors.length) return { schemaVersion: 1 as const, ok: false as const, data: null, errors };\n const ready = eligibleStories(plan.userStories);\n const correctionRequired = Boolean(plan.lastReviewFindings);\n const next = correctionRequired ? undefined : ready[0];\n return {\n schemaVersion: 1 as const,\n ok: true as const,\n data: {\n counts: {\n total: plan.userStories.length,\n passed: plan.userStories.filter((story) => story.passes).length,\n ready: ready.length,\n },\n readyStoryIds: ready.map((story) => story.id),\n blockedStories: plan.userStories\n .filter((story) => !story.passes && !ready.includes(story))\n .map((story) => ({\n id: story.id,\n dependencies: (story.dependencies ?? []).filter(\n (id) => !plan.userStories.find((candidate) => candidate.id === id)?.passes,\n ),\n })),\n correctionRequired,\n executionComplete:\n plan.userStories.length > 0 &&\n plan.userStories.every((story) => story.passes) &&\n !correctionRequired,\n nextStory: next\n ? {\n id: next.id,\n title: next.title,\n description: next.description,\n acceptanceCriteria: next.acceptanceCriteria,\n }\n : null,\n },\n errors: [],\n };\n}\n"],"mappings":";;;;;;AAIO,SAAS,iBAAiB,MAAgB;AAC/C,QAAM,QAAQ,gBAAgB,KAAK,WAAW;AAC9C,QAAM,SAAS,KAAK,qBAAqB,SAAY,MAAM,CAAC;AAC5D,SAAO;AAAA,IACL,WAAW,KAAK;AAAA,IAChB,YAAY,KAAK;AAAA,IACjB,UAAU,KAAK,YAAY;AAAA,IAC3B,QAAQ;AAAA,MACN,OAAO,KAAK,YAAY;AAAA,MACxB,QAAQ,KAAK,YAAY,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE;AAAA,IACnD;AAAA,IACA,mBAAmB,KAAK,YAAY,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,EAAE;AAAA,IAC5E,aAAa,SACT;AAAA,MACE,IAAI,OAAO;AAAA,MACX,OAAO,OAAO;AAAA,MACd,aAAa,OAAO;AAAA,MACpB,oBAAoB,OAAO;AAAA,MAC3B,OAAO,OAAO;AAAA,MACd,eAAe,OAAO,gBAAgB,CAAC,GAAG,IAAI,CAAC,QAAQ;AAAA,QACrD;AAAA,QACA,QAAQ,KAAK,YAAY,KAAK,CAAC,UAAU,MAAM,OAAO,EAAE,GAAG,UAAU;AAAA,MACvE,EAAE;AAAA,IACJ,IACA;AAAA,IACJ,oBAAoB,KAAK,sBAAsB;AAAA,IAC/C,WAAW,KAAK;AAAA,IAChB,iBAAiB,KAAK;AAAA,IACtB,qBAAqB,KAAK;AAAA,EAC5B;AACF;AASO,SAAS,0BAA0B,SAAgD;AACxF,QAAM,SAA0B,CAAC;AACjC,QAAM,OAAO,oBAAI,IAAuB;AACxC,aAAW,CAAC,OAAO,KAAK,KAAK,QAAQ,QAAQ,GAAG;AAC9C,QAAI,KAAK,IAAI,MAAM,EAAE,GAAG;AACtB,aAAO,KAAK;AAAA,QACV,MAAM;AAAA,QACN,MAAM,eAAe,KAAK;AAAA,QAC1B,SAAS,uBAAuB,MAAM,EAAE;AAAA,MAC1C,CAAC;AAAA,IACH;AACA,SAAK,IAAI,MAAM,IAAI,KAAK;AACxB,eAAW,MAAM,MAAM,gBAAgB,CAAC,GAAG;AACzC,UAAI,OAAO,MAAM,MAAM,CAAC,QAAQ,KAAK,CAAC,cAAc,UAAU,OAAO,EAAE,GAAG;AACxE,eAAO,KAAK;AAAA,UACV,MAAM,OAAO,MAAM,KAAK,oBAAoB;AAAA,UAC5C,MAAM,eAAe,KAAK;AAAA,UAC1B,SAAS,GAAG,MAAM,EAAE,eAAe,EAAE;AAAA,QACvC,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AACA,QAAM,UAAU,oBAAI,IAAY;AAChC,QAAM,SAAS,oBAAI,IAAY;AAC/B,WAAS,MAAM,IAAY,OAAuB;AAChD,QAAI,OAAO,IAAI,EAAE,GAAG;AAClB,aAAO,KAAK;AAAA,QACV,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS,qBAAqB,CAAC,GAAG,OAAO,EAAE,EAAE,KAAK,MAAM,CAAC;AAAA,MAC3D,CAAC;AACD;AAAA,IACF;AACA,QAAI,QAAQ,IAAI,EAAE,KAAK,CAAC,KAAK,IAAI,EAAE,EAAG;AACtC,WAAO,IAAI,EAAE;AACb,eAAW,cAAc,KAAK,IAAI,EAAE,GAAG,gBAAgB,CAAC,EAAG,OAAM,YAAY,CAAC,GAAG,OAAO,EAAE,CAAC;AAC3F,WAAO,OAAO,EAAE;AAChB,YAAQ,IAAI,EAAE;AAAA,EAChB;AACA,aAAW,MAAM,KAAK,KAAK,EAAG,OAAM,IAAI,CAAC,CAAC;AAC1C,SAAO;AACT;AAEO,SAAS,gBAAgB,SAA4C;AAC1E,QAAM,SAAS,IAAI,IAAI,QAAQ,OAAO,CAAC,UAAU,MAAM,MAAM,EAAE,IAAI,CAAC,UAAU,MAAM,EAAE,CAAC;AACvF,SAAO,QACJ,OAAO,CAAC,UAAU,CAAC,MAAM,WAAW,MAAM,gBAAgB,CAAC,GAAG,MAAM,CAAC,OAAO,OAAO,IAAI,EAAE,CAAC,CAAC,EAC3F,KAAK,CAAC,GAAG,MAAM,EAAE,WAAW,EAAE,QAAQ;AAC3C;AAGO,SAAS,gBAAgB,OAAgB;AAC9C,QAAM,SAAS,eAAe,UAAU,KAAK;AAC7C,MAAI,CAAC,OAAO,SAAS;AACnB,WAAO;AAAA,MACL,eAAe;AAAA,MACf,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,QAAQ,OAAO,MAAM,OAAO,IAAI,CAAC,WAAW;AAAA,QAC1C,MAAM;AAAA,QACN,MAAM,MAAM,KAAK,KAAK,GAAG;AAAA,QACzB,SAAS,MAAM;AAAA,MACjB,EAAE;AAAA,IACJ;AAAA,EACF;AACA,QAAM,OAAO,OAAO;AACpB,QAAM,SAAS,0BAA0B,KAAK,WAAW;AACzD,MAAI,OAAO,OAAQ,QAAO,EAAE,eAAe,GAAY,IAAI,OAAgB,MAAM,MAAM,OAAO;AAC9F,QAAM,QAAQ,gBAAgB,KAAK,WAAW;AAC9C,QAAM,qBAAqB,QAAQ,KAAK,kBAAkB;AAC1D,QAAM,OAAO,qBAAqB,SAAY,MAAM,CAAC;AACrD,SAAO;AAAA,IACL,eAAe;AAAA,IACf,IAAI;AAAA,IACJ,MAAM;AAAA,MACJ,QAAQ;AAAA,QACN,OAAO,KAAK,YAAY;AAAA,QACxB,QAAQ,KAAK,YAAY,OAAO,CAAC,UAAU,MAAM,MAAM,EAAE;AAAA,QACzD,OAAO,MAAM;AAAA,MACf;AAAA,MACA,eAAe,MAAM,IAAI,CAAC,UAAU,MAAM,EAAE;AAAA,MAC5C,gBAAgB,KAAK,YAClB,OAAO,CAAC,UAAU,CAAC,MAAM,UAAU,CAAC,MAAM,SAAS,KAAK,CAAC,EACzD,IAAI,CAAC,WAAW;AAAA,QACf,IAAI,MAAM;AAAA,QACV,eAAe,MAAM,gBAAgB,CAAC,GAAG;AAAA,UACvC,CAAC,OAAO,CAAC,KAAK,YAAY,KAAK,CAAC,cAAc,UAAU,OAAO,EAAE,GAAG;AAAA,QACtE;AAAA,MACF,EAAE;AAAA,MACJ;AAAA,MACA,mBACE,KAAK,YAAY,SAAS,KAC1B,KAAK,YAAY,MAAM,CAAC,UAAU,MAAM,MAAM,KAC9C,CAAC;AAAA,MACH,WAAW,OACP;AAAA,QACE,IAAI,KAAK;AAAA,QACT,OAAO,KAAK;AAAA,QACZ,aAAa,KAAK;AAAA,QAClB,oBAAoB,KAAK;AAAA,MAC3B,IACA;AAAA,IACN;AAAA,IACA,QAAQ,CAAC;AAAA,EACX;AACF;","names":[]}
@@ -3,60 +3,54 @@ import {
3
3
  applyAcceptanceToPlan,
4
4
  formatVerificationLine,
5
5
  runAcceptanceGate
6
- } from "./chunk-6YQT3SSM.js";
6
+ } from "./chunk-IQYXXFRC.js";
7
7
  import {
8
8
  issuePlaceholders,
9
9
  resolveCommandIssue
10
- } from "./chunk-VE3IYNDN.js";
10
+ } from "./chunk-WPHC6JBR.js";
11
11
  import {
12
12
  publishPhaseMetrics,
13
13
  resolvePolicyPlaceholders
14
- } from "./chunk-HLAPOUEM.js";
14
+ } from "./chunk-WB2FVIUS.js";
15
15
  import {
16
16
  applyPlaceholders,
17
17
  loadPrompt
18
- } from "./chunk-7F7LGMVO.js";
18
+ } from "./chunk-XKR3VD2Z.js";
19
19
  import {
20
20
  DEFAULT_HEADLESS_TIMEOUT_MS,
21
21
  runHeadless
22
- } from "./chunk-UK4E2FUA.js";
23
- import {
24
- resolveIssuePaths
25
- } from "./chunk-DV7HUC4Z.js";
22
+ } from "./chunk-MQTVMB7W.js";
26
23
  import {
27
24
  getGlobalTimeout,
28
25
  printError,
29
26
  printSuccess,
30
- printWarning
31
- } from "./chunk-XZUEFTUP.js";
27
+ printWarning,
28
+ resolveIssuePaths
29
+ } from "./chunk-J6VJ5M2U.js";
32
30
  import {
33
31
  loadTaskPlan,
34
32
  saveTaskPlan
35
- } from "./chunk-SOM4QA6C.js";
33
+ } from "./chunk-GD7JZMSJ.js";
36
34
 
37
- // src/commands/review.ts
38
- function parseReviewResult(output) {
39
- const match = output.match(/<review-result>([\s\S]*?)<\/review-result>/);
40
- if (!match) {
41
- if (/STATUS:\s*PASS/i.test(output)) {
42
- return { status: "PASS" };
43
- }
44
- if (/STATUS:\s*FAIL/i.test(output)) {
45
- const findingsMatch2 = output.match(/FINDINGS:([\s\S]*?)(?:$|<\/)/);
46
- return { status: "FAIL", findings: findingsMatch2?.[1]?.trim() ?? "Unknown findings" };
47
- }
48
- return { status: "PASS" };
35
+ // src/verify/review-result.ts
36
+ function parseIssueReviewResult(output) {
37
+ const blocks = [...output.matchAll(/<review-result>([\s\S]*?)<\/review-result>/g)];
38
+ if (blocks.length !== 1 || (output.match(/<\/?review-result>/g)?.length ?? 0) !== 2 || !output.trimEnd().endsWith("</review-result>")) {
39
+ return { ok: false, error: "Expected exactly one final <review-result> block." };
49
40
  }
50
- const block = match[1];
51
- if (/STATUS:\s*PASS/i.test(block)) {
52
- return { status: "PASS" };
41
+ const body = blocks[0][1].trim();
42
+ if (body === "STATUS: PASS") return { ok: true, status: "PASS" };
43
+ const failure = body.match(/^STATUS: FAIL\s*\r?\nFINDINGS:\s*\r?\n([\s\S]+)$/);
44
+ if (failure && !/^STATUS:/m.test(failure[1])) {
45
+ const lines = failure[1].trim().split(/\r?\n/);
46
+ if (lines.every((line) => /^-\s+\S/.test(line))) {
47
+ return { ok: true, status: "FAIL", findings: lines.join("\n") };
48
+ }
53
49
  }
54
- const findingsMatch = block.match(/FINDINGS:([\s\S]*)/);
55
- return {
56
- status: "FAIL",
57
- findings: findingsMatch?.[1]?.trim() ?? "Unknown findings"
58
- };
50
+ return { ok: false, error: "Invalid review status or findings; no approval inferred." };
59
51
  }
52
+
53
+ // src/commands/review.ts
60
54
  async function runReview(issue, resolvedIssue) {
61
55
  const issueNumber = issue.replace(/^#/, "");
62
56
  const paths = await resolveIssuePaths(issueNumber);
@@ -84,25 +78,16 @@ async function runReview(issue, resolvedIssue) {
84
78
  } else {
85
79
  printSuccess(formatVerificationLine(acceptance.verdict, acceptance.level));
86
80
  }
87
- if (acceptance.review?.status === "failed") {
88
- printError("Independent review failed");
89
- try {
90
- const plan = await loadTaskPlan(tasksPath);
91
- plan.pipeline.reviewCompleted = false;
92
- plan.lastReviewFindings = acceptance.review.findings.map((finding) => finding.claim).join("\n");
93
- await saveTaskPlan(tasksPath, plan);
94
- } catch {
95
- }
96
- return 1;
97
- }
98
81
  const template = await loadPrompt("review");
99
82
  const prompt = applyPlaceholders(template, {
100
83
  // The repository's own conventions. Empty when it declares none, which is
101
84
  // what keeps the rendered prompt identical to the pre-policy one.
102
- ...await resolvePolicyPlaceholders(),
85
+ ...await resolvePolicyPlaceholders({ phase: "review" }),
103
86
  __ISSUE_NUMBER__: issueNumber,
104
87
  __TASKS_PATH__: tasksPath,
105
- ...issuePlaceholders(resolution.resolved)
88
+ __PROGRESS_FILE__: paths.progressFile,
89
+ __VERIFY_PATH__: paths.verifyFile,
90
+ ...issuePlaceholders(resolution.resolved, paths.issueFile)
106
91
  });
107
92
  const startedAtMs = Date.now();
108
93
  let reviewContext;
@@ -134,10 +119,28 @@ async function runReview(issue, resolvedIssue) {
134
119
  printError(`Review failed: ${result.error}`);
135
120
  return 1;
136
121
  }
137
- const review = parseReviewResult(result.result);
122
+ const review = parseIssueReviewResult(result.result);
123
+ if (!review.ok) {
124
+ printError(`Invalid review result: ${review.error}`);
125
+ try {
126
+ const plan = await loadTaskPlan(tasksPath);
127
+ plan.pipeline.reviewCompleted = false;
128
+ plan.issueStatus = "in_progress";
129
+ plan.completedAt = null;
130
+ plan.lastError = {
131
+ category: "review_protocol",
132
+ message: review.error,
133
+ at: (/* @__PURE__ */ new Date()).toISOString()
134
+ };
135
+ await saveTaskPlan(tasksPath, plan);
136
+ } catch {
137
+ }
138
+ return 1;
139
+ }
138
140
  if (review.status === "PASS") {
139
141
  try {
140
142
  const plan = await loadTaskPlan(tasksPath);
143
+ if (plan.lastError?.category === "review_protocol") plan.lastError = null;
141
144
  plan.pipeline.reviewCompleted = true;
142
145
  plan.lastReviewFindings = null;
143
146
  await saveTaskPlan(tasksPath, plan);
@@ -153,6 +156,9 @@ async function runReview(issue, resolvedIssue) {
153
156
  try {
154
157
  const plan = await loadTaskPlan(tasksPath);
155
158
  plan.pipeline.reviewCompleted = false;
159
+ if (plan.lastError?.category === "review_protocol") plan.lastError = null;
160
+ plan.issueStatus = "in_progress";
161
+ plan.completedAt = null;
156
162
  plan.lastReviewFindings = review.findings ?? "Unknown findings";
157
163
  await saveTaskPlan(tasksPath, plan);
158
164
  } catch {
@@ -163,4 +169,4 @@ async function runReview(issue, resolvedIssue) {
163
169
  export {
164
170
  runReview
165
171
  };
166
- //# sourceMappingURL=chunk-MI5TREN3.js.map
172
+ //# sourceMappingURL=chunk-NYDAHE3Y.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/verify/review-result.ts","../src/commands/review.ts"],"sourcesContent":["/** Portable issue-review protocol. No host, filesystem or orchestration dependencies. */\nexport type IssueReviewParse =\n | { ok: true; status: 'PASS' | 'FAIL'; findings?: string }\n | { ok: false; error: string };\n\nexport function parseIssueReviewResult(output: string): IssueReviewParse {\n const blocks = [...output.matchAll(/<review-result>([\\s\\S]*?)<\\/review-result>/g)];\n if (\n blocks.length !== 1 ||\n (output.match(/<\\/?review-result>/g)?.length ?? 0) !== 2 ||\n !output.trimEnd().endsWith('</review-result>')\n ) {\n return { ok: false, error: 'Expected exactly one final <review-result> block.' };\n }\n const body = blocks[0][1].trim();\n if (body === 'STATUS: PASS') return { ok: true, status: 'PASS' };\n const failure = body.match(/^STATUS: FAIL\\s*\\r?\\nFINDINGS:\\s*\\r?\\n([\\s\\S]+)$/);\n if (failure && !/^STATUS:/m.test(failure[1])) {\n const lines = failure[1].trim().split(/\\r?\\n/);\n if (lines.every((line) => /^-\\s+\\S/.test(line))) {\n return { ok: true, status: 'FAIL', findings: lines.join('\\n') };\n }\n }\n return { ok: false, error: 'Invalid review status or findings; no approval inferred.' };\n}\n","import { 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 { loadTaskPlan, saveTaskPlan } from '../core/state-manager.js';\nimport { getGlobalTimeout } from '../core/verbose.js';\nimport { issuePlaceholders, resolveCommandIssue } from '../issues/context.js';\nimport type { ResolvedIssue } from '../issues/types.js';\nimport { resolvePolicyPlaceholders } from '../policy/placeholders.js';\nimport { resolveIssuePaths } from '../storage/resolve.js';\nimport { printError, printSuccess, printWarning } from '../ui/logger.js';\nimport { applyAcceptanceToPlan, runAcceptanceGate } from '../verify/gate.js';\nimport { formatVerificationLine } from '../verify/present.js';\nimport { parseIssueReviewResult } from '../verify/review-result.js';\n\nexport async function runReview(issue: string, resolvedIssue?: ResolvedIssue): Promise<number> {\n const issueNumber = issue.replace(/^#/, '');\n const paths = await resolveIssuePaths(issueNumber);\n const tasksPath = paths.tasksFile;\n\n const resolution = await resolveCommandIssue(issueNumber, resolvedIssue);\n if (!resolution.ok) {\n return resolution.code;\n }\n\n const acceptance = await runAcceptanceGate({\n issueDir: paths.issueDir,\n addDirs: [paths.issueDir],\n });\n if (acceptance.verdict === 'failed') {\n try {\n const plan = await loadTaskPlan(tasksPath);\n const applied = applyAcceptanceToPlan(plan, acceptance);\n await saveTaskPlan(tasksPath, applied.plan);\n } catch {\n printError(formatVerificationLine(acceptance.verdict, acceptance.level));\n }\n return 1;\n }\n if (acceptance.verdict === 'unverified') {\n printWarning(formatVerificationLine(acceptance.verdict, acceptance.level));\n } else {\n printSuccess(formatVerificationLine(acceptance.verdict, acceptance.level));\n }\n const template = await loadPrompt('review');\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({ phase: 'review' })),\n __ISSUE_NUMBER__: issueNumber,\n __TASKS_PATH__: tasksPath,\n __PROGRESS_FILE__: paths.progressFile,\n __VERIFY_PATH__: paths.verifyFile,\n ...issuePlaceholders(resolution.resolved, paths.issueFile),\n });\n\n const startedAtMs = Date.now();\n let reviewContext: { storyIds: string[]; correctionCycle: number } | undefined;\n try {\n const plan = await loadTaskPlan(tasksPath);\n reviewContext = {\n storyIds: plan.userStories.map((story) => story.id),\n correctionCycle: plan.correctionCycle,\n };\n } catch {\n reviewContext = undefined;\n }\n const result = await runHeadless({\n prompt,\n maxTurns: 25,\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 parseReviewResult() already consumed.\n outputFormat: 'json',\n allowedTools: ['Bash', 'Read', 'Glob', 'Grep'],\n addDirs: [paths.issueDir],\n statusMessage: `Reviewing issue #${issueNumber} resolution...`,\n phase: 'review',\n permission: 'read-only',\n ...(reviewContext ?? {}),\n });\n // Before the success check: the tokens were spent either way. A correction\n // cycle calls runReview() again and the reducer sums both invocations.\n publishPhaseMetrics('review', result.cost, startedAtMs, result.agent?.provider);\n\n if (!result.success) {\n printError(`Review failed: ${result.error}`);\n return 1;\n }\n\n const review = parseIssueReviewResult(result.result);\n if (!review.ok) {\n printError(`Invalid review result: ${review.error}`);\n try {\n const plan = await loadTaskPlan(tasksPath);\n plan.pipeline.reviewCompleted = false;\n plan.issueStatus = 'in_progress';\n plan.completedAt = null;\n plan.lastError = {\n category: 'review_protocol',\n message: review.error,\n at: new Date().toISOString(),\n };\n await saveTaskPlan(tasksPath, plan);\n } catch {\n /* Standalone review may have no task plan. */\n }\n return 1;\n }\n\n if (review.status === 'PASS') {\n // Update pipeline state\n try {\n const plan = await loadTaskPlan(tasksPath);\n if (plan.lastError?.category === 'review_protocol') plan.lastError = null;\n plan.pipeline.reviewCompleted = true;\n plan.lastReviewFindings = null;\n await saveTaskPlan(tasksPath, plan);\n } catch {\n // tasks.json may not exist\n }\n\n printSuccess('Review PASSED — implementation meets acceptance criteria');\n return 0;\n }\n\n printError('Review FAILED — issues found:');\n if (review.findings) {\n console.log(review.findings);\n }\n\n // Persist the findings so a correction cycle can act on them: without this,\n // a re-run of execute sees every userStories[].passes already true and\n // exits immediately without attempting any fix (see engine.ts's\n // \"already complete\" guards).\n try {\n const plan = await loadTaskPlan(tasksPath);\n plan.pipeline.reviewCompleted = false;\n if (plan.lastError?.category === 'review_protocol') plan.lastError = null;\n plan.issueStatus = 'in_progress';\n plan.completedAt = null;\n plan.lastReviewFindings = review.findings ?? 'Unknown findings';\n await saveTaskPlan(tasksPath, plan);\n } catch {\n // tasks.json may not exist\n }\n\n return 1;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAKO,SAAS,uBAAuB,QAAkC;AACvE,QAAM,SAAS,CAAC,GAAG,OAAO,SAAS,6CAA6C,CAAC;AACjF,MACE,OAAO,WAAW,MACjB,OAAO,MAAM,qBAAqB,GAAG,UAAU,OAAO,KACvD,CAAC,OAAO,QAAQ,EAAE,SAAS,kBAAkB,GAC7C;AACA,WAAO,EAAE,IAAI,OAAO,OAAO,oDAAoD;AAAA,EACjF;AACA,QAAM,OAAO,OAAO,CAAC,EAAE,CAAC,EAAE,KAAK;AAC/B,MAAI,SAAS,eAAgB,QAAO,EAAE,IAAI,MAAM,QAAQ,OAAO;AAC/D,QAAM,UAAU,KAAK,MAAM,kDAAkD;AAC7E,MAAI,WAAW,CAAC,YAAY,KAAK,QAAQ,CAAC,CAAC,GAAG;AAC5C,UAAM,QAAQ,QAAQ,CAAC,EAAE,KAAK,EAAE,MAAM,OAAO;AAC7C,QAAI,MAAM,MAAM,CAAC,SAAS,UAAU,KAAK,IAAI,CAAC,GAAG;AAC/C,aAAO,EAAE,IAAI,MAAM,QAAQ,QAAQ,UAAU,MAAM,KAAK,IAAI,EAAE;AAAA,IAChE;AAAA,EACF;AACA,SAAO,EAAE,IAAI,OAAO,OAAO,2DAA2D;AACxF;;;ACVA,eAAsB,UAAU,OAAe,eAAgD;AAC7F,QAAM,cAAc,MAAM,QAAQ,MAAM,EAAE;AAC1C,QAAM,QAAQ,MAAM,kBAAkB,WAAW;AACjD,QAAM,YAAY,MAAM;AAExB,QAAM,aAAa,MAAM,oBAAoB,aAAa,aAAa;AACvE,MAAI,CAAC,WAAW,IAAI;AAClB,WAAO,WAAW;AAAA,EACpB;AAEA,QAAM,aAAa,MAAM,kBAAkB;AAAA,IACzC,UAAU,MAAM;AAAA,IAChB,SAAS,CAAC,MAAM,QAAQ;AAAA,EAC1B,CAAC;AACD,MAAI,WAAW,YAAY,UAAU;AACnC,QAAI;AACF,YAAM,OAAO,MAAM,aAAa,SAAS;AACzC,YAAM,UAAU,sBAAsB,MAAM,UAAU;AACtD,YAAM,aAAa,WAAW,QAAQ,IAAI;AAAA,IAC5C,QAAQ;AACN,iBAAW,uBAAuB,WAAW,SAAS,WAAW,KAAK,CAAC;AAAA,IACzE;AACA,WAAO;AAAA,EACT;AACA,MAAI,WAAW,YAAY,cAAc;AACvC,iBAAa,uBAAuB,WAAW,SAAS,WAAW,KAAK,CAAC;AAAA,EAC3E,OAAO;AACL,iBAAa,uBAAuB,WAAW,SAAS,WAAW,KAAK,CAAC;AAAA,EAC3E;AACA,QAAM,WAAW,MAAM,WAAW,QAAQ;AAC1C,QAAM,SAAS,kBAAkB,UAAU;AAAA;AAAA;AAAA,IAGzC,GAAI,MAAM,0BAA0B,EAAE,OAAO,SAAS,CAAC;AAAA,IACvD,kBAAkB;AAAA,IAClB,gBAAgB;AAAA,IAChB,mBAAmB,MAAM;AAAA,IACzB,iBAAiB,MAAM;AAAA,IACvB,GAAG,kBAAkB,WAAW,UAAU,MAAM,SAAS;AAAA,EAC3D,CAAC;AAED,QAAM,cAAc,KAAK,IAAI;AAC7B,MAAI;AACJ,MAAI;AACF,UAAM,OAAO,MAAM,aAAa,SAAS;AACzC,oBAAgB;AAAA,MACd,UAAU,KAAK,YAAY,IAAI,CAAC,UAAU,MAAM,EAAE;AAAA,MAClD,iBAAiB,KAAK;AAAA,IACxB;AAAA,EACF,QAAQ;AACN,oBAAgB;AAAA,EAClB;AACA,QAAM,SAAS,MAAM,YAAY;AAAA,IAC/B;AAAA,IACA,UAAU;AAAA,IACV,SAAS,iBAAiB,KAAK;AAAA;AAAA;AAAA,IAG/B,cAAc;AAAA,IACd,cAAc,CAAC,QAAQ,QAAQ,QAAQ,MAAM;AAAA,IAC7C,SAAS,CAAC,MAAM,QAAQ;AAAA,IACxB,eAAe,oBAAoB,WAAW;AAAA,IAC9C,OAAO;AAAA,IACP,YAAY;AAAA,IACZ,GAAI,iBAAiB,CAAC;AAAA,EACxB,CAAC;AAGD,sBAAoB,UAAU,OAAO,MAAM,aAAa,OAAO,OAAO,QAAQ;AAE9E,MAAI,CAAC,OAAO,SAAS;AACnB,eAAW,kBAAkB,OAAO,KAAK,EAAE;AAC3C,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,uBAAuB,OAAO,MAAM;AACnD,MAAI,CAAC,OAAO,IAAI;AACd,eAAW,0BAA0B,OAAO,KAAK,EAAE;AACnD,QAAI;AACF,YAAM,OAAO,MAAM,aAAa,SAAS;AACzC,WAAK,SAAS,kBAAkB;AAChC,WAAK,cAAc;AACnB,WAAK,cAAc;AACnB,WAAK,YAAY;AAAA,QACf,UAAU;AAAA,QACV,SAAS,OAAO;AAAA,QAChB,KAAI,oBAAI,KAAK,GAAE,YAAY;AAAA,MAC7B;AACA,YAAM,aAAa,WAAW,IAAI;AAAA,IACpC,QAAQ;AAAA,IAER;AACA,WAAO;AAAA,EACT;AAEA,MAAI,OAAO,WAAW,QAAQ;AAE5B,QAAI;AACF,YAAM,OAAO,MAAM,aAAa,SAAS;AACzC,UAAI,KAAK,WAAW,aAAa,kBAAmB,MAAK,YAAY;AACrE,WAAK,SAAS,kBAAkB;AAChC,WAAK,qBAAqB;AAC1B,YAAM,aAAa,WAAW,IAAI;AAAA,IACpC,QAAQ;AAAA,IAER;AAEA,iBAAa,+DAA0D;AACvE,WAAO;AAAA,EACT;AAEA,aAAW,oCAA+B;AAC1C,MAAI,OAAO,UAAU;AACnB,YAAQ,IAAI,OAAO,QAAQ;AAAA,EAC7B;AAMA,MAAI;AACF,UAAM,OAAO,MAAM,aAAa,SAAS;AACzC,SAAK,SAAS,kBAAkB;AAChC,QAAI,KAAK,WAAW,aAAa,kBAAmB,MAAK,YAAY;AACrE,SAAK,cAAc;AACnB,SAAK,cAAc;AACnB,SAAK,qBAAqB,OAAO,YAAY;AAC7C,UAAM,aAAa,WAAW,IAAI;AAAA,EACpC,QAAQ;AAAA,EAER;AAEA,SAAO;AACT;","names":[]}
@@ -1,34 +1,34 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
- GLOBAL_CONFIG_FILENAME,
4
- PROJECT_CONFIG_FILENAME,
5
3
  describeRunAgents,
6
4
  loadAgentConfig,
7
- probeAgent
8
- } from "./chunk-HY5HLFDU.js";
5
+ probeReadinessInventory
6
+ } from "./chunk-UHDXXLYH.js";
9
7
  import {
8
+ GLOBAL_CONFIG_FILENAME,
9
+ PROJECT_CONFIG_FILENAME,
10
10
  printError,
11
11
  printSuccess
12
- } from "./chunk-XZUEFTUP.js";
13
- import {
14
- getGlobalRoot
15
- } from "./chunk-HAKDLR6N.js";
16
- import {
17
- getProjectRoot
18
- } from "./chunk-YVPZUN6X.js";
12
+ } from "./chunk-J6VJ5M2U.js";
19
13
  import {
20
14
  AGENT_PHASES,
21
15
  AGENT_SCHEMA_VERSION,
22
16
  isAgentPhase,
23
17
  isAgentProviderId
24
- } from "./chunk-ICM463EO.js";
18
+ } from "./chunk-IMB6FA2F.js";
19
+ import {
20
+ getGlobalRoot
21
+ } from "./chunk-MAJ6QDRL.js";
22
+ import {
23
+ getProjectRoot
24
+ } from "./chunk-TJVX42KY.js";
25
25
  import {
26
26
  writeFileAtomic
27
- } from "./chunk-3R27MJ5R.js";
27
+ } from "./chunk-PFWHHYEO.js";
28
28
 
29
29
  // src/commands/agent.ts
30
- import { mkdir, readFile } from "fs/promises";
31
- import { dirname, join } from "path";
30
+ import { mkdir, readFile } from "node:fs/promises";
31
+ import { dirname, join } from "node:path";
32
32
  var AGENT_COMMAND_SCHEMA_VERSION = AGENT_SCHEMA_VERSION;
33
33
  function originLabel(origin) {
34
34
  switch (origin) {
@@ -54,12 +54,8 @@ function formatPhaseLine(phase, provider, model, origin, inherited) {
54
54
  async function runAgent(options = {}) {
55
55
  const config = await loadAgentConfig();
56
56
  const summary = await describeRunAgents();
57
- const [claude, codex, cursor, antigravity] = await Promise.all([
58
- probeAgent("claude"),
59
- probeAgent("codex"),
60
- probeAgent("cursor"),
61
- probeAgent("antigravity")
62
- ]);
57
+ const inventory = await probeReadinessInventory();
58
+ const providers = Object.values(inventory.providers);
63
59
  if (options.json === true) {
64
60
  const phases = {};
65
61
  for (const phase of AGENT_PHASES) {
@@ -82,33 +78,21 @@ async function runAgent(options = {}) {
82
78
  origin: summary.defaultOrigin
83
79
  },
84
80
  phases,
85
- availability: [
86
- {
87
- id: "claude",
88
- installed: claude.installed,
89
- version: claude.version,
90
- authenticated: claude.authenticated
91
- },
92
- {
93
- id: "codex",
94
- installed: codex.installed,
95
- version: codex.version,
96
- authenticated: codex.authenticated
97
- },
98
- {
99
- id: "cursor",
100
- installed: cursor.installed,
101
- version: cursor.version,
102
- authenticated: cursor.authenticated
103
- },
104
- {
105
- id: "antigravity",
106
- installed: antigravity.installed,
107
- version: antigravity.version,
108
- authenticated: antigravity.authenticated,
109
- authProbe: "none"
110
- }
111
- ]
81
+ inventory,
82
+ availability: providers.map((entry) => ({
83
+ id: entry.provider,
84
+ harness: entry.harness,
85
+ installed: entry.installed,
86
+ version: entry.version,
87
+ authenticated: entry.authentication !== "failed" && entry.installed,
88
+ authentication: entry.authentication,
89
+ state: entry.state,
90
+ source: entry.source,
91
+ observedAt: entry.observedAt,
92
+ expiresAt: entry.expiresAt,
93
+ detail: entry.detail,
94
+ ...entry.provider === "antigravity" || entry.provider === "claude" ? { authProbe: "none" } : {}
95
+ }))
112
96
  },
113
97
  null,
114
98
  2
@@ -138,13 +122,13 @@ async function runAgent(options = {}) {
138
122
  }
139
123
  console.log("");
140
124
  console.log("Disponibilidade");
141
- console.log(` claude ${(claude.version ?? "\u2014").padEnd(16)} ${claude.detail}`);
142
- console.log(` codex ${(codex.version ?? "\u2014").padEnd(16)} ${codex.detail}`);
143
- console.log(` cursor ${(cursor.version ?? "\u2014").padEnd(16)} ${cursor.detail}`);
144
- console.log(
145
- ` antigravity ${(antigravity.version ?? "\u2014").padEnd(16)} ${antigravity.detail} (no auth probe)`
146
- );
147
- if (antigravity.installed) {
125
+ for (const entry of providers) {
126
+ const authNote = entry.authentication === "unverified" ? " (auth unverified)" : "";
127
+ console.log(
128
+ ` ${entry.provider.padEnd(12)} ${(entry.version ?? "\u2014").padEnd(16)} ${entry.state.padEnd(12)} ${entry.detail}${authNote}`
129
+ );
130
+ }
131
+ if (inventory.providers.antigravity?.installed) {
148
132
  console.log(
149
133
  " Warning: every Antigravity invocation passes --dangerously-skip-permissions. --mode plan is the write containment."
150
134
  );
@@ -216,7 +200,7 @@ async function writeAgentPreference(input) {
216
200
  await writeFileAtomic(path, `${JSON.stringify(existing, null, 2)}
217
201
  `);
218
202
  if (input.provider === "cursor") {
219
- const { ensureCursorStorageGrant } = await import("./permissions-G4XCAESF.js");
203
+ const { ensureCursorStorageGrant } = await import("./permissions-NNNSRC4P.js");
220
204
  await ensureCursorStorageGrant({
221
205
  mode: input.target === "project" ? "project" : "global",
222
206
  ...input.projectRoot === void 0 ? {} : { projectRoot: input.projectRoot }
@@ -235,4 +219,4 @@ export {
235
219
  writeAgentPreference,
236
220
  persistFirstAgentChoice
237
221
  };
238
- //# sourceMappingURL=chunk-UWDCIFTP.js.map
222
+ //# sourceMappingURL=chunk-P7ZYOC23.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/agent.ts"],"sourcesContent":["import { mkdir, readFile } from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\nimport { probeReadinessInventory } from '../agents/availability.js';\nimport { describeRunAgents } from '../agents/resolve.js';\nimport {\n AGENT_PHASES,\n AGENT_SCHEMA_VERSION,\n type AgentPhase,\n type AgentProviderId,\n isAgentPhase,\n isAgentProviderId,\n} from '../agents/types.js';\nimport { GLOBAL_CONFIG_FILENAME, loadAgentConfig, PROJECT_CONFIG_FILENAME } from '../config.js';\nimport { getGlobalRoot } from '../storage/paths.js';\nimport { printError, printSuccess } from '../ui/logger.js';\nimport { writeFileAtomic } from '../utils/fs.js';\nimport { getProjectRoot } from '../utils/git.js';\n\nexport const AGENT_COMMAND_SCHEMA_VERSION = AGENT_SCHEMA_VERSION;\n\nexport interface AgentCommandOptions {\n json?: boolean;\n}\n\nexport interface AgentUseOptions {\n model?: string;\n global?: boolean;\n project?: boolean;\n phase?: string;\n}\n\nfunction originLabel(origin: string): string {\n switch (origin) {\n case 'default':\n return 'default';\n case 'global':\n return '~/.issue-flow/config.json';\n case 'project':\n return '.issue-flow.json';\n case 'env':\n return 'ISSUE_FLOW_*';\n case 'cli':\n return 'CLI';\n default:\n return origin;\n }\n}\n\nfunction formatPhaseLine(\n phase: AgentPhase,\n provider: string,\n model: string | null,\n origin: string,\n inherited: boolean,\n): string {\n const modelBit = model ? ` · ${model}` : '';\n const source = inherited ? 'herdado do padrão' : originLabel(origin);\n return `${` ${phase.padEnd(12)} ${provider}${modelBit}`.padEnd(40)}(${source})`;\n}\n\nexport async function runAgent(options: AgentCommandOptions = {}): Promise<number> {\n const config = await loadAgentConfig();\n const summary = await describeRunAgents();\n const inventory = await probeReadinessInventory();\n const providers = Object.values(inventory.providers);\n\n if (options.json === true) {\n const phases: Record<string, unknown> = {};\n for (const phase of AGENT_PHASES) {\n const resolved = summary.byPhase[phase];\n const inherited = config.phases[phase] === undefined;\n phases[phase] = {\n provider: resolved.provider,\n model: resolved.model,\n origin: resolved.origin,\n inherited,\n };\n }\n console.log(\n JSON.stringify(\n {\n schemaVersion: AGENT_COMMAND_SCHEMA_VERSION,\n default: {\n provider: summary.defaultProvider,\n model: summary.defaultModel,\n origin: summary.defaultOrigin,\n },\n phases,\n inventory,\n availability: providers.map((entry) => ({\n id: entry.provider,\n harness: entry.harness,\n installed: entry.installed,\n version: entry.version,\n authenticated: entry.authentication !== 'failed' && entry.installed,\n authentication: entry.authentication,\n state: entry.state,\n source: entry.source,\n observedAt: entry.observedAt,\n expiresAt: entry.expiresAt,\n detail: entry.detail,\n ...(entry.provider === 'antigravity' || entry.provider === 'claude'\n ? { authProbe: 'none' as const }\n : {}),\n })),\n },\n null,\n 2,\n ),\n );\n return 0;\n }\n\n const modelLabel = summary.defaultModel ?? '(default do provider)';\n console.log(\n `Agente padrão ${summary.defaultProvider.padEnd(22)} (${originLabel(summary.defaultOrigin.provider)})`,\n );\n console.log(`Modelo ${modelLabel} (${originLabel(summary.defaultOrigin.model)})`);\n console.log('');\n console.log('Por fase');\n for (const phase of AGENT_PHASES) {\n const resolved = summary.byPhase[phase];\n const inherited = config.phases[phase] === undefined;\n console.log(\n formatPhaseLine(\n phase,\n resolved.provider,\n resolved.model,\n resolved.origin.provider,\n inherited,\n ),\n );\n }\n console.log('');\n console.log('Disponibilidade');\n for (const entry of providers) {\n const authNote = entry.authentication === 'unverified' ? ' (auth unverified)' : '';\n console.log(\n ` ${entry.provider.padEnd(12)} ${(entry.version ?? '—').padEnd(16)} ${entry.state.padEnd(12)} ${entry.detail}${authNote}`,\n );\n }\n if (inventory.providers.antigravity?.installed) {\n console.log(\n ' Warning: every Antigravity invocation passes --dangerously-skip-permissions. --mode plan is the write containment.',\n );\n }\n return 0;\n}\n\nexport async function runAgentUse(\n providerRaw: string,\n options: AgentUseOptions = {},\n): Promise<number> {\n if (!isAgentProviderId(providerRaw)) {\n printError(\n `Unknown agent provider '${providerRaw}'. Valid providers: claude, codex, cursor, antigravity.`,\n );\n return 1;\n }\n const provider = providerRaw as AgentProviderId;\n\n let phase: AgentPhase | undefined;\n if (options.phase !== undefined) {\n if (!isAgentPhase(options.phase)) {\n printError(\n `Unknown agent phase '${options.phase}'. Valid phases: ${AGENT_PHASES.join(', ')}.`,\n );\n return 1;\n }\n phase = options.phase;\n }\n\n const target: 'global' | 'project' = options.project === true ? 'project' : 'global';\n try {\n const path = await writeAgentPreference({\n target,\n provider,\n model: options.model,\n phase,\n });\n printSuccess(`Wrote agent preference to ${path}`);\n return 0;\n } catch (err) {\n printError(err instanceof Error ? err.message : String(err));\n return 1;\n }\n}\n\nexport async function writeAgentPreference(input: {\n target: 'global' | 'project';\n provider: AgentProviderId;\n model?: string;\n phase?: AgentPhase;\n projectRoot?: string;\n}): Promise<string> {\n const path =\n input.target === 'global'\n ? join(getGlobalRoot(), GLOBAL_CONFIG_FILENAME)\n : join(input.projectRoot ?? (await getProjectRoot()), PROJECT_CONFIG_FILENAME);\n\n let existing: Record<string, unknown> = {};\n try {\n const raw = await readFile(path, 'utf-8');\n const parsed: unknown = JSON.parse(raw);\n if (parsed !== null && typeof parsed === 'object' && !Array.isArray(parsed)) {\n existing = parsed as Record<string, unknown>;\n }\n } catch (err: unknown) {\n if ((err as NodeJS.ErrnoException).code !== 'ENOENT') {\n throw new Error(`Could not read ${path}: ${(err as Error).message}`);\n }\n }\n\n const currentAgent =\n existing.agent !== null && typeof existing.agent === 'object' && !Array.isArray(existing.agent)\n ? { ...(existing.agent as Record<string, unknown>) }\n : {};\n\n if (input.phase) {\n const phases =\n currentAgent.phases !== null &&\n typeof currentAgent.phases === 'object' &&\n !Array.isArray(currentAgent.phases)\n ? { ...(currentAgent.phases as Record<string, unknown>) }\n : {};\n phases[input.phase] = {\n provider: input.provider,\n ...(input.model ? { model: input.model } : {}),\n };\n currentAgent.phases = phases;\n } else {\n currentAgent.provider = input.provider;\n if (input.model) currentAgent.model = input.model;\n else delete currentAgent.model;\n }\n\n existing.agent = currentAgent;\n await mkdir(dirname(path), { recursive: true });\n await writeFileAtomic(path, `${JSON.stringify(existing, null, 2)}\\n`);\n if (input.provider === 'cursor') {\n const { ensureCursorStorageGrant } = await import('../agents/permissions.js');\n await ensureCursorStorageGrant({\n mode: input.target === 'project' ? 'project' : 'global',\n ...(input.projectRoot === undefined ? {} : { projectRoot: input.projectRoot }),\n });\n }\n return path;\n}\n\n/** Used by init to persist a first-run choice without touching other keys. */\nexport async function persistFirstAgentChoice(provider: AgentProviderId): Promise<string> {\n return writeAgentPreference({ target: 'global', provider });\n}\n"],"mappings":"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","names":[]}
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/utils/fs.ts
4
- import * as fsp from "fs/promises";
5
- import { dirname } from "path";
4
+ import * as fsp from "node:fs/promises";
5
+ import { dirname } from "node:path";
6
6
  async function writeFileAtomic(path, content, fs = fsp) {
7
7
  await fs.mkdir(dirname(path), { recursive: true });
8
8
  const tmpFile = `${path}.tmp`;
@@ -22,4 +22,4 @@ async function writeFileAtomic(path, content, fs = fsp) {
22
22
  export {
23
23
  writeFileAtomic
24
24
  };
25
- //# sourceMappingURL=chunk-3R27MJ5R.js.map
25
+ //# sourceMappingURL=chunk-PFWHHYEO.js.map
@@ -1,60 +1,62 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  writeAgentPreference
4
- } from "./chunk-UWDCIFTP.js";
5
- import {
6
- writeRoutingPreference
7
- } from "./chunk-RCZJQUTC.js";
4
+ } from "./chunk-P7ZYOC23.js";
8
5
  import {
9
6
  resolvePackageDir
10
- } from "./chunk-7F7LGMVO.js";
7
+ } from "./chunk-XKR3VD2Z.js";
8
+ import {
9
+ writeRoutingPreference
10
+ } from "./chunk-UDRAD7MF.js";
11
11
  import {
12
12
  MODEL_CATALOG
13
- } from "./chunk-D6ZBGJ3L.js";
13
+ } from "./chunk-F2NFJ27Z.js";
14
14
  import {
15
15
  getPackageVersion
16
- } from "./chunk-C5TL7T4V.js";
16
+ } from "./chunk-2YM2VH6R.js";
17
17
  import {
18
18
  loadRoutingConfig,
19
19
  probeAgent
20
- } from "./chunk-HY5HLFDU.js";
20
+ } from "./chunk-UHDXXLYH.js";
21
21
  import {
22
22
  printInfo,
23
23
  printWarning
24
- } from "./chunk-XZUEFTUP.js";
24
+ } from "./chunk-J6VJ5M2U.js";
25
25
  import {
26
26
  readDiagnostics
27
- } from "./chunk-QPGEFLMY.js";
28
- import {
29
- getGlobalRoot
30
- } from "./chunk-HAKDLR6N.js";
27
+ } from "./chunk-7CMVL4X6.js";
31
28
  import {
32
29
  NullPublisher
33
- } from "./chunk-DUS5ZNKL.js";
30
+ } from "./chunk-DIMDAYZS.js";
34
31
  import {
35
32
  isoNow
36
- } from "./chunk-SOM4QA6C.js";
33
+ } from "./chunk-GD7JZMSJ.js";
37
34
  import {
38
35
  isAgentPhase,
39
36
  isAgentProviderId,
40
37
  isProcessAlive,
41
- routingConfigInputSchema,
42
38
  webLockSchema
43
- } from "./chunk-ICM463EO.js";
39
+ } from "./chunk-IMB6FA2F.js";
40
+ import {
41
+ routingConfigInputSchema
42
+ } from "./chunk-XNK5UN2D.js";
43
+ import {
44
+ getGlobalRoot
45
+ } from "./chunk-MAJ6QDRL.js";
44
46
 
45
47
  // src/web/lock.ts
46
- import { spawn as nodeSpawn } from "child_process";
47
- import { randomUUID as randomUUID2 } from "crypto";
48
- import { mkdir, readFile as readFile2, rm, writeFile } from "fs/promises";
49
- import { join as join2 } from "path";
48
+ import { spawn as nodeSpawn } from "node:child_process";
49
+ import { randomUUID as randomUUID2 } from "node:crypto";
50
+ import { mkdir, readFile as readFile2, rm, writeFile } from "node:fs/promises";
51
+ import { join as join2 } from "node:path";
50
52
  import chalk2 from "chalk";
51
53
  import { execa } from "execa";
52
54
 
53
55
  // src/web/server.ts
54
- import { createHash, randomUUID } from "crypto";
55
- import { readFile } from "fs/promises";
56
- import { createServer } from "http";
57
- import { join } from "path";
56
+ import { createHash, randomUUID } from "node:crypto";
57
+ import { readFile } from "node:fs/promises";
58
+ import { createServer } from "node:http";
59
+ import { join } from "node:path";
58
60
  import chalk from "chalk";
59
61
  var SESSION_LIST_DESCRIPTION_MAX = 280;
60
62
  function truncateSessionDescription(text, max = SESSION_LIST_DESCRIPTION_MAX) {
@@ -315,13 +317,22 @@ async function startWebServer(options) {
315
317
  effective: snapshot?.configuration ?? null,
316
318
  capturedForSession: snapshot?.sessionId ?? null,
317
319
  routing: await loadRoutingConfig(),
318
- catalog: harnesses.map((harness, index) => ({
319
- harness,
320
- provider: providers[index],
321
- installed: availability[index]?.installed ?? false,
322
- authenticated: availability[index]?.authenticated ?? false,
323
- models: MODEL_CATALOG[harness] ?? []
324
- })),
320
+ catalog: harnesses.map((harness, index) => {
321
+ const entry = availability[index];
322
+ return {
323
+ harness,
324
+ provider: providers[index],
325
+ installed: entry?.installed ?? false,
326
+ authenticated: entry?.authenticated ?? false,
327
+ authentication: entry?.authentication ?? "failed",
328
+ state: entry?.state ?? "unavailable",
329
+ source: entry?.source ?? "probe",
330
+ observedAt: entry?.observedAt ?? null,
331
+ expiresAt: entry?.expiresAt ?? null,
332
+ detail: entry?.detail ?? null,
333
+ models: MODEL_CATALOG[harness] ?? []
334
+ };
335
+ }),
325
336
  writable: isLoopbackHost(options.host),
326
337
  writeScope: "global preferences for future executions"
327
338
  });
@@ -930,4 +941,4 @@ export {
930
941
  stopWebMonitor,
931
942
  ensureWebMonitor
932
943
  };
933
- //# sourceMappingURL=chunk-2SUFAE6X.js.map
944
+ //# sourceMappingURL=chunk-PHPAK2L6.js.map