@theokit/sdk 5.2.1 → 5.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/CHANGELOG.md +121 -0
  2. package/dist/{agent-VUNM33WJ.js → agent-G4OFQYLE.js} +3 -3
  3. package/dist/{agent-VUNM33WJ.js.map → agent-G4OFQYLE.js.map} +1 -1
  4. package/dist/{agent-GACKKINM.cjs → agent-UXU5AIOJ.cjs} +4 -4
  5. package/dist/{agent-GACKKINM.cjs.map → agent-UXU5AIOJ.cjs.map} +1 -1
  6. package/dist/agent.d.ts +20 -2
  7. package/dist/{chunk-DEJCKB65.cjs → chunk-5XNRWMMD.cjs} +37 -9
  8. package/dist/chunk-5XNRWMMD.cjs.map +1 -0
  9. package/dist/{chunk-PEAOQMWE.cjs → chunk-OZT6T2RI.cjs} +4 -4
  10. package/dist/{chunk-PEAOQMWE.cjs.map → chunk-OZT6T2RI.cjs.map} +1 -1
  11. package/dist/{chunk-43H4EBS2.js → chunk-ZFEOAC52.js} +35 -7
  12. package/dist/chunk-ZFEOAC52.js.map +1 -0
  13. package/dist/{chunk-WHTMFN4Q.js → chunk-ZU3HQCKR.js} +3 -3
  14. package/dist/{chunk-WHTMFN4Q.js.map → chunk-ZU3HQCKR.js.map} +1 -1
  15. package/dist/cron.cjs +3 -3
  16. package/dist/cron.js +2 -2
  17. package/dist/eval.cjs +2 -2
  18. package/dist/eval.js +1 -1
  19. package/dist/index.cjs +18 -18
  20. package/dist/index.d.cts +20 -2
  21. package/dist/index.d.ts +20 -2
  22. package/dist/index.js +4 -4
  23. package/dist/internal/persistence/list-sessions.d.cts +98 -0
  24. package/dist/internal/persistence/list-sessions.d.ts +98 -0
  25. package/dist/persistence.cjs +65 -0
  26. package/dist/persistence.cjs.map +1 -1
  27. package/dist/persistence.d.cts +1 -0
  28. package/dist/persistence.d.ts +1 -0
  29. package/dist/persistence.js +67 -2
  30. package/dist/persistence.js.map +1 -1
  31. package/docs/harness-capability-map.md +5 -1
  32. package/package.json +1 -1
  33. package/dist/chunk-43H4EBS2.js.map +0 -1
  34. package/dist/chunk-DEJCKB65.cjs.map +0 -1
@@ -1,4 +1,4 @@
1
- import { generateCronId } from './chunk-43H4EBS2.js';
1
+ import { generateCronId } from './chunk-ZFEOAC52.js';
2
2
  import { submit } from './chunk-K2VMFZQ5.js';
3
3
  import { getAgentFacade } from './chunk-6X6ID4MO.js';
4
4
  import { UnknownAgentError, ConfigurationError } from './chunk-ALUN2B4W.js';
@@ -451,5 +451,5 @@ async function updateJobStatus(jobId, enabled) {
451
451
  }
452
452
 
453
453
  export { Cron2 as Cron };
