From 4d93ffb06cde83f20cc4fab8de3551c115a5313c Mon Sep 17 00:00:00 2001 From: catlog22 Date: Wed, 28 Jan 2026 23:37:46 +0800 Subject: [PATCH] feat: Add migration handling for Codex old reference format in CLI manager --- ccw/src/core/routes/claude-routes.ts | 40 +++++++++++++++++-- .../dashboard-js/views/cli-manager.js | 20 ++++++++-- 2 files changed, 52 insertions(+), 8 deletions(-) diff --git a/ccw/src/core/routes/claude-routes.ts b/ccw/src/core/routes/claude-routes.ts index 817c5ca7..ad105894 100644 --- a/ccw/src/core/routes/claude-routes.ts +++ b/ccw/src/core/routes/claude-routes.ts @@ -918,9 +918,11 @@ export async function handleClaudeRoutes(ctx: RouteContext): Promise { const userCodexPath = join(homedir(), '.codex', 'AGENTS.md'); const chineseRefPattern = /@.*chinese-response\.md/i; const chineseSectionPattern = /## 中文回复/; // For Codex direct content + const oldCodexRefPattern = /- \*\*中文回复准则\*\*:\s*@.*chinese-response\.md/i; // Old Codex format let claudeEnabled = false; let codexEnabled = false; + let codexNeedsMigration = false; let guidelinesPath = ''; // Check if user CLAUDE.md exists and contains Chinese response reference @@ -934,6 +936,10 @@ export async function handleClaudeRoutes(ctx: RouteContext): Promise { if (existsSync(userCodexPath)) { const content = readFileSync(userCodexPath, 'utf8'); codexEnabled = chineseSectionPattern.test(content); + // Check if Codex has old @ reference format that needs migration + if (codexEnabled && oldCodexRefPattern.test(content)) { + codexNeedsMigration = true; + } } // Find guidelines file path - always use user-level path @@ -948,6 +954,7 @@ export async function handleClaudeRoutes(ctx: RouteContext): Promise { enabled: claudeEnabled, // backward compatibility claudeEnabled, codexEnabled, + codexNeedsMigration, // New field: true if Codex has old @ reference format guidelinesPath, guidelinesExists: !!guidelinesPath, userClaudeMdExists: existsSync(userClaudePath), @@ -1002,11 +1009,36 @@ export async function handleClaudeRoutes(ctx: RouteContext): Promise { if (isCodex) { // Codex: Direct content concatenation (does not support @ references) const chineseSectionPattern = /\n*## 中文回复\n[\s\S]*?(?=\n## |$)/; + const oldRefPattern = /- \*\*中文回复准则\*\*:\s*@.*chinese-response\.md/i; // Old @ reference format if (enabled) { - // Check if section already exists - if (chineseSectionPattern.test(content)) { - return { success: true, message: 'Already enabled' }; + // Check if section exists and if it needs migration + const hasSection = chineseSectionPattern.test(content); + + if (hasSection) { + // Check if it's the old format with @ reference + const hasOldRef = oldRefPattern.test(content); + + if (hasOldRef) { + // Migrate: remove old section and add new content + content = content.replace(chineseSectionPattern, '\n'); + content = content.replace(/\n{3,}/g, '\n\n').trim(); + if (content) content += '\n'; + + // Read chinese-response.md content + const chineseResponseContent = readFileSync(userGuidelinesPath, 'utf8'); + + // Add new section with direct content + const newSection = `\n## 中文回复\n\n${chineseResponseContent}\n`; + content = content.trimEnd() + '\n' + newSection; + + writeFileSync(targetFile, content, 'utf8'); + + return { success: true, enabled, migrated: true, message: 'Migrated from @ reference to direct content' }; + } + + // Already has correct format + return { success: true, message: 'Already enabled with correct format' }; } // Read chinese-response.md content @@ -1016,7 +1048,7 @@ export async function handleClaudeRoutes(ctx: RouteContext): Promise { const newSection = `\n## 中文回复\n\n${chineseResponseContent}\n`; content = content.trimEnd() + '\n' + newSection; } else { - // Remove Chinese response section + // Remove Chinese response section (both old and new format) content = content.replace(chineseSectionPattern, '\n'); content = content.replace(/\n{3,}/g, '\n\n').trim(); if (content) content += '\n'; diff --git a/ccw/src/templates/dashboard-js/views/cli-manager.js b/ccw/src/templates/dashboard-js/views/cli-manager.js index ef63d58f..a7c12241 100644 --- a/ccw/src/templates/dashboard-js/views/cli-manager.js +++ b/ccw/src/templates/dashboard-js/views/cli-manager.js @@ -1613,6 +1613,7 @@ var chineseResponseEnabled = false; var chineseResponseLoading = false; var codexChineseResponseEnabled = false; var codexChineseResponseLoading = false; +var codexChineseNeedsMigration = false; // Track if Codex needs migration from old @ reference var codexCliEnhancementEnabled = false; var codexCliEnhancementLoading = false; var windowsPlatformEnabled = false; @@ -1626,12 +1627,14 @@ async function loadLanguageSettings() { var data = await response.json(); chineseResponseEnabled = data.claudeEnabled || data.enabled || false; codexChineseResponseEnabled = data.codexEnabled || false; + codexChineseNeedsMigration = data.codexNeedsMigration || false; // Track migration status return data; } catch (err) { console.error('Failed to load language settings:', err); chineseResponseEnabled = false; codexChineseResponseEnabled = false; - return { claudeEnabled: false, codexEnabled: false, guidelinesExists: false }; + codexChineseNeedsMigration = false; + return { claudeEnabled: false, codexEnabled: false, codexNeedsMigration: false, guidelinesExists: false }; } } @@ -1708,6 +1711,11 @@ async function toggleChineseResponse(enabled, target) { var data = await response.json(); if (isCodex) { codexChineseResponseEnabled = data.enabled; + // Handle migration status + if (data.migrated) { + codexChineseNeedsMigration = false; + showRefreshToast('Codex: 已从 @ 引用迁移到直接文本拼接', 'success'); + } } else { chineseResponseEnabled = data.enabled; } @@ -1715,9 +1723,11 @@ async function toggleChineseResponse(enabled, target) { // Update UI renderLanguageSettingsSection(); - // Show toast + // Show toast (skip if migration message already shown) var toolName = isCodex ? 'Codex' : 'Claude'; - showRefreshToast(toolName + ': ' + (enabled ? t('lang.enableSuccess') : t('lang.disableSuccess')), 'success'); + if (!data.migrated) { + showRefreshToast(toolName + ': ' + (enabled ? t('lang.enableSuccess') : t('lang.disableSuccess')), 'success'); + } } catch (err) { console.error('Failed to toggle Chinese response:', err); // Error already shown in the !response.ok block @@ -1921,7 +1931,9 @@ async function renderLanguageSettingsSection() { (codexChineseResponseEnabled ? t('lang.enabled') : t('lang.disabled')) + '' + '' + - '

' + t('lang.chineseDescCodex') + '

' + + '

' + t('lang.chineseDescCodex') + + (codexChineseNeedsMigration ? '
⚠️ 检测到旧格式(@引用),请关闭后重新启用以迁移到新格式' : '') + + '

' + '' + // Windows Platform '
' +