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
@@ -4,39 +4,40 @@ import {
4
4
  PRIORS_VERSION,
5
5
  RECOMMENDED_POLICY_VERSION,
6
6
  decideRouting
7
- } from "./chunk-D6ZBGJ3L.js";
7
+ } from "./chunk-F2NFJ27Z.js";
8
8
  import {
9
- GLOBAL_CONFIG_FILENAME,
10
- loadRoutingConfig
11
- } from "./chunk-HY5HLFDU.js";
12
- import {
13
- resolveIssuePaths
14
- } from "./chunk-DV7HUC4Z.js";
9
+ loadRoutingConfig,
10
+ probeReadinessInventory
11
+ } from "./chunk-UHDXXLYH.js";
15
12
  import {
13
+ GLOBAL_CONFIG_FILENAME,
16
14
  printError,
17
15
  printInfo,
18
- printSuccess
19
- } from "./chunk-XZUEFTUP.js";
20
- import {
21
- getGlobalRoot
22
- } from "./chunk-HAKDLR6N.js";
23
- import {
24
- getProjectRoot
25
- } from "./chunk-YVPZUN6X.js";
16
+ printSuccess,
17
+ resolveIssuePaths
18
+ } from "./chunk-J6VJ5M2U.js";
26
19
  import {
27
20
  loadTaskPlan
28
- } from "./chunk-SOM4QA6C.js";
21
+ } from "./chunk-GD7JZMSJ.js";
22
+ import {
23
+ AGENT_PHASES
24
+ } from "./chunk-IMB6FA2F.js";
29
25
  import {
30
- AGENT_PHASES,
31
26
  routingConfigInputSchema
32
- } from "./chunk-ICM463EO.js";
27
+ } from "./chunk-XNK5UN2D.js";
28
+ import {
29
+ getGlobalRoot
30
+ } from "./chunk-MAJ6QDRL.js";
31
+ import {
32
+ getProjectRoot
33
+ } from "./chunk-TJVX42KY.js";
33
34
  import {
34
35
  writeFileAtomic
35
- } from "./chunk-3R27MJ5R.js";
36
+ } from "./chunk-PFWHHYEO.js";
36
37
 
37
38
  // src/commands/routing.ts
38
- import { mkdir, readFile } from "fs/promises";
39
- import { dirname, join } from "path";
39
+ import { mkdir, readFile } from "node:fs/promises";
40
+ import { dirname, join } from "node:path";
40
41
  var ROUTING_COMMAND_SCHEMA_VERSION = 1;
