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
package/src/lib/cowork-cron.js
CHANGED
|
@@ -53,6 +53,33 @@ export const _deps = {
|
|
|
53
53
|
runTask: null, // injected at runtime to avoid circular import
|
|
54
54
|
};
|
|
55
55
|
|
|
56
|
+
export const COWORK_SCHEDULER_UNKNOWN_LEASE_EXPIRES_AT =
|
|
57
|
+
"9999-12-31T23:59:59.999Z";
|
|
58
|
+
|
|
59
|
+
function coworkSchedulerError(
|
|
60
|
+
code,
|
|
61
|
+
message,
|
|
62
|
+
{ retryable = false, retryAt } = {},
|
|
63
|
+
) {
|
|
64
|
+
const error = new Error(message);
|
|
65
|
+
error.code = code;
|
|
66
|
+
error.retryable = retryable;
|
|
67
|
+
if (retryAt !== undefined) error.retryAt = retryAt;
|
|
68
|
+
return error;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function normalizedDate(value, label) {
|
|
72
|
+
const date =
|
|
73
|
+
value instanceof Date ? new Date(value.getTime()) : new Date(value);
|
|
74
|
+
if (!Number.isFinite(date.getTime())) {
|
|
75
|
+
throw coworkSchedulerError(
|
|
76
|
+
"COWORK_SCHEDULER_TIME_INVALID",
|
|
77
|
+
`${label} must be a valid date`,
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
return date;
|
|
81
|
+
}
|
|
82
|
+
|
|
56
83
|
// ─── Cron parser ─────────────────────────────────────────────────────────────
|
|
57
84
|
|
|
58
85
|
const FIELD_RANGES = [
|
|
@@ -293,9 +320,7 @@ function _withScheduleLock(cwd, body) {
|
|
|
293
320
|
|
|
294
321
|
/** Atomically replace the full schedule list under a fail-closed lock. */
|
|
295
322
|
export function saveSchedules(cwd, schedules) {
|
|
296
|
-
return _withScheduleLock(cwd, () =>
|
|
297
|
-
_saveSchedulesUnlocked(cwd, schedules),
|
|
298
|
-
);
|
|
323
|
+
return _withScheduleLock(cwd, () => _saveSchedulesUnlocked(cwd, schedules));
|
|
299
324
|
}
|
|
300
325
|
|
|
301
326
|
// ─── CRUD ────────────────────────────────────────────────────────────────────
|
|
@@ -363,6 +388,191 @@ export function updateScheduleRunState(cwd, id, { lastRunAt, lastStatus }) {
|
|
|
363
388
|
});
|
|
364
389
|
}
|
|
365
390
|
|
|
391
|
+
/** Return one schedule by id, or null when it does not exist. */
|
|
392
|
+
export function getSchedule(cwd, id) {
|
|
393
|
+
if (typeof id !== "string" || id.length === 0) return null;
|
|
394
|
+
return (
|
|
395
|
+
loadSchedules(cwd, { failOnMalformed: true }).find(
|
|
396
|
+
(schedule) => schedule.id === id,
|
|
397
|
+
) || null
|
|
398
|
+
);
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
/**
|
|
402
|
+
* Bind a scheduler-kernel occurrence before starting the Cowork task.
|
|
403
|
+
* The same JSONL lock used by the legacy driver closes both old-first and
|
|
404
|
+
* new-first claim races during migration.
|
|
405
|
+
*/
|
|
406
|
+
export function bindSchedulerScheduleFire(
|
|
407
|
+
cwd,
|
|
408
|
+
id,
|
|
409
|
+
{ deliveryId, occurrenceId, snapshotDigest, attempt, at = _deps.now() } = {},
|
|
410
|
+
) {
|
|
411
|
+
if (
|
|
412
|
+
typeof deliveryId !== "string" ||
|
|
413
|
+
typeof occurrenceId !== "string" ||
|
|
414
|
+
typeof snapshotDigest !== "string" ||
|
|
415
|
+
deliveryId.length === 0 ||
|
|
416
|
+
occurrenceId.length === 0 ||
|
|
417
|
+
snapshotDigest.length === 0 ||
|
|
418
|
+
!Number.isSafeInteger(attempt) ||
|
|
419
|
+
attempt < 1
|
|
420
|
+
) {
|
|
421
|
+
throw coworkSchedulerError(
|
|
422
|
+
"COWORK_SCHEDULER_BINDING_INVALID",
|
|
423
|
+
"Cowork scheduler binding requires deliveryId, occurrenceId, snapshotDigest, and a positive attempt",
|
|
424
|
+
);
|
|
425
|
+
}
|
|
426
|
+
const now = normalizedDate(at, "cowork scheduler binding time");
|
|
427
|
+
const nowMs = now.getTime();
|
|
428
|
+
return _withScheduleLock(cwd, () => {
|
|
429
|
+
const schedules = loadSchedules(cwd, { failOnMalformed: true });
|
|
430
|
+
const schedule = schedules.find((entry) => entry.id === id);
|
|
431
|
+
if (!schedule) {
|
|
432
|
+
throw coworkSchedulerError(
|
|
433
|
+
"COWORK_SCHEDULER_SCHEDULE_NOT_FOUND",
|
|
434
|
+
`Cowork schedule does not exist: ${id}`,
|
|
435
|
+
);
|
|
436
|
+
}
|
|
437
|
+
const prior = schedule.schedulerExecution;
|
|
438
|
+
if (prior?.status === "running") {
|
|
439
|
+
throw coworkSchedulerError(
|
|
440
|
+
"COWORK_SCHEDULER_OUTCOME_UNKNOWN",
|
|
441
|
+
`Cowork schedule outcome is unknown: ${id}`,
|
|
442
|
+
);
|
|
443
|
+
}
|
|
444
|
+
if (
|
|
445
|
+
prior?.status === "succeeded" &&
|
|
446
|
+
prior.occurrenceId === occurrenceId &&
|
|
447
|
+
prior.snapshotDigest === snapshotDigest
|
|
448
|
+
) {
|
|
449
|
+
return schedule;
|
|
450
|
+
}
|
|
451
|
+
// A legacy runner may have completed after the kernel enqueued this fire
|
|
452
|
+
// but before it acquired the JSONL lock. Its durable delivery id is
|
|
453
|
+
// terminal evidence for the same logical fire, so never overwrite it with
|
|
454
|
+
// a new scheduler claim.
|
|
455
|
+
if (schedule.lastDeliveryId === deliveryId) return schedule;
|
|
456
|
+
|
|
457
|
+
const active = schedule.activeDelivery;
|
|
458
|
+
const activeExpiresAt = Date.parse(active?.leaseExpiresAt || "");
|
|
459
|
+
if (active && Number.isFinite(activeExpiresAt) && activeExpiresAt > nowMs) {
|
|
460
|
+
throw coworkSchedulerError(
|
|
461
|
+
"COWORK_SCHEDULER_LEGACY_CLAIM_ACTIVE",
|
|
462
|
+
`Cowork schedule is already claimed: ${id}`,
|
|
463
|
+
{ retryable: true, retryAt: activeExpiresAt },
|
|
464
|
+
);
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
const fence =
|
|
468
|
+
Math.max(
|
|
469
|
+
Number(schedule.deliveryFence) || 0,
|
|
470
|
+
Number(active?.fence) || 0,
|
|
471
|
+
) + 1;
|
|
472
|
+
schedule.deliveryFence = fence;
|
|
473
|
+
schedule.activeDelivery = {
|
|
474
|
+
deliveryId,
|
|
475
|
+
ownerId: `scheduler:${occurrenceId}:${attempt}`,
|
|
476
|
+
fence,
|
|
477
|
+
claimedAt: now.toISOString(),
|
|
478
|
+
leaseExpiresAt: COWORK_SCHEDULER_UNKNOWN_LEASE_EXPIRES_AT,
|
|
479
|
+
};
|
|
480
|
+
schedule.schedulerExecution = {
|
|
481
|
+
deliveryId,
|
|
482
|
+
occurrenceId,
|
|
483
|
+
snapshotDigest,
|
|
484
|
+
attempt,
|
|
485
|
+
status: "running",
|
|
486
|
+
startedAt: now.toISOString(),
|
|
487
|
+
};
|
|
488
|
+
_saveSchedulesUnlocked(cwd, schedules);
|
|
489
|
+
return schedule;
|
|
490
|
+
});
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
/**
|
|
494
|
+
* Atomically settle scheduler evidence and the legacy Cowork delivery state.
|
|
495
|
+
* A known failure may keep a short legacy-visible fence until retryAt; an
|
|
496
|
+
* unknown outcome never calls this function and therefore remains fenced.
|
|
497
|
+
*/
|
|
498
|
+
export function completeSchedulerScheduleFire(
|
|
499
|
+
cwd,
|
|
500
|
+
id,
|
|
501
|
+
{
|
|
502
|
+
deliveryId,
|
|
503
|
+
occurrenceId,
|
|
504
|
+
snapshotDigest,
|
|
505
|
+
attempt,
|
|
506
|
+
outcome,
|
|
507
|
+
result = null,
|
|
508
|
+
error = null,
|
|
509
|
+
retryAt,
|
|
510
|
+
at = _deps.now(),
|
|
511
|
+
} = {},
|
|
512
|
+
) {
|
|
513
|
+
if (!["succeeded", "failed"].includes(outcome)) {
|
|
514
|
+
throw coworkSchedulerError(
|
|
515
|
+
"COWORK_SCHEDULER_OUTCOME_INVALID",
|
|
516
|
+
"Cowork scheduler outcome must be succeeded or failed",
|
|
517
|
+
);
|
|
518
|
+
}
|
|
519
|
+
const now = normalizedDate(at, "cowork scheduler completion time");
|
|
520
|
+
const retryAtMs =
|
|
521
|
+
retryAt === undefined || retryAt === null ? null : Number(retryAt);
|
|
522
|
+
if (retryAtMs !== null && !Number.isSafeInteger(retryAtMs)) {
|
|
523
|
+
throw coworkSchedulerError(
|
|
524
|
+
"COWORK_SCHEDULER_RETRY_TIME_INVALID",
|
|
525
|
+
"Cowork scheduler retryAt must be a safe epoch millisecond",
|
|
526
|
+
);
|
|
527
|
+
}
|
|
528
|
+
return _withScheduleLock(cwd, () => {
|
|
529
|
+
const schedules = loadSchedules(cwd, { failOnMalformed: true });
|
|
530
|
+
const schedule = schedules.find((entry) => entry.id === id);
|
|
531
|
+
if (!schedule) {
|
|
532
|
+
throw coworkSchedulerError(
|
|
533
|
+
"COWORK_SCHEDULER_SCHEDULE_NOT_FOUND",
|
|
534
|
+
`Cowork schedule does not exist: ${id}`,
|
|
535
|
+
);
|
|
536
|
+
}
|
|
537
|
+
const evidence = schedule.schedulerExecution;
|
|
538
|
+
if (
|
|
539
|
+
!evidence ||
|
|
540
|
+
evidence.deliveryId !== deliveryId ||
|
|
541
|
+
evidence.occurrenceId !== occurrenceId ||
|
|
542
|
+
evidence.snapshotDigest !== snapshotDigest ||
|
|
543
|
+
evidence.attempt !== attempt ||
|
|
544
|
+
evidence.status !== "running"
|
|
545
|
+
) {
|
|
546
|
+
throw coworkSchedulerError(
|
|
547
|
+
"COWORK_SCHEDULER_BINDING_MISMATCH",
|
|
548
|
+
`Cowork scheduler evidence does not match the active claim: ${id}`,
|
|
549
|
+
);
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
schedule.schedulerExecution = {
|
|
553
|
+
...evidence,
|
|
554
|
+
status: outcome,
|
|
555
|
+
endedAt: now.toISOString(),
|
|
556
|
+
...(outcome === "succeeded" ? { result } : { error }),
|
|
557
|
+
};
|
|
558
|
+
if (outcome === "succeeded") {
|
|
559
|
+
schedule.lastDeliveryId = deliveryId;
|
|
560
|
+
schedule.lastRunAt = now.toISOString();
|
|
561
|
+
schedule.lastStatus = result?.status || "completed";
|
|
562
|
+
schedule.activeDelivery = null;
|
|
563
|
+
} else if (retryAtMs !== null && retryAtMs > now.getTime()) {
|
|
564
|
+
schedule.activeDelivery = {
|
|
565
|
+
...schedule.activeDelivery,
|
|
566
|
+
leaseExpiresAt: new Date(retryAtMs).toISOString(),
|
|
567
|
+
};
|
|
568
|
+
} else {
|
|
569
|
+
schedule.activeDelivery = null;
|
|
570
|
+
}
|
|
571
|
+
_saveSchedulesUnlocked(cwd, schedules);
|
|
572
|
+
return schedule;
|
|
573
|
+
});
|
|
574
|
+
}
|
|
575
|
+
|
|
366
576
|
/**
|
|
367
577
|
* Claim one concrete cron fire before launching its side effect. The persisted
|
|
368
578
|
* delivery id prevents two scheduler processes from running the same fire; an
|
|
@@ -564,9 +774,7 @@ export class CoworkCronScheduler {
|
|
|
564
774
|
this._emit({ type: "invalid-cron", id: s.id, error: err.message });
|
|
565
775
|
continue;
|
|
566
776
|
}
|
|
567
|
-
const fireKey =
|
|
568
|
-
matcher.hasSeconds ? _secondKey(now) : _minuteKey(now)
|
|
569
|
-
}`;
|
|
777
|
+
const fireKey = coworkCronFireKey(s, now);
|
|
570
778
|
if (this._firedKeys.has(fireKey)) continue;
|
|
571
779
|
if (this._running.has(s.id)) continue;
|
|
572
780
|
const isDue = matcher(now);
|
|
@@ -634,27 +842,30 @@ export class CoworkCronScheduler {
|
|
|
634
842
|
deliveryId: claim.deliveryId,
|
|
635
843
|
});
|
|
636
844
|
|
|
637
|
-
const renewal = setInterval(
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
845
|
+
const renewal = setInterval(
|
|
846
|
+
() => {
|
|
847
|
+
try {
|
|
848
|
+
const renewed = renewScheduleFire(this.cwd, schedule.id, claim, {
|
|
849
|
+
leaseMs: this.leaseMs,
|
|
850
|
+
});
|
|
851
|
+
if (!renewed) {
|
|
852
|
+
this._emit({
|
|
853
|
+
type: "schedule-lease-lost",
|
|
854
|
+
id: schedule.id,
|
|
855
|
+
deliveryId: claim.deliveryId,
|
|
856
|
+
});
|
|
857
|
+
}
|
|
858
|
+
} catch (err) {
|
|
643
859
|
this._emit({
|
|
644
|
-
type: "schedule-lease-
|
|
860
|
+
type: "schedule-lease-renewal-failed",
|
|
645
861
|
id: schedule.id,
|
|
646
862
|
deliveryId: claim.deliveryId,
|
|
863
|
+
error: err.message,
|
|
647
864
|
});
|
|
648
865
|
}
|
|
649
|
-
}
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
id: schedule.id,
|
|
653
|
-
deliveryId: claim.deliveryId,
|
|
654
|
-
error: err.message,
|
|
655
|
-
});
|
|
656
|
-
}
|
|
657
|
-
}, Math.max(1000, Math.floor(this.leaseMs / 3)));
|
|
866
|
+
},
|
|
867
|
+
Math.max(1000, Math.floor(this.leaseMs / 3)),
|
|
868
|
+
);
|
|
658
869
|
renewal.unref?.();
|
|
659
870
|
|
|
660
871
|
let result = null;
|
|
@@ -718,12 +929,19 @@ export class CoworkCronScheduler {
|
|
|
718
929
|
}
|
|
719
930
|
}
|
|
720
931
|
|
|
721
|
-
function
|
|
932
|
+
export function coworkCronMinuteKey(date) {
|
|
722
933
|
return `${date.getFullYear()}-${date.getMonth()}-${date.getDate()}-${date.getHours()}-${date.getMinutes()}`;
|
|
723
934
|
}
|
|
724
935
|
|
|
725
|
-
function
|
|
726
|
-
return `${
|
|
936
|
+
export function coworkCronSecondKey(date) {
|
|
937
|
+
return `${coworkCronMinuteKey(date)}-${date.getSeconds()}`;
|
|
938
|
+
}
|
|
939
|
+
|
|
940
|
+
export function coworkCronFireKey(schedule, date) {
|
|
941
|
+
const matcher = parseCron(schedule.cron);
|
|
942
|
+
return `${schedule.id}:${
|
|
943
|
+
matcher.hasSeconds ? coworkCronSecondKey(date) : coworkCronMinuteKey(date)
|
|
944
|
+
}`;
|
|
727
945
|
}
|
|
728
946
|
|
|
729
947
|
// =====================================================================
|
|
@@ -719,34 +719,37 @@ export function createDeliveryFlow(config = {}, { now } = {}) {
|
|
|
719
719
|
}
|
|
720
720
|
|
|
721
721
|
function actionPayload(state, action, payload, now) {
|
|
722
|
+
const callerPayload = jsonClone(payload || {});
|
|
722
723
|
const common = {
|
|
723
724
|
flowId: state.flowId,
|
|
724
725
|
revision: state.revision,
|
|
725
726
|
commitSha: state.commitSha,
|
|
726
727
|
diffDigest: state.diff?.digest || null,
|
|
728
|
+
baseCommitSha: state.diff?.baseCommitSha || null,
|
|
729
|
+
changedFiles: jsonClone(state.diff?.changedFiles || []),
|
|
727
730
|
};
|
|
728
731
|
if (action === DELIVERY_ACTION.RUN_GATES) {
|
|
729
732
|
return {
|
|
733
|
+
...callerPayload,
|
|
730
734
|
...common,
|
|
731
735
|
gateSelection: state.gateSelection,
|
|
732
736
|
requiredGates: state.requiredGates,
|
|
733
|
-
...jsonClone(payload || {}),
|
|
734
737
|
};
|
|
735
738
|
}
|
|
736
739
|
if (action === DELIVERY_ACTION.RUN_PREVIEW) {
|
|
737
740
|
return {
|
|
741
|
+
...callerPayload,
|
|
738
742
|
...common,
|
|
739
743
|
changedFiles: state.diff?.changedFiles || [],
|
|
740
|
-
...jsonClone(payload || {}),
|
|
741
744
|
};
|
|
742
745
|
}
|
|
743
746
|
if (action === DELIVERY_ACTION.APPLY_FIX) {
|
|
744
747
|
return {
|
|
748
|
+
...callerPayload,
|
|
745
749
|
...common,
|
|
746
750
|
round: state.round + 1,
|
|
747
751
|
failures: state.failures,
|
|
748
752
|
review: state.review?.report || null,
|
|
749
|
-
...jsonClone(payload || {}),
|
|
750
753
|
};
|
|
751
754
|
}
|
|
752
755
|
if (action === DELIVERY_ACTION.PUBLISH_EVIDENCE) {
|
|
@@ -754,13 +757,26 @@ function actionPayload(state, action, payload, now) {
|
|
|
754
757
|
now: isoNow(now),
|
|
755
758
|
});
|
|
756
759
|
return {
|
|
760
|
+
...callerPayload,
|
|
757
761
|
...common,
|
|
758
762
|
record,
|
|
759
763
|
readiness: assessDeliveryEvidence(record),
|
|
760
|
-
...jsonClone(payload || {}),
|
|
761
764
|
};
|
|
762
765
|
}
|
|
763
|
-
|
|
766
|
+
if (action === DELIVERY_ACTION.MERGE) {
|
|
767
|
+
return {
|
|
768
|
+
...callerPayload,
|
|
769
|
+
...common,
|
|
770
|
+
pr: jsonClone(state.pr),
|
|
771
|
+
evidence: state.evidence
|
|
772
|
+
? {
|
|
773
|
+
recordDigest: state.evidence.record?.recordDigest || null,
|
|
774
|
+
artifact: jsonClone(state.evidence.artifact),
|
|
775
|
+
}
|
|
776
|
+
: null,
|
|
777
|
+
};
|
|
778
|
+
}
|
|
779
|
+
return { ...callerPayload, ...common };
|
|
764
780
|
}
|
|
765
781
|
|
|
766
782
|
export function requestDeliveryAction(
|
|
@@ -941,6 +957,15 @@ function settleFix(state, result) {
|
|
|
941
957
|
? jsonClone(result.changedFiles)
|
|
942
958
|
: state.diff.changedFiles,
|
|
943
959
|
};
|
|
960
|
+
// A fixer can touch files outside the original analyzer corpus. Until a new
|
|
961
|
+
// complete impact analysis is supplied, reruns conservatively expand to the
|
|
962
|
+
// authoritative full required-gate matrix instead of reusing stale impact
|
|
963
|
+
// selection evidence.
|
|
964
|
+
state.gateSelection = selectImpactedGates({
|
|
965
|
+
changedFiles: state.diff.changedFiles,
|
|
966
|
+
requiredGates: state.requiredGates,
|
|
967
|
+
analysis: {},
|
|
968
|
+
});
|
|
944
969
|
state.gateResults = [];
|
|
945
970
|
state.previewArtifacts = [];
|
|
946
971
|
state.review = null;
|