chainlesschain 0.162.174 → 0.162.176
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 +10 -10
- package/src/assets/web-panel/assets/{AIOps-Dcl-X1Hw.js → AIOps-BDLu5Elz.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-ClMh9HzT.js → ActionButton-DH5us-CK.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-DPj0rSQ5.js → Analytics-BZ0u8IFG.js} +3 -3
- package/src/assets/web-panel/assets/AppLayout-Duu8xR14.js +9 -0
- package/src/assets/web-panel/assets/{Artifacts-L8781rE8.js → Artifacts-Br2YBbh_.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-CffB6WIP.js → Audit-C3C6a482.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-BkLhayyY.js → BackgroundAgents-CzHvebcj.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-BQnwFI78.js → Backup-DZNHYDFd.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-xuUGHQch.js → BaseInput-VRiC4fIx.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-feQXwWrg.js → Chat-Cm08WWAD.js} +5 -5
- package/src/assets/web-panel/assets/ChatBubbleRenderer-CGHYrugQ.js +1 -0
- package/src/assets/web-panel/assets/{Checkbox-DVaIiUGW.js → Checkbox-DtByk7d7.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-D2kEnzeU.js → Codegen-CphXXOfD.js} +1 -1
- package/src/assets/web-panel/assets/{Col-azDoyusS.js → Col-Hz86TnLR.js} +1 -1
- package/src/assets/web-panel/assets/{Community-OZdnPWM5.js → Community-HP03ltpD.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-VDMvBN-C.js → Compact-B_N1mqQz.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-CPJ_zgQ1.js → Compliance-CVztRpi8.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-iRBwcsOA.js → Cowork-wUVOyZih.js} +4 -4
- package/src/assets/web-panel/assets/{Cron-DrxrspUz.js → Cron-DW5TLJKw.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-D-rkAZXF.js → Crosschain-CrAFGhWH.js} +1 -1
- package/src/assets/web-panel/assets/{DID-5Pp1Xnmr.js → DID-pA-oD8ke.js} +2 -2
- package/src/assets/web-panel/assets/Dashboard-CXrd5gAw.js +3 -0
- package/src/assets/web-panel/assets/{Dropdown-BWj_E0Ie.js → Dropdown-EweJcsek.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-BT-wgSEh.js → EmailListRenderer-C9xVLPG4.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-1PzH23pa.js → FamilyGuardDashboard-CDcEEqlu.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-BxMIXGC6.js → Federation-DtZda9A_.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-CyJobBln.js → FormItemContext-CiYdcVz3.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-YkjFuQTN.js → GenericCardRenderer-DA13uwA0.js} +1 -1
- package/src/assets/web-panel/assets/{Git-C2a98Wp_.js → Git-DzRhZD1O.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-DKL3Fl84.js → Governance-D5RMgOSb.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-BJ2cQC_3.js → Inference-BgrPfSNk.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-DBAsOngt.js → KnowledgeGraph-DzjnD571.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-COt8g9LO.js → Logs-BhWzVDtN.js} +2 -2
- package/src/assets/web-panel/assets/{MarkdownRenderer-3Lfht1Fd.js → MarkdownRenderer-BDape9cx.js} +1 -1
- package/src/assets/web-panel/assets/{Marketplace-C9Zk9Pb2.js → Marketplace-DJtL5GV7.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-DDWDFWPO.js → McpTools-CZcQygI7.js} +5 -5
- package/src/assets/web-panel/assets/{Memory-BRmVye_o.js → Memory-DUWSDUUu.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-CppBbWpD.js → MobileBridge-BTwq2WKY.js} +1 -1
- package/src/assets/web-panel/assets/MobileProjects-NZvvfDME.js +1 -0
- package/src/assets/web-panel/assets/{Mtc-CcWpeGa6.js → Mtc-BiGugEQm.js} +6 -6
- package/src/assets/web-panel/assets/{MtcAudit-BcllEq0K.js → MtcAudit-DY7a6gUe.js} +4 -4
- package/src/assets/web-panel/assets/{Multisig-BFD1CarL.js → Multisig-BQbDu_w7.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-QNXXYvjz.js → NLProgramming-CM2wXTLv.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-07YwgQVy.js → Notes-DI6gGs1v.js} +4 -4
- package/src/assets/web-panel/assets/{NotificationSettings-bOccEInE.js → NotificationSettings-BsZOLWAB.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-DlRi29WL.js → OrderTableRenderer-C48mu09U.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-CBaezzEr.js → Organization-Cds0_tXr.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-Bl5NohFO.js → Overflow-WunYMD87.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-CLMal9Aw.js → P2P-Bo6j4DDv.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-CGO0NITk.js → PdhVaultBrowser-Bh2XPD5f.js} +3 -3
- package/src/assets/web-panel/assets/{Permissions-CPSw48E2.js → Permissions-EMvMMC8N.js} +3 -3
- package/src/assets/web-panel/assets/{PersonalDataHub-CDM5n134.js → PersonalDataHub-AX3ypUDV.js} +2 -2
- package/src/assets/web-panel/assets/{Pipeline-BdsqG7WV.js → Pipeline-BOx8HOgL.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-B6L4E-M7.js → Privacy-tBeTVQVM.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-DXPyZKRs.js → ProjectInit-CVYg1W4M.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-BrCC3xYT.js → ProjectSettings-Dvt5I7y1.js} +2 -2
- package/src/assets/web-panel/assets/{Projects-BYmuHC2q.js → Projects-Cc7FC9-e.js} +1 -1
- package/src/assets/web-panel/assets/{Providers-CbCe2eUl.js → Providers-Ct8xqY-E.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-DkukgCrR.js → QrScannerModal-Cni8Ooja.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-D-htOrV8.js → QuickAsk-BJVLKdxr.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-Bm7SIfzu.js → Recommend-DPG8Rbbm.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-C9rP-iMc.js → RemoteSession-DsdR7dCt.js} +2 -2
- package/src/assets/web-panel/assets/{Reputation-kGlUgbsl.js → Reputation-Csg1YM-b.js} +1 -1
- package/src/assets/web-panel/assets/{Row-PBupbbUA.js → Row-D9DoFoEf.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-njlwKUGK.js → RssFeed-BsvKrXMS.js} +2 -2
- package/src/assets/web-panel/assets/{Search-DLdEmgBw.js → Search-DFUStfgQ.js} +1 -1
- package/src/assets/web-panel/assets/{Security-SXGPSHdu.js → Security-ILg1zxdK.js} +4 -4
- package/src/assets/web-panel/assets/{Services-CuFGnNsb.js → Services-Dd41PCaY.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-CtUC0mDa.js → Skeleton-Bzo1cN80.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-P1qgOVFn.js → Skills-BDHh17P0.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-CsppE8YV.js → Sla-jl7UTiRY.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-Cq1oG56m.js → SpeechSettings-BePa-RF6.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-DdKW6V-C.js → SyncSettings-DiqqDKGZ.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-BCc9san5.js → Tasks-DYQ_6lxj.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-CcHC1dMA.js → Templates-JiDeI06L.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-CA4PqU22.js → Tenant-hhgI6zwS.js} +1 -1
- package/src/assets/web-panel/assets/Terminal-CjTZPa37.js +3 -0
- package/src/assets/web-panel/assets/{TimelineRenderer-DHWTSvOy.js → TimelineRenderer-B8uB5Llk.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-Ddz-P_yh.js → Tokens-C3b_6r2z.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-ePmrmLZ1.js → Trigger-tIP7HKVe.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-DmuK1CCE.js → Trust-vjoc11vJ.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-CqqBuRrT.js → UkeySign-DUPBnGuH.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-BGlR3uWM.js → VideoEditing-CBvhUY5T.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-Ba_Qx6Ga.js → Wallet-DUaQ0uA5.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-29neXKt2.js → WebAuthn-DllSivjE.js} +5 -5
- package/src/assets/web-panel/assets/{WorkflowEditor-lD0lR0UQ.js → WorkflowEditor-xc8D3uO6.js} +1 -1
- package/src/assets/web-panel/assets/{chat-B3stH01u.js → chat-BVicU7oA.js} +1 -1
- package/src/assets/web-panel/assets/{colors-Czly56MN.js → colors-DJzLmhLm.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-C0TkbkAJ.js → compact-item-BvYRfThE.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-BJmpSlf1.js → createContext-DGXxCBKR.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-BT46Y_QI.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-D1q-zw7u.js → hasIn-SBDJB1y4.js} +1 -1
- package/src/assets/web-panel/assets/{index-DV-twjNO.js → index-1SdDS6lR.js} +1 -1
- package/src/assets/web-panel/assets/{index-B-kTvMq7.js → index-9gdI7uUW.js} +1 -1
- package/src/assets/web-panel/assets/index-B7nuIywP.js +1 -0
- package/src/assets/web-panel/assets/{index-Bm_-RKal.js → index-BJZf9DhV.js} +1 -1
- package/src/assets/web-panel/assets/{index-CQftlZn-.js → index-BO1itZaY.js} +3 -3
- package/src/assets/web-panel/assets/{index-Dw3L_smW.js → index-BTrBGBJs.js} +1 -1
- package/src/assets/web-panel/assets/{index-C7sFKQ53.js → index-BYqz4Wrr.js} +1 -1
- package/src/assets/web-panel/assets/{index-DlvsSuBC.js → index-Bf-ctERC.js} +1 -1
- package/src/assets/web-panel/assets/{index-ChESIe5r.js → index-CKyEivf8.js} +1 -1
- package/src/assets/web-panel/assets/{index-DaqEHaCg.js → index-CdGY9P8a.js} +1 -1
- package/src/assets/web-panel/assets/{index-DZeoKL6t.js → index-Cf-O_g_8.js} +1 -1
- package/src/assets/web-panel/assets/{index-XWV8JWMc.js → index-CloCgBUR.js} +1 -1
- package/src/assets/web-panel/assets/{index-CpMIdPJ0.js → index-CoJAO1Lm.js} +1 -1
- package/src/assets/web-panel/assets/{index-CgS8XUBU.js → index-Crk5NTb0.js} +1 -1
- package/src/assets/web-panel/assets/{index-DmUta2lw.js → index-Cs2rmLFt.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dpz_7sf-.js → index-CtwqO5qo.js} +1 -1
- package/src/assets/web-panel/assets/{index-DRcQsPez.js → index-D7HimK0M.js} +1 -1
- package/src/assets/web-panel/assets/{index-BEt2-3x5.js → index-DCdRAgjy.js} +1 -1
- package/src/assets/web-panel/assets/{index-CHvPlzWJ.js → index-DCqRS6da.js} +1 -1
- package/src/assets/web-panel/assets/{index-BDHXx65P.js → index-DHVLJ8q0.js} +1 -1
- package/src/assets/web-panel/assets/{index-K4YaPDOn.js → index-DKrvvWm4.js} +1 -1
- package/src/assets/web-panel/assets/{index-C1pOqU7D.js → index-DMarmfrv.js} +1 -1
- package/src/assets/web-panel/assets/{index-DAhrn9EJ.js → index-DRfiXB_p.js} +1 -1
- package/src/assets/web-panel/assets/{index-cPjWjvmW.js → index-Dm_77jgR.js} +1 -1
- package/src/assets/web-panel/assets/{index-C27TnOoT.js → index-DnjPdvR6.js} +1 -1
- package/src/assets/web-panel/assets/{index-upY9rkGZ.js → index-DonCnfMr.js} +1 -1
- package/src/assets/web-panel/assets/{index-CbvNJUwu.js → index-DvUTDYXX.js} +1 -1
- package/src/assets/web-panel/assets/{index-BVwJ3jht.js → index-FxZzRyE1.js} +1 -1
- package/src/assets/web-panel/assets/{index-DIF6XHIi.js → index-MjC4G09d.js} +1 -1
- package/src/assets/web-panel/assets/{index-B8KqsomG.js → index-VMfwIH5G.js} +1 -1
- package/src/assets/web-panel/assets/{index-8GKykbS4.js → index-YJkzy8ZF.js} +1 -1
- package/src/assets/web-panel/assets/{index-DpGs96FC.js → index-d5BVd-cL.js} +1 -1
- package/src/assets/web-panel/assets/{index-DO8xOwxi.js → index-e4fXH_WO.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cu_4HaUS.js → index-hxTODbM1.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cf7Gr3NG.js → index-lpaGoTH3.js} +1 -1
- package/src/assets/web-panel/assets/{index-DBqAm8es.js → index-wcCL-miV.js} +1 -1
- package/src/assets/web-panel/assets/{index-ZDUhX41Z.js → index-xfluRkCT.js} +1 -1
- package/src/assets/web-panel/assets/index-ycwAfC-i.js +1 -0
- package/src/assets/web-panel/assets/{index-z8ATo2aQ.js → index-z1ZylsLq.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-QWEXi6-t.js → initDefaultProps-C1zO1KnY.js} +1 -1
- package/src/assets/web-panel/assets/{motion-BfrQwvV1.js → motion-CWLtEGmC.js} +1 -1
- package/src/assets/web-panel/assets/{move-Dn7x0H9t.js → move-DzD_C3Vm.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-F61D_TgE.js → mtc-parser-D880PYJl.js} +1 -1
- package/src/assets/web-panel/assets/{omit-4SQZ39PF.js → omit-CFR_z2ov.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-C7DTe126.js → pickAttrs-srIhgrSC.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-40NeyzDK.js → placementArrow-C1rXpibP.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-BiUJ6qWs.js → responsiveObserve-C30gRcSS.js} +1 -1
- package/src/assets/web-panel/assets/{slide-CacJTM3f.js → slide-CvtKiMfV.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-K812HB-k.js → statusUtils-DNHO7ITG.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-CKeHA2eM.js → styleChecker-Dt_Sl-g4.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-CKl4FqXF.js → useFlexGapSupport-Cjev42Gh.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-DPoiJjSZ.js → useFs-Baxglj2V.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-aHwBspmt.js → usePersonalDataHub-B4NkcLaP.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-DrA-GuCT.js → vnode-mIRkdT7o.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-G3LMswgy.js → zoom-HzI5DlH_.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/auth/npm-auth.js +30 -5
- package/src/commands/agenda.js +64 -2
- package/src/commands/agent.js +45 -3
- package/src/commands/background-session.js +103 -0
- package/src/commands/config.js +70 -5
- package/src/commands/context.js +36 -2
- package/src/commands/hub.js +19 -1
- package/src/commands/memory.js +21 -6
- package/src/commands/permissions.js +57 -1
- package/src/commands/plugin.js +2 -0
- package/src/commands/review.js +23 -11
- package/src/commands/routine.js +31 -8
- package/src/commands/session.js +11 -3
- package/src/commands/team.js +20 -7
- package/src/commands/update.js +65 -10
- package/src/esm-bridge.js +3 -0
- package/src/gateways/terminal/PtyManager.js +8 -1
- package/src/gateways/ws/message-dispatcher.js +3 -0
- package/src/gateways/ws/session-protocol.js +26 -0
- package/src/gateways/ws/ws-agent-handler.js +107 -69
- package/src/gateways/ws/ws-server.js +92 -4
- package/src/harness/jsonl-session-store.js +13 -6
- package/src/harness/mcp-client.js +200 -1
- package/src/index.js +123 -55
- package/src/lazy-dispatch.js +86 -85
- package/src/lib/__tests__/personal-data-hub-aichat-wizard.test.js +15 -0
- package/src/lib/agent-coordinator.js +4 -0
- package/src/lib/agent-ipc-bus.js +32 -2
- package/src/lib/agent-sandbox.js +16 -2
- package/src/lib/agent-schedule-store.js +55 -0
- package/src/lib/agent-tool-admission.js +104 -0
- package/src/lib/api-key-helper.js +10 -2
- package/src/lib/async-hook-supervisor.cjs +26 -4
- package/src/lib/background-interaction-resolver.js +71 -0
- package/src/lib/background-session-transport.js +59 -1
- package/src/lib/changelog.js +19 -11
- package/src/lib/channels/channel-manager.js +6 -0
- package/src/lib/channels/telegram-channel.js +11 -1
- package/src/lib/channels/webhook-channel.js +15 -3
- package/src/lib/checkpoint-store.js +10 -2
- package/src/lib/cloud/bundle.js +12 -2
- package/src/lib/code-review.js +32 -8
- package/src/lib/computer-use/control-backend.js +18 -3
- package/src/lib/context-breakdown.js +46 -0
- package/src/lib/context-source-ledger.js +43 -0
- package/src/lib/crash-reporter.js +6 -0
- package/src/lib/diff-review-follow-up.js +154 -0
- package/src/lib/downloader.js +17 -3
- package/src/lib/ensure-utf8.js +11 -3
- package/src/lib/event-runtime-producer.js +58 -0
- package/src/lib/event-runtime-store.js +354 -0
- package/src/lib/event-runtime-worker.js +109 -0
- package/src/lib/execution-backend.js +72 -21
- package/src/lib/git-integration.js +19 -4
- package/src/lib/hook-manager.js +34 -15
- package/src/lib/hook-runner.cjs +48 -3
- package/src/lib/hooks-v2-producers.js +15 -0
- package/src/lib/hooks-v2-runtime.js +70 -21
- package/src/lib/host-adb-bridge.js +111 -21
- package/src/lib/ide-context.js +128 -1
- package/src/lib/interaction-adapter.js +39 -0
- package/src/lib/ipc-attach-protocol.js +98 -0
- package/src/lib/json-schema-validate.js +190 -36
- package/src/lib/lan-pairing-preflight.js +13 -2
- package/src/lib/lsp/__tests__/lsp-server-registry.test.js +18 -0
- package/src/lib/lsp/lsp-client.js +18 -1
- package/src/lib/lsp/lsp-manager.js +4 -0
- package/src/lib/lsp/lsp-server-registry.js +11 -0
- package/src/lib/mcp-oauth.js +8 -2
- package/src/lib/npm-invocation.js +29 -0
- package/src/lib/packer/pkg-runner.js +13 -2
- package/src/lib/packer/precheck.js +33 -16
- package/src/lib/packer/web-panel-builder.js +16 -2
- package/src/lib/permission-rules.cjs +5 -1
- package/src/lib/personal-data-hub-aichat-wizard.js +22 -6
- package/src/lib/personal-data-hub-wiring.js +27 -3
- package/src/lib/plan-mode.js +204 -11
- package/src/lib/plugin-monitor-supervisor.js +39 -4
- package/src/lib/plugin-runtime/bin.js +45 -0
- package/src/lib/plugin-runtime/hooks.js +14 -1
- package/src/lib/plugin-runtime/install.js +2 -1
- package/src/lib/plugin-runtime/lsp.js +3 -0
- package/src/lib/plugin-runtime/mcp.js +8 -1
- package/src/lib/plugin-runtime/monitors.js +4 -0
- package/src/lib/plugin-runtime/plugin-options.js +74 -7
- package/src/lib/plugin-runtime/signature.js +45 -0
- package/src/lib/pr-create.js +21 -8
- package/src/lib/pr-link-ledger.js +15 -3
- package/src/lib/process-execution-broker/credential-agent.js +295 -0
- package/src/lib/process-execution-broker/index.js +440 -14
- package/src/lib/process-execution-broker/patch-child-process.js +2 -3
- package/src/lib/process-execution-broker/platform-sandbox.js +351 -0
- package/src/lib/process-manager.js +18 -3
- package/src/lib/provenance-api.js +6 -0
- package/src/lib/proxy-bootstrap.js +19 -0
- package/src/lib/publish-workspace.js +14 -6
- package/src/lib/repl-rewind.js +9 -4
- package/src/lib/secret-store.js +159 -0
- package/src/lib/service-manager.js +64 -29
- package/src/lib/session-hooks.js +328 -473
- package/src/lib/session-telemetry-middleware.js +6 -0
- package/src/lib/settings-hook-events.cjs +61 -1
- package/src/lib/settings-hooks.cjs +4 -0
- package/src/lib/side-effect-ledger.js +22 -0
- package/src/lib/sub-agent-context.js +5 -0
- package/src/lib/sub-agent-profiles.js +4 -0
- package/src/lib/trace-api.js +6 -0
- package/src/lib/turn-context.js +14 -8
- package/src/lib/unattended-action-policy.js +83 -0
- package/src/lib/update-notice.js +9 -45
- package/src/lib/with-file-lock.js +7 -0
- package/src/lib/ws-server.js +1 -0
- package/src/repl/agent-repl.js +71 -13
- package/src/repl/clipboard-copy.js +8 -2
- package/src/repl/pr-comments.js +30 -7
- package/src/runtime/agent-core.js +439 -87
- package/src/runtime/agent-runtime.js +1 -0
- package/src/runtime/coding-agent-contract-shared.cjs +52 -0
- package/src/runtime/coding-agent-policy.cjs +20 -0
- package/src/runtime/diagnostics.js +73 -8
- package/src/runtime/headless-runner.js +63 -0
- package/src/runtime/headless-stream.js +269 -17
- package/src/runtime/mcp-config.js +16 -1
- package/src/workers/background-agent-worker.js +80 -1
- package/src/assets/web-panel/assets/AppLayout-7iSKDmlI.js +0 -9
- package/src/assets/web-panel/assets/ChatBubbleRenderer-DcbUHeGW.js +0 -1
- package/src/assets/web-panel/assets/Dashboard-BAKYNavw.js +0 -3
- package/src/assets/web-panel/assets/MobileProjects-C4GKn1dH.js +0 -1
- package/src/assets/web-panel/assets/Terminal-Fj7ea0In.js +0 -3
- package/src/assets/web-panel/assets/devWarning-CDI8Sbaj.js +0 -1
- package/src/assets/web-panel/assets/index-96LBR96V.js +0 -1
- package/src/assets/web-panel/assets/index-DyQkiW24.js +0 -1
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
import fs from "fs";
|
|
18
18
|
import path from "path";
|
|
19
19
|
import { execSync, spawn, spawnSync } from "child_process";
|
|
20
|
+
import broker from "../lib/process-execution-broker/index.js";
|
|
20
21
|
import os from "os";
|
|
21
22
|
import sharedCodingAgentPolicy from "./coding-agent-policy.cjs";
|
|
22
23
|
import sharedShellPolicy from "./coding-agent-shell-policy.cjs";
|
|
@@ -47,6 +48,7 @@ import {
|
|
|
47
48
|
import {
|
|
48
49
|
getCodingAgentFunctionToolDefinitions,
|
|
49
50
|
listCodingAgentToolNames,
|
|
51
|
+
getCodingAgentToolPolicy,
|
|
50
52
|
} from "./coding-agent-contract.js";
|
|
51
53
|
import { createToolContext } from "../tools/tool-context.js";
|
|
52
54
|
import { createToolTelemetryRecord } from "../tools/tool-telemetry.js";
|
|
@@ -78,6 +80,12 @@ import {
|
|
|
78
80
|
imageUrlBlockToAnthropic,
|
|
79
81
|
} from "../lib/image-input.js";
|
|
80
82
|
import { executeToolSearch, gateDeferredMcpCall } from "./mcp-tool-search.js";
|
|
83
|
+
import { emitHooksV2Event } from "../lib/hooks-v2-producers.js";
|
|
84
|
+
import {
|
|
85
|
+
admitTool,
|
|
86
|
+
buildToolAttribution,
|
|
87
|
+
} from "../lib/agent-tool-admission.js";
|
|
88
|
+
import { evaluateUnattendedShellAction } from "../lib/unattended-action-policy.js";
|
|
81
89
|
|
|
82
90
|
/**
|
|
83
91
|
* Names of MCP servers currently mounted by an in-flight run_skill call.
|
|
@@ -470,8 +478,9 @@ async function runSettingsPreToolUseHooks(name, args, context, cwd) {
|
|
|
470
478
|
? await runCommandHooksParallel(matched, payload, {
|
|
471
479
|
cwd,
|
|
472
480
|
event: "PreToolUse",
|
|
481
|
+
broker,
|
|
473
482
|
})
|
|
474
|
-
: runCommandHooks(matched, payload, { cwd, event: "PreToolUse" });
|
|
483
|
+
: runCommandHooks(matched, payload, { cwd, event: "PreToolUse", broker });
|
|
475
484
|
if (outcome.decision === "block") {
|
|
476
485
|
return { blocked: true, reason: outcome.reason, hook: outcome.hook };
|
|
477
486
|
}
|
|
@@ -552,6 +561,7 @@ function runSettingsPermissionRequestHooks(name, args, context, cwd, reason) {
|
|
|
552
561
|
cwd,
|
|
553
562
|
event: "PermissionRequest",
|
|
554
563
|
mergeStrict: _hookStrictMergeEnabled(),
|
|
564
|
+
broker,
|
|
555
565
|
});
|
|
556
566
|
// Precedence: deny > ask > allow > defer. The runner normalizes deny/block →
|
|
557
567
|
// "block" and short-circuits block/ask, but it COLLAPSES an "allow" into the
|
|
@@ -770,6 +780,7 @@ You have access to tools that let you read files, write files, edit files, run s
|
|
|
770
780
|
Key behaviors:
|
|
771
781
|
- When asked to modify code, read the file first, then edit it
|
|
772
782
|
- When asked to create something, use write_file to create it
|
|
783
|
+
- When asked to remove or rename a file, use delete_file or move_file so the filesystem intent is explicit and reviewable
|
|
773
784
|
- When asked to run/test something, use run_shell to execute it
|
|
774
785
|
- For long-running commands (builds, full test suites, dev servers) set run_shell { run_in_background: true } to get a task_id back immediately, then poll output and completion with check_shell { task_id }. Kill a backgrounded server with check_shell { task_id, kill: true } when finished
|
|
775
786
|
- When asked about git status, diff, log, or other repository operations, use the git tool instead of run_shell
|
|
@@ -926,6 +937,9 @@ export function buildSystemPrompt(cwd, opts = {}) {
|
|
|
926
937
|
const personaSkills = allSkills.filter(
|
|
927
938
|
(s) => s.category === "persona" && s.activation === "auto",
|
|
928
939
|
);
|
|
940
|
+
if (typeof opts.onSkillsLoaded === "function") {
|
|
941
|
+
opts.onSkillsLoaded(personaSkills);
|
|
942
|
+
}
|
|
929
943
|
for (const p of personaSkills) {
|
|
930
944
|
if (p.body?.trim()) {
|
|
931
945
|
prompt += `\n\n## Persona: ${p.displayName}\n${p.body}`;
|
|
@@ -1016,8 +1030,21 @@ const IDE_DIFF_EDIT_TOOLS = new Set([
|
|
|
1016
1030
|
"write_file",
|
|
1017
1031
|
"edit_file",
|
|
1018
1032
|
"edit_file_hashed",
|
|
1033
|
+
"delete_file",
|
|
1034
|
+
"move_file",
|
|
1035
|
+
]);
|
|
1036
|
+
const GUARDED_FILE_MUTATION_TOOLS = new Set([
|
|
1037
|
+
...IDE_DIFF_EDIT_TOOLS,
|
|
1038
|
+
"notebook_edit",
|
|
1019
1039
|
]);
|
|
1020
1040
|
|
|
1041
|
+
function fileMutationPaths(name, args = {}) {
|
|
1042
|
+
return [
|
|
1043
|
+
args.path,
|
|
1044
|
+
...(name === "move_file" ? [args.target_path] : []),
|
|
1045
|
+
].filter(Boolean);
|
|
1046
|
+
}
|
|
1047
|
+
|
|
1021
1048
|
/**
|
|
1022
1049
|
* Quote-aware shell tokenizer (mirrors gateways/ws `tokenizeCommand`). The `git`
|
|
1023
1050
|
* tool runs the model-supplied command via argv (spawnSync, NO shell), so a
|
|
@@ -1086,12 +1113,11 @@ function applyLiteralEdit(content, oldStr, newStr, replaceAll) {
|
|
|
1086
1113
|
/**
|
|
1087
1114
|
* Compute the content an edit tool WOULD write, without writing it — the
|
|
1088
1115
|
* left/right sides for an IDE diff review. Mirrors the corresponding
|
|
1089
|
-
* executeToolInner cases exactly (
|
|
1090
|
-
*
|
|
1091
|
-
*
|
|
1092
|
-
*
|
|
1093
|
-
*
|
|
1094
|
-
* own diagnostics.
|
|
1116
|
+
* executeToolInner cases exactly (write/edit/delete/move; hashed edits use the
|
|
1117
|
+
* same pure replaceByHash). Returns an explicit operation plus the left/right
|
|
1118
|
+
* text and optional rename destination, or null when the proposal cannot be
|
|
1119
|
+
* computed — the caller then falls back to normal confirmation so the tool can
|
|
1120
|
+
* produce its own diagnostics.
|
|
1095
1121
|
*/
|
|
1096
1122
|
export function computeProposedEdit(name, args = {}, cwd = process.cwd()) {
|
|
1097
1123
|
try {
|
|
@@ -1099,10 +1125,49 @@ export function computeProposedEdit(name, args = {}, cwd = process.cwd()) {
|
|
|
1099
1125
|
const filePath = path.resolve(cwd, args.path);
|
|
1100
1126
|
if (name === "write_file") {
|
|
1101
1127
|
if (typeof args.content !== "string") return null;
|
|
1102
|
-
const
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1128
|
+
const exists = fs.existsSync(filePath);
|
|
1129
|
+
const originalText = exists ? fs.readFileSync(filePath, "utf8") : "";
|
|
1130
|
+
return {
|
|
1131
|
+
filePath,
|
|
1132
|
+
newContent: args.content,
|
|
1133
|
+
originalText,
|
|
1134
|
+
operation: exists ? "modify" : "create",
|
|
1135
|
+
};
|
|
1136
|
+
}
|
|
1137
|
+
if (name === "delete_file") {
|
|
1138
|
+
if (!fs.existsSync(filePath) || fs.statSync(filePath).isDirectory()) {
|
|
1139
|
+
return null;
|
|
1140
|
+
}
|
|
1141
|
+
const originalText = fs.readFileSync(filePath, "utf8");
|
|
1142
|
+
return {
|
|
1143
|
+
filePath,
|
|
1144
|
+
newContent: "",
|
|
1145
|
+
originalText,
|
|
1146
|
+
operation: "delete",
|
|
1147
|
+
};
|
|
1148
|
+
}
|
|
1149
|
+
if (name === "move_file") {
|
|
1150
|
+
if (
|
|
1151
|
+
!args.target_path ||
|
|
1152
|
+
!fs.existsSync(filePath) ||
|
|
1153
|
+
fs.statSync(filePath).isDirectory()
|
|
1154
|
+
) {
|
|
1155
|
+
return null;
|
|
1156
|
+
}
|
|
1157
|
+
const targetPath = path.resolve(cwd, args.target_path);
|
|
1158
|
+
if (targetPath === filePath || fs.existsSync(targetPath)) return null;
|
|
1159
|
+
const targetDir = path.dirname(targetPath);
|
|
1160
|
+
if (!fs.existsSync(targetDir) || !fs.statSync(targetDir).isDirectory()) {
|
|
1161
|
+
return null;
|
|
1162
|
+
}
|
|
1163
|
+
const originalText = fs.readFileSync(filePath, "utf8");
|
|
1164
|
+
return {
|
|
1165
|
+
filePath,
|
|
1166
|
+
targetPath,
|
|
1167
|
+
newContent: originalText,
|
|
1168
|
+
originalText,
|
|
1169
|
+
operation: "rename",
|
|
1170
|
+
};
|
|
1106
1171
|
}
|
|
1107
1172
|
if (name === "edit_file") {
|
|
1108
1173
|
if (!fs.existsSync(filePath)) return null;
|
|
@@ -1124,7 +1189,12 @@ export function computeProposedEdit(name, args = {}, cwd = process.cwd()) {
|
|
|
1124
1189
|
// No match, or a non-unique match without replace_all → the edit will be
|
|
1125
1190
|
// rejected, so show no (misleading) diff and let the tool report it.
|
|
1126
1191
|
if (count === 0 || (count > 1 && !replaceAll)) return null;
|
|
1127
|
-
return {
|
|
1192
|
+
return {
|
|
1193
|
+
filePath,
|
|
1194
|
+
newContent,
|
|
1195
|
+
originalText: content,
|
|
1196
|
+
operation: "modify",
|
|
1197
|
+
};
|
|
1128
1198
|
}
|
|
1129
1199
|
if (name === "edit_file_hashed") {
|
|
1130
1200
|
if (!fs.existsSync(filePath)) return null;
|
|
@@ -1136,7 +1206,12 @@ export function computeProposedEdit(name, args = {}, cwd = process.cwd()) {
|
|
|
1136
1206
|
newLine: args.new_line,
|
|
1137
1207
|
});
|
|
1138
1208
|
if (!result.success) return null;
|
|
1139
|
-
return {
|
|
1209
|
+
return {
|
|
1210
|
+
filePath,
|
|
1211
|
+
newContent: result.content,
|
|
1212
|
+
originalText: original,
|
|
1213
|
+
operation: "modify",
|
|
1214
|
+
};
|
|
1140
1215
|
}
|
|
1141
1216
|
} catch {
|
|
1142
1217
|
// unreadable file etc. → no proposal, normal path handles it
|
|
@@ -1184,6 +1259,11 @@ async function tryIdeDiffApprovalForEdit(
|
|
|
1184
1259
|
modifiedText: proposal.newContent,
|
|
1185
1260
|
originalText: proposal.originalText,
|
|
1186
1261
|
title: `cc agent: ${name} ${path.basename(proposal.filePath)}`,
|
|
1262
|
+
operation: proposal.operation,
|
|
1263
|
+
targetPath: proposal.targetPath,
|
|
1264
|
+
sessionId: context.sessionId || null,
|
|
1265
|
+
turnId: context.turnId || null,
|
|
1266
|
+
toolUseId: context.toolCallId || null,
|
|
1187
1267
|
});
|
|
1188
1268
|
if (verdict?.outcome === "accepted") {
|
|
1189
1269
|
// When the reviewer amended the proposal in the diff before accepting,
|
|
@@ -1196,24 +1276,32 @@ async function tryIdeDiffApprovalForEdit(
|
|
|
1196
1276
|
: null;
|
|
1197
1277
|
return {
|
|
1198
1278
|
outcome: "accepted",
|
|
1199
|
-
result:
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
? {
|
|
1205
|
-
:
|
|
1206
|
-
|
|
1207
|
-
|
|
1279
|
+
result: attachDiffReviewAudit(
|
|
1280
|
+
{
|
|
1281
|
+
success: true,
|
|
1282
|
+
path: proposal.filePath,
|
|
1283
|
+
operation: proposal.operation,
|
|
1284
|
+
...(proposal.targetPath ? { targetPath: proposal.targetPath } : {}),
|
|
1285
|
+
appliedVia: "ide-diff",
|
|
1286
|
+
...(amendments
|
|
1287
|
+
? { userEdited: true, userAmendments: amendments }
|
|
1288
|
+
: {}),
|
|
1289
|
+
policy: { decision: "allow", rule, via: "ide-diff" },
|
|
1290
|
+
},
|
|
1291
|
+
verdict.audit,
|
|
1292
|
+
),
|
|
1208
1293
|
};
|
|
1209
1294
|
}
|
|
1210
1295
|
if (verdict?.outcome === "rejected") {
|
|
1211
1296
|
return {
|
|
1212
1297
|
outcome: "rejected",
|
|
1213
|
-
result:
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1298
|
+
result: attachDiffReviewAudit(
|
|
1299
|
+
{
|
|
1300
|
+
error: `[Permission] "${name}" was rejected in the IDE diff review (${source}: ${rule}).`,
|
|
1301
|
+
policy: { decision: "deny", rule, via: "ide-diff" },
|
|
1302
|
+
},
|
|
1303
|
+
verdict.audit,
|
|
1304
|
+
),
|
|
1217
1305
|
};
|
|
1218
1306
|
}
|
|
1219
1307
|
if (verdict?.outcome === "changes-requested") {
|
|
@@ -1225,14 +1313,17 @@ async function tryIdeDiffApprovalForEdit(
|
|
|
1225
1313
|
"The user requested changes in the IDE diff review (no specific notes).";
|
|
1226
1314
|
return {
|
|
1227
1315
|
outcome: "changes-requested",
|
|
1228
|
-
result:
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1316
|
+
result: attachDiffReviewAudit(
|
|
1317
|
+
{
|
|
1318
|
+
error:
|
|
1319
|
+
`[IDE review] "${name}" was NOT applied — the user requested changes:\n` +
|
|
1320
|
+
`${feedback}\n` +
|
|
1321
|
+
"Revise the edit to address this feedback, then propose it again.",
|
|
1322
|
+
policy: { decision: "deny", rule, via: "ide-diff-review" },
|
|
1323
|
+
reviewComments: verdict.comments,
|
|
1324
|
+
},
|
|
1325
|
+
verdict.audit,
|
|
1326
|
+
),
|
|
1236
1327
|
};
|
|
1237
1328
|
}
|
|
1238
1329
|
} catch (_err) {
|
|
@@ -1241,6 +1332,20 @@ async function tryIdeDiffApprovalForEdit(
|
|
|
1241
1332
|
return null;
|
|
1242
1333
|
}
|
|
1243
1334
|
|
|
1335
|
+
/**
|
|
1336
|
+
* Keep the audit available to stream/WS ledger consumers without serializing
|
|
1337
|
+
* it into the model-facing tool result (which would waste context tokens).
|
|
1338
|
+
*/
|
|
1339
|
+
function attachDiffReviewAudit(result, audit) {
|
|
1340
|
+
if (!result || typeof result !== "object" || !audit) return result;
|
|
1341
|
+
Object.defineProperty(result, "_diffReviewAudit", {
|
|
1342
|
+
value: audit,
|
|
1343
|
+
enumerable: false,
|
|
1344
|
+
configurable: true,
|
|
1345
|
+
});
|
|
1346
|
+
return result;
|
|
1347
|
+
}
|
|
1348
|
+
|
|
1244
1349
|
/**
|
|
1245
1350
|
* Execute a single tool call with plan-mode filtering and hook pipeline.
|
|
1246
1351
|
*
|
|
@@ -1264,6 +1369,56 @@ export async function executeTool(name, args, context = {}) {
|
|
|
1264
1369
|
: null;
|
|
1265
1370
|
const runtimeDescriptor =
|
|
1266
1371
|
getRuntimeToolDescriptor(name) || localToolDescriptor;
|
|
1372
|
+
const admission = context.toolAdmission;
|
|
1373
|
+
if (admission?.enforce === true) {
|
|
1374
|
+
const override =
|
|
1375
|
+
admission.tools && typeof admission.tools === "object"
|
|
1376
|
+
? admission.tools[name] || {}
|
|
1377
|
+
: {};
|
|
1378
|
+
const tier =
|
|
1379
|
+
override.tier ||
|
|
1380
|
+
runtimeDescriptor?.tier ||
|
|
1381
|
+
getCodingAgentToolPolicy(name)?.tier ||
|
|
1382
|
+
(localToolDescriptor ? "extension" : "mvp");
|
|
1383
|
+
const decision = admitTool({
|
|
1384
|
+
tool: name,
|
|
1385
|
+
tier,
|
|
1386
|
+
capabilityGranted:
|
|
1387
|
+
override.capabilityGranted ?? admission.capabilityGranted,
|
|
1388
|
+
policyAllowed:
|
|
1389
|
+
override.policyAllowed ??
|
|
1390
|
+
(context.hostManagedToolPolicy ?
|
|
1391
|
+
((context.hostManagedToolPolicy?.tools ||
|
|
1392
|
+
context.hostManagedToolPolicy?.toolPolicies || {})[name]
|
|
1393
|
+
?.allowed !== false) :
|
|
1394
|
+
admission.policyAllowed),
|
|
1395
|
+
permissionGranted:
|
|
1396
|
+
override.permissionGranted ?? admission.permissionGranted,
|
|
1397
|
+
budgetOk: override.budgetOk ?? admission.budgetOk,
|
|
1398
|
+
uiSupported: override.uiSupported ?? admission.uiSupported,
|
|
1399
|
+
});
|
|
1400
|
+
const attribution = buildToolAttribution({
|
|
1401
|
+
tool: name,
|
|
1402
|
+
source:
|
|
1403
|
+
override.source ||
|
|
1404
|
+
runtimeDescriptor?.source ||
|
|
1405
|
+
localToolDescriptor?.source ||
|
|
1406
|
+
admission.source ||
|
|
1407
|
+
null,
|
|
1408
|
+
version: override.version || runtimeDescriptor?.version || null,
|
|
1409
|
+
scope: override.scope || localToolDescriptor?.scope || null,
|
|
1410
|
+
callId: context.toolCallId || null,
|
|
1411
|
+
decision,
|
|
1412
|
+
});
|
|
1413
|
+
if (!decision.admitted) {
|
|
1414
|
+
return {
|
|
1415
|
+
error: `[Tool Admission] Tool "${name}" was not admitted: ${decision.unmet.join(", ")}.`,
|
|
1416
|
+
toolAttribution: attribution,
|
|
1417
|
+
policy: { decision: "blocked", via: "tool-admission" },
|
|
1418
|
+
};
|
|
1419
|
+
}
|
|
1420
|
+
context = { ...context, toolAttribution: attribution };
|
|
1421
|
+
}
|
|
1267
1422
|
const toolContext = createToolContext({
|
|
1268
1423
|
toolName: runtimeDescriptor?.name || name,
|
|
1269
1424
|
cwd,
|
|
@@ -1397,26 +1552,29 @@ export async function executeTool(name, args, context = {}) {
|
|
|
1397
1552
|
// An explicit settings `allow` rule is the only bypass (exact user
|
|
1398
1553
|
// pre-authorization); headless without a confirmer fails closed.
|
|
1399
1554
|
if (
|
|
1400
|
-
(name
|
|
1401
|
-
|
|
1402
|
-
name === "notebook_edit") &&
|
|
1403
|
-
settingsVerdict.decision !== "allow" &&
|
|
1404
|
-
args?.path
|
|
1555
|
+
GUARDED_FILE_MUTATION_TOOLS.has(name) &&
|
|
1556
|
+
settingsVerdict.decision !== "allow"
|
|
1405
1557
|
) {
|
|
1406
1558
|
const { sensitiveFileReason, autoExecConfigReason } =
|
|
1407
1559
|
await import("../lib/sensitive-file-guard.js");
|
|
1408
|
-
const
|
|
1409
|
-
|
|
1410
|
-
|
|
1560
|
+
const guarded = fileMutationPaths(name, args)
|
|
1561
|
+
.map((candidatePath) => ({
|
|
1562
|
+
path: candidatePath,
|
|
1563
|
+
reason:
|
|
1564
|
+
sensitiveFileReason(candidatePath) ||
|
|
1565
|
+
autoExecConfigReason(candidatePath),
|
|
1566
|
+
}))
|
|
1567
|
+
.find((candidate) => candidate.reason);
|
|
1568
|
+
if (guarded) {
|
|
1411
1569
|
const ok = await requestInteractivePermission(name, args, context, cwd, {
|
|
1412
1570
|
tool: name,
|
|
1413
1571
|
args,
|
|
1414
1572
|
rule: null,
|
|
1415
|
-
reason: `sensitive file: ${
|
|
1573
|
+
reason: `sensitive file: ${guarded.reason}`,
|
|
1416
1574
|
});
|
|
1417
1575
|
if (!ok) {
|
|
1418
1576
|
return {
|
|
1419
|
-
error: `[Sensitive File]
|
|
1577
|
+
error: `[Sensitive File] Mutating "${guarded.path}" requires confirmation (${guarded.reason}) — denied. Add a settings allow rule to pre-authorize.`,
|
|
1420
1578
|
policy: { decision: "ask", via: "sensitive-file" },
|
|
1421
1579
|
};
|
|
1422
1580
|
}
|
|
@@ -1430,25 +1588,27 @@ export async function executeTool(name, args, context = {}) {
|
|
|
1430
1588
|
// sensitive-file guard: confirm-first, an explicit settings `allow` rule is
|
|
1431
1589
|
// the only bypass, headless without a confirmer fails closed.
|
|
1432
1590
|
if (
|
|
1433
|
-
(name
|
|
1434
|
-
|
|
1435
|
-
name === "notebook_edit") &&
|
|
1436
|
-
settingsVerdict.decision !== "allow" &&
|
|
1437
|
-
args?.path
|
|
1591
|
+
GUARDED_FILE_MUTATION_TOOLS.has(name) &&
|
|
1592
|
+
settingsVerdict.decision !== "allow"
|
|
1438
1593
|
) {
|
|
1439
1594
|
const { sessionStorePathReason } =
|
|
1440
1595
|
await import("../lib/session-store-guard.js");
|
|
1441
|
-
const
|
|
1442
|
-
|
|
1596
|
+
const guarded = fileMutationPaths(name, args)
|
|
1597
|
+
.map((candidatePath) => ({
|
|
1598
|
+
path: candidatePath,
|
|
1599
|
+
reason: sessionStorePathReason(candidatePath, { cwd }),
|
|
1600
|
+
}))
|
|
1601
|
+
.find((candidate) => candidate.reason);
|
|
1602
|
+
if (guarded) {
|
|
1443
1603
|
const ok = await requestInteractivePermission(name, args, context, cwd, {
|
|
1444
1604
|
tool: name,
|
|
1445
1605
|
args,
|
|
1446
1606
|
rule: null,
|
|
1447
|
-
reason: `session store: ${
|
|
1607
|
+
reason: `session store: ${guarded.reason}`,
|
|
1448
1608
|
});
|
|
1449
1609
|
if (!ok) {
|
|
1450
1610
|
return {
|
|
1451
|
-
error: `[Session Store]
|
|
1611
|
+
error: `[Session Store] Mutating "${guarded.path}" would modify a session transcript (${guarded.reason}) — denied. Add a settings allow rule to pre-authorize.`,
|
|
1452
1612
|
policy: { decision: "ask", via: "session-store-guard" },
|
|
1453
1613
|
};
|
|
1454
1614
|
}
|
|
@@ -1532,31 +1692,42 @@ export async function executeTool(name, args, context = {}) {
|
|
|
1532
1692
|
}
|
|
1533
1693
|
}
|
|
1534
1694
|
|
|
1535
|
-
// Plan mode:
|
|
1695
|
+
// Plan mode: settings/host allow rules may help exploration, but they cannot
|
|
1696
|
+
// widen the immutable tool set issued when the user approved the plan.
|
|
1697
|
+
const executionLockActive = planManager.executionLock != null;
|
|
1536
1698
|
if (
|
|
1537
1699
|
planManager.isActive() &&
|
|
1538
|
-
!ruleAllowed &&
|
|
1700
|
+
(!ruleAllowed || executionLockActive) &&
|
|
1539
1701
|
!(name === "git" && isReadOnlyGitCommand(args.command)) &&
|
|
1540
1702
|
!planManager.isToolAllowed(name) &&
|
|
1541
|
-
!(
|
|
1542
|
-
|
|
1703
|
+
!(
|
|
1704
|
+
!executionLockActive &&
|
|
1705
|
+
isExternalHostTool &&
|
|
1706
|
+
hostToolPolicy?.allowed === true
|
|
1707
|
+
) &&
|
|
1708
|
+
!(!executionLockActive && localReadOnlyAllowedInPlanMode)
|
|
1543
1709
|
) {
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1710
|
+
if (!executionLockActive) {
|
|
1711
|
+
planManager.addPlanItem({
|
|
1712
|
+
title: `${name}: ${formatToolArgs(name, args)}`,
|
|
1713
|
+
tool: name,
|
|
1714
|
+
params: args,
|
|
1715
|
+
estimatedImpact:
|
|
1716
|
+
name === "run_shell" ||
|
|
1717
|
+
name === "run_code" ||
|
|
1718
|
+
name === "git" ||
|
|
1719
|
+
localToolDescriptor?.riskLevel === "high"
|
|
1720
|
+
? "high"
|
|
1721
|
+
: GUARDED_FILE_MUTATION_TOOLS.has(name) ||
|
|
1722
|
+
localToolDescriptor?.riskLevel === "medium"
|
|
1723
|
+
? "medium"
|
|
1724
|
+
: "low",
|
|
1725
|
+
});
|
|
1726
|
+
}
|
|
1558
1727
|
return {
|
|
1559
|
-
error:
|
|
1728
|
+
error: executionLockActive
|
|
1729
|
+
? `[Plan Execution Lock] Tool "${name}" was not in the approved tool set. Request a plan revision before using it.`
|
|
1730
|
+
: `[Plan Mode] Tool "${name}" is blocked during planning. It has been added to the plan. Use /plan approve to execute.`,
|
|
1560
1731
|
};
|
|
1561
1732
|
}
|
|
1562
1733
|
|
|
@@ -1636,6 +1807,8 @@ export async function executeTool(name, args, context = {}) {
|
|
|
1636
1807
|
settingsHooks: context.settingsHooks || null,
|
|
1637
1808
|
signal: context.signal || null,
|
|
1638
1809
|
backgroundSubAgents: context.backgroundSubAgents || null,
|
|
1810
|
+
toolAdmission: context.toolAdmission || null,
|
|
1811
|
+
unattendedActionPolicy: context.unattendedActionPolicy || null,
|
|
1639
1812
|
});
|
|
1640
1813
|
} catch (err) {
|
|
1641
1814
|
if (hookDb) {
|
|
@@ -1663,6 +1836,9 @@ export async function executeTool(name, args, context = {}) {
|
|
|
1663
1836
|
});
|
|
1664
1837
|
if (toolResult && typeof toolResult === "object") {
|
|
1665
1838
|
toolResult.toolTelemetryRecord = telemetryRecord;
|
|
1839
|
+
if (context.toolAttribution) {
|
|
1840
|
+
toolResult.toolAttribution = context.toolAttribution;
|
|
1841
|
+
}
|
|
1666
1842
|
}
|
|
1667
1843
|
|
|
1668
1844
|
// PostToolUse hook
|
|
@@ -1717,6 +1893,7 @@ export async function executeTool(name, args, context = {}) {
|
|
|
1717
1893
|
const outcome = runCommandHooks(sync, payload, {
|
|
1718
1894
|
cwd,
|
|
1719
1895
|
event: "PostToolUse",
|
|
1896
|
+
broker,
|
|
1720
1897
|
});
|
|
1721
1898
|
if (outcome.decision === "block" && outcome.reason) {
|
|
1722
1899
|
toolResult.hookFeedback = outcome.reason;
|
|
@@ -1725,7 +1902,7 @@ export async function executeTool(name, args, context = {}) {
|
|
|
1725
1902
|
// Fire-and-forget the async hooks onto the REPL-owned supervisor when
|
|
1726
1903
|
// one is wired; results/rewakes drain into the next turn's context.
|
|
1727
1904
|
if (asyncHooks.length > 0 && context.hookSupervisor) {
|
|
1728
|
-
context.hookSupervisor.dispatch(asyncHooks, payload, { cwd });
|
|
1905
|
+
context.hookSupervisor.dispatch(asyncHooks, payload, { cwd, broker });
|
|
1729
1906
|
}
|
|
1730
1907
|
}
|
|
1731
1908
|
} catch (_err) {
|
|
@@ -2433,6 +2610,8 @@ async function executeToolInner(
|
|
|
2433
2610
|
signal = null,
|
|
2434
2611
|
backgroundSubAgents = null,
|
|
2435
2612
|
subAgentUsageSink = null,
|
|
2613
|
+
toolAdmission = null,
|
|
2614
|
+
unattendedActionPolicy = null,
|
|
2436
2615
|
// Hook-envelope tracing: this run's trace id, threaded into child loops
|
|
2437
2616
|
// (spawn_sub_agent / isolated run_skill) as their parent_id.
|
|
2438
2617
|
hookTraceId = null,
|
|
@@ -2599,6 +2778,86 @@ async function executeToolInner(
|
|
|
2599
2778
|
);
|
|
2600
2779
|
}
|
|
2601
2780
|
|
|
2781
|
+
case "delete_file": {
|
|
2782
|
+
if (!args.path) {
|
|
2783
|
+
return attachDescriptor({ error: "path is required" });
|
|
2784
|
+
}
|
|
2785
|
+
const filePath = path.resolve(cwd, args.path);
|
|
2786
|
+
if (!fs.existsSync(filePath)) {
|
|
2787
|
+
return attachDescriptor({ error: `File not found: ${filePath}` });
|
|
2788
|
+
}
|
|
2789
|
+
if (fs.lstatSync(filePath).isDirectory()) {
|
|
2790
|
+
return attachDescriptor({
|
|
2791
|
+
error: `Refusing to delete a directory: ${filePath}`,
|
|
2792
|
+
});
|
|
2793
|
+
}
|
|
2794
|
+
const stale = _checkFileFreshness(filePath);
|
|
2795
|
+
if (stale) return attachDescriptor({ error: stale });
|
|
2796
|
+
fs.unlinkSync(filePath);
|
|
2797
|
+
_fileObservedMtimes.delete(filePath);
|
|
2798
|
+
return attachDescriptor({
|
|
2799
|
+
success: true,
|
|
2800
|
+
path: filePath,
|
|
2801
|
+
operation: "delete",
|
|
2802
|
+
});
|
|
2803
|
+
}
|
|
2804
|
+
|
|
2805
|
+
case "move_file": {
|
|
2806
|
+
if (!args.path || !args.target_path) {
|
|
2807
|
+
return attachDescriptor({
|
|
2808
|
+
error: "path and target_path are required",
|
|
2809
|
+
});
|
|
2810
|
+
}
|
|
2811
|
+
const filePath = path.resolve(cwd, args.path);
|
|
2812
|
+
const targetPath = path.resolve(cwd, args.target_path);
|
|
2813
|
+
if (filePath === targetPath) {
|
|
2814
|
+
return attachDescriptor({
|
|
2815
|
+
error: "Source and target paths are the same",
|
|
2816
|
+
});
|
|
2817
|
+
}
|
|
2818
|
+
if (!fs.existsSync(filePath)) {
|
|
2819
|
+
return attachDescriptor({ error: `File not found: ${filePath}` });
|
|
2820
|
+
}
|
|
2821
|
+
if (fs.lstatSync(filePath).isDirectory()) {
|
|
2822
|
+
return attachDescriptor({
|
|
2823
|
+
error: `Refusing to move a directory: ${filePath}`,
|
|
2824
|
+
});
|
|
2825
|
+
}
|
|
2826
|
+
if (fs.existsSync(targetPath)) {
|
|
2827
|
+
return attachDescriptor({
|
|
2828
|
+
error: `Move target already exists: ${targetPath}`,
|
|
2829
|
+
});
|
|
2830
|
+
}
|
|
2831
|
+
const targetDir = path.dirname(targetPath);
|
|
2832
|
+
if (!fs.existsSync(targetDir) || !fs.statSync(targetDir).isDirectory()) {
|
|
2833
|
+
return attachDescriptor({
|
|
2834
|
+
error: `Move target directory not found: ${targetDir}`,
|
|
2835
|
+
});
|
|
2836
|
+
}
|
|
2837
|
+
const stale = _checkFileFreshness(filePath);
|
|
2838
|
+
if (stale) return attachDescriptor({ error: stale });
|
|
2839
|
+
fs.renameSync(filePath, targetPath);
|
|
2840
|
+
_fileObservedMtimes.delete(filePath);
|
|
2841
|
+
_recordFileObservation(targetPath);
|
|
2842
|
+
return attachDescriptor(
|
|
2843
|
+
await _withSubtreeInstructions(
|
|
2844
|
+
await _withPostEditDiagnostics(
|
|
2845
|
+
{
|
|
2846
|
+
success: true,
|
|
2847
|
+
path: filePath,
|
|
2848
|
+
targetPath,
|
|
2849
|
+
operation: "rename",
|
|
2850
|
+
},
|
|
2851
|
+
targetPath,
|
|
2852
|
+
cwd,
|
|
2853
|
+
additionalDirectories,
|
|
2854
|
+
),
|
|
2855
|
+
targetPath,
|
|
2856
|
+
cwd,
|
|
2857
|
+
),
|
|
2858
|
+
);
|
|
2859
|
+
}
|
|
2860
|
+
|
|
2602
2861
|
case "notebook_edit": {
|
|
2603
2862
|
const filePath = path.resolve(cwd, args.path);
|
|
2604
2863
|
if (!fs.existsSync(filePath)) {
|
|
@@ -2763,6 +3022,23 @@ async function executeToolInner(
|
|
|
2763
3022
|
}
|
|
2764
3023
|
|
|
2765
3024
|
case "run_shell": {
|
|
3025
|
+
if (unattendedActionPolicy?.unattended === true) {
|
|
3026
|
+
const unattendedVerdict = evaluateUnattendedShellAction(args.command, {
|
|
3027
|
+
...unattendedActionPolicy,
|
|
3028
|
+
attended: false,
|
|
3029
|
+
});
|
|
3030
|
+
if (!unattendedVerdict.allow) {
|
|
3031
|
+
return attachDescriptor({
|
|
3032
|
+
error: `[Unattended Action] ${unattendedVerdict.reason}; shell command was not run.`,
|
|
3033
|
+
unattendedAction: {
|
|
3034
|
+
actionClass: unattendedVerdict.actionClass || null,
|
|
3035
|
+
...unattendedVerdict,
|
|
3036
|
+
},
|
|
3037
|
+
policy: { decision: "deny", via: "unattended-action-policy" },
|
|
3038
|
+
});
|
|
3039
|
+
}
|
|
3040
|
+
}
|
|
3041
|
+
|
|
2766
3042
|
const shellPolicyOpts = {
|
|
2767
3043
|
...(shellPolicyOverrides
|
|
2768
3044
|
? { overrideRuleIds: shellPolicyOverrides }
|
|
@@ -2877,6 +3153,29 @@ async function executeToolInner(
|
|
|
2877
3153
|
: {}
|
|
2878
3154
|
: { shell: shellInv.kind };
|
|
2879
3155
|
|
|
3156
|
+
// PATH-based plugin binaries need explicit provenance at the Broker
|
|
3157
|
+
// boundary; otherwise a trusted plugin executable is indistinguishable
|
|
3158
|
+
// from an ambient system command in the process audit log.
|
|
3159
|
+
let pluginBinProvenance = null;
|
|
3160
|
+
try {
|
|
3161
|
+
const { resolvePluginBinCommand } = await import(
|
|
3162
|
+
"../lib/plugin-runtime/bin.js"
|
|
3163
|
+
);
|
|
3164
|
+
pluginBinProvenance = resolvePluginBinCommand(args.command, { cwd });
|
|
3165
|
+
} catch {
|
|
3166
|
+
pluginBinProvenance = null;
|
|
3167
|
+
}
|
|
3168
|
+
const processOrigin = pluginBinProvenance
|
|
3169
|
+
? "plugin:bin"
|
|
3170
|
+
: "tool:run_shell";
|
|
3171
|
+
const processProvenance = pluginBinProvenance
|
|
3172
|
+
? {
|
|
3173
|
+
pluginId: pluginBinProvenance.pluginId,
|
|
3174
|
+
pluginVersion: pluginBinProvenance.pluginVersion,
|
|
3175
|
+
pluginSource: pluginBinProvenance.pluginSource,
|
|
3176
|
+
}
|
|
3177
|
+
: {};
|
|
3178
|
+
|
|
2880
3179
|
// Background: spawn, register, return a task_id immediately. The agent
|
|
2881
3180
|
// polls output + completion via check_shell. No timeout — that's the whole
|
|
2882
3181
|
// point of backgrounding (builds, test suites, dev servers).
|
|
@@ -2936,9 +3235,16 @@ async function executeToolInner(
|
|
|
2936
3235
|
};
|
|
2937
3236
|
// PowerShell route: explicit argv (shell:false above); default route
|
|
2938
3237
|
// is the historical spawn(command, {shell:true}) byte-for-byte.
|
|
3238
|
+
const brokerOpts = {
|
|
3239
|
+
...bgSpawnOpts,
|
|
3240
|
+
origin: processOrigin,
|
|
3241
|
+
policy: "allow",
|
|
3242
|
+
scope: "agent",
|
|
3243
|
+
...processProvenance,
|
|
3244
|
+
};
|
|
2939
3245
|
const child = shellInv.useDefaultShell
|
|
2940
|
-
? spawn(args.command,
|
|
2941
|
-
: spawn(shellInv.file, shellInv.argv,
|
|
3246
|
+
? broker.spawn(args.command, [], brokerOpts)
|
|
3247
|
+
: broker.spawn(shellInv.file, shellInv.argv, brokerOpts);
|
|
2942
3248
|
task.child = child;
|
|
2943
3249
|
if (child.stdout) {
|
|
2944
3250
|
child.stdout.setEncoding("utf8");
|
|
@@ -3111,15 +3417,22 @@ async function executeToolInner(
|
|
|
3111
3417
|
}).env,
|
|
3112
3418
|
};
|
|
3113
3419
|
let output;
|
|
3420
|
+
const brokerExecOpts = {
|
|
3421
|
+
...fgExecOpts,
|
|
3422
|
+
origin: processOrigin,
|
|
3423
|
+
policy: "allow",
|
|
3424
|
+
scope: "agent",
|
|
3425
|
+
...processProvenance,
|
|
3426
|
+
};
|
|
3114
3427
|
if (shellInv.useDefaultShell) {
|
|
3115
|
-
output = execSync(args.command,
|
|
3428
|
+
output = broker.execSync(args.command, brokerExecOpts);
|
|
3116
3429
|
} else {
|
|
3117
3430
|
// PowerShell route: explicit argv, no intermediate default shell.
|
|
3118
3431
|
// Reproduce execSync's contract so the shared catch shapes errors
|
|
3119
3432
|
// identically: throw on spawn error; throw an Error carrying
|
|
3120
3433
|
// status/stdout/stderr on non-zero exit.
|
|
3121
|
-
const res = spawnSync(shellInv.file, shellInv.argv, {
|
|
3122
|
-
...
|
|
3434
|
+
const res = broker.spawnSync(shellInv.file, shellInv.argv, {
|
|
3435
|
+
...brokerExecOpts,
|
|
3123
3436
|
windowsHide: true,
|
|
3124
3437
|
});
|
|
3125
3438
|
if (res.error) throw res.error;
|
|
@@ -3351,6 +3664,7 @@ async function executeToolInner(
|
|
|
3351
3664
|
signal,
|
|
3352
3665
|
backgroundSubAgents,
|
|
3353
3666
|
subAgentUsageSink,
|
|
3667
|
+
toolAdmission,
|
|
3354
3668
|
}),
|
|
3355
3669
|
);
|
|
3356
3670
|
}
|
|
@@ -4057,6 +4371,7 @@ async function executeToolInner(
|
|
|
4057
4371
|
task: `Execute the "${args.skill_name}" skill with input: ${(args.input || "").substring(0, 200)}`,
|
|
4058
4372
|
allowedTools: ["read_file", "search_files", "list_dir"],
|
|
4059
4373
|
hookParentTraceId: hookTraceId || null,
|
|
4374
|
+
toolAdmission,
|
|
4060
4375
|
cwd,
|
|
4061
4376
|
onUsage: skillUsageSink
|
|
4062
4377
|
? (u) => {
|
|
@@ -5290,10 +5605,32 @@ async function _executeSpawnSubAgent(args, ctx) {
|
|
|
5290
5605
|
// seeded with the mode's tier gates the child's run_shell / browser_act;
|
|
5291
5606
|
// absent (ungated) for a plain default spawn = byte-identical.
|
|
5292
5607
|
...(childApprovalGate ? { approvalGate: childApprovalGate } : {}),
|
|
5608
|
+
...(ctx.toolAdmission ? { toolAdmission: ctx.toolAdmission } : {}),
|
|
5293
5609
|
});
|
|
5294
5610
|
subCtxRef = subCtx;
|
|
5295
5611
|
|
|
5296
5612
|
const emit = (type, payload) => {
|
|
5613
|
+
if (type === "sub-agent.started") {
|
|
5614
|
+
emitHooksV2Event("TaskCreated", {
|
|
5615
|
+
task_id: subCtx.id,
|
|
5616
|
+
session_id: parentSessionId,
|
|
5617
|
+
role: subCtx.role,
|
|
5618
|
+
task: subCtx.task,
|
|
5619
|
+
background: payload?.background === true,
|
|
5620
|
+
});
|
|
5621
|
+
} else if (
|
|
5622
|
+
type === "sub-agent.completed" ||
|
|
5623
|
+
type === "sub-agent.failed"
|
|
5624
|
+
) {
|
|
5625
|
+
emitHooksV2Event("TaskCompleted", {
|
|
5626
|
+
task_id: subCtx.id,
|
|
5627
|
+
session_id: parentSessionId,
|
|
5628
|
+
role: subCtx.role,
|
|
5629
|
+
status: type === "sub-agent.failed" ? "failed" : "completed",
|
|
5630
|
+
error: payload?.error || null,
|
|
5631
|
+
completed_at: payload?.completedAt || null,
|
|
5632
|
+
});
|
|
5633
|
+
}
|
|
5297
5634
|
if (!interaction || typeof interaction.emit !== "function") return;
|
|
5298
5635
|
try {
|
|
5299
5636
|
interaction.emit(type, {
|
|
@@ -6915,6 +7252,12 @@ export async function* agentLoop(messages, options) {
|
|
|
6915
7252
|
hostManagedToolPolicy: options.hostManagedToolPolicy || null,
|
|
6916
7253
|
externalToolDescriptors: options.externalToolDescriptors || null,
|
|
6917
7254
|
externalToolExecutors: options.externalToolExecutors || null,
|
|
7255
|
+
// Optional session-level Extension Tier gate. Hosts that can provide
|
|
7256
|
+
// capability/policy/permission/budget/UI signals opt in with
|
|
7257
|
+
// { enforce: true }; omitting it preserves the CLI's existing per-call
|
|
7258
|
+
// permission pipeline for backwards compatibility.
|
|
7259
|
+
toolAdmission: options.toolAdmission || null,
|
|
7260
|
+
unattendedActionPolicy: options.unattendedActionPolicy || null,
|
|
6918
7261
|
// MCP tool DEFINITIONS the LLM sees (mcp__server__tool). Threaded here so a
|
|
6919
7262
|
// spawn can inherit the parent's MCP tools into the child (filtered by the
|
|
6920
7263
|
// contract's mcpServers allow-list). Otherwise consumed only at agentLoop.
|
|
@@ -7601,17 +7944,17 @@ export async function* agentLoop(messages, options) {
|
|
|
7601
7944
|
let toolArgs;
|
|
7602
7945
|
try {
|
|
7603
7946
|
toolArgs =
|
|
7604
|
-
|
|
7605
|
-
|
|
7606
|
-
|
|
7947
|
+
typeof call.function.arguments === "string"
|
|
7948
|
+
? JSON.parse(call.function.arguments)
|
|
7949
|
+
: call.function.arguments;
|
|
7607
7950
|
} catch {
|
|
7608
7951
|
toolArgs = {};
|
|
7609
7952
|
}
|
|
7610
|
-
const promise = executeTool(
|
|
7611
|
-
|
|
7612
|
-
|
|
7613
|
-
|
|
7614
|
-
).then(
|
|
7953
|
+
const promise = executeTool(call.function.name, toolArgs, {
|
|
7954
|
+
...toolContext,
|
|
7955
|
+
toolCallId: call.id,
|
|
7956
|
+
turnId: `${runId}:t${budget.consumed}`,
|
|
7957
|
+
}).then(
|
|
7615
7958
|
(result) => ({ result, error: null }),
|
|
7616
7959
|
(err) => ({ result: { error: err.message }, error: err.message }),
|
|
7617
7960
|
);
|
|
@@ -7724,7 +8067,12 @@ export async function* agentLoop(messages, options) {
|
|
|
7724
8067
|
recorder,
|
|
7725
8068
|
"agent.tool",
|
|
7726
8069
|
{ "tool.name": toolName, ...(toolIdAttrs || {}) },
|
|
7727
|
-
() =>
|
|
8070
|
+
() =>
|
|
8071
|
+
executeTool(toolName, toolArgs, {
|
|
8072
|
+
...toolContext,
|
|
8073
|
+
toolCallId: call.id,
|
|
8074
|
+
turnId: `${runId}:t${budget.consumed}`,
|
|
8075
|
+
}),
|
|
7728
8076
|
(span, r) => {
|
|
7729
8077
|
span.setAttribute(
|
|
7730
8078
|
"tool.is_error",
|
|
@@ -7819,6 +8167,10 @@ export function formatToolArgs(name, args) {
|
|
|
7819
8167
|
return args.path;
|
|
7820
8168
|
case "edit_file_hashed":
|
|
7821
8169
|
return `${args.path} @${args.anchor_hash}`;
|
|
8170
|
+
case "delete_file":
|
|
8171
|
+
return args.path;
|
|
8172
|
+
case "move_file":
|
|
8173
|
+
return `${args.path} → ${args.target_path}`;
|
|
7822
8174
|
case "run_shell":
|
|
7823
8175
|
return args.run_in_background
|
|
7824
8176
|
? `${args.command} (background)`
|