mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-02-12 02:37:45 +08:00
feat: Implement Codex CLI enhancement settings with API integration and UI toggle
This commit is contained in:
@@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
### Configuration File
|
### Configuration File
|
||||||
|
|
||||||
**Path**: `.claude/cli-tools.json`
|
**Path**: `~/.claude/cli-tools.json`
|
||||||
|
|
||||||
All tool availability, model selection, and routing are defined in this configuration file.
|
All tool availability, model selection, and routing are defined in this configuration file.
|
||||||
|
|
||||||
|
|||||||
@@ -1002,7 +1002,6 @@ export async function handleClaudeRoutes(ctx: RouteContext): Promise<boolean> {
|
|||||||
if (isCodex) {
|
if (isCodex) {
|
||||||
// Codex: Direct content concatenation (does not support @ references)
|
// Codex: Direct content concatenation (does not support @ references)
|
||||||
const chineseSectionPattern = /\n*## 中文回复\n[\s\S]*?(?=\n## |$)/;
|
const chineseSectionPattern = /\n*## 中文回复\n[\s\S]*?(?=\n## |$)/;
|
||||||
const cliToolsSectionPattern = /\n*## CLI \u5de5\u5177\u8c03\u7528\n[\s\S]*?(?=\n## |$)/;
|
|
||||||
|
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
// Check if section already exists
|
// Check if section already exists
|
||||||
@@ -1013,34 +1012,12 @@ export async function handleClaudeRoutes(ctx: RouteContext): Promise<boolean> {
|
|||||||
// Read chinese-response.md content
|
// Read chinese-response.md content
|
||||||
const chineseResponseContent = readFileSync(userGuidelinesPath, 'utf8');
|
const chineseResponseContent = readFileSync(userGuidelinesPath, 'utf8');
|
||||||
|
|
||||||
// Read cli-tools-usage.md content
|
// Add Chinese response section only
|
||||||
const cliToolsUsagePath = join(homedir(), '.claude', 'workflows', 'cli-tools-usage.md');
|
const newSection = `\n## 中文回复\n\n${chineseResponseContent}\n`;
|
||||||
let cliToolsUsageContent = '';
|
|
||||||
if (existsSync(cliToolsUsagePath)) {
|
|
||||||
cliToolsUsageContent = readFileSync(cliToolsUsagePath, 'utf8');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read and format cli-tools.json
|
|
||||||
const cliToolsJsonPath = join(homedir(), '.claude', 'cli-tools.json');
|
|
||||||
let cliToolsJsonContent = '';
|
|
||||||
if (existsSync(cliToolsJsonPath)) {
|
|
||||||
const cliToolsJson = JSON.parse(readFileSync(cliToolsJsonPath, 'utf8'));
|
|
||||||
cliToolsJsonContent = `\n### CLI Tools Configuration\n\n\`\`\`json\n${JSON.stringify(cliToolsJson, null, 2)}\n\`\`\`\n`;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add Chinese response section
|
|
||||||
let newSection = `\n## 中文回复\n\n${chineseResponseContent}\n`;
|
|
||||||
|
|
||||||
// Add CLI tools section if usage content exists
|
|
||||||
if (cliToolsUsageContent) {
|
|
||||||
newSection += `\n## CLI 工具调用\n\n${cliToolsUsageContent}\n${cliToolsJsonContent}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
content = content.trimEnd() + '\n' + newSection;
|
content = content.trimEnd() + '\n' + newSection;
|
||||||
} else {
|
} else {
|
||||||
// Remove both sections
|
// Remove Chinese response section
|
||||||
content = content.replace(chineseSectionPattern, '\n');
|
content = content.replace(chineseSectionPattern, '\n');
|
||||||
content = content.replace(cliToolsSectionPattern, '\n');
|
|
||||||
content = content.replace(/\n{3,}/g, '\n\n').trim();
|
content = content.replace(/\n{3,}/g, '\n\n').trim();
|
||||||
if (content) content += '\n';
|
if (content) content += '\n';
|
||||||
}
|
}
|
||||||
@@ -1082,6 +1059,120 @@ export async function handleClaudeRoutes(ctx: RouteContext): Promise<boolean> {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// API: Get Codex CLI Enhancement setting status
|
||||||
|
if (pathname === '/api/language/codex-cli-enhancement' && req.method === 'GET') {
|
||||||
|
try {
|
||||||
|
const userCodexPath = join(homedir(), '.codex', 'AGENTS.md');
|
||||||
|
const cliEnhancementSectionPattern = /## CLI 工具调用/; // For Codex CLI enhancement
|
||||||
|
|
||||||
|
let enabled = false;
|
||||||
|
let guidelinesPath = '';
|
||||||
|
|
||||||
|
// Check if user AGENTS.md exists and contains CLI enhancement section
|
||||||
|
if (existsSync(userCodexPath)) {
|
||||||
|
const content = readFileSync(userCodexPath, 'utf8');
|
||||||
|
enabled = cliEnhancementSectionPattern.test(content);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find guidelines file path
|
||||||
|
const userGuidelinesPath = join(homedir(), '.claude', 'workflows', 'cli-tools-usage.md');
|
||||||
|
|
||||||
|
if (existsSync(userGuidelinesPath)) {
|
||||||
|
guidelinesPath = userGuidelinesPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
res.writeHead(200, { 'Content-Type': 'application/json' });
|
||||||
|
res.end(JSON.stringify({
|
||||||
|
enabled,
|
||||||
|
guidelinesPath,
|
||||||
|
guidelinesExists: !!guidelinesPath,
|
||||||
|
userCodexAgentsExists: existsSync(userCodexPath)
|
||||||
|
}));
|
||||||
|
return true;
|
||||||
|
} catch (error) {
|
||||||
|
res.writeHead(500, { 'Content-Type': 'application/json' });
|
||||||
|
res.end(JSON.stringify({ error: (error as Error).message }));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// API: Toggle Codex CLI Enhancement setting
|
||||||
|
if (pathname === '/api/language/codex-cli-enhancement' && req.method === 'POST') {
|
||||||
|
handlePostRequest(req, res, async (body: any) => {
|
||||||
|
const { enabled } = body;
|
||||||
|
|
||||||
|
if (typeof enabled !== 'boolean') {
|
||||||
|
return { error: 'Missing or invalid enabled parameter', status: 400 };
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const targetDir = join(homedir(), '.codex');
|
||||||
|
const targetFile = join(targetDir, 'AGENTS.md');
|
||||||
|
|
||||||
|
// Ensure target directory exists
|
||||||
|
if (!existsSync(targetDir)) {
|
||||||
|
mkdirSync(targetDir, { recursive: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
let content = '';
|
||||||
|
if (existsSync(targetFile)) {
|
||||||
|
content = readFileSync(targetFile, 'utf8');
|
||||||
|
} else {
|
||||||
|
// Create new file with minimal header
|
||||||
|
content = '# Codex Code Guidelines\n\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
const cliEnhancementSectionPattern = /\n*## CLI 工具调用\n[\s\S]*?(?=\n## |$)/;
|
||||||
|
|
||||||
|
if (enabled) {
|
||||||
|
// Check if section already exists
|
||||||
|
if (cliEnhancementSectionPattern.test(content)) {
|
||||||
|
return { success: true, message: 'Already enabled' };
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read cli-tools-usage.md content
|
||||||
|
const cliToolsUsagePath = join(homedir(), '.claude', 'workflows', 'cli-tools-usage.md');
|
||||||
|
let cliToolsUsageContent = '';
|
||||||
|
if (existsSync(cliToolsUsagePath)) {
|
||||||
|
cliToolsUsageContent = readFileSync(cliToolsUsagePath, 'utf8');
|
||||||
|
} else {
|
||||||
|
return { error: 'CLI tools usage guidelines file not found at ~/.claude/workflows/cli-tools-usage.md', status: 404 };
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read and format cli-tools.json
|
||||||
|
const cliToolsJsonPath = join(homedir(), '.claude', 'cli-tools.json');
|
||||||
|
let cliToolsJsonContent = '';
|
||||||
|
if (existsSync(cliToolsJsonPath)) {
|
||||||
|
const cliToolsJson = JSON.parse(readFileSync(cliToolsJsonPath, 'utf8'));
|
||||||
|
cliToolsJsonContent = `\n### CLI Tools Configuration\n\n\`\`\`json\n${JSON.stringify(cliToolsJson, null, 2)}\n\`\`\`\n`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add CLI enhancement section
|
||||||
|
const newSection = `\n## CLI 工具调用\n\n${cliToolsUsageContent}\n${cliToolsJsonContent}`;
|
||||||
|
content = content.trimEnd() + '\n' + newSection;
|
||||||
|
} else {
|
||||||
|
// Remove CLI enhancement section
|
||||||
|
content = content.replace(cliEnhancementSectionPattern, '\n');
|
||||||
|
content = content.replace(/\n{3,}/g, '\n\n').trim();
|
||||||
|
if (content) content += '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
writeFileSync(targetFile, content, 'utf8');
|
||||||
|
|
||||||
|
// Broadcast update
|
||||||
|
broadcastToClients({
|
||||||
|
type: 'CLI_ENHANCEMENT_SETTING_CHANGED',
|
||||||
|
data: { cliEnhancement: enabled }
|
||||||
|
});
|
||||||
|
|
||||||
|
return { success: true, enabled };
|
||||||
|
} catch (error) {
|
||||||
|
return { error: (error as Error).message, status: 500 };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// API: Get Windows platform setting status
|
// API: Get Windows platform setting status
|
||||||
if (pathname === '/api/language/windows-platform' && req.method === 'GET') {
|
if (pathname === '/api/language/windows-platform' && req.method === 'GET') {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -1613,6 +1613,8 @@ var chineseResponseEnabled = false;
|
|||||||
var chineseResponseLoading = false;
|
var chineseResponseLoading = false;
|
||||||
var codexChineseResponseEnabled = false;
|
var codexChineseResponseEnabled = false;
|
||||||
var codexChineseResponseLoading = false;
|
var codexChineseResponseLoading = false;
|
||||||
|
var codexCliEnhancementEnabled = false;
|
||||||
|
var codexCliEnhancementLoading = false;
|
||||||
var windowsPlatformEnabled = false;
|
var windowsPlatformEnabled = false;
|
||||||
var windowsPlatformLoading = false;
|
var windowsPlatformLoading = false;
|
||||||
|
|
||||||
@@ -1647,6 +1649,20 @@ async function loadWindowsPlatformSettings() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function loadCodexCliEnhancementSettings() {
|
||||||
|
try {
|
||||||
|
var response = await fetch('/api/language/codex-cli-enhancement');
|
||||||
|
if (!response.ok) throw new Error('Failed to load Codex CLI enhancement settings');
|
||||||
|
var data = await response.json();
|
||||||
|
codexCliEnhancementEnabled = data.enabled || false;
|
||||||
|
return data;
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Failed to load Codex CLI enhancement settings:', err);
|
||||||
|
codexCliEnhancementEnabled = false;
|
||||||
|
return { enabled: false, guidelinesExists: false };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function toggleChineseResponse(enabled, target) {
|
async function toggleChineseResponse(enabled, target) {
|
||||||
// target: 'claude' (default) or 'codex'
|
// target: 'claude' (default) or 'codex'
|
||||||
target = target || 'claude';
|
target = target || 'claude';
|
||||||
@@ -1763,6 +1779,55 @@ async function toggleWindowsPlatform(enabled) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function toggleCodexCliEnhancement(enabled) {
|
||||||
|
if (codexCliEnhancementLoading) return;
|
||||||
|
|
||||||
|
// Pre-check: verify CCW workflows are installed (only when enabling)
|
||||||
|
if (enabled && typeof ccwInstallStatus !== 'undefined' && !ccwInstallStatus.installed) {
|
||||||
|
var missingFile = ccwInstallStatus.missingFiles.find(function(f) { return f === 'cli-tools-usage.md'; });
|
||||||
|
if (missingFile) {
|
||||||
|
showRefreshToast(t('lang.installRequired'), 'warning');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
codexCliEnhancementLoading = true;
|
||||||
|
|
||||||
|
try {
|
||||||
|
var response = await fetch('/api/language/codex-cli-enhancement', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({ enabled: enabled })
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
var errData = await response.json();
|
||||||
|
// Show specific error message from backend
|
||||||
|
var errorMsg = errData.error || 'Failed to update setting';
|
||||||
|
if (errorMsg.includes('not found')) {
|
||||||
|
showRefreshToast(t('lang.installRequired'), 'warning');
|
||||||
|
} else {
|
||||||
|
showRefreshToast((enabled ? t('lang.enableFailed') : t('lang.disableFailed')) + ': ' + errorMsg, 'error');
|
||||||
|
}
|
||||||
|
throw new Error(errorMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
var data = await response.json();
|
||||||
|
codexCliEnhancementEnabled = data.enabled;
|
||||||
|
|
||||||
|
// Update UI
|
||||||
|
renderLanguageSettingsSection();
|
||||||
|
|
||||||
|
// Show toast
|
||||||
|
showRefreshToast('Codex CLI Enhancement: ' + (enabled ? t('lang.enableSuccess') : t('lang.disableSuccess')), 'success');
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Failed to toggle Codex CLI enhancement:', err);
|
||||||
|
// Error already shown in the !response.ok block
|
||||||
|
} finally {
|
||||||
|
codexCliEnhancementLoading = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function renderLanguageSettingsSection() {
|
async function renderLanguageSettingsSection() {
|
||||||
var container = document.getElementById('language-settings-section');
|
var container = document.getElementById('language-settings-section');
|
||||||
if (!container) return;
|
if (!container) return;
|
||||||
@@ -1774,6 +1839,9 @@ async function renderLanguageSettingsSection() {
|
|||||||
if (!windowsPlatformEnabled && !windowsPlatformLoading) {
|
if (!windowsPlatformEnabled && !windowsPlatformLoading) {
|
||||||
await loadWindowsPlatformSettings();
|
await loadWindowsPlatformSettings();
|
||||||
}
|
}
|
||||||
|
if (!codexCliEnhancementEnabled && !codexCliEnhancementLoading) {
|
||||||
|
await loadCodexCliEnhancementSettings();
|
||||||
|
}
|
||||||
|
|
||||||
var settingsHtml = '<div class="section-header">' +
|
var settingsHtml = '<div class="section-header">' +
|
||||||
'<div class="section-header-left">' +
|
'<div class="section-header-left">' +
|
||||||
@@ -1832,6 +1900,23 @@ async function renderLanguageSettingsSection() {
|
|||||||
'</div>' +
|
'</div>' +
|
||||||
'<p class="cli-setting-desc">' + t('lang.windowsDesc') + '</p>' +
|
'<p class="cli-setting-desc">' + t('lang.windowsDesc') + '</p>' +
|
||||||
'</div>' +
|
'</div>' +
|
||||||
|
// CLI Enhancement - Codex
|
||||||
|
'<div class="cli-setting-item">' +
|
||||||
|
'<label class="cli-setting-label">' +
|
||||||
|
'<i data-lucide="terminal" class="w-3 h-3"></i>' +
|
||||||
|
'CLI 调用增强 <span class="badge badge-sm badge-secondary">Codex</span>' +
|
||||||
|
'</label>' +
|
||||||
|
'<div class="cli-setting-control">' +
|
||||||
|
'<label class="cli-toggle">' +
|
||||||
|
'<input type="checkbox"' + (codexCliEnhancementEnabled ? ' checked' : '') + ' onchange="toggleCodexCliEnhancement(this.checked)"' + (codexCliEnhancementLoading ? ' disabled' : '') + '>' +
|
||||||
|
'<span class="cli-toggle-slider"></span>' +
|
||||||
|
'</label>' +
|
||||||
|
'<span class="cli-setting-status ' + (codexCliEnhancementEnabled ? 'enabled' : 'disabled') + '">' +
|
||||||
|
(codexCliEnhancementEnabled ? t('lang.enabled') : t('lang.disabled')) +
|
||||||
|
'</span>' +
|
||||||
|
'</div>' +
|
||||||
|
'<p class="cli-setting-desc">为 Codex 启用多 CLI 工具调用功能,自动拼接 cli-tools-usage.md 和 cli-tools.json 配置</p>' +
|
||||||
|
'</div>' +
|
||||||
'</div>';
|
'</div>';
|
||||||
|
|
||||||
container.innerHTML = settingsHtml;
|
container.innerHTML = settingsHtml;
|
||||||
|
|||||||
Reference in New Issue
Block a user