chainlesschain 0.163.7 → 0.164.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +5 -1
- package/scripts/macos-mcp-launcher-build.mjs +317 -0
- package/scripts/macos-mcp-launcher-postinstall.sh +54 -0
- package/scripts/macos-mcp-launcher-preinstall.sh +61 -0
- package/src/assets/web-panel/assets/{AIOps-axqQfwv8.js → AIOps-D2MEn7fI.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-DV-Ro0By.js → ActionButton-lCW_4Gf0.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-Bt72WEVu.js → Analytics-Bs7i-nsS.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-BtepG55E.js → AppLayout-CK7B6S_j.js} +5 -5
- package/src/assets/web-panel/assets/{Artifacts-B7KaJ7S_.js → Artifacts-C8ILjpyo.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-FNFaUg7A.js → Audit-Bb9cNaWc.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-DFb6J2wQ.js → BackgroundAgents-sC9ooXIf.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-CC7YBhyj.js → Backup-D-DrsplT.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-RkgTNVtj.js → BaseInput-uCNZpwSK.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-hHEmGZy-.js → Chat-CsDK1uE9.js} +6 -6
- package/src/assets/web-panel/assets/{ChatBubbleRenderer-CAP9YhHv.js → ChatBubbleRenderer-OqSDt50w.js} +1 -1
- package/src/assets/web-panel/assets/{Checkbox-z5wXOQP1.js → Checkbox-JhTXM1-K.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-DVaDJnxy.js → Codegen-BbzZLnyD.js} +1 -1
- package/src/assets/web-panel/assets/{Col-CJmaRDR5.js → Col-D4VW4m4j.js} +1 -1
- package/src/assets/web-panel/assets/{Community-DF29_2bI.js → Community-BXrYawxV.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-DtkQkBzn.js → Compact-DCihGy1u.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-xoHDxp7I.js → Compliance-DlyZ-lk8.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-BUm-R7ht.js → Cowork-DvGZrhbO.js} +2 -2
- package/src/assets/web-panel/assets/{Cron-Cgl14ZkB.js → Cron-DUncZi8h.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-BNcbmoqh.js → Crosschain-C_hLuUcm.js} +1 -1
- package/src/assets/web-panel/assets/{DID-Bwja0Zo9.js → DID-b6YSUqxr.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-Bk5XjEdJ.js → Dashboard-uvM15Cfb.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-Ci36Oitq.js → Dropdown-D1-Nd4qY.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer--U04ZN4q.js → EmailListRenderer-8ApvL6Zc.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-B2gNPR2s.js → FamilyGuardDashboard-LYJt8811.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-C4KghYn7.js → Federation-BbI3HGpv.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-QL7x_Q_0.js → FormItemContext-DSoEKuFu.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-F3Ryltwm.js → GenericCardRenderer-B0S9OWd5.js} +1 -1
- package/src/assets/web-panel/assets/{Git-2HassK5k.js → Git-DIs9Zhf3.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-DoBIp7oe.js → Governance-jzZXrxcl.js} +1 -1
- package/src/assets/web-panel/assets/{Inference--W01QhZ-.js → Inference-JUPjf2ZI.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-DmvwqGpT.js → KnowledgeGraph-DxnfJvlP.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-BBJ4yAel.js → Logs-iXiz8BEE.js} +2 -2
- package/src/assets/web-panel/assets/{MarkdownRenderer-BLCZMzhJ.js → MarkdownRenderer-GmB6DOr6.js} +1 -1
- package/src/assets/web-panel/assets/{Marketplace-D5lNngSI.js → Marketplace-Y3Xch312.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-CkEVOMKH.js → McpTools-D7kGGbO7.js} +4 -4
- package/src/assets/web-panel/assets/{Memory-B1Ow1xVE.js → Memory-Do_hVxzh.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-SgYbUfb6.js → MobileBridge-CtrR0Tas.js} +1 -1
- package/src/assets/web-panel/assets/MobileProjects-BL0Czcoj.js +1 -0
- package/src/assets/web-panel/assets/{Mtc-DcTXSSma.js → Mtc-qo5QCTGd.js} +2 -2
- package/src/assets/web-panel/assets/{MtcAudit-Dt3WG4oj.js → MtcAudit-cq5mnjYj.js} +2 -2
- package/src/assets/web-panel/assets/{Multisig-B9B38UZx.js → Multisig-Bq0MAQHw.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-B0S4GGvG.js → NLProgramming-DdWE6Vi2.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-DZ5U58Ng.js → Notes-BxMBFcIp.js} +3 -3
- package/src/assets/web-panel/assets/{NotificationSettings-PjL5ZW34.js → NotificationSettings-RTrAcbUe.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-DrAX2ESt.js → OrderTableRenderer-DJbpGqzT.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-Cv1GYs-c.js → Organization-SQzIPdqC.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-Bbkp_PL3.js → Overflow-02yECh22.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-BD8QUgoZ.js → P2P-BNg4pNCM.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-BO-2PeaB.js → PdhVaultBrowser-BxPJZsD3.js} +3 -3
- package/src/assets/web-panel/assets/{Permissions-D_OPVa02.js → Permissions-CLnDnPAz.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-mh-pEmaB.js → PersonalDataHub-C5m0AjGf.js} +4 -4
- package/src/assets/web-panel/assets/{Pipeline-6JC2EDdb.js → Pipeline-VwOf5Dhv.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-CUshzUAG.js → Privacy-CC0W2hZd.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-Cs2Aalri.js → ProjectInit-Dz893Bob.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-1ak49tcj.js → ProjectSettings-CxQkvl0k.js} +2 -2
- package/src/assets/web-panel/assets/Projects-DDAjkUkT.js +1 -0
- package/src/assets/web-panel/assets/{Providers-CXXxvafH.js → Providers-DeB9IkxK.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-PTcDsF58.js → QrScannerModal-OCeoaswn.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-CDwucrJw.js → QuickAsk-DenotaAj.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-CJlLVRXR.js → Recommend-Cies_jjI.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-DlN-ETsO.js → RemoteSession-Dxzl5n2T.js} +3 -3
- package/src/assets/web-panel/assets/{Reputation-DI23LR6m.js → Reputation-CW0mvxgZ.js} +1 -1
- package/src/assets/web-panel/assets/{Row-Cl7UQMrM.js → Row-SEd32qZU.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-CexHNfh8.js → RssFeed-BSwnJ3Lm.js} +3 -3
- package/src/assets/web-panel/assets/{Search-BneBWvRN.js → Search-xe2m8bkC.js} +1 -1
- package/src/assets/web-panel/assets/{Security-DX7Phgrp.js → Security-Mq2F9Nro.js} +4 -4
- package/src/assets/web-panel/assets/{Services-BWXO8Mte.js → Services-BKGw2V3P.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-DCyOjKPJ.js → Skeleton-DW95-Rxf.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-CXqERsTB.js → Skills-CHgChCv_.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-bhbrbz8E.js → Sla-tKh6k3R7.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-3IPU0HBZ.js → SpeechSettings-D6UL3dA5.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-DBNTQLbM.js → SyncSettings-D0Fw8fVL.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-quP0bkN-.js → Tasks-20x1GB3D.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-BouWmgho.js → Templates-DJ-lts-a.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-qv0D9s7z.js → Tenant-BFdGpbs7.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-BxvbE8BB.js → Terminal-Xpx61vHL.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-D-IeLnJ2.js → TimelineRenderer-C6UIvyZQ.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-CFMKKyVG.js → Tokens-Dellq08f.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-L8as3UuJ.js → Trigger-VKw8d0J-.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-MxmA4VZG.js → Trust-DNftdKT5.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-C0VvJYRi.js → UkeySign-DX9VAKJI.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-Bf5QZj8N.js → VideoEditing-B2h3jO8q.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-BIJ9riRz.js → Wallet-CjGkof7f.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-B8p9Mhkw.js → WebAuthn-2Zfcu55P.js} +4 -4
- package/src/assets/web-panel/assets/{WorkflowEditor-BVsuaPen.js → WorkflowEditor-B9eZ8UxZ.js} +1 -1
- package/src/assets/web-panel/assets/{chat-BfkjoKpV.js → chat-CQNfD-YO.js} +1 -1
- package/src/assets/web-panel/assets/{colors-DeAlsWK8.js → colors-D4usyFT2.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-Cs97bz5j.js → compact-item-s4TpjvjX.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-BqbG60LH.js → createContext-BRCSvYxj.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-DKJjSWRn.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-i_RY0b1X.js → hasIn-AdkUbkV-.js} +1 -1
- package/src/assets/web-panel/assets/{index-BOVkf1K3.js → index--00U6vXZ.js} +1 -1
- package/src/assets/web-panel/assets/{index-B-3tEpTc.js → index-B2V-eKfK.js} +1 -1
- package/src/assets/web-panel/assets/{index-D2B4VPyP.js → index-B4JJCfQ2.js} +1 -1
- package/src/assets/web-panel/assets/{index-BkBi5TmC.js → index-BIoG5yYf.js} +1 -1
- package/src/assets/web-panel/assets/{index-79V_zv1s.js → index-BMcimU-2.js} +1 -1
- package/src/assets/web-panel/assets/{index-U4f5izHz.js → index-BPhkFZ1I.js} +1 -1
- package/src/assets/web-panel/assets/{index-DiSkx4UB.js → index-BQ3DXBtD.js} +3 -3
- package/src/assets/web-panel/assets/{index-dIHr4B_u.js → index-Bad4VNvz.js} +1 -1
- package/src/assets/web-panel/assets/{index-CIG8fQ2_.js → index-BgiXR_-_.js} +1 -1
- package/src/assets/web-panel/assets/{index-DqBgBpgp.js → index-BtobShro.js} +1 -1
- package/src/assets/web-panel/assets/{index-ZxO_-E8a.js → index-Bw2MEnUk.js} +1 -1
- package/src/assets/web-panel/assets/{index-DUUrv141.js → index-C1mJtE6q.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bm7lLR4c.js → index-C484EJiS.js} +1 -1
- package/src/assets/web-panel/assets/{index-COdGA-8n.js → index-C5KAQFPQ.js} +1 -1
- package/src/assets/web-panel/assets/index-C61cnl3K.js +1 -0
- package/src/assets/web-panel/assets/{index-CED2PL_y.js → index-C7Y8Aluc.js} +1 -1
- package/src/assets/web-panel/assets/{index-YXgLng0K.js → index-CCsM_Ybx.js} +1 -1
- package/src/assets/web-panel/assets/{index-0-agYlWL.js → index-CJCFe2Qf.js} +1 -1
- package/src/assets/web-panel/assets/{index-B5UkyA3c.js → index-CJVEOa4i.js} +1 -1
- package/src/assets/web-panel/assets/{index-B1CbOH1i.js → index-CJdQrZth.js} +1 -1
- package/src/assets/web-panel/assets/{index-s1opAL-M.js → index-CKC1t3Ic.js} +1 -1
- package/src/assets/web-panel/assets/{index-yObj1O4n.js → index-CQhAVU5t.js} +1 -1
- package/src/assets/web-panel/assets/{index-CgsqdnRV.js → index-CYdoQsa1.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dk7-v4hP.js → index-Cduu2Hhr.js} +1 -1
- package/src/assets/web-panel/assets/{index-B-JVTrpr.js → index-CkwiSLhU.js} +1 -1
- package/src/assets/web-panel/assets/{index-CeWoNHau.js → index-Cvyt-zhm.js} +1 -1
- package/src/assets/web-panel/assets/{index-CE2VtTlp.js → index-D2GjI2oe.js} +1 -1
- package/src/assets/web-panel/assets/index-D4XFHxBr.js +1 -0
- package/src/assets/web-panel/assets/{index-DmbfhJUP.js → index-DARsAyUp.js} +1 -1
- package/src/assets/web-panel/assets/{index-BESLFt4q.js → index-DVKfQ0Ux.js} +1 -1
- package/src/assets/web-panel/assets/{index-PT_5sBMA.js → index-DZT36ZYq.js} +1 -1
- package/src/assets/web-panel/assets/{index-gyFpvL7l.js → index-D_XBHopw.js} +1 -1
- package/src/assets/web-panel/assets/{index-BYUVuwKt.js → index-DdCB70SS.js} +1 -1
- package/src/assets/web-panel/assets/{index-BcUXAB2s.js → index-DzRjHxEv.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dk2qouAz.js → index-MMN9V6JF.js} +1 -1
- package/src/assets/web-panel/assets/{index-D9evtvg2.js → index-RfMr79MW.js} +1 -1
- package/src/assets/web-panel/assets/{index-BuLQobzW.js → index-_IRVsV9X.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cf3WCLmy.js → index-nXyk8GZ9.js} +1 -1
- package/src/assets/web-panel/assets/{index-CG3PRyAL.js → index-s_buFMEG.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-C9h9yKL3.js → initDefaultProps-Blmpk7HL.js} +1 -1
- package/src/assets/web-panel/assets/{motion-BvmLsPdu.js → motion-DPBJMv1n.js} +1 -1
- package/src/assets/web-panel/assets/{move-CoL4ekU1.js → move-ButdzCM7.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-C4pMy6xV.js → mtc-parser-cyRC_QCe.js} +1 -1
- package/src/assets/web-panel/assets/{omit-DPuJfNxx.js → omit-1epSV7hz.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-D0KEeaK2.js → pickAttrs-DuPY8xJs.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-BpkyINxt.js → placementArrow-6XZqarhe.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-DQI_wOq8.js → responsiveObserve-B40pXBWM.js} +1 -1
- package/src/assets/web-panel/assets/{slide-DYfdDiRg.js → slide-jbZ9Wu4n.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-B5dtvb0D.js → statusUtils-BKQQcVy4.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-CF310mSj.js → styleChecker-NiKfWjUT.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-D1Qp4BLp.js → useFlexGapSupport-bQUCvPeb.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-C7_iyvJK.js → useFs-CUGji7ph.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-DZUt_fIm.js → usePersonalDataHub-4veyN2N2.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-D3dsi0lZ.js → vnode-1-nLug-Z.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-WdbOlvdQ.js → zoom-dhCeRDMo.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/command-help-index.json +6 -6
- package/src/commands/automation.js +103 -1
- package/src/commands/cowork.js +174 -19
- package/src/commands/permissions.js +240 -16
- package/src/commands/plugin.js +1293 -56
- package/src/commands/session-location.js +276 -0
- package/src/commands/session.js +2 -0
- package/src/commands/team-merge-review.js +937 -0
- package/src/commands/team.js +2 -0
- package/src/data/changelog.json +27 -1
- package/src/gateways/ws/action-protocol.js +35 -10
- package/src/gateways/ws/remote-session-protocol.js +24 -1
- package/src/gateways/ws/ws-agent-handler.js +12 -0
- package/src/gateways/ws/ws-server.js +48 -12
- package/src/harness/jsonl-session-store.js +341 -24
- package/src/harness/mcp-client.js +8 -1
- package/src/harness/remote-session-audit.js +1 -0
- package/src/harness/remote-session-crypto.js +210 -2
- package/src/harness/remote-session-registry.js +159 -6
- package/src/harness/session-list-index.js +233 -14
- package/src/lib/agent-authority.js +6 -0
- package/src/lib/agent-schedule-store.js +139 -28
- package/src/lib/agent-team/team-merge-review-store.js +765 -0
- package/src/lib/agent-team/team-merge-review-transaction.js +1223 -0
- package/src/lib/agent-team/team-merge-review.js +1847 -0
- package/src/lib/automation-center-incidents.js +314 -0
- package/src/lib/automation-center-runtime.js +448 -0
- package/src/lib/automation-center.js +182 -38
- package/src/lib/automation-engine.js +41 -0
- package/src/lib/automation-execution-authority.js +241 -12
- package/src/lib/automation-execution-incident.js +737 -0
- package/src/lib/background-agent-keeper-client.js +248 -0
- package/src/lib/background-agent-keeper-protocol.js +147 -0
- package/src/lib/background-agent-supervisor.js +520 -40
- package/src/lib/background-interaction-resolver.js +12 -0
- package/src/lib/background-turn-bootstrap-protocol.js +126 -0
- package/src/lib/cowork-cron.js +85 -14
- package/src/lib/cowork-workflow.js +336 -16
- package/src/lib/dynamic-workflow-facade.js +648 -0
- package/src/lib/execution-location-contract.js +551 -0
- package/src/lib/execution-location-runtime.js +130 -0
- package/src/lib/ide-context.js +94 -6
- package/src/lib/mcp-stdio-package-materialization.js +166 -14
- package/src/lib/packer/pkg-config-generator.js +2 -0
- package/src/lib/permission-authority.js +77 -0
- package/src/lib/permission-side-effect-center.js +495 -0
- package/src/lib/plugin-runtime/install.js +514 -13
- package/src/lib/plugin-runtime/marketplace-artifact-readback.js +900 -0
- package/src/lib/plugin-runtime/marketplace-catalog.js +1181 -0
- package/src/lib/plugin-runtime/marketplace-impact.js +408 -0
- package/src/lib/plugin-runtime/marketplace-remote-artifacts.js +1567 -0
- package/src/lib/plugin-security.js +60 -3
- package/src/lib/process-execution-broker/index.js +1095 -57
- package/src/lib/process-execution-broker/linux-bwrap-descriptor-launch.js +375 -0
- package/src/lib/process-execution-broker/linux-generic-bwrap-runtime.js +90 -16
- package/src/lib/process-execution-broker/linux-generic-bwrap.js +159 -18
- package/src/lib/process-execution-broker/macos-mcp-launcher-contract.js +278 -0
- package/src/lib/process-execution-broker/macos-mcp-launcher-protocol.json +23 -0
- package/src/lib/process-execution-broker/macos-mcp-launcher.c +1497 -0
- package/src/lib/process-execution-broker/mcp-fd-entry-bootstrap.js +37 -0
- package/src/lib/process-execution-broker/platform-sandbox.js +2330 -279
- package/src/lib/process-execution-broker/windows-sandbox-helper.dll +0 -0
- package/src/lib/process-execution-broker/windows-sandbox-helper.exe +0 -0
- package/src/lib/process-execution-broker/windows-sandbox.cs +50 -4
- package/src/lib/public-ide-capability-manifest.js +3 -0
- package/src/lib/remote-approval-bridge.js +123 -17
- package/src/lib/remote-membership-authority.js +632 -0
- package/src/lib/remote-membership-coordinator.js +2409 -0
- package/src/lib/remote-membership-host-store.js +1750 -0
- package/src/lib/scheduler-kernel/agenda-adapter.js +17 -7
- package/src/lib/scheduler-kernel/automation-adapter.js +105 -11
- package/src/lib/scheduler-kernel/automation-event-adapter.js +87 -11
- package/src/lib/scheduler-kernel/contract.js +91 -0
- package/src/lib/scheduler-kernel/cowork-cron-adapter.js +12 -1
- package/src/lib/scheduler-kernel/loop-adapter.js +7 -1
- package/src/lib/scheduler-kernel/routine-adapter.js +7 -1
- package/src/lib/scheduler-kernel/runtime-control-capabilities.js +31 -0
- package/src/lib/scheduler-kernel/runtime.js +176 -3
- package/src/lib/scheduler-kernel/store.js +1253 -45
- package/src/lib/scoped-permission-store.js +369 -0
- package/src/lib/session-anti-rollback-anchor.js +262 -5
- package/src/lib/sub-agent-context.js +4 -0
- package/src/lib/workflow-definition-contract.js +149 -0
- package/src/repl/agent-repl.js +41 -7
- package/src/repl/chat-repl.js +2 -0
- package/src/repl/clipboard-image.js +735 -16
- package/src/repl/ide-status.js +1 -1
- package/src/repl/prompt-interactions.js +59 -6
- package/src/runtime/agent-core.js +93 -3
- package/src/runtime/headless-runner.js +30 -25
- package/src/runtime/headless-stream.js +32 -25
- package/src/runtime/mcp-config.js +81 -10
- package/src/workers/background-agent-keeper.js +498 -0
- package/src/workers/background-agent-worker.js +358 -13
- package/src/workers/background-turn-bootstrap.js +143 -0
- package/src/assets/web-panel/assets/MobileProjects-BWdOvQAj.js +0 -1
- package/src/assets/web-panel/assets/Projects-BV4oApsm.js +0 -1
- package/src/assets/web-panel/assets/devWarning-DPty0mGN.js +0 -1
- package/src/assets/web-panel/assets/index-Bt7g0Vq_.js +0 -1
- package/src/assets/web-panel/assets/index-ChVT0p9u.js +0 -1
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
normalizeJson,
|
|
16
16
|
} from "./contract.js";
|
|
17
17
|
import { SchedulerRuntime } from "./runtime.js";
|
|
18
|
+
import { CHECKPOINT_V1_RUNTIME_CONTROL } from "./runtime-control-capabilities.js";
|
|
18
19
|
import { schedulerMigrationSourceDigest } from "./store.js";
|
|
19
20
|
import {
|
|
20
21
|
bindSchedulerAuthorityPolicy,
|
|
@@ -677,6 +678,7 @@ export function createAgendaSchedulerAdapter({
|
|
|
677
678
|
}
|
|
678
679
|
return {
|
|
679
680
|
kind: AGENDA_SCHEDULER_KIND,
|
|
681
|
+
runtimeControl: CHECKPOINT_V1_RUNTIME_CONTROL,
|
|
680
682
|
async adjudicate({ occurrence, adjudication }) {
|
|
681
683
|
const payload = occurrence.payload;
|
|
682
684
|
const expected = agendaEntrySnapshot(payload?.entry);
|
|
@@ -711,7 +713,7 @@ export function createAgendaSchedulerAdapter({
|
|
|
711
713
|
}
|
|
712
714
|
return { continue: true };
|
|
713
715
|
},
|
|
714
|
-
async execute({ occurrence }) {
|
|
716
|
+
async execute({ occurrence, checkpoint }) {
|
|
715
717
|
const payload = occurrence.payload;
|
|
716
718
|
const expected = agendaEntrySnapshot(payload?.entry);
|
|
717
719
|
const expectedDigest = agendaEntrySnapshotDigest(expected);
|
|
@@ -757,6 +759,17 @@ export function createAgendaSchedulerAdapter({
|
|
|
757
759
|
`Agenda entry changed after occurrence enqueue: ${expected.id}`,
|
|
758
760
|
);
|
|
759
761
|
}
|
|
762
|
+
if (expected.kind === "monitor" && typeof runMonitor !== "function") {
|
|
763
|
+
throw agendaError(
|
|
764
|
+
"AGENDA_SCHEDULER_MONITOR_RUNNER_REQUIRED",
|
|
765
|
+
"Agenda scheduler monitor execution requires a monitor runner",
|
|
766
|
+
);
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
checkpoint({
|
|
770
|
+
entryId: expected.id,
|
|
771
|
+
phase: "before_execution_bind",
|
|
772
|
+
});
|
|
760
773
|
|
|
761
774
|
current = agendaStore.bindSchedulerExecution(expected.id, {
|
|
762
775
|
occurrenceId: occurrence.id,
|
|
@@ -784,12 +797,6 @@ export function createAgendaSchedulerAdapter({
|
|
|
784
797
|
let action = null;
|
|
785
798
|
try {
|
|
786
799
|
if (expected.kind === "monitor") {
|
|
787
|
-
if (typeof runMonitor !== "function") {
|
|
788
|
-
throw agendaError(
|
|
789
|
-
"AGENDA_SCHEDULER_MONITOR_RUNNER_REQUIRED",
|
|
790
|
-
"Agenda scheduler monitor execution requires a monitor runner",
|
|
791
|
-
);
|
|
792
|
-
}
|
|
793
800
|
observation = normalizeMonitorObservation(
|
|
794
801
|
expected,
|
|
795
802
|
await runMonitor({
|
|
@@ -944,6 +951,9 @@ export function createAgendaSchedulerAdapter({
|
|
|
944
951
|
);
|
|
945
952
|
}
|
|
946
953
|
},
|
|
954
|
+
async resume(context) {
|
|
955
|
+
return this.execute(context);
|
|
956
|
+
},
|
|
947
957
|
classifyError(error) {
|
|
948
958
|
return {
|
|
949
959
|
retryable: error?.retryable === true,
|
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
import { createHash, randomUUID } from "node:crypto";
|
|
2
2
|
import { nextCronTime } from "../agent-schedule-store.js";
|
|
3
3
|
import {
|
|
4
|
+
assertAutomationRuntimeBoundary,
|
|
4
5
|
automationExecutionAuthorityDigest,
|
|
5
6
|
automationExecutionAuthoritySnapshot,
|
|
6
7
|
automationSchedulerAuthority,
|
|
8
|
+
classifyAutomationBoundaryError,
|
|
7
9
|
normalizeAutomationExecutionAuthoritySnapshot,
|
|
8
10
|
reserveAutomationExecutionAuthority,
|
|
9
11
|
} from "../automation-execution-authority.js";
|
|
12
|
+
import {
|
|
13
|
+
resolveAutomationExecutionIncidentsForSucceededRun,
|
|
14
|
+
upsertAutomationExecutionIncident,
|
|
15
|
+
} from "../automation-execution-incident.js";
|
|
10
16
|
import {
|
|
11
17
|
EXECUTION_STATUS,
|
|
12
18
|
FLOW_STATUS,
|
|
@@ -33,6 +39,7 @@ import {
|
|
|
33
39
|
normalizeJson,
|
|
34
40
|
} from "./contract.js";
|
|
35
41
|
import { SchedulerRuntime } from "./runtime.js";
|
|
42
|
+
import { CHECKPOINT_V1_RUNTIME_CONTROL } from "./runtime-control-capabilities.js";
|
|
36
43
|
import {
|
|
37
44
|
schedulerJobDefinitionDigest,
|
|
38
45
|
schedulerMigrationSourceDigest,
|
|
@@ -178,6 +185,54 @@ export function automationSchedulerExecutionId(occurrenceId) {
|
|
|
178
185
|
return `exec-scheduler-${digest}`;
|
|
179
186
|
}
|
|
180
187
|
|
|
188
|
+
function automationBoundaryIncidentEvidence(error, snapshot) {
|
|
189
|
+
const classified = classifyAutomationBoundaryError(error);
|
|
190
|
+
if (!classified) return null;
|
|
191
|
+
const deniedPermissions = Array.isArray(error?.details?.permissions)
|
|
192
|
+
? error.details.permissions.map(String).slice(0, 32)
|
|
193
|
+
: [];
|
|
194
|
+
return {
|
|
195
|
+
classified,
|
|
196
|
+
boundary: {
|
|
197
|
+
...(deniedPermissions.length > 0 ? { deniedPermissions } : {}),
|
|
198
|
+
...(snapshot?.budget?.revision === undefined
|
|
199
|
+
? {}
|
|
200
|
+
: { budgetRevision: snapshot.budget.revision }),
|
|
201
|
+
...(Array.isArray(snapshot?.connectors)
|
|
202
|
+
? { connectors: snapshot.connectors }
|
|
203
|
+
: {}),
|
|
204
|
+
},
|
|
205
|
+
details: { reasonCode: classified.code, retryable: false },
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
function persistAutomationSchedulerIncident(
|
|
210
|
+
db,
|
|
211
|
+
occurrence,
|
|
212
|
+
flow,
|
|
213
|
+
snapshot,
|
|
214
|
+
error,
|
|
215
|
+
now,
|
|
216
|
+
) {
|
|
217
|
+
const evidence = automationBoundaryIncidentEvidence(error, snapshot);
|
|
218
|
+
if (!evidence) return null;
|
|
219
|
+
return upsertAutomationExecutionIncident(
|
|
220
|
+
db,
|
|
221
|
+
{
|
|
222
|
+
runId: automationSchedulerExecutionId(occurrence.id),
|
|
223
|
+
flowId: flow.id,
|
|
224
|
+
occurrenceId: occurrence.id,
|
|
225
|
+
triggerType: TRIGGER_TYPE.SCHEDULE,
|
|
226
|
+
category: evidence.classified.category,
|
|
227
|
+
code: evidence.classified.code,
|
|
228
|
+
authorityDigest: automationExecutionAuthorityDigest(snapshot, flow),
|
|
229
|
+
boundary: evidence.boundary,
|
|
230
|
+
details: evidence.details,
|
|
231
|
+
},
|
|
232
|
+
{ now },
|
|
233
|
+
);
|
|
234
|
+
}
|
|
235
|
+
|
|
181
236
|
export function buildAutomationSchedulerJob(flow, executionAuthority) {
|
|
182
237
|
const snapshot = automationFlowSnapshot(flow);
|
|
183
238
|
const normalizedExecutionAuthority =
|
|
@@ -702,7 +757,7 @@ export function authorizeAutomationOccurrence({ job, occurrence }) {
|
|
|
702
757
|
}
|
|
703
758
|
}
|
|
704
759
|
|
|
705
|
-
function existingExecutionResult(db, occurrence, expected) {
|
|
760
|
+
function existingExecutionResult(db, occurrence, expected, now) {
|
|
706
761
|
const executionId = automationSchedulerExecutionId(occurrence.id);
|
|
707
762
|
const execution = getExecution(db, executionId);
|
|
708
763
|
if (!execution) return null;
|
|
@@ -729,6 +784,9 @@ function existingExecutionResult(db, occurrence, expected) {
|
|
|
729
784
|
{ executionId: execution.id, status: execution.status },
|
|
730
785
|
);
|
|
731
786
|
}
|
|
787
|
+
resolveAutomationExecutionIncidentsForSucceededRun(db, execution.id, {
|
|
788
|
+
now,
|
|
789
|
+
});
|
|
732
790
|
return execution;
|
|
733
791
|
}
|
|
734
792
|
|
|
@@ -741,6 +799,7 @@ export function createAutomationSchedulerAdapter({ db, now = Date.now } = {}) {
|
|
|
741
799
|
}
|
|
742
800
|
return {
|
|
743
801
|
kind: AUTOMATION_SCHEDULER_KIND,
|
|
802
|
+
runtimeControl: CHECKPOINT_V1_RUNTIME_CONTROL,
|
|
744
803
|
async adjudicate({ occurrence, adjudication }) {
|
|
745
804
|
const payload = occurrence?.payload;
|
|
746
805
|
const expected = automationFlowSnapshot(payload?.flow);
|
|
@@ -772,7 +831,7 @@ export function createAutomationSchedulerAdapter({ db, now = Date.now } = {}) {
|
|
|
772
831
|
}
|
|
773
832
|
return { continue: true };
|
|
774
833
|
},
|
|
775
|
-
async execute({ occurrence }) {
|
|
834
|
+
async execute({ occurrence, checkpoint }) {
|
|
776
835
|
const payload = occurrence?.payload;
|
|
777
836
|
const expected = automationFlowSnapshot(payload?.flow);
|
|
778
837
|
const expectedDigest = automationFlowSnapshotDigest(expected);
|
|
@@ -789,7 +848,7 @@ export function createAutomationSchedulerAdapter({ db, now = Date.now } = {}) {
|
|
|
789
848
|
// A prior process may have committed the flow result and died before the
|
|
790
849
|
// scheduler settlement. Durable success is authoritative even if the flow
|
|
791
850
|
// was subsequently paused or edited.
|
|
792
|
-
const recovered = existingExecutionResult(db, occurrence, expected);
|
|
851
|
+
const recovered = existingExecutionResult(db, occurrence, expected, now);
|
|
793
852
|
if (recovered) return recovered;
|
|
794
853
|
|
|
795
854
|
const current = getFlow(db, expected.id);
|
|
@@ -813,14 +872,31 @@ export function createAutomationSchedulerAdapter({ db, now = Date.now } = {}) {
|
|
|
813
872
|
);
|
|
814
873
|
}
|
|
815
874
|
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
875
|
+
checkpoint({
|
|
876
|
+
executionId: automationSchedulerExecutionId(occurrence.id),
|
|
877
|
+
phase: "before_execution_reservation",
|
|
878
|
+
});
|
|
879
|
+
|
|
880
|
+
try {
|
|
881
|
+
reserveAutomationExecutionAuthority(
|
|
882
|
+
db,
|
|
883
|
+
effectiveCurrent,
|
|
884
|
+
occurrence.id,
|
|
885
|
+
payload.executionAuthority,
|
|
886
|
+
payload.executionAuthorityDigest,
|
|
887
|
+
{ now },
|
|
888
|
+
);
|
|
889
|
+
} catch (error) {
|
|
890
|
+
persistAutomationSchedulerIncident(
|
|
891
|
+
db,
|
|
892
|
+
occurrence,
|
|
893
|
+
effectiveCurrent,
|
|
894
|
+
payload.executionAuthority,
|
|
895
|
+
error,
|
|
896
|
+
now,
|
|
897
|
+
);
|
|
898
|
+
throw error;
|
|
899
|
+
}
|
|
824
900
|
|
|
825
901
|
let execution;
|
|
826
902
|
try {
|
|
@@ -828,8 +904,20 @@ export function createAutomationSchedulerAdapter({ db, now = Date.now } = {}) {
|
|
|
828
904
|
inputData: {},
|
|
829
905
|
triggerType: TRIGGER_TYPE.SCHEDULE,
|
|
830
906
|
executionId: automationSchedulerExecutionId(occurrence.id),
|
|
907
|
+
executionAuthority: payload.executionAuthority,
|
|
908
|
+
assertRuntimeBoundary: assertAutomationRuntimeBoundary,
|
|
831
909
|
});
|
|
832
910
|
} catch (cause) {
|
|
911
|
+
if (classifyAutomationBoundaryError(cause)) {
|
|
912
|
+
persistAutomationSchedulerIncident(
|
|
913
|
+
db,
|
|
914
|
+
occurrence,
|
|
915
|
+
effectiveCurrent,
|
|
916
|
+
payload.executionAuthority,
|
|
917
|
+
cause,
|
|
918
|
+
now,
|
|
919
|
+
);
|
|
920
|
+
}
|
|
833
921
|
if (cause?.code === "AUTOMATION_EXECUTION_OUTCOME_UNKNOWN") {
|
|
834
922
|
throw automationError(
|
|
835
923
|
"AUTOMATION_SCHEDULER_OUTCOME_UNKNOWN",
|
|
@@ -847,8 +935,14 @@ export function createAutomationSchedulerAdapter({ db, now = Date.now } = {}) {
|
|
|
847
935
|
{ executionId: execution.id, error: execution.error },
|
|
848
936
|
);
|
|
849
937
|
}
|
|
938
|
+
resolveAutomationExecutionIncidentsForSucceededRun(db, execution.id, {
|
|
939
|
+
now,
|
|
940
|
+
});
|
|
850
941
|
return execution;
|
|
851
942
|
},
|
|
943
|
+
async resume(context) {
|
|
944
|
+
return this.execute(context);
|
|
945
|
+
},
|
|
852
946
|
classifyError() {
|
|
853
947
|
return { retryable: false };
|
|
854
948
|
},
|
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
2
|
import { Buffer } from "node:buffer";
|
|
3
3
|
import {
|
|
4
|
+
assertAutomationRuntimeBoundary,
|
|
4
5
|
automationExecutionAuthorityDigest,
|
|
5
6
|
automationExecutionAuthoritySnapshot,
|
|
6
7
|
automationSchedulerAuthority,
|
|
8
|
+
classifyAutomationBoundaryError,
|
|
7
9
|
normalizeAutomationExecutionAuthoritySnapshot,
|
|
8
10
|
reserveAutomationExecutionAuthority,
|
|
9
11
|
} from "../automation-execution-authority.js";
|
|
12
|
+
import {
|
|
13
|
+
resolveAutomationExecutionIncidentsForSucceededRun,
|
|
14
|
+
upsertAutomationExecutionIncident,
|
|
15
|
+
} from "../automation-execution-incident.js";
|
|
10
16
|
import {
|
|
11
17
|
EXECUTION_STATUS,
|
|
12
18
|
FLOW_STATUS,
|
|
@@ -26,6 +32,7 @@ import {
|
|
|
26
32
|
normalizeJson,
|
|
27
33
|
} from "./contract.js";
|
|
28
34
|
import { SchedulerRuntime } from "./runtime.js";
|
|
35
|
+
import { CHECKPOINT_V1_RUNTIME_CONTROL } from "./runtime-control-capabilities.js";
|
|
29
36
|
|
|
30
37
|
export const AUTOMATION_EVENT_KIND = "automation-event";
|
|
31
38
|
export const AUTOMATION_EVENT_CAPABILITY = "automation.execute";
|
|
@@ -294,6 +301,39 @@ export function automationEventExecutionId(occurrenceId) {
|
|
|
294
301
|
.digest("hex")}`;
|
|
295
302
|
}
|
|
296
303
|
|
|
304
|
+
function persistAutomationEventIncident(db, occurrence, flow, error, now) {
|
|
305
|
+
const classified = classifyAutomationBoundaryError(error);
|
|
306
|
+
if (!classified) return null;
|
|
307
|
+
const snapshot = occurrence.payload.executionAuthority;
|
|
308
|
+
const deniedPermissions = Array.isArray(error?.details?.permissions)
|
|
309
|
+
? error.details.permissions.map(String).slice(0, 32)
|
|
310
|
+
: [];
|
|
311
|
+
return upsertAutomationExecutionIncident(
|
|
312
|
+
db,
|
|
313
|
+
{
|
|
314
|
+
runId: automationEventExecutionId(occurrence.id),
|
|
315
|
+
flowId: flow.id,
|
|
316
|
+
occurrenceId: occurrence.id,
|
|
317
|
+
triggerType: TRIGGER_TYPE.EVENT,
|
|
318
|
+
triggerId: occurrence.payload?.trigger?.id || null,
|
|
319
|
+
category: classified.category,
|
|
320
|
+
code: classified.code,
|
|
321
|
+
authorityDigest: automationExecutionAuthorityDigest(snapshot, flow),
|
|
322
|
+
boundary: {
|
|
323
|
+
...(deniedPermissions.length > 0 ? { deniedPermissions } : {}),
|
|
324
|
+
...(snapshot?.budget?.revision === undefined
|
|
325
|
+
? {}
|
|
326
|
+
: { budgetRevision: snapshot.budget.revision }),
|
|
327
|
+
...(Array.isArray(snapshot?.connectors)
|
|
328
|
+
? { connectors: snapshot.connectors }
|
|
329
|
+
: {}),
|
|
330
|
+
},
|
|
331
|
+
details: { reasonCode: classified.code, retryable: false },
|
|
332
|
+
},
|
|
333
|
+
{ now },
|
|
334
|
+
);
|
|
335
|
+
}
|
|
336
|
+
|
|
297
337
|
export function automationEventTriggerKey(event) {
|
|
298
338
|
const normalized = normalizeAutomationChannelEvent(event);
|
|
299
339
|
return `channel:${createHash("sha256")
|
|
@@ -514,7 +554,7 @@ export function authorizeAutomationEventOccurrence({ job, occurrence }) {
|
|
|
514
554
|
}
|
|
515
555
|
}
|
|
516
556
|
|
|
517
|
-
function existingExecutionResult(db, occurrence, expectedFlow) {
|
|
557
|
+
function existingExecutionResult(db, occurrence, expectedFlow, now) {
|
|
518
558
|
const executionId = automationEventExecutionId(occurrence.id);
|
|
519
559
|
const execution = getExecution(db, executionId);
|
|
520
560
|
if (!execution) return null;
|
|
@@ -541,6 +581,9 @@ function existingExecutionResult(db, occurrence, expectedFlow) {
|
|
|
541
581
|
{ executionId: execution.id, status: execution.status },
|
|
542
582
|
);
|
|
543
583
|
}
|
|
584
|
+
resolveAutomationExecutionIncidentsForSucceededRun(db, execution.id, {
|
|
585
|
+
now,
|
|
586
|
+
});
|
|
544
587
|
return execution;
|
|
545
588
|
}
|
|
546
589
|
|
|
@@ -553,6 +596,7 @@ export function createAutomationEventAdapter({ db, now = Date.now } = {}) {
|
|
|
553
596
|
}
|
|
554
597
|
return {
|
|
555
598
|
kind: AUTOMATION_EVENT_KIND,
|
|
599
|
+
runtimeControl: CHECKPOINT_V1_RUNTIME_CONTROL,
|
|
556
600
|
async adjudicate({ occurrence, adjudication }) {
|
|
557
601
|
const payload = occurrence?.payload;
|
|
558
602
|
const expectedFlow = automationEventFlowSnapshot(payload?.flow);
|
|
@@ -588,7 +632,7 @@ export function createAutomationEventAdapter({ db, now = Date.now } = {}) {
|
|
|
588
632
|
}
|
|
589
633
|
return { continue: true };
|
|
590
634
|
},
|
|
591
|
-
async execute({ occurrence }) {
|
|
635
|
+
async execute({ occurrence, checkpoint }) {
|
|
592
636
|
const payload = occurrence?.payload;
|
|
593
637
|
const expectedFlow = automationEventFlowSnapshot(payload?.flow);
|
|
594
638
|
const expectedTrigger = automationEventTriggerSnapshot(payload?.trigger);
|
|
@@ -605,7 +649,12 @@ export function createAutomationEventAdapter({ db, now = Date.now } = {}) {
|
|
|
605
649
|
);
|
|
606
650
|
}
|
|
607
651
|
|
|
608
|
-
const recovered = existingExecutionResult(
|
|
652
|
+
const recovered = existingExecutionResult(
|
|
653
|
+
db,
|
|
654
|
+
occurrence,
|
|
655
|
+
expectedFlow,
|
|
656
|
+
now,
|
|
657
|
+
);
|
|
609
658
|
if (recovered) return recovered;
|
|
610
659
|
|
|
611
660
|
const currentFlow = getFlow(db, expectedFlow.id);
|
|
@@ -630,14 +679,24 @@ export function createAutomationEventAdapter({ db, now = Date.now } = {}) {
|
|
|
630
679
|
);
|
|
631
680
|
}
|
|
632
681
|
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
682
|
+
checkpoint({
|
|
683
|
+
executionId: automationEventExecutionId(occurrence.id),
|
|
684
|
+
phase: "before_execution_reservation",
|
|
685
|
+
});
|
|
686
|
+
|
|
687
|
+
try {
|
|
688
|
+
reserveAutomationExecutionAuthority(
|
|
689
|
+
db,
|
|
690
|
+
currentFlow,
|
|
691
|
+
occurrence.id,
|
|
692
|
+
payload.executionAuthority,
|
|
693
|
+
payload.executionAuthorityDigest,
|
|
694
|
+
{ now },
|
|
695
|
+
);
|
|
696
|
+
} catch (error) {
|
|
697
|
+
persistAutomationEventIncident(db, occurrence, currentFlow, error, now);
|
|
698
|
+
throw error;
|
|
699
|
+
}
|
|
641
700
|
|
|
642
701
|
let execution;
|
|
643
702
|
try {
|
|
@@ -645,8 +704,19 @@ export function createAutomationEventAdapter({ db, now = Date.now } = {}) {
|
|
|
645
704
|
inputData: { event: expectedEvent },
|
|
646
705
|
triggerType: TRIGGER_TYPE.EVENT,
|
|
647
706
|
executionId: automationEventExecutionId(occurrence.id),
|
|
707
|
+
executionAuthority: payload.executionAuthority,
|
|
708
|
+
assertRuntimeBoundary: assertAutomationRuntimeBoundary,
|
|
648
709
|
});
|
|
649
710
|
} catch (cause) {
|
|
711
|
+
if (classifyAutomationBoundaryError(cause)) {
|
|
712
|
+
persistAutomationEventIncident(
|
|
713
|
+
db,
|
|
714
|
+
occurrence,
|
|
715
|
+
currentFlow,
|
|
716
|
+
cause,
|
|
717
|
+
now,
|
|
718
|
+
);
|
|
719
|
+
}
|
|
650
720
|
if (cause?.code === "AUTOMATION_EXECUTION_OUTCOME_UNKNOWN") {
|
|
651
721
|
throw eventError(
|
|
652
722
|
"AUTOMATION_EVENT_OUTCOME_UNKNOWN",
|
|
@@ -664,8 +734,14 @@ export function createAutomationEventAdapter({ db, now = Date.now } = {}) {
|
|
|
664
734
|
{ executionId: execution.id, error: execution.error },
|
|
665
735
|
);
|
|
666
736
|
}
|
|
737
|
+
resolveAutomationExecutionIncidentsForSucceededRun(db, execution.id, {
|
|
738
|
+
now,
|
|
739
|
+
});
|
|
667
740
|
return execution;
|
|
668
741
|
},
|
|
742
|
+
async resume(context) {
|
|
743
|
+
return this.execute(context);
|
|
744
|
+
},
|
|
669
745
|
classifyError() {
|
|
670
746
|
return { retryable: false };
|
|
671
747
|
},
|
|
@@ -3,6 +3,26 @@ import { Buffer } from "node:buffer";
|
|
|
3
3
|
|
|
4
4
|
export const SCHEDULER_SCHEMA_VERSION = 1;
|
|
5
5
|
export const AUTHORITY_ENVELOPE_VERSION = 1;
|
|
6
|
+
export const RUNTIME_CONTROL_SCHEMA_VERSION = 1;
|
|
7
|
+
|
|
8
|
+
export const RUNTIME_PAUSE_RESUME = Object.freeze({
|
|
9
|
+
NONE: "none",
|
|
10
|
+
CHECKPOINT_V1: "checkpoint_v1",
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
export const RUNTIME_CONTROL_SAFE_POINTS = Object.freeze({
|
|
14
|
+
BEFORE_EXECUTE: "before_execute",
|
|
15
|
+
ADAPTER_CHECKPOINT: "adapter_checkpoint",
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
const RUNTIME_CONTROL_FIELDS = new Set([
|
|
19
|
+
"schemaVersion",
|
|
20
|
+
"pauseResume",
|
|
21
|
+
"safePoints",
|
|
22
|
+
]);
|
|
23
|
+
const RUNTIME_CONTROL_SAFE_POINT_SET = new Set(
|
|
24
|
+
Object.values(RUNTIME_CONTROL_SAFE_POINTS),
|
|
25
|
+
);
|
|
6
26
|
|
|
7
27
|
export const OCCURRENCE_STATUS = Object.freeze({
|
|
8
28
|
QUEUED: "queued",
|
|
@@ -286,6 +306,77 @@ export function normalizeHistoryLimit(value = DEFAULT_HISTORY_LIMIT) {
|
|
|
286
306
|
return Math.min(value, MAX_HISTORY_LIMIT);
|
|
287
307
|
}
|
|
288
308
|
|
|
309
|
+
/**
|
|
310
|
+
* Normalize the durable runtime-control capability advertised by an adapter.
|
|
311
|
+
*
|
|
312
|
+
* Missing declarations are deliberately treated as unsupported. A checkpoint
|
|
313
|
+
* declaration is evidence, not a hint: only the two kernel-owned safe points
|
|
314
|
+
* are accepted and every persisted pause request is bound to these canonical
|
|
315
|
+
* bytes.
|
|
316
|
+
*/
|
|
317
|
+
export function normalizeRuntimeControlCapability(input) {
|
|
318
|
+
if (input === undefined || input === null) {
|
|
319
|
+
return Object.freeze({
|
|
320
|
+
schemaVersion: RUNTIME_CONTROL_SCHEMA_VERSION,
|
|
321
|
+
pauseResume: RUNTIME_PAUSE_RESUME.NONE,
|
|
322
|
+
safePoints: Object.freeze([]),
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
const capability = assertPlainObject(input, "runtimeControl");
|
|
326
|
+
assertKnownFields(capability, RUNTIME_CONTROL_FIELDS, "runtimeControl");
|
|
327
|
+
if (
|
|
328
|
+
capability.schemaVersion !== undefined &&
|
|
329
|
+
capability.schemaVersion !== RUNTIME_CONTROL_SCHEMA_VERSION
|
|
330
|
+
) {
|
|
331
|
+
throw invalidArgument(
|
|
332
|
+
`runtimeControl.schemaVersion must be ${RUNTIME_CONTROL_SCHEMA_VERSION}`,
|
|
333
|
+
);
|
|
334
|
+
}
|
|
335
|
+
const pauseResume = capability.pauseResume ?? RUNTIME_PAUSE_RESUME.NONE;
|
|
336
|
+
if (!Object.values(RUNTIME_PAUSE_RESUME).includes(pauseResume)) {
|
|
337
|
+
throw invalidArgument(
|
|
338
|
+
"runtimeControl.pauseResume must be none or checkpoint_v1",
|
|
339
|
+
);
|
|
340
|
+
}
|
|
341
|
+
const inputSafePoints = capability.safePoints ?? [];
|
|
342
|
+
if (!Array.isArray(inputSafePoints)) {
|
|
343
|
+
throw invalidArgument("runtimeControl.safePoints must be an array");
|
|
344
|
+
}
|
|
345
|
+
const safePoints = [
|
|
346
|
+
...new Set(
|
|
347
|
+
inputSafePoints.map((safePoint, index) =>
|
|
348
|
+
normalizeIdentifier(safePoint, `runtimeControl.safePoints[${index}]`, {
|
|
349
|
+
maxLength: 64,
|
|
350
|
+
}),
|
|
351
|
+
),
|
|
352
|
+
),
|
|
353
|
+
].sort();
|
|
354
|
+
const unknownSafePoints = safePoints.filter(
|
|
355
|
+
(safePoint) => !RUNTIME_CONTROL_SAFE_POINT_SET.has(safePoint),
|
|
356
|
+
);
|
|
357
|
+
if (unknownSafePoints.length > 0) {
|
|
358
|
+
throw invalidArgument("runtimeControl.safePoints contains unknown values", {
|
|
359
|
+
safePoints: unknownSafePoints,
|
|
360
|
+
});
|
|
361
|
+
}
|
|
362
|
+
if (
|
|
363
|
+
(pauseResume === RUNTIME_PAUSE_RESUME.NONE && safePoints.length !== 0) ||
|
|
364
|
+
(pauseResume === RUNTIME_PAUSE_RESUME.CHECKPOINT_V1 &&
|
|
365
|
+
safePoints.length === 0)
|
|
366
|
+
) {
|
|
367
|
+
throw invalidArgument(
|
|
368
|
+
pauseResume === RUNTIME_PAUSE_RESUME.NONE
|
|
369
|
+
? "runtimeControl.safePoints must be empty when pauseResume is none"
|
|
370
|
+
: "runtimeControl.safePoints must declare at least one checkpoint",
|
|
371
|
+
);
|
|
372
|
+
}
|
|
373
|
+
return Object.freeze({
|
|
374
|
+
schemaVersion: RUNTIME_CONTROL_SCHEMA_VERSION,
|
|
375
|
+
pauseResume,
|
|
376
|
+
safePoints: Object.freeze(safePoints),
|
|
377
|
+
});
|
|
378
|
+
}
|
|
379
|
+
|
|
289
380
|
/**
|
|
290
381
|
* Stable identity for one logical firing. All adapters must supply the same
|
|
291
382
|
* triggerKey for the same logical schedule. Including jobRevision prevents an
|
|
@@ -25,6 +25,7 @@ import {
|
|
|
25
25
|
normalizeJson,
|
|
26
26
|
} from "./contract.js";
|
|
27
27
|
import { SchedulerRuntime } from "./runtime.js";
|
|
28
|
+
import { CHECKPOINT_V1_RUNTIME_CONTROL } from "./runtime-control-capabilities.js";
|
|
28
29
|
import { schedulerMigrationSourceDigest } from "./store.js";
|
|
29
30
|
import {
|
|
30
31
|
bindSchedulerAuthorityPolicy,
|
|
@@ -571,6 +572,7 @@ export function createCoworkCronSchedulerAdapter({ runTask, now } = {}) {
|
|
|
571
572
|
}
|
|
572
573
|
return {
|
|
573
574
|
kind: COWORK_CRON_SCHEDULER_KIND,
|
|
575
|
+
runtimeControl: CHECKPOINT_V1_RUNTIME_CONTROL,
|
|
574
576
|
async adjudicate({ occurrence, adjudication }) {
|
|
575
577
|
const payload = occurrence.payload;
|
|
576
578
|
const cwd = normalizedCwd(payload.cwd);
|
|
@@ -604,7 +606,7 @@ export function createCoworkCronSchedulerAdapter({ runTask, now } = {}) {
|
|
|
604
606
|
}
|
|
605
607
|
return { continue: true };
|
|
606
608
|
},
|
|
607
|
-
async execute({ occurrence, signal }) {
|
|
609
|
+
async execute({ occurrence, signal, checkpoint }) {
|
|
608
610
|
const payload = occurrence.payload;
|
|
609
611
|
const expected = coworkCronScheduleSnapshot(payload?.schedule);
|
|
610
612
|
const expectedDigest = coworkCronScheduleDigest(expected);
|
|
@@ -662,6 +664,12 @@ export function createCoworkCronSchedulerAdapter({ runTask, now } = {}) {
|
|
|
662
664
|
);
|
|
663
665
|
}
|
|
664
666
|
|
|
667
|
+
checkpoint({
|
|
668
|
+
deliveryId,
|
|
669
|
+
phase: "before_execution_bind",
|
|
670
|
+
scheduleId: expected.id,
|
|
671
|
+
});
|
|
672
|
+
|
|
665
673
|
current = bindSchedulerScheduleFire(cwd, expected.id, {
|
|
666
674
|
deliveryId,
|
|
667
675
|
occurrenceId: occurrence.id,
|
|
@@ -803,6 +811,9 @@ export function createCoworkCronSchedulerAdapter({ runTask, now } = {}) {
|
|
|
803
811
|
);
|
|
804
812
|
}
|
|
805
813
|
},
|
|
814
|
+
async resume(context) {
|
|
815
|
+
return this.execute(context);
|
|
816
|
+
},
|
|
806
817
|
classifyError(error) {
|
|
807
818
|
return {
|
|
808
819
|
retryable: error?.retryable === true,
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
normalizeJson,
|
|
8
8
|
} from "./contract.js";
|
|
9
9
|
import { SchedulerRuntime } from "./runtime.js";
|
|
10
|
+
import { CHECKPOINT_V1_RUNTIME_CONTROL } from "./runtime-control-capabilities.js";
|
|
10
11
|
import {
|
|
11
12
|
schedulerJobDefinitionDigest,
|
|
12
13
|
schedulerMigrationSourceDigest,
|
|
@@ -785,6 +786,7 @@ export function createLoopSchedulerAdapter({ runIteration } = {}) {
|
|
|
785
786
|
const transientResults = new Map();
|
|
786
787
|
return {
|
|
787
788
|
kind: LOOP_SCHEDULER_KIND,
|
|
789
|
+
runtimeControl: CHECKPOINT_V1_RUNTIME_CONTROL,
|
|
788
790
|
async adjudicate({ occurrence, adjudication }) {
|
|
789
791
|
if (adjudication.decision === "confirmed_applied") {
|
|
790
792
|
const match = /^iteration:(\d+)$/.exec(occurrence.triggerKey);
|
|
@@ -799,7 +801,7 @@ export function createLoopSchedulerAdapter({ runIteration } = {}) {
|
|
|
799
801
|
}
|
|
800
802
|
return { continue: true };
|
|
801
803
|
},
|
|
802
|
-
async execute({ occurrence, signal, adjudication }) {
|
|
804
|
+
async execute({ occurrence, signal, adjudication, checkpoint }) {
|
|
803
805
|
const definition = loopExecutionSnapshot(occurrence?.payload?.definition);
|
|
804
806
|
if (
|
|
805
807
|
occurrence.payload.snapshotDigest !== loopExecutionDigest(definition)
|
|
@@ -826,6 +828,7 @@ export function createLoopSchedulerAdapter({ runIteration } = {}) {
|
|
|
826
828
|
`Loop iteration may already have produced side effects; refusing replay: ${occurrence.id}`,
|
|
827
829
|
);
|
|
828
830
|
}
|
|
831
|
+
checkpoint({ iteration, phase: "before_runner" });
|
|
829
832
|
const result =
|
|
830
833
|
(await runIteration(iteration, { signal, definition })) || {};
|
|
831
834
|
const persisted = persistedIterationResult(iteration, result);
|
|
@@ -835,6 +838,9 @@ export function createLoopSchedulerAdapter({ runIteration } = {}) {
|
|
|
835
838
|
});
|
|
836
839
|
return persisted;
|
|
837
840
|
},
|
|
841
|
+
async resume(context) {
|
|
842
|
+
return this.execute(context);
|
|
843
|
+
},
|
|
838
844
|
classifyError() {
|
|
839
845
|
return { retryable: false };
|
|
840
846
|
},
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
normalizeIdentifier,
|
|
14
14
|
} from "./contract.js";
|
|
15
15
|
import { SchedulerRuntime } from "./runtime.js";
|
|
16
|
+
import { CHECKPOINT_V1_RUNTIME_CONTROL } from "./runtime-control-capabilities.js";
|
|
16
17
|
import { schedulerMigrationSourceDigest } from "./store.js";
|
|
17
18
|
import {
|
|
18
19
|
bindSchedulerAuthorityPolicy,
|
|
@@ -772,6 +773,7 @@ export function createRoutineSchedulerAdapter({ routineStore, runAgent } = {}) {
|
|
|
772
773
|
}
|
|
773
774
|
return {
|
|
774
775
|
kind: ROUTINE_SCHEDULER_KIND,
|
|
776
|
+
runtimeControl: CHECKPOINT_V1_RUNTIME_CONTROL,
|
|
775
777
|
async adjudicate({ occurrence, adjudication }) {
|
|
776
778
|
const payload = occurrence.payload;
|
|
777
779
|
const expected = payload?.routine;
|
|
@@ -812,7 +814,7 @@ export function createRoutineSchedulerAdapter({ routineStore, runAgent } = {}) {
|
|
|
812
814
|
}
|
|
813
815
|
return { continue: true };
|
|
814
816
|
},
|
|
815
|
-
async execute({ occurrence, adjudication }) {
|
|
817
|
+
async execute({ occurrence, adjudication, checkpoint }) {
|
|
816
818
|
const payload = occurrence.payload;
|
|
817
819
|
const expected = payload?.routine;
|
|
818
820
|
if (!expected) {
|
|
@@ -884,6 +886,7 @@ export function createRoutineSchedulerAdapter({ routineStore, runAgent } = {}) {
|
|
|
884
886
|
`Routine was disabled before scheduled execution: ${expected.id}`,
|
|
885
887
|
);
|
|
886
888
|
}
|
|
889
|
+
checkpoint({ phase: "before_run_bind", runId: schedulerRunId });
|
|
887
890
|
const execution = await executeRoutine(
|
|
888
891
|
routineStore,
|
|
889
892
|
effectiveCurrent,
|
|
@@ -912,6 +915,9 @@ export function createRoutineSchedulerAdapter({ routineStore, runAgent } = {}) {
|
|
|
912
915
|
}
|
|
913
916
|
return execution;
|
|
914
917
|
},
|
|
918
|
+
async resume(context) {
|
|
919
|
+
return this.execute(context);
|
|
920
|
+
},
|
|
915
921
|
classifyError(error) {
|
|
916
922
|
return { retryable: error?.retryable !== false };
|
|
917
923
|
},
|