mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-07-22 15:51:18 -07:00
refactor(logging): Centralize console logging with debugLogger (#11590)
This commit is contained in:
@@ -43,6 +43,7 @@ import { templateString } from './utils.js';
|
||||
import { parseThought } from '../utils/thoughtUtils.js';
|
||||
import { type z } from 'zod';
|
||||
import { zodToJsonSchema } from 'zod-to-json-schema';
|
||||
import { debugLogger } from '../utils/debugLogger.js';
|
||||
|
||||
/** A callback function to report on agent activity. */
|
||||
export type ActivityCallback = (activity: SubagentActivityEvent) => void;
|
||||
@@ -506,7 +507,7 @@ export class AgentExecutor<TOutput extends z.ZodTypeAny> {
|
||||
if (!allowedToolNames.has(functionCall.name as string)) {
|
||||
const error = `Unauthorized tool call: '${functionCall.name}' is not available to this agent.`;
|
||||
|
||||
console.warn(`[AgentExecutor] Blocked call: ${error}`);
|
||||
debugLogger.warn(`[AgentExecutor] Blocked call: ${error}`);
|
||||
|
||||
syncResponseParts.push({
|
||||
functionResponse: {
|
||||
|
||||
@@ -8,6 +8,7 @@ import type { Config } from '../config/config.js';
|
||||
import type { AgentDefinition } from './types.js';
|
||||
import { CodebaseInvestigatorAgent } from './codebase-investigator.js';
|
||||
import { type z } from 'zod';
|
||||
import { debugLogger } from '../utils/debugLogger.js';
|
||||
|
||||
/**
|
||||
* Manages the discovery, loading, validation, and registration of
|
||||
@@ -26,7 +27,7 @@ export class AgentRegistry {
|
||||
this.loadBuiltInAgents();
|
||||
|
||||
if (this.config.getDebugMode()) {
|
||||
console.log(
|
||||
debugLogger.log(
|
||||
`[AgentRegistry] Initialized with ${this.agents.size} agents.`,
|
||||
);
|
||||
}
|
||||
@@ -72,14 +73,14 @@ export class AgentRegistry {
|
||||
): void {
|
||||
// Basic validation
|
||||
if (!definition.name || !definition.description) {
|
||||
console.warn(
|
||||
debugLogger.warn(
|
||||
`[AgentRegistry] Skipping invalid agent definition. Missing name or description.`,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.agents.has(definition.name) && this.config.getDebugMode()) {
|
||||
console.log(`[AgentRegistry] Overriding agent '${definition.name}'`);
|
||||
debugLogger.log(`[AgentRegistry] Overriding agent '${definition.name}'`);
|
||||
}
|
||||
|
||||
this.agents.set(definition.name, definition);
|
||||
|
||||
@@ -25,6 +25,7 @@ import readline from 'node:readline';
|
||||
import { Storage } from '../config/storage.js';
|
||||
import { OAuthCredentialStorage } from './oauth-credential-storage.js';
|
||||
import { FORCE_ENCRYPTED_FILE_ENV_VAR } from '../mcp/token-storage/index.js';
|
||||
import { debugLogger } from '../utils/debugLogger.js';
|
||||
|
||||
const userAccountManager = new UserAccountManager();
|
||||
|
||||
@@ -110,10 +111,10 @@ async function initOauthClient(
|
||||
await fetchAndCacheUserInfo(client);
|
||||
} catch (error) {
|
||||
// Non-fatal, continue with existing auth.
|
||||
console.warn('Failed to fetch user info:', getErrorMessage(error));
|
||||
debugLogger.warn('Failed to fetch user info:', getErrorMessage(error));
|
||||
}
|
||||
}
|
||||
console.log('Loaded cached credentials.');
|
||||
debugLogger.log('Loaded cached credentials.');
|
||||
return client;
|
||||
}
|
||||
|
||||
@@ -122,13 +123,13 @@ async function initOauthClient(
|
||||
// the identity of the user logged into Cloud Shell.
|
||||
if (authType === AuthType.CLOUD_SHELL) {
|
||||
try {
|
||||
console.log("Attempting to authenticate via Cloud Shell VM's ADC.");
|
||||
debugLogger.log("Attempting to authenticate via Cloud Shell VM's ADC.");
|
||||
const computeClient = new Compute({
|
||||
// We can leave this empty, since the metadata server will provide
|
||||
// the service account email.
|
||||
});
|
||||
await computeClient.getAccessToken();
|
||||
console.log('Authentication successful.');
|
||||
debugLogger.log('Authentication successful.');
|
||||
|
||||
// Do not cache creds in this case; note that Compute client will handle its own refresh
|
||||
return computeClient;
|
||||
@@ -161,7 +162,7 @@ async function initOauthClient(
|
||||
} else {
|
||||
const webLogin = await authWithWeb(client);
|
||||
|
||||
console.log(
|
||||
debugLogger.log(
|
||||
`\n\nCode Assist login required.\n` +
|
||||
`Attempting to open authentication page in your browser.\n` +
|
||||
`Otherwise navigate to:\n\n${webLogin.authUrl}\n\n`,
|
||||
@@ -193,7 +194,7 @@ async function initOauthClient(
|
||||
`Failed to open browser: ${getErrorMessage(err)}`,
|
||||
);
|
||||
}
|
||||
console.log('Waiting for authentication...');
|
||||
debugLogger.log('Waiting for authentication...');
|
||||
|
||||
// Add timeout to prevent infinite waiting when browser tab gets stuck
|
||||
const authTimeout = 5 * 60 * 1000; // 5 minutes timeout
|
||||
@@ -236,10 +237,12 @@ async function authWithUserCode(client: OAuth2Client): Promise<boolean> {
|
||||
code_challenge: codeVerifier.codeChallenge,
|
||||
state,
|
||||
});
|
||||
console.log('Please visit the following URL to authorize the application:');
|
||||
console.log('');
|
||||
console.log(authUrl);
|
||||
console.log('');
|
||||
debugLogger.log(
|
||||
'Please visit the following URL to authorize the application:',
|
||||
);
|
||||
debugLogger.log('');
|
||||
debugLogger.log(authUrl);
|
||||
debugLogger.log('');
|
||||
|
||||
const code = await new Promise<string>((resolve) => {
|
||||
const rl = readline.createInterface({
|
||||
@@ -337,7 +340,7 @@ async function authWithWeb(client: OAuth2Client): Promise<OauthWebLogin> {
|
||||
try {
|
||||
await fetchAndCacheUserInfo(client);
|
||||
} catch (error) {
|
||||
console.warn(
|
||||
debugLogger.warn(
|
||||
'Failed to retrieve Google Account ID during authentication:',
|
||||
getErrorMessage(error),
|
||||
);
|
||||
@@ -462,7 +465,7 @@ async function loadCachedCredentials(client: OAuth2Client): Promise<boolean> {
|
||||
return true;
|
||||
} catch (error) {
|
||||
// Log specific error for debugging, but continue trying other paths
|
||||
console.debug(
|
||||
debugLogger.debug(
|
||||
`Failed to load credentials from ${keyFile}:`,
|
||||
getErrorMessage(error),
|
||||
);
|
||||
|
||||
@@ -157,6 +157,7 @@ import {
|
||||
DEFAULT_FILE_FILTERING_OPTIONS,
|
||||
DEFAULT_MEMORY_FILE_FILTERING_OPTIONS,
|
||||
} from './constants.js';
|
||||
import { debugLogger } from '../utils/debugLogger.js';
|
||||
|
||||
export type { FileFilteringOptions };
|
||||
export {
|
||||
@@ -1123,7 +1124,7 @@ export class Config {
|
||||
// the tool registry.
|
||||
const messageBusEnabled = this.getEnableMessageBusIntegration();
|
||||
if (this.debugMode && messageBusEnabled) {
|
||||
console.log(
|
||||
debugLogger.log(
|
||||
`[DEBUG] enableMessageBusIntegration setting: ${messageBusEnabled}`,
|
||||
);
|
||||
}
|
||||
@@ -1131,7 +1132,7 @@ export class Config {
|
||||
? [...args, this.getMessageBus()]
|
||||
: args;
|
||||
if (this.debugMode && messageBusEnabled) {
|
||||
console.log(
|
||||
debugLogger.log(
|
||||
`[DEBUG] Registering ${className} with messageBus: ${messageBusEnabled ? 'YES' : 'NO'}`,
|
||||
);
|
||||
}
|
||||
@@ -1206,7 +1207,7 @@ export class Config {
|
||||
);
|
||||
}
|
||||
} else if (this.getDebugMode()) {
|
||||
console.log(
|
||||
debugLogger.log(
|
||||
`[Config] Skipping registration of agent '${definition.name}' due to allow/exclude configuration.`,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1385,34 +1385,11 @@ ${JSON.stringify(
|
||||
// Assert
|
||||
expect(finalResult).toBeInstanceOf(Turn);
|
||||
|
||||
// Debug: Check how many times checkNextSpeaker was called
|
||||
const callCount = mockCheckNextSpeaker.mock.calls.length;
|
||||
|
||||
// If infinite loop protection is working, checkNextSpeaker should be called many times
|
||||
// but stop at MAX_TURNS (100). Since each recursive call should trigger checkNextSpeaker,
|
||||
// we expect it to be called multiple times before hitting the limit
|
||||
expect(mockCheckNextSpeaker).toHaveBeenCalled();
|
||||
|
||||
// The test should demonstrate that the infinite loop protection works:
|
||||
// - If checkNextSpeaker is called many times (close to MAX_TURNS), it shows the loop was happening
|
||||
// - If it's only called once, the recursive behavior might not be triggered
|
||||
if (callCount === 0) {
|
||||
throw new Error(
|
||||
'checkNextSpeaker was never called - the recursive condition was not met',
|
||||
);
|
||||
} else if (callCount === 1) {
|
||||
// This might be expected behavior if the turn has pending tool calls or other conditions prevent recursion
|
||||
console.log(
|
||||
'checkNextSpeaker called only once - no infinite loop occurred',
|
||||
);
|
||||
} else {
|
||||
console.log(
|
||||
`checkNextSpeaker called ${callCount} times - infinite loop protection worked`,
|
||||
);
|
||||
// If called multiple times, we expect it to be stopped before MAX_TURNS
|
||||
expect(callCount).toBeLessThanOrEqual(100); // Should not exceed MAX_TURNS
|
||||
}
|
||||
|
||||
// The stream should produce events and eventually terminate
|
||||
expect(eventCount).toBeGreaterThanOrEqual(1);
|
||||
expect(eventCount).toBeLessThan(200); // Should not exceed our safety limit
|
||||
@@ -1537,11 +1514,6 @@ ${JSON.stringify(
|
||||
// the loop should stop at MAX_TURNS (100)
|
||||
expect(callCount).toBeLessThanOrEqual(100); // Should not exceed MAX_TURNS
|
||||
expect(eventCount).toBeLessThanOrEqual(200); // Should have reasonable number of events
|
||||
|
||||
console.log(
|
||||
`Infinite loop protection working: checkNextSpeaker called ${callCount} times, ` +
|
||||
`${eventCount} events generated (properly bounded by MAX_TURNS)`,
|
||||
);
|
||||
});
|
||||
|
||||
it('should yield ContextWindowWillOverflow when the context window is about to overflow', async () => {
|
||||
|
||||
@@ -52,6 +52,7 @@ import type { IdeContext, File } from '../ide/types.js';
|
||||
import { handleFallback } from '../fallback/handler.js';
|
||||
import type { RoutingContext } from '../routing/routingStrategy.js';
|
||||
import { uiTelemetryService } from '../telemetry/uiTelemetry.js';
|
||||
import { debugLogger } from '../utils/debugLogger.js';
|
||||
|
||||
export function isThinkingSupported(model: string) {
|
||||
return model.startsWith('gemini-2.5') || model === DEFAULT_GEMINI_MODEL_AUTO;
|
||||
@@ -341,7 +342,7 @@ My setup is complete. I will provide my first command in the next turn.
|
||||
];
|
||||
|
||||
if (this.config.getDebugMode()) {
|
||||
console.log(contextParts.join('\n'));
|
||||
debugLogger.log(contextParts.join('\n'));
|
||||
}
|
||||
return {
|
||||
contextParts,
|
||||
@@ -451,7 +452,7 @@ My setup is complete. I will provide my first command in the next turn.
|
||||
];
|
||||
|
||||
if (this.config.getDebugMode()) {
|
||||
console.log(contextParts.join('\n'));
|
||||
debugLogger.log(contextParts.join('\n'));
|
||||
}
|
||||
return {
|
||||
contextParts,
|
||||
|
||||
@@ -8,6 +8,7 @@ import path from 'node:path';
|
||||
import { promises as fs } from 'node:fs';
|
||||
import type { Content } from '@google/genai';
|
||||
import type { Storage } from '../config/storage.js';
|
||||
import { debugLogger } from '../utils/debugLogger.js';
|
||||
|
||||
const LOG_FILE_NAME = 'logs.json';
|
||||
|
||||
@@ -82,7 +83,7 @@ export class Logger {
|
||||
const fileContent = await fs.readFile(this.logFilePath, 'utf-8');
|
||||
const parsedLogs = JSON.parse(fileContent);
|
||||
if (!Array.isArray(parsedLogs)) {
|
||||
console.debug(
|
||||
debugLogger.debug(
|
||||
`Log file at ${this.logFilePath} is not a valid JSON array. Starting with empty logs.`,
|
||||
);
|
||||
await this._backupCorruptedLogFile('malformed_array');
|
||||
@@ -102,14 +103,14 @@ export class Logger {
|
||||
return [];
|
||||
}
|
||||
if (error instanceof SyntaxError) {
|
||||
console.debug(
|
||||
debugLogger.debug(
|
||||
`Invalid JSON in log file ${this.logFilePath}. Backing up and starting fresh.`,
|
||||
error,
|
||||
);
|
||||
await this._backupCorruptedLogFile('invalid_json');
|
||||
return [];
|
||||
}
|
||||
console.debug(
|
||||
debugLogger.debug(
|
||||
`Failed to read or parse log file ${this.logFilePath}:`,
|
||||
error,
|
||||
);
|
||||
@@ -122,7 +123,7 @@ export class Logger {
|
||||
const backupPath = `${this.logFilePath}.${reason}.${Date.now()}.bak`;
|
||||
try {
|
||||
await fs.rename(this.logFilePath, backupPath);
|
||||
console.debug(`Backed up corrupted log file to ${backupPath}`);
|
||||
debugLogger.debug(`Backed up corrupted log file to ${backupPath}`);
|
||||
} catch (_backupError) {
|
||||
// If rename fails (e.g. file doesn't exist), no need to log an error here as the primary error (e.g. invalid JSON) is already handled.
|
||||
}
|
||||
@@ -166,7 +167,7 @@ export class Logger {
|
||||
entryToAppend: LogEntry,
|
||||
): Promise<LogEntry | null> {
|
||||
if (!this.logFilePath) {
|
||||
console.debug('Log file path not set. Cannot persist log entry.');
|
||||
debugLogger.debug('Log file path not set. Cannot persist log entry.');
|
||||
throw new Error('Log file path not set during update attempt.');
|
||||
}
|
||||
|
||||
@@ -174,7 +175,7 @@ export class Logger {
|
||||
try {
|
||||
currentLogsOnDisk = await this._readLogFile();
|
||||
} catch (readError) {
|
||||
console.debug(
|
||||
debugLogger.debug(
|
||||
'Critical error reading log file before append:',
|
||||
readError,
|
||||
);
|
||||
@@ -205,7 +206,7 @@ export class Logger {
|
||||
);
|
||||
|
||||
if (entryExists) {
|
||||
console.debug(
|
||||
debugLogger.debug(
|
||||
`Duplicate log entry detected and skipped: session ${entryToAppend.sessionId}, messageId ${entryToAppend.messageId}`,
|
||||
);
|
||||
this.logs = currentLogsOnDisk; // Ensure in-memory is synced with disk
|
||||
@@ -223,7 +224,7 @@ export class Logger {
|
||||
this.logs = currentLogsOnDisk;
|
||||
return entryToAppend; // Return the successfully appended entry
|
||||
} catch (error) {
|
||||
console.debug('Error writing to log file:', error);
|
||||
debugLogger.debug('Error writing to log file:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
@@ -242,7 +243,7 @@ export class Logger {
|
||||
|
||||
async logMessage(type: MessageSenderType, message: string): Promise<void> {
|
||||
if (!this.initialized || this.sessionId === undefined) {
|
||||
console.debug(
|
||||
debugLogger.debug(
|
||||
'Logger not initialized or session ID missing. Cannot log message.',
|
||||
);
|
||||
return;
|
||||
@@ -341,7 +342,7 @@ export class Logger {
|
||||
const fileContent = await fs.readFile(path, 'utf-8');
|
||||
const parsedContent = JSON.parse(fileContent);
|
||||
if (!Array.isArray(parsedContent)) {
|
||||
console.warn(
|
||||
debugLogger.warn(
|
||||
`Checkpoint file at ${path} is not a valid JSON array. Returning empty checkpoint.`,
|
||||
);
|
||||
return [];
|
||||
|
||||
@@ -22,6 +22,7 @@ import { isGitRepository } from '../utils/gitUtils.js';
|
||||
import { CodebaseInvestigatorAgent } from '../agents/codebase-investigator.js';
|
||||
import type { Config } from '../config/config.js';
|
||||
import { GEMINI_DIR } from '../utils/paths.js';
|
||||
import { debugLogger } from '../utils/debugLogger.js';
|
||||
|
||||
export function resolvePathFromEnv(envVar?: string): {
|
||||
isSwitch: boolean;
|
||||
@@ -56,7 +57,7 @@ export function resolvePathFromEnv(envVar?: string): {
|
||||
}
|
||||
} catch (error) {
|
||||
// If os.homedir() fails, we catch the error instead of crashing.
|
||||
console.warn(
|
||||
debugLogger.warn(
|
||||
`Could not resolve home directory for path: ${trimmedEnvVar}`,
|
||||
error,
|
||||
);
|
||||
|
||||
@@ -24,10 +24,11 @@ import * as path from 'node:path';
|
||||
import { EnvHttpProxyAgent } from 'undici';
|
||||
import { ListToolsResultSchema } from '@modelcontextprotocol/sdk/types.js';
|
||||
import { IDE_REQUEST_TIMEOUT_MS } from './constants.js';
|
||||
import { debugLogger } from '../utils/debugLogger.js';
|
||||
|
||||
const logger = {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
debug: (...args: any[]) => console.debug('[DEBUG] [IDEClient]', ...args),
|
||||
debug: (...args: any[]) => debugLogger.debug('[DEBUG] [IDEClient]', ...args),
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
error: (...args: any[]) => console.error('[ERROR] [IDEClient]', ...args),
|
||||
};
|
||||
|
||||
@@ -13,6 +13,7 @@ import type { OAuthToken } from './token-storage/types.js';
|
||||
import { MCPOAuthTokenStorage } from './oauth-token-storage.js';
|
||||
import { getErrorMessage } from '../utils/errors.js';
|
||||
import { OAuthUtils } from './oauth-utils.js';
|
||||
import { debugLogger } from '../utils/debugLogger.js';
|
||||
|
||||
export const OAUTH_DISPLAY_MESSAGE_EVENT = 'oauth-display-message' as const;
|
||||
|
||||
@@ -258,7 +259,9 @@ export class MCPOAuthProvider {
|
||||
|
||||
server.on('error', reject);
|
||||
server.listen(REDIRECT_PORT, () => {
|
||||
console.log(`OAuth callback server listening on port ${REDIRECT_PORT}`);
|
||||
debugLogger.log(
|
||||
`OAuth callback server listening on port ${REDIRECT_PORT}`,
|
||||
);
|
||||
});
|
||||
|
||||
// Timeout after 5 minutes
|
||||
@@ -314,7 +317,7 @@ export class MCPOAuthProvider {
|
||||
OAuthUtils.buildResourceParameter(mcpServerUrl),
|
||||
);
|
||||
} catch (error) {
|
||||
console.warn(
|
||||
debugLogger.warn(
|
||||
`Could not add resource parameter: ${getErrorMessage(error)}`,
|
||||
);
|
||||
}
|
||||
@@ -371,7 +374,7 @@ export class MCPOAuthProvider {
|
||||
OAuthUtils.buildResourceParameter(resourceUrl),
|
||||
);
|
||||
} catch (error) {
|
||||
console.warn(
|
||||
debugLogger.warn(
|
||||
`Could not add resource parameter: ${getErrorMessage(error)}`,
|
||||
);
|
||||
}
|
||||
@@ -413,7 +416,7 @@ export class MCPOAuthProvider {
|
||||
!contentType.includes('application/json') &&
|
||||
!contentType.includes('application/x-www-form-urlencoded')
|
||||
) {
|
||||
console.warn(
|
||||
debugLogger.warn(
|
||||
`Token endpoint returned unexpected content-type: ${contentType}. ` +
|
||||
`Expected application/json or application/x-www-form-urlencoded. ` +
|
||||
`Will attempt to parse response.`,
|
||||
@@ -493,7 +496,7 @@ export class MCPOAuthProvider {
|
||||
OAuthUtils.buildResourceParameter(mcpServerUrl),
|
||||
);
|
||||
} catch (error) {
|
||||
console.warn(
|
||||
debugLogger.warn(
|
||||
`Could not add resource parameter: ${getErrorMessage(error)}`,
|
||||
);
|
||||
}
|
||||
@@ -535,7 +538,7 @@ export class MCPOAuthProvider {
|
||||
!contentType.includes('application/json') &&
|
||||
!contentType.includes('application/x-www-form-urlencoded')
|
||||
) {
|
||||
console.warn(
|
||||
debugLogger.warn(
|
||||
`Token refresh endpoint returned unexpected content-type: ${contentType}. ` +
|
||||
`Expected application/json or application/x-www-form-urlencoded. ` +
|
||||
`Will attempt to parse response.`,
|
||||
@@ -593,13 +596,13 @@ export class MCPOAuthProvider {
|
||||
if (events) {
|
||||
events.emit(OAUTH_DISPLAY_MESSAGE_EVENT, message);
|
||||
} else {
|
||||
console.log(message);
|
||||
debugLogger.log(message);
|
||||
}
|
||||
};
|
||||
|
||||
// If no authorization URL is provided, try to discover OAuth configuration
|
||||
if (!config.authorizationUrl && mcpServerUrl) {
|
||||
console.debug(`Starting OAuth for MCP server "${serverName}"…
|
||||
debugLogger.debug(`Starting OAuth for MCP server "${serverName}"…
|
||||
✓ No authorization URL; using OAuth discovery`);
|
||||
|
||||
// First check if the server requires authentication via WWW-Authenticate header
|
||||
@@ -636,7 +639,7 @@ export class MCPOAuthProvider {
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.debug(
|
||||
debugLogger.debug(
|
||||
`Failed to check endpoint for authentication requirements: ${getErrorMessage(error)}`,
|
||||
);
|
||||
}
|
||||
@@ -681,7 +684,7 @@ export class MCPOAuthProvider {
|
||||
const authUrl = new URL(config.authorizationUrl);
|
||||
const serverUrl = `${authUrl.protocol}//${authUrl.host}`;
|
||||
|
||||
console.debug('→ Attempting dynamic client registration...');
|
||||
debugLogger.debug('→ Attempting dynamic client registration...');
|
||||
|
||||
// Get the authorization server metadata for registration
|
||||
const authServerMetadata =
|
||||
@@ -707,7 +710,7 @@ export class MCPOAuthProvider {
|
||||
config.clientSecret = clientRegistration.client_secret;
|
||||
}
|
||||
|
||||
console.debug('✓ Dynamic client registration successful');
|
||||
debugLogger.debug('✓ Dynamic client registration successful');
|
||||
} else {
|
||||
throw new Error(
|
||||
'No client ID provided and dynamic registration not supported',
|
||||
@@ -747,7 +750,7 @@ ${authUrl}
|
||||
try {
|
||||
await openBrowserSecurely(authUrl);
|
||||
} catch (error) {
|
||||
console.warn(
|
||||
debugLogger.warn(
|
||||
'Failed to open browser automatically:',
|
||||
getErrorMessage(error),
|
||||
);
|
||||
@@ -756,7 +759,9 @@ ${authUrl}
|
||||
// Wait for callback
|
||||
const { code } = await callbackPromise;
|
||||
|
||||
console.debug('✓ Authorization code received, exchanging for tokens...');
|
||||
debugLogger.debug(
|
||||
'✓ Authorization code received, exchanging for tokens...',
|
||||
);
|
||||
|
||||
// Exchange code for tokens
|
||||
const tokenResponse = await this.exchangeCodeForToken(
|
||||
@@ -791,7 +796,7 @@ ${authUrl}
|
||||
config.tokenUrl,
|
||||
mcpServerUrl,
|
||||
);
|
||||
console.debug('✓ Authentication successful! Token saved.');
|
||||
debugLogger.debug('✓ Authentication successful! Token saved.');
|
||||
|
||||
// Verify token was saved
|
||||
const savedToken = await this.tokenStorage.getCredentials(serverName);
|
||||
@@ -802,7 +807,7 @@ ${authUrl}
|
||||
.update(savedToken.token.accessToken)
|
||||
.digest('hex')
|
||||
.slice(0, 8);
|
||||
console.debug(
|
||||
debugLogger.debug(
|
||||
`✓ Token verification successful (fingerprint: ${tokenFingerprint})`,
|
||||
);
|
||||
} else {
|
||||
@@ -829,29 +834,31 @@ ${authUrl}
|
||||
serverName: string,
|
||||
config: MCPOAuthConfig,
|
||||
): Promise<string | null> {
|
||||
console.debug(`Getting valid token for server: ${serverName}`);
|
||||
debugLogger.debug(`Getting valid token for server: ${serverName}`);
|
||||
const credentials = await this.tokenStorage.getCredentials(serverName);
|
||||
|
||||
if (!credentials) {
|
||||
console.debug(`No credentials found for server: ${serverName}`);
|
||||
debugLogger.debug(`No credentials found for server: ${serverName}`);
|
||||
return null;
|
||||
}
|
||||
|
||||
const { token } = credentials;
|
||||
console.debug(
|
||||
debugLogger.debug(
|
||||
`Found token for server: ${serverName}, expired: ${this.tokenStorage.isTokenExpired(token)}`,
|
||||
);
|
||||
|
||||
// Check if token is expired
|
||||
if (!this.tokenStorage.isTokenExpired(token)) {
|
||||
console.debug(`Returning valid token for server: ${serverName}`);
|
||||
debugLogger.debug(`Returning valid token for server: ${serverName}`);
|
||||
return token.accessToken;
|
||||
}
|
||||
|
||||
// Try to refresh if we have a refresh token
|
||||
if (token.refreshToken && config.clientId && credentials.tokenUrl) {
|
||||
try {
|
||||
console.log(`Refreshing expired token for MCP server: ${serverName}`);
|
||||
debugLogger.log(
|
||||
`Refreshing expired token for MCP server: ${serverName}`,
|
||||
);
|
||||
|
||||
const newTokenResponse = await this.refreshAccessToken(
|
||||
config,
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
import type { MCPOAuthConfig } from './oauth-provider.js';
|
||||
import { getErrorMessage } from '../utils/errors.js';
|
||||
import { debugLogger } from '../utils/debugLogger.js';
|
||||
|
||||
/**
|
||||
* OAuth authorization server metadata as per RFC 8414.
|
||||
@@ -94,7 +95,7 @@ export class OAuthUtils {
|
||||
}
|
||||
return (await response.json()) as OAuthProtectedResourceMetadata;
|
||||
} catch (error) {
|
||||
console.debug(
|
||||
debugLogger.debug(
|
||||
`Failed to fetch protected resource metadata from ${resourceMetadataUrl}: ${getErrorMessage(error)}`,
|
||||
);
|
||||
return null;
|
||||
@@ -117,7 +118,7 @@ export class OAuthUtils {
|
||||
}
|
||||
return (await response.json()) as OAuthAuthorizationServerMetadata;
|
||||
} catch (error) {
|
||||
console.debug(
|
||||
debugLogger.debug(
|
||||
`Failed to fetch authorization server metadata from ${authServerMetadataUrl}: ${getErrorMessage(error)}`,
|
||||
);
|
||||
return null;
|
||||
@@ -205,7 +206,7 @@ export class OAuthUtils {
|
||||
}
|
||||
}
|
||||
|
||||
console.debug(
|
||||
debugLogger.debug(
|
||||
`Metadata discovery failed for authorization server ${authServerUrl}`,
|
||||
);
|
||||
return null;
|
||||
@@ -249,7 +250,7 @@ export class OAuthUtils {
|
||||
if (authServerMetadata) {
|
||||
const config = this.metadataToOAuthConfig(authServerMetadata);
|
||||
if (authServerMetadata.registration_endpoint) {
|
||||
console.log(
|
||||
debugLogger.log(
|
||||
'Dynamic client registration is supported at:',
|
||||
authServerMetadata.registration_endpoint,
|
||||
);
|
||||
@@ -259,14 +260,14 @@ export class OAuthUtils {
|
||||
}
|
||||
|
||||
// Fallback: try well-known endpoints at the base URL
|
||||
console.debug(`Trying OAuth discovery fallback at ${serverUrl}`);
|
||||
debugLogger.debug(`Trying OAuth discovery fallback at ${serverUrl}`);
|
||||
const authServerMetadata =
|
||||
await this.discoverAuthorizationServerMetadata(serverUrl);
|
||||
|
||||
if (authServerMetadata) {
|
||||
const config = this.metadataToOAuthConfig(authServerMetadata);
|
||||
if (authServerMetadata.registration_endpoint) {
|
||||
console.log(
|
||||
debugLogger.log(
|
||||
'Dynamic client registration is supported at:',
|
||||
authServerMetadata.registration_endpoint,
|
||||
);
|
||||
@@ -276,7 +277,7 @@ export class OAuthUtils {
|
||||
|
||||
return null;
|
||||
} catch (error) {
|
||||
console.debug(
|
||||
debugLogger.debug(
|
||||
`Failed to discover OAuth configuration: ${getErrorMessage(error)}`,
|
||||
);
|
||||
return null;
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
*/
|
||||
|
||||
import type { DiscoveredMCPPrompt } from '../tools/mcp-client.js';
|
||||
import { debugLogger } from '../utils/debugLogger.js';
|
||||
|
||||
export class PromptRegistry {
|
||||
private prompts: Map<string, DiscoveredMCPPrompt> = new Map();
|
||||
@@ -16,7 +17,7 @@ export class PromptRegistry {
|
||||
registerPrompt(prompt: DiscoveredMCPPrompt): void {
|
||||
if (this.prompts.has(prompt.name)) {
|
||||
const newName = `${prompt.serverName}_${prompt.name}`;
|
||||
console.warn(
|
||||
debugLogger.warn(
|
||||
`Prompt with name "${prompt.name}" is already registered. Renaming to "${newName}".`,
|
||||
);
|
||||
this.prompts.set(newName, { ...prompt, name: newName });
|
||||
|
||||
@@ -27,6 +27,7 @@ import {
|
||||
isFunctionCall,
|
||||
isFunctionResponse,
|
||||
} from '../../utils/messageInspectors.js';
|
||||
import { debugLogger } from '../../utils/debugLogger.js';
|
||||
|
||||
const CLASSIFIER_GENERATION_CONFIG: GenerateContentConfig = {
|
||||
temperature: 0,
|
||||
@@ -153,7 +154,7 @@ export class ClassifierStrategy implements RoutingStrategy {
|
||||
promptId = `classifier-router-fallback-${Date.now()}-${Math.random()
|
||||
.toString(16)
|
||||
.slice(2)}`;
|
||||
console.warn(
|
||||
debugLogger.warn(
|
||||
`Could not find promptId in context. This is unexpected. Using a fallback ID: ${promptId}`,
|
||||
);
|
||||
}
|
||||
@@ -206,7 +207,7 @@ export class ClassifierStrategy implements RoutingStrategy {
|
||||
} catch (error) {
|
||||
// If the classifier fails for any reason (API error, parsing error, etc.),
|
||||
// we log it and return null to allow the composite strategy to proceed.
|
||||
console.warn(`[Routing] ClassifierStrategy failed:`, error);
|
||||
debugLogger.warn(`[Routing] ClassifierStrategy failed:`, error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import {
|
||||
isFunctionCall,
|
||||
isFunctionResponse,
|
||||
} from '../utils/messageInspectors.js';
|
||||
import { debugLogger } from '../utils/debugLogger.js';
|
||||
|
||||
const TOOL_CALL_LOOP_THRESHOLD = 5;
|
||||
const CONTENT_LOOP_THRESHOLD = 10;
|
||||
@@ -431,14 +432,14 @@ export class LoopDetectionService {
|
||||
});
|
||||
} catch (e) {
|
||||
// Do nothing, treat it as a non-loop.
|
||||
this.config.getDebugMode() ? console.error(e) : console.debug(e);
|
||||
this.config.getDebugMode() ? console.error(e) : debugLogger.debug(e);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (typeof result['confidence'] === 'number') {
|
||||
if (result['confidence'] > 0.9) {
|
||||
if (typeof result['reasoning'] === 'string' && result['reasoning']) {
|
||||
console.warn(result['reasoning']);
|
||||
debugLogger.warn(result['reasoning']);
|
||||
}
|
||||
logLoopDetected(
|
||||
this.config,
|
||||
|
||||
@@ -8,6 +8,7 @@ import type { Config } from '../config/config.js';
|
||||
import { isPerformanceMonitoringActive } from './metrics.js';
|
||||
import { getMemoryMonitor } from './memory-monitor.js';
|
||||
import { ActivityType } from './activity-types.js';
|
||||
import { debugLogger } from '../utils/debugLogger.js';
|
||||
|
||||
/**
|
||||
* Activity event data structure
|
||||
@@ -152,7 +153,7 @@ export class ActivityMonitor {
|
||||
listener(event);
|
||||
} catch (error) {
|
||||
// Silently catch listener errors to avoid disrupting the application
|
||||
console.debug('ActivityMonitor listener error:', error);
|
||||
debugLogger.debug('ActivityMonitor listener error:', error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -53,6 +53,7 @@ import {
|
||||
detectIdeFromEnv,
|
||||
isCloudShell,
|
||||
} from '../../ide/detect-ide.js';
|
||||
import { debugLogger } from '../../utils/debugLogger.js';
|
||||
|
||||
export enum EventNames {
|
||||
START_SESSION = 'start_session',
|
||||
@@ -238,7 +239,7 @@ export class ClearcutLogger {
|
||||
]);
|
||||
|
||||
if (wasAtCapacity && this.config?.getDebugMode()) {
|
||||
console.debug(
|
||||
debugLogger.debug(
|
||||
`ClearcutLogger: Dropped old event to prevent memory leak (queue size: ${this.events.size})`,
|
||||
);
|
||||
}
|
||||
@@ -282,14 +283,14 @@ export class ClearcutLogger {
|
||||
}
|
||||
|
||||
this.flushToClearcut().catch((error) => {
|
||||
console.debug('Error flushing to Clearcut:', error);
|
||||
debugLogger.debug('Error flushing to Clearcut:', error);
|
||||
});
|
||||
}
|
||||
|
||||
async flushToClearcut(): Promise<LogResponse> {
|
||||
if (this.flushing) {
|
||||
if (this.config?.getDebugMode()) {
|
||||
console.debug(
|
||||
debugLogger.debug(
|
||||
'ClearcutLogger: Flush already in progress, marking pending flush.',
|
||||
);
|
||||
}
|
||||
@@ -299,7 +300,7 @@ export class ClearcutLogger {
|
||||
this.flushing = true;
|
||||
|
||||
if (this.config?.getDebugMode()) {
|
||||
console.log('Flushing log events to Clearcut.');
|
||||
debugLogger.log('Flushing log events to Clearcut.');
|
||||
}
|
||||
const eventsToSend = this.events.toArray() as LogEventEntry[][];
|
||||
this.events.clear();
|
||||
@@ -359,7 +360,7 @@ export class ClearcutLogger {
|
||||
// Fire and forget the pending flush
|
||||
this.flushToClearcut().catch((error) => {
|
||||
if (this.config?.getDebugMode()) {
|
||||
console.debug('Error in pending flush to Clearcut:', error);
|
||||
debugLogger.debug('Error in pending flush to Clearcut:', error);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -451,7 +452,7 @@ export class ClearcutLogger {
|
||||
// Flush start event immediately
|
||||
this.enqueueLogEvent(this.createLogEvent(EventNames.START_SESSION, data));
|
||||
this.flushToClearcut().catch((error) => {
|
||||
console.debug('Error flushing to Clearcut:', error);
|
||||
debugLogger.debug('Error flushing to Clearcut:', error);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -668,14 +669,14 @@ export class ClearcutLogger {
|
||||
logFlashFallbackEvent(): void {
|
||||
this.enqueueLogEvent(this.createLogEvent(EventNames.FLASH_FALLBACK, []));
|
||||
this.flushToClearcut().catch((error) => {
|
||||
console.debug('Error flushing to Clearcut:', error);
|
||||
debugLogger.debug('Error flushing to Clearcut:', error);
|
||||
});
|
||||
}
|
||||
|
||||
logRipgrepFallbackEvent(): void {
|
||||
this.enqueueLogEvent(this.createLogEvent(EventNames.RIPGREP_FALLBACK, []));
|
||||
this.flushToClearcut().catch((error) => {
|
||||
console.debug('Error flushing to Clearcut:', error);
|
||||
debugLogger.debug('Error flushing to Clearcut:', error);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -811,7 +812,7 @@ export class ClearcutLogger {
|
||||
// Flush immediately on session end.
|
||||
this.enqueueLogEvent(this.createLogEvent(EventNames.END_SESSION, []));
|
||||
this.flushToClearcut().catch((error) => {
|
||||
console.debug('Error flushing to Clearcut:', error);
|
||||
debugLogger.debug('Error flushing to Clearcut:', error);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -910,7 +911,7 @@ export class ClearcutLogger {
|
||||
this.createLogEvent(EventNames.EXTENSION_INSTALL, data),
|
||||
);
|
||||
this.flushToClearcut().catch((error) => {
|
||||
console.debug('Error flushing to Clearcut:', error);
|
||||
debugLogger.debug('Error flushing to Clearcut:', error);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -930,7 +931,7 @@ export class ClearcutLogger {
|
||||
this.createLogEvent(EventNames.EXTENSION_UNINSTALL, data),
|
||||
);
|
||||
this.flushToClearcut().catch((error) => {
|
||||
console.debug('Error flushing to Clearcut:', error);
|
||||
debugLogger.debug('Error flushing to Clearcut:', error);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -962,7 +963,7 @@ export class ClearcutLogger {
|
||||
this.createLogEvent(EventNames.EXTENSION_UPDATE, data),
|
||||
);
|
||||
this.flushToClearcut().catch((error) => {
|
||||
console.debug('Error flushing to Clearcut:', error);
|
||||
debugLogger.debug('Error flushing to Clearcut:', error);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1047,7 +1048,7 @@ export class ClearcutLogger {
|
||||
this.createLogEvent(EventNames.EXTENSION_ENABLE, data),
|
||||
);
|
||||
this.flushToClearcut().catch((error) => {
|
||||
console.debug('Error flushing to Clearcut:', error);
|
||||
debugLogger.debug('Error flushing to Clearcut:', error);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1082,7 +1083,7 @@ export class ClearcutLogger {
|
||||
this.createLogEvent(EventNames.EXTENSION_DISABLE, data),
|
||||
);
|
||||
this.flushToClearcut().catch((error) => {
|
||||
console.debug('Error flushing to Clearcut:', error);
|
||||
debugLogger.debug('Error flushing to Clearcut:', error);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1240,7 +1241,7 @@ export class ClearcutLogger {
|
||||
|
||||
getConfigJson() {
|
||||
const configJson = safeJsonStringifyBooleanValuesOnly(this.config);
|
||||
console.debug(configJson);
|
||||
debugLogger.debug(configJson);
|
||||
return safeJsonStringifyBooleanValuesOnly(this.config);
|
||||
}
|
||||
|
||||
@@ -1254,7 +1255,7 @@ export class ClearcutLogger {
|
||||
|
||||
// Log a warning if we're dropping events
|
||||
if (eventsToSend.length > MAX_RETRY_EVENTS && this.config?.getDebugMode()) {
|
||||
console.warn(
|
||||
debugLogger.warn(
|
||||
`ClearcutLogger: Dropping ${
|
||||
eventsToSend.length - MAX_RETRY_EVENTS
|
||||
} events due to retry queue limit. Total events: ${
|
||||
@@ -1269,7 +1270,7 @@ export class ClearcutLogger {
|
||||
|
||||
if (numEventsToRequeue === 0) {
|
||||
if (this.config?.getDebugMode()) {
|
||||
console.debug(
|
||||
debugLogger.debug(
|
||||
`ClearcutLogger: No events re-queued (queue size: ${this.events.size})`,
|
||||
);
|
||||
}
|
||||
@@ -1292,7 +1293,7 @@ export class ClearcutLogger {
|
||||
}
|
||||
|
||||
if (this.config?.getDebugMode()) {
|
||||
console.debug(
|
||||
debugLogger.debug(
|
||||
`ClearcutLogger: Re-queued ${numEventsToRequeue} events for retry (queue size: ${this.events.size})`,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@ import {
|
||||
GcpLogExporter,
|
||||
} from './gcp-exporters.js';
|
||||
import { TelemetryTarget } from './index.js';
|
||||
import { debugLogger } from '../utils/debugLogger.js';
|
||||
|
||||
// For troubleshooting, set the log level to DiagLogLevel.DEBUG
|
||||
diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.INFO);
|
||||
@@ -184,7 +185,7 @@ export function initializeTelemetry(config: Config): void {
|
||||
try {
|
||||
sdk.start();
|
||||
if (config.getDebugMode()) {
|
||||
console.log('OpenTelemetry SDK started successfully.');
|
||||
debugLogger.log('OpenTelemetry SDK started successfully.');
|
||||
}
|
||||
telemetryInitialized = true;
|
||||
initializeMetrics(config);
|
||||
@@ -211,7 +212,7 @@ export async function shutdownTelemetry(config: Config): Promise<void> {
|
||||
ClearcutLogger.getInstance()?.shutdown();
|
||||
await sdk.shutdown();
|
||||
if (config.getDebugMode()) {
|
||||
console.log('OpenTelemetry SDK shut down successfully.');
|
||||
debugLogger.log('OpenTelemetry SDK shut down successfully.');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error shutting down SDK:', error);
|
||||
|
||||
@@ -34,6 +34,7 @@ import type {
|
||||
import { IdeClient } from '../ide/ide-client.js';
|
||||
import { safeLiteralReplace } from '../utils/textUtils.js';
|
||||
import { EDIT_TOOL_NAME, READ_FILE_TOOL_NAME } from './tool-names.js';
|
||||
import { debugLogger } from '../utils/debugLogger.js';
|
||||
|
||||
export function applyReplacement(
|
||||
currentContent: string | null,
|
||||
@@ -255,12 +256,12 @@ class EditToolInvocation implements ToolInvocation<EditToolParams, ToolResult> {
|
||||
throw error;
|
||||
}
|
||||
const errorMsg = error instanceof Error ? error.message : String(error);
|
||||
console.log(`Error preparing edit: ${errorMsg}`);
|
||||
debugLogger.log(`Error preparing edit: ${errorMsg}`);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (editData.error) {
|
||||
console.log(`Error: ${editData.error.display}`);
|
||||
debugLogger.log(`Error: ${editData.error.display}`);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -388,7 +388,7 @@ class GrepToolInvocation extends BaseToolInvocation<
|
||||
});
|
||||
return this.parseGrepOutput(output, absolutePath);
|
||||
} catch (gitError: unknown) {
|
||||
console.debug(
|
||||
debugLogger.debug(
|
||||
`GrepLogic: git grep failed: ${getErrorMessage(
|
||||
gitError,
|
||||
)}. Falling back...`,
|
||||
@@ -397,7 +397,7 @@ class GrepToolInvocation extends BaseToolInvocation<
|
||||
}
|
||||
|
||||
// --- Strategy 2: System grep ---
|
||||
console.debug(
|
||||
debugLogger.debug(
|
||||
'GrepLogic: System grep is being considered as fallback strategy.',
|
||||
);
|
||||
|
||||
@@ -494,7 +494,7 @@ class GrepToolInvocation extends BaseToolInvocation<
|
||||
});
|
||||
return this.parseGrepOutput(output, absolutePath);
|
||||
} catch (grepError: unknown) {
|
||||
console.debug(
|
||||
debugLogger.debug(
|
||||
`GrepLogic: System grep failed: ${getErrorMessage(
|
||||
grepError,
|
||||
)}. Falling back...`,
|
||||
@@ -503,7 +503,7 @@ class GrepToolInvocation extends BaseToolInvocation<
|
||||
}
|
||||
|
||||
// --- Strategy 3: Pure JavaScript Fallback ---
|
||||
console.debug(
|
||||
debugLogger.debug(
|
||||
'GrepLogic: Falling back to JavaScript grep implementation.',
|
||||
);
|
||||
strategyUsed = 'javascript fallback';
|
||||
@@ -541,7 +541,7 @@ class GrepToolInvocation extends BaseToolInvocation<
|
||||
} catch (readError: unknown) {
|
||||
// Ignore errors like permission denied or file gone during read
|
||||
if (!isNodeError(readError) || readError.code !== 'ENOENT') {
|
||||
console.debug(
|
||||
debugLogger.debug(
|
||||
`GrepLogic: Could not read/process ${fileAbsolutePath}: ${getErrorMessage(
|
||||
readError,
|
||||
)}`,
|
||||
|
||||
@@ -41,6 +41,7 @@ import type {
|
||||
WorkspaceContext,
|
||||
} from '../utils/workspaceContext.js';
|
||||
import type { ToolRegistry } from './tool-registry.js';
|
||||
import { debugLogger } from '../utils/debugLogger.js';
|
||||
|
||||
export const MCP_DEFAULT_TIMEOUT_MSEC = 10 * 60 * 1000; // default to 10 minutes
|
||||
|
||||
@@ -321,7 +322,7 @@ async function handleAutomaticOAuth(
|
||||
wwwAuthenticate: string,
|
||||
): Promise<boolean> {
|
||||
try {
|
||||
console.log(`🔐 '${mcpServerName}' requires OAuth authentication`);
|
||||
debugLogger.log(`🔐 '${mcpServerName}' requires OAuth authentication`);
|
||||
|
||||
// Always try to parse the resource metadata URI from the www-authenticate header
|
||||
let oauthConfig;
|
||||
@@ -358,13 +359,13 @@ async function handleAutomaticOAuth(
|
||||
// Perform OAuth authentication
|
||||
// Pass the server URL for proper discovery
|
||||
const serverUrl = mcpServerConfig.httpUrl || mcpServerConfig.url;
|
||||
console.log(
|
||||
debugLogger.log(
|
||||
`Starting OAuth authentication for server '${mcpServerName}'...`,
|
||||
);
|
||||
const authProvider = new MCPOAuthProvider(new MCPOAuthTokenStorage());
|
||||
await authProvider.authenticate(mcpServerName, oauthAuthConfig, serverUrl);
|
||||
|
||||
console.log(
|
||||
debugLogger.log(
|
||||
`OAuth authentication successful for server '${mcpServerName}'`,
|
||||
);
|
||||
return true;
|
||||
@@ -840,12 +841,12 @@ export async function connectToMcpServer(
|
||||
},
|
||||
);
|
||||
if (hasStoredTokens) {
|
||||
console.log(
|
||||
debugLogger.log(
|
||||
`Stored OAuth token for SSE server '${mcpServerName}' was rejected. ` +
|
||||
`Please re-authenticate using: /mcp auth ${mcpServerName}`,
|
||||
);
|
||||
} else {
|
||||
console.log(
|
||||
debugLogger.log(
|
||||
`401 error received for SSE server '${mcpServerName}' without OAuth configuration. ` +
|
||||
`Please authenticate using: /mcp auth ${mcpServerName}`,
|
||||
);
|
||||
@@ -862,7 +863,7 @@ export async function connectToMcpServer(
|
||||
|
||||
// If we didn't get the header from the error string, try to get it from the server
|
||||
if (!wwwAuthenticate && hasNetworkTransport(mcpServerConfig)) {
|
||||
console.log(
|
||||
debugLogger.log(
|
||||
`No www-authenticate header in error, trying to fetch it from server...`,
|
||||
);
|
||||
try {
|
||||
@@ -880,13 +881,13 @@ export async function connectToMcpServer(
|
||||
if (response.status === 401) {
|
||||
wwwAuthenticate = response.headers.get('www-authenticate');
|
||||
if (wwwAuthenticate) {
|
||||
console.log(
|
||||
debugLogger.log(
|
||||
`Found www-authenticate header from server: ${wwwAuthenticate}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
} catch (fetchError) {
|
||||
console.debug(
|
||||
debugLogger.debug(
|
||||
`Failed to fetch www-authenticate header: ${getErrorMessage(
|
||||
fetchError,
|
||||
)}`,
|
||||
@@ -895,7 +896,7 @@ export async function connectToMcpServer(
|
||||
}
|
||||
|
||||
if (wwwAuthenticate) {
|
||||
console.log(
|
||||
debugLogger.log(
|
||||
`Received 401 with www-authenticate header: ${wwwAuthenticate}`,
|
||||
);
|
||||
|
||||
@@ -907,7 +908,7 @@ export async function connectToMcpServer(
|
||||
);
|
||||
if (oauthSuccess) {
|
||||
// Retry connection with OAuth token
|
||||
console.log(
|
||||
debugLogger.log(
|
||||
`Retrying connection to '${mcpServerName}' with OAuth token...`,
|
||||
);
|
||||
|
||||
@@ -1000,12 +1001,12 @@ export async function connectToMcpServer(
|
||||
},
|
||||
);
|
||||
if (hasStoredTokens) {
|
||||
console.log(
|
||||
debugLogger.log(
|
||||
`Stored OAuth token for SSE server '${mcpServerName}' was rejected. ` +
|
||||
`Please re-authenticate using: /mcp auth ${mcpServerName}`,
|
||||
);
|
||||
} else {
|
||||
console.log(
|
||||
debugLogger.log(
|
||||
`401 error received for SSE server '${mcpServerName}' without OAuth configuration. ` +
|
||||
`Please authenticate using: /mcp auth ${mcpServerName}`,
|
||||
);
|
||||
@@ -1018,7 +1019,9 @@ export async function connectToMcpServer(
|
||||
}
|
||||
|
||||
// For SSE/HTTP servers, try to discover OAuth configuration from the base URL
|
||||
console.log(`🔍 Attempting OAuth discovery for '${mcpServerName}'...`);
|
||||
debugLogger.log(
|
||||
`🔍 Attempting OAuth discovery for '${mcpServerName}'...`,
|
||||
);
|
||||
|
||||
if (hasNetworkTransport(mcpServerConfig)) {
|
||||
const serverUrl = new URL(
|
||||
@@ -1030,7 +1033,7 @@ export async function connectToMcpServer(
|
||||
// Try to discover OAuth configuration from the base URL
|
||||
const oauthConfig = await OAuthUtils.discoverOAuthConfig(baseUrl);
|
||||
if (oauthConfig) {
|
||||
console.log(
|
||||
debugLogger.log(
|
||||
`Discovered OAuth configuration from base URL for server '${mcpServerName}'`,
|
||||
);
|
||||
|
||||
@@ -1046,7 +1049,7 @@ export async function connectToMcpServer(
|
||||
// Pass the server URL for proper discovery
|
||||
const authServerUrl =
|
||||
mcpServerConfig.httpUrl || mcpServerConfig.url;
|
||||
console.log(
|
||||
debugLogger.log(
|
||||
`Starting OAuth authentication for server '${mcpServerName}'...`,
|
||||
);
|
||||
const authProvider = new MCPOAuthProvider(
|
||||
@@ -1257,7 +1260,9 @@ export async function createTransport(
|
||||
|
||||
if (accessToken) {
|
||||
hasOAuthConfig = true;
|
||||
console.log(`Found stored OAuth token for server '${mcpServerName}'`);
|
||||
debugLogger.log(
|
||||
`Found stored OAuth token for server '${mcpServerName}'`,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1322,7 +1327,10 @@ export async function createTransport(
|
||||
if (debugMode) {
|
||||
transport.stderr!.on('data', (data) => {
|
||||
const stderrStr = data.toString().trim();
|
||||
console.debug(`[DEBUG] [MCP STDERR (${mcpServerName})]: `, stderrStr);
|
||||
debugLogger.debug(
|
||||
`[DEBUG] [MCP STDERR (${mcpServerName})]: `,
|
||||
stderrStr,
|
||||
);
|
||||
});
|
||||
}
|
||||
return transport;
|
||||
@@ -1340,7 +1348,7 @@ export function isEnabled(
|
||||
mcpServerConfig: MCPServerConfig,
|
||||
): boolean {
|
||||
if (!funcDecl.name) {
|
||||
console.warn(
|
||||
debugLogger.warn(
|
||||
`Discovered a function declaration without a name from MCP server '${mcpServerName}'. Skipping.`,
|
||||
);
|
||||
return false;
|
||||
|
||||
@@ -733,8 +733,6 @@ Content of file[1]
|
||||
const invocation = tool.build({ paths: files });
|
||||
await invocation.execute(new AbortController().signal);
|
||||
|
||||
console.log('Execution order:', executionOrder);
|
||||
|
||||
// Verify concurrent execution pattern
|
||||
// In parallel execution: all "start:" events should come before all "end:" events
|
||||
// In sequential execution: "start:file1", "end:file1", "start:file2", "end:file2", etc.
|
||||
|
||||
@@ -19,6 +19,7 @@ import type { Config } from '../config/config.js';
|
||||
import { fileExists } from '../utils/fileUtils.js';
|
||||
import { Storage } from '../config/storage.js';
|
||||
import { GREP_TOOL_NAME } from './tool-names.js';
|
||||
import { debugLogger } from '../utils/debugLogger.js';
|
||||
|
||||
const DEFAULT_TOTAL_MAX_MATCHES = 20000;
|
||||
|
||||
@@ -179,7 +180,7 @@ class GrepToolInvocation extends BaseToolInvocation<
|
||||
const totalMaxMatches = DEFAULT_TOTAL_MAX_MATCHES;
|
||||
|
||||
if (this.config.getDebugMode()) {
|
||||
console.log(`[GrepTool] Total result limit: ${totalMaxMatches}`);
|
||||
debugLogger.log(`[GrepTool] Total result limit: ${totalMaxMatches}`);
|
||||
}
|
||||
|
||||
for (const searchDir of searchDirectories) {
|
||||
|
||||
@@ -39,6 +39,7 @@ import { logSmartEditCorrectionEvent } from '../telemetry/loggers.js';
|
||||
|
||||
import { correctPath } from '../utils/pathCorrector.js';
|
||||
import { EDIT_TOOL_NAME, READ_FILE_TOOL_NAME } from './tool-names.js';
|
||||
import { debugLogger } from '../utils/debugLogger.js';
|
||||
interface ReplacementContext {
|
||||
params: EditToolParams;
|
||||
currentContent: string;
|
||||
@@ -616,12 +617,12 @@ class EditToolInvocation implements ToolInvocation<EditToolParams, ToolResult> {
|
||||
throw error;
|
||||
}
|
||||
const errorMsg = error instanceof Error ? error.message : String(error);
|
||||
console.log(`Error preparing edit: ${errorMsg}`);
|
||||
debugLogger.log(`Error preparing edit: ${errorMsg}`);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (editData.error) {
|
||||
console.log(`Error: ${editData.error.display}`);
|
||||
debugLogger.log(`Error: ${editData.error.display}`);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ import { parse } from 'shell-quote';
|
||||
import { ToolErrorType } from './tool-error.js';
|
||||
import { safeJsonStringify } from '../utils/safeJsonStringify.js';
|
||||
import type { EventEmitter } from 'node:events';
|
||||
import { debugLogger } from '../utils/debugLogger.js';
|
||||
|
||||
type ToolParams = Record<string, unknown>;
|
||||
|
||||
@@ -187,7 +188,7 @@ export class ToolRegistry {
|
||||
tool = tool.asFullyQualifiedTool();
|
||||
} else {
|
||||
// Decide on behavior: throw error, log warning, or allow overwrite
|
||||
console.warn(
|
||||
debugLogger.warn(
|
||||
`Tool with name "${tool.name}" is already registered. Overwriting.`,
|
||||
);
|
||||
}
|
||||
@@ -379,7 +380,7 @@ export class ToolRegistry {
|
||||
// register each function as a tool
|
||||
for (const func of functions) {
|
||||
if (!func.name) {
|
||||
console.warn('Discovered a tool with no name. Skipping.');
|
||||
debugLogger.warn('Discovered a tool with no name. Skipping.');
|
||||
continue;
|
||||
}
|
||||
const parameters =
|
||||
|
||||
@@ -32,6 +32,7 @@ import {
|
||||
WebFetchFallbackAttemptEvent,
|
||||
} from '../telemetry/index.js';
|
||||
import { WEB_FETCH_TOOL_NAME } from './tool-names.js';
|
||||
import { debugLogger } from '../utils/debugLogger.js';
|
||||
|
||||
const URL_FETCH_TIMEOUT_MS = 10000;
|
||||
const MAX_CONTENT_LENGTH = 100000;
|
||||
@@ -274,7 +275,7 @@ ${textContent}
|
||||
DEFAULT_GEMINI_FLASH_MODEL,
|
||||
);
|
||||
|
||||
console.debug(
|
||||
debugLogger.debug(
|
||||
`[WebFetchTool] Full response for prompt "${userPrompt.substring(
|
||||
0,
|
||||
50,
|
||||
@@ -367,7 +368,7 @@ ${sourceListFormatted.join('\n')}`;
|
||||
|
||||
const llmContent = responseText;
|
||||
|
||||
console.debug(
|
||||
debugLogger.debug(
|
||||
`[WebFetchTool] Formatted tool response for prompt "${userPrompt}:\n\n":`,
|
||||
llmContent,
|
||||
);
|
||||
|
||||
@@ -8,11 +8,13 @@ import * as fs from 'node:fs/promises';
|
||||
import * as path from 'node:path';
|
||||
import type { FileDiscoveryService } from '../services/fileDiscoveryService.js';
|
||||
import type { FileFilteringOptions } from '../config/constants.js';
|
||||
import { debugLogger } from './debugLogger.js';
|
||||
// Simple console logger for now.
|
||||
// TODO: Integrate with a more robust server-side logger.
|
||||
const logger = {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
debug: (...args: any[]) => console.debug('[DEBUG] [BfsFileSearch]', ...args),
|
||||
debug: (...args: any[]) =>
|
||||
debugLogger.debug('[DEBUG] [BfsFileSearch]', ...args),
|
||||
};
|
||||
|
||||
interface BfsFileSearchOptions {
|
||||
@@ -84,7 +86,7 @@ export async function bfsFileSearch(
|
||||
} catch (error) {
|
||||
// Warn user that a directory could not be read, as this affects search results.
|
||||
const message = (error as Error)?.message ?? 'Unknown error';
|
||||
console.warn(
|
||||
debugLogger.warn(
|
||||
`[WARN] Skipping unreadable directory: ${currentDir} (${message})`,
|
||||
);
|
||||
if (debug) {
|
||||
|
||||
@@ -14,6 +14,7 @@ import type { FileSystemService } from '../services/fileSystemService.js';
|
||||
import { ToolErrorType } from '../tools/tool-error.js';
|
||||
import { BINARY_EXTENSIONS } from './ignorePatterns.js';
|
||||
import { createRequire as createModuleRequire } from 'node:module';
|
||||
import { debugLogger } from './debugLogger.js';
|
||||
|
||||
const requireModule = createModuleRequire(import.meta.url);
|
||||
|
||||
@@ -260,7 +261,7 @@ export async function isBinaryFile(filePath: string): Promise<boolean> {
|
||||
// If >30% non-printable characters, consider it binary
|
||||
return nonPrintableCount / bytesRead > 0.3;
|
||||
} catch (error) {
|
||||
console.warn(
|
||||
debugLogger.warn(
|
||||
`Failed to check if file is binary: ${filePath}`,
|
||||
error instanceof Error ? error.message : String(error),
|
||||
);
|
||||
@@ -270,7 +271,7 @@ export async function isBinaryFile(filePath: string): Promise<boolean> {
|
||||
try {
|
||||
await fh.close();
|
||||
} catch (closeError) {
|
||||
console.warn(
|
||||
debugLogger.warn(
|
||||
`Failed to close file handle for: ${filePath}`,
|
||||
closeError instanceof Error ? closeError.message : String(closeError),
|
||||
);
|
||||
|
||||
@@ -11,6 +11,7 @@ import { getErrorMessage, isNodeError } from './errors.js';
|
||||
import type { FileDiscoveryService } from '../services/fileDiscoveryService.js';
|
||||
import type { FileFilteringOptions } from '../config/constants.js';
|
||||
import { DEFAULT_FILE_FILTERING_OPTIONS } from '../config/constants.js';
|
||||
import { debugLogger } from './debugLogger.js';
|
||||
|
||||
const MAX_ITEMS = 200;
|
||||
const TRUNCATION_INDICATOR = '...';
|
||||
@@ -104,7 +105,7 @@ async function readFullStructure(
|
||||
isNodeError(error) &&
|
||||
(error.code === 'EACCES' || error.code === 'ENOENT')
|
||||
) {
|
||||
console.warn(
|
||||
debugLogger.warn(
|
||||
`Warning: Could not read directory ${currentPath}: ${error.message}`,
|
||||
);
|
||||
if (currentPath === rootPath && error.code === 'ENOENT') {
|
||||
|
||||
@@ -10,6 +10,7 @@ import { type BaseLlmClient } from '../core/baseLlmClient.js';
|
||||
import { LruCache } from './LruCache.js';
|
||||
import { DEFAULT_GEMINI_FLASH_MODEL } from '../config/models.js';
|
||||
import { promptIdContext } from './promptIdContext.js';
|
||||
import { debugLogger } from './debugLogger.js';
|
||||
|
||||
const MAX_CACHE_SIZE = 50;
|
||||
|
||||
@@ -112,7 +113,7 @@ export async function FixLLMEditWithInstruction(
|
||||
let promptId = promptIdContext.getStore();
|
||||
if (!promptId) {
|
||||
promptId = `llm-fixer-fallback-${Date.now()}-${Math.random().toString(16).slice(2)}`;
|
||||
console.warn(
|
||||
debugLogger.warn(
|
||||
`Could not find promptId in context. This is unexpected. Using a fallback ID: ${promptId}`,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -16,15 +16,17 @@ import type { FileFilteringOptions } from '../config/constants.js';
|
||||
import { DEFAULT_MEMORY_FILE_FILTERING_OPTIONS } from '../config/constants.js';
|
||||
import { GEMINI_DIR } from './paths.js';
|
||||
import type { GeminiCLIExtension } from '../config/config.js';
|
||||
import { debugLogger } from './debugLogger.js';
|
||||
|
||||
// Simple console logger, similar to the one previously in CLI's config.ts
|
||||
// TODO: Integrate with a more robust server-side logger if available/appropriate.
|
||||
const logger = {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
debug: (...args: any[]) =>
|
||||
console.debug('[DEBUG] [MemoryDiscovery]', ...args),
|
||||
debugLogger.debug('[DEBUG] [MemoryDiscovery]', ...args),
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
warn: (...args: any[]) => console.warn('[WARN] [MemoryDiscovery]', ...args),
|
||||
warn: (...args: any[]) =>
|
||||
debugLogger.warn('[WARN] [MemoryDiscovery]', ...args),
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
error: (...args: any[]) =>
|
||||
console.error('[ERROR] [MemoryDiscovery]', ...args),
|
||||
|
||||
@@ -8,14 +8,16 @@ import * as fs from 'node:fs/promises';
|
||||
import * as path from 'node:path';
|
||||
import { isSubpath } from './paths.js';
|
||||
import { marked, type Token } from 'marked';
|
||||
import { debugLogger } from './debugLogger.js';
|
||||
|
||||
// Simple console logger for import processing
|
||||
const logger = {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
debug: (...args: any[]) =>
|
||||
console.debug('[DEBUG] [ImportProcessor]', ...args),
|
||||
debugLogger.debug('[DEBUG] [ImportProcessor]', ...args),
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
warn: (...args: any[]) => console.warn('[WARN] [ImportProcessor]', ...args),
|
||||
warn: (...args: any[]) =>
|
||||
debugLogger.warn('[WARN] [ImportProcessor]', ...args),
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
error: (...args: any[]) =>
|
||||
console.error('[ERROR] [ImportProcessor]', ...args),
|
||||
|
||||
@@ -9,6 +9,7 @@ import { DEFAULT_GEMINI_FLASH_MODEL } from '../config/models.js';
|
||||
import type { BaseLlmClient } from '../core/baseLlmClient.js';
|
||||
import type { GeminiChat } from '../core/geminiChat.js';
|
||||
import { isFunctionResponse } from './messageInspectors.js';
|
||||
import { debugLogger } from './debugLogger.js';
|
||||
|
||||
const CHECK_PROMPT = `Analyze *only* the content and structure of your immediately preceding response (your last turn in the conversation history). Based *strictly* on that response, determine who should logically speak next: the 'user' or the 'model' (you).
|
||||
**Decision Rules (apply in order):**
|
||||
@@ -126,7 +127,7 @@ export async function checkNextSpeaker(
|
||||
}
|
||||
return null;
|
||||
} catch (error) {
|
||||
console.warn(
|
||||
debugLogger.warn(
|
||||
'Failed to talk to Gemini endpoint when seeing if conversation should continue.',
|
||||
error,
|
||||
);
|
||||
|
||||
@@ -10,6 +10,7 @@ import { ApiError } from '@google/genai';
|
||||
import type { HttpError } from './retry.js';
|
||||
import { retryWithBackoff } from './retry.js';
|
||||
import { setSimulate429 } from './testUtils.js';
|
||||
import { debugLogger } from './debugLogger.js';
|
||||
|
||||
// Helper to create a mock function that fails a certain number of times
|
||||
const createFailingFunction = (
|
||||
@@ -43,7 +44,7 @@ describe('retryWithBackoff', () => {
|
||||
// Disable 429 simulation for tests
|
||||
setSimulate429(false);
|
||||
// Suppress unhandled promise rejection warnings for tests that expect errors
|
||||
console.warn = vi.fn();
|
||||
debugLogger.warn = vi.fn();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
isGenericQuotaExceededError,
|
||||
} from './quotaErrorDetection.js';
|
||||
import { delay, createAbortError } from './delay.js';
|
||||
import { debugLogger } from './debugLogger.js';
|
||||
|
||||
const FETCH_FAILED_MESSAGE =
|
||||
'exception TypeError: fetch failed sending request';
|
||||
@@ -168,7 +169,7 @@ export async function retryWithBackoff<T>(
|
||||
}
|
||||
} catch (fallbackError) {
|
||||
// If fallback fails, continue with original error
|
||||
console.warn('Fallback to Flash model failed:', fallbackError);
|
||||
debugLogger.warn('Fallback to Flash model failed:', fallbackError);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -195,7 +196,7 @@ export async function retryWithBackoff<T>(
|
||||
}
|
||||
} catch (fallbackError) {
|
||||
// If fallback fails, continue with original error
|
||||
console.warn('Fallback to Flash model failed:', fallbackError);
|
||||
debugLogger.warn('Fallback to Flash model failed:', fallbackError);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -227,7 +228,7 @@ export async function retryWithBackoff<T>(
|
||||
}
|
||||
} catch (fallbackError) {
|
||||
// If fallback fails, continue with original error
|
||||
console.warn('Fallback to Flash model failed:', fallbackError);
|
||||
debugLogger.warn('Fallback to Flash model failed:', fallbackError);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -244,7 +245,7 @@ export async function retryWithBackoff<T>(
|
||||
|
||||
if (delayDurationMs > 0) {
|
||||
// Respect Retry-After header if present and parsed
|
||||
console.warn(
|
||||
debugLogger.warn(
|
||||
`Attempt ${attempt} failed with status ${delayErrorStatus ?? 'unknown'}. Retrying after explicit delay of ${delayDurationMs}ms...`,
|
||||
error,
|
||||
);
|
||||
@@ -367,13 +368,13 @@ function logRetryAttempt(
|
||||
}
|
||||
|
||||
if (errorStatus === 429) {
|
||||
console.warn(message, error);
|
||||
debugLogger.warn(message, error);
|
||||
} else if (errorStatus && errorStatus >= 500 && errorStatus < 600) {
|
||||
console.error(message, error);
|
||||
} else if (error instanceof Error) {
|
||||
// Fallback for errors that might not have a status but have a message
|
||||
if (error.message.includes('429')) {
|
||||
console.warn(
|
||||
debugLogger.warn(
|
||||
`Attempt ${attempt} failed with 429 error (no Retry-After header). Retrying with backoff...`,
|
||||
error,
|
||||
);
|
||||
@@ -383,9 +384,9 @@ function logRetryAttempt(
|
||||
error,
|
||||
);
|
||||
} else {
|
||||
console.warn(message, error); // Default to warn for other errors
|
||||
debugLogger.warn(message, error); // Default to warn for other errors
|
||||
}
|
||||
} else {
|
||||
console.warn(message, error); // Default to warn if error type is unknown
|
||||
debugLogger.warn(message, error); // Default to warn if error type is unknown
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
import { execSync } from 'node:child_process';
|
||||
import os from 'node:os';
|
||||
import { detect as chardetDetect } from 'chardet';
|
||||
import { debugLogger } from './debugLogger.js';
|
||||
|
||||
// Cache for system encoding to avoid repeated detection
|
||||
// Use undefined to indicate "not yet checked" vs null meaning "checked but failed"
|
||||
@@ -66,7 +67,7 @@ export function getSystemEncoding(): string | null {
|
||||
`Unable to parse Windows code page from 'chcp' output "${output.trim()}". `,
|
||||
);
|
||||
} catch (error) {
|
||||
console.warn(
|
||||
debugLogger.warn(
|
||||
`Failed to get Windows code page using 'chcp' command: ${error instanceof Error ? error.message : String(error)}. ` +
|
||||
`Will attempt to detect encoding from command output instead.`,
|
||||
);
|
||||
@@ -88,7 +89,7 @@ export function getSystemEncoding(): string | null {
|
||||
.toString()
|
||||
.trim();
|
||||
} catch (_e) {
|
||||
console.warn('Failed to get locale charmap.');
|
||||
debugLogger.warn('Failed to get locale charmap.');
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -141,7 +142,7 @@ export function windowsCodePageToEncoding(cp: number): string | null {
|
||||
return map[cp];
|
||||
}
|
||||
|
||||
console.warn(`Unable to determine encoding for windows code page ${cp}.`);
|
||||
debugLogger.warn(`Unable to determine encoding for windows code page ${cp}.`);
|
||||
return null; // Return null if no mapping found
|
||||
}
|
||||
|
||||
@@ -159,7 +160,7 @@ export function detectEncodingFromBuffer(buffer: Buffer): string | null {
|
||||
return detected.toLowerCase();
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn('Failed to detect encoding with chardet:', error);
|
||||
debugLogger.warn('Failed to detect encoding with chardet:', error);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
import path from 'node:path';
|
||||
import { promises as fsp, readFileSync } from 'node:fs';
|
||||
import { Storage } from '../config/storage.js';
|
||||
import { debugLogger } from './debugLogger.js';
|
||||
|
||||
interface UserAccounts {
|
||||
active: string | null;
|
||||
@@ -33,7 +34,7 @@ export class UserAccountManager {
|
||||
|
||||
// Inlined validation logic
|
||||
if (typeof parsed !== 'object' || parsed === null) {
|
||||
console.log('Invalid accounts file schema, starting fresh.');
|
||||
debugLogger.log('Invalid accounts file schema, starting fresh.');
|
||||
return defaultState;
|
||||
}
|
||||
const { active, old } = parsed as Partial<UserAccounts>;
|
||||
@@ -43,7 +44,7 @@ export class UserAccountManager {
|
||||
(Array.isArray(old) && old.every((i) => typeof i === 'string')));
|
||||
|
||||
if (!isValid) {
|
||||
console.log('Invalid accounts file schema, starting fresh.');
|
||||
debugLogger.log('Invalid accounts file schema, starting fresh.');
|
||||
return defaultState;
|
||||
}
|
||||
|
||||
@@ -66,7 +67,10 @@ export class UserAccountManager {
|
||||
) {
|
||||
return defaultState;
|
||||
}
|
||||
console.log('Error during sync read of accounts, starting fresh.', error);
|
||||
debugLogger.log(
|
||||
'Error during sync read of accounts, starting fresh.',
|
||||
error,
|
||||
);
|
||||
return defaultState;
|
||||
}
|
||||
}
|
||||
@@ -84,7 +88,7 @@ export class UserAccountManager {
|
||||
) {
|
||||
return defaultState;
|
||||
}
|
||||
console.log('Could not parse accounts file, starting fresh.', error);
|
||||
debugLogger.log('Could not parse accounts file, starting fresh.', error);
|
||||
return defaultState;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import { isNodeError } from '../utils/errors.js';
|
||||
import * as fs from 'node:fs';
|
||||
import * as path from 'node:path';
|
||||
import * as process from 'node:process';
|
||||
import { debugLogger } from './debugLogger.js';
|
||||
|
||||
export type Unsubscribe = () => void;
|
||||
|
||||
@@ -72,7 +73,7 @@ export class WorkspaceContext {
|
||||
this.directories.add(resolved);
|
||||
this.notifyDirectoriesChanged();
|
||||
} catch (err) {
|
||||
console.warn(
|
||||
debugLogger.warn(
|
||||
`[WARN] Skipping unreadable directory: ${directory} (${err instanceof Error ? err.message : String(err)})`,
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user