Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
40882e1
Enable sandboxing for terminal commands
dileepyavan Dec 1, 2025
0b15f7e
removing unused types
dileepyavan Dec 4, 2025
1084d72
code review comments update
dileepyavan Jan 6, 2026
c0b6751
main merge
dileepyavan Jan 7, 2026
b1976dc
refactored the code and added utility for sandboxing
dileepyavan Jan 10, 2026
a7ce30e
refactored the code and added utility for sandboxing
dileepyavan Jan 10, 2026
63cac43
refactored the code and added utility for sandboxing
dileepyavan Jan 10, 2026
caf2c45
fixing build error
dileepyavan Jan 12, 2026
5c21691
review suggestions
dileepyavan Jan 14, 2026
cd71156
review suggestions
dileepyavan Jan 14, 2026
762aaad
changes for retry
dileepyavan Jan 14, 2026
5147287
changes for retry
dileepyavan Jan 14, 2026
697f4f5
Update src/vs/workbench/contrib/terminalContrib/chatAgentTools/common…
dileepyavan Jan 14, 2026
353d912
Update src/vs/workbench/contrib/terminalContrib/chatAgentTools/browse…
dileepyavan Jan 14, 2026
b634138
Update src/vs/workbench/contrib/terminalContrib/chatAgentTools/common…
dileepyavan Jan 14, 2026
94f319d
Update src/vs/workbench/contrib/terminalContrib/chatAgentTools/browse…
dileepyavan Jan 14, 2026
a8b410c
Update src/vs/workbench/contrib/terminalContrib/chatAgentTools/browse…
dileepyavan Jan 14, 2026
f4e9d28
merging from main
dileepyavan Jan 15, 2026
49aeae9
updating anthropic sandbox runtime to 0.0.23
dileepyavan Jan 15, 2026
31ea4be
fixing tests for runInTerminalTool
dileepyavan Jan 15, 2026
10ce464
refactoring changes
dileepyavan Jan 15, 2026
02fec9b
review changes
dileepyavan Jan 15, 2026
22c6a80
review changes
dileepyavan Jan 15, 2026
544d616
review changes
dileepyavan Jan 15, 2026
5b01c73
review changes
dileepyavan Jan 15, 2026
dd41b1b
review changes
dileepyavan Jan 15, 2026
4742604
review changes
dileepyavan Jan 15, 2026
4adb2a6
review changes
dileepyavan Jan 16, 2026
aa3945e
update to sandboxservice
dileepyavan Jan 16, 2026
1e046d4
update to sandboxservice
dileepyavan Jan 16, 2026
e35e56f
update to sandboxservice
dileepyavan Jan 16, 2026
2ed1d8d
removing extra line
dileepyavan Jan 16, 2026
46534e1
formatting PR suggested by copilot
dileepyavan Jan 16, 2026
07dc6df
files location change suggested for review
dileepyavan Jan 16, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 76 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
"update-build-ts-version": "npm install -D typescript@next && npm install -D @typescript/native-preview && (cd build && npm run typecheck)"
},
"dependencies": {
"@anthropic-ai/sandbox-runtime": "^0.0.13",
"@microsoft/1ds-core-js": "^3.2.13",
"@microsoft/1ds-post-js": "^3.2.13",
"@types/semver": "^7.5.8",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ suite('StorageMainService', function () {
promptsHome: joinPath(inMemoryProfileRoot, 'promptsHome'),
extensionsResource: joinPath(inMemoryProfileRoot, 'extensionsResource'),
cacheHome: joinPath(inMemoryProfileRoot, 'cache'),
sandboxSettingsResource: joinPath(inMemoryProfileRoot, 'sandbox-settings.json')
};

class TestStorageMainService extends StorageMainService {
Expand Down
35 changes: 35 additions & 0 deletions src/vs/platform/terminal/common/terminal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,22 @@ import type { IAction } from '../../../base/common/actions.js';
import type { IDisposable } from '../../../base/common/lifecycle.js';
import type { SingleOrMany } from '../../../base/common/types.js';

/**
* Local type definition for sandbox runtime configuration to avoid importing external package
* in the common layer. The actual type should match @anthropic-ai/sandbox-runtime.
*/
export interface ISandboxRuntimeConfig {
network?: {
allowedDomains?: string[];
deniedDomains?: string[];
};
filesystem?: {
denyRead?: string[];
allowWrite?: string[];
denyWrite?: string[];
};
}

export const enum TerminalSettingPrefix {
AutomationProfile = 'terminal.integrated.automationProfile.',
DefaultProfile = 'terminal.integrated.defaultProfile.',
Expand Down Expand Up @@ -670,6 +686,20 @@ export interface IShellLaunchConfig {
shellIntegrationNonce?: string;
}

export interface ISandboxTerminalSettings {
enabled?: boolean;
network?: {
allowedDomains?: string[];
deniedDomains?: string[];
};
filesystem?: {
denyRead?: string[];
allowWrite?: string[];
denyWrite?: string[];
};
Copy link

Copilot AI Dec 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ISandboxTerminalSettings interface correctly uses filesystem (lowercase) which matches ISandboxRuntimeConfig. However, the schema definition in terminalChatAgentToolsConfiguration.ts uses fileSystem (camelCase) at line 75, and the default configuration at line 492 also uses fileSystem. This inconsistency means user settings will not work correctly because the property names don't match. Update the schema to use filesystem to match the TypeScript interface.

Copilot uses AI. Check for mistakes.
}


export interface ITerminalTabAction {
id: string;
label: string;
Expand Down Expand Up @@ -710,6 +740,8 @@ export interface IShellLaunchConfigDto {
isFeatureTerminal?: boolean;
tabActions?: ITerminalTabAction[];
shellIntegrationEnvironmentReporting?: boolean;
sandboxed?: boolean;
sandboxSettings?: ISandboxRuntimeConfig;
}

/**
Expand All @@ -727,6 +759,7 @@ export interface ITerminalProcessOptions {
environmentVariableCollections: ISerializableEnvironmentVariableCollections | undefined;
workspaceFolder: IWorkspaceFolder | undefined;
isScreenReaderOptimized: boolean;
sandboxSettings?: ISandboxRuntimeConfig;
}

export interface ITerminalEnvironment {
Expand Down Expand Up @@ -918,6 +951,8 @@ export interface ITerminalProfile {
overrideName?: boolean;
color?: string;
icon?: ThemeIcon | URI | { light: URI; dark: URI };
sandboxed?: boolean;
sandboxSettings?: ISandboxRuntimeConfig;
}

export interface ITerminalDimensionsOverride extends Readonly<ITerminalDimensions> {
Expand Down
45 changes: 45 additions & 0 deletions src/vs/platform/terminal/common/terminalPlatformConfiguration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,51 @@ export const terminalProfileBaseProperties: IJSONSchemaMap = {
}
};

export const terminalSandboxPropertySchema: IJSONSchemaMap = {
filesystem: {
type: 'object',
description: localize('terminalSandbox.fileSystem', "Controls file system access in the terminal sandbox."),
properties: {
allowWrite: {
type: 'array',
description: localize('terminalSandbox.fileSystem.allowedPaths', "List of allowed file system paths."),
items: { type: 'string' },
default: []
},
denyRead: {
type: 'array',
description: localize('terminalSandbox.fileSystem.deniedPaths', "List of denied file system paths."),
items: { type: 'string' },
default: []
},
denyWrite: {
type: 'array',
description: localize('terminalSandbox.fileSystem.deniedWritePaths', "List of denied file system write paths."),
items: { type: 'string' },
default: []
}
}
},
network: {
type: 'object',
description: localize('terminalSandbox.network', "Controls network access in the terminal sandbox."),
properties: {
allowedDomains: {
type: 'array',
description: localize('terminalSandbox.network.allowedHosts', "List of allowed network hosts."),
items: { type: 'string' },
default: []
},
deniedDomains: {
type: 'array',
description: localize('terminalSandbox.network.deniedDomains', "List of denied network domains."),
items: { type: 'string' },
default: []
}
}
}
};

const terminalProfileSchema: IJSONSchema = {
type: 'object',
required: ['path'],
Expand Down
1 change: 1 addition & 0 deletions src/vs/platform/userData/common/fileUserDataProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ export class FileUserDataProvider extends Disposable implements
this.atomicReadWriteResources.add(profile.keybindingsResource);
this.atomicReadWriteResources.add(profile.tasksResource);
this.atomicReadWriteResources.add(profile.extensionsResource);
this.atomicReadWriteResources.add(profile.sandboxSettingsResource);
}
}

Expand Down
3 changes: 3 additions & 0 deletions src/vs/platform/userDataProfile/common/userDataProfile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ export interface IUserDataProfile {
readonly useDefaultFlags?: UseDefaultProfileFlags;
readonly isTransient?: boolean;
readonly workspaces?: readonly URI[];
readonly sandboxSettingsResource: URI;
}

export function isUserDataProfile(thing: unknown): thing is IUserDataProfile {
Expand Down Expand Up @@ -145,6 +146,7 @@ export function reviveProfile(profile: UriDto<IUserDataProfile>, scheme: string)
useDefaultFlags: profile.useDefaultFlags,
isTransient: profile.isTransient,
workspaces: profile.workspaces?.map(w => URI.revive(w)),
sandboxSettingsResource: URI.revive(profile.sandboxSettingsResource).with({ scheme })
};
}

Expand All @@ -167,6 +169,7 @@ export function toUserDataProfile(id: string, name: string, location: URI, profi
useDefaultFlags: options?.useDefaultFlags,
isTransient: options?.transient,
workspaces: options?.workspaces,
sandboxSettingsResource: joinPath(location, 'sandbox-settings.json')
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ import { removeAnsiEscapeCodes } from '../../../../../../../base/common/strings.
import { PANEL_BACKGROUND } from '../../../../../../common/theme.js';
import { editorBackground } from '../../../../../../../platform/theme/common/colorRegistry.js';
import { IThemeService } from '../../../../../../../platform/theme/common/themeService.js';
import { ISandboxUtility } from '../../../../common/sandboxUtility.js';


const MIN_OUTPUT_ROWS = 1;
const MAX_OUTPUT_ROWS = 10;
Expand Down Expand Up @@ -242,6 +244,7 @@ export class ChatTerminalToolProgressPart extends BaseChatToolInvocationSubPart
@IContextKeyService private readonly _contextKeyService: IContextKeyService,
@IChatWidgetService private readonly _chatWidgetService: IChatWidgetService,
@IKeybindingService private readonly _keybindingService: IKeybindingService,
@ISandboxUtility private readonly _sandboxUtility: ISandboxUtility,
) {
super(toolInvocation);

Expand Down Expand Up @@ -453,7 +456,7 @@ export class ChatTerminalToolProgressPart extends BaseChatToolInvocationSubPart
showOutputAction = this._instantiationService.createInstance(ToggleChatTerminalOutputAction, () => this._toggleOutputFromAction());
this._showOutputAction.value = showOutputAction;
const exitCode = resolvedCommand?.exitCode ?? this._terminalData.terminalCommandState?.exitCode;
if (exitCode) {
if (exitCode && !this._sandboxUtility.isEnabled()) {
this._toggleOutput(true);
}
}
Expand Down
Loading