chainlesschain 0.165.1 → 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 +4 -1
- package/src/assets/web-panel/assets/{AIOps-CYxFDrcm.js → AIOps-lS1R0Cza.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-CPBtdiU2.js → ActionButton-BmlgBPsj.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-Dayq7Dp7.js → Analytics-CNKczv1S.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-6U7bPb2s.js → AppLayout-BuZGJARQ.js} +4 -4
- package/src/assets/web-panel/assets/{Artifacts-D2Iqg_3D.js → Artifacts-Dm73Sl-O.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-CdoOB7WV.js → Audit-BGMW7A5e.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-DrnAVB8w.js → BackgroundAgents-BQ6M54JR.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-CesMi5cy.js → Backup-DBzGP0bR.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-DaX9ptax.js → BaseInput-D1mLCoOV.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-OrwOPxDS.js → Chat-BUfcN7p8.js} +4 -4
- package/src/assets/web-panel/assets/{ChatBubbleRenderer-CvPZFRxM.js → ChatBubbleRenderer-CY5m8ZHg.js} +1 -1
- package/src/assets/web-panel/assets/{Checkbox-DiHbcysC.js → Checkbox-Du0Yg5Pi.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-CbgCkaBJ.js → Codegen-B2RXziHW.js} +1 -1
- package/src/assets/web-panel/assets/{Col-Du5hgrh4.js → Col-DWhekOrR.js} +1 -1
- package/src/assets/web-panel/assets/{Community-DsPOBW-p.js → Community-HQhrkon4.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-BwHIFkNC.js → Compact-izHNb4uz.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-BvrDQSgd.js → Compliance-BDwLy41-.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-gwAE6arx.js → Cowork-DFJhLa7K.js} +3 -3
- package/src/assets/web-panel/assets/{Cron-DW-0l4uF.js → Cron-DYY9RG7-.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-j-NsLesB.js → Crosschain-rr7tJTtv.js} +1 -1
- package/src/assets/web-panel/assets/{DID-CibVEBOI.js → DID-D2sfHRLi.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-W4z9vSfe.js → Dashboard-q_eGdhha.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-DAcrkKxG.js → Dropdown-Cufrh2Bz.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-6GXah-89.js → EmailListRenderer-B-kdv10f.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-TKDCq8Ku.js → FamilyGuardDashboard-D21XjgfG.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-BXBLlcNm.js → Federation-CAwRTLZH.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-BoJJBkG3.js → FormItemContext-vx3daNDF.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-okjsl46v.js → GenericCardRenderer-CRWY2wU4.js} +1 -1
- package/src/assets/web-panel/assets/{Git-Rvs7i6nn.js → Git-Q6SwauyD.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-CHSUxXXS.js → Governance-BJ1q4IQZ.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-V3BlfxsB.js → Inference-CSWjROgD.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-C_NlD4aR.js → KnowledgeGraph-fzuQsWuY.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-Nn4LNxhA.js → Logs-DVF8Mnns.js} +2 -2
- package/src/assets/web-panel/assets/MarkdownRenderer-BLif4QSg.js +1 -0
- package/src/assets/web-panel/assets/{Marketplace-DEmjFcg-.js → Marketplace-BQP7LOA4.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-DlopXipI.js → McpTools-BNlJCmNc.js} +4 -4
- package/src/assets/web-panel/assets/{Memory-BG3ynX60.js → Memory-DLLg5WQ4.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-DeRzWOfT.js → MobileBridge-CR2skNAF.js} +1 -1
- package/src/assets/web-panel/assets/{MobileProjects-Tyd3o2A0.js → MobileProjects-BxVavObl.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-BoPbOv1C.js → Mtc-B17pgqMI.js} +4 -4
- package/src/assets/web-panel/assets/{MtcAudit-un-rTHp7.js → MtcAudit-4UmV5cIL.js} +2 -2
- package/src/assets/web-panel/assets/{Multisig-Ds0oveEB.js → Multisig-DoMEXEcU.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-D09JI-yY.js → NLProgramming-h9DMXFX4.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-DTRhiKJn.js → Notes-Cihn-xX8.js} +3 -3
- package/src/assets/web-panel/assets/{NotificationSettings-BAnnNCim.js → NotificationSettings-BE6ZGa3R.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-Yr-1fSYi.js → OrderTableRenderer-CnwojoSI.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-S9EAolpj.js → Organization-B2vpwmjb.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-CqcLKqJ8.js → Overflow-C4z28R0-.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-Dw0F9EcU.js → P2P-BVlFkwhW.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-BDRwUevN.js → PdhVaultBrowser-BXbEdL5B.js} +3 -3
- package/src/assets/web-panel/assets/{Permissions-D3_c3nKB.js → Permissions-C28xs4lp.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-CxdMV98x.js → PersonalDataHub-Dgl_rBjM.js} +3 -3
- package/src/assets/web-panel/assets/{Pipeline-CgjNQFLI.js → Pipeline-3QUIhrKI.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-BHghIIht.js → Privacy-8Gh33OZ5.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-De6pqaKM.js → ProjectInit-BNmg4tZi.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-Bg4ZkNYQ.js → ProjectSettings-vgMfeCf9.js} +2 -2
- package/src/assets/web-panel/assets/Projects-BhtAVilc.js +1 -0
- package/src/assets/web-panel/assets/{Providers-CUnHbNf-.js → Providers-CXoOa8eX.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-DA2f3Wts.js → QrScannerModal-BhfTF0oS.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-C1FeHDqp.js → QuickAsk-C746HEAj.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-B5guaUMN.js → Recommend-BSej8Eo0.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-PDADSds3.js → RemoteSession-f3gmnlG3.js} +3 -3
- package/src/assets/web-panel/assets/{Reputation-eTlRhgvK.js → Reputation-CyvybpkN.js} +1 -1
- package/src/assets/web-panel/assets/{Row-D7AqSGY0.js → Row-DwV2PeYn.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-JiuLm4Ja.js → RssFeed-11GrzjZy.js} +3 -3
- package/src/assets/web-panel/assets/{Search-CwruahW3.js → Search-BjKXkrAY.js} +1 -1
- package/src/assets/web-panel/assets/{Security-CdhqaR0b.js → Security-eWiFb9Yk.js} +4 -4
- package/src/assets/web-panel/assets/{Services-CU0ZIlcT.js → Services-CdCsMAtt.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-CtduPfAb.js → Skeleton-4Q2UTKQ5.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-CROXm6AY.js → Skills-v4rtYrRj.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-DiZiABFD.js → Sla-CRhsFvd_.js} +1 -1
- package/src/assets/web-panel/assets/SpeechSettings-DLjKsDVu.js +1 -0
- package/src/assets/web-panel/assets/{SyncSettings-DBX6J1Oe.js → SyncSettings-D16zonl7.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-BLyRJd3-.js → Tasks-Xxozz0i_.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-BKa5qzmk.js → Templates-CXJpPtCT.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-DnD3a4M6.js → Tenant-XRV0L1ZF.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-DEitQeTb.js → Terminal-CYuO1i_w.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-CjHggTDq.js → TimelineRenderer-BXqitWsu.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-CsGT7sfl.js → Tokens-BvPrDHIy.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-yr4rFDrW.js → Trigger-DhCrSTf5.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-CLvu1Sjp.js → Trust-DmsuZD6K.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-B0m7yUP8.js → UkeySign-D_yrts5C.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-C0VvP4lc.js → VideoEditing-B01ihPrm.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-kllBAG1M.js → Wallet-DpUjKa-N.js} +3 -3
- package/src/assets/web-panel/assets/{WebAuthn-C54UQNLx.js → WebAuthn-CL07yON6.js} +3 -3
- package/src/assets/web-panel/assets/{WorkflowEditor-B7y8qSvU.js → WorkflowEditor-CLMflnRr.js} +1 -1
- package/src/assets/web-panel/assets/{chat-DRzTh8CJ.js → chat-DtUqe8h_.js} +1 -1
- package/src/assets/web-panel/assets/{colors-BSMwSnCx.js → colors-DPKrgVfy.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-BTg602H5.js → compact-item-BTt2GtOm.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-B6EGsdvp.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-DDKqJ8RD.js → hasIn-1kndiylj.js} +1 -1
- package/src/assets/web-panel/assets/{index-CUEU48o1.js → index-2eyAXE3d.js} +1 -1
- package/src/assets/web-panel/assets/{index-rjzk9z1Q.js → index-4bna2_SR.js} +1 -1
- package/src/assets/web-panel/assets/{index-CmAubjDi.js → index-8nz_fmlj.js} +1 -1
- package/src/assets/web-panel/assets/{index-Co7oM1qr.js → index-B9KvcS7R.js} +1 -1
- package/src/assets/web-panel/assets/{index-BMuGd2--.js → index-BAXfRKfG.js} +1 -1
- package/src/assets/web-panel/assets/{index-BVTAl5N2.js → index-BHpBMWCh.js} +1 -1
- package/src/assets/web-panel/assets/{index-DpTHIRfZ.js → index-BaZAbw9A.js} +1 -1
- package/src/assets/web-panel/assets/{index-CWGax2QW.js → index-BepLZwgB.js} +1 -1
- package/src/assets/web-panel/assets/{index-DiW0sDkz.js → index-Bhudc_Ez.js} +1 -1
- package/src/assets/web-panel/assets/{index-CGNklbP6.js → index-BlDNVgBt.js} +1 -1
- package/src/assets/web-panel/assets/{index-u2YVld9W.js → index-By5n8up9.js} +1 -1
- package/src/assets/web-panel/assets/{index-pqfux8vZ.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-BRqt4fO-.js → index-CX81qSM4.js} +1 -1
- package/src/assets/web-panel/assets/{index-BsR7Y2NG.js → index-CauoBQkH.js} +1 -1
- package/src/assets/web-panel/assets/{index-C_JzIXUq.js → index-CcO04eDn.js} +1 -1
- package/src/assets/web-panel/assets/{index-CQlHFN_g.js → index-CtF7EN49.js} +1 -1
- package/src/assets/web-panel/assets/{index-CwPUZbMI.js → index-CzjkKUmR.js} +1 -1
- package/src/assets/web-panel/assets/{index-th2ihDc0.js → index-D95OFht7.js} +1 -1
- package/src/assets/web-panel/assets/{index-CHfLYwcW.js → index-DFIZ_1Sf.js} +1 -1
- package/src/assets/web-panel/assets/{index-C1GFfuqN.js → index-DG2MZQ3f.js} +1 -1
- package/src/assets/web-panel/assets/{index-D1naNj4U.js → index-DJ8vXGOa.js} +1 -1
- package/src/assets/web-panel/assets/{index-DLdrHhML.js → index-Dbbymxpj.js} +1 -1
- package/src/assets/web-panel/assets/{index-DBT3YeQ9.js → index-DdkplL9R.js} +1 -1
- package/src/assets/web-panel/assets/{index-BICn3Qh1.js → index-DfGl8CqG.js} +1 -1
- package/src/assets/web-panel/assets/{index-DqFXGzzC.js → index-DfKBRdSS.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bx044qDj.js → index-DsJCDUJG.js} +1 -1
- package/src/assets/web-panel/assets/{index-XFe-1twF.js → index-Dwqmtk65.js} +1 -1
- package/src/assets/web-panel/assets/{index-C66NpWy5.js → index-DxdTdBix.js} +1 -1
- package/src/assets/web-panel/assets/{index-CmAInUkX.js → index-FzdwcSy2.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cf23wVMs.js → index-GsoUQ2M7.js} +1 -1
- package/src/assets/web-panel/assets/{index-D5CsBShd.js → index-brCInrzq.js} +1 -1
- package/src/assets/web-panel/assets/{index-323Hhxxt.js → index-dVc-CXY4.js} +1 -1
- package/src/assets/web-panel/assets/{index-p2HYn89m.js → index-fk2Rjacw.js} +3 -3
- package/src/assets/web-panel/assets/{index-Dfv2lKu3.js → index-l1BETrDb.js} +1 -1
- package/src/assets/web-panel/assets/{index-CNxg61YP.js → index-m31Ka8hZ.js} +1 -1
- package/src/assets/web-panel/assets/{index-CDTvsX8t.js → index-ocf06EVQ.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dc77VR3H.js → index-sDoMHTNA.js} +1 -1
- package/src/assets/web-panel/assets/index-xeSyVoRe.js +1 -0
- package/src/assets/web-panel/assets/{initDefaultProps-C3Djh9fa.js → initDefaultProps-CvyYJd7z.js} +1 -1
- package/src/assets/web-panel/assets/{motion-BzqFmbSe.js → motion-DYZkhUdz.js} +1 -1
- package/src/assets/web-panel/assets/{move-DJo_FFaW.js → move-slnJRVT1.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-_tlTiBvk.js → mtc-parser-DVc0CKmy.js} +1 -1
- package/src/assets/web-panel/assets/{omit-CB2ZyxUg.js → omit-BCXAtHCq.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-DZwIFD4u.js → pickAttrs-DBsemz_K.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-DxZY0dgk.js → placementArrow-BRtkJ-nv.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-CzzGt7GL.js → responsiveObserve-Cebq7EZn.js} +1 -1
- package/src/assets/web-panel/assets/{slide-BaIK52yz.js → slide-DT7qvId2.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-3-FHu9_M.js → statusUtils-pQiITLkG.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-BkRT68fK.js → styleChecker-c-19BVKQ.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-DHYwKS-s.js → useFlexGapSupport-DsS5-0bE.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-DVVUhV8p.js → useFs-CxGiMe5n.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-CkrFKAzQ.js → usePersonalDataHub-D9btVID5.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-BuBLFz0c.js → vnode-CUYFsFEN.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-kpm6LtXU.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 +280 -5
- 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 +14 -1
- package/src/gateways/ws/action-protocol.js +1 -1
- package/src/harness/jsonl-session-store.js +638 -2
- package/src/harness/prompt-compressor.js +4 -0
- package/src/lib/background-agent-keeper-client.js +29 -0
- package/src/lib/background-agent-keeper-protocol.js +4 -0
- package/src/lib/background-agent-supervisor.js +59 -29
- package/src/lib/cowork-task-runner.js +70 -0
- package/src/lib/cowork-workflow.js +42 -9
- package/src/lib/doctor-checkup.js +34 -10
- package/src/lib/dynamic-workflow-draft.js +535 -0
- package/src/lib/dynamic-workflow-facade.js +11 -11
- 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/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-membership-coordinator.js +8 -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 +95 -5
- package/src/runtime/agent-core.js +595 -41
- package/src/workers/background-agent-keeper.js +40 -10
- package/src/assets/web-panel/assets/MarkdownRenderer-SVAgNnkt.js +0 -1
- package/src/assets/web-panel/assets/Projects-CP8vPvzs.js +0 -1
- package/src/assets/web-panel/assets/SpeechSettings-B5pLcXUw.js +0 -1
- package/src/assets/web-panel/assets/devWarning-Dol8jLEP.js +0 -1
- package/src/assets/web-panel/assets/index-C3QX5tOl.js +0 -1
- package/src/assets/web-panel/assets/index-xYybvEic.js +0 -1
|
@@ -5,6 +5,8 @@ import {
|
|
|
5
5
|
BACKGROUND_AGENT_KEEPER_ARM,
|
|
6
6
|
BACKGROUND_AGENT_KEEPER_ARMED,
|
|
7
7
|
BACKGROUND_AGENT_KEEPER_HELLO,
|
|
8
|
+
BACKGROUND_AGENT_KEEPER_HEARTBEAT,
|
|
9
|
+
BACKGROUND_AGENT_KEEPER_HEARTBEAT_INTERVAL_MS,
|
|
8
10
|
BACKGROUND_AGENT_KEEPER_PROTOCOL_VERSION,
|
|
9
11
|
BACKGROUND_AGENT_KEEPER_READY,
|
|
10
12
|
BACKGROUND_AGENT_KEEPER_RETIRE,
|
|
@@ -76,11 +78,17 @@ export async function connectBackgroundAgentKeeper(options = {}) {
|
|
|
76
78
|
const retireTimeoutMs = resolveBackgroundAgentKeeperRetireTimeoutMs(
|
|
77
79
|
options.retireTimeoutMs,
|
|
78
80
|
);
|
|
81
|
+
const heartbeatIntervalMs = Math.max(
|
|
82
|
+
10,
|
|
83
|
+
Number(options.heartbeatIntervalMs) ||
|
|
84
|
+
BACKGROUND_AGENT_KEEPER_HEARTBEAT_INTERVAL_MS,
|
|
85
|
+
);
|
|
79
86
|
const socket = await connectWithDeadline(options.pipePath, connectTimeoutMs);
|
|
80
87
|
const pending = new Map();
|
|
81
88
|
let ready = false;
|
|
82
89
|
let closing = false;
|
|
83
90
|
let activeTurn = null;
|
|
91
|
+
let heartbeatTimer = null;
|
|
84
92
|
let readyResolve;
|
|
85
93
|
let readyReject;
|
|
86
94
|
const readyPromise = new Promise((resolve, reject) => {
|
|
@@ -89,6 +97,8 @@ export async function connectBackgroundAgentKeeper(options = {}) {
|
|
|
89
97
|
});
|
|
90
98
|
|
|
91
99
|
const failPending = (error) => {
|
|
100
|
+
clearInterval(heartbeatTimer);
|
|
101
|
+
heartbeatTimer = null;
|
|
92
102
|
readyReject(error);
|
|
93
103
|
for (const entry of pending.values()) {
|
|
94
104
|
clearTimeout(entry.timer);
|
|
@@ -171,6 +181,23 @@ export async function connectBackgroundAgentKeeper(options = {}) {
|
|
|
171
181
|
);
|
|
172
182
|
helloTimer.unref?.();
|
|
173
183
|
await readyPromise.finally(() => clearTimeout(helloTimer));
|
|
184
|
+
const sendHeartbeat = () => {
|
|
185
|
+
try {
|
|
186
|
+
writeMessage(
|
|
187
|
+
socket,
|
|
188
|
+
createBackgroundAgentKeeperMessage(BACKGROUND_AGENT_KEEPER_HEARTBEAT, {
|
|
189
|
+
id: hello.id,
|
|
190
|
+
workerGeneration: hello.workerGeneration,
|
|
191
|
+
workerPid: hello.workerPid,
|
|
192
|
+
}),
|
|
193
|
+
);
|
|
194
|
+
} catch (error) {
|
|
195
|
+
socket.destroy(error);
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
sendHeartbeat();
|
|
199
|
+
heartbeatTimer = setInterval(sendHeartbeat, heartbeatIntervalMs);
|
|
200
|
+
heartbeatTimer.unref?.();
|
|
174
201
|
|
|
175
202
|
const request = (
|
|
176
203
|
type,
|
|
@@ -241,6 +268,8 @@ export async function connectBackgroundAgentKeeper(options = {}) {
|
|
|
241
268
|
close() {
|
|
242
269
|
if (closing) return;
|
|
243
270
|
closing = true;
|
|
271
|
+
clearInterval(heartbeatTimer);
|
|
272
|
+
heartbeatTimer = null;
|
|
244
273
|
socket.end();
|
|
245
274
|
},
|
|
246
275
|
activeTurn: () => activeTurn,
|
|
@@ -5,11 +5,15 @@ import { posix } from "node:path";
|
|
|
5
5
|
export const BACKGROUND_AGENT_KEEPER_PROTOCOL_VERSION = 1;
|
|
6
6
|
export const BACKGROUND_AGENT_KEEPER_HELLO = "background-agent-keeper-hello";
|
|
7
7
|
export const BACKGROUND_AGENT_KEEPER_READY = "background-agent-keeper-ready";
|
|
8
|
+
export const BACKGROUND_AGENT_KEEPER_HEARTBEAT =
|
|
9
|
+
"background-agent-keeper-heartbeat";
|
|
8
10
|
export const BACKGROUND_AGENT_KEEPER_ARM = "background-agent-keeper-arm";
|
|
9
11
|
export const BACKGROUND_AGENT_KEEPER_ARMED = "background-agent-keeper-armed";
|
|
10
12
|
export const BACKGROUND_AGENT_KEEPER_RETIRE = "background-agent-keeper-retire";
|
|
11
13
|
export const BACKGROUND_AGENT_KEEPER_RETIRED =
|
|
12
14
|
"background-agent-keeper-retired";
|
|
15
|
+
export const BACKGROUND_AGENT_KEEPER_HEARTBEAT_INTERVAL_MS = 1_000;
|
|
16
|
+
export const BACKGROUND_AGENT_KEEPER_HEARTBEAT_TIMEOUT_MS = 15_000;
|
|
13
17
|
|
|
14
18
|
// RETIRE is the only keeper request that performs destructive OS cleanup. Its
|
|
15
19
|
// deadline is deliberately independent from the short HELLO/ARM request
|
|
@@ -3051,22 +3051,10 @@ function isDestructiveIdentityRetired(identity) {
|
|
|
3051
3051
|
return ["dead", "reused"].includes(identity?.status);
|
|
3052
3052
|
}
|
|
3053
3053
|
|
|
3054
|
-
function
|
|
3055
|
-
// A one-shot `ps -o lstart=` failure is observational: it says nothing about
|
|
3056
|
-
// whether the exact target is still present. Other unverifiable outcomes can
|
|
3057
|
-
// mean a missing durable anchor, a vanished group owner, PID reuse with a
|
|
3058
|
-
// surviving group, or an untrusted group snapshot; those remain immediately
|
|
3059
|
-
// fail-closed rather than being promoted into the resend path.
|
|
3060
|
-
return (
|
|
3061
|
-
identity?.status === "unverifiable" &&
|
|
3062
|
-
identity?.reason === "creation-time-probe-failed"
|
|
3063
|
-
);
|
|
3064
|
-
}
|
|
3065
|
-
|
|
3066
|
-
function isRecoverableInitialDestructiveIdentityProbe(identity) {
|
|
3054
|
+
function isRecoverableDestructiveIdentityProbe(identity) {
|
|
3067
3055
|
// These outcomes come only from read-only OS observations. Retrying them
|
|
3068
3056
|
// cannot address a process, and the caller still requires two consecutive
|
|
3069
|
-
// fresh exact matches before it may issue
|
|
3057
|
+
// fresh exact matches before it may issue or reissue a signal.
|
|
3070
3058
|
return (
|
|
3071
3059
|
identity?.status === "unverifiable" &&
|
|
3072
3060
|
["creation-time-probe-failed", "process-group-state-probe-failed"].includes(
|
|
@@ -3137,7 +3125,7 @@ function retryRecoverableInitialPosixIdentity({
|
|
|
3137
3125
|
}
|
|
3138
3126
|
if (
|
|
3139
3127
|
lastIdentity?.status !== "match" &&
|
|
3140
|
-
!
|
|
3128
|
+
!isRecoverableDestructiveIdentityProbe(lastIdentity)
|
|
3141
3129
|
) {
|
|
3142
3130
|
return outcome("failed", "preflight-identity");
|
|
3143
3131
|
}
|
|
@@ -3154,7 +3142,7 @@ function retryRecoverableInitialPosixIdentity({
|
|
|
3154
3142
|
}
|
|
3155
3143
|
if (
|
|
3156
3144
|
lastIdentity?.status !== "match" &&
|
|
3157
|
-
!
|
|
3145
|
+
!isRecoverableDestructiveIdentityProbe(lastIdentity)
|
|
3158
3146
|
) {
|
|
3159
3147
|
return outcome("failed", "preflight-identity");
|
|
3160
3148
|
}
|
|
@@ -3172,8 +3160,9 @@ function retryRecoverableInitialPosixIdentity({
|
|
|
3172
3160
|
|
|
3173
3161
|
/**
|
|
3174
3162
|
* Recover from a transient POSIX EPERM without ever signalling from unknown
|
|
3175
|
-
* identity evidence. Probe-only waits may bridge a transient creation-time
|
|
3176
|
-
* lookup failure, but a resend requires two consecutive
|
|
3163
|
+
* identity evidence. Probe-only waits may bridge a transient creation-time or
|
|
3164
|
+
* process-group-state lookup failure, but a resend requires two consecutive
|
|
3165
|
+
* fresh exact matches.
|
|
3177
3166
|
*/
|
|
3178
3167
|
function retryExactPosixSignalAfterPermissionError({
|
|
3179
3168
|
inspectIdentity,
|
|
@@ -3203,7 +3192,7 @@ function retryExactPosixSignalAfterPermissionError({
|
|
|
3203
3192
|
}
|
|
3204
3193
|
if (
|
|
3205
3194
|
lastIdentity?.status !== "match" &&
|
|
3206
|
-
!
|
|
3195
|
+
!isRecoverableDestructiveIdentityProbe(lastIdentity)
|
|
3207
3196
|
) {
|
|
3208
3197
|
return outcome("failed", "identity");
|
|
3209
3198
|
}
|
|
@@ -3226,7 +3215,7 @@ function retryExactPosixSignalAfterPermissionError({
|
|
|
3226
3215
|
}
|
|
3227
3216
|
if (
|
|
3228
3217
|
lastIdentity?.status !== "match" &&
|
|
3229
|
-
!
|
|
3218
|
+
!isRecoverableDestructiveIdentityProbe(lastIdentity)
|
|
3230
3219
|
) {
|
|
3231
3220
|
return outcome("failed", "identity");
|
|
3232
3221
|
}
|
|
@@ -3306,7 +3295,7 @@ function signalExactBackgroundProcessTree(
|
|
|
3306
3295
|
if (lastIdentity.status !== "match") {
|
|
3307
3296
|
if (
|
|
3308
3297
|
platform === "win32" ||
|
|
3309
|
-
!
|
|
3298
|
+
!isRecoverableDestructiveIdentityProbe(lastIdentity)
|
|
3310
3299
|
) {
|
|
3311
3300
|
retryStoppedBy = "preflight-identity";
|
|
3312
3301
|
throw failure(
|
|
@@ -3663,7 +3652,7 @@ export function stopBackgroundAgent(id) {
|
|
|
3663
3652
|
identityProbeRetries: 0,
|
|
3664
3653
|
};
|
|
3665
3654
|
try {
|
|
3666
|
-
|
|
3655
|
+
let preflightIdentity = inspectIdentity();
|
|
3667
3656
|
activeTerminationContext.lastIdentityStatus =
|
|
3668
3657
|
preflightIdentity.status;
|
|
3669
3658
|
activeTerminationContext.lastIdentityReason =
|
|
@@ -3681,14 +3670,55 @@ export function stopBackgroundAgent(id) {
|
|
|
3681
3670
|
continue;
|
|
3682
3671
|
}
|
|
3683
3672
|
if (preflightIdentity.status !== "match") {
|
|
3684
|
-
|
|
3685
|
-
|
|
3686
|
-
|
|
3687
|
-
)
|
|
3673
|
+
if (
|
|
3674
|
+
process.platform === "win32" ||
|
|
3675
|
+
!isRecoverableDestructiveIdentityProbe(preflightIdentity)
|
|
3676
|
+
) {
|
|
3677
|
+
activeTerminationContext.retryStoppedBy = "preflight-identity";
|
|
3678
|
+
throw new Error(
|
|
3679
|
+
`destructive process identity is ${preflightIdentity.status}: ${preflightIdentity.reason || "unknown"}`,
|
|
3680
|
+
);
|
|
3681
|
+
}
|
|
3682
|
+
permissionRetryDeadline =
|
|
3683
|
+
_deps.posixPermissionRetryNowMs() +
|
|
3684
|
+
Math.max(0, Number(_deps.processExitWaitDeadlineMs) || 0);
|
|
3685
|
+
const retry = retryRecoverableInitialPosixIdentity({
|
|
3686
|
+
inspectIdentity,
|
|
3687
|
+
initialIdentity: preflightIdentity,
|
|
3688
|
+
deadline: permissionRetryDeadline,
|
|
3689
|
+
});
|
|
3690
|
+
activeTerminationContext.identityProbeRetries +=
|
|
3691
|
+
retry.identityProbeRetries;
|
|
3692
|
+
preflightIdentity = retry.lastIdentity;
|
|
3693
|
+
activeTerminationContext.lastIdentityStatus =
|
|
3694
|
+
preflightIdentity?.status;
|
|
3695
|
+
activeTerminationContext.lastIdentityReason =
|
|
3696
|
+
preflightIdentity?.reason || null;
|
|
3697
|
+
activeTerminationContext.retryStoppedBy = retry.retryStoppedBy;
|
|
3698
|
+
if (retry.status === "retired") {
|
|
3699
|
+
if (
|
|
3700
|
+
preflightIdentity?.status === "reused" &&
|
|
3701
|
+
primaryWorker?.pid === target.pid &&
|
|
3702
|
+
!signalledPids.has(target.pid)
|
|
3703
|
+
) {
|
|
3704
|
+
workerPidReused = true;
|
|
3705
|
+
}
|
|
3706
|
+
target.retiredBeforeWait = true;
|
|
3707
|
+
signalledPids.add(target.pid);
|
|
3708
|
+
continue;
|
|
3709
|
+
}
|
|
3710
|
+
if (retry.status !== "matched") {
|
|
3711
|
+
throw new Error(
|
|
3712
|
+
`destructive process identity is ${preflightIdentity?.status || "unknown"}: ${preflightIdentity?.reason || "unknown"}`,
|
|
3713
|
+
);
|
|
3714
|
+
}
|
|
3715
|
+
}
|
|
3716
|
+
if (!(permissionRetryDeadline > 0)) {
|
|
3717
|
+
permissionRetryDeadline =
|
|
3718
|
+
_deps.posixPermissionRetryNowMs() +
|
|
3719
|
+
Math.max(0, Number(_deps.processExitWaitDeadlineMs) || 0);
|
|
3688
3720
|
}
|
|
3689
|
-
|
|
3690
|
-
_deps.posixPermissionRetryNowMs() +
|
|
3691
|
-
Math.max(0, Number(_deps.processExitWaitDeadlineMs) || 0);
|
|
3721
|
+
activeTerminationContext.retryStoppedBy = "initial-signal";
|
|
3692
3722
|
target.signalledAsGroup = sendInitialSignal() === "process-group";
|
|
3693
3723
|
signalledPids.add(target.pid);
|
|
3694
3724
|
} catch (error) {
|
|
@@ -58,6 +58,7 @@ export const _deps = {
|
|
|
58
58
|
|
|
59
59
|
const DEFAULT_MAX_ITERATIONS = 50;
|
|
60
60
|
const DEFAULT_TOKEN_BUDGET = 100_000;
|
|
61
|
+
const WORKFLOW_EFFECT_ID_RE = /^sha256:[a-f0-9]{64}$/;
|
|
61
62
|
const COWORK_MCP_CALL_LEDGER_UNSUPPORTED =
|
|
62
63
|
"CC_COWORK_MCP_CALL_LEDGER_UNSUPPORTED";
|
|
63
64
|
const COWORK_MCP_SESSION_UNVERIFIED = "CC_COWORK_MCP_SESSION_UNVERIFIED";
|
|
@@ -74,6 +75,44 @@ function coworkMcpAdmissionError(code, message, sessionId, cause = null) {
|
|
|
74
75
|
return error;
|
|
75
76
|
}
|
|
76
77
|
|
|
78
|
+
function assertWorkflowEffectId(value) {
|
|
79
|
+
if (value == null) return;
|
|
80
|
+
if (typeof value !== "string" || !WORKFLOW_EFFECT_ID_RE.test(value)) {
|
|
81
|
+
const error = new TypeError(
|
|
82
|
+
"workflowEffectId must be a canonical sha256 identity",
|
|
83
|
+
);
|
|
84
|
+
error.code = "CC_COWORK_WORKFLOW_EFFECT_ID_INVALID";
|
|
85
|
+
throw error;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function workflowEffectEvidence(subAgent, workflowEffectId) {
|
|
90
|
+
if (!workflowEffectId) return {};
|
|
91
|
+
const attempts =
|
|
92
|
+
typeof subAgent?.providerRequestAttempts === "function"
|
|
93
|
+
? subAgent.providerRequestAttempts()
|
|
94
|
+
: [];
|
|
95
|
+
const receipts =
|
|
96
|
+
typeof subAgent?.providerRequestReceipts === "function"
|
|
97
|
+
? subAgent.providerRequestReceipts()
|
|
98
|
+
: [];
|
|
99
|
+
const nestedEffectAttempts =
|
|
100
|
+
typeof subAgent?.nestedEffectAttempts === "function"
|
|
101
|
+
? subAgent.nestedEffectAttempts()
|
|
102
|
+
: [];
|
|
103
|
+
const nestedEffectSettlements =
|
|
104
|
+
typeof subAgent?.nestedEffectSettlements === "function"
|
|
105
|
+
? subAgent.nestedEffectSettlements()
|
|
106
|
+
: [];
|
|
107
|
+
return {
|
|
108
|
+
workflowEffectId,
|
|
109
|
+
providerRequestAttempts: attempts,
|
|
110
|
+
providerRequestReceipts: receipts,
|
|
111
|
+
nestedEffectAttempts,
|
|
112
|
+
nestedEffectSettlements,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
|
|
77
116
|
function assertCoworkMcpEventUsageAdmission(event, sessionId) {
|
|
78
117
|
if (event?.type !== "session_start") return;
|
|
79
118
|
const data =
|
|
@@ -477,6 +516,12 @@ export function prepareCoworkMcpRuntime(mcp, options = {}) {
|
|
|
477
516
|
* @param {number} [options.maxIterations] - Override iteration limit
|
|
478
517
|
* @param {number} [options.tokenBudget] - Override token budget
|
|
479
518
|
* @param {string} [options.mcpSessionId] - Stable MCP ledger session for resume
|
|
519
|
+
* @param {string} [options.workflowEffectId] - Canonical durable workflow effect
|
|
520
|
+
* @param {boolean} [options.strictUsageTelemetry] - Require synchronous durable call observers
|
|
521
|
+
* @param {function} [options.onUsageBoundary] - Provider-call durable start observer
|
|
522
|
+
* @param {function} [options.onUsageSettlement] - Provider-call durable settlement observer
|
|
523
|
+
* @param {function} [options.onToolCallBoundary] - Tool-call durable start observer
|
|
524
|
+
* @param {function} [options.onToolCallSettlement] - Tool-call durable settlement observer
|
|
480
525
|
* @param {(request: object) => boolean|Promise<boolean>} [options.approveMcpLocalCodeExecution]
|
|
481
526
|
* @returns {Promise<{ taskId: string, status: string, result: object }>}
|
|
482
527
|
*/
|
|
@@ -493,12 +538,19 @@ export async function runCoworkTask(options = {}) {
|
|
|
493
538
|
onProgress = null,
|
|
494
539
|
signal = null,
|
|
495
540
|
mcpSessionId = null,
|
|
541
|
+
workflowEffectId = null,
|
|
542
|
+
strictUsageTelemetry = false,
|
|
543
|
+
onUsageBoundary = null,
|
|
544
|
+
onUsageSettlement = null,
|
|
545
|
+
onToolCallBoundary = null,
|
|
546
|
+
onToolCallSettlement = null,
|
|
496
547
|
approveMcpLocalCodeExecution = null,
|
|
497
548
|
} = options;
|
|
498
549
|
|
|
499
550
|
if (!userMessage || typeof userMessage !== "string") {
|
|
500
551
|
throw new Error("userMessage is required");
|
|
501
552
|
}
|
|
553
|
+
assertWorkflowEffectId(workflowEffectId);
|
|
502
554
|
|
|
503
555
|
// An explicit canonical authority must be admitted before mounting local MCP
|
|
504
556
|
// servers, constructing a child context, or making any provider call.
|
|
@@ -582,6 +634,16 @@ export async function runCoworkTask(options = {}) {
|
|
|
582
634
|
cwd,
|
|
583
635
|
onProgress,
|
|
584
636
|
signal,
|
|
637
|
+
...(workflowEffectId ? { workflowEffectId } : {}),
|
|
638
|
+
...(strictUsageTelemetry
|
|
639
|
+
? {
|
|
640
|
+
strictUsageTelemetry: true,
|
|
641
|
+
onUsageBoundary,
|
|
642
|
+
onUsageSettlement,
|
|
643
|
+
onToolCallBoundary,
|
|
644
|
+
onToolCallSettlement,
|
|
645
|
+
}
|
|
646
|
+
: {}),
|
|
585
647
|
extraToolDefinitions: mcp.extraToolDefinitions,
|
|
586
648
|
externalToolDescriptors: mcp.externalToolDescriptors,
|
|
587
649
|
externalToolExecutors: mcp.externalToolExecutors,
|
|
@@ -632,17 +694,25 @@ export async function runCoworkTask(options = {}) {
|
|
|
632
694
|
templateId: template.id,
|
|
633
695
|
templateName: template.name,
|
|
634
696
|
...(mcpRuntime.sessionId ? { mcpSessionId: mcpRuntime.sessionId } : {}),
|
|
697
|
+
...workflowEffectEvidence(subAgent, workflowEffectId),
|
|
635
698
|
result,
|
|
636
699
|
};
|
|
637
700
|
_appendHistory(cwd, entry, userMessage);
|
|
638
701
|
return entry;
|
|
639
702
|
} catch (err) {
|
|
703
|
+
// A durable workflow already marked this outer effect as dispatched.
|
|
704
|
+
// Converting a child/provider exception into an ordinary failed result
|
|
705
|
+
// would authorize the step retry path even though the physical provider
|
|
706
|
+
// outcome may be unknown. Propagate so the runtime keeps it pending and
|
|
707
|
+
// requires reconciliation.
|
|
708
|
+
if (workflowEffectId) throw err;
|
|
640
709
|
const entry = {
|
|
641
710
|
taskId,
|
|
642
711
|
status: "failed",
|
|
643
712
|
templateId: template.id,
|
|
644
713
|
templateName: template.name,
|
|
645
714
|
...(mcpRuntime.sessionId ? { mcpSessionId: mcpRuntime.sessionId } : {}),
|
|
715
|
+
...workflowEffectEvidence(subAgent, workflowEffectId),
|
|
646
716
|
result: {
|
|
647
717
|
summary: `Task failed: ${err.message}`,
|
|
648
718
|
artifacts: [],
|
|
@@ -66,6 +66,8 @@ export const COWORK_WORKFLOW_RUN_ADMISSION_INVALID_CODE =
|
|
|
66
66
|
"COWORK_WORKFLOW_RUN_ADMISSION_INVALID";
|
|
67
67
|
export const COWORK_WORKFLOW_RUN_RESULT_INVALID_CODE =
|
|
68
68
|
"COWORK_WORKFLOW_RUN_RESULT_INVALID";
|
|
69
|
+
export const COWORK_WORKFLOW_CONTROL_SIGNAL_CODE =
|
|
70
|
+
"COWORK_WORKFLOW_CONTROL_SIGNAL";
|
|
69
71
|
|
|
70
72
|
const DYNAMIC_WORKFLOW_RUN_ADMISSION_SCHEMA =
|
|
71
73
|
"cc-dynamic-workflow-run-admission/v1";
|
|
@@ -484,7 +486,9 @@ function normalizeWorkflowRunAdmission(
|
|
|
484
486
|
authority.definitionDigest !== definitionDigest ||
|
|
485
487
|
value.executionLocation.authoritySchema !==
|
|
486
488
|
EXECUTION_LOCATION_AUTHORITY_SCHEMA ||
|
|
487
|
-
|
|
489
|
+
!["verified-session-start", "verified-session-location-handoff"].includes(
|
|
490
|
+
value.executionLocation.authority,
|
|
491
|
+
) ||
|
|
488
492
|
value.executionLocation.bindingSchema !==
|
|
489
493
|
EXECUTION_LOCATION_BINDING_SCHEMA ||
|
|
490
494
|
typeof value.executionLocation.location !== "string" ||
|
|
@@ -534,7 +538,7 @@ function normalizeWorkflowRunAdmission(
|
|
|
534
538
|
}),
|
|
535
539
|
executionLocation: Object.freeze({
|
|
536
540
|
authoritySchema: EXECUTION_LOCATION_AUTHORITY_SCHEMA,
|
|
537
|
-
authority:
|
|
541
|
+
authority: value.executionLocation.authority,
|
|
538
542
|
session: Object.freeze({
|
|
539
543
|
sessionId: session.sessionId,
|
|
540
544
|
headHash: session.headHash,
|
|
@@ -1307,6 +1311,7 @@ export async function runStepWithRetry({
|
|
|
1307
1311
|
taskSemaphore,
|
|
1308
1312
|
runTask = _deps.runTask,
|
|
1309
1313
|
recordId = step.id,
|
|
1314
|
+
iteration = 1,
|
|
1310
1315
|
onTaskStart,
|
|
1311
1316
|
admitted = false,
|
|
1312
1317
|
}) {
|
|
@@ -1336,6 +1341,12 @@ export async function runStepWithRetry({
|
|
|
1336
1341
|
files: step.files || [],
|
|
1337
1342
|
cwd,
|
|
1338
1343
|
llmOptions,
|
|
1344
|
+
workflowEffect: Object.freeze({
|
|
1345
|
+
stepId: recordId,
|
|
1346
|
+
iteration,
|
|
1347
|
+
attempt,
|
|
1348
|
+
timeoutMs,
|
|
1349
|
+
}),
|
|
1339
1350
|
...(abortController ? { signal: abortController.signal } : {}),
|
|
1340
1351
|
}),
|
|
1341
1352
|
);
|
|
@@ -1353,20 +1364,38 @@ export async function runStepWithRetry({
|
|
|
1353
1364
|
lastErr = null;
|
|
1354
1365
|
} catch (err) {
|
|
1355
1366
|
if (release) release();
|
|
1367
|
+
if (err?.code === COWORK_WORKFLOW_CONTROL_SIGNAL_CODE) throw err;
|
|
1356
1368
|
if (err?.code === COWORK_WORKFLOW_RUN_RESULT_INVALID_CODE) throw err;
|
|
1357
1369
|
if (admitted && err?.code === STEP_TIMEOUT_CODE && taskPromise != null) {
|
|
1358
1370
|
abortController.abort(err);
|
|
1359
1371
|
// A terminal admitted record must never be written while the physical
|
|
1360
1372
|
// task can still produce side effects. Confirm settlement before a
|
|
1361
1373
|
// retry or final failure; a runner that ignores abort safely blocks.
|
|
1374
|
+
// A late completed result is authoritative and must not be replayed.
|
|
1362
1375
|
try {
|
|
1363
|
-
await taskPromise;
|
|
1364
|
-
|
|
1365
|
-
|
|
1376
|
+
const lateRawEntry = await taskPromise;
|
|
1377
|
+
const lateEntry = normalizeAdmittedTaskEntry(lateRawEntry);
|
|
1378
|
+
if (lateEntry.status === "completed") {
|
|
1379
|
+
return { ok: true, entry: lateEntry, attempts: attempt };
|
|
1380
|
+
}
|
|
1381
|
+
lastEntry = lateEntry;
|
|
1382
|
+
lastErr = null;
|
|
1383
|
+
} catch (lateError) {
|
|
1384
|
+
if (
|
|
1385
|
+
lateError?.code === COWORK_WORKFLOW_CONTROL_SIGNAL_CODE ||
|
|
1386
|
+
lateError?.code === COWORK_WORKFLOW_RUN_RESULT_INVALID_CODE
|
|
1387
|
+
) {
|
|
1388
|
+
throw lateError;
|
|
1389
|
+
}
|
|
1390
|
+
// The timeout remains the attempt's externally visible failure when
|
|
1391
|
+
// a non-authoritative runner error arrives after the deadline.
|
|
1392
|
+
lastErr = err;
|
|
1393
|
+
lastEntry = null;
|
|
1366
1394
|
}
|
|
1395
|
+
} else {
|
|
1396
|
+
lastErr = err; // threw or timed out → retry-eligible
|
|
1397
|
+
lastEntry = null;
|
|
1367
1398
|
}
|
|
1368
|
-
lastErr = err; // threw or timed out → retry-eligible
|
|
1369
|
-
lastEntry = null;
|
|
1370
1399
|
}
|
|
1371
1400
|
if (attempt <= maxRetries) {
|
|
1372
1401
|
const delay = retryDelayFor(step, attempt);
|
|
@@ -1503,6 +1532,7 @@ export async function runLoopStep({
|
|
|
1503
1532
|
taskSemaphore,
|
|
1504
1533
|
runTask,
|
|
1505
1534
|
recordId,
|
|
1535
|
+
iteration: iter,
|
|
1506
1536
|
onTaskStart: (event) => {
|
|
1507
1537
|
if (startAnnounced) return;
|
|
1508
1538
|
startAnnounced = true;
|
|
@@ -1760,8 +1790,11 @@ export async function runPipeline({
|
|
|
1760
1790
|
admitted,
|
|
1761
1791
|
});
|
|
1762
1792
|
} catch (err) {
|
|
1763
|
-
if (
|
|
1764
|
-
|
|
1793
|
+
if (
|
|
1794
|
+
err?.code === COWORK_WORKFLOW_RUN_RESULT_INVALID_CODE ||
|
|
1795
|
+
err?.code === COWORK_WORKFLOW_CONTROL_SIGNAL_CODE
|
|
1796
|
+
) {
|
|
1797
|
+
fatalError ||= err;
|
|
1765
1798
|
halted = true;
|
|
1766
1799
|
active--;
|
|
1767
1800
|
pump();
|
|
@@ -462,7 +462,6 @@ async function pluginSection(opts, _deps2) {
|
|
|
462
462
|
const checks = [];
|
|
463
463
|
try {
|
|
464
464
|
const { listInstalled } = await import("./plugin-runtime/install.js");
|
|
465
|
-
const { readPluginLock } = await import("./plugin-runtime/signature.js");
|
|
466
465
|
const plugins = listInstalled({ cwd: opts.cwd || process.cwd() }) || [];
|
|
467
466
|
if (plugins.length === 0) {
|
|
468
467
|
checks.push(
|
|
@@ -475,22 +474,47 @@ async function pluginSection(opts, _deps2) {
|
|
|
475
474
|
);
|
|
476
475
|
} else {
|
|
477
476
|
let unsigned = 0;
|
|
477
|
+
const runtimeBlocked = [];
|
|
478
|
+
const retainedRecovery = [];
|
|
478
479
|
for (const p of plugins) {
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
480
|
+
if (p.activePointer?.recoveryPath) {
|
|
481
|
+
retainedRecovery.push(`${p.name} (${p.activePointer.recoveryPath})`);
|
|
482
|
+
}
|
|
483
|
+
if (p.runtimeBlocked === true) {
|
|
484
|
+
runtimeBlocked.push(
|
|
485
|
+
`${p.name} (${p.activePointer?.status || "unknown pointer state"})`,
|
|
486
|
+
);
|
|
487
|
+
continue;
|
|
484
488
|
}
|
|
489
|
+
if (p.integrity?.signature?.present !== true) unsigned++;
|
|
485
490
|
}
|
|
486
491
|
checks.push(
|
|
487
492
|
check(
|
|
488
493
|
"plugins",
|
|
489
494
|
`Installed plugins: ${plugins.length}`,
|
|
490
|
-
unsigned > 0
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
495
|
+
unsigned > 0 ||
|
|
496
|
+
runtimeBlocked.length > 0 ||
|
|
497
|
+
retainedRecovery.length > 0
|
|
498
|
+
? CHECK_LEVELS.WARN
|
|
499
|
+
: CHECK_LEVELS.OK,
|
|
500
|
+
[
|
|
501
|
+
runtimeBlocked.length > 0
|
|
502
|
+
? `runtime blocked: ${runtimeBlocked.join(", ")}`
|
|
503
|
+
: null,
|
|
504
|
+
retainedRecovery.length > 0
|
|
505
|
+
? `retained install recovery: ${retainedRecovery.join(", ")}; remove the blocked plugin before another mutation`
|
|
506
|
+
: null,
|
|
507
|
+
unsigned > 0
|
|
508
|
+
? `${unsigned} active without a signature lock — they will be refused if plugins.requireSignedPlugins is enabled`
|
|
509
|
+
: null,
|
|
510
|
+
runtimeBlocked.length === 0 &&
|
|
511
|
+
retainedRecovery.length === 0 &&
|
|
512
|
+
unsigned === 0
|
|
513
|
+
? "all active plugins have signature locks"
|
|
514
|
+
: null,
|
|
515
|
+
]
|
|
516
|
+
.filter(Boolean)
|
|
517
|
+
.join("; "),
|
|
494
518
|
),
|
|
495
519
|
);
|
|
496
520
|
}
|