@theokit/sdk 5.11.1 → 5.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +115 -0
- package/dist/a2a/index.cjs +8 -8
- package/dist/a2a/index.js +3 -3
- package/dist/agent-BVKIUP7F.cjs +71 -0
- package/dist/{agent-OKP4LHG2.cjs.map → agent-BVKIUP7F.cjs.map} +1 -1
- package/dist/{agent-CmKwSyyD.d.ts → agent-CVzDy_Oj.d.ts} +17 -8
- package/dist/{agent-XMkGzff_.d.cts → agent-Cn0sphpA.d.cts} +17 -8
- package/dist/agent-IG7BP6GN.js +62 -0
- package/dist/{agent-DFV52V6E.js.map → agent-IG7BP6GN.js.map} +1 -1
- package/dist/agent-prims-CZyxfCmS.d.cts +206 -0
- package/dist/agent-prims-CZyxfCmS.d.ts +206 -0
- package/dist/agent-session-store-22GKA7O4.js +6 -0
- package/dist/{agent-session-store-ODD3IZCW.js.map → agent-session-store-22GKA7O4.js.map} +1 -1
- package/dist/agent-session-store-WP6NGDVX.cjs +23 -0
- package/dist/{agent-session-store-SVEJHSUA.cjs.map → agent-session-store-WP6NGDVX.cjs.map} +1 -1
- package/dist/auth/index.cjs +33 -33
- package/dist/auth/index.js +6 -6
- package/dist/{batch-427O54FQ.js → batch-EP3FCL6D.js} +9 -9
- package/dist/{batch-427O54FQ.js.map → batch-EP3FCL6D.js.map} +1 -1
- package/dist/{batch-U4SO4RLX.cjs → batch-IZ5EDKJ5.cjs} +29 -29
- package/dist/{batch-U4SO4RLX.cjs.map → batch-IZ5EDKJ5.cjs.map} +1 -1
- package/dist/{chunk-IIYJMXYW.cjs → chunk-27V5I2WW.cjs} +4 -4
- package/dist/{chunk-IIYJMXYW.cjs.map → chunk-27V5I2WW.cjs.map} +1 -1
- package/dist/{chunk-DPY2M74T.js → chunk-2C24NSNV.js} +5 -5
- package/dist/{chunk-DPY2M74T.js.map → chunk-2C24NSNV.js.map} +1 -1
- package/dist/{chunk-7F7XE6CM.js → chunk-2S4HQCDF.js} +3 -3
- package/dist/{chunk-7F7XE6CM.js.map → chunk-2S4HQCDF.js.map} +1 -1
- package/dist/{chunk-LZJXEPEQ.js → chunk-2SFLLOMN.js} +3 -3
- package/dist/{chunk-LZJXEPEQ.js.map → chunk-2SFLLOMN.js.map} +1 -1
- package/dist/{chunk-RGQICWFU.js → chunk-354F3OF5.js} +3 -3
- package/dist/{chunk-RGQICWFU.js.map → chunk-354F3OF5.js.map} +1 -1
- package/dist/{chunk-TX56N7FR.js → chunk-3FSBE4PS.js} +4 -4
- package/dist/{chunk-TX56N7FR.js.map → chunk-3FSBE4PS.js.map} +1 -1
- package/dist/{chunk-RQMCOFAI.cjs → chunk-3HA7N2BB.cjs} +8 -8
- package/dist/{chunk-RQMCOFAI.cjs.map → chunk-3HA7N2BB.cjs.map} +1 -1
- package/dist/{chunk-GM54F4FE.cjs → chunk-3KIUY67P.cjs} +9 -9
- package/dist/{chunk-GM54F4FE.cjs.map → chunk-3KIUY67P.cjs.map} +1 -1
- package/dist/{chunk-CZJ6Q7CW.js → chunk-3OY6H3I7.js} +66 -7
- package/dist/chunk-3OY6H3I7.js.map +1 -0
- package/dist/{chunk-ZWACQM5U.cjs → chunk-3WKWBYPO.cjs} +9 -9
- package/dist/{chunk-ZWACQM5U.cjs.map → chunk-3WKWBYPO.cjs.map} +1 -1
- package/dist/{chunk-Q34EBNYG.js → chunk-4GUFNDZR.js} +5 -5
- package/dist/{chunk-Q34EBNYG.js.map → chunk-4GUFNDZR.js.map} +1 -1
- package/dist/{chunk-XDUGSTYJ.cjs → chunk-4YD2WI57.cjs} +15 -15
- package/dist/{chunk-XDUGSTYJ.cjs.map → chunk-4YD2WI57.cjs.map} +1 -1
- package/dist/{chunk-SKDNCTXG.cjs → chunk-5A4UFBHW.cjs} +15 -15
- package/dist/{chunk-SKDNCTXG.cjs.map → chunk-5A4UFBHW.cjs.map} +1 -1
- package/dist/{chunk-SUVCHX4L.js → chunk-5AR6O7GW.js} +3 -3
- package/dist/{chunk-SUVCHX4L.js.map → chunk-5AR6O7GW.js.map} +1 -1
- package/dist/{chunk-SVCPJRUB.js → chunk-5HSMH2ZZ.js} +6 -6
- package/dist/{chunk-SVCPJRUB.js.map → chunk-5HSMH2ZZ.js.map} +1 -1
- package/dist/{chunk-GTX6FEDP.js → chunk-5IRDK5BC.js} +3 -3
- package/dist/{chunk-GTX6FEDP.js.map → chunk-5IRDK5BC.js.map} +1 -1
- package/dist/{chunk-H3CVJSFC.js → chunk-5IUDICRK.js} +3 -3
- package/dist/{chunk-H3CVJSFC.js.map → chunk-5IUDICRK.js.map} +1 -1
- package/dist/{chunk-FYEHYQ7T.cjs → chunk-6CXRYPG7.cjs} +15 -15
- package/dist/{chunk-FYEHYQ7T.cjs.map → chunk-6CXRYPG7.cjs.map} +1 -1
- package/dist/{chunk-NQVWSSX2.cjs → chunk-6OCJWGVD.cjs} +12 -12
- package/dist/{chunk-NQVWSSX2.cjs.map → chunk-6OCJWGVD.cjs.map} +1 -1
- package/dist/{chunk-MPR2ISL2.cjs → chunk-6XQLTQB6.cjs} +4 -4
- package/dist/{chunk-MPR2ISL2.cjs.map → chunk-6XQLTQB6.cjs.map} +1 -1
- package/dist/{chunk-72CPLZPC.cjs → chunk-7INPXUJI.cjs} +5 -5
- package/dist/{chunk-72CPLZPC.cjs.map → chunk-7INPXUJI.cjs.map} +1 -1
- package/dist/{chunk-HG5LKFG7.cjs → chunk-7WARNHWW.cjs} +16 -16
- package/dist/{chunk-HG5LKFG7.cjs.map → chunk-7WARNHWW.cjs.map} +1 -1
- package/dist/{chunk-KIKKTW5O.cjs → chunk-7YUPSBDV.cjs} +4 -4
- package/dist/{chunk-KIKKTW5O.cjs.map → chunk-7YUPSBDV.cjs.map} +1 -1
- package/dist/{chunk-IZDDSLL2.js → chunk-AB4OPJLD.js} +6 -6
- package/dist/{chunk-IZDDSLL2.js.map → chunk-AB4OPJLD.js.map} +1 -1
- package/dist/{chunk-XERM7PDQ.js → chunk-AGO5S5WD.js} +3 -3
- package/dist/{chunk-XERM7PDQ.js.map → chunk-AGO5S5WD.js.map} +1 -1
- package/dist/{chunk-ZWFTECOE.js → chunk-AHKS3DKI.js} +3 -3
- package/dist/{chunk-ZWFTECOE.js.map → chunk-AHKS3DKI.js.map} +1 -1
- package/dist/{chunk-ECD6ER3E.cjs → chunk-AIZ6WXSL.cjs} +4 -4
- package/dist/{chunk-ECD6ER3E.cjs.map → chunk-AIZ6WXSL.cjs.map} +1 -1
- package/dist/{chunk-KO6SHCEH.js → chunk-AQW54OWQ.js} +3 -3
- package/dist/{chunk-KO6SHCEH.js.map → chunk-AQW54OWQ.js.map} +1 -1
- package/dist/{chunk-P22BZE7G.cjs → chunk-AT2PESXB.cjs} +7 -7
- package/dist/{chunk-P22BZE7G.cjs.map → chunk-AT2PESXB.cjs.map} +1 -1
- package/dist/{chunk-MHIBYKWA.js → chunk-BJ7BPLQK.js} +131 -72
- package/dist/chunk-BJ7BPLQK.js.map +1 -0
- package/dist/{chunk-HV4V63CO.js → chunk-BO3PV3OP.js} +4 -4
- package/dist/{chunk-HV4V63CO.js.map → chunk-BO3PV3OP.js.map} +1 -1
- package/dist/{chunk-GHHIJEFX.cjs → chunk-BWYC7RZG.cjs} +9 -9
- package/dist/{chunk-GHHIJEFX.cjs.map → chunk-BWYC7RZG.cjs.map} +1 -1
- package/dist/{chunk-UNFBHV46.cjs → chunk-CEGU5AVD.cjs} +9 -9
- package/dist/chunk-CEGU5AVD.cjs.map +1 -0
- package/dist/{chunk-JV7JA7BM.cjs → chunk-CGH4BCIY.cjs} +11 -11
- package/dist/{chunk-JV7JA7BM.cjs.map → chunk-CGH4BCIY.cjs.map} +1 -1
- package/dist/{chunk-L3C6CCBG.cjs → chunk-CWQPQTUZ.cjs} +21 -21
- package/dist/{chunk-L3C6CCBG.cjs.map → chunk-CWQPQTUZ.cjs.map} +1 -1
- package/dist/{chunk-X3LOJJMO.js → chunk-DF77RBF4.js} +9 -9
- package/dist/{chunk-X3LOJJMO.js.map → chunk-DF77RBF4.js.map} +1 -1
- package/dist/{chunk-7NQ7HJ3E.cjs → chunk-EPANMGH7.cjs} +8 -7
- package/dist/chunk-EPANMGH7.cjs.map +1 -0
- package/dist/{chunk-NKIQTLFA.cjs → chunk-EQ5IDL6W.cjs} +4 -4
- package/dist/{chunk-NKIQTLFA.cjs.map → chunk-EQ5IDL6W.cjs.map} +1 -1
- package/dist/{chunk-D5KXKBEN.cjs → chunk-FEAWEBWN.cjs} +5 -5
- package/dist/{chunk-D5KXKBEN.cjs.map → chunk-FEAWEBWN.cjs.map} +1 -1
- package/dist/{chunk-NJSIAJEK.cjs → chunk-FLDMPVUC.cjs} +4 -4
- package/dist/{chunk-NJSIAJEK.cjs.map → chunk-FLDMPVUC.cjs.map} +1 -1
- package/dist/{chunk-ASK2OQM5.cjs → chunk-G7XBVM3T.cjs} +5 -5
- package/dist/{chunk-ASK2OQM5.cjs.map → chunk-G7XBVM3T.cjs.map} +1 -1
- package/dist/{chunk-U27XHOEF.js → chunk-H7G65PNI.js} +5 -5
- package/dist/{chunk-U27XHOEF.js.map → chunk-H7G65PNI.js.map} +1 -1
- package/dist/{chunk-JW3GVLM6.cjs → chunk-H7HD6RXO.cjs} +4 -4
- package/dist/{chunk-JW3GVLM6.cjs.map → chunk-H7HD6RXO.cjs.map} +1 -1
- package/dist/{chunk-ZHWKT2NI.js → chunk-HJ2LV464.js} +3 -3
- package/dist/{chunk-ZHWKT2NI.js.map → chunk-HJ2LV464.js.map} +1 -1
- package/dist/{chunk-KGZ66JVZ.cjs → chunk-HN4IKB6X.cjs} +14 -14
- package/dist/{chunk-KGZ66JVZ.cjs.map → chunk-HN4IKB6X.cjs.map} +1 -1
- package/dist/{chunk-XKMVJ443.js → chunk-HWMGR3HA.js} +6 -6
- package/dist/{chunk-XKMVJ443.js.map → chunk-HWMGR3HA.js.map} +1 -1
- package/dist/{chunk-EQ5NCH2Y.cjs → chunk-IO4RI5ZJ.cjs} +24 -24
- package/dist/{chunk-EQ5NCH2Y.cjs.map → chunk-IO4RI5ZJ.cjs.map} +1 -1
- package/dist/{chunk-OLSEWLK5.cjs → chunk-IOFMRS6T.cjs} +6 -6
- package/dist/{chunk-OLSEWLK5.cjs.map → chunk-IOFMRS6T.cjs.map} +1 -1
- package/dist/{chunk-7QJYKVP6.js → chunk-KCM3RMKR.js} +3 -3
- package/dist/{chunk-7QJYKVP6.js.map → chunk-KCM3RMKR.js.map} +1 -1
- package/dist/{chunk-7KIN3L2S.js → chunk-KU5O7WPK.js} +3 -3
- package/dist/{chunk-7KIN3L2S.js.map → chunk-KU5O7WPK.js.map} +1 -1
- package/dist/{chunk-J5623RIV.cjs → chunk-KX5QXLBS.cjs} +10 -10
- package/dist/{chunk-J5623RIV.cjs.map → chunk-KX5QXLBS.cjs.map} +1 -1
- package/dist/{chunk-J6GXS5A2.cjs → chunk-L7JPXZ2C.cjs} +17 -17
- package/dist/{chunk-J6GXS5A2.cjs.map → chunk-L7JPXZ2C.cjs.map} +1 -1
- package/dist/{chunk-P7NNKEWO.cjs → chunk-L7V4DDIE.cjs} +4 -4
- package/dist/{chunk-P7NNKEWO.cjs.map → chunk-L7V4DDIE.cjs.map} +1 -1
- package/dist/chunk-LO6LIUZ6.cjs +18 -0
- package/dist/{chunk-SGC7LSHF.cjs.map → chunk-LO6LIUZ6.cjs.map} +1 -1
- package/dist/{chunk-P5N3Q2NH.cjs → chunk-LSWHDOCL.cjs} +192 -148
- package/dist/chunk-LSWHDOCL.cjs.map +1 -0
- package/dist/{chunk-3JHIFQ4I.js → chunk-M4U24U6G.js} +3 -3
- package/dist/{chunk-3JHIFQ4I.js.map → chunk-M4U24U6G.js.map} +1 -1
- package/dist/{chunk-GGRPAQ3B.js → chunk-MLGETTYX.js} +5 -5
- package/dist/{chunk-GGRPAQ3B.js.map → chunk-MLGETTYX.js.map} +1 -1
- package/dist/{chunk-XZHJYSPB.js → chunk-MLJDW2YK.js} +4 -4
- package/dist/{chunk-XZHJYSPB.js.map → chunk-MLJDW2YK.js.map} +1 -1
- package/dist/{chunk-5Q4RTLMP.js → chunk-MS3TQSXU.js} +3 -3
- package/dist/{chunk-5Q4RTLMP.js.map → chunk-MS3TQSXU.js.map} +1 -1
- package/dist/{chunk-W2ZVTEOD.js → chunk-MSEL5E5P.js} +6 -6
- package/dist/{chunk-W2ZVTEOD.js.map → chunk-MSEL5E5P.js.map} +1 -1
- package/dist/{chunk-ZAM7BJXJ.cjs → chunk-MSW7LB2V.cjs} +5 -5
- package/dist/{chunk-ZAM7BJXJ.cjs.map → chunk-MSW7LB2V.cjs.map} +1 -1
- package/dist/{chunk-GMSRRJ53.js → chunk-NBNRQN6T.js} +5 -4
- package/dist/chunk-NBNRQN6T.js.map +1 -0
- package/dist/{chunk-7HUCU3KK.js → chunk-NHOEXFZT.js} +5 -5
- package/dist/{chunk-7HUCU3KK.js.map → chunk-NHOEXFZT.js.map} +1 -1
- package/dist/{chunk-6G4IRQUD.js → chunk-NJBJ3CUG.js} +6 -6
- package/dist/{chunk-6G4IRQUD.js.map → chunk-NJBJ3CUG.js.map} +1 -1
- package/dist/{chunk-I2ORT6QD.js → chunk-NKQVLWDF.js} +3 -3
- package/dist/{chunk-I2ORT6QD.js.map → chunk-NKQVLWDF.js.map} +1 -1
- package/dist/{chunk-N7KS3TIR.cjs → chunk-NP362THY.cjs} +28 -15
- package/dist/chunk-NP362THY.cjs.map +1 -0
- package/dist/{chunk-NWS2CS3Y.cjs → chunk-NWWTYBD3.cjs} +5 -5
- package/dist/{chunk-NWS2CS3Y.cjs.map → chunk-NWWTYBD3.cjs.map} +1 -1
- package/dist/{chunk-SVQIW5RJ.js → chunk-OLJOI4LK.js} +4 -4
- package/dist/{chunk-SVQIW5RJ.js.map → chunk-OLJOI4LK.js.map} +1 -1
- package/dist/{chunk-7JAKO3NM.js → chunk-ORLTGPOS.js} +3 -3
- package/dist/{chunk-7JAKO3NM.js.map → chunk-ORLTGPOS.js.map} +1 -1
- package/dist/{chunk-5DD4NJN3.js → chunk-PKRPV3R7.js} +3 -3
- package/dist/{chunk-5DD4NJN3.js.map → chunk-PKRPV3R7.js.map} +1 -1
- package/dist/{chunk-R5YPDAKD.cjs → chunk-POBZXULR.cjs} +4 -4
- package/dist/{chunk-R5YPDAKD.cjs.map → chunk-POBZXULR.cjs.map} +1 -1
- package/dist/{chunk-35KBC4BX.cjs → chunk-Q6WT5535.cjs} +446 -387
- package/dist/chunk-Q6WT5535.cjs.map +1 -0
- package/dist/{chunk-MQGSOKR3.js → chunk-Q7UG242V.js} +3 -3
- package/dist/{chunk-MQGSOKR3.js.map → chunk-Q7UG242V.js.map} +1 -1
- package/dist/{chunk-XKZFIP7Z.cjs → chunk-QG4SXZ2A.cjs} +4 -4
- package/dist/{chunk-XKZFIP7Z.cjs.map → chunk-QG4SXZ2A.cjs.map} +1 -1
- package/dist/{chunk-NAGPKWOD.cjs → chunk-QISSETTG.cjs} +4 -4
- package/dist/{chunk-NAGPKWOD.cjs.map → chunk-QISSETTG.cjs.map} +1 -1
- package/dist/{chunk-OR6XIWLB.js → chunk-QK2ERTO3.js} +4 -4
- package/dist/{chunk-OR6XIWLB.js.map → chunk-QK2ERTO3.js.map} +1 -1
- package/dist/{chunk-ZDYDBXSD.js → chunk-RN3XDZGS.js} +6 -6
- package/dist/{chunk-ZDYDBXSD.js.map → chunk-RN3XDZGS.js.map} +1 -1
- package/dist/{chunk-6LHQPOMI.cjs → chunk-RNXXYF22.cjs} +66 -7
- package/dist/chunk-RNXXYF22.cjs.map +1 -0
- package/dist/{chunk-TMKTSYDS.cjs → chunk-RS7YQR4X.cjs} +6 -6
- package/dist/{chunk-TMKTSYDS.cjs.map → chunk-RS7YQR4X.cjs.map} +1 -1
- package/dist/{chunk-HU666T3Q.cjs → chunk-S46WJTDL.cjs} +14 -14
- package/dist/{chunk-HU666T3Q.cjs.map → chunk-S46WJTDL.cjs.map} +1 -1
- package/dist/{chunk-ZD66GFH5.cjs → chunk-SDZ4XDWS.cjs} +35 -35
- package/dist/{chunk-ZD66GFH5.cjs.map → chunk-SDZ4XDWS.cjs.map} +1 -1
- package/dist/{chunk-ZJZ7LV3A.js → chunk-SV63WTA2.js} +3 -3
- package/dist/{chunk-ZJZ7LV3A.js.map → chunk-SV63WTA2.js.map} +1 -1
- package/dist/{chunk-CQYBJOB2.cjs → chunk-SXH37C7X.cjs} +4 -4
- package/dist/{chunk-CQYBJOB2.cjs.map → chunk-SXH37C7X.cjs.map} +1 -1
- package/dist/{chunk-GMRFAX4I.js → chunk-SZQFCHU6.js} +4 -4
- package/dist/{chunk-GMRFAX4I.js.map → chunk-SZQFCHU6.js.map} +1 -1
- package/dist/{chunk-6PB5AQCY.cjs → chunk-TLVI2OQK.cjs} +16 -16
- package/dist/{chunk-6PB5AQCY.cjs.map → chunk-TLVI2OQK.cjs.map} +1 -1
- package/dist/{chunk-B5MHRQJZ.js → chunk-TNFOU6SB.js} +3 -3
- package/dist/chunk-TNFOU6SB.js.map +1 -0
- package/dist/{chunk-N6OEX5TN.cjs → chunk-UDAKAE4Z.cjs} +16 -16
- package/dist/{chunk-N6OEX5TN.cjs.map → chunk-UDAKAE4Z.cjs.map} +1 -1
- package/dist/{chunk-26NEAJ6T.js → chunk-VVGFZQZC.js} +4 -4
- package/dist/{chunk-26NEAJ6T.js.map → chunk-VVGFZQZC.js.map} +1 -1
- package/dist/{chunk-XCQ432OX.js → chunk-VZGE7NAI.js} +3 -3
- package/dist/{chunk-XCQ432OX.js.map → chunk-VZGE7NAI.js.map} +1 -1
- package/dist/{chunk-C7GKRGKN.cjs → chunk-WDVG5R2Q.cjs} +19 -19
- package/dist/{chunk-C7GKRGKN.cjs.map → chunk-WDVG5R2Q.cjs.map} +1 -1
- package/dist/{chunk-FTZTZBCU.js → chunk-XESYJ4JC.js} +4 -4
- package/dist/{chunk-FTZTZBCU.js.map → chunk-XESYJ4JC.js.map} +1 -1
- package/dist/{chunk-OPAKPEPG.js → chunk-XJ3WU5CZ.js} +5 -5
- package/dist/{chunk-OPAKPEPG.js.map → chunk-XJ3WU5CZ.js.map} +1 -1
- package/dist/{chunk-BBJ77S62.js → chunk-XJ4C4NFX.js} +64 -20
- package/dist/chunk-XJ4C4NFX.js.map +1 -0
- package/dist/{chunk-AY43232P.js → chunk-XRPMZ7TO.js} +4 -4
- package/dist/{chunk-AY43232P.js.map → chunk-XRPMZ7TO.js.map} +1 -1
- package/dist/{chunk-X6DUEDAF.js → chunk-XZKIAENA.js} +3 -3
- package/dist/{chunk-X6DUEDAF.js.map → chunk-XZKIAENA.js.map} +1 -1
- package/dist/{chunk-X7EUUHXU.js → chunk-YMVTUV5K.js} +3 -3
- package/dist/{chunk-X7EUUHXU.js.map → chunk-YMVTUV5K.js.map} +1 -1
- package/dist/{chunk-3JANYJYS.cjs → chunk-YOVZMN4P.cjs} +8 -8
- package/dist/{chunk-3JANYJYS.cjs.map → chunk-YOVZMN4P.cjs.map} +1 -1
- package/dist/{chunk-TY56BKSK.cjs → chunk-YQ3XC6C2.cjs} +4 -4
- package/dist/{chunk-TY56BKSK.cjs.map → chunk-YQ3XC6C2.cjs.map} +1 -1
- package/dist/{chunk-JLIRFWUG.js → chunk-ZJAYFSVI.js} +22 -9
- package/dist/chunk-ZJAYFSVI.js.map +1 -0
- package/dist/{chunk-MU7IAA7G.js → chunk-ZLFFDPXC.js} +9 -9
- package/dist/{chunk-MU7IAA7G.js.map → chunk-ZLFFDPXC.js.map} +1 -1
- package/dist/{chunk-JLRLCBJ4.cjs → chunk-ZOFRNNZD.cjs} +4 -4
- package/dist/{chunk-JLRLCBJ4.cjs.map → chunk-ZOFRNNZD.cjs.map} +1 -1
- package/dist/{chunk-MPQJE3G4.cjs → chunk-ZWLFHSON.cjs} +15 -15
- package/dist/{chunk-MPQJE3G4.cjs.map → chunk-ZWLFHSON.cjs.map} +1 -1
- package/dist/compact-session-3U2JYTVG.js +25 -0
- package/dist/{compact-session-4HAUP3HK.js.map → compact-session-3U2JYTVG.js.map} +1 -1
- package/dist/{compact-session-Y56D3S57.cjs → compact-session-NM56BREJ.cjs} +24 -24
- package/dist/{compact-session-Y56D3S57.cjs.map → compact-session-NM56BREJ.cjs.map} +1 -1
- package/dist/compaction.cjs +18 -18
- package/dist/compaction.js +3 -3
- package/dist/concurrency.cjs +6 -6
- package/dist/concurrency.js +4 -4
- package/dist/context/index.cjs +9 -9
- package/dist/context/index.js +6 -6
- package/dist/context-4RSI3AXT.cjs +24 -0
- package/dist/{context-B5J4GX2F.cjs.map → context-4RSI3AXT.cjs.map} +1 -1
- package/dist/context-7EBZST3L.js +7 -0
- package/dist/{context-3FZRAO5K.js.map → context-7EBZST3L.js.map} +1 -1
- package/dist/{cron-Blj6wMYg.d.cts → cron-BWDYetbq.d.cts} +2 -2
- package/dist/{cron-BPccQCO8.d.ts → cron-CHn-F0fC.d.ts} +2 -2
- package/dist/cron.cjs +42 -42
- package/dist/cron.d.cts +4 -4
- package/dist/cron.d.ts +4 -4
- package/dist/cron.js +41 -41
- package/dist/{errors-BWOJeWTZ.d.cts → errors-BiDQFWTG.d.cts} +10 -7
- package/dist/{errors-DDvG18IB.d.ts → errors-Pf22PJJ-.d.ts} +10 -7
- package/dist/errors.cjs +23 -23
- package/dist/errors.d.cts +2 -3
- package/dist/errors.d.ts +2 -3
- package/dist/errors.js +2 -2
- package/dist/eval.cjs +54 -54
- package/dist/eval.js +42 -42
- package/dist/{executor-3NI7KNL4.js → executor-3D2UDJHW.js} +8 -8
- package/dist/{executor-3NI7KNL4.js.map → executor-3D2UDJHW.js.map} +1 -1
- package/dist/{executor-2SUGI3ZT.cjs → executor-HKHT4CWS.cjs} +26 -26
- package/dist/{executor-2SUGI3ZT.cjs.map → executor-HKHT4CWS.cjs.map} +1 -1
- package/dist/filesystem/index.cjs +12 -12
- package/dist/filesystem/index.js +3 -3
- package/dist/fs-session-store-6ZCCJX3K.js +11 -0
- package/dist/{fs-session-store-3VI4CPTX.js.map → fs-session-store-6ZCCJX3K.js.map} +1 -1
- package/dist/fs-session-store-S2AXVJIX.cjs +20 -0
- package/dist/{fs-session-store-IQ6PEHYF.cjs.map → fs-session-store-S2AXVJIX.cjs.map} +1 -1
- package/dist/generate-object-S7MNVF2V.js +7 -0
- package/dist/{generate-object-NTKAWE7D.js.map → generate-object-S7MNVF2V.js.map} +1 -1
- package/dist/generate-object-XBWD2PU7.cjs +20 -0
- package/dist/{generate-object-YHTWG5DB.cjs.map → generate-object-XBWD2PU7.cjs.map} +1 -1
- package/dist/index-manager-HO456AVW.cjs +27 -0
- package/dist/{index-manager-YGXRFJMZ.cjs.map → index-manager-HO456AVW.cjs.map} +1 -1
- package/dist/index-manager-QDH56FER.js +18 -0
- package/dist/{index-manager-JVYIVTZG.js.map → index-manager-QDH56FER.js.map} +1 -1
- package/dist/index.cjs +172 -172
- package/dist/index.d.cts +9 -9
- package/dist/index.d.ts +9 -9
- package/dist/index.js +59 -59
- package/dist/{inject-session-R73PRM7B.cjs → inject-session-JVTZNQF6.cjs} +9 -9
- package/dist/{inject-session-R73PRM7B.cjs.map → inject-session-JVTZNQF6.cjs.map} +1 -1
- package/dist/{inject-session-LJX5JGV5.js → inject-session-THABTKJY.js} +7 -7
- package/dist/{inject-session-LJX5JGV5.js.map → inject-session-THABTKJY.js.map} +1 -1
- package/dist/interactive/index.cjs +4 -4
- package/dist/interactive/index.js +2 -2
- package/dist/internal/budget/normalize-usage.d.ts +5 -1
- package/dist/internal/error-mappers/openai-compatible.d.ts +3 -1
- package/dist/internal/memory/adapters/index.cjs +8 -8
- package/dist/internal/memory/adapters/index.js +7 -7
- package/dist/internal/memory/storage/index.cjs +42 -42
- package/dist/internal/memory/storage/index.js +10 -10
- package/dist/internal/persistence/index.cjs +25 -25
- package/dist/internal/persistence/index.js +8 -8
- package/dist/internal/providers/catalog-schema.d.ts +1 -1
- package/dist/internal/runtime/lifecycle/throw-on-error-run.d.ts +18 -0
- package/dist/internal/runtime/model-selection.d.ts +1 -1
- package/dist/internal/runtime/system-prompt/native-reasoning.d.ts +2 -2
- package/dist/internal/runtime/typed-run-error.d.ts +16 -0
- package/dist/internal/security/index.cjs +13 -13
- package/dist/internal/security/index.js +3 -3
- package/dist/judge-call-4LR4IFVT.js +5 -0
- package/dist/{judge-call-LOL5FQEX.js.map → judge-call-4LR4IFVT.js.map} +1 -1
- package/dist/judge-call-ZTUQMQRL.cjs +22 -0
- package/dist/{judge-call-AQQYK6VT.cjs.map → judge-call-ZTUQMQRL.cjs.map} +1 -1
- package/dist/mcp-auth.cjs +14 -14
- package/dist/mcp-auth.js +4 -4
- package/dist/models.cjs +22 -22
- package/dist/models.js +8 -8
- package/dist/oauth-transaction-store-OMX436YB.cjs +38 -0
- package/dist/{oauth-transaction-store-ZINDV7AF.cjs.map → oauth-transaction-store-OMX436YB.cjs.map} +1 -1
- package/dist/oauth-transaction-store-U34YLEGP.js +5 -0
- package/dist/{oauth-transaction-store-NP2YHZ6D.js.map → oauth-transaction-store-U34YLEGP.js.map} +1 -1
- package/dist/path-safety.cjs +10 -10
- package/dist/path-safety.js +3 -3
- package/dist/persistence.cjs +31 -31
- package/dist/persistence.js +10 -10
- package/dist/project.cjs +5 -5
- package/dist/project.js +3 -3
- package/dist/providers.cjs +9 -9
- package/dist/providers.js +7 -7
- package/dist/registry-5TDAF7RK.js +9 -0
- package/dist/{registry-5FK42CRV.js.map → registry-5TDAF7RK.js.map} +1 -1
- package/dist/registry-W7TSCLQO.cjs +46 -0
- package/dist/{registry-BVTNO73E.cjs.map → registry-W7TSCLQO.cjs.map} +1 -1
- package/dist/retry.cjs +4 -4
- package/dist/retry.js +3 -3
- package/dist/{run-until-DG2KXWB2.cjs → run-until-4KHVF7YC.cjs} +8 -4
- package/dist/run-until-4KHVF7YC.cjs.map +1 -0
- package/dist/{run-until-6D6TQ4JN.js → run-until-G6BW2DWM.js} +8 -4
- package/dist/run-until-G6BW2DWM.js.map +1 -0
- package/dist/sandbox/index.cjs +114 -41
- package/dist/sandbox/index.cjs.map +1 -1
- package/dist/sandbox/index.js +99 -26
- package/dist/sandbox/index.js.map +1 -1
- package/dist/sandbox/linux-sandbox.d.cts +24 -4
- package/dist/sandbox/linux-sandbox.d.ts +24 -4
- package/dist/sandbox/seccomp-delivery.d.cts +46 -0
- package/dist/sandbox/seccomp-delivery.d.ts +46 -0
- package/dist/{run-DsA5Ip2i.d.cts → sdk-agent-4-dXI2GS.d.cts} +1500 -753
- package/dist/{run-DsA5Ip2i.d.ts → sdk-agent-CTOJlWA_.d.ts} +1500 -753
- package/dist/server/auth/index.cjs +22 -22
- package/dist/server/auth/index.js +7 -7
- package/dist/server/errors-envelope.cjs +14 -14
- package/dist/server/errors-envelope.d.cts +2 -3
- package/dist/server/errors-envelope.d.ts +2 -3
- package/dist/server/errors-envelope.js +3 -3
- package/dist/session-transcript-7TZ6HXSX.cjs +62 -0
- package/dist/{session-transcript-RACG7BK2.cjs.map → session-transcript-7TZ6HXSX.cjs.map} +1 -1
- package/dist/session-transcript-BSHZYYY6.js +5 -0
- package/dist/{session-transcript-AR7IBICT.js.map → session-transcript-BSHZYYY6.js.map} +1 -1
- package/dist/skills.cjs +8 -8
- package/dist/skills.js +5 -5
- package/dist/stream-object-R6SMYV4R.js +7 -0
- package/dist/{stream-object-QAEHG4YO.js.map → stream-object-R6SMYV4R.js.map} +1 -1
- package/dist/stream-object-TEEK3CAX.cjs +20 -0
- package/dist/{stream-object-TKVGGA54.cjs.map → stream-object-TEEK3CAX.cjs.map} +1 -1
- package/dist/subagents-loader-TXOA5EJJ.cjs +16 -0
- package/dist/{subagents-loader-5TZCAIYQ.cjs.map → subagents-loader-TXOA5EJJ.cjs.map} +1 -1
- package/dist/subagents-loader-Z744TAKD.js +7 -0
- package/dist/{subagents-loader-PEV3PD4Q.js.map → subagents-loader-Z744TAKD.js.map} +1 -1
- package/dist/subagents-loader.cjs +7 -7
- package/dist/subagents-loader.d.cts +4 -3
- package/dist/subagents-loader.d.ts +4 -3
- package/dist/subagents-loader.js +5 -5
- package/dist/subscription/index.cjs +3 -3
- package/dist/subscription/index.js +2 -2
- package/dist/task-store.cjs +7 -7
- package/dist/task-store.js +4 -4
- package/dist/types/agent-prims.d.ts +16 -0
- package/dist/types/agent.d.ts +15 -6
- package/dist/types/run.d.ts +14 -14
- package/dist/workflow.cjs +27 -27
- package/dist/workflow.d.cts +2 -2
- package/dist/workflow.d.ts +2 -2
- package/dist/workflow.js +6 -6
- package/docs/error-codes.md +24 -23
- package/docs/harness-capability-map.md +5 -5
- package/package.json +1 -1
- package/dist/agent-DFV52V6E.js +0 -62
- package/dist/agent-OKP4LHG2.cjs +0 -71
- package/dist/agent-session-store-ODD3IZCW.js +0 -6
- package/dist/agent-session-store-SVEJHSUA.cjs +0 -23
- package/dist/chunk-35KBC4BX.cjs.map +0 -1
- package/dist/chunk-6LHQPOMI.cjs.map +0 -1
- package/dist/chunk-7NQ7HJ3E.cjs.map +0 -1
- package/dist/chunk-B5MHRQJZ.js.map +0 -1
- package/dist/chunk-BBJ77S62.js.map +0 -1
- package/dist/chunk-CZJ6Q7CW.js.map +0 -1
- package/dist/chunk-GMSRRJ53.js.map +0 -1
- package/dist/chunk-JLIRFWUG.js.map +0 -1
- package/dist/chunk-MHIBYKWA.js.map +0 -1
- package/dist/chunk-N7KS3TIR.cjs.map +0 -1
- package/dist/chunk-P5N3Q2NH.cjs.map +0 -1
- package/dist/chunk-SGC7LSHF.cjs +0 -18
- package/dist/chunk-UNFBHV46.cjs.map +0 -1
- package/dist/compact-session-4HAUP3HK.js +0 -25
- package/dist/context-3FZRAO5K.js +0 -7
- package/dist/context-B5J4GX2F.cjs +0 -24
- package/dist/fs-session-store-3VI4CPTX.js +0 -11
- package/dist/fs-session-store-IQ6PEHYF.cjs +0 -20
- package/dist/generate-object-NTKAWE7D.js +0 -7
- package/dist/generate-object-YHTWG5DB.cjs +0 -20
- package/dist/index-manager-JVYIVTZG.js +0 -18
- package/dist/index-manager-YGXRFJMZ.cjs +0 -27
- package/dist/judge-call-AQQYK6VT.cjs +0 -22
- package/dist/judge-call-LOL5FQEX.js +0 -5
- package/dist/oauth-transaction-store-NP2YHZ6D.js +0 -5
- package/dist/oauth-transaction-store-ZINDV7AF.cjs +0 -38
- package/dist/registry-5FK42CRV.js +0 -9
- package/dist/registry-BVTNO73E.cjs +0 -46
- package/dist/run-until-6D6TQ4JN.js.map +0 -1
- package/dist/run-until-DG2KXWB2.cjs.map +0 -1
- package/dist/sdk-agent-dNwjwCt5.d.cts +0 -940
- package/dist/sdk-agent-wEOLXD3F.d.ts +0 -940
- package/dist/session-transcript-AR7IBICT.js +0 -5
- package/dist/session-transcript-RACG7BK2.cjs +0 -62
- package/dist/stream-object-QAEHG4YO.js +0 -7
- package/dist/stream-object-TKVGGA54.cjs +0 -20
- package/dist/subagents-loader-5TZCAIYQ.cjs +0 -16
- package/dist/subagents-loader-PEV3PD4Q.js +0 -7
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunk3WKWBYPO_cjs = require('./chunk-3WKWBYPO.cjs');
|
|
4
4
|
|
|
5
5
|
// src/internal/session/agent-session-store.ts
|
|
6
6
|
function seedTranscript(prior, opts) {
|
|
7
|
-
return
|
|
7
|
+
return chunk3WKWBYPO_cjs.SessionTranscript.fromRecords(prior, opts);
|
|
8
8
|
}
|
|
9
9
|
function applyThinkingStep(assistant, message) {
|
|
10
10
|
assistant.thinking = message.text;
|
|
@@ -46,7 +46,7 @@ function appendConversation(transcript, conversation) {
|
|
|
46
46
|
}
|
|
47
47
|
async function readSessionMessages(store, agentId) {
|
|
48
48
|
const records = await store.readRecords(agentId);
|
|
49
|
-
return
|
|
49
|
+
return chunk3WKWBYPO_cjs.reconstructMessages(records).map(narrowToSessionMessage);
|
|
50
50
|
}
|
|
51
51
|
function partToText(p) {
|
|
52
52
|
if (p.type === "text") return p.text ?? "";
|
|
@@ -105,5 +105,5 @@ async function appendCompactBoundaryRecord(store, loc, sessionId, meta) {
|
|
|
105
105
|
exports.appendCompactBoundaryRecord = appendCompactBoundaryRecord;
|
|
106
106
|
exports.persistTurn = persistTurn;
|
|
107
107
|
exports.readSessionMessages = readSessionMessages;
|
|
108
|
-
//# sourceMappingURL=chunk-
|
|
109
|
-
//# sourceMappingURL=chunk-
|
|
108
|
+
//# sourceMappingURL=chunk-MSW7LB2V.cjs.map
|
|
109
|
+
//# sourceMappingURL=chunk-MSW7LB2V.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/internal/session/agent-session-store.ts"],"names":["SessionTranscript","reconstructMessages"],"mappings":"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","file":"chunk-ZAM7BJXJ.cjs","sourcesContent":["/**\n * SE40 — native session store over the Claude-shaped `.jsonl` transcript.\n *\n * The theokit session format IS the Claude Code record shape (see\n * `../../persistence/session-transcript.ts`). This module owns the FS lifecycle:\n * read existing records, seed a {@link SessionTranscript}'s parent chain, append\n * the new turn (user + assistant/tool blocks), and write append-only. Compaction\n * appends a `compact_boundary` record (a new root) — it NEVER shrinks the line\n * set (that would break the DAG). Reads reconstruct `LlmMessage[]` via\n * {@link reconstructMessages}, narrowed to the in-memory {@link SessionMessage}.\n *\n * @internal\n */\n\nimport type { ToolResultContentBlock } from \"../../types/content-blocks.js\";\nimport type { ConversationStep, ConversationTurn } from \"../../types/conversation.js\";\nimport type { SessionStore } from \"../../types/session-store.js\";\nimport {\n type AssistantTurn,\n reconstructMessages,\n type SessionRecord,\n SessionTranscript,\n} from \"../persistence/session-transcript.js\";\nimport type { SessionMessage, SessionMessagePart } from \"./types.js\";\n\n/**\n * Seed a {@link SessionTranscript} from the already-on-disk records so a new\n * append parents correctly on the existing DAG leaf. The transcript re-emits the\n * seeded records verbatim before the new turn, so the whole file rewrites atomically\n * as one append-only line set. Returns the transcript primed with the prior records.\n */\nfunction seedTranscript(\n prior: readonly SessionRecord[],\n opts: { cwd: string; sessionId: string; model: string },\n): SessionTranscript {\n return SessionTranscript.fromRecords(prior, opts);\n}\n\n/** The turn to persist: the user's text plus the rich per-turn conversation view. */\nexport interface PersistTurnInput {\n userText: string;\n conversation: readonly ConversationTurn[];\n /**\n * M50 — when supplied, size-driven auto-compaction runs in the SAME write chain after the turn\n * persists (usage real vs the model's context window; summarizer injected by the caller).\n */\n autoCompact?: {\n usageTotal?: number | undefined;\n contextWindow?: number | undefined;\n summarize: (\n messages: readonly import(\"../../compaction.js\").CompressibleMessage[],\n ) => Promise<string>;\n };\n}\n\ninterface MappedTurn {\n assistant: AssistantTurn;\n toolResults: Array<{ toolUseId: string; content: string; isError?: boolean }>;\n}\n\n/**\n * theokit#122 — record the turn's thinking block, signature included.\n *\n * The signature is what makes the block replayable: without it the resumed turn is rejected by\n * Anthropic with `400 \"thinking blocks cannot be modified\"`.\n */\nfunction applyThinkingStep(\n assistant: AssistantTurn,\n message: { text: string; signature?: string },\n): void {\n assistant.thinking = message.text;\n if (message.signature !== undefined) assistant.thinkingSignature = message.signature;\n}\n\n/** Fold one agent turn's steps into an assistant record + paired tool results. */\nfunction mapAgentTurn(steps: readonly ConversationStep[]): MappedTurn {\n const assistant: AssistantTurn = {};\n const toolResults: MappedTurn[\"toolResults\"] = [];\n const toolCalls: NonNullable<AssistantTurn[\"toolCalls\"]> = [];\n for (const step of steps) {\n if (step.type === \"thinkingMessage\") applyThinkingStep(assistant, step.message);\n else if (step.type === \"assistantMessage\") assistant.text = step.message.text;\n else if (step.type === \"toolCall\")\n toolCalls.push({\n id: step.message.callId,\n name: step.message.name,\n input: (step.message.args as Record<string, unknown> | undefined) ?? {},\n });\n else\n toolResults.push({\n toolUseId: step.message.callId,\n content: step.message.result,\n isError: step.message.isError,\n });\n }\n if (toolCalls.length > 0) assistant.toolCalls = toolCalls;\n return { assistant, toolResults };\n}\n\n/** True when the assistant record carries any content worth emitting. */\nfunction hasAssistantContent(a: AssistantTurn): boolean {\n return a.text !== undefined || a.thinking !== undefined || (a.toolCalls?.length ?? 0) > 0;\n}\n\n/**\n * Map the rich `ConversationTurn[]` (from `run.conversation()`) into the native\n * assistant/tool records. One transcript turn is: an `assistant` record carrying\n * thinking + text + tool_use blocks, then (when present) a `user` record carrying\n * the paired tool_result blocks. Tool results pair with tool_use by `callId`.\n */\nfunction appendConversation(\n transcript: SessionTranscript,\n conversation: readonly ConversationTurn[],\n): void {\n for (const ct of conversation) {\n if (ct.type !== \"agentConversationTurn\") continue;\n const { assistant, toolResults } = mapAgentTurn(ct.turn.steps);\n if (hasAssistantContent(assistant)) transcript.appendAssistantTurn(assistant);\n if (toolResults.length > 0) transcript.appendToolResults(toolResults);\n }\n}\n\n/**\n * The per-agent transcript metadata used to seed a {@link SessionTranscript}. The\n * actual record I/O goes through the injected {@link SessionStore} (SE41), so this\n * no longer carries a `baseDir` — the store is already bound to its location.\n */\nexport interface TranscriptLocation {\n cwd: string;\n agentId: string;\n model: string;\n}\n\n/**\n * Read the session's records via the {@link SessionStore} and reconstruct the\n * resumable history, narrowed to the in-memory {@link SessionMessage} shape\n * (user/assistant text). Tool turns fold into assistant-role context so resume\n * keeps tool history. Works identically for the FS default and an external store.\n */\nexport async function readSessionMessages(\n store: SessionStore,\n agentId: string,\n): Promise<SessionMessage[]> {\n const records = await store.readRecords(agentId);\n return reconstructMessages(records).map(narrowToSessionMessage);\n}\n\ntype NarrowPart = {\n type: string;\n text?: string;\n content?: unknown;\n name?: string;\n id?: string;\n toolUseId?: string;\n input?: unknown;\n isError?: boolean;\n};\n\n/** Render one reconstructed content part as folded session text. */\nfunction partToText(p: NarrowPart): string {\n if (p.type === \"text\") return p.text ?? \"\";\n if (p.type === \"tool_use\") return `[tool call] ${p.name ?? \"\"}`;\n if (p.type === \"tool_result\") {\n const body = typeof p.content === \"string\" ? p.content : JSON.stringify(p.content);\n return `[tool result] ${body}`;\n }\n return \"\";\n}\n\n/**\n * theokit#146 — the same part, kept as STRUCTURE.\n *\n * `partToText` above is what the model replay wants; a host rendering tool cards needs the call id,\n * the tool name and the arguments, none of which survive `[tool call] NAME`. Both projections are\n * produced from the one reconstructed part, so they cannot drift apart.\n *\n * Returns `undefined` for a part with no display meaning (e.g. an image placeholder the session\n * projection does not model), which the caller filters out.\n */\nfunction partToStructured(p: NarrowPart): SessionMessagePart | undefined {\n if (p.type === \"text\") return { type: \"text\", text: p.text ?? \"\" };\n if (p.type === \"tool_use\") {\n return {\n type: \"tool_use\",\n id: p.id ?? \"\",\n name: p.name ?? \"\",\n input: (p.input ?? {}) as Record<string, unknown>,\n };\n }\n if (p.type === \"tool_result\") {\n return {\n type: \"tool_result\",\n toolUseId: p.toolUseId ?? \"\",\n // Reconstructed tool results carry either a string or the SE7 content blocks; both are\n // already the session shape, so this narrows `unknown` rather than converting anything.\n content: p.content as string | ReadonlyArray<ToolResultContentBlock>,\n ...(p.isError === true ? { isError: true } : {}),\n };\n }\n return undefined;\n}\n\n/** Flatten a reconstructed `LlmMessage` to the narrowed in-memory `SessionMessage`. */\nfunction narrowToSessionMessage(m: {\n role: \"system\" | \"user\" | \"assistant\";\n content: NarrowPart[];\n}): SessionMessage {\n const role = m.role === \"user\" ? \"user\" : \"assistant\";\n const text = m.content\n .map(partToText)\n .filter((s) => s.length > 0)\n .join(\"\\n\");\n const parts = m.content\n .map(partToStructured)\n .filter((p): p is SessionMessagePart => p !== undefined);\n return { role, text, parts };\n}\n\n/** The records appended by the last turn (the delta beyond the seeded prior). */\nfunction deltaRecords(\n transcript: SessionTranscript,\n priorLength: number,\n): readonly SessionRecord[] {\n return transcript.records().slice(priorLength);\n}\n\n/**\n * Persist one conversation turn (user + assistant/tool records) to the session\n * store, append-only. Reads the prior records to seed the parent chain, folds the\n * new turn, and appends ONLY the delta via {@link SessionStore.appendRecords}\n * (the store owns the append atomicity — the FS default serializes under a file\n * lock). Within one process, turns for an agent are already chained upstream, so\n * the read→append is ordered; cross-host ordering is the external store's contract.\n */\nexport async function persistTurn(\n store: SessionStore,\n loc: TranscriptLocation,\n sessionId: string,\n turn: PersistTurnInput,\n): Promise<void> {\n const prior = await store.readRecords(loc.agentId);\n const transcript = seedTranscript(prior, { cwd: loc.cwd, sessionId, model: loc.model });\n transcript.appendUserTurn(turn.userText);\n appendConversation(transcript, turn.conversation);\n await store.appendRecords(loc.agentId, deltaRecords(transcript, prior.length));\n}\n\n/**\n * Append-only compaction: add a `compact_boundary` system record (a new root) so\n * resume replays only the post-boundary continuation. Appends only the boundary\n * record via the store — NEVER rewrites or shrinks the prior records.\n */\nexport async function appendCompactBoundaryRecord(\n store: SessionStore,\n loc: TranscriptLocation,\n sessionId: string,\n meta: { preTokens: number; trigger: string },\n): Promise<void> {\n const prior = await store.readRecords(loc.agentId);\n const transcript = seedTranscript(prior, { cwd: loc.cwd, sessionId, model: loc.model });\n transcript.appendCompactBoundary(meta);\n await store.appendRecords(loc.agentId, deltaRecords(transcript, prior.length));\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/internal/session/agent-session-store.ts"],"names":["SessionTranscript","reconstructMessages"],"mappings":"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","file":"chunk-MSW7LB2V.cjs","sourcesContent":["/**\n * SE40 — native session store over the Claude-shaped `.jsonl` transcript.\n *\n * The theokit session format IS the Claude Code record shape (see\n * `../../persistence/session-transcript.ts`). This module owns the FS lifecycle:\n * read existing records, seed a {@link SessionTranscript}'s parent chain, append\n * the new turn (user + assistant/tool blocks), and write append-only. Compaction\n * appends a `compact_boundary` record (a new root) — it NEVER shrinks the line\n * set (that would break the DAG). Reads reconstruct `LlmMessage[]` via\n * {@link reconstructMessages}, narrowed to the in-memory {@link SessionMessage}.\n *\n * @internal\n */\n\nimport type { ToolResultContentBlock } from \"../../types/content-blocks.js\";\nimport type { ConversationStep, ConversationTurn } from \"../../types/conversation.js\";\nimport type { SessionStore } from \"../../types/session-store.js\";\nimport {\n type AssistantTurn,\n reconstructMessages,\n type SessionRecord,\n SessionTranscript,\n} from \"../persistence/session-transcript.js\";\nimport type { SessionMessage, SessionMessagePart } from \"./types.js\";\n\n/**\n * Seed a {@link SessionTranscript} from the already-on-disk records so a new\n * append parents correctly on the existing DAG leaf. The transcript re-emits the\n * seeded records verbatim before the new turn, so the whole file rewrites atomically\n * as one append-only line set. Returns the transcript primed with the prior records.\n */\nfunction seedTranscript(\n prior: readonly SessionRecord[],\n opts: { cwd: string; sessionId: string; model: string },\n): SessionTranscript {\n return SessionTranscript.fromRecords(prior, opts);\n}\n\n/** The turn to persist: the user's text plus the rich per-turn conversation view. */\nexport interface PersistTurnInput {\n userText: string;\n conversation: readonly ConversationTurn[];\n /**\n * M50 — when supplied, size-driven auto-compaction runs in the SAME write chain after the turn\n * persists (usage real vs the model's context window; summarizer injected by the caller).\n */\n autoCompact?: {\n usageTotal?: number | undefined;\n contextWindow?: number | undefined;\n summarize: (\n messages: readonly import(\"../../compaction.js\").CompressibleMessage[],\n ) => Promise<string>;\n };\n}\n\ninterface MappedTurn {\n assistant: AssistantTurn;\n toolResults: Array<{ toolUseId: string; content: string; isError?: boolean }>;\n}\n\n/**\n * theokit#122 — record the turn's thinking block, signature included.\n *\n * The signature is what makes the block replayable: without it the resumed turn is rejected by\n * Anthropic with `400 \"thinking blocks cannot be modified\"`.\n */\nfunction applyThinkingStep(\n assistant: AssistantTurn,\n message: { text: string; signature?: string },\n): void {\n assistant.thinking = message.text;\n if (message.signature !== undefined) assistant.thinkingSignature = message.signature;\n}\n\n/** Fold one agent turn's steps into an assistant record + paired tool results. */\nfunction mapAgentTurn(steps: readonly ConversationStep[]): MappedTurn {\n const assistant: AssistantTurn = {};\n const toolResults: MappedTurn[\"toolResults\"] = [];\n const toolCalls: NonNullable<AssistantTurn[\"toolCalls\"]> = [];\n for (const step of steps) {\n if (step.type === \"thinkingMessage\") applyThinkingStep(assistant, step.message);\n else if (step.type === \"assistantMessage\") assistant.text = step.message.text;\n else if (step.type === \"toolCall\")\n toolCalls.push({\n id: step.message.callId,\n name: step.message.name,\n input: (step.message.args as Record<string, unknown> | undefined) ?? {},\n });\n else\n toolResults.push({\n toolUseId: step.message.callId,\n content: step.message.result,\n isError: step.message.isError,\n });\n }\n if (toolCalls.length > 0) assistant.toolCalls = toolCalls;\n return { assistant, toolResults };\n}\n\n/** True when the assistant record carries any content worth emitting. */\nfunction hasAssistantContent(a: AssistantTurn): boolean {\n return a.text !== undefined || a.thinking !== undefined || (a.toolCalls?.length ?? 0) > 0;\n}\n\n/**\n * Map the rich `ConversationTurn[]` (from `run.conversation()`) into the native\n * assistant/tool records. One transcript turn is: an `assistant` record carrying\n * thinking + text + tool_use blocks, then (when present) a `user` record carrying\n * the paired tool_result blocks. Tool results pair with tool_use by `callId`.\n */\nfunction appendConversation(\n transcript: SessionTranscript,\n conversation: readonly ConversationTurn[],\n): void {\n for (const ct of conversation) {\n if (ct.type !== \"agentConversationTurn\") continue;\n const { assistant, toolResults } = mapAgentTurn(ct.turn.steps);\n if (hasAssistantContent(assistant)) transcript.appendAssistantTurn(assistant);\n if (toolResults.length > 0) transcript.appendToolResults(toolResults);\n }\n}\n\n/**\n * The per-agent transcript metadata used to seed a {@link SessionTranscript}. The\n * actual record I/O goes through the injected {@link SessionStore} (SE41), so this\n * no longer carries a `baseDir` — the store is already bound to its location.\n */\nexport interface TranscriptLocation {\n cwd: string;\n agentId: string;\n model: string;\n}\n\n/**\n * Read the session's records via the {@link SessionStore} and reconstruct the\n * resumable history, narrowed to the in-memory {@link SessionMessage} shape\n * (user/assistant text). Tool turns fold into assistant-role context so resume\n * keeps tool history. Works identically for the FS default and an external store.\n */\nexport async function readSessionMessages(\n store: SessionStore,\n agentId: string,\n): Promise<SessionMessage[]> {\n const records = await store.readRecords(agentId);\n return reconstructMessages(records).map(narrowToSessionMessage);\n}\n\ntype NarrowPart = {\n type: string;\n text?: string;\n content?: unknown;\n name?: string;\n id?: string;\n toolUseId?: string;\n input?: unknown;\n isError?: boolean;\n};\n\n/** Render one reconstructed content part as folded session text. */\nfunction partToText(p: NarrowPart): string {\n if (p.type === \"text\") return p.text ?? \"\";\n if (p.type === \"tool_use\") return `[tool call] ${p.name ?? \"\"}`;\n if (p.type === \"tool_result\") {\n const body = typeof p.content === \"string\" ? p.content : JSON.stringify(p.content);\n return `[tool result] ${body}`;\n }\n return \"\";\n}\n\n/**\n * theokit#146 — the same part, kept as STRUCTURE.\n *\n * `partToText` above is what the model replay wants; a host rendering tool cards needs the call id,\n * the tool name and the arguments, none of which survive `[tool call] NAME`. Both projections are\n * produced from the one reconstructed part, so they cannot drift apart.\n *\n * Returns `undefined` for a part with no display meaning (e.g. an image placeholder the session\n * projection does not model), which the caller filters out.\n */\nfunction partToStructured(p: NarrowPart): SessionMessagePart | undefined {\n if (p.type === \"text\") return { type: \"text\", text: p.text ?? \"\" };\n if (p.type === \"tool_use\") {\n return {\n type: \"tool_use\",\n id: p.id ?? \"\",\n name: p.name ?? \"\",\n input: (p.input ?? {}) as Record<string, unknown>,\n };\n }\n if (p.type === \"tool_result\") {\n return {\n type: \"tool_result\",\n toolUseId: p.toolUseId ?? \"\",\n // Reconstructed tool results carry either a string or the SE7 content blocks; both are\n // already the session shape, so this narrows `unknown` rather than converting anything.\n content: p.content as string | ReadonlyArray<ToolResultContentBlock>,\n ...(p.isError === true ? { isError: true } : {}),\n };\n }\n return undefined;\n}\n\n/** Flatten a reconstructed `LlmMessage` to the narrowed in-memory `SessionMessage`. */\nfunction narrowToSessionMessage(m: {\n role: \"system\" | \"user\" | \"assistant\";\n content: NarrowPart[];\n}): SessionMessage {\n const role = m.role === \"user\" ? \"user\" : \"assistant\";\n const text = m.content\n .map(partToText)\n .filter((s) => s.length > 0)\n .join(\"\\n\");\n const parts = m.content\n .map(partToStructured)\n .filter((p): p is SessionMessagePart => p !== undefined);\n return { role, text, parts };\n}\n\n/** The records appended by the last turn (the delta beyond the seeded prior). */\nfunction deltaRecords(\n transcript: SessionTranscript,\n priorLength: number,\n): readonly SessionRecord[] {\n return transcript.records().slice(priorLength);\n}\n\n/**\n * Persist one conversation turn (user + assistant/tool records) to the session\n * store, append-only. Reads the prior records to seed the parent chain, folds the\n * new turn, and appends ONLY the delta via {@link SessionStore.appendRecords}\n * (the store owns the append atomicity — the FS default serializes under a file\n * lock). Within one process, turns for an agent are already chained upstream, so\n * the read→append is ordered; cross-host ordering is the external store's contract.\n */\nexport async function persistTurn(\n store: SessionStore,\n loc: TranscriptLocation,\n sessionId: string,\n turn: PersistTurnInput,\n): Promise<void> {\n const prior = await store.readRecords(loc.agentId);\n const transcript = seedTranscript(prior, { cwd: loc.cwd, sessionId, model: loc.model });\n transcript.appendUserTurn(turn.userText);\n appendConversation(transcript, turn.conversation);\n await store.appendRecords(loc.agentId, deltaRecords(transcript, prior.length));\n}\n\n/**\n * Append-only compaction: add a `compact_boundary` system record (a new root) so\n * resume replays only the post-boundary continuation. Appends only the boundary\n * record via the store — NEVER rewrites or shrinks the prior records.\n */\nexport async function appendCompactBoundaryRecord(\n store: SessionStore,\n loc: TranscriptLocation,\n sessionId: string,\n meta: { preTokens: number; trigger: string },\n): Promise<void> {\n const prior = await store.readRecords(loc.agentId);\n const transcript = seedTranscript(prior, { cwd: loc.cwd, sessionId, model: loc.model });\n transcript.appendCompactBoundary(meta);\n await store.appendRecords(loc.agentId, deltaRecords(transcript, prior.length));\n}\n"]}
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { resolveChildEnv } from './chunk-HKCKOAIO.js';
|
|
2
|
-
import { TheokitAgentError, ConfigurationError } from './chunk-
|
|
2
|
+
import { TheokitAgentError, ConfigurationError } from './chunk-TNFOU6SB.js';
|
|
3
3
|
import { execFile } from 'child_process';
|
|
4
4
|
import { mkdir, writeFile } from 'fs/promises';
|
|
5
5
|
import { dirname } from 'path';
|
|
6
6
|
|
|
7
7
|
// src/sandbox/shell-escape.ts
|
|
8
8
|
function shellEscapePosix(arg) {
|
|
9
|
-
|
|
9
|
+
const quotesEscaped = arg.replace(/'/g, "'\\''");
|
|
10
|
+
return `'${quotesEscaped.replace(/\\(?=\\|'\\''|$)/g, "'\\\\'")}'`;
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
// src/sandbox/types.ts
|
|
@@ -161,5 +162,5 @@ var LocalSandbox = class extends SandboxBackend {
|
|
|
161
162
|
};
|
|
162
163
|
|
|
163
164
|
export { LocalSandbox, SandboxBackend, SandboxNotAvailableError, SandboxSecurityError, resolveSandbox, shellEscapePosix };
|
|
164
|
-
//# sourceMappingURL=chunk-
|
|
165
|
-
//# sourceMappingURL=chunk-
|
|
165
|
+
//# sourceMappingURL=chunk-NBNRQN6T.js.map
|
|
166
|
+
//# sourceMappingURL=chunk-NBNRQN6T.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/sandbox/shell-escape.ts","../src/sandbox/types.ts","../src/sandbox/local-sandbox.ts"],"names":["fsWriteFile"],"mappings":";;;;;;;AAeO,SAAS,iBAAiB,GAAA,EAAqB;AACpD,EAAA,MAAM,aAAA,GAAgB,GAAA,CAAI,OAAA,CAAQ,IAAA,EAAM,OAAO,CAAA;AAC/C,EAAA,OAAO,CAAA,CAAA,EAAI,aAAA,CAAc,OAAA,CAAQ,mBAAA,EAAqB,QAAQ,CAAC,CAAA,CAAA,CAAA;AACjE;;;ACoDO,IAAM,oBAAA,GAAN,cAAmC,iBAAA,CAAkB;AAAA,EACxC,IAAA,GAAO,sBAAA;AAAA,EACP,IAAA,GAAO,kBAAA;AAAA,EACzB,YAAY,OAAA,EAAiB;AAE3B,IAAA,KAAA,CAAM,SAAS,EAAE,IAAA,EAAM,kBAAA,EAAoB,WAAA,EAAa,OAAO,CAAA;AAAA,EACjE;AACF;AAYO,IAAM,wBAAA,GAAN,cAAuC,iBAAA,CAAkB;AAAA,EAC5C,IAAA,GAAO,0BAAA;AAAA,EACP,IAAA,GAAO,uBAAA;AAAA,EACzB,YAAY,OAAA,EAAiB;AAE3B,IAAA,KAAA,CAAM,SAAS,EAAE,IAAA,EAAM,uBAAA,EAAyB,WAAA,EAAa,OAAO,CAAA;AAAA,EACtE;AACF;AAoBO,IAAe,iBAAf,MAA8B;AAAA,EACzB,MAAA;AAAA,EAEV,WAAA,CAAY,MAAA,GAAwB,EAAC,EAAG;AACtC,IAAA,IAAA,CAAK,MAAA,GAAS;AAAA,MACZ,OAAA,EAAS,OAAO,OAAA,IAAW,MAAA;AAAA,MAC3B,SAAA,EAAW,OAAO,SAAA,IAAa,GAAA;AAAA,MAC/B,cAAA,EAAgB,MAAA,CAAO,cAAA,IAAkB,CAAA,GAAI,IAAA,GAAO,IAAA;AAAA;AAAA,MAEpD,GAAA,EAAK,OAAO,GAAA,IAAO;AAAA,KACrB;AAAA,EACF;AAAA,EAMA,MAAM,SAAS,IAAA,EAA+B;AAC5C,IAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,OAAA,CAAQ,OAAO,IAAA,CAAK,WAAA,CAAY,IAAI,CAAC,CAAA,CAAE,CAAA;AACjE,IAAA,IAAI,MAAA,CAAO,aAAa,CAAA,EAAG;AACzB,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,iBAAA,EAAoB,MAAA,CAAO,MAAM,CAAA,CAAE,CAAA;AAAA,IACrD;AACA,IAAA,OAAO,MAAA,CAAO,MAAA;AAAA,EAChB;AAAA,EAEA,MAAM,SAAA,CAAU,IAAA,EAAc,OAAA,EAAgC;AAC5D,IAAA,MAAM,IAAA,CAAK,UAAA,CAAW,IAAA,EAAM,OAAO,CAAA;AAAA,EACrC;AAAA,EAEA,MAAM,IAAA,CAAK,OAAA,EAAiB,GAAA,EAAiC;AAC3D,IAAA,MAAM,GAAA,GAAM,GAAA,IAAO,IAAA,CAAK,MAAA,CAAO,OAAA,IAAW,GAAA;AAC1C,IAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,OAAA;AAAA,MACxB,CAAA,KAAA,EAAQ,KAAK,WAAA,CAAY,GAAG,CAAC,CAAA,OAAA,EAAU,IAAA,CAAK,WAAA,CAAY,OAAO,CAAC,CAAA,oBAAA;AAAA,KAClE;AACA,IAAA,IAAA,CAAK,gBAAA,CAAiB,QAAQ,MAAM,CAAA;AACpC,IAAA,OAAO,MAAA,CAAO,OAAO,IAAA,EAAK,CAAE,MAAM,IAAI,CAAA,CAAE,OAAO,OAAO,CAAA;AAAA,EACxD;AAAA,EAEA,MAAM,IAAA,CAAK,OAAA,EAAiB,IAAA,EAAkC;AAC5D,IAAA,MAAM,SAAS,IAAA,IAAQ,GAAA;AACvB,IAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,OAAA;AAAA,MACxB,CAAA,SAAA,EAAY,KAAK,WAAA,CAAY,OAAO,CAAC,CAAA,CAAA,EAAI,IAAA,CAAK,WAAA,CAAY,MAAM,CAAC,CAAA,YAAA;AAAA,KACnE;AAEA,IAAA,IAAI,OAAO,QAAA,KAAa,CAAA,EAAG,IAAA,CAAK,gBAAA,CAAiB,QAAQ,MAAM,CAAA;AAC/D,IAAA,OAAO,MAAA,CAAO,OAAO,IAAA,EAAK,CAAE,MAAM,IAAI,CAAA,CAAE,OAAO,OAAO,CAAA;AAAA,EACxD;AAAA,EAEA,MAAM,QAAQ,IAAA,EAAiC;AAC7C,IAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,OAAA,CAAQ,SAAS,IAAA,CAAK,WAAA,CAAY,IAAI,CAAC,CAAA,CAAE,CAAA;AACnE,IAAA,IAAA,CAAK,gBAAA,CAAiB,WAAW,MAAM,CAAA;AACvC,IAAA,OAAO,MAAA,CAAO,OAAO,IAAA,EAAK,CAAE,MAAM,IAAI,CAAA,CAAE,OAAO,OAAO,CAAA;AAAA,EACxD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcQ,gBAAA,CAAiB,WAAmB,MAAA,EAA6B;AACvE,IAAA,IAAI,MAAA,CAAO,aAAa,CAAA,EAAG;AAC3B,IAAA,MAAM,IAAI,kBAAA;AAAA,MACR,CAAA,EAAG,SAAS,CAAA,cAAA,EAAiB,MAAA,CAAO,MAAA,CAAO,QAAQ,CAAC,CAAA,GAAA,EAAM,MAAA,CAAO,MAAA,CAAO,IAAA,EAAK,IAAK,WAAW,CAAA,mJAAA,CAAA;AAAA,MAG7F,EAAE,MAAM,+BAAA;AAAgC,KAC1C;AAAA,EACF;AAAA,EAEU,eAAe,MAAA,EAAwB;AAC/C,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,MAAA,CAAO,cAAA,IAAkB,IAAI,IAAA,GAAO,IAAA;AACrD,IAAA,IAAI,MAAA,CAAO,UAAA,CAAW,MAAM,CAAA,GAAI,GAAA,EAAK;AACnC,MAAA,OAAO,CAAA,EAAG,MAAA,CAAO,KAAA,CAAM,CAAA,EAAG,GAAG,CAAC;AAAA,cAAA,CAAA;AAAA,IAChC;AACA,IAAA,OAAO,MAAA;AAAA,EACT;AAAA,EAEQ,YAAY,GAAA,EAAqB;AACvC,IAAA,OAAO,iBAAiB,GAAG,CAAA;AAAA,EAC7B;AACF;AAgBA,eAAsB,cAAA,CACpB,UACA,GAAA,EACyB;AACzB,EAAA,OAAO,QAAA,YAAoB,cAAA,GAAiB,QAAA,GAAW,QAAA,CAAS,GAAG,CAAA;AACrE;ACxKO,IAAM,YAAA,GAAN,cAA2B,cAAA,CAAe;AAAA,EAC/C,WAAA,CAAY,MAAA,GAAwB,EAAC,EAAG;AACtC,IAAA,KAAA,CAAM,MAAM,CAAA;AAAA,EACd;AAAA,EAEA,MAAM,OAAA,CAAQ,OAAA,EAAiB,IAAA,EAAuD;AACpF,IAAA,MAAM,OAAA,GAAU,IAAA,EAAM,SAAA,IAAa,IAAA,CAAK,OAAO,SAAA,IAAa,GAAA;AAC5D,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,MAAA,CAAO,cAAA,IAAkB,IAAI,IAAA,GAAO,IAAA;AAErD,IAAA,OAAO,IAAI,OAAA,CAAuB,CAAC,OAAA,KAAY;AAC7C,MAAA,MAAM,KAAA,GAAQ,QAAA;AAAA,QACZ,SAAA;AAAA,QACA,CAAC,MAAM,OAAO,CAAA;AAAA,QACd;AAAA,UACE,GAAA,EAAK,KAAK,MAAA,CAAO,OAAA;AAAA,UACjB,OAAA;AAAA,UACA,SAAA,EAAW,GAAA;AAAA,UACX,QAAA,EAAU,OAAA;AAAA;AAAA,UAEV,KAAK,eAAA,CAAgB,EAAE,QAAQ,IAAA,CAAK,MAAA,CAAO,KAAK;AAAA,SAClD;AAAA,QACA,CAAC,KAAA,EAAO,MAAA,EAAQ,MAAA,KAAW;AACzB,UAAA,OAAA,CAAQ,KAAK,WAAA,CAAY,KAAA,EAAO,UAAU,EAAA,EAAI,MAAA,IAAU,EAAE,CAAC,CAAA;AAAA,QAC7D;AAAA,OACF;AAGA,MAAA,KAAA,CAAM,EAAA,CAAG,SAAS,MAAM;AACtB,QAAA,OAAA,CAAQ,EAAE,QAAQ,EAAA,EAAI,MAAA,EAAQ,eAAe,QAAA,EAAU,CAAA,EAAG,QAAA,EAAU,KAAA,EAAO,CAAA;AAAA,MAC7E,CAAC,CAAA;AAAA,IACH,CAAC,CAAA;AAAA,EACH;AAAA,EAEQ,WAAA,CAAY,KAAA,EAAqB,MAAA,EAAgB,MAAA,EAA+B;AACtF,IAAA,MAAM,QAAA,GAAW,KAAA,KAAU,IAAA,IAAQ,QAAA,IAAY,SAAU,KAAA,CAA8B,MAAA;AAKvF,IAAA,MAAM,UAAA,GACJ,KAAA,KAAU,IAAA,IAAS,KAAA,CAA6B,IAAA,KAAS,mCAAA;AAC3D,IAAA,OAAO;AAAA,MACL,QAAQ,IAAA,CAAK,SAAA,CAAU,KAAK,cAAA,CAAe,MAAM,GAAG,UAAU,CAAA;AAAA,MAC9D,QAAQ,IAAA,CAAK,SAAA,CAAU,KAAK,cAAA,CAAe,MAAM,GAAG,UAAU,CAAA;AAAA,MAC9D,QAAA,EAAU,QAAA,GAAW,GAAA,GAAM,KAAA,GAAQ,CAAA,GAAI,CAAA;AAAA,MACvC;AAAA,KACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUQ,SAAA,CAAU,QAAgB,UAAA,EAA6B;AAC7D,IAAA,IAAI,CAAC,YAAY,OAAO,MAAA;AACxB,IAAA,IAAI,MAAA,CAAO,QAAA,CAAS,gBAAgB,CAAA,EAAG,OAAO,MAAA;AAC9C,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,MAAA,CAAO,cAAA,IAAkB,IAAI,IAAA,GAAO,IAAA;AACrD,IAAA,OAAO,OAAO,UAAA,CAAW,MAAM,CAAA,IAAK,GAAA,GAAM,GAAG,MAAM;AAAA,cAAA,CAAA,GAAqB,MAAA;AAAA,EAC1E;AAAA,EAEA,MAAM,UAAA,CAAW,IAAA,EAAc,OAAA,EAAyC;AACtE,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,UAAA,CAAW,GAAG,CAAA,GAAI,IAAA,GAAO,CAAA,EAAG,IAAA,CAAK,MAAA,CAAO,OAAO,CAAA,CAAA,EAAI,IAAI,CAAA,CAAA;AAC7E,IAAA,MAAM,MAAM,OAAA,CAAQ,QAAQ,GAAG,EAAE,SAAA,EAAW,MAAM,CAAA;AAClD,IAAA,MAAMA,SAAA,CAAY,QAAA,EAAU,OAAA,EAAS,OAAO,CAAA;AAAA,EAC9C;AACF","file":"chunk-NBNRQN6T.js","sourcesContent":["/**\n * POSIX shell escaping for values interpolated into a `SandboxBackend.execute`\n * command string. `execute` runs via `/bin/sh -c`, so any untrusted value\n * (repo URL, ref, path) MUST be quoted to prevent command injection.\n *\n * @internal\n */\n\n/**\n * Wrap `arg` in single quotes, escaping embedded single quotes (`'\\''`). A backslash before a quote,\n * a backslash or the end is written outside the quotes too (`'\\\\'`), so the word parses the same\n * under fish, which reads `\\'` and `\\\\` inside single quotes as escapes, as under sh (B-600): the PTY\n * runs the sandbox wrap under the user's `$SHELL`. After the first pass an original quote reads\n * `'\\''`, whose own backslash is always followed by `''`, so the second pass never matches it.\n */\nexport function shellEscapePosix(arg: string): string {\n const quotesEscaped = arg.replace(/'/g, \"'\\\\''\");\n return `'${quotesEscaped.replace(/\\\\(?=\\\\|'\\\\''|$)/g, \"'\\\\\\\\'\")}'`;\n}\n","/**\n * Sandbox backend protocol — pluggable execution environment for agent tools.\n *\n * Per ADR D1: only 2 abstract methods (`execute` + `uploadFile`). All\n * higher-level operations are derived on the base class. New backends\n * (Docker, Firecracker, E2B) only implement those 2 methods.\n *\n * @public\n */\n\nimport { ConfigurationError, TheokitAgentError } from \"../errors.js\";\nimport type { EnvPolicy } from \"../types/env-policy.js\";\nimport { shellEscapePosix } from \"./shell-escape.js\";\n\n/**\n * What a {@link SandboxBackend} returns for one command.\n *\n * `exitCode` is a coarse signal rather than the child's real exit status: the backends in this\n * package report `0` on success, `124` on timeout, and `1` for everything else — including a command\n * that exited with its own non-zero code. Read `timedOut` to tell a killed command from a failed one,\n * and `stderr` for the reason; branching on a specific exit code will not work here.\n *\n * `stdout` and `stderr` are truncated independently at `SandboxConfig.maxOutputBytes`, with a\n * trailing `...(truncated)` marker. Neither is safe to parse as a complete document without checking\n * for it.\n */\nexport interface ExecuteResult {\n stdout: string;\n stderr: string;\n exitCode: number;\n timedOut: boolean;\n}\n\n/**\n * Construction-time settings shared by every {@link SandboxBackend}. All fields are optional and the\n * base constructor fills them in, so `{}` is a valid config: `workDir` `/tmp`, `timeoutMs` 30000,\n * `maxOutputBytes` 5 MiB, `env` `\"inherit-scrubbed\"`.\n *\n * `workDir` is the child process's cwd and the base a relative `uploadFile` path resolves against. It\n * is not a boundary — under `LocalSandbox` nothing stops a command, or an absolute path, from leaving\n * it. Only `LinuxSandbox` makes it enforceable.\n *\n * `timeoutMs` is the default for every call; `execute(command, { timeoutMs })` overrides it per\n * command. On expiry the child is killed and the result carries `timedOut: true` with `exitCode`\n * 124 — the partial output collected so far is still returned.\n */\nexport interface SandboxConfig {\n workDir?: string;\n timeoutMs?: number;\n maxOutputBytes?: number;\n /**\n * #54 — env inherit/scrub policy for the executed command's child process.\n * Defaults to `\"inherit-scrubbed\"` (drop secret-like vars: `*KEY*`, `*SECRET*`,\n * `*TOKEN*`, `*PASSWORD*`, `*_AUTH*`). Pass `\"all\"` to restore full inheritance\n * or `\"core\"` for a minimal safe allowlist.\n */\n env?: EnvPolicy;\n}\n\n/**\n * A backend refused a command on policy grounds — the environment works, and it said no. Carries a\n * stable `code: \"sandbox_security\"` for callers that prefer not to match on the class.\n *\n * Nothing in this package throws it, which is worth knowing before you write a `catch` for it:\n * `LocalSandbox` and `LinuxSandbox` report a refusal through {@link ExecuteResult} (non-zero\n * `exitCode`, reason on `stderr`), and a write blocked under confinement surfaces as a plain `Error`\n * from `uploadFile`. This type exists so a custom backend that must reject a command BEFORE spawning\n * anything — a container or VM runner enforcing its own policy — can do so in the protocol's\n * vocabulary instead of inventing an error of its own.\n */\nexport class SandboxSecurityError extends TheokitAgentError {\n override readonly name = \"SandboxSecurityError\";\n override readonly code = \"sandbox_security\" as const;\n constructor(message: string) {\n // not retryable: a refused command is refused every time; retrying re-asks the same question\n super(message, { code: \"sandbox_security\", isRetryable: false });\n }\n}\n\n/**\n * A backend cannot be used at all: its runtime is missing or unusable. The distinction from\n * {@link SandboxSecurityError} is which side failed — there the sandbox worked and denied the\n * command, here there is no sandbox. Carries `code: \"sandbox_not_available\"`.\n *\n * Nothing in this package throws it either, and that is a position rather than an oversight:\n * `createSandboxBackend` treats a missing bubblewrap as a degradation, warns once, and hands back an\n * unconfined `LocalSandbox`. Throw this instead from a backend that must never silently run outside\n * its isolation.\n */\nexport class SandboxNotAvailableError extends TheokitAgentError {\n override readonly name = \"SandboxNotAvailableError\";\n override readonly code = \"sandbox_not_available\" as const;\n constructor(message: string) {\n // not retryable: a missing runtime does not appear on a second attempt\n super(message, { code: \"sandbox_not_available\", isRetryable: false });\n }\n}\n\n/**\n * The execution capability handed to an agent tool, and the extension point for new environments.\n *\n * A backend implements exactly two methods, `execute` and `uploadFile`. Everything else here —\n * `readFile`, `glob`, `grep`, `listDir` — is derived from `execute` by shelling out `cat`, `find`,\n * `grep` and `ls`, so a subclass that overrides `execute` alone inherits confined reads, searches and\n * listings for free. It does not inherit confined writes: `writeFile` delegates to `uploadFile`, and\n * that is the second override `LinuxSandbox` needs.\n *\n * Choosing one: `LocalSandbox` runs the command on the host with no isolation and suits code you\n * already trust; `LinuxSandbox` adds kernel confinement where bubblewrap is available;\n * `createSandboxBackend` probes and picks between them, and is the right entry point unless you have\n * a reason to pin one. For genuinely untrusted code you want a container or VM backend, which this\n * package does not ship — write it against these two methods.\n *\n * Because the derived helpers assemble shell command lines (arguments escaped for POSIX `sh`), a\n * backend whose `execute` is not a POSIX shell must override them as well.\n */\nexport abstract class SandboxBackend {\n protected config: SandboxConfig;\n\n constructor(config: SandboxConfig = {}) {\n this.config = {\n workDir: config.workDir ?? \"/tmp\",\n timeoutMs: config.timeoutMs ?? 30_000,\n maxOutputBytes: config.maxOutputBytes ?? 5 * 1024 * 1024,\n // #54 — preserve the env policy so backends can scrub secrets.\n env: config.env ?? \"inherit-scrubbed\",\n };\n }\n\n abstract execute(command: string, opts?: { timeoutMs?: number }): Promise<ExecuteResult>;\n\n abstract uploadFile(path: string, content: string | Buffer): Promise<void>;\n\n async readFile(path: string): Promise<string> {\n const result = await this.execute(`cat ${this.shellEscape(path)}`);\n if (result.exitCode !== 0) {\n throw new Error(`readFile failed: ${result.stderr}`);\n }\n return result.stdout;\n }\n\n async writeFile(path: string, content: string): Promise<void> {\n await this.uploadFile(path, content);\n }\n\n async glob(pattern: string, cwd?: string): Promise<string[]> {\n const dir = cwd ?? this.config.workDir ?? \".\";\n const result = await this.execute(\n `find ${this.shellEscape(dir)} -name ${this.shellEscape(pattern)} -type f 2>/dev/null`,\n );\n this.assertCommandRan(\"glob\", result);\n return result.stdout.trim().split(\"\\n\").filter(Boolean);\n }\n\n async grep(pattern: string, path?: string): Promise<string[]> {\n const target = path ?? \".\";\n const result = await this.execute(\n `grep -rn ${this.shellEscape(pattern)} ${this.shellEscape(target)} 2>/dev/null`,\n );\n // `grep` exits 1 for NO MATCH and >= 2 for an error, so a 1 is an answer and is not asserted on.\n if (result.exitCode !== 1) this.assertCommandRan(\"grep\", result);\n return result.stdout.trim().split(\"\\n\").filter(Boolean);\n }\n\n async listDir(path: string): Promise<string[]> {\n const result = await this.execute(`ls -1 ${this.shellEscape(path)}`);\n this.assertCommandRan(\"listDir\", result);\n return result.stdout.trim().split(\"\\n\").filter(Boolean);\n }\n\n /**\n * Turns \"the command did not run\" into an error instead of an empty array.\n *\n * `glob`, `grep` and `listDir` used to `return []` on any non-zero exit, so a search that could not\n * run reported the same thing as a search that found nothing — opposite facts, one normal and one\n * meaning the agent is looking at a filesystem it cannot read. That is the failure mode a backend\n * whose `execute` is not a POSIX shell hits, which this class's own docblock warns about in prose\n * and could not enforce.\n *\n * A genuine no-match is still `[]`: `find` exits 0 with empty output, and `grep`'s exit 1 is\n * checked by its caller before this is reached.\n */\n private assertCommandRan(operation: string, result: ExecuteResult): void {\n if (result.exitCode === 0) return;\n throw new ConfigurationError(\n `${operation} failed (exit ${String(result.exitCode)}): ${result.stderr.trim() || \"no stderr\"}. ` +\n `The derived helpers shell out to POSIX \\`cat\\`/\\`find\\`/\\`grep\\`/\\`ls\\` — a backend whose ` +\n `execute() is not a POSIX shell must override them.`,\n { code: \"sandbox_derived_helper_failed\" },\n );\n }\n\n protected truncateOutput(output: string): string {\n const max = this.config.maxOutputBytes ?? 5 * 1024 * 1024;\n if (Buffer.byteLength(output) > max) {\n return `${output.slice(0, max)}\\n...(truncated)`;\n }\n return output;\n }\n\n private shellEscape(arg: string): string {\n return shellEscapePosix(arg);\n }\n}\n\n/**\n * A backend OR a per-request resolver of one — mirrors `FilesystemProvider` / `InteractiveProvider`.\n * A resolver runs at tool-execution time (request scope), so a multi-tenant / multi-role agent gets a\n * distinct sandbox per request without a shared mutable one. This is how a tool takes execution as an\n * INJECTED capability: the same tool runs on a local sandbox, a container/E2B backend (cluster/web), or\n * any future backend, with no direct `child_process` import.\n *\n * @public\n */\nexport type SandboxProvider<Ctx = unknown> =\n | SandboxBackend\n | ((ctx: Ctx) => SandboxBackend | Promise<SandboxBackend>);\n\n/** Resolve a {@link SandboxProvider} to a concrete backend for `ctx`. */\nexport async function resolveSandbox<Ctx>(\n provider: SandboxProvider<Ctx>,\n ctx: Ctx,\n): Promise<SandboxBackend> {\n return provider instanceof SandboxBackend ? provider : provider(ctx);\n}\n","/**\n * LocalSandbox — subprocess-based execution. **This is NOT an isolation\n * boundary.** It runs the command via `/bin/sh -c` in the SAME OS as the host\n * with the host's filesystem and network fully reachable — it provides NO\n * process, filesystem, or network isolation. Its only safety affordances are:\n * - a wall-clock timeout (kills a runaway command),\n * - an output-size cap (bounds memory), and\n * - env scrubbing (#54): secret-like parent env vars (`*KEY*`/`*SECRET*`/\n * `*TOKEN*`/`*PASSWORD*`/`*_AUTH*`) are dropped from the child by default\n * (`SandboxConfig.env`), so a shell tool cannot exfiltrate host secrets via\n * the environment.\n *\n * For real isolation (untrusted code), use a container/VM backend — NOT this.\n *\n * @public\n */\n\nimport { execFile } from \"node:child_process\";\nimport { writeFile as fsWriteFile, mkdir } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\n\nimport { resolveChildEnv } from \"../internal/runtime/lifecycle/env-policy.js\";\nimport { type ExecuteResult, SandboxBackend, type SandboxConfig } from \"./types.js\";\n\n/**\n * Runs a command with `/bin/sh -c` on the host. NOT an isolation boundary — the\n * module note above states exactly what it does and does not protect.\n *\n * const sandbox = new LocalSandbox({ workDir: \"/srv/repo\", timeoutMs: 10_000 });\n * const { stdout, exitCode, timedOut } = await sandbox.execute(\"ls -1\");\n *\n * Needs a POSIX host with `/bin/sh`. Every helper inherited from\n * {@link SandboxBackend} — `readFile`, `glob`, `grep`, `listDir` — is built on\n * this `execute`, so they inherit that requirement too.\n *\n * How it fails: `execute` NEVER rejects. Every outcome, including a failure to\n * spawn, comes back as an {@link ExecuteResult}; read `timedOut` first\n * (`true` implies `exitCode` 124) and `stderr` for the reason. `uploadFile` DOES\n * reject, with the raw `node:fs` error, on a bad path or missing permission.\n *\n * Traps:\n * - `exitCode` is not the child's exit code. It is 0, 124 (timed out) or 1 — a\n * command that exits 3 is reported as 1, so branching on a specific code does\n * not work here.\n * - Output beyond `maxOutputBytes` (default 5 MiB) makes Node kill the child.\n * The result is `exitCode: 1` and `timedOut: false`, with the cut stream\n * carrying the `...(truncated)` marker described on `ExecuteResult` (#363).\n * Since `exitCode` is 1 either way, that marker is what tells a lost-output\n * result from a command that genuinely failed.\n * - `uploadFile` resolves a relative path against `workDir` but does not contain\n * it: an absolute path, or one containing `..`, writes wherever the process\n * can. `workDir` is a starting directory, not a jail.\n * - Secret-like parent env vars are dropped by default. Passing\n * `env: \"all\"` in {@link SandboxConfig} puts the host's API keys back within\n * reach of any command the agent runs.\n */\nexport class LocalSandbox extends SandboxBackend {\n constructor(config: SandboxConfig = {}) {\n super(config);\n }\n\n async execute(command: string, opts?: { timeoutMs?: number }): Promise<ExecuteResult> {\n const timeout = opts?.timeoutMs ?? this.config.timeoutMs ?? 30_000;\n const max = this.config.maxOutputBytes ?? 5 * 1024 * 1024;\n\n return new Promise<ExecuteResult>((resolve) => {\n const child = execFile(\n \"/bin/sh\",\n [\"-c\", command],\n {\n cwd: this.config.workDir,\n timeout,\n maxBuffer: max,\n encoding: \"utf-8\",\n // #54 — scrub secret-like host env vars from the child by default.\n env: resolveChildEnv({ policy: this.config.env }),\n },\n (error, stdout, stderr) => {\n resolve(this.buildResult(error, stdout ?? \"\", stderr ?? \"\"));\n },\n );\n\n // Safety: if child somehow doesn't callback\n child.on(\"error\", () => {\n resolve({ stdout: \"\", stderr: \"spawn error\", exitCode: 1, timedOut: false });\n });\n });\n }\n\n private buildResult(error: Error | null, stdout: string, stderr: string): ExecuteResult {\n const timedOut = error !== null && \"killed\" in error && (error as { killed: boolean }).killed;\n // #363 — the ONLY reliable signal that output was lost. Node caps the buffer AT `maxBuffer`, so\n // for ASCII output the string comes back exactly at the cap and `truncateOutput`'s `> max` test\n // never fires; a length comparison cannot tell a cut document from a complete one that happens\n // to be that long. The child being killed for overflow can.\n const overflowed =\n error !== null && (error as { code?: unknown }).code === \"ERR_CHILD_PROCESS_STDIO_MAXBUFFER\";\n return {\n stdout: this.markIfCut(this.truncateOutput(stdout), overflowed),\n stderr: this.markIfCut(this.truncateOutput(stderr), overflowed),\n exitCode: timedOut ? 124 : error ? 1 : 0,\n timedOut,\n };\n }\n\n /**\n * Append the `...(truncated)` marker `ExecuteResult` tells callers to branch on, when the child\n * was killed for exceeding `maxOutputBytes` and this stream is the one sitting at the cap.\n *\n * `truncateOutput` has already run, so an output it marked is left alone rather than marked\n * twice. Node does not say WHICH stream overflowed, so the stream at the cap is the one that\n * lost data — the other, being shorter, is complete.\n */\n private markIfCut(output: string, overflowed: boolean): string {\n if (!overflowed) return output;\n if (output.endsWith(\"...(truncated)\")) return output;\n const max = this.config.maxOutputBytes ?? 5 * 1024 * 1024;\n return Buffer.byteLength(output) >= max ? `${output}\\n...(truncated)` : output;\n }\n\n async uploadFile(path: string, content: string | Buffer): Promise<void> {\n const fullPath = path.startsWith(\"/\") ? path : `${this.config.workDir}/${path}`;\n await mkdir(dirname(fullPath), { recursive: true });\n await fsWriteFile(fullPath, content, \"utf-8\");\n }\n}\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { safePathJoin, assertNoSymlinkEscape } from './chunk-
|
|
2
|
-
import { readWorkspaceDir, parseSimpleYaml } from './chunk-
|
|
3
|
-
import { ConfigurationError } from './chunk-
|
|
1
|
+
import { safePathJoin, assertNoSymlinkEscape } from './chunk-PKRPV3R7.js';
|
|
2
|
+
import { readWorkspaceDir, parseSimpleYaml } from './chunk-Q7UG242V.js';
|
|
3
|
+
import { ConfigurationError } from './chunk-TNFOU6SB.js';
|
|
4
4
|
import { readFile } from 'fs/promises';
|
|
5
5
|
import { join } from 'path';
|
|
6
6
|
|
|
@@ -166,5 +166,5 @@ ${lines.join("\n")}
|
|
|
166
166
|
}
|
|
167
167
|
|
|
168
168
|
export { buildSkillsBlock, discoverSkills, escapeBlockBody, loadSkillInstructions, stripSkillFrontmatter };
|
|
169
|
-
//# sourceMappingURL=chunk-
|
|
170
|
-
//# sourceMappingURL=chunk-
|
|
169
|
+
//# sourceMappingURL=chunk-NHOEXFZT.js.map
|
|
170
|
+
//# sourceMappingURL=chunk-NHOEXFZT.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/internal/runtime/skills/skill-frontmatter.ts","../src/internal/runtime/skills/discover-skills.ts","../src/internal/runtime/system-prompt/escape.ts","../src/internal/runtime/skills/skills-block.ts"],"names":[],"mappings":"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","file":"chunk-7HUCU3KK.js","sourcesContent":["import { ConfigurationError } from \"../../../errors.js\";\nimport { type FrontmatterValue, parseSimpleYaml } from \"../context/yaml-frontmatter.js\";\n\ntype StringFields = Record<string, string | undefined>;\n\n/** Narrow a FrontmatterValue to string; non-strings + undefined → undefined. */\nfunction asString(v: FrontmatterValue | undefined): string | undefined {\n return typeof v === \"string\" ? v : undefined;\n}\n\n/** Coerce parser output to legacy string-only shape (skill schema is all-string). */\nfunction toStringFields(raw: Record<string, FrontmatterValue | undefined>): StringFields {\n const out: StringFields = {};\n for (const [k, v] of Object.entries(raw)) out[k] = asString(v);\n return out;\n}\n\n/**\n * Strict skill frontmatter schema (ADR D10).\n *\n * Required: `name`, `description`.\n * Optional: `category`, `dependencies` (comma-separated string in the\n * simple-YAML dialect — parsed to `string[]`).\n *\n * Unknown fields are ignored (forward-compat). Malformed YAML or missing\n * required fields surface as `ConfigurationError` with one of the typed\n * codes below.\n *\n * @internal\n */\nexport interface SkillFrontmatter {\n name: string;\n description: string;\n category?: string;\n dependencies?: string[];\n /**\n * `disable-model-invocation: true` — the model is not told this skill exists.\n *\n * The SDK owns this boundary: a skill reaches the model through exactly one place,\n * `buildSystemPromptContext`, so the declaration is enforceable here. It is a DISCLOSURE rule,\n * not an execution rule — `skills.get(name)` still resolves it, because a caller naming a skill\n * has already made the decision the field exists to keep away from the model.\n */\n disableModelInvocation?: boolean;\n /**\n * `user-invocable: false` — carried, deliberately not enforced here.\n *\n * This SDK has no user-facing invocation surface for skills; there is no slash command. Reading\n * `agent.skills.list()` as \"the user\" would be a guess — a host may call it to build a picker or\n * to introspect, and the two want opposite answers. So the declaration travels to the host that\n * does know, instead of being discarded (the defect) or enforced against an invented boundary.\n */\n userInvocable?: boolean;\n}\n\n/**\n * Parse a SKILL.md file body into validated frontmatter.\n *\n * @throws ConfigurationError(code: \"missing_frontmatter\") — no `---` block at file head.\n * @throws ConfigurationError(code: \"schema_invalid\") — YAML malformed OR required field missing.\n *\n * @internal\n */\nexport function parseSkillFrontmatter(raw: string, fallbackName: string): SkillFrontmatter {\n const parsed = extractAndParseFrontmatter(raw, fallbackName);\n const fields = toStringFields(parsed);\n const name = resolveName(fields, fallbackName);\n ensureRequiredFields(fields, name);\n return buildFrontmatter(fields, parsed, name);\n}\n\n/**\n * SE20 — return a SKILL.md's BODY (everything after the frontmatter block), trimmed.\n * When there is no frontmatter block, the whole file is the body. Reuses the same\n * frontmatter regex as {@link parseSkillFrontmatter} (DRY).\n */\nexport function stripSkillFrontmatter(raw: string): string {\n const match = /^---\\s*\\n[\\s\\S]*?\\n---\\s*\\n/.exec(raw);\n return (match === null ? raw : raw.slice(match[0].length)).trim();\n}\n\nfunction extractAndParseFrontmatter(\n raw: string,\n fallbackName: string,\n): Record<string, FrontmatterValue | undefined> {\n const match = /^---\\s*\\n([\\s\\S]*?)\\n---\\s*\\n/.exec(raw);\n if (match === null) {\n throw new ConfigurationError(`Skill ${fallbackName} is missing frontmatter`, {\n code: \"missing_frontmatter\",\n });\n }\n const frontmatter = match[1] ?? \"\";\n // EC-5: guard against syntactically invalid frontmatter so the loader\n // surfaces schema_invalid rather than crashing.\n try {\n return parseSimpleYaml(frontmatter);\n } catch (cause) {\n const detail = cause instanceof Error ? cause.message : String(cause);\n throw new ConfigurationError(\n `Skill ${fallbackName} has malformed YAML frontmatter: ${detail}`,\n { code: \"schema_invalid\", cause },\n );\n }\n}\n\nfunction resolveName(fields: StringFields, fallbackName: string): string {\n if (hasContent(fields.name)) return fields.name;\n if (hasContent(fallbackName)) return fallbackName;\n throw new ConfigurationError(\"Skill at unknown path is missing required field: name\", {\n code: \"schema_invalid\",\n });\n}\n\nfunction ensureRequiredFields(fields: StringFields, name: string): void {\n if (!hasContent(fields.description)) {\n throw new ConfigurationError(`Skill ${name} is missing required field: description`, {\n code: \"schema_invalid\",\n });\n }\n}\n\nfunction buildFrontmatter(\n fields: StringFields,\n parsed: Record<string, FrontmatterValue | undefined>,\n name: string,\n): SkillFrontmatter {\n const description = fields.description;\n if (description === undefined) {\n // ensureRequiredFields already threw; this is unreachable but satisfies TS\n throw new ConfigurationError(`Skill ${name} missing description`, { code: \"schema_invalid\" });\n }\n const result: SkillFrontmatter = { name, description };\n if (hasContent(fields.category)) result.category = fields.category;\n const deps = parseDependencies(fields.dependencies);\n if (deps !== undefined) result.dependencies = deps;\n const disable = readAuthorizationFlag(parsed, \"disable-model-invocation\", name);\n if (disable !== undefined) result.disableModelInvocation = disable;\n const invocable = readAuthorizationFlag(parsed, \"user-invocable\", name);\n if (invocable !== undefined) result.userInvocable = invocable;\n return result;\n}\n\n/**\n * Read one boolean authorization flag, refusing a value this parser cannot represent.\n *\n * Unknown frontmatter keys are ignored here for forward compatibility, and that is right for\n * metadata. It is wrong for these two: the simple-YAML dialect coerces only the literals `true`\n * and `false`, so `disable-model-invocation: yes` — a valid YAML boolean — arrives as the STRING\n * `\"yes\"`, compares unequal to `true`, and the skill is disclosed to the model. The author wrote a\n * restriction and got the default.\n *\n * A restriction that fails open is worse than one that is absent, because the author stops looking.\n * So the value is refused and named, and the run stops on the line that caused it.\n */\nfunction readAuthorizationFlag(\n parsed: Record<string, FrontmatterValue | undefined>,\n key: string,\n name: string,\n): boolean | undefined {\n const value = parsed[key];\n if (value === undefined) return undefined;\n if (typeof value === \"boolean\") return value;\n throw new ConfigurationError(\n `Skill ${name}: \"${key}\" must be true or false (got ${JSON.stringify(value)}) — ` +\n `this dialect reads only the literals \\`true\\` and \\`false\\`, and a value it cannot read ` +\n `would leave the skill disclosed`,\n { code: \"schema_invalid\" },\n );\n}\n\nfunction parseDependencies(raw: string | undefined): string[] | undefined {\n if (!hasContent(raw)) return undefined;\n const deps = (raw as string)\n .split(\",\")\n .map((s) => s.trim())\n .filter((s) => s.length > 0);\n return deps.length > 0 ? deps : undefined;\n}\n\nfunction hasContent(value: string | undefined): value is string {\n return value !== undefined && value.trim().length > 0;\n}\n","import { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { ConfigurationError } from \"../../../errors.js\";\nimport { assertNoSymlinkEscape, safePathJoin } from \"../../security/path-guard.js\";\nimport { readWorkspaceDir } from \"../config/workspace-dir.js\";\nimport { parseSkillFrontmatter, stripSkillFrontmatter } from \"./skill-frontmatter.js\";\n\n/**\n * A discovered skill's metadata. The skill BODY is never included — only the\n * strict frontmatter fields plus the resolved `source` path.\n *\n * Public via `@theokit/sdk/skills`.\n *\n * @public\n */\nexport interface Skill {\n name: string;\n description: string;\n /** Absolute path to the discovered `SKILL.md`. */\n source: string;\n category?: string;\n dependencies?: string[];\n /** `disable-model-invocation: true` — the model is never told this skill exists. */\n disableModelInvocation?: boolean;\n /** `user-invocable: false` — carried for a host that has a picker; this SDK has no such surface. */\n userInvocable?: boolean;\n}\n\n/**\n * Information passed to `onInvalidSkill` when a `SKILL.md` is present but its\n * frontmatter is malformed (missing required field or invalid YAML).\n *\n * @public\n */\nexport interface InvalidSkillInfo {\n /** The skill directory name (used as the fallback skill name). */\n name: string;\n /** Absolute path to the offending `SKILL.md`. */\n source: string;\n /** Typed reason: `missing_frontmatter` or `schema_invalid`. */\n code: string;\n message: string;\n}\n\n/**\n * Options for {@link discoverSkills}.\n *\n * @public\n */\nexport interface DiscoverSkillsOptions {\n /**\n * Called once per directory that contains a `SKILL.md` with malformed\n * frontmatter. The skill is excluded from the result; discovery continues\n * (strict-frontmatter ADR / EC-5). A directory WITHOUT a `SKILL.md` is NOT a\n * malformed skill and does not trigger this callback.\n *\n * Default: no-op (a library primitive must not write to the consumer's\n * stderr by default).\n */\n onInvalidSkill?: (info: InvalidSkillInfo) => void;\n}\n\n/**\n * Discover `SKILL.md` skills under an arbitrary directory.\n *\n * For each immediate subdirectory `<dir>/<name>/` containing a `SKILL.md`, the\n * file's strict YAML frontmatter is parsed (`name`/`description` required;\n * `category`/`dependencies` optional). Malformed skills are skipped (optionally\n * reported via {@link DiscoverSkillsOptions.onInvalidSkill}); a subdirectory\n * whose realpath escapes `dir` (via symlink) is skipped (symlink-escape guard,\n * reusing `@theokit/sdk/path-safety`).\n *\n * NEVER throws: a missing, unreadable, or non-directory `dir` yields `[]`.\n *\n * Discovery order follows the filesystem `readdir` order (OS-dependent). Sort\n * the result before {@link buildSkillsBlock} if a stable block order matters.\n *\n * Public via `@theokit/sdk/skills`.\n *\n * @public\n */\nexport async function discoverSkills(\n dir: string,\n options?: DiscoverSkillsOptions,\n): Promise<Skill[]> {\n let entries: Awaited<ReturnType<typeof readWorkspaceDir>>;\n try {\n entries = await readWorkspaceDir(dir, \"skills_read_error\", \"skills directory\");\n } catch {\n // never-throw contract: unreadable / not-a-directory → no skills (EC-1)\n return [];\n }\n\n const skills: Skill[] = [];\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n let skillDir: string;\n try {\n skillDir = safePathJoin(dir, entry.name);\n assertNoSymlinkEscape(skillDir, dir);\n } catch {\n continue;\n }\n const skillPath = join(skillDir, \"SKILL.md\");\n let raw: string;\n try {\n raw = await readFile(skillPath, \"utf8\");\n } catch {\n // no SKILL.md in this subdir → not a skill, not an error (EC-2)\n continue;\n }\n const skill = tryParseSkill(raw, entry.name, skillPath, options);\n if (skill !== undefined) skills.push(skill);\n }\n return skills;\n}\n\nfunction tryParseSkill(\n raw: string,\n fallbackName: string,\n source: string,\n options: DiscoverSkillsOptions | undefined,\n): Skill | undefined {\n try {\n const frontmatter = parseSkillFrontmatter(raw, fallbackName);\n const skill: Skill = {\n name: frontmatter.name,\n description: frontmatter.description,\n source,\n };\n if (frontmatter.category !== undefined) skill.category = frontmatter.category;\n if (frontmatter.dependencies !== undefined) skill.dependencies = frontmatter.dependencies;\n // The authorization flags travel with the record. Dropping them here would reproduce the defect\n // one layer down: the parser would read the declaration and the discovery result would not\n // carry it, which is indistinguishable from never having parsed it.\n if (frontmatter.disableModelInvocation !== undefined) {\n skill.disableModelInvocation = frontmatter.disableModelInvocation;\n }\n if (frontmatter.userInvocable !== undefined) skill.userInvocable = frontmatter.userInvocable;\n return skill;\n } catch (cause) {\n if (cause instanceof ConfigurationError) {\n options?.onInvalidSkill?.({\n name: fallbackName,\n source,\n code: cause.code ?? \"unknown\",\n message: cause.message,\n });\n return undefined;\n }\n throw cause;\n }\n}\n\n/**\n * Read the BODY of a discovered skill — everything after its frontmatter.\n *\n * A thin selector over {@link discoverSkills} rather than a second reader, which is the same\n * relationship `loadSubagentDefinition` has to `discoverSubagents` in the sibling domain: one\n * parser is the point.\n *\n * ## Why this exists rather than a field on `Skill`\n *\n * `Skill` documents that *\"the skill BODY is never included\"*. That is a written contract with no\n * written reason, and widening it on a guess about the reason is not a trade worth making — a\n * catalog you can put in a prompt without carrying every body is the likely intent, and this keeps\n * that shape intact for whoever relied on it.\n *\n * The body was never expensive to obtain: `discoverSkills` already reads each file in full and\n * discards everything but the frontmatter. What was missing was a door that hands it over.\n *\n * ## What it is for\n *\n * Turning a discovered skill into an inline one — `SkillsSettings.inline` requires `instructions`,\n * and without this the only route was to open `source` and split the frontmatter by hand. That is a\n * second implementation of this module's own convention, and it would fail SILENTLY if the format\n * moved: the frontmatter would land inside the instructions and nothing would say so.\n *\n * Reported by the `theocode` session, which needed exactly that to give an operator's\n * `~/.theokit/skills/` to an agent through the SDK's own parser.\n *\n * @param skill - a record returned by {@link discoverSkills}; its `source` is read.\n * @returns the trimmed body. A file that is all frontmatter yields an empty string.\n * @throws if `source` is unreadable — unlike discovery, which skips what it cannot read, a caller\n * naming ONE skill has asked about that skill and an empty string would answer a question it did\n * not ask.\n * @public\n */\nexport async function loadSkillInstructions(skill: Skill): Promise<string> {\n return stripSkillFrontmatter(await readFile(skill.source, \"utf8\"));\n}\n","/**\n * Block-body XML escape (ADR D9 — prompt-injection defence).\n *\n * Order matters: `&` MUST be escaped first so subsequent `<`/`>` replacements\n * do not double-encode the `&` characters they introduce.\n *\n * @internal\n */\nexport const escapeBlockBody = (s: string): string =>\n s.replace(/&/g, \"&\").replace(/</g, \"<\").replace(/>/g, \">\");\n","import { escapeBlockBody } from \"../system-prompt/escape.js\";\n\n/**\n * Render the `<skills>` system-prompt block from a skill list.\n *\n * Input is the structural subset `{ name, description }` — the skill BODY is\n * NOT in the type, so it cannot leak into the prompt. Both fields are passed\n * through `escapeBlockBody` to neutralise prompt-injection vectors hidden in\n * user-controlled SKILL.md frontmatter (injection-escape ADR).\n *\n * Returns `undefined` for an empty list so the caller can omit the block.\n *\n * Public via `@theokit/sdk/skills`.\n *\n * @public\n */\nexport function buildSkillsBlock(\n skills: ReadonlyArray<{ name: string; description: string }>,\n): string | undefined {\n if (skills.length === 0) return undefined;\n const lines = skills.map(\n (skill) => ` - ${escapeBlockBody(skill.name)}: ${escapeBlockBody(skill.description)}`,\n );\n return `<skills>\\n${lines.join(\"\\n\")}\\n</skills>`;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/internal/runtime/skills/skill-frontmatter.ts","../src/internal/runtime/skills/discover-skills.ts","../src/internal/runtime/system-prompt/escape.ts","../src/internal/runtime/skills/skills-block.ts"],"names":[],"mappings":"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","file":"chunk-NHOEXFZT.js","sourcesContent":["import { ConfigurationError } from \"../../../errors.js\";\nimport { type FrontmatterValue, parseSimpleYaml } from \"../context/yaml-frontmatter.js\";\n\ntype StringFields = Record<string, string | undefined>;\n\n/** Narrow a FrontmatterValue to string; non-strings + undefined → undefined. */\nfunction asString(v: FrontmatterValue | undefined): string | undefined {\n return typeof v === \"string\" ? v : undefined;\n}\n\n/** Coerce parser output to legacy string-only shape (skill schema is all-string). */\nfunction toStringFields(raw: Record<string, FrontmatterValue | undefined>): StringFields {\n const out: StringFields = {};\n for (const [k, v] of Object.entries(raw)) out[k] = asString(v);\n return out;\n}\n\n/**\n * Strict skill frontmatter schema (ADR D10).\n *\n * Required: `name`, `description`.\n * Optional: `category`, `dependencies` (comma-separated string in the\n * simple-YAML dialect — parsed to `string[]`).\n *\n * Unknown fields are ignored (forward-compat). Malformed YAML or missing\n * required fields surface as `ConfigurationError` with one of the typed\n * codes below.\n *\n * @internal\n */\nexport interface SkillFrontmatter {\n name: string;\n description: string;\n category?: string;\n dependencies?: string[];\n /**\n * `disable-model-invocation: true` — the model is not told this skill exists.\n *\n * The SDK owns this boundary: a skill reaches the model through exactly one place,\n * `buildSystemPromptContext`, so the declaration is enforceable here. It is a DISCLOSURE rule,\n * not an execution rule — `skills.get(name)` still resolves it, because a caller naming a skill\n * has already made the decision the field exists to keep away from the model.\n */\n disableModelInvocation?: boolean;\n /**\n * `user-invocable: false` — carried, deliberately not enforced here.\n *\n * This SDK has no user-facing invocation surface for skills; there is no slash command. Reading\n * `agent.skills.list()` as \"the user\" would be a guess — a host may call it to build a picker or\n * to introspect, and the two want opposite answers. So the declaration travels to the host that\n * does know, instead of being discarded (the defect) or enforced against an invented boundary.\n */\n userInvocable?: boolean;\n}\n\n/**\n * Parse a SKILL.md file body into validated frontmatter.\n *\n * @throws ConfigurationError(code: \"missing_frontmatter\") — no `---` block at file head.\n * @throws ConfigurationError(code: \"schema_invalid\") — YAML malformed OR required field missing.\n *\n * @internal\n */\nexport function parseSkillFrontmatter(raw: string, fallbackName: string): SkillFrontmatter {\n const parsed = extractAndParseFrontmatter(raw, fallbackName);\n const fields = toStringFields(parsed);\n const name = resolveName(fields, fallbackName);\n ensureRequiredFields(fields, name);\n return buildFrontmatter(fields, parsed, name);\n}\n\n/**\n * SE20 — return a SKILL.md's BODY (everything after the frontmatter block), trimmed.\n * When there is no frontmatter block, the whole file is the body. Reuses the same\n * frontmatter regex as {@link parseSkillFrontmatter} (DRY).\n */\nexport function stripSkillFrontmatter(raw: string): string {\n const match = /^---\\s*\\n[\\s\\S]*?\\n---\\s*\\n/.exec(raw);\n return (match === null ? raw : raw.slice(match[0].length)).trim();\n}\n\nfunction extractAndParseFrontmatter(\n raw: string,\n fallbackName: string,\n): Record<string, FrontmatterValue | undefined> {\n const match = /^---\\s*\\n([\\s\\S]*?)\\n---\\s*\\n/.exec(raw);\n if (match === null) {\n throw new ConfigurationError(`Skill ${fallbackName} is missing frontmatter`, {\n code: \"missing_frontmatter\",\n });\n }\n const frontmatter = match[1] ?? \"\";\n // EC-5: guard against syntactically invalid frontmatter so the loader\n // surfaces schema_invalid rather than crashing.\n try {\n return parseSimpleYaml(frontmatter);\n } catch (cause) {\n const detail = cause instanceof Error ? cause.message : String(cause);\n throw new ConfigurationError(\n `Skill ${fallbackName} has malformed YAML frontmatter: ${detail}`,\n { code: \"schema_invalid\", cause },\n );\n }\n}\n\nfunction resolveName(fields: StringFields, fallbackName: string): string {\n if (hasContent(fields.name)) return fields.name;\n if (hasContent(fallbackName)) return fallbackName;\n throw new ConfigurationError(\"Skill at unknown path is missing required field: name\", {\n code: \"schema_invalid\",\n });\n}\n\nfunction ensureRequiredFields(fields: StringFields, name: string): void {\n if (!hasContent(fields.description)) {\n throw new ConfigurationError(`Skill ${name} is missing required field: description`, {\n code: \"schema_invalid\",\n });\n }\n}\n\nfunction buildFrontmatter(\n fields: StringFields,\n parsed: Record<string, FrontmatterValue | undefined>,\n name: string,\n): SkillFrontmatter {\n const description = fields.description;\n if (description === undefined) {\n // ensureRequiredFields already threw; this is unreachable but satisfies TS\n throw new ConfigurationError(`Skill ${name} missing description`, { code: \"schema_invalid\" });\n }\n const result: SkillFrontmatter = { name, description };\n if (hasContent(fields.category)) result.category = fields.category;\n const deps = parseDependencies(fields.dependencies);\n if (deps !== undefined) result.dependencies = deps;\n const disable = readAuthorizationFlag(parsed, \"disable-model-invocation\", name);\n if (disable !== undefined) result.disableModelInvocation = disable;\n const invocable = readAuthorizationFlag(parsed, \"user-invocable\", name);\n if (invocable !== undefined) result.userInvocable = invocable;\n return result;\n}\n\n/**\n * Read one boolean authorization flag, refusing a value this parser cannot represent.\n *\n * Unknown frontmatter keys are ignored here for forward compatibility, and that is right for\n * metadata. It is wrong for these two: the simple-YAML dialect coerces only the literals `true`\n * and `false`, so `disable-model-invocation: yes` — a valid YAML boolean — arrives as the STRING\n * `\"yes\"`, compares unequal to `true`, and the skill is disclosed to the model. The author wrote a\n * restriction and got the default.\n *\n * A restriction that fails open is worse than one that is absent, because the author stops looking.\n * So the value is refused and named, and the run stops on the line that caused it.\n */\nfunction readAuthorizationFlag(\n parsed: Record<string, FrontmatterValue | undefined>,\n key: string,\n name: string,\n): boolean | undefined {\n const value = parsed[key];\n if (value === undefined) return undefined;\n if (typeof value === \"boolean\") return value;\n throw new ConfigurationError(\n `Skill ${name}: \"${key}\" must be true or false (got ${JSON.stringify(value)}) — ` +\n `this dialect reads only the literals \\`true\\` and \\`false\\`, and a value it cannot read ` +\n `would leave the skill disclosed`,\n { code: \"schema_invalid\" },\n );\n}\n\nfunction parseDependencies(raw: string | undefined): string[] | undefined {\n if (!hasContent(raw)) return undefined;\n const deps = (raw as string)\n .split(\",\")\n .map((s) => s.trim())\n .filter((s) => s.length > 0);\n return deps.length > 0 ? deps : undefined;\n}\n\nfunction hasContent(value: string | undefined): value is string {\n return value !== undefined && value.trim().length > 0;\n}\n","import { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { ConfigurationError } from \"../../../errors.js\";\nimport { assertNoSymlinkEscape, safePathJoin } from \"../../security/path-guard.js\";\nimport { readWorkspaceDir } from \"../config/workspace-dir.js\";\nimport { parseSkillFrontmatter, stripSkillFrontmatter } from \"./skill-frontmatter.js\";\n\n/**\n * A discovered skill's metadata. The skill BODY is never included — only the\n * strict frontmatter fields plus the resolved `source` path.\n *\n * Public via `@theokit/sdk/skills`.\n *\n * @public\n */\nexport interface Skill {\n name: string;\n description: string;\n /** Absolute path to the discovered `SKILL.md`. */\n source: string;\n category?: string;\n dependencies?: string[];\n /** `disable-model-invocation: true` — the model is never told this skill exists. */\n disableModelInvocation?: boolean;\n /** `user-invocable: false` — carried for a host that has a picker; this SDK has no such surface. */\n userInvocable?: boolean;\n}\n\n/**\n * Information passed to `onInvalidSkill` when a `SKILL.md` is present but its\n * frontmatter is malformed (missing required field or invalid YAML).\n *\n * @public\n */\nexport interface InvalidSkillInfo {\n /** The skill directory name (used as the fallback skill name). */\n name: string;\n /** Absolute path to the offending `SKILL.md`. */\n source: string;\n /** Typed reason: `missing_frontmatter` or `schema_invalid`. */\n code: string;\n message: string;\n}\n\n/**\n * Options for {@link discoverSkills}.\n *\n * @public\n */\nexport interface DiscoverSkillsOptions {\n /**\n * Called once per directory that contains a `SKILL.md` with malformed\n * frontmatter. The skill is excluded from the result; discovery continues\n * (strict-frontmatter ADR / EC-5). A directory WITHOUT a `SKILL.md` is NOT a\n * malformed skill and does not trigger this callback.\n *\n * Default: no-op (a library primitive must not write to the consumer's\n * stderr by default).\n */\n onInvalidSkill?: (info: InvalidSkillInfo) => void;\n}\n\n/**\n * Discover `SKILL.md` skills under an arbitrary directory.\n *\n * For each immediate subdirectory `<dir>/<name>/` containing a `SKILL.md`, the\n * file's strict YAML frontmatter is parsed (`name`/`description` required;\n * `category`/`dependencies` optional). Malformed skills are skipped (optionally\n * reported via {@link DiscoverSkillsOptions.onInvalidSkill}); a subdirectory\n * whose realpath escapes `dir` (via symlink) is skipped (symlink-escape guard,\n * reusing `@theokit/sdk/path-safety`).\n *\n * NEVER throws: a missing, unreadable, or non-directory `dir` yields `[]`.\n *\n * Discovery order follows the filesystem `readdir` order (OS-dependent). Sort\n * the result before {@link buildSkillsBlock} if a stable block order matters.\n *\n * Public via `@theokit/sdk/skills`.\n *\n * @public\n */\nexport async function discoverSkills(\n dir: string,\n options?: DiscoverSkillsOptions,\n): Promise<Skill[]> {\n let entries: Awaited<ReturnType<typeof readWorkspaceDir>>;\n try {\n entries = await readWorkspaceDir(dir, \"skills_read_error\", \"skills directory\");\n } catch {\n // never-throw contract: unreadable / not-a-directory → no skills (EC-1)\n return [];\n }\n\n const skills: Skill[] = [];\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n let skillDir: string;\n try {\n skillDir = safePathJoin(dir, entry.name);\n assertNoSymlinkEscape(skillDir, dir);\n } catch {\n continue;\n }\n const skillPath = join(skillDir, \"SKILL.md\");\n let raw: string;\n try {\n raw = await readFile(skillPath, \"utf8\");\n } catch {\n // no SKILL.md in this subdir → not a skill, not an error (EC-2)\n continue;\n }\n const skill = tryParseSkill(raw, entry.name, skillPath, options);\n if (skill !== undefined) skills.push(skill);\n }\n return skills;\n}\n\nfunction tryParseSkill(\n raw: string,\n fallbackName: string,\n source: string,\n options: DiscoverSkillsOptions | undefined,\n): Skill | undefined {\n try {\n const frontmatter = parseSkillFrontmatter(raw, fallbackName);\n const skill: Skill = {\n name: frontmatter.name,\n description: frontmatter.description,\n source,\n };\n if (frontmatter.category !== undefined) skill.category = frontmatter.category;\n if (frontmatter.dependencies !== undefined) skill.dependencies = frontmatter.dependencies;\n // The authorization flags travel with the record. Dropping them here would reproduce the defect\n // one layer down: the parser would read the declaration and the discovery result would not\n // carry it, which is indistinguishable from never having parsed it.\n if (frontmatter.disableModelInvocation !== undefined) {\n skill.disableModelInvocation = frontmatter.disableModelInvocation;\n }\n if (frontmatter.userInvocable !== undefined) skill.userInvocable = frontmatter.userInvocable;\n return skill;\n } catch (cause) {\n if (cause instanceof ConfigurationError) {\n options?.onInvalidSkill?.({\n name: fallbackName,\n source,\n code: cause.code ?? \"unknown\",\n message: cause.message,\n });\n return undefined;\n }\n throw cause;\n }\n}\n\n/**\n * Read the BODY of a discovered skill — everything after its frontmatter.\n *\n * A thin selector over {@link discoverSkills} rather than a second reader, which is the same\n * relationship `loadSubagentDefinition` has to `discoverSubagents` in the sibling domain: one\n * parser is the point.\n *\n * ## Why this exists rather than a field on `Skill`\n *\n * `Skill` documents that *\"the skill BODY is never included\"*. That is a written contract with no\n * written reason, and widening it on a guess about the reason is not a trade worth making — a\n * catalog you can put in a prompt without carrying every body is the likely intent, and this keeps\n * that shape intact for whoever relied on it.\n *\n * The body was never expensive to obtain: `discoverSkills` already reads each file in full and\n * discards everything but the frontmatter. What was missing was a door that hands it over.\n *\n * ## What it is for\n *\n * Turning a discovered skill into an inline one — `SkillsSettings.inline` requires `instructions`,\n * and without this the only route was to open `source` and split the frontmatter by hand. That is a\n * second implementation of this module's own convention, and it would fail SILENTLY if the format\n * moved: the frontmatter would land inside the instructions and nothing would say so.\n *\n * Reported by the `theocode` session, which needed exactly that to give an operator's\n * `~/.theokit/skills/` to an agent through the SDK's own parser.\n *\n * @param skill - a record returned by {@link discoverSkills}; its `source` is read.\n * @returns the trimmed body. A file that is all frontmatter yields an empty string.\n * @throws if `source` is unreadable — unlike discovery, which skips what it cannot read, a caller\n * naming ONE skill has asked about that skill and an empty string would answer a question it did\n * not ask.\n * @public\n */\nexport async function loadSkillInstructions(skill: Skill): Promise<string> {\n return stripSkillFrontmatter(await readFile(skill.source, \"utf8\"));\n}\n","/**\n * Block-body XML escape (ADR D9 — prompt-injection defence).\n *\n * Order matters: `&` MUST be escaped first so subsequent `<`/`>` replacements\n * do not double-encode the `&` characters they introduce.\n *\n * @internal\n */\nexport const escapeBlockBody = (s: string): string =>\n s.replace(/&/g, \"&\").replace(/</g, \"<\").replace(/>/g, \">\");\n","import { escapeBlockBody } from \"../system-prompt/escape.js\";\n\n/**\n * Render the `<skills>` system-prompt block from a skill list.\n *\n * Input is the structural subset `{ name, description }` — the skill BODY is\n * NOT in the type, so it cannot leak into the prompt. Both fields are passed\n * through `escapeBlockBody` to neutralise prompt-injection vectors hidden in\n * user-controlled SKILL.md frontmatter (injection-escape ADR).\n *\n * Returns `undefined` for an empty list so the caller can omit the block.\n *\n * Public via `@theokit/sdk/skills`.\n *\n * @public\n */\nexport function buildSkillsBlock(\n skills: ReadonlyArray<{ name: string; description: string }>,\n): string | undefined {\n if (skills.length === 0) return undefined;\n const lines = skills.map(\n (skill) => ` - ${escapeBlockBody(skill.name)}: ${escapeBlockBody(skill.description)}`,\n );\n return `<skills>\\n${lines.join(\"\\n\")}\\n</skills>`;\n}\n"]}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { generateCronId } from './chunk-
|
|
2
|
-
import { submit } from './chunk-
|
|
1
|
+
import { generateCronId } from './chunk-BJ7BPLQK.js';
|
|
2
|
+
import { submit } from './chunk-HWMGR3HA.js';
|
|
3
3
|
import { getAgentFacade } from './chunk-6X6ID4MO.js';
|
|
4
|
-
import { UnknownAgentError, ConfigurationError } from './chunk-
|
|
5
|
-
import { resolveApiKey } from './chunk-
|
|
4
|
+
import { UnknownAgentError, ConfigurationError } from './chunk-TNFOU6SB.js';
|
|
5
|
+
import { resolveApiKey } from './chunk-3OY6H3I7.js';
|
|
6
6
|
import { Cron } from 'croner';
|
|
7
7
|
|
|
8
8
|
// src/internal/cron/run-job.ts
|
|
@@ -451,5 +451,5 @@ async function updateJobStatus(jobId, enabled) {
|
|
|
451
451
|
}
|
|
452
452
|
|
|
453
453
|
export { Cron2 as Cron };
|
|
454
|
-
//# sourceMappingURL=chunk-
|
|
455
|
-
//# sourceMappingURL=chunk-
|
|
454
|
+
//# sourceMappingURL=chunk-NJBJ3CUG.js.map
|
|
455
|
+
//# sourceMappingURL=chunk-NJBJ3CUG.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/validate.ts","../src/internal/cron/scheduler.ts","../src/cron.ts"],"names":["Croner","Cron"],"mappings":"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","file":"chunk-6G4IRQUD.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 } from \"croner\";\nimport { 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 !== FIELD_RANGES.length) {\n throw new ConfigurationError(\n `Invalid cron expression: ${cron} (expected ${FIELD_RANGES.length} fields, got ${fields.length})`,\n { code: \"invalid_cron\" },\n );\n }\n for (const [index, range] of FIELD_RANGES.entries()) {\n // The length check above already established one field per range, so the lookup is total.\n // B-116: this replaces a `range === undefined` guard that no caller could reach — its single\n // caller only ran with exactly 5 fields, and FIELD_RANGES has exactly 5 entries, so the branch\n // stayed at 0 executions through 37 tests written specifically to enter it.\n const field = fields[index] as string;\n if (!isValidCronField(field, range)) {\n throw new ConfigurationError(`Invalid cron expression: ${cron} (field ${index + 1})`, {\n code: \"invalid_cron\",\n });\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\n/**\n * Digits, and nothing else. `Number.parseInt` stops at the first non-digit, so it reads `\"5abc\"` as\n * `5` and `\"0x5\"` as `0` — a numeric field parsed that way accepts garbage that happens to start\n * with a digit.\n *\n * This replaces the `String(n) === field` round-trip the literal and step validators used to carry.\n * The round-trip refused the garbage correctly but also refused `\"07\"`, because `String(7) !== \"07\"`\n * — and `isValidRange` never had it at all, so `\"1-5abc\"` was accepted while `\"5abc\"` was refused\n * (B-121). One predicate, applied to every field shape, closes both halves.\n *\n * The boundary that matters is croner 9, the scheduler this SDK actually fires jobs with. Measured\n * 2026-08-19: it ACCEPTS `\"07 * * * *\"` (next run at :07) and REFUSES `\"5abc\"`, `\"1-5abc\"`,\n * `\"1abc-5\"`, `\"0x5\"`, `\"5.9\"`, `\"+5\"` and `\"1e1\"` as \"illegal character\" (B-122). Validating\n * stricter than the engine rejects schedules that would have run; validating looser only moves the\n * failure from `Cron.create()` to fire time, where nobody is watching.\n *\n * @internal\n */\nconst DIGITS_ONLY = /^\\d+$/;\n\nfunction parseFieldNumber(text: string): number | undefined {\n if (!DIGITS_ONLY.test(text)) return undefined;\n return Number.parseInt(text, 10);\n}\n\nfunction isValidStep(stepStr: string, range: FieldRange): boolean {\n const step = parseFieldNumber(stepStr);\n return step !== undefined && 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 = parseFieldNumber(startStr);\n const end = parseFieldNumber(endStr);\n if (start === undefined || end === undefined) return false;\n return start >= range.min && end <= range.max && start <= end;\n}\n\nfunction isValidLiteral(field: string, range: FieldRange): boolean {\n const n = parseFieldNumber(field);\n return n !== undefined && 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 * Shorthand (`@daily`, …) to the POSIX five-field form Croner parses.\n *\n * Moved here from the scheduler: interpreting a cron expression is this module's subject, and\n * {@link nextRunAt} needs the same mapping. Two copies would let the scheduler and the value stored\n * on the job disagree about what `@weekly` means.\n *\n * @internal\n */\nexport function 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\n/**\n * When this expression next fires, or `undefined` when it never does again.\n *\n * This used to be `estimateNextRunAt`, which read neither of its parameters and returned\n * `Date.now() + 3600_000` for every input. Its docstring scoped it to fixture mode — \"real scheduling\n * uses a proper evaluator wired in by the local scheduler\" — and its one call site was\n * `Cron.create()`, so EVERY job created carried a `nextRunAt` one hour out whatever its schedule\n * said. A `@yearly` job reported that it would run in an hour. The scheduler corrected the value\n * later for jobs it picked up, so the fiction was visible exactly in the window between creating a\n * job and the scheduler reaching it — and permanently for a job the scheduler never runs.\n *\n * Croner is already a dependency and already computes this in the scheduler; this is the same call.\n * `undefined` rather than a filled-in number when there is no next run: `CronJob.nextRunAt` is\n * optional, and an absent next run is a real state (a one-shot date in the past), not a zero.\n *\n * @internal\n */\nexport function nextRunAt(cron: string, timezone: string): number | undefined {\n return new Cron(normalizeExpression(cron), { timezone }).nextRun()?.getTime();\n}\n","import { Cron as Croner } from \"croner\";\nimport type { CronJob } from \"../../types/cron.js\";\nimport { listJobs, upsertJob } from \"./store.js\";\nimport { normalizeExpression } from \"./validate.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","// 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 { nextRunAt, validateCronExpression, validateTimezone } 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 // Computed, not estimated. The predecessor returned now+1h for every expression, so a @yearly job\n // reported that it would run within the hour until the scheduler corrected it — and forever if the\n // scheduler never picked it up. Spread conditionally below: `nextRunAt` is optional, and \"no next\n // run\" is a real answer for a one-shot date in the past.\n const nextFireAt = nextRunAt(options.cron, timezone);\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 ...(nextFireAt === undefined ? {} : { nextRunAt: nextFireAt }),\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/validate.ts","../src/internal/cron/scheduler.ts","../src/cron.ts"],"names":["Croner","Cron"],"mappings":"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","file":"chunk-NJBJ3CUG.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 } from \"croner\";\nimport { 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 !== FIELD_RANGES.length) {\n throw new ConfigurationError(\n `Invalid cron expression: ${cron} (expected ${FIELD_RANGES.length} fields, got ${fields.length})`,\n { code: \"invalid_cron\" },\n );\n }\n for (const [index, range] of FIELD_RANGES.entries()) {\n // The length check above already established one field per range, so the lookup is total.\n // B-116: this replaces a `range === undefined` guard that no caller could reach — its single\n // caller only ran with exactly 5 fields, and FIELD_RANGES has exactly 5 entries, so the branch\n // stayed at 0 executions through 37 tests written specifically to enter it.\n const field = fields[index] as string;\n if (!isValidCronField(field, range)) {\n throw new ConfigurationError(`Invalid cron expression: ${cron} (field ${index + 1})`, {\n code: \"invalid_cron\",\n });\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\n/**\n * Digits, and nothing else. `Number.parseInt` stops at the first non-digit, so it reads `\"5abc\"` as\n * `5` and `\"0x5\"` as `0` — a numeric field parsed that way accepts garbage that happens to start\n * with a digit.\n *\n * This replaces the `String(n) === field` round-trip the literal and step validators used to carry.\n * The round-trip refused the garbage correctly but also refused `\"07\"`, because `String(7) !== \"07\"`\n * — and `isValidRange` never had it at all, so `\"1-5abc\"` was accepted while `\"5abc\"` was refused\n * (B-121). One predicate, applied to every field shape, closes both halves.\n *\n * The boundary that matters is croner 9, the scheduler this SDK actually fires jobs with. Measured\n * 2026-08-19: it ACCEPTS `\"07 * * * *\"` (next run at :07) and REFUSES `\"5abc\"`, `\"1-5abc\"`,\n * `\"1abc-5\"`, `\"0x5\"`, `\"5.9\"`, `\"+5\"` and `\"1e1\"` as \"illegal character\" (B-122). Validating\n * stricter than the engine rejects schedules that would have run; validating looser only moves the\n * failure from `Cron.create()` to fire time, where nobody is watching.\n *\n * @internal\n */\nconst DIGITS_ONLY = /^\\d+$/;\n\nfunction parseFieldNumber(text: string): number | undefined {\n if (!DIGITS_ONLY.test(text)) return undefined;\n return Number.parseInt(text, 10);\n}\n\nfunction isValidStep(stepStr: string, range: FieldRange): boolean {\n const step = parseFieldNumber(stepStr);\n return step !== undefined && 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 = parseFieldNumber(startStr);\n const end = parseFieldNumber(endStr);\n if (start === undefined || end === undefined) return false;\n return start >= range.min && end <= range.max && start <= end;\n}\n\nfunction isValidLiteral(field: string, range: FieldRange): boolean {\n const n = parseFieldNumber(field);\n return n !== undefined && 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 * Shorthand (`@daily`, …) to the POSIX five-field form Croner parses.\n *\n * Moved here from the scheduler: interpreting a cron expression is this module's subject, and\n * {@link nextRunAt} needs the same mapping. Two copies would let the scheduler and the value stored\n * on the job disagree about what `@weekly` means.\n *\n * @internal\n */\nexport function 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\n/**\n * When this expression next fires, or `undefined` when it never does again.\n *\n * This used to be `estimateNextRunAt`, which read neither of its parameters and returned\n * `Date.now() + 3600_000` for every input. Its docstring scoped it to fixture mode — \"real scheduling\n * uses a proper evaluator wired in by the local scheduler\" — and its one call site was\n * `Cron.create()`, so EVERY job created carried a `nextRunAt` one hour out whatever its schedule\n * said. A `@yearly` job reported that it would run in an hour. The scheduler corrected the value\n * later for jobs it picked up, so the fiction was visible exactly in the window between creating a\n * job and the scheduler reaching it — and permanently for a job the scheduler never runs.\n *\n * Croner is already a dependency and already computes this in the scheduler; this is the same call.\n * `undefined` rather than a filled-in number when there is no next run: `CronJob.nextRunAt` is\n * optional, and an absent next run is a real state (a one-shot date in the past), not a zero.\n *\n * @internal\n */\nexport function nextRunAt(cron: string, timezone: string): number | undefined {\n return new Cron(normalizeExpression(cron), { timezone }).nextRun()?.getTime();\n}\n","import { Cron as Croner } from \"croner\";\nimport type { CronJob } from \"../../types/cron.js\";\nimport { listJobs, upsertJob } from \"./store.js\";\nimport { normalizeExpression } from \"./validate.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","// 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 { nextRunAt, validateCronExpression, validateTimezone } 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 // Computed, not estimated. The predecessor returned now+1h for every expression, so a @yearly job\n // reported that it would run within the hour until the scheduler corrected it — and forever if the\n // scheduler never picked it up. Spread conditionally below: `nextRunAt` is optional, and \"no next\n // run\" is a real answer for a one-shot date in the past.\n const nextFireAt = nextRunAt(options.cron, timezone);\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 ...(nextFireAt === undefined ? {} : { nextRunAt: nextFireAt }),\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 { registerBuiltins, listProviders, getProviderProfile } from './chunk-
|
|
1
|
+
import { registerBuiltins, listProviders, getProviderProfile } from './chunk-5HSMH2ZZ.js';
|
|
2
2
|
|
|
3
3
|
// src/providers.ts
|
|
4
4
|
function listProviders2() {
|
|
@@ -11,5 +11,5 @@ function getProviderProfile2(name) {
|
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
export { getProviderProfile2 as getProviderProfile, listProviders2 as listProviders };
|
|
14
|
-
//# sourceMappingURL=chunk-
|
|
15
|
-
//# sourceMappingURL=chunk-
|
|
14
|
+
//# sourceMappingURL=chunk-NKQVLWDF.js.map
|
|
15
|
+
//# sourceMappingURL=chunk-NKQVLWDF.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/providers.ts"],"names":["listProviders","getProviderProfile"],"mappings":";;;AA8BO,SAASA,cAAAA,GAA4C;AAC1D,EAAA,gBAAA,EAAiB;AACjB,EAAA,OAAO,aAAA,EAAa;AACtB;AAQO,SAASC,oBAAmB,IAAA,EAA2C;AAC5E,EAAA,gBAAA,EAAiB;AACjB,EAAA,OAAO,mBAAW,IAAI,CAAA;AACxB","file":"chunk-
|
|
1
|
+
{"version":3,"sources":["../src/providers.ts"],"names":["listProviders","getProviderProfile"],"mappings":";;;AA8BO,SAASA,cAAAA,GAA4C;AAC1D,EAAA,gBAAA,EAAiB;AACjB,EAAA,OAAO,aAAA,EAAa;AACtB;AAQO,SAASC,oBAAmB,IAAA,EAA2C;AAC5E,EAAA,gBAAA,EAAiB;AACjB,EAAA,OAAO,mBAAW,IAAI,CAAA;AACxB","file":"chunk-NKQVLWDF.js","sourcesContent":["/**\n * Published as `@theokit/sdk/providers`.\n *\n * The provider registry, as public API.\n *\n * It was `@internal`, which meant the SDK was the only thing that could answer \"which providers\n * exist, and what does each one need?\". `theokit` consequently kept a hand-written list of three —\n * against the 46 registered here — so an agent declaring `ollama/qwen2.5:3b` routed to whatever\n * key happened to be set instead of to Ollama (usetheokit/theokit#326).\n *\n * A second table that nothing forces to agree with the first is not a cache, it is a future bug.\n * These two functions exist so there is one table.\n *\n * Both ensure the builtins are registered before answering: registration is lazy (it happens when\n * an agent is created, a run is routed, or a provider is defined), so a caller asking early would\n * otherwise get an empty registry and reasonably conclude the SDK knows nothing.\n */\n\nimport { registerBuiltins } from \"./internal/providers/builtin/index.js\";\nimport {\n getProviderProfile as getProfile,\n listProviders as listProfiles,\n} from \"./internal/providers/registry.js\";\nimport type { ProviderProfile } from \"./internal/providers/types.js\";\n\n/**\n * Every registered provider — builtins, the JSON catalog, and anything a plugin registered.\n *\n * @public\n */\nexport function listProviders(): readonly ProviderProfile[] {\n registerBuiltins();\n return listProfiles();\n}\n\n/**\n * One provider by name or alias (`lm-studio` resolves to `lmstudio`), or `undefined` when nothing\n * has registered it.\n *\n * @public\n */\nexport function getProviderProfile(name: string): ProviderProfile | undefined {\n registerBuiltins();\n return getProfile(name);\n}\n"]}
|