chainlesschain 0.165.6 → 0.165.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -1
- package/src/assets/web-panel/.build-hash +1 -1
- package/src/assets/web-panel/assets/{AIOps-vfoDb6HZ.js → AIOps-DxwjrnEA.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-Cm5f7p93.js → ActionButton-JdbYowzn.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-yRuvgWxa.js → Analytics-C06GCahv.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-BROsC4h1.js → AppLayout-BUVEEyi1.js} +4 -4
- package/src/assets/web-panel/assets/{Artifacts-CimHApb1.js → Artifacts-D_ORzkJd.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-DI8kr8zI.js → Audit-8o_Y5ejG.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-DSLzKy-n.js → BackgroundAgents-DrkHd5VU.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-DkH_n2r1.js → Backup-CKBZCX11.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-CKSrUoRA.js → BaseInput-C8HkI399.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-ClwfMXUS.js → Chat-zb2H2Wux.js} +6 -6
- package/src/assets/web-panel/assets/{ChatBubbleRenderer-CjMaqfL7.js → ChatBubbleRenderer-BDcNpU_F.js} +1 -1
- package/src/assets/web-panel/assets/{Checkbox-BYTehcQG.js → Checkbox-MwPtQmNz.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-B8AMcp6J.js → Codegen-3p5QCkFK.js} +1 -1
- package/src/assets/web-panel/assets/{Col-BNSogPo3.js → Col-BPLlhn52.js} +1 -1
- package/src/assets/web-panel/assets/{Community-JxPvGb8O.js → Community-C-3dBNOM.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-DF7bFAgE.js → Compact-BUcy-F_b.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-Bvhqnwrq.js → Compliance-CI8NxT8m.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-BDS0CJvM.js → Cowork-DaDEBS-Q.js} +3 -3
- package/src/assets/web-panel/assets/{Cron-DqvRfxoQ.js → Cron-BSv9HXu5.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-CDcIvnqS.js → Crosschain-yuiKlJmv.js} +1 -1
- package/src/assets/web-panel/assets/{DID-D7jaUxU3.js → DID-D6LfldB0.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-B5A18wEV.js → Dashboard-CBhLqG61.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-_6IVkGag.js → Dropdown-BG8pIl3O.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-C9PeiKCG.js → EmailListRenderer-CY92VIE6.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-DXjuEHrX.js → FamilyGuardDashboard-1Q_ehauM.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-B4IAR9zv.js → Federation-D3XirJIU.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-CxQeSNx1.js → FormItemContext-DfI9UuGZ.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-B8GS-Y3N.js → GenericCardRenderer-IeCZk2m7.js} +1 -1
- package/src/assets/web-panel/assets/{Git-BS8SouUX.js → Git-DzK4IJAZ.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-Dq9aYb5Q.js → Governance-BHf5KfmQ.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-BrCEe9AJ.js → Inference-BmaxSALS.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-DybOpiY2.js → KnowledgeGraph-BgePFLA9.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-DBpzbRfx.js → Logs-nqgxpOc4.js} +2 -2
- package/src/assets/web-panel/assets/MarkdownRenderer-xkX6izBt.js +1 -0
- package/src/assets/web-panel/assets/{Marketplace-Cc7CCSCu.js → Marketplace-Bu8to-86.js} +1 -1
- package/src/assets/web-panel/assets/McpTools-BFWTzEk0.js +4 -0
- package/src/assets/web-panel/assets/{Memory-KCqlp9ol.js → Memory-B026G2GA.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-Bys84ySN.js → MobileBridge-CM2Eeg6I.js} +1 -1
- package/src/assets/web-panel/assets/{MobileProjects-B-6qU-je.js → MobileProjects-B79Ob3hy.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-BgY-fvCq.js → Mtc-CxevSZuV.js} +4 -4
- package/src/assets/web-panel/assets/{MtcAudit-B8pCmqQJ.js → MtcAudit-X396cPEX.js} +4 -4
- package/src/assets/web-panel/assets/{Multisig-BbOmYutA.js → Multisig-HWIB_aZ1.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-BocLQz_M.js → NLProgramming-gnYD1Xwy.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-CSwbxEop.js → Notes-Dn2Gf_J1.js} +3 -3
- package/src/assets/web-panel/assets/{NotificationSettings-CqFNSYG3.js → NotificationSettings-BRKBQ5rq.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-C6gMfAk7.js → OrderTableRenderer-Dy___Cgo.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-QrDXVdMJ.js → Organization-cqfccxnt.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-Cxntotjt.js → Overflow-CSX4FHN3.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-CIdBOwNq.js → P2P-Bwa4aghp.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-CT5aP8rD.js → PdhVaultBrowser-Dhszyjig.js} +3 -3
- package/src/assets/web-panel/assets/{Permissions-DH7OM8XU.js → Permissions-CXzTyk6e.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-CnJqbWce.js → PersonalDataHub-CFCAAJbb.js} +4 -4
- package/src/assets/web-panel/assets/{Pipeline-5C3HG1kH.js → Pipeline-BPJbx6xt.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-B4yIp7xK.js → Privacy-BbiXvEHz.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-BMvt-2M0.js → ProjectInit-B-s7-wSD.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-CvSTEMRG.js → ProjectSettings-Dyug206y.js} +2 -2
- package/src/assets/web-panel/assets/{Projects-BKBJxEek.js → Projects-BtAI5Fwo.js} +1 -1
- package/src/assets/web-panel/assets/{Providers-BdwUqFWN.js → Providers-JpIPmz6N.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-DtnCKlTm.js → QrScannerModal-CZdoN64A.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-sTbgwyNr.js → QuickAsk-BwvnoRIT.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-Bzr14gSb.js → Recommend-ASMlMQrD.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-C_TF5IaJ.js → RemoteSession-BiJzKFKi.js} +3 -3
- package/src/assets/web-panel/assets/{Reputation-GCAM4H2K.js → Reputation-C80TWLIO.js} +1 -1
- package/src/assets/web-panel/assets/{Row-Dir0r6OQ.js → Row-C1VNmjmX.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-CpGnlecX.js → RssFeed-T2MyGUlG.js} +3 -3
- package/src/assets/web-panel/assets/{Search-DMMamC6u.js → Search-DXM6O83L.js} +1 -1
- package/src/assets/web-panel/assets/{Security-yqay5yG-.js → Security-nv69kU7W.js} +3 -3
- package/src/assets/web-panel/assets/{Services-C5i2wh9G.js → Services-AyHWe7Qj.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-vUqk35yj.js → Skeleton-D6PWLxFI.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-DzcSkhot.js → Skills-BqVeOmNQ.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-CB6qbYNr.js → Sla-BegIPl9M.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-BHUI7cox.js → SpeechSettings-CKJn3xk-.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-D-RrsxTJ.js → SyncSettings-Th4cnAMl.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-DFxdOJiq.js → Tasks-BuKfBroh.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-SKAob_Aq.js → Templates-CMuWN8Ac.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-BPfsfHQ-.js → Tenant-C4je8E8Q.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-8iw7FpUf.js → Terminal-agJESOcO.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-C4Gjj5Su.js → TimelineRenderer-D2qDuVZ_.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-COYhN18e.js → Tokens-Cvmn99rH.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-B-JzXcf6.js → Trigger-D_QYIHH8.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-BJ5bg0nI.js → Trust-BmzvQLnX.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-BG_ByRMf.js → UkeySign-D_LopHwH.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-B3kOnSiU.js → VideoEditing-DoWl3PhQ.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-CcoGFnK7.js → Wallet-5NYcAkxe.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-DdT8vRC_.js → WebAuthn-B-_Q3ewp.js} +4 -4
- package/src/assets/web-panel/assets/{WorkflowEditor-CZu3M9N8.js → WorkflowEditor-CHET-gi2.js} +1 -1
- package/src/assets/web-panel/assets/{chat-DxJt3Qba.js → chat-C6nvb-n6.js} +1 -1
- package/src/assets/web-panel/assets/{colors-DdYfwJaB.js → colors-CTDE9LTX.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-BG3SUzwj.js → compact-item-KnemdF8D.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-By51z2-1.js → createContext-DUJR3Uek.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-1DqLH1KX.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-B0apZ3KJ.js → hasIn-CFNTaby8.js} +1 -1
- package/src/assets/web-panel/assets/{index-ZxtP8jG7.js → index-65HO56Bv.js} +1 -1
- package/src/assets/web-panel/assets/{index-Da_WBdLX.js → index-B8RtbSkV.js} +1 -1
- package/src/assets/web-panel/assets/{index-BBPf3TpM.js → index-BHqSqnW7.js} +1 -1
- package/src/assets/web-panel/assets/{index-BP94CrBV.js → index-BTetEUWd.js} +1 -1
- package/src/assets/web-panel/assets/{index-p1_8SbI1.js → index-BXWg1crv.js} +1 -1
- package/src/assets/web-panel/assets/{index-BWF8_mkx.js → index-BdiC4LOs.js} +1 -1
- package/src/assets/web-panel/assets/index-BhJtcPWo.js +1 -0
- package/src/assets/web-panel/assets/{index-SQqOlR3d.js → index-BuizJo2E.js} +1 -1
- package/src/assets/web-panel/assets/{index-CpjZhgNd.js → index-BwZM1rod.js} +1 -1
- package/src/assets/web-panel/assets/{index-CzmQElZy.js → index-C96N9xeL.js} +1 -1
- package/src/assets/web-panel/assets/{index-bP_VlDb4.js → index-CHfUdnJH.js} +1 -1
- package/src/assets/web-panel/assets/{index-ZFbps9po.js → index-CKvBF3Ov.js} +1 -1
- package/src/assets/web-panel/assets/{index-DaIz0NAW.js → index-CSD9_I2_.js} +1 -1
- package/src/assets/web-panel/assets/{index-BewKYrX9.js → index-Cc7dbl_p.js} +1 -1
- package/src/assets/web-panel/assets/{index-CNIxXMmN.js → index-CcF0D7UZ.js} +1 -1
- package/src/assets/web-panel/assets/{index-Q2SCX-MI.js → index-Ceu92a8D.js} +1 -1
- package/src/assets/web-panel/assets/{index-DE76D-kA.js → index-CnLpuTAU.js} +1 -1
- package/src/assets/web-panel/assets/index-Cq8MWPDT.js +1 -0
- package/src/assets/web-panel/assets/{index-BkvcEo4p.js → index-CquKnw5r.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cp6e-hGw.js → index-CyEtHvEE.js} +1 -1
- package/src/assets/web-panel/assets/{index-BLIbGOLX.js → index-DF-fcTvQ.js} +1 -1
- package/src/assets/web-panel/assets/{index-DCn8IcxV.js → index-DF1Y0Vuw.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bissefox.js → index-DJyPeBBk.js} +3 -3
- package/src/assets/web-panel/assets/{index-BZ_0qm4g.js → index-DP-PbO11.js} +1 -1
- package/src/assets/web-panel/assets/{index-kf57LJ93.js → index-DZgCRMxk.js} +1 -1
- package/src/assets/web-panel/assets/{index-BYINoRLK.js → index-DfJzS3Qa.js} +1 -1
- package/src/assets/web-panel/assets/{index-3jWkIu5j.js → index-DqPpJkte.js} +1 -1
- package/src/assets/web-panel/assets/{index-B5rLiEo0.js → index-DzReoLyh.js} +1 -1
- package/src/assets/web-panel/assets/{index-CW93tZDv.js → index-JGTiDeOW.js} +1 -1
- package/src/assets/web-panel/assets/{index-C1C9i79A.js → index-NUR0If7O.js} +1 -1
- package/src/assets/web-panel/assets/{index-CAhHirVH.js → index-NtAcnJYW.js} +1 -1
- package/src/assets/web-panel/assets/{index-RD6O-0C6.js → index-OmuhFYKE.js} +1 -1
- package/src/assets/web-panel/assets/{index-oxRrmFO9.js → index-Wlc7o_C8.js} +1 -1
- package/src/assets/web-panel/assets/{index-B3rWuPMW.js → index-bxTPfdri.js} +1 -1
- package/src/assets/web-panel/assets/{index-BIrJfqO4.js → index-k6uorYmf.js} +1 -1
- package/src/assets/web-panel/assets/{index-BfWYsB9t.js → index-ox6mIwE2.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bos5_aMV.js → index-rVDD7AAR.js} +1 -1
- package/src/assets/web-panel/assets/{index-CWEuZWCK.js → index-u0h6QqVV.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dz49VOyQ.js → index-v-mtxmWH.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-BWJktcg8.js → initDefaultProps-qEt8dI-t.js} +1 -1
- package/src/assets/web-panel/assets/{motion-BEXBzUFV.js → motion-DetKPWy-.js} +1 -1
- package/src/assets/web-panel/assets/{move-BUKwn2sx.js → move-BeNYeDV2.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-FTI7btqQ.js → mtc-parser-C0q0MK_T.js} +1 -1
- package/src/assets/web-panel/assets/{omit-CsLtSPH3.js → omit-DLKkrKpE.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-DWZxsT_S.js → pickAttrs-Bw1tWsY8.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-Bcfs43CX.js → placementArrow-DeesBLbd.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-a9bcC1p-.js → responsiveObserve-bqLhxHhn.js} +1 -1
- package/src/assets/web-panel/assets/{slide-BDTzgOXN.js → slide-DGCXRoQm.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-Iq1j_HUg.js → statusUtils-H-re3Egl.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-DAZEYxeh.js → styleChecker-BXg4qGX_.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-DVkjyDrh.js → useFlexGapSupport-CKLb2KA6.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-wXTpNTHt.js → useFs-CTAhHeyw.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-CtQM_aZr.js → usePersonalDataHub-BQ4pDh5g.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-hjEoG85v.js → vnode-jrSK6j4j.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-BHVpyKg_.js → zoom-fOQE24pw.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/command-help-index.json +3 -3
- package/src/commands/agent.js +91 -60
- package/src/commands/git.js +39 -0
- package/src/commands/plugin.js +17 -2
- package/src/commands/session-group.js +131 -0
- package/src/commands/session-location.js +48 -0
- package/src/commands/session.js +11 -0
- package/src/commands/sync-providers.js +4 -1
- package/src/commands/update.js +1 -0
- package/src/data/changelog.json +40 -1
- package/src/gateways/ws/mcp-topic-handlers.js +167 -0
- package/src/gateways/ws/ws-agent-handler.js +20 -12
- package/src/harness/jsonl-session-store.js +279 -37
- package/src/harness/mcp-client.js +701 -91
- package/src/harness/session-index.js +15 -4
- package/src/lib/agent-network.js +166 -29
- package/src/lib/agent-router.js +62 -6
- package/src/lib/agent-sandbox.js +7 -1
- package/src/lib/agent-worktree.js +8 -1
- package/src/lib/auto-mode-safety-classifier.js +3 -17
- package/src/lib/background-agent-keeper-protocol.js +26 -6
- package/src/lib/background-agent-supervisor.js +17 -1
- package/src/lib/browser-evidence.js +1405 -0
- package/src/lib/chrome-connector.js +465 -79
- package/src/lib/claude-code-bridge.js +159 -54
- package/src/lib/claude-project-auto-memory.js +481 -0
- package/src/lib/claude-project-storage-layout.js +104 -0
- package/src/lib/cloud/cloud-client.js +40 -0
- package/src/lib/cowork-workflow.js +69 -6
- package/src/lib/execution-location-local-supervisor.mjs +226 -0
- package/src/lib/execution-location-runner-lifecycle.js +991 -0
- package/src/lib/execution-location-target-preflight.js +333 -0
- package/src/lib/execution-location-target.js +783 -13
- package/src/lib/external-agent-adapters.js +269 -0
- package/src/lib/file-lines.js +6 -1
- package/src/lib/gateway-client-resilience.js +571 -0
- package/src/lib/gitlab-mr-worktree.js +176 -0
- package/src/lib/hooks-v2-producers.js +119 -15
- package/src/lib/hooks-v2-workspace-context.js +44 -1
- package/src/lib/host-resource-budget.js +295 -0
- package/src/lib/ide-context.js +15 -2
- package/src/lib/ipfs-storage.js +127 -25
- package/src/lib/llm-config-defaults.js +43 -0
- package/src/lib/mcp-lifecycle-authority.js +887 -0
- package/src/lib/mcp-oauth.js +101 -20
- package/src/lib/mcp-tls.js +103 -3
- package/src/lib/orchestrator.js +47 -0
- package/src/lib/paths.js +260 -32
- package/src/lib/permission-request.js +48 -0
- package/src/lib/plugin-runtime/bin.js +3 -1
- package/src/lib/plugin-runtime/hooks.js +3 -1
- package/src/lib/plugin-runtime/install.js +117 -1
- package/src/lib/plugin-runtime/lsp.js +4 -4
- package/src/lib/plugin-runtime/marketplace-archive-source.js +40 -5
- package/src/lib/plugin-runtime/marketplace-catalog.js +13 -2
- package/src/lib/plugin-runtime/marketplace-command-descriptor.js +343 -0
- package/src/lib/plugin-runtime/marketplace-command-source.js +580 -0
- package/src/lib/plugin-runtime/marketplace-source-adapter.js +33 -8
- package/src/lib/plugin-runtime/mcp.js +3 -1
- package/src/lib/plugin-runtime/monitors.js +3 -1
- package/src/lib/plugin-runtime/remote-source.js +151 -6
- package/src/lib/plugin-runtime/settings.js +3 -1
- package/src/lib/plugin-runtime/trust.js +274 -13
- package/src/lib/process-execution-broker/credential-agent.js +210 -41
- package/src/lib/process-execution-broker/index.js +15 -1
- package/src/lib/process-execution-broker/linux-cgroup-v2.js +391 -0
- package/src/lib/process-execution-broker/platform-sandbox.js +50 -28
- package/src/lib/project-mcp-trust.js +165 -10
- package/src/lib/resume-session.js +9 -6
- package/src/lib/session-core-singletons.js +26 -11
- package/src/lib/session-host-lease.js +52 -16
- package/src/lib/session-lifecycle-scope.js +153 -0
- package/src/lib/session-message-fabric.js +168 -21
- package/src/lib/session-projection.js +244 -4
- package/src/lib/session-store-guard.js +3 -1
- package/src/lib/session-workbench-store.js +466 -0
- package/src/lib/shell-approval.js +7 -5
- package/src/lib/spellcheck.js +211 -0
- package/src/lib/sub-agent-context.js +9 -9
- package/src/lib/sync-cli-db.js +485 -129
- package/src/lib/sync-credentials.js +31 -20
- package/src/lib/web-fetch.js +112 -40
- package/src/lib/web-search.js +127 -61
- package/src/lib/workflow-engine.js +42 -11
- package/src/lib/workspace-trust.js +793 -0
- package/src/repl/agent-repl.js +124 -5
- package/src/repl/permission-prompt.js +10 -12
- package/src/runtime/agent-core.js +311 -18
- package/src/runtime/agent-runtime.js +12 -1
- package/src/runtime/bootstrap.js +37 -13
- package/src/runtime/coding-agent-contract-shared.cjs +11 -4
- package/src/runtime/headless-runner.js +234 -36
- package/src/runtime/headless-stream.js +181 -6
- package/src/runtime/mcp-config.js +298 -8
- package/src/runtime/policies/agent-policy.js +8 -0
- package/src/runtime/status-diagnostics-lite.js +9 -1
- package/src/assets/web-panel/assets/MarkdownRenderer-CFyt8iUd.js +0 -1
- package/src/assets/web-panel/assets/McpTools-DFaIhOfu.js +0 -7
- package/src/assets/web-panel/assets/devWarning-DorRZcI9.js +0 -1
- package/src/assets/web-panel/assets/index-BETiL0a3.js +0 -1
- package/src/assets/web-panel/assets/index-BhAVHuW8.js +0 -1
|
@@ -20,7 +20,8 @@
|
|
|
20
20
|
import { existsSync, readdirSync, statSync } from "node:fs";
|
|
21
21
|
import { join, basename } from "node:path";
|
|
22
22
|
import { createRequire } from "node:module";
|
|
23
|
-
import { getHomeDir } from "../lib/paths.js";
|
|
23
|
+
import { ensureClaudeProjectStorageTree, getHomeDir } from "../lib/paths.js";
|
|
24
|
+
import { resolveClaudeProjectStorageDir } from "../lib/claude-project-storage-layout.js";
|
|
24
25
|
import { ensurePrivateDirectory, ensurePrivateFile } from "../lib/secure-fs.js";
|
|
25
26
|
import { readVerifiedProjection } from "./jsonl-session-store.js";
|
|
26
27
|
|
|
@@ -39,12 +40,22 @@ export const _deps = {
|
|
|
39
40
|
};
|
|
40
41
|
|
|
41
42
|
function sessionsDir() {
|
|
42
|
-
|
|
43
|
+
const homeDir = getHomeDir();
|
|
44
|
+
return resolveClaudeProjectStorageDir(homeDir) || join(homeDir, "sessions");
|
|
43
45
|
}
|
|
44
46
|
|
|
45
47
|
function indexPath() {
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
+
const homeDir = getHomeDir();
|
|
49
|
+
const projectDir = resolveClaudeProjectStorageDir(homeDir);
|
|
50
|
+
if (projectDir) {
|
|
51
|
+
ensureClaudeProjectStorageTree(homeDir, projectDir);
|
|
52
|
+
}
|
|
53
|
+
const dir = projectDir || homeDir;
|
|
54
|
+
if (!projectDir) ensurePrivateDirectory(dir);
|
|
55
|
+
// Keep the long-standing global cache path for legacy sessions. A
|
|
56
|
+
// Claude-compatible project layout must not make one project's index scan
|
|
57
|
+
// another project's transcripts, so its derived index lives beside those
|
|
58
|
+
// project-local JSONL files.
|
|
48
59
|
return join(dir, "session-index.db");
|
|
49
60
|
}
|
|
50
61
|
|
package/src/lib/agent-network.js
CHANGED
|
@@ -14,6 +14,38 @@
|
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
16
|
import crypto from "crypto";
|
|
17
|
+
import { createSecretStore } from "./secret-store.js";
|
|
18
|
+
|
|
19
|
+
let configuredAgentNetworkSecretStore = null;
|
|
20
|
+
|
|
21
|
+
export function setAgentNetworkSecretStore(secretStore) {
|
|
22
|
+
if (
|
|
23
|
+
!secretStore ||
|
|
24
|
+
typeof secretStore.set !== "function" ||
|
|
25
|
+
typeof secretStore.get !== "function" ||
|
|
26
|
+
typeof secretStore.delete !== "function"
|
|
27
|
+
) {
|
|
28
|
+
throw new TypeError("Agent Network requires a SecretStore");
|
|
29
|
+
}
|
|
30
|
+
configuredAgentNetworkSecretStore = secretStore;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function getAgentNetworkSecretStore() {
|
|
34
|
+
if (!configuredAgentNetworkSecretStore) {
|
|
35
|
+
configuredAgentNetworkSecretStore = createSecretStore({
|
|
36
|
+
service: "chainlesschain-agent-network",
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
return configuredAgentNetworkSecretStore;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function didPrivateKeyRef(did) {
|
|
43
|
+
return `agent-network/did/${crypto.createHash("sha256").update(did).digest("hex")}`;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function authTokenHash(token) {
|
|
47
|
+
return crypto.createHash("sha256").update(String(token)).digest("hex");
|
|
48
|
+
}
|
|
17
49
|
|
|
18
50
|
/* ── Constants ───────────────────────────────────────────── */
|
|
19
51
|
|
|
@@ -77,7 +109,8 @@ export function ensureAgentNetworkTables(db) {
|
|
|
77
109
|
CREATE TABLE IF NOT EXISTS agent_dids (
|
|
78
110
|
did TEXT PRIMARY KEY,
|
|
79
111
|
public_key TEXT NOT NULL,
|
|
80
|
-
private_key TEXT NOT NULL,
|
|
112
|
+
private_key TEXT NOT NULL DEFAULT '',
|
|
113
|
+
private_key_ref TEXT NOT NULL,
|
|
81
114
|
did_document TEXT NOT NULL,
|
|
82
115
|
metadata TEXT,
|
|
83
116
|
status TEXT NOT NULL,
|
|
@@ -124,7 +157,8 @@ export function ensureAgentNetworkTables(db) {
|
|
|
124
157
|
CREATE TABLE IF NOT EXISTS agent_auth_sessions (
|
|
125
158
|
session_id TEXT PRIMARY KEY,
|
|
126
159
|
agent_did TEXT NOT NULL,
|
|
127
|
-
token TEXT NOT NULL,
|
|
160
|
+
token TEXT NOT NULL DEFAULT '',
|
|
161
|
+
token_hash TEXT NOT NULL,
|
|
128
162
|
challenge TEXT NOT NULL,
|
|
129
163
|
status TEXT NOT NULL,
|
|
130
164
|
expires_at INTEGER NOT NULL,
|
|
@@ -161,6 +195,81 @@ export function ensureAgentNetworkTables(db) {
|
|
|
161
195
|
completed_at INTEGER
|
|
162
196
|
)
|
|
163
197
|
`);
|
|
198
|
+
|
|
199
|
+
for (const [table, column, definition] of [
|
|
200
|
+
["agent_dids", "private_key_ref", "TEXT"],
|
|
201
|
+
["agent_auth_sessions", "token_hash", "TEXT"],
|
|
202
|
+
]) {
|
|
203
|
+
const columns = db.prepare(`PRAGMA table_info(${table})`).all();
|
|
204
|
+
if (columns.length > 0 && !columns.some((entry) => entry.name === column)) {
|
|
205
|
+
db.exec(`ALTER TABLE ${table} ADD COLUMN ${column} ${definition}`);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
migrateAgentNetworkSecrets(db);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
export function migrateAgentNetworkSecrets(db, { dryRun = false } = {}) {
|
|
213
|
+
db.exec("PRAGMA secure_delete = ON");
|
|
214
|
+
const didRows = db
|
|
215
|
+
.prepare("SELECT did, private_key, private_key_ref FROM agent_dids")
|
|
216
|
+
.all()
|
|
217
|
+
.filter((row) => row.private_key && !row.private_key_ref);
|
|
218
|
+
const authRows = db
|
|
219
|
+
.prepare("SELECT session_id, token, token_hash FROM agent_auth_sessions")
|
|
220
|
+
.all()
|
|
221
|
+
.filter((row) => row.token && !row.token_hash);
|
|
222
|
+
|
|
223
|
+
if (dryRun) {
|
|
224
|
+
return {
|
|
225
|
+
pendingPrivateKeys: didRows.length,
|
|
226
|
+
pendingTokens: authRows.length,
|
|
227
|
+
migratedPrivateKeys: 0,
|
|
228
|
+
migratedTokens: 0,
|
|
229
|
+
dryRun: true,
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
if (
|
|
234
|
+
(didRows.length > 0 || authRows.length > 0) &&
|
|
235
|
+
typeof db.transaction !== "function"
|
|
236
|
+
) {
|
|
237
|
+
throw new Error(
|
|
238
|
+
"Agent Network secret migration requires transactional database support",
|
|
239
|
+
);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
const secretStore = didRows.length > 0 ? getAgentNetworkSecretStore() : null;
|
|
243
|
+
const stagedKeyRefs = [];
|
|
244
|
+
try {
|
|
245
|
+
for (const row of didRows) {
|
|
246
|
+
const keyRef = didPrivateKeyRef(row.did);
|
|
247
|
+
secretStore.set(keyRef, row.private_key);
|
|
248
|
+
stagedKeyRefs.push(keyRef);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
const applyMigration = db.transaction(() => {
|
|
252
|
+
for (const row of didRows) {
|
|
253
|
+
const keyRef = didPrivateKeyRef(row.did);
|
|
254
|
+
db.prepare(
|
|
255
|
+
"UPDATE agent_dids SET private_key = ?, private_key_ref = ? WHERE did = ?",
|
|
256
|
+
).run("", keyRef, row.did);
|
|
257
|
+
}
|
|
258
|
+
for (const row of authRows) {
|
|
259
|
+
db.prepare(
|
|
260
|
+
"UPDATE agent_auth_sessions SET token = ?, token_hash = ? WHERE session_id = ?",
|
|
261
|
+
).run("", authTokenHash(row.token), row.session_id);
|
|
262
|
+
}
|
|
263
|
+
});
|
|
264
|
+
applyMigration();
|
|
265
|
+
} catch (error) {
|
|
266
|
+
for (const keyRef of stagedKeyRefs) secretStore.delete(keyRef);
|
|
267
|
+
throw error;
|
|
268
|
+
}
|
|
269
|
+
return {
|
|
270
|
+
migratedPrivateKeys: didRows.length,
|
|
271
|
+
migratedTokens: authRows.length,
|
|
272
|
+
};
|
|
164
273
|
}
|
|
165
274
|
|
|
166
275
|
/* ── Helpers ─────────────────────────────────────────────── */
|
|
@@ -258,6 +367,7 @@ export function createAgentDID(db, { displayName, metadata = {} } = {}) {
|
|
|
258
367
|
.slice(0, 32);
|
|
259
368
|
const did = `did:chainless:${idHash}`;
|
|
260
369
|
const now = _now();
|
|
370
|
+
const privateKeyRef = didPrivateKeyRef(did);
|
|
261
371
|
|
|
262
372
|
const didDocument = {
|
|
263
373
|
"@context": ["https://www.w3.org/ns/did/v1"],
|
|
@@ -284,20 +394,28 @@ export function createAgentDID(db, { displayName, metadata = {} } = {}) {
|
|
|
284
394
|
: [],
|
|
285
395
|
};
|
|
286
396
|
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
397
|
+
const secretStore = getAgentNetworkSecretStore();
|
|
398
|
+
secretStore.set(privateKeyRef, privateKey);
|
|
399
|
+
try {
|
|
400
|
+
db.prepare(
|
|
401
|
+
`INSERT INTO agent_dids
|
|
402
|
+
(did, public_key, private_key, private_key_ref, did_document, metadata, status, created_at, updated_at)
|
|
403
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
404
|
+
).run(
|
|
405
|
+
did,
|
|
406
|
+
publicKey,
|
|
407
|
+
"",
|
|
408
|
+
privateKeyRef,
|
|
409
|
+
JSON.stringify(didDocument),
|
|
410
|
+
_json({ displayName, ...metadata }),
|
|
411
|
+
DID_STATUS.ACTIVE,
|
|
412
|
+
now,
|
|
413
|
+
now,
|
|
414
|
+
);
|
|
415
|
+
} catch (error) {
|
|
416
|
+
secretStore.delete(privateKeyRef);
|
|
417
|
+
throw error;
|
|
418
|
+
}
|
|
301
419
|
|
|
302
420
|
return { did, publicKey, didDocument };
|
|
303
421
|
}
|
|
@@ -351,12 +469,19 @@ export function deactivateAgentDID(db, did) {
|
|
|
351
469
|
|
|
352
470
|
export function signWithAgent(db, did, data) {
|
|
353
471
|
const row = db
|
|
354
|
-
.prepare(`SELECT
|
|
472
|
+
.prepare(`SELECT private_key_ref, status FROM agent_dids WHERE did = ?`)
|
|
355
473
|
.get(did);
|
|
356
474
|
if (!row) throw new Error(`Unknown agent DID: ${did}`);
|
|
357
475
|
if (row.status !== DID_STATUS.ACTIVE)
|
|
358
476
|
throw new Error(`Agent DID is not active: ${did}`);
|
|
359
|
-
|
|
477
|
+
if (!row.private_key_ref) {
|
|
478
|
+
throw new Error(`Agent DID private key reference is missing: ${did}`);
|
|
479
|
+
}
|
|
480
|
+
const privateKey = getAgentNetworkSecretStore().get(row.private_key_ref);
|
|
481
|
+
if (!privateKey) {
|
|
482
|
+
throw new Error(`Agent DID private key is unavailable: ${did}`);
|
|
483
|
+
}
|
|
484
|
+
return _signEd25519(privateKey, data);
|
|
360
485
|
}
|
|
361
486
|
|
|
362
487
|
export function verifyWithAgent(db, did, data, signature) {
|
|
@@ -557,14 +682,13 @@ export function startAuth(db, did) {
|
|
|
557
682
|
throw new Error(`Agent DID not active: ${did}`);
|
|
558
683
|
const sessionId = _uuid();
|
|
559
684
|
const challenge = _hex(crypto.randomBytes(32));
|
|
560
|
-
const token = _hex(crypto.randomBytes(24));
|
|
561
685
|
const now = _now();
|
|
562
686
|
const expires = now + SESSION_TTL_MS;
|
|
563
687
|
db.prepare(
|
|
564
688
|
`INSERT INTO agent_auth_sessions
|
|
565
|
-
(session_id, agent_did, token, challenge, status, expires_at, created_at)
|
|
566
|
-
VALUES (?, ?, ?, ?, ?, ?, ?)`,
|
|
567
|
-
).run(sessionId, did,
|
|
689
|
+
(session_id, agent_did, token, token_hash, challenge, status, expires_at, created_at)
|
|
690
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
691
|
+
).run(sessionId, did, "", "", challenge, AUTH_STATUS.PENDING, expires, now);
|
|
568
692
|
return { sessionId, challenge, expiresAt: expires };
|
|
569
693
|
}
|
|
570
694
|
|
|
@@ -584,21 +708,23 @@ export function completeAuth(db, sessionId, signatureHex) {
|
|
|
584
708
|
}
|
|
585
709
|
const ok = verifyWithAgent(db, row.agent_did, row.challenge, signatureHex);
|
|
586
710
|
if (!ok) throw new Error(`Signature verification failed`);
|
|
711
|
+
const token = _hex(crypto.randomBytes(24));
|
|
587
712
|
db.prepare(
|
|
588
|
-
`UPDATE agent_auth_sessions SET status = ? WHERE session_id = ?`,
|
|
589
|
-
).run(AUTH_STATUS.ACTIVE, sessionId);
|
|
713
|
+
`UPDATE agent_auth_sessions SET status = ?, token = ?, token_hash = ? WHERE session_id = ?`,
|
|
714
|
+
).run(AUTH_STATUS.ACTIVE, "", authTokenHash(token), sessionId);
|
|
590
715
|
return {
|
|
591
716
|
sessionId,
|
|
592
|
-
token
|
|
717
|
+
token,
|
|
593
718
|
agentDid: row.agent_did,
|
|
594
719
|
expiresAt: row.expires_at,
|
|
595
720
|
};
|
|
596
721
|
}
|
|
597
722
|
|
|
598
723
|
export function validateSession(db, token) {
|
|
724
|
+
if (typeof token !== "string" || token.length === 0) return null;
|
|
599
725
|
const row = db
|
|
600
|
-
.prepare(`SELECT * FROM agent_auth_sessions WHERE
|
|
601
|
-
.get(token);
|
|
726
|
+
.prepare(`SELECT * FROM agent_auth_sessions WHERE token_hash = ?`)
|
|
727
|
+
.get(authTokenHash(token));
|
|
602
728
|
if (!row) return null;
|
|
603
729
|
const now = _now();
|
|
604
730
|
if (row.status !== AUTH_STATUS.ACTIVE) return null;
|
|
@@ -659,13 +785,24 @@ export function issueCredential(
|
|
|
659
785
|
if (!issuerDid) throw new Error("issuerDid is required");
|
|
660
786
|
if (!subjectDid) throw new Error("subjectDid is required");
|
|
661
787
|
const issuer = db
|
|
662
|
-
.prepare(`SELECT
|
|
788
|
+
.prepare(`SELECT private_key_ref, status FROM agent_dids WHERE did = ?`)
|
|
663
789
|
.get(issuerDid);
|
|
664
790
|
if (!issuer) throw new Error(`Unknown issuer DID: ${issuerDid}`);
|
|
665
791
|
if (issuer.status !== DID_STATUS.ACTIVE)
|
|
666
792
|
throw new Error(`Issuer DID not active: ${issuerDid}`);
|
|
667
793
|
const subject = resolveAgentDID(db, subjectDid);
|
|
668
794
|
if (!subject) throw new Error(`Unknown subject DID: ${subjectDid}`);
|
|
795
|
+
if (!issuer.private_key_ref) {
|
|
796
|
+
throw new Error(
|
|
797
|
+
`Issuer DID private key reference is missing: ${issuerDid}`,
|
|
798
|
+
);
|
|
799
|
+
}
|
|
800
|
+
const issuerPrivateKey = getAgentNetworkSecretStore().get(
|
|
801
|
+
issuer.private_key_ref,
|
|
802
|
+
);
|
|
803
|
+
if (!issuerPrivateKey) {
|
|
804
|
+
throw new Error(`Issuer DID private key is unavailable: ${issuerDid}`);
|
|
805
|
+
}
|
|
669
806
|
const now = _now();
|
|
670
807
|
const id = `vc:${_uuid()}`;
|
|
671
808
|
const payload = {
|
|
@@ -677,7 +814,7 @@ export function issueCredential(
|
|
|
677
814
|
issuedAt: now,
|
|
678
815
|
expiresAt,
|
|
679
816
|
};
|
|
680
|
-
const proof = _credentialProof(
|
|
817
|
+
const proof = _credentialProof(issuerPrivateKey, payload);
|
|
681
818
|
db.prepare(
|
|
682
819
|
`INSERT INTO agent_credentials
|
|
683
820
|
(id, issuer_did, subject_did, type, claims, proof, status, issued_at, expires_at)
|
package/src/lib/agent-router.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Routes coding subtasks across multiple agent backends in parallel:
|
|
5
5
|
* - claude (Claude Code CLI — best for complex reasoning)
|
|
6
|
-
* - codex (
|
|
6
|
+
* - codex (OpenAI Codex CLI — good for repo context)
|
|
7
7
|
* - gemini (Google Gemini via ChainlessChain LLM provider)
|
|
8
8
|
* - openai (GPT-4o via ChainlessChain LLM provider)
|
|
9
9
|
* - ollama (Local LLM — offline / private)
|
|
@@ -32,6 +32,12 @@ import {
|
|
|
32
32
|
detectCodex,
|
|
33
33
|
} from "./claude-code-bridge.js";
|
|
34
34
|
import { createChatFn } from "./cowork-adapter.js";
|
|
35
|
+
import runtimeClaimsContract from "@chainlesschain/session-core/runtime-claims";
|
|
36
|
+
|
|
37
|
+
const { RUNTIME_MODE, createRuntimeClaims } = runtimeClaimsContract;
|
|
38
|
+
const SIMULATED_API_CLAIMS = createRuntimeClaims({
|
|
39
|
+
mode: RUNTIME_MODE.SIMULATED,
|
|
40
|
+
});
|
|
35
41
|
|
|
36
42
|
// ─── Backend type constants ───────────────────────────────────────
|
|
37
43
|
export const BACKEND_TYPE = {
|
|
@@ -70,6 +76,37 @@ const TYPE_KEYWORDS = {
|
|
|
70
76
|
research: ["research", "investigate", "explore", "compare"],
|
|
71
77
|
};
|
|
72
78
|
|
|
79
|
+
export const AGENT_ROUTER_ERROR = Object.freeze({
|
|
80
|
+
WRITE_ISOLATION_REQUIRED: "AGENT_ROUTER_WRITE_ISOLATION_REQUIRED",
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
function normalizedScopes(task) {
|
|
84
|
+
if (!Array.isArray(task?.scopePaths) || task.scopePaths.length === 0) {
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
return task.scopePaths.map(
|
|
88
|
+
(scope) => String(scope).replace(/\\/g, "/").replace(/\/+$/u, "") + "/",
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export function assignmentsHaveDisjointWrites(assignments) {
|
|
93
|
+
if (assignments.every(({ task }) => task?.effects === "read-only")) {
|
|
94
|
+
return true;
|
|
95
|
+
}
|
|
96
|
+
const scopes = assignments.map(({ task }) => normalizedScopes(task));
|
|
97
|
+
if (scopes.some((scope) => scope === null)) return false;
|
|
98
|
+
for (let i = 0; i < scopes.length; i += 1) {
|
|
99
|
+
for (let j = i + 1; j < scopes.length; j += 1) {
|
|
100
|
+
for (const left of scopes[i]) {
|
|
101
|
+
for (const right of scopes[j]) {
|
|
102
|
+
if (left.startsWith(right) || right.startsWith(left)) return false;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return true;
|
|
108
|
+
}
|
|
109
|
+
|
|
73
110
|
function detectTaskType(description) {
|
|
74
111
|
const lower = description.toLowerCase();
|
|
75
112
|
for (const [type, keywords] of Object.entries(TYPE_KEYWORDS)) {
|
|
@@ -116,20 +153,26 @@ async function executeViaAPI(task, options) {
|
|
|
116
153
|
]);
|
|
117
154
|
|
|
118
155
|
return {
|
|
119
|
-
success:
|
|
156
|
+
success: false,
|
|
157
|
+
status: "simulated",
|
|
120
158
|
output,
|
|
121
159
|
exitCode: 0,
|
|
122
160
|
duration: Date.now() - startTime,
|
|
123
161
|
agentId: `api-${provider}`,
|
|
162
|
+
runtimeClaims: SIMULATED_API_CLAIMS,
|
|
163
|
+
terminalEvidence: [],
|
|
124
164
|
};
|
|
125
165
|
} catch (err) {
|
|
126
166
|
return {
|
|
127
167
|
success: false,
|
|
168
|
+
status: "failed",
|
|
128
169
|
output: "",
|
|
129
170
|
exitCode: -1,
|
|
130
171
|
duration: Date.now() - startTime,
|
|
131
172
|
agentId: `api-${provider}`,
|
|
132
173
|
error: err.message,
|
|
174
|
+
runtimeClaims: SIMULATED_API_CLAIMS,
|
|
175
|
+
terminalEvidence: [],
|
|
133
176
|
};
|
|
134
177
|
}
|
|
135
178
|
}
|
|
@@ -257,6 +300,13 @@ export class AgentRouter extends EventEmitter {
|
|
|
257
300
|
|
|
258
301
|
/** Parallel-all: run every task on ALL backends; return best result per task. */
|
|
259
302
|
async _dispatchParallelAll(subtasks, { cwd }) {
|
|
303
|
+
if (this._backends.length > 1) {
|
|
304
|
+
const error = new Error(
|
|
305
|
+
"parallel-all requires per-attempt worktrees and accepted-winner merge",
|
|
306
|
+
);
|
|
307
|
+
error.code = AGENT_ROUTER_ERROR.WRITE_ISOLATION_REQUIRED;
|
|
308
|
+
throw error;
|
|
309
|
+
}
|
|
260
310
|
const results = [];
|
|
261
311
|
for (const task of subtasks) {
|
|
262
312
|
const allResults = await Promise.all(
|
|
@@ -276,10 +326,15 @@ export class AgentRouter extends EventEmitter {
|
|
|
276
326
|
|
|
277
327
|
async _runAssignments(assignments, { cwd }) {
|
|
278
328
|
const results = new Array(assignments.length);
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
329
|
+
const concurrency = assignmentsHaveDisjointWrites(assignments)
|
|
330
|
+
? this.maxParallel
|
|
331
|
+
: 1;
|
|
332
|
+
|
|
333
|
+
// Shared writable cwd tasks are serialized unless their declared write
|
|
334
|
+
// scopes are statically disjoint. Candidate fan-out is rejected above
|
|
335
|
+
// until it has per-attempt worktrees and winner-only merge semantics.
|
|
336
|
+
for (let i = 0; i < assignments.length; i += concurrency) {
|
|
337
|
+
const batch = assignments.slice(i, i + concurrency);
|
|
283
338
|
const batchResults = await Promise.all(
|
|
284
339
|
batch.map(({ task, backend }) =>
|
|
285
340
|
this._runSingleTask(task, backend, { cwd }),
|
|
@@ -332,6 +387,7 @@ export class AgentRouter extends EventEmitter {
|
|
|
332
387
|
maxParallel: 1,
|
|
333
388
|
cliCommand: type === BACKEND_TYPE.CODEX ? "codex" : "claude",
|
|
334
389
|
model: cfg.model || null,
|
|
390
|
+
sandbox: cfg.sandbox || null,
|
|
335
391
|
});
|
|
336
392
|
pool.on("agent:output", (ev) => this.emit("agent:output", ev));
|
|
337
393
|
return {
|
package/src/lib/agent-sandbox.js
CHANGED
|
@@ -259,7 +259,13 @@ export function normalizeAgentSandbox(value, options = {}) {
|
|
|
259
259
|
*/
|
|
260
260
|
export function normalizeAgentSandboxMode(mode, value, options = {}) {
|
|
261
261
|
if (mode == null || mode === "") {
|
|
262
|
-
|
|
262
|
+
// Public agent execution defaults to a real, fail-closed workspace
|
|
263
|
+
// sandbox. Bare-host execution remains available only through the
|
|
264
|
+
// explicit `off` mode below, where managed policy can prohibit it.
|
|
265
|
+
return normalizeAgentSandboxMode("workspace-write", value || true, {
|
|
266
|
+
...options,
|
|
267
|
+
network: false,
|
|
268
|
+
});
|
|
263
269
|
}
|
|
264
270
|
if (!AGENT_SANDBOX_MODES.includes(mode)) {
|
|
265
271
|
const error = new Error(
|
|
@@ -244,7 +244,14 @@ export function finishAgentWorktree(info, { deps = _deps } = {}) {
|
|
|
244
244
|
let headSha = null;
|
|
245
245
|
let readable = false;
|
|
246
246
|
try {
|
|
247
|
-
|
|
247
|
+
// Do not inherit status.showUntrackedFiles=no from repository/user config:
|
|
248
|
+
// an untracked agent output is still work that finalize must preserve.
|
|
249
|
+
dirty =
|
|
250
|
+
git(
|
|
251
|
+
["status", "--porcelain=v1", "--untracked-files=all"],
|
|
252
|
+
info.path,
|
|
253
|
+
deps,
|
|
254
|
+
).trim().length > 0;
|
|
248
255
|
headSha = git(["rev-parse", "HEAD"], info.path, deps).trim();
|
|
249
256
|
readable = true;
|
|
250
257
|
} catch {
|
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
isSecretEnvName,
|
|
21
21
|
} from "./credential-guard.js";
|
|
22
22
|
import { containsSecret } from "./secret-scan.js";
|
|
23
|
+
import { normalizePermissionRequest } from "./permission-request.js";
|
|
23
24
|
|
|
24
25
|
const require_ = createRequire(import.meta.url);
|
|
25
26
|
const shellPolicy = require_("../runtime/coding-agent-shell-policy.cjs");
|
|
@@ -459,21 +460,6 @@ function canonicalShellKeyword(token) {
|
|
|
459
460
|
.replace(/\\(.)/g, "$1");
|
|
460
461
|
}
|
|
461
462
|
|
|
462
|
-
function inputCommand(input) {
|
|
463
|
-
const command = input?.args?.command;
|
|
464
|
-
if (typeof command === "string") return command;
|
|
465
|
-
const argv = input?.args?.argv;
|
|
466
|
-
return Array.isArray(argv)
|
|
467
|
-
? argv
|
|
468
|
-
.map((value) => {
|
|
469
|
-
const token = String(value);
|
|
470
|
-
if (token && !/[\s|;&"'\\]/.test(token)) return token;
|
|
471
|
-
return `"${token.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
|
|
472
|
-
})
|
|
473
|
-
.join(" ")
|
|
474
|
-
: "";
|
|
475
|
-
}
|
|
476
|
-
|
|
477
463
|
function workspaceRoots(context = {}) {
|
|
478
464
|
const roots = [];
|
|
479
465
|
if (Array.isArray(context.workspaceRoots)) {
|
|
@@ -1817,7 +1803,7 @@ export function classifyAutoModeSafety(input = {}) {
|
|
|
1817
1803
|
const args = input.args && typeof input.args === "object" ? input.args : {};
|
|
1818
1804
|
const context =
|
|
1819
1805
|
input.context && typeof input.context === "object" ? input.context : {};
|
|
1820
|
-
const command =
|
|
1806
|
+
const command = normalizePermissionRequest({ tool, args }).command;
|
|
1821
1807
|
const segments = collectCommandSegments(command);
|
|
1822
1808
|
const argsText = stableSerialize(args);
|
|
1823
1809
|
const baseRiskLevel = normalizeRisk(input.baseRiskLevel, "medium");
|
|
@@ -2000,7 +1986,7 @@ export function evaluateAutoModeSafety(input = {}, opts = {}) {
|
|
|
2000
1986
|
: classifyAutoModeSafety;
|
|
2001
1987
|
const classification = classifier(input);
|
|
2002
1988
|
const tool = String(input?.tool || "unknown").toLowerCase();
|
|
2003
|
-
const command =
|
|
1989
|
+
const command = normalizePermissionRequest(input).command;
|
|
2004
1990
|
let policy = null;
|
|
2005
1991
|
if (tool === "run_shell") {
|
|
2006
1992
|
const result = evaluateShellCommandPolicy(command, {
|
|
@@ -257,12 +257,16 @@ export function prepareBackgroundAgentLocalPipePath(
|
|
|
257
257
|
{ platform = process.platform } = {},
|
|
258
258
|
) {
|
|
259
259
|
if (platform === "win32") return pipePath;
|
|
260
|
-
const
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
260
|
+
const normalizedPipePath = posix.resolve(
|
|
261
|
+
String(pipePath || "").replaceAll("\\", "/"),
|
|
262
|
+
);
|
|
263
|
+
const directory = posix.dirname(normalizedPipePath);
|
|
264
|
+
if (fallbackLocalPipeDirectory(pipePath)) {
|
|
265
|
+
try {
|
|
266
|
+
mkdirSync(directory, { mode: 0o700 });
|
|
267
|
+
} catch (error) {
|
|
268
|
+
if (error?.code !== "EEXIST") throw error;
|
|
269
|
+
}
|
|
266
270
|
}
|
|
267
271
|
const stat = lstatSync(directory);
|
|
268
272
|
const uid = typeof process.getuid === "function" ? process.getuid() : null;
|
|
@@ -274,6 +278,22 @@ export function prepareBackgroundAgentLocalPipePath(
|
|
|
274
278
|
) {
|
|
275
279
|
throw new Error("background agent socket directory is not private");
|
|
276
280
|
}
|
|
281
|
+
|
|
282
|
+
let socketStat = null;
|
|
283
|
+
try {
|
|
284
|
+
socketStat = lstatSync(normalizedPipePath);
|
|
285
|
+
} catch (error) {
|
|
286
|
+
if (error?.code !== "ENOENT") throw error;
|
|
287
|
+
}
|
|
288
|
+
if (socketStat) {
|
|
289
|
+
if (
|
|
290
|
+
socketStat.isSymbolicLink() ||
|
|
291
|
+
!socketStat.isSocket() ||
|
|
292
|
+
(uid !== null && socketStat.uid !== uid)
|
|
293
|
+
) {
|
|
294
|
+
throw new Error("background agent socket path is not an owned socket");
|
|
295
|
+
}
|
|
296
|
+
}
|
|
277
297
|
return pipePath;
|
|
278
298
|
}
|
|
279
299
|
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
|
+
chmodSync,
|
|
2
3
|
closeSync,
|
|
3
4
|
existsSync,
|
|
5
|
+
lstatSync,
|
|
4
6
|
mkdirSync,
|
|
5
7
|
openSync,
|
|
6
8
|
readFileSync,
|
|
@@ -651,7 +653,21 @@ export function backgroundAgentsDir() {
|
|
|
651
653
|
const dir =
|
|
652
654
|
process.env.CC_BACKGROUND_AGENTS_DIR ||
|
|
653
655
|
join(getHomeDir(), "background-agents");
|
|
654
|
-
if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
|
|
656
|
+
if (!existsSync(dir)) mkdirSync(dir, { recursive: true, mode: 0o700 });
|
|
657
|
+
if (process.platform !== "win32") {
|
|
658
|
+
const stat = lstatSync(dir);
|
|
659
|
+
const uid = typeof process.getuid === "function" ? process.getuid() : null;
|
|
660
|
+
if (
|
|
661
|
+
!stat.isDirectory() ||
|
|
662
|
+
stat.isSymbolicLink() ||
|
|
663
|
+
(uid !== null && stat.uid !== uid)
|
|
664
|
+
) {
|
|
665
|
+
throw new Error(
|
|
666
|
+
"background agent state directory is not owner-controlled",
|
|
667
|
+
);
|
|
668
|
+
}
|
|
669
|
+
chmodSync(dir, 0o700);
|
|
670
|
+
}
|
|
655
671
|
return dir;
|
|
656
672
|
}
|
|
657
673
|
|