chainlesschain 0.162.181 → 0.162.183
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -1
- package/scripts/build-windows-sandbox-helper.ps1 +163 -0
- package/src/assets/web-panel/assets/{AIOps-cq0dwbnf.js → AIOps-BapS7lz4.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-CvcgGl3w.js → ActionButton-CXYdXEUI.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-hM2-jFqg.js → Analytics-CKR5Lexn.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-B9_Gsd_g.js → AppLayout-DATVUOXB.js} +5 -5
- package/src/assets/web-panel/assets/{Artifacts-B7bu52Og.js → Artifacts-vb_0ZlV1.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-DThfDgqB.js → Audit-BI1l9GWt.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-DjlFiD4v.js → BackgroundAgents-BFXbaUEf.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-CK9xJKnG.js → Backup-DEYBJJ6H.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-DEiSU8K8.js → BaseInput-COdzeO0M.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-CpT96czj.js → Chat-oSN6sfM5.js} +6 -6
- package/src/assets/web-panel/assets/ChatBubbleRenderer-CI_jT0ru.js +1 -0
- package/src/assets/web-panel/assets/{Checkbox-C1GfDnO0.js → Checkbox-BezEa4tm.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-3DAKgiLx.js → Codegen-CNEL0Ife.js} +1 -1
- package/src/assets/web-panel/assets/{Col-74cOwZU1.js → Col-Bf2Y2Bn1.js} +1 -1
- package/src/assets/web-panel/assets/{Community-tn9Kkz9j.js → Community-BfUlu4Hc.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-BcoXH7m4.js → Compact-BN4xWP9e.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-DIPGUBgi.js → Compliance-Bt6BKmEP.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-doD5_91c.js → Cowork-DKLp8YxO.js} +2 -2
- package/src/assets/web-panel/assets/{Cron-C-IDvubz.js → Cron-o7Hhw6ky.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-CdcCoBdj.js → Crosschain-DaNXWJIw.js} +1 -1
- package/src/assets/web-panel/assets/{DID-DdH5aMMA.js → DID-B-Qa2mha.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-DHLA4mm0.js → Dashboard-CMX0Qnxw.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-dEeCt7Md.js → Dropdown-BLuLyRu_.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-BMaecFv9.js → EmailListRenderer-CFBAeMij.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-DUaUukTN.js → FamilyGuardDashboard-DWzXQ67V.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-CMBE0_rp.js → Federation-DB1QSLgr.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-PG-JDbXq.js → FormItemContext-C-OKCToP.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-Bcb0p88m.js → GenericCardRenderer-DMJFtFZf.js} +1 -1
- package/src/assets/web-panel/assets/{Git-Bgv15myB.js → Git-DsGSujOV.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-DB8YTArI.js → Governance-B0iS9NEW.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-BQMwCWaS.js → Inference-CH004H7c.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-B1_ZziiB.js → KnowledgeGraph-Q9MTQ83c.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-DovEEnt_.js → Logs-B_fyjZK9.js} +2 -2
- package/src/assets/web-panel/assets/{MarkdownRenderer-D201OL4T.js → MarkdownRenderer-C0o4FtpD.js} +1 -1
- package/src/assets/web-panel/assets/{Marketplace-BlCXSpyB.js → Marketplace-BIStF9d1.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-CsCR09Wj.js → McpTools-pGfal768.js} +5 -5
- package/src/assets/web-panel/assets/{Memory-CBVRLKno.js → Memory-xbNqpIqB.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-C9OIafgA.js → MobileBridge-B5EQGrIK.js} +1 -1
- package/src/assets/web-panel/assets/MobileProjects-VTc3gT1y.js +1 -0
- package/src/assets/web-panel/assets/{Mtc-vE-HdvLj.js → Mtc-a_rmfxJH.js} +4 -4
- package/src/assets/web-panel/assets/{MtcAudit-CPLaekCd.js → MtcAudit-BmKuofUr.js} +4 -4
- package/src/assets/web-panel/assets/{Multisig-C_UP9C2o.js → Multisig-BQbJ-CAN.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-2nODJcU1.js → NLProgramming-JtPJKX25.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-BhE-SJGu.js → Notes-ZFKznTSG.js} +3 -3
- package/src/assets/web-panel/assets/{NotificationSettings-D21q7BNU.js → NotificationSettings-B6aHRBBR.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-0b62GYOD.js → OrderTableRenderer-DdcsOqEz.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-CEqmw_sb.js → Organization-BFDTAUgS.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-MW-gMDO_.js → Overflow-0FoTfbWH.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-CY0hjI_G.js → P2P-CWd90etw.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-BbWh7Man.js → PdhVaultBrowser-DtCGC-W-.js} +3 -3
- package/src/assets/web-panel/assets/{Permissions-ChqEA_4Q.js → Permissions-CvQ7nr7T.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-B3YrbYfD.js → PersonalDataHub-rdNPcR-Z.js} +5 -5
- package/src/assets/web-panel/assets/{Pipeline-B8WBhhlW.js → Pipeline-CmrfiNOs.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-Cmb0PXNx.js → Privacy-D7ep1h_t.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-hF6zW3Nz.js → ProjectInit-C0xKINHS.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-BFSVfpW0.js → ProjectSettings-AOmZFp-F.js} +2 -2
- package/src/assets/web-panel/assets/Projects-BWHSkXZP.js +1 -0
- package/src/assets/web-panel/assets/{Providers-B8yux8Dx.js → Providers-Cb7JCTPL.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-N76cQluO.js → QrScannerModal-BDMehcXC.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-ClvZ0KYR.js → QuickAsk-BF6_1nvx.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-B-GfgBpT.js → Recommend-BHfT-A28.js} +1 -1
- package/src/assets/web-panel/assets/RemoteSession-B6EEf8hh.js +5 -0
- package/src/assets/web-panel/assets/{Reputation-DJIZzQeG.js → Reputation-CsWHLEcj.js} +1 -1
- package/src/assets/web-panel/assets/{Row-COzxu_bb.js → Row-D6srnWhm.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-CoYsJQuE.js → RssFeed-Xhr-KyVd.js} +3 -3
- package/src/assets/web-panel/assets/{Search-DC77Mq9S.js → Search-vIbIJvwL.js} +1 -1
- package/src/assets/web-panel/assets/{Security-Loy2EdMO.js → Security-Bzi5Aiko.js} +4 -4
- package/src/assets/web-panel/assets/{Services-GUD07Eu0.js → Services-BHtVX52P.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-DWzkptYU.js → Skeleton-C0R8B2jf.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-CEDn1r-Z.js → Skills-DtT6rWOX.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-ub_k4pXh.js → Sla-0B37mxVU.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-D7HLX9CA.js → SpeechSettings-0V2jE1Bs.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-DbwOvl6m.js → SyncSettings-CYedRzaj.js} +2 -2
- package/src/assets/web-panel/assets/Tasks-D-R1x8vm.js +1 -0
- package/src/assets/web-panel/assets/{Templates-BNVeIhud.js → Templates-BKoHztGT.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-PS9AzhXU.js → Tenant--17nwVNZ.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-Cgb4eLB_.js → Terminal-Dnkos7vW.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-CrmXMOkg.js → TimelineRenderer-C5jx4AE3.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-DD-VDHw1.js → Tokens-DYJKYa9t.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-BsoN_n-n.js → Trigger-DChpWiQ9.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-n8LmN4ZV.js → Trust-DfWG52EA.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-C9_7MImA.js → UkeySign-CMugYcyA.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-DyBteNgn.js → VideoEditing-BOSmrHAd.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-BS5ixeXI.js → Wallet-D5g3k3Sa.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-spc4UImU.js → WebAuthn-D-7u4Mkc.js} +3 -3
- package/src/assets/web-panel/assets/{WorkflowEditor-D7iVvaBO.js → WorkflowEditor-CFzZMSUJ.js} +1 -1
- package/src/assets/web-panel/assets/{chat-6CmBkHrL.js → chat-VbR6l6mc.js} +1 -1
- package/src/assets/web-panel/assets/{colors-BGoCLkxI.js → colors-BSZn8EDS.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-fYZBetMO.js → compact-item-y74obMEq.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-BeM-1UVj.js → createContext-C326bjex.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-D3Bho_6u.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-CE7ZuEnV.js → hasIn-D_INJQT_.js} +1 -1
- package/src/assets/web-panel/assets/{index-ukg99D1V.js → index-4PIeTM--.js} +1 -1
- package/src/assets/web-panel/assets/{index-B2U-ObMq.js → index-4eyH-eC2.js} +1 -1
- package/src/assets/web-panel/assets/index-5iAFwYx1.js +1 -0
- package/src/assets/web-panel/assets/{index-CRLjEP1H.js → index-9PIVuXqo.js} +1 -1
- package/src/assets/web-panel/assets/{index-BfPL-m46.js → index-B7SrC-On.js} +1 -1
- package/src/assets/web-panel/assets/{index--lap6cf7.js → index-BJi3UqBt.js} +1 -1
- package/src/assets/web-panel/assets/{index-B3CDgvNW.js → index-BY8-nCgs.js} +1 -1
- package/src/assets/web-panel/assets/index-BfnB7LPx.js +1 -0
- package/src/assets/web-panel/assets/{index-De0quFDw.js → index-Bfw2hf2s.js} +1 -1
- package/src/assets/web-panel/assets/{index-BunaQCa0.js → index-BjcWKg1S.js} +1 -1
- package/src/assets/web-panel/assets/{index-BsMfoaeo.js → index-BnSfnSMP.js} +1 -1
- package/src/assets/web-panel/assets/{index-C0v6YKKO.js → index-Bnua8IX3.js} +1 -1
- package/src/assets/web-panel/assets/{index-C4SJVjs4.js → index-C-ZCaUJc.js} +1 -1
- package/src/assets/web-panel/assets/{index-BNZDILcO.js → index-C2NyllnW.js} +1 -1
- package/src/assets/web-panel/assets/{index-YjcumOZ4.js → index-C327pLbw.js} +1 -1
- package/src/assets/web-panel/assets/{index-CRnUE8Cb.js → index-CMHqs3Jb.js} +1 -1
- package/src/assets/web-panel/assets/{index-CIpVrf5P.js → index-CfLJ42kv.js} +1 -1
- package/src/assets/web-panel/assets/{index-BEVm0lCS.js → index-Cr3uuz0C.js} +3 -3
- package/src/assets/web-panel/assets/{index-Dw1PyYPm.js → index-CsovTpx9.js} +1 -1
- package/src/assets/web-panel/assets/{index-lJBjB1QX.js → index-CzE53HiB.js} +1 -1
- package/src/assets/web-panel/assets/{index-CpIGIB85.js → index-DBkzrpiL.js} +1 -1
- package/src/assets/web-panel/assets/{index-DoXk5KJ8.js → index-DNMxIsDg.js} +1 -1
- package/src/assets/web-panel/assets/{index-DsvfrESp.js → index-DUU2606o.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cip8emOQ.js → index-DdyjrCAu.js} +1 -1
- package/src/assets/web-panel/assets/{index-ATcSr_2O.js → index-DkH1JvEt.js} +1 -1
- package/src/assets/web-panel/assets/{index-BV551878.js → index-Dlxh9D8D.js} +1 -1
- package/src/assets/web-panel/assets/{index-BU_2qiDk.js → index-DuIkfnTF.js} +1 -1
- package/src/assets/web-panel/assets/{index-zb7rVOhV.js → index-DwHSZLXg.js} +1 -1
- package/src/assets/web-panel/assets/{index-MtOuq2i6.js → index-E_v1ZCTP.js} +1 -1
- package/src/assets/web-panel/assets/{index-B8BsdNV_.js → index-FQBsuExX.js} +1 -1
- package/src/assets/web-panel/assets/{index-WUrJ6S1j.js → index-GA80ir_u.js} +1 -1
- package/src/assets/web-panel/assets/{index-RMZ8a7Yt.js → index-IZAWt0H8.js} +1 -1
- package/src/assets/web-panel/assets/{index-D1r9tT3J.js → index-Iw0FfqUz.js} +1 -1
- package/src/assets/web-panel/assets/{index-BowH1eLQ.js → index-KF9Zmqln.js} +1 -1
- package/src/assets/web-panel/assets/{index-Puq6Luf1.js → index-abmn_8Yz.js} +1 -1
- package/src/assets/web-panel/assets/{index-QIpnpZgz.js → index-gINyI1rh.js} +1 -1
- package/src/assets/web-panel/assets/{index-C9Y3k0HI.js → index-jYaogFE8.js} +1 -1
- package/src/assets/web-panel/assets/{index-B4wiTEOM.js → index-nSn2-C4N.js} +1 -1
- package/src/assets/web-panel/assets/{index-DT3zPSVX.js → index-qMA4GYdQ.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-CYHMs1ag.js → initDefaultProps-DI0Zaf8-.js} +1 -1
- package/src/assets/web-panel/assets/{motion-DDB2Ffk5.js → motion-BZDKSy3Z.js} +1 -1
- package/src/assets/web-panel/assets/{move-Bg3cD-dX.js → move-DsIW01Vp.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-B5nedjTS.js → mtc-parser-CohkDhsf.js} +1 -1
- package/src/assets/web-panel/assets/{omit-BHyuUILu.js → omit-DpiN5rzg.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-C9YQnEN9.js → pickAttrs-qbuqni3y.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-DBUFYUe7.js → placementArrow-mBky6714.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-nBs2Obnk.js → responsiveObserve-Bas3eQ2K.js} +1 -1
- package/src/assets/web-panel/assets/{slide-DkCEaXNU.js → slide-CBx_SKoK.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-aqE1Wi6U.js → statusUtils-BlYguJSV.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-CN5bhfHB.js → styleChecker-BCYQmRGv.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-B_oX_kvJ.js → useFlexGapSupport-Dp5dybLM.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-rCuXHeme.js → useFs-DHAMBgA2.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-DZR9Abyd.js → usePersonalDataHub-W6jsSw76.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-ConCYQlX.js → vnode-BkI6aayc.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-CUdDxG5M.js → zoom-C_IMGueq.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/commands/agenda.js +115 -3
- package/src/commands/agent.js +15 -0
- package/src/commands/background-session.js +49 -0
- package/src/commands/plugin.js +235 -23
- package/src/commands/session.js +13 -0
- package/src/data/changelog.json +26 -0
- package/src/gateways/terminal/PtyManager.js +45 -4
- package/src/gateways/ws/ws-server.js +10 -1
- package/src/harness/background-task-manager.js +70 -2
- package/src/harness/jsonl-session-store.js +6 -4
- package/src/harness/worktree-isolator.js +14 -3
- package/src/lib/agent-core.js +1 -0
- package/src/lib/agent-schedule-store.js +45 -22
- package/src/lib/agent-team/team-runner.js +19 -1
- package/src/lib/background-agent-supervisor.js +49 -0
- package/src/lib/hook-runner.js +6 -2
- package/src/lib/packer/pkg-config-generator.js +3 -1
- package/src/lib/plugin-runtime/bin.js +1148 -70
- package/src/lib/plugin-runtime/install.js +226 -7
- package/src/lib/plugin-runtime/manifest.js +68 -12
- package/src/lib/plugin-runtime/scopes.js +33 -12
- package/src/lib/plugin-usage-attribution.js +44 -0
- package/src/lib/process-execution-broker/index.js +626 -48
- package/src/lib/process-execution-broker/platform-sandbox.js +4971 -266
- 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 +3856 -0
- package/src/lib/repl-bang-memorize.js +67 -10
- package/src/lib/session-usage.js +77 -0
- package/src/lib/slash-commands.js +27 -4
- package/src/repl/agent-repl.js +10 -9
- package/src/runtime/agent-core.js +376 -52
- package/src/runtime/agent-runtime.js +13 -1
- package/src/runtime/headless-runner.js +13 -4
- package/src/runtime/headless-stream.js +20 -1
- package/src/runtime/mcp-config.js +15 -5
- package/src/assets/web-panel/assets/ChatBubbleRenderer-BKPPNmZI.js +0 -1
- package/src/assets/web-panel/assets/MobileProjects-D_zoJ8Xs.js +0 -1
- package/src/assets/web-panel/assets/Projects-DAWkVFkc.js +0 -1
- package/src/assets/web-panel/assets/RemoteSession-mlglCdQi.js +0 -5
- package/src/assets/web-panel/assets/Tasks-CBQzoAu5.js +0 -1
- package/src/assets/web-panel/assets/devWarning-BzPwHnw8.js +0 -1
- package/src/assets/web-panel/assets/index-DacrAdc-.js +0 -1
- package/src/assets/web-panel/assets/index-EHzNJozo.js +0 -1
- package/src/lib/process-execution-broker/windows-sandbox.ps1 +0 -999
|
@@ -21,6 +21,7 @@ import fsDefault from "fs";
|
|
|
21
21
|
import pathDefault from "path";
|
|
22
22
|
import { findProjectRoot } from "./project-instructions.js";
|
|
23
23
|
import executionBroker from "./process-execution-broker/index.js";
|
|
24
|
+
import { collectPluginBinSandboxPolicy as collectDefaultPluginBinSandboxPolicy } from "./plugin-runtime/bin.js";
|
|
24
25
|
|
|
25
26
|
export const BANG_TIMEOUT_MS = 120_000;
|
|
26
27
|
export const BANG_MAX_BUFFER = 10 * 1024 * 1024;
|
|
@@ -33,6 +34,8 @@ export const MEMO_NOTE_MAX = 4_000;
|
|
|
33
34
|
|
|
34
35
|
export const _deps = {
|
|
35
36
|
spawnSync: (...args) => executionBroker.spawnSync(...args),
|
|
37
|
+
collectPluginBinSandboxPolicy: (opts) =>
|
|
38
|
+
collectDefaultPluginBinSandboxPolicy(opts),
|
|
36
39
|
fs: fsDefault,
|
|
37
40
|
path: pathDefault,
|
|
38
41
|
};
|
|
@@ -44,6 +47,46 @@ function cap(s) {
|
|
|
44
47
|
: str;
|
|
45
48
|
}
|
|
46
49
|
|
|
50
|
+
function resolveWindowsCommandShell(opts = {}) {
|
|
51
|
+
const path = opts.deps?.path || _deps.path;
|
|
52
|
+
const env = opts.env || process.env;
|
|
53
|
+
const normalizeLocalPath = (candidate) => {
|
|
54
|
+
const value =
|
|
55
|
+
typeof candidate === "string"
|
|
56
|
+
? candidate.trim()
|
|
57
|
+
: String(candidate || "");
|
|
58
|
+
// `path.win32.isAbsolute("\\foo")` is true even though the result still
|
|
59
|
+
// depends on the process's current drive. Require a drive-qualified local
|
|
60
|
+
// path so the helper receives one deterministic executable identity.
|
|
61
|
+
if (!/^[a-z]:[\\/]/i.test(value)) return null;
|
|
62
|
+
return path.win32.normalize(value);
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
for (const candidate of [opts.comSpec, env.ComSpec, env.COMSPEC]) {
|
|
66
|
+
const value = normalizeLocalPath(candidate);
|
|
67
|
+
if (value && path.win32.basename(value).toLowerCase() === "cmd.exe") {
|
|
68
|
+
return value;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
for (const candidate of [
|
|
73
|
+
opts.systemRoot,
|
|
74
|
+
env.SystemRoot,
|
|
75
|
+
env.SYSTEMROOT,
|
|
76
|
+
env.WINDIR,
|
|
77
|
+
"C:\\Windows",
|
|
78
|
+
]) {
|
|
79
|
+
const value = normalizeLocalPath(candidate);
|
|
80
|
+
if (value) {
|
|
81
|
+
return path.win32.join(value, "System32", "cmd.exe");
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// The literal fallback above is absolute, so this is unreachable with Node's
|
|
86
|
+
// path.win32 implementation. Keep a fail-closed guard for injected path seams.
|
|
87
|
+
throw new Error("No absolute Windows command shell is available");
|
|
88
|
+
}
|
|
89
|
+
|
|
47
90
|
/** True when the REPL line is a `!` bash passthrough. */
|
|
48
91
|
export function isBangCommand(trimmed) {
|
|
49
92
|
return (
|
|
@@ -70,24 +113,37 @@ export function isMemorizeLine(trimmed) {
|
|
|
70
113
|
*/
|
|
71
114
|
export function runBangCommand(line, opts = {}) {
|
|
72
115
|
const spawnSync = opts.deps?.spawnSync || _deps.spawnSync;
|
|
116
|
+
const collectPluginBinSandboxPolicy =
|
|
117
|
+
opts.deps?.collectPluginBinSandboxPolicy ||
|
|
118
|
+
_deps.collectPluginBinSandboxPolicy;
|
|
73
119
|
const cwd = opts.cwd || process.cwd();
|
|
74
120
|
const isWin =
|
|
75
121
|
opts.platform != null
|
|
76
122
|
? opts.platform === "win32"
|
|
77
123
|
: process.platform === "win32";
|
|
78
124
|
const cmd = String(line).replace(/^!/, "").trim();
|
|
125
|
+
// A bang command is another arbitrary workspace process surface. Collect the
|
|
126
|
+
// tighten-only Plugin bin boundary union before the shell starts so it cannot
|
|
127
|
+
// bypass a policy that run_shell already pins for the same workspace.
|
|
128
|
+
const sandboxPolicy = collectPluginBinSandboxPolicy({ cwd });
|
|
129
|
+
const sandboxOptions = sandboxPolicy ? { sandboxPolicy } : {};
|
|
79
130
|
|
|
80
131
|
const res = isWin
|
|
81
|
-
? spawnSync(
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
132
|
+
? spawnSync(
|
|
133
|
+
resolveWindowsCommandShell(opts),
|
|
134
|
+
["/d", "/s", "/c", `chcp 65001 >nul && ${cmd}`],
|
|
135
|
+
{
|
|
136
|
+
encoding: "utf-8",
|
|
137
|
+
timeout: BANG_TIMEOUT_MS,
|
|
138
|
+
maxBuffer: BANG_MAX_BUFFER,
|
|
139
|
+
cwd,
|
|
140
|
+
origin: "repl:bang-command",
|
|
141
|
+
policy: "allow",
|
|
142
|
+
scope: "repl",
|
|
143
|
+
shell: false,
|
|
144
|
+
...sandboxOptions,
|
|
145
|
+
},
|
|
146
|
+
)
|
|
91
147
|
: spawnSync("/bin/sh", ["-c", cmd], {
|
|
92
148
|
encoding: "utf-8",
|
|
93
149
|
timeout: BANG_TIMEOUT_MS,
|
|
@@ -97,6 +153,7 @@ export function runBangCommand(line, opts = {}) {
|
|
|
97
153
|
policy: "allow",
|
|
98
154
|
scope: "repl",
|
|
99
155
|
shell: false,
|
|
156
|
+
...sandboxOptions,
|
|
100
157
|
});
|
|
101
158
|
|
|
102
159
|
const exitCode = res.status == null ? (res.error ? -1 : 0) : res.status;
|
package/src/lib/session-usage.js
CHANGED
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
readEvents,
|
|
13
13
|
listJsonlSessions,
|
|
14
14
|
} from "../harness/jsonl-session-store.js";
|
|
15
|
+
import { extractPluginUsageAttribution } from "./plugin-usage-attribution.js";
|
|
15
16
|
|
|
16
17
|
// Injectable disk seams (tests override). readEvents skips malformed JSON lines
|
|
17
18
|
// but does NOT guard readFileSync, so an unreadable session file (EACCES /
|
|
@@ -228,6 +229,7 @@ function _isToolResultError(event) {
|
|
|
228
229
|
export function aggregateToolCalls(events) {
|
|
229
230
|
const byTool = new Map();
|
|
230
231
|
const byServer = new Map();
|
|
232
|
+
const byPlugin = new Map();
|
|
231
233
|
let totalCalls = 0;
|
|
232
234
|
let totalErrors = 0;
|
|
233
235
|
|
|
@@ -253,19 +255,42 @@ export function aggregateToolCalls(events) {
|
|
|
253
255
|
}
|
|
254
256
|
return s;
|
|
255
257
|
};
|
|
258
|
+
const bumpPlugin = (plugin, version = null) => {
|
|
259
|
+
const key = `${plugin}@${version || "?"}`;
|
|
260
|
+
let row = byPlugin.get(key);
|
|
261
|
+
if (!row) {
|
|
262
|
+
row = {
|
|
263
|
+
plugin,
|
|
264
|
+
version: version || null,
|
|
265
|
+
calls: 0,
|
|
266
|
+
errors: 0,
|
|
267
|
+
turnTokens: 0,
|
|
268
|
+
};
|
|
269
|
+
byPlugin.set(key, row);
|
|
270
|
+
}
|
|
271
|
+
return row;
|
|
272
|
+
};
|
|
256
273
|
|
|
257
274
|
let turnTools = new Set();
|
|
258
275
|
let turnServers = new Set();
|
|
276
|
+
let turnPlugins = new Set();
|
|
259
277
|
let turnTokens = 0;
|
|
278
|
+
let pendingPlugin = null;
|
|
260
279
|
const flushTurn = () => {
|
|
261
280
|
if (turnTokens > 0) {
|
|
262
281
|
for (const name of turnTools) bumpTool(name).turnTokens += turnTokens;
|
|
263
282
|
for (const server of turnServers)
|
|
264
283
|
bumpServer(server).turnTokens += turnTokens;
|
|
284
|
+
for (const key of turnPlugins) {
|
|
285
|
+
const row = byPlugin.get(key);
|
|
286
|
+
if (row) row.turnTokens += turnTokens;
|
|
287
|
+
}
|
|
265
288
|
}
|
|
266
289
|
turnTools = new Set();
|
|
267
290
|
turnServers = new Set();
|
|
291
|
+
turnPlugins = new Set();
|
|
268
292
|
turnTokens = 0;
|
|
293
|
+
pendingPlugin = null;
|
|
269
294
|
};
|
|
270
295
|
|
|
271
296
|
for (const evt of events || []) {
|
|
@@ -292,6 +317,21 @@ export function aggregateToolCalls(events) {
|
|
|
292
317
|
if (isErr) s.errors++;
|
|
293
318
|
turnServers.add(server);
|
|
294
319
|
}
|
|
320
|
+
const plugin =
|
|
321
|
+
typeof evt.data?.plugin === "string" && evt.data.plugin
|
|
322
|
+
? evt.data.plugin
|
|
323
|
+
: null;
|
|
324
|
+
const pluginVersion =
|
|
325
|
+
typeof evt.data?.plugin_version === "string"
|
|
326
|
+
? evt.data.plugin_version
|
|
327
|
+
: null;
|
|
328
|
+
pendingPlugin = { tool: name, plugin, version: pluginVersion };
|
|
329
|
+
if (plugin) {
|
|
330
|
+
const p = bumpPlugin(plugin, pluginVersion);
|
|
331
|
+
p.calls++;
|
|
332
|
+
if (isErr) p.errors++;
|
|
333
|
+
turnPlugins.add(`${plugin}@${pluginVersion || "?"}`);
|
|
334
|
+
}
|
|
295
335
|
continue;
|
|
296
336
|
}
|
|
297
337
|
if (evt.type === "tool_result") {
|
|
@@ -304,6 +344,26 @@ export function aggregateToolCalls(events) {
|
|
|
304
344
|
bumpTool(name).errors++;
|
|
305
345
|
if (server) bumpServer(server).errors++;
|
|
306
346
|
}
|
|
347
|
+
const extracted = extractPluginUsageAttribution(evt.data?.result);
|
|
348
|
+
const plugin =
|
|
349
|
+
typeof evt.data?.plugin === "string" && evt.data.plugin
|
|
350
|
+
? evt.data.plugin
|
|
351
|
+
: extracted.plugin || null;
|
|
352
|
+
const pluginVersion =
|
|
353
|
+
typeof evt.data?.plugin_version === "string"
|
|
354
|
+
? evt.data.plugin_version
|
|
355
|
+
: extracted.pluginVersion || null;
|
|
356
|
+
if (plugin) {
|
|
357
|
+
const p = bumpPlugin(plugin, pluginVersion);
|
|
358
|
+
const countedByCall =
|
|
359
|
+
pendingPlugin?.tool === name &&
|
|
360
|
+
pendingPlugin?.plugin === plugin &&
|
|
361
|
+
(pendingPlugin?.version || null) === (pluginVersion || null);
|
|
362
|
+
if (!countedByCall) p.calls++;
|
|
363
|
+
if (_isToolResultError(evt) && !countedByCall) p.errors++;
|
|
364
|
+
turnPlugins.add(`${plugin}@${pluginVersion || "?"}`);
|
|
365
|
+
}
|
|
366
|
+
pendingPlugin = null;
|
|
307
367
|
continue;
|
|
308
368
|
}
|
|
309
369
|
const u = extractUsage(evt);
|
|
@@ -317,6 +377,7 @@ export function aggregateToolCalls(events) {
|
|
|
317
377
|
totalErrors,
|
|
318
378
|
byTool: Array.from(byTool.values()).sort(byCallsDesc),
|
|
319
379
|
byMcpServer: Array.from(byServer.values()).sort(byCallsDesc),
|
|
380
|
+
byPlugin: Array.from(byPlugin.values()).sort(byCallsDesc),
|
|
320
381
|
};
|
|
321
382
|
}
|
|
322
383
|
|
|
@@ -457,6 +518,7 @@ export function allSessionsUsage({ limit = 1000 } = {}) {
|
|
|
457
518
|
const gSubagent = new Map();
|
|
458
519
|
const gTool = new Map();
|
|
459
520
|
const gServer = new Map();
|
|
521
|
+
const gPlugin = new Map();
|
|
460
522
|
let gToolCalls = 0;
|
|
461
523
|
let gToolErrors = 0;
|
|
462
524
|
const mergeRow = (map, key, row, seed) => {
|
|
@@ -508,6 +570,20 @@ export function allSessionsUsage({ limit = 1000 } = {}) {
|
|
|
508
570
|
entry.turnTokens += row.turnTokens || 0;
|
|
509
571
|
gServer.set(row.server, entry);
|
|
510
572
|
}
|
|
573
|
+
for (const row of tools.byPlugin || []) {
|
|
574
|
+
const key = `${row.plugin}@${row.version || "?"}`;
|
|
575
|
+
const entry = gPlugin.get(key) || {
|
|
576
|
+
plugin: row.plugin,
|
|
577
|
+
version: row.version || null,
|
|
578
|
+
calls: 0,
|
|
579
|
+
errors: 0,
|
|
580
|
+
turnTokens: 0,
|
|
581
|
+
};
|
|
582
|
+
entry.calls += row.calls || 0;
|
|
583
|
+
entry.errors += row.errors || 0;
|
|
584
|
+
entry.turnTokens += row.turnTokens || 0;
|
|
585
|
+
gPlugin.set(key, entry);
|
|
586
|
+
}
|
|
511
587
|
}
|
|
512
588
|
const byCallsDesc = (a, b) => b.calls - a.calls;
|
|
513
589
|
|
|
@@ -527,6 +603,7 @@ export function allSessionsUsage({ limit = 1000 } = {}) {
|
|
|
527
603
|
totalErrors: gToolErrors,
|
|
528
604
|
byTool: Array.from(gTool.values()).sort(byCallsDesc),
|
|
529
605
|
byMcpServer: Array.from(gServer.values()).sort(byCallsDesc),
|
|
606
|
+
byPlugin: Array.from(gPlugin.values()).sort(byCallsDesc),
|
|
530
607
|
},
|
|
531
608
|
},
|
|
532
609
|
};
|
|
@@ -24,11 +24,14 @@ import { homedir } from "node:os";
|
|
|
24
24
|
import { expandFileRefs } from "../runtime/file-ref-expander.js";
|
|
25
25
|
import { projectRootBase } from "./project-root.cjs";
|
|
26
26
|
import executionBroker from "./process-execution-broker/index.js";
|
|
27
|
+
import { collectPluginBinSandboxPolicy as collectDefaultPluginBinSandboxPolicy } from "./plugin-runtime/bin.js";
|
|
27
28
|
|
|
28
29
|
const _deps = {
|
|
29
30
|
fs: fsDefault,
|
|
30
31
|
path: pathDefault,
|
|
31
32
|
execSync: (...args) => executionBroker.execSync(...args),
|
|
33
|
+
collectPluginBinSandboxPolicy: (opts) =>
|
|
34
|
+
collectDefaultPluginBinSandboxPolicy(opts),
|
|
32
35
|
};
|
|
33
36
|
|
|
34
37
|
/**
|
|
@@ -186,8 +189,16 @@ export function substituteArgs(text, args = []) {
|
|
|
186
189
|
return out;
|
|
187
190
|
}
|
|
188
191
|
|
|
192
|
+
function isSandboxFailClosedError(error) {
|
|
193
|
+
return (
|
|
194
|
+
error?.sandboxFailClosed === true ||
|
|
195
|
+
(typeof error?.code === "string" &&
|
|
196
|
+
error.code.startsWith("ERR_PROCESS_SANDBOX"))
|
|
197
|
+
);
|
|
198
|
+
}
|
|
199
|
+
|
|
189
200
|
/** Run every `!`cmd`` and replace it with the command's stdout (best-effort). */
|
|
190
|
-
function runBangs(text, { cwd, execSync }) {
|
|
201
|
+
function runBangs(text, { cwd, execSync, sandboxPolicy }) {
|
|
191
202
|
return text.replace(/!`([^`]+)`/g, (_, cmd) => {
|
|
192
203
|
try {
|
|
193
204
|
const out = execSync(cmd, {
|
|
@@ -199,9 +210,13 @@ function runBangs(text, { cwd, execSync }) {
|
|
|
199
210
|
policy: "allow",
|
|
200
211
|
scope: "slash-command",
|
|
201
212
|
shell: true,
|
|
213
|
+
...(sandboxPolicy ? { sandboxPolicy } : {}),
|
|
202
214
|
});
|
|
203
215
|
return String(out).trim();
|
|
204
216
|
} catch (err) {
|
|
217
|
+
// Broker boundary failures are security decisions, not ordinary command
|
|
218
|
+
// failures. Preserve the exact structured error for the caller.
|
|
219
|
+
if (isSandboxFailClosedError(err)) throw err;
|
|
205
220
|
return `[command failed: ${cmd} — ${err.message?.split("\n")[0] || err}]`;
|
|
206
221
|
}
|
|
207
222
|
});
|
|
@@ -215,18 +230,26 @@ function runBangs(text, { cwd, execSync }) {
|
|
|
215
230
|
*
|
|
216
231
|
* @param {object} command output of getCommand/parseCommandFile (needs .body)
|
|
217
232
|
* @param {string[]} args
|
|
218
|
-
* @param {object} [opts] { cwd, allowBang,
|
|
233
|
+
* @param {object} [opts] { cwd, allowBang,
|
|
234
|
+
* deps:{ execSync, collectPluginBinSandboxPolicy } }
|
|
219
235
|
* @returns {{ prompt:string, warnings:string[] }}
|
|
220
236
|
*/
|
|
221
237
|
export function expandCommand(command, args = [], opts = {}) {
|
|
222
238
|
const cwd = opts.cwd || process.cwd();
|
|
223
239
|
const execSync = opts.deps?.execSync || _deps.execSync;
|
|
240
|
+
const collectPluginBinSandboxPolicy =
|
|
241
|
+
opts.deps?.collectPluginBinSandboxPolicy ||
|
|
242
|
+
_deps.collectPluginBinSandboxPolicy;
|
|
224
243
|
const warnings = [];
|
|
225
244
|
|
|
226
245
|
let text = substituteArgs(command.body || "", args);
|
|
227
246
|
|
|
228
|
-
if (opts.allowBang !== false) {
|
|
229
|
-
|
|
247
|
+
if (opts.allowBang !== false && /!`[^`]+`/.test(text)) {
|
|
248
|
+
// Resolve and pin once before the first bang. Every expansion in this macro
|
|
249
|
+
// receives the same immutable policy object, so no earlier command can run
|
|
250
|
+
// before a later discovery failure or observe a weaker boundary set.
|
|
251
|
+
const sandboxPolicy = collectPluginBinSandboxPolicy({ cwd });
|
|
252
|
+
text = runBangs(text, { cwd, execSync, sandboxPolicy });
|
|
230
253
|
}
|
|
231
254
|
|
|
232
255
|
// @file expansion appends a <referenced-files> block when anything resolves.
|
package/src/repl/agent-repl.js
CHANGED
|
@@ -108,6 +108,7 @@ import {
|
|
|
108
108
|
import { resolveSlashMacro } from "./slash-macro.js";
|
|
109
109
|
import { expandMcpPrompt, renderMcpSurface } from "./mcp-prompt.js";
|
|
110
110
|
import { newCostStore, addUsage } from "./session-cost.js";
|
|
111
|
+
import { extractPluginUsageAttribution } from "../lib/plugin-usage-attribution.js";
|
|
111
112
|
import { parseThinkCommand, parseEffortCommand } from "./think-command.js";
|
|
112
113
|
import { parseBtwCommand, buildAsideBlock, applyAside } from "./btw-command.js";
|
|
113
114
|
import { shouldStreamLive } from "./stream-decision.js";
|
|
@@ -360,9 +361,9 @@ export async function agentLoop(messages, options) {
|
|
|
360
361
|
);
|
|
361
362
|
} else if (event.type === "tool-result") {
|
|
362
363
|
// 用量归因: persist a compact tool_call record (name + error flag +
|
|
363
|
-
// skill
|
|
364
|
-
// `cc session usage --by tool|mcp` and `cc insights` can
|
|
365
|
-
// tool use for REPL sessions. Best-effort; opt out with
|
|
364
|
+
// skill/plugin hints — never args, which can carry whole file bodies)
|
|
365
|
+
// so `cc session usage --by tool|mcp|plugin` and `cc insights` can
|
|
366
|
+
// aggregate tool use for REPL sessions. Best-effort; opt out with
|
|
366
367
|
// options.persistToolCalls === false.
|
|
367
368
|
if (options.sessionId && options.persistToolCalls !== false) {
|
|
368
369
|
try {
|
|
@@ -373,6 +374,7 @@ export async function agentLoop(messages, options) {
|
|
|
373
374
|
event.tool === "run_skill" && _lastExec?.tool === "run_skill"
|
|
374
375
|
? _lastExec.args?.skill_name
|
|
375
376
|
: undefined,
|
|
377
|
+
...extractPluginUsageAttribution(event.result),
|
|
376
378
|
});
|
|
377
379
|
} catch (_e) {
|
|
378
380
|
// persistence is best-effort — never break the turn
|
|
@@ -915,8 +917,9 @@ export async function startAgentRepl(options = {}) {
|
|
|
915
917
|
_pluginMonitors = null;
|
|
916
918
|
}
|
|
917
919
|
|
|
918
|
-
//
|
|
919
|
-
// restored at SessionEnd.
|
|
920
|
+
// Preserve PATH compatibility for trusted legacy bin components without a
|
|
921
|
+
// sandboxPolicy, restored at SessionEnd. Policy-bearing bins stay off PATH
|
|
922
|
+
// and use agent-core's exact direct Broker route.
|
|
920
923
|
try {
|
|
921
924
|
const { applyPluginBinPath } = await import("../lib/plugin-runtime/bin.js");
|
|
922
925
|
const res = applyPluginBinPath({ cwd: process.cwd() });
|
|
@@ -1843,9 +1846,7 @@ export async function startAgentRepl(options = {}) {
|
|
|
1843
1846
|
" Open this secure page? [y/N] ",
|
|
1844
1847
|
),
|
|
1845
1848
|
async (answer) => {
|
|
1846
|
-
const approved = /^(y|yes)$/i.test(
|
|
1847
|
-
String(answer || "").trim(),
|
|
1848
|
-
);
|
|
1849
|
+
const approved = /^(y|yes)$/i.test(String(answer || "").trim());
|
|
1849
1850
|
if (!approved) {
|
|
1850
1851
|
resolve({ action: "decline" });
|
|
1851
1852
|
rl.prompt();
|
|
@@ -3876,7 +3877,7 @@ export async function startAgentRepl(options = {}) {
|
|
|
3876
3877
|
/* monitor restart is best-effort */
|
|
3877
3878
|
}
|
|
3878
3879
|
|
|
3879
|
-
// Re-apply plugin bin PATH
|
|
3880
|
+
// Re-apply legacy plugin bin PATH; strict bins remain direct-only.
|
|
3880
3881
|
try {
|
|
3881
3882
|
const { applyPluginBinPath } =
|
|
3882
3883
|
await import("../lib/plugin-runtime/bin.js");
|