@iowarp/clio-coder 0.4.4 → 0.4.6

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 (598) hide show
  1. package/CHANGELOG.md +116 -2
  2. package/CONTRIBUTING.md +39 -24
  3. package/NOTICE +16 -0
  4. package/README.md +343 -403
  5. package/dist/{acp-WNAYYF4F.js → acp-UVEVWSDL.js} +25 -24
  6. package/dist/{agents-3OKXHLOI.js → agents-VWY37DTK.js} +78 -77
  7. package/dist/assets/codewiki.json +1 -1
  8. package/dist/{auth-VKNNMGPU.js → auth-PCV2XQDV.js} +38 -38
  9. package/dist/builtins-PD652MTK.js +22 -0
  10. package/dist/{chunk-TQAHXW6Y.js → chunk-22PQ4TX4.js} +4 -4
  11. package/dist/{chunk-NRO2BJRH.js → chunk-24T2YZ7A.js} +10686 -4464
  12. package/dist/{chunk-Y55JBDO5.js → chunk-2AKYFREM.js} +38 -23
  13. package/dist/{chunk-NEDJ26B5.js → chunk-2GPGAE5W.js} +6 -51
  14. package/dist/{chunk-IKCO5N3L.js → chunk-2QPI3TR3.js} +3 -3
  15. package/dist/{chunk-HRQMFLJP.js → chunk-32KJPXAM.js} +6 -6
  16. package/dist/{chunk-65DEGPJ6.js → chunk-3A3CUMKA.js} +6 -4
  17. package/dist/{chunk-UXCU4E3T.js → chunk-3BJGMT2D.js} +35 -14
  18. package/dist/{chunk-5ICU3EUH.js → chunk-3HQVBIKD.js} +5 -5
  19. package/dist/{chunk-GWZNEVM2.js → chunk-3JLFK5MW.js} +9 -9
  20. package/dist/{chunk-XXYSBZIQ.js → chunk-3O2ZAUGQ.js} +4 -4
  21. package/dist/{chunk-GX5WYQO4.js → chunk-3QKXHCGS.js} +8 -8
  22. package/dist/{chunk-JCI2ROMZ.js → chunk-3T4DXWP6.js} +7 -7
  23. package/dist/{chunk-DR52UMZW.js → chunk-3UW3KU4A.js} +2 -2
  24. package/dist/{chunk-OEJSLEPW.js → chunk-3WBALRQH.js} +337 -337
  25. package/dist/{chunk-ELWDPP3Y.js → chunk-4DU2TVI4.js} +8 -8
  26. package/dist/{chunk-JSD46VO2.js → chunk-4U4TKZFR.js} +43 -36
  27. package/dist/{chunk-FEAXX7B6.js → chunk-4VMV6OS6.js} +4 -4
  28. package/dist/{chunk-2ZSONWVL.js → chunk-536HXRFE.js} +13 -13
  29. package/dist/{chunk-W54I7H25.js → chunk-5A6XR3RJ.js} +44 -19
  30. package/dist/{chunk-YPC6ZR5L.js → chunk-5CMARGPF.js} +119 -5
  31. package/dist/{chunk-KXDSS5WJ.js → chunk-5CY4Q6QI.js} +4 -4
  32. package/dist/{chunk-D4CJV46V.js → chunk-5GZICIYO.js} +3 -3
  33. package/dist/{chunk-4IUZQIJ3.js → chunk-5PHVPU4G.js} +2 -2
  34. package/dist/{chunk-Q4WO54TA.js → chunk-5QRX7SLS.js} +11 -11
  35. package/dist/{chunk-3ODX73FK.js → chunk-5VTJP36Q.js} +4 -4
  36. package/dist/chunk-5ZSZEYJK.js +119 -0
  37. package/dist/{chunk-EBY63B7G.js → chunk-6EXUUOSN.js} +2 -2
  38. package/dist/{chunk-DT3LWJOB.js → chunk-6HAO6X5B.js} +24 -6
  39. package/dist/{chunk-SVNXH4L2.js → chunk-6ICZKDUC.js} +2 -2
  40. package/dist/{chunk-K6T2ZAMZ.js → chunk-6OII3LOK.js} +6 -6
  41. package/dist/{chunk-36CT5VVL.js → chunk-6RYDAVQT.js} +138 -89
  42. package/dist/{chunk-I7XBWTYH.js → chunk-6VRRJT7L.js} +5 -5
  43. package/dist/{chunk-DQOVN6KV.js → chunk-6YA46L5A.js} +4 -4
  44. package/dist/{chunk-NZMNUPZZ.js → chunk-77CZRFTE.js} +3 -3
  45. package/dist/{chunk-NAI6ZFCY.js → chunk-7JSSKXG2.js} +122 -11
  46. package/dist/{chunk-2VTFPG5O.js → chunk-7WLRF2U5.js} +2 -2
  47. package/dist/chunk-7WUZEB2M.js +165 -0
  48. package/dist/{chunk-3UUXNFEX.js → chunk-7YJWEF2L.js} +61 -34
  49. package/dist/{chunk-3EBYEESD.js → chunk-A46ILRS2.js} +5 -5
  50. package/dist/{chunk-IXIY2H4R.js → chunk-ACCKVSHU.js} +5 -5
  51. package/dist/{chunk-UOIZ7DA4.js → chunk-AP7HDJOP.js} +2 -2
  52. package/dist/{chunk-JEIYHLOR.js → chunk-B3MOMLJ4.js} +12 -12
  53. package/dist/{chunk-APJ265NV.js → chunk-B5GGDIHT.js} +146 -146
  54. package/dist/{chunk-PMZVFWSR.js → chunk-B5ZTR6KZ.js} +2 -2
  55. package/dist/{chunk-I5FWO7L5.js → chunk-B6UM3OZC.js} +2 -2
  56. package/dist/{chunk-2CU2H6KE.js → chunk-BBV5TKE6.js} +5 -5
  57. package/dist/{chunk-23L32XTI.js → chunk-BLTEAUCB.js} +68 -39
  58. package/dist/{chunk-4O6MANBS.js → chunk-BS4GAMUB.js} +14 -10
  59. package/dist/{chunk-XULDXHTN.js → chunk-BT7HGDOX.js} +105 -53
  60. package/dist/{chunk-S66XZJOF.js → chunk-C27U2TYG.js} +2 -2
  61. package/dist/{chunk-QZWQA4DE.js → chunk-CBSKDFWL.js} +3 -3
  62. package/dist/{chunk-2LEAKD4C.js → chunk-CKK25WN3.js} +3 -3
  63. package/dist/{chunk-BYP5D4HI.js → chunk-CTTI7G3T.js} +2 -2
  64. package/dist/{chunk-XAKHZX5N.js → chunk-CVDAFGPW.js} +4 -4
  65. package/dist/{chunk-RKKLTLYB.js → chunk-CXQ37WJH.js} +3 -3
  66. package/dist/{chunk-GTUD2WMY.js → chunk-DBREN25X.js} +44 -9
  67. package/dist/{chunk-NDDGJUXD.js → chunk-DNCE23JJ.js} +2 -2
  68. package/dist/{chunk-HVDIIIQW.js → chunk-DNHVRBH4.js} +3 -3
  69. package/dist/{chunk-D7E7WCDF.js → chunk-DVNAPPXU.js} +2 -2
  70. package/dist/{chunk-6UINWWS6.js → chunk-DXLUVUD4.js} +16 -16
  71. package/dist/{chunk-YXLYO42X.js → chunk-DXVMLM3Z.js} +3 -2
  72. package/dist/{chunk-5MEZN6CB.js → chunk-DZK63TZJ.js} +6 -6
  73. package/dist/{chunk-IWHMRKLL.js → chunk-E3LEPLQ2.js} +2 -2
  74. package/dist/{chunk-JT2RFCC5.js → chunk-E7RF4KBO.js} +5 -5
  75. package/dist/{chunk-3R73A4XB.js → chunk-ECBHH7LU.js} +3 -3
  76. package/dist/chunk-ECOMVOHP.js +139 -0
  77. package/dist/chunk-EFSEIZE6.js +56 -0
  78. package/dist/{chunk-4NSRCOYP.js → chunk-EHOSNVVM.js} +3 -2
  79. package/dist/chunk-EM2WNQS2.js +93 -0
  80. package/dist/{chunk-57XXR6DR.js → chunk-F5Z7EWMN.js} +967 -246
  81. package/dist/{chunk-HAXOFFRH.js → chunk-FQOOGXBH.js} +7 -7
  82. package/dist/{chunk-ZTJUVLTU.js → chunk-FXFVDPWY.js} +2 -2
  83. package/dist/{chunk-XPLRXC72.js → chunk-GD55RTIW.js} +3 -3
  84. package/dist/{chunk-5B2AEOW5.js → chunk-GH5ZR6JP.js} +472 -472
  85. package/dist/{chunk-TOIVGRUX.js → chunk-GJ24ODAX.js} +5 -5
  86. package/dist/{chunk-EXLD33WO.js → chunk-GLYBJ4RQ.js} +24 -9
  87. package/dist/{chunk-26QSH3EJ.js → chunk-HHVJNVUJ.js} +5 -5
  88. package/dist/{chunk-F4EKGO4N.js → chunk-HL26ADLH.js} +4 -2
  89. package/dist/{chunk-FFUPXJC4.js → chunk-HPTJF6DG.js} +32 -56
  90. package/dist/{chunk-ID64D7PE.js → chunk-HXHFDHB6.js} +24 -24
  91. package/dist/{chunk-CUSRQKPU.js → chunk-HZ2T2YED.js} +299 -89
  92. package/dist/{chunk-YD5GIKET.js → chunk-HZFBVU5X.js} +49 -580
  93. package/dist/{chunk-6QOTUPRG.js → chunk-I2K2NCZQ.js} +65 -17
  94. package/dist/{chunk-SZAA6XDG.js → chunk-IFDRAD6F.js} +2 -2
  95. package/dist/{chunk-I2DWJ4GM.js → chunk-IGLVVNEG.js} +54 -42
  96. package/dist/{chunk-6Q3CYFD3.js → chunk-IKRWLEDA.js} +186 -35
  97. package/dist/{chunk-2JH2WHGE.js → chunk-J2FYEQ5L.js} +4 -4
  98. package/dist/{chunk-BMS5RKQY.js → chunk-JABWPKFY.js} +3 -3
  99. package/dist/{chunk-2DSOYNFC.js → chunk-JMPL7NUB.js} +7 -7
  100. package/dist/{chunk-QDC3K2U3.js → chunk-K2BLQC5E.js} +3 -3
  101. package/dist/{chunk-AUPNRN7C.js → chunk-K2HL3GBL.js} +4 -4
  102. package/dist/{chunk-54X7T7DK.js → chunk-KAFMW7WM.js} +72 -81
  103. package/dist/{chunk-OZNBF4L3.js → chunk-KECNXMDE.js} +2 -2
  104. package/dist/{chunk-BTK3SSSK.js → chunk-KMF54VH3.js} +2 -2
  105. package/dist/chunk-KPRLAMP4.js +32 -0
  106. package/dist/{chunk-ECH6PKUQ.js → chunk-KQ6IDQIB.js} +2 -2
  107. package/dist/{chunk-3UNOLWNZ.js → chunk-KTFSFCVN.js} +20 -9
  108. package/dist/{chunk-IRXAATOX.js → chunk-L4N3DWNW.js} +3 -3
  109. package/dist/{chunk-JQLNNIKT.js → chunk-LIN2K3EL.js} +6 -6
  110. package/dist/{chunk-2STGEDFV.js → chunk-LK2FN5JY.js} +2 -2
  111. package/dist/{chunk-LCGCVYZ4.js → chunk-LQTKDAUO.js} +2 -2
  112. package/dist/{chunk-U6TMQNSI.js → chunk-LTR5QCLS.js} +4 -4
  113. package/dist/chunk-LUL5Z66S.js +221 -0
  114. package/dist/{chunk-ELZVTCGV.js → chunk-LVFANMOH.js} +151 -327
  115. package/dist/{chunk-H7IXIC72.js → chunk-LY4N4TTL.js} +17 -3
  116. package/dist/{chunk-VKPAQYEB.js → chunk-LZBMXNLP.js} +5 -5
  117. package/dist/{chunk-UL3WSD3F.js → chunk-M4KFUXS7.js} +2 -2
  118. package/dist/{chunk-NXYCB2VD.js → chunk-M6TAYK66.js} +6 -6
  119. package/dist/{chunk-CFGTUFWB.js → chunk-MCJKEGHO.js} +2 -2
  120. package/dist/{chunk-6XLNIQDB.js → chunk-MYI32N4R.js} +2 -2
  121. package/dist/{chunk-4WR7VSYB.js → chunk-N2OKBREN.js} +23 -9
  122. package/dist/{chunk-3GY4F45V.js → chunk-NC4KV7EL.js} +6 -6
  123. package/dist/{chunk-LLXSDWXS.js → chunk-NF3BK5WR.js} +5 -5
  124. package/dist/{chunk-4M6Z5QVF.js → chunk-NNWJYUNO.js} +11 -11
  125. package/dist/chunk-NTK3WTHM.js +141 -0
  126. package/dist/{chunk-GYV6VZOC.js → chunk-NTTS3O53.js} +2 -2
  127. package/dist/{chunk-4BJ5BYCE.js → chunk-O3VV6IVK.js} +2 -2
  128. package/dist/{chunk-W6GROXXM.js → chunk-O5F25NIE.js} +2 -2
  129. package/dist/{chunk-NXIMQY5W.js → chunk-ODUTYZIU.js} +5 -5
  130. package/dist/{chunk-KFV5L5SK.js → chunk-OQM5IVJY.js} +118 -232
  131. package/dist/{chunk-75W7L2E2.js → chunk-P5JMBPDJ.js} +1052 -171
  132. package/dist/{chunk-XRZT5WY5.js → chunk-P5SC4DLJ.js} +4 -4
  133. package/dist/{chunk-S6PYF2XF.js → chunk-P6M7RKMI.js} +4 -4
  134. package/dist/{chunk-R6Q67RJH.js → chunk-PECBKCDK.js} +34 -6
  135. package/dist/{chunk-33YXPOE3.js → chunk-PPEZJWUG.js} +2 -2
  136. package/dist/{chunk-RXTN6AKH.js → chunk-PWWSIB2A.js} +5 -5
  137. package/dist/{chunk-DXKJURES.js → chunk-PZN2LQY6.js} +14 -11
  138. package/dist/{chunk-N56KALIC.js → chunk-Q7NNUHQV.js} +62 -35
  139. package/dist/{chunk-RQCKCSRL.js → chunk-QCOV5DFY.js} +22 -22
  140. package/dist/{chunk-3DPEIQKN.js → chunk-QH3ZTUOA.js} +2 -2
  141. package/dist/{chunk-NEKRRTYW.js → chunk-QJMRYTCX.js} +8 -8
  142. package/dist/{chunk-YNFKXPEC.js → chunk-QNWRHOMF.js} +35 -66
  143. package/dist/{chunk-YAKGTXEV.js → chunk-QRFXEO6Y.js} +2 -2
  144. package/dist/{chunk-35MSIRKH.js → chunk-QUIJZSDW.js} +2 -2
  145. package/dist/{chunk-72YIHOZQ.js → chunk-QXFBABFJ.js} +10 -10
  146. package/dist/chunk-R2CT5YDO.js +66 -0
  147. package/dist/{chunk-HHV2GANA.js → chunk-R2P2U3ZS.js} +2 -2
  148. package/dist/{chunk-IGLP3ODT.js → chunk-RGZNQ5CT.js} +15 -15
  149. package/dist/chunk-SD7SHNDW.js +15 -0
  150. package/dist/chunk-SL2RDHKO.js +19 -0
  151. package/dist/{chunk-NUGM5KR6.js → chunk-SRCEQKQS.js} +2 -2
  152. package/dist/{chunk-OMQNJVKW.js → chunk-SRZOW5L2.js} +43 -13
  153. package/dist/{chunk-UEPWCCTY.js → chunk-SXQKNKRA.js} +12 -12
  154. package/dist/{chunk-3M6DQK6S.js → chunk-T334FW2H.js} +7 -7
  155. package/dist/{chunk-V76WTFTW.js → chunk-T52TPHYC.js} +6 -6
  156. package/dist/{chunk-5636DCO5.js → chunk-TJFDL26W.js} +59 -12
  157. package/dist/{chunk-3I7MS7N2.js → chunk-TK2BMCBZ.js} +2 -2
  158. package/dist/{chunk-5OIVVPHF.js → chunk-TN5FW4XY.js} +13 -6
  159. package/dist/{chunk-LL4KHSZI.js → chunk-U2MSJ57E.js} +2 -2
  160. package/dist/{chunk-FTMGRKEF.js → chunk-U44YYLVV.js} +4 -4
  161. package/dist/{chunk-YECAMM3D.js → chunk-U7H5WRG5.js} +5 -5
  162. package/dist/{chunk-5TUB6SLS.js → chunk-UFYNOQK4.js} +7 -7
  163. package/dist/{chunk-R346GLFC.js → chunk-UHW5V7HC.js} +2 -2
  164. package/dist/{chunk-VIA6RFQZ.js → chunk-UQIVHSE4.js} +4 -4
  165. package/dist/{chunk-RAY4OVGZ.js → chunk-URBGEOH3.js} +5 -5
  166. package/dist/chunk-USZA7GWL.js +341 -0
  167. package/dist/{chunk-ZA4VCIGV.js → chunk-UUQ5G6EZ.js} +60 -41
  168. package/dist/{chunk-VG7TBQIY.js → chunk-V552WL53.js} +68 -4
  169. package/dist/{chunk-7UGL4MB5.js → chunk-VAHLPXPY.js} +10 -10
  170. package/dist/{chunk-25QBEXRS.js → chunk-VANN3GDP.js} +7 -26
  171. package/dist/{chunk-BWH6N36D.js → chunk-VHKTOLEW.js} +272 -42
  172. package/dist/{chunk-QUFRYSWI.js → chunk-VHMX7SXF.js} +129 -48
  173. package/dist/{chunk-336NSSKI.js → chunk-VNBICSS2.js} +2 -2
  174. package/dist/{chunk-VAVR4IJY.js → chunk-VQD7NH7Z.js} +3 -3
  175. package/dist/{chunk-LBMZMYH2.js → chunk-W2RJEH6Q.js} +3 -3
  176. package/dist/{chunk-7CR24IG7.js → chunk-WDV62RKY.js} +2 -2
  177. package/dist/{chunk-BJVFZO5U.js → chunk-WJIMKGD6.js} +7 -7
  178. package/dist/{chunk-USR47QNF.js → chunk-WKUYQBCG.js} +14 -14
  179. package/dist/{chunk-GHS5EBTQ.js → chunk-WNGF5AJX.js} +36 -22
  180. package/dist/{chunk-MXHC5QYU.js → chunk-WTQGRBHV.js} +5 -144
  181. package/dist/{chunk-6OSVSQL5.js → chunk-WV6TDAPN.js} +41 -23
  182. package/dist/chunk-WXA2CFJO.js +23 -0
  183. package/dist/{chunk-2ASED4PZ.js → chunk-X3BI7HTV.js} +26 -26
  184. package/dist/{chunk-QSNYB6ZV.js → chunk-XCUDZQLX.js} +3 -3
  185. package/dist/{chunk-RZDWV63N.js → chunk-XWMSPJYN.js} +6 -6
  186. package/dist/chunk-YGDMBK7O.js +567 -0
  187. package/dist/{chunk-6PAZTBPA.js → chunk-YPRSNUTC.js} +15 -6
  188. package/dist/{chunk-2IR2NMPA.js → chunk-ZIDFQJRB.js} +2 -2
  189. package/dist/{chunk-LTIKRKFL.js → chunk-ZS43Y2FT.js} +4 -4
  190. package/dist/{chunk-6EJMN2Y3.js → chunk-ZTNFYMIO.js} +2 -2
  191. package/dist/{chunk-WEPFGWHJ.js → chunk-ZZFWWYLX.js} +2 -2
  192. package/dist/cli/index.js +44 -44
  193. package/dist/clio-QQCMTUZE.js +26 -0
  194. package/dist/{code-nav-IJR2DBPR.js → code-nav-GUPM6766.js} +48 -32
  195. package/dist/codewiki/build-worker.js +76 -29
  196. package/dist/{compile-cache-OQAVB7Y5.js → compile-cache-WJEPUZEJ.js} +4 -4
  197. package/dist/{components-2TGAI2RC.js → components-TNIKXCBH.js} +13 -13
  198. package/dist/{config-IUA6OYNS.js → config-IIM7YOD3.js} +211 -124
  199. package/dist/configure-4ZM5HWJX.js +73 -0
  200. package/dist/{context-BOYF5EJM.js → context-44BZLJ3J.js} +62 -31
  201. package/dist/{context-4MPR7WKB.js → context-AIDVQKMW.js} +126 -121
  202. package/dist/{context-2DKHWH2T.js → context-OL5P3HEP.js} +92 -62
  203. package/dist/context-clear-OQV76MYP.js +184 -0
  204. package/dist/{context-index-HNG3MOME.js → context-index-HP2JFUWA.js} +13 -11
  205. package/dist/{context-map-COB37XXN.js → context-map-INTXD54D.js} +71 -21
  206. package/dist/{context-working-set-3I3FYX6Y.js → context-working-set-ZUW3EGLS.js} +32 -31
  207. package/dist/detail-UXPWRANG.js +115 -0
  208. package/dist/{dispatch-runner-RJ5I2F2O.js → dispatch-runner-P3ZW6G77.js} +192 -116
  209. package/dist/{docs-SPOV3BAN.js → docs-BL7ROUFN.js} +4 -4
  210. package/dist/{doctor-DKICC2SN.js → doctor-JJVGPZWT.js} +59 -58
  211. package/dist/{eval-OQOQUDHK.js → eval-V2RTN3UH.js} +476 -170
  212. package/dist/{eval-inventory-Y6QRFOH5.js → eval-inventory-QOYZERXJ.js} +7 -7
  213. package/dist/evidence-35PYWGSO.js +225 -0
  214. package/dist/{evidence-4DQ25GUQ.js → evidence-CIGGKI6J.js} +111 -94
  215. package/dist/{evolve-GSS52E5J.js → evolve-33SM3NJP.js} +108 -91
  216. package/dist/{extensions-G7MFLYHT.js → extensions-YVRHX6ZI.js} +16 -16
  217. package/dist/{fleet-Q37YHHAQ.js → fleet-LFO7SIPC.js} +147 -146
  218. package/dist/{fleet-commands-G7E4N7SM.js → fleet-commands-RLK72GU3.js} +27 -26
  219. package/dist/{fleet-decisions-O7M6QBA2.js → fleet-decisions-3SBSCTCW.js} +16 -15
  220. package/dist/{fleet-graph-TOUBW6OW.js → fleet-graph-JZIBCGMW.js} +39 -38
  221. package/dist/{fleet-inspect-SW33JJNI.js → fleet-inspect-2L5YGGZJ.js} +108 -91
  222. package/dist/{fleet-new-RDVJLHHH.js → fleet-new-RCKGSRDV.js} +3 -3
  223. package/dist/{fleet-preflight-CV2655TW.js → fleet-preflight-QRSHIIDE.js} +10 -9
  224. package/dist/{fleet-validate-KESZX2YH.js → fleet-validate-LIAVKDUU.js} +46 -42
  225. package/dist/{fleet-verify-UQPMTVE3.js → fleet-verify-JIK3OQZR.js} +106 -89
  226. package/dist/fleet-view-IWHYGQKK.js +118 -0
  227. package/dist/{init-PXEXQSBF.js → init-NJEDOTQW.js} +124 -123
  228. package/dist/{install-NKNG7KD4.js → install-3RZDDP23.js} +5 -5
  229. package/dist/{interop-ZG5T62U3.js → interop-RVCAYECG.js} +25 -25
  230. package/dist/inventory-74UL7UHU.js +118 -0
  231. package/dist/{library-B2W4N74O.js → library-CTKZA7K3.js} +45 -44
  232. package/dist/{memory-YCANYS5A.js → memory-I76I5VUH.js} +108 -93
  233. package/dist/{models-GERTU3YI.js → models-D4YDIQZQ.js} +64 -62
  234. package/dist/{monitor-CPNIUULB.js → monitor-NKVD55HX.js} +137 -107
  235. package/dist/{orchestrator-J4BSH4WQ.js → orchestrator-I6OATVPK.js} +1715 -1687
  236. package/dist/{panes-BOHAEGYC.js → panes-7BTYH3XQ.js} +8 -8
  237. package/dist/{panes-NXSLDQZ2.js → panes-WPOMEMRH.js} +22 -22
  238. package/dist/{paths-VSUWNC22.js → paths-J3KN7UAO.js} +12 -12
  239. package/dist/preload-EJAWJEIO.js +116 -0
  240. package/dist/{registry-LG64LTF4.js → registry-DESGAXWK.js} +3 -3
  241. package/dist/{reset-TNWTB5LU.js → reset-4XMQKDNZ.js} +22 -20
  242. package/dist/{resources-4PXNMD5G.js → resources-TVYVXK3Q.js} +41 -40
  243. package/dist/{run-D6XJ34CN.js → run-OWQNNSJU.js} +164 -157
  244. package/dist/{share-2NWMJJEE.js → share-NPZZMUXG.js} +43 -42
  245. package/dist/{skills-KR7WON5G.js → skills-OXFEAWMT.js} +47 -46
  246. package/dist/{skills-eval-O2ZNOLDS.js → skills-eval-J5TCKSJA.js} +128 -107
  247. package/dist/{skills-inventory-ZZOUBK7O.js → skills-inventory-7II4DM57.js} +41 -40
  248. package/dist/slash-commands-MDSDSWYF.js +92 -0
  249. package/dist/{steer-XA25PSCS.js → steer-S7D7IKPU.js} +7 -7
  250. package/dist/{support-7EMVWYG2.js → support-5VAEC32W.js} +14 -14
  251. package/dist/{targets-OMH2XCSN.js → targets-KILZEOCE.js} +161 -94
  252. package/dist/tasks-R6P6OV22.js +36 -0
  253. package/dist/{terminal-lease-C2J3JYRE.js → terminal-lease-LZCG2KN3.js} +12 -11
  254. package/dist/tools-6OCQ6SVB.js +28 -0
  255. package/dist/{trace-FXMXUZUF.js → trace-JHLXWUMN.js} +18 -17
  256. package/dist/{tree-sitter-HGKH6LG4.js → tree-sitter-AQUUOSYM.js} +6 -6
  257. package/dist/{tui-primitives-K5PASC3O.js → tui-primitives-RCY2HN7G.js} +3 -3
  258. package/dist/{uninstall-HALS6BLF.js → uninstall-FXYMFFRT.js} +17 -17
  259. package/dist/{upgrade-MS72RJEP.js → upgrade-D2OZH6IQ.js} +42 -41
  260. package/dist/{usage-NHG6MCJM.js → usage-PIASNUS4.js} +137 -105
  261. package/dist/{verifiers-7AUNVXDY.js → verifiers-LTHUY2PX.js} +28 -27
  262. package/dist/verify-HYF7KBVE.js +30 -0
  263. package/dist/{version-KGEG7EPO.js → version-RFPKO6T7.js} +4 -4
  264. package/dist/{web-fetch-V4FKSDAV.js → web-fetch-MQN4FH3X.js} +169 -18
  265. package/dist/wiki-generate-RK7JQ5NP.js +615 -0
  266. package/dist/{with-panes-BDQEWBRT.js → with-panes-OFTNAR4Y.js} +34 -20
  267. package/dist/worker/entry.js +108 -95
  268. package/dist/{workspace-ZJ6BFM3Q.js → workspace-DZ7JADBG.js} +6 -6
  269. package/docs/README.md +7 -6
  270. package/docs/architecture/acp.md +10 -0
  271. package/docs/architecture/architecture.md +5 -5
  272. package/docs/architecture/context-engine.md +45 -60
  273. package/docs/architecture/context-working-set.md +7 -9
  274. package/docs/architecture/dispatch-architecture-rationale.md +1 -1
  275. package/docs/architecture/evidence-and-memory.md +10 -0
  276. package/docs/architecture/pi-boundary.md +37 -7
  277. package/docs/architecture/prompt-envelope-and-tools.md +7 -7
  278. package/docs/architecture/session-lifecycle.md +4 -4
  279. package/docs/architecture/tui-design.md +45 -30
  280. package/docs/architecture/worker-dispatch-mechanics.md +4 -0
  281. package/docs/guide/commands-and-modes.md +75 -61
  282. package/docs/guide/configuration-and-targets.md +126 -26
  283. package/docs/guide/configuration-reference.md +22 -7
  284. package/docs/guide/environment-variables.md +6 -2
  285. package/docs/guide/fleet-dispatch.md +13 -6
  286. package/docs/guide/glossary.md +1 -1
  287. package/docs/guide/installation-and-lifecycle.md +79 -20
  288. package/docs/guide/proactive-memory.md +1 -1
  289. package/docs/guide/skills-marketplace.md +11 -3
  290. package/docs/guide/tool-usage.md +9 -2
  291. package/docs/process/development-pipeline.md +11 -11
  292. package/docs/process/documentation-coverage.md +1 -1
  293. package/docs/process/documentation-guide.md +2 -2
  294. package/docs/process/eval-runner.md +15 -0
  295. package/docs/process/evals-internal.md +1 -1
  296. package/docs/process/release-cut-checklist.md +24 -12
  297. package/evals/README.md +4 -0
  298. package/evals/behavioral-corpus-grader.mjs +147 -14
  299. package/evals/behavioral-model-negative-control.yaml +1 -0
  300. package/evals/behavioral-model.yaml +266 -1
  301. package/evals/fixtures/docs-retrieval.json +102 -0
  302. package/evals/fixtures/scalar-decision.json +17 -0
  303. package/evals/fixtures/scout-citation-pipeline.json +55 -0
  304. package/evals/fixtures/source-explanation.json +74 -0
  305. package/evals/fixtures/tool-arguments.json +18 -0
  306. package/evals/fixtures/tool-surface/read.txt +4 -0
  307. package/evals/fixtures/tool-surface/subdir/keep.txt +1 -0
  308. package/evals/no-edit-memory-grader.mjs +149 -0
  309. package/evals/scalar-decision-grader.py +41 -0
  310. package/evals/scalar-decision-machinery.ts +145 -0
  311. package/evals/source-explanation-grader.mjs +118 -0
  312. package/evals/tool-surface-grader.mjs +53 -0
  313. package/evals/tool-surface-model.yaml +274 -0
  314. package/package.json +14 -14
  315. package/skills/README.md +6 -6
  316. package/skills/registry.yaml +1 -1
  317. package/skills/skill-marketplace.json +1 -1
  318. package/src/cli/ask.ts +10 -10
  319. package/src/cli/bootstrap-generate.ts +6 -0
  320. package/src/cli/config-inspect.ts +24 -7
  321. package/src/cli/config-trust.ts +62 -0
  322. package/src/cli/config.ts +8 -0
  323. package/src/cli/configure-editor.ts +51 -0
  324. package/src/cli/configure-interop.ts +1 -1
  325. package/src/cli/configure-oauth.ts +1 -1
  326. package/src/cli/configure-onboarding.ts +232 -96
  327. package/src/cli/configure-prompts.ts +76 -0
  328. package/src/cli/configure-quick.ts +274 -0
  329. package/src/cli/configure-target.ts +14 -2
  330. package/src/cli/configure.ts +413 -174
  331. package/src/cli/context-map.ts +75 -14
  332. package/src/cli/context.ts +46 -17
  333. package/src/cli/eval.ts +17 -3
  334. package/src/cli/modes/print.ts +32 -4
  335. package/src/cli/oauth-manual-input.ts +1 -1
  336. package/src/cli/reset.ts +2 -0
  337. package/src/cli/run.ts +16 -14
  338. package/src/cli/select.ts +35 -4
  339. package/src/cli/skills-eval.ts +10 -8
  340. package/src/cli/steer-channel.ts +31 -18
  341. package/src/cli/targets.ts +83 -31
  342. package/src/cli/tasks.ts +10 -1
  343. package/src/cli/upgrade.ts +11 -8
  344. package/src/cli/usage.ts +24 -0
  345. package/src/cli/wiki-generate.ts +239 -96
  346. package/src/core/bash-exec.ts +43 -15
  347. package/src/core/bus-events.ts +15 -0
  348. package/src/core/config.ts +39 -15
  349. package/src/core/defaults.ts +38 -15
  350. package/src/{interactive → core}/external-editor.ts +4 -4
  351. package/src/core/file-references.ts +11 -1
  352. package/src/core/incomplete-installation.ts +3 -1
  353. package/src/core/settings-layers.ts +21 -5
  354. package/src/core/termination.ts +26 -9
  355. package/src/core/untrusted-content.ts +16 -0
  356. package/src/core/workspace-trust.ts +179 -0
  357. package/src/domains/agents/builtins/coder.md +4 -2
  358. package/src/domains/agents/builtins/context-bootstrap.md +3 -1
  359. package/src/domains/agents/builtins/documenter.md +7 -4
  360. package/src/domains/agents/builtins/researcher.md +1 -0
  361. package/src/domains/agents/builtins/scout.md +7 -1
  362. package/src/domains/agents/result-contract.ts +199 -26
  363. package/src/domains/config/classify.ts +1 -1
  364. package/src/domains/config/keybindings.ts +3 -31
  365. package/src/domains/context/bootstrap-prompt.ts +11 -9
  366. package/src/domains/context/bootstrap.ts +74 -39
  367. package/src/domains/context/clio-md.ts +88 -26
  368. package/src/domains/context/codewiki/build-operation.ts +121 -0
  369. package/src/domains/context/codewiki/build-worker-protocol.ts +37 -3
  370. package/src/domains/context/codewiki/build-worker.ts +3 -35
  371. package/src/domains/context/codewiki/coordinator.ts +36 -6
  372. package/src/domains/context/codewiki/indexer.ts +59 -19
  373. package/src/domains/context/contract.ts +6 -2
  374. package/src/domains/context/extension.ts +72 -10
  375. package/src/domains/context/fingerprint.ts +39 -34
  376. package/src/domains/context/index.ts +7 -1
  377. package/src/domains/context/prompt-context.ts +55 -14
  378. package/src/domains/context/refresh.ts +9 -57
  379. package/src/domains/context/wiki/assemble.ts +14 -10
  380. package/src/domains/context/wiki/evidence.ts +209 -0
  381. package/src/domains/context/wiki/generate.ts +201 -67
  382. package/src/domains/context/wiki/meta.ts +10 -2
  383. package/src/domains/context/wiki/plan-store.ts +70 -14
  384. package/src/domains/context/wiki/plan.ts +71 -14
  385. package/src/domains/context/wiki/prompts.ts +42 -1
  386. package/src/domains/context/wiki/source-content.ts +106 -0
  387. package/src/domains/context/wiki/staleness.ts +33 -22
  388. package/src/domains/context/working-set/contract.ts +8 -2
  389. package/src/domains/context/working-set/engine.ts +17 -4
  390. package/src/domains/context/working-set/fold.ts +15 -2
  391. package/src/domains/context/working-set/marker.ts +2 -1
  392. package/src/domains/context/working-set/project.ts +18 -7
  393. package/src/domains/context/working-set/recall.ts +82 -56
  394. package/src/domains/dispatch/active-route-planner.ts +6 -3
  395. package/src/domains/dispatch/admission-queue.ts +19 -7
  396. package/src/domains/dispatch/admission.ts +3 -3
  397. package/src/domains/dispatch/budget-envelope.ts +47 -82
  398. package/src/domains/dispatch/capacity-lease.ts +57 -19
  399. package/src/domains/dispatch/contract.ts +10 -2
  400. package/src/domains/dispatch/event-pump.ts +28 -7
  401. package/src/domains/dispatch/execution-role.ts +49 -2
  402. package/src/domains/dispatch/execution-scheduler.ts +2 -0
  403. package/src/domains/dispatch/extension.ts +190 -105
  404. package/src/domains/dispatch/fleet-run.ts +20 -0
  405. package/src/domains/dispatch/gate-role-prompts.ts +4 -2
  406. package/src/domains/dispatch/parallel-writers.ts +34 -0
  407. package/src/domains/dispatch/reservation-store.ts +8 -34
  408. package/src/domains/dispatch/route-approval.ts +3 -3
  409. package/src/domains/dispatch/route-observer.ts +4 -2
  410. package/src/domains/dispatch/route-quality.ts +6 -1
  411. package/src/domains/dispatch/types.ts +4 -3
  412. package/src/domains/dispatch/worker-spawn.ts +58 -21
  413. package/src/domains/dispatch/workspace-checkpoint.ts +57 -0
  414. package/src/domains/eval/compare/behavioral.ts +81 -14
  415. package/src/domains/eval/compare/compare.ts +15 -5
  416. package/src/domains/eval/compare/envelope.ts +12 -5
  417. package/src/domains/eval/metrics/context.ts +24 -1
  418. package/src/domains/eval/metrics/tracked.ts +4 -28
  419. package/src/domains/eval/reports/comparison.ts +9 -9
  420. package/src/domains/eval/runners/clio-run.ts +5 -1
  421. package/src/domains/eval/schema/suite.ts +2 -0
  422. package/src/domains/eval/schema/validate.ts +1 -0
  423. package/src/domains/eval/suites/run.ts +189 -13
  424. package/src/domains/eval/verifiers/integrity.ts +39 -0
  425. package/src/domains/eval/verifiers/patch.ts +58 -2
  426. package/src/domains/eval/workspaces/temp-copy.ts +3 -0
  427. package/src/domains/evidence/build.ts +4 -2
  428. package/src/domains/interop/registry.ts +2 -2
  429. package/src/domains/middleware/hooks-io.ts +45 -26
  430. package/src/domains/middleware/hooks.ts +6 -0
  431. package/src/domains/middleware/injection-screen.ts +23 -0
  432. package/src/domains/middleware/rules.ts +5 -1
  433. package/src/domains/middleware/stalled-turn.ts +18 -3
  434. package/src/domains/middleware/task-board-reminder.ts +4 -2
  435. package/src/domains/middleware/task-nudge.ts +4 -1
  436. package/src/domains/mux/contract.ts +34 -1
  437. package/src/domains/mux/dock-controller.ts +8 -1
  438. package/src/domains/mux/index.ts +1 -0
  439. package/src/domains/mux/socket-client.ts +13 -3
  440. package/src/domains/observability/contract.ts +2 -2
  441. package/src/domains/observability/projection.ts +30 -9
  442. package/src/domains/prompts/compiler.ts +10 -2
  443. package/src/domains/prompts/contract.ts +7 -4
  444. package/src/domains/prompts/extension.ts +28 -64
  445. package/src/domains/prompts/fragments/identity/clio.md +23 -0
  446. package/src/domains/prompts/fragments/operating/contract.md +10 -0
  447. package/src/domains/prompts/fragments/operating/delegation.md +5 -0
  448. package/src/domains/prompts/fragments/wiki/page.md +28 -15
  449. package/src/domains/prompts/fragments/wiki/plan.md +4 -4
  450. package/src/domains/prompts/preload-prefix.ts +31 -0
  451. package/src/domains/prompts/preload.ts +135 -61
  452. package/src/domains/providers/auth/backend-file.ts +15 -11
  453. package/src/domains/providers/auth/storage.ts +3 -5
  454. package/src/domains/providers/catalog.ts +18 -3
  455. package/src/domains/providers/probe/fingerprint.ts +13 -6
  456. package/src/domains/providers/probe/reasoning.ts +2 -0
  457. package/src/domains/providers/runtime-resolution.ts +11 -9
  458. package/src/domains/providers/runtimes/cloud/openrouter.ts +2 -0
  459. package/src/domains/providers/runtimes/common/probe-helpers.ts +23 -7
  460. package/src/domains/providers/runtimes/protocol/anthropic-compat.ts +7 -2
  461. package/src/domains/providers/runtimes/protocol/openai-compat.ts +10 -4
  462. package/src/domains/resources/skills/promotion.ts +8 -1
  463. package/src/domains/safety/action-classifier.ts +9 -0
  464. package/src/domains/safety/autonomy.ts +10 -1
  465. package/src/domains/safety/contract.ts +5 -1
  466. package/src/domains/safety/default-path-policy.ts +11 -0
  467. package/src/domains/safety/extension.ts +11 -2
  468. package/src/domains/safety/policy-engine.ts +189 -32
  469. package/src/domains/safety/project-policy.ts +7 -2
  470. package/src/domains/safety/workspace-trust.ts +43 -0
  471. package/src/domains/session/compaction/compact.ts +384 -21
  472. package/src/domains/session/compaction/cut-point.ts +42 -5
  473. package/src/domains/session/compaction/tokens.ts +9 -1
  474. package/src/domains/session/decision-board.ts +43 -33
  475. package/src/domains/session/entries.ts +169 -4
  476. package/src/domains/session/prompt-manifest.ts +47 -8
  477. package/src/domains/session/task-board.ts +21 -3
  478. package/src/domains/user-tasks/handoff.ts +16 -0
  479. package/src/engine/acp/adapter.ts +44 -12
  480. package/src/engine/acp/server.ts +1 -0
  481. package/src/engine/acp/transport.ts +2 -1
  482. package/src/engine/acp/types.ts +6 -1
  483. package/src/engine/antigravity/subprocess-runtime.ts +20 -4
  484. package/src/engine/api-registry.ts +19 -2
  485. package/src/engine/apis/openai-completions.ts +13 -6
  486. package/src/engine/apis/output-budget.ts +26 -10
  487. package/src/engine/claude/sdk-runtime.ts +4 -3
  488. package/src/engine/env-api-keys.ts +2 -1
  489. package/src/engine/external-subprocess.ts +14 -3
  490. package/src/engine/loop-guard.ts +19 -2
  491. package/src/engine/provider-diagnostics.ts +129 -0
  492. package/src/engine/provider-payload.ts +3 -1
  493. package/src/engine/worker-runtime.ts +13 -2
  494. package/src/engine/worker-tools.ts +5 -1
  495. package/src/entry/extension-reload.ts +1 -0
  496. package/src/entry/orchestrator.ts +53 -15
  497. package/src/interactive/application-controller.ts +1 -31
  498. package/src/interactive/chat-loop-messages.ts +12 -4
  499. package/src/interactive/chat-loop.ts +115 -45
  500. package/src/interactive/chat-panel.ts +163 -637
  501. package/src/interactive/chat-renderer.ts +73 -30
  502. package/src/interactive/context-recall-command.ts +2 -1
  503. package/src/interactive/dispatch-board.ts +18 -5
  504. package/src/interactive/editor-submit.ts +21 -31
  505. package/src/interactive/footer/dashboard.ts +8 -3
  506. package/src/interactive/footer/widgets.ts +50 -91
  507. package/src/interactive/interactive-application.ts +24 -44
  508. package/src/interactive/interactive-event-projection.ts +9 -45
  509. package/src/interactive/interactive-input-runtime.ts +3 -28
  510. package/src/interactive/interactive-presentation.ts +45 -16
  511. package/src/interactive/interactive-slash-runtime.ts +5 -40
  512. package/src/interactive/layout.ts +31 -5
  513. package/src/interactive/model-session-replay.ts +2 -2
  514. package/src/interactive/overlay-frame.ts +1 -0
  515. package/src/interactive/overlay-general-openers.ts +5 -1
  516. package/src/interactive/overlay-lifecycle.ts +1 -0
  517. package/src/interactive/overlay-session-lifecycle.ts +7 -1
  518. package/src/interactive/overlays/ask-user.ts +1 -0
  519. package/src/interactive/overlays/message-picker.ts +1 -1
  520. package/src/interactive/overlays/settings.ts +9 -8
  521. package/src/interactive/renderers/preview.ts +16 -0
  522. package/src/interactive/renderers/tool-execution.ts +84 -161
  523. package/src/interactive/renderers/worker-entry.ts +74 -43
  524. package/src/interactive/slash-autocomplete.ts +1 -6
  525. package/src/interactive/slash-commands.ts +16 -46
  526. package/src/interactive/status/controller.ts +0 -5
  527. package/src/interactive/status/state-machine.ts +44 -26
  528. package/src/interactive/status/types.ts +3 -0
  529. package/src/interactive/status/verbs.ts +13 -12
  530. package/src/interactive/transcript-detail.ts +50 -112
  531. package/src/interactive/turn-context.ts +221 -53
  532. package/src/interactive/turn-middleware.ts +3 -1
  533. package/src/interactive/turn-persistence.ts +3 -0
  534. package/src/interactive/turn-runtime.ts +11 -2
  535. package/src/interactive/turn-state.ts +10 -9
  536. package/src/interactive/view/artifacts.ts +4 -0
  537. package/src/interactive/view/view-overlay.ts +44 -34
  538. package/src/interactive/watch-pane.ts +18 -4
  539. package/src/interactive/worker-stream.ts +7 -7
  540. package/src/tools/agent-tools.ts +6 -3
  541. package/src/tools/bash.ts +1 -1
  542. package/src/tools/builtin-tool-catalog.ts +9 -2
  543. package/src/tools/codewiki/code-nav.ts +4 -10
  544. package/src/tools/compete-judge-task.ts +71 -0
  545. package/src/tools/compete-worktrees.ts +34 -0
  546. package/src/tools/context/index.ts +32 -7
  547. package/src/tools/context/surface.ts +15 -4
  548. package/src/tools/decide.ts +1 -1
  549. package/src/tools/dispatch-admission.ts +12 -1
  550. package/src/tools/dispatch-arguments.ts +38 -1
  551. package/src/tools/dispatch-plan.ts +7 -7
  552. package/src/tools/dispatch-runner.ts +48 -32
  553. package/src/tools/dispatch-schema.ts +30 -23
  554. package/src/tools/dispatch-scout-admission.ts +10 -44
  555. package/src/tools/dispatch-scout.ts +2 -3
  556. package/src/tools/find.ts +13 -4
  557. package/src/tools/grep.ts +13 -1
  558. package/src/tools/ls.ts +7 -1
  559. package/src/tools/monitor.ts +26 -11
  560. package/src/tools/network-policy.ts +11 -24
  561. package/src/tools/observation.ts +39 -2
  562. package/src/tools/presentation.ts +1 -1
  563. package/src/tools/read.ts +112 -15
  564. package/src/tools/registry.ts +55 -18
  565. package/src/tools/result-shaping.ts +110 -2
  566. package/src/tools/tasks.ts +33 -7
  567. package/src/tools/verify/frontend.ts +67 -30
  568. package/src/tools/verify/numeric.ts +10 -5
  569. package/src/tools/web-fetch-network.ts +179 -0
  570. package/src/tools/web-fetch-surface.ts +2 -1
  571. package/src/tools/web-fetch.ts +15 -13
  572. package/src/tools/worker-evidence.ts +27 -0
  573. package/src/worker/spec-contract.ts +12 -8
  574. package/dist/builtins-WGALA46I.js +0 -22
  575. package/dist/chunk-2WZ546HR.js +0 -792
  576. package/dist/chunk-5PSMVOLM.js +0 -56
  577. package/dist/chunk-EL24TAU4.js +0 -1560
  578. package/dist/chunk-IZXGRF7P.js +0 -4048
  579. package/dist/chunk-JVCV3ICN.js +0 -47
  580. package/dist/chunk-MNJGS2IN.js +0 -33
  581. package/dist/chunk-O5CVSAG5.js +0 -122
  582. package/dist/chunk-ODGTEFFI.js +0 -50
  583. package/dist/chunk-OQE5J4C6.js +0 -73
  584. package/dist/chunk-UUVG37B4.js +0 -244
  585. package/dist/chunk-V6HJFQZE.js +0 -228
  586. package/dist/clio-QLICPCF5.js +0 -25
  587. package/dist/configure-VEPX4NMX.js +0 -55
  588. package/dist/context-clear-S4ZJCQUX.js +0 -182
  589. package/dist/detail-A7JAVSIG.js +0 -98
  590. package/dist/evidence-4F5USFKH.js +0 -208
  591. package/dist/fleet-view-MN2VG4MR.js +0 -101
  592. package/dist/inventory-C26CFDRR.js +0 -101
  593. package/dist/preload-P6DGH2PZ.js +0 -13
  594. package/dist/slash-commands-ZXPJD64J.js +0 -92
  595. package/dist/tasks-IPAGMEIX.js +0 -36
  596. package/dist/tools-EFFEAIDP.js +0 -28
  597. package/dist/verify-FWYGPKMR.js +0 -29
  598. package/dist/wiki-generate-743CIGJW.js +0 -476
