@iowarp/clio-coder 0.4.7 → 0.4.8

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 (485) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/CHANGELOG.md +29 -0
  3. package/CONTRIBUTING.md +83 -74
  4. package/README.md +66 -45
  5. package/dist/{acp-W3Y3TRHD.js → acp-JWPQZM2D.js} +14 -14
  6. package/dist/{agents-J4ICNLQ3.js → agents-4GCDIRVX.js} +55 -54
  7. package/dist/assets/codewiki.json +1 -1
  8. package/dist/assets/web-notices/@hono__node-server-LICENSE +21 -0
  9. package/dist/assets/web-notices/hono-LICENSE +21 -0
  10. package/dist/{auth-X2UJUMOC.js → auth-SYAKTDQE.js} +22 -22
  11. package/dist/background-OW67WMYR.js +37 -0
  12. package/dist/{builtins-XLXWWSRF.js → builtins-TKS63VNV.js} +4 -4
  13. package/dist/chunk-2JSCCEKO.js +85 -0
  14. package/dist/{chunk-QKWL7SYE.js → chunk-2SXGG2IV.js} +49 -38
  15. package/dist/{chunk-MZHXENL7.js → chunk-2U2U5POA.js} +5 -5
  16. package/dist/{chunk-NCCQ6DVS.js → chunk-2ZWLMA3T.js} +6 -6
  17. package/dist/{chunk-FQOOGXBH.js → chunk-36XSBPXL.js} +7 -7
  18. package/dist/{chunk-5AJPUR72.js → chunk-3IQOZRQ6.js} +7 -7
  19. package/dist/{chunk-4MFBBY2Z.js → chunk-44U2OUSM.js} +3 -3
  20. package/dist/{chunk-5ZSZEYJK.js → chunk-4P6M2TTE.js} +2 -2
  21. package/dist/{chunk-IZYTT3CD.js → chunk-526ABLHD.js} +6 -6
  22. package/dist/{chunk-BO4XV5VX.js → chunk-5C2OQHLR.js} +4 -4
  23. package/dist/chunk-5D2FNBMG.js +185 -0
  24. package/dist/{chunk-M6Z2V6YU.js → chunk-5HULHKT2.js} +5 -5
  25. package/dist/{chunk-PFLOULP3.js → chunk-5UG6EZI3.js} +4 -4
  26. package/dist/{chunk-WN552PKN.js → chunk-5W4FRA5Q.js} +280 -900
  27. package/dist/{chunk-KAFMW7WM.js → chunk-6R5MBXBJ.js} +1 -1
  28. package/dist/{chunk-24S3DN22.js → chunk-6TKOFFGE.js} +4 -4
  29. package/dist/{chunk-YKRJTYNP.js → chunk-6UJ7RDI7.js} +4 -4
  30. package/dist/{chunk-GXIWHXDB.js → chunk-6X7VOCDY.js} +3 -3
  31. package/dist/{chunk-KKEYGFX4.js → chunk-7QQRPB2E.js} +11 -11
  32. package/dist/{chunk-34XHRVKG.js → chunk-ARRUMZ7X.js} +2 -2
  33. package/dist/{chunk-3T4DXWP6.js → chunk-ATB3Q7YO.js} +1 -6
  34. package/dist/chunk-AUHVBIDW.js +19 -0
  35. package/dist/{chunk-L3Z5ANCV.js → chunk-BE4I3UJ2.js} +7 -7
  36. package/dist/chunk-BFPHMSK7.js +169 -0
  37. package/dist/{chunk-LVFANMOH.js → chunk-BHJMMCXS.js} +4 -4
  38. package/dist/{chunk-D2T66PDV.js → chunk-BIY22UUK.js} +35 -203
  39. package/dist/{chunk-VMATUZB6.js → chunk-D55WO5J7.js} +11 -11
  40. package/dist/{chunk-2O2LVQQK.js → chunk-E2NSPYLC.js} +4 -4
  41. package/dist/{chunk-IJMW64DX.js → chunk-EFXMQYI6.js} +32 -32
  42. package/dist/{chunk-GVZFCJHE.js → chunk-EPYATQMG.js} +18 -18
  43. package/dist/{chunk-MZNWZUJM.js → chunk-EXKUF426.js} +11 -11
  44. package/dist/{chunk-IMOD2YPV.js → chunk-F7Y6QTPL.js} +9 -19
  45. package/dist/{chunk-IQCNVLO6.js → chunk-FB3KTE2J.js} +10 -7
  46. package/dist/{chunk-3LXJOICS.js → chunk-FNVPQQYT.js} +2 -2
  47. package/dist/{chunk-UUQ5G6EZ.js → chunk-GEYX2NZ5.js} +2 -2
  48. package/dist/{chunk-CP3HIR5H.js → chunk-GJBJHJNY.js} +19 -18
  49. package/dist/{chunk-LZBMXNLP.js → chunk-GM4TY6VN.js} +43 -6
  50. package/dist/{chunk-WT5TRMO4.js → chunk-GVU4CXPJ.js} +179 -65
  51. package/dist/{chunk-TZ6UVP2H.js → chunk-H5DPSUBB.js} +8 -8
  52. package/dist/{chunk-EUEXGXXR.js → chunk-H77XBUBM.js} +5 -5
  53. package/dist/{config-YXARKGTX.js → chunk-HMGAKB7E.js} +15 -259
  54. package/dist/{chunk-EUZRMP4Y.js → chunk-HP7KJ5O2.js} +19 -19
  55. package/dist/chunk-HVCAY2FH.js +67 -0
  56. package/dist/{chunk-CPXGJI2A.js → chunk-ICYIUNO4.js} +4 -4
  57. package/dist/{chunk-GI5RRMAH.js → chunk-IILXVWJY.js} +7 -7
  58. package/dist/{chunk-MNQN3X6Y.js → chunk-JCVIL6TY.js} +5 -5
  59. package/dist/chunk-JIMWEYWO.js +63 -0
  60. package/dist/{chunk-C3G5PNUO.js → chunk-JLBVCROW.js} +25 -25
  61. package/dist/chunk-JOBN2YQQ.js +176 -0
  62. package/dist/chunk-JOL2QRLE.js +152 -0
  63. package/dist/{chunk-N37QC5FV.js → chunk-JRA6OBHY.js} +5 -5
  64. package/dist/{chunk-C6GEXX4L.js → chunk-JV25I7ID.js} +7 -7
  65. package/dist/{chunk-SEDI5K5B.js → chunk-JYKUMHCQ.js} +16 -16
  66. package/dist/{chunk-UA6W4XFJ.js → chunk-K3W6BF5C.js} +2 -2
  67. package/dist/chunk-K45LHSCI.js +194 -0
  68. package/dist/{chunk-UA3W4FGC.js → chunk-K53E2PTW.js} +5 -5
  69. package/dist/{chunk-VCRVEDUC.js → chunk-K5UJD6MM.js} +5 -5
  70. package/dist/{chunk-65BGHOUR.js → chunk-KGP3UQGJ.js} +5 -5
  71. package/dist/chunk-KKRXONXG.js +43 -0
  72. package/dist/{chunk-LBFQMYS3.js → chunk-KWJXCL2X.js} +5 -3
  73. package/dist/{chunk-RTLNFZMD.js → chunk-L75H5B3B.js} +3 -3
  74. package/dist/{chunk-G4LGUTOE.js → chunk-LLCGGVSW.js} +6 -6
  75. package/dist/{chunk-HRAKUPIH.js → chunk-LZCCBLRC.js} +5 -5
  76. package/dist/{chunk-WURGVOZJ.js → chunk-LZDLYSUN.js} +18 -14
  77. package/dist/{chunk-ISNCCX42.js → chunk-MATCRH3M.js} +7 -6
  78. package/dist/{chunk-BAU36233.js → chunk-MEHBW2SP.js} +7 -7
  79. package/dist/{chunk-BQQ5MXUC.js → chunk-MUXNDNMZ.js} +3 -3
  80. package/dist/{chunk-NO7J45X6.js → chunk-MWMW53WW.js} +90 -51
  81. package/dist/chunk-MZDPF35R.js +45 -0
  82. package/dist/{chunk-P4DL2LM5.js → chunk-MZKYVIWW.js} +8 -119
  83. package/dist/{chunk-T334FW2H.js → chunk-O2QJDRWP.js} +5 -5
  84. package/dist/{chunk-T7QQBNLH.js → chunk-O3HSB2YL.js} +9 -7
  85. package/dist/{chunk-WB7POC6M.js → chunk-OEMFEL26.js} +6 -6
  86. package/dist/{chunk-77CZRFTE.js → chunk-OPC4DQD6.js} +2 -2
  87. package/dist/{chunk-4UHVS5T7.js → chunk-ORRNGQDV.js} +8 -8
  88. package/dist/{chunk-TZHN5ITX.js → chunk-P4JS3MH5.js} +5 -5
  89. package/dist/{chunk-WBVKKTUT.js → chunk-P7GTE4FX.js} +2 -2
  90. package/dist/{chunk-6TAATXXH.js → chunk-PAQVETLA.js} +6 -6
  91. package/dist/{chunk-6CA2BHOR.js → chunk-PFZJMXIY.js} +4 -4
  92. package/dist/{chunk-4QKAITQT.js → chunk-PGEFOTJB.js} +70 -7
  93. package/dist/{chunk-MBJO5VNZ.js → chunk-PJ5H5B7A.js} +25 -25
  94. package/dist/{chunk-DO7M3LSX.js → chunk-PMUUAABD.js} +43 -96
  95. package/dist/{chunk-A67NR5AT.js → chunk-Q32C6AWI.js} +11 -8
  96. package/dist/{chunk-ECOMVOHP.js → chunk-QGIC5SX5.js} +2 -2
  97. package/dist/{chunk-5CMARGPF.js → chunk-QLAGXTTV.js} +7 -2
  98. package/dist/{chunk-GFQ7P2UF.js → chunk-QLKCCC2J.js} +9 -9
  99. package/dist/{chunk-SELG4SUR.js → chunk-QWUSS2QP.js} +7 -4
  100. package/dist/{chunk-P5SC4DLJ.js → chunk-QYSAZMSH.js} +2 -2
  101. package/dist/{fleet-decisions-S3PTZV2D.js → chunk-R5NRX5N4.js} +5 -41
  102. package/dist/{chunk-DLIYANB7.js → chunk-RAUOKUZV.js} +11 -11
  103. package/dist/{chunk-UFYNOQK4.js → chunk-RBES4TCZ.js} +7 -7
  104. package/dist/{chunk-T52TPHYC.js → chunk-RFULVPBX.js} +4 -4
  105. package/dist/{chunk-TLTGZTXI.js → chunk-RKFNU5UA.js} +3 -3
  106. package/dist/{chunk-T4TY5GG3.js → chunk-RM3XJX7P.js} +3 -3
  107. package/dist/{chunk-6YA46L5A.js → chunk-RNLAPBJL.js} +2 -2
  108. package/dist/chunk-RPMNIFRY.js +65 -0
  109. package/dist/{chunk-DACXIVVF.js → chunk-RRZFRIJP.js} +5 -5
  110. package/dist/{chunk-CE64C5K5.js → chunk-RXI7K4J5.js} +61 -61
  111. package/dist/{chunk-CULVKYTK.js → chunk-STC6CWUZ.js} +5 -5
  112. package/dist/{chunk-6YHPAAZR.js → chunk-TEHVMHOK.js} +3 -3
  113. package/dist/{chunk-VTYHHQ57.js → chunk-TOPICHGR.js} +2 -2
  114. package/dist/{chunk-UWD3JD5X.js → chunk-UB33F3YW.js} +10 -10
  115. package/dist/{chunk-TN5FW4XY.js → chunk-UDAK6GR2.js} +12 -9
  116. package/dist/chunk-USBBEKHW.js +177 -0
  117. package/dist/{chunk-6CB2IL4N.js → chunk-W5RM7YAH.js} +1 -1
  118. package/dist/{chunk-6LRLOJHQ.js → chunk-W7KNI3F5.js} +11 -62
  119. package/dist/chunk-WFTSK7N3.js +637 -0
  120. package/dist/{chunk-YPRSNUTC.js → chunk-WJWNZXRM.js} +2 -2
  121. package/dist/chunk-WS4FOGLY.js +686 -0
  122. package/dist/{chunk-ZGIGW4ZG.js → chunk-WTZVSMQZ.js} +5 -5
  123. package/dist/{chunk-XR3XJN2M.js → chunk-WWRV5RJI.js} +4 -4
  124. package/dist/{chunk-24TOGHPO.js → chunk-X6FLVUM5.js} +4 -4
  125. package/dist/chunk-XC5POIL4.js +68 -0
  126. package/dist/{chunk-XZ6UFQ52.js → chunk-XTLJDC2X.js} +22 -17
  127. package/dist/{chunk-7EEGBKV4.js → chunk-YGIV24MF.js} +8 -8
  128. package/dist/{chunk-RXFPB32E.js → chunk-YJCCMYYT.js} +2 -2
  129. package/dist/{chunk-4N2RZ4TO.js → chunk-YKIIWURD.js} +3 -3
  130. package/dist/{chunk-USZA7GWL.js → chunk-YQ3GFEUY.js} +2 -2
  131. package/dist/{chunk-KS7ETA3P.js → chunk-YXANQGCX.js} +6 -6
  132. package/dist/{chunk-HOX4YZ2K.js → chunk-YXFKLMX2.js} +5 -5
  133. package/dist/chunk-ZST3FRCV.js +132 -0
  134. package/dist/cli/index.js +39 -37
  135. package/dist/{clio-L2P7S2R2.js → clio-BPBAPZGA.js} +9 -9
  136. package/dist/{code-nav-B5LNX4KU.js → code-nav-KBQ3RIFK.js} +33 -33
  137. package/dist/{components-63MMQKUT.js → components-6DKAXWFN.js} +10 -10
  138. package/dist/config-FWL5JK2H.js +270 -0
  139. package/dist/config-graph-ACDB26L2.js +156 -0
  140. package/dist/{configure-LMVQJ46J.js → configure-ZIZ4YV62.js} +48 -48
  141. package/dist/{context-7HJEWTTP.js → context-EZZPT2ZV.js} +49 -49
  142. package/dist/{context-YG2LZDYZ.js → context-VIL5MFRH.js} +86 -84
  143. package/dist/{context-XSZKKFBW.js → context-Z3GOBHDK.js} +16 -16
  144. package/dist/{context-clear-AC5NXHM2.js → context-clear-ZPB3L7MN.js} +72 -70
  145. package/dist/{context-index-KKTPRV5G.js → context-index-W6A4V7OC.js} +4 -4
  146. package/dist/{context-map-T7ROR5D5.js → context-map-DKL3QT6D.js} +3 -3
  147. package/dist/{context-working-set-F4Q4J3NS.js → context-working-set-2GLBVF7L.js} +23 -22
  148. package/dist/{detail-H73BEF2N.js → detail-VSBWYSGZ.js} +73 -71
  149. package/dist/{dispatch-runner-3RY5FSJC.js → dispatch-runner-EEEHGKX4.js} +78 -76
  150. package/dist/docs-VMMWFVHL.js +101 -0
  151. package/dist/{doctor-EQYJOGUG.js → doctor-V5L4IQGP.js} +63 -62
  152. package/dist/{eval-4P7O6CCE.js → eval-VJYJ2BV3.js} +80 -65
  153. package/dist/{eval-inventory-QOYZERXJ.js → eval-inventory-CX24K2JT.js} +5 -60
  154. package/dist/evals-J2H5V6DD.js +104 -0
  155. package/dist/{evidence-D6GUSYJW.js → evidence-POWAEBEW.js} +72 -70
  156. package/dist/evidence-XCCCLS36.js +242 -0
  157. package/dist/{evidence-O76QF7TZ.js → evidence-Y35YSXH6.js} +80 -78
  158. package/dist/{evolve-H47BCETS.js → evolve-GPG72VB6.js} +74 -72
  159. package/dist/{extensions-NNL3ZOCU.js → extensions-YIZ7W3DA.js} +12 -11
  160. package/dist/fleet-2MDCQ2VK.js +264 -0
  161. package/dist/{fleet-KMNS6NOM.js → fleet-W2AF3TOJ.js} +127 -123
  162. package/dist/{fleet-commands-DOWSYCBX.js → fleet-commands-WS56G26H.js} +11 -11
  163. package/dist/fleet-decisions-MYGZ3JW7.js +52 -0
  164. package/dist/{fleet-graph-F2DE2TME.js → fleet-graph-ELTBXBAV.js} +22 -22
  165. package/dist/{fleet-inspect-EN2Q6IVB.js → fleet-inspect-45IK73L4.js} +84 -248
  166. package/dist/{fleet-preflight-FRLETDD3.js → fleet-preflight-T5NCZKHE.js} +4 -4
  167. package/dist/{fleet-validate-B2XDLS57.js → fleet-validate-VG4JBLA4.js} +26 -26
  168. package/dist/{fleet-verify-4JKUWGJ7.js → fleet-verify-VTSABAYO.js} +72 -70
  169. package/dist/{fleet-view-BHJFW26B.js → fleet-view-XC7WMKSS.js} +75 -73
  170. package/dist/{init-XAT5N5YM.js → init-VTJNNTIP.js} +95 -92
  171. package/dist/install-6PIF6F6W.js +19 -0
  172. package/dist/{interop-FVECHFKG.js → interop-IU6BNA7C.js} +25 -25
  173. package/dist/{inventory-7KFQGLCV.js → inventory-QPQUTUUZ.js} +75 -73
  174. package/dist/{library-NY2XOT75.js → library-HUTAS57T.js} +33 -33
  175. package/dist/{library-QAPAO23R.js → library-LF7DLU6S.js} +13 -13
  176. package/dist/library-Q3NWL5CM.js +75 -0
  177. package/dist/{library-import-5Y6MAS3R.js → library-import-PPW4YUC5.js} +25 -25
  178. package/dist/{library-inventory-JT6HWITQ.js → library-inventory-DIRVFRZU.js} +19 -19
  179. package/dist/{library-validation-EQUH25DC.js → library-validation-XHUZ3INE.js} +17 -17
  180. package/dist/{memory-DYVTTCP6.js → memory-Z2LSKNV6.js} +74 -72
  181. package/dist/{models-MASFJ6Y2.js → models-3FTREYPY.js} +53 -52
  182. package/dist/{monitor-YMP4NXJJ.js → monitor-HF2MQRB3.js} +83 -80
  183. package/dist/{orchestrator-AFQRRTEI.js → orchestrator-UYPA6W4S.js} +498 -358
  184. package/dist/{panes-NICTHQCV.js → panes-736XB73K.js} +14 -14
  185. package/dist/{panes-D3Y2KFG5.js → panes-C4P3PIWT.js} +4 -4
  186. package/dist/{paths-PSFAUIGO.js → paths-JQ4QYIYB.js} +6 -6
  187. package/dist/{preload-5Q7VXRFJ.js → preload-XSLRYH3Y.js} +72 -70
  188. package/dist/{reset-7NKZK7JN.js → reset-V7QSPZYE.js} +9 -9
  189. package/dist/{resources-NILSIZAT.js → resources-OJGDFHYT.js} +22 -22
  190. package/dist/{run-BPZGEBZV.js → run-T354SMDW.js} +129 -125
  191. package/dist/settings-MWZXO6RV.js +72 -0
  192. package/dist/{share-EZ6ERBMH.js → share-Y5ZKJPND.js} +26 -26
  193. package/dist/{skills-BTVVNYVM.js → skills-4GLZC4LN.js} +28 -28
  194. package/dist/{skills-eval-UY34MNK7.js → skills-eval-L5T7GODM.js} +87 -85
  195. package/dist/{skills-inventory-JDHSIA7I.js → skills-inventory-LASKXEZI.js} +22 -22
  196. package/dist/{slash-commands-K4FNQ2AT.js → slash-commands-OIMRU36D.js} +49 -49
  197. package/dist/{steer-2B3EQGFH.js → steer-KMAM2Y2C.js} +4 -4
  198. package/dist/{support-L2SOL3IE.js → support-AWC3XKPX.js} +8 -8
  199. package/dist/system-CD75NYBU.js +116 -0
  200. package/dist/{targets-44VKGFLN.js → targets-VSZX2J2S.js} +66 -65
  201. package/dist/{tasks-3KODKFU7.js → tasks-AN567LYH.js} +14 -14
  202. package/dist/{terminal-lease-LXA7MMPO.js → terminal-lease-6KTWNHVY.js} +3 -3
  203. package/dist/{tools-3UB7TEVR.js → tools-AGRK3V5J.js} +13 -13
  204. package/dist/{trace-TAMIU4OJ.js → trace-P4MQZD33.js} +18 -67
  205. package/dist/{uninstall-QYVRPEM4.js → uninstall-BRUTEPIC.js} +37 -12
  206. package/dist/{upgrade-7PMKM2JH.js → upgrade-SBCGHQGJ.js} +22 -21
  207. package/dist/{usage-6EQV7EQK.js → usage-BIDVTO6V.js} +93 -87
  208. package/dist/{verifiers-JLITWSHU.js → verifiers-LTGCAMXS.js} +12 -12
  209. package/dist/{verify-T7NAEVIG.js → verify-OZU4LLNP.js} +9 -9
  210. package/dist/web/client/THIRD_PARTY_LICENSES.md +1809 -0
  211. package/dist/web/client/assets/abnfDiagram-VCTEODGH-C5wfoHm3.js +1 -0
  212. package/dist/web/client/assets/arc-oH91sfLl.js +1 -0
  213. package/dist/web/client/assets/architecture-7GRP2DOG-EGozsYEO.js +1 -0
  214. package/dist/web/client/assets/architectureDiagram-5GKGNRK7-z9FokbJl.js +36 -0
  215. package/dist/web/client/assets/array-BifhSqXX.js +1 -0
  216. package/dist/web/client/assets/atkinson-hyperlegible-next-latin-ext-wght-normal-C6vrW8VD.woff2 +0 -0
  217. package/dist/web/client/assets/atkinson-hyperlegible-next-latin-wght-normal-BcXVPD7q.woff2 +0 -0
  218. package/dist/web/client/assets/blockDiagram-I7D4REHJ-wi0_CYHL.js +129 -0
  219. package/dist/web/client/assets/c4Diagram-7LVT6UL2-DV7NYc2W.js +38 -0
  220. package/dist/web/client/assets/channel-CiUWbHN9.js +1 -0
  221. package/dist/web/client/assets/chunk-2Q5K7J3B-C1jixKkw.js +1 -0
  222. package/dist/web/client/assets/chunk-4HAMMTFA-Bhsegh3F.js +62 -0
  223. package/dist/web/client/assets/chunk-5VM5RSS4-ZNzvKenW.js +15 -0
  224. package/dist/web/client/assets/chunk-75Z2AOVW-RQCckcQG.js +2 -0
  225. package/dist/web/client/assets/chunk-DU6HZSFF-C5USiOAy.js +125 -0
  226. package/dist/web/client/assets/chunk-F27PBJKO-BcNqv2x1.js +1 -0
  227. package/dist/web/client/assets/chunk-FOHPRMQF-CoA4358r.js +161 -0
  228. package/dist/web/client/assets/chunk-GMAD6QVW-Bq8JWiZT.js +72 -0
  229. package/dist/web/client/assets/chunk-GVQU2GXP-DbchrAeJ.js +1 -0
  230. package/dist/web/client/assets/chunk-IMKFNOWR-DrpvjocK.js +231 -0
  231. package/dist/web/client/assets/chunk-JWPE2WC7-DVXcaiue.js +1 -0
  232. package/dist/web/client/assets/chunk-L3NEJ4N5-DHLmTnCe.js +1 -0
  233. package/dist/web/client/assets/chunk-OSK3NFVY-CsRbtN9n.js +10 -0
  234. package/dist/web/client/assets/chunk-P2QGCYS3-aqPbxoMh.js +1 -0
  235. package/dist/web/client/assets/chunk-POPQ4Y6H-Dl5vw0h0.js +1 -0
  236. package/dist/web/client/assets/chunk-PWAF6VOD-D7OBRSdO.js +1 -0
  237. package/dist/web/client/assets/chunk-SHT3W25Y-CdKCIwuB.js +168 -0
  238. package/dist/web/client/assets/chunk-SVP7TREG-B94Nu_1-.js +88 -0
  239. package/dist/web/client/assets/chunk-TICWLB2K-jjRQI_hk.js +206 -0
  240. package/dist/web/client/assets/chunk-XXDRQBXY-azkbKE37.js +1 -0
  241. package/dist/web/client/assets/chunk-Y2CYZVJY-DsF7k-Jl.js +1 -0
  242. package/dist/web/client/assets/classDiagram-ZZMXUADV-CMODalmo.js +1 -0
  243. package/dist/web/client/assets/classDiagram-v2-VYDZK3BY-CMODalmo.js +1 -0
  244. package/dist/web/client/assets/commit-mono-latin-400-normal-s0S3qwFW.woff +0 -0
  245. package/dist/web/client/assets/commit-mono-latin-400-normal-wzhe4RuD.woff2 +0 -0
  246. package/dist/web/client/assets/cose-bilkent-JH36ORCC-RbQL23qS.js +1 -0
  247. package/dist/web/client/assets/cynefin-OW5HDTMX--i9RDU5f.js +1 -0
  248. package/dist/web/client/assets/cynefinDiagram-5FMLGOSQ-cRcvyBdp.js +62 -0
  249. package/dist/web/client/assets/cytoscape.esm-c2aL46s-.js +321 -0
  250. package/dist/web/client/assets/dagre-C-rnJpZF.js +1 -0
  251. package/dist/web/client/assets/dagre-GXQ25YYZ-C9mZmAPe.js +4 -0
  252. package/dist/web/client/assets/defaultLocale-BFoDCU3G.js +1 -0
  253. package/dist/web/client/assets/diagram-S7CK7UJ4-Oj_zlLDY.js +30 -0
  254. package/dist/web/client/assets/diagram-UQ7AKVKN-BWKbbfcR.js +41 -0
  255. package/dist/web/client/assets/diagram-VSXAHHWV-C3N3f7DO.js +3 -0
  256. package/dist/web/client/assets/diagram-VX7I27RA-CtDKDAWe.js +24 -0
  257. package/dist/web/client/assets/diagram-Z3DM3KII-B8bkBRCz.js +24 -0
  258. package/dist/web/client/assets/dist-D0_q-A2b.js +1 -0
  259. package/dist/web/client/assets/ebnfDiagram-PWID7BFC-CskW-Whx.js +1 -0
  260. package/dist/web/client/assets/erDiagram-RLTQ6QDP-C-83cgCW.js +99 -0
  261. package/dist/web/client/assets/eventmodeling-NTZA5JFV-DjVq8wKU.js +1 -0
  262. package/dist/web/client/assets/flowDiagram-HODETNUW-BUiCBGXt.js +1 -0
  263. package/dist/web/client/assets/ganttDiagram-EL5Y4UJY-B2lb8lvF.js +292 -0
  264. package/dist/web/client/assets/gitGraph-4MIJSDKK-B40cQtBE.js +1 -0
  265. package/dist/web/client/assets/gitGraphDiagram-WWUBYQGX-CH-7P7Di.js +106 -0
  266. package/dist/web/client/assets/graphlib-DS17s2tU.js +1 -0
  267. package/dist/web/client/assets/index-Dsi52apB.css +1 -0
  268. package/dist/web/client/assets/index-FSIC94pi.js +83 -0
  269. package/dist/web/client/assets/info-A6RAGUB7-eCCE9D_Q.js +1 -0
  270. package/dist/web/client/assets/infoDiagram-27XIBGKW-DRnvqMjM.js +2 -0
  271. package/dist/web/client/assets/init-C-OQMol4.js +1 -0
  272. package/dist/web/client/assets/ishikawaDiagram-5VMMS53U-DBA_55wp.js +70 -0
  273. package/dist/web/client/assets/journeyDiagram-3NMN7TZE-C-ewpNl7.js +139 -0
  274. package/dist/web/client/assets/kanban-definition-UXKFOSKX-B1taGsu0.js +89 -0
  275. package/dist/web/client/assets/katex-ZlcWpGUi.js +257 -0
  276. package/dist/web/client/assets/line-lZ0kyxDI.js +1 -0
  277. package/dist/web/client/assets/linear-DIc8FgZj.js +1 -0
  278. package/dist/web/client/assets/mermaid-parser.core-SXolxpXw.js +7 -0
  279. package/dist/web/client/assets/mermaid.core-DXgQtkNg.js +44 -0
  280. package/dist/web/client/assets/mindmap-definition-YA3MSWOX-DXJas9K7.js +96 -0
  281. package/dist/web/client/assets/newsreader-latin-ext-wght-normal-C-3rgBeH.woff2 +0 -0
  282. package/dist/web/client/assets/newsreader-latin-wght-normal-CCVVNp6i.woff2 +0 -0
  283. package/dist/web/client/assets/newsreader-vietnamese-wght-normal-Czsa-EzN.woff2 +0 -0
  284. package/dist/web/client/assets/ordinal-BDEzSJ7C.js +1 -0
  285. package/dist/web/client/assets/packet-AYTQ26CC-OqVl_07o.js +1 -0
  286. package/dist/web/client/assets/path-fybaL0A-.js +1 -0
  287. package/dist/web/client/assets/pegDiagram-XKGWAZYB-CPE_zdfN.js +1 -0
  288. package/dist/web/client/assets/pie-WAS4IAKB-DAxnMBLe.js +1 -0
  289. package/dist/web/client/assets/pieDiagram-E7YTZNPT-Uwjpufxv.js +39 -0
  290. package/dist/web/client/assets/prism-bash-D6zCJ74D.js +1 -0
  291. package/dist/web/client/assets/prism-c-04YixN25.js +1 -0
  292. package/dist/web/client/assets/prism-clike-DapgWyxx.js +1 -0
  293. package/dist/web/client/assets/prism-core-BngLtbUd.js +1 -0
  294. package/dist/web/client/assets/prism-cpp-C-lJbC-6.js +1 -0
  295. package/dist/web/client/assets/prism-css-CPgOzxXp.js +1 -0
  296. package/dist/web/client/assets/prism-diff-BF8m0_mq.js +3 -0
  297. package/dist/web/client/assets/prism-docker-DkT6yOFj.js +1 -0
  298. package/dist/web/client/assets/prism-fortran-Be5x3y1V.js +1 -0
  299. package/dist/web/client/assets/prism-go-C_8qAH5n.js +1 -0
  300. package/dist/web/client/assets/prism-ini-BESK3y0r.js +1 -0
  301. package/dist/web/client/assets/prism-javascript-BnO-swvr.js +1 -0
  302. package/dist/web/client/assets/prism-json-Dp_-W-Hv.js +1 -0
  303. package/dist/web/client/assets/prism-jsx-D-D0NWtC.js +1 -0
  304. package/dist/web/client/assets/prism-julia-DIjOgiAV.js +1 -0
  305. package/dist/web/client/assets/prism-latex-DNMbqcH_.js +1 -0
  306. package/dist/web/client/assets/prism-makefile-CRKWLQ8l.js +1 -0
  307. package/dist/web/client/assets/prism-markdown-C0FPJ1Iz.js +1 -0
  308. package/dist/web/client/assets/prism-markup-Cp04rIa1.js +1 -0
  309. package/dist/web/client/assets/prism-matlab-D-nk08al.js +1 -0
  310. package/dist/web/client/assets/prism-python-CfiSVtM6.js +1 -0
  311. package/dist/web/client/assets/prism-r-QmNGR8LX.js +1 -0
  312. package/dist/web/client/assets/prism-rust-Bu9N8X3N.js +1 -0
  313. package/dist/web/client/assets/prism-shell-session-Be4UuYoM.js +1 -0
  314. package/dist/web/client/assets/prism-sql-CYhVDMEE.js +1 -0
  315. package/dist/web/client/assets/prism-toml-DKb54GAT.js +1 -0
  316. package/dist/web/client/assets/prism-tsx-p6J2Kc_4.js +1 -0
  317. package/dist/web/client/assets/prism-typescript-BMqONzxf.js +1 -0
  318. package/dist/web/client/assets/prism-yaml-C0JHu8gr.js +1 -0
  319. package/dist/web/client/assets/purify.es-ChwZkWde.js +3 -0
  320. package/dist/web/client/assets/quadrantDiagram-AXDQQJYC-Bjs4yjgs.js +7 -0
  321. package/dist/web/client/assets/radar-RG4KPBEZ-CuCKjHM3.js +1 -0
  322. package/dist/web/client/assets/railroad-74A4TZTK-CnQK-Cc1.js +1 -0
  323. package/dist/web/client/assets/railroad-abnf-HS5TGJTU-BcW01NZG.js +1 -0
  324. package/dist/web/client/assets/railroad-ebnf-LZEXJU2U-B7YCEDDd.js +1 -0
  325. package/dist/web/client/assets/railroad-peg-WCYAUIDC-DjNZbSTZ.js +1 -0
  326. package/dist/web/client/assets/railroadDiagram-O6MQD6OU-BDDIPNLL.js +1 -0
  327. package/dist/web/client/assets/requirementDiagram-BXWQKSXE-B5Ydyxc1.js +84 -0
  328. package/dist/web/client/assets/rough.esm-Dy-Kn_BL.js +1 -0
  329. package/dist/web/client/assets/sankeyDiagram-P5KCCOFB-Bw2Qym75.js +40 -0
  330. package/dist/web/client/assets/sequenceDiagram-WJ2MYXX4-BZf36nO0.js +162 -0
  331. package/dist/web/client/assets/sizeCapture-INFHLROL-B0uUizjq.js +1 -0
  332. package/dist/web/client/assets/src-yeptRXpt.js +1 -0
  333. package/dist/web/client/assets/stateDiagram-D77RDMKH-DnH6JRkp.js +1 -0
  334. package/dist/web/client/assets/stateDiagram-v2-MP3YSRHH-C7QtHeK4.js +1 -0
  335. package/dist/web/client/assets/swimlanes-42K2YHIH-D9PZmtZg.js +1 -0
  336. package/dist/web/client/assets/swimlanesDiagram-VR7AAH4N-CBZlPFky.js +8 -0
  337. package/dist/web/client/assets/timeline-definition-24CTP7MA-CrkZZBo7.js +120 -0
  338. package/dist/web/client/assets/treeView-Q6P3EWNA-C9zDShoC.js +1 -0
  339. package/dist/web/client/assets/treemap-WGGIJYW6-B-plj9yK.js +1 -0
  340. package/dist/web/client/assets/vennDiagram-4TSXK5OY-VeOdaphN.js +34 -0
  341. package/dist/web/client/assets/wardley-WFR3VGLG-Wl1P_m6L.js +1 -0
  342. package/dist/web/client/assets/wardleyDiagram-VM6X3IG4-B85-R9t2.js +78 -0
  343. package/dist/web/client/assets/xychartDiagram-S5SC5T6Z-BrD8OW8m.js +7 -0
  344. package/dist/web/client/clio-coder-logo.webp +0 -0
  345. package/dist/web/client/icon-192.png +0 -0
  346. package/dist/web/client/icon-512.png +0 -0
  347. package/dist/web/client/index.html +4 -0
  348. package/dist/web/client/manifest.webmanifest +15 -0
  349. package/dist/web/client/offline.css +55 -0
  350. package/dist/web/client/offline.html +5 -0
  351. package/dist/web/client/offline.js +27 -0
  352. package/dist/web/client/sw.js +34 -0
  353. package/dist/web/ops-worker.js +37 -0
  354. package/dist/web/reads-worker.js +1726 -0
  355. package/dist/web/server.js +8499 -0
  356. package/dist/web-EU6ATJWA.js +13 -0
  357. package/dist/{web-fetch-W4TNW4Q7.js → web-fetch-U22Q7HV4.js} +3 -3
  358. package/dist/{wiki-generate-T2TJQJUA.js → wiki-generate-LZRLFG6I.js} +98 -95
  359. package/dist/{with-panes-CHFC7HGI.js → with-panes-X5CZOGML.js} +9 -9
  360. package/dist/worker/entry.js +68 -68
  361. package/docs/README.md +27 -26
  362. package/docs/architecture/acp.md +5 -9
  363. package/docs/architecture/alcf-provider.md +0 -3
  364. package/docs/architecture/architecture.md +0 -3
  365. package/docs/architecture/artifact-placement.md +0 -3
  366. package/docs/architecture/artifact-versions.md +0 -3
  367. package/docs/architecture/capacity-and-scheduling.md +0 -3
  368. package/docs/architecture/context-engine.md +0 -3
  369. package/docs/architecture/context-working-set.md +0 -3
  370. package/docs/architecture/dispatch-architecture-rationale.md +0 -3
  371. package/docs/architecture/dispatch-typed-intent.md +0 -3
  372. package/docs/architecture/evidence-and-memory.md +0 -3
  373. package/docs/architecture/library.md +0 -2
  374. package/docs/architecture/middleware-and-components.md +0 -3
  375. package/docs/architecture/model-catalog.md +1 -4
  376. package/docs/architecture/observability.md +0 -3
  377. package/docs/architecture/pi-boundary.md +6 -9
  378. package/docs/architecture/prompt-envelope-and-tools.md +1 -4
  379. package/docs/architecture/provider-adapter-cookbook.md +1 -4
  380. package/docs/architecture/safety-model.md +0 -3
  381. package/docs/architecture/session-lifecycle.md +0 -3
  382. package/docs/architecture/time-conventions.md +0 -3
  383. package/docs/architecture/trace-store.md +28 -20
  384. package/docs/architecture/tui-design.md +1 -4
  385. package/docs/architecture/worker-context.md +1 -3
  386. package/docs/architecture/worker-dispatch-mechanics.md +1 -4
  387. package/docs/guide/authoring-plugins.md +1 -3
  388. package/docs/guide/built-in-agents.md +0 -3
  389. package/docs/guide/commands-and-modes.md +2 -6
  390. package/docs/guide/configuration-and-targets.md +197 -4
  391. package/docs/guide/configuration-reference.md +9 -4
  392. package/docs/guide/environment-variables.md +0 -3
  393. package/docs/guide/exit-codes-and-output.md +0 -3
  394. package/docs/guide/extensions-and-sharing.md +0 -3
  395. package/docs/guide/fleet-dispatch.md +0 -3
  396. package/docs/guide/glossary.md +0 -3
  397. package/docs/guide/harness-extensions.md +0 -2
  398. package/docs/guide/installation-and-lifecycle.md +1 -4
  399. package/docs/guide/interop.md +0 -2
  400. package/docs/guide/panes-and-files.md +0 -3
  401. package/docs/guide/plugins.md +0 -3
  402. package/docs/guide/proactive-memory.md +0 -3
  403. package/docs/guide/resource-library.md +0 -2
  404. package/docs/guide/skills-marketplace.md +0 -2
  405. package/docs/guide/tool-usage.md +0 -3
  406. package/docs/guide/troubleshooting.md +0 -3
  407. package/docs/history/config-knobs-audit.md +0 -3
  408. package/docs/history/release-cut-checklist.md +0 -3
  409. package/docs/process/development-pipeline.md +0 -3
  410. package/docs/process/documentation-coverage.md +3 -3
  411. package/docs/process/documentation-guide.md +15 -22
  412. package/docs/process/eval-runner.md +0 -3
  413. package/docs/process/evals-internal.md +0 -3
  414. package/docs/process/evolution.md +0 -3
  415. package/docs/process/fleet-demo-runbook.md +0 -3
  416. package/docs/process/git-commit-provenance.md +0 -3
  417. package/docs/process/performance-methodology.md +1 -4
  418. package/docs/process/release-cut-checklist.md +114 -221
  419. package/docs/process/scientific-validation.md +1 -4
  420. package/library/registry.yaml +2 -2
  421. package/library/skills/meta/clio-coder-test/SKILL.md +25 -15
  422. package/library/skills/meta/clio-coder-test/evals.md +16 -2
  423. package/library/skills/meta/clio-coder-test/plugin.json +1 -1
  424. package/library/skills/meta/clio-coder-test/references/test-map.md +19 -18
  425. package/library/skills/registry.yaml +2 -2
  426. package/library/skills/skill-marketplace.json +1 -1
  427. package/package.json +13 -11
  428. package/src/cli/docs.ts +65 -328
  429. package/src/cli/index.ts +3 -1
  430. package/src/cli/trace.ts +4 -65
  431. package/src/cli/uninstall.ts +26 -0
  432. package/src/cli/usage.ts +3 -0
  433. package/src/cli/web.ts +79 -0
  434. package/src/core/bus-events.ts +3 -4
  435. package/src/core/config.ts +71 -0
  436. package/src/core/domain-loader.ts +37 -28
  437. package/src/core/termination.ts +13 -9
  438. package/src/domains/agents/contract.ts +1 -1
  439. package/src/domains/agents/extension.ts +18 -10
  440. package/src/domains/config/extension.ts +5 -4
  441. package/src/domains/dispatch/extension.ts +75 -12
  442. package/src/domains/dispatch/index.ts +1 -0
  443. package/src/domains/dispatch/orphan-recovery.ts +1 -0
  444. package/src/domains/dispatch/receipt-integrity.ts +3 -0
  445. package/src/domains/dispatch/state.ts +1 -2
  446. package/src/domains/dispatch/types.ts +2 -0
  447. package/src/domains/eval/metrics/tracked.ts +22 -2
  448. package/src/domains/extensions/operator-runtime.ts +3 -1
  449. package/src/domains/middleware/hooks.ts +2 -2
  450. package/src/domains/observability/background-memory-usage.ts +3 -0
  451. package/src/domains/observability/compaction-usage.ts +2 -0
  452. package/src/domains/observability/cost.ts +5 -0
  453. package/src/domains/observability/extension.ts +1 -0
  454. package/src/domains/observability/out-of-turn-usage.ts +2 -0
  455. package/src/domains/observability/trace-store.ts +65 -5
  456. package/src/domains/prompts/extension.ts +4 -17
  457. package/src/domains/providers/cache-deployment.ts +147 -0
  458. package/src/domains/providers/catalog.ts +12 -7
  459. package/src/domains/providers/extension.ts +27 -5
  460. package/src/domains/providers/index.ts +1 -0
  461. package/src/domains/providers/plugins.ts +3 -13
  462. package/src/domains/providers/runtimes/common/local-synth.ts +4 -0
  463. package/src/domains/providers/types/target-descriptor.ts +17 -0
  464. package/src/domains/session/compaction/compact.ts +4 -1
  465. package/src/domains/session/entries.ts +1 -0
  466. package/src/domains/session/usage.ts +6 -7
  467. package/src/engine/acp/server.ts +11 -0
  468. package/src/engine/ai.ts +2 -0
  469. package/src/engine/apis/openai-completions.ts +9 -4
  470. package/src/engine/prewarm.ts +232 -0
  471. package/src/engine/provider-diagnostics.ts +6 -1
  472. package/src/entry/orchestrator.ts +20 -16
  473. package/src/interactive/chat-loop-messages.ts +3 -0
  474. package/src/interactive/chat-loop.ts +2 -8
  475. package/src/interactive/prewarm.ts +11 -197
  476. package/src/interactive/session-usage-reseed.ts +2 -0
  477. package/src/interactive/side-question.ts +2 -0
  478. package/src/interactive/turn-context.ts +1 -0
  479. package/src/interactive/turn-persistence.ts +3 -0
  480. package/src/interactive/turn-prewarm.ts +126 -19
  481. package/src/interactive/turn-runtime.ts +14 -0
  482. package/src/tools/builtin-tool-catalog.ts +8 -4
  483. package/src/tools/registry.ts +12 -2
  484. package/src/worker/spec-contract.ts +27 -0
  485. package/dist/docs-BL7ROUFN.js +0 -292
@@ -0,0 +1,232 @@
1
+ /**
2
+ * One bounded-output warm through the eventual caller's engine request path.
3
+ * Copies portable context, applies public Pi transforms and payload hooks,
4
+ * and consumes the response without running tools or appending conversation.
5
+ * Admission and lifecycle remain with the caller. A matching serialized
6
+ * prefix is only a reuse candidate; the backend decides actual cache reuse.
7
+ */
8
+
9
+ import type { Agent } from "@earendil-works/pi-agent-core";
10
+ import type { BackendCompletionTimings } from "../core/cache-telemetry.js";
11
+ import { streamSimple } from "./ai.js";
12
+ import { estimateInputTokensFromContext } from "./apis/output-budget.js";
13
+ import type { AgentMessage, AgentTool, EngineModel, Usage } from "./types.js";
14
+
15
+ /**
16
+ * The one user message appended so the chat template renders the prefix up to
17
+ * the user turn. One character: it has to exist for the template to close the
18
+ * prefix, and everything after the last shared byte is re-evaluated by the real
19
+ * turn anyway.
20
+ */
21
+ export const PREWARM_USER_TEXT = ".";
22
+
23
+ /** Output budget for the round. The tokens the model produces are not the point. */
24
+ export const PREWARM_MAX_TOKENS = 1;
25
+
26
+ /** Which trigger asked for the pre-warm. Recorded on the ledger entry. */
27
+ export type PrewarmTrigger = "session-start" | "resume" | "compaction";
28
+
29
+ export interface PrewarmContext {
30
+ systemPrompt: string;
31
+ messages: ReadonlyArray<AgentMessage>;
32
+ tools: ReadonlyArray<AgentTool>;
33
+ }
34
+
35
+ /**
36
+ * The roles pi-agent-core's default `convertToLlm` keeps when it turns the
37
+ * agent's message list into provider messages. The pre-warm applies the same
38
+ * filter so its message array is the one a turn would send, not the agent's
39
+ * internal list.
40
+ */
41
+ const LLM_MESSAGE_ROLES: ReadonlySet<string> = new Set(["user", "assistant", "toolResult"]);
42
+
43
+ export interface PrewarmRoundInput {
44
+ model: EngineModel;
45
+ /** Live agent state the next turn would send. Read-only; the round copies it. */
46
+ state: {
47
+ systemPrompt: string;
48
+ messages: ReadonlyArray<AgentMessage>;
49
+ tools: ReadonlyArray<AgentTool>;
50
+ thinkingLevel: string;
51
+ };
52
+ apiKey?: string;
53
+ signal?: AbortSignal;
54
+ /** Admission bound on the engine's input estimate, after context selection. */
55
+ maxInputTokens?: number;
56
+ /** Public Pi preparation hooks of the eventual caller. No tools or agent loop are executed. */
57
+ agent?: Pick<
58
+ Agent,
59
+ | "transformContext"
60
+ | "convertToLlm"
61
+ | "streamFunction"
62
+ | "onPayload"
63
+ | "onResponse"
64
+ | "sessionId"
65
+ | "thinkingBudgets"
66
+ | "transport"
67
+ | "maxRetryDelayMs"
68
+ >;
69
+ /** Test seam. Production uses the engine dispatcher a turn runs on. */
70
+ streamFn?: typeof streamSimple;
71
+ }
72
+
73
+ export interface PrewarmRoundResult {
74
+ /** True when the operator submitted (or the session moved) before the round settled. */
75
+ aborted: boolean;
76
+ /** Provider usage for the round; null when the backend reported none. */
77
+ usage: Usage | null;
78
+ /** Backend prefill and prediction timings when the server reported them. */
79
+ backend: BackendCompletionTimings | null;
80
+ /** Wall clock the round spent, in the shape a turn's assistant entry uses. */
81
+ timing: { ttftMs: number | null; apiMs: number };
82
+ /** Provider error text when the round failed outright. */
83
+ errorMessage: string | null;
84
+ }
85
+
86
+ function usageOf(message: unknown): Usage | null {
87
+ if (message === null || typeof message !== "object") return null;
88
+ const usage = (message as { usage?: unknown }).usage;
89
+ if (usage === null || typeof usage !== "object") return null;
90
+ const record = usage as Usage;
91
+ // Pi initializes missing usage to zero, including on aborted/error calls.
92
+ // A warm with no observed tokens cannot be called a measured free request.
93
+ return [record.input, record.output, record.cacheRead, record.cacheWrite, record.cost?.total].some(
94
+ (value) => typeof value === "number" && Number.isFinite(value) && value > 0,
95
+ )
96
+ ? record
97
+ : null;
98
+ }
99
+
100
+ function backendOf(message: unknown): BackendCompletionTimings | null {
101
+ if (message === null || typeof message !== "object") return null;
102
+ const backend = (message as { backendTimings?: unknown }).backendTimings;
103
+ return backend !== null && typeof backend === "object" ? (backend as BackendCompletionTimings) : null;
104
+ }
105
+
106
+ /**
107
+ * Prompt tokens the backend actually processed for one pre-warm. The server's
108
+ * own prompt count is authoritative when it reported one; otherwise the
109
+ * provider usage prompt side, cached tokens folded in, is the honest figure.
110
+ * Null when neither exists, which is different from a measured zero.
111
+ */
112
+ export function prewarmPromptTokens(result: Pick<PrewarmRoundResult, "usage" | "backend">): number | null {
113
+ if (result.backend) return result.backend.promptTokens;
114
+ const usage = result.usage;
115
+ if (!usage) return null;
116
+ const total = (usage.input || 0) + (usage.cacheRead || 0) + (usage.cacheWrite || 0);
117
+ return total > 0 ? total : null;
118
+ }
119
+
120
+ /**
121
+ * Send the prefix and wait for the backend to acknowledge it. Resolves rather
122
+ * than rejects on a provider failure: a pre-warm is an optimization, and a
123
+ * backend that refuses it must not be able to break the session it was warming.
124
+ */
125
+ export async function runPrewarmRound(input: PrewarmRoundInput): Promise<PrewarmRoundResult> {
126
+ // pi-agent-core maps `thinkingLevel: "off"` onto an absent `reasoning`; the
127
+ // pre-warm has to make the same mapping or the thinking composition resolves
128
+ // against a different level and the rendered template moves.
129
+ const options: Record<string, unknown> = { maxTokens: PREWARM_MAX_TOKENS };
130
+ // Narrow residency authority without changing prompt rendering. A warm may
131
+ // not inherit the foreground turn's implicit load/unload authorization.
132
+ const metadata = (input.model as EngineModel & { clioCoder?: Record<string, unknown> }).clioCoder;
133
+ const model = metadata ? { ...input.model, clioCoder: { ...metadata, lifecycle: "user-managed" } } : input.model;
134
+ if (metadata?.runtimeId === "llamacpp") {
135
+ // A worker that disappeared after admission must not be JIT-loaded by
136
+ // the pinned llama router. This query is independent of prompt bytes.
137
+ options.fetch = (request: string | URL | Request, init?: RequestInit) => {
138
+ const url = new URL(request instanceof Request ? request.url : request);
139
+ url.searchParams.set("autoload", "false");
140
+ return fetch(request instanceof Request ? new Request(url, request) : url, init);
141
+ };
142
+ }
143
+ if (input.state.thinkingLevel !== "off") options.reasoning = input.state.thinkingLevel;
144
+ if (input.apiKey !== undefined) options.apiKey = input.apiKey;
145
+ if (input.signal !== undefined) options.signal = input.signal;
146
+ if (input.agent) {
147
+ for (const key of [
148
+ "onPayload",
149
+ "onResponse",
150
+ "sessionId",
151
+ "thinkingBudgets",
152
+ "transport",
153
+ "maxRetryDelayMs",
154
+ ] as const) {
155
+ if (input.agent[key] !== undefined) options[key] = input.agent[key];
156
+ }
157
+ }
158
+
159
+ const send = input.streamFn ?? input.agent?.streamFunction ?? streamSimple;
160
+ const startedAt = performance.now();
161
+ let firstDeltaAt: number | null = null;
162
+ const elapsed = (): number => Math.round(Math.max(0, performance.now() - startedAt));
163
+ const ttft = (): number | null => (firstDeltaAt === null ? null : Math.round(Math.max(0, firstDeltaAt - startedAt)));
164
+
165
+ try {
166
+ input.signal?.throwIfAborted();
167
+ let messages: AgentMessage[] = [
168
+ ...structuredClone([...input.state.messages]),
169
+ { role: "user", content: [{ type: "text", text: PREWARM_USER_TEXT }], timestamp: Date.now() },
170
+ ];
171
+ if (input.agent?.transformContext) messages = await input.agent.transformContext(messages, input.signal);
172
+ const converted = input.agent
173
+ ? await input.agent.convertToLlm(messages)
174
+ : messages.filter((message) => LLM_MESSAGE_ROLES.has(message.role));
175
+ input.signal?.throwIfAborted();
176
+ const context = {
177
+ systemPrompt: input.state.systemPrompt,
178
+ messages: converted,
179
+ tools: [...input.state.tools],
180
+ } as Parameters<typeof streamSimple>[1];
181
+ if (input.maxInputTokens !== undefined && estimateInputTokensFromContext(context) > input.maxInputTokens) {
182
+ throw new Error("pre-warm input estimate exceeds its token budget");
183
+ }
184
+ const events = await send(
185
+ model,
186
+ context as unknown as Parameters<typeof streamSimple>[1],
187
+ options as unknown as Parameters<typeof streamSimple>[2],
188
+ );
189
+ for await (const event of events) {
190
+ const hasDelta =
191
+ event.type === "toolcall_start" ||
192
+ ((event.type === "text_delta" || event.type === "thinking_delta" || event.type === "toolcall_delta") &&
193
+ event.delta.length > 0);
194
+ if (firstDeltaAt === null && hasDelta) firstDeltaAt = performance.now();
195
+ if (event.type === "done") {
196
+ return {
197
+ aborted: false,
198
+ usage: usageOf(event.message),
199
+ backend: backendOf(event.message),
200
+ timing: { ttftMs: ttft(), apiMs: elapsed() },
201
+ errorMessage: null,
202
+ };
203
+ }
204
+ if (event.type === "error") {
205
+ const failed = event.error as { stopReason?: unknown; errorMessage?: unknown };
206
+ const aborted = event.reason === "aborted" || failed.stopReason === "aborted" || input.signal?.aborted === true;
207
+ return {
208
+ aborted,
209
+ usage: usageOf(event.error),
210
+ backend: backendOf(event.error),
211
+ timing: { ttftMs: ttft(), apiMs: elapsed() },
212
+ errorMessage: aborted ? null : typeof failed.errorMessage === "string" ? failed.errorMessage : "pre-warm failed",
213
+ };
214
+ }
215
+ }
216
+ } catch (error) {
217
+ return {
218
+ aborted: input.signal?.aborted === true,
219
+ usage: null,
220
+ backend: null,
221
+ timing: { ttftMs: ttft(), apiMs: elapsed() },
222
+ errorMessage: input.signal?.aborted === true ? null : error instanceof Error ? error.message : String(error),
223
+ };
224
+ }
225
+ return {
226
+ aborted: input.signal?.aborted === true,
227
+ usage: null,
228
+ backend: null,
229
+ timing: { ttftMs: ttft(), apiMs: elapsed() },
230
+ errorMessage: null,
231
+ };
232
+ }
@@ -2,6 +2,7 @@ import { randomUUID } from "node:crypto";
2
2
  import { closeSync, constants, fstatSync, openSync, writeFileSync } from "node:fs";
3
3
  import { isAbsolute } from "node:path";
4
4
  import type { Api, AssistantMessageEventStream, Model, StreamOptions } from "@earendil-works/pi-ai";
5
+ import type { TargetCacheSettings } from "../domains/providers/types/target-descriptor.js";
5
6
  import { findEngineEnvKeys } from "./env-api-keys.js";
6
7
 
7
8
  /** Process-owned opt-in reaches every native engine call, including prewarm and workers. */
@@ -11,7 +12,11 @@ export function instrumentProviderCall<T extends StreamOptions>(
11
12
  invoke: (options: T | undefined) => AssistantMessageEventStream,
12
13
  ): AssistantMessageEventStream {
13
14
  let effective = options;
14
- if (model.api === "anthropic-messages" && options?.cacheRetention === undefined) {
15
+ const configured = (model as Model<Api> & { clioCoder?: { cache?: TargetCacheSettings } }).clioCoder?.cache?.retention;
16
+ if (options?.cacheRetention === undefined && configured !== undefined) {
17
+ effective = { ...options, cacheRetention: configured } as T;
18
+ }
19
+ if (model.api === "anthropic-messages" && effective?.cacheRetention === undefined) {
15
20
  const retention = process.env.CLIO_CODER_ANTHROPIC_CACHE_RETENTION;
16
21
  if (retention !== undefined && retention !== "") {
17
22
  if (retention !== "none" && retention !== "short" && retention !== "long") {
@@ -36,7 +36,7 @@ import {
36
36
  import { getSharedBus } from "../core/shared-bus.js";
37
37
  import { isSkillActivation } from "../core/skill-activation.js";
38
38
  import { StartupTimer } from "../core/startup-timer.js";
39
- import { getTerminationCoordinator } from "../core/termination.js";
39
+ import { getTerminationCoordinator, resolveShutdownHookBudgetMs } from "../core/termination.js";
40
40
  import { captureProjectSurface, projectSurfaceTrustNotice } from "../core/workspace-trust.js";
41
41
  import { clioDataDir, clioStateDir } from "../core/xdg.js";
42
42
  import { renderAgentCatalogSectionsFromSpecs } from "../domains/agents/catalog.js";
@@ -1203,8 +1203,10 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
1203
1203
  await dispatch.drain();
1204
1204
  });
1205
1205
  }
1206
- termination.onPersist(async () => {
1207
- await result.stop();
1206
+ // The loader caps each domain separately. The outer hook must allow the
1207
+ // whole sequence to finish, including cleanup after a timed-out domain.
1208
+ termination.onPersist(() => result.stop(), {
1209
+ timeoutMs: Math.min(2 ** 31 - 1, (result.loaded.length + 1) * resolveShutdownHookBudgetMs()),
1208
1210
  });
1209
1211
 
1210
1212
  bus.emit(BusChannels.SessionStart, { at: Date.now() });
@@ -1373,12 +1375,10 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
1373
1375
  // this boot projection below.
1374
1376
  configureRunEventJournal(resolvedSettings.fleet.history.journal);
1375
1377
 
1376
- // Guard registrations on the middleware contract, in order: loop guard,
1377
- // protected artifacts (last among guards so it absorbs protect_path effects
1378
- // from everything before it), dispatch dedup. Workers register their own
1379
- // loop guard and protected-artifacts instances inside their subprocess in
1380
- // worker-runtime.ts; the orchestrator instances carry the bus and the
1381
- // session persistence sink.
1378
+ // Register the loop and dispatch guards first. The protected-artifact guard
1379
+ // is constructed here but registered after user hooks below, so it can
1380
+ // absorb their protect_path effects. Workers register their own guards in
1381
+ // worker-runtime.ts; these instances carry the bus and session persistence.
1382
1382
  middleware.registerHook(
1383
1383
  createLoopGuardRegistration({
1384
1384
  safety,
@@ -1427,7 +1427,6 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
1427
1427
  }
1428
1428
  return protectedArtifactsGuard.state();
1429
1429
  };
1430
- middleware.registerHook(protectedArtifactsGuard);
1431
1430
  middleware.registerHook(createDispatchDedupRegistration());
1432
1431
  // Observers run after the guards; they emit no effects and their sinks are
1433
1432
  // best-effort (session ledger, codewiki refresh).
@@ -1525,9 +1524,9 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
1525
1524
  }
1526
1525
  // User-defined hooks: extensions and the project (.clio-coder/hooks.yaml,
1527
1526
  // .clio-coder/hooks.local.yaml) declare a conservative, receipted hook set on the
1528
- // same effect machinery. They register after the guards, so safety stays
1529
- // authoritative: a hook may add effects (including request block_tool) but
1530
- // cannot grant a permission safety would deny. Loading is best-effort.
1527
+ // same effect machinery. A hook may add effects (including request block_tool)
1528
+ // but cannot grant a permission safety would deny. The protected-artifact
1529
+ // guard follows them to consume protect_path before tool execution.
1531
1530
  // The coordinator is the only writer of the "user-hooks" owner and the only
1532
1531
  // caller of the extensions reload; it publishes the extension generation
1533
1532
  // and the hook registrations with two adjacent assignments on one stack
@@ -1535,7 +1534,7 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
1535
1534
  // published here too (the extensions bundle publishes nothing at start),
1536
1535
  // so no consumer ever sees extension resources paired with hooks from a
1537
1536
  // different generation. The owner slot is anchored here, so user hooks
1538
- // keep evaluating after the guards and before the assessors below.
1537
+ // keep evaluating before the protection consumer and assessors below.
1539
1538
  const hookReceiptLog = createHookReceiptLog({ persistPath: join(clioStateDir(), "hook-receipts.json") });
1540
1539
  let bootHookNotices = true;
1541
1540
  const reloadPlugins = () =>
@@ -1556,6 +1555,7 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
1556
1555
  },
1557
1556
  });
1558
1557
  extensionReload.applyBoot();
1558
+ middleware.registerHook(protectedArtifactsGuard);
1559
1559
  bootHookNotices = false;
1560
1560
  termination.onDrain(() => hookReceiptLog.flush());
1561
1561
  // Autonomy is hot-reloaded for interactive and headless admissions. ACP
@@ -1836,8 +1836,12 @@ export async function bootOrchestrator(options: BootOptions = {}): Promise<BootR
1836
1836
  // The config bundle publishes saved values on reload; session-scoped
1837
1837
  // overrides must win, so re-derive every process-local projection from the
1838
1838
  // effective session view after it.
1839
- const unsubscribeSettingsProjectionSync = bus.on(BusChannels.ConfigHotReload, () => bumpSessionState());
1840
- termination.onDrain(() => unsubscribeSettingsProjectionSync());
1839
+ const unsubscribeSettingsProjectionSync = [BusChannels.ConfigHotReload, BusChannels.ConfigNextTurn].map((channel) =>
1840
+ bus.on(channel, () => bumpSessionState()),
1841
+ );
1842
+ termination.onDrain(() => {
1843
+ for (const unsubscribe of unsubscribeSettingsProjectionSync) unsubscribe();
1844
+ });
1841
1845
  const getTaskMemorySeedOffer = (): { source: string; count: number } | null => {
1842
1846
  return taskMemoryHandoffSeedOffer(process.cwd(), getCurrentSettings().context.memory.enabled);
1843
1847
  };
@@ -362,6 +362,7 @@ export interface RunUsageSummary {
362
362
  output: number;
363
363
  cacheRead: number;
364
364
  cacheWrite: number;
365
+ cacheWrite1h?: number;
365
366
  reasoning: number;
366
367
  apiCalls: number;
367
368
  hadReasoning: boolean;
@@ -407,6 +408,7 @@ export function sumRunUsage(messages: ReadonlyArray<AgentMessage>): RunUsageSumm
407
408
  output?: unknown;
408
409
  cacheRead?: unknown;
409
410
  cacheWrite?: unknown;
411
+ cacheWrite1h?: unknown;
410
412
  totalTokens?: unknown;
411
413
  cost?: { total?: unknown };
412
414
  };
@@ -432,6 +434,7 @@ export function sumRunUsage(messages: ReadonlyArray<AgentMessage>): RunUsageSumm
432
434
  summary.output += output;
433
435
  summary.cacheRead += cacheRead;
434
436
  summary.cacheWrite += cacheWrite;
437
+ if (typeof usage.cacheWrite1h === "number") summary.cacheWrite1h = (summary.cacheWrite1h ?? 0) + usage.cacheWrite1h;
435
438
  const reasoning = extractReasoningTokens(usage);
436
439
  if (reasoning !== null) {
437
440
  summary.reasoning += reasoning;
@@ -862,13 +862,6 @@ export function createChatLoop(deps: CreateChatLoopDeps): ChatLoop {
862
862
  deps.bus?.on(BusChannels.ConfigHotReload, () => {
863
863
  context.invalidateSessionPromptCache();
864
864
  }) ?? null;
865
- // A committed extension generation with new content can change the skill
866
- // and prompt inputs the session prompt compiles from; same invalidation.
867
- const unsubscribeExtensionsReload =
868
- deps.bus?.on(BusChannels.ExtensionsReloaded, (payload) => {
869
- if (payload.changed) context.invalidateSessionPromptCache();
870
- }) ?? null;
871
-
872
865
  const unsubscribePluginsReload =
873
866
  deps.bus?.on(BusChannels.PluginsReloaded, () => {
874
867
  context.invalidateSessionPromptCache();
@@ -981,6 +974,7 @@ export function createChatLoop(deps: CreateChatLoopDeps): ChatLoop {
981
974
  output: usage.output,
982
975
  cacheRead: usage.cacheRead,
983
976
  cacheWrite: usage.cacheWrite,
977
+ ...(usage.cacheWrite1h === undefined ? {} : { cacheWrite1h: usage.cacheWrite1h }),
984
978
  reasoningTokens: usage.reasoning,
985
979
  totalTokens: usage.totalTokens,
986
980
  apiCalls: 1,
@@ -1004,6 +998,7 @@ export function createChatLoop(deps: CreateChatLoopDeps): ChatLoop {
1004
998
  output: usage.output,
1005
999
  cacheRead: usage.cacheRead,
1006
1000
  cacheWrite: usage.cacheWrite,
1001
+ ...(usage.cacheWrite1h === undefined ? {} : { cacheWrite1h: usage.cacheWrite1h }),
1007
1002
  reasoning: usage.reasoning,
1008
1003
  totalTokens: usage.totalTokens,
1009
1004
  costUsd: usage.costUsd,
@@ -1572,7 +1567,6 @@ export function createChatLoop(deps: CreateChatLoopDeps): ChatLoop {
1572
1567
 
1573
1568
  dispose(): void {
1574
1569
  unsubscribeConfigReload?.();
1575
- unsubscribeExtensionsReload?.();
1576
1570
  unsubscribePluginsReload?.();
1577
1571
  unsubscribeSynthesisLock?.();
1578
1572
  unsubscribePrewarmCompaction();
@@ -1,197 +1,11 @@
1
- /**
2
- * The session pre-warm round: the request the next turn would send, minus the
3
- * operator's text, issued as soon as the prefix is known.
4
- *
5
- * On a local server prefill is the cost. A fresh session's first turn prefills
6
- * the whole compiled prompt plus the tool schemas before the model emits a
7
- * token, and a resumed session's first turn prefills the entire replayed
8
- * history. Both are paid after the operator presses Enter, and both are fully
9
- * determined before they type anything. llama.cpp picks the slot with the
10
- * longest common prefix and re-evaluates only the suffix, so sending the prefix
11
- * early leaves the processed KV in the slot for the real turn to land on.
12
- *
13
- * The payload is not hand-assembled. It goes through `streamSimple`, the same
14
- * dispatcher `createEngineAgent` hands pi-agent-core as its `streamFn`, with the
15
- * same system prompt, the same tool schemas, the same replayed messages, and the
16
- * same thinking level, so `withSamplingOverrides`, the thinking composition, and
17
- * `cache_prompt` resolve exactly as they do for a turn. Any byte that differs
18
- * ahead of the user turn would defeat the purpose.
19
- */
20
-
21
- import type { BackendCompletionTimings } from "../core/cache-telemetry.js";
22
- import { streamSimple } from "../engine/ai.js";
23
- import type { AgentMessage, AgentTool, EngineModel, Usage } from "../engine/types.js";
24
-
25
- /**
26
- * The one user message appended so the chat template renders the prefix up to
27
- * the user turn. One character: it has to exist for the template to close the
28
- * prefix, and everything after the last shared byte is re-evaluated by the real
29
- * turn anyway.
30
- */
31
- export const PREWARM_USER_TEXT = ".";
32
-
33
- /** Output budget for the round. The tokens the model produces are not the point. */
34
- export const PREWARM_MAX_TOKENS = 1;
35
-
36
- /** Which trigger asked for the pre-warm. Recorded on the ledger entry. */
37
- export type PrewarmTrigger = "session-start" | "resume" | "compaction";
38
-
39
- export interface PrewarmContext {
40
- systemPrompt: string;
41
- messages: ReadonlyArray<AgentMessage>;
42
- tools: ReadonlyArray<AgentTool>;
43
- }
44
-
45
- /**
46
- * The roles pi-agent-core's default `convertToLlm` keeps when it turns the
47
- * agent's message list into provider messages. The pre-warm applies the same
48
- * filter so its message array is the one a turn would send, not the agent's
49
- * internal list.
50
- */
51
- const LLM_MESSAGE_ROLES: ReadonlySet<string> = new Set(["user", "assistant", "toolResult"]);
52
-
53
- /**
54
- * The prefix of the next turn's request: system prompt, tool schemas, and the
55
- * replayed conversation, with no user turn yet.
56
- */
57
- function prewarmPrefix(state: {
58
- systemPrompt: string;
59
- messages: ReadonlyArray<AgentMessage>;
60
- tools: ReadonlyArray<AgentTool>;
61
- }): PrewarmContext {
62
- return {
63
- systemPrompt: state.systemPrompt,
64
- messages: state.messages.filter((message) => LLM_MESSAGE_ROLES.has((message as { role?: string }).role ?? "")),
65
- tools: [...state.tools],
66
- };
67
- }
68
-
69
- export interface PrewarmRoundInput {
70
- model: EngineModel;
71
- /** Live agent state the next turn would send. Read-only; the round copies it. */
72
- state: {
73
- systemPrompt: string;
74
- messages: ReadonlyArray<AgentMessage>;
75
- tools: ReadonlyArray<AgentTool>;
76
- thinkingLevel: string;
77
- };
78
- apiKey?: string;
79
- signal?: AbortSignal;
80
- /** Test seam. Production uses the engine dispatcher a turn runs on. */
81
- streamFn?: typeof streamSimple;
82
- }
83
-
84
- export interface PrewarmRoundResult {
85
- /** True when the operator submitted (or the session moved) before the round settled. */
86
- aborted: boolean;
87
- /** Provider usage for the round; null when the backend reported none. */
88
- usage: Usage | null;
89
- /** Backend prefill and prediction timings when the server reported them. */
90
- backend: BackendCompletionTimings | null;
91
- /** Wall clock the round spent, in the shape a turn's assistant entry uses. */
92
- timing: { ttftMs: number | null; apiMs: number };
93
- /** Provider error text when the round failed outright. */
94
- errorMessage: string | null;
95
- }
96
-
97
- function usageOf(message: unknown): Usage | null {
98
- if (message === null || typeof message !== "object") return null;
99
- const usage = (message as { usage?: unknown }).usage;
100
- return usage !== null && typeof usage === "object" ? (usage as Usage) : null;
101
- }
102
-
103
- function backendOf(message: unknown): BackendCompletionTimings | null {
104
- if (message === null || typeof message !== "object") return null;
105
- const backend = (message as { backendTimings?: unknown }).backendTimings;
106
- return backend !== null && typeof backend === "object" ? (backend as BackendCompletionTimings) : null;
107
- }
108
-
109
- /**
110
- * Prompt tokens the backend actually processed for one pre-warm. The server's
111
- * own prompt count is authoritative when it reported one; otherwise the
112
- * provider usage prompt side, cached tokens folded in, is the honest figure.
113
- * Null when neither exists, which is different from a measured zero.
114
- */
115
- export function prewarmPromptTokens(result: Pick<PrewarmRoundResult, "usage" | "backend">): number | null {
116
- if (result.backend) return result.backend.promptTokens;
117
- const usage = result.usage;
118
- if (!usage) return null;
119
- const total = (usage.input || 0) + (usage.cacheRead || 0) + (usage.cacheWrite || 0);
120
- return total > 0 ? total : null;
121
- }
122
-
123
- /**
124
- * Send the prefix and wait for the backend to acknowledge it. Resolves rather
125
- * than rejects on a provider failure: a pre-warm is an optimization, and a
126
- * backend that refuses it must not be able to break the session it was warming.
127
- */
128
- export async function runPrewarmRound(input: PrewarmRoundInput): Promise<PrewarmRoundResult> {
129
- const prefix = prewarmPrefix(input.state);
130
- const context = {
131
- systemPrompt: prefix.systemPrompt,
132
- messages: [
133
- ...prefix.messages,
134
- { role: "user", content: [{ type: "text", text: PREWARM_USER_TEXT }], timestamp: Date.now() },
135
- ],
136
- tools: prefix.tools,
137
- };
138
- // pi-agent-core maps `thinkingLevel: "off"` onto an absent `reasoning`; the
139
- // pre-warm has to make the same mapping or the thinking composition resolves
140
- // against a different level and the rendered template moves.
141
- const options: Record<string, unknown> = { maxTokens: PREWARM_MAX_TOKENS };
142
- if (input.state.thinkingLevel !== "off") options.reasoning = input.state.thinkingLevel;
143
- if (input.apiKey !== undefined) options.apiKey = input.apiKey;
144
- if (input.signal !== undefined) options.signal = input.signal;
145
-
146
- const send = input.streamFn ?? streamSimple;
147
- const startedAt = performance.now();
148
- let firstDeltaAt: number | null = null;
149
- const elapsed = (): number => Math.round(Math.max(0, performance.now() - startedAt));
150
- const ttft = (): number | null => (firstDeltaAt === null ? null : Math.round(Math.max(0, firstDeltaAt - startedAt)));
151
-
152
- try {
153
- const events = send(
154
- input.model,
155
- context as unknown as Parameters<typeof streamSimple>[1],
156
- options as unknown as Parameters<typeof streamSimple>[2],
157
- );
158
- for await (const event of events) {
159
- if (firstDeltaAt === null && event.type !== "start") firstDeltaAt = performance.now();
160
- if (event.type === "done") {
161
- return {
162
- aborted: false,
163
- usage: usageOf(event.message),
164
- backend: backendOf(event.message),
165
- timing: { ttftMs: ttft(), apiMs: elapsed() },
166
- errorMessage: null,
167
- };
168
- }
169
- if (event.type === "error") {
170
- const failed = event.error as { stopReason?: unknown; errorMessage?: unknown };
171
- const aborted = event.reason === "aborted" || failed.stopReason === "aborted" || input.signal?.aborted === true;
172
- return {
173
- aborted,
174
- usage: usageOf(event.error),
175
- backend: backendOf(event.error),
176
- timing: { ttftMs: ttft(), apiMs: elapsed() },
177
- errorMessage: aborted ? null : typeof failed.errorMessage === "string" ? failed.errorMessage : "pre-warm failed",
178
- };
179
- }
180
- }
181
- } catch (error) {
182
- return {
183
- aborted: input.signal?.aborted === true,
184
- usage: null,
185
- backend: null,
186
- timing: { ttftMs: ttft(), apiMs: elapsed() },
187
- errorMessage: input.signal?.aborted === true ? null : error instanceof Error ? error.message : String(error),
188
- };
189
- }
190
- return {
191
- aborted: input.signal?.aborted === true,
192
- usage: null,
193
- backend: null,
194
- timing: { ttftMs: ttft(), apiMs: elapsed() },
195
- errorMessage: null,
196
- };
197
- }
1
+ /** Compatibility entry point; engine preparation is shared with headless callers. */
2
+ export {
3
+ PREWARM_MAX_TOKENS,
4
+ PREWARM_USER_TEXT,
5
+ type PrewarmContext,
6
+ type PrewarmRoundInput,
7
+ type PrewarmRoundResult,
8
+ type PrewarmTrigger,
9
+ prewarmPromptTokens,
10
+ runPrewarmRound,
11
+ } from "../engine/prewarm.js";
@@ -35,6 +35,7 @@ export interface SessionUsageSink {
35
35
  output: number;
36
36
  cacheRead: number;
37
37
  cacheWrite: number;
38
+ cacheWrite1h?: number;
38
39
  reasoningTokens: number;
39
40
  totalTokens: number;
40
41
  apiCalls?: number;
@@ -86,6 +87,7 @@ export function reseedSessionUsageFromLedger(
86
87
  output: call.output,
87
88
  cacheRead: call.cacheRead,
88
89
  cacheWrite: call.cacheWrite,
90
+ ...(call.cacheWrite1h === undefined ? {} : { cacheWrite1h: call.cacheWrite1h }),
89
91
  reasoningTokens: call.reasoningTokens,
90
92
  totalTokens: call.totalTokens,
91
93
  apiCalls: call.apiCalls ?? 1,
@@ -41,6 +41,7 @@ export interface SideQuestionUsage {
41
41
  output: number;
42
42
  cacheRead: number;
43
43
  cacheWrite: number;
44
+ cacheWrite1h?: number;
44
45
  reasoning: number;
45
46
  totalTokens: number;
46
47
  costUsd: number;
@@ -117,6 +118,7 @@ export function sideQuestionUsage(raw: unknown): SideQuestionUsage | null {
117
118
  output,
118
119
  cacheRead,
119
120
  cacheWrite,
121
+ ...(usage.cacheWrite1h === undefined ? {} : { cacheWrite1h: positive(usage.cacheWrite1h) }),
120
122
  reasoning: positive(usage.reasoning),
121
123
  totalTokens,
122
124
  costUsd: positive(usage.cost?.total),
@@ -705,6 +705,7 @@ export function createTurnContext(deps: TurnContextDeps): TurnContext {
705
705
  output: usage.output,
706
706
  cacheRead: usage.cacheRead,
707
707
  cacheWrite: usage.cacheWrite,
708
+ ...(usage.cacheWrite1h === undefined ? {} : { cacheWrite1h: usage.cacheWrite1h }),
708
709
  reasoningTokens: usage.reasoning,
709
710
  totalTokens: usage.totalTokens,
710
711
  apiCalls: Math.max(1, Math.round(usage.apiCalls)),
@@ -213,6 +213,9 @@ export function createTurnPersistence(deps: TurnPersistenceDeps): TurnPersistenc
213
213
  outputTokens: total.outputTokens + summary.output,
214
214
  cacheReadTokens: total.cacheReadTokens + summary.cacheRead,
215
215
  cacheWriteTokens: total.cacheWriteTokens + summary.cacheWrite,
216
+ ...(total.cacheWrite1hTokens === undefined && summary.cacheWrite1h === undefined
217
+ ? {}
218
+ : { cacheWrite1hTokens: (total.cacheWrite1hTokens ?? 0) + (summary.cacheWrite1h ?? 0) }),
216
219
  reasoningTokens: total.reasoningTokens + summary.reasoning,
217
220
  totalTokens: total.totalTokens + summary.tokens,
218
221
  costUsd: (total.costUsd ?? 0) + summary.costUsd,