@theokit/sdk 4.37.2 → 4.39.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (457) hide show
  1. package/CHANGELOG.md +309 -72
  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-SmxntivO.d.ts → agent-D7bRK9Kg.d.cts} +108 -41
  7. package/dist/agent-I3EZZR6S.cjs +55 -0
  8. package/dist/{agent-IE6IE4NW.cjs.map → agent-I3EZZR6S.cjs.map} +1 -1
  9. package/dist/agent-KKZYLY5D.js +46 -0
  10. package/dist/{agent-DW2J37IH.js.map → agent-KKZYLY5D.js.map} +1 -1
  11. package/dist/{agent-DGv1-d81.d.cts → agent-ZCZa7YQv.d.ts} +108 -41
  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 +38 -2
  17. package/dist/auth/index.cjs +15 -15
  18. package/dist/auth/index.js +4 -4
  19. package/dist/{batch-SY5GZLFD.js → batch-6KQM3EBA.js} +12 -12
  20. package/dist/batch-6KQM3EBA.js.map +1 -0
  21. package/dist/{batch-3SEPDXCU.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-2WFB5ZOX.js → chunk-42IFCKQZ.js} +5 -5
  28. package/dist/{chunk-2WFB5ZOX.js.map → chunk-42IFCKQZ.js.map} +1 -1
  29. package/dist/{chunk-DCJ5MCJ3.js → chunk-4F7JQZOX.js} +9 -36
  30. package/dist/chunk-4F7JQZOX.js.map +1 -0
  31. package/dist/{chunk-JNIWFCKI.js → chunk-4JSZYSGW.js} +3 -3
  32. package/dist/{chunk-JNIWFCKI.js.map → chunk-4JSZYSGW.js.map} +1 -1
  33. package/dist/{chunk-EEZ7CFMM.js → chunk-5KOW3GLE.js} +2 -2
  34. package/dist/chunk-5KOW3GLE.js.map +1 -0
  35. package/dist/{chunk-6VP3XGEK.js → chunk-65ONFZWM.js} +12 -11
  36. package/dist/chunk-65ONFZWM.js.map +1 -0
  37. package/dist/{chunk-CSZRJ4RE.js → chunk-6EEYRFJC.js} +5 -5
  38. package/dist/{chunk-CSZRJ4RE.js.map → chunk-6EEYRFJC.js.map} +1 -1
  39. package/dist/{chunk-FAY3QDGC.cjs → chunk-6LGQECT7.cjs} +11 -11
  40. package/dist/{chunk-FAY3QDGC.cjs.map → chunk-6LGQECT7.cjs.map} +1 -1
  41. package/dist/{chunk-PAEJPLVN.cjs → chunk-6NEHIHFU.cjs} +4 -4
  42. package/dist/{chunk-PAEJPLVN.cjs.map → chunk-6NEHIHFU.cjs.map} +1 -1
  43. package/dist/chunk-6YNYA7GD.cjs +103 -0
  44. package/dist/chunk-6YNYA7GD.cjs.map +1 -0
  45. package/dist/chunk-74D7KSBP.cjs +112 -0
  46. package/dist/chunk-74D7KSBP.cjs.map +1 -0
  47. package/dist/{chunk-FK4EJD2I.cjs → chunk-75DSEWTJ.cjs} +7 -7
  48. package/dist/{chunk-FK4EJD2I.cjs.map → chunk-75DSEWTJ.cjs.map} +1 -1
  49. package/dist/{chunk-SWIBQFPH.cjs → chunk-7OLG7VI4.cjs} +4 -4
  50. package/dist/{chunk-SWIBQFPH.cjs.map → chunk-7OLG7VI4.cjs.map} +1 -1
  51. package/dist/chunk-7U2HAAWB.cjs +199 -0
  52. package/dist/chunk-7U2HAAWB.cjs.map +1 -0
  53. package/dist/{chunk-YBFDBOUN.cjs → chunk-7YBJZS5P.cjs} +8 -8
  54. package/dist/{chunk-YBFDBOUN.cjs.map → chunk-7YBJZS5P.cjs.map} +1 -1
  55. package/dist/{chunk-GLUWH6JO.js → chunk-AECV3G5Z.js} +4 -4
  56. package/dist/{chunk-GLUWH6JO.js.map → chunk-AECV3G5Z.js.map} +1 -1
  57. package/dist/{chunk-UQPDFW4E.js → chunk-AR5MQZ3J.js} +3 -3
  58. package/dist/{chunk-UQPDFW4E.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-LTCOPATU.cjs → chunk-BCQ3E2ZG.cjs} +12 -3
  62. package/dist/chunk-BCQ3E2ZG.cjs.map +1 -0
  63. package/dist/{chunk-ALU3KC4G.cjs → chunk-BPN5ONSW.cjs} +223 -277
  64. package/dist/chunk-BPN5ONSW.cjs.map +1 -0
  65. package/dist/{chunk-YHZXBDAW.js → chunk-BQDUEG4C.js} +16 -16
  66. package/dist/{chunk-YHZXBDAW.js.map → chunk-BQDUEG4C.js.map} +1 -1
  67. package/dist/{chunk-IT3PWBW4.cjs → chunk-BURYFNOM.cjs} +2 -2
  68. package/dist/chunk-BURYFNOM.cjs.map +1 -0
  69. package/dist/{chunk-BJMKQOY2.cjs → chunk-C7OP3FAK.cjs} +47 -11
  70. package/dist/chunk-C7OP3FAK.cjs.map +1 -0
  71. package/dist/{chunk-XAYVHS2B.cjs → chunk-CEIHCKTO.cjs} +4 -4
  72. package/dist/chunk-CEIHCKTO.cjs.map +1 -0
  73. package/dist/{chunk-2423XDPT.cjs → chunk-CN6UX5EV.cjs} +28 -56
  74. package/dist/chunk-CN6UX5EV.cjs.map +1 -0
  75. package/dist/{chunk-VNNK6AKU.js → chunk-D7IULBF2.js} +3 -3
  76. package/dist/chunk-D7IULBF2.js.map +1 -0
  77. package/dist/chunk-DCXRHCZJ.cjs +118 -0
  78. package/dist/chunk-DCXRHCZJ.cjs.map +1 -0
  79. package/dist/{chunk-ICYBIC6N.cjs → chunk-DGLLVCNB.cjs} +4 -4
  80. package/dist/chunk-DGLLVCNB.cjs.map +1 -0
  81. package/dist/{chunk-I35DI7ES.js → chunk-DKFGUOWL.js} +3 -3
  82. package/dist/{chunk-I35DI7ES.js.map → chunk-DKFGUOWL.js.map} +1 -1
  83. package/dist/{chunk-TQI3KRXZ.cjs → chunk-DMTZ3FII.cjs} +18 -18
  84. package/dist/{chunk-TQI3KRXZ.cjs.map → chunk-DMTZ3FII.cjs.map} +1 -1
  85. package/dist/{chunk-QFMXXUUT.js → chunk-DU7DE543.js} +3 -3
  86. package/dist/{chunk-QFMXXUUT.js.map → chunk-DU7DE543.js.map} +1 -1
  87. package/dist/{chunk-W4QN5CMG.cjs → chunk-DWY25VLP.cjs} +9 -9
  88. package/dist/{chunk-W4QN5CMG.cjs.map → chunk-DWY25VLP.cjs.map} +1 -1
  89. package/dist/chunk-E2FFG33C.js +109 -0
  90. package/dist/chunk-E2FFG33C.js.map +1 -0
  91. package/dist/{chunk-QUFSDDNU.cjs → chunk-E4IUN3JB.cjs} +15 -15
  92. package/dist/{chunk-QUFSDDNU.cjs.map → chunk-E4IUN3JB.cjs.map} +1 -1
  93. package/dist/{chunk-THEYGCYS.cjs → chunk-ECHGWE47.cjs} +4 -4
  94. package/dist/chunk-ECHGWE47.cjs.map +1 -0
  95. package/dist/{chunk-U2WLFOA3.cjs → chunk-ECW2MLEW.cjs} +4 -4
  96. package/dist/{chunk-U2WLFOA3.cjs.map → chunk-ECW2MLEW.cjs.map} +1 -1
  97. package/dist/{chunk-MXSMAGDU.js → chunk-ET6PHZRX.js} +33 -26
  98. package/dist/chunk-ET6PHZRX.js.map +1 -0
  99. package/dist/{chunk-G6AASL5T.cjs → chunk-FRUBE44B.cjs} +24 -24
  100. package/dist/{chunk-G6AASL5T.cjs.map → chunk-FRUBE44B.cjs.map} +1 -1
  101. package/dist/{chunk-3ILFUXNE.cjs → chunk-FWBSDQZ7.cjs} +5 -5
  102. package/dist/{chunk-3ILFUXNE.cjs.map → chunk-FWBSDQZ7.cjs.map} +1 -1
  103. package/dist/{chunk-7DXLNNKH.cjs → chunk-G2Q3ZC6C.cjs} +4 -4
  104. package/dist/{chunk-7DXLNNKH.cjs.map → chunk-G2Q3ZC6C.cjs.map} +1 -1
  105. package/dist/{chunk-56ZM6P7Z.cjs → chunk-G4XUXSRN.cjs} +12 -12
  106. package/dist/chunk-G4XUXSRN.cjs.map +1 -0
  107. package/dist/{chunk-VYJSHGAY.js → chunk-GIRD3RWH.js} +422 -295
  108. package/dist/chunk-GIRD3RWH.js.map +1 -0
  109. package/dist/{chunk-NQ4AC2U4.cjs → chunk-HIQFVHC6.cjs} +9 -9
  110. package/dist/{chunk-NQ4AC2U4.cjs.map → chunk-HIQFVHC6.cjs.map} +1 -1
  111. package/dist/{chunk-EXQV452X.js → chunk-HWNVAUK4.js} +3 -3
  112. package/dist/{chunk-EXQV452X.js.map → chunk-HWNVAUK4.js.map} +1 -1
  113. package/dist/{chunk-P34DHHYQ.cjs → chunk-I53ZQHU6.cjs} +34 -27
  114. package/dist/chunk-I53ZQHU6.cjs.map +1 -0
  115. package/dist/{chunk-MHCKWQR3.cjs → chunk-IHFNRNTJ.cjs} +8 -8
  116. package/dist/{chunk-MHCKWQR3.cjs.map → chunk-IHFNRNTJ.cjs.map} +1 -1
  117. package/dist/{chunk-W52DKZBR.cjs → chunk-INSFS5GT.cjs} +680 -553
  118. package/dist/chunk-INSFS5GT.cjs.map +1 -0
  119. package/dist/{chunk-TAPQWDW2.js → chunk-IVSD7L22.js} +12 -4
  120. package/dist/chunk-IVSD7L22.js.map +1 -0
  121. package/dist/{chunk-WDGCZDRG.js → chunk-J3UK2GMN.js} +3 -3
  122. package/dist/{chunk-WDGCZDRG.js.map → chunk-J3UK2GMN.js.map} +1 -1
  123. package/dist/{chunk-4YB7B3RP.cjs → chunk-J6T5LWJ4.cjs} +15 -14
  124. package/dist/chunk-J6T5LWJ4.cjs.map +1 -0
  125. package/dist/{chunk-XAEAMI5H.js → chunk-JRLXEYR4.js} +21 -5
  126. package/dist/chunk-JRLXEYR4.js.map +1 -0
  127. package/dist/{chunk-ZJN6NTHE.js → chunk-JZUPMTJY.js} +3 -3
  128. package/dist/{chunk-ZJN6NTHE.js.map → chunk-JZUPMTJY.js.map} +1 -1
  129. package/dist/{chunk-M5ZQBOIZ.js → chunk-KE6XKRLQ.js} +3 -3
  130. package/dist/{chunk-M5ZQBOIZ.js.map → chunk-KE6XKRLQ.js.map} +1 -1
  131. package/dist/chunk-KGRIHEDT.js +110 -0
  132. package/dist/chunk-KGRIHEDT.js.map +1 -0
  133. package/dist/{chunk-T4QWDOG6.js → chunk-KWUNN5J2.js} +5 -5
  134. package/dist/{chunk-T4QWDOG6.js.map → chunk-KWUNN5J2.js.map} +1 -1
  135. package/dist/{chunk-56OXYUZE.js → chunk-KX7JV5KM.js} +3 -3
  136. package/dist/chunk-KX7JV5KM.js.map +1 -0
  137. package/dist/{chunk-D4ZUJTFB.cjs → chunk-LALG2K33.cjs} +8 -8
  138. package/dist/{chunk-D4ZUJTFB.cjs.map → chunk-LALG2K33.cjs.map} +1 -1
  139. package/dist/{chunk-QGDKZDPN.js → chunk-LGILIGV3.js} +3 -3
  140. package/dist/{chunk-QGDKZDPN.js.map → chunk-LGILIGV3.js.map} +1 -1
  141. package/dist/{chunk-HEN5WXXI.js → chunk-LJX2SQV2.js} +6 -6
  142. package/dist/{chunk-HEN5WXXI.js.map → chunk-LJX2SQV2.js.map} +1 -1
  143. package/dist/{chunk-SDIBMLL5.js → chunk-MC5EINBV.js} +44 -8
  144. package/dist/chunk-MC5EINBV.js.map +1 -0
  145. package/dist/{chunk-F6Y4IEQM.js → chunk-ML5A5DOJ.js} +4 -4
  146. package/dist/{chunk-F6Y4IEQM.js.map → chunk-ML5A5DOJ.js.map} +1 -1
  147. package/dist/{chunk-6EDQBX7U.cjs → chunk-N475ETD6.cjs} +17 -17
  148. package/dist/{chunk-6EDQBX7U.cjs.map → chunk-N475ETD6.cjs.map} +1 -1
  149. package/dist/{chunk-YPQF26X7.cjs → chunk-OBA6YK2R.cjs} +2 -2
  150. package/dist/chunk-OBA6YK2R.cjs.map +1 -0
  151. package/dist/chunk-OXNYIMZZ.js +31 -0
  152. package/dist/chunk-OXNYIMZZ.js.map +1 -0
  153. package/dist/{chunk-NFCKEBHI.js → chunk-PI4RO4GR.js} +3 -3
  154. package/dist/{chunk-NFCKEBHI.js.map → chunk-PI4RO4GR.js.map} +1 -1
  155. package/dist/{chunk-2ONFGMBV.js → chunk-PY2RQOA7.js} +2 -2
  156. package/dist/chunk-PY2RQOA7.js.map +1 -0
  157. package/dist/chunk-QKE556YD.js +197 -0
  158. package/dist/chunk-QKE556YD.js.map +1 -0
  159. package/dist/{chunk-FV3YEMQ7.js → chunk-RP5HQVLD.js} +13 -14
  160. package/dist/chunk-RP5HQVLD.js.map +1 -0
  161. package/dist/chunk-SCFW5MJZ.js +100 -0
  162. package/dist/chunk-SCFW5MJZ.js.map +1 -0
  163. package/dist/{chunk-CD73YHEH.js → chunk-SG5ZWT6C.js} +3 -3
  164. package/dist/{chunk-CD73YHEH.js.map → chunk-SG5ZWT6C.js.map} +1 -1
  165. package/dist/{chunk-MRODLUGY.cjs → chunk-TIMPJL5V.cjs} +4 -4
  166. package/dist/{chunk-MRODLUGY.cjs.map → chunk-TIMPJL5V.cjs.map} +1 -1
  167. package/dist/{chunk-77WHPVXE.js → chunk-TOTP24P6.js} +4 -4
  168. package/dist/chunk-TOTP24P6.js.map +1 -0
  169. package/dist/{chunk-3O2ELBST.cjs → chunk-USZTVNUQ.cjs} +5 -5
  170. package/dist/{chunk-3O2ELBST.cjs.map → chunk-USZTVNUQ.cjs.map} +1 -1
  171. package/dist/{chunk-YDLNI7J6.js → chunk-V2RBCCN5.js} +3 -3
  172. package/dist/chunk-V2RBCCN5.js.map +1 -0
  173. package/dist/{chunk-NNSKJCBM.cjs → chunk-VJYSQXN6.cjs} +10 -10
  174. package/dist/{chunk-NNSKJCBM.cjs.map → chunk-VJYSQXN6.cjs.map} +1 -1
  175. package/dist/{chunk-GM7QDQ24.cjs → chunk-W4WKVOOQ.cjs} +11 -11
  176. package/dist/{chunk-GM7QDQ24.cjs.map → chunk-W4WKVOOQ.cjs.map} +1 -1
  177. package/dist/chunk-XYOHKCYG.cjs +109 -0
  178. package/dist/chunk-XYOHKCYG.cjs.map +1 -0
  179. package/dist/{chunk-ZW345YOI.js → chunk-YP67XZES.js} +4 -4
  180. package/dist/{chunk-ZW345YOI.js.map → chunk-YP67XZES.js.map} +1 -1
  181. package/dist/{chunk-YCXMSDSP.js → chunk-YRXY2A5L.js} +4 -4
  182. package/dist/{chunk-YCXMSDSP.js.map → chunk-YRXY2A5L.js.map} +1 -1
  183. package/dist/{chunk-IEUDKUPM.cjs → chunk-Z2CUEBXV.cjs} +25 -9
  184. package/dist/chunk-Z2CUEBXV.cjs.map +1 -0
  185. package/dist/{chunk-GL7CFBVC.js → chunk-ZYB6B7QJ.js} +112 -165
  186. package/dist/chunk-ZYB6B7QJ.js.map +1 -0
  187. package/dist/compact-session-PYEC3NZV.js +18 -0
  188. package/dist/{compact-session-WNKKIIDW.js.map → compact-session-PYEC3NZV.js.map} +1 -1
  189. package/dist/compact-session-VVT6IBJG.cjs +55 -0
  190. package/dist/{compact-session-H5TKLD55.cjs.map → compact-session-VVT6IBJG.cjs.map} +1 -1
  191. package/dist/compaction.cjs +19 -19
  192. package/dist/compaction.d.cts +9 -9
  193. package/dist/compaction.d.ts +9 -9
  194. package/dist/compaction.js +3 -3
  195. package/dist/concurrency.cjs +6 -6
  196. package/dist/concurrency.js +4 -4
  197. package/dist/context-2FZSC6VQ.cjs +22 -0
  198. package/dist/{context-ZV33V4DC.cjs.map → context-2FZSC6VQ.cjs.map} +1 -1
  199. package/dist/context-ATJJAFOS.js +5 -0
  200. package/dist/{context-VAYLPT4O.js.map → context-ATJJAFOS.js.map} +1 -1
  201. package/dist/{cron-Dx7B-3WB.d.ts → cron-Bx7tzm5R.d.ts} +54 -2
  202. package/dist/{cron-BiK_aNJI.d.cts → cron-D-DVjGQe.d.cts} +54 -2
  203. package/dist/cron.cjs +34 -30
  204. package/dist/cron.d.cts +3 -3
  205. package/dist/cron.d.ts +3 -3
  206. package/dist/cron.js +33 -29
  207. package/dist/{errors-DyVbXdR4.d.cts → errors-DMY-gLSK.d.cts} +1 -1
  208. package/dist/{errors-Cua4WC9H.d.ts → errors-DjBQ4Tn8.d.ts} +1 -1
  209. package/dist/errors.cjs +21 -21
  210. package/dist/errors.d.cts +2 -2
  211. package/dist/errors.d.ts +2 -2
  212. package/dist/errors.js +2 -2
  213. package/dist/eval.cjs +42 -37
  214. package/dist/eval.cjs.map +1 -1
  215. package/dist/eval.js +38 -33
  216. package/dist/eval.js.map +1 -1
  217. package/dist/{executor-OZSYXDKF.cjs → executor-BMRICN46.cjs} +26 -25
  218. package/dist/executor-BMRICN46.cjs.map +1 -0
  219. package/dist/{executor-PAH72CB5.js → executor-T65PPOPT.js} +10 -9
  220. package/dist/executor-T65PPOPT.js.map +1 -0
  221. package/dist/filesystem/index.cjs +7 -7
  222. package/dist/filesystem/index.js +3 -3
  223. package/dist/fs-session-store-J5MCFFUM.cjs +19 -0
  224. package/dist/{fs-session-store-7E7UPLF2.cjs.map → fs-session-store-J5MCFFUM.cjs.map} +1 -1
  225. package/dist/fs-session-store-O6FNHECD.js +10 -0
  226. package/dist/{fs-session-store-6MY7PNI2.js.map → fs-session-store-O6FNHECD.js.map} +1 -1
  227. package/dist/generate-object-UF6WIZLF.cjs +20 -0
  228. package/dist/{generate-object-5SCEH2EE.cjs.map → generate-object-UF6WIZLF.cjs.map} +1 -1
  229. package/dist/generate-object-XDCBYVK3.js +7 -0
  230. package/dist/{generate-object-I7UD4NWN.js.map → generate-object-XDCBYVK3.js.map} +1 -1
  231. package/dist/index-manager-N7RQYUKT.cjs +20 -0
  232. package/dist/{index-manager-R6ZJFEZF.cjs.map → index-manager-N7RQYUKT.cjs.map} +1 -1
  233. package/dist/index-manager-ZVZUHPP7.js +11 -0
  234. package/dist/{index-manager-KKAK7NT3.js.map → index-manager-ZVZUHPP7.js.map} +1 -1
  235. package/dist/index.cjs +154 -148
  236. package/dist/index.cjs.map +1 -1
  237. package/dist/index.d.cts +201 -43
  238. package/dist/index.d.ts +201 -43
  239. package/dist/index.js +62 -59
  240. package/dist/index.js.map +1 -1
  241. package/dist/{inject-session-UXNJQTZ6.js → inject-session-GQMTDZUN.js} +8 -7
  242. package/dist/inject-session-GQMTDZUN.js.map +1 -0
  243. package/dist/{inject-session-DM4SKTZO.cjs → inject-session-LFCYVSLJ.cjs} +11 -10
  244. package/dist/inject-session-LFCYVSLJ.cjs.map +1 -0
  245. package/dist/internal/agent-loop/live-events.d.ts +46 -0
  246. package/dist/internal/agent-loop/loop-thinking-steps.d.ts +28 -0
  247. package/dist/internal/agent-loop/message-builders.d.ts +12 -3
  248. package/dist/internal/budget/compute-cost.d.ts +1 -1
  249. package/dist/internal/diagnostics.d.ts +46 -31
  250. package/dist/internal/error-mappers/anthropic.d.ts +1 -1
  251. package/dist/internal/global-singleton.d.ts +7 -7
  252. package/dist/internal/judge/judge-call.d.ts +14 -14
  253. package/dist/internal/llm/anthropic-shared.d.ts +4 -4
  254. package/dist/internal/llm/retrying-client.d.ts +29 -29
  255. package/dist/internal/llm/transport-error.d.ts +2 -2
  256. package/dist/internal/llm/types.d.ts +49 -9
  257. package/dist/internal/local-agent/mcp-pool.d.ts +7 -3
  258. package/dist/internal/memory/adapters/azure-openai-embedding.d.cts +2 -0
  259. package/dist/internal/memory/adapters/catalog.d.cts +1 -0
  260. package/dist/internal/memory/adapters/cohere-embedding.d.cts +2 -0
  261. package/dist/internal/memory/adapters/deepinfra-embedding.d.cts +2 -0
  262. package/dist/internal/memory/adapters/gemini-embedding.d.cts +2 -0
  263. package/dist/internal/memory/adapters/index.cjs +28 -0
  264. package/dist/internal/memory/adapters/index.cjs.map +1 -0
  265. package/dist/internal/memory/adapters/index.d.cts +16 -0
  266. package/dist/internal/memory/adapters/index.d.ts +16 -0
  267. package/dist/internal/memory/adapters/index.js +11 -0
  268. package/dist/internal/memory/adapters/index.js.map +1 -0
  269. package/dist/internal/memory/adapters/jina-embedding.d.cts +2 -0
  270. package/dist/internal/memory/adapters/mistral-embedding.d.cts +2 -0
  271. package/dist/internal/memory/adapters/ollama-embedding.d.cts +34 -0
  272. package/dist/internal/memory/adapters/openai-compatible.d.cts +51 -0
  273. package/dist/internal/memory/adapters/openai-compatible.d.ts +28 -0
  274. package/dist/internal/memory/adapters/openai-embedding.d.cts +2 -0
  275. package/dist/internal/memory/adapters/openrouter-embedding.d.cts +2 -0
  276. package/dist/internal/memory/adapters/voyage-embedding.d.cts +2 -0
  277. package/dist/internal/memory/dreaming/diary.d.ts +4 -0
  278. package/dist/internal/memory/dreaming/phases.d.ts +15 -0
  279. package/dist/internal/memory/dreaming/run.d.ts +10 -0
  280. package/dist/internal/memory/migrate-sqlite-to-lance.d.ts +15 -0
  281. package/dist/internal/memory/sdk-memory-peer-loader.d.ts +21 -0
  282. package/dist/internal/persistence/exclusive-create.d.cts +2 -2
  283. package/dist/internal/persistence/exclusive-create.d.ts +2 -2
  284. package/dist/internal/persistence/fs-session-store.d.cts +18 -18
  285. package/dist/internal/persistence/fs-session-store.d.ts +18 -18
  286. package/dist/internal/persistence/index.cjs +25 -25
  287. package/dist/internal/persistence/index.cjs.map +1 -1
  288. package/dist/internal/persistence/index.js +6 -6
  289. package/dist/internal/persistence/index.js.map +1 -1
  290. package/dist/internal/persistence/paths.d.cts +7 -7
  291. package/dist/internal/persistence/paths.d.ts +7 -7
  292. package/dist/internal/persistence/session-transcript.d.cts +13 -7
  293. package/dist/internal/persistence/session-transcript.d.ts +13 -7
  294. package/dist/internal/persistence/session-writer.d.cts +30 -13
  295. package/dist/internal/persistence/session-writer.d.ts +30 -13
  296. package/dist/internal/runtime/concurrency/subagent-credentials.d.ts +35 -0
  297. package/dist/internal/runtime/fixtures/fixture-run-base.d.ts +45 -13
  298. package/dist/internal/runtime/lifecycle/goal-marker.d.ts +8 -8
  299. package/dist/internal/security/index.cjs +13 -13
  300. package/dist/internal/security/index.js +3 -3
  301. package/dist/internal/session/agent-session-store.d.ts +1 -0
  302. package/dist/internal/session/agent-session.d.ts +14 -14
  303. package/dist/internal/session/session-cache.d.ts +9 -9
  304. package/dist/internal/session/session-types.d.ts +6 -1
  305. package/dist/judge-call-NA2G6ZMJ.js +5 -0
  306. package/dist/{judge-call-TAEIXMYG.js.map → judge-call-NA2G6ZMJ.js.map} +1 -1
  307. package/dist/judge-call-U2D33JOW.cjs +22 -0
  308. package/dist/{judge-call-SP3G3X2Y.cjs.map → judge-call-U2D33JOW.cjs.map} +1 -1
  309. package/dist/models.cjs +20 -20
  310. package/dist/models.cjs.map +1 -1
  311. package/dist/models.js +5 -5
  312. package/dist/models.js.map +1 -1
  313. package/dist/path-safety.cjs +10 -10
  314. package/dist/path-safety.js +3 -3
  315. package/dist/persistence.cjs +43 -43
  316. package/dist/persistence.cjs.map +1 -1
  317. package/dist/persistence.d.cts +1 -1
  318. package/dist/persistence.d.ts +1 -1
  319. package/dist/persistence.js +14 -14
  320. package/dist/persistence.js.map +1 -1
  321. package/dist/project.cjs +5 -5
  322. package/dist/project.js +3 -3
  323. package/dist/registry-CAS6Y5ZY.js +9 -0
  324. package/dist/{registry-SOXE4RY6.js.map → registry-CAS6Y5ZY.js.map} +1 -1
  325. package/dist/registry-JSDI4WKA.cjs +46 -0
  326. package/dist/{registry-N3GTKYCI.cjs.map → registry-JSDI4WKA.cjs.map} +1 -1
  327. package/dist/retry.cjs +4 -4
  328. package/dist/retry.js +3 -3
  329. package/dist/{run-CwEJtLPE.d.ts → run-i2-fUohR.d.cts} +217 -174
  330. package/dist/{run-CwEJtLPE.d.cts → run-i2-fUohR.d.ts} +217 -174
  331. package/dist/{run-until-YZ2ODWOF.js → run-until-BK56WG4P.js} +3 -3
  332. package/dist/{run-until-YZ2ODWOF.js.map → run-until-BK56WG4P.js.map} +1 -1
  333. package/dist/{run-until-ZZ2JLPJM.cjs → run-until-L5KQD3PV.cjs} +4 -4
  334. package/dist/{run-until-ZZ2JLPJM.cjs.map → run-until-L5KQD3PV.cjs.map} +1 -1
  335. package/dist/sandbox/bwrap.d.cts +20 -20
  336. package/dist/sandbox/bwrap.d.ts +20 -20
  337. package/dist/sandbox/index.cjs +39 -39
  338. package/dist/sandbox/index.cjs.map +1 -1
  339. package/dist/sandbox/index.d.cts +1 -1
  340. package/dist/sandbox/index.d.ts +1 -1
  341. package/dist/sandbox/index.js +35 -35
  342. package/dist/sandbox/index.js.map +1 -1
  343. package/dist/sandbox/linux-sandbox.d.cts +26 -21
  344. package/dist/sandbox/linux-sandbox.d.ts +26 -21
  345. package/dist/server/auth/index.cjs.map +1 -1
  346. package/dist/server/auth/index.d.cts +6 -6
  347. package/dist/server/auth/index.d.ts +6 -6
  348. package/dist/server/auth/index.js.map +1 -1
  349. package/dist/server/auth/orchestrator.d.cts +2 -2
  350. package/dist/server/auth/orchestrator.d.ts +2 -2
  351. package/dist/server/auth/types.d.cts +4 -4
  352. package/dist/server/auth/types.d.ts +4 -4
  353. package/dist/server/errors-envelope.cjs +14 -14
  354. package/dist/server/errors-envelope.d.cts +3 -3
  355. package/dist/server/errors-envelope.d.ts +3 -3
  356. package/dist/server/errors-envelope.js +3 -3
  357. package/dist/session-transcript-3B52DKTG.js +5 -0
  358. package/dist/{session-transcript-6WKLYIN4.js.map → session-transcript-3B52DKTG.js.map} +1 -1
  359. package/dist/session-transcript-H7NUFXXM.cjs +50 -0
  360. package/dist/{session-transcript-EAKR4D2W.cjs.map → session-transcript-H7NUFXXM.cjs.map} +1 -1
  361. package/dist/skills.cjs +7 -7
  362. package/dist/skills.js +5 -5
  363. package/dist/stream-object-4FDU76YW.cjs +20 -0
  364. package/dist/{stream-object-Y7YCX3BI.cjs.map → stream-object-4FDU76YW.cjs.map} +1 -1
  365. package/dist/stream-object-HWDEEQN4.js +7 -0
  366. package/dist/{stream-object-OFM66VUT.js.map → stream-object-HWDEEQN4.js.map} +1 -1
  367. package/dist/subagents-loader-A4W6C3QP.cjs +15 -0
  368. package/dist/subagents-loader-A4W6C3QP.cjs.map +1 -0
  369. package/dist/subagents-loader-X33KH2SZ.js +6 -0
  370. package/dist/subagents-loader-X33KH2SZ.js.map +1 -0
  371. package/dist/subagents-loader.cjs +6 -6
  372. package/dist/subagents-loader.d.cts +2 -2
  373. package/dist/subagents-loader.d.ts +2 -2
  374. package/dist/subagents-loader.js +4 -4
  375. package/dist/subscription/index.cjs +3 -3
  376. package/dist/subscription/index.js +2 -2
  377. package/dist/task-store.cjs +7 -7
  378. package/dist/task-store.js +4 -4
  379. package/dist/types/agent-prims.d.ts +4 -4
  380. package/dist/types/agent.d.ts +68 -3
  381. package/dist/types/conversation.d.ts +7 -0
  382. package/dist/types/goal-events.d.ts +24 -23
  383. package/dist/types/messages.d.ts +9 -0
  384. package/dist/types/run.d.ts +27 -0
  385. package/dist/types/session-message.d.ts +59 -0
  386. package/dist/types/session-record.d.ts +14 -13
  387. package/dist/types/workflow.d.ts +36 -0
  388. package/dist/workflow.cjs +27 -27
  389. package/dist/workflow.d.cts +17 -1
  390. package/dist/workflow.d.ts +17 -1
  391. package/dist/workflow.js +6 -6
  392. package/docs/harness-capability-map.md +22 -0
  393. package/package.json +22 -13
  394. package/dist/agent-DW2J37IH.js +0 -42
  395. package/dist/agent-IE6IE4NW.cjs +0 -51
  396. package/dist/batch-3SEPDXCU.cjs.map +0 -1
  397. package/dist/batch-SY5GZLFD.js.map +0 -1
  398. package/dist/chunk-2423XDPT.cjs.map +0 -1
  399. package/dist/chunk-2ONFGMBV.js.map +0 -1
  400. package/dist/chunk-4YB7B3RP.cjs.map +0 -1
  401. package/dist/chunk-56OXYUZE.js.map +0 -1
  402. package/dist/chunk-56ZM6P7Z.cjs.map +0 -1
  403. package/dist/chunk-5SB4V74H.js +0 -176
  404. package/dist/chunk-5SB4V74H.js.map +0 -1
  405. package/dist/chunk-6VP3XGEK.js.map +0 -1
  406. package/dist/chunk-77WHPVXE.js.map +0 -1
  407. package/dist/chunk-ALU3KC4G.cjs.map +0 -1
  408. package/dist/chunk-BJMKQOY2.cjs.map +0 -1
  409. package/dist/chunk-DCJ5MCJ3.js.map +0 -1
  410. package/dist/chunk-EEZ7CFMM.js.map +0 -1
  411. package/dist/chunk-FV3YEMQ7.js.map +0 -1
  412. package/dist/chunk-G2F67XUR.cjs.map +0 -1
  413. package/dist/chunk-GL7CFBVC.js.map +0 -1
  414. package/dist/chunk-H5YVJB4K.cjs +0 -185
  415. package/dist/chunk-H5YVJB4K.cjs.map +0 -1
  416. package/dist/chunk-ICYBIC6N.cjs.map +0 -1
  417. package/dist/chunk-IEUDKUPM.cjs.map +0 -1
  418. package/dist/chunk-IT3PWBW4.cjs.map +0 -1
  419. package/dist/chunk-ITLS5LRF.cjs +0 -105
  420. package/dist/chunk-ITLS5LRF.cjs.map +0 -1
  421. package/dist/chunk-LTCOPATU.cjs.map +0 -1
  422. package/dist/chunk-MXSMAGDU.js.map +0 -1
  423. package/dist/chunk-P34DHHYQ.cjs.map +0 -1
  424. package/dist/chunk-SDIBMLL5.js.map +0 -1
  425. package/dist/chunk-TAPQWDW2.js.map +0 -1
  426. package/dist/chunk-THEYGCYS.cjs.map +0 -1
  427. package/dist/chunk-VNNK6AKU.js.map +0 -1
  428. package/dist/chunk-VYJSHGAY.js.map +0 -1
  429. package/dist/chunk-W52DKZBR.cjs.map +0 -1
  430. package/dist/chunk-XAEAMI5H.js.map +0 -1
  431. package/dist/chunk-XAYVHS2B.cjs.map +0 -1
  432. package/dist/chunk-YDLNI7J6.js.map +0 -1
  433. package/dist/chunk-YPQF26X7.cjs.map +0 -1
  434. package/dist/chunk-YVTNFKZO.js +0 -103
  435. package/dist/chunk-YVTNFKZO.js.map +0 -1
  436. package/dist/compact-session-H5TKLD55.cjs +0 -54
  437. package/dist/compact-session-WNKKIIDW.js +0 -17
  438. package/dist/context-VAYLPT4O.js +0 -5
  439. package/dist/context-ZV33V4DC.cjs +0 -22
  440. package/dist/executor-OZSYXDKF.cjs.map +0 -1
  441. package/dist/executor-PAH72CB5.js.map +0 -1
  442. package/dist/fs-session-store-6MY7PNI2.js +0 -10
  443. package/dist/fs-session-store-7E7UPLF2.cjs +0 -19
  444. package/dist/generate-object-5SCEH2EE.cjs +0 -20
  445. package/dist/generate-object-I7UD4NWN.js +0 -7
  446. package/dist/index-manager-KKAK7NT3.js +0 -10
  447. package/dist/index-manager-R6ZJFEZF.cjs +0 -19
  448. package/dist/inject-session-DM4SKTZO.cjs.map +0 -1
  449. package/dist/inject-session-UXNJQTZ6.js.map +0 -1
  450. package/dist/judge-call-SP3G3X2Y.cjs +0 -22
  451. package/dist/judge-call-TAEIXMYG.js +0 -5
  452. package/dist/registry-N3GTKYCI.cjs +0 -46
  453. package/dist/registry-SOXE4RY6.js +0 -9
  454. package/dist/session-transcript-6WKLYIN4.js +0 -5
  455. package/dist/session-transcript-EAKR4D2W.cjs +0 -50
  456. package/dist/stream-object-OFM66VUT.js +0 -7
  457. package/dist/stream-object-Y7YCX3BI.cjs +0 -20
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/generate-object.ts"],"names":[],"mappings":"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","file":"chunk-M5ZQBOIZ.js","sourcesContent":["import type { z as ZodNamespace, ZodType } from \"zod\";\n\nimport {\n buildToolPrompt,\n buildTransientAgentOptions,\n disposeAndDeleteTransient,\n extractUsage,\n makeOutputTool,\n setupStructuredOutput,\n} from \"./internal/structured-output-helpers.js\";\nimport type { AgentOptions, LocalOptions, ModelSelection, SDKAgent } from \"./types/agent.js\";\nimport type { ProviderRoutingSettings } from \"./types/providers.js\";\n\n/**\n * Options accepted by {@link Agent.generateObject}. Returns a typed object\n * matching the supplied Zod schema. See ADR D33.\n *\n * @public\n */\nexport interface GenerateObjectOptions<T extends ZodType> {\n /** Zod schema describing the expected object shape. */\n schema: T;\n /** User prompt — the model is asked to fill the schema given this prompt. */\n prompt: string;\n /** Optional system prompt steering the model. */\n systemPrompt?: string;\n /** Model selection. Required (transient agents need a model). SE8 — accepts a\n * bare-string id shorthand (`\"openai/gpt-4o-mini\"`) or a {@link ModelSelection}. */\n model: string | ModelSelection;\n /**\n * M21 — optional separate model for the STRUCTURING step. When set, `model` first produces a\n * free-text reasoned answer to the prompt (phase 1), then `structuringModel` extracts the\n * schema-matched object by calling the `output` tool over that answer (phase 2). Lets a large\n * model reason while a cheap fast model does the extraction. Absent ⇒ today's single-model flow.\n */\n structuringModel?: string | ModelSelection;\n /** API key. Falls back to env (THEOKIT_API_KEY etc). */\n apiKey?: string;\n /** Local runtime config (cwd, sandbox). Required to keep the transient agent local-only. */\n local: LocalOptions;\n /**\n * Retry budget on parse failures. Default 1 (initial attempt + 1 retry).\n * The transient agent is REUSED across retries so the registry sees a\n * single entry (EC-3).\n */\n maxRetries?: number;\n /**\n * Optional provider routing forwarded to the transient agent. Required when\n * `model.id` uses a prefix (e.g. `openai/gpt-4o-mini`) but the credential is\n * for a unified gateway (e.g. OpenRouter). Without this, the SDK infers\n * provider from the prefix and may fail with `provider_unresolved` even\n * when the right env key is set under a different provider name.\n */\n providers?: ProviderRoutingSettings;\n /**\n * What to do when the model's output fails schema validation after all\n * retries are exhausted (M14):\n * - `'throw'` (default) — throw {@link GenerateObjectError} `parse_failed`.\n * - `'return-raw'` — resolve with the raw, UNVALIDATED input the model sent\n * (`object` may not match the schema; inspect `raw` too).\n * - `'return-partial'` — for object schemas, resolve with only the fields that\n * individually validate (best-effort salvage); non-object schemas fall back\n * to raw.\n */\n errorStrategy?: \"throw\" | \"return-partial\" | \"return-raw\";\n}\n\n/**\n * Successful return from {@link Agent.generateObject}.\n *\n * @public\n */\nexport interface GenerateObjectResult<T> {\n /** Typed object parsed via the Zod schema. */\n object: T;\n /** Raw input the model passed to the synthetic tool, before Zod parse. */\n raw: unknown;\n /** Token usage of the LLM call(s) that produced the result. */\n usage: { inputTokens: number; outputTokens: number };\n /** Stop reason of the underlying agent run. */\n finishReason: \"tool_use\" | \"error\";\n}\n\n/**\n * Typed error thrown by {@link Agent.generateObject} when the model refuses\n * to call the synthetic `output` tool or when retries are exhausted.\n *\n * @public\n */\nexport class GenerateObjectError extends Error {\n override readonly name = \"GenerateObjectError\";\n readonly code: \"no_tool_call\" | \"parse_failed\";\n override readonly cause?: unknown;\n constructor(code: \"no_tool_call\" | \"parse_failed\", message: string, cause?: unknown) {\n super(message);\n this.code = code;\n if (cause !== undefined) this.cause = cause;\n }\n}\n\ninterface GenerateObjectDeps {\n create: (options: AgentOptions) => Promise<SDKAgent>;\n /** Hard-delete the transient agent from the registry after dispose. */\n delete: (agentId: string) => Promise<void>;\n}\n\n/**\n * M14 — best-effort partial salvage for `errorStrategy: 'return-partial'`. For an object schema,\n * keep only the fields that individually validate; anything else (non-object schema or non-object\n * raw) falls back to the raw value. Works across Zod v3/v4 via the `.shape` record both expose.\n */\nfunction salvagePartial<T extends ZodType>(schema: T, raw: unknown): unknown {\n if (typeof raw !== \"object\" || raw === null) return raw;\n const shape = (schema as { shape?: Record<string, ZodType> }).shape;\n if (shape === undefined || typeof shape !== \"object\") return raw;\n const rawObj = raw as Record<string, unknown>;\n const out: Record<string, unknown> = {};\n for (const [key, fieldSchema] of Object.entries(shape)) {\n if (typeof fieldSchema?.safeParse !== \"function\") continue;\n const parsed = fieldSchema.safeParse(rawObj[key]);\n if (parsed.success) out[key] = parsed.data;\n }\n return out;\n}\n\n/**\n * Implementation of `Agent.generateObject`. Receives the `Agent.create`\n * factory as a callback to keep the dependency graph acyclic (mirrors the\n * AgentBuilder pattern in D25 / agent.ts injection).\n *\n * Algorithm:\n * 1. Convert the consumer's Zod schema to JSON Schema.\n * 2. Build a single synthetic `output` CustomTool whose handler captures\n * the raw input and short-circuits the agent loop. The handler\n * THROWS a sentinel so the loop terminates immediately without a\n * second LLM round-trip.\n * 3. Create ONE transient agent (per the entire generateObject call,\n * not per retry — EC-3). Each retry re-sends through the same agent,\n * driving fresh LLM rounds.\n * 4. On each attempt, send a wrapper prompt instructing the model to\n * call the `output` tool. Capture the raw input via the sentinel.\n * 5. Parse the raw input via schema.parse. On success, return typed.\n * On failure, retry until the budget is exhausted.\n * 6. Always dispose the transient agent in `finally`.\n *\n * @internal\n */\n/**\n * M21 — phase 1: run `options.model` as a plain reasoning agent (no output tool) and return its\n * free-text answer, which phase 2's structuring model then extracts. The transient reasoning agent\n * is disposed + hard-deleted so the registry count stays stable (EC-3, mirrors the phase-2 finally).\n */\nasync function runReasoningPhase<T extends ZodType>(\n options: GenerateObjectOptions<T>,\n deps: GenerateObjectDeps,\n): Promise<string> {\n const reasoningOptions: AgentOptions = {\n model: options.model,\n local: options.local,\n ...(options.systemPrompt !== undefined ? { systemPrompt: options.systemPrompt } : {}),\n ...(options.apiKey !== undefined ? { apiKey: options.apiKey } : {}),\n ...(options.providers !== undefined ? { providers: options.providers } : {}),\n };\n const reasoningAgent = await deps.create(reasoningOptions);\n try {\n const run = await reasoningAgent.send(options.prompt);\n const result = await run.wait();\n const text = (result as { result?: unknown }).result;\n return typeof text === \"string\" ? text : options.prompt;\n } finally {\n await disposeAndDeleteTransient(reasoningAgent, deps.delete);\n }\n}\n\n// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: retry loop + capture sentinel + dispose-and-delete is a single transaction; splitting harms locality and the finally block.\nexport async function generateObjectImpl<T extends ZodType>(\n options: GenerateObjectOptions<T>,\n deps: GenerateObjectDeps,\n): Promise<GenerateObjectResult<ZodNamespace.infer<T>>> {\n const { jsonSchema, maxRetries, initialUsage } = setupStructuredOutput(\n options.schema,\n options.maxRetries,\n );\n let capturedRaw: unknown;\n let lastUsage = initialUsage;\n const sentinel = Symbol(\"generate-object-sentinel\");\n class CaptureSentinel extends Error {\n readonly [sentinel] = true;\n constructor(public readonly captured: unknown) {\n super(\"generate-object-capture\");\n }\n }\n\n const outputTool = makeOutputTool(jsonSchema, (input) => {\n // EC-D10 (parallel tool use): first capture wins. Subsequent calls\n // in the same response are ignored.\n if (capturedRaw === undefined) {\n capturedRaw = input;\n }\n throw new CaptureSentinel(input);\n });\n\n // M21 — when a separate structuring model is set, `model` first reasons in free text (phase 1),\n // and `structuringModel` extracts the object over that text (phase 2). Absent ⇒ single-model flow.\n const reasoningText =\n options.structuringModel !== undefined ? await runReasoningPhase(options, deps) : undefined;\n const structuringModel = options.structuringModel ?? options.model;\n const structuringPrompt = reasoningText ?? options.prompt;\n\n const agentOptions: AgentOptions = buildTransientAgentOptions({\n model: structuringModel,\n local: options.local,\n outputTool,\n ...(options.systemPrompt !== undefined ? { systemPrompt: options.systemPrompt } : {}),\n ...(options.apiKey !== undefined ? { apiKey: options.apiKey } : {}),\n ...(options.providers !== undefined ? { providers: options.providers } : {}),\n });\n const agent = await deps.create(agentOptions);\n\n try {\n const userMessage = buildToolPrompt(structuringPrompt);\n let lastParseError: unknown;\n\n for (let attempt = 0; attempt <= maxRetries; attempt += 1) {\n capturedRaw = undefined;\n const run = await agent.send(userMessage);\n const result = await run.wait();\n lastUsage = extractUsage(result);\n\n if (capturedRaw === undefined) {\n // EC: when the underlying run errored (e.g. provider_unresolved),\n // surface the original cause instead of the misleading \"model\n // returned text\" message — there was no model call at all.\n if (result.status === \"error\" && result.error !== undefined) {\n throw new GenerateObjectError(\n \"no_tool_call\",\n `Agent run failed before the model could reply: ${result.error.message ?? \"unknown error\"} [${result.error.code ?? \"?\"}]`,\n result.error,\n );\n }\n // Model didn't call the output tool.\n if (attempt === maxRetries) {\n throw new GenerateObjectError(\n \"no_tool_call\",\n \"The model returned text instead of calling the `output` tool.\",\n );\n }\n continue;\n }\n\n const parsed = options.schema.safeParse(capturedRaw);\n if (parsed.success) {\n return {\n object: parsed.data,\n raw: capturedRaw,\n usage: lastUsage,\n finishReason: \"tool_use\",\n };\n }\n lastParseError = parsed.error;\n }\n\n // M14 — all retries exhausted with a parse failure. `errorStrategy` decides the outcome; the\n // tool WAS called (capturedRaw is set), so `finishReason` stays `tool_use`.\n if (options.errorStrategy === \"return-raw\") {\n return {\n object: capturedRaw as ZodNamespace.infer<T>,\n raw: capturedRaw,\n usage: lastUsage,\n finishReason: \"tool_use\",\n };\n }\n if (options.errorStrategy === \"return-partial\") {\n return {\n object: salvagePartial(options.schema, capturedRaw) as ZodNamespace.infer<T>,\n raw: capturedRaw,\n usage: lastUsage,\n finishReason: \"tool_use\",\n };\n }\n throw new GenerateObjectError(\n \"parse_failed\",\n \"Schema parse failed after all retries.\",\n lastParseError,\n );\n } finally {\n // EC-3: dispose AND hard-delete the transient agent so registry count\n // stays stable across retries.\n await disposeAndDeleteTransient(agent, deps.delete);\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/generate-object.ts"],"names":[],"mappings":"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","file":"chunk-KE6XKRLQ.js","sourcesContent":["import type { z as ZodNamespace, ZodType } from \"zod\";\n\nimport {\n buildToolPrompt,\n buildTransientAgentOptions,\n disposeAndDeleteTransient,\n extractUsage,\n makeOutputTool,\n setupStructuredOutput,\n} from \"./internal/structured-output-helpers.js\";\nimport type { AgentOptions, LocalOptions, ModelSelection, SDKAgent } from \"./types/agent.js\";\nimport type { ProviderRoutingSettings } from \"./types/providers.js\";\n\n/**\n * Options accepted by {@link Agent.generateObject}. Returns a typed object\n * matching the supplied Zod schema. See ADR D33.\n *\n * @public\n */\nexport interface GenerateObjectOptions<T extends ZodType> {\n /** Zod schema describing the expected object shape. */\n schema: T;\n /** User prompt — the model is asked to fill the schema given this prompt. */\n prompt: string;\n /** Optional system prompt steering the model. */\n systemPrompt?: string;\n /** Model selection. Required (transient agents need a model). SE8 — accepts a\n * bare-string id shorthand (`\"openai/gpt-4o-mini\"`) or a {@link ModelSelection}. */\n model: string | ModelSelection;\n /**\n * M21 — optional separate model for the STRUCTURING step. When set, `model` first produces a\n * free-text reasoned answer to the prompt (phase 1), then `structuringModel` extracts the\n * schema-matched object by calling the `output` tool over that answer (phase 2). Lets a large\n * model reason while a cheap fast model does the extraction. Absent ⇒ today's single-model flow.\n */\n structuringModel?: string | ModelSelection;\n /** API key. Falls back to env (THEOKIT_API_KEY etc). */\n apiKey?: string;\n /** Local runtime config (cwd, sandbox). Required to keep the transient agent local-only. */\n local: LocalOptions;\n /**\n * Retry budget on parse failures. Default 1 (initial attempt + 1 retry).\n * The transient agent is REUSED across retries so the registry sees a\n * single entry (EC-3).\n */\n maxRetries?: number;\n /**\n * Optional provider routing forwarded to the transient agent. Required when\n * `model.id` uses a prefix (e.g. `openai/gpt-4o-mini`) but the credential is\n * for a unified gateway (e.g. OpenRouter). Without this, the SDK infers\n * provider from the prefix and may fail with `provider_unresolved` even\n * when the right env key is set under a different provider name.\n */\n providers?: ProviderRoutingSettings;\n /**\n * What to do when the model's output fails schema validation after all\n * retries are exhausted (M14):\n * - `'throw'` (default) — throw {@link GenerateObjectError} `parse_failed`.\n * - `'return-raw'` — resolve with the raw, UNVALIDATED input the model sent\n * (`object` may not match the schema; inspect `raw` too).\n * - `'return-partial'` — for object schemas, resolve with only the fields that\n * individually validate (best-effort salvage); non-object schemas fall back\n * to raw.\n */\n errorStrategy?: \"throw\" | \"return-partial\" | \"return-raw\";\n}\n\n/**\n * Successful return from {@link Agent.generateObject}.\n *\n * @public\n */\nexport interface GenerateObjectResult<T> {\n /** Typed object parsed via the Zod schema. */\n object: T;\n /** Raw input the model passed to the synthetic tool, before Zod parse. */\n raw: unknown;\n /** Token usage of the LLM call(s) that produced the result. */\n usage: { inputTokens: number; outputTokens: number };\n /** Stop reason of the underlying agent run. */\n finishReason: \"tool_use\" | \"error\";\n}\n\n/**\n * Typed error thrown by {@link Agent.generateObject} when the model refuses\n * to call the synthetic `output` tool or when retries are exhausted.\n *\n * @public\n */\nexport class GenerateObjectError extends Error {\n override readonly name = \"GenerateObjectError\";\n readonly code: \"no_tool_call\" | \"parse_failed\";\n override readonly cause?: unknown;\n constructor(code: \"no_tool_call\" | \"parse_failed\", message: string, cause?: unknown) {\n super(message);\n this.code = code;\n if (cause !== undefined) this.cause = cause;\n }\n}\n\ninterface GenerateObjectDeps {\n create: (options: AgentOptions) => Promise<SDKAgent>;\n /** Hard-delete the transient agent from the registry after dispose. */\n delete: (agentId: string) => Promise<void>;\n}\n\n/**\n * M14 — best-effort partial salvage for `errorStrategy: 'return-partial'`. For an object schema,\n * keep only the fields that individually validate; anything else (non-object schema or non-object\n * raw) falls back to the raw value. Works across Zod v3/v4 via the `.shape` record both expose.\n */\nfunction salvagePartial<T extends ZodType>(schema: T, raw: unknown): unknown {\n if (typeof raw !== \"object\" || raw === null) return raw;\n const shape = (schema as { shape?: Record<string, ZodType> }).shape;\n if (shape === undefined || typeof shape !== \"object\") return raw;\n const rawObj = raw as Record<string, unknown>;\n const out: Record<string, unknown> = {};\n for (const [key, fieldSchema] of Object.entries(shape)) {\n if (typeof fieldSchema?.safeParse !== \"function\") continue;\n const parsed = fieldSchema.safeParse(rawObj[key]);\n if (parsed.success) out[key] = parsed.data;\n }\n return out;\n}\n\n/**\n * Implementation of `Agent.generateObject`. Receives the `Agent.create`\n * factory as a callback to keep the dependency graph acyclic (mirrors the\n * AgentBuilder pattern in D25 / agent.ts injection).\n *\n * Algorithm:\n * 1. Convert the consumer's Zod schema to JSON Schema.\n * 2. Build a single synthetic `output` CustomTool whose handler captures\n * the raw input and short-circuits the agent loop. The handler\n * THROWS a sentinel so the loop terminates immediately without a\n * second LLM round-trip.\n * 3. Create ONE transient agent (per the entire generateObject call,\n * not per retry — EC-3). Each retry re-sends through the same agent,\n * driving fresh LLM rounds.\n * 4. On each attempt, send a wrapper prompt instructing the model to\n * call the `output` tool. Capture the raw input via the sentinel.\n * 5. Parse the raw input via schema.parse. On success, return typed.\n * On failure, retry until the budget is exhausted.\n * 6. Always dispose the transient agent in `finally`.\n *\n * @internal\n */\n/**\n * M21 — phase 1: run `options.model` as a plain reasoning agent (no output tool) and return its\n * free-text answer, which phase 2's structuring model then extracts. The transient reasoning agent\n * is disposed + hard-deleted so the registry count stays stable (EC-3, mirrors the phase-2 finally).\n */\nasync function runReasoningPhase<T extends ZodType>(\n options: GenerateObjectOptions<T>,\n deps: GenerateObjectDeps,\n): Promise<string> {\n const reasoningOptions: AgentOptions = {\n model: options.model,\n local: options.local,\n ...(options.systemPrompt !== undefined ? { systemPrompt: options.systemPrompt } : {}),\n ...(options.apiKey !== undefined ? { apiKey: options.apiKey } : {}),\n ...(options.providers !== undefined ? { providers: options.providers } : {}),\n };\n const reasoningAgent = await deps.create(reasoningOptions);\n try {\n const run = await reasoningAgent.send(options.prompt);\n const result = await run.wait();\n const text = (result as { result?: unknown }).result;\n return typeof text === \"string\" ? text : options.prompt;\n } finally {\n await disposeAndDeleteTransient(reasoningAgent, deps.delete);\n }\n}\n\n// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: retry loop + capture sentinel + dispose-and-delete is a single transaction; splitting harms locality and the finally block.\nexport async function generateObjectImpl<T extends ZodType>(\n options: GenerateObjectOptions<T>,\n deps: GenerateObjectDeps,\n): Promise<GenerateObjectResult<ZodNamespace.infer<T>>> {\n const { jsonSchema, maxRetries, initialUsage } = setupStructuredOutput(\n options.schema,\n options.maxRetries,\n );\n let capturedRaw: unknown;\n let lastUsage = initialUsage;\n const sentinel = Symbol(\"generate-object-sentinel\");\n class CaptureSentinel extends Error {\n readonly [sentinel] = true;\n constructor(public readonly captured: unknown) {\n super(\"generate-object-capture\");\n }\n }\n\n const outputTool = makeOutputTool(jsonSchema, (input) => {\n // EC-D10 (parallel tool use): first capture wins. Subsequent calls\n // in the same response are ignored.\n if (capturedRaw === undefined) {\n capturedRaw = input;\n }\n throw new CaptureSentinel(input);\n });\n\n // M21 — when a separate structuring model is set, `model` first reasons in free text (phase 1),\n // and `structuringModel` extracts the object over that text (phase 2). Absent ⇒ single-model flow.\n const reasoningText =\n options.structuringModel !== undefined ? await runReasoningPhase(options, deps) : undefined;\n const structuringModel = options.structuringModel ?? options.model;\n const structuringPrompt = reasoningText ?? options.prompt;\n\n const agentOptions: AgentOptions = buildTransientAgentOptions({\n model: structuringModel,\n local: options.local,\n outputTool,\n ...(options.systemPrompt !== undefined ? { systemPrompt: options.systemPrompt } : {}),\n ...(options.apiKey !== undefined ? { apiKey: options.apiKey } : {}),\n ...(options.providers !== undefined ? { providers: options.providers } : {}),\n });\n const agent = await deps.create(agentOptions);\n\n try {\n const userMessage = buildToolPrompt(structuringPrompt);\n let lastParseError: unknown;\n\n for (let attempt = 0; attempt <= maxRetries; attempt += 1) {\n capturedRaw = undefined;\n const run = await agent.send(userMessage);\n const result = await run.wait();\n lastUsage = extractUsage(result);\n\n if (capturedRaw === undefined) {\n // EC: when the underlying run errored (e.g. provider_unresolved),\n // surface the original cause instead of the misleading \"model\n // returned text\" message — there was no model call at all.\n if (result.status === \"error\" && result.error !== undefined) {\n throw new GenerateObjectError(\n \"no_tool_call\",\n `Agent run failed before the model could reply: ${result.error.message ?? \"unknown error\"} [${result.error.code ?? \"?\"}]`,\n result.error,\n );\n }\n // Model didn't call the output tool.\n if (attempt === maxRetries) {\n throw new GenerateObjectError(\n \"no_tool_call\",\n \"The model returned text instead of calling the `output` tool.\",\n );\n }\n continue;\n }\n\n const parsed = options.schema.safeParse(capturedRaw);\n if (parsed.success) {\n return {\n object: parsed.data,\n raw: capturedRaw,\n usage: lastUsage,\n finishReason: \"tool_use\",\n };\n }\n lastParseError = parsed.error;\n }\n\n // M14 — all retries exhausted with a parse failure. `errorStrategy` decides the outcome; the\n // tool WAS called (capturedRaw is set), so `finishReason` stays `tool_use`.\n if (options.errorStrategy === \"return-raw\") {\n return {\n object: capturedRaw as ZodNamespace.infer<T>,\n raw: capturedRaw,\n usage: lastUsage,\n finishReason: \"tool_use\",\n };\n }\n if (options.errorStrategy === \"return-partial\") {\n return {\n object: salvagePartial(options.schema, capturedRaw) as ZodNamespace.infer<T>,\n raw: capturedRaw,\n usage: lastUsage,\n finishReason: \"tool_use\",\n };\n }\n throw new GenerateObjectError(\n \"parse_failed\",\n \"Schema parse failed after all retries.\",\n lastParseError,\n );\n } finally {\n // EC-3: dispose AND hard-delete the transient agent so registry count\n // stays stable across retries.\n await disposeAndDeleteTransient(agent, deps.delete);\n }\n}\n"]}
@@ -0,0 +1,110 @@
1
+ import { acquireSessionWriter } from './chunk-ET6PHZRX.js';
2
+ import { readTranscript, transcriptPath } from './chunk-JRLXEYR4.js';
3
+ import { withFileLock, appendJsonl } from './chunk-BQDUEG4C.js';
4
+ import { mkdir } from 'fs/promises';
5
+ import { dirname } from 'path';
6
+
7
+ var sharedLeases = /* @__PURE__ */ new Map();
8
+ async function acquireShared(path) {
9
+ const existing = sharedLeases.get(path);
10
+ if (existing !== void 0) {
11
+ existing.refs++;
12
+ return createProxy(path);
13
+ }
14
+ const lease = await acquireSessionWriter(path);
15
+ sharedLeases.set(path, { lease, refs: 1 });
16
+ return createProxy(path);
17
+ }
18
+ function createProxy(path) {
19
+ let released = false;
20
+ return {
21
+ sessionPath: path,
22
+ // The proxy forwards the renewal to the ONE real lease this path shares. Renewing through any
23
+ // holder is correct and is the point: the record must say "someone in this process is still
24
+ // writing", and the refcount already guarantees they are all the same owner.
25
+ renew: () => {
26
+ if (released) return;
27
+ sharedLeases.get(path)?.lease.renew();
28
+ },
29
+ release: async () => {
30
+ if (released) return;
31
+ released = true;
32
+ const entry = sharedLeases.get(path);
33
+ if (entry === void 0) return;
34
+ entry.refs--;
35
+ if (entry.refs > 0) return;
36
+ sharedLeases.delete(path);
37
+ await entry.lease.release();
38
+ }
39
+ };
40
+ }
41
+ var FsSessionStore = class {
42
+ #baseDir;
43
+ #cwd;
44
+ /** One lease per `agentId` — a store serves more than one session over the process lifetime. */
45
+ #leases = /* @__PURE__ */ new Map();
46
+ constructor(options) {
47
+ this.#baseDir = options.baseDir;
48
+ this.#cwd = options.cwd;
49
+ }
50
+ async readRecords(agentId) {
51
+ return readTranscript(transcriptPath(this.#baseDir, this.#cwd, agentId));
52
+ }
53
+ async appendRecords(agentId, records) {
54
+ if (records.length === 0) return;
55
+ const path = transcriptPath(this.#baseDir, this.#cwd, agentId);
56
+ await mkdir(dirname(path), { recursive: true });
57
+ await withFileLock(path, async () => {
58
+ for (const record of records) appendJsonl(path, record);
59
+ });
60
+ }
61
+ /**
62
+ * Takes the session's writer lease. Throws `SessionBusyError` when another process holds it.
63
+ *
64
+ * **Explicit, and NOT inside `appendRecords`** — M95's adversarial review measured why that
65
+ * matters: the `SessionStore` contract states that "an `appendRecords` rejection is logged to
66
+ * stderr, NOT thrown to the caller (best-effort write)". Acquiring there made the
67
+ * `SessionBusyError` get **swallowed**, and the result was worse than the original problem:
68
+ * instead of two writers interleaving lines, the loser **lost the turn silently** — nothing on
69
+ * disk, a stderr warning invisible under the TUI, and no way for the caller to react.
70
+ *
71
+ * At init the error reaches someone who can act: `exec` forks to a new id, which is exactly what
72
+ * the error message itself prescribes. It is the difference between failing where a decision is
73
+ * possible and failing where only loss is.
74
+ */
75
+ async acquire(agentId) {
76
+ if (this.#leases.has(agentId)) return;
77
+ const path = transcriptPath(this.#baseDir, this.#cwd, agentId);
78
+ await mkdir(dirname(path), { recursive: true });
79
+ this.#leases.set(agentId, await acquireShared(path));
80
+ }
81
+ /**
82
+ * Releases ONE agent's lease.
83
+ *
84
+ * It exists because `dispose()` releases **every** lease the store holds, and a store injected by
85
+ * the consumer may serve several agents: an init that fails for agent B must not free agent A's
86
+ * lease, which is still live and writing.
87
+ */
88
+ async release(agentId) {
89
+ const lease = this.#leases.get(agentId);
90
+ if (lease === void 0) return;
91
+ this.#leases.delete(agentId);
92
+ await lease.release();
93
+ }
94
+ /**
95
+ * Releases every lease this store holds.
96
+ *
97
+ * Without it the `.writer.lock` outlives the process and the next open would have to wait out the
98
+ * heartbeat window — recoverable, but 30 s of waiting after a CLEAN shutdown would be an avoidable
99
+ * defect. Idempotent: calling it twice is not an error.
100
+ */
101
+ async dispose() {
102
+ const leases = [...this.#leases.values()];
103
+ this.#leases.clear();
104
+ for (const lease of leases) await lease.release();
105
+ }
106
+ };
107
+
108
+ export { FsSessionStore };
109
+ //# sourceMappingURL=chunk-KGRIHEDT.js.map
110
+ //# sourceMappingURL=chunk-KGRIHEDT.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/internal/persistence/fs-session-store.ts"],"names":[],"mappings":"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","file":"chunk-KGRIHEDT.js","sourcesContent":["/**\n * SE41 — `FsSessionStore`, the DEFAULT reference implementation of the pluggable\n * {@link SessionStore} seam. It reads and append-writes the native Claude-shaped\n * `.jsonl` transcript at `<baseDir>/projects/<encoded-cwd>/<agentId>.jsonl` — the\n * exact on-disk format SE40 introduced (the file the Claude Code CLI can\n * `--continue`). Omitting `local.sessionStore` resolves to this store, so the\n * default persistence path is byte-identical to SE40 behavior.\n *\n * `readRecords` is `readTranscript(transcriptPath(...))` (a missing session →\n * `[]`, not an error — a fresh agent has no history). `appendRecords` is a TRUE\n * append: it reads the prior records, concatenates the new-turn delta, and\n * rewrites the whole line set atomically under the SE40 cross-process file lock\n * (`writeTranscript` never shrinks — the native format is an append-only\n * `parentUuid` DAG). The parent dir is created BEFORE acquiring the lock because\n * the lock's companion `<path>.lock` file needs an existing parent dir (the SE40\n * `mkdir(dirname)`-before-lock fix).\n *\n * @internal\n */\n\nimport { mkdir } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\nimport type { SessionStore } from \"../../types/session-store.js\";\nimport { withFileLock } from \"./file-lock.js\";\nimport { appendJsonl } from \"./jsonl.js\";\nimport { readTranscript, type SessionRecord, transcriptPath } from \"./session-transcript.js\";\nimport { acquireSessionWriter, type SessionWriterLease } from \"./session-writer.js\";\n\n/** Options identifying the on-disk transcript location for the FS default store. */\nexport interface FsSessionStoreOptions {\n /** Transcript base dir (`~/.theokit` default, `~/.claude` for CLI interop) — already `~`-expanded. */\n baseDir: string;\n /** The workspace cwd whose encoded form is the transcript project dir. */\n cwd: string;\n}\n\n/**\n * The default `SessionStore` — reads/append-writes the native `.jsonl` transcript.\n *\n * @internal\n */\n/**\n * Reference-counted leases, shared per path.\n *\n * `acquireSessionWriter` is STRICT on purpose: two concurrent acquisitions of the same path, and\n * exactly one wins — \"a lease that let both through would be decorative\" (the M81 test says exactly\n * that, and it is right). That is the primitive's contract, and it does not change.\n *\n * But within ONE process it is normal to have more than one store over the same session: the golden\n * compaction tests and the concurrent-send tests do exactly that, and they record real runtime\n * behavior. Applying the raw primitive there would turn a legitimate pattern into a\n * `SessionBusyError`.\n *\n * The reconciliation belongs here, in the primitive's consumer: the process takes ONE lease per path\n * and counts how many stores use it. The last to release actually frees it. Cross-process stays\n * strict — which is the problem M81 states (\"`exec resume --last` can write into the TUI's live\n * session\").\n */\nconst sharedLeases = new Map<string, { lease: SessionWriterLease; refs: number }>();\n\nasync function acquireShared(path: string): Promise<SessionWriterLease> {\n const existing = sharedLeases.get(path);\n if (existing !== undefined) {\n existing.refs++;\n return createProxy(path);\n }\n const lease = await acquireSessionWriter(path);\n sharedLeases.set(path, { lease, refs: 1 });\n return createProxy(path);\n}\n\n/** A handle that decrements the count; the last to release frees the real lease. */\nfunction createProxy(path: string): SessionWriterLease {\n let released = false;\n return {\n sessionPath: path,\n // The proxy forwards the renewal to the ONE real lease this path shares. Renewing through any\n // holder is correct and is the point: the record must say \"someone in this process is still\n // writing\", and the refcount already guarantees they are all the same owner.\n renew: (): void => {\n if (released) return;\n sharedLeases.get(path)?.lease.renew();\n },\n release: async (): Promise<void> => {\n if (released) return;\n released = true;\n const entry = sharedLeases.get(path);\n if (entry === undefined) return;\n entry.refs--;\n if (entry.refs > 0) return;\n sharedLeases.delete(path);\n await entry.lease.release();\n },\n };\n}\n\nexport class FsSessionStore implements SessionStore {\n readonly #baseDir: string;\n readonly #cwd: string;\n /** One lease per `agentId` — a store serves more than one session over the process lifetime. */\n readonly #leases = new Map<string, SessionWriterLease>();\n\n constructor(options: FsSessionStoreOptions) {\n this.#baseDir = options.baseDir;\n this.#cwd = options.cwd;\n }\n\n async readRecords(agentId: string): Promise<SessionRecord[]> {\n return readTranscript(transcriptPath(this.#baseDir, this.#cwd, agentId));\n }\n\n async appendRecords(agentId: string, records: readonly SessionRecord[]): Promise<void> {\n // Empty delta → nothing to persist (avoids an unnecessary lock + rewrite).\n if (records.length === 0) return;\n const path = transcriptPath(this.#baseDir, this.#cwd, agentId);\n // mkdir BEFORE the lock: withFileLock's companion `<path>.lock` needs the parent dir.\n await mkdir(dirname(path), { recursive: true });\n\n await withFileLock(path, async () => {\n // M93 — appends the DELTA instead of rewriting the whole file.\n //\n // Before: `readTranscript` + `writeTranscript` of everything, per turn. O(n) of I/O **and** of\n // parsing on every turn, O(n^2) per session — the consumer note in\n // `agents/lib/session/backtrack.ts` records 1.4 MB / 3000 lines over 200 turns.\n //\n // Correct because the format **is already append-only**: the `parentUuid` DAG does not depend\n // on line order, and every record carries its own parent. `appendJsonl` **already existed in\n // the package** and had a single caller (`eval/runner.ts`) — the primitive was there, it was\n // the store that ignored it (rung 4).\n //\n // `withFileLock` stays — but the earlier claim that \"it is what serializes two concurrent\n // `appendRecords`\" was too strong, and M93's adversarial review measured it: removing it fails\n // no test. The reason is the paragraph above — the `parentUuid` DAG does not depend on line\n // order, so two interleaved batches reconstruct identically. The work the lock was doing\n // (protecting a read-modify-write) disappeared along with the rewrite.\n //\n // What it still covers is the TOCTOU window in `needsLineBreakBefore` (read the last byte,\n // then write): without it, two processes can both conclude \"a \\n is missing\" and produce a\n // blank line — which the reader discards, i.e. benign. It stays as a **declared, not\n // mechanized** defense (the discipline in `error-handling.md` § 4: enumerate the residue\n // rather than let a missing test pass for coverage).\n //\n // `writeTranscript` still exists for **compaction**, the one operation that legitimately\n // rewrites the file.\n for (const record of records) appendJsonl(path, record);\n });\n }\n\n /**\n * Takes the session's writer lease. Throws `SessionBusyError` when another process holds it.\n *\n * **Explicit, and NOT inside `appendRecords`** — M95's adversarial review measured why that\n * matters: the `SessionStore` contract states that \"an `appendRecords` rejection is logged to\n * stderr, NOT thrown to the caller (best-effort write)\". Acquiring there made the\n * `SessionBusyError` get **swallowed**, and the result was worse than the original problem:\n * instead of two writers interleaving lines, the loser **lost the turn silently** — nothing on\n * disk, a stderr warning invisible under the TUI, and no way for the caller to react.\n *\n * At init the error reaches someone who can act: `exec` forks to a new id, which is exactly what\n * the error message itself prescribes. It is the difference between failing where a decision is\n * possible and failing where only loss is.\n */\n async acquire(agentId: string): Promise<void> {\n if (this.#leases.has(agentId)) return;\n const path = transcriptPath(this.#baseDir, this.#cwd, agentId);\n await mkdir(dirname(path), { recursive: true });\n this.#leases.set(agentId, await acquireShared(path));\n }\n\n /**\n * Releases ONE agent's lease.\n *\n * It exists because `dispose()` releases **every** lease the store holds, and a store injected by\n * the consumer may serve several agents: an init that fails for agent B must not free agent A's\n * lease, which is still live and writing.\n */\n async release(agentId: string): Promise<void> {\n const lease = this.#leases.get(agentId);\n if (lease === undefined) return;\n this.#leases.delete(agentId);\n await lease.release();\n }\n\n /**\n * Releases every lease this store holds.\n *\n * Without it the `.writer.lock` outlives the process and the next open would have to wait out the\n * heartbeat window — recoverable, but 30 s of waiting after a CLEAN shutdown would be an avoidable\n * defect. Idempotent: calling it twice is not an error.\n */\n async dispose(): Promise<void> {\n const leases = [...this.#leases.values()];\n this.#leases.clear();\n for (const lease of leases) await lease.release();\n }\n}\n"]}
@@ -1,7 +1,7 @@
1
- import { resolveApiKey, generateCronId } from './chunk-VYJSHGAY.js';
2
- import { submit } from './chunk-HEN5WXXI.js';
1
+ import { resolveApiKey, generateCronId } from './chunk-GIRD3RWH.js';
2
+ import { submit } from './chunk-LJX2SQV2.js';
3
3
  import { getAgentFacade } from './chunk-6X6ID4MO.js';
4
- import { UnknownAgentError, ConfigurationError } from './chunk-CD73YHEH.js';
4
+ import { UnknownAgentError, ConfigurationError } from './chunk-SG5ZWT6C.js';
5
5
  import { Cron as Cron$1 } from 'croner';
6
6
 
7
7
  // src/internal/cron/run-job.ts
@@ -454,5 +454,5 @@ async function updateJobStatus(jobId, enabled) {
454
454
  }
455
455
 
456
456
  export { Cron };
457
- //# sourceMappingURL=chunk-T4QWDOG6.js.map
458
- //# sourceMappingURL=chunk-T4QWDOG6.js.map
457
+ //# sourceMappingURL=chunk-KWUNN5J2.js.map
458
+ //# sourceMappingURL=chunk-KWUNN5J2.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/internal/cron/run-job.ts","../src/internal/cron/fire-handler.ts","../src/internal/cron/store.ts","../src/internal/cron/scheduler.ts","../src/internal/cron/validate.ts","../src/cron.ts"],"names":["Croner"],"mappings":"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","file":"chunk-T4QWDOG6.js","sourcesContent":["import { ConfigurationError, UnknownAgentError } from \"../../errors.js\";\nimport type { AgentOptions } from \"../../types/agent.js\";\nimport type { CronJob } from \"../../types/cron.js\";\nimport type { Run, SDKUserMessage } from \"../../types/run.js\";\nimport type { WorkflowRun } from \"../../types/workflow.js\";\nimport { getAgentFacade } from \"../runtime/registry/agent-factory-registry.js\";\n\n/**\n * Execute a cron job. Dispatches to one of three targets:\n * - `workflow` (SE35) → `workflow.run(inputData)` on the held instance (the\n * instance carries its own `.run`, so this module never imports `workflow.ts`),\n * returning the already-terminal {@link WorkflowRun}.\n * - `agent` → an ephemeral agent per fire; `agent.send(message)` → {@link Run}.\n * - `agentId` → reuse an existing agent; `agent.send(message)` → {@link Run}.\n *\n * Used by both `Cron.run(jobId)` (manual off-schedule fire) and the scheduler's\n * default fire handler. ADR 0014.\n *\n * @internal\n */\nexport async function runCronJob(job: CronJob): Promise<Run | WorkflowRun> {\n // `Workflow.run()` resolves only on a TERMINAL run (completed/failed/suspended/\n // cancelled — the executor never returns `status: \"running\"`), so the fire\n // handler treats the returned WorkflowRun as terminal (no `.wait()`).\n if (job.workflow !== undefined) return job.workflow.run(job.inputData);\n if (job.agent !== undefined) return runWithEphemeralAgent(job.agent, requireMessage(job));\n if (job.agentId !== undefined) return runWithExistingAgent(job.agentId, requireMessage(job));\n throw new ConfigurationError(\n `Cron job ${job.id} has no target (agent, agentId, or workflow) — cannot run.`,\n { code: \"cron_no_target\" },\n );\n}\n\n/**\n * Discriminate the {@link runCronJob} union: an agent `Run` is deferred (carries\n * `.wait()`/`.cancel()`); a {@link WorkflowRun} is already terminal (no `.wait()`).\n * @internal\n */\nexport function isAgentRun(outcome: Run | WorkflowRun): outcome is Run {\n return typeof (outcome as Run).wait === \"function\";\n}\n\n/** Agent targets require a message; fail-loud if one somehow reached a fire without it. */\nfunction requireMessage(job: CronJob): string | SDKUserMessage {\n if (job.message === undefined) {\n throw new ConfigurationError(`Cron job ${job.id} is an agent target but has no message.`, {\n code: \"cron_missing_message\",\n });\n }\n return job.message;\n}\n\nasync function runWithExistingAgent(\n agentId: string,\n message: string | SDKUserMessage,\n): Promise<Run> {\n const info = await getAgentFacade()\n .get(agentId)\n .catch(() => undefined);\n if (info === undefined) {\n throw new UnknownAgentError(\n `Cron job references agentId \"${agentId}\" but no such agent is registered. The agent may have been disposed or the process restarted without persisting the agent registry.`,\n { code: \"agent_not_registered\" },\n );\n }\n const agent = await getAgentFacade().resume(agentId);\n return agent.send(message);\n}\n\nasync function runWithEphemeralAgent(\n baseOptions: AgentOptions,\n message: string | SDKUserMessage,\n): Promise<Run> {\n const agent = await getAgentFacade().create(baseOptions);\n return agent.send(message);\n}\n","/**\n * Default cron fire handler (extracted from `Cron.start` for testability + G8).\n *\n * Every fire registers as a Task (ADRs D363/D374) so callers observe it via\n * `Task.list` / `Task.subscribe`. SE35 (ADR 0014): the fire target may be an\n * agent (a deferred {@link Run} — abort-wire + `wait()`) OR a workflow (an\n * already-terminal {@link WorkflowRun} — no `wait()`); `isAgentRun` discriminates\n * so the handler records the correct terminal status/runId for each shape.\n *\n * @internal\n */\n\nimport type { CronJob } from \"../../types/cron.js\";\nimport { submit as taskRegistrySubmit } from \"../task/registry.js\";\nimport { isAgentRun, runCronJob } from \"./run-job.js\";\n\nexport async function fireCronJobAsTask(job: CronJob): Promise<void> {\n // The task id namespace `cron-{jobId}-{fireEpochMs}` honors D368/EC-5.\n const fireTs = Date.now();\n const taskId = `cron-${job.id}-${fireTs}`;\n try {\n await taskRegistrySubmit({\n kind: \"cron\",\n id: taskId,\n allowReservedPrefix: true,\n meta: { jobId: job.id, jobName: job.name, schedule: job.cron, firedAt: fireTs },\n work: async (ctx) => {\n const outcome = await runCronJob(job);\n if (isAgentRun(outcome)) {\n // Agent target — the Run is deferred: abort-wire + await terminal.\n ctx.signal.addEventListener(\"abort\", () => void outcome.cancel().catch(() => {}), {\n once: true,\n });\n const result = await outcome.wait();\n ctx.emit({ status: result.status, runId: outcome.id });\n return { status: result.status, runId: outcome.id };\n }\n // SE35 workflow target — the WorkflowRun is ALREADY terminal (no wait()).\n ctx.emit({ status: outcome.status, runId: outcome.id });\n return { status: outcome.status, runId: outcome.id };\n },\n });\n } catch {\n // Task registry must not break cron — fall through to a direct run. No\n // double-execution: `taskRegistrySubmit` runs `work` (which calls\n // `runCronJob`) fire-and-forget, so a throw here means the SUBMIT itself\n // failed (id/registry setup) BEFORE `work` started — the job never ran, and\n // this is its first + only execution.\n const outcome = await runCronJob(job);\n if (isAgentRun(outcome)) await outcome.wait();\n }\n}\n","import type { CronJob } from \"../../types/cron.js\";\n\n/**\n * Process-wide cron job store. In Phase 1 we keep all jobs in memory\n * (across local + cloud runtimes). Local-runtime persistence to\n * `.theokit/cron/jobs.json` lands when the local runtime adapter is wired.\n *\n * @internal\n */\nconst jobs = new Map<string, CronJob>();\n\n/** Snapshot of every known cron job. @internal */\nexport function listJobs(): CronJob[] {\n return Array.from(jobs.values());\n}\n\n/** Total job count across runtimes. @internal */\nexport function jobCount(): number {\n return jobs.size;\n}\n\n/** Fetch a single job by id, or `undefined` if it does not exist. @internal */\nexport function getJob(jobId: string): CronJob | undefined {\n return jobs.get(jobId);\n}\n\n/** Insert or replace a job. @internal */\nexport function upsertJob(job: CronJob): void {\n jobs.set(job.id, job);\n}\n\n/** Delete a job. Returns `true` if a job was removed. @internal */\nexport function deleteJob(jobId: string): boolean {\n return jobs.delete(jobId);\n}\n\n/** Test-only: drop every job. @internal */\nexport function clearJobs(): void {\n jobs.clear();\n}\n","import { Cron as Croner } from \"croner\";\n\nimport type { CronJob } from \"../../types/cron.js\";\nimport { listJobs, upsertJob } from \"./store.js\";\n\n/**\n * Real local cron scheduler. When `Cron.start()` is called the scheduler\n * installs a Croner timer per enabled local job; on fire the registered\n * fire handler runs the underlying agent. `Cron.stop()` tears every timer\n * down but keeps the jobs in the store.\n *\n * @internal\n */\n\nexport type CronFireHandler = (job: CronJob) => Promise<void> | void;\n\ninterface SchedulerState {\n running: boolean;\n cwd?: string;\n timers: Map<string, Croner>;\n fireHandler?: CronFireHandler;\n}\n\nconst state: SchedulerState = { running: false, timers: new Map() };\n\n/**\n * Register the callback invoked when a job fires. The runtime adapter\n * supplies a handler that actually executes the agent; fixture-mode tests\n * leave it unset so timers tick without side effects.\n *\n * @internal\n */\nexport function setCronFireHandler(handler: CronFireHandler | undefined): void {\n state.fireHandler = handler;\n}\n\n/** Activate the scheduler and install timers for every enabled local job. @internal */\nexport function startScheduler(cwd?: string): void {\n state.running = true;\n if (cwd !== undefined) state.cwd = cwd;\n for (const job of listJobs()) {\n if (job.runtime === \"local\" && job.enabled !== false) scheduleJob(job);\n }\n}\n\n/** Deactivate the scheduler. Stops every timer; jobs remain in the store. @internal */\nexport function stopScheduler(): void {\n state.running = false;\n for (const timer of state.timers.values()) timer.stop();\n state.timers.clear();\n}\n\n/** Schedule a single job. No-op if the scheduler is not running. @internal */\nexport function scheduleJob(job: CronJob): void {\n if (!state.running) return;\n unscheduleJob(job.id);\n const expression = normalizeExpression(job.cron);\n const timer = new Croner(\n expression,\n { timezone: job.timezone, name: job.id, protect: true },\n () => {\n void fireJob(job.id);\n },\n );\n state.timers.set(job.id, timer);\n refreshNextRunAt(job.id, timer);\n}\n\n/** Tear down the timer for a single job. @internal */\nexport function unscheduleJob(jobId: string): boolean {\n const timer = state.timers.get(jobId);\n if (timer === undefined) return false;\n timer.stop();\n state.timers.delete(jobId);\n return true;\n}\n\n/** Snapshot of the scheduler's running flag and configured workspace. @internal */\nexport function getSchedulerState(): { running: boolean; cwd?: string } {\n const result: { running: boolean; cwd?: string } = { running: state.running };\n if (state.cwd !== undefined) result.cwd = state.cwd;\n return result;\n}\n\nasync function fireJob(jobId: string): Promise<void> {\n const fresh = listJobs().find((entry) => entry.id === jobId);\n if (fresh === undefined || fresh.enabled === false) return;\n const handler = state.fireHandler;\n upsertJob({ ...fresh, lastRunAt: Date.now() });\n if (handler === undefined) return;\n try {\n await handler(fresh);\n } catch {\n // Swallow handler errors — the scheduler must keep ticking. Real\n // surface for run failures lives on the Run.wait() result itself.\n }\n}\n\nfunction refreshNextRunAt(jobId: string, timer: Croner): void {\n const next = timer.nextRun();\n if (next === null) return;\n const existing = listJobs().find((entry) => entry.id === jobId);\n if (existing === undefined) return;\n upsertJob({ ...existing, nextRunAt: next.getTime() });\n}\n\nfunction normalizeExpression(cron: string): string {\n switch (cron) {\n case \"@hourly\":\n return \"0 * * * *\";\n case \"@daily\":\n return \"0 0 * * *\";\n case \"@weekly\":\n return \"0 0 * * 0\";\n case \"@monthly\":\n return \"0 0 1 * *\";\n case \"@yearly\":\n return \"0 0 1 1 *\";\n default:\n return cron;\n }\n}\n","import { ConfigurationError } from \"../../errors.js\";\n\n/**\n * POSIX-cron + shorthand validators used by `Cron.create()`. Throws\n * `ConfigurationError` with a stable message and code on invalid input.\n *\n * @internal\n */\n\nconst SHORTHANDS = new Set([\"@hourly\", \"@daily\", \"@weekly\", \"@monthly\", \"@yearly\"]);\n\ninterface FieldRange {\n min: number;\n max: number;\n}\n\nconst FIELD_RANGES: readonly FieldRange[] = [\n { min: 0, max: 59 }, // minute\n { min: 0, max: 23 }, // hour\n { min: 1, max: 31 }, // day-of-month\n { min: 1, max: 12 }, // month\n { min: 0, max: 6 }, // day-of-week\n];\n\n/**\n * Validate a cron expression. Accepts shorthand (`@hourly`, ..., `@yearly`)\n * or 5-field POSIX cron with star, literals, star/N step, N-M range, and\n * N,M,P list.\n *\n * @internal\n */\nexport function validateCronExpression(cron: string): void {\n if (typeof cron !== \"string\" || cron.length === 0) {\n throw new ConfigurationError(\"Invalid cron expression: empty\", {\n code: \"invalid_cron\",\n });\n }\n if (cron.startsWith(\"@\")) {\n if (!SHORTHANDS.has(cron)) {\n throw new ConfigurationError(`Invalid cron expression: unknown shorthand ${cron}`, {\n code: \"invalid_cron\",\n });\n }\n return;\n }\n\n const fields = cron.trim().split(/\\s+/);\n if (fields.length !== 5) {\n throw new ConfigurationError(\n `Invalid cron expression: ${cron} (expected 5 fields, got ${fields.length})`,\n { code: \"invalid_cron\" },\n );\n }\n for (const [index, field] of fields.entries()) {\n validateFieldOrThrow(field, index, cron);\n }\n}\n\nfunction validateFieldOrThrow(field: string, index: number, cron: string): void {\n const range = FIELD_RANGES[index];\n if (range === undefined) {\n throw new ConfigurationError(`Invalid cron expression: ${cron} (field ${index + 1})`, {\n code: \"invalid_cron\",\n });\n }\n if (!isValidCronField(field, range)) {\n throw new ConfigurationError(`Invalid cron expression: ${cron} (field ${index + 1})`, {\n code: \"invalid_cron\",\n });\n }\n}\n\nfunction isValidCronField(field: string, range: FieldRange): boolean {\n if (field === \"*\") return true;\n if (field.startsWith(\"*/\")) return isValidStep(field.slice(2), range);\n if (field.includes(\",\")) {\n return field.split(\",\").every((part) => isValidCronField(part, range));\n }\n if (field.includes(\"-\")) return isValidRange(field, range);\n return isValidLiteral(field, range);\n}\n\nfunction isValidStep(stepStr: string, range: FieldRange): boolean {\n const step = Number.parseInt(stepStr, 10);\n return Number.isInteger(step) && String(step) === stepStr && step > 0 && step <= range.max;\n}\n\nfunction isValidRange(field: string, range: FieldRange): boolean {\n const parts = field.split(\"-\");\n if (parts.length !== 2) return false;\n const [startStr, endStr] = parts;\n if (startStr === undefined || endStr === undefined) return false;\n const start = Number.parseInt(startStr, 10);\n const end = Number.parseInt(endStr, 10);\n if (!Number.isInteger(start) || !Number.isInteger(end)) return false;\n return start >= range.min && end <= range.max && start <= end;\n}\n\nfunction isValidLiteral(field: string, range: FieldRange): boolean {\n const n = Number.parseInt(field, 10);\n return Number.isInteger(n) && String(n) === field && n >= range.min && n <= range.max;\n}\n\n/**\n * Validate an IANA timezone. Uses `Intl.DateTimeFormat`'s strict timezone\n * lookup; invalid values raise `RangeError` which we wrap.\n *\n * @internal\n */\nexport function validateTimezone(timezone: string): void {\n try {\n new Intl.DateTimeFormat(\"en-US\", { timeZone: timezone });\n } catch {\n throw new ConfigurationError(`Invalid IANA timezone: ${timezone}`, {\n code: \"invalid_timezone\",\n });\n }\n}\n\n/**\n * Heuristic next-fire-at estimator for fixture mode. Returns a timestamp\n * one hour in the future for shorthand/POSIX inputs. Real scheduling uses\n * a proper evaluator wired in by the local scheduler.\n *\n * @internal\n */\nexport function estimateNextRunAt(_cron: string, _timezone: string): number {\n return Date.now() + 60 * 60 * 1000;\n}\n","// Bootstrap import: loading this facade must register the public Agent facade\n// into the agent-factory-registry seam, because `internal/cron/run-job.ts`\n// resolves it via `getAgentFacade()` at runtime instead of importing `agent.ts`\n// directly (which would invert the public-api -> internal dependency\n// direction). The `@theokit/sdk/cron` sub-path entry would otherwise throw\n// \"Agent facade not registered\" at runtime.\nimport \"./agent.js\";\nimport { ConfigurationError, UnknownAgentError } from \"./errors.js\";\nimport { fireCronJobAsTask } from \"./internal/cron/fire-handler.js\";\nimport { runCronJob } from \"./internal/cron/run-job.js\";\nimport {\n getSchedulerState,\n scheduleJob,\n setCronFireHandler,\n startScheduler,\n stopScheduler,\n unscheduleJob,\n} from \"./internal/cron/scheduler.js\";\nimport { deleteJob, getJob, jobCount, listJobs, upsertJob } from \"./internal/cron/store.js\";\nimport {\n estimateNextRunAt,\n validateCronExpression,\n validateTimezone,\n} from \"./internal/cron/validate.js\";\nimport { resolveApiKey } from \"./internal/env.js\";\nimport { generateCronId } from \"./internal/ids.js\";\nimport type { AgentOptions, ListResult } from \"./types/agent.js\";\nimport type {\n CronCreateOptions,\n CronGetOptions,\n CronJob,\n CronListOptions,\n CronOperationOptions,\n CronRunOptions,\n CronRuntime,\n CronSchedulerStatus,\n CronStartOptions,\n} from \"./types/cron.js\";\nimport type { Run } from \"./types/run.js\";\n\n/**\n * Static façade for scheduling Theo agent runs on a cron expression.\n *\n * @public\n */\nexport class Cron {\n private constructor() {\n // Static-only façade.\n }\n\n /**\n * Create and persist a cron job.\n *\n * @public\n */\n static async create(options: CronCreateOptions): Promise<CronJob> {\n const job = await createCronJob(options);\n if (job.runtime === \"local\" && job.enabled !== false) scheduleJob(job);\n return job;\n }\n\n /**\n * List cron jobs (local, cloud, or both).\n *\n * @public\n */\n static list(options: CronListOptions = {}): Promise<ListResult<CronJob>> {\n const runtimeFilter = options.runtime;\n const items = listJobs().filter((job) =>\n runtimeFilter === undefined ? true : job.runtime === runtimeFilter,\n );\n return Promise.resolve({ items });\n }\n\n /**\n * Get a single cron job by ID.\n *\n * @public\n */\n static get(jobId: string, _options: CronGetOptions = {}): Promise<CronJob> {\n const job = getJob(jobId);\n if (job === undefined) {\n return Promise.reject(\n new UnknownAgentError(`Cron job ${jobId} not found`, { code: \"unknown_cron_job\" }),\n );\n }\n return Promise.resolve(job);\n }\n\n /**\n * Delete a cron job permanently.\n *\n * @public\n */\n static delete(jobId: string, _options: CronOperationOptions = {}): Promise<void> {\n unscheduleJob(jobId);\n deleteJob(jobId);\n return Promise.resolve();\n }\n\n /**\n * Re-enable a paused cron job.\n *\n * @public\n */\n static async enable(jobId: string, _options: CronOperationOptions = {}): Promise<CronJob> {\n return updateJobStatus(jobId, true);\n }\n\n /**\n * Pause a cron job without deleting it.\n *\n * @public\n */\n static async disable(jobId: string, _options: CronOperationOptions = {}): Promise<CronJob> {\n return updateJobStatus(jobId, false);\n }\n\n /**\n * Manually trigger a cron job off-schedule. Returns the resulting `Run`\n * (agent target) or `WorkflowRun` (workflow target — SE35).\n *\n * @public\n */\n static async run(\n jobId: string,\n _options: CronRunOptions = {},\n ): Promise<Run | import(\"./types/workflow.js\").WorkflowRun> {\n const job = getJob(jobId);\n if (job === undefined) {\n throw new UnknownAgentError(`Cron job ${jobId} not found`, { code: \"unknown_cron_job\" });\n }\n return runCronJob(job);\n }\n\n /**\n * Activate the in-process scheduler for local cron jobs.\n *\n * @public\n */\n static start(options: CronStartOptions = {}): Promise<void> {\n // Install the default fire handler so timer ticks actually drive a real\n // agent/workflow run. Users can override via `setCronFireHandler` from\n // `@theokit/sdk/internal` (test-mode hook). Handler body lives in\n // `internal/cron/fire-handler.ts` (testable + G8).\n setCronFireHandler(fireCronJobAsTask);\n startScheduler(options.cwd);\n return Promise.resolve();\n }\n\n /**\n * Stop the in-process scheduler. Jobs are preserved.\n *\n * @public\n */\n static stop(): Promise<void> {\n stopScheduler();\n return Promise.resolve();\n }\n\n /**\n * Snapshot of the local scheduler.\n *\n * @public\n */\n static status(_options: CronStartOptions = {}): Promise<CronSchedulerStatus> {\n const scheduler = getSchedulerState();\n return Promise.resolve({ running: scheduler.running, jobCount: jobCount() });\n }\n}\n\nasync function createCronJob(options: CronCreateOptions): Promise<CronJob> {\n validateCronTarget(options);\n\n validateCronExpression(options.cron);\n const timezone = options.timezone ?? \"UTC\";\n validateTimezone(timezone);\n\n // apiKey is accepted but not required for cron-create in fixture mode.\n resolveApiKey(options.apiKey);\n\n const runtime = detectRuntime(options);\n const now = Date.now();\n const job: CronJob = {\n id: generateCronId(),\n cron: options.cron,\n timezone,\n enabled: options.enabled ?? true,\n status: options.enabled === false ? \"paused\" : \"scheduled\",\n runtime,\n createdAt: now,\n nextRunAt: estimateNextRunAt(options.cron, timezone),\n ...(options.name !== undefined ? { name: options.name } : {}),\n ...(options.message !== undefined ? { message: options.message } : {}),\n ...(options.agent !== undefined ? { agent: options.agent } : {}),\n ...(options.agentId !== undefined ? { agentId: options.agentId } : {}),\n ...(options.workflow !== undefined ? { workflow: options.workflow } : {}),\n ...(options.inputData !== undefined ? { inputData: options.inputData } : {}),\n };\n upsertJob(job);\n return job;\n}\n\n/**\n * SE35 (ADR 0014) — exactly ONE target (`agent` | `agentId` | `workflow`).\n * Agent targets require `message`; a workflow target takes `inputData` and MUST\n * NOT set `message`.\n */\nfunction validateCronTarget(options: CronCreateOptions): void {\n const targets = [options.agent, options.agentId, options.workflow].filter(\n (t) => t !== undefined,\n ).length;\n if (targets > 1) {\n throw new ConfigurationError(\n \"agent, agentId, and workflow are mutually exclusive — pass exactly one target.\",\n { code: \"cron_ambiguous_target\" },\n );\n }\n if (targets === 0) {\n throw new ConfigurationError(\n \"Cron job requires exactly one target: agent, agentId, or workflow.\",\n { code: \"cron_no_target\" },\n );\n }\n if (options.workflow !== undefined && options.message !== undefined) {\n throw new ConfigurationError(\n \"A workflow cron target takes inputData, not a message — remove `message`.\",\n { code: \"cron_workflow_message\" },\n );\n }\n if (options.workflow === undefined && options.message === undefined) {\n throw new ConfigurationError(\"An agent cron target requires a message.\", {\n code: \"cron_missing_message\",\n });\n }\n}\n\nfunction detectRuntime(options: CronCreateOptions): CronRuntime {\n // SE35 — a workflow target is a held in-memory instance; it can only run in\n // the local (in-process) scheduler. A workflow instance cannot cross the\n // cloud process boundary (ADR 0014).\n if (options.workflow !== undefined) return \"local\";\n if (options.agentId !== undefined) {\n return options.agentId.startsWith(\"bc-\") ? \"cloud\" : \"local\";\n }\n const agent = options.agent as AgentOptions | undefined;\n if (agent?.cloud !== undefined) return \"cloud\";\n return \"local\";\n}\n\nasync function updateJobStatus(jobId: string, enabled: boolean): Promise<CronJob> {\n const existing = getJob(jobId);\n if (existing === undefined) {\n throw new UnknownAgentError(`Cron job ${jobId} not found`, { code: \"unknown_cron_job\" });\n }\n const updated: CronJob = {\n ...existing,\n enabled,\n status: enabled ? \"scheduled\" : \"paused\",\n };\n upsertJob(updated);\n if (updated.runtime === \"local\") {\n if (enabled) {\n scheduleJob(updated);\n } else {\n unscheduleJob(updated.id);\n }\n }\n return updated;\n}\n"]}
1
+ {"version":3,"sources":["../src/internal/cron/run-job.ts","../src/internal/cron/fire-handler.ts","../src/internal/cron/store.ts","../src/internal/cron/scheduler.ts","../src/internal/cron/validate.ts","../src/cron.ts"],"names":["Croner"],"mappings":"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","file":"chunk-KWUNN5J2.js","sourcesContent":["import { ConfigurationError, UnknownAgentError } from \"../../errors.js\";\nimport type { AgentOptions } from \"../../types/agent.js\";\nimport type { CronJob } from \"../../types/cron.js\";\nimport type { Run, SDKUserMessage } from \"../../types/run.js\";\nimport type { WorkflowRun } from \"../../types/workflow.js\";\nimport { getAgentFacade } from \"../runtime/registry/agent-factory-registry.js\";\n\n/**\n * Execute a cron job. Dispatches to one of three targets:\n * - `workflow` (SE35) → `workflow.run(inputData)` on the held instance (the\n * instance carries its own `.run`, so this module never imports `workflow.ts`),\n * returning the already-terminal {@link WorkflowRun}.\n * - `agent` → an ephemeral agent per fire; `agent.send(message)` → {@link Run}.\n * - `agentId` → reuse an existing agent; `agent.send(message)` → {@link Run}.\n *\n * Used by both `Cron.run(jobId)` (manual off-schedule fire) and the scheduler's\n * default fire handler. ADR 0014.\n *\n * @internal\n */\nexport async function runCronJob(job: CronJob): Promise<Run | WorkflowRun> {\n // `Workflow.run()` resolves only on a TERMINAL run (completed/failed/suspended/\n // cancelled — the executor never returns `status: \"running\"`), so the fire\n // handler treats the returned WorkflowRun as terminal (no `.wait()`).\n if (job.workflow !== undefined) return job.workflow.run(job.inputData);\n if (job.agent !== undefined) return runWithEphemeralAgent(job.agent, requireMessage(job));\n if (job.agentId !== undefined) return runWithExistingAgent(job.agentId, requireMessage(job));\n throw new ConfigurationError(\n `Cron job ${job.id} has no target (agent, agentId, or workflow) — cannot run.`,\n { code: \"cron_no_target\" },\n );\n}\n\n/**\n * Discriminate the {@link runCronJob} union: an agent `Run` is deferred (carries\n * `.wait()`/`.cancel()`); a {@link WorkflowRun} is already terminal (no `.wait()`).\n * @internal\n */\nexport function isAgentRun(outcome: Run | WorkflowRun): outcome is Run {\n return typeof (outcome as Run).wait === \"function\";\n}\n\n/** Agent targets require a message; fail-loud if one somehow reached a fire without it. */\nfunction requireMessage(job: CronJob): string | SDKUserMessage {\n if (job.message === undefined) {\n throw new ConfigurationError(`Cron job ${job.id} is an agent target but has no message.`, {\n code: \"cron_missing_message\",\n });\n }\n return job.message;\n}\n\nasync function runWithExistingAgent(\n agentId: string,\n message: string | SDKUserMessage,\n): Promise<Run> {\n const info = await getAgentFacade()\n .get(agentId)\n .catch(() => undefined);\n if (info === undefined) {\n throw new UnknownAgentError(\n `Cron job references agentId \"${agentId}\" but no such agent is registered. The agent may have been disposed or the process restarted without persisting the agent registry.`,\n { code: \"agent_not_registered\" },\n );\n }\n const agent = await getAgentFacade().resume(agentId);\n return agent.send(message);\n}\n\nasync function runWithEphemeralAgent(\n baseOptions: AgentOptions,\n message: string | SDKUserMessage,\n): Promise<Run> {\n const agent = await getAgentFacade().create(baseOptions);\n return agent.send(message);\n}\n","/**\n * Default cron fire handler (extracted from `Cron.start` for testability + G8).\n *\n * Every fire registers as a Task (ADRs D363/D374) so callers observe it via\n * `Task.list` / `Task.subscribe`. SE35 (ADR 0014): the fire target may be an\n * agent (a deferred {@link Run} — abort-wire + `wait()`) OR a workflow (an\n * already-terminal {@link WorkflowRun} — no `wait()`); `isAgentRun` discriminates\n * so the handler records the correct terminal status/runId for each shape.\n *\n * @internal\n */\n\nimport type { CronJob } from \"../../types/cron.js\";\nimport { submit as taskRegistrySubmit } from \"../task/registry.js\";\nimport { isAgentRun, runCronJob } from \"./run-job.js\";\n\nexport async function fireCronJobAsTask(job: CronJob): Promise<void> {\n // The task id namespace `cron-{jobId}-{fireEpochMs}` honors D368/EC-5.\n const fireTs = Date.now();\n const taskId = `cron-${job.id}-${fireTs}`;\n try {\n await taskRegistrySubmit({\n kind: \"cron\",\n id: taskId,\n allowReservedPrefix: true,\n meta: { jobId: job.id, jobName: job.name, schedule: job.cron, firedAt: fireTs },\n work: async (ctx) => {\n const outcome = await runCronJob(job);\n if (isAgentRun(outcome)) {\n // Agent target — the Run is deferred: abort-wire + await terminal.\n ctx.signal.addEventListener(\"abort\", () => void outcome.cancel().catch(() => {}), {\n once: true,\n });\n const result = await outcome.wait();\n ctx.emit({ status: result.status, runId: outcome.id });\n return { status: result.status, runId: outcome.id };\n }\n // SE35 workflow target — the WorkflowRun is ALREADY terminal (no wait()).\n ctx.emit({ status: outcome.status, runId: outcome.id });\n return { status: outcome.status, runId: outcome.id };\n },\n });\n } catch {\n // Task registry must not break cron — fall through to a direct run. No\n // double-execution: `taskRegistrySubmit` runs `work` (which calls\n // `runCronJob`) fire-and-forget, so a throw here means the SUBMIT itself\n // failed (id/registry setup) BEFORE `work` started — the job never ran, and\n // this is its first + only execution.\n const outcome = await runCronJob(job);\n if (isAgentRun(outcome)) await outcome.wait();\n }\n}\n","import type { CronJob } from \"../../types/cron.js\";\n\n/**\n * Process-wide cron job store. In Phase 1 we keep all jobs in memory\n * (across local + cloud runtimes). Local-runtime persistence to\n * `.theokit/cron/jobs.json` lands when the local runtime adapter is wired.\n *\n * @internal\n */\nconst jobs = new Map<string, CronJob>();\n\n/** Snapshot of every known cron job. @internal */\nexport function listJobs(): CronJob[] {\n return Array.from(jobs.values());\n}\n\n/** Total job count across runtimes. @internal */\nexport function jobCount(): number {\n return jobs.size;\n}\n\n/** Fetch a single job by id, or `undefined` if it does not exist. @internal */\nexport function getJob(jobId: string): CronJob | undefined {\n return jobs.get(jobId);\n}\n\n/** Insert or replace a job. @internal */\nexport function upsertJob(job: CronJob): void {\n jobs.set(job.id, job);\n}\n\n/** Delete a job. Returns `true` if a job was removed. @internal */\nexport function deleteJob(jobId: string): boolean {\n return jobs.delete(jobId);\n}\n\n/** Test-only: drop every job. @internal */\nexport function clearJobs(): void {\n jobs.clear();\n}\n","import { Cron as Croner } from \"croner\";\n\nimport type { CronJob } from \"../../types/cron.js\";\nimport { listJobs, upsertJob } from \"./store.js\";\n\n/**\n * Real local cron scheduler. When `Cron.start()` is called the scheduler\n * installs a Croner timer per enabled local job; on fire the registered\n * fire handler runs the underlying agent. `Cron.stop()` tears every timer\n * down but keeps the jobs in the store.\n *\n * @internal\n */\n\nexport type CronFireHandler = (job: CronJob) => Promise<void> | void;\n\ninterface SchedulerState {\n running: boolean;\n cwd?: string;\n timers: Map<string, Croner>;\n fireHandler?: CronFireHandler;\n}\n\nconst state: SchedulerState = { running: false, timers: new Map() };\n\n/**\n * Register the callback invoked when a job fires. The runtime adapter\n * supplies a handler that actually executes the agent; fixture-mode tests\n * leave it unset so timers tick without side effects.\n *\n * @internal\n */\nexport function setCronFireHandler(handler: CronFireHandler | undefined): void {\n state.fireHandler = handler;\n}\n\n/** Activate the scheduler and install timers for every enabled local job. @internal */\nexport function startScheduler(cwd?: string): void {\n state.running = true;\n if (cwd !== undefined) state.cwd = cwd;\n for (const job of listJobs()) {\n if (job.runtime === \"local\" && job.enabled !== false) scheduleJob(job);\n }\n}\n\n/** Deactivate the scheduler. Stops every timer; jobs remain in the store. @internal */\nexport function stopScheduler(): void {\n state.running = false;\n for (const timer of state.timers.values()) timer.stop();\n state.timers.clear();\n}\n\n/** Schedule a single job. No-op if the scheduler is not running. @internal */\nexport function scheduleJob(job: CronJob): void {\n if (!state.running) return;\n unscheduleJob(job.id);\n const expression = normalizeExpression(job.cron);\n const timer = new Croner(\n expression,\n { timezone: job.timezone, name: job.id, protect: true },\n () => {\n void fireJob(job.id);\n },\n );\n state.timers.set(job.id, timer);\n refreshNextRunAt(job.id, timer);\n}\n\n/** Tear down the timer for a single job. @internal */\nexport function unscheduleJob(jobId: string): boolean {\n const timer = state.timers.get(jobId);\n if (timer === undefined) return false;\n timer.stop();\n state.timers.delete(jobId);\n return true;\n}\n\n/** Snapshot of the scheduler's running flag and configured workspace. @internal */\nexport function getSchedulerState(): { running: boolean; cwd?: string } {\n const result: { running: boolean; cwd?: string } = { running: state.running };\n if (state.cwd !== undefined) result.cwd = state.cwd;\n return result;\n}\n\nasync function fireJob(jobId: string): Promise<void> {\n const fresh = listJobs().find((entry) => entry.id === jobId);\n if (fresh === undefined || fresh.enabled === false) return;\n const handler = state.fireHandler;\n upsertJob({ ...fresh, lastRunAt: Date.now() });\n if (handler === undefined) return;\n try {\n await handler(fresh);\n } catch {\n // Swallow handler errors — the scheduler must keep ticking. Real\n // surface for run failures lives on the Run.wait() result itself.\n }\n}\n\nfunction refreshNextRunAt(jobId: string, timer: Croner): void {\n const next = timer.nextRun();\n if (next === null) return;\n const existing = listJobs().find((entry) => entry.id === jobId);\n if (existing === undefined) return;\n upsertJob({ ...existing, nextRunAt: next.getTime() });\n}\n\nfunction normalizeExpression(cron: string): string {\n switch (cron) {\n case \"@hourly\":\n return \"0 * * * *\";\n case \"@daily\":\n return \"0 0 * * *\";\n case \"@weekly\":\n return \"0 0 * * 0\";\n case \"@monthly\":\n return \"0 0 1 * *\";\n case \"@yearly\":\n return \"0 0 1 1 *\";\n default:\n return cron;\n }\n}\n","import { ConfigurationError } from \"../../errors.js\";\n\n/**\n * POSIX-cron + shorthand validators used by `Cron.create()`. Throws\n * `ConfigurationError` with a stable message and code on invalid input.\n *\n * @internal\n */\n\nconst SHORTHANDS = new Set([\"@hourly\", \"@daily\", \"@weekly\", \"@monthly\", \"@yearly\"]);\n\ninterface FieldRange {\n min: number;\n max: number;\n}\n\nconst FIELD_RANGES: readonly FieldRange[] = [\n { min: 0, max: 59 }, // minute\n { min: 0, max: 23 }, // hour\n { min: 1, max: 31 }, // day-of-month\n { min: 1, max: 12 }, // month\n { min: 0, max: 6 }, // day-of-week\n];\n\n/**\n * Validate a cron expression. Accepts shorthand (`@hourly`, ..., `@yearly`)\n * or 5-field POSIX cron with star, literals, star/N step, N-M range, and\n * N,M,P list.\n *\n * @internal\n */\nexport function validateCronExpression(cron: string): void {\n if (typeof cron !== \"string\" || cron.length === 0) {\n throw new ConfigurationError(\"Invalid cron expression: empty\", {\n code: \"invalid_cron\",\n });\n }\n if (cron.startsWith(\"@\")) {\n if (!SHORTHANDS.has(cron)) {\n throw new ConfigurationError(`Invalid cron expression: unknown shorthand ${cron}`, {\n code: \"invalid_cron\",\n });\n }\n return;\n }\n\n const fields = cron.trim().split(/\\s+/);\n if (fields.length !== 5) {\n throw new ConfigurationError(\n `Invalid cron expression: ${cron} (expected 5 fields, got ${fields.length})`,\n { code: \"invalid_cron\" },\n );\n }\n for (const [index, field] of fields.entries()) {\n validateFieldOrThrow(field, index, cron);\n }\n}\n\nfunction validateFieldOrThrow(field: string, index: number, cron: string): void {\n const range = FIELD_RANGES[index];\n if (range === undefined) {\n throw new ConfigurationError(`Invalid cron expression: ${cron} (field ${index + 1})`, {\n code: \"invalid_cron\",\n });\n }\n if (!isValidCronField(field, range)) {\n throw new ConfigurationError(`Invalid cron expression: ${cron} (field ${index + 1})`, {\n code: \"invalid_cron\",\n });\n }\n}\n\nfunction isValidCronField(field: string, range: FieldRange): boolean {\n if (field === \"*\") return true;\n if (field.startsWith(\"*/\")) return isValidStep(field.slice(2), range);\n if (field.includes(\",\")) {\n return field.split(\",\").every((part) => isValidCronField(part, range));\n }\n if (field.includes(\"-\")) return isValidRange(field, range);\n return isValidLiteral(field, range);\n}\n\nfunction isValidStep(stepStr: string, range: FieldRange): boolean {\n const step = Number.parseInt(stepStr, 10);\n return Number.isInteger(step) && String(step) === stepStr && step > 0 && step <= range.max;\n}\n\nfunction isValidRange(field: string, range: FieldRange): boolean {\n const parts = field.split(\"-\");\n if (parts.length !== 2) return false;\n const [startStr, endStr] = parts;\n if (startStr === undefined || endStr === undefined) return false;\n const start = Number.parseInt(startStr, 10);\n const end = Number.parseInt(endStr, 10);\n if (!Number.isInteger(start) || !Number.isInteger(end)) return false;\n return start >= range.min && end <= range.max && start <= end;\n}\n\nfunction isValidLiteral(field: string, range: FieldRange): boolean {\n const n = Number.parseInt(field, 10);\n return Number.isInteger(n) && String(n) === field && n >= range.min && n <= range.max;\n}\n\n/**\n * Validate an IANA timezone. Uses `Intl.DateTimeFormat`'s strict timezone\n * lookup; invalid values raise `RangeError` which we wrap.\n *\n * @internal\n */\nexport function validateTimezone(timezone: string): void {\n try {\n new Intl.DateTimeFormat(\"en-US\", { timeZone: timezone });\n } catch {\n throw new ConfigurationError(`Invalid IANA timezone: ${timezone}`, {\n code: \"invalid_timezone\",\n });\n }\n}\n\n/**\n * Heuristic next-fire-at estimator for fixture mode. Returns a timestamp\n * one hour in the future for shorthand/POSIX inputs. Real scheduling uses\n * a proper evaluator wired in by the local scheduler.\n *\n * @internal\n */\nexport function estimateNextRunAt(_cron: string, _timezone: string): number {\n return Date.now() + 60 * 60 * 1000;\n}\n","// Bootstrap import: loading this facade must register the public Agent facade\n// into the agent-factory-registry seam, because `internal/cron/run-job.ts`\n// resolves it via `getAgentFacade()` at runtime instead of importing `agent.ts`\n// directly (which would invert the public-api -> internal dependency\n// direction). The `@theokit/sdk/cron` sub-path entry would otherwise throw\n// \"Agent facade not registered\" at runtime.\nimport \"./agent.js\";\nimport { ConfigurationError, UnknownAgentError } from \"./errors.js\";\nimport { fireCronJobAsTask } from \"./internal/cron/fire-handler.js\";\nimport { runCronJob } from \"./internal/cron/run-job.js\";\nimport {\n getSchedulerState,\n scheduleJob,\n setCronFireHandler,\n startScheduler,\n stopScheduler,\n unscheduleJob,\n} from \"./internal/cron/scheduler.js\";\nimport { deleteJob, getJob, jobCount, listJobs, upsertJob } from \"./internal/cron/store.js\";\nimport {\n estimateNextRunAt,\n validateCronExpression,\n validateTimezone,\n} from \"./internal/cron/validate.js\";\nimport { resolveApiKey } from \"./internal/env.js\";\nimport { generateCronId } from \"./internal/ids.js\";\nimport type { AgentOptions, ListResult } from \"./types/agent.js\";\nimport type {\n CronCreateOptions,\n CronGetOptions,\n CronJob,\n CronListOptions,\n CronOperationOptions,\n CronRunOptions,\n CronRuntime,\n CronSchedulerStatus,\n CronStartOptions,\n} from \"./types/cron.js\";\nimport type { Run } from \"./types/run.js\";\n\n/**\n * Static façade for scheduling Theo agent runs on a cron expression.\n *\n * @public\n */\nexport class Cron {\n private constructor() {\n // Static-only façade.\n }\n\n /**\n * Create and persist a cron job.\n *\n * @public\n */\n static async create(options: CronCreateOptions): Promise<CronJob> {\n const job = await createCronJob(options);\n if (job.runtime === \"local\" && job.enabled !== false) scheduleJob(job);\n return job;\n }\n\n /**\n * List cron jobs (local, cloud, or both).\n *\n * @public\n */\n static list(options: CronListOptions = {}): Promise<ListResult<CronJob>> {\n const runtimeFilter = options.runtime;\n const items = listJobs().filter((job) =>\n runtimeFilter === undefined ? true : job.runtime === runtimeFilter,\n );\n return Promise.resolve({ items });\n }\n\n /**\n * Get a single cron job by ID.\n *\n * @public\n */\n static get(jobId: string, _options: CronGetOptions = {}): Promise<CronJob> {\n const job = getJob(jobId);\n if (job === undefined) {\n return Promise.reject(\n new UnknownAgentError(`Cron job ${jobId} not found`, { code: \"unknown_cron_job\" }),\n );\n }\n return Promise.resolve(job);\n }\n\n /**\n * Delete a cron job permanently.\n *\n * @public\n */\n static delete(jobId: string, _options: CronOperationOptions = {}): Promise<void> {\n unscheduleJob(jobId);\n deleteJob(jobId);\n return Promise.resolve();\n }\n\n /**\n * Re-enable a paused cron job.\n *\n * @public\n */\n static async enable(jobId: string, _options: CronOperationOptions = {}): Promise<CronJob> {\n return updateJobStatus(jobId, true);\n }\n\n /**\n * Pause a cron job without deleting it.\n *\n * @public\n */\n static async disable(jobId: string, _options: CronOperationOptions = {}): Promise<CronJob> {\n return updateJobStatus(jobId, false);\n }\n\n /**\n * Manually trigger a cron job off-schedule. Returns the resulting `Run`\n * (agent target) or `WorkflowRun` (workflow target — SE35).\n *\n * @public\n */\n static async run(\n jobId: string,\n _options: CronRunOptions = {},\n ): Promise<Run | import(\"./types/workflow.js\").WorkflowRun> {\n const job = getJob(jobId);\n if (job === undefined) {\n throw new UnknownAgentError(`Cron job ${jobId} not found`, { code: \"unknown_cron_job\" });\n }\n return runCronJob(job);\n }\n\n /**\n * Activate the in-process scheduler for local cron jobs.\n *\n * @public\n */\n static start(options: CronStartOptions = {}): Promise<void> {\n // Install the default fire handler so timer ticks actually drive a real\n // agent/workflow run. Users can override via `setCronFireHandler` from\n // `@theokit/sdk/internal` (test-mode hook). Handler body lives in\n // `internal/cron/fire-handler.ts` (testable + G8).\n setCronFireHandler(fireCronJobAsTask);\n startScheduler(options.cwd);\n return Promise.resolve();\n }\n\n /**\n * Stop the in-process scheduler. Jobs are preserved.\n *\n * @public\n */\n static stop(): Promise<void> {\n stopScheduler();\n return Promise.resolve();\n }\n\n /**\n * Snapshot of the local scheduler.\n *\n * @public\n */\n static status(_options: CronStartOptions = {}): Promise<CronSchedulerStatus> {\n const scheduler = getSchedulerState();\n return Promise.resolve({ running: scheduler.running, jobCount: jobCount() });\n }\n}\n\nasync function createCronJob(options: CronCreateOptions): Promise<CronJob> {\n validateCronTarget(options);\n\n validateCronExpression(options.cron);\n const timezone = options.timezone ?? \"UTC\";\n validateTimezone(timezone);\n\n // apiKey is accepted but not required for cron-create in fixture mode.\n resolveApiKey(options.apiKey);\n\n const runtime = detectRuntime(options);\n const now = Date.now();\n const job: CronJob = {\n id: generateCronId(),\n cron: options.cron,\n timezone,\n enabled: options.enabled ?? true,\n status: options.enabled === false ? \"paused\" : \"scheduled\",\n runtime,\n createdAt: now,\n nextRunAt: estimateNextRunAt(options.cron, timezone),\n ...(options.name !== undefined ? { name: options.name } : {}),\n ...(options.message !== undefined ? { message: options.message } : {}),\n ...(options.agent !== undefined ? { agent: options.agent } : {}),\n ...(options.agentId !== undefined ? { agentId: options.agentId } : {}),\n ...(options.workflow !== undefined ? { workflow: options.workflow } : {}),\n ...(options.inputData !== undefined ? { inputData: options.inputData } : {}),\n };\n upsertJob(job);\n return job;\n}\n\n/**\n * SE35 (ADR 0014) — exactly ONE target (`agent` | `agentId` | `workflow`).\n * Agent targets require `message`; a workflow target takes `inputData` and MUST\n * NOT set `message`.\n */\nfunction validateCronTarget(options: CronCreateOptions): void {\n const targets = [options.agent, options.agentId, options.workflow].filter(\n (t) => t !== undefined,\n ).length;\n if (targets > 1) {\n throw new ConfigurationError(\n \"agent, agentId, and workflow are mutually exclusive — pass exactly one target.\",\n { code: \"cron_ambiguous_target\" },\n );\n }\n if (targets === 0) {\n throw new ConfigurationError(\n \"Cron job requires exactly one target: agent, agentId, or workflow.\",\n { code: \"cron_no_target\" },\n );\n }\n if (options.workflow !== undefined && options.message !== undefined) {\n throw new ConfigurationError(\n \"A workflow cron target takes inputData, not a message — remove `message`.\",\n { code: \"cron_workflow_message\" },\n );\n }\n if (options.workflow === undefined && options.message === undefined) {\n throw new ConfigurationError(\"An agent cron target requires a message.\", {\n code: \"cron_missing_message\",\n });\n }\n}\n\nfunction detectRuntime(options: CronCreateOptions): CronRuntime {\n // SE35 — a workflow target is a held in-memory instance; it can only run in\n // the local (in-process) scheduler. A workflow instance cannot cross the\n // cloud process boundary (ADR 0014).\n if (options.workflow !== undefined) return \"local\";\n if (options.agentId !== undefined) {\n return options.agentId.startsWith(\"bc-\") ? \"cloud\" : \"local\";\n }\n const agent = options.agent as AgentOptions | undefined;\n if (agent?.cloud !== undefined) return \"cloud\";\n return \"local\";\n}\n\nasync function updateJobStatus(jobId: string, enabled: boolean): Promise<CronJob> {\n const existing = getJob(jobId);\n if (existing === undefined) {\n throw new UnknownAgentError(`Cron job ${jobId} not found`, { code: \"unknown_cron_job\" });\n }\n const updated: CronJob = {\n ...existing,\n enabled,\n status: enabled ? \"scheduled\" : \"paused\",\n };\n upsertJob(updated);\n if (updated.runtime === \"local\") {\n if (enabled) {\n scheduleJob(updated);\n } else {\n unscheduleJob(updated.id);\n }\n }\n return updated;\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { diag } from './chunk-TAPQWDW2.js';
1
+ import { diag } from './chunk-IVSD7L22.js';
2
2
  import { randomBytes } from 'crypto';
3
3
  import { open, rename, unlink, mkdir, statfs } from 'fs/promises';
4
4
  import { dirname } from 'path';
@@ -65,5 +65,5 @@ async function atomicWriteText(filePath, content) {
65
65
  }
66
66
 
67
67
  export { atomicWriteJson, atomicWriteText, replaceFileAtomic };
68
- //# sourceMappingURL=chunk-56OXYUZE.js.map
69
- //# sourceMappingURL=chunk-56OXYUZE.js.map
68
+ //# sourceMappingURL=chunk-KX7JV5KM.js.map
69
+ //# sourceMappingURL=chunk-KX7JV5KM.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/internal/persistence/atomic-write.ts"],"names":[],"mappings":"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","file":"chunk-KX7JV5KM.js","sourcesContent":["import { randomBytes } from \"node:crypto\";\nimport { mkdir, open, rename, statfs, unlink } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\nimport { diag } from \"../diagnostics.js\";\n\n// T5.8 — Linux filesystem magic numbers (from `<linux/magic.h>`).\n// Used by `detectNetworkFsName` to identify the parent directory's\n// filesystem type from a `statfs()` return value. The four entries\n// below cover the network/FUSE cases where `rename()` is best-effort\n// rather than strictly atomic; everything else is treated as local.\nconst NETWORK_FS_MAGIC: ReadonlyMap<number, string> = new Map([\n [0x6969, \"nfs\"],\n [0x517b, \"smb\"],\n [0xff534d42, \"cifs\"],\n [0x65735546, \"fuse\"],\n]);\n\n/**\n * T5.8 — Map a `statfs().type` magic number to a network-FS label, or\n * `null` for local filesystems. Pure function — exported via the\n * `__TESTING__` seam so unit tests can drive the parse logic without\n * needing a network mount.\n *\n * @internal\n */\nfunction detectNetworkFsName(typeMagic: number): string | null {\n return NETWORK_FS_MAGIC.get(typeMagic) ?? null;\n}\n\nconst warnedNfsDirs = new Set<string>();\n\n/**\n * T5.8 — Best-effort one-shot stderr warning when `dirPath` lives on a\n * network/FUSE filesystem. Silent no-op on local filesystems, on\n * statfs failure (Windows / Node < 18.15 / EACCES), or after the\n * first warning per (dir + label) pair. Mirrors the `sqlite-wal.ts`\n * warn-once-per-label pattern (D63).\n *\n * @internal\n */\nasync function warnOnNetworkFsOnce(dirPath: string, label: string): Promise<void> {\n const key = `${dirPath}\\0${label}`;\n if (warnedNfsDirs.has(key)) return;\n warnedNfsDirs.add(key);\n try {\n const info = await statfs(dirPath);\n const fsName = detectNetworkFsName(info.type);\n if (fsName === null) return;\n diag(\n `[theokit-sdk] ${label}: detected network fs (${fsName}) at ${dirPath} — ` +\n \"rename() atomicity guarantees may be weaker than expected.\\n\",\n );\n } catch {\n // statfs unavailable (Windows / Node < 18.15) or unreadable —\n // silent fallback. The warning is purely informational.\n }\n}\n\n/**\n * T5.8 — Test seam exposing the pure detection function so unit tests\n * can assert magic-number coverage without spinning up a network FS.\n * NOT included in the public barrel.\n *\n * @internal\n */\nexport function __TESTING__detectNetworkFsName(typeMagic: number): string | null {\n return detectNetworkFsName(typeMagic);\n}\n\n/**\n * T5.8 — Test seam: clear the per-directory warn-once registry between\n * tests so warning-emission tests stay deterministic.\n *\n * @internal\n */\nexport function __TESTING__resetNfsWarnings(): void {\n warnedNfsDirs.clear();\n}\n\n/**\n * M107 — temp-file creation control, shared by `replaceFileAtomic`,\n * `atomicWriteJson` e `atomicWriteText`.\n *\n * Both fields are OPTIONAL and the default is byte-identical to the behavior\n * before M107. See `replaceFileAtomic` for why the mode reassertion\n * is conditional.\n *\n * @internal\n */\nexport interface AtomicWriteFileOptions {\n /**\n * Permission bits of the created file. Default: `0o600`, the previous fixed\n * literal — filtered by the `umask`, as it always was. When provided, the mode is\n * reasserted on the descriptor, so the `umask` cannot silently\n * clearing bits the caller asked for.\n */\n mode?: number;\n /**\n * Create the temp file with `wx` (exclusive creation) instead of `w`. Default:\n * `false` — the previous flag. With `true`, a pre-existing temp file becomes\n * `EEXIST` em vez de ser truncado.\n */\n exclusive?: boolean;\n}\n\n/**\n * Atomic file replacement: write content to a per-call unique tmp path,\n * fsync, then rename over the target. Crash mid-write leaves either the old\n * file intact or the new file complete — never a half-written file.\n *\n * The tmp suffix is `<pid>.<rand>.tmp` so parallel processes (and concurrent\n * burst writes within one process) never collide on the same tmp path — a\n * race that would manifest as `ENOENT` on `rename` after the rival process\n * already moved its tmp into place.\n *\n * Mirrors peer-project's `replaceFileAtomic` from\n * `referencia/peer-project/packages/memory-host-sdk/src/host/fs-utils.ts` with\n * the multi-writer robustness fix.\n *\n * ## M107 — `options` is optional, and the default is byte-identical\n *\n * The third parameter is additive: every earlier caller still compiles and\n * writing exactly the same bytes, with the same mode, to the same path.\n *\n * The mode reassertion (`handle.chmod`) is **conditional on `mode !== undefined`**,\n * and that is not cosmetic. `open`'s mode argument is filtered by the `umask`,\n * which only CLEARS bits — measured in this codebase before the change:\n *\n * ```\n * umask 0o002 -> 0o600 umask 0o022 -> 0o600 umask 0o200 -> 0o400\n * ```\n *\n * Um `chmod` incondicional levaria o terceiro caso de `0o400` para `0o600` — uma\n * an on-disk change for every caller that asked for nothing, including external\n * consumers. When the caller DOES ask for a mode, however, letting the `umask` decide\n * silently is the defect this parameter exists to close; hence the reassertion.\n *\n * It goes on the DESCRIPTOR, before the `rename`, never after: chmod-ing the final\n * final one would leave a window where it carries the `umask`'s mode — the anti-pattern\n * de `opencode/packages/core/src/fs-util.ts:110-114`. A forma escolhida (modo como\n * `open` argument) is that of `codex-rs/network-proxy/src/certs.rs:687,783-791`.\n *\n * @internal\n */\nexport async function replaceFileAtomic(\n filePath: string,\n content: string,\n options?: AtomicWriteFileOptions,\n): Promise<void> {\n // T5.8 — warn once per parent directory if it lives on a network /\n // FUSE filesystem where `rename()` atomicity is best-effort. The\n // write proceeds unchanged; the warning is purely informational so\n // operators can spot the case in stderr / log aggregators.\n await warnOnNetworkFsOnce(dirname(filePath), \"atomic-write\");\n // T5.7 — crypto-random tmp suffix (CSPRNG, 64 bits of entropy)\n // replaces the predictable `Math.random().toString(36)` source. An\n // attacker observing the process can no longer predict the next\n // tmp path and pre-stage a hostile file to be renamed into place.\n const suffix = randomBytes(8).toString(\"hex\");\n const tmp = `${filePath}.${process.pid}.${suffix}.tmp`;\n // T5.7 — mode 0o600 on the tmp file (owner read+write only). The\n // tmp file holds the FULL in-flight content (credential snapshots,\n // OAuth tokens) before the rename. World-readable default would\n // expose secrets during the ms-window between open and rename\n // (TOCTOU). On modern Linux the post-rename target inherits the\n // tmp's permission bits, so the final file is also 0o600.\n const handle = await open(tmp, options?.exclusive === true ? \"wx\" : \"w\", options?.mode ?? 0o600);\n try {\n await handle.writeFile(content, \"utf8\");\n await handle.sync();\n // Conditional by measurement, not by taste — see this function's docblock.\n if (options?.mode !== undefined) await handle.chmod(options.mode);\n } finally {\n await handle.close();\n }\n try {\n await rename(tmp, filePath);\n } catch (cause) {\n // Cleanup tmp on rename failure so we don't leak stale .tmp files.\n await unlink(tmp).catch(() => undefined);\n throw cause;\n }\n}\n\n/**\n * Options for `atomicWriteJson`.\n *\n * @internal\n */\nexport interface AtomicWriteJsonOptions extends AtomicWriteFileOptions {\n /** Indent passed to `JSON.stringify`. Default: 2. */\n indent?: number;\n /** Whether to append a trailing newline (POSIX convention). Default: true. */\n trailingNewline?: boolean;\n}\n\n/**\n * Typed JSON atomic write helper.\n *\n * Serializes `data` to JSON, then delegates to `replaceFileAtomic`. The\n * parent directory is auto-created (recursive `mkdir`) to make this helper\n * safe for callers who haven't ensured the directory exists (EC-4 in the\n * persistence-state-hardening plan).\n *\n * Throws `TypeError` on circular refs or `undefined` data (propagates from\n * `JSON.stringify`).\n *\n * @internal\n */\nexport async function atomicWriteJson<T>(\n filePath: string,\n data: T,\n options?: AtomicWriteJsonOptions,\n): Promise<void> {\n const indent = options?.indent ?? 2;\n const trailingNewline = options?.trailingNewline ?? true;\n const json = JSON.stringify(data, null, indent);\n if (json === undefined) {\n throw new TypeError(\"atomicWriteJson: cannot serialize undefined\");\n }\n const content = trailingNewline ? `${json}\\n` : json;\n await mkdir(dirname(filePath), { recursive: true });\n await replaceFileAtomic(filePath, content, options);\n}\n\n/**\n * Atomic text write. Same crash-safety guarantees as `replaceFileAtomic` +\n * auto-mkdir of the parent directory. Used by `theokit-migrate-config`\n * (T4.1, EC-2 MUST FIX) so a crash mid-migration leaves previous MD files\n * intact rather than corrupting them.\n *\n * @internal\n */\nexport async function atomicWriteText(filePath: string, content: string): Promise<void> {\n await mkdir(dirname(filePath), { recursive: true });\n await replaceFileAtomic(filePath, content);\n}\n"]}
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
- var chunkICYBIC6N_cjs = require('./chunk-ICYBIC6N.cjs');
4
- var chunkLTCOPATU_cjs = require('./chunk-LTCOPATU.cjs');
3
+ var chunkDGLLVCNB_cjs = require('./chunk-DGLLVCNB.cjs');
4
+ var chunkBCQ3E2ZG_cjs = require('./chunk-BCQ3E2ZG.cjs');
5
5
  var promises = require('fs/promises');
6
6
  var os = require('os');
7
7
  var path = require('path');
@@ -46,10 +46,10 @@ async function readVersionedJson(opts) {
46
46
  const asidePath = `${path}.corrupt.${Date.now()}`;
47
47
  try {
48
48
  await promises.rename(path, asidePath);
49
- chunkLTCOPATU_cjs.diag(`[theokit-sdk] ${path} is corrupt; moved to ${asidePath}. Using default value.
49
+ chunkBCQ3E2ZG_cjs.diag(`[theokit-sdk] ${path} is corrupt; moved to ${asidePath}. Using default value.
50
50
  `);
51
51
  } catch {
52
- chunkLTCOPATU_cjs.diag(`[theokit-sdk] ${path} is corrupt; using default value.
52
+ chunkBCQ3E2ZG_cjs.diag(`[theokit-sdk] ${path} is corrupt; using default value.
53
53
  `);
54
54
  }
55
55
  return defaultValue();
@@ -64,7 +64,7 @@ async function readVersionedJson(opts) {
64
64
  return file.data;
65
65
  }
66
66
  if (stored > currentVersion) {
67
- chunkLTCOPATU_cjs.diag(
67
+ chunkBCQ3E2ZG_cjs.diag(
68
68
  `[theokit-sdk] ${path} schema version ${stored} > current ${currentVersion}; using default value (forward-only).
69
69
  `
70
70
  );
@@ -77,7 +77,7 @@ async function writeVersionedJson(path, data, currentVersion) {
77
77
  _schemaVersion: currentVersion,
78
78
  data
79
79
  };
80
- await chunkICYBIC6N_cjs.atomicWriteJson(path, file);
80
+ await chunkDGLLVCNB_cjs.atomicWriteJson(path, file);
81
81
  }
82
82
  var THEOKIT_DIR_NAME = ".theokit";
83
83
  function getTheokitHome(cwd) {
@@ -106,5 +106,5 @@ exports.getTheokitHome = getTheokitHome;
106
106
  exports.migrateSchema = migrateSchema;
107
107
  exports.readVersionedJson = readVersionedJson;
108
108
  exports.writeVersionedJson = writeVersionedJson;
109
- //# sourceMappingURL=chunk-D4ZUJTFB.cjs.map
110
- //# sourceMappingURL=chunk-D4ZUJTFB.cjs.map
109
+ //# sourceMappingURL=chunk-LALG2K33.cjs.map
110
+ //# sourceMappingURL=chunk-LALG2K33.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/internal/persistence/schema-version.ts","../src/internal/persistence/paths.ts"],"names":["readFile","rename","diag","atomicWriteJson","join","homedir"],"mappings":"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","file":"chunk-D4ZUJTFB.cjs","sourcesContent":["/**\n * Schema versioning helpers (ADR D62).\n *\n * Two parallel APIs:\n * - `migrateSchema` — SQLite via `PRAGMA user_version` + ordered forward-only migrations.\n * - `readVersionedJson` / `writeVersionedJson` — JSON files with `_schemaVersion` field.\n *\n * Forward-only: never deletes data, never downgrades. Migration callbacks\n * own the transformation; this module owns the bookkeeping.\n *\n * @internal\n */\n\nimport { readFile, rename } from \"node:fs/promises\";\nimport { diag } from \"../diagnostics.js\";\nimport { atomicWriteJson } from \"./atomic-write.js\";\n\n// ────────────────────── SQLite migrations ──────────────────────\n\n/**\n * Minimal Database interface so this file does not hard-depend on\n * `better-sqlite3` at module load time. Compatible with the runtime\n * shape exposed by `better-sqlite3`.\n *\n * @internal\n */\nexport interface SqliteLike {\n pragma: (statement: string, options?: { simple?: boolean }) => unknown;\n exec: (sql: string) => void;\n transaction: <Args extends unknown[], R>(fn: (...args: Args) => R) => (...args: Args) => R;\n}\n\n/**\n * One forward migration step. `up` receives the DB inside a transaction;\n * `toVersion` is the value the pragma will be set to AFTER `up` returns.\n *\n * @internal\n */\nexport interface Migration {\n toVersion: number;\n up: (db: SqliteLike) => void;\n}\n\n/**\n * Options for `migrateSchema`.\n *\n * @internal\n */\nexport interface MigrateSchemaOptions {\n db: SqliteLike;\n currentVersion: number;\n migrations: ReadonlyArray<Migration>;\n /** For log/error context (e.g., \"memory-index\", \"registry\"). */\n label?: string;\n}\n\n/**\n * Result of `migrateSchema`.\n *\n * @internal\n */\nexport interface MigrateSchemaResult {\n from: number;\n to: number;\n ran: number;\n}\n\n/**\n * Run pending migrations to bring the DB from its current `user_version` up\n * to `currentVersion`. Migrations are sorted ascending by `toVersion` and\n * only those `> stored && <= currentVersion` execute. Each runs inside the\n * shared transaction.\n *\n * Throws if `stored > currentVersion` (downgrade attempt — forward-only).\n *\n * @internal\n */\nexport function migrateSchema(opts: MigrateSchemaOptions): MigrateSchemaResult {\n const { db, currentVersion, migrations, label = \"db\" } = opts;\n const storedRaw = db.pragma(\"user_version\", { simple: true });\n const stored = typeof storedRaw === \"number\" ? storedRaw : 0;\n\n if (stored > currentVersion) {\n throw new Error(\n `[${label}] schema version ${stored} > current ${currentVersion}; ` +\n \"did you downgrade the SDK? Forward-only migrations only.\",\n );\n }\n\n if (stored === currentVersion) {\n return { from: stored, to: stored, ran: 0 };\n }\n\n const pending = [...migrations]\n .sort((a, b) => a.toVersion - b.toVersion)\n .filter((m) => m.toVersion > stored && m.toVersion <= currentVersion);\n\n let ran = 0;\n let lastApplied = stored;\n\n db.transaction(() => {\n for (const m of pending) {\n m.up(db);\n db.pragma(`user_version = ${m.toVersion}`);\n lastApplied = m.toVersion;\n ran += 1;\n }\n })();\n\n return { from: stored, to: lastApplied, ran };\n}\n\n// ────────────────────── JSON versioned files ──────────────────────\n\n/**\n * Standard wrapper shape: `{ _schemaVersion: N, data: T }`. Use\n * `readVersionedJson` / `writeVersionedJson` for read/write.\n *\n * @internal\n */\nexport interface VersionedJsonFile<T> {\n _schemaVersion: number;\n data: T;\n}\n\n/**\n * Migration callback for `readVersionedJson`. Receives the FULL parsed\n * JSON object (not just `.data`), so legacy shapes without the\n * `_schemaVersion` / `data` wrapper can be migrated correctly (EC-2 fix).\n *\n * @internal\n */\nexport type VersionedJsonMigrate<T> = (parsed: unknown, fromVersion: number) => T;\n\n/**\n * Options for `readVersionedJson`.\n *\n * @internal\n */\nexport interface ReadVersionedJsonOptions<T> {\n path: string;\n currentVersion: number;\n migrate: VersionedJsonMigrate<T>;\n defaultValue: () => T;\n}\n\n/**\n * Read a versioned JSON file. Returns:\n * - file's `.data` when `_schemaVersion === currentVersion`\n * - migrated value (via `migrate(parsed, stored)`) when stored < current\n * - `defaultValue()` when file missing, corrupt, or stored > current\n *\n * Fail-soft: never throws. Corrupt or mismatched-newer files log a stderr\n * warning and fall back to `defaultValue()`.\n *\n * @internal\n */\nexport async function readVersionedJson<T>(opts: ReadVersionedJsonOptions<T>): Promise<T> {\n const { path, currentVersion, migrate, defaultValue } = opts;\n\n let raw: string;\n try {\n raw = await readFile(path, \"utf-8\");\n } catch {\n return defaultValue();\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n // T5.10 — move corrupt file aside so (a) user can investigate and\n // (b) next run starts fresh instead of hitting the same warning loop.\n const asidePath = `${path}.corrupt.${Date.now()}`;\n try {\n await rename(path, asidePath);\n diag(`[theokit-sdk] ${path} is corrupt; moved to ${asidePath}. Using default value.\\n`);\n } catch {\n diag(`[theokit-sdk] ${path} is corrupt; using default value.\\n`);\n }\n return defaultValue();\n }\n\n if (typeof parsed !== \"object\" || parsed === null) {\n return defaultValue();\n }\n\n const file = parsed as { _schemaVersion?: unknown; data?: unknown };\n const storedRaw = file._schemaVersion;\n const stored = typeof storedRaw === \"number\" ? storedRaw : 0;\n\n if (stored === currentVersion) {\n return file.data as T;\n }\n\n if (stored > currentVersion) {\n diag(\n `[theokit-sdk] ${path} schema version ${stored} > current ${currentVersion}; ` +\n \"using default value (forward-only).\\n\",\n );\n return defaultValue();\n }\n\n // EC-2 fix: pass the FULL parsed object to migrate, not just `file.data`.\n // Legacy shapes (e.g., `{ schemaVersion: \"1.0\", agents: {...} }` without\n // a `data` field) need to inspect the whole thing.\n return migrate(parsed, stored);\n}\n\n/**\n * Write `data` as a versioned JSON file via atomic write.\n *\n * @internal\n */\nexport async function writeVersionedJson<T>(\n path: string,\n data: T,\n currentVersion: number,\n): Promise<void> {\n const file: VersionedJsonFile<T> = {\n _schemaVersion: currentVersion,\n data,\n };\n await atomicWriteJson(path, file);\n}\n","/**\n * Path resolution for SDK state files (ADR D60).\n *\n * Theokit anchors state at `<cwd>/.theokit/` by default (per-cwd). An\n * optional `THEOKIT_HOME` environment variable overrides this, enabling\n * test isolation, profile switching, and multi-tenant deployments.\n *\n * Rules:\n * - `getTheokitHome(cwd)` is the canonical resolver **for cwd-anchored state**. Never hardcode\n * `path.join(cwd, \".theokit\")` in callers — use this function so tests\n * and overrides stay consistent.\n *\n * M94 — este comentário dizia \"the ONLY canonical resolver\", e deixou de ser verdade: o\n * transcript ganhou `transcriptRoot()`, que é **home-ancorado** (`~/.theokit`) com o mesmo\n * override por `THEOKIT_HOME`. Os dois defaults diferem de propósito — unificar moveria o\n * transcript de todo mundo que NÃO define a variável, que é uma migração de dados e não um\n * re-export.\n *\n * Consequência que merece estar escrita: **sem `THEOKIT_HOME` o estado segue partido em dois**\n * — registry em `<cwd>/.theokit`, transcript em `~/.theokit`. O M94 unifica só para quem define\n * a variável. Unificar os dois defaults é trabalho de outro milestone.\n * - `getProfilesRoot()` is intentionally home-anchored (not affected by\n * `THEOKIT_HOME`) so `theokit profile list` discovers all profiles\n * regardless of which is active.\n * - `displayTheokitHome(cwd)` returns a human-readable path for logs.\n *\n * @internal\n */\n\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\nconst THEOKIT_DIR_NAME = \".theokit\";\n\n/**\n * Resolve the active Theokit state directory.\n *\n * Returns the value of `THEOKIT_HOME` env var if set (and non-empty after\n * trim); otherwise returns `<cwd>/.theokit`.\n *\n * @internal\n */\nexport function getTheokitHome(cwd: string): string {\n const override = process.env.THEOKIT_HOME?.trim();\n if (override !== undefined && override.length > 0) {\n return override;\n }\n return join(cwd, THEOKIT_DIR_NAME);\n}\n\n/**\n * Profiles root is ALWAYS at `~/.theokit/profiles/`, regardless of\n * `THEOKIT_HOME`. This lets `theokit profile list` see all profiles\n * regardless of which one is currently active.\n *\n * @internal\n */\nexport function getProfilesRoot(): string {\n return join(homedir(), THEOKIT_DIR_NAME, \"profiles\");\n}\n\n/**\n * Human-readable Theokit home for log/print output. Collapses `$HOME` to\n * `~` when applicable. NEVER used for `fs.*` calls — use `getTheokitHome`\n * for those.\n *\n * @internal\n */\nexport function displayTheokitHome(cwd: string): string {\n const resolved = getTheokitHome(cwd);\n const home = homedir();\n if (resolved === home) return \"~\";\n if (resolved.startsWith(`${home}/`)) {\n return `~${resolved.slice(home.length)}`;\n }\n return resolved;\n}\n"]}
1
+ {"version":3,"sources":["../src/internal/persistence/schema-version.ts","../src/internal/persistence/paths.ts"],"names":["readFile","rename","diag","atomicWriteJson","join","homedir"],"mappings":"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","file":"chunk-LALG2K33.cjs","sourcesContent":["/**\n * Schema versioning helpers (ADR D62).\n *\n * Two parallel APIs:\n * - `migrateSchema` — SQLite via `PRAGMA user_version` + ordered forward-only migrations.\n * - `readVersionedJson` / `writeVersionedJson` — JSON files with `_schemaVersion` field.\n *\n * Forward-only: never deletes data, never downgrades. Migration callbacks\n * own the transformation; this module owns the bookkeeping.\n *\n * @internal\n */\n\nimport { readFile, rename } from \"node:fs/promises\";\nimport { diag } from \"../diagnostics.js\";\nimport { atomicWriteJson } from \"./atomic-write.js\";\n\n// ────────────────────── SQLite migrations ──────────────────────\n\n/**\n * Minimal Database interface so this file does not hard-depend on\n * `better-sqlite3` at module load time. Compatible with the runtime\n * shape exposed by `better-sqlite3`.\n *\n * @internal\n */\nexport interface SqliteLike {\n pragma: (statement: string, options?: { simple?: boolean }) => unknown;\n exec: (sql: string) => void;\n transaction: <Args extends unknown[], R>(fn: (...args: Args) => R) => (...args: Args) => R;\n}\n\n/**\n * One forward migration step. `up` receives the DB inside a transaction;\n * `toVersion` is the value the pragma will be set to AFTER `up` returns.\n *\n * @internal\n */\nexport interface Migration {\n toVersion: number;\n up: (db: SqliteLike) => void;\n}\n\n/**\n * Options for `migrateSchema`.\n *\n * @internal\n */\nexport interface MigrateSchemaOptions {\n db: SqliteLike;\n currentVersion: number;\n migrations: ReadonlyArray<Migration>;\n /** For log/error context (e.g., \"memory-index\", \"registry\"). */\n label?: string;\n}\n\n/**\n * Result of `migrateSchema`.\n *\n * @internal\n */\nexport interface MigrateSchemaResult {\n from: number;\n to: number;\n ran: number;\n}\n\n/**\n * Run pending migrations to bring the DB from its current `user_version` up\n * to `currentVersion`. Migrations are sorted ascending by `toVersion` and\n * only those `> stored && <= currentVersion` execute. Each runs inside the\n * shared transaction.\n *\n * Throws if `stored > currentVersion` (downgrade attempt — forward-only).\n *\n * @internal\n */\nexport function migrateSchema(opts: MigrateSchemaOptions): MigrateSchemaResult {\n const { db, currentVersion, migrations, label = \"db\" } = opts;\n const storedRaw = db.pragma(\"user_version\", { simple: true });\n const stored = typeof storedRaw === \"number\" ? storedRaw : 0;\n\n if (stored > currentVersion) {\n throw new Error(\n `[${label}] schema version ${stored} > current ${currentVersion}; ` +\n \"did you downgrade the SDK? Forward-only migrations only.\",\n );\n }\n\n if (stored === currentVersion) {\n return { from: stored, to: stored, ran: 0 };\n }\n\n const pending = [...migrations]\n .sort((a, b) => a.toVersion - b.toVersion)\n .filter((m) => m.toVersion > stored && m.toVersion <= currentVersion);\n\n let ran = 0;\n let lastApplied = stored;\n\n db.transaction(() => {\n for (const m of pending) {\n m.up(db);\n db.pragma(`user_version = ${m.toVersion}`);\n lastApplied = m.toVersion;\n ran += 1;\n }\n })();\n\n return { from: stored, to: lastApplied, ran };\n}\n\n// ────────────────────── JSON versioned files ──────────────────────\n\n/**\n * Standard wrapper shape: `{ _schemaVersion: N, data: T }`. Use\n * `readVersionedJson` / `writeVersionedJson` for read/write.\n *\n * @internal\n */\nexport interface VersionedJsonFile<T> {\n _schemaVersion: number;\n data: T;\n}\n\n/**\n * Migration callback for `readVersionedJson`. Receives the FULL parsed\n * JSON object (not just `.data`), so legacy shapes without the\n * `_schemaVersion` / `data` wrapper can be migrated correctly (EC-2 fix).\n *\n * @internal\n */\nexport type VersionedJsonMigrate<T> = (parsed: unknown, fromVersion: number) => T;\n\n/**\n * Options for `readVersionedJson`.\n *\n * @internal\n */\nexport interface ReadVersionedJsonOptions<T> {\n path: string;\n currentVersion: number;\n migrate: VersionedJsonMigrate<T>;\n defaultValue: () => T;\n}\n\n/**\n * Read a versioned JSON file. Returns:\n * - file's `.data` when `_schemaVersion === currentVersion`\n * - migrated value (via `migrate(parsed, stored)`) when stored < current\n * - `defaultValue()` when file missing, corrupt, or stored > current\n *\n * Fail-soft: never throws. Corrupt or mismatched-newer files log a stderr\n * warning and fall back to `defaultValue()`.\n *\n * @internal\n */\nexport async function readVersionedJson<T>(opts: ReadVersionedJsonOptions<T>): Promise<T> {\n const { path, currentVersion, migrate, defaultValue } = opts;\n\n let raw: string;\n try {\n raw = await readFile(path, \"utf-8\");\n } catch {\n return defaultValue();\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n // T5.10 — move corrupt file aside so (a) user can investigate and\n // (b) next run starts fresh instead of hitting the same warning loop.\n const asidePath = `${path}.corrupt.${Date.now()}`;\n try {\n await rename(path, asidePath);\n diag(`[theokit-sdk] ${path} is corrupt; moved to ${asidePath}. Using default value.\\n`);\n } catch {\n diag(`[theokit-sdk] ${path} is corrupt; using default value.\\n`);\n }\n return defaultValue();\n }\n\n if (typeof parsed !== \"object\" || parsed === null) {\n return defaultValue();\n }\n\n const file = parsed as { _schemaVersion?: unknown; data?: unknown };\n const storedRaw = file._schemaVersion;\n const stored = typeof storedRaw === \"number\" ? storedRaw : 0;\n\n if (stored === currentVersion) {\n return file.data as T;\n }\n\n if (stored > currentVersion) {\n diag(\n `[theokit-sdk] ${path} schema version ${stored} > current ${currentVersion}; ` +\n \"using default value (forward-only).\\n\",\n );\n return defaultValue();\n }\n\n // EC-2 fix: pass the FULL parsed object to migrate, not just `file.data`.\n // Legacy shapes (e.g., `{ schemaVersion: \"1.0\", agents: {...} }` without\n // a `data` field) need to inspect the whole thing.\n return migrate(parsed, stored);\n}\n\n/**\n * Write `data` as a versioned JSON file via atomic write.\n *\n * @internal\n */\nexport async function writeVersionedJson<T>(\n path: string,\n data: T,\n currentVersion: number,\n): Promise<void> {\n const file: VersionedJsonFile<T> = {\n _schemaVersion: currentVersion,\n data,\n };\n await atomicWriteJson(path, file);\n}\n","/**\n * Path resolution for SDK state files (ADR D60).\n *\n * Theokit anchors state at `<cwd>/.theokit/` by default (per-cwd). An\n * optional `THEOKIT_HOME` environment variable overrides this, enabling\n * test isolation, profile switching, and multi-tenant deployments.\n *\n * Rules:\n * - `getTheokitHome(cwd)` is the canonical resolver **for cwd-anchored state**. Never hardcode\n * `path.join(cwd, \".theokit\")` in callers — use this function so tests\n * and overrides stay consistent.\n *\n * M94 — this comment said \"the ONLY canonical resolver\", and stopped being true: the\n * transcript gained `transcriptRoot()`, which is **home-anchored** (`~/.theokit`) with the same\n * `THEOKIT_HOME` override. The two defaults differ on purpose — unifying would move the\n * transcript of everyone who does NOT set the variable, which is a data migration and not a\n * re-export.\n *\n * A consequence worth writing down: **without `THEOKIT_HOME` the state stays split in two**\n * — registry in `<cwd>/.theokit`, transcript in `~/.theokit`. M94 unifies only for those who set\n * the variable. Unifying both defaults is another milestone's work.\n * - `getProfilesRoot()` is intentionally home-anchored (not affected by\n * `THEOKIT_HOME`) so `theokit profile list` discovers all profiles\n * regardless of which is active.\n * - `displayTheokitHome(cwd)` returns a human-readable path for logs.\n *\n * @internal\n */\n\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\nconst THEOKIT_DIR_NAME = \".theokit\";\n\n/**\n * Resolve the active Theokit state directory.\n *\n * Returns the value of `THEOKIT_HOME` env var if set (and non-empty after\n * trim); otherwise returns `<cwd>/.theokit`.\n *\n * @internal\n */\nexport function getTheokitHome(cwd: string): string {\n const override = process.env.THEOKIT_HOME?.trim();\n if (override !== undefined && override.length > 0) {\n return override;\n }\n return join(cwd, THEOKIT_DIR_NAME);\n}\n\n/**\n * Profiles root is ALWAYS at `~/.theokit/profiles/`, regardless of\n * `THEOKIT_HOME`. This lets `theokit profile list` see all profiles\n * regardless of which one is currently active.\n *\n * @internal\n */\nexport function getProfilesRoot(): string {\n return join(homedir(), THEOKIT_DIR_NAME, \"profiles\");\n}\n\n/**\n * Human-readable Theokit home for log/print output. Collapses `$HOME` to\n * `~` when applicable. NEVER used for `fs.*` calls — use `getTheokitHome`\n * for those.\n *\n * @internal\n */\nexport function displayTheokitHome(cwd: string): string {\n const resolved = getTheokitHome(cwd);\n const home = homedir();\n if (resolved === home) return \"~\";\n if (resolved.startsWith(`${home}/`)) {\n return `~${resolved.slice(home.length)}`;\n }\n return resolved;\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { createSemaphore } from './chunk-NFCKEBHI.js';
1
+ import { createSemaphore } from './chunk-PI4RO4GR.js';
2
2
 
3
3
  // src/internal/runtime/concurrency/map-with-concurrency.ts
4
4
  var NEVER_ABORT = new AbortController().signal;
@@ -21,5 +21,5 @@ async function mapWithConcurrency(items, concurrency, fn, options) {
21
21
  }
22
22
 
23
23
  export { mapWithConcurrency };
24
- //# sourceMappingURL=chunk-QGDKZDPN.js.map
25
- //# sourceMappingURL=chunk-QGDKZDPN.js.map
24
+ //# sourceMappingURL=chunk-LGILIGV3.js.map
25
+ //# sourceMappingURL=chunk-LGILIGV3.js.map