@@ -1,12 +1,15 @@
1
1
  import { existsSync } from "node:fs";
2
- import { join } from "node:path";
2
+ import { join, relative } from "node:path";
3
3
  import { performance } from "node:perf_hooks";
4
4
  import { type LoadResult, loadDomains } from "../core/domain-loader.js";
5
+ import { asDirectoryPathBoundary } from "../core/path-boundary.js";
6
+ import { runWithBudget, writeShutdownNotice } from "../core/termination.js";
5
7
  import { ToolNames } from "../core/tool-names.js";
6
8
  import { AgentsDomainModule } from "../domains/agents/index.js";
7
9
  import type { ConfigContract } from "../domains/config/contract.js";
8
10
  import { ConfigDomainModule } from "../domains/config/index.js";
9
11
  import { ContextDomainModule } from "../domains/context/runtime.js";
12
+ import { inspectWikiPageEvidence } from "../domains/context/wiki/evidence.js";
10
13
  import type { WikiGenerate, WikiGenerateInput } from "../domains/context/wiki/generate.js";
11
14
  import type { WikiPlan, WikiPlanPage } from "../domains/context/wiki/plan.js";
12
15
  import {
@@ -18,6 +21,7 @@ import {
18
21
  import { buildWikiPagePrompt, buildWikiPlanPrompt } from "../domains/context/wiki/prompts.js";
19
22
  import type { DispatchContract } from "../domains/dispatch/contract.js";
20
23
  import { DispatchDomainModule } from "../domains/dispatch/index.js";
24
+ import { declaredScopeIntent } from "../domains/dispatch/intent.js";
21
25
  import type { RunReceipt } from "../domains/dispatch/types.js";
22
26
  import type { JobSpec, JobThinkingLevel } from "../domains/dispatch/validation.js";
23
27
  import { MiddlewareDomainModule } from "../domains/middleware/index.js";
@@ -28,7 +32,6 @@ import { ResourcesDomainModule } from "../domains/resources/index.js";
28
32
  import { SafetyDomainModule } from "../domains/safety/index.js";
29
33
  import { SchedulingDomainModule } from "../domains/scheduling/index.js";
30
34
  import { SessionDomainModule } from "../domains/session/index.js";
31
- import { armInternalDispatchDeadline } from "./internal-dispatch.js";
32
35
 
33
36
  /**
34
37
  * Model id recorded on wiki metadata when the documenter target cannot be
@@ -41,25 +44,10 @@ const UNRESOLVED_DOCUMENTER_MODEL = "unresolved-documenter-target";
41
44
  /** The agent recipe that plans and writes pages. */
42
45
  const WIKI_AGENT_ID = "wiki-writer";
43
46
 
44
- /**
45
- * Wall-clock ceiling for one page dispatch, clamped against the configured
46
- * internal-dispatch guardrail. A page is a small job: read a handful of named
47
- * sources and write one file. Bounding it here is what keeps one degenerate
48
- * page from consuming the time every other page needed, and losing it costs
49
- * exactly that page because the plan records it as still owed.
50
- */
51
- const PAGE_DEADLINE_MS = 6 * 60 * 1000;
52
-
53
- /** Wall-clock ceiling for the single planning dispatch. */
54
- const PLAN_DEADLINE_MS = 8 * 60 * 1000;
55
-
56
- /**
57
- * Wall-clock budget for a whole generation, checked between page dispatches and
58
- * never during one. Exceeding it ends the run cleanly with every finished page
59
- * promoted and the rest recorded as owed, so a repository too large for one
60
- * sitting is finished by the next run instead of failing forever.
61
- */
62
- const RUN_BUDGET_MS = 60 * 60 * 1000;
47
+ /** Planning estimates inform progress, never admission or execution limits. */
48
+ const PAGE_ESTIMATE_MS = 6 * 60 * 1000;
49
+ const PLAN_ESTIMATE_MS = 8 * 60 * 1000;
50
+ const RUN_ESTIMATE_MS = 60 * 60 * 1000;
63
51
 
64
52
  export interface WikiModelRoute {
65
53
  target?: string;
@@ -70,8 +58,10 @@ export interface WikiModelRoute {
70
58
  export interface ModelWikiGenerateOptions {
71
59
  dispatch?: DispatchContract;
72
60
  route?: WikiModelRoute;
73
- /** Overrides the whole-run wall-clock budget. Tests use it to force an early stop. */
61
+ /** Explicit whole-run duration; omission leaves ordinary estimates advisory. */
74
62
  runBudgetMs?: number;
63
+ /** Explicit absolute deadline, shared unchanged by planning and every page. */
64
+ deadlineAt?: number;
75
65
  }
76
66
 
77
67
  function isRecord(value: unknown): value is Record<string, unknown> {
@@ -122,13 +112,7 @@ interface DispatchSummary {
122
112
  mix: string;
123
113
  }
124
114
 
125
- /**
126
- * Longest an in-flight phase may go without saying anything. The planner is
127
- * allowed eight minutes and a page six, and the operator who reported this saw
128
- * two lines in five minutes, concluded the command had deadlocked, and killed
129
- * it. Narrating every tool call would scroll the terminal for nothing, so the
130
- * heartbeat is throttled to this and carries only elapsed time and tool count.
131
- */
115
+ /** Throttle activity summaries so long-running healthy work remains visible. */
132
116
  const HEARTBEAT_MS = 30_000;
133
117
 
134
118
  /**
@@ -180,9 +164,30 @@ function summaryDetail(summary: DispatchSummary, startedAtClock: number): string
180
164
  );
181
165
  }
182
166
 
183
- interface WikiDispatchOutcome {
184
- ok: boolean;
185
- detail: string;
167
+ type WikiDispatchOutcome =
168
+ | { ok: false; phase: "admission"; detail: string }
169
+ | { ok: boolean; phase: "writer"; detail: string; runId: string };
170
+
171
+ interface WikiDeadline {
172
+ at: number;
173
+ remainingMs(): number;
174
+ }
175
+
176
+ function explicitWikiDeadline(options: ModelWikiGenerateOptions): WikiDeadline | undefined {
177
+ if (options.runBudgetMs !== undefined && (!Number.isFinite(options.runBudgetMs) || options.runBudgetMs < 0))
178
+ throw new Error("wiki runBudgetMs must be a finite non-negative duration");
179
+ if (options.deadlineAt !== undefined && !Number.isFinite(options.deadlineAt))
180
+ throw new Error("wiki deadlineAt must be a finite timestamp");
181
+ if (options.deadlineAt === undefined && options.runBudgetMs === undefined) return undefined;
182
+ const wallNow = Date.now();
183
+ const at = Math.min(
184
+ options.deadlineAt ?? Number.POSITIVE_INFINITY,
185
+ wallNow + (options.runBudgetMs ?? Number.POSITIVE_INFINITY),
186
+ );
187
+ if (!Number.isFinite(new Date(at).getTime())) throw new Error("wiki deadline exceeds the supported timestamp range");
188
+ const clockNow = performance.now();
189
+ // Keep the admission timestamp fixed while elapsed enforcement is monotonic.
190
+ return { at, remainingMs: () => at - wallNow - (performance.now() - clockNow) };
186
191
  }
187
192
 
188
193
  /**
@@ -195,22 +200,33 @@ async function runWikiDispatch(input: {
195
200
  cwd: string;
196
201
  outputDir: string;
197
202
  task: string;
203
+ /** Caller-owned page path, relative to cwd; the planner remains unbound. */
204
+ artifactPath?: string;
198
205
  route: WikiModelRoute;
199
- deadlineMs: number;
200
- label: string;
206
+ deadline: WikiDeadline | undefined;
201
207
  /** Liveness signal while the dispatch runs, already throttled by the caller. */
202
208
  onHeartbeat?: (info: { elapsedMs: number; tools: number }) => void;
203
209
  }): Promise<WikiDispatchOutcome> {
204
- // `startedAt` is a wall anchor because the admission deadline below is one
205
- // too; every elapsed figure spans the monotonic twin instead.
206
- const startedAt = Date.now();
207
210
  const startedAtClock = performance.now();
208
211
  let handle: Awaited<ReturnType<DispatchContract["dispatch"]>>;
209
212
  try {
213
+ if (input.deadline && input.deadline.remainingMs() <= 0)
214
+ throw new Error("explicit wiki deadline reached before admission");
215
+ const stagingRoot = relative(input.cwd, input.outputDir);
216
+ if (!stagingRoot) throw new Error("wiki staging directory must be below the repository root");
217
+ // The repository is readable; only this staging tree is writable. Declare
218
+ // those paths directly so absolute filenames in prompt prose cannot become
219
+ // legacy scope tokens (including a sentence-ending period).
220
+ const scope = declaredScopeIntent({ readRoots: ["."], writeRoots: [asDirectoryPathBoundary(stagingRoot)] });
221
+ if (!scope.ok) throw new Error(`${scope.reason}: ${scope.message}`);
210
222
  handle = await input.dispatch.dispatch({
223
+ intent: scope.intent,
211
224
  agentId: WIKI_AGENT_ID,
212
225
  executionRole: "builder",
213
226
  task: input.task,
227
+ ...(input.artifactPath !== undefined
228
+ ? { resultContractOverride: { kind: "artifact-report" as const, path: input.artifactPath } }
229
+ : {}),
214
230
  cwd: input.cwd,
215
231
  requestOrigin: "internal",
216
232
  noSkills: true,
@@ -222,21 +238,29 @@ async function runWikiDispatch(input: {
222
238
  denyTools: [ToolNames.Git],
223
239
  // Containment: the worker safety seam blocks any write-class tool call
224
240
  // whose target escapes the staging dir.
225
- writeRoots: [input.outputDir],
226
- // Admission patience must match execution patience. Without this the
227
- // queue applies its 60s default while `deadlineMs` below allows six
228
- // minutes to run, so a page waiting behind two in-flight writers was
229
- // dropped before it ever started. Observed live: a 33-page plan lost
230
- // `core.md` to `dispatch: admission timed_out` at 10/33 while every
231
- // page ahead of it was taking 110 to 125 seconds. A page the caller is
232
- // willing to wait six minutes for is a page it should be willing to
233
- // queue for six minutes.
234
- assignmentDeadlineAt: startedAt + input.deadlineMs,
241
+ writeRoots: [asDirectoryPathBoundary(input.outputDir)],
242
+ // Only an explicit caller deadline constrains admission; recipe estimates
243
+ // must not become assignment deadlines or restart for each page.
244
+ ...(input.deadline ? { assignmentDeadlineAt: input.deadline.at } : {}),
235
245
  });
236
246
  } catch (err) {
237
- return { ok: false, detail: err instanceof Error ? err.message : String(err) };
247
+ return { ok: false, phase: "admission", detail: err instanceof Error ? err.message : String(err) };
238
248
  }
239
- const deadline = armInternalDispatchDeadline(input.dispatch, handle.runId, input.label, input.deadlineMs);
249
+ let timedOut = false;
250
+ let timer: ReturnType<typeof setTimeout> | undefined;
251
+ const armDeadline = (): void => {
252
+ if (!input.deadline) return;
253
+ const remaining = input.deadline.remainingMs();
254
+ if (remaining <= 0) {
255
+ timedOut = true;
256
+ input.dispatch.abort(handle.runId, { cause: "timeout", detail: "explicit wiki deadline reached" });
257
+ return;
258
+ }
259
+ // Long explicit deadlines must not overflow Node's timer range into 1ms.
260
+ timer = setTimeout(armDeadline, Math.min(remaining, 2_147_483_647));
261
+ timer.unref();
262
+ };
263
+ armDeadline();
240
264
  let lastHeartbeatAt = startedAtClock;
241
265
  try {
242
266
  const summary = await drainDispatchEvents(handle.events, (tools) => {
@@ -246,25 +270,42 @@ async function runWikiDispatch(input: {
246
270
  input.onHeartbeat({ elapsedMs: Math.round(nowMs - startedAtClock), tools });
247
271
  });
248
272
  const receipt = await handle.finalPromise;
249
- if (deadline.timedOut()) return { ok: false, detail: `timed out; ${summaryDetail(summary, startedAtClock)}` };
273
+ if (timedOut)
274
+ return {
275
+ ok: false,
276
+ phase: "writer",
277
+ runId: handle.runId,
278
+ detail: `timed out; ${summaryDetail(summary, startedAtClock)}`,
279
+ };
250
280
  if (receipt.exitCode !== 0) {
251
281
  input.dispatch.abort(handle.runId);
252
- return { ok: false, detail: `${receiptFailure(receipt)}; ${summaryDetail(summary, startedAtClock)}` };
282
+ return {
283
+ ok: false,
284
+ phase: "writer",
285
+ runId: handle.runId,
286
+ detail: `${receiptFailure(receipt)}; ${summaryDetail(summary, startedAtClock)}`,
287
+ };
253
288
  }
254
- return { ok: true, detail: summaryDetail(summary, startedAtClock) };
289
+ return { ok: true, phase: "writer", runId: handle.runId, detail: summaryDetail(summary, startedAtClock) };
255
290
  } catch (err) {
256
- if (!deadline.timedOut()) input.dispatch.abort(handle.runId);
291
+ if (!timedOut) input.dispatch.abort(handle.runId);
257
292
  await handle.finalPromise.catch(() => undefined);
258
- const reason = deadline.timedOut() ? "timed out" : err instanceof Error ? err.message : String(err);
259
- return { ok: false, detail: `${reason}; ${formatElapsed(performance.now() - startedAtClock)}` };
293
+ const reason = timedOut ? "timed out" : err instanceof Error ? err.message : String(err);
294
+ return {
295
+ ok: false,
296
+ phase: "writer",
297
+ runId: handle.runId,
298
+ detail: `${reason}; ${formatElapsed(performance.now() - startedAtClock)}`,
299
+ };
260
300
  } finally {
261
- deadline.clear();
301
+ clearTimeout(timer);
262
302
  }
263
303
  }
264
304
 
265
305
  function receiptFailure(receipt: RunReceipt): string {
266
306
  const code = receipt.outcomeCode ? ` (${receipt.outcomeCode})` : "";
267
- return `exit ${receipt.exitCode}${code}`;
307
+ const detail = receipt.outcomeDetail?.replace(/\s+/gu, " ").slice(0, 350);
308
+ return `exit ${receipt.exitCode}${code}${detail ? `: ${detail}` : ""}`;
268
309
  }
269
310
 
270
311
  /**
@@ -276,6 +317,7 @@ async function runPlanPhase(
276
317
  dispatch: DispatchContract,
277
318
  input: WikiGenerateInput,
278
319
  route: WikiModelRoute,
320
+ deadline: WikiDeadline | undefined,
279
321
  ): Promise<WikiPlan> {
280
322
  input.progress?.({ phase: "generate", status: "running", message: "planning wiki pages" });
281
323
  const outcome = await runWikiDispatch({
@@ -293,14 +335,13 @@ async function runPlanPhase(
293
335
  gitHead: input.gitHead ?? null,
294
336
  }),
295
337
  route,
296
- deadlineMs: PLAN_DEADLINE_MS,
297
- label: "wiki planner",
338
+ deadline,
298
339
  onHeartbeat: ({ elapsedMs, tools }) =>
299
340
  input.progress?.({
300
341
  phase: "generate",
301
342
  status: "running",
302
343
  message: `still planning (${formatElapsed(elapsedMs)}, ${tools} tool calls)`,
303
- detail: `planner deadline ${Math.round(PLAN_DEADLINE_MS / 60000)}m`,
344
+ detail: `planner estimate ${Math.round(PLAN_ESTIMATE_MS / 60000)}m; healthy work may continue longer`,
304
345
  }),
305
346
  });
306
347
  const revised = readAuthoredWikiPlan(input.outputDir, input.plan);
@@ -324,13 +365,16 @@ async function runPagePhase(
324
365
  page: WikiPlanPage,
325
366
  route: WikiModelRoute,
326
367
  position: { index: number; total: number },
368
+ deadline: WikiDeadline | undefined,
327
369
  ): Promise<WikiPlan> {
328
370
  const seeded = existsSync(join(input.outputDir, page.path));
329
371
  const outcome = await runWikiDispatch({
330
372
  dispatch,
331
373
  cwd: input.cwd,
332
374
  outputDir: input.outputDir,
375
+ artifactPath: relative(input.cwd, join(input.outputDir, page.path)),
333
376
  task: buildWikiPagePrompt({
377
+ depth: input.generation.depth,
334
378
  cwd: input.cwd,
335
379
  mode: input.mode,
336
380
  codewiki: input.codewiki,
@@ -341,33 +385,52 @@ async function runPagePhase(
341
385
  seeded,
342
386
  }),
343
387
  route,
344
- deadlineMs: PAGE_DEADLINE_MS,
345
- label: `wiki page ${page.path}`,
388
+ deadline,
346
389
  onHeartbeat: ({ elapsedMs, tools }) =>
347
390
  input.progress?.({
348
391
  phase: "generate",
349
392
  status: "running",
350
393
  message: `still writing ${page.path} (${position.index}/${position.total}, ${formatElapsed(elapsedMs)}, ${tools} tool calls)`,
351
- detail: `page deadline ${Math.round(PAGE_DEADLINE_MS / 60000)}m`,
394
+ detail: `page estimate ${Math.round(PAGE_ESTIMATE_MS / 60000)}m; healthy work may continue longer`,
352
395
  }),
353
396
  });
354
- // The file on disk is the postcondition, not what the writer reported. A run
355
- // that ended on its budget after writing the page still wrote the page.
356
- const written = existsSync(join(input.outputDir, page.path));
397
+ // Keep failed refresh prose available, but require both a successful writer
398
+ // and mechanically valid evidence before crediting a page as completed.
399
+ const evidence = outcome.ok
400
+ ? inspectWikiPageEvidence({
401
+ pagePath: page.path,
402
+ outputDir: input.outputDir,
403
+ sourceRoot: input.cwd,
404
+ })
405
+ : undefined;
406
+ const written = outcome.ok && evidence?.ok === true;
407
+ const detail = evidence && !evidence.ok ? `evidence check failed: ${evidence.reasons.join("; ")}` : outcome.detail;
357
408
  const next: WikiPlan = {
358
409
  ...plan,
359
- pages: plan.pages.map((entry) =>
360
- entry.path === page.path
361
- ? { ...entry, status: written ? ("written" as const) : ("pending" as const), attempts: entry.attempts + 1 }
362
- : entry,
363
- ),
410
+ pages: plan.pages.map((entry) => {
411
+ if (entry.path !== page.path) return entry;
412
+ const nextPage: WikiPlanPage = {
413
+ ...entry,
414
+ status: written ? "written" : "pending",
415
+ ...(written ? { dependencies: evidence?.dependencies ?? [] } : {}),
416
+ attempts: entry.attempts + (outcome.phase === "writer" ? 1 : 0),
417
+ };
418
+ if (written) delete nextPage.lastFailure;
419
+ else
420
+ nextPage.lastFailure = {
421
+ phase: outcome.ok ? "validation" : outcome.phase,
422
+ detail: detail.replace(/\s+/gu, " ").slice(0, 500),
423
+ ...(outcome.phase === "writer" ? { runId: outcome.runId } : {}),
424
+ };
425
+ return nextPage;
426
+ }),
364
427
  };
365
428
  writeWikiPlanFile(input.outputDir, next);
366
429
  input.progress?.({
367
430
  phase: "generate",
368
431
  status: "running",
369
432
  message: `${written ? "wrote" : "could not write"} ${page.path} (${position.index}/${position.total})`,
370
- detail: outcome.detail,
433
+ detail,
371
434
  });
372
435
  return next;
373
436
  }
@@ -376,8 +439,10 @@ async function generateWikiWithDocumenter(
376
439
  dispatch: DispatchContract,
377
440
  input: WikiGenerateInput,
378
441
  route: WikiModelRoute = {},
379
- runBudgetMs: number = RUN_BUDGET_MS,
442
+ deadline?: WikiDeadline,
443
+ signal?: AbortSignal,
380
444
  ): Promise<void> {
445
+ signal?.throwIfAborted();
381
446
  const startedAtClock = performance.now();
382
447
  const routeDetail = [route.target, route.model, route.thinkingLevel ? `thinking=${route.thinkingLevel}` : undefined]
383
448
  .filter((value): value is string => value !== undefined)
@@ -393,43 +458,61 @@ async function generateWikiWithDocumenter(
393
458
  // re-planning would churn the paths those pages already link to. Every other
394
459
  // run plans, including an update, which is the only thing allowed to change
395
460
  // a wiki's shape as the repository grows.
396
- let plan = input.resumed ? input.plan : await runPlanPhase(dispatch, input, route);
461
+ let plan = input.resumed ? input.plan : await runPlanPhase(dispatch, input, route, deadline);
462
+ signal?.throwIfAborted();
397
463
  if (!input.resumed) writeWikiPlanFile(input.outputDir, plan);
398
464
 
399
- const queue = pendingPages(plan);
465
+ const queue = pendingPages(plan, input.retryPending);
400
466
  if (queue.length === 0) {
401
- input.progress?.({ phase: "generate", status: "running", message: "every planned page is already current" });
467
+ const pending = plan.pages.filter((page) => page.status !== "written").length;
468
+ input.progress?.({
469
+ phase: "generate",
470
+ status: "running",
471
+ message:
472
+ pending > 0
473
+ ? `${pending} pending page${pending === 1 ? " has" : "s have"} exhausted writer attempts`
474
+ : "every planned page is already current",
475
+ });
402
476
  return;
403
477
  }
404
478
  // Say the shape of the wait before starting it. A 20-page wiki is 20 model
405
479
  // runs and can legitimately take most of an hour, which is longer than any
406
480
  // default command timeout an operator is likely to have wrapped around it.
407
481
  {
408
- const worstCaseMs = Math.min(runBudgetMs, queue.length * PAGE_DEADLINE_MS);
482
+ const estimateMs = Math.min(RUN_ESTIMATE_MS, queue.length * PAGE_ESTIMATE_MS);
409
483
  input.progress?.({
410
484
  phase: "generate",
411
485
  status: "running",
412
486
  message: `${queue.length} page${queue.length === 1 ? "" : "s"} to write, one model run each`,
413
- detail: `up to ${Math.round(worstCaseMs / 60000)}m; progress is reported at least every ${Math.round(HEARTBEAT_MS / 1000)}s and finished pages are kept if the run stops early`,
487
+ detail: `estimate ${Math.round(estimateMs / 60000)}m; activity summaries every ${Math.round(HEARTBEAT_MS / 1000)}s; finished pages are kept if the run stops early${deadline ? `; explicit deadline ${new Date(deadline.at).toISOString()}` : "; healthy work may continue beyond estimates"}`,
414
488
  });
415
489
  }
416
490
  for (const [index, page] of queue.entries()) {
417
- if (performance.now() - startedAtClock >= runBudgetMs) {
491
+ signal?.throwIfAborted();
492
+ if (deadline && deadline.remainingMs() <= 0) {
418
493
  const left = queue.length - index;
419
494
  input.progress?.({
420
495
  phase: "generate",
421
496
  status: "running",
422
- message: `run budget reached with ${left} page${left === 1 ? "" : "s"} unwritten`,
497
+ message: `explicit deadline reached with ${left} page${left === 1 ? "" : "s"} unwritten`,
423
498
  detail: `${formatElapsed(performance.now() - startedAtClock)}; staged pages are kept and promoted`,
424
499
  });
425
500
  return;
426
501
  }
427
502
  const current = plan.pages.find((entry) => entry.path === page.path) ?? page;
428
- if (current.status === "written" || current.attempts >= MAX_PAGE_ATTEMPTS) continue;
429
- plan = await runPagePhase(dispatch, input, plan, current, route, {
430
- index: index + 1,
431
- total: queue.length,
432
- });
503
+ if (current.status === "written" || (!input.retryPending && current.attempts >= MAX_PAGE_ATTEMPTS)) continue;
504
+ plan = await runPagePhase(
505
+ dispatch,
506
+ input,
507
+ plan,
508
+ current,
509
+ route,
510
+ {
511
+ index: index + 1,
512
+ total: queue.length,
513
+ },
514
+ deadline,
515
+ );
433
516
  }
434
517
  }
435
518
 
@@ -493,19 +576,79 @@ export async function resolveDocumenterModelId(route: WikiModelRoute = {}): Prom
493
576
  }
494
577
  }
495
578
 
579
+ /**
580
+ * A standalone wiki command owns a dispatch runtime outside the main entry
581
+ * orchestrator. Hold its signal ownership until workers settle, including
582
+ * their 500ms forced-kill window, then stop domains before exiting. This is
583
+ * scoped to the runtime we loaded; injected dispatches keep their caller's
584
+ * lifecycle. The signal budget fits inside the enclosing editor shell grace.
585
+ */
586
+ export async function withWikiDispatchLifecycle(
587
+ runtime: { dispatch: Pick<DispatchContract, "drain">; stop(): Promise<void> },
588
+ generate: (signal: AbortSignal) => Promise<void>,
589
+ ): Promise<void> {
590
+ const abort = new AbortController();
591
+ let closing: Promise<void> | null = null;
592
+ let interrupted: Promise<void> | null = null;
593
+ const close = (): Promise<void> => {
594
+ closing ??= (async () => {
595
+ let failure: { error: unknown } | null = null;
596
+ try {
597
+ await runtime.dispatch.drain();
598
+ } catch (error) {
599
+ failure = { error };
600
+ }
601
+ try {
602
+ await runtime.stop();
603
+ } catch (error) {
604
+ if (failure) writeShutdownNotice(`clio-coder context wiki: domain cleanup failed: ${String(error)}`);
605
+ else failure = { error };
606
+ }
607
+ if (failure) throw failure.error;
608
+ })();
609
+ return closing;
610
+ };
611
+ const exitCodes = { SIGINT: 130, SIGTERM: 143, SIGHUP: 129 } as const;
612
+ const onSignal = (signal: keyof typeof exitCodes): void => {
613
+ if (interrupted) return;
614
+ abort.abort(new Error(`wiki generation interrupted by ${signal}`));
615
+ interrupted = (async () => {
616
+ const completed = await runWithBudget(close, 2000, (error) => {
617
+ writeShutdownNotice(`clio-coder context wiki: shutdown failed: ${String(error)}`);
618
+ });
619
+ if (!completed) writeShutdownNotice("clio-coder context wiki: shutdown exceeded 2000ms budget");
620
+ process.exit(exitCodes[signal]);
621
+ })();
622
+ };
623
+ for (const signal of Object.keys(exitCodes) as Array<keyof typeof exitCodes>) process.on(signal, onSignal);
624
+ let failure: { error: unknown } | null = null;
625
+ try {
626
+ await generate(abort.signal);
627
+ } catch (error) {
628
+ failure = { error };
629
+ }
630
+ try {
631
+ if (interrupted) await interrupted;
632
+ else await close();
633
+ } catch (error) {
634
+ if (failure) writeShutdownNotice(`clio-coder context wiki: cleanup failed: ${String(error)}`);
635
+ else failure = { error };
636
+ } finally {
637
+ for (const signal of Object.keys(exitCodes) as Array<keyof typeof exitCodes>) process.off(signal, onSignal);
638
+ }
639
+ if (failure) throw failure.error;
640
+ }
641
+
496
642
  export function modelWikiGenerate(options: ModelWikiGenerateOptions = {}): WikiGenerate {
497
643
  return async (input) => {
498
- let loaded: LoadResult | null = null;
499
- try {
500
- if (options.dispatch) {
501
- await generateWikiWithDocumenter(options.dispatch, input, options.route, options.runBudgetMs);
502
- return;
503
- }
504
- const lazy = await loadWikiDispatch();
505
- loaded = lazy.loaded;
506
- await generateWikiWithDocumenter(lazy.dispatch, input, options.route, options.runBudgetMs);
507
- } finally {
508
- if (loaded) await loaded.stop();
644
+ const deadline = explicitWikiDeadline(options);
645
+ if (options.dispatch) {
646
+ await generateWikiWithDocumenter(options.dispatch, input, options.route, deadline);
647
+ return;
509
648
  }
649
+ const { dispatch, loaded } = await loadWikiDispatch();
650
+ await withWikiDispatchLifecycle({ dispatch, stop: () => loaded.stop() }, (signal) =>
651
+ generateWikiWithDocumenter(dispatch, input, options.route, deadline, signal),
652
+ );
510
653
  };
511
654
  }
@@ -1,5 +1,6 @@
1
1
  import { spawn } from "node:child_process";
2
2
  import { StringDecoder } from "node:string_decoder";
3
+ import { isSecretArgKey } from "../domains/safety/redaction.js";
3
4
  import { AI_AGENT_NAME } from "./agent-environment.js";
4
5
  import {
5
6
  gitCommitAttributionEnabled,
@@ -18,7 +19,7 @@ export { clampTimerDelayMs as clampTimeoutMs } from "./timers.js";
18
19
  // (failing assertion, compiler error, exit summary) must survive.
19
20
  export const BASH_HARD_CAP_BYTES = 16 * 1024 * 1024;
20
21
 
21
- const CLIO_CONTROL_ENV_KEYS = ["CLIO_CODER_INTERACTIVE"] as const;
22
+ const CLIO_CONTROL_ENV_KEYS = ["CLIO_CODER_INTERACTIVE", "BASH_ENV", "ENV"] as const;
22
23
 
23
24
  export interface BashCommandResult {
24
25
  error: NodeJS.ErrnoException | null;
@@ -175,8 +176,10 @@ export function createBashOutputProgressController(
175
176
  };
176
177
  }
177
178
 
178
- function buildToolEnv(): NodeJS.ProcessEnv {
179
- const env = { ...process.env };
179
+ function buildToolEnv(source: NodeJS.ProcessEnv = process.env): NodeJS.ProcessEnv {
180
+ const env = { ...source };
181
+ for (const key of Object.keys(env))
182
+ if (isSecretArgKey(key) || key.startsWith("BASH_FUNC_")) Reflect.deleteProperty(env, key);
180
183
  env.AI_AGENT = AI_AGENT_NAME;
181
184
  for (const key of CLIO_CONTROL_ENV_KEYS) {
182
185
  Reflect.deleteProperty(env, key);
@@ -192,7 +195,7 @@ function buildToolEnv(): NodeJS.ProcessEnv {
192
195
  // call still gets a fresh shell — only the env composition is cached, so
193
196
  // there is no state bleed and cancellation semantics are untouched. When the
194
197
  // capture fails (profile error, timeout, no PATH), every call falls back to
195
- // the historical per-call `-lc`.
198
+ // the filtered non-login environment; failed capture must not source secrets again.
196
199
  const LOGIN_ENV_CAPTURE_TIMEOUT_MS = 10_000;
197
200
 
198
201
  let loginEnvCapture: Promise<NodeJS.ProcessEnv | null> | null = null;
@@ -243,15 +246,11 @@ interface BashSpawnPlan {
243
246
  async function bashSpawnPlan(): Promise<BashSpawnPlan> {
244
247
  loginEnvCapture ??= captureLoginEnv();
245
248
  const captured = await loginEnvCapture;
246
- if (captured === null) return { mode: "-lc", env: buildToolEnv() };
249
+ if (captured === null) return { mode: "-c", env: buildToolEnv() };
247
250
  // Captured (login-transformed) values win; keys added to process.env after
248
251
  // the capture still flow through; the CLIO control keys are re-stripped
249
252
  // last so they never reach the child from either source.
250
- const env: NodeJS.ProcessEnv = { ...process.env, ...captured };
251
- env.AI_AGENT = AI_AGENT_NAME;
252
- for (const key of CLIO_CONTROL_ENV_KEYS) {
253
- Reflect.deleteProperty(env, key);
254
- }
253
+ const env = buildToolEnv({ ...process.env, ...captured });
255
254
  return { mode: "-c", env };
256
255
  }
257
256
 
@@ -275,6 +274,7 @@ export async function runBashCommand(command: string, options: RunBashCommandOpt
275
274
  let timeoutId: ReturnType<typeof setTimeout> | null = null;
276
275
  let killGraceTimer: ReturnType<typeof setTimeout> | null = null;
277
276
  let killSent = false;
277
+ let pendingClose: (() => void) | null = null;
278
278
  const output = createBashOutputProgressController(options.onUpdate);
279
279
 
280
280
  const child = spawn("/bin/bash", [plan.mode, command], {
@@ -305,12 +305,42 @@ export async function runBashCommand(command: string, options: RunBashCommandOpt
305
305
  child.kill(signalName);
306
306
  };
307
307
 
308
+ const hasOwnedProcesses = (): boolean => {
309
+ const pid = child.pid;
310
+ if (pid === undefined) return false;
311
+ if (process.platform !== "win32") {
312
+ try {
313
+ process.kill(-pid, 0);
314
+ return true;
315
+ } catch (error) {
316
+ if ((error as NodeJS.ErrnoException).code === "EPERM") return true;
317
+ }
318
+ }
319
+ return child.exitCode === null && child.signalCode === null;
320
+ };
321
+
322
+ const resolveAfterCancellation = (result: BashCommandResult): void => {
323
+ // A TERM handler can exit while a same-group child ignores TERM and
324
+ // holds no pipes. Keep the original result, but do not let close discard
325
+ // the escalation that still owns that child's cancellation.
326
+ if (killGraceTimer !== null && hasOwnedProcesses()) {
327
+ pendingClose = () => resolve(result);
328
+ return;
329
+ }
330
+ clearKillGraceTimer();
331
+ resolve(result);
332
+ };
333
+
308
334
  const killChild = (): void => {
309
335
  if (killSent) return;
310
336
  killSent = true;
311
337
  sendSignal("SIGTERM");
312
338
  killGraceTimer = setTimeout(() => {
313
- sendSignal("SIGKILL");
339
+ killGraceTimer = null;
340
+ if (hasOwnedProcesses()) sendSignal("SIGKILL");
341
+ const finish = pendingClose;
342
+ pendingClose = null;
343
+ finish?.();
314
344
  }, 5000);
315
345
  };
316
346
 
@@ -342,10 +372,9 @@ export async function runBashCommand(command: string, options: RunBashCommandOpt
342
372
  if (settled) return;
343
373
  settled = true;
344
374
  if (timeoutId) clearTimeout(timeoutId);
345
- clearKillGraceTimer();
346
375
  const finalOutput = output.settle();
347
376
  options.signal?.removeEventListener("abort", onAbort);
348
- resolve({
377
+ resolveAfterCancellation({
349
378
  error: error as NodeJS.ErrnoException,
350
379
  ...finalOutput,
351
380
  exitCode: null,
@@ -358,7 +387,6 @@ export async function runBashCommand(command: string, options: RunBashCommandOpt
358
387
  if (settled) return;
359
388
  settled = true;
360
389
  if (timeoutId) clearTimeout(timeoutId);
361
- clearKillGraceTimer();
362
390
  const finalOutput = output.settle();
363
391
  options.signal?.removeEventListener("abort", onAbort);
364
392
  const error =
@@ -370,7 +398,7 @@ export async function runBashCommand(command: string, options: RunBashCommandOpt
370
398
  code: code ?? undefined,
371
399
  signal: signalName ?? undefined,
372
400
  } as NodeJS.ErrnoException);
373
- resolve({
401
+ resolveAfterCancellation({
374
402
  error,
375
403
  ...finalOutput,
376
404
  exitCode: code,