Files
metona-ai-desktop/src/lib/i18n-strings.ts
T
thzxx 839860083f
CI / 类型检查 + Lint + 单元测试 (push) Failing after 9m8s
CI / 全量测试 (Electron ABI) (push) Failing after 6m8s
CI / 产物编译验证 (push) Successful in 11m1s
fix: v0.8.0 修订 — 思考用户意图优先 · 移除元信息硬门控 · 实施清单入库
- DeepSeek/MiMo/Agnes 移除 supportsThinking 元信息硬门控:思考参数完全遵循用户配置
  (事故复盘中 vision-exp 元信息标注不支持思考、实际产生了 8189 token 推理内容,
  元信息不可靠;预算耗尽由引擎降级重试兜底,元信息不符仅告警不拦截)
- Ollama 保留 /api/show 能力探测门控(服务端硬协议约束:向不支持思考的模型发
  think 每次请求 400,属协议正确性而非意图覆盖),探测失败 fail-open
- LLM 设置提示文案修订:元信息不符仍按用户配置发送,降级重试自动兜底
- 测试契约反向钉住:vision-exp + 用户开启→照发 enabled+reasoning_effort;
  关闭/未配置→显式 disabled;Ollama 探测 false→不发 think / null→fail-open
- 补录 docs/v0.8.0-迭代实施清单.md(含逐项验证记录与本次修订记录;
  首次提交时该文件因故未入库,本次补齐)
- 验证:typecheck 0 错误 / lint 0 问题 / 系统 Node 2146 通过 / thinking 矩阵 101 用例全绿
2026-09-05 20:49:20 +08:00

