diff --git a/packages/cli/index.ts b/packages/cli/index.ts index e247b09590..8f9a066327 100644 --- a/packages/cli/index.ts +++ b/packages/cli/index.ts @@ -8,7 +8,7 @@ import './src/gemini.js'; import { main } from './src/gemini.js'; -import { FatalError } from '@google/gemini-cli-core'; +import { debugLogger, FatalError } from '@google/gemini-cli-core'; // --- Global Entry Point --- main().catch((error) => { @@ -17,14 +17,14 @@ main().catch((error) => { if (!process.env['NO_COLOR']) { errorMessage = `\x1b[31m${errorMessage}\x1b[0m`; } - console.error(errorMessage); + debugLogger.error(errorMessage); process.exit(error.exitCode); } - console.error('An unexpected critical error occurred:'); + debugLogger.error('An unexpected critical error occurred:'); if (error instanceof Error) { - console.error(error.stack); + debugLogger.error(error.stack); } else { - console.error(String(error)); + debugLogger.error(String(error)); } process.exit(1); }); diff --git a/packages/cli/src/commands/extensions/disable.ts b/packages/cli/src/commands/extensions/disable.ts index 0a88ce08f2..b79691c0d0 100644 --- a/packages/cli/src/commands/extensions/disable.ts +++ b/packages/cli/src/commands/extensions/disable.ts @@ -8,6 +8,7 @@ import { type CommandModule } from 'yargs'; import { disableExtension } from '../../config/extension.js'; import { SettingScope } from '../../config/settings.js'; import { getErrorMessage } from '../../utils/errors.js'; +import { debugLogger } from '@google/gemini-cli-core'; interface DisableArgs { name: string; @@ -21,11 +22,11 @@ export function handleDisable(args: DisableArgs) { } else { disableExtension(args.name, SettingScope.User); } - console.log( + debugLogger.log( `Extension "${args.name}" successfully disabled for scope "${args.scope}".`, ); } catch (error) { - console.error(getErrorMessage(error)); + debugLogger.error(getErrorMessage(error)); process.exit(1); } } diff --git a/packages/cli/src/commands/extensions/install.ts b/packages/cli/src/commands/extensions/install.ts index e9f0c59be2..fbe953c11f 100644 --- a/packages/cli/src/commands/extensions/install.ts +++ b/packages/cli/src/commands/extensions/install.ts @@ -10,7 +10,10 @@ import { installOrUpdateExtension, requestConsentNonInteractive, } from '../../config/extension.js'; -import type { ExtensionInstallMetadata } from '@google/gemini-cli-core'; +import { + debugLogger, + type ExtensionInstallMetadata, +} from '@google/gemini-cli-core'; import { getErrorMessage } from '../../utils/errors.js'; import { stat } from 'node:fs/promises'; @@ -60,16 +63,16 @@ export async function handleInstall(args: InstallArgs) { ? () => Promise.resolve(true) : requestConsentNonInteractive; if (args.consent) { - console.log('You have consented to the following:'); - console.log(INSTALL_WARNING_MESSAGE); + debugLogger.log('You have consented to the following:'); + debugLogger.log(INSTALL_WARNING_MESSAGE); } const name = await installOrUpdateExtension( installMetadata, requestConsent, ); - console.log(`Extension "${name}" installed successfully and enabled.`); + debugLogger.log(`Extension "${name}" installed successfully and enabled.`); } catch (error) { - console.error(getErrorMessage(error)); + debugLogger.error(getErrorMessage(error)); process.exit(1); } } diff --git a/packages/cli/src/commands/extensions/link.ts b/packages/cli/src/commands/extensions/link.ts index fad958a6bf..6bbfcebd7e 100644 --- a/packages/cli/src/commands/extensions/link.ts +++ b/packages/cli/src/commands/extensions/link.ts @@ -9,7 +9,10 @@ import { installOrUpdateExtension, requestConsentNonInteractive, } from '../../config/extension.js'; -import type { ExtensionInstallMetadata } from '@google/gemini-cli-core'; +import { + debugLogger, + type ExtensionInstallMetadata, +} from '@google/gemini-cli-core'; import { getErrorMessage } from '../../utils/errors.js'; @@ -27,11 +30,11 @@ export async function handleLink(args: InstallArgs) { installMetadata, requestConsentNonInteractive, ); - console.log( + debugLogger.log( `Extension "${extensionName}" linked successfully and enabled.`, ); } catch (error) { - console.error(getErrorMessage(error)); + debugLogger.error(getErrorMessage(error)); process.exit(1); } } diff --git a/packages/cli/src/commands/extensions/list.ts b/packages/cli/src/commands/extensions/list.ts index acfe758890..532d6b7233 100644 --- a/packages/cli/src/commands/extensions/list.ts +++ b/packages/cli/src/commands/extensions/list.ts @@ -8,6 +8,7 @@ import type { CommandModule } from 'yargs'; import { loadExtensions, toOutputString } from '../../config/extension.js'; import { getErrorMessage } from '../../utils/errors.js'; import { ExtensionEnablementManager } from '../../config/extensions/extensionEnablement.js'; +import { debugLogger } from '@google/gemini-cli-core'; export async function handleList() { try { @@ -16,16 +17,16 @@ export async function handleList() { process.cwd(), ); if (extensions.length === 0) { - console.log('No extensions installed.'); + debugLogger.log('No extensions installed.'); return; } - console.log( + debugLogger.log( extensions .map((extension, _): string => toOutputString(extension, process.cwd())) .join('\n\n'), ); } catch (error) { - console.error(getErrorMessage(error)); + debugLogger.error(getErrorMessage(error)); process.exit(1); } } diff --git a/packages/cli/src/commands/extensions/new.ts b/packages/cli/src/commands/extensions/new.ts index c6455496d2..5bd6a12d6d 100644 --- a/packages/cli/src/commands/extensions/new.ts +++ b/packages/cli/src/commands/extensions/new.ts @@ -8,7 +8,7 @@ import { access, cp, mkdir, readdir, writeFile } from 'node:fs/promises'; import { join, dirname, basename } from 'node:path'; import type { CommandModule } from 'yargs'; import { fileURLToPath } from 'node:url'; -import { getErrorMessage } from '../../utils/errors.js'; +import { debugLogger } from '@google/gemini-cli-core'; interface NewArgs { path: string; @@ -49,32 +49,27 @@ async function copyDirectory(template: string, path: string) { } async function handleNew(args: NewArgs) { - try { - if (args.template) { - await copyDirectory(args.template, args.path); - console.log( - `Successfully created new extension from template "${args.template}" at ${args.path}.`, - ); - } else { - await createDirectory(args.path); - const extensionName = basename(args.path); - const manifest = { - name: extensionName, - version: '1.0.0', - }; - await writeFile( - join(args.path, 'gemini-extension.json'), - JSON.stringify(manifest, null, 2), - ); - console.log(`Successfully created new extension at ${args.path}.`); - } - console.log( - `You can install this using "gemini extensions link ${args.path}" to test it out.`, + if (args.template) { + await copyDirectory(args.template, args.path); + debugLogger.log( + `Successfully created new extension from template "${args.template}" at ${args.path}.`, ); - } catch (error) { - console.error(getErrorMessage(error)); - throw error; + } else { + await createDirectory(args.path); + const extensionName = basename(args.path); + const manifest = { + name: extensionName, + version: '1.0.0', + }; + await writeFile( + join(args.path, 'gemini-extension.json'), + JSON.stringify(manifest, null, 2), + ); + debugLogger.log(`Successfully created new extension at ${args.path}.`); } + debugLogger.log( + `You can install this using "gemini extensions link ${args.path}" to test it out.`, + ); } async function getBoilerplateChoices() { diff --git a/packages/cli/src/commands/extensions/uninstall.ts b/packages/cli/src/commands/extensions/uninstall.ts index 615698e193..82717f0f00 100644 --- a/packages/cli/src/commands/extensions/uninstall.ts +++ b/packages/cli/src/commands/extensions/uninstall.ts @@ -7,6 +7,7 @@ import type { CommandModule } from 'yargs'; import { uninstallExtension } from '../../config/extension.js'; import { getErrorMessage } from '../../utils/errors.js'; +import { debugLogger } from '@google/gemini-cli-core'; interface UninstallArgs { name: string; // can be extension name or source URL. @@ -15,9 +16,9 @@ interface UninstallArgs { export async function handleUninstall(args: UninstallArgs) { try { await uninstallExtension(args.name, false); - console.log(`Extension "${args.name}" successfully uninstalled.`); + debugLogger.log(`Extension "${args.name}" successfully uninstalled.`); } catch (error) { - console.error(getErrorMessage(error)); + debugLogger.error(getErrorMessage(error)); process.exit(1); } } diff --git a/packages/cli/src/commands/extensions/update.ts b/packages/cli/src/commands/extensions/update.ts index 4361474346..6f8ceb13a7 100644 --- a/packages/cli/src/commands/extensions/update.ts +++ b/packages/cli/src/commands/extensions/update.ts @@ -20,6 +20,7 @@ import { checkForExtensionUpdate } from '../../config/extensions/github.js'; import { getErrorMessage } from '../../utils/errors.js'; import { ExtensionUpdateState } from '../../ui/state/extensions.js'; import { ExtensionEnablementManager } from '../../config/extensions/extensionEnablement.js'; +import { debugLogger } from '@google/gemini-cli-core'; interface UpdateArgs { name?: string; @@ -48,18 +49,18 @@ export async function handleUpdate(args: UpdateArgs) { (extension) => extension.name === args.name, ); if (!extension) { - console.log(`Extension "${args.name}" not found.`); + debugLogger.log(`Extension "${args.name}" not found.`); return; } if (!extension.installMetadata) { - console.log( + debugLogger.log( `Unable to install extension "${args.name}" due to missing install metadata`, ); return; } const updateState = await checkForExtensionUpdate(extension); if (updateState !== ExtensionUpdateState.UPDATE_AVAILABLE) { - console.log(`Extension "${args.name}" is already up to date.`); + debugLogger.log(`Extension "${args.name}" is already up to date.`); return; } // TODO(chrstnb): we should list extensions if the requested extension is not installed. @@ -74,14 +75,14 @@ export async function handleUpdate(args: UpdateArgs) { updatedExtensionInfo.originalVersion !== updatedExtensionInfo.updatedVersion ) { - console.log( + debugLogger.log( `Extension "${args.name}" successfully updated: ${updatedExtensionInfo.originalVersion} → ${updatedExtensionInfo.updatedVersion}.`, ); } else { - console.log(`Extension "${args.name}" is already up to date.`); + debugLogger.log(`Extension "${args.name}" is already up to date.`); } } catch (error) { - console.error(getErrorMessage(error)); + debugLogger.error(getErrorMessage(error)); } } if (args.all) { @@ -109,12 +110,12 @@ export async function handleUpdate(args: UpdateArgs) { (info) => info.originalVersion !== info.updatedVersion, ); if (updateInfos.length === 0) { - console.log('No extensions to update.'); + debugLogger.log('No extensions to update.'); return; } - console.log(updateInfos.map((info) => updateOutput(info)).join('\n')); + debugLogger.log(updateInfos.map((info) => updateOutput(info)).join('\n')); } catch (error) { - console.error(getErrorMessage(error)); + debugLogger.error(getErrorMessage(error)); } } } diff --git a/packages/cli/src/commands/mcp/add.ts b/packages/cli/src/commands/mcp/add.ts index eb275ba104..16c5383a85 100644 --- a/packages/cli/src/commands/mcp/add.ts +++ b/packages/cli/src/commands/mcp/add.ts @@ -7,7 +7,7 @@ // File for 'gemini mcp add' command import type { CommandModule } from 'yargs'; import { loadSettings, SettingScope } from '../../config/settings.js'; -import type { MCPServerConfig } from '@google/gemini-cli-core'; +import { debugLogger, type MCPServerConfig } from '@google/gemini-cli-core'; async function addMcpServer( name: string, @@ -41,7 +41,7 @@ async function addMcpServer( const inHome = settings.workspace.path === settings.user.path; if (scope === 'project' && inHome) { - console.error( + debugLogger.error( 'Error: Please use --scope user to edit settings in the home directory.', ); process.exit(1); @@ -116,7 +116,7 @@ async function addMcpServer( const isExistingServer = !!mcpServers[name]; if (isExistingServer) { - console.log( + debugLogger.log( `MCP server "${name}" is already configured within ${scope} settings.`, ); } @@ -126,9 +126,9 @@ async function addMcpServer( settings.setValue(settingsScope, 'mcpServers', mcpServers); if (isExistingServer) { - console.log(`MCP server "${name}" updated in ${scope} settings.`); + debugLogger.log(`MCP server "${name}" updated in ${scope} settings.`); } else { - console.log( + debugLogger.log( `MCP server "${name}" added to ${scope} settings. (${transport})`, ); } diff --git a/packages/cli/src/config/config.ts b/packages/cli/src/config/config.ts index 79cb519ab1..e44026b272 100755 --- a/packages/cli/src/config/config.ts +++ b/packages/cli/src/config/config.ts @@ -36,6 +36,7 @@ import { FatalConfigError, getPty, EDIT_TOOL_NAME, + debugLogger, } from '@google/gemini-cli-core'; import type { Settings } from './settings.js'; @@ -49,16 +50,6 @@ import { isWorkspaceTrusted } from './trustedFolders.js'; import { createPolicyEngineConfig } from './policy.js'; import type { ExtensionEnablementManager } from './extensions/extensionEnablement.js'; -// Simple console logger for now - replace with actual logger if available -const logger = { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - debug: (...args: any[]) => console.debug('[DEBUG]', ...args), - // eslint-disable-next-line @typescript-eslint/no-explicit-any - warn: (...args: any[]) => console.warn('[WARN]', ...args), - // eslint-disable-next-line @typescript-eslint/no-explicit-any - error: (...args: any[]) => console.error('[ERROR]', ...args), -}; - export interface CliArgs { query: string | undefined; model: string | undefined; @@ -210,7 +201,7 @@ export async function parseArguments(settings: Settings): Promise { ) // Ensure validation flows through .fail() for clean UX .fail((msg, err, yargs) => { - console.error(msg || err?.message || 'Unknown error'); + debugLogger.error(msg || err?.message || 'Unknown error'); yargs.showHelp(); process.exit(1); }) @@ -313,7 +304,7 @@ export async function loadHierarchicalGeminiMemory( const effectiveCwd = isHomeDirectory ? '' : currentWorkingDirectory; if (debugMode) { - logger.debug( + debugLogger.debug( `CLI: Delegating hierarchical memory load to server for CWD: ${currentWorkingDirectory} (memoryImportFormat: ${memoryImportFormat})`, ); } @@ -470,7 +461,7 @@ export async function loadCliConfig( // Force approval mode to default if the folder is not trusted. if (!trustedFolder && approvalMode !== ApprovalMode.DEFAULT) { - logger.warn( + debugLogger.warn( `Approval mode overridden to "default" because the current folder is not trusted.`, ); approvalMode = ApprovalMode.DEFAULT; @@ -700,7 +691,7 @@ function mergeMcpServers(settings: Settings, extensions: GeminiCLIExtension[]) { for (const extension of extensions) { Object.entries(extension.mcpServers || {}).forEach(([key, server]) => { if (mcpServers[key]) { - logger.warn( + debugLogger.warn( `Skipping extension MCP config for server with key "${key}" as it already exists.`, ); return; diff --git a/packages/cli/src/config/extension.ts b/packages/cli/src/config/extension.ts index d102edfa9e..a3c4624ed4 100644 --- a/packages/cli/src/config/extension.ts +++ b/packages/cli/src/config/extension.ts @@ -23,6 +23,7 @@ import { logExtensionUninstall, logExtensionUpdateEvent, logExtensionDisable, + debugLogger, } from '@google/gemini-cli-core'; import * as fs from 'node:fs'; import * as path from 'node:path'; @@ -233,7 +234,7 @@ export function loadExtension( id, }; } catch (e) { - console.error( + debugLogger.error( `Warning: Skipping extension in ${effectiveExtensionPath}: ${getErrorMessage( e, )}`, @@ -324,7 +325,7 @@ export function annotateActiveExtensions( export async function requestConsentNonInteractive( consentDescription: string, ): Promise { - console.info(consentDescription); + debugLogger.log(consentDescription); const result = await promptForConsentNonInteractive( 'Do you want to continue? [Y/n]: ', ); diff --git a/packages/cli/src/config/extensions/github.ts b/packages/cli/src/config/extensions/github.ts index 2b28e9eab4..70b4cd94d5 100644 --- a/packages/cli/src/config/extensions/github.ts +++ b/packages/cli/src/config/extensions/github.ts @@ -6,9 +6,10 @@ import { simpleGit } from 'simple-git'; import { getErrorMessage } from '../../utils/errors.js'; -import type { - ExtensionInstallMetadata, - GeminiCLIExtension, +import { + debugLogger, + type ExtensionInstallMetadata, + type GeminiCLIExtension, } from '@google/gemini-cli-core'; import { ExtensionUpdateState } from '../../ui/state/extensions.js'; import * as os from 'node:os'; @@ -160,7 +161,7 @@ export async function checkForExtensionUpdate( workspaceDir: cwd, }); if (!newExtension) { - console.error( + debugLogger.error( `Failed to check for update for local extension "${extension.name}". Could not load extension from source path: ${installMetadata.source}`, ); return ExtensionUpdateState.ERROR; @@ -182,12 +183,14 @@ export async function checkForExtensionUpdate( const git = simpleGit(extension.path); const remotes = await git.getRemotes(true); if (remotes.length === 0) { - console.error('No git remotes found.'); + debugLogger.error('No git remotes found.'); return ExtensionUpdateState.ERROR; } const remoteUrl = remotes[0].refs.fetch; if (!remoteUrl) { - console.error(`No fetch URL found for git remote ${remotes[0].name}.`); + debugLogger.error( + `No fetch URL found for git remote ${remotes[0].name}.`, + ); return ExtensionUpdateState.ERROR; } @@ -197,7 +200,7 @@ export async function checkForExtensionUpdate( const lsRemoteOutput = await git.listRemote([remoteUrl, refToCheck]); if (typeof lsRemoteOutput !== 'string' || lsRemoteOutput.trim() === '') { - console.error(`Git ref ${refToCheck} not found.`); + debugLogger.error(`Git ref ${refToCheck} not found.`); return ExtensionUpdateState.ERROR; } @@ -205,7 +208,7 @@ export async function checkForExtensionUpdate( const localHash = await git.revparse(['HEAD']); if (!remoteHash) { - console.error( + debugLogger.error( `Unable to parse hash from git ls-remote output "${lsRemoteOutput}"`, ); return ExtensionUpdateState.ERROR; @@ -217,12 +220,12 @@ export async function checkForExtensionUpdate( } else { const { source, releaseTag } = installMetadata; if (!source) { - console.error(`No "source" provided for extension.`); + debugLogger.error(`No "source" provided for extension.`); return ExtensionUpdateState.ERROR; } const repoInfo = tryParseGithubUrl(source); if (!repoInfo) { - console.error( + debugLogger.error( `Source is not a valid GitHub repository for release checks: ${source}`, ); return ExtensionUpdateState.ERROR; @@ -244,7 +247,7 @@ export async function checkForExtensionUpdate( return ExtensionUpdateState.UP_TO_DATE; } } catch (error) { - console.error( + debugLogger.error( `Failed to check for updates for extension "${installMetadata.source}": ${getErrorMessage(error)}`, ); return ExtensionUpdateState.ERROR; diff --git a/packages/cli/src/config/extensions/update.ts b/packages/cli/src/config/extensions/update.ts index 5c8f615962..744d2b15a8 100644 --- a/packages/cli/src/config/extensions/update.ts +++ b/packages/cli/src/config/extensions/update.ts @@ -18,7 +18,7 @@ import { loadExtensionConfig, } from '../extension.js'; import { checkForExtensionUpdate } from './github.js'; -import type { GeminiCLIExtension } from '@google/gemini-cli-core'; +import { debugLogger, type GeminiCLIExtension } from '@google/gemini-cli-core'; import * as fs from 'node:fs'; import { getErrorMessage } from '../../utils/errors.js'; @@ -101,7 +101,7 @@ export async function updateExtension( updatedVersion, }; } catch (e) { - console.error( + debugLogger.error( `Error updating extension, rolling back. ${getErrorMessage(e)}`, ); dispatchExtensionStateUpdate({ diff --git a/packages/cli/src/gemini.tsx b/packages/cli/src/gemini.tsx index 70950167b9..a0fa434685 100644 --- a/packages/cli/src/gemini.tsx +++ b/packages/cli/src/gemini.tsx @@ -40,6 +40,7 @@ import { AuthType, getOauthClient, UserPromptEvent, + debugLogger, } from '@google/gemini-cli-core'; import { initializeApp, @@ -79,7 +80,7 @@ export function validateDnsResolutionOrder( return order; } // We don't want to throw here, just warn and use the default. - console.warn( + debugLogger.warn( `Invalid value for dnsResolutionOrder in settings: "${order}". Using default "${defaultValue}".`, ); return defaultValue; @@ -95,7 +96,7 @@ function getNodeMemoryArgs(isDebugMode: boolean): string[] { // Set target to 50% of total memory const targetMaxOldSpaceSizeInMB = Math.floor(totalMemoryMB * 0.5); if (isDebugMode) { - console.debug( + debugLogger.debug( `Current heap size ${currentMaxOldSpaceSizeMb.toFixed(2)} MB`, ); } @@ -106,7 +107,7 @@ function getNodeMemoryArgs(isDebugMode: boolean): string[] { if (targetMaxOldSpaceSizeInMB > currentMaxOldSpaceSizeMb) { if (isDebugMode) { - console.debug( + debugLogger.debug( `Need to relaunch with more memory: ${targetMaxOldSpaceSizeInMB.toFixed(2)} MB`, ); } @@ -213,7 +214,7 @@ export async function startInteractiveUI( .catch((err) => { // Silently ignore update check errors. if (config.getDebugMode()) { - console.error('Update check failed:', err); + debugLogger.warn('Update check failed:', err); } }); @@ -230,7 +231,7 @@ export async function main() { // Check for invalid input combinations early to prevent crashes if (argv.promptInteractive && !process.stdin.isTTY) { - console.error( + debugLogger.error( 'Error: The --prompt-interactive flag cannot be used when input is piped from stdin.', ); process.exit(1); @@ -266,7 +267,9 @@ export async function main() { if (!themeManager.setActiveTheme(settings.merged.ui?.theme)) { // If the theme is not found during initial load, log a warning and continue. // The useThemeCommand hook in AppContainer.tsx will handle opening the dialog. - console.warn(`Warning: Theme "${settings.merged.ui?.theme}" not found.`); + debugLogger.warn( + `Warning: Theme "${settings.merged.ui?.theme}" not found.`, + ); } } @@ -308,7 +311,7 @@ export async function main() { settings.merged.security.auth.selectedType, ); } catch (err) { - console.error('Error authenticating:', err); + debugLogger.error('Error authenticating:', err); process.exit(1); } } @@ -373,9 +376,9 @@ export async function main() { await cleanupExpiredSessions(config, settings.merged); if (config.getListExtensions()) { - console.log('Installed extensions:'); + debugLogger.log('Installed extensions:'); for (const extension of extensions) { - console.log(`- ${extension.name}`); + debugLogger.log(`- ${extension.name}`); } process.exit(0); } @@ -443,7 +446,7 @@ export async function main() { } } if (!input) { - console.error( + debugLogger.error( `No input provided via stdin. Input can be provided by piping data into gemini or using the --prompt option.`, ); process.exit(1); @@ -468,7 +471,7 @@ export async function main() { ); if (config.getDebugMode()) { - console.log('Session ID: %s', sessionId); + debugLogger.log('Session ID: %s', sessionId); } await runNonInteractive(nonInteractiveConfig, settings, input, prompt_id); diff --git a/packages/cli/src/nonInteractiveCli.ts b/packages/cli/src/nonInteractiveCli.ts index 4d854139e2..f92b17e800 100644 --- a/packages/cli/src/nonInteractiveCli.ts +++ b/packages/cli/src/nonInteractiveCli.ts @@ -23,6 +23,7 @@ import { StreamJsonFormatter, JsonStreamEventType, uiTelemetryService, + debugLogger, } from '@google/gemini-cli-core'; import type { Content, Part } from '@google/genai'; @@ -255,7 +256,7 @@ export async function runNonInteractive( .getChat() .recordCompletedToolCalls(currentModel, completedToolCalls); } catch (error) { - console.error( + debugLogger.error( `Error recording completed tool call information: ${error}`, ); } diff --git a/packages/cli/src/services/prompt-processors/atFileProcessor.ts b/packages/cli/src/services/prompt-processors/atFileProcessor.ts index bff19fb63e..48e527ed5f 100644 --- a/packages/cli/src/services/prompt-processors/atFileProcessor.ts +++ b/packages/cli/src/services/prompt-processors/atFileProcessor.ts @@ -5,6 +5,7 @@ */ import { + debugLogger, flatMapTextParts, readPathFromWorkspace, } from '@google/gemini-cli-core'; @@ -68,8 +69,9 @@ export class AtFileProcessor implements IPromptProcessor { error instanceof Error ? error.message : String(error); const uiMessage = `Failed to inject content for '@{${pathStr}}': ${message}`; - console.error( - `[AtFileProcessor] ${uiMessage}. Leaving placeholder in prompt.`, + // `context.invocation` should always be present at this point. + debugLogger.error( + `Error while loading custom command (${context.invocation!.name}) ${uiMessage}. Leaving placeholder in prompt.`, ); context.ui.addItem( { type: MessageType.ERROR, text: uiMessage }, diff --git a/packages/cli/src/validateNonInterActiveAuth.ts b/packages/cli/src/validateNonInterActiveAuth.ts index 54c7e4cc1e..18292afee5 100644 --- a/packages/cli/src/validateNonInterActiveAuth.ts +++ b/packages/cli/src/validateNonInterActiveAuth.ts @@ -5,7 +5,7 @@ */ import type { Config } from '@google/gemini-cli-core'; -import { AuthType, OutputFormat } from '@google/gemini-cli-core'; +import { AuthType, debugLogger, OutputFormat } from '@google/gemini-cli-core'; import { USER_SETTINGS_PATH } from './config/settings.js'; import { validateAuthMethod } from './config/auth.js'; import { type LoadedSettings } from './config/settings.js'; @@ -65,7 +65,7 @@ export async function validateNonInteractiveAuth( 1, ); } else { - console.error(error instanceof Error ? error.message : String(error)); + debugLogger.error(error instanceof Error ? error.message : String(error)); process.exit(1); } } diff --git a/packages/core/src/utils/editor.ts b/packages/core/src/utils/editor.ts index 1023abe4a0..896a348255 100644 --- a/packages/core/src/utils/editor.ts +++ b/packages/core/src/utils/editor.ts @@ -5,6 +5,7 @@ */ import { execSync, spawn, spawnSync } from 'node:child_process'; +import { debugLogger } from './debugLogger.js'; export type EditorType = | 'vscode' @@ -168,50 +169,45 @@ export async function openDiff( ): Promise { const diffCommand = getDiffCommand(oldPath, newPath, editor); if (!diffCommand) { - console.error('No diff tool available. Install a supported editor.'); + debugLogger.error('No diff tool available. Install a supported editor.'); return; } - try { - const isTerminalEditor = ['vim', 'emacs', 'neovim'].includes(editor); + const isTerminalEditor = ['vim', 'emacs', 'neovim'].includes(editor); - if (isTerminalEditor) { - try { - const result = spawnSync(diffCommand.command, diffCommand.args, { - stdio: 'inherit', - }); - if (result.error) { - throw result.error; - } - if (result.status !== 0) { - throw new Error(`${editor} exited with code ${result.status}`); - } - } finally { - onEditorClose(); - } - return; - } - - return new Promise((resolve, reject) => { - const childProcess = spawn(diffCommand.command, diffCommand.args, { + if (isTerminalEditor) { + try { + const result = spawnSync(diffCommand.command, diffCommand.args, { stdio: 'inherit', - shell: process.platform === 'win32', }); - - childProcess.on('close', (code) => { - if (code === 0) { - resolve(); - } else { - reject(new Error(`${editor} exited with code ${code}`)); - } - }); - - childProcess.on('error', (error) => { - reject(error); - }); - }); - } catch (error) { - console.error(error); - throw error; + if (result.error) { + throw result.error; + } + if (result.status !== 0) { + throw new Error(`${editor} exited with code ${result.status}`); + } + } finally { + onEditorClose(); + } + return; } + + return new Promise((resolve, reject) => { + const childProcess = spawn(diffCommand.command, diffCommand.args, { + stdio: 'inherit', + shell: process.platform === 'win32', + }); + + childProcess.on('close', (code) => { + if (code === 0) { + resolve(); + } else { + reject(new Error(`${editor} exited with code ${code}`)); + } + }); + + childProcess.on('error', (error) => { + reject(error); + }); + }); }