Skip to content

Commit 4d93ffb

Browse files
author
catlog22
committed
feat: Add migration handling for Codex old reference format in CLI manager
1 parent 204cb20 commit 4d93ffb

2 files changed

Lines changed: 52 additions & 8 deletions

File tree

ccw/src/core/routes/claude-routes.ts

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -918,9 +918,11 @@ export async function handleClaudeRoutes(ctx: RouteContext): Promise<boolean> {
918918
const userCodexPath = join(homedir(), '.codex', 'AGENTS.md');
919919
const chineseRefPattern = /@.*chinese-response\.md/i;
920920
const chineseSectionPattern = /## /; // For Codex direct content
921+
const oldCodexRefPattern = /- \*\*\*\*:\s*@.*chinese-response\.md/i; // Old Codex format
921922

922923
let claudeEnabled = false;
923924
let codexEnabled = false;
925+
let codexNeedsMigration = false;
924926
let guidelinesPath = '';
925927

926928
// Check if user CLAUDE.md exists and contains Chinese response reference
@@ -934,6 +936,10 @@ export async function handleClaudeRoutes(ctx: RouteContext): Promise<boolean> {
934936
if (existsSync(userCodexPath)) {
935937
const content = readFileSync(userCodexPath, 'utf8');
936938
codexEnabled = chineseSectionPattern.test(content);
939+
// Check if Codex has old @ reference format that needs migration
940+
if (codexEnabled && oldCodexRefPattern.test(content)) {
941+
codexNeedsMigration = true;
942+
}
937943
}
938944

939945
// Find guidelines file path - always use user-level path
@@ -948,6 +954,7 @@ export async function handleClaudeRoutes(ctx: RouteContext): Promise<boolean> {
948954
enabled: claudeEnabled, // backward compatibility
949955
claudeEnabled,
950956
codexEnabled,
957+
codexNeedsMigration, // New field: true if Codex has old @ reference format
951958
guidelinesPath,
952959
guidelinesExists: !!guidelinesPath,
953960
userClaudeMdExists: existsSync(userClaudePath),
@@ -1002,11 +1009,36 @@ export async function handleClaudeRoutes(ctx: RouteContext): Promise<boolean> {
10021009
if (isCodex) {
10031010
// Codex: Direct content concatenation (does not support @ references)
10041011
const chineseSectionPattern = /\n*## \n[\s\S]*?(?=\n## |$)/;
1012+
const oldRefPattern = /- \*\*\*\*:\s*@.*chinese-response\.md/i; // Old @ reference format
10051013

10061014
if (enabled) {
1007-
// Check if section already exists
1008-
if (chineseSectionPattern.test(content)) {
1009-
return { success: true, message: 'Already enabled' };
1015+
// Check if section exists and if it needs migration
1016+
const hasSection = chineseSectionPattern.test(content);
1017+
1018+
if (hasSection) {
1019+
// Check if it's the old format with @ reference
1020+
const hasOldRef = oldRefPattern.test(content);
1021+
1022+
if (hasOldRef) {
1023+
// Migrate: remove old section and add new content
1024+
content = content.replace(chineseSectionPattern, '\n');
1025+
content = content.replace(/\n{3,}/g, '\n\n').trim();
1026+
if (content) content += '\n';
1027+
1028+
// Read chinese-response.md content
1029+
const chineseResponseContent = readFileSync(userGuidelinesPath, 'utf8');
1030+
1031+
// Add new section with direct content
1032+
const newSection = `\n## 中文回复\n\n${chineseResponseContent}\n`;
1033+
content = content.trimEnd() + '\n' + newSection;
1034+
1035+
writeFileSync(targetFile, content, 'utf8');
1036+
1037+
return { success: true, enabled, migrated: true, message: 'Migrated from @ reference to direct content' };
1038+
}
1039+
1040+
// Already has correct format
1041+
return { success: true, message: 'Already enabled with correct format' };
10101042
}
10111043

10121044
// Read chinese-response.md content
@@ -1016,7 +1048,7 @@ export async function handleClaudeRoutes(ctx: RouteContext): Promise<boolean> {
10161048
const newSection = `\n## 中文回复\n\n${chineseResponseContent}\n`;
10171049
content = content.trimEnd() + '\n' + newSection;
10181050
} else {
1019-
// Remove Chinese response section
1051+
// Remove Chinese response section (both old and new format)
10201052
content = content.replace(chineseSectionPattern, '\n');
10211053
content = content.replace(/\n{3,}/g, '\n\n').trim();
10221054
if (content) content += '\n';

ccw/src/templates/dashboard-js/views/cli-manager.js

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1613,6 +1613,7 @@ var chineseResponseEnabled = false;
16131613
var chineseResponseLoading = false;
16141614
var codexChineseResponseEnabled = false;
16151615
var codexChineseResponseLoading = false;
1616+
var codexChineseNeedsMigration = false; // Track if Codex needs migration from old @ reference
16161617
var codexCliEnhancementEnabled = false;
16171618
var codexCliEnhancementLoading = false;
16181619
var windowsPlatformEnabled = false;
@@ -1626,12 +1627,14 @@ async function loadLanguageSettings() {
16261627
var data = await response.json();
16271628
chineseResponseEnabled = data.claudeEnabled || data.enabled || false;
16281629
codexChineseResponseEnabled = data.codexEnabled || false;
1630+
codexChineseNeedsMigration = data.codexNeedsMigration || false; // Track migration status
16291631
return data;
16301632
} catch (err) {
16311633
console.error('Failed to load language settings:', err);
16321634
chineseResponseEnabled = false;
16331635
codexChineseResponseEnabled = false;
1634-
return { claudeEnabled: false, codexEnabled: false, guidelinesExists: false };
1636+
codexChineseNeedsMigration = false;
1637+
return { claudeEnabled: false, codexEnabled: false, codexNeedsMigration: false, guidelinesExists: false };
16351638
}
16361639
}
16371640

@@ -1708,16 +1711,23 @@ async function toggleChineseResponse(enabled, target) {
17081711
var data = await response.json();
17091712
if (isCodex) {
17101713
codexChineseResponseEnabled = data.enabled;
1714+
// Handle migration status
1715+
if (data.migrated) {
1716+
codexChineseNeedsMigration = false;
1717+
showRefreshToast('Codex: 已从 @ 引用迁移到直接文本拼接', 'success');
1718+
}
17111719
} else {
17121720
chineseResponseEnabled = data.enabled;
17131721
}
17141722

17151723
// Update UI
17161724
renderLanguageSettingsSection();
17171725

1718-
// Show toast
1726+
// Show toast (skip if migration message already shown)
17191727
var toolName = isCodex ? 'Codex' : 'Claude';
1720-
showRefreshToast(toolName + ': ' + (enabled ? t('lang.enableSuccess') : t('lang.disableSuccess')), 'success');
1728+
if (!data.migrated) {
1729+
showRefreshToast(toolName + ': ' + (enabled ? t('lang.enableSuccess') : t('lang.disableSuccess')), 'success');
1730+
}
17211731
} catch (err) {
17221732
console.error('Failed to toggle Chinese response:', err);
17231733
// Error already shown in the !response.ok block
@@ -1921,7 +1931,9 @@ async function renderLanguageSettingsSection() {
19211931
(codexChineseResponseEnabled ? t('lang.enabled') : t('lang.disabled')) +
19221932
'</span>' +
19231933
'</div>' +
1924-
'<p class="cli-setting-desc">' + t('lang.chineseDescCodex') + '</p>' +
1934+
'<p class="cli-setting-desc">' + t('lang.chineseDescCodex') +
1935+
(codexChineseNeedsMigration ? '<br><span style="color: #f59e0b; font-size: 0.85em;">⚠️ 检测到旧格式(@引用),请关闭后重新启用以迁移到新格式</span>' : '') +
1936+
'</p>' +
19251937
'</div>' +
19261938
// Windows Platform
19271939
'<div class="cli-setting-item">' +

0 commit comments

Comments
 (0)