chainlesschain 0.163.5 → 0.163.7
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/completions/_cc +1 -1
- package/completions/cc.bash +1 -1
- package/completions/cc.fish +1 -1
- package/completions/cc.ps1 +1 -1
- package/package.json +1 -1
- package/src/assets/web-panel/assets/{AIOps-Cv2EE1Zy.js → AIOps-axqQfwv8.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-CcpxMLuW.js → ActionButton-DV-Ro0By.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-DE8mJoMI.js → Analytics-Bt72WEVu.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-DKn9dk9L.js → AppLayout-BtepG55E.js} +5 -5
- package/src/assets/web-panel/assets/{Artifacts-Cp3mG3Py.js → Artifacts-B7KaJ7S_.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-zvsQfF2C.js → Audit-FNFaUg7A.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-Bi85SsjN.js → BackgroundAgents-DFb6J2wQ.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-Cw47Dj6s.js → Backup-CC7YBhyj.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-C5Ip2afH.js → BaseInput-RkgTNVtj.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-C0iAFkJv.js → Chat-hHEmGZy-.js} +5 -5
- package/src/assets/web-panel/assets/{ChatBubbleRenderer-BV9Wv7wO.js → ChatBubbleRenderer-CAP9YhHv.js} +1 -1
- package/src/assets/web-panel/assets/{Checkbox-3KZZCiAF.js → Checkbox-z5wXOQP1.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-C8OMbBAz.js → Codegen-DVaDJnxy.js} +1 -1
- package/src/assets/web-panel/assets/{Col-B-MB84LJ.js → Col-CJmaRDR5.js} +1 -1
- package/src/assets/web-panel/assets/{Community-DpR7Dxao.js → Community-DF29_2bI.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-CyDtz0OS.js → Compact-DtkQkBzn.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-5tiRa2An.js → Compliance-xoHDxp7I.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-DnQaKZ5x.js → Cowork-BUm-R7ht.js} +4 -4
- package/src/assets/web-panel/assets/{Cron-BaWfoEDf.js → Cron-Cgl14ZkB.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-Bu0HoHhb.js → Crosschain-BNcbmoqh.js} +1 -1
- package/src/assets/web-panel/assets/{DID-31zk8upX.js → DID-Bwja0Zo9.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-BmVne-e2.js → Dashboard-Bk5XjEdJ.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-B4PkoOWd.js → Dropdown-Ci36Oitq.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-BZ6tyFtI.js → EmailListRenderer--U04ZN4q.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-Osozn4Ds.js → FamilyGuardDashboard-B2gNPR2s.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-DaH8TOAP.js → Federation-C4KghYn7.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-tbU0uwis.js → FormItemContext-QL7x_Q_0.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-Df8LQBrL.js → GenericCardRenderer-F3Ryltwm.js} +1 -1
- package/src/assets/web-panel/assets/{Git-DsMB6-14.js → Git-2HassK5k.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-BnH0dZzd.js → Governance-DoBIp7oe.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-DhnN1N_P.js → Inference--W01QhZ-.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-DnNshAgn.js → KnowledgeGraph-DmvwqGpT.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-BmBFX3_N.js → Logs-BBJ4yAel.js} +2 -2
- package/src/assets/web-panel/assets/{MarkdownRenderer-DCslfQU3.js → MarkdownRenderer-BLCZMzhJ.js} +1 -1
- package/src/assets/web-panel/assets/{Marketplace-CPEgWDc3.js → Marketplace-D5lNngSI.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-C36qjgF9.js → McpTools-CkEVOMKH.js} +5 -5
- package/src/assets/web-panel/assets/{Memory-tNHvrgqN.js → Memory-B1Ow1xVE.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-Xaf6cKjc.js → MobileBridge-SgYbUfb6.js} +1 -1
- package/src/assets/web-panel/assets/{MobileProjects-D2E5TTeO.js → MobileProjects-BWdOvQAj.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-D4AJ2dwV.js → Mtc-DcTXSSma.js} +2 -2
- package/src/assets/web-panel/assets/{MtcAudit-Df-gtn2_.js → MtcAudit-Dt3WG4oj.js} +4 -4
- package/src/assets/web-panel/assets/{Multisig-DTCHLWld.js → Multisig-B9B38UZx.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-DruZ_1Jb.js → NLProgramming-B0S4GGvG.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-Dx3pdGDs.js → Notes-DZ5U58Ng.js} +4 -4
- package/src/assets/web-panel/assets/{NotificationSettings-Bi3L69oL.js → NotificationSettings-PjL5ZW34.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-BHY33m7C.js → OrderTableRenderer-DrAX2ESt.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-BG2ZVEV-.js → Organization-Cv1GYs-c.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-Viwtg4Mn.js → Overflow-Bbkp_PL3.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-Clm_yc1Z.js → P2P-BD8QUgoZ.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-NKmmDiOw.js → PdhVaultBrowser-BO-2PeaB.js} +5 -5
- package/src/assets/web-panel/assets/{Permissions-DIL8u9Nk.js → Permissions-D_OPVa02.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-B-jM4wt-.js → PersonalDataHub-mh-pEmaB.js} +4 -4
- package/src/assets/web-panel/assets/{Pipeline-627I__H5.js → Pipeline-6JC2EDdb.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-2DN2qrkW.js → Privacy-CUshzUAG.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-CN4wC0sF.js → ProjectInit-Cs2Aalri.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-K35vsh5H.js → ProjectSettings-1ak49tcj.js} +2 -2
- package/src/assets/web-panel/assets/{Projects-B_wQadhX.js → Projects-BV4oApsm.js} +1 -1
- package/src/assets/web-panel/assets/{Providers-MckaQUhQ.js → Providers-CXXxvafH.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-BS3mtA_O.js → QrScannerModal-PTcDsF58.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-BHp_nofL.js → QuickAsk-CDwucrJw.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-DlmnPuZj.js → Recommend-CJlLVRXR.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-tsyFbvpy.js → RemoteSession-DlN-ETsO.js} +2 -2
- package/src/assets/web-panel/assets/{Reputation-Ba1iWv2D.js → Reputation-DI23LR6m.js} +1 -1
- package/src/assets/web-panel/assets/{Row-NnlGC--f.js → Row-Cl7UQMrM.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-CjThSIRv.js → RssFeed-CexHNfh8.js} +3 -3
- package/src/assets/web-panel/assets/{Search-CojUyC5x.js → Search-BneBWvRN.js} +1 -1
- package/src/assets/web-panel/assets/{Security-c-sxeJEc.js → Security-DX7Phgrp.js} +4 -4
- package/src/assets/web-panel/assets/{Services-CtcKEEmF.js → Services-BWXO8Mte.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-CIBBXflN.js → Skeleton-DCyOjKPJ.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-D1XOOK9n.js → Skills-CXqERsTB.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-hRfEp5Sn.js → Sla-bhbrbz8E.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-Dexb1f_6.js → SpeechSettings-3IPU0HBZ.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-BJsSFGYy.js → SyncSettings-DBNTQLbM.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-CfSZ8A1L.js → Tasks-quP0bkN-.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-idDf47W-.js → Templates-BouWmgho.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-C-UsX6w6.js → Tenant-qv0D9s7z.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-BgJtX5n1.js → Terminal-BxvbE8BB.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-DP0BLKTl.js → TimelineRenderer-D-IeLnJ2.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-LwCzqETp.js → Tokens-CFMKKyVG.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-D_9tVch0.js → Trigger-L8as3UuJ.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-BH2UlEWh.js → Trust-MxmA4VZG.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-CIpD0nYb.js → UkeySign-C0VvJYRi.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-9ShhYxK_.js → VideoEditing-Bf5QZj8N.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-C7afGNIG.js → Wallet-BIJ9riRz.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-bUKn6i5R.js → WebAuthn-B8p9Mhkw.js} +4 -4
- package/src/assets/web-panel/assets/{WorkflowEditor-CxgQaGyp.js → WorkflowEditor-BVsuaPen.js} +1 -1
- package/src/assets/web-panel/assets/{chat-DMVkmJwx.js → chat-BfkjoKpV.js} +1 -1
- package/src/assets/web-panel/assets/{colors-CDzQh5nS.js → colors-DeAlsWK8.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-C51kEF4D.js → compact-item-Cs97bz5j.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-BTk9bXBn.js → createContext-BqbG60LH.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-DPty0mGN.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-CMje33rb.js → hasIn-i_RY0b1X.js} +1 -1
- package/src/assets/web-panel/assets/{index-DpcrFxMI.js → index-0-agYlWL.js} +1 -1
- package/src/assets/web-panel/assets/{index-BW4F5YDF.js → index-79V_zv1s.js} +1 -1
- package/src/assets/web-panel/assets/{index-DRG-aqOs.js → index-B-3tEpTc.js} +1 -1
- package/src/assets/web-panel/assets/{index-BCRvG9lq.js → index-B-JVTrpr.js} +1 -1
- package/src/assets/web-panel/assets/{index-DgivOKHA.js → index-B1CbOH1i.js} +1 -1
- package/src/assets/web-panel/assets/{index-BzCkNylB.js → index-B5UkyA3c.js} +1 -1
- package/src/assets/web-panel/assets/{index-x53Vf7la.js → index-BESLFt4q.js} +1 -1
- package/src/assets/web-panel/assets/{index-CCLj9hcD.js → index-BOVkf1K3.js} +1 -1
- package/src/assets/web-panel/assets/{index-CypsfcEq.js → index-BYUVuwKt.js} +1 -1
- package/src/assets/web-panel/assets/{index-BtlEqHLP.js → index-BcUXAB2s.js} +1 -1
- package/src/assets/web-panel/assets/{index-Ld_4mFmC.js → index-BkBi5TmC.js} +1 -1
- package/src/assets/web-panel/assets/{index-DqU9njjT.js → index-Bm7lLR4c.js} +1 -1
- package/src/assets/web-panel/assets/index-Bt7g0Vq_.js +1 -0
- package/src/assets/web-panel/assets/{index-CwGPwjUu.js → index-BuLQobzW.js} +1 -1
- package/src/assets/web-panel/assets/{index-C5IWTMVl.js → index-CE2VtTlp.js} +1 -1
- package/src/assets/web-panel/assets/{index-DJfnCuMq.js → index-CED2PL_y.js} +1 -1
- package/src/assets/web-panel/assets/{index-hg_emBsi.js → index-CG3PRyAL.js} +1 -1
- package/src/assets/web-panel/assets/{index-togc_uYn.js → index-CIG8fQ2_.js} +1 -1
- package/src/assets/web-panel/assets/{index-C4rQCS8T.js → index-COdGA-8n.js} +1 -1
- package/src/assets/web-panel/assets/{index-0Auljb10.js → index-CeWoNHau.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cd0hmPxD.js → index-Cf3WCLmy.js} +1 -1
- package/src/assets/web-panel/assets/{index-BXQBPLyE.js → index-CgsqdnRV.js} +1 -1
- package/src/assets/web-panel/assets/index-ChVT0p9u.js +1 -0
- package/src/assets/web-panel/assets/{index-h31MwrME.js → index-D2B4VPyP.js} +1 -1
- package/src/assets/web-panel/assets/{index-C1oZReaY.js → index-D9evtvg2.js} +1 -1
- package/src/assets/web-panel/assets/{index-CfC-piWZ.js → index-DUUrv141.js} +1 -1
- package/src/assets/web-panel/assets/{index-D9rC-fGW.js → index-DiSkx4UB.js} +3 -3
- package/src/assets/web-panel/assets/{index-CvSeVzqe.js → index-Dk2qouAz.js} +1 -1
- package/src/assets/web-panel/assets/{index-CtM8OT_7.js → index-Dk7-v4hP.js} +1 -1
- package/src/assets/web-panel/assets/{index-BBz9LIMS.js → index-DmbfhJUP.js} +1 -1
- package/src/assets/web-panel/assets/{index-BAfY7m7i.js → index-DqBgBpgp.js} +1 -1
- package/src/assets/web-panel/assets/{index-BVePe_Rf.js → index-PT_5sBMA.js} +1 -1
- package/src/assets/web-panel/assets/{index-CDLkNkLj.js → index-U4f5izHz.js} +1 -1
- package/src/assets/web-panel/assets/{index-BTlsE8Df.js → index-YXgLng0K.js} +1 -1
- package/src/assets/web-panel/assets/{index-BeEaAEIp.js → index-ZxO_-E8a.js} +1 -1
- package/src/assets/web-panel/assets/{index-B0-zMtKA.js → index-dIHr4B_u.js} +1 -1
- package/src/assets/web-panel/assets/{index-C1oZQmAA.js → index-gyFpvL7l.js} +1 -1
- package/src/assets/web-panel/assets/{index-DRLQyp2A.js → index-s1opAL-M.js} +1 -1
- package/src/assets/web-panel/assets/{index-OS-vfbTA.js → index-yObj1O4n.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-vrA8K-ac.js → initDefaultProps-C9h9yKL3.js} +1 -1
- package/src/assets/web-panel/assets/{motion-ByEzwIAl.js → motion-BvmLsPdu.js} +1 -1
- package/src/assets/web-panel/assets/{move-Ck4AWjw-.js → move-CoL4ekU1.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-6p0l9SrB.js → mtc-parser-C4pMy6xV.js} +1 -1
- package/src/assets/web-panel/assets/{omit-B1CUPQ6R.js → omit-DPuJfNxx.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-B1STg1iW.js → pickAttrs-D0KEeaK2.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-DTTllkBV.js → placementArrow-BpkyINxt.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-AIrrCfBb.js → responsiveObserve-DQI_wOq8.js} +1 -1
- package/src/assets/web-panel/assets/{slide-C_fPMjdR.js → slide-DYfdDiRg.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-D5ow2yIP.js → statusUtils-B5dtvb0D.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-Dy3hEA--.js → styleChecker-CF310mSj.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-WfzcfSh4.js → useFlexGapSupport-D1Qp4BLp.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-CKSejfas.js → useFs-C7_iyvJK.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-od3zpPBN.js → usePersonalDataHub-DZUt_fIm.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-DRD_2DFA.js → vnode-D3dsi0lZ.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-DmNrEtgf.js → zoom-WdbOlvdQ.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/command-help-index.json +5 -5
- package/src/command-manifest.json +1 -1
- package/src/commands/agenda.js +76 -4
- package/src/commands/agent.js +90 -1
- package/src/commands/automation.js +462 -3
- package/src/commands/background-session.js +102 -1
- package/src/commands/chat.js +11 -2
- package/src/commands/compact.js +106 -23
- package/src/commands/cowork.js +6 -1
- package/src/commands/loop.js +187 -38
- package/src/commands/routine.js +12 -5
- package/src/commands/scheduler-daemon.js +807 -0
- package/src/commands/session-observability.js +305 -0
- package/src/commands/session.js +38 -0
- package/src/data/changelog.json +28 -2
- package/src/gateways/ws/ws-agent-handler.js +439 -5
- package/src/harness/jsonl-session-store.js +463 -125
- package/src/harness/prompt-compressor.js +86 -13
- package/src/harness/provider-backed-compaction.js +100 -27
- package/src/lib/advisor-runtime.js +3 -1
- package/src/lib/agent-schedule-store.js +737 -47
- package/src/lib/agent-team/team-adjudication.js +40 -1
- package/src/lib/automation-center-routines.js +363 -0
- package/src/lib/automation-center.js +435 -0
- package/src/lib/automation-engine.js +568 -19
- package/src/lib/automation-execution-authority.js +736 -0
- package/src/lib/background-agent-supervisor.js +871 -215
- package/src/lib/background-command-argv.js +24 -0
- package/src/lib/background-interaction-journal.js +361 -52
- package/src/lib/background-interaction-resolver.js +32 -0
- package/src/lib/background-launch-profile.js +2 -0
- package/src/lib/background-needs-input-incident.js +221 -0
- package/src/lib/causal-observability.js +2661 -0
- package/src/lib/chat-session-admission.js +76 -0
- package/src/lib/cost-budget.js +5 -7
- package/src/lib/cowork/ab-comparator-cli.js +11 -0
- package/src/lib/cowork/debate-review-cli.js +12 -0
- package/src/lib/cowork-adapter.js +159 -38
- package/src/lib/cowork-cron.js +673 -19
- package/src/lib/cowork-observe.js +5 -1
- package/src/lib/cowork-task-runner.js +112 -17
- package/src/lib/delivery-coordinator.js +142 -0
- package/src/lib/direct-model-usage.js +121 -0
- package/src/lib/file-lines.js +183 -47
- package/src/lib/llm-pricing.js +12 -17
- package/src/lib/loop.js +62 -3
- package/src/lib/permission-engine.js +14 -7
- package/src/lib/public-ide-capability-manifest.js +2 -0
- package/src/lib/routine-store.js +546 -86
- package/src/lib/runtime-usage-ledger.js +182 -0
- package/src/lib/scheduler-kernel/agenda-adapter.js +604 -29
- package/src/lib/scheduler-kernel/authority-resolver.js +163 -0
- package/src/lib/scheduler-kernel/automation-adapter.js +994 -0
- package/src/lib/scheduler-kernel/automation-event-adapter.js +757 -0
- package/src/lib/scheduler-kernel/contract.js +11 -3
- package/src/lib/scheduler-kernel/cowork-cron-adapter.js +343 -15
- package/src/lib/scheduler-kernel/loop-adapter.js +913 -0
- package/src/lib/scheduler-kernel/migration-admin.js +346 -0
- package/src/lib/scheduler-kernel/migration-rollback-admin.js +932 -0
- package/src/lib/scheduler-kernel/routine-adapter.js +691 -22
- package/src/lib/scheduler-kernel/runtime.js +63 -1
- package/src/lib/scheduler-kernel/service.js +328 -0
- package/src/lib/scheduler-kernel/source-locator-path.js +142 -0
- package/src/lib/scheduler-kernel/store.js +3439 -206
- package/src/lib/session-host-lease.js +171 -2
- package/src/lib/session-host-snapshot.js +14 -3
- package/src/lib/session-persistence-failure.js +1 -0
- package/src/lib/session-tail.js +179 -34
- package/src/lib/session-transcript-structure.js +96 -0
- package/src/lib/sub-agent-context.js +328 -22
- package/src/lib/ws-agent-handler.js +4 -1
- package/src/repl/agent-repl.js +732 -91
- package/src/repl/chat-repl.js +5 -1
- package/src/runtime/agent-core.js +1274 -208
- package/src/runtime/coding-agent-contract-shared.cjs +5 -0
- package/src/runtime/fallback-model.js +5 -0
- package/src/runtime/headless-runner.js +324 -82
- package/src/runtime/headless-stream.js +232 -26
- package/src/runtime/policies/agent-policy.js +4 -0
- package/src/workers/background-agent-worker.js +468 -98
- package/src/assets/web-panel/assets/devWarning-CdwPwYj8.js +0 -1
- package/src/assets/web-panel/assets/index-BEeOdfEe.js +0 -1
- package/src/assets/web-panel/assets/index-BTe0TOu6.js +0 -1
|
@@ -4,8 +4,30 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import chalk from "chalk";
|
|
7
|
+
import {
|
|
8
|
+
inspectAutomationExecutionAuthority,
|
|
9
|
+
setAutomationExecutionBudget,
|
|
10
|
+
} from "../lib/automation-execution-authority.js";
|
|
11
|
+
import {
|
|
12
|
+
buildAutomationCenterProjection,
|
|
13
|
+
runAutomationCenterAction,
|
|
14
|
+
} from "../lib/automation-center.js";
|
|
15
|
+
import {
|
|
16
|
+
createAutomationCenterRoutine,
|
|
17
|
+
editAutomationCenterRoutine,
|
|
18
|
+
runAutomationCenterRoutineAction,
|
|
19
|
+
} from "../lib/automation-center-routines.js";
|
|
7
20
|
import { logger } from "../lib/logger.js";
|
|
8
21
|
import { parseJsonOption } from "../lib/parse-json-option.js";
|
|
22
|
+
import { AutomationSchedulerBridge } from "../lib/scheduler-kernel/automation-adapter.js";
|
|
23
|
+
import { AutomationEventDispatcher } from "../lib/scheduler-kernel/automation-event-adapter.js";
|
|
24
|
+
import { openSchedulerStore } from "../lib/scheduler-kernel/store.js";
|
|
25
|
+
import {
|
|
26
|
+
RoutineSchedulerBridge,
|
|
27
|
+
routineBridgeRunId,
|
|
28
|
+
} from "../lib/scheduler-kernel/routine-adapter.js";
|
|
29
|
+
import { RoutineStore } from "../lib/routine-store.js";
|
|
30
|
+
import { defaultRunAgent } from "./routine.js";
|
|
9
31
|
import { bootstrap, shutdown } from "../runtime/bootstrap.js";
|
|
10
32
|
import {
|
|
11
33
|
ensureAutomationTables,
|
|
@@ -68,8 +90,56 @@ import {
|
|
|
68
90
|
} from "../lib/automation-engine.js";
|
|
69
91
|
|
|
70
92
|
function _dbFromCtx(cmd) {
|
|
71
|
-
|
|
72
|
-
|
|
93
|
+
let current = cmd;
|
|
94
|
+
while (current) {
|
|
95
|
+
if (current._db) return current._db;
|
|
96
|
+
current = current.parent;
|
|
97
|
+
}
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
async function readBoundedJsonStdin(options, maximum = 80 * 1024) {
|
|
102
|
+
if (options?.jsonStdin !== true) {
|
|
103
|
+
throw new Error("--json-stdin is required for routine definitions");
|
|
104
|
+
}
|
|
105
|
+
let serialized = "";
|
|
106
|
+
for await (const chunk of process.stdin) {
|
|
107
|
+
serialized += chunk;
|
|
108
|
+
if (Buffer.byteLength(serialized, "utf8") > maximum) {
|
|
109
|
+
throw new Error(`routine definition exceeds ${maximum} UTF-8 bytes`);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
let parsed;
|
|
113
|
+
try {
|
|
114
|
+
parsed = JSON.parse(serialized);
|
|
115
|
+
} catch {
|
|
116
|
+
throw new Error("routine definition stdin must be valid JSON");
|
|
117
|
+
}
|
|
118
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
119
|
+
throw new Error("routine definition stdin must be a JSON object");
|
|
120
|
+
}
|
|
121
|
+
return parsed;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
async function triggerCenterRoutine(store, routine) {
|
|
125
|
+
const schedulerStore = openSchedulerStore();
|
|
126
|
+
try {
|
|
127
|
+
const bridge = new RoutineSchedulerBridge({
|
|
128
|
+
routineStore: store,
|
|
129
|
+
schedulerStore,
|
|
130
|
+
runAgent: defaultRunAgent,
|
|
131
|
+
});
|
|
132
|
+
const fired = await bridge.trigger(routine);
|
|
133
|
+
const runId = routineBridgeRunId(fired);
|
|
134
|
+
if (!runId) {
|
|
135
|
+
throw new Error(
|
|
136
|
+
`routine occurrence did not execute: ${fired.result?.status || "unknown"}`,
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
return store.getRun(runId) || { runId, status: "unknown" };
|
|
140
|
+
} finally {
|
|
141
|
+
schedulerStore.close();
|
|
142
|
+
}
|
|
73
143
|
}
|
|
74
144
|
|
|
75
145
|
async function _prepare(cmd) {
|
|
@@ -84,6 +154,129 @@ async function _prepare(cmd) {
|
|
|
84
154
|
return db;
|
|
85
155
|
}
|
|
86
156
|
|
|
157
|
+
export async function runAutomationScheduled(db, options = {}, _deps = {}) {
|
|
158
|
+
const log = _deps.log || ((message) => console.log(message));
|
|
159
|
+
let schedulerStore = _deps.schedulerStore;
|
|
160
|
+
const ownsSchedulerStore = schedulerStore == null;
|
|
161
|
+
try {
|
|
162
|
+
schedulerStore ||= openSchedulerStore();
|
|
163
|
+
const bridge = new AutomationSchedulerBridge({
|
|
164
|
+
db,
|
|
165
|
+
schedulerStore,
|
|
166
|
+
now: _deps.now || Date.now,
|
|
167
|
+
...(_deps.ownerId === undefined ? {} : { ownerId: _deps.ownerId }),
|
|
168
|
+
...(options.leaseMs === undefined
|
|
169
|
+
? {}
|
|
170
|
+
: { leaseMs: Number(options.leaseMs) }),
|
|
171
|
+
});
|
|
172
|
+
const results = await bridge.runDue({ signal: _deps.signal });
|
|
173
|
+
const summary = results.map((entry) => ({
|
|
174
|
+
flow: entry.flow,
|
|
175
|
+
occurrence: entry.occurrence,
|
|
176
|
+
status: entry.result?.status ?? "unknown",
|
|
177
|
+
recovered: entry.recovered === true,
|
|
178
|
+
deduplicated: entry.deduplicated === true,
|
|
179
|
+
executionId:
|
|
180
|
+
typeof entry.result?.result?.id === "string"
|
|
181
|
+
? entry.result.result.id
|
|
182
|
+
: null,
|
|
183
|
+
error: entry.result?.error ?? null,
|
|
184
|
+
}));
|
|
185
|
+
if (options.json) {
|
|
186
|
+
log(
|
|
187
|
+
JSON.stringify({ due: summary.length, executions: summary }, null, 2),
|
|
188
|
+
);
|
|
189
|
+
} else if (summary.length === 0) {
|
|
190
|
+
log(chalk.gray("Nothing due."));
|
|
191
|
+
} else {
|
|
192
|
+
for (const entry of summary) {
|
|
193
|
+
const color = entry.status === "succeeded" ? chalk.green : chalk.red;
|
|
194
|
+
log(
|
|
195
|
+
color(
|
|
196
|
+
`${entry.flow} → ${entry.status}${entry.executionId ? ` (${entry.executionId})` : ""}`,
|
|
197
|
+
),
|
|
198
|
+
);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
return summary.some(
|
|
202
|
+
(entry) =>
|
|
203
|
+
entry.status !== "succeeded" &&
|
|
204
|
+
entry.status !== "idle" &&
|
|
205
|
+
entry.status !== "busy",
|
|
206
|
+
)
|
|
207
|
+
? 1
|
|
208
|
+
: 0;
|
|
209
|
+
} finally {
|
|
210
|
+
if (ownsSchedulerStore) schedulerStore?.close();
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
export async function runAutomationChannelEvent(db, options = {}, _deps = {}) {
|
|
215
|
+
const log = _deps.log || ((message) => console.log(message));
|
|
216
|
+
let schedulerStore = _deps.schedulerStore;
|
|
217
|
+
const ownsSchedulerStore = schedulerStore == null;
|
|
218
|
+
try {
|
|
219
|
+
schedulerStore ||= openSchedulerStore();
|
|
220
|
+
const dispatcher = new AutomationEventDispatcher({
|
|
221
|
+
db,
|
|
222
|
+
schedulerStore,
|
|
223
|
+
now: _deps.now || Date.now,
|
|
224
|
+
...(_deps.ownerId === undefined ? {} : { ownerId: _deps.ownerId }),
|
|
225
|
+
...(options.leaseMs === undefined
|
|
226
|
+
? {}
|
|
227
|
+
: { leaseMs: Number(options.leaseMs) }),
|
|
228
|
+
});
|
|
229
|
+
const result = await dispatcher.dispatch(
|
|
230
|
+
{
|
|
231
|
+
id: options.eventId,
|
|
232
|
+
type: "channel.event",
|
|
233
|
+
origin: options.origin,
|
|
234
|
+
sender: options.sender || null,
|
|
235
|
+
text: options.text,
|
|
236
|
+
meta: options.meta || {},
|
|
237
|
+
producedAt:
|
|
238
|
+
options.producedAt === undefined
|
|
239
|
+
? Number((_deps.now || Date.now)())
|
|
240
|
+
: Number(options.producedAt),
|
|
241
|
+
},
|
|
242
|
+
{ signal: _deps.signal },
|
|
243
|
+
);
|
|
244
|
+
const summary = {
|
|
245
|
+
eventId: result.eventId,
|
|
246
|
+
matched: result.matched,
|
|
247
|
+
rejected: result.rejected,
|
|
248
|
+
executions: result.results.map((entry) => ({
|
|
249
|
+
flowId: entry.flowId,
|
|
250
|
+
triggerId: entry.triggerId,
|
|
251
|
+
occurrenceId: entry.occurrenceId,
|
|
252
|
+
deduplicated: entry.deduplicated,
|
|
253
|
+
status: entry.result?.status || "unknown",
|
|
254
|
+
executionId: entry.result?.result?.id || null,
|
|
255
|
+
error: entry.result?.error || null,
|
|
256
|
+
})),
|
|
257
|
+
};
|
|
258
|
+
if (options.json) {
|
|
259
|
+
log(JSON.stringify(summary, null, 2));
|
|
260
|
+
} else if (summary.matched === 0) {
|
|
261
|
+
log(
|
|
262
|
+
chalk.gray(`No scoped automation trigger matched ${summary.eventId}.`),
|
|
263
|
+
);
|
|
264
|
+
} else {
|
|
265
|
+
for (const entry of summary.executions) {
|
|
266
|
+
const color = entry.status === "succeeded" ? chalk.green : chalk.red;
|
|
267
|
+
log(
|
|
268
|
+
color(
|
|
269
|
+
`${entry.triggerId} → ${entry.status}${entry.executionId ? ` (${entry.executionId})` : ""}`,
|
|
270
|
+
),
|
|
271
|
+
);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
return summary;
|
|
275
|
+
} finally {
|
|
276
|
+
if (ownsSchedulerStore) schedulerStore?.close();
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
87
280
|
export function registerAutomationCommand(program) {
|
|
88
281
|
const make = (name) => {
|
|
89
282
|
const cmd = program
|
|
@@ -92,7 +285,12 @@ export function registerAutomationCommand(program) {
|
|
|
92
285
|
"Workflow automation engine — 12 SaaS connectors + triggers (Phase 96)",
|
|
93
286
|
)
|
|
94
287
|
.hook("preAction", async (thisCommand, actionCommand) => {
|
|
95
|
-
if (
|
|
288
|
+
if (
|
|
289
|
+
actionCommand &&
|
|
290
|
+
(actionCommand.name().endsWith("-v2") ||
|
|
291
|
+
actionCommand.name().startsWith("center-routine-"))
|
|
292
|
+
)
|
|
293
|
+
return;
|
|
96
294
|
const db = await _prepare(thisCommand);
|
|
97
295
|
thisCommand._db = db;
|
|
98
296
|
});
|
|
@@ -241,6 +439,140 @@ function _wire(root) {
|
|
|
241
439
|
}
|
|
242
440
|
});
|
|
243
441
|
|
|
442
|
+
root
|
|
443
|
+
.command("center-projection")
|
|
444
|
+
.description("Emit the versioned Automation Center projection for IDEs")
|
|
445
|
+
.option("-l, --limit <n>", "Maximum flows", "100")
|
|
446
|
+
.option("--json", "Output as JSON")
|
|
447
|
+
.action(async (opts, cmd) => {
|
|
448
|
+
const db = _dbFromCtx(cmd);
|
|
449
|
+
try {
|
|
450
|
+
const projection = buildAutomationCenterProjection(db, {
|
|
451
|
+
limit: Number(opts.limit),
|
|
452
|
+
});
|
|
453
|
+
if (opts.json) console.log(JSON.stringify(projection, null, 2));
|
|
454
|
+
else {
|
|
455
|
+
logger.info(
|
|
456
|
+
`${projection.summary.total} items (${projection.summary.flows} flows, ${projection.summary.routines} routines), ${projection.summary.needsAttention} need attention`,
|
|
457
|
+
);
|
|
458
|
+
for (const flow of projection.items) {
|
|
459
|
+
logger.log(
|
|
460
|
+
` ${chalk.cyan(flow.id)} ${flow.kind.padEnd(7)} ${flow.status.padEnd(8)} ${flow.name} preflight=${flow.security.state}`,
|
|
461
|
+
);
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
} catch (e) {
|
|
465
|
+
logger.error(e.message);
|
|
466
|
+
process.exitCode = 1;
|
|
467
|
+
} finally {
|
|
468
|
+
await shutdown();
|
|
469
|
+
}
|
|
470
|
+
});
|
|
471
|
+
|
|
472
|
+
root
|
|
473
|
+
.command("center-routine-create")
|
|
474
|
+
.description("Create a revision-gated Routine from JSON stdin")
|
|
475
|
+
.requiredOption(
|
|
476
|
+
"--expected-revision <revision>",
|
|
477
|
+
"Exact Routine catalog revision shown by center-projection",
|
|
478
|
+
)
|
|
479
|
+
.requiredOption("--json-stdin", "Read the Routine definition from stdin")
|
|
480
|
+
.option("--json", "Output as JSON")
|
|
481
|
+
.action(async (opts) => {
|
|
482
|
+
try {
|
|
483
|
+
const result = createAutomationCenterRoutine(new RoutineStore(), {
|
|
484
|
+
expectedRevision: opts.expectedRevision,
|
|
485
|
+
definition: await readBoundedJsonStdin(opts),
|
|
486
|
+
});
|
|
487
|
+
if (opts.json) console.log(JSON.stringify(result, null, 2));
|
|
488
|
+
else logger.success(`Created routine ${result.routineId}`);
|
|
489
|
+
} catch (e) {
|
|
490
|
+
logger.error(e.message);
|
|
491
|
+
process.exitCode = 1;
|
|
492
|
+
} finally {
|
|
493
|
+
await shutdown();
|
|
494
|
+
}
|
|
495
|
+
});
|
|
496
|
+
|
|
497
|
+
root
|
|
498
|
+
.command("center-routine-edit <routineId>")
|
|
499
|
+
.description("Edit a revision-gated Routine from JSON stdin")
|
|
500
|
+
.requiredOption(
|
|
501
|
+
"--expected-revision <revision>",
|
|
502
|
+
"Exact Routine item revision shown by center-projection",
|
|
503
|
+
)
|
|
504
|
+
.requiredOption("--json-stdin", "Read the Routine definition from stdin")
|
|
505
|
+
.option("--json", "Output as JSON")
|
|
506
|
+
.action(async (routineId, opts) => {
|
|
507
|
+
try {
|
|
508
|
+
const result = editAutomationCenterRoutine(new RoutineStore(), {
|
|
509
|
+
routineId,
|
|
510
|
+
expectedRevision: opts.expectedRevision,
|
|
511
|
+
definition: await readBoundedJsonStdin(opts),
|
|
512
|
+
});
|
|
513
|
+
if (opts.json) console.log(JSON.stringify(result, null, 2));
|
|
514
|
+
else logger.success(`Edited routine ${result.routineId}`);
|
|
515
|
+
} catch (e) {
|
|
516
|
+
logger.error(e.message);
|
|
517
|
+
process.exitCode = 1;
|
|
518
|
+
} finally {
|
|
519
|
+
await shutdown();
|
|
520
|
+
}
|
|
521
|
+
});
|
|
522
|
+
|
|
523
|
+
root
|
|
524
|
+
.command("center-routine-action <routineId> <action>")
|
|
525
|
+
.description("Run a revision-gated Routine action")
|
|
526
|
+
.requiredOption(
|
|
527
|
+
"--expected-revision <revision>",
|
|
528
|
+
"Exact Routine item revision shown by center-projection",
|
|
529
|
+
)
|
|
530
|
+
.option("--json", "Output as JSON")
|
|
531
|
+
.action(async (routineId, action, opts) => {
|
|
532
|
+
try {
|
|
533
|
+
const store = new RoutineStore();
|
|
534
|
+
const result = await runAutomationCenterRoutineAction(store, {
|
|
535
|
+
routineId,
|
|
536
|
+
action,
|
|
537
|
+
expectedRevision: opts.expectedRevision,
|
|
538
|
+
triggerRoutine: (routine) => triggerCenterRoutine(store, routine),
|
|
539
|
+
});
|
|
540
|
+
if (opts.json) console.log(JSON.stringify(result, null, 2));
|
|
541
|
+
else logger.success(`${routineId} ${action} completed`);
|
|
542
|
+
} catch (e) {
|
|
543
|
+
logger.error(e.message);
|
|
544
|
+
process.exitCode = 1;
|
|
545
|
+
} finally {
|
|
546
|
+
await shutdown();
|
|
547
|
+
}
|
|
548
|
+
});
|
|
549
|
+
|
|
550
|
+
root
|
|
551
|
+
.command("center-action <flowId> <action>")
|
|
552
|
+
.description("Run a revision-gated Automation Center action")
|
|
553
|
+
.requiredOption(
|
|
554
|
+
"--expected-revision <revision>",
|
|
555
|
+
"Exact flow revision shown by center-projection",
|
|
556
|
+
)
|
|
557
|
+
.option("--json", "Output as JSON")
|
|
558
|
+
.action(async (flowId, action, opts, cmd) => {
|
|
559
|
+
const db = _dbFromCtx(cmd);
|
|
560
|
+
try {
|
|
561
|
+
const result = runAutomationCenterAction(db, {
|
|
562
|
+
flowId,
|
|
563
|
+
action,
|
|
564
|
+
expectedRevision: opts.expectedRevision,
|
|
565
|
+
});
|
|
566
|
+
if (opts.json) console.log(JSON.stringify(result, null, 2));
|
|
567
|
+
else logger.success(`${flowId} ${action} completed`);
|
|
568
|
+
} catch (e) {
|
|
569
|
+
logger.error(e.message);
|
|
570
|
+
process.exitCode = 1;
|
|
571
|
+
} finally {
|
|
572
|
+
await shutdown();
|
|
573
|
+
}
|
|
574
|
+
});
|
|
575
|
+
|
|
244
576
|
root
|
|
245
577
|
.command("show <flowId>")
|
|
246
578
|
.description("Show flow detail")
|
|
@@ -360,6 +692,94 @@ function _wire(root) {
|
|
|
360
692
|
}
|
|
361
693
|
});
|
|
362
694
|
|
|
695
|
+
root
|
|
696
|
+
.command("run-scheduled")
|
|
697
|
+
.description("Run due cron flows through the durable scheduler kernel")
|
|
698
|
+
.option("--json", "Output as JSON")
|
|
699
|
+
.option("--lease-ms <ms>", "Scheduler execution lease in milliseconds")
|
|
700
|
+
.action(async (opts, cmd) => {
|
|
701
|
+
const db = _dbFromCtx(cmd);
|
|
702
|
+
try {
|
|
703
|
+
const code = await runAutomationScheduled(db, opts);
|
|
704
|
+
if (code !== 0) process.exitCode = code;
|
|
705
|
+
} catch (e) {
|
|
706
|
+
logger.error(e.message);
|
|
707
|
+
process.exitCode = 1;
|
|
708
|
+
} finally {
|
|
709
|
+
await shutdown();
|
|
710
|
+
}
|
|
711
|
+
});
|
|
712
|
+
|
|
713
|
+
root
|
|
714
|
+
.command("set-execution-budget <flowId>")
|
|
715
|
+
.description("Set the durable unattended-execution budget for a flow")
|
|
716
|
+
.requiredOption("--window-ms <ms>", "Fixed budget window in milliseconds")
|
|
717
|
+
.requiredOption("--max-runs <n>", "Maximum executions per window")
|
|
718
|
+
.requiredOption(
|
|
719
|
+
"--max-action-steps <n>",
|
|
720
|
+
"Maximum connector action steps per window",
|
|
721
|
+
)
|
|
722
|
+
.option("--json", "Output as JSON")
|
|
723
|
+
.action(async (flowId, opts, cmd) => {
|
|
724
|
+
const db = _dbFromCtx(cmd);
|
|
725
|
+
try {
|
|
726
|
+
const budget = setAutomationExecutionBudget(db, flowId, {
|
|
727
|
+
windowMs: Number(opts.windowMs),
|
|
728
|
+
maxRuns: Number(opts.maxRuns),
|
|
729
|
+
maxActionSteps: Number(opts.maxActionSteps),
|
|
730
|
+
});
|
|
731
|
+
if (opts.json) console.log(JSON.stringify(budget, null, 2));
|
|
732
|
+
else {
|
|
733
|
+
logger.success(`Execution budget set for ${flowId}`);
|
|
734
|
+
logger.log(
|
|
735
|
+
` revision=${budget.revision} window=${budget.windowMs}ms runs=${budget.maxRuns} actionSteps=${budget.maxActionSteps}`,
|
|
736
|
+
);
|
|
737
|
+
}
|
|
738
|
+
} catch (e) {
|
|
739
|
+
logger.error(e.message);
|
|
740
|
+
process.exitCode = 1;
|
|
741
|
+
} finally {
|
|
742
|
+
await shutdown();
|
|
743
|
+
}
|
|
744
|
+
});
|
|
745
|
+
|
|
746
|
+
root
|
|
747
|
+
.command("execution-preflight <flowId>")
|
|
748
|
+
.description(
|
|
749
|
+
"Check live RBAC connector permissions and durable budget availability",
|
|
750
|
+
)
|
|
751
|
+
.option("--json", "Output as JSON")
|
|
752
|
+
.action(async (flowId, opts, cmd) => {
|
|
753
|
+
const db = _dbFromCtx(cmd);
|
|
754
|
+
try {
|
|
755
|
+
const flow = getFlow(db, flowId);
|
|
756
|
+
if (!flow) throw new Error(`Flow not found: ${flowId}`);
|
|
757
|
+
const result = inspectAutomationExecutionAuthority(db, flow);
|
|
758
|
+
if (opts.json) console.log(JSON.stringify(result, null, 2));
|
|
759
|
+
else {
|
|
760
|
+
const color = result.ready ? chalk.green : chalk.red;
|
|
761
|
+
logger.log(
|
|
762
|
+
color(`Execution preflight: ${result.ready ? "READY" : "DENIED"}`),
|
|
763
|
+
);
|
|
764
|
+
logger.log(` principal: ${result.snapshot.principalId}`);
|
|
765
|
+
for (const permission of result.permissions) {
|
|
766
|
+
logger.log(
|
|
767
|
+
` ${permission.allowed ? "ALLOW" : "DENY "} ${permission.permission}`,
|
|
768
|
+
);
|
|
769
|
+
}
|
|
770
|
+
logger.log(
|
|
771
|
+
` remaining: runs=${result.window.remainingRuns} actionSteps=${result.window.remainingActionSteps}`,
|
|
772
|
+
);
|
|
773
|
+
}
|
|
774
|
+
if (!result.ready) process.exitCode = 1;
|
|
775
|
+
} catch (e) {
|
|
776
|
+
logger.error(e.message);
|
|
777
|
+
process.exitCode = 1;
|
|
778
|
+
} finally {
|
|
779
|
+
await shutdown();
|
|
780
|
+
}
|
|
781
|
+
});
|
|
782
|
+
|
|
363
783
|
root
|
|
364
784
|
.command("share <flowId>")
|
|
365
785
|
.description("Record flow share to another org")
|
|
@@ -530,6 +950,45 @@ function _wire(root) {
|
|
|
530
950
|
}
|
|
531
951
|
});
|
|
532
952
|
|
|
953
|
+
root
|
|
954
|
+
.command("dispatch-channel-event")
|
|
955
|
+
.description(
|
|
956
|
+
"Dispatch one durable, scope-checked webhook or Telegram event",
|
|
957
|
+
)
|
|
958
|
+
.requiredOption(
|
|
959
|
+
"--event-id <id>",
|
|
960
|
+
"Stable source event id for deduplication",
|
|
961
|
+
)
|
|
962
|
+
.requiredOption("--origin <origin>", "Event origin (webhook|telegram)")
|
|
963
|
+
.requiredOption("--text <text>", "Inbound event text")
|
|
964
|
+
.option("--sender <id>", "Inbound sender id")
|
|
965
|
+
.option("--meta <json>", "Bounded event metadata as JSON")
|
|
966
|
+
.option("--produced-at <ms>", "Trusted source event epoch milliseconds")
|
|
967
|
+
.option("--lease-ms <ms>", "Scheduler execution lease milliseconds")
|
|
968
|
+
.option("--json", "Output as JSON")
|
|
969
|
+
.action(async (opts, cmd) => {
|
|
970
|
+
const db = _dbFromCtx(cmd);
|
|
971
|
+
try {
|
|
972
|
+
const summary = await runAutomationChannelEvent(db, {
|
|
973
|
+
...opts,
|
|
974
|
+
meta: parseJsonOption(opts.meta, "--meta") || {},
|
|
975
|
+
});
|
|
976
|
+
if (
|
|
977
|
+
summary.rejected.length > 0 ||
|
|
978
|
+
summary.executions.some(
|
|
979
|
+
(entry) => !["succeeded", "busy"].includes(entry.status),
|
|
980
|
+
)
|
|
981
|
+
) {
|
|
982
|
+
process.exitCode = 1;
|
|
983
|
+
}
|
|
984
|
+
} catch (e) {
|
|
985
|
+
logger.error(e.message);
|
|
986
|
+
process.exitCode = 1;
|
|
987
|
+
} finally {
|
|
988
|
+
await shutdown();
|
|
989
|
+
}
|
|
990
|
+
});
|
|
991
|
+
|
|
533
992
|
// ─── Execution ────────────────────────────────────────────
|
|
534
993
|
|
|
535
994
|
root
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
} from "../lib/collaboration-run-store.js";
|
|
10
10
|
import { readSessionHostResumeState } from "../lib/session-host-snapshot.js";
|
|
11
11
|
import executionBroker from "../lib/process-execution-broker/index.js";
|
|
12
|
+
import { registerSchedulerDaemonCommands } from "./scheduler-daemon.js";
|
|
12
13
|
|
|
13
14
|
export function buildBackgroundDispatchArgs(prompt) {
|
|
14
15
|
return ["agent", "--bg", `--print=${prompt}`];
|
|
@@ -100,6 +101,21 @@ export function formatBackgroundAgentDetails(
|
|
|
100
101
|
);
|
|
101
102
|
}
|
|
102
103
|
if (session.phase) lines.push(` phase: ${session.phase}`);
|
|
104
|
+
if (session.pendingQuestion) {
|
|
105
|
+
const prompt = String(
|
|
106
|
+
session.pendingQuestion.prompt || session.pendingQuestion.question || "",
|
|
107
|
+
)
|
|
108
|
+
.replace(/\s+/gu, " ")
|
|
109
|
+
.trim()
|
|
110
|
+
.slice(0, 240);
|
|
111
|
+
lines.push(` needsInput: ${prompt || "question pending"}`);
|
|
112
|
+
}
|
|
113
|
+
if (session.needsInputIncident) {
|
|
114
|
+
const incident = session.needsInputIncident;
|
|
115
|
+
lines.push(
|
|
116
|
+
` needsInputIncident: ${incident.incidentId || "-"} status=${incident.status || "?"} notification=${incident.notification?.status || "?"}`,
|
|
117
|
+
);
|
|
118
|
+
}
|
|
103
119
|
if (session.pr?.number) {
|
|
104
120
|
lines.push(
|
|
105
121
|
` pr: #${session.pr.number}${session.pr.state ? ` ${session.pr.state}` : ""}${session.pr.url ? ` ${session.pr.url}` : ""}`,
|
|
@@ -120,6 +136,19 @@ export function formatBackgroundAgentDetails(
|
|
|
120
136
|
lines.push("", "Commands:");
|
|
121
137
|
lines.push(` cc attach ${session.id}`);
|
|
122
138
|
lines.push(` cc logs ${session.id} -n 100`);
|
|
139
|
+
if (
|
|
140
|
+
["failed", "unconfigured"].includes(
|
|
141
|
+
session.needsInputIncident?.notification?.status,
|
|
142
|
+
)
|
|
143
|
+
) {
|
|
144
|
+
lines.push(` cc daemon notify-needs-input ${session.id}`);
|
|
145
|
+
} else if (
|
|
146
|
+
["delivering", "outcome_unknown", "partial"].includes(
|
|
147
|
+
session.needsInputIncident?.notification?.status,
|
|
148
|
+
)
|
|
149
|
+
) {
|
|
150
|
+
lines.push(` cc daemon notify-needs-input ${session.id} --force`);
|
|
151
|
+
}
|
|
123
152
|
if (session.status === "running") {
|
|
124
153
|
lines.push(` cc daemon stop ${session.id}`);
|
|
125
154
|
}
|
|
@@ -275,6 +304,49 @@ export async function replyBackgroundAgent(id, prompt, dependencies = {}) {
|
|
|
275
304
|
}
|
|
276
305
|
}
|
|
277
306
|
|
|
307
|
+
export async function retryBackgroundNeedsInputNotification(
|
|
308
|
+
id,
|
|
309
|
+
options = {},
|
|
310
|
+
dependencies = {},
|
|
311
|
+
) {
|
|
312
|
+
const sessionId = String(id || "").trim();
|
|
313
|
+
if (!sessionId) throw new Error("background agent id is required");
|
|
314
|
+
const supervisor = dependencies.supervisor || (await loadSupervisor());
|
|
315
|
+
const state = supervisor.readBackgroundAgentState(sessionId);
|
|
316
|
+
if (!state) throw new Error(`Background agent not found: ${sessionId}`);
|
|
317
|
+
if (!state.needsInputIncident) {
|
|
318
|
+
throw new Error(
|
|
319
|
+
`Background agent ${sessionId} has no needs-input incident`,
|
|
320
|
+
);
|
|
321
|
+
}
|
|
322
|
+
const result = await supervisor.deliverBackgroundNeedsInputNotification(
|
|
323
|
+
sessionId,
|
|
324
|
+
{
|
|
325
|
+
retry: true,
|
|
326
|
+
force: options.force === true,
|
|
327
|
+
...(dependencies.notify ? { notify: dependencies.notify } : {}),
|
|
328
|
+
},
|
|
329
|
+
);
|
|
330
|
+
if (!result.applied) {
|
|
331
|
+
const error = new Error(
|
|
332
|
+
result.reason === "delivery_in_progress"
|
|
333
|
+
? `Needs-input notification is already being delivered for ${sessionId}`
|
|
334
|
+
: result.reason === "delivery_not_retryable"
|
|
335
|
+
? `Needs-input notification for ${sessionId} is not safely retryable; use --force only after accepting possible duplicate delivery`
|
|
336
|
+
: `Background agent ${sessionId} no longer has a pending needs-input incident`,
|
|
337
|
+
);
|
|
338
|
+
error.code = "BACKGROUND_NEEDS_INPUT_NOTIFICATION_NOT_RETRYABLE";
|
|
339
|
+
error.reason = result.reason;
|
|
340
|
+
throw error;
|
|
341
|
+
}
|
|
342
|
+
return {
|
|
343
|
+
id: sessionId,
|
|
344
|
+
incidentId: result.incident?.incidentId || null,
|
|
345
|
+
incidentStatus: result.incident?.status || null,
|
|
346
|
+
notification: result.incident?.notification || null,
|
|
347
|
+
};
|
|
348
|
+
}
|
|
349
|
+
|
|
278
350
|
export const LOG_TRUNCATION_NOTICE =
|
|
279
351
|
"--- log truncated/rotated, resuming from tail ---";
|
|
280
352
|
const TRUNCATION_RESUME_TAIL_BYTES = 4096;
|
|
@@ -825,7 +897,36 @@ export function registerBackgroundSessionCommands(program) {
|
|
|
825
897
|
|
|
826
898
|
const daemon = program
|
|
827
899
|
.command("daemon")
|
|
828
|
-
.description("
|
|
900
|
+
.description("Manage background agent and scheduler services");
|
|
901
|
+
|
|
902
|
+
registerSchedulerDaemonCommands(daemon);
|
|
903
|
+
|
|
904
|
+
daemon
|
|
905
|
+
.command("notify-needs-input <id>")
|
|
906
|
+
.description(
|
|
907
|
+
"Retry a durable needs-input notification for a background run",
|
|
908
|
+
)
|
|
909
|
+
.option(
|
|
910
|
+
"--force",
|
|
911
|
+
"Retry an ambiguous or already-delivered notification (may duplicate)",
|
|
912
|
+
)
|
|
913
|
+
.option("--json", "Output as JSON")
|
|
914
|
+
.action(async (id, options) => {
|
|
915
|
+
try {
|
|
916
|
+
const result = await retryBackgroundNeedsInputNotification(id, options);
|
|
917
|
+
if (options.json) console.log(JSON.stringify(result, null, 2));
|
|
918
|
+
else {
|
|
919
|
+
logger.log(
|
|
920
|
+
chalk.green(
|
|
921
|
+
`Needs-input notification ${result.notification?.status || "settled"} for ${id}`,
|
|
922
|
+
),
|
|
923
|
+
);
|
|
924
|
+
}
|
|
925
|
+
} catch (error) {
|
|
926
|
+
logger.error(chalk.red(error.message));
|
|
927
|
+
process.exitCode = 1;
|
|
928
|
+
}
|
|
929
|
+
});
|
|
829
930
|
|
|
830
931
|
daemon
|
|
831
932
|
.command("status")
|
package/src/commands/chat.js
CHANGED
|
@@ -4,8 +4,16 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { createAgentRuntimeFactory } from "../runtime/runtime-factory.js";
|
|
7
|
+
import { assertChatSessionUsageAdmission } from "../lib/chat-session-admission.js";
|
|
7
8
|
|
|
8
|
-
export
|
|
9
|
+
export { assertChatSessionUsageAdmission } from "../lib/chat-session-admission.js";
|
|
10
|
+
|
|
11
|
+
export function registerChatCommand(program, dependencies = {}) {
|
|
12
|
+
const createRuntimeFactory =
|
|
13
|
+
dependencies.createAgentRuntimeFactory || createAgentRuntimeFactory;
|
|
14
|
+
const assertUsageAdmission =
|
|
15
|
+
dependencies.assertChatSessionUsageAdmission ||
|
|
16
|
+
assertChatSessionUsageAdmission;
|
|
9
17
|
program
|
|
10
18
|
.command("chat")
|
|
11
19
|
.description("Start an interactive AI chat session")
|
|
@@ -22,7 +30,8 @@ export function registerChatCommand(program) {
|
|
|
22
30
|
)
|
|
23
31
|
.option("--session <id>", "Resume a previous session (agent mode)")
|
|
24
32
|
.action(async (options) => {
|
|
25
|
-
|
|
33
|
+
if (!options.agent) assertUsageAdmission(options.session);
|
|
34
|
+
const factory = createRuntimeFactory();
|
|
26
35
|
const runtimeOptions = {
|
|
27
36
|
model: options.model,
|
|
28
37
|
provider: options.provider,
|