feat(studio): first-run UX, recovery affordances, l10n, bundled fonts

- Connection-aware Welcome: when the hub is down, show a hero with a
  primary "Start hub" CTA + install fallback instead of a dead,
  all-unchecked onboarding checklist (the first-run cliff).
- Actionable binary-not-found (file picker + install link, not a
  "set FAI_BIN" dead end) and a connect-failure banner after
  repeated failed health polls.
- Localize six hardcoded English error/toast clusters (DE+EN ARB).
- Bundle Inter + JetBrains Mono as assets; drop the runtime
  google_fonts fetch (air-gap / KRITIS safe, no font-swap flash).

Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
This commit is contained in:
flemming-it 2026-06-11 23:52:18 +02:00
parent 7511867774
commit 5313266cc4
25 changed files with 1231 additions and 234 deletions

View file

@ -4279,6 +4279,197 @@ abstract class AppLocalizations {
/// In en, this message translates to:
/// **'Install failed: {error}'**
String installFailed(String error);
/// No description provided for @welcomeHubDownTitle.
///
/// In en, this message translates to:
/// **'The hub isn\'t running yet'**
String get welcomeHubDownTitle;
/// No description provided for @welcomeHubDownBody.
///
/// In en, this message translates to:
/// **'Studio talks to a local hub — the engine that loads modules and runs flows. It isn\'t reachable right now. Start it to begin.'**
String get welcomeHubDownBody;
/// No description provided for @welcomeHubDownStart.
///
/// In en, this message translates to:
/// **'Start hub'**
String get welcomeHubDownStart;
/// No description provided for @welcomeHubDownStarting.
///
/// In en, this message translates to:
/// **'Starting…'**
String get welcomeHubDownStarting;
/// No description provided for @welcomeHubDownDocsLink.
///
/// In en, this message translates to:
/// **'Can\'t start it? Read the getting-started guide'**
String get welcomeHubDownDocsLink;
/// No description provided for @welcomeHubDownEndpoint.
///
/// In en, this message translates to:
/// **'Endpoint: {endpoint}'**
String welcomeHubDownEndpoint(String endpoint);
/// No description provided for @daemonStartRequested.
///
/// In en, this message translates to:
/// **'Daemon start requested. Reconnecting…'**
String get daemonStartRequested;
/// No description provided for @daemonStartFailed.
///
/// In en, this message translates to:
/// **'Could not start daemon: {detail}'**
String daemonStartFailed(String detail);
/// No description provided for @faiBinaryNotFound.
///
/// In en, this message translates to:
/// **'Could not find the `fai` program on this machine.'**
String get faiBinaryNotFound;
/// No description provided for @faiBinaryNotFoundHint.
///
/// In en, this message translates to:
/// **'Install the F∆I platform, or point Studio at an existing `fai` binary.'**
String get faiBinaryNotFoundHint;
/// No description provided for @faiBinaryLocateButton.
///
/// In en, this message translates to:
/// **'Locate `fai` binary…'**
String get faiBinaryLocateButton;
/// No description provided for @faiBinaryInstallDocsButton.
///
/// In en, this message translates to:
/// **'Open install guide'**
String get faiBinaryInstallDocsButton;
/// No description provided for @faiBinaryPickerTitle.
///
/// In en, this message translates to:
/// **'Select the `fai` binary'**
String get faiBinaryPickerTitle;
/// No description provided for @faiBinarySetOk.
///
/// In en, this message translates to:
/// **'Using `fai` binary at {path}'**
String faiBinarySetOk(String path);
/// No description provided for @sysAiFixParse.
///
/// In en, this message translates to:
/// **'The provider sent a response in an unexpected format. Providers that aren\'t OpenAI-compatible may need a translation proxy.'**
String get sysAiFixParse;
/// No description provided for @sysAiFixUnknown.
///
/// In en, this message translates to:
/// **'Unexpected failure ({kind}). See the System AI documentation.'**
String sysAiFixUnknown(String kind);
/// No description provided for @sysAiFixDisabled.
///
/// In en, this message translates to:
/// **'Configure System AI in Settings (Cmd+,) → System AI panel.'**
String get sysAiFixDisabled;
/// No description provided for @sysAiFixEnvMissing.
///
/// In en, this message translates to:
/// **'The API-key environment variable is empty. Set it in your shell, then restart the daemon.'**
String get sysAiFixEnvMissing;
/// No description provided for @sysAiFixNetwork.
///
/// In en, this message translates to:
/// **'The hub can\'t reach the configured endpoint. Is your provider running?'**
String get sysAiFixNetwork;
/// No description provided for @sysAiFixHttp.
///
/// In en, this message translates to:
/// **'The provider returned a non-2xx status. Verify the endpoint, model name, and API key.'**
String get sysAiFixHttp;
/// No description provided for @sysAiFixEmptyResponse.
///
/// In en, this message translates to:
/// **'The provider answered with no content. Try a different model or rephrase the prompt.'**
String get sysAiFixEmptyResponse;
/// No description provided for @channelSwitchOk.
///
/// In en, this message translates to:
/// **'Switched active channel to \"{name}\". Daemon restarted.'**
String channelSwitchOk(String name);
/// No description provided for @channelSwitchFailed.
///
/// In en, this message translates to:
/// **'Channel switch failed: {detail}'**
String channelSwitchFailed(String detail);
/// No description provided for @providerDescOllama.
///
/// In en, this message translates to:
/// **'Local `ollama serve`. Models stay on your machine. No API key needed.'**
String get providerDescOllama;
/// No description provided for @providerDescOpenai.
///
/// In en, this message translates to:
/// **'OpenAI hosted API. Requires an API key. Data leaves your machine.'**
String get providerDescOpenai;
/// No description provided for @providerDescLmstudio.
///
/// In en, this message translates to:
/// **'Local LM Studio server. Models stay on your machine. No API key needed.'**
String get providerDescLmstudio;
/// No description provided for @providerDescVllm.
///
/// In en, this message translates to:
/// **'Self-hosted vLLM or any other OpenAI-compatible server. Endpoint required.'**
String get providerDescVllm;
/// No description provided for @providerDescCustom.
///
/// In en, this message translates to:
/// **'Anything else that speaks the OpenAI-compatible chat-completions wire (LiteLLM proxy, internal mirror, …).'**
String get providerDescCustom;
/// No description provided for @welcomeDocLoadFailedBody.
///
/// In en, this message translates to:
/// **'Could not load the bundled doc \"{slug}\" ({locale}).\nTried: {attempted}\nUnderlying: {underlying}\nThis usually means the Studio build on disk predates the doc bundle. Rebuild Studio or open the online copy.'**
String welcomeDocLoadFailedBody(
String slug,
String locale,
String attempted,
String underlying,
);
/// No description provided for @hubUnreachableBanner.
///
/// In en, this message translates to:
/// **'Can\'t reach {endpoint} — open Settings'**
String hubUnreachableBanner(String endpoint);
/// No description provided for @hubUnreachableOpenSettings.
///
/// In en, this message translates to:
/// **'Open Settings'**
String get hubUnreachableOpenSettings;
}
class _AppLocalizationsDelegate