diff --git a/.codex/AGENTS.md b/.codex/AGENTS.md index d485d40a..21c1e653 100644 --- a/.codex/AGENTS.md +++ b/.codex/AGENTS.md @@ -1,8 +1,5 @@ # Codex Code Guidelines -**Strictly follow the cli-tools.json configuration** - -Available CLI endpoints are dynamically defined by the config file ## Code Quality Standards diff --git a/ccw/src/core/routes/claude-routes.ts b/ccw/src/core/routes/claude-routes.ts index 5bec67c2..817c5ca7 100644 --- a/ccw/src/core/routes/claude-routes.ts +++ b/ccw/src/core/routes/claude-routes.ts @@ -1099,9 +1099,12 @@ export async function handleClaudeRoutes(ctx: RouteContext): Promise { // 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; + const { enabled, action } = body; - if (typeof enabled !== 'boolean') { + // Support two actions: 'toggle' (default) and 'refresh' + const actionType = action || 'toggle'; + + if (actionType === 'toggle' && typeof enabled !== 'boolean') { return { error: 'Missing or invalid enabled parameter', status: 400 }; } @@ -1123,10 +1126,52 @@ export async function handleClaudeRoutes(ctx: RouteContext): Promise { } const cliEnhancementSectionPattern = /\n*## CLI 工具调用\n[\s\S]*?(?=\n## |$)/; + const isCurrentlyEnabled = cliEnhancementSectionPattern.test(content); + // Handle refresh action + if (actionType === 'refresh') { + if (!isCurrentlyEnabled) { + return { error: 'CLI enhancement is not enabled, cannot refresh', status: 400 }; + } + + // Remove existing section + content = content.replace(cliEnhancementSectionPattern, '\n'); + content = content.replace(/\n{3,}/g, '\n\n').trim(); + if (content) content += '\n'; + + // Read and add updated section + 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 }; + } + + 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`; + } + + const newSection = `\n## CLI 工具调用\n\n${cliToolsUsageContent}\n${cliToolsJsonContent}`; + content = content.trimEnd() + '\n' + newSection; + + writeFileSync(targetFile, content, 'utf8'); + + broadcastToClients({ + type: 'CLI_ENHANCEMENT_SETTING_CHANGED', + data: { cliEnhancement: true, refreshed: true } + }); + + return { success: true, refreshed: true }; + } + + // Handle toggle action if (enabled) { // Check if section already exists - if (cliEnhancementSectionPattern.test(content)) { + if (isCurrentlyEnabled) { return { success: true, message: 'Already enabled' }; } diff --git a/ccw/src/templates/dashboard-css/18-cli-settings.css b/ccw/src/templates/dashboard-css/18-cli-settings.css index 64601fff..9b430588 100644 --- a/ccw/src/templates/dashboard-css/18-cli-settings.css +++ b/ccw/src/templates/dashboard-css/18-cli-settings.css @@ -65,6 +65,41 @@ .cli-setting-control { margin-bottom: 0.5rem; flex-shrink: 0; + display: flex; + align-items: center; + gap: 0.5rem; +} + +/* Small icon button for refresh etc */ +.btn-icon-sm { + display: inline-flex; + align-items: center; + justify-content: center; + width: 24px; + height: 24px; + padding: 0; + border: 1px solid hsl(var(--border)); + border-radius: 0.375rem; + background: hsl(var(--background)); + color: hsl(var(--muted-foreground)); + cursor: pointer; + transition: all 0.15s ease; +} + +.btn-icon-sm:hover:not(:disabled) { + border-color: hsl(var(--primary) / 0.5); + color: hsl(var(--primary)); + background: hsl(var(--primary) / 0.05); +} + +.btn-icon-sm:disabled { + opacity: 0.5; + cursor: not-allowed; +} + +.btn-icon-sm i { + width: 12px; + height: 12px; } .cli-setting-select { diff --git a/ccw/src/templates/dashboard-js/views/cli-manager.js b/ccw/src/templates/dashboard-js/views/cli-manager.js index c89536f0..ef63d58f 100644 --- a/ccw/src/templates/dashboard-js/views/cli-manager.js +++ b/ccw/src/templates/dashboard-js/views/cli-manager.js @@ -1797,7 +1797,7 @@ async function toggleCodexCliEnhancement(enabled) { var response = await fetch('/api/language/codex-cli-enhancement', { method: 'POST', headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ enabled: enabled }) + body: JSON.stringify({ enabled: enabled, action: 'toggle' }) }); if (!response.ok) { @@ -1828,6 +1828,46 @@ async function toggleCodexCliEnhancement(enabled) { } } +async function refreshCodexCliEnhancement() { + if (codexCliEnhancementLoading) return; + + codexCliEnhancementLoading = true; + + try { + var response = await fetch('/api/language/codex-cli-enhancement', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ action: 'refresh' }) + }); + + if (!response.ok) { + var errData = await response.json(); + var errorMsg = errData.error || 'Failed to refresh setting'; + if (errorMsg.includes('not found')) { + showRefreshToast(t('lang.installRequired'), 'warning'); + } else if (errorMsg.includes('not enabled')) { + showRefreshToast('CLI 调用增强未启用', 'warning'); + } else { + showRefreshToast('刷新失败: ' + errorMsg, 'error'); + } + throw new Error(errorMsg); + } + + var data = await response.json(); + + // Update UI + renderLanguageSettingsSection(); + + // Show toast + showRefreshToast('CLI 调用增强已刷新', 'success'); + } catch (err) { + console.error('Failed to refresh Codex CLI enhancement:', err); + // Error already shown in the !response.ok block + } finally { + codexCliEnhancementLoading = false; + } +} + async function renderLanguageSettingsSection() { var container = document.getElementById('language-settings-section'); if (!container) return; @@ -1914,8 +1954,15 @@ async function renderLanguageSettingsSection() { '' + (codexCliEnhancementEnabled ? t('lang.enabled') : t('lang.disabled')) + '' + + (codexCliEnhancementEnabled ? + '' + : '') + '' + - '

为 Codex 启用多 CLI 工具调用功能,自动拼接 cli-tools-usage.md 和 cli-tools.json 配置

' + + '

为 Codex 启用多 CLI 工具调用功能,自动拼接 cli-tools-usage.md 和 cli-tools.json 配置' + + (codexCliEnhancementEnabled ? '
💡 配置文件变更后,点击刷新按钮更新内容' : '') + + '

' + '' + '';