Jelajahi Sumber

chore: sync staged changes across 115 files

Batch update touching CLI, commands, components, hooks, services, tools,
and utilities — mostly minor formatting and structural adjustments.
Jarvis 2 bulan lalu
induk
melakukan
8aeab0da59
100 mengubah file dengan 432 tambahan dan 435 penghapusan
  1. 7 7
      src/cli/print.ts
  2. 2 2
      src/commands.ts
  3. 5 5
      src/commands/insights.ts
  4. 1 1
      src/commands/install-github-app/install-github-app.tsx
  5. 2 2
      src/commands/install-github-app/setupGitHubActions.ts
  6. 1 1
      src/commands/install-slack-app/install-slack-app.ts
  7. 1 1
      src/commands/keybindings/keybindings.ts
  8. 15 15
      src/commands/mcp/addCommand.ts
  9. 10 13
      src/commands/mcp/xaaIdpCommand.ts
  10. 4 4
      src/commands/plugin/ManageMarketplaces.tsx
  11. 1 1
      src/commands/remote-setup/api.ts
  12. 1 1
      src/commands/review/reviewRemote.ts
  13. 2 2
      src/commands/thinkback-play/thinkback-play.ts
  14. 1 1
      src/commands/ultraplan.tsx
  15. 2 2
      src/components/Feedback.tsx
  16. 1 1
      src/components/LogSelector.tsx
  17. 8 8
      src/components/MessageSelector.tsx
  18. 4 4
      src/components/PromptInput/PromptInput.tsx
  19. 43 43
      src/components/Settings/Config.tsx
  20. 1 1
      src/components/StatusLine.tsx
  21. 1 1
      src/components/mcp/MCPAgentServerMenu.tsx
  22. 13 13
      src/components/mcp/MCPRemoteServerMenu.tsx
  23. 4 4
      src/components/mcp/MCPStdioServerMenu.tsx
  24. 9 9
      src/coordinator/coordinatorMode.ts
  25. 3 3
      src/hooks/notifs/useFastModeNotification.tsx
  26. 2 2
      src/hooks/notifs/useIDEStatusIndicator.tsx
  27. 1 1
      src/hooks/useChromeExtensionNotification.tsx
  28. 2 2
      src/hooks/useManagePlugins.ts
  29. 2 2
      src/hooks/useReplBridge.tsx
  30. 1 1
      src/hooks/useSSHSession.ts
  31. 1 1
      src/hooks/useTextInput.ts
  32. 2 2
      src/hooks/useTypeahead.tsx
  33. 6 6
      src/hooks/useVoice.ts
  34. 2 2
      src/keybindings/loadUserBindings.ts
  35. 1 1
      src/keybindings/validate.ts
  36. 3 3
      src/main.tsx
  37. 2 2
      src/projectOnboardingState.ts
  38. 1 1
      src/services/PromptSuggestion/promptSuggestion.ts
  39. 1 1
      src/services/SessionMemory/sessionMemory.ts
  40. 1 1
      src/services/analytics/firstPartyEventLoggingExporter.ts
  41. 1 1
      src/services/analytics/growthbook.ts
  42. 1 1
      src/services/api/claude.ts
  43. 1 1
      src/services/api/filesApi.ts
  44. 3 3
      src/services/mcp/client.ts
  45. 1 1
      src/services/mcp/config.ts
  46. 1 1
      src/services/mcp/types.ts
  47. 1 1
      src/services/plugins/pluginOperations.ts
  48. 7 7
      src/services/policyLimits/index.ts
  49. 4 4
      src/services/rateLimitMocking.ts
  50. 8 8
      src/services/remoteManagedSettings/index.ts
  51. 6 6
      src/services/settingsSync/index.ts
  52. 3 3
      src/services/teamMemorySync/index.ts
  53. 1 1
      src/services/voice.ts
  54. 1 1
      src/tools/AgentTool/AgentTool.tsx
  55. 7 7
      src/tools/AgentTool/agentDisplay.ts
  56. 1 1
      src/tools/AgentTool/agentToolUtils.ts
  57. 2 2
      src/tools/BashTool/bashCommandHelpers.ts
  58. 61 61
      src/tools/BashTool/bashSecurity.ts
  59. 4 4
      src/tools/BashTool/modeValidation.ts
  60. 6 6
      src/tools/BashTool/pathValidation.ts
  61. 3 3
      src/tools/BashTool/readOnlyValidation.ts
  62. 2 2
      src/tools/BashTool/sedValidation.ts
  63. 1 1
      src/tools/ConfigTool/ConfigTool.ts
  64. 1 1
      src/tools/ExitPlanModeTool/ExitPlanModeV2Tool.ts
  65. 1 1
      src/tools/FileEditTool/FileEditTool.ts
  66. 1 1
      src/tools/MCPTool/MCPTool.ts
  67. 7 7
      src/tools/NotebookEditTool/NotebookEditTool.ts
  68. 4 4
      src/tools/PowerShellTool/modeValidation.ts
  69. 3 3
      src/tools/PowerShellTool/pathValidation.ts
  70. 19 19
      src/tools/PowerShellTool/powershellSecurity.ts
  71. 6 6
      src/tools/SendMessageTool/SendMessageTool.ts
  72. 1 1
      src/tools/TaskStopTool/TaskStopTool.ts
  73. 2 2
      src/tools/TaskUpdateTool/TaskUpdateTool.ts
  74. 1 1
      src/tools/TeamCreateTool/TeamCreateTool.ts
  75. 2 2
      src/tools/WebSearchTool/WebSearchTool.ts
  76. 1 1
      src/utils/authFileDescriptor.ts
  77. 2 2
      src/utils/bash/shellQuote.ts
  78. 2 2
      src/utils/bash/specs/alias.ts
  79. 2 2
      src/utils/bash/specs/nohup.ts
  80. 22 22
      src/utils/bash/specs/pyright.ts
  81. 2 2
      src/utils/bash/specs/sleep.ts
  82. 6 6
      src/utils/bash/specs/srun.ts
  83. 2 2
      src/utils/bash/specs/time.ts
  84. 3 3
      src/utils/bash/specs/timeout.ts
  85. 2 2
      src/utils/claudeInChrome/chromeNativeHost.ts
  86. 1 1
      src/utils/claudeInChrome/setup.ts
  87. 1 1
      src/utils/computerUse/cleanup.ts
  88. 1 1
      src/utils/desktopDeepLink.ts
  89. 1 1
      src/utils/effort.ts
  90. 4 4
      src/utils/hooks/hookHelpers.ts
  91. 2 2
      src/utils/mcp/dateTimeParser.ts
  92. 3 3
      src/utils/mcp/elicitationValidation.ts
  93. 2 2
      src/utils/messages.ts
  94. 6 6
      src/utils/model/agent.ts
  95. 13 13
      src/utils/model/modelOptions.ts
  96. 3 3
      src/utils/model/validateModel.ts
  97. 1 1
      src/utils/nativeInstaller/installer.ts
  98. 2 2
      src/utils/pdf.ts
  99. 3 3
      src/utils/permissions/permissionExplainer.ts
  100. 1 1
      src/utils/permissions/permissions.ts

+ 7 - 7
src/cli/print.ts

