@theokit/sdk 4.38.0 → 4.39.1

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 (378) hide show
  1. package/CHANGELOG.md +285 -0
  2. package/dist/a2a/index.cjs +3 -3
  3. package/dist/a2a/index.js +1 -1
  4. package/dist/a2a/subagent.d.cts +1 -0
  5. package/dist/a2a/subagent.d.ts +1 -0
  6. package/dist/agent-6ULDAQT7.js +46 -0
  7. package/dist/{agent-3H3UKD6U.js.map → agent-6ULDAQT7.js.map} +1 -1
  8. package/dist/{agent-U3lBX-5t.d.cts → agent-D7bRK9Kg.d.cts} +70 -5
  9. package/dist/agent-PVUKI3BB.cjs +55 -0
  10. package/dist/{agent-2GZC4W2A.cjs.map → agent-PVUKI3BB.cjs.map} +1 -1
  11. package/dist/{agent-C3AEtM-W.d.ts → agent-ZCZa7YQv.d.ts} +70 -5
  12. package/dist/agent-session-store-N4TVKHBU.cjs +23 -0
  13. package/dist/agent-session-store-N4TVKHBU.cjs.map +1 -0
  14. package/dist/agent-session-store-RHMHP5DG.js +6 -0
  15. package/dist/agent-session-store-RHMHP5DG.js.map +1 -0
  16. package/dist/agent.d.ts +37 -1
  17. package/dist/auth/index.cjs +15 -15
  18. package/dist/auth/index.js +4 -4
  19. package/dist/{batch-LXSALQC3.js → batch-6KQM3EBA.js} +12 -12
  20. package/dist/batch-6KQM3EBA.js.map +1 -0
  21. package/dist/{batch-NZGN6SFV.cjs → batch-X6JKGDPK.cjs} +26 -26
  22. package/dist/batch-X6JKGDPK.cjs.map +1 -0
  23. package/dist/chunk-2RW7K6FN.cjs +34 -0
  24. package/dist/chunk-2RW7K6FN.cjs.map +1 -0
  25. package/dist/chunk-3I4B3OIX.js +105 -0
  26. package/dist/chunk-3I4B3OIX.js.map +1 -0
  27. package/dist/{chunk-KWXC6ERT.js → chunk-42IFCKQZ.js} +5 -5
  28. package/dist/{chunk-KWXC6ERT.js.map → chunk-42IFCKQZ.js.map} +1 -1
  29. package/dist/{chunk-4APWS2YF.js → chunk-4F7JQZOX.js} +9 -36
  30. package/dist/chunk-4F7JQZOX.js.map +1 -0
  31. package/dist/{chunk-VYD6BGKK.js → chunk-4JSZYSGW.js} +3 -3
  32. package/dist/{chunk-VYD6BGKK.js.map → chunk-4JSZYSGW.js.map} +1 -1
  33. package/dist/{chunk-A6GXYF2Q.js → chunk-65ONFZWM.js} +7 -6
  34. package/dist/chunk-65ONFZWM.js.map +1 -0
  35. package/dist/{chunk-SGTMDQ4O.js → chunk-6EEYRFJC.js} +5 -5
  36. package/dist/{chunk-SGTMDQ4O.js.map → chunk-6EEYRFJC.js.map} +1 -1
  37. package/dist/{chunk-M4OGSS66.cjs → chunk-6LGQECT7.cjs} +11 -11
  38. package/dist/{chunk-M4OGSS66.cjs.map → chunk-6LGQECT7.cjs.map} +1 -1
  39. package/dist/{chunk-KTXOHCAE.cjs → chunk-6NEHIHFU.cjs} +4 -4
  40. package/dist/{chunk-KTXOHCAE.cjs.map → chunk-6NEHIHFU.cjs.map} +1 -1
  41. package/dist/chunk-6YNYA7GD.cjs +103 -0
  42. package/dist/chunk-6YNYA7GD.cjs.map +1 -0
  43. package/dist/{chunk-2R6NBT5F.cjs → chunk-74D7KSBP.cjs} +11 -11
  44. package/dist/{chunk-2R6NBT5F.cjs.map → chunk-74D7KSBP.cjs.map} +1 -1
  45. package/dist/{chunk-6OIO4FYX.cjs → chunk-75DSEWTJ.cjs} +7 -7
  46. package/dist/{chunk-6OIO4FYX.cjs.map → chunk-75DSEWTJ.cjs.map} +1 -1
  47. package/dist/{chunk-3XRXORBS.cjs → chunk-7OLG7VI4.cjs} +4 -4
  48. package/dist/{chunk-3XRXORBS.cjs.map → chunk-7OLG7VI4.cjs.map} +1 -1
  49. package/dist/chunk-7U2HAAWB.cjs +199 -0
  50. package/dist/chunk-7U2HAAWB.cjs.map +1 -0
  51. package/dist/{chunk-QJQ2MAZF.cjs → chunk-7YBJZS5P.cjs} +8 -8
  52. package/dist/{chunk-QJQ2MAZF.cjs.map → chunk-7YBJZS5P.cjs.map} +1 -1
  53. package/dist/{chunk-A4XXV2C6.js → chunk-7YSRCQDE.js} +5 -72
  54. package/dist/chunk-7YSRCQDE.js.map +1 -0
  55. package/dist/{chunk-ZFZYPLQI.js → chunk-AECV3G5Z.js} +4 -4
  56. package/dist/{chunk-ZFZYPLQI.js.map → chunk-AECV3G5Z.js.map} +1 -1
  57. package/dist/{chunk-QFWQLXCL.js → chunk-AR5MQZ3J.js} +3 -3
  58. package/dist/{chunk-QFWQLXCL.js.map → chunk-AR5MQZ3J.js.map} +1 -1
  59. package/dist/{chunk-G2F67XUR.cjs → chunk-B4YA6BRS.cjs} +13 -14
  60. package/dist/chunk-B4YA6BRS.cjs.map +1 -0
  61. package/dist/{chunk-BE3W4HYV.cjs → chunk-BCQ3E2ZG.cjs} +12 -3
  62. package/dist/chunk-BCQ3E2ZG.cjs.map +1 -0
  63. package/dist/{chunk-XJ5TMOGA.js → chunk-BQDUEG4C.js} +3 -3
  64. package/dist/{chunk-XJ5TMOGA.js.map → chunk-BQDUEG4C.js.map} +1 -1
  65. package/dist/{chunk-OFWU6UKF.cjs → chunk-C7OP3FAK.cjs} +47 -11
  66. package/dist/chunk-C7OP3FAK.cjs.map +1 -0
  67. package/dist/{chunk-UZBA6YYP.cjs → chunk-CAFV7WPQ.cjs} +540 -534
  68. package/dist/chunk-CAFV7WPQ.cjs.map +1 -0
  69. package/dist/{chunk-BUGVDCI5.cjs → chunk-CEIHCKTO.cjs} +4 -4
  70. package/dist/chunk-CEIHCKTO.cjs.map +1 -0
  71. package/dist/{chunk-3BSP7LSG.cjs → chunk-CN6UX5EV.cjs} +28 -56
  72. package/dist/chunk-CN6UX5EV.cjs.map +1 -0
  73. package/dist/{chunk-5BVBNE2F.js → chunk-D7IULBF2.js} +3 -3
  74. package/dist/{chunk-5BVBNE2F.js.map → chunk-D7IULBF2.js.map} +1 -1
  75. package/dist/{chunk-G7X2Y7Y2.cjs → chunk-DAXEQELR.cjs} +186 -236
  76. package/dist/chunk-DAXEQELR.cjs.map +1 -0
  77. package/dist/{chunk-YVI4YPUP.cjs → chunk-DGLLVCNB.cjs} +4 -4
  78. package/dist/{chunk-YVI4YPUP.cjs.map → chunk-DGLLVCNB.cjs.map} +1 -1
  79. package/dist/{chunk-JI34KBNC.js → chunk-DKFGUOWL.js} +3 -3
  80. package/dist/{chunk-JI34KBNC.js.map → chunk-DKFGUOWL.js.map} +1 -1
  81. package/dist/{chunk-ZET34IZE.cjs → chunk-DMTZ3FII.cjs} +5 -5
  82. package/dist/{chunk-ZET34IZE.cjs.map → chunk-DMTZ3FII.cjs.map} +1 -1
  83. package/dist/{chunk-6XZBKFQ7.js → chunk-DU7DE543.js} +3 -3
  84. package/dist/{chunk-6XZBKFQ7.js.map → chunk-DU7DE543.js.map} +1 -1
  85. package/dist/{chunk-VVMLMKYZ.cjs → chunk-DWY25VLP.cjs} +9 -9
  86. package/dist/{chunk-VVMLMKYZ.cjs.map → chunk-DWY25VLP.cjs.map} +1 -1
  87. package/dist/{chunk-R4AMI7KD.cjs → chunk-E4IUN3JB.cjs} +15 -15
  88. package/dist/{chunk-R4AMI7KD.cjs.map → chunk-E4IUN3JB.cjs.map} +1 -1
  89. package/dist/{chunk-TKDWD3MU.cjs → chunk-ECHGWE47.cjs} +4 -4
  90. package/dist/{chunk-TKDWD3MU.cjs.map → chunk-ECHGWE47.cjs.map} +1 -1
  91. package/dist/{chunk-KL7E244K.cjs → chunk-ECW2MLEW.cjs} +4 -4
  92. package/dist/{chunk-KL7E244K.cjs.map → chunk-ECW2MLEW.cjs.map} +1 -1
  93. package/dist/{chunk-EDI7DBWO.js → chunk-ET6PHZRX.js} +3 -3
  94. package/dist/{chunk-EDI7DBWO.js.map → chunk-ET6PHZRX.js.map} +1 -1
  95. package/dist/{chunk-HLK35TD7.cjs → chunk-FOZC5H7V.cjs} +24 -24
  96. package/dist/{chunk-HLK35TD7.cjs.map → chunk-FOZC5H7V.cjs.map} +1 -1
  97. package/dist/{chunk-SRIF7HMN.cjs → chunk-FWBSDQZ7.cjs} +5 -5
  98. package/dist/{chunk-SRIF7HMN.cjs.map → chunk-FWBSDQZ7.cjs.map} +1 -1
  99. package/dist/{chunk-XKBJT7WI.cjs → chunk-G2Q3ZC6C.cjs} +4 -4
  100. package/dist/{chunk-XKBJT7WI.cjs.map → chunk-G2Q3ZC6C.cjs.map} +1 -1
  101. package/dist/{chunk-4MWBKBS4.cjs → chunk-G4XUXSRN.cjs} +12 -12
  102. package/dist/{chunk-4MWBKBS4.cjs.map → chunk-G4XUXSRN.cjs.map} +1 -1
  103. package/dist/{chunk-EE24WJJR.js → chunk-GTVJIGAH.js} +5 -5
  104. package/dist/{chunk-EE24WJJR.js.map → chunk-GTVJIGAH.js.map} +1 -1
  105. package/dist/{chunk-VUDH4D2M.js → chunk-H3BOKK42.js} +282 -276
  106. package/dist/chunk-H3BOKK42.js.map +1 -0
  107. package/dist/{chunk-BT6DFWZB.cjs → chunk-HIQFVHC6.cjs} +9 -9
  108. package/dist/{chunk-BT6DFWZB.cjs.map → chunk-HIQFVHC6.cjs.map} +1 -1
  109. package/dist/{chunk-HI6G3SNY.js → chunk-HSPVMV6T.js} +76 -125
  110. package/dist/chunk-HSPVMV6T.js.map +1 -0
  111. package/dist/{chunk-UWEALKAN.js → chunk-HWNVAUK4.js} +3 -3
  112. package/dist/{chunk-UWEALKAN.js.map → chunk-HWNVAUK4.js.map} +1 -1
  113. package/dist/{chunk-3VKTDQMX.cjs → chunk-I53ZQHU6.cjs} +4 -4
  114. package/dist/{chunk-3VKTDQMX.cjs.map → chunk-I53ZQHU6.cjs.map} +1 -1
  115. package/dist/{chunk-A3MHE2MQ.cjs → chunk-IHFNRNTJ.cjs} +8 -8
  116. package/dist/{chunk-A3MHE2MQ.cjs.map → chunk-IHFNRNTJ.cjs.map} +1 -1
  117. package/dist/{chunk-KCZW75PI.js → chunk-IVSD7L22.js} +12 -4
  118. package/dist/chunk-IVSD7L22.js.map +1 -0
  119. package/dist/{chunk-JCXIDFRI.js → chunk-J3UK2GMN.js} +3 -3
  120. package/dist/{chunk-JCXIDFRI.js.map → chunk-J3UK2GMN.js.map} +1 -1
  121. package/dist/{chunk-IBDE4R5L.cjs → chunk-J6T5LWJ4.cjs} +10 -9
  122. package/dist/chunk-J6T5LWJ4.cjs.map +1 -0
  123. package/dist/{chunk-AOZYORH7.js → chunk-JRLXEYR4.js} +21 -5
  124. package/dist/chunk-JRLXEYR4.js.map +1 -0
  125. package/dist/{chunk-EUB7YLU2.js → chunk-JZUPMTJY.js} +3 -3
  126. package/dist/{chunk-EUB7YLU2.js.map → chunk-JZUPMTJY.js.map} +1 -1
  127. package/dist/{chunk-ZK3BJ4XQ.js → chunk-KE6XKRLQ.js} +3 -3
  128. package/dist/{chunk-ZK3BJ4XQ.js.map → chunk-KE6XKRLQ.js.map} +1 -1
  129. package/dist/{chunk-4NVV3GRU.js → chunk-KGRIHEDT.js} +5 -5
  130. package/dist/{chunk-4NVV3GRU.js.map → chunk-KGRIHEDT.js.map} +1 -1
  131. package/dist/{chunk-LGCEYEU2.js → chunk-KX7JV5KM.js} +3 -3
  132. package/dist/{chunk-LGCEYEU2.js.map → chunk-KX7JV5KM.js.map} +1 -1
  133. package/dist/{chunk-2K7PRHDB.cjs → chunk-LALG2K33.cjs} +8 -8
  134. package/dist/{chunk-2K7PRHDB.cjs.map → chunk-LALG2K33.cjs.map} +1 -1
  135. package/dist/{chunk-4WIJSKFA.js → chunk-LGILIGV3.js} +3 -3
  136. package/dist/{chunk-4WIJSKFA.js.map → chunk-LGILIGV3.js.map} +1 -1
  137. package/dist/{chunk-7QDTZJRV.js → chunk-LJX2SQV2.js} +6 -6
  138. package/dist/{chunk-7QDTZJRV.js.map → chunk-LJX2SQV2.js.map} +1 -1
  139. package/dist/{chunk-ACHGT3D2.js → chunk-MC5EINBV.js} +44 -8
  140. package/dist/chunk-MC5EINBV.js.map +1 -0
  141. package/dist/{chunk-M6UUTNDT.js → chunk-ML5A5DOJ.js} +4 -4
  142. package/dist/{chunk-M6UUTNDT.js.map → chunk-ML5A5DOJ.js.map} +1 -1
  143. package/dist/{chunk-3MUIYMUG.cjs → chunk-N475ETD6.cjs} +17 -17
  144. package/dist/{chunk-3MUIYMUG.cjs.map → chunk-N475ETD6.cjs.map} +1 -1
  145. package/dist/chunk-OXNYIMZZ.js +31 -0
  146. package/dist/chunk-OXNYIMZZ.js.map +1 -0
  147. package/dist/{chunk-YCHC45BY.js → chunk-PI4RO4GR.js} +3 -3
  148. package/dist/{chunk-YCHC45BY.js.map → chunk-PI4RO4GR.js.map} +1 -1
  149. package/dist/chunk-QKE556YD.js +197 -0
  150. package/dist/chunk-QKE556YD.js.map +1 -0
  151. package/dist/{chunk-FV3YEMQ7.js → chunk-RP5HQVLD.js} +13 -14
  152. package/dist/chunk-RP5HQVLD.js.map +1 -0
  153. package/dist/chunk-SCFW5MJZ.js +100 -0
  154. package/dist/chunk-SCFW5MJZ.js.map +1 -0
  155. package/dist/{chunk-ZYOHF37V.js → chunk-SG5ZWT6C.js} +3 -3
  156. package/dist/{chunk-ZYOHF37V.js.map → chunk-SG5ZWT6C.js.map} +1 -1
  157. package/dist/{chunk-ED7ANP6W.cjs → chunk-TIMPJL5V.cjs} +4 -4
  158. package/dist/{chunk-ED7ANP6W.cjs.map → chunk-TIMPJL5V.cjs.map} +1 -1
  159. package/dist/{chunk-3XKVRLR2.js → chunk-TOTP24P6.js} +4 -4
  160. package/dist/{chunk-3XKVRLR2.js.map → chunk-TOTP24P6.js.map} +1 -1
  161. package/dist/{chunk-PG3QQLWS.cjs → chunk-USZTVNUQ.cjs} +5 -5
  162. package/dist/{chunk-PG3QQLWS.cjs.map → chunk-USZTVNUQ.cjs.map} +1 -1
  163. package/dist/{chunk-XS7SKY2F.js → chunk-V2RBCCN5.js} +3 -3
  164. package/dist/chunk-V2RBCCN5.js.map +1 -0
  165. package/dist/{chunk-D3SJLXYZ.cjs → chunk-VJYSQXN6.cjs} +10 -10
  166. package/dist/{chunk-D3SJLXYZ.cjs.map → chunk-VJYSQXN6.cjs.map} +1 -1
  167. package/dist/{chunk-6ZGD7R27.cjs → chunk-VWI3CDEW.cjs} +8 -75
  168. package/dist/chunk-VWI3CDEW.cjs.map +1 -0
  169. package/dist/{chunk-MXRBNJ6D.cjs → chunk-W4WKVOOQ.cjs} +11 -11
  170. package/dist/{chunk-MXRBNJ6D.cjs.map → chunk-W4WKVOOQ.cjs.map} +1 -1
  171. package/dist/chunk-XYOHKCYG.cjs +109 -0
  172. package/dist/chunk-XYOHKCYG.cjs.map +1 -0
  173. package/dist/{chunk-UD2T7ISG.js → chunk-YP67XZES.js} +4 -4
  174. package/dist/{chunk-UD2T7ISG.js.map → chunk-YP67XZES.js.map} +1 -1
  175. package/dist/{chunk-HHUDNTZC.js → chunk-YRXY2A5L.js} +4 -4
  176. package/dist/{chunk-HHUDNTZC.js.map → chunk-YRXY2A5L.js.map} +1 -1
  177. package/dist/{chunk-6OKPJZMX.cjs → chunk-Z2CUEBXV.cjs} +25 -9
  178. package/dist/chunk-Z2CUEBXV.cjs.map +1 -0
  179. package/dist/compact-session-GKA7GFVT.js +18 -0
  180. package/dist/{compact-session-RR3ILTES.js.map → compact-session-GKA7GFVT.js.map} +1 -1
  181. package/dist/compact-session-XMP6OGY3.cjs +55 -0
  182. package/dist/{compact-session-YOWJJPPB.cjs.map → compact-session-XMP6OGY3.cjs.map} +1 -1
  183. package/dist/compaction.cjs +16 -16
  184. package/dist/compaction.js +3 -3
  185. package/dist/concurrency.cjs +6 -6
  186. package/dist/concurrency.js +4 -4
  187. package/dist/context-2FZSC6VQ.cjs +22 -0
  188. package/dist/{context-Q6ISOCN2.cjs.map → context-2FZSC6VQ.cjs.map} +1 -1
  189. package/dist/context-ATJJAFOS.js +5 -0
  190. package/dist/{context-ZDBBPIHY.js.map → context-ATJJAFOS.js.map} +1 -1
  191. package/dist/{cron-ChQ6zcW2.d.ts → cron-Bx7tzm5R.d.ts} +54 -2
  192. package/dist/{cron-BdXOZco9.d.cts → cron-D-DVjGQe.d.cts} +54 -2
  193. package/dist/cron.cjs +33 -29
  194. package/dist/cron.d.cts +3 -3
  195. package/dist/cron.d.ts +3 -3
  196. package/dist/cron.js +32 -28
  197. package/dist/{errors-BUVjJGJA.d.cts → errors-DMY-gLSK.d.cts} +1 -1
  198. package/dist/{errors-CZIUKLHt.d.ts → errors-DjBQ4Tn8.d.ts} +1 -1
  199. package/dist/errors.cjs +21 -21
  200. package/dist/errors.d.cts +2 -2
  201. package/dist/errors.d.ts +2 -2
  202. package/dist/errors.js +2 -2
  203. package/dist/eval.cjs +41 -36
  204. package/dist/eval.cjs.map +1 -1
  205. package/dist/eval.js +37 -32
  206. package/dist/eval.js.map +1 -1
  207. package/dist/{executor-DPCBSI35.cjs → executor-BMRICN46.cjs} +26 -25
  208. package/dist/executor-BMRICN46.cjs.map +1 -0
  209. package/dist/{executor-ASDDIM2X.js → executor-T65PPOPT.js} +10 -9
  210. package/dist/executor-T65PPOPT.js.map +1 -0
  211. package/dist/filesystem/index.cjs +7 -7
  212. package/dist/filesystem/index.js +3 -3
  213. package/dist/fs-session-store-J5MCFFUM.cjs +19 -0
  214. package/dist/{fs-session-store-T5ZLQX42.cjs.map → fs-session-store-J5MCFFUM.cjs.map} +1 -1
  215. package/dist/fs-session-store-O6FNHECD.js +10 -0
  216. package/dist/{fs-session-store-K5QUPNJZ.js.map → fs-session-store-O6FNHECD.js.map} +1 -1
  217. package/dist/generate-object-UF6WIZLF.cjs +20 -0
  218. package/dist/{generate-object-F56VIZ6U.cjs.map → generate-object-UF6WIZLF.cjs.map} +1 -1
  219. package/dist/generate-object-XDCBYVK3.js +7 -0
  220. package/dist/{generate-object-LPSO6GVW.js.map → generate-object-XDCBYVK3.js.map} +1 -1
  221. package/dist/index-manager-N7RQYUKT.cjs +20 -0
  222. package/dist/{index-manager-DBJ55ZSO.cjs.map → index-manager-N7RQYUKT.cjs.map} +1 -1
  223. package/dist/index-manager-ZVZUHPP7.js +11 -0
  224. package/dist/{index-manager-F2H2RCZU.js.map → index-manager-ZVZUHPP7.js.map} +1 -1
  225. package/dist/index.cjs +138 -132
  226. package/dist/index.cjs.map +1 -1
  227. package/dist/index.d.cts +167 -9
  228. package/dist/index.d.ts +167 -9
  229. package/dist/index.js +47 -44
  230. package/dist/index.js.map +1 -1
  231. package/dist/{inject-session-RKNLUE72.js → inject-session-7P4CZGDT.js} +7 -6
  232. package/dist/inject-session-7P4CZGDT.js.map +1 -0
  233. package/dist/{inject-session-25EC74WV.cjs → inject-session-CC4KBYF6.cjs} +9 -8
  234. package/dist/inject-session-CC4KBYF6.cjs.map +1 -0
  235. package/dist/internal/agent-loop/loop-thinking-steps.d.ts +28 -0
  236. package/dist/internal/agent-loop/message-builders.d.ts +12 -3
  237. package/dist/internal/diagnostics.d.ts +24 -11
  238. package/dist/internal/llm/anthropic-shared.d.ts +4 -4
  239. package/dist/internal/llm/types.d.ts +49 -9
  240. package/dist/internal/local-agent/mcp-pool.d.ts +7 -3
  241. package/dist/internal/memory/adapters/azure-openai-embedding.d.cts +2 -0
  242. package/dist/internal/memory/adapters/catalog.d.cts +1 -0
  243. package/dist/internal/memory/adapters/cohere-embedding.d.cts +2 -0
  244. package/dist/internal/memory/adapters/deepinfra-embedding.d.cts +2 -0
  245. package/dist/internal/memory/adapters/gemini-embedding.d.cts +2 -0
  246. package/dist/internal/memory/adapters/index.cjs +28 -0
  247. package/dist/internal/memory/adapters/index.cjs.map +1 -0
  248. package/dist/internal/memory/adapters/index.d.cts +16 -0
  249. package/dist/internal/memory/adapters/index.d.ts +16 -0
  250. package/dist/internal/memory/adapters/index.js +11 -0
  251. package/dist/internal/memory/adapters/index.js.map +1 -0
  252. package/dist/internal/memory/adapters/jina-embedding.d.cts +2 -0
  253. package/dist/internal/memory/adapters/mistral-embedding.d.cts +2 -0
  254. package/dist/internal/memory/adapters/ollama-embedding.d.cts +34 -0
  255. package/dist/internal/memory/adapters/openai-compatible.d.cts +51 -0
  256. package/dist/internal/memory/adapters/openai-compatible.d.ts +28 -0
  257. package/dist/internal/memory/adapters/openai-embedding.d.cts +2 -0
  258. package/dist/internal/memory/adapters/openrouter-embedding.d.cts +2 -0
  259. package/dist/internal/memory/adapters/voyage-embedding.d.cts +2 -0
  260. package/dist/internal/memory/dreaming/diary.d.ts +4 -0
  261. package/dist/internal/memory/dreaming/phases.d.ts +15 -0
  262. package/dist/internal/memory/dreaming/run.d.ts +10 -0
  263. package/dist/internal/memory/migrate-sqlite-to-lance.d.ts +15 -0
  264. package/dist/internal/memory/sdk-memory-peer-loader.d.ts +21 -0
  265. package/dist/internal/persistence/index.cjs +25 -25
  266. package/dist/internal/persistence/index.js +6 -6
  267. package/dist/internal/persistence/session-transcript.d.cts +6 -0
  268. package/dist/internal/persistence/session-transcript.d.ts +6 -0
  269. package/dist/internal/runtime/concurrency/subagent-credentials.d.ts +35 -0
  270. package/dist/internal/security/index.cjs +13 -13
  271. package/dist/internal/security/index.js +3 -3
  272. package/dist/internal/session/agent-session-store.d.ts +1 -0
  273. package/dist/internal/session/session-types.d.ts +6 -1
  274. package/dist/judge-call-NA2G6ZMJ.js +5 -0
  275. package/dist/{judge-call-3S3T6O2Z.js.map → judge-call-NA2G6ZMJ.js.map} +1 -1
  276. package/dist/judge-call-U2D33JOW.cjs +22 -0
  277. package/dist/{judge-call-XIQJ5GIE.cjs.map → judge-call-U2D33JOW.cjs.map} +1 -1
  278. package/dist/models.cjs +20 -20
  279. package/dist/models.js +5 -5
  280. package/dist/path-safety.cjs +10 -10
  281. package/dist/path-safety.js +3 -3
  282. package/dist/persistence.cjs +35 -35
  283. package/dist/persistence.js +7 -7
  284. package/dist/project.cjs +5 -5
  285. package/dist/project.js +3 -3
  286. package/dist/registry-CAS6Y5ZY.js +9 -0
  287. package/dist/{registry-KMI5RA22.js.map → registry-CAS6Y5ZY.js.map} +1 -1
  288. package/dist/registry-JSDI4WKA.cjs +46 -0
  289. package/dist/{registry-BA3SLAN7.cjs.map → registry-JSDI4WKA.cjs.map} +1 -1
  290. package/dist/retry.cjs +4 -4
  291. package/dist/retry.js +3 -3
  292. package/dist/{run-vJHg2eGw.d.cts → run-i2-fUohR.d.cts} +16 -0
  293. package/dist/{run-vJHg2eGw.d.ts → run-i2-fUohR.d.ts} +16 -0
  294. package/dist/sandbox/index.cjs +6 -6
  295. package/dist/sandbox/index.js +2 -2
  296. package/dist/server/errors-envelope.cjs +14 -14
  297. package/dist/server/errors-envelope.d.cts +3 -3
  298. package/dist/server/errors-envelope.d.ts +3 -3
  299. package/dist/server/errors-envelope.js +3 -3
  300. package/dist/session-transcript-3B52DKTG.js +5 -0
  301. package/dist/{session-transcript-MMPWCESR.js.map → session-transcript-3B52DKTG.js.map} +1 -1
  302. package/dist/session-transcript-H7NUFXXM.cjs +50 -0
  303. package/dist/{session-transcript-DFGX6WNL.cjs.map → session-transcript-H7NUFXXM.cjs.map} +1 -1
  304. package/dist/skills.cjs +7 -7
  305. package/dist/skills.js +5 -5
  306. package/dist/stream-object-4FDU76YW.cjs +20 -0
  307. package/dist/{stream-object-YPXZ4F5P.cjs.map → stream-object-4FDU76YW.cjs.map} +1 -1
  308. package/dist/stream-object-HWDEEQN4.js +7 -0
  309. package/dist/{stream-object-AFERZU63.js.map → stream-object-HWDEEQN4.js.map} +1 -1
  310. package/dist/subagents-loader-A4W6C3QP.cjs +15 -0
  311. package/dist/subagents-loader-A4W6C3QP.cjs.map +1 -0
  312. package/dist/subagents-loader-X33KH2SZ.js +6 -0
  313. package/dist/subagents-loader-X33KH2SZ.js.map +1 -0
  314. package/dist/subagents-loader.cjs +6 -6
  315. package/dist/subagents-loader.d.cts +2 -2
  316. package/dist/subagents-loader.d.ts +2 -2
  317. package/dist/subagents-loader.js +4 -4
  318. package/dist/subscription/index.cjs +3 -3
  319. package/dist/subscription/index.js +2 -2
  320. package/dist/task-store.cjs +7 -7
  321. package/dist/task-store.js +4 -4
  322. package/dist/types/agent.d.ts +68 -3
  323. package/dist/types/conversation.d.ts +7 -0
  324. package/dist/types/messages.d.ts +9 -0
  325. package/dist/types/session-message.d.ts +59 -0
  326. package/dist/types/workflow.d.ts +36 -0
  327. package/dist/workflow.cjs +27 -27
  328. package/dist/workflow.d.cts +17 -1
  329. package/dist/workflow.d.ts +17 -1
  330. package/dist/workflow.js +6 -6
  331. package/docs/harness-capability-map.md +22 -0
  332. package/package.json +11 -1
  333. package/dist/agent-2GZC4W2A.cjs +0 -51
  334. package/dist/agent-3H3UKD6U.js +0 -42
  335. package/dist/batch-LXSALQC3.js.map +0 -1
  336. package/dist/batch-NZGN6SFV.cjs.map +0 -1
  337. package/dist/chunk-3BSP7LSG.cjs.map +0 -1
  338. package/dist/chunk-4APWS2YF.js.map +0 -1
  339. package/dist/chunk-6OKPJZMX.cjs.map +0 -1
  340. package/dist/chunk-6ZGD7R27.cjs.map +0 -1
  341. package/dist/chunk-A4XXV2C6.js.map +0 -1
  342. package/dist/chunk-A6GXYF2Q.js.map +0 -1
  343. package/dist/chunk-ACHGT3D2.js.map +0 -1
  344. package/dist/chunk-AOZYORH7.js.map +0 -1
  345. package/dist/chunk-BE3W4HYV.cjs.map +0 -1
  346. package/dist/chunk-BUGVDCI5.cjs.map +0 -1
  347. package/dist/chunk-FV3YEMQ7.js.map +0 -1
  348. package/dist/chunk-G2F67XUR.cjs.map +0 -1
  349. package/dist/chunk-G7X2Y7Y2.cjs.map +0 -1
  350. package/dist/chunk-HI6G3SNY.js.map +0 -1
  351. package/dist/chunk-IBDE4R5L.cjs.map +0 -1
  352. package/dist/chunk-KCZW75PI.js.map +0 -1
  353. package/dist/chunk-OFWU6UKF.cjs.map +0 -1
  354. package/dist/chunk-UZBA6YYP.cjs.map +0 -1
  355. package/dist/chunk-VUDH4D2M.js.map +0 -1
  356. package/dist/chunk-XS7SKY2F.js.map +0 -1
  357. package/dist/compact-session-RR3ILTES.js +0 -17
  358. package/dist/compact-session-YOWJJPPB.cjs +0 -54
  359. package/dist/context-Q6ISOCN2.cjs +0 -22
  360. package/dist/context-ZDBBPIHY.js +0 -5
  361. package/dist/executor-ASDDIM2X.js.map +0 -1
  362. package/dist/executor-DPCBSI35.cjs.map +0 -1
  363. package/dist/fs-session-store-K5QUPNJZ.js +0 -10
  364. package/dist/fs-session-store-T5ZLQX42.cjs +0 -19
  365. package/dist/generate-object-F56VIZ6U.cjs +0 -20
  366. package/dist/generate-object-LPSO6GVW.js +0 -7
  367. package/dist/index-manager-DBJ55ZSO.cjs +0 -19
  368. package/dist/index-manager-F2H2RCZU.js +0 -10
  369. package/dist/inject-session-25EC74WV.cjs.map +0 -1
  370. package/dist/inject-session-RKNLUE72.js.map +0 -1
  371. package/dist/judge-call-3S3T6O2Z.js +0 -5
  372. package/dist/judge-call-XIQJ5GIE.cjs +0 -22
  373. package/dist/registry-BA3SLAN7.cjs +0 -46
  374. package/dist/registry-KMI5RA22.js +0 -9
  375. package/dist/session-transcript-DFGX6WNL.cjs +0 -50
  376. package/dist/session-transcript-MMPWCESR.js +0 -5
  377. package/dist/stream-object-AFERZU63.js +0 -7
  378. package/dist/stream-object-YPXZ4F5P.cjs +0 -20
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/internal/runtime/retry/with-retry.ts","../src/retry.ts"],"names":[],"mappings":"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","file":"chunk-VYD6BGKK.js","sourcesContent":["/**\n * Generic retry wrapper (plan m0-foundation-expose-primitives, M0-3).\n *\n * Exponential backoff with full jitter, deterministically testable via an\n * injectable `sleep` and `rng` (no real timers in unit tests, per the repo\n * testing rule). The default `isRetryable` predicate is {@link isTransientError}\n * so SDK errors retry exactly as the SDK classifies them. The workflow-internal\n * `withRetry` (RetryPolicy-coupled) is intentionally separate (ADR-M0-3).\n *\n * @internal — public via `@theokit/sdk/retry`\n */\n\nimport { ConfigurationError, isTransientError } from \"../../../errors.js\";\n\n/** Options for {@link withRetry}. All fields optional; sensible defaults applied. */\nexport interface RetryOptions {\n /** Number of retries after the first attempt (total attempts = retries + 1). Default 3. */\n retries?: number;\n /** Predicate deciding whether a thrown error is worth retrying. Default {@link isTransientError}. */\n isRetryable?: (err: unknown) => boolean;\n /** Base backoff in ms for the first retry. Default 100. */\n initialDelayMs?: number;\n /** Upper bound for a single backoff sleep. Default 30_000. */\n maxDelayMs?: number;\n /** Exponential multiplier applied per retry. Default 2. */\n backoffMultiplier?: number;\n /** [0, 1) source for full-jitter. Default `Math.random`. Inject for deterministic tests. */\n rng?: () => number;\n /** Sleep function. Default a `setTimeout`-based abortable sleep. Inject for deterministic tests. */\n sleep?: (ms: number, signal?: AbortSignal) => Promise<void>;\n /** Abort signal; once aborted, the abortable default sleep rejects and the loop stops. */\n signal?: AbortSignal;\n}\n\nfunction defaultSleep(ms: number, signal?: AbortSignal): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n if (signal?.aborted) {\n reject(signal.reason instanceof Error ? signal.reason : new Error(\"withRetry: aborted\"));\n return;\n }\n const timer = setTimeout(() => {\n signal?.removeEventListener(\"abort\", onAbort);\n resolve();\n }, ms);\n function onAbort(): void {\n clearTimeout(timer);\n reject(signal?.reason instanceof Error ? signal.reason : new Error(\"withRetry: aborted\"));\n }\n signal?.addEventListener(\"abort\", onAbort, { once: true });\n });\n}\n\ninterface ResolvedRetry {\n retries: number;\n isRetryable: (err: unknown) => boolean;\n initialDelayMs: number;\n maxDelayMs: number;\n backoffMultiplier: number;\n rng: () => number;\n sleep: (ms: number, signal?: AbortSignal) => Promise<void>;\n signal?: AbortSignal;\n}\n\nfunction resolveRetryOptions(options?: RetryOptions): ResolvedRetry {\n const retries = options?.retries ?? 3;\n if (!Number.isInteger(retries) || retries < 0) {\n throw new ConfigurationError(\n `withRetry: retries must be a non-negative integer, got ${retries}`,\n { code: \"invalid_retry_config\" },\n );\n }\n return {\n retries,\n isRetryable: options?.isRetryable ?? isTransientError,\n initialDelayMs: options?.initialDelayMs ?? 100,\n maxDelayMs: options?.maxDelayMs ?? 30_000,\n backoffMultiplier: options?.backoffMultiplier ?? 2,\n rng: options?.rng ?? Math.random,\n sleep: options?.sleep ?? defaultSleep,\n signal: options?.signal,\n };\n}\n\n/** Full-jitter backoff for the given (0-indexed) retry attempt. */\nfunction backoffMs(cfg: ResolvedRetry, attempt: number): number {\n const ceiling = Math.min(cfg.maxDelayMs, cfg.initialDelayMs * cfg.backoffMultiplier ** attempt);\n return Math.floor(cfg.rng() * ceiling);\n}\n\n/**\n * Run `fn`, retrying transient failures with exponential backoff + full jitter.\n *\n * @returns the resolved value of the first successful `fn()` call\n * @throws the last error when retries are exhausted or the error is not retryable\n *\n * @example\n * const data = await withRetry(() => fetchJson(url)); // retries rate-limit/network\n */\nexport async function withRetry<T>(fn: () => Promise<T>, options?: RetryOptions): Promise<T> {\n const cfg = resolveRetryOptions(options);\n let attempt = 0;\n for (;;) {\n try {\n return await fn();\n } catch (err) {\n if (attempt >= cfg.retries || !cfg.isRetryable(err)) throw err;\n await cfg.sleep(backoffMs(cfg, attempt), cfg.signal);\n attempt += 1;\n }\n }\n}\n","/**\n * Public generic retry primitive (plan m0-foundation-expose-primitives, M0-3).\n *\n * Split into its own top-level module so `tsup` builds a dedicated\n * `@theokit/sdk/retry` sub-path entry, mirroring the `path-safety` pattern.\n * The default retry predicate is `isTransientError`, so retries follow the\n * SDK's own error classification.\n */\n\nimport { type RetryOptions, withRetry } from \"./internal/runtime/retry/with-retry.js\";\n\nexport type { RetryOptions };\n\n/**\n * SE36 — `Retry.create` replaces `withRetry` (ADR 0015 / ADR-P2). NOTE: `withRetry` is an\n * EXECUTOR, not a constructor — `Retry.create(fn, opts)` RUNS `fn` with retry and resolves to\n * its result (`Promise<T>`), not a `Retry` instance. The `.create` name is the uniformity\n * mandate; the executor semantics are the documented, accepted awkwardness. @public\n */\nexport class Retry {\n private constructor() {}\n static create<T>(fn: () => Promise<T>, options?: RetryOptions): Promise<T> {\n return withRetry(fn, options);\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/internal/runtime/retry/with-retry.ts","../src/retry.ts"],"names":[],"mappings":"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","file":"chunk-4JSZYSGW.js","sourcesContent":["/**\n * Generic retry wrapper (plan m0-foundation-expose-primitives, M0-3).\n *\n * Exponential backoff with full jitter, deterministically testable via an\n * injectable `sleep` and `rng` (no real timers in unit tests, per the repo\n * testing rule). The default `isRetryable` predicate is {@link isTransientError}\n * so SDK errors retry exactly as the SDK classifies them. The workflow-internal\n * `withRetry` (RetryPolicy-coupled) is intentionally separate (ADR-M0-3).\n *\n * @internal — public via `@theokit/sdk/retry`\n */\n\nimport { ConfigurationError, isTransientError } from \"../../../errors.js\";\n\n/** Options for {@link withRetry}. All fields optional; sensible defaults applied. */\nexport interface RetryOptions {\n /** Number of retries after the first attempt (total attempts = retries + 1). Default 3. */\n retries?: number;\n /** Predicate deciding whether a thrown error is worth retrying. Default {@link isTransientError}. */\n isRetryable?: (err: unknown) => boolean;\n /** Base backoff in ms for the first retry. Default 100. */\n initialDelayMs?: number;\n /** Upper bound for a single backoff sleep. Default 30_000. */\n maxDelayMs?: number;\n /** Exponential multiplier applied per retry. Default 2. */\n backoffMultiplier?: number;\n /** [0, 1) source for full-jitter. Default `Math.random`. Inject for deterministic tests. */\n rng?: () => number;\n /** Sleep function. Default a `setTimeout`-based abortable sleep. Inject for deterministic tests. */\n sleep?: (ms: number, signal?: AbortSignal) => Promise<void>;\n /** Abort signal; once aborted, the abortable default sleep rejects and the loop stops. */\n signal?: AbortSignal;\n}\n\nfunction defaultSleep(ms: number, signal?: AbortSignal): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n if (signal?.aborted) {\n reject(signal.reason instanceof Error ? signal.reason : new Error(\"withRetry: aborted\"));\n return;\n }\n const timer = setTimeout(() => {\n signal?.removeEventListener(\"abort\", onAbort);\n resolve();\n }, ms);\n function onAbort(): void {\n clearTimeout(timer);\n reject(signal?.reason instanceof Error ? signal.reason : new Error(\"withRetry: aborted\"));\n }\n signal?.addEventListener(\"abort\", onAbort, { once: true });\n });\n}\n\ninterface ResolvedRetry {\n retries: number;\n isRetryable: (err: unknown) => boolean;\n initialDelayMs: number;\n maxDelayMs: number;\n backoffMultiplier: number;\n rng: () => number;\n sleep: (ms: number, signal?: AbortSignal) => Promise<void>;\n signal?: AbortSignal;\n}\n\nfunction resolveRetryOptions(options?: RetryOptions): ResolvedRetry {\n const retries = options?.retries ?? 3;\n if (!Number.isInteger(retries) || retries < 0) {\n throw new ConfigurationError(\n `withRetry: retries must be a non-negative integer, got ${retries}`,\n { code: \"invalid_retry_config\" },\n );\n }\n return {\n retries,\n isRetryable: options?.isRetryable ?? isTransientError,\n initialDelayMs: options?.initialDelayMs ?? 100,\n maxDelayMs: options?.maxDelayMs ?? 30_000,\n backoffMultiplier: options?.backoffMultiplier ?? 2,\n rng: options?.rng ?? Math.random,\n sleep: options?.sleep ?? defaultSleep,\n signal: options?.signal,\n };\n}\n\n/** Full-jitter backoff for the given (0-indexed) retry attempt. */\nfunction backoffMs(cfg: ResolvedRetry, attempt: number): number {\n const ceiling = Math.min(cfg.maxDelayMs, cfg.initialDelayMs * cfg.backoffMultiplier ** attempt);\n return Math.floor(cfg.rng() * ceiling);\n}\n\n/**\n * Run `fn`, retrying transient failures with exponential backoff + full jitter.\n *\n * @returns the resolved value of the first successful `fn()` call\n * @throws the last error when retries are exhausted or the error is not retryable\n *\n * @example\n * const data = await withRetry(() => fetchJson(url)); // retries rate-limit/network\n */\nexport async function withRetry<T>(fn: () => Promise<T>, options?: RetryOptions): Promise<T> {\n const cfg = resolveRetryOptions(options);\n let attempt = 0;\n for (;;) {\n try {\n return await fn();\n } catch (err) {\n if (attempt >= cfg.retries || !cfg.isRetryable(err)) throw err;\n await cfg.sleep(backoffMs(cfg, attempt), cfg.signal);\n attempt += 1;\n }\n }\n}\n","/**\n * Public generic retry primitive (plan m0-foundation-expose-primitives, M0-3).\n *\n * Split into its own top-level module so `tsup` builds a dedicated\n * `@theokit/sdk/retry` sub-path entry, mirroring the `path-safety` pattern.\n * The default retry predicate is `isTransientError`, so retries follow the\n * SDK's own error classification.\n */\n\nimport { type RetryOptions, withRetry } from \"./internal/runtime/retry/with-retry.js\";\n\nexport type { RetryOptions };\n\n/**\n * SE36 — `Retry.create` replaces `withRetry` (ADR 0015 / ADR-P2). NOTE: `withRetry` is an\n * EXECUTOR, not a constructor — `Retry.create(fn, opts)` RUNS `fn` with retry and resolves to\n * its result (`Promise<T>`), not a `Retry` instance. The `.create` name is the uniformity\n * mandate; the executor semantics are the documented, accepted awkwardness. @public\n */\nexport class Retry {\n private constructor() {}\n static create<T>(fn: () => Promise<T>, options?: RetryOptions): Promise<T> {\n return withRetry(fn, options);\n }\n}\n"]}
@@ -1,5 +1,5 @@
1
- import { TheokitAgentError } from './chunk-ZYOHF37V.js';
2
- import { redactSecrets } from './chunk-KCZW75PI.js';
1
+ import { TheokitAgentError } from './chunk-SG5ZWT6C.js';
2
+ import { diag, redactSecrets } from './chunk-IVSD7L22.js';
3
3
 
