From 02531c4d1584752d143a150464b21f8a76c59cc4 Mon Sep 17 00:00:00 2001 From: catlog22 Date: Thu, 22 Jan 2026 14:53:38 +0800 Subject: [PATCH] feat: i18n for CLI history view; fix Claude session discovery path encoding MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Changes ### i18n 中文化 (i18n.js, cli-history.js) - 添加 60+ 个翻译键用于 CLI 执行历史和对话详情 - 将 cli-history.js 中的硬编码英文字符串替换为 t() 函数调用 - 覆盖范围: 执行历史、对话详情、状态、工具标签、按钮、提示等 ### 修复 Claude 会话追踪 (native-session-discovery.ts) - 问题: Claude 使用路径编码存储会话 (D:\path -> D--path),但代码使用 SHA256 哈希导致无法发现 - 解决方案: - 添加 encodeClaudeProjectPath() 函数用于路径编码 - 更新 ClaudeSessionDiscoverer.getSessions() 使用路径编码 - 增强 extractFirstUserMessage() 支持多种消息格式 (string/array) - 结果: Claude 会话现可正确关联,UI 按钮 "查看完整过程对话" 应可正常显示 ## 验证 - npm run build 通过 ✅ - Claude 会话发现 1267 个会话 ✅ - 消息提取成功率 80% ✅ - 路径编码验证正确 ✅ --- .../dashboard-js/components/cli-history.js | 96 +++++++------- ccw/src/templates/dashboard-js/i18n.js | 120 ++++++++++++++++++ ccw/src/tools/native-session-discovery.ts | 45 ++++++- 3 files changed, 206 insertions(+), 55 deletions(-) diff --git a/ccw/src/templates/dashboard-js/components/cli-history.js b/ccw/src/templates/dashboard-js/components/cli-history.js index 130acc16..2ece0bf3 100644 --- a/ccw/src/templates/dashboard-js/components/cli-history.js +++ b/ccw/src/templates/dashboard-js/components/cli-history.js @@ -102,7 +102,7 @@ function renderCliHistory() { if (cliExecutionHistory.length === 0) { container.innerHTML = `
-

Execution History

+

${t('cli.executionHistory')}

${renderHistorySearch()} ${renderToolFilter()} @@ -113,7 +113,7 @@ function renderCliHistory() {
-

No executions yet

+

${t('cli.noExecutions')}

`; @@ -124,7 +124,7 @@ function renderCliHistory() { const historyHtml = filteredHistory.length === 0 ? `
-

No matching results

+

${t('cli.noMatchingResults')}

` : filteredHistory.map(exec => { const statusIcon = exec.status === 'success' ? 'check-circle' : @@ -140,7 +140,7 @@ function renderCliHistory() { // Native session indicator const hasNative = exec.hasNativeSession || exec.nativeSessionId; const nativeBadge = hasNative - ? ` + ? ` ` : ''; @@ -173,14 +173,14 @@ function renderCliHistory() { ${hasNative ? ` - ` : ''} - -
@@ -211,7 +211,7 @@ function renderHistorySearch() { return ` @@ -224,7 +224,7 @@ function renderToolFilter() { @@ -235,7 +235,7 @@ function renderToolFilter() { async function showExecutionDetail(executionId, sourceDir) { const conversation = await loadExecutionDetail(executionId, sourceDir); if (!conversation) { - showRefreshToast('Conversation not found', 'error'); + showRefreshToast(t('cli.conversationNotFound'), 'error'); return; } @@ -264,7 +264,7 @@ async function showExecutionDetail(executionId, sourceDir) {
${isFirst ? '▶' : '↳'} Turn ${turn.turn} - ${isLast ? 'Latest' : ''} + ${isLast ? `${t('cli.latest')}` : ''}
${turnTime} @@ -276,12 +276,12 @@ async function showExecutionDetail(executionId, sourceDir) {
-

User Prompt

+

${t('cli.userPrompt')}

${escapeHtml(turn.prompt)}
${turn.output.stdout ? `
-

Assistant Response

+

${t('cli.assistantResponse')}

${escapeHtml(turn.output.stdout)}
` : ''} @@ -340,7 +340,7 @@ async function showExecutionDetail(executionId, sourceDir) { concatenatedPromptHtml = `