@theokit/sdk 4.53.1 → 4.54.0

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 (692) hide show
  1. package/CHANGELOG.md +1088 -0
  2. package/README.md +9 -4
  3. package/dist/a2a/agent-mailbox.d.cts +27 -0
  4. package/dist/a2a/agent-mailbox.d.ts +27 -0
  5. package/dist/a2a/index.cjs +9 -4
  6. package/dist/a2a/index.cjs.map +1 -1
  7. package/dist/a2a/index.js +7 -2
  8. package/dist/a2a/index.js.map +1 -1
  9. package/dist/a2a/message-bus.d.cts +39 -0
  10. package/dist/a2a/message-bus.d.ts +39 -0
  11. package/dist/a2a/subagent.d.cts +68 -7
  12. package/dist/a2a/subagent.d.ts +68 -7
  13. package/dist/a2a/types.d.cts +26 -0
  14. package/dist/a2a/types.d.ts +26 -0
  15. package/dist/{agent-B9HXlwID.d.ts → agent-CIUgz7cN.d.cts} +190 -850
  16. package/dist/{agent-nLqeXKIX.d.cts → agent-DSec-E0c.d.ts} +190 -850
  17. package/dist/agent-NOEGF4GI.cjs +61 -0
  18. package/dist/{agent-YLAHVHEH.cjs.map → agent-NOEGF4GI.cjs.map} +1 -1
  19. package/dist/agent-VGD5WL4N.js +52 -0
  20. package/dist/{agent-FFVV4U5N.js.map → agent-VGD5WL4N.js.map} +1 -1
  21. package/dist/agent-builder.d.ts +19 -0
  22. package/dist/agent-session-store-P6V3FINW.js +7 -0
  23. package/dist/{agent-session-store-TNCGL5RN.js.map → agent-session-store-P6V3FINW.js.map} +1 -1
  24. package/dist/agent-session-store-ZJ3JSRS4.cjs +24 -0
  25. package/dist/{agent-session-store-DUGBAX5V.cjs.map → agent-session-store-ZJ3JSRS4.cjs.map} +1 -1
  26. package/dist/agent.d.ts +9 -6
  27. package/dist/auth/index.cjs +52 -35
  28. package/dist/auth/index.cjs.map +1 -1
  29. package/dist/auth/index.js +26 -9
  30. package/dist/auth/index.js.map +1 -1
  31. package/dist/{batch-UPKN4SG6.js → batch-2TGJMNCJ.js} +14 -13
  32. package/dist/batch-2TGJMNCJ.js.map +1 -0
  33. package/dist/{batch-ZEFN5SO7.cjs → batch-ND32UKZS.cjs} +31 -30
  34. package/dist/batch-ND32UKZS.cjs.map +1 -0
  35. package/dist/{chunk-TTJ54H3E.cjs → chunk-2ADR2GSO.cjs} +8 -8
  36. package/dist/chunk-2ADR2GSO.cjs.map +1 -0
  37. package/dist/{chunk-VGPXHHF3.cjs → chunk-2C72DXQF.cjs} +63 -27
  38. package/dist/chunk-2C72DXQF.cjs.map +1 -0
  39. package/dist/{chunk-4Q4K4WB5.js → chunk-2D34UTDC.js} +20 -4
  40. package/dist/chunk-2D34UTDC.js.map +1 -0
  41. package/dist/{chunk-UFIXH26P.js → chunk-2QKTVKH3.js} +4 -4
  42. package/dist/{chunk-UFIXH26P.js.map → chunk-2QKTVKH3.js.map} +1 -1
  43. package/dist/{chunk-GBBDINFK.js → chunk-3E77SX4H.js} +4 -4
  44. package/dist/{chunk-GBBDINFK.js.map → chunk-3E77SX4H.js.map} +1 -1
  45. package/dist/{chunk-VYHJZVL5.cjs → chunk-3EE6LVWT.cjs} +2 -2
  46. package/dist/chunk-3EE6LVWT.cjs.map +1 -0
  47. package/dist/chunk-3KGLRRFC.cjs +18 -0
  48. package/dist/chunk-3KGLRRFC.cjs.map +1 -0
  49. package/dist/{chunk-5NBUH3NO.js → chunk-3OR54XG4.js} +2 -2
  50. package/dist/{chunk-C6Y6CWYD.cjs.map → chunk-3OR54XG4.js.map} +1 -1
  51. package/dist/{chunk-ZN2DGEY3.cjs → chunk-3YJNUKYN.cjs} +15 -15
  52. package/dist/{chunk-ZN2DGEY3.cjs.map → chunk-3YJNUKYN.cjs.map} +1 -1
  53. package/dist/{chunk-POWRZSK4.js → chunk-44JAAH4X.js} +3 -3
  54. package/dist/{chunk-POWRZSK4.js.map → chunk-44JAAH4X.js.map} +1 -1
  55. package/dist/{chunk-SSDD676S.js → chunk-44MBDIHG.js} +4 -4
  56. package/dist/{chunk-SSDD676S.js.map → chunk-44MBDIHG.js.map} +1 -1
  57. package/dist/{chunk-OY7O3Q6R.js → chunk-4ERPXIVB.js} +5 -5
  58. package/dist/{chunk-OY7O3Q6R.js.map → chunk-4ERPXIVB.js.map} +1 -1
  59. package/dist/{chunk-3BK6YR5P.cjs → chunk-4I55V454.cjs} +4 -4
  60. package/dist/{chunk-3BK6YR5P.cjs.map → chunk-4I55V454.cjs.map} +1 -1
  61. package/dist/{chunk-B4YA6BRS.cjs → chunk-4O5TGQBW.cjs} +30 -7
  62. package/dist/chunk-4O5TGQBW.cjs.map +1 -0
  63. package/dist/{chunk-4JBHSLQO.cjs → chunk-4OTIXDMU.cjs} +2 -2
  64. package/dist/{chunk-4JBHSLQO.cjs.map → chunk-4OTIXDMU.cjs.map} +1 -1
  65. package/dist/{chunk-C6Y6CWYD.cjs → chunk-52NKC5HT.cjs} +2 -2
  66. package/dist/chunk-52NKC5HT.cjs.map +1 -0
  67. package/dist/{chunk-665SFFFR.cjs → chunk-53CBTBWO.cjs} +11 -11
  68. package/dist/{chunk-665SFFFR.cjs.map → chunk-53CBTBWO.cjs.map} +1 -1
  69. package/dist/{chunk-2D43RD5D.cjs → chunk-5BJV5UPY.cjs} +27 -27
  70. package/dist/chunk-5BJV5UPY.cjs.map +1 -0
  71. package/dist/{chunk-FFM3SJTQ.js → chunk-5JLFFPCH.js} +4 -4
  72. package/dist/{chunk-FFM3SJTQ.js.map → chunk-5JLFFPCH.js.map} +1 -1
  73. package/dist/{chunk-34XOCZJO.js → chunk-5PHVENFV.js} +3 -3
  74. package/dist/chunk-5PHVENFV.js.map +1 -0
  75. package/dist/{chunk-BDTVFIPB.cjs → chunk-5UOVYM3P.cjs} +36 -31
  76. package/dist/chunk-5UOVYM3P.cjs.map +1 -0
  77. package/dist/{chunk-VF7X6HDR.cjs → chunk-5USCYPPI.cjs} +15 -15
  78. package/dist/{chunk-VF7X6HDR.cjs.map → chunk-5USCYPPI.cjs.map} +1 -1
  79. package/dist/{chunk-D24WJWN2.js → chunk-AEOZTXVW.js} +3 -3
  80. package/dist/{chunk-D24WJWN2.js.map → chunk-AEOZTXVW.js.map} +1 -1
  81. package/dist/{chunk-DGOG5NXR.js → chunk-AG5JPQIY.js} +3 -3
  82. package/dist/{chunk-DGOG5NXR.js.map → chunk-AG5JPQIY.js.map} +1 -1
  83. package/dist/{chunk-V6HWJQQV.js → chunk-AGSBJD2L.js} +27 -30
  84. package/dist/chunk-AGSBJD2L.js.map +1 -0
  85. package/dist/{chunk-BFYGJGC5.js → chunk-AQLGBKNT.js} +3 -3
  86. package/dist/chunk-AQLGBKNT.js.map +1 -0
  87. package/dist/{chunk-7W7ZWMLQ.js → chunk-AWO27VRZ.js} +3 -3
  88. package/dist/chunk-AWO27VRZ.js.map +1 -0
  89. package/dist/{chunk-VYCKUKPA.cjs → chunk-B2J4ZMZL.cjs} +3 -2
  90. package/dist/chunk-B2J4ZMZL.cjs.map +1 -0
  91. package/dist/{chunk-BERBYXFH.js → chunk-BMAZLQQ4.js} +3 -3
  92. package/dist/{chunk-BERBYXFH.js.map → chunk-BMAZLQQ4.js.map} +1 -1
  93. package/dist/{chunk-5YKNEMXR.cjs → chunk-BVZW2B5V.cjs} +4 -4
  94. package/dist/chunk-BVZW2B5V.cjs.map +1 -0
  95. package/dist/{chunk-MSFLYJDY.js → chunk-CQ2TQ32Y.js} +4 -4
  96. package/dist/chunk-CQ2TQ32Y.js.map +1 -0
  97. package/dist/{chunk-C5DEO6OI.cjs → chunk-CQGYNZ3K.cjs} +4 -4
  98. package/dist/{chunk-C5DEO6OI.cjs.map → chunk-CQGYNZ3K.cjs.map} +1 -1
  99. package/dist/{chunk-D75S2X6I.cjs → chunk-CTCGWIUD.cjs} +5 -5
  100. package/dist/{chunk-D75S2X6I.cjs.map → chunk-CTCGWIUD.cjs.map} +1 -1
  101. package/dist/{chunk-NZL4BNFQ.js → chunk-CV7XMBHP.js} +4 -4
  102. package/dist/chunk-CV7XMBHP.js.map +1 -0
  103. package/dist/{chunk-SEL2ZQMT.js → chunk-DAPSQZT4.js} +15 -10
  104. package/dist/chunk-DAPSQZT4.js.map +1 -0
  105. package/dist/{chunk-SVO5WPZX.cjs → chunk-DQKERTND.cjs} +11 -11
  106. package/dist/{chunk-SVO5WPZX.cjs.map → chunk-DQKERTND.cjs.map} +1 -1
  107. package/dist/{chunk-GOVJO4YE.js → chunk-DUIF54UP.js} +6 -6
  108. package/dist/chunk-DUIF54UP.js.map +1 -0
  109. package/dist/{chunk-N5CR3TJZ.js → chunk-DZBSJX6J.js} +4 -4
  110. package/dist/{chunk-N5CR3TJZ.js.map → chunk-DZBSJX6J.js.map} +1 -1
  111. package/dist/{chunk-RAHSWE5C.cjs → chunk-EI2Q7SJ5.cjs} +12 -12
  112. package/dist/chunk-EI2Q7SJ5.cjs.map +1 -0
  113. package/dist/{chunk-UCFONJBG.js → chunk-EPSICJLZ.js} +2 -2
  114. package/dist/{chunk-UCFONJBG.js.map → chunk-EPSICJLZ.js.map} +1 -1
  115. package/dist/{chunk-3X6PM7DU.cjs → chunk-F3YZMOAU.cjs} +8 -8
  116. package/dist/{chunk-3X6PM7DU.cjs.map → chunk-F3YZMOAU.cjs.map} +1 -1
  117. package/dist/{chunk-HE4BIAOS.js → chunk-F7AQV62G.js} +5 -4
  118. package/dist/chunk-F7AQV62G.js.map +1 -0
  119. package/dist/{chunk-HSQ5Q3I5.js → chunk-FXEUP75G.js} +5 -5
  120. package/dist/chunk-FXEUP75G.js.map +1 -0
  121. package/dist/{chunk-2RW7K6FN.cjs → chunk-GHX4P3V2.cjs} +2 -2
  122. package/dist/chunk-GHX4P3V2.cjs.map +1 -0
  123. package/dist/{chunk-B6HOIWQ6.js → chunk-GJ6RK75E.js} +5 -5
  124. package/dist/chunk-GJ6RK75E.js.map +1 -0
  125. package/dist/{chunk-FOXKFTVZ.cjs → chunk-GNT35C5U.cjs} +13 -13
  126. package/dist/chunk-GNT35C5U.cjs.map +1 -0
  127. package/dist/{chunk-4NAKHID5.js → chunk-GTKFV7O5.js} +2 -2
  128. package/dist/chunk-GTKFV7O5.js.map +1 -0
  129. package/dist/{chunk-ELKO4ZLR.cjs → chunk-GWC3HADL.cjs} +4 -4
  130. package/dist/{chunk-ELKO4ZLR.cjs.map → chunk-GWC3HADL.cjs.map} +1 -1
  131. package/dist/{chunk-OXNYIMZZ.js → chunk-H73MEMQB.js} +2 -2
  132. package/dist/chunk-H73MEMQB.js.map +1 -0
  133. package/dist/{chunk-E7FJOO4G.cjs → chunk-HJBMA5MB.cjs} +11 -11
  134. package/dist/{chunk-E7FJOO4G.cjs.map → chunk-HJBMA5MB.cjs.map} +1 -1
  135. package/dist/{chunk-VW6M4B3Z.cjs → chunk-HY57ULY2.cjs} +5 -5
  136. package/dist/{chunk-VW6M4B3Z.cjs.map → chunk-HY57ULY2.cjs.map} +1 -1
  137. package/dist/{chunk-CAH3G4IS.js → chunk-HY66GLM6.js} +2 -2
  138. package/dist/chunk-HY66GLM6.js.map +1 -0
  139. package/dist/{chunk-C4H6PB5J.cjs → chunk-I6TGFUCO.cjs} +4 -4
  140. package/dist/{chunk-C4H6PB5J.cjs.map → chunk-I6TGFUCO.cjs.map} +1 -1
  141. package/dist/{chunk-U4UJHOSH.js → chunk-IDCKSLYH.js} +3 -3
  142. package/dist/{chunk-U4UJHOSH.js.map → chunk-IDCKSLYH.js.map} +1 -1
  143. package/dist/{chunk-WQ53UQL4.cjs → chunk-ILCGLTSA.cjs} +4 -4
  144. package/dist/{chunk-WQ53UQL4.cjs.map → chunk-ILCGLTSA.cjs.map} +1 -1
  145. package/dist/{chunk-SZHU7A5B.cjs → chunk-IWBGCBR6.cjs} +4 -4
  146. package/dist/{chunk-SZHU7A5B.cjs.map → chunk-IWBGCBR6.cjs.map} +1 -1
  147. package/dist/{chunk-Q4RESANI.cjs → chunk-J24VJOH3.cjs} +20 -4
  148. package/dist/chunk-J24VJOH3.cjs.map +1 -0
  149. package/dist/{chunk-Y4AXQOT4.cjs → chunk-JHPGF3FP.cjs} +8 -8
  150. package/dist/{chunk-Y4AXQOT4.cjs.map → chunk-JHPGF3FP.cjs.map} +1 -1
  151. package/dist/{chunk-BM6N4KHO.cjs → chunk-JTB5Q42C.cjs} +6 -22
  152. package/dist/chunk-JTB5Q42C.cjs.map +1 -0
  153. package/dist/{chunk-LPVIRJVF.cjs → chunk-K3FW2XZD.cjs} +9 -9
  154. package/dist/{chunk-LPVIRJVF.cjs.map → chunk-K3FW2XZD.cjs.map} +1 -1
  155. package/dist/{chunk-XPR366DL.cjs → chunk-NGESVVJN.cjs} +17 -17
  156. package/dist/chunk-NGESVVJN.cjs.map +1 -0
  157. package/dist/{chunk-VC5ABJXC.js → chunk-NLTVXLGT.js} +3 -3
  158. package/dist/{chunk-VC5ABJXC.js.map → chunk-NLTVXLGT.js.map} +1 -1
  159. package/dist/chunk-NUKRL3I6.cjs +23 -0
  160. package/dist/chunk-NUKRL3I6.cjs.map +1 -0
  161. package/dist/{chunk-R5YZACGK.js → chunk-OC4NTGMN.js} +3 -3
  162. package/dist/{chunk-R5YZACGK.js.map → chunk-OC4NTGMN.js.map} +1 -1
  163. package/dist/{chunk-FPYT5WZP.cjs → chunk-P6A3M6VD.cjs} +10 -10
  164. package/dist/{chunk-FPYT5WZP.cjs.map → chunk-P6A3M6VD.cjs.map} +1 -1
  165. package/dist/{chunk-OKLYRPKL.cjs → chunk-Q47R5E2X.cjs} +8 -8
  166. package/dist/chunk-Q47R5E2X.cjs.map +1 -0
  167. package/dist/{chunk-2XLKLVVR.js → chunk-Q5EWJPRY.js} +2 -2
  168. package/dist/chunk-Q5EWJPRY.js.map +1 -0
  169. package/dist/{chunk-SK4QLUBK.js → chunk-QARJGQSA.js} +16 -7
  170. package/dist/chunk-QARJGQSA.js.map +1 -0
  171. package/dist/{chunk-CZ2GKKYL.cjs → chunk-QDED6YO6.cjs} +5 -5
  172. package/dist/{chunk-CZ2GKKYL.cjs.map → chunk-QDED6YO6.cjs.map} +1 -1
  173. package/dist/{chunk-VK7MAV65.cjs → chunk-QKLOP4VC.cjs} +2 -2
  174. package/dist/{chunk-VK7MAV65.cjs.map → chunk-QKLOP4VC.cjs.map} +1 -1
  175. package/dist/{chunk-FIOCJYLA.js → chunk-QRSUA2CV.js} +3 -3
  176. package/dist/{chunk-FIOCJYLA.js.map → chunk-QRSUA2CV.js.map} +1 -1
  177. package/dist/{chunk-ZT57WTUJ.cjs → chunk-R3UPQFKK.cjs} +21 -12
  178. package/dist/chunk-R3UPQFKK.cjs.map +1 -0
  179. package/dist/{chunk-X2FR4OIT.js → chunk-R7WIIPUR.js} +2 -2
  180. package/dist/chunk-R7WIIPUR.js.map +1 -0
  181. package/dist/{chunk-VUKQL3L2.cjs → chunk-RM7Y65IG.cjs} +13 -13
  182. package/dist/chunk-RM7Y65IG.cjs.map +1 -0
  183. package/dist/{chunk-RP5HQVLD.js → chunk-RNB4APBZ.js} +30 -7
  184. package/dist/chunk-RNB4APBZ.js.map +1 -0
  185. package/dist/{chunk-GD63JPGC.cjs → chunk-ROYPRJH4.cjs} +9 -9
  186. package/dist/{chunk-GD63JPGC.cjs.map → chunk-ROYPRJH4.cjs.map} +1 -1
  187. package/dist/{chunk-V26QVGUG.js → chunk-RUDY2GTT.js} +59 -23
  188. package/dist/chunk-RUDY2GTT.js.map +1 -0
  189. package/dist/{chunk-JIQRXKTA.cjs → chunk-SKXBJ2NU.cjs} +7 -7
  190. package/dist/chunk-SKXBJ2NU.cjs.map +1 -0
  191. package/dist/chunk-SSQZA3DZ.js +15 -0
  192. package/dist/chunk-SSQZA3DZ.js.map +1 -0
  193. package/dist/{chunk-XROIW6BH.js → chunk-SUKXXLWD.js} +6 -6
  194. package/dist/chunk-SUKXXLWD.js.map +1 -0
  195. package/dist/{chunk-LTSTGCL6.js → chunk-T73NA43R.js} +3 -3
  196. package/dist/{chunk-LTSTGCL6.js.map → chunk-T73NA43R.js.map} +1 -1
  197. package/dist/chunk-T7O6K6PX.js +20 -0
  198. package/dist/chunk-T7O6K6PX.js.map +1 -0
  199. package/dist/{chunk-5F5NWKPN.js → chunk-T7XEKOVW.js} +5 -20
  200. package/dist/chunk-T7XEKOVW.js.map +1 -0
  201. package/dist/{chunk-G3JWXOGY.js → chunk-TPTZA6NI.js} +250 -103
  202. package/dist/chunk-TPTZA6NI.js.map +1 -0
  203. package/dist/{chunk-QBTVATSF.cjs → chunk-TTHBHAJI.cjs} +44 -47
  204. package/dist/chunk-TTHBHAJI.cjs.map +1 -0
  205. package/dist/{chunk-HAWE74GQ.cjs → chunk-U2AC6JUP.cjs} +8 -8
  206. package/dist/chunk-U2AC6JUP.cjs.map +1 -0
  207. package/dist/{chunk-3WVMJY7F.js → chunk-UC3HT2S4.js} +3 -3
  208. package/dist/{chunk-3WVMJY7F.js.map → chunk-UC3HT2S4.js.map} +1 -1
  209. package/dist/{chunk-F77UENR6.cjs → chunk-UFAO4T7Z.cjs} +526 -379
  210. package/dist/chunk-UFAO4T7Z.cjs.map +1 -0
  211. package/dist/{chunk-2FYEVT2B.cjs → chunk-UNDROG5N.cjs} +201 -154
  212. package/dist/chunk-UNDROG5N.cjs.map +1 -0
  213. package/dist/{chunk-PBZ7HMBP.js → chunk-UPRJR6IP.js} +4 -4
  214. package/dist/chunk-UPRJR6IP.js.map +1 -0
  215. package/dist/{chunk-3V7UJLQT.js → chunk-UQGQFBRL.js} +3 -3
  216. package/dist/chunk-UQGQFBRL.js.map +1 -0
  217. package/dist/{chunk-LS3LMQ23.js → chunk-VDEWG5TV.js} +88 -43
  218. package/dist/chunk-VDEWG5TV.js.map +1 -0
  219. package/dist/{chunk-6AZDM6LK.js → chunk-VF7EWVDG.js} +3 -3
  220. package/dist/{chunk-6AZDM6LK.js.map → chunk-VF7EWVDG.js.map} +1 -1
  221. package/dist/{chunk-PNVDQL5Y.cjs → chunk-VTYY7XL5.cjs} +2 -2
  222. package/dist/chunk-VTYY7XL5.cjs.map +1 -0
  223. package/dist/{chunk-Y4I4EQFK.js → chunk-WKRSH2VR.js} +3 -3
  224. package/dist/{chunk-Y4I4EQFK.js.map → chunk-WKRSH2VR.js.map} +1 -1
  225. package/dist/{chunk-4QEC4CCS.js → chunk-WTMU7J4U.js} +2 -2
  226. package/dist/{chunk-4QEC4CCS.js.map → chunk-WTMU7J4U.js.map} +1 -1
  227. package/dist/{chunk-KSWHTR54.js → chunk-XN7NOENA.js} +6 -6
  228. package/dist/chunk-XN7NOENA.js.map +1 -0
  229. package/dist/{chunk-ADLLFY3H.cjs → chunk-XSX2UU6Y.cjs} +10 -9
  230. package/dist/chunk-XSX2UU6Y.cjs.map +1 -0
  231. package/dist/{chunk-LD4MOBFX.js → chunk-XV4IZNV4.js} +9 -9
  232. package/dist/chunk-XV4IZNV4.js.map +1 -0
  233. package/dist/{chunk-EZ2YEF4F.cjs → chunk-XWL6O3SW.cjs} +4 -4
  234. package/dist/chunk-XWL6O3SW.cjs.map +1 -0
  235. package/dist/{chunk-PGP7IOJ2.js → chunk-YMA4S2WO.js} +4 -4
  236. package/dist/{chunk-PGP7IOJ2.js.map → chunk-YMA4S2WO.js.map} +1 -1
  237. package/dist/{chunk-OUOXM36O.cjs → chunk-YPJ5NH5N.cjs} +11 -11
  238. package/dist/chunk-YPJ5NH5N.cjs.map +1 -0
  239. package/dist/{chunk-YLQQX5W2.cjs → chunk-ZF2LDKQQ.cjs} +2 -2
  240. package/dist/chunk-ZF2LDKQQ.cjs.map +1 -0
  241. package/dist/{chunk-L5YO6PWL.cjs → chunk-ZNW6V4Y6.cjs} +2 -2
  242. package/dist/chunk-ZNW6V4Y6.cjs.map +1 -0
  243. package/dist/client/index.cjs.map +1 -1
  244. package/dist/client/index.js.map +1 -1
  245. package/dist/client/theokit-client.d.cts +36 -0
  246. package/dist/client/theokit-client.d.ts +36 -0
  247. package/dist/client/types.d.cts +30 -0
  248. package/dist/client/types.d.ts +30 -0
  249. package/dist/compact-session-K5LXTBPJ.js +22 -0
  250. package/dist/{compact-session-4MNKNMO2.js.map → compact-session-K5LXTBPJ.js.map} +1 -1
  251. package/dist/compact-session-YCT6JMBX.cjs +59 -0
  252. package/dist/{compact-session-EPFBQ46Z.cjs.map → compact-session-YCT6JMBX.cjs.map} +1 -1
  253. package/dist/compaction.cjs +17 -16
  254. package/dist/compaction.d.cts +13 -13
  255. package/dist/compaction.d.ts +13 -13
  256. package/dist/compaction.js +4 -3
  257. package/dist/concurrency.cjs +7 -6
  258. package/dist/concurrency.cjs.map +1 -1
  259. package/dist/concurrency.js +5 -4
  260. package/dist/concurrency.js.map +1 -1
  261. package/dist/context/index.cjs +7 -7
  262. package/dist/context/index.js +3 -3
  263. package/dist/context-FDOON2DB.js +6 -0
  264. package/dist/{context-ENXZNF6J.js.map → context-FDOON2DB.js.map} +1 -1
  265. package/dist/context-VMIE4BMD.cjs +23 -0
  266. package/dist/{context-7USNN6LP.cjs.map → context-VMIE4BMD.cjs.map} +1 -1
  267. package/dist/cron-CRwy2JBF.d.ts +240 -0
  268. package/dist/cron-DxxeQ-sK.d.cts +240 -0
  269. package/dist/cron.cjs +43 -41
  270. package/dist/cron.d.cts +5 -3
  271. package/dist/cron.d.ts +5 -3
  272. package/dist/cron.js +42 -40
  273. package/dist/define-tool.d.ts +14 -6
  274. package/dist/{errors-BSoXcl3F.d.cts → errors-BgJH9PHi.d.cts} +39 -24
  275. package/dist/{errors-CHllybaU.d.ts → errors-C5fJUqLk.d.ts} +39 -24
  276. package/dist/errors.cjs +22 -21
  277. package/dist/errors.d.cts +2 -2
  278. package/dist/errors.d.ts +2 -2
  279. package/dist/errors.js +3 -2
  280. package/dist/eval.cjs +61 -58
  281. package/dist/eval.cjs.map +1 -1
  282. package/dist/eval.d.cts +38 -0
  283. package/dist/eval.d.ts +38 -0
  284. package/dist/eval.js +51 -48
  285. package/dist/eval.js.map +1 -1
  286. package/dist/event-bus.d.ts +16 -0
  287. package/dist/{executor-2Z6XJJJG.js → executor-BMEHFOXZ.js} +8 -7
  288. package/dist/executor-BMEHFOXZ.js.map +1 -0
  289. package/dist/{executor-2Z3LGG3I.cjs → executor-ZERJ3DGN.cjs} +25 -24
  290. package/dist/executor-ZERJ3DGN.cjs.map +1 -0
  291. package/dist/filesystem/index.cjs +8 -7
  292. package/dist/filesystem/index.cjs.map +1 -1
  293. package/dist/filesystem/index.js +4 -3
  294. package/dist/filesystem/index.js.map +1 -1
  295. package/dist/filesystem/local-filesystem.d.cts +18 -0
  296. package/dist/filesystem/local-filesystem.d.ts +18 -0
  297. package/dist/filesystem/types.d.cts +12 -0
  298. package/dist/filesystem/types.d.ts +12 -0
  299. package/dist/fs-session-store-3MOJQGP2.cjs +20 -0
  300. package/dist/{fs-session-store-VVY2AHWG.cjs.map → fs-session-store-3MOJQGP2.cjs.map} +1 -1
  301. package/dist/fs-session-store-IN7JTTXD.js +11 -0
  302. package/dist/{fs-session-store-R5FD3EN6.js.map → fs-session-store-IN7JTTXD.js.map} +1 -1
  303. package/dist/generate-object-N5MDZUJI.js +8 -0
  304. package/dist/{generate-object-WQRCXFD2.js.map → generate-object-N5MDZUJI.js.map} +1 -1
  305. package/dist/generate-object-PGSP5U7N.cjs +21 -0
  306. package/dist/{generate-object-AVXOJK2I.cjs.map → generate-object-PGSP5U7N.cjs.map} +1 -1
  307. package/dist/generate-object.d.ts +20 -0
  308. package/dist/index-manager-NG5YENWO.cjs +22 -0
  309. package/dist/{index-manager-VRU3A2YL.cjs.map → index-manager-NG5YENWO.cjs.map} +1 -1
  310. package/dist/index-manager-ZMRJ6ZII.js +13 -0
  311. package/dist/{index-manager-WS7TVKUW.js.map → index-manager-ZMRJ6ZII.js.map} +1 -1
  312. package/dist/index.cjs +169 -155
  313. package/dist/index.cjs.map +1 -1
  314. package/dist/index.d.cts +702 -54
  315. package/dist/index.d.ts +702 -54
  316. package/dist/index.js +61 -58
  317. package/dist/index.js.map +1 -1
  318. package/dist/{inject-session-GMBMJVNZ.js → inject-session-DDR6X6PC.js} +9 -8
  319. package/dist/inject-session-DDR6X6PC.js.map +1 -0
  320. package/dist/inject-session-XLO3KTBM.cjs +29 -0
  321. package/dist/inject-session-XLO3KTBM.cjs.map +1 -0
  322. package/dist/internal/auth/auth-types.d.ts +83 -1
  323. package/dist/internal/auth/credential-store.d.ts +34 -6
  324. package/dist/internal/auth/oauth-device.d.ts +0 -1
  325. package/dist/internal/auth/resolve-credential.d.ts +40 -0
  326. package/dist/internal/budget/tracker/budget.d.ts +12 -14
  327. package/dist/internal/budget/usage-accumulator.d.ts +15 -0
  328. package/dist/internal/llm/anthropic-shared.d.ts +8 -4
  329. package/dist/internal/llm/model-identifier.d.ts +26 -0
  330. package/dist/internal/llm/openai.d.ts +8 -0
  331. package/dist/internal/llm/router.d.ts +8 -0
  332. package/dist/internal/llm/types.d.ts +12 -1
  333. package/dist/internal/local-agent/real-local-run-provider.d.ts +8 -3
  334. package/dist/internal/local-agent/real-local-run-tools.d.ts +8 -0
  335. package/dist/internal/mcp/oauth.d.ts +5 -0
  336. package/dist/internal/mcp/token-storage.d.ts +34 -0
  337. package/dist/internal/memory/adapters/index.cjs +12 -11
  338. package/dist/internal/memory/adapters/index.d.cts +3 -1
  339. package/dist/internal/memory/adapters/index.d.ts +3 -1
  340. package/dist/internal/memory/adapters/index.js +9 -8
  341. package/dist/internal/memory/adapters/openai-compatible.d.cts +45 -0
  342. package/dist/internal/memory/adapters/openai-compatible.d.ts +45 -0
  343. package/dist/internal/memory/embedding-cache.d.ts +42 -1
  344. package/dist/internal/memory/escape-like-pattern.d.ts +22 -0
  345. package/dist/internal/memory/sqlite-vec-loader.d.ts +1 -3
  346. package/dist/internal/memory/storage/markdown-store.d.ts +0 -5
  347. package/dist/internal/persistence/cwd-mutex.d.cts +34 -0
  348. package/dist/internal/persistence/cwd-mutex.d.ts +34 -0
  349. package/dist/internal/persistence/exclusive-create.d.cts +31 -0
  350. package/dist/internal/persistence/exclusive-create.d.ts +31 -0
  351. package/dist/internal/persistence/file-lock.d.cts +28 -0
  352. package/dist/internal/persistence/file-lock.d.ts +28 -0
  353. package/dist/internal/persistence/fs-session-store.d.cts +3 -0
  354. package/dist/internal/persistence/fs-session-store.d.ts +3 -0
  355. package/dist/internal/persistence/fts5-sanitize.d.cts +20 -0
  356. package/dist/internal/persistence/fts5-sanitize.d.ts +20 -0
  357. package/dist/internal/persistence/index.cjs +40 -39
  358. package/dist/internal/persistence/index.cjs.map +1 -1
  359. package/dist/internal/persistence/index.d.cts +6 -1
  360. package/dist/internal/persistence/index.d.ts +6 -1
  361. package/dist/internal/persistence/index.js +9 -8
  362. package/dist/internal/persistence/index.js.map +1 -1
  363. package/dist/internal/persistence/paths.d.cts +54 -1
  364. package/dist/internal/persistence/paths.d.ts +54 -1
  365. package/dist/internal/persistence/persistence-schema.d.cts +9 -1
  366. package/dist/internal/persistence/persistence-schema.d.ts +9 -1
  367. package/dist/internal/persistence/schema-version.d.cts +215 -1
  368. package/dist/internal/persistence/schema-version.d.ts +215 -1
  369. package/dist/internal/persistence/session-writer.d.cts +7 -7
  370. package/dist/internal/persistence/session-writer.d.ts +7 -7
  371. package/dist/internal/persistence/sqlite-cas.d.cts +37 -1
  372. package/dist/internal/persistence/sqlite-cas.d.ts +37 -1
  373. package/dist/internal/persistence/sqlite-open.d.cts +14 -0
  374. package/dist/internal/persistence/sqlite-open.d.ts +14 -0
  375. package/dist/internal/persistence/sqlite-wal.d.cts +45 -0
  376. package/dist/internal/persistence/sqlite-wal.d.ts +45 -0
  377. package/dist/internal/persistence/transcript-ops.d.cts +7 -1
  378. package/dist/internal/persistence/transcript-ops.d.ts +7 -1
  379. package/dist/internal/plugins/types.d.cts +1 -1
  380. package/dist/internal/plugins/types.d.ts +1 -1
  381. package/dist/internal/providers/builtin/openai-chatgpt.d.ts +12 -0
  382. package/dist/internal/providers/catalog-loader.d.ts +8 -0
  383. package/dist/internal/providers/catalog-schema.d.ts +55 -0
  384. package/dist/internal/providers/catalog-source-models-dev.d.ts +36 -0
  385. package/dist/internal/runtime/concurrency/delegation-depth.d.ts +27 -0
  386. package/dist/internal/runtime/concurrency/subagent-credentials.d.ts +33 -1
  387. package/dist/internal/runtime/context/context-discovery-runner.d.ts +44 -0
  388. package/dist/internal/runtime/context/context-discovery.d.ts +58 -0
  389. package/dist/internal/runtime/context/context-rules-frontmatter.d.ts +70 -1
  390. package/dist/internal/runtime/fixtures/fixture-mode.d.ts +15 -1
  391. package/dist/internal/runtime/lifecycle/post-run-lifecycle.d.ts +15 -0
  392. package/dist/internal/runtime/registry/agent-registry-store.d.ts +12 -0
  393. package/dist/internal/runtime/registry/live-agent-registry.d.ts +37 -0
  394. package/dist/internal/scorers/llm-judge.d.ts +6 -1
  395. package/dist/internal/security/index.cjs +14 -13
  396. package/dist/internal/security/index.d.cts +4 -1
  397. package/dist/internal/security/index.d.ts +4 -1
  398. package/dist/internal/security/index.js +4 -3
  399. package/dist/internal/security/path-guard.d.cts +46 -0
  400. package/dist/internal/security/path-guard.d.ts +46 -0
  401. package/dist/internal/security/redact.d.cts +71 -0
  402. package/dist/internal/security/redact.d.ts +71 -0
  403. package/dist/internal/session/agent-session.d.ts +15 -4
  404. package/dist/internal/session/session-cache.d.ts +5 -0
  405. package/dist/internal/task/store.d.ts +91 -5
  406. package/dist/internal/telemetry/span-names.d.ts +0 -1
  407. package/dist/internal/telemetry/tracer.d.ts +14 -0
  408. package/dist/job-queue.d.ts +18 -0
  409. package/dist/judge-call-DWHAJATE.js +6 -0
  410. package/dist/{judge-call-MDIPTBJI.js.map → judge-call-DWHAJATE.js.map} +1 -1
  411. package/dist/judge-call-EGYRC2RE.cjs +23 -0
  412. package/dist/{judge-call-G5SGV2M2.cjs.map → judge-call-EGYRC2RE.cjs.map} +1 -1
  413. package/dist/mcp-auth.cjs +41 -25
  414. package/dist/mcp-auth.cjs.map +1 -1
  415. package/dist/mcp-auth.js +34 -18
  416. package/dist/mcp-auth.js.map +1 -1
  417. package/dist/models.cjs +42 -27
  418. package/dist/models.cjs.map +1 -1
  419. package/dist/models.js +25 -10
  420. package/dist/models.js.map +1 -1
  421. package/dist/oauth-transaction-store-BT4GLTLK.cjs +36 -0
  422. package/dist/{oauth-transaction-store-7CKHPQRN.cjs.map → oauth-transaction-store-BT4GLTLK.cjs.map} +1 -1
  423. package/dist/oauth-transaction-store-W52KVHQ4.js +3 -0
  424. package/dist/{oauth-transaction-store-W74I6EFD.js.map → oauth-transaction-store-W52KVHQ4.js.map} +1 -1
  425. package/dist/path-safety.cjs +11 -10
  426. package/dist/path-safety.js +4 -3
  427. package/dist/permission-engine.d.ts +55 -0
  428. package/dist/persistence.cjs +43 -42
  429. package/dist/persistence.cjs.map +1 -1
  430. package/dist/persistence.js +13 -12
  431. package/dist/persistence.js.map +1 -1
  432. package/dist/project.cjs +9 -8
  433. package/dist/project.cjs.map +1 -1
  434. package/dist/project.js +5 -4
  435. package/dist/project.js.map +1 -1
  436. package/dist/providers.cjs +23 -0
  437. package/dist/providers.cjs.map +1 -0
  438. package/dist/providers.d.cts +29 -0
  439. package/dist/providers.d.ts +29 -0
  440. package/dist/providers.js +10 -0
  441. package/dist/providers.js.map +1 -0
  442. package/dist/registry-VFKX7WOP.cjs +47 -0
  443. package/dist/{registry-63ASMXT4.cjs.map → registry-VFKX7WOP.cjs.map} +1 -1
  444. package/dist/registry-VFP3WWQP.js +10 -0
  445. package/dist/{registry-O7FJ2MPM.js.map → registry-VFP3WWQP.js.map} +1 -1
  446. package/dist/retry.cjs +5 -4
  447. package/dist/retry.js +4 -3
  448. package/dist/{run-C8FBAC8o.d.cts → run-BYSHf58D.d.cts} +185 -33
  449. package/dist/{run-C8FBAC8o.d.ts → run-BYSHf58D.d.ts} +185 -33
  450. package/dist/{run-to-completion-JDPIUKSH.js → run-to-completion-DRO77625.js} +3 -3
  451. package/dist/{run-to-completion-JDPIUKSH.js.map → run-to-completion-DRO77625.js.map} +1 -1
  452. package/dist/{run-to-completion-J73I6IY4.cjs → run-to-completion-X4OWM673.cjs} +13 -13
  453. package/dist/{run-to-completion-J73I6IY4.cjs.map → run-to-completion-X4OWM673.cjs.map} +1 -1
  454. package/dist/sandbox/bwrap.d.cts +27 -13
  455. package/dist/sandbox/bwrap.d.ts +27 -13
  456. package/dist/sandbox/index.cjs +20 -19
  457. package/dist/sandbox/index.cjs.map +1 -1
  458. package/dist/sandbox/index.js +5 -4
  459. package/dist/sandbox/index.js.map +1 -1
  460. package/dist/sandbox/linux-sandbox.d.cts +72 -0
  461. package/dist/sandbox/linux-sandbox.d.ts +72 -0
  462. package/dist/sandbox/local-sandbox.d.cts +41 -0
  463. package/dist/sandbox/local-sandbox.d.ts +41 -0
  464. package/dist/sandbox/seccomp.d.cts +6 -0
  465. package/dist/sandbox/seccomp.d.ts +6 -0
  466. package/dist/sandbox/types.d.cts +64 -0
  467. package/dist/sandbox/types.d.ts +64 -0
  468. package/dist/scorers.d.ts +38 -7
  469. package/dist/sdk-agent-D8qJVkuV.d.ts +860 -0
  470. package/dist/sdk-agent-DEoKhA8a.d.cts +860 -0
  471. package/dist/server/auth/errors.d.cts +1 -1
  472. package/dist/server/auth/errors.d.ts +1 -1
  473. package/dist/server/auth/index.cjs +29 -21
  474. package/dist/server/auth/index.cjs.map +1 -1
  475. package/dist/server/auth/index.d.cts +25 -15
  476. package/dist/server/auth/index.d.ts +25 -15
  477. package/dist/server/auth/index.js +15 -7
  478. package/dist/server/auth/index.js.map +1 -1
  479. package/dist/server/auth/oauth-transaction-store.d.cts +13 -1
  480. package/dist/server/auth/oauth-transaction-store.d.ts +13 -1
  481. package/dist/server/auth/orchestrator.d.cts +1 -1
  482. package/dist/server/auth/orchestrator.d.ts +1 -1
  483. package/dist/server/auth/types.d.cts +1 -1
  484. package/dist/server/auth/types.d.ts +1 -1
  485. package/dist/server/auth/validate-return-to.d.cts +21 -11
  486. package/dist/server/auth/validate-return-to.d.ts +21 -11
  487. package/dist/server/errors-envelope.cjs +15 -14
  488. package/dist/server/errors-envelope.cjs.map +1 -1
  489. package/dist/server/errors-envelope.d.cts +4 -4
  490. package/dist/server/errors-envelope.d.ts +4 -4
  491. package/dist/server/errors-envelope.js +4 -3
  492. package/dist/server/errors-envelope.js.map +1 -1
  493. package/dist/session-transcript-AKDYYGXQ.js +6 -0
  494. package/dist/{session-transcript-RAKEK76V.js.map → session-transcript-AKDYYGXQ.js.map} +1 -1
  495. package/dist/session-transcript-JXHFTB7G.cjs +51 -0
  496. package/dist/{session-transcript-DOM3UTXR.cjs.map → session-transcript-JXHFTB7G.cjs.map} +1 -1
  497. package/dist/skills.cjs +8 -7
  498. package/dist/skills.js +6 -5
  499. package/dist/stream-object-BUCF5PHO.cjs +21 -0
  500. package/dist/{stream-object-L3Q7PBMF.cjs.map → stream-object-BUCF5PHO.cjs.map} +1 -1
  501. package/dist/stream-object-L57K4OFS.js +8 -0
  502. package/dist/{stream-object-ZYXWS4B2.js.map → stream-object-L57K4OFS.js.map} +1 -1
  503. package/dist/{stream-to-completion-DFJ5T3BK.js → stream-to-completion-QV5HCL3J.js} +3 -3
  504. package/dist/{stream-to-completion-DFJ5T3BK.js.map → stream-to-completion-QV5HCL3J.js.map} +1 -1
  505. package/dist/{stream-to-completion-H2MHISSK.cjs → stream-to-completion-SRISU5AB.cjs} +10 -10
  506. package/dist/{stream-to-completion-H2MHISSK.cjs.map → stream-to-completion-SRISU5AB.cjs.map} +1 -1
  507. package/dist/subagents-loader-AZIXJ7D3.cjs +16 -0
  508. package/dist/{subagents-loader-VRW73QQT.cjs.map → subagents-loader-AZIXJ7D3.cjs.map} +1 -1
  509. package/dist/subagents-loader-J54ESLDV.js +7 -0
  510. package/dist/{subagents-loader-I56GSKAQ.js.map → subagents-loader-J54ESLDV.js.map} +1 -1
  511. package/dist/subagents-loader.cjs +7 -6
  512. package/dist/subagents-loader.cjs.map +1 -1
  513. package/dist/subagents-loader.d.cts +3 -2
  514. package/dist/subagents-loader.d.ts +3 -2
  515. package/dist/subagents-loader.js +5 -4
  516. package/dist/subagents-loader.js.map +1 -1
  517. package/dist/subscription/define-subscription.d.cts +1 -1
  518. package/dist/subscription/define-subscription.d.ts +1 -1
  519. package/dist/subscription/index.cjs +22 -9
  520. package/dist/subscription/index.cjs.map +1 -1
  521. package/dist/subscription/index.d.cts +1 -1
  522. package/dist/subscription/index.d.ts +1 -1
  523. package/dist/subscription/index.js +21 -8
  524. package/dist/subscription/index.js.map +1 -1
  525. package/dist/subscription/internal/adapter-types.d.cts +1 -1
  526. package/dist/subscription/internal/adapter-types.d.ts +1 -1
  527. package/dist/subscription/internal/server-integration.d.cts +1 -1
  528. package/dist/subscription/internal/server-integration.d.ts +1 -1
  529. package/dist/subscription/internal/sse-encoder.d.cts +1 -1
  530. package/dist/subscription/internal/sse-encoder.d.ts +1 -1
  531. package/dist/subscription/internal/sse-parser.d.cts +1 -1
  532. package/dist/subscription/internal/sse-parser.d.ts +1 -1
  533. package/dist/subscription/internal/subscription-runtime.d.cts +1 -1
  534. package/dist/subscription/internal/subscription-runtime.d.ts +1 -1
  535. package/dist/subscription/internal/ws-adapter-node.d.cts +1 -1
  536. package/dist/subscription/internal/ws-adapter-node.d.ts +1 -1
  537. package/dist/subscription/theokit-subscribe.d.cts +14 -1
  538. package/dist/subscription/theokit-subscribe.d.ts +14 -1
  539. package/dist/subscription/types.d.cts +19 -1
  540. package/dist/subscription/types.d.ts +19 -1
  541. package/dist/task-store.cjs +8 -7
  542. package/dist/task-store.js +5 -4
  543. package/dist/types/agent-prims.d.ts +14 -0
  544. package/dist/types/agent.d.ts +50 -11
  545. package/dist/types/batch.d.ts +7 -1
  546. package/dist/types/conversation.d.ts +18 -5
  547. package/dist/types/goal-events.d.ts +4 -8
  548. package/dist/types/memory-adapter.d.ts +12 -1
  549. package/dist/types/plugin.d.ts +101 -0
  550. package/dist/types/provider-profile.d.ts +19 -0
  551. package/dist/types/run-events.d.ts +28 -1
  552. package/dist/types/run.d.ts +35 -23
  553. package/dist/types/sdk-agent.d.ts +14 -0
  554. package/dist/types/session-record.d.ts +18 -1
  555. package/dist/types/task.d.ts +15 -1
  556. package/dist/types/theokit.d.ts +10 -1
  557. package/dist/types/updates.d.ts +35 -4
  558. package/dist/types/workflow.d.ts +155 -0
  559. package/dist/workflow.cjs +29 -28
  560. package/dist/workflow.d.cts +666 -17
  561. package/dist/workflow.d.ts +666 -17
  562. package/dist/workflow.js +8 -7
  563. package/docs/error-codes.md +215 -0
  564. package/docs/harness-capability-map.md +1357 -0
  565. package/package.json +29 -16
  566. package/bin/init-claude.mjs +0 -68
  567. package/claude-template/AGENTS.md +0 -157
  568. package/claude-template/CLAUDE.md +0 -66
  569. package/claude-template/dot-claude/rules/theokit-conventions.md +0 -32
  570. package/claude-template/dot-claude/settings.json +0 -16
  571. package/claude-template/dot-claude/skills/theokit-agent-core/SKILL.md +0 -209
  572. package/claude-template/dot-claude/skills/theokit-auth/SKILL.md +0 -102
  573. package/claude-template/dot-claude/skills/theokit-budget/SKILL.md +0 -176
  574. package/claude-template/dot-claude/skills/theokit-client/SKILL.md +0 -58
  575. package/claude-template/dot-claude/skills/theokit-compaction/SKILL.md +0 -102
  576. package/claude-template/dot-claude/skills/theokit-concurrency/SKILL.md +0 -68
  577. package/claude-template/dot-claude/skills/theokit-config/SKILL.md +0 -139
  578. package/claude-template/dot-claude/skills/theokit-cron/SKILL.md +0 -148
  579. package/claude-template/dot-claude/skills/theokit-di/SKILL.md +0 -233
  580. package/claude-template/dot-claude/skills/theokit-di-agent/SKILL.md +0 -294
  581. package/claude-template/dot-claude/skills/theokit-errors/SKILL.md +0 -172
  582. package/claude-template/dot-claude/skills/theokit-eval/SKILL.md +0 -179
  583. package/claude-template/dot-claude/skills/theokit-filesystem/SKILL.md +0 -74
  584. package/claude-template/dot-claude/skills/theokit-gateways/SKILL.md +0 -209
  585. package/claude-template/dot-claude/skills/theokit-memory/SKILL.md +0 -176
  586. package/claude-template/dot-claude/skills/theokit-messages/SKILL.md +0 -58
  587. package/claude-template/dot-claude/skills/theokit-models/SKILL.md +0 -79
  588. package/claude-template/dot-claude/skills/theokit-path-safety/SKILL.md +0 -60
  589. package/claude-template/dot-claude/skills/theokit-persistence/SKILL.md +0 -85
  590. package/claude-template/dot-claude/skills/theokit-project/SKILL.md +0 -55
  591. package/claude-template/dot-claude/skills/theokit-retry/SKILL.md +0 -50
  592. package/claude-template/dot-claude/skills/theokit-sandbox/SKILL.md +0 -93
  593. package/claude-template/dot-claude/skills/theokit-sanitize/SKILL.md +0 -66
  594. package/claude-template/dot-claude/skills/theokit-skills/SKILL.md +0 -68
  595. package/claude-template/dot-claude/skills/theokit-streaming/SKILL.md +0 -156
  596. package/claude-template/dot-claude/skills/theokit-subagents/SKILL.md +0 -109
  597. package/claude-template/dot-claude/skills/theokit-subscriptions/SKILL.md +0 -148
  598. package/claude-template/dot-claude/skills/theokit-task-store/SKILL.md +0 -75
  599. package/claude-template/dot-claude/skills/theokit-tools/SKILL.md +0 -170
  600. package/claude-template/dot-claude/skills/theokit-workflows/SKILL.md +0 -218
  601. package/dist/agent-FFVV4U5N.js +0 -50
  602. package/dist/agent-YLAHVHEH.cjs +0 -59
  603. package/dist/agent-session-store-DUGBAX5V.cjs +0 -23
  604. package/dist/agent-session-store-TNCGL5RN.js +0 -6
  605. package/dist/batch-UPKN4SG6.js.map +0 -1
  606. package/dist/batch-ZEFN5SO7.cjs.map +0 -1
  607. package/dist/chunk-2D43RD5D.cjs.map +0 -1
  608. package/dist/chunk-2FYEVT2B.cjs.map +0 -1
  609. package/dist/chunk-2RW7K6FN.cjs.map +0 -1
  610. package/dist/chunk-2XLKLVVR.js.map +0 -1
  611. package/dist/chunk-34XOCZJO.js.map +0 -1
  612. package/dist/chunk-3V7UJLQT.js.map +0 -1
  613. package/dist/chunk-4NAKHID5.js.map +0 -1
  614. package/dist/chunk-4Q4K4WB5.js.map +0 -1
  615. package/dist/chunk-5F5NWKPN.js.map +0 -1
  616. package/dist/chunk-5NBUH3NO.js.map +0 -1
  617. package/dist/chunk-5YKNEMXR.cjs.map +0 -1
  618. package/dist/chunk-7W7ZWMLQ.js.map +0 -1
  619. package/dist/chunk-ADLLFY3H.cjs.map +0 -1
  620. package/dist/chunk-B4YA6BRS.cjs.map +0 -1
  621. package/dist/chunk-B6HOIWQ6.js.map +0 -1
  622. package/dist/chunk-BDTVFIPB.cjs.map +0 -1
  623. package/dist/chunk-BFYGJGC5.js.map +0 -1
  624. package/dist/chunk-BM6N4KHO.cjs.map +0 -1
  625. package/dist/chunk-CAH3G4IS.js.map +0 -1
  626. package/dist/chunk-EZ2YEF4F.cjs.map +0 -1
  627. package/dist/chunk-F77UENR6.cjs.map +0 -1
  628. package/dist/chunk-FOXKFTVZ.cjs.map +0 -1
  629. package/dist/chunk-G3JWXOGY.js.map +0 -1
  630. package/dist/chunk-GOVJO4YE.js.map +0 -1
  631. package/dist/chunk-HAWE74GQ.cjs.map +0 -1
  632. package/dist/chunk-HE4BIAOS.js.map +0 -1
  633. package/dist/chunk-HSQ5Q3I5.js.map +0 -1
  634. package/dist/chunk-JIQRXKTA.cjs.map +0 -1
  635. package/dist/chunk-KSWHTR54.js.map +0 -1
  636. package/dist/chunk-L5YO6PWL.cjs.map +0 -1
  637. package/dist/chunk-LD4MOBFX.js.map +0 -1
  638. package/dist/chunk-LS3LMQ23.js.map +0 -1
  639. package/dist/chunk-MSFLYJDY.js.map +0 -1
  640. package/dist/chunk-NZL4BNFQ.js.map +0 -1
  641. package/dist/chunk-OKLYRPKL.cjs.map +0 -1
  642. package/dist/chunk-OUOXM36O.cjs.map +0 -1
  643. package/dist/chunk-OXNYIMZZ.js.map +0 -1
  644. package/dist/chunk-PBZ7HMBP.js.map +0 -1
  645. package/dist/chunk-PNVDQL5Y.cjs.map +0 -1
  646. package/dist/chunk-Q4RESANI.cjs.map +0 -1
  647. package/dist/chunk-QBTVATSF.cjs.map +0 -1
  648. package/dist/chunk-RAHSWE5C.cjs.map +0 -1
  649. package/dist/chunk-RP5HQVLD.js.map +0 -1
  650. package/dist/chunk-SEL2ZQMT.js.map +0 -1
  651. package/dist/chunk-SK4QLUBK.js.map +0 -1
  652. package/dist/chunk-TTJ54H3E.cjs.map +0 -1
  653. package/dist/chunk-V26QVGUG.js.map +0 -1
  654. package/dist/chunk-V6HWJQQV.js.map +0 -1
  655. package/dist/chunk-VGPXHHF3.cjs.map +0 -1
  656. package/dist/chunk-VUKQL3L2.cjs.map +0 -1
  657. package/dist/chunk-VYCKUKPA.cjs.map +0 -1
  658. package/dist/chunk-VYHJZVL5.cjs.map +0 -1
  659. package/dist/chunk-X2FR4OIT.js.map +0 -1
  660. package/dist/chunk-XPR366DL.cjs.map +0 -1
  661. package/dist/chunk-XROIW6BH.js.map +0 -1
  662. package/dist/chunk-YLQQX5W2.cjs.map +0 -1
  663. package/dist/chunk-ZT57WTUJ.cjs.map +0 -1
  664. package/dist/compact-session-4MNKNMO2.js +0 -21
  665. package/dist/compact-session-EPFBQ46Z.cjs +0 -58
  666. package/dist/context-7USNN6LP.cjs +0 -22
  667. package/dist/context-ENXZNF6J.js +0 -5
  668. package/dist/cron-BMjgFH-_.d.ts +0 -631
  669. package/dist/cron-DFDdCdMM.d.cts +0 -631
  670. package/dist/executor-2Z3LGG3I.cjs.map +0 -1
  671. package/dist/executor-2Z6XJJJG.js.map +0 -1
  672. package/dist/fs-session-store-R5FD3EN6.js +0 -10
  673. package/dist/fs-session-store-VVY2AHWG.cjs +0 -19
  674. package/dist/generate-object-AVXOJK2I.cjs +0 -20
  675. package/dist/generate-object-WQRCXFD2.js +0 -7
  676. package/dist/index-manager-VRU3A2YL.cjs +0 -21
  677. package/dist/index-manager-WS7TVKUW.js +0 -12
  678. package/dist/inject-session-AUQLBDRS.cjs +0 -28
  679. package/dist/inject-session-AUQLBDRS.cjs.map +0 -1
  680. package/dist/inject-session-GMBMJVNZ.js.map +0 -1
  681. package/dist/judge-call-G5SGV2M2.cjs +0 -22
  682. package/dist/judge-call-MDIPTBJI.js +0 -5
  683. package/dist/oauth-transaction-store-7CKHPQRN.cjs +0 -32
  684. package/dist/oauth-transaction-store-W74I6EFD.js +0 -3
  685. package/dist/registry-63ASMXT4.cjs +0 -46
  686. package/dist/registry-O7FJ2MPM.js +0 -9
  687. package/dist/session-transcript-DOM3UTXR.cjs +0 -50
  688. package/dist/session-transcript-RAKEK76V.js +0 -5
  689. package/dist/stream-object-L3Q7PBMF.cjs +0 -20
  690. package/dist/stream-object-ZYXWS4B2.js +0 -7
  691. package/dist/subagents-loader-I56GSKAQ.js +0 -6
  692. package/dist/subagents-loader-VRW73QQT.cjs +0 -15
