chainlesschain 0.163.7 → 0.164.0
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 +5 -1
- package/scripts/macos-mcp-launcher-build.mjs +317 -0
- package/scripts/macos-mcp-launcher-postinstall.sh +54 -0
- package/scripts/macos-mcp-launcher-preinstall.sh +61 -0
- package/src/assets/web-panel/assets/{AIOps-axqQfwv8.js → AIOps-D2MEn7fI.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-DV-Ro0By.js → ActionButton-lCW_4Gf0.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-Bt72WEVu.js → Analytics-Bs7i-nsS.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-BtepG55E.js → AppLayout-CK7B6S_j.js} +5 -5
- package/src/assets/web-panel/assets/{Artifacts-B7KaJ7S_.js → Artifacts-C8ILjpyo.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-FNFaUg7A.js → Audit-Bb9cNaWc.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-DFb6J2wQ.js → BackgroundAgents-sC9ooXIf.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-CC7YBhyj.js → Backup-D-DrsplT.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-RkgTNVtj.js → BaseInput-uCNZpwSK.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-hHEmGZy-.js → Chat-CsDK1uE9.js} +6 -6
- package/src/assets/web-panel/assets/{ChatBubbleRenderer-CAP9YhHv.js → ChatBubbleRenderer-OqSDt50w.js} +1 -1
- package/src/assets/web-panel/assets/{Checkbox-z5wXOQP1.js → Checkbox-JhTXM1-K.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-DVaDJnxy.js → Codegen-BbzZLnyD.js} +1 -1
- package/src/assets/web-panel/assets/{Col-CJmaRDR5.js → Col-D4VW4m4j.js} +1 -1
- package/src/assets/web-panel/assets/{Community-DF29_2bI.js → Community-BXrYawxV.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-DtkQkBzn.js → Compact-DCihGy1u.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-xoHDxp7I.js → Compliance-DlyZ-lk8.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-BUm-R7ht.js → Cowork-DvGZrhbO.js} +2 -2
- package/src/assets/web-panel/assets/{Cron-Cgl14ZkB.js → Cron-DUncZi8h.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-BNcbmoqh.js → Crosschain-C_hLuUcm.js} +1 -1
- package/src/assets/web-panel/assets/{DID-Bwja0Zo9.js → DID-b6YSUqxr.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-Bk5XjEdJ.js → Dashboard-uvM15Cfb.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-Ci36Oitq.js → Dropdown-D1-Nd4qY.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer--U04ZN4q.js → EmailListRenderer-8ApvL6Zc.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-B2gNPR2s.js → FamilyGuardDashboard-LYJt8811.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-C4KghYn7.js → Federation-BbI3HGpv.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-QL7x_Q_0.js → FormItemContext-DSoEKuFu.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-F3Ryltwm.js → GenericCardRenderer-B0S9OWd5.js} +1 -1
- package/src/assets/web-panel/assets/{Git-2HassK5k.js → Git-DIs9Zhf3.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-DoBIp7oe.js → Governance-jzZXrxcl.js} +1 -1
- package/src/assets/web-panel/assets/{Inference--W01QhZ-.js → Inference-JUPjf2ZI.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-DmvwqGpT.js → KnowledgeGraph-DxnfJvlP.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-BBJ4yAel.js → Logs-iXiz8BEE.js} +2 -2
- package/src/assets/web-panel/assets/{MarkdownRenderer-BLCZMzhJ.js → MarkdownRenderer-GmB6DOr6.js} +1 -1
- package/src/assets/web-panel/assets/{Marketplace-D5lNngSI.js → Marketplace-Y3Xch312.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-CkEVOMKH.js → McpTools-D7kGGbO7.js} +4 -4
- package/src/assets/web-panel/assets/{Memory-B1Ow1xVE.js → Memory-Do_hVxzh.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-SgYbUfb6.js → MobileBridge-CtrR0Tas.js} +1 -1
- package/src/assets/web-panel/assets/MobileProjects-BL0Czcoj.js +1 -0
- package/src/assets/web-panel/assets/{Mtc-DcTXSSma.js → Mtc-qo5QCTGd.js} +2 -2
- package/src/assets/web-panel/assets/{MtcAudit-Dt3WG4oj.js → MtcAudit-cq5mnjYj.js} +2 -2
- package/src/assets/web-panel/assets/{Multisig-B9B38UZx.js → Multisig-Bq0MAQHw.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-B0S4GGvG.js → NLProgramming-DdWE6Vi2.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-DZ5U58Ng.js → Notes-BxMBFcIp.js} +3 -3
- package/src/assets/web-panel/assets/{NotificationSettings-PjL5ZW34.js → NotificationSettings-RTrAcbUe.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-DrAX2ESt.js → OrderTableRenderer-DJbpGqzT.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-Cv1GYs-c.js → Organization-SQzIPdqC.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-Bbkp_PL3.js → Overflow-02yECh22.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-BD8QUgoZ.js → P2P-BNg4pNCM.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-BO-2PeaB.js → PdhVaultBrowser-BxPJZsD3.js} +3 -3
- package/src/assets/web-panel/assets/{Permissions-D_OPVa02.js → Permissions-CLnDnPAz.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-mh-pEmaB.js → PersonalDataHub-C5m0AjGf.js} +4 -4
- package/src/assets/web-panel/assets/{Pipeline-6JC2EDdb.js → Pipeline-VwOf5Dhv.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-CUshzUAG.js → Privacy-CC0W2hZd.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-Cs2Aalri.js → ProjectInit-Dz893Bob.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-1ak49tcj.js → ProjectSettings-CxQkvl0k.js} +2 -2
- package/src/assets/web-panel/assets/Projects-DDAjkUkT.js +1 -0
- package/src/assets/web-panel/assets/{Providers-CXXxvafH.js → Providers-DeB9IkxK.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-PTcDsF58.js → QrScannerModal-OCeoaswn.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-CDwucrJw.js → QuickAsk-DenotaAj.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-CJlLVRXR.js → Recommend-Cies_jjI.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-DlN-ETsO.js → RemoteSession-Dxzl5n2T.js} +3 -3
- package/src/assets/web-panel/assets/{Reputation-DI23LR6m.js → Reputation-CW0mvxgZ.js} +1 -1
- package/src/assets/web-panel/assets/{Row-Cl7UQMrM.js → Row-SEd32qZU.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-CexHNfh8.js → RssFeed-BSwnJ3Lm.js} +3 -3
- package/src/assets/web-panel/assets/{Search-BneBWvRN.js → Search-xe2m8bkC.js} +1 -1
- package/src/assets/web-panel/assets/{Security-DX7Phgrp.js → Security-Mq2F9Nro.js} +4 -4
- package/src/assets/web-panel/assets/{Services-BWXO8Mte.js → Services-BKGw2V3P.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-DCyOjKPJ.js → Skeleton-DW95-Rxf.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-CXqERsTB.js → Skills-CHgChCv_.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-bhbrbz8E.js → Sla-tKh6k3R7.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-3IPU0HBZ.js → SpeechSettings-D6UL3dA5.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-DBNTQLbM.js → SyncSettings-D0Fw8fVL.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-quP0bkN-.js → Tasks-20x1GB3D.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-BouWmgho.js → Templates-DJ-lts-a.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-qv0D9s7z.js → Tenant-BFdGpbs7.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-BxvbE8BB.js → Terminal-Xpx61vHL.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-D-IeLnJ2.js → TimelineRenderer-C6UIvyZQ.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-CFMKKyVG.js → Tokens-Dellq08f.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-L8as3UuJ.js → Trigger-VKw8d0J-.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-MxmA4VZG.js → Trust-DNftdKT5.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-C0VvJYRi.js → UkeySign-DX9VAKJI.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-Bf5QZj8N.js → VideoEditing-B2h3jO8q.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-BIJ9riRz.js → Wallet-CjGkof7f.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-B8p9Mhkw.js → WebAuthn-2Zfcu55P.js} +4 -4
- package/src/assets/web-panel/assets/{WorkflowEditor-BVsuaPen.js → WorkflowEditor-B9eZ8UxZ.js} +1 -1
- package/src/assets/web-panel/assets/{chat-BfkjoKpV.js → chat-CQNfD-YO.js} +1 -1
- package/src/assets/web-panel/assets/{colors-DeAlsWK8.js → colors-D4usyFT2.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-Cs97bz5j.js → compact-item-s4TpjvjX.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-BqbG60LH.js → createContext-BRCSvYxj.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-DKJjSWRn.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-i_RY0b1X.js → hasIn-AdkUbkV-.js} +1 -1
- package/src/assets/web-panel/assets/{index-BOVkf1K3.js → index--00U6vXZ.js} +1 -1
- package/src/assets/web-panel/assets/{index-B-3tEpTc.js → index-B2V-eKfK.js} +1 -1
- package/src/assets/web-panel/assets/{index-D2B4VPyP.js → index-B4JJCfQ2.js} +1 -1
- package/src/assets/web-panel/assets/{index-BkBi5TmC.js → index-BIoG5yYf.js} +1 -1
- package/src/assets/web-panel/assets/{index-79V_zv1s.js → index-BMcimU-2.js} +1 -1
- package/src/assets/web-panel/assets/{index-U4f5izHz.js → index-BPhkFZ1I.js} +1 -1
- package/src/assets/web-panel/assets/{index-DiSkx4UB.js → index-BQ3DXBtD.js} +3 -3
- package/src/assets/web-panel/assets/{index-dIHr4B_u.js → index-Bad4VNvz.js} +1 -1
- package/src/assets/web-panel/assets/{index-CIG8fQ2_.js → index-BgiXR_-_.js} +1 -1
- package/src/assets/web-panel/assets/{index-DqBgBpgp.js → index-BtobShro.js} +1 -1
- package/src/assets/web-panel/assets/{index-ZxO_-E8a.js → index-Bw2MEnUk.js} +1 -1
- package/src/assets/web-panel/assets/{index-DUUrv141.js → index-C1mJtE6q.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bm7lLR4c.js → index-C484EJiS.js} +1 -1
- package/src/assets/web-panel/assets/{index-COdGA-8n.js → index-C5KAQFPQ.js} +1 -1
- package/src/assets/web-panel/assets/index-C61cnl3K.js +1 -0
- package/src/assets/web-panel/assets/{index-CED2PL_y.js → index-C7Y8Aluc.js} +1 -1
- package/src/assets/web-panel/assets/{index-YXgLng0K.js → index-CCsM_Ybx.js} +1 -1
- package/src/assets/web-panel/assets/{index-0-agYlWL.js → index-CJCFe2Qf.js} +1 -1
- package/src/assets/web-panel/assets/{index-B5UkyA3c.js → index-CJVEOa4i.js} +1 -1
- package/src/assets/web-panel/assets/{index-B1CbOH1i.js → index-CJdQrZth.js} +1 -1
- package/src/assets/web-panel/assets/{index-s1opAL-M.js → index-CKC1t3Ic.js} +1 -1
- package/src/assets/web-panel/assets/{index-yObj1O4n.js → index-CQhAVU5t.js} +1 -1
- package/src/assets/web-panel/assets/{index-CgsqdnRV.js → index-CYdoQsa1.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dk7-v4hP.js → index-Cduu2Hhr.js} +1 -1
- package/src/assets/web-panel/assets/{index-B-JVTrpr.js → index-CkwiSLhU.js} +1 -1
- package/src/assets/web-panel/assets/{index-CeWoNHau.js → index-Cvyt-zhm.js} +1 -1
- package/src/assets/web-panel/assets/{index-CE2VtTlp.js → index-D2GjI2oe.js} +1 -1
- package/src/assets/web-panel/assets/index-D4XFHxBr.js +1 -0
- package/src/assets/web-panel/assets/{index-DmbfhJUP.js → index-DARsAyUp.js} +1 -1
- package/src/assets/web-panel/assets/{index-BESLFt4q.js → index-DVKfQ0Ux.js} +1 -1
- package/src/assets/web-panel/assets/{index-PT_5sBMA.js → index-DZT36ZYq.js} +1 -1
- package/src/assets/web-panel/assets/{index-gyFpvL7l.js → index-D_XBHopw.js} +1 -1
- package/src/assets/web-panel/assets/{index-BYUVuwKt.js → index-DdCB70SS.js} +1 -1
- package/src/assets/web-panel/assets/{index-BcUXAB2s.js → index-DzRjHxEv.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dk2qouAz.js → index-MMN9V6JF.js} +1 -1
- package/src/assets/web-panel/assets/{index-D9evtvg2.js → index-RfMr79MW.js} +1 -1
- package/src/assets/web-panel/assets/{index-BuLQobzW.js → index-_IRVsV9X.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cf3WCLmy.js → index-nXyk8GZ9.js} +1 -1
- package/src/assets/web-panel/assets/{index-CG3PRyAL.js → index-s_buFMEG.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-C9h9yKL3.js → initDefaultProps-Blmpk7HL.js} +1 -1
- package/src/assets/web-panel/assets/{motion-BvmLsPdu.js → motion-DPBJMv1n.js} +1 -1
- package/src/assets/web-panel/assets/{move-CoL4ekU1.js → move-ButdzCM7.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-C4pMy6xV.js → mtc-parser-cyRC_QCe.js} +1 -1
- package/src/assets/web-panel/assets/{omit-DPuJfNxx.js → omit-1epSV7hz.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-D0KEeaK2.js → pickAttrs-DuPY8xJs.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-BpkyINxt.js → placementArrow-6XZqarhe.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-DQI_wOq8.js → responsiveObserve-B40pXBWM.js} +1 -1
- package/src/assets/web-panel/assets/{slide-DYfdDiRg.js → slide-jbZ9Wu4n.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-B5dtvb0D.js → statusUtils-BKQQcVy4.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-CF310mSj.js → styleChecker-NiKfWjUT.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-D1Qp4BLp.js → useFlexGapSupport-bQUCvPeb.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-C7_iyvJK.js → useFs-CUGji7ph.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-DZUt_fIm.js → usePersonalDataHub-4veyN2N2.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-D3dsi0lZ.js → vnode-1-nLug-Z.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-WdbOlvdQ.js → zoom-dhCeRDMo.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/command-help-index.json +6 -6
- package/src/commands/automation.js +103 -1
- package/src/commands/cowork.js +174 -19
- package/src/commands/permissions.js +240 -16
- package/src/commands/plugin.js +1293 -56
- package/src/commands/session-location.js +276 -0
- package/src/commands/session.js +2 -0
- package/src/commands/team-merge-review.js +937 -0
- package/src/commands/team.js +2 -0
- package/src/data/changelog.json +27 -1
- package/src/gateways/ws/action-protocol.js +35 -10
- package/src/gateways/ws/remote-session-protocol.js +24 -1
- package/src/gateways/ws/ws-agent-handler.js +12 -0
- package/src/gateways/ws/ws-server.js +48 -12
- package/src/harness/jsonl-session-store.js +341 -24
- package/src/harness/mcp-client.js +8 -1
- package/src/harness/remote-session-audit.js +1 -0
- package/src/harness/remote-session-crypto.js +210 -2
- package/src/harness/remote-session-registry.js +159 -6
- package/src/harness/session-list-index.js +233 -14
- package/src/lib/agent-authority.js +6 -0
- package/src/lib/agent-schedule-store.js +139 -28
- package/src/lib/agent-team/team-merge-review-store.js +765 -0
- package/src/lib/agent-team/team-merge-review-transaction.js +1223 -0
- package/src/lib/agent-team/team-merge-review.js +1847 -0
- package/src/lib/automation-center-incidents.js +314 -0
- package/src/lib/automation-center-runtime.js +448 -0
- package/src/lib/automation-center.js +182 -38
- package/src/lib/automation-engine.js +41 -0
- package/src/lib/automation-execution-authority.js +241 -12
- package/src/lib/automation-execution-incident.js +737 -0
- package/src/lib/background-agent-keeper-client.js +248 -0
- package/src/lib/background-agent-keeper-protocol.js +147 -0
- package/src/lib/background-agent-supervisor.js +520 -40
- package/src/lib/background-interaction-resolver.js +12 -0
- package/src/lib/background-turn-bootstrap-protocol.js +126 -0
- package/src/lib/cowork-cron.js +85 -14
- package/src/lib/cowork-workflow.js +336 -16
- package/src/lib/dynamic-workflow-facade.js +648 -0
- package/src/lib/execution-location-contract.js +551 -0
- package/src/lib/execution-location-runtime.js +130 -0
- package/src/lib/ide-context.js +94 -6
- package/src/lib/mcp-stdio-package-materialization.js +166 -14
- package/src/lib/packer/pkg-config-generator.js +2 -0
- package/src/lib/permission-authority.js +77 -0
- package/src/lib/permission-side-effect-center.js +495 -0
- package/src/lib/plugin-runtime/install.js +514 -13
- package/src/lib/plugin-runtime/marketplace-artifact-readback.js +900 -0
- package/src/lib/plugin-runtime/marketplace-catalog.js +1181 -0
- package/src/lib/plugin-runtime/marketplace-impact.js +408 -0
- package/src/lib/plugin-runtime/marketplace-remote-artifacts.js +1567 -0
- package/src/lib/plugin-security.js +60 -3
- package/src/lib/process-execution-broker/index.js +1095 -57
- package/src/lib/process-execution-broker/linux-bwrap-descriptor-launch.js +375 -0
- package/src/lib/process-execution-broker/linux-generic-bwrap-runtime.js +90 -16
- package/src/lib/process-execution-broker/linux-generic-bwrap.js +159 -18
- package/src/lib/process-execution-broker/macos-mcp-launcher-contract.js +278 -0
- package/src/lib/process-execution-broker/macos-mcp-launcher-protocol.json +23 -0
- package/src/lib/process-execution-broker/macos-mcp-launcher.c +1497 -0
- package/src/lib/process-execution-broker/mcp-fd-entry-bootstrap.js +37 -0
- package/src/lib/process-execution-broker/platform-sandbox.js +2330 -279
- package/src/lib/process-execution-broker/windows-sandbox-helper.dll +0 -0
- package/src/lib/process-execution-broker/windows-sandbox-helper.exe +0 -0
- package/src/lib/process-execution-broker/windows-sandbox.cs +50 -4
- package/src/lib/public-ide-capability-manifest.js +3 -0
- package/src/lib/remote-approval-bridge.js +123 -17
- package/src/lib/remote-membership-authority.js +632 -0
- package/src/lib/remote-membership-coordinator.js +2409 -0
- package/src/lib/remote-membership-host-store.js +1750 -0
- package/src/lib/scheduler-kernel/agenda-adapter.js +17 -7
- package/src/lib/scheduler-kernel/automation-adapter.js +105 -11
- package/src/lib/scheduler-kernel/automation-event-adapter.js +87 -11
- package/src/lib/scheduler-kernel/contract.js +91 -0
- package/src/lib/scheduler-kernel/cowork-cron-adapter.js +12 -1
- package/src/lib/scheduler-kernel/loop-adapter.js +7 -1
- package/src/lib/scheduler-kernel/routine-adapter.js +7 -1
- package/src/lib/scheduler-kernel/runtime-control-capabilities.js +31 -0
- package/src/lib/scheduler-kernel/runtime.js +176 -3
- package/src/lib/scheduler-kernel/store.js +1253 -45
- package/src/lib/scoped-permission-store.js +369 -0
- package/src/lib/session-anti-rollback-anchor.js +262 -5
- package/src/lib/sub-agent-context.js +4 -0
- package/src/lib/workflow-definition-contract.js +149 -0
- package/src/repl/agent-repl.js +41 -7
- package/src/repl/chat-repl.js +2 -0
- package/src/repl/clipboard-image.js +735 -16
- package/src/repl/ide-status.js +1 -1
- package/src/repl/prompt-interactions.js +59 -6
- package/src/runtime/agent-core.js +93 -3
- package/src/runtime/headless-runner.js +30 -25
- package/src/runtime/headless-stream.js +32 -25
- package/src/runtime/mcp-config.js +81 -10
- package/src/workers/background-agent-keeper.js +498 -0
- package/src/workers/background-agent-worker.js +358 -13
- package/src/workers/background-turn-bootstrap.js +143 -0
- package/src/assets/web-panel/assets/MobileProjects-BWdOvQAj.js +0 -1
- package/src/assets/web-panel/assets/Projects-BV4oApsm.js +0 -1
- package/src/assets/web-panel/assets/devWarning-DPty0mGN.js +0 -1
- package/src/assets/web-panel/assets/index-Bt7g0Vq_.js +0 -1
- package/src/assets/web-panel/assets/index-ChVT0p9u.js +0 -1
package/src/repl/ide-status.js
CHANGED
|
@@ -45,7 +45,7 @@ export function renderIdeStatus(mcp, diag = null) {
|
|
|
45
45
|
lines.push(` tools: ${tools.map((t) => IDE_PREFIX + t).join(", ")}`);
|
|
46
46
|
lines.push(
|
|
47
47
|
" selection/diagnostics auto-share each turn · " +
|
|
48
|
-
"@selection / @diagnostics expand on demand",
|
|
48
|
+
"@selection / @diagnostics / @terminal / @context expand on demand",
|
|
49
49
|
);
|
|
50
50
|
return lines.join("\n");
|
|
51
51
|
}
|
|
@@ -18,6 +18,8 @@ import {
|
|
|
18
18
|
} from "./repl-keybindings.js";
|
|
19
19
|
import {
|
|
20
20
|
detectClipboardImageCapability,
|
|
21
|
+
MAX_CLIPBOARD_IMAGE_ATTACHMENTS,
|
|
22
|
+
MAX_CLIPBOARD_IMAGE_TOTAL_BYTES,
|
|
21
23
|
readClipboardImageChip,
|
|
22
24
|
} from "./clipboard-image.js";
|
|
23
25
|
import { layoutTerminalText } from "./terminal-layout.js";
|
|
@@ -36,6 +38,12 @@ function safeErrorText(value) {
|
|
|
36
38
|
.join("\n");
|
|
37
39
|
}
|
|
38
40
|
|
|
41
|
+
function boundedClipboardQueueLimit(value, fallback, maximum) {
|
|
42
|
+
const parsed = Number(value);
|
|
43
|
+
if (!Number.isSafeInteger(parsed) || parsed <= 0) return fallback;
|
|
44
|
+
return Math.min(parsed, maximum);
|
|
45
|
+
}
|
|
46
|
+
|
|
39
47
|
export const PROMPT_INTERACTION_SLASH_COMMANDS = Object.freeze([
|
|
40
48
|
Object.freeze({
|
|
41
49
|
name: "/recap",
|
|
@@ -136,6 +144,17 @@ export class PromptInteractionController {
|
|
|
136
144
|
this.persistSuggestionEnabled = options.persistSuggestionEnabled;
|
|
137
145
|
this.clipboardBinding = options.clipboardBinding || null;
|
|
138
146
|
this.clipboardImageChips = [];
|
|
147
|
+
this.clipboardImageBytes = 0;
|
|
148
|
+
this.maxClipboardImageAttachments = boundedClipboardQueueLimit(
|
|
149
|
+
options.maxClipboardImageAttachments,
|
|
150
|
+
MAX_CLIPBOARD_IMAGE_ATTACHMENTS,
|
|
151
|
+
MAX_CLIPBOARD_IMAGE_ATTACHMENTS,
|
|
152
|
+
);
|
|
153
|
+
this.maxClipboardImageTotalBytes = boundedClipboardQueueLimit(
|
|
154
|
+
options.maxClipboardImageTotalBytes,
|
|
155
|
+
MAX_CLIPBOARD_IMAGE_TOTAL_BYTES,
|
|
156
|
+
MAX_CLIPBOARD_IMAGE_TOTAL_BYTES,
|
|
157
|
+
);
|
|
139
158
|
|
|
140
159
|
const validated = validateReplKeybindings(options.keybindings || {});
|
|
141
160
|
this.keybindingDiagnostics = validated.errors.slice();
|
|
@@ -279,12 +298,38 @@ export class PromptInteractionController {
|
|
|
279
298
|
this._print(result.reason, { error: true });
|
|
280
299
|
return { handled: true, action: "paste-image", ...result };
|
|
281
300
|
}
|
|
282
|
-
|
|
301
|
+
if (
|
|
302
|
+
this.clipboardImageChips.length >= this.maxClipboardImageAttachments
|
|
303
|
+
) {
|
|
304
|
+
const result = {
|
|
305
|
+
ok: false,
|
|
306
|
+
supported: true,
|
|
307
|
+
mode: detectClipboardImageCapability(this.clipboardBinding).mode,
|
|
308
|
+
reason: `Clipboard attachment queue is limited to ${this.maxClipboardImageAttachments} images.`,
|
|
309
|
+
};
|
|
310
|
+
this._print(result.reason, { error: true });
|
|
311
|
+
return { handled: true, action: "paste-image", ...result };
|
|
312
|
+
}
|
|
313
|
+
let result = await readClipboardImageChip(this.clipboardBinding);
|
|
283
314
|
if (result.ok) {
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
)
|
|
315
|
+
if (
|
|
316
|
+
this.clipboardImageBytes + result.bytes >
|
|
317
|
+
this.maxClipboardImageTotalBytes
|
|
318
|
+
) {
|
|
319
|
+
result = {
|
|
320
|
+
ok: false,
|
|
321
|
+
supported: true,
|
|
322
|
+
mode: result.mode,
|
|
323
|
+
reason: `Clipboard attachment queue exceeds ${this.maxClipboardImageTotalBytes} bytes.`,
|
|
324
|
+
};
|
|
325
|
+
this._print(result.reason, { error: true });
|
|
326
|
+
} else {
|
|
327
|
+
this.clipboardImageChips.push(result.chip);
|
|
328
|
+
this.clipboardImageBytes += result.bytes;
|
|
329
|
+
this._print(
|
|
330
|
+
`Image attached from clipboard (${result.mediaType}, ${result.bytes} bytes).`,
|
|
331
|
+
);
|
|
332
|
+
}
|
|
288
333
|
} else {
|
|
289
334
|
this._print(result.reason, { error: true });
|
|
290
335
|
}
|
|
@@ -371,12 +416,20 @@ export class PromptInteractionController {
|
|
|
371
416
|
takeClipboardImageChips() {
|
|
372
417
|
const chips = this.clipboardImageChips.slice();
|
|
373
418
|
this.clipboardImageChips.length = 0;
|
|
419
|
+
this.clipboardImageBytes = 0;
|
|
374
420
|
return chips;
|
|
375
421
|
}
|
|
376
422
|
|
|
423
|
+
clearClipboardImageChips() {
|
|
424
|
+
const cleared = this.clipboardImageChips.length;
|
|
425
|
+
this.clipboardImageChips.length = 0;
|
|
426
|
+
this.clipboardImageBytes = 0;
|
|
427
|
+
return cleared;
|
|
428
|
+
}
|
|
429
|
+
|
|
377
430
|
dispose() {
|
|
378
431
|
this.suggestions.dispose();
|
|
379
|
-
this.
|
|
432
|
+
this.clearClipboardImageChips();
|
|
380
433
|
}
|
|
381
434
|
}
|
|
382
435
|
|
|
@@ -2401,20 +2401,88 @@ export async function executeTool(name, args, context = {}) {
|
|
|
2401
2401
|
// shell-policy denylist also still applies.
|
|
2402
2402
|
// No matching rule + no host policy → every existing layer runs unchanged
|
|
2403
2403
|
// (default behaviour is byte-for-byte).
|
|
2404
|
-
|
|
2404
|
+
let permissionAuthority = null;
|
|
2405
|
+
let effectivePermissionRules = context.permissionRules || null;
|
|
2406
|
+
if (typeof context.permissionRulesProvider === "function") {
|
|
2407
|
+
try {
|
|
2408
|
+
permissionAuthority = await context.permissionRulesProvider({
|
|
2409
|
+
cwd,
|
|
2410
|
+
tool: name,
|
|
2411
|
+
args,
|
|
2412
|
+
});
|
|
2413
|
+
effectivePermissionRules =
|
|
2414
|
+
permissionAuthority?.rules || permissionAuthority || null;
|
|
2415
|
+
if (
|
|
2416
|
+
effectivePermissionRules &&
|
|
2417
|
+
(!Array.isArray(effectivePermissionRules.allow) ||
|
|
2418
|
+
!Array.isArray(effectivePermissionRules.ask) ||
|
|
2419
|
+
!Array.isArray(effectivePermissionRules.deny))
|
|
2420
|
+
) {
|
|
2421
|
+
throw new TypeError(
|
|
2422
|
+
"permission authority provider returned an invalid ruleset",
|
|
2423
|
+
);
|
|
2424
|
+
}
|
|
2425
|
+
} catch (error) {
|
|
2426
|
+
return {
|
|
2427
|
+
error:
|
|
2428
|
+
`[Permission Authority] Tool "${name}" was blocked because the current permission authority could not be resolved. ` +
|
|
2429
|
+
"No tool side effect was started.",
|
|
2430
|
+
policy: {
|
|
2431
|
+
decision: "blocked",
|
|
2432
|
+
via: "permission-authority-load",
|
|
2433
|
+
code: error?.code || "CC_PERMISSION_AUTHORITY_UNAVAILABLE",
|
|
2434
|
+
},
|
|
2435
|
+
};
|
|
2436
|
+
}
|
|
2437
|
+
}
|
|
2438
|
+
const evaluatedSettingsVerdict = effectivePermissionRules
|
|
2405
2439
|
? evaluatePermissionRules({
|
|
2406
2440
|
tool: name,
|
|
2407
2441
|
args,
|
|
2408
2442
|
cwd,
|
|
2409
|
-
rules:
|
|
2443
|
+
rules: effectivePermissionRules,
|
|
2410
2444
|
})
|
|
2411
2445
|
: { decision: null, rule: null };
|
|
2446
|
+
const permissionRuleSource = evaluatedSettingsVerdict.rule
|
|
2447
|
+
? permissionAuthority?.sources?.[
|
|
2448
|
+
`${evaluatedSettingsVerdict.decision}:${evaluatedSettingsVerdict.rule}`
|
|
2449
|
+
] || null
|
|
2450
|
+
: null;
|
|
2451
|
+
const matchedScopedRule = permissionRuleSource?.startsWith("scoped:")
|
|
2452
|
+
? permissionAuthority?.scoped?.rules?.find(
|
|
2453
|
+
(record) =>
|
|
2454
|
+
record.status === "active" &&
|
|
2455
|
+
`scoped:${record.id}` === permissionRuleSource,
|
|
2456
|
+
)
|
|
2457
|
+
: null;
|
|
2458
|
+
const settingsVerdict = {
|
|
2459
|
+
...evaluatedSettingsVerdict,
|
|
2460
|
+
source: permissionRuleSource,
|
|
2461
|
+
priority:
|
|
2462
|
+
evaluatedSettingsVerdict.decision === "deny"
|
|
2463
|
+
? 1
|
|
2464
|
+
: evaluatedSettingsVerdict.decision === "ask"
|
|
2465
|
+
? 3
|
|
2466
|
+
: evaluatedSettingsVerdict.decision === "allow"
|
|
2467
|
+
? 4
|
|
2468
|
+
: null,
|
|
2469
|
+
scopedRule: matchedScopedRule || null,
|
|
2470
|
+
};
|
|
2412
2471
|
|
|
2413
2472
|
// 1. settings deny
|
|
2414
2473
|
if (settingsVerdict.decision === "deny") {
|
|
2415
2474
|
return {
|
|
2416
2475
|
error: `[Permission] Tool "${name}" denied by settings rule: ${settingsVerdict.rule}. This is a configured policy — retrying won't help; tell the user if the task genuinely needs it.`,
|
|
2417
|
-
policy: {
|
|
2476
|
+
policy: {
|
|
2477
|
+
decision: "deny",
|
|
2478
|
+
rule: settingsVerdict.rule,
|
|
2479
|
+
via: "settings",
|
|
2480
|
+
source: settingsVerdict.source,
|
|
2481
|
+
priority: settingsVerdict.priority,
|
|
2482
|
+
scopedRuleId: settingsVerdict.scopedRule?.id || null,
|
|
2483
|
+
revision: settingsVerdict.scopedRule?.revision || null,
|
|
2484
|
+
expiresAt: settingsVerdict.scopedRule?.expiresAt || null,
|
|
2485
|
+
},
|
|
2418
2486
|
};
|
|
2419
2487
|
}
|
|
2420
2488
|
|
|
@@ -2523,6 +2591,11 @@ export async function executeTool(name, args, context = {}) {
|
|
|
2523
2591
|
decision: "ask",
|
|
2524
2592
|
rule: settingsVerdict.rule,
|
|
2525
2593
|
via: "settings",
|
|
2594
|
+
source: settingsVerdict.source,
|
|
2595
|
+
priority: settingsVerdict.priority,
|
|
2596
|
+
scopedRuleId: settingsVerdict.scopedRule?.id || null,
|
|
2597
|
+
revision: settingsVerdict.scopedRule?.revision || null,
|
|
2598
|
+
expiresAt: settingsVerdict.scopedRule?.expiresAt || null,
|
|
2526
2599
|
},
|
|
2527
2600
|
};
|
|
2528
2601
|
}
|
|
@@ -2865,6 +2938,7 @@ export async function executeTool(name, args, context = {}) {
|
|
|
2865
2938
|
backgroundUsageFailureState: context.backgroundUsageFailureState || null,
|
|
2866
2939
|
planManager,
|
|
2867
2940
|
permissionRules: context.permissionRules || null,
|
|
2941
|
+
permissionRulesProvider: context.permissionRulesProvider || null,
|
|
2868
2942
|
effectiveAllowedToolNames: context.effectiveAllowedToolNames ?? null,
|
|
2869
2943
|
hostManagedToolPolicy: context.hostManagedToolPolicy || null,
|
|
2870
2944
|
externalToolDescriptors: context.externalToolDescriptors || null,
|
|
@@ -6873,6 +6947,16 @@ async function executeToolInner(
|
|
|
6873
6947
|
});
|
|
6874
6948
|
}
|
|
6875
6949
|
try {
|
|
6950
|
+
if (localToolExecutor.op === "list-templates") {
|
|
6951
|
+
const resourceTemplates =
|
|
6952
|
+
typeof mcpClient.listResourceTemplates === "function"
|
|
6953
|
+
? mcpClient.listResourceTemplates(args?.server || undefined)
|
|
6954
|
+
: [];
|
|
6955
|
+
return attachDescriptor({
|
|
6956
|
+
count: resourceTemplates.length,
|
|
6957
|
+
resourceTemplates,
|
|
6958
|
+
});
|
|
6959
|
+
}
|
|
6876
6960
|
if (localToolExecutor.op === "list") {
|
|
6877
6961
|
const resources =
|
|
6878
6962
|
typeof mcpClient.listResources === "function"
|
|
@@ -8709,6 +8793,9 @@ async function _executeSpawnSubAgent(args, ctx) {
|
|
|
8709
8793
|
// Parent execution authority is inherited as a tighten-only bundle and is
|
|
8710
8794
|
// re-enforced by the child's executeTool path on every provider tool call.
|
|
8711
8795
|
...(ctx.permissionRules ? { permissionRules: ctx.permissionRules } : {}),
|
|
8796
|
+
...(ctx.permissionRulesProvider
|
|
8797
|
+
? { permissionRulesProvider: ctx.permissionRulesProvider }
|
|
8798
|
+
: {}),
|
|
8712
8799
|
...(childHostManagedToolPolicy
|
|
8713
8800
|
? { hostManagedToolPolicy: childHostManagedToolPolicy }
|
|
8714
8801
|
: {}),
|
|
@@ -11341,6 +11428,9 @@ export async function* agentLoop(messages, options) {
|
|
|
11341
11428
|
: options.additionalDirectories || null,
|
|
11342
11429
|
sandbox: options.sandbox || null,
|
|
11343
11430
|
permissionRules: hermeticExecution ? null : options.permissionRules || null,
|
|
11431
|
+
permissionRulesProvider: hermeticExecution
|
|
11432
|
+
? null
|
|
11433
|
+
: options.permissionRulesProvider || null,
|
|
11344
11434
|
permissionConfirm: hermeticExecution
|
|
11345
11435
|
? null
|
|
11346
11436
|
: options.permissionConfirm || null,
|
|
@@ -65,6 +65,7 @@ import {
|
|
|
65
65
|
reconcileSideEffects,
|
|
66
66
|
classifyToolSideEffect,
|
|
67
67
|
} from "../lib/side-effect-ledger.js";
|
|
68
|
+
import { collectToolResourceIdentifiers } from "../lib/permission-side-effect-center.js";
|
|
68
69
|
import { DiffReviewFollowUpTracker } from "../lib/diff-review-follow-up.js";
|
|
69
70
|
import { SIDE_EFFECT_LEDGER_EVENT } from "../lib/side-effect-ledger-store.js";
|
|
70
71
|
import {
|
|
@@ -105,6 +106,7 @@ import {
|
|
|
105
106
|
exitCodeForEndReason,
|
|
106
107
|
} from "../lib/exit-codes.cjs";
|
|
107
108
|
import { isolationLevel } from "../lib/agent-sandbox.js";
|
|
109
|
+
import { captureAmbientExecutionLocation } from "../lib/execution-location-runtime.js";
|
|
108
110
|
import { createBackgroundPhaseReporter } from "../lib/background-phase-reporter.js";
|
|
109
111
|
import { createBackgroundInteractionClient } from "../lib/background-interaction-resolver.js";
|
|
110
112
|
import { withQuietStdout } from "./quiet-stdout.js";
|
|
@@ -738,34 +740,26 @@ async function runAgentHeadlessInWorkspace(
|
|
|
738
740
|
let permissionRules = hermeticExecution
|
|
739
741
|
? null
|
|
740
742
|
: options.permissionRules || null;
|
|
743
|
+
let permissionRulesProvider = hermeticExecution
|
|
744
|
+
? null
|
|
745
|
+
: options.permissionRulesProvider || null;
|
|
741
746
|
let managedSettings = null;
|
|
742
747
|
let settingsFiles = [];
|
|
743
748
|
if (!hermeticExecution) {
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
loaded.rules.deny.length;
|
|
759
|
-
permissionRules = total > 0 ? loaded.rules : null;
|
|
760
|
-
} else if (managedSettings) {
|
|
761
|
-
permissionRules = applyManagedPermissionPolicy(
|
|
762
|
-
permissionRules,
|
|
763
|
-
managedSettings,
|
|
764
|
-
);
|
|
765
|
-
}
|
|
766
|
-
} catch (error) {
|
|
767
|
-
if (error?.code === "CC_MANAGED_SETTINGS_INVALID") throw error;
|
|
768
|
-
// Preserve caller-provided rules; absent settings keep legacy behavior.
|
|
749
|
+
const { createPermissionRulesProvider, loadPermissionAuthority } =
|
|
750
|
+
await import("../lib/permission-authority.js");
|
|
751
|
+
const authorityOptions = {
|
|
752
|
+
cwd,
|
|
753
|
+
settingsFile: options.settingsFile,
|
|
754
|
+
managedSettingsFile: options.managedSettingsFile,
|
|
755
|
+
baseRules: options.permissionRules || null,
|
|
756
|
+
};
|
|
757
|
+
const loaded = loadPermissionAuthority(authorityOptions);
|
|
758
|
+
managedSettings = loaded.managed;
|
|
759
|
+
settingsFiles = Array.isArray(loaded.files) ? loaded.files : [];
|
|
760
|
+
permissionRules = loaded.hasRules ? loaded.rules : null;
|
|
761
|
+
if (!permissionRulesProvider) {
|
|
762
|
+
permissionRulesProvider = createPermissionRulesProvider(authorityOptions);
|
|
769
763
|
}
|
|
770
764
|
}
|
|
771
765
|
|
|
@@ -1719,6 +1713,10 @@ async function runAgentHeadlessInWorkspace(
|
|
|
1719
1713
|
provider,
|
|
1720
1714
|
model,
|
|
1721
1715
|
observabilityScope: options.observabilityScope,
|
|
1716
|
+
executionLocation: captureAmbientExecutionLocation({
|
|
1717
|
+
provider,
|
|
1718
|
+
model,
|
|
1719
|
+
}),
|
|
1722
1720
|
});
|
|
1723
1721
|
}
|
|
1724
1722
|
// Persist the expanded content so a resumed session faithfully replays
|
|
@@ -2163,6 +2161,7 @@ async function runAgentHeadlessInWorkspace(
|
|
|
2163
2161
|
hookDb: hermeticExecution ? null : db,
|
|
2164
2162
|
approvalGate: hermeticExecution ? null : approvalGate,
|
|
2165
2163
|
permissionRules: hermeticExecution ? null : permissionRules,
|
|
2164
|
+
permissionRulesProvider: hermeticExecution ? null : permissionRulesProvider,
|
|
2166
2165
|
settingsHooks: hermeticExecution ? null : settingsHooks,
|
|
2167
2166
|
// Seed the subagent-contract CEILING with this run's permission mode so a
|
|
2168
2167
|
// spawned sub-agent inherits/tightens from it (tighten-only): a
|
|
@@ -2758,6 +2757,12 @@ async function runAgentHeadlessInWorkspace(
|
|
|
2758
2757
|
// and countDuplicateCommittedEffects can measure `0` repeats.
|
|
2759
2758
|
meta: {
|
|
2760
2759
|
tool: event.tool,
|
|
2760
|
+
toolUseId: telemetryToolId,
|
|
2761
|
+
turnId: event.turn_id || null,
|
|
2762
|
+
resources: collectToolResourceIdentifiers(
|
|
2763
|
+
event.tool,
|
|
2764
|
+
event.args,
|
|
2765
|
+
),
|
|
2761
2766
|
idempotencyKey: operationIdempotencyKey({
|
|
2762
2767
|
tool: event.tool,
|
|
2763
2768
|
args: event.args,
|
|
@@ -60,6 +60,7 @@ import {
|
|
|
60
60
|
expandIdeMentions,
|
|
61
61
|
} from "../lib/ide-context.js";
|
|
62
62
|
import { detectVersionSkew, versionSkewMessage } from "../lib/version-skew.js";
|
|
63
|
+
import { captureAmbientExecutionLocation } from "../lib/execution-location-runtime.js";
|
|
63
64
|
import {
|
|
64
65
|
resolveAgentMcp,
|
|
65
66
|
resolvePermissionPromptTool,
|
|
@@ -114,6 +115,7 @@ import {
|
|
|
114
115
|
reconcileSideEffects,
|
|
115
116
|
classifyToolSideEffect,
|
|
116
117
|
} from "../lib/side-effect-ledger.js";
|
|
118
|
+
import { collectToolResourceIdentifiers } from "../lib/permission-side-effect-center.js";
|
|
117
119
|
import { DiffReviewFollowUpTracker } from "../lib/diff-review-follow-up.js";
|
|
118
120
|
import {
|
|
119
121
|
loadSideEffectLedger,
|
|
@@ -909,6 +911,12 @@ async function runTurn(
|
|
|
909
911
|
// and countDuplicateCommittedEffects can measure `0` repeats.
|
|
910
912
|
meta: {
|
|
911
913
|
tool: event.tool,
|
|
914
|
+
toolUseId: toolUseId || null,
|
|
915
|
+
turnId: event.turn_id || null,
|
|
916
|
+
resources: collectToolResourceIdentifiers(
|
|
917
|
+
event.tool,
|
|
918
|
+
event.args,
|
|
919
|
+
),
|
|
912
920
|
idempotencyKey: operationIdempotencyKey({
|
|
913
921
|
tool: event.tool,
|
|
914
922
|
args: event.args,
|
|
@@ -1608,33 +1616,27 @@ async function runAgentHeadlessStreamInWorkspace(
|
|
|
1608
1616
|
// .claude/settings.json permission rules (deny > ask > allow); see
|
|
1609
1617
|
// runAgentHeadless for the full semantics. null = no file → unchanged.
|
|
1610
1618
|
let permissionRules = options.permissionRules || null;
|
|
1619
|
+
let permissionRulesProvider = options.permissionRulesProvider || null;
|
|
1611
1620
|
let managedSettings = null;
|
|
1612
1621
|
let settingsFiles = [];
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
permissionRules,
|
|
1632
|
-
managedSettings,
|
|
1633
|
-
);
|
|
1634
|
-
}
|
|
1635
|
-
} catch (error) {
|
|
1636
|
-
if (error?.code === "CC_MANAGED_SETTINGS_INVALID") throw error;
|
|
1637
|
-
// Preserve caller-provided rules; absent settings keep legacy behavior.
|
|
1622
|
+
const { createPermissionRulesProvider, loadPermissionAuthority } =
|
|
1623
|
+
await import("../lib/permission-authority.js");
|
|
1624
|
+
const authorityOptions = {
|
|
1625
|
+
cwd,
|
|
1626
|
+
settingsFile: options.settingsFile,
|
|
1627
|
+
managedSettingsFile: options.managedSettingsFile,
|
|
1628
|
+
baseRules: options.permissionRules || null,
|
|
1629
|
+
};
|
|
1630
|
+
const loadedPermissionAuthority = loadPermissionAuthority(authorityOptions);
|
|
1631
|
+
managedSettings = loadedPermissionAuthority.managed;
|
|
1632
|
+
settingsFiles = Array.isArray(loadedPermissionAuthority.files)
|
|
1633
|
+
? loadedPermissionAuthority.files
|
|
1634
|
+
: [];
|
|
1635
|
+
permissionRules = loadedPermissionAuthority.hasRules
|
|
1636
|
+
? loadedPermissionAuthority.rules
|
|
1637
|
+
: null;
|
|
1638
|
+
if (!permissionRulesProvider) {
|
|
1639
|
+
permissionRulesProvider = createPermissionRulesProvider(authorityOptions);
|
|
1638
1640
|
}
|
|
1639
1641
|
|
|
1640
1642
|
// .claude/settings.json `hooks` block (decision-capable PreToolUse/PostToolUse).
|
|
@@ -2368,6 +2370,10 @@ async function runAgentHeadlessStreamInWorkspace(
|
|
|
2368
2370
|
provider,
|
|
2369
2371
|
model,
|
|
2370
2372
|
observabilityScope: options.observabilityScope,
|
|
2373
|
+
executionLocation: captureAmbientExecutionLocation({
|
|
2374
|
+
provider,
|
|
2375
|
+
model,
|
|
2376
|
+
}),
|
|
2371
2377
|
}),
|
|
2372
2378
|
"startSession",
|
|
2373
2379
|
);
|
|
@@ -2791,6 +2797,7 @@ async function runAgentHeadlessStreamInWorkspace(
|
|
|
2791
2797
|
hookDb: db,
|
|
2792
2798
|
approvalGate,
|
|
2793
2799
|
permissionRules,
|
|
2800
|
+
permissionRulesProvider,
|
|
2794
2801
|
settingsHooks,
|
|
2795
2802
|
toolAdmission: options.toolAdmission || null,
|
|
2796
2803
|
classifyAllShell,
|
|
@@ -332,7 +332,8 @@ export function mcpAuthHint(url, errMessage) {
|
|
|
332
332
|
* @param {object} servers `{ name: { command|url, args, env, transport, headers } }`
|
|
333
333
|
* @param {object} [deps] { writeErr, createClient }
|
|
334
334
|
* @returns {Promise<{mcpClient, extraToolDefinitions, externalToolExecutors,
|
|
335
|
-
* externalToolDescriptors, connected
|
|
335
|
+
* externalToolDescriptors, connected, resources,
|
|
336
|
+
* resourceTemplates, prompts}>}
|
|
336
337
|
*/
|
|
337
338
|
export async function setupMcpFromConfig(servers, deps = {}) {
|
|
338
339
|
const writeErr = deps.writeErr || (() => {});
|
|
@@ -354,6 +355,7 @@ export async function setupMcpFromConfig(servers, deps = {}) {
|
|
|
354
355
|
externalToolDescriptors: {},
|
|
355
356
|
connected: [],
|
|
356
357
|
resources: [],
|
|
358
|
+
resourceTemplates: [],
|
|
357
359
|
prompts: [],
|
|
358
360
|
};
|
|
359
361
|
if (!(result._mcpServerNameReservations instanceof Set)) {
|
|
@@ -362,9 +364,12 @@ export async function setupMcpFromConfig(servers, deps = {}) {
|
|
|
362
364
|
configurable: true,
|
|
363
365
|
});
|
|
364
366
|
}
|
|
365
|
-
// Back-fill the resource/prompt accumulators when an older
|
|
366
|
-
// (created before
|
|
367
|
+
// Back-fill the resource/template/prompt accumulators when an older
|
|
368
|
+
// `deps.into` object (created before these fields existed) is passed in.
|
|
367
369
|
if (!Array.isArray(result.resources)) result.resources = [];
|
|
370
|
+
if (!Array.isArray(result.resourceTemplates)) {
|
|
371
|
+
result.resourceTemplates = [];
|
|
372
|
+
}
|
|
368
373
|
if (!Array.isArray(result.prompts)) result.prompts = [];
|
|
369
374
|
// Per-server usage instructions from the MCP initialize response (surfaced
|
|
370
375
|
// by tool search; absent for servers that send none).
|
|
@@ -477,6 +482,9 @@ export async function setupMcpFromConfig(servers, deps = {}) {
|
|
|
477
482
|
toolMetadataError = error;
|
|
478
483
|
}
|
|
479
484
|
const resources = Array.isArray(res?.resources) ? res.resources : [];
|
|
485
|
+
const resourceTemplates = Array.isArray(res?.resourceTemplates)
|
|
486
|
+
? res.resourceTemplates
|
|
487
|
+
: [];
|
|
480
488
|
const prompts = Array.isArray(res?.prompts) ? res.prompts : [];
|
|
481
489
|
// A server can connect (initialize OK) yet have its tools/list fail — the
|
|
482
490
|
// mcp-client surfaces that as `res.toolsError` (Claude-Code 2.1.181
|
|
@@ -507,6 +515,10 @@ export async function setupMcpFromConfig(servers, deps = {}) {
|
|
|
507
515
|
if (!r || !r.uri) continue;
|
|
508
516
|
result.resources.push({ ...r, server: name });
|
|
509
517
|
}
|
|
518
|
+
for (const template of resourceTemplates) {
|
|
519
|
+
if (!template || !template.uriTemplate) continue;
|
|
520
|
+
result.resourceTemplates.push({ ...template, server: name });
|
|
521
|
+
}
|
|
510
522
|
for (const p of prompts) {
|
|
511
523
|
if (!p || !p.name) continue;
|
|
512
524
|
result.prompts.push({ ...p, server: name });
|
|
@@ -566,13 +578,16 @@ export async function setupMcpFromConfig(servers, deps = {}) {
|
|
|
566
578
|
}
|
|
567
579
|
}
|
|
568
580
|
|
|
569
|
-
// Expose MCP resources to the LLM as
|
|
570
|
-
//
|
|
571
|
-
//
|
|
572
|
-
// accumulating `deps.into` batches.
|
|
573
|
-
if (result.resources.length > 0) {
|
|
581
|
+
// Expose MCP resources to the LLM as generic read-only tools. A
|
|
582
|
+
// templates-only server still needs the read tool so the model can
|
|
583
|
+
// instantiate a URI template and explicitly read that URI. Registration is
|
|
584
|
+
// re-entrant safe for accumulating `deps.into` batches.
|
|
585
|
+
if (result.resources.length > 0 || result.resourceTemplates.length > 0) {
|
|
574
586
|
registerMcpResourceTools(result);
|
|
575
587
|
}
|
|
588
|
+
if (result.resourceTemplates.length > 0) {
|
|
589
|
+
registerMcpResourceTemplateTool(result);
|
|
590
|
+
}
|
|
576
591
|
|
|
577
592
|
return result;
|
|
578
593
|
}
|
|
@@ -615,14 +630,14 @@ export function registerMcpResourceTools(result) {
|
|
|
615
630
|
name: "read_mcp_resource",
|
|
616
631
|
description:
|
|
617
632
|
"Read the contents of an MCP resource by its URI. Use " +
|
|
618
|
-
"list_mcp_resources first to discover
|
|
633
|
+
"list_mcp_resources or list_mcp_resource_templates first to discover a URI.",
|
|
619
634
|
parameters: {
|
|
620
635
|
type: "object",
|
|
621
636
|
properties: {
|
|
622
637
|
server: {
|
|
623
638
|
type: "string",
|
|
624
639
|
description:
|
|
625
|
-
"MCP server name that owns the resource
|
|
640
|
+
"MCP server name that owns the resource or resource template.",
|
|
626
641
|
},
|
|
627
642
|
uri: {
|
|
628
643
|
type: "string",
|
|
@@ -689,6 +704,62 @@ export function registerMcpResourceTools(result) {
|
|
|
689
704
|
};
|
|
690
705
|
}
|
|
691
706
|
|
|
707
|
+
/** Register the read-only resource-template discovery tool once. */
|
|
708
|
+
function registerMcpResourceTemplateTool(result) {
|
|
709
|
+
const {
|
|
710
|
+
extraToolDefinitions,
|
|
711
|
+
externalToolExecutors,
|
|
712
|
+
externalToolDescriptors,
|
|
713
|
+
} = result;
|
|
714
|
+
if (externalToolExecutors.list_mcp_resource_templates) return;
|
|
715
|
+
|
|
716
|
+
extraToolDefinitions.push({
|
|
717
|
+
type: "function",
|
|
718
|
+
function: {
|
|
719
|
+
name: "list_mcp_resource_templates",
|
|
720
|
+
description:
|
|
721
|
+
"List URI templates exposed by connected MCP servers. Fill a template " +
|
|
722
|
+
"with concrete arguments, then pass the resulting URI and returned " +
|
|
723
|
+
"server name to read_mcp_resource.",
|
|
724
|
+
parameters: {
|
|
725
|
+
type: "object",
|
|
726
|
+
properties: {
|
|
727
|
+
server: {
|
|
728
|
+
type: "string",
|
|
729
|
+
description: "Optional MCP server name to filter by.",
|
|
730
|
+
},
|
|
731
|
+
},
|
|
732
|
+
},
|
|
733
|
+
},
|
|
734
|
+
});
|
|
735
|
+
externalToolExecutors.list_mcp_resource_templates = {
|
|
736
|
+
kind: "mcp-resource",
|
|
737
|
+
op: "list-templates",
|
|
738
|
+
};
|
|
739
|
+
externalToolDescriptors.list_mcp_resource_templates = {
|
|
740
|
+
name: "list_mcp_resource_templates",
|
|
741
|
+
kind: "mcp-resource",
|
|
742
|
+
category: "mcp",
|
|
743
|
+
source: "mcp",
|
|
744
|
+
isReadOnly: true,
|
|
745
|
+
riskLevel: "low",
|
|
746
|
+
effectContract: {
|
|
747
|
+
version: 1,
|
|
748
|
+
declaredEffect: "read",
|
|
749
|
+
authorizedEffect: "read",
|
|
750
|
+
riskLevel: "low",
|
|
751
|
+
sourceTrusted: true,
|
|
752
|
+
provenance: "host:mcp-resource-wrapper",
|
|
753
|
+
annotations: {
|
|
754
|
+
readOnlyHint: true,
|
|
755
|
+
destructiveHint: false,
|
|
756
|
+
idempotentHint: true,
|
|
757
|
+
openWorldHint: false,
|
|
758
|
+
},
|
|
759
|
+
},
|
|
760
|
+
};
|
|
761
|
+
}
|
|
762
|
+
|
|
692
763
|
/**
|
|
693
764
|
* Read + parse a `--mcp-config` file and connect its servers.
|
|
694
765
|
* Throws on an unreadable/empty config (fail fast — the user asked for MCP).
|