4
4
  // src/internal/runtime/compression/compression-helpers.ts
5
5
  function selectCompressionWindow(messages, preserveLast = 6) {
@@ -71,8 +71,9 @@ async function runSummarize(summarize, head, template, failSafe) {
71
71
  return await summarize(head, template);
72
72
  } catch (err) {
73
73
  if (!failSafe) throw err;
74
- console.warn(
75
- `[compaction] summarizer failed \u2014 proceeding uncompacted: ${redactSecrets(err instanceof Error ? err.message : String(err))}`
74
+ diag(
75
+ `[compaction] summarizer failed \u2014 proceeding uncompacted: ${redactSecrets(err instanceof Error ? err.message : String(err))}
76
+ `
76
77
  );
77
78
  return FAILSAFE_ABORT;
78
79
  }
@@ -152,5 +153,5 @@ function shouldCompact(input) {
152
153
  }
153
154
 
154
155
  export { ABSOLUTE_CONTEXT_WINDOW_CAP, CHECKPOINT_MARKER, CONTEXT_WINDOW_FLOOR, CONTEXT_WINDOW_MARGIN, ContextWindowMarginError, SUMMARY_TEMPLATE, buildCheckpoint, compactTranscript, estimateTokens, filterFromLatestCheckpoint, isContextOverflowError, resolveEffectiveContextWindow, shouldCompact };
155
- //# sourceMappingURL=chunk-A6GXYF2Q.js.map
156
- //# sourceMappingURL=chunk-A6GXYF2Q.js.map
156
+ //# sourceMappingURL=chunk-65ONFZWM.js.map
157
+ //# sourceMappingURL=chunk-65ONFZWM.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/internal/runtime/compression/compression-helpers.ts","../src/compaction.ts"],"names":[],"mappings":"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","file":"chunk-65ONFZWM.js","sourcesContent":["/**\n * Compression helpers (T2.3, ADR D92).\n *\n * Scaffold for future compression LLM integration:\n * - `selectCompressionWindow` — splits messages into compress/preserve halves\n * - `assertCompressionReduced` — 10% reduction floor to detect \"compression placebo\"\n *\n * The compression LLM call itself is out of scope for this plan (requires\n * an auxiliary-model ADR). These helpers are used by `Agent.send` when a\n * future iteration adds compression.\n *\n * @internal\n */\n\nexport interface CompressionWindow<M> {\n toCompress: M[];\n toPreserve: M[];\n}\n\n/**\n * Split `messages` into the half to compress (older) and the half to\n * preserve verbatim (recent). When `messages.length <= preserveLast`,\n * everything is preserved.\n *\n * @internal\n */\nexport function selectCompressionWindow<M>(\n messages: readonly M[],\n preserveLast = 6,\n): CompressionWindow<M> {\n if (messages.length <= preserveLast) {\n return { toCompress: [], toPreserve: [...messages] };\n }\n return {\n toCompress: messages.slice(0, -preserveLast),\n toPreserve: messages.slice(-preserveLast),\n };\n}\n\nexport interface CompressionCheck {\n reduced: boolean;\n reductionPct: number;\n reason?: string;\n}\n\n/**\n * Check that compression actually reduced token count by at least `minPct`\n * (default 10%). Returns `{ reduced: false }` for spirals-in-formation\n * (compression LLM outputs that grow or barely shrink).\n *\n * @internal\n */\nexport function assertCompressionReduced(\n before: number,\n after: number,\n minPct = 10,\n): CompressionCheck {\n if (before <= 0) {\n return { reduced: false, reductionPct: 0, reason: \"before count was zero\" };\n }\n const reductionPct = ((before - after) / before) * 100;\n if (reductionPct >= minPct) {\n return { reduced: true, reductionPct };\n }\n return {\n reduced: false,\n reductionPct,\n reason: `compression reduced ${reductionPct.toFixed(1)}% (< ${minPct}% min). Spiral likely.`,\n };\n}\n","/**\n * Public compaction / context-management helpers (M2-1, extended V3-3).\n *\n * Promotes the SDK's compaction capability to a public surface so consumers can\n * compact a transcript, mark/filter conversation checkpoints, and detect\n * context-overflow — without reaching into `internal/`.\n *\n * Two recent-window modes (V3-3):\n * - `keepRecent` (turn-count, default) — keeps the last N turns verbatim and\n * always preserves leading system PROMPTS; reuses the internal\n * `selectCompressionWindow` (no second algorithm).\n * - `keepTokens` (token-budget) — keeps the trailing turns whose accumulated\n * `estimateTokens` fits the budget (theocode `splitTranscript` semantics). In\n * this mode leading system prompts are NOT special-cased (D6).\n *\n * Summarization is delegated to a caller-supplied callback (which receives the\n * older window + the summary template). With `failSafe`, a thrown summarizer\n * returns the ORIGINAL transcript + a structured warn (compaction is an\n * optimization, never a cause of data loss); without it, the error propagates.\n *\n * Public from the `@theokit/sdk/compaction` sub-path.\n */\n\nimport { TheokitAgentError } from \"./errors.js\";\nimport { diag } from \"./internal/diagnostics.js\";\nimport { selectCompressionWindow } from \"./internal/runtime/compression/compression-helpers.js\";\nimport { redactSecrets } from \"./internal/security/redact.js\";\n\n/**\n * Minimal message shape for compaction/compression input. THE canonical public origin (leaf type —\n * rollup-plugin-dts cannot re-export types from internal modules into entry bundles; M42 lesson).\n *\n * @public\n */\nexport interface CompressibleMessage {\n role: \"user\" | \"assistant\" | \"system\";\n content: string;\n}\n\n/**\n * Sentinel prefix marking a conversation checkpoint turn. A visible, structured,\n * prose-unlikely token (no invisible/control bytes — safe to persist and to read\n * in source). Only {@link buildCheckpoint} should produce content beginning with it.\n */\nexport const CHECKPOINT_MARKER = \"[[theokit:checkpoint]] \";\n\n/**\n * The 7-section summary template handed to the `summarize` callback (theocode\n * parity shape). Every header is always present so the summarizer cannot silently\n * drop a category; the model is told to preserve file paths, commands, and error\n * text verbatim. Override per-call via {@link CompactTranscriptOptions.summaryTemplate}.\n */\nexport const SUMMARY_TEMPLATE = `Summarize the conversation so far into these sections (keep every header even if empty):\n\n## Goal\nWhat the user is ultimately trying to achieve.\n\n## Constraints\nHard requirements, conventions, and rules stated.\n\n## Progress\nWhat has been done so far.\n\n## Decisions\nChoices made and their rationale.\n\n## Next\nThe immediate next steps.\n\n## Critical\nAnything that MUST NOT be forgotten (preserve verbatim: error messages, exact values).\n\n## Files\nFile paths touched or referenced (verbatim).`;\n\n/** Reject an empty marker — it would match every turn via `startsWith(\"\")` (EC-3). */\nfunction assertMarker(marker: string): void {\n if (marker === \"\") {\n throw new TheokitAgentError(\"compaction marker must be non-empty\", {\n code: \"invalid_argument\",\n });\n }\n}\n\n/** True for a real system prompt — a `system` turn that is NOT a checkpoint marker. */\nfunction isSystemPrompt(message: CompressibleMessage, marker: string): boolean {\n return message.role === \"system\" && !message.content.startsWith(marker);\n}\n\n/** Carried split: leading system prompts (preserved), the older window, the verbatim tail. */\ninterface TranscriptSplit {\n systemPrompts: CompressibleMessage[];\n head: CompressibleMessage[];\n recent: CompressibleMessage[];\n}\n\n/**\n * Token-budget split (theocode `splitTranscript`): walk from the END accumulating\n * `estimateTokens` until `keepTokens` is exceeded; everything older is the head.\n * Always keeps ≥ 1 recent turn. No system-prompt special-casing (D6).\n */\nfunction selectByTokenBudget(\n messages: CompressibleMessage[],\n keepTokens: number,\n): { head: CompressibleMessage[]; recent: CompressibleMessage[] } {\n let acc = 0;\n let splitIndex = messages.length;\n for (let i = messages.length - 1; i >= 0; i -= 1) {\n acc += estimateTokens(messages[i]?.content ?? \"\");\n if (acc > keepTokens && i < messages.length - 1) {\n splitIndex = i + 1;\n break;\n }\n splitIndex = i;\n }\n return { head: messages.slice(0, splitIndex), recent: messages.slice(splitIndex) };\n}\n\n/** Turn-count split (M2): preserve leading system prompts; window the rest by `keepRecent`. */\nfunction splitByRecent(\n messages: CompressibleMessage[],\n keepRecent: number,\n marker: string,\n): TranscriptSplit {\n const systemPrompts = messages.filter((m) => isSystemPrompt(m, marker));\n const rest = messages.filter((m) => !isSystemPrompt(m, marker));\n const { toCompress, toPreserve } = selectCompressionWindow(rest, keepRecent);\n return { systemPrompts, head: toCompress, recent: toPreserve };\n}\n\n/** Options for {@link compactTranscript}. */\nexport interface CompactTranscriptOptions {\n /** Trailing turns preserved verbatim by COUNT (default 6). Ignored when `keepTokens` is set. */\n keepRecent?: number;\n /**\n * Trailing turns preserved verbatim by TOKEN BUDGET (theocode mode). When set,\n * takes precedence over `keepRecent` and disables system-prompt preservation (D6).\n */\n keepTokens?: number;\n /** Checkpoint marker (default {@link CHECKPOINT_MARKER}). Must be non-empty. */\n marker?: string;\n /** Summary template passed to `summarize` (default {@link SUMMARY_TEMPLATE}). */\n summaryTemplate?: string;\n /** Summarize the older window into one turn; if omitted, the older window is dropped. */\n summarize?: (older: CompressibleMessage[], template: string) => Promise<CompressibleMessage>;\n /**\n * When true, a thrown `summarize` returns the ORIGINAL transcript + a structured\n * warn (compaction never loses data). Default false: the error propagates.\n */\n failSafe?: boolean;\n}\n\n/** Sentinel returned by {@link runSummarize} when fail-safe swallowed a throw. */\nconst FAILSAFE_ABORT = Symbol(\"failsafe-abort\");\n\n/** Run the summarizer; on throw, either propagate or (fail-safe) warn + signal abort. */\nasync function runSummarize(\n summarize: NonNullable<CompactTranscriptOptions[\"summarize\"]>,\n head: CompressibleMessage[],\n template: string,\n failSafe: boolean,\n): Promise<CompressibleMessage | typeof FAILSAFE_ABORT> {\n try {\n return await summarize(head, template);\n } catch (err) {\n if (!failSafe) throw err;\n // Unbreakable Rule 8 — never fail silently. The breadcrumb points at the root\n // cause when a summarizer fails every turn and context grows unchecked. The\n // summarizer is caller-supplied, so its error text is routed through\n // `redactSecrets` (ADR D68 — no unredacted output sink in src/).\n // theokit#147 — through the interceptable channel. A summarizer failing every turn is exactly\n // the breadcrumb a TUI host wants in its own panel, not smeared across its alternate screen.\n diag(\n `[compaction] summarizer failed — proceeding uncompacted: ${redactSecrets(err instanceof Error ? err.message : String(err))}\\n`,\n );\n return FAILSAFE_ABORT;\n }\n}\n\n/**\n * Compact a transcript. In `keepRecent` mode (default) the last `keepRecent` turns\n * are kept verbatim and leading system PROMPTS preserved; in `keepTokens` mode the\n * trailing turns within the token budget are kept (no system special-casing, D6).\n * The older window is summarized (via `summarize`, receiving the template) or\n * dropped. Never mutates the input.\n */\nexport async function compactTranscript(\n messages: CompressibleMessage[],\n options: CompactTranscriptOptions = {},\n): Promise<CompressibleMessage[]> {\n const marker = options.marker ?? CHECKPOINT_MARKER;\n assertMarker(marker);\n const split =\n options.keepTokens != null\n ? { systemPrompts: [], ...selectByTokenBudget(messages, options.keepTokens) }\n : splitByRecent(messages, options.keepRecent ?? 6, marker);\n if (split.head.length === 0) {\n return [...messages];\n }\n if (!options.summarize) {\n return [...split.systemPrompts, ...split.recent];\n }\n const template = options.summaryTemplate ?? SUMMARY_TEMPLATE;\n const summary = await runSummarize(\n options.summarize,\n split.head,\n template,\n options.failSafe ?? false,\n );\n if (summary === FAILSAFE_ABORT) {\n return [...messages];\n }\n return [...split.systemPrompts, summary, ...split.recent];\n}\n\n/**\n * Build a checkpoint marker turn (a `system` turn whose content starts with\n * `marker`, default {@link CHECKPOINT_MARKER}). `marker` must be non-empty.\n */\nexport function buildCheckpoint(\n label?: string,\n marker: string = CHECKPOINT_MARKER,\n): CompressibleMessage {\n assertMarker(marker);\n return { role: \"system\", content: marker + (label ?? \"\") };\n}\n\n/** Options for {@link filterFromLatestCheckpoint}. */\nexport interface FilterCheckpointOptions {\n /** Marker to scan for (default {@link CHECKPOINT_MARKER}). */\n marker?: string;\n /**\n * `'after'` (default, M2) returns turns AFTER the latest marker (exclusive);\n * `'from'` (theocode) returns turns FROM the latest marker (inclusive).\n */\n include?: \"after\" | \"from\";\n}\n\n/**\n * Return the turns relative to the most recent checkpoint marker (all turns if\n * none). `include: 'after'` (default) excludes the checkpoint; `'from'` includes\n * it (the summary stands in for the pruned head). Never mutates the input.\n */\nexport function filterFromLatestCheckpoint(\n messages: CompressibleMessage[],\n options: FilterCheckpointOptions = {},\n): CompressibleMessage[] {\n const marker = options.marker ?? CHECKPOINT_MARKER;\n const offset = options.include === \"from\" ? 0 : 1;\n for (let i = messages.length - 1; i >= 0; i -= 1) {\n if (messages[i]?.content.startsWith(marker)) {\n return messages.slice(i + offset);\n }\n }\n return [...messages];\n}\n\n/**\n * True iff `err` is a {@link TheokitAgentError} (or subclass) reporting a\n * context-window-exceeded condition (the typed `context_too_long` code). Reads\n * both `code` (set by provider mappers) and `metadata.code` (the preferred field)\n * — never a brittle message regex.\n */\nexport function isContextOverflowError(err: unknown): boolean {\n return (\n err instanceof TheokitAgentError &&\n (err.code === \"context_too_long\" || err.metadata?.code === \"context_too_long\")\n );\n}\n\n/**\n * M77 — the margin is outside `(0, 1]`. Typed, because a margin > 1 would GROW the assumed window,\n * which is the unsafe direction: `shouldCompact` is monotonically decreasing in `contextWindow`, so\n * overestimating it makes the trigger fire too late and the context overflow.\n */\nexport class ContextWindowMarginError extends TheokitAgentError {\n constructor(readonly margin: number) {\n super(\n `context-window margin must be in (0, 1], got ${String(margin)}. ` +\n `A margin above 1 grows the assumed window and delays compaction past the real limit.`,\n { code: \"invalid_context_window_margin\" },\n );\n }\n}\n\n/**\n * M77 — default safety margin on the context window.\n *\n * `0.95` is not a guess: it is the single reference's value. Codex ships\n * `effective_context_window_percent: 95` (`models-manager/src/model_info.rs:158`) and never budgets\n * against 100% of a window. Being MULTIPLICATIVE, it stays conservative at any window size, which a\n * fixed subtraction would not.\n */\nexport const CONTEXT_WINDOW_MARGIN = 0.95;\n\n/**\n * M77 — the floor used ONLY when neither the catalog nor the caller knows the window.\n *\n * Honest about its own weakness. This number has **one** source (the M77 milestone text); the search\n * for a second one failed, because the reference has no fallback at all — Codex returns `Option` and\n * its callers early-return (`core/src/session/turn_context.rs:213`, `core/src/compact_remote.rs:374`).\n *\n * It is conservative only UPWARD. For a model whose real window is larger, budgeting against 128k\n * compacts early — wasteful but safe. For a model whose real window is SMALLER (an 8k or 32k model\n * absent from the catalog), it compacts too late and the context still overflows. That residual risk\n * is real and is why {@link resolveEffectiveContextWindow} never lets this floor compete with a known\n * catalog value, and why the `compaction_fallback` event exists: a surface can show that the budget is\n * a guess instead of the user finding out when the provider rejects the request.\n */\nexport const CONTEXT_WINDOW_FLOOR = 128_000;\n\n/** Where the effective window came from — carried into the M77 structured event. */\nexport type ContextWindowSource = \"override\" | \"catalog\" | \"fallback\";\n\n/** Input to {@link resolveEffectiveContextWindow}. */\nexport interface EffectiveContextWindowInput {\n /** Caller-supplied window, in tokens. Clamped by `catalog` when both are present. */\n readonly override?: number | undefined;\n /** The model's window from the catalog, in tokens. Absent when the model is unknown. */\n readonly catalog?: number | undefined;\n /** Safety margin in `(0, 1]`. Codex uses 0.95 (`model_info.rs:158`). */\n readonly margin: number;\n /** Conservative floor used ONLY when neither `override` nor `catalog` is available. */\n readonly floor?: number | undefined;\n}\n\n/** Result of {@link resolveEffectiveContextWindow}. */\nexport interface EffectiveContextWindow {\n /** The window to budget against, after clamp and margin. */\n readonly window: number;\n /** Which input won — `\"fallback\"` means neither override nor catalog was available. */\n readonly source: ContextWindowSource;\n /** `true` when an `override` above the catalog window was clamped down to it. */\n readonly clamped: boolean;\n}\n\n/**\n * Resolve the window to budget against — the fail-SAFE replacement for reading the catalog directly.\n *\n * Today `post-run-lifecycle.ts` reads `getCatalogModelInfo(model)?.limit?.context` and, when that is\n * `undefined`, auto-compaction simply never fires. That is fail-OPEN: the context grows until the\n * provider rejects the request. (The comment there calls it \"fail-safe\" — M77 corrects it.)\n *\n * Three techniques, two of them borrowed from the single reference:\n *\n * 1. **Override, CLAMPED by the catalog** — Codex `models-manager/src/model_info.rs:26-31` lets\n * config override the window but limits it with `context_window.min(max_context_window)`.\n * Without the clamp, declaring 999k on a 200k model reopens the overflow through another door.\n * 2. **Multiplicative margin** — Codex `model_info.rs:158` (`effective_context_window_percent: 95`)\n * never budgets against 100% of the window. Being multiplicative, it is conservative for ANY\n * window size.\n * 3. **Floor, only when nothing is known** — deliberately NOT a blanket default. A fixed floor is\n * conservative only upward: applied to a small model it would inflate the assumed window and\n * reproduce the very fail-open this function exists to close. Hence the floor never competes\n * with a known catalog value.\n *\n * Pure — no catalog lookup, no I/O. The caller supplies the numbers, mirroring `shouldCompact`.\n */\n/**\n * Absolute cap on a declared context window, applied when no catalog entry exists to compare against.\n *\n * **10M**, not 2M. The first version used 2M on the rationale that it sat \"comfortably above the\n * largest published window\" — adversarial review measured the opposite: Llama 4 Scout publishes\n * **10M**, and it arrives precisely via OpenRouter, the provider **without** a catalog, which is the\n * case this cap exists to cover. The user would have silently lost 80% of the declared window.\n *\n * The cap still serves what motivates it — one extra zero on 400k gives 4M, which passes; two zeros\n * give 40M, which does not. A limit that rejects legitimate configuration is worse than no limit,\n * because failing OPEN is visible when it happens and silently losing 80% is not.\n */\nexport const ABSOLUTE_CONTEXT_WINDOW_CAP = 10_000_000;\n\nexport function resolveEffectiveContextWindow(\n input: EffectiveContextWindowInput,\n): EffectiveContextWindow {\n if (!(input.margin > 0) || input.margin > 1) {\n throw new ContextWindowMarginError(input.margin);\n }\n\n const withMargin = (raw: number): number => Math.floor(raw * input.margin);\n\n if (input.override !== undefined) {\n // The catalog is the preferred cap; without it the ABSOLUTE cap applies.\n //\n // M95 (adversarial review of M94) — the previous version clamped **only** when a catalog entry\n // existed, and the whole reason the `contextWindow` key exists is the model that has NO entry\n // (OpenRouter has zero). So the clamp was missing in exactly the case that justifies the\n // feature, while the documentation — including an already-published CHANGELOG — stated without\n // qualification that \"declaring 10M does not blow past the provider\".\n //\n // The concrete scenario is one extra zero: `context_window = 4000000`. The only guard was a\n // `.positive().int()`, which sets no upper bound. The agent would never compact until the\n // provider refused the turn — the silent fail-OPEN that M77 exists to prevent.\n const cap = input.catalog ?? ABSOLUTE_CONTEXT_WINDOW_CAP;\n const clamped = input.override > cap;\n return { window: withMargin(clamped ? cap : input.override), source: \"override\", clamped };\n }\n\n if (input.catalog !== undefined) {\n return { window: withMargin(input.catalog), source: \"catalog\", clamped: false };\n }\n\n return { window: withMargin(input.floor ?? 0), source: \"fallback\", clamped: false };\n}\n\n/** Input to {@link shouldCompact}: an estimate, the model's window, and reserved headroom. */\nexport interface ShouldCompactInput {\n /** Estimated token count of the next request (e.g. from {@link estimateTokens}). */\n readonly estimated: number;\n /** The model's total context window, in tokens. */\n readonly contextWindow: number;\n /** Tokens to reserve as headroom (output + safety margin). */\n readonly buffer: number;\n /**\n * Tokens reserved for the model's response generation, SEPARATE from `buffer`.\n * Default 0 — omitting it preserves the legacy\n * `estimated >= contextWindow - buffer` result.\n */\n readonly maxOutput?: number;\n}\n\n/**\n * Tokenizer-free token estimate via the conventional ~4-chars-per-token\n * heuristic: `ceil(text.length / 4)`. `\"\"` → 0; any non-empty text → ≥ 1.\n * A cheap PRE-CALL gate for {@link shouldCompact} — NOT exact tokenization\n * (a consumer needing exactness supplies their own tokenizer). Uses UTF-16\n * `.length` (code units), so multibyte text is approximate.\n */\nexport function estimateTokens(text: string): number {\n return Math.ceil(text.length / 4);\n}\n\n/**\n * Decide BEFORE sending whether to compact: `true` when the `estimated` token\n * count leaves less than `buffer` headroom in the `contextWindow`\n * (`estimated >= contextWindow - buffer`). A `buffer >= contextWindow`\n * (non-positive threshold) always returns `true`. Pure — the caller supplies\n * the window (e.g. from `resolveModelCapabilities`), keeping this decoupled\n * from the per-model catalog.\n */\nexport function shouldCompact(input: ShouldCompactInput): boolean {\n return input.estimated >= input.contextWindow - input.buffer - (input.maxOutput ?? 0);\n}\n"]}
@@ -1,6 +1,6 @@
1
- import { atomicWriteText } from './chunk-LGCEYEU2.js';
2
- import { InvalidTaskIdError } from './chunk-ZYOHF37V.js';
3
- import { diag } from './chunk-KCZW75PI.js';
1
+ import { atomicWriteText } from './chunk-KX7JV5KM.js';
2
+ import { InvalidTaskIdError } from './chunk-SG5ZWT6C.js';
3
+ import { diag } from './chunk-IVSD7L22.js';
4
4
  import { mkdirSync, readdirSync } from 'fs';
5
5
  import { readFile, unlink } from 'fs/promises';
6
6
  import { join } from 'path';
@@ -188,5 +188,5 @@ function getTaskStoreFor(options) {
188
188
  }
189
189
 
190
190
  export { InMemoryTaskStore, JsonFileTaskStore, getTaskStoreFor, isValidTaskId };
191
- //# sourceMappingURL=chunk-SGTMDQ4O.js.map
192
- //# sourceMappingURL=chunk-SGTMDQ4O.js.map
191
+ //# sourceMappingURL=chunk-6EEYRFJC.js.map
192
+ //# sourceMappingURL=chunk-6EEYRFJC.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/types/task.ts","../src/internal/task/store.ts"],"names":[],"mappings":"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","file":"chunk-SGTMDQ4O.js","sourcesContent":["/**\n * Public type contract for the Task observability registry (ADRs D361-D374).\n *\n * Tasks are an opt-in observability layer over async work in the SDK\n * (`Agent.send`, `Agent.batch`, `Workflow.run`, `Cron` fires). They have\n * a closed 5-state lifecycle (D362), discriminated events (D366), and a\n * pluggable store (D364). The `Task` facade in `task.ts` is the public\n * surface; consumers import these types from `@theokit/sdk`.\n *\n * @public\n */\n\n/**\n * Closed enum of the 5 lifecycle states (D362).\n *\n * Transitions are acyclic:\n * queued → running → (finished | error | cancelled)\n * queued → cancelled (direct, no run started)\n */\nexport type TaskState = \"queued\" | \"running\" | \"finished\" | \"error\" | \"cancelled\";\n\n/** Discriminator of the runtime that produced a task (D374). */\nexport type TaskKind = \"run\" | \"batch\" | \"workflow\" | \"cron\" | \"custom\";\n\n/** Discriminated union of task lifecycle events (D366). */\nexport type TaskEvent =\n | {\n readonly type: \"submitted\";\n readonly taskId: string;\n readonly kind: TaskKind;\n readonly submittedAt: number;\n readonly meta?: Record<string, unknown>;\n /** D372 — flag set on the first yielded event when the ring buffer was at cap. */\n readonly truncated?: boolean;\n }\n | { readonly type: \"started\"; readonly taskId: string; readonly startedAt: number }\n | {\n readonly type: \"progress\";\n readonly taskId: string;\n readonly at: number;\n readonly payload: unknown;\n }\n | {\n readonly type: \"finished\";\n readonly taskId: string;\n readonly finishedAt: number;\n readonly result: unknown;\n }\n | {\n readonly type: \"errored\";\n readonly taskId: string;\n readonly erroredAt: number;\n readonly error: { readonly code: string; readonly message: string };\n }\n | {\n readonly type: \"cancelled\";\n readonly taskId: string;\n readonly cancelledAt: number;\n readonly reason?: string;\n };\n\n/** Public read-only view of a task entry in the registry. */\nexport interface TaskHandle {\n readonly id: string;\n readonly kind: TaskKind;\n readonly state: TaskState;\n readonly submittedAt: number;\n readonly startedAt?: number;\n readonly finishedAt?: number;\n readonly cancelledAt?: number;\n readonly erroredAt?: number;\n readonly result?: unknown;\n readonly error?: { readonly code: string; readonly message: string };\n readonly meta?: Record<string, unknown>;\n /**\n * EC-7 — cross-process best-effort cancel flag. Set by CLI\n * `theokit tasks cancel` via JsonFileTaskStore. The owning process\n * polls at checkpoints and honors via AbortController. Always\n * `undefined` for in-process cancel paths (which go directly through\n * AbortController).\n */\n readonly cancelRequested?: boolean;\n}\n\n/** Query filter for `Task.list`. */\nexport interface TaskFilter {\n readonly state?: TaskState | readonly TaskState[];\n readonly kind?: TaskKind | readonly TaskKind[];\n readonly submittedAfter?: number;\n readonly submittedBefore?: number;\n /** Defaults to 100. JsonFileTaskStore hard-caps loaded entries at 256 (D364). */\n readonly limit?: number;\n}\n\n/** Options for `Task.submit`. */\nexport interface TaskSubmitOptions {\n /**\n * Optional user-supplied ID. Must match grammar `^[a-z0-9][a-z0-9_-]*$`\n * and MUST NOT start with the reserved prefixes `wf-` / `b-` / `cron-`\n * (D368, EC-5). When omitted, `crypto.randomUUID()` is used.\n */\n readonly id?: string;\n readonly meta?: Record<string, unknown>;\n /**\n * Optional caller-provided AbortSignal. If already aborted at submit\n * time, the registry short-circuits to `cancelled` without acquiring\n * a semaphore slot (EC-4).\n */\n readonly signal?: AbortSignal;\n /**\n * SE2 — an opt-in {@link import(\"./run-events.js\").RunEventSink}. The task's\n * lifecycle is forwarded to it as typed `task_started` / `task_updated` /\n * `task_completed` RunEvents, so a caller that spawned the task can observe it\n * through the same `onRunEvent` channel as the rest of the run. Best-effort (a\n * throwing sink never breaks the task). The dedicated `Task.subscribe(id)`\n * channel is unaffected.\n */\n readonly onRunEvent?: import(\"./run-events.js\").RunEventSink;\n}\n\n/** Options shape for `TaskStore` factory (D364). */\nexport type TaskStoreOptions =\n | { readonly backend: \"memory\" }\n | { readonly backend: \"json\"; readonly dir: string };\n\n/** Result of `Task.cancel` (D365 — idempotent). */\nexport interface TaskCancelResult {\n readonly cancelled: boolean;\n readonly alreadyTerminal: boolean;\n}\n\n/**\n * Grammar for user-supplied task IDs (D368).\n * `crypto.randomUUID()` outputs do NOT match this (UUIDs have dashes\n * AND uppercase letters in their canonical form on some Node versions),\n * but the registry normalizes auto-generated IDs to lowercase before\n * insertion, so they pass the same regex.\n */\nconst TASK_ID_GRAMMAR = /^[a-z0-9][a-z0-9_-]*$/;\n\n/** Reserved prefixes for adapter-generated IDs (D368, EC-5). */\nconst RESERVED_PREFIXES = [\"wf-\", \"b-\", \"cron-\"] as const;\n\n/**\n * Validates a task ID against the public grammar + reserved prefixes.\n * Throws `InvalidTaskIdError` from `../errors.js` on rejection.\n *\n * Adapter callers (workflow/batch/cron) MUST set `allowReserved: true`\n * to register their own IDs; user-facing surfaces (`Task.submit`,\n * `agent.send({ task: { id } })`) leave it false.\n */\nexport function isValidTaskId(id: string, allowReserved: boolean): boolean {\n if (!TASK_ID_GRAMMAR.test(id)) return false;\n if (allowReserved) return true;\n for (const prefix of RESERVED_PREFIXES) {\n if (id.startsWith(prefix)) return false;\n }\n return true;\n}\n\n/** Re-exported for adapter implementations + tests. */\nexport const TASK_RESERVED_PREFIXES: readonly string[] = RESERVED_PREFIXES;\n","/**\n * `TaskStore` interface + 2 implementations (ADR D364).\n *\n * - `InMemoryTaskStore` — default, transient, single-process.\n * - `JsonFileTaskStore` — opt-in, one JSON file per task under a\n * dedicated dir; single-process invariant (EC-15 documented).\n *\n * Edge cases absorbed:\n * - EC-1: constructor auto-creates dir (mkdirSync recursive idempotent).\n * - EC-2: every method validates the task id against the public\n * grammar (D368) BEFORE doing any path I/O — path-traversal defense.\n * - EC-6: `list()` returns `[]` on ENOENT (fresh install path).\n * - EC-8: `list()` skips `.tmp.*` orphan files left by interrupted\n * atomic writes.\n * - EC-14 (DOCUMENT): `list()` JSDoc documents the 256-row hard cap\n * and the `submittedBefore` paging idiom.\n * - EC-15 (DOCUMENT): `JsonFileTaskStore` JSDoc documents the\n * single-process invariant; v0.2 SQLite covers cross-process.\n *\n * @internal\n */\n\nimport { mkdirSync, readdirSync } from \"node:fs\";\nimport { readFile, unlink } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { InvalidTaskIdError } from \"../../errors.js\";\nimport {\n isValidTaskId,\n type TaskFilter,\n type TaskHandle,\n type TaskState,\n type TaskStoreOptions,\n} from \"../../types/task.js\";\nimport { diag } from \"../diagnostics.js\";\nimport { atomicWriteText } from \"../persistence/atomic-write.js\";\n\nconst JSON_LOAD_CAP = 256;\nconst DEFAULT_LIST_LIMIT = 100;\n\n/** Storage interface used by `TaskRegistry`. */\nexport interface TaskStore {\n insert(handle: TaskHandle): Promise<void>;\n update(id: string, mutate: (h: TaskHandle) => TaskHandle): Promise<TaskHandle | undefined>;\n get(id: string): Promise<TaskHandle | undefined>;\n /**\n * Returns at most `filter.limit ?? 100` matching handles. JsonFile\n * backend hard-caps loaded entries at 256 — callers needing larger\n * pages must use `submittedBefore` to walk the timeline.\n */\n list(filter: TaskFilter): Promise<TaskHandle[]>;\n delete(id: string): Promise<boolean>;\n /** Removes terminal handles whose terminal-timestamp is older than `epochMs`. */\n evictTerminalOlderThan(epochMs: number): Promise<number>;\n}\n\nfunction assertValidIdForStore(id: string): void {\n if (!isValidTaskId(id, /* allowReserved */ true)) {\n throw new InvalidTaskIdError(`store rejects invalid task id: ${id}`, id);\n }\n}\n\nfunction terminalTimestamp(h: TaskHandle): number | undefined {\n if (h.state === \"finished\") return h.finishedAt;\n if (h.state === \"error\") return h.erroredAt;\n if (h.state === \"cancelled\") return h.cancelledAt;\n return undefined;\n}\n\nfunction isTerminal(state: TaskState): boolean {\n return state === \"finished\" || state === \"error\" || state === \"cancelled\";\n}\n\nfunction matchesState(h: TaskHandle, filter: TaskFilter): boolean {\n if (filter.state === undefined) return true;\n const states = Array.isArray(filter.state) ? filter.state : [filter.state];\n return states.includes(h.state);\n}\nfunction matchesKind(h: TaskHandle, filter: TaskFilter): boolean {\n if (filter.kind === undefined) return true;\n const kinds = Array.isArray(filter.kind) ? filter.kind : [filter.kind];\n return kinds.includes(h.kind);\n}\nfunction matchesTime(h: TaskHandle, filter: TaskFilter): boolean {\n if (filter.submittedAfter !== undefined && h.submittedAt <= filter.submittedAfter) return false;\n if (filter.submittedBefore !== undefined && h.submittedAt >= filter.submittedBefore) return false;\n return true;\n}\nfunction matchesFilter(h: TaskHandle, filter: TaskFilter): boolean {\n return matchesState(h, filter) && matchesKind(h, filter) && matchesTime(h, filter);\n}\n\nfunction applyFilter(values: Iterable<TaskHandle>, filter: TaskFilter): TaskHandle[] {\n const limit = filter.limit ?? DEFAULT_LIST_LIMIT;\n const out: TaskHandle[] = [];\n for (const h of values) {\n if (matchesFilter(h, filter)) {\n out.push(h);\n if (out.length >= limit) break;\n }\n }\n return out;\n}\n\n/* ─── InMemory ─── */\n\nexport class InMemoryTaskStore implements TaskStore {\n private readonly map = new Map<string, TaskHandle>();\n\n async insert(handle: TaskHandle): Promise<void> {\n assertValidIdForStore(handle.id);\n this.map.set(handle.id, handle);\n }\n\n async update(id: string, mutate: (h: TaskHandle) => TaskHandle): Promise<TaskHandle | undefined> {\n assertValidIdForStore(id);\n const existing = this.map.get(id);\n if (existing === undefined) return undefined;\n const next = mutate(existing);\n this.map.set(id, next);\n return next;\n }\n\n async get(id: string): Promise<TaskHandle | undefined> {\n assertValidIdForStore(id);\n return this.map.get(id);\n }\n\n async list(filter: TaskFilter): Promise<TaskHandle[]> {\n return applyFilter(this.map.values(), filter);\n }\n\n async delete(id: string): Promise<boolean> {\n assertValidIdForStore(id);\n return this.map.delete(id);\n }\n\n async evictTerminalOlderThan(epochMs: number): Promise<number> {\n let count = 0;\n for (const [id, h] of this.map.entries()) {\n if (!isTerminal(h.state)) continue;\n const ts = terminalTimestamp(h);\n if (ts !== undefined && ts < epochMs) {\n this.map.delete(id);\n count++;\n }\n }\n return count;\n }\n}\n\n/* ─── JsonFile (opt-in) ───\n *\n * IMPORTANT (EC-15): `JsonFileTaskStore` is **single-process**.\n * Concurrent writers from multiple Node processes against the same\n * directory may corrupt entries (atomic-write protects per-file, but\n * the `list()` scan + `update()` read-modify-write cycle is not\n * serialised across processes). Use only when the `TaskRegistry`\n * runs in exactly one process. v0.2 will add a SQLite backend with\n * the same interface for cross-process scenarios (D364 + D61).\n */\nexport class JsonFileTaskStore implements TaskStore {\n constructor(private readonly dir: string) {\n // EC-1: idempotent mkdir; ignore EEXIST.\n try {\n mkdirSync(dir, { recursive: true });\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== \"EEXIST\") throw err;\n }\n }\n\n private filePath(id: string): string {\n return join(this.dir, `${id}.json`);\n }\n\n async insert(handle: TaskHandle): Promise<void> {\n assertValidIdForStore(handle.id);\n await atomicWriteText(this.filePath(handle.id), JSON.stringify(handle));\n }\n\n async update(id: string, mutate: (h: TaskHandle) => TaskHandle): Promise<TaskHandle | undefined> {\n assertValidIdForStore(id);\n const existing = await this.get(id);\n if (existing === undefined) return undefined;\n const next = mutate(existing);\n await atomicWriteText(this.filePath(id), JSON.stringify(next));\n return next;\n }\n\n async get(id: string): Promise<TaskHandle | undefined> {\n assertValidIdForStore(id);\n try {\n const raw = await readFile(this.filePath(id), \"utf8\");\n return JSON.parse(raw) as TaskHandle;\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n if (code === \"ENOENT\") return undefined;\n // Corrupt JSON or other I/O error — log + degrade gracefully (D50/EC-7 cache pattern).\n diag(`[task-store] failed to read ${id}: ${(err as Error).message}\\n`);\n return undefined;\n }\n }\n\n async list(filter: TaskFilter): Promise<TaskHandle[]> {\n let entries: string[];\n try {\n entries = readdirSync(this.dir);\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === \"ENOENT\") return []; // EC-6\n throw err;\n }\n // EC-8: skip orphan .tmp files left by interrupted atomic writes.\n const candidates = entries\n .filter((name) => name.endsWith(\".json\") && !name.includes(\".tmp\"))\n .slice(0, JSON_LOAD_CAP);\n\n const loaded = await Promise.all(\n candidates.map(async (name) => {\n const id = name.slice(0, -\".json\".length);\n if (!isValidTaskId(id, true)) return undefined;\n return this.get(id);\n }),\n );\n const handles = loaded.filter((h): h is TaskHandle => h !== undefined);\n return applyFilter(handles, filter);\n }\n\n async delete(id: string): Promise<boolean> {\n assertValidIdForStore(id);\n try {\n await unlink(this.filePath(id));\n return true;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === \"ENOENT\") return false;\n throw err;\n }\n }\n\n async evictTerminalOlderThan(epochMs: number): Promise<number> {\n const handles = await this.list({ state: [\"finished\", \"error\", \"cancelled\"], limit: 256 });\n let count = 0;\n for (const h of handles) {\n const ts = terminalTimestamp(h);\n if (ts !== undefined && ts < epochMs) {\n if (await this.delete(h.id)) count++;\n }\n }\n return count;\n }\n}\n\n/** Factory used by `TaskRegistry.configure` (D364). */\nexport function getTaskStoreFor(options: TaskStoreOptions): TaskStore {\n if (options.backend === \"memory\") return new InMemoryTaskStore();\n return new JsonFileTaskStore(options.dir);\n}\n"]}
1
+ {"version":3,"sources":["../src/types/task.ts","../src/internal/task/store.ts"],"names":[],"mappings":";;;;;;;;AA0IA,IAAM,eAAA,GAAkB,uBAAA;AAGxB,IAAM,iBAAA,GAAoB,CAAC,KAAA,EAAO,IAAA,EAAM,OAAO,CAAA;AAUxC,SAAS,aAAA,CAAc,IAAY,aAAA,EAAiC;AACzE,EAAA,IAAI,CAAC,eAAA,CAAgB,IAAA,CAAK,EAAE,GAAG,OAAO,KAAA;AACtC,EAAA,IAAI,eAAe,OAAO,IAAA;AAC1B,EAAA,KAAA,MAAW,UAAU,iBAAA,EAAmB;AACtC,IAAA,IAAI,EAAA,CAAG,UAAA,CAAW,MAAM,CAAA,EAAG,OAAO,KAAA;AAAA,EACpC;AACA,EAAA,OAAO,IAAA;AACT;ACzHA,IAAM,aAAA,GAAgB,GAAA;AACtB,IAAM,kBAAA,GAAqB,GAAA;AAkB3B,SAAS,sBAAsB,EAAA,EAAkB;AAC/C,EAAA,IAAI,CAAC,aAAA;AAAA,IAAc,EAAA;AAAA;AAAA,IAAwB;AAAA,GAAI,EAAG;AAChD,IAAA,MAAM,IAAI,kBAAA,CAAmB,CAAA,+BAAA,EAAkC,EAAE,IAAI,EAAE,CAAA;AAAA,EACzE;AACF;AAEA,SAAS,kBAAkB,CAAA,EAAmC;AAC5D,EAAA,IAAI,CAAA,CAAE,KAAA,KAAU,UAAA,EAAY,OAAO,CAAA,CAAE,UAAA;AACrC,EAAA,IAAI,CAAA,CAAE,KAAA,KAAU,OAAA,EAAS,OAAO,CAAA,CAAE,SAAA;AAClC,EAAA,IAAI,CAAA,CAAE,KAAA,KAAU,WAAA,EAAa,OAAO,CAAA,CAAE,WAAA;AACtC,EAAA,OAAO,MAAA;AACT;AAEA,SAAS,WAAW,KAAA,EAA2B;AAC7C,EAAA,OAAO,KAAA,KAAU,UAAA,IAAc,KAAA,KAAU,OAAA,IAAW,KAAA,KAAU,WAAA;AAChE;AAEA,SAAS,YAAA,CAAa,GAAe,MAAA,EAA6B;AAChE,EAAA,IAAI,MAAA,CAAO,KAAA,KAAU,MAAA,EAAW,OAAO,IAAA;AACvC,EAAA,MAAM,MAAA,GAAS,KAAA,CAAM,OAAA,CAAQ,MAAA,CAAO,KAAK,IAAI,MAAA,CAAO,KAAA,GAAQ,CAAC,MAAA,CAAO,KAAK,CAAA;AACzE,EAAA,OAAO,MAAA,CAAO,QAAA,CAAS,CAAA,CAAE,KAAK,CAAA;AAChC;AACA,SAAS,WAAA,CAAY,GAAe,MAAA,EAA6B;AAC/D,EAAA,IAAI,MAAA,CAAO,IAAA,KAAS,MAAA,EAAW,OAAO,IAAA;AACtC,EAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,OAAA,CAAQ,MAAA,CAAO,IAAI,IAAI,MAAA,CAAO,IAAA,GAAO,CAAC,MAAA,CAAO,IAAI,CAAA;AACrE,EAAA,OAAO,KAAA,CAAM,QAAA,CAAS,CAAA,CAAE,IAAI,CAAA;AAC9B;AACA,SAAS,WAAA,CAAY,GAAe,MAAA,EAA6B;AAC/D,EAAA,IAAI,OAAO,cAAA,KAAmB,MAAA,IAAa,EAAE,WAAA,IAAe,MAAA,CAAO,gBAAgB,OAAO,KAAA;AAC1F,EAAA,IAAI,OAAO,eAAA,KAAoB,MAAA,IAAa,EAAE,WAAA,IAAe,MAAA,CAAO,iBAAiB,OAAO,KAAA;AAC5F,EAAA,OAAO,IAAA;AACT;AACA,SAAS,aAAA,CAAc,GAAe,MAAA,EAA6B;AACjE,EAAA,OAAO,YAAA,CAAa,CAAA,EAAG,MAAM,CAAA,IAAK,WAAA,CAAY,GAAG,MAAM,CAAA,IAAK,WAAA,CAAY,CAAA,EAAG,MAAM,CAAA;AACnF;AAEA,SAAS,WAAA,CAAY,QAA8B,MAAA,EAAkC;AACnF,EAAA,MAAM,KAAA,GAAQ,OAAO,KAAA,IAAS,kBAAA;AAC9B,EAAA,MAAM,MAAoB,EAAC;AAC3B,EAAA,KAAA,MAAW,KAAK,MAAA,EAAQ;AACtB,IAAA,IAAI,aAAA,CAAc,CAAA,EAAG,MAAM,CAAA,EAAG;AAC5B,MAAA,GAAA,CAAI,KAAK,CAAC,CAAA;AACV,MAAA,IAAI,GAAA,CAAI,UAAU,KAAA,EAAO;AAAA,IAC3B;AAAA,EACF;AACA,EAAA,OAAO,GAAA;AACT;AAIO,IAAM,oBAAN,MAA6C;AAAA,EACjC,GAAA,uBAAU,GAAA,EAAwB;AAAA,EAEnD,MAAM,OAAO,MAAA,EAAmC;AAC9C,IAAA,qBAAA,CAAsB,OAAO,EAAE,CAAA;AAC/B,IAAA,IAAA,CAAK,GAAA,CAAI,GAAA,CAAI,MAAA,CAAO,EAAA,EAAI,MAAM,CAAA;AAAA,EAChC;AAAA,EAEA,MAAM,MAAA,CAAO,EAAA,EAAY,MAAA,EAAwE;AAC/F,IAAA,qBAAA,CAAsB,EAAE,CAAA;AACxB,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,GAAA,CAAI,GAAA,CAAI,EAAE,CAAA;AAChC,IAAA,IAAI,QAAA,KAAa,QAAW,OAAO,MAAA;AACnC,IAAA,MAAM,IAAA,GAAO,OAAO,QAAQ,CAAA;AAC5B,IAAA,IAAA,CAAK,GAAA,CAAI,GAAA,CAAI,EAAA,EAAI,IAAI,CAAA;AACrB,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEA,MAAM,IAAI,EAAA,EAA6C;AACrD,IAAA,qBAAA,CAAsB,EAAE,CAAA;AACxB,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,GAAA,CAAI,EAAE,CAAA;AAAA,EACxB;AAAA,EAEA,MAAM,KAAK,MAAA,EAA2C;AACpD,IAAA,OAAO,WAAA,CAAY,IAAA,CAAK,GAAA,CAAI,MAAA,IAAU,MAAM,CAAA;AAAA,EAC9C;AAAA,EAEA,MAAM,OAAO,EAAA,EAA8B;AACzC,IAAA,qBAAA,CAAsB,EAAE,CAAA;AACxB,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,MAAA,CAAO,EAAE,CAAA;AAAA,EAC3B;AAAA,EAEA,MAAM,uBAAuB,OAAA,EAAkC;AAC7D,IAAA,IAAI,KAAA,GAAQ,CAAA;AACZ,IAAA,KAAA,MAAW,CAAC,EAAA,EAAI,CAAC,KAAK,IAAA,CAAK,GAAA,CAAI,SAAQ,EAAG;AACxC,MAAA,IAAI,CAAC,UAAA,CAAW,CAAA,CAAE,KAAK,CAAA,EAAG;AAC1B,MAAA,MAAM,EAAA,GAAK,kBAAkB,CAAC,CAAA;AAC9B,MAAA,IAAI,EAAA,KAAO,MAAA,IAAa,EAAA,GAAK,OAAA,EAAS;AACpC,QAAA,IAAA,CAAK,GAAA,CAAI,OAAO,EAAE,CAAA;AAClB,QAAA,KAAA,EAAA;AAAA,MACF;AAAA,IACF;AACA,IAAA,OAAO,KAAA;AAAA,EACT;AACF;AAYO,IAAM,oBAAN,MAA6C;AAAA,EAClD,YAA6B,GAAA,EAAa;AAAb,IAAA,IAAA,CAAA,GAAA,GAAA,GAAA;AAE3B,IAAA,IAAI;AACF,MAAA,SAAA,CAAU,GAAA,EAAK,EAAE,SAAA,EAAW,IAAA,EAAM,CAAA;AAAA,IACpC,SAAS,GAAA,EAAK;AACZ,MAAA,IAAK,GAAA,CAA8B,IAAA,KAAS,QAAA,EAAU,MAAM,GAAA;AAAA,IAC9D;AAAA,EACF;AAAA,EAP6B,GAAA;AAAA,EASrB,SAAS,EAAA,EAAoB;AACnC,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,GAAA,EAAK,CAAA,EAAG,EAAE,CAAA,KAAA,CAAO,CAAA;AAAA,EACpC;AAAA,EAEA,MAAM,OAAO,MAAA,EAAmC;AAC9C,IAAA,qBAAA,CAAsB,OAAO,EAAE,CAAA;AAC/B,IAAA,MAAM,eAAA,CAAgB,KAAK,QAAA,CAAS,MAAA,CAAO,EAAE,CAAA,EAAG,IAAA,CAAK,SAAA,CAAU,MAAM,CAAC,CAAA;AAAA,EACxE;AAAA,EAEA,MAAM,MAAA,CAAO,EAAA,EAAY,MAAA,EAAwE;AAC/F,IAAA,qBAAA,CAAsB,EAAE,CAAA;AACxB,IAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,GAAA,CAAI,EAAE,CAAA;AAClC,IAAA,IAAI,QAAA,KAAa,QAAW,OAAO,MAAA;AACnC,IAAA,MAAM,IAAA,GAAO,OAAO,QAAQ,CAAA;AAC5B,IAAA,MAAM,eAAA,CAAgB,KAAK,QAAA,CAAS,EAAE,GAAG,IAAA,CAAK,SAAA,CAAU,IAAI,CAAC,CAAA;AAC7D,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEA,MAAM,IAAI,EAAA,EAA6C;AACrD,IAAA,qBAAA,CAAsB,EAAE,CAAA;AACxB,IAAA,IAAI;AACF,MAAA,MAAM,MAAM,MAAM,QAAA,CAAS,KAAK,QAAA,CAAS,EAAE,GAAG,MAAM,CAAA;AACpD,MAAA,OAAO,IAAA,CAAK,MAAM,GAAG,CAAA;AAAA,IACvB,SAAS,GAAA,EAAK;AACZ,MAAA,MAAM,OAAQ,GAAA,CAA8B,IAAA;AAC5C,MAAA,IAAI,IAAA,KAAS,UAAU,OAAO,MAAA;AAE9B,MAAA,IAAA,CAAK,CAAA,4BAAA,EAA+B,EAAE,CAAA,EAAA,EAAM,GAAA,CAAc,OAAO;AAAA,CAAI,CAAA;AACrE,MAAA,OAAO,MAAA;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAM,KAAK,MAAA,EAA2C;AACpD,IAAA,IAAI,OAAA;AACJ,IAAA,IAAI;AACF,MAAA,OAAA,GAAU,WAAA,CAAY,KAAK,GAAG,CAAA;AAAA,IAChC,SAAS,GAAA,EAAK;AACZ,MAAA,IAAK,GAAA,CAA8B,IAAA,KAAS,QAAA,EAAU,OAAO,EAAC;AAC9D,MAAA,MAAM,GAAA;AAAA,IACR;AAEA,IAAA,MAAM,aAAa,OAAA,CAChB,MAAA,CAAO,CAAC,IAAA,KAAS,KAAK,QAAA,CAAS,OAAO,CAAA,IAAK,CAAC,KAAK,QAAA,CAAS,MAAM,CAAC,CAAA,CACjE,KAAA,CAAM,GAAG,aAAa,CAAA;AAEzB,IAAA,MAAM,MAAA,GAAS,MAAM,OAAA,CAAQ,GAAA;AAAA,MAC3B,UAAA,CAAW,GAAA,CAAI,OAAO,IAAA,KAAS;AAC7B,QAAA,MAAM,KAAK,IAAA,CAAK,KAAA,CAAM,CAAA,EAAG,CAAC,QAAQ,MAAM,CAAA;AACxC,QAAA,IAAI,CAAC,aAAA,CAAc,EAAA,EAAI,IAAI,GAAG,OAAO,MAAA;AACrC,QAAA,OAAO,IAAA,CAAK,IAAI,EAAE,CAAA;AAAA,MACpB,CAAC;AAAA,KACH;AACA,IAAA,MAAM,UAAU,MAAA,CAAO,MAAA,CAAO,CAAC,CAAA,KAAuB,MAAM,MAAS,CAAA;AACrE,IAAA,OAAO,WAAA,CAAY,SAAS,MAAM,CAAA;AAAA,EACpC;AAAA,EAEA,MAAM,OAAO,EAAA,EAA8B;AACzC,IAAA,qBAAA,CAAsB,EAAE,CAAA;AACxB,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,CAAO,IAAA,CAAK,QAAA,CAAS,EAAE,CAAC,CAAA;AAC9B,MAAA,OAAO,IAAA;AAAA,IACT,SAAS,GAAA,EAAK;AACZ,MAAA,IAAK,GAAA,CAA8B,IAAA,KAAS,QAAA,EAAU,OAAO,KAAA;AAC7D,MAAA,MAAM,GAAA;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,uBAAuB,OAAA,EAAkC;AAC7D,IAAA,MAAM,OAAA,GAAU,MAAM,IAAA,CAAK,IAAA,CAAK,EAAE,KAAA,EAAO,CAAC,UAAA,EAAY,OAAA,EAAS,WAAW,CAAA,EAAG,KAAA,EAAO,KAAK,CAAA;AACzF,IAAA,IAAI,KAAA,GAAQ,CAAA;AACZ,IAAA,KAAA,MAAW,KAAK,OAAA,EAAS;AACvB,MAAA,MAAM,EAAA,GAAK,kBAAkB,CAAC,CAAA;AAC9B,MAAA,IAAI,EAAA,KAAO,MAAA,IAAa,EAAA,GAAK,OAAA,EAAS;AACpC,QAAA,IAAI,MAAM,IAAA,CAAK,MAAA,CAAO,CAAA,CAAE,EAAE,CAAA,EAAG,KAAA,EAAA;AAAA,MAC/B;AAAA,IACF;AACA,IAAA,OAAO,KAAA;AAAA,EACT;AACF;AAGO,SAAS,gBAAgB,OAAA,EAAsC;AACpE,EAAA,IAAI,OAAA,CAAQ,OAAA,KAAY,QAAA,EAAU,OAAO,IAAI,iBAAA,EAAkB;AAC/D,EAAA,OAAO,IAAI,iBAAA,CAAkB,OAAA,CAAQ,GAAG,CAAA;AAC1C","file":"chunk-6EEYRFJC.js","sourcesContent":["/**\n * Public type contract for the Task observability registry (ADRs D361-D374).\n *\n * Tasks are an opt-in observability layer over async work in the SDK\n * (`Agent.send`, `Agent.batch`, `Workflow.run`, `Cron` fires). They have\n * a closed 5-state lifecycle (D362), discriminated events (D366), and a\n * pluggable store (D364). The `Task` facade in `task.ts` is the public\n * surface; consumers import these types from `@theokit/sdk`.\n *\n * @public\n */\n\n/**\n * Closed enum of the 5 lifecycle states (D362).\n *\n * Transitions are acyclic:\n * queued → running → (finished | error | cancelled)\n * queued → cancelled (direct, no run started)\n */\nexport type TaskState = \"queued\" | \"running\" | \"finished\" | \"error\" | \"cancelled\";\n\n/** Discriminator of the runtime that produced a task (D374). */\nexport type TaskKind = \"run\" | \"batch\" | \"workflow\" | \"cron\" | \"custom\";\n\n/** Discriminated union of task lifecycle events (D366). */\nexport type TaskEvent =\n | {\n readonly type: \"submitted\";\n readonly taskId: string;\n readonly kind: TaskKind;\n readonly submittedAt: number;\n readonly meta?: Record<string, unknown>;\n /** D372 — flag set on the first yielded event when the ring buffer was at cap. */\n readonly truncated?: boolean;\n }\n | { readonly type: \"started\"; readonly taskId: string; readonly startedAt: number }\n | {\n readonly type: \"progress\";\n readonly taskId: string;\n readonly at: number;\n readonly payload: unknown;\n }\n | {\n readonly type: \"finished\";\n readonly taskId: string;\n readonly finishedAt: number;\n readonly result: unknown;\n }\n | {\n readonly type: \"errored\";\n readonly taskId: string;\n readonly erroredAt: number;\n readonly error: { readonly code: string; readonly message: string };\n }\n | {\n readonly type: \"cancelled\";\n readonly taskId: string;\n readonly cancelledAt: number;\n readonly reason?: string;\n };\n\n/** Public read-only view of a task entry in the registry. */\nexport interface TaskHandle {\n readonly id: string;\n readonly kind: TaskKind;\n readonly state: TaskState;\n readonly submittedAt: number;\n readonly startedAt?: number;\n readonly finishedAt?: number;\n readonly cancelledAt?: number;\n readonly erroredAt?: number;\n readonly result?: unknown;\n readonly error?: { readonly code: string; readonly message: string };\n readonly meta?: Record<string, unknown>;\n /**\n * EC-7 — cross-process best-effort cancel flag. Set by CLI\n * `theokit tasks cancel` via JsonFileTaskStore. The owning process\n * polls at checkpoints and honors via AbortController. Always\n * `undefined` for in-process cancel paths (which go directly through\n * AbortController).\n */\n readonly cancelRequested?: boolean;\n}\n\n/** Query filter for `Task.list`. */\nexport interface TaskFilter {\n readonly state?: TaskState | readonly TaskState[];\n readonly kind?: TaskKind | readonly TaskKind[];\n readonly submittedAfter?: number;\n readonly submittedBefore?: number;\n /** Defaults to 100. JsonFileTaskStore hard-caps loaded entries at 256 (D364). */\n readonly limit?: number;\n}\n\n/** Options for `Task.submit`. */\nexport interface TaskSubmitOptions {\n /**\n * Optional user-supplied ID. Must match grammar `^[a-z0-9][a-z0-9_-]*$`\n * and MUST NOT start with the reserved prefixes `wf-` / `b-` / `cron-`\n * (D368, EC-5). When omitted, `crypto.randomUUID()` is used.\n */\n readonly id?: string;\n readonly meta?: Record<string, unknown>;\n /**\n * Optional caller-provided AbortSignal. If already aborted at submit\n * time, the registry short-circuits to `cancelled` without acquiring\n * a semaphore slot (EC-4).\n */\n readonly signal?: AbortSignal;\n /**\n * SE2 — an opt-in {@link import(\"./run-events.js\").RunEventSink}. The task's\n * lifecycle is forwarded to it as typed `task_started` / `task_updated` /\n * `task_completed` RunEvents, so a caller that spawned the task can observe it\n * through the same `onRunEvent` channel as the rest of the run. Best-effort (a\n * throwing sink never breaks the task). The dedicated `Task.subscribe(id)`\n * channel is unaffected.\n */\n readonly onRunEvent?: import(\"./run-events.js\").RunEventSink;\n}\n\n/** Options shape for `TaskStore` factory (D364). */\nexport type TaskStoreOptions =\n | { readonly backend: \"memory\" }\n | { readonly backend: \"json\"; readonly dir: string };\n\n/** Result of `Task.cancel` (D365 — idempotent). */\nexport interface TaskCancelResult {\n readonly cancelled: boolean;\n readonly alreadyTerminal: boolean;\n}\n\n/**\n * Grammar for user-supplied task IDs (D368).\n * `crypto.randomUUID()` outputs do NOT match this (UUIDs have dashes\n * AND uppercase letters in their canonical form on some Node versions),\n * but the registry normalizes auto-generated IDs to lowercase before\n * insertion, so they pass the same regex.\n */\nconst TASK_ID_GRAMMAR = /^[a-z0-9][a-z0-9_-]*$/;\n\n/** Reserved prefixes for adapter-generated IDs (D368, EC-5). */\nconst RESERVED_PREFIXES = [\"wf-\", \"b-\", \"cron-\"] as const;\n\n/**\n * Validates a task ID against the public grammar + reserved prefixes.\n * Throws `InvalidTaskIdError` from `../errors.js` on rejection.\n *\n * Adapter callers (workflow/batch/cron) MUST set `allowReserved: true`\n * to register their own IDs; user-facing surfaces (`Task.submit`,\n * `agent.send({ task: { id } })`) leave it false.\n */\nexport function isValidTaskId(id: string, allowReserved: boolean): boolean {\n if (!TASK_ID_GRAMMAR.test(id)) return false;\n if (allowReserved) return true;\n for (const prefix of RESERVED_PREFIXES) {\n if (id.startsWith(prefix)) return false;\n }\n return true;\n}\n\n/** Re-exported for adapter implementations + tests. */\nexport const TASK_RESERVED_PREFIXES: readonly string[] = RESERVED_PREFIXES;\n","/**\n * `TaskStore` interface + 2 implementations (ADR D364).\n *\n * - `InMemoryTaskStore` — default, transient, single-process.\n * - `JsonFileTaskStore` — opt-in, one JSON file per task under a\n * dedicated dir; single-process invariant (EC-15 documented).\n *\n * Edge cases absorbed:\n * - EC-1: constructor auto-creates dir (mkdirSync recursive idempotent).\n * - EC-2: every method validates the task id against the public\n * grammar (D368) BEFORE doing any path I/O — path-traversal defense.\n * - EC-6: `list()` returns `[]` on ENOENT (fresh install path).\n * - EC-8: `list()` skips `.tmp.*` orphan files left by interrupted\n * atomic writes.\n * - EC-14 (DOCUMENT): `list()` JSDoc documents the 256-row hard cap\n * and the `submittedBefore` paging idiom.\n * - EC-15 (DOCUMENT): `JsonFileTaskStore` JSDoc documents the\n * single-process invariant; v0.2 SQLite covers cross-process.\n *\n * @internal\n */\n\nimport { mkdirSync, readdirSync } from \"node:fs\";\nimport { readFile, unlink } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { InvalidTaskIdError } from \"../../errors.js\";\nimport {\n isValidTaskId,\n type TaskFilter,\n type TaskHandle,\n type TaskState,\n type TaskStoreOptions,\n} from \"../../types/task.js\";\nimport { diag } from \"../diagnostics.js\";\nimport { atomicWriteText } from \"../persistence/atomic-write.js\";\n\nconst JSON_LOAD_CAP = 256;\nconst DEFAULT_LIST_LIMIT = 100;\n\n/** Storage interface used by `TaskRegistry`. */\nexport interface TaskStore {\n insert(handle: TaskHandle): Promise<void>;\n update(id: string, mutate: (h: TaskHandle) => TaskHandle): Promise<TaskHandle | undefined>;\n get(id: string): Promise<TaskHandle | undefined>;\n /**\n * Returns at most `filter.limit ?? 100` matching handles. JsonFile\n * backend hard-caps loaded entries at 256 — callers needing larger\n * pages must use `submittedBefore` to walk the timeline.\n */\n list(filter: TaskFilter): Promise<TaskHandle[]>;\n delete(id: string): Promise<boolean>;\n /** Removes terminal handles whose terminal-timestamp is older than `epochMs`. */\n evictTerminalOlderThan(epochMs: number): Promise<number>;\n}\n\nfunction assertValidIdForStore(id: string): void {\n if (!isValidTaskId(id, /* allowReserved */ true)) {\n throw new InvalidTaskIdError(`store rejects invalid task id: ${id}`, id);\n }\n}\n\nfunction terminalTimestamp(h: TaskHandle): number | undefined {\n if (h.state === \"finished\") return h.finishedAt;\n if (h.state === \"error\") return h.erroredAt;\n if (h.state === \"cancelled\") return h.cancelledAt;\n return undefined;\n}\n\nfunction isTerminal(state: TaskState): boolean {\n return state === \"finished\" || state === \"error\" || state === \"cancelled\";\n}\n\nfunction matchesState(h: TaskHandle, filter: TaskFilter): boolean {\n if (filter.state === undefined) return true;\n const states = Array.isArray(filter.state) ? filter.state : [filter.state];\n return states.includes(h.state);\n}\nfunction matchesKind(h: TaskHandle, filter: TaskFilter): boolean {\n if (filter.kind === undefined) return true;\n const kinds = Array.isArray(filter.kind) ? filter.kind : [filter.kind];\n return kinds.includes(h.kind);\n}\nfunction matchesTime(h: TaskHandle, filter: TaskFilter): boolean {\n if (filter.submittedAfter !== undefined && h.submittedAt <= filter.submittedAfter) return false;\n if (filter.submittedBefore !== undefined && h.submittedAt >= filter.submittedBefore) return false;\n return true;\n}\nfunction matchesFilter(h: TaskHandle, filter: TaskFilter): boolean {\n return matchesState(h, filter) && matchesKind(h, filter) && matchesTime(h, filter);\n}\n\nfunction applyFilter(values: Iterable<TaskHandle>, filter: TaskFilter): TaskHandle[] {\n const limit = filter.limit ?? DEFAULT_LIST_LIMIT;\n const out: TaskHandle[] = [];\n for (const h of values) {\n if (matchesFilter(h, filter)) {\n out.push(h);\n if (out.length >= limit) break;\n }\n }\n return out;\n}\n\n/* ─── InMemory ─── */\n\nexport class InMemoryTaskStore implements TaskStore {\n private readonly map = new Map<string, TaskHandle>();\n\n async insert(handle: TaskHandle): Promise<void> {\n assertValidIdForStore(handle.id);\n this.map.set(handle.id, handle);\n }\n\n async update(id: string, mutate: (h: TaskHandle) => TaskHandle): Promise<TaskHandle | undefined> {\n assertValidIdForStore(id);\n const existing = this.map.get(id);\n if (existing === undefined) return undefined;\n const next = mutate(existing);\n this.map.set(id, next);\n return next;\n }\n\n async get(id: string): Promise<TaskHandle | undefined> {\n assertValidIdForStore(id);\n return this.map.get(id);\n }\n\n async list(filter: TaskFilter): Promise<TaskHandle[]> {\n return applyFilter(this.map.values(), filter);\n }\n\n async delete(id: string): Promise<boolean> {\n assertValidIdForStore(id);\n return this.map.delete(id);\n }\n\n async evictTerminalOlderThan(epochMs: number): Promise<number> {\n let count = 0;\n for (const [id, h] of this.map.entries()) {\n if (!isTerminal(h.state)) continue;\n const ts = terminalTimestamp(h);\n if (ts !== undefined && ts < epochMs) {\n this.map.delete(id);\n count++;\n }\n }\n return count;\n }\n}\n\n/* ─── JsonFile (opt-in) ───\n *\n * IMPORTANT (EC-15): `JsonFileTaskStore` is **single-process**.\n * Concurrent writers from multiple Node processes against the same\n * directory may corrupt entries (atomic-write protects per-file, but\n * the `list()` scan + `update()` read-modify-write cycle is not\n * serialised across processes). Use only when the `TaskRegistry`\n * runs in exactly one process. v0.2 will add a SQLite backend with\n * the same interface for cross-process scenarios (D364 + D61).\n */\nexport class JsonFileTaskStore implements TaskStore {\n constructor(private readonly dir: string) {\n // EC-1: idempotent mkdir; ignore EEXIST.\n try {\n mkdirSync(dir, { recursive: true });\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== \"EEXIST\") throw err;\n }\n }\n\n private filePath(id: string): string {\n return join(this.dir, `${id}.json`);\n }\n\n async insert(handle: TaskHandle): Promise<void> {\n assertValidIdForStore(handle.id);\n await atomicWriteText(this.filePath(handle.id), JSON.stringify(handle));\n }\n\n async update(id: string, mutate: (h: TaskHandle) => TaskHandle): Promise<TaskHandle | undefined> {\n assertValidIdForStore(id);\n const existing = await this.get(id);\n if (existing === undefined) return undefined;\n const next = mutate(existing);\n await atomicWriteText(this.filePath(id), JSON.stringify(next));\n return next;\n }\n\n async get(id: string): Promise<TaskHandle | undefined> {\n assertValidIdForStore(id);\n try {\n const raw = await readFile(this.filePath(id), \"utf8\");\n return JSON.parse(raw) as TaskHandle;\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n if (code === \"ENOENT\") return undefined;\n // Corrupt JSON or other I/O error — log + degrade gracefully (D50/EC-7 cache pattern).\n diag(`[task-store] failed to read ${id}: ${(err as Error).message}\\n`);\n return undefined;\n }\n }\n\n async list(filter: TaskFilter): Promise<TaskHandle[]> {\n let entries: string[];\n try {\n entries = readdirSync(this.dir);\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === \"ENOENT\") return []; // EC-6\n throw err;\n }\n // EC-8: skip orphan .tmp files left by interrupted atomic writes.\n const candidates = entries\n .filter((name) => name.endsWith(\".json\") && !name.includes(\".tmp\"))\n .slice(0, JSON_LOAD_CAP);\n\n const loaded = await Promise.all(\n candidates.map(async (name) => {\n const id = name.slice(0, -\".json\".length);\n if (!isValidTaskId(id, true)) return undefined;\n return this.get(id);\n }),\n );\n const handles = loaded.filter((h): h is TaskHandle => h !== undefined);\n return applyFilter(handles, filter);\n }\n\n async delete(id: string): Promise<boolean> {\n assertValidIdForStore(id);\n try {\n await unlink(this.filePath(id));\n return true;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === \"ENOENT\") return false;\n throw err;\n }\n }\n\n async evictTerminalOlderThan(epochMs: number): Promise<number> {\n const handles = await this.list({ state: [\"finished\", \"error\", \"cancelled\"], limit: 256 });\n let count = 0;\n for (const h of handles) {\n const ts = terminalTimestamp(h);\n if (ts !== undefined && ts < epochMs) {\n if (await this.delete(h.id)) count++;\n }\n }\n return count;\n }\n}\n\n/** Factory used by `TaskRegistry.configure` (D364). */\nexport function getTaskStoreFor(options: TaskStoreOptions): TaskStore {\n if (options.backend === \"memory\") return new InMemoryTaskStore();\n return new JsonFileTaskStore(options.dir);\n}\n"]}
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
- var chunkA3MHE2MQ_cjs = require('./chunk-A3MHE2MQ.cjs');
4
- var chunkBE3W4HYV_cjs = require('./chunk-BE3W4HYV.cjs');
3
+ var chunkIHFNRNTJ_cjs = require('./chunk-IHFNRNTJ.cjs');
4
+ var chunkBCQ3E2ZG_cjs = require('./chunk-BCQ3E2ZG.cjs');
5
5
  var async_hooks = require('async_hooks');
6
6
  var fs = require('fs');
7
7
  var promises = require('fs/promises');
@@ -17,7 +17,7 @@ var warned = /* @__PURE__ */ new Set();
17
17
  function warnOnce(key, message) {
18
18
  if (warned.has(key)) return;
19
19
  warned.add(key);
20
- chunkBE3W4HYV_cjs.diag(`${message}
20
+ chunkBCQ3E2ZG_cjs.diag(`${message}
21
21
  `);
22
22
  }
23
23
  async function loadHookConfig(cwd) {
@@ -35,7 +35,7 @@ async function loadHookConfig(cwd) {
35
35
  try {
36
36
  raw = await promises.readFile(jsonPath, "utf8");
37
37
  } catch (cause) {
38
- throw new chunkA3MHE2MQ_cjs.ConfigurationError(`Failed to read hooks config: ${jsonPath}`, {
38
+ throw new chunkIHFNRNTJ_cjs.ConfigurationError(`Failed to read hooks config: ${jsonPath}`, {
39
39
  code: "hooks_read_error",
40
40
  cause
41
41
  });
@@ -44,7 +44,7 @@ async function loadHookConfig(cwd) {
44
44
  try {
45
45
  parsed = JSON.parse(raw);
46
46
  } catch (cause) {
47
- throw new chunkA3MHE2MQ_cjs.ConfigurationError(`Invalid JSON in hooks config: ${jsonPath}`, {
47
+ throw new chunkIHFNRNTJ_cjs.ConfigurationError(`Invalid JSON in hooks config: ${jsonPath}`, {
48
48
  code: "hooks_json_invalid",
49
49
  cause
50
50
  });
@@ -53,7 +53,7 @@ async function loadHookConfig(cwd) {
53
53
  }
54
54
  function asRecord(value, path, where) {
55
55
  if (typeof value !== "object" || value === null || Array.isArray(value)) {
56
- throw new chunkA3MHE2MQ_cjs.ConfigurationError(`hooks: expected an object at ${where} in ${path}`, {
56
+ throw new chunkIHFNRNTJ_cjs.ConfigurationError(`hooks: expected an object at ${where} in ${path}`, {
57
57
  code: "hooks_json_invalid"
58
58
  });
59
59
  }
@@ -61,7 +61,7 @@ function asRecord(value, path, where) {
61
61
  }
62
62
  function asArray(value, path, where) {
63
63
  if (!Array.isArray(value)) {
64
- throw new chunkA3MHE2MQ_cjs.ConfigurationError(`hooks: expected an array at ${where} in ${path}`, {
64
+ throw new chunkIHFNRNTJ_cjs.ConfigurationError(`hooks: expected an array at ${where} in ${path}`, {
65
65
  code: "hooks_json_invalid"
66
66
  });
67
67
  }
@@ -99,13 +99,13 @@ function flattenEventGroups(groups, path, ccEvent) {
99
99
  function parseClaudeCodeCommand(raw, matcher, path, ccEvent) {
100
100
  const cmd = asRecord(raw, path, `hooks.${ccEvent}[].hooks[]`);
101
101
  if (cmd.type !== "command") {
102
- throw new chunkA3MHE2MQ_cjs.ConfigurationError(
102
+ throw new chunkIHFNRNTJ_cjs.ConfigurationError(
103
103
  `hooks: only { "type": "command" } is supported (got ${JSON.stringify(cmd.type)}) in ${path}`,
104
104
  { code: "hooks_unsupported_type" }
105
105
  );
106
106
  }
107
107
  if (typeof cmd.command !== "string" || cmd.command.length === 0) {
108
- throw new chunkA3MHE2MQ_cjs.ConfigurationError(`hooks: "command" must be a non-empty string in ${path}`, {
108
+ throw new chunkIHFNRNTJ_cjs.ConfigurationError(`hooks: "command" must be a non-empty string in ${path}`, {
109
109
  code: "hooks_invalid_command"
110
110
  });
111
111
  }
@@ -137,5 +137,5 @@ exports.loadHookConfig = loadHookConfig;
137
137
  exports.warnOnce = warnOnce;
138
138
  exports.warnPersonalitySwitchInsideFork = warnPersonalitySwitchInsideFork;
139
139
  exports.withPersonalityContext = withPersonalityContext;
140
- //# sourceMappingURL=chunk-M4OGSS66.cjs.map
141
- //# sourceMappingURL=chunk-M4OGSS66.cjs.map
140
+ //# sourceMappingURL=chunk-6LGQECT7.cjs.map
141
+ //# sourceMappingURL=chunk-6LGQECT7.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/internal/runtime/hooks/hooks-source.ts","../src/internal/personality/context.ts"],"names":["diag","join","existsSync","readFile","ConfigurationError","AsyncLocalStorage"],"mappings":"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","file":"chunk-M4OGSS66.cjs","sourcesContent":["/**\n * Single source of truth for loading the hooks config (ADR 0016 — reverses\n * D74/D77 for hooks: JSON is canonical again, in the Claude Code shape).\n *\n * `.theokit/hooks.json` (Claude-Code-shaped JSON) is the only supported form.\n * A stray legacy `.theokit/hooks/*.md` dir (no hooks.json) is NOT loaded — it\n * warns to migrate and yields no hooks. Absent both → empty config.\n *\n * Consumed by `hooks-executor.ts` (runtime dispatch).\n *\n * Config shape (identical to Claude Code's `settings.json` hooks):\n * { \"hooks\": { \"PreToolUse\": [ { \"matcher\": \"shell\",\n * \"hooks\": [ { \"type\": \"command\", \"command\": \"…\", \"timeout\": 30 } ] } ] } }\n *\n * @internal\n */\n\nimport { existsSync } from \"node:fs\";\nimport { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { ConfigurationError } from \"../../../errors.js\";\nimport { diag } from \"../../diagnostics.js\";\n\n/** The five lifecycle events the SDK runtime actually fires. */\nexport type HookEvent = \"preRun\" | \"postRun\" | \"preToolUse\" | \"postToolUse\" | \"stop\";\n\n/**\n * Claude Code event name → the SDK firing event. Only events the runtime\n * genuinely emits are mapped; a Claude Code event with no SDK firing point\n * (SessionStart / SubagentStop / PreCompact / Notification / SessionEnd) is\n * skipped with a warn rather than silently accepted (it would never run).\n */\nconst CLAUDE_CODE_EVENT_MAP: Readonly<Record<string, HookEvent>> = {\n PreToolUse: \"preToolUse\",\n PostToolUse: \"postToolUse\",\n UserPromptSubmit: \"preRun\",\n Stop: \"stop\",\n};\n\nexport interface HookCommand {\n command: string;\n matcher?: string;\n timeoutMs?: number;\n}\n\nexport interface HookConfig {\n hooks?: Partial<Record<HookEvent, HookCommand[]>>;\n}\n\nconst warned = new Set<string>();\n\n/**\n * Emit a stderr warn once per process per unique key. Helps surface the\n * deprecation path without spamming when the loader is called many times\n * during a session (cron + send + skills all hit this).\n *\n * Note: spawned workers (cron, subagent) start fresh processes — warn\n * re-emits there, by design (1 per process boot, not per call).\n *\n * @internal\n */\nexport function warnOnce(key: string, message: string): void {\n if (warned.has(key)) return;\n warned.add(key);\n diag(`${message}\\n`);\n}\n\n/** Reset for tests; not exported via barrel. @internal */\nexport function _resetWarnOnceForTests(): void {\n warned.clear();\n}\n\n/**\n * Load hooks from `.theokit/hooks.json` (Claude-Code-shaped — the only supported\n * form). A stray legacy `.theokit/hooks/*.md` markdown dir (no `hooks.json`) is\n * NOT loaded — it emits a one-time migration warn and yields no hooks.\n *\n * @internal\n */\nexport async function loadHookConfig(cwd: string): Promise<HookConfig> {\n const jsonPath = join(cwd, \".theokit\", \"hooks.json\");\n\n if (!existsSync(jsonPath)) {\n if (existsSync(join(cwd, \".theokit\", \"hooks\"))) {\n warnOnce(\n \"hooks-md-unsupported\",\n \"[theokit-sdk] .theokit/hooks/*.md hooks are no longer supported (ADR 0016) — migrate to a Claude-Code-shaped .theokit/hooks.json\",\n );\n }\n return {};\n }\n\n let raw: string;\n try {\n raw = await readFile(jsonPath, \"utf8\");\n } catch (cause) {\n throw new ConfigurationError(`Failed to read hooks config: ${jsonPath}`, {\n code: \"hooks_read_error\",\n cause,\n });\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch (cause) {\n throw new ConfigurationError(`Invalid JSON in hooks config: ${jsonPath}`, {\n code: \"hooks_json_invalid\",\n cause,\n });\n }\n return parseClaudeCodeConfig(parsed, jsonPath);\n}\n\n/** Narrow an unknown to a record, or throw a typed config error. */\nfunction asRecord(value: unknown, path: string, where: string): Record<string, unknown> {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n throw new ConfigurationError(`hooks: expected an object at ${where} in ${path}`, {\n code: \"hooks_json_invalid\",\n });\n }\n return value as Record<string, unknown>;\n}\n\n/** Narrow an unknown to an array, or throw a typed config error. */\nfunction asArray(value: unknown, path: string, where: string): unknown[] {\n if (!Array.isArray(value)) {\n throw new ConfigurationError(`hooks: expected an array at ${where} in ${path}`, {\n code: \"hooks_json_invalid\",\n });\n }\n return value;\n}\n\n/**\n * Parse Claude Code's nested hooks config into the SDK's flat internal shape:\n * `{ hooks: { PreToolUse: [{ matcher?, hooks: [{ type:\"command\", command, timeout? }] }] } }`\n * → `{ hooks: { preToolUse: [{ command, matcher?, timeoutMs? }] } }`. Each group's\n * `matcher` applies to every command it wraps; `timeout` (seconds) → `timeoutMs`.\n */\nfunction parseClaudeCodeConfig(raw: unknown, path: string): HookConfig {\n const root = asRecord(raw, path, \"the root\");\n if (root.hooks === undefined) return {};\n const hooksRec = asRecord(root.hooks, path, `\"hooks\"`);\n const grouped: Partial<Record<HookEvent, HookCommand[]>> = {};\n\n for (const [ccEvent, groups] of Object.entries(hooksRec)) {\n const event = CLAUDE_CODE_EVENT_MAP[ccEvent];\n if (event === undefined) {\n warnOnce(\n `hooks-event-${ccEvent}`,\n `[theokit-sdk] hooks: event \"${ccEvent}\" is not fired by the SDK runtime (supported: ${Object.keys(CLAUDE_CODE_EVENT_MAP).join(\", \")}) — skipping`,\n );\n continue;\n }\n grouped[event] = [...(grouped[event] ?? []), ...flattenEventGroups(groups, path, ccEvent)];\n }\n return { hooks: grouped };\n}\n\n/** Flatten one Claude Code event's matcher-groups into internal HookCommands. */\nfunction flattenEventGroups(groups: unknown, path: string, ccEvent: string): HookCommand[] {\n const commands: HookCommand[] = [];\n for (const rawGroup of asArray(groups, path, `hooks.${ccEvent}`)) {\n const group = asRecord(rawGroup, path, `hooks.${ccEvent}[]`);\n const matcher = group.matcher === undefined ? undefined : String(group.matcher);\n for (const rawCmd of asArray(group.hooks, path, `hooks.${ccEvent}[].hooks`)) {\n commands.push(parseClaudeCodeCommand(rawCmd, matcher, path, ccEvent));\n }\n }\n return commands;\n}\n\n/** One `{ type:\"command\", command, timeout? }` entry → an internal HookCommand. */\nfunction parseClaudeCodeCommand(\n raw: unknown,\n matcher: string | undefined,\n path: string,\n ccEvent: string,\n): HookCommand {\n const cmd = asRecord(raw, path, `hooks.${ccEvent}[].hooks[]`);\n if (cmd.type !== \"command\") {\n throw new ConfigurationError(\n `hooks: only { \"type\": \"command\" } is supported (got ${JSON.stringify(cmd.type)}) in ${path}`,\n { code: \"hooks_unsupported_type\" },\n );\n }\n if (typeof cmd.command !== \"string\" || cmd.command.length === 0) {\n throw new ConfigurationError(`hooks: \"command\" must be a non-empty string in ${path}`, {\n code: \"hooks_invalid_command\",\n });\n }\n const hc: HookCommand = { command: cmd.command };\n if (matcher !== undefined) hc.matcher = matcher;\n if (typeof cmd.timeout === \"number\" && cmd.timeout > 0) {\n hc.timeoutMs = Math.round(cmd.timeout * 1000);\n }\n return hc;\n}\n","/**\n * Personality fork-context (ADR D168 + EC-A snapshot semantic).\n *\n * Uses Node's `AsyncLocalStorage` so a fork's execution chain can know\n * that it is running inside a fork AND can see the slug that was active\n * on the parent **at fork-construction time**.\n *\n * **EC-A:** The slug stored here is captured ONCE at the wrap site\n * (`localAgentFork`) — passing `parentStore.active(parentAgentId)`\n * returns a primitive `string | undefined`, which is then frozen\n * inside the ALS context object. Subsequent `usePersonality` calls on\n * the parent do NOT mutate the fork's view, because the fork reads from\n * its own ALS frame, not from the parent's store.\n *\n * @internal\n */\n\nimport { AsyncLocalStorage } from \"node:async_hooks\";\n\nimport { warnOnce } from \"../runtime/hooks/hooks-source.js\";\n\n/**\n * Snapshot data carried into a fork's async context.\n *\n * @internal\n */\nexport interface PersonalityForkContext {\n /** Parent's active personality slug at fork-construction time. */\n readonly slug: string | undefined;\n /** Always `true` inside this scope (used by guards). */\n readonly isFork: true;\n}\n\nconst storage = new AsyncLocalStorage<PersonalityForkContext>();\n\n/**\n * Run `fn` with `ctx` bound as the active fork context. Nested calls\n * shadow the outer context (EC-22).\n *\n * @internal\n */\nexport function withPersonalityContext<T>(\n ctx: PersonalityForkContext,\n fn: () => Promise<T>,\n): Promise<T> {\n return storage.run(ctx, fn);\n}\n\n/**\n * Return the active fork context, or `undefined` when called outside a\n * fork scope.\n *\n * @internal\n */\nexport function currentPersonalityContext(): PersonalityForkContext | undefined {\n return storage.getStore();\n}\n\n/**\n * Emit one warning per agentId stating that personality switches inside\n * a fork are no-ops. The fork inherits the parent snapshot — runtime\n * mutation is intentionally rejected to keep fork voice deterministic.\n *\n * @internal\n */\nexport function warnPersonalitySwitchInsideFork(agentId: string): void {\n warnOnce(\n `personality-switch-in-fork-${agentId}`,\n `[theokit-sdk] usePersonality is a no-op inside a fork (D168). Subagents inherit the parent's active personality at fork-construction time.`,\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/internal/runtime/hooks/hooks-source.ts","../src/internal/personality/context.ts"],"names":["diag","join","existsSync","readFile","ConfigurationError","AsyncLocalStorage"],"mappings":"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","file":"chunk-6LGQECT7.cjs","sourcesContent":["/**\n * Single source of truth for loading the hooks config (ADR 0016 — reverses\n * D74/D77 for hooks: JSON is canonical again, in the Claude Code shape).\n *\n * `.theokit/hooks.json` (Claude-Code-shaped JSON) is the only supported form.\n * A stray legacy `.theokit/hooks/*.md` dir (no hooks.json) is NOT loaded — it\n * warns to migrate and yields no hooks. Absent both → empty config.\n *\n * Consumed by `hooks-executor.ts` (runtime dispatch).\n *\n * Config shape (identical to Claude Code's `settings.json` hooks):\n * { \"hooks\": { \"PreToolUse\": [ { \"matcher\": \"shell\",\n * \"hooks\": [ { \"type\": \"command\", \"command\": \"…\", \"timeout\": 30 } ] } ] } }\n *\n * @internal\n */\n\nimport { existsSync } from \"node:fs\";\nimport { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { ConfigurationError } from \"../../../errors.js\";\nimport { diag } from \"../../diagnostics.js\";\n\n/** The five lifecycle events the SDK runtime actually fires. */\nexport type HookEvent = \"preRun\" | \"postRun\" | \"preToolUse\" | \"postToolUse\" | \"stop\";\n\n/**\n * Claude Code event name → the SDK firing event. Only events the runtime\n * genuinely emits are mapped; a Claude Code event with no SDK firing point\n * (SessionStart / SubagentStop / PreCompact / Notification / SessionEnd) is\n * skipped with a warn rather than silently accepted (it would never run).\n */\nconst CLAUDE_CODE_EVENT_MAP: Readonly<Record<string, HookEvent>> = {\n PreToolUse: \"preToolUse\",\n PostToolUse: \"postToolUse\",\n UserPromptSubmit: \"preRun\",\n Stop: \"stop\",\n};\n\nexport interface HookCommand {\n command: string;\n matcher?: string;\n timeoutMs?: number;\n}\n\nexport interface HookConfig {\n hooks?: Partial<Record<HookEvent, HookCommand[]>>;\n}\n\nconst warned = new Set<string>();\n\n/**\n * Emit a stderr warn once per process per unique key. Helps surface the\n * deprecation path without spamming when the loader is called many times\n * during a session (cron + send + skills all hit this).\n *\n * Note: spawned workers (cron, subagent) start fresh processes — warn\n * re-emits there, by design (1 per process boot, not per call).\n *\n * @internal\n */\nexport function warnOnce(key: string, message: string): void {\n if (warned.has(key)) return;\n warned.add(key);\n diag(`${message}\\n`);\n}\n\n/** Reset for tests; not exported via barrel. @internal */\nexport function _resetWarnOnceForTests(): void {\n warned.clear();\n}\n\n/**\n * Load hooks from `.theokit/hooks.json` (Claude-Code-shaped — the only supported\n * form). A stray legacy `.theokit/hooks/*.md` markdown dir (no `hooks.json`) is\n * NOT loaded — it emits a one-time migration warn and yields no hooks.\n *\n * @internal\n */\nexport async function loadHookConfig(cwd: string): Promise<HookConfig> {\n const jsonPath = join(cwd, \".theokit\", \"hooks.json\");\n\n if (!existsSync(jsonPath)) {\n if (existsSync(join(cwd, \".theokit\", \"hooks\"))) {\n warnOnce(\n \"hooks-md-unsupported\",\n \"[theokit-sdk] .theokit/hooks/*.md hooks are no longer supported (ADR 0016) — migrate to a Claude-Code-shaped .theokit/hooks.json\",\n );\n }\n return {};\n }\n\n let raw: string;\n try {\n raw = await readFile(jsonPath, \"utf8\");\n } catch (cause) {\n throw new ConfigurationError(`Failed to read hooks config: ${jsonPath}`, {\n code: \"hooks_read_error\",\n cause,\n });\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch (cause) {\n throw new ConfigurationError(`Invalid JSON in hooks config: ${jsonPath}`, {\n code: \"hooks_json_invalid\",\n cause,\n });\n }\n return parseClaudeCodeConfig(parsed, jsonPath);\n}\n\n/** Narrow an unknown to a record, or throw a typed config error. */\nfunction asRecord(value: unknown, path: string, where: string): Record<string, unknown> {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n throw new ConfigurationError(`hooks: expected an object at ${where} in ${path}`, {\n code: \"hooks_json_invalid\",\n });\n }\n return value as Record<string, unknown>;\n}\n\n/** Narrow an unknown to an array, or throw a typed config error. */\nfunction asArray(value: unknown, path: string, where: string): unknown[] {\n if (!Array.isArray(value)) {\n throw new ConfigurationError(`hooks: expected an array at ${where} in ${path}`, {\n code: \"hooks_json_invalid\",\n });\n }\n return value;\n}\n\n/**\n * Parse Claude Code's nested hooks config into the SDK's flat internal shape:\n * `{ hooks: { PreToolUse: [{ matcher?, hooks: [{ type:\"command\", command, timeout? }] }] } }`\n * → `{ hooks: { preToolUse: [{ command, matcher?, timeoutMs? }] } }`. Each group's\n * `matcher` applies to every command it wraps; `timeout` (seconds) → `timeoutMs`.\n */\nfunction parseClaudeCodeConfig(raw: unknown, path: string): HookConfig {\n const root = asRecord(raw, path, \"the root\");\n if (root.hooks === undefined) return {};\n const hooksRec = asRecord(root.hooks, path, `\"hooks\"`);\n const grouped: Partial<Record<HookEvent, HookCommand[]>> = {};\n\n for (const [ccEvent, groups] of Object.entries(hooksRec)) {\n const event = CLAUDE_CODE_EVENT_MAP[ccEvent];\n if (event === undefined) {\n warnOnce(\n `hooks-event-${ccEvent}`,\n `[theokit-sdk] hooks: event \"${ccEvent}\" is not fired by the SDK runtime (supported: ${Object.keys(CLAUDE_CODE_EVENT_MAP).join(\", \")}) — skipping`,\n );\n continue;\n }\n grouped[event] = [...(grouped[event] ?? []), ...flattenEventGroups(groups, path, ccEvent)];\n }\n return { hooks: grouped };\n}\n\n/** Flatten one Claude Code event's matcher-groups into internal HookCommands. */\nfunction flattenEventGroups(groups: unknown, path: string, ccEvent: string): HookCommand[] {\n const commands: HookCommand[] = [];\n for (const rawGroup of asArray(groups, path, `hooks.${ccEvent}`)) {\n const group = asRecord(rawGroup, path, `hooks.${ccEvent}[]`);\n const matcher = group.matcher === undefined ? undefined : String(group.matcher);\n for (const rawCmd of asArray(group.hooks, path, `hooks.${ccEvent}[].hooks`)) {\n commands.push(parseClaudeCodeCommand(rawCmd, matcher, path, ccEvent));\n }\n }\n return commands;\n}\n\n/** One `{ type:\"command\", command, timeout? }` entry → an internal HookCommand. */\nfunction parseClaudeCodeCommand(\n raw: unknown,\n matcher: string | undefined,\n path: string,\n ccEvent: string,\n): HookCommand {\n const cmd = asRecord(raw, path, `hooks.${ccEvent}[].hooks[]`);\n if (cmd.type !== \"command\") {\n throw new ConfigurationError(\n `hooks: only { \"type\": \"command\" } is supported (got ${JSON.stringify(cmd.type)}) in ${path}`,\n { code: \"hooks_unsupported_type\" },\n );\n }\n if (typeof cmd.command !== \"string\" || cmd.command.length === 0) {\n throw new ConfigurationError(`hooks: \"command\" must be a non-empty string in ${path}`, {\n code: \"hooks_invalid_command\",\n });\n }\n const hc: HookCommand = { command: cmd.command };\n if (matcher !== undefined) hc.matcher = matcher;\n if (typeof cmd.timeout === \"number\" && cmd.timeout > 0) {\n hc.timeoutMs = Math.round(cmd.timeout * 1000);\n }\n return hc;\n}\n","/**\n * Personality fork-context (ADR D168 + EC-A snapshot semantic).\n *\n * Uses Node's `AsyncLocalStorage` so a fork's execution chain can know\n * that it is running inside a fork AND can see the slug that was active\n * on the parent **at fork-construction time**.\n *\n * **EC-A:** The slug stored here is captured ONCE at the wrap site\n * (`localAgentFork`) — passing `parentStore.active(parentAgentId)`\n * returns a primitive `string | undefined`, which is then frozen\n * inside the ALS context object. Subsequent `usePersonality` calls on\n * the parent do NOT mutate the fork's view, because the fork reads from\n * its own ALS frame, not from the parent's store.\n *\n * @internal\n */\n\nimport { AsyncLocalStorage } from \"node:async_hooks\";\n\nimport { warnOnce } from \"../runtime/hooks/hooks-source.js\";\n\n/**\n * Snapshot data carried into a fork's async context.\n *\n * @internal\n */\nexport interface PersonalityForkContext {\n /** Parent's active personality slug at fork-construction time. */\n readonly slug: string | undefined;\n /** Always `true` inside this scope (used by guards). */\n readonly isFork: true;\n}\n\nconst storage = new AsyncLocalStorage<PersonalityForkContext>();\n\n/**\n * Run `fn` with `ctx` bound as the active fork context. Nested calls\n * shadow the outer context (EC-22).\n *\n * @internal\n */\nexport function withPersonalityContext<T>(\n ctx: PersonalityForkContext,\n fn: () => Promise<T>,\n): Promise<T> {\n return storage.run(ctx, fn);\n}\n\n/**\n * Return the active fork context, or `undefined` when called outside a\n * fork scope.\n *\n * @internal\n */\nexport function currentPersonalityContext(): PersonalityForkContext | undefined {\n return storage.getStore();\n}\n\n/**\n * Emit one warning per agentId stating that personality switches inside\n * a fork are no-ops. The fork inherits the parent snapshot — runtime\n * mutation is intentionally rejected to keep fork voice deterministic.\n *\n * @internal\n */\nexport function warnPersonalitySwitchInsideFork(agentId: string): void {\n warnOnce(\n `personality-switch-in-fork-${agentId}`,\n `[theokit-sdk] usePersonality is a no-op inside a fork (D168). Subagents inherit the parent's active personality at fork-construction time.`,\n );\n}\n"]}
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var chunkC6Y6CWYD_cjs = require('./chunk-C6Y6CWYD.cjs');
4
- var chunkA3MHE2MQ_cjs = require('./chunk-A3MHE2MQ.cjs');
4
+ var chunkIHFNRNTJ_cjs = require('./chunk-IHFNRNTJ.cjs');
5
5
  var crypto = require('crypto');
6
6
  var fs = require('fs');
7
7
  var path = require('path');
@@ -14,7 +14,7 @@ function credentialHome(config, env = {}) {
14
14
  function authFilePath(config, env = {}) {
15
15
  return path.join(credentialHome(config, env), config.fileName);
16
16
  }
17
- var CredentialError = class extends chunkA3MHE2MQ_cjs.AuthenticationError {
17
+ var CredentialError = class extends chunkIHFNRNTJ_cjs.AuthenticationError {
18
18
  // Field, not an assignment in the constructor: `AuthenticationError.name` is `override readonly`
19
19
  // (`errors.ts:174`), so `this.name = …` does not compile. Caught by `tsc`, not by vitest — the
20
20
  // suite was green with the broken assignment because the transpiler strips the type.
@@ -320,5 +320,5 @@ exports.readStoredOAuth = readStoredOAuth;
320
320
  exports.refreshOAuthTokens = refreshOAuthTokens;
321
321
  exports.resolveCredential = resolveCredential;
322
322
  exports.writeCredential = writeCredential;
323
- //# sourceMappingURL=chunk-KTXOHCAE.cjs.map
324
- //# sourceMappingURL=chunk-KTXOHCAE.cjs.map
323
+ //# sourceMappingURL=chunk-6NEHIHFU.cjs.map
324
+ //# sourceMappingURL=chunk-6NEHIHFU.cjs.map