package/CHANGELOG.md CHANGED
@@ -1,5 +1,1093 @@
1
1
  # Changelog
2
2
 
3
+ ## 4.54.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 0258f3c: Two `theokit` flags that were advertised in `--help` and read by nothing now behave.
8
+
9
+ `tasks cancel --reason <r>` records the reason: `TaskHandle` gains a `cancelReason` field, written
10
+ alongside `cancelledAt` for a queued task and alongside `cancelRequested` for a running one. A task
11
+ that is already terminal is left untouched, reason or not.
12
+
13
+ **Breaking:** `theokit init --here` is removed. It never scaffolded into the current directory, and
14
+ the writer cannot honour it — the tree is built in a temp directory and moved into place with `rm` +
15
+ `rename`, so a destination equal to `cwd` would mean deleting the directory the process is running
16
+ in. An unknown-option error is immediate and clear where silence was not.
17
+
18
+ - d485b4e: Fix three unresolved type references in the published declaration file (#335).
19
+
20
+ `MemoryProviderFactory` is now exported from the package root. It is the shape a
21
+ consumer must satisfy to write a memory plugin — the public `Plugin` union names
22
+ it in the `createProvider` position — but it carried the internal-visibility
23
+ JSDoc tag, so `stripInternal` deleted the declaration while the union went on
24
+ referencing it. The shipped `.d.ts` named a type it did not declare.
25
+
26
+ `AgentBuilderDeps` and the blast-radius symbol used as a computed key in
27
+ `WithBlastRadius<T>` had the same defect on other surfaces and are now emitted.
28
+ Neither is added to the public API — they only needed to exist in the declaration
29
+ file that references them.
30
+
31
+ None of this is visible under `skipLibCheck`, which is why it shipped. Consumers
32
+ running type-aware lint saw every type reached through those references degrade
33
+ to `error`, producing `no-unsafe-*` reports on correct SDK calls.
34
+
35
+ - 181967f: New `RunEvent` member: `mcp_server_ready`, carrying the server name and the tool names it listed.
36
+
37
+ `mcp_server_failed` already reached consumers, so a broken MCP server was visible. A server that came
38
+ up was not — the resolved tool table never leaves the agent loop's internals, and no event carried an
39
+ inventory. A consumer could list what was configured and what broke, and could not tell a server that
40
+ came up with twelve tools from one that came up with none.
41
+
42
+ Emitted from the same function as its failure sibling, on the other branch. An event rather than a
43
+ getter because the state is scoped to the run: with `mcpLifecycle: "run"` a server may not exist by
44
+ the time anyone asks. Tool names are the server's own, not the sanitized `mcp_<server>_<tool>` form
45
+ the model sees.
46
+
47
+ Requested by `usetheokit/theokit#426`.
48
+
49
+ - f33b52b: `MemoryAdapter.isAvailable()` now disables an adapter that returns `false`, as its mandatory
50
+ presence always implied.
51
+
52
+ Nothing called it. Every third-party adapter implements it as "is there a non-empty apiKey", so an
53
+ implementer reasonably read `false` as "disable me" — and it disabled nothing: the client is built
54
+ lazily, so `mem0Memory({ apiKey: "" })` started normally and surfaced mid-conversation as
55
+ `auth_failed`, at the point where a memory write is happening rather than where the operator could
56
+ still fix it.
57
+
58
+ An unavailable adapter is now skipped with a diagnostic naming it, so a missing key degrades to
59
+ no-memory and a multi-adapter setup falls back to the ones that work. When every registered adapter
60
+ declines, `write` and `recall` fail with a message saying exactly that — distinct from the message
61
+ for no adapter registered at all.
62
+
63
+ - 398e7a0: `ModelSelection.url` — a model can name the endpoint it should reach.
64
+
65
+ The base URL came only from a process-wide env var (`OLLAMA_HOST`, `OPENAI_API_BASE_URL`) or the
66
+ provider profile's shipped default, so every `ollama/*` model in a process shared one host. An app
67
+ could not run a small model on localhost and a large one on a GPU box, and could not talk to two
68
+ OpenAI-compatible servers at once. The information had nowhere to travel: `ProviderRouterOptions`
69
+ carried no URL field at all (usetheokit/theokit-sdk#332).
70
+
71
+ ```ts
72
+ model: { id: "ollama/llama3.3:70b", url: "http://gpu-box:11434" }
73
+ ```
74
+
75
+ Precedence is `ModelSelection.url` → the provider's base-URL env var → `profile.baseUrl`. The model
76
+ outranks the env var deliberately: with the env var winning, whoever set it for one model would keep
77
+ hijacking every other one, which is the same bug wearing a hat.
78
+
79
+ Leaving `url` unset changes nothing — `ollama/qwen2.5:3b` still resolves to `http://localhost:11434`
80
+ from the profile, with no key and no setup.
81
+
82
+ Applied to both transports separately, because they do not share the override: `OllamaNativeClient`
83
+ (the native `/api/chat` path Ollama tool calling requires) and the OpenAI-compatible client, which
84
+ covers `lmstudio` and `llamacpp`. The tests assert the URL the stubbed `fetch` actually received
85
+ rather than the options object handed to the client — an options-level assertion passes with the
86
+ precedence inverted.
87
+
88
+ - 8d1feaa: `PostAssistantReplyContext` now carries `usedTools`, and `@theokit/sdk-cache` stops caching
89
+ tool-using turns in plugin mode.
90
+
91
+ The cache's D266/EC-10 guard exists because replaying an answer produced by a `write_file` / HTTP
92
+ POST / payment call re-serves the text without the side effect having happened. The
93
+ `post_assistant_reply` hook had no tool signal to key on and passed a literal `false`, so the guard
94
+ never fired on the path that runs automatically — only a hand-written `cache.remember(..., {
95
+ usedTools: true })` reached it.
96
+
97
+ The runtime derives the flag from the run's replayed event stream. A hook handler written against
98
+ the previous shape keeps working; code that CONSTRUCTS a `PostAssistantReplyContext` (test doubles,
99
+ custom emitters) now has to supply the field.
100
+
101
+ - 9a27a72: Exposes the provider registry: `listProviders()` and `getProviderProfile(name)`.
102
+
103
+ The registry was `@internal`, so the SDK was the only thing that could answer "which providers
104
+ exist, and what does each one need?". `theokit` consequently kept its own hand-written list of
105
+ three — against the 46 registered here — and an agent declaring `ollama/qwen2.5:3b` routed to
106
+ whichever API key happened to be set rather than to Ollama (usetheokit/theokit#326).
107
+
108
+ A second table that nothing forces to agree with the first is not a cache, it is a future bug.
109
+ These two functions exist so there is one table, and the framework can stop guessing.
110
+
111
+ Both register the builtins before answering. Registration is lazy — it happens when an agent is
112
+ created, a run is routed, or a provider is defined — so a caller asking early would otherwise get
113
+ an empty registry and reasonably conclude the SDK knows nothing. Local providers (`ollama`,
114
+ `lmstudio`, `llamacpp`) come back with `authType: "none"`, which is what lets a consumer tell "no
115
+ credential needed" apart from "credential missing" without hardcoding names.
116
+
117
+ - f692988: The reference docs no longer ship inside the package. `node_modules/@theokit/sdk/docs/` is gone, along with the `harness-capability-map.md` and `error-codes.md` files it carried — the `docs` entry was removed from the published `files` list and the build step that generated it was removed with it.
118
+
119
+ The exported TypeScript types are now the only reference surface, and they remain the canonical contract: every public primitive carries its import path, signature and JSDoc example, surfaced by your editor. Nothing about the runtime API changed.
120
+
121
+ The scaffolded agent context still ships, unchanged, under `claude-template/`.
122
+
123
+ - 4556488: **`local.sessionDir` replaces `local.baseDir`** (#301). "Base directory" read as the directory the agent works in, in an interface whose `cwd` is the option that actually means that — so `baseDir: "./"` ran without error and wrote session transcripts into the caller's repository root. `baseDir` still works and still resolves to the same place; it emits a deprecation diagnostic, and `sessionDir` wins if both are set.
124
+
125
+ **`isValidTaskId` and `TASK_RESERVED_PREFIXES` now exist at runtime** (#279). The bundled `.d.ts` had declared both as values since 4.51.1 while `dist/index.js` exported neither, so `import { isValidTaskId } from "@theokit/sdk"` typechecked clean and threw at the call site.
126
+
127
+ **Thirteen `@theokit/sdk/persistence`, `@theokit/sdk/path-safety` and `@theokit/sdk/mcp-auth` symbols now arrive typed** (#280). Those re-exports resolved to no declaration at all, because each symbol carried `@internal` and `stripInternal` deletes it — while the public barrel went on naming it. They imported and ran, untyped: `atomicWriteText` in particular hid that it is `async`, so a caller could skip the `await` and watch a write report success before the bytes landed.
128
+
129
+ **`OTelSpan` and `TelemetryHandle` are exported** from the root entry. Types only; nothing is added to the bundle.
130
+
131
+ - 566615c: BREAKING: `npx theokit-init-claude` and the bundled `claude-template/` are gone. The
132
+ agent skills they scaffolded now live in [`@theokit/skills`](https://www.npmjs.com/package/@theokit/skills):
133
+
134
+ ```bash
135
+ npx @theokit/skills
136
+ ```
137
+
138
+ The thirty per-module skills were authored here and copied into that package by a sync
139
+ script, so they existed twice and the copy was the worse of the two — the script
140
+ stripped YAML frontmatter, and the frontmatter is where the `paths:` globs live that
141
+ make a skill load only when you are editing something it covers. They are authored
142
+ there now, with the globs intact.
143
+
144
+ Three things a consumer gets that the old scaffold did not offer. It installs for
145
+ every tool rather than Claude Code alone: `.agents/skills/` is read by OpenAI Codex,
146
+ Gemini CLI, GitHub Copilot, Zed and Devin Desktop, and `.claude/skills/` by Claude
147
+ Code. It links instead of copying when it is a real dependency, so the skills follow
148
+ your lockfile rather than freezing at scaffold time. And `--check` fails in CI when
149
+ what is installed has drifted, which is the only thing that stops an instruction file
150
+ from quietly going stale — a stale one is followed exactly as diligently as a current
151
+ one.
152
+
153
+ The SDK tarball drops 328 KB. Nothing in `dist/` referenced the template; it was
154
+ scaffold material, never runtime.
155
+
156
+ - 4397a90: `Theokit.subscribe` accepts an injected `fetch` and `WebSocket`.
157
+
158
+ Both were read off `globalThis` at call time, so the only way to exercise the SSE or WebSocket path —
159
+ in our own tests or in a consumer's — was to replace a global for the duration of the call. That is a
160
+ process-wide mutation to test one function, and it makes the transports untestable in any environment
161
+ where patching globals is not acceptable: a worker, a sandbox, an embedded runtime, or a suite running
162
+ files in parallel.
163
+
164
+ `SubscribeOptions` now takes optional `fetch` and `WebSocket`, each falling back to the global when
165
+ absent, so existing callers are unaffected. The SSE path, the WebSocket path and the automatic
166
+ transport selection all resolve through the same seam.
167
+
168
+ One case still requires replacing the global rather than injecting: asserting the error a caller gets
169
+ when no `WebSocket` exists at all. Node 22 ships a real global `WebSocket`, and a fallback cannot
170
+ express absence — only removal can. That single test says so where it stands.
171
+
172
+ - 7c7b21a: `theokit init` gains four templates — `chatbot`, `multi-agent`, `rag-agent` and
173
+ `workflow-automation` — and its `telegram-bot` template now installs and
174
+ compiles. It imported `createAgentFactory`, which the SE36 rename replaced with
175
+ `AgentFactory.create`, and pinned `@theokit/gateway` to the SDK's own version, so
176
+ a scaffolded project failed at `pnpm install` before any code ran.
177
+
178
+ `@theokit/cli` exports the `eval.config.ts` contract its README tells you to use:
179
+ `EvalConfig`, `DatasetEntry`, `Scorer` and `Score`.
180
+
181
+ `@theokit/sdk` exports `Workflow`, `fn` and `agentStep` from the package root.
182
+ `CronCreateOptions.workflow` types against the copy in the cron chunk, while the
183
+ `./workflow` subpath emits its own declaration of the same class — so a workflow
184
+ built the documented way was rejected by `Cron.create` on a private-field
185
+ mismatch. Importing both from the root now gives one identity.
186
+
187
+ ### Patch Changes
188
+
189
+ - 1cb6607: Adding a published sub-entry to the SDK now fails fast and names every file still missing, and the
190
+ ACP smoke test actually sends the request its name promises.
191
+
192
+ Thirty-four sub-entries are published, and adding one required editing four files that nothing forced
193
+ to agree: the package's `exports`, the bundler's entry list, the declaration-build include, and the
194
+ declaration-mirroring script's target list. Only the first omission failed quickly. Skipping the last
195
+ two broke nothing visible — output was emitted, typechecking passed, the whole suite passed — and the
196
+ only gate that noticed ran at pre-push, about ten minutes in, where the error surfaces on whoever
197
+ pushes next rather than on whoever caused it. A consistency check now derives the expected set from
198
+ `exports`, the file that decides what is actually published, and reports every place that disagrees.
199
+ It runs at the front of the validation chain, not at the end of it.
200
+
201
+ Separately, the ACP smoke test was named for initializing a session, prompting, cancelling and
202
+ shutting down, and its docblock promised a response with a stop reason. It never sent a prompt. Two
203
+ defects in one: a name that tells the reader a path is covered, and a real gap on the protocol's main
204
+ path. It now sends the request over the wire and asserts the stop reason it gets back — verified by
205
+ mutating the handler to return a different reason and watching the test fail.
206
+
207
+ - 034da4d: A model id could stall the process for minutes. The Anthropic price lookup normalised dots with
208
+ `/(\d+)\.(\d+)/g`, which on a long run of digits containing no dot consumes to the end of the
209
+ string at every start position and backtracks — quadratic in a value the caller supplies.
210
+
211
+ Measured: 12,500 digits took 762 ms; 25,000 took 3 seconds; 200,000 took **154 seconds** with one
212
+ CPU pinned. For an SDK built to run inside a server handling other people's requests, that is a
213
+ denial of service reachable from a single field.
214
+
215
+ The same input now takes about 4 milliseconds. The pattern matches one dot between two digits
216
+ using lookarounds, so there is nothing for the engine to backtrack over.
217
+
218
+ One behaviour difference, and it is checked rather than assumed: a model id with two dots between
219
+ digits (`1.2.3`) normalised to `1-2.3` before and `1-2-3` now, because the old pattern swallowed
220
+ the middle digit into its first match. No id in the provider catalog has two — measured across all
221
+ 34, of which 14 have exactly one.
222
+
223
+ Separately, reading a transcript's tail called `statSync(path)` and then `openSync(path)`, and the
224
+ size from the first call drove every read offset against the descriptor from the second. It now
225
+ sizes the descriptor it reads.
226
+
227
+ - 803e3ef: `MessageBus.send` discarded the handler's promise. `MessageHandler` may return one and `request`
228
+ awaits it; only `send` dropped it, so a rejecting handler became an unhandled rejection — fatal
229
+ under Node's default `--unhandled-rejections=throw` — while `await bus.send(...)` resolved cleanly
230
+ and the sender learned nothing.
231
+
232
+ Fire-and-forget means the sender does not wait for the result. It does not mean nobody is told when
233
+ delivery fails. The rejection is now caught and reported, naming the target agent and the reason,
234
+ and `send` stays non-blocking.
235
+
236
+ `AgentMailbox.send` forwards into this path and is fixed with it.
237
+
238
+ - ce6a591: Fix `ReferenceError: process is not defined` in the browser, which blanked every page of any app built on `theokit@0.48.x` (usetheokit/theokit#317).
239
+
240
+ `errors.ts` is imported by the client bindings framework consumers ship to the front end, and it pulls in the redaction and retry modules with it. Two of them read a bare `process.env` — one at module scope, in `internal/security/redact.ts` — so the read threw while the module graph was still evaluating, before a single component rendered. The page went blank with one console error naming no cause.
241
+
242
+ Environment reads on that path now go through `readEnv()`, which resolves `globalThis.process?.env?.[name]`: unchanged on the server, `undefined` in a browser, and still replaced at build time by bundlers that inline `process.env.X`. Redaction stays **enabled** when the flag cannot be read, since unreadable must mean unset rather than disabled.
243
+
244
+ `diagFailure` no longer relies on a `try/catch` swallowing the same ReferenceError to reach its fallback.
245
+
246
+ `tests/security/browser-safe-env.test.ts` walks the import graph reachable from `errors.ts` and fails on any bare `process` in it — a stronger guard than the two modules that happened to break this time.
247
+
248
+ - aea04f4: Fifteen tests that quietly reported success on machines missing a native dependency now report as
249
+ skipped.
250
+
251
+ Each was shaped `if (!(await probe())) return;` as the first line of the test body. A guard written
252
+ that way returns before any assertion runs, and the runner counts the case as passed — so a machine
253
+ without `better-sqlite3`, without the vector stack, or running as root was indistinguishable from one
254
+ where every assertion held. The skip was invisible in the count, which is the only place anyone would
255
+ have looked.
256
+
257
+ Measured on the same six guards in one package, forced on:
258
+
259
+ ```
260
+ old shape 31 passed, 0 skipped
261
+ new shape 25 passed, 6 skipped
262
+ ```
263
+
264
+ Across all three packages the conversion moves fifteen cases from a silent pass to a reported skip.
265
+
266
+ A full triage of every occurrence of this shape was done before changing anything, because the shape
267
+ alone does not identify the defect. Of thirty-three occurrences, fifteen were silent skips; the other
268
+ eighteen are legitimate and untouched — seven are type narrowings placed immediately after an
269
+ assertion that has already reported the failure, and eleven are ordinary control flow inside
270
+ callbacks, loops and handlers.
271
+
272
+ - 1471fd7: The `tests/chaos` and `tests/load` families no longer report resilience coverage they do not have.
273
+
274
+ Every file in both directories exercised `node:fs`, `node:http` and `node:child_process` without
275
+ importing a single line of SDK source, and two of their assertions could not fail at all:
276
+ `result.code !== undefined || result.signal !== null` is always true when `code` is `number | null`,
277
+ and `typeof process.uptime === "function"` cannot be false in a process alive enough to run the
278
+ assertion. The directory names promised that OOM, SIGKILL-mid-stream, filesystem partition and
279
+ generator leaks were covered against the product. They were not.
280
+
281
+ The OOM test now asserts what it observes: that the heap-capped child aborts rather than exiting
282
+ cleanly, and that its allocation loop never printed `survived`. Measured — V8's out-of-memory is a
283
+ fatal process abort, not a catchable exception, so the child's own `catch`/`exit(7)` never runs and
284
+ the assertion does not pretend otherwise. Verified to go red when the heap cap is raised so the child
285
+ survives.
286
+
287
+ The generator-leak test is rewritten against real SDK code. It previously asked
288
+ `FinalizationRegistry` whether a generator had been collected, behind a `globalThis.gc` guard nothing
289
+ in the repository satisfied, so it reported a pass without executing its assertion for its entire
290
+ life; supplying the flag makes it fail, and no window can fix that, because the specification gives
291
+ `FinalizationRegistry` no timing guarantee at all. It now asserts cleanup through the task event
292
+ stream's own subscriber count — deterministic, no GC and no timers — and it is verified by mutation:
293
+ removing the iterator's `return()` turns it red.
294
+
295
+ That rewrite also corrects the premise it was built on. Breaking out of a `for await` loop does not
296
+ leak a generator; the iteration protocol calls `.return()` on your behalf, on `break` and on `throw`
297
+ alike. Only an iterator taken by hand and abandoned escapes cleanup, and that is the shape now
298
+ asserted.
299
+
300
+ The scaffolds that remain unwired each carry a todo naming the SDK path they stand in for, an owner
301
+ and a sunset date, and each directory carries a README stating plainly what it does and does not
302
+ cover.
303
+
304
+ - 521f8c7: A disposed `CloudAgent` now refuses `send()`, as `LocalAgent` already did.
305
+
306
+ `CloudAgent` tracked a `disposed` flag but consulted it only to make `dispose()` idempotent — `send()`
307
+ never checked it. So after disposing a cloud agent, sending still started a real run and resolved with
308
+ a live `CloudRun`, while the identical call on a local agent rejected. A caller reaching a torn-down
309
+ handle through a stale reference, a retry, or an `await using` scope that had already exited got work
310
+ started on an agent they believed was released.
311
+
312
+ `send()` now throws `AgentDisposedError` (code `agent_disposed`) before constructing anything, matching
313
+ `LocalAgent`. `dispose()` keeps its own idempotence, so `await using` double-dispatch is unaffected.
314
+
315
+ Thrown rather than returned as a failed run: the error is not retryable and a disposed handle never
316
+ becomes un-disposed, so a rejected run would invite retry loops around a condition that cannot clear.
317
+
318
+ - d0c800c: A real cloud run now reports a `RunStatus` the public type actually declares
319
+ (#341). The SSE transport cast the server's terminal token straight into
320
+ `RunStatus`, and the server sends `FINISHED` while `RunStatus` is lowercase — so
321
+ `result.status === "finished"` never fired on a successful cloud run, and
322
+ `throwOnError`, which keys on `"error"`, never fired on a failed one. Silently,
323
+ on the primary cloud path.
324
+
325
+ Server tokens are now mapped case-insensitively onto `RunStatus`, and an
326
+ unrecognised one fails the run with an actionable message instead of defaulting
327
+ to `"finished"`. `EXPIRED` settles as `"error"`: a run that expired did not
328
+ finish. The wire-level `SDKStatusMessage.status` stays uppercase — that is its
329
+ declared union — but is validated rather than cast.
330
+
331
+ - 969b36e: `Cron.create()` now accepts zero-padded fields and refuses malformed ranges, matching the scheduler
332
+ that actually runs the job.
333
+
334
+ The validator parsed each field shape differently. Literals and steps carried a `String(n) === field`
335
+ round-trip; ranges did not. So `"5abc * * * *"` was refused while `"1-5abc * * * *"` was accepted —
336
+ the same malformed input, two answers, decided by which shape the user happened to write it in. The
337
+ accepted ones did not become working jobs: they were refused later by croner at fire time, where the
338
+ failure is a scheduling error nobody is watching rather than a rejected call the caller can fix.
339
+
340
+ The round-trip also refused `"07 * * * *"`, because `String(7) !== "07"`. Measured against croner 9,
341
+ the scheduler this SDK fires jobs with: it accepts `"07 * * * *"` and fires it at :07, accepts
342
+ `"01-05"` and `"*/05"`, and refuses `"5abc"`, `"1-5abc"`, `"1abc-5"`, `"0x5"`, `"5.9"`, `"+5"` and
343
+ `"1e1"` as illegal characters. Validating stricter than the engine rejects schedules that would have
344
+ run correctly; validating looser only defers the failure. Both directions were wrong, in different
345
+ field shapes, for the same reason.
346
+
347
+ One digits-only predicate now decides every shape, reproducing croner's answer on each case above.
348
+ Zero-padded expressions that were previously rejected are accepted; malformed ranges that were
349
+ previously accepted are rejected at `Cron.create()` with `ConfigurationError` / `invalid_cron`, which
350
+ is where the caller can still do something about it.
351
+
352
+ Also removes a defensive branch in the same validator that no caller could reach: its only caller ran
353
+ with exactly five fields against a five-entry table, so the "field index out of range" guard stayed at
354
+ zero executions through 37 tests written specifically to enter it.
355
+
356
+ - ba8ebeb: Remove four unused internal exports surfaced once the dead-code gate stopped
357
+ skipping `src/internal/` — `isSqliteVecLoaded`, `listNotes` (with its `NoteFile`
358
+ type), `MemoryFileEntry`, and the derived `SpanName` union. None had a caller;
359
+ all four lived behind `@internal`, so no public export changes.
360
+
361
+ Two docblocks corrected in the process. `session-loader` claimed to return
362
+ `MemoryFileEntry`-shaped records against a two-field type where the interface had
363
+ four, with the path field named differently. `span-names` described the removed
364
+ union as the mechanism preventing span-name drift; the `as const` map is what
365
+ does that, and emitters read keys off it.
366
+
367
+ The HITL approval middleware is now documented as not wired — it is constructed
368
+ nowhere outside its own test file — with the timeout-versus-denial semantics
369
+ pinned by characterization tests. Behaviour unchanged.
370
+
371
+ - d610c2a: Device login now reports a non-JSON response as a typed error instead of a raw `SyntaxError`.
372
+
373
+ Every failure in the OAuth device flows is supposed to reach the caller as an `AuthCallbackError`
374
+ carrying a code the CLI can branch on. Three of the four entry points broke that contract: they
375
+ parsed the response with `res.json()`, so an endpoint answering with HTML — a captive portal, a
376
+ corporate proxy's sign-in page, a load balancer's error page — rejected with a `SyntaxError` that no
377
+ `catch` in the module handled. It escaped untyped past callers prepared only for `AuthCallbackError`.
378
+
379
+ Affected: `requestDeviceCode`, `requestOpenAIUsercode`, and the two-step poll inside
380
+ `openaiDeviceLogin`. The RFC 8628 poll loop was already safe and is unchanged.
381
+
382
+ The message now quotes the body (truncated), because "not JSON" and "not JSON, and it looks like a
383
+ proxy login page" are different diagnoses for whoever is holding the terminal — and sending someone
384
+ to debug the provider when the fault is their own network is the expensive kind of wrong.
385
+
386
+ - e3f2a82: Public-API documentation reviewed file by file, and corrected wherever it disagreed
387
+ with the code. The docblocks ship in the `.d.ts`, so these read as behaviour changes
388
+ in an editor even though no behaviour changed.
389
+
390
+ The corrections that change what a caller would do:
391
+
392
+ - **`sdk-cache` documented its own premise backwards.** The header example labelled a
393
+ semantic hit as if it avoided the provider call. `asPlugin()` returns the cached
394
+ answer as `recalledContext`, which the agent loop injects as a `<memory-context>`
395
+ block _before_ the prompt — the request still goes to the provider. The two modes
396
+ are now labelled separately, with a table saying which one short-circuits and which
397
+ one seeds.
398
+ - **`sdk-handoff`'s five error classes said "throw".** Under the plugin wiring the
399
+ handler never throws; every failure becomes a tool result `{"ok":false,…}` handed
400
+ back to the model. Each class now says where it is actually observable. The header
401
+ also told readers to `import { Handoff } from "@theokit/sdk"`, from which it was
402
+ extracted.
403
+ - **`sdk-budget`'s `charge()` claimed idempotency across concurrent calls.** The mutex
404
+ serialises, it does not deduplicate: two identical calls record twice. Related, and
405
+ newly documented: with `maxUsd` set, a model missing from the pricing table denies
406
+ every request rather than passing it — and the table matches by exact string, so
407
+ `"openai/gpt-4o"` does not match `"gpt-4o"`.
408
+ - **The three `memory-*` adapters advertised an env-var fallback they do not read**,
409
+ and their peer dependencies are required rather than optional. Their behavioural
410
+ differences are now stated where they break the "interchangeable adapter"
411
+ assumption — honcho ignores `k` and always throws on `delete`; mem0 recalls across
412
+ sessions by design; supermemory ignores `sessionId` entirely.
413
+ - **`sdk-memory`'s `truncated` flag was documented as its own inverse**, and its
414
+ dreaming sweep claimed a mutex it never takes against the writer it names.
415
+ - **`sdk-tools`** corrected `run_vitest`'s unreachable `no_vitest` code, `truncation`'s
416
+ replacement-character claim, and two return shapes missing a live error code.
417
+ - **`acp`/`cli`** corrected sixteen statements including a named error class that is
418
+ not the one raised, a handler documented as calling `fork()` that refuses
419
+ unconditionally, handlers described as pure that mint ids and mutate a store, a
420
+ config loader credited to Zod in a package that does not import it, and a `--force`
421
+ scaffold described as atomic that deletes the destination before the rename.
422
+
423
+ Undocumented public symbols were documented across every package, with each claim
424
+ checked against the implementation rather than inferred from the name.
425
+
426
+ - e368fc1: Every published declaration file now compiles without `skipLibCheck` (#345). The
427
+ DTS rollup emitted symbols as a re-export from a chunk while omitting them from
428
+ that chunk's `import`, and dropped type-only imports from external packages —
429
+ leaving 51 unresolved references across ten of the twelve packages. Nothing broke
430
+ at runtime, and `tsc` stayed green for anyone with `skipLibCheck` on, but a
431
+ consumer running type-aware lint saw every type reached through one degrade to
432
+ `error`.
433
+
434
+ The declarations are repaired at build time from the compiler's own diagnostics.
435
+ No source or API change.
436
+
437
+ - 3ac2b08: `LiveAgentRegistry` is no longer offered as a constructible value by the published
438
+ declaration. The source exports it type-only — the runtime singleton is reached
439
+ via `Agent.registry` — but the DTS rollup emitted `declare class` and re-exported
440
+ it as a value, while `dist/index.js` never exported it at all. A consumer writing
441
+ `new LiveAgentRegistry()` typechecked and failed at runtime.
442
+ - 29ebaa1: Three places where a value was reported that nobody had actually selected.
443
+
444
+ **An empty `POSTHOG_API_KEY` no longer masks a valid `POSTHOG_PROJECT_API_KEY`.** The adapter read
445
+ `POSTHOG_API_KEY ?? POSTHOG_PROJECT_API_KEY`, and `??` treats `""` as present. Leaving a variable
446
+ blank in a `.env` or a CI config is the ordinary way to say "unset", so a blank primary key silently
447
+ disabled telemetry while a working key sat in the sibling variable — and telemetry going quiet is the
448
+ one failure that reports itself as nothing at all. Empty and whitespace-only values now fall through.
449
+ The same trap on `POSTHOG_HOST` is closed with it.
450
+
451
+ **The provider inspector reports the model the route resolves to.** `extractModelName` documented
452
+ itself as surfacing the name from the prefix split and instead returned a hard-coded default, so a
453
+ route configured as `anthropic:claude-opus-4` with no explicit `route.model` reported
454
+ `claude-3-7-sonnet`. That field exists to let a caller confirm which model a route resolves to; a
455
+ wrong answer there is worse than no answer, because it is indistinguishable from a right one. The
456
+ name is now derived from the model id the route actually carries, and the default-model lookup that
457
+ produced the literal is deleted rather than left as a decoy.
458
+
459
+ **An errored ACP run no longer reaches the client as `end_turn`.** The stop-reason mapping fell
460
+ through to `end_turn` for any run status it did not recognise, so a failure was reported over the
461
+ wire as an ordinary completed turn — invisible to every ACP client, which is the swallowed-error
462
+ shape the project's error-handling rules forbid by name. The protocol's `StopReason` has no error
463
+ value, so an unmapped status now surfaces through the JSON-RPC error channel the handler already uses
464
+ for every other failure, with a message naming the status that was not mapped. A dead branch
465
+ returning `end_turn` twice is removed in the same pass.
466
+
467
+ - 0bc18f6: Adds negative-case tests over two modules whose typed errors were never entered by any test.
468
+
469
+ A sweep of the SDK found 340 `throw new *Error` sites with roughly a third never executed. The error
470
+ hierarchy exists so callers can branch on a typed code, and the project's own testing rule requires a
471
+ negative case to assert the specific error and message rather than merely that something threw — so
472
+ an untested throw site is a contract nobody has checked.
473
+
474
+ The hook-source loader is now fully covered on its failure paths: an unreadable hooks file, malformed
475
+ JSON, a non-object root, a non-array event group, and an invalid command shape. Each asserts the
476
+ class, the code and a message substring. One pre-existing test that asserted only
477
+ `.rejects.toThrow(/hook/i)` is upgraded to the same standard — matching a regular expression against
478
+ a message is not the same as identifying which guard fired.
479
+
480
+ Agent-helper resolution gains the same treatment on four of its five uncovered throw sites. The
481
+ fifth is left untested on purpose and recorded: its condition cannot be false for any caller, because
482
+ a sibling predicate that feeds it returns a constant. Writing a test for it would require mocking
483
+ that predicate away in order to reach a line real callers cannot, which is the decoy pattern this
484
+ project has already removed three times.
485
+
486
+ - b5b5e77: `humanizeModelName` stripped trailing slashes with a pattern that backtracks. On a model id ending
487
+ in a long run of slashes, the engine consumed to the end of the string at every start position:
488
+ 25,000 slashes took half a second, 100,000 took **31 seconds** with one CPU pinned — to render a
489
+ label.
490
+
491
+ The trim is now a single linear pass. Behaviour is unchanged: a trailing slash is still stripped,
492
+ several are still stripped, and an id without one is untouched.
493
+
494
+ - 14ccb69: A run that exhausts its iteration budget now says so (#338 item 4). It reported
495
+ `status: "error"` with an empty result and no error detail — byte-for-byte the
496
+ shape a provider rejection produces, so a caller could not tell "the model ran out
497
+ of turns" from "the provider refused the request". `RunResult.error` now carries
498
+ `code: "iteration_limit_reached"`, the limit that was hit, and the name of the
499
+ option that raises it.
500
+
501
+ `LocalOptions` documents two behaviours that were reported as surprises: a `shell`
502
+ tool is registered on every local agent even when you pass `tools: []`, and a
503
+ finished run writes a transcript with the full prompt and reply to
504
+ `.theokit/memory/sessions/` under the workspace. Behaviour unchanged; both now
505
+ appear where a consumer meets them.
506
+
507
+ - fbf6721: Remove three unused error classes from the internal iteration-budget module
508
+ (`IterationBudgetExhaustedError`, `CompressionExhaustedError`,
509
+ `CompressionIneffectiveError`). They were never thrown: the budget reports
510
+ exhaustion by return value (`recordCompression()` answers
511
+ `{ allowed: false, reason }`), which is the shape the agent loop actually reads.
512
+ They were left over from an earlier exception-based design and advertised a
513
+ contract the module does not honour. No public export changes — all three lived
514
+ behind `@internal`.
515
+ - 240ae12: `LocalSandbox` now appends the `...(truncated)` marker when a command's output exceeds
516
+ `maxOutputBytes`, as `ExecuteResult` has always documented.
517
+
518
+ Node caps `execFile`'s buffer AT `maxBuffer`, so for ASCII output the string came back exactly at
519
+ the cap — never _greater_ — and the length test that gated the marker never fired. Callers were
520
+ told to branch on a marker that was never written, and every derived helper (`readFile`, `glob`,
521
+ `grep`, `listDir`) returned a silent prefix. Since a cut command reports `exitCode: 1` like any
522
+ other failure, the marker is the only thing that distinguishes lost output from a failed command.
523
+
524
+ `LinuxSandbox` routes through the same `execute` and is fixed with it.
525
+
526
+ - da98560: A malformed API key for a named provider is now refused when the agent is created, instead of failing
527
+ later wherever the key is first used.
528
+
529
+ The strict shape check existed and could never run. Deciding whether a key was headed for a provider
530
+ reused the predicate that decides whether a local runtime is available — and that one always answers
531
+ yes, because the SDK ships a local provider as a builtin. So the answer was no for every possible
532
+ input: the strict branch and the provider-prefix check were unreachable, and a key that could not
533
+ possibly work was accepted at the boundary.
534
+
535
+ The two questions are now answered separately. Whether to drive the real local runtime is still
536
+ decided where it always was. Whether a key reaches a provider that authenticates with it is decided by
537
+ that provider's own declared authentication type, so a provider that ignores keys entirely — the local
538
+ ones — accepts any shape, exactly as before.
539
+
540
+ Both unknowns stay permissive on purpose: an unrecognised model identifier or an unregistered provider
541
+ skips strictness. Rejecting a valid key blocks someone outright, while accepting a malformed one for a
542
+ provider we cannot identify only restores the previous behaviour for that case.
543
+
544
+ **This can newly reject keys that previously reached agent creation.** A short placeholder key paired
545
+ with a real provider prefix is the case to look for — two test suites in this repository were relying
546
+ on exactly that. Keys for local providers, fixture keys, and any setup with a base-URL override are
547
+ unaffected.
548
+
549
+ Also removes an authentication error that could not be raised: its condition depended on the same
550
+ always-true predicate, and the check that now does its job is the strict one above.
551
+
552
+ - 510ee70: The MCP OAuth token store now honours `THEOKIT_HOME`. When the variable is set, the store lives at `$THEOKIT_HOME/mcp-tokens.json`; when it is not, it stays exactly where it was, at `~/.theokit/mcp-tokens.json`.
553
+
554
+ `internal/mcp/token-storage.ts` was the only module on the credential path that ignored the variable this SDK isolates state with, and the consequence was not confined to configuration preference. `vitest.setup.ts` isolates every test in `@theokit/sdk` by pointing `THEOKIT_HOME` at a fresh tmpdir; it backs `HOME` up and never sets it. A home-anchored module that ignored `THEOKIT_HOME` therefore resolved to the developer's real `~` while the suite believed it was isolated — and it did resolve there: a default-config run of the suite deposited four refresh-token entries (`test-srv`, `srv-2`, `srv-race`, `srv-roundtrip`) into `~/.theokit/mcp-tokens.json` at mode 0600, written by the OAuth golden tests. Every key in that file was verified to be a test fixture rather than a real credential, and this predates the per-call path resolution shipped earlier — the old module constant resolved to the same real home.
555
+
556
+ A suite that is wrong about its own isolation is a false green about the property the rest of its greens rest on, which is why this shipped as a defect rather than as a preference.
557
+
558
+ **This is the code catching up to a contract the SDK already published, not a new policy.** `src/project-env.ts:47-49` documents `THEOKIT_HOME` as _"Locates the SDK home — sessions, and the credential store beneath it"_, and lists it as a sovereign key precisely because it governs where credentials live. The public contract already said the token store sits under the variable. This module was the half that disagreed, so what changes here is not the promise — it is the code finally keeping it.
559
+
560
+ **The resolver adopted is `transcriptRoot()`'s, not `getTheokitHome(cwd)`'s.** The transcript is the sibling with the matching shape: home-anchored default, `THEOKIT_HOME` override, trimmed and empty-guarded — and its own docstring records that before M94 it ignored the variable, so "whoever set it had their state split in two silently", which is this defect verbatim. M94 ADR-2 already accepted that migration for identically-shaped state. `getTheokitHome(cwd)` falls back to `<cwd>/.theokit` instead, so adopting it would have moved the token file of everyone who does **not** set the variable — and to a _different place per working directory_, making whether you are logged in a property of which folder you launched from. That is a regression for every user, not a migration.
561
+
562
+ **The migration this does carry, stated rather than buried.** A user who already holds `~/.theokit/mcp-tokens.json` **and** sets `THEOKIT_HOME` stops seeing those tokens: `getTokens` returns `undefined`, the caller surfaces it as "not logged in", and the OAuth flow re-runs. Nothing is deleted and nothing is overwritten — the old file stays where it is and is found again the moment the variable is unset. No migration step is performed on the user's behalf, because silently relocating a credential file is a worse failure than a re-auth, and a store that moved a token without being asked would be indistinguishable from one that lost it. Users who do not set `THEOKIT_HOME` — the default — see no change at all.
563
+
564
+ **Two further consequences for those who do set it**, both on the directory-permission path rather than on path resolution.
565
+
566
+ The store no longer re-permissions a `THEOKIT_HOME` it did not create. `ensurePrivateStoreDir` chmods the store directory 0700, and that was written unconditional on purpose: `mkdir`'s mode applies only at creation, so a machine that ran an older build already has a loose `~/.theokit`, and a fix reaching only fresh installs misses the population that has the problem. But that reasoning names its own population — directories _this SDK_ created. Once `THEOKIT_HOME` is honoured, an unconditional chmod also reaches a root the operator chose and shares with sessions, transcripts, personality and credential-pool state, which `paths.ts` documents as a multi-tenant deployment knob and which no other consumer of the variable imposes a mode on. Measured: it silently demoted a 0775 `$THEOKIT_HOME` to 0700. The retro-fix now keeps its population and loses the one it never had; a directory the SDK creates is still born 0700 wherever it points.
567
+
568
+ The consequence of not repairing it is that `getTokens` **refuses** — a typed `CredentialError` naming the directory and the `chmod 700` that fixes it — rather than returning `undefined`, when `$THEOKIT_HOME` is group- or world-writable. That is the intended end state, and the two alternatives are worse: silently tightening the operator's root breaks a deployment to protect them from a choice they may have made deliberately, and silently returning the token hands the caller a refresh token that any local user could already have swapped. One asymmetry is left unfixed and is not hidden: the write path has no matching gate, so `setTokens` writes into such a directory and the next `getTokens` refuses it.
569
+
570
+ An empty or whitespace-only `THEOKIT_HOME` falls through to the home-anchored default. That guard is load-bearing in a way the sibling `HOME` guard is not: without it, `THEOKIT_HOME=""` resolves the store to a **cwd-relative** `mcp-tokens.json` and `THEOKIT_HOME=" "` to a directory literally named three spaces. Neither falls back to anything — both are new locations invented from an unusable value.
571
+
572
+ Pinned in both directions, per `rules/testing.md § 4.2`: one test asserts the store follows the override and leaves the home default untouched, one asserts the read path looks there too (the file is placed by hand rather than through `setTokens`, so a roundtrip cannot pass by having both halves agree on the wrong path), and two assert that an unusable value leaves the home default in place. Verified by mutation, six mutants and six deaths: removing the override branch, relaxing the empty guard, dropping the `.trim()`, hard-coding the old path back into the warning, chmodding unconditionally, and dropping the chmod entirely each kill a test named for the property it breaks. A seventh — guarding the chmod on "we just created it" as well — killed nothing, because a umask only clears bits and 0700 carries none in the group/other range, so `mkdir(0700)` is private under every umask. That clause was deleted rather than pinned with a test written to justify it.
573
+
574
+ The keytar-absent fallback warning now names the **resolved** store path instead of the literal `~/.theokit/mcp-tokens.json`. That literal was correct until this change; afterwards it would have sent anyone who sets `THEOKIT_HOME` to look at a file the store no longer writes, and a diagnostic that names the wrong location costs more than one that names none — the reader stops looking once they find it empty.
575
+
576
+ - 1362583: The MCP OAuth token store now resolves its path when an operation runs — reading the same environment variable `os.homedir()` reads on that platform (`USERPROFILE` on Windows, `HOME` elsewhere), with `os.homedir()` itself as the fallback — instead of binding a path once when the module is first imported.
577
+
578
+ `internal/mcp/token-storage.ts` held `const FILE_PATH = join(homedir(), ".theokit", "mcp-tokens.json")` at module scope. A constant at module scope captures ambient global state at import, so the store kept reading and writing under whichever `HOME` was set at that moment and never noticed a later change. It made the module's correctness a property of _when_ it was imported, which is not a property a credential store should have.
579
+
580
+ Reading the environment first is not a stylistic preference, and **the variable read is per platform because `os.homedir()` itself is**: on POSIX it prefers `$HOME`, on Windows it reads `USERPROFILE` and never consults `HOME`. Mirroring that split keeps this a binding-time fix rather than a behaviour change. In a normal process on either platform the resolved path is identical to what shipped before.
581
+
582
+ They diverge in exactly one place — inside a worker thread, `process.env` is a JS-level copy while `os.homedir()` is a native call reading the real process environment, so a home moved inside a worker is invisible to `homedir()`.
583
+
584
+ An empty or whitespace-only value falls through to `homedir()`. Being precise about what that buys, because an earlier draft of this note overstated it: on POSIX it is close to a no-op, since `homedir()` returns the same empty value, and an empty home resolves the store to a CWD-relative `.theokit/mcp-tokens.json` either way. It earns its place on Windows and for a worker whose environment copy was blanked.
585
+
586
+ **The Windows OS is untested; the platform branch is not.** Every POSIX-mode test in `mcp-token-store-modes.test.ts` is guarded by `it.skipIf(!POSIX)` so it does not run on Windows, and CI runs ubuntu only, so nothing here exercises real Windows chmod semantics or libuv's `USERPROFILE` lookup. The branch SELECTION does run everywhere: one test spies `process.platform` and asserts the store follows `USERPROFILE` rather than `HOME`. The split itself is reasoned from `os.homedir()`'s documented per-platform source, not from a run on Windows.
587
+
588
+ The path is resolved once per operation and passed down, including into the directory-permission step. Resolving it per use would let a read and the write that follows it disagree if `HOME` moved in between, or lock down one directory while the token lands in another.
589
+
590
+ **Behaviour change, both directions.** A process that moves `HOME` after importing the SDK now has its tokens follow the new home. On the write path that is the safer reading — the alternative writes credentials to a location the caller no longer considers theirs. On the read path it has a cost worth naming: tokens stored under the previous home are no longer found, so `getTokens` returns `undefined` and the caller sees "not logged in" rather than an error. Following the current home is still the right trade for a credential store, but it converts a stale-write risk into a silent-re-auth one, and both sides are stated here rather than only the favourable one.
591
+
592
+ `THEOKIT_HOME` is deliberately not honoured by this store. `transcriptRoot()` does honour it and M94 ADR-2 accepted that migration for the sibling module; doing the same for credentials changes what existing token holders see, which is a product decision rather than a prerequisite for making this module independent of the execution model.
593
+
594
+ Found while measuring whether mutation testing is viable on this package: the directory-permission tests passed only because `vitest.config.ts` pins the `forks` pool with `fileParallelism: false`. A tool that controls test execution refused to start against that baseline. The suite now carries a regression test that holds under the default config **and** under `--pool=threads`.
595
+
596
+ - 2cdadcc: The memory index's `LIKE` fallback — used when FTS5 cannot tokenise a query, which is the normal
597
+ path for CJK text — escaped `%` and `_` but not the backslash that its own `ESCAPE '\'` clause
598
+ depends on. A query containing a backslash produced a pattern where the inserted escape was
599
+ consumed escaping the user's backslash, leaving the next wildcard live:
600
+
601
+ ```
602
+ search for x\%y
603
+ old pattern %x\\%y% the % is unescaped — matches anything between "x\" and "y"
604
+ ```
605
+
606
+ So a literal search silently became a scan, returning rows the caller never asked for. Escaping the
607
+ backslash first fixes it, and the rule now lives in one function with the ordering argument written
608
+ next to it.
609
+
610
+ Separately, `ContextManager` called `stat()` on each source file and discarded the result before
611
+ reading it. `readFile` already fails when the file is gone, so the extra lookup added nothing but a
612
+ window in which the path could resolve to a different file between the two calls. It is gone.
613
+
614
+ - 1c94ad3: The "Missing API key" refusal now names the provider credential you actually have
615
+ (#338 item 5). With `OPENROUTER_API_KEY` exported and `THEOKIT_API_KEY` unset,
616
+ the old three-word message named neither — while the SDK consults that exact
617
+ variable a moment later to decide whether to drive a real runtime, so the
618
+ environment looks configured to whoever set it up. Reported as three hours of
619
+ diagnosis on the wrong cause.
620
+
621
+ Resolution is unchanged: a provider key is still not adopted from the
622
+ environment, because with two of them exported there is no non-arbitrary answer
623
+ to which one was meant. The message says where to put it instead. Names the
624
+ variables, never their values.
625
+
626
+ - 3ad398d: `ModelSelection.url` names the endpoint a specific model lives at, and it was handed to every
627
+ provider in a fallback chain. A fallback therefore inherited the primary's host and could never
628
+ reach its own — so a configured failover silently retried the same dead endpoint instead of moving
629
+ on.
630
+
631
+ Measured against two servers with the primary refusing every request: with `model.url` set, the
632
+ primary received 6 requests and the fallback 0. Pointing each provider with its own
633
+ `*_API_BASE_URL` instead gave 3 and 1.
634
+
635
+ The per-call URL now reaches only the provider the model id names. Each fallback resolves its own
636
+ endpoint from its profile and its own `*_API_BASE_URL`, which is what makes a fallback a different
637
+ destination rather than a retry.
638
+
639
+ - a8cf443: `ModelSelection.url` names the endpoint a call should reach, and it reached only two of the four
640
+ transport branches. On `anthropic_messages`, `bedrock` and the Responses API it was silently
641
+ dropped: a run explicitly aimed at a local host went to the vendor instead, with the caller's key,
642
+ and nothing said so.
643
+
644
+ Measured on the anthropic branch: the local server recorded zero requests and the run failed with
645
+ `Anthropic API error: auth_failed (HTTP 401)` — a 401 from `api.anthropic.com`, after the caller
646
+ had named a different host.
647
+
648
+ All four branches now honour it, and it outranks the process-wide `*_API_BASE_URL` on each, which
649
+ is the contract the field's own documentation states. Nothing changes when it is absent.
650
+
651
+ - aadc9dd: Seventeen more negative-case tests now identify which failure they caught, and a registry test suite
652
+ stops sleeping to make timestamps differ.
653
+
654
+ Most of those assertions turned out to be under-asserting rather than untestable: twelve of them sat
655
+ on errors that were **already typed**, and simply checked that something threw. They now name the
656
+ class, the stable code and a message fragment — which means a change that swaps one failure for
657
+ another is caught, where before any error at all satisfied the test.
658
+
659
+ Four remain matched on a message fragment because the underlying error genuinely has no type yet, and
660
+ one of those is filed separately: a public entry point throwing a plain error gives callers nothing to
661
+ branch on but a string that changes whenever someone improves the wording.
662
+
663
+ Four more were reclassified out of scope after reading the source rather than the name: they raise
664
+ errors owned by Node, by the schema library, or by a database driver, and pinning a third-party class
665
+ buys little.
666
+
667
+ Separately, the live-agent-registry tests slept thirteen times — some to force last-used timestamps
668
+ apart so eviction ordering could be asserted, others to let fire-and-forget cleanup finish. Both are
669
+ now driven by the test clock, a mechanism this same file already used elsewhere and which needed no
670
+ production change. The file runs in a fraction of the time and no longer depends on how busy the
671
+ machine is.
672
+
673
+ - a1cae95: Removes an unreachable `ollama` arm from the provider base-URL resolver. `OLLAMA_HOST` is unaffected
674
+ and keeps working exactly as before.
675
+
676
+ The router's base-URL env switch carried a `case "ollama"` returning `process.env.OLLAMA_HOST`. It
677
+ never ran. Ollama is served by its own native client, which the transport selector returns before the
678
+ OpenAI-compatible branch — the only place that switch is consulted — so the arm was unreachable from
679
+ the first line of the function containing it. Measured two ways: line coverage over the router and
680
+ provider suites puts the arm at 0 entries while all four siblings are entered, and a probe that
681
+ replaced its body with a throw was never triggered by any test, plugin profile or alias.
682
+
683
+ The one construction that could reach it is a provider profile whose `name` getter returns a
684
+ different value on successive reads — a profile contradicting itself. Run against the old code, that
685
+ path shows what the line actually did: it pointed the **OpenAI-compatible** transport at the Ollama
686
+ host, producing `…/v1/chat/completions` against an Ollama daemon. That is the failure mode ADR D191
687
+ exists to prevent — models emitting raw tool JSON as plain text. So this is not merely an inert line
688
+ being tidied away; it is a latent bug being removed on the only path that reached it.
689
+
690
+ The line also cost real time as a decoy: it reads exactly like the mechanism implementing
691
+ `OLLAMA_HOST` and is not. A repair pass mutated it, measured a green suite, and concluded the real
692
+ override was untested. The real one lives on the native branch and is now pinned by a test asserting
693
+ that an ollama request reaches `/api/chat` at the configured host, so the routing this removal
694
+ depends on cannot change unnoticed.
695
+
696
+ - 8226bc6: Fourteen negative-case tests now identify which guard fired, and a scheduled job keeps test-order
697
+ independence honest.
698
+
699
+ Assertions that only checked "something threw" now assert the error class, its stable code and a
700
+ message substring — for concurrency validation, retry configuration, path traversal, filename
701
+ validation and credential loading. Each conversion was verified by mutating the production error's
702
+ code and watching the corresponding test fail, so the assertions are pinned to the real constants
703
+ rather than to a copy of them.
704
+
705
+ Forty-five remaining sites are deliberately left alone and grouped with reasons: ten raise validation
706
+ errors owned by a third-party schema library, thirteen surface Node's own errors, and twenty-two are
707
+ plain untyped errors in our code where there is no class or code to assert yet.
708
+
709
+ Separately, the suite runs one file at a time, and a comment in the configuration said that was
710
+ covering up a leak. Measured: with file-level parallelism restored the suite is fully green, twice
711
+ over — the two leaks that comment named have since been fixed. Restoring _within-file_ concurrency
712
+ plus randomised order does still fail, reproducibly, in one file that shares a mutable counter
713
+ between its cases; that is filed on its own and is not fixed here.
714
+
715
+ The default gate is unchanged. A separate weekly job runs the suite in shuffled order so the
716
+ remaining coupling keeps surfacing instead of staying suppressed by the serial default.
717
+
718
+ Also documented for contributors: what makes a wait trustworthy, and why a premise that justifies
719
+ deleting something needs checking in a way that a premise justifying keeping something does not.
720
+
721
+ - e699569: **The repository moved to the official `usetheokit` organization.** Every `repository`, `bugs` and `homepage` field now points there, along with the README, `CONTRIBUTING.md`, `SECURITY.md` and the issue templates. Existing clones and any URL already published keep working — GitHub redirects a transferred repository permanently — so this is a correctness fix for the metadata npm renders, not a break.
722
+
723
+ **The Apache-2.0 text every package ships was replaced with the official one.** The copy distributed until now had paragraph 4(d) truncated: it read "except as required for describing the origin of the Work and reproducing the content of the NOTICE file", dropping "reasonable and customary use" from the licensed clause. §4(d) governs what a redistributor must do with attribution notices, and the omission narrowed it.
724
+
725
+ That matters more than a typo would. The manifests declare the SPDX identifier `Apache-2.0`, which is an assertion that the terms are _the_ Apache-2.0 terms — a licence scanner resolves the identifier and never reads the file. A consumer's compliance review, which does read the file, would find a body that no longer matches the identifier and has no name of its own. Every `LICENSE` in this repository is now byte-identical to the canonical text, with the appendix filled in.
726
+
727
+ Nothing else about the terms changed: the licence is the same licence it has always been meant to be, and no package changes what it grants.
728
+
729
+ - 6950332: A `PermissionRule` argument matcher written as a predicate was invoked with `undefined` when the
730
+ call supplied no such argument. The string and RegExp forms already treated a missing argument as
731
+ "does not match"; the predicate branch returned before that guard.
732
+
733
+ Both directions were wrong, and the first is a permission escape: an allow rule like
734
+ `(v) => v !== "prod"` returns `true` for `undefined`, so a call that supplied nothing produced an
735
+ explicit allow — a matcher written to narrow, widening. A deny rule like `(v) => v.includes("rm")`
736
+ raised `TypeError` out of the permission gate instead of denying.
737
+
738
+ A rule that declares an argument is a rule about that argument. A call that omitted it no longer
739
+ satisfies the rule, whatever form the matcher takes.
740
+
741
+ - 9e6828e: When the API key's own prefix or an explicit `providers.routes` entry overrides the provider named
742
+ in the model id, the SDK now says so once per process, naming both the provider asked for and the
743
+ one used.
744
+
745
+ The precedence itself is unchanged and deliberate: an explicitly-passed key is ground truth about
746
+ which endpoint will actually be reached, so a `sk-or-` key beats an `openai/...` prefix. What was
747
+ missing was the sentence. A caller writing `model: { id: "custom/model" }` and receiving
748
+ `openai API error: auth_failed` had no way to learn their prefix had been overruled, because the
749
+ error names only the winner.
750
+
751
+ Nothing is emitted when the model id carries no prefix, or when the prefix is what was used.
752
+
753
+ - e3f2a82: Every symbol these packages declare in `exports` now reaches the `.d.ts` they publish.
754
+
755
+ Sixty-six declarations across twenty-three published files did not compile, and four entry
756
+ points silently omitted names their own barrel exports — `@theokit/sdk/internal/security`
757
+ dropped seven at once. Runtime was never affected; this is types-only. A consumer with
758
+ `skipLibCheck` on saw nothing, and a consumer running type-aware lint saw every type reached
759
+ through one of them degrade to `error`.
760
+
761
+ The cause was `stripInternal`, which deletes a declaration when the literal `@internal`
762
+ appears in ANY leading comment range of it. The tag was being used here to mean "outside the
763
+ semver contract" — `internal/persistence/sqlite-open.ts` said so in those words, on a subpath
764
+ the manifest publishes and a back-compat test pins. The compiler reads it as "erase this", and
765
+ the two meanings only diverge in the published artifact. It now says the semver exemption in
766
+ prose, and the tag is gone from the symbols that are published.
767
+
768
+ Two further mechanisms had the same cause and a wider blast radius. A tag in a BARREL header
769
+ deleted the first `export … from` beneath it; a tag in a MODULE header deleted the following
770
+ `import`, so `import { z } from "zod"` vanished and every type it bound became
771
+ `Cannot find name`. Nothing was added to any `exports` map and no `export` line changed — a
772
+ deleted import was never privacy, only a broken declaration.
773
+
774
+ `@theokit/sdk-handoff`'s `./internal` entry left `SDKAgent` and `CustomTool` unbound, from a
775
+ different defect: the declaration repair only ever looked at `exports["."]`, so it fixed each
776
+ package's main entry and shipped the rest unrepaired. It now covers every declared subpath, and
777
+ binds the side-effect import form (`import '@theokit/sdk';`) the rollup emits with the names
778
+ stripped out.
779
+
780
+ Three gates were widened or added so this cannot return silently: the declaration typecheck
781
+ now covers all 45 published entries rather than 12, a new export-parity check fails when a
782
+ source barrel exports a name the emit omits, and public-API documentation coverage is gated at
783
+ 100%.
784
+
785
+ Two consequences worth naming rather than discovering. `coerceToKnownAgentRunErrorCode` — the
786
+ boundary helper the 4.x release notes point at as the migration path off the open
787
+ `AgentRunErrorCode` union — was tagged internal and therefore absent from the published types; it
788
+ is now exported and documented, which is a small addition to the public surface. And
789
+ `packages/sdk/typedoc.json` sets `excludeInternal: true`, so the generated API reference gains the
790
+ ~57 symbols whose tags were removed. That is the intended direction: those symbols are published,
791
+ and the reference now says so.
792
+
793
+ - ac08996: `sanitizeIdentifier` now reports every rejection as `ConfigurationError` with code
794
+ `invalid_identifier`.
795
+
796
+ It used to throw two classes and the input chose which: a NUL, C0 control char or DEL produced
797
+ `PathTraversalError` (code `path_traversal`), everything else produced `invalid_identifier`. A
798
+ caller branching on the documented code — the shape an HTTP handler uses to answer 400 — rethrew
799
+ for exactly the input class an attacker controls, so a rejection surfaced as a 500 and the 400/500
800
+ split became an oracle for which branch was reached. The input was rejected either way; this was
801
+ never a traversal bypass.
802
+
803
+ The message still names the offending byte (`<nul-byte>`, `<control-char-0x1f>`), which is the part
804
+ the second class existed for. `@theokit/sdk/workflow` validates step ids through this function and
805
+ inherits the fix.
806
+
807
+ - 96b28ba: Test-harness repairs: an unmeasurable socket probe now reports as skipped instead of passing, and a
808
+ fixed sleep is replaced by polling the real value.
809
+
810
+ The CLOSE_WAIT socket monitor returned a bare `null` when it could not measure — off Linux, or when
811
+ `ss` was unavailable — and the caller treated that as a pass. An environment where the probe could
812
+ not run was therefore indistinguishable from one where the assertion held. It now returns an explicit
813
+ unavailable result with a reason, the caller reports the case as skipped and names that reason, and
814
+ the assertion helper refuses an unavailable result rather than quietly doing nothing.
815
+
816
+ The same test slept a fixed 500ms to let the operating system finish tearing sockets down. The OS
817
+ decides that timing, not the test process, so the wait is now a poll against the real count with a
818
+ deadline. The threshold moves to the value the harness's own docblock documents; the number at the
819
+ call site had never matched it and never explained itself.
820
+
821
+ A shared polling helper replaces three more fixed sleeps in the semaphore tests, where the queue
822
+ depth is a real signal that can be waited on, and absorbs one hand-rolled poll loop that had already
823
+ been written by hand elsewhere.
824
+
825
+ Every change is verified by mutation rather than by construction: mutating the production semaphore's
826
+ pending-count turns the converted tests red, and three mutants of the socket monitor each kill the
827
+ test named for them.
828
+
829
+ Honest limit, recorded in the test and tracked separately: the CLOSE_WAIT assertion still cannot
830
+ detect a real leak. Removing the driver's own socket cleanup entirely leaves the count at zero,
831
+ because Node completes the FIN handshake on its own and the fixture server closes idle sockets. This
832
+ change makes the test honest about what it cannot measure; it does not give it detection power.
833
+
834
+ - f53ee6a: A stream cut mid-flight now delivers the text that already arrived, instead of dropping it.
835
+
836
+ Measured on a 200-chunk answer severed just before its terminator: the provider sent 1490 characters
837
+ and the consumer received none. Truncated streams are routine — proxy timeouts, load-balancer idle
838
+ limits, mobile links — and every one of them turned a mostly-complete answer into nothing, the more
839
+ so the longer the answer. The run is still reported as errored; what the caller gets back is the
840
+ choice of whether a partial answer is usable.
841
+
842
+ A body read that fails mid-stream is also routed through the transport-error mapper, so it reads
843
+ `openai transport failure on /v1/chat/completions: terminated` and carries `code:
844
+ "transport_failure"` instead of undici's bare `terminated` with no code. `RunResult.usage` is
845
+ documented as absent for such a run: the counts arrive with the terminating frame a severed
846
+ connection never delivers.
847
+
848
+ - 1af99fa: `maxDelegationDepth` now bounds the delegation chain it always claimed to.
849
+
850
+ The check ran once at tool-construction time against a `parentDepth` argument nothing in the SDK
851
+ incremented, so under the documented `SubAgent.create(spec)` call it could never fire and a
852
+ subagent whose tools include another subagent recursed unbounded. Depth is now counted at dispatch
853
+ and travels with the run, so nesting is bounded without threading a counter by hand.
854
+
855
+ A caller that does thread `parentDepth` keeps its existing behaviour — the threaded value offsets
856
+ the chain depth, and an already-impossible spec is still refused at construction.
857
+
858
+ - 8f8d3eb: Breaking out of a subscription now closes the underlying connection instead of leaving it open.
859
+
860
+ `Theokit.subscribe`'s SSE transport released its stream reader on exit but never cancelled it. Per
861
+ the Streams specification those are different operations: releasing detaches the reader and leaves
862
+ the stream — and therefore the `fetch` response and its socket — open until something else cancels it
863
+ or reads it to completion. So the ordinary consumer shape, breaking out of the loop early, left a
864
+ connection dangling every time. The WebSocket transport already closed its socket correctly; only the
865
+ SSE half was affected.
866
+
867
+ The reader is now cancelled on early exit, best-effort and skipped on natural completion, where the
868
+ stream is already finished and cancelling would only risk surfacing a spurious rejection.
869
+
870
+ This is the leak a load test in this repo has claimed to detect for some time and never could. That
871
+ test drove raw sockets with no SDK code in the path at all, and passed whether or not anything
872
+ cleaned up — measured by deleting its own cleanup call and watching the count stay at zero, twice.
873
+ Its claim is now withdrawn in the test itself and in that directory's README, and the real property
874
+ is asserted where the code actually lives: a test that drives the SSE and WebSocket transports
875
+ through injected mocks, with no network and no operating-system probing, and that fails when either
876
+ transport stops cleaning up.
877
+
878
+ Also included: the plugin manager's seven manifest-validation errors now each have a test asserting
879
+ the specific error class, code and message, plus cases each guard must accept — a guard tested only
880
+ on what it rejects cannot be told apart from one that rejects everything.
881
+
882
+ - 883f473: Seventeen module docblocks that opened with `@theokit/...` are rewritten to open with a sentence.
883
+
884
+ A JSDoc block whose first line begins with `@` has no description: TypeScript parses the whole block
885
+ as that tag's value, so `getDocumentationComment()` returns nothing and editor tooltips, TypeDoc and
886
+ this repo's doc-coverage instrument all report the symbol as undocumented while the source plainly
887
+ documents it. The affected files are the `server/auth` and `subscription` surfaces; the same words
888
+ now appear in an order the tooling can read.
889
+
890
+ A new `quality:doc-tag-first` gate fails the build on the shape, so it cannot come back.
891
+
892
+ - 36e5879: The task-registry tests wait for the state they need instead of sleeping.
893
+
894
+ Twelve waits in that suite were fixed sleeps between 10ms and 200ms, each chosen to be "long enough"
895
+ for the registry's fire-and-forget work to reach a state. The state is observable — the registry can
896
+ be asked for it — so the sleep was guessing at something the test could simply read. Under load those
897
+ guesses stop being long enough, which is how a suite acquires flakes that only appear on a busy
898
+ machine or a slow runner.
899
+
900
+ Each now polls the real state with a deadline. A passing run is never slower than the sleep it
901
+ replaced, because it returns the moment the state arrives; a state that genuinely never arrives fails
902
+ with the state it was waiting for, rather than an assertion on stale data.
903
+
904
+ The shared polling helper was widened to accept an asynchronous condition rather than growing a
905
+ second near-identical copy for the case where the value has to be awaited.
906
+
907
+ - b68704b: `JsonFileTaskStore.list()` no longer hides tasks past the 256th file.
908
+
909
+ The 256-entry cap was applied to the raw directory listing, before `state`, `kind` and the
910
+ `submittedBefore` / `submittedAfter` window were considered — so past 256 task files the visible
911
+ set was an arbitrary, readdir-ordered subset, `submittedBefore` narrowed within that subset instead
912
+ of paging beyond it, and `evictTerminalOlderThan()` left eligible handles behind however many times
913
+ it was called.
914
+
915
+ The cap is now a bound on concurrent file reads, which is the cost it was meant to control, and
916
+ results come back newest-first so `submittedBefore` works as a cursor. Eviction sweeps the whole
917
+ directory: one call now means everything eligible is gone.
918
+
919
+ - 9ab1f0d: The test suite runs its files in parallel again.
920
+
921
+ It had been pinned to one file at a time, with a comment explaining that the serialisation was holding
922
+ back two leaks: tests mutating the home directory environment variable, and a process-wide registry
923
+ accumulating entries across tests. Both were fixed elsewhere, and nobody went back to ask whether the
924
+ constraint still had a reason. It did not — what actually prevents the home-directory race is that
925
+ each file already gets its own subprocess, which is a separate setting and unchanged here.
926
+
927
+ One genuine coupling had to be removed first: a contract test kept a file-level counter that three of
928
+ its cases each expected a specific value from, which only holds if they run in declaration order. Each
929
+ case now owns its own identifier, so nothing is shared to race over.
930
+
931
+ Within-file concurrency stays capped at one, deliberately. The more aggressive configuration —
932
+ concurrent cases plus randomised order — remains a separate periodic probe rather than part of the
933
+ gate, and a test now pins that split so it cannot drift quietly.
934
+
935
+ - 464c390: Repairs four quality gates that were measuring something other than what they claimed.
936
+
937
+ **The Portuguese-language lint no longer scans files git does not track.** It walked the tree with
938
+ `readdir` and skipped only dot-directories, so it flagged untracked files CI never sees — going red
939
+ on a developer's machine while CI stayed green — and simultaneously missed `.github/workflows/`,
940
+ which CI very much does have. A red that CI cannot reproduce is what teaches people to reach for
941
+ `--no-verify`. The scan is now driven by `git ls-files`, which fixes both halves at once: untracked
942
+ files disappear by construction, and tracked dot-directories come into scope. Portuguese text the
943
+ lint could not previously see in the CI workflow is translated as part of the change.
944
+
945
+ **The pre-push Biome gate has the same repair.** `biome check .` walked everything on disk;
946
+ `biome.json`'s `vcs.useIgnoreFile` skips gitignored files but not untracked-but-unignored ones, which
947
+ is exactly the class that broke the gate. Measured: the tracked-only scan and the walk-everything
948
+ scan process the same 1686 files on a clean tree, so scoping to tracked files costs no coverage.
949
+
950
+ **The pre-commit typecheck no longer typechecks all fifteen packages on every commit.** It is scoped
951
+ to the packages the diff actually touches, with a guard the item this came from insisted on: the run
952
+ reports how many packages it selected, and a selection of zero fails loudly instead of exiting 0.
953
+ That silent-zero case is real — a stale or unfetched ref makes the scoped filter select nothing while
954
+ turbo reports success — and swapping an expensive honest gate for a cheap silent one would have
955
+ reproduced the defect being repaired. The full unscoped verdict still runs at pre-push and in CI.
956
+
957
+ **Dead Vitest 4 settings are removed rather than migrated.** The config carried a `poolOptions` block
958
+ that Vitest 4 no longer reads, printing a deprecation warning on every run. Migrating those keys
959
+ would not have revived the knob they configured: `fileParallelism: false` overwrites the worker count
960
+ unconditionally, so the `SDK_TEST_MAX_FORKS` environment variable was inert by two independent paths.
961
+ The block and the variable are deleted, `fileParallelism: false` is kept (test-order safety currently
962
+ depends on it), and Vitest 4's actual replacement for the isolation setting is declared explicitly.
963
+
964
+ - c7385d2: Test runs no longer claim every core on the host.
965
+
966
+ None of the package configs capped `maxWorkers`, so vitest's default applied: `os.availableParallelism()`,
967
+ one fork per core, each booting a full test environment. The repo's `test` script is
968
+ `turbo run test --filter='./packages/*'`, so that default is paid once per package _concurrently_ —
969
+ nproc forks times turbo's concurrency, on nproc cores. Measured on a 12-thread machine during an
970
+ unrelated investigation, two vitest pools alone were enough to reach load average 33.89 with the
971
+ desktop unusable; a full fan-out is several times that.
972
+
973
+ `@theokit/sdk` is the interesting case. B-104 recorded on 2026-08-19 that the `poolOptions.forks.*`
974
+ block was 100% dead in Vitest 4, deleted it, and noted that `fileParallelism: false` was forcing
975
+ `maxWorkers` to 1 unconditionally, so a fork-count knob could not act. B-059 then flipped
976
+ `fileParallelism` to `true` on 2026-08-20, which made the knob able to act again — and nothing
977
+ reintroduced one, so the package silently went back to the uncapped default. That comment has been
978
+ corrected along with the config; it claimed no knob existed, which is no longer true.
979
+
980
+ The cap leaves 4 cores free (`Math.max(2, cpus().length - 4)`), scaling with the runner rather than
981
+ hard-coding one machine's core count. It costs no wall-clock: measured in `theokit-ui`, the full
982
+ suite ran 73.96s at 4 workers against 74.36s at 12, so the parallelism above the cap was already
983
+ noise. Verified as resolved config rather than as file contents — `createVitest` reports
984
+ `maxWorkers: 8` on a 12-thread host, which is the formula, not the default.
985
+
986
+ This changes no published behaviour; it is test tooling only. Refs usetheokit/theokit-ui#51.
987
+
988
+ - 9f5cc20: A test run can no longer write into the developer's real home directory.
989
+
990
+ The shared test setup gave every test an isolated `THEOKIT_HOME` in a fresh temporary directory, and
991
+ backed up `HOME` alongside it — but never actually set `HOME`. So any module reading `HOME` or
992
+ `os.homedir()` directly, instead of consulting `THEOKIT_HOME`, resolved to the real home and wrote
993
+ there. That was not hypothetical: the MCP token store did exactly this, and a real `~/.theokit`
994
+ credential file was observed accumulating test fixtures and changing timestamps across an afternoon
995
+ of runs.
996
+
997
+ That one module was fixed previously. This closes the gap itself, so the next module that reads the
998
+ home directory without going through `THEOKIT_HOME` cannot repeat it. Isolation is now enforced by
999
+ the setup rather than by each module remembering, which is the difference between a property and a
1000
+ convention.
1001
+
1002
+ Verified the way the problem was originally found: the golden MCP suite was run with `HOME` pointed
1003
+ at a throwaway sentinel directory, and nothing was written to it.
1004
+
1005
+ Also included: the dependency-boundary check now cruises the test tree as well as the source tree,
1006
+ and the code-quality gate refuses to report success when it audited no languages at all — previously
1007
+ a gate with nothing enabled returned a pass, which is indistinguishable from a clean run.
1008
+
1009
+ - 5fac0f6: Test-suite hygiene: scratch directories are cleaned up, the working directory is no longer mutated
1010
+ process-wide, and the agent registry starts empty in every test.
1011
+
1012
+ Fifty-nine test files created temporary directories and never removed them, so a full run left its
1013
+ debris behind on every machine that executed it. Each now removes its directory when the test
1014
+ finishes, through the same retry-hardened helper the workspace fixture already used — the retries
1015
+ matter because a directory holding a file another handle has open cannot be removed on the first
1016
+ attempt.
1017
+
1018
+ Three tests changed the process's working directory to exercise code that reads it. `process.chdir`
1019
+ is process-wide, so a test doing that mutates the environment of every other test sharing the worker,
1020
+ and the two production paths involved hardcode the current directory with no override to pass. They
1021
+ now replace the reader rather than the process state. A lint test bans any future live `chdir` under
1022
+ the test tree, so this does not return for a fourth time.
1023
+
1024
+ The agent registry is a process-wide map that does not follow the per-test home directory, so entries
1025
+ accumulated across tests and individual files had taken to clearing it by hand — which only works for
1026
+ the files that remember. It is now cleared by the shared setup, unconditionally.
1027
+
1028
+ One test file was removed rather than repaired: it exercised a locally-declared copy of a concurrency
1029
+ helper instead of the real one, so nothing it asserted could fail when production changed. Its one
1030
+ genuinely distinct assertion — that three tasks overlap under a barrier — moved to a test that drives
1031
+ the real function, and was verified by stubbing that function to return nothing and watching four
1032
+ tests die.
1033
+
1034
+ - e685ccb: The model catalog was fetched with `res.text()` and written to the cache with no size limit. The
1035
+ default source is trusted, but `THEOKIT_MODELS_URL` lets an operator point the fetch anywhere, and
1036
+ a host serving a multi-gigabyte document would have been materialised in memory and then written
1037
+ to disk.
1038
+
1039
+ The fetch now refuses anything over 32 MiB — roughly 40x the real catalog. The declared
1040
+ `content-length` is checked before the body is read, and the received size is checked after,
1041
+ because a server that omits or misstates the header is exactly the one worth bounding.
1042
+
1043
+ A refused catalog is handled the way every other refresh failure already is: the SDK keeps serving
1044
+ the data it had, and says so.
1045
+
1046
+ - 7fd8c7e: Removes two guards no caller could reach, makes `Batch`'s `concurrency` option actually bound
1047
+ `onResult`, and stops three `Agent` APIs from accepting documented options they discarded.
1048
+
1049
+ **`concurrency` now bounds `onResult`.** The semaphore slot was released before the result callback
1050
+ ran, so a batch configured with `concurrency: 2` could have any number of `onResult` callbacks in
1051
+ flight at once. Callers using that option to protect a rate-limited downstream — the reason to set it
1052
+ at all — were not protected. The callback now runs inside the slot it belongs to. A test that had
1053
+ pinned the old behaviour as a contract is inverted, because it documented the bug as a promise.
1054
+
1055
+ **Three `Agent` APIs honour their options or stop accepting them.** `Agent.get` and `Agent.listRuns`
1056
+ took a `cwd` and ignored it, so they answered about the wrong workspace; `Agent.list` took
1057
+ `includeArchived`, `limit` and `cursor` and ignored all three. Each is now wired, with pagination
1058
+ opt-in so the default ordering is unchanged. Two options are removed rather than half-implemented:
1059
+ `prUrl`, which would need the on-disk registry to retain per-repo URLs, and `ListRunsOptions.runtime`,
1060
+ which is redundant once an `agentId` pins the runtime. Silently discarding a documented option is
1061
+ worse than not offering it, because the caller has no way to detect it.
1062
+
1063
+ **One unreachable guard is deleted.** The Vertex client's fetch wrapper branched on `URL` and
1064
+ `Request` input forms its only caller never produces, and on a URL condition that caller always
1065
+ satisfies. It is removed rather than annotated: a defensive branch nothing can reach is a decoy that
1066
+ reads like working machinery, and this project has spent real time on several of them.
1067
+
1068
+ - 60010b4: Provider-reported token usage is validated before it reaches `run.usage`, the cost calculation and
1069
+ `@theokit/sdk-budget`.
1070
+
1071
+ A negative count used to be billed as a negative cost and moved a budget gate downward; a numeric
1072
+ string was concatenated rather than summed, producing `"0100050"` where a total was intended. Both
1073
+ now drop with a diagnostic naming the field, and a numeric string parses. Fractional counts are
1074
+ floored rather than discarded.
1075
+
1076
+ Magnitude is deliberately not checked: any ceiling here would be invented, rejecting a legitimate
1077
+ large batch while still passing anything just under it. That is a budget policy, and
1078
+ `@theokit/sdk-budget` is where a cap belongs.
1079
+
1080
+ - 25b7eee: `Workflow` is now one type across `@theokit/sdk` and `@theokit/sdk/workflow`.
1081
+
1082
+ The two entries were built by different declaration pipelines and each emitted its own
1083
+ `declare class Workflow`. A class with a private field is compared nominally, so the documented
1084
+ combination — `import { Workflow } from "@theokit/sdk/workflow"` passed to `Cron.create` from the
1085
+ root — was rejected with "types have separate declarations of a private property '\_options'".
1086
+ Nothing in-tree crosses that boundary, because in-tree code imports from `src/`.
1087
+
1088
+ Both entries now resolve to a single declaration, and a new `quality:dts-identity` gate fails the
1089
+ build if any exported class is ever declared twice across published entries again.
1090
+
3
1091
  ## 4.53.0
4
1092
 
5
1093
  ### Minor Changes