mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-07-05 15:46:47 -07:00
refactor(logging): Centralize console logging with debugLogger (#11590)
This commit is contained in:
@@ -5,7 +5,11 @@
|
||||
*/
|
||||
|
||||
import { type CommandModule } from 'yargs';
|
||||
import { FatalConfigError, getErrorMessage } from '@google/gemini-cli-core';
|
||||
import {
|
||||
debugLogger,
|
||||
FatalConfigError,
|
||||
getErrorMessage,
|
||||
} from '@google/gemini-cli-core';
|
||||
import { enableExtension } from '../../config/extension.js';
|
||||
import { SettingScope } from '../../config/settings.js';
|
||||
import { ExtensionEnablementManager } from '../../config/extensions/extensionEnablement.js';
|
||||
@@ -28,11 +32,11 @@ export function handleEnable(args: EnableArgs) {
|
||||
enableExtension(args.name, SettingScope.User, extensionEnablementManager);
|
||||
}
|
||||
if (args.scope) {
|
||||
console.log(
|
||||
debugLogger.log(
|
||||
`Extension "${args.name}" successfully enabled for scope "${args.scope}".`,
|
||||
);
|
||||
} else {
|
||||
console.log(
|
||||
debugLogger.log(
|
||||
`Extension "${args.name}" successfully enabled in all scopes.`,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -4,20 +4,11 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import {
|
||||
vi,
|
||||
describe,
|
||||
it,
|
||||
expect,
|
||||
beforeEach,
|
||||
afterEach,
|
||||
type Mock,
|
||||
type MockInstance,
|
||||
} from 'vitest';
|
||||
import { vi, describe, it, expect, beforeEach, type Mock } from 'vitest';
|
||||
import { listMcpServers } from './list.js';
|
||||
import { loadSettings } from '../../config/settings.js';
|
||||
import { ExtensionStorage, loadExtensions } from '../../config/extension.js';
|
||||
import { createTransport } from '@google/gemini-cli-core';
|
||||
import { createTransport, debugLogger } from '@google/gemini-cli-core';
|
||||
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
||||
|
||||
vi.mock('../../config/settings.js', () => ({
|
||||
@@ -43,6 +34,12 @@ vi.mock('@google/gemini-cli-core', () => ({
|
||||
})),
|
||||
GEMINI_DIR: '.gemini',
|
||||
getErrorMessage: (e: unknown) => (e instanceof Error ? e.message : String(e)),
|
||||
debugLogger: {
|
||||
log: vi.fn(),
|
||||
warn: vi.fn(),
|
||||
error: vi.fn(),
|
||||
debug: vi.fn(),
|
||||
},
|
||||
}));
|
||||
vi.mock('@modelcontextprotocol/sdk/client/index.js');
|
||||
|
||||
@@ -64,15 +61,12 @@ interface MockTransport {
|
||||
}
|
||||
|
||||
describe('mcp list command', () => {
|
||||
let consoleSpy: MockInstance;
|
||||
let mockClient: MockClient;
|
||||
let mockTransport: MockTransport;
|
||||
|
||||
beforeEach(() => {
|
||||
vi.resetAllMocks();
|
||||
|
||||
consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
|
||||
|
||||
mockTransport = { close: vi.fn() };
|
||||
mockClient = {
|
||||
connect: vi.fn(),
|
||||
@@ -86,16 +80,12 @@ describe('mcp list command', () => {
|
||||
mockedGetUserExtensionsDir.mockReturnValue('/mocked/extensions/dir');
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
consoleSpy.mockRestore();
|
||||
});
|
||||
|
||||
it('should display message when no servers configured', async () => {
|
||||
mockedLoadSettings.mockReturnValue({ merged: { mcpServers: {} } });
|
||||
|
||||
await listMcpServers();
|
||||
|
||||
expect(consoleSpy).toHaveBeenCalledWith('No MCP servers configured.');
|
||||
expect(debugLogger.log).toHaveBeenCalledWith('No MCP servers configured.');
|
||||
});
|
||||
|
||||
it('should display different server types with connected status', async () => {
|
||||
@@ -114,18 +104,18 @@ describe('mcp list command', () => {
|
||||
|
||||
await listMcpServers();
|
||||
|
||||
expect(consoleSpy).toHaveBeenCalledWith('Configured MCP servers:\n');
|
||||
expect(consoleSpy).toHaveBeenCalledWith(
|
||||
expect(debugLogger.log).toHaveBeenCalledWith('Configured MCP servers:\n');
|
||||
expect(debugLogger.log).toHaveBeenCalledWith(
|
||||
expect.stringContaining(
|
||||
'stdio-server: /path/to/server arg1 (stdio) - Connected',
|
||||
),
|
||||
);
|
||||
expect(consoleSpy).toHaveBeenCalledWith(
|
||||
expect(debugLogger.log).toHaveBeenCalledWith(
|
||||
expect.stringContaining(
|
||||
'sse-server: https://example.com/sse (sse) - Connected',
|
||||
),
|
||||
);
|
||||
expect(consoleSpy).toHaveBeenCalledWith(
|
||||
expect(debugLogger.log).toHaveBeenCalledWith(
|
||||
expect.stringContaining(
|
||||
'http-server: https://example.com/http (http) - Connected',
|
||||
),
|
||||
@@ -145,7 +135,7 @@ describe('mcp list command', () => {
|
||||
|
||||
await listMcpServers();
|
||||
|
||||
expect(consoleSpy).toHaveBeenCalledWith(
|
||||
expect(debugLogger.log).toHaveBeenCalledWith(
|
||||
expect.stringContaining(
|
||||
'test-server: /test/server (stdio) - Disconnected',
|
||||
),
|
||||
@@ -171,12 +161,12 @@ describe('mcp list command', () => {
|
||||
|
||||
await listMcpServers();
|
||||
|
||||
expect(consoleSpy).toHaveBeenCalledWith(
|
||||
expect(debugLogger.log).toHaveBeenCalledWith(
|
||||
expect.stringContaining(
|
||||
'config-server: /config/server (stdio) - Connected',
|
||||
),
|
||||
);
|
||||
expect(consoleSpy).toHaveBeenCalledWith(
|
||||
expect(debugLogger.log).toHaveBeenCalledWith(
|
||||
expect.stringContaining(
|
||||
'extension-server (from test-extension): /ext/server (stdio) - Connected',
|
||||
),
|
||||
|
||||
@@ -8,7 +8,11 @@
|
||||
import type { CommandModule } from 'yargs';
|
||||
import { loadSettings } from '../../config/settings.js';
|
||||
import type { MCPServerConfig } from '@google/gemini-cli-core';
|
||||
import { MCPServerStatus, createTransport } from '@google/gemini-cli-core';
|
||||
import {
|
||||
MCPServerStatus,
|
||||
createTransport,
|
||||
debugLogger,
|
||||
} from '@google/gemini-cli-core';
|
||||
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
||||
import { loadExtensions } from '../../config/extension.js';
|
||||
import { ExtensionEnablementManager } from '../../config/extensions/extensionEnablement.js';
|
||||
@@ -84,11 +88,11 @@ export async function listMcpServers(): Promise<void> {
|
||||
const serverNames = Object.keys(mcpServers);
|
||||
|
||||
if (serverNames.length === 0) {
|
||||
console.log('No MCP servers configured.');
|
||||
debugLogger.log('No MCP servers configured.');
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('Configured MCP servers:\n');
|
||||
debugLogger.log('Configured MCP servers:\n');
|
||||
|
||||
for (const serverName of serverNames) {
|
||||
const server = mcpServers[serverName];
|
||||
@@ -125,7 +129,7 @@ export async function listMcpServers(): Promise<void> {
|
||||
serverInfo += `${server.command} ${server.args?.join(' ') || ''} (stdio)`;
|
||||
}
|
||||
|
||||
console.log(`${statusIndicator} ${serverInfo} - ${statusText}`);
|
||||
debugLogger.log(`${statusIndicator} ${serverInfo} - ${statusText}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
// File for 'gemini mcp remove' command
|
||||
import type { CommandModule } from 'yargs';
|
||||
import { loadSettings, SettingScope } from '../../config/settings.js';
|
||||
import { debugLogger } from '@google/gemini-cli-core';
|
||||
|
||||
async function removeMcpServer(
|
||||
name: string,
|
||||
@@ -23,7 +24,7 @@ async function removeMcpServer(
|
||||
const mcpServers = existingSettings.mcpServers || {};
|
||||
|
||||
if (!mcpServers[name]) {
|
||||
console.log(`Server "${name}" not found in ${scope} settings.`);
|
||||
debugLogger.log(`Server "${name}" not found in ${scope} settings.`);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -31,7 +32,7 @@ async function removeMcpServer(
|
||||
|
||||
settings.setValue(settingsScope, 'mcpServers', mcpServers);
|
||||
|
||||
console.log(`Server "${name}" removed from ${scope} settings.`);
|
||||
debugLogger.log(`Server "${name}" removed from ${scope} settings.`);
|
||||
}
|
||||
|
||||
export const removeCommand: CommandModule = {
|
||||
|
||||
@@ -1073,8 +1073,6 @@ describe('Settings Loading and Merging', () => {
|
||||
);
|
||||
|
||||
const settings = loadSettings(MOCK_WORKSPACE_DIR);
|
||||
const e = settings.user.settings.model?.chatCompression;
|
||||
console.log(e);
|
||||
|
||||
expect(settings.user.settings.model?.chatCompression).toEqual({
|
||||
contextPercentageThreshold: 0.5,
|
||||
|
||||
@@ -10,6 +10,7 @@ import { homedir, platform } from 'node:os';
|
||||
import * as dotenv from 'dotenv';
|
||||
import process from 'node:process';
|
||||
import {
|
||||
debugLogger,
|
||||
FatalConfigError,
|
||||
GEMINI_DIR,
|
||||
getErrorMessage,
|
||||
@@ -753,7 +754,7 @@ export function migrateDeprecatedSettings(
|
||||
const processScope = (scope: SettingScope) => {
|
||||
const settings = loadedSettings.forScope(scope).settings;
|
||||
if (settings.extensions?.disabled) {
|
||||
console.log(
|
||||
debugLogger.log(
|
||||
`Migrating deprecated extensions.disabled settings from ${scope} settings...`,
|
||||
);
|
||||
const extensionEnablementManager = new ExtensionEnablementManager();
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import { debugLogger } from '@google/gemini-cli-core';
|
||||
import type { SlashCommand } from '../ui/commands/types.js';
|
||||
import type { ICommandLoader } from './types.js';
|
||||
|
||||
@@ -57,7 +58,7 @@ export class CommandService {
|
||||
if (result.status === 'fulfilled') {
|
||||
allCommands.push(...result.value);
|
||||
} else {
|
||||
console.debug('A command loader failed:', result.reason);
|
||||
debugLogger.debug('A command loader failed:', result.reason);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -42,6 +42,7 @@ import {
|
||||
AuthType,
|
||||
clearCachedCredentialFile,
|
||||
ShellExecutionService,
|
||||
debugLogger,
|
||||
} from '@google/gemini-cli-core';
|
||||
import { validateAuthMethod } from '../config/auth.js';
|
||||
import { loadHierarchicalGeminiMemory } from '../config/config.js';
|
||||
@@ -389,7 +390,7 @@ export const AppContainer = (props: AppContainerProps) => {
|
||||
config.isBrowserLaunchSuppressed()
|
||||
) {
|
||||
await runExitCleanup();
|
||||
console.log(`
|
||||
debugLogger.log(`
|
||||
----------------------------------------------------------------
|
||||
Logging in with Google... Please restart Gemini CLI to continue.
|
||||
----------------------------------------------------------------
|
||||
@@ -558,7 +559,7 @@ Logging in with Google... Please restart Gemini CLI to continue.
|
||||
Date.now(),
|
||||
);
|
||||
if (config.getDebugMode()) {
|
||||
console.log(
|
||||
debugLogger.log(
|
||||
`[DEBUG] Refreshed memory content in config: ${memoryContent.substring(
|
||||
0,
|
||||
200,
|
||||
@@ -933,7 +934,7 @@ Logging in with Google... Please restart Gemini CLI to continue.
|
||||
(key: Key) => {
|
||||
// Debug log keystrokes if enabled
|
||||
if (settings.merged.general?.debugKeystrokeLogging) {
|
||||
console.log('[DEBUG] Keystroke:', JSON.stringify(key));
|
||||
debugLogger.log('[DEBUG] Keystroke:', JSON.stringify(key));
|
||||
}
|
||||
|
||||
if (keyMatchers[Command.QUIT](key)) {
|
||||
|
||||
@@ -14,6 +14,7 @@ import { SettingScope } from '../../config/settings.js';
|
||||
import {
|
||||
AuthType,
|
||||
clearCachedCredentialFile,
|
||||
debugLogger,
|
||||
type Config,
|
||||
} from '@google/gemini-cli-core';
|
||||
import { useKeypress } from '../hooks/useKeypress.js';
|
||||
@@ -108,7 +109,7 @@ export function AuthDialog({
|
||||
config.isBrowserLaunchSuppressed()
|
||||
) {
|
||||
runExitCleanup();
|
||||
console.log(
|
||||
debugLogger.log(
|
||||
`
|
||||
----------------------------------------------------------------
|
||||
Logging in with Google... Please restart Gemini CLI to continue.
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
import { useState, useEffect, useCallback } from 'react';
|
||||
import type { LoadedSettings } from '../../config/settings.js';
|
||||
import { AuthType, type Config } from '@google/gemini-cli-core';
|
||||
import { AuthType, debugLogger, type Config } from '@google/gemini-cli-core';
|
||||
import { getErrorMessage } from '@google/gemini-cli-core';
|
||||
import { AuthState } from '../types.js';
|
||||
import { validateAuthMethod } from '../../config/auth.js';
|
||||
@@ -80,7 +80,7 @@ export const useAuthCommand = (settings: LoadedSettings, config: Config) => {
|
||||
try {
|
||||
await config.refreshAuth(authType);
|
||||
|
||||
console.log(`Authenticated via "${authType}".`);
|
||||
debugLogger.log(`Authenticated via "${authType}".`);
|
||||
setAuthError(null);
|
||||
setAuthState(AuthState.Authenticated);
|
||||
} catch (e) {
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import { debugLogger } from '@google/gemini-cli-core';
|
||||
import { copyToClipboard } from '../utils/commandUtils.js';
|
||||
import type { SlashCommand, SlashCommandActionReturn } from './types.js';
|
||||
import { CommandKind } from './types.js';
|
||||
@@ -45,7 +46,7 @@ export const copyCommand: SlashCommand = {
|
||||
};
|
||||
} catch (error) {
|
||||
const message = error instanceof Error ? error.message : String(error);
|
||||
console.debug(message);
|
||||
debugLogger.debug(message);
|
||||
|
||||
return {
|
||||
type: 'message',
|
||||
|
||||
@@ -20,6 +20,7 @@ import {
|
||||
import type { SlashCommand, SlashCommandActionReturn } from './types.js';
|
||||
import { CommandKind } from './types.js';
|
||||
import { getUrlOpenCommand } from '../../ui/utils/commandUtils.js';
|
||||
import { debugLogger } from '@google/gemini-cli-core';
|
||||
|
||||
export const GITHUB_WORKFLOW_PATHS = [
|
||||
'gemini-dispatch/gemini-dispatch.yml',
|
||||
@@ -84,7 +85,7 @@ export async function updateGitignore(gitRepoRoot: string): Promise<void> {
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.debug('Failed to update .gitignore:', error);
|
||||
debugLogger.debug('Failed to update .gitignore:', error);
|
||||
// Continue without failing the whole command
|
||||
}
|
||||
}
|
||||
@@ -109,7 +110,7 @@ export const setupGithubCommand: SlashCommand = {
|
||||
try {
|
||||
gitRepoRoot = getGitRepoRoot();
|
||||
} catch (_error) {
|
||||
console.debug(`Failed to get git repo root:`, _error);
|
||||
debugLogger.debug(`Failed to get git repo root:`, _error);
|
||||
throw new Error(
|
||||
'Unable to determine the GitHub repository. /setup-github must be run from a git repository.',
|
||||
);
|
||||
@@ -125,7 +126,7 @@ export const setupGithubCommand: SlashCommand = {
|
||||
try {
|
||||
await fs.promises.mkdir(githubWorkflowsDir, { recursive: true });
|
||||
} catch (_error) {
|
||||
console.debug(
|
||||
debugLogger.debug(
|
||||
`Failed to create ${githubWorkflowsDir} directory:`,
|
||||
_error,
|
||||
);
|
||||
|
||||
@@ -37,6 +37,7 @@ import {
|
||||
type SettingsValue,
|
||||
TOGGLE_TYPES,
|
||||
} from '../../config/settingsSchema.js';
|
||||
import { debugLogger } from '@google/gemini-cli-core';
|
||||
|
||||
interface SettingsDialogProps {
|
||||
settings: LoadedSettings;
|
||||
@@ -162,7 +163,7 @@ export function SettingsDialog({
|
||||
newValue,
|
||||
currentScopeSettings,
|
||||
);
|
||||
console.log(
|
||||
debugLogger.log(
|
||||
`[DEBUG SettingsDialog] Saving ${key} immediately with value:`,
|
||||
newValue,
|
||||
);
|
||||
@@ -207,7 +208,7 @@ export function SettingsDialog({
|
||||
setModifiedSettings((prev) => {
|
||||
const updated = new Set(prev).add(key);
|
||||
const needsRestart = hasRestartRequiredSettings(updated);
|
||||
console.log(
|
||||
debugLogger.log(
|
||||
`[DEBUG SettingsDialog] Modified settings:`,
|
||||
Array.from(updated),
|
||||
'Needs restart:',
|
||||
|
||||
@@ -9,6 +9,7 @@ import * as path from 'node:path';
|
||||
import type { PartListUnion, PartUnion } from '@google/genai';
|
||||
import type { AnyToolInvocation, Config } from '@google/gemini-cli-core';
|
||||
import {
|
||||
debugLogger,
|
||||
getErrorMessage,
|
||||
isNodeError,
|
||||
unescapePath,
|
||||
@@ -372,7 +373,7 @@ export async function handleAtCommand({
|
||||
}
|
||||
|
||||
const message = `Ignored ${totalIgnored} files:\n${messages.join('\n')}`;
|
||||
console.log(message);
|
||||
debugLogger.log(message);
|
||||
onDebugMessage(message);
|
||||
}
|
||||
|
||||
|
||||
@@ -222,8 +222,6 @@ export const useShellCommandProcessor = (
|
||||
shellExecutionConfig,
|
||||
);
|
||||
|
||||
console.log(terminalHeight, terminalWidth);
|
||||
|
||||
executionPid = pid;
|
||||
if (pid) {
|
||||
setActiveShellPtyId(pid);
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import { debugLogger } from '@google/gemini-cli-core';
|
||||
import { useState, useCallback } from 'react';
|
||||
|
||||
interface Logger {
|
||||
@@ -69,7 +70,10 @@ export function useInputHistoryStore(): UseInputHistoryStoreReturn {
|
||||
setIsInitialized(true);
|
||||
} catch (error) {
|
||||
// Start with empty history even if logger initialization fails
|
||||
console.warn('Failed to initialize input history from logger:', error);
|
||||
debugLogger.warn(
|
||||
'Failed to initialize input history from logger:',
|
||||
error,
|
||||
);
|
||||
setPastSessionMessages([]);
|
||||
recalculateHistory([], []);
|
||||
setIsInitialized(true);
|
||||
|
||||
@@ -20,7 +20,7 @@ import type {
|
||||
Status as CoreStatus,
|
||||
EditorType,
|
||||
} from '@google/gemini-cli-core';
|
||||
import { CoreToolScheduler } from '@google/gemini-cli-core';
|
||||
import { CoreToolScheduler, debugLogger } from '@google/gemini-cli-core';
|
||||
import { useCallback, useState, useMemo } from 'react';
|
||||
import type {
|
||||
HistoryItemToolGroup,
|
||||
@@ -198,7 +198,7 @@ function mapCoreStatusToDisplayStatus(coreStatus: CoreStatus): ToolCallStatus {
|
||||
return ToolCallStatus.Pending;
|
||||
default: {
|
||||
const exhaustiveCheck: never = coreStatus;
|
||||
console.warn(`Unknown core status encountered: ${exhaustiveCheck}`);
|
||||
debugLogger.warn(`Unknown core status encountered: ${exhaustiveCheck}`);
|
||||
return ToolCallStatus.Error;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
import type { Message } from '../types.js';
|
||||
import { MessageType } from '../types.js';
|
||||
import type { Config } from '@google/gemini-cli-core';
|
||||
import { debugLogger, type Config } from '@google/gemini-cli-core';
|
||||
import type { LoadedSettings } from '../../config/settings.js';
|
||||
|
||||
export function createShowMemoryAction(
|
||||
@@ -27,7 +27,7 @@ export function createShowMemoryAction(
|
||||
const debugMode = config.getDebugMode();
|
||||
|
||||
if (debugMode) {
|
||||
console.log('[DEBUG] Show Memory command invoked.');
|
||||
debugLogger.log('[DEBUG] Show Memory command invoked.');
|
||||
}
|
||||
|
||||
const currentMemory = config.getUserMemory();
|
||||
@@ -38,10 +38,10 @@ export function createShowMemoryAction(
|
||||
: [contextFileName];
|
||||
|
||||
if (debugMode) {
|
||||
console.log(
|
||||
debugLogger.log(
|
||||
`[DEBUG] Showing memory. Content from config.getUserMemory() (first 200 chars): ${currentMemory.substring(0, 200)}...`,
|
||||
);
|
||||
console.log(`[DEBUG] Number of context files loaded: ${fileCount}`);
|
||||
debugLogger.log(`[DEBUG] Number of context files loaded: ${fileCount}`);
|
||||
}
|
||||
|
||||
if (fileCount > 0) {
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
type CommandContext,
|
||||
type SlashCommand,
|
||||
} from '../commands/types.js';
|
||||
import { debugLogger } from '@google/gemini-cli-core';
|
||||
|
||||
// Type alias for improved type safety based on actual fzf result structure
|
||||
type FzfCommandResult = {
|
||||
@@ -189,7 +190,7 @@ function useCommandSuggestions(
|
||||
|
||||
// Safety check: ensure leafCommand and completion exist
|
||||
if (!leafCommand?.completion) {
|
||||
console.warn(
|
||||
debugLogger.warn(
|
||||
'Attempted argument completion without completion function',
|
||||
);
|
||||
return;
|
||||
|
||||
@@ -8,6 +8,7 @@ import { useCallback, useReducer, useEffect } from 'react';
|
||||
import type { Key } from './useKeypress.js';
|
||||
import type { TextBuffer } from '../components/shared/text-buffer.js';
|
||||
import { useVimMode } from '../contexts/VimModeContext.js';
|
||||
import { debugLogger } from '@google/gemini-cli-core';
|
||||
|
||||
export type VimMode = 'NORMAL' | 'INSERT';
|
||||
|
||||
@@ -394,7 +395,7 @@ export function useVim(buffer: TextBuffer, onSubmit?: (value: string) => void) {
|
||||
normalizedKey = normalizeKey(key);
|
||||
} catch (error) {
|
||||
// Handle malformed key inputs gracefully
|
||||
console.warn('Malformed key input in vim mode:', key, error);
|
||||
debugLogger.warn('Malformed key input in vim mode:', key, error);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import { debugLogger } from '@google/gemini-cli-core';
|
||||
|
||||
// Mapping from common CSS color names (lowercase) to hex codes (lowercase)
|
||||
// Excludes names directly supported by Ink
|
||||
export const CSS_NAME_TO_HEX_MAP: Readonly<Record<string, string>> = {
|
||||
@@ -224,7 +226,7 @@ export function resolveColor(colorValue: string): string | undefined {
|
||||
}
|
||||
|
||||
// 4. Could not resolve
|
||||
console.warn(
|
||||
debugLogger.warn(
|
||||
`[ColorUtils] Could not resolve color "${colorValue}" to an Ink-compatible format.`,
|
||||
);
|
||||
return undefined;
|
||||
|
||||
@@ -25,6 +25,7 @@ import { ANSI } from './ansi.js';
|
||||
import { ANSILight } from './ansi-light.js';
|
||||
import { NoColorTheme } from './no-color.js';
|
||||
import process from 'node:process';
|
||||
import { debugLogger } from '@google/gemini-cli-core';
|
||||
|
||||
export interface ThemeDisplay {
|
||||
name: string;
|
||||
@@ -75,7 +76,7 @@ class ThemeManager {
|
||||
const validation = validateCustomTheme(customThemeConfig);
|
||||
if (validation.isValid) {
|
||||
if (validation.warning) {
|
||||
console.warn(`Theme "${name}": ${validation.warning}`);
|
||||
debugLogger.warn(`Theme "${name}": ${validation.warning}`);
|
||||
}
|
||||
const themeWithDefaults: CustomTheme = {
|
||||
...DEFAULT_THEME.colors,
|
||||
@@ -88,10 +89,10 @@ class ThemeManager {
|
||||
const theme = createCustomTheme(themeWithDefaults);
|
||||
this.customThemes.set(name, theme);
|
||||
} catch (error) {
|
||||
console.warn(`Failed to load custom theme "${name}":`, error);
|
||||
debugLogger.warn(`Failed to load custom theme "${name}":`, error);
|
||||
}
|
||||
} else {
|
||||
console.warn(`Invalid custom theme "${name}": ${validation.error}`);
|
||||
debugLogger.warn(`Invalid custom theme "${name}": ${validation.error}`);
|
||||
}
|
||||
}
|
||||
// If the current active theme is a custom theme, keep it if still valid
|
||||
@@ -246,7 +247,7 @@ class ThemeManager {
|
||||
// 2. Perform security check.
|
||||
const homeDir = path.resolve(os.homedir());
|
||||
if (!canonicalPath.startsWith(homeDir)) {
|
||||
console.warn(
|
||||
debugLogger.warn(
|
||||
`Theme file at "${themePath}" is outside your home directory. ` +
|
||||
`Only load themes from trusted sources.`,
|
||||
);
|
||||
@@ -259,14 +260,14 @@ class ThemeManager {
|
||||
|
||||
const validation = validateCustomTheme(customThemeConfig);
|
||||
if (!validation.isValid) {
|
||||
console.warn(
|
||||
debugLogger.warn(
|
||||
`Invalid custom theme from file "${themePath}": ${validation.error}`,
|
||||
);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (validation.warning) {
|
||||
console.warn(`Theme from "${themePath}": ${validation.warning}`);
|
||||
debugLogger.warn(`Theme from "${themePath}": ${validation.warning}`);
|
||||
}
|
||||
|
||||
// 4. Create and cache the theme.
|
||||
@@ -286,7 +287,10 @@ class ThemeManager {
|
||||
if (
|
||||
!(error instanceof Error && 'code' in error && error.code === 'ENOENT')
|
||||
) {
|
||||
console.warn(`Could not load theme from file "${themePath}":`, error);
|
||||
debugLogger.warn(
|
||||
`Could not load theme from file "${themePath}":`,
|
||||
error,
|
||||
);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import { debugLogger } from '@google/gemini-cli-core';
|
||||
import type { SpawnOptions } from 'node:child_process';
|
||||
import { spawn } from 'node:child_process';
|
||||
|
||||
@@ -165,7 +166,7 @@ export const getUrlOpenCommand = (): string => {
|
||||
default:
|
||||
// Default to xdg-open, which appears to be supported for the less popular operating systems.
|
||||
openCmd = 'xdg-open';
|
||||
console.warn(
|
||||
debugLogger.warn(
|
||||
`Unknown platform: ${process.platform}. Attempting to open URLs with: ${openCmd}.`,
|
||||
);
|
||||
break;
|
||||
|
||||
@@ -30,6 +30,7 @@ import { exec } from 'node:child_process';
|
||||
import { promisify } from 'node:util';
|
||||
import { isKittyProtocolEnabled } from './kittyProtocolDetector.js';
|
||||
import { VSCODE_SHIFT_ENTER_SEQUENCE } from './platformConstants.js';
|
||||
import { debugLogger } from '@google/gemini-cli-core';
|
||||
|
||||
const execAsync = promisify(exec);
|
||||
|
||||
@@ -88,7 +89,7 @@ async function detectTerminal(): Promise<SupportedTerminal | null> {
|
||||
return 'vscode';
|
||||
} catch (error) {
|
||||
// Continue detection even if process check fails
|
||||
console.debug('Parent process detection failed:', error);
|
||||
debugLogger.debug('Parent process detection failed:', error);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,7 +104,7 @@ async function backupFile(filePath: string): Promise<void> {
|
||||
await fs.copyFile(filePath, backupPath);
|
||||
} catch (error) {
|
||||
// Log backup errors but continue with operation
|
||||
console.warn(`Failed to create backup of ${filePath}:`, error);
|
||||
debugLogger.warn(`Failed to create backup of ${filePath}:`, error);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ import updateNotifier from 'update-notifier';
|
||||
import semver from 'semver';
|
||||
import { getPackageJson } from '../../utils/package.js';
|
||||
import type { LoadedSettings } from '../../config/settings.js';
|
||||
import { debugLogger } from '@google/gemini-cli-core';
|
||||
|
||||
export const FETCH_TIMEOUT_MS = 2000;
|
||||
|
||||
@@ -101,7 +102,7 @@ export async function checkForUpdates(
|
||||
|
||||
return null;
|
||||
} catch (e) {
|
||||
console.warn('Failed to check for updates: ' + e);
|
||||
debugLogger.warn('Failed to check for updates: ' + e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import { debugLogger } from '@google/gemini-cli-core';
|
||||
import { execSync } from 'node:child_process';
|
||||
import { ProxyAgent } from 'undici';
|
||||
|
||||
@@ -24,7 +25,7 @@ export const isGitHubRepository = (): boolean => {
|
||||
return pattern.test(remotes);
|
||||
} catch (_error) {
|
||||
// If any filesystem error occurs, assume not a git repo
|
||||
console.debug(`Failed to get git remote:`, _error);
|
||||
debugLogger.debug(`Failed to get git remote:`, _error);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
@@ -83,7 +84,10 @@ export const getLatestGitHubRelease = async (
|
||||
}
|
||||
return releaseTag;
|
||||
} catch (_error) {
|
||||
console.debug(`Failed to determine latest run-gemini-cli release:`, _error);
|
||||
debugLogger.debug(
|
||||
`Failed to determine latest run-gemini-cli release:`,
|
||||
_error,
|
||||
);
|
||||
throw new Error(
|
||||
`Unable to determine the latest run-gemini-cli release on GitHub.`,
|
||||
);
|
||||
|
||||
@@ -9,10 +9,16 @@ import { getInstallationInfo, PackageManager } from './installationInfo.js';
|
||||
import * as fs from 'node:fs';
|
||||
import * as path from 'node:path';
|
||||
import * as childProcess from 'node:child_process';
|
||||
import { isGitRepository } from '@google/gemini-cli-core';
|
||||
import { isGitRepository, debugLogger } from '@google/gemini-cli-core';
|
||||
|
||||
vi.mock('@google/gemini-cli-core', () => ({
|
||||
isGitRepository: vi.fn(),
|
||||
debugLogger: {
|
||||
log: vi.fn(),
|
||||
warn: vi.fn(),
|
||||
error: vi.fn(),
|
||||
debug: vi.fn(),
|
||||
},
|
||||
}));
|
||||
|
||||
vi.mock('fs', async (importOriginal) => {
|
||||
@@ -59,7 +65,6 @@ describe('getInstallationInfo', () => {
|
||||
});
|
||||
|
||||
it('should return UNKNOWN and log error if realpathSync fails', () => {
|
||||
const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
|
||||
process.argv[1] = '/path/to/cli';
|
||||
const error = new Error('realpath failed');
|
||||
mockedRealPathSync.mockImplementation(() => {
|
||||
@@ -69,8 +74,7 @@ describe('getInstallationInfo', () => {
|
||||
const info = getInstallationInfo(projectRoot, false);
|
||||
|
||||
expect(info.packageManager).toBe(PackageManager.UNKNOWN);
|
||||
expect(consoleSpy).toHaveBeenCalledWith(error);
|
||||
consoleSpy.mockRestore();
|
||||
expect(debugLogger.log).toHaveBeenCalledWith(error);
|
||||
});
|
||||
|
||||
it('should detect running from a local git clone', () => {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import { isGitRepository } from '@google/gemini-cli-core';
|
||||
import { debugLogger, isGitRepository } from '@google/gemini-cli-core';
|
||||
import * as fs from 'node:fs';
|
||||
import * as path from 'node:path';
|
||||
import * as childProcess from 'node:child_process';
|
||||
@@ -174,7 +174,7 @@ export function getInstallationInfo(
|
||||
: 'Installed with npm. Attempting to automatically update now...',
|
||||
};
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
debugLogger.log(error);
|
||||
return { packageManager: PackageManager.UNKNOWN, isGlobal: false };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import { debugLogger } from '@google/gemini-cli-core';
|
||||
|
||||
export async function readStdin(): Promise<string> {
|
||||
const MAX_STDIN_SIZE = 8 * 1024 * 1024; // 8MB
|
||||
return new Promise((resolve, reject) => {
|
||||
@@ -30,7 +32,7 @@ export async function readStdin(): Promise<string> {
|
||||
if (totalSize + chunk.length > MAX_STDIN_SIZE) {
|
||||
const remainingSize = MAX_STDIN_SIZE - totalSize;
|
||||
data += chunk.slice(0, remainingSize);
|
||||
console.warn(
|
||||
debugLogger.warn(
|
||||
`Warning: stdin input truncated to ${MAX_STDIN_SIZE} bytes.`,
|
||||
);
|
||||
process.stdin.destroy(); // Stop reading further
|
||||
|
||||
@@ -14,7 +14,11 @@ import { quote, parse } from 'shell-quote';
|
||||
import { USER_SETTINGS_DIR } from '../config/settings.js';
|
||||
import { promisify } from 'node:util';
|
||||
import type { Config, SandboxConfig } from '@google/gemini-cli-core';
|
||||
import { FatalSandboxError, GEMINI_DIR } from '@google/gemini-cli-core';
|
||||
import {
|
||||
debugLogger,
|
||||
FatalSandboxError,
|
||||
GEMINI_DIR,
|
||||
} from '@google/gemini-cli-core';
|
||||
import { ConsolePatcher } from '../ui/utils/ConsolePatcher.js';
|
||||
import { randomBytes } from 'node:crypto';
|
||||
|
||||
@@ -92,7 +96,7 @@ async function shouldUseCurrentUserInSandbox(): Promise<boolean> {
|
||||
} catch (_err) {
|
||||
// Silently ignore if /etc/os-release is not found or unreadable.
|
||||
// The default (false) will be applied in this case.
|
||||
console.warn(
|
||||
debugLogger.warn(
|
||||
'Warning: Could not read /etc/os-release to auto-detect Debian/Ubuntu for UID/GID default.',
|
||||
);
|
||||
}
|
||||
@@ -301,7 +305,7 @@ export async function start_sandbox(
|
||||
});
|
||||
// install handlers to stop proxy on exit/signal
|
||||
const stopProxy = () => {
|
||||
console.log('stopping proxy ...');
|
||||
debugLogger.log('stopping proxy ...');
|
||||
if (proxyProcess?.pid) {
|
||||
process.kill(-proxyProcess.pid, 'SIGTERM');
|
||||
}
|
||||
@@ -325,7 +329,7 @@ export async function start_sandbox(
|
||||
`Proxy command '${proxyCommand}' exited with code ${code}, signal ${signal}`,
|
||||
);
|
||||
});
|
||||
console.log('waiting for proxy to start ...');
|
||||
debugLogger.log('waiting for proxy to start ...');
|
||||
await execAsync(
|
||||
`until timeout 0.25 curl -s http://localhost:8877; do sleep 0.25; done`,
|
||||
);
|
||||
@@ -559,7 +563,7 @@ export async function start_sandbox(
|
||||
containerName = `gemini-cli-integration-test-${randomBytes(4).toString(
|
||||
'hex',
|
||||
)}`;
|
||||
console.log(`ContainerName: ${containerName}`);
|
||||
debugLogger.log(`ContainerName: ${containerName}`);
|
||||
} else {
|
||||
let index = 0;
|
||||
const containerNameCheck = execSync(
|
||||
@@ -571,7 +575,7 @@ export async function start_sandbox(
|
||||
index++;
|
||||
}
|
||||
containerName = `${imageName}-${index}`;
|
||||
console.log(`ContainerName (regular): ${containerName}`);
|
||||
debugLogger.log(`ContainerName (regular): ${containerName}`);
|
||||
}
|
||||
args.push('--name', containerName, '--hostname', containerName);
|
||||
|
||||
@@ -773,7 +777,7 @@ export async function start_sandbox(
|
||||
});
|
||||
// install handlers to stop proxy on exit/signal
|
||||
const stopProxy = () => {
|
||||
console.log('stopping proxy container ...');
|
||||
debugLogger.log('stopping proxy container ...');
|
||||
execSync(`${config.command} rm -f ${SANDBOX_PROXY_NAME}`);
|
||||
};
|
||||
process.on('exit', stopProxy);
|
||||
@@ -795,7 +799,7 @@ export async function start_sandbox(
|
||||
`Proxy container command '${proxyContainerCommand}' exited with code ${code}, signal ${signal}`,
|
||||
);
|
||||
});
|
||||
console.log('waiting for proxy to start ...');
|
||||
debugLogger.log('waiting for proxy to start ...');
|
||||
await execAsync(
|
||||
`until timeout 0.25 curl -s http://localhost:8877; do sleep 0.25; done`,
|
||||
);
|
||||
@@ -821,7 +825,7 @@ export async function start_sandbox(
|
||||
sandboxProcess?.on('close', (code, signal) => {
|
||||
process.stdin.resume();
|
||||
if (code !== 0 && code !== null) {
|
||||
console.log(
|
||||
debugLogger.log(
|
||||
`Sandbox process exited with code: ${code}, signal: ${signal}`,
|
||||
);
|
||||
}
|
||||
@@ -847,7 +851,7 @@ async function imageExists(sandbox: string, image: string): Promise<boolean> {
|
||||
}
|
||||
|
||||
checkProcess.on('error', (err) => {
|
||||
console.warn(
|
||||
debugLogger.warn(
|
||||
`Failed to start '${sandbox}' command for image check: ${err.message}`,
|
||||
);
|
||||
resolve(false);
|
||||
@@ -882,7 +886,7 @@ async function pullImage(sandbox: string, image: string): Promise<boolean> {
|
||||
};
|
||||
|
||||
const onError = (err: Error) => {
|
||||
console.warn(
|
||||
debugLogger.warn(
|
||||
`Failed to start '${sandbox} pull ${image}' command: ${err.message}`,
|
||||
);
|
||||
cleanup();
|
||||
@@ -895,7 +899,7 @@ async function pullImage(sandbox: string, image: string): Promise<boolean> {
|
||||
cleanup();
|
||||
resolve(true);
|
||||
} else {
|
||||
console.warn(
|
||||
debugLogger.warn(
|
||||
`Failed to pull image ${image}. '${sandbox} pull ${image}' exited with code ${code}.`,
|
||||
);
|
||||
if (stderrData.trim()) {
|
||||
@@ -953,7 +957,7 @@ async function ensureSandboxImageIsPresent(
|
||||
console.info(`Sandbox image ${image} is now available after pulling.`);
|
||||
return true;
|
||||
} else {
|
||||
console.warn(
|
||||
debugLogger.warn(
|
||||
`Sandbox image ${image} still not found after a pull attempt. This might indicate an issue with the image name or registry, or the pull command reported success but failed to make the image available.`,
|
||||
);
|
||||
return false;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
import * as fs from 'node:fs/promises';
|
||||
import * as path from 'node:path';
|
||||
import { type Config } from '@google/gemini-cli-core';
|
||||
import { debugLogger, type Config } from '@google/gemini-cli-core';
|
||||
import type { Settings, SessionRetentionSettings } from '../config/settings.js';
|
||||
import { getAllSessionFiles, type SessionFileEntry } from './sessionUtils.js';
|
||||
|
||||
@@ -88,11 +88,11 @@ export async function cleanupExpiredSessions(
|
||||
|
||||
if (config.getDebugMode()) {
|
||||
if (sessionToDelete.sessionInfo === null) {
|
||||
console.debug(
|
||||
debugLogger.debug(
|
||||
`Deleted corrupted session file: ${sessionToDelete.fileName}`,
|
||||
);
|
||||
} else {
|
||||
console.debug(
|
||||
debugLogger.debug(
|
||||
`Deleted expired session: ${sessionToDelete.sessionInfo.id} (${sessionToDelete.sessionInfo.lastUpdated})`,
|
||||
);
|
||||
}
|
||||
@@ -125,7 +125,7 @@ export async function cleanupExpiredSessions(
|
||||
result.skipped = result.scanned - result.deleted - result.failed;
|
||||
|
||||
if (config.getDebugMode() && result.deleted > 0) {
|
||||
console.debug(
|
||||
debugLogger.debug(
|
||||
`Session cleanup: deleted ${result.deleted}, skipped ${result.skipped}, failed ${result.failed}`,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -53,10 +53,7 @@ describe('validateNonInterActiveAuth', () => {
|
||||
throw new Error(`process.exit(${code}) called`);
|
||||
});
|
||||
vi.spyOn(auth, 'validateAuthMethod').mockReturnValue(null);
|
||||
refreshAuthMock = vi.fn().mockImplementation(async () => {
|
||||
console.log('DEBUG: refreshAuthMock called');
|
||||
return 'refreshed';
|
||||
});
|
||||
refreshAuthMock = vi.fn().mockImplementation(async () => 'refreshed');
|
||||
mockSettings = {
|
||||
system: { path: '', settings: {} },
|
||||
systemDefaults: { path: '', settings: {} },
|
||||
|
||||
@@ -30,6 +30,7 @@ import {
|
||||
DEFAULT_GEMINI_MODEL,
|
||||
DEFAULT_GEMINI_MODEL_AUTO,
|
||||
DEFAULT_GEMINI_FLASH_MODEL,
|
||||
debugLogger,
|
||||
} from '@google/gemini-cli-core';
|
||||
import * as acp from './acp.js';
|
||||
import { AcpFileSystemService } from './fileSystemService.js';
|
||||
@@ -592,7 +593,7 @@ class Session {
|
||||
const reason = respectGitIgnore
|
||||
? 'git-ignored and will be skipped'
|
||||
: 'ignored by custom patterns';
|
||||
console.warn(`Path ${pathName} is ${reason}.`);
|
||||
debugLogger.warn(`Path ${pathName} is ${reason}.`);
|
||||
continue;
|
||||
}
|
||||
let currentPathSpec = pathName;
|
||||
@@ -739,7 +740,7 @@ class Session {
|
||||
|
||||
if (pathSpecsToRead.length === 0 && embeddedContext.length === 0) {
|
||||
// Fallback for lone "@" or completely invalid @-commands resulting in empty initialQueryText
|
||||
console.warn('No valid file paths found in @ commands to read.');
|
||||
debugLogger.warn('No valid file paths found in @ commands to read.');
|
||||
return [{ text: initialQueryText }];
|
||||
}
|
||||
|
||||
@@ -802,7 +803,7 @@ class Session {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
console.warn(
|
||||
debugLogger.warn(
|
||||
'read_many_files tool returned no content or empty content.',
|
||||
);
|
||||
}
|
||||
@@ -855,7 +856,7 @@ class Session {
|
||||
|
||||
debug(msg: string) {
|
||||
if (this.config.getDebugMode()) {
|
||||
console.warn(msg);
|
||||
debugLogger.warn(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user