diff --git a/src/App.tsx b/src/App.tsx index 97f71f2..eabdfa7 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -81,7 +81,7 @@ function App() { setProjects(projectList); } catch (err) { console.error("Failed to load projects:", err); - setError("Failed to load projects. Please ensure ~/.claude directory exists."); + setError("加载项目失败。请确保 ~/.claude 目录存在。"); } finally { setLoading(false); } @@ -99,7 +99,7 @@ function App() { setSelectedProject(project); } catch (err) { console.error("Failed to load sessions:", err); - setError("Failed to load sessions for this project."); + setError("加载此项目的会话失败。"); } finally { setLoading(false); } @@ -144,9 +144,9 @@ function App() { // Check if we're navigating away from an active Claude session if (view === "claude-code-session" && isClaudeStreaming && activeClaudeSessionId) { const shouldLeave = window.confirm( - "Claude is still responding. If you navigate away, Claude will continue running in the background.\n\n" + - "You can return to this session from the Projects view.\n\n" + - "Do you want to continue?" + "Claude 仍在响应中。如果您离开此页面,Claude 将继续在后台运行。\n\n" + + "您可以从项目视图返回到此会话。\n\n" + + "是否继续?" ); if (!shouldLeave) { @@ -172,7 +172,7 @@ function App() { >

- Welcome to Claudia + 欢迎使用 Claudia

@@ -190,7 +190,7 @@ function App() { >
-

CC Agents

+

CC 智能助手

@@ -207,7 +207,7 @@ function App() { >
-

CC Projects

+

CC 项目

@@ -255,12 +255,12 @@ function App() { onClick={() => handleViewChange("welcome")} className="mb-4" > - ← Back to Home + ← 返回主页
-

CC Projects

+

CC 项目

- Browse your Claude Code sessions + 浏览您的 Claude Code 会话

@@ -322,7 +322,7 @@ function App() { className="w-full" > - New Claude Code session + 新建 Claude Code 会话 @@ -338,7 +338,7 @@ function App() { ) : (

- No projects found in ~/.claude/projects + 在 ~/.claude/projects 中未找到项目

)} @@ -413,7 +413,7 @@ function App() { open={showClaudeBinaryDialog} onOpenChange={setShowClaudeBinaryDialog} onSuccess={() => { - setToast({ message: "Claude binary path saved successfully", type: "success" }); + setToast({ message: "Claude 二进制文件路径保存成功", type: "success" }); // Trigger a refresh of the Claude version check window.location.reload(); }} diff --git a/src/components/AgentExecution.tsx b/src/components/AgentExecution.tsx index f929560..7225738 100644 --- a/src/components/AgentExecution.tsx +++ b/src/components/AgentExecution.tsx @@ -251,7 +251,7 @@ export const AgentExecution: React.FC = ({ const selected = await open({ directory: true, multiple: false, - title: "Select Project Directory" + title: "选择项目目录" }); if (selected) { @@ -262,7 +262,7 @@ export const AgentExecution: React.FC = ({ console.error("Failed to select directory:", err); // More detailed error logging const errorMessage = err instanceof Error ? err.message : String(err); - setError(`Failed to select directory: ${errorMessage}`); + setError(`选择目录失败: ${errorMessage}`); } }; @@ -306,14 +306,14 @@ export const AgentExecution: React.FC = ({ setIsRunning(false); setExecutionStartTime(null); if (!event.payload) { - setError("Agent execution failed"); + setError("智能体执行失败"); } }); const cancelUnlisten = await listen(`agent-cancelled:${executionRunId}`, () => { setIsRunning(false); setExecutionStartTime(null); - setError("Agent execution was cancelled"); + setError("智能体执行已取消"); }); unlistenRefs.current = [outputUnlisten, errorUnlisten, completeUnlisten, cancelUnlisten]; @@ -327,7 +327,7 @@ export const AgentExecution: React.FC = ({ type: "result", subtype: "error", is_error: true, - result: `Failed to execute agent: ${err instanceof Error ? err.message : 'Unknown error'}`, + result: `智能体执行失败: ${err instanceof Error ? err.message : '未知错误'}`, duration_ms: 0, usage: { input_tokens: 0, @@ -366,7 +366,7 @@ export const AgentExecution: React.FC = ({ type: "result", subtype: "error", is_error: true, - result: "Execution stopped by user", + result: "执行已被用户停止", duration_ms: elapsedTime * 1000, usage: { input_tokens: totalTokens, @@ -384,7 +384,7 @@ export const AgentExecution: React.FC = ({ type: "result", subtype: "error", is_error: true, - result: `Failed to stop execution: ${err instanceof Error ? err.message : 'Unknown error'}`, + result: `停止执行失败: ${err instanceof Error ? err.message : '未知错误'}`, duration_ms: elapsedTime * 1000, usage: { input_tokens: totalTokens, @@ -398,7 +398,7 @@ export const AgentExecution: React.FC = ({ if (isRunning) { // Show confirmation dialog before navigating away during execution const shouldLeave = window.confirm( - "An agent is currently running. If you navigate away, the agent will continue running in the background. You can view running sessions in the 'Running Sessions' tab within CC Agents.\n\nDo you want to continue?" + "智能体正在运行中。如果您离开此页面,智能体将继续在后台运行。您可以在 CC Agents 的 '运行中的会话' 标签页中查看运行状态。\n\n您要继续吗?" ); if (!shouldLeave) { return; @@ -420,63 +420,63 @@ export const AgentExecution: React.FC = ({ }; const handleCopyAsMarkdown = async () => { - let markdown = `# Agent Execution: ${agent.name}\n\n`; - markdown += `**Task:** ${task}\n`; - markdown += `**Model:** ${model === 'opus' ? 'Claude 4 Opus' : 'Claude 4 Sonnet'}\n`; - markdown += `**Date:** ${new Date().toISOString()}\n\n`; + let markdown = `# 智能体执行: ${agent.name}\n\n`; + markdown += `**任务:** ${task}\n`; + markdown += `**模型:** ${model === 'opus' ? 'Claude 4 Opus' : 'Claude 4 Sonnet'}\n`; + markdown += `**日期:** ${new Date().toISOString()}\n\n`; markdown += `---\n\n`; for (const msg of messages) { if (msg.type === "system" && msg.subtype === "init") { - markdown += `## System Initialization\n\n`; - markdown += `- Session ID: \`${msg.session_id || 'N/A'}\`\n`; - markdown += `- Model: \`${msg.model || 'default'}\`\n`; - if (msg.cwd) markdown += `- Working Directory: \`${msg.cwd}\`\n`; - if (msg.tools?.length) markdown += `- Tools: ${msg.tools.join(', ')}\n`; + markdown += `## 系统初始化\n\n`; + markdown += `- 会话ID: \`${msg.session_id || '无'}\`\n`; + markdown += `- 模型: \`${msg.model || '默认'}\`\n`; + if (msg.cwd) markdown += `- 工作目录: \`${msg.cwd}\`\n`; + if (msg.tools?.length) markdown += `- 工具: ${msg.tools.join(', ')}\n`; markdown += `\n`; } else if (msg.type === "assistant" && msg.message) { - markdown += `## Assistant\n\n`; + markdown += `## 助手\n\n`; for (const content of msg.message.content || []) { if (content.type === "text") { markdown += `${content.text}\n\n`; } else if (content.type === "tool_use") { - markdown += `### Tool: ${content.name}\n\n`; + markdown += `### 工具: ${content.name}\n\n`; markdown += `\`\`\`json\n${JSON.stringify(content.input, null, 2)}\n\`\`\`\n\n`; } } if (msg.message.usage) { - markdown += `*Tokens: ${msg.message.usage.input_tokens} in, ${msg.message.usage.output_tokens} out*\n\n`; + markdown += `*令牌: ${msg.message.usage.input_tokens} 输入, ${msg.message.usage.output_tokens} 输出*\n\n`; } } else if (msg.type === "user" && msg.message) { - markdown += `## User\n\n`; + markdown += `## 用户\n\n`; for (const content of msg.message.content || []) { if (content.type === "text") { markdown += `${content.text}\n\n`; } else if (content.type === "tool_result") { - markdown += `### Tool Result\n\n`; + markdown += `### 工具结果\n\n`; markdown += `\`\`\`\n${content.content}\n\`\`\`\n\n`; } } } else if (msg.type === "result") { - markdown += `## Execution Result\n\n`; + markdown += `## 执行结果\n\n`; if (msg.result) { markdown += `${msg.result}\n\n`; } if (msg.error) { - markdown += `**Error:** ${msg.error}\n\n`; + markdown += `**错误:** ${msg.error}\n\n`; } if (msg.cost_usd !== undefined) { - markdown += `- **Cost:** $${msg.cost_usd.toFixed(4)} USD\n`; + markdown += `- **费用:** $${msg.cost_usd.toFixed(4)} 美元\n`; } if (msg.duration_ms !== undefined) { - markdown += `- **Duration:** ${(msg.duration_ms / 1000).toFixed(2)}s\n`; + markdown += `- **持续时间:** ${(msg.duration_ms / 1000).toFixed(2)}秒\n`; } if (msg.num_turns !== undefined) { - markdown += `- **Turns:** ${msg.num_turns}\n`; + markdown += `- **轮次:** ${msg.num_turns}\n`; } if (msg.usage) { const total = msg.usage.input_tokens + msg.usage.output_tokens; - markdown += `- **Total Tokens:** ${total} (${msg.usage.input_tokens} in, ${msg.usage.output_tokens} out)\n`; + markdown += `- **总令牌数:** ${total} (${msg.usage.input_tokens} 输入, ${msg.usage.output_tokens} 输出)\n`; } } } @@ -520,12 +520,12 @@ export const AgentExecution: React.FC = ({ {isRunning && (
- Running + 运行中
)}

- {isRunning ? "Click back to return to main menu - view in CC Agents > Running Sessions" : "Execute CC Agent"} + {isRunning ? "点击返回主菜单 - 在 CC Agents > 运行中的会话 中查看" : "执行 CC 智能体"}

@@ -541,7 +541,7 @@ export const AgentExecution: React.FC = ({ className="flex items-center gap-2" > - Fullscreen + 全屏 = ({ className="flex items-center gap-2" > - Copy Output + 复制输出 } @@ -563,7 +563,7 @@ export const AgentExecution: React.FC = ({ className="w-full justify-start" onClick={handleCopyAsJsonl} > - Copy as JSONL + 复制为 JSONL } @@ -603,12 +603,12 @@ export const AgentExecution: React.FC = ({ {/* Project Path */}
- +
setProjectPath(e.target.value)} - placeholder="Select or enter project path" + placeholder="选择或输入项目路径" disabled={isRunning} className="flex-1" /> @@ -625,7 +625,7 @@ export const AgentExecution: React.FC = ({ {/* Model Selection */}
- +
@@ -741,9 +741,9 @@ export const AgentExecution: React.FC = ({ {messages.length === 0 && !isRunning && (
-

Ready to Execute

+

准备执行

- Select a project path and enter a task to run the agent + 选择项目路径并输入任务以运行智能体

)} @@ -752,7 +752,7 @@ export const AgentExecution: React.FC = ({
- Initializing agent... + 初始化智能体中...
)} @@ -806,11 +806,11 @@ export const AgentExecution: React.FC = ({
{renderIcon()} -

{agent.name} - Output

+

{agent.name} - 输出

{isRunning && (
- Running + 运行中
)}
@@ -823,7 +823,7 @@ export const AgentExecution: React.FC = ({ className="flex items-center gap-2" > - Copy Output + 复制输出 } @@ -835,7 +835,7 @@ export const AgentExecution: React.FC = ({ className="w-full justify-start" onClick={handleCopyAsJsonl} > - Copy as JSONL + 复制为 JSONL
} @@ -858,7 +858,7 @@ export const AgentExecution: React.FC = ({ className="flex items-center gap-2" > - Close + 关闭
@@ -883,9 +883,9 @@ export const AgentExecution: React.FC = ({ {messages.length === 0 && !isRunning && (
-

Ready to Execute

+

准备执行

- Select a project path and enter a task to run the agent + 选择项目路径并输入任务以运行智能体

)} @@ -894,7 +894,7 @@ export const AgentExecution: React.FC = ({
- Initializing agent... + 初始化智能体中...
)} diff --git a/src/components/CCAgents.tsx b/src/components/CCAgents.tsx index 9262bae..4a4b5e5 100644 --- a/src/components/CCAgents.tsx +++ b/src/components/CCAgents.tsx @@ -96,8 +96,8 @@ export const CCAgents: React.FC = ({ onBack, className }) => { setAgents(agentsList); } catch (err) { console.error("Failed to load agents:", err); - setError("Failed to load agents"); - setToast({ message: "Failed to load agents", type: "error" }); + setError("加载智能体失败"); + setToast({ message: "加载智能体失败", type: "error" }); } finally { setLoading(false); } @@ -134,12 +134,12 @@ export const CCAgents: React.FC = ({ onBack, className }) => { try { setIsDeleting(true); await api.deleteAgent(agentToDelete.id); - setToast({ message: "Agent deleted successfully", type: "success" }); + setToast({ message: "智能体删除成功", type: "success" }); await loadAgents(); await loadRuns(); // Reload runs as they might be affected } catch (err) { console.error("Failed to delete agent:", err); - setToast({ message: "Failed to delete agent", type: "error" }); + setToast({ message: "删除智能体失败", type: "error" }); } finally { setIsDeleting(false); setShowDeleteDialog(false); @@ -168,13 +168,13 @@ export const CCAgents: React.FC = ({ onBack, className }) => { const handleAgentCreated = async () => { setView("list"); await loadAgents(); - setToast({ message: "Agent created successfully", type: "success" }); + setToast({ message: "智能体创建成功", type: "success" }); }; const handleAgentUpdated = async () => { setView("list"); await loadAgents(); - setToast({ message: "Agent updated successfully", type: "success" }); + setToast({ message: "智能体更新成功", type: "success" }); }; // const handleRunClick = (run: AgentRunWithMetrics) => { @@ -211,10 +211,10 @@ export const CCAgents: React.FC = ({ onBack, className }) => { filePath }); - setToast({ message: `Agent "${agent.name}" exported successfully`, type: "success" }); + setToast({ message: `智能体 "${agent.name}" 导出成功`, type: "success" }); } catch (err) { console.error("Failed to export agent:", err); - setToast({ message: "Failed to export agent", type: "error" }); + setToast({ message: "导出智能体失败", type: "error" }); } }; @@ -237,7 +237,7 @@ export const CCAgents: React.FC = ({ onBack, className }) => { // Import the agent from the selected file await api.importAgentFromFile(filePath as string); - setToast({ message: "Agent imported successfully", type: "success" }); + setToast({ message: "智能体导入成功", type: "success" }); await loadAgents(); } catch (err) { console.error("Failed to import agent:", err); @@ -310,9 +310,9 @@ export const CCAgents: React.FC = ({ onBack, className }) => {
-

CC Agents

+

CC 智能体

- Manage your Claude Code agents + 管理您的 Claude Code 智能体

@@ -325,18 +325,18 @@ export const CCAgents: React.FC = ({ onBack, className }) => { className="flex items-center gap-2" > - Import + 导入 - From File + 从文件 setShowGitHubBrowser(true)}> - From GitHub + 从 GitHub @@ -346,7 +346,7 @@ export const CCAgents: React.FC = ({ onBack, className }) => { className="flex items-center gap-2" > - Create CC Agent + 创建 CC 智能体
@@ -377,7 +377,7 @@ export const CCAgents: React.FC = ({ onBack, className }) => { >
- Agents + 智能体
@@ -418,13 +418,13 @@ export const CCAgents: React.FC = ({ onBack, className }) => { ) : agents.length === 0 ? (
-

No agents yet

+

暂无智能体

- Create your first CC Agent to get started + 创建您的第一个 CC 智能体开始使用

) : ( @@ -448,7 +448,7 @@ export const CCAgents: React.FC = ({ onBack, className }) => { {agent.name}

- Created: {new Date(agent.created_at).toLocaleDateString()} + 创建时间:{new Date(agent.created_at).toLocaleDateString()}

@@ -460,7 +460,7 @@ export const CCAgents: React.FC = ({ onBack, className }) => { title="Execute agent" > - Execute + 执行 @@ -508,10 +508,10 @@ export const CCAgents: React.FC = ({ onBack, className }) => { onClick={() => setCurrentPage(p => Math.max(1, p - 1))} disabled={currentPage === 1} > - Previous + 上一页 - Page {currentPage} of {totalPages} + 第 {currentPage} 页,共 {totalPages} 页 )} @@ -532,7 +532,7 @@ export const CCAgents: React.FC = ({ onBack, className }) => {
-

Recent Executions

+

最近执行

{runsLoading ? (
@@ -582,7 +582,7 @@ export const CCAgents: React.FC = ({ onBack, className }) => { onImportSuccess={async () => { setShowGitHubBrowser(false); await loadAgents(); - setToast({ message: "Agent imported successfully from GitHub", type: "success" }); + setToast({ message: "从 GitHub 导入智能体成功", type: "success" }); }} /> @@ -592,11 +592,11 @@ export const CCAgents: React.FC = ({ onBack, className }) => { - Delete Agent + 删除智能体 - Are you sure you want to delete the agent "{agentToDelete?.name}"? - This action cannot be undone and will permanently remove the agent and all its associated data. + 您确定要删除智能体 "{agentToDelete?.name}" 吗? + 此操作无法撤销,将永久删除该智能体及其所有相关数据。 @@ -606,7 +606,7 @@ export const CCAgents: React.FC = ({ onBack, className }) => { disabled={isDeleting} className="w-full sm:w-auto" > - Cancel + 取消 diff --git a/src/components/ClaudeBinaryDialog.tsx b/src/components/ClaudeBinaryDialog.tsx index eb72ccd..1e40b9b 100644 --- a/src/components/ClaudeBinaryDialog.tsx +++ b/src/components/ClaudeBinaryDialog.tsx @@ -39,7 +39,7 @@ export function ClaudeBinaryDialog({ open, onOpenChange, onSuccess, onError }: C const handleSave = async () => { if (!selectedInstallation) { - onError("Please select a Claude installation"); + onError("请选择一个 Claude 安装"); return; } @@ -50,7 +50,7 @@ export function ClaudeBinaryDialog({ open, onOpenChange, onSuccess, onError }: C onOpenChange(false); } catch (error) { console.error("Failed to save Claude binary path:", error); - onError(error instanceof Error ? error.message : "Failed to save Claude binary path"); + onError(error instanceof Error ? error.message : "保存 Claude 二进制路径失败"); } finally { setIsValidating(false); } @@ -62,29 +62,29 @@ export function ClaudeBinaryDialog({ open, onOpenChange, onSuccess, onError }: C - Select Claude Code Installation + 选择 Claude Code 安装 {checkingInstallations ? (
- Searching for Claude installations... + 正在搜索 Claude 安装...
) : hasInstallations ? (

- Multiple Claude Code installations were found on your system. - Please select which one you'd like to use. + 在您的系统中发现了多个 Claude Code 安装。 + 请选择您想要使用的版本。

) : ( <>

- Claude Code was not found in any of the common installation locations. - Please install Claude Code to continue. + 在常见安装位置未找到 Claude Code。 + 请安装 Claude Code 以继续。

- Searched locations: PATH, /usr/local/bin, + 搜索位置: PATH, /usr/local/bin, /opt/homebrew/bin, ~/.nvm/versions/node/*/bin, ~/.claude/local, ~/.local/bin

@@ -94,7 +94,7 @@ export function ClaudeBinaryDialog({ open, onOpenChange, onSuccess, onError }: C

- Tip: You can install Claude Code using{" "} + 提示: 您可以使用以下命令安装 Claude Code{" "} npm install -g @claude

@@ -118,20 +118,20 @@ export function ClaudeBinaryDialog({ open, onOpenChange, onSuccess, onError }: C className="mr-auto" > - Installation Guide + 安装指南
diff --git a/src/components/CreateAgent.tsx b/src/components/CreateAgent.tsx index 3ea9141..f893091 100644 --- a/src/components/CreateAgent.tsx +++ b/src/components/CreateAgent.tsx @@ -56,12 +56,12 @@ export const CreateAgent: React.FC = ({ const handleSave = async () => { if (!name.trim()) { - setError("Agent name is required"); + setError("智能体名称为必填项"); return; } if (!systemPrompt.trim()) { - setError("System prompt is required"); + setError("系统提示词为必填项"); return; } @@ -91,9 +91,9 @@ export const CreateAgent: React.FC = ({ onAgentCreated(); } catch (err) { console.error("Failed to save agent:", err); - setError(isEditMode ? "Failed to update agent" : "Failed to create agent"); + setError(isEditMode ? "更新智能体失败" : "创建智能体失败"); setToast({ - message: isEditMode ? "Failed to update agent" : "Failed to create agent", + message: isEditMode ? "更新智能体失败" : "创建智能体失败", type: "error" }); } finally { @@ -107,7 +107,7 @@ export const CreateAgent: React.FC = ({ systemPrompt !== (agent?.system_prompt || "") || defaultTask !== (agent?.default_task || "") || model !== (agent?.model || "sonnet")) && - !confirm("You have unsaved changes. Are you sure you want to leave?")) { + !confirm("您有未保存的更改。您确定要离开吗?")) { return; } onBack(); @@ -134,10 +134,10 @@ export const CreateAgent: React.FC = ({

- {isEditMode ? "Edit CC Agent" : "Create CC Agent"} + {isEditMode ? "编辑 CC 智能体" : "创建 CC 智能体"}

- {isEditMode ? "Update your Claude Code agent" : "Create a new Claude Code agent"} + {isEditMode ? "更新您的 Claude Code 智能体" : "创建一个新的 Claude Code 智能体"}

@@ -152,7 +152,7 @@ export const CreateAgent: React.FC = ({ ) : ( )} - {saving ? "Saving..." : "Save"} + {saving ? "保存中..." : "保存"} @@ -178,24 +178,24 @@ export const CreateAgent: React.FC = ({ {/* Basic Information */}
-

Basic Information

+

基本信息

{/* Name and Icon */}
- + setName(e.target.value)} - placeholder="e.g., Code Assistant" + placeholder="例如:代码助手" required />
- +
setShowIconPicker(true)} className="h-10 px-3 py-2 bg-background border border-input rounded-md cursor-pointer hover:bg-accent hover:text-accent-foreground transition-colors flex items-center justify-between" @@ -218,7 +218,7 @@ export const CreateAgent: React.FC = ({ {/* Model Selection */}
- +
Claude 4 Sonnet
-
Faster, efficient for most tasks
+
速度快,适用于大多数任务
@@ -269,7 +269,7 @@ export const CreateAgent: React.FC = ({
Claude 4 Opus
-
More capable, better for complex tasks
+
功能更强,适用于复杂任务
@@ -278,17 +278,17 @@ export const CreateAgent: React.FC = ({ {/* Default Task */}
- + setDefaultTask(e.target.value)} className="max-w-md" />

- This will be used as the default task placeholder when executing the agent + 这将作为执行智能体时的默认任务占位符

@@ -296,9 +296,9 @@ export const CreateAgent: React.FC = ({ {/* System Prompt Editor */}
- +

- Define the behavior and capabilities of your CC Agent + 定义您的 CC 智能体的行为和能力

}, { id: "opus", name: "Claude 4 Opus", - description: "More capable, better for complex tasks", + description: "更强大,适用于复杂任务", icon: } ]; @@ -490,7 +490,7 @@ const FloatingPromptInputInner = ( onClick={(e) => e.stopPropagation()} >
-

Compose your prompt

+

编写您的提示词

-

{THINKING_MODES.find(m => m.id === selectedThinkingMode)?.name || "Auto"}

+

{THINKING_MODES.find(m => m.id === selectedThinkingMode)?.name || "自动"}

{THINKING_MODES.find(m => m.id === selectedThinkingMode)?.description}

@@ -708,7 +708,7 @@ const FloatingPromptInputInner = ( -

{THINKING_MODES.find(m => m.id === selectedThinkingMode)?.name || "Auto"}

+

{THINKING_MODES.find(m => m.id === selectedThinkingMode)?.name || "自动"}

{THINKING_MODES.find(m => m.id === selectedThinkingMode)?.description}

@@ -756,7 +756,7 @@ const FloatingPromptInputInner = ( value={prompt} onChange={handleTextChange} onKeyDown={handleKeyDown} - placeholder={dragActive ? "Drop images here..." : "Ask Claude anything..."} + placeholder={dragActive ? "将图片拖放至此..." : "向 Claude 提问任何问题..."} disabled={disabled} className={cn( "min-h-[44px] max-h-[120px] resize-none pr-10", @@ -799,7 +799,7 @@ const FloatingPromptInputInner = ( {isLoading ? ( <> - Stop + 停止 ) : ( @@ -808,7 +808,7 @@ const FloatingPromptInputInner = (
- Press Enter to send, Shift+Enter for new line{projectPath?.trim() && ", @ to mention files, drag & drop images"} + 按回车发送,Shift+回车换行{projectPath?.trim() && ",@ 符号提及文件,拖放图片"}
diff --git a/src/components/MCPAddServer.tsx b/src/components/MCPAddServer.tsx index abe3f92..0a3c3b5 100644 --- a/src/components/MCPAddServer.tsx +++ b/src/components/MCPAddServer.tsx @@ -97,12 +97,12 @@ export const MCPAddServer: React.FC = ({ */ const handleAddStdioServer = async () => { if (!stdioName.trim()) { - onError("Server name is required"); + onError("服务器名称为必填项"); return; } if (!stdioCommand.trim()) { - onError("Command is required"); + onError("命令为必填项"); return; } @@ -142,7 +142,7 @@ export const MCPAddServer: React.FC = ({ onError(result.message); } } catch (error) { - onError("Failed to add server"); + onError("添加服务器失败"); console.error("Failed to add stdio server:", error); } finally { setSaving(false); @@ -154,12 +154,12 @@ export const MCPAddServer: React.FC = ({ */ const handleAddSseServer = async () => { if (!sseName.trim()) { - onError("Server name is required"); + onError("服务器名称为必填项"); return; } if (!sseUrl.trim()) { - onError("URL is required"); + onError("URL 为必填项"); return; } @@ -195,7 +195,7 @@ export const MCPAddServer: React.FC = ({ onError(result.message); } } catch (error) { - onError("Failed to add server"); + onError("添加服务器失败"); console.error("Failed to add SSE server:", error); } finally { setSaving(false); @@ -209,7 +209,7 @@ export const MCPAddServer: React.FC = ({ return (
- +
@@ -257,9 +257,9 @@ export const MCPAddServer: React.FC = ({ return (
-

Add MCP Server

+

添加 MCP 服务器

- Configure a new Model Context Protocol server + 配置新的 Model Context Protocol 服务器

@@ -280,7 +280,7 @@ export const MCPAddServer: React.FC = ({
- + = ({ onChange={(e) => setStdioName(e.target.value)} />

- A unique name to identify this server + 用于标识此服务器的唯一名称

- + = ({ className="font-mono" />

- The command to execute the server + 执行服务器的命令

- + = ({ className="font-mono" />

- Space-separated command arguments + 空格分隔的命令参数

- + setStdioScope(value)} options={[ - { value: "local", label: "Local (this project only)" }, - { value: "project", label: "Project (shared via .mcp.json)" }, - { value: "user", label: "User (all projects)" }, + { value: "local", label: "本地(仅限此项目)" }, + { value: "project", label: "项目(通过 .mcp.json 共享)" }, + { value: "user", label: "用户(所有项目)" }, ]} />
@@ -345,12 +345,12 @@ export const MCPAddServer: React.FC = ({ {saving ? ( <> - Adding Server... + 正在添加服务器... ) : ( <> - Add Stdio Server + 添加 Stdio 服务器 )} @@ -363,7 +363,7 @@ export const MCPAddServer: React.FC = ({
- + = ({ onChange={(e) => setSseName(e.target.value)} />

- A unique name to identify this server + 用于标识此服务器的唯一名称

@@ -385,19 +385,19 @@ export const MCPAddServer: React.FC = ({ className="font-mono" />

- The SSE endpoint URL + SSE 端点 URL

- + setSseScope(value)} options={[ - { value: "local", label: "Local (this project only)" }, - { value: "project", label: "Project (shared via .mcp.json)" }, - { value: "user", label: "User (all projects)" }, + { value: "local", label: "本地(仅限此项目)" }, + { value: "project", label: "项目(通过 .mcp.json 共享)" }, + { value: "user", label: "用户(所有项目)" }, ]} />
@@ -414,12 +414,12 @@ export const MCPAddServer: React.FC = ({ {saving ? ( <> - Adding Server... + 正在添加服务器... ) : ( <> - Add SSE Server + 添加 SSE 服务器 )} @@ -433,7 +433,7 @@ export const MCPAddServer: React.FC = ({
- Example Commands + 命令示例
diff --git a/src/components/MCPManager.tsx b/src/components/MCPManager.tsx index 2d6de9a..2a60a88 100644 --- a/src/components/MCPManager.tsx +++ b/src/components/MCPManager.tsx @@ -54,7 +54,7 @@ export const MCPManager: React.FC = ({ setServers(serverList); } catch (err) { console.error("MCPManager: Failed to load MCP servers:", err); - setError("Failed to load MCP servers. Make sure Claude Code is installed."); + setError("无法加载 MCP 服务器。请确保已安装 Claude Code。"); } finally { setLoading(false); } @@ -65,7 +65,7 @@ export const MCPManager: React.FC = ({ */ const handleServerAdded = () => { loadServers(); - setToast({ message: "MCP server added successfully!", type: "success" }); + setToast({ message: "MCP 服务器添加成功!", type: "success" }); setActiveTab("servers"); }; @@ -74,7 +74,7 @@ export const MCPManager: React.FC = ({ */ const handleServerRemoved = (name: string) => { setServers(prev => prev.filter(s => s.name !== name)); - setToast({ message: `Server "${name}" removed successfully!`, type: "success" }); + setToast({ message: `服务器 "${name}" 删除成功!`, type: "success" }); }; /** @@ -84,12 +84,12 @@ export const MCPManager: React.FC = ({ loadServers(); if (failed === 0) { setToast({ - message: `Successfully imported ${imported} server${imported > 1 ? 's' : ''}!`, + message: `成功导入 ${imported} 个服务器!`, type: "success" }); } else { setToast({ - message: `Imported ${imported} server${imported > 1 ? 's' : ''}, ${failed} failed`, + message: `已导入 ${imported} 个服务器,${failed} 个失败`, type: "error" }); } @@ -117,10 +117,10 @@ export const MCPManager: React.FC = ({

- MCP Servers + MCP 服务器

- Manage Model Context Protocol servers + 管理 Model Context Protocol 服务器

@@ -152,15 +152,15 @@ export const MCPManager: React.FC = ({ - Servers + 服务器 - Add Server + 添加服务器 - Import/Export + 导入/导出 diff --git a/src/components/MCPServerList.tsx b/src/components/MCPServerList.tsx index 0481282..f175d86 100644 --- a/src/components/MCPServerList.tsx +++ b/src/components/MCPServerList.tsx @@ -157,11 +157,11 @@ export const MCPServerList: React.FC = ({ const getScopeDisplayName = (scope: string) => { switch (scope) { case "local": - return "Local (Project-specific)"; + return "本地(项目特定)"; case "project": - return "Project (Shared via .mcp.json)"; + return "项目(通过 .mcp.json 共享)"; case "user": - return "User (All projects)"; + return "用户(所有项目)"; default: return scope; } @@ -193,7 +193,7 @@ export const MCPServerList: React.FC = ({ {server.status?.running && ( - Running + 运行中 )}
@@ -210,7 +210,7 @@ export const MCPServerList: React.FC = ({ className="h-6 px-2 text-xs hover:bg-primary/10" > - Show full + 展开全部
)} @@ -225,7 +225,7 @@ export const MCPServerList: React.FC = ({ {Object.keys(server.env).length > 0 && !isExpanded && (
- Environment variables: {Object.keys(server.env).length} + 环境变量:{Object.keys(server.env).length}
)}
@@ -272,7 +272,7 @@ export const MCPServerList: React.FC = ({ {server.command && (
-

Command

+

命令

@@ -302,7 +302,7 @@ export const MCPServerList: React.FC = ({ {server.args && server.args.length > 0 && (
-

Arguments

+

参数

{server.args.map((arg, idx) => (
@@ -325,7 +325,7 @@ export const MCPServerList: React.FC = ({ {Object.keys(server.env).length > 0 && (
-

Environment Variables

+

环境变量

{Object.entries(server.env).map(([key, value]) => (
@@ -357,9 +357,9 @@ export const MCPServerList: React.FC = ({ {/* Header */}
-

Configured Servers

+

已配置的服务器

- {servers.length} server{servers.length !== 1 ? "s" : ""} configured + 已配置 {servers.length} 个服务器

@@ -379,9 +379,9 @@ export const MCPServerList: React.FC = ({
-

No MCP servers configured

+

没有配置 MCP 服务器

- Add a server to get started with Model Context Protocol + 添加服务器以开始使用 Model Context Protocol

) : ( diff --git a/src/components/ProjectList.tsx b/src/components/ProjectList.tsx index 3b2e536..9e6b707 100644 --- a/src/components/ProjectList.tsx +++ b/src/components/ProjectList.tsx @@ -76,7 +76,7 @@ export const ProjectList: React.FC = ({

{project.path}

- {project.sessions.length} session{project.sessions.length !== 1 ? 's' : ''} + {project.sessions.length} 个会话
diff --git a/src/components/RunningSessionsView.tsx b/src/components/RunningSessionsView.tsx index 0061fd6..1adba7b 100644 --- a/src/components/RunningSessionsView.tsx +++ b/src/components/RunningSessionsView.tsx @@ -28,7 +28,7 @@ export function RunningSessionsView({ className, showBackButton = false, onBack setRunningSessions(sessions); } catch (error) { console.error('Failed to load running sessions:', error); - setToast({ message: 'Failed to load running sessions', type: 'error' }); + setToast({ message: '加载运行中的会话失败', type: 'error' }); } finally { setLoading(false); } @@ -41,10 +41,10 @@ export function RunningSessionsView({ className, showBackButton = false, onBack await api.cleanupFinishedProcesses(); // Then reload the list await loadRunningSessions(); - setToast({ message: 'Running sessions list has been updated', type: 'success' }); + setToast({ message: '运行中的会话列表已更新', type: 'success' }); } catch (error) { console.error('Failed to refresh sessions:', error); - setToast({ message: 'Failed to refresh sessions', type: 'error' }); + setToast({ message: '刷新会话失败', type: 'error' }); } finally { setRefreshing(false); } @@ -54,15 +54,15 @@ export function RunningSessionsView({ className, showBackButton = false, onBack try { const success = await api.killAgentSession(runId); if (success) { - setToast({ message: `${agentName} session has been stopped`, type: 'success' }); + setToast({ message: `${agentName} 会话已停止`, type: 'success' }); // Refresh the list after killing await loadRunningSessions(); } else { - setToast({ message: 'Session may have already finished', type: 'error' }); + setToast({ message: '会话可能已经结束', type: 'error' }); } } catch (error) { console.error('Failed to kill session:', error); - setToast({ message: 'Failed to terminate session', type: 'error' }); + setToast({ message: '终止会话失败', type: 'error' }); } }; @@ -78,9 +78,9 @@ export function RunningSessionsView({ className, showBackButton = false, onBack const getStatusBadge = (status: string) => { switch (status) { case 'running': - return Running; + return 运行中; case 'pending': - return Pending; + return 等待中; default: return {status}; } @@ -104,7 +104,7 @@ export function RunningSessionsView({ className, showBackButton = false, onBack
- Loading running sessions... + 正在加载运行中的会话...
); @@ -125,7 +125,7 @@ export function RunningSessionsView({ className, showBackButton = false, onBack )} -

Running Agent Sessions

+

运行中的代理会话

{runningSessions.length}
@@ -145,7 +145,7 @@ export function RunningSessionsView({ className, showBackButton = false, onBack
-

No agent sessions are currently running

+

当前没有正在运行的代理会话

@@ -187,7 +187,7 @@ export function RunningSessionsView({ className, showBackButton = false, onBack className="flex items-center space-x-2" > - View Output + 查看输出
@@ -204,28 +204,28 @@ export function RunningSessionsView({ className, showBackButton = false, onBack
-

Task

+

任务

{session.task}

-

Model

+

模型

{session.model}

-

Duration

+

持续时间

{session.process_started_at ? formatDuration(session.process_started_at) - : 'Unknown' + : '未知' }

-

Project Path

+

项目路径

{session.project_path}

@@ -233,7 +233,7 @@ export function RunningSessionsView({ className, showBackButton = false, onBack {session.session_id && (
-

Session ID

+

会话ID

{session.session_id}

diff --git a/src/components/SessionList.tsx b/src/components/SessionList.tsx index 7b0a282..802ccd0 100644 --- a/src/components/SessionList.tsx +++ b/src/components/SessionList.tsx @@ -89,7 +89,7 @@ export const SessionList: React.FC = ({

{projectPath}

- {sessions.length} session{sessions.length !== 1 ? 's' : ''} + {sessions.length} 个会话

@@ -149,7 +149,7 @@ export const SessionList: React.FC = ({
- First message: + 首条消息:

{truncateText(getFirstLine(session.first_message), 100)} @@ -173,7 +173,7 @@ export const SessionList: React.FC = ({ {session.todo_data && (

- Has todo + 有待办事项
)}
diff --git a/src/components/Settings.tsx b/src/components/Settings.tsx index b130243..9fc526f 100644 --- a/src/components/Settings.tsx +++ b/src/components/Settings.tsx @@ -145,7 +145,7 @@ export const Settings: React.FC = ({ } } catch (err) { console.error("Failed to load settings:", err); - setError("Failed to load settings. Please ensure ~/.claude directory exists."); + setError("加载设置失败。请确保 ~/.claude 目录存在。"); setSettings({}); } finally { setLoading(false); @@ -187,11 +187,11 @@ export const Settings: React.FC = ({ setBinaryPathChanged(false); } - setToast({ message: "Settings saved successfully!", type: "success" }); + setToast({ message: "设置保存成功!", type: "success" }); } catch (err) { console.error("Failed to save settings:", err); - setError("Failed to save settings."); - setToast({ message: "Failed to save settings", type: "error" }); + setError("保存设置失败。"); + setToast({ message: "保存设置失败", type: "error" }); } finally { setSaving(false); } @@ -302,9 +302,9 @@ export const Settings: React.FC = ({
-

Settings

+

设置

- Configure Claude Code preferences + 配置 Claude Code 偏好设置

@@ -318,12 +318,12 @@ export const Settings: React.FC = ({ {saving ? ( <> - Saving... + 保存中... ) : ( <> - Save Settings + 保存设置 )} @@ -355,19 +355,19 @@ export const Settings: React.FC = ({ - General + 常规 - Permissions + 权限 - Environment + 环境 - Advanced + 高级 @@ -375,15 +375,15 @@ export const Settings: React.FC = ({
-

General Settings

+

常规设置

{/* Include Co-authored By */}
- +

- Add Claude attribution to git commits and pull requests + 在 git 提交和拉取请求中添加 Claude 署名

= ({ {/* Verbose Output */}
- +

- Show full bash and command outputs + 显示完整的 bash 和命令输出

= ({ {/* Cleanup Period */}
- + = ({ }} />

- How long to retain chat transcripts locally (default: 30 days) + 本地保留聊天记录的时长(默认:30 天)

{/* Claude Binary Path Selector */}
- +

- Select which Claude Code installation to use + 选择要使用的 Claude Code 安装版本

= ({ /> {binaryPathChanged && (

- ⚠️ Claude binary path has been changed. Remember to save your settings. + ⚠️ Claude 二进制路径已更改。请记得保存您的设置。

)}
@@ -455,16 +455,16 @@ export const Settings: React.FC = ({
-

Permission Rules

+

权限规则

- Control which tools Claude Code can use without manual approval + 控制 Claude Code 可以在无需手动批准的情况下使用哪些工具

{/* Allow Rules */}
- +
{allowRules.length === 0 ? (

- No allow rules configured. Claude will ask for approval for all tools. + 未配置允许规则。Claude 将对所有工具请求批准。

) : ( allowRules.map((rule) => ( @@ -489,7 +489,7 @@ export const Settings: React.FC = ({ className="flex items-center gap-2" > updatePermissionRule("allow", rule.id, e.target.value)} className="flex-1" @@ -511,7 +511,7 @@ export const Settings: React.FC = ({ {/* Deny Rules */}
- +
{denyRules.length === 0 ? (

- No deny rules configured. + 未配置拒绝规则。

) : ( denyRules.map((rule) => ( @@ -536,7 +536,7 @@ export const Settings: React.FC = ({ className="flex items-center gap-2" > updatePermissionRule("deny", rule.id, e.target.value)} className="flex-1" @@ -557,14 +557,14 @@ export const Settings: React.FC = ({

- Examples: + 示例:

    -
  • Bash - Allow all bash commands
  • -
  • Bash(npm run build) - Allow exact command
  • -
  • Bash(npm run test:*) - Allow commands with prefix
  • -
  • Read(~/.zshrc) - Allow reading specific file
  • -
  • Edit(docs/**) - Allow editing files in docs directory
  • +
  • Bash - 允许所有 bash 命令
  • +
  • Bash(npm run build) - 允许精确命令
  • +
  • Bash(npm run test:*) - 允许带前缀的命令
  • +
  • Read(~/.zshrc) - 允许读取特定文件
  • +
  • Edit(docs/**) - 允许编辑 docs 目录中的文件
@@ -577,9 +577,9 @@ export const Settings: React.FC = ({
-

Environment Variables

+

环境变量

- Environment variables applied to every Claude Code session + 应用于每个 Claude Code 会话的环境变量

{envVars.length === 0 ? (

- No environment variables configured. + 未配置环境变量。

) : ( envVars.map((envVar) => ( @@ -607,14 +607,14 @@ export const Settings: React.FC = ({ className="flex items-center gap-2" > updateEnvVar(envVar.id, "key", e.target.value)} className="flex-1 font-mono text-sm" /> = updateEnvVar(envVar.id, "value", e.target.value)} className="flex-1 font-mono text-sm" @@ -634,12 +634,12 @@ export const Settings: React.FC = ({

- Common variables: + 常用变量:

    -
  • CLAUDE_CODE_ENABLE_TELEMETRY - Enable/disable telemetry (0 or 1)
  • -
  • ANTHROPIC_MODEL - Custom model name
  • -
  • DISABLE_COST_WARNINGS - Disable cost warnings (1)
  • +
  • CLAUDE_CODE_ENABLE_TELEMETRY - 启用/禁用遥测 (0 或 1)
  • +
  • ANTHROPIC_MODEL - 自定义模型名称
  • +
  • DISABLE_COST_WARNINGS - 禁用成本警告 (1)
@@ -650,15 +650,15 @@ export const Settings: React.FC = ({
-

Advanced Settings

+

高级设置

- Additional configuration options for advanced users + 为高级用户提供的额外配置选项

{/* API Key Helper */}
- + = ({ onChange={(e) => updateSetting("apiKeyHelper", e.target.value || undefined)} />

- Custom script to generate auth values for API requests + 用于为 API 请求生成身份验证值的自定义脚本

{/* Raw JSON Editor */}
- +
{JSON.stringify(settings, null, 2)}

- This shows the raw JSON that will be saved to ~/.claude/settings.json + 这显示了将保存到 ~/.claude/settings.json 的原始 JSON 数据

diff --git a/src/components/Topbar.tsx b/src/components/Topbar.tsx index e28aec4..f96c859 100644 --- a/src/components/Topbar.tsx +++ b/src/components/Topbar.tsx @@ -87,7 +87,7 @@ export const Topbar: React.FC = ({ return (
- Checking... + 检查中...
); } @@ -125,7 +125,7 @@ export const Topbar: React.FC = ({ trigger={statusContent} content={
-

Claude Code not found

+

未找到 Claude Code

                   {versionStatus.output}
@@ -137,7 +137,7 @@ export const Topbar: React.FC = ({
                 className="w-full"
                 onClick={onSettingsClick}
               >
-                Select Claude Installation
+                选择 Claude 安装
               
                = ({
                 rel="noopener noreferrer"
                 className="flex items-center space-x-1 text-xs text-primary hover:underline"
               >
-                Install Claude Code
+                安装 Claude Code
                 
               
             
@@ -180,7 +180,7 @@ export const Topbar: React.FC = ({ className="text-xs" > - Usage Dashboard + 使用情况仪表板 diff --git a/src/components/UsageDashboard.tsx b/src/components/UsageDashboard.tsx index 81890fb..f5c730f 100644 --- a/src/components/UsageDashboard.tsx +++ b/src/components/UsageDashboard.tsx @@ -82,7 +82,7 @@ export const UsageDashboard: React.FC = ({ onBack }) => { setSessionStats(sessionData); } catch (err) { console.error("Failed to load usage stats:", err); - setError("Failed to load usage statistics. Please try again."); + setError("加载使用统计失败,请重试。"); } finally { setLoading(false); } @@ -98,7 +98,7 @@ export const UsageDashboard: React.FC = ({ onBack }) => { }; const formatNumber = (num: number): string => { - return new Intl.NumberFormat('en-US').format(num); + return new Intl.NumberFormat('zh-CN').format(num); }; const formatTokens = (num: number): string => { @@ -146,9 +146,9 @@ export const UsageDashboard: React.FC = ({ onBack }) => {
-

Usage Dashboard

+

使用情况仪表板

- Track your Claude Code usage and costs + 跟踪您的 Claude Code 使用情况和费用

@@ -165,7 +165,7 @@ export const UsageDashboard: React.FC = ({ onBack }) => { onClick={() => setSelectedDateRange(range)} className="text-xs" > - {range === "all" ? "All Time" : range === "7d" ? "Last 7 Days" : "Last 30 Days"} + {range === "all" ? "全部时间" : range === "7d" ? "最近 7 天" : "最近 30 天"} ))}
@@ -179,7 +179,7 @@ export const UsageDashboard: React.FC = ({ onBack }) => {
-

Loading usage statistics...

+

正在加载使用统计...

) : error ? ( @@ -187,7 +187,7 @@ export const UsageDashboard: React.FC = ({ onBack }) => {

{error}

@@ -204,7 +204,7 @@ export const UsageDashboard: React.FC = ({ onBack }) => {
-

Total Cost

+

总费用

{formatCurrency(stats.total_cost)}

@@ -217,7 +217,7 @@ export const UsageDashboard: React.FC = ({ onBack }) => {
-

Total Sessions

+

总会话数

{formatNumber(stats.total_sessions)}

@@ -230,7 +230,7 @@ export const UsageDashboard: React.FC = ({ onBack }) => {
-

Total Tokens

+

总令牌数

{formatTokens(stats.total_tokens)}

@@ -243,7 +243,7 @@ export const UsageDashboard: React.FC = ({ onBack }) => {
-

Avg Cost/Session

+

平均会话费用

{formatCurrency( stats.total_sessions > 0 @@ -260,32 +260,32 @@ export const UsageDashboard: React.FC = ({ onBack }) => { {/* Tabs for different views */} - Overview - By Model - By Project - By Session - Timeline + 概览 + 按模型 + 按项目 + 按会话 + 时间线 {/* Overview Tab */} -

Token Breakdown

+

令牌分布

-

Input Tokens

+

输入令牌

{formatTokens(stats.total_input_tokens)}

-

Output Tokens

+

输出令牌

{formatTokens(stats.total_output_tokens)}

-

Cache Write

+

缓存写入

{formatTokens(stats.total_cache_creation_tokens)}

-

Cache Read

+

缓存读取

{formatTokens(stats.total_cache_read_tokens)}

@@ -294,7 +294,7 @@ export const UsageDashboard: React.FC = ({ onBack }) => { {/* Quick Stats */}
-

Most Used Models

+

常用模型

{stats.by_model.slice(0, 3).map((model) => (
@@ -303,7 +303,7 @@ export const UsageDashboard: React.FC = ({ onBack }) => { {getModelDisplayName(model.model)} - {model.session_count} sessions + {model.session_count} 个会话
@@ -315,7 +315,7 @@ export const UsageDashboard: React.FC = ({ onBack }) => { -

Top Projects

+

热门项目

{stats.by_project.slice(0, 3).map((project) => (
@@ -324,7 +324,7 @@ export const UsageDashboard: React.FC = ({ onBack }) => { {project.project_path} - {project.session_count} sessions + {project.session_count} 个会话
@@ -340,7 +340,7 @@ export const UsageDashboard: React.FC = ({ onBack }) => { {/* Models Tab */} -

Usage by Model

+

按模型使用情况

{stats.by_model.map((model) => (
@@ -353,7 +353,7 @@ export const UsageDashboard: React.FC = ({ onBack }) => { {getModelDisplayName(model.model)} - {model.session_count} sessions + {model.session_count} 个会话
@@ -362,19 +362,19 @@ export const UsageDashboard: React.FC = ({ onBack }) => {
- Input: + 输入: {formatTokens(model.input_tokens)}
- Output: + 输出: {formatTokens(model.output_tokens)}
- Cache W: + 缓存写: {formatTokens(model.cache_creation_tokens)}
- Cache R: + 缓存读: {formatTokens(model.cache_read_tokens)}
@@ -387,7 +387,7 @@ export const UsageDashboard: React.FC = ({ onBack }) => { {/* Projects Tab */} -

Usage by Project

+

按项目使用情况

{stats.by_project.map((project) => (
@@ -397,17 +397,17 @@ export const UsageDashboard: React.FC = ({ onBack }) => {
- {project.session_count} sessions + {project.session_count} 个会话 - {formatTokens(project.total_tokens)} tokens + {formatTokens(project.total_tokens)} 个令牌

{formatCurrency(project.total_cost)}

- {formatCurrency(project.total_cost / project.session_count)}/session + {formatCurrency(project.total_cost / project.session_count)}/会话

@@ -419,7 +419,7 @@ export const UsageDashboard: React.FC = ({ onBack }) => { {/* Sessions Tab */} -

Usage by Session

+

按会话使用情况

{sessionStats?.map((session) => (
@@ -451,7 +451,7 @@ export const UsageDashboard: React.FC = ({ onBack }) => {

- Daily Usage + 每日使用情况

{stats.by_date.length > 0 ? (() => { const maxCost = Math.max(...stats.by_date.map(d => d.total_cost), 0); @@ -471,7 +471,7 @@ export const UsageDashboard: React.FC = ({ onBack }) => { {stats.by_date.slice().reverse().map((day) => { const heightPercent = maxCost > 0 ? (day.total_cost / maxCost) * 100 : 0; const date = new Date(day.date.replace(/-/g, '/')); - const formattedDate = date.toLocaleDateString('en-US', { + const formattedDate = date.toLocaleDateString('zh-CN', { weekday: 'short', month: 'short', day: 'numeric' @@ -484,13 +484,13 @@ export const UsageDashboard: React.FC = ({ onBack }) => {

{formattedDate}

- Cost: {formatCurrency(day.total_cost)} + 费用: {formatCurrency(day.total_cost)}

- {formatTokens(day.total_tokens)} tokens + {formatTokens(day.total_tokens)} 个令牌

- {day.models_used.length} model{day.models_used.length !== 1 ? 's' : ''} + {day.models_used.length} 个模型

@@ -508,7 +508,7 @@ export const UsageDashboard: React.FC = ({ onBack }) => {
- {date.toLocaleDateString('en-US', { month: 'short', day: 'numeric' })} + {date.toLocaleDateString('zh-CN', { month: 'short', day: 'numeric' })}
); @@ -517,13 +517,13 @@ export const UsageDashboard: React.FC = ({ onBack }) => { {/* X-axis label */}
- Daily Usage Over Time + 每日使用趋势
) })() : (
- No usage data available for the selected period + 所选时间段内没有可用的使用数据
)} diff --git a/src/components/ui/dialog.tsx b/src/components/ui/dialog.tsx index c75bf99..4e98594 100644 --- a/src/components/ui/dialog.tsx +++ b/src/components/ui/dialog.tsx @@ -43,7 +43,7 @@ const DialogContent = React.forwardRef< {children} - Close + 关闭 diff --git a/src/components/ui/pagination.tsx b/src/components/ui/pagination.tsx index 4a10c6d..347595c 100644 --- a/src/components/ui/pagination.tsx +++ b/src/components/ui/pagination.tsx @@ -55,7 +55,7 @@ export const Pagination: React.FC = ({ - Page {currentPage} of {totalPages} + 第 {currentPage} 页,共 {totalPages} 页