Add support for sensitive keychain-stored per-extension settings (#11953)

This commit is contained in:
christine betts
2025-10-28 14:48:50 -04:00
committed by GitHub
parent 7a238bd938
commit 7e987113a2
22 changed files with 706 additions and 212 deletions
@@ -17,7 +17,7 @@ interface DisableArgs {
scope?: string;
}
export function handleDisable(args: DisableArgs) {
export async function handleDisable(args: DisableArgs) {
const workspaceDir = process.cwd();
const extensionManager = new ExtensionManager({
workspaceDir,
@@ -25,13 +25,16 @@ export function handleDisable(args: DisableArgs) {
requestSetting: promptForSetting,
settings: loadSettings(workspaceDir).merged,
});
extensionManager.loadExtensions();
await extensionManager.loadExtensions();
try {
if (args.scope?.toLowerCase() === 'workspace') {
extensionManager.disableExtension(args.name, SettingScope.Workspace);
await extensionManager.disableExtension(
args.name,
SettingScope.Workspace,
);
} else {
extensionManager.disableExtension(args.name, SettingScope.User);
await extensionManager.disableExtension(args.name, SettingScope.User);
}
debugLogger.log(
`Extension "${args.name}" successfully disabled for scope "${args.scope}".`,
@@ -20,7 +20,7 @@ interface EnableArgs {
scope?: string;
}
export function handleEnable(args: EnableArgs) {
export async function handleEnable(args: EnableArgs) {
const workingDir = process.cwd();
const extensionManager = new ExtensionManager({
workspaceDir: workingDir,
@@ -28,7 +28,7 @@ export function handleEnable(args: EnableArgs) {
requestSetting: promptForSetting,
settings: loadSettings(workingDir).merged,
});
extensionManager.loadExtensions();
await extensionManager.loadExtensions();
try {
if (args.scope?.toLowerCase() === 'workspace') {
@@ -76,7 +76,7 @@ export async function handleInstall(args: InstallArgs) {
requestSetting: promptForSetting,
settings: loadSettings(workspaceDir).merged,
});
extensionManager.loadExtensions();
await extensionManager.loadExtensions();
const name =
await extensionManager.installOrUpdateExtension(installMetadata);
debugLogger.log(`Extension "${name}" installed successfully and enabled.`);
+1 -1
View File
@@ -33,7 +33,7 @@ export async function handleLink(args: InstallArgs) {
requestSetting: promptForSetting,
settings: loadSettings(workspaceDir).merged,
});
extensionManager.loadExtensions();
await extensionManager.loadExtensions();
const extensionName =
await extensionManager.installOrUpdateExtension(installMetadata);
debugLogger.log(
+1 -1
View File
@@ -21,7 +21,7 @@ export async function handleList() {
requestSetting: promptForSetting,
settings: loadSettings(workspaceDir).merged,
});
const extensions = extensionManager.loadExtensions();
const extensions = await extensionManager.loadExtensions();
if (extensions.length === 0) {
debugLogger.log('No extensions installed.');
return;
@@ -25,7 +25,7 @@ export async function handleUninstall(args: UninstallArgs) {
requestSetting: promptForSetting,
settings: loadSettings(workspaceDir).merged,
});
extensionManager.loadExtensions();
await extensionManager.loadExtensions();
await extensionManager.uninstallExtension(args.name, false);
debugLogger.log(`Extension "${args.name}" successfully uninstalled.`);
} catch (error) {
@@ -37,7 +37,7 @@ export async function handleUpdate(args: UpdateArgs) {
settings: loadSettings(workspaceDir).merged,
});
const extensions = extensionManager.loadExtensions();
const extensions = await extensionManager.loadExtensions();
if (args.name) {
try {
const extension = extensions.find(
+1 -1
View File
@@ -33,7 +33,7 @@ async function getMcpServersFromConfig(): Promise<
requestConsent: requestConsentNonInteractive,
requestSetting: promptForSetting,
});
const extensions = extensionManager.loadExtensions();
const extensions = await extensionManager.loadExtensions();
const mcpServers = { ...(settings.merged.mcpServers || {}) };
for (const extension of extensions) {
Object.entries(extension.mcpServers || {}).forEach(([key, server]) => {