454
- //# sourceMappingURL=chunk-WHTMFN4Q.js.map
455
- //# sourceMappingURL=chunk-WHTMFN4Q.js.map
454
+ //# sourceMappingURL=chunk-ZU3HQCKR.js.map
455
+ //# sourceMappingURL=chunk-ZU3HQCKR.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":";;;;;;;;AAoBA,eAAsB,WAAW,GAAA,EAA0C;AAIzE,EAAA,IAAI,GAAA,CAAI,aAAa,MAAA,EAAW,OAAO,IAAI,QAAA,CAAS,GAAA,CAAI,IAAI,SAAS,CAAA;AACrE,EAAA,IAAI,GAAA,CAAI,UAAU,MAAA,EAAW,OAAO,sBAAsB,GAAA,CAAI,KAAA,EAAO,cAAA,CAAe,GAAG,CAAC,CAAA;AACxF,EAAA,IAAI,GAAA,CAAI,YAAY,MAAA,EAAW,OAAO,qBAAqB,GAAA,CAAI,OAAA,EAAS,cAAA,CAAe,GAAG,CAAC,CAAA;AAC3F,EAAA,MAAM,IAAI,kBAAA;AAAA,IACR,CAAA,SAAA,EAAY,IAAI,EAAE,CAAA,+DAAA,CAAA;AAAA,IAClB,EAAE,MAAM,gBAAA;AAAiB,GAC3B;AACF;AAOO,SAAS,WAAW,OAAA,EAA4C;AACrE,EAAA,OAAO,OAAQ,QAAgB,IAAA,KAAS,UAAA;AAC1C;AAGA,SAAS,eAAe,GAAA,EAAuC;AAC7D,EAAA,IAAI,GAAA,CAAI,YAAY,MAAA,EAAW;AAC7B,IAAA,MAAM,IAAI,kBAAA,CAAmB,CAAA,SAAA,EAAY,GAAA,CAAI,EAAE,CAAA,uCAAA,CAAA,EAA2C;AAAA,MACxF,IAAA,EAAM;AAAA,KACP,CAAA;AAAA,EACH;AACA,EAAA,OAAO,GAAA,CAAI,OAAA;AACb;AAEA,eAAe,oBAAA,CACb,SACA,OAAA,EACc;AACd,EAAA,MAAM,IAAA,GAAO,MAAM,cAAA,EAAe,CAC/B,IAAI,OAAO,CAAA,CACX,KAAA,CAAM,MAAM,MAAS,CAAA;AACxB,EAAA,IAAI,SAAS,MAAA,EAAW;AACtB,IAAA,MAAM,IAAI,iBAAA;AAAA,MACR,gCAAgC,OAAO,CAAA,mIAAA,CAAA;AAAA,MACvC,EAAE,MAAM,sBAAA;AAAuB,KACjC;AAAA,EACF;AACA,EAAA,MAAM,KAAA,GAAQ,MAAM,cAAA,EAAe,CAAE,OAAO,OAAO,CAAA;AACnD,EAAA,OAAO,KAAA,CAAM,KAAK,OAAO,CAAA;AAC3B;AAEA,eAAe,qBAAA,CACb,aACA,OAAA,EACc;AACd,EAAA,MAAM,KAAA,GAAQ,MAAM,cAAA,EAAe,CAAE,OAAO,WAAW,CAAA;AACvD,EAAA,OAAO,KAAA,CAAM,KAAK,OAAO,CAAA;AAC3B;;;AC3DA,eAAsB,kBAAkB,GAAA,EAA6B;AAEnE,EAAA,MAAM,MAAA,GAAS,KAAK,GAAA,EAAI;AACxB,EAAA,MAAM,MAAA,GAAS,CAAA,KAAA,EAAQ,GAAA,CAAI,EAAE,IAAI,MAAM,CAAA,CAAA;AACvC,EAAA,IAAI;AACF,IAAA,MAAM,MAAA,CAAmB;AAAA,MACvB,IAAA,EAAM,MAAA;AAAA,MACN,EAAA,EAAI,MAAA;AAAA,MACJ,mBAAA,EAAqB,IAAA;AAAA,MACrB,IAAA,EAAM,EAAE,KAAA,EAAO,GAAA,CAAI,EAAA,EAAI,OAAA,EAAS,GAAA,CAAI,IAAA,EAAM,QAAA,EAAU,GAAA,CAAI,IAAA,EAAM,OAAA,EAAS,MAAA,EAAO;AAAA,MAC9E,IAAA,EAAM,OAAO,GAAA,KAAQ;AACnB,QAAA,MAAM,OAAA,GAAU,MAAM,UAAA,CAAW,GAAG,CAAA;AACpC,QAAA,IAAI,UAAA,CAAW,OAAO,CAAA,EAAG;AAEvB,UAAA,GAAA,CAAI,MAAA,CAAO,iBAAiB,OAAA,EAAS,MAAM,KAAK,OAAA,CAAQ,MAAA,EAAO,CAAE,KAAA,CAAM,MAAM;AAAA,UAAC,CAAC,CAAA,EAAG;AAAA,YAChF,IAAA,EAAM;AAAA,WACP,CAAA;AACD,UAAA,MAAM,MAAA,GAAS,MAAM,OAAA,CAAQ,IAAA,EAAK;AAClC,UAAA,GAAA,CAAI,IAAA,CAAK,EAAE,MAAA,EAAQ,MAAA,CAAO,QAAQ,KAAA,EAAO,OAAA,CAAQ,IAAI,CAAA;AACrD,UAAA,OAAO,EAAE,MAAA,EAAQ,MAAA,CAAO,MAAA,EAAQ,KAAA,EAAO,QAAQ,EAAA,EAAG;AAAA,QACpD;AAEA,QAAA,GAAA,CAAI,IAAA,CAAK,EAAE,MAAA,EAAQ,OAAA,CAAQ,QAAQ,KAAA,EAAO,OAAA,CAAQ,IAAI,CAAA;AACtD,QAAA,OAAO,EAAE,MAAA,EAAQ,OAAA,CAAQ,MAAA,EAAQ,KAAA,EAAO,QAAQ,EAAA,EAAG;AAAA,MACrD;AAAA,KACD,CAAA;AAAA,EACH,CAAA,CAAA,MAAQ;AAMN,IAAA,MAAM,OAAA,GAAU,MAAM,UAAA,CAAW,GAAG,CAAA;AACpC,IAAA,IAAI,UAAA,CAAW,OAAO,CAAA,EAAG,MAAM,QAAQ,IAAA,EAAK;AAAA,EAC9C;AACF;;;AC1CA,IAAM,IAAA,uBAAW,GAAA,EAAqB;AAG/B,SAAS,QAAA,GAAsB;AACpC,EAAA,OAAO,KAAA,CAAM,IAAA,CAAK,IAAA,CAAK,MAAA,EAAQ,CAAA;AACjC;AAGO,SAAS,QAAA,GAAmB;AACjC,EAAA,OAAO,IAAA,CAAK,IAAA;AACd;AAGO,SAAS,OAAO,KAAA,EAAoC;AACzD,EAAA,OAAO,IAAA,CAAK,IAAI,KAAK,CAAA;AACvB;AAGO,SAAS,UAAU,GAAA,EAAoB;AAC5C,EAAA,IAAA,CAAK,GAAA,CAAI,GAAA,CAAI,EAAA,EAAI,GAAG,CAAA;AACtB;AAGO,SAAS,UAAU,KAAA,EAAwB;AAChD,EAAA,OAAO,IAAA,CAAK,OAAO,KAAK,CAAA;AAC1B;ACxBA,IAAM,UAAA,uBAAiB,GAAA,CAAI,CAAC,WAAW,QAAA,EAAU,SAAA,EAAW,UAAA,EAAY,SAAS,CAAC,CAAA;AAOlF,IAAM,YAAA,GAAsC;AAAA,EAC1C,EAAE,GAAA,EAAK,CAAA,EAAG,GAAA,EAAK,EAAA,EAAG;AAAA;AAAA,EAClB,EAAE,GAAA,EAAK,CAAA,EAAG,GAAA,EAAK,EAAA,EAAG;AAAA;AAAA,EAClB,EAAE,GAAA,EAAK,CAAA,EAAG,GAAA,EAAK,EAAA,EAAG;AAAA;AAAA,EAClB,EAAE,GAAA,EAAK,CAAA,EAAG,GAAA,EAAK,EAAA,EAAG;AAAA;AAAA,EAClB,EAAE,GAAA,EAAK,CAAA,EAAG,GAAA,EAAK,CAAA;AAAE;AACnB,CAAA;AASO,SAAS,uBAAuB,IAAA,EAAoB;AACzD,EAAA,IAAI,OAAO,IAAA,KAAS,QAAA,IAAY,IAAA,CAAK,WAAW,CAAA,EAAG;AACjD,IAAA,MAAM,IAAI,mBAAmB,gCAAA,EAAkC;AAAA,MAC7D,IAAA,EAAM;AAAA,KACP,CAAA;AAAA,EACH;AACA,EAAA,IAAI,IAAA,CAAK,UAAA,CAAW,GAAG,CAAA,EAAG;AACxB,IAAA,IAAI,CAAC,UAAA,CAAW,GAAA,CAAI,IAAI,CAAA,EAAG;AACzB,MAAA,MAAM,IAAI,kBAAA,CAAmB,CAAA,2CAAA,EAA8C,IAAI,CAAA,CAAA,EAAI;AAAA,QACjF,IAAA,EAAM;AAAA,OACP,CAAA;AAAA,IACH;AACA,IAAA;AAAA,EACF;AAEA,EAAA,MAAM,MAAA,GAAS,IAAA,CAAK,IAAA,EAAK,CAAE,MAAM,KAAK,CAAA;AACtC,EAAA,IAAI,MAAA,CAAO,MAAA,KAAW,YAAA,CAAa,MAAA,EAAQ;AACzC,IAAA,MAAM,IAAI,kBAAA;AAAA,MACR,4BAA4B,IAAI,CAAA,WAAA,EAAc,aAAa,MAAM,CAAA,aAAA,EAAgB,OAAO,MAAM,CAAA,CAAA,CAAA;AAAA,MAC9F,EAAE,MAAM,cAAA;AAAe,KACzB;AAAA,EACF;AACA,EAAA,KAAA,MAAW,CAAC,KAAA,EAAO,KAAK,CAAA,IAAK,YAAA,CAAa,SAAQ,EAAG;AAKnD,IAAA,MAAM,KAAA,GAAQ,OAAO,KAAK,CAAA;AAC1B,IAAA,IAAI,CAAC,gBAAA,CAAiB,KAAA,EAAO,KAAK,CAAA,EAAG;AACnC,MAAA,MAAM,IAAI,kBAAA,CAAmB,CAAA,yBAAA,EAA4B,IAAI,CAAA,QAAA,EAAW,KAAA,GAAQ,CAAC,CAAA,CAAA,CAAA,EAAK;AAAA,QACpF,IAAA,EAAM;AAAA,OACP,CAAA;AAAA,IACH;AAAA,EACF;AACF;AAEA,SAAS,gBAAA,CAAiB,OAAe,KAAA,EAA4B;AACnE,EAAA,IAAI,KAAA,KAAU,KAAK,OAAO,IAAA;AAC1B,EAAA,IAAI,KAAA,CAAM,UAAA,CAAW,IAAI,CAAA,EAAG,OAAO,YAAY,KAAA,CAAM,KAAA,CAAM,CAAC,CAAA,EAAG,KAAK,CAAA;AACpE,EAAA,IAAI,KAAA,CAAM,QAAA,CAAS,GAAG,CAAA,EAAG;AACvB,IAAA,OAAO,KAAA,CAAM,KAAA,CAAM,GAAG,CAAA,CAAE,KAAA,CAAM,CAAC,IAAA,KAAS,gBAAA,CAAiB,IAAA,EAAM,KAAK,CAAC,CAAA;AAAA,EACvE;AACA,EAAA,IAAI,MAAM,QAAA,CAAS,GAAG,GAAG,OAAO,YAAA,CAAa,OAAO,KAAK,CAAA;AACzD,EAAA,OAAO,cAAA,CAAe,OAAO,KAAK,CAAA;AACpC;AAoBA,IAAM,WAAA,GAAc,OAAA;AAEpB,SAAS,iBAAiB,IAAA,EAAkC;AAC1D,EAAA,IAAI,CAAC,WAAA,CAAY,IAAA,CAAK,IAAI,GAAG,OAAO,MAAA;AACpC,EAAA,OAAO,MAAA,CAAO,QAAA,CAAS,IAAA,EAAM,EAAE,CAAA;AACjC;AAEA,SAAS,WAAA,CAAY,SAAiB,KAAA,EAA4B;AAChE,EAAA,MAAM,IAAA,GAAO,iBAAiB,OAAO,CAAA;AACrC,EAAA,OAAO,IAAA,KAAS,MAAA,IAAa,IAAA,GAAO,CAAA,IAAK,QAAQ,KAAA,CAAM,GAAA;AACzD;AAEA,SAAS,YAAA,CAAa,OAAe,KAAA,EAA4B;AAC/D,EAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,KAAA,CAAM,GAAG,CAAA;AAC7B,EAAA,IAAI,KAAA,CAAM,MAAA,KAAW,CAAA,EAAG,OAAO,KAAA;AAC/B,EAAA,MAAM,CAAC,QAAA,EAAU,MAAM,CAAA,GAAI,KAAA;AAC3B,EAAA,IAAI,QAAA,KAAa,MAAA,IAAa,MAAA,KAAW,MAAA,EAAW,OAAO,KAAA;AAC3D,EAAA,MAAM,KAAA,GAAQ,iBAAiB,QAAQ,CAAA;AACvC,EAAA,MAAM,GAAA,GAAM,iBAAiB,MAAM,CAAA;AACnC,EAAA,IAAI,KAAA,KAAU,MAAA,IAAa,GAAA,KAAQ,MAAA,EAAW,OAAO,KAAA;AACrD,EAAA,OAAO,SAAS,KAAA,CAAM,GAAA,IAAO,GAAA,IAAO,KAAA,CAAM,OAAO,KAAA,IAAS,GAAA;AAC5D;AAEA,SAAS,cAAA,CAAe,OAAe,KAAA,EAA4B;AACjE,EAAA,MAAM,CAAA,GAAI,iBAAiB,KAAK,CAAA;AAChC,EAAA,OAAO,MAAM,MAAA,IAAa,CAAA,IAAK,KAAA,CAAM,GAAA,IAAO,KAAK,KAAA,CAAM,GAAA;AACzD;AAQO,SAAS,iBAAiB,QAAA,EAAwB;AACvD,EAAA,IAAI;AACF,IAAA,IAAI,KAAK,cAAA,CAAe,OAAA,EAAS,EAAE,QAAA,EAAU,UAAU,CAAA;AAAA,EACzD,CAAA,CAAA,MAAQ;AACN,IAAA,MAAM,IAAI,kBAAA,CAAmB,CAAA,uBAAA,EAA0B,QAAQ,CAAA,CAAA,EAAI;AAAA,MACjE,IAAA,EAAM;AAAA,KACP,CAAA;AAAA,EACH;AACF;AAWO,SAAS,oBAAoB,IAAA,EAAsB;AACxD,EAAA,QAAQ,IAAA;AAAM,IACZ,KAAK,SAAA;AACH,MAAA,OAAO,WAAA;AAAA,IACT,KAAK,QAAA;AACH,MAAA,OAAO,WAAA;AAAA,IACT,KAAK,SAAA;AACH,MAAA,OAAO,WAAA;AAAA,IACT,KAAK,UAAA;AACH,MAAA,OAAO,WAAA;AAAA,IACT,KAAK,SAAA;AACH,MAAA,OAAO,WAAA;AAAA,IACT;AACE,MAAA,OAAO,IAAA;AAAA;AAEb;AAmBO,SAAS,SAAA,CAAU,MAAc,QAAA,EAAsC;AAC5E,EAAA,OAAO,IAAI,IAAA,CAAK,mBAAA,CAAoB,IAAI,CAAA,EAAG,EAAE,QAAA,EAAU,CAAA,CAAE,OAAA,EAAQ,EAAG,OAAA,EAAQ;AAC9E;;;AClKA,IAAM,QAAwB,EAAE,OAAA,EAAS,OAAO,MAAA,kBAAQ,IAAI,KAAI,EAAE;AAS3D,SAAS,mBAAmB,OAAA,EAA4C;AAC7E,EAAA,KAAA,CAAM,WAAA,GAAc,OAAA;AACtB;AAGO,SAAS,eAAe,GAAA,EAAoB;AACjD,EAAA,KAAA,CAAM,OAAA,GAAU,IAAA;AAChB,EAAA,IAAI,GAAA,KAAQ,MAAA,EAAW,KAAA,CAAM,GAAA,GAAM,GAAA;AACnC,EAAA,KAAA,MAAW,GAAA,IAAO,UAAS,EAAG;AAC5B,IAAA,IAAI,IAAI,OAAA,KAAY,OAAA,IAAW,IAAI,OAAA,KAAY,KAAA,cAAmB,GAAG,CAAA;AAAA,EACvE;AACF;AAGO,SAAS,aAAA,GAAsB;AACpC,EAAA,KAAA,CAAM,OAAA,GAAU,KAAA;AAChB,EAAA,KAAA,MAAW,SAAS,KAAA,CAAM,MAAA,CAAO,MAAA,EAAO,QAAS,IAAA,EAAK;AACtD,EAAA,KAAA,CAAM,OAAO,KAAA,EAAM;AACrB;AAGO,SAAS,YAAY,GAAA,EAAoB;AAC9C,EAAA,IAAI,CAAC,MAAM,OAAA,EAAS;AACpB,EAAA,aAAA,CAAc,IAAI,EAAE,CAAA;AACpB,EAAA,MAAM,UAAA,GAAa,mBAAA,CAAoB,GAAA,CAAI,IAAI,CAAA;AAC/C,EAAA,MAAM,QAAQ,IAAIA,IAAA;AAAA,IAChB,UAAA;AAAA,IACA,EAAE,UAAU,GAAA,CAAI,QAAA,EAAU,MAAM,GAAA,CAAI,EAAA,EAAI,SAAS,IAAA,EAAK;AAAA,IACtD,MAAM;AACJ,MAAA,KAAK,OAAA,CAAQ,IAAI,EAAE,CAAA;AAAA,IACrB;AAAA,GACF;AACA,EAAA,KAAA,CAAM,MAAA,CAAO,GAAA,CAAI,GAAA,CAAI,EAAA,EAAI,KAAK,CAAA;AAC9B,EAAA,gBAAA,CAAiB,GAAA,CAAI,IAAI,KAAK,CAAA;AAChC;AAGO,SAAS,cAAc,KAAA,EAAwB;AACpD,EAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,MAAA,CAAO,GAAA,CAAI,KAAK,CAAA;AACpC,EAAA,IAAI,KAAA,KAAU,QAAW,OAAO,KAAA;AAChC,EAAA,KAAA,CAAM,IAAA,EAAK;AACX,EAAA,KAAA,CAAM,MAAA,CAAO,OAAO,KAAK,CAAA;AACzB,EAAA,OAAO,IAAA;AACT;AAGO,SAAS,iBAAA,GAAwD;AACtE,EAAA,MAAM,MAAA,GAA6C,EAAE,OAAA,EAAS,KAAA,CAAM,OAAA,EAAQ;AAC5E,EAAA,IAAI,KAAA,CAAM,GAAA,KAAQ,MAAA,EAAW,MAAA,CAAO,MAAM,KAAA,CAAM,GAAA;AAChD,EAAA,OAAO,MAAA;AACT;AAEA,eAAe,QAAQ,KAAA,EAA8B;AACnD,EAAA,MAAM,KAAA,GAAQ,UAAS,CAAE,IAAA,CAAK,CAAC,KAAA,KAAU,KAAA,CAAM,OAAO,KAAK,CAAA;AAC3D,EAAA,IAAI,KAAA,KAAU,MAAA,IAAa,KAAA,CAAM,OAAA,KAAY,KAAA,EAAO;AACpD,EAAA,MAAM,UAAU,KAAA,CAAM,WAAA;AACtB,EAAA,SAAA,CAAU,EAAE,GAAG,KAAA,EAAO,WAAW,IAAA,CAAK,GAAA,IAAO,CAAA;AAC7C,EAAA,IAAI,YAAY,MAAA,EAAW;AAC3B,EAAA,IAAI;AACF,IAAA,MAAM,QAAQ,KAAK,CAAA;AAAA,EACrB,CAAA,CAAA,MAAQ;AAAA,EAGR;AACF;AAEA,SAAS,gBAAA,CAAiB,OAAe,KAAA,EAAqB;AAC5D,EAAA,MAAM,IAAA,GAAO,MAAM,OAAA,EAAQ;AAC3B,EAAA,IAAI,SAAS,IAAA,EAAM;AACnB,EAAA,MAAM,QAAA,GAAW,UAAS,CAAE,IAAA,CAAK,CAAC,KAAA,KAAU,KAAA,CAAM,OAAO,KAAK,CAAA;AAC9D,EAAA,IAAI,aAAa,MAAA,EAAW;AAC5B,EAAA,SAAA,CAAU,EAAE,GAAG,QAAA,EAAU,WAAW,IAAA,CAAK,OAAA,IAAW,CAAA;AACtD;;;AC/DO,IAAMC,QAAN,MAAW;AAAA,EACR,WAAA,GAAc;AAAA,EAEtB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,aAAa,OAAO,OAAA,EAA8C;AAChE,IAAA,MAAM,GAAA,GAAM,MAAM,aAAA,CAAc,OAAO,CAAA;AACvC,IAAA,IAAI,IAAI,OAAA,KAAY,OAAA,IAAW,IAAI,OAAA,KAAY,KAAA,cAAmB,GAAG,CAAA;AACrE,IAAA,OAAO,GAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAAO,IAAA,CAAK,OAAA,GAA2B,EAAC,EAAiC;AACvE,IAAA,MAAM,gBAAgB,OAAA,CAAQ,OAAA;AAC9B,IAAA,MAAM,KAAA,GAAQ,UAAS,CAAE,MAAA;AAAA,MAAO,CAAC,GAAA,KAC/B,aAAA,KAAkB,MAAA,GAAY,IAAA,GAAO,IAAI,OAAA,KAAY;AAAA,KACvD;AACA,IAAA,OAAO,OAAA,CAAQ,OAAA,CAAQ,EAAE,KAAA,EAAO,CAAA;AAAA,EAClC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAAO,GAAA,CAAI,KAAA,EAAe,QAAA,GAA2B,EAAC,EAAqB;AACzE,IAAA,MAAM,GAAA,GAAM,OAAO,KAAK,CAAA;AACxB,IAAA,IAAI,QAAQ,MAAA,EAAW;AACrB,MAAA,OAAO,OAAA,CAAQ,MAAA;AAAA,QACb,IAAI,kBAAkB,CAAA,SAAA,EAAY,KAAK,cAAc,EAAE,IAAA,EAAM,oBAAoB;AAAA,OACnF;AAAA,IACF;AACA,IAAA,OAAO,OAAA,CAAQ,QAAQ,GAAG,CAAA;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAAO,MAAA,CAAO,KAAA,EAAe,QAAA,GAAiC,EAAC,EAAkB;AAC/E,IAAA,aAAA,CAAc,KAAK,CAAA;AACnB,IAAA,SAAA,CAAU,KAAK,CAAA;AACf,IAAA,OAAO,QAAQ,OAAA,EAAQ;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,aAAa,MAAA,CAAO,KAAA,EAAe,QAAA,GAAiC,EAAC,EAAqB;AACxF,IAAA,OAAO,eAAA,CAAgB,OAAO,IAAI,CAAA;AAAA,EACpC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,aAAa,OAAA,CAAQ,KAAA,EAAe,QAAA,GAAiC,EAAC,EAAqB;AACzF,IAAA,OAAO,eAAA,CAAgB,OAAO,KAAK,CAAA;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,aAAa,GAAA,CACX,KAAA,EACA,QAAA,GAA2B,EAAC,EAC8B;AAC1D,IAAA,MAAM,GAAA,GAAM,OAAO,KAAK,CAAA;AACxB,IAAA,IAAI,QAAQ,MAAA,EAAW;AACrB,MAAA,MAAM,IAAI,kBAAkB,CAAA,SAAA,EAAY,KAAK,cAAc,EAAE,IAAA,EAAM,oBAAoB,CAAA;AAAA,IACzF;AACA,IAAA,OAAO,WAAW,GAAG,CAAA;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAAO,KAAA,CAAM,OAAA,GAA4B,EAAC,EAAkB;AAK1D,IAAA,kBAAA,CAAmB,iBAAiB,CAAA;AACpC,IAAA,cAAA,CAAe,QAAQ,GAAG,CAAA;AAC1B,IAAA,OAAO,QAAQ,OAAA,EAAQ;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAAO,IAAA,GAAsB;AAC3B,IAAA,aAAA,EAAc;AACd,IAAA,OAAO,QAAQ,OAAA,EAAQ;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAAO,MAAA,CAAO,QAAA,GAA6B,EAAC,EAAiC;AAC3E,IAAA,MAAM,YAAY,iBAAA,EAAkB;AACpC,IAAA,OAAO,OAAA,CAAQ,QAAQ,EAAE,OAAA,EAAS,UAAU,OAAA,EAAS,QAAA,EAAU,QAAA,EAAS,EAAG,CAAA;AAAA,EAC7E;AACF;AAEA,eAAe,cAAc,OAAA,EAA8C;AACzE,EAAA,kBAAA,CAAmB,OAAO,CAAA;AAE1B,EAAA,sBAAA,CAAuB,QAAQ,IAAI,CAAA;AACnC,EAAA,MAAM,QAAA,GAAW,QAAQ,QAAA,IAAY,KAAA;AACrC,EAAA,gBAAA,CAAiB,QAAQ,CAAA;AAGzB,EAAA,aAAA,CAAc,QAAQ,MAAM,CAAA;AAE5B,EAAA,MAAM,OAAA,GAAU,cAAc,OAAO,CAAA;AACrC,EAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AAKrB,EAAA,MAAM,UAAA,GAAa,SAAA,CAAU,OAAA,CAAQ,IAAA,EAAM,QAAQ,CAAA;AACnD,EAAA,MAAM,GAAA,GAAe;AAAA,IACnB,IAAI,cAAA,EAAe;AAAA,IACnB,MAAM,OAAA,CAAQ,IAAA;AAAA,IACd,QAAA;AAAA,IACA,OAAA,EAAS,QAAQ,OAAA,IAAW,IAAA;AAAA,IAC5B,MAAA,EAAQ,OAAA,CAAQ,OAAA,KAAY,KAAA,GAAQ,QAAA,GAAW,WAAA;AAAA,IAC/C,OAAA;AAAA,IACA,SAAA,EAAW,GAAA;AAAA,IACX,GAAI,UAAA,KAAe,MAAA,GAAY,EAAC,GAAI,EAAE,WAAW,UAAA,EAAW;AAAA,IAC5D,GAAI,QAAQ,IAAA,KAAS,MAAA,GAAY,EAAE,IAAA,EAAM,OAAA,CAAQ,IAAA,EAAK,GAAI,EAAC;AAAA,IAC3D,GAAI,QAAQ,OAAA,KAAY,MAAA,GAAY,EAAE,OAAA,EAAS,OAAA,CAAQ,OAAA,EAAQ,GAAI,EAAC;AAAA,IACpE,GAAI,QAAQ,KAAA,KAAU,MAAA,GAAY,EAAE,KAAA,EAAO,OAAA,CAAQ,KAAA,EAAM,GAAI,EAAC;AAAA,IAC9D,GAAI,QAAQ,OAAA,KAAY,MAAA,GAAY,EAAE,OAAA,EAAS,OAAA,CAAQ,OAAA,EAAQ,GAAI,EAAC;AAAA,IACpE,GAAI,QAAQ,QAAA,KAAa,MAAA,GAAY,EAAE,QAAA,EAAU,OAAA,CAAQ,QAAA,EAAS,GAAI,EAAC;AAAA,IACvE,GAAI,QAAQ,SAAA,KAAc,MAAA,GAAY,EAAE,SAAA,EAAW,OAAA,CAAQ,SAAA,EAAU,GAAI;AAAC,GAC5E;AACA,EAAA,SAAA,CAAU,GAAG,CAAA;AACb,EAAA,OAAO,GAAA;AACT;AAOA,SAAS,mBAAmB,OAAA,EAAkC;AAC5D,EAAA,MAAM,OAAA,GAAU,CAAC,OAAA,CAAQ,KAAA,EAAO,QAAQ,OAAA,EAAS,OAAA,CAAQ,QAAQ,CAAA,CAAE,MAAA;AAAA,IACjE,CAAC,MAAM,CAAA,KAAM;AAAA,GACf,CAAE,MAAA;AACF,EAAA,IAAI,UAAU,CAAA,EAAG;AACf,IAAA,MAAM,IAAI,kBAAA;AAAA,MACR,qFAAA;AAAA,MACA,EAAE,MAAM,uBAAA;AAAwB,KAClC;AAAA,EACF;AACA,EAAA,IAAI,YAAY,CAAA,EAAG;AACjB,IAAA,MAAM,IAAI,kBAAA;AAAA,MACR,oEAAA;AAAA,MACA,EAAE,MAAM,gBAAA;AAAiB,KAC3B;AAAA,EACF;AACA,EAAA,IAAI,OAAA,CAAQ,QAAA,KAAa,MAAA,IAAa,OAAA,CAAQ,YAAY,MAAA,EAAW;AACnE,IAAA,MAAM,IAAI,kBAAA;AAAA,MACR,gFAAA;AAAA,MACA,EAAE,MAAM,uBAAA;AAAwB,KAClC;AAAA,EACF;AACA,EAAA,IAAI,OAAA,CAAQ,QAAA,KAAa,MAAA,IAAa,OAAA,CAAQ,YAAY,MAAA,EAAW;AACnE,IAAA,MAAM,IAAI,mBAAmB,0CAAA,EAA4C;AAAA,MACvE,IAAA,EAAM;AAAA,KACP,CAAA;AAAA,EACH;AACF;AAEA,SAAS,cAAc,OAAA,EAAyC;AAI9D,EAAA,IAAI,OAAA,CAAQ,QAAA,KAAa,MAAA,EAAW,OAAO,OAAA;AAC3C,EAAA,IAAI,OAAA,CAAQ,YAAY,MAAA,EAAW;AACjC,IAAA,OAAO,OAAA,CAAQ,OAAA,CAAQ,UAAA,CAAW,KAAK,IAAI,OAAA,GAAU,OAAA;AAAA,EACvD;AACA,EAAA,MAAM,QAAQ,OAAA,CAAQ,KAAA;AACtB,EAAA,IAAI,KAAA,EAAO,KAAA,KAAU,MAAA,EAAW,OAAO,OAAA;AACvC,EAAA,OAAO,OAAA;AACT;AAEA,eAAe,eAAA,CAAgB,OAAe,OAAA,EAAoC;AAChF,EAAA,MAAM,QAAA,GAAW,OAAO,KAAK,CAAA;AAC7B,EAAA,IAAI,aAAa,MAAA,EAAW;AAC1B,IAAA,MAAM,IAAI,kBAAkB,CAAA,SAAA,EAAY,KAAK,cAAc,EAAE,IAAA,EAAM,oBAAoB,CAAA;AAAA,EACzF;AACA,EAAA,MAAM,OAAA,GAAmB;AAAA,IACvB,GAAG,QAAA;AAAA,IACH,OAAA;AAAA,IACA,MAAA,EAAQ,UAAU,WAAA,GAAc;AAAA,GAClC;AACA,EAAA,SAAA,CAAU,OAAO,CAAA;AACjB,EAAA,IAAI,OAAA,CAAQ,YAAY,OAAA,EAAS;AAC/B,IAAA,IAAI,OAAA,EAAS;AACX,MAAA,WAAA,CAAY,OAAO,CAAA;AAAA,IACrB,CAAA,MAAO;AACL,MAAA,aAAA,CAAc,QAAQ,EAAE,CAAA;AAAA,IAC1B;AAAA,EACF;AACA,EAAA,OAAO,OAAA;AACT","file":"chunk-WHTMFN4Q.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":";;;;;;;;AAoBA,eAAsB,WAAW,GAAA,EAA0C;AAIzE,EAAA,IAAI,GAAA,CAAI,aAAa,MAAA,EAAW,OAAO,IAAI,QAAA,CAAS,GAAA,CAAI,IAAI,SAAS,CAAA;AACrE,EAAA,IAAI,GAAA,CAAI,UAAU,MAAA,EAAW,OAAO,sBAAsB,GAAA,CAAI,KAAA,EAAO,cAAA,CAAe,GAAG,CAAC,CAAA;AACxF,EAAA,IAAI,GAAA,CAAI,YAAY,MAAA,EAAW,OAAO,qBAAqB,GAAA,CAAI,OAAA,EAAS,cAAA,CAAe,GAAG,CAAC,CAAA;AAC3F,EAAA,MAAM,IAAI,kBAAA;AAAA,IACR,CAAA,SAAA,EAAY,IAAI,EAAE,CAAA,+DAAA,CAAA;AAAA,IAClB,EAAE,MAAM,gBAAA;AAAiB,GAC3B;AACF;AAOO,SAAS,WAAW,OAAA,EAA4C;AACrE,EAAA,OAAO,OAAQ,QAAgB,IAAA,KAAS,UAAA;AAC1C;AAGA,SAAS,eAAe,GAAA,EAAuC;AAC7D,EAAA,IAAI,GAAA,CAAI,YAAY,MAAA,EAAW;AAC7B,IAAA,MAAM,IAAI,kBAAA,CAAmB,CAAA,SAAA,EAAY,GAAA,CAAI,EAAE,CAAA,uCAAA,CAAA,EAA2C;AAAA,MACxF,IAAA,EAAM;AAAA,KACP,CAAA;AAAA,EACH;AACA,EAAA,OAAO,GAAA,CAAI,OAAA;AACb;AAEA,eAAe,oBAAA,CACb,SACA,OAAA,EACc;AACd,EAAA,MAAM,IAAA,GAAO,MAAM,cAAA,EAAe,CAC/B,IAAI,OAAO,CAAA,CACX,KAAA,CAAM,MAAM,MAAS,CAAA;AACxB,EAAA,IAAI,SAAS,MAAA,EAAW;AACtB,IAAA,MAAM,IAAI,iBAAA;AAAA,MACR,gCAAgC,OAAO,CAAA,mIAAA,CAAA;AAAA,MACvC,EAAE,MAAM,sBAAA;AAAuB,KACjC;AAAA,EACF;AACA,EAAA,MAAM,KAAA,GAAQ,MAAM,cAAA,EAAe,CAAE,OAAO,OAAO,CAAA;AACnD,EAAA,OAAO,KAAA,CAAM,KAAK,OAAO,CAAA;AAC3B;AAEA,eAAe,qBAAA,CACb,aACA,OAAA,EACc;AACd,EAAA,MAAM,KAAA,GAAQ,MAAM,cAAA,EAAe,CAAE,OAAO,WAAW,CAAA;AACvD,EAAA,OAAO,KAAA,CAAM,KAAK,OAAO,CAAA;AAC3B;;;AC3DA,eAAsB,kBAAkB,GAAA,EAA6B;AAEnE,EAAA,MAAM,MAAA,GAAS,KAAK,GAAA,EAAI;AACxB,EAAA,MAAM,MAAA,GAAS,CAAA,KAAA,EAAQ,GAAA,CAAI,EAAE,IAAI,MAAM,CAAA,CAAA;AACvC,EAAA,IAAI;AACF,IAAA,MAAM,MAAA,CAAmB;AAAA,MACvB,IAAA,EAAM,MAAA;AAAA,MACN,EAAA,EAAI,MAAA;AAAA,MACJ,mBAAA,EAAqB,IAAA;AAAA,MACrB,IAAA,EAAM,EAAE,KAAA,EAAO,GAAA,CAAI,EAAA,EAAI,OAAA,EAAS,GAAA,CAAI,IAAA,EAAM,QAAA,EAAU,GAAA,CAAI,IAAA,EAAM,OAAA,EAAS,MAAA,EAAO;AAAA,MAC9E,IAAA,EAAM,OAAO,GAAA,KAAQ;AACnB,QAAA,MAAM,OAAA,GAAU,MAAM,UAAA,CAAW,GAAG,CAAA;AACpC,QAAA,IAAI,UAAA,CAAW,OAAO,CAAA,EAAG;AAEvB,UAAA,GAAA,CAAI,MAAA,CAAO,iBAAiB,OAAA,EAAS,MAAM,KAAK,OAAA,CAAQ,MAAA,EAAO,CAAE,KAAA,CAAM,MAAM;AAAA,UAAC,CAAC,CAAA,EAAG;AAAA,YAChF,IAAA,EAAM;AAAA,WACP,CAAA;AACD,UAAA,MAAM,MAAA,GAAS,MAAM,OAAA,CAAQ,IAAA,EAAK;AAClC,UAAA,GAAA,CAAI,IAAA,CAAK,EAAE,MAAA,EAAQ,MAAA,CAAO,QAAQ,KAAA,EAAO,OAAA,CAAQ,IAAI,CAAA;AACrD,UAAA,OAAO,EAAE,MAAA,EAAQ,MAAA,CAAO,MAAA,EAAQ,KAAA,EAAO,QAAQ,EAAA,EAAG;AAAA,QACpD;AAEA,QAAA,GAAA,CAAI,IAAA,CAAK,EAAE,MAAA,EAAQ,OAAA,CAAQ,QAAQ,KAAA,EAAO,OAAA,CAAQ,IAAI,CAAA;AACtD,QAAA,OAAO,EAAE,MAAA,EAAQ,OAAA,CAAQ,MAAA,EAAQ,KAAA,EAAO,QAAQ,EAAA,EAAG;AAAA,MACrD;AAAA,KACD,CAAA;AAAA,EACH,CAAA,CAAA,MAAQ;AAMN,IAAA,MAAM,OAAA,GAAU,MAAM,UAAA,CAAW,GAAG,CAAA;AACpC,IAAA,IAAI,UAAA,CAAW,OAAO,CAAA,EAAG,MAAM,QAAQ,IAAA,EAAK;AAAA,EAC9C;AACF;;;AC1CA,IAAM,IAAA,uBAAW,GAAA,EAAqB;AAG/B,SAAS,QAAA,GAAsB;AACpC,EAAA,OAAO,KAAA,CAAM,IAAA,CAAK,IAAA,CAAK,MAAA,EAAQ,CAAA;AACjC;AAGO,SAAS,QAAA,GAAmB;AACjC,EAAA,OAAO,IAAA,CAAK,IAAA;AACd;AAGO,SAAS,OAAO,KAAA,EAAoC;AACzD,EAAA,OAAO,IAAA,CAAK,IAAI,KAAK,CAAA;AACvB;AAGO,SAAS,UAAU,GAAA,EAAoB;AAC5C,EAAA,IAAA,CAAK,GAAA,CAAI,GAAA,CAAI,EAAA,EAAI,GAAG,CAAA;AACtB;AAGO,SAAS,UAAU,KAAA,EAAwB;AAChD,EAAA,OAAO,IAAA,CAAK,OAAO,KAAK,CAAA;AAC1B;ACxBA,IAAM,UAAA,uBAAiB,GAAA,CAAI,CAAC,WAAW,QAAA,EAAU,SAAA,EAAW,UAAA,EAAY,SAAS,CAAC,CAAA;AAOlF,IAAM,YAAA,GAAsC;AAAA,EAC1C,EAAE,GAAA,EAAK,CAAA,EAAG,GAAA,EAAK,EAAA,EAAG;AAAA;AAAA,EAClB,EAAE,GAAA,EAAK,CAAA,EAAG,GAAA,EAAK,EAAA,EAAG;AAAA;AAAA,EAClB,EAAE,GAAA,EAAK,CAAA,EAAG,GAAA,EAAK,EAAA,EAAG;AAAA;AAAA,EAClB,EAAE,GAAA,EAAK,CAAA,EAAG,GAAA,EAAK,EAAA,EAAG;AAAA;AAAA,EAClB,EAAE,GAAA,EAAK,CAAA,EAAG,GAAA,EAAK,CAAA;AAAE;AACnB,CAAA;AASO,SAAS,uBAAuB,IAAA,EAAoB;AACzD,EAAA,IAAI,OAAO,IAAA,KAAS,QAAA,IAAY,IAAA,CAAK,WAAW,CAAA,EAAG;AACjD,IAAA,MAAM,IAAI,mBAAmB,gCAAA,EAAkC;AAAA,MAC7D,IAAA,EAAM;AAAA,KACP,CAAA;AAAA,EACH;AACA,EAAA,IAAI,IAAA,CAAK,UAAA,CAAW,GAAG,CAAA,EAAG;AACxB,IAAA,IAAI,CAAC,UAAA,CAAW,GAAA,CAAI,IAAI,CAAA,EAAG;AACzB,MAAA,MAAM,IAAI,kBAAA,CAAmB,CAAA,2CAAA,EAA8C,IAAI,CAAA,CAAA,EAAI;AAAA,QACjF,IAAA,EAAM;AAAA,OACP,CAAA;AAAA,IACH;AACA,IAAA;AAAA,EACF;AAEA,EAAA,MAAM,MAAA,GAAS,IAAA,CAAK,IAAA,EAAK,CAAE,MAAM,KAAK,CAAA;AACtC,EAAA,IAAI,MAAA,CAAO,MAAA,KAAW,YAAA,CAAa,MAAA,EAAQ;AACzC,IAAA,MAAM,IAAI,kBAAA;AAAA,MACR,4BAA4B,IAAI,CAAA,WAAA,EAAc,aAAa,MAAM,CAAA,aAAA,EAAgB,OAAO,MAAM,CAAA,CAAA,CAAA;AAAA,MAC9F,EAAE,MAAM,cAAA;AAAe,KACzB;AAAA,EACF;AACA,EAAA,KAAA,MAAW,CAAC,KAAA,EAAO,KAAK,CAAA,IAAK,YAAA,CAAa,SAAQ,EAAG;AAKnD,IAAA,MAAM,KAAA,GAAQ,OAAO,KAAK,CAAA;AAC1B,IAAA,IAAI,CAAC,gBAAA,CAAiB,KAAA,EAAO,KAAK,CAAA,EAAG;AACnC,MAAA,MAAM,IAAI,kBAAA,CAAmB,CAAA,yBAAA,EAA4B,IAAI,CAAA,QAAA,EAAW,KAAA,GAAQ,CAAC,CAAA,CAAA,CAAA,EAAK;AAAA,QACpF,IAAA,EAAM;AAAA,OACP,CAAA;AAAA,IACH;AAAA,EACF;AACF;AAEA,SAAS,gBAAA,CAAiB,OAAe,KAAA,EAA4B;AACnE,EAAA,IAAI,KAAA,KAAU,KAAK,OAAO,IAAA;AAC1B,EAAA,IAAI,KAAA,CAAM,UAAA,CAAW,IAAI,CAAA,EAAG,OAAO,YAAY,KAAA,CAAM,KAAA,CAAM,CAAC,CAAA,EAAG,KAAK,CAAA;AACpE,EAAA,IAAI,KAAA,CAAM,QAAA,CAAS,GAAG,CAAA,EAAG;AACvB,IAAA,OAAO,KAAA,CAAM,KAAA,CAAM,GAAG,CAAA,CAAE,KAAA,CAAM,CAAC,IAAA,KAAS,gBAAA,CAAiB,IAAA,EAAM,KAAK,CAAC,CAAA;AAAA,EACvE;AACA,EAAA,IAAI,MAAM,QAAA,CAAS,GAAG,GAAG,OAAO,YAAA,CAAa,OAAO,KAAK,CAAA;AACzD,EAAA,OAAO,cAAA,CAAe,OAAO,KAAK,CAAA;AACpC;AAoBA,IAAM,WAAA,GAAc,OAAA;AAEpB,SAAS,iBAAiB,IAAA,EAAkC;AAC1D,EAAA,IAAI,CAAC,WAAA,CAAY,IAAA,CAAK,IAAI,GAAG,OAAO,MAAA;AACpC,EAAA,OAAO,MAAA,CAAO,QAAA,CAAS,IAAA,EAAM,EAAE,CAAA;AACjC;AAEA,SAAS,WAAA,CAAY,SAAiB,KAAA,EAA4B;AAChE,EAAA,MAAM,IAAA,GAAO,iBAAiB,OAAO,CAAA;AACrC,EAAA,OAAO,IAAA,KAAS,MAAA,IAAa,IAAA,GAAO,CAAA,IAAK,QAAQ,KAAA,CAAM,GAAA;AACzD;AAEA,SAAS,YAAA,CAAa,OAAe,KAAA,EAA4B;AAC/D,EAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,KAAA,CAAM,GAAG,CAAA;AAC7B,EAAA,IAAI,KAAA,CAAM,MAAA,KAAW,CAAA,EAAG,OAAO,KAAA;AAC/B,EAAA,MAAM,CAAC,QAAA,EAAU,MAAM,CAAA,GAAI,KAAA;AAC3B,EAAA,IAAI,QAAA,KAAa,MAAA,IAAa,MAAA,KAAW,MAAA,EAAW,OAAO,KAAA;AAC3D,EAAA,MAAM,KAAA,GAAQ,iBAAiB,QAAQ,CAAA;AACvC,EAAA,MAAM,GAAA,GAAM,iBAAiB,MAAM,CAAA;AACnC,EAAA,IAAI,KAAA,KAAU,MAAA,IAAa,GAAA,KAAQ,MAAA,EAAW,OAAO,KAAA;AACrD,EAAA,OAAO,SAAS,KAAA,CAAM,GAAA,IAAO,GAAA,IAAO,KAAA,CAAM,OAAO,KAAA,IAAS,GAAA;AAC5D;AAEA,SAAS,cAAA,CAAe,OAAe,KAAA,EAA4B;AACjE,EAAA,MAAM,CAAA,GAAI,iBAAiB,KAAK,CAAA;AAChC,EAAA,OAAO,MAAM,MAAA,IAAa,CAAA,IAAK,KAAA,CAAM,GAAA,IAAO,KAAK,KAAA,CAAM,GAAA;AACzD;AAQO,SAAS,iBAAiB,QAAA,EAAwB;AACvD,EAAA,IAAI;AACF,IAAA,IAAI,KAAK,cAAA,CAAe,OAAA,EAAS,EAAE,QAAA,EAAU,UAAU,CAAA;AAAA,EACzD,CAAA,CAAA,MAAQ;AACN,IAAA,MAAM,IAAI,kBAAA,CAAmB,CAAA,uBAAA,EAA0B,QAAQ,CAAA,CAAA,EAAI;AAAA,MACjE,IAAA,EAAM;AAAA,KACP,CAAA;AAAA,EACH;AACF;AAWO,SAAS,oBAAoB,IAAA,EAAsB;AACxD,EAAA,QAAQ,IAAA;AAAM,IACZ,KAAK,SAAA;AACH,MAAA,OAAO,WAAA;AAAA,IACT,KAAK,QAAA;AACH,MAAA,OAAO,WAAA;AAAA,IACT,KAAK,SAAA;AACH,MAAA,OAAO,WAAA;AAAA,IACT,KAAK,UAAA;AACH,MAAA,OAAO,WAAA;AAAA,IACT,KAAK,SAAA;AACH,MAAA,OAAO,WAAA;AAAA,IACT;AACE,MAAA,OAAO,IAAA;AAAA;AAEb;AAmBO,SAAS,SAAA,CAAU,MAAc,QAAA,EAAsC;AAC5E,EAAA,OAAO,IAAI,IAAA,CAAK,mBAAA,CAAoB,IAAI,CAAA,EAAG,EAAE,QAAA,EAAU,CAAA,CAAE,OAAA,EAAQ,EAAG,OAAA,EAAQ;AAC9E;;;AClKA,IAAM,QAAwB,EAAE,OAAA,EAAS,OAAO,MAAA,kBAAQ,IAAI,KAAI,EAAE;AAS3D,SAAS,mBAAmB,OAAA,EAA4C;AAC7E,EAAA,KAAA,CAAM,WAAA,GAAc,OAAA;AACtB;AAGO,SAAS,eAAe,GAAA,EAAoB;AACjD,EAAA,KAAA,CAAM,OAAA,GAAU,IAAA;AAChB,EAAA,IAAI,GAAA,KAAQ,MAAA,EAAW,KAAA,CAAM,GAAA,GAAM,GAAA;AACnC,EAAA,KAAA,MAAW,GAAA,IAAO,UAAS,EAAG;AAC5B,IAAA,IAAI,IAAI,OAAA,KAAY,OAAA,IAAW,IAAI,OAAA,KAAY,KAAA,cAAmB,GAAG,CAAA;AAAA,EACvE;AACF;AAGO,SAAS,aAAA,GAAsB;AACpC,EAAA,KAAA,CAAM,OAAA,GAAU,KAAA;AAChB,EAAA,KAAA,MAAW,SAAS,KAAA,CAAM,MAAA,CAAO,MAAA,EAAO,QAAS,IAAA,EAAK;AACtD,EAAA,KAAA,CAAM,OAAO,KAAA,EAAM;AACrB;AAGO,SAAS,YAAY,GAAA,EAAoB;AAC9C,EAAA,IAAI,CAAC,MAAM,OAAA,EAAS;AACpB,EAAA,aAAA,CAAc,IAAI,EAAE,CAAA;AACpB,EAAA,MAAM,UAAA,GAAa,mBAAA,CAAoB,GAAA,CAAI,IAAI,CAAA;AAC/C,EAAA,MAAM,QAAQ,IAAIA,IAAA;AAAA,IAChB,UAAA;AAAA,IACA,EAAE,UAAU,GAAA,CAAI,QAAA,EAAU,MAAM,GAAA,CAAI,EAAA,EAAI,SAAS,IAAA,EAAK;AAAA,IACtD,MAAM;AACJ,MAAA,KAAK,OAAA,CAAQ,IAAI,EAAE,CAAA;AAAA,IACrB;AAAA,GACF;AACA,EAAA,KAAA,CAAM,MAAA,CAAO,GAAA,CAAI,GAAA,CAAI,EAAA,EAAI,KAAK,CAAA;AAC9B,EAAA,gBAAA,CAAiB,GAAA,CAAI,IAAI,KAAK,CAAA;AAChC;AAGO,SAAS,cAAc,KAAA,EAAwB;AACpD,EAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,MAAA,CAAO,GAAA,CAAI,KAAK,CAAA;AACpC,EAAA,IAAI,KAAA,KAAU,QAAW,OAAO,KAAA;AAChC,EAAA,KAAA,CAAM,IAAA,EAAK;AACX,EAAA,KAAA,CAAM,MAAA,CAAO,OAAO,KAAK,CAAA;AACzB,EAAA,OAAO,IAAA;AACT;AAGO,SAAS,iBAAA,GAAwD;AACtE,EAAA,MAAM,MAAA,GAA6C,EAAE,OAAA,EAAS,KAAA,CAAM,OAAA,EAAQ;AAC5E,EAAA,IAAI,KAAA,CAAM,GAAA,KAAQ,MAAA,EAAW,MAAA,CAAO,MAAM,KAAA,CAAM,GAAA;AAChD,EAAA,OAAO,MAAA;AACT;AAEA,eAAe,QAAQ,KAAA,EAA8B;AACnD,EAAA,MAAM,KAAA,GAAQ,UAAS,CAAE,IAAA,CAAK,CAAC,KAAA,KAAU,KAAA,CAAM,OAAO,KAAK,CAAA;AAC3D,EAAA,IAAI,KAAA,KAAU,MAAA,IAAa,KAAA,CAAM,OAAA,KAAY,KAAA,EAAO;AACpD,EAAA,MAAM,UAAU,KAAA,CAAM,WAAA;AACtB,EAAA,SAAA,CAAU,EAAE,GAAG,KAAA,EAAO,WAAW,IAAA,CAAK,GAAA,IAAO,CAAA;AAC7C,EAAA,IAAI,YAAY,MAAA,EAAW;AAC3B,EAAA,IAAI;AACF,IAAA,MAAM,QAAQ,KAAK,CAAA;AAAA,EACrB,CAAA,CAAA,MAAQ;AAAA,EAGR;AACF;AAEA,SAAS,gBAAA,CAAiB,OAAe,KAAA,EAAqB;AAC5D,EAAA,MAAM,IAAA,GAAO,MAAM,OAAA,EAAQ;AAC3B,EAAA,IAAI,SAAS,IAAA,EAAM;AACnB,EAAA,MAAM,QAAA,GAAW,UAAS,CAAE,IAAA,CAAK,CAAC,KAAA,KAAU,KAAA,CAAM,OAAO,KAAK,CAAA;AAC9D,EAAA,IAAI,aAAa,MAAA,EAAW;AAC5B,EAAA,SAAA,CAAU,EAAE,GAAG,QAAA,EAAU,WAAW,IAAA,CAAK,OAAA,IAAW,CAAA;AACtD;;;AC/DO,IAAMC,QAAN,MAAW;AAAA,EACR,WAAA,GAAc;AAAA,EAEtB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,aAAa,OAAO,OAAA,EAA8C;AAChE,IAAA,MAAM,GAAA,GAAM,MAAM,aAAA,CAAc,OAAO,CAAA;AACvC,IAAA,IAAI,IAAI,OAAA,KAAY,OAAA,IAAW,IAAI,OAAA,KAAY,KAAA,cAAmB,GAAG,CAAA;AACrE,IAAA,OAAO,GAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAAO,IAAA,CAAK,OAAA,GAA2B,EAAC,EAAiC;AACvE,IAAA,MAAM,gBAAgB,OAAA,CAAQ,OAAA;AAC9B,IAAA,MAAM,KAAA,GAAQ,UAAS,CAAE,MAAA;AAAA,MAAO,CAAC,GAAA,KAC/B,aAAA,KAAkB,MAAA,GAAY,IAAA,GAAO,IAAI,OAAA,KAAY;AAAA,KACvD;AACA,IAAA,OAAO,OAAA,CAAQ,OAAA,CAAQ,EAAE,KAAA,EAAO,CAAA;AAAA,EAClC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAAO,GAAA,CAAI,KAAA,EAAe,QAAA,GAA2B,EAAC,EAAqB;AACzE,IAAA,MAAM,GAAA,GAAM,OAAO,KAAK,CAAA;AACxB,IAAA,IAAI,QAAQ,MAAA,EAAW;AACrB,MAAA,OAAO,OAAA,CAAQ,MAAA;AAAA,QACb,IAAI,kBAAkB,CAAA,SAAA,EAAY,KAAK,cAAc,EAAE,IAAA,EAAM,oBAAoB;AAAA,OACnF;AAAA,IACF;AACA,IAAA,OAAO,OAAA,CAAQ,QAAQ,GAAG,CAAA;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAAO,MAAA,CAAO,KAAA,EAAe,QAAA,GAAiC,EAAC,EAAkB;AAC/E,IAAA,aAAA,CAAc,KAAK,CAAA;AACnB,IAAA,SAAA,CAAU,KAAK,CAAA;AACf,IAAA,OAAO,QAAQ,OAAA,EAAQ;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,aAAa,MAAA,CAAO,KAAA,EAAe,QAAA,GAAiC,EAAC,EAAqB;AACxF,IAAA,OAAO,eAAA,CAAgB,OAAO,IAAI,CAAA;AAAA,EACpC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,aAAa,OAAA,CAAQ,KAAA,EAAe,QAAA,GAAiC,EAAC,EAAqB;AACzF,IAAA,OAAO,eAAA,CAAgB,OAAO,KAAK,CAAA;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,aAAa,GAAA,CACX,KAAA,EACA,QAAA,GAA2B,EAAC,EAC8B;AAC1D,IAAA,MAAM,GAAA,GAAM,OAAO,KAAK,CAAA;AACxB,IAAA,IAAI,QAAQ,MAAA,EAAW;AACrB,MAAA,MAAM,IAAI,kBAAkB,CAAA,SAAA,EAAY,KAAK,cAAc,EAAE,IAAA,EAAM,oBAAoB,CAAA;AAAA,IACzF;AACA,IAAA,OAAO,WAAW,GAAG,CAAA;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAAO,KAAA,CAAM,OAAA,GAA4B,EAAC,EAAkB;AAK1D,IAAA,kBAAA,CAAmB,iBAAiB,CAAA;AACpC,IAAA,cAAA,CAAe,QAAQ,GAAG,CAAA;AAC1B,IAAA,OAAO,QAAQ,OAAA,EAAQ;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAAO,IAAA,GAAsB;AAC3B,IAAA,aAAA,EAAc;AACd,IAAA,OAAO,QAAQ,OAAA,EAAQ;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAAO,MAAA,CAAO,QAAA,GAA6B,EAAC,EAAiC;AAC3E,IAAA,MAAM,YAAY,iBAAA,EAAkB;AACpC,IAAA,OAAO,OAAA,CAAQ,QAAQ,EAAE,OAAA,EAAS,UAAU,OAAA,EAAS,QAAA,EAAU,QAAA,EAAS,EAAG,CAAA;AAAA,EAC7E;AACF;AAEA,eAAe,cAAc,OAAA,EAA8C;AACzE,EAAA,kBAAA,CAAmB,OAAO,CAAA;AAE1B,EAAA,sBAAA,CAAuB,QAAQ,IAAI,CAAA;AACnC,EAAA,MAAM,QAAA,GAAW,QAAQ,QAAA,IAAY,KAAA;AACrC,EAAA,gBAAA,CAAiB,QAAQ,CAAA;AAGzB,EAAA,aAAA,CAAc,QAAQ,MAAM,CAAA;AAE5B,EAAA,MAAM,OAAA,GAAU,cAAc,OAAO,CAAA;AACrC,EAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AAKrB,EAAA,MAAM,UAAA,GAAa,SAAA,CAAU,OAAA,CAAQ,IAAA,EAAM,QAAQ,CAAA;AACnD,EAAA,MAAM,GAAA,GAAe;AAAA,IACnB,IAAI,cAAA,EAAe;AAAA,IACnB,MAAM,OAAA,CAAQ,IAAA;AAAA,IACd,QAAA;AAAA,IACA,OAAA,EAAS,QAAQ,OAAA,IAAW,IAAA;AAAA,IAC5B,MAAA,EAAQ,OAAA,CAAQ,OAAA,KAAY,KAAA,GAAQ,QAAA,GAAW,WAAA;AAAA,IAC/C,OAAA;AAAA,IACA,SAAA,EAAW,GAAA;AAAA,IACX,GAAI,UAAA,KAAe,MAAA,GAAY,EAAC,GAAI,EAAE,WAAW,UAAA,EAAW;AAAA,IAC5D,GAAI,QAAQ,IAAA,KAAS,MAAA,GAAY,EAAE,IAAA,EAAM,OAAA,CAAQ,IAAA,EAAK,GAAI,EAAC;AAAA,IAC3D,GAAI,QAAQ,OAAA,KAAY,MAAA,GAAY,EAAE,OAAA,EAAS,OAAA,CAAQ,OAAA,EAAQ,GAAI,EAAC;AAAA,IACpE,GAAI,QAAQ,KAAA,KAAU,MAAA,GAAY,EAAE,KAAA,EAAO,OAAA,CAAQ,KAAA,EAAM,GAAI,EAAC;AAAA,IAC9D,GAAI,QAAQ,OAAA,KAAY,MAAA,GAAY,EAAE,OAAA,EAAS,OAAA,CAAQ,OAAA,EAAQ,GAAI,EAAC;AAAA,IACpE,GAAI,QAAQ,QAAA,KAAa,MAAA,GAAY,EAAE,QAAA,EAAU,OAAA,CAAQ,QAAA,EAAS,GAAI,EAAC;AAAA,IACvE,GAAI,QAAQ,SAAA,KAAc,MAAA,GAAY,EAAE,SAAA,EAAW,OAAA,CAAQ,SAAA,EAAU,GAAI;AAAC,GAC5E;AACA,EAAA,SAAA,CAAU,GAAG,CAAA;AACb,EAAA,OAAO,GAAA;AACT;AAOA,SAAS,mBAAmB,OAAA,EAAkC;AAC5D,EAAA,MAAM,OAAA,GAAU,CAAC,OAAA,CAAQ,KAAA,EAAO,QAAQ,OAAA,EAAS,OAAA,CAAQ,QAAQ,CAAA,CAAE,MAAA;AAAA,IACjE,CAAC,MAAM,CAAA,KAAM;AAAA,GACf,CAAE,MAAA;AACF,EAAA,IAAI,UAAU,CAAA,EAAG;AACf,IAAA,MAAM,IAAI,kBAAA;AAAA,MACR,qFAAA;AAAA,MACA,EAAE,MAAM,uBAAA;AAAwB,KAClC;AAAA,EACF;AACA,EAAA,IAAI,YAAY,CAAA,EAAG;AACjB,IAAA,MAAM,IAAI,kBAAA;AAAA,MACR,oEAAA;AAAA,MACA,EAAE,MAAM,gBAAA;AAAiB,KAC3B;AAAA,EACF;AACA,EAAA,IAAI,OAAA,CAAQ,QAAA,KAAa,MAAA,IAAa,OAAA,CAAQ,YAAY,MAAA,EAAW;AACnE,IAAA,MAAM,IAAI,kBAAA;AAAA,MACR,gFAAA;AAAA,MACA,EAAE,MAAM,uBAAA;AAAwB,KAClC;AAAA,EACF;AACA,EAAA,IAAI,OAAA,CAAQ,QAAA,KAAa,MAAA,IAAa,OAAA,CAAQ,YAAY,MAAA,EAAW;AACnE,IAAA,MAAM,IAAI,mBAAmB,0CAAA,EAA4C;AAAA,MACvE,IAAA,EAAM;AAAA,KACP,CAAA;AAAA,EACH;AACF;AAEA,SAAS,cAAc,OAAA,EAAyC;AAI9D,EAAA,IAAI,OAAA,CAAQ,QAAA,KAAa,MAAA,EAAW,OAAO,OAAA;AAC3C,EAAA,IAAI,OAAA,CAAQ,YAAY,MAAA,EAAW;AACjC,IAAA,OAAO,OAAA,CAAQ,OAAA,CAAQ,UAAA,CAAW,KAAK,IAAI,OAAA,GAAU,OAAA;AAAA,EACvD;AACA,EAAA,MAAM,QAAQ,OAAA,CAAQ,KAAA;AACtB,EAAA,IAAI,KAAA,EAAO,KAAA,KAAU,MAAA,EAAW,OAAO,OAAA;AACvC,EAAA,OAAO,OAAA;AACT;AAEA,eAAe,eAAA,CAAgB,OAAe,OAAA,EAAoC;AAChF,EAAA,MAAM,QAAA,GAAW,OAAO,KAAK,CAAA;AAC7B,EAAA,IAAI,aAAa,MAAA,EAAW;AAC1B,IAAA,MAAM,IAAI,kBAAkB,CAAA,SAAA,EAAY,KAAK,cAAc,EAAE,IAAA,EAAM,oBAAoB,CAAA;AAAA,EACzF;AACA,EAAA,MAAM,OAAA,GAAmB;AAAA,IACvB,GAAG,QAAA;AAAA,IACH,OAAA;AAAA,IACA,MAAA,EAAQ,UAAU,WAAA,GAAc;AAAA,GAClC;AACA,EAAA,SAAA,CAAU,OAAO,CAAA;AACjB,EAAA,IAAI,OAAA,CAAQ,YAAY,OAAA,EAAS;AAC/B,IAAA,IAAI,OAAA,EAAS;AACX,MAAA,WAAA,CAAY,OAAO,CAAA;AAAA,IACrB,CAAA,MAAO;AACL,MAAA,aAAA,CAAc,QAAQ,EAAE,CAAA;AAAA,IAC1B;AAAA,EACF;AACA,EAAA,OAAO,OAAA;AACT","file":"chunk-ZU3HQCKR.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"]}
package/dist/cron.cjs CHANGED
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
- var chunkPEAOQMWE_cjs = require('./chunk-PEAOQMWE.cjs');
4
- require('./chunk-DEJCKB65.cjs');
3
+ var chunkOZT6T2RI_cjs = require('./chunk-OZT6T2RI.cjs');
4
+ require('./chunk-5XNRWMMD.cjs');
5
5
  require('./chunk-KVSAY6NZ.cjs');
6
6
  require('./chunk-Y2KYR2ED.cjs');
7
7
  require('./chunk-BUUUWQMB.cjs');
@@ -62,7 +62,7 @@ require('./chunk-6LHQPOMI.cjs');
62
62
 
63
63
  Object.defineProperty(exports, "Cron", {
64
64
  enumerable: true,
65
- get: function () { return chunkPEAOQMWE_cjs.Cron; }
65
+ get: function () { return chunkOZT6T2RI_cjs.Cron; }
66
66
  });
67
67
  //# sourceMappingURL=cron.cjs.map
68
68
  //# sourceMappingURL=cron.cjs.map
package/dist/cron.js CHANGED
@@ -1,5 +1,5 @@
1
- export { Cron } from './chunk-WHTMFN4Q.js';
2
- import './chunk-43H4EBS2.js';
1
+ export { Cron } from './chunk-ZU3HQCKR.js';
2
+ import './chunk-ZFEOAC52.js';
3
3
  import './chunk-K2VMFZQ5.js';
4
4
  import './chunk-AWINL3ZC.js';
5
5
  import './chunk-K2BQQ445.js';
package/dist/eval.cjs CHANGED
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var chunkUADQJBHR_cjs = require('./chunk-UADQJBHR.cjs');
4
- var chunkDEJCKB65_cjs = require('./chunk-DEJCKB65.cjs');
4
+ var chunk5XNRWMMD_cjs = require('./chunk-5XNRWMMD.cjs');
5
5
  require('./chunk-KVSAY6NZ.cjs');