1446 lines
75 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 集中文案字典(v0.6.4 P3-5 第一轮 → v0.7.2 P4-15 第二阶段 → v0.7.4 P3-1 收口)
*
* 目标:把散落在数据层与核心组件的硬编码文案收敛为稳定 key。
* 第三阶段(v0.7.4 P3-1)覆盖渲染层全量迁移:CommandPalette / ContextMenu /
* 聊天组件(AssistantMessage、ChatInput、MessageList、StreamingIndicator、ThoughtBlock、
* ToolCallCard、ToolResultBlock、UserMessage/ ErrorBoundary / DetailPanel / Header /
* 各设置 TabAgent、Appearance、Logs、MCP、SearXNG、SettingsModal、Tools、Workspace/
* TaskList / TraceTokenUsage、TraceStep、TraceViewer/ WorkspaceViewer / useConfig。
* 组件层按此模式渐进迁移 —— 每迁一处,删一处字面量。
*/
import { registerTranslations } from './i18n';
registerTranslations('zh-CN', {
// ===== 会话终止(useAgentStream done 分支)=====
'agent.terminated.max_iterations': '⏹ 已达到最大迭代轮次上限',
'agent.terminated.timeout': '⏹ 任务执行超时',
'agent.terminated.error': '执行出错',
// ===== 确认/中断 =====
'agent.system.stopped': '⏹ 会话已停止:{{reason}}',
'agent.error.generic': '错误: {{message}}',
'agent.error.content_filtered': '⚠️ {{message}}',
// v0.8.0 P2-4: @ 文件提及
'input.mention.failed': '@{{path}} 读取失败:{{reason}}',
// ===== v0.8.0 P0-2/P0-4: 流结束契约提示 =====
'agent.terminated.output_truncated':
'⚠️ 回答可能因输出上限被截断(finish_reason=length)。可在 设置 → LLM 配置 中提高"最大输出上限",或降低思考强度',
'agent.error.output_length_exceeded':
'⚠️ 模型的思考内容耗尽了输出 token 预算,未能产出回答(finish_reason=length)。建议:提高"最大输出上限" / 关闭思考模式或降低思考强度 / 更换输出预算更大的模型',
'agent.error.empty_response':
'⚠️ 模型未返回任何内容(含重试)。可能为上游中断或输出上限截断,请重试或调整输出上限/思考设置',
'agent.system.empty_completed': '⚠️ 模型未返回内容。请重试,或检查输出上限与思考模式设置',
'agent.system.finalize_missing':
'⚠️ 会话已结束但未收到正常收尾事件,已恢复输入(结果以数据库内容为准)',
'agent.system.abort_failed': '⚠️ 中断请求失败,Agent 可能仍在运行;已恢复实时显示',
'agent.system.replay_truncated': '(提示:后台运行内容较多,仅恢复了最近部分事件)',
'agent.system.tool_interrupted': '已中断',
// ===== 通用 =====
'common.cancel': '取消',
'common.delete': '删除',
'common.refresh': '刷新',
'common.close': '关闭',
// v0.8.0 P2-2: 会话回放
'replay.title': '会话回放',
'replay.file': '选择录制文件',
'replay.play': '播放',
'replay.pause': '暂停',
'replay.stepBack': '上一步',
'replay.stepForward': '下一步',
'replay.speed': '播放速度',
'replay.loadFailed': '加载录制失败',
'replay.noRecordings': '该会话还没有 TRACE 录制文件(logs/session_*.jsonl',
'replay.skippedLines': '{{count}} 行损坏/截断被跳过',
'replay.event.iterationStart': '▶ 第 {{iteration}} 轮开始',
'replay.event.iterationEnd': '■ 第 {{iteration}} 轮结束({{duration}}',
'replay.event.sessionEnd': '会话结束:{{reason}}{{iterations}} 轮)',
// ===== 工具确认弹框(ConfirmationDialog=====
'confirm.title': '工具执行确认',
'confirm.parallelSuffix': '{{count}} 个并行请求)',
'confirm.refreshList': '刷新 pending 列表',
'confirm.batchReason':
'检测到 {{count}} 个并行工具调用请求确认(涉及 {{groups}} 个不同工具)。综合最高风险:{{risk}}',
'confirm.defaultReason': 'Agent 正在请求执行工具',
'confirm.rememberedDenials': '本会话中已记住拒绝的工具({{minutes}} 分钟后自动恢复询问):',
'confirm.askAgain': '重新询问',
'confirm.earliestExpiry': '最早过期 ',
'confirm.remaining': '剩余 ',
'confirm.selectAll': '全选',
'confirm.deselectAll': '全不选',
'confirm.selectedCount': '已选 {{selected}} / {{total}}',
'confirm.noArgs': '(无参数)',
'confirm.rememberSession': '在本次会话中记住此决定(同工具不再询问)',
'confirm.autoExecuteLabel': '永久自动执行选中工具(跨会话不再询问,可在设置中关闭)',
'confirm.autoExecuteApplies': '· 将应用到 {{count}} 个工具',
'confirm.autoExecConfirmTitle': '确认永久自动执行?',
'confirm.autoExecConfirmBody':
'勾选后,选中的工具将永久自动执行(跨会话不再询问),包括未来的潜在危险操作。此设置可在「设置 → 工具管理」中关闭。',
'confirm.autoExecConfirmQuestion': '确定要启用吗?',
'confirm.autoExecConfirmYes': '确认自动执行',
'confirm.denyAll': '拒绝全部 ({{count}})',
'confirm.denyAllTitle': '拒绝全部请求',
'confirm.denyAllExpiredTitle': '已超时,点击立即清理全部请求',
'confirm.approveAll': '批准全部',
'confirm.approveAllTitle': '批准全部请求',
'confirm.approveAllDisabledTitle': '已全部选中,请使用"批准选中"',
'confirm.approveAllExpiredTitle': '已超时(批准不再生效)',
'confirm.approveSelected': '批准选中 ({{count}})',
'confirm.confirmExecution': '确认执行 ({{count}})',
'confirm.expired': '已超时',
'confirm.expiredHint': '已超时,将自动拒绝;如需重新触发请等待 Agent 重试',
// ===== 侧边栏(Sidebar=====
'sidebar.newSession': '新建会话',
'sidebar.searchPlaceholder': '搜索会话标题与内容...',
'sidebar.noMatch': '无匹配结果',
'sidebar.empty': '暂无会话',
'sidebar.archived': '已归档',
// v0.8.0 P2-1: 回收站
'sidebar.trash': '回收站(30 天后自动清理)',
'sidebar.trash.empty': '回收站为空',
'sidebar.trash.purge': '彻底删除',
'sidebar.trash.purgeTitle': '彻底删除会话?',
'sidebar.trash.purgeBody': '「{{title}}」及其全部消息将被永久删除,此操作不可恢复。',
'sidebar.count': '{{count}} 个',
'sidebar.restore': '恢复',
'sidebar.deleteTitle': '删除会话',
'sidebar.deleteBody': '确定删除会话「{{title}}」?此操作不可恢复。',
'sidebar.deleteSessionAria': '删除会话 {{title}}',
'sidebar.messageCount': '{{count}} 条',
'sidebar.matchCount': '({{count}} 处) ',
'sidebar.toolManager': '工具管理',
'sidebar.toolsReady': '{{count}} 就绪',
'sidebar.toast.createFailed': '创建会话失败,请检查数据库状态',
'sidebar.toast.bridgeUnavailable': 'IPC 桥不可用:无法创建会话',
'sidebar.toast.deleteFailed': '删除会话失败,请重试',
'sidebar.toast.restoreFailed': '恢复失败',
'sidebar.toast.toolsLoadFailed': '加载工具列表失败',
// ===== 状态栏(StatusBar=====
'status.checkUpdate': '点击检查更新(当前 {{version}}',
'status.checking': '检查中…',
'status.newVersion': '发现新版本 {{version}},点击此通知或设置中打开下载页',
'status.upToDate': '已是最新版本',
'status.settings': '设置 (Ctrl+,)',
'status.agent.idle': '空闲',
'status.agent.thinking': '思考中...',
'status.agent.executing': '执行中...',
'status.agent.error': '错误',
// ===== Agent 状态监视(AgentMonitor=====
'monitor.agentStatus': 'Agent 状态',
'monitor.subAgentTasks': 'SubAgent 任务',
'monitor.count': '{{count}} 个',
'monitor.provider': 'Provider',
'monitor.model': '模型',
'monitor.iteration': '迭代',
'monitor.totalDuration': '总耗时',
'monitor.sub.delegated': '已委派',
'monitor.sub.running': '运行中',
'monitor.sub.completed': '已完成',
'monitor.sub.error': '失败',
// ===== 输入框(ChatInput)—— v0.7.3 P4-3 =====
'input.placeholder.ready': '输入消息... (Cmd/Ctrl+Enter 发送, Cmd/Ctrl+Shift+Enter 换行, / 命令)',
'input.placeholder.toolsLoading': '工具加载中...',
'input.placeholder.configLoading': '正在加载配置...',
'input.send': '发送',
'input.abort': '中断',
'input.attach.image': '附加文件(图片/文本/代码)',
'input.attach.textOnly.model': '附加文件(文本/代码)— 当前模型不支持图片',
'input.attach.textOnly.toggle': '附加文件(文本/代码)— 多模态未开启(设置 → LLM 配置)',
'input.image.skipped.model':
'当前模型不支持图片({{provider}} 需多模态模型),已跳过 {{count}} 个图片文件',
'input.image.skipped.toggle': '多模态未开启(设置 → LLM 配置),已跳过 {{count}} 个图片文件',
'input.image.skipped.probe': '当前模型不支持图片(能力探测),已跳过 {{count}} 个图片文件',
'input.file.readFailed': '文件读取失败,请检查文件是否损坏或被锁定',
'input.file.partialFailed': '{{count}} 个文件读取失败,已跳过',
'input.text.truncated': '文本附件 "{{name}}" 超过 512KB,已截断为前 512KB',
'input.text.truncatedNote':
'\n\n[... 文件内容已截断:原始大小 {{size}},仅包含前 {{limit}}。如需完整内容请分段处理 ...]',
'input.toast.toolsLoading': '工具正在加载中,请稍候...',
'input.slash.tool': '选择工具',
'input.slash.memory': '搜索记忆',
'input.slash.clear': '清空会话',
'input.slash.export': '导出 Markdown',
// ===== LLM 配置(LLMSettings)—— v0.7.3 P4-3 =====
'llm.title': 'LLM 配置',
'llm.loading': '加载中...',
'llm.provider.label': 'Provider',
'llm.baseURL': 'API Base URL',
'llm.baseURL.error': '需以 http:// 或 https:// 开头',
'llm.model.label': '模型名称',
'llm.model.placeholder': '如 deepseek-v4-pro、gpt-4o、claude-sonnet-4-5',
'llm.model.space': '模型名称不能包含空格',
'llm.models.load': '获取模型列表',
'llm.models.hint': '基于「已保存」的配置查询(修改后请先保存)',
'llm.models.hint.unloaded': '可手动输入,或点击下方按钮获取模型列表',
'llm.models.failed': '获取模型列表失败',
'llm.multimodal.label': '启用多模态(图片输入)',
'llm.multimodal.helper':
'开启后可在输入框上传图片;DeepSeek 需 vision 系列模型。历史会话图片会随上下文回传(最近 10 张)',
'llm.apiKey.label': 'API Key',
'llm.apiKey.required': '必填,未填 {{provider}} 的 API Key 会 401',
'llm.numCtx.label': '上下文长度 (num_ctx)',
'llm.numCtx.placeholder': '默认由模型决定(如 2048、4096、128000',
'llm.numCtx.error': '最小值为 512',
'llm.ctxWindow.label': '上下文窗口 (contextWindow)',
'llm.ctxWindow.placeholder': '如 64000、128000、1000000',
'llm.ctxWindow.minError': '最小值为 4096',
'llm.ctxWindow.helper': '用于上下文压缩判断,不传给 API',
'llm.ctxWindow.mimoHelper': '默认 10000001M),用于上下文压缩判断',
'llm.ctxWindow.oaHelper': 'gpt-4o 默认 128Kgpt-4.1 默认 1M',
'llm.ctxWindow.anthropicHelper': 'Claude 默认 200K',
// v0.8.0 FEAT-1: 最大输出上限(llm.maxTokens,按请求传给 API
'llm.maxTokens.label': '最大输出上限 (tokens)',
'llm.maxTokens.helper': '单次回复(含思考内容)的最大 token 数;思考会占用此预算',
'llm.maxTokens.minError': '最小值为 256',
'llm.maxTokens.exceedCap': '当前模型输出上限为 {{cap}},保存后将按模型上限生效(配置值被钳制)',
'llm.maxTokens.capInfo': '当前模型输出上限:{{cap}} tokens',
'llm.thinking.unsupported':
'当前模型元信息标注不支持思考:仍按你的配置发送思考参数;若思考耗尽输出预算,会自动关闭思考重试一次',
'llm.pull.title': '下载 Ollama 模型',
'llm.pull.placeholder': '模型名,如 qwen3:8b',
'llm.pull.download': '下载',
'llm.pull.cancel': '取消',
'llm.pull.helper':
'从 Ollama 服务拉取模型(大模型下载耗时取决于网络,可随时取消);完成后获取模型列表即可见',
'llm.pull.done': '模型 {{name}} 下载完成',
'llm.pull.failed': '模型下载失败:{{message}}',
'llm.balance.label': '账户余额',
'llm.balance.querying': '查询中...',
'llm.balance.unqueried': '未查询(需已保存 API Key',
'llm.balance.granted': '(赠送 {{granted}} + 充值 {{topped}}',
'llm.balance.queryFailed': '查询失败',
'llm.fallback.title': '故障转移(可选)',
'llm.fallback.helper':
'主 Provider 请求失败(重试耗尽或密钥失效)时自动切换到备用 Provider 重发。留空禁用。',
'llm.fallback.provider': '备用 Provider',
'llm.fallback.disabled': '禁用',
'llm.fallback.baseURL': '备用 Base URL',
'llm.fallback.model': '备用模型名称',
'llm.fallback.apiKey': '备用 API Key',
'llm.save': '保存配置',
'llm.saving': '保存中...',
'llm.save.blocked': '请修正表单错误后再保存',
'llm.save.blockedToast': '请修正表单中的错误后再保存',
'llm.save.success': '配置已保存',
'llm.save.failed': '保存失败:{{message}}',
'llm.api.unavailable': '配置 API 不可用',
'llm.save.failed.generic': '配置保存失败',
// ===== 记忆库(MemoryViewer)—— v0.7.3 P4-3 =====
'memory.search.title': '记忆搜索',
'memory.list.title': '记忆库',
'memory.results': '{{count}} 条结果',
'memory.total': '{{count}} 条',
'memory.search.placeholder': '搜索记忆...',
'memory.search.clear': '清除',
'memory.searching': '搜索中...',
'memory.search.empty': '无匹配结果',
'memory.empty': '暂无记忆数据',
'memory.loadFailed': '加载记忆失败',
'memory.deleteFailed': '删除失败',
'memory.type.episodic': '情景记忆',
'memory.type.semantic': '语义记忆',
'memory.type.working': '工作记忆',
// ===== 引导向导(OnboardingWizard)—— v0.7.3 P4-3 =====
'onboarding.step.welcome': '欢迎',
'onboarding.step.llm': '配置 LLM',
'onboarding.step.agent': '自定义 Agent',
'onboarding.step.workspace': '工作空间',
'onboarding.step.done': '开始使用',
'onboarding.prev': '上一步',
'onboarding.next': '下一步',
'onboarding.finish': '开始使用',
'onboarding.welcome.title': '欢迎使用 MetonaAI Desktop',
'onboarding.welcome.body':
'生产级通用 AI Agent 智能体桌面应用,支持多轮对话、工具调用、记忆系统和 MCP 协议集成。',
'onboarding.welcome.hint': '让我们花 1 分钟完成初始配置。',
'onboarding.llm.title': '配置 LLM Provider',
'onboarding.llm.body': '选择 Provider 并填写 API 信息。Base URL 和模型名称支持任意输入。',
'onboarding.llm.multimodal.label': '启用多模态(图片输入)',
'onboarding.llm.multimodal.helper': '开启后可在输入框上传图片;DeepSeek 需 vision 系列模型',
'onboarding.llm.apiKey.placeholder': 'sk-...(本地模型可留空)',
'onboarding.llm.ctx.ollama': '上下文长度 (num_ctx)',
'onboarding.llm.ctx.window': '上下文窗口 (contextWindow)',
'onboarding.llm.ctx.ollamaPlaceholder': '默认由模型决定(如 2048、4096、128000',
'onboarding.llm.ctx.placeholder': '如 64000、128000、1000000',
'onboarding.llm.ctx.helper': '用于上下文压缩判断,不传给 API',
'onboarding.llm.ctx.minError': '最小值为 {{min}}',
'onboarding.agent.title': '自定义 Agent',
'onboarding.agent.body': '编辑工作空间中的 SOUL.md 文件来定义 Agent 的身份和性格。',
'onboarding.agent.soulLabel': 'SOUL.md — 定义 Agent 的身份、性格、核心价值观',
'onboarding.agent.soulHint': '此步骤可稍后在工作空间目录中完成。',
'onboarding.workspace.title': '工作空间',
'onboarding.workspace.body': '选择工作空间目录,或使用默认路径。',
'onboarding.workspace.pick': '选择文件夹',
'onboarding.workspace.placeholder': '~/MetonaWorkspaces/default/',
'onboarding.workspace.helper': '包含 SOUL.md、MEMORY.md 两个必需文件,首次打开时自动创建。',
'onboarding.done.title': '配置完成!',
'onboarding.done.body': 'MetonaAI Desktop 已准备就绪。开始与你的 AI Agent 对话吧!',
'onboarding.done.hint': '按 Ctrl+Enter 发送消息,输入 / 查看命令列表',
'onboarding.toast.saveFailed': '配置保存失败,请重试',
'onboarding.toast.saveFailedWithReason': '保存配置失败:{{message}}',
'onboarding.toast.folderFailed': '选择文件夹失败',
// ===== 通用(v0.7.4 P3-1 补充)=====
'common.loading': '加载中...',
// ===== 命令面板(CommandPalette=====
'command.newSession': '新建会话',
'command.newSessionDesc': '创建一个新的对话会话',
'command.createFailed': '创建会话失败',
'command.clearSession': '清空当前会话',
'command.openSettings': '打开设置',
'command.messageCount': '{{count}} 条消息',
'command.searchPlaceholder': '搜索会话、命令...',
'command.noMatch': '无匹配结果',
'command.navHint': '↑↓ 导航',
'command.selectHint': '↵ 选择',
'command.closeHint': 'Esc 关闭',
// ===== 右键菜单(ContextMenu=====
'contextMenu.confirm': '确认',
'contextMenu.prompt': '输入',
'contextMenu.ok': '确定',
'contextMenu.toast.copyFailed': '复制失败',
'contextMenu.copy': '复制',
'contextMenu.quote': '引用回复',
'contextMenu.regenerate': '重新生成',
'contextMenu.rename': '重命名',
'contextMenu.renamePromptLabel': '新会话名称',
'contextMenu.renamePromptTitle': '重命名会话',
'contextMenu.toast.renameFailed': '重命名失败',
'contextMenu.pin': '置顶',
'contextMenu.unpin': '取消置顶',
'contextMenu.toast.pinFailed': '置顶失败',
'contextMenu.archive': '归档',
'contextMenu.unarchive': '取消归档',
'contextMenu.toast.archiveFailed': '归档失败',
'contextMenu.exportJson': '导出 JSON',
'contextMenu.exportMarkdown': '导出 Markdown',
'contextMenu.sessionExportTitle': '会话导出',
'contextMenu.toast.exportFailed': '导出失败',
'contextMenu.deleteConfirmBody': '确定删除此会话?此操作不可撤销。',
'contextMenu.toast.deleteFailed': '删除失败',
// ===== 聊天(chat / assistant / messageList / streaming / thought / toolCall / toolResult / userMessage=====
'chat.export.title': '会话导出',
'assistant.thinking': '正在思考...',
'assistant.thinkingLabel': '思考过程',
'assistant.generating': '正在生成回复...',
'assistant.toolCalls': '工具调用',
'assistant.reply': '回复',
'assistant.copy': '复制',
'assistant.copied': '已复制',
'messageList.subtitle': '生产级通用 AI Agent 智能体桌面应用',
'messageList.emptyHint': 'Agent 就绪 · 选择一个 Provider 开始对话',
'messageList.ariaLabel': '聊天消息列表',
'streaming.connecting': '正在连接 AI...',
'thought.thinkingLabel': '思考过程',
'toolCall.status.pending': '等待中',
'toolCall.status.executing': '执行中',
'toolCall.status.success': '成功',
'toolCall.status.error': '失败',
'toolCall.status.blocked': '已阻止',
'toolResult.title': '{{name}} 结果',
'userMessage.saveOnly': '仅保存',
'userMessage.saveAndResend': '保存并重发',
'userMessage.resendHint': '重发将删除此消息之后的所有消息 · Ctrl+Enter',
// ===== 错误边界(ErrorBoundary=====
'errorBoundary.renderFailed': '组件渲染失败',
'errorBoundary.unknownError': '未知错误',
'errorBoundary.retry': '重试',
// ===== 详情面板(DetailPanel=====
'detailPanel.error.trace': 'Trace 渲染失败',
'detailPanel.error.memory': 'Memory 渲染失败',
'detailPanel.error.tasks': 'Tasks 渲染失败',
'detailPanel.error.workspace': 'Workspace 渲染失败',
// ===== 顶栏(Header=====
'header.theme.light': '浅色主题',
'header.theme.dark': '深色主题',
'header.theme.auto': '跟随系统',
'header.hideSidebar': '隐藏侧边栏',
'header.showSidebar': '显示侧边栏',
'header.hideDetail': '隐藏详情面板',
'header.showDetail': '显示详情面板',
'header.exitFocus': '退出专注模式',
'header.enterFocus': '进入专注模式',
'header.settings': '设置',
// ===== Agent 监视(AgentMonitor 补充)=====
'monitor.iterations': ' · {{count}} 轮',
// ===== Agent 配置(AgentSettings=====
'settings.agent.title': 'Agent 配置',
'settings.agent.maxIterations': '最大迭代次数',
'settings.agent.totalTimeout': '总超时(秒)',
'settings.agent.toolExecTimeout': '工具执行超时(秒)',
'settings.agent.toolExecTimeoutHelper':
'单个工具执行的最大时长,超时自动终止(最低 10 秒,无上限)',
'settings.agent.confirmTimeout': '工具确认超时(秒)',
'settings.agent.confirmTimeoutHelper': '用户未响应工具确认时,超时自动视为拒绝(30~600 秒)',
'settings.agent.enableThinking': '启用思考模式',
'settings.agent.thinkingEffort': '思考强度',
'settings.agent.enableReflection': '启用反思阶段(REFLECTING',
'settings.agent.enableReflectionHelper':
'每轮工具执行后进入反思状态,存在失败结果时记录告警(不阻断执行)',
// ===== 外观设置(AppearanceSettings=====
'settings.appearance.title': '外观',
'settings.appearance.theme': '主题',
'settings.appearance.dark': '深色',
'settings.appearance.light': '浅色',
'settings.appearance.auto': '跟随系统',
'settings.appearance.locale': '界面语言',
'settings.appearance.localeZhCN': '简体中文',
'settings.appearance.localeEnUS': 'English',
'settings.appearance.localeHelper':
'切换即时生效;已迁移的界面(系统消息 / 工具确认弹框 / 侧边栏 / 状态栏 / Agent 状态区)将跟随所选语言显示',
// ===== 日志与数据(LogsSettings=====
'settings.logs.title': '日志与数据',
'settings.logs.logLevel': '日志级别',
'settings.logs.logFile': '日志文件',
'settings.logs.pathLoading': '正在获取路径...',
'settings.logs.pathUnavailable': '路径不可用',
'settings.logs.openLogFolder': '打开日志文件夹',
'settings.logs.copied': '已复制',
'settings.logs.copyPath': '复制路径',
'settings.logs.copyFailed': '复制失败',
'settings.logs.openFailed': '打开失败: {{message}}',
'settings.logs.logLevelHelper':
'日志级别变更重启后生效。日志文件按日期滚动,旧日志保留在 logs 目录下。',
'settings.logs.dataManagement': '数据管理',
'settings.logs.exportAllData': '📦 导出全部数据(JSON',
'settings.logs.exportFailed': '导出失败: {{message}}',
'settings.logs.exporting': '导出中...',
'settings.logs.exportAuditJsonl': '📋 导出审计 (JSONL)',
'settings.logs.exportAuditCsv': '📊 导出审计 (CSV)',
'settings.logs.auditExported': '已导出 {{count}} 条审计记录',
'settings.logs.auditExportFailed': '审计导出失败: {{message}}',
'settings.logs.clearing': '清理中...',
'settings.logs.clearSessions': '🗑️ 清理所有会话',
'settings.logs.clearMemories': '🗑️ 清理所有记忆',
'settings.logs.clearAuditLogs': '🗑️ 清理审计日志',
'settings.logs.clear': '清理',
'settings.logs.clearFailed': '失败: {{message}}',
'settings.logs.confirmClearTitle': '确认清理',
'settings.logs.confirmClearBody': '确定清理{{label}}?此操作不可撤销。',
'settings.logs.cleared': '{{label}}已清理',
'settings.logs.data.sessions': '所有会话',
'settings.logs.data.memories': '所有记忆',
'settings.logs.data.auditLogs': '审计日志',
'settings.logs.traceFilesTitle': '会话录制文件(TRACE JSONL',
// v0.8.0 P2-3: 检查更新 / 下载安装
'settings.logs.update.title': '应用更新',
'settings.logs.update.check': '检查更新',
'settings.logs.update.checking': '检查中…',
'settings.logs.update.downloadInstall': '下载并安装',
'settings.logs.update.installing': '准备安装…',
'settings.logs.update.available': '新版本 {{version}} 可用,点击"下载并安装"升级',
'settings.logs.update.upToDate': '已是最新版本({{version}}',
'settings.logs.update.disabled': '未配置更新源(app.updateFeedUrl',
'settings.logs.update.error': '更新失败:{{message}}',
'settings.logs.update.downloaded': '下载完成,即将重启安装…',
'settings.logs.traceStats':
'{{count}} 个文件 · 共 {{size}}(保留策略:最近 200 个,启动时自动清理)',
'settings.logs.statsLoading': '统计中...',
'settings.logs.refreshStats': '刷新统计',
'settings.logs.pruneOldFiles': '清理旧录制文件',
'settings.logs.pruneDone': '已清理 {{count}} 个旧录制文件(保留最近 200 个)',
'settings.logs.pruneFailed': '清理失败:{{message}}',
'settings.logs.healthTitle': '运行健康(SLO / 健康检查)',
'settings.logs.noSnapshot': '暂无快照',
'settings.logs.health.errorRate': '请求错误率(5 分钟窗口)',
'settings.logs.health.errorRateValue': '{{pct}}{{count}} 次请求)',
'settings.logs.health.latency': '延迟 P50 / P95 / P99',
'settings.logs.health.burnRate': 'SLO 燃烧速率(目标 99.9%',
'settings.logs.health.check': '健康检查',
'settings.logs.health.allPassed': '全部通过',
'settings.logs.health.abnormal': '异常:{{checks}}',
'settings.logs.health.notRunYet': '启动后尚未执行(周期 60s',
'settings.logs.health.chainVerify': '审计日志链校验',
'settings.logs.health.chainValid': '通过({{verified}}/{{total}} 条)',
'settings.logs.health.chainTampered': '已篡改!首个异常记录 #{{index}}',
'settings.logs.health.verifyChainBtn': '校验审计日志链',
'settings.logs.verifyFailed': '校验失败:{{message}}',
// ===== MCP 服务(MCPSettings=====
'settings.mcp.title': 'MCP 服务',
'settings.mcp.empty': '暂无 MCP 服务',
'settings.mcp.toolCount': '{{count}} 工具',
'settings.mcp.connect': '连接',
'settings.mcp.disconnect': '断开',
'settings.mcp.remove': '移除',
'settings.mcp.add': '添加',
'settings.mcp.addServer': '+ 添加 MCP 服务',
'settings.mcp.serverName': '服务名称',
'settings.mcp.localStdio': '本地 (stdio)',
'settings.mcp.remoteHttp': '远程 (HTTP)',
'settings.mcp.commandPlaceholder': '命令路径(如 npx / node / python',
'settings.mcp.argsPlaceholder': '参数 (空格分隔)',
'settings.mcp.urlPlaceholder': 'Streamable HTTP URL(如 https://example.com/mcp',
'settings.mcp.headersPlaceholder':
'自定义请求头 (JSON,可选),如 {"Authorization": "Bearer xxx"}',
'settings.mcp.headersInvalid':
'自定义请求头需为合法 JSON 对象,如 {"Authorization": "Bearer xxx"}',
'settings.mcp.addFailed': '添加 MCP 服务失败',
'settings.mcp.addFailedMsg': '添加 MCP 服务失败:{{message}}',
'settings.mcp.removeFailed': '移除失败',
// v0.8.0 P2-5: MCP Resources / Prompts 发现
'settings.mcp.contents.show': '查看资源与提示词',
'settings.mcp.contents.hide': '收起资源与提示词',
'settings.mcp.contents.empty': '该 Server 未声明 Resources / Prompts 能力',
'settings.mcp.removeFailedMsg': '移除失败:{{message}}',
'settings.mcp.toggleFailed': '操作失败',
'settings.mcp.toggleFailedMsg': '操作失败:{{message}}',
'settings.mcp.removeConfirmTitle': '确认移除',
'settings.mcp.removeConfirmBody': '确定移除 MCP 服务 "{{name}}"?此操作不可撤销。',
// ===== SearXNG 配置(SearXNGSettings=====
'settings.searxng.tabTitle': 'SearXNG',
'settings.searxng.title': 'SearXNG 元搜索',
'settings.searxng.description':
'SearXNG 是开源元搜索引擎,支持 70+ 搜索引擎聚合。启用后替代内置四引擎搜索通道,未启用时回退到 Bing + 百度 + 搜狗 + 360 搜索。',
'settings.searxng.enabled': '已启用',
'settings.searxng.disabled': '未启用',
'settings.searxng.enableAria': '启用 SearXNG',
'settings.searxng.enable': '启用 SearXNG',
'settings.searxng.urlLabel': 'API 地址',
'settings.searxng.urlPlaceholder': '如 https://searxng.example.com',
'settings.searxng.urlError': '需以 http:// 或 https:// 开头',
'settings.searxng.urlHelper': '实例根地址(不含 /search 路径)',
'settings.searxng.test': '测试连接',
'settings.searxng.testSuccess': '连接成功({{latency}}ms',
'settings.searxng.testFailedHttp': '连接失败(HTTP {{code}}',
'settings.searxng.enginesLabel': '搜索引擎(逗号分隔)',
'settings.searxng.enginesPlaceholder': '如 google,bing,duckduckgo(留空使用实例默认)',
'settings.searxng.language': '语言',
'settings.searxng.langZhCN': '简体中文',
'settings.searxng.langZhTW': '繁體中文',
'settings.searxng.langAuto': '自动检测',
'settings.searxng.safesearch': '安全搜索',
'settings.searxng.safeOff': '关闭',
'settings.searxng.safeMedium': '中等',
'settings.searxng.safeStrict': '严格',
'settings.searxng.timeRange': '时间范围',
'settings.searxng.timeAny': '不限',
'settings.searxng.timeDay': '一天',
'settings.searxng.timeWeek': '一周',
'settings.searxng.timeMonth': '一月',
'settings.searxng.timeYear': '一年',
'settings.searxng.format': '返回格式',
'settings.searxng.formatJson': 'JSON(结构化解析)',
'settings.searxng.formatHtml': 'HTML(原始网页)',
'settings.searxng.maxResults': '最大结果数',
'settings.searxng.maxResultsPlaceholder': '0 表示使用默认',
'settings.searxng.fetchCount': '自动抓取条数',
'settings.searxng.fetchCountPlaceholder': '0 表示由 AI 决定',
'settings.searxng.fetchMode': '抓取类型',
'settings.searxng.fetchSequential': '顺序抓取',
'settings.searxng.fetchRandom': '随机抓取',
'settings.searxng.authTitle': '认证设置',
'settings.searxng.authType': '认证类型',
'settings.searxng.authToken': 'Token',
'settings.searxng.authUserPass': '用户名:密码',
'settings.searxng.authTokenPlaceholder': '访问令牌原值',
'settings.searxng.authUserPassPlaceholder': 'username:password',
'settings.searxng.hideKey': '隐藏密钥',
'settings.searxng.showKey': '显示密钥',
'settings.searxng.authBearerHelper':
'Bearer: 直接填写令牌原值,原样透传到 Authorization 头。建议配合 HTTPS 使用。',
'settings.searxng.authBasicHelper':
'Basic: 填写 username:password 明文串,系统自动 Base64 编码。必须配合 HTTPS 使用。',
'settings.searxng.saved': 'SearXNG 配置已保存',
'settings.searxng.saveFailed': '保存失败',
'settings.searxng.toggleFailed': '开关保存失败',
'settings.searxng.saving': '保存中...',
'settings.searxng.saveChanges': '保存更改',
'settings.searxng.dirty': '有未保存的修改',
'settings.searxng.savedNotice': '已保存',
'settings.searxng.loading': '正在读取配置...',
// ===== 设置弹窗(SettingsModal=====
'settings.title': '设置',
'settings.tabs.workspace': '工作空间',
'settings.tabs.llm': 'LLM 配置',
'settings.tabs.agent': 'Agent 配置',
'settings.tabs.tools': '工具管理',
'settings.tabs.mcp': 'MCP 服务',
'settings.tabs.searxng': 'SearXNG',
'settings.tabs.appearance': '外观',
'settings.tabs.logs': '日志与数据',
'settings.error.workspace': '工作空间设置渲染失败',
'settings.error.llm': 'LLM 配置渲染失败',
'settings.error.agent': 'Agent 配置渲染失败',
'settings.error.tools': '工具管理渲染失败',
'settings.error.mcp': 'MCP 服务渲染失败',
'settings.error.searxng': 'SearXNG 渲染失败',
'settings.error.appearance': '外观设置渲染失败',
'settings.error.logs': '日志与数据渲染失败',
'settings.saveFailed': '配置保存失败',
// ===== 工具管理(ToolsSettings=====
'settings.tools.title': '工具管理',
'settings.tools.toggleFailed': '切换工具失败',
'settings.tools.autoExecFailed': '设置自动执行失败',
'settings.tools.autoExecTitle': '自动执行工具',
'settings.tools.autoExecCount': '{{count}} 个',
'settings.tools.autoExecHelper':
'已设为自动执行的工具将跳过用户确认步骤,直接执行。此设置跨会话持久化。',
'settings.tools.noAutoExec': '暂无自动执行工具',
'settings.tools.autoChip': '自动',
'settings.tools.cancelAuto': '取消自动',
'settings.tools.availableAutoExec': '可设为自动执行(当前需要确认)',
'settings.tools.setAuto': '设为自动',
'settings.tools.proxyTitle': '网络代理',
'settings.tools.proxyLabel': '代理地址(可选)',
'settings.tools.proxyPlaceholder': 'http://127.0.0.1:7890 或 socks5://…(留空直连)',
'settings.tools.proxyError': '需以 http://、https://、socks5:// 或 socks4:// 开头',
'settings.tools.proxyHelper':
'应用于 Chromium 会话与主进程全部网络请求;未填时回退系统环境变量 HTTPS_PROXY。',
// ===== 工作空间设置(WorkspaceSettings=====
'settings.workspace.title': '工作空间',
'settings.workspace.description':
'工作空间是 Metona 的组织核心,包含 SOUL.md、MEMORY.md 两个必需文件。',
'settings.workspace.placeholder': '~/MetonaWorkspaces/default/',
'settings.workspace.checking': '校验中...',
'settings.workspace.check': '校验',
'settings.workspace.checkingInProgress': '正在校验工作空间...',
'settings.workspace.invalidPath': '路径无效:{{reason}}',
'settings.workspace.openInFileManager': '📂 在文件管理器中打开',
'settings.workspace.openFolderFailed': '打开文件夹失败',
'settings.workspace.targetWorkspace': '目标工作空间:{{path}}',
'settings.workspace.newWorkspace':
'新工作空间 — 切换后将自动创建 2 个必需文件(SOUL.md、MEMORY.md',
'settings.workspace.missingFiles':
'已有目录但缺少 {{count}} 个文件:{{files}}。缺失文件将自动创建。',
'settings.workspace.existingWorkspace':
'已有工作空间 — 2 个必需文件均已就绪,将直接加载现有配置。',
'settings.workspace.inheritFromCurrent': '从当前工作空间继承:',
'settings.workspace.inheritSoul': 'SOUL.md(身份与角色定义)',
'settings.workspace.inheritDatabase': '数据库 agent.db(会话/消息/记忆/Trace 历史记录)',
'settings.workspace.inheritDatabaseHelper':
'勾选后将复制当前工作空间的全部历史数据到新工作空间(通过 SQLite backup API 原子性导出)',
'settings.workspace.memoryNotInherited': 'MEMORY.md 不继承(记忆与工作空间项目上下文绑定)',
'settings.workspace.applying': '应用中...',
'settings.workspace.confirmSwitch': '确认切换',
'settings.workspace.restartHint': '修改工作空间路径后需重启应用生效。',
'settings.workspace.switchedTitle': '工作空间已切换',
'settings.workspace.switchedBody': '工作空间已更新为:',
'settings.workspace.restartQuestion': '需要重启应用以加载新工作空间的配置和文件。是否立即重启?',
'settings.workspace.restartLater': '稍后手动重启',
'settings.workspace.restartNow': '立即重启',
'settings.workspace.dbIntegrityFailed': '源数据库校验失败:{{message}}',
'settings.workspace.dbCorrupted': '源数据库损坏({{detail}}),无法继承',
'settings.workspace.dbIntegrityError': '源数据库校验异常:{{message}}',
'settings.workspace.inheritPartialFailed': '部分文件继承失败:{{message}},请手动检查',
'settings.workspace.switchFailed': '切换工作空间失败:{{message}}',
// ===== 任务列表(TaskList=====
'taskList.title': '任务列表',
'taskList.count': '{{count}} 项',
'taskList.addTask': '新增任务',
'taskList.cancelAdd': '取消新增',
'taskList.titlePlaceholder': '任务标题...',
'taskList.creating': '...',
'taskList.create': '创建',
'taskList.cancelAddTask': '取消新增任务',
'taskList.selectSession': '请先选择或创建会话',
'taskList.titleRequired': '任务标题不能为空',
'taskList.createFailed': '创建任务失败',
'taskList.updateFailed': '更新任务失败',
'taskList.deleteFailed': '删除任务失败',
'taskList.loadFailed': '加载任务失败',
'taskList.selectSessionHint': '请先选择会话',
'taskList.empty': '暂无任务,点击 + 创建',
'taskList.noDescription': '无描述',
'taskList.status.pending': '待处理',
'taskList.status.inProgress': '进行中',
'taskList.status.completed': '已完成',
'taskList.status.blocked': '阻塞',
'taskList.status.cancelled': '已取消',
'taskList.priority.low': '低',
'taskList.priority.medium': '中',
'taskList.priority.high': '高',
'taskList.priority.critical': '紧急',
// ===== Token 统计(TokenUsage=====
'trace.token.usage': 'Token 用量',
'trace.token.input': '输入',
'trace.token.output': '输出',
'trace.token.total': '累计消耗',
'trace.token.context': '上下文占用',
'trace.token.compressedSaved': '压缩节省',
// ===== Trace 步骤(TraceStep / constants=====
'trace.step.toolCalls': '工具调用',
'trace.state.INIT': '初始化',
'trace.state.THINKING': '思考',
'trace.state.PARSING': '解析',
'trace.state.EXECUTING': '执行',
'trace.state.OBSERVING': '观察',
'trace.state.REFLECTING': '反思',
'trace.state.COMPRESSING': '压缩',
'trace.state.TERMINATED': '终止',
// ===== Trace 视图(TraceViewer=====
'trace.viewer.rounds': '共 {{count}} 轮',
'trace.viewer.waiting': '等待 Agent 活动...',
'trace.viewer.roundNumber': '第 {{index}} 轮',
'trace.viewer.inProgress': '进行中',
'trace.viewer.completed': '已完成',
'trace.viewer.steps': '{{count}} 步',
// ===== 工作空间浏览器(WorkspaceViewer=====
'workspace.currentWorkspace': '当前工作空间',
'workspace.openInFileManager': '在文件管理器中打开',
'workspace.showInFileManager': '在文件管理器中显示',
'workspace.coreFiles': '核心文件({{count}}/{{total}}',
'workspace.emptyFile': '(空文件)',
'workspace.fileMissing': '文件不存在',
'workspace.autoDirs': '自动目录',
'workspace.dirFileCount': '{{count}} 个文件',
'workspace.dirMissing': '不存在',
'workspace.noData': '无数据',
'workspace.loadFailed': '加载工作空间信息失败',
'workspace.openFailed': '打开文件夹失败',
});
registerTranslations('en-US', {
'agent.terminated.max_iterations': '⏹ Max iteration limit reached',
'agent.terminated.timeout': '⏹ Task timed out',
'agent.terminated.error': 'Execution error',
'agent.system.stopped': '⏹ Session stopped: {{reason}}',
'agent.error.generic': 'Error: {{message}}',
'agent.error.content_filtered': '⚠️ {{message}}',
// v0.8.0 P2-4: @ file mention
'input.mention.failed': '@{{path}} read failed: {{reason}}',
// ===== v0.8.0 P0-2/P0-4: stream-end contract notices =====
'agent.terminated.output_truncated':
'⚠️ The answer may have been truncated by the output token limit (finish_reason=length). Raise "Max Output Tokens" in Settings → LLM, or lower thinking effort',
'agent.error.output_length_exceeded':
'⚠️ The model consumed its entire output token budget on reasoning and produced no answer (finish_reason=length). Try: raise "Max Output Tokens" / disable or lower thinking / switch to a model with a larger output budget',
'agent.error.empty_response':
'⚠️ The model returned no content (after retries). This may be an upstream drop or output-limit cutoff — retry, or adjust output limit / thinking settings',
'agent.system.empty_completed':
'⚠️ The model returned no content. Please retry, or check the output limit / thinking settings',
'agent.system.finalize_missing':
'⚠️ The run ended without a normal completion event — input restored (results reflect the database)',
'agent.system.abort_failed':
'⚠️ Abort request failed — the agent may still be running; live display restored',
'agent.system.replay_truncated':
' (Note: many events occurred in the background; only the most recent were restored)',
'agent.system.tool_interrupted': 'Interrupted',
'common.cancel': 'Cancel',
'common.delete': 'Delete',
'common.refresh': 'Refresh',
'common.close': 'Close',
// v0.8.0 P2-2: Session replay
'replay.title': 'Session replay',
'replay.file': 'Select recording',
'replay.play': 'Play',
'replay.pause': 'Pause',
'replay.stepBack': 'Step back',
'replay.stepForward': 'Step forward',
'replay.speed': 'Playback speed',
'replay.loadFailed': 'Failed to load recording',
'replay.noRecordings': 'No TRACE recordings for this session yet (logs/session_*.jsonl)',
'replay.skippedLines': '{{count}} corrupt/truncated line(s) skipped',
'replay.event.iterationStart': '▶ Iteration {{iteration}} start',
'replay.event.iterationEnd': '■ Iteration {{iteration}} end ({{duration}})',
'replay.event.sessionEnd': 'Session ended: {{reason}} ({{iterations}} iterations)',
'confirm.title': 'Tool Execution Confirmation',
'confirm.parallelSuffix': ' ({{count}} parallel requests)',
'confirm.refreshList': 'Refresh pending list',
'confirm.batchReason':
'{{count}} parallel tool calls are requesting confirmation ({{groups}} distinct tools). Highest risk: {{risk}}',
'confirm.defaultReason': 'The agent is requesting to execute a tool',
'confirm.rememberedDenials':
'Tools remembered as denied in this session (asking again in {{minutes}} min):',
'confirm.askAgain': 'Ask again',
'confirm.earliestExpiry': 'Earliest expires in ',
'confirm.remaining': 'Remaining ',
'confirm.selectAll': 'Select all',
'confirm.deselectAll': 'Deselect all',
'confirm.selectedCount': 'Selected {{selected}} / {{total}}',
'confirm.noArgs': '(no arguments)',
'confirm.rememberSession': 'Remember this decision for this session (ask no more)',
'confirm.autoExecuteLabel':
'Always auto-execute selected tools (across sessions; disable in Settings)',
'confirm.autoExecuteApplies': '· Applies to {{count}} tool(s)',
'confirm.autoExecConfirmTitle': 'Enable permanent auto-execution?',
'confirm.autoExecConfirmBody':
'Once enabled, the selected tools will always run without asking — including potentially dangerous operations in the future. You can turn this off in Settings → Tools.',
'confirm.autoExecConfirmQuestion': 'Are you sure?',
'confirm.autoExecConfirmYes': 'Enable auto-execution',
'confirm.denyAll': 'Deny all ({{count}})',
'confirm.denyAllTitle': 'Deny all requests',
'confirm.denyAllExpiredTitle': 'Expired — click to clean up all requests now',
'confirm.approveAll': 'Approve all',
'confirm.approveAllTitle': 'Approve all requests',
'confirm.approveAllDisabledTitle': 'All selected — use "Approve selected" instead',
'confirm.approveAllExpiredTitle': 'Expired (approval no longer applies)',
'confirm.approveSelected': 'Approve selected ({{count}})',
'confirm.confirmExecution': 'Confirm execution ({{count}})',
'confirm.expired': 'Expired',
'confirm.expiredHint': 'Expired and will be auto-denied; wait for the agent to retry if needed',
'sidebar.newSession': 'New Session',
'sidebar.searchPlaceholder': 'Search session titles and content...',
'sidebar.noMatch': 'No matches',
'sidebar.empty': 'No sessions yet',
'sidebar.archived': 'Archived',
// v0.8.0 P2-1: Trash
'sidebar.trash': 'Trash (auto-purged after 30 days)',
'sidebar.trash.empty': 'Trash is empty',
'sidebar.trash.purge': 'Delete forever',
'sidebar.trash.purgeTitle': 'Delete session forever?',
'sidebar.trash.purgeBody':
'"{{title}}" and all of its messages will be permanently deleted. This cannot be undone.',
'sidebar.count': '{{count}}',
'sidebar.restore': 'Restore',
'sidebar.deleteTitle': 'Delete Session',
'sidebar.deleteBody': 'Delete session "{{title}}"? This cannot be undone.',
'sidebar.deleteSessionAria': 'Delete session {{title}}',
'sidebar.messageCount': '{{count}} msgs',
'sidebar.matchCount': '({{count}} hits) ',
'sidebar.toolManager': 'Tools',
'sidebar.toolsReady': '{{count}} ready',
'sidebar.toast.createFailed': 'Failed to create session — check database status',
'sidebar.toast.bridgeUnavailable': 'IPC bridge unavailable: cannot create session',
'sidebar.toast.deleteFailed': 'Failed to delete session — please retry',
'sidebar.toast.restoreFailed': 'Restore failed',
'sidebar.toast.toolsLoadFailed': 'Failed to load tool list',
'status.checkUpdate': 'Click to check for updates (current {{version}})',
'status.checking': 'Checking…',
'status.newVersion':
'New version {{version}} available — click this notification to open the download page',
'status.upToDate': 'Up to date',
'status.settings': 'Settings (Ctrl+,)',
'status.agent.idle': 'Idle',
'status.agent.thinking': 'Thinking...',
'status.agent.executing': 'Executing...',
'status.agent.error': 'Error',
'monitor.agentStatus': 'Agent Status',
'monitor.subAgentTasks': 'SubAgent Tasks',
'monitor.count': '{{count}}',
'monitor.provider': 'Provider',
'monitor.model': 'Model',
'monitor.iteration': 'Iteration',
'monitor.totalDuration': 'Total time',
'monitor.sub.delegated': 'Delegated',
'monitor.sub.running': 'Running',
'monitor.sub.completed': 'Completed',
'monitor.sub.error': 'Failed',
// ===== 输入框(ChatInput=====
'input.placeholder.ready':
'Type a message... (Cmd/Ctrl+Enter to send, Cmd/Ctrl+Shift+Enter for newline, / for commands)',
'input.placeholder.toolsLoading': 'Loading tools...',
'input.placeholder.configLoading': 'Loading configuration...',
'input.send': 'Send',
'input.abort': 'Stop',
'input.attach.image': 'Attach files (images/text/code)',
'input.attach.textOnly.model': 'Attach files (text/code) — current model has no image support',
'input.attach.textOnly.toggle': 'Attach files (text/code) — multimodal disabled (Settings → LLM)',
'input.image.skipped.model':
'Current model has no image support ({{provider}} requires a multimodal model); {{count}} image file(s) skipped',
'input.image.skipped.toggle':
'Multimodal is disabled (Settings → LLM); {{count}} image file(s) skipped',
'input.image.skipped.probe':
'Current model has no image support (capability probe); {{count}} image file(s) skipped',
'input.file.readFailed': 'Failed to read files — check whether they are corrupted or locked',
'input.file.partialFailed': '{{count}} file(s) failed to read and were skipped',
'input.text.truncated':
'Text attachment "{{name}}" exceeds 512KB and was truncated to the first 512KB',
'input.text.truncatedNote':
'\n\n[... File content truncated: original size {{size}}, only the first {{limit}} included. Process in segments if you need the full content ...]',
'input.toast.toolsLoading': 'Tools are still loading, please wait...',
'input.slash.tool': 'Pick a tool',
'input.slash.memory': 'Search memory',
'input.slash.clear': 'Clear session',
'input.slash.export': 'Export Markdown',
// ===== LLM 配置(LLMSettings=====
'llm.title': 'LLM Configuration',
'llm.loading': 'Loading...',
'llm.provider.label': 'Provider',
'llm.baseURL': 'API Base URL',
'llm.baseURL.error': 'Must start with http:// or https://',
'llm.model.label': 'Model Name',
'llm.model.placeholder': 'e.g. deepseek-v4-pro, gpt-4o, claude-sonnet-4-5',
'llm.model.space': 'Model name must not contain spaces',
'llm.models.load': 'Fetch model list',
'llm.models.hint': 'Queries the saved configuration (save changes first)',
'llm.models.hint.unloaded': 'Type manually, or fetch the model list below',
'llm.models.failed': 'Failed to fetch model list',
'llm.multimodal.label': 'Enable multimodal (image input)',
'llm.multimodal.helper':
'Allows uploading images; DeepSeek requires a vision model. Images from history are replayed (last 10)',
'llm.apiKey.label': 'API Key',
'llm.apiKey.required': 'Required — missing {{provider}} API Key will result in 401',
'llm.numCtx.label': 'Context length (num_ctx)',
'llm.numCtx.placeholder': 'Default decided by the model (e.g. 2048, 4096, 128000)',
'llm.numCtx.error': 'Minimum is 512',
'llm.ctxWindow.label': 'Context window (contextWindow)',
'llm.ctxWindow.placeholder': 'e.g. 64000, 128000, 1000000',
'llm.ctxWindow.minError': 'Minimum is 4096',
'llm.ctxWindow.helper': 'Used for context-compression decisions; not sent to the API',
'llm.ctxWindow.mimoHelper': 'Default 1000000 (1M), used for compression decisions',
'llm.ctxWindow.oaHelper': 'gpt-4o defaults to 128K, gpt-4.1 to 1M',
'llm.ctxWindow.anthropicHelper': 'Claude defaults to 200K',
// v0.8.0 FEAT-1: max output tokens (llm.maxTokens, sent per request)
'llm.maxTokens.label': 'Max output tokens',
'llm.maxTokens.helper':
'Maximum tokens per response (reasoning included); thinking consumes this budget',
'llm.maxTokens.minError': 'Minimum is 256',
'llm.maxTokens.exceedCap':
'This model caps output at {{cap}} — the saved value will be clamped to the model limit',
'llm.maxTokens.capInfo': 'Model output cap: {{cap}} tokens',
'llm.thinking.unsupported':
'Model metadata marks thinking as unsupported — your setting is still sent; if reasoning exhausts the output budget, one degraded retry (thinking off) runs automatically',
'llm.pull.title': 'Download Ollama model',
'llm.pull.placeholder': 'Model name, e.g. qwen3:8b',
'llm.pull.download': 'Download',
'llm.pull.cancel': 'Cancel',
'llm.pull.helper':
'Pull a model from the Ollama server (large downloads depend on network; cancellable). Fetch the list afterwards',
'llm.pull.done': 'Model {{name}} downloaded',
'llm.pull.failed': 'Model download failed: {{message}}',
'llm.balance.label': 'Account Balance',
'llm.balance.querying': 'Querying...',
'llm.balance.unqueried': 'Not queried (requires a saved API Key)',
'llm.balance.granted': '(granted {{granted}} + topped up {{topped}})',
'llm.balance.queryFailed': 'Query failed',
'llm.fallback.title': 'Failover (optional)',
'llm.fallback.helper':
'Switch to the fallback provider when the primary fails (retries exhausted or invalid key). Leave empty to disable.',
'llm.fallback.provider': 'Fallback Provider',
'llm.fallback.disabled': 'Disabled',
'llm.fallback.baseURL': 'Fallback Base URL',
'llm.fallback.model': 'Fallback Model Name',
'llm.fallback.apiKey': 'Fallback API Key',
'llm.save': 'Save Configuration',
'llm.saving': 'Saving...',
'llm.save.blocked': 'Fix form errors before saving',
'llm.save.blockedToast': 'Please fix the form errors before saving',
'llm.save.success': 'Configuration saved',
'llm.save.failed': 'Save failed: {{message}}',
'llm.api.unavailable': 'Configuration API unavailable',
'llm.save.failed.generic': 'Failed to save configuration',
// ===== 记忆库(MemoryViewer=====
'memory.search.title': 'Memory Search',
'memory.list.title': 'Memory Store',
'memory.results': '{{count}} results',
'memory.total': '{{count}} items',
'memory.search.placeholder': 'Search memories...',
'memory.search.clear': 'Clear',
'memory.searching': 'Searching...',
'memory.search.empty': 'No matches',
'memory.empty': 'No memories yet',
'memory.loadFailed': 'Failed to load memories',
'memory.deleteFailed': 'Delete failed',
'memory.type.episodic': 'Episodic',
'memory.type.semantic': 'Semantic',
'memory.type.working': 'Working',
// ===== 引导向导(OnboardingWizard=====
'onboarding.step.welcome': 'Welcome',
'onboarding.step.llm': 'Configure LLM',
'onboarding.step.agent': 'Customize Agent',
'onboarding.step.workspace': 'Workspace',
'onboarding.step.done': 'Get Started',
'onboarding.prev': 'Back',
'onboarding.next': 'Next',
'onboarding.finish': 'Get Started',
'onboarding.welcome.title': 'Welcome to MetonaAI Desktop',
'onboarding.welcome.body':
'A production-grade AI Agent desktop app with multi-turn chat, tool calling, memory, and MCP integration.',
'onboarding.welcome.hint': "Let's spend 1 minute on initial setup.",
'onboarding.llm.title': 'Configure LLM Provider',
'onboarding.llm.body':
'Pick a provider and fill in API details. Base URL and model accept any input.',
'onboarding.llm.multimodal.label': 'Enable multimodal (image input)',
'onboarding.llm.multimodal.helper': 'Allows uploading images; DeepSeek requires a vision model',
'onboarding.llm.apiKey.placeholder': 'sk-... (leave empty for local models)',
'onboarding.llm.ctx.ollama': 'Context length (num_ctx)',
'onboarding.llm.ctx.window': 'Context window (contextWindow)',
'onboarding.llm.ctx.ollamaPlaceholder': 'Default decided by the model (e.g. 2048, 4096, 128000)',
'onboarding.llm.ctx.placeholder': 'e.g. 64000, 128000, 1000000',
'onboarding.llm.ctx.helper': 'Used for context-compression decisions; not sent to the API',
'onboarding.llm.ctx.minError': 'Minimum is {{min}}',
'onboarding.agent.title': 'Customize Agent',
'onboarding.agent.body':
'Edit SOUL.md in the workspace to define the agent identity and personality.',
'onboarding.agent.soulLabel': 'SOUL.md — define the agent identity, personality, and core values',
'onboarding.agent.soulHint': 'You can do this later in the workspace directory.',
'onboarding.workspace.title': 'Workspace',
'onboarding.workspace.body': 'Choose a workspace directory, or keep the default.',
'onboarding.workspace.pick': 'Choose Folder',
'onboarding.workspace.placeholder': '~/MetonaWorkspaces/default/',
'onboarding.workspace.helper':
'Contains the two required files SOUL.md and MEMORY.md, auto-created on first open.',
'onboarding.done.title': 'All set!',
'onboarding.done.body': 'MetonaAI Desktop is ready. Start chatting with your AI agent!',
'onboarding.done.hint': 'Press Ctrl+Enter to send; type / to see commands',
'onboarding.toast.saveFailed': 'Failed to save configuration, please retry',
'onboarding.toast.saveFailedWithReason': 'Failed to save configuration: {{message}}',
'onboarding.toast.folderFailed': 'Failed to choose folder',
// ===== Common =====
'common.loading': 'Loading...',
// ===== Command Palette =====
'command.newSession': 'New Session',
'command.newSessionDesc': 'Create a new chat session',
'command.createFailed': 'Failed to create session',
'command.clearSession': 'Clear current session',
'command.openSettings': 'Open Settings',
'command.messageCount': '{{count}} messages',
'command.searchPlaceholder': 'Search sessions and commands...',
'command.noMatch': 'No matches',
'command.navHint': '↑↓ Navigate',
'command.selectHint': '↵ Select',
'command.closeHint': 'Esc Close',
// ===== Context Menu =====
'contextMenu.confirm': 'Confirm',
'contextMenu.prompt': 'Input',
'contextMenu.ok': 'OK',
'contextMenu.toast.copyFailed': 'Copy failed',
'contextMenu.copy': 'Copy',
'contextMenu.quote': 'Quote reply',
'contextMenu.regenerate': 'Regenerate',
'contextMenu.rename': 'Rename',
'contextMenu.renamePromptLabel': 'New session name',
'contextMenu.renamePromptTitle': 'Rename Session',
'contextMenu.toast.renameFailed': 'Rename failed',
'contextMenu.pin': 'Pin',
'contextMenu.unpin': 'Unpin',
'contextMenu.toast.pinFailed': 'Pin failed',
'contextMenu.archive': 'Archive',
'contextMenu.unarchive': 'Unarchive',
'contextMenu.toast.archiveFailed': 'Archive failed',
'contextMenu.exportJson': 'Export JSON',
'contextMenu.exportMarkdown': 'Export Markdown',
'contextMenu.sessionExportTitle': 'Session Export',
'contextMenu.toast.exportFailed': 'Export failed',
'contextMenu.deleteConfirmBody': 'Delete this session? This cannot be undone.',
'contextMenu.toast.deleteFailed': 'Delete failed',
// ===== Chat / assistant / messageList / streaming / thought / toolCall / toolResult / userMessage =====
'chat.export.title': 'Session Export',
'assistant.thinking': 'Thinking...',
'assistant.thinkingLabel': 'Thought process',
'assistant.generating': 'Generating reply...',
'assistant.toolCalls': 'Tool calls',
'assistant.reply': 'Reply',
'assistant.copy': 'Copy',
'assistant.copied': 'Copied',
'messageList.subtitle': 'A production-grade AI Agent desktop app',
'messageList.emptyHint': 'Agent ready · pick a provider to start chatting',
'messageList.ariaLabel': 'Chat message list',
'streaming.connecting': 'Connecting to AI...',
'thought.thinkingLabel': 'Thought process',
'toolCall.status.pending': 'Waiting',
'toolCall.status.executing': 'Executing',
'toolCall.status.success': 'Success',
'toolCall.status.error': 'Failed',
'toolCall.status.blocked': 'Blocked',
'toolResult.title': '{{name}} result',
'userMessage.saveOnly': 'Save only',
'userMessage.saveAndResend': 'Save & resend',
'userMessage.resendHint': 'Resending deletes all messages after this one · Ctrl+Enter',
// ===== Error Boundary =====
'errorBoundary.renderFailed': 'Component render failed',
'errorBoundary.unknownError': 'Unknown error',
'errorBoundary.retry': 'Retry',
// ===== Detail Panel =====
'detailPanel.error.trace': 'Failed to render Trace',
'detailPanel.error.memory': 'Failed to render Memory',
'detailPanel.error.tasks': 'Failed to render Tasks',
'detailPanel.error.workspace': 'Failed to render Workspace',
// ===== Header =====
'header.theme.light': 'Light theme',
'header.theme.dark': 'Dark theme',
'header.theme.auto': 'System theme',
'header.hideSidebar': 'Hide sidebar',
'header.showSidebar': 'Show sidebar',
'header.hideDetail': 'Hide detail panel',
'header.showDetail': 'Show detail panel',
'header.exitFocus': 'Exit focus mode',
'header.enterFocus': 'Enter focus mode',
'header.settings': 'Settings',
// ===== Agent Monitor (supplement) =====
'monitor.iterations': ' · {{count}} round(s)',
// ===== Agent Settings =====
'settings.agent.title': 'Agent Configuration',
'settings.agent.maxIterations': 'Max iterations',
'settings.agent.totalTimeout': 'Total timeout (seconds)',
'settings.agent.toolExecTimeout': 'Tool execution timeout (seconds)',
'settings.agent.toolExecTimeoutHelper':
'Maximum duration for a single tool call; auto-terminated on timeout (min 10s, no upper limit)',
'settings.agent.confirmTimeout': 'Tool confirmation timeout (seconds)',
'settings.agent.confirmTimeoutHelper':
'If the user does not respond to a tool confirmation, it is auto-denied after the timeout (30600s)',
'settings.agent.enableThinking': 'Enable thinking mode',
'settings.agent.thinkingEffort': 'Thinking effort',
'settings.agent.enableReflection': 'Enable reflection phase (REFLECTING)',
'settings.agent.enableReflectionHelper':
'Enters a reflection state after each round of tool execution; logs warnings on failed results (does not block execution)',
// ===== Appearance Settings =====
'settings.appearance.title': 'Appearance',
'settings.appearance.theme': 'Theme',
'settings.appearance.dark': 'Dark',
'settings.appearance.light': 'Light',
'settings.appearance.auto': 'System',
'settings.appearance.locale': 'Interface language',
'settings.appearance.localeZhCN': '简体中文',
'settings.appearance.localeEnUS': 'English',
'settings.appearance.localeHelper':
'Takes effect immediately; migrated UI (system messages / tool confirmation dialog / sidebar / status bar / agent status) follows the selected language',
// ===== Logs & Data Settings =====
'settings.logs.title': 'Logs & Data',
'settings.logs.logLevel': 'Log level',
'settings.logs.logFile': 'Log file',
'settings.logs.pathLoading': 'Fetching path...',
'settings.logs.pathUnavailable': 'Path unavailable',
'settings.logs.openLogFolder': 'Open log folder',
'settings.logs.copied': 'Copied',
'settings.logs.copyPath': 'Copy path',
'settings.logs.copyFailed': 'Copy failed',
'settings.logs.openFailed': 'Failed to open: {{message}}',
'settings.logs.logLevelHelper':
'Log level changes take effect after restart. Log files rotate by date; old logs are kept in the logs directory.',
'settings.logs.dataManagement': 'Data management',
'settings.logs.exportAllData': '📦 Export all data (JSON)',
'settings.logs.exportFailed': 'Export failed: {{message}}',
'settings.logs.exporting': 'Exporting...',
'settings.logs.exportAuditJsonl': '📋 Export audit (JSONL)',
'settings.logs.exportAuditCsv': '📊 Export audit (CSV)',
'settings.logs.auditExported': 'Exported {{count}} audit record(s)',
'settings.logs.auditExportFailed': 'Audit export failed: {{message}}',
'settings.logs.clearing': 'Clearing...',
'settings.logs.clearSessions': '🗑️ Clear all sessions',
'settings.logs.clearMemories': '🗑️ Clear all memories',
'settings.logs.clearAuditLogs': '🗑️ Clear audit logs',
'settings.logs.clear': 'Clear',
'settings.logs.clearFailed': 'Failed: {{message}}',
'settings.logs.confirmClearTitle': 'Confirm clear',
'settings.logs.confirmClearBody': 'Clear {{label}}? This cannot be undone.',
'settings.logs.cleared': '{{label}} cleared',
'settings.logs.data.sessions': 'all sessions',
'settings.logs.data.memories': 'all memories',
'settings.logs.data.auditLogs': 'audit logs',
'settings.logs.traceFilesTitle': 'Session recording files (TRACE JSONL)',
// v0.8.0 P2-3: App update
'settings.logs.update.title': 'App update',
'settings.logs.update.check': 'Check for updates',
'settings.logs.update.checking': 'Checking…',
'settings.logs.update.downloadInstall': 'Download & install',
'settings.logs.update.installing': 'Preparing to install…',
'settings.logs.update.available':
'Version {{version}} is available — click "Download & install" to upgrade',
'settings.logs.update.upToDate': 'Up to date ({{version}})',
'settings.logs.update.disabled': 'No update feed configured (app.updateFeedUrl)',
'settings.logs.update.error': 'Update failed: {{message}}',
'settings.logs.update.downloaded': 'Download complete — restarting to install…',
'settings.logs.traceStats':
'{{count}} file(s) · {{size}} total (retention: last 200, auto-cleaned on startup)',
'settings.logs.statsLoading': 'Computing...',
'settings.logs.refreshStats': 'Refresh stats',
'settings.logs.pruneOldFiles': 'Clear old recordings',
'settings.logs.pruneDone': 'Cleared {{count}} old recording file(s) (keeping the last 200)',
'settings.logs.pruneFailed': 'Clear failed: {{message}}',
'settings.logs.healthTitle': 'Runtime health (SLO / health checks)',
'settings.logs.noSnapshot': 'No snapshot yet',
'settings.logs.health.errorRate': 'Request error rate (5-min window)',
'settings.logs.health.errorRateValue': '{{pct}} ({{count}} requests)',
'settings.logs.health.latency': 'Latency P50 / P95 / P99',
'settings.logs.health.burnRate': 'SLO burn rate (target 99.9%)',
'settings.logs.health.check': 'Health checks',
'settings.logs.health.allPassed': 'All passed',
'settings.logs.health.abnormal': 'Abnormal: {{checks}}',
'settings.logs.health.notRunYet': 'Not run since startup (interval 60s)',
'settings.logs.health.chainVerify': 'Audit log chain verification',
'settings.logs.health.chainValid': 'Passed ({{verified}}/{{total}})',
'settings.logs.health.chainTampered': 'Tampered! First anomaly at record #{{index}}',
'settings.logs.health.verifyChainBtn': 'Verify audit chain',
'settings.logs.verifyFailed': 'Verification failed: {{message}}',
// ===== MCP Settings =====
'settings.mcp.title': 'MCP Services',
'settings.mcp.empty': 'No MCP servers yet',
'settings.mcp.toolCount': '{{count}} tools',
'settings.mcp.connect': 'Connect',
'settings.mcp.disconnect': 'Disconnect',
'settings.mcp.remove': 'Remove',
'settings.mcp.add': 'Add',
'settings.mcp.addServer': '+ Add MCP server',
'settings.mcp.serverName': 'Server name',
'settings.mcp.localStdio': 'Local (stdio)',
'settings.mcp.remoteHttp': 'Remote (HTTP)',
'settings.mcp.commandPlaceholder': 'Command path (e.g. npx / node / python)',
'settings.mcp.argsPlaceholder': 'Arguments (space-separated)',
'settings.mcp.urlPlaceholder': 'Streamable HTTP URL (e.g. https://example.com/mcp)',
'settings.mcp.headersPlaceholder':
'Custom headers (JSON, optional), e.g. {"Authorization": "Bearer xxx"}',
'settings.mcp.headersInvalid':
'Custom headers must be a valid JSON object, e.g. {"Authorization": "Bearer xxx"}',
'settings.mcp.addFailed': 'Failed to add MCP server',
'settings.mcp.addFailedMsg': 'Failed to add MCP server: {{message}}',
'settings.mcp.removeFailed': 'Remove failed',
// v0.8.0 P2-5: MCP discovery
'settings.mcp.contents.show': 'Show resources & prompts',
'settings.mcp.contents.hide': 'Hide resources & prompts',
'settings.mcp.contents.empty': 'This server does not declare Resources / Prompts capabilities',
'settings.mcp.removeFailedMsg': 'Remove failed: {{message}}',
'settings.mcp.toggleFailed': 'Operation failed',
'settings.mcp.toggleFailedMsg': 'Operation failed: {{message}}',
'settings.mcp.removeConfirmTitle': 'Confirm removal',
'settings.mcp.removeConfirmBody': 'Remove MCP server "{{name}}"? This cannot be undone.',
// ===== SearXNG Settings =====
'settings.searxng.tabTitle': 'SearXNG',
'settings.searxng.title': 'SearXNG Meta Search',
'settings.searxng.description':
'SearXNG is an open-source metasearch engine aggregating 70+ search engines. When enabled it replaces the built-in four-engine channel; otherwise it falls back to Bing + Baidu + Sogou + 360.',
'settings.searxng.enabled': 'Enabled',
'settings.searxng.disabled': 'Disabled',
'settings.searxng.enableAria': 'Enable SearXNG',
'settings.searxng.enable': 'Enable SearXNG',
'settings.searxng.urlLabel': 'API URL',
'settings.searxng.urlPlaceholder': 'e.g. https://searxng.example.com',
'settings.searxng.urlError': 'Must start with http:// or https://',
'settings.searxng.urlHelper': 'Instance root URL (without the /search path)',
'settings.searxng.test': 'Test connection',
'settings.searxng.testSuccess': 'Connection successful ({{latency}}ms)',
'settings.searxng.testFailedHttp': 'Connection failed (HTTP {{code}})',
'settings.searxng.enginesLabel': 'Search engines (comma-separated)',
'settings.searxng.enginesPlaceholder':
'e.g. google,bing,duckduckgo (empty uses instance default)',
'settings.searxng.language': 'Language',
'settings.searxng.langZhCN': '简体中文',
'settings.searxng.langZhTW': '繁體中文',
'settings.searxng.langAuto': 'Auto-detect',
'settings.searxng.safesearch': 'Safe search',
'settings.searxng.safeOff': 'Off',
'settings.searxng.safeMedium': 'Moderate',
'settings.searxng.safeStrict': 'Strict',
'settings.searxng.timeRange': 'Time range',
'settings.searxng.timeAny': 'Any',
'settings.searxng.timeDay': 'A day',
'settings.searxng.timeWeek': 'A week',
'settings.searxng.timeMonth': 'A month',
'settings.searxng.timeYear': 'A year',
'settings.searxng.format': 'Result format',
'settings.searxng.formatJson': 'JSON (structured parsing)',
'settings.searxng.formatHtml': 'HTML (raw page)',
'settings.searxng.maxResults': 'Max results',
'settings.searxng.maxResultsPlaceholder': '0 uses the default',
'settings.searxng.fetchCount': 'Auto-fetch count',
'settings.searxng.fetchCountPlaceholder': '0 lets the AI decide',
'settings.searxng.fetchMode': 'Fetch mode',
'settings.searxng.fetchSequential': 'Sequential fetch',
'settings.searxng.fetchRandom': 'Random fetch',
'settings.searxng.authTitle': 'Authentication',
'settings.searxng.authType': 'Auth type',
'settings.searxng.authToken': 'Token',
'settings.searxng.authUserPass': 'Username:password',
'settings.searxng.authTokenPlaceholder': 'Raw access token',
'settings.searxng.authUserPassPlaceholder': 'username:password',
'settings.searxng.hideKey': 'Hide key',
'settings.searxng.showKey': 'Show key',
'settings.searxng.authBearerHelper':
'Bearer: paste the raw token; it is passed through to the Authorization header. Recommended with HTTPS.',
'settings.searxng.authBasicHelper':
'Basic: enter a plaintext username:password pair; the app Base64-encodes it. HTTPS is required.',
'settings.searxng.saved': 'SearXNG configuration saved',
'settings.searxng.saveFailed': 'Save failed',
'settings.searxng.toggleFailed': 'Failed to save the toggle',
'settings.searxng.saving': 'Saving...',
'settings.searxng.saveChanges': 'Save changes',
'settings.searxng.dirty': 'You have unsaved changes',
'settings.searxng.savedNotice': 'Saved',
'settings.searxng.loading': 'Loading configuration...',
// ===== Settings Modal =====
'settings.title': 'Settings',
'settings.tabs.workspace': 'Workspace',
'settings.tabs.llm': 'LLM Configuration',
'settings.tabs.agent': 'Agent Configuration',
'settings.tabs.tools': 'Tools',
'settings.tabs.mcp': 'MCP Services',
'settings.tabs.searxng': 'SearXNG',
'settings.tabs.appearance': 'Appearance',
'settings.tabs.logs': 'Logs & Data',
'settings.error.workspace': 'Failed to render workspace settings',
'settings.error.llm': 'Failed to render LLM settings',
'settings.error.agent': 'Failed to render agent settings',
'settings.error.tools': 'Failed to render tool settings',
'settings.error.mcp': 'Failed to render MCP settings',
'settings.error.searxng': 'Failed to render SearXNG settings',
'settings.error.appearance': 'Failed to render appearance settings',
'settings.error.logs': 'Failed to render logs & data settings',
'settings.saveFailed': 'Failed to save configuration',
// ===== Tools Settings =====
'settings.tools.title': 'Tools',
'settings.tools.toggleFailed': 'Failed to toggle tool',
'settings.tools.autoExecFailed': 'Failed to set auto-execute',
'settings.tools.autoExecTitle': 'Auto-execute tools',
'settings.tools.autoExecCount': '{{count}}',
'settings.tools.autoExecHelper':
'Tools set to auto-execute skip the user confirmation step and run directly. This setting persists across sessions.',
'settings.tools.noAutoExec': 'No auto-execute tools yet',
'settings.tools.autoChip': 'Auto',
'settings.tools.cancelAuto': 'Cancel auto',
'settings.tools.availableAutoExec':
'Available for auto-execute (currently requires confirmation)',
'settings.tools.setAuto': 'Set auto',
'settings.tools.proxyTitle': 'Network proxy',
'settings.tools.proxyLabel': 'Proxy URL (optional)',
'settings.tools.proxyPlaceholder': 'http://127.0.0.1:7890 or socks5://… (empty = direct)',
'settings.tools.proxyError': 'Must start with http://, https://, socks5:// or socks4://',
'settings.tools.proxyHelper':
'Applies to all network requests from the Chromium session and the main process; falls back to the HTTPS_PROXY environment variable when empty.',
// ===== Workspace Settings =====
'settings.workspace.title': 'Workspace',
'settings.workspace.description':
"The workspace is Metona's organizational core, containing the two required files SOUL.md and MEMORY.md.",
'settings.workspace.placeholder': '~/MetonaWorkspaces/default/',
'settings.workspace.checking': 'Checking...',
'settings.workspace.check': 'Check',
'settings.workspace.checkingInProgress': 'Checking workspace...',
'settings.workspace.invalidPath': 'Invalid path: {{reason}}',
'settings.workspace.openInFileManager': '📂 Open in file manager',
'settings.workspace.openFolderFailed': 'Failed to open folder',
'settings.workspace.targetWorkspace': 'Target workspace: {{path}}',
'settings.workspace.newWorkspace':
'New workspace — the 2 required files (SOUL.md, MEMORY.md) will be auto-created on switch',
'settings.workspace.missingFiles':
'Directory exists but {{count}} file(s) are missing: {{files}}. Missing files will be auto-created.',
'settings.workspace.existingWorkspace':
'Existing workspace — the 2 required files are ready; existing configuration will be loaded.',
'settings.workspace.inheritFromCurrent': 'Inherit from the current workspace:',
'settings.workspace.inheritSoul': 'SOUL.md (identity & role definition)',
'settings.workspace.inheritDatabase':
'Database agent.db (sessions/messages/memories/Trace history)',
'settings.workspace.inheritDatabaseHelper':
'When checked, all history from the current workspace is copied to the new one (exported atomically via the SQLite backup API)',
'settings.workspace.memoryNotInherited':
'MEMORY.md is not inherited (memories are bound to the workspace project context)',
'settings.workspace.applying': 'Applying...',
'settings.workspace.confirmSwitch': 'Confirm switch',
'settings.workspace.restartHint':
'Changing the workspace path requires an app restart to take effect.',
'settings.workspace.switchedTitle': 'Workspace switched',
'settings.workspace.switchedBody': 'The workspace has been updated to:',
'settings.workspace.restartQuestion':
'An app restart is required to load the new workspace configuration and files. Restart now?',
'settings.workspace.restartLater': 'Restart later',
'settings.workspace.restartNow': 'Restart now',
'settings.workspace.dbIntegrityFailed': 'Source database verification failed: {{message}}',
'settings.workspace.dbCorrupted': 'Source database is corrupted ({{detail}}); cannot inherit',
'settings.workspace.dbIntegrityError': 'Source database verification error: {{message}}',
'settings.workspace.inheritPartialFailed':
'Some files failed to inherit: {{message}} — check manually',
'settings.workspace.switchFailed': 'Failed to switch workspace: {{message}}',
// ===== Task List =====
'taskList.title': 'Tasks',
'taskList.count': '{{count}} item(s)',
'taskList.addTask': 'Add task',
'taskList.cancelAdd': 'Cancel add',
'taskList.titlePlaceholder': 'Task title...',
'taskList.creating': '...',
'taskList.create': 'Create',
'taskList.cancelAddTask': 'Cancel adding task',
'taskList.selectSession': 'Select or create a session first',
'taskList.titleRequired': 'Task title cannot be empty',
'taskList.createFailed': 'Failed to create task',
'taskList.updateFailed': 'Failed to update task',
'taskList.deleteFailed': 'Failed to delete task',
'taskList.loadFailed': 'Failed to load tasks',
'taskList.selectSessionHint': 'Select a session first',
'taskList.empty': 'No tasks yet — click + to create',
'taskList.noDescription': 'No description',
'taskList.status.pending': 'Pending',
'taskList.status.inProgress': 'In progress',
'taskList.status.completed': 'Completed',
'taskList.status.blocked': 'Blocked',
'taskList.status.cancelled': 'Cancelled',
'taskList.priority.low': 'Low',
'taskList.priority.medium': 'Medium',
'taskList.priority.high': 'High',
'taskList.priority.critical': 'Critical',
// ===== Token Usage =====
'trace.token.usage': 'Token Usage',
'trace.token.input': 'Input',
'trace.token.output': 'Output',
'trace.token.total': 'Total usage',
'trace.token.context': 'Context usage',
'trace.token.compressedSaved': 'Saved by compression',
// ===== Trace Step (TraceStep / constants) =====
'trace.step.toolCalls': 'Tool calls',
'trace.state.INIT': 'Initializing',
'trace.state.THINKING': 'Thinking',
'trace.state.PARSING': 'Parsing',
'trace.state.EXECUTING': 'Executing',
'trace.state.OBSERVING': 'Observing',
'trace.state.REFLECTING': 'Reflecting',
'trace.state.COMPRESSING': 'Compressing',
'trace.state.TERMINATED': 'Terminated',
// ===== Trace Viewer =====
'trace.viewer.rounds': '{{count}} round(s)',
'trace.viewer.waiting': 'Waiting for agent activity...',
'trace.viewer.roundNumber': 'Round {{index}}',
'trace.viewer.inProgress': 'In progress',
'trace.viewer.completed': 'Completed',
'trace.viewer.steps': '{{count}} step(s)',
// ===== Workspace Viewer =====
'workspace.currentWorkspace': 'Current workspace',
'workspace.openInFileManager': 'Open in file manager',
'workspace.showInFileManager': 'Show in file manager',
'workspace.coreFiles': 'Core files ({{count}}/{{total}})',
'workspace.emptyFile': '(empty file)',
'workspace.fileMissing': 'File does not exist',
'workspace.autoDirs': 'Auto directories',
'workspace.dirFileCount': '{{count}} files',
'workspace.dirMissing': 'Does not exist',
'workspace.noData': 'No data',
'workspace.loadFailed': 'Failed to load workspace info',
'workspace.openFailed': 'Failed to open folder',
});