/** * 集中文案字典(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 / * 各设置 Tab(Agent、Appearance、Logs、MCP、SearXNG、SettingsModal、Tools、Workspace)/ * TaskList / Trace(TokenUsage、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': '默认 1000000(1M),用于上下文压缩判断', 'llm.ctxWindow.oaHelper': 'gpt-4o 默认 128K,gpt-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 (30–600s)', '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', });