feat: добавить локализацию TUI (en/ru) с переключением клавишей L

- Добавлены TuiResources (sealed record), Locale, LocalizationService
- Все строки интерфейса вынесены из .razor-файлов в TuiResources
- App.razor: клавиша L циклически переключает локаль, заголовок показывает [EN]/[RU]
- Дочерние компоненты получают Loc как параметр (stateless)
- Создан AGENT.tui.md с правилами работы с TUI для агентов
- Обновлены AGENTS.md и CLAUDE.md со ссылками на AGENT.tui.md

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-13 23:53:59 +03:00
parent 4819fbca6c
commit 01565b32d9
12 changed files with 279 additions and 91 deletions

View File

@@ -0,0 +1,107 @@
namespace LazyBear.MCP.TUI.Localization;
/// <summary>
/// Все строки TUI для одной локали.
/// При добавлении новой строки: добавить свойство сюда и перевод в оба статических экземпляра.
/// </summary>
public sealed record TuiResources
{
// ── Подсказка и вкладки ──────────────────────────────────────────────────
public string HintBar { get; init; } = "";
public string TabOverview { get; init; } = "";
public string TabLogs { get; init; } = "";
public string TabSettings { get; init; } = "";
// ── Overview ─────────────────────────────────────────────────────────────
public string OverviewTitle { get; init; } = "";
public string OverviewHint { get; init; } = "";
public string OverviewEmpty { get; init; } = "";
public string StateOn { get; init; } = "";
public string StateOff { get; init; } = "";
public string FooterModule { get; init; } = "";
public string FooterTools { get; init; } = "";
// ── Logs ─────────────────────────────────────────────────────────────────
public string LogsTitle { get; init; } = "";
public string LogsHint { get; init; } = "";
public string LogsEmpty { get; init; } = "";
public string LogsPlaceholder { get; init; } = "";
public string LogsSticky { get; init; } = "";
public string LogsManual { get; init; } = "";
public string FilterLabel { get; init; } = "";
public string FilterAll { get; init; } = "";
// ── Settings ─────────────────────────────────────────────────────────────
public string SettingsTitle { get; init; } = "";
public string SettingsHint { get; init; } = "";
public string SettingsEmpty { get; init; } = "";
public string SettingsUnavailable { get; init; } = "";
public string ModuleOff { get; init; } = "";
public string ModuleOffPreserved { get; init; } = "";
// ── Локали ───────────────────────────────────────────────────────────────
public static readonly TuiResources En = new()
{
HintBar = "Tab: tabs | Arrows: navigate | Space: toggle | Enter: open | L: language",
TabOverview = "Overview",
TabLogs = "Logs",
TabSettings = "Settings",
OverviewTitle = "Module Overview",
OverviewHint = "Up/Down: select module. Enter: open settings.",
OverviewEmpty = "No modules registered.",
StateOn = "ON",
StateOff = "OFF",
FooterModule = "Module",
FooterTools = "Tools",
LogsTitle = "Runtime Logs",
LogsHint = "Left/Right: filter | Up/Down: scroll | PageUp/Down: page",
LogsEmpty = "No log entries yet.",
LogsPlaceholder = "Incoming log entries will appear here.",
LogsSticky = "sticky",
LogsManual = "manual",
FilterLabel = "Filter",
FilterAll = "All",
SettingsTitle = "Tool Registry",
SettingsHint = "Up/Down: select | Left/Right: expand/collapse | Space: toggle",
SettingsEmpty = "No modules available.",
SettingsUnavailable = "Runtime enable/disable settings are unavailable.",
ModuleOff = "(module off)",
ModuleOffPreserved = "(module is OFF, tool state is preserved)"
};
public static readonly TuiResources Ru = new()
{
HintBar = "Tab: вкладки | Стрелки: навигация | Space: вкл/выкл | Enter: открыть | L: язык",
TabOverview = "Обзор",
TabLogs = "Логи",
TabSettings = "Настройки",
OverviewTitle = "Модули",
OverviewHint = "Вверх/вниз: выбор модуля. Enter: открыть настройки.",
OverviewEmpty = "Нет зарегистрированных модулей.",
StateOn = "ВКЛ",
StateOff = "ВЫКЛ",
FooterModule = "Модуль",
FooterTools = "Инструменты",
LogsTitle = "Логи",
LogsHint = "Лево/право: фильтр | Вверх/вниз: прокрутка | PageUp/Down: страница",
LogsEmpty = "Записей пока нет.",
LogsPlaceholder = "Новые записи будут появляться здесь.",
LogsSticky = "следить",
LogsManual = "вручную",
FilterLabel = "Фильтр",
FilterAll = "Все",
SettingsTitle = "Реестр инструментов",
SettingsHint = "Вверх/вниз: выбор | Лево/право: развернуть/свернуть | Space: вкл/выкл",
SettingsEmpty = "Нет доступных модулей.",
SettingsUnavailable = "Настройки включения/выключения недоступны.",
ModuleOff = "(модуль выкл)",
ModuleOffPreserved = "(модуль ВЫКЛ, состояние инструментов сохранено)"
};
}