[extensions] Add extensions list command (#6879)

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
This commit is contained in:
christine betts
2025-08-25 18:27:38 +00:00
committed by GitHub
parent 4170dbdac3
commit 0641b1c095
3 changed files with 64 additions and 0 deletions

View File

@@ -7,6 +7,7 @@
import { CommandModule } from 'yargs';
import { installCommand } from './extensions/install.js';
import { uninstallCommand } from './extensions/uninstall.js';
import { listCommand } from './extensions/list.js';
export const extensionsCommand: CommandModule = {
command: 'extensions <command>',
@@ -15,6 +16,7 @@ export const extensionsCommand: CommandModule = {
yargs
.command(installCommand)
.command(uninstallCommand)
.command(listCommand)
.demandCommand(1, 'You need at least one command before continuing.')
.version(false),
handler: () => {

View File

@@ -0,0 +1,35 @@
/**
* @license
* Copyright 2025 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import { CommandModule } from 'yargs';
import { loadUserExtensions, toOutputString } from '../../config/extension.js';
export async function handleList() {
try {
const extensions = loadUserExtensions();
if (extensions.length === 0) {
console.log('No extensions installed.');
return;
}
console.log(
extensions
.map((extension, _): string => toOutputString(extension))
.join('\n\n'),
);
} catch (error) {
console.error((error as Error).message);
process.exit(1);
}
}
export const listCommand: CommandModule = {
command: 'list',
describe: 'Lists installed extensions.',
builder: (yargs) => yargs,
handler: async () => {
await handleList();
},
};

View File

@@ -354,3 +354,30 @@ export async function uninstallExtension(extensionName: string): Promise<void> {
force: true,
});
}
export function toOutputString(extension: Extension): string {
let output = `${extension.config.name} (${extension.config.version})`;
output += `\n Path: ${extension.path}`;
if (extension.installMetadata) {
output += `\n Source: ${extension.installMetadata.source}`;
}
if (extension.contextFiles.length > 0) {
output += `\n Context files:`;
extension.contextFiles.forEach((contextFile) => {
output += `\n ${contextFile}`;
});
}
if (extension.config.mcpServers) {
output += `\n MCP servers:`;
Object.keys(extension.config.mcpServers).forEach((key) => {
output += `\n ${key}`;
});
}
if (extension.config.excludeTools) {
output += `\n Excluded tools:`;
extension.config.excludeTools.forEach((tool) => {
output += `\n ${tool}`;
});
}
return output;
}