diff --git a/packages/cli/src/acp/commandHandler.test.ts b/packages/cli/src/acp/commandHandler.test.ts index 8e04f014f3..23bf907ec3 100644 --- a/packages/cli/src/acp/commandHandler.test.ts +++ b/packages/cli/src/acp/commandHandler.test.ts @@ -26,5 +26,8 @@ describe('CommandHandler', () => { const init = parse('/init'); expect(init.commandToExecute?.name).toBe('init'); + + const about = parse('/about'); + expect(about.commandToExecute?.name).toBe('about'); }); }); diff --git a/packages/cli/src/acp/commandHandler.ts b/packages/cli/src/acp/commandHandler.ts index 836cdf7736..4ed846188e 100644 --- a/packages/cli/src/acp/commandHandler.ts +++ b/packages/cli/src/acp/commandHandler.ts @@ -10,6 +10,7 @@ import { MemoryCommand } from './commands/memory.js'; import { ExtensionsCommand } from './commands/extensions.js'; import { InitCommand } from './commands/init.js'; import { RestoreCommand } from './commands/restore.js'; +import { AboutCommand } from './commands/about.js'; export class CommandHandler { private registry: CommandRegistry; @@ -24,6 +25,7 @@ export class CommandHandler { registry.register(new ExtensionsCommand()); registry.register(new InitCommand()); registry.register(new RestoreCommand()); + registry.register(new AboutCommand()); return registry; } diff --git a/packages/cli/src/acp/commands/about.ts b/packages/cli/src/acp/commands/about.ts new file mode 100644 index 0000000000..06349e88d7 --- /dev/null +++ b/packages/cli/src/acp/commands/about.ts @@ -0,0 +1,74 @@ +/** + * @license + * Copyright 2026 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import { + IdeClient, + UserAccountManager, + getVersion, +} from '@google/gemini-cli-core'; +import type { + Command, + CommandContext, + CommandExecutionResponse, +} from './types.js'; +import process from 'node:process'; + +export class AboutCommand implements Command { + readonly name = 'about'; + readonly description = 'Show version and environment info'; + + async execute( + context: CommandContext, + _args: string[] = [], + ): Promise { + const osVersion = process.platform; + let sandboxEnv = 'no sandbox'; + if (process.env['SANDBOX'] && process.env['SANDBOX'] !== 'sandbox-exec') { + sandboxEnv = process.env['SANDBOX']; + } else if (process.env['SANDBOX'] === 'sandbox-exec') { + sandboxEnv = `sandbox-exec (${ + process.env['SEATBELT_PROFILE'] || 'unknown' + })`; + } + const modelVersion = context.agentContext.config.getModel() || 'Unknown'; + const cliVersion = await getVersion(); + const selectedAuthType = + context.settings.merged?.security?.auth?.selectedType ?? ''; + const gcpProject = process.env['GOOGLE_CLOUD_PROJECT'] || ''; + const ideClient = await getIdeClientName(context); + + const userAccountManager = new UserAccountManager(); + const cachedAccount = userAccountManager.getCachedGoogleAccount(); + const userEmail = cachedAccount ?? 'Unknown'; + + const tier = context.agentContext.config.getUserTierName() || 'Unknown'; + + const info = [ + `- Version: ${cliVersion}`, + `- OS: ${osVersion}`, + `- Sandbox: ${sandboxEnv}`, + `- Model: ${modelVersion}`, + `- Auth Type: ${selectedAuthType}`, + `- GCP Project: ${gcpProject}`, + `- IDE Client: ${ideClient}`, + `- User Email: ${userEmail}`, + `- Tier: ${tier}`, + ].join('\n'); + + return { + name: this.name, + data: `Gemini CLI Info:\n${info}`, + }; + } +} + +async function getIdeClientName(context: CommandContext) { + if (!context.agentContext.config.getIdeMode()) { + return ''; + } + const ideClient = await IdeClient.getInstance(); + return ideClient?.getDetectedIdeDisplayName() ?? ''; +}