6
6
  require('./chunk-Y2KYR2ED.cjs');
7
7
  var chunkBUUUWQMB_cjs = require('./chunk-BUUUWQMB.cjs');
@@ -795,7 +795,7 @@ function makeDefaultEmbedder(opts) {
795
795
  let runtime;
796
796
  return (texts) => {
797
797
  if (runtime === void 0) {
798
- runtime = chunkDEJCKB65_cjs.openRouterMemoryEmbeddingProviderAdapter.create(embedderCreateOptions(opts));
798
+ runtime = chunk5XNRWMMD_cjs.openRouterMemoryEmbeddingProviderAdapter.create(embedderCreateOptions(opts));
799
799
  }
800
800
  return runtime.then((rt) => rt.embed(texts));
801
801
  };
package/dist/eval.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { shellEscapePosix, LocalSandbox } from './chunk-O6USDERH.js';
2
- import { openRouterMemoryEmbeddingProviderAdapter } from './chunk-43H4EBS2.js';
2
+ import { openRouterMemoryEmbeddingProviderAdapter } from './chunk-ZFEOAC52.js';
3
3
  import './chunk-K2VMFZQ5.js';
4
4
  import './chunk-AWINL3ZC.js';
5
5
  import { getTracer } from './chunk-K2BQQ445.js';
package/dist/index.cjs CHANGED
@@ -9,8 +9,8 @@ require('./chunk-7JJ3A6AT.cjs');
9
9
  var chunk4HS6FFGL_cjs = require('./chunk-4HS6FFGL.cjs');
10
10
  require('./chunk-4A3SKJ53.cjs');
11
11
  require('./chunk-VTYY7XL5.cjs');
12
- var chunkPEAOQMWE_cjs = require('./chunk-PEAOQMWE.cjs');
13
- var chunkDEJCKB65_cjs = require('./chunk-DEJCKB65.cjs');
12
+ var chunkOZT6T2RI_cjs = require('./chunk-OZT6T2RI.cjs');
13
+ var chunk5XNRWMMD_cjs = require('./chunk-5XNRWMMD.cjs');
14
14
  var chunkKVSAY6NZ_cjs = require('./chunk-KVSAY6NZ.cjs');
15
15
  require('./chunk-Y2KYR2ED.cjs');
16
16
  require('./chunk-BUUUWQMB.cjs');
@@ -74,8 +74,8 @@ var path = require('path');
74
74
  // src/agent-factory.ts
75
75
  function createAgentFactory(common) {
76
76
  return {
77
- forSession: (agentId, overrides) => chunkDEJCKB65_cjs.Agent.create(mergeAgentOptions(common, overrides, agentId)),
78
- getOrCreate: (agentId, overrides) => chunkDEJCKB65_cjs.Agent.getOrCreate(agentId, mergeAgentOptions(common, overrides, agentId))
77
+ forSession: (agentId, overrides) => chunk5XNRWMMD_cjs.Agent.create(mergeAgentOptions(common, overrides, agentId)),
78
+ getOrCreate: (agentId, overrides) => chunk5XNRWMMD_cjs.Agent.getOrCreate(agentId, mergeAgentOptions(common, overrides, agentId))
79
79
  };
80
80
  }
81
81
  function mergeAgentOptions(common, overrides, agentId) {
@@ -1335,7 +1335,7 @@ var Memory = {
1335
1335
  return await peer.IndexManager.open(openArgs);
1336
1336
  }
1337
1337
  const { IndexManager } = await import('./index-manager-3UNPYH34.cjs');
1338
- openArgs.embedding = await resolveEmbedding(opts.embedding, chunkDEJCKB65_cjs.MEMORY_EMBEDDING_ADAPTERS);
1338
+ openArgs.embedding = await resolveEmbedding(opts.embedding, chunk5XNRWMMD_cjs.MEMORY_EMBEDDING_ADAPTERS);
1339
1339
  return await IndexManager.open(openArgs);
1340
1340
  },
1341
1341
  /**
@@ -1346,7 +1346,7 @@ var Memory = {
1346
1346
  */
1347
1347
  async runDreamingSweep(opts) {
1348
1348
  const peer = await tryLoadSdkMemoryPeer();
1349
- const catalog = peer !== null ? peer.MEMORY_EMBEDDING_ADAPTERS : chunkDEJCKB65_cjs.MEMORY_EMBEDDING_ADAPTERS;
1349
+ const catalog = peer !== null ? peer.MEMORY_EMBEDDING_ADAPTERS : chunk5XNRWMMD_cjs.MEMORY_EMBEDDING_ADAPTERS;
1350
1350
  const sweepArgs = await buildDreamingSweepArgs(opts, catalog);
1351
1351
  const result = peer !== null ? (
1352
1352
  // biome-ignore lint/suspicious/noExplicitAny: peer is dynamically loaded — structural compat ensured by sdk-memory
@@ -1770,7 +1770,7 @@ function guardSessionDestruction(sessionId, live) {
1770
1770
  // src/session-messages.ts
1771
1771
  async function readSessionMessages2(options) {
1772
1772
  const cwd = options.cwd ?? process.cwd();
1773
- const baseDir = chunkDEJCKB65_cjs.resolveSessionDir({ sessionDir: options.sessionDir });
1773
+ const baseDir = chunk5XNRWMMD_cjs.resolveSessionDir({ sessionDir: options.sessionDir });
1774
1774
  return chunkYIFFF23U_cjs.readSessionMessages(new chunk7FDKWDA2_cjs.FsSessionStore({ baseDir, cwd }), options.sessionId);
1775
1775
  }
1776
1776
 
@@ -1787,7 +1787,7 @@ function isBuiltAgent(m) {
1787
1787
  return typeof m.send === "function";
1788
1788
  }
1789
1789
  async function materialize(def, index) {
1790
- const { Agent: Agent2 } = await import('./agent-GACKKINM.cjs');
1790
+ const { Agent: Agent2 } = await import('./agent-UXU5AIOJ.cjs');
1791
1791
  return Agent2.create({
1792
1792
  // `AgentDefinition.model` admits the sentinel `'inherit'`, which is not a model id. Inheriting
1793
1793
  // here means "declare nothing and let the default apply" — forwarding the literal would create
@@ -1929,7 +1929,7 @@ var FIXTURE_USER = {
1929
1929
  };
1930
1930
  var FIXTURE_MODELS = [
1931
1931
  {
1932
- id: chunkDEJCKB65_cjs.DEFAULT_AGENTIC_MODEL_ID,
1932
+ id: chunk5XNRWMMD_cjs.DEFAULT_AGENTIC_MODEL_ID,
1933
1933
  name: "Gemini 2.0 Flash",
1934
1934
  displayName: "Gemini 2.0 Flash",
1935
1935
  parameters: [
@@ -2132,7 +2132,7 @@ var Theokit = class {
2132
2132
  envVars: p.envVars
2133
2133
  }));
2134
2134
  },
2135
- embeddingAdapters: () => Object.entries(chunkDEJCKB65_cjs.MEMORY_EMBEDDING_ADAPTERS).map(([id, adapter]) => ({
2135
+ embeddingAdapters: () => Object.entries(chunk5XNRWMMD_cjs.MEMORY_EMBEDDING_ADAPTERS).map(([id, adapter]) => ({
2136
2136
  id,
2137
2137
  transport: adapter.transport,
2138
2138
  defaultModel: adapter.defaultModel
@@ -2351,35 +2351,35 @@ Object.defineProperty(exports, "fn", {
2351
2351
  });
2352
2352
  Object.defineProperty(exports, "Cron", {
2353
2353
  enumerable: true,
2354
- get: function () { return chunkPEAOQMWE_cjs.Cron; }
2354
+ get: function () { return chunkOZT6T2RI_cjs.Cron; }
2355
2355
  });
2356
2356
  Object.defineProperty(exports, "Agent", {
2357
2357
  enumerable: true,
2358
- get: function () { return chunkDEJCKB65_cjs.Agent; }
2358
+ get: function () { return chunk5XNRWMMD_cjs.Agent; }
2359
2359
  });
2360
2360
  Object.defineProperty(exports, "AgentBuilder", {
2361
2361
  enumerable: true,
2362
- get: function () { return chunkDEJCKB65_cjs.AgentBuilder; }
2362
+ get: function () { return chunk5XNRWMMD_cjs.AgentBuilder; }
2363
2363
  });
2364
2364
  Object.defineProperty(exports, "Tool", {
2365
2365
  enumerable: true,
2366
- get: function () { return chunkDEJCKB65_cjs.Tool; }
2366
+ get: function () { return chunk5XNRWMMD_cjs.Tool; }
2367
2367
  });
2368
2368
  Object.defineProperty(exports, "ToolError", {
2369
2369
  enumerable: true,
2370
- get: function () { return chunkDEJCKB65_cjs.ToolError; }
2370
+ get: function () { return chunk5XNRWMMD_cjs.ToolError; }
2371
2371
  });
2372
2372
  Object.defineProperty(exports, "UsageAccumulator", {
2373
2373
  enumerable: true,
2374
- get: function () { return chunkDEJCKB65_cjs.UsageAccumulator; }
2374
+ get: function () { return chunk5XNRWMMD_cjs.UsageAccumulator; }
2375
2375
  });
2376
2376
  Object.defineProperty(exports, "computeCost", {
2377
2377
  enumerable: true,
2378
- get: function () { return chunkDEJCKB65_cjs.computeCost; }
2378
+ get: function () { return chunk5XNRWMMD_cjs.computeCost; }
2379
2379
  });
2380
2380
  Object.defineProperty(exports, "getPricingEntry", {
2381
2381
  enumerable: true,
2382
- get: function () { return chunkDEJCKB65_cjs.getPricingEntry; }
2382
+ get: function () { return chunk5XNRWMMD_cjs.getPricingEntry; }
2383
2383
  });
2384
2384
  Object.defineProperty(exports, "emitRunEvent", {
2385
2385
  enumerable: true,
package/dist/index.d.cts CHANGED
@@ -871,11 +871,29 @@ declare class Agent {
871
871
  */
872
872
  static describe(agentId: string): Promise<AgentDescription>;
873
873
  /**
874
- * Permanently delete a cloud agent.
874
+ * Permanently delete a registered agent — local or cloud.
875
+ *
876
+ * #612 — this HYDRATES before removing, and until it did the method was a no-op against the
877
+ * persisted registry whenever the agent was not already in this process's memory. Which is every
878
+ * agent in a freshly started process: `removeRegisteredAgent` only schedules a save when the entry
879
+ * was in the Map, so `agents.delete()` returned `false`, nothing was scheduled, and
880
+ * `flushRegistrySaves()` flushed an empty queue. The entry survived and this returned normally.
881
+ *
882
+ * Every neighbouring mutator already did this — `rename` and `archive` reach
883
+ * `getRegisteredAgentOrThrow`, which hydrates on a miss. `delete` was the only one that did not.
884
+ *
885
+ * `options.cwd` is read rather than defaulted away: it is declared on `AgentOperationOptions`, and
886
+ * hydrating `process.cwd()` unconditionally is the B-115 defect — an option that compiles and does
887
+ * nothing — on the one path that is supposed to remove data.
888
+ *
889
+ * Deleting an unknown id still resolves rather than throwing, deliberately. `rename` throws
890
+ * `UnknownAgentError` and matching it here is defensible, but it is a breaking change for callers
891
+ * that delete idempotently, and an entry and its transcript can legitimately outlive one another
892
+ * in both directions. That decision belongs to its own change, not to a persistence fix.
875
893
  *
876
894
  * @public
877
895
  */
878
- static delete(agentId: string, _options?: AgentOperationOptions): Promise<void>;
896
+ static delete(agentId: string, options?: AgentOperationOptions): Promise<void>;
879
897
  }
880
898
 
881
899
  /**
package/dist/index.d.ts CHANGED
@@ -871,11 +871,29 @@ declare class Agent {
871
871
  */
872
872
  static describe(agentId: string): Promise<AgentDescription>;
873
873
  /**
874
- * Permanently delete a cloud agent.
874
+ * Permanently delete a registered agent — local or cloud.
875
+ *
876
+ * #612 — this HYDRATES before removing, and until it did the method was a no-op against the
877
+ * persisted registry whenever the agent was not already in this process's memory. Which is every
878
+ * agent in a freshly started process: `removeRegisteredAgent` only schedules a save when the entry
879
+ * was in the Map, so `agents.delete()` returned `false`, nothing was scheduled, and
880
+ * `flushRegistrySaves()` flushed an empty queue. The entry survived and this returned normally.
881
+ *
882
+ * Every neighbouring mutator already did this — `rename` and `archive` reach
883
+ * `getRegisteredAgentOrThrow`, which hydrates on a miss. `delete` was the only one that did not.
884
+ *
885
+ * `options.cwd` is read rather than defaulted away: it is declared on `AgentOperationOptions`, and
886
+ * hydrating `process.cwd()` unconditionally is the B-115 defect — an option that compiles and does
887
+ * nothing — on the one path that is supposed to remove data.
888
+ *
889
+ * Deleting an unknown id still resolves rather than throwing, deliberately. `rename` throws
890
+ * `UnknownAgentError` and matching it here is defensible, but it is a breaking change for callers
891
+ * that delete idempotently, and an entry and its transcript can legitimately outlive one another
892
+ * in both directions. That decision belongs to its own change, not to a persistence fix.
875
893
  *
876
894
  * @public
877
895
  */
878
- static delete(agentId: string, _options?: AgentOperationOptions): Promise<void>;
896
+ static delete(agentId: string, options?: AgentOperationOptions): Promise<void>;
879
897
  }
880
898
 
881
899
  /**
package/dist/index.js CHANGED
@@ -8,9 +8,9 @@ import { Workflow, agentStep } from './chunk-HFEJE7AC.js';
8
8
  export { Workflow, agentStep, fn } from './chunk-HFEJE7AC.js';
9
9
  import './chunk-GBCVPKHE.js';
10
10
  import './chunk-HY66GLM6.js';
11
- export { Cron } from './chunk-WHTMFN4Q.js';
12
- import { MEMORY_EMBEDDING_ADAPTERS, resolveSessionDir, DEFAULT_AGENTIC_MODEL_ID, Agent } from './chunk-43H4EBS2.js';
13
- export { Agent, AgentBuilder, Tool, ToolError, UsageAccumulator, computeCost, getPricingEntry } from './chunk-43H4EBS2.js';
11
+ export { Cron } from './chunk-ZU3HQCKR.js';
12
+ import { MEMORY_EMBEDDING_ADAPTERS, resolveSessionDir, DEFAULT_AGENTIC_MODEL_ID, Agent } from './chunk-ZFEOAC52.js';
13
+ export { Agent, AgentBuilder, Tool, ToolError, UsageAccumulator, computeCost, getPricingEntry } from './chunk-ZFEOAC52.js';
14
14
  import { configure, submit, list, get, cancel, subscribe } from './chunk-K2VMFZQ5.js';
15
15
  export { emitRunEvent } from './chunk-K2VMFZQ5.js';
16
16
  import './chunk-AWINL3ZC.js';
@@ -1792,7 +1792,7 @@ function isBuiltAgent(m) {
1792
1792
  return typeof m.send === "function";
1793
1793
  }
1794
1794
  async function materialize(def, index) {
1795
- const { Agent: Agent2 } = await import('./agent-VUNM33WJ.js');
1795
+ const { Agent: Agent2 } = await import('./agent-G4OFQYLE.js');
1796
1796
  return Agent2.create({
1797
1797
  // `AgentDefinition.model` admits the sentinel `'inherit'`, which is not a model id. Inheriting
1798
1798
  // here means "declare nothing and let the default apply" — forwarding the literal would create
@@ -0,0 +1,98 @@
1
+ /**
2
+ * #598 — enumerate the sessions on disk, saying where each id came from.
3
+ *
4
+ * ## Why this exists
5
+ *
6
+ * Every transcript helper this package published mapped FORWARD — `sessionUuidFor`,
7
+ * `transcriptPath`, `legacyTranscriptPath`, `encodeProjectDir`, `transcriptRoot`. **None enumerated.**
8
+ * So a consumer that needed the list rebuilt it, and two independent ones did, in opposite
9
+ * directions, and both got it wrong on the first attempt:
10
+ *
11
+ * | consumer | direction | what broke |
12
+ * |---|---|---|
13
+ * | `@theokit/agents` | file → id | derived the id from the file STEM |
14
+ * | a downstream agent runtime | id → file | compared session ids against filenames |
15
+ *
16
+ * The second measured, against 5.0.1: the protected set never matched, **so neither the registered
17
+ * sessions nor the live one were protected and everything classified as an orphan** — a garbage
18
+ * collector that would delete the session in use.
19
+ *
20
+ * ## Why documentation was not the fix
21
+ *
22
+ * `b85dab4` documented the rename thoroughly. One of those two consumers had READ it and broke
23
+ * anyway; the other had not and broke identically. Two samples, one informed and one not, same
24
+ * defect. If reading were sufficient the informed sample would have survived — so the cause is the
25
+ * shape of the surface, not the reader.
26
+ *
27
+ * And it cannot be closed by publishing an inverse: the filename is a UUIDv8 over SHA-256, which has
28
+ * none. Whoever holds the file must read the id from INSIDE it, and that the id lives in the first
29
+ * record is this package's knowledge. Both consumers had to discover it by reading bytes.
30
+ *
31
+ * ## Why the id is not just a string
32
+ *
33
+ * An `id: string` that is sometimes read from the transcript and sometimes inferred from the
34
+ * filename is the same defect one layer up: a value that reads as authoritative and occasionally is
35
+ * not. That is precisely what produced the garbage-collector failure above.
36
+ *
37
+ * So every entry carries {@link SessionListing.idSource}, and an entry whose id could not be
38
+ * determined is `undefined` rather than guessed. A caller deciding what to DELETE needs to tell
39
+ * "this session is not registered" from "I could not read this file" — those look identical in a
40
+ * plain list and mean opposite things.
41
+ *
42
+ * @public
43
+ */
44
+ /** How the `id` on a {@link SessionListing} was obtained. */
45
+ export type SessionIdSource =
46
+ /** Read from the `sessionId` of the transcript's first well-formed record. Authoritative. */
47
+ "transcript"
48
+ /**
49
+ * Not determined: the file was unreadable, empty, or its first records carried no `sessionId`.
50
+ * `id` is `undefined` — deliberately not the filename, which is a hash and not an id.
51
+ */
52
+ | "unavailable";
53
+ /** One session found on disk. */
54
+ export interface SessionListing {
55
+ /**
56
+ * The session id, or `undefined` when {@link idSource} is `"unavailable"`.
57
+ *
58
+ * Never derived from the filename. The filename is a UUIDv8 over SHA-256 of the id, so treating
59
+ * it as the id is the exact defect this function exists to prevent.
60
+ */
61
+ readonly id: string | undefined;
62
+ /** Where {@link id} came from. Check this before acting on `id`. */
63
+ readonly idSource: SessionIdSource;
64
+ /** Absolute path to the `.jsonl` transcript. */
65
+ readonly transcript: string;
66
+ /** Last modification time of the transcript. */
67
+ readonly modifiedAt: Date;
68
+ }
69
+ /** Options for {@link listSessions}. */
70
+ export interface ListSessionsOptions {
71
+ /**
72
+ * Root under which `projects/<encoded-cwd>/` lives. Defaults to {@link transcriptRoot}, which
73
+ * honours `THEOKIT_HOME`.
74
+ */
75
+ readonly baseDir?: string;
76
+ /**
77
+ * How many bytes of each transcript to read looking for the id. Default 65536.
78
+ *
79
+ * A cap rather than a full read because a transcript grows without bound and the id is in the
80
+ * first record. A session whose id is not in the first 64KB reports `"unavailable"` rather than
81
+ * being read to the end — bounded work with a declared outcome beats an unbounded read.
82
+ */
83
+ readonly idScanBytes?: number;
84
+ }
85
+ /**
86
+ * Every session transcript under `<baseDir>/projects/<encoded-cwd>/`, with the id read from inside
87
+ * each file.
88
+ *
89
+ * An absent directory yields `[]` — a cwd with no sessions is the common case, not an error.
90
+ *
91
+ * ```ts
92
+ * for (const s of await listSessions(process.cwd())) {
93
+ * if (s.idSource === "unavailable") continue; // do not guess, and do not delete
94
+ * …
95
+ * }
96
+ * ```
97
+ */
98
+ export declare function listSessions(cwd: string, options?: ListSessionsOptions): Promise<readonly SessionListing[]>;