feat(studio): MCP suggestions + Approvals/Audit/Settings i18n (v0.26.0)
- Add curated catalogue of 9 official Anthropic MCP servers as click-to-prefill chips in the Add-MCP-server dialog. Operator still confirms via "Add + discover"; nothing is auto-spawned, preserving the regulated-environment trust model. - Localize Approvals page: pending/history empty states, status pills, payload preview, approve/reject toasts, reject dialog, history detail dialog, expires-in pill. - Localize Audit page: filter chips, clear-log dialog and toasts, no-events / hub-unreachable empty states, live-status bar with pluralized event count, hash-chain-verified badge, System AI panel (cached pill, latency, regenerate tooltip, asking state), event-detail dialog actions. - Localize Settings dialog: hub-endpoint section, channel blurb + popup-menu items, System AI panel headers and off-blurb, MCP/N8N panel headers + pluralized counts + refresh/add/remove tooltips, Add-MCP and Add-n8n dialogs (intro, suggestions label, all field labels and hints, save buttons, toasts). Field labels that map directly to JSON keys (event_id, flow, step, module, provider, endpoint, model) stay English by design — they're technical identifiers, not UI copy. Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
This commit is contained in:
parent
349619d68e
commit
d25b4c87ae
9 changed files with 2022 additions and 209 deletions
|
|
@ -102,6 +102,182 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||
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>`-Capabilities.';
|
||||
|
||||
@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>`-Capabilities.';
|
||||
|
||||
@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';
|
||||
|
||||
|
|
@ -186,6 +362,128 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||
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. Chain 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-Chain 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';
|
||||
|
||||
|
|
@ -253,6 +551,86 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||
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-chained 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';
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue