chainlesschain 0.166.76 → 0.166.78
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 +19 -8
- 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/linux-subreaper/linux-arm64/manifest.json +10 -0
- package/src/assets/linux-subreaper/linux-arm64/supervisor +0 -0
- package/src/assets/linux-subreaper/linux-x64/manifest.json +10 -0
- package/src/assets/linux-subreaper/linux-x64/supervisor +0 -0
- package/src/assets/web-panel/assets/{AIOps-CNaejClV.js → AIOps-DSyZEY2G.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-CF_CVKT_.js → ActionButton-DhNyZ577.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-a3Z6J7gv.js → Analytics-HMMpxmyi.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-BFtWEnct.js → AppLayout-CwKMM5Ie.js} +5 -5
- package/src/assets/web-panel/assets/{Artifacts-BQ8oeMvX.js → Artifacts-CNzDmph7.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-NOo9bmgk.js → Audit-DxWpUW3V.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-QRc7F3Tp.js → BackgroundAgents-C1R2ST-P.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-UlVgLn2P.js → Backup-B6biTaEV.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-BER9LJAr.js → BaseInput-CVnkD2Z5.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-Z8z2Fdfz.js → Chat-Dbewl4Je.js} +6 -6
- package/src/assets/web-panel/assets/{ChatBubbleRenderer-DdmuBrdQ.js → ChatBubbleRenderer-DVZ6SwC5.js} +1 -1
- package/src/assets/web-panel/assets/{Checkbox-CXPgyB8L.js → Checkbox-BqqiF1JE.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-D1vOsLJ7.js → Codegen-BVMkGumc.js} +1 -1
- package/src/assets/web-panel/assets/{Col-ucLnUJC7.js → Col-DmiRHy96.js} +1 -1
- package/src/assets/web-panel/assets/{Community-COsV9n9t.js → Community-BDlpygqA.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-D0EkBEYh.js → Compact-B2NME_m-.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-C8w9SUjt.js → Compliance-BlzDLE-R.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-CmVaKEJS.js → Cowork-C8raPybB.js} +3 -3
- package/src/assets/web-panel/assets/{Cron-B_FiMMV2.js → Cron-DA8Py0zP.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-ByO3YL8N.js → Crosschain-DU2XyHqB.js} +1 -1
- package/src/assets/web-panel/assets/{DID-DwpsLM9r.js → DID-Df098fT_.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-B_8IUvM_.js → Dashboard-D1rT702x.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-Bo6WQkuX.js → Dropdown-BweXGo1O.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-C9LiQesx.js → EmailListRenderer-B9ShbgJH.js} +1 -1
- package/src/assets/web-panel/assets/EvolutionSettings-D75_iBoc.js +1 -0
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-Dst6VUnO.js → FamilyGuardDashboard-DrznZFVs.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-Ci7CoLkJ.js → Federation-DQZ2adIA.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-bdDyUhUM.js → FormItemContext-DN30Dowh.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-CrRwOUVi.js → GenericCardRenderer-DRdt0j1e.js} +1 -1
- package/src/assets/web-panel/assets/{Git-Dis8h-Z-.js → Git-wwRgStzk.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-DX7OH5w2.js → Governance-CI4Uw0Nh.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-Cavv_Q_Z.js → Inference-5TuE2AJI.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-Cck8tnZn.js → KnowledgeGraph-oXyvmFSR.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-BQt3aGMu.js → Logs-ewudSWuv.js} +2 -2
- package/src/assets/web-panel/assets/MarkdownRenderer-Cz5nyufm.js +1 -0
- package/src/assets/web-panel/assets/{Marketplace-CdmAKNSN.js → Marketplace-DcZeWFrs.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-BUlJdyPY.js → McpTools-BcV9p1RS.js} +3 -3
- package/src/assets/web-panel/assets/{Memory-DQRTQDr-.js → Memory-CMhYvugt.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-C0dnxgsl.js → MobileBridge-5RP2uwvT.js} +1 -1
- package/src/assets/web-panel/assets/{MobileProjects-DQ5Gy7fa.js → MobileProjects-BIuM9Ze4.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-Xl7u2isS.js → Mtc-DmBszTDe.js} +5 -5
- package/src/assets/web-panel/assets/{MtcAudit-C3KX0574.js → MtcAudit-Czdp5ZGt.js} +2 -2
- package/src/assets/web-panel/assets/{Multisig-CHEhfkn8.js → Multisig-DRWUuNr-.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-Ce38mH-8.js → NLProgramming-IRQQN0-c.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-C7nuTd7c.js → Notes-CGhD1lW9.js} +4 -4
- package/src/assets/web-panel/assets/{NotificationSettings-BcoEcyq8.js → NotificationSettings-BtyPgQAh.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-D-t5hKkx.js → OrderTableRenderer-yUaqwCty.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-C_BGi4xi.js → Organization-C3kTVn5i.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-BodhraDq.js → Overflow-C2-0iZhq.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-BTa3sAIy.js → P2P-CISoEUxA.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-BjZslP9T.js → PdhVaultBrowser-NfTVtvKQ.js} +5 -5
- package/src/assets/web-panel/assets/{Permissions-u3UDzGef.js → Permissions-CfK0jJhm.js} +3 -3
- package/src/assets/web-panel/assets/{PersonalDataHub-Cb7ybv65.js → PersonalDataHub-OsVxxh_j.js} +4 -4
- package/src/assets/web-panel/assets/{Pipeline-CS24k-P7.js → Pipeline-DEmK_Ch2.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-Ddj6Kqs7.js → Privacy-D61s73b0.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-Bg5uQIgg.js → ProjectInit-DkLF5gHb.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-AmPR8T12.js → ProjectSettings-BA7odTrI.js} +2 -2
- package/src/assets/web-panel/assets/{Projects-DGSbAyTK.js → Projects-CdI1GcAG.js} +1 -1
- package/src/assets/web-panel/assets/{Providers-Dc1C3lbB.js → Providers-D9BYyP1r.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-Cv3HXpce.js → QrScannerModal-CXMItUDD.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-3dpbXARb.js → QuickAsk-8-tF9ffZ.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-5aGRVnJK.js → Recommend-C2QGWOSi.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-CTS2jx0p.js → RemoteSession-B1M_v1lx.js} +2 -2
- package/src/assets/web-panel/assets/{Reputation-BxaKI0hY.js → Reputation-D0WZHgv1.js} +1 -1
- package/src/assets/web-panel/assets/{Row-C23uQdwd.js → Row-D6nf9-c-.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-ssX9YOhm.js → RssFeed-ClZ6M-mN.js} +3 -3
- package/src/assets/web-panel/assets/{Search-C24GogII.js → Search-ZWkt8vuO.js} +1 -1
- package/src/assets/web-panel/assets/{Security-DdAcGKkk.js → Security-BUlQut2m.js} +3 -3
- package/src/assets/web-panel/assets/{Services-D0dCiEuq.js → Services-Cd_3xJOc.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-DEY44o0v.js → Skeleton-C8e2-cHW.js} +1 -1
- package/src/assets/web-panel/assets/Skills-DucVRJp1.js +1 -0
- package/src/assets/web-panel/assets/{Sla-B_bbo2vB.js → Sla-Csr5pUwI.js} +1 -1
- package/src/assets/web-panel/assets/SpeechSettings-CXvyaRAT.js +1 -0
- package/src/assets/web-panel/assets/{SyncSettings-CpIXql0Z.js → SyncSettings-KdsIcV5h.js} +2 -2
- package/src/assets/web-panel/assets/Tasks-B-eHmJm9.js +1 -0
- package/src/assets/web-panel/assets/{Templates-C_44nVPq.js → Templates-BglVeaLK.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-CyZ2ey2P.js → Tenant-BBbQ8qan.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-DwGNHWnp.js → Terminal-Ca_pCVBi.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-BTAHNkqU.js → TimelineRenderer-YD6XG_vZ.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-DCJWkUwc.js → Tokens-2lRoeVli.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-BCjDO9-E.js → Trigger-C-3XNAU9.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-_YS8WbRb.js → Trust-k-1PxdLG.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-m6R8xGq7.js → UkeySign-FG-qW646.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-xOfk29c4.js → VideoEditing-BNOe1cmd.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-B1Gw0awc.js → Wallet-D5C3i2Kw.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-CHK5ft18.js → WebAuthn-BOpztqd3.js} +4 -4
- package/src/assets/web-panel/assets/{WorkflowEditor-DEp1ukQQ.js → WorkflowEditor-BpVrpUEv.js} +1 -1
- package/src/assets/web-panel/assets/{chat-B2sFizun.js → chat-DIuMHb38.js} +1 -1
- package/src/assets/web-panel/assets/{colors-DJ17YV1E.js → colors-CTFJPyzQ.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-CBhJJgEC.js → compact-item-CONfmJcW.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-BZkpvNJy.js → createContext-RkW5CRrz.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-DaEBln_q.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-C0ZKo6Ei.js → hasIn-CW4XOjDC.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bc3vVG2X.js → index-7wMSBCU7.js} +1 -1
- package/src/assets/web-panel/assets/{index-vFMwiAN4.js → index-Akmg1WdH.js} +1 -1
- package/src/assets/web-panel/assets/{index-DOBXNMdh.js → index-B54qoVff.js} +1 -1
- package/src/assets/web-panel/assets/{index-DLo8Ls9u.js → index-B8r2t0Ch.js} +1 -1
- package/src/assets/web-panel/assets/{index-C7gv9dvb.js → index-B9XoBoty.js} +1 -1
- package/src/assets/web-panel/assets/{index-DHtpMr1G.js → index-B9aS2VLu.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dxe0YlZe.js → index-BFs1Tznc.js} +1 -1
- package/src/assets/web-panel/assets/{index-DumLgj1t.js → index-BKgaRT0b.js} +1 -1
- package/src/assets/web-panel/assets/{index-BNp6HKFh.js → index-BM7bOUvu.js} +1 -1
- package/src/assets/web-panel/assets/{index-DM0rWF6z.js → index-BMg2JFmW.js} +1 -1
- package/src/assets/web-panel/assets/{index-4oULtRqE.js → index-BRZsPxNn.js} +1 -1
- package/src/assets/web-panel/assets/{index-LPPe0val.js → index-Bf19fKef.js} +1 -1
- package/src/assets/web-panel/assets/{index-Ctguam0K.js → index-BkAbfBF-.js} +1 -1
- package/src/assets/web-panel/assets/{index-DrU5xVpF.js → index-CBjb2A5R.js} +1 -1
- package/src/assets/web-panel/assets/{index-CCOr6Q27.js → index-CEZWQthY.js} +1 -1
- package/src/assets/web-panel/assets/{index-C9gYiACH.js → index-CFGLf88d.js} +1 -1
- package/src/assets/web-panel/assets/{index-CZW84cEf.js → index-CLUa68JH.js} +3 -3
- package/src/assets/web-panel/assets/{index-BoDUYyuo.js → index-CM2X25Er.js} +1 -1
- package/src/assets/web-panel/assets/{index-DyiCbHeL.js → index-CX4T2uKN.js} +1 -1
- package/src/assets/web-panel/assets/{index-CW5o1Gar.js → index-CixqfdRk.js} +1 -1
- package/src/assets/web-panel/assets/{index-5K2z_tgO.js → index-CkRojEip.js} +1 -1
- package/src/assets/web-panel/assets/{index-BOfPp5OV.js → index-Cvmc3f25.js} +1 -1
- package/src/assets/web-panel/assets/{index-CdxJm-HB.js → index-D-lpTPS8.js} +1 -1
- package/src/assets/web-panel/assets/{index-8ueG48gl.js → index-D59GbWCN.js} +1 -1
- package/src/assets/web-panel/assets/{index-BMxOoITz.js → index-DAESljiJ.js} +1 -1
- package/src/assets/web-panel/assets/{index-DLMr5KMd.js → index-DDHUx4Yz.js} +1 -1
- package/src/assets/web-panel/assets/index-DG1mcYTa.js +1 -0
- package/src/assets/web-panel/assets/{index-BGIvhCPl.js → index-DP5pPedy.js} +1 -1
- package/src/assets/web-panel/assets/index-DRs5Pe8u.js +1 -0
- package/src/assets/web-panel/assets/{index-DjdSFO0d.js → index-DSlXL6Ju.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cn5UzvgR.js → index-DWCJnn2O.js} +1 -1
- package/src/assets/web-panel/assets/{index-Chct9tL8.js → index-DWY7YwDu.js} +1 -1
- package/src/assets/web-panel/assets/{index-BEnd5fiz.js → index-DZTwP364.js} +1 -1
- package/src/assets/web-panel/assets/{index-KzNhWykP.js → index-DidrMvOx.js} +1 -1
- package/src/assets/web-panel/assets/{index-BpyrhOeh.js → index-Dj3K5kHs.js} +1 -1
- package/src/assets/web-panel/assets/{index-CZlkPrxb.js → index-YaeGscSw.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dfgxe-fw.js → index-YlMnFNOi.js} +1 -1
- package/src/assets/web-panel/assets/{index-IHgzfc1u.js → index-asWsB34i.js} +1 -1
- package/src/assets/web-panel/assets/{index-DJkoJzTU.js → index-gkjiFjQd.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-Cqfoq0TJ.js → initDefaultProps-BOr4igh3.js} +1 -1
- package/src/assets/web-panel/assets/{motion-CIiVJHNu.js → motion-CK469n2j.js} +1 -1
- package/src/assets/web-panel/assets/{move-CFl1o_A8.js → move-DzjudlYQ.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-DYoCxcZ1.js → mtc-parser-BQaKUxC6.js} +1 -1
- package/src/assets/web-panel/assets/{omit-C1P2q5TY.js → omit-MciovCFD.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-BtTRpJtC.js → pickAttrs-DDPJ4zAz.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-Cst2PcNM.js → placementArrow-Cznyb-jI.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-CF5kalV2.js → responsiveObserve-AJK3SLzJ.js} +1 -1
- package/src/assets/web-panel/assets/{slide-CtHGqpXN.js → slide-CPQ28wu7.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-N__biHXf.js → statusUtils-CFjzvqf_.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-DR8V_H-i.js → styleChecker-BPyFfTuR.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-D274dqun.js → useFlexGapSupport-Dq7N6R05.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-BwHLYU5b.js → useFs-C3GS0uTc.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-BiA-hVqt.js → usePersonalDataHub-BhgIVzP_.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-Bugl94dy.js → vnode-4ZD9-MDr.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-DEFl8GCu.js → zoom-Bx4MRVNW.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/command-help-index.json +1 -1
- package/src/command-manifest.json +1 -1
- package/src/commands/checkpoint.js +42 -7
- package/src/commands/orchestrate.js +85 -25
- package/src/commands/session-location.js +5 -0
- package/src/commands/session-show.js +109 -1
- package/src/commands/session.js +26 -2
- package/src/commands/tokens.js +9 -4
- package/src/data/changelog.json +26 -0
- package/src/generated/cc-agent-protocol.schema.json +71 -0
- package/src/harness/jsonl-session-store.js +357 -114
- package/src/harness/mcp-client.js +44 -1
- package/src/lib/agent-router.js +35 -7
- package/src/lib/app-server/server.js +14 -0
- package/src/lib/background-agent-supervisor.js +14 -4
- package/src/lib/causal-observability.js +64 -1
- package/src/lib/checkpoint-summary-projection.js +98 -0
- package/src/lib/checkpoint-timeline-authority.js +15 -51
- package/src/lib/claude-code-bridge.js +302 -60
- package/src/lib/codex-app-server-adapter.js +161 -35
- package/src/lib/cost-budget.js +4 -0
- package/src/lib/decision-layer/providers.js +84 -9
- package/src/lib/decision-layer/runtime.js +86 -49
- package/src/lib/direct-model-usage.js +14 -3
- package/src/lib/doctor-checkup.js +31 -2
- package/src/lib/durable-security-store.js +6 -1
- package/src/lib/evolution/evolution-artifact-identity.js +21 -0
- package/src/lib/evolution/evolution-artifact-ports.js +5 -11
- package/src/lib/evolution/evolution-eval-cohort-receipt-reconciliation.js +389 -0
- package/src/lib/execution-location-failure-site.js +63 -0
- package/src/lib/execution-location-target.js +102 -8
- package/src/lib/external-agent-adapters.js +2 -0
- package/src/lib/image-file-boundary.js +154 -0
- package/src/lib/image-input.js +16 -3
- package/src/lib/llm-pricing.js +114 -8
- package/src/lib/mcp-call-ledger-store.js +7 -2
- package/src/lib/model-capabilities.js +21 -10
- package/src/lib/model-context-catalog.js +60 -1
- package/src/lib/openai-responses.js +7 -1
- package/src/lib/orchestrator.js +8 -2
- package/src/lib/process-execution-broker/index.js +93 -1
- package/src/lib/process-execution-broker/linux-subreaper-artifact.js +120 -0
- package/src/lib/process-execution-broker/linux-subreaper-helper.js +344 -0
- package/src/lib/process-execution-broker/linux-subreaper-process.js +326 -0
- package/src/lib/process-execution-broker/linux-subreaper-supervisor.c +360 -0
- package/src/lib/process-execution-broker/owned-posix-process-group-worker.mjs +131 -0
- package/src/lib/process-execution-broker/owned-posix-process-group.js +267 -0
- package/src/lib/process-execution-broker/process-ownership-journal.js +297 -0
- package/src/lib/process-execution-broker/process-ownership-quarantine.js +91 -0
- package/src/lib/runtime-usage-ledger.js +3 -0
- package/src/lib/secure-fs.js +158 -42
- package/src/lib/session-branch-history.js +240 -0
- package/src/lib/session-history-origins.js +285 -0
- package/src/lib/session-input-receipt.js +110 -0
- package/src/lib/session-resource-budget.js +8 -8
- package/src/lib/session-transcript-history.js +456 -0
- package/src/lib/session-transcript-page.js +164 -0
- package/src/lib/session-transcript-reference.js +38 -0
- package/src/lib/session-usage.js +8 -0
- package/src/lib/token-tracker.js +32 -54
- package/src/lib/usage-pricing-context.js +93 -0
- package/src/runtime/headless-runner.js +8 -0
- package/src/runtime/headless-stream.js +202 -4
- package/src/assets/web-panel/assets/EvolutionSettings-Pc1IpRfk.js +0 -1
- package/src/assets/web-panel/assets/MarkdownRenderer-BIUeeiVA.js +0 -1
- package/src/assets/web-panel/assets/Skills-CYt0Mu2W.js +0 -1
- package/src/assets/web-panel/assets/SpeechSettings-a2BBjtTL.js +0 -1
- package/src/assets/web-panel/assets/Tasks-BYQKU-GL.js +0 -1
- package/src/assets/web-panel/assets/devWarning-DZhu13vj.js +0 -1
- package/src/assets/web-panel/assets/index-C6iFyQYz.js +0 -1
- package/src/assets/web-panel/assets/index-CztThH9f.js +0 -1
|
@@ -17,6 +17,11 @@ import { EventEmitter } from "events";
|
|
|
17
17
|
import crypto from "crypto";
|
|
18
18
|
import runtimeClaimsContract from "@chainlesschain/session-core/runtime-claims";
|
|
19
19
|
import executionBroker from "./process-execution-broker/index.js";
|
|
20
|
+
import { PROCESS_OWNERSHIP_UNCONFIRMED } from "./process-execution-broker/process-ownership-quarantine.js";
|
|
21
|
+
import {
|
|
22
|
+
PROCESS_OWNERSHIP_PENDING,
|
|
23
|
+
PROCESS_OWNERSHIP_JOURNAL_UNAVAILABLE,
|
|
24
|
+
} from "./process-execution-broker/process-ownership-journal.js";
|
|
20
25
|
import {
|
|
21
26
|
createExternalAgentAdapter,
|
|
22
27
|
EXTERNAL_AGENT_ERROR,
|
|
@@ -68,6 +73,7 @@ export const AGENT_STATUS = {
|
|
|
68
73
|
FAILED: "failed",
|
|
69
74
|
TIMEOUT: "timeout",
|
|
70
75
|
CANCELLED: "cancelled",
|
|
76
|
+
QUARANTINED: "quarantined",
|
|
71
77
|
};
|
|
72
78
|
|
|
73
79
|
// Bound how much of a child's stdout/stderr we retain in memory. A verbose or
|
|
@@ -157,8 +163,20 @@ export class ClaudeCodeAgent extends EventEmitter {
|
|
|
157
163
|
* @param {string} options.context - Extra context prepended to task
|
|
158
164
|
* @param {string} options.allowedTools - Comma-separated tool allow-list
|
|
159
165
|
* @returns {Promise<{success, output, exitCode, duration, taskId}>}
|
|
166
|
+
* A quarantined failure report does not release process ownership. It emits
|
|
167
|
+
* task:quarantined instead of task:complete and the agent cannot be reused.
|
|
160
168
|
*/
|
|
161
169
|
async executeTask(taskDescription, options = {}) {
|
|
170
|
+
if (this.status === AGENT_STATUS.QUARANTINED) {
|
|
171
|
+
const error = new Error(
|
|
172
|
+
"External agent still owns an unconfirmed process tree",
|
|
173
|
+
);
|
|
174
|
+
error.code = EXTERNAL_AGENT_ERROR.CLEANUP_UNCONFIRMED;
|
|
175
|
+
throw error;
|
|
176
|
+
}
|
|
177
|
+
if (this.status === AGENT_STATUS.RUNNING) {
|
|
178
|
+
throw new Error("External agent already has a running task");
|
|
179
|
+
}
|
|
162
180
|
const {
|
|
163
181
|
cwd = process.cwd(),
|
|
164
182
|
timeout = 300_000,
|
|
@@ -174,7 +192,29 @@ export class ClaudeCodeAgent extends EventEmitter {
|
|
|
174
192
|
|
|
175
193
|
this.status = AGENT_STATUS.RUNNING;
|
|
176
194
|
this.currentTask = taskDescription;
|
|
195
|
+
this._cancelRequested = false;
|
|
177
196
|
this.emit("task:start", { agentId: this.id, task: taskDescription });
|
|
197
|
+
if (this._cancelRequested) {
|
|
198
|
+
this.status = AGENT_STATUS.CANCELLED;
|
|
199
|
+
this.currentTask = null;
|
|
200
|
+
const result = {
|
|
201
|
+
success: false,
|
|
202
|
+
status: AGENT_STATUS.CANCELLED,
|
|
203
|
+
output: "",
|
|
204
|
+
exitCode: -1,
|
|
205
|
+
duration: 0,
|
|
206
|
+
timedOut: false,
|
|
207
|
+
cancelled: true,
|
|
208
|
+
agentId: this.id,
|
|
209
|
+
error: "External agent was cancelled before spawn",
|
|
210
|
+
errorCode: EXTERNAL_AGENT_ERROR.CANCELLED,
|
|
211
|
+
protocol: this.adapter.capabilities().protocol,
|
|
212
|
+
runtimeClaims: VALIDATION_ONLY_CLAIMS,
|
|
213
|
+
terminalEvidence: [],
|
|
214
|
+
};
|
|
215
|
+
this.emit("task:complete", result);
|
|
216
|
+
return result;
|
|
217
|
+
}
|
|
178
218
|
|
|
179
219
|
let args;
|
|
180
220
|
try {
|
|
@@ -201,8 +241,6 @@ export class ClaudeCodeAgent extends EventEmitter {
|
|
|
201
241
|
return result;
|
|
202
242
|
}
|
|
203
243
|
|
|
204
|
-
this._cancelRequested = false;
|
|
205
|
-
|
|
206
244
|
return new Promise((resolve) => {
|
|
207
245
|
const startTime = Date.now();
|
|
208
246
|
const outputChunks = [];
|
|
@@ -213,6 +251,114 @@ export class ClaudeCodeAgent extends EventEmitter {
|
|
|
213
251
|
const outDecoder = new TextDecoder("utf-8");
|
|
214
252
|
const errDecoder = new TextDecoder("utf-8");
|
|
215
253
|
let timedOut = false;
|
|
254
|
+
let finalized = false;
|
|
255
|
+
let stopping = false;
|
|
256
|
+
let proc = null;
|
|
257
|
+
let timer = null;
|
|
258
|
+
let killTimer = null;
|
|
259
|
+
let processError = null;
|
|
260
|
+
let spawnFailure = null;
|
|
261
|
+
let brokerCloseFence = null;
|
|
262
|
+
const finalize = (result) => {
|
|
263
|
+
if (finalized) return;
|
|
264
|
+
finalized = true;
|
|
265
|
+
clearTimeout(timer);
|
|
266
|
+
clearTimeout(killTimer);
|
|
267
|
+
this._proc = null;
|
|
268
|
+
this._stop = null;
|
|
269
|
+
this.currentTask = null;
|
|
270
|
+
this.emit("task:complete", result);
|
|
271
|
+
resolve(result);
|
|
272
|
+
};
|
|
273
|
+
const failSpawn = (err) => {
|
|
274
|
+
if (finalized) return;
|
|
275
|
+
const admissionBlocked = [
|
|
276
|
+
PROCESS_OWNERSHIP_UNCONFIRMED,
|
|
277
|
+
PROCESS_OWNERSHIP_PENDING,
|
|
278
|
+
PROCESS_OWNERSHIP_JOURNAL_UNAVAILABLE,
|
|
279
|
+
].includes(err.code);
|
|
280
|
+
this.status = AGENT_STATUS.FAILED;
|
|
281
|
+
finalize({
|
|
282
|
+
success: false,
|
|
283
|
+
status: admissionBlocked ? "not-started" : "failed",
|
|
284
|
+
output: "",
|
|
285
|
+
exitCode: -1,
|
|
286
|
+
duration: Date.now() - startTime,
|
|
287
|
+
timedOut,
|
|
288
|
+
cancelled: this._cancelRequested && !timedOut,
|
|
289
|
+
agentId: this.id,
|
|
290
|
+
error: err.message,
|
|
291
|
+
errorCode: admissionBlocked
|
|
292
|
+
? err.code
|
|
293
|
+
: EXTERNAL_AGENT_ERROR.SPAWN_FAILED,
|
|
294
|
+
protocol: this.adapter.capabilities().protocol,
|
|
295
|
+
runtimeClaims: admissionBlocked
|
|
296
|
+
? VALIDATION_ONLY_CLAIMS
|
|
297
|
+
: REAL_EXECUTION_CLAIMS,
|
|
298
|
+
terminalEvidence: [],
|
|
299
|
+
...(admissionBlocked
|
|
300
|
+
? { executionStarted: false, recoveryRequired: true }
|
|
301
|
+
: {}),
|
|
302
|
+
});
|
|
303
|
+
};
|
|
304
|
+
const quarantine = (receipt) => {
|
|
305
|
+
if (finalized || receipt?.cleanup?.confirmed !== false) return;
|
|
306
|
+
// Return a failure report without declaring task completion or releasing
|
|
307
|
+
// the process handle, task identity or pool slot. No synthetic close.
|
|
308
|
+
finalized = true;
|
|
309
|
+
clearTimeout(timer);
|
|
310
|
+
clearTimeout(killTimer);
|
|
311
|
+
this._stop = null;
|
|
312
|
+
this.status = AGENT_STATUS.QUARANTINED;
|
|
313
|
+
const rawOutput = outputChunks.join("");
|
|
314
|
+
const result = {
|
|
315
|
+
success: false,
|
|
316
|
+
status: AGENT_STATUS.QUARANTINED,
|
|
317
|
+
output: rawOutput.slice(-4000),
|
|
318
|
+
rawOutput,
|
|
319
|
+
outputTruncated,
|
|
320
|
+
stderr: errorChunks.join("").slice(-2000),
|
|
321
|
+
exitCode: null,
|
|
322
|
+
duration: Date.now() - startTime,
|
|
323
|
+
timedOut,
|
|
324
|
+
cancelled: this._cancelRequested && !timedOut,
|
|
325
|
+
agentId: this.id,
|
|
326
|
+
error:
|
|
327
|
+
"External agent process-tree cleanup is unconfirmed; recovery is required",
|
|
328
|
+
errorCode: EXTERNAL_AGENT_ERROR.CLEANUP_UNCONFIRMED,
|
|
329
|
+
protocol: this.adapter.capabilities().protocol,
|
|
330
|
+
runtimeClaims: REAL_EXECUTION_CLAIMS,
|
|
331
|
+
terminalEvidence: [],
|
|
332
|
+
processOwnershipReleased: false,
|
|
333
|
+
recoveryRequired: true,
|
|
334
|
+
cleanup: { ...receipt.cleanup },
|
|
335
|
+
};
|
|
336
|
+
resolve(result);
|
|
337
|
+
this.emit("task:quarantined", result);
|
|
338
|
+
};
|
|
339
|
+
const stop = () => {
|
|
340
|
+
if (finalized || stopping) return;
|
|
341
|
+
stopping = true;
|
|
342
|
+
clearTimeout(timer);
|
|
343
|
+
// Schedule before TERM: a child can close synchronously in adapters.
|
|
344
|
+
// Use the broker's child handle (including its sandbox supervisor),
|
|
345
|
+
// never a delayed numeric PID which may have been reused.
|
|
346
|
+
killTimer = setTimeout(() => {
|
|
347
|
+
if (!finalized) {
|
|
348
|
+
try {
|
|
349
|
+
proc.kill("SIGKILL");
|
|
350
|
+
} catch (err) {
|
|
351
|
+
processError = err;
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
}, killGraceMs);
|
|
355
|
+
killTimer.unref?.();
|
|
356
|
+
try {
|
|
357
|
+
proc.kill("SIGTERM");
|
|
358
|
+
} catch (err) {
|
|
359
|
+
processError = err;
|
|
360
|
+
}
|
|
361
|
+
};
|
|
216
362
|
// Tail-bounded byte counters for the two buffers (see MAX_AGENT_OUTPUT_BYTES).
|
|
217
363
|
let outBytes = 0;
|
|
218
364
|
let errBytes = 0;
|
|
@@ -227,33 +373,49 @@ export class ClaudeCodeAgent extends EventEmitter {
|
|
|
227
373
|
return bytes;
|
|
228
374
|
};
|
|
229
375
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
376
|
+
try {
|
|
377
|
+
proc = _deps.spawn(this.adapter.command, args, {
|
|
378
|
+
cwd,
|
|
379
|
+
env: { ...process.env },
|
|
380
|
+
windowsHide: true,
|
|
381
|
+
origin: "claude-code-bridge:agent",
|
|
382
|
+
policy: "allow",
|
|
383
|
+
scope: "orchestrator",
|
|
384
|
+
shell: false,
|
|
385
|
+
...(process.platform === "linux"
|
|
386
|
+
? { linuxSubreaper: { graceMs: killGraceMs } }
|
|
387
|
+
: {}),
|
|
388
|
+
});
|
|
389
|
+
} catch (err) {
|
|
390
|
+
// Broker admission/bookkeeping can fail after native spawn. Its
|
|
391
|
+
// attached child remains ours until close; a kill request is not exit
|
|
392
|
+
// evidence and must not release this agent for another task.
|
|
393
|
+
if (!err?.spawnedProcess) {
|
|
394
|
+
failSpawn(err);
|
|
395
|
+
return;
|
|
396
|
+
}
|
|
397
|
+
proc = err.spawnedProcess;
|
|
398
|
+
processError = err;
|
|
399
|
+
spawnFailure = err;
|
|
400
|
+
brokerCloseFence = err.workspaceProcessClosed;
|
|
401
|
+
}
|
|
239
402
|
this._proc = proc;
|
|
403
|
+
this._stop = stop;
|
|
240
404
|
|
|
241
405
|
// SIGKILL-escalation timer is hoisted so the close/error handlers can
|
|
242
406
|
// clear it — otherwise, when the process dies promptly from SIGTERM, this
|
|
243
407
|
// inner timer still fires a redundant SIGKILL on a dead pid AND holds the
|
|
244
408
|
// event loop open for the full grace period. unref() is a second guard so
|
|
245
409
|
// it never keeps the process alive on its own.
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
killTimer.unref();
|
|
253
|
-
}
|
|
254
|
-
}, timeout);
|
|
410
|
+
if (!spawnFailure) {
|
|
411
|
+
timer = setTimeout(() => {
|
|
412
|
+
timedOut = true;
|
|
413
|
+
stop();
|
|
414
|
+
}, timeout);
|
|
415
|
+
}
|
|
255
416
|
|
|
256
417
|
proc.stdout.on("data", (data) => {
|
|
418
|
+
if (finalized) return;
|
|
257
419
|
const chunk =
|
|
258
420
|
typeof data === "string"
|
|
259
421
|
? data
|
|
@@ -270,6 +432,7 @@ export class ClaudeCodeAgent extends EventEmitter {
|
|
|
270
432
|
});
|
|
271
433
|
|
|
272
434
|
proc.stderr.on("data", (data) => {
|
|
435
|
+
if (finalized) return;
|
|
273
436
|
const chunk =
|
|
274
437
|
typeof data === "string"
|
|
275
438
|
? data
|
|
@@ -281,19 +444,24 @@ export class ClaudeCodeAgent extends EventEmitter {
|
|
|
281
444
|
}
|
|
282
445
|
});
|
|
283
446
|
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
if (killTimer) clearTimeout(killTimer);
|
|
287
|
-
this._proc = null;
|
|
447
|
+
const completeClosed = (code) => {
|
|
448
|
+
if (finalized) return;
|
|
288
449
|
const duration = Date.now() - startTime;
|
|
289
450
|
const rawOutput = outputChunks.join("");
|
|
290
451
|
const cancelled = this._cancelRequested && !timedOut;
|
|
291
|
-
|
|
452
|
+
let projection;
|
|
453
|
+
try {
|
|
454
|
+
projection = this.adapter.parseTranscript(rawOutput);
|
|
455
|
+
} catch (err) {
|
|
456
|
+
projection = { terminal: "failed", error: err.message };
|
|
457
|
+
}
|
|
292
458
|
const missingTerminal =
|
|
293
459
|
this.adapter.capabilities().requiresTerminalEvent &&
|
|
294
460
|
projection.terminal === null;
|
|
295
461
|
const protocolFailed =
|
|
296
|
-
projection.terminal === "failed" ||
|
|
462
|
+
projection.terminal === "failed" ||
|
|
463
|
+
missingTerminal ||
|
|
464
|
+
Boolean(processError);
|
|
297
465
|
const status = timedOut
|
|
298
466
|
? AGENT_STATUS.TIMEOUT
|
|
299
467
|
: cancelled
|
|
@@ -336,11 +504,15 @@ export class ClaudeCodeAgent extends EventEmitter {
|
|
|
336
504
|
? EXTERNAL_AGENT_ERROR.TIMEOUT
|
|
337
505
|
: cancelled
|
|
338
506
|
? EXTERNAL_AGENT_ERROR.CANCELLED
|
|
339
|
-
:
|
|
340
|
-
? EXTERNAL_AGENT_ERROR.
|
|
341
|
-
:
|
|
342
|
-
?
|
|
343
|
-
:
|
|
507
|
+
: spawnFailure
|
|
508
|
+
? EXTERNAL_AGENT_ERROR.SPAWN_FAILED
|
|
509
|
+
: processError?.code === PROCESS_OWNERSHIP_JOURNAL_UNAVAILABLE
|
|
510
|
+
? PROCESS_OWNERSHIP_JOURNAL_UNAVAILABLE
|
|
511
|
+
: code !== 0
|
|
512
|
+
? EXTERNAL_AGENT_ERROR.EXIT_NONZERO
|
|
513
|
+
: protocolFailed
|
|
514
|
+
? EXTERNAL_AGENT_ERROR.PROTOCOL_FAILED
|
|
515
|
+
: null;
|
|
344
516
|
|
|
345
517
|
const result = {
|
|
346
518
|
success,
|
|
@@ -356,7 +528,8 @@ export class ClaudeCodeAgent extends EventEmitter {
|
|
|
356
528
|
stderr: errorChunks.join("").slice(-2000),
|
|
357
529
|
error: success
|
|
358
530
|
? undefined
|
|
359
|
-
:
|
|
531
|
+
: processError?.message ||
|
|
532
|
+
projection.error ||
|
|
360
533
|
(missingTerminal
|
|
361
534
|
? "External agent JSONL stream ended without a terminal event"
|
|
362
535
|
: null) ||
|
|
@@ -374,44 +547,72 @@ export class ClaudeCodeAgent extends EventEmitter {
|
|
|
374
547
|
malformedLineCount: projection.malformedLineCount,
|
|
375
548
|
runtimeClaims: REAL_EXECUTION_CLAIMS,
|
|
376
549
|
terminalEvidence,
|
|
550
|
+
...(processError?.code === PROCESS_OWNERSHIP_JOURNAL_UNAVAILABLE
|
|
551
|
+
? { recoveryRequired: true }
|
|
552
|
+
: {}),
|
|
377
553
|
};
|
|
378
554
|
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
555
|
+
finalize(result);
|
|
556
|
+
};
|
|
557
|
+
proc.on("close", completeClosed);
|
|
382
558
|
|
|
383
559
|
proc.on("error", (err) => {
|
|
384
|
-
|
|
385
|
-
if (
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
560
|
+
if (finalized) return;
|
|
561
|
+
if (err.code === PROCESS_OWNERSHIP_JOURNAL_UNAVAILABLE) {
|
|
562
|
+
// The actual child has run. A failed durable settlement must not be
|
|
563
|
+
// mislabeled as an admission denial or evidence that nothing started.
|
|
564
|
+
processError = err;
|
|
565
|
+
return;
|
|
566
|
+
}
|
|
567
|
+
if (err.code === EXTERNAL_AGENT_ERROR.CLEANUP_UNCONFIRMED) {
|
|
568
|
+
quarantine(proc.ownedProcessTreeEvidence);
|
|
569
|
+
if (finalized) return;
|
|
570
|
+
}
|
|
571
|
+
if (
|
|
572
|
+
err.code === EXTERNAL_AGENT_ERROR.SPAWN_FAILED &&
|
|
573
|
+
proc.ownedProcessTreeClosed
|
|
574
|
+
) {
|
|
575
|
+
processError = err;
|
|
576
|
+
spawnFailure = err;
|
|
577
|
+
}
|
|
578
|
+
if (spawnFailure) {
|
|
579
|
+
// Keep the original admission failure and wait for the owned child;
|
|
580
|
+
// another signal/transport error is still not proof of its exit.
|
|
581
|
+
stop();
|
|
582
|
+
return;
|
|
583
|
+
}
|
|
584
|
+
// A post-spawn error (e.g. signal failure) is not proof of exit.
|
|
585
|
+
// Retain ownership and wait for close, escalating cancellation.
|
|
586
|
+
if (proc.pid && proc.exitCode == null && proc.signalCode == null) {
|
|
587
|
+
processError = err;
|
|
588
|
+
stop();
|
|
589
|
+
} else {
|
|
590
|
+
failSpawn(err);
|
|
591
|
+
}
|
|
406
592
|
});
|
|
593
|
+
proc.on("cleanup:unconfirmed", quarantine);
|
|
594
|
+
if (spawnFailure) {
|
|
595
|
+
if (brokerCloseFence?.then) {
|
|
596
|
+
Promise.resolve(brokerCloseFence).then(
|
|
597
|
+
(receipt) => {
|
|
598
|
+
if (receipt?.observed === true) completeClosed(receipt.exitCode);
|
|
599
|
+
},
|
|
600
|
+
() => {
|
|
601
|
+
// A failed close observer proves nothing. Keep the actual
|
|
602
|
+
// ChildProcess close listener and termination deadline active.
|
|
603
|
+
},
|
|
604
|
+
);
|
|
605
|
+
}
|
|
606
|
+
stop();
|
|
607
|
+
}
|
|
407
608
|
});
|
|
408
609
|
}
|
|
409
610
|
|
|
410
611
|
/** Abort the currently running task. */
|
|
411
612
|
abort() {
|
|
412
|
-
if (this.
|
|
613
|
+
if (this.status === AGENT_STATUS.RUNNING) {
|
|
413
614
|
this._cancelRequested = true;
|
|
414
|
-
this.
|
|
615
|
+
this._stop?.();
|
|
415
616
|
}
|
|
416
617
|
}
|
|
417
618
|
|
|
@@ -422,6 +623,9 @@ export class ClaudeCodeAgent extends EventEmitter {
|
|
|
422
623
|
cliCommand: this.cliCommand,
|
|
423
624
|
protocol: this.adapter.capabilities().protocol,
|
|
424
625
|
currentTask: this.currentTask,
|
|
626
|
+
...(this.status === AGENT_STATUS.QUARANTINED
|
|
627
|
+
? { processOwnershipReleased: false, recoveryRequired: true }
|
|
628
|
+
: {}),
|
|
425
629
|
};
|
|
426
630
|
}
|
|
427
631
|
}
|
|
@@ -475,6 +679,10 @@ export class ClaudeCodePool extends EventEmitter {
|
|
|
475
679
|
|
|
476
680
|
// Process in batches of maxParallel
|
|
477
681
|
for (let i = 0; i < tasks.length; i += this.maxParallel) {
|
|
682
|
+
if (this._hasQuarantinedAgent()) {
|
|
683
|
+
results.push(...tasks.slice(i).map((task) => this._blockedTask(task)));
|
|
684
|
+
break;
|
|
685
|
+
}
|
|
478
686
|
const batch = tasks.slice(i, i + this.maxParallel);
|
|
479
687
|
this.emit("batch:start", {
|
|
480
688
|
batchIndex: i / this.maxParallel,
|
|
@@ -496,8 +704,9 @@ export class ClaudeCodePool extends EventEmitter {
|
|
|
496
704
|
}
|
|
497
705
|
|
|
498
706
|
async _runTask(task, { cwd }) {
|
|
707
|
+
if (this._hasQuarantinedAgent()) return this._blockedTask(task);
|
|
499
708
|
const agent = new ClaudeCodeAgent({
|
|
500
|
-
id: `agent-${task.id}`,
|
|
709
|
+
id: `agent-${task.id}-${crypto.randomUUID()}`,
|
|
501
710
|
cliCommand: this.cliCommand,
|
|
502
711
|
model: this.model,
|
|
503
712
|
sandbox: this.sandbox,
|
|
@@ -505,6 +714,12 @@ export class ClaudeCodePool extends EventEmitter {
|
|
|
505
714
|
|
|
506
715
|
this._agents.set(agent.id, agent);
|
|
507
716
|
agent.on("output", (ev) => this.emit("agent:output", ev));
|
|
717
|
+
agent.on("task:quarantined", (result) => {
|
|
718
|
+
// Stop already admitted siblings through their retained handles. Their
|
|
719
|
+
// own close fences still decide release; no new batch may start.
|
|
720
|
+
this.abortAll();
|
|
721
|
+
this.emit("agent:quarantined", { taskId: task.id, ...result });
|
|
722
|
+
});
|
|
508
723
|
|
|
509
724
|
const result = await agent.executeTask(task.description, {
|
|
510
725
|
cwd,
|
|
@@ -513,6 +728,9 @@ export class ClaudeCodePool extends EventEmitter {
|
|
|
513
728
|
allowedTools: task.allowedTools || null,
|
|
514
729
|
});
|
|
515
730
|
|
|
731
|
+
if (agent.status === AGENT_STATUS.QUARANTINED) {
|
|
732
|
+
return { taskId: task.id, ...result };
|
|
733
|
+
}
|
|
516
734
|
this._agents.delete(agent.id);
|
|
517
735
|
this._completed.push({ ...result, taskId: task.id });
|
|
518
736
|
if (this._completed.length > this.maxCompleted) {
|
|
@@ -523,6 +741,30 @@ export class ClaudeCodePool extends EventEmitter {
|
|
|
523
741
|
return { taskId: task.id, ...result };
|
|
524
742
|
}
|
|
525
743
|
|
|
744
|
+
_hasQuarantinedAgent() {
|
|
745
|
+
return [...this._agents.values()].some(
|
|
746
|
+
(agent) => agent.status === AGENT_STATUS.QUARANTINED,
|
|
747
|
+
);
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
_blockedTask(task) {
|
|
751
|
+
return {
|
|
752
|
+
taskId: task.id,
|
|
753
|
+
agentId: null,
|
|
754
|
+
success: false,
|
|
755
|
+
status: "not-started",
|
|
756
|
+
output: "",
|
|
757
|
+
exitCode: null,
|
|
758
|
+
duration: 0,
|
|
759
|
+
executionStarted: false,
|
|
760
|
+
recoveryRequired: true,
|
|
761
|
+
error: "External agent pool retains an unconfirmed process tree",
|
|
762
|
+
errorCode: EXTERNAL_AGENT_ERROR.EXECUTION_BLOCKED,
|
|
763
|
+
runtimeClaims: VALIDATION_ONLY_CLAIMS,
|
|
764
|
+
terminalEvidence: [],
|
|
765
|
+
};
|
|
766
|
+
}
|
|
767
|
+
|
|
526
768
|
/** Current pool status snapshot. */
|
|
527
769
|
status() {
|
|
528
770
|
const active = [...this._agents.values()].map((a) => a.toJSON());
|