@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
@@ -21,15 +21,19 @@ import { coordinateCodewikiWrite } from "../codewiki/coordinator.js";
21
21
  import type { Codewiki } from "../codewiki/schema.js";
22
22
  import type { Fingerprint } from "../fingerprint.js";
23
23
  import { readClioState, writeClioState } from "../state.js";
24
- import { assembleWikiTree, normalizeRepoPath, pageSourceIndex } from "./assemble.js";
24
+ import { assembleWikiTree, pageSourceIndex } from "./assemble.js";
25
+ import { inspectWikiPageEvidence } from "./evidence.js";
25
26
  import { isGeneratedWikiFile, listWikiPagesInDir, WIKI_PLAN_FILE, wikiDir, wikiMarkdownFilesInDir } from "./layout.js";
26
27
  import {
27
28
  computeWikiContentHash,
28
29
  computeWikiContentHashOfDir,
29
30
  currentWikiGitHead,
30
31
  readWikiMeta,
32
+ readWikiMetaInDir,
33
+ type WikiMeta,
31
34
  wikiMetaPath,
32
35
  writeWikiMeta,
36
+ writeWikiMetaInDir,
33
37
  } from "./meta.js";
34
38
  import {
35
39
  planWikiGeneration,
@@ -38,8 +42,9 @@ import {
38
42
  type WikiPlan,
39
43
  type WikiPlanPage,
40
44
  } from "./plan.js";
41
- import { readWikiPlanFile, scopePlanForUpdate, unclaimedCandidates, writeWikiPlanFile } from "./plan-store.js";
45
+ import { readWikiPlanFile, unclaimedCandidates, writeWikiPlanFile } from "./plan-store.js";
42
46
  import type { WikiGenerateMode } from "./prompts.js";
47
+ import { captureWikiSourceContent, type WikiSourceContent, wikiSourcesMatch } from "./source-content.js";
43
48
  import { changedPathsSince } from "./staleness.js";
44
49
 
45
50
  export type { WikiDepth, WikiGenerateMode };
@@ -70,6 +75,8 @@ export interface WikiGenerateInput {
70
75
  * paths.
71
76
  */
72
77
  resumed: boolean;
78
+ /** Operator-requested retry of pending work, including exhausted writers, once this run. */
79
+ retryPending?: boolean;
73
80
  /** Indexed areas no existing page covers, offered to a planning pass. */
74
81
  unclaimedAreas: ReadonlyArray<WikiPlanPage>;
75
82
  gitHead?: string | null;
@@ -85,6 +92,8 @@ export interface RunWikiGenerateInput {
85
92
  mode?: WikiGenerateMode;
86
93
  /** Repository-detail policy. Auto scales decomposition from indexed files and lines. */
87
94
  depth?: WikiDepth;
95
+ /** Resume the existing plan, allowing exhausted pending writers one more attempt. */
96
+ retryPending?: boolean;
88
97
  model: string;
89
98
  generate?: WikiGenerate;
90
99
  onProgress?: BootstrapProgressSink;
@@ -299,13 +308,29 @@ function adoptOrCreateStaging(cwd: string): { dir: string; adopted: boolean } {
299
308
 
300
309
  type PromoteResult = { ok: true } | { ok: false; problems: string[] };
301
310
 
302
- /**
303
- * Atomically swap staging into place: move the current wiki aside to
304
- * .clio-coder/wiki-prev, rename staging to .clio-coder/wiki, then write meta.json. On any
305
- * failure after the old wiki is moved aside, restore it; if the restore fails,
306
- * the recovered content is left at wiki-prev and its path is surfaced.
307
- */
308
- function promoteStaging(cwd: string, stagingDir: string, writeMeta: () => void): PromoteResult {
311
+ /** Resolve a previous process crash before reading metadata or cleaning staging. */
312
+ function recoverPublication(cwd: string): void {
313
+ const wiki = wikiDir(cwd);
314
+ const prev = join(clioDir(cwd), WIKI_PREV_DIR);
315
+ if (!existsSync(prev)) return;
316
+ const valid = (dir: string): boolean => {
317
+ const meta = readWikiMetaInDir(dir);
318
+ return meta !== null && meta.contentHash === computeWikiContentHashOfDir(dir);
319
+ };
320
+ if (valid(wiki)) {
321
+ removeDir(prev);
322
+ return;
323
+ }
324
+ if (!valid(prev)) throw new Error(`wiki recovery requires a valid publication; preserved ${wiki} and ${prev}`);
325
+ if (existsSync(wiki)) {
326
+ const interrupted = mkdtempSync(join(clioDir(cwd), "wiki-interrupted-"));
327
+ renameSync(wiki, join(interrupted, "wiki"));
328
+ }
329
+ renameSync(prev, wiki);
330
+ }
331
+
332
+ /** Promote a prepared content/metadata pair; restore the old pair on rename failure. */
333
+ function promoteStaging(cwd: string, stagingDir: string): PromoteResult {
309
334
  const wiki = wikiDir(cwd);
310
335
  const prev = join(clioDir(cwd), WIKI_PREV_DIR);
311
336
  removeDir(prev);
@@ -313,7 +338,6 @@ function promoteStaging(cwd: string, stagingDir: string, writeMeta: () => void):
313
338
  if (hadWiki) renameSync(wiki, prev);
314
339
  try {
315
340
  renameSync(stagingDir, wiki);
316
- writeMeta();
317
341
  } catch (err) {
318
342
  const problems = [`wiki promotion failed: ${err instanceof Error ? err.message : String(err)}`];
319
343
  removeDir(stagingDir);
@@ -337,9 +361,9 @@ function promoteStaging(cwd: string, stagingDir: string, writeMeta: () => void):
337
361
  * interrupted run, then the plan the last promoted wiki recorded, then the
338
362
  * candidate skeleton the index just produced.
339
363
  *
340
- * A resumed plan is used exactly as it was left. It was settled when the wiki
341
- * was planned, and the pages already written link to its paths, so changing it
342
- * mid-flight would strand those links. Areas the index has since found that no
364
+ * A resumed plan retains its structure because finished pages link to its
365
+ * paths. Completed dispatches are reusable only when the checkpoint source
366
+ * content matches; missing or changed evidence requeues the pages. Areas the index has since found that no
343
367
  * page covers are carried separately and offered to a planning pass, which is
344
368
  * the only thing allowed to change a plan's shape.
345
369
  */
@@ -350,24 +374,60 @@ function resolvePlan(input: {
350
374
  mode: WikiGenerateMode;
351
375
  candidate: WikiPlan;
352
376
  previousPlan: WikiPlan | undefined;
377
+ sourceContent: WikiSourceContent;
353
378
  gitHead: string | null;
354
379
  }): { plan: WikiPlan; resumed: boolean; unclaimedAreas: WikiPlanPage[] } {
355
380
  const staged = input.adopted ? readWikiPlanFile(input.stagingDir) : null;
356
- if (staged !== null) return { plan: staged, resumed: true, unclaimedAreas: [] };
357
- if (input.mode === "update" && input.previousPlan !== undefined) {
381
+ const previous = staged ?? (input.mode === "update" ? input.previousPlan : undefined);
382
+ if (previous) {
358
383
  const pageSources = pageSourceIndex(input.stagingDir, input.cwd);
359
- const changed = new Set(
360
- changedPathsSince(input.cwd, input.gitHead).map((path) => normalizeRepoPath(input.cwd, path)),
361
- );
362
- return {
363
- plan: scopePlanForUpdate({
364
- plan: input.previousPlan,
365
- changedPaths: changed,
366
- existingPages: new Set(wikiMarkdownFilesInDir(input.stagingDir)),
367
- pageSources,
384
+ // A partial first publication has no whole-wiki Git certification yet.
385
+ // Its completed pages still have the harness-captured plan baseline.
386
+ const partialHead =
387
+ input.gitHead === null && previous.pages.some((page) => page.status !== "written")
388
+ ? previous.sourceGitHead
389
+ : undefined;
390
+ const gitAvailable = changedPathsSince(input.cwd, staged?.sourceGitHead ?? partialHead ?? input.gitHead) !== null;
391
+ const existing = new Set(wikiMarkdownFilesInDir(input.stagingDir));
392
+ const plan = {
393
+ ...previous,
394
+ pages: previous.pages.map((page) => {
395
+ if (page.status !== "written") return page;
396
+ const evidence = inspectWikiPageEvidence({
397
+ pagePath: page.path,
398
+ outputDir: input.stagingDir,
399
+ sourceRoot: input.cwd,
400
+ });
401
+ const sources = [
402
+ ...page.sources,
403
+ ...(page.dependencies ?? []),
404
+ ...(pageSources.get(page.path) ?? []),
405
+ ...(evidence.dependencies ?? []),
406
+ ];
407
+ return gitAvailable &&
408
+ existing.has(page.path) &&
409
+ evidence.ok &&
410
+ wikiSourcesMatch(previous.sourceContent, input.sourceContent, sources)
411
+ ? { ...page, dependencies: evidence.dependencies ?? [] }
412
+ : {
413
+ ...page,
414
+ status: "pending" as const,
415
+ attempts: 0,
416
+ ...(!evidence.ok
417
+ ? {
418
+ lastFailure: {
419
+ phase: "validation" as const,
420
+ detail: `saved page evidence check failed: ${evidence.reasons.join("; ")}`.slice(0, 500),
421
+ },
422
+ }
423
+ : {}),
424
+ };
368
425
  }),
369
- resumed: false,
370
- unclaimedAreas: unclaimedCandidates(input.previousPlan, input.candidate, pageSources),
426
+ };
427
+ return {
428
+ plan,
429
+ resumed: staged !== null,
430
+ unclaimedAreas: staged ? [] : unclaimedCandidates(previous, input.candidate, pageSources),
371
431
  };
372
432
  }
373
433
  return { plan: input.candidate, resumed: false, unclaimedAreas: [] };
@@ -376,9 +436,9 @@ function resolvePlan(input: {
376
436
  /**
377
437
  * Reconcile the plan against the tree that actually exists. A page whose file
378
438
  * the assembly pass dropped, or that was never written, is owed again; a page
379
- * on disk is recorded as written whatever the writer reported. A page that
380
- * exists without a plan entry is adopted, because a page on disk is a page: the
381
- * alternative is a plan that keeps re-dispatching a subject already covered.
439
+ * on disk retains its recorded dispatch outcome. A page
440
+ * created by a writer without a plan entry remains available and is adopted
441
+ * pending: its own completed dispatch has not yet been recorded.
382
442
  */
383
443
  function reconcilePlan(plan: WikiPlan, stagingDir: string): WikiPlan {
384
444
  const contentFiles = wikiMarkdownFilesInDir(stagingDir).filter((relPath) => !isGeneratedWikiFile(relPath));
@@ -391,15 +451,13 @@ function reconcilePlan(plan: WikiPlan, stagingDir: string): WikiPlan {
391
451
  title: relPath.replace(/\.md$/, ""),
392
452
  intent: "",
393
453
  sources: [],
394
- status: "written" as const,
395
- attempts: 1,
454
+ status: "pending" as const,
455
+ attempts: 0,
396
456
  }));
397
457
  return {
398
458
  ...plan,
399
459
  pages: [
400
- ...plan.pages.map((page) =>
401
- onDisk.has(page.path) ? { ...page, status: "written" as const } : { ...page, status: "pending" as const },
402
- ),
460
+ ...plan.pages.map((page) => (onDisk.has(page.path) ? page : { ...page, status: "pending" as const })),
403
461
  ...adopted,
404
462
  ],
405
463
  };
@@ -409,8 +467,6 @@ export async function runWikiGenerate(
409
467
  input: RunWikiGenerateInput = { model: "configured-clio-target" },
410
468
  ): Promise<RunWikiGenerateResult> {
411
469
  const cwd = input.cwd ?? process.cwd();
412
- const existingMeta = readWikiMeta(cwd);
413
- const mode = input.mode ?? (existingMeta ? "update" : "init");
414
470
 
415
471
  const lock = acquireWikiLock(cwd);
416
472
  if (!lock.ok) {
@@ -420,10 +476,12 @@ export async function runWikiGenerate(
420
476
  }
421
477
 
422
478
  try {
479
+ recoverPublication(cwd);
480
+ const existingMeta = readWikiMeta(cwd);
481
+ const mode = input.mode ?? (existingMeta ? "update" : "init");
423
482
  progress(input, { phase: "codewiki", status: "started", message: "loading codewiki for wiki generation" });
424
483
  const { codewiki, fingerprint } = await loadOrBuildCodewiki(cwd);
425
484
  const sourceTreeHash = fingerprint.treeHash;
426
- const generation = planWikiGeneration(codewiki, input.depth ?? "auto");
427
485
  progress(input, {
428
486
  phase: "codewiki",
429
487
  status: "completed",
@@ -433,6 +491,27 @@ export async function runWikiGenerate(
433
491
  });
434
492
 
435
493
  const staging = adoptOrCreateStaging(cwd);
494
+ const stagedPlan = staging.adopted ? readWikiPlanFile(staging.dir) : null;
495
+ const savedPlan = stagedPlan ?? (mode === "update" ? existingMeta?.plan : undefined);
496
+ const savedDepth = savedPlan?.depth ?? existingMeta?.generation?.depth;
497
+ const continuing = Boolean(
498
+ stagedPlan || input.retryPending || savedPlan?.pages.some((page) => page.status !== "written"),
499
+ );
500
+ const requestedDepth = input.depth ?? savedPlan?.requestedDepth ?? existingMeta?.generation?.requestedDepth ?? "auto";
501
+ const generation = planWikiGeneration(
502
+ codewiki,
503
+ continuing && (input.depth === undefined || input.depth === "auto") && savedDepth ? savedDepth : requestedDepth,
504
+ );
505
+ // Keep the policy separate from its resolved coverage so a completed auto wiki can grow.
506
+ generation.requestedDepth =
507
+ continuing && (input.depth === undefined || input.depth === "auto")
508
+ ? (savedPlan?.requestedDepth ?? existingMeta?.generation?.requestedDepth ?? savedDepth ?? requestedDepth)
509
+ : requestedDepth;
510
+ const depthChanged = Boolean(
511
+ savedPlan && (savedDepth ? savedDepth !== generation.depth : input.depth !== undefined && input.depth !== "auto"),
512
+ );
513
+ const sourceGitHead = currentWikiGitHead(cwd) ?? undefined;
514
+ const sourceContent = captureWikiSourceContent(cwd);
436
515
  const resolved = resolvePlan({
437
516
  cwd,
438
517
  stagingDir: staging.dir,
@@ -440,8 +519,25 @@ export async function runWikiGenerate(
440
519
  mode,
441
520
  candidate: generation.plan,
442
521
  previousPlan: existingMeta?.plan,
522
+ sourceContent,
443
523
  gitHead: existingMeta?.gitHead ?? null,
444
524
  });
525
+ if (input.retryPending && !resolved.resumed && !existingMeta?.plan) {
526
+ if (!staging.adopted) removeDir(staging.dir);
527
+ return failed(
528
+ ["no saved wiki plan to retry; run `clio-coder context wiki` first"],
529
+ listWikiPagesInDir(wikiDir(cwd)).length,
530
+ );
531
+ }
532
+ if (depthChanged) {
533
+ resolved.plan = {
534
+ ...resolved.plan,
535
+ pages: resolved.plan.pages.map((page) => ({ ...page, status: "pending", attempts: 0 })),
536
+ };
537
+ resolved.resumed = false;
538
+ }
539
+ resolved.plan.depth = generation.depth;
540
+ resolved.plan.requestedDepth = generation.requestedDepth;
445
541
  const owed = resolved.plan.pages.filter((page) => page.status !== "written").length;
446
542
  progress(input, {
447
543
  phase: "codewiki",
@@ -450,8 +546,14 @@ export async function runWikiGenerate(
450
546
  detail:
451
547
  `${generation.sourceFiles} source files; ${generation.sourceLines} lines; ` +
452
548
  `${resolved.plan.pages.length} pages planned; ${owed} to write` +
453
- (resolved.resumed ? "; resuming an interrupted run" : ""),
549
+ (resolved.resumed ? "; resuming an interrupted run" : "") +
550
+ (depthChanged
551
+ ? `; coverage changed from ${savedDepth ?? "legacy unspecified"} to ${generation.depth}; prior pages requeued with prose retained`
552
+ : ""),
454
553
  });
554
+ resolved.plan = { ...resolved.plan, sourceTreeHash, sourceContent };
555
+ if (sourceGitHead) resolved.plan.sourceGitHead = sourceGitHead;
556
+ else delete resolved.plan.sourceGitHead;
455
557
  writeWikiPlanFile(staging.dir, resolved.plan);
456
558
 
457
559
  const beforeHash = computeWikiContentHash(cwd);
@@ -476,7 +578,8 @@ export async function runWikiGenerate(
476
578
  codewiki,
477
579
  generation,
478
580
  plan: resolved.plan,
479
- resumed: resolved.resumed,
581
+ resumed: resolved.resumed || (input.retryPending === true && !depthChanged),
582
+ ...(input.retryPending ? { retryPending: true } : {}),
480
583
  unclaimedAreas: resolved.unclaimedAreas,
481
584
  ...(input.decisions ? { decisions: input.decisions } : {}),
482
585
  gitHead: existingMeta?.gitHead ?? null,
@@ -501,9 +604,33 @@ export async function runWikiGenerate(
501
604
  }
502
605
  progress(input, { phase: "generate", status: "completed", message: "wiki generator completed" });
503
606
 
504
- const workedPlan = readWikiPlanFile(staging.dir, resolved.plan) ?? resolved.plan;
607
+ const checkpoint = readWikiPlanFile(staging.dir) ?? resolved.plan;
608
+ // Replanning explicitly retires old planned publications. Other writer
609
+ // additions remain available, including pages linked by completed work.
610
+ for (const path of checkpoint.retiredPages ?? []) rmSync(join(staging.dir, path), { force: true });
611
+ // Capture citation evidence before assembly removes missing paths from
612
+ // routing metadata. Failed refreshes and no-op runs must retain it.
613
+ const citedSources = pageSourceIndex(staging.dir, cwd);
614
+ const currentContent = captureWikiSourceContent(cwd);
615
+ const workedPlan: WikiPlan = {
616
+ ...checkpoint,
617
+ sourceTreeHash,
618
+ sourceContent,
619
+ pages: checkpoint.pages.map((page) => {
620
+ const dependencies = [...new Set([...(page.dependencies ?? []), ...(citedSources.get(page.path) ?? [])])];
621
+ const stable = wikiSourcesMatch(sourceContent, currentContent, [...page.sources, ...dependencies]);
622
+ return {
623
+ ...page,
624
+ dependencies,
625
+ ...(page.status === "written" && !stable ? { status: "pending" as const, attempts: 0 } : {}),
626
+ };
627
+ }),
628
+ };
629
+ if (sourceGitHead) workedPlan.sourceGitHead = sourceGitHead;
630
+ else delete workedPlan.sourceGitHead;
505
631
  const report = assembleWikiTree({ dir: staging.dir, sourceRoot: cwd, plan: workedPlan });
506
632
  const finalPlan = reconcilePlan(workedPlan, staging.dir);
633
+ delete finalPlan.retiredPages;
507
634
  const pendingCount = finalPlan.pages.filter((page) => page.status !== "written").length;
508
635
  progress(input, {
509
636
  phase: "state",
@@ -515,9 +642,6 @@ export async function runWikiGenerate(
515
642
  (pendingCount > 0 ? `; ${pendingCount} page${pendingCount === 1 ? "" : "s"} still to write` : ""),
516
643
  });
517
644
 
518
- // The plan lives on in meta.json, so the staged working copy must not be
519
- // promoted into the wiki tree alongside the pages.
520
- rmSync(join(staging.dir, WIKI_PLAN_FILE), { force: true });
521
645
  const afterHash = computeWikiContentHashOfDir(staging.dir);
522
646
  const stagedPages = listWikiPagesInDir(staging.dir);
523
647
  // Unresolved references are reported, not fatal. They are repaired in the
@@ -525,25 +649,31 @@ export async function runWikiGenerate(
525
649
  // reach the operator and the next update run without costing this one.
526
650
  const problems = report.issues.map((issue) => `${issue.page} has an unresolved ${issue.kind}: ${issue.reference}`);
527
651
 
528
- const writeMeta = (): void => {
529
- writeWikiMeta(cwd, {
530
- version: 1,
531
- updatedAt: new Date().toISOString(),
532
- gitHead: currentWikiGitHead(cwd),
533
- sourceTreeHash,
534
- model: input.model,
535
- contentHash: afterHash,
536
- pages: stagedPages,
537
- generation: {
538
- requestedDepth: generation.requestedDepth,
539
- depth: generation.depth,
540
- sourceFiles: generation.sourceFiles,
541
- sourceLines: generation.sourceLines,
542
- pagesPlanned: finalPlan.pages.length,
543
- pagesWritten: finalPlan.pages.length - pendingCount,
544
- },
545
- plan: finalPlan,
546
- });
652
+ const unchanged = afterHash === beforeHash && existingMeta !== null;
653
+ const pendingPublishedPage = finalPlan.pages.some(
654
+ (page) => page.status !== "written" && stagedPages.some((available) => available.path === page.path),
655
+ );
656
+ const meta: WikiMeta = {
657
+ version: 1,
658
+ updatedAt: unchanged ? existingMeta.updatedAt : new Date().toISOString(),
659
+ gitHead: pendingPublishedPage ? (existingMeta?.gitHead ?? null) : currentWikiGitHead(cwd),
660
+ ...(pendingPublishedPage
661
+ ? existingMeta?.sourceTreeHash
662
+ ? { sourceTreeHash: existingMeta.sourceTreeHash }
663
+ : {}
664
+ : { sourceTreeHash }),
665
+ model: unchanged ? existingMeta.model : input.model,
666
+ contentHash: afterHash,
667
+ pages: stagedPages,
668
+ generation: {
669
+ requestedDepth: generation.requestedDepth,
670
+ depth: generation.depth,
671
+ sourceFiles: generation.sourceFiles,
672
+ sourceLines: generation.sourceLines,
673
+ pagesPlanned: finalPlan.pages.length,
674
+ pagesWritten: finalPlan.pages.length - pendingCount,
675
+ },
676
+ plan: finalPlan,
547
677
  };
548
678
 
549
679
  const done = (status: "generated" | "noop"): RunWikiGenerateResult => ({
@@ -558,22 +688,25 @@ export async function runWikiGenerate(
558
688
  // the assembled tree matches the live wiki byte for byte there is nothing
559
689
  // to swap, so metadata is refreshed in place.
560
690
  if (afterHash === beforeHash && computeWikiContentHash(cwd) === beforeHash && existingMeta) {
691
+ writeWikiMeta(cwd, meta);
692
+ rmSync(join(wikiDir(cwd), WIKI_PLAN_FILE), { force: true });
561
693
  removeDir(staging.dir);
562
- // Metadata is left exactly as it was. Rewriting it would churn
563
- // `updatedAt` and `model` on a run that changed nothing, which makes
564
- // every no-op look like a regeneration to anything reading the file.
565
694
  progress(input, {
566
695
  phase: "state",
567
696
  status: "completed",
568
- message: "wiki unchanged; metadata preserved",
697
+ message: "wiki unchanged; progress recorded",
569
698
  detail: wikiMetaPath(cwd),
570
699
  });
571
700
  progress(input, { phase: "done", status: "completed", message: "wiki unchanged" });
572
701
  return done("noop");
573
702
  }
574
703
 
704
+ // Keep the checkpoint until the complete publication is prepared. A crash
705
+ // during either rename can then recover the last good content/metadata pair.
706
+ writeWikiPlanFile(staging.dir, finalPlan);
707
+ writeWikiMetaInDir(staging.dir, meta);
575
708
  progress(input, { phase: "state", status: "running", message: "promoting wiki" });
576
- const promoted = promoteStaging(cwd, staging.dir, writeMeta);
709
+ const promoted = promoteStaging(cwd, staging.dir);
577
710
  if (!promoted.ok) {
578
711
  progress(input, {
579
712
  phase: "done",
@@ -583,6 +716,7 @@ export async function runWikiGenerate(
583
716
  });
584
717
  return failed(promoted.problems, listWikiPagesInDir(wikiDir(cwd)).length);
585
718
  }
719
+ rmSync(join(wikiDir(cwd), WIKI_PLAN_FILE), { force: true });
586
720
  progress(input, { phase: "state", status: "completed", message: "wiki metadata written" });
587
721
  progress(input, {
588
722
  phase: "done",
@@ -168,7 +168,11 @@ export function isWikiMeta(value: unknown): value is WikiMeta {
168
168
  }
169
169
 
170
170
  export function readWikiMeta(cwd: string): WikiMeta | null {
171
- const filePath = wikiMetaPath(cwd);
171
+ return readWikiMetaInDir(wikiDir(cwd));
172
+ }
173
+
174
+ export function readWikiMetaInDir(dir: string): WikiMeta | null {
175
+ const filePath = join(dir, "meta.json");
172
176
  if (!existsSync(filePath)) return null;
173
177
  let parsed: unknown;
174
178
  try {
@@ -181,6 +185,10 @@ export function readWikiMeta(cwd: string): WikiMeta | null {
181
185
  }
182
186
 
183
187
  export function writeWikiMeta(cwd: string, meta: WikiMeta): void {
188
+ writeWikiMetaInDir(wikiDir(cwd), meta);
189
+ }
190
+
191
+ export function writeWikiMetaInDir(dir: string, meta: WikiMeta): void {
184
192
  const normalized: WikiMeta = {
185
193
  version: 1,
186
194
  updatedAt: meta.updatedAt,
@@ -192,7 +200,7 @@ export function writeWikiMeta(cwd: string, meta: WikiMeta): void {
192
200
  ...(meta.generation !== undefined ? { generation: { ...meta.generation } } : {}),
193
201
  ...(meta.plan !== undefined ? { plan: meta.plan } : {}),
194
202
  };
195
- safeResourceWrite(wikiMetaPath(cwd), `${JSON.stringify(normalized)}\n`, { encoding: "utf8" });
203
+ safeResourceWrite(join(dir, "meta.json"), `${JSON.stringify(normalized)}\n`, { encoding: "utf8" });
196
204
  }
197
205
 
198
206
  /**
@@ -13,7 +13,8 @@ import { existsSync, readFileSync } from "node:fs";
13
13
  import { join } from "node:path";
14
14
  import { safeResourceWrite } from "../../../core/safe-resource-write.js";
15
15
  import { isGeneratedWikiFile, WIKI_PLAN_FILE } from "./layout.js";
16
- import type { WikiPageStatus, WikiPlan, WikiPlanPage } from "./plan.js";
16
+ import type { WikiPageFailure, WikiPageStatus, WikiPlan, WikiPlanPage } from "./plan.js";
17
+ import { parseWikiSourceContent } from "./source-content.js";
17
18
 
18
19
  /** Dispatches one page may receive across all runs before it is left alone. */
19
20
  export const MAX_PAGE_ATTEMPTS = 3;
@@ -75,6 +76,16 @@ function parsedAttempts(value: unknown): number | null {
75
76
  return typeof value === "number" && Number.isSafeInteger(value) && value >= 0 ? value : null;
76
77
  }
77
78
 
79
+ function parsedFailure(value: unknown): WikiPageFailure | undefined {
80
+ if (!isRecord(value)) return undefined;
81
+ const phase = value.phase;
82
+ if (phase !== "admission" && phase !== "writer" && phase !== "validation") return undefined;
83
+ const detail = usableString(value.detail)?.replace(/\s+/gu, " ").slice(0, 500);
84
+ if (!detail) return undefined;
85
+ const runId = usableString(value.runId)?.slice(0, 120);
86
+ return { phase, detail, ...(runId ? { runId } : {}) };
87
+ }
88
+
78
89
  export interface SanitizeWikiPlanOptions {
79
90
  /**
80
91
  * Whether the recorded progress in this document may be believed.
@@ -90,7 +101,7 @@ export interface SanitizeWikiPlanOptions {
90
101
 
91
102
  /**
92
103
  * Parse a plan, preferring harness-owned progress from `previous` for any page
93
- * whose path survived. Returns null when nothing usable is left, so the caller
104
+ * whose path and specification survived. Returns null when nothing usable is left, so the caller
94
105
  * falls back to the candidate plan.
95
106
  */
96
107
  export function sanitizeWikiPlan(
@@ -107,22 +118,65 @@ export function sanitizeWikiPlan(
107
118
  if (!isRecord(entry)) continue;
108
119
  const path = sanitizePagePath(entry.path);
109
120
  if (path === null || seen.has(path)) continue;
110
- const intent = usableString(entry.intent);
121
+ const intent = (usableString(entry.intent) ?? "").slice(0, MAX_INTENT_CHARS);
122
+ const title = usableString(entry.title) ?? path.replace(/\.md$/, "");
123
+ const sources = stringList(entry.sources, 16);
111
124
  const prior = priorByPath.get(path);
125
+ const changedSpec =
126
+ prior !== undefined &&
127
+ (prior.title !== title ||
128
+ prior.intent !== intent ||
129
+ JSON.stringify([...prior.sources].sort()) !== JSON.stringify([...sources].sort()));
112
130
  const recorded = options.trustStatus ? parsedStatus(entry.status) : null;
113
131
  const recordedAttempts = options.trustStatus ? parsedAttempts(entry.attempts) : null;
132
+ const lastFailure = prior?.lastFailure ?? (options.trustStatus ? parsedFailure(entry.lastFailure) : undefined);
133
+ const dependencies =
134
+ prior?.dependencies ?? (options.trustStatus ? stringList(entry.dependencies, Number.POSITIVE_INFINITY) : []);
114
135
  seen.add(path);
115
136
  pages.push({
116
137
  path,
117
- title: usableString(entry.title) ?? path.replace(/\.md$/, ""),
118
- intent: intent === null ? "" : intent.slice(0, MAX_INTENT_CHARS),
119
- sources: stringList(entry.sources, 16),
120
- status: prior?.status ?? recorded ?? "pending",
121
- attempts: prior?.attempts ?? recordedAttempts ?? 0,
138
+ title,
139
+ intent,
140
+ sources,
141
+ ...(dependencies.length > 0 ? { dependencies } : {}),
142
+ status: changedSpec ? "pending" : (prior?.status ?? recorded ?? "pending"),
143
+ attempts: changedSpec ? 0 : (prior?.attempts ?? recordedAttempts ?? 0),
144
+ ...(!changedSpec && (prior?.status ?? recorded) !== "written" && lastFailure ? { lastFailure } : {}),
122
145
  });
123
146
  }
124
147
  if (pages.length === 0) return null;
125
- return { version: 1, overview: usableString(value.overview) ?? previous?.overview ?? "", pages };
148
+ const retiredPages = [
149
+ ...new Set([
150
+ ...(previous?.retiredPages ?? (options.trustStatus ? stringList(value.retiredPages, MAX_PLAN_PAGES) : [])),
151
+ ...(previous?.pages.filter((page) => !seen.has(page.path)).map((page) => page.path) ?? []),
152
+ ]),
153
+ ]
154
+ .map(sanitizePagePath)
155
+ .filter((path): path is string => path !== null && !seen.has(path));
156
+ const sourceContent =
157
+ previous?.sourceContent ?? (options.trustStatus ? parseWikiSourceContent(value.sourceContent) : undefined);
158
+ const sourceTreeHash = previous?.sourceTreeHash ?? (options.trustStatus ? value.sourceTreeHash : undefined);
159
+ const sourceGitHead = previous?.sourceGitHead ?? (options.trustStatus ? value.sourceGitHead : undefined);
160
+ const depth = previous?.depth ?? (options.trustStatus ? value.depth : undefined);
161
+ const requestedDepth = previous?.requestedDepth ?? (options.trustStatus ? value.requestedDepth : undefined);
162
+ return {
163
+ version: 1,
164
+ ...(depth === "simple" || depth === "medium" || depth === "detailed" ? { depth } : {}),
165
+ ...(requestedDepth === "auto" ||
166
+ requestedDepth === "simple" ||
167
+ requestedDepth === "medium" ||
168
+ requestedDepth === "detailed"
169
+ ? { requestedDepth }
170
+ : {}),
171
+ ...(sourceContent ? { sourceContent } : {}),
172
+ ...(retiredPages.length ? { retiredPages } : {}),
173
+ ...(typeof sourceTreeHash === "string" && /^[a-f0-9]{64}$/.test(sourceTreeHash) ? { sourceTreeHash } : {}),
174
+ ...(typeof sourceGitHead === "string" && /^(?:[a-f0-9]{40}|[a-f0-9]{64})$/.test(sourceGitHead)
175
+ ? { sourceGitHead }
176
+ : {}),
177
+ overview: usableString(value.overview) ?? previous?.overview ?? "",
178
+ pages,
179
+ };
126
180
  }
127
181
 
128
182
  function readPlanDocument(dir: string): unknown {
@@ -174,7 +228,8 @@ export function unclaimedCandidates(
174
228
  const knownPaths = new Set(plan.pages.map((page) => page.path));
175
229
  const claimed = new Set<string>();
176
230
  for (const page of plan.pages) {
177
- for (const source of [...page.sources, ...(pageSources.get(page.path) ?? [])]) claimed.add(source);
231
+ for (const source of [...page.sources, ...(page.dependencies ?? []), ...(pageSources.get(page.path) ?? [])])
232
+ claimed.add(source);
178
233
  }
179
234
  return candidate.pages.filter(
180
235
  (page) => !knownPaths.has(page.path) && !page.sources.some((source) => claimed.has(source)),
@@ -201,8 +256,9 @@ export interface ScopeUpdateInput {
201
256
  export function scopePlanForUpdate(input: ScopeUpdateInput): WikiPlan {
202
257
  const changedPrefixes = [...input.changedPaths];
203
258
  const pages = input.plan.pages.map((page): WikiPlanPage => {
259
+ if (page.status !== "written") return page;
204
260
  if (!input.existingPages.has(page.path)) return { ...page, status: "pending", attempts: 0 };
205
- const claimed = [...(input.pageSources.get(page.path) ?? []), ...page.sources];
261
+ const claimed = [...(input.pageSources.get(page.path) ?? []), ...page.sources, ...(page.dependencies ?? [])];
206
262
  const touched = claimed.some((source) =>
207
263
  changedPrefixes.some((changed) => changed === source || changed.startsWith(`${source}/`)),
208
264
  );
@@ -211,7 +267,7 @@ export function scopePlanForUpdate(input: ScopeUpdateInput): WikiPlan {
211
267
  return { ...input.plan, pages };
212
268
  }
213
269
 
214
- /** Pages this run still owes, in plan order, excluding ones already exhausted. */
215
- export function pendingPages(plan: WikiPlan): WikiPlanPage[] {
216
- return plan.pages.filter((page) => page.status !== "written" && page.attempts < MAX_PAGE_ATTEMPTS);
270
+ /** An explicit operator retry includes exhausted pages without erasing their attempt history. */
271
+ export function pendingPages(plan: WikiPlan, retryExhausted = false): WikiPlanPage[] {
272
+ return plan.pages.filter((page) => page.status !== "written" && (retryExhausted || page.attempts < MAX_PAGE_ATTEMPTS));
217
273
  }