mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-04-28 19:52:02 +00:00
feat(cli): migrate console calls to debugLogger and stdioHelpers (M3 Phase 7-9)
Route CLI console.* calls to structured logging: - Debug/internal diagnostics → debugLogger (logfile) - User-facing output → writeStdoutLine/writeStderrLine/clearScreen (stdioHelpers) - Add stdioHelpers.ts with writeStdoutLine, writeStderrLine, clearScreen - Migrate pre-session files (gemini.tsx, sandbox.ts, config.ts) to stdioHelpers - Migrate extension/MCP commands to stdioHelpers - Migrate non-interactive session/control to debugLogger - Migrate UI hooks and components to debugLogger
This commit is contained in:
parent
45df0e8b82
commit
7995c65571
82 changed files with 606 additions and 485 deletions
|
|
@ -8,6 +8,7 @@ import type {
|
|||
Config,
|
||||
ConfigInitializeOptions,
|
||||
} from '@qwen-code/qwen-code-core';
|
||||
import { createDebugLogger } from '@qwen-code/qwen-code-core';
|
||||
import { StreamJsonInputReader } from './io/StreamJsonInputReader.js';
|
||||
import { StreamJsonOutputAdapter } from './io/StreamJsonOutputAdapter.js';
|
||||
import { ControlContext } from './control/ControlContext.js';
|
||||
|
|
@ -34,6 +35,8 @@ import { createMinimalSettings } from '../config/settings.js';
|
|||
import { runNonInteractive } from '../nonInteractiveCli.js';
|
||||
import { ConsolePatcher } from '../ui/utils/ConsolePatcher.js';
|
||||
|
||||
const debugLogger = createDebugLogger('NON_INTERACTIVE_SESSION');
|
||||
|
||||
class Session {
|
||||
private userMessageQueue: CLIUserMessage[] = [];
|
||||
private abortController: AbortController;
|
||||
|
|
@ -46,7 +49,6 @@ class Session {
|
|||
private dispatcher: ControlDispatcher | null = null;
|
||||
private controlService: ControlService | null = null;
|
||||
private controlSystemEnabled: boolean | null = null;
|
||||
private debugMode: boolean;
|
||||
private shutdownHandler: (() => void) | null = null;
|
||||
private initialPrompt: CLIUserMessage | null = null;
|
||||
private processingPromise: Promise<void> | null = null;
|
||||
|
|
@ -62,7 +64,6 @@ class Session {
|
|||
constructor(config: Config, initialPrompt?: CLIUserMessage) {
|
||||
this.config = config;
|
||||
this.sessionId = config.getSessionId();
|
||||
this.debugMode = config.getDebugMode();
|
||||
this.abortController = new AbortController();
|
||||
this.initialPrompt = initialPrompt ?? null;
|
||||
|
||||
|
|
@ -105,17 +106,13 @@ class Session {
|
|||
return;
|
||||
}
|
||||
|
||||
if (this.debugMode) {
|
||||
console.error('[Session] Initializing config');
|
||||
}
|
||||
debugLogger.debug('[Session] Initializing config');
|
||||
|
||||
try {
|
||||
await this.config.initialize(options);
|
||||
this.configInitialized = true;
|
||||
} catch (error) {
|
||||
if (this.debugMode) {
|
||||
console.error('[Session] Failed to initialize config:', error);
|
||||
}
|
||||
debugLogger.error('[Session] Failed to initialize config:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
|
@ -125,9 +122,7 @@ class Session {
|
|||
*/
|
||||
private completeInitialization(): void {
|
||||
if (this.initializationResolve) {
|
||||
if (this.debugMode) {
|
||||
console.error('[Session] Initialization complete');
|
||||
}
|
||||
debugLogger.debug('[Session] Initialization complete');
|
||||
this.initializationResolve();
|
||||
this.initializationResolve = null;
|
||||
this.initializationReject = null;
|
||||
|
|
@ -139,9 +134,7 @@ class Session {
|
|||
*/
|
||||
private failInitialization(error: Error): void {
|
||||
if (this.initializationReject) {
|
||||
if (this.debugMode) {
|
||||
console.error('[Session] Initialization failed:', error);
|
||||
}
|
||||
debugLogger.error('[Session] Initialization failed:', error);
|
||||
this.initializationReject(error);
|
||||
this.initializationResolve = null;
|
||||
this.initializationReject = null;
|
||||
|
|
@ -213,11 +206,9 @@ class Session {
|
|||
return;
|
||||
}
|
||||
|
||||
if (this.debugMode) {
|
||||
console.error(
|
||||
'[Session] Ignoring non-initialize control request during initialization',
|
||||
);
|
||||
}
|
||||
debugLogger.debug(
|
||||
'[Session] Ignoring non-initialize control request during initialization',
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -254,9 +245,7 @@ class Session {
|
|||
// Initialization complete!
|
||||
this.completeInitialization();
|
||||
} catch (error) {
|
||||
if (this.debugMode) {
|
||||
console.error('[Session] SDK mode initialization failed:', error);
|
||||
}
|
||||
debugLogger.error('[Session] SDK mode initialization failed:', error);
|
||||
this.failInitialization(
|
||||
error instanceof Error ? error : new Error(String(error)),
|
||||
);
|
||||
|
|
@ -281,9 +270,7 @@ class Session {
|
|||
// Enqueue the first user message for processing
|
||||
this.enqueueUserMessage(userMessage);
|
||||
} catch (error) {
|
||||
if (this.debugMode) {
|
||||
console.error('[Session] Direct mode initialization failed:', error);
|
||||
}
|
||||
debugLogger.error('[Session] Direct mode initialization failed:', error);
|
||||
this.failInitialization(
|
||||
error instanceof Error ? error : new Error(String(error)),
|
||||
);
|
||||
|
|
@ -297,18 +284,14 @@ class Session {
|
|||
private handleControlRequestAsync(request: CLIControlRequest): void {
|
||||
const dispatcher = this.getDispatcher();
|
||||
if (!dispatcher) {
|
||||
if (this.debugMode) {
|
||||
console.error('[Session] Control system not enabled');
|
||||
}
|
||||
debugLogger.warn('[Session] Control system not enabled');
|
||||
return;
|
||||
}
|
||||
|
||||
// Fire-and-forget: dispatch runs concurrently
|
||||
// The dispatcher's pendingIncomingRequests tracks completion
|
||||
void dispatcher.dispatch(request).catch((error) => {
|
||||
if (this.debugMode) {
|
||||
console.error('[Session] Control request dispatch error:', error);
|
||||
}
|
||||
debugLogger.error('[Session] Control request dispatch error:', error);
|
||||
// Error response is already sent by dispatcher.dispatch()
|
||||
});
|
||||
}
|
||||
|
|
@ -338,9 +321,7 @@ class Session {
|
|||
private async processUserMessage(userMessage: CLIUserMessage): Promise<void> {
|
||||
const input = extractUserMessageText(userMessage);
|
||||
if (!input) {
|
||||
if (this.debugMode) {
|
||||
console.error('[Session] No text content in user message');
|
||||
}
|
||||
debugLogger.debug('[Session] No text content in user message');
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -362,9 +343,7 @@ class Session {
|
|||
},
|
||||
);
|
||||
} catch (error) {
|
||||
if (this.debugMode) {
|
||||
console.error('[Session] Query execution error:', error);
|
||||
}
|
||||
debugLogger.error('[Session] Query execution error:', error);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -382,9 +361,7 @@ class Session {
|
|||
try {
|
||||
await this.processUserMessage(userMessage);
|
||||
} catch (error) {
|
||||
if (this.debugMode) {
|
||||
console.error('[Session] Error processing user message:', error);
|
||||
}
|
||||
debugLogger.error('[Session] Error processing user message:', error);
|
||||
this.emitErrorResult(error);
|
||||
}
|
||||
}
|
||||
|
|
@ -430,18 +407,14 @@ class Session {
|
|||
}
|
||||
|
||||
private handleInterrupt(): void {
|
||||
if (this.debugMode) {
|
||||
console.error('[Session] Interrupt requested');
|
||||
}
|
||||
debugLogger.info('[Session] Interrupt requested');
|
||||
this.abortController.abort();
|
||||
this.abortController = new AbortController();
|
||||
}
|
||||
|
||||
private setupSignalHandlers(): void {
|
||||
this.shutdownHandler = () => {
|
||||
if (this.debugMode) {
|
||||
console.error('[Session] Shutdown signal received');
|
||||
}
|
||||
debugLogger.info('[Session] Shutdown signal received');
|
||||
this.isShuttingDown = true;
|
||||
this.abortController.abort();
|
||||
};
|
||||
|
|
@ -458,16 +431,17 @@ class Session {
|
|||
try {
|
||||
await this.waitForInitialization();
|
||||
} catch (error) {
|
||||
if (this.debugMode) {
|
||||
console.error('[Session] Initialization error during shutdown:', error);
|
||||
}
|
||||
debugLogger.error(
|
||||
'[Session] Initialization error during shutdown:',
|
||||
error,
|
||||
);
|
||||
}
|
||||
|
||||
// 2. Wait for all control request handlers using dispatcher's tracking
|
||||
if (this.dispatcher) {
|
||||
const pendingCount = this.dispatcher.getPendingIncomingRequestCount();
|
||||
if (pendingCount > 0 && this.debugMode) {
|
||||
console.error(
|
||||
if (pendingCount > 0) {
|
||||
debugLogger.debug(
|
||||
`[Session] Waiting for ${pendingCount} pending control request handlers`,
|
||||
);
|
||||
}
|
||||
|
|
@ -476,23 +450,17 @@ class Session {
|
|||
|
||||
// 3. Wait for user message processing queue
|
||||
while (this.processingPromise) {
|
||||
if (this.debugMode) {
|
||||
console.error('[Session] Waiting for user message processing');
|
||||
}
|
||||
debugLogger.debug('[Session] Waiting for user message processing');
|
||||
try {
|
||||
await this.processingPromise;
|
||||
} catch (error) {
|
||||
if (this.debugMode) {
|
||||
console.error('[Session] Error in user message processing:', error);
|
||||
}
|
||||
debugLogger.error('[Session] Error in user message processing:', error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async shutdown(): Promise<void> {
|
||||
if (this.debugMode) {
|
||||
console.error('[Session] Shutting down');
|
||||
}
|
||||
debugLogger.debug('[Session] Shutting down');
|
||||
|
||||
this.isShuttingDown = true;
|
||||
|
||||
|
|
@ -528,9 +496,7 @@ class Session {
|
|||
*/
|
||||
async run(): Promise<void> {
|
||||
try {
|
||||
if (this.debugMode) {
|
||||
console.error('[Session] Starting session', this.sessionId);
|
||||
}
|
||||
debugLogger.info('[Session] Starting session', this.sessionId);
|
||||
|
||||
// Handle initial prompt if provided (fire-and-forget)
|
||||
if (this.initialPrompt !== null) {
|
||||
|
|
@ -571,18 +537,16 @@ class Session {
|
|||
} else if (isCLIUserMessage(message)) {
|
||||
// User messages are enqueued, processing runs separately
|
||||
this.enqueueUserMessage(message as CLIUserMessage);
|
||||
} else if (this.debugMode) {
|
||||
if (
|
||||
!isCLIAssistantMessage(message) &&
|
||||
!isCLISystemMessage(message) &&
|
||||
!isCLIResultMessage(message) &&
|
||||
!isCLIPartialAssistantMessage(message)
|
||||
) {
|
||||
console.error(
|
||||
'[Session] Unknown message type:',
|
||||
JSON.stringify(message, null, 2),
|
||||
);
|
||||
}
|
||||
} else if (
|
||||
!isCLIAssistantMessage(message) &&
|
||||
!isCLISystemMessage(message) &&
|
||||
!isCLIResultMessage(message) &&
|
||||
!isCLIPartialAssistantMessage(message)
|
||||
) {
|
||||
debugLogger.warn(
|
||||
'[Session] Unknown message type:',
|
||||
JSON.stringify(message, null, 2),
|
||||
);
|
||||
}
|
||||
|
||||
if (this.isShuttingDown) {
|
||||
|
|
@ -590,9 +554,7 @@ class Session {
|
|||
}
|
||||
}
|
||||
} catch (streamError) {
|
||||
if (this.debugMode) {
|
||||
console.error('[Session] Stream reading error:', streamError);
|
||||
}
|
||||
debugLogger.error('[Session] Stream reading error:', streamError);
|
||||
throw streamError;
|
||||
}
|
||||
|
||||
|
|
@ -600,9 +562,7 @@ class Session {
|
|||
await this.waitForAllPendingWork();
|
||||
await this.shutdown();
|
||||
} catch (error) {
|
||||
if (this.debugMode) {
|
||||
console.error('[Session] Error:', error);
|
||||
}
|
||||
debugLogger.error('[Session] Error:', error);
|
||||
await this.shutdown();
|
||||
throw error;
|
||||
} finally {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue