feat: multi-OpenClaw CLI detection/binding + i18n infrastructure

Multi-OpenClaw Detection & Binding:
- Add resolve_openclaw_cli_path() and classify_cli_source() in utils.rs
- Support openclawCliPath binding in clawpanel.json (user selects CLI)
- VersionInfo now includes cli_path, cli_source, all_installations
- scan_all_installations() detects all OpenClaw installs on system
- Dashboard shows CLI source label + multi-install warning
- Settings page: CLI binding UI with auto-detect and manual selection
- dev-api.js synced with cli_path/cli_source fields for Web mode

i18n Infrastructure:
- Create src/lib/i18n.js core module (t(), setLang(), initI18n())
- Create src/locales/zh-CN.json and src/locales/en.json
- Sidebar fully i18n-ized (nav labels, sections, instance switcher)
- Dashboard stat cards fully i18n-ized
- Settings page: language switcher UI (live reload)
- initI18n() called in main.js on startup
This commit is contained in:
晴天
2026-03-24 11:57:00 +08:00
parent 7aa13ff7d5
commit 0c062e93e0
12 changed files with 951 additions and 84 deletions

189
src/locales/en.json Normal file
View File

@@ -0,0 +1,189 @@
{
"common": {
"save": "Save",
"cancel": "Cancel",
"confirm": "Confirm",
"delete": "Delete",
"edit": "Edit",
"add": "Add",
"close": "Close",
"loading": "Loading...",
"retry": "Retry",
"copy": "Copy",
"copied": "Copied",
"search": "Search",
"refresh": "Refresh",
"back": "Back",
"submit": "Submit",
"reset": "Reset",
"enabled": "Enabled",
"disabled": "Disabled",
"unknown": "Unknown",
"none": "None",
"yes": "Yes",
"no": "No",
"online": "Online",
"offline": "Offline",
"running": "Running",
"stopped": "Stopped",
"error": "Error",
"success": "Success",
"warning": "Warning",
"info": "Info",
"loadFailed": "Load failed",
"saveFailed": "Save failed",
"saveSuccess": "Saved successfully",
"operationFailed": "Operation failed",
"operationSuccess": "Operation succeeded",
"noData": "No data",
"unit": "",
"survivalRate": "Uptime"
},
"sidebar": {
"collapse": "Collapse / Expand",
"closeMenu": "Close menu",
"themeLight": "Light Mode",
"themeDark": "Dark Mode",
"sectionMonitor": "Monitor",
"sectionConfig": "Config",
"sectionData": "Data",
"sectionExtension": "Extensions",
"dashboard": "Dashboard",
"assistant": "Assistant",
"chat": "Live Chat",
"services": "Services",
"logs": "Logs",
"models": "Models",
"agents": "Agents",
"gateway": "Gateway",
"channels": "Channels",
"communication": "Communication",
"security": "Security",
"memory": "Memory",
"cron": "Cron Jobs",
"usage": "Usage",
"skills": "Skills",
"settings": "Settings",
"chatDebug": "Diagnostics",
"about": "About",
"setup": "Setup"
},
"instance": {
"local": "Local",
"remote": "Remote",
"docker": "Docker",
"switchHint": "After switching, Models, Agents and other pages will manage the selected instance",
"addInstance": "Add Instance",
"addRemote": "Add Remote Instance",
"namePlaceholder": "Remote Server",
"endpointPlaceholder": "http://192.168.1.100:1420",
"nameLabel": "Name",
"endpointLabel": "Panel Address",
"gwPortLabel": "Gateway Port (optional)",
"nameRequired": "Please fill in name and endpoint",
"endpointExists": "This endpoint already exists",
"adding": "Adding...",
"switchedTo": "Switched to {name} — Models, Agents, etc. will manage this instance",
"current": "Active",
"remoteHint": "The remote server must be running ClawPanel (serve.js).",
"example": "Example"
},
"dashboard": {
"title": "Dashboard",
"desc": "OpenClaw runtime status overview",
"gateway": "Gateway",
"portDetect": "Port detection",
"notStarted": "Not started",
"versionLabel": "Version",
"versionOfficial": "Official",
"versionChinese": "Chinese",
"versionUnknown": "Version info unavailable",
"versionAhead": "Current version is ahead of recommended stable {version}, may be unstable",
"versionStable": "Stable {version}",
"versionRecommend": "Recommended stable {version}",
"versionLatest": "Latest upstream {version}",
"agentFleet": "Agent Fleet",
"defaultAgent": "Default",
"modelPool": "Model Pool",
"basedOnProviders": "From {count} providers",
"baseServices": "Services",
"controlUI": "Control UI",
"controlUIDesc": "OpenClaw native panel",
"controlUIClick": "Click to open in browser",
"controlUINotRunning": "Gateway not running",
"restartGw": "Restart Gateway",
"checkUpdate": "Check Updates",
"createBackup": "Create Backup",
"recentLogs": "Recent Logs",
"cliPath": "CLI Path",
"cliSource": "Install Source",
"cliSourceStandalone": "Standalone",
"cliSourceNpmZh": "npm (Chinese)",
"cliSourceNpmOfficial": "npm (Official)",
"cliSourceNpmGlobal": "npm (Global)",
"cliSourceUnknown": "Unknown",
"multiInstall": "Multiple installations detected",
"multiInstallHint": "Choose which one to use in Settings",
"installCount": "{count} installations"
},
"services": {
"title": "Services",
"desc": "Manage OpenClaw Gateway and related services",
"start": "Start",
"stop": "Stop",
"restart": "Restart",
"install": "Install Service",
"uninstall": "Uninstall Service"
},
"settings": {
"title": "Settings",
"desc": "Manage ClawPanel network, proxy and download source settings",
"networkProxy": "Network Proxy",
"modelProxy": "Model Request Proxy",
"npmRegistry": "npm Registry",
"openclawDir": "OpenClaw Install Path",
"openclawCli": "OpenClaw CLI Binding",
"cliAutoDetect": "Auto-detect (Recommended)",
"cliBindHint": "Select which OpenClaw CLI the panel should use, useful when multiple versions coexist",
"cliCurrent": "Currently used",
"cliBound": "Bound",
"cliActive": "Active",
"cliVersion": "Version",
"cliSwitchConfirm": "Switch to this CLI? The panel will use this installation for all operations.",
"language": "Language",
"languageHint": "Switch the interface language. Some content may remain in the original language."
},
"models": {
"title": "Models",
"desc": "Manage AI model providers and model lists"
},
"agents": {
"title": "Agents",
"desc": "Manage AI Agent role configurations"
},
"channels": {
"title": "Channels",
"desc": "Manage messaging channels"
},
"chat": {
"title": "Live Chat",
"desc": "Chat with AI Agents in real-time"
},
"setup": {
"title": "Setup",
"desc": "Install and configure OpenClaw"
},
"about": {
"title": "About",
"desc": "ClawPanel version and project info"
},
"toast": {
"copySuccess": "Copied to clipboard",
"copyFailed": "Copy failed"
},
"modal": {
"confirmTitle": "Confirm",
"confirmOk": "OK",
"confirmCancel": "Cancel"
}
}

