汉化
This commit is contained in:
@@ -5,6 +5,7 @@ import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { Toast, ToastContainer } from "@/components/ui/toast";
|
||||
import { useTranslation } from "@/hooks/useTranslation";
|
||||
import { api, type Agent } from "@/lib/api";
|
||||
import { cn } from "@/lib/utils";
|
||||
import MDEditor from "@uiw/react-md-editor";
|
||||
@@ -43,6 +44,7 @@ export const CreateAgent: React.FC<CreateAgentProps> = ({
|
||||
onAgentCreated,
|
||||
className,
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const [name, setName] = useState(agent?.name || "");
|
||||
const [selectedIcon, setSelectedIcon] = useState<AgentIconName>((agent?.icon as AgentIconName) || "bot");
|
||||
const [systemPrompt, setSystemPrompt] = useState(agent?.system_prompt || "");
|
||||
@@ -92,9 +94,9 @@ export const CreateAgent: React.FC<CreateAgentProps> = ({
|
||||
onAgentCreated();
|
||||
} catch (err) {
|
||||
console.error("Failed to save agent:", err);
|
||||
setError(isEditMode ? "Failed to update agent" : "Failed to create agent");
|
||||
setError(isEditMode ? t('agents.updateFailed') : t('agents.createFailed'));
|
||||
setToast({
|
||||
message: isEditMode ? "Failed to update agent" : "Failed to create agent",
|
||||
message: isEditMode ? t('agents.updateFailed') : t('agents.createFailed'),
|
||||
type: "error"
|
||||
});
|
||||
} finally {
|
||||
@@ -108,7 +110,7 @@ export const CreateAgent: React.FC<CreateAgentProps> = ({
|
||||
systemPrompt !== (agent?.system_prompt || "") ||
|
||||
defaultTask !== (agent?.default_task || "") ||
|
||||
model !== (agent?.model || "sonnet")) &&
|
||||
!confirm("You have unsaved changes. Are you sure you want to leave?")) {
|
||||
!confirm(t('messages.unsavedChanges'))) {
|
||||
return;
|
||||
}
|
||||
onBack();
|
||||
@@ -135,10 +137,10 @@ export const CreateAgent: React.FC<CreateAgentProps> = ({
|
||||
</Button>
|
||||
<div>
|
||||
<h2 className="text-lg font-semibold">
|
||||
{isEditMode ? "Edit CC Agent" : "Create CC Agent"}
|
||||
{isEditMode ? t('agents.editAgent') : t('agents.createAgent')}
|
||||
</h2>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
{isEditMode ? "Update your Claude Code agent" : "Create a new Claude Code agent"}
|
||||
{isEditMode ? t('agents.updateAgentDescription') : t('agents.createAgentDescription')}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -153,7 +155,7 @@ export const CreateAgent: React.FC<CreateAgentProps> = ({
|
||||
) : (
|
||||
<Save className="mr-2 h-4 w-4" />
|
||||
)}
|
||||
{saving ? "Saving..." : "Save"}
|
||||
{saving ? t('app.loading') : t('app.save')}
|
||||
</Button>
|
||||
</motion.div>
|
||||
|
||||
|
85
src/components/LanguageSwitcher.tsx
Normal file
85
src/components/LanguageSwitcher.tsx
Normal file
@@ -0,0 +1,85 @@
|
||||
import React from 'react';
|
||||
import { Globe, Check } from 'lucide-react';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
} from '@/components/ui/dropdown-menu';
|
||||
import { useTranslation } from '@/hooks/useTranslation';
|
||||
import { api } from '@/lib/api';
|
||||
import { cn } from '@/lib/utils';
|
||||
|
||||
interface LanguageSwitcherProps {
|
||||
className?: string;
|
||||
showText?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* 语言切换组件
|
||||
*
|
||||
* @example
|
||||
* <LanguageSwitcher />
|
||||
* <LanguageSwitcher showText={true} className="ml-2" />
|
||||
*/
|
||||
export const LanguageSwitcher: React.FC<LanguageSwitcherProps> = ({
|
||||
className,
|
||||
showText = false
|
||||
}) => {
|
||||
const { changeLanguage, currentLanguage, supportedLanguages } = useTranslation();
|
||||
|
||||
const handleLanguageChange = async (languageCode: string) => {
|
||||
try {
|
||||
// 映射前端语言代码到后端格式
|
||||
const backendLocale = languageCode === 'zh' ? 'zh-CN' : 'en-US';
|
||||
|
||||
// 同步到后端
|
||||
await api.setLanguage(backendLocale);
|
||||
|
||||
// 更新前端
|
||||
changeLanguage(languageCode);
|
||||
} catch (error) {
|
||||
console.error('Failed to change language:', error);
|
||||
// 即使后端同步失败,也要尝试更新前端
|
||||
changeLanguage(languageCode);
|
||||
}
|
||||
};
|
||||
|
||||
const getCurrentLanguageDisplay = () => {
|
||||
const currentLang = supportedLanguages.find(lang => lang.code === currentLanguage);
|
||||
return currentLang?.nativeName || currentLanguage.toUpperCase();
|
||||
};
|
||||
|
||||
return (
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
className={cn("gap-2", className)}
|
||||
>
|
||||
<Globe className="h-4 w-4" />
|
||||
{showText && <span className="hidden sm:inline">{getCurrentLanguageDisplay()}</span>}
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="end" className="w-48">
|
||||
{supportedLanguages.map((language) => (
|
||||
<DropdownMenuItem
|
||||
key={language.code}
|
||||
onClick={() => handleLanguageChange(language.code)}
|
||||
className="flex items-center justify-between cursor-pointer"
|
||||
>
|
||||
<div className="flex flex-col">
|
||||
<span className="font-medium">{language.nativeName}</span>
|
||||
<span className="text-xs text-muted-foreground">{language.name}</span>
|
||||
</div>
|
||||
{currentLanguage === language.code && (
|
||||
<Check className="h-4 w-4 text-primary" />
|
||||
)}
|
||||
</DropdownMenuItem>
|
||||
))}
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
);
|
||||
};
|
@@ -3,6 +3,8 @@ import { motion } from "framer-motion";
|
||||
import { Circle, FileText, Settings, ExternalLink, BarChart3, Network, Info, Bot } from "lucide-react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Popover } from "@/components/ui/popover";
|
||||
import { LanguageSwitcher } from "@/components/LanguageSwitcher";
|
||||
import { useTranslation } from "@/hooks/useTranslation";
|
||||
import { api, type ClaudeVersionStatus } from "@/lib/api";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
@@ -57,6 +59,7 @@ export const Topbar: React.FC<TopbarProps> = ({
|
||||
onAgentsClick,
|
||||
className,
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const [versionStatus, setVersionStatus] = useState<ClaudeVersionStatus | null>(null);
|
||||
const [checking, setChecking] = useState(true);
|
||||
|
||||
@@ -130,7 +133,7 @@ export const Topbar: React.FC<TopbarProps> = ({
|
||||
trigger={statusContent}
|
||||
content={
|
||||
<div className="space-y-3 max-w-xs">
|
||||
<p className="text-sm font-medium">Claude Code not found</p>
|
||||
<p className="text-sm font-medium">{t('messages.claudeCodeNotFound')}</p>
|
||||
<div className="rounded-md bg-muted p-3">
|
||||
<pre className="text-xs font-mono whitespace-pre-wrap">
|
||||
{versionStatus.output}
|
||||
@@ -142,7 +145,7 @@ export const Topbar: React.FC<TopbarProps> = ({
|
||||
className="w-full"
|
||||
onClick={onSettingsClick}
|
||||
>
|
||||
Select Claude Installation
|
||||
{t('messages.selectClaudeInstallation')}
|
||||
</Button>
|
||||
<a
|
||||
href="https://www.anthropic.com/claude-code"
|
||||
@@ -150,7 +153,7 @@ export const Topbar: React.FC<TopbarProps> = ({
|
||||
rel="noopener noreferrer"
|
||||
className="flex items-center space-x-1 text-xs text-primary hover:underline"
|
||||
>
|
||||
<span>Install Claude Code</span>
|
||||
<span>{t('messages.installClaudeCode')}</span>
|
||||
<ExternalLink className="h-3 w-3" />
|
||||
</a>
|
||||
</div>
|
||||
@@ -186,7 +189,7 @@ export const Topbar: React.FC<TopbarProps> = ({
|
||||
className="text-xs"
|
||||
>
|
||||
<Bot className="mr-2 h-3 w-3" />
|
||||
Agents
|
||||
{t('navigation.agents')}
|
||||
</Button>
|
||||
)}
|
||||
|
||||
@@ -197,7 +200,7 @@ export const Topbar: React.FC<TopbarProps> = ({
|
||||
className="text-xs"
|
||||
>
|
||||
<BarChart3 className="mr-2 h-3 w-3" />
|
||||
Usage Dashboard
|
||||
{t('navigation.usage')}
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
@@ -217,7 +220,7 @@ export const Topbar: React.FC<TopbarProps> = ({
|
||||
className="text-xs"
|
||||
>
|
||||
<Network className="mr-2 h-3 w-3" />
|
||||
MCP
|
||||
{t('navigation.mcp')}
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
@@ -227,15 +230,18 @@ export const Topbar: React.FC<TopbarProps> = ({
|
||||
className="text-xs"
|
||||
>
|
||||
<Settings className="mr-2 h-3 w-3" />
|
||||
Settings
|
||||
{t('navigation.settings')}
|
||||
</Button>
|
||||
|
||||
{/* Language Switcher */}
|
||||
<LanguageSwitcher />
|
||||
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
onClick={onInfoClick}
|
||||
className="h-8 w-8"
|
||||
title="About"
|
||||
title={t('navigation.about')}
|
||||
>
|
||||
<Info className="h-4 w-4" />
|
||||
</Button>
|
||||
|
@@ -24,3 +24,4 @@ export {
|
||||
useAsyncPerformanceTracker
|
||||
} from './usePerformanceMonitor';
|
||||
export { TAB_SCREEN_NAMES } from './useAnalytics';
|
||||
export { useTranslation, getLanguageDisplayName } from './useTranslation';
|
||||
|
55
src/hooks/useTranslation.ts
Normal file
55
src/hooks/useTranslation.ts
Normal file
@@ -0,0 +1,55 @@
|
||||
import { useTranslation as useI18nTranslation } from 'react-i18next';
|
||||
|
||||
/**
|
||||
* 自定义 i18n Hook,提供类型安全的翻译功能
|
||||
*/
|
||||
export const useTranslation = (namespace?: string) => {
|
||||
const { t, i18n } = useI18nTranslation(namespace || 'common');
|
||||
|
||||
/**
|
||||
* 切换语言
|
||||
* @param language 语言代码 ('en' | 'zh')
|
||||
*/
|
||||
const changeLanguage = (language: string) => {
|
||||
i18n.changeLanguage(language);
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取当前语言
|
||||
*/
|
||||
const currentLanguage = i18n.language;
|
||||
|
||||
/**
|
||||
* 检查是否是中文
|
||||
*/
|
||||
const isChineseLang = currentLanguage.startsWith('zh');
|
||||
|
||||
/**
|
||||
* 获取支持的语言列表
|
||||
*/
|
||||
const supportedLanguages = [
|
||||
{ code: 'en', name: 'English', nativeName: 'English' },
|
||||
{ code: 'zh', name: 'Chinese', nativeName: '中文' },
|
||||
];
|
||||
|
||||
return {
|
||||
t,
|
||||
changeLanguage,
|
||||
currentLanguage,
|
||||
isChineseLang,
|
||||
supportedLanguages,
|
||||
i18n,
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* 语言选择器组件的辅助函数
|
||||
*/
|
||||
export const getLanguageDisplayName = (code: string, displayInNative = false) => {
|
||||
const languages = {
|
||||
en: displayInNative ? 'English' : 'English',
|
||||
zh: displayInNative ? '中文' : 'Chinese',
|
||||
};
|
||||
|
||||
return languages[code as keyof typeof languages] || code;
|
||||
};
|
@@ -1879,5 +1879,49 @@ export const api = {
|
||||
console.error("Failed to delete slash command:", error);
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
|
||||
// ================================
|
||||
// Language Settings
|
||||
// ================================
|
||||
|
||||
/**
|
||||
* Gets the current language setting
|
||||
* @returns Promise resolving to the current language locale
|
||||
*/
|
||||
async getCurrentLanguage(): Promise<string> {
|
||||
try {
|
||||
return await invoke<string>("get_current_language");
|
||||
} catch (error) {
|
||||
console.error("Failed to get current language:", error);
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets the language setting
|
||||
* @param locale - Language locale to set (e.g., 'en-US', 'zh-CN')
|
||||
* @returns Promise resolving when language is set
|
||||
*/
|
||||
async setLanguage(locale: string): Promise<void> {
|
||||
try {
|
||||
await invoke<void>("set_language", { locale });
|
||||
} catch (error) {
|
||||
console.error("Failed to set language:", error);
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the list of supported languages
|
||||
* @returns Promise resolving to array of supported language locales
|
||||
*/
|
||||
async getSupportedLanguages(): Promise<string[]> {
|
||||
try {
|
||||
return await invoke<string[]>("get_supported_languages");
|
||||
} catch (error) {
|
||||
console.error("Failed to get supported languages:", error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
57
src/lib/i18n.ts
Normal file
57
src/lib/i18n.ts
Normal file
@@ -0,0 +1,57 @@
|
||||
import i18n from 'i18next';
|
||||
import { initReactI18next } from 'react-i18next';
|
||||
import LanguageDetector from 'i18next-browser-languagedetector';
|
||||
|
||||
// 引入语言资源文件
|
||||
import en from '@/locales/en/common.json';
|
||||
import zh from '@/locales/zh/common.json';
|
||||
|
||||
// 配置语言检测器
|
||||
const languageDetectorOptions = {
|
||||
// 检测顺序
|
||||
order: ['localStorage', 'navigator', 'htmlTag'],
|
||||
// 缓存语言到localStorage
|
||||
caches: ['localStorage'],
|
||||
// 检查所有可用语言
|
||||
checkWhitelist: true,
|
||||
};
|
||||
|
||||
i18n
|
||||
.use(LanguageDetector)
|
||||
.use(initReactI18next)
|
||||
.init({
|
||||
// 回退语言
|
||||
fallbackLng: 'en',
|
||||
// 调试模式(开发环境)
|
||||
debug: process.env.NODE_ENV === 'development',
|
||||
|
||||
// 语言资源
|
||||
resources: {
|
||||
en: {
|
||||
common: en,
|
||||
},
|
||||
zh: {
|
||||
common: zh,
|
||||
},
|
||||
},
|
||||
|
||||
// 命名空间配置
|
||||
defaultNS: 'common',
|
||||
ns: ['common'],
|
||||
|
||||
// 语言检测选项
|
||||
detection: languageDetectorOptions,
|
||||
|
||||
// 插值配置
|
||||
interpolation: {
|
||||
escapeValue: false, // React 已经默认防止XSS
|
||||
},
|
||||
|
||||
// 白名单支持的语言
|
||||
supportedLngs: ['en', 'zh'],
|
||||
|
||||
// 非显式支持的语言回退到en
|
||||
nonExplicitSupportedLngs: true,
|
||||
});
|
||||
|
||||
export default i18n;
|
156
src/locales/en/common.json
Normal file
156
src/locales/en/common.json
Normal file
@@ -0,0 +1,156 @@
|
||||
{
|
||||
"app": {
|
||||
"name": "Claudia",
|
||||
"welcome": "Welcome to Claudia",
|
||||
"loading": "Loading...",
|
||||
"error": "Error",
|
||||
"success": "Success",
|
||||
"cancel": "Cancel",
|
||||
"save": "Save",
|
||||
"delete": "Delete",
|
||||
"edit": "Edit",
|
||||
"create": "Create",
|
||||
"update": "Update",
|
||||
"remove": "Remove",
|
||||
"add": "Add",
|
||||
"confirm": "Confirm",
|
||||
"back": "Back",
|
||||
"next": "Next",
|
||||
"previous": "Previous",
|
||||
"refresh": "Refresh",
|
||||
"close": "Close",
|
||||
"open": "Open"
|
||||
},
|
||||
"navigation": {
|
||||
"projects": "CC Projects",
|
||||
"agents": "CC Agents",
|
||||
"settings": "Settings",
|
||||
"usage": "Usage Dashboard",
|
||||
"mcp": "MCP Manager",
|
||||
"about": "About"
|
||||
},
|
||||
"projects": {
|
||||
"title": "Projects",
|
||||
"noProjects": "No projects found",
|
||||
"selectProject": "Select a project",
|
||||
"openSession": "Open Session",
|
||||
"newSession": "New Session",
|
||||
"sessions": "Sessions",
|
||||
"noSessions": "No sessions found",
|
||||
"lastModified": "Last Modified",
|
||||
"sessionHistory": "Session History"
|
||||
},
|
||||
"agents": {
|
||||
"title": "CC Agents",
|
||||
"newAgent": "New Agent",
|
||||
"createAgent": "Create Agent",
|
||||
"editAgent": "Edit Agent",
|
||||
"deleteAgent": "Delete Agent",
|
||||
"executeAgent": "Execute Agent",
|
||||
"agentName": "Agent Name",
|
||||
"agentIcon": "Agent Icon",
|
||||
"systemPrompt": "System Prompt",
|
||||
"defaultTask": "Default Task",
|
||||
"model": "Model",
|
||||
"permissions": "Permissions",
|
||||
"fileAccess": "File Access",
|
||||
"networkAccess": "Network Access",
|
||||
"noAgents": "No agents found",
|
||||
"agentCreated": "Agent created successfully",
|
||||
"agentUpdated": "Agent updated successfully",
|
||||
"agentDeleted": "Agent deleted successfully",
|
||||
"confirmDelete": "Are you sure you want to delete this agent?",
|
||||
"executionHistory": "Execution History",
|
||||
"runAgent": "Run Agent",
|
||||
"agentRuns": "Agent Runs",
|
||||
"createAgentDescription": "Create a new Claude Code agent",
|
||||
"updateAgentDescription": "Update your Claude Code agent",
|
||||
"createFailed": "Failed to create agent",
|
||||
"updateFailed": "Failed to update agent"
|
||||
},
|
||||
"settings": {
|
||||
"title": "Settings",
|
||||
"general": "General",
|
||||
"appearance": "Appearance",
|
||||
"language": "Language",
|
||||
"theme": "Theme",
|
||||
"checkpointSettings": "Checkpoint Settings",
|
||||
"autoCheckpoint": "Auto Checkpoint",
|
||||
"checkpointInterval": "Checkpoint Interval",
|
||||
"maxCheckpoints": "Max Checkpoints",
|
||||
"proxySettings": "Proxy Settings",
|
||||
"enableProxy": "Enable Proxy",
|
||||
"httpProxy": "HTTP Proxy",
|
||||
"httpsProxy": "HTTPS Proxy",
|
||||
"noProxy": "No Proxy",
|
||||
"analyticsConsent": "Analytics Consent",
|
||||
"enableAnalytics": "Enable Analytics",
|
||||
"disableAnalytics": "Disable Analytics"
|
||||
},
|
||||
"mcp": {
|
||||
"title": "MCP Server Management",
|
||||
"addServer": "Add Server",
|
||||
"serverName": "Server Name",
|
||||
"serverCommand": "Server Command",
|
||||
"serverArgs": "Server Arguments",
|
||||
"testConnection": "Test Connection",
|
||||
"connectionSuccess": "Connection successful",
|
||||
"connectionFailed": "Connection failed",
|
||||
"importFromClaude": "Import from Claude Desktop",
|
||||
"exportConfig": "Export Configuration",
|
||||
"noServers": "No MCP servers configured"
|
||||
},
|
||||
"usage": {
|
||||
"title": "Usage Dashboard",
|
||||
"totalTokens": "Total Tokens",
|
||||
"totalCost": "Total Cost",
|
||||
"byModel": "By Model",
|
||||
"byProject": "By Project",
|
||||
"byDate": "By Date",
|
||||
"last7Days": "Last 7 Days",
|
||||
"last30Days": "Last 30 Days",
|
||||
"allTime": "All Time",
|
||||
"exportData": "Export Data"
|
||||
},
|
||||
"checkpoint": {
|
||||
"title": "Checkpoints",
|
||||
"createCheckpoint": "Create Checkpoint",
|
||||
"restoreCheckpoint": "Restore Checkpoint",
|
||||
"deleteCheckpoint": "Delete Checkpoint",
|
||||
"checkpointName": "Checkpoint Name",
|
||||
"checkpointMessage": "Checkpoint Message",
|
||||
"timeline": "Timeline",
|
||||
"diff": "Diff",
|
||||
"noCheckpoints": "No checkpoints found"
|
||||
},
|
||||
"placeholders": {
|
||||
"searchProjects": "Search projects...",
|
||||
"searchAgents": "Search agents...",
|
||||
"enterAgentName": "Enter agent name...",
|
||||
"enterSystemPrompt": "Enter system prompt...",
|
||||
"enterDefaultTask": "Enter default task...",
|
||||
"enterURL": "Enter URL...",
|
||||
"searchCommands": "Search commands...",
|
||||
"enterCommand": "Enter command...",
|
||||
"enterDescription": "Enter description..."
|
||||
},
|
||||
"validation": {
|
||||
"required": "This field is required",
|
||||
"invalidEmail": "Invalid email address",
|
||||
"invalidUrl": "Invalid URL",
|
||||
"minLength": "Minimum {{count}} characters required",
|
||||
"maxLength": "Maximum {{count}} characters allowed"
|
||||
},
|
||||
"messages": {
|
||||
"saveSuccess": "Saved successfully",
|
||||
"deleteSuccess": "Deleted successfully",
|
||||
"operationFailed": "Operation failed",
|
||||
"confirmAction": "Are you sure you want to perform this action?",
|
||||
"unsavedChanges": "You have unsaved changes",
|
||||
"networkError": "Network error occurred",
|
||||
"unknownError": "Unknown error occurred",
|
||||
"claudeCodeNotFound": "Claude Code not found",
|
||||
"selectClaudeInstallation": "Select Claude Installation",
|
||||
"installClaudeCode": "Install Claude Code"
|
||||
}
|
||||
}
|
156
src/locales/zh/common.json
Normal file
156
src/locales/zh/common.json
Normal file
@@ -0,0 +1,156 @@
|
||||
{
|
||||
"app": {
|
||||
"name": "Claudia",
|
||||
"welcome": "欢迎使用 Claudia",
|
||||
"loading": "加载中...",
|
||||
"error": "错误",
|
||||
"success": "成功",
|
||||
"cancel": "取消",
|
||||
"save": "保存",
|
||||
"delete": "删除",
|
||||
"edit": "编辑",
|
||||
"create": "创建",
|
||||
"update": "更新",
|
||||
"remove": "移除",
|
||||
"add": "添加",
|
||||
"confirm": "确认",
|
||||
"back": "返回",
|
||||
"next": "下一步",
|
||||
"previous": "上一步",
|
||||
"refresh": "刷新",
|
||||
"close": "关闭",
|
||||
"open": "打开"
|
||||
},
|
||||
"navigation": {
|
||||
"projects": "CC 项目",
|
||||
"agents": "CC 智能体",
|
||||
"settings": "设置",
|
||||
"usage": "用量仪表板",
|
||||
"mcp": "MCP 管理器",
|
||||
"about": "关于"
|
||||
},
|
||||
"projects": {
|
||||
"title": "项目",
|
||||
"noProjects": "未找到项目",
|
||||
"selectProject": "选择项目",
|
||||
"openSession": "打开会话",
|
||||
"newSession": "新建会话",
|
||||
"sessions": "会话",
|
||||
"noSessions": "未找到会话",
|
||||
"lastModified": "最近修改",
|
||||
"sessionHistory": "会话历史"
|
||||
},
|
||||
"agents": {
|
||||
"title": "CC 智能体",
|
||||
"newAgent": "新建智能体",
|
||||
"createAgent": "创建智能体",
|
||||
"editAgent": "编辑智能体",
|
||||
"deleteAgent": "删除智能体",
|
||||
"executeAgent": "执行智能体",
|
||||
"agentName": "智能体名称",
|
||||
"agentIcon": "智能体图标",
|
||||
"systemPrompt": "系统提示",
|
||||
"defaultTask": "默认任务",
|
||||
"model": "模型",
|
||||
"permissions": "权限",
|
||||
"fileAccess": "文件访问",
|
||||
"networkAccess": "网络访问",
|
||||
"noAgents": "未找到智能体",
|
||||
"agentCreated": "智能体创建成功",
|
||||
"agentUpdated": "智能体更新成功",
|
||||
"agentDeleted": "智能体删除成功",
|
||||
"confirmDelete": "确认要删除此智能体吗?",
|
||||
"executionHistory": "执行历史",
|
||||
"runAgent": "运行智能体",
|
||||
"agentRuns": "智能体运行记录",
|
||||
"createAgentDescription": "创建新的 Claude Code 智能体",
|
||||
"updateAgentDescription": "更新您的 Claude Code 智能体",
|
||||
"createFailed": "创建智能体失败",
|
||||
"updateFailed": "更新智能体失败"
|
||||
},
|
||||
"settings": {
|
||||
"title": "设置",
|
||||
"general": "常规",
|
||||
"appearance": "外观",
|
||||
"language": "语言",
|
||||
"theme": "主题",
|
||||
"checkpointSettings": "检查点设置",
|
||||
"autoCheckpoint": "自动检查点",
|
||||
"checkpointInterval": "检查点间隔",
|
||||
"maxCheckpoints": "最大检查点数",
|
||||
"proxySettings": "代理设置",
|
||||
"enableProxy": "启用代理",
|
||||
"httpProxy": "HTTP 代理",
|
||||
"httpsProxy": "HTTPS 代理",
|
||||
"noProxy": "无代理",
|
||||
"analyticsConsent": "分析同意",
|
||||
"enableAnalytics": "启用分析",
|
||||
"disableAnalytics": "禁用分析"
|
||||
},
|
||||
"mcp": {
|
||||
"title": "MCP 服务器管理",
|
||||
"addServer": "添加服务器",
|
||||
"serverName": "服务器名称",
|
||||
"serverCommand": "服务器命令",
|
||||
"serverArgs": "服务器参数",
|
||||
"testConnection": "测试连接",
|
||||
"connectionSuccess": "连接成功",
|
||||
"connectionFailed": "连接失败",
|
||||
"importFromClaude": "从 Claude Desktop 导入",
|
||||
"exportConfig": "导出配置",
|
||||
"noServers": "未配置 MCP 服务器"
|
||||
},
|
||||
"usage": {
|
||||
"title": "用量仪表板",
|
||||
"totalTokens": "总令牌数",
|
||||
"totalCost": "总成本",
|
||||
"byModel": "按模型",
|
||||
"byProject": "按项目",
|
||||
"byDate": "按日期",
|
||||
"last7Days": "最近 7 天",
|
||||
"last30Days": "最近 30 天",
|
||||
"allTime": "全部时间",
|
||||
"exportData": "导出数据"
|
||||
},
|
||||
"checkpoint": {
|
||||
"title": "检查点",
|
||||
"createCheckpoint": "创建检查点",
|
||||
"restoreCheckpoint": "恢复检查点",
|
||||
"deleteCheckpoint": "删除检查点",
|
||||
"checkpointName": "检查点名称",
|
||||
"checkpointMessage": "检查点消息",
|
||||
"timeline": "时间线",
|
||||
"diff": "差异",
|
||||
"noCheckpoints": "未找到检查点"
|
||||
},
|
||||
"placeholders": {
|
||||
"searchProjects": "搜索项目...",
|
||||
"searchAgents": "搜索智能体...",
|
||||
"enterAgentName": "输入智能体名称...",
|
||||
"enterSystemPrompt": "输入系统提示...",
|
||||
"enterDefaultTask": "输入默认任务...",
|
||||
"enterURL": "输入 URL...",
|
||||
"searchCommands": "搜索命令...",
|
||||
"enterCommand": "输入命令...",
|
||||
"enterDescription": "输入描述..."
|
||||
},
|
||||
"validation": {
|
||||
"required": "此字段为必填项",
|
||||
"invalidEmail": "无效的邮箱地址",
|
||||
"invalidUrl": "无效的 URL",
|
||||
"minLength": "至少需要 {{count}} 个字符",
|
||||
"maxLength": "最多允许 {{count}} 个字符"
|
||||
},
|
||||
"messages": {
|
||||
"saveSuccess": "保存成功",
|
||||
"deleteSuccess": "删除成功",
|
||||
"operationFailed": "操作失败",
|
||||
"confirmAction": "确认要执行此操作吗?",
|
||||
"unsavedChanges": "您有未保存的更改",
|
||||
"networkError": "网络错误",
|
||||
"unknownError": "未知错误",
|
||||
"claudeCodeNotFound": "未找到 Claude Code",
|
||||
"selectClaudeInstallation": "选择 Claude 安装",
|
||||
"installClaudeCode": "安装 Claude Code"
|
||||
}
|
||||
}
|
@@ -5,6 +5,7 @@ import { ErrorBoundary } from "./components/ErrorBoundary";
|
||||
import { AnalyticsErrorBoundary } from "./components/AnalyticsErrorBoundary";
|
||||
import { analytics, resourceMonitor } from "./lib/analytics";
|
||||
import { PostHogProvider } from "posthog-js/react";
|
||||
import "./lib/i18n"; // 初始化国际化
|
||||
import "./assets/shimmer.css";
|
||||
import "./styles.css";
|
||||
|
||||
|
Reference in New Issue
Block a user