chainlesschain 0.164.0 → 0.165.2
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/README.md +248 -2
- package/package.json +7 -4
- package/src/assets/web-panel/.build-hash +1 -1
- package/src/assets/web-panel/assets/{AIOps-D2MEn7fI.js → AIOps-lS1R0Cza.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-lCW_4Gf0.js → ActionButton-BmlgBPsj.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-Bs7i-nsS.js → Analytics-CNKczv1S.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-CK7B6S_j.js → AppLayout-BuZGJARQ.js} +5 -5
- package/src/assets/web-panel/assets/{Artifacts-C8ILjpyo.js → Artifacts-Dm73Sl-O.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-Bb9cNaWc.js → Audit-BGMW7A5e.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-sC9ooXIf.js → BackgroundAgents-BQ6M54JR.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-D-DrsplT.js → Backup-DBzGP0bR.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-uCNZpwSK.js → BaseInput-D1mLCoOV.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-CsDK1uE9.js → Chat-BUfcN7p8.js} +6 -6
- package/src/assets/web-panel/assets/{ChatBubbleRenderer-OqSDt50w.js → ChatBubbleRenderer-CY5m8ZHg.js} +1 -1
- package/src/assets/web-panel/assets/{Checkbox-JhTXM1-K.js → Checkbox-Du0Yg5Pi.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-BbzZLnyD.js → Codegen-B2RXziHW.js} +1 -1
- package/src/assets/web-panel/assets/{Col-D4VW4m4j.js → Col-DWhekOrR.js} +1 -1
- package/src/assets/web-panel/assets/{Community-BXrYawxV.js → Community-HQhrkon4.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-DCihGy1u.js → Compact-izHNb4uz.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-DlyZ-lk8.js → Compliance-BDwLy41-.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-DvGZrhbO.js → Cowork-DFJhLa7K.js} +3 -3
- package/src/assets/web-panel/assets/{Cron-DUncZi8h.js → Cron-DYY9RG7-.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-C_hLuUcm.js → Crosschain-rr7tJTtv.js} +1 -1
- package/src/assets/web-panel/assets/{DID-b6YSUqxr.js → DID-D2sfHRLi.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-uvM15Cfb.js → Dashboard-q_eGdhha.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-D1-Nd4qY.js → Dropdown-Cufrh2Bz.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-8ApvL6Zc.js → EmailListRenderer-B-kdv10f.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-LYJt8811.js → FamilyGuardDashboard-D21XjgfG.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-BbI3HGpv.js → Federation-CAwRTLZH.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-DSoEKuFu.js → FormItemContext-vx3daNDF.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-B0S9OWd5.js → GenericCardRenderer-CRWY2wU4.js} +1 -1
- package/src/assets/web-panel/assets/{Git-DIs9Zhf3.js → Git-Q6SwauyD.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-jzZXrxcl.js → Governance-BJ1q4IQZ.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-JUPjf2ZI.js → Inference-CSWjROgD.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-DxnfJvlP.js → KnowledgeGraph-fzuQsWuY.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-iXiz8BEE.js → Logs-DVF8Mnns.js} +2 -2
- package/src/assets/web-panel/assets/MarkdownRenderer-BLif4QSg.js +1 -0
- package/src/assets/web-panel/assets/{Marketplace-Y3Xch312.js → Marketplace-BQP7LOA4.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-D7kGGbO7.js → McpTools-BNlJCmNc.js} +4 -4
- package/src/assets/web-panel/assets/{Memory-Do_hVxzh.js → Memory-DLLg5WQ4.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-CtrR0Tas.js → MobileBridge-CR2skNAF.js} +1 -1
- package/src/assets/web-panel/assets/MobileProjects-BxVavObl.js +1 -0
- package/src/assets/web-panel/assets/{Mtc-qo5QCTGd.js → Mtc-B17pgqMI.js} +4 -4
- package/src/assets/web-panel/assets/{MtcAudit-cq5mnjYj.js → MtcAudit-4UmV5cIL.js} +2 -2
- package/src/assets/web-panel/assets/{Multisig-Bq0MAQHw.js → Multisig-DoMEXEcU.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-DdWE6Vi2.js → NLProgramming-h9DMXFX4.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-BxMBFcIp.js → Notes-Cihn-xX8.js} +3 -3
- package/src/assets/web-panel/assets/{NotificationSettings-RTrAcbUe.js → NotificationSettings-BE6ZGa3R.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-DJbpGqzT.js → OrderTableRenderer-CnwojoSI.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-SQzIPdqC.js → Organization-B2vpwmjb.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-02yECh22.js → Overflow-C4z28R0-.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-BNg4pNCM.js → P2P-BVlFkwhW.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-BxPJZsD3.js → PdhVaultBrowser-BXbEdL5B.js} +3 -3
- package/src/assets/web-panel/assets/{Permissions-CLnDnPAz.js → Permissions-C28xs4lp.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-C5m0AjGf.js → PersonalDataHub-Dgl_rBjM.js} +4 -4
- package/src/assets/web-panel/assets/{Pipeline-VwOf5Dhv.js → Pipeline-3QUIhrKI.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-CC0W2hZd.js → Privacy-8Gh33OZ5.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-Dz893Bob.js → ProjectInit-BNmg4tZi.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-CxQkvl0k.js → ProjectSettings-vgMfeCf9.js} +2 -2
- package/src/assets/web-panel/assets/Projects-BhtAVilc.js +1 -0
- package/src/assets/web-panel/assets/{Providers-DeB9IkxK.js → Providers-CXoOa8eX.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-OCeoaswn.js → QrScannerModal-BhfTF0oS.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-DenotaAj.js → QuickAsk-C746HEAj.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-Cies_jjI.js → Recommend-BSej8Eo0.js} +1 -1
- package/src/assets/web-panel/assets/RemoteSession-f3gmnlG3.js +5 -0
- package/src/assets/web-panel/assets/{Reputation-CW0mvxgZ.js → Reputation-CyvybpkN.js} +1 -1
- package/src/assets/web-panel/assets/{Row-SEd32qZU.js → Row-DwV2PeYn.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-BSwnJ3Lm.js → RssFeed-11GrzjZy.js} +3 -3
- package/src/assets/web-panel/assets/{Search-xe2m8bkC.js → Search-BjKXkrAY.js} +1 -1
- package/src/assets/web-panel/assets/{Security-Mq2F9Nro.js → Security-eWiFb9Yk.js} +4 -4
- package/src/assets/web-panel/assets/{Services-BKGw2V3P.js → Services-CdCsMAtt.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-DW95-Rxf.js → Skeleton-4Q2UTKQ5.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-CHgChCv_.js → Skills-v4rtYrRj.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-tKh6k3R7.js → Sla-CRhsFvd_.js} +1 -1
- package/src/assets/web-panel/assets/SpeechSettings-DLjKsDVu.js +1 -0
- package/src/assets/web-panel/assets/{SyncSettings-D0Fw8fVL.js → SyncSettings-D16zonl7.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-20x1GB3D.js → Tasks-Xxozz0i_.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-DJ-lts-a.js → Templates-CXJpPtCT.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-BFdGpbs7.js → Tenant-XRV0L1ZF.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-Xpx61vHL.js → Terminal-CYuO1i_w.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-C6UIvyZQ.js → TimelineRenderer-BXqitWsu.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-Dellq08f.js → Tokens-BvPrDHIy.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-VKw8d0J-.js → Trigger-DhCrSTf5.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-DNftdKT5.js → Trust-DmsuZD6K.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-DX9VAKJI.js → UkeySign-D_yrts5C.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-B2h3jO8q.js → VideoEditing-B01ihPrm.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-CjGkof7f.js → Wallet-DpUjKa-N.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-2Zfcu55P.js → WebAuthn-CL07yON6.js} +4 -4
- package/src/assets/web-panel/assets/{WorkflowEditor-B9eZ8UxZ.js → WorkflowEditor-CLMflnRr.js} +1 -1
- package/src/assets/web-panel/assets/{chat-CQNfD-YO.js → chat-DtUqe8h_.js} +1 -1
- package/src/assets/web-panel/assets/{colors-D4usyFT2.js → colors-DPKrgVfy.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-s4TpjvjX.js → compact-item-BTt2GtOm.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-BRCSvYxj.js → createContext-D_VeUc1J.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-Bj5nUW2v.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-AdkUbkV-.js → hasIn-1kndiylj.js} +1 -1
- package/src/assets/web-panel/assets/{index-BIoG5yYf.js → index-2eyAXE3d.js} +1 -1
- package/src/assets/web-panel/assets/{index-nXyk8GZ9.js → index-4bna2_SR.js} +1 -1
- package/src/assets/web-panel/assets/{index-B2V-eKfK.js → index-8nz_fmlj.js} +1 -1
- package/src/assets/web-panel/assets/{index-D_XBHopw.js → index-B9KvcS7R.js} +1 -1
- package/src/assets/web-panel/assets/{index-s_buFMEG.js → index-BAXfRKfG.js} +1 -1
- package/src/assets/web-panel/assets/{index-DZT36ZYq.js → index-BHpBMWCh.js} +1 -1
- package/src/assets/web-panel/assets/{index-BMcimU-2.js → index-BaZAbw9A.js} +1 -1
- package/src/assets/web-panel/assets/{index-DzRjHxEv.js → index-BepLZwgB.js} +1 -1
- package/src/assets/web-panel/assets/{index--00U6vXZ.js → index-Bhudc_Ez.js} +1 -1
- package/src/assets/web-panel/assets/{index-C7Y8Aluc.js → index-BlDNVgBt.js} +1 -1
- package/src/assets/web-panel/assets/{index-BtobShro.js → index-By5n8up9.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cvyt-zhm.js → index-CHG-KcS4.js} +1 -1
- package/src/assets/web-panel/assets/index-CPcM-eqo.js +1 -0
- package/src/assets/web-panel/assets/{index-MMN9V6JF.js → index-CX81qSM4.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bad4VNvz.js → index-CauoBQkH.js} +1 -1
- package/src/assets/web-panel/assets/{index-CCsM_Ybx.js → index-CcO04eDn.js} +1 -1
- package/src/assets/web-panel/assets/{index-DARsAyUp.js → index-CtF7EN49.js} +1 -1
- package/src/assets/web-panel/assets/{index-C5KAQFPQ.js → index-CzjkKUmR.js} +1 -1
- package/src/assets/web-panel/assets/{index-RfMr79MW.js → index-D95OFht7.js} +1 -1
- package/src/assets/web-panel/assets/{index-DdCB70SS.js → index-DFIZ_1Sf.js} +1 -1
- package/src/assets/web-panel/assets/{index-CYdoQsa1.js → index-DG2MZQ3f.js} +1 -1
- package/src/assets/web-panel/assets/{index-BPhkFZ1I.js → index-DJ8vXGOa.js} +1 -1
- package/src/assets/web-panel/assets/{index-_IRVsV9X.js → index-Dbbymxpj.js} +1 -1
- package/src/assets/web-panel/assets/{index-DVKfQ0Ux.js → index-DdkplL9R.js} +1 -1
- package/src/assets/web-panel/assets/{index-CkwiSLhU.js → index-DfGl8CqG.js} +1 -1
- package/src/assets/web-panel/assets/{index-CJVEOa4i.js → index-DfKBRdSS.js} +1 -1
- package/src/assets/web-panel/assets/{index-C1mJtE6q.js → index-DsJCDUJG.js} +1 -1
- package/src/assets/web-panel/assets/{index-BgiXR_-_.js → index-Dwqmtk65.js} +1 -1
- package/src/assets/web-panel/assets/{index-CJCFe2Qf.js → index-DxdTdBix.js} +1 -1
- package/src/assets/web-panel/assets/{index-C484EJiS.js → index-FzdwcSy2.js} +1 -1
- package/src/assets/web-panel/assets/{index-B4JJCfQ2.js → index-GsoUQ2M7.js} +1 -1
- package/src/assets/web-panel/assets/{index-CQhAVU5t.js → index-brCInrzq.js} +1 -1
- package/src/assets/web-panel/assets/{index-CKC1t3Ic.js → index-dVc-CXY4.js} +1 -1
- package/src/assets/web-panel/assets/{index-BQ3DXBtD.js → index-fk2Rjacw.js} +3 -3
- package/src/assets/web-panel/assets/{index-Cduu2Hhr.js → index-l1BETrDb.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bw2MEnUk.js → index-m31Ka8hZ.js} +1 -1
- package/src/assets/web-panel/assets/{index-D2GjI2oe.js → index-ocf06EVQ.js} +1 -1
- package/src/assets/web-panel/assets/{index-CJdQrZth.js → index-sDoMHTNA.js} +1 -1
- package/src/assets/web-panel/assets/index-xeSyVoRe.js +1 -0
- package/src/assets/web-panel/assets/{initDefaultProps-Blmpk7HL.js → initDefaultProps-CvyYJd7z.js} +1 -1
- package/src/assets/web-panel/assets/{motion-DPBJMv1n.js → motion-DYZkhUdz.js} +1 -1
- package/src/assets/web-panel/assets/{move-ButdzCM7.js → move-slnJRVT1.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-cyRC_QCe.js → mtc-parser-DVc0CKmy.js} +1 -1
- package/src/assets/web-panel/assets/{omit-1epSV7hz.js → omit-BCXAtHCq.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-DuPY8xJs.js → pickAttrs-DBsemz_K.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-6XZqarhe.js → placementArrow-BRtkJ-nv.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-B40pXBWM.js → responsiveObserve-Cebq7EZn.js} +1 -1
- package/src/assets/web-panel/assets/{slide-jbZ9Wu4n.js → slide-DT7qvId2.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-BKQQcVy4.js → statusUtils-pQiITLkG.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-NiKfWjUT.js → styleChecker-c-19BVKQ.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-bQUCvPeb.js → useFlexGapSupport-DsS5-0bE.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-CUGji7ph.js → useFs-CxGiMe5n.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-4veyN2N2.js → usePersonalDataHub-D9btVID5.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-1-nLug-Z.js → vnode-CUYFsFEN.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-dhCeRDMo.js → zoom-CXmn_35j.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/command-help-index.json +1 -1
- package/src/commands/cowork.js +559 -62
- package/src/commands/plugin.js +819 -64
- package/src/commands/session-location.js +318 -7
- package/src/constants.js +2 -2
- package/src/data/changelog.json +28 -2
- package/src/gateways/ws/action-protocol.js +293 -19
- package/src/gateways/ws/message-dispatcher.js +30 -0
- package/src/gateways/ws/remote-session-protocol.js +542 -35
- package/src/gateways/ws/ws-approval-gate.js +5 -0
- package/src/gateways/ws/ws-server.js +462 -38
- package/src/harness/jsonl-session-store.js +638 -2
- package/src/harness/prompt-compressor.js +4 -0
- package/src/harness/remote-session-audit.js +1 -0
- package/src/harness/remote-session-crypto.js +750 -50
- package/src/harness/remote-session-registry.js +795 -27
- package/src/lib/auto-mode-config.js +98 -3
- package/src/lib/background-agent-keeper-client.js +29 -0
- package/src/lib/background-agent-keeper-protocol.js +158 -10
- package/src/lib/background-agent-supervisor.js +870 -48
- package/src/lib/background-session-transport.js +23 -6
- package/src/lib/background-turn-bootstrap-protocol.js +64 -0
- package/src/lib/cowork-task-runner.js +70 -0
- package/src/lib/cowork-workflow.js +887 -62
- package/src/lib/delivery-production-adapter.js +38 -2
- package/src/lib/doctor-checkup.js +34 -10
- package/src/lib/dynamic-workflow-draft.js +535 -0
- package/src/lib/dynamic-workflow-facade.js +1105 -17
- package/src/lib/dynamic-workflow-runtime.js +2974 -0
- package/src/lib/execution-location-contract.js +111 -7
- package/src/lib/execution-location-runtime.js +3 -1
- package/src/lib/execution-location-target.js +910 -0
- package/src/lib/llm-providers.js +1 -0
- package/src/lib/mcp-call-ledger-store.js +35 -0
- package/src/lib/mcp-call-ledger.js +30 -0
- package/src/lib/mcp-stdio-package-materialization.js +1 -1
- package/src/lib/plugin-runtime/__tests__/remote-source.test.js +34 -16
- package/src/lib/plugin-runtime/install.js +4956 -657
- package/src/lib/plugin-runtime/manifest.js +3 -1
- package/src/lib/plugin-runtime/marketplace-artifact-readback.js +671 -31
- package/src/lib/plugin-runtime/marketplace-catalog.js +68 -2
- package/src/lib/plugin-runtime/marketplace-impact.js +208 -15
- package/src/lib/plugin-runtime/marketplace-network.js +317 -0
- package/src/lib/plugin-runtime/marketplace-pac-worker.js +15 -0
- package/src/lib/plugin-runtime/marketplace-remote-artifacts.js +25 -2
- package/src/lib/plugin-runtime/marketplace-source-cache.js +359 -0
- package/src/lib/plugin-runtime/policy.js +21 -6
- package/src/lib/plugin-runtime/publisher-trust.js +332 -0
- package/src/lib/plugin-runtime/remote-source.js +323 -27
- package/src/lib/plugin-runtime/scopes.js +317 -41
- package/src/lib/plugin-runtime/transaction-journal.js +806 -0
- package/src/lib/public-ide-capability-manifest.js +1 -1
- package/src/lib/remote-approval-bridge.js +745 -108
- package/src/lib/remote-control.js +2 -0
- package/src/lib/remote-membership-coordinator.js +612 -46
- package/src/lib/remote-membership-host-store.js +59 -10
- package/src/lib/runtime-provenance-ledger.js +171 -46
- package/src/lib/shell-approval.js +169 -6
- package/src/lib/sub-agent-context.js +268 -2
- package/src/lib/task-model-selector.js +1 -1
- package/src/lib/with-file-lock.js +167 -42
- package/src/repl/agent-repl.js +70 -29
- package/src/repl/remote-approval.js +29 -7
- package/src/runtime/agent-core.js +1695 -194
- package/src/runtime/headless-runner.js +22 -5
- package/src/runtime/headless-stream.js +19 -3
- package/src/workers/background-agent-keeper.js +279 -58
- package/src/workers/background-agent-worker.js +7 -0
- package/src/workers/background-turn-bootstrap.js +29 -2
- package/src/assets/web-panel/assets/MarkdownRenderer-GmB6DOr6.js +0 -1
- package/src/assets/web-panel/assets/MobileProjects-BL0Czcoj.js +0 -1
- package/src/assets/web-panel/assets/Projects-DDAjkUkT.js +0 -1
- package/src/assets/web-panel/assets/RemoteSession-Dxzl5n2T.js +0 -5
- package/src/assets/web-panel/assets/SpeechSettings-D6UL3dA5.js +0 -1
- package/src/assets/web-panel/assets/devWarning-DKJjSWRn.js +0 -1
- package/src/assets/web-panel/assets/index-C61cnl3K.js +0 -1
- package/src/assets/web-panel/assets/index-D4XFHxBr.js +0 -1
package/src/commands/cowork.js
CHANGED
|
@@ -9,6 +9,71 @@ import fs from "fs";
|
|
|
9
9
|
import path from "path";
|
|
10
10
|
import { logger } from "../lib/logger.js";
|
|
11
11
|
|
|
12
|
+
const SESSION_EXECUTION_LOCATION_AUTHORITY_SCHEMA =
|
|
13
|
+
"cc-session-execution-location-authority/v1";
|
|
14
|
+
|
|
15
|
+
function workflowAuthorityError(code, message) {
|
|
16
|
+
const error = new Error(message);
|
|
17
|
+
error.code = code;
|
|
18
|
+
error.executionStarted = false;
|
|
19
|
+
return error;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function requireWorkflowExecutionAuthoritySession(sessionId) {
|
|
23
|
+
if (typeof sessionId !== "string" || sessionId.trim() === "") {
|
|
24
|
+
throw workflowAuthorityError(
|
|
25
|
+
"CC_DYNAMIC_WORKFLOW_EXECUTION_AUTHORITY_MISSING",
|
|
26
|
+
"--execution-authority-session <id> is required",
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
return sessionId;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function projectWorkflowExecutionAuthority(sessionId, verifiedProof) {
|
|
33
|
+
requireWorkflowExecutionAuthoritySession(sessionId);
|
|
34
|
+
let proof;
|
|
35
|
+
try {
|
|
36
|
+
proof = structuredClone(verifiedProof);
|
|
37
|
+
} catch {
|
|
38
|
+
throw workflowAuthorityError(
|
|
39
|
+
"CC_DYNAMIC_WORKFLOW_EXECUTION_AUTHORITY_INVALID",
|
|
40
|
+
"verified execution authority could not be safely snapshotted",
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
if (proof?.sessionId !== sessionId) {
|
|
44
|
+
throw workflowAuthorityError(
|
|
45
|
+
"CC_DYNAMIC_WORKFLOW_EXECUTION_AUTHORITY_SESSION_MISMATCH",
|
|
46
|
+
"verified execution authority does not match the requested session",
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
return Object.freeze({
|
|
50
|
+
schema: SESSION_EXECUTION_LOCATION_AUTHORITY_SCHEMA,
|
|
51
|
+
authority: proof.authority || "verified-session-start",
|
|
52
|
+
sessionId: proof.sessionId,
|
|
53
|
+
headHash: proof.headHash,
|
|
54
|
+
eventCount: proof.eventCount,
|
|
55
|
+
binding: proof.binding,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function renderWorkflowPreflight(preflight) {
|
|
60
|
+
const color = preflight.allowed ? chalk.green : chalk.red;
|
|
61
|
+
logger.log(color(preflight.allowed ? "READY" : "BLOCKED"));
|
|
62
|
+
logger.log(` definition: ${preflight.definition.definitionDigest}`);
|
|
63
|
+
logger.log(
|
|
64
|
+
` task calls: ${preflight.scale.worstCaseTaskCalls ?? "unknown"}`,
|
|
65
|
+
);
|
|
66
|
+
logger.log(
|
|
67
|
+
` tokens/USD: ${preflight.cost.projectedTokens ?? "unknown"} / ${preflight.cost.projectedUsd ?? "unknown"}`,
|
|
68
|
+
);
|
|
69
|
+
for (const blocker of preflight.blockers) {
|
|
70
|
+
logger.log(chalk.red(` blocker: ${blocker}`));
|
|
71
|
+
}
|
|
72
|
+
for (const warning of preflight.warnings) {
|
|
73
|
+
logger.log(chalk.yellow(` warning: ${warning}`));
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
12
77
|
async function loadCoworkWorkflowRecord(cwd, id, definitionDigest) {
|
|
13
78
|
const { getWorkflowRecord, getWorkflowVersion } =
|
|
14
79
|
await import("../lib/cowork-workflow.js");
|
|
@@ -17,7 +82,38 @@ async function loadCoworkWorkflowRecord(cwd, id, definitionDigest) {
|
|
|
17
82
|
: getWorkflowRecord(cwd, id);
|
|
18
83
|
}
|
|
19
84
|
|
|
20
|
-
|
|
85
|
+
function verifyWorkflowRunAuthorities(
|
|
86
|
+
cwd,
|
|
87
|
+
{ workflowId, definitionDigest, executionAuthoritySessionId },
|
|
88
|
+
deps,
|
|
89
|
+
) {
|
|
90
|
+
const definitionAuthority = deps.getWorkflowVersion(
|
|
91
|
+
cwd,
|
|
92
|
+
workflowId,
|
|
93
|
+
definitionDigest,
|
|
94
|
+
);
|
|
95
|
+
if (
|
|
96
|
+
!definitionAuthority ||
|
|
97
|
+
definitionAuthority.definitionDigest !== definitionDigest
|
|
98
|
+
) {
|
|
99
|
+
throw workflowAuthorityError(
|
|
100
|
+
"CC_DYNAMIC_WORKFLOW_DEFINITION_AUTHORITY_DRIFT",
|
|
101
|
+
"the exact admitted workflow definition version is no longer available",
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
const executionLocationAuthority = projectWorkflowExecutionAuthority(
|
|
105
|
+
executionAuthoritySessionId,
|
|
106
|
+
deps.getVerifiedSessionExecutionLocationAuthority(
|
|
107
|
+
executionAuthoritySessionId,
|
|
108
|
+
),
|
|
109
|
+
);
|
|
110
|
+
return Object.freeze({
|
|
111
|
+
definitionAuthority,
|
|
112
|
+
executionLocationAuthority,
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export function registerCoworkCommand(program, commandDeps = {}) {
|
|
21
117
|
const cowork = program
|
|
22
118
|
.command("cowork")
|
|
23
119
|
.description(
|
|
@@ -770,6 +866,256 @@ export function registerCoworkCommand(program) {
|
|
|
770
866
|
.command("workflow")
|
|
771
867
|
.description("Define and execute multi-step Cowork workflows (DAG)");
|
|
772
868
|
|
|
869
|
+
workflow
|
|
870
|
+
.command("draft <prompt>")
|
|
871
|
+
.description(
|
|
872
|
+
"Generate a digest-bound workflow draft for explicit human review",
|
|
873
|
+
)
|
|
874
|
+
.option("--provider <name>", "LLM provider to use")
|
|
875
|
+
.option("--model <name>", "LLM model to use")
|
|
876
|
+
.action(async (prompt, options) => {
|
|
877
|
+
try {
|
|
878
|
+
let chat;
|
|
879
|
+
let provider;
|
|
880
|
+
let model;
|
|
881
|
+
if (Object.hasOwn(commandDeps, "workflowDraftChat")) {
|
|
882
|
+
const descriptor = Object.getOwnPropertyDescriptor(
|
|
883
|
+
commandDeps,
|
|
884
|
+
"workflowDraftChat",
|
|
885
|
+
);
|
|
886
|
+
if (
|
|
887
|
+
!descriptor ||
|
|
888
|
+
!Object.hasOwn(descriptor, "value") ||
|
|
889
|
+
typeof descriptor.value !== "function"
|
|
890
|
+
) {
|
|
891
|
+
throw new Error(
|
|
892
|
+
"Cowork workflow draft chat seam must be a function data property",
|
|
893
|
+
);
|
|
894
|
+
}
|
|
895
|
+
chat = descriptor.value;
|
|
896
|
+
provider = options.provider || "fixture";
|
|
897
|
+
model = options.model || "fixture-model";
|
|
898
|
+
} else {
|
|
899
|
+
const [{ createChatFn }, { BUILT_IN_PROVIDERS }, { loadConfig }] =
|
|
900
|
+
await Promise.all([
|
|
901
|
+
import("../lib/cowork-adapter.js"),
|
|
902
|
+
import("../lib/llm-providers.js"),
|
|
903
|
+
import("../lib/config-manager.js"),
|
|
904
|
+
]);
|
|
905
|
+
const config = loadConfig()?.llm || {};
|
|
906
|
+
provider =
|
|
907
|
+
options.provider ||
|
|
908
|
+
process.env.LLM_PROVIDER ||
|
|
909
|
+
config.provider ||
|
|
910
|
+
"ollama";
|
|
911
|
+
const providerDefinition = BUILT_IN_PROVIDERS[provider];
|
|
912
|
+
if (!providerDefinition) {
|
|
913
|
+
throw new Error(`Unsupported workflow draft provider: ${provider}`);
|
|
914
|
+
}
|
|
915
|
+
model =
|
|
916
|
+
options.model ||
|
|
917
|
+
process.env.LLM_MODEL ||
|
|
918
|
+
(config.provider === provider ? config.model : null) ||
|
|
919
|
+
providerDefinition.models[0];
|
|
920
|
+
chat = createChatFn({
|
|
921
|
+
provider,
|
|
922
|
+
model,
|
|
923
|
+
...(config.provider === provider && config.baseUrl
|
|
924
|
+
? { baseUrl: config.baseUrl }
|
|
925
|
+
: {}),
|
|
926
|
+
...(config.provider === provider && config.apiKey
|
|
927
|
+
? { apiKey: config.apiKey }
|
|
928
|
+
: {}),
|
|
929
|
+
});
|
|
930
|
+
}
|
|
931
|
+
const { generateDynamicWorkflowDraft } =
|
|
932
|
+
await import("../lib/dynamic-workflow-draft.js");
|
|
933
|
+
const draft = await generateDynamicWorkflowDraft(
|
|
934
|
+
{ prompt, provider, model },
|
|
935
|
+
{ chat },
|
|
936
|
+
);
|
|
937
|
+
console.log(JSON.stringify(draft, null, 2));
|
|
938
|
+
} catch (err) {
|
|
939
|
+
logger.error(`WORKFLOW_DRAFT_FAILED: ${err.message}`);
|
|
940
|
+
process.exitCode = 2;
|
|
941
|
+
}
|
|
942
|
+
});
|
|
943
|
+
|
|
944
|
+
workflow
|
|
945
|
+
.command("review <file>")
|
|
946
|
+
.description(
|
|
947
|
+
"Accept or reject an exact workflow draft; accepted definitions are versioned",
|
|
948
|
+
)
|
|
949
|
+
.requiredOption(
|
|
950
|
+
"--expected-draft-digest <sha256>",
|
|
951
|
+
"Exact draft digest shown during review",
|
|
952
|
+
)
|
|
953
|
+
.requiredOption("--reviewer <identity>", "Human reviewer identity")
|
|
954
|
+
.option("--accept", "Accept and save the reviewed definition")
|
|
955
|
+
.option("--reject", "Reject without saving the definition")
|
|
956
|
+
.option("--reason <text>", "Bounded, secret-free review reason")
|
|
957
|
+
.option("--json", "Machine-readable JSON output")
|
|
958
|
+
.action(async (file, options) => {
|
|
959
|
+
try {
|
|
960
|
+
if (options.accept === options.reject) {
|
|
961
|
+
throw new Error("exactly one of --accept or --reject is required");
|
|
962
|
+
}
|
|
963
|
+
const [draftModule, workflowModule] = await Promise.all([
|
|
964
|
+
import("../lib/dynamic-workflow-draft.js"),
|
|
965
|
+
import("../lib/cowork-workflow.js"),
|
|
966
|
+
]);
|
|
967
|
+
const draft = draftModule.readDynamicWorkflowDraftFile(file);
|
|
968
|
+
const review = draftModule.reviewDynamicWorkflowDraft({
|
|
969
|
+
draft,
|
|
970
|
+
expectedDraftDigest: options.expectedDraftDigest,
|
|
971
|
+
decision: options.accept ? "accept" : "reject",
|
|
972
|
+
reviewer: options.reviewer,
|
|
973
|
+
reason: options.reason,
|
|
974
|
+
});
|
|
975
|
+
let persisted = false;
|
|
976
|
+
if (review.status === "accepted") {
|
|
977
|
+
workflowModule.saveWorkflow(process.cwd(), review.definition);
|
|
978
|
+
const record = workflowModule.getWorkflowRecord(
|
|
979
|
+
process.cwd(),
|
|
980
|
+
review.definition.id,
|
|
981
|
+
);
|
|
982
|
+
if (
|
|
983
|
+
!record ||
|
|
984
|
+
record.definitionDigest !== review.acceptedDefinitionDigest
|
|
985
|
+
) {
|
|
986
|
+
throw new Error(
|
|
987
|
+
"reviewed workflow readback did not match its accepted digest",
|
|
988
|
+
);
|
|
989
|
+
}
|
|
990
|
+
persisted = true;
|
|
991
|
+
}
|
|
992
|
+
const result = Object.freeze({ ...review, persisted });
|
|
993
|
+
if (options.json) {
|
|
994
|
+
console.log(JSON.stringify(result, null, 2));
|
|
995
|
+
return;
|
|
996
|
+
}
|
|
997
|
+
const label = review.status === "accepted" ? "Accepted" : "Rejected";
|
|
998
|
+
logger.log(`${label} workflow draft ${review.draftDigest}`);
|
|
999
|
+
logger.log(` review: ${review.reviewDigest}`);
|
|
1000
|
+
logger.log(
|
|
1001
|
+
` definition: ${review.acceptedDefinitionDigest || "not-saved"}`,
|
|
1002
|
+
);
|
|
1003
|
+
} catch (err) {
|
|
1004
|
+
logger.error(`WORKFLOW_REVIEW_FAILED: ${err.message}`);
|
|
1005
|
+
process.exitCode = 2;
|
|
1006
|
+
}
|
|
1007
|
+
});
|
|
1008
|
+
|
|
1009
|
+
workflow
|
|
1010
|
+
.command("runtime-status <run-id>")
|
|
1011
|
+
.description("Read a durable workflow run without invoking a task provider")
|
|
1012
|
+
.option("--json", "Machine-readable JSON output")
|
|
1013
|
+
.action(async (runId, options) => {
|
|
1014
|
+
try {
|
|
1015
|
+
const runtime = await import("../lib/dynamic-workflow-runtime.js");
|
|
1016
|
+
const statePath = runtime.dynamicWorkflowRunStatePath(
|
|
1017
|
+
process.cwd(),
|
|
1018
|
+
runId,
|
|
1019
|
+
);
|
|
1020
|
+
const projection = runtime.projectDynamicWorkflowRuntime(statePath);
|
|
1021
|
+
if (options.json) {
|
|
1022
|
+
console.log(JSON.stringify(projection, null, 2));
|
|
1023
|
+
return;
|
|
1024
|
+
}
|
|
1025
|
+
logger.log(`${projection.runId} ${projection.status}`);
|
|
1026
|
+
logger.log(` revision: ${projection.revision}`);
|
|
1027
|
+
logger.log(` definition: ${projection.definitionDigest}`);
|
|
1028
|
+
logger.log(
|
|
1029
|
+
` effects: ${projection.settledEffectCount}/${projection.effectCount} settled`,
|
|
1030
|
+
);
|
|
1031
|
+
for (const effect of projection.pendingEffects) {
|
|
1032
|
+
logger.log(` pending: ${effect.id} (${effect.key})`);
|
|
1033
|
+
}
|
|
1034
|
+
} catch (err) {
|
|
1035
|
+
logger.error(`WORKFLOW_RUNTIME_STATUS_FAILED: ${err.message}`);
|
|
1036
|
+
process.exitCode = 2;
|
|
1037
|
+
}
|
|
1038
|
+
});
|
|
1039
|
+
|
|
1040
|
+
for (const action of ["pause", "stop", "resume"]) {
|
|
1041
|
+
workflow
|
|
1042
|
+
.command(`runtime-${action} <run-id>`)
|
|
1043
|
+
.description(
|
|
1044
|
+
`${action[0].toUpperCase()}${action.slice(1)} a revision-bound durable workflow run`,
|
|
1045
|
+
)
|
|
1046
|
+
.requiredOption(
|
|
1047
|
+
"--expected-revision <n>",
|
|
1048
|
+
"Exact runtime revision shown by runtime-status",
|
|
1049
|
+
)
|
|
1050
|
+
.option("--json", "Machine-readable JSON output")
|
|
1051
|
+
.action(async (runId, options) => {
|
|
1052
|
+
try {
|
|
1053
|
+
const runtime = await import("../lib/dynamic-workflow-runtime.js");
|
|
1054
|
+
const statePath = runtime.dynamicWorkflowRunStatePath(
|
|
1055
|
+
process.cwd(),
|
|
1056
|
+
runId,
|
|
1057
|
+
);
|
|
1058
|
+
const operation =
|
|
1059
|
+
action === "pause"
|
|
1060
|
+
? runtime.requestDurableWorkflowPause
|
|
1061
|
+
: action === "stop"
|
|
1062
|
+
? runtime.requestDurableWorkflowStop
|
|
1063
|
+
: runtime.prepareDurableWorkflowResume;
|
|
1064
|
+
const state = operation(statePath, options.expectedRevision);
|
|
1065
|
+
const projection = runtime.projectDynamicWorkflowRuntime(state);
|
|
1066
|
+
if (options.json) {
|
|
1067
|
+
console.log(JSON.stringify(projection, null, 2));
|
|
1068
|
+
} else {
|
|
1069
|
+
logger.log(
|
|
1070
|
+
`${projection.runId} ${projection.status} revision=${projection.revision}`,
|
|
1071
|
+
);
|
|
1072
|
+
}
|
|
1073
|
+
} catch (err) {
|
|
1074
|
+
logger.error(
|
|
1075
|
+
`WORKFLOW_RUNTIME_${action.toUpperCase()}_FAILED: ${err.message}`,
|
|
1076
|
+
);
|
|
1077
|
+
process.exitCode = 2;
|
|
1078
|
+
}
|
|
1079
|
+
});
|
|
1080
|
+
}
|
|
1081
|
+
|
|
1082
|
+
workflow
|
|
1083
|
+
.command("runtime-reconcile <run-id> <effect-id> <result-file>")
|
|
1084
|
+
.description(
|
|
1085
|
+
"Settle one outcome-unknown effect from a bounded provider result file",
|
|
1086
|
+
)
|
|
1087
|
+
.requiredOption(
|
|
1088
|
+
"--expected-revision <n>",
|
|
1089
|
+
"Exact runtime revision shown by runtime-status",
|
|
1090
|
+
)
|
|
1091
|
+
.option("--json", "Machine-readable JSON output")
|
|
1092
|
+
.action(async (runId, effectId, resultFile, options) => {
|
|
1093
|
+
try {
|
|
1094
|
+
const runtime = await import("../lib/dynamic-workflow-runtime.js");
|
|
1095
|
+
const statePath = runtime.dynamicWorkflowRunStatePath(
|
|
1096
|
+
process.cwd(),
|
|
1097
|
+
runId,
|
|
1098
|
+
);
|
|
1099
|
+
const result = runtime.readDynamicWorkflowEffectResultFile(resultFile);
|
|
1100
|
+
const state = runtime.reconcileDurableWorkflowEffect(statePath, {
|
|
1101
|
+
expectedRevision: options.expectedRevision,
|
|
1102
|
+
effectId,
|
|
1103
|
+
result,
|
|
1104
|
+
});
|
|
1105
|
+
const projection = runtime.projectDynamicWorkflowRuntime(state);
|
|
1106
|
+
if (options.json) {
|
|
1107
|
+
console.log(JSON.stringify(projection, null, 2));
|
|
1108
|
+
} else {
|
|
1109
|
+
logger.log(
|
|
1110
|
+
`${projection.runId} ${projection.status} revision=${projection.revision}`,
|
|
1111
|
+
);
|
|
1112
|
+
}
|
|
1113
|
+
} catch (err) {
|
|
1114
|
+
logger.error(`WORKFLOW_RUNTIME_RECONCILE_FAILED: ${err.message}`);
|
|
1115
|
+
process.exitCode = 2;
|
|
1116
|
+
}
|
|
1117
|
+
});
|
|
1118
|
+
|
|
773
1119
|
workflow
|
|
774
1120
|
.command("list")
|
|
775
1121
|
.description("List saved workflows")
|
|
@@ -896,53 +1242,96 @@ export function registerCoworkCommand(program) {
|
|
|
896
1242
|
"--definition-digest <sha256>",
|
|
897
1243
|
"Preflight an immutable saved definition version",
|
|
898
1244
|
)
|
|
1245
|
+
.option(
|
|
1246
|
+
"--execution-authority-session <id>",
|
|
1247
|
+
"Verified session whose start event anchors execution authority",
|
|
1248
|
+
)
|
|
899
1249
|
.option("--max-parallel <n>", "Requested maximum parallel steps", "4")
|
|
900
1250
|
.option("--json", "Machine-readable JSON output")
|
|
901
1251
|
.action(async (id, options) => {
|
|
902
1252
|
try {
|
|
903
1253
|
const [
|
|
904
|
-
{
|
|
905
|
-
{
|
|
1254
|
+
{ buildDynamicWorkflowRunAdmission },
|
|
1255
|
+
{ getWorkflowVersion },
|
|
1256
|
+
{ getVerifiedSessionExecutionLocationAuthority },
|
|
906
1257
|
record,
|
|
907
1258
|
] = await Promise.all([
|
|
908
1259
|
import("../lib/dynamic-workflow-facade.js"),
|
|
909
|
-
import("../lib/
|
|
1260
|
+
import("../lib/cowork-workflow.js"),
|
|
1261
|
+
import("../harness/jsonl-session-store.js"),
|
|
910
1262
|
loadCoworkWorkflowRecord(process.cwd(), id, options.definitionDigest),
|
|
911
1263
|
]);
|
|
912
1264
|
if (!record) {
|
|
913
|
-
|
|
1265
|
+
if (options.json) {
|
|
1266
|
+
console.log(
|
|
1267
|
+
JSON.stringify(
|
|
1268
|
+
{
|
|
1269
|
+
schema: "cc-dynamic-workflow-run-admission-error/v1",
|
|
1270
|
+
allowed: false,
|
|
1271
|
+
executionStarted: false,
|
|
1272
|
+
code: "WORKFLOW_NOT_FOUND",
|
|
1273
|
+
message: `Workflow not found: ${id}`,
|
|
1274
|
+
},
|
|
1275
|
+
null,
|
|
1276
|
+
2,
|
|
1277
|
+
),
|
|
1278
|
+
);
|
|
1279
|
+
} else {
|
|
1280
|
+
logger.error(`Workflow not found: ${id}`);
|
|
1281
|
+
}
|
|
914
1282
|
process.exitCode = 1;
|
|
915
1283
|
return;
|
|
916
1284
|
}
|
|
917
|
-
const
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
1285
|
+
const executionAuthoritySessionId =
|
|
1286
|
+
requireWorkflowExecutionAuthoritySession(
|
|
1287
|
+
options.executionAuthoritySession,
|
|
1288
|
+
);
|
|
1289
|
+
const admission = buildDynamicWorkflowRunAdmission(
|
|
1290
|
+
{
|
|
1291
|
+
definitionAuthority: record,
|
|
1292
|
+
executionAuthoritySessionId,
|
|
1293
|
+
maxParallel: options.maxParallel,
|
|
1294
|
+
execution: {
|
|
1295
|
+
cwd: process.cwd(),
|
|
1296
|
+
continueOnError: false,
|
|
1297
|
+
pipeline: record.definition.pipeline === true,
|
|
1298
|
+
},
|
|
1299
|
+
},
|
|
1300
|
+
{
|
|
1301
|
+
verifyAuthorities: (lookup) =>
|
|
1302
|
+
verifyWorkflowRunAuthorities(process.cwd(), lookup, {
|
|
1303
|
+
getWorkflowVersion,
|
|
1304
|
+
getVerifiedSessionExecutionLocationAuthority,
|
|
1305
|
+
}),
|
|
1306
|
+
},
|
|
1307
|
+
);
|
|
1308
|
+
const preflight = admission.preflight;
|
|
923
1309
|
if (options.json) {
|
|
924
1310
|
console.log(JSON.stringify(preflight, null, 2));
|
|
925
1311
|
} else {
|
|
926
|
-
|
|
927
|
-
logger.log(color(preflight.allowed ? "READY" : "BLOCKED"));
|
|
928
|
-
logger.log(` definition: ${preflight.definition.definitionDigest}`);
|
|
929
|
-
logger.log(
|
|
930
|
-
` task calls: ${preflight.scale.worstCaseTaskCalls ?? "unknown"}`,
|
|
931
|
-
);
|
|
932
|
-
logger.log(
|
|
933
|
-
` tokens/USD: ${preflight.cost.projectedTokens ?? "unknown"} / ${preflight.cost.projectedUsd ?? "unknown"}`,
|
|
934
|
-
);
|
|
935
|
-
for (const blocker of preflight.blockers) {
|
|
936
|
-
logger.log(chalk.red(` blocker: ${blocker}`));
|
|
937
|
-
}
|
|
938
|
-
for (const warning of preflight.warnings) {
|
|
939
|
-
logger.log(chalk.yellow(` warning: ${warning}`));
|
|
940
|
-
}
|
|
1312
|
+
renderWorkflowPreflight(preflight);
|
|
941
1313
|
}
|
|
942
|
-
process.exitCode =
|
|
1314
|
+
process.exitCode = admission.allowed ? 0 : 2;
|
|
943
1315
|
} catch (err) {
|
|
944
|
-
|
|
945
|
-
|
|
1316
|
+
const code = err.code || "WORKFLOW_PREFLIGHT_BLOCKED";
|
|
1317
|
+
if (options.json) {
|
|
1318
|
+
console.log(
|
|
1319
|
+
JSON.stringify(
|
|
1320
|
+
{
|
|
1321
|
+
schema: "cc-dynamic-workflow-run-admission-error/v1",
|
|
1322
|
+
allowed: false,
|
|
1323
|
+
executionStarted: false,
|
|
1324
|
+
code,
|
|
1325
|
+
message: err.message,
|
|
1326
|
+
},
|
|
1327
|
+
null,
|
|
1328
|
+
2,
|
|
1329
|
+
),
|
|
1330
|
+
);
|
|
1331
|
+
} else {
|
|
1332
|
+
logger.error(`${code}: ${err.message}`);
|
|
1333
|
+
}
|
|
1334
|
+
process.exitCode = 2;
|
|
946
1335
|
}
|
|
947
1336
|
});
|
|
948
1337
|
|
|
@@ -983,20 +1372,80 @@ export function registerCoworkCommand(program) {
|
|
|
983
1372
|
"--definition-digest <sha256>",
|
|
984
1373
|
"Replay an immutable saved definition version",
|
|
985
1374
|
)
|
|
1375
|
+
.option(
|
|
1376
|
+
"--execution-authority-session <id>",
|
|
1377
|
+
"Verified session whose start event anchors execution authority",
|
|
1378
|
+
)
|
|
986
1379
|
.option("--continue-on-error", "Keep running after a step fails", false)
|
|
987
|
-
.option("--max-parallel <n>", "Max parallel steps per batch"
|
|
1380
|
+
.option("--max-parallel <n>", "Max parallel steps per batch")
|
|
1381
|
+
.option(
|
|
1382
|
+
"--durable-run-id <id>",
|
|
1383
|
+
"Use request-before-provider durable runtime with atomic effect batches",
|
|
1384
|
+
)
|
|
988
1385
|
.option(
|
|
989
1386
|
"--pipeline",
|
|
990
1387
|
"No-barrier scheduling: start each step as soon as its own deps finish",
|
|
991
1388
|
false,
|
|
992
1389
|
)
|
|
993
1390
|
.action(async (id, options) => {
|
|
994
|
-
|
|
995
|
-
|
|
1391
|
+
let executionStarted = false;
|
|
1392
|
+
try {
|
|
1393
|
+
let workflowExecutionAuthorityModule;
|
|
1394
|
+
if (Object.hasOwn(commandDeps, "workflowExecutionAuthorityProvider")) {
|
|
1395
|
+
const descriptor = Object.getOwnPropertyDescriptor(
|
|
1396
|
+
commandDeps,
|
|
1397
|
+
"workflowExecutionAuthorityProvider",
|
|
1398
|
+
);
|
|
1399
|
+
if (!descriptor || !Object.hasOwn(descriptor, "value")) {
|
|
1400
|
+
throw new Error(
|
|
1401
|
+
"Cowork workflow authority provider seam must be a data property",
|
|
1402
|
+
);
|
|
1403
|
+
}
|
|
1404
|
+
workflowExecutionAuthorityModule = Promise.resolve({
|
|
1405
|
+
getVerifiedSessionExecutionLocationAuthority: descriptor.value,
|
|
1406
|
+
});
|
|
1407
|
+
} else {
|
|
1408
|
+
workflowExecutionAuthorityModule =
|
|
1409
|
+
import("../harness/jsonl-session-store.js");
|
|
1410
|
+
}
|
|
1411
|
+
let workflowRunTaskModule;
|
|
1412
|
+
if (Object.hasOwn(commandDeps, "workflowRunTask")) {
|
|
1413
|
+
const descriptor = Object.getOwnPropertyDescriptor(
|
|
1414
|
+
commandDeps,
|
|
1415
|
+
"workflowRunTask",
|
|
1416
|
+
);
|
|
1417
|
+
if (!descriptor || !Object.hasOwn(descriptor, "value")) {
|
|
1418
|
+
throw new Error(
|
|
1419
|
+
"Cowork workflow task runner seam must be a data property",
|
|
1420
|
+
);
|
|
1421
|
+
}
|
|
1422
|
+
workflowRunTaskModule = Promise.resolve({
|
|
1423
|
+
runCoworkTask: descriptor.value,
|
|
1424
|
+
});
|
|
1425
|
+
} else {
|
|
1426
|
+
workflowRunTaskModule = import("../lib/cowork-task-runner.js");
|
|
1427
|
+
}
|
|
1428
|
+
const [
|
|
1429
|
+
{ executeWorkflow: executeCoworkWorkflow, getWorkflowVersion },
|
|
1430
|
+
{ executeDynamicWorkflowWithAdmission },
|
|
1431
|
+
{ getVerifiedSessionExecutionLocationAuthority },
|
|
1432
|
+
{ runCoworkTask },
|
|
1433
|
+
] = await Promise.all([
|
|
996
1434
|
import("../lib/cowork-workflow.js"),
|
|
997
|
-
import("../lib/
|
|
1435
|
+
import("../lib/dynamic-workflow-facade.js"),
|
|
1436
|
+
workflowExecutionAuthorityModule,
|
|
1437
|
+
workflowRunTaskModule,
|
|
998
1438
|
]);
|
|
999
|
-
|
|
1439
|
+
if (typeof runCoworkTask !== "function") {
|
|
1440
|
+
throw new Error("Cowork workflow task runner is unavailable");
|
|
1441
|
+
}
|
|
1442
|
+
if (
|
|
1443
|
+
typeof getVerifiedSessionExecutionLocationAuthority !== "function"
|
|
1444
|
+
) {
|
|
1445
|
+
throw new Error(
|
|
1446
|
+
"Cowork workflow execution authority provider is unavailable",
|
|
1447
|
+
);
|
|
1448
|
+
}
|
|
1000
1449
|
const record = await loadCoworkWorkflowRecord(
|
|
1001
1450
|
process.cwd(),
|
|
1002
1451
|
id,
|
|
@@ -1008,33 +1457,79 @@ export function registerCoworkCommand(program) {
|
|
|
1008
1457
|
return;
|
|
1009
1458
|
}
|
|
1010
1459
|
const wf = record.definition;
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
const
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
out
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1460
|
+
const requestedMaxParallel =
|
|
1461
|
+
options.maxParallel || (options.durableRunId ? "1" : "4");
|
|
1462
|
+
const executionAuthoritySessionId =
|
|
1463
|
+
requireWorkflowExecutionAuthoritySession(
|
|
1464
|
+
options.executionAuthoritySession,
|
|
1465
|
+
);
|
|
1466
|
+
const outcome = await executeDynamicWorkflowWithAdmission(
|
|
1467
|
+
{
|
|
1468
|
+
definitionAuthority: record,
|
|
1469
|
+
executionAuthoritySessionId,
|
|
1470
|
+
maxParallel: requestedMaxParallel,
|
|
1471
|
+
execution: {
|
|
1472
|
+
cwd: process.cwd(),
|
|
1473
|
+
continueOnError: !!options.continueOnError,
|
|
1474
|
+
// Omit (rather than pass undefined) when absent so a
|
|
1475
|
+
// workflow-level `pipeline: true` remains authoritative.
|
|
1476
|
+
...(options.pipeline ? { pipeline: true } : {}),
|
|
1477
|
+
onStepStart: ({ stepId }) =>
|
|
1478
|
+
logger.log(chalk.gray(` → step ${stepId} ...`)),
|
|
1479
|
+
onStepComplete: (out) => {
|
|
1480
|
+
const flag =
|
|
1481
|
+
out.status === "completed"
|
|
1482
|
+
? chalk.green("✓")
|
|
1483
|
+
: out.status === "skipped"
|
|
1484
|
+
? chalk.gray("—")
|
|
1485
|
+
: chalk.red("✗");
|
|
1486
|
+
logger.log(` ${flag} ${out.id} (${out.status})`);
|
|
1487
|
+
},
|
|
1488
|
+
},
|
|
1489
|
+
onAdmitted: () => {
|
|
1490
|
+
executionStarted = true;
|
|
1491
|
+
logger.log(
|
|
1492
|
+
chalk.bold(
|
|
1493
|
+
`\nExecuting workflow '${wf.name}' (${wf.steps.length} steps, ${record.definitionDigest})...`,
|
|
1494
|
+
),
|
|
1495
|
+
);
|
|
1496
|
+
},
|
|
1036
1497
|
},
|
|
1037
|
-
|
|
1498
|
+
{
|
|
1499
|
+
verifyAuthorities: (lookup) =>
|
|
1500
|
+
verifyWorkflowRunAuthorities(process.cwd(), lookup, {
|
|
1501
|
+
getWorkflowVersion,
|
|
1502
|
+
getVerifiedSessionExecutionLocationAuthority,
|
|
1503
|
+
}),
|
|
1504
|
+
executeWorkflow: async (execution) => {
|
|
1505
|
+
if (!options.durableRunId) {
|
|
1506
|
+
return executeCoworkWorkflow({
|
|
1507
|
+
...execution,
|
|
1508
|
+
runTask: runCoworkTask,
|
|
1509
|
+
});
|
|
1510
|
+
}
|
|
1511
|
+
const runtime =
|
|
1512
|
+
await import("../lib/dynamic-workflow-runtime.js");
|
|
1513
|
+
return runtime.executeDurableDynamicWorkflow(
|
|
1514
|
+
{
|
|
1515
|
+
statePath: runtime.dynamicWorkflowRunStatePath(
|
|
1516
|
+
process.cwd(),
|
|
1517
|
+
options.durableRunId,
|
|
1518
|
+
),
|
|
1519
|
+
runId: options.durableRunId,
|
|
1520
|
+
execution,
|
|
1521
|
+
},
|
|
1522
|
+
{ runTask: runCoworkTask },
|
|
1523
|
+
);
|
|
1524
|
+
},
|
|
1525
|
+
},
|
|
1526
|
+
);
|
|
1527
|
+
if (!outcome.allowed) {
|
|
1528
|
+
renderWorkflowPreflight(outcome.preflight);
|
|
1529
|
+
process.exitCode = 2;
|
|
1530
|
+
return;
|
|
1531
|
+
}
|
|
1532
|
+
const result = outcome.record;
|
|
1038
1533
|
const color =
|
|
1039
1534
|
result.status === "completed"
|
|
1040
1535
|
? chalk.green
|
|
@@ -1042,9 +1537,11 @@ export function registerCoworkCommand(program) {
|
|
|
1042
1537
|
? chalk.yellow
|
|
1043
1538
|
: chalk.red;
|
|
1044
1539
|
logger.log(color(`\nWorkflow ${result.status}.\n`));
|
|
1540
|
+
process.exitCode = result.status === "completed" ? 0 : 1;
|
|
1045
1541
|
} catch (err) {
|
|
1046
|
-
logger.error(err.message);
|
|
1047
|
-
process.
|
|
1542
|
+
logger.error(`${err.code || "WORKFLOW_RUN_FAILED"}: ${err.message}`);
|
|
1543
|
+
process.exitCode =
|
|
1544
|
+
executionStarted || err.executionStarted === true ? 1 : 2;
|
|
1048
1545
|
}
|
|
1049
1546
|
});
|
|
1050
1547
|
|