189
src/locales/zh-CN.json Normal file
View File

@@ -0,0 +1,189 @@
{
"common": {
"save": "保存",
"cancel": "取消",
"confirm": "确认",
"delete": "删除",
"edit": "编辑",
"add": "添加",
"close": "关闭",
"loading": "加载中...",
"retry": "重试",
"copy": "复制",
"copied": "已复制",
"search": "搜索",
"refresh": "刷新",
"back": "返回",
"submit": "提交",
"reset": "重置",
"enabled": "已启用",
"disabled": "已禁用",
"unknown": "未知",
"none": "无",
"yes": "是",
"no": "否",
"online": "在线",
"offline": "离线",
"running": "运行中",
"stopped": "已停止",
"error": "错误",
"success": "成功",
"warning": "警告",
"info": "提示",
"loadFailed": "加载失败",
"saveFailed": "保存失败",
"saveSuccess": "保存成功",
"operationFailed": "操作失败",
"operationSuccess": "操作成功",
"noData": "暂无数据",
"unit": "个",
"survivalRate": "存活率"
},
"sidebar": {
"collapse": "折叠/展开",
"closeMenu": "关闭菜单",
"themeLight": "日间模式",
"themeDark": "夜间模式",
"sectionMonitor": "监控",
"sectionConfig": "配置",
"sectionData": "数据",
"sectionExtension": "扩展",
"dashboard": "仪表盘",
"assistant": "晴辰助手",
"chat": "实时聊天",
"services": "服务管理",
"logs": "日志查看",
"models": "模型配置",
"agents": "Agent 管理",
"gateway": "Gateway",
"channels": "消息渠道",
"communication": "通信与自动化",
"security": "安全设置",
"memory": "记忆文件",
"cron": "定时任务",
"usage": "使用情况",
"skills": "Skills",
"settings": "面板设置",
"chatDebug": "系统诊断",
"about": "关于",
"setup": "初始设置"
},
"instance": {
"local": "本机",
"remote": "远程",
"docker": "Docker",
"switchHint": "切换后模型配置、Agent 等页面将管理对应实例",
"addInstance": "添加实例",
"addRemote": "添加远程实例",
"namePlaceholder": "远程服务器",
"endpointPlaceholder": "http://192.168.1.100:1420",
"nameLabel": "\u540d\u79f0",
"endpointLabel": "\u9762\u677f\u5730\u5740",
"gwPortLabel": "Gateway \u7aef\u53e3\uff08\u53ef\u9009\uff09",
"nameRequired": "请填写名称和面板地址",
"endpointExists": "该端点已存在",
"adding": "添加中...",
"switchedTo": "已切换到 {name} — 模型配置、Agent 等将管理该实例",
"current": "当前",
"remoteHint": "远程服务器需要运行 ClawPanel (serve.js)。",
"example": "示例"
},
"dashboard": {
"title": "仪表盘",
"desc": "OpenClaw 运行状态概览",
"gateway": "Gateway",
"portDetect": "端口检测",
"notStarted": "未启动",
"versionLabel": "版本",
"versionOfficial": "官方",
"versionChinese": "汉化",
"versionUnknown": "版本信息未获取",
"versionAhead": "当前版本高于推荐稳定版 {version},可能不稳定",
"versionStable": "稳定版 {version}",
"versionRecommend": "推荐稳定版 {version}",
"versionLatest": "最新上游 {version}",
"agentFleet": "Agent 舰队",
"defaultAgent": "默认",
"modelPool": "模型池",
"basedOnProviders": "基于 {count} 个渠道商",
"baseServices": "基础服务",
"controlUI": "Control UI",
"controlUIDesc": "OpenClaw 原生面板",
"controlUIClick": "点击打开浏览器",
"controlUINotRunning": "Gateway 未运行",
"restartGw": "重启 Gateway",
"checkUpdate": "检查更新",
"createBackup": "创建备份",
"recentLogs": "最近日志",
"cliPath": "CLI 路径",
"cliSource": "安装来源",
"cliSourceStandalone": "独立安装版",
"cliSourceNpmZh": "npm 汉化版",
"cliSourceNpmOfficial": "npm 官方版",
"cliSourceNpmGlobal": "npm 全局",
"cliSourceUnknown": "未知来源",
"multiInstall": "检测到多个安装",
"multiInstallHint": "在「面板设置」中可选择使用哪个",
"installCount": "{count} 个安装"
},
"services": {
"title": "服务管理",
"desc": "管理 OpenClaw Gateway 和相关服务",
"start": "启动",
"stop": "停止",
"restart": "重启",
"install": "安装服务",
"uninstall": "卸载服务"
},
"settings": {
"title": "面板设置",
"desc": "管理 ClawPanel 的网络、代理和下载源配置",
"networkProxy": "网络代理",
"modelProxy": "模型请求代理",
"npmRegistry": "npm 源设置",
"openclawDir": "OpenClaw 安装路径",
"openclawCli": "OpenClaw CLI 绑定",
"cliAutoDetect": "自动检测(推荐)",
"cliBindHint": "选择面板实际使用的 OpenClaw CLI适用于多版本共存场景",
"cliCurrent": "当前使用",
"cliBound": "已绑定",
"cliActive": "活跃",
"cliVersion": "版本",
"cliSwitchConfirm": "确定切换到此 CLI 吗?切换后面板将使用该安装进行所有操作。",
"language": "界面语言",
"languageHint": "切换界面显示语言,部分内容可能仍为中文"
},
"models": {
"title": "模型配置",
"desc": "管理 AI 模型供应商和模型列表"
},
"agents": {
"title": "Agent 管理",
"desc": "管理 AI Agent 角色配置"
},
"channels": {
"title": "消息渠道",
"desc": "管理消息接入渠道"
},
"chat": {
"title": "实时聊天",
"desc": "与 AI Agent 实时对话"
},
"setup": {
"title": "初始设置",
"desc": "安装和配置 OpenClaw"
},
"about": {
"title": "关于",
"desc": "ClawPanel 版本和项目信息"
},
"toast": {
"copySuccess": "已复制到剪贴板",
"copyFailed": "复制失败"
},
"modal": {
"confirmTitle": "确认操作",
"confirmOk": "确认",
"confirmCancel": "取消"
}
}