feat: move dashboard to apps/ so we can share ws proto
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
import { createContext, useContext, useState, useCallback, type ReactNode } from "react";
|
||||
import type { Locale, Translations } from "./types";
|
||||
import { en } from "./en";
|
||||
import { zh } from "./zh";
|
||||
|
||||
const TRANSLATIONS: Record<Locale, Translations> = { en, zh };
|
||||
const STORAGE_KEY = "hermes-locale";
|
||||
|
||||
function getInitialLocale(): Locale {
|
||||
try {
|
||||
const stored = localStorage.getItem(STORAGE_KEY);
|
||||
if (stored === "en" || stored === "zh") return stored;
|
||||
} catch {
|
||||
// SSR or privacy mode
|
||||
}
|
||||
return "en";
|
||||
}
|
||||
|
||||
interface I18nContextValue {
|
||||
locale: Locale;
|
||||
setLocale: (l: Locale) => void;
|
||||
t: Translations;
|
||||
}
|
||||
|
||||
const I18nContext = createContext<I18nContextValue>({
|
||||
locale: "en",
|
||||
setLocale: () => {},
|
||||
t: en,
|
||||
});
|
||||
|
||||
export function I18nProvider({ children }: { children: ReactNode }) {
|
||||
const [locale, setLocaleState] = useState<Locale>(getInitialLocale);
|
||||
|
||||
const setLocale = useCallback((l: Locale) => {
|
||||
setLocaleState(l);
|
||||
try {
|
||||
localStorage.setItem(STORAGE_KEY, l);
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
}, []);
|
||||
|
||||
const value: I18nContextValue = {
|
||||
locale,
|
||||
setLocale,
|
||||
t: TRANSLATIONS[locale],
|
||||
};
|
||||
|
||||
return (
|
||||
<I18nContext.Provider value={value}>
|
||||
{children}
|
||||
</I18nContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
export function useI18n() {
|
||||
return useContext(I18nContext);
|
||||
}
|
||||
@@ -0,0 +1,429 @@
|
||||
import type { Translations } from "./types";
|
||||
|
||||
export const en: Translations = {
|
||||
common: {
|
||||
save: "Save",
|
||||
saving: "Saving...",
|
||||
cancel: "Cancel",
|
||||
close: "Close",
|
||||
confirm: "Confirm",
|
||||
delete: "Delete",
|
||||
refresh: "Refresh",
|
||||
retry: "Retry",
|
||||
search: "Search...",
|
||||
loading: "Loading...",
|
||||
create: "Create",
|
||||
creating: "Creating...",
|
||||
set: "Set",
|
||||
replace: "Replace",
|
||||
clear: "Clear",
|
||||
live: "Live",
|
||||
off: "Off",
|
||||
enabled: "enabled",
|
||||
disabled: "disabled",
|
||||
active: "active",
|
||||
inactive: "inactive",
|
||||
unknown: "unknown",
|
||||
untitled: "Untitled",
|
||||
none: "None",
|
||||
form: "Form",
|
||||
noResults: "No results",
|
||||
of: "of",
|
||||
page: "Page",
|
||||
msgs: "msgs",
|
||||
tools: "tools",
|
||||
match: "match",
|
||||
other: "Other",
|
||||
configured: "configured",
|
||||
removed: "removed",
|
||||
failedToToggle: "Failed to toggle",
|
||||
failedToRemove: "Failed to remove",
|
||||
failedToReveal: "Failed to reveal",
|
||||
collapse: "Collapse",
|
||||
expand: "Expand",
|
||||
general: "General",
|
||||
messaging: "Messaging",
|
||||
pluginLoadFailed:
|
||||
"Could not load this plugin’s script. Check the Network tab (dashboard-plugins/…) and the server’s plugin path.",
|
||||
pluginNotRegistered:
|
||||
"The plugin’s script did not call register(), or the script errored. Open the browser console for details.",
|
||||
},
|
||||
|
||||
app: {
|
||||
brand: "Hermes Agent",
|
||||
brandShort: "HA",
|
||||
closeNavigation: "Close navigation",
|
||||
closeModelTools: "Close model and tools",
|
||||
footer: {
|
||||
org: "Nous Research",
|
||||
},
|
||||
activeSessionsLabel: "Active Sessions:",
|
||||
gatewayStatusLabel: "Gateway Status:",
|
||||
gatewayStrip: {
|
||||
failed: "Start failed",
|
||||
off: "Off",
|
||||
running: "Running",
|
||||
starting: "Starting",
|
||||
stopped: "Stopped",
|
||||
},
|
||||
nav: {
|
||||
analytics: "Analytics",
|
||||
chat: "Chat",
|
||||
config: "Config",
|
||||
cron: "Cron",
|
||||
documentation: "Documentation",
|
||||
keys: "Keys",
|
||||
logs: "Logs",
|
||||
models: "Models",
|
||||
profiles: "profiles : multi agents",
|
||||
plugins: "Plugins",
|
||||
sessions: "Sessions",
|
||||
skills: "Skills",
|
||||
},
|
||||
modelToolsSheetSubtitle: "& tools",
|
||||
modelToolsSheetTitle: "Model",
|
||||
navigation: "Navigation",
|
||||
openDocumentation: "Open documentation in a new tab",
|
||||
openNavigation: "Open navigation",
|
||||
pluginNavSection: "Plugins",
|
||||
sessionsActiveCount: "{count} active",
|
||||
statusOverview: "Status overview",
|
||||
system: "System",
|
||||
webUi: "Web UI",
|
||||
},
|
||||
|
||||
status: {
|
||||
actionFailed: "Action failed",
|
||||
actionFinished: "Finished",
|
||||
actions: "Actions",
|
||||
agent: "Agent",
|
||||
activeSessions: "Active Sessions",
|
||||
connected: "Connected",
|
||||
connectedPlatforms: "Connected Platforms",
|
||||
disconnected: "Disconnected",
|
||||
error: "Error",
|
||||
failed: "Failed",
|
||||
gateway: "Gateway",
|
||||
gatewayFailedToStart: "Gateway failed to start",
|
||||
lastUpdate: "Last update",
|
||||
noneRunning: "None",
|
||||
notRunning: "Not running",
|
||||
pid: "PID",
|
||||
platformDisconnected: "disconnected",
|
||||
platformError: "error",
|
||||
recentSessions: "Recent Sessions",
|
||||
restartGateway: "Restart Gateway",
|
||||
restartingGateway: "Restarting gateway…",
|
||||
running: "Running",
|
||||
runningRemote: "Running (remote)",
|
||||
startFailed: "Start failed",
|
||||
starting: "Starting",
|
||||
startedInBackground: "Started in background — check logs for progress",
|
||||
stopped: "Stopped",
|
||||
updateHermes: "Update Hermes",
|
||||
updatingHermes: "Updating Hermes…",
|
||||
waitingForOutput: "Waiting for output…",
|
||||
},
|
||||
|
||||
sessions: {
|
||||
title: "Sessions",
|
||||
searchPlaceholder: "Search message content...",
|
||||
noSessions: "No sessions yet",
|
||||
noMatch: "No sessions match your search",
|
||||
startConversation: "Start a conversation to see it here",
|
||||
noMessages: "No messages",
|
||||
untitledSession: "Untitled session",
|
||||
deleteSession: "Delete session",
|
||||
confirmDeleteTitle: "Delete session?",
|
||||
confirmDeleteMessage:
|
||||
"This permanently removes the conversation and all of its messages. This cannot be undone.",
|
||||
sessionDeleted: "Session deleted",
|
||||
failedToDelete: "Failed to delete session",
|
||||
resumeInChat: "Resume in Chat",
|
||||
previousPage: "Previous page",
|
||||
nextPage: "Next page",
|
||||
roles: {
|
||||
user: "User",
|
||||
assistant: "Assistant",
|
||||
system: "System",
|
||||
tool: "Tool",
|
||||
},
|
||||
},
|
||||
|
||||
analytics: {
|
||||
period: "Period:",
|
||||
totalTokens: "Total Tokens",
|
||||
totalSessions: "Total Sessions",
|
||||
apiCalls: "API Calls",
|
||||
dailyTokenUsage: "Daily Token Usage",
|
||||
dailyBreakdown: "Daily Breakdown",
|
||||
perModelBreakdown: "Per-Model Breakdown",
|
||||
topSkills: "Top Skills",
|
||||
skill: "Skill",
|
||||
loads: "Agent Loaded",
|
||||
edits: "Agent Managed",
|
||||
lastUsed: "Last Used",
|
||||
input: "Input",
|
||||
output: "Output",
|
||||
total: "Total",
|
||||
noUsageData: "No usage data for this period",
|
||||
startSession: "Start a session to see analytics here",
|
||||
date: "Date",
|
||||
model: "Model",
|
||||
tokens: "Tokens",
|
||||
perDayAvg: "/day avg",
|
||||
acrossModels: "across {count} models",
|
||||
inOut: "{input} in / {output} out",
|
||||
},
|
||||
|
||||
models: {
|
||||
modelsUsed: "Models Used",
|
||||
estimatedCost: "Est. Cost",
|
||||
tokens: "tokens",
|
||||
sessions: "sessions",
|
||||
avgPerSession: "avg/session",
|
||||
apiCalls: "API calls",
|
||||
toolCalls: "tool calls",
|
||||
noModelsData: "No model usage data for this period",
|
||||
startSession: "Start a session to see model data here",
|
||||
},
|
||||
|
||||
logs: {
|
||||
title: "Logs",
|
||||
autoRefresh: "Auto-refresh",
|
||||
file: "File",
|
||||
level: "Level",
|
||||
component: "Component",
|
||||
lines: "Lines",
|
||||
noLogLines: "No log lines found",
|
||||
},
|
||||
|
||||
cron: {
|
||||
confirmDeleteMessage:
|
||||
"This removes the job from the schedule. This cannot be undone.",
|
||||
confirmDeleteTitle: "Delete scheduled job?",
|
||||
newJob: "New Cron Job",
|
||||
nameOptional: "Name (optional)",
|
||||
namePlaceholder: "e.g. Daily summary",
|
||||
prompt: "Prompt",
|
||||
promptPlaceholder: "What should the agent do on each run?",
|
||||
schedule: "Schedule (cron expression)",
|
||||
schedulePlaceholder: "0 9 * * *",
|
||||
deliverTo: "Deliver to",
|
||||
scheduledJobs: "Scheduled Jobs",
|
||||
noJobs: "No cron jobs configured. Create one above.",
|
||||
last: "Last",
|
||||
next: "Next",
|
||||
pause: "Pause",
|
||||
resume: "Resume",
|
||||
triggerNow: "Trigger now",
|
||||
delivery: {
|
||||
local: "Local",
|
||||
telegram: "Telegram",
|
||||
discord: "Discord",
|
||||
slack: "Slack",
|
||||
email: "Email",
|
||||
},
|
||||
},
|
||||
|
||||
profiles: {
|
||||
newProfile: "New Profile",
|
||||
name: "Name",
|
||||
namePlaceholder: "e.g. coder, writer, etc.",
|
||||
nameRequired: "Name is required",
|
||||
nameRule:
|
||||
"Lowercase letters, digits, _ and - only; must start with a letter or digit; up to 64 characters.",
|
||||
invalidName: "Invalid profile name",
|
||||
cloneFromDefault: "Clone config from default profile",
|
||||
allProfiles: "Profiles",
|
||||
noProfiles: "No profiles found.",
|
||||
defaultBadge: "default",
|
||||
hasEnv: "env",
|
||||
model: "Model",
|
||||
skills: "Skills",
|
||||
rename: "Rename",
|
||||
editSoul: "Edit SOUL.md",
|
||||
soulSection: "SOUL.md (personality / system prompt)",
|
||||
soulPlaceholder: "# How this agent should behave…",
|
||||
saveSoul: "Save SOUL",
|
||||
soulSaved: "SOUL.md saved",
|
||||
openInTerminal: "Copy CLI command",
|
||||
commandCopied: "Copied to clipboard",
|
||||
copyFailed: "Could not copy",
|
||||
confirmDeleteTitle: "Delete profile?",
|
||||
confirmDeleteMessage:
|
||||
"This permanently deletes profile '{name}' — config, keys, memories, sessions, skills, cron jobs. Cannot be undone.",
|
||||
created: "Created",
|
||||
deleted: "Deleted",
|
||||
renamed: "Renamed",
|
||||
},
|
||||
|
||||
pluginsPage: {
|
||||
contextEngineLabel: "Context engine",
|
||||
dashboardSlots: "Dashboard slots",
|
||||
disableRuntime: "Disable",
|
||||
enableAfterInstall: "Enable after install",
|
||||
enableRuntime: "Enable",
|
||||
forceReinstall: "Force reinstall (delete existing folder first)",
|
||||
headline:
|
||||
"Discover, install, enable, and update Hermes plugins (`hermes plugins` parity).",
|
||||
identifierLabel: "Git URL or owner/repo",
|
||||
inactive: "inactive",
|
||||
installBtn: "Install from Git",
|
||||
installHeading: "Install from GitHub / Git URL",
|
||||
installHint: "Use owner/repo shorthand or a full https:// or git@ clone URL.",
|
||||
memoryProviderLabel: "Memory provider",
|
||||
missingEnvWarn: "Set these in Keys before the plugin can run:",
|
||||
noDashboardTab: "No dashboard tab",
|
||||
openTab: "Open",
|
||||
orphanHeading: "Dashboard-only extensions (no agent plugin.yaml match)",
|
||||
pluginListHeading: "Installed plugins",
|
||||
providerDefaults: "built-in / default",
|
||||
providersHeading: "Runtime provider plugins",
|
||||
providersHint:
|
||||
"Writes memory.provider (empty = built-in) and context.engine to config.yaml. Takes effect next session.",
|
||||
refreshDashboard: "Rescan dashboard extensions",
|
||||
removeConfirm: "Remove this plugin from ~/.hermes/plugins/?",
|
||||
removeHint: "Only user-installed plugins under ~/.hermes/plugins can be removed.",
|
||||
rescanHeading: "SPA plugin registry",
|
||||
rescanHint: "Rescan after adding files on disk so the dashboard sidebar picks up new manifests.",
|
||||
runtimeHeading: "Gateway runtime (YAML plugins)",
|
||||
saveProviders: "Save provider settings",
|
||||
savedProviders: "Provider settings saved.",
|
||||
sourceBadge: "Source",
|
||||
authRequired: "Auth required",
|
||||
authRequiredHint: "Run this command to authenticate:",
|
||||
updateGit: "Git pull",
|
||||
versionBadge: "Version",
|
||||
showInSidebar: "Show in sidebar",
|
||||
hideFromSidebar: "Hide from sidebar",
|
||||
},
|
||||
|
||||
skills: {
|
||||
title: "Skills",
|
||||
searchPlaceholder: "Search skills and toolsets...",
|
||||
enabledOf: "{enabled}/{total} enabled",
|
||||
all: "All",
|
||||
categories: "Categories",
|
||||
filters: "Filters",
|
||||
noSkills: "No skills found. Skills are loaded from ~/.hermes/skills/",
|
||||
noSkillsMatch: "No skills match your search or filter.",
|
||||
skillCount: "{count} skill{s}",
|
||||
resultCount: "{count} result{s}",
|
||||
noDescription: "No description available.",
|
||||
toolsets: "Toolsets",
|
||||
toolsetLabel: "{name} toolset",
|
||||
noToolsetsMatch: "No toolsets match the search.",
|
||||
setupNeeded: "Setup needed",
|
||||
disabledForCli: "Disabled for CLI",
|
||||
more: "+{count} more",
|
||||
},
|
||||
|
||||
config: {
|
||||
configPath: "~/.hermes/config.yaml",
|
||||
filters: "Filters",
|
||||
sections: "Sections",
|
||||
exportConfig: "Export config as JSON",
|
||||
importConfig: "Import config from JSON",
|
||||
resetDefaults: "Reset to defaults",
|
||||
resetScopeTooltip: "Reset {scope} to defaults",
|
||||
confirmResetScope: "Reset all {scope} settings to their defaults? This only updates the form — changes aren't written to config.yaml until you press Save.",
|
||||
resetScopeToast: "{scope} reset to defaults — review and Save to persist",
|
||||
rawYaml: "Raw YAML Configuration",
|
||||
searchResults: "Search Results",
|
||||
fields: "field{s}",
|
||||
noFieldsMatch: 'No fields match "{query}"',
|
||||
configSaved: "Configuration saved",
|
||||
yamlConfigSaved: "YAML config saved",
|
||||
failedToSave: "Failed to save",
|
||||
failedToSaveYaml: "Failed to save YAML",
|
||||
failedToLoadRaw: "Failed to load raw config",
|
||||
configImported: "Config imported — review and save",
|
||||
invalidJson: "Invalid JSON file",
|
||||
categories: {
|
||||
general: "General",
|
||||
agent: "Agent",
|
||||
terminal: "Terminal",
|
||||
display: "Display",
|
||||
delegation: "Delegation",
|
||||
memory: "Memory",
|
||||
compression: "Compression",
|
||||
security: "Security",
|
||||
browser: "Browser",
|
||||
voice: "Voice",
|
||||
tts: "Text-to-Speech",
|
||||
stt: "Speech-to-Text",
|
||||
logging: "Logging",
|
||||
discord: "Discord",
|
||||
auxiliary: "Auxiliary",
|
||||
},
|
||||
},
|
||||
|
||||
env: {
|
||||
changesNote: "Changes are saved to disk immediately. Active sessions pick up new keys automatically.",
|
||||
confirmClearMessage:
|
||||
"The stored value for this variable will be removed from your .env file. This cannot be undone from the UI.",
|
||||
confirmClearTitle: "Clear this key?",
|
||||
description: "Manage API keys and secrets stored in",
|
||||
hideAdvanced: "Hide Advanced",
|
||||
showAdvanced: "Show Advanced",
|
||||
llmProviders: "LLM Providers",
|
||||
providersConfigured: "{configured} of {total} providers configured",
|
||||
getKey: "Get key",
|
||||
notConfigured: "{count} not configured",
|
||||
notSet: "Not set",
|
||||
keysCount: "{count} key{s}",
|
||||
enterValue: "Enter value...",
|
||||
replaceCurrentValue: "Replace current value ({preview})",
|
||||
showValue: "Show real value",
|
||||
hideValue: "Hide value",
|
||||
},
|
||||
|
||||
oauth: {
|
||||
title: "Provider Logins (OAuth)",
|
||||
providerLogins: "Provider Logins (OAuth)",
|
||||
description: "{connected} of {total} OAuth providers connected. Login flows currently run via the CLI; click Copy command and paste into a terminal to set up.",
|
||||
connected: "Connected",
|
||||
expired: "Expired",
|
||||
notConnected: "Not connected. Run {command} in a terminal.",
|
||||
runInTerminal: "in a terminal.",
|
||||
noProviders: "No OAuth-capable providers detected.",
|
||||
login: "Login",
|
||||
disconnect: "Disconnect",
|
||||
managedExternally: "Managed externally",
|
||||
copied: "Copied ✓",
|
||||
cli: "CLI",
|
||||
copyCliCommand: "Copy CLI command (for external / fallback)",
|
||||
connect: "Connect",
|
||||
sessionExpires: "Session expires in {time}",
|
||||
initiatingLogin: "Initiating login flow…",
|
||||
exchangingCode: "Exchanging code for tokens…",
|
||||
connectedClosing: "Connected! Closing…",
|
||||
loginFailed: "Login failed.",
|
||||
sessionExpired: "Session expired. Click Retry to start a new login.",
|
||||
reOpenAuth: "Re-open auth page",
|
||||
reOpenVerification: "Re-open verification page",
|
||||
submitCode: "Submit code",
|
||||
pasteCode: "Paste authorization code (with #state suffix is fine)",
|
||||
waitingAuth: "Waiting for you to authorize in the browser…",
|
||||
enterCodePrompt: "A new tab opened. Enter this code if prompted:",
|
||||
pkceStep1: "A new tab opened to claude.ai. Sign in and click Authorize.",
|
||||
pkceStep2: "Copy the authorization code shown after authorizing.",
|
||||
pkceStep3: "Paste it below and submit.",
|
||||
flowLabels: {
|
||||
pkce: "Browser login (PKCE)",
|
||||
device_code: "Device code",
|
||||
external: "External CLI",
|
||||
},
|
||||
expiresIn: "expires in {time}",
|
||||
},
|
||||
|
||||
language: {
|
||||
switchTo: "Switch to Chinese",
|
||||
},
|
||||
|
||||
theme: {
|
||||
title: "Theme",
|
||||
switchTheme: "Switch theme",
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,2 @@
|
||||
export { I18nProvider, useI18n } from "./context";
|
||||
export type { Locale, Translations } from "./types";
|
||||
@@ -0,0 +1,436 @@
|
||||
export type Locale = "en" | "zh";
|
||||
|
||||
export interface Translations {
|
||||
// ── Common ──
|
||||
common: {
|
||||
save: string;
|
||||
saving: string;
|
||||
cancel: string;
|
||||
close: string;
|
||||
confirm: string;
|
||||
delete: string;
|
||||
refresh: string;
|
||||
retry: string;
|
||||
search: string;
|
||||
loading: string;
|
||||
create: string;
|
||||
creating: string;
|
||||
set: string;
|
||||
replace: string;
|
||||
clear: string;
|
||||
live: string;
|
||||
off: string;
|
||||
enabled: string;
|
||||
disabled: string;
|
||||
active: string;
|
||||
inactive: string;
|
||||
unknown: string;
|
||||
untitled: string;
|
||||
none: string;
|
||||
form: string;
|
||||
noResults: string;
|
||||
of: string;
|
||||
page: string;
|
||||
msgs: string;
|
||||
tools: string;
|
||||
match: string;
|
||||
other: string;
|
||||
configured: string;
|
||||
removed: string;
|
||||
failedToToggle: string;
|
||||
failedToRemove: string;
|
||||
failedToReveal: string;
|
||||
collapse: string;
|
||||
expand: string;
|
||||
general: string;
|
||||
messaging: string;
|
||||
pluginLoadFailed: string;
|
||||
pluginNotRegistered: string;
|
||||
};
|
||||
|
||||
// ── App shell ──
|
||||
app: {
|
||||
brand: string;
|
||||
brandShort: string;
|
||||
closeNavigation: string;
|
||||
closeModelTools: string;
|
||||
footer: {
|
||||
org: string;
|
||||
};
|
||||
activeSessionsLabel: string;
|
||||
gatewayStatusLabel: string;
|
||||
gatewayStrip: {
|
||||
failed: string;
|
||||
off: string;
|
||||
running: string;
|
||||
starting: string;
|
||||
stopped: string;
|
||||
};
|
||||
nav: {
|
||||
analytics: string;
|
||||
chat: string;
|
||||
config: string;
|
||||
cron: string;
|
||||
documentation: string;
|
||||
keys: string;
|
||||
logs: string;
|
||||
models: string;
|
||||
profiles: string;
|
||||
plugins: string;
|
||||
sessions: string;
|
||||
skills: string;
|
||||
};
|
||||
modelToolsSheetSubtitle: string;
|
||||
modelToolsSheetTitle: string;
|
||||
navigation: string;
|
||||
openDocumentation: string;
|
||||
openNavigation: string;
|
||||
pluginNavSection: string;
|
||||
sessionsActiveCount: string;
|
||||
statusOverview: string;
|
||||
system: string;
|
||||
webUi: string;
|
||||
};
|
||||
|
||||
// ── Status page ──
|
||||
status: {
|
||||
actionFailed: string;
|
||||
actionFinished: string;
|
||||
actions: string;
|
||||
agent: string;
|
||||
connected: string;
|
||||
connectedPlatforms: string;
|
||||
disconnected: string;
|
||||
error: string;
|
||||
failed: string;
|
||||
gateway: string;
|
||||
gatewayFailedToStart: string;
|
||||
lastUpdate: string;
|
||||
noneRunning: string;
|
||||
notRunning: string;
|
||||
pid: string;
|
||||
platformDisconnected: string;
|
||||
platformError: string;
|
||||
activeSessions: string;
|
||||
recentSessions: string;
|
||||
restartGateway: string;
|
||||
restartingGateway: string;
|
||||
running: string;
|
||||
runningRemote: string;
|
||||
startFailed: string;
|
||||
starting: string;
|
||||
startedInBackground: string;
|
||||
stopped: string;
|
||||
updateHermes: string;
|
||||
updatingHermes: string;
|
||||
waitingForOutput: string;
|
||||
};
|
||||
|
||||
// ── Sessions page ──
|
||||
sessions: {
|
||||
title: string;
|
||||
searchPlaceholder: string;
|
||||
noSessions: string;
|
||||
noMatch: string;
|
||||
startConversation: string;
|
||||
noMessages: string;
|
||||
untitledSession: string;
|
||||
deleteSession: string;
|
||||
confirmDeleteTitle: string;
|
||||
confirmDeleteMessage: string;
|
||||
sessionDeleted: string;
|
||||
failedToDelete: string;
|
||||
resumeInChat: string;
|
||||
previousPage: string;
|
||||
nextPage: string;
|
||||
roles: {
|
||||
user: string;
|
||||
assistant: string;
|
||||
system: string;
|
||||
tool: string;
|
||||
};
|
||||
};
|
||||
|
||||
// ── Analytics page ──
|
||||
analytics: {
|
||||
period: string;
|
||||
totalTokens: string;
|
||||
totalSessions: string;
|
||||
apiCalls: string;
|
||||
dailyTokenUsage: string;
|
||||
dailyBreakdown: string;
|
||||
perModelBreakdown: string;
|
||||
topSkills: string;
|
||||
skill: string;
|
||||
loads: string;
|
||||
edits: string;
|
||||
lastUsed: string;
|
||||
input: string;
|
||||
output: string;
|
||||
total: string;
|
||||
noUsageData: string;
|
||||
startSession: string;
|
||||
date: string;
|
||||
model: string;
|
||||
tokens: string;
|
||||
perDayAvg: string;
|
||||
acrossModels: string;
|
||||
inOut: string;
|
||||
};
|
||||
|
||||
// ── Models page ──
|
||||
models: {
|
||||
modelsUsed: string;
|
||||
estimatedCost: string;
|
||||
tokens: string;
|
||||
sessions: string;
|
||||
avgPerSession: string;
|
||||
apiCalls: string;
|
||||
toolCalls: string;
|
||||
noModelsData: string;
|
||||
startSession: string;
|
||||
};
|
||||
|
||||
// ── Logs page ──
|
||||
logs: {
|
||||
title: string;
|
||||
autoRefresh: string;
|
||||
file: string;
|
||||
level: string;
|
||||
component: string;
|
||||
lines: string;
|
||||
noLogLines: string;
|
||||
};
|
||||
|
||||
// ── Cron page ──
|
||||
cron: {
|
||||
confirmDeleteMessage: string;
|
||||
confirmDeleteTitle: string;
|
||||
newJob: string;
|
||||
nameOptional: string;
|
||||
namePlaceholder: string;
|
||||
prompt: string;
|
||||
promptPlaceholder: string;
|
||||
schedule: string;
|
||||
schedulePlaceholder: string;
|
||||
deliverTo: string;
|
||||
scheduledJobs: string;
|
||||
noJobs: string;
|
||||
last: string;
|
||||
next: string;
|
||||
pause: string;
|
||||
resume: string;
|
||||
triggerNow: string;
|
||||
delivery: {
|
||||
local: string;
|
||||
telegram: string;
|
||||
discord: string;
|
||||
slack: string;
|
||||
email: string;
|
||||
};
|
||||
};
|
||||
|
||||
// ── Plugins page ──
|
||||
pluginsPage: {
|
||||
contextEngineLabel: string;
|
||||
dashboardSlots: string;
|
||||
disableRuntime: string;
|
||||
enableAfterInstall: string;
|
||||
enableRuntime: string;
|
||||
forceReinstall: string;
|
||||
headline: string;
|
||||
identifierLabel: string;
|
||||
inactive: string;
|
||||
installBtn: string;
|
||||
installHeading: string;
|
||||
installHint: string;
|
||||
memoryProviderLabel: string;
|
||||
missingEnvWarn: string;
|
||||
noDashboardTab: string;
|
||||
openTab: string;
|
||||
orphanHeading: string;
|
||||
pluginListHeading: string;
|
||||
providerDefaults: string;
|
||||
providersHeading: string;
|
||||
providersHint: string;
|
||||
refreshDashboard: string;
|
||||
removeConfirm: string;
|
||||
removeHint: string;
|
||||
rescanHeading: string;
|
||||
rescanHint: string;
|
||||
runtimeHeading: string;
|
||||
saveProviders: string;
|
||||
savedProviders: string;
|
||||
sourceBadge: string;
|
||||
authRequired: string;
|
||||
authRequiredHint: string;
|
||||
updateGit: string;
|
||||
versionBadge: string;
|
||||
showInSidebar: string;
|
||||
hideFromSidebar: string;
|
||||
};
|
||||
|
||||
// ── Profiles page ──
|
||||
profiles: {
|
||||
newProfile: string;
|
||||
name: string;
|
||||
namePlaceholder: string;
|
||||
nameRequired: string;
|
||||
nameRule: string;
|
||||
invalidName: string;
|
||||
cloneFromDefault: string;
|
||||
allProfiles: string;
|
||||
noProfiles: string;
|
||||
defaultBadge: string;
|
||||
hasEnv: string;
|
||||
model: string;
|
||||
skills: string;
|
||||
rename: string;
|
||||
editSoul: string;
|
||||
soulSection: string;
|
||||
soulPlaceholder: string;
|
||||
saveSoul: string;
|
||||
soulSaved: string;
|
||||
openInTerminal: string;
|
||||
commandCopied: string;
|
||||
copyFailed: string;
|
||||
confirmDeleteTitle: string;
|
||||
confirmDeleteMessage: string;
|
||||
created: string;
|
||||
deleted: string;
|
||||
renamed: string;
|
||||
};
|
||||
|
||||
// ── Skills page ──
|
||||
skills: {
|
||||
title: string;
|
||||
searchPlaceholder: string;
|
||||
enabledOf: string;
|
||||
all: string;
|
||||
categories: string;
|
||||
filters: string;
|
||||
noSkills: string;
|
||||
noSkillsMatch: string;
|
||||
skillCount: string;
|
||||
resultCount: string;
|
||||
noDescription: string;
|
||||
toolsets: string;
|
||||
toolsetLabel: string;
|
||||
noToolsetsMatch: string;
|
||||
setupNeeded: string;
|
||||
disabledForCli: string;
|
||||
more: string;
|
||||
};
|
||||
|
||||
// ── Config page ──
|
||||
config: {
|
||||
configPath: string;
|
||||
filters: string;
|
||||
sections: string;
|
||||
exportConfig: string;
|
||||
importConfig: string;
|
||||
resetDefaults: string;
|
||||
resetScopeTooltip: string;
|
||||
confirmResetScope: string;
|
||||
resetScopeToast: string;
|
||||
rawYaml: string;
|
||||
searchResults: string;
|
||||
fields: string;
|
||||
noFieldsMatch: string;
|
||||
configSaved: string;
|
||||
yamlConfigSaved: string;
|
||||
failedToSave: string;
|
||||
failedToSaveYaml: string;
|
||||
failedToLoadRaw: string;
|
||||
configImported: string;
|
||||
invalidJson: string;
|
||||
categories: {
|
||||
general: string;
|
||||
agent: string;
|
||||
terminal: string;
|
||||
display: string;
|
||||
delegation: string;
|
||||
memory: string;
|
||||
compression: string;
|
||||
security: string;
|
||||
browser: string;
|
||||
voice: string;
|
||||
tts: string;
|
||||
stt: string;
|
||||
logging: string;
|
||||
discord: string;
|
||||
auxiliary: string;
|
||||
};
|
||||
};
|
||||
|
||||
// ── Env / Keys page ──
|
||||
env: {
|
||||
changesNote: string;
|
||||
confirmClearMessage: string;
|
||||
confirmClearTitle: string;
|
||||
description: string;
|
||||
enterValue: string;
|
||||
getKey: string;
|
||||
hideAdvanced: string;
|
||||
hideValue: string;
|
||||
keysCount: string;
|
||||
llmProviders: string;
|
||||
notConfigured: string;
|
||||
notSet: string;
|
||||
providersConfigured: string;
|
||||
replaceCurrentValue: string;
|
||||
showAdvanced: string;
|
||||
showValue: string;
|
||||
};
|
||||
|
||||
// ── OAuth ──
|
||||
oauth: {
|
||||
title: string;
|
||||
providerLogins: string;
|
||||
description: string;
|
||||
connected: string;
|
||||
expired: string;
|
||||
notConnected: string;
|
||||
runInTerminal: string;
|
||||
noProviders: string;
|
||||
login: string;
|
||||
disconnect: string;
|
||||
managedExternally: string;
|
||||
copied: string;
|
||||
cli: string;
|
||||
copyCliCommand: string;
|
||||
connect: string;
|
||||
sessionExpires: string;
|
||||
initiatingLogin: string;
|
||||
exchangingCode: string;
|
||||
connectedClosing: string;
|
||||
loginFailed: string;
|
||||
sessionExpired: string;
|
||||
reOpenAuth: string;
|
||||
reOpenVerification: string;
|
||||
submitCode: string;
|
||||
pasteCode: string;
|
||||
waitingAuth: string;
|
||||
enterCodePrompt: string;
|
||||
pkceStep1: string;
|
||||
pkceStep2: string;
|
||||
pkceStep3: string;
|
||||
flowLabels: {
|
||||
pkce: string;
|
||||
device_code: string;
|
||||
external: string;
|
||||
};
|
||||
expiresIn: string;
|
||||
};
|
||||
|
||||
// ── Language switcher ──
|
||||
language: {
|
||||
switchTo: string;
|
||||
};
|
||||
|
||||
// ── Theme switcher ──
|
||||
theme: {
|
||||
title: string;
|
||||
switchTheme: string;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,424 @@
|
||||
import type { Translations } from "./types";
|
||||
|
||||
export const zh: Translations = {
|
||||
common: {
|
||||
save: "保存",
|
||||
saving: "保存中...",
|
||||
cancel: "取消",
|
||||
close: "关闭",
|
||||
confirm: "确认",
|
||||
delete: "删除",
|
||||
refresh: "刷新",
|
||||
retry: "重试",
|
||||
search: "搜索...",
|
||||
loading: "加载中...",
|
||||
create: "创建",
|
||||
creating: "创建中...",
|
||||
set: "设置",
|
||||
replace: "替换",
|
||||
clear: "清除",
|
||||
live: "在线",
|
||||
off: "离线",
|
||||
enabled: "已启用",
|
||||
disabled: "已禁用",
|
||||
active: "活跃",
|
||||
inactive: "未激活",
|
||||
unknown: "未知",
|
||||
untitled: "无标题",
|
||||
none: "无",
|
||||
form: "表单",
|
||||
noResults: "无结果",
|
||||
of: "/",
|
||||
page: "页",
|
||||
msgs: "消息",
|
||||
tools: "工具",
|
||||
match: "匹配",
|
||||
other: "其他",
|
||||
configured: "已配置",
|
||||
removed: "已移除",
|
||||
failedToToggle: "切换失败",
|
||||
failedToRemove: "移除失败",
|
||||
failedToReveal: "显示失败",
|
||||
collapse: "折叠",
|
||||
expand: "展开",
|
||||
general: "通用",
|
||||
messaging: "消息平台",
|
||||
pluginLoadFailed:
|
||||
"无法加载此插件的脚本。请检查网络请求(dashboard-plugins/…)以及服务器上的插件路径。",
|
||||
pluginNotRegistered: "插件脚本未调用 register(),或执行出错。请打开浏览器控制台查看详情。",
|
||||
},
|
||||
|
||||
app: {
|
||||
brand: "Hermes Agent",
|
||||
brandShort: "HA",
|
||||
closeNavigation: "关闭导航",
|
||||
closeModelTools: "关闭模型与工具",
|
||||
footer: {
|
||||
org: "Nous Research",
|
||||
},
|
||||
activeSessionsLabel: "活跃会话:",
|
||||
gatewayStatusLabel: "网关状态:",
|
||||
gatewayStrip: {
|
||||
failed: "启动失败",
|
||||
off: "关闭",
|
||||
running: "运行中",
|
||||
starting: "启动中",
|
||||
stopped: "已停止",
|
||||
},
|
||||
nav: {
|
||||
analytics: "分析",
|
||||
chat: "对话",
|
||||
config: "配置",
|
||||
cron: "定时任务",
|
||||
documentation: "文档",
|
||||
keys: "密钥",
|
||||
logs: "日志",
|
||||
models: "模型",
|
||||
profiles: "多Agent配置",
|
||||
plugins: "插件管理",
|
||||
sessions: "会话",
|
||||
skills: "技能",
|
||||
},
|
||||
modelToolsSheetSubtitle: "与工具",
|
||||
modelToolsSheetTitle: "模型",
|
||||
navigation: "导航",
|
||||
openDocumentation: "在新标签页中打开文档",
|
||||
openNavigation: "打开导航",
|
||||
pluginNavSection: "插件",
|
||||
sessionsActiveCount: "{count} 个活跃",
|
||||
statusOverview: "状态概览",
|
||||
system: "系统",
|
||||
webUi: "管理面板",
|
||||
},
|
||||
|
||||
status: {
|
||||
actionFailed: "操作失败",
|
||||
actionFinished: "已完成",
|
||||
actions: "操作",
|
||||
agent: "代理",
|
||||
activeSessions: "活跃会话",
|
||||
connected: "已连接",
|
||||
connectedPlatforms: "已连接平台",
|
||||
disconnected: "已断开",
|
||||
error: "错误",
|
||||
failed: "失败",
|
||||
gateway: "网关",
|
||||
gatewayFailedToStart: "网关启动失败",
|
||||
lastUpdate: "最后更新",
|
||||
noneRunning: "无",
|
||||
notRunning: "未运行",
|
||||
pid: "进程",
|
||||
platformDisconnected: "已断开",
|
||||
platformError: "错误",
|
||||
recentSessions: "最近会话",
|
||||
restartGateway: "重启网关",
|
||||
restartingGateway: "正在重启网关…",
|
||||
running: "运行中",
|
||||
runningRemote: "运行中(远程)",
|
||||
startFailed: "启动失败",
|
||||
starting: "启动中",
|
||||
startedInBackground: "已在后台启动 — 请查看日志",
|
||||
stopped: "已停止",
|
||||
updateHermes: "更新 Hermes",
|
||||
updatingHermes: "正在更新 Hermes…",
|
||||
waitingForOutput: "等待输出…",
|
||||
},
|
||||
|
||||
sessions: {
|
||||
title: "会话",
|
||||
searchPlaceholder: "搜索消息内容...",
|
||||
noSessions: "暂无会话",
|
||||
noMatch: "没有匹配的会话",
|
||||
startConversation: "开始对话后将显示在此处",
|
||||
noMessages: "暂无消息",
|
||||
untitledSession: "无标题会话",
|
||||
deleteSession: "删除会话",
|
||||
confirmDeleteTitle: "删除会话?",
|
||||
confirmDeleteMessage: "此操作将永久删除对话及其所有消息,无法恢复。",
|
||||
sessionDeleted: "会话已删除",
|
||||
failedToDelete: "删除会话失败",
|
||||
resumeInChat: "在对话中继续",
|
||||
previousPage: "上一页",
|
||||
nextPage: "下一页",
|
||||
roles: {
|
||||
user: "用户",
|
||||
assistant: "助手",
|
||||
system: "系统",
|
||||
tool: "工具",
|
||||
},
|
||||
},
|
||||
|
||||
analytics: {
|
||||
period: "时间范围:",
|
||||
totalTokens: "总 Token 数",
|
||||
totalSessions: "总会话数",
|
||||
apiCalls: "API 调用",
|
||||
dailyTokenUsage: "每日 Token 用量",
|
||||
dailyBreakdown: "每日明细",
|
||||
perModelBreakdown: "模型用量明细",
|
||||
topSkills: "常用技能",
|
||||
skill: "技能",
|
||||
loads: "代理加载",
|
||||
edits: "代理管理",
|
||||
lastUsed: "最近使用",
|
||||
input: "输入",
|
||||
output: "输出",
|
||||
total: "总计",
|
||||
noUsageData: "该时间段暂无使用数据",
|
||||
startSession: "开始会话后将在此显示分析数据",
|
||||
date: "日期",
|
||||
model: "模型",
|
||||
tokens: "Token",
|
||||
perDayAvg: "/天 平均",
|
||||
acrossModels: "共 {count} 个模型",
|
||||
inOut: "输入 {input} / 输出 {output}",
|
||||
},
|
||||
|
||||
models: {
|
||||
modelsUsed: "使用模型数",
|
||||
estimatedCost: "预估费用",
|
||||
tokens: "Token",
|
||||
sessions: "会话",
|
||||
avgPerSession: "平均/会话",
|
||||
apiCalls: "API 调用",
|
||||
toolCalls: "工具调用",
|
||||
noModelsData: "该时间段暂无模型使用数据",
|
||||
startSession: "开始会话后将在此显示模型数据",
|
||||
},
|
||||
|
||||
logs: {
|
||||
title: "日志",
|
||||
autoRefresh: "自动刷新",
|
||||
file: "文件",
|
||||
level: "级别",
|
||||
component: "组件",
|
||||
lines: "行数",
|
||||
noLogLines: "未找到日志记录",
|
||||
},
|
||||
|
||||
cron: {
|
||||
confirmDeleteMessage: "将从此计划移除该任务,此操作无法撤销。",
|
||||
confirmDeleteTitle: "删除定时任务?",
|
||||
newJob: "新建定时任务",
|
||||
nameOptional: "名称(可选)",
|
||||
namePlaceholder: "例如:每日总结",
|
||||
prompt: "提示词",
|
||||
promptPlaceholder: "代理每次运行时应执行什么操作?",
|
||||
schedule: "调度表达式(cron)",
|
||||
schedulePlaceholder: "0 9 * * *",
|
||||
deliverTo: "投递至",
|
||||
scheduledJobs: "已调度任务",
|
||||
noJobs: "暂无定时任务。在上方创建一个。",
|
||||
last: "上次",
|
||||
next: "下次",
|
||||
pause: "暂停",
|
||||
resume: "恢复",
|
||||
triggerNow: "立即触发",
|
||||
delivery: {
|
||||
local: "本地",
|
||||
telegram: "Telegram",
|
||||
discord: "Discord",
|
||||
slack: "Slack",
|
||||
email: "邮件",
|
||||
},
|
||||
},
|
||||
|
||||
profiles: {
|
||||
newProfile: "新建多Agent配置",
|
||||
name: "名称",
|
||||
namePlaceholder: "例如:coder, writer 等",
|
||||
nameRequired: "名称必填",
|
||||
nameRule:
|
||||
"仅允许小写字母、数字、下划线和短横线;首字符必须是字母或数字;最多 64 个字符。",
|
||||
invalidName: "多Agent配置名称非法",
|
||||
cloneFromDefault: "从默认多Agent配置克隆配置",
|
||||
allProfiles: "多Agent配置列表",
|
||||
noProfiles: "暂无多Agent配置。",
|
||||
defaultBadge: "默认",
|
||||
hasEnv: "已配置 env",
|
||||
model: "模型",
|
||||
skills: "技能",
|
||||
rename: "重命名",
|
||||
editSoul: "编辑 SOUL.md",
|
||||
soulSection: "SOUL.md(人格 / 系统提示词)",
|
||||
soulPlaceholder: "# 这个代理应当如何工作……",
|
||||
saveSoul: "保存 SOUL",
|
||||
soulSaved: "SOUL.md 已保存",
|
||||
openInTerminal: "复制 CLI 命令",
|
||||
commandCopied: "已复制到剪贴板",
|
||||
copyFailed: "复制失败",
|
||||
confirmDeleteTitle: "删除多Agent配置?",
|
||||
confirmDeleteMessage:
|
||||
"将永久删除多Agent配置 '{name}' — 包括配置、密钥、记忆、会话、技能、定时任务。此操作无法撤销。",
|
||||
created: "已创建",
|
||||
deleted: "已删除",
|
||||
renamed: "已重命名",
|
||||
},
|
||||
|
||||
pluginsPage: {
|
||||
contextEngineLabel: "上下文引擎",
|
||||
dashboardSlots: "面板插槽",
|
||||
disableRuntime: "禁用",
|
||||
enableAfterInstall: "安装后启用",
|
||||
enableRuntime: "启用",
|
||||
forceReinstall: "强制重装(先删除已有目录)",
|
||||
headline: "发现、安装、启用和更新 Hermes 插件(对齐 `hermes plugins` CLI)。",
|
||||
identifierLabel: "Git 地址或 owner/repo",
|
||||
inactive: "未启用",
|
||||
installBtn: "从 Git 安装",
|
||||
installHeading: "从 GitHub / Git 地址安装",
|
||||
installHint: "使用 owner/repo 简写或完整的 https:// / git@ 克隆地址。",
|
||||
memoryProviderLabel: "记忆提供方",
|
||||
missingEnvWarn: "在「密钥」页面设置以下变量后再运行插件:",
|
||||
noDashboardTab: "无仪表盘标签",
|
||||
openTab: "打开",
|
||||
orphanHeading: "仅仪表盘扩展(无匹配的 agent plugin.yaml)",
|
||||
pluginListHeading: "已安装插件",
|
||||
providerDefaults: "内置 / 默认",
|
||||
providersHeading: "运行时提供方插件",
|
||||
providersHint:
|
||||
"写入 config.yaml:memory.provider(留空为内置)、context.engine。下次会话生效。",
|
||||
refreshDashboard: "重新扫描仪表盘扩展",
|
||||
removeConfirm: "从 ~/.hermes/plugins/ 删除此插件?",
|
||||
removeHint: "仅可移除用户安装在 ~/.hermes/plugins 下的插件。",
|
||||
rescanHeading: "SPA 插件注册表",
|
||||
rescanHint: "在磁盘新增文件后扫描,使侧边栏载入新 manifest。",
|
||||
runtimeHeading: "网关运行时(YAML 插件)",
|
||||
saveProviders: "保存提供方设置",
|
||||
savedProviders: "提供方设置已保存。",
|
||||
sourceBadge: "来源",
|
||||
authRequired: "需要认证",
|
||||
authRequiredHint: "运行此命令以完成认证:",
|
||||
updateGit: "git pull",
|
||||
versionBadge: "版本",
|
||||
showInSidebar: "在侧边栏显示",
|
||||
hideFromSidebar: "从侧边栏隐藏",
|
||||
},
|
||||
|
||||
skills: {
|
||||
title: "技能",
|
||||
searchPlaceholder: "搜索技能和工具集...",
|
||||
enabledOf: "已启用 {enabled}/{total}",
|
||||
all: "全部",
|
||||
categories: "分类",
|
||||
filters: "筛选",
|
||||
noSkills: "未找到技能。技能从 ~/.hermes/skills/ 加载",
|
||||
noSkillsMatch: "没有匹配的技能。",
|
||||
skillCount: "{count} 个技能",
|
||||
resultCount: "{count} 个结果",
|
||||
noDescription: "暂无描述。",
|
||||
toolsets: "工具集",
|
||||
toolsetLabel: "{name} 工具集",
|
||||
noToolsetsMatch: "没有匹配的工具集。",
|
||||
setupNeeded: "需要配置",
|
||||
disabledForCli: "CLI 已禁用",
|
||||
more: "还有 {count} 个",
|
||||
},
|
||||
|
||||
config: {
|
||||
configPath: "~/.hermes/config.yaml",
|
||||
filters: "筛选",
|
||||
sections: "分类",
|
||||
exportConfig: "导出配置为 JSON",
|
||||
importConfig: "从 JSON 导入配置",
|
||||
resetDefaults: "恢复默认值",
|
||||
resetScopeTooltip: "将{scope}恢复为默认值",
|
||||
confirmResetScope: "确定要将{scope}的所有设置恢复为默认值吗?此操作仅更新表单,在按下「保存」按钮前不会写入 config.yaml。",
|
||||
resetScopeToast: "{scope}已恢复为默认值 — 请检查并保存以生效",
|
||||
rawYaml: "原始 YAML 配置",
|
||||
searchResults: "搜索结果",
|
||||
fields: "个字段",
|
||||
noFieldsMatch: '没有匹配"{query}"的字段',
|
||||
configSaved: "配置已保存",
|
||||
yamlConfigSaved: "YAML 配置已保存",
|
||||
failedToSave: "保存失败",
|
||||
failedToSaveYaml: "YAML 保存失败",
|
||||
failedToLoadRaw: "加载原始配置失败",
|
||||
configImported: "配置已导入 — 请检查后保存",
|
||||
invalidJson: "无效的 JSON 文件",
|
||||
categories: {
|
||||
general: "通用",
|
||||
agent: "代理",
|
||||
terminal: "终端",
|
||||
display: "显示",
|
||||
delegation: "委托",
|
||||
memory: "记忆",
|
||||
compression: "压缩",
|
||||
security: "安全",
|
||||
browser: "浏览器",
|
||||
voice: "语音",
|
||||
tts: "文字转语音",
|
||||
stt: "语音转文字",
|
||||
logging: "日志",
|
||||
discord: "Discord",
|
||||
auxiliary: "辅助",
|
||||
},
|
||||
},
|
||||
|
||||
env: {
|
||||
changesNote: "更改会立即保存到磁盘。活跃会话将自动获取新密钥。",
|
||||
confirmClearMessage: "该变量的已存值将从 .env 文件中删除。无法在此界面撤销。",
|
||||
confirmClearTitle: "清除此密钥?",
|
||||
description: "管理存储在以下位置的 API 密钥和凭据",
|
||||
hideAdvanced: "隐藏高级选项",
|
||||
showAdvanced: "显示高级选项",
|
||||
llmProviders: "LLM 提供商",
|
||||
providersConfigured: "已配置 {configured}/{total} 个提供商",
|
||||
getKey: "获取密钥",
|
||||
notConfigured: "{count} 个未配置",
|
||||
notSet: "未设置",
|
||||
keysCount: "{count} 个密钥",
|
||||
enterValue: "输入值...",
|
||||
replaceCurrentValue: "替换当前值({preview})",
|
||||
showValue: "显示实际值",
|
||||
hideValue: "隐藏值",
|
||||
},
|
||||
|
||||
oauth: {
|
||||
title: "提供商登录(OAuth)",
|
||||
providerLogins: "提供商登录(OAuth)",
|
||||
description: "已连接 {connected}/{total} 个 OAuth 提供商。登录流程目前通过 CLI 运行;点击「复制命令」并粘贴到终端中进行设置。",
|
||||
connected: "已连接",
|
||||
expired: "已过期",
|
||||
notConnected: "未连接。在终端中运行 {command}。",
|
||||
runInTerminal: "在终端中。",
|
||||
noProviders: "未检测到支持 OAuth 的提供商。",
|
||||
login: "登录",
|
||||
disconnect: "断开连接",
|
||||
managedExternally: "外部管理",
|
||||
copied: "已复制 ✓",
|
||||
cli: "CLI",
|
||||
copyCliCommand: "复制 CLI 命令(用于外部/备用方式)",
|
||||
connect: "连接",
|
||||
sessionExpires: "会话将在 {time} 后过期",
|
||||
initiatingLogin: "正在启动登录流程…",
|
||||
exchangingCode: "正在交换令牌…",
|
||||
connectedClosing: "已连接!正在关闭…",
|
||||
loginFailed: "登录失败。",
|
||||
sessionExpired: "会话已过期。点击重试以开始新的登录。",
|
||||
reOpenAuth: "重新打开授权页面",
|
||||
reOpenVerification: "重新打开验证页面",
|
||||
submitCode: "提交代码",
|
||||
pasteCode: "粘贴授权代码(包含 #state 后缀也可以)",
|
||||
waitingAuth: "等待您在浏览器中授权…",
|
||||
enterCodePrompt: "已在新标签页中打开。如果需要,请输入以下代码:",
|
||||
pkceStep1: "已在新标签页打开 claude.ai。请登录并点击「授权」。",
|
||||
pkceStep2: "复制授权后显示的授权代码。",
|
||||
pkceStep3: "将代码粘贴到下方并提交。",
|
||||
flowLabels: {
|
||||
pkce: "浏览器登录(PKCE)",
|
||||
device_code: "设备代码",
|
||||
external: "外部 CLI",
|
||||
},
|
||||
expiresIn: "{time}后过期",
|
||||
},
|
||||
|
||||
language: {
|
||||
switchTo: "切换到英文",
|
||||
},
|
||||
|
||||
theme: {
|
||||
title: "主题",
|
||||
switchTheme: "切换主题",
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user