1748 lines
72 KiB
TypeScript
1748 lines
72 KiB
TypeScript
import { createI18n } from 'vue-i18n'
|
||
|
||
const zhCN = {
|
||
nav: {
|
||
dashboard: '仪表盘',
|
||
memories: '全局记忆',
|
||
projects: '项目',
|
||
search: '搜索与编辑',
|
||
progress: '进度',
|
||
vault: '密码库',
|
||
files: '文件仓储',
|
||
tokens: 'MCP Token',
|
||
clients: '客户端配置',
|
||
prompt: '提示词',
|
||
curation: 'AI 整理',
|
||
git: '记忆版本',
|
||
system: '系统与备份',
|
||
},
|
||
common: {
|
||
create: '创建',
|
||
new: '新建',
|
||
save: '保存',
|
||
cancel: '取消',
|
||
search: '搜索',
|
||
refresh: '刷新',
|
||
edit: '编辑',
|
||
deactivate: '停用',
|
||
moveToTrash: '移入回收站',
|
||
permanentDelete: '永久删除',
|
||
delete: '删除',
|
||
copy: '复制',
|
||
reveal: '显示',
|
||
download: '下载',
|
||
close: '关闭',
|
||
status: '状态',
|
||
actions: '操作',
|
||
moreActions: '更多操作',
|
||
name: '名称',
|
||
description: '说明',
|
||
version: '版本',
|
||
tags: '标签',
|
||
project: '项目',
|
||
title: '标题',
|
||
type: '类型',
|
||
purpose: '用途',
|
||
size: '大小',
|
||
none: '无',
|
||
never: '从未',
|
||
available: '可用',
|
||
unavailable: '不可用',
|
||
configured: '已配置',
|
||
unconfigured: '未配置',
|
||
confirmDelete: '确认删除',
|
||
confirm: '确认',
|
||
confirmDeactivate: '确认停用',
|
||
confirmTrash: '确认移入回收站',
|
||
rename: '重命名',
|
||
back: '返回上级',
|
||
root: '根目录',
|
||
logout: '退出登录',
|
||
language: '界面语言',
|
||
usageProfile: '记忆空间',
|
||
noData: '暂无数据',
|
||
enabled: '已启用',
|
||
disabled: '已关闭',
|
||
},
|
||
status: {
|
||
available: '可用',
|
||
missing: '缺失',
|
||
vault: {
|
||
unlocked: '已解锁',
|
||
cached: '离线缓存',
|
||
locked: '已锁定',
|
||
connecting: '连接中',
|
||
syncing: '同步中',
|
||
pending: '等待连接',
|
||
disconnected: '未连接',
|
||
error: '连接异常',
|
||
},
|
||
},
|
||
memoryTypes: {
|
||
rule: { label: '规则', description: '必须持续遵守的明确约束和工作规范' },
|
||
preference: { label: '偏好', description: '语言、工具、风格和协作方式等个人偏好' },
|
||
fact: { label: '事实', description: '已经确认且相对稳定的项目或环境信息' },
|
||
decision: { label: '决定', description: '已经敲定的技术选择及其关键理由' },
|
||
experience: { label: '经验', description: '可复用的问题结论、排查方法和实践经验' },
|
||
checkpoint: { label: '检查点', description: '某个时间点的项目进度、现状和后续事项' },
|
||
prd: { label: '需求文档', description: '产品目标、用户场景、需求范围和验收标准' },
|
||
task_list: { label: '任务列表', description: '可跟踪状态、优先级和负责人等信息的任务清单' },
|
||
},
|
||
memoryTemplates: {
|
||
rule: '# 规则\n\n## 适用范围\n\n## 必须遵守\n\n- \n\n## 例外\n\n- 无',
|
||
preference: '# 偏好\n\n## 偏好内容\n\n- \n\n## 适用场景\n\n- ',
|
||
fact: '# 已确认事实\n\n## 内容\n\n\n## 依据\n\n- ',
|
||
decision: '# 决定\n\n## 结论\n\n\n## 背景与理由\n\n\n## 影响\n\n- ',
|
||
experience: '# 经验\n\n## 问题\n\n\n## 解决方案\n\n\n## 复用条件\n\n- ',
|
||
checkpoint:
|
||
'# 当前进度\n\n## 已完成\n\n- [ ] \n\n## 当前状态\n\n\n## 下一步\n\n- [ ] \n\n## 风险与阻塞\n\n- 无\n\n## 给下个会话\n\n- 未完成线索:\n- 临时约定:\n- 需要避开的坑:',
|
||
prd: '# 产品需求文档\n\n## 背景与目标\n\n\n## 用户与场景\n\n\n## 需求范围\n\n### 功能需求\n\n- \n\n### 非功能需求\n\n- \n\n## 验收标准\n\n- [ ] \n\n## 不在范围内\n\n- ',
|
||
task_list: '# 任务列表\n\n## 待办\n\n- [ ] \n\n## 进行中\n\n- [ ] \n\n## 已完成\n\n- [x] ',
|
||
},
|
||
auth: {
|
||
initialize: '初始化 MemRelay',
|
||
login: '登录 MemRelay',
|
||
username: '用户名',
|
||
password: '密码',
|
||
confirmPassword: '确认密码',
|
||
completeInitialize: '完成初始化',
|
||
signIn: '登录',
|
||
passwordMismatch: '两次输入的密码不一致',
|
||
},
|
||
memoryEditor: {
|
||
create: '新建记忆',
|
||
edit: '编辑记忆',
|
||
scope: '范围',
|
||
global: '全局',
|
||
project: '项目',
|
||
markdown: 'Markdown 内容',
|
||
mode: '编辑模式',
|
||
commaTags: '使用逗号分隔',
|
||
required: '标题和内容不能为空',
|
||
chooseProject: '请选择项目',
|
||
saved: '记忆已保存',
|
||
editMode: '编辑',
|
||
previewMode: '预览',
|
||
previewEmpty: '暂无可预览内容',
|
||
},
|
||
dashboard: {
|
||
subtitle: '共享工作区与依赖服务的当前状态',
|
||
projects: '项目',
|
||
memories: '记忆',
|
||
checkpoints: '检查点',
|
||
files: '文件',
|
||
capacity: '仓储容量',
|
||
activeTokens: '有效 Token',
|
||
pendingMemories: '待整理记忆',
|
||
curatedMemories: '已整理记忆',
|
||
supersededMemories: '已替代记忆',
|
||
curatedDocuments: '稳定整理文档',
|
||
dependencies: '依赖状态',
|
||
memoryDistribution: '记忆类型分布',
|
||
projectRanking: '项目记忆排行',
|
||
recentActivity: '最近开发活动',
|
||
activityTrend: '新增记忆趋势',
|
||
last14Days: '最近 14 天',
|
||
},
|
||
memories: {
|
||
subtitle: '跨项目共享的规则、偏好、事实和经验',
|
||
updatedAt: '更新时间',
|
||
empty: '还没有全局记忆',
|
||
archiveConfirm: '将“{title}”移入回收站?内容仍会保留。',
|
||
deleteConfirm: '永久删除“{title}”?此操作无法撤销。',
|
||
},
|
||
memoryLifecycle: {
|
||
label: '整理状态',
|
||
markPending: '重新放回待整理',
|
||
movedToPending: '已重新放回待整理',
|
||
filters: {
|
||
current: '当前有效',
|
||
pending: '待整理',
|
||
covered: '已整理',
|
||
superseded: '已替代',
|
||
checkpoint: '检查点',
|
||
archived: '回收站',
|
||
all: '全部',
|
||
},
|
||
labels: {
|
||
current: '当前有效',
|
||
pending: '待整理',
|
||
covered: '已整理',
|
||
reviewed: '已审阅',
|
||
superseded: '已替代',
|
||
archived: '回收站',
|
||
},
|
||
descriptions: {
|
||
current: '同时检索稳定整理文档和尚未整理的新来源',
|
||
pending: '尚未被稳定整理文档明确覆盖,默认参与搜索和上下文组装',
|
||
covered: '内容已被稳定整理文档引用,原始 Markdown 保留用于追溯',
|
||
reviewed: '模型已审阅此内容并确认无需提炼(冗余或无可整理信息),原始 Markdown 保留',
|
||
superseded: '内容已被更新来源替代,原始 Markdown 保留用于历史追溯',
|
||
checkpoint: '会话检查点快照,单独统计,不参与整理覆盖判定',
|
||
archived: '已移入回收站,不参与默认搜索和上下文组装',
|
||
},
|
||
},
|
||
projects: {
|
||
subtitle: '通过 Git remote、目录别名或名称识别项目上下文',
|
||
create: '新建项目',
|
||
created: '项目已创建',
|
||
archived: '已停用',
|
||
empty: '还没有项目',
|
||
select: '从左侧选择项目',
|
||
emptyMemory: '项目还没有记忆',
|
||
archiveConfirm: '停用项目“{name}”?项目将停止使用,但数据仍会保留,之后可永久删除。',
|
||
deleteConfirm: '永久删除已停用项目“{name}”及其全部记忆?此操作不可恢复。',
|
||
deleted: '项目已删除',
|
||
renamed: '项目名称已更新',
|
||
renameTitle: '编辑项目名称',
|
||
directoryAliases: '设备目录别名',
|
||
oneDirectoryPerLine: '每行一个目录',
|
||
gitRemote: 'Git remote',
|
||
searchPlaceholder: '搜索名称、Git 地址或目录',
|
||
downloadDocs: '下载项目文档',
|
||
memoryTab: '项目记忆',
|
||
timelineTab: '开发时间线',
|
||
emptyTimeline: '该项目还没有开发检查点',
|
||
workspaceType: '工作区类型',
|
||
workspaceTypeUpdated: '工作区类型已更新',
|
||
curationTemplate: '整理模板',
|
||
curationTemplateUpdated: '项目整理模板已更新',
|
||
curationTemplateHelp: '可选。仅在启用 AI 整理时追加到该项目的整理提示词。',
|
||
curationTemplatePlaceholder: '例如:保留实验编号,按日期组织结论,并单列未解决问题。',
|
||
noCurationTemplate: '未设置项目专用整理模板,将使用工作区类型的默认模板。',
|
||
sourceTab: '整理与来源',
|
||
sourceSettings: '工作区整理与来源',
|
||
sourceHelp: '这些设置仅在启用 AI 整理时生效;Git 地址、分支和凭证均为可选。',
|
||
curationEnabled: '允许整理此工作区',
|
||
sourceStrategy: '来源策略',
|
||
sourceBranch: '源码分支',
|
||
sourceCredential: '源码仓库凭证',
|
||
noSourceCredential: '匿名访问或暂不配置',
|
||
defaultBranch: '自动识别默认分支',
|
||
lastSourceCommit: '最后源码 Commit',
|
||
lastSourceFetch: '最后源码刷新',
|
||
lastAgentSync: 'Agent 最近同步',
|
||
sourceState: '来源状态',
|
||
cachedSource: '正在使用缓存源码',
|
||
freshSource: '源码已刷新',
|
||
notFetched: '尚未读取源码',
|
||
sourceSaved: '工作区来源设置已保存',
|
||
sourceStrategies: {
|
||
auto: '自动选择',
|
||
mcp: '仅 Agent/MCP',
|
||
repository: '仅文件仓储',
|
||
git: '仅源码 Git',
|
||
all: '全部来源',
|
||
},
|
||
workspaceTypes: {
|
||
development: '开发',
|
||
office: '办公',
|
||
study: '学习',
|
||
research: '研究',
|
||
personal: '个人',
|
||
general: '通用',
|
||
},
|
||
},
|
||
search: {
|
||
subtitle: '全文、标题和本地多语言语义检索',
|
||
placeholder: '搜索记忆',
|
||
hybrid: '混合搜索',
|
||
text: '全文搜索',
|
||
title: '标题搜索',
|
||
semantic: '语义搜索',
|
||
degraded: '语义模型不可用,结果已降级为全文搜索',
|
||
match: '匹配内容',
|
||
relevance: '相关度',
|
||
empty: '输入关键词开始搜索',
|
||
project: '所属项目',
|
||
unknownProject: '未知项目',
|
||
curatedDocument: '整理文档',
|
||
curatedDocumentDescription: 'AI 整理后的当前有效文档,可直接查看和编辑',
|
||
},
|
||
progress: {
|
||
subtitle: '按项目保存的追加式工作检查点',
|
||
create: '新建检查点',
|
||
chooseProject: '请先选择项目',
|
||
empty: '该项目还没有检查点',
|
||
deleteConfirm: '永久删除检查点“{title}”?',
|
||
deleted: '检查点已删除',
|
||
},
|
||
vault: {
|
||
title: '外部密码库',
|
||
subtitle: '集中管理账号、密码、Token、TOTP 和其他可复用凭证',
|
||
configure: '配置连接',
|
||
reconfigure: '重新配置',
|
||
syncNow: '立即同步',
|
||
connectionStatus: '连接状态',
|
||
serverUrl: '服务地址',
|
||
account: '账号',
|
||
loginMethod: '登录方式',
|
||
passwordLogin: '邮箱登录',
|
||
apiKeyLogin: 'API 密钥',
|
||
lastSync: '最后同步',
|
||
offlineCache: '离线缓存',
|
||
queryPlaceholder: '服务、域名或凭证名称',
|
||
noAccount: '无账号',
|
||
username: '账号',
|
||
password: '密码',
|
||
notes: '备注',
|
||
cached: '来自离线缓存',
|
||
selectCredential: '选择一个凭证',
|
||
empty: '没有匹配的密码条目',
|
||
newItem: '新建条目',
|
||
createItem: '新建密码条目',
|
||
editItem: '编辑密码条目',
|
||
itemName: '条目名称',
|
||
uris: '网站地址',
|
||
uriPlaceholder: '每行一个网站地址',
|
||
totp: 'TOTP 密钥',
|
||
totpSeed: 'TOTP 密钥',
|
||
totpSeedHelp: '支持 Base32 TOTP 密钥或完整的 otpauth:// 地址。',
|
||
customFields: '自定义字段',
|
||
addField: '添加字段',
|
||
fieldName: '字段名称',
|
||
fieldValue: '字段值',
|
||
hiddenField: '隐藏',
|
||
itemCreated: '密码条目已创建',
|
||
itemUpdated: '密码条目已更新',
|
||
itemDeleted: '密码条目已删除',
|
||
deleteConfirm: '删除“{name}”?该条目会移入密码库回收站。',
|
||
dialogTitle: '配置外部密码库',
|
||
httpsUrl: 'HTTP/HTTPS 服务地址',
|
||
serverUrlPlaceholder: 'https://vault.example.com 或 http://vault.lan',
|
||
serverUrlHelp: '局域网可使用 HTTP;公网建议通过反向代理提供 HTTPS。',
|
||
registeredEmail: '注册邮箱',
|
||
clientId: 'Client ID',
|
||
clientSecret: 'Client Secret',
|
||
masterPassword: '主密码',
|
||
connect: '连接并同步',
|
||
connected: '密码库已连接',
|
||
synced: '同步完成',
|
||
copied: '已复制',
|
||
},
|
||
files: {
|
||
subtitle: '可搜索的通用文件、程序和构建资源',
|
||
queryPlaceholder: '名称、说明、版本或用途',
|
||
scan: '扫描',
|
||
upload: '上传',
|
||
file: '文件',
|
||
directory: '目录',
|
||
createDirectory: '新建目录',
|
||
directoryName: '目录名称',
|
||
currentDirectory: '当前位置',
|
||
openDirectory: '进入目录',
|
||
empty: '仓储中还没有文件',
|
||
uploadTitle: '上传文件',
|
||
storagePath: '仓储路径',
|
||
allowOverwrite: '允许覆盖已有文件',
|
||
editMetadata: '编辑文件元数据',
|
||
moveTitle: '移动或重命名',
|
||
newPath: '新路径',
|
||
allowTargetOverwrite: '允许覆盖目标文件',
|
||
move: '移动',
|
||
chooseFile: '请选择文件',
|
||
uploaded: '上传完成',
|
||
deleteConfirm: '永久删除“{path}”?',
|
||
scanResult: '新增 {added},更新 {updated},丢失 {missing}',
|
||
directoryCreated: '目录已创建',
|
||
directoryNotEmpty: '目录不为空,请先处理目录内的内容',
|
||
},
|
||
tokens: {
|
||
subtitle: '为设备和客户端分配可撤销的只读或读写访问',
|
||
create: '创建 Token',
|
||
createTitle: '创建 MCP Token',
|
||
permission: '权限',
|
||
readWrite: '读写',
|
||
readOnly: '只读',
|
||
lastUsed: '最后使用',
|
||
revoked: '已撤销',
|
||
active: '有效',
|
||
revoke: '撤销',
|
||
namePlaceholder: '例如:办公室 Codex',
|
||
copied: 'Token 已复制',
|
||
revokeConfirm: '撤销“{name}”?Token 会立即永久失效,但记录仍会保留。',
|
||
deleteConfirm: '永久删除“{name}”的 Token 记录?',
|
||
confirmRevoke: '确认撤销',
|
||
revokeHint: '立即使 Token 永久失效,但保留记录和最后使用时间',
|
||
deleteHint: '永久删除 Token 记录;有效 Token 也会立即失效',
|
||
usageProfile: '记忆空间',
|
||
usageProfileHint: '决定该 Token 或当前 Web 会话可以读取和写入哪些个人、团队记忆。',
|
||
sharedProfile: '共享空间',
|
||
allProfiles: '全部记忆空间(自动包含后续新增)',
|
||
tokenTab: 'MCP Token',
|
||
profileTab: '记忆空间',
|
||
createProfile: '新建空间',
|
||
currentProfile: '当前 Web 记忆空间',
|
||
currentProfileUpdated: '当前记忆空间已更新',
|
||
profileEdit: '编辑记忆空间',
|
||
profileDelete: '删除记忆空间',
|
||
profileMigration: '将现有数据迁移到',
|
||
memories: '记忆数',
|
||
boundTokens: 'Token 数',
|
||
},
|
||
clients: {
|
||
subtitle: '生成远程 Streamable HTTP MCP 连接配置',
|
||
regenerate: '重新生成',
|
||
generic: '通用 HTTP MCP',
|
||
copy: '复制配置',
|
||
empty: '请先创建并选择一个有效 Token',
|
||
createTokenFirst: '请先创建 Token',
|
||
copied: '配置已复制',
|
||
},
|
||
prompt: {
|
||
subtitle: '根据当前能力动态生成的 Agent 使用约定',
|
||
copied: '提示词已复制',
|
||
pathCopied: '路径已复制',
|
||
language: '提示词语言',
|
||
chinese: '中文',
|
||
english: 'English',
|
||
scenarioWorkflow: '通用工作流',
|
||
scenarioNewProject: '新项目接入',
|
||
scenarioMigration: '已有项目迁移',
|
||
clientColumn: '客户端',
|
||
locationColumn: '规则文件位置(项目根)',
|
||
noteColumn: '说明',
|
||
locations: {
|
||
cursor: '也可用 .cursor/rules/*.mdc 并设置 alwaysApply: true;两者都会自动注入每次会话',
|
||
codex: '全局规则放 ~/.codex/AGENTS.md;项目文件优先生效',
|
||
claude: '全局规则放 ~/.claude/CLAUDE.md;项目文件优先生效',
|
||
vscode: 'Copilot 自定义指令文件,新版本也支持项目根 AGENTS.md',
|
||
genericClient: '其他客户端',
|
||
generic: 'AGENTS.md 是跨客户端的事实标准,未列出的客户端优先尝试它',
|
||
},
|
||
newStep1Title: '第一步:创建规则文件',
|
||
newStep1Text:
|
||
'在项目根目录按下表为你的客户端创建规则文件。客户端会在每次会话自动读取并注入该文件,AI 无需额外配置即会遵守其中的约定。',
|
||
newStep2Title: '第二步:粘贴工作流提示词',
|
||
newStep2Text: '把下方完整提示词粘贴进刚创建的文件并保存。',
|
||
copyWorkflow: '复制工作流提示词',
|
||
newStep3Title: '第三步:验证',
|
||
newStep3Text:
|
||
'开一个新会话说"开始工作",AI 应主动调用 capabilities_get 并解析/创建当前项目;可追问"当前项目在 MemRelay 的 ID 是什么"确认已接入。',
|
||
migrationIntro:
|
||
'适用于已经写了很多代码和文档、想把知识沉淀进 MemRelay 的项目。先按"新项目接入"放好规则文件,再把下方迁移提示词粘贴到该项目的 AI 对话中发送一次。',
|
||
migrationHow:
|
||
'AI 会解析项目、通读现有文档、把确定的规则/事实/决定/经验精炼写入记忆、建立迁移基线检查点并自检,之后自动转入标准工作流。原有文档保持不动。',
|
||
},
|
||
curation: {
|
||
subtitle: '可选的无人值守资料整理;未配置时不影响任何基础能力',
|
||
optionalEmpty:
|
||
'AI 整理是可选增强。当前未配置模型,记忆、项目、搜索、密码库、文件和 MCP 均正常可用。',
|
||
enabled: '已启用',
|
||
disabled: '未启用',
|
||
overview: '总览',
|
||
model: '模型',
|
||
modelConnection: 'OpenAI-compatible 模型连接',
|
||
modelState: '模型状态',
|
||
queue: '队列',
|
||
workers: '活动 / 目标 Worker',
|
||
waiting: '等待恢复',
|
||
pendingMemories: '待整理记忆',
|
||
curatedMemories: '已整理记忆',
|
||
supersededMemories: '已替代记忆',
|
||
activeJobs: '当前任务',
|
||
runNow: '立即整理',
|
||
scope: '范围',
|
||
global: '全局',
|
||
trigger: '触发方式',
|
||
scheduled: '计划执行',
|
||
baseUrl: 'Base URL',
|
||
baseUrlHint: '填写 OpenAI 兼容接口的版本根地址,例如 https://example.com/v1。',
|
||
baseUrlRequired: '请先填写 Base URL',
|
||
textModel: '文本模型',
|
||
visionModel: '视觉模型',
|
||
visionModelHint: '可选;用于需要图像理解的整理任务,留空时不启用视觉探测。',
|
||
protocol: '协议',
|
||
protocolHint: '自动模式会依次探测 Responses 和 Chat Completions。',
|
||
apiToken: 'API Token',
|
||
apiTokenHint: '用于模型接口鉴权;留空时可继续使用已保存的 Token。',
|
||
keepToken: '留空以保留现有 Token',
|
||
timeout: '超时(秒)',
|
||
probeInterval: '探测间隔',
|
||
probeIntervalHint: '模型连接健康探测的时间间隔,单位为秒。',
|
||
managementUrl: '管理地址',
|
||
managementUrlHint: '可选;模型服务的管理页面地址。',
|
||
stream: '使用流式响应',
|
||
testConnection: '测试连接',
|
||
testConnectionHelp:
|
||
'使用当前保存的协议、流式与超时设置,端到端验证:模型列表、文本生成(Responses / Chat Completions)、结构化输出、流式输出和视觉模型(如已配置)。',
|
||
probeRunning: '正在测试模型连接(已进行 {seconds} 秒)',
|
||
probeChecklist:
|
||
'本次依次验证:模型列表 → 文本生成(Responses / Chat Completions)→ 结构化输出 → 流式输出 → 视觉模型(如已配置)。',
|
||
probeLeaveHint: '受超时与重试影响可能需要数分钟;可离开此页面,结果会保留在这里。',
|
||
lastProbe: '最近一次检测:{time}',
|
||
modelSaved: '模型配置已保存',
|
||
modelTested: '模型连接测试完成',
|
||
capabilities: '能力探测',
|
||
schedules: '调度',
|
||
documents: '整理文档',
|
||
history: '任务历史',
|
||
settings: '设置',
|
||
profiles: '记忆空间',
|
||
revision: '修订',
|
||
updatedAt: '更新时间',
|
||
createdAt: '创建时间',
|
||
mode: '模式',
|
||
error: '错误',
|
||
timezone: '时区',
|
||
nextRun: '下次执行',
|
||
maxConcurrency: '最大并发',
|
||
inputTokens: '单次输入 Token 上限',
|
||
outputTokens: '单次输出 Token 上限',
|
||
maxCalls: '单任务最大调用次数',
|
||
maxTokens: '单任务最大 Token',
|
||
batchChars: '单批字符数',
|
||
freshness: 'Agent 来源新鲜度(小时)',
|
||
mergeLevels: '最大合并层级',
|
||
retryInitial: '初始重试间隔(秒)',
|
||
retryMaximum: '最大重试间隔(秒)',
|
||
maxSourceFiles: '单任务最大来源文件数',
|
||
maxSourceChars: '单任务最大提取字符数',
|
||
textFileLimit: '文本文件上限(字节)',
|
||
richFileLimit: '富文档文件上限(字节)',
|
||
policyOverrides: '场景与工作区覆盖',
|
||
policyOverridesHint: '未填写的字段依次继承场景和实例设置。',
|
||
policyScope: '覆盖层级',
|
||
policyScenario: '场景',
|
||
policyWorkspace: '工作区',
|
||
policyTarget: '目标',
|
||
policyValues: '覆盖值',
|
||
policyEdit: '编辑整理策略覆盖',
|
||
policyEmpty: '请至少填写一个覆盖值',
|
||
policyTargetRequired: '请选择工作区',
|
||
policyDuplicate: '该目标已经存在覆盖配置',
|
||
policyEmptyState: '当前全部工作区继承实例设置',
|
||
customTemplate: '自定义整理模板',
|
||
policyFields: {
|
||
context_input_tokens: '输入 Token',
|
||
context_output_tokens: '输出 Token',
|
||
task_max_calls: '最大调用',
|
||
task_max_tokens: '任务 Token',
|
||
batch_chars: '单批字符',
|
||
max_merge_levels: '合并层级',
|
||
max_concurrency: '最大并发',
|
||
source_freshness_hours: '来源新鲜度',
|
||
retry_initial_seconds: '初始重试',
|
||
retry_max_seconds: '最大重试',
|
||
max_source_files: '来源文件',
|
||
max_source_chars: '提取字符',
|
||
text_file_max_bytes: '文本上限',
|
||
rich_file_max_bytes: '富文档上限',
|
||
custom_template: '自定义模板',
|
||
},
|
||
fieldHints: {
|
||
context_input_tokens: '单次模型调用可使用的最大输入 Token 数。',
|
||
context_output_tokens: '单次模型调用允许生成的最大输出 Token 数。',
|
||
task_max_calls: '一个整理任务最多调用模型的次数。',
|
||
task_max_tokens: '一个整理任务累计允许消耗的最大 Token 数。',
|
||
batch_chars: '拆分来源内容时,每批允许包含的最大字符数。',
|
||
max_merge_levels: '分批结果最多进行多少层合并。',
|
||
max_concurrency: '实例同时运行的整理任务数量。',
|
||
source_freshness_hours: 'Agent 提交的来源在多少小时内视为新鲜,过期后可使用其他来源补齐。',
|
||
retry_initial_seconds: '依赖不可用后首次自动重试的等待秒数。',
|
||
retry_max_seconds: '自动重试退避允许达到的最长等待秒数。',
|
||
max_source_files: '单个整理任务最多读取的来源文件数量。',
|
||
max_source_chars: '单个整理任务最多提取的来源字符总数。',
|
||
text_file_max_bytes: '单个纯文本文件允许读取的最大字节数。',
|
||
rich_file_max_bytes: '单个 PDF、Office 等富文档允许读取的最大字节数。',
|
||
},
|
||
settingsSaved: 'AI 整理设置已保存',
|
||
incremental: '增量',
|
||
full: '全量',
|
||
reason: '原因(可选)',
|
||
queueRun: '加入队列',
|
||
queued: '整理任务已加入队列',
|
||
scheduleEdit: '编辑调度规则',
|
||
quiet: '工作区静默',
|
||
fallback: '工作区兜底',
|
||
globalSchedule: '全局整理',
|
||
recurrence: '重复规则',
|
||
quietSeconds: '静默时长',
|
||
quietSecondsHint: '工作区停止变化达到该秒数后执行整理。',
|
||
maxDelaySeconds: '最大延迟',
|
||
maxDelaySecondsHint: '工作区持续变化时,最多延迟多少秒后仍执行;0 表示不限制。',
|
||
inheritance: '项目规则',
|
||
inherit: '继承实例规则',
|
||
override: '覆盖实例规则',
|
||
disableForProject: '对该项目关闭',
|
||
missedPolicy: '错过执行',
|
||
runOnce: '合并补跑一次',
|
||
skipMissed: '跳过',
|
||
interval: '固定间隔',
|
||
daily: '每天',
|
||
weekly: '每周',
|
||
intervalValue: '间隔数值',
|
||
intervalUnit: '间隔单位',
|
||
minutes: '分钟',
|
||
hours: '小时',
|
||
days: '天',
|
||
runTime: '执行时间',
|
||
weekdays: '星期',
|
||
preview: '预览下次执行',
|
||
previewEmpty: '点击预览,查看按当前规则计算的后续执行时间。',
|
||
resetDefaults: '恢复默认调度',
|
||
scheduleResetConfirm: '恢复三个实例调度为默认值?项目覆盖规则不会改变。',
|
||
scheduleReset: '默认调度已恢复',
|
||
intervalAnchor: '间隔锚点(可选)',
|
||
anchorNow: '留空则从保存时间开始',
|
||
profileEdit: '编辑记忆空间',
|
||
profileMemories: '记忆数',
|
||
profileTokens: 'Token 数',
|
||
profileTokenBinding: '绑定 MCP Token',
|
||
lastActivity: '最后活动',
|
||
details: '任务详情',
|
||
cancelJob: '取消任务',
|
||
retryJob: '重新运行',
|
||
retryCurrentConfig: '使用当前配置重试',
|
||
retryOriginalConfig: '使用原配置重试',
|
||
attempts: '执行尝试',
|
||
sources: '来源',
|
||
modelCalls: '模型调用',
|
||
generatedDocuments: '生成文档',
|
||
executionOutput: '执行输出',
|
||
executionProgress: '处理进度',
|
||
autoRefresh: '执行中,自动刷新',
|
||
emptyExecutionOutput: '暂无执行输出',
|
||
executionLevels: {
|
||
info: '信息',
|
||
warning: '警告',
|
||
error: '错误',
|
||
},
|
||
executionPhases: {
|
||
queued: '排队中',
|
||
collecting: '收集来源',
|
||
running: '模型处理中',
|
||
applying: '写入文档',
|
||
waiting_dependency: '等待模型恢复',
|
||
completed: '已完成',
|
||
failed: '失败',
|
||
cancelled: '已取消',
|
||
},
|
||
executionFields: {
|
||
attempt: '尝试',
|
||
total: '总数',
|
||
usable: '可用',
|
||
skipped: '跳过',
|
||
current: '当前',
|
||
level: '层级',
|
||
count: '数量',
|
||
changed: '变化',
|
||
sourceCount: '来源数',
|
||
documentCount: '文档数',
|
||
purpose: '用途',
|
||
code: '代码',
|
||
model: '模型',
|
||
protocol: '协议',
|
||
latency: '耗时',
|
||
inputTokens: '输入 Token',
|
||
outputTokens: '输出 Token',
|
||
elapsedSeconds: '已等待秒数',
|
||
requestAttempts: '请求尝试次数',
|
||
},
|
||
executionMessages: {
|
||
workerRestartedRequeued: '服务重启后已重新排队,将从已保存的来源继续处理',
|
||
documentBatchCompleted: '整理文档批次已生成:{current}/{total}',
|
||
jobStarted: '任务开始,准备收集来源(第 {attempt} 次尝试)',
|
||
sourcesCollected: '来源收集完成:共 {total} 条,{usable} 条将用于整理,{skipped} 条跳过',
|
||
noUsableSources: '没有可供整理的来源,任务无需调用模型',
|
||
noPrimaryChanges: '自上次整理以来没有实质性新变化,任务零调用直接完成',
|
||
batchesPrepared: '来源已拆分为 {total} 个模型输入批次',
|
||
budgetCallsAutoRaised:
|
||
'任务工作量约需 {required} 次调用,超过配置上限 {configured},本次已自动放宽(Token 预算不变)',
|
||
batchCompleted: '证据批次处理完成:{current}/{total}',
|
||
mergeCompleted: '第 {level} 层合并完成:{current}/{total}',
|
||
documentGenerationStarted: '开始生成整理文档,共 {count} 个目标文档',
|
||
modelCallStarted: '开始模型调用:{purpose}',
|
||
modelCallWaiting: '模型仍在处理:{purpose},已等待 {elapsed_seconds} 秒',
|
||
modelCallCompleted:
|
||
'模型调用完成:{purpose},共尝试 {request_attempts} 次,端到端耗时 {latency_ms} ms',
|
||
modelCallCompletedLegacy: '模型调用完成:{purpose},耗时 {latency_ms} ms',
|
||
modelCallFailed: '模型调用失败:{purpose}({code})',
|
||
modelCallCancelled: '模型调用因服务停止或任务取消而结束:{purpose}',
|
||
modelCandidateSwitched: '候选模型切换:{from_model} → {to_model}({code})',
|
||
documentsGenerated: '模型已生成 {count} 个整理文档,准备校验与写入',
|
||
applyingDocuments: '开始写入 {count} 个整理文档',
|
||
documentsApplied: '整理文档写入完成:{changed}/{count} 个发生变化',
|
||
memoryLifecycleUpdated:
|
||
'记忆覆盖状态已更新:{changed_document_count} 个文档变化,{reviewed_count} 条来源被标记已审阅',
|
||
dependencyWaiting: '模型服务暂不可用,任务将等待恢复后自动继续({code})',
|
||
localDependencyWaiting:
|
||
'本地记忆引擎暂不可用,任务将在 {delay_seconds} 秒后自动重试({code})',
|
||
jobCompleted: '任务完成:处理 {source_count} 条来源,生成 {document_count} 个文档',
|
||
jobFailed: '任务失败:{code}',
|
||
},
|
||
sourceDisposition: '处置',
|
||
inputOutputTokens: '输入 / 输出 Token',
|
||
refreshModels: '刷新模型列表',
|
||
outputLanguage: '整理输出语言',
|
||
outputLanguageHint:
|
||
'整理文档正文使用的语言。自动 = 跟随来源的主导语言并保持单份文档一致;指定语言后无论来源语言一律按目标语言书写。',
|
||
outputLanguageAuto: '自动(跟随来源)',
|
||
assignMode: '模型分配',
|
||
assignModeHint: '决定各类整理任务分别使用哪个模型',
|
||
assignUnified: '统一模型',
|
||
assignPerTask: '按任务分配',
|
||
assignUnifiedHint: '所有整理任务使用上方的文本模型,涉及图片的内容使用视觉模型。',
|
||
assignPerTaskHint:
|
||
'为特定任务指定专属模型,留空的任务使用文本模型;模型调用失败会冷却并按顺序尝试通用兜底。保存时按此结构重写候选配置。',
|
||
followPrimary: '跟随文本模型',
|
||
fallbackModels: '通用兜底',
|
||
fallbackModelsHint: '任务模型失败冷却后,按顺序尝试这里的模型',
|
||
fallbackModelsEmpty: '不配置则只使用上方模型',
|
||
candidateCooling: '冷却中',
|
||
candidateCooldown: '失败冷却(秒)',
|
||
candidateCooldownHint: '候选模型调用失败后,在此时间内跳过该模型',
|
||
taskClasses: {
|
||
incremental: '高频增量',
|
||
global: '全局整理',
|
||
development: '开发项目',
|
||
},
|
||
documentSaved: '整理文档已保存',
|
||
documentHistory: '修订历史',
|
||
compare: '对比当前',
|
||
revisionDiff: 'Revision {from} → {to} 差异',
|
||
noDifference: '两个版本内容一致',
|
||
revert: '恢复此版本',
|
||
revertConfirm: '确认把当前文档恢复为 revision {revision}?恢复会生成新的 revision。',
|
||
scheduleDeleteConfirm: '确认删除此调度规则?内置规则会改为关闭。',
|
||
profileDelete: '删除记忆空间',
|
||
profileMigration: '将已有来源和 Token 迁移到',
|
||
historyFilter: '筛选任务历史',
|
||
allStatuses: '全部状态',
|
||
states: {
|
||
disabled: '未启用',
|
||
unconfigured: '未配置',
|
||
checking: '检查中',
|
||
available: '可用',
|
||
degraded: '部分可用',
|
||
unavailable: '不可用',
|
||
error: '异常',
|
||
paused: '已暂停',
|
||
waiting_dependency: '等待服务恢复',
|
||
configuration_error: '配置异常',
|
||
supported: '支持',
|
||
unsupported: '不支持',
|
||
unknown: '未知',
|
||
not_configured: '未配置',
|
||
},
|
||
weekday: {
|
||
0: '周一',
|
||
1: '周二',
|
||
2: '周三',
|
||
3: '周四',
|
||
4: '周五',
|
||
5: '周六',
|
||
6: '周日',
|
||
},
|
||
},
|
||
git: {
|
||
subtitle: '可选的 Markdown 本地版本历史与远程镜像;未启用时不会创建 .git',
|
||
optionalEmpty:
|
||
'记忆 Git 是可选增强。当前未启用,现有记忆仍按 Basic Memory 与 SQLite 流程正常读写。',
|
||
connection: '连接设置',
|
||
repositories: '记忆仓库',
|
||
history: '提交历史',
|
||
filterAuthor: '按提交者筛选',
|
||
filterAction: '操作类型',
|
||
filterProject: '工作区',
|
||
filterResource: '资源 ID',
|
||
filterStart: '开始时间',
|
||
filterEnd: '结束时间',
|
||
enabled: '启用记忆 Git',
|
||
disabled: '未启用',
|
||
mode: '仓库模式',
|
||
single: '单仓库',
|
||
perWorkspace: '每个工作区独立仓库',
|
||
remoteUrl: 'Remote URL(可选)',
|
||
remoteHintSingle: '例如:https://git.example.com/user/memrelay.git',
|
||
remoteHintWorkspace: '必须包含 {repo},例如:https://git.example.com/user/{repo}.git',
|
||
transport: '传输方式',
|
||
username: '用户名',
|
||
credential: 'Token、密码或 SSH 私钥',
|
||
keepCredential: '留空以保留现有凭证',
|
||
credentialStorage: '凭证存储',
|
||
localEncrypted: '本地加密',
|
||
vaultStorage: '外部密码库',
|
||
branch: '默认分支',
|
||
authorName: '提交者名称',
|
||
authorEmail: '提交者邮箱',
|
||
allowWriteTest: '允许写入能力测试',
|
||
allowPushToCreate: '允许首次推送尝试创建远程仓库',
|
||
save: '保存连接',
|
||
test: '测试连接',
|
||
initialize: '初始化本地历史',
|
||
saved: 'Git 设置已保存',
|
||
tested: 'Git 连接测试完成',
|
||
initialized: '本地记忆仓库已初始化',
|
||
status: '仓库状态',
|
||
localPath: '本地目录',
|
||
remote: '远程地址',
|
||
currentCommit: '当前提交',
|
||
pending: '待同步',
|
||
selectRepository: '选择仓库查看历史',
|
||
noRepositories: '尚未初始化任何记忆仓库',
|
||
capability: '连接能力',
|
||
localOnly: '仅本地历史',
|
||
inspectRemote: '检查远程',
|
||
diff: '查看差异',
|
||
deleteConnectionConfirm: '确认删除 Git 连接?已有本地仓库和历史会保留。',
|
||
repositoryDetails: '仓库详情',
|
||
syncNow: '立即同步',
|
||
syncQueued: '同步任务已加入队列',
|
||
unbindRemote: '解除远程绑定',
|
||
unbindConfirm: '确认解除此仓库的 remote 绑定?本地历史会保留。',
|
||
purgeArchive: '永久清除历史',
|
||
purgeConfirm: '确认永久删除此停用项目保留的 Git 历史?此操作不可恢复。',
|
||
remoteInspection: '远程检查结果',
|
||
importRemote: '导入远程历史',
|
||
imported: '远程历史已安全导入',
|
||
bootstrap: '从远程冷启动',
|
||
bootstrapConfirm: '仅应在空恢复实例执行冷启动。确认继续?',
|
||
bootstrapped: '已从远程重建记忆',
|
||
restoreSnapshot: '恢复仓库快照',
|
||
snapshotRestoreConfirm: '确认按此提交恢复整个记忆快照?现有差异会形成新的提交。',
|
||
versionGet: '查看单文档版本',
|
||
restoreVersion: '恢复此文档版本',
|
||
restored: '恢复操作已完成并生成新版本',
|
||
modeMigration: '切换仓库模式',
|
||
modeMigrationHelp:
|
||
'迁移会先归档现有 Git 历史,再按目标模式建立仓库;当前 Markdown 内容不会丢失。',
|
||
currentMode: '当前模式',
|
||
targetMode: '目标模式',
|
||
migrationWarnings: '迁移提示',
|
||
migrationErrors: '无法迁移',
|
||
confirmMigration: '确认迁移',
|
||
modeMigrated: '仓库模式迁移完成',
|
||
enableBeforeMigration: '请先启用当前记忆 Git,再切换已有仓库的模式',
|
||
},
|
||
system: {
|
||
subtitle: '运行参数、管理员密码和完整数据备份',
|
||
runtime: '运行设置',
|
||
publicUrl: '公共 URL',
|
||
fileScanInterval: '文件扫描',
|
||
fileScanIntervalHint: '文件仓储自动扫描间隔,单位为秒;0 表示关闭周期扫描。',
|
||
vaultSyncInterval: '密码库同步',
|
||
vaultSyncIntervalHint: '外部密码库自动同步间隔,单位为秒;0 表示关闭周期同步。',
|
||
contextMaxChars: '上下文长度',
|
||
contextMaxCharsHint: '一次 MCP 上下文响应允许返回的最大字符数。',
|
||
signedUrlTtl: '签名链接',
|
||
signedUrlTtlHint: '文件上传和下载签名地址的有效时间。',
|
||
seconds: '{count} 秒',
|
||
saveSettings: '保存设置',
|
||
adminPassword: '管理员密码',
|
||
currentPassword: '当前密码',
|
||
newPassword: '新密码',
|
||
confirmNewPassword: '确认新密码',
|
||
updatePassword: '更新密码',
|
||
backup: '完整备份与恢复',
|
||
manualBackup: '宿主机手动备份',
|
||
backupHelp:
|
||
'使用仓库中的 PowerShell 或 Shell 脚本短暂停止 Compose,归档整个 /data,并生成版本清单和 SHA-256 校验值。',
|
||
settingsSaved: '设置已保存',
|
||
passwordMismatch: '两次密码不一致',
|
||
passwordUpdated: '密码已更新',
|
||
},
|
||
}
|
||
|
||
const enUS = {
|
||
nav: {
|
||
dashboard: 'Dashboard',
|
||
memories: 'Global Memory',
|
||
projects: 'Projects',
|
||
search: 'Search & Edit',
|
||
progress: 'Progress',
|
||
vault: 'Password Vault',
|
||
files: 'File Repository',
|
||
tokens: 'MCP Tokens',
|
||
clients: 'Client Config',
|
||
prompt: 'Prompt',
|
||
curation: 'AI Curation',
|
||
git: 'Memory Versions',
|
||
system: 'System & Backup',
|
||
},
|
||
common: {
|
||
create: 'Create',
|
||
new: 'New',
|
||
save: 'Save',
|
||
cancel: 'Cancel',
|
||
search: 'Search',
|
||
refresh: 'Refresh',
|
||
edit: 'Edit',
|
||
deactivate: 'Deactivate',
|
||
moveToTrash: 'Move to trash',
|
||
permanentDelete: 'Permanently delete',
|
||
delete: 'Delete',
|
||
copy: 'Copy',
|
||
reveal: 'Reveal',
|
||
download: 'Download',
|
||
close: 'Close',
|
||
status: 'Status',
|
||
actions: 'Actions',
|
||
moreActions: 'More actions',
|
||
name: 'Name',
|
||
description: 'Description',
|
||
version: 'Version',
|
||
tags: 'Tags',
|
||
project: 'Project',
|
||
title: 'Title',
|
||
type: 'Type',
|
||
purpose: 'Purpose',
|
||
size: 'Size',
|
||
none: 'None',
|
||
never: 'Never',
|
||
available: 'Available',
|
||
unavailable: 'Unavailable',
|
||
configured: 'Configured',
|
||
unconfigured: 'Not configured',
|
||
confirmDelete: 'Confirm deletion',
|
||
confirm: 'Confirm',
|
||
confirmDeactivate: 'Confirm deactivation',
|
||
confirmTrash: 'Confirm moving to trash',
|
||
rename: 'Rename',
|
||
back: 'Up one level',
|
||
root: 'Root',
|
||
logout: 'Sign out',
|
||
language: 'Language',
|
||
usageProfile: 'Memory space',
|
||
noData: 'No data',
|
||
enabled: 'Enabled',
|
||
disabled: 'Disabled',
|
||
},
|
||
status: {
|
||
available: 'Available',
|
||
missing: 'Missing',
|
||
vault: {
|
||
unlocked: 'Unlocked',
|
||
cached: 'Offline cache',
|
||
locked: 'Locked',
|
||
connecting: 'Connecting',
|
||
syncing: 'Syncing',
|
||
pending: 'Pending',
|
||
disconnected: 'Disconnected',
|
||
error: 'Connection error',
|
||
},
|
||
},
|
||
memoryTypes: {
|
||
rule: { label: 'Rule', description: 'A firm constraint or workflow that must be followed' },
|
||
preference: {
|
||
label: 'Preference',
|
||
description: 'A personal language, tool, style, or collaboration preference',
|
||
},
|
||
fact: {
|
||
label: 'Fact',
|
||
description: 'Confirmed and relatively stable project or environment information',
|
||
},
|
||
decision: {
|
||
label: 'Decision',
|
||
description: 'A settled technical choice and its important rationale',
|
||
},
|
||
experience: {
|
||
label: 'Experience',
|
||
description: 'A reusable conclusion, diagnostic method, or practice',
|
||
},
|
||
checkpoint: {
|
||
label: 'Checkpoint',
|
||
description: 'Project progress, current state, and next actions at a point in time',
|
||
},
|
||
prd: {
|
||
label: 'PRD',
|
||
description: 'Product goals, user scenarios, requirements, and acceptance criteria',
|
||
},
|
||
task_list: {
|
||
label: 'Task list',
|
||
description: 'Tasks with trackable status, priority, ownership, and completion',
|
||
},
|
||
},
|
||
memoryTemplates: {
|
||
rule: '# Rule\n\n## Scope\n\n## Requirements\n\n- \n\n## Exceptions\n\n- None',
|
||
preference: '# Preference\n\n## Details\n\n- \n\n## Applies to\n\n- ',
|
||
fact: '# Confirmed fact\n\n## Details\n\n\n## Evidence\n\n- ',
|
||
decision: '# Decision\n\n## Outcome\n\n\n## Context and rationale\n\n\n## Impact\n\n- ',
|
||
experience: '# Experience\n\n## Problem\n\n\n## Solution\n\n\n## Reuse conditions\n\n- ',
|
||
checkpoint:
|
||
'# Current progress\n\n## Completed\n\n- [ ] \n\n## Current state\n\n\n## Next actions\n\n- [ ] \n\n## Risks and blockers\n\n- None\n\n## Handoff to the next session\n\n- Unfinished threads: \n- Temporary agreements: \n- Pitfalls to avoid: ',
|
||
prd: '# Product requirements document\n\n## Background and goals\n\n\n## Users and scenarios\n\n\n## Scope\n\n### Functional requirements\n\n- \n\n### Non-functional requirements\n\n- \n\n## Acceptance criteria\n\n- [ ] \n\n## Out of scope\n\n- ',
|
||
task_list:
|
||
'# Task list\n\n## To do\n\n- [ ] \n\n## In progress\n\n- [ ] \n\n## Completed\n\n- [x] ',
|
||
},
|
||
auth: {
|
||
initialize: 'Initialize MemRelay',
|
||
login: 'Sign in to MemRelay',
|
||
username: 'Username',
|
||
password: 'Password',
|
||
confirmPassword: 'Confirm password',
|
||
completeInitialize: 'Complete setup',
|
||
signIn: 'Sign in',
|
||
passwordMismatch: 'The passwords do not match',
|
||
},
|
||
memoryEditor: {
|
||
create: 'Create memory',
|
||
edit: 'Edit memory',
|
||
scope: 'Scope',
|
||
global: 'Global',
|
||
project: 'Project',
|
||
markdown: 'Markdown content',
|
||
mode: 'Editor mode',
|
||
commaTags: 'Separate tags with commas',
|
||
required: 'Title and content are required',
|
||
chooseProject: 'Choose a project',
|
||
saved: 'Memory saved',
|
||
editMode: 'Edit',
|
||
previewMode: 'Preview',
|
||
previewEmpty: 'Nothing to preview yet',
|
||
},
|
||
dashboard: {
|
||
subtitle: 'Current status of the shared workspace and dependencies',
|
||
projects: 'Projects',
|
||
memories: 'Memories',
|
||
checkpoints: 'Checkpoints',
|
||
files: 'Files',
|
||
capacity: 'Repository size',
|
||
activeTokens: 'Active tokens',
|
||
pendingMemories: 'Pending memories',
|
||
curatedMemories: 'Curated memories',
|
||
supersededMemories: 'Superseded memories',
|
||
curatedDocuments: 'Stable curated docs',
|
||
dependencies: 'Dependency status',
|
||
memoryDistribution: 'Memory type distribution',
|
||
projectRanking: 'Project memory ranking',
|
||
recentActivity: 'Recent development activity',
|
||
activityTrend: 'New memory trend',
|
||
last14Days: 'Last 14 days',
|
||
},
|
||
memories: {
|
||
subtitle: 'Rules, preferences, facts, and experience shared across projects',
|
||
updatedAt: 'Updated',
|
||
empty: 'No global memories yet',
|
||
archiveConfirm: 'Move “{title}” to the trash? Its content will be retained.',
|
||
deleteConfirm: 'Permanently delete “{title}”? This action cannot be undone.',
|
||
},
|
||
memoryLifecycle: {
|
||
label: 'Curation state',
|
||
markPending: 'Move back to pending',
|
||
movedToPending: 'Moved back to pending',
|
||
filters: {
|
||
current: 'Current',
|
||
pending: 'Pending',
|
||
covered: 'Curated',
|
||
superseded: 'Superseded',
|
||
checkpoint: 'Checkpoints',
|
||
archived: 'Trash',
|
||
all: 'All',
|
||
},
|
||
labels: {
|
||
current: 'Current',
|
||
pending: 'Pending',
|
||
covered: 'Curated',
|
||
reviewed: 'Reviewed',
|
||
superseded: 'Superseded',
|
||
archived: 'Trash',
|
||
},
|
||
descriptions: {
|
||
current: 'Searches stable curated documents together with new pending sources',
|
||
pending: 'Not explicitly covered by a stable curated document; included by default',
|
||
covered: 'Referenced by a stable curated document; the original Markdown is retained',
|
||
reviewed:
|
||
'Reviewed by the model with nothing left to extract (redundant or no actionable content); the original Markdown is retained',
|
||
superseded: 'Replaced by newer sources; the original Markdown is retained for history',
|
||
checkpoint: 'Session checkpoint snapshots, counted separately from curation coverage',
|
||
archived: 'Moved to trash and excluded from default search and context assembly',
|
||
},
|
||
},
|
||
projects: {
|
||
subtitle: 'Resolve project context from Git remotes, directory aliases, or names',
|
||
create: 'Create project',
|
||
created: 'Project created',
|
||
archived: 'Deactivated',
|
||
empty: 'No projects yet',
|
||
select: 'Select a project on the left',
|
||
emptyMemory: 'This project has no memories',
|
||
archiveConfirm:
|
||
'Deactivate project “{name}”? The project will become inactive, but its data will be retained and can be permanently deleted later.',
|
||
deleteConfirm:
|
||
'Permanently delete deactivated project “{name}” and all its memories? This cannot be undone.',
|
||
deleted: 'Project deleted',
|
||
renamed: 'Project name updated',
|
||
renameTitle: 'Edit project name',
|
||
directoryAliases: 'Device directory aliases',
|
||
oneDirectoryPerLine: 'One directory per line',
|
||
gitRemote: 'Git remote',
|
||
searchPlaceholder: 'Search name, Git remote, or directory',
|
||
downloadDocs: 'Download project docs',
|
||
memoryTab: 'Project memories',
|
||
timelineTab: 'Development timeline',
|
||
emptyTimeline: 'This project has no development checkpoints',
|
||
workspaceType: 'Workspace type',
|
||
workspaceTypeUpdated: 'Workspace type updated',
|
||
curationTemplate: 'Curation template',
|
||
curationTemplateUpdated: 'Project curation template updated',
|
||
curationTemplateHelp:
|
||
'Optional. This is appended to the project prompt only when AI curation is enabled.',
|
||
curationTemplatePlaceholder:
|
||
'Example: preserve experiment IDs, organize conclusions by date, and list unresolved issues.',
|
||
noCurationTemplate:
|
||
'No project-specific template is set. The workspace type default will be used.',
|
||
sourceTab: 'Curation & sources',
|
||
sourceSettings: 'Workspace curation and sources',
|
||
sourceHelp:
|
||
'These settings apply only when AI curation is enabled. Git URL, branch, and credentials are optional.',
|
||
curationEnabled: 'Allow curation for this workspace',
|
||
sourceStrategy: 'Source strategy',
|
||
sourceBranch: 'Source branch',
|
||
sourceCredential: 'Source repository credential',
|
||
noSourceCredential: 'Anonymous access or not configured',
|
||
defaultBranch: 'Detect the default branch',
|
||
lastSourceCommit: 'Last source commit',
|
||
lastSourceFetch: 'Last source refresh',
|
||
lastAgentSync: 'Latest Agent sync',
|
||
sourceState: 'Source status',
|
||
cachedSource: 'Using cached source',
|
||
freshSource: 'Source refreshed',
|
||
notFetched: 'Source has not been read',
|
||
sourceSaved: 'Workspace source settings saved',
|
||
sourceStrategies: {
|
||
auto: 'Automatic',
|
||
mcp: 'Agent/MCP only',
|
||
repository: 'File repository only',
|
||
git: 'Source Git only',
|
||
all: 'All sources',
|
||
},
|
||
workspaceTypes: {
|
||
development: 'Development',
|
||
office: 'Office',
|
||
study: 'Study',
|
||
research: 'Research',
|
||
personal: 'Personal',
|
||
general: 'General',
|
||
},
|
||
},
|
||
search: {
|
||
subtitle: 'Full-text, title, and local multilingual semantic search',
|
||
placeholder: 'Search memories',
|
||
hybrid: 'Hybrid search',
|
||
text: 'Full-text search',
|
||
title: 'Title search',
|
||
semantic: 'Semantic search',
|
||
degraded: 'The semantic model is unavailable; results use full-text search',
|
||
match: 'Matched content',
|
||
relevance: 'Relevance',
|
||
empty: 'Enter keywords to search',
|
||
project: 'Project',
|
||
unknownProject: 'Unknown project',
|
||
curatedDocument: 'Curated document',
|
||
curatedDocumentDescription:
|
||
'The current AI-curated document, available for viewing and editing',
|
||
},
|
||
progress: {
|
||
subtitle: 'Append-only work checkpoints stored by project',
|
||
create: 'Create checkpoint',
|
||
chooseProject: 'Choose a project first',
|
||
empty: 'This project has no checkpoints',
|
||
deleteConfirm: 'Permanently delete checkpoint “{title}”?',
|
||
deleted: 'Checkpoint deleted',
|
||
},
|
||
vault: {
|
||
title: 'External Password Vault',
|
||
subtitle: 'Manage accounts, passwords, tokens, TOTP, and other reusable credentials',
|
||
configure: 'Configure',
|
||
reconfigure: 'Reconfigure',
|
||
syncNow: 'Sync now',
|
||
connectionStatus: 'Connection status',
|
||
serverUrl: 'Server URL',
|
||
account: 'Account',
|
||
loginMethod: 'Login method',
|
||
passwordLogin: 'Email login',
|
||
apiKeyLogin: 'API key',
|
||
lastSync: 'Last sync',
|
||
offlineCache: 'Offline cache',
|
||
queryPlaceholder: 'Service, domain, or credential name',
|
||
noAccount: 'No username',
|
||
username: 'Username',
|
||
password: 'Password',
|
||
notes: 'Notes',
|
||
cached: 'From offline cache',
|
||
selectCredential: 'Select a credential',
|
||
empty: 'No matching password items',
|
||
newItem: 'New item',
|
||
createItem: 'Create password item',
|
||
editItem: 'Edit password item',
|
||
itemName: 'Item name',
|
||
uris: 'Website addresses',
|
||
uriPlaceholder: 'One website address per line',
|
||
totp: 'TOTP secret',
|
||
totpSeed: 'TOTP seed',
|
||
totpSeedHelp: 'Accepts a Base32 TOTP seed or a complete otpauth:// URI.',
|
||
customFields: 'Custom fields',
|
||
addField: 'Add field',
|
||
fieldName: 'Field name',
|
||
fieldValue: 'Field value',
|
||
hiddenField: 'Hidden',
|
||
itemCreated: 'Password item created',
|
||
itemUpdated: 'Password item updated',
|
||
itemDeleted: 'Password item deleted',
|
||
deleteConfirm: 'Delete “{name}”? The item will be moved to the vault trash.',
|
||
dialogTitle: 'Configure external vault',
|
||
httpsUrl: 'HTTP/HTTPS server URL',
|
||
serverUrlPlaceholder: 'https://vault.example.com or http://vault.lan',
|
||
serverUrlHelp: 'HTTP is supported on private networks; use reverse-proxy HTTPS publicly.',
|
||
registeredEmail: 'Registered email',
|
||
clientId: 'Client ID',
|
||
clientSecret: 'Client Secret',
|
||
masterPassword: 'Master password',
|
||
connect: 'Connect and sync',
|
||
connected: 'Password vault connected',
|
||
synced: 'Sync complete',
|
||
copied: 'Copied',
|
||
},
|
||
files: {
|
||
subtitle: 'Searchable shared files, programs, and build resources',
|
||
queryPlaceholder: 'Name, description, version, or purpose',
|
||
scan: 'Scan',
|
||
upload: 'Upload',
|
||
file: 'File',
|
||
directory: 'Directory',
|
||
createDirectory: 'New directory',
|
||
directoryName: 'Directory name',
|
||
currentDirectory: 'Current location',
|
||
openDirectory: 'Open directory',
|
||
empty: 'No files in the repository',
|
||
uploadTitle: 'Upload file',
|
||
storagePath: 'Repository path',
|
||
allowOverwrite: 'Allow overwriting an existing file',
|
||
editMetadata: 'Edit file metadata',
|
||
moveTitle: 'Move or rename',
|
||
newPath: 'New path',
|
||
allowTargetOverwrite: 'Allow overwriting the target file',
|
||
move: 'Move',
|
||
chooseFile: 'Choose a file',
|
||
uploaded: 'Upload complete',
|
||
deleteConfirm: 'Permanently delete “{path}”?',
|
||
scanResult: 'Added {added}, updated {updated}, missing {missing}',
|
||
directoryCreated: 'Directory created',
|
||
directoryNotEmpty: 'The directory is not empty. Remove its contents first.',
|
||
},
|
||
tokens: {
|
||
subtitle: 'Issue revocable read-only or read-write access to devices and clients',
|
||
create: 'Create token',
|
||
createTitle: 'Create MCP token',
|
||
permission: 'Access',
|
||
readWrite: 'Read and write',
|
||
readOnly: 'Read only',
|
||
lastUsed: 'Last used',
|
||
revoked: 'Revoked',
|
||
active: 'Active',
|
||
revoke: 'Revoke',
|
||
namePlaceholder: 'Example: Office Codex',
|
||
copied: 'Token copied',
|
||
revokeConfirm:
|
||
'Revoke “{name}”? The token becomes permanently invalid, while its record is retained.',
|
||
deleteConfirm: 'Permanently delete the token record for “{name}”?',
|
||
confirmRevoke: 'Confirm revocation',
|
||
revokeHint: 'Permanently invalidate the token while retaining its record and last-used time',
|
||
deleteHint:
|
||
'Permanently delete the token record; an active token also becomes invalid immediately',
|
||
usageProfile: 'Memory space',
|
||
usageProfileHint:
|
||
'Controls which personal or team memories this token or Web session can read and write.',
|
||
sharedProfile: 'Shared space',
|
||
allProfiles: 'All memory spaces (includes future spaces)',
|
||
tokenTab: 'MCP tokens',
|
||
profileTab: 'Memory spaces',
|
||
createProfile: 'Create space',
|
||
currentProfile: 'Current Web memory space',
|
||
currentProfileUpdated: 'Current memory space updated',
|
||
profileEdit: 'Edit memory space',
|
||
profileDelete: 'Delete memory space',
|
||
profileMigration: 'Migrate existing data to',
|
||
memories: 'Memories',
|
||
boundTokens: 'Tokens',
|
||
},
|
||
clients: {
|
||
subtitle: 'Generate remote Streamable HTTP MCP client configuration',
|
||
regenerate: 'Regenerate',
|
||
generic: 'Generic HTTP MCP',
|
||
copy: 'Copy configuration',
|
||
empty: 'Create and select an active token first',
|
||
createTokenFirst: 'Create a token first',
|
||
copied: 'Configuration copied',
|
||
},
|
||
prompt: {
|
||
subtitle: 'Agent instructions generated from the current capabilities',
|
||
copied: 'Prompt copied',
|
||
pathCopied: 'Path copied',
|
||
language: 'Prompt language',
|
||
chinese: '中文',
|
||
english: 'English',
|
||
scenarioWorkflow: 'Workflow',
|
||
scenarioNewProject: 'New project',
|
||
scenarioMigration: 'Migrate existing',
|
||
clientColumn: 'Client',
|
||
locationColumn: 'Rule file (repo root)',
|
||
noteColumn: 'Notes',
|
||
locations: {
|
||
cursor:
|
||
'Or .cursor/rules/*.mdc with alwaysApply: true; both are injected into every session automatically',
|
||
codex: 'Global rules live in ~/.codex/AGENTS.md; the project file takes precedence',
|
||
claude: 'Global rules live in ~/.claude/CLAUDE.md; the project file takes precedence',
|
||
vscode:
|
||
'Copilot custom-instructions file; recent versions also read AGENTS.md at the repo root',
|
||
genericClient: 'Other clients',
|
||
generic: 'AGENTS.md is the cross-client de facto standard; try it first for unlisted clients',
|
||
},
|
||
newStep1Title: 'Step 1: create the rule file',
|
||
newStep1Text:
|
||
'Create the rule file for your client at the repository root using the table below. Clients read and inject it into every session automatically, so the AI follows it without extra setup.',
|
||
newStep2Title: 'Step 2: paste the workflow prompt',
|
||
newStep2Text: 'Paste the full prompt below into the file you just created and save it.',
|
||
copyWorkflow: 'Copy workflow prompt',
|
||
newStep3Title: 'Step 3: verify',
|
||
newStep3Text:
|
||
'Start a new session and say "start working". The AI should call capabilities_get and resolve or create the current project; ask it for the MemRelay project ID to confirm.',
|
||
migrationIntro:
|
||
'For projects that already have plenty of code and documentation. Set up the rule file first (see "New project"), then paste the migration prompt below into an AI chat in that project and send it once.',
|
||
migrationHow:
|
||
'The AI resolves the project, reads the existing documentation, distills confirmed rules/facts/decisions/experience into memories, creates a migration baseline checkpoint, verifies searchability, and then continues with the standard workflow. Original documents stay untouched.',
|
||
},
|
||
curation: {
|
||
subtitle: 'Optional unattended curation; all core features work without it',
|
||
optionalEmpty:
|
||
'AI curation is optional. No model is configured, while memory, projects, search, vault, files, and MCP remain fully available.',
|
||
enabled: 'Enabled',
|
||
disabled: 'Disabled',
|
||
overview: 'Overview',
|
||
model: 'Model',
|
||
modelConnection: 'OpenAI-compatible model connection',
|
||
modelState: 'Model state',
|
||
queue: 'Queue',
|
||
workers: 'Active / target workers',
|
||
waiting: 'Waiting',
|
||
pendingMemories: 'Pending memories',
|
||
curatedMemories: 'Curated memories',
|
||
supersededMemories: 'Superseded memories',
|
||
activeJobs: 'Active jobs',
|
||
runNow: 'Run now',
|
||
scope: 'Scope',
|
||
global: 'Global',
|
||
trigger: 'Trigger',
|
||
scheduled: 'Scheduled',
|
||
baseUrl: 'Base URL',
|
||
baseUrlHint: 'OpenAI-compatible version root, for example https://example.com/v1.',
|
||
baseUrlRequired: 'Enter a Base URL first',
|
||
textModel: 'Text model',
|
||
visionModel: 'Vision model',
|
||
visionModelHint:
|
||
'Optional; used for curation tasks that need image understanding. Leave blank to skip vision probing.',
|
||
protocol: 'Protocol',
|
||
protocolHint: 'Auto probes Responses and Chat Completions in order.',
|
||
apiToken: 'API token',
|
||
apiTokenHint:
|
||
'Used to authenticate with the model endpoint; leave blank to reuse the saved token.',
|
||
keepToken: 'Leave blank to keep the current token',
|
||
timeout: 'Timeout (seconds)',
|
||
probeInterval: 'Probe interval',
|
||
probeIntervalHint: 'Interval between model connection health probes, in seconds.',
|
||
managementUrl: 'Management URL',
|
||
managementUrlHint: 'Optional management page URL for the model service.',
|
||
stream: 'Use streaming responses',
|
||
testConnection: 'Test connection',
|
||
testConnectionHelp:
|
||
'Runs an end-to-end check with the saved protocol, streaming, and timeout settings: model list, text generation (Responses / Chat Completions), structured output, streaming output, and the vision model when configured.',
|
||
probeRunning: 'Testing the model connection ({seconds}s elapsed)',
|
||
probeChecklist:
|
||
'This test verifies in order: model list → text generation (Responses / Chat Completions) → structured output → streaming output → vision model (when configured).',
|
||
probeLeaveHint:
|
||
'It may take several minutes depending on timeouts and retries; you can leave this page and the result will stay here.',
|
||
lastProbe: 'Last checked: {time}',
|
||
modelSaved: 'Model settings saved',
|
||
modelTested: 'Model connection test completed',
|
||
capabilities: 'Capabilities',
|
||
schedules: 'Schedules',
|
||
documents: 'Curated documents',
|
||
history: 'Job history',
|
||
settings: 'Settings',
|
||
profiles: 'Memory spaces',
|
||
revision: 'Revision',
|
||
updatedAt: 'Updated',
|
||
createdAt: 'Created',
|
||
mode: 'Mode',
|
||
error: 'Error',
|
||
timezone: 'Timezone',
|
||
nextRun: 'Next run',
|
||
maxConcurrency: 'Maximum concurrency',
|
||
inputTokens: 'Input token limit',
|
||
outputTokens: 'Output token limit',
|
||
maxCalls: 'Calls per job',
|
||
maxTokens: 'Tokens per job',
|
||
batchChars: 'Batch characters',
|
||
freshness: 'Agent source freshness (hours)',
|
||
mergeLevels: 'Maximum merge levels',
|
||
retryInitial: 'Initial retry interval (seconds)',
|
||
retryMaximum: 'Maximum retry interval (seconds)',
|
||
maxSourceFiles: 'Maximum source files per job',
|
||
maxSourceChars: 'Maximum extracted characters per job',
|
||
textFileLimit: 'Text file limit (bytes)',
|
||
richFileLimit: 'Rich document limit (bytes)',
|
||
policyOverrides: 'Scenario and workspace overrides',
|
||
policyOverridesHint: 'Unset values inherit from the scenario and then the instance.',
|
||
policyScope: 'Override level',
|
||
policyScenario: 'Scenario',
|
||
policyWorkspace: 'Workspace',
|
||
policyTarget: 'Target',
|
||
policyValues: 'Override values',
|
||
policyEdit: 'Edit curation policy override',
|
||
policyEmpty: 'Configure at least one override value',
|
||
policyTargetRequired: 'Select a workspace',
|
||
policyDuplicate: 'An override already exists for this target',
|
||
policyEmptyState: 'All workspaces currently inherit the instance settings',
|
||
customTemplate: 'Custom curation template',
|
||
policyFields: {
|
||
context_input_tokens: 'Input tokens',
|
||
context_output_tokens: 'Output tokens',
|
||
task_max_calls: 'Maximum calls',
|
||
task_max_tokens: 'Job tokens',
|
||
batch_chars: 'Batch characters',
|
||
max_merge_levels: 'Merge levels',
|
||
max_concurrency: 'Concurrency',
|
||
source_freshness_hours: 'Source freshness',
|
||
retry_initial_seconds: 'Initial retry',
|
||
retry_max_seconds: 'Maximum retry',
|
||
max_source_files: 'Source files',
|
||
max_source_chars: 'Extracted characters',
|
||
text_file_max_bytes: 'Text limit',
|
||
rich_file_max_bytes: 'Rich document limit',
|
||
custom_template: 'Custom template',
|
||
},
|
||
fieldHints: {
|
||
context_input_tokens: 'Maximum input tokens available to one model call.',
|
||
context_output_tokens: 'Maximum output tokens generated by one model call.',
|
||
task_max_calls: 'Maximum model calls allowed for one curation job.',
|
||
task_max_tokens: 'Maximum cumulative tokens allowed for one curation job.',
|
||
batch_chars: 'Maximum source characters included in each processing batch.',
|
||
max_merge_levels: 'Maximum number of merge levels for batched results.',
|
||
max_concurrency: 'Number of curation jobs that may run at the same time.',
|
||
source_freshness_hours:
|
||
'Hours before Agent-submitted sources are considered stale and may be supplemented.',
|
||
retry_initial_seconds: 'Seconds to wait before the first automatic dependency retry.',
|
||
retry_max_seconds: 'Maximum retry backoff in seconds.',
|
||
max_source_files: 'Maximum source files read by one curation job.',
|
||
max_source_chars: 'Maximum total source characters extracted by one curation job.',
|
||
text_file_max_bytes: 'Maximum bytes read from one plain-text file.',
|
||
rich_file_max_bytes: 'Maximum bytes read from one PDF or Office document.',
|
||
},
|
||
settingsSaved: 'AI curation settings saved',
|
||
incremental: 'Incremental',
|
||
full: 'Full',
|
||
reason: 'Reason (optional)',
|
||
queueRun: 'Queue run',
|
||
queued: 'Curation job queued',
|
||
scheduleEdit: 'Edit schedule',
|
||
quiet: 'Workspace quiet',
|
||
fallback: 'Workspace fallback',
|
||
globalSchedule: 'Global curation',
|
||
recurrence: 'Recurrence',
|
||
quietSeconds: 'Quiet period',
|
||
quietSecondsHint: 'Run after the workspace has stopped changing for this many seconds.',
|
||
maxDelaySeconds: 'Maximum delay',
|
||
maxDelaySecondsHint: 'Run after this many seconds even if changes continue; 0 means unlimited.',
|
||
inheritance: 'Project rule',
|
||
inherit: 'Inherit instance rule',
|
||
override: 'Override instance rule',
|
||
disableForProject: 'Disable for this project',
|
||
missedPolicy: 'Missed runs',
|
||
runOnce: 'Run once',
|
||
skipMissed: 'Skip',
|
||
interval: 'Interval',
|
||
daily: 'Daily',
|
||
weekly: 'Weekly',
|
||
intervalValue: 'Interval value',
|
||
intervalUnit: 'Interval unit',
|
||
minutes: 'Minutes',
|
||
hours: 'Hours',
|
||
days: 'Days',
|
||
runTime: 'Run time',
|
||
weekdays: 'Weekdays',
|
||
preview: 'Preview next runs',
|
||
previewEmpty: 'Preview to see the next run times calculated from the current rule.',
|
||
resetDefaults: 'Restore defaults',
|
||
scheduleResetConfirm:
|
||
'Restore the three instance schedules to their defaults? Workspace overrides are preserved.',
|
||
scheduleReset: 'Default schedules restored',
|
||
intervalAnchor: 'Interval anchor (optional)',
|
||
anchorNow: 'Leave blank to start from the save time',
|
||
profileEdit: 'Edit memory space',
|
||
profileMemories: 'Memories',
|
||
profileTokens: 'Tokens',
|
||
profileTokenBinding: 'Bound MCP tokens',
|
||
lastActivity: 'Last activity',
|
||
details: 'Job details',
|
||
cancelJob: 'Cancel job',
|
||
retryJob: 'Retry job',
|
||
retryCurrentConfig: 'Retry with current config',
|
||
retryOriginalConfig: 'Retry with original config',
|
||
attempts: 'Attempts',
|
||
sources: 'Sources',
|
||
modelCalls: 'Model calls',
|
||
generatedDocuments: 'Generated documents',
|
||
executionOutput: 'Execution output',
|
||
executionProgress: 'Progress',
|
||
autoRefresh: 'Refreshing automatically',
|
||
emptyExecutionOutput: 'No execution output yet',
|
||
executionLevels: {
|
||
info: 'Info',
|
||
warning: 'Warning',
|
||
error: 'Error',
|
||
},
|
||
executionPhases: {
|
||
queued: 'Queued',
|
||
collecting: 'Collecting sources',
|
||
running: 'Processing with model',
|
||
applying: 'Applying documents',
|
||
waiting_dependency: 'Waiting for model recovery',
|
||
completed: 'Completed',
|
||
failed: 'Failed',
|
||
cancelled: 'Cancelled',
|
||
},
|
||
executionFields: {
|
||
attempt: 'Attempt',
|
||
total: 'Total',
|
||
usable: 'Usable',
|
||
skipped: 'Skipped',
|
||
current: 'Current',
|
||
level: 'Level',
|
||
count: 'Count',
|
||
changed: 'Changed',
|
||
sourceCount: 'Sources',
|
||
documentCount: 'Documents',
|
||
purpose: 'Purpose',
|
||
code: 'Code',
|
||
model: 'Model',
|
||
protocol: 'Protocol',
|
||
latency: 'Latency',
|
||
inputTokens: 'Input tokens',
|
||
outputTokens: 'Output tokens',
|
||
elapsedSeconds: 'Elapsed seconds',
|
||
requestAttempts: 'Request attempts',
|
||
},
|
||
executionMessages: {
|
||
workerRestartedRequeued:
|
||
'The service restarted; the job was requeued and will continue from saved sources',
|
||
documentBatchCompleted: 'Curation document batch generated: {current}/{total}',
|
||
jobStarted: 'Job started; preparing source collection (attempt {attempt})',
|
||
sourcesCollected:
|
||
'Source collection completed: {total} total, {usable} usable, {skipped} skipped',
|
||
noUsableSources: 'No usable sources were found; the model was not called',
|
||
noPrimaryChanges:
|
||
'No substantive changes since the last curation; the job completed without model calls',
|
||
batchesPrepared: 'Sources split into {total} model input batches',
|
||
budgetCallsAutoRaised:
|
||
'Workload needs about {required} calls, above the configured cap of {configured}; the cap was raised for this job (token budget unchanged)',
|
||
batchCompleted: 'Evidence batch completed: {current}/{total}',
|
||
mergeCompleted: 'Merge level {level} completed: {current}/{total}',
|
||
documentGenerationStarted: 'Generating {count} target curation documents',
|
||
modelCallStarted: 'Starting model call: {purpose}',
|
||
modelCallWaiting: 'Model is still processing: {purpose}, {elapsed_seconds} seconds elapsed',
|
||
modelCallCompleted:
|
||
'Model call completed: {purpose}, {request_attempts} attempts, {latency_ms} ms end to end',
|
||
modelCallCompletedLegacy: 'Model call completed: {purpose}, {latency_ms} ms',
|
||
modelCallFailed: 'Model call failed: {purpose} ({code})',
|
||
modelCallCancelled: 'Model call ended because the service or job was stopped: {purpose}',
|
||
modelCandidateSwitched: 'Model candidate switched: {from_model} → {to_model} ({code})',
|
||
documentsGenerated: 'Model generated {count} curation documents; validating and applying',
|
||
applyingDocuments: 'Applying {count} curation documents',
|
||
documentsApplied: 'Curation documents applied: {changed}/{count} changed',
|
||
memoryLifecycleUpdated:
|
||
'Memory coverage updated: {changed_document_count} documents changed, {reviewed_count} sources marked reviewed',
|
||
dependencyWaiting:
|
||
'Model service is temporarily unavailable; the job will resume after recovery ({code})',
|
||
localDependencyWaiting:
|
||
'The local memory engine is unavailable; retrying in {delay_seconds} seconds ({code})',
|
||
jobCompleted:
|
||
'Job completed: {source_count} sources processed, {document_count} documents generated',
|
||
jobFailed: 'Job failed: {code}',
|
||
},
|
||
sourceDisposition: 'Disposition',
|
||
inputOutputTokens: 'Input / output tokens',
|
||
refreshModels: 'Refresh models',
|
||
outputLanguage: 'Curation output language',
|
||
outputLanguageHint:
|
||
'Language used for curated document bodies. Auto follows the dominant source language and keeps each document consistent; an explicit choice always writes in that language regardless of the sources.',
|
||
outputLanguageAuto: 'Auto (follow sources)',
|
||
assignMode: 'Model assignment',
|
||
assignModeHint: 'Choose which model serves each kind of curation job',
|
||
assignUnified: 'Unified',
|
||
assignPerTask: 'Per task',
|
||
assignUnifiedHint:
|
||
'Every curation job uses the text model above; image content uses the vision model.',
|
||
assignPerTaskHint:
|
||
'Assign dedicated models to specific jobs; empty slots follow the text model. Failing models cool down and the shared fallbacks are tried in order. Saving rewrites the candidate list in this shape.',
|
||
followPrimary: 'Use the text model',
|
||
fallbackModels: 'Shared fallbacks',
|
||
fallbackModelsHint: 'Tried in order after the job model fails and cools down',
|
||
fallbackModelsEmpty: 'Leave empty to rely on the models above only',
|
||
candidateCooling: 'Cooling',
|
||
candidateCooldown: 'Failure cooldown (seconds)',
|
||
candidateCooldownHint: 'Skip a failed candidate for this long before trying it again',
|
||
taskClasses: {
|
||
incremental: 'Incremental',
|
||
global: 'Global',
|
||
development: 'Development',
|
||
},
|
||
documentSaved: 'Curated document saved',
|
||
documentHistory: 'Revision history',
|
||
compare: 'Compare current',
|
||
revisionDiff: 'Revision {from} → {to} diff',
|
||
noDifference: 'The two revisions are identical',
|
||
revert: 'Restore this revision',
|
||
revertConfirm:
|
||
'Restore the current document from revision {revision}? A new revision will be created.',
|
||
scheduleDeleteConfirm: 'Delete this schedule? Built-in schedules will be disabled.',
|
||
profileDelete: 'Delete memory space',
|
||
profileMigration: 'Migrate existing sources and tokens to',
|
||
historyFilter: 'Filter job history',
|
||
allStatuses: 'All statuses',
|
||
states: {
|
||
disabled: 'Disabled',
|
||
unconfigured: 'Unconfigured',
|
||
checking: 'Checking',
|
||
available: 'Available',
|
||
degraded: 'Degraded',
|
||
unavailable: 'Unavailable',
|
||
error: 'Error',
|
||
paused: 'Paused',
|
||
waiting_dependency: 'Waiting for service',
|
||
configuration_error: 'Configuration error',
|
||
supported: 'Supported',
|
||
unsupported: 'Unsupported',
|
||
unknown: 'Unknown',
|
||
not_configured: 'Not configured',
|
||
},
|
||
weekday: {
|
||
0: 'Mon',
|
||
1: 'Tue',
|
||
2: 'Wed',
|
||
3: 'Thu',
|
||
4: 'Fri',
|
||
5: 'Sat',
|
||
6: 'Sun',
|
||
},
|
||
},
|
||
git: {
|
||
subtitle: 'Optional local Markdown history and remote mirror; no .git is created until enabled',
|
||
optionalEmpty:
|
||
'Memory Git is optional. It is disabled and existing memory continues to use Basic Memory and SQLite normally.',
|
||
connection: 'Connection',
|
||
repositories: 'Memory repositories',
|
||
history: 'Commit history',
|
||
filterAuthor: 'Filter by author',
|
||
filterAction: 'Action',
|
||
filterProject: 'Workspace',
|
||
filterResource: 'Resource ID',
|
||
filterStart: 'Start time',
|
||
filterEnd: 'End time',
|
||
enabled: 'Enable memory Git',
|
||
disabled: 'Disabled',
|
||
mode: 'Repository mode',
|
||
single: 'Single repository',
|
||
perWorkspace: 'Repository per workspace',
|
||
remoteUrl: 'Remote URL (optional)',
|
||
remoteHintSingle: 'Example: https://git.example.com/user/memrelay.git',
|
||
remoteHintWorkspace: 'Must contain {repo}, for example https://git.example.com/user/{repo}.git',
|
||
transport: 'Transport',
|
||
username: 'Username',
|
||
credential: 'Token, password, or SSH private key',
|
||
keepCredential: 'Leave blank to keep the current credential',
|
||
credentialStorage: 'Credential storage',
|
||
localEncrypted: 'Local encrypted storage',
|
||
vaultStorage: 'External vault',
|
||
branch: 'Default branch',
|
||
authorName: 'Author name',
|
||
authorEmail: 'Author email',
|
||
allowWriteTest: 'Allow write capability test',
|
||
allowPushToCreate: 'Allow first push to attempt remote repository creation',
|
||
save: 'Save connection',
|
||
test: 'Test connection',
|
||
initialize: 'Initialize local history',
|
||
saved: 'Git settings saved',
|
||
tested: 'Git connection test completed',
|
||
initialized: 'Local memory repositories initialized',
|
||
status: 'Repository status',
|
||
localPath: 'Local path',
|
||
remote: 'Remote URL',
|
||
currentCommit: 'Current commit',
|
||
pending: 'Pending',
|
||
selectRepository: 'Select a repository to view history',
|
||
noRepositories: 'No memory repositories initialized',
|
||
capability: 'Connection capabilities',
|
||
localOnly: 'Local history only',
|
||
inspectRemote: 'Inspect remote',
|
||
diff: 'View diff',
|
||
deleteConnectionConfirm:
|
||
'Delete the Git connection? Existing local repositories and history will be kept.',
|
||
repositoryDetails: 'Repository details',
|
||
syncNow: 'Sync now',
|
||
syncQueued: 'Sync job queued',
|
||
unbindRemote: 'Unbind remote',
|
||
unbindConfirm: 'Unbind this repository remote? Local history will be kept.',
|
||
purgeArchive: 'Permanently delete history',
|
||
purgeConfirm:
|
||
'Permanently delete the Git history retained for this deactivated project? This cannot be undone.',
|
||
remoteInspection: 'Remote inspection',
|
||
importRemote: 'Import remote history',
|
||
imported: 'Remote history imported safely',
|
||
bootstrap: 'Bootstrap from remote',
|
||
bootstrapConfirm: 'Bootstrap should only run in an empty recovery instance. Continue?',
|
||
bootstrapped: 'Memory rebuilt from remote',
|
||
restoreSnapshot: 'Restore repository snapshot',
|
||
snapshotRestoreConfirm:
|
||
'Restore the full memory snapshot from this commit? Current differences will become a new commit.',
|
||
versionGet: 'View document version',
|
||
restoreVersion: 'Restore this document version',
|
||
restored: 'Restore completed and a new version was created',
|
||
modeMigration: 'Change repository mode',
|
||
modeMigrationHelp:
|
||
'Migration archives existing Git history before creating the target layout. Current Markdown content is preserved.',
|
||
currentMode: 'Current mode',
|
||
targetMode: 'Target mode',
|
||
migrationWarnings: 'Migration notes',
|
||
migrationErrors: 'Cannot migrate',
|
||
confirmMigration: 'Confirm migration',
|
||
modeMigrated: 'Repository mode migration completed',
|
||
enableBeforeMigration: 'Enable the current memory Git connection before changing its mode',
|
||
},
|
||
system: {
|
||
subtitle: 'Runtime settings, administrator password, and complete data backup',
|
||
runtime: 'Runtime settings',
|
||
publicUrl: 'Public URL',
|
||
fileScanInterval: 'File scan',
|
||
fileScanIntervalHint: 'Automatic file repository scan interval in seconds; 0 disables it.',
|
||
vaultSyncInterval: 'Vault sync',
|
||
vaultSyncIntervalHint: 'External vault sync interval in seconds; 0 disables it.',
|
||
contextMaxChars: 'Context size',
|
||
contextMaxCharsHint: 'Maximum characters returned by one MCP context response.',
|
||
signedUrlTtl: 'Signed URL',
|
||
signedUrlTtlHint: 'Lifetime of signed file upload and download URLs.',
|
||
seconds: '{count} seconds',
|
||
saveSettings: 'Save settings',
|
||
adminPassword: 'Administrator password',
|
||
currentPassword: 'Current password',
|
||
newPassword: 'New password',
|
||
confirmNewPassword: 'Confirm new password',
|
||
updatePassword: 'Update password',
|
||
backup: 'Complete backup and restore',
|
||
manualBackup: 'Manual host backup',
|
||
backupHelp:
|
||
'Use the repository PowerShell or Shell script to briefly stop Compose, archive all of /data, and generate a version manifest and SHA-256 checksum.',
|
||
settingsSaved: 'Settings saved',
|
||
passwordMismatch: 'The passwords do not match',
|
||
passwordUpdated: 'Password updated',
|
||
},
|
||
}
|
||
|
||
const locale = localStorage.getItem('memrelay-locale') || 'zh-CN'
|
||
export const i18n = createI18n({
|
||
legacy: false,
|
||
locale,
|
||
fallbackLocale: 'zh-CN',
|
||
messages: { 'zh-CN': zhCN, 'en-US': enUS },
|
||
})
|