Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
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
19 changes: 17 additions & 2 deletions src/vs/platform/environment/common/environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,11 +94,26 @@ export interface IEnvironmentService {
agentSessionsWorkspace?: URI;

/**
* When running as the embedded Agents app, the user roaming data home of
* When running as the embedded app, the user roaming data home of
* the host VS Code application (i.e. the default profile's settings/User
* directory). `undefined` when not running as embedded.
*/
readonly hostUserRoamingDataHome?: URI;
readonly parentAppUserRoamingDataHome?: URI;

/**
* When running as the embedded app, the data home of the host
* VS Code application (e.g. `~/.vscode-insiders`). This identifies the
* host application's home/data directory and is used alongside other
* host-specific paths such as `hostUserRoamingDataHome` and
* `hostExtensionsHome`. `undefined` when not running as embedded.
*/
readonly parentAppUserHome?: URI;

/**
* When running as the embedded app, the extensions directory of
* the host VS Code application. `undefined` when not running as embedded.
*/
readonly parentAppExtensionsHome?: URI;

// --- Policy
policyFile?: URI;
Expand Down
32 changes: 32 additions & 0 deletions src/vs/platform/environment/common/environmentService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,20 @@ export interface INativeEnvironmentPaths {
* OS tmp dir.
*/
tmpDir: string;

/**
* The parent application user data directory, if the current instance is running as an embedded application.
* This can be used to access data from the parent application that is not shared with the embedded application.
* This is only set when running as an embedded application and is `undefined` otherwise.
*/
parentAppUserDataDir: string | undefined;

/**
* The parent application home directory, if the current instance is running as an embedded application.
* This can be used to access data from the parent application that is not shared with the embedded application.
* This is only set when running as an embedded application and is `undefined` otherwise.
*/
parentAppUserHomeDir: string | undefined;
}

export abstract class AbstractNativeEnvironmentService implements INativeEnvironmentService {
Expand Down Expand Up @@ -299,6 +313,24 @@ export abstract class AbstractNativeEnvironmentService implements INativeEnviron
this.args['continueOn'] = value;
}

@memoize
get parentAppUserRoamingDataHome(): URI | undefined {
return this.paths.parentAppUserDataDir ? URI.file(this.paths.parentAppUserDataDir).with({ scheme: Schemas.vscodeUserData }) : undefined;
}

@memoize
get parentAppUserHome(): URI | undefined {
return this.paths.parentAppUserHomeDir ? URI.file(this.paths.parentAppUserHomeDir) : undefined;
}

@memoize
get parentAppExtensionsHome(): URI | undefined {
if (!this.parentAppUserHome) {
return undefined;
}
return joinPath(this.parentAppUserHome, 'extensions');
}

get args(): NativeParsedArgs { return this._args; }

constructor(
Expand Down
90 changes: 56 additions & 34 deletions src/vs/platform/environment/node/environmentService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,53 +4,27 @@
*--------------------------------------------------------------------------------------------*/

import { homedir, tmpdir } from 'os';
import { memoize } from '../../../base/common/decorators.js';
import { INodeProcess } from '../../../base/common/platform.js';
import { joinPath } from '../../../base/common/resources.js';
import { URI } from '../../../base/common/uri.js';
import { Schemas } from '../../../base/common/network.js';
import { NativeParsedArgs } from '../common/argv.js';
import { IDebugParams } from '../common/environment.js';
import { AbstractNativeEnvironmentService, parseDebugParams } from '../common/environmentService.js';
import { getUserDataPath } from './userDataPath.js';
import { IProductService } from '../../product/common/productService.js';
import { INodeProcess } from '../../../base/common/platform.js';
import { join } from '../../../base/common/path.js';
import { env } from '../../../base/common/process.js';

export class NativeEnvironmentService extends AbstractNativeEnvironmentService {

constructor(args: NativeParsedArgs, productService: IProductService) {
const homeDir = homedir();
super(args, {
homeDir: homedir(),
homeDir,
tmpDir: tmpdir(),
userDataDir: getUserDataPath(args, productService.nameShort)
userDataDir: getUserDataPath(args, productService.nameShort),
parentAppUserDataDir: getParentAppUserDataDir(args, productService),
parentAppUserHomeDir: getParentAppUserHomeDir(homeDir, productService)
}, productService);
}

@memoize
get hostUserRoamingDataHome(): URI | undefined {
if (!(process as INodeProcess).isEmbeddedApp) {
return undefined;
}
if (!this.isBuilt) {
return undefined;
}
const quality = this.productService.quality;
let hostProductName: string;
if (quality === 'stable') {
hostProductName = 'Code';
} else if (quality === 'insider') {
hostProductName = 'Code - Insiders';
} else if (quality === 'exploration') {
hostProductName = 'Code - Exploration';
} else {
return undefined;
}

// Honor the same env-var overrides that the host VS Code itself uses
// (portable mode and VSCODE_APPDATA), but intentionally skip --user-data-dir
// because that CLI arg belongs to the Agents app, not the host.
const hostUserDataPath = getUserDataPath(this.args, hostProductName);
return joinPath(URI.file(hostUserDataPath), 'User').with({ scheme: Schemas.vscodeUserData });
}
}

export function parsePtyHostDebugPort(args: NativeParsedArgs, isBuilt: boolean): IDebugParams {
Expand All @@ -64,3 +38,51 @@ export function parseAgentHostDebugPort(args: NativeParsedArgs, isBuilt: boolean
export function parseSharedProcessDebugPort(args: NativeParsedArgs, isBuilt: boolean): IDebugParams {
return parseDebugParams(args['inspect-sharedprocess'], args['inspect-brk-sharedprocess'], 5879, isBuilt, args.extensionEnvironment);
}


function getParentAppUserDataDir(args: NativeParsedArgs, productService: IProductService): string | undefined {
if (!(process as INodeProcess).isEmbeddedApp) {
return undefined;
}
if (env['VSCODE_DEV']) {
return undefined;
}
const quality = productService.quality;
let hostProductName: string;
if (quality === 'stable') {
hostProductName = 'Code';
} else if (quality === 'insider') {
hostProductName = 'Code - Insiders';
} else if (quality === 'exploration') {
hostProductName = 'Code - Exploration';
} else {
return undefined;
}

// Honor the same env-var overrides that the host VS Code itself uses
// (portable mode and VSCODE_APPDATA), but intentionally skip --user-data-dir
// because that CLI arg belongs to the Agents app, not the host.
const hostUserDataPath = getUserDataPath(args, hostProductName);
return join(hostUserDataPath, 'User');
}

function getParentAppUserHomeDir(homeDir: string, productService: IProductService): string | undefined {
if (!(process as INodeProcess).isEmbeddedApp) {
return undefined;
}
if (env['VSCODE_DEV']) {
return undefined;
}
const quality = productService.quality;
let hostDataFolderName: string;
if (quality === 'stable') {
hostDataFolderName = '.vscode';
} else if (quality === 'insider') {
hostDataFolderName = '.vscode-insiders';
} else if (quality === 'exploration') {
hostDataFolderName = '.vscode-exploration';
} else {
return undefined;
}
return join(homeDir, hostDataFolderName);
}
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ export class StorageMainService extends Disposable implements IStorageMainServic
// from APPLICATION to APPLICATION_SHARED scope:
// In VS Code: reuse the own application storage (keys are local)
let fallbackStorage: IStorageMain = this.applicationStorage;
const hostUserRoamingDataHome = this.environmentService.hostUserRoamingDataHome;
const hostUserRoamingDataHome = this.environmentService.parentAppUserRoamingDataHome;
if (hostUserRoamingDataHome) {
// - In the Agents App: create a storage backed by the host (VS Code)
// app's application DB so keys are found even if VS Code hasn't
Expand Down
35 changes: 10 additions & 25 deletions src/vs/platform/userDataProfile/electron-main/userDataProfile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,10 @@ export class UserDataProfilesMainService extends UserDataProfilesService impleme
@INativeEnvironmentService environmentService: INativeEnvironmentService,
@IFileService fileService: IFileService,
@ILogService logService: ILogService,
@IProductService private readonly productService: IProductService,
@IProductService productService: IProductService,
) {
super(stateService, uriIdentityService, environmentService, fileService, logService);
this.agentPluginsHome = URI.file(getAgentPluginsPath(environmentService.args, environmentService.userHome, productService.dataFolderName));
this.agentPluginsHome = URI.file(getAgentPluginsPath(environmentService.args, joinPath(environmentService.userHome, productService.dataFolderName)));
}

protected override createDefaultProfile(): IUserDataProfile {
Expand All @@ -54,11 +54,11 @@ export class UserDataProfilesMainService extends UserDataProfilesService impleme
if (!(process as INodeProcess).isEmbeddedApp) {
return defaultProfile;
}
const hostUserRoamingDataHome = this.environmentService.hostUserRoamingDataHome;
const hostUserRoamingDataHome = this.environmentService.parentAppUserRoamingDataHome;
if (!hostUserRoamingDataHome) {
return defaultProfile;
}
const hostAgentPluginsHome = getHostAgentPluginsPath(this.nativeEnvironmentService, this.productService);
const hostAgentPluginsHome = getParentAppAgentPluginsPath(this.nativeEnvironmentService);
return {
...defaultProfile,
keybindingsResource: joinPath(hostUserRoamingDataHome, 'keybindings.json'),
Expand All @@ -77,30 +77,15 @@ export class UserDataProfilesMainService extends UserDataProfilesService impleme
}
}

function getHostAgentPluginsPath(environmentService: INativeEnvironmentService, productService: IProductService): string | undefined {
if (!(process as INodeProcess).isEmbeddedApp) {
function getParentAppAgentPluginsPath(environmentService: INativeEnvironmentService): string | undefined {
const hostUserHome = environmentService.parentAppUserHome;
if (!hostUserHome) {
return undefined;
}
if (!environmentService.isBuilt) {
return undefined;
}

const quality = productService.quality;
let hostDataFolderName: string;
if (quality === 'stable') {
hostDataFolderName = '.vscode';
} else if (quality === 'insider') {
hostDataFolderName = '.vscode-insiders';
} else if (quality === 'exploration') {
hostDataFolderName = '.vscode-exploration';
} else {
return undefined;
}

return getAgentPluginsPath(environmentService.args, environmentService.userHome, hostDataFolderName);
return getAgentPluginsPath(environmentService.args, hostUserHome);
}

function getAgentPluginsPath(args: NativeParsedArgs, userHome: URI, dataFolderName: string): string {
function getAgentPluginsPath(args: NativeParsedArgs, userHome: URI): string {
const cliAgentPluginsDir = args['agent-plugins-dir'];
if (cliAgentPluginsDir) {
return resolve(cliAgentPluginsDir);
Expand All @@ -116,5 +101,5 @@ function getAgentPluginsPath(args: NativeParsedArgs, userHome: URI, dataFolderNa
return join(vscodePortable, 'agent-plugins');
}

return joinPath(userHome, dataFolderName, 'agent-plugins').fsPath;
return joinPath(userHome, 'agent-plugins').fsPath;
}
2 changes: 2 additions & 0 deletions src/vs/platform/window/common/window.ts
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,8 @@ export interface INativeWindowConfiguration extends IWindowConfiguration, Native
homeDir: string;
tmpDir: string;
userDataDir: string;
parentAppUserDataDir?: string;
parentAppUserHomeDir?: string;

partsSplash?: IPartsSplash;

Expand Down
2 changes: 2 additions & 0 deletions src/vs/platform/windows/electron-main/windowsMainService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1571,6 +1571,8 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic
homeDir: this.environmentMainService.userHome.with({ scheme: Schemas.file }).fsPath,
tmpDir: this.environmentMainService.tmpDir.with({ scheme: Schemas.file }).fsPath,
userDataDir: this.environmentMainService.userDataPath,
parentAppUserDataDir: this.environmentMainService.parentAppUserRoamingDataHome?.with({ scheme: Schemas.file }).fsPath,
parentAppUserHomeDir: this.environmentMainService.parentAppUserHome?.with({ scheme: Schemas.file }).fsPath,

remoteAuthority: options.remoteAuthority,
workspace: options.workspace,
Expand Down
Loading
Loading