feat(i18n): localize all gateway commands + web dashboard, add 8 new locales (16 total) (#22914)

* feat(i18n): localize /model command output

Reported by @tianma8888: when Chinese users run /model, the labels
("Provider:", "Context:", "_session only_", etc.) are still English.
This routes the static prose through the existing i18n catalog so it
follows display.language / HERMES_LANGUAGE.

Changes:
- locales/{en,zh,ja,de,es,fr,tr,uk}.yaml: add 17 keys under
  gateway.model.* covering switched/provider/context/max_output/cost/
  capabilities/prompt_caching/warning/saved_global/session_only_hint/
  current_label/current_tag/more_models_suffix/usage_*.
- gateway/run.py _handle_model_command: replace hardcoded f-strings in
  the picker callback, the text-list fallback, and the direct-switch
  confirmation block with t("gateway.model.<key>", ...).

What stays English:
- model IDs, provider slugs, capability strings, cost figures, and the
  "[Note: model was just switched...]" prepended to the model's next
  prompt (LLM-facing, not user-facing).
- The two slightly-different session-only hints unify on a single key
  with the em-dash phrasing.

Validation: tests/agent/test_i18n.py 27/27 passing (parity contract
holds), tests/gateway/ -k 'model or i18n' 74/74 passing.

* feat(i18n): localize all gateway slash command outputs

Expands the i18n catalog from 7 strings to 234 keys across 35 gateway
slash command handlers, so non-English users see localized output for
\`/profile\`, \`/status\`, \`/help\`, \`/personality\`, \`/voice\`, \`/reset\`,
\`/agents\`, \`/restart\`, \`/commands\`, \`/goal\`, \`/retry\`, \`/undo\`,
\`/sethome\`, \`/title\`, \`/yolo\`, \`/background\`, \`/approve\`, \`/deny\`,
\`/insights\`, \`/debug\`, \`/rollback\`, \`/reasoning\`, \`/fast\`,
\`/verbose\`, \`/footer\`, \`/compress\`, \`/topic\`, \`/kanban\`,
\`/resume\`, \`/branch\`, \`/usage\`, \`/reload-mcp\`, \`/reload-skills\`,
\`/update\`, \`/stop\` (plus the \`/model\` block already added in the
previous commit).

Reported by @tianma8888 — Chinese users want command output prose in
their language, not just the labels we already had.

Translations are hand-written for all 8 supported locales (en, zh, ja,
de, es, fr, tr, uk), matching each catalog's existing style: full-width
punctuation in zh, em-dashes in zh/ja/uk, French spaced colons,
German noun capitalization, etc.

What stays English (unchanged):
- Identifiers/values: model IDs, file paths, profile names, session IDs,
  command flag names like --global, URLs, config keys.
- Backtick code spans: \`/foo\`, \`config.yaml\`.
- Log messages (logger.info/warning/error).
- LLM-facing system notes prepended to next prompt (e.g. [Note: model
  was just switched...]).
- Strings produced by external modules (gateway_help_lines,
  format_gateway, manual_compression_feedback) — those have their
  own surfaces.

New shared keys for cross-handler boilerplate:
- gateway.shared.session_db_unavailable (5 call sites: branch, title,
  resume, topic, _disable_telegram_topic_mode_for_chat)
- gateway.shared.session_not_found (1 site)
- gateway.shared.warn_passthrough (2 sites in /title's f"⚠️ {e}" pattern)

YAML gotcha fixed: \`yolo.on\` and \`yolo.off\` were originally written
unquoted, which YAML 1.1 parses as boolean True/False keys. Renamed to
\`yolo.enabled\` / \`yolo.disabled\` for both safety and clarity.

Test fix: tests/agent/test_i18n.py::test_t_missing_key_in_non_english_falls_back_to_english
now resets the catalog cache on teardown, so the fake "foo: English Foo"
locale doesn't poison the module-level cache for subsequent tests in
the same xdist worker. (Without this, every gateway slash command test
that shares a worker with the i18n suite would see the fake catalog.)

Validation:
- tests/agent/test_i18n.py: 27/27 (parity contract — every key in every
  locale, matching placeholder tokens).
- tests/gateway/: 5077 passed, 0 failed (full gateway suite).
- 180 t() call sites added across 35 handlers; 1872 catalog entries
  total (234 keys × 8 locales).

* feat(i18n): add 8 new locales — af, ko, it, ga, zh-hant, pt, ru, hu

Expands the static-message catalog from 8 → 16 languages, each with full
270-key parity against the English source-of-truth.  Every locale now
covers the same surface PR #22914 added: approval prompts plus all 35
gateway slash command outputs.

New locales:
- af  Afrikaans      (community ask in #21961 by @GodsBoy; PRs #21962, #21970)
- ko  Korean         (PRs #20297 by @tmdgusya, #22285 by @project820)
- it  Italian        (PR #20371 by @leprincep35700)
- ga  Irish/Gaeilge  (PR #20962 by @ryanmcc09-dot)
- zh-hant Traditional Chinese (PRs #20523 by @jackey8616, #13140 by @anomixer)
- pt  Portuguese     (PRs #20443 by @pedroborges, #15737 by @carloshenriquecarniatto, #22063 by @Magaav)
- ru  Russian        (PR #22770 by @DrMaks22)
- hu  Hungarian      (PR #22336 by @lunasec007)

Each locale uses native-quality translations matching the existing tone
and conventions of the older 8 locales:
- zh-hant uses 繁體 characters with TW/HK technical vocabulary (軟體
  not 软件, 連線 not 连接, 設定 not 设置, 訊息 not 消息, 工作階段 not 会话, 程式
  not 程序, 預設 not 默认, 伺服器 not 服务器), full-width punctuation 「:()」.
- ko uses formal 합니다체 (습니다/합니다) register throughout.
- pt uses European Portuguese as baseline with neutral PT/BR vocabulary
  where possible.
- ga uses standard An Caighdeán Oifigiúil; English loanwords retained
  for tech terms without good Irish equivalents (gateway, API, JSON).
- All preserve {placeholder} tokens, backtick code spans, slash commands,
  brand names (Hermes, MCP, TTS, YOLO, OpenAI, Telegram, etc.), and emoji.

Aliases added in agent/i18n.py:
- af-za, Afrikaans → af
- ko-kr, Korean, 한국어 → ko
- it-it, italiano → it
- ga-ie, Irish, Gaeilge → ga
- zh-tw, zh-hk, zh-mo, traditional-chinese → zh-hant (note: zh-tw used to
  alias to zh; now aliases to its own zh-hant catalog)
- zh-cn, zh-hans, zh-sg → zh (unchanged from before)
- pt-pt, pt-br, brazilian, portuguese → pt
- ru-ru, Russian, русский → ru
- hu-hu, Magyar → hu

The zh-tw alias re-routing is intentional: previously typing 'zh-TW' got
the Simplified Chinese catalog (wrong vocabulary for Taiwan/HK users).
Now those users get the proper Traditional Chinese catalog.

Validation:
- tests/agent/test_i18n.py: 43/43 (parity contract holds for all 16
  languages × 270 keys = 4320 catalog entries, with matching placeholder
  tokens).
- E2E alias resolution verified for all 19 alias inputs (Afrikaans, ko-KR,
  한국어, italiano, Gaeilge, zh-TW, zh-HK, traditional-chinese, pt-BR,
  brazilian, Magyar, etc.).
- tests/gateway/: 5198 passed (3 pre-existing TTS routing failures
  unrelated to i18n).

Credit to all contributors whose PRs surfaced these language requests.
Their original PRs may now be closed as superseded with credit.

* feat(dashboard-i18n): add 14 web dashboard locales matching the static catalog

Brings the React dashboard (web/src/) up to the same 16-language
coverage the static catalog already has after the previous commits in
this PR. The Translations interface is TypeScript-typed, so every new
locale must provide every key — tsc -b is the parity guard.

Languages added (each is a complete 429-line locale file):
- af  Afrikaans
- ja  Japanese        (PR #22513 by @snuffxxx surfaced this)
- de  German          (PR #21749 by @mag1art)
- es  Spanish         (PR #21749)
- fr  French          (PRs #21749, #10310 by @foXaCe)
- tr  Turkish
- uk  Ukrainian
- ko  Korean          (PRs #21749, #18894 by @ovstng, #22285 by @project820)
- it  Italian
- ga  Irish (Gaeilge)
- zh-hant Traditional Chinese (PR #13140 by @anomixer)
- pt  Portuguese      (PRs #22063 by @Magaav, #22182 by @wesleysimplicio, #15737 by @carloshenriquecarniatto)
- ru  Russian         (PRs #21749, #22770 by @DrMaks22)
- hu  Hungarian       (PR #22336 by @lunasec007)

Each translation covers all 15 namespaces with full key parity vs en.ts,
preserves every {placeholder} token verbatim, keeps identifiers
untranslated (brand names, file paths, cron expressions, code spans),
translates the language.switchTo tooltip into the target language, and
matches existing tone conventions (zh-hant uses TW/HK vocab; ja uses
formal desu/masu; ko uses formal seumnida register; ga uses An
Caighdean Oifigiuil with English loanwords for tech vocab without good
Irish equivalents).

Plumbing:
- web/src/i18n/types.ts: Locale union expanded to all 16 codes.
- web/src/i18n/context.tsx: imports all 16 catalogs; exports
  LOCALE_META (endonym + flag per locale); isLocale() type guard.
- web/src/i18n/index.ts: re-export LOCALE_META.
- web/src/components/LanguageSwitcher.tsx: replaced two-state EN-ZH
  toggle with a click-to-open dropdown listing all 16 languages.

Note: zh-hant.ts exports zhHant (camelCase) since hyphen is invalid in
a JS identifier; the canonical 'zh-hant' string keys it in TRANSLATIONS.

Validation:
- npx tsc -b: 0 errors. Every locale satisfies Translations.
- npm run build (tsc + vite production): green, 2062 modules.
- Each locale file is exactly 429 lines.

Out of scope: plugin dashboards (kanban/achievements ship as prebuilt
bundles with no source in repo); Docusaurus docs (separate surface);
TUI (no i18n yet).

* feat(plugin-i18n): localize achievements + kanban plugin dashboards across all 16 locales

Brings the two shipped plugin dashboards (hermes-achievements, kanban)
under the same i18n umbrella as the core dashboard PR #22914 just
established.  Both bundles now read user-facing strings from the host's
i18n catalog via SDK.useI18n() instead of hardcoded English.

## Approach

Plugin dashboards ship as prebuilt IIFE bundles in
plugins/<name>/dashboard/dist/index.js — no build step, no source in
repo (upstream-authored, vendored as compiled JS).  Earlier contributor
PRs (#22594, #22595, #18747) tried direct edits but didn't actually
wire the bundles to read translations.

This change does the wiring properly:

1.  Each bundle gets a useI18n shim at IIFE scope:
        const useI18n = SDK.useI18n
          || function () { return { t: { kanban: null }, locale: "en" }; };
    Older host SDKs without useI18n still load the bundle and render
    English fallbacks.

2.  A small tx(t, path, fallback, vars) helper resolves dotted keys
    under the plugin's namespace (t.kanban.* or t.achievements.*) and
    interpolates {placeholder} tokens.

3.  Every React component starts with const { t } = useI18n() and
    each user-visible string is wrapped in tx(t, "key", "English fallback").
    Helpers called outside React components (window.prompt callers,
    constants used during init) take t as a parameter.

4.  Top-level constants that were English dictionaries (COLUMN_LABEL,
    COLUMN_HELP, DESTRUCTIVE_TRANSITIONS, DIAGNOSTIC_EVENT_LABELS in
    kanban) become getColumnLabel(t, status)-style functions backed by
    FALLBACK_* dictionaries.

## Translations added

Two new top-level namespaces added to the dashboard's TypeScript-typed
Translations interface:

- achievements: ~70 keys covering the hero, scan banner, achievement
  card, share dialog, stats, filters, and empty states.
- kanban: ~145 keys covering the board, columns (with nested
  columnLabels and columnHelp sub-dicts), card detail panel,
  bulk-actions toolbar, dependency editor, board switcher, and
  diagnostic callouts.

Each key is provided across all 16 supported locales:
en, zh, zh-hant, ja, de, es, fr, tr, uk, af, ko, it, ga, pt, ru, hu.

Total new translation entries: ~3,440 (215 keys × 16 locales).

## What stays English (deliberate)

- API paths, CSS class names, data-* attributes, JSON keys, regex
  strings, URLs, file paths (~/.hermes/kanban.db, boards/_archived/).
- State identifier strings used as lookup keys (triage / todo / ready /
  running / blocked / done / archived) — labels translate, key strings
  don't.
- The PNG share-card text rendered to canvas in the achievements
  ShareDialog (HERMES AGENT watermark, UNLOCKED stamp, tier names) —
  these become part of a globally-shared image and stay English.
- localStorage keys (hermes.kanban.selectedBoard).
- Brand names (Kanban, Hermes, WebSocket, Nous Research).

## Contributor credit

PR #22594 by @02356abc and PR #22595 by @02356abc supplied the
en + zh kanban namespace skeleton (145 keys); used as the en source-
of-truth in this commit and translated to the other 14 locales.

PR #18747 by @laolaoshiren first surfaced the achievements
localization request.

## Validation

- npx tsc -b: 0 errors. All 16 locale .ts files satisfy the
  Translations type with full key parity.
- npm run build (tsc + vite production build): green, 2062 modules,
  1.56MB JS / 95KB CSS, ~2.5s build.
- node --check on both plugin bundles: parse cleanly.
- 126 tx() call sites in kanban, 46 in achievements.

## Out of scope

- TUI (ui-tui/) has no i18n infrastructure yet.
- Docusaurus docs (website/i18n/) — already had zh-Hans; expanding
  is a separate translation workstream (Thai / Korean / Hindi PRs).
This commit is contained in:
Teknium 2026-05-10 07:14:14 -07:00 committed by GitHub
parent 62b1c74cbc
commit c39168453d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
41 changed files with 16907 additions and 690 deletions

View file

@ -1,36 +1,100 @@
import { useState, useRef, useEffect } from "react";
import { Button } from "@nous-research/ui/ui/components/button";
import { Typography } from "@/components/NouiTypography";
import { useI18n } from "@/i18n/context";
import { LOCALE_META } from "@/i18n";
import type { Locale } from "@/i18n";
/**
* Compact language toggle shows a clickable flag that switches between
* English and Chinese. Persists choice to localStorage.
* Language picker shows the current language's flag + endonym, opens a
* dropdown of all supported locales when clicked. Persists choice to
* localStorage via the I18n context.
*
* Replaces the older two-state ENZH toggle now that we ship 16 locales
* (en, zh, zh-hant, ja, de, es, fr, tr, uk, af, ko, it, ga, pt, ru, hu).
*/
export function LanguageSwitcher() {
const { locale, setLocale, t } = useI18n();
const [open, setOpen] = useState(false);
const containerRef = useRef<HTMLDivElement>(null);
const toggle = () => setLocale(locale === "en" ? "zh" : "en");
// Close on outside click / Escape so the dropdown doesn't trap the user.
useEffect(() => {
if (!open) return;
function onPointerDown(e: PointerEvent) {
if (!containerRef.current) return;
if (!containerRef.current.contains(e.target as Node)) {
setOpen(false);
}
}
function onKey(e: KeyboardEvent) {
if (e.key === "Escape") setOpen(false);
}
document.addEventListener("pointerdown", onPointerDown);
document.addEventListener("keydown", onKey);
return () => {
document.removeEventListener("pointerdown", onPointerDown);
document.removeEventListener("keydown", onKey);
};
}, [open]);
const current = LOCALE_META[locale];
const allLocales = Object.entries(LOCALE_META) as Array<[Locale, typeof current]>;
return (
<Button
ghost
onClick={toggle}
title={t.language.switchTo}
aria-label={t.language.switchTo}
className="px-2 py-1 normal-case tracking-normal font-normal text-xs text-muted-foreground hover:text-foreground"
>
<span className="inline-flex items-center gap-1.5">
<span className="text-base leading-none">
{locale === "en" ? "🇬🇧" : "🇨🇳"}
<div ref={containerRef} className="relative inline-flex">
<Button
ghost
onClick={() => setOpen((v) => !v)}
title={t.language.switchTo}
aria-label={t.language.switchTo}
aria-haspopup="listbox"
aria-expanded={open}
className="px-2 py-1 normal-case tracking-normal font-normal text-xs text-muted-foreground hover:text-foreground"
>
<span className="inline-flex items-center gap-1.5">
<span className="text-base leading-none">{current.flag}</span>
<Typography
mondwest
className="hidden sm:inline tracking-wide uppercase text-[0.65rem]"
>
{locale === "en" ? "EN" : current.name}
</Typography>
</span>
</Button>
<Typography
mondwest
className="hidden sm:inline tracking-wide uppercase text-[0.65rem]"
{open && (
<div
role="listbox"
aria-label={t.language.switchTo}
className="absolute right-0 top-full mt-1 z-50 min-w-[10rem] rounded-md border border-border bg-popover shadow-md py-1 max-h-80 overflow-y-auto"
>
{locale === "en" ? "EN" : "中文"}
</Typography>
</span>
</Button>
{allLocales.map(([code, meta]) => {
const selected = code === locale;
return (
<button
key={code}
role="option"
aria-selected={selected}
onClick={() => {
setLocale(code);
setOpen(false);
}}
className={
"w-full text-left px-3 py-1.5 text-xs flex items-center gap-2 hover:bg-accent hover:text-accent-foreground transition-colors " +
(selected ? "font-semibold text-foreground" : "text-muted-foreground")
}
>
<span className="text-base leading-none">{meta.flag}</span>
<span className="truncate">{meta.name}</span>
{selected && <span className="ml-auto text-xs"></span>}
</button>
);
})}
</div>
)}
</div>
);
}

696
web/src/i18n/af.ts Normal file
View file

@ -0,0 +1,696 @@
import type { Translations } from "./types";
export const af: Translations = {
common: {
save: "Stoor",
saving: "Besig om te stoor...",
cancel: "Kanselleer",
close: "Maak toe",
confirm: "Bevestig",
delete: "Skrap",
refresh: "Herlaai",
retry: "Probeer weer",
search: "Soek...",
loading: "Besig om te laai...",
create: "Skep",
creating: "Besig om te skep...",
set: "Stel",
replace: "Vervang",
clear: "Vee uit",
live: "Lewendig",
off: "Af",
enabled: "geaktiveer",
disabled: "gedeaktiveer",
active: "aktief",
inactive: "onaktief",
unknown: "onbekend",
untitled: "Sonder titel",
none: "Geen",
form: "Vorm",
noResults: "Geen resultate",
of: "van",
page: "Bladsy",
msgs: "boodskappe",
tools: "gereedskap",
match: "passing",
other: "Ander",
configured: "gekonfigureer",
removed: "verwyder",
failedToToggle: "Kon nie wissel nie",
failedToRemove: "Kon nie verwyder nie",
failedToReveal: "Kon nie openbaar nie",
collapse: "Vou in",
expand: "Vou uit",
general: "Algemeen",
messaging: "Boodskappe",
pluginLoadFailed:
"Kon nie hierdie inprop se skrip laai nie. Kontroleer die Netwerk-oortjie (dashboard-plugins/…) en die bediener se inprop-pad.",
pluginNotRegistered:
"Die inprop se skrip het nie register() geroep nie, of die skrip het 'n fout gegee. Maak die blaaier-konsole oop vir besonderhede.",
},
app: {
brand: "Hermes Agent",
brandShort: "HA",
closeNavigation: "Maak navigasie toe",
closeModelTools: "Maak model en gereedskap toe",
footer: {
org: "Nous Research",
},
activeSessionsLabel: "Aktiewe Sessies:",
gatewayStatusLabel: "Gateway-status:",
gatewayStrip: {
failed: "Begin het misluk",
off: "Af",
running: "Loop",
starting: "Begin",
stopped: "Gestop",
},
nav: {
analytics: "Analise",
chat: "Klets",
config: "Konfigurasie",
cron: "Cron",
documentation: "Dokumentasie",
keys: "Sleutels",
logs: "Logs",
models: "Modelle",
profiles: "profiele : multi-agente",
plugins: "Inproppe",
sessions: "Sessies",
skills: "Vaardighede",
},
modelToolsSheetSubtitle: "& gereedskap",
modelToolsSheetTitle: "Model",
navigation: "Navigasie",
openDocumentation: "Maak dokumentasie in 'n nuwe oortjie oop",
openNavigation: "Maak navigasie oop",
pluginNavSection: "Inproppe",
sessionsActiveCount: "{count} aktief",
statusOverview: "Statusoorsig",
system: "Stelsel",
webUi: "Web UI",
},
status: {
actionFailed: "Aksie het misluk",
actionFinished: "Voltooi",
actions: "Aksies",
agent: "Agent",
activeSessions: "Aktiewe Sessies",
connected: "Gekoppel",
connectedPlatforms: "Gekoppelde Platforms",
disconnected: "Ontkoppel",
error: "Fout",
failed: "Misluk",
gateway: "Gateway",
gatewayFailedToStart: "Gateway kon nie begin nie",
lastUpdate: "Laaste opdatering",
noneRunning: "Geen",
notRunning: "Loop nie",
pid: "PID",
platformDisconnected: "ontkoppel",
platformError: "fout",
recentSessions: "Onlangse Sessies",
restartGateway: "Herbegin Gateway",
restartingGateway: "Besig om gateway te herbegin…",
running: "Loop",
runningRemote: "Loop (afgeleë)",
startFailed: "Begin het misluk",
starting: "Begin",
startedInBackground: "Begin in agtergrond — kyk logs vir vordering",
stopped: "Gestop",
updateHermes: "Werk Hermes op",
updatingHermes: "Besig om Hermes op te werk…",
waitingForOutput: "Wag vir uitset…",
},
sessions: {
title: "Sessies",
searchPlaceholder: "Soek boodskap-inhoud...",
noSessions: "Nog geen sessies nie",
noMatch: "Geen sessies stem ooreen met jou soektog nie",
startConversation: "Begin 'n gesprek om dit hier te sien",
noMessages: "Geen boodskappe",
untitledSession: "Sessie sonder titel",
deleteSession: "Skrap sessie",
confirmDeleteTitle: "Skrap sessie?",
confirmDeleteMessage:
"Dit verwyder die gesprek en al sy boodskappe permanent. Dit kan nie ongedaan gemaak word nie.",
sessionDeleted: "Sessie geskrap",
failedToDelete: "Kon nie sessie skrap nie",
resumeInChat: "Hervat in Klets",
previousPage: "Vorige bladsy",
nextPage: "Volgende bladsy",
roles: {
user: "Gebruiker",
assistant: "Assistent",
system: "Stelsel",
tool: "Gereedskap",
},
},
analytics: {
period: "Tydperk:",
totalTokens: "Totale Tokens",
totalSessions: "Totale Sessies",
apiCalls: "API-oproepe",
dailyTokenUsage: "Daaglikse Tokengebruik",
dailyBreakdown: "Daaglikse Uiteensetting",
perModelBreakdown: "Per-Model Uiteensetting",
topSkills: "Top Vaardighede",
skill: "Vaardigheid",
loads: "Agent Gelaai",
edits: "Agent Bestuur",
lastUsed: "Laas Gebruik",
input: "Inset",
output: "Uitset",
total: "Totaal",
noUsageData: "Geen gebruiksdata vir hierdie tydperk nie",
startSession: "Begin 'n sessie om analise hier te sien",
date: "Datum",
model: "Model",
tokens: "Tokens",
perDayAvg: "/dag gem.",
acrossModels: "oor {count} modelle",
inOut: "{input} in / {output} uit",
},
models: {
modelsUsed: "Modelle Gebruik",
estimatedCost: "Geskatte Koste",
tokens: "tokens",
sessions: "sessies",
avgPerSession: "gem./sessie",
apiCalls: "API-oproepe",
toolCalls: "gereedskap-oproepe",
noModelsData: "Geen modelgebruiksdata vir hierdie tydperk nie",
startSession: "Begin 'n sessie om modeldata hier te sien",
},
logs: {
title: "Logs",
autoRefresh: "Outo-herlaai",
file: "Lêer",
level: "Vlak",
component: "Komponent",
lines: "Reëls",
noLogLines: "Geen logreëls gevind nie",
},
cron: {
confirmDeleteMessage:
"Dit verwyder die taak van die skedule. Dit kan nie ongedaan gemaak word nie.",
confirmDeleteTitle: "Skrap geskeduleerde taak?",
newJob: "Nuwe Cron-taak",
nameOptional: "Naam (opsioneel)",
namePlaceholder: "bv. Daaglikse opsomming",
prompt: "Opdrag",
promptPlaceholder: "Wat moet die agent met elke uitvoering doen?",
schedule: "Skedule (cron-uitdrukking)",
schedulePlaceholder: "0 9 * * *",
deliverTo: "Lewer aan",
scheduledJobs: "Geskeduleerde Take",
noJobs: "Geen cron-take gekonfigureer nie. Skep een hierbo.",
last: "Laaste",
next: "Volgende",
pause: "Pouse",
resume: "Hervat",
triggerNow: "Voer nou uit",
delivery: {
local: "Plaaslik",
telegram: "Telegram",
discord: "Discord",
slack: "Slack",
email: "Email",
},
},
profiles: {
newProfile: "Nuwe Profiel",
name: "Naam",
namePlaceholder: "bv. coder, writer, ens.",
nameRequired: "Naam word vereis",
nameRule:
"Slegs kleinletters, syfers, _ en -; moet met 'n letter of syfer begin; tot 64 karakters.",
invalidName: "Ongeldige profielnaam",
cloneFromDefault: "Kloon konfigurasie vanaf verstekprofiel",
allProfiles: "Profiele",
noProfiles: "Geen profiele gevind nie.",
defaultBadge: "verstek",
hasEnv: "env",
model: "Model",
skills: "Vaardighede",
rename: "Hernoem",
editSoul: "Wysig SOUL.md",
soulSection: "SOUL.md (persoonlikheid / stelselopdrag)",
soulPlaceholder: "# Hoe hierdie agent moet optree…",
saveSoul: "Stoor SOUL",
soulSaved: "SOUL.md gestoor",
openInTerminal: "Kopieer CLI-opdrag",
commandCopied: "Na knipbord gekopieer",
copyFailed: "Kon nie kopieer nie",
confirmDeleteTitle: "Skrap profiel?",
confirmDeleteMessage:
"Dit skrap profiel '{name}' permanent — konfigurasie, sleutels, geheue, sessies, vaardighede, cron-take. Kan nie ongedaan gemaak word nie.",
created: "Geskep",
deleted: "Geskrap",
renamed: "Hernoem",
},
pluginsPage: {
contextEngineLabel: "Konteks-enjin",
dashboardSlots: "Dashboard-gleuwe",
disableRuntime: "Deaktiveer",
enableAfterInstall: "Aktiveer ná installasie",
enableRuntime: "Aktiveer",
forceReinstall: "Forseer herinstallasie (skrap eers bestaande gids)",
headline:
"Ontdek, installeer, aktiveer en werk Hermes-inproppe op (`hermes plugins` ekwivalent).",
identifierLabel: "Git-URL of owner/repo",
inactive: "onaktief",
installBtn: "Installeer vanaf Git",
installHeading: "Installeer vanaf GitHub / Git-URL",
installHint: "Gebruik owner/repo-kortvorm of 'n volledige https:// of git@ kloon-URL.",
memoryProviderLabel: "Geheueverskaffer",
missingEnvWarn: "Stel hierdie in Sleutels voordat die inprop kan loop:",
noDashboardTab: "Geen dashboard-oortjie",
openTab: "Maak oop",
orphanHeading: "Slegs-dashboard-uitbreidings (geen ooreenstemmende agent plugin.yaml nie)",
pluginListHeading: "Geïnstalleerde inproppe",
providerDefaults: "ingebou / verstek",
providersHeading: "Looptyd-verskafferinproppe",
providersHint:
"Skryf memory.provider (leeg = ingebou) en context.engine na config.yaml. Tree volgende sessie in werking.",
refreshDashboard: "Herskandeer dashboard-uitbreidings",
removeConfirm: "Verwyder hierdie inprop uit ~/.hermes/plugins/?",
removeHint: "Slegs gebruiker-geïnstalleerde inproppe onder ~/.hermes/plugins kan verwyder word.",
rescanHeading: "SPA-inprop-register",
rescanHint: "Herskandeer ná die byvoeg van lêers op skyf sodat die dashboard-sybalk nuwe manifeste optel.",
runtimeHeading: "Gateway-looptyd (YAML-inproppe)",
saveProviders: "Stoor verskaffer-instellings",
savedProviders: "Verskaffer-instellings gestoor.",
sourceBadge: "Bron",
authRequired: "Verifikasie vereis",
authRequiredHint: "Voer hierdie opdrag uit om te verifieer:",
updateGit: "Git pull",
versionBadge: "Weergawe",
showInSidebar: "Wys in sybalk",
hideFromSidebar: "Versteek van sybalk",
},
skills: {
title: "Vaardighede",
searchPlaceholder: "Soek vaardighede en gereedskapstelle...",
enabledOf: "{enabled}/{total} geaktiveer",
all: "Alles",
categories: "Kategorieë",
filters: "Filters",
noSkills: "Geen vaardighede gevind nie. Vaardighede word gelaai uit ~/.hermes/skills/",
noSkillsMatch: "Geen vaardighede stem ooreen met jou soektog of filter nie.",
skillCount: "{count} vaardighe{s}id",
resultCount: "{count} resulta{s}at",
noDescription: "Geen beskrywing beskikbaar nie.",
toolsets: "Gereedskapstelle",
toolsetLabel: "{name} gereedskapstel",
noToolsetsMatch: "Geen gereedskapstelle stem ooreen met die soektog nie.",
setupNeeded: "Opstelling nodig",
disabledForCli: "Gedeaktiveer vir CLI",
more: "+{count} meer",
},
config: {
configPath: "~/.hermes/config.yaml",
filters: "Filters",
sections: "Afdelings",
exportConfig: "Voer konfigurasie uit as JSON",
importConfig: "Voer konfigurasie in vanaf JSON",
resetDefaults: "Stel terug na verstek",
resetScopeTooltip: "Stel {scope} terug na verstek",
confirmResetScope: "Stel alle {scope}-instellings terug na hul verstek? Dit werk slegs die vorm op — veranderinge word nie na config.yaml geskryf voordat jy Stoor druk nie.",
resetScopeToast: "{scope} teruggestel na verstek — kontroleer en Stoor om te behou",
rawYaml: "Rou YAML-konfigurasie",
searchResults: "Soekresultate",
fields: "veld{s}",
noFieldsMatch: 'Geen velde stem ooreen met "{query}" nie',
configSaved: "Konfigurasie gestoor",
yamlConfigSaved: "YAML-konfigurasie gestoor",
failedToSave: "Kon nie stoor nie",
failedToSaveYaml: "Kon nie YAML stoor nie",
failedToLoadRaw: "Kon nie rou konfigurasie laai nie",
configImported: "Konfigurasie ingevoer — kontroleer en stoor",
invalidJson: "Ongeldige JSON-lêer",
categories: {
general: "Algemeen",
agent: "Agent",
terminal: "Terminaal",
display: "Vertoon",
delegation: "Delegasie",
memory: "Geheue",
compression: "Kompressie",
security: "Sekuriteit",
browser: "Blaaier",
voice: "Stem",
tts: "Teks-na-Spraak",
stt: "Spraak-na-Teks",
logging: "Aantekening",
discord: "Discord",
auxiliary: "Hulpmiddels",
},
},
env: {
changesNote: "Veranderinge word onmiddellik na skyf gestoor. Aktiewe sessies tel nuwe sleutels outomaties op.",
confirmClearMessage:
"Die gestoorde waarde vir hierdie veranderlike sal uit jou .env-lêer verwyder word. Dit kan nie vanaf die UI ongedaan gemaak word nie.",
confirmClearTitle: "Vee hierdie sleutel uit?",
description: "Bestuur API-sleutels en geheime gestoor in",
hideAdvanced: "Versteek Gevorderd",
showAdvanced: "Wys Gevorderd",
llmProviders: "LLM-verskaffers",
providersConfigured: "{configured} van {total} verskaffers gekonfigureer",
getKey: "Kry sleutel",
notConfigured: "{count} nie gekonfigureer nie",
notSet: "Nie gestel nie",
keysCount: "{count} sleutel{s}",
enterValue: "Voer waarde in...",
replaceCurrentValue: "Vervang huidige waarde ({preview})",
showValue: "Wys werklike waarde",
hideValue: "Versteek waarde",
},
oauth: {
title: "Verskaffer-aanmeldings (OAuth)",
providerLogins: "Verskaffer-aanmeldings (OAuth)",
description: "{connected} van {total} OAuth-verskaffers gekoppel. Aanmeldvloei loop tans via die CLI; klik Kopieer opdrag en plak in 'n terminaal om op te stel.",
connected: "Gekoppel",
expired: "Verval",
notConnected: "Nie gekoppel nie. Voer {command} uit in 'n terminaal.",
runInTerminal: "in 'n terminaal.",
noProviders: "Geen OAuth-bekwame verskaffers opgespoor nie.",
login: "Meld aan",
disconnect: "Ontkoppel",
managedExternally: "Ekstern bestuur",
copied: "Gekopieer ✓",
cli: "CLI",
copyCliCommand: "Kopieer CLI-opdrag (vir ekstern / terugval)",
connect: "Koppel",
sessionExpires: "Sessie verval oor {time}",
initiatingLogin: "Aanmeldvloei word begin…",
exchangingCode: "Kode word vir tokens omgeruil…",
connectedClosing: "Gekoppel! Besig om toe te maak…",
loginFailed: "Aanmelding het misluk.",
sessionExpired: "Sessie het verval. Klik Probeer weer om 'n nuwe aanmelding te begin.",
reOpenAuth: "Heropen verifikasiebladsy",
reOpenVerification: "Heropen verifikasiebladsy",
submitCode: "Dien kode in",
pasteCode: "Plak magtigingskode (met #state agtervoegsel is in die haak)",
waitingAuth: "Wag vir jou om in die blaaier te magtig…",
enterCodePrompt: "'n Nuwe oortjie het oopgegaan. Voer hierdie kode in indien gevra:",
pkceStep1: "'n Nuwe oortjie het na claude.ai oopgegaan. Meld aan en klik Magtig.",
pkceStep2: "Kopieer die magtigingskode wat ná magtiging vertoon word.",
pkceStep3: "Plak dit hieronder en dien in.",
flowLabels: {
pkce: "Blaaier-aanmelding (PKCE)",
device_code: "Toestel-kode",
external: "Eksterne CLI",
},
expiresIn: "verval oor {time}",
},
language: {
switchTo: "Skakel oor na Engels",
},
theme: {
title: "Tema",
switchTheme: "Wissel tema",
},
achievements: {
hero: {
kicker: "Agentic Gamerscore",
title: "Hermes Achievements",
subtitle:
"Versamelbare Hermes-kentekens wat verdien word uit werklike sessiegeskiedenis. Bekende, onvoltooide prestasies word as Ontdek vertoon; Geheime prestasies bly verborge totdat die eerste ooreenstemmende gedrag verskyn.",
scan_subtitle:
"Hermes-sessiegeskiedenis word geskandeer. Die eerste skandering kan 510 sekondes neem op groot geskiedenisse.",
},
actions: {
rescan: "Herskandeer",
},
stats: {
unlocked: "Ontsluit",
unlocked_hint: "verdiende kentekens",
discovered: "Ontdek",
discovered_hint: "bekend, nog nie verdien nie",
secrets: "Geheime",
secrets_hint: "verborge tot eerste sein",
highest_tier: "Hoogste vlak",
highest_tier_hint: "Copper → Silver → Gold → Diamond → Olympian",
latest: "Jongste",
latest_hint_empty: "gebruik Hermes meer",
none_yet: "Nog geen",
},
state: {
unlocked: "Ontsluit",
discovered: "Ontdek",
secret: "Geheim",
},
tier: {
target: "Teiken {tier}",
hidden: "Verborge",
complete: "Voltooi",
objective: "Doelwit",
},
progress: {
hidden: "verborge",
},
scan: {
building_headline: "Prestasieprofiel word gebou…",
building_detail:
"Sessies, gereedskaproepe, modelmetadata en ontsluitstatus word gelees.",
starting_headline: "Prestasieskandering begin…",
progress_detail:
"{scanned} van {total} sessies geskandeer · {pct}%. Kentekens ontsluit soos meer geskiedenis instroom.",
idle_detail:
"Sessies, gereedskaproepe, modelmetadata en ontsluitstatus word gelees. Kentekens verskyn hier soos hulle ontsluit.",
},
guide: {
tiers_header: "Vlakke",
secret_header: "Geheime prestasies",
secret_body:
"Geheime hou hul presiese sneller verborge. Sodra Hermes 'n verwante sein sien, word die kaart Ontdek en wys sy vereiste.",
scan_status_header: "Skanderingstatus",
scan_status_body:
"Hermes skandeer plaaslike geskiedenis een keer, daarna verskyn kaarte outomaties. Niks is vasgevang as dit 'n paar sekondes neem nie.",
what_scanned_header: "Wat geskandeer word",
what_scanned_body:
"Sessies, gereedskaproepe, modelmetadata, foute, prestasies en plaaslike ontsluitstatus.",
},
card: {
share_title: "Deel hierdie prestasie",
share_label: "Deel {name}",
share_text: "Deel",
how_to_reveal: "Hoe om te onthul",
what_counts: "Wat tel",
evidence_label: "Bewys",
evidence_session_fallback: "sessie",
no_evidence: "Nog geen bewys nie",
},
latest: {
header: "Onlangse ontsluitings",
},
empty: {
no_secrets_header: "Geen verborge geheime in hierdie skandering oor nie.",
no_secrets_body:
"Wenk: geheime begin gewoonlik by ongewone mislukkings of magsgebruikerspatrone — poortbotsings, toestemmingsmure, ontbrekende env-veranderlikes, YAML-foute, Docker-botsings, terugrol/kontrolepunt-gebruik, kasterugslae of klein regstellings na baie rooi teks.",
},
filters: {
all_categories: "Alles",
visibility_all: "alles",
visibility_unlocked: "ontsluit",
visibility_discovered: "ontdek",
visibility_secret: "geheim",
},
share: {
dialog_label: "Deel prestasie",
header: "Deel: {name}",
close: "Maak toe",
rendering: "Lewer tans…",
card_alt: "{name} deelkaart",
error_generic: "Iets het verkeerd geloop.",
x_title: "Maak X oop met 'n vooraf-ingevulde plasing",
x_button: "Deel op X",
copy_title: "Kopieer die beeld om in jou plasing te plak",
copy_button: "Kopieer beeld",
copied: "Gekopieer ✓",
download_button: "Laai PNG af",
hint:
"Deel op X maak 'n vooraf-ingevulde plasing in 'n nuwe oortjie oop. Klik eers op Kopieer beeld as jy die 1200×630-kenteken aangeheg wil hê — X laat jou dit direk in die tweet-skrywer plak. Laai PNG af stoor die lêer om enige plek te gebruik.",
clipboard_unsupported:
"Beeldkopiëring na knipbord word nie in hierdie blaaier ondersteun nie — gebruik eerder Aflaai.",
tweet_text: "Just unlocked {tier_part}\"{name}\" in Hermes Agent ☤",
},
},
kanban: {
loading: "Kanban-bord word gelaai…",
loadFailed: "Kon nie Kanban-bord laai nie: ",
loadFailedHint:
"Die agterkant skep kanban.db outomaties met die eerste lees. Indien hierdie probleem aanhou, raadpleeg die paneellogboeke.",
board: "Bord",
newBoard: "+ Nuwe bord",
newBoardTitle: "Nuwe bord",
newBoardDescription:
"Borde laat u toe om onverwante werkstrome te skei — een per projek, repositorium of domein. Werkers op een bord sien nooit 'n ander bord se take nie.",
slug: "Slug",
slugHint: "— kleinletters, koppeltekens, bv. atm10-server",
displayName: "Vertoonnaam",
displayNameHint: "(opsioneel)",
description: "Beskrywing",
descriptionHint: "(opsioneel)",
icon: "Ikoon",
iconHint: "(enkele karakter of emoji)",
switchAfterCreate: "Skakel oor na hierdie bord nadat dit geskep is",
cancel: "Kanselleer",
creating: "Word geskep…",
createBoard: "Skep bord",
search: "Soek",
filterCards: "Filter kaarte…",
tenant: "Huurder",
allTenants: "Alle huurders",
assignee: "Toegewysde",
allProfiles: "Alle profiele",
showArchived: "Wys gearchiveerde",
lanesByProfile: "Bane per profiel",
nudgeDispatcher: "Por versender aan",
refresh: "Verfris",
selected: "gekies",
complete: "Voltooi",
archive: "Argiveer",
apply: "Pas toe",
clear: "Maak skoon",
createTask: "Skep taak in hierdie kolom",
noTasks: "— geen take —",
unassigned: "nie toegewys nie",
untitled: "(sonder titel)",
loadingDetail: "Word gelaai…",
addComment: "Voeg 'n opmerking by… (Enter om in te dien)",
comment: "Opmerking",
status: "Status",
workspace: "Werkruimte",
skills: "Vaardighede",
createdBy: "Geskep deur",
result: "Resultaat",
comments: "Opmerkings",
events: "Gebeurtenisse",
runHistory: "Uitvoergeskiedenis",
workerLog: "Werker-log",
loadingLog: "Log word gelaai…",
noWorkerLog:
"— nog geen werker-log nie (taak is nog nie ontketen nie of die log is geroteer) —",
noDescription: "— geen beskrywing —",
noComments: "— geen opmerkings —",
edit: "redigeer",
save: "Stoor",
dependencies: "Afhanklikhede",
parents: "Ouers:",
children: "Kinders:",
none: "geen",
addParent: "— voeg ouer by —",
addChild: "— voeg kind by —",
removeDependency: "Verwyder afhanklikheid",
block: "Blokkeer",
unblock: "Deblokkeer",
notifyHomeChannels: "Stel tuiskanale in kennis",
diagnostics: "Diagnostiek",
hide: "Versteek",
show: "Wys",
attention: "Aandag",
tasksNeedAttention: "take benodig aandag",
taskNeedsAttention: "1 taak benodig aandag",
diagnostic: "diagnose",
open: "Maak oop",
close: "Sluit (Esc)",
reassignTo: "Hertoeken aan:",
copied: "Gekopieer",
copyCommand: "Kopieer opdrag na knipbord",
reclaim: "Heroor",
reassign: "Hertoeken",
renderingError: "Kanban-oortjie het 'n weergawefout teëgekom",
reloadView: "Herlaai aansig",
wsAuthFailed:
"WebSocket-verifikasie het misluk — herlaai die bladsy om die sessietoken te verfris.",
markDone: "Merk {n} take as klaar?",
markArchived: "Argiveer {n} take?",
warning: "Waarskuwing",
phantomIds: "Spook-ID's:",
active: "aktief",
ended: "geëindig",
noProfile: "(geen profiel)",
showAllAttempts: "Wys alle pogings",
sendingUpdates: "Stuur opdaterings na",
sendNotifications: "Stuur completed / blocked / gave_up kennisgewings na",
archiveBoardConfirm:
"Argiveer bord '{name}'? Dit sal na boards/_archived/ geskuif word sodat u dit later kan herstel. Take op hierdie bord sal nie meer in die UI verskyn nie.",
archiveBoardTitle: "Argiveer hierdie bord",
boardSwitcherHint: "Borde laat u toe om onverwante werkstrome te skei",
taskCreatedWarning: "Taak geskep, maar: ",
moveFailed: "Skuif het misluk: ",
bulkFailed: "Grootmaat: ",
completionBlockedHallucination: "⚠ Voltooiing geblokkeer — spook-kaart-ID's",
suspectedHallucinatedReferences: "⚠ Teks het na spook-kaart-ID's verwys",
pickProfileFirst: "Kies eers 'n profiel.",
unblockedMessage: "{id} gedeblokkeer. Taak is gereed vir die volgende tik.",
unblockFailed: "Deblokkering het misluk: ",
reclaimedMessage: "{id} heroor. Taak is terug op gereed.",
reclaimFailed: "Heroornaming het misluk: ",
reassignedMessage: "{id} hertoegeken aan {profile}.",
reassignFailed: "Hertoekenning het misluk: ",
selectForBulk: "Kies vir grootmaataksies",
clickToEdit: "Klik om te redigeer",
clickToEditAssignee: "Klik om toegewysde te redigeer",
emptyAssignee: "(leeg = ontbind toekenning)",
columnLabels: {
triage: "Triage",
todo: "Te doen",
ready: "Gereed",
running: "Aan die gang",
blocked: "Geblokkeer",
done: "Klaar",
archived: "Gearchiveer",
},
columnHelp: {
triage: "Rou idees — 'n spesifiseerder sal die spesifikasie uitwerk",
todo: "Wag op afhanklikhede of nie toegewys nie",
ready: "Toegewys en wag vir 'n versender-tik",
running: "Deur 'n werker geëis — in vlug",
blocked: "Werker het mensinvoer aangevra",
done: "Voltooi",
archived: "Gearchiveer",
},
confirmDone:
"Merk hierdie taak as klaar? Die werker se eis word vrygestel en afhanklike kinders word gereed.",
confirmArchive:
"Argiveer hierdie taak? Dit verdwyn uit die verstek-bordaansig.",
confirmBlocked:
"Merk hierdie taak as geblokkeer? Die werker se eis word vrygestel.",
completionSummary:
"Voltooiingsopsomming vir {label}. Dit word as die taak se result gestoor.",
completionSummaryRequired:
"'n Voltooiingsopsomming is verpligtend voordat 'n taak as klaar gemerk word.",
triagePlaceholder: "Rowwe idee — KI sal dit spesifiseer…",
taskTitlePlaceholder: "Nuwe taaktitel…",
specifier: "spesifiseerder",
assigneePlaceholder: "toegewysde",
priority: "Prioriteit",
skillsPlaceholder:
"vaardighede (opsioneel, kommageskei): translation, github-code-review",
noParent: "— geen ouer —",
workspacePathDir: "werkruimtepad (verpligtend, bv. ~/projects/my-app)",
workspacePathOptional:
"werkruimtepad (opsioneel, afgelei van toegewysde indien leeg)",
logTruncated: "(toon laaste 100 KB — volledige log by ",
logAt: ")",
},
};

View file

@ -2,14 +2,74 @@ import { createContext, useContext, useState, useCallback, type ReactNode } from
import type { Locale, Translations } from "./types";
import { en } from "./en";
import { zh } from "./zh";
import { zhHant } from "./zh-hant";
import { ja } from "./ja";
import { de } from "./de";
import { es } from "./es";
import { fr } from "./fr";
import { tr } from "./tr";
import { uk } from "./uk";
import { af } from "./af";
import { ko } from "./ko";
import { it } from "./it";
import { ga } from "./ga";
import { pt } from "./pt";
import { ru } from "./ru";
import { hu } from "./hu";
const TRANSLATIONS: Record<Locale, Translations> = { en, zh };
const TRANSLATIONS: Record<Locale, Translations> = {
en,
zh,
"zh-hant": zhHant,
ja,
de,
es,
fr,
tr,
uk,
af,
ko,
it,
ga,
pt,
ru,
hu,
};
// Display metadata for the language picker — endonym (native name) so users
// recognize their language even if they don't speak the current UI language,
// plus a flag emoji for visual scanning. Exposed as a constant so the
// LanguageSwitcher and any future settings page can share the same list.
export const LOCALE_META: Record<Locale, { name: string; flag: string }> = {
en: { name: "English", flag: "🇬🇧" },
zh: { name: "简体中文", flag: "🇨🇳" },
"zh-hant": { name: "繁體中文", flag: "🇹🇼" },
ja: { name: "日本語", flag: "🇯🇵" },
de: { name: "Deutsch", flag: "🇩🇪" },
es: { name: "Español", flag: "🇪🇸" },
fr: { name: "Français", flag: "🇫🇷" },
tr: { name: "Türkçe", flag: "🇹🇷" },
uk: { name: "Українська", flag: "🇺🇦" },
af: { name: "Afrikaans", flag: "🇿🇦" },
ko: { name: "한국어", flag: "🇰🇷" },
it: { name: "Italiano", flag: "🇮🇹" },
ga: { name: "Gaeilge", flag: "🇮🇪" },
pt: { name: "Português", flag: "🇵🇹" },
ru: { name: "Русский", flag: "🇷🇺" },
hu: { name: "Magyar", flag: "🇭🇺" },
};
const SUPPORTED_LOCALES = Object.keys(TRANSLATIONS) as Locale[];
const STORAGE_KEY = "hermes-locale";
function isLocale(value: string): value is Locale {
return (SUPPORTED_LOCALES as string[]).includes(value);
}
function getInitialLocale(): Locale {
try {
const stored = localStorage.getItem(STORAGE_KEY);
if (stored === "en" || stored === "zh") return stored;
if (stored && isLocale(stored)) return stored;
} catch {
// SSR or privacy mode
}

695
web/src/i18n/de.ts Normal file
View file

@ -0,0 +1,695 @@
import type { Translations } from "./types";
export const de: Translations = {
common: {
save: "Speichern",
saving: "Speichern...",
cancel: "Abbrechen",
close: "Schließen",
confirm: "Bestätigen",
delete: "Löschen",
refresh: "Aktualisieren",
retry: "Erneut versuchen",
search: "Suchen...",
loading: "Lädt...",
create: "Erstellen",
creating: "Erstellen...",
set: "Festlegen",
replace: "Ersetzen",
clear: "Leeren",
live: "Live",
off: "Aus",
enabled: "aktiviert",
disabled: "deaktiviert",
active: "aktiv",
inactive: "inaktiv",
unknown: "unbekannt",
untitled: "Ohne Titel",
none: "Keine",
form: "Formular",
noResults: "Keine Ergebnisse",
of: "von",
page: "Seite",
msgs: "Nachr.",
tools: "Werkzeuge",
match: "Treffer",
other: "Sonstige",
configured: "konfiguriert",
removed: "entfernt",
failedToToggle: "Umschalten fehlgeschlagen",
failedToRemove: "Entfernen fehlgeschlagen",
failedToReveal: "Anzeigen fehlgeschlagen",
collapse: "Einklappen",
expand: "Ausklappen",
general: "Allgemein",
messaging: "Messaging",
pluginLoadFailed:
"Das Skript dieses Plugins konnte nicht geladen werden. Prüfe den Netzwerk-Tab (dashboard-plugins/…) und den Plugin-Pfad des Servers.",
pluginNotRegistered:
"Das Skript des Plugins hat register() nicht aufgerufen oder ist fehlgeschlagen. Öffne die Browser-Konsole für Details.",
},
app: {
brand: "Hermes Agent",
brandShort: "HA",
closeNavigation: "Navigation schließen",
closeModelTools: "Modell und Werkzeuge schließen",
footer: {
org: "Nous Research",
},
activeSessionsLabel: "Aktive Sitzungen:",
gatewayStatusLabel: "Gateway-Status:",
gatewayStrip: {
failed: "Start fehlgeschlagen",
off: "Aus",
running: "Läuft",
starting: "Startet",
stopped: "Gestoppt",
},
nav: {
analytics: "Analyse",
chat: "Chat",
config: "Konfiguration",
cron: "Cron",
documentation: "Dokumentation",
keys: "Schlüssel",
logs: "Protokolle",
models: "Modelle",
profiles: "Profile : Multi-Agenten",
plugins: "Plugins",
sessions: "Sitzungen",
skills: "Skills",
},
modelToolsSheetSubtitle: "& Werkzeuge",
modelToolsSheetTitle: "Modell",
navigation: "Navigation",
openDocumentation: "Dokumentation in neuem Tab öffnen",
openNavigation: "Navigation öffnen",
pluginNavSection: "Plugins",
sessionsActiveCount: "{count} aktiv",
statusOverview: "Statusübersicht",
system: "System",
webUi: "Web UI",
},
status: {
actionFailed: "Aktion fehlgeschlagen",
actionFinished: "Abgeschlossen",
actions: "Aktionen",
agent: "Agent",
activeSessions: "Aktive Sitzungen",
connected: "Verbunden",
connectedPlatforms: "Verbundene Plattformen",
disconnected: "Getrennt",
error: "Fehler",
failed: "Fehlgeschlagen",
gateway: "Gateway",
gatewayFailedToStart: "Gateway konnte nicht gestartet werden",
lastUpdate: "Letzte Aktualisierung",
noneRunning: "Keine",
notRunning: "Läuft nicht",
pid: "PID",
platformDisconnected: "getrennt",
platformError: "Fehler",
recentSessions: "Letzte Sitzungen",
restartGateway: "Gateway neu starten",
restartingGateway: "Gateway wird neu gestartet…",
running: "Läuft",
runningRemote: "Läuft (remote)",
startFailed: "Start fehlgeschlagen",
starting: "Startet",
startedInBackground: "Im Hintergrund gestartet — siehe Protokolle für den Fortschritt",
stopped: "Gestoppt",
updateHermes: "Hermes aktualisieren",
updatingHermes: "Hermes wird aktualisiert…",
waitingForOutput: "Warte auf Ausgabe…",
},
sessions: {
title: "Sitzungen",
searchPlaceholder: "Nachrichteninhalt suchen...",
noSessions: "Noch keine Sitzungen",
noMatch: "Keine Sitzungen entsprechen deiner Suche",
startConversation: "Starte eine Unterhaltung, um sie hier zu sehen",
noMessages: "Keine Nachrichten",
untitledSession: "Sitzung ohne Titel",
deleteSession: "Sitzung löschen",
confirmDeleteTitle: "Sitzung löschen?",
confirmDeleteMessage:
"Dies entfernt die Unterhaltung und alle Nachrichten dauerhaft. Dies kann nicht rückgängig gemacht werden.",
sessionDeleted: "Sitzung gelöscht",
failedToDelete: "Sitzung konnte nicht gelöscht werden",
resumeInChat: "Im Chat fortsetzen",
previousPage: "Vorherige Seite",
nextPage: "Nächste Seite",
roles: {
user: "Benutzer",
assistant: "Assistent",
system: "System",
tool: "Werkzeug",
},
},
analytics: {
period: "Zeitraum:",
totalTokens: "Tokens gesamt",
totalSessions: "Sitzungen gesamt",
apiCalls: "API-Aufrufe",
dailyTokenUsage: "Tägliche Token-Nutzung",
dailyBreakdown: "Tagesaufschlüsselung",
perModelBreakdown: "Aufschlüsselung pro Modell",
topSkills: "Top-Skills",
skill: "Skill",
loads: "Agent geladen",
edits: "Agent verwaltet",
lastUsed: "Zuletzt verwendet",
input: "Eingabe",
output: "Ausgabe",
total: "Gesamt",
noUsageData: "Keine Nutzungsdaten für diesen Zeitraum",
startSession: "Starte eine Sitzung, um hier Analysen zu sehen",
date: "Datum",
model: "Modell",
tokens: "Tokens",
perDayAvg: "/Tag Ø",
acrossModels: "über {count} Modelle",
inOut: "{input} ein / {output} aus",
},
models: {
modelsUsed: "Verwendete Modelle",
estimatedCost: "Gesch. Kosten",
tokens: "Tokens",
sessions: "Sitzungen",
avgPerSession: "Ø/Sitzung",
apiCalls: "API-Aufrufe",
toolCalls: "Werkzeug-Aufrufe",
noModelsData: "Keine Modellnutzungsdaten für diesen Zeitraum",
startSession: "Starte eine Sitzung, um hier Modelldaten zu sehen",
},
logs: {
title: "Protokolle",
autoRefresh: "Auto-Aktualisierung",
file: "Datei",
level: "Stufe",
component: "Komponente",
lines: "Zeilen",
noLogLines: "Keine Protokollzeilen gefunden",
},
cron: {
confirmDeleteMessage:
"Damit wird die Aufgabe aus dem Zeitplan entfernt. Dies kann nicht rückgängig gemacht werden.",
confirmDeleteTitle: "Geplante Aufgabe löschen?",
newJob: "Neue Cron-Aufgabe",
nameOptional: "Name (optional)",
namePlaceholder: "z. B. Tägliche Zusammenfassung",
prompt: "Prompt",
promptPlaceholder: "Was soll der Agent bei jedem Lauf tun?",
schedule: "Zeitplan (Cron-Ausdruck)",
schedulePlaceholder: "0 9 * * *",
deliverTo: "Zustellen an",
scheduledJobs: "Geplante Aufgaben",
noJobs: "Keine Cron-Aufgaben konfiguriert. Erstelle oben eine.",
last: "Zuletzt",
next: "Nächste",
pause: "Pausieren",
resume: "Fortsetzen",
triggerNow: "Jetzt auslösen",
delivery: {
local: "Lokal",
telegram: "Telegram",
discord: "Discord",
slack: "Slack",
email: "Email",
},
},
profiles: {
newProfile: "Neues Profil",
name: "Name",
namePlaceholder: "z. B. coder, writer usw.",
nameRequired: "Name ist erforderlich",
nameRule:
"Nur Kleinbuchstaben, Ziffern, _ und -; muss mit einem Buchstaben oder einer Ziffer beginnen; maximal 64 Zeichen.",
invalidName: "Ungültiger Profilname",
cloneFromDefault: "Konfiguration vom Standardprofil klonen",
allProfiles: "Profile",
noProfiles: "Keine Profile gefunden.",
defaultBadge: "Standard",
hasEnv: "env",
model: "Modell",
skills: "Skills",
rename: "Umbenennen",
editSoul: "SOUL.md bearbeiten",
soulSection: "SOUL.md (Persönlichkeit / System-Prompt)",
soulPlaceholder: "# Wie sich dieser Agent verhalten soll…",
saveSoul: "SOUL speichern",
soulSaved: "SOUL.md gespeichert",
openInTerminal: "CLI-Befehl kopieren",
commandCopied: "In Zwischenablage kopiert",
copyFailed: "Kopieren fehlgeschlagen",
confirmDeleteTitle: "Profil löschen?",
confirmDeleteMessage:
"Damit wird das Profil '{name}' dauerhaft gelöscht — Konfiguration, Schlüssel, Erinnerungen, Sitzungen, Skills, Cron-Aufgaben. Kann nicht rückgängig gemacht werden.",
created: "Erstellt",
deleted: "Gelöscht",
renamed: "Umbenannt",
},
pluginsPage: {
contextEngineLabel: "Kontext-Engine",
dashboardSlots: "Dashboard-Slots",
disableRuntime: "Deaktivieren",
enableAfterInstall: "Nach Installation aktivieren",
enableRuntime: "Aktivieren",
forceReinstall: "Neuinstallation erzwingen (bestehenden Ordner zuerst löschen)",
headline:
"Hermes-Plugins entdecken, installieren, aktivieren und aktualisieren (entspricht `hermes plugins`).",
identifierLabel: "Git-URL oder owner/repo",
inactive: "inaktiv",
installBtn: "Aus Git installieren",
installHeading: "Aus GitHub / Git-URL installieren",
installHint: "Verwende owner/repo-Kurzform oder eine vollständige https:// oder git@ Klon-URL.",
memoryProviderLabel: "Speicheranbieter",
missingEnvWarn: "Setze diese unter Schlüssel, bevor das Plugin laufen kann:",
noDashboardTab: "Kein Dashboard-Tab",
openTab: "Öffnen",
orphanHeading: "Nur-Dashboard-Erweiterungen (keine Übereinstimmung mit Agent plugin.yaml)",
pluginListHeading: "Installierte Plugins",
providerDefaults: "eingebaut / Standard",
providersHeading: "Laufzeit-Anbieter-Plugins",
providersHint:
"Schreibt memory.provider (leer = eingebaut) und context.engine in config.yaml. Wirkt sich auf die nächste Sitzung aus.",
refreshDashboard: "Dashboard-Erweiterungen erneut scannen",
removeConfirm: "Dieses Plugin aus ~/.hermes/plugins/ entfernen?",
removeHint: "Nur vom Benutzer installierte Plugins unter ~/.hermes/plugins können entfernt werden.",
rescanHeading: "SPA-Plugin-Registry",
rescanHint: "Nach dem Hinzufügen von Dateien auf dem Datenträger erneut scannen, damit die Sidebar neue Manifeste erkennt.",
runtimeHeading: "Gateway-Laufzeit (YAML-Plugins)",
saveProviders: "Anbieter-Einstellungen speichern",
savedProviders: "Anbieter-Einstellungen gespeichert.",
sourceBadge: "Quelle",
authRequired: "Authentifizierung erforderlich",
authRequiredHint: "Führe diesen Befehl aus, um dich zu authentifizieren:",
updateGit: "Git pull",
versionBadge: "Version",
showInSidebar: "In Sidebar anzeigen",
hideFromSidebar: "Aus Sidebar ausblenden",
},
skills: {
title: "Skills",
searchPlaceholder: "Skills und Toolsets suchen...",
enabledOf: "{enabled}/{total} aktiviert",
all: "Alle",
categories: "Kategorien",
filters: "Filter",
noSkills: "Keine Skills gefunden. Skills werden aus ~/.hermes/skills/ geladen",
noSkillsMatch: "Keine Skills entsprechen deiner Suche oder deinem Filter.",
skillCount: "{count} Skill{s}",
resultCount: "{count} Ergebnis{s}",
noDescription: "Keine Beschreibung verfügbar.",
toolsets: "Toolsets",
toolsetLabel: "{name} Toolset",
noToolsetsMatch: "Keine Toolsets entsprechen der Suche.",
setupNeeded: "Einrichtung erforderlich",
disabledForCli: "Für CLI deaktiviert",
more: "+{count} weitere",
},
config: {
configPath: "~/.hermes/config.yaml",
filters: "Filter",
sections: "Bereiche",
exportConfig: "Konfiguration als JSON exportieren",
importConfig: "Konfiguration aus JSON importieren",
resetDefaults: "Auf Standardwerte zurücksetzen",
resetScopeTooltip: "{scope} auf Standardwerte zurücksetzen",
confirmResetScope: "Alle {scope}-Einstellungen auf ihre Standardwerte zurücksetzen? Dies aktualisiert nur das Formular — Änderungen werden erst in config.yaml geschrieben, wenn du auf Speichern drückst.",
resetScopeToast: "{scope} auf Standardwerte zurückgesetzt — überprüfen und Speichern, um zu übernehmen",
rawYaml: "Rohe YAML-Konfiguration",
searchResults: "Suchergebnisse",
fields: "Feld{s}",
noFieldsMatch: 'Keine Felder entsprechen "{query}"',
configSaved: "Konfiguration gespeichert",
yamlConfigSaved: "YAML-Konfiguration gespeichert",
failedToSave: "Speichern fehlgeschlagen",
failedToSaveYaml: "YAML konnte nicht gespeichert werden",
failedToLoadRaw: "Rohe Konfiguration konnte nicht geladen werden",
configImported: "Konfiguration importiert — überprüfen und speichern",
invalidJson: "Ungültige JSON-Datei",
categories: {
general: "Allgemein",
agent: "Agent",
terminal: "Terminal",
display: "Anzeige",
delegation: "Delegation",
memory: "Speicher",
compression: "Komprimierung",
security: "Sicherheit",
browser: "Browser",
voice: "Stimme",
tts: "Text-zu-Sprache",
stt: "Sprache-zu-Text",
logging: "Protokollierung",
discord: "Discord",
auxiliary: "Hilfs",
},
},
env: {
changesNote: "Änderungen werden sofort auf der Festplatte gespeichert. Aktive Sitzungen übernehmen neue Schlüssel automatisch.",
confirmClearMessage:
"Der gespeicherte Wert für diese Variable wird aus deiner .env-Datei entfernt. Dies kann über die UI nicht rückgängig gemacht werden.",
confirmClearTitle: "Diesen Schlüssel löschen?",
description: "Verwalte API-Schlüssel und Geheimnisse, die hier gespeichert sind",
hideAdvanced: "Erweitert ausblenden",
showAdvanced: "Erweitert anzeigen",
llmProviders: "LLM-Anbieter",
providersConfigured: "{configured} von {total} Anbietern konfiguriert",
getKey: "Schlüssel holen",
notConfigured: "{count} nicht konfiguriert",
notSet: "Nicht gesetzt",
keysCount: "{count} Schlüssel",
enterValue: "Wert eingeben...",
replaceCurrentValue: "Aktuellen Wert ersetzen ({preview})",
showValue: "Echten Wert anzeigen",
hideValue: "Wert ausblenden",
},
oauth: {
title: "Anbieter-Logins (OAuth)",
providerLogins: "Anbieter-Logins (OAuth)",
description: "{connected} von {total} OAuth-Anbietern verbunden. Login-Abläufe laufen derzeit über die CLI; klicke auf Befehl kopieren und füge ihn in ein Terminal ein, um einzurichten.",
connected: "Verbunden",
expired: "Abgelaufen",
notConnected: "Nicht verbunden. Führe {command} in einem Terminal aus.",
runInTerminal: "in einem Terminal.",
noProviders: "Keine OAuth-fähigen Anbieter erkannt.",
login: "Anmelden",
disconnect: "Trennen",
managedExternally: "Extern verwaltet",
copied: "Kopiert ✓",
cli: "CLI",
copyCliCommand: "CLI-Befehl kopieren (für extern / Fallback)",
connect: "Verbinden",
sessionExpires: "Sitzung läuft in {time} ab",
initiatingLogin: "Login-Ablauf wird gestartet…",
exchangingCode: "Code wird gegen Tokens getauscht…",
connectedClosing: "Verbunden! Wird geschlossen…",
loginFailed: "Anmeldung fehlgeschlagen.",
sessionExpired: "Sitzung abgelaufen. Klicke auf Erneut versuchen, um eine neue Anmeldung zu starten.",
reOpenAuth: "Authentifizierungsseite erneut öffnen",
reOpenVerification: "Verifizierungsseite erneut öffnen",
submitCode: "Code einreichen",
pasteCode: "Autorisierungscode einfügen (mit #state-Suffix ist okay)",
waitingAuth: "Warte, bis du im Browser autorisierst…",
enterCodePrompt: "Ein neuer Tab wurde geöffnet. Gib bei Aufforderung diesen Code ein:",
pkceStep1: "Ein neuer Tab wurde zu claude.ai geöffnet. Melde dich an und klicke auf Autorisieren.",
pkceStep2: "Kopiere den Autorisierungscode, der nach der Autorisierung angezeigt wird.",
pkceStep3: "Füge ihn unten ein und sende ab.",
flowLabels: {
pkce: "Browser-Login (PKCE)",
device_code: "Gerätecode",
external: "Externe CLI",
},
expiresIn: "läuft in {time} ab",
},
language: {
switchTo: "Zu Englisch wechseln",
},
theme: {
title: "Design",
switchTheme: "Design wechseln",
},
achievements: {
hero: {
kicker: "Agentic Gamerscore",
title: "Hermes Achievements",
subtitle:
"Sammelbare Hermes-Abzeichen, verdient durch echten Sitzungsverlauf. Bekannte, noch nicht abgeschlossene Achievements werden als Entdeckt angezeigt; geheime Achievements bleiben verborgen, bis das erste passende Verhalten auftritt.",
scan_subtitle:
"Hermes-Sitzungsverlauf wird gescannt. Der erste Scan kann bei umfangreichem Verlauf 510 Sekunden dauern.",
},
actions: {
rescan: "Neu scannen",
},
stats: {
unlocked: "Freigeschaltet",
unlocked_hint: "verdiente Abzeichen",
discovered: "Entdeckt",
discovered_hint: "bekannt, noch nicht verdient",
secrets: "Geheimnisse",
secrets_hint: "verborgen bis zum ersten Signal",
highest_tier: "Höchste Stufe",
highest_tier_hint: "Copper → Silver → Gold → Diamond → Olympian",
latest: "Neueste",
latest_hint_empty: "nutze Hermes mehr",
none_yet: "Noch keine",
},
state: {
unlocked: "Freigeschaltet",
discovered: "Entdeckt",
secret: "Geheim",
},
tier: {
target: "Ziel {tier}",
hidden: "Verborgen",
complete: "Abgeschlossen",
objective: "Ziel",
},
progress: {
hidden: "verborgen",
},
scan: {
building_headline: "Achievement-Profil wird erstellt…",
building_detail:
"Sitzungen, Tool-Aufrufe, Modell-Metadaten und Freischaltstatus werden gelesen.",
starting_headline: "Achievement-Scan wird gestartet…",
progress_detail:
"{scanned} von {total} Sitzungen gescannt · {pct}%. Abzeichen werden freigeschaltet, sobald mehr Verlauf eingelesen wird.",
idle_detail:
"Sitzungen, Tool-Aufrufe, Modell-Metadaten und Freischaltstatus werden gelesen. Abzeichen erscheinen hier, sobald sie freigeschaltet werden.",
},
guide: {
tiers_header: "Stufen",
secret_header: "Geheime Achievements",
secret_body:
"Geheimnisse verbergen ihren genauen Auslöser. Sobald Hermes ein verwandtes Signal erkennt, wird die Karte zu Entdeckt und zeigt ihre Anforderung an.",
scan_status_header: "Scan-Status",
scan_status_body:
"Hermes scannt den lokalen Verlauf einmalig, danach erscheinen die Karten automatisch. Es ist nichts hängengeblieben, wenn dies ein paar Sekunden dauert.",
what_scanned_header: "Was gescannt wird",
what_scanned_body:
"Sitzungen, Tool-Aufrufe, Modell-Metadaten, Fehler, Achievements und lokaler Freischaltstatus.",
},
card: {
share_title: "Dieses Achievement teilen",
share_label: "{name} teilen",
share_text: "Teilen",
how_to_reveal: "Wie aufdecken",
what_counts: "Was zählt",
evidence_label: "Beleg",
evidence_session_fallback: "Sitzung",
no_evidence: "Noch kein Beleg",
},
latest: {
header: "Letzte Freischaltungen",
},
empty: {
no_secrets_header: "Keine verborgenen Geheimnisse mehr in diesem Scan.",
no_secrets_body:
"Hinweis: Geheimnisse beginnen meist bei ungewöhnlichen Fehlern oder Power-User-Mustern Port-Konflikten, Berechtigungswänden, fehlenden Umgebungsvariablen, YAML-Fehlern, Docker-Kollisionen, Rollback-/Checkpoint-Nutzung, Cache-Treffern oder kleinen Fixes nach viel rotem Text.",
},
filters: {
all_categories: "Alle",
visibility_all: "alle",
visibility_unlocked: "freigeschaltet",
visibility_discovered: "entdeckt",
visibility_secret: "geheim",
},
share: {
dialog_label: "Achievement teilen",
header: "Teilen: {name}",
close: "Schließen",
rendering: "Wird gerendert…",
card_alt: "{name} Share-Karte",
error_generic: "Etwas ist schiefgelaufen.",
x_title: "Öffnet X mit einem vorgefertigten Post",
x_button: "Auf X teilen",
copy_title: "Bild kopieren, um es in deinen Post einzufügen",
copy_button: "Bild kopieren",
copied: "Kopiert ✓",
download_button: "PNG herunterladen",
hint:
"Auf X teilen öffnet einen vorgefertigten Post in einem neuen Tab. Klicke zuerst auf Bild kopieren, wenn du das 1200×630-Abzeichen anhängen möchtest X lässt dich es direkt in den Tweet-Editor einfügen. PNG herunterladen speichert die Datei zur Nutzung an beliebiger Stelle.",
clipboard_unsupported:
"Bildkopie über die Zwischenablage wird in diesem Browser nicht unterstützt nutze stattdessen Herunterladen.",
tweet_text: "Just unlocked {tier_part}\"{name}\" in Hermes Agent ☤",
},
},
kanban: {
loading: "Kanban-Board wird geladen…",
loadFailed: "Laden des Kanban-Boards fehlgeschlagen: ",
loadFailedHint:
"Das Backend erstellt kanban.db beim ersten Lesen automatisch. Wenn das Problem bestehen bleibt, prüfe die Dashboard-Logs.",
board: "Board",
newBoard: "+ Neues Board",
newBoardTitle: "Neues Board",
newBoardDescription:
"Mit Boards kannst du voneinander unabhängige Arbeitsabläufe trennen — eines pro Projekt, Repository oder Domäne. Worker auf einem Board sehen niemals die Aufgaben eines anderen Boards.",
slug: "Slug",
slugHint: "— Kleinbuchstaben, Bindestriche, z. B. atm10-server",
displayName: "Anzeigename",
displayNameHint: "(optional)",
description: "Beschreibung",
descriptionHint: "(optional)",
icon: "Symbol",
iconHint: "(einzelnes Zeichen oder Emoji)",
switchAfterCreate: "Nach dem Erstellen zu diesem Board wechseln",
cancel: "Abbrechen",
creating: "Wird erstellt…",
createBoard: "Board erstellen",
search: "Suchen",
filterCards: "Karten filtern…",
tenant: "Tenant",
allTenants: "Alle Tenants",
assignee: "Zuständige Person",
allProfiles: "Alle Profile",
showArchived: "Archivierte anzeigen",
lanesByProfile: "Spuren nach Profil",
nudgeDispatcher: "Dispatcher anstoßen",
refresh: "Aktualisieren",
selected: "ausgewählt",
complete: "Abschließen",
archive: "Archivieren",
apply: "Anwenden",
clear: "Zurücksetzen",
createTask: "Aufgabe in dieser Spalte erstellen",
noTasks: "— keine Aufgaben —",
unassigned: "nicht zugewiesen",
untitled: "(ohne Titel)",
loadingDetail: "Wird geladen…",
addComment: "Kommentar hinzufügen… (Enter zum Senden)",
comment: "Kommentar",
status: "Status",
workspace: "Arbeitsbereich",
skills: "Fähigkeiten",
createdBy: "Erstellt von",
result: "Ergebnis",
comments: "Kommentare",
events: "Ereignisse",
runHistory: "Ausführungsverlauf",
workerLog: "Worker-Log",
loadingLog: "Log wird geladen…",
noWorkerLog:
"— noch kein Worker-Log (Aufgabe wurde nicht gestartet oder Log wurde rotiert) —",
noDescription: "— keine Beschreibung —",
noComments: "— keine Kommentare —",
edit: "bearbeiten",
save: "Speichern",
dependencies: "Abhängigkeiten",
parents: "Übergeordnet:",
children: "Untergeordnet:",
none: "keine",
addParent: "— übergeordnete Aufgabe hinzufügen —",
addChild: "— untergeordnete Aufgabe hinzufügen —",
removeDependency: "Abhängigkeit entfernen",
block: "Blockieren",
unblock: "Freigeben",
notifyHomeChannels: "Home-Kanäle benachrichtigen",
diagnostics: "Diagnose",
hide: "Ausblenden",
show: "Anzeigen",
attention: "Achtung",
tasksNeedAttention: "Aufgaben benötigen Aufmerksamkeit",
taskNeedsAttention: "1 Aufgabe benötigt Aufmerksamkeit",
diagnostic: "Diagnose",
open: "Öffnen",
close: "Schließen (Esc)",
reassignTo: "Neu zuweisen an:",
copied: "Kopiert",
copyCommand: "Befehl in die Zwischenablage kopieren",
reclaim: "Zurückholen",
reassign: "Neu zuweisen",
renderingError: "Im Kanban-Tab ist ein Renderfehler aufgetreten",
reloadView: "Ansicht neu laden",
wsAuthFailed:
"WebSocket-Authentifizierung fehlgeschlagen — lade die Seite neu, um das Sitzungs-Token zu aktualisieren.",
markDone: "{n} Aufgabe(n) als erledigt markieren?",
markArchived: "{n} Aufgabe(n) archivieren?",
warning: "Warnung",
phantomIds: "Phantom-IDs:",
active: "aktiv",
ended: "beendet",
noProfile: "(kein Profil)",
showAllAttempts: "Alle Versuche anzeigen",
sendingUpdates: "Aktualisierungen werden gesendet an ",
sendNotifications: "Benachrichtigungen für Abgeschlossen / Blockiert / Aufgegeben senden an",
archiveBoardConfirm:
"Board „{name}“ archivieren? Es wird nach boards/_archived/ verschoben, sodass du es später wiederherstellen kannst. Aufgaben auf diesem Board erscheinen nirgendwo mehr in der UI.",
archiveBoardTitle: "Dieses Board archivieren",
boardSwitcherHint: "Mit Boards kannst du voneinander unabhängige Arbeitsabläufe trennen",
taskCreatedWarning: "Aufgabe erstellt, aber: ",
moveFailed: "Verschieben fehlgeschlagen: ",
bulkFailed: "Bulk: ",
completionBlockedHallucination: "⚠ Abschluss blockiert — Phantom-Karten-IDs",
suspectedHallucinatedReferences: "⚠ Text verweist auf Phantom-Karten-IDs",
pickProfileFirst: "Wähle zuerst ein Profil aus.",
unblockedMessage: "{id} freigegeben. Aufgabe ist bereit für den nächsten Tick.",
unblockFailed: "Freigeben fehlgeschlagen: ",
reclaimedMessage: "{id} zurückgeholt. Aufgabe ist wieder auf ready.",
reclaimFailed: "Zurückholen fehlgeschlagen: ",
reassignedMessage: "{id} an {profile} neu zugewiesen.",
reassignFailed: "Neu zuweisen fehlgeschlagen: ",
selectForBulk: "Für Bulk-Aktionen auswählen",
clickToEdit: "Zum Bearbeiten klicken",
clickToEditAssignee: "Klicken, um zuständige Person zu bearbeiten",
emptyAssignee: "(leer = Zuweisung aufheben)",
columnLabels: {
triage: "Triage",
todo: "Zu erledigen",
ready: "Bereit",
running: "In Bearbeitung",
blocked: "Blockiert",
done: "Erledigt",
archived: "Archiviert",
},
columnHelp: {
triage: "Rohe Ideen — ein Specifier wird die Spezifikation ausarbeiten",
todo: "Wartet auf Abhängigkeiten oder ist nicht zugewiesen",
ready: "Zugewiesen und wartet auf einen Dispatcher-Tick",
running: "Von einem Worker übernommen — in Bearbeitung",
blocked: "Worker hat um menschliche Eingabe gebeten",
done: "Abgeschlossen",
archived: "Archiviert",
},
confirmDone:
"Diese Aufgabe als erledigt markieren? Der Anspruch des Workers wird freigegeben und abhängige untergeordnete Aufgaben werden bereit.",
confirmArchive:
"Diese Aufgabe archivieren? Sie verschwindet aus der Standard-Board-Ansicht.",
confirmBlocked:
"Diese Aufgabe als blockiert markieren? Der Anspruch des Workers wird freigegeben.",
completionSummary:
"Abschluss-Zusammenfassung für {label}. Diese wird als Ergebnis der Aufgabe gespeichert.",
completionSummaryRequired:
"Eine Abschluss-Zusammenfassung ist erforderlich, bevor eine Aufgabe als erledigt markiert werden kann.",
triagePlaceholder: "Grobe Idee — die KI wird die Spezifikation erstellen…",
taskTitlePlaceholder: "Titel der neuen Aufgabe…",
specifier: "Specifier",
assigneePlaceholder: "Zuständige Person",
priority: "Priorität",
skillsPlaceholder:
"Fähigkeiten (optional, kommagetrennt): translation, github-code-review",
noParent: "— keine übergeordnete Aufgabe —",
workspacePathDir: "Arbeitsbereichs-Pfad (erforderlich, z. B. ~/projects/my-app)",
workspacePathOptional:
"Arbeitsbereichs-Pfad (optional, wird aus zuständiger Person abgeleitet, wenn leer)",
logTruncated: "(zeige die letzten 100 KB — vollständiges Log unter ",
logAt: ")",
},
};

View file

@ -426,4 +426,272 @@ export const en: Translations = {
title: "Theme",
switchTheme: "Switch theme",
},
achievements: {
hero: {
kicker: "Agentic Gamerscore",
title: "Hermes Achievements",
subtitle:
"Collectible Hermes badges earned from real session history. Known unfinished achievements are shown as Discovered; Secret achievements stay hidden until the first matching behavior appears.",
scan_subtitle:
"Scanning Hermes session history. First scan can take 510 seconds on large histories.",
},
actions: {
rescan: "Rescan",
},
stats: {
unlocked: "Unlocked",
unlocked_hint: "earned badges",
discovered: "Discovered",
discovered_hint: "known, not earned yet",
secrets: "Secrets",
secrets_hint: "hidden until first signal",
highest_tier: "Highest tier",
highest_tier_hint: "Copper → Silver → Gold → Diamond → Olympian",
latest: "Latest",
latest_hint_empty: "run Hermes more",
none_yet: "None yet",
},
state: {
unlocked: "Unlocked",
discovered: "Discovered",
secret: "Secret",
},
tier: {
target: "Target {tier}",
hidden: "Hidden",
complete: "Complete",
objective: "Objective",
},
progress: {
hidden: "hidden",
},
scan: {
building_headline: "Building achievement profile…",
building_detail:
"Reading sessions, tool calls, model metadata, and unlock state.",
starting_headline: "Starting achievement scan…",
progress_detail:
"Scanned {scanned} of {total} sessions · {pct}%. Badges unlock as more history streams in.",
idle_detail:
"Reading sessions, tool calls, model metadata, and unlock state. Badges appear here as they unlock.",
},
guide: {
tiers_header: "Tiers",
secret_header: "Secret achievements",
secret_body:
"Secrets hide their exact trigger. Once Hermes sees a related signal, the card becomes Discovered and shows its requirement.",
scan_status_header: "Scan status",
scan_status_body:
"Hermes is scanning local history once, then cards will appear automatically. Nothing is stuck if this takes a few seconds.",
what_scanned_header: "What is scanned",
what_scanned_body:
"Sessions, tool calls, model metadata, errors, achievements, and local unlock state.",
},
card: {
share_title: "Share this achievement",
share_label: "Share {name}",
share_text: "Share",
how_to_reveal: "How to reveal",
what_counts: "What counts",
evidence_label: "Evidence",
evidence_session_fallback: "session",
no_evidence: "No evidence yet",
},
latest: {
header: "Recent unlocks",
},
empty: {
no_secrets_header: "No hidden secrets left in this scan.",
no_secrets_body:
"Clue: secrets usually start from unusual failure or power-user patterns — port conflicts, permission walls, missing env vars, YAML mistakes, Docker collisions, rollback/checkpoint use, cache hits, or tiny fixes after lots of red text.",
},
filters: {
all_categories: "All",
visibility_all: "all",
visibility_unlocked: "unlocked",
visibility_discovered: "discovered",
visibility_secret: "secret",
},
share: {
dialog_label: "Share achievement",
header: "Share: {name}",
close: "Close",
rendering: "Rendering…",
card_alt: "{name} share card",
error_generic: "Something went wrong.",
x_title: "Opens X with a pre-filled post",
x_button: "Share on X",
copy_title: "Copy the image to paste into your post",
copy_button: "Copy image",
copied: "Copied ✓",
download_button: "Download PNG",
hint:
"Share on X opens a pre-filled post in a new tab. Click Copy image first if you want the 1200×630 badge attached — X lets you paste it right into the tweet composer. Download PNG saves the file for use anywhere.",
clipboard_unsupported:
"Clipboard image copy not supported in this browser — use Download instead.",
tweet_text: "Just unlocked {tier_part}\"{name}\" in Hermes Agent ☤",
},
},
kanban: {
loading: "Loading Kanban board…",
loadFailed: "Failed to load Kanban board: ",
loadFailedHint:
"The backend auto-creates kanban.db on first read. If this persists, check the dashboard logs.",
board: "Board",
newBoard: "+ New board",
newBoardTitle: "New board",
newBoardDescription:
"Boards let you separate unrelated streams of work — one per project, repo, or domain. Workers on one board never see another board's tasks.",
slug: "Slug",
slugHint: "— lowercase, hyphens, e.g. atm10-server",
displayName: "Display name",
displayNameHint: "(optional)",
description: "Description",
descriptionHint: "(optional)",
icon: "Icon",
iconHint: "(single character or emoji)",
switchAfterCreate: "Switch to this board after creating it",
cancel: "Cancel",
creating: "Creating…",
createBoard: "Create board",
search: "Search",
filterCards: "Filter cards…",
tenant: "Tenant",
allTenants: "All tenants",
assignee: "Assignee",
allProfiles: "All profiles",
showArchived: "Show archived",
lanesByProfile: "Lanes by profile",
nudgeDispatcher: "Nudge dispatcher",
refresh: "Refresh",
selected: "selected",
complete: "Complete",
archive: "Archive",
apply: "Apply",
clear: "Clear",
createTask: "Create task in this column",
noTasks: "— no tasks —",
unassigned: "unassigned",
untitled: "(untitled)",
loadingDetail: "Loading…",
addComment: "Add a comment… (Enter to submit)",
comment: "Comment",
status: "Status",
workspace: "Workspace",
skills: "Skills",
createdBy: "Created by",
result: "Result",
comments: "Comments",
events: "Events",
runHistory: "Run history",
workerLog: "Worker log",
loadingLog: "Loading log…",
noWorkerLog:
"— no worker log yet (task hasn't spawned or log was rotated away) —",
noDescription: "— no description —",
noComments: "— no comments —",
edit: "edit",
save: "Save",
dependencies: "Dependencies",
parents: "Parents:",
children: "Children:",
none: "none",
addParent: "— add parent —",
addChild: "— add child —",
removeDependency: "Remove dependency",
block: "Block",
unblock: "Unblock",
notifyHomeChannels: "Notify home channels",
diagnostics: "Diagnostics",
hide: "Hide",
show: "Show",
attention: "Attention",
tasksNeedAttention: "tasks need attention",
taskNeedsAttention: "1 task needs attention",
diagnostic: "diagnostic",
open: "Open",
close: "Close (Esc)",
reassignTo: "Reassign to:",
copied: "Copied",
copyCommand: "Copy command to clipboard",
reclaim: "Reclaim",
reassign: "Reassign",
renderingError: "Kanban tab hit a rendering error",
reloadView: "Reload view",
wsAuthFailed:
"WebSocket auth failed — reload the page to refresh the session token.",
markDone: "Mark {n} task(s) as done?",
markArchived: "Archive {n} task(s)?",
warning: "Warning",
phantomIds: "Phantom ids:",
active: "active",
ended: "ended",
noProfile: "(no profile)",
showAllAttempts: "Show all attempts",
sendingUpdates: "Sending updates to",
sendNotifications: "Send completed / blocked / gave_up notifications to",
archiveBoardConfirm:
"Archive board '{name}'? It will be moved to boards/_archived/ so you can recover it later. Tasks on this board will no longer appear anywhere in the UI.",
archiveBoardTitle: "Archive this board",
boardSwitcherHint: "Boards let you separate unrelated streams of work",
taskCreatedWarning: "Task created, but: ",
moveFailed: "Move failed: ",
bulkFailed: "Bulk: ",
completionBlockedHallucination: "⚠ Completion blocked — phantom card ids",
suspectedHallucinatedReferences: "⚠ Prose referenced phantom card ids",
pickProfileFirst: "Pick a profile first.",
unblockedMessage: "Unblocked {id}. Task is ready for the next tick.",
unblockFailed: "Unblock failed: ",
reclaimedMessage: "Reclaimed {id}. Task is back to ready.",
reclaimFailed: "Reclaim failed: ",
reassignedMessage: "Reassigned {id} to {profile}.",
reassignFailed: "Reassign failed: ",
selectForBulk: "Select for bulk actions",
clickToEdit: "Click to edit",
clickToEditAssignee: "Click to edit assignee",
emptyAssignee: "(empty = unassign)",
columnLabels: {
triage: "Triage",
todo: "Todo",
ready: "Ready",
running: "In Progress",
blocked: "Blocked",
done: "Done",
archived: "Archived",
},
columnHelp: {
triage: "Raw ideas — a specifier will flesh out the spec",
todo: "Waiting on dependencies or unassigned",
ready: "Assigned and waiting for a dispatcher tick",
running: "Claimed by a worker — in-flight",
blocked: "Worker asked for human input",
done: "Completed",
archived: "Archived",
},
confirmDone:
"Mark this task as done? The worker's claim is released and dependent children become ready.",
confirmArchive:
"Archive this task? It disappears from the default board view.",
confirmBlocked:
"Mark this task as blocked? The worker's claim is released.",
completionSummary:
"Completion summary for {label}. This is stored as the task result.",
completionSummaryRequired:
"Completion summary is required before marking a task done.",
triagePlaceholder: "Rough idea — AI will spec it…",
taskTitlePlaceholder: "New task title…",
specifier: "specifier",
assigneePlaceholder: "assignee",
priority: "Priority",
skillsPlaceholder:
"skills (optional, comma-separated): translation, github-code-review",
noParent: "— no parent —",
workspacePathDir: "workspace path (required, e.g. ~/projects/my-app)",
workspacePathOptional:
"workspace path (optional, derived from assignee if blank)",
logTruncated: "(showing last 100 KB — full log at ",
logAt: ")",
},
};

695
web/src/i18n/es.ts Normal file
View file

@ -0,0 +1,695 @@
import type { Translations } from "./types";
export const es: Translations = {
common: {
save: "Guardar",
saving: "Guardando...",
cancel: "Cancelar",
close: "Cerrar",
confirm: "Confirmar",
delete: "Eliminar",
refresh: "Actualizar",
retry: "Reintentar",
search: "Buscar...",
loading: "Cargando...",
create: "Crear",
creating: "Creando...",
set: "Establecer",
replace: "Reemplazar",
clear: "Limpiar",
live: "En vivo",
off: "Apagado",
enabled: "habilitado",
disabled: "deshabilitado",
active: "activo",
inactive: "inactivo",
unknown: "desconocido",
untitled: "Sin título",
none: "Ninguno",
form: "Formulario",
noResults: "Sin resultados",
of: "de",
page: "Página",
msgs: "msjs",
tools: "herramientas",
match: "coincidencia",
other: "Otros",
configured: "configurado",
removed: "eliminado",
failedToToggle: "No se pudo alternar",
failedToRemove: "No se pudo eliminar",
failedToReveal: "No se pudo mostrar",
collapse: "Contraer",
expand: "Expandir",
general: "General",
messaging: "Mensajería",
pluginLoadFailed:
"No se pudo cargar el script de este complemento. Revisa la pestaña Network (dashboard-plugins/…) y la ruta del complemento del servidor.",
pluginNotRegistered:
"El script del complemento no llamó a register(), o falló. Abre la consola del navegador para más detalles.",
},
app: {
brand: "Hermes Agent",
brandShort: "HA",
closeNavigation: "Cerrar navegación",
closeModelTools: "Cerrar modelo y herramientas",
footer: {
org: "Nous Research",
},
activeSessionsLabel: "Sesiones activas:",
gatewayStatusLabel: "Estado del Gateway:",
gatewayStrip: {
failed: "Inicio fallido",
off: "Apagado",
running: "En ejecución",
starting: "Iniciando",
stopped: "Detenido",
},
nav: {
analytics: "Analíticas",
chat: "Chat",
config: "Configuración",
cron: "Cron",
documentation: "Documentación",
keys: "Claves",
logs: "Registros",
models: "Modelos",
profiles: "perfiles : multi agentes",
plugins: "Complementos",
sessions: "Sesiones",
skills: "Habilidades",
},
modelToolsSheetSubtitle: "y herramientas",
modelToolsSheetTitle: "Modelo",
navigation: "Navegación",
openDocumentation: "Abrir documentación en una nueva pestaña",
openNavigation: "Abrir navegación",
pluginNavSection: "Complementos",
sessionsActiveCount: "{count} activas",
statusOverview: "Resumen de estado",
system: "Sistema",
webUi: "Web UI",
},
status: {
actionFailed: "Acción fallida",
actionFinished: "Finalizado",
actions: "Acciones",
agent: "Agente",
activeSessions: "Sesiones activas",
connected: "Conectado",
connectedPlatforms: "Plataformas conectadas",
disconnected: "Desconectado",
error: "Error",
failed: "Fallido",
gateway: "Gateway",
gatewayFailedToStart: "El Gateway no pudo iniciarse",
lastUpdate: "Última actualización",
noneRunning: "Ninguno",
notRunning: "No en ejecución",
pid: "PID",
platformDisconnected: "desconectado",
platformError: "error",
recentSessions: "Sesiones recientes",
restartGateway: "Reiniciar Gateway",
restartingGateway: "Reiniciando gateway…",
running: "En ejecución",
runningRemote: "En ejecución (remoto)",
startFailed: "Inicio fallido",
starting: "Iniciando",
startedInBackground: "Iniciado en segundo plano — revisa los registros para ver el progreso",
stopped: "Detenido",
updateHermes: "Actualizar Hermes",
updatingHermes: "Actualizando Hermes…",
waitingForOutput: "Esperando salida…",
},
sessions: {
title: "Sesiones",
searchPlaceholder: "Buscar contenido de mensajes...",
noSessions: "Aún no hay sesiones",
noMatch: "Ninguna sesión coincide con tu búsqueda",
startConversation: "Inicia una conversación para verla aquí",
noMessages: "Sin mensajes",
untitledSession: "Sesión sin título",
deleteSession: "Eliminar sesión",
confirmDeleteTitle: "¿Eliminar sesión?",
confirmDeleteMessage:
"Esto elimina permanentemente la conversación y todos sus mensajes. No se puede deshacer.",
sessionDeleted: "Sesión eliminada",
failedToDelete: "No se pudo eliminar la sesión",
resumeInChat: "Reanudar en el chat",
previousPage: "Página anterior",
nextPage: "Página siguiente",
roles: {
user: "Usuario",
assistant: "Asistente",
system: "Sistema",
tool: "Herramienta",
},
},
analytics: {
period: "Período:",
totalTokens: "Tokens totales",
totalSessions: "Sesiones totales",
apiCalls: "Llamadas API",
dailyTokenUsage: "Uso diario de tokens",
dailyBreakdown: "Desglose diario",
perModelBreakdown: "Desglose por modelo",
topSkills: "Habilidades principales",
skill: "Habilidad",
loads: "Agente cargó",
edits: "Agente gestionó",
lastUsed: "Último uso",
input: "Entrada",
output: "Salida",
total: "Total",
noUsageData: "No hay datos de uso para este período",
startSession: "Inicia una sesión para ver analíticas aquí",
date: "Fecha",
model: "Modelo",
tokens: "Tokens",
perDayAvg: "/día prom.",
acrossModels: "en {count} modelos",
inOut: "{input} entrada / {output} salida",
},
models: {
modelsUsed: "Modelos utilizados",
estimatedCost: "Coste est.",
tokens: "tokens",
sessions: "sesiones",
avgPerSession: "prom./sesión",
apiCalls: "llamadas API",
toolCalls: "llamadas de herramientas",
noModelsData: "No hay datos de uso de modelos para este período",
startSession: "Inicia una sesión para ver datos de modelos aquí",
},
logs: {
title: "Registros",
autoRefresh: "Actualización automática",
file: "Archivo",
level: "Nivel",
component: "Componente",
lines: "Líneas",
noLogLines: "No se encontraron líneas de registro",
},
cron: {
confirmDeleteMessage:
"Esto elimina la tarea de la programación. No se puede deshacer.",
confirmDeleteTitle: "¿Eliminar tarea programada?",
newJob: "Nueva tarea Cron",
nameOptional: "Nombre (opcional)",
namePlaceholder: "p. ej. Resumen diario",
prompt: "Prompt",
promptPlaceholder: "¿Qué debe hacer el agente en cada ejecución?",
schedule: "Programación (expresión cron)",
schedulePlaceholder: "0 9 * * *",
deliverTo: "Entregar a",
scheduledJobs: "Tareas programadas",
noJobs: "No hay tareas cron configuradas. Crea una arriba.",
last: "Última",
next: "Próxima",
pause: "Pausar",
resume: "Reanudar",
triggerNow: "Ejecutar ahora",
delivery: {
local: "Local",
telegram: "Telegram",
discord: "Discord",
slack: "Slack",
email: "Email",
},
},
profiles: {
newProfile: "Nuevo perfil",
name: "Nombre",
namePlaceholder: "p. ej. coder, writer, etc.",
nameRequired: "El nombre es obligatorio",
nameRule:
"Solo letras minúsculas, dígitos, _ y -; debe comenzar con una letra o dígito; hasta 64 caracteres.",
invalidName: "Nombre de perfil no válido",
cloneFromDefault: "Clonar configuración del perfil predeterminado",
allProfiles: "Perfiles",
noProfiles: "No se encontraron perfiles.",
defaultBadge: "predeterminado",
hasEnv: "env",
model: "Modelo",
skills: "Habilidades",
rename: "Renombrar",
editSoul: "Editar SOUL.md",
soulSection: "SOUL.md (personalidad / prompt del sistema)",
soulPlaceholder: "# Cómo debe comportarse este agente…",
saveSoul: "Guardar SOUL",
soulSaved: "SOUL.md guardado",
openInTerminal: "Copiar comando CLI",
commandCopied: "Copiado al portapapeles",
copyFailed: "No se pudo copiar",
confirmDeleteTitle: "¿Eliminar perfil?",
confirmDeleteMessage:
"Esto elimina permanentemente el perfil '{name}' — configuración, claves, memorias, sesiones, habilidades, tareas cron. No se puede deshacer.",
created: "Creado",
deleted: "Eliminado",
renamed: "Renombrado",
},
pluginsPage: {
contextEngineLabel: "Motor de contexto",
dashboardSlots: "Slots del panel",
disableRuntime: "Deshabilitar",
enableAfterInstall: "Habilitar tras instalar",
enableRuntime: "Habilitar",
forceReinstall: "Forzar reinstalación (eliminar carpeta existente primero)",
headline:
"Descubre, instala, habilita y actualiza complementos de Hermes (equivalente a `hermes plugins`).",
identifierLabel: "URL de Git u owner/repo",
inactive: "inactivo",
installBtn: "Instalar desde Git",
installHeading: "Instalar desde GitHub / URL de Git",
installHint: "Usa la forma corta owner/repo o una URL de clonación https:// o git@ completa.",
memoryProviderLabel: "Proveedor de memoria",
missingEnvWarn: "Configura estos en Claves antes de que el complemento pueda ejecutarse:",
noDashboardTab: "Sin pestaña de panel",
openTab: "Abrir",
orphanHeading: "Extensiones solo del panel (sin coincidencia de plugin.yaml del agente)",
pluginListHeading: "Complementos instalados",
providerDefaults: "incorporado / predeterminado",
providersHeading: "Complementos de proveedor en tiempo de ejecución",
providersHint:
"Escribe memory.provider (vacío = incorporado) y context.engine en config.yaml. Surte efecto en la próxima sesión.",
refreshDashboard: "Volver a escanear extensiones del panel",
removeConfirm: "¿Eliminar este complemento de ~/.hermes/plugins/?",
removeHint: "Solo se pueden eliminar complementos instalados por el usuario en ~/.hermes/plugins.",
rescanHeading: "Registro de complementos SPA",
rescanHint: "Vuelve a escanear tras añadir archivos en disco para que la barra lateral del panel detecte nuevos manifiestos.",
runtimeHeading: "Tiempo de ejecución del Gateway (complementos YAML)",
saveProviders: "Guardar configuración del proveedor",
savedProviders: "Configuración del proveedor guardada.",
sourceBadge: "Fuente",
authRequired: "Autenticación requerida",
authRequiredHint: "Ejecuta este comando para autenticarte:",
updateGit: "Git pull",
versionBadge: "Versión",
showInSidebar: "Mostrar en barra lateral",
hideFromSidebar: "Ocultar de la barra lateral",
},
skills: {
title: "Habilidades",
searchPlaceholder: "Buscar habilidades y conjuntos de herramientas...",
enabledOf: "{enabled}/{total} habilitados",
all: "Todas",
categories: "Categorías",
filters: "Filtros",
noSkills: "No se encontraron habilidades. Las habilidades se cargan desde ~/.hermes/skills/",
noSkillsMatch: "Ninguna habilidad coincide con tu búsqueda o filtro.",
skillCount: "{count} habilidad{s}",
resultCount: "{count} resultado{s}",
noDescription: "No hay descripción disponible.",
toolsets: "Conjuntos de herramientas",
toolsetLabel: "conjunto de herramientas {name}",
noToolsetsMatch: "Ningún conjunto de herramientas coincide con la búsqueda.",
setupNeeded: "Configuración necesaria",
disabledForCli: "Deshabilitado para CLI",
more: "+{count} más",
},
config: {
configPath: "~/.hermes/config.yaml",
filters: "Filtros",
sections: "Secciones",
exportConfig: "Exportar configuración como JSON",
importConfig: "Importar configuración desde JSON",
resetDefaults: "Restablecer valores predeterminados",
resetScopeTooltip: "Restablecer {scope} a los valores predeterminados",
confirmResetScope: "¿Restablecer todos los ajustes de {scope} a sus valores predeterminados? Esto solo actualiza el formulario — los cambios no se escriben en config.yaml hasta que pulses Guardar.",
resetScopeToast: "{scope} restablecido a los valores predeterminados — revisa y guarda para que persista",
rawYaml: "Configuración YAML en bruto",
searchResults: "Resultados de búsqueda",
fields: "campo{s}",
noFieldsMatch: 'Ningún campo coincide con "{query}"',
configSaved: "Configuración guardada",
yamlConfigSaved: "Configuración YAML guardada",
failedToSave: "No se pudo guardar",
failedToSaveYaml: "No se pudo guardar YAML",
failedToLoadRaw: "No se pudo cargar la configuración en bruto",
configImported: "Configuración importada — revisa y guarda",
invalidJson: "Archivo JSON no válido",
categories: {
general: "General",
agent: "Agente",
terminal: "Terminal",
display: "Pantalla",
delegation: "Delegación",
memory: "Memoria",
compression: "Compresión",
security: "Seguridad",
browser: "Navegador",
voice: "Voz",
tts: "Texto a voz",
stt: "Voz a texto",
logging: "Registro",
discord: "Discord",
auxiliary: "Auxiliar",
},
},
env: {
changesNote: "Los cambios se guardan en disco inmediatamente. Las sesiones activas adoptan las nuevas claves automáticamente.",
confirmClearMessage:
"El valor almacenado para esta variable se eliminará de tu archivo .env. Esto no se puede deshacer desde la UI.",
confirmClearTitle: "¿Limpiar esta clave?",
description: "Gestiona claves API y secretos almacenados en",
hideAdvanced: "Ocultar avanzado",
showAdvanced: "Mostrar avanzado",
llmProviders: "Proveedores LLM",
providersConfigured: "{configured} de {total} proveedores configurados",
getKey: "Obtener clave",
notConfigured: "{count} no configurados",
notSet: "No establecido",
keysCount: "{count} clave{s}",
enterValue: "Introduce un valor...",
replaceCurrentValue: "Reemplazar valor actual ({preview})",
showValue: "Mostrar valor real",
hideValue: "Ocultar valor",
},
oauth: {
title: "Inicios de sesión de proveedores (OAuth)",
providerLogins: "Inicios de sesión de proveedores (OAuth)",
description: "{connected} de {total} proveedores OAuth conectados. Los flujos de inicio de sesión actualmente se ejecutan a través de la CLI; haz clic en Copiar comando y pégalo en una terminal para configurar.",
connected: "Conectado",
expired: "Caducado",
notConnected: "No conectado. Ejecuta {command} en una terminal.",
runInTerminal: "en una terminal.",
noProviders: "No se han detectado proveedores compatibles con OAuth.",
login: "Iniciar sesión",
disconnect: "Desconectar",
managedExternally: "Gestionado externamente",
copied: "Copiado ✓",
cli: "CLI",
copyCliCommand: "Copiar comando CLI (para externo / alternativa)",
connect: "Conectar",
sessionExpires: "La sesión caduca en {time}",
initiatingLogin: "Iniciando flujo de inicio de sesión…",
exchangingCode: "Intercambiando código por tokens…",
connectedClosing: "¡Conectado! Cerrando…",
loginFailed: "Inicio de sesión fallido.",
sessionExpired: "Sesión caducada. Haz clic en Reintentar para iniciar un nuevo inicio de sesión.",
reOpenAuth: "Reabrir página de autenticación",
reOpenVerification: "Reabrir página de verificación",
submitCode: "Enviar código",
pasteCode: "Pega el código de autorización (con el sufijo #state está bien)",
waitingAuth: "Esperando que autorices en el navegador…",
enterCodePrompt: "Se abrió una nueva pestaña. Introduce este código si se solicita:",
pkceStep1: "Se abrió una nueva pestaña en claude.ai. Inicia sesión y haz clic en Autorizar.",
pkceStep2: "Copia el código de autorización mostrado tras autorizar.",
pkceStep3: "Pégalo abajo y envía.",
flowLabels: {
pkce: "Inicio de sesión por navegador (PKCE)",
device_code: "Código de dispositivo",
external: "CLI externa",
},
expiresIn: "caduca en {time}",
},
language: {
switchTo: "Cambiar a inglés",
},
theme: {
title: "Tema",
switchTheme: "Cambiar tema",
},
achievements: {
hero: {
kicker: "Agentic Gamerscore",
title: "Hermes Achievements",
subtitle:
"Insignias coleccionables de Hermes ganadas a partir del historial real de sesiones. Los logros conocidos no completados se muestran como Descubiertos; los logros secretos permanecen ocultos hasta que aparece el primer comportamiento coincidente.",
scan_subtitle:
"Escaneando el historial de sesiones de Hermes. El primer escaneo puede tardar 510 segundos en historiales grandes.",
},
actions: {
rescan: "Volver a escanear",
},
stats: {
unlocked: "Desbloqueados",
unlocked_hint: "insignias ganadas",
discovered: "Descubiertos",
discovered_hint: "conocidos, aún no ganados",
secrets: "Secretos",
secrets_hint: "ocultos hasta la primera señal",
highest_tier: "Nivel más alto",
highest_tier_hint: "Copper → Silver → Gold → Diamond → Olympian",
latest: "Más reciente",
latest_hint_empty: "usa Hermes más",
none_yet: "Ninguno aún",
},
state: {
unlocked: "Desbloqueado",
discovered: "Descubierto",
secret: "Secreto",
},
tier: {
target: "Objetivo {tier}",
hidden: "Oculto",
complete: "Completo",
objective: "Objetivo",
},
progress: {
hidden: "oculto",
},
scan: {
building_headline: "Construyendo perfil de logros…",
building_detail:
"Leyendo sesiones, llamadas a herramientas, metadatos del modelo y estado de desbloqueo.",
starting_headline: "Iniciando escaneo de logros…",
progress_detail:
"Escaneadas {scanned} de {total} sesiones · {pct}%. Las insignias se desbloquean a medida que se procesa más historial.",
idle_detail:
"Leyendo sesiones, llamadas a herramientas, metadatos del modelo y estado de desbloqueo. Las insignias aparecerán aquí a medida que se desbloqueen.",
},
guide: {
tiers_header: "Niveles",
secret_header: "Logros secretos",
secret_body:
"Los secretos ocultan su disparador exacto. Una vez que Hermes detecta una señal relacionada, la tarjeta pasa a Descubierto y muestra su requisito.",
scan_status_header: "Estado del escaneo",
scan_status_body:
"Hermes está escaneando el historial local una vez, después las tarjetas aparecerán automáticamente. No hay nada bloqueado si tarda unos segundos.",
what_scanned_header: "Qué se escanea",
what_scanned_body:
"Sesiones, llamadas a herramientas, metadatos del modelo, errores, logros y estado de desbloqueo local.",
},
card: {
share_title: "Compartir este logro",
share_label: "Compartir {name}",
share_text: "Compartir",
how_to_reveal: "Cómo revelarlo",
what_counts: "Qué cuenta",
evidence_label: "Evidencia",
evidence_session_fallback: "sesión",
no_evidence: "Aún sin evidencia",
},
latest: {
header: "Desbloqueos recientes",
},
empty: {
no_secrets_header: "No quedan secretos ocultos en este escaneo.",
no_secrets_body:
"Pista: los secretos suelen comenzar a partir de fallos inusuales o patrones de usuario avanzado: conflictos de puertos, muros de permisos, variables de entorno faltantes, errores de YAML, colisiones de Docker, uso de rollback/checkpoint, aciertos de caché o pequeñas correcciones tras mucho texto rojo.",
},
filters: {
all_categories: "Todos",
visibility_all: "todos",
visibility_unlocked: "desbloqueados",
visibility_discovered: "descubiertos",
visibility_secret: "secretos",
},
share: {
dialog_label: "Compartir logro",
header: "Compartir: {name}",
close: "Cerrar",
rendering: "Renderizando…",
card_alt: "Tarjeta para compartir de {name}",
error_generic: "Algo salió mal.",
x_title: "Abre X con una publicación predefinida",
x_button: "Compartir en X",
copy_title: "Copia la imagen para pegarla en tu publicación",
copy_button: "Copiar imagen",
copied: "Copiado ✓",
download_button: "Descargar PNG",
hint:
"Compartir en X abre una publicación predefinida en una nueva pestaña. Haz clic primero en Copiar imagen si quieres adjuntar la insignia 1200×630: X te permite pegarla directamente en el redactor del tuit. Descargar PNG guarda el archivo para usarlo en cualquier lugar.",
clipboard_unsupported:
"Este navegador no admite copiar imágenes al portapapeles: usa Descargar en su lugar.",
tweet_text: "Just unlocked {tier_part}\"{name}\" in Hermes Agent ☤",
},
},
kanban: {
loading: "Cargando tablero Kanban…",
loadFailed: "Error al cargar el tablero Kanban: ",
loadFailedHint:
"El backend crea automáticamente kanban.db en la primera lectura. Si el problema persiste, revisa los registros del panel.",
board: "Tablero",
newBoard: "+ Nuevo tablero",
newBoardTitle: "Nuevo tablero",
newBoardDescription:
"Los tableros te permiten separar flujos de trabajo no relacionados — uno por proyecto, repositorio o dominio. Los workers de un tablero nunca ven las tareas de otro.",
slug: "Slug",
slugHint: "— minúsculas, guiones, p. ej. atm10-server",
displayName: "Nombre visible",
displayNameHint: "(opcional)",
description: "Descripción",
descriptionHint: "(opcional)",
icon: "Icono",
iconHint: "(un solo carácter o emoji)",
switchAfterCreate: "Cambiar a este tablero tras crearlo",
cancel: "Cancelar",
creating: "Creando…",
createBoard: "Crear tablero",
search: "Buscar",
filterCards: "Filtrar tarjetas…",
tenant: "Tenant",
allTenants: "Todos los tenants",
assignee: "Asignado a",
allProfiles: "Todos los perfiles",
showArchived: "Mostrar archivados",
lanesByProfile: "Carriles por perfil",
nudgeDispatcher: "Avisar al dispatcher",
refresh: "Actualizar",
selected: "seleccionado(s)",
complete: "Completar",
archive: "Archivar",
apply: "Aplicar",
clear: "Limpiar",
createTask: "Crear tarea en esta columna",
noTasks: "— sin tareas —",
unassigned: "sin asignar",
untitled: "(sin título)",
loadingDetail: "Cargando…",
addComment: "Añadir un comentario… (Enter para enviar)",
comment: "Comentario",
status: "Estado",
workspace: "Workspace",
skills: "Habilidades",
createdBy: "Creado por",
result: "Result",
comments: "Comentarios",
events: "Eventos",
runHistory: "Historial de ejecuciones",
workerLog: "Registro del worker",
loadingLog: "Cargando registro…",
noWorkerLog:
"— aún no hay registro del worker (la tarea no se ha lanzado o el registro fue rotado) —",
noDescription: "— sin descripción —",
noComments: "— sin comentarios —",
edit: "editar",
save: "Guardar",
dependencies: "Dependencias",
parents: "Padres:",
children: "Hijos:",
none: "ninguno",
addParent: "— añadir padre —",
addChild: "— añadir hijo —",
removeDependency: "Eliminar dependencia",
block: "Bloquear",
unblock: "Desbloquear",
notifyHomeChannels: "Notificar a los canales de inicio",
diagnostics: "Diagnósticos",
hide: "Ocultar",
show: "Mostrar",
attention: "Atención",
tasksNeedAttention: "tareas requieren atención",
taskNeedsAttention: "1 tarea requiere atención",
diagnostic: "diagnóstico",
open: "Abrir",
close: "Cerrar (Esc)",
reassignTo: "Reasignar a:",
copied: "Copiado",
copyCommand: "Copiar comando al portapapeles",
reclaim: "Recuperar",
reassign: "Reasignar",
renderingError: "La pestaña Kanban tuvo un error de renderizado",
reloadView: "Recargar vista",
wsAuthFailed:
"Error de autenticación de WebSocket — recarga la página para refrescar el token de sesión.",
markDone: "¿Marcar {n} tarea(s) como hechas?",
markArchived: "¿Archivar {n} tarea(s)?",
warning: "Advertencia",
phantomIds: "IDs fantasma:",
active: "activo",
ended: "finalizado",
noProfile: "(sin perfil)",
showAllAttempts: "Mostrar todos los intentos",
sendingUpdates: "Enviando actualizaciones a",
sendNotifications: "Enviar notificaciones de completed / blocked / gave_up a",
archiveBoardConfirm:
"¿Archivar el tablero '{name}'? Se moverá a boards/_archived/ para que puedas recuperarlo más tarde. Las tareas de este tablero ya no aparecerán en ninguna parte de la UI.",
archiveBoardTitle: "Archivar este tablero",
boardSwitcherHint: "Los tableros te permiten separar flujos de trabajo no relacionados",
taskCreatedWarning: "Tarea creada, pero: ",
moveFailed: "Error al mover: ",
bulkFailed: "Lote: ",
completionBlockedHallucination: "⚠ Completado bloqueado — IDs de tarjeta fantasma",
suspectedHallucinatedReferences: "⚠ El texto referenció IDs de tarjeta fantasma",
pickProfileFirst: "Elige primero un perfil.",
unblockedMessage: "Desbloqueado {id}. La tarea está lista para el próximo tick.",
unblockFailed: "Error al desbloquear: ",
reclaimedMessage: "Recuperado {id}. La tarea vuelve a estar lista.",
reclaimFailed: "Error al recuperar: ",
reassignedMessage: "Reasignado {id} a {profile}.",
reassignFailed: "Error al reasignar: ",
selectForBulk: "Seleccionar para acciones por lotes",
clickToEdit: "Haz clic para editar",
clickToEditAssignee: "Haz clic para editar el asignado",
emptyAssignee: "(vacío = sin asignar)",
columnLabels: {
triage: "Clasificación",
todo: "Por hacer",
ready: "Listo",
running: "En curso",
blocked: "Bloqueado",
done: "Hecho",
archived: "Archivado",
},
columnHelp: {
triage: "Ideas en bruto — un specifier desarrollará la especificación",
todo: "Esperando dependencias o sin asignar",
ready: "Asignado y esperando un tick del dispatcher",
running: "Reclamado por un worker — en ejecución",
blocked: "El worker pidió intervención humana",
done: "Completado",
archived: "Archivado",
},
confirmDone:
"¿Marcar esta tarea como hecha? Se libera el reclamo del worker y los hijos dependientes pasan a estar listos.",
confirmArchive:
"¿Archivar esta tarea? Desaparecerá de la vista por defecto del tablero.",
confirmBlocked:
"¿Marcar esta tarea como bloqueada? Se libera el reclamo del worker.",
completionSummary:
"Resumen de finalización para {label}. Se almacena como el result de la tarea.",
completionSummaryRequired:
"El resumen de finalización es obligatorio antes de marcar una tarea como hecha.",
triagePlaceholder: "Idea aproximada — la IA la especificará…",
taskTitlePlaceholder: "Título de la nueva tarea…",
specifier: "specifier",
assigneePlaceholder: "asignado",
priority: "Prioridad",
skillsPlaceholder:
"habilidades (opcional, separadas por comas): translation, github-code-review",
noParent: "— sin padre —",
workspacePathDir: "ruta del workspace (obligatoria, p. ej. ~/projects/my-app)",
workspacePathOptional:
"ruta del workspace (opcional, derivada del asignado si está vacía)",
logTruncated: "(mostrando los últimos 100 KB — registro completo en ",
logAt: ")",
},
};

695
web/src/i18n/fr.ts Normal file
View file

@ -0,0 +1,695 @@
import type { Translations } from "./types";
export const fr: Translations = {
common: {
save: "Enregistrer",
saving: "Enregistrement...",
cancel: "Annuler",
close: "Fermer",
confirm: "Confirmer",
delete: "Supprimer",
refresh: "Actualiser",
retry: "Réessayer",
search: "Rechercher...",
loading: "Chargement...",
create: "Créer",
creating: "Création...",
set: "Définir",
replace: "Remplacer",
clear: "Effacer",
live: "En direct",
off: "Désactivé",
enabled: "activé",
disabled: "désactivé",
active: "actif",
inactive: "inactif",
unknown: "inconnu",
untitled: "Sans titre",
none: "Aucun",
form: "Formulaire",
noResults: "Aucun résultat",
of: "sur",
page: "Page",
msgs: "msgs",
tools: "outils",
match: "correspondance",
other: "Autre",
configured: "configuré",
removed: "supprimé",
failedToToggle: "Échec du basculement",
failedToRemove: "Échec de la suppression",
failedToReveal: "Échec de l'affichage",
collapse: "Réduire",
expand: "Développer",
general: "Général",
messaging: "Messagerie",
pluginLoadFailed:
"Impossible de charger le script de ce plugin. Vérifiez l'onglet Réseau (dashboard-plugins/…) et le chemin des plugins du serveur.",
pluginNotRegistered:
"Le script du plugin n'a pas appelé register(), ou le script a échoué. Ouvrez la console du navigateur pour plus de détails.",
},
app: {
brand: "Hermes Agent",
brandShort: "HA",
closeNavigation: "Fermer la navigation",
closeModelTools: "Fermer modèle et outils",
footer: {
org: "Nous Research",
},
activeSessionsLabel: "Sessions actives:",
gatewayStatusLabel: "État de la passerelle:",
gatewayStrip: {
failed: "Échec du démarrage",
off: "Désactivé",
running: "En cours",
starting: "Démarrage",
stopped: "Arrêté",
},
nav: {
analytics: "Analyses",
chat: "Chat",
config: "Configuration",
cron: "Cron",
documentation: "Documentation",
keys: "Clés",
logs: "Journaux",
models: "Modèles",
profiles: "profils : multi agents",
plugins: "Plugins",
sessions: "Sessions",
skills: "Compétences",
},
modelToolsSheetSubtitle: "& outils",
modelToolsSheetTitle: "Modèle",
navigation: "Navigation",
openDocumentation: "Ouvrir la documentation dans un nouvel onglet",
openNavigation: "Ouvrir la navigation",
pluginNavSection: "Plugins",
sessionsActiveCount: "{count} actives",
statusOverview: "Aperçu de l'état",
system: "Système",
webUi: "Web UI",
},
status: {
actionFailed: "Action échouée",
actionFinished: "Terminé",
actions: "Actions",
agent: "Agent",
activeSessions: "Sessions actives",
connected: "Connecté",
connectedPlatforms: "Plateformes connectées",
disconnected: "Déconnecté",
error: "Erreur",
failed: "Échec",
gateway: "Passerelle",
gatewayFailedToStart: "Le démarrage de la passerelle a échoué",
lastUpdate: "Dernière mise à jour",
noneRunning: "Aucun",
notRunning: "Non lancé",
pid: "PID",
platformDisconnected: "déconnecté",
platformError: "erreur",
recentSessions: "Sessions récentes",
restartGateway: "Redémarrer la passerelle",
restartingGateway: "Redémarrage de la passerelle…",
running: "En cours",
runningRemote: "En cours (distant)",
startFailed: "Échec du démarrage",
starting: "Démarrage",
startedInBackground: "Démarré en arrière-plan — consultez les journaux pour la progression",
stopped: "Arrêté",
updateHermes: "Mettre à jour Hermes",
updatingHermes: "Mise à jour de Hermes…",
waitingForOutput: "En attente de la sortie…",
},
sessions: {
title: "Sessions",
searchPlaceholder: "Rechercher dans les messages...",
noSessions: "Aucune session pour l'instant",
noMatch: "Aucune session ne correspond à votre recherche",
startConversation: "Démarrez une conversation pour la voir ici",
noMessages: "Aucun message",
untitledSession: "Session sans titre",
deleteSession: "Supprimer la session",
confirmDeleteTitle: "Supprimer la session ?",
confirmDeleteMessage:
"Cela supprime définitivement la conversation et tous ses messages. Cette action est irréversible.",
sessionDeleted: "Session supprimée",
failedToDelete: "Échec de la suppression de la session",
resumeInChat: "Reprendre dans le chat",
previousPage: "Page précédente",
nextPage: "Page suivante",
roles: {
user: "Utilisateur",
assistant: "Assistant",
system: "Système",
tool: "Outil",
},
},
analytics: {
period: "Période:",
totalTokens: "Tokens totaux",
totalSessions: "Sessions totales",
apiCalls: "Appels API",
dailyTokenUsage: "Utilisation quotidienne des tokens",
dailyBreakdown: "Détail quotidien",
perModelBreakdown: "Détail par modèle",
topSkills: "Compétences les plus utilisées",
skill: "Compétence",
loads: "Agent chargé",
edits: "Agent géré",
lastUsed: "Dernière utilisation",
input: "Entrée",
output: "Sortie",
total: "Total",
noUsageData: "Aucune donnée d'utilisation pour cette période",
startSession: "Démarrez une session pour voir les analyses ici",
date: "Date",
model: "Modèle",
tokens: "Tokens",
perDayAvg: "/jour moy",
acrossModels: "sur {count} modèles",
inOut: "{input} entrée / {output} sortie",
},
models: {
modelsUsed: "Modèles utilisés",
estimatedCost: "Coût est.",
tokens: "tokens",
sessions: "sessions",
avgPerSession: "moy/session",
apiCalls: "appels API",
toolCalls: "appels d'outil",
noModelsData: "Aucune donnée de modèle pour cette période",
startSession: "Démarrez une session pour voir les données de modèle ici",
},
logs: {
title: "Journaux",
autoRefresh: "Actualisation auto",
file: "Fichier",
level: "Niveau",
component: "Composant",
lines: "Lignes",
noLogLines: "Aucune ligne de journal trouvée",
},
cron: {
confirmDeleteMessage:
"Cela supprime la tâche du planning. Cette action est irréversible.",
confirmDeleteTitle: "Supprimer la tâche planifiée ?",
newJob: "Nouvelle tâche cron",
nameOptional: "Nom (facultatif)",
namePlaceholder: "ex. Résumé quotidien",
prompt: "Invite",
promptPlaceholder: "Que doit faire l'agent à chaque exécution ?",
schedule: "Planning (expression cron)",
schedulePlaceholder: "0 9 * * *",
deliverTo: "Livrer à",
scheduledJobs: "Tâches planifiées",
noJobs: "Aucune tâche cron configurée. Créez-en une ci-dessus.",
last: "Dernière",
next: "Prochaine",
pause: "Pause",
resume: "Reprendre",
triggerNow: "Déclencher maintenant",
delivery: {
local: "Local",
telegram: "Telegram",
discord: "Discord",
slack: "Slack",
email: "Email",
},
},
profiles: {
newProfile: "Nouveau profil",
name: "Nom",
namePlaceholder: "ex. coder, writer, etc.",
nameRequired: "Le nom est requis",
nameRule:
"Lettres minuscules, chiffres, _ et - uniquement ; doit commencer par une lettre ou un chiffre ; jusqu'à 64 caractères.",
invalidName: "Nom de profil invalide",
cloneFromDefault: "Cloner la configuration du profil par défaut",
allProfiles: "Profils",
noProfiles: "Aucun profil trouvé.",
defaultBadge: "défaut",
hasEnv: "env",
model: "Modèle",
skills: "Compétences",
rename: "Renommer",
editSoul: "Modifier SOUL.md",
soulSection: "SOUL.md (personnalité / invite système)",
soulPlaceholder: "# Comment cet agent doit se comporter…",
saveSoul: "Enregistrer SOUL",
soulSaved: "SOUL.md enregistré",
openInTerminal: "Copier la commande CLI",
commandCopied: "Copié dans le presse-papiers",
copyFailed: "Impossible de copier",
confirmDeleteTitle: "Supprimer le profil ?",
confirmDeleteMessage:
"Cela supprime définitivement le profil '{name}' — configuration, clés, mémoires, sessions, compétences, tâches cron. Action irréversible.",
created: "Créé",
deleted: "Supprimé",
renamed: "Renommé",
},
pluginsPage: {
contextEngineLabel: "Moteur de contexte",
dashboardSlots: "Emplacements du tableau de bord",
disableRuntime: "Désactiver",
enableAfterInstall: "Activer après l'installation",
enableRuntime: "Activer",
forceReinstall: "Forcer la réinstallation (supprimer d'abord le dossier existant)",
headline:
"Découvrez, installez, activez et mettez à jour les plugins Hermes (parité avec `hermes plugins`).",
identifierLabel: "URL Git ou owner/repo",
inactive: "inactif",
installBtn: "Installer depuis Git",
installHeading: "Installer depuis GitHub / URL Git",
installHint: "Utilisez le raccourci owner/repo ou une URL de clonage complète https:// ou git@.",
memoryProviderLabel: "Fournisseur de mémoire",
missingEnvWarn: "Définissez ces variables dans Clés avant que le plugin puisse s'exécuter:",
noDashboardTab: "Aucun onglet de tableau de bord",
openTab: "Ouvrir",
orphanHeading: "Extensions du tableau de bord uniquement (aucune correspondance plugin.yaml d'agent)",
pluginListHeading: "Plugins installés",
providerDefaults: "intégré / par défaut",
providersHeading: "Plugins fournisseurs d'exécution",
providersHint:
"Écrit memory.provider (vide = intégré) et context.engine dans config.yaml. Prend effet à la prochaine session.",
refreshDashboard: "Re-scanner les extensions du tableau de bord",
removeConfirm: "Retirer ce plugin de ~/.hermes/plugins/ ?",
removeHint: "Seuls les plugins installés par l'utilisateur sous ~/.hermes/plugins peuvent être supprimés.",
rescanHeading: "Registre des plugins SPA",
rescanHint: "Re-scannez après avoir ajouté des fichiers sur le disque pour que la barre latérale prenne en compte les nouveaux manifestes.",
runtimeHeading: "Exécution de la passerelle (plugins YAML)",
saveProviders: "Enregistrer les paramètres de fournisseur",
savedProviders: "Paramètres de fournisseur enregistrés.",
sourceBadge: "Source",
authRequired: "Authentification requise",
authRequiredHint: "Exécutez cette commande pour vous authentifier:",
updateGit: "Git pull",
versionBadge: "Version",
showInSidebar: "Afficher dans la barre latérale",
hideFromSidebar: "Masquer de la barre latérale",
},
skills: {
title: "Compétences",
searchPlaceholder: "Rechercher des compétences et des outils...",
enabledOf: "{enabled}/{total} activées",
all: "Toutes",
categories: "Catégories",
filters: "Filtres",
noSkills: "Aucune compétence trouvée. Les compétences sont chargées depuis ~/.hermes/skills/",
noSkillsMatch: "Aucune compétence ne correspond à votre recherche ou filtre.",
skillCount: "{count} compétence{s}",
resultCount: "{count} résultat{s}",
noDescription: "Aucune description disponible.",
toolsets: "Ensembles d'outils",
toolsetLabel: "Ensemble d'outils {name}",
noToolsetsMatch: "Aucun ensemble d'outils ne correspond à la recherche.",
setupNeeded: "Configuration nécessaire",
disabledForCli: "Désactivé pour CLI",
more: "+{count} de plus",
},
config: {
configPath: "~/.hermes/config.yaml",
filters: "Filtres",
sections: "Sections",
exportConfig: "Exporter la configuration en JSON",
importConfig: "Importer la configuration depuis JSON",
resetDefaults: "Réinitialiser aux valeurs par défaut",
resetScopeTooltip: "Réinitialiser {scope} aux valeurs par défaut",
confirmResetScope: "Réinitialiser tous les paramètres de {scope} aux valeurs par défaut ? Cela ne met à jour que le formulaire — les modifications ne sont écrites dans config.yaml qu'après avoir appuyé sur Enregistrer.",
resetScopeToast: "{scope} réinitialisé aux valeurs par défaut — vérifiez et enregistrez pour conserver",
rawYaml: "Configuration YAML brute",
searchResults: "Résultats de recherche",
fields: "champ{s}",
noFieldsMatch: 'Aucun champ ne correspond à "{query}"',
configSaved: "Configuration enregistrée",
yamlConfigSaved: "Configuration YAML enregistrée",
failedToSave: "Échec de l'enregistrement",
failedToSaveYaml: "Échec de l'enregistrement YAML",
failedToLoadRaw: "Échec du chargement de la configuration brute",
configImported: "Configuration importée — vérifiez et enregistrez",
invalidJson: "Fichier JSON invalide",
categories: {
general: "Général",
agent: "Agent",
terminal: "Terminal",
display: "Affichage",
delegation: "Délégation",
memory: "Mémoire",
compression: "Compression",
security: "Sécurité",
browser: "Navigateur",
voice: "Voix",
tts: "Synthèse vocale",
stt: "Reconnaissance vocale",
logging: "Journalisation",
discord: "Discord",
auxiliary: "Auxiliaire",
},
},
env: {
changesNote: "Les modifications sont enregistrées sur le disque immédiatement. Les sessions actives récupèrent les nouvelles clés automatiquement.",
confirmClearMessage:
"La valeur stockée pour cette variable sera supprimée de votre fichier .env. Cette action ne peut pas être annulée depuis l'interface.",
confirmClearTitle: "Effacer cette clé ?",
description: "Gérer les clés API et les secrets stockés dans",
hideAdvanced: "Masquer les options avancées",
showAdvanced: "Afficher les options avancées",
llmProviders: "Fournisseurs LLM",
providersConfigured: "{configured} sur {total} fournisseurs configurés",
getKey: "Obtenir la clé",
notConfigured: "{count} non configuré",
notSet: "Non défini",
keysCount: "{count} clé{s}",
enterValue: "Saisir une valeur...",
replaceCurrentValue: "Remplacer la valeur actuelle ({preview})",
showValue: "Afficher la valeur réelle",
hideValue: "Masquer la valeur",
},
oauth: {
title: "Connexions fournisseurs (OAuth)",
providerLogins: "Connexions fournisseurs (OAuth)",
description: "{connected} sur {total} fournisseurs OAuth connectés. Les flux de connexion s'exécutent actuellement via le CLI ; cliquez sur Copier la commande et collez-la dans un terminal pour configurer.",
connected: "Connecté",
expired: "Expiré",
notConnected: "Non connecté. Exécutez {command} dans un terminal.",
runInTerminal: "dans un terminal.",
noProviders: "Aucun fournisseur compatible OAuth détecté.",
login: "Connexion",
disconnect: "Déconnecter",
managedExternally: "Géré en externe",
copied: "Copié ✓",
cli: "CLI",
copyCliCommand: "Copier la commande CLI (pour externe / repli)",
connect: "Connecter",
sessionExpires: "La session expire dans {time}",
initiatingLogin: "Lancement du flux de connexion…",
exchangingCode: "Échange du code contre des jetons…",
connectedClosing: "Connecté ! Fermeture…",
loginFailed: "Échec de la connexion.",
sessionExpired: "Session expirée. Cliquez sur Réessayer pour démarrer une nouvelle connexion.",
reOpenAuth: "Rouvrir la page d'authentification",
reOpenVerification: "Rouvrir la page de vérification",
submitCode: "Soumettre le code",
pasteCode: "Collez le code d'autorisation (avec suffixe #state accepté)",
waitingAuth: "En attente de votre autorisation dans le navigateur…",
enterCodePrompt: "Un nouvel onglet s'est ouvert. Saisissez ce code si demandé:",
pkceStep1: "Un nouvel onglet s'est ouvert vers claude.ai. Connectez-vous et cliquez sur Autoriser.",
pkceStep2: "Copiez le code d'autorisation affiché après autorisation.",
pkceStep3: "Collez-le ci-dessous et soumettez.",
flowLabels: {
pkce: "Connexion navigateur (PKCE)",
device_code: "Code d'appareil",
external: "CLI externe",
},
expiresIn: "expire dans {time}",
},
language: {
switchTo: "Passer à l'anglais",
},
theme: {
title: "Thème",
switchTheme: "Changer de thème",
},
achievements: {
hero: {
kicker: "Agentic Gamerscore",
title: "Hermes Achievements",
subtitle:
"Badges Hermes à collectionner, gagnés à partir de l'historique réel des sessions. Les succès connus non terminés sont affichés comme Découverts ; les succès secrets restent cachés jusqu'à l'apparition du premier comportement correspondant.",
scan_subtitle:
"Analyse de l'historique des sessions Hermes en cours. Le premier scan peut prendre 5 à 10 secondes sur les historiques volumineux.",
},
actions: {
rescan: "Relancer le scan",
},
stats: {
unlocked: "Débloqués",
unlocked_hint: "badges obtenus",
discovered: "Découverts",
discovered_hint: "connus, pas encore obtenus",
secrets: "Secrets",
secrets_hint: "cachés jusqu'au premier signal",
highest_tier: "Niveau le plus élevé",
highest_tier_hint: "Copper → Silver → Gold → Diamond → Olympian",
latest: "Dernier",
latest_hint_empty: "utilisez Hermes davantage",
none_yet: "Aucun pour l'instant",
},
state: {
unlocked: "Débloqué",
discovered: "Découvert",
secret: "Secret",
},
tier: {
target: "Cible {tier}",
hidden: "Caché",
complete: "Terminé",
objective: "Objectif",
},
progress: {
hidden: "caché",
},
scan: {
building_headline: "Création du profil de succès…",
building_detail:
"Lecture des sessions, des appels d'outils, des métadonnées du modèle et de l'état de déblocage.",
starting_headline: "Démarrage du scan des succès…",
progress_detail:
"{scanned} sessions analysées sur {total} · {pct}%. Les badges se débloquent à mesure que l'historique est traité.",
idle_detail:
"Lecture des sessions, des appels d'outils, des métadonnées du modèle et de l'état de déblocage. Les badges apparaissent ici à mesure qu'ils se débloquent.",
},
guide: {
tiers_header: "Niveaux",
secret_header: "Succès secrets",
secret_body:
"Les secrets cachent leur déclencheur exact. Dès qu'Hermes détecte un signal lié, la carte passe à Découvert et affiche son exigence.",
scan_status_header: "État du scan",
scan_status_body:
"Hermes analyse l'historique local une seule fois, puis les cartes apparaîtront automatiquement. Rien n'est bloqué si cela prend quelques secondes.",
what_scanned_header: "Ce qui est analysé",
what_scanned_body:
"Sessions, appels d'outils, métadonnées du modèle, erreurs, succès et état de déblocage local.",
},
card: {
share_title: "Partager ce succès",
share_label: "Partager {name}",
share_text: "Partager",
how_to_reveal: "Comment le révéler",
what_counts: "Ce qui compte",
evidence_label: "Preuve",
evidence_session_fallback: "session",
no_evidence: "Pas encore de preuve",
},
latest: {
header: "Déblocages récents",
},
empty: {
no_secrets_header: "Plus aucun secret caché dans ce scan.",
no_secrets_body:
"Indice: les secrets démarrent généralement à partir d'échecs inhabituels ou de schémas d'utilisateurs avancés — conflits de ports, murs de permissions, variables d'environnement manquantes, erreurs YAML, collisions Docker, utilisation de rollback/checkpoint, succès de cache ou petits correctifs après beaucoup de texte rouge.",
},
filters: {
all_categories: "Tous",
visibility_all: "tous",
visibility_unlocked: "débloqués",
visibility_discovered: "découverts",
visibility_secret: "secrets",
},
share: {
dialog_label: "Partager le succès",
header: "Partager: {name}",
close: "Fermer",
rendering: "Rendu en cours…",
card_alt: "Carte de partage {name}",
error_generic: "Une erreur s'est produite.",
x_title: "Ouvre X avec une publication préremplie",
x_button: "Partager sur X",
copy_title: "Copiez l'image pour la coller dans votre publication",
copy_button: "Copier l'image",
copied: "Copié ✓",
download_button: "Télécharger le PNG",
hint:
"Partager sur X ouvre une publication préremplie dans un nouvel onglet. Cliquez d'abord sur Copier l'image si vous voulez joindre le badge 1200×630 — X vous laisse le coller directement dans l'éditeur de tweet. Télécharger le PNG enregistre le fichier pour l'utiliser n'importe où.",
clipboard_unsupported:
"La copie d'image dans le presse-papiers n'est pas prise en charge par ce navigateur — utilisez Télécharger à la place.",
tweet_text: "Just unlocked {tier_part}\"{name}\" in Hermes Agent ☤",
},
},
kanban: {
loading: "Chargement du tableau Kanban…",
loadFailed: "Échec du chargement du tableau Kanban: ",
loadFailedHint:
"Le backend crée automatiquement kanban.db à la première lecture. Si le problème persiste, consultez les logs du dashboard.",
board: "Tableau",
newBoard: "+ Nouveau tableau",
newBoardTitle: "Nouveau tableau",
newBoardDescription:
"Les tableaux vous permettent de séparer des flux de travail indépendants — un par projet, dépôt ou domaine. Les workers d'un tableau ne voient jamais les tâches d'un autre.",
slug: "Slug",
slugHint: "— minuscules, tirets, par ex. atm10-server",
displayName: "Nom affiché",
displayNameHint: "(facultatif)",
description: "Description",
descriptionHint: "(facultatif)",
icon: "Icône",
iconHint: "(un seul caractère ou emoji)",
switchAfterCreate: "Basculer sur ce tableau après l'avoir créé",
cancel: "Annuler",
creating: "Création…",
createBoard: "Créer le tableau",
search: "Rechercher",
filterCards: "Filtrer les cartes…",
tenant: "Tenant",
allTenants: "Tous les tenants",
assignee: "Assigné à",
allProfiles: "Tous les profils",
showArchived: "Afficher les archivés",
lanesByProfile: "Couloirs par profil",
nudgeDispatcher: "Solliciter le dispatcher",
refresh: "Rafraîchir",
selected: "sélectionné(s)",
complete: "Terminer",
archive: "Archiver",
apply: "Appliquer",
clear: "Effacer",
createTask: "Créer une tâche dans cette colonne",
noTasks: "— aucune tâche —",
unassigned: "non assigné",
untitled: "(sans titre)",
loadingDetail: "Chargement…",
addComment: "Ajouter un commentaire… (Enter pour envoyer)",
comment: "Commentaire",
status: "Statut",
workspace: "Workspace",
skills: "Compétences",
createdBy: "Créé par",
result: "Result",
comments: "Commentaires",
events: "Événements",
runHistory: "Historique d'exécution",
workerLog: "Log du worker",
loadingLog: "Chargement du log…",
noWorkerLog:
"— pas encore de log du worker (la tâche n'a pas démarré ou le log a été effacé par rotation) —",
noDescription: "— aucune description —",
noComments: "— aucun commentaire —",
edit: "modifier",
save: "Enregistrer",
dependencies: "Dépendances",
parents: "Parents:",
children: "Enfants:",
none: "aucun",
addParent: "— ajouter un parent —",
addChild: "— ajouter un enfant —",
removeDependency: "Supprimer la dépendance",
block: "Bloquer",
unblock: "Débloquer",
notifyHomeChannels: "Notifier les canaux home",
diagnostics: "Diagnostics",
hide: "Masquer",
show: "Afficher",
attention: "Attention",
tasksNeedAttention: "tâches nécessitent une attention",
taskNeedsAttention: "1 tâche nécessite une attention",
diagnostic: "diagnostic",
open: "Ouvrir",
close: "Fermer (Esc)",
reassignTo: "Réassigner à:",
copied: "Copié",
copyCommand: "Copier la commande dans le presse-papiers",
reclaim: "Récupérer",
reassign: "Réassigner",
renderingError: "L'onglet Kanban a rencontré une erreur de rendu",
reloadView: "Recharger la vue",
wsAuthFailed:
"Échec d'authentification WebSocket — rechargez la page pour rafraîchir le jeton de session.",
markDone: "Marquer {n} tâche(s) comme terminée(s) ?",
markArchived: "Archiver {n} tâche(s) ?",
warning: "Avertissement",
phantomIds: "IDs fantômes:",
active: "actif",
ended: "terminé",
noProfile: "(aucun profil)",
showAllAttempts: "Afficher toutes les tentatives",
sendingUpdates: "Envoi des mises à jour à",
sendNotifications: "Envoyer les notifications completed / blocked / gave_up à",
archiveBoardConfirm:
"Archiver le tableau '{name}' ? Il sera déplacé vers boards/_archived/ pour pouvoir être récupéré plus tard. Les tâches de ce tableau n'apparaîtront plus nulle part dans l'UI.",
archiveBoardTitle: "Archiver ce tableau",
boardSwitcherHint: "Les tableaux vous permettent de séparer des flux de travail indépendants",
taskCreatedWarning: "Tâche créée, mais: ",
moveFailed: "Échec du déplacement: ",
bulkFailed: "Lot: ",
completionBlockedHallucination: "⚠ Achèvement bloqué — IDs de carte fantômes",
suspectedHallucinatedReferences: "⚠ Le texte a référencé des IDs de carte fantômes",
pickProfileFirst: "Choisissez d'abord un profil.",
unblockedMessage: "Débloqué {id}. La tâche est prête pour le prochain tick.",
unblockFailed: "Échec du déblocage: ",
reclaimedMessage: "Récupéré {id}. La tâche est de nouveau prête.",
reclaimFailed: "Échec de la récupération: ",
reassignedMessage: "Réassigné {id} à {profile}.",
reassignFailed: "Échec de la réassignation: ",
selectForBulk: "Sélectionner pour des actions groupées",
clickToEdit: "Cliquez pour modifier",
clickToEditAssignee: "Cliquez pour modifier l'assigné",
emptyAssignee: "(vide = désassigner)",
columnLabels: {
triage: "Triage",
todo: "À faire",
ready: "Prêt",
running: "En cours",
blocked: "Bloqué",
done: "Terminé",
archived: "Archivé",
},
columnHelp: {
triage: "Idées brutes — un specifier rédigera la spécification",
todo: "En attente de dépendances ou non assigné",
ready: "Assigné et en attente d'un tick du dispatcher",
running: "Réclamé par un worker — en cours d'exécution",
blocked: "Le worker a demandé une intervention humaine",
done: "Terminé",
archived: "Archivé",
},
confirmDone:
"Marquer cette tâche comme terminée ? La revendication du worker est libérée et les enfants dépendants deviennent prêts.",
confirmArchive:
"Archiver cette tâche ? Elle disparaîtra de la vue par défaut du tableau.",
confirmBlocked:
"Marquer cette tâche comme bloquée ? La revendication du worker est libérée.",
completionSummary:
"Résumé d'achèvement pour {label}. Stocké comme result de la tâche.",
completionSummaryRequired:
"Un résumé d'achèvement est requis avant de marquer une tâche comme terminée.",
triagePlaceholder: "Idée approximative — l'IA la spécifiera…",
taskTitlePlaceholder: "Titre de la nouvelle tâche…",
specifier: "specifier",
assigneePlaceholder: "assigné",
priority: "Priorité",
skillsPlaceholder:
"compétences (facultatif, séparées par virgules): translation, github-code-review",
noParent: "— aucun parent —",
workspacePathDir: "chemin du workspace (requis, par ex. ~/projects/my-app)",
workspacePathOptional:
"chemin du workspace (facultatif, dérivé de l'assigné si vide)",
logTruncated: "(affichage des derniers 100 KB — log complet à ",
logAt: ")",
},
};

696
web/src/i18n/ga.ts Normal file
View file

@ -0,0 +1,696 @@
import type { Translations } from "./types";
export const ga: Translations = {
common: {
save: "Sábháil",
saving: "Á shábháil...",
cancel: "Cealaigh",
close: "Dún",
confirm: "Deimhnigh",
delete: "Scrios",
refresh: "Athnuaigh",
retry: "Bain triail eile as",
search: "Cuardaigh...",
loading: "Á luchtú...",
create: "Cruthaigh",
creating: "Á chruthú...",
set: "Socraigh",
replace: "Athchuir",
clear: "Glan",
live: "Beo",
off: "As",
enabled: "cumasaithe",
disabled: "díchumasaithe",
active: "gníomhach",
inactive: "neamhghníomhach",
unknown: "anaithnid",
untitled: "Gan teideal",
none: "Aon cheann",
form: "Foirm",
noResults: "Aon toradh",
of: "as",
page: "Leathanach",
msgs: "tcht",
tools: "uirlisí",
match: "meaitseáil",
other: "Eile",
configured: "cumraithe",
removed: "bainte",
failedToToggle: "Theip ar an scoránú",
failedToRemove: "Theip ar an mbaint",
failedToReveal: "Theip ar an taispeáint",
collapse: "Laghdaigh",
expand: "Leathnaigh",
general: "Ginearálta",
messaging: "Teachtaireachtaí",
pluginLoadFailed:
"Níorbh fhéidir script an plugin seo a luchtú. Seiceáil an cluaisín Network (dashboard-plugins/…) agus conair plugin an fhreastalaí.",
pluginNotRegistered:
"Níor ghlaoigh script an plugin ar register(), nó tharla earráid sa script. Oscail consól an bhrabhsálaí le haghaidh sonraí.",
},
app: {
brand: "Hermes Agent",
brandShort: "HA",
closeNavigation: "Dún an nascleanúint",
closeModelTools: "Dún an samhail agus na huirlisí",
footer: {
org: "Nous Research",
},
activeSessionsLabel: "Seisiúin gníomhacha:",
gatewayStatusLabel: "Stádas an gateway:",
gatewayStrip: {
failed: "Theip ar an tús",
off: "As",
running: "Ag rith",
starting: "Ag tosú",
stopped: "Stoptha",
},
nav: {
analytics: "Anailís",
chat: "Comhrá",
config: "Cumraíocht",
cron: "Cron",
documentation: "Doiciméadú",
keys: "Eochracha",
logs: "Logaí",
models: "Samhlacha",
profiles: "próifílí : il-agents",
plugins: "Plugins",
sessions: "Seisiúin",
skills: "Scileanna",
},
modelToolsSheetSubtitle: "agus uirlisí",
modelToolsSheetTitle: "Samhail",
navigation: "Nascleanúint",
openDocumentation: "Oscail an doiciméadú i gcluaisín nua",
openNavigation: "Oscail an nascleanúint",
pluginNavSection: "Plugins",
sessionsActiveCount: "{count} gníomhach",
statusOverview: "Forbhreathnú stádais",
system: "Córas",
webUi: "Web UI",
},
status: {
actionFailed: "Theip ar an ngníomh",
actionFinished: "Críochnaithe",
actions: "Gníomhartha",
agent: "Agent",
activeSessions: "Seisiúin ghníomhacha",
connected: "Ceangailte",
connectedPlatforms: "Ardáin cheangailte",
disconnected: "Dícheangailte",
error: "Earráid",
failed: "Theip",
gateway: "Gateway",
gatewayFailedToStart: "Theip ar an gateway tosú",
lastUpdate: "Nuashonrú deireanach",
noneRunning: "Aon cheann",
notRunning: "Níl ag rith",
pid: "PID",
platformDisconnected: "dícheangailte",
platformError: "earráid",
recentSessions: "Seisiúin le déanaí",
restartGateway: "Atosaigh an gateway",
restartingGateway: "Ag atosú an gateway…",
running: "Ag rith",
runningRemote: "Ag rith (cianda)",
startFailed: "Theip ar an tús",
starting: "Ag tosú",
startedInBackground: "Tosaithe sa chúlra — seiceáil na logaí le haghaidh dul chun cinn",
stopped: "Stoptha",
updateHermes: "Nuashonraigh Hermes",
updatingHermes: "Ag nuashonrú Hermes…",
waitingForOutput: "Ag fanacht le haschur…",
},
sessions: {
title: "Seisiúin",
searchPlaceholder: "Cuardaigh ábhar teachtaireachta...",
noSessions: "Gan seisiúin go fóill",
noMatch: "Níl seisiún ar bith ag teacht le do chuardach",
startConversation: "Tosaigh comhrá chun é a fheiceáil anseo",
noMessages: "Gan teachtaireachtaí",
untitledSession: "Seisiún gan teideal",
deleteSession: "Scrios an seisiún",
confirmDeleteTitle: "Scrios an seisiún?",
confirmDeleteMessage:
"Baineann sé seo an comhrá agus a chuid teachtaireachtaí ar fad go buan. Ní féidir é seo a chealú.",
sessionDeleted: "Seisiún scriosta",
failedToDelete: "Theip ar scriosadh an tseisiúin",
resumeInChat: "Lean ar aghaidh sa chomhrá",
previousPage: "Leathanach roimhe seo",
nextPage: "An chéad leathanach eile",
roles: {
user: "Úsáideoir",
assistant: "Cúntóir",
system: "Córas",
tool: "Uirlis",
},
},
analytics: {
period: "Tréimhse:",
totalTokens: "Tokens iomlána",
totalSessions: "Seisiúin iomlána",
apiCalls: "Glaonna API",
dailyTokenUsage: "Úsáid laethúil tokens",
dailyBreakdown: "Miondealú laethúil",
perModelBreakdown: "Miondealú de réir samhla",
topSkills: "Príomhscileanna",
skill: "Scil",
loads: "Luchtaithe ag an Agent",
edits: "Bainistithe ag an Agent",
lastUsed: "Úsáidte go deireanach",
input: "Ionchur",
output: "Aschur",
total: "Iomlán",
noUsageData: "Gan sonraí úsáide don tréimhse seo",
startSession: "Tosaigh seisiún chun anailís a fheiceáil anseo",
date: "Dáta",
model: "Samhail",
tokens: "Tokens",
perDayAvg: "/lá meán",
acrossModels: "thar {count} samhail",
inOut: "{input} isteach / {output} amach",
},
models: {
modelsUsed: "Samhlacha úsáidte",
estimatedCost: "Costas measta",
tokens: "tokens",
sessions: "seisiúin",
avgPerSession: "meán/seisiún",
apiCalls: "glaonna API",
toolCalls: "glaonna uirlise",
noModelsData: "Gan sonraí úsáide samhla don tréimhse seo",
startSession: "Tosaigh seisiún chun sonraí samhla a fheiceáil anseo",
},
logs: {
title: "Logaí",
autoRefresh: "Athnuachan uathoibríoch",
file: "Comhad",
level: "Leibhéal",
component: "Comhpháirt",
lines: "Línte",
noLogLines: "Níor aimsíodh línte loga",
},
cron: {
confirmDeleteMessage:
"Baineann sé seo an post ón sceideal. Ní féidir é seo a chealú.",
confirmDeleteTitle: "Scrios an post sceidealta?",
newJob: "Post Cron Nua",
nameOptional: "Ainm (roghnach)",
namePlaceholder: "m.sh. Achoimre laethúil",
prompt: "Prompt",
promptPlaceholder: "Cad ba chóir don agent a dhéanamh ag gach rith?",
schedule: "Sceideal (slonn cron)",
schedulePlaceholder: "0 9 * * *",
deliverTo: "Seachadadh chuig",
scheduledJobs: "Poist sceidealta",
noJobs: "Níl poist cron cumraithe. Cruthaigh ceann thuas.",
last: "Deireanach",
next: "Ar aghaidh",
pause: "Sos",
resume: "Lean ar aghaidh",
triggerNow: "Spreag anois",
delivery: {
local: "Áitiúil",
telegram: "Telegram",
discord: "Discord",
slack: "Slack",
email: "Email",
},
},
profiles: {
newProfile: "Próifíl Nua",
name: "Ainm",
namePlaceholder: "m.sh. coder, writer, srl.",
nameRequired: "Tá ainm riachtanach",
nameRule:
"Litreacha cás íochtair, digití, _ agus - amháin; caithfidh tús a chur le litir nó digit; suas le 64 carachtar.",
invalidName: "Ainm próifíle neamhbhailí",
cloneFromDefault: "Clónáil cumraíocht ón bpróifíl réamhshocraithe",
allProfiles: "Próifílí",
noProfiles: "Níor aimsíodh próifílí.",
defaultBadge: "réamhshocraithe",
hasEnv: "env",
model: "Samhail",
skills: "Scileanna",
rename: "Athainmnigh",
editSoul: "Cuir SOUL.md in eagar",
soulSection: "SOUL.md (pearsantacht / prompt córais)",
soulPlaceholder: "# Conas ba chóir don agent seo iompar…",
saveSoul: "Sábháil SOUL",
soulSaved: "SOUL.md sábháilte",
openInTerminal: "Cóipeáil ordú CLI",
commandCopied: "Cóipeáilte chuig an ngearrthaisce",
copyFailed: "Níorbh fhéidir cóipeáil",
confirmDeleteTitle: "Scrios an phróifíl?",
confirmDeleteMessage:
"Scriosann sé seo an phróifíl '{name}' go buan — cumraíocht, eochracha, cuimhní, seisiúin, scileanna, poist cron. Ní féidir é a chealú.",
created: "Cruthaithe",
deleted: "Scriosta",
renamed: "Athainmnithe",
},
pluginsPage: {
contextEngineLabel: "Inneall comhthéacs",
dashboardSlots: "Slots an dashboard",
disableRuntime: "Díchumasaigh",
enableAfterInstall: "Cumasaigh tar éis suiteála",
enableRuntime: "Cumasaigh",
forceReinstall: "Cuir iallach ar athshuiteáil (scrios an fillteán atá ann ar dtús)",
headline:
"Faigh, suiteáil, cumasaigh agus nuashonraigh plugins Hermes (paireacht le `hermes plugins`).",
identifierLabel: "URL Git nó owner/repo",
inactive: "neamhghníomhach",
installBtn: "Suiteáil ó Git",
installHeading: "Suiteáil ó GitHub / URL Git",
installHint: "Úsáid an gearrshamhail owner/repo nó URL clóin iomlán https:// nó git@.",
memoryProviderLabel: "Soláthraí cuimhne",
missingEnvWarn: "Socraigh iad seo in Eochracha sular féidir leis an plugin rith:",
noDashboardTab: "Gan cluaisín dashboard",
openTab: "Oscail",
orphanHeading: "Síntí dashboard amháin (gan meaitseáil le agent plugin.yaml)",
pluginListHeading: "Plugins suiteáilte",
providerDefaults: "ionsuite / réamhshocraithe",
providersHeading: "Plugins soláthraí runtime",
providersHint:
"Scríobhann memory.provider (folamh = ionsuite) agus context.engine chuig config.yaml. Beidh éifeacht aige sa chéad seisiún eile.",
refreshDashboard: "Athscan síntí an dashboard",
removeConfirm: "Bain an plugin seo ó ~/.hermes/plugins/?",
removeHint: "Ní féidir ach plugins atá suiteáilte ag an úsáideoir faoi ~/.hermes/plugins a bhaint.",
rescanHeading: "Clár plugin SPA",
rescanHint: "Athscan tar éis comhaid a chur leis an diosca ionas go n-aimseoidh barra taoibh an dashboard manifests nua.",
runtimeHeading: "Runtime gateway (plugins YAML)",
saveProviders: "Sábháil socruithe an tsoláthraí",
savedProviders: "Socruithe an tsoláthraí sábháilte.",
sourceBadge: "Foinse",
authRequired: "Fíordheimhniú riachtanach",
authRequiredHint: "Rith an t-ordú seo chun fíordheimhniú a dhéanamh:",
updateGit: "Git pull",
versionBadge: "Leagan",
showInSidebar: "Taispeáin sa bharra taoibh",
hideFromSidebar: "Folaigh ón mbarra taoibh",
},
skills: {
title: "Scileanna",
searchPlaceholder: "Cuardaigh scileanna agus toolsets...",
enabledOf: "{enabled}/{total} cumasaithe",
all: "Gach ceann",
categories: "Catagóirí",
filters: "Scagairí",
noSkills: "Níor aimsíodh scileanna. Luchtaítear scileanna ó ~/.hermes/skills/",
noSkillsMatch: "Níl scil ar bith ag teacht le do chuardach nó scagaire.",
skillCount: "{count} scil{s}",
resultCount: "{count} torad{s}",
noDescription: "Gan cur síos ar fáil.",
toolsets: "Toolsets",
toolsetLabel: "toolset {name}",
noToolsetsMatch: "Níl toolset ar bith ag teacht leis an gcuardach.",
setupNeeded: "Socrú ag teastáil",
disabledForCli: "Díchumasaithe don CLI",
more: "+{count} eile",
},
config: {
configPath: "~/.hermes/config.yaml",
filters: "Scagairí",
sections: "Ranna",
exportConfig: "Easpórtáil cumraíocht mar JSON",
importConfig: "Iompórtáil cumraíocht ó JSON",
resetDefaults: "Athshocraigh chuig réamhshocruithe",
resetScopeTooltip: "Athshocraigh {scope} chuig réamhshocruithe",
confirmResetScope: "Athshocraigh socruithe uile {scope} chuig a réamhshocruithe? Nuashonraíonn sé seo an fhoirm amháin — ní scríobhfar athruithe chuig config.yaml go dtí go mbrúnn tú Sábháil.",
resetScopeToast: "{scope} athshocraithe chuig réamhshocruithe — athbhreithnigh agus Sábháil chun é a choinneáil",
rawYaml: "Cumraíocht YAML amh",
searchResults: "Torthaí cuardaigh",
fields: "réims{s}",
noFieldsMatch: 'Níl aon réimsí ag teacht le "{query}"',
configSaved: "Cumraíocht sábháilte",
yamlConfigSaved: "Cumraíocht YAML sábháilte",
failedToSave: "Theip ar shábháil",
failedToSaveYaml: "Theip ar shábháil an YAML",
failedToLoadRaw: "Theip ar luchtú na cumraíochta amh",
configImported: "Cumraíocht iompórtáilte — athbhreithnigh agus sábháil",
invalidJson: "Comhad JSON neamhbhailí",
categories: {
general: "Ginearálta",
agent: "Agent",
terminal: "Teirminéal",
display: "Taispeáint",
delegation: "Tarmligean",
memory: "Cuimhne",
compression: "Comhbhrú",
security: "Slándáil",
browser: "Brabhsálaí",
voice: "Guth",
tts: "Téacs go Caint",
stt: "Caint go Téacs",
logging: "Logáil",
discord: "Discord",
auxiliary: "Cúntach",
},
},
env: {
changesNote: "Sábháiltear athruithe chuig an diosca láithreach. Aimsíonn seisiúin ghníomhacha eochracha nua go huathoibríoch.",
confirmClearMessage:
"Bainfear an luach stóráilte don athróg seo ó do chomhad .env. Ní féidir é seo a chealú ón UI.",
confirmClearTitle: "Glan an eochair seo?",
description: "Bainistigh eochracha API agus rúin atá stóráilte i",
hideAdvanced: "Folaigh Ardroghanna",
showAdvanced: "Taispeáin Ardroghanna",
llmProviders: "Soláthraithe LLM",
providersConfigured: "{configured} as {total} soláthraí cumraithe",
getKey: "Faigh eochair",
notConfigured: "{count} gan cumrú",
notSet: "Gan socrú",
keysCount: "{count} eochai{s}",
enterValue: "Cuir luach isteach...",
replaceCurrentValue: "Athchuir an luach reatha ({preview})",
showValue: "Taispeáin an fíorluach",
hideValue: "Folaigh an luach",
},
oauth: {
title: "Logálacha isteach soláthraí (OAuth)",
providerLogins: "Logálacha isteach soláthraí (OAuth)",
description: "{connected} as {total} soláthraí OAuth ceangailte. Reáchtáiltear sreabha logála isteach faoi láthair tríd an CLI; cliceáil Cóipeáil ordú agus greamaigh i dteirminéal chun é a shocrú.",
connected: "Ceangailte",
expired: "As feidhm",
notConnected: "Gan cheangal. Rith {command} i dteirminéal.",
runInTerminal: "i dteirminéal.",
noProviders: "Níor aimsíodh soláthraithe a thacaíonn le OAuth.",
login: "Logáil isteach",
disconnect: "Dícheangail",
managedExternally: "Bainistithe go seachtrach",
copied: "Cóipeáilte ✓",
cli: "CLI",
copyCliCommand: "Cóipeáil ordú CLI (le haghaidh úsáide seachtraí / cúltaca)",
connect: "Ceangail",
sessionExpires: "Téann an seisiún as feidhm i {time}",
initiatingLogin: "Ag tosú an tsreabha logála isteach…",
exchangingCode: "Ag malartú an chóid ar tokens…",
connectedClosing: "Ceangailte! Á dhúnadh…",
loginFailed: "Theip ar an logáil isteach.",
sessionExpired: "Seisiún as feidhm. Cliceáil Bain triail eile as chun logáil isteach nua a thosú.",
reOpenAuth: "Athoscail an leathanach údaraithe",
reOpenVerification: "Athoscail an leathanach fíoraithe",
submitCode: "Cuir an cód isteach",
pasteCode: "Greamaigh an cód údaraithe (tá iarmhír #state ceart go leor)",
waitingAuth: "Ag fanacht leat údarú a dhéanamh sa bhrabhsálaí…",
enterCodePrompt: "D'oscail cluaisín nua. Cuir an cód seo isteach má iarrtar ort:",
pkceStep1: "D'oscail cluaisín nua chuig claude.ai. Logáil isteach agus cliceáil Údaraigh.",
pkceStep2: "Cóipeáil an cód údaraithe a thaispeántar tar éis údaraithe.",
pkceStep3: "Greamaigh thíos é agus cuir isteach é.",
flowLabels: {
pkce: "Logáil isteach brabhsálaí (PKCE)",
device_code: "Cód gléis",
external: "CLI seachtrach",
},
expiresIn: "as feidhm i {time}",
},
language: {
switchTo: "Athraigh go Béarla",
},
theme: {
title: "Téama",
switchTheme: "Athraigh téama",
},
achievements: {
hero: {
kicker: "Agentic Gamerscore",
title: "Hermes Achievements",
subtitle:
"Suaitheantais Hermes inbhailithe a thuilltear ó stair fíor-session. Léirítear gnóthachtálacha aitheanta neamhchríochnaithe mar Discovered; fanann gnóthachtálacha Secret i bhfolach go dtí go bhfeictear an chéad iompar comhoiriúnach.",
scan_subtitle:
"Stair session Hermes á scanadh. Is féidir leis an gcéad scan 510 soicind a thógáil ar staireanna móra.",
},
actions: {
rescan: "Athscan",
},
stats: {
unlocked: "Díghlasáilte",
unlocked_hint: "suaitheantais tuillte",
discovered: "Aimsithe",
discovered_hint: "ar eolas, gan tuilleamh fós",
secrets: "Rúin",
secrets_hint: "i bhfolach go dtí an chéad chomhartha",
highest_tier: "An leibhéal is airde",
highest_tier_hint: "Copper → Silver → Gold → Diamond → Olympian",
latest: "An ceann is déanaí",
latest_hint_empty: "rith Hermes níos mó",
none_yet: "Aon cheann fós",
},
state: {
unlocked: "Díghlasáilte",
discovered: "Aimsithe",
secret: "Rún",
},
tier: {
target: "Sprioc {tier}",
hidden: "I bhfolach",
complete: "Críochnaithe",
objective: "Cuspóir",
},
progress: {
hidden: "i bhfolach",
},
scan: {
building_headline: "Próifíl ghnóthachtála á tógáil…",
building_detail:
"Sessions, glaonna ar uirlisí, meiteashonraí samhla agus staid díghlasála á léamh.",
starting_headline: "Scan ghnóthachtála á thosú…",
progress_detail:
"{scanned} as {total} session scanta · {pct}%. Díghlasáiltear suaitheantais de réir mar a shníonn níos mó staire isteach.",
idle_detail:
"Sessions, glaonna ar uirlisí, meiteashonraí samhla agus staid díghlasála á léamh. Feicfear suaitheantais anseo de réir mar a dhíghlasáiltear iad.",
},
guide: {
tiers_header: "Leibhéil",
secret_header: "Gnóthachtálacha rúnda",
secret_body:
"Coinníonn rúin a dtruicear cruinn faoi cheilt. Nuair a fheiceann Hermes comhartha gaolmhar, athraíonn an cárta go Aimsithe agus taispeánann sé a riachtanas.",
scan_status_header: "Stádas an scanta",
scan_status_body:
"Scanann Hermes an stair logánta uair amháin, ansin feicfear cártaí go huathoibríoch. Níl aon rud sáinnithe má thógann sé cúpla soicind.",
what_scanned_header: "Cad a scantar",
what_scanned_body:
"Sessions, glaonna ar uirlisí, meiteashonraí samhla, earráidí, gnóthachtálacha agus staid díghlasála logánta.",
},
card: {
share_title: "Comhroinn an gnóthachtáil seo",
share_label: "Comhroinn {name}",
share_text: "Comhroinn",
how_to_reveal: "Conas é a nochtadh",
what_counts: "Cad a chomhairtear",
evidence_label: "Fianaise",
evidence_session_fallback: "session",
no_evidence: "Níl fianaise ann fós",
},
latest: {
header: "Díghlasálacha le déanaí",
},
empty: {
no_secrets_header: "Níl aon rúin fhalaithe fágtha sa scan seo.",
no_secrets_body:
"Leid: tosaíonn rúin de ghnáth le patrúin teipe neamhghnácha nó patrúin power-user — coinbhleachtaí poirt, ballaí ceadanna, athróga env in easnamh, botúin YAML, imbhuailtí Docker, úsáid rollback/checkpoint, amais cache, nó mionchóirithe tar éis go leor téacs dheirg.",
},
filters: {
all_categories: "Gach rud",
visibility_all: "uile",
visibility_unlocked: "díghlasáilte",
visibility_discovered: "aimsithe",
visibility_secret: "rún",
},
share: {
dialog_label: "Comhroinn gnóthachtáil",
header: "Comhroinn: {name}",
close: "Dún",
rendering: "Á rindreáil…",
card_alt: "Cárta comhroinnte {name}",
error_generic: "Chuaigh rud éigin amú.",
x_title: "Osclaíonn X le post réamhlíonta",
x_button: "Comhroinn ar X",
copy_title: "Cóipeáil an íomhá le greamú isteach i do phost",
copy_button: "Cóipeáil íomhá",
copied: "Cóipeáilte ✓",
download_button: "Íoslódáil PNG",
hint:
"Osclaíonn Comhroinn ar X post réamhlíonta i gcluaisín nua. Cliceáil Cóipeáil íomhá ar dtús más mian leat an suaitheantas 1200×630 a bheith ceangailte — ligeann X duit é a ghreamú díreach isteach i scríbhneoir an tweet. Sábhálann Íoslódáil PNG an comhad le húsáid áit ar bith.",
clipboard_unsupported:
"Ní thacaítear le cóipeáil íomhá chuig an ngearrthaisce sa bhrabhsálaí seo — úsáid Íoslódáil ina ionad sin.",
tweet_text: "Just unlocked {tier_part}\"{name}\" in Hermes Agent ☤",
},
},
kanban: {
loading: "Clár Kanban á luchtú…",
loadFailed: "Theip ar luchtú an chláir Kanban: ",
loadFailedHint:
"Cruthaíonn an cúl-inneall kanban.db go huathoibríoch ar an gcéad léamh. Má leanann sé seo, féach logaí an dashboard.",
board: "Clár",
newBoard: "+ Clár nua",
newBoardTitle: "Clár nua",
newBoardDescription:
"Ligeann boards duit sruthanna oibre neamhghaolmhara a scaradh — ceann amháin in aghaidh an tionscadail, an repo nó an fhearainn. Ní fheiceann workers ar bhord amháin tascanna board eile riamh.",
slug: "Slug",
slugHint: "— litreacha beaga, fleiscíní, m.sh. atm10-server",
displayName: "Ainm taispeána",
displayNameHint: "(roghnach)",
description: "Cur síos",
descriptionHint: "(roghnach)",
icon: "Deilbhín",
iconHint: "(carachtar amháin nó emoji)",
switchAfterCreate: "Athraigh chuig an gclár seo tar éis a chruthaithe",
cancel: "Cealaigh",
creating: "Á chruthú…",
createBoard: "Cruthaigh clár",
search: "Cuardaigh",
filterCards: "Scag cártaí…",
tenant: "Tenant",
allTenants: "Gach tenant",
assignee: "Sannaí",
allProfiles: "Gach profile",
showArchived: "Taispeáin cinn cartlannaithe",
lanesByProfile: "Lánaí de réir profile",
nudgeDispatcher: "Spreag an dispatcher",
refresh: "Athnuaigh",
selected: "roghnaithe",
complete: "Cuir i gcrích",
archive: "Cartlannaigh",
apply: "Cuir i bhfeidhm",
clear: "Glan",
createTask: "Cruthaigh tasc sa cholún seo",
noTasks: "— gan tascanna —",
unassigned: "gan sannadh",
untitled: "(gan teideal)",
loadingDetail: "Á luchtú…",
addComment: "Cuir nóta tráchta… (Enter chun seoladh)",
comment: "Nóta tráchta",
status: "Stádas",
workspace: "Workspace",
skills: "Scileanna",
createdBy: "Cruthaithe ag",
result: "Toradh",
comments: "Nótaí tráchta",
events: "Imeachtaí",
runHistory: "Stair na rití",
workerLog: "Loga an worker",
loadingLog: "Loga á luchtú…",
noWorkerLog:
"— níl loga worker ann fós (níor sheol an tasc nó rinneadh an loga a rothlú) —",
noDescription: "— gan cur síos —",
noComments: "— gan nótaí tráchta —",
edit: "cuir in eagar",
save: "Sábháil",
dependencies: "Spleáchais",
parents: "Tuismitheoirí:",
children: "Leanaí:",
none: "ceann ar bith",
addParent: "— cuir tuismitheoir leis —",
addChild: "— cuir leanbh leis —",
removeDependency: "Bain spleáchas",
block: "Bac",
unblock: "Díbhac",
notifyHomeChannels: "Cuir cainéil bhaile ar an eolas",
diagnostics: "Diagnóisic",
hide: "Folaigh",
show: "Taispeáin",
attention: "Aird",
tasksNeedAttention: "tasc ag teastáil aird",
taskNeedsAttention: "Tá aird ag teastáil ó 1 thasc",
diagnostic: "diagnóis",
open: "Oscail",
close: "Dún (Esc)",
reassignTo: "Athshann chuig:",
copied: "Cóipeáilte",
copyCommand: "Cóipeáil ordú chuig an ngearrthaisce",
reclaim: "Athéiligh",
reassign: "Athshann",
renderingError: "Bhuail earráid rindreála an chluaisín Kanban",
reloadView: "Athluchtaigh an radharc",
wsAuthFailed:
"Theip ar fhíordheimhniú WebSocket — athluchtaigh an leathanach chun an comhartha seisiúin a athnuachan.",
markDone: "Marcáil {n} tasc mar críochnaithe?",
markArchived: "Cartlannaigh {n} tasc?",
warning: "Rabhadh",
phantomIds: "ID-anna taibhse:",
active: "gníomhach",
ended: "críochnaithe",
noProfile: "(gan profile)",
showAllAttempts: "Taispeáin gach iarracht",
sendingUpdates: "Nuashonruithe á seoladh chuig",
sendNotifications: "Seol fógraí completed / blocked / gave_up chuig",
archiveBoardConfirm:
"Cartlannaigh an clár '{name}'? Bogfar é go boards/_archived/ ionas gur féidir é a aisghabháil níos déanaí. Ní bheidh tascanna an chláir seo le feiceáil aon áit san UI a thuilleadh.",
archiveBoardTitle: "Cartlannaigh an clár seo",
boardSwitcherHint: "Ligeann boards duit sruthanna oibre neamhghaolmhara a scaradh",
taskCreatedWarning: "Cruthaíodh an tasc, ach: ",
moveFailed: "Theip ar an mbogadh: ",
bulkFailed: "Cnuasach: ",
completionBlockedHallucination: "⚠ Cuireadh bac ar chríochnú — ID-anna taibhse na gcártaí",
suspectedHallucinatedReferences: "⚠ Tagairt sa téacs do ID-anna taibhse na gcártaí",
pickProfileFirst: "Roghnaigh profile ar dtús.",
unblockedMessage: "Díbhacadh {id}. Tá an tasc réidh don chéad tic eile.",
unblockFailed: "Theip ar an díbhacadh: ",
reclaimedMessage: "Athéilíodh {id}. Tá an tasc ar ais ag ready.",
reclaimFailed: "Theip ar an athéileamh: ",
reassignedMessage: "Athshannadh {id} chuig {profile}.",
reassignFailed: "Theip ar an athshannadh: ",
selectForBulk: "Roghnaigh do ghníomhartha cnuasaigh",
clickToEdit: "Cliceáil chun eagarthóireacht a dhéanamh",
clickToEditAssignee: "Cliceáil chun an sannaí a chur in eagar",
emptyAssignee: "(folamh = bain an sannadh)",
columnLabels: {
triage: "Triáiseáil",
todo: "Le déanamh",
ready: "Réidh",
running: "Ar siúl",
blocked: "Bactha",
done: "Críochnaithe",
archived: "Cartlannaithe",
},
columnHelp: {
triage: "Smaointe amha — déanfaidh specifier an spec a chur i bhfeidhm",
todo: "Ag fanacht ar spleáchais nó gan sannadh",
ready: "Sannta agus ag fanacht ar thic an dispatcher",
running: "Éilithe ag worker — ar siúl",
blocked: "D'iarr an worker ionchur duine",
done: "Críochnaithe",
archived: "Cartlannaithe",
},
confirmDone:
"Marcáil an tasc seo mar críochnaithe? Scaoiltear éileamh an worker agus éiríonn leanaí spleácha ready.",
confirmArchive:
"Cartlannaigh an tasc seo? Imíonn sé as an réamhradharc cláir.",
confirmBlocked:
"Marcáil an tasc seo mar bactha? Scaoiltear éileamh an worker.",
completionSummary:
"Achoimre chríochnaithe ar {label}. Stóráiltear é seo mar result an taisc.",
completionSummaryRequired:
"Tá achoimre chríochnaithe riachtanach sula marcáiltear tasc mar críochnaithe.",
triagePlaceholder: "Smaoineamh garbh — déanfaidh AI an spec…",
taskTitlePlaceholder: "Teideal taisc nua…",
specifier: "specifier",
assigneePlaceholder: "sannaí",
priority: "Tosaíocht",
skillsPlaceholder:
"scileanna (roghnach, scartha le camóga): translation, github-code-review",
noParent: "— gan tuismitheoir —",
workspacePathDir: "conair workspace (riachtanach, m.sh. ~/projects/my-app)",
workspacePathOptional:
"conair workspace (roghnach, díorthaithe ón sannaí má tá sé folamh)",
logTruncated: "(taispeántar an 100 KB deireanach — loga iomlán ag ",
logAt: ")",
},
};

696
web/src/i18n/hu.ts Normal file
View file

@ -0,0 +1,696 @@
import type { Translations } from "./types";
export const hu: Translations = {
common: {
save: "Mentés",
saving: "Mentés...",
cancel: "Mégse",
close: "Bezárás",
confirm: "Megerősítés",
delete: "Törlés",
refresh: "Frissítés",
retry: "Újra",
search: "Keresés...",
loading: "Betöltés...",
create: "Létrehozás",
creating: "Létrehozás...",
set: "Beállítás",
replace: "Csere",
clear: "Törlés",
live: "Élő",
off: "Ki",
enabled: "engedélyezve",
disabled: "letiltva",
active: "aktív",
inactive: "inaktív",
unknown: "ismeretlen",
untitled: "Névtelen",
none: "Nincs",
form: "Űrlap",
noResults: "Nincs találat",
of: "/",
page: "Oldal",
msgs: "üzenet",
tools: "eszközök",
match: "egyezés",
other: "Egyéb",
configured: "beállítva",
removed: "eltávolítva",
failedToToggle: "Nem sikerült átváltani",
failedToRemove: "Nem sikerült eltávolítani",
failedToReveal: "Nem sikerült megjeleníteni",
collapse: "Összecsukás",
expand: "Kibontás",
general: "Általános",
messaging: "Üzenetküldés",
pluginLoadFailed:
"Nem sikerült betölteni a bővítmény szkriptjét. Ellenőrizze a Network fület (dashboard-plugins/…) és a kiszolgáló bővítmény-elérési útját.",
pluginNotRegistered:
"A bővítmény szkriptje nem hívta meg a register() függvényt, vagy hibára futott. A részletekért nyissa meg a böngésző konzolját.",
},
app: {
brand: "Hermes Agent",
brandShort: "HA",
closeNavigation: "Navigáció bezárása",
closeModelTools: "Modell és eszközök bezárása",
footer: {
org: "Nous Research",
},
activeSessionsLabel: "Aktív munkamenetek:",
gatewayStatusLabel: "Átjáró állapota:",
gatewayStrip: {
failed: "Indítás sikertelen",
off: "Ki",
running: "Fut",
starting: "Indul",
stopped: "Leállítva",
},
nav: {
analytics: "Analitika",
chat: "Csevegés",
config: "Beállítások",
cron: "Cron",
documentation: "Dokumentáció",
keys: "Kulcsok",
logs: "Naplók",
models: "Modellek",
profiles: "profilok: több ügynök",
plugins: "Bővítmények",
sessions: "Munkamenetek",
skills: "Készségek",
},
modelToolsSheetSubtitle: "és eszközök",
modelToolsSheetTitle: "Modell",
navigation: "Navigáció",
openDocumentation: "Dokumentáció megnyitása új lapon",
openNavigation: "Navigáció megnyitása",
pluginNavSection: "Bővítmények",
sessionsActiveCount: "{count} aktív",
statusOverview: "Állapot áttekintése",
system: "Rendszer",
webUi: "Web UI",
},
status: {
actionFailed: "Művelet sikertelen",
actionFinished: "Befejezve",
actions: "Műveletek",
agent: "Ügynök",
activeSessions: "Aktív munkamenetek",
connected: "Csatlakoztatva",
connectedPlatforms: "Csatlakoztatott platformok",
disconnected: "Lekapcsolva",
error: "Hiba",
failed: "Sikertelen",
gateway: "Átjáró",
gatewayFailedToStart: "Az átjáró nem indult el",
lastUpdate: "Utolsó frissítés",
noneRunning: "Nincs",
notRunning: "Nem fut",
pid: "PID",
platformDisconnected: "lekapcsolva",
platformError: "hiba",
recentSessions: "Legutóbbi munkamenetek",
restartGateway: "Átjáró újraindítása",
restartingGateway: "Átjáró újraindítása…",
running: "Fut",
runningRemote: "Fut (távoli)",
startFailed: "Indítás sikertelen",
starting: "Indul",
startedInBackground: "Háttérben elindítva — kövesse a naplókat a folyamathoz",
stopped: "Leállítva",
updateHermes: "Hermes frissítése",
updatingHermes: "Hermes frissítése…",
waitingForOutput: "Várakozás a kimenetre…",
},
sessions: {
title: "Munkamenetek",
searchPlaceholder: "Keresés üzenettartalomban...",
noSessions: "Még nincsenek munkamenetek",
noMatch: "Nincs a keresésnek megfelelő munkamenet",
startConversation: "Indítson egy beszélgetést, hogy itt megjelenjen",
noMessages: "Nincsenek üzenetek",
untitledSession: "Névtelen munkamenet",
deleteSession: "Munkamenet törlése",
confirmDeleteTitle: "Törli a munkamenetet?",
confirmDeleteMessage:
"Ez véglegesen eltávolítja a beszélgetést és minden üzenetét. A művelet nem vonható vissza.",
sessionDeleted: "Munkamenet törölve",
failedToDelete: "Nem sikerült törölni a munkamenetet",
resumeInChat: "Folytatás a csevegésben",
previousPage: "Előző oldal",
nextPage: "Következő oldal",
roles: {
user: "Felhasználó",
assistant: "Asszisztens",
system: "Rendszer",
tool: "Eszköz",
},
},
analytics: {
period: "Időszak:",
totalTokens: "Összes token",
totalSessions: "Összes munkamenet",
apiCalls: "API-hívások",
dailyTokenUsage: "Napi tokenhasználat",
dailyBreakdown: "Napi bontás",
perModelBreakdown: "Modellek szerinti bontás",
topSkills: "Legnépszerűbb készségek",
skill: "Készség",
loads: "Ügynök által betöltve",
edits: "Ügynök által kezelve",
lastUsed: "Utoljára használva",
input: "Bemenet",
output: "Kimenet",
total: "Összesen",
noUsageData: "Nincs használati adat erre az időszakra",
startSession: "Indítson munkamenetet az analitika megtekintéséhez",
date: "Dátum",
model: "Modell",
tokens: "Tokenek",
perDayAvg: "/nap átlag",
acrossModels: "{count} modellen át",
inOut: "{input} be / {output} ki",
},
models: {
modelsUsed: "Használt modellek",
estimatedCost: "Becsült költség",
tokens: "tokenek",
sessions: "munkamenetek",
avgPerSession: "átlag/munkamenet",
apiCalls: "API-hívások",
toolCalls: "eszközhívások",
noModelsData: "Nincs modellhasználati adat erre az időszakra",
startSession: "Indítson munkamenetet a modelladatok megtekintéséhez",
},
logs: {
title: "Naplók",
autoRefresh: "Automatikus frissítés",
file: "Fájl",
level: "Szint",
component: "Komponens",
lines: "Sorok",
noLogLines: "Nem található naplóbejegyzés",
},
cron: {
confirmDeleteMessage:
"Ez eltávolítja a feladatot az ütemezésből. A művelet nem vonható vissza.",
confirmDeleteTitle: "Törli az ütemezett feladatot?",
newJob: "Új Cron-feladat",
nameOptional: "Név (opcionális)",
namePlaceholder: "pl. Napi összegzés",
prompt: "Prompt",
promptPlaceholder: "Mit tegyen az ügynök minden futtatáskor?",
schedule: "Ütemezés (cron-kifejezés)",
schedulePlaceholder: "0 9 * * *",
deliverTo: "Kézbesítés ide",
scheduledJobs: "Ütemezett feladatok",
noJobs: "Nincs beállított cron-feladat. Hozzon létre egyet fent.",
last: "Utolsó",
next: "Következő",
pause: "Szüneteltetés",
resume: "Folytatás",
triggerNow: "Indítás most",
delivery: {
local: "Helyi",
telegram: "Telegram",
discord: "Discord",
slack: "Slack",
email: "Email",
},
},
profiles: {
newProfile: "Új profil",
name: "Név",
namePlaceholder: "pl. coder, writer stb.",
nameRequired: "A név kötelező",
nameRule:
"Csak kisbetűk, számjegyek, _ és - karakterek; betűvel vagy számjeggyel kell kezdődnie; legfeljebb 64 karakter.",
invalidName: "Érvénytelen profilnév",
cloneFromDefault: "Konfiguráció klónozása az alapértelmezett profilból",
allProfiles: "Profilok",
noProfiles: "Nem található profil.",
defaultBadge: "alapértelmezett",
hasEnv: "env",
model: "Modell",
skills: "Készségek",
rename: "Átnevezés",
editSoul: "SOUL.md szerkesztése",
soulSection: "SOUL.md (személyiség / rendszerprompt)",
soulPlaceholder: "# Hogyan viselkedjen ez az ügynök…",
saveSoul: "SOUL mentése",
soulSaved: "SOUL.md mentve",
openInTerminal: "CLI-parancs másolása",
commandCopied: "Vágólapra másolva",
copyFailed: "Nem sikerült másolni",
confirmDeleteTitle: "Törli a profilt?",
confirmDeleteMessage:
"Ez véglegesen törli a(z) '{name}' profilt — konfigurációt, kulcsokat, emlékeket, munkameneteket, készségeket, cron-feladatokat. A művelet nem vonható vissza.",
created: "Létrehozva",
deleted: "Törölve",
renamed: "Átnevezve",
},
pluginsPage: {
contextEngineLabel: "Kontextusmotor",
dashboardSlots: "Vezérlőpult-slotok",
disableRuntime: "Letiltás",
enableAfterInstall: "Engedélyezés a telepítés után",
enableRuntime: "Engedélyezés",
forceReinstall: "Kényszerített újratelepítés (a meglévő mappa előbb törlődik)",
headline:
"Hermes-bővítmények felfedezése, telepítése, engedélyezése és frissítése (a `hermes plugins` paritás).",
identifierLabel: "Git URL vagy owner/repo",
inactive: "inaktív",
installBtn: "Telepítés Gitből",
installHeading: "Telepítés GitHubról / Git URL-ről",
installHint: "Használjon owner/repo rövidítést vagy teljes https:// vagy git@ klónozási URL-t.",
memoryProviderLabel: "Memória-szolgáltató",
missingEnvWarn: "Állítsa be ezeket a Kulcsok között, mielőtt a bővítmény futhatna:",
noDashboardTab: "Nincs vezérlőpult-fül",
openTab: "Megnyitás",
orphanHeading: "Csak vezérlőpult-bővítmények (nincs egyező agent plugin.yaml)",
pluginListHeading: "Telepített bővítmények",
providerDefaults: "beépített / alapértelmezett",
providersHeading: "Futási idejű szolgáltató-bővítmények",
providersHint:
"A memory.provider (üres = beépített) és a context.engine értékét írja a config.yaml fájlba. A következő munkamenetben lép életbe.",
refreshDashboard: "Vezérlőpult-bővítmények újraolvasása",
removeConfirm: "Eltávolítja ezt a bővítményt a ~/.hermes/plugins/ mappából?",
removeHint: "Csak a felhasználó által a ~/.hermes/plugins alá telepített bővítmények távolíthatók el.",
rescanHeading: "SPA-bővítményregiszter",
rescanHint: "Olvassa újra a fájlokat a lemezen történő hozzáadás után, hogy az oldalsáv felvegye az új manifesteket.",
runtimeHeading: "Átjáró-futási idő (YAML-bővítmények)",
saveProviders: "Szolgáltatóbeállítások mentése",
savedProviders: "Szolgáltatóbeállítások mentve.",
sourceBadge: "Forrás",
authRequired: "Hitelesítés szükséges",
authRequiredHint: "Futtassa ezt a parancsot a hitelesítéshez:",
updateGit: "Git pull",
versionBadge: "Verzió",
showInSidebar: "Megjelenítés az oldalsávon",
hideFromSidebar: "Elrejtés az oldalsávról",
},
skills: {
title: "Készségek",
searchPlaceholder: "Készségek és eszközkészletek keresése...",
enabledOf: "{enabled}/{total} engedélyezve",
all: "Összes",
categories: "Kategóriák",
filters: "Szűrők",
noSkills: "Nem található készség. A készségek a ~/.hermes/skills/ mappából töltődnek be",
noSkillsMatch: "Nincs a keresésnek vagy szűrőnek megfelelő készség.",
skillCount: "{count} készség{s}",
resultCount: "{count} találat{s}",
noDescription: "Nincs elérhető leírás.",
toolsets: "Eszközkészletek",
toolsetLabel: "{name} eszközkészlet",
noToolsetsMatch: "Nincs a keresésnek megfelelő eszközkészlet.",
setupNeeded: "Beállítás szükséges",
disabledForCli: "CLI-hez letiltva",
more: "+{count} további",
},
config: {
configPath: "~/.hermes/config.yaml",
filters: "Szűrők",
sections: "Szakaszok",
exportConfig: "Konfiguráció exportálása JSON-ba",
importConfig: "Konfiguráció importálása JSON-ból",
resetDefaults: "Visszaállítás alapértelmezettre",
resetScopeTooltip: "{scope} visszaállítása alapértelmezettre",
confirmResetScope: "Visszaállítja az összes {scope} beállítást alapértelmezettre? Ez csak az űrlapot frissíti — a változások nem íródnak be a config.yaml fájlba, amíg meg nem nyomja a Mentés gombot.",
resetScopeToast: "{scope} visszaállítva alapértelmezettre — ellenőrizze és mentse a megőrzéshez",
rawYaml: "Nyers YAML-konfiguráció",
searchResults: "Keresési eredmények",
fields: "mező{s}",
noFieldsMatch: 'Nincs a(z) "{query}" keresésnek megfelelő mező',
configSaved: "Konfiguráció mentve",
yamlConfigSaved: "YAML-konfiguráció mentve",
failedToSave: "Mentés sikertelen",
failedToSaveYaml: "YAML mentése sikertelen",
failedToLoadRaw: "Nem sikerült betölteni a nyers konfigurációt",
configImported: "Konfiguráció importálva — ellenőrizze és mentse",
invalidJson: "Érvénytelen JSON-fájl",
categories: {
general: "Általános",
agent: "Ügynök",
terminal: "Terminál",
display: "Megjelenítés",
delegation: "Delegálás",
memory: "Memória",
compression: "Tömörítés",
security: "Biztonság",
browser: "Böngésző",
voice: "Hang",
tts: "Szövegfelolvasás",
stt: "Beszédfelismerés",
logging: "Naplózás",
discord: "Discord",
auxiliary: "Kiegészítő",
},
},
env: {
changesNote: "A változások azonnal mentésre kerülnek a lemezre. Az aktív munkamenetek automatikusan átveszik az új kulcsokat.",
confirmClearMessage:
"A változó tárolt értéke törlődik a .env fájlból. Ez a felületről nem vonható vissza.",
confirmClearTitle: "Törli ezt a kulcsot?",
description: "API-kulcsok és titkok kezelése a következő helyen:",
hideAdvanced: "Speciális elrejtése",
showAdvanced: "Speciális megjelenítése",
llmProviders: "LLM-szolgáltatók",
providersConfigured: "{configured} / {total} szolgáltató beállítva",
getKey: "Kulcs lekérése",
notConfigured: "{count} nincs beállítva",
notSet: "Nincs beállítva",
keysCount: "{count} kulcs{s}",
enterValue: "Adjon meg értéket...",
replaceCurrentValue: "Jelenlegi érték cseréje ({preview})",
showValue: "Tényleges érték megjelenítése",
hideValue: "Érték elrejtése",
},
oauth: {
title: "Szolgáltatói bejelentkezések (OAuth)",
providerLogins: "Szolgáltatói bejelentkezések (OAuth)",
description: "{connected} / {total} OAuth-szolgáltató csatlakoztatva. A bejelentkezési folyamat jelenleg a CLI-n keresztül fut; kattintson a Parancs másolása gombra, és illessze be egy terminálba a beállításhoz.",
connected: "Csatlakoztatva",
expired: "Lejárt",
notConnected: "Nincs csatlakoztatva. Futtassa a {command} parancsot egy terminálban.",
runInTerminal: "egy terminálban.",
noProviders: "Nem észlelhető OAuth-képes szolgáltató.",
login: "Bejelentkezés",
disconnect: "Lecsatlakozás",
managedExternally: "Külsőleg kezelt",
copied: "Másolva ✓",
cli: "CLI",
copyCliCommand: "CLI-parancs másolása (külső / tartalék)",
connect: "Csatlakozás",
sessionExpires: "A munkamenet {time} múlva lejár",
initiatingLogin: "Bejelentkezési folyamat indítása…",
exchangingCode: "Kód cseréje tokenekre…",
connectedClosing: "Csatlakoztatva! Bezárás…",
loginFailed: "A bejelentkezés sikertelen.",
sessionExpired: "A munkamenet lejárt. Kattintson az Újra gombra új bejelentkezéshez.",
reOpenAuth: "Hitelesítési oldal újranyitása",
reOpenVerification: "Ellenőrzési oldal újranyitása",
submitCode: "Kód beküldése",
pasteCode: "Illessze be a hitelesítési kódot (a #state utótaggal együtt is megfelel)",
waitingAuth: "Várakozás a böngészőben történő engedélyezésre…",
enterCodePrompt: "Új lap nyílt meg. Adja meg ezt a kódot, ha kéri:",
pkceStep1: "Új lap nyílt meg a claude.ai oldalra. Jelentkezzen be, és kattintson az Authorize gombra.",
pkceStep2: "Másolja ki az engedélyezés után megjelenő hitelesítési kódot.",
pkceStep3: "Illessze be alább, és küldje be.",
flowLabels: {
pkce: "Bejelentkezés böngészőből (PKCE)",
device_code: "Eszközkód",
external: "Külső CLI",
},
expiresIn: "lejár {time} múlva",
},
language: {
switchTo: "Váltás angolra",
},
theme: {
title: "Téma",
switchTheme: "Téma váltása",
},
achievements: {
hero: {
kicker: "Agentic Gamerscore",
title: "Hermes Achievements",
subtitle:
"Gyűjthető Hermes-jelvények, valós munkamenet-előzmények alapján szerezve. Az ismert, de még nem szerzett teljesítmények Felfedezettként jelennek meg; a Titkos teljesítmények rejtve maradnak az első egyező viselkedésig.",
scan_subtitle:
"Hermes munkamenet-előzmények vizsgálata. Az első vizsgálat 510 másodpercig is eltarthat nagy előzmények esetén.",
},
actions: {
rescan: "Újravizsgálat",
},
stats: {
unlocked: "Feloldva",
unlocked_hint: "megszerzett jelvények",
discovered: "Felfedezve",
discovered_hint: "ismert, még nem szerzett",
secrets: "Titkok",
secrets_hint: "rejtve az első jelzésig",
highest_tier: "Legmagasabb szint",
highest_tier_hint: "Copper → Silver → Gold → Diamond → Olympian",
latest: "Legutóbbi",
latest_hint_empty: "futtasd többet a Hermest",
none_yet: "Még semmi",
},
state: {
unlocked: "Feloldva",
discovered: "Felfedezve",
secret: "Titkos",
},
tier: {
target: "Cél: {tier}",
hidden: "Rejtett",
complete: "Kész",
objective: "Cél",
},
progress: {
hidden: "rejtett",
},
scan: {
building_headline: "Teljesítményprofil építése…",
building_detail:
"Munkamenetek, eszközhívások, modell-metaadatok és feloldási állapot olvasása.",
starting_headline: "Teljesítmény-vizsgálat indítása…",
progress_detail:
"{scanned} / {total} munkamenet vizsgálva · {pct}%. A jelvények a további előzmények beolvasásával oldódnak fel.",
idle_detail:
"Munkamenetek, eszközhívások, modell-metaadatok és feloldási állapot olvasása. A jelvények itt jelennek meg, ahogy feloldódnak.",
},
guide: {
tiers_header: "Szintek",
secret_header: "Titkos teljesítmények",
secret_body:
"A titkos teljesítmények elrejtik a pontos kiváltó eseményt. Amint a Hermes kapcsolódó jelet észlel, a kártya Felfedezettre vált, és megjeleníti a követelményt.",
scan_status_header: "Vizsgálat állapota",
scan_status_body:
"A Hermes egyszer átvizsgálja a helyi előzményeket, majd a kártyák automatikusan megjelennek. Semmi sem akadt el, ha ez néhány másodpercig tart.",
what_scanned_header: "Mit vizsgálunk",
what_scanned_body:
"Munkamenetek, eszközhívások, modell-metaadatok, hibák, teljesítmények és helyi feloldási állapot.",
},
card: {
share_title: "Teljesítmény megosztása",
share_label: "{name} megosztása",
share_text: "Megosztás",
how_to_reveal: "Hogyan fedhető fel",
what_counts: "Mi számít",
evidence_label: "Bizonyíték",
evidence_session_fallback: "munkamenet",
no_evidence: "Még nincs bizonyíték",
},
latest: {
header: "Legutóbbi feloldások",
},
empty: {
no_secrets_header: "Ebben a vizsgálatban nem maradt rejtett titok.",
no_secrets_body:
"Tipp: a titkok általában szokatlan hibákból vagy haladó felhasználói mintákból indulnak — portütközések, jogosultsági falak, hiányzó környezeti változók, YAML-hibák, Docker-ütközések, rollback/checkpoint használata, gyorsítótár-találatok vagy apró javítások sok piros szöveg után.",
},
filters: {
all_categories: "Összes",
visibility_all: "összes",
visibility_unlocked: "feloldott",
visibility_discovered: "felfedezett",
visibility_secret: "titkos",
},
share: {
dialog_label: "Teljesítmény megosztása",
header: "Megosztás: {name}",
close: "Bezárás",
rendering: "Renderelés…",
card_alt: "{name} megosztókártya",
error_generic: "Valami hiba történt.",
x_title: "Megnyitja az X-et előre kitöltött bejegyzéssel",
x_button: "Megosztás az X-en",
copy_title: "Kép másolása a bejegyzésbe való beillesztéshez",
copy_button: "Kép másolása",
copied: "Másolva ✓",
download_button: "PNG letöltése",
hint:
"A „Megosztás az X-en” új lapon nyit meg egy előre kitöltött bejegyzést. Először kattints a „Kép másolása” gombra, ha az 1200×630-as jelvényt is csatolnád — az X engedi, hogy közvetlenül beillesszd a bejegyzésszerkesztőbe. A „PNG letöltése” bárhol felhasználható fájlként menti.",
clipboard_unsupported:
"A kép vágólapra másolása nem támogatott ebben a böngészőben — használd inkább a Letöltést.",
tweet_text: "Just unlocked {tier_part}\"{name}\" in Hermes Agent ☤",
},
},
kanban: {
loading: "Kanban tábla betöltése…",
loadFailed: "Nem sikerült betölteni a Kanban táblát: ",
loadFailedHint:
"A backend első olvasáskor automatikusan létrehozza a kanban.db fájlt. Ha továbbra is fennáll, ellenőrizd a dashboard naplóit.",
board: "Tábla",
newBoard: "+ Új tábla",
newBoardTitle: "Új tábla",
newBoardDescription:
"A táblákkal külön tudod választani az egymással nem összefüggő munkafolyamokat — egyet projektenként, repónként vagy területenként. Az egyik tábla workerei sosem látják a másik tábla feladatait.",
slug: "Slug",
slugHint: "— kisbetűk, kötőjelek, pl. atm10-server",
displayName: "Megjelenítendő név",
displayNameHint: "(opcionális)",
description: "Leírás",
descriptionHint: "(opcionális)",
icon: "Ikon",
iconHint: "(egyetlen karakter vagy emodzsi)",
switchAfterCreate: "Váltás erre a táblára létrehozás után",
cancel: "Mégse",
creating: "Létrehozás…",
createBoard: "Tábla létrehozása",
search: "Keresés",
filterCards: "Kártyák szűrése…",
tenant: "Tenant",
allTenants: "Összes tenant",
assignee: "Felelős",
allProfiles: "Összes profil",
showArchived: "Archiváltak megjelenítése",
lanesByProfile: "Sávok profil szerint",
nudgeDispatcher: "Dispatcher noszogatása",
refresh: "Frissítés",
selected: "kiválasztva",
complete: "Befejezés",
archive: "Archiválás",
apply: "Alkalmaz",
clear: "Törlés",
createTask: "Feladat létrehozása ebben az oszlopban",
noTasks: "— nincsenek feladatok —",
unassigned: "nincs felelős",
untitled: "(névtelen)",
loadingDetail: "Betöltés…",
addComment: "Hozzászólás hozzáadása… (Enter a beküldéshez)",
comment: "Hozzászólás",
status: "Állapot",
workspace: "Munkaterület",
skills: "Készségek",
createdBy: "Létrehozta",
result: "Eredmény",
comments: "Hozzászólások",
events: "Események",
runHistory: "Futási előzmények",
workerLog: "Worker napló",
loadingLog: "Napló betöltése…",
noWorkerLog:
"— még nincs worker napló (a feladat nem indult el, vagy a napló rotálódott) —",
noDescription: "— nincs leírás —",
noComments: "— nincsenek hozzászólások —",
edit: "szerkesztés",
save: "Mentés",
dependencies: "Függőségek",
parents: "Szülők:",
children: "Gyermekek:",
none: "nincs",
addParent: "— szülő hozzáadása —",
addChild: "— gyermek hozzáadása —",
removeDependency: "Függőség eltávolítása",
block: "Blokkolás",
unblock: "Feloldás",
notifyHomeChannels: "Otthoni csatornák értesítése",
diagnostics: "Diagnosztika",
hide: "Elrejtés",
show: "Megjelenítés",
attention: "Figyelem",
tasksNeedAttention: "feladat figyelmet igényel",
taskNeedsAttention: "1 feladat figyelmet igényel",
diagnostic: "diagnosztika",
open: "Megnyitás",
close: "Bezárás (Esc)",
reassignTo: "Új felelős:",
copied: "Másolva",
copyCommand: "Parancs másolása a vágólapra",
reclaim: "Visszavétel",
reassign: "Újrakiosztás",
renderingError: "A Kanban fülön renderelési hiba lépett fel",
reloadView: "Nézet újratöltése",
wsAuthFailed:
"WebSocket-hitelesítés sikertelen — töltsd újra az oldalt a munkamenet-token frissítéséhez.",
markDone: "Megjelölöd {n} feladatot késznek?",
markArchived: "Archiválsz {n} feladatot?",
warning: "Figyelmeztetés",
phantomIds: "Fantom id-k:",
active: "aktív",
ended: "befejeződött",
noProfile: "(nincs profil)",
showAllAttempts: "Összes próbálkozás megjelenítése",
sendingUpdates: "Frissítések küldése ide:",
sendNotifications: "completed / blocked / gave_up értesítések küldése ide:",
archiveBoardConfirm:
"Archiválod a(z) '{name}' táblát? Áthelyezzük a boards/_archived/ mappába, hogy később visszaállíthasd. A táblán lévő feladatok többé nem jelennek meg sehol az UI-ban.",
archiveBoardTitle: "Tábla archiválása",
boardSwitcherHint: "A táblákkal külön tudod választani az egymással nem összefüggő munkafolyamokat",
taskCreatedWarning: "Feladat létrehozva, de: ",
moveFailed: "Áthelyezés sikertelen: ",
bulkFailed: "Tömeges: ",
completionBlockedHallucination: "⚠ Befejezés blokkolva — fantom kártya id-k",
suspectedHallucinatedReferences: "⚠ A szöveg fantom kártya id-kre hivatkozott",
pickProfileFirst: "Először válassz profilt.",
unblockedMessage: "{id} feloldva. A feladat készen áll a következő tickre.",
unblockFailed: "Feloldás sikertelen: ",
reclaimedMessage: "{id} visszavéve. A feladat újra ready állapotban van.",
reclaimFailed: "Visszavétel sikertelen: ",
reassignedMessage: "{id} újrakiosztva neki: {profile}.",
reassignFailed: "Újrakiosztás sikertelen: ",
selectForBulk: "Kijelölés tömeges műveletekhez",
clickToEdit: "Kattints a szerkesztéshez",
clickToEditAssignee: "Kattints a felelős szerkesztéséhez",
emptyAssignee: "(üres = felelős eltávolítása)",
columnLabels: {
triage: "Triázs",
todo: "Tennivaló",
ready: "Indulásra kész",
running: "Folyamatban",
blocked: "Blokkolva",
done: "Kész",
archived: "Archivált",
},
columnHelp: {
triage: "Nyers ötletek — egy specifier kidolgozza a specifikációt",
todo: "Függőségekre vár vagy nincs felelőse",
ready: "Kiosztva, dispatcher tickre vár",
running: "Worker felvette — folyamatban",
blocked: "A worker emberi beavatkozást kért",
done: "Befejezve",
archived: "Archiválva",
},
confirmDone:
"Megjelölöd ezt a feladatot késznek? A worker foglalása felszabadul, és a függő gyermekek ready állapotba kerülnek.",
confirmArchive:
"Archiválod ezt a feladatot? Eltűnik az alapértelmezett tábla nézetből.",
confirmBlocked:
"Megjelölöd ezt a feladatot blokkoltként? A worker foglalása felszabadul.",
completionSummary:
"Befejezési összefoglaló a következőhöz: {label}. Ez a feladat eredményeként kerül tárolásra.",
completionSummaryRequired:
"A feladat késznek jelölése előtt kötelező megadni a befejezési összefoglalót.",
triagePlaceholder: "Nyers ötlet — az AI specifikálja…",
taskTitlePlaceholder: "Új feladat címe…",
specifier: "specifier",
assigneePlaceholder: "felelős",
priority: "Prioritás",
skillsPlaceholder:
"készségek (opcionális, vesszővel elválasztva): translation, github-code-review",
noParent: "— nincs szülő —",
workspacePathDir: "munkaterület útvonala (kötelező, pl. ~/projects/my-app)",
workspacePathOptional:
"munkaterület útvonala (opcionális, üresen a felelősből származtatva)",
logTruncated: "(az utolsó 100 KB látható — teljes napló: ",
logAt: ")",
},
};

View file

@ -1,2 +1,2 @@
export { I18nProvider, useI18n } from "./context";
export { I18nProvider, useI18n, LOCALE_META } from "./context";
export type { Locale, Translations } from "./types";

695
web/src/i18n/it.ts Normal file
View file

@ -0,0 +1,695 @@
import type { Translations } from "./types";
export const it: Translations = {
common: {
save: "Salva",
saving: "Salvataggio...",
cancel: "Annulla",
close: "Chiudi",
confirm: "Conferma",
delete: "Elimina",
refresh: "Aggiorna",
retry: "Riprova",
search: "Cerca...",
loading: "Caricamento...",
create: "Crea",
creating: "Creazione...",
set: "Imposta",
replace: "Sostituisci",
clear: "Cancella",
live: "In tempo reale",
off: "Spento",
enabled: "abilitato",
disabled: "disabilitato",
active: "attivo",
inactive: "inattivo",
unknown: "sconosciuto",
untitled: "Senza titolo",
none: "Nessuno",
form: "Modulo",
noResults: "Nessun risultato",
of: "di",
page: "Pagina",
msgs: "msg",
tools: "strumenti",
match: "corrispondenza",
other: "Altro",
configured: "configurato",
removed: "rimosso",
failedToToggle: "Commutazione non riuscita",
failedToRemove: "Rimozione non riuscita",
failedToReveal: "Visualizzazione non riuscita",
collapse: "Comprimi",
expand: "Espandi",
general: "Generale",
messaging: "Messaggistica",
pluginLoadFailed:
"Impossibile caricare lo script di questo plugin. Controlla la scheda Network (dashboard-plugins/…) e il percorso dei plugin del server.",
pluginNotRegistered:
"Lo script del plugin non ha chiamato register(), oppure ha generato un errore. Apri la console del browser per i dettagli.",
},
app: {
brand: "Hermes Agent",
brandShort: "HA",
closeNavigation: "Chiudi navigazione",
closeModelTools: "Chiudi modello e strumenti",
footer: {
org: "Nous Research",
},
activeSessionsLabel: "Sessioni attive:",
gatewayStatusLabel: "Stato gateway:",
gatewayStrip: {
failed: "Avvio non riuscito",
off: "Spento",
running: "In esecuzione",
starting: "Avvio in corso",
stopped: "Arrestato",
},
nav: {
analytics: "Analisi",
chat: "Chat",
config: "Configurazione",
cron: "Cron",
documentation: "Documentazione",
keys: "Chiavi",
logs: "Log",
models: "Modelli",
profiles: "profili : multi agent",
plugins: "Plugin",
sessions: "Sessioni",
skills: "Competenze",
},
modelToolsSheetSubtitle: "e strumenti",
modelToolsSheetTitle: "Modello",
navigation: "Navigazione",
openDocumentation: "Apri la documentazione in una nuova scheda",
openNavigation: "Apri navigazione",
pluginNavSection: "Plugin",
sessionsActiveCount: "{count} attive",
statusOverview: "Panoramica dello stato",
system: "Sistema",
webUi: "Web UI",
},
status: {
actionFailed: "Azione non riuscita",
actionFinished: "Completata",
actions: "Azioni",
agent: "Agente",
activeSessions: "Sessioni attive",
connected: "Connesso",
connectedPlatforms: "Piattaforme connesse",
disconnected: "Disconnesso",
error: "Errore",
failed: "Non riuscito",
gateway: "Gateway",
gatewayFailedToStart: "Avvio del gateway non riuscito",
lastUpdate: "Ultimo aggiornamento",
noneRunning: "Nessuno",
notRunning: "Non in esecuzione",
pid: "PID",
platformDisconnected: "disconnesso",
platformError: "errore",
recentSessions: "Sessioni recenti",
restartGateway: "Riavvia gateway",
restartingGateway: "Riavvio del gateway…",
running: "In esecuzione",
runningRemote: "In esecuzione (remoto)",
startFailed: "Avvio non riuscito",
starting: "Avvio in corso",
startedInBackground: "Avviato in background — controlla i log per i progressi",
stopped: "Arrestato",
updateHermes: "Aggiorna Hermes",
updatingHermes: "Aggiornamento di Hermes…",
waitingForOutput: "In attesa di output…",
},
sessions: {
title: "Sessioni",
searchPlaceholder: "Cerca nel contenuto dei messaggi...",
noSessions: "Nessuna sessione",
noMatch: "Nessuna sessione corrisponde alla ricerca",
startConversation: "Avvia una conversazione per vederla qui",
noMessages: "Nessun messaggio",
untitledSession: "Sessione senza titolo",
deleteSession: "Elimina sessione",
confirmDeleteTitle: "Eliminare la sessione?",
confirmDeleteMessage:
"Questa operazione rimuove definitivamente la conversazione e tutti i suoi messaggi. Non può essere annullata.",
sessionDeleted: "Sessione eliminata",
failedToDelete: "Eliminazione della sessione non riuscita",
resumeInChat: "Riprendi nella chat",
previousPage: "Pagina precedente",
nextPage: "Pagina successiva",
roles: {
user: "Utente",
assistant: "Assistente",
system: "Sistema",
tool: "Strumento",
},
},
analytics: {
period: "Periodo:",
totalTokens: "Token totali",
totalSessions: "Sessioni totali",
apiCalls: "Chiamate API",
dailyTokenUsage: "Utilizzo giornaliero token",
dailyBreakdown: "Dettaglio giornaliero",
perModelBreakdown: "Dettaglio per modello",
topSkills: "Competenze più usate",
skill: "Competenza",
loads: "Caricato dall'agente",
edits: "Gestito dall'agente",
lastUsed: "Ultimo uso",
input: "Input",
output: "Output",
total: "Totale",
noUsageData: "Nessun dato di utilizzo per questo periodo",
startSession: "Avvia una sessione per vedere le analisi qui",
date: "Data",
model: "Modello",
tokens: "Token",
perDayAvg: "/giorno medio",
acrossModels: "su {count} modelli",
inOut: "{input} in / {output} out",
},
models: {
modelsUsed: "Modelli utilizzati",
estimatedCost: "Costo stim.",
tokens: "token",
sessions: "sessioni",
avgPerSession: "media/sessione",
apiCalls: "chiamate API",
toolCalls: "chiamate strumenti",
noModelsData: "Nessun dato sull'uso dei modelli per questo periodo",
startSession: "Avvia una sessione per vedere i dati dei modelli qui",
},
logs: {
title: "Log",
autoRefresh: "Aggiornamento automatico",
file: "File",
level: "Livello",
component: "Componente",
lines: "Righe",
noLogLines: "Nessuna riga di log trovata",
},
cron: {
confirmDeleteMessage:
"Questa operazione rimuove l'attività dalla pianificazione. Non può essere annullata.",
confirmDeleteTitle: "Eliminare l'attività pianificata?",
newJob: "Nuova attività cron",
nameOptional: "Nome (facoltativo)",
namePlaceholder: "es. Riepilogo giornaliero",
prompt: "Prompt",
promptPlaceholder: "Cosa deve fare l'agente a ogni esecuzione?",
schedule: "Pianificazione (espressione cron)",
schedulePlaceholder: "0 9 * * *",
deliverTo: "Consegna a",
scheduledJobs: "Attività pianificate",
noJobs: "Nessuna attività cron configurata. Creane una sopra.",
last: "Ultima",
next: "Prossima",
pause: "Pausa",
resume: "Riprendi",
triggerNow: "Esegui ora",
delivery: {
local: "Locale",
telegram: "Telegram",
discord: "Discord",
slack: "Slack",
email: "Email",
},
},
profiles: {
newProfile: "Nuovo profilo",
name: "Nome",
namePlaceholder: "es. coder, writer, ecc.",
nameRequired: "Il nome è obbligatorio",
nameRule:
"Solo lettere minuscole, cifre, _ e -; deve iniziare con una lettera o cifra; fino a 64 caratteri.",
invalidName: "Nome del profilo non valido",
cloneFromDefault: "Clona la configurazione dal profilo predefinito",
allProfiles: "Profili",
noProfiles: "Nessun profilo trovato.",
defaultBadge: "predefinito",
hasEnv: "env",
model: "Modello",
skills: "Competenze",
rename: "Rinomina",
editSoul: "Modifica SOUL.md",
soulSection: "SOUL.md (personalità / prompt di sistema)",
soulPlaceholder: "# Come dovrebbe comportarsi questo agente…",
saveSoul: "Salva SOUL",
soulSaved: "SOUL.md salvato",
openInTerminal: "Copia comando CLI",
commandCopied: "Copiato negli appunti",
copyFailed: "Impossibile copiare",
confirmDeleteTitle: "Eliminare il profilo?",
confirmDeleteMessage:
"Questa operazione elimina definitivamente il profilo '{name}' — configurazione, chiavi, memorie, sessioni, competenze, attività cron. Non può essere annullata.",
created: "Creato",
deleted: "Eliminato",
renamed: "Rinominato",
},
pluginsPage: {
contextEngineLabel: "Motore di contesto",
dashboardSlots: "Slot del dashboard",
disableRuntime: "Disabilita",
enableAfterInstall: "Abilita dopo l'installazione",
enableRuntime: "Abilita",
forceReinstall: "Forza reinstallazione (elimina prima la cartella esistente)",
headline:
"Scopri, installa, abilita e aggiorna i plugin Hermes (parità con `hermes plugins`).",
identifierLabel: "URL Git o owner/repo",
inactive: "inattivo",
installBtn: "Installa da Git",
installHeading: "Installa da GitHub / URL Git",
installHint: "Usa la forma breve owner/repo o un URL clone https:// o git@ completo.",
memoryProviderLabel: "Provider di memoria",
missingEnvWarn: "Imposta queste variabili in Chiavi prima di eseguire il plugin:",
noDashboardTab: "Nessuna scheda nel dashboard",
openTab: "Apri",
orphanHeading: "Estensioni solo dashboard (nessuna corrispondenza con plugin.yaml)",
pluginListHeading: "Plugin installati",
providerDefaults: "integrato / predefinito",
providersHeading: "Plugin provider runtime",
providersHint:
"Scrive memory.provider (vuoto = integrato) e context.engine in config.yaml. Effetto dalla prossima sessione.",
refreshDashboard: "Riscansiona estensioni dashboard",
removeConfirm: "Rimuovere questo plugin da ~/.hermes/plugins/?",
removeHint: "Solo i plugin installati dall'utente in ~/.hermes/plugins possono essere rimossi.",
rescanHeading: "Registro plugin SPA",
rescanHint: "Riscansiona dopo aver aggiunto file su disco affinché la barra laterale rilevi i nuovi manifest.",
runtimeHeading: "Runtime gateway (plugin YAML)",
saveProviders: "Salva impostazioni provider",
savedProviders: "Impostazioni provider salvate.",
sourceBadge: "Origine",
authRequired: "Autenticazione richiesta",
authRequiredHint: "Esegui questo comando per autenticarti:",
updateGit: "Git pull",
versionBadge: "Versione",
showInSidebar: "Mostra nella barra laterale",
hideFromSidebar: "Nascondi dalla barra laterale",
},
skills: {
title: "Competenze",
searchPlaceholder: "Cerca competenze e toolset...",
enabledOf: "{enabled}/{total} abilitati",
all: "Tutti",
categories: "Categorie",
filters: "Filtri",
noSkills: "Nessuna competenza trovata. Le competenze vengono caricate da ~/.hermes/skills/",
noSkillsMatch: "Nessuna competenza corrisponde alla ricerca o al filtro.",
skillCount: "{count} competenz{s}",
resultCount: "{count} risultat{s}",
noDescription: "Nessuna descrizione disponibile.",
toolsets: "Toolset",
toolsetLabel: "Toolset {name}",
noToolsetsMatch: "Nessun toolset corrisponde alla ricerca.",
setupNeeded: "Configurazione necessaria",
disabledForCli: "Disabilitato per CLI",
more: "+{count} in più",
},
config: {
configPath: "~/.hermes/config.yaml",
filters: "Filtri",
sections: "Sezioni",
exportConfig: "Esporta configurazione come JSON",
importConfig: "Importa configurazione da JSON",
resetDefaults: "Ripristina predefiniti",
resetScopeTooltip: "Ripristina {scope} ai valori predefiniti",
confirmResetScope: "Ripristinare tutte le impostazioni di {scope} ai valori predefiniti? Questa operazione aggiorna solo il modulo — le modifiche non vengono scritte in config.yaml finché non premi Salva.",
resetScopeToast: "{scope} ripristinato ai valori predefiniti — controlla e Salva per rendere persistente",
rawYaml: "Configurazione YAML grezza",
searchResults: "Risultati della ricerca",
fields: "camp{s}",
noFieldsMatch: 'Nessun campo corrisponde a "{query}"',
configSaved: "Configurazione salvata",
yamlConfigSaved: "Configurazione YAML salvata",
failedToSave: "Salvataggio non riuscito",
failedToSaveYaml: "Salvataggio YAML non riuscito",
failedToLoadRaw: "Caricamento configurazione grezza non riuscito",
configImported: "Configurazione importata — controlla e salva",
invalidJson: "File JSON non valido",
categories: {
general: "Generale",
agent: "Agente",
terminal: "Terminale",
display: "Visualizzazione",
delegation: "Delega",
memory: "Memoria",
compression: "Compressione",
security: "Sicurezza",
browser: "Browser",
voice: "Voce",
tts: "Sintesi vocale",
stt: "Riconoscimento vocale",
logging: "Log",
discord: "Discord",
auxiliary: "Ausiliario",
},
},
env: {
changesNote: "Le modifiche vengono salvate immediatamente su disco. Le sessioni attive rilevano automaticamente le nuove chiavi.",
confirmClearMessage:
"Il valore memorizzato per questa variabile sarà rimosso dal tuo file .env. Non può essere annullato dall'interfaccia.",
confirmClearTitle: "Cancellare questa chiave?",
description: "Gestisci chiavi API e segreti memorizzati in",
hideAdvanced: "Nascondi avanzate",
showAdvanced: "Mostra avanzate",
llmProviders: "Provider LLM",
providersConfigured: "{configured} di {total} provider configurati",
getKey: "Ottieni chiave",
notConfigured: "{count} non configurat{s}",
notSet: "Non impostato",
keysCount: "{count} chiav{s}",
enterValue: "Inserisci valore...",
replaceCurrentValue: "Sostituisci valore corrente ({preview})",
showValue: "Mostra valore reale",
hideValue: "Nascondi valore",
},
oauth: {
title: "Accessi provider (OAuth)",
providerLogins: "Accessi provider (OAuth)",
description: "{connected} di {total} provider OAuth connessi. I flussi di accesso vengono attualmente eseguiti tramite la CLI; clicca Copia comando e incolla in un terminale per configurare.",
connected: "Connesso",
expired: "Scaduto",
notConnected: "Non connesso. Esegui {command} in un terminale.",
runInTerminal: "in un terminale.",
noProviders: "Nessun provider compatibile con OAuth rilevato.",
login: "Accedi",
disconnect: "Disconnetti",
managedExternally: "Gestito esternamente",
copied: "Copiato ✓",
cli: "CLI",
copyCliCommand: "Copia comando CLI (per uso esterno / fallback)",
connect: "Connetti",
sessionExpires: "La sessione scade tra {time}",
initiatingLogin: "Avvio del flusso di accesso…",
exchangingCode: "Scambio del codice per i token…",
connectedClosing: "Connesso! Chiusura…",
loginFailed: "Accesso non riuscito.",
sessionExpired: "Sessione scaduta. Clicca Riprova per iniziare un nuovo accesso.",
reOpenAuth: "Riapri pagina di autenticazione",
reOpenVerification: "Riapri pagina di verifica",
submitCode: "Invia codice",
pasteCode: "Incolla codice di autorizzazione (con suffisso #state va bene)",
waitingAuth: "In attesa che tu autorizzi nel browser…",
enterCodePrompt: "È stata aperta una nuova scheda. Inserisci questo codice se richiesto:",
pkceStep1: "È stata aperta una nuova scheda su claude.ai. Accedi e clicca Autorizza.",
pkceStep2: "Copia il codice di autorizzazione mostrato dopo l'autorizzazione.",
pkceStep3: "Incollalo qui sotto e invia.",
flowLabels: {
pkce: "Accesso browser (PKCE)",
device_code: "Codice dispositivo",
external: "CLI esterna",
},
expiresIn: "scade tra {time}",
},
language: {
switchTo: "Passa all'inglese",
},
theme: {
title: "Tema",
switchTheme: "Cambia tema",
},
achievements: {
hero: {
kicker: "Agentic Gamerscore",
title: "Hermes Achievements",
subtitle:
"Badge Hermes da collezione, ottenuti dalla cronologia reale delle sessioni. Gli achievement noti non completati vengono mostrati come Scoperti; gli achievement segreti restano nascosti finché non compare il primo comportamento corrispondente.",
scan_subtitle:
"Scansione della cronologia delle sessioni Hermes in corso. La prima scansione può richiedere 510 secondi su cronologie ampie.",
},
actions: {
rescan: "Riscansiona",
},
stats: {
unlocked: "Sbloccati",
unlocked_hint: "badge ottenuti",
discovered: "Scoperti",
discovered_hint: "noti, non ancora ottenuti",
secrets: "Segreti",
secrets_hint: "nascosti fino al primo segnale",
highest_tier: "Livello più alto",
highest_tier_hint: "Copper → Silver → Gold → Diamond → Olympian",
latest: "Più recente",
latest_hint_empty: "usa Hermes di più",
none_yet: "Nessuno ancora",
},
state: {
unlocked: "Sbloccato",
discovered: "Scoperto",
secret: "Segreto",
},
tier: {
target: "Obiettivo {tier}",
hidden: "Nascosto",
complete: "Completato",
objective: "Obiettivo",
},
progress: {
hidden: "nascosto",
},
scan: {
building_headline: "Costruzione del profilo achievement…",
building_detail:
"Lettura di sessioni, chiamate agli strumenti, metadati del modello e stato di sblocco.",
starting_headline: "Avvio della scansione achievement…",
progress_detail:
"Scansionate {scanned} di {total} sessioni · {pct}%. I badge si sbloccano man mano che viene elaborata altra cronologia.",
idle_detail:
"Lettura di sessioni, chiamate agli strumenti, metadati del modello e stato di sblocco. I badge appaiono qui non appena vengono sbloccati.",
},
guide: {
tiers_header: "Livelli",
secret_header: "Achievement segreti",
secret_body:
"I segreti nascondono il loro trigger esatto. Quando Hermes rileva un segnale correlato, la carta passa a Scoperto e mostra il requisito.",
scan_status_header: "Stato della scansione",
scan_status_body:
"Hermes sta scansionando la cronologia locale una sola volta, poi le carte appariranno automaticamente. Non è bloccato nulla se richiede qualche secondo.",
what_scanned_header: "Cosa viene scansionato",
what_scanned_body:
"Sessioni, chiamate agli strumenti, metadati del modello, errori, achievement e stato di sblocco locale.",
},
card: {
share_title: "Condividi questo achievement",
share_label: "Condividi {name}",
share_text: "Condividi",
how_to_reveal: "Come rivelarlo",
what_counts: "Cosa conta",
evidence_label: "Prova",
evidence_session_fallback: "sessione",
no_evidence: "Nessuna prova ancora",
},
latest: {
header: "Sblocchi recenti",
},
empty: {
no_secrets_header: "Nessun segreto nascosto rimasto in questa scansione.",
no_secrets_body:
"Indizio: i segreti di solito partono da fallimenti inusuali o pattern da utente esperto — conflitti di porte, muri di permessi, variabili d'ambiente mancanti, errori YAML, collisioni Docker, uso di rollback/checkpoint, cache hit o piccole correzioni dopo molto testo rosso.",
},
filters: {
all_categories: "Tutti",
visibility_all: "tutti",
visibility_unlocked: "sbloccati",
visibility_discovered: "scoperti",
visibility_secret: "segreti",
},
share: {
dialog_label: "Condividi achievement",
header: "Condividi: {name}",
close: "Chiudi",
rendering: "Rendering…",
card_alt: "Carta di condivisione {name}",
error_generic: "Qualcosa è andato storto.",
x_title: "Apre X con un post precompilato",
x_button: "Condividi su X",
copy_title: "Copia l'immagine per incollarla nel tuo post",
copy_button: "Copia immagine",
copied: "Copiato ✓",
download_button: "Scarica PNG",
hint:
"Condividi su X apre un post precompilato in una nuova scheda. Clicca prima su Copia immagine se vuoi allegare il badge 1200×630 — X ti permette di incollarlo direttamente nell'editor del tweet. Scarica PNG salva il file per l'uso ovunque.",
clipboard_unsupported:
"La copia delle immagini negli appunti non è supportata in questo browser — usa Scarica invece.",
tweet_text: "Just unlocked {tier_part}\"{name}\" in Hermes Agent ☤",
},
},
kanban: {
loading: "Caricamento bacheca Kanban…",
loadFailed: "Caricamento della bacheca Kanban non riuscito: ",
loadFailedHint:
"Il backend crea automaticamente kanban.db alla prima lettura. Se il problema persiste, controlla i log del dashboard.",
board: "Bacheca",
newBoard: "+ Nuova bacheca",
newBoardTitle: "Nuova bacheca",
newBoardDescription:
"Le bacheche ti permettono di separare flussi di lavoro non correlati — una per progetto, repository o dominio. I worker su una bacheca non vedono mai le attività di un'altra.",
slug: "Slug",
slugHint: "— minuscolo, trattini, ad es. atm10-server",
displayName: "Nome visualizzato",
displayNameHint: "(facoltativo)",
description: "Descrizione",
descriptionHint: "(facoltativo)",
icon: "Icona",
iconHint: "(un singolo carattere o emoji)",
switchAfterCreate: "Passa a questa bacheca dopo la creazione",
cancel: "Annulla",
creating: "Creazione…",
createBoard: "Crea bacheca",
search: "Cerca",
filterCards: "Filtra schede…",
tenant: "Tenant",
allTenants: "Tutti i tenant",
assignee: "Assegnatario",
allProfiles: "Tutti i profili",
showArchived: "Mostra archiviati",
lanesByProfile: "Corsie per profilo",
nudgeDispatcher: "Sollecita dispatcher",
refresh: "Aggiorna",
selected: "selezionato/i",
complete: "Completa",
archive: "Archivia",
apply: "Applica",
clear: "Cancella",
createTask: "Crea attività in questa colonna",
noTasks: "— nessuna attività —",
unassigned: "non assegnato",
untitled: "(senza titolo)",
loadingDetail: "Caricamento…",
addComment: "Aggiungi un commento… (Enter per inviare)",
comment: "Commento",
status: "Stato",
workspace: "Workspace",
skills: "Competenze",
createdBy: "Creato da",
result: "Result",
comments: "Commenti",
events: "Eventi",
runHistory: "Cronologia esecuzioni",
workerLog: "Log del worker",
loadingLog: "Caricamento log…",
noWorkerLog:
"— nessun log del worker ancora (l'attività non è stata avviata o il log è stato ruotato) —",
noDescription: "— nessuna descrizione —",
noComments: "— nessun commento —",
edit: "modifica",
save: "Salva",
dependencies: "Dipendenze",
parents: "Padri:",
children: "Figli:",
none: "nessuno",
addParent: "— aggiungi padre —",
addChild: "— aggiungi figlio —",
removeDependency: "Rimuovi dipendenza",
block: "Blocca",
unblock: "Sblocca",
notifyHomeChannels: "Notifica i canali home",
diagnostics: "Diagnostica",
hide: "Nascondi",
show: "Mostra",
attention: "Attenzione",
tasksNeedAttention: "attività richiedono attenzione",
taskNeedsAttention: "1 attività richiede attenzione",
diagnostic: "diagnostica",
open: "Apri",
close: "Chiudi (Esc)",
reassignTo: "Riassegna a:",
copied: "Copiato",
copyCommand: "Copia comando negli appunti",
reclaim: "Recupera",
reassign: "Riassegna",
renderingError: "La scheda Kanban ha avuto un errore di rendering",
reloadView: "Ricarica vista",
wsAuthFailed:
"Autenticazione WebSocket non riuscita — ricarica la pagina per aggiornare il token di sessione.",
markDone: "Contrassegnare {n} attività come completate?",
markArchived: "Archiviare {n} attività?",
warning: "Avviso",
phantomIds: "ID fantasma:",
active: "attivo",
ended: "terminato",
noProfile: "(nessun profilo)",
showAllAttempts: "Mostra tutti i tentativi",
sendingUpdates: "Invio aggiornamenti a",
sendNotifications: "Invia notifiche di completed / blocked / gave_up a",
archiveBoardConfirm:
"Archiviare la bacheca '{name}'? Verrà spostata in boards/_archived/ in modo da poterla recuperare in seguito. Le attività di questa bacheca non appariranno più da nessuna parte nell'UI.",
archiveBoardTitle: "Archivia questa bacheca",
boardSwitcherHint: "Le bacheche ti permettono di separare flussi di lavoro non correlati",
taskCreatedWarning: "Attività creata, ma: ",
moveFailed: "Spostamento non riuscito: ",
bulkFailed: "Massivo: ",
completionBlockedHallucination: "⚠ Completamento bloccato — ID schede fantasma",
suspectedHallucinatedReferences: "⚠ Il testo ha fatto riferimento a ID schede fantasma",
pickProfileFirst: "Scegli prima un profilo.",
unblockedMessage: "Sbloccato {id}. L'attività è pronta per il prossimo tick.",
unblockFailed: "Sblocco non riuscito: ",
reclaimedMessage: "Recuperato {id}. L'attività è di nuovo pronta.",
reclaimFailed: "Recupero non riuscito: ",
reassignedMessage: "Riassegnato {id} a {profile}.",
reassignFailed: "Riassegnazione non riuscita: ",
selectForBulk: "Seleziona per azioni massive",
clickToEdit: "Clicca per modificare",
clickToEditAssignee: "Clicca per modificare l'assegnatario",
emptyAssignee: "(vuoto = rimuovi assegnazione)",
columnLabels: {
triage: "Triage",
todo: "Da fare",
ready: "Pronto",
running: "In corso",
blocked: "Bloccato",
done: "Fatto",
archived: "Archiviato",
},
columnHelp: {
triage: "Idee grezze — un specifier elaborerà la specifica",
todo: "In attesa di dipendenze o non assegnato",
ready: "Assegnato e in attesa di un tick del dispatcher",
running: "Preso in carico da un worker — in esecuzione",
blocked: "Il worker ha richiesto input umano",
done: "Completato",
archived: "Archiviato",
},
confirmDone:
"Contrassegnare questa attività come completata? La presa in carico del worker viene rilasciata e i figli dipendenti diventano pronti.",
confirmArchive:
"Archiviare questa attività? Sparirà dalla vista predefinita della bacheca.",
confirmBlocked:
"Contrassegnare questa attività come bloccata? La presa in carico del worker viene rilasciata.",
completionSummary:
"Riepilogo di completamento per {label}. Memorizzato come result dell'attività.",
completionSummaryRequired:
"Il riepilogo di completamento è obbligatorio prima di contrassegnare un'attività come completata.",
triagePlaceholder: "Idea approssimativa — l'IA la specificherà…",
taskTitlePlaceholder: "Titolo della nuova attività…",
specifier: "specifier",
assigneePlaceholder: "assegnatario",
priority: "Priorità",
skillsPlaceholder:
"competenze (facoltative, separate da virgole): translation, github-code-review",
noParent: "— nessun padre —",
workspacePathDir: "percorso del workspace (richiesto, ad es. ~/projects/my-app)",
workspacePathOptional:
"percorso del workspace (facoltativo, derivato dall'assegnatario se vuoto)",
logTruncated: "(mostrando ultimi 100 KB — log completo in ",
logAt: ")",
},
};

696
web/src/i18n/ja.ts Normal file
View file

@ -0,0 +1,696 @@
import type { Translations } from "./types";
export const ja: 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:
"このプラグインのスクリプトを読み込めませんでした。Network タブ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: "Cron",
documentation: "ドキュメント",
keys: "キー",
logs: "ログ",
models: "モデル",
profiles: "プロファイル : マルチエージェント",
plugins: "プラグイン",
sessions: "セッション",
skills: "スキル",
},
modelToolsSheetSubtitle: "とツール",
modelToolsSheetTitle: "モデル",
navigation: "ナビゲーション",
openDocumentation: "ドキュメントを新しいタブで開く",
openNavigation: "ナビゲーションを開く",
pluginNavSection: "プラグイン",
sessionsActiveCount: "{count} 件アクティブ",
statusOverview: "ステータス概要",
system: "システム",
webUi: "Web UI",
},
status: {
actionFailed: "アクションが失敗しました",
actionFinished: "完了",
actions: "アクション",
agent: "エージェント",
activeSessions: "アクティブなセッション",
connected: "接続済み",
connectedPlatforms: "接続済みプラットフォーム",
disconnected: "切断",
error: "エラー",
failed: "失敗",
gateway: "ゲートウェイ",
gatewayFailedToStart: "ゲートウェイの起動に失敗しました",
lastUpdate: "最終更新",
noneRunning: "なし",
notRunning: "実行されていません",
pid: "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: "合計トークン数",
totalSessions: "合計セッション数",
apiCalls: "API 呼び出し",
dailyTokenUsage: "日次トークン使用量",
dailyBreakdown: "日次内訳",
perModelBreakdown: "モデル別内訳",
topSkills: "トップスキル",
skill: "スキル",
loads: "エージェント読み込み",
edits: "エージェント管理",
lastUsed: "最終使用",
input: "入力",
output: "出力",
total: "合計",
noUsageData: "この期間の使用データはありません",
startSession: "セッションを開始すると分析がここに表示されます",
date: "日付",
model: "モデル",
tokens: "トークン",
perDayAvg: "/日 平均",
acrossModels: "{count} モデル全体",
inOut: "{input} 入力 / {output} 出力",
},
models: {
modelsUsed: "使用モデル",
estimatedCost: "推定コスト",
tokens: "トークン",
sessions: "セッション",
avgPerSession: "平均/セッション",
apiCalls: "API 呼び出し",
toolCalls: "ツール呼び出し",
noModelsData: "この期間のモデル使用データはありません",
startSession: "セッションを開始するとモデルデータがここに表示されます",
},
logs: {
title: "ログ",
autoRefresh: "自動更新",
file: "ファイル",
level: "レベル",
component: "コンポーネント",
lines: "行数",
noLogLines: "ログ行が見つかりません",
},
cron: {
confirmDeleteMessage:
"ジョブをスケジュールから削除します。この操作は取り消せません。",
confirmDeleteTitle: "スケジュールされたジョブを削除しますか?",
newJob: "新しい Cron ジョブ",
nameOptional: "名前 (任意)",
namePlaceholder: "例: 日次サマリー",
prompt: "プロンプト",
promptPlaceholder: "実行ごとにエージェントが行う内容は?",
schedule: "スケジュール (cron 式)",
schedulePlaceholder: "0 9 * * *",
deliverTo: "配信先",
scheduledJobs: "スケジュール済みジョブ",
noJobs: "Cron ジョブが設定されていません。上で作成してください。",
last: "前回",
next: "次回",
pause: "一時停止",
resume: "再開",
triggerNow: "今すぐ実行",
delivery: {
local: "ローカル",
telegram: "Telegram",
discord: "Discord",
slack: "Slack",
email: "Email",
},
},
profiles: {
newProfile: "新しいプロファイル",
name: "名前",
namePlaceholder: "例: coder, writer など",
nameRequired: "名前は必須です",
nameRule:
"小文字、数字、_ および - のみ使用可能。最初は文字または数字で始める必要があります。最大 64 文字。",
invalidName: "無効なプロファイル名",
cloneFromDefault: "デフォルトプロファイルから設定を複製",
allProfiles: "プロファイル",
noProfiles: "プロファイルが見つかりません。",
defaultBadge: "デフォルト",
hasEnv: "env",
model: "モデル",
skills: "スキル",
rename: "名前を変更",
editSoul: "SOUL.md を編集",
soulSection: "SOUL.md (パーソナリティ / システムプロンプト)",
soulPlaceholder: "# このエージェントの振る舞い…",
saveSoul: "SOUL を保存",
soulSaved: "SOUL.md を保存しました",
openInTerminal: "CLI コマンドをコピー",
commandCopied: "クリップボードにコピーしました",
copyFailed: "コピーできませんでした",
confirmDeleteTitle: "プロファイルを削除しますか?",
confirmDeleteMessage:
"プロファイル '{name}' を完全に削除します — 設定、キー、メモリ、セッション、スキル、cron ジョブ。この操作は取り消せません。",
created: "作成しました",
deleted: "削除しました",
renamed: "名前を変更しました",
},
pluginsPage: {
contextEngineLabel: "コンテキストエンジン",
dashboardSlots: "ダッシュボードスロット",
disableRuntime: "無効化",
enableAfterInstall: "インストール後に有効化",
enableRuntime: "有効化",
forceReinstall: "強制再インストール (既存のフォルダを先に削除)",
headline:
"Hermes プラグインを発見、インストール、有効化、更新します (`hermes plugins` 相当)。",
identifierLabel: "Git URL または owner/repo",
inactive: "非アクティブ",
installBtn: "Git からインストール",
installHeading: "GitHub / Git URL からインストール",
installHint: "owner/repo の短縮形、または完全な https:// もしくは git@ クローン URL を使用してください。",
memoryProviderLabel: "メモリプロバイダー",
missingEnvWarn: "プラグインを実行する前にこれらをキーに設定してください:",
noDashboardTab: "ダッシュボードタブなし",
openTab: "開く",
orphanHeading: "ダッシュボード専用拡張 (該当する agent plugin.yaml なし)",
pluginListHeading: "インストール済みプラグイン",
providerDefaults: "組み込み / デフォルト",
providersHeading: "ランタイムプロバイダープラグイン",
providersHint:
"memory.provider (空 = 組み込み) と context.engine を config.yaml に書き込みます。次のセッションで有効になります。",
refreshDashboard: "ダッシュボード拡張を再スキャン",
removeConfirm: "このプラグインを ~/.hermes/plugins/ から削除しますか?",
removeHint: "削除できるのは ~/.hermes/plugins 配下のユーザーがインストールしたプラグインのみです。",
rescanHeading: "SPA プラグインレジストリ",
rescanHint: "ディスクにファイルを追加した後に再スキャンすると、ダッシュボードのサイドバーが新しいマニフェストを認識します。",
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} スキル{s}",
resultCount: "{count} 件の結果{s}",
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: "フィールド{s}",
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 ファイルから削除されます。この操作は UI から取り消せません。",
confirmClearTitle: "このキーをクリアしますか?",
description: "API キーとシークレットを管理します。保存先:",
hideAdvanced: "詳細設定を隠す",
showAdvanced: "詳細設定を表示",
llmProviders: "LLM プロバイダー",
providersConfigured: "{configured} / {total} プロバイダーが設定済み",
getKey: "キーを取得",
notConfigured: "{count} 件未設定",
notSet: "未設定",
keysCount: "{count} キー{s}",
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 への新しいタブが開きました。サインインして「Authorize」をクリックしてください。",
pkceStep2: "認可後に表示される認可コードをコピーしてください。",
pkceStep3: "下に貼り付けて送信してください。",
flowLabels: {
pkce: "ブラウザログイン (PKCE)",
device_code: "デバイスコード",
external: "外部 CLI",
},
expiresIn: "{time} 後に期限切れ",
},
language: {
switchTo: "英語に切り替え",
},
theme: {
title: "テーマ",
switchTheme: "テーマを切り替え",
},
achievements: {
hero: {
kicker: "Agentic Gamerscore",
title: "Hermes Achievements",
subtitle:
"実際のセッション履歴から獲得できる Hermes のコレクタブル バッジです。既知の未達成の実績は「Discovered」として表示され、Secret 実績は最初の該当する挙動が検出されるまで非表示のままです。",
scan_subtitle:
"Hermes のセッション履歴をスキャンしています。履歴が大きい場合、初回スキャンには 510 秒かかることがあります。",
},
actions: {
rescan: "再スキャン",
},
stats: {
unlocked: "解除済み",
unlocked_hint: "獲得したバッジ",
discovered: "発見済み",
discovered_hint: "判明していますが未獲得",
secrets: "シークレット",
secrets_hint: "最初のシグナルまで非表示",
highest_tier: "最高ティア",
highest_tier_hint: "Copper → Silver → Gold → Diamond → Olympian",
latest: "最新",
latest_hint_empty: "Hermes をもっと使ってみてください",
none_yet: "まだありません",
},
state: {
unlocked: "解除済み",
discovered: "発見済み",
secret: "シークレット",
},
tier: {
target: "目標 {tier}",
hidden: "非表示",
complete: "達成",
objective: "目的",
},
progress: {
hidden: "非表示",
},
scan: {
building_headline: "実績プロファイルを構築中…",
building_detail:
"セッション、ツール呼び出し、モデルのメタデータ、解除状態を読み込んでいます。",
starting_headline: "実績スキャンを開始しています…",
progress_detail:
"{total} 件中 {scanned} 件のセッションをスキャンしました · {pct}%。履歴が読み込まれるにつれてバッジが解除されます。",
idle_detail:
"セッション、ツール呼び出し、モデルのメタデータ、解除状態を読み込んでいます。バッジは解除され次第ここに表示されます。",
},
guide: {
tiers_header: "ティア",
secret_header: "シークレット実績",
secret_body:
"シークレットはトリガー条件を隠しています。Hermes が関連するシグナルを検出すると、カードは「Discovered」になり、要件が表示されます。",
scan_status_header: "スキャン状況",
scan_status_body:
"Hermes はローカル履歴を一度スキャンし、その後カードが自動的に表示されます。数秒かかってもスタックしているわけではありません。",
what_scanned_header: "スキャン対象",
what_scanned_body:
"セッション、ツール呼び出し、モデルのメタデータ、エラー、実績、ローカルの解除状態。",
},
card: {
share_title: "この実績を共有",
share_label: "{name} を共有",
share_text: "共有",
how_to_reveal: "解除する方法",
what_counts: "対象となる条件",
evidence_label: "エビデンス",
evidence_session_fallback: "セッション",
no_evidence: "エビデンスはまだありません",
},
latest: {
header: "最近の解除",
},
empty: {
no_secrets_header: "このスキャンに残っている隠しシークレットはありません。",
no_secrets_body:
"ヒント: シークレットは通常、想定外の失敗やパワーユーザー的なパターンから生まれます — ポート競合、権限の壁、環境変数の不足、YAML のミス、Docker の衝突、ロールバックやチェックポイントの利用、キャッシュヒット、あるいは大量の赤いエラーの後の小さな修正など。",
},
filters: {
all_categories: "すべて",
visibility_all: "すべて",
visibility_unlocked: "解除済み",
visibility_discovered: "発見済み",
visibility_secret: "シークレット",
},
share: {
dialog_label: "実績を共有",
header: "共有: {name}",
close: "閉じる",
rendering: "描画中…",
card_alt: "{name} の共有カード",
error_generic: "問題が発生しました。",
x_title: "事前入力された投稿で X を開きます",
x_button: "X で共有",
copy_title: "投稿に貼り付けるために画像をコピーします",
copy_button: "画像をコピー",
copied: "コピーしました ✓",
download_button: "PNG をダウンロード",
hint:
"「X で共有」は事前入力された投稿を新しいタブで開きます。1200×630 のバッジを添付したい場合は、先に「画像をコピー」を押してください — X では投稿エディタに直接貼り付けられます。「PNG をダウンロード」はファイルとして保存し、どこでも使えるようにします。",
clipboard_unsupported:
"このブラウザではクリップボードへの画像コピーがサポートされていません — 代わりに「ダウンロード」をご利用ください。",
tweet_text: "Just unlocked {tier_part}\"{name}\" in Hermes Agent ☤",
},
},
kanban: {
loading: "Kanban ボードを読み込んでいます…",
loadFailed: "Kanban ボードの読み込みに失敗しました: ",
loadFailedHint:
"バックエンドは初回読み込み時に kanban.db を自動作成します。問題が続く場合は、ダッシュボードのログをご確認ください。",
board: "ボード",
newBoard: "+ 新しいボード",
newBoardTitle: "新しいボード",
newBoardDescription:
"ボードを使うと、関連のない作業の流れを分けられます — プロジェクト、リポジトリ、ドメインごとに 1 つずつ。あるボードのワーカーは、別のボードのタスクを見ることはありません。",
slug: "スラッグ",
slugHint: "— 小文字とハイフン、例: atm10-server",
displayName: "表示名",
displayNameHint: "(任意)",
description: "説明",
descriptionHint: "(任意)",
icon: "アイコン",
iconHint: "1 文字または絵文字)",
switchAfterCreate: "作成後にこのボードへ切り替える",
cancel: "キャンセル",
creating: "作成中…",
createBoard: "ボードを作成",
search: "検索",
filterCards: "カードを絞り込む…",
tenant: "テナント",
allTenants: "すべてのテナント",
assignee: "担当者",
allProfiles: "すべてのプロファイル",
showArchived: "アーカイブ済みを表示",
lanesByProfile: "プロファイル別レーン",
nudgeDispatcher: "ディスパッチャーを起動",
refresh: "更新",
selected: "選択中",
complete: "完了",
archive: "アーカイブ",
apply: "適用",
clear: "クリア",
createTask: "この列にタスクを作成",
noTasks: "— タスクはありません —",
unassigned: "未割り当て",
untitled: "(タイトルなし)",
loadingDetail: "読み込み中…",
addComment: "コメントを追加…Enter で送信)",
comment: "コメント",
status: "ステータス",
workspace: "ワークスペース",
skills: "スキル",
createdBy: "作成者",
result: "結果",
comments: "コメント",
events: "イベント",
runHistory: "実行履歴",
workerLog: "ワーカーログ",
loadingLog: "ログを読み込んでいます…",
noWorkerLog:
"— ワーカーログはまだありません(タスクが起動していないか、ログがローテーションされました)—",
noDescription: "— 説明はありません —",
noComments: "— コメントはありません —",
edit: "編集",
save: "保存",
dependencies: "依存関係",
parents: "親タスク:",
children: "子タスク:",
none: "なし",
addParent: "— 親タスクを追加 —",
addChild: "— 子タスクを追加 —",
removeDependency: "依存関係を削除",
block: "ブロック",
unblock: "ブロック解除",
notifyHomeChannels: "ホームチャンネルに通知する",
diagnostics: "診断情報",
hide: "非表示",
show: "表示",
attention: "注意",
tasksNeedAttention: "件のタスクが対応を必要としています",
taskNeedsAttention: "1 件のタスクが対応を必要としています",
diagnostic: "診断",
open: "開く",
close: "閉じる (Esc)",
reassignTo: "再割り当て先:",
copied: "コピーしました",
copyCommand: "コマンドをクリップボードにコピー",
reclaim: "回収",
reassign: "再割り当て",
renderingError: "Kanban タブで描画エラーが発生しました",
reloadView: "ビューを再読み込み",
wsAuthFailed:
"WebSocket 認証に失敗しました — ページを再読み込みしてセッショントークンを更新してください。",
markDone: "{n} 件のタスクを完了にしますか?",
markArchived: "{n} 件のタスクをアーカイブしますか?",
warning: "警告",
phantomIds: "ファントム ID:",
active: "実行中",
ended: "終了",
noProfile: "(プロファイルなし)",
showAllAttempts: "すべての試行を表示",
sendingUpdates: "更新の送信先: ",
sendNotifications: "完了 / ブロック / 諦めの通知の送信先",
archiveBoardConfirm:
"ボード「{name}」をアーカイブしますか?ボードは boards/_archived/ に移動され、後で復元できます。このボード上のタスクは UI のどこにも表示されなくなります。",
archiveBoardTitle: "このボードをアーカイブ",
boardSwitcherHint: "ボードを使うと、関連のない作業の流れを分けられます",
taskCreatedWarning: "タスクは作成されましたが: ",
moveFailed: "移動に失敗しました: ",
bulkFailed: "一括処理: ",
completionBlockedHallucination: "⚠ 完了がブロックされました — ファントムカード ID",
suspectedHallucinatedReferences: "⚠ 本文がファントムカード ID を参照しています",
pickProfileFirst: "まずプロファイルを選択してください。",
unblockedMessage: "{id} のブロックを解除しました。タスクは次のティックの準備ができています。",
unblockFailed: "ブロック解除に失敗しました: ",
reclaimedMessage: "{id} を回収しました。タスクは ready に戻りました。",
reclaimFailed: "回収に失敗しました: ",
reassignedMessage: "{id} を {profile} に再割り当てしました。",
reassignFailed: "再割り当てに失敗しました: ",
selectForBulk: "一括操作のために選択",
clickToEdit: "クリックして編集",
clickToEditAssignee: "クリックして担当者を編集",
emptyAssignee: "(空 = 割り当て解除)",
columnLabels: {
triage: "トリアージ",
todo: "ToDo",
ready: "準備完了",
running: "進行中",
blocked: "ブロック中",
done: "完了",
archived: "アーカイブ済み",
},
columnHelp: {
triage: "未整理のアイデア — スペシファイアが仕様を肉付けします",
todo: "依存関係の待機中、または未割り当て",
ready: "割り当て済み、ディスパッチャーのティック待ち",
running: "ワーカーが取得中 — 実行中",
blocked: "ワーカーが人間の入力を求めています",
done: "完了",
archived: "アーカイブ済み",
},
confirmDone:
"このタスクを完了にしますか?ワーカーの取得は解放され、依存している子タスクが ready になります。",
confirmArchive:
"このタスクをアーカイブしますか?既定のボードビューから消えます。",
confirmBlocked:
"このタスクをブロック中にしますか?ワーカーの取得は解放されます。",
completionSummary:
"{label} の完了サマリ。これはタスクの結果として保存されます。",
completionSummaryRequired:
"タスクを完了にする前に、完了サマリの入力が必要です。",
triagePlaceholder: "おおまかなアイデア — AI が仕様化します…",
taskTitlePlaceholder: "新しいタスクのタイトル…",
specifier: "スペシファイア",
assigneePlaceholder: "担当者",
priority: "優先度",
skillsPlaceholder:
"スキル(任意、カンマ区切り): translation, github-code-review",
noParent: "— 親タスクなし —",
workspacePathDir: "ワークスペースのパス(必須、例: ~/projects/my-app",
workspacePathOptional:
"ワークスペースのパス(任意、空の場合は担当者から導出)",
logTruncated: "(最後の 100 KB を表示中 — 完全なログは ",
logAt: "",
},
};

696
web/src/i18n/ko.ts Normal file
View file

@ -0,0 +1,696 @@
import type { Translations } from "./types";
export const ko: 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:
"이 플러그인의 스크립트를 로드할 수 없습니다. Network 탭(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: "Cron",
documentation: "문서",
keys: "키",
logs: "로그",
models: "모델",
profiles: "프로필: 멀티 에이전트",
plugins: "플러그인",
sessions: "세션",
skills: "스킬",
},
modelToolsSheetSubtitle: "및 도구",
modelToolsSheetTitle: "모델",
navigation: "내비게이션",
openDocumentation: "새 탭에서 문서 열기",
openNavigation: "내비게이션 열기",
pluginNavSection: "플러그인",
sessionsActiveCount: "{count}개 활성",
statusOverview: "상태 개요",
system: "시스템",
webUi: "Web UI",
},
status: {
actionFailed: "작업 실패",
actionFinished: "완료됨",
actions: "작업",
agent: "에이전트",
activeSessions: "활성 세션",
connected: "연결됨",
connectedPlatforms: "연결된 플랫폼",
disconnected: "연결 끊김",
error: "오류",
failed: "실패",
gateway: "게이트웨이",
gatewayFailedToStart: "게이트웨이 시작 실패",
lastUpdate: "마지막 업데이트",
noneRunning: "없음",
notRunning: "실행 중이 아님",
pid: "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: "총 토큰",
totalSessions: "총 세션",
apiCalls: "API 호출",
dailyTokenUsage: "일일 토큰 사용량",
dailyBreakdown: "일별 내역",
perModelBreakdown: "모델별 내역",
topSkills: "주요 스킬",
skill: "스킬",
loads: "에이전트 로드됨",
edits: "에이전트 관리",
lastUsed: "마지막 사용",
input: "입력",
output: "출력",
total: "합계",
noUsageData: "이 기간에 대한 사용 데이터가 없습니다",
startSession: "세션을 시작하면 여기에 분석이 표시됩니다",
date: "날짜",
model: "모델",
tokens: "토큰",
perDayAvg: "/일 평균",
acrossModels: "{count}개 모델 전반",
inOut: "입력 {input} / 출력 {output}",
},
models: {
modelsUsed: "사용된 모델",
estimatedCost: "예상 비용",
tokens: "토큰",
sessions: "세션",
avgPerSession: "세션당 평균",
apiCalls: "API 호출",
toolCalls: "도구 호출",
noModelsData: "이 기간에 대한 모델 사용 데이터가 없습니다",
startSession: "세션을 시작하면 여기에 모델 데이터가 표시됩니다",
},
logs: {
title: "로그",
autoRefresh: "자동 새로고침",
file: "파일",
level: "레벨",
component: "구성 요소",
lines: "줄 수",
noLogLines: "로그 줄을 찾을 수 없습니다",
},
cron: {
confirmDeleteMessage:
"이 작업은 일정에서 작업을 제거합니다. 되돌릴 수 없습니다.",
confirmDeleteTitle: "예약된 작업을 삭제하시겠습니까?",
newJob: "새 Cron 작업",
nameOptional: "이름 (선택 사항)",
namePlaceholder: "예: 일일 요약",
prompt: "프롬프트",
promptPlaceholder: "에이전트가 매 실행 시 무엇을 해야 합니까?",
schedule: "스케줄 (cron 표현식)",
schedulePlaceholder: "0 9 * * *",
deliverTo: "전달 대상",
scheduledJobs: "예약된 작업",
noJobs: "구성된 cron 작업이 없습니다. 위에서 하나 만드세요.",
last: "마지막",
next: "다음",
pause: "일시 정지",
resume: "재개",
triggerNow: "지금 실행",
delivery: {
local: "로컬",
telegram: "Telegram",
discord: "Discord",
slack: "Slack",
email: "Email",
},
},
profiles: {
newProfile: "새 프로필",
name: "이름",
namePlaceholder: "예: coder, writer 등.",
nameRequired: "이름은 필수입니다",
nameRule:
"소문자, 숫자, _ 및 - 만 사용 가능합니다. 문자나 숫자로 시작해야 하며 최대 64자입니다.",
invalidName: "잘못된 프로필 이름입니다",
cloneFromDefault: "기본 프로필에서 설정 복제",
allProfiles: "프로필",
noProfiles: "프로필을 찾을 수 없습니다.",
defaultBadge: "기본",
hasEnv: "env",
model: "모델",
skills: "스킬",
rename: "이름 변경",
editSoul: "SOUL.md 편집",
soulSection: "SOUL.md (개성 / 시스템 프롬프트)",
soulPlaceholder: "# 이 에이전트가 어떻게 동작해야 하는지…",
saveSoul: "SOUL 저장",
soulSaved: "SOUL.md가 저장되었습니다",
openInTerminal: "CLI 명령 복사",
commandCopied: "클립보드에 복사되었습니다",
copyFailed: "복사할 수 없습니다",
confirmDeleteTitle: "프로필을 삭제하시겠습니까?",
confirmDeleteMessage:
"이 작업은 '{name}' 프로필 — 설정, 키, 메모리, 세션, 스킬, cron 작업 — 을 영구적으로 삭제합니다. 되돌릴 수 없습니다.",
created: "생성됨",
deleted: "삭제됨",
renamed: "이름 변경됨",
},
pluginsPage: {
contextEngineLabel: "컨텍스트 엔진",
dashboardSlots: "대시보드 슬롯",
disableRuntime: "비활성화",
enableAfterInstall: "설치 후 활성화",
enableRuntime: "활성화",
forceReinstall: "강제 재설치 (기존 폴더를 먼저 삭제)",
headline:
"Hermes 플러그인을 검색, 설치, 활성화 및 업데이트합니다 (`hermes plugins` 동등).",
identifierLabel: "Git URL 또는 owner/repo",
inactive: "비활성",
installBtn: "Git에서 설치",
installHeading: "GitHub / Git URL에서 설치",
installHint: "owner/repo 약어 또는 전체 https:// 또는 git@ 클론 URL을 사용하세요.",
memoryProviderLabel: "메모리 제공자",
missingEnvWarn: "플러그인을 실행하기 전에 Keys에서 다음 항목을 설정하세요:",
noDashboardTab: "대시보드 탭 없음",
openTab: "열기",
orphanHeading: "대시보드 전용 확장 (일치하는 agent plugin.yaml 없음)",
pluginListHeading: "설치된 플러그인",
providerDefaults: "내장 / 기본",
providersHeading: "런타임 제공자 플러그인",
providersHint:
"memory.provider (비어 있으면 = 내장)와 context.engine을 config.yaml에 기록합니다. 다음 세션부터 적용됩니다.",
refreshDashboard: "대시보드 확장 재스캔",
removeConfirm: "~/.hermes/plugins/에서 이 플러그인을 제거하시겠습니까?",
removeHint: "~/.hermes/plugins 아래에 사용자가 설치한 플러그인만 제거할 수 있습니다.",
rescanHeading: "SPA 플러그인 레지스트리",
rescanHint: "디스크에 파일을 추가한 후 재스캔하여 대시보드 사이드바가 새 매니페스트를 인식하도록 합니다.",
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 파일에서 제거됩니다. UI에서는 이 작업을 되돌릴 수 없습니다.",
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로 새 탭이 열렸습니다. 로그인하고 Authorize를 클릭하세요.",
pkceStep2: "인증 후 표시된 인증 코드를 복사하세요.",
pkceStep3: "아래에 붙여넣고 제출하세요.",
flowLabels: {
pkce: "브라우저 로그인 (PKCE)",
device_code: "디바이스 코드",
external: "외부 CLI",
},
expiresIn: "{time} 후 만료",
},
language: {
switchTo: "영어로 전환",
},
theme: {
title: "테마",
switchTheme: "테마 전환",
},
achievements: {
hero: {
kicker: "Agentic Gamerscore",
title: "Hermes Achievements",
subtitle:
"실제 세션 기록에서 획득하는 Hermes 컬렉터블 배지입니다. 알려져 있지만 아직 달성되지 않은 업적은 Discovered로 표시되며, Secret 업적은 일치하는 동작이 처음 나타날 때까지 숨겨집니다.",
scan_subtitle:
"Hermes 세션 기록을 스캔하고 있습니다. 기록이 많으면 첫 스캔에 5~10초가 걸릴 수 있습니다.",
},
actions: {
rescan: "다시 스캔",
},
stats: {
unlocked: "해제됨",
unlocked_hint: "획득한 배지",
discovered: "발견됨",
discovered_hint: "알려져 있으나 아직 획득하지 못함",
secrets: "시크릿",
secrets_hint: "첫 신호가 있을 때까지 숨겨짐",
highest_tier: "최고 등급",
highest_tier_hint: "Copper → Silver → Gold → Diamond → Olympian",
latest: "최근",
latest_hint_empty: "Hermes를 더 사용해 보세요",
none_yet: "아직 없음",
},
state: {
unlocked: "해제됨",
discovered: "발견됨",
secret: "시크릿",
},
tier: {
target: "목표 {tier}",
hidden: "숨김",
complete: "완료",
objective: "목표",
},
progress: {
hidden: "숨김",
},
scan: {
building_headline: "업적 프로필을 구성하고 있습니다…",
building_detail:
"세션, 도구 호출, 모델 메타데이터, 해제 상태를 읽고 있습니다.",
starting_headline: "업적 스캔을 시작합니다…",
progress_detail:
"{total}개 중 {scanned}개의 세션을 스캔했습니다 · {pct}%. 더 많은 기록이 들어오면 배지가 해제됩니다.",
idle_detail:
"세션, 도구 호출, 모델 메타데이터, 해제 상태를 읽고 있습니다. 배지가 해제되면 여기에 표시됩니다.",
},
guide: {
tiers_header: "등급",
secret_header: "시크릿 업적",
secret_body:
"시크릿은 정확한 트리거 조건을 숨깁니다. Hermes가 관련 신호를 감지하면 카드가 Discovered로 바뀌고 요건이 표시됩니다.",
scan_status_header: "스캔 상태",
scan_status_body:
"Hermes는 로컬 기록을 한 번 스캔한 뒤 카드를 자동으로 표시합니다. 몇 초 걸리더라도 멈춘 것이 아닙니다.",
what_scanned_header: "스캔 대상",
what_scanned_body:
"세션, 도구 호출, 모델 메타데이터, 오류, 업적 및 로컬 해제 상태입니다.",
},
card: {
share_title: "이 업적 공유",
share_label: "{name} 공유",
share_text: "공유",
how_to_reveal: "공개하는 방법",
what_counts: "인정되는 조건",
evidence_label: "근거",
evidence_session_fallback: "세션",
no_evidence: "아직 근거가 없습니다",
},
latest: {
header: "최근 해제",
},
empty: {
no_secrets_header: "이번 스캔에 남은 숨겨진 시크릿이 없습니다.",
no_secrets_body:
"힌트: 시크릿은 보통 비정상적인 실패나 파워 유저 패턴에서 시작됩니다 — 포트 충돌, 권한 차단, 누락된 환경 변수, YAML 실수, Docker 충돌, 롤백/체크포인트 사용, 캐시 적중, 또는 많은 오류 메시지 뒤의 작은 수정 등입니다.",
},
filters: {
all_categories: "전체",
visibility_all: "전체",
visibility_unlocked: "해제됨",
visibility_discovered: "발견됨",
visibility_secret: "시크릿",
},
share: {
dialog_label: "업적 공유",
header: "공유: {name}",
close: "닫기",
rendering: "렌더링 중…",
card_alt: "{name} 공유 카드",
error_generic: "문제가 발생했습니다.",
x_title: "미리 작성된 게시물로 X를 엽니다",
x_button: "X에 공유",
copy_title: "게시물에 붙여넣을 수 있도록 이미지를 복사합니다",
copy_button: "이미지 복사",
copied: "복사됨 ✓",
download_button: "PNG 다운로드",
hint:
"X에 공유를 누르면 새 탭에서 미리 작성된 게시물이 열립니다. 1200×630 배지를 첨부하려면 먼저 이미지 복사를 누르세요 — X 작성기에서 바로 붙여넣을 수 있습니다. PNG 다운로드는 파일을 저장하여 어디서나 사용할 수 있게 합니다.",
clipboard_unsupported:
"이 브라우저에서는 클립보드 이미지 복사를 지원하지 않습니다 — 대신 다운로드를 이용하세요.",
tweet_text: "Just unlocked {tier_part}\"{name}\" in Hermes Agent ☤",
},
},
kanban: {
loading: "Kanban 보드를 불러오는 중입니다…",
loadFailed: "Kanban 보드를 불러오지 못했습니다: ",
loadFailedHint:
"백엔드는 처음 읽을 때 kanban.db를 자동으로 생성합니다. 문제가 계속되면 대시보드 로그를 확인하십시오.",
board: "보드",
newBoard: "+ 새 보드",
newBoardTitle: "새 보드",
newBoardDescription:
"보드를 사용하면 관련 없는 작업 흐름을 분리할 수 있습니다 — 프로젝트, 저장소, 도메인마다 하나씩. 한 보드의 워커는 다른 보드의 작업을 절대 보지 않습니다.",
slug: "슬러그",
slugHint: "— 소문자, 하이픈, 예: atm10-server",
displayName: "표시 이름",
displayNameHint: "(선택)",
description: "설명",
descriptionHint: "(선택)",
icon: "아이콘",
iconHint: "(한 글자 또는 이모지)",
switchAfterCreate: "생성 후 이 보드로 전환",
cancel: "취소",
creating: "생성 중…",
createBoard: "보드 생성",
search: "검색",
filterCards: "카드 필터링…",
tenant: "테넌트",
allTenants: "모든 테넌트",
assignee: "담당자",
allProfiles: "모든 프로필",
showArchived: "보관된 항목 표시",
lanesByProfile: "프로필별 레인",
nudgeDispatcher: "디스패처 깨우기",
refresh: "새로 고침",
selected: "선택됨",
complete: "완료",
archive: "보관",
apply: "적용",
clear: "지우기",
createTask: "이 열에 작업 만들기",
noTasks: "— 작업 없음 —",
unassigned: "미지정",
untitled: "(제목 없음)",
loadingDetail: "불러오는 중…",
addComment: "댓글 추가… (Enter로 전송)",
comment: "댓글",
status: "상태",
workspace: "작업 공간",
skills: "스킬",
createdBy: "작성자",
result: "결과",
comments: "댓글",
events: "이벤트",
runHistory: "실행 기록",
workerLog: "워커 로그",
loadingLog: "로그를 불러오는 중…",
noWorkerLog:
"— 아직 워커 로그가 없습니다 (작업이 시작되지 않았거나 로그가 순환되었습니다) —",
noDescription: "— 설명 없음 —",
noComments: "— 댓글 없음 —",
edit: "편집",
save: "저장",
dependencies: "종속성",
parents: "상위 작업:",
children: "하위 작업:",
none: "없음",
addParent: "— 상위 작업 추가 —",
addChild: "— 하위 작업 추가 —",
removeDependency: "종속성 제거",
block: "차단",
unblock: "차단 해제",
notifyHomeChannels: "홈 채널에 알림",
diagnostics: "진단",
hide: "숨기기",
show: "표시",
attention: "주의",
tasksNeedAttention: "개의 작업이 주의를 필요로 합니다",
taskNeedsAttention: "작업 1개가 주의를 필요로 합니다",
diagnostic: "진단",
open: "열기",
close: "닫기 (Esc)",
reassignTo: "다음으로 재지정:",
copied: "복사됨",
copyCommand: "명령을 클립보드로 복사",
reclaim: "회수",
reassign: "재지정",
renderingError: "Kanban 탭에서 렌더링 오류가 발생했습니다",
reloadView: "뷰 다시 불러오기",
wsAuthFailed:
"WebSocket 인증 실패 — 페이지를 다시 불러와 세션 토큰을 갱신하십시오.",
markDone: "{n}개의 작업을 완료로 표시하시겠습니까?",
markArchived: "{n}개의 작업을 보관하시겠습니까?",
warning: "경고",
phantomIds: "팬텀 ID:",
active: "활성",
ended: "종료됨",
noProfile: "(프로필 없음)",
showAllAttempts: "모든 시도 표시",
sendingUpdates: "업데이트 전송 대상: ",
sendNotifications: "완료 / 차단됨 / 포기 알림 전송 대상",
archiveBoardConfirm:
"보드 '{name}'을(를) 보관하시겠습니까? 보드는 boards/_archived/로 이동되어 나중에 복구할 수 있습니다. 이 보드의 작업은 더 이상 UI 어디에도 나타나지 않습니다.",
archiveBoardTitle: "이 보드 보관",
boardSwitcherHint: "보드를 사용하면 관련 없는 작업 흐름을 분리할 수 있습니다",
taskCreatedWarning: "작업이 생성되었지만: ",
moveFailed: "이동 실패: ",
bulkFailed: "일괄 처리: ",
completionBlockedHallucination: "⚠ 완료가 차단됨 — 팬텀 카드 ID",
suspectedHallucinatedReferences: "⚠ 본문이 팬텀 카드 ID를 참조함",
pickProfileFirst: "먼저 프로필을 선택하십시오.",
unblockedMessage: "{id}의 차단을 해제했습니다. 작업이 다음 틱을 위해 준비되었습니다.",
unblockFailed: "차단 해제 실패: ",
reclaimedMessage: "{id}을(를) 회수했습니다. 작업이 ready 상태로 돌아갔습니다.",
reclaimFailed: "회수 실패: ",
reassignedMessage: "{id}을(를) {profile}(으)로 재지정했습니다.",
reassignFailed: "재지정 실패: ",
selectForBulk: "일괄 작업을 위해 선택",
clickToEdit: "클릭하여 편집",
clickToEditAssignee: "클릭하여 담당자 편집",
emptyAssignee: "(비우면 = 지정 해제)",
columnLabels: {
triage: "분류",
todo: "할 일",
ready: "준비됨",
running: "진행 중",
blocked: "차단됨",
done: "완료",
archived: "보관됨",
},
columnHelp: {
triage: "원시 아이디어 — 스페시파이어가 사양을 구체화합니다",
todo: "종속성 대기 중 또는 미지정",
ready: "지정되었으며 디스패처 틱 대기 중",
running: "워커가 점유 중 — 실행 중",
blocked: "워커가 사람의 입력을 요청함",
done: "완료됨",
archived: "보관됨",
},
confirmDone:
"이 작업을 완료로 표시하시겠습니까? 워커의 점유가 해제되고 종속된 하위 작업이 ready 상태가 됩니다.",
confirmArchive:
"이 작업을 보관하시겠습니까? 기본 보드 보기에서 사라집니다.",
confirmBlocked:
"이 작업을 차단됨으로 표시하시겠습니까? 워커의 점유가 해제됩니다.",
completionSummary:
"{label}의 완료 요약입니다. 이는 작업 결과로 저장됩니다.",
completionSummaryRequired:
"작업을 완료로 표시하기 전에 완료 요약이 필요합니다.",
triagePlaceholder: "대략적인 아이디어 — AI가 사양을 작성합니다…",
taskTitlePlaceholder: "새 작업 제목…",
specifier: "스페시파이어",
assigneePlaceholder: "담당자",
priority: "우선순위",
skillsPlaceholder:
"스킬 (선택, 쉼표로 구분): translation, github-code-review",
noParent: "— 상위 작업 없음 —",
workspacePathDir: "작업 공간 경로 (필수, 예: ~/projects/my-app)",
workspacePathOptional:
"작업 공간 경로 (선택, 비어 있으면 담당자에서 파생됨)",
logTruncated: "(마지막 100 KB 표시 중 — 전체 로그 위치: ",
logAt: ")",
},
};

696
web/src/i18n/pt.ts Normal file
View file

@ -0,0 +1,696 @@
import type { Translations } from "./types";
export const pt: Translations = {
common: {
save: "Guardar",
saving: "A guardar...",
cancel: "Cancelar",
close: "Fechar",
confirm: "Confirmar",
delete: "Eliminar",
refresh: "Atualizar",
retry: "Tentar novamente",
search: "Pesquisar...",
loading: "A carregar...",
create: "Criar",
creating: "A criar...",
set: "Definir",
replace: "Substituir",
clear: "Limpar",
live: "Ativo",
off: "Desligado",
enabled: "ativado",
disabled: "desativado",
active: "ativo",
inactive: "inativo",
unknown: "desconhecido",
untitled: "Sem título",
none: "Nenhum",
form: "Formulário",
noResults: "Sem resultados",
of: "de",
page: "Página",
msgs: "msgs",
tools: "ferramentas",
match: "correspondência",
other: "Outro",
configured: "configurado",
removed: "removido",
failedToToggle: "Falha ao alternar",
failedToRemove: "Falha ao remover",
failedToReveal: "Falha ao revelar",
collapse: "Recolher",
expand: "Expandir",
general: "Geral",
messaging: "Mensagens",
pluginLoadFailed:
"Não foi possível carregar o script deste plugin. Verifique o separador Network (dashboard-plugins/…) e o caminho do plugin no servidor.",
pluginNotRegistered:
"O script do plugin não chamou register(), ou o script falhou. Abra a consola do browser para mais detalhes.",
},
app: {
brand: "Hermes Agent",
brandShort: "HA",
closeNavigation: "Fechar navegação",
closeModelTools: "Fechar modelo e ferramentas",
footer: {
org: "Nous Research",
},
activeSessionsLabel: "Sessões ativas:",
gatewayStatusLabel: "Estado do gateway:",
gatewayStrip: {
failed: "Falha ao iniciar",
off: "Desligado",
running: "A executar",
starting: "A iniciar",
stopped: "Parado",
},
nav: {
analytics: "Análise",
chat: "Chat",
config: "Configuração",
cron: "Cron",
documentation: "Documentação",
keys: "Chaves",
logs: "Registos",
models: "Modelos",
profiles: "perfis: multiagentes",
plugins: "Plugins",
sessions: "Sessões",
skills: "Competências",
},
modelToolsSheetSubtitle: "e ferramentas",
modelToolsSheetTitle: "Modelo",
navigation: "Navegação",
openDocumentation: "Abrir documentação num novo separador",
openNavigation: "Abrir navegação",
pluginNavSection: "Plugins",
sessionsActiveCount: "{count} ativa(s)",
statusOverview: "Visão geral do estado",
system: "Sistema",
webUi: "Web UI",
},
status: {
actionFailed: "Ação falhou",
actionFinished: "Concluído",
actions: "Ações",
agent: "Agente",
activeSessions: "Sessões ativas",
connected: "Ligado",
connectedPlatforms: "Plataformas ligadas",
disconnected: "Desligado",
error: "Erro",
failed: "Falhou",
gateway: "Gateway",
gatewayFailedToStart: "O gateway falhou ao iniciar",
lastUpdate: "Última atualização",
noneRunning: "Nenhum",
notRunning: "Não está a executar",
pid: "PID",
platformDisconnected: "desligado",
platformError: "erro",
recentSessions: "Sessões recentes",
restartGateway: "Reiniciar gateway",
restartingGateway: "A reiniciar gateway…",
running: "A executar",
runningRemote: "A executar (remoto)",
startFailed: "Falha ao iniciar",
starting: "A iniciar",
startedInBackground: "Iniciado em segundo plano — verifique os registos para acompanhar",
stopped: "Parado",
updateHermes: "Atualizar Hermes",
updatingHermes: "A atualizar Hermes…",
waitingForOutput: "À espera de saída…",
},
sessions: {
title: "Sessões",
searchPlaceholder: "Pesquisar conteúdo das mensagens...",
noSessions: "Ainda não há sessões",
noMatch: "Nenhuma sessão corresponde à pesquisa",
startConversation: "Inicie uma conversa para a ver aqui",
noMessages: "Sem mensagens",
untitledSession: "Sessão sem título",
deleteSession: "Eliminar sessão",
confirmDeleteTitle: "Eliminar sessão?",
confirmDeleteMessage:
"Esta ação remove permanentemente a conversa e todas as suas mensagens. Não é possível anular.",
sessionDeleted: "Sessão eliminada",
failedToDelete: "Falha ao eliminar a sessão",
resumeInChat: "Retomar no Chat",
previousPage: "Página anterior",
nextPage: "Página seguinte",
roles: {
user: "Utilizador",
assistant: "Assistente",
system: "Sistema",
tool: "Ferramenta",
},
},
analytics: {
period: "Período:",
totalTokens: "Tokens totais",
totalSessions: "Sessões totais",
apiCalls: "Chamadas à API",
dailyTokenUsage: "Utilização diária de tokens",
dailyBreakdown: "Detalhe diário",
perModelBreakdown: "Detalhe por modelo",
topSkills: "Competências principais",
skill: "Competência",
loads: "Carregadas pelo agente",
edits: "Geridas pelo agente",
lastUsed: "Última utilização",
input: "Entrada",
output: "Saída",
total: "Total",
noUsageData: "Sem dados de utilização para este período",
startSession: "Inicie uma sessão para ver as análises aqui",
date: "Data",
model: "Modelo",
tokens: "Tokens",
perDayAvg: "/dia (média)",
acrossModels: "em {count} modelos",
inOut: "{input} entrada / {output} saída",
},
models: {
modelsUsed: "Modelos utilizados",
estimatedCost: "Custo est.",
tokens: "tokens",
sessions: "sessões",
avgPerSession: "média/sessão",
apiCalls: "chamadas à API",
toolCalls: "chamadas a ferramentas",
noModelsData: "Sem dados de utilização de modelos para este período",
startSession: "Inicie uma sessão para ver os dados de modelos aqui",
},
logs: {
title: "Registos",
autoRefresh: "Atualização automática",
file: "Ficheiro",
level: "Nível",
component: "Componente",
lines: "Linhas",
noLogLines: "Não foram encontradas linhas de registo",
},
cron: {
confirmDeleteMessage:
"Esta ação remove a tarefa do agendamento. Não é possível anular.",
confirmDeleteTitle: "Eliminar tarefa agendada?",
newJob: "Nova tarefa cron",
nameOptional: "Nome (opcional)",
namePlaceholder: "ex: Resumo diário",
prompt: "Prompt",
promptPlaceholder: "O que deve o agente fazer em cada execução?",
schedule: "Agendamento (expressão cron)",
schedulePlaceholder: "0 9 * * *",
deliverTo: "Entregar a",
scheduledJobs: "Tarefas agendadas",
noJobs: "Sem tarefas cron configuradas. Crie uma acima.",
last: "Última",
next: "Próxima",
pause: "Pausar",
resume: "Retomar",
triggerNow: "Acionar agora",
delivery: {
local: "Local",
telegram: "Telegram",
discord: "Discord",
slack: "Slack",
email: "Email",
},
},
profiles: {
newProfile: "Novo perfil",
name: "Nome",
namePlaceholder: "ex: coder, writer, etc.",
nameRequired: "O nome é obrigatório",
nameRule:
"Apenas letras minúsculas, dígitos, _ e -; deve começar com letra ou dígito; até 64 caracteres.",
invalidName: "Nome de perfil inválido",
cloneFromDefault: "Clonar configuração do perfil predefinido",
allProfiles: "Perfis",
noProfiles: "Não foram encontrados perfis.",
defaultBadge: "predefinido",
hasEnv: "env",
model: "Modelo",
skills: "Competências",
rename: "Renomear",
editSoul: "Editar SOUL.md",
soulSection: "SOUL.md (personalidade / prompt do sistema)",
soulPlaceholder: "# Como este agente se deve comportar…",
saveSoul: "Guardar SOUL",
soulSaved: "SOUL.md guardado",
openInTerminal: "Copiar comando da CLI",
commandCopied: "Copiado para a área de transferência",
copyFailed: "Não foi possível copiar",
confirmDeleteTitle: "Eliminar perfil?",
confirmDeleteMessage:
"Esta ação elimina permanentemente o perfil '{name}' — configuração, chaves, memórias, sessões, competências, tarefas cron. Não é possível anular.",
created: "Criado",
deleted: "Eliminado",
renamed: "Renomeado",
},
pluginsPage: {
contextEngineLabel: "Motor de contexto",
dashboardSlots: "Slots do dashboard",
disableRuntime: "Desativar",
enableAfterInstall: "Ativar após instalação",
enableRuntime: "Ativar",
forceReinstall: "Forçar reinstalação (eliminar pasta existente primeiro)",
headline:
"Descobrir, instalar, ativar e atualizar plugins Hermes (paridade com `hermes plugins`).",
identifierLabel: "URL Git ou owner/repo",
inactive: "inativo",
installBtn: "Instalar a partir do Git",
installHeading: "Instalar a partir de GitHub / URL Git",
installHint: "Use a forma curta owner/repo ou um URL completo de clone https:// ou git@.",
memoryProviderLabel: "Fornecedor de memória",
missingEnvWarn: "Defina os seguintes em Chaves antes de o plugin poder executar:",
noDashboardTab: "Sem separador no dashboard",
openTab: "Abrir",
orphanHeading: "Extensões só de dashboard (sem plugin.yaml de agente correspondente)",
pluginListHeading: "Plugins instalados",
providerDefaults: "incorporado / predefinido",
providersHeading: "Plugins de fornecedor em runtime",
providersHint:
"Escreve memory.provider (vazio = incorporado) e context.engine no config.yaml. Aplicado na próxima sessão.",
refreshDashboard: "Re-analisar extensões do dashboard",
removeConfirm: "Remover este plugin de ~/.hermes/plugins/?",
removeHint: "Apenas plugins instalados pelo utilizador em ~/.hermes/plugins podem ser removidos.",
rescanHeading: "Registo de plugins SPA",
rescanHint: "Re-analise depois de adicionar ficheiros em disco para que a barra lateral detete novos manifestos.",
runtimeHeading: "Runtime do gateway (plugins YAML)",
saveProviders: "Guardar definições do fornecedor",
savedProviders: "Definições do fornecedor guardadas.",
sourceBadge: "Fonte",
authRequired: "Autenticação necessária",
authRequiredHint: "Execute este comando para autenticar:",
updateGit: "Git pull",
versionBadge: "Versão",
showInSidebar: "Mostrar na barra lateral",
hideFromSidebar: "Ocultar da barra lateral",
},
skills: {
title: "Competências",
searchPlaceholder: "Pesquisar competências e conjuntos de ferramentas...",
enabledOf: "{enabled}/{total} ativadas",
all: "Todas",
categories: "Categorias",
filters: "Filtros",
noSkills: "Nenhuma competência encontrada. As competências são carregadas de ~/.hermes/skills/",
noSkillsMatch: "Nenhuma competência corresponde à pesquisa ou filtro.",
skillCount: "{count} competência{s}",
resultCount: "{count} resultado{s}",
noDescription: "Sem descrição disponível.",
toolsets: "Conjuntos de ferramentas",
toolsetLabel: "conjunto {name}",
noToolsetsMatch: "Nenhum conjunto de ferramentas corresponde à pesquisa.",
setupNeeded: "Configuração necessária",
disabledForCli: "Desativado para CLI",
more: "+{count} mais",
},
config: {
configPath: "~/.hermes/config.yaml",
filters: "Filtros",
sections: "Secções",
exportConfig: "Exportar configuração como JSON",
importConfig: "Importar configuração de JSON",
resetDefaults: "Repor predefinições",
resetScopeTooltip: "Repor {scope} para predefinições",
confirmResetScope: "Repor todas as definições de {scope} para os valores predefinidos? Isto apenas atualiza o formulário — as alterações só são escritas em config.yaml quando premir Guardar.",
resetScopeToast: "{scope} reposto para predefinições — reveja e Guarde para persistir",
rawYaml: "Configuração YAML em bruto",
searchResults: "Resultados da pesquisa",
fields: "campo{s}",
noFieldsMatch: 'Nenhum campo corresponde a "{query}"',
configSaved: "Configuração guardada",
yamlConfigSaved: "Configuração YAML guardada",
failedToSave: "Falha ao guardar",
failedToSaveYaml: "Falha ao guardar YAML",
failedToLoadRaw: "Falha ao carregar configuração em bruto",
configImported: "Configuração importada — reveja e guarde",
invalidJson: "Ficheiro JSON inválido",
categories: {
general: "Geral",
agent: "Agente",
terminal: "Terminal",
display: "Visualização",
delegation: "Delegação",
memory: "Memória",
compression: "Compressão",
security: "Segurança",
browser: "Browser",
voice: "Voz",
tts: "Texto para fala",
stt: "Fala para texto",
logging: "Registo",
discord: "Discord",
auxiliary: "Auxiliar",
},
},
env: {
changesNote: "As alterações são guardadas em disco imediatamente. As sessões ativas detetam novas chaves automaticamente.",
confirmClearMessage:
"O valor armazenado para esta variável será removido do seu ficheiro .env. Esta ação não pode ser anulada a partir da UI.",
confirmClearTitle: "Limpar esta chave?",
description: "Gerir chaves de API e segredos armazenados em",
hideAdvanced: "Ocultar avançadas",
showAdvanced: "Mostrar avançadas",
llmProviders: "Fornecedores LLM",
providersConfigured: "{configured} de {total} fornecedores configurados",
getKey: "Obter chave",
notConfigured: "{count} não configurado(s)",
notSet: "Não definido",
keysCount: "{count} chave{s}",
enterValue: "Introduzir valor...",
replaceCurrentValue: "Substituir valor atual ({preview})",
showValue: "Mostrar valor real",
hideValue: "Ocultar valor",
},
oauth: {
title: "Inícios de sessão de fornecedor (OAuth)",
providerLogins: "Inícios de sessão de fornecedor (OAuth)",
description: "{connected} de {total} fornecedores OAuth ligados. Os fluxos de início de sessão são executados via CLI; clique em Copiar comando e cole num terminal para configurar.",
connected: "Ligado",
expired: "Expirado",
notConnected: "Não ligado. Execute {command} num terminal.",
runInTerminal: "num terminal.",
noProviders: "Não foram detetados fornecedores compatíveis com OAuth.",
login: "Iniciar sessão",
disconnect: "Desligar",
managedExternally: "Gerido externamente",
copied: "Copiado ✓",
cli: "CLI",
copyCliCommand: "Copiar comando CLI (para externo / fallback)",
connect: "Ligar",
sessionExpires: "A sessão expira em {time}",
initiatingLogin: "A iniciar fluxo de início de sessão…",
exchangingCode: "A trocar código por tokens…",
connectedClosing: "Ligado! A fechar…",
loginFailed: "Início de sessão falhou.",
sessionExpired: "Sessão expirada. Clique em Tentar novamente para iniciar um novo início de sessão.",
reOpenAuth: "Reabrir página de autenticação",
reOpenVerification: "Reabrir página de verificação",
submitCode: "Submeter código",
pasteCode: "Cole o código de autorização (com sufixo #state também é válido)",
waitingAuth: "À espera que autorize no browser…",
enterCodePrompt: "Foi aberto um novo separador. Introduza este código se for solicitado:",
pkceStep1: "Foi aberto um novo separador para claude.ai. Inicie sessão e clique em Authorize.",
pkceStep2: "Copie o código de autorização mostrado após autorizar.",
pkceStep3: "Cole-o abaixo e submeta.",
flowLabels: {
pkce: "Início de sessão pelo browser (PKCE)",
device_code: "Código de dispositivo",
external: "CLI externa",
},
expiresIn: "expira em {time}",
},
language: {
switchTo: "Mudar para inglês",
},
theme: {
title: "Tema",
switchTheme: "Mudar tema",
},
achievements: {
hero: {
kicker: "Agentic Gamerscore",
title: "Hermes Achievements",
subtitle:
"Distintivos colecionáveis do Hermes obtidos a partir do histórico real de sessões. Conquistas conhecidas mas ainda não obtidas aparecem como Descobertas; conquistas Secretas permanecem ocultas até surgir o primeiro comportamento correspondente.",
scan_subtitle:
"A analisar o histórico de sessões do Hermes. A primeira análise pode demorar 510 segundos em históricos extensos.",
},
actions: {
rescan: "Voltar a analisar",
},
stats: {
unlocked: "Desbloqueadas",
unlocked_hint: "distintivos obtidos",
discovered: "Descobertas",
discovered_hint: "conhecidas, ainda não obtidas",
secrets: "Secretas",
secrets_hint: "ocultas até ao primeiro sinal",
highest_tier: "Nível mais alto",
highest_tier_hint: "Copper → Silver → Gold → Diamond → Olympian",
latest: "Mais recente",
latest_hint_empty: "execute mais o Hermes",
none_yet: "Ainda nenhuma",
},
state: {
unlocked: "Desbloqueada",
discovered: "Descoberta",
secret: "Secreta",
},
tier: {
target: "Objetivo {tier}",
hidden: "Oculto",
complete: "Completo",
objective: "Objetivo",
},
progress: {
hidden: "oculto",
},
scan: {
building_headline: "A construir perfil de conquistas…",
building_detail:
"A ler sessões, chamadas de ferramentas, metadados de modelos e estado de desbloqueio.",
starting_headline: "A iniciar análise de conquistas…",
progress_detail:
"Analisadas {scanned} de {total} sessões · {pct}%. Os distintivos são desbloqueados à medida que mais histórico é processado.",
idle_detail:
"A ler sessões, chamadas de ferramentas, metadados de modelos e estado de desbloqueio. Os distintivos aparecem aqui à medida que são desbloqueados.",
},
guide: {
tiers_header: "Níveis",
secret_header: "Conquistas secretas",
secret_body:
"As secretas escondem o seu acionador exato. Assim que o Hermes detetar um sinal relacionado, o cartão passa a Descoberta e mostra o requisito.",
scan_status_header: "Estado da análise",
scan_status_body:
"O Hermes analisa o histórico local uma vez e depois os cartões aparecem automaticamente. Nada está bloqueado se isto demorar alguns segundos.",
what_scanned_header: "O que é analisado",
what_scanned_body:
"Sessões, chamadas de ferramentas, metadados de modelos, erros, conquistas e estado de desbloqueio local.",
},
card: {
share_title: "Partilhar esta conquista",
share_label: "Partilhar {name}",
share_text: "Partilhar",
how_to_reveal: "Como revelar",
what_counts: "O que conta",
evidence_label: "Evidência",
evidence_session_fallback: "sessão",
no_evidence: "Ainda sem evidência",
},
latest: {
header: "Desbloqueios recentes",
},
empty: {
no_secrets_header: "Não restam segredos ocultos nesta análise.",
no_secrets_body:
"Pista: as secretas começam normalmente em padrões pouco comuns de falha ou de utilizador avançado — conflitos de portas, barreiras de permissões, variáveis de ambiente em falta, erros de YAML, colisões de Docker, uso de rollback/checkpoint, acertos de cache ou pequenas correções após muito texto a vermelho.",
},
filters: {
all_categories: "Todas",
visibility_all: "todas",
visibility_unlocked: "desbloqueadas",
visibility_discovered: "descobertas",
visibility_secret: "secretas",
},
share: {
dialog_label: "Partilhar conquista",
header: "Partilhar: {name}",
close: "Fechar",
rendering: "A renderizar…",
card_alt: "Cartão de partilha de {name}",
error_generic: "Algo correu mal.",
x_title: "Abre o X com uma publicação pré-preenchida",
x_button: "Partilhar no X",
copy_title: "Copiar a imagem para colar na sua publicação",
copy_button: "Copiar imagem",
copied: "Copiado ✓",
download_button: "Transferir PNG",
hint:
"Partilhar no X abre uma publicação pré-preenchida num novo separador. Clique primeiro em Copiar imagem se quiser anexar o distintivo 1200×630 — o X permite colá-lo diretamente no compositor da publicação. Transferir PNG guarda o ficheiro para utilização em qualquer lado.",
clipboard_unsupported:
"A cópia de imagens para a área de transferência não é suportada neste navegador — utilize Transferir.",
tweet_text: "Just unlocked {tier_part}\"{name}\" in Hermes Agent ☤",
},
},
kanban: {
loading: "A carregar o quadro Kanban…",
loadFailed: "Falha ao carregar o quadro Kanban: ",
loadFailedHint:
"O backend cria automaticamente kanban.db na primeira leitura. Se persistir, consulte os registos do dashboard.",
board: "Quadro",
newBoard: "+ Novo quadro",
newBoardTitle: "Novo quadro",
newBoardDescription:
"Os quadros permitem-lhe separar fluxos de trabalho não relacionados — um por projeto, repositório ou domínio. Os workers de um quadro nunca veem as tarefas de outro quadro.",
slug: "Slug",
slugHint: "— minúsculas, hífenes, p. ex. atm10-server",
displayName: "Nome a apresentar",
displayNameHint: "(opcional)",
description: "Descrição",
descriptionHint: "(opcional)",
icon: "Ícone",
iconHint: "(carácter único ou emoji)",
switchAfterCreate: "Mudar para este quadro após o criar",
cancel: "Cancelar",
creating: "A criar…",
createBoard: "Criar quadro",
search: "Pesquisar",
filterCards: "Filtrar cartões…",
tenant: "Tenant",
allTenants: "Todos os tenants",
assignee: "Responsável",
allProfiles: "Todos os perfis",
showArchived: "Mostrar arquivados",
lanesByProfile: "Faixas por perfil",
nudgeDispatcher: "Despertar o dispatcher",
refresh: "Atualizar",
selected: "selecionado(s)",
complete: "Concluir",
archive: "Arquivar",
apply: "Aplicar",
clear: "Limpar",
createTask: "Criar tarefa nesta coluna",
noTasks: "— sem tarefas —",
unassigned: "sem atribuição",
untitled: "(sem título)",
loadingDetail: "A carregar…",
addComment: "Adicionar um comentário… (Enter para submeter)",
comment: "Comentário",
status: "Estado",
workspace: "Espaço de trabalho",
skills: "Competências",
createdBy: "Criado por",
result: "Resultado",
comments: "Comentários",
events: "Eventos",
runHistory: "Histórico de execuções",
workerLog: "Registo do worker",
loadingLog: "A carregar registo…",
noWorkerLog:
"— ainda não há registo do worker (a tarefa não foi iniciada ou o registo foi rotacionado) —",
noDescription: "— sem descrição —",
noComments: "— sem comentários —",
edit: "editar",
save: "Guardar",
dependencies: "Dependências",
parents: "Pais:",
children: "Filhos:",
none: "nenhum",
addParent: "— adicionar pai —",
addChild: "— adicionar filho —",
removeDependency: "Remover dependência",
block: "Bloquear",
unblock: "Desbloquear",
notifyHomeChannels: "Notificar canais principais",
diagnostics: "Diagnósticos",
hide: "Ocultar",
show: "Mostrar",
attention: "Atenção",
tasksNeedAttention: "tarefas precisam de atenção",
taskNeedsAttention: "1 tarefa precisa de atenção",
diagnostic: "diagnóstico",
open: "Abrir",
close: "Fechar (Esc)",
reassignTo: "Reatribuir a:",
copied: "Copiado",
copyCommand: "Copiar comando para a área de transferência",
reclaim: "Reivindicar",
reassign: "Reatribuir",
renderingError: "O separador Kanban encontrou um erro de renderização",
reloadView: "Recarregar vista",
wsAuthFailed:
"Falha de autenticação WebSocket — recarregue a página para atualizar o token de sessão.",
markDone: "Marcar {n} tarefa(s) como concluídas?",
markArchived: "Arquivar {n} tarefa(s)?",
warning: "Aviso",
phantomIds: "Ids fantasma:",
active: "ativo",
ended: "terminado",
noProfile: "(sem perfil)",
showAllAttempts: "Mostrar todas as tentativas",
sendingUpdates: "A enviar atualizações para",
sendNotifications: "Enviar notificações de completed / blocked / gave_up para",
archiveBoardConfirm:
"Arquivar o quadro '{name}'? Será movido para boards/_archived/ para que possa recuperá-lo mais tarde. As tarefas deste quadro deixarão de aparecer em qualquer parte da interface.",
archiveBoardTitle: "Arquivar este quadro",
boardSwitcherHint: "Os quadros permitem-lhe separar fluxos de trabalho não relacionados",
taskCreatedWarning: "Tarefa criada, mas: ",
moveFailed: "Falha ao mover: ",
bulkFailed: "Em lote: ",
completionBlockedHallucination: "⚠ Conclusão bloqueada — ids de cartões fantasma",
suspectedHallucinatedReferences: "⚠ O texto referenciou ids de cartões fantasma",
pickProfileFirst: "Escolha primeiro um perfil.",
unblockedMessage: "{id} desbloqueado. A tarefa está pronta para o próximo tick.",
unblockFailed: "Falha ao desbloquear: ",
reclaimedMessage: "{id} reivindicado. A tarefa voltou a ready.",
reclaimFailed: "Falha ao reivindicar: ",
reassignedMessage: "{id} reatribuído a {profile}.",
reassignFailed: "Falha ao reatribuir: ",
selectForBulk: "Selecionar para ações em lote",
clickToEdit: "Clique para editar",
clickToEditAssignee: "Clique para editar responsável",
emptyAssignee: "(vazio = remover atribuição)",
columnLabels: {
triage: "Triagem",
todo: "A fazer",
ready: "Pronto",
running: "Em curso",
blocked: "Bloqueado",
done: "Concluído",
archived: "Arquivado",
},
columnHelp: {
triage: "Ideias em bruto — um specifier vai detalhar a especificação",
todo: "À espera de dependências ou sem atribuição",
ready: "Atribuído e à espera de um tick do dispatcher",
running: "Reivindicado por um worker — em execução",
blocked: "O worker pediu intervenção humana",
done: "Concluído",
archived: "Arquivado",
},
confirmDone:
"Marcar esta tarefa como concluída? A reivindicação do worker é libertada e os filhos dependentes ficam prontos.",
confirmArchive:
"Arquivar esta tarefa? Desaparece da vista padrão do quadro.",
confirmBlocked:
"Marcar esta tarefa como bloqueada? A reivindicação do worker é libertada.",
completionSummary:
"Resumo de conclusão para {label}. Será guardado como o resultado da tarefa.",
completionSummaryRequired:
"É necessário um resumo de conclusão antes de marcar uma tarefa como concluída.",
triagePlaceholder: "Ideia aproximada — a IA irá especificá-la…",
taskTitlePlaceholder: "Título da nova tarefa…",
specifier: "specifier",
assigneePlaceholder: "responsável",
priority: "Prioridade",
skillsPlaceholder:
"competências (opcional, separadas por vírgulas): translation, github-code-review",
noParent: "— sem pai —",
workspacePathDir: "caminho do espaço de trabalho (obrigatório, p. ex. ~/projects/my-app)",
workspacePathOptional:
"caminho do espaço de trabalho (opcional, derivado do responsável se vazio)",
logTruncated: "(a mostrar os últimos 100 KB — registo completo em ",
logAt: ")",
},
};

696
web/src/i18n/ru.ts Normal file
View file

@ -0,0 +1,696 @@
import type { Translations } from "./types";
export const ru: 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: "Cron",
documentation: "Документация",
keys: "Ключи",
logs: "Журналы",
models: "Модели",
profiles: "профили: мульти-агенты",
plugins: "Плагины",
sessions: "Сессии",
skills: "Навыки",
},
modelToolsSheetSubtitle: "и инструменты",
modelToolsSheetTitle: "Модель",
navigation: "Навигация",
openDocumentation: "Открыть документацию в новой вкладке",
openNavigation: "Открыть навигацию",
pluginNavSection: "Плагины",
sessionsActiveCount: "{count} активн.",
statusOverview: "Обзор статуса",
system: "Система",
webUi: "Web UI",
},
status: {
actionFailed: "Ошибка действия",
actionFinished: "Завершено",
actions: "Действия",
agent: "Агент",
activeSessions: "Активные сессии",
connected: "Подключено",
connectedPlatforms: "Подключённые платформы",
disconnected: "Отключено",
error: "Ошибка",
failed: "Сбой",
gateway: "Шлюз",
gatewayFailedToStart: "Шлюзу не удалось запуститься",
lastUpdate: "Последнее обновление",
noneRunning: "Нет",
notRunning: "Не запущено",
pid: "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: "Всего токенов",
totalSessions: "Всего сессий",
apiCalls: "Вызовы API",
dailyTokenUsage: "Расход токенов по дням",
dailyBreakdown: "Разбивка по дням",
perModelBreakdown: "Разбивка по моделям",
topSkills: "Популярные навыки",
skill: "Навык",
loads: "Загружено агентом",
edits: "Управляется агентом",
lastUsed: "Последнее использование",
input: "Ввод",
output: "Вывод",
total: "Итого",
noUsageData: "Нет данных об использовании за этот период",
startSession: "Начните сессию, чтобы увидеть аналитику",
date: "Дата",
model: "Модель",
tokens: "Токены",
perDayAvg: "/день в среднем",
acrossModels: "по {count} моделям",
inOut: "{input} вход / {output} выход",
},
models: {
modelsUsed: "Использовано моделей",
estimatedCost: "Оценка стоимости",
tokens: "токены",
sessions: "сессии",
avgPerSession: "ср./сессию",
apiCalls: "вызовы API",
toolCalls: "вызовы инструментов",
noModelsData: "Нет данных по моделям за этот период",
startSession: "Начните сессию, чтобы увидеть данные по моделям",
},
logs: {
title: "Журналы",
autoRefresh: "Автообновление",
file: "Файл",
level: "Уровень",
component: "Компонент",
lines: "Строк",
noLogLines: "Записи журнала не найдены",
},
cron: {
confirmDeleteMessage:
"Это удалит задачу из расписания. Действие нельзя отменить.",
confirmDeleteTitle: "Удалить запланированную задачу?",
newJob: "Новая Cron-задача",
nameOptional: "Имя (необязательно)",
namePlaceholder: "напр. Ежедневная сводка",
prompt: "Запрос",
promptPlaceholder: "Что должен делать агент при каждом запуске?",
schedule: "Расписание (cron-выражение)",
schedulePlaceholder: "0 9 * * *",
deliverTo: "Доставить в",
scheduledJobs: "Запланированные задачи",
noJobs: "Cron-задачи не настроены. Создайте задачу выше.",
last: "Последний",
next: "Следующий",
pause: "Пауза",
resume: "Возобновить",
triggerNow: "Запустить сейчас",
delivery: {
local: "Локально",
telegram: "Telegram",
discord: "Discord",
slack: "Slack",
email: "Email",
},
},
profiles: {
newProfile: "Новый профиль",
name: "Имя",
namePlaceholder: "напр. coder, writer и т.п.",
nameRequired: "Имя обязательно",
nameRule:
"Только строчные буквы, цифры, _ и -; должно начинаться с буквы или цифры; до 64 символов.",
invalidName: "Недопустимое имя профиля",
cloneFromDefault: "Клонировать конфигурацию из профиля по умолчанию",
allProfiles: "Профили",
noProfiles: "Профили не найдены.",
defaultBadge: "по умолчанию",
hasEnv: "env",
model: "Модель",
skills: "Навыки",
rename: "Переименовать",
editSoul: "Редактировать SOUL.md",
soulSection: "SOUL.md (личность / системный промпт)",
soulPlaceholder: "# Как должен вести себя этот агент…",
saveSoul: "Сохранить SOUL",
soulSaved: "SOUL.md сохранён",
openInTerminal: "Скопировать команду CLI",
commandCopied: "Скопировано в буфер обмена",
copyFailed: "Не удалось скопировать",
confirmDeleteTitle: "Удалить профиль?",
confirmDeleteMessage:
"Это безвозвратно удалит профиль '{name}' — конфигурацию, ключи, память, сессии, навыки, cron-задачи. Отменить нельзя.",
created: "Создан",
deleted: "Удалён",
renamed: "Переименован",
},
pluginsPage: {
contextEngineLabel: "Движок контекста",
dashboardSlots: "Слоты панели",
disableRuntime: "Отключить",
enableAfterInstall: "Включить после установки",
enableRuntime: "Включить",
forceReinstall: "Принудительная переустановка (сначала удалить существующую папку)",
headline:
"Поиск, установка, включение и обновление плагинов Hermes (аналог `hermes plugins`).",
identifierLabel: "Git URL или owner/repo",
inactive: "неактивно",
installBtn: "Установить из Git",
installHeading: "Установка из GitHub / Git URL",
installHint: "Используйте сокращение owner/repo или полный https:// или git@ URL для клонирования.",
memoryProviderLabel: "Провайдер памяти",
missingEnvWarn: "Задайте эти переменные в разделе «Ключи», прежде чем плагин сможет работать:",
noDashboardTab: "Нет вкладки в панели",
openTab: "Открыть",
orphanHeading: "Расширения только для панели (без соответствующего plugin.yaml агента)",
pluginListHeading: "Установленные плагины",
providerDefaults: "встроенный / по умолчанию",
providersHeading: "Плагины-провайдеры рантайма",
providersHint:
"Записывает memory.provider (пусто = встроенный) и context.engine в config.yaml. Применяется со следующей сессии.",
refreshDashboard: "Пересканировать расширения панели",
removeConfirm: "Удалить этот плагин из ~/.hermes/plugins/?",
removeHint: "Удалять можно только плагины, установленные пользователем в ~/.hermes/plugins.",
rescanHeading: "Реестр SPA-плагинов",
rescanHint: "Пересканируйте после добавления файлов на диск, чтобы боковая панель подхватила новые манифесты.",
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} навык{s}",
resultCount: "{count} результат{s}",
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: "пол{s}",
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} ключ{s}",
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. Войдите и нажмите «Authorize».",
pkceStep2: "Скопируйте код авторизации, отображённый после авторизации.",
pkceStep3: "Вставьте его ниже и отправьте.",
flowLabels: {
pkce: "Вход через браузер (PKCE)",
device_code: "Код устройства",
external: "Внешний CLI",
},
expiresIn: "истекает через {time}",
},
language: {
switchTo: "Переключиться на английский",
},
theme: {
title: "Тема",
switchTheme: "Сменить тему",
},
achievements: {
hero: {
kicker: "Agentic Gamerscore",
title: "Hermes Achievements",
subtitle:
"Коллекционные значки Hermes, полученные на основе реальной истории сессий. Известные, но ещё не полученные достижения отображаются как «Обнаруженные»; «Секретные» достижения остаются скрытыми до появления первого подходящего поведения.",
scan_subtitle:
"Анализ истории сессий Hermes. Первое сканирование может занять 510 секунд при большой истории.",
},
actions: {
rescan: "Пересканировать",
},
stats: {
unlocked: "Разблокировано",
unlocked_hint: "полученные значки",
discovered: "Обнаружено",
discovered_hint: "известные, ещё не получены",
secrets: "Секреты",
secrets_hint: "скрыты до первого сигнала",
highest_tier: "Высший уровень",
highest_tier_hint: "Copper → Silver → Gold → Diamond → Olympian",
latest: "Последнее",
latest_hint_empty: "запускайте Hermes чаще",
none_yet: "Пока нет",
},
state: {
unlocked: "Разблокировано",
discovered: "Обнаружено",
secret: "Секрет",
},
tier: {
target: "Цель: {tier}",
hidden: "Скрыто",
complete: "Завершено",
objective: "Задача",
},
progress: {
hidden: "скрыто",
},
scan: {
building_headline: "Создание профиля достижений…",
building_detail:
"Чтение сессий, вызовов инструментов, метаданных моделей и состояния разблокировки.",
starting_headline: "Запуск сканирования достижений…",
progress_detail:
"Просканировано {scanned} из {total} сессий · {pct}%. Значки разблокируются по мере поступления истории.",
idle_detail:
"Чтение сессий, вызовов инструментов, метаданных моделей и состояния разблокировки. Значки появляются здесь по мере разблокировки.",
},
guide: {
tiers_header: "Уровни",
secret_header: "Секретные достижения",
secret_body:
"Секретные достижения скрывают свой точный триггер. Как только Hermes обнаруживает связанный сигнал, карточка становится «Обнаруженной» и показывает требование.",
scan_status_header: "Статус сканирования",
scan_status_body:
"Hermes сканирует локальную историю один раз, затем карточки появятся автоматически. Если это занимает несколько секунд — ничего не зависло.",
what_scanned_header: "Что сканируется",
what_scanned_body:
"Сессии, вызовы инструментов, метаданные моделей, ошибки, достижения и локальное состояние разблокировки.",
},
card: {
share_title: "Поделиться этим достижением",
share_label: "Поделиться: {name}",
share_text: "Поделиться",
how_to_reveal: "Как открыть",
what_counts: "Что засчитывается",
evidence_label: "Подтверждение",
evidence_session_fallback: "сессия",
no_evidence: "Подтверждений пока нет",
},
latest: {
header: "Недавние разблокировки",
},
empty: {
no_secrets_header: "В этом сканировании больше не осталось скрытых секретов.",
no_secrets_body:
"Подсказка: секреты обычно начинаются с необычных ошибок или паттернов опытных пользователей — конфликты портов, ограничения прав, отсутствующие переменные окружения, ошибки YAML, коллизии Docker, использование rollback/checkpoint, попадания в кеш или мелкие исправления после большого количества красного текста.",
},
filters: {
all_categories: "Все",
visibility_all: "все",
visibility_unlocked: "разблокированные",
visibility_discovered: "обнаруженные",
visibility_secret: "секретные",
},
share: {
dialog_label: "Поделиться достижением",
header: "Поделиться: {name}",
close: "Закрыть",
rendering: "Отрисовка…",
card_alt: "Карточка для публикации {name}",
error_generic: "Что-то пошло не так.",
x_title: "Открывает X с заранее заполненным постом",
x_button: "Поделиться в X",
copy_title: "Скопировать изображение для вставки в публикацию",
copy_button: "Скопировать изображение",
copied: "Скопировано ✓",
download_button: "Скачать PNG",
hint:
"«Поделиться в X» открывает пост с заранее заполненным текстом в новой вкладке. Сначала нажмите «Скопировать изображение», если хотите прикрепить значок 1200×630 — X позволяет вставить его прямо в редактор твита. «Скачать PNG» сохраняет файл для использования где угодно.",
clipboard_unsupported:
"Копирование изображений в буфер обмена не поддерживается в этом браузере — используйте «Скачать».",
tweet_text: "Just unlocked {tier_part}\"{name}\" in Hermes Agent ☤",
},
},
kanban: {
loading: "Загрузка доски Kanban…",
loadFailed: "Не удалось загрузить доску Kanban: ",
loadFailedHint:
"Бэкенд автоматически создаёт kanban.db при первом чтении. Если ошибка повторяется, проверьте логи панели.",
board: "Доска",
newBoard: "+ Новая доска",
newBoardTitle: "Новая доска",
newBoardDescription:
"Доски позволяют разделять не связанные между собой потоки работы — по одной на проект, репозиторий или область. Воркеры одной доски никогда не видят задачи другой.",
slug: "Slug",
slugHint: "— строчные буквы, дефисы, например atm10-server",
displayName: "Отображаемое имя",
displayNameHint: "(необязательно)",
description: "Описание",
descriptionHint: "(необязательно)",
icon: "Значок",
iconHint: "(один символ или эмодзи)",
switchAfterCreate: "Переключиться на эту доску после создания",
cancel: "Отмена",
creating: "Создание…",
createBoard: "Создать доску",
search: "Поиск",
filterCards: "Фильтр карточек…",
tenant: "Tenant",
allTenants: "Все tenant'ы",
assignee: "Исполнитель",
allProfiles: "Все профили",
showArchived: "Показать архив",
lanesByProfile: "Дорожки по профилю",
nudgeDispatcher: "Подтолкнуть диспетчер",
refresh: "Обновить",
selected: "выбрано",
complete: "Завершить",
archive: "В архив",
apply: "Применить",
clear: "Очистить",
createTask: "Создать задачу в этой колонке",
noTasks: "— нет задач —",
unassigned: "без исполнителя",
untitled: "(без названия)",
loadingDetail: "Загрузка…",
addComment: "Добавить комментарий… (Enter — отправить)",
comment: "Комментарий",
status: "Статус",
workspace: "Рабочая область",
skills: "Навыки",
createdBy: "Создал",
result: "Результат",
comments: "Комментарии",
events: "События",
runHistory: "История запусков",
workerLog: "Журнал воркера",
loadingLog: "Загрузка журнала…",
noWorkerLog:
"— журнала воркера ещё нет (задача не запускалась или журнал был ротирован) —",
noDescription: "— нет описания —",
noComments: "— нет комментариев —",
edit: "изменить",
save: "Сохранить",
dependencies: "Зависимости",
parents: "Родители:",
children: "Потомки:",
none: "нет",
addParent: "— добавить родителя —",
addChild: "— добавить потомка —",
removeDependency: "Удалить зависимость",
block: "Заблокировать",
unblock: "Разблокировать",
notifyHomeChannels: "Уведомить домашние каналы",
diagnostics: "Диагностика",
hide: "Скрыть",
show: "Показать",
attention: "Внимание",
tasksNeedAttention: "задач(и) требуют внимания",
taskNeedsAttention: "1 задача требует внимания",
diagnostic: "диагностика",
open: "Открыть",
close: "Закрыть (Esc)",
reassignTo: "Переназначить на:",
copied: "Скопировано",
copyCommand: "Скопировать команду в буфер обмена",
reclaim: "Вернуть",
reassign: "Переназначить",
renderingError: "Во вкладке Kanban произошла ошибка отрисовки",
reloadView: "Перезагрузить вид",
wsAuthFailed:
"Сбой аутентификации WebSocket — перезагрузите страницу, чтобы обновить токен сессии.",
markDone: "Отметить {n} задач(и) как выполненные?",
markArchived: "Архивировать {n} задач(и)?",
warning: "Предупреждение",
phantomIds: "Фантомные id:",
active: "активно",
ended: "завершено",
noProfile: "(нет профиля)",
showAllAttempts: "Показать все попытки",
sendingUpdates: "Отправка обновлений в",
sendNotifications: "Отправлять уведомления completed / blocked / gave_up в",
archiveBoardConfirm:
"Архивировать доску '{name}'? Она будет перемещена в boards/_archived/, чтобы её можно было восстановить позже. Задачи этой доски больше не будут отображаться нигде в интерфейсе.",
archiveBoardTitle: "Архивировать эту доску",
boardSwitcherHint: "Доски позволяют разделять не связанные между собой потоки работы",
taskCreatedWarning: "Задача создана, но: ",
moveFailed: "Не удалось переместить: ",
bulkFailed: "Массовая операция: ",
completionBlockedHallucination: "⚠ Завершение заблокировано — фантомные id карточек",
suspectedHallucinatedReferences: "⚠ В тексте упомянуты фантомные id карточек",
pickProfileFirst: "Сначала выберите профиль.",
unblockedMessage: "{id} разблокирована. Задача готова к следующему тику.",
unblockFailed: "Не удалось разблокировать: ",
reclaimedMessage: "{id} возвращена. Задача снова в состоянии ready.",
reclaimFailed: "Не удалось вернуть: ",
reassignedMessage: "{id} переназначена на {profile}.",
reassignFailed: "Не удалось переназначить: ",
selectForBulk: "Выбрать для массовых действий",
clickToEdit: "Нажмите, чтобы изменить",
clickToEditAssignee: "Нажмите, чтобы изменить исполнителя",
emptyAssignee: "(пусто = снять назначение)",
columnLabels: {
triage: "Сортировка",
todo: "К выполнению",
ready: "Готово к работе",
running: "В работе",
blocked: "Заблокировано",
done: "Готово",
archived: "В архиве",
},
columnHelp: {
triage: "Сырые идеи — specifier подготовит спецификацию",
todo: "Ожидает зависимостей или без исполнителя",
ready: "Назначено и ждёт тика диспетчера",
running: "Взято воркером — выполняется",
blocked: "Воркер запросил вмешательство человека",
done: "Завершено",
archived: "В архиве",
},
confirmDone:
"Отметить эту задачу как выполненную? Захват воркера будет освобождён, а зависимые потомки станут готовыми.",
confirmArchive:
"Архивировать эту задачу? Она исчезнет из стандартного вида доски.",
confirmBlocked:
"Отметить эту задачу как заблокированную? Захват воркера будет освобождён.",
completionSummary:
"Сводка завершения для {label}. Сохраняется как результат задачи.",
completionSummaryRequired:
"Перед отметкой задачи как выполненной требуется сводка завершения.",
triagePlaceholder: "Черновая идея — ИИ её проспецифицирует…",
taskTitlePlaceholder: "Название новой задачи…",
specifier: "specifier",
assigneePlaceholder: "исполнитель",
priority: "Приоритет",
skillsPlaceholder:
"навыки (необязательно, через запятую): translation, github-code-review",
noParent: "— без родителя —",
workspacePathDir: "путь к рабочей области (обязательно, например ~/projects/my-app)",
workspacePathOptional:
"путь к рабочей области (необязательно, выводится из исполнителя, если не указан)",
logTruncated: "(показаны последние 100 KB — полный журнал в ",
logAt: ")",
},
};

696
web/src/i18n/tr.ts Normal file
View file

@ -0,0 +1,696 @@
import type { Translations } from "./types";
export const tr: Translations = {
common: {
save: "Kaydet",
saving: "Kaydediliyor...",
cancel: "İptal",
close: "Kapat",
confirm: "Onayla",
delete: "Sil",
refresh: "Yenile",
retry: "Yeniden dene",
search: "Ara...",
loading: "Yükleniyor...",
create: "Oluştur",
creating: "Oluşturuluyor...",
set: "Ayarla",
replace: "Değiştir",
clear: "Temizle",
live: "Canlı",
off: "Kapalı",
enabled: "etkin",
disabled: "devre dışı",
active: "aktif",
inactive: "pasif",
unknown: "bilinmiyor",
untitled: "Başlıksız",
none: "Yok",
form: "Form",
noResults: "Sonuç yok",
of: "/",
page: "Sayfa",
msgs: "mesaj",
tools: "araçlar",
match: "eşleşme",
other: "Diğer",
configured: "yapılandırıldı",
removed: "kaldırıldı",
failedToToggle: "Değiştirilemedi",
failedToRemove: "Kaldırılamadı",
failedToReveal: "Gösterilemedi",
collapse: "Daralt",
expand: "Genişlet",
general: "Genel",
messaging: "Mesajlaşma",
pluginLoadFailed:
"Bu eklentinin betiği yüklenemedi. Ağ sekmesini (dashboard-plugins/…) ve sunucunun eklenti yolunu kontrol edin.",
pluginNotRegistered:
"Eklenti betiği register() çağırmadı veya betik hata verdi. Ayrıntılar için tarayıcı konsolunu açın.",
},
app: {
brand: "Hermes Agent",
brandShort: "HA",
closeNavigation: "Gezintiyi kapat",
closeModelTools: "Modeli ve araçları kapat",
footer: {
org: "Nous Research",
},
activeSessionsLabel: "Aktif Oturumlar:",
gatewayStatusLabel: "Ağ Geçidi Durumu:",
gatewayStrip: {
failed: "Başlatma başarısız",
off: "Kapalı",
running: "Çalışıyor",
starting: "Başlatılıyor",
stopped: "Durduruldu",
},
nav: {
analytics: "Analiz",
chat: "Sohbet",
config: "Yapılandırma",
cron: "Cron",
documentation: "Dokümantasyon",
keys: "Anahtarlar",
logs: "Günlükler",
models: "Modeller",
profiles: "profiller : çoklu agent",
plugins: "Eklentiler",
sessions: "Oturumlar",
skills: "Yetenekler",
},
modelToolsSheetSubtitle: "& araçlar",
modelToolsSheetTitle: "Model",
navigation: "Gezinti",
openDocumentation: "Dokümantasyonu yeni sekmede aç",
openNavigation: "Gezintiyi aç",
pluginNavSection: "Eklentiler",
sessionsActiveCount: "{count} aktif",
statusOverview: "Durum özeti",
system: "Sistem",
webUi: "Web UI",
},
status: {
actionFailed: "İşlem başarısız",
actionFinished: "Tamamlandı",
actions: "İşlemler",
agent: "Agent",
activeSessions: "Aktif Oturumlar",
connected: "Bağlandı",
connectedPlatforms: "Bağlı Platformlar",
disconnected: "Bağlantı kesildi",
error: "Hata",
failed: "Başarısız",
gateway: "Ağ Geçidi",
gatewayFailedToStart: "Ağ geçidi başlatılamadı",
lastUpdate: "Son güncelleme",
noneRunning: "Yok",
notRunning: "Çalışmıyor",
pid: "PID",
platformDisconnected: "bağlantı kesildi",
platformError: "hata",
recentSessions: "Son Oturumlar",
restartGateway: "Ağ Geçidini Yeniden Başlat",
restartingGateway: "Ağ geçidi yeniden başlatılıyor…",
running: "Çalışıyor",
runningRemote: "Çalışıyor (uzak)",
startFailed: "Başlatma başarısız",
starting: "Başlatılıyor",
startedInBackground: "Arka planda başlatıldı — ilerleme için günlüklere bakın",
stopped: "Durduruldu",
updateHermes: "Hermes'i Güncelle",
updatingHermes: "Hermes güncelleniyor…",
waitingForOutput: ıktı bekleniyor…",
},
sessions: {
title: "Oturumlar",
searchPlaceholder: "Mesaj içeriğinde ara...",
noSessions: "Henüz oturum yok",
noMatch: "Aramanızla eşleşen oturum yok",
startConversation: "Burada görmek için bir konuşma başlatın",
noMessages: "Mesaj yok",
untitledSession: "Başlıksız oturum",
deleteSession: "Oturumu sil",
confirmDeleteTitle: "Oturum silinsin mi?",
confirmDeleteMessage:
"Bu, konuşmayı ve tüm mesajlarını kalıcı olarak siler. Bu işlem geri alınamaz.",
sessionDeleted: "Oturum silindi",
failedToDelete: "Oturum silinemedi",
resumeInChat: "Sohbette Devam Et",
previousPage: "Önceki sayfa",
nextPage: "Sonraki sayfa",
roles: {
user: "Kullanıcı",
assistant: "Asistan",
system: "Sistem",
tool: "Araç",
},
},
analytics: {
period: "Dönem:",
totalTokens: "Toplam Token",
totalSessions: "Toplam Oturum",
apiCalls: "API Çağrıları",
dailyTokenUsage: "Günlük Token Kullanımı",
dailyBreakdown: "Günlük Dağılım",
perModelBreakdown: "Model Bazında Dağılım",
topSkills: "En Çok Kullanılan Yetenekler",
skill: "Yetenek",
loads: "Agent Yüklendi",
edits: "Agent Yönetildi",
lastUsed: "Son Kullanım",
input: "Giriş",
output: ıkış",
total: "Toplam",
noUsageData: "Bu dönem için kullanım verisi yok",
startSession: "Burada analizleri görmek için bir oturum başlatın",
date: "Tarih",
model: "Model",
tokens: "Token",
perDayAvg: "/gün ort",
acrossModels: "{count} model üzerinden",
inOut: "{input} giriş / {output} çıkış",
},
models: {
modelsUsed: "Kullanılan Modeller",
estimatedCost: "Tahmini Maliyet",
tokens: "token",
sessions: "oturum",
avgPerSession: "ort/oturum",
apiCalls: "API çağrıları",
toolCalls: "araç çağrıları",
noModelsData: "Bu dönem için model kullanım verisi yok",
startSession: "Burada model verilerini görmek için bir oturum başlatın",
},
logs: {
title: "Günlükler",
autoRefresh: "Otomatik yenile",
file: "Dosya",
level: "Seviye",
component: "Bileşen",
lines: "Satırlar",
noLogLines: "Günlük satırı bulunamadı",
},
cron: {
confirmDeleteMessage:
"Bu, görevi zamanlamadan kaldırır. Bu işlem geri alınamaz.",
confirmDeleteTitle: "Zamanlanmış görev silinsin mi?",
newJob: "Yeni Cron Görevi",
nameOptional: "Ad (isteğe bağlı)",
namePlaceholder: "örn. Günlük özet",
prompt: "İstem",
promptPlaceholder: "Agent her çalıştırmada ne yapmalı?",
schedule: "Zamanlama (cron ifadesi)",
schedulePlaceholder: "0 9 * * *",
deliverTo: "Şuraya teslim et",
scheduledJobs: "Zamanlanmış Görevler",
noJobs: "Yapılandırılmış cron görevi yok. Yukarıdan bir tane oluşturun.",
last: "Son",
next: "Sonraki",
pause: "Duraklat",
resume: "Devam ettir",
triggerNow: "Şimdi tetikle",
delivery: {
local: "Yerel",
telegram: "Telegram",
discord: "Discord",
slack: "Slack",
email: "Email",
},
},
profiles: {
newProfile: "Yeni Profil",
name: "Ad",
namePlaceholder: "örn. coder, writer, vb.",
nameRequired: "Ad gereklidir",
nameRule:
"Yalnızca küçük harfler, rakamlar, _ ve - kullanılabilir; harf veya rakamla başlamalı; en fazla 64 karakter.",
invalidName: "Geçersiz profil adı",
cloneFromDefault: "Varsayılan profilden yapılandırmayı klonla",
allProfiles: "Profiller",
noProfiles: "Profil bulunamadı.",
defaultBadge: "varsayılan",
hasEnv: "env",
model: "Model",
skills: "Yetenekler",
rename: "Yeniden adlandır",
editSoul: "SOUL.md'yi düzenle",
soulSection: "SOUL.md (kişilik / sistem istemi)",
soulPlaceholder: "# Bu agent nasıl davranmalı…",
saveSoul: "SOUL'u kaydet",
soulSaved: "SOUL.md kaydedildi",
openInTerminal: "CLI komutunu kopyala",
commandCopied: "Panoya kopyalandı",
copyFailed: "Kopyalanamadı",
confirmDeleteTitle: "Profil silinsin mi?",
confirmDeleteMessage:
"Bu, '{name}' profilini kalıcı olarak siler — yapılandırma, anahtarlar, hatıralar, oturumlar, yetenekler, cron görevleri. Geri alınamaz.",
created: "Oluşturuldu",
deleted: "Silindi",
renamed: "Yeniden adlandırıldı",
},
pluginsPage: {
contextEngineLabel: "Bağlam motoru",
dashboardSlots: "Pano yuvaları",
disableRuntime: "Devre dışı bırak",
enableAfterInstall: "Yüklemeden sonra etkinleştir",
enableRuntime: "Etkinleştir",
forceReinstall: "Yeniden yüklemeyi zorla (önce mevcut klasörü sil)",
headline:
"Hermes eklentilerini keşfedin, yükleyin, etkinleştirin ve güncelleyin (`hermes plugins` ile eşdeğer).",
identifierLabel: "Git URL veya owner/repo",
inactive: "pasif",
installBtn: "Git'ten yükle",
installHeading: "GitHub / Git URL'sinden yükle",
installHint: "owner/repo kısayolunu veya tam https:// ya da git@ klon URL'sini kullanın.",
memoryProviderLabel: "Bellek sağlayıcısı",
missingEnvWarn: "Eklenti çalışmadan önce bunları Anahtarlar bölümünde ayarlayın:",
noDashboardTab: "Pano sekmesi yok",
openTab: "Aç",
orphanHeading: "Yalnızca pano uzantıları (eşleşen agent plugin.yaml yok)",
pluginListHeading: "Yüklü eklentiler",
providerDefaults: "yerleşik / varsayılan",
providersHeading: "Çalışma zamanı sağlayıcı eklentileri",
providersHint:
"config.yaml'a memory.provider (boş = yerleşik) ve context.engine yazar. Bir sonraki oturumda etkili olur.",
refreshDashboard: "Pano uzantılarını yeniden tara",
removeConfirm: "Bu eklenti ~/.hermes/plugins/ içinden kaldırılsın mı?",
removeHint: "Yalnızca ~/.hermes/plugins altındaki kullanıcı tarafından yüklenmiş eklentiler kaldırılabilir.",
rescanHeading: "SPA eklenti kayıt defteri",
rescanHint: "Diske dosya ekledikten sonra yeniden tarayın, böylece pano kenar çubuğu yeni manifestleri algılar.",
runtimeHeading: "Ağ geçidi çalışma zamanı (YAML eklentileri)",
saveProviders: "Sağlayıcı ayarlarını kaydet",
savedProviders: "Sağlayıcı ayarları kaydedildi.",
sourceBadge: "Kaynak",
authRequired: "Kimlik doğrulama gerekli",
authRequiredHint: "Kimlik doğrulamak için bu komutu çalıştırın:",
updateGit: "Git pull",
versionBadge: "Sürüm",
showInSidebar: "Kenar çubuğunda göster",
hideFromSidebar: "Kenar çubuğundan gizle",
},
skills: {
title: "Yetenekler",
searchPlaceholder: "Yetenek ve araç setlerinde ara...",
enabledOf: "{enabled}/{total} etkin",
all: "Tümü",
categories: "Kategoriler",
filters: "Filtreler",
noSkills: "Yetenek bulunamadı. Yetenekler ~/.hermes/skills/ adresinden yüklenir",
noSkillsMatch: "Aramanız veya filtrenizle eşleşen yetenek yok.",
skillCount: "{count} yetenek{s}",
resultCount: "{count} sonuç{s}",
noDescription: "Açıklama mevcut değil.",
toolsets: "Araç setleri",
toolsetLabel: "{name} araç seti",
noToolsetsMatch: "Aramayla eşleşen araç seti yok.",
setupNeeded: "Kurulum gerekli",
disabledForCli: "CLI için devre dışı",
more: "+{count} daha",
},
config: {
configPath: "~/.hermes/config.yaml",
filters: "Filtreler",
sections: "Bölümler",
exportConfig: "Yapılandırmayı JSON olarak dışa aktar",
importConfig: "Yapılandırmayı JSON'dan içe aktar",
resetDefaults: "Varsayılanlara sıfırla",
resetScopeTooltip: "{scope} varsayılanlara sıfırla",
confirmResetScope: "{scope} ayarlarının tümü varsayılanlara sıfırlansın mı? Bu yalnızca formu günceller — değişiklikler Kaydet'e basılana kadar config.yaml'a yazılmaz.",
resetScopeToast: "{scope} varsayılanlara sıfırlandı — gözden geçirip kalıcı kılmak için Kaydet'e basın",
rawYaml: "Ham YAML Yapılandırması",
searchResults: "Arama Sonuçları",
fields: "alan{s}",
noFieldsMatch: '"{query}" ile eşleşen alan yok',
configSaved: "Yapılandırma kaydedildi",
yamlConfigSaved: "YAML yapılandırması kaydedildi",
failedToSave: "Kaydedilemedi",
failedToSaveYaml: "YAML kaydedilemedi",
failedToLoadRaw: "Ham yapılandırma yüklenemedi",
configImported: "Yapılandırma içe aktarıldı — gözden geçirip kaydedin",
invalidJson: "Geçersiz JSON dosyası",
categories: {
general: "Genel",
agent: "Agent",
terminal: "Terminal",
display: "Görüntü",
delegation: "Yetkilendirme",
memory: "Bellek",
compression: "Sıkıştırma",
security: "Güvenlik",
browser: "Tarayıcı",
voice: "Ses",
tts: "Metinden Konuşmaya",
stt: "Konuşmadan Metne",
logging: "Günlükleme",
discord: "Discord",
auxiliary: "Yardımcı",
},
},
env: {
changesNote: "Değişiklikler diske hemen kaydedilir. Aktif oturumlar yeni anahtarları otomatik olarak alır.",
confirmClearMessage:
"Bu değişken için saklanan değer .env dosyanızdan kaldırılacak. Bu işlem arayüzden geri alınamaz.",
confirmClearTitle: "Bu anahtar temizlensin mi?",
description: "Şurada saklanan API anahtarlarını ve sırları yönetin",
hideAdvanced: "Gelişmişi Gizle",
showAdvanced: "Gelişmişi Göster",
llmProviders: "LLM Sağlayıcıları",
providersConfigured: "{configured}/{total} sağlayıcı yapılandırıldı",
getKey: "Anahtar al",
notConfigured: "{count} yapılandırılmamış",
notSet: "Ayarlanmadı",
keysCount: "{count} anahtar",
enterValue: "Değer girin...",
replaceCurrentValue: "Mevcut değeri değiştir ({preview})",
showValue: "Gerçek değeri göster",
hideValue: "Değeri gizle",
},
oauth: {
title: "Sağlayıcı Girişleri (OAuth)",
providerLogins: "Sağlayıcı Girişleri (OAuth)",
description: "{connected}/{total} OAuth sağlayıcısı bağlandı. Giriş akışları şu anda CLI üzerinden çalışır; Komutu kopyala'ya tıklayın ve kurmak için bir terminale yapıştırın.",
connected: "Bağlandı",
expired: "Süresi doldu",
notConnected: "Bağlı değil. Bir terminalde {command} komutunu çalıştırın.",
runInTerminal: "bir terminalde.",
noProviders: "OAuth uyumlu sağlayıcı algılanmadı.",
login: "Giriş",
disconnect: "Bağlantıyı kes",
managedExternally: "Harici olarak yönetiliyor",
copied: "Kopyalandı ✓",
cli: "CLI",
copyCliCommand: "CLI komutunu kopyala (harici / yedek için)",
connect: "Bağlan",
sessionExpires: "Oturumun süresi {time} sonra dolacak",
initiatingLogin: "Giriş akışı başlatılıyor…",
exchangingCode: "Kod, jetonlarla değiştiriliyor…",
connectedClosing: "Bağlandı! Kapatılıyor…",
loginFailed: "Giriş başarısız.",
sessionExpired: "Oturum süresi doldu. Yeni bir giriş başlatmak için Yeniden Dene'ye tıklayın.",
reOpenAuth: "Kimlik doğrulama sayfasını yeniden aç",
reOpenVerification: "Doğrulama sayfasını yeniden aç",
submitCode: "Kodu gönder",
pasteCode: "Yetkilendirme kodunu yapıştırın (#state ekiyle de olabilir)",
waitingAuth: "Tarayıcıda yetkilendirmeniz bekleniyor…",
enterCodePrompt: "Yeni bir sekme açıldı. İstenirse bu kodu girin:",
pkceStep1: "claude.ai için yeni bir sekme açıldı. Giriş yapın ve Yetkilendir'e tıklayın.",
pkceStep2: "Yetkilendirmeden sonra gösterilen yetkilendirme kodunu kopyalayın.",
pkceStep3: "Aşağıya yapıştırıp gönderin.",
flowLabels: {
pkce: "Tarayıcı girişi (PKCE)",
device_code: "Cihaz kodu",
external: "Harici CLI",
},
expiresIn: "{time} sonra sona erer",
},
language: {
switchTo: "İngilizce'ye geç",
},
theme: {
title: "Tema",
switchTheme: "Temayı değiştir",
},
achievements: {
hero: {
kicker: "Agentic Gamerscore",
title: "Hermes Achievements",
subtitle:
"Gerçek oturum geçmişinden kazanılan, koleksiyonluk Hermes rozetleri. Bilinen ama henüz tamamlanmamış başarılar Keşfedildi olarak gösterilir; Gizli başarılar ilk eşleşen davranış görünene kadar saklı kalır.",
scan_subtitle:
"Hermes oturum geçmişi taranıyor. Büyük geçmişlerde ilk tarama 510 saniye sürebilir.",
},
actions: {
rescan: "Yeniden tara",
},
stats: {
unlocked: "Açıldı",
unlocked_hint: "kazanılan rozetler",
discovered: "Keşfedildi",
discovered_hint: "biliniyor, henüz kazanılmadı",
secrets: "Sırlar",
secrets_hint: "ilk sinyale kadar gizli",
highest_tier: "En yüksek kademe",
highest_tier_hint: "Copper → Silver → Gold → Diamond → Olympian",
latest: "En son",
latest_hint_empty: "Hermes'i daha çok çalıştır",
none_yet: "Henüz yok",
},
state: {
unlocked: "Açıldı",
discovered: "Keşfedildi",
secret: "Gizli",
},
tier: {
target: "Hedef {tier}",
hidden: "Gizli",
complete: "Tamamlandı",
objective: "Amaç",
},
progress: {
hidden: "gizli",
},
scan: {
building_headline: "Başarı profili oluşturuluyor…",
building_detail:
"Oturumlar, araç çağrıları, model meta verileri ve açılma durumu okunuyor.",
starting_headline: "Başarı taraması başlatılıyor…",
progress_detail:
"{total} oturumun {scanned} tanesi tarandı · %{pct}. Daha fazla geçmiş aktıkça rozetler açılır.",
idle_detail:
"Oturumlar, araç çağrıları, model meta verileri ve açılma durumu okunuyor. Rozetler açıldıkça burada görünür.",
},
guide: {
tiers_header: "Kademeler",
secret_header: "Gizli başarılar",
secret_body:
"Sırlar, tetikleyicilerini saklı tutar. Hermes ilgili bir sinyal gördüğünde kart Keşfedildi durumuna geçer ve gereksinimini gösterir.",
scan_status_header: "Tarama durumu",
scan_status_body:
"Hermes yerel geçmişi bir kez tarıyor; sonra kartlar otomatik olarak görünür. Birkaç saniye sürmesi normaldir, hiçbir şey takılmadı.",
what_scanned_header: "Neler taranır",
what_scanned_body:
"Oturumlar, araç çağrıları, model meta verileri, hatalar, başarılar ve yerel açılma durumu.",
},
card: {
share_title: "Bu başarıyı paylaş",
share_label: "{name} paylaş",
share_text: "Paylaş",
how_to_reveal: "Nasıl ortaya çıkarılır",
what_counts: "Neler sayılır",
evidence_label: "Kanıt",
evidence_session_fallback: "oturum",
no_evidence: "Henüz kanıt yok",
},
latest: {
header: "Son açılanlar",
},
empty: {
no_secrets_header: "Bu taramada gizli sır kalmadı.",
no_secrets_body:
"İpucu: sırlar genellikle alışılmadık hata veya ileri kullanıcı kalıplarıyla başlar — port çakışmaları, izin duvarları, eksik ortam değişkenleri, YAML hataları, Docker çakışmaları, geri alma/checkpoint kullanımı, önbellek isabetleri ya da çokça kırmızı yazıdan sonra yapılan ufak düzeltmeler.",
},
filters: {
all_categories: "Tümü",
visibility_all: "tümü",
visibility_unlocked: "açıldı",
visibility_discovered: "keşfedildi",
visibility_secret: "gizli",
},
share: {
dialog_label: "Başarıyı paylaş",
header: "Paylaş: {name}",
close: "Kapat",
rendering: "Oluşturuluyor…",
card_alt: "{name} paylaşım kartı",
error_generic: "Bir şeyler ters gitti.",
x_title: "X'i önceden doldurulmuş bir gönderiyle açar",
x_button: "X'te paylaş",
copy_title: "Görseli kopyalayıp gönderine yapıştır",
copy_button: "Görseli kopyala",
copied: "Kopyalandı ✓",
download_button: "PNG indir",
hint:
"X'te paylaş, yeni sekmede önceden doldurulmuş bir gönderi açar. 1200×630 rozetin eklenmesini istiyorsan önce Görseli kopyala'ya tıkla — X, görseli doğrudan tweet düzenleyiciye yapıştırmana izin verir. PNG indir, dosyayı her yerde kullanmak üzere kaydeder.",
clipboard_unsupported:
"Bu tarayıcıda panoya görsel kopyalama desteklenmiyor — bunun yerine İndir'i kullanın.",
tweet_text: "Just unlocked {tier_part}\"{name}\" in Hermes Agent ☤",
},
},
kanban: {
loading: "Kanban panosu yükleniyor…",
loadFailed: "Kanban panosu yüklenemedi: ",
loadFailedHint:
"Backend, ilk okumada kanban.db'yi otomatik olarak oluşturur. Sorun devam ederse panel günlüklerini kontrol edin.",
board: "Pano",
newBoard: "+ Yeni pano",
newBoardTitle: "Yeni pano",
newBoardDescription:
"Panolar, ilgisiz iş akışlarını ayırmanızı sağlar — proje, depo veya alan başına bir pano. Bir panodaki worker'lar başka bir panonun görevlerini asla görmez.",
slug: "Slug",
slugHint: "— küçük harf, tire, ör. atm10-server",
displayName: "Görünen ad",
displayNameHint: "(isteğe bağlı)",
description: "Açıklama",
descriptionHint: "(isteğe bağlı)",
icon: "Simge",
iconHint: "(tek karakter veya emoji)",
switchAfterCreate: "Oluşturduktan sonra bu panoya geç",
cancel: "İptal",
creating: "Oluşturuluyor…",
createBoard: "Pano oluştur",
search: "Ara",
filterCards: "Kartları filtrele…",
tenant: "Tenant",
allTenants: "Tüm tenant'lar",
assignee: "Atanan kişi",
allProfiles: "Tüm profiller",
showArchived: "Arşivlenenleri göster",
lanesByProfile: "Profile göre şeritler",
nudgeDispatcher: "Dispatcher'ı dürt",
refresh: "Yenile",
selected: "seçili",
complete: "Tamamla",
archive: "Arşivle",
apply: "Uygula",
clear: "Temizle",
createTask: "Bu sütunda görev oluştur",
noTasks: "— görev yok —",
unassigned: "atanmamış",
untitled: "(başlıksız)",
loadingDetail: "Yükleniyor…",
addComment: "Yorum ekle… (göndermek için Enter)",
comment: "Yorum",
status: "Durum",
workspace: "Workspace",
skills: "Beceriler",
createdBy: "Oluşturan",
result: "Result",
comments: "Yorumlar",
events: "Olaylar",
runHistory: "Çalıştırma geçmişi",
workerLog: "Worker günlüğü",
loadingLog: "Günlük yükleniyor…",
noWorkerLog:
"— henüz worker günlüğü yok (görev başlatılmadı veya günlük döndürüldü) —",
noDescription: "— açıklama yok —",
noComments: "— yorum yok —",
edit: "düzenle",
save: "Kaydet",
dependencies: "Bağımlılıklar",
parents: "Üstler:",
children: "Altlar:",
none: "yok",
addParent: "— üst ekle —",
addChild: "— alt ekle —",
removeDependency: "Bağımlılığı kaldır",
block: "Engelle",
unblock: "Engeli kaldır",
notifyHomeChannels: "Ana kanalları bilgilendir",
diagnostics: "Tanılama",
hide: "Gizle",
show: "Göster",
attention: "Dikkat",
tasksNeedAttention: "görev dikkat gerektiriyor",
taskNeedsAttention: "1 görev dikkat gerektiriyor",
diagnostic: "tanılama",
open: "Aç",
close: "Kapat (Esc)",
reassignTo: "Yeniden ata:",
copied: "Kopyalandı",
copyCommand: "Komutu panoya kopyala",
reclaim: "Geri al",
reassign: "Yeniden ata",
renderingError: "Kanban sekmesinde bir oluşturma hatası oluştu",
reloadView: "Görünümü yeniden yükle",
wsAuthFailed:
"WebSocket kimlik doğrulaması başarısız — oturum jetonunu yenilemek için sayfayı yeniden yükleyin.",
markDone: "{n} görev tamamlandı olarak işaretlensin mi?",
markArchived: "{n} görev arşivlensin mi?",
warning: "Uyarı",
phantomIds: "Hayalet ID'ler:",
active: "etkin",
ended: "sona erdi",
noProfile: "(profil yok)",
showAllAttempts: "Tüm denemeleri göster",
sendingUpdates: "Güncellemeler şuraya gönderiliyor",
sendNotifications: "completed / blocked / gave_up bildirimlerini şuraya gönder",
archiveBoardConfirm:
"'{name}' panosu arşivlensin mi? boards/_archived/ dizinine taşınacak, böylece daha sonra kurtarabilirsiniz. Bu panodaki görevler artık UI'nin hiçbir yerinde görünmeyecek.",
archiveBoardTitle: "Bu panoyu arşivle",
boardSwitcherHint: "Panolar, ilgisiz iş akışlarını ayırmanızı sağlar",
taskCreatedWarning: "Görev oluşturuldu, ancak: ",
moveFailed: "Taşıma başarısız: ",
bulkFailed: "Toplu: ",
completionBlockedHallucination: "⚠ Tamamlanma engellendi — hayalet kart ID'leri",
suspectedHallucinatedReferences: "⚠ Metin hayalet kart ID'lerine atıfta bulundu",
pickProfileFirst: "Önce bir profil seçin.",
unblockedMessage: "{id} engeli kaldırıldı. Görev sonraki tick için hazır.",
unblockFailed: "Engel kaldırma başarısız: ",
reclaimedMessage: "{id} geri alındı. Görev tekrar hazır.",
reclaimFailed: "Geri alma başarısız: ",
reassignedMessage: "{id}, {profile} kişisine yeniden atandı.",
reassignFailed: "Yeniden atama başarısız: ",
selectForBulk: "Toplu işlemler için seç",
clickToEdit: "Düzenlemek için tıklayın",
clickToEditAssignee: "Atanan kişiyi düzenlemek için tıklayın",
emptyAssignee: "(boş = atamayı kaldır)",
columnLabels: {
triage: "Triyaj",
todo: "Yapılacak",
ready: "Hazır",
running: "Sürüyor",
blocked: "Engellendi",
done: "Bitti",
archived: "Arşivlendi",
},
columnHelp: {
triage: "Ham fikirler — bir specifier şartnameyi detaylandıracak",
todo: "Bağımlılıklar bekleniyor veya atanmamış",
ready: "Atanmış ve dispatcher tick'i bekleniyor",
running: "Bir worker tarafından alındı — yürütülüyor",
blocked: "Worker insan girdisi istedi",
done: "Tamamlandı",
archived: "Arşivlendi",
},
confirmDone:
"Bu görev tamamlandı olarak işaretlensin mi? Worker'ın sahiplenmesi serbest bırakılır ve bağımlı altlar hazır hale gelir.",
confirmArchive:
"Bu görev arşivlensin mi? Varsayılan pano görünümünden kaybolur.",
confirmBlocked:
"Bu görev engellendi olarak işaretlensin mi? Worker'ın sahiplenmesi serbest bırakılır.",
completionSummary:
"{label} için tamamlanma özeti. Görev result'ı olarak saklanır.",
completionSummaryRequired:
"Bir görevi tamamlandı olarak işaretlemeden önce tamamlanma özeti gereklidir.",
triagePlaceholder: "Kabataslak fikir — yapay zeka şartnameyi yazacak…",
taskTitlePlaceholder: "Yeni görev başlığı…",
specifier: "specifier",
assigneePlaceholder: "atanan",
priority: "Öncelik",
skillsPlaceholder:
"beceriler (isteğe bağlı, virgülle ayrılmış): translation, github-code-review",
noParent: "— üst yok —",
workspacePathDir: "workspace yolu (zorunlu, ör. ~/projects/my-app)",
workspacePathOptional:
"workspace yolu (isteğe bağlı, boşsa atanan kişiden türetilir)",
logTruncated: "(son 100 KB gösteriliyor — tam günlük şurada: ",
logAt: ")",
},
};

View file

@ -1,4 +1,20 @@
export type Locale = "en" | "zh";
export type Locale =
| "en"
| "zh"
| "zh-hant"
| "ja"
| "de"
| "es"
| "fr"
| "tr"
| "uk"
| "af"
| "ko"
| "it"
| "ga"
| "pt"
| "ru"
| "hu";
export interface Translations {
// ── Common ──
@ -433,4 +449,251 @@ export interface Translations {
title: string;
switchTheme: string;
};
// ── Achievements plugin (plugins/hermes-achievements) ──
achievements: {
hero: {
kicker: string;
title: string;
subtitle: string;
scan_subtitle: string;
};
actions: {
rescan: string;
};
stats: {
unlocked: string;
unlocked_hint: string;
discovered: string;
discovered_hint: string;
secrets: string;
secrets_hint: string;
highest_tier: string;
highest_tier_hint: string;
latest: string;
latest_hint_empty: string;
none_yet: string;
};
state: {
unlocked: string;
discovered: string;
secret: string;
};
tier: {
target: string;
hidden: string;
complete: string;
objective: string;
};
progress: {
hidden: string;
};
scan: {
building_headline: string;
building_detail: string;
starting_headline: string;
progress_detail: string;
idle_detail: string;
};
guide: {
tiers_header: string;
secret_header: string;
secret_body: string;
scan_status_header: string;
scan_status_body: string;
what_scanned_header: string;
what_scanned_body: string;
};
card: {
share_title: string;
share_label: string;
share_text: string;
how_to_reveal: string;
what_counts: string;
evidence_label: string;
evidence_session_fallback: string;
no_evidence: string;
};
latest: {
header: string;
};
empty: {
no_secrets_header: string;
no_secrets_body: string;
};
filters: {
all_categories: string;
visibility_all: string;
visibility_unlocked: string;
visibility_discovered: string;
visibility_secret: string;
};
share: {
dialog_label: string;
header: string;
close: string;
rendering: string;
card_alt: string;
error_generic: string;
x_title: string;
x_button: string;
copy_title: string;
copy_button: string;
copied: string;
download_button: string;
hint: string;
clipboard_unsupported: string;
tweet_text: string;
};
};
// ── Kanban ──
kanban: {
loading: string;
loadFailed: string;
loadFailedHint: string;
board: string;
newBoard: string;
newBoardTitle: string;
newBoardDescription: string;
slug: string;
slugHint: string;
displayName: string;
displayNameHint: string;
description: string;
descriptionHint: string;
icon: string;
iconHint: string;
switchAfterCreate: string;
cancel: string;
creating: string;
createBoard: string;
search: string;
filterCards: string;
tenant: string;
allTenants: string;
assignee: string;
allProfiles: string;
showArchived: string;
lanesByProfile: string;
nudgeDispatcher: string;
refresh: string;
selected: string;
complete: string;
archive: string;
apply: string;
clear: string;
createTask: string;
noTasks: string;
unassigned: string;
untitled: string;
loadingDetail: string;
addComment: string;
comment: string;
status: string;
workspace: string;
skills: string;
createdBy: string;
result: string;
comments: string;
events: string;
runHistory: string;
workerLog: string;
loadingLog: string;
noWorkerLog: string;
noDescription: string;
noComments: string;
edit: string;
save: string;
dependencies: string;
parents: string;
children: string;
none: string;
addParent: string;
addChild: string;
removeDependency: string;
block: string;
unblock: string;
notifyHomeChannels: string;
diagnostics: string;
hide: string;
show: string;
attention: string;
tasksNeedAttention: string;
taskNeedsAttention: string;
diagnostic: string;
open: string;
close: string;
reassignTo: string;
copied: string;
copyCommand: string;
reclaim: string;
reassign: string;
renderingError: string;
reloadView: string;
wsAuthFailed: string;
markDone: string;
markArchived: string;
warning: string;
phantomIds: string;
active: string;
ended: string;
noProfile: string;
showAllAttempts: string;
sendingUpdates: string;
sendNotifications: string;
archiveBoardConfirm: string;
archiveBoardTitle: string;
boardSwitcherHint: string;
taskCreatedWarning: string;
moveFailed: string;
bulkFailed: string;
completionBlockedHallucination: string;
suspectedHallucinatedReferences: string;
pickProfileFirst: string;
unblockedMessage: string;
unblockFailed: string;
reclaimedMessage: string;
reclaimFailed: string;
reassignedMessage: string;
reassignFailed: string;
selectForBulk: string;
clickToEdit: string;
clickToEditAssignee: string;
emptyAssignee: string;
columnLabels: {
triage: string;
todo: string;
ready: string;
running: string;
blocked: string;
done: string;
archived: string;
};
columnHelp: {
triage: string;
todo: string;
ready: string;
running: string;
blocked: string;
done: string;
archived: string;
};
confirmDone: string;
confirmArchive: string;
confirmBlocked: string;
completionSummary: string;
completionSummaryRequired: string;
triagePlaceholder: string;
taskTitlePlaceholder: string;
specifier: string;
assigneePlaceholder: string;
priority: string;
skillsPlaceholder: string;
noParent: string;
workspacePathDir: string;
workspacePathOptional: string;
logTruncated: string;
logAt: string;
};
}

696
web/src/i18n/uk.ts Normal file
View file

@ -0,0 +1,696 @@
import type { Translations } from "./types";
export const uk: 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:
"Не вдалося завантажити скрипт цього плагіна. Перевірте вкладку Network (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: "Cron",
documentation: "Документація",
keys: "Ключі",
logs: "Журнали",
models: "Моделі",
profiles: "профілі: мульти-агенти",
plugins: "Плагіни",
sessions: "Сесії",
skills: "Навички",
},
modelToolsSheetSubtitle: "та інструменти",
modelToolsSheetTitle: "Модель",
navigation: "Навігація",
openDocumentation: "Відкрити документацію в новій вкладці",
openNavigation: "Відкрити навігацію",
pluginNavSection: "Плагіни",
sessionsActiveCount: "{count} активних",
statusOverview: "Огляд стану",
system: "Система",
webUi: "Web UI",
},
status: {
actionFailed: "Дія не вдалася",
actionFinished: "Завершено",
actions: "Дії",
agent: "Агент",
activeSessions: "Активні сесії",
connected: "Підключено",
connectedPlatforms: "Підключені платформи",
disconnected: "Відключено",
error: "Помилка",
failed: "Не вдалося",
gateway: "Шлюз",
gatewayFailedToStart: "Не вдалося запустити шлюз",
lastUpdate: "Останнє оновлення",
noneRunning: "Немає",
notRunning: "Не запущено",
pid: "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: "Усього токенів",
totalSessions: "Усього сесій",
apiCalls: "Виклики API",
dailyTokenUsage: "Щоденне використання токенів",
dailyBreakdown: "Щоденна розбивка",
perModelBreakdown: "Розбивка за моделями",
topSkills: "Топ навичок",
skill: "Навичка",
loads: "Агент завантажив",
edits: "Агент керує",
lastUsed: "Останнє використання",
input: "Вхід",
output: "Вихід",
total: "Усього",
noUsageData: "Немає даних про використання за цей період",
startSession: "Почніть сесію, щоб побачити аналітику тут",
date: "Дата",
model: "Модель",
tokens: "Токени",
perDayAvg: "/день у сер.",
acrossModels: "по {count} моделях",
inOut: "{input} вх. / {output} вих.",
},
models: {
modelsUsed: "Використано моделей",
estimatedCost: "Орієнт. вартість",
tokens: "токени",
sessions: "сесії",
avgPerSession: "сер./сесію",
apiCalls: "виклики API",
toolCalls: "виклики інструментів",
noModelsData: "Немає даних про використання моделей за цей період",
startSession: "Почніть сесію, щоб побачити дані моделей тут",
},
logs: {
title: "Журнали",
autoRefresh: "Автооновлення",
file: "Файл",
level: "Рівень",
component: "Компонент",
lines: "Рядки",
noLogLines: "Записів журналу не знайдено",
},
cron: {
confirmDeleteMessage:
"Це видаляє завдання з розкладу. Цю дію не можна скасувати.",
confirmDeleteTitle: "Видалити заплановане завдання?",
newJob: "Нове Cron-завдання",
nameOptional: "Назва (необов'язково)",
namePlaceholder: "напр. Щоденне зведення",
prompt: "Запит",
promptPlaceholder: "Що агент має робити при кожному запуску?",
schedule: "Розклад (cron-вираз)",
schedulePlaceholder: "0 9 * * *",
deliverTo: "Надіслати на",
scheduledJobs: "Заплановані завдання",
noJobs: "Cron-завдань не налаштовано. Створіть одне вище.",
last: "Останнє",
next: "Наступне",
pause: "Призупинити",
resume: "Відновити",
triggerNow: "Запустити зараз",
delivery: {
local: "Локально",
telegram: "Telegram",
discord: "Discord",
slack: "Slack",
email: "Email",
},
},
profiles: {
newProfile: "Новий профіль",
name: "Назва",
namePlaceholder: "напр. coder, writer тощо.",
nameRequired: "Назва обов'язкова",
nameRule:
"Лише малі літери, цифри, _ та -; має починатися з літери або цифри; до 64 символів.",
invalidName: "Недопустима назва профілю",
cloneFromDefault: "Клонувати конфігурацію з профілю за замовчуванням",
allProfiles: "Профілі",
noProfiles: "Профілів не знайдено.",
defaultBadge: "за замовчуванням",
hasEnv: "env",
model: "Модель",
skills: "Навички",
rename: "Перейменувати",
editSoul: "Редагувати SOUL.md",
soulSection: "SOUL.md (особистість / системний запит)",
soulPlaceholder: "# Як цей агент має поводитися…",
saveSoul: "Зберегти SOUL",
soulSaved: "SOUL.md збережено",
openInTerminal: "Скопіювати CLI-команду",
commandCopied: "Скопійовано в буфер обміну",
copyFailed: "Не вдалося скопіювати",
confirmDeleteTitle: "Видалити профіль?",
confirmDeleteMessage:
"Це назавжди видаляє профіль '{name}' — конфігурацію, ключі, спогади, сесії, навички, cron-завдання. Не можна скасувати.",
created: "Створено",
deleted: "Видалено",
renamed: "Перейменовано",
},
pluginsPage: {
contextEngineLabel: "Контекстний рушій",
dashboardSlots: "Слоти панелі",
disableRuntime: "Вимкнути",
enableAfterInstall: "Увімкнути після встановлення",
enableRuntime: "Увімкнути",
forceReinstall: "Примусово перевстановити (спершу видалити наявну теку)",
headline:
"Знаходьте, встановлюйте, вмикайте та оновлюйте плагіни Hermes (паритет з `hermes plugins`).",
identifierLabel: "Git URL або owner/repo",
inactive: "неактивний",
installBtn: "Встановити з Git",
installHeading: "Встановити з GitHub / Git URL",
installHint: "Використовуйте скорочення owner/repo або повну https:// чи git@ URL для клонування.",
memoryProviderLabel: "Постачальник пам'яті",
missingEnvWarn: "Встановіть їх у Keys, перш ніж плагін зможе працювати:",
noDashboardTab: "Немає вкладки панелі",
openTab: "Відкрити",
orphanHeading: "Розширення лише для панелі (без відповідного agent plugin.yaml)",
pluginListHeading: "Встановлені плагіни",
providerDefaults: "вбудований / за замовчуванням",
providersHeading: "Плагіни постачальників часу виконання",
providersHint:
"Записує memory.provider (порожньо = вбудований) та context.engine у config.yaml. Набуває чинності в наступній сесії.",
refreshDashboard: "Перескан розширень панелі",
removeConfirm: "Видалити цей плагін з ~/.hermes/plugins/?",
removeHint: "Видаляти можна лише плагіни, встановлені користувачем у ~/.hermes/plugins.",
rescanHeading: "Реєстр SPA-плагінів",
rescanHint: "Скануйте після додавання файлів на диск, щоб бічна панель підхопила нові маніфести.",
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-файлу. Цю дію не можна скасувати з UI.",
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. Увійдіть та натисніть Authorize.",
pkceStep2: "Скопіюйте код авторизації, що відображається після авторизації.",
pkceStep3: "Вставте його нижче та надішліть.",
flowLabels: {
pkce: "Вхід через браузер (PKCE)",
device_code: "Код пристрою",
external: "Зовнішній CLI",
},
expiresIn: "завершується через {time}",
},
language: {
switchTo: "Перемкнути на англійську",
},
theme: {
title: "Тема",
switchTheme: "Змінити тему",
},
achievements: {
hero: {
kicker: "Agentic Gamerscore",
title: "Hermes Achievements",
subtitle:
"Колекційні значки Hermes, отримані з реальної історії сеансів. Відомі, але ще не виконані досягнення показані як Виявлені; Секретні досягнення залишаються прихованими, доки не з'явиться перший відповідний сигнал.",
scan_subtitle:
"Сканування історії сеансів Hermes. Перше сканування на великих історіях може тривати 510 секунд.",
},
actions: {
rescan: "Повторне сканування",
},
stats: {
unlocked: "Розблоковано",
unlocked_hint: "отримані значки",
discovered: "Виявлено",
discovered_hint: "відомі, ще не отримані",
secrets: "Секрети",
secrets_hint: "приховані до першого сигналу",
highest_tier: "Найвищий рівень",
highest_tier_hint: "Copper → Silver → Gold → Diamond → Olympian",
latest: "Останнє",
latest_hint_empty: "запускайте Hermes частіше",
none_yet: "Поки немає",
},
state: {
unlocked: "Розблоковано",
discovered: "Виявлено",
secret: "Секрет",
},
tier: {
target: "Ціль {tier}",
hidden: "Приховано",
complete: "Завершено",
objective: "Завдання",
},
progress: {
hidden: "приховано",
},
scan: {
building_headline: "Побудова профілю досягнень…",
building_detail:
"Читання сеансів, викликів інструментів, метаданих моделей і стану розблокування.",
starting_headline: "Запуск сканування досягнень…",
progress_detail:
"Проскановано {scanned} з {total} сеансів · {pct}%. Значки розблоковуються в міру надходження історії.",
idle_detail:
"Читання сеансів, викликів інструментів, метаданих моделей і стану розблокування. Значки з'являються тут у міру розблокування.",
},
guide: {
tiers_header: "Рівні",
secret_header: "Секретні досягнення",
secret_body:
"Секрети приховують свій точний тригер. Щойно Hermes побачить пов'язаний сигнал, картка стає Виявленою та показує свою умову.",
scan_status_header: "Стан сканування",
scan_status_body:
"Hermes одноразово сканує локальну історію, а потім картки з'являться автоматично. Якщо це триває кілька секунд — нічого не зависло.",
what_scanned_header: "Що сканується",
what_scanned_body:
"Сеанси, виклики інструментів, метадані моделей, помилки, досягнення та локальний стан розблокування.",
},
card: {
share_title: "Поділитися цим досягненням",
share_label: "Поділитися {name}",
share_text: "Поділитися",
how_to_reveal: "Як розкрити",
what_counts: "Що зараховується",
evidence_label: "Доказ",
evidence_session_fallback: "сеанс",
no_evidence: "Доказів поки немає",
},
latest: {
header: "Нещодавні розблокування",
},
empty: {
no_secrets_header: "У цьому скануванні не залишилося прихованих секретів.",
no_secrets_body:
"Підказка: секрети зазвичай починаються з незвичних збоїв або шаблонів досвідчених користувачів — конфлікти портів, стіни дозволів, відсутні змінні середовища, помилки YAML, колізії Docker, відкат/контрольні точки, влучання в кеш або дрібні виправлення після купи червоного тексту.",
},
filters: {
all_categories: "Усі",
visibility_all: "усі",
visibility_unlocked: "розблоковано",
visibility_discovered: "виявлено",
visibility_secret: "секрет",
},
share: {
dialog_label: "Поділитися досягненням",
header: "Поділитися: {name}",
close: "Закрити",
rendering: "Рендеринг…",
card_alt: "Картка для поширення {name}",
error_generic: "Щось пішло не так.",
x_title: "Відкриває X із попередньо заповненим дописом",
x_button: "Поділитися в X",
copy_title: "Скопіюйте зображення, щоб вставити у свій допис",
copy_button: "Копіювати зображення",
copied: "Скопійовано ✓",
download_button: "Завантажити PNG",
hint:
"«Поділитися в X» відкриває попередньо заповнений допис у новій вкладці. Якщо хочете прикріпити значок 1200×630 — спочатку натисніть «Копіювати зображення»: X дозволить вставити його прямо в редактор твіта. «Завантажити PNG» збереже файл для використання будь-де.",
clipboard_unsupported:
"Цей браузер не підтримує копіювання зображень у буфер обміну — використайте «Завантажити».",
tweet_text: "Just unlocked {tier_part}\"{name}\" in Hermes Agent ☤",
},
},
kanban: {
loading: "Завантаження дошки Kanban…",
loadFailed: "Не вдалося завантажити дошку Kanban: ",
loadFailedHint:
"Бекенд автоматично створює kanban.db під час першого читання. Якщо помилка не зникає, перевірте журнали панелі.",
board: "Дошка",
newBoard: "+ Нова дошка",
newBoardTitle: "Нова дошка",
newBoardDescription:
"Дошки дозволяють розділяти непов'язані потоки роботи — по одній на проєкт, репозиторій або домен. Воркери на одній дошці ніколи не бачать задач іншої дошки.",
slug: "Slug",
slugHint: "— рядкові літери, дефіси, напр. atm10-server",
displayName: "Відображувана назва",
displayNameHint: "(необов'язково)",
description: "Опис",
descriptionHint: "(необов'язково)",
icon: "Іконка",
iconHint: "(один символ або емодзі)",
switchAfterCreate: "Перейти на цю дошку після створення",
cancel: "Скасувати",
creating: "Створення…",
createBoard: "Створити дошку",
search: "Пошук",
filterCards: "Фільтрувати картки…",
tenant: "Орендар",
allTenants: "Усі орендарі",
assignee: "Виконавець",
allProfiles: "Усі профілі",
showArchived: "Показати архівовані",
lanesByProfile: "Доріжки за профілем",
nudgeDispatcher: "Підштовхнути диспетчер",
refresh: "Оновити",
selected: "вибрано",
complete: "Завершити",
archive: "Архівувати",
apply: "Застосувати",
clear: "Очистити",
createTask: "Створити задачу в цьому стовпці",
noTasks: "— немає задач —",
unassigned: "не призначено",
untitled: "(без назви)",
loadingDetail: "Завантаження…",
addComment: "Додати коментар… (Enter для надсилання)",
comment: "Коментар",
status: "Статус",
workspace: "Робоча область",
skills: "Навички",
createdBy: "Створив",
result: "Результат",
comments: "Коментарі",
events: "Події",
runHistory: "Історія запусків",
workerLog: "Журнал воркера",
loadingLog: "Завантаження журналу…",
noWorkerLog:
"— журналу воркера ще немає (задачу не запущено або журнал ротаційно видалено) —",
noDescription: "— немає опису —",
noComments: "— немає коментарів —",
edit: "редагувати",
save: "Зберегти",
dependencies: "Залежності",
parents: "Батьки:",
children: "Нащадки:",
none: "немає",
addParent: "— додати батька —",
addChild: "— додати нащадка —",
removeDependency: "Видалити залежність",
block: "Заблокувати",
unblock: "Розблокувати",
notifyHomeChannels: "Повідомити домашні канали",
diagnostics: "Діагностика",
hide: "Приховати",
show: "Показати",
attention: "Увага",
tasksNeedAttention: "задач потребують уваги",
taskNeedsAttention: "1 задача потребує уваги",
diagnostic: "діагностика",
open: "Відкрити",
close: "Закрити (Esc)",
reassignTo: "Перепризначити на:",
copied: "Скопійовано",
copyCommand: "Скопіювати команду в буфер обміну",
reclaim: "Повернути",
reassign: "Перепризначити",
renderingError: "На вкладці Kanban сталася помилка рендерингу",
reloadView: "Перезавантажити вигляд",
wsAuthFailed:
"Помилка автентифікації WebSocket — перезавантажте сторінку, щоб оновити токен сесії.",
markDone: "Позначити {n} задач(у) як виконані?",
markArchived: "Архівувати {n} задач(у)?",
warning: "Попередження",
phantomIds: "Фантомні id:",
active: "активна",
ended: "завершена",
noProfile: "(немає профілю)",
showAllAttempts: "Показати всі спроби",
sendingUpdates: "Надсилання оновлень до",
sendNotifications: "Надсилати сповіщення completed / blocked / gave_up до",
archiveBoardConfirm:
"Архівувати дошку «{name}»? Її буде переміщено до boards/_archived/, тож пізніше її можна відновити. Задачі цієї дошки більше не з'являтимуться в інтерфейсі.",
archiveBoardTitle: "Архівувати цю дошку",
boardSwitcherHint: "Дошки дозволяють розділяти непов'язані потоки роботи",
taskCreatedWarning: "Задачу створено, але: ",
moveFailed: "Переміщення не вдалося: ",
bulkFailed: "Масова дія: ",
completionBlockedHallucination: "⚠ Завершення заблоковано — фантомні id карток",
suspectedHallucinatedReferences: "⚠ Текст посилався на фантомні id карток",
pickProfileFirst: "Спочатку виберіть профіль.",
unblockedMessage: "{id} розблоковано. Задача готова до наступного тіку.",
unblockFailed: "Розблокування не вдалося: ",
reclaimedMessage: "{id} повернуто. Задача знову готова.",
reclaimFailed: "Повернення не вдалося: ",
reassignedMessage: "{id} перепризначено на {profile}.",
reassignFailed: "Перепризначення не вдалося: ",
selectForBulk: "Вибрати для масових дій",
clickToEdit: "Клікніть, щоб редагувати",
clickToEditAssignee: "Клікніть, щоб редагувати виконавця",
emptyAssignee: "(порожньо = зняти призначення)",
columnLabels: {
triage: "Сортування",
todo: "До виконання",
ready: "Готово",
running: "У роботі",
blocked: "Заблоковано",
done: "Виконано",
archived: "Архів",
},
columnHelp: {
triage: "Сирі ідеї — специфікатор деталізує специфікацію",
todo: "Очікує на залежності або не призначено",
ready: "Призначено, очікує тіку диспетчера",
running: "Захоплено воркером — у роботі",
blocked: "Воркер запитав втручання людини",
done: "Завершено",
archived: "Архівовано",
},
confirmDone:
"Позначити цю задачу як виконану? Захоплення воркера буде звільнено, а залежні нащадки стануть готовими.",
confirmArchive:
"Архівувати цю задачу? Вона зникне з типового вигляду дошки.",
confirmBlocked:
"Позначити цю задачу як заблоковану? Захоплення воркера буде звільнено.",
completionSummary:
"Підсумок завершення для {label}. Зберігається як result задачі.",
completionSummaryRequired:
"Підсумок завершення обов'язковий перед позначенням задачі виконаною.",
triagePlaceholder: "Чорнова ідея — ШІ її специфікує…",
taskTitlePlaceholder: "Назва нової задачі…",
specifier: "специфікатор",
assigneePlaceholder: "виконавець",
priority: "Пріоритет",
skillsPlaceholder:
"навички (необов'язково, через кому): translation, github-code-review",
noParent: "— без батька —",
workspacePathDir: "шлях робочої області (обов'язково, напр. ~/projects/my-app)",
workspacePathOptional:
"шлях робочої області (необов'язково, виводиться з виконавця, якщо порожньо)",
logTruncated: "(показано останні 100 KB — повний журнал у ",
logAt: ")",
},
};

696
web/src/i18n/zh-hant.ts Normal file
View file

@ -0,0 +1,696 @@
import type { Translations } from "./types";
export const zhHant: 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: "多代理設定檔",
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: "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: "Email",
},
},
profiles: {
newProfile: "新增設定檔",
name: "名稱",
namePlaceholder: "例如coder、writer 等",
nameRequired: "名稱為必填",
nameRule:
"僅允許小寫字母、數字、底線及連字號;首字必須為字母或數字;最多 64 個字元。",
invalidName: "設定檔名稱無效",
cloneFromDefault: "從預設設定檔複製設定",
allProfiles: "設定檔",
noProfiles: "找不到設定檔。",
defaultBadge: "預設",
hasEnv: "env",
model: "模型",
skills: "技能",
rename: "重新命名",
editSoul: "編輯 SOUL.md",
soulSection: "SOUL.md人格 / 系統提示詞)",
soulPlaceholder: "# 此代理應如何運作…",
saveSoul: "儲存 SOUL",
soulSaved: "SOUL.md 已儲存",
openInTerminal: "複製 CLI 指令",
commandCopied: "已複製到剪貼簿",
copyFailed: "複製失敗",
confirmDeleteTitle: "刪除設定檔?",
confirmDeleteMessage:
"將永久刪除設定檔「{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 URL 安裝",
installHint: "可使用 owner/repo 簡寫或完整的 https:// 或 git@ 複製網址。",
memoryProviderLabel: "記憶提供者",
missingEnvWarn: "請先在「金鑰」頁面設定下列項目,外掛才能執行:",
noDashboardTab: "無儀表板分頁",
openTab: "開啟",
orphanHeading: "僅儀表板擴充功能(無對應的 agent plugin.yaml",
pluginListHeading: "已安裝的外掛",
providerDefaults: "內建 / 預設",
providersHeading: "執行階段提供者外掛",
providersHint:
"會寫入 config.yamlmemory.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。請登入並點擊「Authorize」。",
pkceStep2: "複製授權後顯示的授權代碼。",
pkceStep3: "將其貼到下方並提交。",
flowLabels: {
pkce: "瀏覽器登入PKCE",
device_code: "裝置代碼",
external: "外部 CLI",
},
expiresIn: "{time}後過期",
},
language: {
switchTo: "切換為英文",
},
theme: {
title: "主題",
switchTheme: "切換主題",
},
achievements: {
hero: {
kicker: "Agentic Gamerscore",
title: "Hermes Achievements",
subtitle:
"從真實工作階段歷史中獲得的 Hermes 可收集徽章。已知尚未達成的成就會顯示為「已發現」;秘密成就在首次出現相符行為之前保持隱藏。",
scan_subtitle:
"正在掃描 Hermes 工作階段歷史。在歷史紀錄較多時,首次掃描可能需要 510 秒。",
},
actions: {
rescan: "重新掃描",
},
stats: {
unlocked: "已解鎖",
unlocked_hint: "獲得的徽章",
discovered: "已發現",
discovered_hint: "已知,但尚未獲得",
secrets: "秘密",
secrets_hint: "在首次訊號出現前保持隱藏",
highest_tier: "最高等級",
highest_tier_hint: "Copper → Silver → Gold → Diamond → Olympian",
latest: "最新",
latest_hint_empty: "多多執行 Hermes",
none_yet: "尚無",
},
state: {
unlocked: "已解鎖",
discovered: "已發現",
secret: "秘密",
},
tier: {
target: "目標 {tier}",
hidden: "隱藏",
complete: "已完成",
objective: "目標",
},
progress: {
hidden: "隱藏",
},
scan: {
building_headline: "正在建立成就檔案…",
building_detail:
"正在讀取工作階段、工具呼叫、模型中繼資料以及解鎖狀態。",
starting_headline: "正在開始成就掃描…",
progress_detail:
"已掃描 {scanned} / {total} 個工作階段 · {pct}%。隨著更多歷史串入,徽章會陸續解鎖。",
idle_detail:
"正在讀取工作階段、工具呼叫、模型中繼資料以及解鎖狀態。徽章解鎖後會顯示在這裡。",
},
guide: {
tiers_header: "等級",
secret_header: "秘密成就",
secret_body:
"秘密成就會隱藏其確切觸發條件。一旦 Hermes 偵測到相關訊號,卡片便會變為「已發現」並顯示其需求。",
scan_status_header: "掃描狀態",
scan_status_body:
"Hermes 正在對本機歷史進行一次掃描,之後卡片會自動出現。即使需要幾秒鐘,也並未卡住。",
what_scanned_header: "掃描內容",
what_scanned_body:
"工作階段、工具呼叫、模型中繼資料、錯誤、成就以及本機解鎖狀態。",
},
card: {
share_title: "分享此成就",
share_label: "分享 {name}",
share_text: "分享",
how_to_reveal: "如何揭示",
what_counts: "計入條件",
evidence_label: "證據",
evidence_session_fallback: "工作階段",
no_evidence: "尚無證據",
},
latest: {
header: "最近解鎖",
},
empty: {
no_secrets_header: "本次掃描已沒有隱藏的秘密。",
no_secrets_body:
"提示:秘密通常源自異常失敗或進階使用者的行為模式 —— 連接埠衝突、權限阻擋、缺少環境變數、YAML 錯誤、Docker 衝突、回復或檢查點的使用、快取命中,或在大量紅色錯誤後做出的小小修正。",
},
filters: {
all_categories: "全部",
visibility_all: "全部",
visibility_unlocked: "已解鎖",
visibility_discovered: "已發現",
visibility_secret: "秘密",
},
share: {
dialog_label: "分享成就",
header: "分享:{name}",
close: "關閉",
rendering: "繪製中…",
card_alt: "{name} 分享卡片",
error_generic: "發生錯誤。",
x_title: "在 X 中開啟預先填寫的貼文",
x_button: "在 X 上分享",
copy_title: "複製圖片以貼上到你的貼文",
copy_button: "複製圖片",
copied: "已複製 ✓",
download_button: "下載 PNG",
hint:
"「在 X 上分享」會在新分頁中開啟預先填寫的貼文。若想附上 1200×630 的徽章,請先點擊「複製圖片」—— X 允許你直接貼到推文編輯器中。「下載 PNG」會將檔案儲存下來可在任何地方使用。",
clipboard_unsupported:
"此瀏覽器不支援剪貼簿圖片複製 —— 請改用「下載」。",
tweet_text: "Just unlocked {tier_part}\"{name}\" in Hermes Agent ☤",
},
},
kanban: {
loading: "正在載入看板…",
loadFailed: "載入看板失敗:",
loadFailedHint:
"後端會在首次讀取時自動建立 kanban.db。如果問題持續請檢查儀表板日誌。",
board: "看板",
newBoard: "+ 新增看板",
newBoardTitle: "新增看板",
newBoardDescription:
"看板可將不相關的工作流分開——每個專案、程式碼庫或網域一個看板。一個看板上的工作者不會看到另一個看板的任務。",
slug: "識別碼",
slugHint: "— 小寫字母、連字號,例如 atm10-server",
displayName: "顯示名稱",
displayNameHint: "(選填)",
description: "描述",
descriptionHint: "(選填)",
icon: "圖示",
iconHint: "(單一字元或表情符號)",
switchAfterCreate: "建立後切換到此看板",
cancel: "取消",
creating: "建立中…",
createBoard: "建立看板",
search: "搜尋",
filterCards: "篩選卡片…",
tenant: "租戶",
allTenants: "全部租戶",
assignee: "負責人",
allProfiles: "全部設定檔",
showArchived: "顯示已封存",
lanesByProfile: "依設定檔分組",
nudgeDispatcher: "觸發排程器",
refresh: "重新整理",
selected: "已選取",
complete: "完成",
archive: "封存",
apply: "套用",
clear: "清除",
createTask: "在此欄建立任務",
noTasks: "— 沒有任務 —",
unassigned: "未指派",
untitled: "(無標題)",
loadingDetail: "載入中…",
addComment: "新增留言…(按 Enter 送出)",
comment: "留言",
status: "狀態",
workspace: "工作區",
skills: "技能",
createdBy: "建立者",
result: "結果",
comments: "留言",
events: "事件",
runHistory: "執行紀錄",
workerLog: "工作者日誌",
loadingLog: "正在載入日誌…",
noWorkerLog:
"— 尚無工作者日誌(任務尚未啟動或日誌已被輪替)—",
noDescription: "— 沒有描述 —",
noComments: "— 沒有留言 —",
edit: "編輯",
save: "儲存",
dependencies: "相依項目",
parents: "上層任務:",
children: "下層任務:",
none: "無",
addParent: "— 新增上層任務 —",
addChild: "— 新增下層任務 —",
removeDependency: "移除相依項目",
block: "封鎖",
unblock: "解除封鎖",
notifyHomeChannels: "通知主要頻道",
diagnostics: "診斷",
hide: "隱藏",
show: "顯示",
attention: "注意",
tasksNeedAttention: "個任務需要關注",
taskNeedsAttention: "1 個任務需要關注",
diagnostic: "診斷",
open: "開啟",
close: "關閉 (Esc)",
reassignTo: "重新指派給:",
copied: "已複製",
copyCommand: "複製指令到剪貼簿",
reclaim: "收回",
reassign: "重新指派",
renderingError: "看板分頁發生繪製錯誤",
reloadView: "重新載入檢視",
wsAuthFailed:
"WebSocket 驗證失敗 — 請重新載入頁面以更新工作階段權杖。",
markDone: "將 {n} 個任務標記為完成?",
markArchived: "封存 {n} 個任務?",
warning: "警告",
phantomIds: "幽靈 ID",
active: "進行中",
ended: "已結束",
noProfile: "(無設定檔)",
showAllAttempts: "顯示所有嘗試",
sendingUpdates: "正在傳送更新到",
sendNotifications: "傳送完成 / 封鎖 / 放棄通知到",
archiveBoardConfirm:
"封存看板「{name}」?看板將會移至 boards/_archived/,以便日後復原。此看板上的任務將不再出現在 UI 中的任何位置。",
archiveBoardTitle: "封存此看板",
boardSwitcherHint: "看板可將不相關的工作流分開",
taskCreatedWarning: "任務已建立,但:",
moveFailed: "移動失敗:",
bulkFailed: "批次操作:",
completionBlockedHallucination: "⚠ 完成被封鎖 — 幽靈卡片 ID",
suspectedHallucinatedReferences: "⚠ 文字內容引用了幽靈卡片 ID",
pickProfileFirst: "請先選擇一個設定檔。",
unblockedMessage: "已解除封鎖 {id}。任務已準備好進入下一輪排程。",
unblockFailed: "解除封鎖失敗:",
reclaimedMessage: "已收回 {id}。任務已回到就緒狀態。",
reclaimFailed: "收回失敗:",
reassignedMessage: "已將 {id} 重新指派給 {profile}。",
reassignFailed: "重新指派失敗:",
selectForBulk: "選取以進行批次操作",
clickToEdit: "點擊以編輯",
clickToEditAssignee: "點擊以編輯負責人",
emptyAssignee: "(留空 = 取消指派)",
columnLabels: {
triage: "待分類",
todo: "待辦",
ready: "就緒",
running: "進行中",
blocked: "已封鎖",
done: "已完成",
archived: "已封存",
},
columnHelp: {
triage: "原始想法 — 規格制定者將完善規格",
todo: "等待相依項目或尚未指派",
ready: "已指派,等待排程器輪詢",
running: "已被工作者領取 — 執行中",
blocked: "工作者請求人工輸入",
done: "已完成",
archived: "已封存",
},
confirmDone:
"將此任務標記為完成?工作者的領取將被釋放,下層相依任務將變為就緒。",
confirmArchive:
"封存此任務?它將從預設看板檢視中消失。",
confirmBlocked:
"將此任務標記為已封鎖?工作者的領取將被釋放。",
completionSummary:
"{label} 的完成摘要。這將作為任務結果儲存。",
completionSummaryRequired:
"在將任務標記為完成之前,必須提供完成摘要。",
triagePlaceholder: "粗略的想法 — AI 將完善規格…",
taskTitlePlaceholder: "新任務標題…",
specifier: "規格制定者",
assigneePlaceholder: "負責人",
priority: "優先順序",
skillsPlaceholder:
"技能選填以逗號分隔translation、github-code-review",
noParent: "— 無上層任務 —",
workspacePathDir: "工作區路徑(必填,例如 ~/projects/my-app",
workspacePathOptional:
"工作區路徑(選填,留空則依負責人推導)",
logTruncated: "(顯示最後 100 KB — 完整日誌位於 ",
logAt: "",
},
};

View file

@ -421,4 +421,272 @@ export const zh: Translations = {
title: "主题",
switchTheme: "切换主题",
},
achievements: {
hero: {
kicker: "Agentic Gamerscore",
title: "Hermes Achievements",
subtitle:
"从真实会话历史中获得的 Hermes 可收集徽章。已知尚未达成的成就显示为「已发现」;秘密成就在首次出现匹配行为之前保持隐藏。",
scan_subtitle:
"正在扫描 Hermes 会话历史。在历史记录较多时,首次扫描可能需要 510 秒。",
},
actions: {
rescan: "重新扫描",
},
stats: {
unlocked: "已解锁",
unlocked_hint: "获得的徽章",
discovered: "已发现",
discovered_hint: "已知,但尚未获得",
secrets: "秘密",
secrets_hint: "在首次信号出现前保持隐藏",
highest_tier: "最高等级",
highest_tier_hint: "Copper → Silver → Gold → Diamond → Olympian",
latest: "最新",
latest_hint_empty: "多多运行 Hermes",
none_yet: "暂无",
},
state: {
unlocked: "已解锁",
discovered: "已发现",
secret: "秘密",
},
tier: {
target: "目标 {tier}",
hidden: "隐藏",
complete: "已完成",
objective: "目标",
},
progress: {
hidden: "隐藏",
},
scan: {
building_headline: "正在构建成就档案…",
building_detail:
"正在读取会话、工具调用、模型元数据和解锁状态。",
starting_headline: "正在开始成就扫描…",
progress_detail:
"已扫描 {scanned} / {total} 个会话 · {pct}%。随着更多历史流入,徽章会陆续解锁。",
idle_detail:
"正在读取会话、工具调用、模型元数据和解锁状态。徽章解锁后将在此显示。",
},
guide: {
tiers_header: "等级",
secret_header: "秘密成就",
secret_body:
"秘密成就会隐藏其确切触发条件。一旦 Hermes 检测到相关信号,卡片将变为「已发现」并显示其要求。",
scan_status_header: "扫描状态",
scan_status_body:
"Hermes 正在对本地历史进行一次扫描,之后卡片会自动出现。即使这需要几秒钟,也没有卡住。",
what_scanned_header: "扫描内容",
what_scanned_body:
"会话、工具调用、模型元数据、错误、成就和本地解锁状态。",
},
card: {
share_title: "分享此成就",
share_label: "分享 {name}",
share_text: "分享",
how_to_reveal: "如何揭示",
what_counts: "计入条件",
evidence_label: "证据",
evidence_session_fallback: "会话",
no_evidence: "暂无证据",
},
latest: {
header: "最近解锁",
},
empty: {
no_secrets_header: "本次扫描中已没有隐藏的秘密。",
no_secrets_body:
"提示:秘密通常源于异常失败或高级用户行为模式 —— 端口冲突、权限阻拦、缺少环境变量、YAML 错误、Docker 冲突、回滚或检查点使用、缓存命中,或在大量红色错误后做出的小小修复。",
},
filters: {
all_categories: "全部",
visibility_all: "全部",
visibility_unlocked: "已解锁",
visibility_discovered: "已发现",
visibility_secret: "秘密",
},
share: {
dialog_label: "分享成就",
header: "分享:{name}",
close: "关闭",
rendering: "渲染中…",
card_alt: "{name} 分享卡片",
error_generic: "发生错误。",
x_title: "在 X 中打开预填好的帖子",
x_button: "在 X 上分享",
copy_title: "复制图片以粘贴到你的帖子中",
copy_button: "复制图片",
copied: "已复制 ✓",
download_button: "下载 PNG",
hint:
"「在 X 上分享」会在新标签页中打开预填好的帖子。如果想附上 1200×630 的徽章,请先点击「复制图片」—— X 允许你直接粘贴到推文编辑器中。「下载 PNG」会将文件保存下来可在任意位置使用。",
clipboard_unsupported:
"此浏览器不支持复制剪贴板图片 —— 请改用「下载」。",
tweet_text: "Just unlocked {tier_part}\"{name}\" in Hermes Agent ☤",
},
},
kanban: {
loading: "正在加载看板…",
loadFailed: "加载看板失败:",
loadFailedHint:
"后端会在首次读取时自动创建 kanban.db。如果问题持续请检查仪表盘日志。",
board: "看板",
newBoard: "+ 新建看板",
newBoardTitle: "新建看板",
newBoardDescription:
"看板可以将不相关的工作流分开——每个项目、代码库或域一个看板。一个看板上的工作者不会看到另一个看板的任务。",
slug: "标识",
slugHint: "— 小写字母、连字符,例如 atm10-server",
displayName: "显示名称",
displayNameHint: "(可选)",
description: "描述",
descriptionHint: "(可选)",
icon: "图标",
iconHint: "(单个字符或表情)",
switchAfterCreate: "创建后切换到此看板",
cancel: "取消",
creating: "创建中…",
createBoard: "创建看板",
search: "搜索",
filterCards: "筛选卡片…",
tenant: "租户",
allTenants: "全部租户",
assignee: "负责人",
allProfiles: "全部配置",
showArchived: "显示已归档",
lanesByProfile: "按配置分组",
nudgeDispatcher: "触发调度器",
refresh: "刷新",
selected: "已选中",
complete: "完成",
archive: "归档",
apply: "应用",
clear: "清除",
createTask: "在此列创建任务",
noTasks: "— 无任务 —",
unassigned: "未分配",
untitled: "(无标题)",
loadingDetail: "加载中…",
addComment: "添加评论…(按回车提交)",
comment: "评论",
status: "状态",
workspace: "工作区",
skills: "技能",
createdBy: "创建者",
result: "结果",
comments: "评论",
events: "事件",
runHistory: "运行历史",
workerLog: "工作日志",
loadingLog: "正在加载日志…",
noWorkerLog:
"— 暂无工作日志(任务尚未启动或日志已被轮转)—",
noDescription: "— 无描述 —",
noComments: "— 无评论 —",
edit: "编辑",
save: "保存",
dependencies: "依赖",
parents: "父任务:",
children: "子任务:",
none: "无",
addParent: "— 添加父任务 —",
addChild: "— 添加子任务 —",
removeDependency: "移除依赖",
block: "阻塞",
unblock: "解除阻塞",
notifyHomeChannels: "通知主页频道",
diagnostics: "诊断",
hide: "隐藏",
show: "显示",
attention: "注意",
tasksNeedAttention: "个任务需要关注",
taskNeedsAttention: "1 个任务需要关注",
diagnostic: "诊断",
open: "打开",
close: "关闭 (Esc)",
reassignTo: "重新分配给:",
copied: "已复制",
copyCommand: "复制命令到剪贴板",
reclaim: "收回",
reassign: "重新分配",
renderingError: "看板标签页发生渲染错误",
reloadView: "重新加载视图",
wsAuthFailed:
"WebSocket 认证失败 — 请刷新页面以更新会话令牌。",
markDone: "将 {n} 个任务标记为完成?",
markArchived: "归档 {n} 个任务?",
warning: "警告",
phantomIds: "幽灵 ID",
active: "运行中",
ended: "已结束",
noProfile: "(无配置)",
showAllAttempts: "显示所有尝试",
sendingUpdates: "正在发送更新到",
sendNotifications: "发送完成 / 阻塞 / 放弃通知到",
archiveBoardConfirm:
"归档看板 '{name}'?它将被移动到 boards/_archived/ 以便稍后恢复。此看板上的任务将不再出现在 UI 中的任何地方。",
archiveBoardTitle: "归档此看板",
boardSwitcherHint: "看板可以将不相关的工作流分开",
taskCreatedWarning: "任务已创建,但:",
moveFailed: "移动失败:",
bulkFailed: "批量操作:",
completionBlockedHallucination: "⚠ 完成被阻塞 — 幽灵卡片 ID",
suspectedHallucinatedReferences: "⚠ 文本引用了幽灵卡片 ID",
pickProfileFirst: "请先选择一个配置。",
unblockedMessage: "已解除阻塞 {id}。任务已准备好进入下一轮调度。",
unblockFailed: "解除阻塞失败:",
reclaimedMessage: "已收回 {id}。任务已回到就绪状态。",
reclaimFailed: "收回失败:",
reassignedMessage: "已将 {id} 重新分配给 {profile}。",
reassignFailed: "重新分配失败:",
selectForBulk: "选择以进行批量操作",
clickToEdit: "点击编辑",
clickToEditAssignee: "点击编辑负责人",
emptyAssignee: "(留空 = 取消分配)",
columnLabels: {
triage: "待分类",
todo: "待办",
ready: "就绪",
running: "进行中",
blocked: "阻塞",
done: "已完成",
archived: "已归档",
},
columnHelp: {
triage: "原始想法 — 规范制定者将完善规格",
todo: "等待依赖项或未分配",
ready: "已分配,等待调度器轮询",
running: "已被工作者认领 — 执行中",
blocked: "工作者请求人工输入",
done: "已完成",
archived: "已归档",
},
confirmDone:
"将此任务标记为完成?工作者将被释放,依赖的子任务将变为就绪。",
confirmArchive:
"归档此任务?它将从默认看板视图中消失。",
confirmBlocked:
"将此任务标记为阻塞?工作者将被释放。",
completionSummary:
"{label} 的完成摘要。这将作为任务结果存储。",
completionSummaryRequired:
"在将任务标记为完成之前,必须提供完成摘要。",
triagePlaceholder: "粗略想法 — AI 将完善规格…",
taskTitlePlaceholder: "新任务标题…",
specifier: "规范制定者",
assigneePlaceholder: "负责人",
priority: "优先级",
skillsPlaceholder:
"技能可选逗号分隔翻译、github-code-review",
noParent: "— 无父任务 —",
workspacePathDir: "工作区路径(必填,例如 ~/projects/my-app",
workspacePathOptional:
"工作区路径(可选,留空则根据负责人推导)",
logTruncated: "(显示最后 100 KB — 完整日志位于 ",
logAt: "",
},
};