chainlesschain 0.163.3 → 0.163.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +3 -2
- package/scripts/command-lifecycle-report.mjs +330 -38
- package/src/assets/web-panel/assets/{AIOps-DIY6KxV-.js → AIOps-Cv2EE1Zy.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-BXH0muPt.js → ActionButton-CcpxMLuW.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-D39w8vmg.js → Analytics-DE8mJoMI.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-CUU1zvLs.js → AppLayout-DKn9dk9L.js} +5 -5
- package/src/assets/web-panel/assets/{Artifacts-D8azHO3T.js → Artifacts-Cp3mG3Py.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-D0tAwXTg.js → Audit-zvsQfF2C.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-C29mhJll.js → BackgroundAgents-Bi85SsjN.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-D6Aa1Gro.js → Backup-Cw47Dj6s.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-B1uoHbPQ.js → BaseInput-C5Ip2afH.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-Bs4DLOR5.js → Chat-C0iAFkJv.js} +5 -5
- package/src/assets/web-panel/assets/{ChatBubbleRenderer-DUYIBSle.js → ChatBubbleRenderer-BV9Wv7wO.js} +1 -1
- package/src/assets/web-panel/assets/{Checkbox-CNcBPEa4.js → Checkbox-3KZZCiAF.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-CIY89763.js → Codegen-C8OMbBAz.js} +1 -1
- package/src/assets/web-panel/assets/{Col-CsPYFmgo.js → Col-B-MB84LJ.js} +1 -1
- package/src/assets/web-panel/assets/{Community-BBocEge4.js → Community-DpR7Dxao.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-TQ8Ux0Lf.js → Compact-CyDtz0OS.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-DfBsZTft.js → Compliance-5tiRa2An.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-Cg-I6FVH.js → Cowork-DnQaKZ5x.js} +4 -4
- package/src/assets/web-panel/assets/{Cron-DTQzfRTp.js → Cron-BaWfoEDf.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-DGxEKGpR.js → Crosschain-Bu0HoHhb.js} +1 -1
- package/src/assets/web-panel/assets/{DID-DLZ1RDSr.js → DID-31zk8upX.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-XneICKNI.js → Dashboard-BmVne-e2.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-BRU00J1-.js → Dropdown-B4PkoOWd.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-BzCbJuAy.js → EmailListRenderer-BZ6tyFtI.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-D7BRyNBG.js → FamilyGuardDashboard-Osozn4Ds.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-D9DeFIhW.js → Federation-DaH8TOAP.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-6rAtA9Ko.js → FormItemContext-tbU0uwis.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-8Hqy80pU.js → GenericCardRenderer-Df8LQBrL.js} +1 -1
- package/src/assets/web-panel/assets/{Git-Cmvkj1rt.js → Git-DsMB6-14.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-BRiQUjjw.js → Governance-BnH0dZzd.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-CKN_EzVf.js → Inference-DhnN1N_P.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-BCDHwpwQ.js → KnowledgeGraph-DnNshAgn.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-DK9ovhaB.js → Logs-BmBFX3_N.js} +2 -2
- package/src/assets/web-panel/assets/{MarkdownRenderer-D53pHiHy.js → MarkdownRenderer-DCslfQU3.js} +1 -1
- package/src/assets/web-panel/assets/{Marketplace-BILPGakp.js → Marketplace-CPEgWDc3.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-DTVCOr9-.js → McpTools-C36qjgF9.js} +5 -5
- package/src/assets/web-panel/assets/{Memory-Hzc1iow4.js → Memory-tNHvrgqN.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-GXfgnGYV.js → MobileBridge-Xaf6cKjc.js} +1 -1
- package/src/assets/web-panel/assets/{MobileProjects-B-3TJWsS.js → MobileProjects-D2E5TTeO.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-DwSJMWtK.js → Mtc-D4AJ2dwV.js} +4 -4
- package/src/assets/web-panel/assets/{MtcAudit-D2uxf-DA.js → MtcAudit-Df-gtn2_.js} +4 -4
- package/src/assets/web-panel/assets/{Multisig-DG6kbKK0.js → Multisig-DTCHLWld.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-f5p49EDU.js → NLProgramming-DruZ_1Jb.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-FUgHyzSD.js → Notes-Dx3pdGDs.js} +4 -4
- package/src/assets/web-panel/assets/{NotificationSettings-DCHGee7e.js → NotificationSettings-Bi3L69oL.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-Dm6LlIoa.js → OrderTableRenderer-BHY33m7C.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-BawA7qAg.js → Organization-BG2ZVEV-.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-D6a5wZU1.js → Overflow-Viwtg4Mn.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-K8WavwnA.js → P2P-Clm_yc1Z.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-4JAJYaqx.js → PdhVaultBrowser-NKmmDiOw.js} +5 -5
- package/src/assets/web-panel/assets/{Permissions-BDWvi8PD.js → Permissions-DIL8u9Nk.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-DF_K4E9i.js → PersonalDataHub-B-jM4wt-.js} +4 -4
- package/src/assets/web-panel/assets/{Pipeline-BYeZlesI.js → Pipeline-627I__H5.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-BIHlgnIc.js → Privacy-2DN2qrkW.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-Cvf-6B5P.js → ProjectInit-CN4wC0sF.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-CnwfJrRz.js → ProjectSettings-K35vsh5H.js} +2 -2
- package/src/assets/web-panel/assets/Projects-B_wQadhX.js +1 -0
- package/src/assets/web-panel/assets/{Providers-CxC7JuYv.js → Providers-MckaQUhQ.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-VLf3gAfL.js → QrScannerModal-BS3mtA_O.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-B5vGjRiF.js → QuickAsk-BHp_nofL.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend--UW4iYs-.js → Recommend-DlmnPuZj.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-DMSPcfKR.js → RemoteSession-tsyFbvpy.js} +2 -2
- package/src/assets/web-panel/assets/{Reputation-kQXlEHmj.js → Reputation-Ba1iWv2D.js} +1 -1
- package/src/assets/web-panel/assets/{Row-CxGu3pit.js → Row-NnlGC--f.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-Bi5lo8MZ.js → RssFeed-CjThSIRv.js} +3 -3
- package/src/assets/web-panel/assets/{Search-Cq_H5RTh.js → Search-CojUyC5x.js} +1 -1
- package/src/assets/web-panel/assets/{Security-YFbmkaQS.js → Security-c-sxeJEc.js} +3 -3
- package/src/assets/web-panel/assets/{Services-DLOGdaLm.js → Services-CtcKEEmF.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-CteIxb3D.js → Skeleton-CIBBXflN.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-CccopaIZ.js → Skills-D1XOOK9n.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-AzfEQKX1.js → Sla-hRfEp5Sn.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-ekGo5l77.js → SpeechSettings-Dexb1f_6.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-BmZmAgYH.js → SyncSettings-BJsSFGYy.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-D7q3Z4uL.js → Tasks-CfSZ8A1L.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-CX1Tgeka.js → Templates-idDf47W-.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-Zc59jF4i.js → Tenant-C-UsX6w6.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-CXOD7y83.js → Terminal-BgJtX5n1.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-B1aBHPBo.js → TimelineRenderer-DP0BLKTl.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-zALlOq_U.js → Tokens-LwCzqETp.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-CQfJMXaq.js → Trigger-D_9tVch0.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-BU0RcM-w.js → Trust-BH2UlEWh.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-IFZ3HsbH.js → UkeySign-CIpD0nYb.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-BzslgW0v.js → VideoEditing-9ShhYxK_.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-BZAcQNS6.js → Wallet-C7afGNIG.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-CBK1DMi0.js → WebAuthn-bUKn6i5R.js} +3 -3
- package/src/assets/web-panel/assets/{WorkflowEditor-BlMTPzO-.js → WorkflowEditor-CxgQaGyp.js} +1 -1
- package/src/assets/web-panel/assets/{chat-B51-8QVn.js → chat-DMVkmJwx.js} +1 -1
- package/src/assets/web-panel/assets/{colors-504RTByU.js → colors-CDzQh5nS.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-C-GP6IQM.js → compact-item-C51kEF4D.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-DOkIj7ID.js → createContext-BTk9bXBn.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-CdwPwYj8.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-DN7V-_FW.js → hasIn-CMje33rb.js} +1 -1
- package/src/assets/web-panel/assets/{index-CKTfZyfU.js → index-0Auljb10.js} +1 -1
- package/src/assets/web-panel/assets/{index-D9LyiN-L.js → index-B0-zMtKA.js} +1 -1
- package/src/assets/web-panel/assets/{index-DEMPUVa3.js → index-BAfY7m7i.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bkxhaeta.js → index-BBz9LIMS.js} +1 -1
- package/src/assets/web-panel/assets/{index-7jIqHbzw.js → index-BCRvG9lq.js} +1 -1
- package/src/assets/web-panel/assets/index-BEeOdfEe.js +1 -0
- package/src/assets/web-panel/assets/index-BTe0TOu6.js +1 -0
- package/src/assets/web-panel/assets/{index-P2mfY27Z.js → index-BTlsE8Df.js} +1 -1
- package/src/assets/web-panel/assets/{index-DAOpQvl_.js → index-BVePe_Rf.js} +1 -1
- package/src/assets/web-panel/assets/{index-CYopNjcJ.js → index-BW4F5YDF.js} +1 -1
- package/src/assets/web-panel/assets/{index-B_vGU-Js.js → index-BXQBPLyE.js} +1 -1
- package/src/assets/web-panel/assets/{index-kt_5rfcZ.js → index-BeEaAEIp.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cao5DZy7.js → index-BtlEqHLP.js} +1 -1
- package/src/assets/web-panel/assets/{index-DA2f1UV3.js → index-BzCkNylB.js} +1 -1
- package/src/assets/web-panel/assets/{index-B2-x9bS8.js → index-C1oZQmAA.js} +1 -1
- package/src/assets/web-panel/assets/{index-D1phyca8.js → index-C1oZReaY.js} +1 -1
- package/src/assets/web-panel/assets/{index-FcV8J_Qz.js → index-C4rQCS8T.js} +1 -1
- package/src/assets/web-panel/assets/{index-C3TSohzc.js → index-C5IWTMVl.js} +1 -1
- package/src/assets/web-panel/assets/{index-CySTJKeq.js → index-CCLj9hcD.js} +1 -1
- package/src/assets/web-panel/assets/{index-C9_48OzU.js → index-CDLkNkLj.js} +1 -1
- package/src/assets/web-panel/assets/{index-so8eIIxF.js → index-Cd0hmPxD.js} +1 -1
- package/src/assets/web-panel/assets/{index-CX78k-qf.js → index-CfC-piWZ.js} +1 -1
- package/src/assets/web-panel/assets/{index-DE-hmI2l.js → index-CtM8OT_7.js} +1 -1
- package/src/assets/web-panel/assets/{index-kAqQXfP6.js → index-CvSeVzqe.js} +1 -1
- package/src/assets/web-panel/assets/{index-C0k_Nqg9.js → index-CwGPwjUu.js} +1 -1
- package/src/assets/web-panel/assets/{index-CP2A226L.js → index-CypsfcEq.js} +1 -1
- package/src/assets/web-panel/assets/{index-CfiEM64n.js → index-D9rC-fGW.js} +3 -3
- package/src/assets/web-panel/assets/{index-yYTQZypF.js → index-DJfnCuMq.js} +1 -1
- package/src/assets/web-panel/assets/{index-f4Bo4KXm.js → index-DRG-aqOs.js} +1 -1
- package/src/assets/web-panel/assets/{index-By6u5IV1.js → index-DRLQyp2A.js} +1 -1
- package/src/assets/web-panel/assets/{index-ConjaJro.js → index-DgivOKHA.js} +1 -1
- package/src/assets/web-panel/assets/{index--n-ZciV3.js → index-DpcrFxMI.js} +1 -1
- package/src/assets/web-panel/assets/{index-CqcLo5WV.js → index-DqU9njjT.js} +1 -1
- package/src/assets/web-panel/assets/{index-CUhQpiYv.js → index-Ld_4mFmC.js} +1 -1
- package/src/assets/web-panel/assets/{index-C4DV_5uA.js → index-OS-vfbTA.js} +1 -1
- package/src/assets/web-panel/assets/{index-DaA__-q1.js → index-h31MwrME.js} +1 -1
- package/src/assets/web-panel/assets/{index-BFIFJ5Dr.js → index-hg_emBsi.js} +1 -1
- package/src/assets/web-panel/assets/{index-C8UltbXK.js → index-togc_uYn.js} +1 -1
- package/src/assets/web-panel/assets/{index-et5JIPHO.js → index-x53Vf7la.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-CPYEIdpV.js → initDefaultProps-vrA8K-ac.js} +1 -1
- package/src/assets/web-panel/assets/{motion-Cjim9pxs.js → motion-ByEzwIAl.js} +1 -1
- package/src/assets/web-panel/assets/{move-DuU-cgz3.js → move-Ck4AWjw-.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-DJHNAkta.js → mtc-parser-6p0l9SrB.js} +1 -1
- package/src/assets/web-panel/assets/{omit-DSQBgdBj.js → omit-B1CUPQ6R.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-CTmT_j5m.js → pickAttrs-B1STg1iW.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-Lfm6v-r4.js → placementArrow-DTTllkBV.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-CgrcPcDi.js → responsiveObserve-AIrrCfBb.js} +1 -1
- package/src/assets/web-panel/assets/{slide-CuE3110i.js → slide-C_fPMjdR.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-DiK5nbpf.js → statusUtils-D5ow2yIP.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-DPEJdQaZ.js → styleChecker-Dy3hEA--.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-CnnodGmp.js → useFlexGapSupport-WfzcfSh4.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-DWF84Yav.js → useFs-CKSejfas.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-a5b5Dw2f.js → usePersonalDataHub-od3zpPBN.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-DAluzXOq.js → vnode-DRD_2DFA.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-Dokg7uAZ.js → zoom-DmNrEtgf.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/command-help-index.json +1 -1
- package/src/commands/agenda.js +52 -6
- package/src/commands/artifacts.js +98 -0
- package/src/commands/cowork.js +24 -12
- package/src/commands/mcp.js +1 -1
- package/src/commands/review.js +221 -22
- package/src/commands/routine.js +40 -10
- package/src/commands/session-mcp-recovery.js +5 -5
- package/src/data/changelog.json +27 -1
- package/src/gateways/ws/ws-agent-handler.js +492 -14
- package/src/harness/jsonl-session-store.js +39 -1
- package/src/harness/mcp-client.js +172 -29
- package/src/harness/prompt-compressor.js +24 -0
- package/src/harness/provider-backed-compaction.js +205 -0
- package/src/lib/agent-schedule-store.js +197 -4
- package/src/lib/app-preview.js +3 -0
- package/src/lib/command-lifecycle-report.js +1340 -145
- package/src/lib/cowork-cron.js +243 -25
- package/src/lib/delivery-coordinator.js +30 -5
- package/src/lib/delivery-production-adapter.js +1777 -0
- package/src/lib/delivery-production-runner.js +240 -0
- package/src/lib/durable-security-store.js +29 -17
- package/src/lib/execution-trace/trace-context.cjs +179 -0
- package/src/lib/execution-trace/trace-context.js +8 -175
- package/src/lib/mcp-call-ledger-store.js +58 -6
- package/src/lib/mcp-host-recovery-runtime.js +2 -0
- package/src/lib/mcp-ledger-recovery-admission.js +39 -3
- package/src/lib/mcp-recovery-adjudication.js +256 -19
- package/src/lib/mcp-sandbox-policy.js +29 -0
- package/src/lib/mcp-stdio-capsule-builder-worker.cjs +495 -0
- package/src/lib/mcp-stdio-executable-identity.js +33 -2
- package/src/lib/mcp-stdio-immutable-vfs-resolver.cjs +830 -0
- package/src/lib/mcp-stdio-package-materialization.js +721 -333
- package/src/lib/micro-compact.js +11 -5
- package/src/lib/observability/index.js +2 -0
- package/src/lib/observability/otlp-exporter.js +2 -2
- package/src/lib/packer/pack-update-applier.js +8 -1
- package/src/lib/packer/pkg-config-generator.js +34 -0
- package/src/lib/process-execution-broker/index.js +48 -8
- package/src/lib/process-execution-broker/platform-sandbox.js +82 -1
- package/src/lib/routine-store.js +76 -3
- package/src/lib/scheduler-kernel/agenda-adapter.js +542 -0
- package/src/lib/scheduler-kernel/contract.js +315 -0
- package/src/lib/scheduler-kernel/cowork-cron-adapter.js +774 -0
- package/src/lib/scheduler-kernel/routine-adapter.js +517 -0
- package/src/lib/scheduler-kernel/runtime.js +527 -0
- package/src/lib/scheduler-kernel/store.js +1455 -0
- package/src/lib/session-host-lease.js +403 -30
- package/src/lib/session-message-provenance.js +4 -1
- package/src/lib/session-persistence-failure.js +4 -1
- package/src/lib/sub-agent-context.js +8 -0
- package/src/repl/agent-repl.js +309 -43
- package/src/runtime/agent-core.js +1079 -105
- package/src/runtime/headless-runner.js +260 -166
- package/src/runtime/headless-stream.js +254 -25
- package/src/assets/web-panel/assets/Projects-b-jPXzF4.js +0 -1
- package/src/assets/web-panel/assets/devWarning-kB0nCNwN.js +0 -1
- package/src/assets/web-panel/assets/index-Bya64sZE.js +0 -1
- package/src/assets/web-panel/assets/index-D_FWpDZM.js +0 -1
|
@@ -168,6 +168,34 @@ function hasLiveExecutionLease(entry, now) {
|
|
|
168
168
|
return Number(entry.executionLease?.expiresAt) > Number(now);
|
|
169
169
|
}
|
|
170
170
|
|
|
171
|
+
function agendaStoreError(code, message, { retryable = false, retryAt } = {}) {
|
|
172
|
+
const error = new Error(message);
|
|
173
|
+
error.code = code;
|
|
174
|
+
error.retryable = retryable;
|
|
175
|
+
if (retryAt !== undefined) error.retryAt = retryAt;
|
|
176
|
+
return error;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
function applyScheduledAgentSuccess(entry, atMs) {
|
|
180
|
+
if (entry.kind === "wakeup") {
|
|
181
|
+
entry.status = "fired";
|
|
182
|
+
entry.firedAt = atMs;
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
if (entry.kind === "cron") {
|
|
186
|
+
entry.lastRunAt = atMs;
|
|
187
|
+
entry.runs = (entry.runs || 0) + 1;
|
|
188
|
+
const next = nextCronTime(entry.cron, atMs);
|
|
189
|
+
if (next == null) entry.status = "exhausted";
|
|
190
|
+
else entry.nextAt = next;
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
throw agendaStoreError(
|
|
194
|
+
"AGENDA_SCHEDULER_KIND_UNSUPPORTED",
|
|
195
|
+
`Scheduler execution is not supported for agenda kind: ${entry.kind}`,
|
|
196
|
+
);
|
|
197
|
+
}
|
|
198
|
+
|
|
171
199
|
/** Statuses an entry can never leave — safe to prune. */
|
|
172
200
|
export const TERMINAL_STATUSES = Object.freeze([
|
|
173
201
|
"fired",
|
|
@@ -499,6 +527,11 @@ export class AgentScheduleStore {
|
|
|
499
527
|
return out;
|
|
500
528
|
}
|
|
501
529
|
|
|
530
|
+
get(id) {
|
|
531
|
+
if (typeof id !== "string" || id.length === 0) return null;
|
|
532
|
+
return this.list().find((entry) => entry.id === id) || null;
|
|
533
|
+
}
|
|
534
|
+
|
|
502
535
|
/** Entries whose time has come (pending wakeup / active cron|monitor). */
|
|
503
536
|
due(kind = null, atMs = null) {
|
|
504
537
|
const now = atMs != null ? atMs : this._now();
|
|
@@ -524,16 +557,20 @@ export class AgentScheduleStore {
|
|
|
524
557
|
* lease expires. This is deliberately separate from `due()` for backwards
|
|
525
558
|
* compatibility with read-only callers and injected test stores.
|
|
526
559
|
*/
|
|
527
|
-
claimDue(atMs = null, leaseMs = 120000) {
|
|
560
|
+
claimDue(atMs = null, leaseMs = 120000, kind = null) {
|
|
528
561
|
const now = atMs != null ? Number(atMs) : this._now();
|
|
529
562
|
const ttl = Math.max(1000, Number(leaseMs) || 120000);
|
|
563
|
+
const kinds = kind == null ? SCHEDULE_KINDS : [kind];
|
|
564
|
+
if (kinds.some((value) => !SCHEDULE_KINDS.includes(value))) {
|
|
565
|
+
throw new Error(`unknown schedule kind: ${kind}`);
|
|
566
|
+
}
|
|
530
567
|
this._ensureDir();
|
|
531
568
|
return withFileLock(
|
|
532
569
|
path.join(this.dir, ".agenda-claims"),
|
|
533
570
|
() => {
|
|
534
571
|
const claimed = [];
|
|
535
|
-
for (const
|
|
536
|
-
const entries = this._readAll(
|
|
572
|
+
for (const scheduleKind of kinds) {
|
|
573
|
+
const entries = this._readAll(scheduleKind);
|
|
537
574
|
let changed = false;
|
|
538
575
|
for (const entry of entries) {
|
|
539
576
|
if (!isSchedulableStatus(entry) || isEntryExpired(entry, now))
|
|
@@ -552,7 +589,7 @@ export class AgentScheduleStore {
|
|
|
552
589
|
});
|
|
553
590
|
changed = true;
|
|
554
591
|
}
|
|
555
|
-
if (changed) this._writeAll(
|
|
592
|
+
if (changed) this._writeAll(scheduleKind, entries);
|
|
556
593
|
}
|
|
557
594
|
return claimed;
|
|
558
595
|
},
|
|
@@ -571,6 +608,162 @@ export class AgentScheduleStore {
|
|
|
571
608
|
return null;
|
|
572
609
|
}
|
|
573
610
|
|
|
611
|
+
/**
|
|
612
|
+
* Bind a scheduler claim to the legacy Agenda entry before agent execution.
|
|
613
|
+
* The same lock used by legacy `claimDue()` prevents an old/new driver from
|
|
614
|
+
* starting the entry concurrently during migration.
|
|
615
|
+
*/
|
|
616
|
+
bindSchedulerExecution(
|
|
617
|
+
id,
|
|
618
|
+
{ occurrenceId, snapshotDigest, attempt, atMs = null } = {},
|
|
619
|
+
) {
|
|
620
|
+
const now = atMs != null ? Number(atMs) : this._now();
|
|
621
|
+
if (typeof occurrenceId !== "string" || occurrenceId.length === 0) {
|
|
622
|
+
throw agendaStoreError(
|
|
623
|
+
"AGENDA_SCHEDULER_BINDING_INVALID",
|
|
624
|
+
"Agenda scheduler occurrenceId is required",
|
|
625
|
+
);
|
|
626
|
+
}
|
|
627
|
+
if (typeof snapshotDigest !== "string" || snapshotDigest.length === 0) {
|
|
628
|
+
throw agendaStoreError(
|
|
629
|
+
"AGENDA_SCHEDULER_BINDING_INVALID",
|
|
630
|
+
"Agenda scheduler snapshotDigest is required",
|
|
631
|
+
);
|
|
632
|
+
}
|
|
633
|
+
if (!Number.isSafeInteger(attempt) || attempt < 1) {
|
|
634
|
+
throw agendaStoreError(
|
|
635
|
+
"AGENDA_SCHEDULER_BINDING_INVALID",
|
|
636
|
+
"Agenda scheduler attempt must be a positive integer",
|
|
637
|
+
);
|
|
638
|
+
}
|
|
639
|
+
this._ensureDir();
|
|
640
|
+
return withFileLock(
|
|
641
|
+
path.join(this.dir, ".agenda-claims"),
|
|
642
|
+
() => {
|
|
643
|
+
for (const kind of ["wakeup", "cron"]) {
|
|
644
|
+
const entries = this._readAll(kind);
|
|
645
|
+
const entry = entries.find((candidate) => candidate.id === id);
|
|
646
|
+
if (!entry) continue;
|
|
647
|
+
const prior = entry.schedulerExecution;
|
|
648
|
+
if (prior?.status === "running") {
|
|
649
|
+
throw agendaStoreError(
|
|
650
|
+
"AGENDA_SCHEDULER_OUTCOME_UNKNOWN",
|
|
651
|
+
`Agenda scheduler execution outcome is unknown: ${id}`,
|
|
652
|
+
);
|
|
653
|
+
}
|
|
654
|
+
if (
|
|
655
|
+
prior?.status === "succeeded" &&
|
|
656
|
+
prior.occurrenceId === occurrenceId &&
|
|
657
|
+
prior.snapshotDigest === snapshotDigest
|
|
658
|
+
) {
|
|
659
|
+
return entry;
|
|
660
|
+
}
|
|
661
|
+
if (hasLiveExecutionLease(entry, now)) {
|
|
662
|
+
throw agendaStoreError(
|
|
663
|
+
"AGENDA_SCHEDULER_LEGACY_CLAIM_ACTIVE",
|
|
664
|
+
`Agenda entry is already claimed by a legacy runner: ${id}`,
|
|
665
|
+
{
|
|
666
|
+
retryable: true,
|
|
667
|
+
retryAt: Number(entry.executionLease.expiresAt),
|
|
668
|
+
},
|
|
669
|
+
);
|
|
670
|
+
}
|
|
671
|
+
entry.schedulerExecution = {
|
|
672
|
+
occurrenceId,
|
|
673
|
+
snapshotDigest,
|
|
674
|
+
attempt,
|
|
675
|
+
status: "running",
|
|
676
|
+
startedAt: now,
|
|
677
|
+
};
|
|
678
|
+
// Fence an older CLI that only understands the legacy claim field.
|
|
679
|
+
// Terminal scheduler evidence clears this lease; an outcome-unknown
|
|
680
|
+
// execution intentionally keeps it non-expiring until adjudicated so
|
|
681
|
+
// an old runner cannot duplicate an uncertain agent side effect.
|
|
682
|
+
entry.executionLease = {
|
|
683
|
+
owner: `scheduler:${occurrenceId}:${attempt}`,
|
|
684
|
+
claimedAt: now,
|
|
685
|
+
expiresAt: Number.MAX_SAFE_INTEGER,
|
|
686
|
+
};
|
|
687
|
+
this._writeAll(kind, entries);
|
|
688
|
+
return entry;
|
|
689
|
+
}
|
|
690
|
+
throw agendaStoreError(
|
|
691
|
+
"AGENDA_SCHEDULER_ENTRY_NOT_FOUND",
|
|
692
|
+
`Agenda entry does not exist: ${id}`,
|
|
693
|
+
);
|
|
694
|
+
},
|
|
695
|
+
{ failIfUnavailable: true },
|
|
696
|
+
);
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
/**
|
|
700
|
+
* Atomically publish scheduler evidence and the legacy wakeup/cron state.
|
|
701
|
+
* A successful cron advances exactly once in the same JSONL replacement that
|
|
702
|
+
* records terminal evidence; failures keep the entry schedulable for the
|
|
703
|
+
* scheduler kernel's bounded retry policy.
|
|
704
|
+
*/
|
|
705
|
+
completeSchedulerExecution(
|
|
706
|
+
id,
|
|
707
|
+
{
|
|
708
|
+
occurrenceId,
|
|
709
|
+
snapshotDigest,
|
|
710
|
+
attempt,
|
|
711
|
+
outcome,
|
|
712
|
+
result = null,
|
|
713
|
+
error = null,
|
|
714
|
+
atMs = null,
|
|
715
|
+
} = {},
|
|
716
|
+
) {
|
|
717
|
+
if (!["succeeded", "failed"].includes(outcome)) {
|
|
718
|
+
throw agendaStoreError(
|
|
719
|
+
"AGENDA_SCHEDULER_OUTCOME_INVALID",
|
|
720
|
+
"Agenda scheduler outcome must be succeeded or failed",
|
|
721
|
+
);
|
|
722
|
+
}
|
|
723
|
+
const now = atMs != null ? Number(atMs) : this._now();
|
|
724
|
+
this._ensureDir();
|
|
725
|
+
return withFileLock(
|
|
726
|
+
path.join(this.dir, ".agenda-claims"),
|
|
727
|
+
() => {
|
|
728
|
+
for (const kind of ["wakeup", "cron"]) {
|
|
729
|
+
const entries = this._readAll(kind);
|
|
730
|
+
const entry = entries.find((candidate) => candidate.id === id);
|
|
731
|
+
if (!entry) continue;
|
|
732
|
+
const evidence = entry.schedulerExecution;
|
|
733
|
+
if (
|
|
734
|
+
!evidence ||
|
|
735
|
+
evidence.occurrenceId !== occurrenceId ||
|
|
736
|
+
evidence.snapshotDigest !== snapshotDigest ||
|
|
737
|
+
evidence.attempt !== attempt ||
|
|
738
|
+
evidence.status !== "running"
|
|
739
|
+
) {
|
|
740
|
+
throw agendaStoreError(
|
|
741
|
+
"AGENDA_SCHEDULER_BINDING_MISMATCH",
|
|
742
|
+
`Agenda scheduler evidence does not match the active claim: ${id}`,
|
|
743
|
+
);
|
|
744
|
+
}
|
|
745
|
+
if (outcome === "succeeded") {
|
|
746
|
+
applyScheduledAgentSuccess(entry, now);
|
|
747
|
+
}
|
|
748
|
+
entry.schedulerExecution = {
|
|
749
|
+
...evidence,
|
|
750
|
+
status: outcome,
|
|
751
|
+
endedAt: now,
|
|
752
|
+
...(outcome === "succeeded" ? { result } : { error }),
|
|
753
|
+
};
|
|
754
|
+
delete entry.executionLease;
|
|
755
|
+
this._writeAll(kind, entries);
|
|
756
|
+
return entry;
|
|
757
|
+
}
|
|
758
|
+
throw agendaStoreError(
|
|
759
|
+
"AGENDA_SCHEDULER_ENTRY_NOT_FOUND",
|
|
760
|
+
`Agenda entry does not exist: ${id}`,
|
|
761
|
+
);
|
|
762
|
+
},
|
|
763
|
+
{ failIfUnavailable: true },
|
|
764
|
+
);
|
|
765
|
+
}
|
|
766
|
+
|
|
574
767
|
/**
|
|
575
768
|
* Retire every schedulable entry whose `expiresAt` has passed (status →
|
|
576
769
|
* "expired", stamping `expiredAt`), across all kinds, so it never fires again.
|
package/src/lib/app-preview.js
CHANGED
|
@@ -311,6 +311,9 @@ export function buildEvidenceArtifact(kind, data = {}) {
|
|
|
311
311
|
...base,
|
|
312
312
|
// The image bytes/path are opaque to this layer; only metadata here.
|
|
313
313
|
ref: d.ref == null ? null : String(d.ref),
|
|
314
|
+
digest: /^sha256:[0-9a-f]{64}$/iu.test(String(d.digest || ""))
|
|
315
|
+
? String(d.digest).toLowerCase()
|
|
316
|
+
: null,
|
|
314
317
|
width: Number.isFinite(Number(d.width)) ? Number(d.width) : null,
|
|
315
318
|
height: Number.isFinite(Number(d.height)) ? Number(d.height) : null,
|
|
316
319
|
};
|