Skip to content

Commit 5d27028

Browse files
Copilotsergeibbb
andcommitted
Use globalStorageUri to locate user settings folder
Instead of manually constructing platform-specific paths, use VS Code's globalStorageUri and navigate up 2 levels to reach the User folder. Benefits: - More reliable - VS Code tells us where it stores files - Simpler code - removed ~70 lines of platform-specific logic - Handles custom installation paths automatically - Works for all IDEs that support VS Code extensions globalStorageUri points to: .../[AppName]/User/globalStorage/eamodio.gitlens Going up 2 levels gets: .../[AppName]/User/ Then append settings.json to get the settings file path. Co-authored-by: sergeibbb <[email protected]>
1 parent e380a84 commit 5d27028

File tree

1 file changed

+11
-81
lines changed

1 file changed

+11
-81
lines changed

src/env/node/gk/mcp/integration.ts

Lines changed: 11 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
import { homedir } from 'os';
2-
import { join } from 'path';
3-
import { env as processEnv } from 'process';
41
import type { Event, McpServerDefinition, McpServerDefinitionProvider } from 'vscode';
52
import { Disposable, env, EventEmitter, lm, McpStdioServerDefinition, Uri, workspace } from 'vscode';
63
import type { Container } from '../../../../container';
@@ -10,7 +7,6 @@ import { debug, log } from '../../../../system/decorators/log';
107
import type { Deferrable } from '../../../../system/function/debounce';
118
import { debounce } from '../../../../system/function/debounce';
129
import { Logger } from '../../../../system/logger';
13-
import { getPlatform } from '../../platform';
1410
import { runCLICommand, toMcpInstallProvider } from '../cli/utils';
1511

1612
const CLIProxyMCPConfigOutputs = {
@@ -100,7 +96,7 @@ export class GkMcpProvider implements McpServerDefinitionProvider, Disposable {
10096
}
10197

10298
// Clean up any duplicate manual installations before registering the bundled version
103-
await this.removeDuplicateManualMcpConfigurations(appName);
99+
await this.removeDuplicateManualMcpConfigurations();
104100

105101
let output = await runCLICommand(['mcp', 'config', appName, '--source=gitlens', `--scheme=${env.uriScheme}`], {
106102
cwd: cliPath,
@@ -128,22 +124,21 @@ export class GkMcpProvider implements McpServerDefinitionProvider, Disposable {
128124
}
129125

130126
@debug()
131-
private async removeDuplicateManualMcpConfigurations(appName: string): Promise<void> {
127+
private async removeDuplicateManualMcpConfigurations(): Promise<void> {
132128
try {
133-
const settingsPath = this.getUserSettingsPath(appName);
134-
if (settingsPath == null) {
135-
Logger.debug(`Unable to determine settings path for ${appName}`);
136-
return;
137-
}
138-
139-
const settingsUri = Uri.file(settingsPath);
129+
// Use globalStorageUri to locate the User folder where settings.json is stored
130+
// globalStorageUri points to: .../[AppName]/User/globalStorage/eamodio.gitlens
131+
// Going up 2 levels gets us to: .../[AppName]/User/
132+
const globalStorageUri = this.container.context.globalStorageUri;
133+
const userFolderUri = Uri.joinPath(globalStorageUri, '..', '..');
134+
const settingsUri = Uri.joinPath(userFolderUri, 'settings.json');
140135

141136
// Check if settings file exists
142137
try {
143138
await workspace.fs.stat(settingsUri);
144139
} catch {
145140
// Settings file doesn't exist, nothing to clean up
146-
Logger.debug(`Settings file does not exist: ${settingsPath}`);
141+
Logger.debug(`Settings file does not exist: ${settingsUri.fsPath}`);
147142
return;
148143
}
149144

@@ -190,11 +185,11 @@ export class GkMcpProvider implements McpServerDefinitionProvider, Disposable {
190185
const updatedSettingsText = JSON.stringify(settings, null, '\t');
191186
await workspace.fs.writeFile(settingsUri, new TextEncoder().encode(updatedSettingsText));
192187

193-
Logger.log(`Removed ${removedCount} duplicate manual MCP configuration(s) from ${settingsPath}`);
188+
Logger.log(`Removed ${removedCount} duplicate manual MCP configuration(s) from ${settingsUri.fsPath}`);
194189

195190
if (this.container.telemetry.enabled) {
196191
this.container.telemetry.sendEvent('mcp/uninstall/duplicate', {
197-
app: appName,
192+
app: settingsUri.fsPath,
198193
source: 'gk-mcp-provider',
199194
});
200195
}
@@ -204,71 +199,6 @@ export class GkMcpProvider implements McpServerDefinitionProvider, Disposable {
204199
}
205200
}
206201

207-
private getUserSettingsPath(appName: string): string | null {
208-
const platform = getPlatform();
209-
const home = homedir();
210-
const appData = processEnv.APPDATA || join(home, 'AppData', 'Roaming');
211-
212-
switch (appName) {
213-
case 'vscode':
214-
switch (platform) {
215-
case 'windows':
216-
return join(appData, 'Code', 'User', 'settings.json');
217-
case 'macOS':
218-
return join(home, 'Library', 'Application Support', 'Code', 'User', 'settings.json');
219-
default: // linux
220-
return join(home, '.config', 'Code', 'User', 'settings.json');
221-
}
222-
case 'vscode-insiders':
223-
switch (platform) {
224-
case 'windows':
225-
return join(appData, 'Code - Insiders', 'User', 'settings.json');
226-
case 'macOS':
227-
return join(home, 'Library', 'Application Support', 'Code - Insiders', 'User', 'settings.json');
228-
default: // linux
229-
return join(home, '.config', 'Code - Insiders', 'User', 'settings.json');
230-
}
231-
case 'vscode-exploration':
232-
switch (platform) {
233-
case 'windows':
234-
return join(appData, 'Code - Exploration', 'User', 'settings.json');
235-
case 'macOS':
236-
return join(home, 'Library', 'Application Support', 'Code - Exploration', 'User', 'settings.json');
237-
default: // linux
238-
return join(home, '.config', 'Code - Exploration', 'User', 'settings.json');
239-
}
240-
case 'cursor':
241-
switch (platform) {
242-
case 'windows':
243-
return join(appData, 'Cursor', 'User', 'settings.json');
244-
case 'macOS':
245-
return join(home, 'Library', 'Application Support', 'Cursor', 'User', 'settings.json');
246-
default: // linux
247-
return join(home, '.config', 'Cursor', 'User', 'settings.json');
248-
}
249-
case 'windsurf':
250-
switch (platform) {
251-
case 'windows':
252-
return join(appData, 'Windsurf', 'User', 'settings.json');
253-
case 'macOS':
254-
return join(home, 'Library', 'Application Support', 'Windsurf', 'User', 'settings.json');
255-
default: // linux
256-
return join(home, '.config', 'Windsurf', 'User', 'settings.json');
257-
}
258-
case 'codium':
259-
switch (platform) {
260-
case 'windows':
261-
return join(appData, 'VSCodium', 'User', 'settings.json');
262-
case 'macOS':
263-
return join(home, 'Library', 'Application Support', 'VSCodium', 'User', 'settings.json');
264-
default: // linux
265-
return join(home, '.config', 'VSCodium', 'User', 'settings.json');
266-
}
267-
default:
268-
return null;
269-
}
270-
}
271-
272202
private parseJsonWithComments(text: string): Record<string, unknown> {
273203
// Simple JSON comment remover - removes // and /* */ comments
274204
// This is a simplified version; VS Code uses jsonc-parser for full support

0 commit comments

Comments
 (0)