mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-04-30 04:30:48 +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
|
|
@ -18,10 +18,15 @@ import { ScopeSelector } from './shared/ScopeSelector.js';
|
|||
import type { LoadedSettings } from '../../config/settings.js';
|
||||
import { SettingScope } from '../../config/settings.js';
|
||||
import type { EditorType } from '@qwen-code/qwen-code-core';
|
||||
import { isEditorAvailable } from '@qwen-code/qwen-code-core';
|
||||
import {
|
||||
createDebugLogger,
|
||||
isEditorAvailable,
|
||||
} from '@qwen-code/qwen-code-core';
|
||||
import { useKeypress } from '../hooks/useKeypress.js';
|
||||
import { t } from '../../i18n/index.js';
|
||||
|
||||
const debugLogger = createDebugLogger('EDITOR_SETTINGS_DIALOG');
|
||||
|
||||
interface EditorDialogProps {
|
||||
onSelect: (editorType: EditorType | undefined, scope: SettingScope) => void;
|
||||
settings: LoadedSettings;
|
||||
|
|
@ -61,7 +66,7 @@ export function EditorSettingsDialog({
|
|||
)
|
||||
: 0;
|
||||
if (editorIndex === -1) {
|
||||
console.error(`Editor is not supported: ${currentPreference}`);
|
||||
debugLogger.error(`Editor is not supported: ${currentPreference}`);
|
||||
editorIndex = 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,11 +9,14 @@ import { theme } from '../semantic-colors.js';
|
|||
import { useKeypress } from '../hooks/useKeypress.js';
|
||||
import { relaunchApp } from '../../utils/processUtils.js';
|
||||
import { type RestartReason } from '../hooks/useIdeTrustListener.js';
|
||||
import { createDebugLogger } from '@qwen-code/qwen-code-core';
|
||||
|
||||
interface IdeTrustChangeDialogProps {
|
||||
reason: RestartReason;
|
||||
}
|
||||
|
||||
const debugLogger = createDebugLogger('IDE_TRUST_DIALOG');
|
||||
|
||||
export const IdeTrustChangeDialog = ({ reason }: IdeTrustChangeDialogProps) => {
|
||||
useKeypress(
|
||||
(key) => {
|
||||
|
|
@ -27,7 +30,7 @@ export const IdeTrustChangeDialog = ({ reason }: IdeTrustChangeDialogProps) => {
|
|||
let message = 'Workspace trust has changed.';
|
||||
if (reason === 'NONE') {
|
||||
// This should not happen, but provides a fallback and a debug log.
|
||||
console.error(
|
||||
debugLogger.error(
|
||||
'IdeTrustChangeDialog rendered with unexpected reason "NONE"',
|
||||
);
|
||||
} else if (reason === 'CONNECTION_CHANGE') {
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ import { useKeypress } from '../hooks/useKeypress.js';
|
|||
import { keyMatchers, Command } from '../keyMatchers.js';
|
||||
import type { CommandContext, SlashCommand } from '../commands/types.js';
|
||||
import type { Config } from '@qwen-code/qwen-code-core';
|
||||
import { ApprovalMode } from '@qwen-code/qwen-code-core';
|
||||
import { ApprovalMode, createDebugLogger } from '@qwen-code/qwen-code-core';
|
||||
import {
|
||||
parseInputForHighlighting,
|
||||
buildSegmentsForVisualSlice,
|
||||
|
|
@ -38,6 +38,8 @@ import { SCREEN_READER_USER_PREFIX } from '../textConstants.js';
|
|||
import { useShellFocusState } from '../contexts/ShellFocusContext.js';
|
||||
import { useUIState } from '../contexts/UIStateContext.js';
|
||||
import { FEEDBACK_DIALOG_KEYS } from '../FeedbackDialog.js';
|
||||
|
||||
const debugLogger = createDebugLogger('INPUT_PROMPT');
|
||||
export interface InputPromptProps {
|
||||
buffer: TextBuffer;
|
||||
onSubmit: (value: string) => void;
|
||||
|
|
@ -299,7 +301,7 @@ export const InputPrompt: React.FC<InputPromptProps> = ({
|
|||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error handling clipboard image:', error);
|
||||
debugLogger.error('Error handling clipboard image:', error);
|
||||
}
|
||||
}, [buffer, config]);
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import Link from 'ink-link';
|
|||
import qrcode from 'qrcode-terminal';
|
||||
import { Colors } from '../colors.js';
|
||||
import type { DeviceAuthorizationData } from '@qwen-code/qwen-code-core';
|
||||
import { createDebugLogger } from '@qwen-code/qwen-code-core';
|
||||
import { useKeypress } from '../hooks/useKeypress.js';
|
||||
import { t } from '../../i18n/index.js';
|
||||
|
||||
|
|
@ -29,6 +30,8 @@ interface QwenOAuthProgressProps {
|
|||
authMessage?: string | null;
|
||||
}
|
||||
|
||||
const debugLogger = createDebugLogger('QWEN_OAUTH_PROGRESS');
|
||||
|
||||
/**
|
||||
* Static QR Code Display Component
|
||||
* Renders the QR code and URL once and doesn't re-render unless the URL changes
|
||||
|
|
@ -161,7 +164,7 @@ export function QwenOAuthProgress({
|
|||
},
|
||||
);
|
||||
} catch (error) {
|
||||
console.error('Failed to generate QR code:', error);
|
||||
debugLogger.error('Failed to generate QR code:', error);
|
||||
setQrCodeData(null);
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ import {
|
|||
} from '../../utils/settingsUtils.js';
|
||||
import { updateOutputLanguageFile } from '../../utils/languageUtils.js';
|
||||
import { useVimMode } from '../contexts/VimModeContext.js';
|
||||
import { type Config } from '@qwen-code/qwen-code-core';
|
||||
import { createDebugLogger, type Config } from '@qwen-code/qwen-code-core';
|
||||
import { useKeypress } from '../hooks/useKeypress.js';
|
||||
import chalk from 'chalk';
|
||||
import { cpSlice, cpLen, stripUnsafeCharacters } from '../utils/textUtils.js';
|
||||
|
|
@ -46,6 +46,8 @@ interface SettingsDialogProps {
|
|||
config?: Config;
|
||||
}
|
||||
|
||||
const debugLogger = createDebugLogger('SETTINGS_DIALOG');
|
||||
|
||||
const maxItemsToShow = 8;
|
||||
|
||||
export function SettingsDialog({
|
||||
|
|
@ -162,7 +164,7 @@ export function SettingsDialog({
|
|||
{} as Settings,
|
||||
);
|
||||
|
||||
console.log(
|
||||
debugLogger.debug(
|
||||
`[DEBUG SettingsDialog] Saving ${key} immediately with value:`,
|
||||
newValue,
|
||||
);
|
||||
|
|
@ -177,7 +179,7 @@ export function SettingsDialog({
|
|||
if (key === 'general.vimMode' && newValue !== vimEnabled) {
|
||||
// Call toggleVimEnabled to sync the VimModeContext local state
|
||||
toggleVimEnabled().catch((error) => {
|
||||
console.error('Failed to toggle vim mode:', error);
|
||||
debugLogger.error('Failed to toggle vim mode:', error);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -189,7 +191,7 @@ export function SettingsDialog({
|
|||
try {
|
||||
config?.setApprovalMode(settings.merged.tools.approvalMode);
|
||||
} catch (error) {
|
||||
console.error(
|
||||
debugLogger.error(
|
||||
'Failed to apply approval mode to current session:',
|
||||
error,
|
||||
);
|
||||
|
|
@ -663,7 +665,7 @@ export function SettingsDialog({
|
|||
try {
|
||||
config?.setApprovalMode(settings.merged.tools.approvalMode);
|
||||
} catch (error) {
|
||||
console.error(
|
||||
debugLogger.error(
|
||||
'Failed to apply approval mode to current session:',
|
||||
error,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import { render, Box, useApp } from 'ink';
|
|||
import { getGitBranch, SessionService } from '@qwen-code/qwen-code-core';
|
||||
import { KeypressProvider } from '../contexts/KeypressContext.js';
|
||||
import { SessionPicker } from './SessionPicker.js';
|
||||
import { writeStdoutLine } from '../../utils/stdioHelpers.js';
|
||||
|
||||
interface StandalonePickerScreenProps {
|
||||
sessionService: SessionService;
|
||||
|
|
@ -70,7 +71,7 @@ export async function showResumeSessionPicker(
|
|||
const sessionService = new SessionService(cwd);
|
||||
const hasSession = await sessionService.loadLastSession();
|
||||
if (!hasSession) {
|
||||
console.log('No sessions found. Start a new session with `qwen`.');
|
||||
writeStdoutLine('No sessions found. Start a new session with `qwen`.');
|
||||
return undefined;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,8 +10,10 @@ import stringWidth from 'string-width';
|
|||
import { theme } from '../../semantic-colors.js';
|
||||
import { toCodePoints } from '../../utils/textUtils.js';
|
||||
import { useOverflowActions } from '../../contexts/OverflowContext.js';
|
||||
import { createDebugLogger } from '@qwen-code/qwen-code-core';
|
||||
|
||||
let enableDebugLog = false;
|
||||
const debugLogger = createDebugLogger('MAX_SIZED_BOX');
|
||||
|
||||
/**
|
||||
* Minimum height for the MaxSizedBox component.
|
||||
|
|
@ -28,7 +30,7 @@ function debugReportError(message: string, element: React.ReactNode) {
|
|||
if (!enableDebugLog) return;
|
||||
|
||||
if (!React.isValidElement(element)) {
|
||||
console.error(
|
||||
debugLogger.error(
|
||||
message,
|
||||
`Invalid element: '${String(element)}' typeof=${typeof element}`,
|
||||
);
|
||||
|
|
@ -44,10 +46,13 @@ function debugReportError(message: string, element: React.ReactNode) {
|
|||
const lineNumber = elementWithSource._source?.lineNumber;
|
||||
sourceMessage = fileName ? `${fileName}:${lineNumber}` : '<Unknown file>';
|
||||
} catch (error) {
|
||||
console.error('Error while trying to get file name:', error);
|
||||
debugLogger.error('Error while trying to get file name:', error);
|
||||
}
|
||||
|
||||
console.error(message, `${String(element.type)}. Source: ${sourceMessage}`);
|
||||
debugLogger.error(
|
||||
message,
|
||||
`${String(element.type)}. Source: ${sourceMessage}`,
|
||||
);
|
||||
}
|
||||
interface MaxSizedBoxProps {
|
||||
children?: React.ReactNode;
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import fs from 'node:fs';
|
|||
import os from 'node:os';
|
||||
import pathMod from 'node:path';
|
||||
import { useState, useCallback, useEffect, useMemo, useReducer } from 'react';
|
||||
import { unescapePath } from '@qwen-code/qwen-code-core';
|
||||
import { createDebugLogger, unescapePath } from '@qwen-code/qwen-code-core';
|
||||
import {
|
||||
toCodePoints,
|
||||
cpLen,
|
||||
|
|
@ -20,6 +20,8 @@ import {
|
|||
import type { VimAction } from './vim-buffer-actions.js';
|
||||
import { handleVimAction } from './vim-buffer-actions.js';
|
||||
|
||||
const debugLogger = createDebugLogger('TEXT_BUFFER');
|
||||
|
||||
export type Direction =
|
||||
| 'left'
|
||||
| 'right'
|
||||
|
|
@ -1143,7 +1145,7 @@ function textBufferReducerLogic(
|
|||
break;
|
||||
default: {
|
||||
const exhaustiveCheck: never = dir;
|
||||
console.error(
|
||||
debugLogger.error(
|
||||
`Unknown visual movement direction: ${exhaustiveCheck}`,
|
||||
);
|
||||
return state;
|
||||
|
|
@ -1489,7 +1491,7 @@ function textBufferReducerLogic(
|
|||
|
||||
default: {
|
||||
const exhaustiveCheck: never = action;
|
||||
console.error(`Unknown action encountered: ${exhaustiveCheck}`);
|
||||
debugLogger.error(`Unknown action encountered: ${exhaustiveCheck}`);
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
|
@ -1858,7 +1860,7 @@ export function useTextBuffer({
|
|||
newText = newText.replace(/\r\n?/g, '\n');
|
||||
dispatch({ type: 'set_text', payload: newText, pushToUndo: false });
|
||||
} catch (err) {
|
||||
console.error('[useTextBuffer] external editor error', err);
|
||||
debugLogger.error('[useTextBuffer] external editor error', err);
|
||||
} finally {
|
||||
if (wasRaw) setRawMode?.(true);
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -11,12 +11,15 @@ import type {
|
|||
SubagentManager,
|
||||
SubagentConfig,
|
||||
} from '@qwen-code/qwen-code-core';
|
||||
import { createDebugLogger } from '@qwen-code/qwen-code-core';
|
||||
import { theme } from '../../../semantic-colors.js';
|
||||
import { shouldShowColor, getColorForDisplay } from '../utils.js';
|
||||
import { useLaunchEditor } from '../../../hooks/useLaunchEditor.js';
|
||||
import { useKeypress } from '../../../hooks/useKeypress.js';
|
||||
import { t } from '../../../../i18n/index.js';
|
||||
|
||||
const debugLogger = createDebugLogger('SUBAGENT_CREATION_SUMMARY');
|
||||
|
||||
/**
|
||||
* Step 6: Final confirmation and actions.
|
||||
*/
|
||||
|
|
@ -87,7 +90,7 @@ export function CreationSummary({
|
|||
}
|
||||
} catch (error) {
|
||||
// Silently handle errors in warning checks
|
||||
console.warn('Error checking subagent name availability:', error);
|
||||
debugLogger.warn('Error checking subagent name availability:', error);
|
||||
}
|
||||
|
||||
// Check length warnings
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
import { Box, Text } from 'ink';
|
||||
import { type SubagentConfig } from '@qwen-code/qwen-code-core';
|
||||
import { createDebugLogger } from '@qwen-code/qwen-code-core';
|
||||
import type { StepNavigationProps } from '../types.js';
|
||||
import { theme } from '../../../semantic-colors.js';
|
||||
import { useKeypress } from '../../../hooks/useKeypress.js';
|
||||
|
|
@ -16,6 +17,8 @@ interface AgentDeleteStepProps extends StepNavigationProps {
|
|||
onDelete: (agent: SubagentConfig) => Promise<void>;
|
||||
}
|
||||
|
||||
const debugLogger = createDebugLogger('AGENT_DELETE_STEP');
|
||||
|
||||
export function AgentDeleteStep({
|
||||
selectedAgent,
|
||||
onDelete,
|
||||
|
|
@ -30,7 +33,7 @@ export function AgentDeleteStep({
|
|||
await onDelete(selectedAgent);
|
||||
// Navigation will be handled by the parent component after successful deletion
|
||||
} catch (error) {
|
||||
console.error('Failed to delete agent:', error);
|
||||
debugLogger.error('Failed to delete agent:', error);
|
||||
}
|
||||
} else if (key.name === 'n') {
|
||||
onNavigateBack();
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import { MANAGEMENT_STEPS } from '../types.js';
|
|||
import { theme } from '../../../semantic-colors.js';
|
||||
import { getColorForDisplay, shouldShowColor } from '../utils.js';
|
||||
import type { SubagentConfig, Config } from '@qwen-code/qwen-code-core';
|
||||
import { createDebugLogger } from '@qwen-code/qwen-code-core';
|
||||
import { useKeypress } from '../../../hooks/useKeypress.js';
|
||||
import { t } from '../../../../i18n/index.js';
|
||||
|
||||
|
|
@ -25,6 +26,8 @@ interface AgentsManagerDialogProps {
|
|||
config: Config | null;
|
||||
}
|
||||
|
||||
const debugLogger = createDebugLogger('AGENTS_MANAGER_DIALOG');
|
||||
|
||||
/**
|
||||
* Main orchestrator component for the agents management dialog.
|
||||
*/
|
||||
|
|
@ -108,7 +111,7 @@ export function AgentsManagerDialog({
|
|||
setNavigationStack([MANAGEMENT_STEPS.AGENT_SELECTION]);
|
||||
setSelectedAgentIndex(-1);
|
||||
} catch (error) {
|
||||
console.error('Failed to delete agent:', error);
|
||||
debugLogger.error('Failed to delete agent:', error);
|
||||
throw error; // Re-throw to let the component handle the error state
|
||||
}
|
||||
},
|
||||
|
|
@ -253,7 +256,7 @@ export function AgentsManagerDialog({
|
|||
await loadAgents();
|
||||
handleNavigateBack();
|
||||
} catch (error) {
|
||||
console.error('Failed to save agent changes:', error);
|
||||
debugLogger.error('Failed to save agent changes:', error);
|
||||
}
|
||||
}
|
||||
}}
|
||||
|
|
@ -282,7 +285,7 @@ export function AgentsManagerDialog({
|
|||
await loadAgents();
|
||||
handleNavigateBack();
|
||||
} catch (error) {
|
||||
console.error('Failed to save color changes:', error);
|
||||
debugLogger.error('Failed to save color changes:', error);
|
||||
}
|
||||
}
|
||||
}}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,9 @@
|
|||
import { Box, Text } from 'ink';
|
||||
import { useUIState } from '../../contexts/UIStateContext.js';
|
||||
import { ExtensionUpdateState } from '../../state/extensions.js';
|
||||
import { createDebugLogger } from '@qwen-code/qwen-code-core';
|
||||
|
||||
const debugLogger = createDebugLogger('EXTENSIONS_LIST');
|
||||
|
||||
export const ExtensionsList = () => {
|
||||
const { extensionsUpdateState, commandContext } = useUIState();
|
||||
|
|
@ -47,7 +50,7 @@ export const ExtensionsList = () => {
|
|||
stateColor = 'green';
|
||||
break;
|
||||
default:
|
||||
console.error(`Unhandled ExtensionUpdateState ${state}`);
|
||||
debugLogger.error(`Unhandled ExtensionUpdateState ${state}`);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue