@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
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/internal/persistence/fts5-sanitize.ts","../src/internal/persistence/sqlite-wal.ts","../src/internal/persistence/sqlite-open.ts"],"names":[],"mappings":"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","file":"chunk-CQ2TQ32Y.js","sourcesContent":["/**\n * FTS5 query sanitization + CJK detection (ADR D64).\n *\n * Port of Hermes' 6-step sanitizer (`hermes_state.py:1797-1847`). Prevents\n * crashes on user inputs with hyphens, dots, underscores, and unmatched\n * specials. Auto-quotes identifier-shaped tokens so `error-code` finds\n * literal `error-code` instead of `error AND code`.\n *\n * CJK detection returns true for inputs containing characters in the main\n * CJK Unicode ranges (Chinese, Japanese, Korean). CJK trigram routing is\n * deferred to v1.4 — callers receiving `containsCjk === true` should\n * short-circuit to an empty result or LIKE fallback for v1.3.\n *\n * @internal\n */\n\n// Control-char sentinels for the phrase-preservation placeholder. U+0001\n// and U+0002 are essentially never present in real user queries, and\n// crucially do NOT form word boundaries / `\\w` characters, so Step 5's\n// auto-quote regex (`\\b\\w+[-._]\\w[\\w\\-._]*\\b`) cannot match them.\n// Choosing `__PHRASE_N__` instead would re-trigger Step 5 on the second\n// sanitize pass and break idempotence.\nconst PHRASE_OPEN = \"\u0001\";\nconst PHRASE_CLOSE = \"\u0002\";\n\n/**\n * Six-step FTS5 query sanitizer. Returns a query string safe for passing\n * to `WHERE <fts5_table> MATCH ?` as a parameter.\n *\n * Returns empty string when the input contains only specials (caller MUST\n * short-circuit to avoid runtime SQL error — EC-3).\n *\n */\nexport function sanitizeFts5Query(query: string): string {\n if (query.length === 0) return query;\n\n // Step 1: preserve \"quoted phrases\" via control-char placeholders.\n const phrases: string[] = [];\n let text = query.replace(/\"[^\"]+\"/g, (match) => {\n phrases.push(match);\n return `${PHRASE_OPEN}${phrases.length - 1}${PHRASE_CLOSE}`;\n });\n\n // Step 2: strip unmatched specials (brackets, braces, parens, double quotes, caret).\n text = text.replace(/[[\\]{}()\"^]/g, \" \");\n\n // Step 3: collapse repeated asterisks (FTS5 prefix operator is single `*`).\n text = text.replace(/\\*+/g, \"*\");\n\n // Step 4: strip dangling boolean operators (AND/OR/NOT) at start/end.\n text = text.replace(/^\\s*(AND|OR|NOT)\\s+/i, \"\");\n text = text.replace(/\\s+(AND|OR|NOT)\\s*$/i, \"\");\n\n // Step 5: auto-quote identifier-shaped tokens that contain `-`, `.`, or `_`.\n // FTS5 tokenizer would otherwise split them as boolean conjunctions.\n text = text.replace(/\\b\\w+[-._]\\w[\\w\\-._]*\\b/g, (match) => `\"${match}\"`);\n\n // Step 6: restore preserved phrases.\n for (let i = 0; i < phrases.length; i += 1) {\n text = text.replace(`${PHRASE_OPEN}${i}${PHRASE_CLOSE}`, phrases[i] ?? \"\");\n }\n\n return text.trim();\n}\n\n// CJK code-point ranges. Coverage matches Hermes' coarse detection for v1.3;\n// fine-grained trigram routing comes in v1.4.\nconst CJK_RANGES: ReadonlyArray<readonly [number, number]> = [\n [0x3000, 0x303f], // CJK Symbols and Punctuation\n [0x3040, 0x309f], // Hiragana\n [0x30a0, 0x30ff], // Katakana\n [0x3400, 0x4dbf], // CJK Unified Ideographs Extension A\n [0x4e00, 0x9fff], // CJK Unified Ideographs\n [0xac00, 0xd7af], // Hangul Syllables\n];\n\n/**\n * Report whether `text` holds at least one Chinese, Japanese or Korean character.\n *\n * Iterates by code point, so surrogate pairs are handled correctly, and returns on the first hit.\n * An empty string is `false`.\n *\n * Coverage is deliberately coarse: CJK Symbols and Punctuation, Hiragana, Katakana, Hangul\n * Syllables, and CJK Unified Ideographs including Extension A. Everything beyond that — the\n * higher ideograph extensions, Halfwidth and Fullwidth Forms, Hangul Jamo — reads as `false`, so\n * a `false` is not proof that the text is CJK-free.\n *\n * The reason to ask is FTS5: the default tokenizer splits on whitespace, which CJK text does not\n * use, so a matching query against it returns nothing rather than failing. A caller seeing `true`\n * should short-circuit to an empty result or a LIKE fallback instead of running the search and\n * reporting no matches.\n *\n * Semver-exempt: reachable via the `@theokit/sdk/internal/persistence` sub-path, which the package\n * declares in `exports` but does NOT cover with its semver contract.\n */\nexport function containsCjk(text: string): boolean {\n for (const char of text) {\n const cp = char.codePointAt(0);\n if (cp === undefined) continue;\n for (const [lo, hi] of CJK_RANGES) {\n if (cp >= lo && cp <= hi) return true;\n }\n }\n return false;\n}\n","/**\n * SQLite WAL mode helper with NFS/SMB/FUSE fallback to DELETE (ADR D63).\n *\n * WAL is faster (concurrent readers + one writer) but unsupported on some\n * network/FUSE filesystems. Try WAL; if the pragma returns something else\n * or throws, fall back to DELETE journal mode. Warn one time per label.\n *\n * This block is the MODULE header and must stay at offset 0. Sitting below the import it became a\n * leading comment of the first declaration instead, which is how its tag deleted `PragmaCapable`\n * from the emitted `.d.ts` while `applyWalWithFallback` — which names it — survived.\n */\n\nimport { diag } from \"../diagnostics.js\";\n\n/**\n * The narrow slice of a SQLite handle this module needs: anything with a `pragma()` method, which\n * `better-sqlite3` satisfies without being named here.\n *\n * Not exported, but it appears in the signature of `applyWalWithFallback`, so it is emitted into\n * the published declarations and a consumer can structurally satisfy it.\n */\ninterface PragmaCapable {\n pragma: (statement: string, options?: { simple?: boolean }) => unknown;\n}\n\n/**\n * What journal mode a connection ended up in after `applyWalWithFallback`.\n *\n * `mode` is the mode actually in effect, never the one that was requested. `fellBack` is `true`\n * only when WAL was attempted and refused — either the pragma threw or it reported a mode other\n * than `wal` — and the connection was put into DELETE instead.\n *\n * `fellBack: true` is normal on NFS, SMB and FUSE, where WAL needs shared memory the filesystem\n * does not provide. It is not an error and nothing further is required of the caller; the\n * consequence is slower concurrent access, since DELETE mode does not allow readers alongside a\n * writer. Treat it as a signal about the storage, not about the database.\n *\n * @public — re-exported from the semver-protected `@theokit/sdk/persistence` barrel, and (for\n * back-compat) from the semver-exempt `@theokit/sdk/internal/persistence` alias.\n */\nexport interface WalApplyResult {\n /** Final journal_mode actually in effect. */\n mode: \"wal\" | \"delete\";\n /** True if we wanted WAL but the filesystem refused. */\n fellBack: boolean;\n}\n\nconst warnedLabels = new Set<string>();\n\n/**\n * Apply WAL mode with DELETE fallback. Idempotent — safe to call multiple\n * times on the same connection.\n *\n * @param db any `pragma()`-capable SQLite handle (e.g., `better-sqlite3`)\n * @param label short identifier used in the warning (e.g., \"memory-index\")\n *\n */\nexport function applyWalWithFallback(db: PragmaCapable, label: string): WalApplyResult {\n try {\n const result = db.pragma(\"journal_mode = WAL\", { simple: true });\n if (typeof result === \"string\" && result.toLowerCase() === \"wal\") {\n return { mode: \"wal\", fellBack: false };\n }\n logFallback(label, `got \"${String(result)}\" instead of \"wal\"`);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n logFallback(label, msg);\n }\n\n db.pragma(\"journal_mode = DELETE\");\n return { mode: \"delete\", fellBack: true };\n}\n\nfunction logFallback(label: string, reason: string): void {\n if (warnedLabels.has(label)) return;\n warnedLabels.add(label);\n diag(\n `[theokit-sdk] ${label}: WAL unavailable (${reason}); using DELETE journal mode. ` +\n \"This is normal on NFS/SMB/FUSE; expect slightly slower concurrent access.\\n\",\n );\n}\n\n/**\n * Test helper — clears the warn-once registry.\n *\n * @internal\n */\nexport function _resetWalWarnings(): void {\n warnedLabels.clear();\n}\n","/**\n * Resilient SQLite open (plan m0-foundation-expose-primitives, M0-5).\n *\n * Generalizes the driver-load + WAL-apply + corruption-recovery logic that was\n * duplicated (byte-identical) across `sdk/internal/memory/index-db.ts` and\n * `sdk-memory/internal/index/index-db.ts`. Schema-agnostic: the caller applies\n * its own PRAGMA/SCHEMA via the `onOpen` callback.\n *\n * Corruption recovery (EC-7): when opening fails with a \"malformed\" / \"not a\n * database\" / \"encrypted\" error and `recoverCorrupt` is not false, the file is\n * renamed aside to `<path>.corrupt-<ts>` (plus its WAL/SHM siblings) and a fresh\n * DB is opened. The corrupt file is renamed, NOT backed up — the timestamped\n * `.corrupt-*` file is kept for manual recovery.\n *\n * @internal — public via `@theokit/sdk/internal/persistence` (semver-exempt)\n */\n\nimport { mkdir, rename } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\n\nimport { ConfigurationError } from \"../../errors.js\";\nimport { diag } from \"../diagnostics.js\";\nimport { applyWalWithFallback } from \"./sqlite-wal.js\";\n\n/** Minimal SQLite handle surface every driver (`better-sqlite3`) exposes. */\nexport interface ResilientSqliteDb {\n /** SQLite `pragma()` access (used by `applyWalWithFallback`). */\n pragma(statement: string, options?: { simple?: boolean }): unknown;\n exec(sql: string): void;\n close(): void;\n}\n\n/**\n * Input to {@link openSqliteResilient}.\n *\n * The trap is `recoverCorrupt`, whose default is ON. When the driver reports a corrupt or encrypted\n * database, the file is renamed aside and a FRESH one is opened — so the call SUCCEEDS and hands\n * back an EMPTY database. The old bytes survive on disk under the renamed path, but a caller that\n * treats a resolved promise as \"my data is here\" is wrong exactly when it matters. Pass\n * `recoverCorrupt: false` to get the corruption error thrown instead.\n *\n * Semver-exempt: reachable via the '@theokit/sdk/internal/persistence' sub-path, which the package\n * declares in 'exports' but does NOT cover with its semver contract.\n *\n * @typeParam T - the concrete DB handle the driver returns; defaults to {@link ResilientSqliteDb}\n */\nexport interface OpenSqliteResilientOptions<T extends ResilientSqliteDb> {\n /** Absolute path to the SQLite file. Parent directories are created. */\n filePath: string;\n /**\n * Called after the driver is open and WAL is applied, before the handle is\n * returned. Apply PRAGMA/SCHEMA statements here. Errors propagate.\n */\n onOpen?: (db: T) => void | Promise<void>;\n /** Label used in the WAL-fallback warning and corruption-recovery log. Default \"sqlite\". */\n label?: string;\n /** When true (default) a corruption error renames the file aside and rebuilds. */\n recoverCorrupt?: boolean;\n}\n\n/**\n * Open a SQLite file with WAL (+ DELETE fallback) and corruption recovery.\n *\n * @typeParam T - the concrete DB handle type the driver returns (defaults to the\n * minimal {@link ResilientSqliteDb} surface)\n */\nexport async function openSqliteResilient<T extends ResilientSqliteDb = ResilientSqliteDb>(\n options: OpenSqliteResilientOptions<T>,\n): Promise<T> {\n await mkdir(dirname(options.filePath), { recursive: true });\n try {\n return await openConcrete(options);\n } catch (cause) {\n if (options.recoverCorrupt !== false && isCorruptionError(cause)) {\n await renameAside(options.filePath, options.label ?? \"sqlite\");\n return await openConcrete(options);\n }\n throw cause;\n }\n}\n\nasync function openConcrete<T extends ResilientSqliteDb>(\n options: OpenSqliteResilientOptions<T>,\n): Promise<T> {\n const db = await loadDriver<T>(options.filePath);\n // Apply WAL with NFS/SMB/FUSE fallback BEFORE schema so the journal mode is\n // set for the whole session.\n applyWalWithFallback(db, options.label ?? \"sqlite\");\n await options.onOpen?.(db);\n return db;\n}\n\n/** Injectable driver loaders (tests simulate a consumer env without better-sqlite3). */\ninterface DriverLoaders {\n betterSqlite3?: () => Promise<unknown>;\n nodeSqlite?: () => Promise<unknown>;\n}\nlet driverLoaderOverrides: DriverLoaders | undefined;\n\n/** Test-only. @internal */\nexport function _setDriverLoadersForTests(overrides: DriverLoaders | undefined): void {\n driverLoaderOverrides = overrides;\n}\n\n/**\n * Adapt `node:sqlite`'s `DatabaseSync` to the better-sqlite3 surface this module's callers use\n * (`prepare/get/all/run`, `exec`, `close`, `pragma`, `loadExtension`). The error message below has\n * ALWAYS promised this fallback (\"or run on Node 22.5+ for built-in node:sqlite\") — before the\n * flicker-bug fix the promise was fabricated: only better-sqlite3 was ever tried, so every consumer\n * without the optional native dep lost memory tools AND got a per-turn stderr WARN.\n */\nfunction adaptNodeSqlite(db: {\n prepare(sql: string): unknown;\n exec(sql: string): void;\n close(): void;\n loadExtension?: (path: string) => void;\n}): ResilientSqliteDb {\n const pragma = (statement: string, options?: { simple?: boolean }): unknown => {\n const stmt = db.prepare(`PRAGMA ${statement}`) as {\n get(): Record<string, unknown> | undefined;\n };\n const row = stmt.get();\n if (options?.simple === true) {\n return row === undefined ? undefined : Object.values(row)[0];\n }\n return row === undefined ? [] : [row];\n };\n return new Proxy(db as unknown as ResilientSqliteDb, {\n get(target, prop, receiver) {\n if (prop === \"pragma\") return pragma;\n if (prop === \"loadExtension\" && typeof db.loadExtension !== \"function\") {\n return () => {\n throw new Error(\n \"SQLite extension loading is unavailable on the node:sqlite fallback — install better-sqlite3 for sqlite-vec\",\n );\n };\n }\n const value = Reflect.get(target, prop, receiver) as unknown;\n return typeof value === \"function\"\n ? (value as (...a: unknown[]) => unknown).bind(target)\n : value;\n },\n });\n}\n\n// PRE-EXISTING debt, exposed when M75 fixed the Biome config that used to abort before\n// sweeping these files (a nested root under refactor/). It is not new code and was not touched\n// by M75; refactoring SDK internals without review would trade a visible problem for a diff\n// risky. Tracked in usetheodev/theokit-sdk#151.\n// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: see the reason just above\nasync function loadDriver<T extends ResilientSqliteDb>(filePath: string): Promise<T> {\n let betterSqliteCause: unknown;\n try {\n const mod = (await (driverLoaderOverrides?.betterSqlite3?.() ?? import(\"better-sqlite3\"))) as {\n default?: unknown;\n };\n const Ctor = mod.default ?? mod;\n if (typeof Ctor !== \"function\") {\n throw new Error(`better-sqlite3 export is not a constructor (got ${typeof Ctor})`);\n }\n return new (Ctor as new (path: string) => unknown)(filePath) as T;\n } catch (cause) {\n betterSqliteCause = cause;\n }\n // Fallback: the Node 22.5+ built-in driver (the path the error message documents).\n // `process.getBuiltinModule` (Node 22.3+) instead of `import(\"node:sqlite\")` — bundlers that\n // predate the sqlite builtin rewrite the import specifier to a bare \"sqlite\" package (proven in\n // the published dist: \"Cannot find package 'sqlite'\"), while getBuiltinModule is opaque to them.\n try {\n const mod = (await (driverLoaderOverrides?.nodeSqlite?.() ??\n Promise.resolve(\n (process as { getBuiltinModule?: (id: string) => unknown }).getBuiltinModule?.(\n \"node:sqlite\",\n ) ??\n (() => {\n throw new Error(\"node:sqlite built-in unavailable (Node < 22.3)\");\n })(),\n ))) as {\n DatabaseSync: new (\n path: string,\n ) => {\n prepare(sql: string): unknown;\n exec(sql: string): void;\n close(): void;\n };\n };\n return adaptNodeSqlite(new mod.DatabaseSync(filePath)) as T;\n } catch (nodeSqliteCause) {\n const b =\n betterSqliteCause instanceof Error ? betterSqliteCause.message : String(betterSqliteCause);\n const n = nodeSqliteCause instanceof Error ? nodeSqliteCause.message : String(nodeSqliteCause);\n throw new ConfigurationError(\n `Failed to load SQLite driver. Install \\`better-sqlite3\\` or run on Node 22.5+ for built-in \\`node:sqlite\\`. better-sqlite3: ${b}; node:sqlite: ${n}`,\n { code: \"sqlite_driver_unavailable\", cause: nodeSqliteCause },\n );\n }\n}\n\n/** True when an open error indicates an unreadable / corrupt database file. */\nexport function isCorruptionError(cause: unknown): boolean {\n if (!(cause instanceof Error)) return false;\n const msg = cause.message.toLowerCase();\n return (\n msg.includes(\"malformed\") ||\n msg.includes(\"not a database\") ||\n msg.includes(\"encrypted\") ||\n msg.includes(\"disk image is malformed\")\n );\n}\n\nasync function renameAside(filePath: string, label: string): Promise<void> {\n const asidePath = `${filePath}.corrupt-${Date.now()}`;\n await rename(filePath, asidePath).catch(() => undefined);\n await rename(`${filePath}-wal`, `${asidePath}-wal`).catch(() => undefined);\n await rename(`${filePath}-shm`, `${asidePath}-shm`).catch(() => undefined);\n diag(\n `[theokit-sdk] ${label} database corrupt; renamed aside to ${asidePath} and rebuilt schema\\n`,\n );\n}\n"]}
@@ -1,11 +1,11 @@
1
1
  'use strict';
2
2
 
3
- var chunkLPVIRJVF_cjs = require('./chunk-LPVIRJVF.cjs');
3
+ var chunkK3FW2XZD_cjs = require('./chunk-K3FW2XZD.cjs');
4
4
 
5
5
  // src/internal/runtime/concurrency/async-semaphore.ts
6
6
  function createSemaphore(permits) {
7
7
  if (!Number.isInteger(permits) || permits < 1) {
8
- throw new chunkLPVIRJVF_cjs.ConfigurationError(
8
+ throw new chunkK3FW2XZD_cjs.ConfigurationError(
9
9
  `async-semaphore: permits must be a positive integer, got ${permits}`,
10
10
  { code: "invalid_concurrency" }
11
11
  );
@@ -41,5 +41,5 @@ function createSemaphore(permits) {
41
41
  }
42
42
 
43
43
  exports.createSemaphore = createSemaphore;
44
- //# sourceMappingURL=chunk-C5DEO6OI.cjs.map
45
- //# sourceMappingURL=chunk-C5DEO6OI.cjs.map
44
+ //# sourceMappingURL=chunk-CQGYNZ3K.cjs.map
45
+ //# sourceMappingURL=chunk-CQGYNZ3K.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/internal/runtime/concurrency/async-semaphore.ts"],"names":["ConfigurationError"],"mappings":";;;;;AA2BO,SAAS,gBAAgB,OAAA,EAAiC;AAC/D,EAAA,IAAI,CAAC,MAAA,CAAO,SAAA,CAAU,OAAO,CAAA,IAAK,UAAU,CAAA,EAAG;AAC7C,IAAA,MAAM,IAAIA,oCAAA;AAAA,MACR,4DAA4D,OAAO,CAAA,CAAA;AAAA,MACnE,EAAE,MAAM,qBAAA;AAAsB,KAChC;AAAA,EACF;AACA,EAAA,IAAI,MAAA,GAAS,CAAA;AACb,EAAA,MAAM,QAA2B,EAAC;AAElC,EAAA,SAAS,QAAA,GAAiB;AACxB,IAAA,IAAI,MAAA,GAAS,OAAA,IAAW,KAAA,CAAM,MAAA,GAAS,CAAA,EAAG;AACxC,MAAA,MAAM,OAAA,GAAU,MAAM,KAAA,EAAM;AAC5B,MAAA,IAAI,YAAY,MAAA,EAAW;AACzB,QAAA,MAAA,IAAU,CAAA;AACV,QAAA,OAAA,EAAQ;AAAA,MACV;AAAA,IACF;AAAA,EACF;AAEA,EAAA,OAAO;AAAA,IACL,UAAU,MAAM,MAAA;AAAA,IAChB,OAAA,EAAS,MAAM,KAAA,CAAM,MAAA,GAAS,MAAA;AAAA,IAC9B,MAAM,OAAA,GAAU;AACd,MAAA,MAAM,IAAI,OAAA,CAAc,CAAC,OAAA,KAAY;AACnC,QAAA,KAAA,CAAM,KAAK,OAAO,CAAA;AAClB,QAAA,QAAA,EAAS;AAAA,MACX,CAAC,CAAA;AACD,MAAA,IAAI,QAAA,GAAW,KAAA;AACf,MAAA,OAAO,MAAM;AACX,QAAA,IAAI,QAAA,EAAU;AACd,QAAA,QAAA,GAAW,IAAA;AACX,QAAA,MAAA,IAAU,CAAA;AACV,QAAA,QAAA,EAAS;AAAA,MACX,CAAA;AAAA,IACF;AAAA,GACF;AACF","file":"chunk-C5DEO6OI.cjs","sourcesContent":["/**\n * Async-aware counting semaphore (ADR D135).\n *\n * N-permit gate for cooperative concurrency control inside a single\n * Node process. Used by `Agent.batch` to bound parallel agent count\n * without pulling in `p-limit` or `p-queue` (~30 LoC in-house).\n *\n * Contract: `acquire()` returns a release function. Caller MUST call\n * release exactly once when done — typically in a `finally` block.\n * Release is idempotent (multiple calls are no-ops after the first)\n * for defense against caller bugs, but leaking the release function\n * permanently consumes one permit (EC-G — caller responsibility).\n *\n * @internal\n */\n\nimport { ConfigurationError } from \"../../../errors.js\";\n\nexport interface AsyncSemaphore {\n /** Acquire a permit. Returns the release function (call once). */\n acquire(): Promise<() => void>;\n /** Permits currently held in flight. */\n inFlight(): number;\n /** Total: in-flight + queued waiters. */\n pending(): number;\n}\n\nexport function createSemaphore(permits: number): AsyncSemaphore {\n if (!Number.isInteger(permits) || permits < 1) {\n throw new ConfigurationError(\n `async-semaphore: permits must be a positive integer, got ${permits}`,\n { code: \"invalid_concurrency\" },\n );\n }\n let active = 0;\n const queue: Array<() => void> = [];\n\n function tryGrant(): void {\n if (active < permits && queue.length > 0) {\n const resolve = queue.shift();\n if (resolve !== undefined) {\n active += 1;\n resolve();\n }\n }\n }\n\n return {\n inFlight: () => active,\n pending: () => queue.length + active,\n async acquire() {\n await new Promise<void>((resolve) => {\n queue.push(resolve);\n tryGrant();\n });\n let released = false;\n return () => {\n if (released) return;\n released = true;\n active -= 1;\n tryGrant();\n };\n },\n };\n}\n"]}
1
+ {"version":3,"sources":["../src/internal/runtime/concurrency/async-semaphore.ts"],"names":["ConfigurationError"],"mappings":";;;;;AA2BO,SAAS,gBAAgB,OAAA,EAAiC;AAC/D,EAAA,IAAI,CAAC,MAAA,CAAO,SAAA,CAAU,OAAO,CAAA,IAAK,UAAU,CAAA,EAAG;AAC7C,IAAA,MAAM,IAAIA,oCAAA;AAAA,MACR,4DAA4D,OAAO,CAAA,CAAA;AAAA,MACnE,EAAE,MAAM,qBAAA;AAAsB,KAChC;AAAA,EACF;AACA,EAAA,IAAI,MAAA,GAAS,CAAA;AACb,EAAA,MAAM,QAA2B,EAAC;AAElC,EAAA,SAAS,QAAA,GAAiB;AACxB,IAAA,IAAI,MAAA,GAAS,OAAA,IAAW,KAAA,CAAM,MAAA,GAAS,CAAA,EAAG;AACxC,MAAA,MAAM,OAAA,GAAU,MAAM,KAAA,EAAM;AAC5B,MAAA,IAAI,YAAY,MAAA,EAAW;AACzB,QAAA,MAAA,IAAU,CAAA;AACV,QAAA,OAAA,EAAQ;AAAA,MACV;AAAA,IACF;AAAA,EACF;AAEA,EAAA,OAAO;AAAA,IACL,UAAU,MAAM,MAAA;AAAA,IAChB,OAAA,EAAS,MAAM,KAAA,CAAM,MAAA,GAAS,MAAA;AAAA,IAC9B,MAAM,OAAA,GAAU;AACd,MAAA,MAAM,IAAI,OAAA,CAAc,CAAC,OAAA,KAAY;AACnC,QAAA,KAAA,CAAM,KAAK,OAAO,CAAA;AAClB,QAAA,QAAA,EAAS;AAAA,MACX,CAAC,CAAA;AACD,MAAA,IAAI,QAAA,GAAW,KAAA;AACf,MAAA,OAAO,MAAM;AACX,QAAA,IAAI,QAAA,EAAU;AACd,QAAA,QAAA,GAAW,IAAA;AACX,QAAA,MAAA,IAAU,CAAA;AACV,QAAA,QAAA,EAAS;AAAA,MACX,CAAA;AAAA,IACF;AAAA,GACF;AACF","file":"chunk-CQGYNZ3K.cjs","sourcesContent":["/**\n * Async-aware counting semaphore (ADR D135).\n *\n * N-permit gate for cooperative concurrency control inside a single\n * Node process. Used by `Agent.batch` to bound parallel agent count\n * without pulling in `p-limit` or `p-queue` (~30 LoC in-house).\n *\n * Contract: `acquire()` returns a release function. Caller MUST call\n * release exactly once when done — typically in a `finally` block.\n * Release is idempotent (multiple calls are no-ops after the first)\n * for defense against caller bugs, but leaking the release function\n * permanently consumes one permit (EC-G — caller responsibility).\n *\n * @internal\n */\n\nimport { ConfigurationError } from \"../../../errors.js\";\n\nexport interface AsyncSemaphore {\n /** Acquire a permit. Returns the release function (call once). */\n acquire(): Promise<() => void>;\n /** Permits currently held in flight. */\n inFlight(): number;\n /** Total: in-flight + queued waiters. */\n pending(): number;\n}\n\nexport function createSemaphore(permits: number): AsyncSemaphore {\n if (!Number.isInteger(permits) || permits < 1) {\n throw new ConfigurationError(\n `async-semaphore: permits must be a positive integer, got ${permits}`,\n { code: \"invalid_concurrency\" },\n );\n }\n let active = 0;\n const queue: Array<() => void> = [];\n\n function tryGrant(): void {\n if (active < permits && queue.length > 0) {\n const resolve = queue.shift();\n if (resolve !== undefined) {\n active += 1;\n resolve();\n }\n }\n }\n\n return {\n inFlight: () => active,\n pending: () => queue.length + active,\n async acquire() {\n await new Promise<void>((resolve) => {\n queue.push(resolve);\n tryGrant();\n });\n let released = false;\n return () => {\n if (released) return;\n released = true;\n active -= 1;\n tryGrant();\n };\n },\n };\n}\n"]}
@@ -1,10 +1,10 @@
1
1
  'use strict';
2
2
 
3
- var chunkY4AXQOT4_cjs = require('./chunk-Y4AXQOT4.cjs');
3
+ var chunkJHPGF3FP_cjs = require('./chunk-JHPGF3FP.cjs');
4
4
 
5
5
  // src/internal/session/agent-session-store.ts
6
6
  function seedTranscript(prior, opts) {
7
- return chunkY4AXQOT4_cjs.SessionTranscript.fromRecords(prior, opts);
7
+ return chunkJHPGF3FP_cjs.SessionTranscript.fromRecords(prior, opts);
8
8
  }
9
9
  function applyThinkingStep(assistant, message) {
10
10
  assistant.thinking = message.text;
@@ -46,7 +46,7 @@ function appendConversation(transcript, conversation) {
46
46
  }
47
47
  async function readSessionMessages(store, agentId) {
48
48
  const records = await store.readRecords(agentId);
49
- return chunkY4AXQOT4_cjs.reconstructMessages(records).map(narrowToSessionMessage);
49
+ return chunkJHPGF3FP_cjs.reconstructMessages(records).map(narrowToSessionMessage);
50
50
  }
51
51
  function partToText(p) {
52
52
  if (p.type === "text") return p.text ?? "";
@@ -105,5 +105,5 @@ async function appendCompactBoundaryRecord(store, loc, sessionId, meta) {
105
105
  exports.appendCompactBoundaryRecord = appendCompactBoundaryRecord;
106
106
  exports.persistTurn = persistTurn;
107
107
  exports.readSessionMessages = readSessionMessages;
108
- //# sourceMappingURL=chunk-D75S2X6I.cjs.map
109
- //# sourceMappingURL=chunk-D75S2X6I.cjs.map
108
+ //# sourceMappingURL=chunk-CTCGWIUD.cjs.map
109
+ //# sourceMappingURL=chunk-CTCGWIUD.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/internal/session/agent-session-store.ts"],"names":["SessionTranscript","reconstructMessages"],"mappings":"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","file":"chunk-D75S2X6I.cjs","sourcesContent":["/**\n * SE40 — native session store over the Claude-shaped `.jsonl` transcript.\n *\n * The theokit session format IS the Claude Code record shape (see\n * `../../persistence/session-transcript.ts`). This module owns the FS lifecycle:\n * read existing records, seed a {@link SessionTranscript}'s parent chain, append\n * the new turn (user + assistant/tool blocks), and write append-only. Compaction\n * appends a `compact_boundary` record (a new root) — it NEVER shrinks the line\n * set (that would break the DAG). Reads reconstruct `LlmMessage[]` via\n * {@link reconstructMessages}, narrowed to the in-memory {@link SessionMessage}.\n *\n * @internal\n */\n\nimport type { ToolResultContentBlock } from \"../../types/content-blocks.js\";\nimport type { ConversationStep, ConversationTurn } from \"../../types/conversation.js\";\nimport type { SessionStore } from \"../../types/session-store.js\";\nimport {\n type AssistantTurn,\n reconstructMessages,\n type SessionRecord,\n SessionTranscript,\n} from \"../persistence/session-transcript.js\";\nimport type { SessionMessage, SessionMessagePart } from \"./session-types.js\";\n\n/**\n * Seed a {@link SessionTranscript} from the already-on-disk records so a new\n * append parents correctly on the existing DAG leaf. The transcript re-emits the\n * seeded records verbatim before the new turn, so the whole file rewrites atomically\n * as one append-only line set. Returns the transcript primed with the prior records.\n */\nfunction seedTranscript(\n prior: readonly SessionRecord[],\n opts: { cwd: string; sessionId: string; model: string },\n): SessionTranscript {\n return SessionTranscript.fromRecords(prior, opts);\n}\n\n/** The turn to persist: the user's text plus the rich per-turn conversation view. */\nexport interface PersistTurnInput {\n userText: string;\n conversation: readonly ConversationTurn[];\n /**\n * M50 — when supplied, size-driven auto-compaction runs in the SAME write chain after the turn\n * persists (usage real vs the model's context window; summarizer injected by the caller).\n */\n autoCompact?: {\n usageTotal?: number | undefined;\n contextWindow?: number | undefined;\n summarize: (\n messages: readonly import(\"../../compaction.js\").CompressibleMessage[],\n ) => Promise<string>;\n };\n}\n\ninterface MappedTurn {\n assistant: AssistantTurn;\n toolResults: Array<{ toolUseId: string; content: string; isError?: boolean }>;\n}\n\n/**\n * theokit#122 — record the turn's thinking block, signature included.\n *\n * The signature is what makes the block replayable: without it the resumed turn is rejected by\n * Anthropic with `400 \"thinking blocks cannot be modified\"`.\n */\nfunction applyThinkingStep(\n assistant: AssistantTurn,\n message: { text: string; signature?: string },\n): void {\n assistant.thinking = message.text;\n if (message.signature !== undefined) assistant.thinkingSignature = message.signature;\n}\n\n/** Fold one agent turn's steps into an assistant record + paired tool results. */\nfunction mapAgentTurn(steps: readonly ConversationStep[]): MappedTurn {\n const assistant: AssistantTurn = {};\n const toolResults: MappedTurn[\"toolResults\"] = [];\n const toolCalls: NonNullable<AssistantTurn[\"toolCalls\"]> = [];\n for (const step of steps) {\n if (step.type === \"thinkingMessage\") applyThinkingStep(assistant, step.message);\n else if (step.type === \"assistantMessage\") assistant.text = step.message.text;\n else if (step.type === \"toolCall\")\n toolCalls.push({\n id: step.message.callId,\n name: step.message.name,\n input: (step.message.args as Record<string, unknown> | undefined) ?? {},\n });\n else\n toolResults.push({\n toolUseId: step.message.callId,\n content: step.message.result,\n isError: step.message.isError,\n });\n }\n if (toolCalls.length > 0) assistant.toolCalls = toolCalls;\n return { assistant, toolResults };\n}\n\n/** True when the assistant record carries any content worth emitting. */\nfunction hasAssistantContent(a: AssistantTurn): boolean {\n return a.text !== undefined || a.thinking !== undefined || (a.toolCalls?.length ?? 0) > 0;\n}\n\n/**\n * Map the rich `ConversationTurn[]` (from `run.conversation()`) into the native\n * assistant/tool records. One transcript turn is: an `assistant` record carrying\n * thinking + text + tool_use blocks, then (when present) a `user` record carrying\n * the paired tool_result blocks. Tool results pair with tool_use by `callId`.\n */\nfunction appendConversation(\n transcript: SessionTranscript,\n conversation: readonly ConversationTurn[],\n): void {\n for (const ct of conversation) {\n if (ct.type !== \"agentConversationTurn\") continue;\n const { assistant, toolResults } = mapAgentTurn(ct.turn.steps);\n if (hasAssistantContent(assistant)) transcript.appendAssistantTurn(assistant);\n if (toolResults.length > 0) transcript.appendToolResults(toolResults);\n }\n}\n\n/**\n * The per-agent transcript metadata used to seed a {@link SessionTranscript}. The\n * actual record I/O goes through the injected {@link SessionStore} (SE41), so this\n * no longer carries a `baseDir` — the store is already bound to its location.\n */\nexport interface TranscriptLocation {\n cwd: string;\n agentId: string;\n model: string;\n}\n\n/**\n * Read the session's records via the {@link SessionStore} and reconstruct the\n * resumable history, narrowed to the in-memory {@link SessionMessage} shape\n * (user/assistant text). Tool turns fold into assistant-role context so resume\n * keeps tool history. Works identically for the FS default and an external store.\n */\nexport async function readSessionMessages(\n store: SessionStore,\n agentId: string,\n): Promise<SessionMessage[]> {\n const records = await store.readRecords(agentId);\n return reconstructMessages(records).map(narrowToSessionMessage);\n}\n\ntype NarrowPart = {\n type: string;\n text?: string;\n content?: unknown;\n name?: string;\n id?: string;\n toolUseId?: string;\n input?: unknown;\n isError?: boolean;\n};\n\n/** Render one reconstructed content part as folded session text. */\nfunction partToText(p: NarrowPart): string {\n if (p.type === \"text\") return p.text ?? \"\";\n if (p.type === \"tool_use\") return `[tool call] ${p.name ?? \"\"}`;\n if (p.type === \"tool_result\") {\n const body = typeof p.content === \"string\" ? p.content : JSON.stringify(p.content);\n return `[tool result] ${body}`;\n }\n return \"\";\n}\n\n/**\n * theokit#146 — the same part, kept as STRUCTURE.\n *\n * `partToText` above is what the model replay wants; a host rendering tool cards needs the call id,\n * the tool name and the arguments, none of which survive `[tool call] NAME`. Both projections are\n * produced from the one reconstructed part, so they cannot drift apart.\n *\n * Returns `undefined` for a part with no display meaning (e.g. an image placeholder the session\n * projection does not model), which the caller filters out.\n */\nfunction partToStructured(p: NarrowPart): SessionMessagePart | undefined {\n if (p.type === \"text\") return { type: \"text\", text: p.text ?? \"\" };\n if (p.type === \"tool_use\") {\n return {\n type: \"tool_use\",\n id: p.id ?? \"\",\n name: p.name ?? \"\",\n input: (p.input ?? {}) as Record<string, unknown>,\n };\n }\n if (p.type === \"tool_result\") {\n return {\n type: \"tool_result\",\n toolUseId: p.toolUseId ?? \"\",\n // Reconstructed tool results carry either a string or the SE7 content blocks; both are\n // already the session shape, so this narrows `unknown` rather than converting anything.\n content: p.content as string | ReadonlyArray<ToolResultContentBlock>,\n ...(p.isError === true ? { isError: true } : {}),\n };\n }\n return undefined;\n}\n\n/** Flatten a reconstructed `LlmMessage` to the narrowed in-memory `SessionMessage`. */\nfunction narrowToSessionMessage(m: {\n role: \"system\" | \"user\" | \"assistant\";\n content: NarrowPart[];\n}): SessionMessage {\n const role = m.role === \"user\" ? \"user\" : \"assistant\";\n const text = m.content\n .map(partToText)\n .filter((s) => s.length > 0)\n .join(\"\\n\");\n const parts = m.content\n .map(partToStructured)\n .filter((p): p is SessionMessagePart => p !== undefined);\n return { role, text, parts };\n}\n\n/** The records appended by the last turn (the delta beyond the seeded prior). */\nfunction deltaRecords(\n transcript: SessionTranscript,\n priorLength: number,\n): readonly SessionRecord[] {\n return transcript.records().slice(priorLength);\n}\n\n/**\n * Persist one conversation turn (user + assistant/tool records) to the session\n * store, append-only. Reads the prior records to seed the parent chain, folds the\n * new turn, and appends ONLY the delta via {@link SessionStore.appendRecords}\n * (the store owns the append atomicity — the FS default serializes under a file\n * lock). Within one process, turns for an agent are already chained upstream, so\n * the read→append is ordered; cross-host ordering is the external store's contract.\n */\nexport async function persistTurn(\n store: SessionStore,\n loc: TranscriptLocation,\n sessionId: string,\n turn: PersistTurnInput,\n): Promise<void> {\n const prior = await store.readRecords(loc.agentId);\n const transcript = seedTranscript(prior, { cwd: loc.cwd, sessionId, model: loc.model });\n transcript.appendUserTurn(turn.userText);\n appendConversation(transcript, turn.conversation);\n await store.appendRecords(loc.agentId, deltaRecords(transcript, prior.length));\n}\n\n/**\n * Append-only compaction: add a `compact_boundary` system record (a new root) so\n * resume replays only the post-boundary continuation. Appends only the boundary\n * record via the store — NEVER rewrites or shrinks the prior records.\n */\nexport async function appendCompactBoundaryRecord(\n store: SessionStore,\n loc: TranscriptLocation,\n sessionId: string,\n meta: { preTokens: number; trigger: string },\n): Promise<void> {\n const prior = await store.readRecords(loc.agentId);\n const transcript = seedTranscript(prior, { cwd: loc.cwd, sessionId, model: loc.model });\n transcript.appendCompactBoundary(meta);\n await store.appendRecords(loc.agentId, deltaRecords(transcript, prior.length));\n}\n"]}
1
+ {"version":3,"sources":["../src/internal/session/agent-session-store.ts"],"names":["SessionTranscript","reconstructMessages"],"mappings":"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","file":"chunk-CTCGWIUD.cjs","sourcesContent":["/**\n * SE40 — native session store over the Claude-shaped `.jsonl` transcript.\n *\n * The theokit session format IS the Claude Code record shape (see\n * `../../persistence/session-transcript.ts`). This module owns the FS lifecycle:\n * read existing records, seed a {@link SessionTranscript}'s parent chain, append\n * the new turn (user + assistant/tool blocks), and write append-only. Compaction\n * appends a `compact_boundary` record (a new root) — it NEVER shrinks the line\n * set (that would break the DAG). Reads reconstruct `LlmMessage[]` via\n * {@link reconstructMessages}, narrowed to the in-memory {@link SessionMessage}.\n *\n * @internal\n */\n\nimport type { ToolResultContentBlock } from \"../../types/content-blocks.js\";\nimport type { ConversationStep, ConversationTurn } from \"../../types/conversation.js\";\nimport type { SessionStore } from \"../../types/session-store.js\";\nimport {\n type AssistantTurn,\n reconstructMessages,\n type SessionRecord,\n SessionTranscript,\n} from \"../persistence/session-transcript.js\";\nimport type { SessionMessage, SessionMessagePart } from \"./session-types.js\";\n\n/**\n * Seed a {@link SessionTranscript} from the already-on-disk records so a new\n * append parents correctly on the existing DAG leaf. The transcript re-emits the\n * seeded records verbatim before the new turn, so the whole file rewrites atomically\n * as one append-only line set. Returns the transcript primed with the prior records.\n */\nfunction seedTranscript(\n prior: readonly SessionRecord[],\n opts: { cwd: string; sessionId: string; model: string },\n): SessionTranscript {\n return SessionTranscript.fromRecords(prior, opts);\n}\n\n/** The turn to persist: the user's text plus the rich per-turn conversation view. */\nexport interface PersistTurnInput {\n userText: string;\n conversation: readonly ConversationTurn[];\n /**\n * M50 — when supplied, size-driven auto-compaction runs in the SAME write chain after the turn\n * persists (usage real vs the model's context window; summarizer injected by the caller).\n */\n autoCompact?: {\n usageTotal?: number | undefined;\n contextWindow?: number | undefined;\n summarize: (\n messages: readonly import(\"../../compaction.js\").CompressibleMessage[],\n ) => Promise<string>;\n };\n}\n\ninterface MappedTurn {\n assistant: AssistantTurn;\n toolResults: Array<{ toolUseId: string; content: string; isError?: boolean }>;\n}\n\n/**\n * theokit#122 — record the turn's thinking block, signature included.\n *\n * The signature is what makes the block replayable: without it the resumed turn is rejected by\n * Anthropic with `400 \"thinking blocks cannot be modified\"`.\n */\nfunction applyThinkingStep(\n assistant: AssistantTurn,\n message: { text: string; signature?: string },\n): void {\n assistant.thinking = message.text;\n if (message.signature !== undefined) assistant.thinkingSignature = message.signature;\n}\n\n/** Fold one agent turn's steps into an assistant record + paired tool results. */\nfunction mapAgentTurn(steps: readonly ConversationStep[]): MappedTurn {\n const assistant: AssistantTurn = {};\n const toolResults: MappedTurn[\"toolResults\"] = [];\n const toolCalls: NonNullable<AssistantTurn[\"toolCalls\"]> = [];\n for (const step of steps) {\n if (step.type === \"thinkingMessage\") applyThinkingStep(assistant, step.message);\n else if (step.type === \"assistantMessage\") assistant.text = step.message.text;\n else if (step.type === \"toolCall\")\n toolCalls.push({\n id: step.message.callId,\n name: step.message.name,\n input: (step.message.args as Record<string, unknown> | undefined) ?? {},\n });\n else\n toolResults.push({\n toolUseId: step.message.callId,\n content: step.message.result,\n isError: step.message.isError,\n });\n }\n if (toolCalls.length > 0) assistant.toolCalls = toolCalls;\n return { assistant, toolResults };\n}\n\n/** True when the assistant record carries any content worth emitting. */\nfunction hasAssistantContent(a: AssistantTurn): boolean {\n return a.text !== undefined || a.thinking !== undefined || (a.toolCalls?.length ?? 0) > 0;\n}\n\n/**\n * Map the rich `ConversationTurn[]` (from `run.conversation()`) into the native\n * assistant/tool records. One transcript turn is: an `assistant` record carrying\n * thinking + text + tool_use blocks, then (when present) a `user` record carrying\n * the paired tool_result blocks. Tool results pair with tool_use by `callId`.\n */\nfunction appendConversation(\n transcript: SessionTranscript,\n conversation: readonly ConversationTurn[],\n): void {\n for (const ct of conversation) {\n if (ct.type !== \"agentConversationTurn\") continue;\n const { assistant, toolResults } = mapAgentTurn(ct.turn.steps);\n if (hasAssistantContent(assistant)) transcript.appendAssistantTurn(assistant);\n if (toolResults.length > 0) transcript.appendToolResults(toolResults);\n }\n}\n\n/**\n * The per-agent transcript metadata used to seed a {@link SessionTranscript}. The\n * actual record I/O goes through the injected {@link SessionStore} (SE41), so this\n * no longer carries a `baseDir` — the store is already bound to its location.\n */\nexport interface TranscriptLocation {\n cwd: string;\n agentId: string;\n model: string;\n}\n\n/**\n * Read the session's records via the {@link SessionStore} and reconstruct the\n * resumable history, narrowed to the in-memory {@link SessionMessage} shape\n * (user/assistant text). Tool turns fold into assistant-role context so resume\n * keeps tool history. Works identically for the FS default and an external store.\n */\nexport async function readSessionMessages(\n store: SessionStore,\n agentId: string,\n): Promise<SessionMessage[]> {\n const records = await store.readRecords(agentId);\n return reconstructMessages(records).map(narrowToSessionMessage);\n}\n\ntype NarrowPart = {\n type: string;\n text?: string;\n content?: unknown;\n name?: string;\n id?: string;\n toolUseId?: string;\n input?: unknown;\n isError?: boolean;\n};\n\n/** Render one reconstructed content part as folded session text. */\nfunction partToText(p: NarrowPart): string {\n if (p.type === \"text\") return p.text ?? \"\";\n if (p.type === \"tool_use\") return `[tool call] ${p.name ?? \"\"}`;\n if (p.type === \"tool_result\") {\n const body = typeof p.content === \"string\" ? p.content : JSON.stringify(p.content);\n return `[tool result] ${body}`;\n }\n return \"\";\n}\n\n/**\n * theokit#146 — the same part, kept as STRUCTURE.\n *\n * `partToText` above is what the model replay wants; a host rendering tool cards needs the call id,\n * the tool name and the arguments, none of which survive `[tool call] NAME`. Both projections are\n * produced from the one reconstructed part, so they cannot drift apart.\n *\n * Returns `undefined` for a part with no display meaning (e.g. an image placeholder the session\n * projection does not model), which the caller filters out.\n */\nfunction partToStructured(p: NarrowPart): SessionMessagePart | undefined {\n if (p.type === \"text\") return { type: \"text\", text: p.text ?? \"\" };\n if (p.type === \"tool_use\") {\n return {\n type: \"tool_use\",\n id: p.id ?? \"\",\n name: p.name ?? \"\",\n input: (p.input ?? {}) as Record<string, unknown>,\n };\n }\n if (p.type === \"tool_result\") {\n return {\n type: \"tool_result\",\n toolUseId: p.toolUseId ?? \"\",\n // Reconstructed tool results carry either a string or the SE7 content blocks; both are\n // already the session shape, so this narrows `unknown` rather than converting anything.\n content: p.content as string | ReadonlyArray<ToolResultContentBlock>,\n ...(p.isError === true ? { isError: true } : {}),\n };\n }\n return undefined;\n}\n\n/** Flatten a reconstructed `LlmMessage` to the narrowed in-memory `SessionMessage`. */\nfunction narrowToSessionMessage(m: {\n role: \"system\" | \"user\" | \"assistant\";\n content: NarrowPart[];\n}): SessionMessage {\n const role = m.role === \"user\" ? \"user\" : \"assistant\";\n const text = m.content\n .map(partToText)\n .filter((s) => s.length > 0)\n .join(\"\\n\");\n const parts = m.content\n .map(partToStructured)\n .filter((p): p is SessionMessagePart => p !== undefined);\n return { role, text, parts };\n}\n\n/** The records appended by the last turn (the delta beyond the seeded prior). */\nfunction deltaRecords(\n transcript: SessionTranscript,\n priorLength: number,\n): readonly SessionRecord[] {\n return transcript.records().slice(priorLength);\n}\n\n/**\n * Persist one conversation turn (user + assistant/tool records) to the session\n * store, append-only. Reads the prior records to seed the parent chain, folds the\n * new turn, and appends ONLY the delta via {@link SessionStore.appendRecords}\n * (the store owns the append atomicity — the FS default serializes under a file\n * lock). Within one process, turns for an agent are already chained upstream, so\n * the read→append is ordered; cross-host ordering is the external store's contract.\n */\nexport async function persistTurn(\n store: SessionStore,\n loc: TranscriptLocation,\n sessionId: string,\n turn: PersistTurnInput,\n): Promise<void> {\n const prior = await store.readRecords(loc.agentId);\n const transcript = seedTranscript(prior, { cwd: loc.cwd, sessionId, model: loc.model });\n transcript.appendUserTurn(turn.userText);\n appendConversation(transcript, turn.conversation);\n await store.appendRecords(loc.agentId, deltaRecords(transcript, prior.length));\n}\n\n/**\n * Append-only compaction: add a `compact_boundary` system record (a new root) so\n * resume replays only the post-boundary continuation. Appends only the boundary\n * record via the store — NEVER rewrites or shrinks the prior records.\n */\nexport async function appendCompactBoundaryRecord(\n store: SessionStore,\n loc: TranscriptLocation,\n sessionId: string,\n meta: { preTokens: number; trigger: string },\n): Promise<void> {\n const prior = await store.readRecords(loc.agentId);\n const transcript = seedTranscript(prior, { cwd: loc.cwd, sessionId, model: loc.model });\n transcript.appendCompactBoundary(meta);\n await store.appendRecords(loc.agentId, deltaRecords(transcript, prior.length));\n}\n"]}
@@ -1,5 +1,5 @@
1
- import { withCwdMutex } from './chunk-2XLKLVVR.js';
2
- import { diag } from './chunk-5F5NWKPN.js';
1
+ import { withCwdMutex } from './chunk-Q5EWJPRY.js';
2
+ import { diag } from './chunk-T7O6K6PX.js';
3
3
  import { readFileSync, mkdirSync, openSync, writeSync, closeSync, fstatSync, readSync } from 'fs';
4
4
  import { dirname } from 'path';
5
5
 
@@ -175,5 +175,5 @@ function readJsonlIds(path, keyFn) {
175
175
  }
176
176
 
177
177
  export { JsonlParseError, appendJsonl, loadJsonl, readJsonlIds, withFileLock };
178
- //# sourceMappingURL=chunk-NZL4BNFQ.js.map
179
- //# sourceMappingURL=chunk-NZL4BNFQ.js.map
178
+ //# sourceMappingURL=chunk-CV7XMBHP.js.map
179
+ //# sourceMappingURL=chunk-CV7XMBHP.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/internal/persistence/file-lock.ts","../src/internal/persistence/jsonl.ts"],"names":[],"mappings":"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","file":"chunk-CV7XMBHP.js","sourcesContent":["/**\n * Cross-process file lock helper (ADR D61).\n *\n * Uses `proper-lockfile` (optional peer dep) for cross-process locks. When\n * the peer dep is absent, falls back to `withCwdMutex` (in-process only)\n * with a one-shot stderr warning.\n *\n * EC-1 fix: uses a companion `<path>.lock` file with `realpath: false` so\n * `withFileLock` works even when the target `path` does not exist yet.\n * Without this, fresh installs that lock-then-create would crash with ENOENT.\n *\n * @internal\n */\n\nimport { diag } from \"../diagnostics.js\";\nimport { withCwdMutex } from \"./cwd-mutex.js\";\n\ninterface ProperLockfileModule {\n lock: (file: string, options: ProperLockfileOptions) => Promise<() => Promise<void>>;\n}\n\ninterface ProperLockfileOptions {\n lockfilePath?: string;\n realpath?: boolean;\n stale?: number;\n retries?: {\n retries: number;\n factor?: number;\n minTimeout?: number;\n maxTimeout?: number;\n };\n}\n\nlet cached: ProperLockfileModule | null | undefined;\nlet warnedMissing = false;\nlet warnedStructural = false;\n/** Why the import failed, kept so the warning can report the observation instead of a guess (#174). */\nlet loadFailure: unknown;\n\n/** Node reports a missing module as `ERR_MODULE_NOT_FOUND` (ESM loader) or `MODULE_NOT_FOUND` (CJS). */\nfunction isModuleAbsent(err: unknown): boolean {\n const code = (err as { code?: unknown } | null | undefined)?.code;\n return code === \"ERR_MODULE_NOT_FOUND\" || code === \"MODULE_NOT_FOUND\";\n}\n\n/**\n * #174 — build the fallback warning from what actually happened.\n *\n * This used to always read \"proper-lockfile not installed\", because the import was wrapped in a\n * bare `catch` that discarded the error (Unbreakable Rule 8: a swallowed error is the dangerous\n * kind). A consumer whose package WAS installed, declared and resolvable spent a debugging session\n * re-verifying the install, because the message named a cause the code had never checked.\n *\n * Absence is now the only case that claims absence. Every other failure — a broken install, an\n * interop problem, a bundler that rewrote the specifier — reports its own code and message, which\n * is what points at the real cause.\n *\n * @internal\n */\nfunction describeLockLoadFailure(err: unknown): string {\n const consequence =\n \"cross-process file lock unavailable — concurrent processes over the same file are NOT serialized.\";\n if (isModuleAbsent(err)) {\n return `[theokit-sdk] proper-lockfile not installed; ${consequence} Install with: pnpm add proper-lockfile\\n`;\n }\n const code = (err as { code?: unknown } | null | undefined)?.code;\n const detail = err instanceof Error ? err.message : String(err);\n return (\n `[theokit-sdk] proper-lockfile could not be loaded${code !== undefined ? ` (${String(code)})` : \"\"}: ` +\n `${detail}. ${consequence} The package resolves for the SDK but failed to load — check bundling ` +\n \"and module-format interop before re-checking the install.\\n\"\n );\n}\n\n/** Test seam for the message builder — NOT in the public barrel. @internal */\nexport function __TESTING__describeLockLoadFailure(err: unknown): string {\n return describeLockLoadFailure(err);\n}\n\nasync function getProperLockfile(): Promise<ProperLockfileModule | null> {\n if (cached !== undefined) return cached;\n try {\n const mod = await import(\"proper-lockfile\");\n // T5.9 — supply-chain hardening: validate the imported module\n // exposes the API surface we depend on BEFORE caching it. A\n // tampered or incompatible version that lacks `lock`/`unlock`\n // functions gets treated as \"not installed\" with an advisory\n // warning — never silently used.\n if (!validateLockModule(mod)) {\n if (!warnedStructural) {\n warnedStructural = true;\n diag(\n \"[theokit-sdk] proper-lockfile: imported module does NOT expose \" +\n \"the expected `lock`/`unlock` API surface. This may indicate a \" +\n \"supply-chain compromise or an incompatible major version. \" +\n \"Falling back to in-process mutex (no cross-process safety). \" +\n \"Reinstall with: pnpm add proper-lockfile@^11\\n\",\n );\n }\n cached = null;\n return cached;\n }\n cached = mod as ProperLockfileModule;\n } catch (err) {\n // #174 — keep WHY. Discarding it here is what made the fallback warning assert a cause it had\n // never observed, and sent a consumer to re-check an install that was already correct.\n loadFailure = err;\n cached = null;\n }\n return cached;\n}\n\n/**\n * T5.9 — Structural validation of the dynamically-imported\n * `proper-lockfile` module. Verifies the API surface we depend on\n * (`lock` and `unlock` as functions) is present. Pure function —\n * never throws, never mutates, never performs I/O.\n *\n * Exported via `__TESTING__validateLockModule` seam so unit tests\n * can drive the check without spinning up the dynamic import.\n *\n * @internal\n */\nfunction validateLockModule(mod: unknown): boolean {\n if (mod === null || mod === undefined || typeof mod !== \"object\") return false;\n const m = mod as Record<string, unknown>;\n return typeof m.lock === \"function\" && typeof m.unlock === \"function\";\n}\n\n/**\n * T5.9 — Test seam: expose the structural validator for unit tests.\n * NOT included in the public barrel.\n *\n * @internal\n */\nexport function __TESTING__validateLockModule(mod: unknown): boolean {\n return validateLockModule(mod);\n}\n\n/**\n * T5.9 — Test seam: reset the module cache + warning flags between\n * tests so each test starts fresh. NOT included in the public barrel.\n *\n * @internal\n */\nexport function __TESTING__resetFileLockCache(): void {\n cached = undefined;\n warnedMissing = false;\n warnedStructural = false;\n loadFailure = undefined;\n}\n\n/**\n * Retry and staleness tuning for `withFileLock`.\n *\n * Every field is optional and the defaults are applied per call, so `undefined` means the default\n * rather than \"no limit\". They are handed to `proper-lockfile` and have NO effect on the fallback\n * path: when that package is absent, `withFileLock` degrades to the in-process mutex, which\n * queues indefinitely and never goes stale.\n *\n * `stale` (default 30000 ms) is how old a lock file must be before it is treated as abandoned by a\n * dead process and broken. Setting it below the longest a legitimate holder can run is what turns\n * a slow operation into two concurrent ones.\n *\n * `retries` (default 5) is the number of acquisition attempts AFTER the first, and `retryFactor`\n * (default 1.5) the backoff multiplier between them. The per-attempt wait is clamped to\n * 100–5000 ms, which the caller cannot change. Exhausting the retries rejects — it does not fall\n * through to running `fn` unlocked.\n *\n * @public — re-exported from the semver-protected `@theokit/sdk/persistence` barrel, and (for\n * back-compat) from the semver-exempt `@theokit/sdk/internal/persistence` alias.\n */\nexport interface FileLockOptions {\n /** Stale lock timeout in ms. Default 30_000 (30s). */\n stale?: number;\n /** Max retries on busy lock. Default 5. */\n retries?: number;\n /** Backoff factor between retries. Default 1.5. */\n retryFactor?: number;\n}\n\n/**\n * Run `fn` while holding an OS-level cross-process lock on `path`.\n *\n * If `proper-lockfile` is installed, uses it with a companion `<path>.lock`\n * file (`realpath: false`, so target file does NOT need to exist yet).\n * Otherwise falls back to in-process `withCwdMutex` and prints a one-shot\n * stderr warning telling the user to install `proper-lockfile` for\n * cross-process safety.\n *\n * The lock is released even when `fn` throws.\n *\n */\nexport async function withFileLock<T>(\n path: string,\n fn: () => Promise<T>,\n options?: FileLockOptions,\n): Promise<T> {\n const lib = await getProperLockfile();\n\n if (lib === null) {\n // #174 — stay silent when the structural check already explained itself. Emitting \"not\n // installed\" on top of \"does not expose lock/unlock\" would be two contradictory diagnoses of\n // one failure, and the reader has no way to tell which is true.\n if (!warnedMissing && !warnedStructural) {\n warnedMissing = true;\n diag(describeLockLoadFailure(loadFailure));\n }\n return withCwdMutex(`file-lock:${path}`, fn);\n }\n\n // proper-lockfile errors immediately on same-process concurrent acquire\n // (\"Lock file is already being held\"). Wrap with cwd-mutex first so\n // in-process callers queue and only ONE thread at a time enters the\n // cross-process acquire path. Combined: full in-process + cross-process\n // serialization.\n return withCwdMutex(`file-lock:${path}`, async () => {\n const release = await lib.lock(path, {\n // EC-1: companion lockfile, target path may not exist yet.\n lockfilePath: `${path}.lock`,\n realpath: false,\n stale: options?.stale ?? 30_000,\n retries: {\n retries: options?.retries ?? 5,\n factor: options?.retryFactor ?? 1.5,\n minTimeout: 100,\n maxTimeout: 5_000,\n },\n });\n\n try {\n return await fn();\n } finally {\n await release();\n }\n });\n}\n\n/**\n * Test helper — resets the cached proper-lockfile module + warning flag.\n * Allows tests to simulate \"module absent\" by clearing cache then\n * monkey-patching the dynamic import resolution.\n *\n * @internal\n */\nexport function _resetFileLockCacheForTesting(): void {\n cached = undefined;\n warnedMissing = false;\n}\n","/**\n * Durable JSONL primitives shared by the eval harness (M6).\n *\n * - `loadJsonl` — generic dataset reader (split/trim/skip-blank/parse) with a\n * line-numbered {@link JsonlParseError}. The dataset SCHEMA is the caller's\n * concern via `map` (M6 ADR D3) — this module owns only the parse.\n * - `appendJsonl` / `readJsonlIds` — crash-durable, resumable batch persistence\n * (M6 ADR D1): each record is appended as one whole `\\n`-terminated line the\n * instant it is produced, and a re-run resumes by skipping already-keyed rows.\n *\n * reference: knowledge-base/references/theocode-eval/lib/swebench-dataset.ts:82\n * (parseJsonl + line-N error) and swebench-batch.ts:113,205 (resume + per-line\n * flush).\n *\n * @internal\n */\nimport {\n closeSync,\n fstatSync,\n mkdirSync,\n openSync,\n readFileSync,\n readSync,\n writeSync,\n} from \"node:fs\";\nimport { dirname } from \"node:path\";\n\n/** Raised when a JSONL line is not valid JSON or is not a JSON object. Carries the 1-based line number. */\nexport class JsonlParseError extends Error {\n constructor(\n message: string,\n readonly line: number,\n ) {\n super(message);\n this.name = \"JsonlParseError\";\n }\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/** Parse a single trimmed line to a plain object, or `undefined` if blank / invalid / non-object. */\nfunction tryParseObjectLine(line: string): Record<string, unknown> | undefined {\n if (line.length === 0) return undefined;\n let parsed: unknown;\n try {\n parsed = JSON.parse(line);\n } catch {\n return undefined;\n }\n return isPlainObject(parsed) ? parsed : undefined;\n}\n\n/**\n * Parse a JSONL file into rows. Blank lines are skipped. A malformed or\n * non-object line throws {@link JsonlParseError} naming the 1-based line. When\n * `map` is provided, each raw object is mapped to the typed row (the SWE-bench\n * schema lives in the caller's `map`, per M6 ADR D3).\n */\nexport function loadJsonl<T = Record<string, unknown>>(\n path: string,\n opts: {\n map?: (raw: Record<string, unknown>, lineNumber: number) => T;\n /**\n * M81 — tolerate a truncated LAST line (a crash artifact: the process died mid-write).\n *\n * Opt-in on purpose. As a default it would also swallow corruption in the MIDDLE of the file,\n * turning loud data loss into silent data loss — the wrong trade for a session store.\n */\n tolerateTrailingPartialLine?: boolean;\n } = {},\n): T[] {\n const lines = readFileSync(path, \"utf8\").split(\"\\n\");\n const out: T[] = [];\n for (let i = 0; i < lines.length; i += 1) {\n const lineNumber = i + 1;\n const line = (lines[i] ?? \"\").trim();\n if (line.length === 0) continue;\n // M81 — `undefined` = a tolerated invalid line (the last one, truncated by a crash). Any other\n // invalid line has already thrown inside `parseLine`.\n const parsed = parseLine(\n line,\n lineNumber,\n opts.tolerateTrailingPartialLine === true && lineNumber === lines.length,\n );\n if (parsed === undefined) break;\n out.push(opts.map ? opts.map(parsed, lineNumber) : (parsed as unknown as T));\n }\n return out;\n}\n\n/**\n * Parses ONE line, returning `undefined` when it is a tolerated truncated last line.\n *\n * Extracted because `loadJsonl` went over the cognitive-complexity ceiling once it gained the\n * tolerance — and because parsing a line and iterating a file are two responsibilities that were\n * only together out of habit.\n */\nfunction parseLine(\n line: string,\n lineNumber: number,\n tolerate: boolean,\n): Record<string, unknown> | undefined {\n let parsed: unknown;\n try {\n parsed = JSON.parse(line);\n } catch {\n if (tolerate) return undefined;\n throw new JsonlParseError(`line ${lineNumber}: invalid JSON`, lineNumber);\n }\n if (!isPlainObject(parsed)) {\n throw new JsonlParseError(`line ${lineNumber}: not a JSON object`, lineNumber);\n }\n return parsed;\n}\n\n/**\n * Append one record as a whole `\\n`-terminated JSON line. Creates the parent dir\n * if missing. `appendFileSync` is synchronous, so within a single Node process\n * the event loop serializes writes and each call writes its line atomically —\n * interleave-safe for the bounded-concurrency batch runner.\n *\n * reference: swebench-batch.ts:192 (mkdir-before-append), :205 (per-line flush).\n */\nexport function appendJsonl(path: string, record: unknown): void {\n // T2.4 — `0o700` for the same reason the file below is `0o600`, and it is the half M93 missed. A\n // private file inside a group-writable directory can be replaced wholesale, and the replacement's\n // mode is whatever the writer chose. Under `umask 002` this directory was born `0775`.\n //\n // The directory sits under `~/.theokit`, shared with the credential and trust stores, and the\n // framework already wrote the diagnosis while fixing a sibling (`@theokit/agents\n // config/trust-store.ts:157-161`): the mode argument is a no-op on a directory that already\n // exists, \"and this one is shared with the SDK's transcript root — whoever creates it first sets\n // the permissions\". Whoever creates it first is usually THIS function, because a session writes a\n // transcript before it ever touches a credential. So `assertSecureModes` was not wrong to demand a\n // private directory; this path was wrong to produce one that fails it, depending on run order.\n //\n // Creation-time only, deliberately: repairing a pre-existing directory means `stat` + `chmod` on\n // every append, and this is the hot path of every session. The pre-existing case is what\n // `assertSecureModes` is for.\n mkdirSync(dirname(path), { recursive: true, mode: 0o700 });\n const prefix = needsLineBreakBefore(path) ? \"\\n\" : \"\";\n // M93 (adversarial review, H1) — `0o600`. `appendFileSync` takes no `mode`, so the permission came\n // from the umask: under `umask 022` the transcript was born `0664`, world-readable. The previous\n // path (`replaceFileAtomic`) pinned `0o600` on purpose — \"holds the FULL in-flight content\n // (credential snapshots, OAuth tokens)\" (`atomic-write.ts:107`) — and switching to append lost\n // that silently. The same class had already been caught in the consumer (`atomic-sync.ts`, M88\n // HIGH-1).\n //\n // `mode` only applies on CREATION; a pre-existing file keeps whatever permission it already has.\n const fd = openSync(path, \"a\", 0o600);\n try {\n writeSync(fd, `${prefix}${JSON.stringify(record)}\\n`);\n } finally {\n closeSync(fd);\n }\n}\n\n/**\n * Does the file end without a `\\n`? Then the last line is truncated — a crash mid-append.\n *\n * Without this check the next append **glues** itself onto the middle of the broken line, producing\n * an invalid line the reader discards: the NEW record disappears along with the partial one. The\n * previous path (read-modify-write) self-healed from this because it rewrote the whole file.\n * Measured in M93's adversarial review (H2): after an append over a truncated file, the\n * just-written record was no longer readable.\n *\n * Reads **one byte**, not the file.\n */\nfunction needsLineBreakBefore(path: string): boolean {\n let fd: number;\n try {\n fd = openSync(path, \"r\");\n } catch {\n return false; // the file does not exist yet: nothing to splice onto\n }\n try {\n const size = fstatSync(fd).size;\n if (size === 0) return false;\n const buf = Buffer.alloc(1);\n readSync(fd, buf, 0, 1, size - 1);\n return buf[0] !== 0x0a;\n } finally {\n closeSync(fd);\n }\n}\n\n/**\n * Read the set of keys from an existing JSONL file for which `keyFn(parsed)`\n * returns a non-empty string. Used to resume a crashed batch by skipping rows\n * already persisted with a successful result. A trailing partial line from an\n * interrupted append is tolerated (skipped, not thrown), and a missing file\n * yields an empty set.\n *\n * reference: swebench-batch.ts:113 (readDoneIds), :129 (success-only),\n * :131 (tolerate partial line).\n */\nexport function readJsonlIds(\n path: string,\n keyFn: (parsed: Record<string, unknown>) => string | undefined,\n): Set<string> {\n const done = new Set<string>();\n let text: string;\n try {\n text = readFileSync(path, \"utf8\");\n } catch {\n return done; // no file yet → nothing done\n }\n for (const rawLine of text.split(\"\\n\")) {\n // A trailing partial line from an interrupted run parses to undefined → skipped.\n const parsed = tryParseObjectLine(rawLine.trim());\n if (parsed === undefined) continue;\n const key = keyFn(parsed);\n if (typeof key === \"string\" && key.length > 0) done.add(key);\n }\n return done;\n}\n"]}
@@ -1,16 +1,21 @@
1
- import { LruEmbeddingCache } from './chunk-OXNYIMZZ.js';
2
- import { openSqliteResilient, sanitizeFts5Query } from './chunk-MSFLYJDY.js';
3
- import { withCwdMutex } from './chunk-2XLKLVVR.js';
4
- import { replaceFileAtomic } from './chunk-6AZDM6LK.js';
5
- import { sanitizeIdentifier, safePathJoin, safeFilenameForId } from './chunk-SK4QLUBK.js';
6
- import { ConfigurationError } from './chunk-U4UJHOSH.js';
7
- import { redactSecrets } from './chunk-5F5NWKPN.js';
1
+ import { LruEmbeddingCache } from './chunk-H73MEMQB.js';
2
+ import { sanitizeIdentifier, safePathJoin, safeFilenameForId } from './chunk-QARJGQSA.js';
3
+ import { openSqliteResilient, sanitizeFts5Query } from './chunk-CQ2TQ32Y.js';
4
+ import { withCwdMutex } from './chunk-Q5EWJPRY.js';
5
+ import { replaceFileAtomic } from './chunk-VF7EWVDG.js';
6
+ import { ConfigurationError } from './chunk-IDCKSLYH.js';
7
+ import { redactSecrets } from './chunk-T7XEKOVW.js';
8
8
  import { createHash } from 'crypto';
9
9
  import { readFile, mkdir, stat, readdir } from 'fs/promises';
10
10
  import { join, resolve, relative } from 'path';
11
11
  import { mkdirSync } from 'fs';
12
12
  import { createRequire } from 'module';
13
13
 
14
+ // src/internal/memory/escape-like-pattern.ts
15
+ function escapeLikePattern(query) {
16
+ return `%${query.replace(/\\/g, "\\\\").replace(/%/g, "\\%").replace(/_/g, "\\_")}%`;
17
+ }
18
+
14
19
  // src/internal/memory/index-schema.ts
15
20
  var SCHEMA_STATEMENTS = [
16
21
  `CREATE TABLE IF NOT EXISTS files (
@@ -845,7 +850,7 @@ var IndexManager = class _IndexManager {
845
850
  * `ftsSearch` so callers are unaware of the fallback.
846
851
  */
847
852
  likeSearchFallback(query, limit) {
848
- const pattern = `%${query.replace(/%/g, "\\%").replace(/_/g, "\\_")}%`;
853
+ const pattern = escapeLikePattern(query);
849
854
  const stmt = this.db.prepare(
850
855
  `SELECT chunks.id as id, files.rel_path as rel_path, files.source as source,
851
856
  chunks.start_line as start_line, chunks.end_line as end_line,
@@ -963,5 +968,5 @@ var IndexManager = class _IndexManager {
963
968
  };
964
969
 
965
970
  export { IndexManager, LanceIndex, appendFact, appendFactToMarkdown, defaultIndexPath, lanceStoragePath, legacyMemoryJsonPath, memoryDir, memoryMdPath, openMemoryDb, readFacts, readFactsFromMarkdown, writeSessionSummary };
966
- //# sourceMappingURL=chunk-SEL2ZQMT.js.map
967
- //# sourceMappingURL=chunk-SEL2ZQMT.js.map
971
+ //# sourceMappingURL=chunk-DAPSQZT4.js.map
972
+ //# sourceMappingURL=chunk-DAPSQZT4.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/internal/memory/escape-like-pattern.ts","../src/internal/memory/index-schema.ts","../src/internal/memory/index-db.ts","../src/internal/memory/lance-index.ts","../src/internal/memory/memory-index.ts","../src/internal/memory/lance-memory-adapter.ts","../src/internal/memory/index-manager-dispatch.ts","../src/internal/memory/types.ts","../src/internal/memory/storage/markdown-store.ts","../src/internal/memory/storage/session-summary-writer.ts","../src/internal/memory/storage/session-loader.ts","../src/internal/memory/storage/wiki-loader.ts","../src/internal/memory/index-manager-helpers.ts","../src/internal/memory/sqlite-vec-loader.ts","../src/internal/memory/storage/chunk-markdown.ts","../src/internal/memory/vec-index.ts","../src/internal/memory/index-manager.ts"],"names":["join","resolvePath","mkdir","readdir","relativeToRoot","createHash","readFile","stat"],"mappings":"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","file":"chunk-DAPSQZT4.js","sourcesContent":["/**\n * Escapes a user query for a SQL `LIKE ... ESCAPE '\\'` clause.\n *\n * The order of the three replacements is the whole correctness argument, so it is its own\n * function rather than a chain inline at the call site.\n *\n * The previous version escaped `%` and `_` but not the escape character itself, which is the\n * defect CodeQL reports as `js/incomplete-sanitization` (alerts #14, #15). Two things went wrong,\n * and the second is the one that matters:\n *\n * \"back\\slash\" -> \"%back\\slash%\" the `\\s` is an escape of `s`, which LIKE does not define\n * \"x\\%y\" -> \"%x\\\\%y%\" the inserted `\\` is consumed escaping the user's `\\`,\n * leaving `%` UNESCAPED — a wildcard the caller did not\n * write, matching anything between `x\\` and `y`\n *\n * The second is wildcard injection: a search for a literal string silently becomes a scan. In a\n * memory index that is both a wrong answer and a way to pull back rows the query never asked for.\n *\n * Escaping the backslash FIRST is what fixes it — afterwards every `\\` in the string is one this\n * function put there, so the later replacements cannot collide with a user-supplied one.\n */\nexport function escapeLikePattern(query: string): string {\n return `%${query.replace(/\\\\/g, \"\\\\\\\\\").replace(/%/g, \"\\\\%\").replace(/_/g, \"\\\\_\")}%`;\n}\n","/**\n * SQLite schema for the memory index.\n *\n * Tables:\n * - files — one row per indexed markdown file (path, mtime, hash).\n * - chunks — one row per chunk produced by `chunkMarkdown`.\n * - chunks_fts — FTS5 virtual table mirroring chunks.text for BM25 search.\n * - meta — key/value store; persists the active embedding identity\n * (provider id, model, dimension) so we detect when the\n * index was built against a different embedding setup.\n * - embeddings — sqlite-vec virtual table holding the chunk vectors\n * (created on demand by `vec-index.ts`).\n *\n * @internal\n */\n\nexport const SCHEMA_STATEMENTS: ReadonlyArray<string> = [\n `CREATE TABLE IF NOT EXISTS files (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n path TEXT UNIQUE NOT NULL,\n rel_path TEXT NOT NULL,\n mtime INTEGER NOT NULL,\n hash TEXT NOT NULL,\n source TEXT NOT NULL DEFAULT 'memory'\n )`,\n `CREATE TABLE IF NOT EXISTS chunks (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n file_id INTEGER NOT NULL REFERENCES files(id) ON DELETE CASCADE,\n start_line INTEGER NOT NULL,\n end_line INTEGER NOT NULL,\n text TEXT NOT NULL,\n hash TEXT NOT NULL,\n session_key TEXT\n )`,\n `CREATE VIRTUAL TABLE IF NOT EXISTS chunks_fts USING fts5(\n text,\n content='chunks',\n content_rowid='id'\n )`,\n `CREATE TRIGGER IF NOT EXISTS chunks_fts_insert AFTER INSERT ON chunks BEGIN\n INSERT INTO chunks_fts(rowid, text) VALUES (new.id, new.text);\n END`,\n `CREATE TRIGGER IF NOT EXISTS chunks_fts_delete AFTER DELETE ON chunks BEGIN\n INSERT INTO chunks_fts(chunks_fts, rowid, text) VALUES ('delete', old.id, old.text);\n END`,\n `CREATE TABLE IF NOT EXISTS meta (\n key TEXT PRIMARY KEY,\n value TEXT\n )`,\n `CREATE INDEX IF NOT EXISTS idx_chunks_file_id ON chunks(file_id)`,\n];\n\n/**\n * Non-WAL pragmas. WAL is applied separately via\n * `applyWalWithFallback` (T4.2, ADR D63) so NFS/SMB users get a graceful\n * DELETE fallback instead of crashing.\n */\nexport const PRAGMA_STATEMENTS: ReadonlyArray<string> = [\n \"PRAGMA synchronous=NORMAL\",\n \"PRAGMA foreign_keys=ON\",\n];\n","import { join } from \"node:path\";\n\nimport { openSqliteResilient } from \"../persistence/sqlite-open.js\";\nimport { PRAGMA_STATEMENTS, SCHEMA_STATEMENTS } from \"./index-schema.js\";\n\n/**\n * Memory index DB handle + opener.\n *\n * M0-5 (plan m0-foundation-expose-primitives): the driver-load + WAL +\n * corruption-recovery (EC-7) plumbing is now the shared `openSqliteResilient`\n * primitive in `internal/persistence`; this module only declares the memory\n * schema application (PRAGMA + SCHEMA) via its `onOpen` callback.\n *\n * @internal\n */\n\nexport interface MemoryDb {\n exec(sql: string): void;\n prepare(sql: string): {\n run(...args: unknown[]): { changes: number; lastInsertRowid: number | bigint };\n get(...args: unknown[]): Record<string, unknown> | undefined;\n all(...args: unknown[]): Array<Record<string, unknown>>;\n };\n /** SQLite `pragma()` access (used by `applyWalWithFallback`). */\n pragma(statement: string, options?: { simple?: boolean }): unknown;\n close(): void;\n /** Load a SQLite loadable extension at the given path (used by sqlite-vec). */\n loadExtension(path: string): void;\n}\n\nexport interface OpenDbOptions {\n filePath: string;\n /**\n * When true and opening fails with a corruption error, rename the file aside\n * and create a fresh DB. Default true.\n */\n recoverCorrupt?: boolean;\n}\n\nexport async function openMemoryDb(opts: OpenDbOptions): Promise<MemoryDb> {\n return openSqliteResilient<MemoryDb>({\n filePath: opts.filePath,\n label: \"memory-index\",\n recoverCorrupt: opts.recoverCorrupt,\n onOpen: (db) => {\n // PRAGMA + SCHEMA run after WAL is applied (handled by openSqliteResilient).\n for (const pragma of PRAGMA_STATEMENTS) db.exec(pragma);\n for (const stmt of SCHEMA_STATEMENTS) db.exec(stmt);\n },\n });\n}\n\nexport function defaultIndexPath(cwd: string): string {\n return join(cwd, \".theokit\", \"memory\", \".index\", \"memory.sqlite\");\n}\n","import { existsSync, mkdirSync } from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { join } from \"node:path\";\n\nimport { ConfigurationError } from \"../../errors.js\";\nimport type { EmbeddingRuntime } from \"./embedding-adapter.js\";\n\n/**\n * LanceDB-backed memory index (ADR D43). Implements the same logical\n * interface as `IndexManager` but stores embeddings in Lance's columnar\n * vector-aware file format — scalable to 100k+ facts.\n *\n * Opt-in via `Memory.create({ index: { backend: \"lance\" } })`. SQLite\n * remains the default; this code path only activates when explicitly\n * requested AND `@lancedb/lancedb` is installed.\n *\n * EC-1 MUST FIX: filters use Lance structured filter API (object form) —\n * NEVER string interpolation. SQL injection via namespace is impossible.\n *\n * EC-8: embedding dimension is validated when opening an existing table.\n *\n * @internal\n */\n\ninterface LanceModule {\n connect: (uri: string) => Promise<LanceConnection>;\n}\n\ninterface LanceConnection {\n openTable: (name: string) => Promise<LanceTable>;\n createTable: (name: string, data: ReadonlyArray<LanceFactRecord>) => Promise<LanceTable>;\n tableNames: () => Promise<string[]>;\n}\n\ninterface LanceTable {\n add: (rows: ReadonlyArray<LanceFactRecord>) => Promise<void>;\n search: (vector: ReadonlyArray<number>) => LanceQuery;\n delete: (predicate: string) => Promise<void>;\n countRows: () => Promise<number>;\n // EC-8: schema introspection for dimension check.\n schema: () => Promise<{\n fields: ReadonlyArray<{\n name: string;\n // Lance 0.30 returns Apache Arrow Field. FixedSizeList type has\n // `listSize`, not `fixedSize`. typeId=16 = FixedSizeList in Arrow.\n type: { listSize?: number; fixedSize?: number };\n }>;\n }>;\n}\n\ninterface LanceQuery {\n where: (filter: string | Record<string, unknown>) => LanceQuery;\n limit: (n: number) => LanceQuery;\n toArray: () => Promise<ReadonlyArray<LanceFactRecord & { _distance?: number }>>;\n}\n\nexport interface LanceFactRecord {\n id: string;\n text: string;\n source: \"memory\" | \"sessions\" | \"wiki\";\n embedding: ReadonlyArray<number>;\n namespace: string;\n scope: string;\n user_id: string;\n timestamp: number;\n}\n\nexport interface OpenLanceOptions {\n cwd: string;\n embedding: EmbeddingRuntime;\n /** Override storage location. Default: `<cwd>/.theokit/memory/lance/`. */\n storagePath?: string;\n}\n\nexport interface LanceSearchOptions {\n namespace: string;\n scope?: string;\n limit?: number;\n sources?: ReadonlyArray<\"memory\" | \"sessions\" | \"wiki\">;\n}\n\nexport interface LanceSearchHit {\n id: string;\n text: string;\n source: \"memory\" | \"sessions\" | \"wiki\";\n namespace: string;\n scope: string;\n userId: string;\n score: number;\n}\n\n/**\n * Lazily load `@lancedb/lancedb`. Throws typed error when absent.\n *\n * @internal\n */\nfunction requireLance(): LanceModule {\n try {\n const r = createRequire(import.meta.url);\n return r(\"@lancedb/lancedb\") as LanceModule;\n } catch (cause) {\n throw new ConfigurationError(\n \"Lance backend selected but `@lancedb/lancedb` is not installed. \" +\n 'Install with: `pnpm add @lancedb/lancedb`. SQLite remains available as the default (omit `backend: \"lance\"`).',\n { code: \"lance_backend_unavailable\", cause },\n );\n }\n}\n\n/**\n * Lance-backed memory index. Public API mirrors the SQLite one logically:\n * `addFacts`, `search`, `countFacts`, `removeFacts`, `close`.\n *\n * @internal\n */\nexport class LanceIndex {\n private constructor(\n private readonly table: LanceTable,\n private readonly embedding: EmbeddingRuntime,\n private readonly embeddingDim: number,\n ) {}\n\n static async open(opts: OpenLanceOptions): Promise<LanceIndex> {\n const lance = requireLance();\n const storagePath = opts.storagePath ?? join(opts.cwd, \".theokit\", \"memory\", \"lance\");\n mkdirSync(storagePath, { recursive: true });\n const conn = await lance.connect(storagePath);\n const dim = opts.embedding.dimension;\n const tableName = \"facts\";\n const existing = await conn.tableNames();\n let table: LanceTable;\n if (existing.includes(tableName)) {\n table = await conn.openTable(tableName);\n // EC-8: validate embedding dimension matches what's in storage.\n // Lance 0.30 uses Apache Arrow FixedSizeList type — the size lives\n // in `type.listSize` (older API used `fixedSize`; we read both for\n // forward/backward safety).\n const schema = await table.schema();\n const embField = schema.fields.find((f) => f.name === \"embedding\");\n const existingDim = embField?.type?.listSize ?? embField?.type?.fixedSize;\n if (typeof existingDim === \"number\" && existingDim !== dim) {\n throw new ConfigurationError(\n `Embedding dimension mismatch in Lance index: storage has ${existingDim}-dim vectors, current provider yields ${dim}-dim. Run \\`theokit-migrate-memory\\` after switching providers, or use a different storagePath.`,\n { code: \"embedding_dimension_mismatch\" },\n );\n }\n } else {\n // Create with one bootstrap record. Lance requires an initial row to\n // infer schema; we delete the bootstrap immediately.\n const bootstrap: LanceFactRecord = {\n id: \"__bootstrap__\",\n text: \"\",\n source: \"memory\",\n embedding: new Array(dim).fill(0),\n namespace: \"__bootstrap__\",\n scope: \"__bootstrap__\",\n user_id: \"__bootstrap__\",\n timestamp: 0,\n };\n table = await conn.createTable(tableName, [bootstrap]);\n await table.delete(\"namespace = '__bootstrap__'\");\n }\n return new LanceIndex(table, opts.embedding, dim);\n }\n\n async addFacts(facts: ReadonlyArray<Omit<LanceFactRecord, \"embedding\">>): Promise<void> {\n if (facts.length === 0) return;\n const texts = facts.map((f) => f.text);\n const embeddings = await this.embedding.embed(texts);\n const rows: LanceFactRecord[] = facts.map((f, i) => ({\n ...f,\n embedding: embeddings[i] ?? new Array(this.embeddingDim).fill(0),\n }));\n await this.table.add(rows);\n }\n\n /**\n * Search facts by semantic similarity. EC-1: filters use Lance's\n * structured object filter — NEVER string interpolation.\n */\n async search(query: string, opts: LanceSearchOptions): Promise<LanceSearchHit[]> {\n const [embedding] = await this.embedding.embed([query]);\n if (embedding === undefined) return [];\n // EC-1 (lancedb-backend-ship-v1-1 integration test caught this 2026-05-31):\n // Lance 0.30.0's `.where()` accepts SQL STRING only, NOT object filter —\n // contrary to D43's original assumption. We build the SQL string with\n // single-quote escaping (`'` → `''`) to neutralize injection. This is\n // the standard SQL string-literal escape; bind parameters are not\n // supported in Lance's predicate API. Backed by integration test\n // `injection attempt in namespace does not break filter` (test 7).\n const predicates: string[] = [`namespace = '${escapeSqlValue(opts.namespace)}'`];\n if (opts.scope !== undefined) {\n predicates.push(`scope = '${escapeSqlValue(opts.scope)}'`);\n }\n let q = this.table.search(embedding).where(predicates.join(\" AND \"));\n if (opts.limit !== undefined) q = q.limit(opts.limit);\n const results = await q.toArray();\n return results\n .filter((r) => opts.sources === undefined || opts.sources.includes(r.source))\n .map((r) => ({\n id: r.id,\n text: r.text,\n source: r.source,\n namespace: r.namespace,\n scope: r.scope,\n userId: r.user_id,\n // Lower _distance = better match; normalize to 0..1 (1=best).\n score: 1 / (1 + (r._distance ?? 1)),\n }));\n }\n\n async countFacts(namespace: string): Promise<number> {\n // Total count, regardless of namespace, used by migration validation.\n // For per-namespace count, callers can do a where() + countRows() if\n // Lance supports it; v1.2 ships with global count only.\n void namespace;\n return this.table.countRows();\n }\n\n async removeFacts(ids: ReadonlyArray<string>): Promise<void> {\n if (ids.length === 0) return;\n // Build a parameterized-style delete predicate. Lance's delete still\n // takes a string predicate, so we explicitly quote-escape each id —\n // ids in our system are content-hashed (alphanumeric), so the risk\n // is low, but we belt-and-suspenders.\n const escaped = ids.map((id) => `'${id.replace(/'/g, \"''\")}'`).join(\", \");\n await this.table.delete(`id IN (${escaped})`);\n }\n\n async close(): Promise<void> {\n // Lance auto-closes on GC; no explicit shutdown needed.\n }\n}\n\n/**\n * T5.2 — Harden SQL value escaping for Lance `.where()` predicates.\n *\n * Pre-T5.2 this only escaped single quotes (`'` → `''`). T5.2 adds:\n * - NUL byte rejection (NUL truncates the string in some SQL engines)\n * - C0 control char rejection (prevents invisible payload injection)\n * - Backslash escaping (`\\` → `\\\\` — some engines interpret `\\'` as\n * a single-quote escape, bypassing the `''` defense)\n *\n * Throws `ConfigurationError` on NUL/control to surface the attack\n * honestly rather than silently corrupting the query.\n */\nfunction escapeSqlValue(value: string): string {\n // Reject NUL + C0/DEL control chars (T5.5 pattern adapted for SQL).\n for (let i = 0; i < value.length; i++) {\n const code = value.charCodeAt(i);\n if (code === 0x00 || (code >= 0x01 && code <= 0x1f) || code === 0x7f) {\n throw new ConfigurationError(\n `SQL filter value contains control character at position ${i} (0x${code.toString(16)}). ` +\n \"This may indicate an injection attempt.\",\n { code: \"sql_injection_blocked\" },\n );\n }\n }\n // Escape both single-quote and backslash.\n return value.replace(/\\\\/g, \"\\\\\\\\\").replace(/'/g, \"''\");\n}\n\n/**\n * Test helper for {@link LanceIndex}: indicates whether the Lance module\n * is loadable in the current environment. Allows tests to gracefully skip\n * when the optional dep is absent.\n *\n * @internal\n */\nexport function isLanceAvailable(): boolean {\n try {\n const r = createRequire(import.meta.url);\n r(\"@lancedb/lancedb\");\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Test helper: re-export the storage path computation.\n *\n * @internal\n */\nexport function lanceStoragePath(cwd: string): string {\n return join(cwd, \".theokit\", \"memory\", \"lance\");\n}\n\nvoid existsSync; // imported but only used conditionally via mkdirSync\n","/**\n * Common `MemoryIndex` interface shared between the SQLite-backed\n * `IndexManager` (default) and the Lance-backed adapter (ADR D43, shipped\n * v1.4.0 via lancedb-backend-ship-v1-1 plan).\n *\n * Consumers (`local-agent-memory.ts`, `active-memory.ts`, `tools.ts`,\n * `runActiveMemory`) only ever call `sync()`, `search()`, `status()`,\n * `close()` — the union of those four methods is the portable surface.\n *\n * Why a separate file (vs declaring inline in `index-manager.ts`)? D43\n * promised \"extract an abstract `MemoryIndex` interface in\n * `internal/memory/index-interface.ts`\". Keeping the contract physically\n * separated from one of its implementations preserves OCP — future\n * backends (Qdrant, PGVector) can land without touching IndexManager.\n *\n * @internal\n */\n\nimport type { IndexStatus, MemorySearchHit, SearchOptions } from \"./index-manager-contract.js\";\n\n// Re-export consumer-facing shapes for stable internal import paths.\nexport type { IndexStatus, MemorySearchHit, SearchOptions };\n\nexport interface SyncResult {\n filesScanned: number;\n filesUpdated: number;\n chunksWritten: number;\n chunksEmbedded: number;\n}\n\n/**\n * Common search-options parser used by both `IndexManager.search` and\n * `LanceMemoryAdapter.search`. Returns the normalized cap + minimum-score\n * floor — eliminates jscpd duplication while keeping per-backend search\n * logic distinct.\n */\nexport function parseSearchOptions(options: SearchOptions = {}): {\n maxResults: number;\n minScore: number;\n} {\n return {\n maxResults: Math.max(1, options.maxResults ?? 10),\n minScore: options.minScore ?? 0,\n };\n}\n\nexport interface MemoryIndex {\n /**\n * Walk the memory corpus + reindex changed files. Lance backend has no\n * markdown corpus to walk — its adapter returns zero counts (no-op) and\n * relies on explicit `addFact` calls instead.\n */\n sync(): Promise<SyncResult>;\n\n /**\n * Semantic + textual search over the indexed corpus. Both backends\n * return the same `MemorySearchHit[]` shape; Lance leaves `textScore`\n * undefined (vector-only — no FTS5 layer).\n */\n search(query: string, options?: SearchOptions): Promise<MemorySearchHit[]>;\n\n /** Snapshot of the index health (backend type + counts). */\n status(): IndexStatus;\n\n /** Release native handles. Idempotent. */\n close(): Promise<void> | void;\n}\n","/**\n * `LanceMemoryAdapter` — wraps `LanceIndex` to expose the common\n * `MemoryIndex` interface (sync/search/status/close) so consumers of\n * `IndexManager.open({ backend: \"lance\" })` get a drop-in replacement\n * for the SQLite-backed `IndexManager`.\n *\n * Semantic deltas vs SQLite (documented so callers know what to expect):\n *\n * - `sync()` is a NO-OP. Lance is a pure vector store — there is no\n * markdown corpus to crawl. Returns zero counts. Consumers writing\n * facts use `LanceIndex.addFacts` directly (exposed via the index\n * object returned to advanced callers).\n * - `search()` performs vector-only retrieval. `MemorySearchHit.textScore`\n * is undefined (no FTS5 layer); `vectorScore === score`.\n * - `status()` reports `backend: \"hybrid\"` only when an embedding runtime\n * is wired (always the case for Lance — embedding is required at open).\n * `chunksIndexed` reflects total Lance row count; `filesIndexed` is 0\n * because Lance does not track file provenance per-row.\n *\n * Ships with the lancedb-backend-ship-v1-1 plan (close D12, supersede via\n * D43). v1.4.0 of `@theokit/sdk`.\n *\n * @internal\n */\n\nimport type { IndexStatus, MemorySearchHit, SearchOptions } from \"./index-manager-contract.js\";\nimport type { LanceIndex } from \"./lance-index.js\";\nimport { type MemoryIndex, parseSearchOptions, type SyncResult } from \"./memory-index.js\";\n\n/**\n * Default namespace used when consumers call `search()` without specifying\n * one. The SQLite `IndexManager` does not surface namespace in its public\n * `search()` signature either — both backends therefore behave consistently\n * under the \"single-workspace, single-namespace\" assumption that v1.4 ships.\n *\n * v1.5 candidate: surface `namespace` in `SearchOptions` (additive — no\n * breaking change) so multi-tenant Lance consumers can scope queries.\n */\nconst DEFAULT_NAMESPACE = \"default\";\n\n/** Empty sync result — Lance has no corpus to walk. */\nconst EMPTY_SYNC_RESULT: SyncResult = Object.freeze({\n filesScanned: 0,\n filesUpdated: 0,\n chunksWritten: 0,\n chunksEmbedded: 0,\n});\n\nexport class LanceMemoryAdapter implements MemoryIndex {\n constructor(private readonly inner: LanceIndex) {}\n\n /**\n * No-op for Lance — see file header. Returns zero counts so callers'\n * existing logging (`filesScanned: X`) does not break.\n */\n async sync(): Promise<SyncResult> {\n return EMPTY_SYNC_RESULT;\n }\n\n // jscpd:ignore-start — search signature + early-out is idiomatic\n // overlap with IndexManager.search; further factoring would hurt\n // readability (the bodies diverge sharply right after).\n async search(query: string, options: SearchOptions = {}): Promise<MemorySearchHit[]> {\n if (query.trim().length === 0) return [];\n const { maxResults, minScore } = parseSearchOptions(options);\n // jscpd:ignore-end\n const lanceHits = await this.inner.search(query, {\n namespace: DEFAULT_NAMESPACE,\n limit: maxResults * 2,\n ...(options.sources !== undefined ? { sources: options.sources } : {}),\n });\n return lanceHits\n .filter((h) => h.score >= minScore)\n .slice(0, maxResults)\n .map((h) => translateLanceHit(h, query));\n }\n\n status(): IndexStatus {\n // chunksIndexed via a synchronous best-effort — Lance API is async so\n // we surface zero here and document that consumers needing exact counts\n // should call `inner.countFacts()` directly.\n return {\n backend: \"hybrid\",\n filesIndexed: 0,\n chunksIndexed: 0,\n };\n }\n\n async close(): Promise<void> {\n await this.inner.close();\n }\n\n /**\n * Escape hatch for advanced callers (migration tool, benchmark script)\n * that need direct access to addFacts/countFacts/removeFacts.\n */\n unwrap(): LanceIndex {\n return this.inner;\n }\n}\n\n/**\n * Translate `LanceSearchHit` to `MemorySearchHit`. Field mapping:\n *\n * - `id` → `path` (Lance has no file-system provenance; use opaque id)\n * - `text` → `snippet` (truncated to 200 chars matching IndexManager convention)\n * - `score` → combined (0.7 × vectorScore + 0.3 × textScore)\n * - `vectorScore` → from Lance's distance metric\n * - `textScore` → T4.5 client-side term-overlap ratio (removes ADR D43 vector-only caveat)\n * - `source` → `source`\n * - synthetic `startLine: 0, endLine: 0` (Lance has no line info)\n * - synthetic `citation: id` (no path:line citation available)\n */\nfunction translateLanceHit(\n hit: { id: string; text: string; source: \"memory\" | \"sessions\" | \"wiki\"; score: number },\n query?: string,\n): MemorySearchHit {\n const textScore = query !== undefined ? computeTermOverlapScore(query, hit.text) : 0;\n const vectorScore = hit.score;\n // Hybrid combination: 70% vector (semantic) + 30% text (lexical).\n const combined = 0.7 * vectorScore + 0.3 * textScore;\n return {\n path: hit.id,\n startLine: 0,\n endLine: 0,\n score: combined,\n textScore,\n vectorScore,\n snippet: hit.text.slice(0, 200),\n source: hit.source,\n citation: hit.id,\n };\n}\n\n/**\n * T4.5 — Client-side term-overlap score for Lance hybrid search.\n * Counts what fraction of query terms appear in the text (case-insensitive).\n * Simple but effective for re-ranking vector hits by lexical relevance.\n * Returns 0..1 where 1 = all query terms present.\n */\nfunction computeTermOverlapScore(query: string, text: string): number {\n const queryTerms = query\n .toLowerCase()\n .split(/\\s+/)\n .filter((t) => t.length > 1);\n if (queryTerms.length === 0) return 0;\n const textLower = text.toLowerCase();\n const matched = queryTerms.filter((term) => textLower.includes(term)).length;\n return matched / queryTerms.length;\n}\n","/**\n * Dispatch helpers for `IndexManager.open`. Extracted to keep\n * `index-manager.ts` under the G8 400-LoC budget (lancedb-backend-ship-v1-1).\n *\n * @internal\n */\n\nimport { ConfigurationError } from \"../../errors.js\";\nimport type { MemoryBackend, OpenIndexOptions } from \"./index-manager-contract.js\";\nimport { LanceIndex } from \"./lance-index.js\";\nimport { LanceMemoryAdapter } from \"./lance-memory-adapter.js\";\nimport type { MemoryIndex } from \"./memory-index.js\";\n\n/** Valid backend identifiers — runtime guard against TS-narrowing escapes (EC-1). */\nexport const VALID_BACKENDS: readonly MemoryBackend[] = [\"sqlite-vec\", \"lance\"];\n\n/**\n * EC-1: runtime guard for `opts.backend`. TS union is compile-time only;\n * consumers passing JS `as any` typos must hit a typed error, not silent\n * SQLite fallback.\n */\nexport function assertValidBackend(backend: string): asserts backend is MemoryBackend {\n if (!VALID_BACKENDS.includes(backend as MemoryBackend)) {\n throw new ConfigurationError(\n `Invalid memory backend \"${backend}\". Valid values: ${VALID_BACKENDS.join(\", \")}.`,\n { code: \"invalid_memory_backend\" },\n );\n }\n}\n\n/**\n * Lance-path open. Throws `lance_requires_embedding` when no embedding\n * runtime is provided (Lance is vector-only — no FTS fallback).\n * Surfaces `lance_backend_unavailable` from LanceIndex.open when peer\n * dep is absent.\n */\nexport async function openLanceIndex(opts: OpenIndexOptions): Promise<MemoryIndex> {\n if (opts.embedding === undefined) {\n throw new ConfigurationError(\n \"Lance backend requires an embedding runtime. Pass `embedding: { provider, model, apiKey }` in Memory.create options (or omit `backend` to use SQLite default).\",\n { code: \"lance_requires_embedding\" },\n );\n }\n const lance = await LanceIndex.open({\n cwd: opts.cwd,\n embedding: opts.embedding,\n ...(opts.filePath !== undefined ? { storagePath: opts.filePath } : {}),\n });\n return new LanceMemoryAdapter(lance);\n}\n","/**\n * Public memory types (used by runtime + storage + migration + future index).\n *\n * Leaf module — only depends on `node:path` — so neither `runtime/memory-store.ts`\n * nor `internal/memory/markdown-store.ts` introduces a dependency cycle.\n *\n * @internal\n */\nimport { resolve as resolvePath } from \"node:path\";\n\nimport { safePathJoin, sanitizeIdentifier } from \"../security/path-guard.js\";\n\nexport interface MemoryConfig {\n enabled: boolean;\n namespace?: string;\n userId?: string;\n scope?: \"agent\" | \"user\" | \"team\";\n storePath?: string;\n}\n\nexport interface MemoryFact {\n text: string;\n}\n\n// `redactSecrets` is now re-exported from the canonical security module\n// (ADR D68). Pre-T0.2 it was a 3-pattern local fn; consolidated to avoid\n// drift with the central 12-pattern list.\nexport { redactSecrets } from \"../security/index.js\";\n\n/**\n * Resolve the legacy JSON memory path used pre-ADR-D8 (kept for migration\n * helpers + tests). Centralized here so `migration.ts` and the legacy-aware\n * `runtime/memory-store.ts` don't duplicate the path logic (jscpd cleanup).\n */\nexport function legacyMemoryJsonPath(cwd: string, config: MemoryConfig): string {\n // ADRs D79-D81: storePath is programmatic (trusted); namespace/scope/userId\n // are user-shaped and pass sanitizeIdentifier. EC-7 (edge-case review):\n // realistic userIds (UUIDs, hash IDs, \"default\") pass; \"user@example.com\"\n // and similar need to be normalized by the caller before passing.\n if (config.storePath !== undefined) {\n return resolvePath(cwd, config.storePath);\n }\n const namespace = sanitizeIdentifier(config.namespace ?? \"default\");\n const scope = sanitizeIdentifier(config.scope ?? \"agent\", { maxLen: 16 });\n const userId = sanitizeIdentifier(config.userId ?? \"default\");\n return safePathJoin(cwd, \".theokit\", \"memory\", namespace, `${scope}-${userId}.json`);\n}\n\n/**\n * A semantically meaningful slice of a markdown memory file, produced by\n * `chunkMarkdown`. Each chunk carries stable line numbers + a content hash\n * used downstream by the embedding cache.\n *\n * Mirrors peer-project's `MemoryChunk` shape\n * (`reference/peer-project/packages/memory-host-sdk/src/host/engine-storage.ts`).\n *\n * @internal\n */\nexport interface MemoryChunk {\n /** 1-indexed starting line in the source file. */\n startLine: number;\n /** 1-indexed ending line (inclusive). */\n endLine: number;\n /** Slice of markdown source text. */\n text: string;\n /** sha256 of `text`; stable across runs for identical inputs. */\n hash: string;\n /** Optional nearest heading text (without the `#` markers). */\n heading?: string;\n}\n\n/**\n * Result of `reader.readFile`. Contains the bounded slice plus truncation\n * + provenance info.\n *\n * Mirrors peer-project's `MemoryReadResult` shape.\n *\n * @internal\n */\nexport interface MemoryReadResult {\n path: string;\n /** Requested starting line (1-indexed, defaults to 1). */\n from: number;\n /** Number of lines actually returned (may be less than `lines` near EOF). */\n linesReturned: number;\n /** Total lines in the file (after the read). */\n totalLines: number;\n /** True when fewer lines were returned than the requested `lines` AND EOF was hit. */\n truncated: boolean;\n /** Lines past the returned slice that remain in the file. */\n remainingLines: number;\n /** Slice text (joined with `\\n`). */\n text: string;\n}\n","import { mkdir, readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { replaceFileAtomic } from \"../../persistence/atomic-write.js\";\nimport { withCwdMutex } from \"../../persistence/cwd-mutex.js\";\nimport { type MemoryConfig, type MemoryFact, redactSecrets } from \"../types.js\";\n\n/**\n * Markdown-first memory storage (ADR D1 of memory-system-peer-project-parity).\n *\n * Layout:\n * .theokit/memory/\n * ├── MEMORY.md # facts under `## Facts`\n * └── notes/\n * └── <slug>.md # per-topic notes\n *\n * All writes go through `replaceFileAtomic` + a per-cwd mutex (EC-4 of the\n * edge-case review) so concurrent `appendFact` calls within the same process\n * serialize. Multi-process safety is NOT provided.\n *\n * @internal\n */\n\nconst MEMORY_MD_HEADER =\n \"# Memory\\n\\n> Auto-managed by @theokit/sdk. Edit freely — the SDK reads from here.\\n\";\nconst FACTS_HEADING = \"## Facts\";\n\nexport function memoryDir(cwd: string): string {\n return join(cwd, \".theokit\", \"memory\");\n}\n\nexport function memoryMdPath(cwd: string): string {\n return join(memoryDir(cwd), \"MEMORY.md\");\n}\n\nexport function notesDir(cwd: string): string {\n return join(memoryDir(cwd), \"notes\");\n}\n\n/** Read facts from `MEMORY.md`'s `## Facts` section. Returns `[]` when missing. */\nexport async function readFactsFromMarkdown(cwd: string): Promise<MemoryFact[]> {\n let raw: string;\n try {\n raw = await readFile(memoryMdPath(cwd), \"utf8\");\n } catch {\n return [];\n }\n return parseFactsSection(raw);\n}\n\n/** Append a fact to `MEMORY.md ## Facts`. Creates the section if missing. Atomic + serialized. */\nexport function appendFactToMarkdown(cwd: string, fact: MemoryFact): Promise<void> {\n return withCwdMutex(memoryDir(cwd), async () => {\n const path = memoryMdPath(cwd);\n let raw = \"\";\n try {\n raw = await readFile(path, \"utf8\");\n } catch {\n raw = \"\";\n }\n const sanitized = redactSecrets(fact.text);\n const next = insertFactBullet(raw, sanitized);\n await mkdir(memoryDir(cwd), { recursive: true });\n await replaceFileAtomic(path, next);\n });\n}\n\nfunction parseFactsSection(raw: string): MemoryFact[] {\n const idx = raw.indexOf(FACTS_HEADING);\n if (idx === -1) return [];\n const tail = raw.slice(idx + FACTS_HEADING.length);\n // Stop at the next top-level or h2 heading.\n const nextHeading = tail.search(/\\n#{1,2}\\s/);\n const block = nextHeading === -1 ? tail : tail.slice(0, nextHeading);\n return block\n .split(\"\\n\")\n .map((line) => line.trim())\n .filter((line) => line.startsWith(\"- \"))\n .map((line) => ({ text: line.slice(2).trim() }));\n}\n\nfunction insertFactBullet(raw: string, fact: string): string {\n const bullet = `- ${fact}`;\n if (raw.length === 0) {\n return `${MEMORY_MD_HEADER}\\n${FACTS_HEADING}\\n\\n${bullet}\\n`;\n }\n const idx = raw.indexOf(FACTS_HEADING);\n if (idx === -1) {\n // Append a new ## Facts section, preserving prior content (EC-5).\n const sep = raw.endsWith(\"\\n\") ? \"\" : \"\\n\";\n return `${raw}${sep}\\n${FACTS_HEADING}\\n\\n${bullet}\\n`;\n }\n // Find end of the facts block (next h2/h1 heading) and insert before it.\n const after = idx + FACTS_HEADING.length;\n const nextHeading = raw.slice(after).search(/\\n#{1,2}\\s/);\n if (nextHeading === -1) {\n const trailing = raw.endsWith(\"\\n\") ? \"\" : \"\\n\";\n return `${raw}${trailing}${bullet}\\n`;\n }\n const insertAt = after + nextHeading;\n return `${raw.slice(0, insertAt)}\\n${bullet}${raw.slice(insertAt)}`;\n}\n\n/** Configuration-aware accessors honoring the existing MemoryConfig contract. */\nexport async function readFacts(cwd: string, config: MemoryConfig): Promise<MemoryFact[]> {\n if (!config.enabled) return [];\n return readFactsFromMarkdown(cwd);\n}\n\nexport async function appendFact(\n cwd: string,\n config: MemoryConfig,\n fact: MemoryFact,\n): Promise<void> {\n if (!config.enabled) return;\n await appendFactToMarkdown(cwd, fact);\n}\n","import { mkdir } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { replaceFileAtomic } from \"../../persistence/atomic-write.js\";\nimport { safeFilenameForId } from \"../../security/path-guard.js\";\nimport { redactSecrets } from \"../types.js\";\nimport { memoryDir } from \"./markdown-store.js\";\n\n/**\n * Per-run session summary writer (ADR D20).\n *\n * After every finished run, write a markdown summary to\n * `.theokit/memory/sessions/<runId>.md`. IndexManager picks these up with\n * `source=\"sessions\"` so `memory_search({ corpus: \"sessions\" })` can recall\n * past conversations.\n *\n * EC-9: only `status === \"finished\"` runs trigger a write. Cancelled/errored\n * runs would otherwise pollute the recall corpus with partial transcripts.\n *\n * @internal\n */\n\nexport interface SessionSummaryInput {\n cwd: string;\n runId: string;\n agentId: string;\n userText: string;\n assistantText: string;\n status: \"finished\" | \"running\" | \"error\" | \"cancelled\";\n at: number;\n}\n\nconst MAX_TURN_CHARS = 2000;\n\nexport function sessionsDir(cwd: string): string {\n return join(memoryDir(cwd), \"sessions\");\n}\n\nexport function sessionSummaryPath(cwd: string, runId: string): string {\n // M0-4: total id->filename helper. UUID runIds (the production case, from\n // randomUUID) pass through to the identical name; non-conforming ids get a\n // deterministic sha256 token instead of the old lossy replace-collapse.\n return join(sessionsDir(cwd), `${safeFilenameForId(runId, { maxLen: 128 })}.md`);\n}\n\nfunction truncate(text: string): string {\n if (text.length <= MAX_TURN_CHARS) return text;\n return `${text.slice(0, MAX_TURN_CHARS)}…`;\n}\n\n/**\n * Write a session summary file. EC-9: a non-finished status returns early\n * without touching disk. Secrets in both user and assistant text are\n * redacted via the shared `redactSecrets` pattern.\n *\n * @internal\n */\nexport async function writeSessionSummary(input: SessionSummaryInput): Promise<void> {\n if (input.status !== \"finished\") return;\n const path = sessionSummaryPath(input.cwd, input.runId);\n await mkdir(sessionsDir(input.cwd), { recursive: true });\n\n const safeUser = redactSecrets(truncate(input.userText));\n const safeAssistant = redactSecrets(truncate(input.assistantText));\n const iso = new Date(input.at).toISOString();\n\n const body = [\n \"---\",\n `runId: ${input.runId}`,\n `agentId: ${input.agentId}`,\n `at: ${iso}`,\n `status: ${input.status}`,\n \"---\",\n \"\",\n \"## User\",\n \"\",\n safeUser,\n \"\",\n \"## Assistant\",\n \"\",\n safeAssistant,\n \"\",\n ].join(\"\\n\");\n\n await replaceFileAtomic(path, body);\n}\n","import { readdir } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { memoryDir } from \"./markdown-store.js\";\nimport { sessionsDir } from \"./session-summary-writer.js\";\n\n/**\n * Session summary discovery (ADR D20).\n *\n * Mirrors `wiki-loader.ts:discoverWikiFiles`: scans\n * `.theokit/memory/sessions/*.md` and returns `SessionFile` records —\n * `{ absolutePath, relPath }`. IndexManager tags each chunk with\n * `source=\"sessions\"` so `memory_search({ corpus: \"sessions\" })` filters\n * them in.\n *\n * B-140: this said \"returns `MemoryFileEntry`-shaped records\" and that was\n * not true — `MemoryFileEntry` carried four fields (`path`, `relPath`,\n * `mtime`, `hash`) against this function's two, and even the path field was\n * named differently. Nothing consumed the interface, so it was removed and\n * the sentence now names the type the function actually returns. A docblock\n * asserting agreement between two shapes is worth no more than the agreement.\n *\n * @internal\n */\n\nexport interface SessionFile {\n absolutePath: string;\n relPath: string;\n}\n\nexport async function discoverSessionFiles(cwd: string): Promise<SessionFile[]> {\n let entries: string[];\n try {\n entries = await readdir(sessionsDir(cwd));\n } catch {\n return [];\n }\n const root = memoryDir(cwd);\n return entries\n .filter((entry) => entry.endsWith(\".md\"))\n .map((entry) => {\n const absolutePath = join(sessionsDir(cwd), entry);\n return {\n absolutePath,\n relPath: relativeToRoot(root, absolutePath),\n };\n });\n}\n\nfunction relativeToRoot(root: string, absolutePath: string): string {\n if (absolutePath.startsWith(`${root}/`)) return absolutePath.slice(root.length + 1);\n return absolutePath;\n}\n","import { readdir } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { memoryDir } from \"./markdown-store.js\";\n\n/**\n * Wiki supplement discovery (ADR Phase 10 of memory-system-peer-project-parity).\n *\n * Wiki files live under `.theokit/memory/wiki/*.md`. They are READ-ONLY —\n * the SDK never writes here. Each indexed chunk carries `source=\"wiki\"` so\n * `memory_search { corpus: \"wiki\" }` and `corpus: \"all\"` can scope hits.\n *\n * @internal\n */\n\nexport interface WikiFile {\n absolutePath: string;\n relPath: string;\n}\n\nexport function wikiDir(cwd: string): string {\n return join(memoryDir(cwd), \"wiki\");\n}\n\nexport async function discoverWikiFiles(cwd: string): Promise<WikiFile[]> {\n let entries: string[];\n try {\n entries = await readdir(wikiDir(cwd));\n } catch {\n return [];\n }\n const root = memoryDir(cwd);\n return entries\n .filter((entry) => entry.endsWith(\".md\"))\n .map((entry) => ({\n absolutePath: join(wikiDir(cwd), entry),\n relPath: join(\"wiki\", entry),\n }))\n .map((file) => ({\n absolutePath: file.absolutePath,\n relPath: relativeToRoot(root, file.absolutePath),\n }));\n}\n\nfunction relativeToRoot(root: string, absolutePath: string): string {\n // memory root is e.g. /tmp/x/.theokit/memory; wiki file is /tmp/x/.theokit/memory/wiki/foo.md\n // Strip the root + \"/\" prefix to get \"wiki/foo.md\".\n if (absolutePath.startsWith(`${root}/`)) return absolutePath.slice(root.length + 1);\n return absolutePath;\n}\n","import { createHash } from \"node:crypto\";\nimport { readdir, stat } from \"node:fs/promises\";\nimport { join, relative } from \"node:path\";\n\nimport type { MemorySearchHit, SearchOptions } from \"./index-manager-contract.js\";\nimport { memoryDir, memoryMdPath, notesDir } from \"./storage/markdown-store.js\";\nimport { discoverSessionFiles } from \"./storage/session-loader.js\";\nimport { discoverWikiFiles } from \"./storage/wiki-loader.js\";\n\n// ───── hybrid scoring helpers ─────────────────────────────────────────\n\n/** @internal */\nexport interface HybridWeights {\n vectorWeight: number;\n textWeight: number;\n total: number;\n}\n\n/** @internal */\nexport function resolveWeights(options: SearchOptions): HybridWeights {\n const vectorWeight = options.vectorWeight ?? 0.6;\n const textWeight = options.textWeight ?? 0.4;\n const total = vectorWeight + textWeight || 1;\n return { vectorWeight, textWeight, total };\n}\n\n/** @internal */\nexport function blendScores(\n hit: MemorySearchHit & { chunkId: number },\n vectorScore: number,\n weights: HybridWeights,\n): MemorySearchHit {\n const score =\n (vectorScore * weights.vectorWeight + hit.textScore * weights.textWeight) / weights.total;\n return {\n path: hit.path,\n startLine: hit.startLine,\n endLine: hit.endLine,\n score,\n textScore: hit.textScore,\n snippet: hit.snippet,\n source: hit.source,\n citation: hit.citation,\n ...(vectorScore > 0 ? { vectorScore } : {}),\n };\n}\n\n// ───── file discovery ─────────────────────────────────────────────────\n\n/** @internal */\nexport interface DiscoveredFile {\n absolutePath: string;\n relPath: string;\n source: \"memory\" | \"wiki\" | \"sessions\";\n}\n\n/** @internal */\nexport async function collectMarkdownFiles(cwd: string): Promise<DiscoveredFile[]> {\n const root = memoryDir(cwd);\n const results: DiscoveredFile[] = [];\n // MEMORY.md\n try {\n await stat(memoryMdPath(cwd));\n results.push({\n absolutePath: memoryMdPath(cwd),\n relPath: relative(root, memoryMdPath(cwd)),\n source: \"memory\",\n });\n } catch {\n // skip\n }\n // notes/*.md\n try {\n const entries = await readdir(notesDir(cwd));\n for (const entry of entries) {\n if (!entry.endsWith(\".md\")) continue;\n const abs = join(notesDir(cwd), entry);\n results.push({ absolutePath: abs, relPath: relative(root, abs), source: \"memory\" });\n }\n } catch {\n // notes dir doesn't exist yet — that's fine\n }\n // wiki/*.md (Phase 10 — read-only supplements)\n const wikiFiles = await discoverWikiFiles(cwd);\n for (const wiki of wikiFiles) {\n results.push({\n absolutePath: wiki.absolutePath,\n relPath: wiki.relPath,\n source: \"wiki\",\n });\n }\n // sessions/*.md (ADR D20 — per-run summaries for corpus=\"sessions\" recall)\n const sessionFiles = await discoverSessionFiles(cwd);\n for (const session of sessionFiles) {\n results.push({\n absolutePath: session.absolutePath,\n relPath: session.relPath,\n source: \"sessions\",\n });\n }\n return results;\n}\n\n// ───── misc helpers ───────────────────────────────────────────────────\n\n/** @internal */\nexport function sha256(text: string): string {\n return createHash(\"sha256\").update(text).digest(\"hex\");\n}\n\n/** @internal */\nexport function truncateSnippet(text: string): string {\n const max = 500;\n return text.length <= max ? text : `${text.slice(0, max)}…`;\n}\n","import { ConfigurationError } from \"../../errors.js\";\nimport type { MemoryDb } from \"./index-db.js\";\n\n/**\n * Load the `sqlite-vec` extension into an opened SQLite connection.\n *\n * Wraps the native `load(db)` call from the `sqlite-vec` npm package with a\n * typed error path (EC-8 of the edge-case review) so callers see a\n * `sqlite_vec_unavailable` ConfigurationError instead of a raw native error.\n *\n * @internal\n */\nexport async function loadSqliteVecExtension(db: MemoryDb): Promise<void> {\n try {\n const mod = await import(\"sqlite-vec\");\n const loadFn = (mod as { load?: (db: unknown) => void }).load;\n if (typeof loadFn !== \"function\") {\n throw new Error(\"sqlite-vec module exposes no `load` export\");\n }\n loadFn(db);\n } catch (cause) {\n const message = cause instanceof Error ? cause.message : String(cause);\n throw new ConfigurationError(\n `sqlite-vec extension unavailable. Install \\`sqlite-vec\\` and ensure the native binary matches your Node + OS. Cause: ${message}`,\n { code: \"sqlite_vec_unavailable\", cause },\n );\n }\n}\n","import { createHash } from \"node:crypto\";\n\nimport type { MemoryChunk } from \"../types.js\";\n\n/**\n * Split a markdown document into semantically meaningful chunks (ADR D1 of\n * memory-system-peer-project-parity).\n *\n * Algorithm:\n * 1. Walk lines tracking the current heading (latest `^#+ ` line).\n * 2. Split chunks at the next heading boundary AND on blank-line paragraph\n * boundaries.\n * 3. If a single paragraph exceeds `maxChars`, split it at the nearest\n * whitespace ≤ maxChars (word-aligned per edge-case review EC-6) —\n * never mid-word.\n *\n * Mirrors peer-project's `chunkMarkdown` from\n * `packages/memory-host-sdk/src/host/chunk-markdown.ts`.\n *\n * @internal\n */\n\nexport interface ChunkMarkdownOptions {\n /** Maximum chars per chunk. Default 800. */\n maxChars?: number;\n /** Minimum chars per chunk (avoids splintering tiny lines). Default 80. */\n minChars?: number;\n}\n\nconst HEADING_RE = /^(#{1,6})\\s+(.+?)\\s*$/;\n\ninterface ChunkAccumulator {\n chunks: MemoryChunk[];\n lines: string[];\n start: number;\n heading: string | undefined;\n}\n\nexport function chunkMarkdown(text: string, options: ChunkMarkdownOptions = {}): MemoryChunk[] {\n const maxChars = options.maxChars ?? 800;\n if (text.length === 0) return [];\n const lines = text.split(\"\\n\");\n const acc: ChunkAccumulator = { chunks: [], lines: [], start: 1, heading: undefined };\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i] ?? \"\";\n const lineNumber = i + 1;\n processLine(acc, line, lineNumber, maxChars);\n }\n flushAccumulator(acc, lines.length, maxChars);\n return acc.chunks;\n}\n\nfunction processLine(\n acc: ChunkAccumulator,\n line: string,\n lineNumber: number,\n maxChars: number,\n): void {\n const headingMatch = HEADING_RE.exec(line);\n const isBlank = line.trim().length === 0;\n if (headingMatch !== null && acc.lines.length > 0) {\n flushAccumulator(acc, lineNumber - 1, maxChars);\n }\n if (headingMatch !== null) acc.heading = headingMatch[2];\n acc.lines.push(line);\n if (isBlank && acc.lines.length > 1) {\n const joined = acc.lines.join(\"\\n\");\n if (joined.trim().length > 0) flushAccumulator(acc, lineNumber, maxChars);\n }\n}\n\nfunction flushAccumulator(acc: ChunkAccumulator, endLineExclusive: number, maxChars: number): void {\n if (acc.lines.length === 0) return;\n const chunkText = acc.lines.join(\"\\n\");\n if (chunkText.trim().length === 0) {\n acc.lines = [];\n acc.start = endLineExclusive + 1;\n return;\n }\n if (chunkText.length > maxChars) {\n pushOversizedSlices(acc.chunks, chunkText, acc.start, acc.heading, maxChars);\n } else {\n acc.chunks.push(buildChunk(chunkText, acc.start, endLineExclusive, acc.heading));\n }\n acc.lines = [];\n acc.start = endLineExclusive + 1;\n}\n\nfunction buildChunk(\n text: string,\n startLine: number,\n endLine: number,\n heading: string | undefined,\n): MemoryChunk {\n return {\n startLine,\n endLine,\n text,\n hash: createHash(\"sha256\").update(text).digest(\"hex\"),\n ...(heading !== undefined ? { heading } : {}),\n };\n}\n\nfunction pushOversizedSlices(\n chunks: MemoryChunk[],\n text: string,\n startLine: number,\n heading: string | undefined,\n maxChars: number,\n): void {\n let remaining = text;\n let lineCursor = startLine;\n while (remaining.length > maxChars) {\n const splitAt = findWordBoundarySplit(remaining, maxChars);\n const slice = remaining.slice(0, splitAt);\n const sliceLines = slice.split(\"\\n\").length;\n chunks.push(buildChunk(slice, lineCursor, lineCursor + sliceLines - 1, heading));\n remaining = remaining.slice(splitAt).replace(/^\\s+/, \"\");\n lineCursor += sliceLines - 1;\n }\n if (remaining.length > 0) {\n const sliceLines = remaining.split(\"\\n\").length;\n chunks.push(buildChunk(remaining, lineCursor, lineCursor + sliceLines - 1, heading));\n }\n}\n\n/**\n * Find a split point ≤ maxChars that lands on a whitespace boundary so we\n * don't slice a word in half. Falls back to maxChars if no whitespace is\n * within range (very rare — a single token > maxChars).\n */\nfunction findWordBoundarySplit(text: string, maxChars: number): number {\n if (text.length <= maxChars) return text.length;\n // Walk backward from maxChars looking for whitespace.\n for (let i = maxChars; i > Math.max(0, maxChars - 200); i--) {\n if (/\\s/.test(text[i] ?? \"x\")) return i;\n }\n // No whitespace within 200 chars of the cap — accept a hard split.\n return maxChars;\n}\n","import type { EmbeddingRuntime } from \"./embedding-adapter.js\";\nimport type { MemoryDb } from \"./index-db.js\";\n\n/**\n * Vector index helpers (ADR D2 + D4 of memory-system-peer-project-parity).\n *\n * Embeddings live in `embeddings(chunk_id, vec)` — a `vec0` virtual table\n * provided by the sqlite-vec extension. Embedding identity (providerId +\n * model + dimension) lives in the `meta` table; mismatches force a full\n * re-embed sweep (EC-1).\n *\n * @internal\n */\n\nexport const META_KEY_PROVIDER_ID = \"embedding.providerId\";\nexport const META_KEY_MODEL = \"embedding.model\";\nexport const META_KEY_DIMENSION = \"embedding.dimension\";\n\nexport interface EmbeddingIdentity {\n providerId: string;\n model: string;\n dimension: number;\n}\n\nexport function readEmbeddingIdentity(db: MemoryDb): EmbeddingIdentity | undefined {\n const get = (key: string): string | undefined => {\n const row = db.prepare(\"SELECT value FROM meta WHERE key = ?\").get(key);\n return row !== undefined ? String(row.value) : undefined;\n };\n const providerId = get(META_KEY_PROVIDER_ID);\n const model = get(META_KEY_MODEL);\n const dimRaw = get(META_KEY_DIMENSION);\n if (providerId === undefined || model === undefined || dimRaw === undefined) return undefined;\n const dimension = Number(dimRaw);\n if (!Number.isFinite(dimension) || dimension <= 0) return undefined;\n return { providerId, model, dimension };\n}\n\nexport function writeEmbeddingIdentity(db: MemoryDb, identity: EmbeddingIdentity): void {\n const stmt = db.prepare(\n \"INSERT INTO meta (key, value) VALUES (?, ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value\",\n );\n stmt.run(META_KEY_PROVIDER_ID, identity.providerId);\n stmt.run(META_KEY_MODEL, identity.model);\n stmt.run(META_KEY_DIMENSION, String(identity.dimension));\n}\n\nexport function identityMatches(a: EmbeddingIdentity, b: EmbeddingIdentity): boolean {\n return a.providerId === b.providerId && a.model === b.model && a.dimension === b.dimension;\n}\n\nexport function dropVectorIndex(db: MemoryDb): void {\n db.exec(\"DROP TABLE IF EXISTS embeddings\");\n}\n\nexport function createVectorIndex(db: MemoryDb, dimension: number): void {\n db.exec(`CREATE VIRTUAL TABLE IF NOT EXISTS embeddings USING vec0(\n chunk_id INTEGER PRIMARY KEY,\n vec FLOAT[${dimension}]\n )`);\n}\n\n/** Pack a Float32Array into a Buffer suitable for sqlite-vec BLOB binding. */\nexport function packVector(vec: ReadonlyArray<number>): Buffer {\n const f32 = new Float32Array(vec.length);\n for (let i = 0; i < vec.length; i++) f32[i] = vec[i] ?? 0;\n return Buffer.from(f32.buffer);\n}\n\nexport function upsertEmbedding(db: MemoryDb, chunkId: number, vec: ReadonlyArray<number>): void {\n // sqlite-vec vec0 virtual tables don't support UPSERT — emulate via\n // DELETE-then-INSERT. vec0 REJECTS JS Number for chunk_id columns; it\n // requires BigInt binding. Verified via repro against vec0 v0.1.9.\n const id = BigInt(chunkId);\n db.prepare(\"DELETE FROM embeddings WHERE chunk_id = ?\").run(id);\n db.prepare(\"INSERT INTO embeddings (chunk_id, vec) VALUES (?, ?)\").run(id, packVector(vec));\n}\n\nexport interface VectorHitRow {\n chunk_id: number;\n distance: number;\n}\n\nexport function vectorSearch(\n db: MemoryDb,\n query: ReadonlyArray<number>,\n k: number,\n): VectorHitRow[] {\n // sqlite-vec returns distance (lower = closer). Use KNN syntax. k needs\n // a BigInt-typed binding too.\n const rows = db\n .prepare(\n `SELECT chunk_id, distance FROM embeddings\n WHERE vec MATCH ? AND k = ?\n ORDER BY distance`,\n )\n .all(packVector(query), BigInt(k));\n return rows.map((row) => ({ chunk_id: Number(row.chunk_id), distance: Number(row.distance) }));\n}\n\nexport interface EmbedAllArgs {\n db: MemoryDb;\n runtime: EmbeddingRuntime;\n}\n\n/** Embed every chunk that doesn't yet have a vector. */\nexport async function embedMissingChunks(args: EmbedAllArgs): Promise<number> {\n const rows = args.db\n .prepare(\n `SELECT chunks.id as id, chunks.text as text\n FROM chunks\n LEFT JOIN embeddings ON embeddings.chunk_id = chunks.id\n WHERE embeddings.chunk_id IS NULL`,\n )\n .all();\n if (rows.length === 0) return 0;\n const normalized = rows.map((row) => ({ id: Number(row.id), text: String(row.text ?? \"\") }));\n const vectors = await args.runtime.embed(normalized.map((r) => r.text));\n for (let i = 0; i < normalized.length; i++) {\n const row = normalized[i];\n const vector = vectors[i];\n if (row === undefined || vector === undefined) continue;\n upsertEmbedding(args.db, row.id, vector);\n }\n return normalized.length;\n}\n","import { createHash } from \"node:crypto\";\nimport { readFile, stat } from \"node:fs/promises\";\nimport { sanitizeFts5Query } from \"../persistence/fts5-sanitize.js\";\nimport type { EmbeddingRuntime } from \"./embedding-adapter.js\";\nimport { LruEmbeddingCache } from \"./embedding-cache.js\";\nimport { escapeLikePattern } from \"./escape-like-pattern.js\";\nimport { defaultIndexPath, type MemoryDb, openMemoryDb } from \"./index-db.js\";\nimport { assertValidBackend, openLanceIndex } from \"./index-manager-dispatch.js\";\nimport {\n blendScores,\n collectMarkdownFiles,\n resolveWeights,\n sha256,\n truncateSnippet,\n} from \"./index-manager-helpers.js\";\nimport { type MemoryIndex, parseSearchOptions } from \"./memory-index.js\";\nimport { loadSqliteVecExtension } from \"./sqlite-vec-loader.js\";\nimport { chunkMarkdown } from \"./storage/chunk-markdown.js\";\n\n// T4.1 — query-vector LRU cache (DR4 finding #1). Keyed by\n// sha256(query); caches the embedding vector so repeated search\n// queries skip the HTTP round-trip (p99 1.5-3s → ~0ms on hit).\n// Process-wide singleton with bounded capacity (default 2000 queries).\nconst queryVectorCache = new LruEmbeddingCache(2000);\n\nimport {\n createVectorIndex,\n dropVectorIndex,\n embedMissingChunks,\n identityMatches,\n readEmbeddingIdentity,\n vectorSearch,\n writeEmbeddingIdentity,\n} from \"./vec-index.js\";\n\n/**\n * Memory index manager (ADR D2). FTS5-only at Phase 3; vector index lands in\n * Phase 5.\n *\n * Lifecycle:\n * const idx = await IndexManager.open({ cwd });\n * await idx.sync();\n * const hits = await idx.search(\"query\");\n * idx.close();\n *\n * @internal\n */\n\n// T2.1 / ADR D433 — these types now live in `index-manager-contract.ts`\n// to break the 3-cycle memory cluster. Re-exported here for back-compat\n// with downstream importers that historically pulled from this file.\nexport type {\n IndexStatus,\n MemoryBackend,\n MemorySearchHit,\n OpenIndexOptions,\n SearchOptions,\n} from \"./index-manager-contract.js\";\n\nimport type {\n IndexStatus,\n MemorySearchHit,\n OpenIndexOptions,\n SearchOptions,\n} from \"./index-manager-contract.js\";\n\nexport class IndexManager implements MemoryIndex {\n private lastSyncMs: number | undefined;\n private vectorReady = false;\n\n private constructor(\n private readonly cwd: string,\n private readonly db: MemoryDb,\n private readonly embedding: EmbeddingRuntime | undefined,\n ) {}\n\n /**\n * Open a memory index. Dispatches to SQLite (default) or Lance (opt-in\n * via `backend: \"lance\"`). See `openLanceInternal` for Lance-specific\n * preconditions + typed errors.\n */\n static async open(opts: OpenIndexOptions & { backend: \"lance\" }): Promise<MemoryIndex>;\n static async open(\n opts: Omit<OpenIndexOptions, \"backend\"> | (OpenIndexOptions & { backend?: \"sqlite-vec\" }),\n ): Promise<IndexManager>;\n static async open(opts: OpenIndexOptions): Promise<MemoryIndex> {\n const backend = opts.backend ?? \"sqlite-vec\";\n assertValidBackend(backend);\n if (backend === \"lance\") return await openLanceIndex(opts);\n return await IndexManager.openSqliteInternal(opts);\n }\n\n /** Internal SQLite-path open. Renamed from previous public `open`. */\n private static async openSqliteInternal(opts: OpenIndexOptions): Promise<IndexManager> {\n const filePath = opts.filePath ?? defaultIndexPath(opts.cwd);\n const db = await openMemoryDb({ filePath });\n const manager = new IndexManager(opts.cwd, db, opts.embedding);\n if (opts.embedding !== undefined) await manager.initVectorBackend(opts.embedding);\n return manager;\n }\n\n private async initVectorBackend(runtime: EmbeddingRuntime): Promise<void> {\n await loadSqliteVecExtension(this.db);\n const currentIdentity = {\n providerId: runtime.id,\n model: runtime.model,\n dimension: runtime.dimension,\n };\n const persisted = readEmbeddingIdentity(this.db);\n if (persisted !== undefined && !identityMatches(persisted, currentIdentity)) {\n // EC-1: dimension/model/provider changed — drop the vector index and\n // force a full re-embed on next sync.\n dropVectorIndex(this.db);\n }\n createVectorIndex(this.db, runtime.dimension);\n writeEmbeddingIdentity(this.db, currentIdentity);\n this.vectorReady = true;\n }\n\n /** Walk the memory corpus + (re)index changed files. */\n async sync(): Promise<{\n filesScanned: number;\n filesUpdated: number;\n chunksWritten: number;\n chunksEmbedded: number;\n }> {\n const files = await collectMarkdownFiles(this.cwd);\n let filesUpdated = 0;\n let chunksWritten = 0;\n const existingByPath = this.loadFilesIndex();\n for (const entry of files) {\n const raw = await readFile(entry.absolutePath, \"utf8\");\n const hash = sha256(raw);\n const existing = existingByPath.get(entry.absolutePath);\n if (existing !== undefined && existing.hash === hash) continue;\n const stats = await stat(entry.absolutePath);\n const fileId = this.upsertFile(\n entry.absolutePath,\n entry.relPath,\n hash,\n stats.mtimeMs,\n entry.source,\n );\n this.deleteChunksForFile(fileId);\n const chunks = chunkMarkdown(raw);\n for (const chunk of chunks) {\n this.insertChunk(fileId, chunk.startLine, chunk.endLine, chunk.text, chunk.hash);\n }\n filesUpdated += 1;\n chunksWritten += chunks.length;\n }\n let chunksEmbedded = 0;\n if (this.vectorReady && this.embedding !== undefined) {\n chunksEmbedded = await embedMissingChunks({ db: this.db, runtime: this.embedding });\n }\n this.lastSyncMs = Date.now();\n return { filesScanned: files.length, filesUpdated, chunksWritten, chunksEmbedded };\n }\n\n async search(query: string, options: SearchOptions = {}): Promise<MemorySearchHit[]> {\n if (query.trim().length === 0) return [];\n const { maxResults, minScore } = parseSearchOptions(options);\n const textHits = this.ftsSearch(query, maxResults * 2);\n const vectorHitsById = await this.vectorSearchById(query, maxResults * 2);\n const combined = this.combineHybridScores(textHits, vectorHitsById, options);\n return combined\n .filter((h) => h.score >= minScore)\n .filter((h) => options.sources === undefined || options.sources.includes(h.source))\n .slice(0, maxResults);\n }\n\n status(): IndexStatus {\n const files = this.db.prepare(\"SELECT COUNT(*) as n FROM files\").get() ?? { n: 0 };\n const chunks = this.db.prepare(\"SELECT COUNT(*) as n FROM chunks\").get() ?? { n: 0 };\n const status: IndexStatus = {\n backend: this.vectorReady ? \"hybrid\" : \"fts-only\",\n filesIndexed: Number(files.n ?? 0),\n chunksIndexed: Number(chunks.n ?? 0),\n };\n if (this.lastSyncMs !== undefined) status.lastSyncMs = this.lastSyncMs;\n return status;\n }\n\n // ───── search internals ──────────────────────────────────────────────\n\n private ftsSearch(query: string, limit: number): Array<MemorySearchHit & { chunkId: number }> {\n // EC-3: short-circuit when sanitizer reduces input to empty string.\n // Calling `MATCH ''` would error inside FTS5 on some SQLite versions.\n const sanitized = sanitizeFts5Query(query);\n if (sanitized.length === 0) return [];\n const stmt = this.db.prepare(\n `SELECT chunks.id as id, files.rel_path as rel_path, files.source as source,\n chunks.start_line as start_line, chunks.end_line as end_line,\n chunks.text as text, bm25(chunks_fts) as bm25_score\n FROM chunks_fts\n JOIN chunks ON chunks_fts.rowid = chunks.id\n JOIN files ON chunks.file_id = files.id\n WHERE chunks_fts MATCH ?\n ORDER BY bm25_score\n LIMIT ?`,\n );\n let rows: Array<Record<string, unknown>> = [];\n try {\n rows = stmt.all(sanitized, limit);\n } catch {\n // T4.8 — CJK fallback: FTS5's default tokenizer chokes on CJK\n // characters (no word boundaries). Instead of returning empty,\n // fall back to a LIKE search which handles CJK correctly (slower\n // but correct). ADR D64 documents the trigram-routing deferral.\n return this.likeSearchFallback(query, limit);\n }\n return rows.map((row) => {\n const bm25 = Number(row.bm25_score ?? 0);\n const textScore = bm25 < 0 ? 1 / (1 + Math.abs(bm25)) : 1 / (1 + bm25);\n const startLine = Number(row.start_line ?? 0);\n const endLine = Number(row.end_line ?? 0);\n const path = String(row.rel_path);\n return {\n path,\n startLine,\n endLine,\n score: textScore,\n textScore,\n snippet: truncateSnippet(String(row.text ?? \"\")),\n source: String(row.source) as \"memory\" | \"sessions\" | \"wiki\",\n citation: `${path}:${startLine}-${endLine}`,\n // sneak the chunk id through for the hybrid join below\n // (cast away later)\n chunkId: Number(row.id),\n } as MemorySearchHit & { chunkId: number };\n });\n }\n\n /**\n * T4.8 — LIKE-based fallback for CJK and other scripts that FTS5's\n * default tokenizer cannot segment. Slower than FTS5 (full table scan)\n * but correct for any Unicode input. Returns the same shape as\n * `ftsSearch` so callers are unaware of the fallback.\n */\n private likeSearchFallback(\n query: string,\n limit: number,\n ): Array<MemorySearchHit & { chunkId: number }> {\n const pattern = escapeLikePattern(query);\n const stmt = this.db.prepare(\n `SELECT chunks.id as id, files.rel_path as rel_path, files.source as source,\n chunks.start_line as start_line, chunks.end_line as end_line,\n chunks.text as text\n FROM chunks\n JOIN files ON chunks.file_id = files.id\n WHERE chunks.text LIKE ? ESCAPE '\\\\'\n LIMIT ?`,\n );\n const rows = stmt.all(pattern, limit) as Array<Record<string, unknown>>;\n return rows.map((row) => {\n const path = String(row.rel_path ?? \"\");\n const startLine = Number(row.start_line ?? 0);\n const endLine = Number(row.end_line ?? 0);\n return {\n path,\n startLine,\n endLine,\n score: 0.5, // LIKE has no relevance score — use a neutral midpoint\n textScore: 0.5,\n snippet: truncateSnippet(String(row.text ?? \"\")),\n source: String(row.source) as \"memory\" | \"sessions\" | \"wiki\",\n citation: `${path}:${startLine}-${endLine}`,\n chunkId: Number(row.id),\n } as MemorySearchHit & { chunkId: number };\n });\n }\n\n private async vectorSearchById(\n query: string,\n limit: number,\n ): Promise<Map<number, { vectorScore: number; snippet?: string }>> {\n if (!this.vectorReady || this.embedding === undefined) return new Map();\n // T4.1 — query-vector LRU cache. The embed call is the p99 hottest\n // path (1.5-3s per hit). Cache by sha256(query) so repeated queries\n // skip the HTTP round-trip entirely. The embedding cache (T4.4\n // globalEmbeddingCache) catches text-level dedup; this catches the\n // query-level search-result dedup on top.\n const cacheKey = createHash(\"sha256\").update(query).digest(\"hex\");\n const cached = queryVectorCache.get(cacheKey);\n const queryVec = cached ?? (await this.embedding.embed([query]))[0];\n if (queryVec === undefined) return new Map();\n if (cached === undefined) queryVectorCache.set(cacheKey, queryVec);\n const rows = vectorSearch(this.db, queryVec, limit);\n // sqlite-vec distance: lower = closer. Normalize to 0..1 with higher = better.\n const out = new Map<number, { vectorScore: number }>();\n for (const row of rows) {\n const score = 1 / (1 + Math.max(0, row.distance));\n out.set(row.chunk_id, { vectorScore: score });\n }\n return out;\n }\n\n private combineHybridScores(\n textHits: Array<MemorySearchHit & { chunkId: number }>,\n vectorHitsById: Map<number, { vectorScore: number }>,\n options: SearchOptions,\n ): MemorySearchHit[] {\n const weights = resolveWeights(options);\n const merged = this.mergeHits(textHits, vectorHitsById);\n const combined = [...merged.values()].map((hit) =>\n blendScores(hit, vectorHitsById.get(hit.chunkId)?.vectorScore ?? 0, weights),\n );\n return combined.sort((a, b) => b.score - a.score);\n }\n\n private mergeHits(\n textHits: Array<MemorySearchHit & { chunkId: number }>,\n vectorHitsById: Map<number, { vectorScore: number }>,\n ): Map<number, MemorySearchHit & { chunkId: number }> {\n const merged = new Map<number, MemorySearchHit & { chunkId: number }>();\n for (const hit of textHits) merged.set(hit.chunkId, hit);\n const missingIds = [...vectorHitsById.keys()].filter((id) => !merged.has(id));\n if (missingIds.length > 0) {\n for (const hit of this.fetchChunksByIds(missingIds)) {\n merged.set(hit.chunkId, { ...hit, score: 0, textScore: 0 });\n }\n }\n return merged;\n }\n\n private fetchChunksByIds(\n ids: ReadonlyArray<number>,\n ): Array<MemorySearchHit & { chunkId: number }> {\n if (ids.length === 0) return [];\n const placeholders = ids.map(() => \"?\").join(\",\");\n const rows = this.db\n .prepare(\n `SELECT chunks.id as id, files.rel_path as rel_path, files.source as source,\n chunks.start_line as start_line, chunks.end_line as end_line,\n chunks.text as text\n FROM chunks JOIN files ON chunks.file_id = files.id\n WHERE chunks.id IN (${placeholders})`,\n )\n .all(...ids);\n return rows.map((row) => {\n const startLine = Number(row.start_line ?? 0);\n const endLine = Number(row.end_line ?? 0);\n const path = String(row.rel_path);\n return {\n chunkId: Number(row.id),\n path,\n startLine,\n endLine,\n score: 0,\n textScore: 0,\n snippet: truncateSnippet(String(row.text ?? \"\")),\n source: String(row.source) as \"memory\" | \"sessions\" | \"wiki\",\n citation: `${path}:${startLine}-${endLine}`,\n };\n });\n }\n\n // ───── persistence helpers ─────────────────────────────────────────\n\n private loadFilesIndex(): Map<string, { id: number; hash: string }> {\n const rows = this.db.prepare(\"SELECT id, path, hash FROM files\").all() as Array<{\n id: number;\n path: string;\n hash: string;\n }>;\n return new Map(rows.map((row) => [row.path, { id: row.id, hash: row.hash }]));\n }\n\n private upsertFile(\n absPath: string,\n relPath: string,\n hash: string,\n mtimeMs: number,\n source: \"memory\" | \"wiki\" | \"sessions\" = \"memory\",\n ): number {\n const stmt = this.db.prepare(\n `INSERT INTO files (path, rel_path, mtime, hash, source) VALUES (?, ?, ?, ?, ?)\n ON CONFLICT(path) DO UPDATE SET hash = excluded.hash, mtime = excluded.mtime, source = excluded.source\n RETURNING id`,\n );\n const row = stmt.get(absPath, relPath, Math.floor(mtimeMs), hash, source) as { id: number };\n return row.id;\n }\n\n private deleteChunksForFile(fileId: number): void {\n this.db.prepare(\"DELETE FROM chunks WHERE file_id = ?\").run(fileId);\n }\n\n private insertChunk(\n fileId: number,\n startLine: number,\n endLine: number,\n text: string,\n hash: string,\n ): void {\n this.db\n .prepare(\n \"INSERT INTO chunks (file_id, start_line, end_line, text, hash) VALUES (?, ?, ?, ?, ?)\",\n )\n .run(fileId, startLine, endLine, text, hash);\n }\n\n close(): void {\n this.db.close();\n }\n}\n\n// Replaced by `sanitizeFts5Query` from `internal/persistence/fts5-sanitize.ts`\n// (T5.2, ADR D64). The new sanitizer is the 6-step port of Hermes'\n// `_sanitize_fts5_query` and handles hyphens/dots/underscores correctly\n// without quoting every token.\n"]}