diff --git a/src/components/layout/Sidebar.tsx b/src/components/layout/Sidebar.tsx index e58a19d57..1d5cb9dba 100644 --- a/src/components/layout/Sidebar.tsx +++ b/src/components/layout/Sidebar.tsx @@ -167,7 +167,7 @@ export function Sidebar() { } const navItems = [ - { to: '/models', icon: , label: t('sidebar.models', 'Models') }, + { to: '/models', icon: , label: t('sidebar.models') }, { to: '/channels', icon: , label: t('sidebar.channels') }, { to: '/skills', icon: , label: t('sidebar.skills') }, { to: '/cron', icon: , label: t('sidebar.cronTasks') }, @@ -318,7 +318,7 @@ export function Sidebar() { {!sidebarCollapsed && ( <> - OpenClaw Page + {t('common:sidebar.openClawPage')} )} @@ -327,10 +327,10 @@ export function Sidebar() { { if (!sessionToDelete) return; diff --git a/src/i18n/locales/en/channels.json b/src/i18n/locales/en/channels.json index 5b46244b7..87cbd884e 100644 --- a/src/i18n/locales/en/channels.json +++ b/src/i18n/locales/en/channels.json @@ -9,6 +9,8 @@ "disconnected": "Disconnected" }, "gatewayWarning": "Gateway service is not running. Channels cannot connect.", + "availableChannels": "Available Channels", + "supportedChannels": "Supported Channels", "available": "Available Channels", "availableDesc": "Connect a new channel", "configured": "Configured Channels", diff --git a/src/i18n/locales/en/common.json b/src/i18n/locales/en/common.json index 2522d2d21..a0ed61c8a 100644 --- a/src/i18n/locales/en/common.json +++ b/src/i18n/locales/en/common.json @@ -7,7 +7,10 @@ "channels": "Channels", "dashboard": "Dashboard", "settings": "Settings", - "devConsole": "Developer Console" + "devConsole": "Developer Console", + "models": "Models", + "deleteSessionConfirm": "Are you sure you want to delete session \"{{label}}\"?", + "openClawPage": "OpenClaw Page" }, "actions": { "save": "Save", @@ -52,4 +55,4 @@ "notRunningDesc": "The OpenClaw Gateway needs to be running to use this feature. It will start automatically, or you can start it from Settings.", "warning": "Gateway is not running." } -} +} \ No newline at end of file diff --git a/src/i18n/locales/en/dashboard.json b/src/i18n/locales/en/dashboard.json index 80445fada..a555d8c6a 100644 --- a/src/i18n/locales/en/dashboard.json +++ b/src/i18n/locales/en/dashboard.json @@ -9,6 +9,10 @@ "enabledOf": "{{enabled}} of {{total}} enabled", "sinceRestart": "Since last restart", "gatewayNotRunning": "Gateway not running", + "models": { + "title": "Models", + "subtitle": "Manage your AI providers and monitor token usage." + }, "quickActions": { "title": "Quick Actions", "description": "Common tasks and shortcuts", @@ -53,4 +57,4 @@ "cacheWrite": "Cache write {{value}}", "cost": "Cost ${{amount}}" } -} +} \ No newline at end of file diff --git a/src/i18n/locales/en/setup.json b/src/i18n/locales/en/setup.json index 22c1e87f0..c280e7cb9 100644 --- a/src/i18n/locales/en/setup.json +++ b/src/i18n/locales/en/setup.json @@ -115,5 +115,27 @@ "skipStep": "Skip this step", "skipSetup": "Skip Setup", "getStarted": "Get Started" + }, + "defaultSkills": { + "opencode": { + "name": "OpenCode", + "description": "AI coding assistant backend" + }, + "python-env": { + "name": "Python Environment", + "description": "Python runtime for skills" + }, + "code-assist": { + "name": "Code Assist", + "description": "Code analysis and suggestions" + }, + "file-tools": { + "name": "File Tools", + "description": "File operations and management" + }, + "terminal": { + "name": "Terminal", + "description": "Shell command execution" + } } } \ No newline at end of file diff --git a/src/i18n/locales/en/skills.json b/src/i18n/locales/en/skills.json index 43f252433..4aa6c6253 100644 --- a/src/i18n/locales/en/skills.json +++ b/src/i18n/locales/en/skills.json @@ -48,7 +48,10 @@ "saveConfig": "Save Configuration", "configSaved": "Configuration saved", "openManual": "Open Manual", - "configurable": "Configurable" + "configurable": "Configurable", + "uninstall": "Uninstall", + "enable": "Enable", + "disable": "Disable" }, "toast": { "enabled": "Skill enabled", @@ -83,4 +86,4 @@ "emptyPrompt": "Search for new skills to expand your capabilities.", "searchError": "ClawHub search failed. Check your connection or installation." } -} +} \ No newline at end of file diff --git a/src/i18n/locales/ja/channels.json b/src/i18n/locales/ja/channels.json index eee1174ef..ab240f753 100644 --- a/src/i18n/locales/ja/channels.json +++ b/src/i18n/locales/ja/channels.json @@ -9,6 +9,8 @@ "disconnected": "未接続" }, "gatewayWarning": "ゲートウェイサービスが実行されていないため、チャンネルに接続できません。", + "availableChannels": "利用可能なチャンネル", + "supportedChannels": "サポートされているチャンネル", "available": "利用可能なチャンネル", "availableDesc": "新しいチャンネルを接続", "configured": "設定済みチャンネル", diff --git a/src/i18n/locales/ja/common.json b/src/i18n/locales/ja/common.json index 99d25c990..6784a7425 100644 --- a/src/i18n/locales/ja/common.json +++ b/src/i18n/locales/ja/common.json @@ -7,7 +7,10 @@ "channels": "チャンネル", "dashboard": "ダッシュボード", "settings": "設定", - "devConsole": "開発者コンソール" + "devConsole": "開発者コンソール", + "models": "モデル", + "deleteSessionConfirm": "セッション \"{{label}}\" を削除してもよろしいですか?", + "openClawPage": "OpenClaw ページ" }, "actions": { "save": "保存", @@ -52,4 +55,4 @@ "notRunningDesc": "この機能を使用するには OpenClaw ゲートウェイが実行されている必要があります。自動的に起動するか、設定から起動できます。", "warning": "ゲートウェイが停止中です。" } -} +} \ No newline at end of file diff --git a/src/i18n/locales/ja/dashboard.json b/src/i18n/locales/ja/dashboard.json index 47730d990..59a6c0413 100644 --- a/src/i18n/locales/ja/dashboard.json +++ b/src/i18n/locales/ja/dashboard.json @@ -9,6 +9,10 @@ "enabledOf": "{{total}} 中 {{enabled}} 有効", "sinceRestart": "前回の再起動から", "gatewayNotRunning": "ゲートウェイが停止中", + "models": { + "title": "モデル", + "subtitle": "AI プロバイダーを管理し、トークン使用量を監視します。" + }, "quickActions": { "title": "クイックアクション", "description": "よく使うタスクとショートカット", @@ -53,4 +57,4 @@ "cacheWrite": "キャッシュ書込 {{value}}", "cost": "コスト ${{amount}}" } -} +} \ No newline at end of file diff --git a/src/i18n/locales/ja/setup.json b/src/i18n/locales/ja/setup.json index a199f8558..636410092 100644 --- a/src/i18n/locales/ja/setup.json +++ b/src/i18n/locales/ja/setup.json @@ -115,5 +115,27 @@ "skipStep": "この手順をスキップ", "skipSetup": "セットアップをスキップ", "getStarted": "始める" + }, + "defaultSkills": { + "opencode": { + "name": "OpenCode", + "description": "AI コーディングアシスタントのバックエンド" + }, + "python-env": { + "name": "Python 環境", + "description": "スキルのための Python ランタイム" + }, + "code-assist": { + "name": "コードアシスト", + "description": "コードの分析と提案" + }, + "file-tools": { + "name": "ファイルツール", + "description": "ファイルの操作と管理" + }, + "terminal": { + "name": "ターミナル", + "description": "シェルコマンドの実行" + } } } \ No newline at end of file diff --git a/src/i18n/locales/ja/skills.json b/src/i18n/locales/ja/skills.json index f582e8d99..8a6ff767b 100644 --- a/src/i18n/locales/ja/skills.json +++ b/src/i18n/locales/ja/skills.json @@ -48,7 +48,10 @@ "saveConfig": "設定を保存", "configSaved": "設定を保存しました", "openManual": "マニュアルを開く", - "configurable": "設定可能" + "configurable": "設定可能", + "uninstall": "アンインストール", + "enable": "有効化", + "disable": "無効化" }, "toast": { "enabled": "スキルを有効にしました", @@ -83,4 +86,4 @@ "emptyPrompt": "新しいスキルを検索して機能を拡張しましょう。", "searchError": "ClawHub検索に失敗しました。接続またはインストールを確認してください。" } -} +} \ No newline at end of file diff --git a/src/i18n/locales/zh/channels.json b/src/i18n/locales/zh/channels.json index bdb837070..083b202af 100644 --- a/src/i18n/locales/zh/channels.json +++ b/src/i18n/locales/zh/channels.json @@ -1,6 +1,6 @@ { "title": "消息频道", - "subtitle": "管理您的消息频道和连接", + "subtitle": "连接到消息平台。", "refresh": "刷新", "addChannel": "添加频道", "stats": { @@ -8,7 +8,10 @@ "connected": "已连接", "disconnected": "未连接" }, - "gatewayWarning": "网关服务未运行,频道无法连接。", + "gatewayWarning": "网关未运行。未启用网关时无法管理频道。", + "availableChannels": "可用频道", + "supportedChannels": "支持的频道", + "pluginBadge": "插件", "available": "可用频道", "availableDesc": "连接一个新的频道", "configured": "已配置频道", @@ -16,7 +19,6 @@ "configuredBadge": "已配置", "deleteConfirm": "确定要删除此频道吗?", "showAll": "显示全部", - "pluginBadge": "插件", "toast": { "whatsappConnected": "WhatsApp 连接成功", "whatsappFailed": "WhatsApp 连接失败: {{error}}", diff --git a/src/i18n/locales/zh/common.json b/src/i18n/locales/zh/common.json index f91a84779..418ab75ff 100644 --- a/src/i18n/locales/zh/common.json +++ b/src/i18n/locales/zh/common.json @@ -7,7 +7,10 @@ "channels": "频道", "dashboard": "仪表盘", "settings": "设置", - "devConsole": "开发者控制台" + "devConsole": "开发者控制台", + "models": "模型", + "deleteSessionConfirm": "确定要删除对话 \"{{label}}\" 吗?", + "openClawPage": "OpenClaw 页面" }, "actions": { "save": "保存", @@ -52,4 +55,4 @@ "notRunningDesc": "OpenClaw 网关需要运行才能使用此功能。它将自动启动,或者您可以从设置中启动。", "warning": "网关未运行。" } -} +} \ No newline at end of file diff --git a/src/i18n/locales/zh/dashboard.json b/src/i18n/locales/zh/dashboard.json index 8400ec3ef..3e2e2f796 100644 --- a/src/i18n/locales/zh/dashboard.json +++ b/src/i18n/locales/zh/dashboard.json @@ -9,6 +9,10 @@ "enabledOf": "{{enabled}} / {{total}} 已启用", "sinceRestart": "自上次重启", "gatewayNotRunning": "网关未运行", + "models": { + "title": "模型", + "subtitle": "管理您的 AI 提供商并监控 Token 用量。" + }, "quickActions": { "title": "快捷操作", "description": "常用任务和快捷方式", @@ -53,4 +57,4 @@ "cacheWrite": "缓存写入 {{value}}", "cost": "费用 ${{amount}}" } -} +} \ No newline at end of file diff --git a/src/i18n/locales/zh/setup.json b/src/i18n/locales/zh/setup.json index 733a98dd9..2afa252bd 100644 --- a/src/i18n/locales/zh/setup.json +++ b/src/i18n/locales/zh/setup.json @@ -115,5 +115,27 @@ "skipStep": "跳过此步骤", "skipSetup": "跳过设置", "getStarted": "开始使用" + }, + "defaultSkills": { + "opencode": { + "name": "OpenCode", + "description": "AI 编程助手后端" + }, + "python-env": { + "name": "Python 环境", + "description": "技能所需的 Python 运行时" + }, + "code-assist": { + "name": "代码辅助", + "description": "代码分析与建议" + }, + "file-tools": { + "name": "文件工具", + "description": "文件操作与管理" + }, + "terminal": { + "name": "终端", + "description": "Shell 命令执行" + } } } \ No newline at end of file diff --git a/src/i18n/locales/zh/skills.json b/src/i18n/locales/zh/skills.json index 6bee96b87..7c49be45d 100644 --- a/src/i18n/locales/zh/skills.json +++ b/src/i18n/locales/zh/skills.json @@ -48,7 +48,10 @@ "saveConfig": "保存配置", "configSaved": "配置已保存", "openManual": "打开手册", - "configurable": "可配置" + "configurable": "可配置", + "uninstall": "卸载", + "enable": "启用", + "disable": "禁用" }, "toast": { "enabled": "技能已启用", @@ -83,4 +86,4 @@ "emptyPrompt": "搜索新技能以扩展您的能力。", "searchError": "ClawHub 搜索失败。请检查您的连接或安装。" } -} +} \ No newline at end of file diff --git a/src/pages/Channels/index.tsx b/src/pages/Channels/index.tsx index 22a814b88..92acc8994 100644 --- a/src/pages/Channels/index.tsx +++ b/src/pages/Channels/index.tsx @@ -121,10 +121,10 @@ export function Channels() {

- {t('title') || 'Channels'} + {t('title')}

- {t('subtitle') || 'Connect to messaging platforms.'} + {t('subtitle')}

@@ -170,7 +170,7 @@ export function Channels() { {safeChannels.length > 0 && (

- Available Channels + {t('availableChannels')}

{safeChannels.map((channel) => ( @@ -187,7 +187,7 @@ export function Channels() { {/* Supported Channels (Not yet configured) */}

- Supported Channels + {t('supportedChannels')}

@@ -217,7 +217,7 @@ export function Channels() {

{meta.name}

{meta.isPlugin && ( - {t('pluginBadge', 'Plugin')} + {t('pluginBadge')} )}
diff --git a/src/pages/Models/index.tsx b/src/pages/Models/index.tsx index 89bb2bb1a..c1e387e4a 100644 --- a/src/pages/Models/index.tsx +++ b/src/pages/Models/index.tsx @@ -72,10 +72,10 @@ export function Models() {

- Models + {t('dashboard:models.title')}

- Manage your AI providers and monitor token usage. + {t('dashboard:models.subtitle')}

diff --git a/src/pages/Setup/index.tsx b/src/pages/Setup/index.tsx index 4786b7c34..41e8a8a62 100644 --- a/src/pages/Setup/index.tsx +++ b/src/pages/Setup/index.tsx @@ -29,6 +29,7 @@ import { cn } from '@/lib/utils'; import { useGatewayStore } from '@/stores/gateway'; import { useSettingsStore } from '@/stores/settings'; import { useTranslation } from 'react-i18next'; +import type { TFunction } from 'i18next'; import { SUPPORTED_LANGUAGES } from '@/i18n'; import { toast } from 'sonner'; import { invokeIpc } from '@/lib/api-client'; @@ -48,31 +49,31 @@ const STEP = { COMPLETE: 4, } as const; -const steps: SetupStep[] = [ +const getSteps = (t: TFunction): SetupStep[] => [ { id: 'welcome', - title: 'Welcome to ClawX', - description: 'Your AI assistant is ready to be configured', + title: t('steps.welcome.title'), + description: t('steps.welcome.description'), }, { id: 'runtime', - title: 'Environment Check', - description: 'Verifying system requirements', + title: t('steps.runtime.title'), + description: t('steps.runtime.description'), }, { id: 'provider', - title: 'AI Provider', - description: 'Configure your AI service', + title: t('steps.provider.title'), + description: t('steps.provider.description'), }, { id: 'installing', - title: 'Setting Up', - description: 'Installing essential components', + title: t('steps.installing.title'), + description: t('steps.installing.description'), }, { id: 'complete', - title: 'All Set!', - description: 'ClawX is ready to use', + title: t('steps.complete.title'), + description: t('steps.complete.description'), }, ]; @@ -83,12 +84,12 @@ interface DefaultSkill { description: string; } -const defaultSkills: DefaultSkill[] = [ - { id: 'opencode', name: 'OpenCode', description: 'AI coding assistant backend' }, - { id: 'python-env', name: 'Python Environment', description: 'Python runtime for skills' }, - { id: 'code-assist', name: 'Code Assist', description: 'Code analysis and suggestions' }, - { id: 'file-tools', name: 'File Tools', description: 'File operations and management' }, - { id: 'terminal', name: 'Terminal', description: 'Shell command execution' }, +const getDefaultSkills = (t: TFunction): DefaultSkill[] => [ + { id: 'opencode', name: t('defaultSkills.opencode.name'), description: t('defaultSkills.opencode.description') }, + { id: 'python-env', name: t('defaultSkills.python-env.name'), description: t('defaultSkills.python-env.description') }, + { id: 'code-assist', name: t('defaultSkills.code-assist.name'), description: t('defaultSkills.code-assist.description') }, + { id: 'file-tools', name: t('defaultSkills.file-tools.name'), description: t('defaultSkills.file-tools.description') }, + { id: 'terminal', name: t('defaultSkills.terminal.name'), description: t('defaultSkills.terminal.description') }, ]; import { @@ -130,6 +131,7 @@ export function Setup() { // Runtime check status const [runtimeChecksPassed, setRuntimeChecksPassed] = useState(false); + const steps = getSteps(t); const safeStepIndex = Number.isInteger(currentStep) ? Math.min(Math.max(currentStep, STEP.WELCOME), steps.length - 1) : STEP.WELCOME; @@ -255,7 +257,7 @@ export function Setup() { )} {safeStepIndex === STEP.INSTALLING && ( setCurrentStep((i) => i + 1)} /> @@ -634,10 +636,10 @@ function RuntimeContent({ onStatusChange }: RuntimeContentProps) {
- Gateway Service + {t('runtime.gateway')} {checks.gateway.status === 'error' && ( )}
@@ -665,19 +667,19 @@ function RuntimeContent({ onStatusChange }: RuntimeContentProps) { {showLogs && (
-

Application Logs

+

{t('runtime.logs.title')}

-            {logContent || '(No logs available yet)'}
+            {logContent || t('runtime.logs.noLogs')}
           
)} @@ -1574,9 +1576,9 @@ function CompleteContent({ selectedProvider, installedSkills }: CompleteContentP const gatewayStatus = useGatewayStore((state) => state.status); const providerData = providers.find((p) => p.id === selectedProvider); - const installedSkillNames = defaultSkills - .filter((s) => installedSkills.includes(s.id)) - .map((s) => s.name) + const installedSkillNames = getDefaultSkills(t) + .filter((s: DefaultSkill) => installedSkills.includes(s.id)) + .map((s: DefaultSkill) => s.name) .join(', '); return ( diff --git a/src/pages/Skills/index.tsx b/src/pages/Skills/index.tsx index 10b7919be..78c8bbce4 100644 --- a/src/pages/Skills/index.tsx +++ b/src/pages/Skills/index.tsx @@ -197,7 +197,7 @@ function SkillDetailDialog({ skill, isOpen, onClose, onToggle, onUninstall }: Sk

- API Key + {t('detail.apiKey')}

- Environment Variables + {t('detail.envVars')} {envVars.length > 0 && ( {envVars.length} @@ -298,7 +298,7 @@ function SkillDetailDialog({ skill, isOpen, onClose, onToggle, onUninstall }: Sk )} disabled={isSaving} > - {isSaving ? t('detail.saving', 'Saving...') : 'Save Configuration'} + {isSaving ? t('detail.saving') : t('detail.saveConfig')} )} @@ -316,8 +316,8 @@ function SkillDetailDialog({ skill, isOpen, onClose, onToggle, onUninstall }: Sk }} > {!skill.isBundled && onUninstall - ? 'Uninstall' - : (skill.enabled ? t('detail.disable', 'Disable') : t('detail.enable', 'Enable'))} + ? t('detail.uninstall') + : (skill.enabled ? t('detail.disable') : t('detail.enable'))} )}

@@ -554,10 +554,10 @@ export function Skills() {

- {t('title') || 'Skills'} + {t('title')}

- {t('subtitle') || 'Browse and manage AI capabilities.'} + {t('subtitle')}

@@ -568,7 +568,7 @@ export function Skills() { className="hover:bg-black/5 dark:hover:bg-white/5 transition-colors shrink-0 text-[13px] font-medium px-4 h-8 rounded-full border border-black/10 dark:border-white/10 flex items-center justify-center text-foreground/80 hover:text-foreground" > - Open Skills Folder + {t('openFolder')} )}
@@ -611,22 +611,19 @@ export function Skills() { onClick={() => { setActiveTab('all'); setSelectedSource('all'); }} className={cn("font-medium transition-colors flex items-center gap-1.5", activeTab === 'all' && selectedSource === 'all' ? "text-foreground" : "text-muted-foreground hover:text-foreground")} > - All Skills - {sourceStats.all} + {t('filter.all', { count: sourceStats.all })}
@@ -640,7 +637,7 @@ export function Skills() { onClick={() => bulkToggleVisible(true)} className="h-8 text-[13px] font-medium rounded-md px-3 border-black/10 dark:border-white/10 bg-transparent hover:bg-black/5 dark:hover:bg-white/5 shadow-none" > - Enable All + {t('actions.enableVisible')} )}