diff --git a/lib/l10n/app_de.arb b/lib/l10n/app_de.arb index ad82cf9..6a38afa 100644 --- a/lib/l10n/app_de.arb +++ b/lib/l10n/app_de.arb @@ -78,8 +78,8 @@ "welcomeChecklistBody": "Vier Schritte zu einem funktionierenden Hub. Live-Zustand — nach jeder Änderung aktualisieren.", "welcomeChecklistAi": "System-KI konfigurieren", "welcomeChecklistAiHint": "Einstellungen → System-KI. Wird für die KI-Suche und Fehlererklärungen gebraucht.", - "welcomeChecklistMcp": "Öffentlichen Werkzeug-Katalog verbinden", - "welcomeChecklistMcpHint": "Verbindet einen öffentlichen Werkzeug-Katalog (Fachbegriff: MCP) — dessen Fähigkeiten erscheinen dann im Store. Dort hinzufügen oder unter Einstellungen → MCP-Clients.", + "welcomeChecklistMcp": "Öffentliche Capability-Quelle hinzufügen", + "welcomeChecklistMcpHint": "Verbindet einen öffentlichen Werkzeug-Katalog (MCP) — dessen Bausteine erscheinen dann im Store. Dort hinzufügen oder unter Einstellungen → MCP-Clients.", "welcomeChecklistModule": "Ein Text-Modul installieren", "welcomeChecklistModuleHint": "Im Store ein Modul aus der Kategorie Ihrer Wahl installieren. Module sind isolierte (sandboxed) Ch∆In-Komponenten.", "welcomeChecklistFlow": "Einen gespeicherten Flow starten", @@ -1158,7 +1158,7 @@ } }, "doctorSummaryPending": "offen", - "doctorSummaryChain": "{verified} von {total} Ereignissen geprüft", + "doctorSummaryChain": "{verified}/{total} Kette", "@doctorSummaryChain": { "placeholders": { "verified": { @@ -1586,7 +1586,7 @@ "settingsAiPanelTitle": "System-KI", "settingsAiPanelBody": "Operator-verwalteter LLM-Endpunkt, den Studio für die KI-Helfer nutzt (System-KI-Edit, Install-Vorschläge, Doctor-Zusammenfassung). Kein Flow ruft das jemals auf; Module sprechen mit ihrem eigenen LLM.", "settingsIntegrationsPanelTitle": "Integrationen", - "settingsIntegrationsPanelBody": "Externe Tool-Server, deren Fähigkeiten der Hub föderiert. MCP-Server bieten Tool-Endpunkte; n8n-Endpunkte stellen gehostete Workflows bereit.", + "settingsIntegrationsPanelBody": "Externe Tool-Server, deren Capabilities der Hub föderiert. MCP-Server bieten Tool-Endpunkte; n8n-Endpunkte stellen gehostete Workflows bereit.", "settingsSecurityPanelTitle": "Sicherheit & Zugangsdaten", "settingsSecurityPanelBody": "Tokens, die der Hub für Sie verwahrt. Liegen in ~/.chain/ mit Modus 0600; werden nie als Telemetrie versendet.", "settingsMaintenancePanelTitle": "Wartung", @@ -1717,19 +1717,19 @@ "federationReloadTooltip": "Satelliten neu laden", "federationAddSatellite": "Satellit hinzufügen", "federationEmptyTitle": "Keine Satelliten verbunden", - "federationEmptyHint": "Verbinden Sie einen weiteren Hub als Satellit, um Fähigkeiten dort auszuführen. Stellen Sie dazu ein Registrierungs-Token aus.", + "federationEmptyHint": "Verbinden Sie einen weiteren Hub als Satellit, um Capabilities dort auszuführen. Stellen Sie dazu ein Enrollment-Token aus.", "federationPillConnected": "verbunden", "federationRegionNone": "keine Region", - "federationCapabilities": "{count} angebotene Fähigkeiten", - "federationAddDialogTitle": "Registrierungs-Token ausstellen", + "federationCapabilities": "{count} angebotene Capabilities", + "federationAddDialogTitle": "Enrollment-Token ausstellen", "federationNameLabel": "Satelliten-Name", "federationIssueButton": "Ausstellen", "federationIssueFailed": "Token konnte nicht ausgestellt werden: {error}", "federationEnrollmentTitle": "{name} einrichten", - "federationTokenLabel": "Einmal-Token für die Einrichtung", + "federationTokenLabel": "Bootstrap-Token (einmalig)", "federationConfigLabel": "Satelliten-Konfiguration (in den Satelliten einfügen)", "federationCopied": "In die Zwischenablage kopiert", - "federationEnrollmentHint": "Übergeben Sie das Token dem Satelliten-Betreiber über einen sicheren Kanal. Die mitgelieferte Zertifikatsstelle authentifiziert die erste Verbindung des Satelliten.", + "federationEnrollmentHint": "Übergib das Token dem Satelliten-Betreiber über einen sicheren Kanal. Die mitgelieferte CA authentifiziert den ersten Connect des Satelliten.", "workspaceAll": "Alle Projekte", "workspaceSwitcherTooltip": "Arbeitsbereich — filtert diese Ansicht und stempelt neue Läufe mit dem gewählten Projekt", "workspaceProtectedHint": "Geschützt: logisch getrennt im gemeinsamen Hub — keine harte Prozessgrenze. Kritische Mandate nutzen einen abgeschotteten Bereich.", diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 55b1cf2..d258a9d 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -86,8 +86,8 @@ "welcomeChecklistBody": "Four steps to a working hub. Live state — refresh after changing anything.", "welcomeChecklistAi": "Configure System AI", "welcomeChecklistAiHint": "Settings → System AI. Required for the AI search and inline failure explanations.", - "welcomeChecklistMcp": "Connect a public tool catalog", - "welcomeChecklistMcpHint": "Connects a public tool catalog (the technical term is MCP) — its capabilities then appear in the Store. Add one there, or under Settings → MCP Clients.", + "welcomeChecklistMcp": "Add a public capability source", + "welcomeChecklistMcpHint": "Add an MCP source from the Store, or configure one under Settings → MCP Clients.", "welcomeChecklistModule": "Install a text module", "welcomeChecklistModuleHint": "Install a module from the Store — pick whichever category fits your work. Modules are sandboxed Ch∆In components.", "welcomeChecklistFlow": "Run a saved flow", @@ -1182,7 +1182,7 @@ } }, "doctorSummaryPending": "pending", - "doctorSummaryChain": "{verified} of {total} events verified", + "doctorSummaryChain": "{verified}/{total} chain", "@doctorSummaryChain": { "placeholders": { "verified": { diff --git a/lib/l10n/app_localizations.dart b/lib/l10n/app_localizations.dart index a19dbb2..3d3bbbd 100644 --- a/lib/l10n/app_localizations.dart +++ b/lib/l10n/app_localizations.dart @@ -527,13 +527,13 @@ abstract class AppLocalizations { /// No description provided for @welcomeChecklistMcp. /// /// In en, this message translates to: - /// **'Connect a public tool catalog'** + /// **'Add a public capability source'** String get welcomeChecklistMcp; /// No description provided for @welcomeChecklistMcpHint. /// /// In en, this message translates to: - /// **'Connects a public tool catalog (the technical term is MCP) — its capabilities then appear in the Store. Add one there, or under Settings → MCP Clients.'** + /// **'Add an MCP source from the Store, or configure one under Settings → MCP Clients.'** String get welcomeChecklistMcpHint; /// No description provided for @welcomeChecklistModule. @@ -3575,7 +3575,7 @@ abstract class AppLocalizations { /// No description provided for @doctorSummaryChain. /// /// In en, this message translates to: - /// **'{verified} of {total} events verified'** + /// **'{verified}/{total} chain'** String doctorSummaryChain(int verified, int total); /// No description provided for @doctorSummaryDeclared. diff --git a/lib/l10n/app_localizations_de.dart b/lib/l10n/app_localizations_de.dart index 017c2a0..2e1cad1 100644 --- a/lib/l10n/app_localizations_de.dart +++ b/lib/l10n/app_localizations_de.dart @@ -257,11 +257,11 @@ class AppLocalizationsDe extends AppLocalizations { 'Einstellungen → System-KI. Wird für die KI-Suche und Fehlererklärungen gebraucht.'; @override - String get welcomeChecklistMcp => 'Öffentlichen Werkzeug-Katalog verbinden'; + String get welcomeChecklistMcp => 'Öffentliche Capability-Quelle hinzufügen'; @override String get welcomeChecklistMcpHint => - 'Verbindet einen öffentlichen Werkzeug-Katalog (Fachbegriff: MCP) — dessen Fähigkeiten erscheinen dann im Store. Dort hinzufügen oder unter Einstellungen → MCP-Clients.'; + 'Verbindet einen öffentlichen Werkzeug-Katalog (MCP) — dessen Bausteine erscheinen dann im Store. Dort hinzufügen oder unter Einstellungen → MCP-Clients.'; @override String get welcomeChecklistModule => 'Ein Text-Modul installieren'; @@ -2077,7 +2077,7 @@ class AppLocalizationsDe extends AppLocalizations { @override String doctorSummaryChain(int verified, int total) { - return '$verified von $total Ereignissen geprüft'; + return '$verified/$total Kette'; } @override @@ -2801,7 +2801,7 @@ class AppLocalizationsDe extends AppLocalizations { @override String get settingsIntegrationsPanelBody => - 'Externe Tool-Server, deren Fähigkeiten der Hub föderiert. MCP-Server bieten Tool-Endpunkte; n8n-Endpunkte stellen gehostete Workflows bereit.'; + 'Externe Tool-Server, deren Capabilities der Hub föderiert. MCP-Server bieten Tool-Endpunkte; n8n-Endpunkte stellen gehostete Workflows bereit.'; @override String get settingsSecurityPanelTitle => 'Sicherheit & Zugangsdaten'; @@ -3042,7 +3042,7 @@ class AppLocalizationsDe extends AppLocalizations { @override String get federationEmptyHint => - 'Verbinden Sie einen weiteren Hub als Satellit, um Fähigkeiten dort auszuführen. Stellen Sie dazu ein Registrierungs-Token aus.'; + 'Verbinden Sie einen weiteren Hub als Satellit, um Capabilities dort auszuführen. Stellen Sie dazu ein Enrollment-Token aus.'; @override String get federationPillConnected => 'verbunden'; @@ -3052,11 +3052,11 @@ class AppLocalizationsDe extends AppLocalizations { @override String federationCapabilities(int count) { - return '$count angebotene Fähigkeiten'; + return '$count angebotene Capabilities'; } @override - String get federationAddDialogTitle => 'Registrierungs-Token ausstellen'; + String get federationAddDialogTitle => 'Enrollment-Token ausstellen'; @override String get federationNameLabel => 'Satelliten-Name'; @@ -3075,7 +3075,7 @@ class AppLocalizationsDe extends AppLocalizations { } @override - String get federationTokenLabel => 'Einmal-Token für die Einrichtung'; + String get federationTokenLabel => 'Bootstrap-Token (einmalig)'; @override String get federationConfigLabel => @@ -3086,7 +3086,7 @@ class AppLocalizationsDe extends AppLocalizations { @override String get federationEnrollmentHint => - 'Übergeben Sie das Token dem Satelliten-Betreiber über einen sicheren Kanal. Die mitgelieferte Zertifikatsstelle authentifiziert die erste Verbindung des Satelliten.'; + 'Übergib das Token dem Satelliten-Betreiber über einen sicheren Kanal. Die mitgelieferte CA authentifiziert den ersten Connect des Satelliten.'; @override String get workspaceAll => 'Alle Projekte'; diff --git a/lib/l10n/app_localizations_en.dart b/lib/l10n/app_localizations_en.dart index 89f3b27..b450b96 100644 --- a/lib/l10n/app_localizations_en.dart +++ b/lib/l10n/app_localizations_en.dart @@ -257,11 +257,11 @@ class AppLocalizationsEn extends AppLocalizations { 'Settings → System AI. Required for the AI search and inline failure explanations.'; @override - String get welcomeChecklistMcp => 'Connect a public tool catalog'; + String get welcomeChecklistMcp => 'Add a public capability source'; @override String get welcomeChecklistMcpHint => - 'Connects a public tool catalog (the technical term is MCP) — its capabilities then appear in the Store. Add one there, or under Settings → MCP Clients.'; + 'Add an MCP source from the Store, or configure one under Settings → MCP Clients.'; @override String get welcomeChecklistModule => 'Install a text module'; @@ -2084,7 +2084,7 @@ class AppLocalizationsEn extends AppLocalizations { @override String doctorSummaryChain(int verified, int total) { - return '$verified of $total events verified'; + return '$verified/$total chain'; } @override diff --git a/lib/pages/doctor.dart b/lib/pages/doctor.dart index d91bbd9..42fda7f 100644 --- a/lib/pages/doctor.dart +++ b/lib/pages/doctor.dart @@ -1,5 +1,4 @@ import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; import '../data/error_presentation.dart'; import '../data/chain_log.dart'; @@ -437,19 +436,6 @@ class _PathRow extends StatelessWidget { ), ), const SizedBox(width: ChainSpace.sm), - IconButton( - icon: const Icon(Icons.copy_outlined, size: 14), - tooltip: l.buttonCopy, - visualDensity: VisualDensity.compact, - onPressed: () async { - await Clipboard.setData(ClipboardData(text: path)); - if (!context.mounted) return; - ScaffoldMessenger.of(context).showSnackBar( - SnackBar(content: Text(l.aboutCopiedToast)), - ); - }, - ), - const SizedBox(width: ChainSpace.xs), if (isLog || isConfig) ...[ OutlinedButton.icon( onPressed: () => isConfig @@ -729,31 +715,12 @@ class _DaemonActionsCardState extends State<_DaemonActionsCard> { } /// Format the per-source-kind capability count map as a -/// human-readable line like "6 Bundle · 3 MCP · 1 System". -/// Sorted alphabetically for deterministic rendering. The hub -/// reports lowercase wire identifiers; render them as display -/// names so no raw English tokens leak into the localized UI. +/// human-readable line like "6 bundle · 3 mcp · 1 system". +/// Sorted alphabetically for deterministic rendering. String _sourceBreakdown(Map bySource) { final entries = bySource.entries.toList() ..sort((a, b) => a.key.compareTo(b.key)); - return entries - .map((e) => '${e.value} ${_sourceKindLabel(e.key)}') - .join(' · '); -} - -String _sourceKindLabel(String kind) { - switch (kind) { - case 'mcp': - return 'MCP'; - case 'bundle': - return 'Bundle'; - case 'system': - return 'System'; - default: - return kind.isEmpty - ? kind - : kind[0].toUpperCase() + kind.substring(1); - } + return entries.map((e) => '${e.value} ${e.key}').join(' · '); } class _ModulesPanel extends StatelessWidget { diff --git a/test/l10n_formality_test.dart b/test/l10n_formality_test.dart index 86d9cdf..de1ae34 100644 --- a/test/l10n_formality_test.dart +++ b/test/l10n_formality_test.dart @@ -18,15 +18,10 @@ void main() { // Pronouns + possessives + common 2nd-person-singular verb // forms. Word-bounded so "individuell" or "Bedingungen" // never match. - // Also catches reader-addressed imperatives ("Übergib …", - // "Wähle …"). Only unambiguous ones — forms that double as - // the app's first-person progress voice ("Starte …") or as - // nouns ("Versuche") stay out. final informal = RegExp( r"\b(du|dich|dir|dein|deine|deiner|deinem|deinen|deins|" r"brauchst|tippst|willst|kannst|hast|bist|machst|siehst|" - r"klickst|wählst|öffnest|startest|versuchst|versuch's|" - r"übergib|wähle|klicke|tippe)\b", + r"klickst|wählst|öffnest|startest|versuchst|versuch's)\b", caseSensitive: false, ); final offenders = [];