mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-03-10 22:21:22 -07:00
Update enablement behavior + info (#9758)
This commit is contained in:
@@ -5,12 +5,7 @@
|
||||
*/
|
||||
|
||||
import type { CommandModule } from 'yargs';
|
||||
import {
|
||||
loadUserExtensions,
|
||||
toOutputString,
|
||||
ExtensionStorage,
|
||||
} from '../../config/extension.js';
|
||||
import { ExtensionEnablementManager } from '../../config/extensions/extensionEnablement.js';
|
||||
import { loadUserExtensions, toOutputString } from '../../config/extension.js';
|
||||
import { getErrorMessage } from '../../utils/errors.js';
|
||||
|
||||
export async function handleList() {
|
||||
@@ -20,16 +15,9 @@ export async function handleList() {
|
||||
console.log('No extensions installed.');
|
||||
return;
|
||||
}
|
||||
const manager = new ExtensionEnablementManager(
|
||||
ExtensionStorage.getUserExtensionsDir(),
|
||||
);
|
||||
const cwd = process.cwd();
|
||||
console.log(
|
||||
extensions
|
||||
.map((extension): string => {
|
||||
const isEnabled = manager.isEnabled(extension.config.name, cwd);
|
||||
return toOutputString(extension, isEnabled);
|
||||
})
|
||||
.map((extension, _): string => toOutputString(extension, process.cwd()))
|
||||
.join('\n\n'),
|
||||
);
|
||||
} catch (error) {
|
||||
|
||||
@@ -1235,6 +1235,12 @@ This extension will run the following MCP servers:
|
||||
|
||||
describe('disableExtension', () => {
|
||||
it('should disable an extension at the user scope', () => {
|
||||
createExtension({
|
||||
extensionsDir: userExtensionsDir,
|
||||
name: 'my-extension',
|
||||
version: '1.0.0',
|
||||
});
|
||||
|
||||
disableExtension('my-extension', SettingScope.User);
|
||||
expect(
|
||||
isEnabled({
|
||||
@@ -1246,6 +1252,12 @@ This extension will run the following MCP servers:
|
||||
});
|
||||
|
||||
it('should disable an extension at the workspace scope', () => {
|
||||
createExtension({
|
||||
extensionsDir: userExtensionsDir,
|
||||
name: 'my-extension',
|
||||
version: '1.0.0',
|
||||
});
|
||||
|
||||
disableExtension(
|
||||
'my-extension',
|
||||
SettingScope.Workspace,
|
||||
@@ -1268,6 +1280,12 @@ This extension will run the following MCP servers:
|
||||
});
|
||||
|
||||
it('should handle disabling the same extension twice', () => {
|
||||
createExtension({
|
||||
extensionsDir: userExtensionsDir,
|
||||
name: 'my-extension',
|
||||
version: '1.0.0',
|
||||
});
|
||||
|
||||
disableExtension('my-extension', SettingScope.User);
|
||||
disableExtension('my-extension', SettingScope.User);
|
||||
expect(
|
||||
@@ -1286,6 +1304,12 @@ This extension will run the following MCP servers:
|
||||
});
|
||||
|
||||
it('should log a disable event', () => {
|
||||
createExtension({
|
||||
extensionsDir: userExtensionsDir,
|
||||
name: 'ext1',
|
||||
version: '1.0.0',
|
||||
});
|
||||
|
||||
disableExtension('ext1', SettingScope.Workspace);
|
||||
|
||||
expect(mockLogExtensionDisable).toHaveBeenCalled();
|
||||
|
||||
@@ -260,6 +260,32 @@ export function loadExtension(context: LoadExtensionContext): Extension | null {
|
||||
}
|
||||
}
|
||||
|
||||
export function loadExtensionByName(
|
||||
name: string,
|
||||
workspaceDir: string = process.cwd(),
|
||||
): Extension | null {
|
||||
const userExtensionsDir = ExtensionStorage.getUserExtensionsDir();
|
||||
if (!fs.existsSync(userExtensionsDir)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (const subdir of fs.readdirSync(userExtensionsDir)) {
|
||||
const extensionDir = path.join(userExtensionsDir, subdir);
|
||||
if (!fs.statSync(extensionDir).isDirectory()) {
|
||||
continue;
|
||||
}
|
||||
const extension = loadExtension({ extensionDir, workspaceDir });
|
||||
if (
|
||||
extension &&
|
||||
extension.config.name.toLowerCase() === name.toLowerCase()
|
||||
) {
|
||||
return extension;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function filterMcpConfig(original: MCPServerConfig): MCPServerConfig {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const { trust, ...rest } = original;
|
||||
@@ -701,9 +727,18 @@ export async function uninstallExtension(
|
||||
|
||||
export function toOutputString(
|
||||
extension: Extension,
|
||||
isEnabled: boolean,
|
||||
workspaceDir: string,
|
||||
): string {
|
||||
const status = isEnabled ? chalk.green('✓') : chalk.red('✗');
|
||||
const manager = new ExtensionEnablementManager(
|
||||
ExtensionStorage.getUserExtensionsDir(),
|
||||
);
|
||||
const userEnabled = manager.isEnabled(extension.config.name, os.homedir());
|
||||
const workspaceEnabled = manager.isEnabled(
|
||||
extension.config.name,
|
||||
workspaceDir,
|
||||
);
|
||||
|
||||
const status = workspaceEnabled ? chalk.green('✓') : chalk.red('✗');
|
||||
let output = `${status} ${extension.config.name} (${extension.config.version})`;
|
||||
output += `\n Path: ${extension.path}`;
|
||||
if (extension.installMetadata) {
|
||||
@@ -715,6 +750,8 @@ export function toOutputString(
|
||||
output += `\n Release tag: ${extension.installMetadata.releaseTag}`;
|
||||
}
|
||||
}
|
||||
output += `\n Enabled (User): ${userEnabled}`;
|
||||
output += `\n Enabled (Workspace): ${workspaceEnabled}`;
|
||||
if (extension.contextFiles.length > 0) {
|
||||
output += `\n Context files:`;
|
||||
extension.contextFiles.forEach((contextFile) => {
|
||||
@@ -745,6 +782,10 @@ export function disableExtension(
|
||||
if (scope === SettingScope.System || scope === SettingScope.SystemDefaults) {
|
||||
throw new Error('System and SystemDefaults scopes are not supported.');
|
||||
}
|
||||
const extension = loadExtensionByName(name, cwd);
|
||||
if (!extension) {
|
||||
throw new Error(`Extension with name ${name} does not exist.`);
|
||||
}
|
||||
|
||||
const manager = new ExtensionEnablementManager(
|
||||
ExtensionStorage.getUserExtensionsDir(),
|
||||
@@ -762,6 +803,10 @@ export function enableExtension(
|
||||
if (scope === SettingScope.System || scope === SettingScope.SystemDefaults) {
|
||||
throw new Error('System and SystemDefaults scopes are not supported.');
|
||||
}
|
||||
const extension = loadExtensionByName(name, cwd);
|
||||
if (!extension) {
|
||||
throw new Error(`Extension with name ${name} does not exist.`);
|
||||
}
|
||||
const manager = new ExtensionEnablementManager(
|
||||
ExtensionStorage.getUserExtensionsDir(),
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user