feat(studio): Doctor + Modules localized + sparse-store federation nudge (v0.25.0)
Two threads.
Translation expansion: every visible string on the Doctor
page (section headers, status text, button labels, daemon-
control card, daemon-files panel, update banner) and the
Modules page (recent-activity strip, capabilities label,
uninstall dialog + toast) flips between DE and EN with the
sidebar toggle. Adds ~50 ARB keys split between
`app_en.arb` / `app_de.arb`. Pluralised + parametrised
strings (`{n} events verified`, `Running on {name}: {endpoint}`)
use the standard ICU placeholder syntax so future locales
slot in without code changes.
Sparse-store federation nudge: the Store page renders an
inline banner above the grid when the operator has zero
federated entries — single biggest store-fullness lever is
configuring an MCP server / n8n endpoint, so the banner
says exactly that and the button opens Settings straight
to the editor. Banner dismisses automatically the next
render after a federated entry appears.
Coverage stand for translation: Doctor + Modules + sidebar
+ page titles + nav + Cmd+K labels are bilingual. Settings
dialog, Approvals cards, Audit drilldown, MCP/n8n editors,
Store search hint + filter chips remain English-literal.
The infrastructure (ARB plumbing, generator hookup,
locale-notifier) means each follow-up surface is a
one-line ARB edit + one call-site swap.
Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
This commit is contained in:
parent
ee83eb851a
commit
349619d68e
11 changed files with 1091 additions and 80 deletions
|
|
@ -404,6 +404,24 @@ abstract class AppLocalizations {
|
|||
/// **'{n} result{n, plural, =1{} other{s}}'**
|
||||
String storeNResults(int n);
|
||||
|
||||
/// No description provided for @storeFederationNudgeTitle.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Want more capabilities?'**
|
||||
String get storeFederationNudgeTitle;
|
||||
|
||||
/// No description provided for @storeFederationNudgeBody.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Configure an MCP server or n8n endpoint in Settings → MCP Clients / N8N Endpoints. Discovered tools and workflows surface here as `mcp.<server>.<tool>` and `n8n.<endpoint>.<workflow>` capabilities — every Anthropic / community MCP server adds a handful at once.'**
|
||||
String get storeFederationNudgeBody;
|
||||
|
||||
/// No description provided for @storeFederationNudgeButton.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Open Settings'**
|
||||
String get storeFederationNudgeButton;
|
||||
|
||||
/// No description provided for @auditTitle.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
|
|
@ -434,12 +452,78 @@ abstract class AppLocalizations {
|
|||
/// **'No modules yet'**
|
||||
String get modulesNoneTitle;
|
||||
|
||||
/// No description provided for @modulesNoneHint.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Run `fai install <capability-name>` or check ~/.fai/modules/.'**
|
||||
String get modulesNoneHint;
|
||||
|
||||
/// No description provided for @modulesReloadTooltip.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Reload'**
|
||||
String get modulesReloadTooltip;
|
||||
|
||||
/// No description provided for @modulesRecentActivity.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'RECENT ACTIVITY'**
|
||||
String get modulesRecentActivity;
|
||||
|
||||
/// No description provided for @modulesRecentActivityHint.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'last {n} install/uninstall events from the audit log'**
|
||||
String modulesRecentActivityHint(int n);
|
||||
|
||||
/// No description provided for @modulesActivityInstalled.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'installed'**
|
||||
String get modulesActivityInstalled;
|
||||
|
||||
/// No description provided for @modulesActivityUninstalled.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'uninstalled'**
|
||||
String get modulesActivityUninstalled;
|
||||
|
||||
/// No description provided for @modulesCapabilitiesLabel.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Capabilities'**
|
||||
String get modulesCapabilitiesLabel;
|
||||
|
||||
/// No description provided for @modulesUninstallTitle.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Uninstall module?'**
|
||||
String get modulesUninstallTitle;
|
||||
|
||||
/// No description provided for @modulesUninstallBody.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Removes {name} v{version} from this hub. Flows that reference it will fail at the next run. A `module.uninstalled` audit event is recorded.'**
|
||||
String modulesUninstallBody(String name, String version);
|
||||
|
||||
/// No description provided for @modulesUninstalledToast.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Uninstalled {name} v{version}.'**
|
||||
String modulesUninstalledToast(String name, String version);
|
||||
|
||||
/// No description provided for @modulesUninstallFailed.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Uninstall failed: {error}'**
|
||||
String modulesUninstallFailed(String error);
|
||||
|
||||
/// No description provided for @modulesUninstalling.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Uninstalling…'**
|
||||
String get modulesUninstalling;
|
||||
|
||||
/// No description provided for @approvalsTitle.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
|
|
@ -476,6 +560,258 @@ abstract class AppLocalizations {
|
|||
/// **'Doctor'**
|
||||
String get doctorTitle;
|
||||
|
||||
/// No description provided for @doctorRecheckTooltip.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Re-check'**
|
||||
String get doctorRecheckTooltip;
|
||||
|
||||
/// No description provided for @doctorEventLogSection.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Event log'**
|
||||
String get doctorEventLogSection;
|
||||
|
||||
/// No description provided for @doctorModulesApprovalsSection.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Modules & approvals'**
|
||||
String get doctorModulesApprovalsSection;
|
||||
|
||||
/// No description provided for @doctorHostServicesSection.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Host services'**
|
||||
String get doctorHostServicesSection;
|
||||
|
||||
/// No description provided for @doctorDaemonFilesSection.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Daemon files'**
|
||||
String get doctorDaemonFilesSection;
|
||||
|
||||
/// No description provided for @doctorDaemonControlSection.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Daemon control'**
|
||||
String get doctorDaemonControlSection;
|
||||
|
||||
/// No description provided for @doctorChainIntact.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Hash chain intact'**
|
||||
String get doctorChainIntact;
|
||||
|
||||
/// No description provided for @doctorChainIntactDetail.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'{n} events · prev_event_sha256 verified end-to-end'**
|
||||
String doctorChainIntactDetail(int n);
|
||||
|
||||
/// No description provided for @doctorChainTampered.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Tampering detected'**
|
||||
String get doctorChainTampered;
|
||||
|
||||
/// No description provided for @doctorChainTamperedDetail.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'{verified} of {total} verified before mismatch at {id}'**
|
||||
String doctorChainTamperedDetail(int verified, int total, String id);
|
||||
|
||||
/// No description provided for @doctorChainPillOk.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'WORM-1'**
|
||||
String get doctorChainPillOk;
|
||||
|
||||
/// No description provided for @doctorChainPillTamper.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'TAMPER'**
|
||||
String get doctorChainPillTamper;
|
||||
|
||||
/// No description provided for @doctorVerifyNow.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Verify now'**
|
||||
String get doctorVerifyNow;
|
||||
|
||||
/// No description provided for @doctorRestart.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Restart'**
|
||||
String get doctorRestart;
|
||||
|
||||
/// No description provided for @doctorStart.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Start'**
|
||||
String get doctorStart;
|
||||
|
||||
/// No description provided for @doctorStop.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Stop'**
|
||||
String get doctorStop;
|
||||
|
||||
/// No description provided for @doctorStatusAction.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Status'**
|
||||
String get doctorStatusAction;
|
||||
|
||||
/// No description provided for @doctorRunningOn.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Running on {name}: {endpoint}'**
|
||||
String doctorRunningOn(String name, String endpoint);
|
||||
|
||||
/// No description provided for @doctorStoppedOn.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'{name} daemon stopped'**
|
||||
String doctorStoppedOn(String name);
|
||||
|
||||
/// No description provided for @doctorStatusUnknown.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Daemon status: …'**
|
||||
String get doctorStatusUnknown;
|
||||
|
||||
/// No description provided for @doctorPillRunning.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'running'**
|
||||
String get doctorPillRunning;
|
||||
|
||||
/// No description provided for @doctorPillStopped.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'stopped'**
|
||||
String get doctorPillStopped;
|
||||
|
||||
/// No description provided for @doctorDaemonControlHint.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Studio shells out to the platform binary — mirrors `fai daemon …` exactly so the CLI and UI stay in lockstep.'**
|
||||
String get doctorDaemonControlHint;
|
||||
|
||||
/// No description provided for @doctorDaemonControlWorking.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Working…'**
|
||||
String get doctorDaemonControlWorking;
|
||||
|
||||
/// No description provided for @doctorPathLog.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Log'**
|
||||
String get doctorPathLog;
|
||||
|
||||
/// No description provided for @doctorPathConfig.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Config'**
|
||||
String get doctorPathConfig;
|
||||
|
||||
/// No description provided for @doctorPathDb.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Audit DB'**
|
||||
String get doctorPathDb;
|
||||
|
||||
/// No description provided for @doctorPathModules.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Modules dir'**
|
||||
String get doctorPathModules;
|
||||
|
||||
/// No description provided for @doctorPathFlows.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Flows dir'**
|
||||
String get doctorPathFlows;
|
||||
|
||||
/// No description provided for @doctorPathPid.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'PID file'**
|
||||
String get doctorPathPid;
|
||||
|
||||
/// No description provided for @doctorPathsEmpty.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Daemon did not report file paths. Update the running hub via `fai daemon restart`.'**
|
||||
String get doctorPathsEmpty;
|
||||
|
||||
/// No description provided for @doctorOpenError.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Could not open: {detail}'**
|
||||
String doctorOpenError(String detail);
|
||||
|
||||
/// No description provided for @doctorUpdateAvailable.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Update available — {version}'**
|
||||
String doctorUpdateAvailable(String version);
|
||||
|
||||
/// No description provided for @doctorUpdateBody.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Channel {channel} now offers {version}. Apply via the button — Studio shells out to `fai update apply --channel {channel}`.'**
|
||||
String doctorUpdateBody(String channel, String version);
|
||||
|
||||
/// No description provided for @doctorUpdateUnreachable.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Release host unreachable'**
|
||||
String get doctorUpdateUnreachable;
|
||||
|
||||
/// No description provided for @doctorUpdateUnreachableBody.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Could not contact the release feed for {channel}.'**
|
||||
String doctorUpdateUnreachableBody(String channel);
|
||||
|
||||
/// No description provided for @doctorReleaseNotes.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'notes: {url}'**
|
||||
String doctorReleaseNotes(String url);
|
||||
|
||||
/// No description provided for @doctorPillNew.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'new'**
|
||||
String get doctorPillNew;
|
||||
|
||||
/// No description provided for @doctorPillOffline.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'offline'**
|
||||
String get doctorPillOffline;
|
||||
|
||||
/// No description provided for @doctorApplyUpdate.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Apply update'**
|
||||
String get doctorApplyUpdate;
|
||||
|
||||
/// No description provided for @doctorApplying.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Applying…'**
|
||||
String get doctorApplying;
|
||||
|
||||
/// No description provided for @doctorApplyDone.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Update applied. Restart Studio to see the new daemon version.'**
|
||||
String get doctorApplyDone;
|
||||
|
||||
/// No description provided for @mcpHeader.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue