src/vs/platform/agentHost/node/copilot/agentHostSandboxEngine.ts

142 LOC · 131 covered · 11 uncovered · 25 ranges · 966 concepts · 4 introducers · 453 tests

File neighbourhood

The centred file is linked to every concept that introduces one of its ranges, every test that runs code from the file, and the gray connector concepts standing between those tests and the file's own introducer concepts. Undirected links join concepts to every file where they introduce source and concepts to the tests they introduce; arrows show specialization between the displayed concepts and bridge only concepts omitted from this view. Concept colors match the source ranges below; connector concepts have no source color and are shown in gray.

Focused file, its introducer and connector concepts, their introduced files, and tests that run code from the file

In the embedded map, ordinary wheel input scrolls the page; use the visible controls to zoom and drag to pan. Open the full-screen map for canvas navigation: wheel pans, Ctrl/Command plus wheel zooms, and arrow keys pan when this region is focused. On touch screens, open the full-screen map to pan or pinch. If JavaScript or WebGL is unavailable, use the related-file, concept, and source links on this page.

Graph controls are ready.

Interactive rendering requires JavaScript and WebGL. Use the related-file, concept, and source links on this page while the interactive map is unavailable.

1 > /*--------------------------------------------------------------------------------------------- copilotShellTools.ts ×23
2 > * Copyright (c) Microsoft Corporation. All rights reserved.
3 > * Licensed under the MIT License. See License.txt in the project root for license information.
4 > *--------------------------------------------------------------------------------------------*/
5 >
6 > import { Event } from '../../../../base/common/event.js';
7 > import { FileAccess } from '../../../../base/common/network.js';
8 > import { dirname } from '../../../../base/common/path.js';
9 > import { OS, OperatingSystem } from '../../../../base/common/platform.js';
10 > import { URI } from '../../../../base/common/uri.js';
11 > import { createHash } from 'crypto';
12 > import { IEnvironmentService, INativeEnvironmentService } from '../../../environment/common/environment.js';
13 > import { IInstantiationService } from '../../../instantiation/common/instantiation.js';
14 > import { IProductService } from '../../../product/common/productService.js';
15 > import { ISandboxHelperService, type ISandboxDependencyStatus, type IWindowsMxcPolicyContainment, type IWindowsMxcSandboxPolicy } from '../../../sandbox/common/sandboxHelperService.js';
16 > import { ITerminalSandboxEngineHost, ITerminalSandboxRuntimeInfo, TerminalSandboxEngine } from '../../../sandbox/common/terminalSandboxEngine.js';
17 > import { IAgentConfigurationService } from '../agentConfigurationService.js';
18 > import { getAppNodeModulesDirName } from '../appNodeModules.js';
19 > import { AgentHostSandboxConfigKey, sandboxConfigSchema, sandboxSettingIdToAgentHostKey } from '../../common/sandboxConfigSchema.js';
20 >
21 > /** Subdirectory under the user home + product data folder where the engine creates its temp dir. */
22 > const SANDBOX_TEMP_DIR_NAME = 'tmp';
23 >
24 > /**
25 > * Host adapter that bridges agent-host environment data into the shared
26 > * {@link TerminalSandboxEngine}. One instance per session, wired up via
27 > * {@link createAgentHostSandboxEngine}.
28 > */
29 > class AgentHostTerminalSandboxHost implements ITerminalSandboxEngineHost {
30 > readonly onDidChangeRoots = Event.None;
31 > readonly onDidChangeSandboxSettings: Event<void>;
32 > private readonly _sandboxHelper: ISandboxHelperService;
33 >
34 > constructor(
35 > private readonly _sessionId: string, agentHostSandboxEngine.ts ×2
36 > private readonly _workingDirectory: URI | undefined,
37 > private readonly _environmentService: INativeEnvironmentService,
38 > private readonly _productService: IProductService,
39 > private readonly _agentConfigurationService: IAgentConfigurationService,
40 > sandboxHelper: ISandboxHelperService,
41 > ) {
42 > this._sandboxHelper = sandboxHelper;
43 > this.onDidChangeSandboxSettings = this._agentConfigurationService.onDidRootConfigChange;
44 > }
46 > async getOS(): Promise<OperatingSystem> {
47 > return OS; copilotShellTools.ts ×11
48 > }
50 > async getRuntimeInfo(): Promise<ITerminalSandboxRuntimeInfo> {
51 > const appRoot = dirname(FileAccess.asFileUri('').path); agentHostSandboxEngine.ts ×7
52 > const runAsNode = !!process.versions['electron'];
53 > // In the desktop app the native binaries (ripgrep-universal, mxc-sdk) are
54 > // unpacked from the ASAR archive into `node_modules.asar.unpacked`; in dev
55 > // and on the server (which has no ASAR) they remain in a plain
56 > // `node_modules`.
57 > const nativeModulesDir = getAppNodeModulesDirName();
58 > return { appRoot, execPath: process.execPath, runAsNode, nativeModulesDir };
59 > }
61 > async getUserHome(): Promise<URI | undefined> {
62 > return this._environmentService.userHome; agentHostSandboxEngine.ts ×7
63 > }
65 > async getSandboxTempDir(): Promise<URI | undefined> {
66 > const userHome = this._environmentService.userHome; agentHostSandboxEngine.ts ×7
67 > if (!userHome) {
68 return undefined;
69 }
70 > const sandboxRoot = URI.joinPath(userHome, this._productService.dataFolderName, SANDBOX_TEMP_DIR_NAME); agentHostSandboxEngine.ts ×7
71 > // Keep the per-session leaf short and bounded: the sandbox runtime
72 > // creates its network-bridge UNIX sockets (e.g. `claude-socks-<id>.sock`,
73 > // ~35 bytes) directly under this directory, and the full socket path must
74 > // stay within the AF_UNIX 108-byte limit. The raw session id is a URI
75 > // segment (often a UUID), so hash it to a short hex string instead. A
76 > // 64-bit SHA-256 prefix (16 hex chars) keeps the leaf short and
77 > // collisions infeasible.
78 > const digest = createHash('sha256').update(this._sessionId).digest('hex');
79 > const sessionLeaf = `agenthost_${digest.substring(0, 16)}`;
80 > return URI.joinPath(sandboxRoot, sessionLeaf);
81 > }
83 > async getWorkspaceStorageReadRoot(): Promise<URI | undefined> {
84 > // The agent host has no workspace-storage equivalent today. agentHostSandboxEngine.ts ×7
85 > return undefined;
86 > }
88 > getWriteRoots(): readonly URI[] {
89 > return this._workingDirectory ? [this._workingDirectory] : []; agentHostSandboxEngine.ts ×7
90 > }
92 > async checkSandboxDependencies(): Promise<ISandboxDependencyStatus | undefined> {
93 return this._sandboxHelper.checkSandboxDependencies();
94 }
96 > async getWindowsMxcFilesystemPolicy() {
97 return this._sandboxHelper.getWindowsMxcFilesystemPolicy();
98 }
100 > async getWindowsMxcEnvironment() {
101 return this._sandboxHelper.getWindowsMxcEnvironment();
102 }
104 > async buildWindowsMxcSandboxPayload(commandLine: string, policy: IWindowsMxcSandboxPolicy, workingDirectory?: string, containerName?: string, containment?: IWindowsMxcPolicyContainment) {
105 return this._sandboxHelper.buildWindowsMxcSandboxPayload(commandLine, policy, workingDirectory, containerName, containment);
106 }
108 > getSandboxSetting<T>(settingId: string): T | undefined {
109 > // The agent host stores sandbox settings nested under a single copilotShellTools.ts ×11
110 > // top-level `sandbox` object with prefix-free sub-keys (e.g.
111 > // `sandbox.enabled` rather than `chat.agent.sandbox.enabled`). Map
112 > // from the engine's modern setting ID into that sub-key namespace;
113 > // unknown IDs (which include all deprecated keys — handled host-side
114 > // by the workbench client) resolve to undefined.
115 > const innerKey = sandboxSettingIdToAgentHostKey[settingId];
116 > if (innerKey === undefined) {
117 > return undefined; agentHostSandboxEngine.ts ×7
118 > }
119 > const sandbox = this._agentConfigurationService.getRootValue(sandboxConfigSchema, AgentHostSandboxConfigKey.Sandbox); copilotShellTools.ts ×11
120 > return sandbox?.[innerKey] as T | undefined;
121 > }
123 >
124 > /**
125 > * Construct a per-session {@link TerminalSandboxEngine} for the agent host.
126 > * The returned engine is registered with the caller's instantiation service
127 > * but the caller is responsible for disposing it (typically by registering it
128 > * alongside the per-session {@link ShellManager}).
129 > */
130 > export function createAgentHostSandboxEngine(
131 > instantiationService: IInstantiationService, agentHostSandboxEngine.ts ×2
132 > environmentService: IEnvironmentService,
133 > productService: IProductService,
134 > agentConfigurationService: IAgentConfigurationService,
135 > sandboxHelper: ISandboxHelperService,
136 > sessionId: string,
137 > workingDirectory: URI | undefined,
138 > ): TerminalSandboxEngine {
139 > const host = new AgentHostTerminalSandboxHost(sessionId, workingDirectory, environmentService as INativeEnvironmentService, productService, agentConfigurationService, sandboxHelper);
140 > return instantiationService.createInstance(TerminalSandboxEngine, host);
141 > }
142