41
42
  function targetLabel(target) {
42
43
  if (target === void 0) return "\u2014";
@@ -112,6 +113,7 @@ async function runRoutingReport(options) {
112
113
  }
113
114
  async function runRoutingExplain(options = {}) {
114
115
  const config = await loadRoutingConfig();
116
+ const inventory = await probeReadinessInventory();
115
117
  const phases = AGENT_PHASES.map((phase) => {
116
118
  const decision = decideRouting({
117
119
  phase,
@@ -119,21 +121,47 @@ async function runRoutingExplain(options = {}) {
119
121
  actualProvider: "claude",
120
122
  mode: config.mode === "off" ? "shadow" : config.mode,
121
123
  profile: config.profile,
122
- policy: config.policy
124
+ policy: config.policy,
125
+ readiness: inventory
123
126
  });
127
+ const ranking = (decision?.candidates ?? []).filter((candidate) => candidate.eligible).slice(0, 5).map((candidate) => ({
128
+ harness: candidate.harness,
129
+ provider: candidate.provider,
130
+ model: candidate.model,
131
+ tier: candidate.tier,
132
+ score: candidate.score,
133
+ reasonCodes: candidate.reasonCodes
134
+ }));
124
135
  return {
125
136
  phase,
126
137
  target: decision?.selected ?? null,
127
- origin: config.policy === "recommended" ? "recommended policy" : "adaptive score"
138
+ origin: config.policy === "recommended" ? "recommended policy" : "adaptive score",
139
+ reasonCodes: decision?.reasonCodes ?? [],
140
+ ranking
128
141
  };
129
142
  });
130
143
  if (options.json === true) {
131
144
  console.log(
132
- JSON.stringify({ schemaVersion: ROUTING_COMMAND_SCHEMA_VERSION, config, phases }, null, 2)
145
+ JSON.stringify(
146
+ {
147
+ schemaVersion: ROUTING_COMMAND_SCHEMA_VERSION,
148
+ config,
149
+ inventory,
150
+ phases
151
+ },
152
+ null,
153
+ 2
154
+ )
133
155
  );
134
156
  return 0;
135
157
  }
136
158
  printInfo(`routing policy: ${config.policy ?? "adaptive"} (${config.mode})`);
159
+ printInfo("inventory");
160
+ for (const provider of Object.values(inventory.providers)) {
161
+ printInfo(
162
+ ` ${provider.provider.padEnd(12)} ${provider.state.padEnd(12)} auth=${provider.authentication} \xB7 ${provider.detail}`
163
+ );
164
+ }
137
165
  for (const phase of phases) {
138
166
  printInfo(
139
167
  `${phase.phase.padEnd(12)} ${targetLabel(phase.target ?? void 0)} (${phase.origin})`
@@ -175,9 +203,14 @@ async function runRoutingUse(policy, options = {}) {
175
203
  try {
176
204
  const file = await writeRoutingPreference({
177
205
  target: options.project === true ? "project" : "global",
178
- values: { policy: "recommended" }
206
+ values: {
207
+ policy: "recommended",
208
+ ...options.active === true ? { mode: "active" } : {}
209
+ }
179
210
  });
180
- printSuccess(`Wrote recommended routing policy to ${file}`);
211
+ printSuccess(
212
+ `Wrote recommended routing policy${options.active === true ? " in active mode" : ""} to ${file}`
213
+ );
181
214
  return 0;
182
215
  } catch (error) {
183
216
  printError(error instanceof Error ? error.message : String(error));
@@ -193,4 +226,4 @@ export {
193
226
  writeRoutingPreference,
194
227
  runRoutingUse
195
228
  };
196
- //# sourceMappingURL=chunk-RCZJQUTC.js.map
229
+ //# sourceMappingURL=chunk-UDRAD7MF.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/routing.ts"],"sourcesContent":["import { mkdir, readFile } from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\nimport { probeReadinessInventory } from '../agents/availability.js';\nimport { AGENT_PHASES } from '../agents/types.js';\nimport { GLOBAL_CONFIG_FILENAME, loadRoutingConfig } from '../config.js';\nimport { loadTaskPlan } from '../core/state-manager.js';\nimport { decideRouting } from '../routing/decide.js';\nimport { MODEL_CATALOG_VERSION } from '../routing/models.js';\nimport { RECOMMENDED_POLICY_VERSION } from '../routing/policy.js';\nimport { PRIORS_VERSION } from '../routing/priors.js';\nimport { type RoutingConfigInput, routingConfigInputSchema } from '../schemas.js';\nimport { getGlobalRoot } from '../storage/paths.js';\nimport { resolveIssuePaths } from '../storage/resolve.js';\nimport { printError, printInfo, printSuccess } from '../ui/logger.js';\nimport { writeFileAtomic } from '../utils/fs.js';\nimport { getProjectRoot } from '../utils/git.js';\n\nexport const ROUTING_COMMAND_SCHEMA_VERSION = 1;\n\nfunction targetLabel(\n target:\n | { harness: string; provider: string; model?: string | null; tier?: string }\n | string\n | undefined,\n): string {\n if (target === undefined) return '—';\n if (typeof target === 'string') return target;\n const tier = target.tier ? `:${target.tier}` : '';\n const model = target.model ? ` · ${target.model}` : '';\n return `${target.provider}${tier}${model}`;\n}\n\nfunction targetKey(\n target:\n | { harness: string; provider: string; model?: string | null; tier?: string }\n | string\n | undefined,\n): string {\n if (target === undefined) return '—';\n if (typeof target === 'string') return target;\n return `${target.harness}:${target.provider}:${target.model ?? ''}`;\n}\n\nexport async function runRoutingInspect(options: { json?: boolean }): Promise<number> {\n const config = await loadRoutingConfig();\n const sample = decideRouting({\n phase: 'execute',\n actualHarness: 'claude-code',\n mode: config.mode,\n profile: config.profile,\n });\n if (options.json === true) {\n console.log(\n JSON.stringify(\n {\n schemaVersion: ROUTING_COMMAND_SCHEMA_VERSION,\n priorsVersion: PRIORS_VERSION,\n modelCatalogVersion: MODEL_CATALOG_VERSION,\n recommendedPolicyVersion: RECOMMENDED_POLICY_VERSION,\n config,\n sample,\n },\n null,\n 2,\n ),\n );\n return 0;\n }\n printInfo(`routing.mode: ${config.mode} (default shadow — records, does not act)`);\n printInfo(`routing.profile: ${config.profile}`);\n if (sample) {\n printInfo(\n `sample selected=${targetLabel(sample.selected)} actual=${targetLabel(sample.actual)} class=${sample.taskClass}`,\n );\n }\n return 0;\n}\n\nexport async function runRoutingReport(options: {\n issue?: string;\n json?: boolean;\n}): Promise<number> {\n if (options.issue === undefined) {\n printInfo('Pass --issue N to compare selected vs actual on that plan.');\n return 0;\n }\n const paths = await resolveIssuePaths(options.issue);\n const plan = await loadTaskPlan(paths.tasksFile);\n const records = plan.executions ?? [];\n let agree = 0;\n let total = 0;\n for (const record of records) {\n const decision = record.routingDecision;\n if (decision === undefined || decision === null) continue;\n total += 1;\n if (targetKey(decision.selected) === targetKey(decision.actual)) agree += 1;\n }\n const rate = total === 0 ? 0 : agree / total;\n if (options.json === true) {\n console.log(\n JSON.stringify({ schemaVersion: ROUTING_COMMAND_SCHEMA_VERSION, total, agree, rate }),\n );\n return 0;\n }\n printInfo(`shadow agreement: ${agree}/${total} (${(rate * 100).toFixed(0)}%)`);\n return 0;\n}\n\nexport async function runRoutingExplain(options: { json?: boolean } = {}): Promise<number> {\n const config = await loadRoutingConfig();\n const inventory = await probeReadinessInventory();\n const phases = AGENT_PHASES.map((phase) => {\n const decision = decideRouting({\n phase,\n actualHarness: 'claude-code',\n actualProvider: 'claude',\n mode: config.mode === 'off' ? 'shadow' : config.mode,\n profile: config.profile,\n policy: config.policy,\n readiness: inventory,\n });\n const ranking = (decision?.candidates ?? [])\n .filter((candidate) => candidate.eligible)\n .slice(0, 5)\n .map((candidate) => ({\n harness: candidate.harness,\n provider: candidate.provider,\n model: candidate.model,\n tier: candidate.tier,\n score: candidate.score,\n reasonCodes: candidate.reasonCodes,\n }));\n return {\n phase,\n target: decision?.selected ?? null,\n origin: config.policy === 'recommended' ? 'recommended policy' : 'adaptive score',\n reasonCodes: decision?.reasonCodes ?? [],\n ranking,\n };\n });\n if (options.json === true) {\n console.log(\n JSON.stringify(\n {\n schemaVersion: ROUTING_COMMAND_SCHEMA_VERSION,\n config,\n inventory,\n phases,\n },\n null,\n 2,\n ),\n );\n return 0;\n }\n printInfo(`routing policy: ${config.policy ?? 'adaptive'} (${config.mode})`);\n printInfo('inventory');\n for (const provider of Object.values(inventory.providers)) {\n printInfo(\n ` ${provider.provider.padEnd(12)} ${provider.state.padEnd(12)} auth=${provider.authentication} · ${provider.detail}`,\n );\n }\n for (const phase of phases) {\n printInfo(\n `${phase.phase.padEnd(12)} ${targetLabel(phase.target ?? undefined)} (${phase.origin})`,\n );\n }\n return 0;\n}\n\nexport async function writeRoutingPreference(input: {\n target: 'global' | 'project';\n values: RoutingConfigInput;\n projectRoot?: string;\n}): Promise<string> {\n const parsed = routingConfigInputSchema.safeParse(input.values);\n if (!parsed.success || Object.keys(parsed.data).length === 0) {\n throw new Error(\n parsed.success\n ? 'At least one routing setting is required.'\n : `Invalid routing setting: ${parsed.error.issues[0]?.message ?? 'invalid value'}.`,\n );\n }\n const path =\n input.target === 'global'\n ? join(getGlobalRoot(), GLOBAL_CONFIG_FILENAME)\n : join(input.projectRoot ?? (await getProjectRoot()), '.issue-flow.json');\n let existing: Record<string, unknown> = {};\n try {\n const value: unknown = JSON.parse(await readFile(path, 'utf-8'));\n if (value !== null && typeof value === 'object' && !Array.isArray(value)) {\n existing = value as Record<string, unknown>;\n }\n } catch (error: unknown) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') {\n throw new Error(`Could not read ${path}: ${(error as Error).message}`);\n }\n }\n const current =\n existing.routing !== null &&\n typeof existing.routing === 'object' &&\n !Array.isArray(existing.routing)\n ? (existing.routing as Record<string, unknown>)\n : {};\n existing.routing = { ...current, ...parsed.data };\n await mkdir(dirname(path), { recursive: true });\n await writeFileAtomic(path, `${JSON.stringify(existing, null, 2)}\\n`);\n return path;\n}\n\nexport async function runRoutingUse(\n policy: string,\n options: { active?: boolean; global?: boolean; project?: boolean } = {},\n): Promise<number> {\n if (policy !== 'recommended') {\n printError(`Unknown routing policy '${policy}'. Valid policy: recommended.`);\n return 1;\n }\n try {\n const file = await writeRoutingPreference({\n target: options.project === true ? 'project' : 'global',\n values: {\n policy: 'recommended',\n ...(options.active === true ? { mode: 'active' as const } : {}),\n },\n });\n printSuccess(\n `Wrote recommended routing policy${options.active === true ? ' in active mode' : ''} to ${file}`,\n );\n return 0;\n } catch (error) {\n printError(error instanceof Error ? error.message : String(error));\n return 1;\n }\n}\n"],"mappings":"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","names":[]}
@@ -1,26 +1,20 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
- resolveIssuePaths
4
- } from "./chunk-DV7HUC4Z.js";
5
- import {
3
+ GLOBAL_CONFIG_FILENAME,
4
+ PROJECT_CONFIG_FILENAME,
6
5
  formatDuration,
7
- printWarning
8
- } from "./chunk-XZUEFTUP.js";
9
- import {
10
- getGlobalRoot
11
- } from "./chunk-HAKDLR6N.js";
12
- import {
13
- RETRY_CONFIG_KEYS,
14
- getProjectRoot,
15
- run
16
- } from "./chunk-YVPZUN6X.js";
6
+ loadGlobalConfig,
7
+ printWarning,
8
+ readProjectConfigFile,
9
+ resolveIssuePaths
10
+ } from "./chunk-J6VJ5M2U.js";
17
11
  import {
18
12
  DEFAULT_TELEMETRY_CONFIG
19
- } from "./chunk-YII4U7ZD.js";
13
+ } from "./chunk-HEHHQU4G.js";
20
14
  import {
21
15
  parseCodexUsage,
22
16
  parseUsage
23
- } from "./chunk-SOM4QA6C.js";
17
+ } from "./chunk-GD7JZMSJ.js";
24
18
  import {
25
19
  AGENT_PHASES,
26
20
  ANTIGRAVITY_CAPABILITIES,
@@ -28,110 +22,30 @@ import {
28
22
  CODEX_CAPABILITIES,
29
23
  CURSOR_CAPABILITIES,
30
24
  agentConfigInputSchema,
31
- globalConfigSchema,
32
25
  isAgentPhase,
33
26
  isAgentProviderId,
34
- issuesConfigSchema,
35
27
  parsePhasesInput,
28
+ resilienceConfigSchema,
29
+ telemetryConfigInputSchema
30
+ } from "./chunk-IMB6FA2F.js";
31
+ import {
32
+ issuesConfigSchema,
36
33
  policyConfigInputSchema,
37
34
  policyConfigSchema,
38
35
  prReviewConfigSchema,
39
- resilienceConfigSchema,
40
36
  routingConfigInputSchema,
41
37
  routingConfigSchema,
42
- telemetryConfigInputSchema,
43
38
  verifyConfigSchema,
44
39
  webConfigSchema
45
- } from "./chunk-ICM463EO.js";
46
-
47
- // src/config/sources.ts
48
- import { existsSync } from "fs";
49
- import { readFile } from "fs/promises";
50
- import { dirname, join } from "path";
51
- var PROJECT_CONFIG_FILENAME = ".issue-flow.json";
52
- function findProjectRootFromCwd(start = process.cwd()) {
53
- let dir = start;
54
- while (true) {
55
- if (existsSync(join(dir, PROJECT_CONFIG_FILENAME)) || existsSync(join(dir, ".git"))) {
56
- return dir;
57
- }
58
- const parent = dirname(dir);
59
- if (parent === dir) return void 0;
60
- dir = parent;
61
- }
62
- }
63
- async function readProjectConfigFile(projectRoot, warn) {
64
- const root = projectRoot ?? findProjectRootFromCwd();
65
- if (root === void 0) {
66
- return null;
67
- }
68
- const filePath = join(root, PROJECT_CONFIG_FILENAME);
69
- let raw;
70
- try {
71
- raw = await readFile(filePath, "utf-8");
72
- } catch {
73
- return null;
74
- }
75
- let parsed;
76
- try {
77
- parsed = JSON.parse(raw);
78
- } catch {
79
- warn(`Ignoring ${PROJECT_CONFIG_FILENAME}: invalid JSON.`);
80
- return null;
81
- }
82
- if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
83
- warn(`Ignoring ${PROJECT_CONFIG_FILENAME}: expected a JSON object.`);
84
- return null;
85
- }
86
- return parsed;
87
- }
88
- var GLOBAL_CONFIG_FILENAME = "config.json";
89
- async function loadGlobalConfig(options = {}) {
90
- const warn = options.warn ?? printWarning;
91
- let root;
92
- try {
93
- root = options.globalRoot ?? getGlobalRoot({ env: options.env ?? process.env });
94
- } catch (err) {
95
- warn(`Ignoring ${GLOBAL_CONFIG_FILENAME}: ${err.message}`);
96
- return {};
97
- }
98
- const filePath = join(root, GLOBAL_CONFIG_FILENAME);
99
- let raw;
100
- try {
101
- raw = await readFile(filePath, "utf-8");
102
- } catch (err) {
103
- if (err.code !== "ENOENT") {
104
- warn(`Ignoring ${GLOBAL_CONFIG_FILENAME}: ${err.message}`);
105
- }
106
- return {};
107
- }
108
- let parsed;
109
- try {
110
- parsed = JSON.parse(raw);
111
- } catch {
112
- warn(`Ignoring ${GLOBAL_CONFIG_FILENAME}: invalid JSON.`);
113
- return {};
114
- }
115
- if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
116
- warn(`Ignoring ${GLOBAL_CONFIG_FILENAME}: expected a JSON object.`);
117
- return {};
118
- }
119
- const config = {};
120
- for (const [key, value] of Object.entries(parsed)) {
121
- const result = globalConfigSchema.safeParse({ [key]: value });
122
- if (!result.success) {
123
- warn(
124
- `Ignoring "${key}" key of ${GLOBAL_CONFIG_FILENAME}: ${result.error.issues[0]?.message ?? "invalid value"}.`
125
- );
126
- continue;
127
- }
128
- Object.assign(config, result.data);
129
- }
130
- return config;
131
- }
40
+ } from "./chunk-XNK5UN2D.js";
41
+ import {
42
+ RETRY_CONFIG_KEYS,
43
+ getProjectRoot,
44
+ run
45
+ } from "./chunk-TJVX42KY.js";
132
46
 
133
47
  // src/config/dependencies.ts
134
- import { platform } from "os";
48
+ import { platform } from "node:os";
135
49
 
136
50
  // src/agents/availability.ts
137
51
  import { execa as execa6 } from "execa";
@@ -340,7 +254,7 @@ function describeStall(silentMs, provider = "claude") {
340
254
  import { execa } from "execa";
341
255
 
342
256
  // src/core/stream.ts
343
- import { createInterface } from "readline";
257
+ import { createInterface } from "node:readline";
344
258
  async function readClaudeStream(stdout, options = {}) {
345
259
  const outcome = { result: "", isError: false, usage: null, events: 0, raw: "" };
346
260
  const collected = [];
@@ -1065,9 +979,9 @@ ${stdout}`
1065
979
  };
1066
980
 
1067
981
  // src/agents/codex.ts
1068
- import { mkdtemp, readFile as readFile2, rm } from "fs/promises";
1069
- import { tmpdir } from "os";
1070
- import { join as join2 } from "path";
982
+ import { mkdtemp, readFile, rm } from "node:fs/promises";
983
+ import { tmpdir } from "node:os";
984
+ import { join } from "node:path";
1071
985
  import { execa as execa3 } from "execa";
1072
986
  var BANNED_CODEX_FLAGS = [
1073
987
  "--dangerously-bypass-approvals-and-sandbox",
@@ -1221,8 +1135,8 @@ var CodexRunner = class {
1221
1135
  return { command: "codex", args: ["login", "status"] };
1222
1136
  }
1223
1137
  async run(invocation, settings) {
1224
- const tmp = await mkdtemp(join2(tmpdir(), "issue-flow-codex-"));
1225
- const outputFile = join2(tmp, "last-message.txt");
1138
+ const tmp = await mkdtemp(join(tmpdir(), "issue-flow-codex-"));
1139
+ const outputFile = join(tmp, "last-message.txt");
1226
1140
  const args = buildCodexArgv(invocation, settings, outputFile);
1227
1141
  const agent = { provider: this.id, model: settings.model };
1228
1142
  const base = { agent, harnessVersion: peekHarnessVersion(this.id) };
@@ -1259,7 +1173,7 @@ var CodexRunner = class {
1259
1173
  };
1260
1174
  const collected = [];
1261
1175
  if (subprocess.stdout) {
1262
- const { createInterface: createInterface2 } = await import("readline");
1176
+ const { createInterface: createInterface2 } = await import("node:readline");
1263
1177
  const lines = createInterface2({ input: subprocess.stdout });
1264
1178
  for await (const line of lines) {
1265
1179
  watchdog.beat();
@@ -1279,7 +1193,7 @@ ${stderr}` : "");
1279
1193
  const parsed = parseCodexStream(collected, invocation.onEvent);
1280
1194
  let lastMessage = "";
1281
1195
  try {
1282
- lastMessage = (await readFile2(outputFile, "utf-8")).trimEnd();
1196
+ lastMessage = (await readFile(outputFile, "utf-8")).trimEnd();
1283
1197
  } catch {
1284
1198
  lastMessage = "";
1285
1199
  }
@@ -1631,7 +1545,7 @@ function dropUndefined(value) {
1631
1545
  return result;
1632
1546
  }
1633
1547
  async function resolveAgentFor(phase, options = {}) {
1634
- const { getAgentCliOverrides: getAgentCliOverrides2, loadAgentConfig: loadAgentConfig2 } = await import("./config-KGZUPAUP.js");
1548
+ const { getAgentCliOverrides: getAgentCliOverrides2, loadAgentConfig: loadAgentConfig2 } = await import("./config-56B4OHZE.js");
1635
1549
  const config = options.config ?? await loadAgentConfig2();
1636
1550
  const cli = options.cli ?? getAgentCliOverrides2();
1637
1551
  const defaultBlock = {
@@ -1737,7 +1651,7 @@ async function describeRunAgents(phases = AGENT_PHASES) {
1737
1651
  defaultModel = settings.model;
1738
1652
  }
1739
1653
  }
1740
- const { loadAgentConfig: loadAgentConfig2 } = await import("./config-KGZUPAUP.js");
1654
+ const { loadAgentConfig: loadAgentConfig2 } = await import("./config-56B4OHZE.js");
1741
1655
  const config = await loadAgentConfig2();
1742
1656
  defaultProvider = config.provider;
1743
1657
  defaultModel = config.model;
@@ -1769,17 +1683,54 @@ function hasExplicitAgentSelection(config, cli, phase) {
1769
1683
  }
1770
1684
 
1771
1685
  // src/agents/availability.ts
1686
+ var READINESS_SCHEMA_VERSION = "1";
1687
+ var DEFAULT_READINESS_TTL_MS = 5 * 6e4;
1688
+ var PROVIDER_HARNESS = {
1689
+ claude: "claude-code",
1690
+ codex: "codex-cli",
1691
+ cursor: "cursor-cli",
1692
+ antigravity: "antigravity-cli"
1693
+ };
1694
+ var ALL_PROVIDERS = ["claude", "codex", "cursor", "antigravity"];
1772
1695
  var probeCache = /* @__PURE__ */ new Map();
1696
+ var inventoryCache = null;
1697
+ function deriveState(installed2, authentication, cooldownUntil, nowMs) {
1698
+ if (!installed2) return "unavailable";
1699
+ if (cooldownUntil !== null && Date.parse(cooldownUntil) > nowMs) return "unavailable";
1700
+ if (authentication === "failed") return "unavailable";
1701
+ if (authentication === "unverified") return "conditional";
1702
+ return "ready";
1703
+ }
1704
+ function toAvailability(readiness) {
1705
+ return {
1706
+ id: readiness.provider,
1707
+ installed: readiness.installed,
1708
+ version: readiness.version,
1709
+ authenticated: readiness.installed && readiness.authentication !== "failed",
1710
+ authentication: readiness.authentication,
1711
+ state: readiness.state,
1712
+ detail: readiness.detail,
1713
+ observedAt: readiness.observedAt,
1714
+ expiresAt: readiness.expiresAt,
1715
+ source: readiness.source,
1716
+ cooldownUntil: readiness.cooldownUntil
1717
+ };
1718
+ }
1773
1719
  async function probeAgent(id) {
1774
1720
  const cached = probeCache.get(id);
1775
1721
  if (cached) return cached;
1776
- const pending = probeAgentUncached(id);
1722
+ const pending = probeAgentUncached(id).then(toAvailability);
1777
1723
  probeCache.set(id, pending);
1778
1724
  return pending;
1779
1725
  }
1780
- async function probeAgentUncached(id) {
1726
+ async function probeAgentUncached(id, options = {}) {
1781
1727
  ensureRunnersRegistered();
1782
1728
  const runner = runnerFor(id);
1729
+ const now = options.now?.() ?? /* @__PURE__ */ new Date();
1730
+ const ttlMs = options.ttlMs ?? DEFAULT_READINESS_TTL_MS;
1731
+ const observedAt = now.toISOString();
1732
+ const expiresAt = new Date(now.getTime() + ttlMs).toISOString();
1733
+ const cooldownUntil = options.cooldownUntil ?? null;
1783
1734
  let version = null;
1784
1735
  let installed2 = false;
1785
1736
  try {
@@ -1790,22 +1741,85 @@ async function probeAgentUncached(id) {
1790
1741
  } catch {
1791
1742
  installed2 = false;
1792
1743
  }
1793
- let authenticated = installed2;
1744
+ let authentication = installed2 ? "unverified" : "failed";
1794
1745
  let detail = installed2 ? version ?? "installed" : "not found";
1795
- if (installed2 && runner.authCommand && runner.capabilities.authProbe !== "none") {
1746
+ let source = "probe";
1747
+ if (!installed2) {
1748
+ authentication = "failed";
1749
+ detail = "not found";
1750
+ } else if (runner.authCommand && runner.capabilities.authProbe !== "none") {
1796
1751
  try {
1797
1752
  const { command, args } = runner.authCommand();
1798
1753
  const auth = await execa6(command, args, { reject: false, timeout: 1e4 });
1799
1754
  const text = `${auth.stdout?.toString() ?? ""}
1800
1755
  ${auth.stderr?.toString() ?? ""}`;
1801
- authenticated = runner.capabilities.authProbe === "text" ? !/not logged in|not authenticated|no models available/i.test(text) : auth.exitCode === 0;
1802
- detail = authenticated ? `${version} (authenticated)` : `${version} (not authenticated)`;
1756
+ const ok = runner.capabilities.authProbe === "text" ? !/not logged in|not authenticated|no models available/i.test(text) : auth.exitCode === 0;
1757
+ authentication = ok ? "confirmed" : "failed";
1758
+ detail = ok ? `${version} (authenticated)` : `${version} (not authenticated)`;
1803
1759
  } catch {
1804
- authenticated = false;
1760
+ authentication = "failed";
1805
1761
  detail = `${version} (not authenticated)`;
1806
1762
  }
1763
+ } else {
1764
+ authentication = "unverified";
1765
+ detail = `${version} (auth unverified)`;
1766
+ source = "probe";
1767
+ }
1768
+ const state = deriveState(installed2, authentication, cooldownUntil, now.getTime());
1769
+ if (state === "unavailable" && cooldownUntil !== null && Date.parse(cooldownUntil) > now.getTime()) {
1770
+ detail = `${detail}; cooldown until ${cooldownUntil}`;
1807
1771
  }
1808
- return { id, installed: installed2, version, authenticated, detail };
1772
+ return {
1773
+ provider: id,
1774
+ harness: PROVIDER_HARNESS[id],
1775
+ installed: installed2,
1776
+ authentication,
1777
+ state,
1778
+ models: [
1779
+ {
1780
+ id: null,
1781
+ access: installed2 ? "unverified" : "denied",
1782
+ confidence: "unknown",
1783
+ source: "static-catalog"
1784
+ }
1785
+ ],
1786
+ version,
1787
+ detail,
1788
+ observedAt,
1789
+ expiresAt,
1790
+ source,
1791
+ cooldownUntil
1792
+ };
1793
+ }
1794
+ async function probeReadinessInventory(options = {}) {
1795
+ const now = options.now?.() ?? /* @__PURE__ */ new Date();
1796
+ const ttlMs = options.ttlMs ?? DEFAULT_READINESS_TTL_MS;
1797
+ if (!options.force && inventoryCache !== null && inventoryCache.expiresAtMs > now.getTime()) {
1798
+ return inventoryCache.promise;
1799
+ }
1800
+ const promise = (async () => {
1801
+ const providers = await Promise.all(
1802
+ ALL_PROVIDERS.map(
1803
+ (id) => probeAgentUncached(id, {
1804
+ now: () => now,
1805
+ ttlMs,
1806
+ cooldownUntil: options.cooldowns?.[id] ?? null
1807
+ })
1808
+ )
1809
+ );
1810
+ const byId = Object.fromEntries(providers.map((entry) => [entry.provider, entry]));
1811
+ for (const entry of providers) {
1812
+ probeCache.set(entry.provider, Promise.resolve(toAvailability(entry)));
1813
+ }
1814
+ return {
1815
+ schemaVersion: READINESS_SCHEMA_VERSION,
1816
+ observedAt: now.toISOString(),
1817
+ expiresAt: new Date(now.getTime() + ttlMs).toISOString(),
1818
+ providers: byId
1819
+ };
1820
+ })();
1821
+ inventoryCache = { expiresAtMs: now.getTime() + ttlMs, promise };
1822
+ return promise;
1809
1823
  }
1810
1824
  function installHint(id) {
1811
1825
  if (id === "codex") {
@@ -2129,7 +2143,7 @@ async function validateDependencies() {
2129
2143
  }
2130
2144
 
2131
2145
  // src/config/engine.ts
2132
- import { join as join3 } from "path";
2146
+ import { join as join2 } from "node:path";
2133
2147
  var DEFAULTS = {
2134
2148
  retryLimit: 10,
2135
2149
  retryForever: false,
@@ -2139,6 +2153,7 @@ var DEFAULTS = {
2139
2153
  function createConfig(options) {
2140
2154
  return {
2141
2155
  issueNumber: options.issueNumber,
2156
+ inPipeline: options.inPipeline,
2142
2157
  maxIterations: options.maxIterations,
2143
2158
  retryLimit: options.retryLimit ?? DEFAULTS.retryLimit,
2144
2159
  retryForever: options.retryForever ?? DEFAULTS.retryForever,
@@ -2164,13 +2179,13 @@ async function resolvePaths(config, scriptDir) {
2164
2179
  }
2165
2180
  const base = scriptDir ?? projectRoot;
2166
2181
  const standalone = {
2167
- prdFile: join3(base, "prd.json"),
2168
- progressFile: join3(base, "progress.txt"),
2169
- archiveDir: join3(base, "archive"),
2170
- lastBranchFile: join3(base, ".last-branch"),
2182
+ prdFile: join2(base, "prd.json"),
2183
+ progressFile: join2(base, "progress.txt"),
2184
+ archiveDir: join2(base, "archive"),
2185
+ lastBranchFile: join2(base, ".last-branch"),
2171
2186
  projectRoot
2172
2187
  };
2173
- const { bindTelemetry } = await import("./recorder-N7U66HCO.js");
2188
+ const { bindTelemetry } = await import("./recorder-T7426CKV.js");
2174
2189
  bindTelemetry({ tasksPath: standalone.prdFile });
2175
2190
  return standalone;
2176
2191
  }
@@ -2728,9 +2743,6 @@ async function loadWebConfig(options = {}) {
2728
2743
  var WEB_CONFIG_FILENAME = PROJECT_CONFIG_FILENAME;
2729
2744
 
2730
2745
  export {
2731
- PROJECT_CONFIG_FILENAME,
2732
- GLOBAL_CONFIG_FILENAME,
2733
- loadGlobalConfig,
2734
2746
  getShutdownSignal,
2735
2747
  onShutdown,
2736
2748
  installShutdownHandlers,
@@ -2742,6 +2754,7 @@ export {
2742
2754
  runnerFor,
2743
2755
  ensureHarnessVersion,
2744
2756
  probeAgent,
2757
+ probeReadinessInventory,
2745
2758
  mergeConfigLayers,
2746
2759
  setAgentCliOverrides,
2747
2760
  getAgentCliOverrides,
@@ -2774,4 +2787,4 @@ export {
2774
2787
  describeRunAgents,
2775
2788
  hasExplicitAgentSelection
2776
2789
  };
2777
- //# sourceMappingURL=chunk-HY5HLFDU.js.map
2790
+ //# sourceMappingURL=chunk-UHDXXLYH.js.map