@@ -3480,7 +3480,7 @@ function runHeadlessStreaming(
             if (!hasCodeOrError) {
               sendControlResponseError(
                 message,
-                'Invalid callback URL: missing authorization code. Please paste the full redirect URL including the code parameter.',
+                '无效的回调链接:缺少授权码。请粘贴包含完整 code 参数的跳转链接。',
               )
             } else {
               oauthManualCallbackUsed.add(serverName)
@@ -4193,7 +4193,7 @@ export function createCanUseToolWithPermissionPrompt(
       cleanupAbortListener()
       return {
         behavior: 'deny',
-        message: 'Permission prompt was aborted.',
+        message: '权限确认已取消。',
         decisionReason: {
           type: 'permissionPromptTool' as const,
           permissionPromptToolName: tool.name,
@@ -4225,7 +4225,7 @@ export function createCanUseToolWithPermissionPrompt(
     if (raceResult === 'aborted' || combinedSignal.aborted) {
       return {
         behavior: 'deny',
-        message: 'Permission prompt was aborted.',
+        message: '权限确认已取消。',
         decisionReason: {
           type: 'permissionPromptTool' as const,
           permissionPromptToolName: tool.name,
@@ -4357,7 +4357,7 @@ async function handleInitializeRequest(
       type: 'control_response',
       response: {
         subtype: 'error',
-        error: 'Already initialized',
+        error: '已初始化',
         request_id: requestId,
         pending_permission_requests:
           structuredIO.getPendingPermissionRequests(),
@@ -4524,12 +4524,12 @@ async function handleRewindFiles(
   dryRun: boolean,
 ): Promise<RewindFilesResult> {
   if (!fileHistoryEnabled()) {
-    return { canRewind: false, error: 'File rewinding is not enabled.' }
+    return { canRewind: false, error: '文件回退功能未启用。' }
   }
   if (!fileHistoryCanRestore(appState.fileHistory, userMessageId)) {
     return {
       canRewind: false,
-      error: 'No file checkpoint found for this message.',
+      error: '未找到此消息的文件检查点。',
     }
   }
 
@@ -4990,7 +4990,7 @@ async function loadInitialMessages(
     try {
       if (!isPolicyAllowed('allow_remote_sessions')) {
         throw new Error(
-          "Remote sessions are disabled by your organization's policy.",
+          '远程会话已被您所在组织停用。',
         )
       }
 

+ 2 - 2
src/commands.ts

@@ -190,9 +190,9 @@ import stats from './commands/stats/index.js'
 const usageReport: Command = {
   type: 'prompt',
   name: 'insights',
-  description: 'Generate a report analyzing your Claude Code sessions',
+  description: '生成分析报告,分析您的 Claude Code 会话',
   contentLength: 0,
-  progressMessage: 'analyzing your sessions',
+  progressMessage: '正在分析您的会话',
   source: 'builtin',
   async getPromptForCommand(args, context) {
     const real = (await import('./commands/insights.js')).default

+ 5 - 5
src/commands/insights.ts

@@ -2426,10 +2426,10 @@ function generateHtmlReport(
     const rawHourCounts = ${hourCountsJson};
     function updateHourHistogram(offsetFromPT) {
       const periods = [
-        { label: "Morning (6-12)", range: [6,7,8,9,10,11] },
-        { label: "Afternoon (12-18)", range: [12,13,14,15,16,17] },
-        { label: "Evening (18-24)", range: [18,19,20,21,22,23] },
-        { label: "Night (0-6)", range: [0,1,2,3,4,5] }
+        { label: "上午(6-12 点)", range: [6,7,8,9,10,11] },
+        { label: "下午(12-18 点)", range: [12,13,14,15,16,17] },
+        { label: "傍晚(18-24 点)", range: [18,19,20,21,22,23] },
+        { label: "夜间(0-6 点)", range: [0,1,2,3,4,5] }
       ];
       const adjustedCounts = {};
       for (const [hour, count] of Object.entries(rawHourCounts)) {
@@ -3039,7 +3039,7 @@ function safeKeys(obj: Record<string, unknown> | undefined | null): string[] {
 const usageReport: Command = {
   type: 'prompt',
   name: 'insights',
-  description: 'Generate a report analyzing your Claude Code sessions',
+  description: '生成分析报告,分析你的 Claude Code 会话',
   contentLength: 0, // Dynamic content
   progressMessage: 'analyzing your sessions',
   source: 'builtin',

+ 1 - 1
src/commands/install-github-app/install-github-app.tsx

@@ -162,7 +162,7 @@ function InstallGitHubApp(props: {
         setState(prev_2 => ({
           ...prev_2,
           step: 'error',
-          error: 'A Claude workflow file already exists in this repository.',
+          error: '仓库中已存在 Claude 工作流文件。',
           errorReason: '工作流文件冲突',
           errorInstructions: ['The file .github/workflows/claude.yml already exists', 'You can either:', '  1. Delete the existing file and run this command again', '  2. Update the existing file manually using the template from:', `     ${GITHUB_ACTION_SETUP_DOCS_URL}`]
         }));

+ 2 - 2
src/commands/install-github-app/setupGitHubActions.ts

@@ -225,7 +225,7 @@ export async function setupGitHubActions(
         workflows.push({
           path: '.github/workflows/claude.yml',
           content: WORKFLOW_CONTENT,
-          message: 'Claude PR Assistant workflow',
+          message: 'Claude PR 助手工作流',
         })
       }
 
@@ -233,7 +233,7 @@ export async function setupGitHubActions(
         workflows.push({
           path: '.github/workflows/claude-code-review.yml',
           content: CODE_REVIEW_PLUGIN_WORKFLOW_CONTENT,
-          message: 'Claude Code Review workflow',
+          message: 'Claude Code 审查工作流',
         })
       }
 

+ 1 - 1
src/commands/install-slack-app/install-slack-app.ts

@@ -19,7 +19,7 @@ export async function call(): Promise<LocalCommandResult> {
   if (success) {
     return {
       type: 'text',
-      value: 'Opening Slack app installation page in browser…',
+      value: '正在浏览器中打开 Slack 应用安装页面…',
     }
   } else {
     return {

+ 1 - 1
src/commands/keybindings/keybindings.ts

@@ -13,7 +13,7 @@ export async function call(): Promise<{ type: 'text'; value: string }> {
     return {
       type: 'text',
       value:
-        'Keybinding customization is not enabled. This feature is currently in preview.',
+        '快捷键自定义功能未启用。此功能目前处于预览阶段。',
     }
   }
 

+ 15 - 15
src/commands/mcp/addCommand.ts

@@ -34,48 +34,48 @@ export function registerMcpAddCommand(mcp: Command): void {
   mcp
     .command('add <name> <commandOrUrl> [args...]')
     .description(
-      'Add an MCP server to Claude Code.\n\n' +
-        'Examples:\n' +
-        '  # Add HTTP server:\n' +
+      '向 Claude Code 添加 MCP 服务器。\n\n' +
+        '示例:\n' +
+        '  # 添加 HTTP 服务器:\n' +
         '  claude mcp add --transport http sentry https://mcp.sentry.dev/mcp\n\n' +
-        '  # Add HTTP server with headers:\n' +
+        '  # 添加带请求头的 HTTP 服务器:\n' +
         '  claude mcp add --transport http corridor https://app.corridor.dev/api/mcp --header "Authorization: Bearer ..."\n\n' +
-        '  # Add stdio server with environment variables:\n' +
+        '  # 添加带环境变量的 stdio 服务器:\n' +
         '  claude mcp add -e API_KEY=xxx my-server -- npx my-mcp-server\n\n' +
-        '  # Add stdio server with subprocess flags:\n' +
+        '  # 添加带子进程参数的 stdio 服务器:\n' +
         '  claude mcp add my-server -- my-command --some-flag arg1',
     )
     .option(
       '-s, --scope <scope>',
-      'Configuration scope (local, user, or project)',
+      '配置作用域(local、user 或 project)',
       'local',
     )
     .option(
       '-t, --transport <transport>',
-      'Transport type (stdio, sse, http). Defaults to stdio if not specified.',
+      '传输类型(stdio、sse、http)。未指定时默认为 stdio。',
     )
     .option(
       '-e, --env <env...>',
-      'Set environment variables (e.g. -e KEY=value)',
+      '设置环境变量(例如 -e KEY=value)',
     )
     .option(
       '-H, --header <header...>',
-      'Set WebSocket headers (e.g. -H "X-Api-Key: abc123" -H "X-Custom: value")',
+      '设置 WebSocket 请求头(例如 -H "X-Api-Key: abc123" -H "X-Custom: value")',
     )
-    .option('--client-id <clientId>', 'OAuth client ID for HTTP/SSE servers')
+    .option('--client-id <clientId>', 'HTTP/SSE 服务器的 OAuth 客户端 ID')
     .option(
       '--client-secret',
-      'Prompt for OAuth client secret (or set MCP_CLIENT_SECRET env var)',
+      '提示输入 OAuth 客户端密钥(或设置 MCP_CLIENT_SECRET 环境变量)',
     )
     .option(
       '--callback-port <port>',
-      'Fixed port for OAuth callback (for servers requiring pre-registered redirect URIs)',
+      'OAuth 回调的固定端口(适用于需要预注册重定向 URI 的服务器)',
     )
-    .helpOption('-h, --help', 'Display help for command')
+    .helpOption('-h, --help', '显示命令帮助')
     .addOption(
       new Option(
         '--xaa',
-        "Enable XAA (SEP-990) for this server. Requires 'claude mcp xaa setup' first. Also requires --client-id and --client-secret (for the MCP server's AS).",
+        "为此服务器启用 XAA (SEP-990)。需要先运行 'claude mcp xaa setup'。还需要 --client-id 和 --client-secret(用于 MCP 服务器的 AS)。",
       ).hideHelp(!isXaaEnabled()),
     )
     .action(async (name, commandOrUrl, args, options) => {

+ 10 - 13
src/commands/mcp/xaaIdpCommand.ts

@@ -24,22 +24,22 @@ import { updateSettingsForSource } from '../../utils/settings/settings.js'
 export function registerMcpXaaIdpCommand(mcp: Command): void {
   const xaaIdp = mcp
     .command('xaa')
-    .description('Manage the XAA (SEP-990) IdP connection')
+    .description('管理 XAA (SEP-990) IdP 连接')
 
   xaaIdp
     .command('setup')
     .description(
-      'Configure the IdP connection (one-time setup for all XAA-enabled servers)',
+      '配置 IdP 连接(为所有启用 XAA 的服务器进行一次性设置)',
     )
-    .requiredOption('--issuer <url>', 'IdP issuer URL (OIDC discovery)')
-    .requiredOption('--client-id <id>', "Claude Code's client_id at the IdP")
+    .requiredOption('--issuer <url>', 'IdP issuer URL(OIDC 发现)')
+    .requiredOption('--client-id <id>', 'IdP 上 Claude Code 的 client_id')
     .option(
       '--client-secret',
-      'Read IdP client secret from MCP_XAA_IDP_CLIENT_SECRET env var',
+      '从 MCP_XAA_IDP_CLIENT_SECRET 环境变量读取 IdP 客户端密钥',
     )
     .option(
       '--callback-port <port>',
-      'Fixed loopback callback port (only if IdP does not honor RFC 8252 port-any matching)',
+      '固定回环回调端口(仅适用于 IdP 不遵循 RFC 8252 端口任意匹配的情况)',
     )
     .action(options => {
       // Validate everything BEFORE any writes. An exit(1) mid-write leaves
@@ -150,21 +150,18 @@ export function registerMcpXaaIdpCommand(mcp: Command): void {
   xaaIdp
     .command('login')
     .description(
-      'Cache an IdP id_token so XAA-enabled MCP servers authenticate ' +
-        'silently. Default: run the OIDC browser login. With --id-token: ' +
-        'write a pre-obtained JWT directly (used by conformance/e2e tests ' +
-        'where the mock IdP does not serve /authorize).',
+      '缓存 IdP id_token,使启用 XAA 的 MCP 服务器静默认证。默认:执行 OIDC 浏览器登录。配合 --id-token:直接写入预获取的 JWT(用于一致性/e2e 测试,模拟 IdP 不提供 /authorize 端点)。',
     )
     .option(
       '--force',
-      'Ignore any cached id_token and re-login (useful after IdP-side revocation)',
+      '忽略已缓存的 id_token 并重新登录(适用于 IdP 端吊销后)',
     )
     // TODO(paulc): read the JWT from stdin instead of argv to keep it out of
     // shell history. Fine for conformance (docker exec uses argv directly,
     // no shell parser), but a real user would want `echo $TOKEN | ... --stdin`.
     .option(
       '--id-token <jwt>',
-      'Write this pre-obtained id_token directly to cache, skipping the OIDC browser login',
+      '将此预获取的 id_token 直接写入缓存,跳过 OIDC 浏览器登录',
     )
     .action(async options => {
       const idp = getXaaIdpSettings()
@@ -242,7 +239,7 @@ export function registerMcpXaaIdpCommand(mcp: Command): void {
 
   xaaIdp
     .command('clear')
-    .description('Clear the IdP connection config and cached id_token')
+    .description('清除 IdP 连接配置和已缓存的 id_token')
     .action(() => {
       // Read issuer first so we can clear the right keychain slots.
       const idp = getXaaIdpSettings()

+ 4 - 4
src/commands/plugin/ManageMarketplaces.tsx

@@ -368,20 +368,20 @@ export function ManageMarketplaces({
       label: `Browse plugins (${marketplace.pluginCount ?? 0})`,
       value: 'browse'
     }, {
-      label: 'Update marketplace',
-      secondaryLabel: marketplace.lastUpdated ? `(last updated ${new Date(marketplace.lastUpdated).toLocaleDateString()})` : undefined,
+      label: '更新插件市场',
+      secondaryLabel: marketplace.lastUpdated ? `(最后更新 ${new Date(marketplace.lastUpdated).toLocaleDateString()})` : undefined,
       value: 'update'
     }];
 
     // Only show auto-update toggle if auto-updater is not globally disabled
     if (!shouldSkipPluginAutoupdate()) {
       options.push({
-        label: marketplace.autoUpdate ? 'Disable auto-update' : 'Enable auto-update',
+        label: marketplace.autoUpdate ? '禁用自动更新' : '启用自动更新',
         value: 'toggle-auto-update'
       });
     }
     options.push({
-      label: 'Remove marketplace',
+      label: '移除插件市场',
       value: 'remove'
     });
     return options;

+ 1 - 1
src/commands/remote-setup/api.ts

@@ -143,7 +143,7 @@ export async function createDefaultEnvironment(): Promise<boolean> {
       {
         name: 'Default',
         kind: 'anthropic_cloud',
-        description: 'Default - trusted network access',
+        description: '默认 - 受信任网络访问',
         config: {
           environment_type: 'anthropic',
           cwd: '/home/user',

+ 1 - 1
src/commands/review/reviewRemote.ts

@@ -283,7 +283,7 @@ export async function launchRemoteReview(
       return [
         {
           type: 'text',
-          text: 'Repo is too large. Push a PR and use `/ultrareview <PR#>` instead.',
+          text: '仓库过大。请推送 PR 后使用 /ultrareview <PR#> 代替。',
         },
       ]
     }

+ 2 - 2
src/commands/thinkback-play/thinkback-play.ts

@@ -25,7 +25,7 @@ export async function call(): Promise<LocalCommandResult> {
     return {
       type: 'text' as const,
       value:
-        'Thinkback plugin not installed. Run /think-back first to install it.',
+        'Thinkback 插件未安装。请先运行 /think-back 安装。',
     }
   }
 
@@ -33,7 +33,7 @@ export async function call(): Promise<LocalCommandResult> {
   if (!firstInstall?.installPath) {
     return {
       type: 'text' as const,
-      value: 'Thinkback plugin installation path not found.',
+      value: '未找到 Thinkback 插件安装路径。',
     }
   }
 

+ 1 - 1
src/commands/ultraplan.tsx

@@ -216,7 +216,7 @@ export async function stopUltraplan(taskId: string, sessionId: string, setAppSta
     mode: 'task-notification'
   });
   enqueuePendingNotification({
-    value: 'The user stopped the ultraplan session above. Do not respond to the stop notification — wait for their next message.',
+    value: '用户已停止上述 ultraplan 会话。请勿响应停止通知——等待用户下一条消息。',
     mode: 'task-notification',
     isMeta: true
   });

+ 2 - 2
src/components/Feedback.tsx

@@ -456,7 +456,7 @@ async function generateTitle(description: string, abortSignal: AbortSignal): Pro
         mcpTools: []
       }
     });
-    const title = response.message.content[0]?.type === 'text' ? response.message.content[0].text : 'Bug Report';
+    const title = response.message.content[0]?.type === 'text' ? response.message.content[0].text : 'Bug 报告';
 
     // Check if the title contains an API error message
     if (startsWithApiErrorPrefix(title)) {
@@ -492,7 +492,7 @@ function createFallbackTitle(description: string): string {
     }
     truncated += '...';
   }
-  return truncated.length < 10 ? 'Bug Report' : truncated;
+  return truncated.length < 10 ? 'Bug 报告' : truncated;
 }
 
 // Helper function to sanitize and log errors without exposing API keys

+ 1 - 1
src/components/LogSelector.tsx

@@ -823,7 +823,7 @@ export function LogSelector(t0) {
         }
         setAgenticSearchState({
           status: "error",
-          message: error instanceof Error ? error.message : "Search failed"
+          message: error instanceof Error ? error.message : "搜索失败"
         });
         logEvent("tengu_agentic_search_error", {
           query_length: searchQuery.length

+ 8 - 8
src/components/MessageSelector.tsx

@@ -93,20 +93,20 @@ export function MessageSelector({
   function getRestoreOptions(canRestoreCode: boolean): OptionWithDescription<RestoreOption>[] {
     const baseOptions: OptionWithDescription<RestoreOption>[] = canRestoreCode ? [{
       value: 'both',
-      label: 'Restore code and conversation'
+      label: '恢复代码和对话'
     }, {
       value: 'conversation',
-      label: 'Restore conversation'
+      label: '仅恢复对话'
     }, {
       value: 'code',
-      label: 'Restore code'
+      label: '仅恢复代码'
     }] : [{
       value: 'conversation',
-      label: 'Restore conversation'
+      label: '恢复对话'
     }];
     const summarizeInputProps = {
       type: 'input' as const,
-      placeholder: 'add context (optional)',
+      placeholder: '添加上下文(可选)',
       initialValue: '',
       allowEmptySubmitToCancel: true,
       showLabelWithValue: true,
@@ -114,21 +114,21 @@ export function MessageSelector({
     };
     baseOptions.push({
       value: 'summarize',
-      label: 'Summarize from here',
+      label: '从此处总结',
       ...summarizeInputProps,
       onChange: setSummarizeFromFeedback
     });
     if ("external" === 'ant') {
       baseOptions.push({
         value: 'summarize_up_to',
-        label: 'Summarize up to here',
+        label: '总结到此行为止',
         ...summarizeInputProps,
         onChange: setSummarizeUpToFeedback
       });
     }
     baseOptions.push({
       value: 'nevermind',
-      label: 'Never mind'
+      label: '取消'
     });
     return baseOptions;
   }

+ 4 - 4
src/components/PromptInput/PromptInput.tsx

@@ -749,7 +749,7 @@ function PromptInput({
     if (thinkTriggers.length && isUltrathinkEnabled()) {
       addNotification({
         key: 'ultrathink-active',
-        text: 'Effort set to high for this turn',
+        text: '本轮努力已设为高',
         priority: 'immediate',
         timeoutMs: 5000
       });
@@ -761,7 +761,7 @@ function PromptInput({
     if (feature('ULTRAPLAN') && ultraplanTriggers.length) {
       addNotification({
         key: 'ultraplan-active',
-        text: 'This prompt will launch an ultraplan session in Claude Code on the web',
+        text: '此提示将启动网页版 Claude Code 的 ultraplan 会话',
         priority: 'immediate',
         timeoutMs: 5000
       });
@@ -773,7 +773,7 @@ function PromptInput({
     if (isUltrareviewEnabled() && ultrareviewTriggers.length) {
       addNotification({
         key: 'ultrareview-active',
-        text: 'Run /ultrareview after Claude finishes to review these changes in the cloud',
+        text: '在 Claude 完成后运行 /ultrareview 在云端审查这些更改',
         priority: 'immediate',
         timeoutMs: 5000
       });
@@ -1623,7 +1623,7 @@ function PromptInput({
         onImagePaste(imageData.base64, imageData.mediaType);
       } else {
         const shortcutDisplay = getShortcutDisplay('chat:imagePaste', 'Chat', 'ctrl+v');
-        const message = env.isSSH() ? "No image found in clipboard. You're SSH'd; try scp?" : `No image found in clipboard. Use ${shortcutDisplay} to paste images.`;
+        const message = env.isSSH() ? "剪贴板中未找到图片。当前处于 SSH 模式,请尝试 scp 传输。" : `剪贴板中未找到图片。请使用 ${shortcutDisplay} 粘贴图片。`;
         addNotification({
           key: 'no-image-in-clipboard',
           text: message,

+ 43 - 43
src/components/Settings/Config.tsx

@@ -265,7 +265,7 @@ export function Config({
   // Global settings
   {
     id: 'autoCompactEnabled',
-    label: 'Auto-compact',
+    label: '自动压缩',
     value: globalConfig.autoCompactEnabled,
     type: 'boolean' as const,
     onChange(autoCompactEnabled: boolean) {
@@ -283,7 +283,7 @@ export function Config({
     }
   }, {
     id: 'spinnerTipsEnabled',
-    label: 'Show tips',
+    label: '显示提示技巧',
     value: settingsData?.spinnerTipsEnabled ?? true,
     type: 'boolean' as const,
     onChange(spinnerTipsEnabled: boolean) {
@@ -301,7 +301,7 @@ export function Config({
     }
   }, {
     id: 'prefersReducedMotion',
-    label: 'Reduce motion',
+    label: '减弱动态效果',
     value: settingsData?.prefersReducedMotion ?? false,
     type: 'boolean' as const,
     onChange(prefersReducedMotion: boolean) {
@@ -326,7 +326,7 @@ export function Config({
     }
   }, {
     id: 'thinkingEnabled',
-    label: 'Thinking mode',
+    label: '思考模式',
     value: thinkingEnabled ?? true,
     type: 'boolean' as const,
     onChange(enabled: boolean) {
@@ -345,7 +345,7 @@ export function Config({
   // Fast mode toggle (ant-only, eliminated from external builds)
   ...(isFastModeEnabled() && isFastModeAvailable() ? [{
     id: 'fastMode',
-    label: `Fast mode (${FAST_MODE_MODEL_DISPLAY} only)`,
+    label: `快速模式(仅 ${FAST_MODE_MODEL_DISPLAY})`,
     value: !!isFastMode,
     type: 'boolean' as const,
     onChange(enabled_0: boolean) {
@@ -378,7 +378,7 @@ export function Config({
     }
   }] : []), ...(getFeatureValue_CACHED_MAY_BE_STALE('tengu_chomp_inflection', false) ? [{
     id: 'promptSuggestionEnabled',
-    label: 'Prompt suggestions',
+    label: '提示词建议',
     value: promptSuggestionEnabled,
     type: 'boolean' as const,
     onChange(enabled_1: boolean) {
@@ -394,7 +394,7 @@ export function Config({
   // Speculation toggle (ant-only)
   ...("external" === 'ant' ? [{
     id: 'speculationEnabled',
-    label: 'Speculative execution',
+    label: '推测执行',
     value: globalConfig.speculationEnabled ?? true,
     type: 'boolean' as const,
     onChange(enabled_2: boolean) {
@@ -415,7 +415,7 @@ export function Config({
     }
   }] : []), ...(isFileCheckpointingAvailable ? [{
     id: 'fileCheckpointingEnabled',
-    label: 'Rewind code (checkpoints)',
+    label: '代码回退(检查点)',
     value: globalConfig.fileCheckpointingEnabled,
     type: 'boolean' as const,
     onChange(enabled_3: boolean) {
@@ -433,13 +433,13 @@ export function Config({
     }
   }] : []), {
     id: 'verbose',
-    label: 'Verbose output',
+    label: '详细输出',
     value: verbose,
     type: 'boolean',
     onChange: onChangeVerbose
   }, {
     id: 'terminalProgressBarEnabled',
-    label: 'Terminal progress bar',
+    label: '终端进度条',
     value: globalConfig.terminalProgressBarEnabled,
     type: 'boolean' as const,
     onChange(terminalProgressBarEnabled: boolean) {
@@ -457,7 +457,7 @@ export function Config({
     }
   }, ...(getFeatureValue_CACHED_MAY_BE_STALE('tengu_terminal_sidebar', false) ? [{
     id: 'showStatusInTerminalTab',
-    label: 'Show status in terminal tab',
+    label: '终端标签显示状态',
     value: globalConfig.showStatusInTerminalTab ?? false,
     type: 'boolean' as const,
     onChange(showStatusInTerminalTab: boolean) {
@@ -475,7 +475,7 @@ export function Config({
     }
   }] : []), {
     id: 'showTurnDuration',
-    label: 'Show turn duration',
+    label: '显示轮次耗时',
     value: globalConfig.showTurnDuration,
     type: 'boolean' as const,
     onChange(showTurnDuration: boolean) {
@@ -493,7 +493,7 @@ export function Config({
     }
   }, {
     id: 'defaultPermissionMode',
-    label: 'Default permission mode',
+    label: '默认权限模式',
     value: settingsData?.permissions?.defaultMode || 'default',
     options: (() => {
       const priorityOrder: PermissionMode[] = ['default', 'plan'];
@@ -543,7 +543,7 @@ export function Config({
     }
   }, ...(feature('TRANSCRIPT_CLASSIFIER') && showAutoInDefaultModePicker ? [{
     id: 'useAutoModeDuringPlan',
-    label: 'Use auto mode during plan',
+    label: '规划时使用自动模式',
     value: (settingsData as {
       useAutoModeDuringPlan?: boolean;
     } | undefined)?.useAutoModeDuringPlan ?? true,
@@ -574,7 +574,7 @@ export function Config({
     }
   }] : []), {
     id: 'respectGitignore',
-    label: 'Respect .gitignore in file picker',
+    label: '文件选择器中遵守 .gitignore',
     value: globalConfig.respectGitignore,
     type: 'boolean' as const,
     onChange(respectGitignore: boolean) {
@@ -592,7 +592,7 @@ export function Config({
     }
   }, {
     id: 'copyFullResponse',
-    label: 'Always copy full response (skip /copy picker)',
+    label: '始终复制完整响应(跳过 /copy 选择器)',
     value: globalConfig.copyFullResponse,
     type: 'boolean' as const,
     onChange(copyFullResponse: boolean) {
@@ -614,7 +614,7 @@ export function Config({
   // alt-screen mode). In inline mode the terminal emulator owns selection.
   ...(isFullscreenEnvEnabled() ? [{
     id: 'copyOnSelect',
-    label: 'Copy on select',
+    label: '选中即复制',
     value: globalConfig.copyOnSelect ?? true,
     type: 'boolean' as const,
     onChange(copyOnSelect: boolean) {
@@ -635,13 +635,13 @@ export function Config({
   // autoUpdates setting is hidden - use DISABLE_AUTOUPDATER env var to control
   autoUpdaterDisabledReason ? {
     id: 'autoUpdatesChannel',
-    label: 'Auto-update channel',
+    label: '自动更新通道',
     value: 'disabled',
     type: 'managedEnum' as const,
     onChange() {}
   } : {
     id: 'autoUpdatesChannel',
-    label: 'Auto-update channel',
+    label: '自动更新通道',
     value: settingsData?.autoUpdatesChannel ?? 'latest',
     type: 'managedEnum' as const,
     onChange() {
@@ -649,7 +649,7 @@ export function Config({
     }
   }, {
     id: 'theme',
-    label: 'Theme',
+    label: '主题',
     value: themeSetting,
     type: 'managedEnum',
     onChange: setTheme
@@ -671,7 +671,7 @@ export function Config({
     }
   }, ...(feature('KAIROS') || feature('KAIROS_PUSH_NOTIFICATION') ? [{
     id: 'taskCompleteNotifEnabled',
-    label: 'Push when idle',
+    label: '空闲时推送',
     value: globalConfig.taskCompleteNotifEnabled ?? false,
     type: 'boolean' as const,
     onChange(taskCompleteNotifEnabled: boolean) {
@@ -686,7 +686,7 @@ export function Config({
     }
   }, {
     id: 'inputNeededNotifEnabled',
-    label: 'Push when input needed',
+    label: '需要输入时推送',
     value: globalConfig.inputNeededNotifEnabled ?? false,
     type: 'boolean' as const,
     onChange(inputNeededNotifEnabled: boolean) {
@@ -701,7 +701,7 @@ export function Config({
     }
   }, {
     id: 'agentPushNotifEnabled',
-    label: 'Push when Claude decides',
+    label: 'Claude 决定时推送',
     value: globalConfig.agentPushNotifEnabled ?? false,
     type: 'boolean' as const,
     onChange(agentPushNotifEnabled: boolean) {
@@ -716,13 +716,13 @@ export function Config({
     }
   }] : []), {
     id: 'outputStyle',
-    label: 'Output style',
+    label: '输出样式',
     value: currentOutputStyle,
     type: 'managedEnum' as const,
     onChange: () => {} // handled by OutputStylePicker submenu
   }, ...(showDefaultViewPicker ? [{
     id: 'defaultView',
-    label: 'What you see by default',
+    label: '默认视图',
     // 'default' means the setting is unset — currently resolves to
     // transcript (main.tsx falls through when defaultView !== 'chat').
     // String() narrows the conditional-schema-spread union to string.
@@ -761,13 +761,13 @@ export function Config({
     }
   }] : []), {
     id: 'language',
-    label: 'Language',
-    value: currentLanguage ?? 'Default (English)',
+    label: '语言',
+    value: currentLanguage ?? '默认(英文)',
     type: 'managedEnum' as const,
     onChange: () => {} // handled by LanguagePicker submenu
   }, {
     id: 'editorMode',
-    label: 'Editor mode',
+    label: '编辑模式',
     // Convert 'emacs' to 'normal' for backward compatibility
     value: globalConfig.editorMode === 'emacs' ? 'normal' : globalConfig.editorMode || 'normal',
     options: ['normal', 'vim'],
@@ -788,7 +788,7 @@ export function Config({
     }
   }, {
     id: 'prStatusFooterEnabled',
-    label: 'Show PR status footer',
+    label: '显示 PR 状态页脚',
     value: globalConfig.prStatusFooterEnabled ?? true,
     type: 'boolean' as const,
     onChange(enabled_4: boolean) {
@@ -809,13 +809,13 @@ export function Config({
     }
   }, {
     id: 'model',
-    label: 'Model',
-    value: mainLoopModel === null ? 'Default (recommended)' : mainLoopModel,
+    label: '模型',
+    value: mainLoopModel === null ? '默认(推荐)' : mainLoopModel,
     type: 'managedEnum' as const,
     onChange: onChangeMainModelConfig
   }, ...(isConnectedToIde ? [{
     id: 'diffTool',
-    label: 'Diff tool',
+    label: '差异工具',
     value: globalConfig.diffTool ?? 'auto',
     options: ['terminal', 'auto'],
     type: 'enum' as const,
@@ -835,7 +835,7 @@ export function Config({
     }
   }] : []), ...(!isSupportedTerminal() ? [{
     id: 'autoConnectIde',
-    label: 'Auto-connect to IDE (external terminal)',
+    label: '自动连接 IDE(外部终端)',
     value: globalConfig.autoConnectIde ?? false,
     type: 'boolean' as const,
     onChange(autoConnectIde: boolean) {
@@ -854,7 +854,7 @@ export function Config({
     }
   }] : []), ...(isSupportedTerminal() ? [{
     id: 'autoInstallIdeExtension',
-    label: 'Auto-install IDE extension',
+    label: '自动安装 IDE 扩展',
     value: globalConfig.autoInstallIdeExtension ?? true,
     type: 'boolean' as const,
     onChange(autoInstallIdeExtension: boolean) {
@@ -873,7 +873,7 @@ export function Config({
     }
   }] : []), {
     id: 'claudeInChromeDefaultEnabled',
-    label: 'Claude in Chrome enabled by default',
+    label: '默认启用 Chrome 中的 Claude',
     value: globalConfig.claudeInChromeDefaultEnabled ?? true,
     type: 'boolean' as const,
     onChange(enabled_5: boolean) {
@@ -893,7 +893,7 @@ export function Config({
   // Teammate mode (only shown when agent swarms are enabled)
   ...(isAgentSwarmsEnabled() ? (() => {
     const cliOverride = getCliTeammateModeOverride();
-    const label = cliOverride ? `Teammate mode [overridden: ${cliOverride}]` : 'Teammate mode';
+    const label = cliOverride ? `协作者模式 [被覆盖: ${cliOverride}]` : '协作者模式';
     return [{
       id: 'teammateMode',
       label,
@@ -920,7 +920,7 @@ export function Config({
       }
     }, {
       id: 'teammateDefaultModel',
-      label: 'Default teammate model',
+      label: '默认协作者模型',
       value: teammateModelDisplayString(globalConfig.teammateDefaultModel),
       type: 'managedEnum' as const,
       onChange() {}
@@ -929,7 +929,7 @@ export function Config({
   // Remote at startup toggle — gated on build flag + GrowthBook + policy
   ...(feature('BRIDGE_MODE') && isBridgeEnabled() ? [{
     id: 'remoteControlAtStartup',
-    label: 'Enable Remote Control for all sessions',
+    label: '为所有会话启用远程控制',
     value: globalConfig.remoteControlAtStartup === undefined ? 'default' : String(globalConfig.remoteControlAtStartup),
     options: ['true', 'false', 'default'],
     type: 'enum' as const,
@@ -975,7 +975,7 @@ export function Config({
     }
   }] : []), ...(shouldShowExternalIncludesToggle ? [{
     id: 'showExternalIncludesDialog',
-    label: 'External CLAUDE.md includes',
+    label: '外部 CLAUDE.md 引用',
     value: (() => {
       const projectConfig = getCurrentProjectConfig();
       if (projectConfig.hasClaudeMdExternalIncludesApproved) {
@@ -1137,7 +1137,7 @@ export function Config({
       formattedChanges.push(`${globalConfig.autoInstallIdeExtension ? 'Enabled' : 'Disabled'} auto-install IDE extension`);
     }
     if (globalConfig.autoCompactEnabled !== initialConfig.current.autoCompactEnabled) {
-      formattedChanges.push(`${globalConfig.autoCompactEnabled ? 'Enabled' : 'Disabled'} auto-compact`);
+      formattedChanges.push(`${globalConfig.autoCompactEnabled ? '已启用' : '已禁用'}自动压缩`);
     }
     if (globalConfig.respectGitignore !== initialConfig.current.respectGitignore) {
       formattedChanges.push(`${globalConfig.respectGitignore ? 'Enabled' : 'Disabled'} respect .gitignore in file picker`);
@@ -1158,7 +1158,7 @@ export function Config({
       formattedChanges.push(`${globalConfig.showTurnDuration ? 'Enabled' : 'Disabled'} turn duration`);
     }
     if (globalConfig.remoteControlAtStartup !== initialConfig.current.remoteControlAtStartup) {
-      const remoteLabel = globalConfig.remoteControlAtStartup === undefined ? 'Reset Remote Control to default' : `${globalConfig.remoteControlAtStartup ? 'Enabled' : 'Disabled'} Remote Control for all sessions`;
+      const remoteLabel = globalConfig.remoteControlAtStartup === undefined ? '远程控制重置为默认' : `${globalConfig.remoteControlAtStartup ? '已启用' : '已禁用'}所有会话的远程控制`;
       formattedChanges.push(remoteLabel);
     }
     if (settingsData?.autoUpdatesChannel !== initialSettingsData.current?.autoUpdatesChannel) {
@@ -1593,10 +1593,10 @@ export function Config({
                   auto-updates.
                 </Text>}
             </> : <Select options={[{
-        label: 'Enable with latest channel',
+        label: '使用最新通道启用',
         value: 'latest'
       }, {
-        label: 'Enable with stable channel',
+        label: '使用稳定通道启用',
         value: 'stable'
       }]} onChange={(channel: string) => {
         isDirty.current = true;

+ 1 - 1
src/components/StatusLine.tsx

@@ -277,7 +277,7 @@ function StatusLineInner({
       if (!checkHasTrustDialogAccepted()) {
         addNotification({
           key: 'statusline-trust-blocked',
-          text: 'statusline skipped · restart to fix',
+          text: '状态栏已跳过 · 重启以修复',
           color: 'warning',
           priority: 'low'
         });

+ 1 - 1
src/components/mcp/MCPAgentServerMenu.tsx

@@ -112,7 +112,7 @@ export function MCPAgentServerMenu({
     });
   }
   menuOptions.push({
-    label: 'Back',
+    label: '返回',
     value: 'back'
   });
   return <Dialog title={`${capitalizedServerName} MCP 服务器`} subtitle="仅代理" onCancel={onCancel} inputGuide={exitState => exitState.pending ? <Text>再次按 {exitState.keyName} 退出</Text> : <Byline>

+ 13 - 13
src/components/mcp/MCPRemoteServerMenu.tsx

@@ -102,7 +102,7 @@ export function MCPRemoteServerMenu({
       if (success) {
         onComplete?.(`Authentication successful. Connected to ${server.name}.`);
       } else if (result.client.type === 'needs-auth') {
-        onComplete?.('Authentication successful, but server still requires authentication. You may need to manually restart Claude Code.');
+        onComplete?.('认证成功,但服务器仍需要认证。您可能需要手动重启 Claude Code。');
       } else {
         onComplete?.('Authentication successful, but server reconnection failed. You may need to manually restart Claude Code for the changes to take effect.');
       }
@@ -281,11 +281,11 @@ export function MCPRemoteServerMenu({
           const message = isEffectivelyAuthenticated ? `Authentication successful. Reconnected to ${server.name}.` : `Authentication successful. Connected to ${server.name}.`;
           onComplete?.(message);
         } else if (result_0.client.type === 'needs-auth') {
-          onComplete?.('Authentication successful, but server still requires authentication. You may need to manually restart Claude Code.');
+          onComplete?.('认证成功,但服务器仍需要认证。您可能需要手动重启 Claude Code。');
         } else {
           // result.client.type === 'failed'
           logMCPDebug(server.name, `Reconnection failed after authentication`);
-          onComplete?.('Authentication successful, but server reconnection failed. You may need to manually restart Claude Code for the changes to take effect.');
+          onComplete?.('认证成功,但服务器重新连接失败。您可能需要手动重启 Claude Code 以使更改生效。');
         }
       }
     } catch (err_1) {
@@ -472,42 +472,42 @@ export function MCPRemoteServerMenu({
   // If server is disabled, show Enable first as the primary action
   if (server.client.type === 'disabled') {
     menuOptions.push({
-      label: 'Enable',
+      label: '启用',
       value: 'toggle-enabled'
     });
   }
   if (server.client.type === 'connected' && serverToolsCount > 0) {
     menuOptions.push({
-      label: 'View tools',
+      label: '查看工具',
       value: 'tools'
     });
   }
   if (server.config.type === 'claudeai-proxy') {
     if (server.client.type === 'connected') {
       menuOptions.push({
-        label: 'Clear authentication',
+        label: '清除认证',
         value: 'claudeai-clear-auth'
       });
     } else if (server.client.type !== 'disabled') {
       menuOptions.push({
-        label: 'Authenticate',
+        label: '认证',
         value: 'claudeai-auth'
       });
     }
   } else {
     if (isEffectivelyAuthenticated) {
       menuOptions.push({
-        label: 'Re-authenticate',
+        label: '重新认证',
         value: 'reauth'
       });
       menuOptions.push({
-        label: 'Clear authentication',
+        label: '清除认证',
         value: 'clear-auth'
       });
     }
     if (!isEffectivelyAuthenticated) {
       menuOptions.push({
-        label: 'Authenticate',
+        label: '认证',
         value: 'auth'
       });
     }
@@ -515,12 +515,12 @@ export function MCPRemoteServerMenu({
   if (server.client.type !== 'disabled') {
     if (server.client.type !== 'needs-auth') {
       menuOptions.push({
-        label: 'Reconnect',
+        label: '重新连接',
         value: 'reconnectMcpServer'
       });
     }
     menuOptions.push({
-      label: 'Disable',
+      label: '禁用',
       value: 'toggle-enabled'
     });
   }
@@ -528,7 +528,7 @@ export function MCPRemoteServerMenu({
   // If there are no other options, add a back option so Select handles escape
   if (menuOptions.length === 0) {
     menuOptions.push({
-      label: 'Back',
+      label: '返回',
       value: 'back'
     });
   }

+ 4 - 4
src/components/mcp/MCPStdioServerMenu.tsx

@@ -61,7 +61,7 @@ export function MCPStdioServerMenu({
   // Only show "View tools" if server is not disabled and has tools
   if (server.client.type !== 'disabled' && serverToolsCount > 0) {
     menuOptions.push({
-      label: 'View tools',
+      label: '查看工具',
       value: 'tools'
     });
   }
@@ -69,19 +69,19 @@ export function MCPStdioServerMenu({
   // Only show reconnect option if the server is not disabled
   if (server.client.type !== 'disabled') {
     menuOptions.push({
-      label: 'Reconnect',
+      label: '重新连接',
       value: 'reconnectMcpServer'
     });
   }
   menuOptions.push({
-    label: server.client.type !== 'disabled' ? 'Disable' : 'Enable',
+    label: server.client.type !== 'disabled' ? '禁用' : '启用',
     value: 'toggle-enabled'
   });
 
   // If there are no other options, add a back option so Select handles escape
   if (menuOptions.length === 0) {
     menuOptions.push({
-      label: 'Back',
+      label: '返回',
       value: 'back'
     });
   }

+ 9 - 9
src/coordinator/coordinatorMode.ts

@@ -170,8 +170,8 @@ Each "You:" block is a separate coordinator turn. The "User:" block is a \`<task
 You:
   Let me start some research on that.
 
-  ${AGENT_TOOL_NAME}({ description: "Investigate auth bug", subagent_type: "worker", prompt: "..." })
-  ${AGENT_TOOL_NAME}({ description: "Research secure token storage", subagent_type: "worker", prompt: "..." })
+  ${AGENT_TOOL_NAME}({ description: "调查认证 bug", subagent_type: "worker", prompt: "..." })
+  ${AGENT_TOOL_NAME}({ description: "研究安全令牌存储", subagent_type: "worker", prompt: "..." })
 
   Investigating both issues in parallel — I'll report back with findings.
 
@@ -179,7 +179,7 @@ User:
   <task-notification>
   <task-id>agent-a1b</task-id>
   <status>completed</status>
-  <summary>Agent "Investigate auth bug" completed</summary>
+  <summary>Agent "调查认证 bug" completed</summary>
   <result>Found null pointer in src/auth/validate.ts:42...</result>
   </task-notification>
 
@@ -187,7 +187,7 @@ You:
   Found the bug — null pointer in confirmTokenExists in validate.ts. I'll fix it.
   Still waiting on the token storage research.
 
-  ${SEND_MESSAGE_TOOL_NAME}({ to: "agent-a1b", message: "Fix the null pointer in src/auth/validate.ts:42..." })
+  ${SEND_MESSAGE_TOOL_NAME}({ to: "agent-a1b", message: "修复 src/auth/validate.ts:42 中的空指针..." })
 
 ## 3. Workers
 
@@ -238,7 +238,7 @@ Use ${TASK_STOP_TOOL_NAME} to stop a worker you sent in the wrong direction —
 
 \`\`\`
 // Launched a worker to refactor auth to use JWT
-${AGENT_TOOL_NAME}({ description: "Refactor auth to JWT", subagent_type: "worker", prompt: "Replace session-based auth with JWT..." })
+${AGENT_TOOL_NAME}({ description: "重构认证为 JWT", subagent_type: "worker", prompt: "Replace session-based auth with JWT..." })
 // ... returns task_id: "agent-x7q" ...
 
 // User clarifies: "Actually, keep sessions — just fix the null pointer"
@@ -302,7 +302,7 @@ ${SEND_MESSAGE_TOOL_NAME}({ to: "xyz-456", message: "Fix the null pointer in src
 
 \`\`\`
 // Correction — worker just reported test failures from its own change, keep it brief
-${SEND_MESSAGE_TOOL_NAME}({ to: "xyz-456", message: "Two tests still failing at lines 58 and 72 — update the assertions to match the new error message." })
+${SEND_MESSAGE_TOOL_NAME}({ to: "xyz-456", message: "两个测试在第 58 和 72 行仍然失败 — 更新断言以匹配新的错误消息。" })
 \`\`\`
 
 ### Prompt tips
@@ -341,8 +341,8 @@ User: "There's a null pointer in the auth module. Can you fix it?"
 You:
   Let me investigate first.
 
-  ${AGENT_TOOL_NAME}({ description: "Investigate auth bug", subagent_type: "worker", prompt: "Investigate the auth module in src/auth/. Find where null pointer exceptions could occur around session handling and token validation... Report specific file paths, line numbers, and types involved. Do not modify files." })
-  ${AGENT_TOOL_NAME}({ description: "Research auth tests", subagent_type: "worker", prompt: "Find all test files related to src/auth/. Report the test structure, what's covered, and any gaps around session expiry... Do not modify files." })
+  ${AGENT_TOOL_NAME}({ description: "调查认证 bug", subagent_type: "worker", prompt: "Investigate the auth module in src/auth/. Find where null pointer exceptions could occur around session handling and token validation... Report specific file paths, line numbers, and types involved. Do not modify files." })
+  ${AGENT_TOOL_NAME}({ description: "研究认证测试", subagent_type: "worker", prompt: "Find all test files related to src/auth/. Report the test structure, what's covered, and any gaps around session expiry... Do not modify files." })
 
   Investigating from two angles — I'll report back with findings.
 
@@ -350,7 +350,7 @@ User:
   <task-notification>
   <task-id>agent-a1b</task-id>
   <status>completed</status>
-  <summary>Agent "Investigate auth bug" completed</summary>
+  <summary>Agent "调查认证 bug" completed</summary>
   <result>Found null pointer in src/auth/validate.ts:42. The user field on Session is undefined when the session expires but ...</result>
   </task-notification>
 

+ 3 - 3
src/hooks/notifs/useFastModeNotification.tsx

@@ -32,7 +32,7 @@ export function useFastModeNotification() {
             key: ORG_CHANGED_KEY,
             color: "fastMode",
             priority: "immediate",
-            text: "Fast mode is now available \xB7 /fast to turn on"
+            text: "\u5feb\u901f\u6a21\u5f0f\u73b0\u5df2\u53ef\u7528 \u00b7 \u8fd0\u884c /fast \u5f00\u542f"
           });
         } else {
           if (isFastMode) {
@@ -41,7 +41,7 @@ export function useFastModeNotification() {
               key: ORG_CHANGED_KEY,
               color: "warning",
               priority: "immediate",
-              text: "Fast mode has been disabled by your organization"
+              text: "快速模式已被你的组织禁用"
             });
           }
         }
@@ -116,7 +116,7 @@ export function useFastModeNotification() {
           key: COOLDOWN_EXPIRED_KEY,
           invalidates: [COOLDOWN_STARTED_KEY],
           color: "fastMode",
-          text: "Fast limit reset \xB7 now using fast mode",
+          text: "\u5feb\u901f\u9650\u5236\u5df2\u91cd\u7f6e \u00b7 \u73b0\u5728\u4f7f\u7528\u5feb\u901f\u6a21\u5f0f",
           priority: "immediate"
         });
       });

+ 2 - 2
src/hooks/notifs/useIDEStatusIndicator.tsx

@@ -118,7 +118,7 @@ export function useIDEStatusIndicator(t0) {
       }
       addNotification({
         key: "ide-status-jetbrains-disconnected",
-        text: "IDE plugin not connected \xB7 /status for info",
+        text: "IDE \u63d2\u4ef6\u672a\u8fde\u63a5 \u00b7 \u8fd0\u884c /status \u67e5\u770b",
         priority: "medium"
       });
     };
@@ -146,7 +146,7 @@ export function useIDEStatusIndicator(t0) {
       }
       addNotification({
         key: "ide-status-install-error",
-        text: "IDE extension install failed (see /status for info)",
+        text: "IDE 扩展安装失败(见 /status)",
         color: "error",
         priority: "medium"
       });

+ 1 - 1
src/hooks/useChromeExtensionNotification.tsx

@@ -41,7 +41,7 @@ async function _temp() {
   if (chromeFlag === undefined) {
     return {
       key: "claude-in-chrome-default-enabled",
-      text: "Claude in Chrome enabled \xB7 /chrome",
+      text: "Chrome 扩展已启用 · 使用 /chrome 管理",
       priority: "low"
     };
   }

+ 2 - 2
src/hooks/useManagePlugins.ts

@@ -61,7 +61,7 @@ export function useManagePlugins({
       if (Object.keys(flagged).length > 0) {
         addNotification({
           key: 'plugin-delisted-flagged',
-          text: 'Plugins flagged. Check /plugins',
+          text: '插件存在异常,请检查 /plugins',
           color: 'warning',
           priority: 'high',
         })
@@ -294,7 +294,7 @@ export function useManagePlugins({
     if (!enabled || !needsRefresh) return
     addNotification({
       key: 'plugin-reload-pending',
-      text: 'Plugins changed. Run /reload-plugins to activate.',
+      text: '插件状态已变化,请运行 /reload-plugins 生效',
       color: 'suggestion',
       priority: 'low',
     })

+ 2 - 2
src/hooks/useReplBridge.tsx

@@ -428,13 +428,13 @@ export function useReplBridge(messages: Message[], setMessages: (action: React.S
                 if (isBypassPermissionsModeDisabled()) {
                   return {
                     ok: false,
-                    error: 'Cannot set permission mode to bypassPermissions because it is disabled by settings or configuration'
+                    error: '无法设置为绕过权限模式,因为设置或配置中已禁用'
                   };
                 }
                 if (!store.getState().toolPermissionContext.isBypassPermissionsModeAvailable) {
                   return {
                     ok: false,
-                    error: 'Cannot set permission mode to bypassPermissions because the session was not launched with --dangerously-skip-permissions'
+                    error: '无法设置为绕过权限模式,因为会话未使用 --dangerously-skip-permissions 启动'
                   };
                 }
               }

+ 1 - 1
src/hooks/useSSHSession.ts

@@ -124,7 +124,7 @@ export function useSSHSession({
           onAbort() {
             manager.respondToPermissionRequest(requestId, {
               behavior: 'deny',
-              message: 'User aborted',
+              message: '用户已中止',
             })
             setToolUseConfirmQueue(q =>
               q.filter(i => i.toolUseID !== request.tool_use_id),

+ 1 - 1
src/hooks/useTextInput.ts

@@ -130,7 +130,7 @@ export function useTextInput({
       }
       addNotification({
         key: 'escape-again-to-clear',
-        text: 'Esc again to clear',
+        text: '再次按 Esc 清除',
         priority: 'immediate',
         timeoutMs: 1000,
       })

+ 2 - 2
src/hooks/useTypeahead.tsx

@@ -609,7 +609,7 @@ export function useTypeahead({
           members.push({
             id: `dm-${t.name}`,
             displayText: `@${t.name}`,
-            description: 'send message'
+            description: '发送消息'
           });
         }
       }
@@ -620,7 +620,7 @@ export function useTypeahead({
         members.push({
           id: `dm-${name}`,
           displayText: `@${name}`,
-          description: status ? `send message · ${status}` : 'send message'
+          description: status ? `send message · ${status}` : '发送消息'
         });
       }
       if (members.length > 0) {

+ 6 - 6
src/hooks/useVoice.ts

@@ -496,15 +496,15 @@ export function useVoice({
             // WS never connected → audio never reached backend. Not a silent
             // drop; a connection failure (slow OAuth refresh, network, etc).
             onErrorRef.current?.(
-              'Voice connection failed. Check your network and try again.',
+              '语音连接失败。请检查网络后重试。',
             )
           } else if (!hadAudioSignal) {
             // Distinguish silent mic (capture issue) from speech not recognized.
             onErrorRef.current?.(
-              'No audio detected from microphone. Check that the correct input device is selected and that Claude Code has microphone access.',
+              '麦克风未检测到音频。请检查输入设备是否正确,以及 Claude Code 是否具有麦克风权限。',
             )
           } else {
-            onErrorRef.current?.('No speech detected.')
+            onErrorRef.current?.('未检测到语音。')
           }
         }
 
@@ -633,7 +633,7 @@ export function useVoice({
   async function startRecordingSession(): Promise<void> {
     if (!voiceModule) {
       onErrorRef.current?.(
-        'Voice module not loaded yet. Try again in a moment.',
+        '语音模块尚未加载。请稍后重试。',
       )
       return
     }
@@ -733,7 +733,7 @@ export function useVoice({
     if (!started) {
       logError(new Error('[voice] Recording failed — no audio tool found'))
       onErrorRef.current?.(
-        'Failed to start audio capture. Check that your microphone is accessible.',
+        '无法启动音频采集。请检查麦克风是否可用。',
       )
       cleanup()
       updateState('idle')
@@ -988,7 +988,7 @@ export function useVoice({
             '[voice] Failed to connect to voice_stream (no OAuth token?)',
           )
           onErrorRef.current?.(
-            'Voice mode requires a Claude.ai account. Please run /login to sign in.',
+            '语音模式需要 Claude.ai 账号。请运行 /login 登录。',
           )
           // Clear the audio buffer on failure
           audioBuffer.length = 0

+ 2 - 2
src/keybindings/loadUserBindings.ts

@@ -150,7 +150,7 @@ export async function loadKeybindings(): Promise<KeybindingsLoadResult> {
       userBlocks = (parsed as { bindings: unknown }).bindings
     } else {
       // Invalid format - missing bindings property
-      const errorMessage = 'keybindings.json must have a "bindings" array'
+      const errorMessage = 'keybindings.json 必须包含 "bindings" 数组'
       const suggestion = 'Use format: { "bindings": [ ... ] }'
       logForDebugging(`[keybindings] Invalid keybindings.json: ${errorMessage}`)
       return {
@@ -288,7 +288,7 @@ export function loadKeybindingsSyncWithWarnings(): KeybindingsLoadResult {
         {
           type: 'parse_error',
           severity: 'error',
-          message: 'keybindings.json must have a "bindings" array',
+          message: 'keybindings.json 必须包含 "bindings" 数组',
           suggestion: 'Use format: { "bindings": [ ... ] }',
         },
       ]

+ 1 - 1
src/keybindings/validate.ts

@@ -316,7 +316,7 @@ export function validateUserConfig(userBlocks: unknown): KeybindingWarning[] {
     warnings.push({
       type: 'parse_error',
       severity: 'error',
-      message: 'keybindings.json must contain an array',
+      message: 'keybindings.json 必须包含数组',
       suggestion: 'Wrap your bindings in [ ]',
     })
     return warnings

+ 3 - 3
src/main.tsx

@@ -1895,7 +1895,7 @@ async function run(): Promise<CommanderCommand> {
         });
       } else {
         logEvent('tengu_structured_output_failure', {
-          error: 'Invalid JSON schema' as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS
+          error: 'JSON 模式无效' as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS
         });
       }
     }
@@ -3317,7 +3317,7 @@ async function run(): Promise<CommanderCommand> {
       try {
         apiCreds = await prepareApiRequest();
       } catch (e) {
-        return await exitWithError(root, `Error: ${e instanceof Error ? e.message : 'Failed to authenticate'}`, () => gracefulShutdown(1));
+        return await exitWithError(root, `Error: ${e instanceof Error ? e.message : '认证失败'}`, () => gracefulShutdown(1));
       }
       const getAccessToken = (): string => getClaudeAIOAuthTokens()?.accessToken ?? apiCreds.accessToken;
 
@@ -3456,7 +3456,7 @@ async function run(): Promise<CommanderCommand> {
           apiCreds = await prepareApiRequest();
         } catch (error) {
           logError(toError(error));
-          return await exitWithError(root, `Error: ${errorMessage(error) || 'Failed to authenticate'}`, () => gracefulShutdown(1));
+          return await exitWithError(root, `Error: ${errorMessage(error) || '认证失败'}`, () => gracefulShutdown(1));
         }
 
         // Create remote session config for the REPL

+ 2 - 2
src/projectOnboardingState.ts

@@ -25,14 +25,14 @@ export function getSteps(): Step[] {
   return [
     {
       key: 'workspace',
-      text: 'Ask Claude to create a new app or clone a repository',
+      text: '让 Claude 创建新应用或克隆仓库',
       isComplete: false,
       isCompletable: true,
       isEnabled: isWorkspaceDirEmpty,
     },
     {
       key: 'claudemd',
-      text: 'Run /init to create a CLAUDE.md file with instructions for Claude',
+      text: '运行 /init 创建 CLAUDE.md 文件,为 Claude 提供指令说明',
       isComplete: hasClaudeMd,
       isCompletable: true,
       isEnabled: !isWorkspaceDirEmpty,

+ 1 - 1
src/services/PromptSuggestion/promptSuggestion.ts

@@ -301,7 +301,7 @@ export async function generateSuggestion(
   // Deny tools via callback, NOT by passing tools:[] - that busts cache (0% hit)
   const canUseTool = async () => ({
     behavior: 'deny' as const,
-    message: 'No tools needed for suggestion',
+    message: '无需工具即可提供建议',
     decisionReason: { type: 'other' as const, reason: 'suggestion only' },
   })
 

+ 1 - 1
src/services/SessionMemory/sessionMemory.ts

@@ -389,7 +389,7 @@ export async function manuallyExtractSessionMemory(
   toolUseContext: ToolUseContext,
 ): Promise<ManualExtractionResult> {
   if (messages.length === 0) {
-    return { success: false, error: 'No messages to summarize' }
+    return { success: false, error: '无可总结的消息' }
   }
   markExtractionStarted()
 

+ 1 - 1
src/services/analytics/firstPartyEventLoggingExporter.ts

@@ -569,7 +569,7 @@ export class FirstPartyEventLoggingExporter implements LogRecordExporter {
 
     // Try with auth headers first (unless trust not established or token is known to be expired)
     const authResult = shouldSkipAuth
-      ? { headers: {}, error: 'trust not established or Oauth token expired' }
+      ? { headers: {}, error: '信任未建立或 OAuth 令牌已过期' }
       : getAuthHeaders()
     const useAuth = !authResult.error
 

+ 1 - 1
src/services/analytics/growthbook.ts

@@ -517,7 +517,7 @@ const getGrowthBookClient = memoize(
       getIsNonInteractiveSession()
     const authHeaders = hasTrust
       ? getAuthHeaders()
-      : { headers: {}, error: 'trust not established' }
+      : { headers: {}, error: '信任未建立' }
     const hasAuth = !authHeaders.error
     clientCreatedWithAuth = hasAuth
 

+ 1 - 1
src/services/api/claude.ts

@@ -2457,7 +2457,7 @@ async function* queryModel(
             { level: 'error' },
           )
           // Throw a more specific error for timeout
-          throw new APIConnectionTimeoutError({ message: 'Request timed out' })
+          throw new APIConnectionTimeoutError({ message: '请求超时' })
         }
       }
 

+ 1 - 1
src/services/api/filesApi.ts

@@ -473,7 +473,7 @@ export async function uploadFile(
           if (!fileId) {
             return {
               done: false,
-              error: 'Upload succeeded but no file ID returned',
+              error: '上传成功但未返回文件 ID',
             }
           }
           logDebug(`Uploaded file ${filePath} -> ${fileId} (${fileSize} bytes)`)

+ 3 - 3
src/services/mcp/client.ts

@@ -989,7 +989,7 @@ export const connectToServer = memoize(
           name: 'claude-code',
           title: 'Claude Code',
           version: MACRO.VERSION ?? 'unknown',
-          description: "Anthropic's agentic coding tool",
+          description: "Anthropic \u7684\u667a\u80fd\u7f16\u7801\u5de5\u5177",
           websiteUrl: PRODUCT_URL,
         },
         {
@@ -1816,7 +1816,7 @@ export const fetchToolsForClient = memoizeWithLRU(
             async checkPermissions() {
               return {
                 behavior: 'passthrough' as const,
-                message: 'MCPTool requires permission.',
+                message: 'MCP 工具需要权限。',
                 suggestions: [
                   {
                     type: 'addRules' as const,
@@ -3284,7 +3284,7 @@ export async function setupSdkMcpClients(
           name: 'claude-code',
           title: 'Claude Code',
           version: MACRO.VERSION ?? 'unknown',
-          description: "Anthropic's agentic coding tool",
+          description: "Anthropic \u7684\u667a\u80fd\u7f16\u7801\u5de5\u5177",
           websiteUrl: PRODUCT_URL,
         },
         {

+ 1 - 1
src/services/mcp/config.ts

@@ -1311,7 +1311,7 @@ export function parseMcpConfig(params: {
       errors: schemaResult.error.issues.map(issue => ({
         ...(filePath && { file: filePath }),
         path: issue.path.join('.'),
-        message: 'Does not adhere to MCP server configuration schema',
+        message: '不符合 MCP 服务器配置模式',
         mcpErrorMetadata: {
           scope,
           severity: 'fatal',

+ 1 - 1
src/services/mcp/types.ts

@@ -48,7 +48,7 @@ const McpOAuthConfigSchema = lazySchema(() =>
       .string()
       .url()
       .startsWith('https://', {
-        message: 'authServerMetadataUrl must use https://',
+        message: 'authServerMetadataUrl 必须使用 https://',
       })
       .optional(),
     xaa: McpXaaConfigSchema().optional(),

+ 1 - 1
src/services/plugins/pluginOperations.ts

@@ -783,7 +783,7 @@ export async function disableAllPluginsOp(): Promise<PluginOperationResult> {
   const enabledPlugins = getPluginEditableScopes()
 
   if (enabledPlugins.size === 0) {
-    return { success: true, message: 'No enabled plugins to disable' }
+    return { success: true, message: '无已启用插件可禁用' }
   }
 
   const disabled: string[] = []

+ 7 - 7
src/services/policyLimits/index.ts

@@ -257,7 +257,7 @@ function getAuthHeaders(): {
 
   return {
     headers: {},
-    error: 'No authentication available',
+    error: '无可用认证',
   }
 }
 
@@ -307,7 +307,7 @@ async function fetchPolicyLimits(
     if (authHeaders.error) {
       return {
         success: false,
-        error: 'Authentication required for policy limits',
+        error: '策略限制需要认证',
         skipRetry: true,
       }
     }
@@ -356,7 +356,7 @@ async function fetchPolicyLimits(
       )
       return {
         success: false,
-        error: 'Invalid policy limits format',
+        error: '策略限制格式无效',
       }
     }
 
@@ -372,13 +372,13 @@ async function fetchPolicyLimits(
       case 'auth':
         return {
           success: false,
-          error: 'Not authorized for policy limits',
+          error: '无策略限制授权',
           skipRetry: true,
         }
       case 'timeout':
-        return { success: false, error: 'Policy limits request timeout' }
+        return { success: false, error: '策略限制请求超时' }
       case 'network':
-        return { success: false, error: 'Cannot connect to server' }
+        return { success: false, error: '无法连接到服务器' }
       default:
         return { success: false, error: message }
     }
@@ -420,7 +420,7 @@ async function saveCachedRestrictions(
     logForDebugging(`Policy limits: Saved to ${path}`)
   } catch (error) {
     logForDebugging(
-      `Policy limits: Failed to save - ${error instanceof Error ? error.message : 'unknown error'}`,
+      `Policy limits: Failed to save - ${error instanceof Error ? error.message : '未知错误'}`,
     )
   }
 }

+ 4 - 4
src/services/rateLimitMocking.ts

@@ -95,8 +95,8 @@ export function checkMockRateLimitError(
     // Create a mock 429 error with the fast mode headers
     const error = new APIError(
       429,
-      { error: { type: 'rate_limit_error', message: 'Rate limit exceeded' } },
-      'Rate limit exceeded',
+      { error: { type: 'rate_limit_error', message: '超出频率限制' } },
+      '超出频率限制',
       // eslint-disable-next-line eslint-plugin-n/no-unsupported-features/node-builtins
       new globalThis.Headers(
         Object.entries(fastModeHeaders).filter(([_, v]) => v !== undefined) as [
@@ -115,8 +115,8 @@ export function checkMockRateLimitError(
     // Create a mock 429 error with the appropriate headers
     const error = new APIError(
       429,
-      { error: { type: 'rate_limit_error', message: 'Rate limit exceeded' } },
-      'Rate limit exceeded',
+      { error: { type: 'rate_limit_error', message: '超出频率限制' } },
+      '超出频率限制',
       // eslint-disable-next-line eslint-plugin-n/no-unsupported-features/node-builtins
       new globalThis.Headers(
         Object.entries(mockHeaders).filter(([_, v]) => v !== undefined) as [

+ 8 - 8
src/services/remoteManagedSettings/index.ts

@@ -198,7 +198,7 @@ function getRemoteSettingsAuthHeaders(): {
 
   return {
     headers: {},
-    error: 'No authentication available',
+    error: '无可用认证',
   }
 }
 
@@ -314,7 +314,7 @@ async function fetchRemoteManagedSettings(
       )
       return {
         success: false,
-        error: 'Invalid remote settings format',
+        error: '远程设置格式无效',
       }
     }
 
@@ -326,7 +326,7 @@ async function fetchRemoteManagedSettings(
       )
       return {
         success: false,
-        error: 'Invalid settings structure',
+        error: '设置结构无效',
       }
     }
 
@@ -347,13 +347,13 @@ async function fetchRemoteManagedSettings(
         // Auth errors (401, 403) should not be retried - the API key doesn't have access
         return {
           success: false,
-          error: 'Not authorized for remote settings',
+          error: '无远程设置授权',
           skipRetry: true,
         }
       case 'timeout':
-        return { success: false, error: 'Remote settings request timeout' }
+        return { success: false, error: '远程设置请求超时' }
       case 'network':
-        return { success: false, error: 'Cannot connect to server' }
+        return { success: false, error: '无法连接到服务器' }
       default:
         return { success: false, error: message }
     }
@@ -379,7 +379,7 @@ async function saveSettings(settings: SettingsJson): Promise<void> {
     logForDebugging(`Remote settings: Saved to ${path}`)
   } catch (error) {
     logForDebugging(
-      `Remote settings: Failed to save - ${error instanceof Error ? error.message : 'unknown error'}`,
+      `Remote settings: Failed to save - ${error instanceof Error ? error.message : '未知错误'}`,
     )
     // Ignore save errors - we'll refetch on next startup
   }
@@ -484,7 +484,7 @@ async function fetchAndLoadRemoteManagedSettings(): Promise<SettingsJson | null>
       const code = getErrnoCode(e)
       if (code !== 'ENOENT') {
         logForDebugging(
-          `Remote settings: Failed to delete cached file - ${e instanceof Error ? e.message : 'unknown error'}`,
+          `Remote settings: Failed to delete cached file - ${e instanceof Error ? e.message : '未知错误'}`,
         )
       }
     }

+ 6 - 6
src/services/settingsSync/index.ts

@@ -240,7 +240,7 @@ function getSettingsSyncAuthHeaders(): {
 
   return {
     headers: {},
-    error: 'No OAuth token available',
+    error: '无可用 OAuth 令牌',
   }
 }
 
@@ -283,7 +283,7 @@ async function fetchUserSettingsOnce(): Promise<SettingsSyncFetchResult> {
       logForDiagnosticsNoPII('warn', 'settings_sync_fetch_invalid_format')
       return {
         success: false,
-        error: 'Invalid settings sync response format',
+        error: '设置同步响应格式无效',
       }
     }
 
@@ -299,13 +299,13 @@ async function fetchUserSettingsOnce(): Promise<SettingsSyncFetchResult> {
       case 'auth':
         return {
           success: false,
-          error: 'Not authorized for settings sync',
+          error: '无设置同步授权',
           skipRetry: true,
         }
       case 'timeout':
-        return { success: false, error: 'Settings sync request timeout' }
+        return { success: false, error: '设置同步请求超时' }
       case 'network':
-        return { success: false, error: 'Cannot connect to server' }
+        return { success: false, error: '无法连接到服务器' }
       default:
         return { success: false, error: message }
     }
@@ -386,7 +386,7 @@ async function uploadUserSettings(
     logForDiagnosticsNoPII('warn', 'settings_sync_upload_error')
     return {
       success: false,
-      error: error instanceof Error ? error.message : 'Unknown error',
+      error: error instanceof Error ? error.message : '未知错误',
     }
   }
 }

+ 3 - 3
src/services/teamMemorySync/index.ts

@@ -496,7 +496,7 @@ async function uploadTeamMemory(
       logForDebugging('team-memory-sync: conflict (412 Precondition Failed)', {
         level: 'info',
       })
-      return { success: false, conflict: true, error: 'ETag mismatch' }
+      return { success: false, conflict: true, error: 'ETag 不匹配' }
     }
 
     const responseChecksum = response.data?.checksum
@@ -787,7 +787,7 @@ export async function pullTeamMemory(
       success: false,
       filesWritten: 0,
       entryCount: 0,
-      error: 'OAuth not available',
+      error: 'OAuth 不可用',
     }
   }
 
@@ -897,7 +897,7 @@ export async function pushTeamMemory(
     return {
       success: false,
       filesUploaded: 0,
-      error: 'OAuth not available',
+      error: 'OAuth 不可用',
       errorType: 'no_oauth',
     }
   }

+ 1 - 1
src/services/voice.ts

@@ -52,7 +52,7 @@ function loadAudioNapi(): Promise<AudioNapi> {
       return mod
     } catch (error) {
       const message =
-        error instanceof Error ? error.message : 'unknown load error'
+        error instanceof Error ? error.message : '未知的加载错误'
       audioNapi = unavailableAudioNapi
       logForDebugging(
         `[voice] audio-capture-napi unavailable, falling back: ${message}`,

+ 1 - 1
src/tools/AgentTool/AgentTool.tsx

@@ -1346,7 +1346,7 @@ The agent is now running and will receive instructions via mailbox.`
       // immediately. Say so explicitly so the parent has something to react to.
       const contentOrMarker = data.content.length > 0 ? data.content : [{
         type: 'text' as const,
-        text: '(Subagent completed but returned no output.)'
+        text: '(子代理已完成但未返回输出。)'
       }];
       // One-shot built-ins (Explore, Plan) are never continued via SendMessage
       // — the agentId hint and <usage> block are dead weight (~135 chars ×

+ 7 - 7
src/tools/AgentTool/agentDisplay.ts

@@ -22,13 +22,13 @@ export type AgentSourceGroup = {
  * Both the CLI and interactive UI should use this to ensure consistent ordering.
  */
 export const AGENT_SOURCE_GROUPS: AgentSourceGroup[] = [
-  { label: 'User agents', source: 'userSettings' },
-  { label: 'Project agents', source: 'projectSettings' },
-  { label: 'Local agents', source: 'localSettings' },
-  { label: 'Managed agents', source: 'policySettings' },
-  { label: 'Plugin agents', source: 'plugin' },
-  { label: 'CLI arg agents', source: 'flagSettings' },
-  { label: 'Built-in agents', source: 'built-in' },
+  { label: '用户代理', source: 'userSettings' },
+  { label: '项目代理', source: 'projectSettings' },
+  { label: '本地代理', source: 'localSettings' },
+  { label: '托管代理', source: 'policySettings' },
+  { label: '插件代理', source: 'plugin' },
+  { label: '命令行参数代理', source: 'flagSettings' },
+  { label: '内置代理', source: 'built-in' },
 ]
 
 export type ResolvedAgent = AgentDefinition & {

+ 1 - 1
src/tools/AgentTool/agentToolUtils.ts

@@ -414,7 +414,7 @@ export async function classifyHandoffIfNeeded({
         content: [
           {
             type: 'text',
-            text: "Sub-agent has finished and is handing back control to the main agent. Review the sub-agent's work based on the block rules and let the main agent know if any file is dangerous (the main agent will see the reason).",
+            text: "\u5b50\u4ee3\u7406\u5df2\u5b8c\u6210\u5e76\u5c06\u63a7\u5236\u6743\u4ea4\u8fd8\u7ed9\u4e3b\u4ee3\u7406\u3002\u8bf7\u6839\u636e\u963b\u6b62\u89c4\u5219\u5ba1\u67e5\u5b50\u4ee3\u7406\u7684\u5de5\u4f5c\uff0c\u5982\u6709\u5371\u9669\u6587\u4ef6\u8bf7\u901a\u77e5\u4e3b\u4ee3\u7406\u3002",
           },
         ],
       },

+ 2 - 2
src/tools/BashTool/bashCommandHelpers.ts

@@ -191,7 +191,7 @@ export async function checkCommandOperatorPermissions(
       ? buildParsedCommandFromRoot(input.command, astRoot)
       : await ParsedCommand.parse(input.command)
   if (!parsed) {
-    return { behavior: 'passthrough', message: 'Failed to parse command' }
+    return { behavior: 'passthrough', message: '命令解析失败' }
   }
   return bashToolCheckCommandOperatorPermissions(
     input,
@@ -246,7 +246,7 @@ async function bashToolCheckCommandOperatorPermissions(
   if (pipeSegments.length <= 1) {
     return {
       behavior: 'passthrough',
-      message: 'No pipes found in command',
+      message: '命令中未找到管道',
     }
   }
 

+ 61 - 61
src/tools/BashTool/bashSecurity.ts

@@ -14,30 +14,30 @@ const HEREDOC_IN_SUBSTITUTION = /\$\(.*<</
 // Note: Backtick pattern is handled separately in validateDangerousPatterns
 // to distinguish between escaped and unescaped backticks
 const COMMAND_SUBSTITUTION_PATTERNS = [
-  { pattern: /<\(/, message: 'process substitution <()' },
-  { pattern: />\(/, message: 'process substitution >()' },
-  { pattern: /=\(/, message: 'Zsh process substitution =()' },
+  { pattern: /<\(/, message: '进程替换 <()' },
+  { pattern: />\(/, message: '进程替换 >()' },
+  { pattern: /=\(/, message: 'Zsh 进程替换 =()' },
   // Zsh EQUALS expansion: =cmd at word start expands to $(which cmd).
   // `=curl evil.com` → `/usr/bin/curl evil.com`, bypassing Bash(curl:*) deny
   // rules since the parser sees `=curl` as the base command, not `curl`.
   // Only matches word-initial = followed by a command-name char (not VAR=val).
   {
     pattern: /(?:^|[\s;&|])=[a-zA-Z_]/,
-    message: 'Zsh equals expansion (=cmd)',
+    message: 'Zsh 等号展开 (=cmd)',
   },
-  { pattern: /\$\(/, message: '$() command substitution' },
-  { pattern: /\$\{/, message: '${} parameter substitution' },
-  { pattern: /\$\[/, message: '$[] legacy arithmetic expansion' },
-  { pattern: /~\[/, message: 'Zsh-style parameter expansion' },
-  { pattern: /\(e:/, message: 'Zsh-style glob qualifiers' },
-  { pattern: /\(\+/, message: 'Zsh glob qualifier with command execution' },
+  { pattern: /\$\(/, message: '$() 命令替换' },
+  { pattern: /\$\{/, message: '${} 参数替换' },
+  { pattern: /\$\[/, message: '$[] 传统算术展开' },
+  { pattern: /~\[/, message: 'Zsh 风格的参数展开' },
+  { pattern: /\(e:/, message: 'Zsh 风格的 glob 限定符' },
+  { pattern: /\(\+/, message: '带命令执行的 Zsh glob 限定符' },
   {
     pattern: /\}\s*always\s*\{/,
-    message: 'Zsh always block (try/always construct)',
+    message: 'Zsh always 块(try/always 结构)',
   },
   // Defense in depth: Block PowerShell comment syntax even though we don't execute in PowerShell
   // Added as protection against future changes that might introduce PowerShell execution
-  { pattern: /<#/, message: 'PowerShell comment syntax' },
+  { pattern: /<#/, message: 'PowerShell 注释语法' },
 ]
 
 // Zsh-specific dangerous commands that can bypass security checks.
@@ -238,7 +238,7 @@ function validateEmpty(context: ValidationContext): PermissionResult {
       decisionReason: { type: 'other', reason: 'Empty command is safe' },
     }
   }
-  return { behavior: 'passthrough', message: 'Command is not empty' }
+  return { behavior: 'passthrough', message: '命令非空' }
 }
 
 function validateIncompleteCommands(
@@ -254,7 +254,7 @@ function validateIncompleteCommands(
     })
     return {
       behavior: 'ask',
-      message: 'Command appears to be an incomplete fragment (starts with tab)',
+      message: '命令看似不完整(以制表符开头)',
     }
   }
 
@@ -282,7 +282,7 @@ function validateIncompleteCommands(
     }
   }
 
-  return { behavior: 'passthrough', message: 'Command appears complete' }
+  return { behavior: 'passthrough', message: '命令看似完整' }
 }
 
 /**
@@ -588,7 +588,7 @@ function validateSafeCommandSubstitution(
   const { originalCommand } = context
 
   if (!HEREDOC_IN_SUBSTITUTION.test(originalCommand)) {
-    return { behavior: 'passthrough', message: 'No heredoc in substitution' }
+    return { behavior: 'passthrough', message: '替换中无 heredoc' }
   }
 
   if (isSafeHeredoc(originalCommand)) {
@@ -605,7 +605,7 @@ function validateSafeCommandSubstitution(
 
   return {
     behavior: 'passthrough',
-    message: 'Command substitution needs validation',
+    message: '命令替换需要验证',
   }
 }
 
@@ -613,7 +613,7 @@ function validateGitCommit(context: ValidationContext): PermissionResult {
   const { originalCommand, baseCommand } = context
 
   if (baseCommand !== 'git' || !/^git\s+commit\s+/.test(originalCommand)) {
-    return { behavior: 'passthrough', message: 'Not a git commit' }
+    return { behavior: 'passthrough', message: '非 git 提交' }
   }
 
   // SECURITY: Backslashes can cause our regex to mis-identify quote boundaries
@@ -622,7 +622,7 @@ function validateGitCommit(context: ValidationContext): PermissionResult {
   if (originalCommand.includes('\\')) {
     return {
       behavior: 'passthrough',
-      message: 'Git commit contains backslash, needs full validation',
+      message: 'Git 提交包含反斜杠,需完整验证',
     }
   }
 
@@ -655,7 +655,7 @@ function validateGitCommit(context: ValidationContext): PermissionResult {
       })
       return {
         behavior: 'ask',
-        message: 'Git commit message contains command substitution patterns',
+        message: 'Git 提交消息包含命令替换模式',
       }
     }
 
@@ -679,7 +679,7 @@ function validateGitCommit(context: ValidationContext): PermissionResult {
     if (remainder && /[;|&()`]|\$\(|\$\{/.test(remainder)) {
       return {
         behavior: 'passthrough',
-        message: 'Git commit remainder contains shell metacharacters',
+        message: 'Git 提交剩余部分包含 Shell 元字符',
       }
     }
     if (remainder) {
@@ -708,7 +708,7 @@ function validateGitCommit(context: ValidationContext): PermissionResult {
       if (/[<>]/.test(unquoted)) {
         return {
           behavior: 'passthrough',
-          message: 'Git commit remainder contains unquoted redirect operator',
+          message: 'Git 提交剩余部分包含未引号重定向符',
         }
       }
     }
@@ -722,7 +722,7 @@ function validateGitCommit(context: ValidationContext): PermissionResult {
       })
       return {
         behavior: 'ask',
-        message: 'Command contains quoted characters in flag names',
+        message: '命令在标志名中包含引号字符',
       }
     }
 
@@ -736,7 +736,7 @@ function validateGitCommit(context: ValidationContext): PermissionResult {
     }
   }
 
-  return { behavior: 'passthrough', message: 'Git commit needs validation' }
+  return { behavior: 'passthrough', message: 'Git 提交需要验证' }
 }
 
 function validateJqCommand(context: ValidationContext): PermissionResult {
@@ -777,7 +777,7 @@ function validateJqCommand(context: ValidationContext): PermissionResult {
     }
   }
 
-  return { behavior: 'passthrough', message: 'jq command is safe' }
+  return { behavior: 'passthrough', message: 'jq 命令安全' }
 }
 
 function validateShellMetacharacters(
@@ -817,7 +817,7 @@ function validateShellMetacharacters(
     return { behavior: 'ask', message }
   }
 
-  return { behavior: 'passthrough', message: 'No metacharacters' }
+  return { behavior: 'passthrough', message: '无元字符' }
 }
 
 function validateDangerousVariables(
@@ -840,7 +840,7 @@ function validateDangerousVariables(
     }
   }
 
-  return { behavior: 'passthrough', message: 'No dangerous variables' }
+  return { behavior: 'passthrough', message: '无危险变量' }
 }
 
 function validateDangerousPatterns(
@@ -853,7 +853,7 @@ function validateDangerousPatterns(
   if (hasUnescapedChar(unquotedContent, '`')) {
     return {
       behavior: 'ask',
-      message: 'Command contains backticks (`) for command substitution',
+      message: '命令包含反引号 (`) 用于命令替换',
     }
   }
 
@@ -869,7 +869,7 @@ function validateDangerousPatterns(
     }
   }
 
-  return { behavior: 'passthrough', message: 'No dangerous patterns' }
+  return { behavior: 'passthrough', message: '无危险模式' }
 }
 
 function validateRedirections(context: ValidationContext): PermissionResult {
@@ -899,7 +899,7 @@ function validateRedirections(context: ValidationContext): PermissionResult {
     }
   }
 
-  return { behavior: 'passthrough', message: 'No redirections' }
+  return { behavior: 'passthrough', message: '无重定向' }
 }
 
 function validateNewlines(context: ValidationContext): PermissionResult {
@@ -911,7 +911,7 @@ function validateNewlines(context: ValidationContext): PermissionResult {
 
   // Check for newlines in unquoted content
   if (!/[\n\r]/.test(fullyUnquotedPreStrip)) {
-    return { behavior: 'passthrough', message: 'No newlines' }
+    return { behavior: 'passthrough', message: '无换行符' }
   }
 
   // Flag any newline/CR followed by non-whitespace, EXCEPT backslash-newline
@@ -936,7 +936,7 @@ function validateNewlines(context: ValidationContext): PermissionResult {
 
   return {
     behavior: 'passthrough',
-    message: 'Newlines appear to be within data',
+    message: '换行符似乎在数据内',
   }
 }
 
@@ -972,7 +972,7 @@ function validateCarriageReturn(context: ValidationContext): PermissionResult {
   const { originalCommand } = context
 
   if (!originalCommand.includes('\r')) {
-    return { behavior: 'passthrough', message: 'No carriage return' }
+    return { behavior: 'passthrough', message: '无回车符' }
   }
 
   // Check if CR appears outside double quotes. CR outside DQ (including inside
@@ -1011,7 +1011,7 @@ function validateCarriageReturn(context: ValidationContext): PermissionResult {
     }
   }
 
-  return { behavior: 'passthrough', message: 'CR only inside double quotes' }
+  return { behavior: 'passthrough', message: '回车符仅在双引号内' }
 }
 
 function validateIFSInjection(context: ValidationContext): PermissionResult {
@@ -1032,7 +1032,7 @@ function validateIFSInjection(context: ValidationContext): PermissionResult {
     }
   }
 
-  return { behavior: 'passthrough', message: 'No IFS injection detected' }
+  return { behavior: 'passthrough', message: '未检测到 IFS 注入' }
 }
 
 // Additional hardening against reading environment variables via /proc filesystem.
@@ -1062,7 +1062,7 @@ function validateProcEnvironAccess(
 
   return {
     behavior: 'passthrough',
-    message: 'No /proc/environ access detected',
+    message: '未检测到 /proc/environ 访问',
   }
 }
 
@@ -1089,7 +1089,7 @@ function validateMalformedTokenInjection(
     // Parse failed - this is handled elsewhere (bashToolHasPermission checks this)
     return {
       behavior: 'passthrough',
-      message: 'Parse failed, handled elsewhere',
+      message: '解析失败,在别处处理',
     }
   }
 
@@ -1105,7 +1105,7 @@ function validateMalformedTokenInjection(
   )
 
   if (!hasCommandSeparator) {
-    return { behavior: 'passthrough', message: 'No command separators' }
+    return { behavior: 'passthrough', message: '无命令分隔符' }
   }
 
   // Check for malformed tokens (unbalanced delimiters)
@@ -1123,7 +1123,7 @@ function validateMalformedTokenInjection(
 
   return {
     behavior: 'passthrough',
-    message: 'No malformed token injection detected',
+    message: '未检测到恶意令牌注入',
   }
 }
 
@@ -1139,7 +1139,7 @@ function validateObfuscatedFlags(context: ValidationContext): PermissionResult {
   if (baseCommand === 'echo' && !hasShellOperators) {
     return {
       behavior: 'passthrough',
-      message: 'echo command is safe and has no dangerous flags',
+      message: 'echo 命令安全',
     }
   }
 
@@ -1159,7 +1159,7 @@ function validateObfuscatedFlags(context: ValidationContext): PermissionResult {
     })
     return {
       behavior: 'ask',
-      message: 'Command contains ANSI-C quoting which can hide characters',
+      message: '命令包含 ANSI-C 引号可能隐藏字符',
     }
   }
 
@@ -1172,7 +1172,7 @@ function validateObfuscatedFlags(context: ValidationContext): PermissionResult {
     })
     return {
       behavior: 'ask',
-      message: 'Command contains locale quoting which can hide characters',
+      message: '命令包含区域引号可能隐藏字符',
     }
   }
 
@@ -1200,7 +1200,7 @@ function validateObfuscatedFlags(context: ValidationContext): PermissionResult {
     })
     return {
       behavior: 'ask',
-      message: 'Command contains empty quotes before dash (potential bypass)',
+      message: '命令在破折号前包含空引号(可能绕过)',
     }
   }
 
@@ -1444,7 +1444,7 @@ function validateObfuscatedFlags(context: ValidationContext): PermissionResult {
         })
         return {
           behavior: 'ask',
-          message: 'Command contains quoted characters in flag names',
+          message: '命令在标志名中包含引号字符',
         }
       }
     }
@@ -1501,7 +1501,7 @@ function validateObfuscatedFlags(context: ValidationContext): PermissionResult {
         })
         return {
           behavior: 'ask',
-          message: 'Command contains quoted characters in flag names',
+          message: '命令在标志名中包含引号字符',
         }
       }
     }
@@ -1516,7 +1516,7 @@ function validateObfuscatedFlags(context: ValidationContext): PermissionResult {
     })
     return {
       behavior: 'ask',
-      message: 'Command contains quoted characters in flag names',
+      message: '命令在标志名中包含引号字符',
     }
   }
 
@@ -1529,11 +1529,11 @@ function validateObfuscatedFlags(context: ValidationContext): PermissionResult {
     })
     return {
       behavior: 'ask',
-      message: 'Command contains quoted characters in flag names',
+      message: '命令在标志名中包含引号字符',
     }
   }
 
-  return { behavior: 'passthrough', message: 'No obfuscated flags detected' }
+  return { behavior: 'passthrough', message: '未检测到混淆标志' }
 }
 
 /**
@@ -1596,7 +1596,7 @@ function validateBackslashEscapedWhitespace(
 
   return {
     behavior: 'passthrough',
-    message: 'No backslash-escaped whitespace',
+    message: '无反斜杠转义空格',
   }
 }
 
@@ -1700,7 +1700,7 @@ function validateBackslashEscapedOperators(
   // in the AST, then any \; is just an escaped character in a word argument
   // (e.g., `find . -exec cmd {} \;`). Skip the expensive regex check.
   if (context.treeSitter && !context.treeSitter.hasActualOperatorNodes) {
-    return { behavior: 'passthrough', message: 'No operator nodes in AST' }
+    return { behavior: 'passthrough', message: '无运算符 AST 节点' }
   }
 
   if (hasBackslashEscapedOperator(context.originalCommand)) {
@@ -1716,7 +1716,7 @@ function validateBackslashEscapedOperators(
 
   return {
     behavior: 'passthrough',
-    message: 'No backslash-escaped operators',
+    message: '无反斜杠转义运算符',
   }
 }
 
@@ -1887,7 +1887,7 @@ function validateBraceExpansion(context: ValidationContext): PermissionResult {
 
   return {
     behavior: 'passthrough',
-    message: 'No brace expansion detected',
+    message: '无大括号展开',
   }
 }
 
@@ -1913,7 +1913,7 @@ function validateUnicodeWhitespace(
         'Command contains Unicode whitespace characters that could cause parsing inconsistencies',
     }
   }
-  return { behavior: 'passthrough', message: 'No Unicode whitespace' }
+  return { behavior: 'passthrough', message: '无 Unicode 空格' }
 }
 
 function validateMidWordHash(context: ValidationContext): PermissionResult {
@@ -1958,7 +1958,7 @@ function validateMidWordHash(context: ValidationContext): PermissionResult {
         'Command contains mid-word # which is parsed differently by shell-quote vs bash',
     }
   }
-  return { behavior: 'passthrough', message: 'No mid-word hash' }
+  return { behavior: 'passthrough', message: '词中无井号' }
 }
 
 /**
@@ -1998,7 +1998,7 @@ function validateCommentQuoteDesync(
   if (context.treeSitter) {
     return {
       behavior: 'passthrough',
-      message: 'Tree-sitter quote context is authoritative',
+      message: 'Tree-sitter 引号上下文是权威的',
     }
   }
 
@@ -2070,7 +2070,7 @@ function validateCommentQuoteDesync(
     }
   }
 
-  return { behavior: 'passthrough', message: 'No comment quote desync' }
+  return { behavior: 'passthrough', message: '注释引号同步' }
 }
 
 /**
@@ -2113,7 +2113,7 @@ function validateQuotedNewline(context: ValidationContext): PermissionResult {
   // stripCommentLines only strips lines where trim().startsWith('#'), so
   // no # means no possible trigger.
   if (!originalCommand.includes('\n') || !originalCommand.includes('#')) {
-    return { behavior: 'passthrough', message: 'No newline or no hash' }
+    return { behavior: 'passthrough', message: '无换行或无井号' }
   }
 
   // Track quote state. Mirrors extractQuotedContent / validateCommentQuoteDesync:
@@ -2171,7 +2171,7 @@ function validateQuotedNewline(context: ValidationContext): PermissionResult {
     }
   }
 
-  return { behavior: 'passthrough', message: 'No quoted newline-hash pattern' }
+  return { behavior: 'passthrough', message: '无引号换行-井号模式' }
 }
 
 /**
@@ -2237,7 +2237,7 @@ function validateZshDangerousCommands(
 
   return {
     behavior: 'passthrough',
-    message: 'No Zsh dangerous commands',
+    message: '无 Zsh 危险命令',
   }
 }
 
@@ -2408,7 +2408,7 @@ export function bashCommandIsSafe_DEPRECATED(
 
   return {
     behavior: 'passthrough',
-    message: 'Command passed all security checks',
+    message: '命令通过所有安全检查',
   }
 }
 
@@ -2587,6 +2587,6 @@ export async function bashCommandIsSafeAsync_DEPRECATED(
 
   return {
     behavior: 'passthrough',
-    message: 'Command passed all security checks',
+    message: '命令通过所有安全检查',
   }
 }

+ 4 - 4
src/tools/BashTool/modeValidation.ts

@@ -30,7 +30,7 @@ function validateCommandForMode(
   if (!baseCmd) {
     return {
       behavior: 'passthrough',
-      message: 'Base command not found',
+      message: '基础命令未找到',
     }
   }
 
@@ -77,7 +77,7 @@ export function checkPermissionMode(
   if (toolPermissionContext.mode === 'bypassPermissions') {
     return {
       behavior: 'passthrough',
-      message: 'Bypass mode is handled in main permission flow',
+      message: '绕过模式在主权限流程中处理',
     }
   }
 
@@ -85,7 +85,7 @@ export function checkPermissionMode(
   if (toolPermissionContext.mode === 'dontAsk') {
     return {
       behavior: 'passthrough',
-      message: 'DontAsk mode is handled in main permission flow',
+      message: '不询问模式在主权限流程中处理',
     }
   }
 
@@ -104,7 +104,7 @@ export function checkPermissionMode(
   // No mode-specific handling needed
   return {
     behavior: 'passthrough',
-    message: 'No mode-specific validation required',
+    message: '无需模式特异性验证',
   }
 }
 

+ 6 - 6
src/tools/BashTool/pathValidation.ts

@@ -849,7 +849,7 @@ function validateSinglePathCommand(
   if (extractedArgs.length === 0) {
     return {
       behavior: 'passthrough',
-      message: 'Empty command - no paths to validate',
+      message: '空命令 - 无路径可验证',
     }
   }
 
@@ -895,7 +895,7 @@ function validateSinglePathCommandArgv(
   if (argv.length === 0) {
     return {
       behavior: 'passthrough',
-      message: 'Empty command - no paths to validate',
+      message: '空命令 - 无路径可验证',
     }
   }
   const [baseCmd, ...args] = argv
@@ -998,7 +998,7 @@ function validateOutputRedirections(
 
   return {
     behavior: 'passthrough',
-    message: 'No unsafe redirections found',
+    message: '未发现不安全重定向',
   }
 }
 
@@ -1052,10 +1052,10 @@ export function checkPathConstraints(
   if (hasDangerousRedirection) {
     return {
       behavior: 'ask',
-      message: 'Shell expansion syntax in paths requires manual approval',
+      message: '路径中的 Shell 展开语法需手动批准',
       decisionReason: {
         type: 'other',
-        reason: 'Shell expansion syntax in paths requires manual approval',
+        reason: '路径中的 Shell 展开语法需手动批准',
       },
     }
   }
@@ -1104,7 +1104,7 @@ export function checkPathConstraints(
   // Always return passthrough to let other permission checks handle the command
   return {
     behavior: 'passthrough',
-    message: 'All path commands validated successfully',
+    message: '所有路径命令验证成功',
   }
 }
 

+ 3 - 3
src/tools/BashTool/readOnlyValidation.ts

@@ -1884,7 +1884,7 @@ export function checkReadOnlyConstraints(
   if (!result.success) {
     return {
       behavior: 'passthrough',
-      message: 'Command cannot be parsed, requires further permission checks',
+      message: '命令无法解析,需进一步权限检查',
     }
   }
 
@@ -1894,7 +1894,7 @@ export function checkReadOnlyConstraints(
   if (bashCommandIsSafe_DEPRECATED(command).behavior !== 'passthrough') {
     return {
       behavior: 'passthrough',
-      message: 'Command is not read-only, requires further permission checks',
+      message: '命令非只读,需进一步权限检查',
     }
   }
 
@@ -1985,6 +1985,6 @@ export function checkReadOnlyConstraints(
   // If not read-only, return passthrough to let other permission checks handle it
   return {
     behavior: 'passthrough',
-    message: 'Command is not read-only, requires further permission checks',
+    message: '命令非只读,需进一步权限检查',
   }
 }

+ 2 - 2
src/tools/BashTool/sedValidation.ts

@@ -458,7 +458,7 @@ export function extractSedExpressions(command: string): string[] {
   } catch (error) {
     // If shell-quote parsing fails, treat the sed command as unsafe
     throw new Error(
-      `Failed to parse sed command: ${error instanceof Error ? error.message : 'Unknown error'}`,
+      `Failed to parse sed command: ${error instanceof Error ? error.message : '未知错误'}`,
     )
   }
 
@@ -679,6 +679,6 @@ export function checkSedConstraints(
   // No dangerous sed commands found (or no sed commands at all)
   return {
     behavior: 'passthrough',
-    message: 'No dangerous sed operations detected',
+    message: '未检测到危险的 sed 操作',
   }
 }

+ 1 - 1
src/tools/ConfigTool/ConfigTool.ts

@@ -319,7 +319,7 @@ export const ConfigTool = buildTool({
               success: false,
               operation: 'set',
               setting,
-              error: 'Invalid setting path',
+              error: '设置路径无效',
             },
           }
         }

+ 1 - 1
src/tools/ExitPlanModeTool/ExitPlanModeV2Tool.ts

@@ -233,7 +233,7 @@ export const ExitPlanModeV2Tool: Tool<InputSchema, Output> = buildTool({
     // For non-teammates, require user confirmation to exit plan mode
     return {
       behavior: 'ask' as const,
-      message: 'Exit plan mode?',
+      message: '退出规划模式?',
       updatedInput: input,
     }
   },

+ 1 - 1
src/tools/FileEditTool/FileEditTool.ts

@@ -252,7 +252,7 @@ export const FileEditTool = buildTool({
         return {
           result: false,
           behavior: 'ask',
-          message: 'Cannot create new file - file already exists.',
+          message: '无法创建新文件 - 文件已存在。',
           errorCode: 3,
         }
       }

+ 1 - 1
src/tools/MCPTool/MCPTool.ts

@@ -56,7 +56,7 @@ export const MCPTool = buildTool({
   async checkPermissions(): Promise<PermissionResult> {
     return {
       behavior: 'passthrough',
-      message: 'MCPTool requires permission.',
+      message: 'MCP 工具需要权限。',
     }
   },
   renderToolUseMessage,

+ 7 - 7
src/tools/NotebookEditTool/NotebookEditTool.ts

@@ -202,7 +202,7 @@ export const NotebookEditTool = buildTool({
     ) {
       return {
         result: false,
-        message: 'Edit mode must be replace, insert, or delete.',
+        message: '编辑模式必须是 replace、insert 或 delete。',
         errorCode: 4,
       }
     }
@@ -210,7 +210,7 @@ export const NotebookEditTool = buildTool({
     if (edit_mode === 'insert' && !cell_type) {
       return {
         result: false,
-        message: 'Cell type is required when using edit_mode=insert.',
+        message: '使用 edit_mode=insert 时需要指定单元格类型。',
         errorCode: 5,
       }
     }
@@ -243,7 +243,7 @@ export const NotebookEditTool = buildTool({
       if (isENOENT(e)) {
         return {
           result: false,
-          message: 'Notebook file does not exist.',
+          message: 'Notebook 文件不存在。',
           errorCode: 1,
         }
       }
@@ -253,7 +253,7 @@ export const NotebookEditTool = buildTool({
     if (!notebook) {
       return {
         result: false,
-        message: 'Notebook is not valid JSON.',
+        message: 'Notebook 不是有效的 JSON。',
         errorCode: 6,
       }
     }
@@ -261,7 +261,7 @@ export const NotebookEditTool = buildTool({
       if (edit_mode !== 'insert') {
         return {
           result: false,
-          message: 'Cell ID must be specified when not inserting a new cell.',
+          message: '不插入新单元格时必须指定 Cell ID。',
           errorCode: 7,
         }
       }
@@ -338,7 +338,7 @@ export const NotebookEditTool = buildTool({
             cell_type: cell_type ?? 'code',
             language: 'python',
             edit_mode: 'replace',
-            error: 'Notebook is not valid JSON.',
+            error: 'Notebook 不是有效的 JSON。',
             cell_id,
             notebook_path: fullPath,
             original_file: '',
@@ -476,7 +476,7 @@ export const NotebookEditTool = buildTool({
         cell_type: cell_type ?? 'code',
         language: 'python',
         edit_mode: 'replace',
-        error: 'Unknown error occurred while editing notebook',
+        error: '编辑 Notebook 时发生未知错误',
         cell_id,
         notebook_path: fullPath,
         original_file: '',

+ 4 - 4
src/tools/PowerShellTool/modeValidation.ts

@@ -141,14 +141,14 @@ export function checkPermissionMode(
   ) {
     return {
       behavior: 'passthrough',
-      message: 'Mode is handled in main permission flow',
+      message: '模式在主权限流程中处理',
     }
   }
 
   if (toolPermissionContext.mode !== 'acceptEdits') {
     return {
       behavior: 'passthrough',
-      message: 'No mode-specific validation required',
+      message: '无需模式特异性验证',
     }
   }
 
@@ -156,7 +156,7 @@ export function checkPermissionMode(
   if (!parsed.valid) {
     return {
       behavior: 'passthrough',
-      message: 'Cannot validate mode for unparsed command',
+      message: '无法验证未解析命令的模式',
     }
   }
 
@@ -185,7 +185,7 @@ export function checkPermissionMode(
   if (segments.length === 0) {
     return {
       behavior: 'passthrough',
-      message: 'No commands found to validate for acceptEdits mode',
+      message: 'acceptEdits 模式下未找到要验证的命令',
     }
   }
 

+ 3 - 3
src/tools/PowerShellTool/pathValidation.ts

@@ -1534,7 +1534,7 @@ export function checkPathConstraints(
   if (!parsed.valid) {
     return {
       behavior: 'passthrough',
-      message: 'Cannot validate paths for unparsed command',
+      message: '无法验证未解析命令的路径',
     }
   }
 
@@ -1561,7 +1561,7 @@ export function checkPathConstraints(
   return (
     firstAsk ?? {
       behavior: 'passthrough',
-      message: 'All path constraints validated successfully',
+      message: '所有路径约束验证成功',
     }
   )
 }
@@ -2043,7 +2043,7 @@ function checkPathConstraintsForStatement(
   return (
     firstAsk ?? {
       behavior: 'passthrough',
-      message: 'All path constraints validated successfully',
+      message: '所有路径约束验证成功',
     }
   )
 }

+ 19 - 19
src/tools/PowerShellTool/powershellSecurity.ts

@@ -171,7 +171,7 @@ function checkEncodedCommand(
       if (psExeHasParamAbbreviation(cmd, '-encodedcommand', '-e')) {
         return {
           behavior: 'ask',
-          message: 'Command uses encoded parameters which obscure intent',
+          message: '命令使用编码参数掩盖意图',
         }
       }
     }
@@ -245,7 +245,7 @@ function checkDownloadCradles(
     if (hasDownloader && hasIex) {
       return {
         behavior: 'ask',
-        message: 'Command downloads and executes remote code',
+        message: '命令下载并执行远程代码',
       }
     }
   }
@@ -256,7 +256,7 @@ function checkDownloadCradles(
   if (all.some(c => isDownloader(c.name)) && all.some(c => isIex(c.name))) {
     return {
       behavior: 'ask',
-      message: 'Command downloads and executes remote code',
+      message: '命令下载并执行远程代码',
     }
   }
 
@@ -282,7 +282,7 @@ function checkDownloadUtilities(
     if (lower === 'start-bitstransfer') {
       return {
         behavior: 'ask',
-        message: 'Command downloads files via BITS transfer',
+        message: '命令通过 BITS 传输下载文件',
       }
     }
     // certutil / certutil.exe — only when -urlcache is present. certutil has
@@ -297,7 +297,7 @@ function checkDownloadUtilities(
       if (hasUrlcache) {
         return {
           behavior: 'ask',
-          message: 'Command uses certutil to download from a URL',
+          message: '命令使用 certutil 从 URL 下载',
         }
       }
     }
@@ -306,7 +306,7 @@ function checkDownloadUtilities(
       if (cmd.args.some(a => a.toLowerCase() === '/transfer')) {
         return {
           behavior: 'ask',
-          message: 'Command downloads files via BITS transfer',
+          message: '命令通过 BITS 传输下载文件',
         }
       }
     }
@@ -324,7 +324,7 @@ function checkAddType(
   if (hasCommandNamed(parsed, 'Add-Type')) {
     return {
       behavior: 'ask',
-      message: 'Command compiles and loads .NET code',
+      message: '命令编译并加载 .NET 代码',
     }
   }
   return { behavior: 'passthrough' }
@@ -564,7 +564,7 @@ function checkStartProcess(
     ) {
       return {
         behavior: 'ask',
-        message: 'Command requests elevated privileges',
+        message: '命令请求提升的权限',
       }
     }
     // Colon syntax — two layers:
@@ -588,7 +588,7 @@ function checkStartProcess(
           if (child.text.replace(/['"`\s]/g, '').toLowerCase() === 'runas') {
             return {
               behavior: 'ask',
-              message: 'Command requests elevated privileges',
+              message: '命令请求提升的权限',
             }
           }
         }
@@ -605,7 +605,7 @@ function checkStartProcess(
     ) {
       return {
         behavior: 'ask',
-        message: 'Command requests elevated privileges',
+        message: '命令请求提升的权限',
       }
     }
     // Vector 2: Start-Process targeting a PowerShell executable.
@@ -704,7 +704,7 @@ function checkScriptBlockInjection(
 
   return {
     behavior: 'ask',
-    message: 'Command contains script block that may execute arbitrary code',
+    message: '命令包含可能执行任意代码的脚本块',
   }
 }
 
@@ -717,7 +717,7 @@ function checkSubExpressions(
   if (deriveSecurityFlags(parsed).hasSubExpressions) {
     return {
       behavior: 'ask',
-      message: 'Command contains subexpressions $()',
+      message: '命令包含子表达式 $()',
     }
   }
   return { behavior: 'passthrough' }
@@ -734,7 +734,7 @@ function checkExpandableStrings(
   if (deriveSecurityFlags(parsed).hasExpandableStrings) {
     return {
       behavior: 'ask',
-      message: 'Command contains expandable strings with embedded expressions',
+      message: '命令包含嵌入表达式的可扩展字符串',
     }
   }
   return { behavior: 'passthrough' }
@@ -749,7 +749,7 @@ function checkSplatting(
   if (deriveSecurityFlags(parsed).hasSplatting) {
     return {
       behavior: 'ask',
-      message: 'Command uses splatting (@variable)',
+      message: '命令使用 splatting (@variable)',
     }
   }
   return { behavior: 'passthrough' }
@@ -764,7 +764,7 @@ function checkStopParsing(
   if (deriveSecurityFlags(parsed).hasStopParsing) {
     return {
       behavior: 'ask',
-      message: 'Command uses stop-parsing token (--%)',
+      message: '命令使用停止解析令牌 (--%)',
     }
   }
   return { behavior: 'passthrough' }
@@ -779,7 +779,7 @@ function checkMemberInvocations(
   if (deriveSecurityFlags(parsed).hasMemberInvocations) {
     return {
       behavior: 'ask',
-      message: 'Command invokes .NET methods',
+      message: '命令调用 .NET 方法',
     }
   }
   return { behavior: 'passthrough' }
@@ -917,7 +917,7 @@ function checkEnvVarManipulation(
     if (ENV_WRITE_CMDLETS.has(cmd.name.toLowerCase())) {
       return {
         behavior: 'ask',
-        message: 'Command modifies environment variables',
+        message: '命令修改环境变量',
       }
     }
   }
@@ -925,7 +925,7 @@ function checkEnvVarManipulation(
   if (deriveSecurityFlags(parsed).hasAssignments && envVars.length > 0) {
     return {
       behavior: 'ask',
-      message: 'Command modifies environment variables',
+      message: '命令修改环境变量',
     }
   }
   return { behavior: 'passthrough' }
@@ -1047,7 +1047,7 @@ export function powershellCommandIsSafe(
   if (!parsed.valid) {
     return {
       behavior: 'ask',
-      message: 'Could not parse command for security analysis',
+      message: '无法解析命令以进行安全分析',
     }
   }
 

+ 6 - 6
src/tools/SendMessageTool/SendMessageTool.ts

@@ -229,7 +229,7 @@ async function handleBroadcast(
     return {
       data: {
         success: true,
-        message: 'No teammates to broadcast to (you are the only team member)',
+        message: '无协作者可广播(你是唯一成员)',
         recipients: [],
       },
     }
@@ -605,7 +605,7 @@ export const SendMessageTool: Tool<InputSchema, SendMessageToolOutput> =
       if (input.to.trim().length === 0) {
         return {
           result: false,
-          message: 'to must not be empty',
+          message: 'to 不能为空',
           errorCode: 9,
         }
       }
@@ -616,7 +616,7 @@ export const SendMessageTool: Tool<InputSchema, SendMessageToolOutput> =
       ) {
         return {
           result: false,
-          message: 'address target must not be empty',
+          message: '地址目标不能为空',
           errorCode: 9,
         }
       }
@@ -668,7 +668,7 @@ export const SendMessageTool: Tool<InputSchema, SendMessageToolOutput> =
         if (!input.summary || input.summary.trim().length === 0) {
           return {
             result: false,
-            message: 'summary is required when message is a string',
+            message: '消息为字符串时必须提供 summary',
             errorCode: 9,
           }
         }
@@ -678,7 +678,7 @@ export const SendMessageTool: Tool<InputSchema, SendMessageToolOutput> =
       if (input.to === '*') {
         return {
           result: false,
-          message: 'structured messages cannot be broadcast (to: "*")',
+          message: '结构化消息不能广播(to: "*")',
           errorCode: 9,
         }
       }
@@ -709,7 +709,7 @@ export const SendMessageTool: Tool<InputSchema, SendMessageToolOutput> =
       ) {
         return {
           result: false,
-          message: 'reason is required when rejecting a shutdown request',
+          message: '拒绝关闭请求时必须提供原因',
           errorCode: 9,
         }
       }

+ 1 - 1
src/tools/TaskStopTool/TaskStopTool.ts

@@ -63,7 +63,7 @@ export const TaskStopTool = buildTool({
     if (!id) {
       return {
         result: false,
-        message: 'Missing required parameter: task_id',
+        message: '缺少必需参数:task_id',
         errorCode: 1,
       }
     }

+ 2 - 2
src/tools/TaskUpdateTool/TaskUpdateTool.ts

@@ -150,7 +150,7 @@ export const TaskUpdateTool = buildTool({
           success: false,
           taskId,
           updatedFields: [],
-          error: 'Task not found',
+          error: '任务未找到',
         },
       }
     }
@@ -372,7 +372,7 @@ export const TaskUpdateTool = buildTool({
     } = content as Output
     if (!success) {
       // Return as non-error so it doesn't trigger sibling tool cancellation
-      // in StreamingToolExecutor. "Task not found" is a benign condition
+      // in StreamingToolExecutor. "任务未找到" is a benign condition
       // (e.g., task list already cleaned up) that the model can handle.
       return {
         tool_use_id: toolUseID,

+ 1 - 1
src/tools/TeamCreateTool/TeamCreateTool.ts

@@ -97,7 +97,7 @@ export const TeamCreateTool: Tool<InputSchema, Output> = buildTool({
     if (!input.team_name || input.team_name.trim().length === 0) {
       return {
         result: false,
-        message: 'team_name is required for TeamCreate',
+        message: 'TeamCreate 需要 team_name',
         errorCode: 9,
       }
     }

+ 2 - 2
src/tools/WebSearchTool/WebSearchTool.ts

@@ -209,7 +209,7 @@ export const WebSearchTool = buildTool({
   async checkPermissions(_input): Promise<PermissionResult> {
     return {
       behavior: 'passthrough',
-      message: 'WebSearchTool requires permission.',
+      message: '网页搜索工具需要权限。',
       suggestions: [
         {
           type: 'addRules',
@@ -237,7 +237,7 @@ export const WebSearchTool = buildTool({
     if (!query.length) {
       return {
         result: false,
-        message: 'Error: Missing query',
+        message: '错误:缺少查询',
         errorCode: 1,
       }
     }

+ 1 - 1
src/utils/authFileDescriptor.ts

@@ -174,7 +174,7 @@ export function getOAuthTokenFromFileDescriptor(): string | null {
   return getCredentialFromFd({
     envVar: 'CLAUDE_CODE_OAUTH_TOKEN_FILE_DESCRIPTOR',
     wellKnownPath: CCR_OAUTH_TOKEN_PATH,
-    label: 'OAuth token',
+    label: 'OAuth 令牌',
     getCached: getOauthTokenFromFd,
     setCached: setOauthTokenFromFd,
   })

+ 2 - 2
src/utils/bash/shellQuote.ts

@@ -39,7 +39,7 @@ export function tryParseShellCommand(
     }
     return {
       success: false,
-      error: error instanceof Error ? error.message : 'Unknown parse error',
+      error: error instanceof Error ? error.message : '未知解析错误',
     }
   }
 }
@@ -89,7 +89,7 @@ export function tryQuoteShellArgs(args: unknown[]): ShellQuoteResult {
     }
     return {
       success: false,
-      error: error instanceof Error ? error.message : 'Unknown quote error',
+      error: error instanceof Error ? error.message : '未知引号错误',
     }
   }
 }

+ 2 - 2
src/utils/bash/specs/alias.ts

@@ -2,10 +2,10 @@ import type { CommandSpec } from '../registry.js'
 
 const alias: CommandSpec = {
   name: 'alias',
-  description: 'Create or list command aliases',
+  description: '创建或列出命令别名',
   args: {
     name: 'definition',
-    description: 'Alias definition in the form name=value',
+    description: '别名定义,格式为 name=value',
     isOptional: true,
     isVariadic: true,
   },

+ 2 - 2
src/utils/bash/specs/nohup.ts

@@ -2,10 +2,10 @@ import type { CommandSpec } from '../registry.js'
 
 const nohup: CommandSpec = {
   name: 'nohup',
-  description: 'Run a command immune to hangups',
+  description: '运行不受挂断影响的命令',
   args: {
     name: 'command',
-    description: 'Command to run with nohup',
+    description: '用 nohup 运行的命令',
     isCommand: true,
   },
 }

+ 22 - 22
src/utils/bash/specs/pyright.ts

@@ -2,82 +2,82 @@ import type { CommandSpec } from '../registry.js'
 
 export default {
   name: 'pyright',
-  description: 'Type checker for Python',
+  description: 'Python 类型检查器',
   options: [
-    { name: ['--help', '-h'], description: 'Show help message' },
-    { name: '--version', description: 'Print pyright version and exit' },
+    { name: ['--help', '-h'], description: '显示帮助信息' },
+    { name: '--version', description: '打印 pyright 版本并退出' },
     {
       name: ['--watch', '-w'],
-      description: 'Continue to run and watch for changes',
+      description: '持续运行并监视更改',
     },
     {
       name: ['--project', '-p'],
-      description: 'Use the configuration file at this location',
+      description: '使用此位置的配置文件',
       args: { name: 'FILE OR DIRECTORY' },
     },
-    { name: '-', description: 'Read file or directory list from stdin' },
+    { name: '-', description: '从 stdin 读取文件或目录列表' },
     {
       name: '--createstub',
-      description: 'Create type stub file(s) for import',
+      description: '为导入创建类型存根文件',
       args: { name: 'IMPORT' },
     },
     {
       name: ['--typeshedpath', '-t'],
-      description: 'Use typeshed type stubs at this location',
+      description: '使用此位置的 typeshed 类型存根',
       args: { name: 'DIRECTORY' },
     },
     {
       name: '--verifytypes',
-      description: 'Verify completeness of types in py.typed package',
+      description: '验证 py.typed 包中类型的完整性',
       args: { name: 'IMPORT' },
     },
     {
       name: '--ignoreexternal',
-      description: 'Ignore external imports for --verifytypes',
+      description: '忽略 --verifytypes 的外部导入',
     },
     {
       name: '--pythonpath',
-      description: 'Path to the Python interpreter',
+      description: 'Python 解释器路径',
       args: { name: 'FILE' },
     },
     {
       name: '--pythonplatform',
-      description: 'Analyze for platform',
+      description: '分析平台',
       args: { name: 'PLATFORM' },
     },
     {
       name: '--pythonversion',
-      description: 'Analyze for Python version',
+      description: '分析 Python 版本',
       args: { name: 'VERSION' },
     },
     {
       name: ['--venvpath', '-v'],
-      description: 'Directory that contains virtual environments',
+      description: '包含虚拟环境的目录',
       args: { name: 'DIRECTORY' },
     },
-    { name: '--outputjson', description: 'Output results in JSON format' },
-    { name: '--verbose', description: 'Emit verbose diagnostics' },
-    { name: '--stats', description: 'Print detailed performance stats' },
+    { name: '--outputjson', description: '以 JSON 格式输出结果' },
+    { name: '--verbose', description: '输出详细诊断信息' },
+    { name: '--stats', description: '打印详细性能统计' },
     {
       name: '--dependencies',
-      description: 'Emit import dependency information',
+      description: '输出导入依赖信息',
     },
     {
       name: '--level',
-      description: 'Minimum diagnostic level',
+      description: '最低诊断级别',
       args: { name: 'LEVEL' },
     },
     {
       name: '--skipunannotated',
-      description: 'Skip type analysis of unannotated functions',
+      description: '跳过未注解函数的类型分析',
     },
     {
       name: '--warnings',
-      description: 'Use exit code of 1 if warnings are reported',
+      description: '有警告时使用退出码 1',
     },
     {
       name: '--threads',
-      description: 'Use up to N threads to parallelize type checking',
+      description: '使用最多 N 个线程并行化类型检查',
       args: { name: 'N', isOptional: true },
     },
   ],

+ 2 - 2
src/utils/bash/specs/sleep.ts

@@ -2,10 +2,10 @@ import type { CommandSpec } from '../registry.js'
 
 const sleep: CommandSpec = {
   name: 'sleep',
-  description: 'Delay for a specified amount of time',
+  description: '延迟指定时间',
   args: {
     name: 'duration',
-    description: 'Duration to sleep (seconds or with suffix like 5s, 2m, 1h)',
+    description: '睡眠时长(秒或带后缀如 5s、2m、1h)',
     isOptional: false,
   },
 }

+ 6 - 6
src/utils/bash/specs/srun.ts

@@ -2,28 +2,28 @@ import type { CommandSpec } from '../registry.js'
 
 const srun: CommandSpec = {
   name: 'srun',
-  description: 'Run a command on SLURM cluster nodes',
+  description: '在 SLURM 集群节点上运行命令',
   options: [
     {
       name: ['-n', '--ntasks'],
-      description: 'Number of tasks',
+      description: '任务数量',
       args: {
         name: 'count',
-        description: 'Number of tasks to run',
+        description: '要运行的任务数量',
       },
     },
     {
       name: ['-N', '--nodes'],
-      description: 'Number of nodes',
+      description: '节点数量',
       args: {
         name: 'count',
-        description: 'Number of nodes to allocate',
+        description: '要分配的节点数量',
       },
     },
   ],
   args: {
     name: 'command',
-    description: 'Command to run on the cluster',
+    description: '在集群上运行的命令',
     isCommand: true,
   },
 }

+ 2 - 2
src/utils/bash/specs/time.ts

@@ -2,10 +2,10 @@ import type { CommandSpec } from '../registry.js'
 
 const time: CommandSpec = {
   name: 'time',
-  description: 'Time a command',
+  description: '为命令计时',
   args: {
     name: 'command',
-    description: 'Command to time',
+    description: '要计时的命令',
     isCommand: true,
   },
 }

+ 3 - 3
src/utils/bash/specs/timeout.ts

@@ -2,16 +2,16 @@ import type { CommandSpec } from '../registry.js'
 
 const timeout: CommandSpec = {
   name: 'timeout',
-  description: 'Run a command with a time limit',
+  description: '在时间限制内运行命令',
   args: [
     {
       name: 'duration',
-      description: 'Duration to wait before timing out (e.g., 10, 5s, 2m)',
+      description: '超时前等待时长(如 10、5s、2m)',
       isOptional: false,
     },
     {
       name: 'command',
-      description: 'Command to run',
+      description: '要运行的命令',
       isCommand: true,
     },
   ],

+ 2 - 2
src/utils/claudeInChrome/chromeNativeHost.ts

@@ -251,7 +251,7 @@ class ChromeNativeHost {
       sendChromeMessage(
         jsonStringify({
           type: 'error',
-          error: 'Invalid message format',
+          error: '消息格式无效',
         }),
       )
       return
@@ -262,7 +262,7 @@ class ChromeNativeHost {
       sendChromeMessage(
         jsonStringify({
           type: 'error',
-          error: 'Invalid message format',
+          error: '消息格式无效',
         }),
       )
       return

+ 1 - 1
src/utils/claudeInChrome/setup.ts

@@ -198,7 +198,7 @@ export async function installChromeNativeHostManifest(
 
   const manifest = {
     name: NATIVE_HOST_IDENTIFIER,
-    description: 'Claude Code Browser Extension Native Host',
+    description: 'Claude Code 浏览器扩展原生宿主',
     path: manifestBinaryPath,
     type: 'stdio',
     allowed_origins: [

+ 1 - 1
src/utils/computerUse/cleanup.ts

@@ -79,7 +79,7 @@ export async function cleanupComputerUseAfterTurn(
 
   if (await releaseComputerUseLock()) {
     ctx.sendOSNotification?.({
-      message: 'Claude is done using your computer',
+      message: 'Claude 已完成操作',
       notificationType: 'computer_use_exit',
     })
   }

+ 1 - 1
src/utils/desktopDeepLink.ts

@@ -227,7 +227,7 @@ export async function openCurrentSessionInDesktop(): Promise<{
   if (!opened) {
     return {
       success: false,
-      error: 'Failed to open Claude Desktop. Please try opening it manually.',
+      error: '无法打开 Claude Desktop,请手动打开。',
       deepLinkUrl,
     }
   }

+ 1 - 1
src/utils/effort.ts

@@ -259,7 +259,7 @@ export type OpusDefaultEffortConfig = {
 
 const OPUS_DEFAULT_EFFORT_CONFIG_DEFAULT: OpusDefaultEffortConfig = {
   enabled: true,
-  dialogTitle: 'We recommend medium effort for Opus',
+  dialogTitle: '建议 Opus 使用中等强度',
   dialogDescription:
     'Effort determines how long Claude thinks for when completing your task. We recommend medium effort for most tasks to balance speed and intelligence and maximize rate limits. Use ultrathink to trigger high effort when needed.',
 }

+ 4 - 4
src/utils/hooks/hookHelpers.ts

@@ -15,10 +15,10 @@ import { addFunctionHook } from './sessionHooks.js'
  */
 export const hookResponseSchema = lazySchema(() =>
   z.object({
-    ok: z.boolean().describe('Whether the condition was met'),
+    ok: z.boolean().describe('条件是否满足'),
     reason: z
       .string()
-      .describe('Reason, if the condition was not met')
+      .describe('条件未满足的原因')
       .optional(),
   }),
 )
@@ -47,11 +47,11 @@ export function createStructuredOutputTool(): Tool {
       properties: {
         ok: {
           type: 'boolean',
-          description: 'Whether the condition was met',
+          description: '条件是否满足',
         },
         reason: {
           type: 'string',
-          description: 'Reason, if the condition was not met',
+          description: '条件未满足的原因',
         },
       },
       required: ['ok'],

+ 2 - 2
src/utils/mcp/dateTimeParser.ts

@@ -86,7 +86,7 @@ Parse the user's input into ISO 8601 format. Return ONLY the formatted string, o
     if (!parsedText || parsedText === 'INVALID') {
       return {
         success: false,
-        error: 'Unable to parse date/time from input',
+        error: '无法从输入中解析日期/时间',
       }
     }
 
@@ -94,7 +94,7 @@ Parse the user's input into ISO 8601 format. Return ONLY the formatted string, o
     if (!/^\d{4}/.test(parsedText)) {
       return {
         success: false,
-        error: 'Unable to parse date/time from input',
+        error: '无法从输入中解析日期/时间',
       }
     }
 

+ 3 - 3
src/utils/mcp/elicitationValidation.ts

@@ -20,7 +20,7 @@ export type ValidationResult = {
 
 const STRING_FORMATS = {
   email: {
-    description: 'email address',
+    description: '邮箱地址',
     example: 'user@example.com',
   },
   uri: {
@@ -155,12 +155,12 @@ function getZodSchema(schema: PrimitiveSchemaDefinition): z.ZodTypeAny {
     switch (schema.format) {
       case 'email':
         stringSchema = stringSchema.email({
-          message: 'Must be a valid email address, e.g. user@example.com',
+          message: '必须是有效的邮箱地址,如 user@example.com',
         })
         break
       case 'uri':
         stringSchema = stringSchema.url({
-          message: 'Must be a valid URI, e.g. https://example.com',
+          message: '必须是有效的 URI,如 https://example.com',
         })
         break
       case 'date':

+ 2 - 2
src/utils/messages.ts

@@ -3896,7 +3896,7 @@ You have exited auto mode. The user may now want to interact more directly. You
             transformedBlocks.push(
               {
                 type: 'text',
-                text: 'Full contents of resource:',
+                text: '资源的完整内容:',
               },
               {
                 type: 'text',
@@ -3904,7 +3904,7 @@ You have exited auto mode. The user may now want to interact more directly. You
               },
               {
                 type: 'text',
-                text: 'Do NOT read this resource again unless you think it may have changed, since you already have the full contents.',
+                text: '除非你认为资源可能已更改,否则请勿再次读取,因为你已经有了完整内容。',
               },
             )
           } else if ('blob' in item) {

+ 6 - 6
src/utils/model/agent.ts

@@ -124,7 +124,7 @@ function aliasMatchesParentTier(alias: string, parentModel: string): boolean {
 export function getAgentModelDisplay(model: string | undefined): string {
   // When model is omitted, getDefaultSubagentModel() returns 'inherit' at runtime
   if (!model) return 'Inherit from parent (default)'
-  if (model === 'inherit') return 'Inherit from parent'
+  if (model === 'inherit') return '继承自父级'
   return capitalize(model)
 }
 
@@ -136,22 +136,22 @@ export function getAgentModelOptions(): AgentModelOption[] {
     {
       value: 'sonnet',
       label: 'Sonnet',
-      description: 'Balanced performance - best for most agents',
+      description: '平衡性能 - 最适合大多数代理',
     },
     {
       value: 'opus',
       label: 'Opus',
-      description: 'Most capable for complex reasoning tasks',
+      description: '最适合复杂推理任务',
     },
     {
       value: 'haiku',
       label: 'Haiku',
-      description: 'Fast and efficient for simple tasks',
+      description: '简单任务快速高效',
     },
     {
       value: 'inherit',
-      label: 'Inherit from parent',
-      description: 'Use the same model as the main conversation',
+      label: '继承自父级',
+      description: '使用与主对话相同的模型',
     },
   ]
 }

+ 13 - 13
src/utils/model/modelOptions.ts

@@ -49,7 +49,7 @@ export function getDefaultOptionForUser(fastMode = false): ModelOption {
     )
     return {
       value: null,
-      label: 'Default (recommended)',
+      label: '默认(推荐)',
       description: `Use the default model for Ants (currently ${currentModel})`,
       descriptionForModel: `Default model (currently ${currentModel})`,
     }
@@ -59,7 +59,7 @@ export function getDefaultOptionForUser(fastMode = false): ModelOption {
   if (isClaudeAISubscriber()) {
     return {
       value: null,
-      label: 'Default (recommended)',
+      label: '默认(推荐)',
       description: getClaudeAiUserDefaultModelDescription(fastMode),
     }
   }
@@ -68,7 +68,7 @@ export function getDefaultOptionForUser(fastMode = false): ModelOption {
   const is3P = getAPIProvider() !== 'firstParty'
   return {
     value: null,
-    label: 'Default (recommended)',
+    label: '默认(推荐)',
     description: `Use the default model (currently ${renderDefaultModelSetting(getDefaultMainLoopModelSetting())})${is3P ? '' : ` · ${formatModelPricing(COST_TIER_3_15)}`}`,
   }
 }
@@ -144,7 +144,7 @@ export function getSonnet46_1MOption(): ModelOption {
   const is3P = getAPIProvider() !== 'firstParty'
   return {
     value: is3P ? getModelStrings().sonnet46 + '[1m]' : 'sonnet[1m]',
-    label: 'Sonnet (1M context)',
+    label: 'Sonnet(1M 上下文)',
     description: `Sonnet 4.6 for long sessions${is3P ? '' : ` · ${formatModelPricing(COST_TIER_3_15)}`}`,
     descriptionForModel:
       'Sonnet 4.6 with 1M context window - for long sessions with large codebases',
@@ -155,7 +155,7 @@ export function getOpus46_1MOption(fastMode = false): ModelOption {
   const is3P = getAPIProvider() !== 'firstParty'
   return {
     value: is3P ? getModelStrings().opus46 + '[1m]' : 'opus[1m]',
-    label: 'Opus (1M context)',
+    label: 'Opus(1M 上下文)',
     description: `Opus 4.6 for long sessions${getOpus46PricingSuffix(fastMode)}`,
     descriptionForModel:
       'Opus 4.6 with 1M context window - for long sessions with large codebases',
@@ -221,7 +221,7 @@ export function getMaxSonnet46_1MOption(): ModelOption {
   const billingInfo = isClaudeAISubscriber() ? ' · Billed as extra usage' : ''
   return {
     value: 'sonnet[1m]',
-    label: 'Sonnet (1M context)',
+    label: 'Sonnet(1M 上下文)',
     description: `Sonnet 4.6 with 1M context${billingInfo}${is3P ? '' : ` · ${formatModelPricing(COST_TIER_3_15)}`}`,
   }
 }
@@ -230,7 +230,7 @@ export function getMaxOpus46_1MOption(fastMode = false): ModelOption {
   const billingInfo = isClaudeAISubscriber() ? ' · Billed as extra usage' : ''
   return {
     value: 'opus[1m]',
-    label: 'Opus (1M context)',
+    label: 'Opus(1M 上下文)',
     description: `Opus 4.6 with 1M context${billingInfo}${getOpus46PricingSuffix(fastMode)}`,
   }
 }
@@ -239,7 +239,7 @@ function getMergedOpus1MOption(fastMode = false): ModelOption {
   const is3P = getAPIProvider() !== 'firstParty'
   return {
     value: is3P ? getModelStrings().opus46 + '[1m]' : 'opus[1m]',
-    label: 'Opus (1M context)',
+    label: 'Opus(1M 上下文)',
     description: `Opus 4.6 with 1M context · Most capable for complex work${!is3P && fastMode ? getOpus46PricingSuffix(fastMode) : ''}`,
     descriptionForModel:
       'Opus 4.6 with 1M context - most capable for complex work',
@@ -249,20 +249,20 @@ function getMergedOpus1MOption(fastMode = false): ModelOption {
 const MaxSonnet46Option: ModelOption = {
   value: 'sonnet',
   label: 'Sonnet',
-  description: 'Sonnet 4.6 · Best for everyday tasks',
+  description: 'Sonnet 4.6 · 最适合日常任务',
 }
 
 const MaxHaiku45Option: ModelOption = {
   value: 'haiku',
   label: 'Haiku',
-  description: 'Haiku 4.5 · Fastest for quick answers',
+  description: 'Haiku 4.5 · 最适合快速回答',
 }
 
 function getOpusPlanOption(): ModelOption {
   return {
     value: 'opusplan',
-    label: 'Opus Plan Mode',
-    description: 'Use Opus 4.6 in plan mode, Sonnet 4.6 otherwise',
+    label: 'Opus 规划模式',
+    description: '规划模式使用 Opus 4.6,其他模式使用 Sonnet 4.6',
   }
 }
 
@@ -517,7 +517,7 @@ export function getModelOptions(fastMode = false): ModelOption[] {
       options.push({
         value: customModel,
         label: customModel,
-        description: 'Custom model',
+        description: '自定义模型',
       })
     }
     return filterModelOptionsByAllowlist(options)

+ 3 - 3
src/utils/model/validateModel.ts

@@ -24,7 +24,7 @@ export async function validateModel(
 
   // Empty model is invalid
   if (!normalizedModel) {
-    return { valid: false, error: 'Model name cannot be empty' }
+    return { valid: false, error: '模型名称不能为空' }
   }
 
   // Check against availableModels allowlist before any API call
@@ -100,14 +100,14 @@ function handleValidationError(
     if (error instanceof AuthenticationError) {
       return {
         valid: false,
-        error: 'Authentication failed. Please check your API credentials.',
+        error: '认证失败,请检查 API 凭据。',
       }
     }
 
     if (error instanceof APIConnectionError) {
       return {
         valid: false,
-        error: 'Network error. Please check your internet connection.',
+        error: '网络错误,请检查网络连接。',
       }
     }
 

+ 1 - 1
src/utils/nativeInstaller/installer.ts

@@ -1535,7 +1535,7 @@ async function manualRemoveNpmPackage(
     if (prefixResult.code !== 0 || !prefixResult.stdout) {
       return {
         success: false,
-        error: 'Failed to get npm global prefix',
+        error: '获取 npm 全局前缀失败',
       }
     }
 

+ 2 - 2
src/utils/pdf.ts

@@ -249,7 +249,7 @@ export async function extractPDFPages(
           success: false,
           error: {
             reason: 'corrupted',
-            message: 'PDF file is corrupted or invalid.',
+            message: 'PDF 文件损坏或无效。',
           },
         }
       }
@@ -269,7 +269,7 @@ export async function extractPDFPages(
         success: false,
         error: {
           reason: 'corrupted',
-          message: 'pdftoppm produced no output pages. The PDF may be invalid.',
+          message: 'pdftoppm 未输出任何页面。PDF 可能无效。',
         },
       }
     }

+ 3 - 3
src/utils/permissions/permissionExplainer.ts

@@ -45,13 +45,13 @@ const SYSTEM_PROMPT = `Analyze shell commands and explain what they do, why you'
 // Tool definition for forced structured output (no beta required)
 const EXPLAIN_COMMAND_TOOL = {
   name: 'explain_command',
-  description: 'Provide an explanation of a shell command',
+  description: '提供 Shell 命令的解释',
   input_schema: {
     type: 'object' as const,
     properties: {
       explanation: {
         type: 'string',
-        description: 'What this command does (1-2 sentences)',
+        description: '此命令的作用(1-2 句话)',
       },
       reasoning: {
         type: 'string',
@@ -60,7 +60,7 @@ const EXPLAIN_COMMAND_TOOL = {
       },
       risk: {
         type: 'string',
-        description: 'What could go wrong, under 15 words',
+        description: '可能出错的地方(少于 15 字)',
       },
       riskLevel: {
         type: 'string',

+ 1 - 1
src/utils/permissions/permissions.ts

@@ -576,7 +576,7 @@ export const hasPermissionsToUseTool: CanUseToolFn = async (
         if (appState.toolPermissionContext.shouldAvoidPermissionPrompts) {
           return {
             behavior: 'deny',
-            message: 'PowerShell tool requires interactive approval',
+            message: 'PowerShell 工具需要交互式确认',
             decisionReason: {
               type: 'asyncAgent',
               reason:

Beberapa file tidak ditampilkan karena terlalu banyak file yang berubah dalam diff ini