Compare commits

..

No commits in common. "b52590c7d3d400daba1f0ac8cf41141a7118cf2a" and "dfc24d3c58e2dbd009dff4fb2dd2ae9a96be1131" have entirely different histories.

7 changed files with 31 additions and 69 deletions

View file

@ -78,8 +78,8 @@
"welcomeChecklistBody": "Vier Schritte zu einem funktionierenden Hub. Live-Zustand — nach jeder Änderung aktualisieren.", "welcomeChecklistBody": "Vier Schritte zu einem funktionierenden Hub. Live-Zustand — nach jeder Änderung aktualisieren.",
"welcomeChecklistAi": "System-KI konfigurieren", "welcomeChecklistAi": "System-KI konfigurieren",
"welcomeChecklistAiHint": "Einstellungen → System-KI. Wird für die KI-Suche und Fehlererklärungen gebraucht.", "welcomeChecklistAiHint": "Einstellungen → System-KI. Wird für die KI-Suche und Fehlererklärungen gebraucht.",
"welcomeChecklistMcp": "Öffentlichen Werkzeug-Katalog verbinden", "welcomeChecklistMcp": "Öffentliche Capability-Quelle hinzufügen",
"welcomeChecklistMcpHint": "Verbindet einen öffentlichen Werkzeug-Katalog (Fachbegriff: MCP) — dessen Fähigkeiten erscheinen dann im Store. Dort hinzufügen oder unter Einstellungen → MCP-Clients.", "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", "welcomeChecklistModule": "Ein Text-Modul installieren",
"welcomeChecklistModuleHint": "Im Store ein Modul aus der Kategorie Ihrer Wahl installieren. Module sind isolierte (sandboxed) Ch∆In-Komponenten.", "welcomeChecklistModuleHint": "Im Store ein Modul aus der Kategorie Ihrer Wahl installieren. Module sind isolierte (sandboxed) Ch∆In-Komponenten.",
"welcomeChecklistFlow": "Einen gespeicherten Flow starten", "welcomeChecklistFlow": "Einen gespeicherten Flow starten",
@ -1158,7 +1158,7 @@
} }
}, },
"doctorSummaryPending": "offen", "doctorSummaryPending": "offen",
"doctorSummaryChain": "{verified} von {total} Ereignissen geprüft", "doctorSummaryChain": "{verified}/{total} Kette",
"@doctorSummaryChain": { "@doctorSummaryChain": {
"placeholders": { "placeholders": {
"verified": { "verified": {
@ -1586,7 +1586,7 @@
"settingsAiPanelTitle": "System-KI", "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.", "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", "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", "settingsSecurityPanelTitle": "Sicherheit & Zugangsdaten",
"settingsSecurityPanelBody": "Tokens, die der Hub für Sie verwahrt. Liegen in ~/.chain/ mit Modus 0600; werden nie als Telemetrie versendet.", "settingsSecurityPanelBody": "Tokens, die der Hub für Sie verwahrt. Liegen in ~/.chain/ mit Modus 0600; werden nie als Telemetrie versendet.",
"settingsMaintenancePanelTitle": "Wartung", "settingsMaintenancePanelTitle": "Wartung",
@ -1717,19 +1717,19 @@
"federationReloadTooltip": "Satelliten neu laden", "federationReloadTooltip": "Satelliten neu laden",
"federationAddSatellite": "Satellit hinzufügen", "federationAddSatellite": "Satellit hinzufügen",
"federationEmptyTitle": "Keine Satelliten verbunden", "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", "federationPillConnected": "verbunden",
"federationRegionNone": "keine Region", "federationRegionNone": "keine Region",
"federationCapabilities": "{count} angebotene Fähigkeiten", "federationCapabilities": "{count} angebotene Capabilities",
"federationAddDialogTitle": "Registrierungs-Token ausstellen", "federationAddDialogTitle": "Enrollment-Token ausstellen",
"federationNameLabel": "Satelliten-Name", "federationNameLabel": "Satelliten-Name",
"federationIssueButton": "Ausstellen", "federationIssueButton": "Ausstellen",
"federationIssueFailed": "Token konnte nicht ausgestellt werden: {error}", "federationIssueFailed": "Token konnte nicht ausgestellt werden: {error}",
"federationEnrollmentTitle": "{name} einrichten", "federationEnrollmentTitle": "{name} einrichten",
"federationTokenLabel": "Einmal-Token für die Einrichtung", "federationTokenLabel": "Bootstrap-Token (einmalig)",
"federationConfigLabel": "Satelliten-Konfiguration (in den Satelliten einfügen)", "federationConfigLabel": "Satelliten-Konfiguration (in den Satelliten einfügen)",
"federationCopied": "In die Zwischenablage kopiert", "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", "workspaceAll": "Alle Projekte",
"workspaceSwitcherTooltip": "Arbeitsbereich — filtert diese Ansicht und stempelt neue Läufe mit dem gewählten Projekt", "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.", "workspaceProtectedHint": "Geschützt: logisch getrennt im gemeinsamen Hub — keine harte Prozessgrenze. Kritische Mandate nutzen einen abgeschotteten Bereich.",

View file

@ -86,8 +86,8 @@
"welcomeChecklistBody": "Four steps to a working hub. Live state — refresh after changing anything.", "welcomeChecklistBody": "Four steps to a working hub. Live state — refresh after changing anything.",
"welcomeChecklistAi": "Configure System AI", "welcomeChecklistAi": "Configure System AI",
"welcomeChecklistAiHint": "Settings → System AI. Required for the AI search and inline failure explanations.", "welcomeChecklistAiHint": "Settings → System AI. Required for the AI search and inline failure explanations.",
"welcomeChecklistMcp": "Connect a public tool catalog", "welcomeChecklistMcp": "Add a public capability source",
"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.", "welcomeChecklistMcpHint": "Add an MCP source from the Store, or configure one under Settings → MCP Clients.",
"welcomeChecklistModule": "Install a text module", "welcomeChecklistModule": "Install a text module",
"welcomeChecklistModuleHint": "Install a module from the Store — pick whichever category fits your work. Modules are sandboxed Ch∆In components.", "welcomeChecklistModuleHint": "Install a module from the Store — pick whichever category fits your work. Modules are sandboxed Ch∆In components.",
"welcomeChecklistFlow": "Run a saved flow", "welcomeChecklistFlow": "Run a saved flow",
@ -1182,7 +1182,7 @@
} }
}, },
"doctorSummaryPending": "pending", "doctorSummaryPending": "pending",
"doctorSummaryChain": "{verified} of {total} events verified", "doctorSummaryChain": "{verified}/{total} chain",
"@doctorSummaryChain": { "@doctorSummaryChain": {
"placeholders": { "placeholders": {
"verified": { "verified": {

View file

@ -527,13 +527,13 @@ abstract class AppLocalizations {
/// No description provided for @welcomeChecklistMcp. /// No description provided for @welcomeChecklistMcp.
/// ///
/// In en, this message translates to: /// In en, this message translates to:
/// **'Connect a public tool catalog'** /// **'Add a public capability source'**
String get welcomeChecklistMcp; String get welcomeChecklistMcp;
/// No description provided for @welcomeChecklistMcpHint. /// No description provided for @welcomeChecklistMcpHint.
/// ///
/// In en, this message translates to: /// 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; String get welcomeChecklistMcpHint;
/// No description provided for @welcomeChecklistModule. /// No description provided for @welcomeChecklistModule.
@ -3575,7 +3575,7 @@ abstract class AppLocalizations {
/// No description provided for @doctorSummaryChain. /// No description provided for @doctorSummaryChain.
/// ///
/// In en, this message translates to: /// In en, this message translates to:
/// **'{verified} of {total} events verified'** /// **'{verified}/{total} chain'**
String doctorSummaryChain(int verified, int total); String doctorSummaryChain(int verified, int total);
/// No description provided for @doctorSummaryDeclared. /// No description provided for @doctorSummaryDeclared.

View file

@ -257,11 +257,11 @@ class AppLocalizationsDe extends AppLocalizations {
'Einstellungen → System-KI. Wird für die KI-Suche und Fehlererklärungen gebraucht.'; 'Einstellungen → System-KI. Wird für die KI-Suche und Fehlererklärungen gebraucht.';
@override @override
String get welcomeChecklistMcp => 'Öffentlichen Werkzeug-Katalog verbinden'; String get welcomeChecklistMcp => 'Öffentliche Capability-Quelle hinzufügen';
@override @override
String get welcomeChecklistMcpHint => 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 @override
String get welcomeChecklistModule => 'Ein Text-Modul installieren'; String get welcomeChecklistModule => 'Ein Text-Modul installieren';
@ -2077,7 +2077,7 @@ class AppLocalizationsDe extends AppLocalizations {
@override @override
String doctorSummaryChain(int verified, int total) { String doctorSummaryChain(int verified, int total) {
return '$verified von $total Ereignissen geprüft'; return '$verified/$total Kette';
} }
@override @override
@ -2801,7 +2801,7 @@ class AppLocalizationsDe extends AppLocalizations {
@override @override
String get settingsIntegrationsPanelBody => 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 @override
String get settingsSecurityPanelTitle => 'Sicherheit & Zugangsdaten'; String get settingsSecurityPanelTitle => 'Sicherheit & Zugangsdaten';
@ -3042,7 +3042,7 @@ class AppLocalizationsDe extends AppLocalizations {
@override @override
String get federationEmptyHint => 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 @override
String get federationPillConnected => 'verbunden'; String get federationPillConnected => 'verbunden';
@ -3052,11 +3052,11 @@ class AppLocalizationsDe extends AppLocalizations {
@override @override
String federationCapabilities(int count) { String federationCapabilities(int count) {
return '$count angebotene Fähigkeiten'; return '$count angebotene Capabilities';
} }
@override @override
String get federationAddDialogTitle => 'Registrierungs-Token ausstellen'; String get federationAddDialogTitle => 'Enrollment-Token ausstellen';
@override @override
String get federationNameLabel => 'Satelliten-Name'; String get federationNameLabel => 'Satelliten-Name';
@ -3075,7 +3075,7 @@ class AppLocalizationsDe extends AppLocalizations {
} }
@override @override
String get federationTokenLabel => 'Einmal-Token für die Einrichtung'; String get federationTokenLabel => 'Bootstrap-Token (einmalig)';
@override @override
String get federationConfigLabel => String get federationConfigLabel =>
@ -3086,7 +3086,7 @@ class AppLocalizationsDe extends AppLocalizations {
@override @override
String get federationEnrollmentHint => 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 @override
String get workspaceAll => 'Alle Projekte'; String get workspaceAll => 'Alle Projekte';

View file

@ -257,11 +257,11 @@ class AppLocalizationsEn extends AppLocalizations {
'Settings → System AI. Required for the AI search and inline failure explanations.'; 'Settings → System AI. Required for the AI search and inline failure explanations.';
@override @override
String get welcomeChecklistMcp => 'Connect a public tool catalog'; String get welcomeChecklistMcp => 'Add a public capability source';
@override @override
String get welcomeChecklistMcpHint => 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 @override
String get welcomeChecklistModule => 'Install a text module'; String get welcomeChecklistModule => 'Install a text module';
@ -2084,7 +2084,7 @@ class AppLocalizationsEn extends AppLocalizations {
@override @override
String doctorSummaryChain(int verified, int total) { String doctorSummaryChain(int verified, int total) {
return '$verified of $total events verified'; return '$verified/$total chain';
} }
@override @override

View file

@ -1,5 +1,4 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import '../data/error_presentation.dart'; import '../data/error_presentation.dart';
import '../data/chain_log.dart'; import '../data/chain_log.dart';
@ -437,19 +436,6 @@ class _PathRow extends StatelessWidget {
), ),
), ),
const SizedBox(width: ChainSpace.sm), 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) ...[ if (isLog || isConfig) ...[
OutlinedButton.icon( OutlinedButton.icon(
onPressed: () => isConfig onPressed: () => isConfig
@ -729,31 +715,12 @@ class _DaemonActionsCardState extends State<_DaemonActionsCard> {
} }
/// Format the per-source-kind capability count map as a /// Format the per-source-kind capability count map as a
/// human-readable line like "6 Bundle · 3 MCP · 1 System". /// human-readable line like "6 bundle · 3 mcp · 1 system".
/// Sorted alphabetically for deterministic rendering. The hub /// Sorted alphabetically for deterministic rendering.
/// reports lowercase wire identifiers; render them as display
/// names so no raw English tokens leak into the localized UI.
String _sourceBreakdown(Map<String, int> bySource) { String _sourceBreakdown(Map<String, int> bySource) {
final entries = bySource.entries.toList() final entries = bySource.entries.toList()
..sort((a, b) => a.key.compareTo(b.key)); ..sort((a, b) => a.key.compareTo(b.key));
return entries return entries.map((e) => '${e.value} ${e.key}').join(' · ');
.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);
}
} }
class _ModulesPanel extends StatelessWidget { class _ModulesPanel extends StatelessWidget {

View file

@ -18,15 +18,10 @@ void main() {
// Pronouns + possessives + common 2nd-person-singular verb // Pronouns + possessives + common 2nd-person-singular verb
// forms. Word-bounded so "individuell" or "Bedingungen" // forms. Word-bounded so "individuell" or "Bedingungen"
// never match. // 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( final informal = RegExp(
r"\b(du|dich|dir|dein|deine|deiner|deinem|deinen|deins|" r"\b(du|dich|dir|dein|deine|deiner|deinem|deinen|deins|"
r"brauchst|tippst|willst|kannst|hast|bist|machst|siehst|" r"brauchst|tippst|willst|kannst|hast|bist|machst|siehst|"
r"klickst|wählst|öffnest|startest|versuchst|versuch's|" r"klickst|wählst|öffnest|startest|versuchst|versuch's)\b",
r"übergib|wähle|klicke|tippe)\b",
caseSensitive: false, caseSensitive: false,
); );
final offenders = <String>[]; final offenders = <String>[];