When a saved flow is missing modules, each capability pill in the "Needs:" row is now clickable: tap one and a per-item progress dialog walks the bare capability name through installModule, then the flows page refreshes. When more than one capability is missing, an extra "Install all (N)" button runs the same dialog over the whole list sequentially so a fresh operator can take an unrunnable flow and one click later have its dependencies resolved. Also adds a pencil icon next to Run that hands the YAML path to the OS via SystemActions.openInOs — the operator's default editor for .yaml decides what opens. Makes the path next to the flow name actionable instead of decorative. The install dialog renders one row per spec with a status icon (pending circle / spinner / check / error), shows the installed version on success, and surfaces the full error in a copyable FaiErrorBox on failure so the operator can paste it back. Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
1824 lines
45 KiB
Dart
1824 lines
45 KiB
Dart
// ignore: unused_import
|
||
import 'package:intl/intl.dart' as intl;
|
||
import 'app_localizations.dart';
|
||
|
||
// ignore_for_file: type=lint
|
||
|
||
/// The translations for German (`de`).
|
||
class AppLocalizationsDe extends AppLocalizations {
|
||
AppLocalizationsDe([String locale = 'de']) : super(locale);
|
||
|
||
@override
|
||
String get appTitle => 'F∆I Studio';
|
||
|
||
@override
|
||
String get navWelcome => 'Willkommen';
|
||
|
||
@override
|
||
String get welcomeHeroTitle => 'F∆I Platform';
|
||
|
||
@override
|
||
String get welcomeHeroSubtitle =>
|
||
'Deterministische Workflow-Engine für KI-gestützte Dokumentenverarbeitung in regulierten Umgebungen.';
|
||
|
||
@override
|
||
String get welcomePillarHubTitle => 'Hub';
|
||
|
||
@override
|
||
String get welcomePillarHubBody =>
|
||
'Ein Rust-Binary, das Module lädt und Flows ausführt. SQLite für den State. Kein Docker, kein Message-Broker, keine Hintergrunddienste, die gepflegt werden müssen.';
|
||
|
||
@override
|
||
String get welcomePillarModuleTitle => 'Modul';
|
||
|
||
@override
|
||
String get welcomePillarModuleBody =>
|
||
'Eine kleine WebAssembly-Komponente, die eine Sache macht. Deklariert Netzwerk-Endpunkte, Dateien und Umgebungsvariablen, auf die sie zugreift; der Hub setzt die Liste durch.';
|
||
|
||
@override
|
||
String get welcomePillarFlowTitle => 'Flow';
|
||
|
||
@override
|
||
String get welcomePillarFlowBody =>
|
||
'Eine YAML-Datei, die Module verkettet. Eingaben rein, Module laufen in der deklarierten Reihenfolge, Ausgaben raus — jeder Schritt in einem hash-verketteten Audit-Log festgehalten.';
|
||
|
||
@override
|
||
String get welcomeTrustHeader => 'TRUST-POSTURE';
|
||
|
||
@override
|
||
String get welcomeTrustSandboxTitle => 'Sandbox von Anfang an';
|
||
|
||
@override
|
||
String get welcomeTrustSandboxBody =>
|
||
'Jedes Modul bringt eine explizite Berechtigungsliste mit — Netzwerk-Endpunkte, Dateien, Umgebungsvariablen. Der Hub setzt sie durch; ohne Operator-Freigabe verlässt nichts die Sandbox.';
|
||
|
||
@override
|
||
String get welcomeTrustAuditTitle => 'Manipulationssicheres Audit-Log';
|
||
|
||
@override
|
||
String get welcomeTrustAuditBody =>
|
||
'Flow-Läufe, Installationen, Deinstallationen, Freigabe-Entscheidungen — alles wird in ein hash-verkettetes Audit-Log geschrieben. Die Diagnose-Seite verifiziert die Kette bei jedem Laden komplett.';
|
||
|
||
@override
|
||
String get welcomeTrustAirgapTitle => 'Air-Gap-tauglich';
|
||
|
||
@override
|
||
String get welcomeTrustAirgapBody =>
|
||
'Der gesamte Hub steckt in einem einzigen Binary für Linux, macOS und Windows. Sobald ein Modul installiert ist, läuft der Flow, der es nutzt, ohne weiteren Netzwerkzugriff — ideal für regulierte Umgebungen.';
|
||
|
||
@override
|
||
String get welcomeDocsHeader => 'DOKUMENTATION';
|
||
|
||
@override
|
||
String get welcomeDocsBody =>
|
||
'Operator-Erklärungen, inline gerendert. Kein Browser, kein externer Link — air-gap-tauglich.';
|
||
|
||
@override
|
||
String get welcomeDocArchitectureTitle => 'Architektur in einem Absatz';
|
||
|
||
@override
|
||
String get welcomeDocArchitectureBlurb =>
|
||
'Hub, Modul, Flow — und wie die drei zusammenpassen.';
|
||
|
||
@override
|
||
String get welcomeDocSecurityTitle => 'Sandbox-Modell';
|
||
|
||
@override
|
||
String get welcomeDocSecurityBlurb =>
|
||
'Was ein Modul deklariert, was der Operator deckelt, was der Hub durchsetzt.';
|
||
|
||
@override
|
||
String get welcomeDocAuditTitle => 'Manipulationssicheres Audit-Log';
|
||
|
||
@override
|
||
String get welcomeDocAuditBlurb =>
|
||
'Wie die Hash-Kette funktioniert und warum WORM-1 für KRITIS reicht.';
|
||
|
||
@override
|
||
String get welcomeDocFlowsTitle => 'Flow-Komposition';
|
||
|
||
@override
|
||
String get welcomeDocFlowsBlurb =>
|
||
'YAML-Grundlagen, Templating-Referenz, das Extract→Summarize-Beispiel.';
|
||
|
||
@override
|
||
String get welcomeDocClose => 'Schließen';
|
||
|
||
@override
|
||
String welcomeDocFailedToLoad(String error) {
|
||
return 'Doku konnte nicht geladen werden: $error';
|
||
}
|
||
|
||
@override
|
||
String get welcomeChecklistHeader => 'ERSTE SCHRITTE';
|
||
|
||
@override
|
||
String get welcomeChecklistBody =>
|
||
'Vier Schritte zu einem funktionierenden Hub. Live-Zustand — nach jeder Änderung aktualisieren.';
|
||
|
||
@override
|
||
String get welcomeChecklistAi => 'System-AI konfigurieren';
|
||
|
||
@override
|
||
String get welcomeChecklistAiHint =>
|
||
'Einstellungen → System-AI. Wird für die KI-Suche und Fehlererklärungen gebraucht.';
|
||
|
||
@override
|
||
String get welcomeChecklistMcp => 'Öffentliche Capability-Quelle hinzufügen';
|
||
|
||
@override
|
||
String get welcomeChecklistMcpHint =>
|
||
'Store → Today-Hero, oder Einstellungen → MCP-Clients. DeepWiki und Semgrep sind je ein Klick.';
|
||
|
||
@override
|
||
String get welcomeChecklistModule => 'Ein Text-Modul installieren';
|
||
|
||
@override
|
||
String get welcomeChecklistModuleHint =>
|
||
'Store → nach „text\" suchen → Installieren. text.extract für PDFs und DOCX ist ein guter Start.';
|
||
|
||
@override
|
||
String get welcomeChecklistFlow => 'Einen gespeicherten Flow starten';
|
||
|
||
@override
|
||
String get welcomeChecklistFlowHint =>
|
||
'Flows → einen wählen → Starten. Der mitgelieferte extract-summarize.yaml ist ein guter erster Lauf.';
|
||
|
||
@override
|
||
String get welcomeChecklistAllDone => 'Alle vier Schritte erledigt.';
|
||
|
||
@override
|
||
String get welcomeChecklistDismiss => 'Checkliste ausblenden';
|
||
|
||
@override
|
||
String get welcomeChecklistRefresh => 'Aktualisieren';
|
||
|
||
@override
|
||
String get welcomeChecklistRefreshing => 'Prüfe…';
|
||
|
||
@override
|
||
String get welcomeChecklistDone => 'Erledigt';
|
||
|
||
@override
|
||
String get welcomeChecklistTodo => 'Offen';
|
||
|
||
@override
|
||
String get navDoctor => 'Diagnose';
|
||
|
||
@override
|
||
String get navModules => 'Module';
|
||
|
||
@override
|
||
String get navStore => 'Store';
|
||
|
||
@override
|
||
String get navFlows => 'Flows';
|
||
|
||
@override
|
||
String get navAudit => 'Protokoll';
|
||
|
||
@override
|
||
String get navApprovals => 'Freigaben';
|
||
|
||
@override
|
||
String get connectionConnected => 'verbunden';
|
||
|
||
@override
|
||
String get connectionUnreachable => 'nicht erreichbar';
|
||
|
||
@override
|
||
String get connectionConnecting => 'verbinde…';
|
||
|
||
@override
|
||
String get connectionStartHub => 'Hub starten';
|
||
|
||
@override
|
||
String get buttonCancel => 'Abbrechen';
|
||
|
||
@override
|
||
String get buttonSave => 'Speichern';
|
||
|
||
@override
|
||
String get buttonClose => 'Schließen';
|
||
|
||
@override
|
||
String get buttonRetry => 'Erneut versuchen';
|
||
|
||
@override
|
||
String get buttonRefresh => 'Aktualisieren';
|
||
|
||
@override
|
||
String get buttonInstall => 'Installieren';
|
||
|
||
@override
|
||
String get buttonUninstall => 'Deinstallieren';
|
||
|
||
@override
|
||
String get buttonDetails => 'Details';
|
||
|
||
@override
|
||
String get buttonAdd => 'Hinzufügen';
|
||
|
||
@override
|
||
String get buttonRemove => 'Entfernen';
|
||
|
||
@override
|
||
String get buttonOpen => 'Öffnen';
|
||
|
||
@override
|
||
String get buttonExplain => 'Erklären';
|
||
|
||
@override
|
||
String get buttonReadDocs => 'Doku öffnen';
|
||
|
||
@override
|
||
String get buttonCopy => 'In Zwischenablage kopieren';
|
||
|
||
@override
|
||
String get buttonCopied => 'Kopiert';
|
||
|
||
@override
|
||
String get settingsTitle => 'Hub-Endpunkt';
|
||
|
||
@override
|
||
String get settingsHost => 'Host';
|
||
|
||
@override
|
||
String get settingsPort => 'Port';
|
||
|
||
@override
|
||
String get settingsTls => 'TLS';
|
||
|
||
@override
|
||
String get settingsSaveAndConnect => 'Speichern & verbinden';
|
||
|
||
@override
|
||
String get settingsLanguage => 'Sprache';
|
||
|
||
@override
|
||
String get settingsLanguageHint =>
|
||
'Sprache der App. Wirkt auf alle Seiten; mehrsprachige Store-Einträge folgen ebenfalls.';
|
||
|
||
@override
|
||
String get settingsHubEndpointHint =>
|
||
'Wohin soll Studio sich verbinden? Standard ist der lokale Hub auf 127.0.0.1:50051.';
|
||
|
||
@override
|
||
String get settingsTlsSubtitle => 'https/grpc-secure';
|
||
|
||
@override
|
||
String get settingsPortError => 'Port muss 1–65535 sein';
|
||
|
||
@override
|
||
String get channelsBlurb =>
|
||
'Hub-Kanal wechseln (schreibt ~/.fai/current-channel und startet den Daemon neu). Verbinden ändert nur die Wire von Studio.';
|
||
|
||
@override
|
||
String get channelsActionsTooltip => 'Kanal-Aktionen';
|
||
|
||
@override
|
||
String get systemAiHeader => 'SYSTEM-AI';
|
||
|
||
@override
|
||
String get systemAiEnabled => 'aktiv';
|
||
|
||
@override
|
||
String get systemAiOff => 'aus';
|
||
|
||
@override
|
||
String get systemAiEdit => 'Bearbeiten…';
|
||
|
||
@override
|
||
String get systemAiConfigure => 'Konfigurieren…';
|
||
|
||
@override
|
||
String get systemAiOffBlurb =>
|
||
'Aus — Fehlererklärungen auf der Protokoll-Seite sind deaktiviert. Klicke Konfigurieren…, um einen Provider zu wählen (Ollama / OpenAI / LM Studio / vLLM / Eigene). Die Operator-Konfig wird direkt überschrieben; kein Daemon-Neustart nötig.';
|
||
|
||
@override
|
||
String mcpServersCount(int n) {
|
||
String _temp0 = intl.Intl.pluralLogic(
|
||
n,
|
||
locale: localeName,
|
||
other: 'Server',
|
||
one: 'Server',
|
||
);
|
||
return '$n $_temp0';
|
||
}
|
||
|
||
@override
|
||
String get mcpRediscoverTooltip => 'Discovery neu ausführen';
|
||
|
||
@override
|
||
String get mcpAddTooltip => 'MCP-Server hinzufügen';
|
||
|
||
@override
|
||
String get mcpRemoveTooltip => 'Server entfernen';
|
||
|
||
@override
|
||
String mcpToolsCount(int n) {
|
||
return '$n Tools';
|
||
}
|
||
|
||
@override
|
||
String n8nEndpointsCount(int n) {
|
||
String _temp0 = intl.Intl.pluralLogic(
|
||
n,
|
||
locale: localeName,
|
||
other: 'Endpunkte',
|
||
one: 'Endpunkt',
|
||
);
|
||
return '$n $_temp0';
|
||
}
|
||
|
||
@override
|
||
String n8nWorkflowsCount(int n) {
|
||
return '$n Workflows';
|
||
}
|
||
|
||
@override
|
||
String get n8nRediscoverTooltip => 'Discovery neu ausführen';
|
||
|
||
@override
|
||
String get n8nAddTooltip => 'n8n-Endpunkt hinzufügen';
|
||
|
||
@override
|
||
String get n8nRemoveTooltip => 'Endpunkt entfernen';
|
||
|
||
@override
|
||
String get addMcpTitle => 'MCP-Server hinzufügen';
|
||
|
||
@override
|
||
String get addMcpIntro =>
|
||
'Tools, die der Server via `tools/list` anbietet, erscheinen im Store als `mcp.<name>.<tool>`-Fähigkeiten.';
|
||
|
||
@override
|
||
String get addMcpSuggestionsLabel => 'Vorschläge — zum Vorausfüllen klicken';
|
||
|
||
@override
|
||
String get addMcpNameLabel => 'Name (keine Punkte)';
|
||
|
||
@override
|
||
String get addMcpNameHint => 'filesystem';
|
||
|
||
@override
|
||
String get addMcpEndpointLabel => 'Endpunkt';
|
||
|
||
@override
|
||
String get addMcpEndpointHint => 'http://127.0.0.1:3001/mcp';
|
||
|
||
@override
|
||
String get addMcpApiKeyLabel => 'API-Key-Umgebungsvariable (optional)';
|
||
|
||
@override
|
||
String get addMcpApiKeyHint => 'MCP_FILESYSTEM_TOKEN';
|
||
|
||
@override
|
||
String get addMcpNotesLabel => 'Notizen (optional)';
|
||
|
||
@override
|
||
String get addMcpAddButton => 'Hinzufügen + Discovery';
|
||
|
||
@override
|
||
String get addN8nTitle => 'n8n-Endpunkt hinzufügen';
|
||
|
||
@override
|
||
String get addN8nIntro =>
|
||
'Aktive Workflows erscheinen im Store als `n8n.<name>.<workflow_slug>`-Fähigkeiten.';
|
||
|
||
@override
|
||
String get addN8nNameLabel => 'Name (keine Punkte)';
|
||
|
||
@override
|
||
String get addN8nNameHint => 'ops';
|
||
|
||
@override
|
||
String get addN8nBaseUrlLabel => 'Basis-URL (ohne /api/v1)';
|
||
|
||
@override
|
||
String get addN8nBaseUrlHint => 'https://n8n.example.com';
|
||
|
||
@override
|
||
String get addN8nApiKeyLabel => 'API-Key-Umgebungsvariable (optional)';
|
||
|
||
@override
|
||
String get addN8nApiKeyHint => 'N8N_OPS_KEY';
|
||
|
||
@override
|
||
String get addN8nNotesLabel => 'Notizen (optional)';
|
||
|
||
@override
|
||
String get addN8nAddButton => 'Hinzufügen + Discovery';
|
||
|
||
@override
|
||
String addedMcpToast(String name) {
|
||
return 'MCP-Server „$name\" hinzugefügt.';
|
||
}
|
||
|
||
@override
|
||
String addedN8nToast(String name) {
|
||
return 'n8n-Endpunkt „$name\" hinzugefügt.';
|
||
}
|
||
|
||
@override
|
||
String addFailedToast(String error) {
|
||
return 'Hinzufügen fehlgeschlagen: $error';
|
||
}
|
||
|
||
@override
|
||
String removeFailedToast(String error) {
|
||
return 'Entfernen fehlgeschlagen: $error';
|
||
}
|
||
|
||
@override
|
||
String refreshFailedToast(String error) {
|
||
return 'Aktualisieren fehlgeschlagen: $error';
|
||
}
|
||
|
||
@override
|
||
String get channelsHeader => 'KANÄLE';
|
||
|
||
@override
|
||
String get channelsActive => 'aktiv';
|
||
|
||
@override
|
||
String get channelsRunning => 'läuft';
|
||
|
||
@override
|
||
String get channelsStopped => 'gestoppt';
|
||
|
||
@override
|
||
String get channelsConnect => 'Studio mit diesem Kanal verbinden';
|
||
|
||
@override
|
||
String get channelsSwitch => 'Diesen Kanal aktivieren';
|
||
|
||
@override
|
||
String get channelsEnableAutostart => 'Autostart bei Anmeldung aktivieren';
|
||
|
||
@override
|
||
String get channelsDisableAutostart => 'Autostart deaktivieren';
|
||
|
||
@override
|
||
String get storeSearchHint =>
|
||
'Module suchen — Name, Tagline, Tag, Fähigkeit…';
|
||
|
||
@override
|
||
String get storeAskHint =>
|
||
'Was brauchst du? Versuch\'s mit „ein Modul, das tabellarische Daten liest\" oder tippe einfach einen Begriff.';
|
||
|
||
@override
|
||
String get storeAskSubmit => 'Suchen';
|
||
|
||
@override
|
||
String get storeAskAi => 'KI fragen';
|
||
|
||
@override
|
||
String get storeAskClear => 'Frage zurücksetzen';
|
||
|
||
@override
|
||
String get storeAskAiThinking => 'Module werden durchsucht…';
|
||
|
||
@override
|
||
String get storeAskAiUnavailable =>
|
||
'Konfiguriere eine System-AI in den Einstellungen, um Fragen in normaler Sprache zu stellen.';
|
||
|
||
@override
|
||
String get storeAskNoMatches =>
|
||
'Keine Treffer — Frage verfeinern oder im Grid unten stöbern.';
|
||
|
||
@override
|
||
String get storeAskAnswerLabel => 'KI-Vorschlag';
|
||
|
||
@override
|
||
String get storeAskAnswerWhy => 'Warum es passt';
|
||
|
||
@override
|
||
String get storeAskMatchPill => 'Treffer';
|
||
|
||
@override
|
||
String get storeFilterLabel => 'Filter';
|
||
|
||
@override
|
||
String storeFilterActiveCount(int n) {
|
||
return '$n aktiv';
|
||
}
|
||
|
||
@override
|
||
String get storeFilterReset => 'Filter zurücksetzen';
|
||
|
||
@override
|
||
String get storeFilterApply => 'Fertig';
|
||
|
||
@override
|
||
String get storeFilterStatusGroup => 'Status';
|
||
|
||
@override
|
||
String get storeFilterSourceGroup => 'Quelle';
|
||
|
||
@override
|
||
String get storeFilterInstalledGroup => 'Nur installierte zeigen';
|
||
|
||
@override
|
||
String get storeFeatured => 'EMPFOHLEN';
|
||
|
||
@override
|
||
String get storeFeaturedHint => 'kuratierte Auswahl · klicken für Details';
|
||
|
||
@override
|
||
String get storeNoMatches => 'Keine Treffer';
|
||
|
||
@override
|
||
String get storeNoMatchesHint =>
|
||
'Filter anpassen oder Suche leeren, um alle Einträge zu sehen.';
|
||
|
||
@override
|
||
String get storeClearFilters => 'Filter zurücksetzen';
|
||
|
||
@override
|
||
String get storeStatusAll => 'Alle';
|
||
|
||
@override
|
||
String get storeStatusPublished => 'stabil';
|
||
|
||
@override
|
||
String get storeStatusAlpha => 'experimentell';
|
||
|
||
@override
|
||
String get storeStatusPlanned => 'geplant';
|
||
|
||
@override
|
||
String get storeInstalledOnly => 'Installiert';
|
||
|
||
@override
|
||
String get storeCategoryLabel => 'Kategorie';
|
||
|
||
@override
|
||
String get storeCategoryAll => 'Alle Kategorien';
|
||
|
||
@override
|
||
String get storeCategoryBridge => 'Verbindungen';
|
||
|
||
@override
|
||
String get storeCategoryDebug => 'Beispiele';
|
||
|
||
@override
|
||
String get storeCategoryText => 'Text';
|
||
|
||
@override
|
||
String get storeCategoryLlm => 'KI-Modelle';
|
||
|
||
@override
|
||
String get storeCategorySystem => 'System';
|
||
|
||
@override
|
||
String get storeCategoryAuth => 'Authentifizierung';
|
||
|
||
@override
|
||
String get storeCategoryStorage => 'Speicher';
|
||
|
||
@override
|
||
String get storeCategoryChannel => 'Kanäle';
|
||
|
||
@override
|
||
String get storeCategoryWeb => 'Web';
|
||
|
||
@override
|
||
String get storeCategoryOrchestrator => 'Orchestrierung';
|
||
|
||
@override
|
||
String storeNResults(int n) {
|
||
return '$n Treffer';
|
||
}
|
||
|
||
@override
|
||
String get storeReloadTooltip => 'Aktualisieren';
|
||
|
||
@override
|
||
String get storeTodayBadge => 'HEUTE';
|
||
|
||
@override
|
||
String get storeTodayDeck => 'Von der F∆I-Redaktion';
|
||
|
||
@override
|
||
String get storeTodayDismissTooltip => 'Für diese Sitzung ausblenden';
|
||
|
||
@override
|
||
String get storePillInstalled => 'installiert';
|
||
|
||
@override
|
||
String get storePillUpdate => 'Update';
|
||
|
||
@override
|
||
String storeUpdateButton(String version) {
|
||
return 'Update auf $version';
|
||
}
|
||
|
||
@override
|
||
String storeUpdateTooltip(String installed, String best) {
|
||
return 'Installiert $installed — Store bietet v$best';
|
||
}
|
||
|
||
@override
|
||
String get storeNoTagline => '(keine Beschreibung)';
|
||
|
||
@override
|
||
String get storeUninstallTitle => 'Modul deinstallieren?';
|
||
|
||
@override
|
||
String storeUninstallBody(String name) {
|
||
return 'Entfernt $name aus diesem Hub. Flows, die es verwenden, schlagen beim nächsten Lauf fehl.';
|
||
}
|
||
|
||
@override
|
||
String storeInstalledToast(String name, String version) {
|
||
return '$name v$version installiert.';
|
||
}
|
||
|
||
@override
|
||
String storeInstallFailedToast(String error) {
|
||
return 'Installation fehlgeschlagen: $error';
|
||
}
|
||
|
||
@override
|
||
String storeUninstalledToast(String name, String version) {
|
||
return '$name v$version deinstalliert.';
|
||
}
|
||
|
||
@override
|
||
String storeUninstallFailedToast(String error) {
|
||
return 'Deinstallation fehlgeschlagen: $error';
|
||
}
|
||
|
||
@override
|
||
String storeOpenBrowserFailed(String error) {
|
||
return 'Browser konnte nicht geöffnet werden: $error';
|
||
}
|
||
|
||
@override
|
||
String get storeSectionTags => 'Tags';
|
||
|
||
@override
|
||
String get storeSectionRequiredCapabilities => 'Erforderliche Fähigkeiten';
|
||
|
||
@override
|
||
String get storeSectionRequiredHostServices => 'Erforderliche Host-Dienste';
|
||
|
||
@override
|
||
String get storeSectionScreenshots => 'Screenshots';
|
||
|
||
@override
|
||
String get storeSectionDocumentation => 'Dokumentation';
|
||
|
||
@override
|
||
String get storeSectionSource => 'Quelle';
|
||
|
||
@override
|
||
String get storeSectionPermissions => 'Deklarierte Berechtigungen';
|
||
|
||
@override
|
||
String get storeSectionDirectory => 'Modul-Verzeichnis';
|
||
|
||
@override
|
||
String get storeSectionPermissionsNone => '(keine — reines Berechnungsmodul)';
|
||
|
||
@override
|
||
String get storeInstallingButton => 'Installiere…';
|
||
|
||
@override
|
||
String get storeNotInstallable => 'Nicht installierbar';
|
||
|
||
@override
|
||
String storeNotInstallableTooltip(String status) {
|
||
return 'Status „$status\" — Installations-Pfad noch nicht verdrahtet.';
|
||
}
|
||
|
||
@override
|
||
String storeInstallProgressTitle(String name) {
|
||
return 'Installation von $name';
|
||
}
|
||
|
||
@override
|
||
String get storeInstallProgressBody => 'Holen, verifizieren, entpacken…';
|
||
|
||
@override
|
||
String get storeLoadDocs => 'Dokumentation laden';
|
||
|
||
@override
|
||
String get storeDocsHint =>
|
||
'README inline gerendert; nutzt das Registry-Token des Hubs, falls nötig.';
|
||
|
||
@override
|
||
String get storeDocsFetching => 'README wird geladen…';
|
||
|
||
@override
|
||
String get storeOpenRepoButton => 'Repository im Browser öffnen';
|
||
|
||
@override
|
||
String get storeDocsErrorNotFound =>
|
||
'Dieses Modul ist nicht im Store-Index des Hubs enthalten.';
|
||
|
||
@override
|
||
String get storeDocsErrorNoDocs =>
|
||
'Für dieses Modul ist keine Repository-URL hinterlegt.';
|
||
|
||
@override
|
||
String get storeDocsErrorAuth =>
|
||
'Die Registry erfordert Authentifizierung, um dieses README zu laden. Setze FAI_REGISTRY_TOKEN in der Umgebung des Daemons und starte den Hub neu.';
|
||
|
||
@override
|
||
String storeDocsErrorNetwork(String detail) {
|
||
return 'Netzwerkfehler beim Laden des README. $detail';
|
||
}
|
||
|
||
@override
|
||
String get storeDocsErrorParse => 'README ist kein gültiges UTF-8.';
|
||
|
||
@override
|
||
String get storeDocsErrorGeneric => 'README konnte nicht geladen werden.';
|
||
|
||
@override
|
||
String get storeSourceLabel => 'Quelle';
|
||
|
||
@override
|
||
String get storeSourceAll => 'Alle Quellen';
|
||
|
||
@override
|
||
String get storeSourceNative => 'Nativ';
|
||
|
||
@override
|
||
String get storeSourceMcp => 'MCP';
|
||
|
||
@override
|
||
String get storeSourceN8n => 'n8n';
|
||
|
||
@override
|
||
String get storeProvenanceNative => 'nativ';
|
||
|
||
@override
|
||
String storeProvenanceMcp(String provider) {
|
||
return 'mcp · $provider';
|
||
}
|
||
|
||
@override
|
||
String storeProvenanceN8n(String provider) {
|
||
return 'n8n · $provider';
|
||
}
|
||
|
||
@override
|
||
String get storeRecommendedTitle =>
|
||
'Öffentliche Quelle hinzufügen — ein Klick';
|
||
|
||
@override
|
||
String get storeRecommendedBody =>
|
||
'Kuratierte MCP-Server über HTTPS erreichbar. Kein Subprozess, kein API-Key, kein Node. Föderierte Fähigkeiten erscheinen sofort im Store.';
|
||
|
||
@override
|
||
String get storeRecommendedAddTooltip => 'Hinzufügen und entdecken';
|
||
|
||
@override
|
||
String get storeRecommendedAdding => 'Wird hinzugefügt…';
|
||
|
||
@override
|
||
String get storeRecommendedDeepWikiTagline =>
|
||
'GitHub-Repo-Doku-Suche (KI-gestützt)';
|
||
|
||
@override
|
||
String get storeRecommendedSemgrepTagline =>
|
||
'Security-Scanning für Code-Schwachstellen';
|
||
|
||
@override
|
||
String storeProviderAddedToast(String name, int n) {
|
||
String _temp0 = intl.Intl.pluralLogic(
|
||
n,
|
||
locale: localeName,
|
||
other: 'föderierte Fähigkeiten',
|
||
one: 'föderierte Fähigkeit',
|
||
);
|
||
return '$name hinzugefügt — $n $_temp0.';
|
||
}
|
||
|
||
@override
|
||
String storeProviderAddedZeroToast(String name) {
|
||
return '$name ist eingetragen, aber der Server hat noch keine Fähigkeiten geliefert. Öffne Einstellungen → MCP-Clients, um Discovery erneut zu versuchen oder den Server zu prüfen.';
|
||
}
|
||
|
||
@override
|
||
String storeProviderAddFailed(String name, String error) {
|
||
return '$name konnte nicht hinzugefügt werden: $error';
|
||
}
|
||
|
||
@override
|
||
String get auditTitle => 'Protokoll';
|
||
|
||
@override
|
||
String get auditNoEvents => 'Noch keine Ereignisse';
|
||
|
||
@override
|
||
String get auditNoEventsHint =>
|
||
'Starte einen Flow, um den Audit-Stream zu füllen.\nEreignisse erscheinen innerhalb von Sekunden.';
|
||
|
||
@override
|
||
String get auditFilterAll => 'alle';
|
||
|
||
@override
|
||
String get auditFilterFlow => 'Flow';
|
||
|
||
@override
|
||
String get auditFilterStep => 'Step';
|
||
|
||
@override
|
||
String get auditFilterModule => 'Modul';
|
||
|
||
@override
|
||
String get auditClearLogTooltip => 'Protokoll löschen (nur local/dev Kanal)';
|
||
|
||
@override
|
||
String auditClearedToast(int n, String channel) {
|
||
return '$n Ereignisse auf Kanal „$channel\" gelöscht. Kette mit Marker neu geseedet.';
|
||
}
|
||
|
||
@override
|
||
String auditClearFailed(String detail) {
|
||
return 'Löschen fehlgeschlagen: $detail';
|
||
}
|
||
|
||
@override
|
||
String get auditExplain => 'Erklären';
|
||
|
||
@override
|
||
String get auditReask => 'Neu fragen';
|
||
|
||
@override
|
||
String get auditAsking => 'Frage läuft…';
|
||
|
||
@override
|
||
String get auditSystemAi => 'SYSTEM-AI';
|
||
|
||
@override
|
||
String get auditCachedPill => 'gecacht';
|
||
|
||
@override
|
||
String auditOriginalLatency(int ms) {
|
||
return 'ursprünglich $ms ms';
|
||
}
|
||
|
||
@override
|
||
String auditLatency(int ms) {
|
||
return '$ms ms';
|
||
}
|
||
|
||
@override
|
||
String get auditRegenerateTooltip =>
|
||
'Neu generieren — Cache überspringen, Modell erneut fragen';
|
||
|
||
@override
|
||
String auditLiveStatus(int n) {
|
||
String _temp0 = intl.Intl.pluralLogic(
|
||
n,
|
||
locale: localeName,
|
||
other: 'Ereignisse',
|
||
one: 'Ereignis',
|
||
);
|
||
return 'live · Abfrage alle 2s · $n $_temp0';
|
||
}
|
||
|
||
@override
|
||
String auditDisconnected(String error) {
|
||
return 'getrennt · $error';
|
||
}
|
||
|
||
@override
|
||
String get auditHashChainVerified => 'Hash-Kette verifiziert';
|
||
|
||
@override
|
||
String get auditDetailHeader => 'DETAIL';
|
||
|
||
@override
|
||
String get auditAskingFull => 'Frage an die konfigurierte System-AI läuft…';
|
||
|
||
@override
|
||
String get auditFixLabel => 'FIX';
|
||
|
||
@override
|
||
String auditCachedTooltipKnown(String at, String hits) {
|
||
return 'Aus dem lokalen Cache geliefert. Ursprünglich erzeugt am $at$hits.';
|
||
}
|
||
|
||
@override
|
||
String auditCachedTooltipUnknown(String hits) {
|
||
return 'Aus dem lokalen Cache geliefert. Ursprünglicher Zeitpunkt unbekannt$hits.';
|
||
}
|
||
|
||
@override
|
||
String auditCachedTooltipHits(int n) {
|
||
return ' · $n Treffer';
|
||
}
|
||
|
||
@override
|
||
String get auditConfigureSystemAi =>
|
||
'System-AI unter Einstellungen konfigurieren (Cmd+,)';
|
||
|
||
@override
|
||
String get auditClearDialogTitle => 'Audit-Log löschen?';
|
||
|
||
@override
|
||
String get auditClearDialogBody =>
|
||
'Löscht jedes Audit-Event auf dem aktiven Kanal und seedet einen neuen chain.reset-Marker mit Prüfer und Begründung. Auf beta / production verweigert. Nicht umkehrbar.';
|
||
|
||
@override
|
||
String get auditClearReviewerLabel => 'Prüfer';
|
||
|
||
@override
|
||
String get auditClearReasonLabel =>
|
||
'Begründung (im chain.reset-Marker festgehalten)';
|
||
|
||
@override
|
||
String get auditClearReasonHelper =>
|
||
'Erforderlich — Auditoren werden das lesen.';
|
||
|
||
@override
|
||
String get auditClearLogButton => 'Log löschen';
|
||
|
||
@override
|
||
String get modulesTitle => 'Module';
|
||
|
||
@override
|
||
String get modulesNoneTitle => 'Noch keine Module';
|
||
|
||
@override
|
||
String get modulesNoneHint =>
|
||
'`fai install <capability-name>` ausführen oder ~/.fai/modules/ prüfen.';
|
||
|
||
@override
|
||
String get modulesReloadTooltip => 'Aktualisieren';
|
||
|
||
@override
|
||
String get modulesRecentActivity => 'LETZTE AKTIVITÄT';
|
||
|
||
@override
|
||
String modulesRecentActivityHint(int n) {
|
||
return 'letzte $n install/uninstall-Ereignisse aus dem Audit-Log';
|
||
}
|
||
|
||
@override
|
||
String get modulesActivityInstalled => 'installiert';
|
||
|
||
@override
|
||
String get modulesActivityUninstalled => 'deinstalliert';
|
||
|
||
@override
|
||
String get modulesCapabilitiesLabel => 'Fähigkeiten';
|
||
|
||
@override
|
||
String get modulesUninstallTitle => 'Modul deinstallieren?';
|
||
|
||
@override
|
||
String modulesUninstallBody(String name, String version) {
|
||
return 'Entfernt $name v$version von diesem Hub. Flows, die es verwenden, schlagen beim nächsten Lauf fehl. Ein `module.uninstalled`-Audit-Event wird festgehalten.';
|
||
}
|
||
|
||
@override
|
||
String modulesUninstalledToast(String name, String version) {
|
||
return '$name v$version deinstalliert.';
|
||
}
|
||
|
||
@override
|
||
String modulesUninstallFailed(String error) {
|
||
return 'Deinstallation fehlgeschlagen: $error';
|
||
}
|
||
|
||
@override
|
||
String get modulesUninstalling => 'Wird deinstalliert…';
|
||
|
||
@override
|
||
String moduleSheetFailedToLoad(String error) {
|
||
return 'Laden fehlgeschlagen: $error';
|
||
}
|
||
|
||
@override
|
||
String get moduleSheetCapabilities => 'Fähigkeiten';
|
||
|
||
@override
|
||
String get moduleSheetPermissions => 'Deklarierte Berechtigungen';
|
||
|
||
@override
|
||
String get moduleSheetNoPermissions => '(keine — reines Berechnungsmodul)';
|
||
|
||
@override
|
||
String get flowsTitle => 'Flows';
|
||
|
||
@override
|
||
String get flowsReloadTooltip => 'Aktualisieren';
|
||
|
||
@override
|
||
String get flowsNoneTitle => 'Keine gespeicherten Flows';
|
||
|
||
@override
|
||
String get flowsNoneHint =>
|
||
'Flow speichern mit `fai admin flows save <name> <flow.yaml>`, dann taucht er hier auf.';
|
||
|
||
@override
|
||
String flowsRunDialogTitle(String name) {
|
||
return '$name ausführen';
|
||
}
|
||
|
||
@override
|
||
String get flowsRunDialogBody =>
|
||
'Pro deklariertem Input ein Feld. Bytes-Inputs öffnen einen Datei-Picker; alle anderen sind Klartext. Der Starten-Button aktiviert sich, wenn alle Pflichtfelder gefüllt sind.';
|
||
|
||
@override
|
||
String get flowsLoadingDefinition => 'Inputs werden geladen…';
|
||
|
||
@override
|
||
String get flowsDefinitionFailed =>
|
||
'Flow-Definition konnte nicht geladen werden';
|
||
|
||
@override
|
||
String get flowsNoInputs =>
|
||
'Dieser Flow deklariert keine Inputs. Starten klicken, um loszulegen.';
|
||
|
||
@override
|
||
String get flowsTypeBytesPick => 'Datei wählen…';
|
||
|
||
@override
|
||
String get flowsTypeBytesChange => 'Datei ändern';
|
||
|
||
@override
|
||
String get flowsTypeBytesNoFile => 'Keine Datei ausgewählt';
|
||
|
||
@override
|
||
String flowsTypeBytesSize(int n) {
|
||
return '$n Bytes';
|
||
}
|
||
|
||
@override
|
||
String get flowsRunErrorTitle => 'Flow-Lauf fehlgeschlagen';
|
||
|
||
@override
|
||
String flowsFileReadFailed(String path, String error) {
|
||
return '„$path\" konnte nicht gelesen werden: $error';
|
||
}
|
||
|
||
@override
|
||
String get flowsMissingModulesLabel => 'Braucht:';
|
||
|
||
@override
|
||
String get flowsRunDisabledTooltip =>
|
||
'Erst die fehlenden Module installieren.';
|
||
|
||
@override
|
||
String flowsInstallAllButton(int n) {
|
||
return 'Alle installieren ($n)';
|
||
}
|
||
|
||
@override
|
||
String get flowsInstallPillTooltip => 'Zum Installieren klicken';
|
||
|
||
@override
|
||
String get flowsInstallDepsTitle => 'Abhängigkeiten installieren';
|
||
|
||
@override
|
||
String get flowsInstallDepsBody =>
|
||
'Die fehlenden Module werden der Reihe nach installiert. Vorhandene Installationen bleiben unberührt.';
|
||
|
||
@override
|
||
String get flowsInstallStatusPending => 'Wartet';
|
||
|
||
@override
|
||
String get flowsInstallStatusInstalling => 'Wird installiert…';
|
||
|
||
@override
|
||
String flowsInstallStatusDone(String version) {
|
||
return 'Installiert v$version';
|
||
}
|
||
|
||
@override
|
||
String get flowsInstallStatusFailed => 'Fehlgeschlagen';
|
||
|
||
@override
|
||
String flowsInstallStatusFailedDetail(String error) {
|
||
return '$error';
|
||
}
|
||
|
||
@override
|
||
String get flowsInstallDepsAllDone => 'Alle Abhängigkeiten installiert.';
|
||
|
||
@override
|
||
String flowsInstallDepsAnyFailed(int ok, int failed) {
|
||
return '$ok installiert, $failed fehlgeschlagen.';
|
||
}
|
||
|
||
@override
|
||
String get flowsOpenInEditorTooltip => 'YAML-Datei im Standard-Editor öffnen';
|
||
|
||
@override
|
||
String flowsOpenInEditorFailed(String error) {
|
||
return 'Konnte Datei nicht öffnen: $error';
|
||
}
|
||
|
||
@override
|
||
String get welcomeChecklistAllSetTitle => 'Du bist eingerichtet.';
|
||
|
||
@override
|
||
String get welcomeChecklistAllSetBody =>
|
||
'Drei Stränge, an denen du als nächstes ziehen kannst:';
|
||
|
||
@override
|
||
String get welcomeChecklistNextAuditTitle => 'Audit-Log lesen';
|
||
|
||
@override
|
||
String get welcomeChecklistNextAuditBody =>
|
||
'Jede Installation, jeder Flow-Lauf, jede Freigabe landet im hash-verketteten Log. Im Protokoll-Tab siehst du, was dein Hub gemacht hat.';
|
||
|
||
@override
|
||
String get welcomeChecklistNextAuditButton => 'Protokoll öffnen';
|
||
|
||
@override
|
||
String get welcomeChecklistNextTodayTitle => 'Daily-Today-Story einrichten';
|
||
|
||
@override
|
||
String get welcomeChecklistNextTodayBody =>
|
||
'tools/today/propose.sh per Cron laufen lassen und die Editorial-Karte im Store füllt sich mit operator-kuratierten Stories.';
|
||
|
||
@override
|
||
String get welcomeChecklistNextTodayButton => 'Today-Doku öffnen';
|
||
|
||
@override
|
||
String get welcomeChecklistNextModuleTitle => 'Eigenes Modul bauen';
|
||
|
||
@override
|
||
String get welcomeChecklistNextModuleBody =>
|
||
'Mit `fai new module <name>` ein Rust+WASM-Scaffold erzeugen. Das module-sdk übernimmt die WIT-Plumbing; du schreibst nur ein typisiertes invoke.';
|
||
|
||
@override
|
||
String get welcomeChecklistNextModuleButton => 'Doku lesen';
|
||
|
||
@override
|
||
String get auditGroupToday => 'HEUTE';
|
||
|
||
@override
|
||
String get auditGroupYesterday => 'GESTERN';
|
||
|
||
@override
|
||
String get auditGroupThisWeek => 'DIESE WOCHE';
|
||
|
||
@override
|
||
String get auditGroupOlder => 'ÄLTER';
|
||
|
||
@override
|
||
String get auditEventViewFlowRun => 'Flow-Lauf ansehen';
|
||
|
||
@override
|
||
String auditFlowRunDialogTitle(String flow) {
|
||
return 'Flow-Lauf · $flow';
|
||
}
|
||
|
||
@override
|
||
String auditFlowRunDialogSubtitle(int n, String execution) {
|
||
String _temp0 = intl.Intl.pluralLogic(
|
||
n,
|
||
locale: localeName,
|
||
other: 'Ereignisse',
|
||
one: 'Ereignis',
|
||
);
|
||
return '$n $_temp0 für Lauf $execution';
|
||
}
|
||
|
||
@override
|
||
String get approvalsSelectAll => 'Alle wählen';
|
||
|
||
@override
|
||
String get approvalsClearSelection => 'Auswahl aufheben';
|
||
|
||
@override
|
||
String approvalsBatchSelected(int n) {
|
||
return '$n ausgewählt';
|
||
}
|
||
|
||
@override
|
||
String get approvalsBatchApprove => 'Alle freigeben';
|
||
|
||
@override
|
||
String get approvalsBatchReject => 'Alle ablehnen';
|
||
|
||
@override
|
||
String approvalsBatchApproveDoneToast(int n) {
|
||
return '$n Freigaben erteilt.';
|
||
}
|
||
|
||
@override
|
||
String approvalsBatchRejectDoneToast(int n) {
|
||
return '$n Freigaben abgelehnt.';
|
||
}
|
||
|
||
@override
|
||
String approvalsBatchPartialFailure(int ok, int failed) {
|
||
return '$ok erledigt, $failed fehlgeschlagen.';
|
||
}
|
||
|
||
@override
|
||
String get flowsRunButton => 'Starten';
|
||
|
||
@override
|
||
String flowsRunningTitle(String name) {
|
||
return '$name läuft';
|
||
}
|
||
|
||
@override
|
||
String get flowsRunning => 'Flow läuft…';
|
||
|
||
@override
|
||
String get flowsNoOutputs => 'Flow abgeschlossen ohne deklarierte Outputs.';
|
||
|
||
@override
|
||
String get approvalsTitle => 'Freigaben';
|
||
|
||
@override
|
||
String get approvalsTabPending => 'Offen';
|
||
|
||
@override
|
||
String get approvalsTabHistory => 'Verlauf';
|
||
|
||
@override
|
||
String get approvalsInboxZero => 'Posteingang leer';
|
||
|
||
@override
|
||
String get approvalsInboxHint =>
|
||
'Alles erledigt. Neue `system.approval@^0`-Schritte landen automatisch hier.';
|
||
|
||
@override
|
||
String get approvalsReloadTooltip => 'Aktualisieren';
|
||
|
||
@override
|
||
String get approvalsPillPending => 'offen';
|
||
|
||
@override
|
||
String get approvalsPillApproved => 'freigegeben';
|
||
|
||
@override
|
||
String get approvalsPillRejected => 'abgelehnt';
|
||
|
||
@override
|
||
String get approvalsPillExpired => 'abgelaufen';
|
||
|
||
@override
|
||
String get approvalsPayloadPreview => 'PAYLOAD-VORSCHAU';
|
||
|
||
@override
|
||
String get approvalsApproveButton => 'Freigeben';
|
||
|
||
@override
|
||
String get approvalsRejectButton => 'Ablehnen';
|
||
|
||
@override
|
||
String get approvalsRejectDialogTitle => 'Freigabe ablehnen';
|
||
|
||
@override
|
||
String get approvalsRejectReasonLabel =>
|
||
'Begründung (im Audit-Log festgehalten)';
|
||
|
||
@override
|
||
String approvalsApprovedToast(String flow, String step) {
|
||
return 'freigegeben · $flow › $step';
|
||
}
|
||
|
||
@override
|
||
String approvalsRejectedToast(String flow, String step) {
|
||
return 'abgelehnt · $flow › $step';
|
||
}
|
||
|
||
@override
|
||
String approvalsApproveFailed(String error) {
|
||
return 'Freigabe fehlgeschlagen: $error';
|
||
}
|
||
|
||
@override
|
||
String approvalsRejectFailed(String error) {
|
||
return 'Ablehnung fehlgeschlagen: $error';
|
||
}
|
||
|
||
@override
|
||
String get approvalsHistoryEmpty => 'Noch kein Verlauf';
|
||
|
||
@override
|
||
String get approvalsHistoryEmptyHint =>
|
||
'Entschiedene Freigaben (freigegeben / abgelehnt / abgelaufen) erscheinen hier.\nDas Audit-Log enthält den vollständigen hash-verketteten Datensatz.';
|
||
|
||
@override
|
||
String get approvalsDialogDecided => 'entschieden';
|
||
|
||
@override
|
||
String get approvalsDialogCreated => 'erstellt';
|
||
|
||
@override
|
||
String get approvalsDialogReason => 'Begründung';
|
||
|
||
@override
|
||
String get approvalsDialogPrompt => 'PROMPT';
|
||
|
||
@override
|
||
String approvalsExpiresIn(int minutes) {
|
||
return '${minutes}m';
|
||
}
|
||
|
||
@override
|
||
String approvalsExpiresInHours(int hours) {
|
||
return '${hours}h';
|
||
}
|
||
|
||
@override
|
||
String get doctorTitle => 'Diagnose';
|
||
|
||
@override
|
||
String get doctorSummaryModules => 'Module';
|
||
|
||
@override
|
||
String get doctorSummaryApprovals => 'Freigaben';
|
||
|
||
@override
|
||
String get doctorSummaryAudit => 'Protokoll';
|
||
|
||
@override
|
||
String get doctorSummaryServices => 'Dienste';
|
||
|
||
@override
|
||
String doctorSummaryCapabilities(int n) {
|
||
return '$n Fähigkeiten';
|
||
}
|
||
|
||
@override
|
||
String get doctorSummaryPending => 'offen';
|
||
|
||
@override
|
||
String doctorSummaryChain(int verified, int total) {
|
||
return '$verified/$total Kette';
|
||
}
|
||
|
||
@override
|
||
String get doctorSummaryDeclared => 'deklariert';
|
||
|
||
@override
|
||
String doctorModulesPanelSummary(int n, int m) {
|
||
return '$n Module · $m Fähigkeiten';
|
||
}
|
||
|
||
@override
|
||
String get doctorApprovalsNone => 'Keine offenen Freigaben';
|
||
|
||
@override
|
||
String doctorApprovalsCount(int n) {
|
||
String _temp0 = intl.Intl.pluralLogic(
|
||
n,
|
||
locale: localeName,
|
||
other: '$n Freigaben warten auf Prüfung',
|
||
one: '1 Freigabe wartet auf Prüfung',
|
||
);
|
||
return '$_temp0';
|
||
}
|
||
|
||
@override
|
||
String get doctorApprovalsAttentionPill => 'wichtig';
|
||
|
||
@override
|
||
String get doctorServicesEmpty => 'Keine Host-Dienste deklariert';
|
||
|
||
@override
|
||
String get doctorServicesEmptyHint =>
|
||
'in ~/.fai/config.yaml unter services: hinzufügen';
|
||
|
||
@override
|
||
String get doctorPillLoaded => 'geladen';
|
||
|
||
@override
|
||
String get doctorPillEmpty => 'leer';
|
||
|
||
@override
|
||
String get doctorRecheckTooltip => 'Erneut prüfen';
|
||
|
||
@override
|
||
String get doctorEventLogSection => 'Audit-Log';
|
||
|
||
@override
|
||
String get doctorModulesApprovalsSection => 'Module & Freigaben';
|
||
|
||
@override
|
||
String get doctorHostServicesSection => 'Host-Dienste';
|
||
|
||
@override
|
||
String get doctorDaemonFilesSection => 'Daemon-Dateien';
|
||
|
||
@override
|
||
String get doctorDaemonControlSection => 'Daemon-Steuerung';
|
||
|
||
@override
|
||
String get doctorChainIntact => 'Hash-Kette intakt';
|
||
|
||
@override
|
||
String doctorChainIntactDetail(int n) {
|
||
return '$n Ereignisse · prev_event_sha256 lückenlos verifiziert';
|
||
}
|
||
|
||
@override
|
||
String get doctorChainTampered => 'Manipulation erkannt';
|
||
|
||
@override
|
||
String doctorChainTamperedDetail(int verified, int total, String id) {
|
||
return '$verified von $total verifiziert vor Mismatch bei $id';
|
||
}
|
||
|
||
@override
|
||
String get doctorChainPillOk => 'WORM-1';
|
||
|
||
@override
|
||
String get doctorChainPillTamper => 'MANIPULIERT';
|
||
|
||
@override
|
||
String get doctorVerifyNow => 'Jetzt prüfen';
|
||
|
||
@override
|
||
String get doctorRestart => 'Neustart';
|
||
|
||
@override
|
||
String get doctorStart => 'Starten';
|
||
|
||
@override
|
||
String get doctorStop => 'Stoppen';
|
||
|
||
@override
|
||
String get doctorStatusAction => 'Status';
|
||
|
||
@override
|
||
String doctorRunningOn(String name, String endpoint) {
|
||
return 'Läuft auf $name: $endpoint';
|
||
}
|
||
|
||
@override
|
||
String doctorStoppedOn(String name) {
|
||
return '$name-Daemon gestoppt';
|
||
}
|
||
|
||
@override
|
||
String get doctorStatusUnknown => 'Daemon-Status: …';
|
||
|
||
@override
|
||
String get doctorPillRunning => 'läuft';
|
||
|
||
@override
|
||
String get doctorPillStopped => 'gestoppt';
|
||
|
||
@override
|
||
String get doctorDaemonControlHint =>
|
||
'Studio ruft das Platform-Binary auf — entspricht `fai daemon …`, sodass CLI und UI im Gleichschritt bleiben.';
|
||
|
||
@override
|
||
String get doctorDaemonControlWorking => 'Wird ausgeführt…';
|
||
|
||
@override
|
||
String get doctorPathLog => 'Log';
|
||
|
||
@override
|
||
String get doctorPathConfig => 'Konfig';
|
||
|
||
@override
|
||
String get doctorPathDb => 'Audit-DB';
|
||
|
||
@override
|
||
String get doctorPathModules => 'Module-Verzeichnis';
|
||
|
||
@override
|
||
String get doctorPathFlows => 'Flow-Verzeichnis';
|
||
|
||
@override
|
||
String get doctorPathPid => 'PID-Datei';
|
||
|
||
@override
|
||
String get doctorPathsEmpty =>
|
||
'Daemon hat keine Datei-Pfade gemeldet. Hub aktualisieren via `fai daemon restart`.';
|
||
|
||
@override
|
||
String doctorOpenError(String detail) {
|
||
return 'Konnte nicht öffnen: $detail';
|
||
}
|
||
|
||
@override
|
||
String doctorUpdateAvailable(String version) {
|
||
return 'Update verfügbar — $version';
|
||
}
|
||
|
||
@override
|
||
String doctorUpdateBody(String channel, String version) {
|
||
return 'Kanal $channel bietet jetzt $version. Per Button anwenden — Studio ruft `fai update apply --channel $channel` auf.';
|
||
}
|
||
|
||
@override
|
||
String get doctorUpdateUnreachable => 'Release-Host nicht erreichbar';
|
||
|
||
@override
|
||
String doctorUpdateUnreachableBody(String channel) {
|
||
return 'Release-Feed für $channel konnte nicht erreicht werden.';
|
||
}
|
||
|
||
@override
|
||
String doctorReleaseNotes(String url) {
|
||
return 'Notes: $url';
|
||
}
|
||
|
||
@override
|
||
String get doctorPillNew => 'neu';
|
||
|
||
@override
|
||
String get doctorPillOffline => 'offline';
|
||
|
||
@override
|
||
String get doctorApplyUpdate => 'Update anwenden';
|
||
|
||
@override
|
||
String get doctorApplying => 'Wird angewendet…';
|
||
|
||
@override
|
||
String get doctorApplyDone =>
|
||
'Update angewendet. Studio neu starten, um die neue Daemon-Version zu sehen.';
|
||
|
||
@override
|
||
String get mcpHeader => 'MCP-CLIENTS';
|
||
|
||
@override
|
||
String get mcpHint =>
|
||
'Externe MCP-Server bringen ihre Tools als `mcp.<server>.<tool>` Fähigkeiten ein. Einmal konfigurieren, im Store sichtbar.';
|
||
|
||
@override
|
||
String get mcpEmpty =>
|
||
'Keine MCP-Server konfiguriert. + klicken zum Hinzufügen.';
|
||
|
||
@override
|
||
String get n8nHeader => 'N8N-ENDPUNKTE';
|
||
|
||
@override
|
||
String get n8nHint =>
|
||
'Aktive n8n-Workflows erscheinen als `n8n.<endpoint>.<slug>` Fähigkeiten. Einmal konfigurieren, im Store sichtbar.';
|
||
|
||
@override
|
||
String get n8nEmpty =>
|
||
'Keine n8n-Endpunkte konfiguriert. + klicken zum Hinzufügen.';
|
||
|
||
@override
|
||
String get hubUnreachable => 'Hub nicht erreichbar';
|
||
|
||
@override
|
||
String get hubUnreachableHint => 'Hub starten mit `fai serve`.';
|
||
|
||
@override
|
||
String get languageEnglish => 'English';
|
||
|
||
@override
|
||
String get languageGerman => 'Deutsch';
|
||
|
||
@override
|
||
String get searchHint =>
|
||
'Springe überall hin — Module, Store, Flows, Seiten…';
|
||
|
||
@override
|
||
String get searchIndexing => 'Indiziere…';
|
||
|
||
@override
|
||
String get searchNoMatches => 'Keine Treffer.';
|
||
|
||
@override
|
||
String get searchHintNavigate => '↑↓ navigieren';
|
||
|
||
@override
|
||
String get searchHintOpen => 'Enter öffnen';
|
||
|
||
@override
|
||
String get searchHintClose => 'Esc schließen';
|
||
|
||
@override
|
||
String get searchGroupPages => 'Seiten';
|
||
|
||
@override
|
||
String get searchGroupModules => 'Module';
|
||
|
||
@override
|
||
String get searchGroupStore => 'Store';
|
||
|
||
@override
|
||
String get searchGroupFlows => 'Flows';
|
||
|
||
@override
|
||
String get searchSettingsLabel => 'Einstellungen';
|
||
|
||
@override
|
||
String searchPageHint(int n) {
|
||
return 'Seite · ⌘$n';
|
||
}
|
||
|
||
@override
|
||
String get searchSettingsHint => 'Hub-Endpunkt, Kanäle, System-AI · ⌘;';
|
||
|
||
@override
|
||
String searchInstalledModuleHint(String version) {
|
||
return 'installiertes Modul · v$version';
|
||
}
|
||
|
||
@override
|
||
String get searchStoreUncategorized => 'ohne Kategorie';
|
||
|
||
@override
|
||
String searchStoreHintWithTagline(String tagline) {
|
||
return 'Store · $tagline';
|
||
}
|
||
|
||
@override
|
||
String searchStoreHintWithCategory(String category) {
|
||
return 'Store · $category';
|
||
}
|
||
|
||
@override
|
||
String get searchSavedFlowHint => 'gespeicherter Flow';
|
||
|
||
@override
|
||
String get systemAiTitle => 'System-AI';
|
||
|
||
@override
|
||
String get systemAiIntro =>
|
||
'Die hub-interne LLM, die die Plattform selbst für Fehlererklärungen und Operator-Hilfe nutzt. Standardmäßig aus; hier konfigurieren. Siehe docs/architecture/system-ai.md, was über die Leitung geht.';
|
||
|
||
@override
|
||
String get systemAiProviderLabel => 'Provider';
|
||
|
||
@override
|
||
String get systemAiEndpointLabel => 'Endpunkt-URL (bis /v1)';
|
||
|
||
@override
|
||
String get systemAiApiKeyRequired =>
|
||
'API-Key-Umgebungsvariable (erforderlich)';
|
||
|
||
@override
|
||
String get systemAiApiKeyOptional => 'API-Key-Umgebungsvariable (optional)';
|
||
|
||
@override
|
||
String systemAiApiKeyDisclaimer(String name) {
|
||
return 'Studio liest oder speichert den Key-Wert nie — nur den Namen der Umgebungsvariable. Der Hub liest `\$$name` zur Anfragezeit.';
|
||
}
|
||
|
||
@override
|
||
String get systemAiTestConnection => 'Verbindung testen';
|
||
|
||
@override
|
||
String get systemAiTesting => 'Teste…';
|
||
|
||
@override
|
||
String get systemAiSave => 'Speichern';
|
||
|
||
@override
|
||
String get systemAiPrivacyHeader => 'PRIVACY-MODUS';
|
||
|
||
@override
|
||
String get systemAiPrivacyOffLabel => 'Aus';
|
||
|
||
@override
|
||
String get systemAiPrivacyOffDesc =>
|
||
'Feature deaktiviert. Keine Anfragen verlassen den Hub.';
|
||
|
||
@override
|
||
String get systemAiPrivacyRedactedLabel => 'Redigiert';
|
||
|
||
@override
|
||
String get systemAiPrivacyRedactedDesc =>
|
||
'Nur event_type / error / Modul-Namen. KRITIS-freundlicher Standard.';
|
||
|
||
@override
|
||
String get systemAiPrivacyFullLabel => 'Voll';
|
||
|
||
@override
|
||
String get systemAiPrivacyFullDesc =>
|
||
'Enthält das Audit-Detail-JSON (nur Hash — keine Roh-Payloads).';
|
||
|
||
@override
|
||
String get systemAiConnectionOk => 'Verbindung ok';
|
||
|
||
@override
|
||
String get systemAiConnectionFailed => 'Verbindung fehlgeschlagen';
|
||
|
||
@override
|
||
String systemAiReplyPrefix(String text) {
|
||
return 'Antwort: $text';
|
||
}
|
||
|
||
@override
|
||
String get systemAiModelLabel => 'Modell (erforderlich)';
|
||
|
||
@override
|
||
String get systemAiModelHintFallback =>
|
||
'Modell-Identifier, den der Provider erwartet';
|
||
|
||
@override
|
||
String get systemAiModelHelperBase =>
|
||
'Erforderlich: aus der Liste auswählen (Aktualisieren) oder eintippen.';
|
||
|
||
@override
|
||
String get systemAiModelHelperOllama =>
|
||
'Erforderlich: aus der Liste auswählen (Aktualisieren) oder eintippen. Mit Pull von Ollama herunterladen.';
|
||
|
||
@override
|
||
String get systemAiRefresh => 'Aktualisieren';
|
||
|
||
@override
|
||
String get systemAiPull => 'Pull';
|
||
|
||
@override
|
||
String get systemAiPulling => 'Lade…';
|
||
|
||
@override
|
||
String systemAiCouldNotListModels(String error) {
|
||
return 'Modelle konnten nicht aufgelistet werden: $error';
|
||
}
|
||
|
||
@override
|
||
String get systemAiNoModelsOllama =>
|
||
'Noch keine Modelle auf dem Ollama-Server. Oben eintippen und Pull klicken.';
|
||
|
||
@override
|
||
String get systemAiNoModelsGeneric => 'Provider lieferte keine Modelle.';
|
||
|
||
@override
|
||
String get systemAiSuitabilityRecommended => 'empfohlen';
|
||
|
||
@override
|
||
String get systemAiSuitabilityBalanced => 'ausgewogen';
|
||
|
||
@override
|
||
String get systemAiSuitabilitySmall => 'klein — Qualität evtl. eingeschränkt';
|
||
|
||
@override
|
||
String get systemAiSuitabilityLarge => 'groß — langsamer';
|
||
|
||
@override
|
||
String get systemAiSuitabilityHuge =>
|
||
'sehr groß — auf einem Laptop wahrscheinlich zu langsam';
|
||
|
||
@override
|
||
String get systemAiSuitabilityUnknown => 'Größe unbekannt';
|
||
|
||
@override
|
||
String systemAiHwDetected(String summary) {
|
||
return 'Erkannt: $summary';
|
||
}
|
||
|
||
@override
|
||
String systemAiHwReviewed(String date) {
|
||
return ' · Kuratierung geprüft $date';
|
||
}
|
||
|
||
@override
|
||
String systemAiLegendRecommended(String tier) {
|
||
return 'empfohlen für diese Hardware$tier';
|
||
}
|
||
|
||
@override
|
||
String get systemAiLegendBalanced => 'ausgewogen (4-8B)';
|
||
|
||
@override
|
||
String get systemAiLegendSmallLarge =>
|
||
'klein <3B / groß 9-15B / über Hardware';
|
||
|
||
@override
|
||
String get systemAiLegendHuge => 'sehr groß >15B';
|
||
|
||
@override
|
||
String get systemAiLegendUnknown => 'Größe unbekannt';
|
||
|
||
@override
|
||
String systemAiCacheRow(int n) {
|
||
String _temp0 = intl.Intl.pluralLogic(
|
||
n,
|
||
locale: localeName,
|
||
other: 'gespeicherte Erklärungen',
|
||
one: 'gespeicherte Erklärung',
|
||
);
|
||
return 'Cache: $n $_temp0. Identische Prompts treffen den Cache; Modell- oder Privacy-Modus-Wechsel leeren ihn automatisch.';
|
||
}
|
||
|
||
@override
|
||
String get systemAiCacheClear => 'Leeren';
|
||
|
||
@override
|
||
String systemAiCacheClearedToast(int n) {
|
||
return '$n gespeicherte System-AI-Erklärungen gelöscht.';
|
||
}
|
||
|
||
@override
|
||
String systemAiCacheClearFailed(String error) {
|
||
return 'Cache-Löschen fehlgeschlagen: $error';
|
||
}
|
||
|
||
@override
|
||
String get systemAiPullEmptyError =>
|
||
'Erst eine Modell-ID eintippen (z.B. gemma3:4b).';
|
||
|
||
@override
|
||
String systemAiPullFailedError(String error) {
|
||
return 'Pull fehlgeschlagen: $error';
|
||
}
|
||
}
|