chain-studio/lib/l10n/app_en.arb
flemming-it 63e19974c0 feat(studio): @-syntax file inputs in flows, copyable doc errors, services-row overflow (v0.40.0)
Three concrete fixes against today's user feedback.

- Flows that take binary inputs (extract / extract-summarize /
  …) work from the Flows tab. The run-flow input dialog now
  accepts the same `@/path/to/file` syntax `fai run --input`
  uses on the CLI: any value beginning with `@` is read as
  bytes and sent as a binary Payload; plain values still flow
  through as text. The dialog hint copy and the example
  placeholder reflect the new syntax. File-read failures
  surface as a SnackBar before the run dialog opens, so a
  typo in the path doesn't reach the hub. Threaded through
  `_FlowRunDialog` and `HubService.runSavedFlow`, which both
  carry separate `textInputs` and `fileInputs` maps now and
  forward to the SDK's mixed-mode runSavedFlow (v0.14.0).

- The Welcome doc-reader's error path uses `FaiErrorBox` so
  the actual underlying error is selectable + copy-to-
  clipboard via the existing widget. Plus the loader throws
  a richer error string that names *both* attempted asset
  paths (`<slug>_<lang>.md` and the EN fallback) and the
  underlying exception each, so the operator can paste a
  diagnostic into a chat without us having to ship a
  separate "how to read Flutter asset errors" doc.

- Doctor's empty Services panel had a horizontal RenderFlex
  overflow at narrow widths because the long mono-spaced
  hint ("add to ~/.fai/config.yaml under services:") and
  the leading icon+text both demanded full intrinsic width
  in a single Row. Now wraps via a `Wrap` widget so the
  hint flows to a second line on narrow viewports and stays
  in the same row when there's space.

Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
2026-05-09 02:07:31 +02:00

639 lines
32 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{
"@@locale": "en",
"appTitle": "F∆I Studio",
"@appTitle": { "description": "App-bar title in the OS task switcher." },
"navWelcome": "Welcome",
"welcomeHeroTitle": "F∆I Platform",
"welcomeHeroSubtitle": "Deterministic workflow engine for AI-assisted document processing in regulated environments.",
"welcomePillarHubTitle": "Hub",
"welcomePillarHubBody": "One Rust binary that loads modules and runs flows. SQLite for state. No Docker, no message broker, no background services to babysit.",
"welcomePillarModuleTitle": "Module",
"welcomePillarModuleBody": "A small WebAssembly component that does one thing. Declares the network endpoints, files, and environment variables it touches; the hub enforces the list.",
"welcomePillarFlowTitle": "Flow",
"welcomePillarFlowBody": "A YAML file that chains modules together. Inputs go in, modules run in declared order, outputs come out — every step recorded in a hash-chained audit log.",
"welcomeTrustHeader": "TRUST POSTURE",
"welcomeTrustSandboxTitle": "Sandbox by default",
"welcomeTrustSandboxBody": "Every module ships with an explicit permission list — network endpoints, files, environment variables. The hub enforces it; nothing reaches outside the sandbox without operator approval.",
"welcomeTrustAuditTitle": "Tamper-evident audit log",
"welcomeTrustAuditBody": "Flow runs, install / uninstall actions, approval decisions — all of them write into a hash-chained audit log. The Doctor page verifies the chain end-to-end on every load.",
"welcomeTrustAirgapTitle": "Air-gap ready",
"welcomeTrustAirgapBody": "The whole hub fits in a single binary that runs on Linux, macOS and Windows. Once a module is installed, the flow it powers runs without further network access — perfect for regulated environments.",
"welcomeDocsHeader": "DOCUMENTATION",
"welcomeDocsBody": "Operator-facing explainers, rendered inline. No browser, no external link — air-gap-friendly.",
"welcomeDocArchitectureTitle": "Architecture in one paragraph",
"welcomeDocArchitectureBlurb": "Hub, Module, Flow — and how the three fit together.",
"welcomeDocSecurityTitle": "Sandbox model",
"welcomeDocSecurityBlurb": "What a module declares, what the operator caps, what the hub enforces.",
"welcomeDocAuditTitle": "Tamper-evident audit log",
"welcomeDocAuditBlurb": "How the hash chain works and why WORM-1 is enough for KRITIS.",
"welcomeDocFlowsTitle": "Flow composition",
"welcomeDocFlowsBlurb": "YAML basics, templating reference, the extract→summarize example.",
"welcomeDocClose": "Close",
"welcomeDocFailedToLoad": "Could not load documentation: {error}",
"@welcomeDocFailedToLoad": { "placeholders": { "error": { "type": "String" } } },
"welcomeChecklistHeader": "GETTING STARTED",
"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": "Add a public capability source",
"welcomeChecklistMcpHint": "Store → Today hero, or Settings → MCP Clients. DeepWiki and Semgrep are one click each.",
"welcomeChecklistModule": "Install a text module",
"welcomeChecklistModuleHint": "Store → search \"text\" → Install. Try text.extract for PDFs and DOCX.",
"welcomeChecklistFlow": "Run a saved flow",
"welcomeChecklistFlowHint": "Flows → pick one → Run. The bundled extract-summarize.yaml is a good first run.",
"welcomeChecklistAllDone": "All four steps complete.",
"welcomeChecklistDismiss": "Hide checklist",
"welcomeChecklistRefresh": "Refresh",
"welcomeChecklistRefreshing": "Checking…",
"welcomeChecklistDone": "Done",
"welcomeChecklistTodo": "Pending",
"navDoctor": "Doctor",
"navModules": "Modules",
"navStore": "Store",
"navFlows": "Flows",
"navAudit": "Audit",
"navApprovals": "Approvals",
"connectionConnected": "connected",
"connectionUnreachable": "unreachable",
"connectionConnecting": "connecting…",
"connectionStartHub": "Start hub",
"buttonCancel": "Cancel",
"buttonSave": "Save",
"buttonClose": "Close",
"buttonRetry": "Retry",
"buttonRefresh": "Refresh",
"buttonInstall": "Install",
"buttonUninstall": "Uninstall",
"buttonDetails": "Details",
"buttonAdd": "Add",
"buttonRemove": "Remove",
"buttonOpen": "Open",
"buttonExplain": "Explain",
"buttonReadDocs": "Read docs",
"buttonCopy": "Copy to clipboard",
"buttonCopied": "Copied",
"settingsTitle": "Hub endpoint",
"settingsHost": "Host",
"settingsPort": "Port",
"settingsTls": "TLS",
"settingsSaveAndConnect": "Save & connect",
"settingsLanguage": "Language",
"settingsLanguageHint": "App language. Affects every page; bilingual store entries also flip via this toggle.",
"settingsHubEndpointHint": "Where should Studio connect? Default is the local hub at 127.0.0.1:50051.",
"settingsTlsSubtitle": "https/grpc-secure",
"settingsPortError": "port must be 165535",
"channelsBlurb": "Switch hub channel (writes ~/.fai/current-channel and restarts the daemon). Connect just changes Studio's wire.",
"channelsActionsTooltip": "Channel actions",
"systemAiHeader": "SYSTEM AI",
"systemAiEnabled": "enabled",
"systemAiOff": "off",
"systemAiEdit": "Edit…",
"systemAiConfigure": "Configure…",
"systemAiOffBlurb": "Off — failure explanations on the audit page are disabled. Click Configure… to pick a provider (Ollama / OpenAI / LM Studio / vLLM / Custom). Operator config is rewritten in place; no daemon restart needed.",
"mcpServersCount": "{n} {n, plural, =1{server} other{servers}}",
"@mcpServersCount": { "placeholders": { "n": { "type": "int" } } },
"mcpRediscoverTooltip": "Re-run discovery",
"mcpAddTooltip": "Add MCP server",
"mcpRemoveTooltip": "Remove server",
"mcpToolsCount": "{n} {n, plural, =1{tool} other{tools}}",
"@mcpToolsCount": { "placeholders": { "n": { "type": "int" } } },
"n8nEndpointsCount": "{n} {n, plural, =1{endpoint} other{endpoints}}",
"@n8nEndpointsCount": { "placeholders": { "n": { "type": "int" } } },
"n8nWorkflowsCount": "{n} {n, plural, =1{workflow} other{workflows}}",
"@n8nWorkflowsCount": { "placeholders": { "n": { "type": "int" } } },
"n8nRediscoverTooltip": "Re-run discovery",
"n8nAddTooltip": "Add n8n endpoint",
"n8nRemoveTooltip": "Remove endpoint",
"addMcpTitle": "Add MCP server",
"addMcpIntro": "Tools the server advertises via `tools/list` appear in the Store as `mcp.<name>.<tool>` capabilities.",
"addMcpSuggestionsLabel": "Suggested servers — click to pre-fill",
"addMcpNameLabel": "Name (no dots)",
"addMcpNameHint": "filesystem",
"addMcpEndpointLabel": "Endpoint",
"addMcpEndpointHint": "http://127.0.0.1:3001/mcp",
"addMcpApiKeyLabel": "API key env var (optional)",
"addMcpApiKeyHint": "MCP_FILESYSTEM_TOKEN",
"addMcpNotesLabel": "Notes (optional)",
"addMcpAddButton": "Add + discover",
"addN8nTitle": "Add n8n endpoint",
"addN8nIntro": "Active workflows surface in the Store as `n8n.<name>.<workflow_slug>` capabilities.",
"addN8nNameLabel": "Name (no dots)",
"addN8nNameHint": "ops",
"addN8nBaseUrlLabel": "Base URL (without /api/v1)",
"addN8nBaseUrlHint": "https://n8n.example.com",
"addN8nApiKeyLabel": "API key env var (optional)",
"addN8nApiKeyHint": "N8N_OPS_KEY",
"addN8nNotesLabel": "Notes (optional)",
"addN8nAddButton": "Add + discover",
"addedMcpToast": "Added MCP server \"{name}\".",
"@addedMcpToast": { "placeholders": { "name": { "type": "String" } } },
"addedN8nToast": "Added n8n endpoint \"{name}\".",
"@addedN8nToast": { "placeholders": { "name": { "type": "String" } } },
"addFailedToast": "Add failed: {error}",
"@addFailedToast": { "placeholders": { "error": { "type": "String" } } },
"removeFailedToast": "Remove failed: {error}",
"@removeFailedToast": { "placeholders": { "error": { "type": "String" } } },
"refreshFailedToast": "Refresh failed: {error}",
"@refreshFailedToast": { "placeholders": { "error": { "type": "String" } } },
"channelsHeader": "CHANNELS",
"channelsActive": "active",
"channelsRunning": "running",
"channelsStopped": "stopped",
"channelsConnect": "Connect Studio to this channel",
"channelsSwitch": "Make this the active channel",
"channelsEnableAutostart": "Enable autostart at login",
"channelsDisableAutostart": "Disable autostart",
"storeSearchHint": "Search modules — name, tagline, tag, capability…",
"storeAskHint": "What do you need? Try \"a module that reads tabular data\" or just type a keyword.",
"storeAskSubmit": "Search",
"storeAskAi": "Ask the AI",
"storeAskClear": "Clear question",
"storeAskAiThinking": "Looking through modules…",
"storeAskAiUnavailable": "Configure a System AI in Settings to ask questions in plain language.",
"storeAskNoMatches": "No matches yet — refine the question or browse the grid below.",
"storeAskAnswerLabel": "AI suggestion",
"storeAskAnswerWhy": "Why this matches",
"storeAskMatchPill": "match",
"storeFilterLabel": "Filter",
"storeFilterActiveCount": "{n} active",
"@storeFilterActiveCount": { "placeholders": { "n": { "type": "int" } } },
"storeFilterReset": "Reset filters",
"storeFilterApply": "Done",
"storeFilterStatusGroup": "Status",
"storeFilterSourceGroup": "Source",
"storeFilterInstalledGroup": "Show only installed",
"storeFeatured": "FEATURED",
"storeFeaturedHint": "curated picks · click for details",
"storeNoMatches": "No matches",
"storeNoMatchesHint": "Adjust the filters or clear the search to see all entries.",
"storeClearFilters": "Clear filters",
"storeStatusAll": "All",
"storeStatusPublished": "stable",
"storeStatusAlpha": "experimental",
"storeStatusPlanned": "coming soon",
"storeInstalledOnly": "Installed",
"storeCategoryLabel": "Category",
"storeCategoryAll": "All categories",
"storeCategoryBridge": "Connectors",
"storeCategoryDebug": "Sample modules",
"storeCategoryText": "Text",
"storeCategoryLlm": "AI models",
"storeCategorySystem": "System",
"storeCategoryAuth": "Authentication",
"storeCategoryStorage": "Storage",
"storeCategoryChannel": "Channels",
"storeCategoryWeb": "Web",
"storeCategoryOrchestrator": "Orchestration",
"storeNResults": "{n} result{n, plural, =1{} other{s}}",
"@storeNResults": {
"placeholders": { "n": { "type": "int" } }
},
"storeReloadTooltip": "Reload",
"storeTodayBadge": "TODAY",
"storeTodayDeck": "From the F∆I editor",
"storeTodayDismissTooltip": "Hide for this session",
"storePillInstalled": "installed",
"storePillUpdate": "update",
"storeUpdateButton": "Update to {version}",
"@storeUpdateButton": { "placeholders": { "version": { "type": "String" } } },
"storeUpdateTooltip": "Installed {installed} — store has v{best}",
"@storeUpdateTooltip": {
"placeholders": {
"installed": { "type": "String" },
"best": { "type": "String" }
}
},
"storeNoTagline": "(no tagline)",
"storeUninstallTitle": "Uninstall module?",
"storeUninstallBody": "Removes {name} from this hub. Flows that reference it will fail at the next run.",
"@storeUninstallBody": { "placeholders": { "name": { "type": "String" } } },
"storeInstalledToast": "{name} v{version} installed.",
"@storeInstalledToast": {
"placeholders": {
"name": { "type": "String" },
"version": { "type": "String" }
}
},
"storeInstallFailedToast": "Install failed: {error}",
"@storeInstallFailedToast": { "placeholders": { "error": { "type": "String" } } },
"storeUninstalledToast": "{name} v{version} uninstalled.",
"@storeUninstalledToast": {
"placeholders": {
"name": { "type": "String" },
"version": { "type": "String" }
}
},
"storeUninstallFailedToast": "Uninstall failed: {error}",
"@storeUninstallFailedToast": { "placeholders": { "error": { "type": "String" } } },
"storeOpenBrowserFailed": "Could not open browser: {error}",
"@storeOpenBrowserFailed": { "placeholders": { "error": { "type": "String" } } },
"storeSectionTags": "Tags",
"storeSectionRequiredCapabilities": "Required capabilities",
"storeSectionRequiredHostServices": "Required host services",
"storeSectionScreenshots": "Screenshots",
"storeSectionDocumentation": "Documentation",
"storeSectionSource": "Source",
"storeSectionPermissions": "Declared permissions",
"storeSectionDirectory": "Module directory",
"storeSectionPermissionsNone": "(none — pure-computation module)",
"storeInstallingButton": "Installing…",
"storeNotInstallable": "Not installable",
"storeNotInstallableTooltip": "Status \"{status}\" — install path not yet wired.",
"@storeNotInstallableTooltip": { "placeholders": { "status": { "type": "String" } } },
"storeInstallProgressTitle": "Installing {name}",
"@storeInstallProgressTitle": { "placeholders": { "name": { "type": "String" } } },
"storeInstallProgressBody": "Fetching, verifying, unpacking…",
"storeLoadDocs": "Load documentation",
"storeDocsHint": "README rendered inline; uses the hub's registry token when needed.",
"storeDocsFetching": "Fetching README…",
"storeOpenRepoButton": "Open repository in browser",
"storeDocsErrorNotFound": "This module is not in the hub's store index.",
"storeDocsErrorNoDocs": "No repository URL is recorded for this module.",
"storeDocsErrorAuth": "The registry requires authentication to fetch this README. Set FAI_REGISTRY_TOKEN in the daemon's environment and restart the hub.",
"storeDocsErrorNetwork": "Network error while fetching the README. {detail}",
"@storeDocsErrorNetwork": { "placeholders": { "detail": { "type": "String" } } },
"storeDocsErrorParse": "README is not valid UTF-8.",
"storeDocsErrorGeneric": "Could not load README.",
"storeSourceLabel": "Source",
"storeSourceAll": "All sources",
"storeSourceNative": "Native",
"storeSourceMcp": "MCP",
"storeSourceN8n": "n8n",
"storeProvenanceNative": "native",
"storeProvenanceMcp": "mcp · {provider}",
"@storeProvenanceMcp": { "placeholders": { "provider": { "type": "String" } } },
"storeProvenanceN8n": "n8n · {provider}",
"@storeProvenanceN8n": { "placeholders": { "provider": { "type": "String" } } },
"storeRecommendedTitle": "Add a public source — one click",
"storeRecommendedBody": "Curated MCP servers reachable over HTTPS. No subprocess, no API key, no Node. Federated capabilities appear in the store immediately.",
"storeRecommendedAddTooltip": "Add and discover",
"storeRecommendedAdding": "Adding…",
"storeRecommendedDeepWikiTagline": "GitHub repo documentation search (AI-powered)",
"storeRecommendedSemgrepTagline": "Security scanning for code vulnerabilities",
"storeProviderAddedToast": "Added {name} — {n} federated {n, plural, =1{capability} other{capabilities}}.",
"@storeProviderAddedToast": {
"placeholders": {
"name": { "type": "String" },
"n": { "type": "int" }
}
},
"storeProviderAddedZeroToast": "{name} registered, but the server returned no capabilities yet. Open Settings → MCP Clients to retry discovery or check the server.",
"@storeProviderAddedZeroToast": {
"placeholders": { "name": { "type": "String" } }
},
"storeProviderAddFailed": "Could not add {name}: {error}",
"@storeProviderAddFailed": {
"placeholders": {
"name": { "type": "String" },
"error": { "type": "String" }
}
},
"auditTitle": "Audit",
"auditNoEvents": "No events yet",
"auditNoEventsHint": "Run a flow to populate the audit stream.\nEvents appear here within seconds.",
"auditFilterAll": "all",
"auditFilterFlow": "flow",
"auditFilterStep": "step",
"auditFilterModule": "module",
"auditClearLogTooltip": "Clear log (local/dev channels only)",
"auditClearedToast": "Cleared {n} events on channel \"{channel}\". Chain reseeded with marker.",
"@auditClearedToast": {
"placeholders": {
"n": { "type": "int" },
"channel": { "type": "String" }
}
},
"auditClearFailed": "Clear failed: {detail}",
"@auditClearFailed": { "placeholders": { "detail": { "type": "String" } } },
"auditExplain": "Explain",
"auditReask": "Re-ask",
"auditAsking": "Asking…",
"auditSystemAi": "SYSTEM AI",
"auditCachedPill": "cached",
"auditOriginalLatency": "orig {ms} ms",
"@auditOriginalLatency": { "placeholders": { "ms": { "type": "int" } } },
"auditLatency": "{ms} ms",
"@auditLatency": { "placeholders": { "ms": { "type": "int" } } },
"auditRegenerateTooltip": "Regenerate — skip cache, ask the model again",
"auditLiveStatus": "live · polling 2s · {n} {n, plural, =1{event} other{events}}",
"@auditLiveStatus": { "placeholders": { "n": { "type": "int" } } },
"auditDisconnected": "disconnected · {error}",
"@auditDisconnected": { "placeholders": { "error": { "type": "String" } } },
"auditHashChainVerified": "hash chain verified",
"auditDetailHeader": "DETAIL",
"auditAskingFull": "Asking the configured System AI…",
"auditFixLabel": "FIX",
"auditCachedTooltipKnown": "Served from the local cache. Originally generated on {at}{hits}.",
"@auditCachedTooltipKnown": {
"placeholders": {
"at": { "type": "String" },
"hits": { "type": "String" }
}
},
"auditCachedTooltipUnknown": "Served from the local cache. Originally generated at unknown time{hits}.",
"@auditCachedTooltipUnknown": { "placeholders": { "hits": { "type": "String" } } },
"auditCachedTooltipHits": " · {n} hits",
"@auditCachedTooltipHits": { "placeholders": { "n": { "type": "int" } } },
"auditConfigureSystemAi": "Configure System AI in Settings (Cmd+,)",
"auditClearDialogTitle": "Clear audit log?",
"auditClearDialogBody": "Wipes every audit event on the active channel and seeds a fresh chain.reset marker carrying reviewer + reason. Refused on beta / production. Irreversible.",
"auditClearReviewerLabel": "Reviewer",
"auditClearReasonLabel": "Reason (recorded in chain.reset marker)",
"auditClearReasonHelper": "Required — auditors will read this.",
"auditClearLogButton": "Clear log",
"modulesTitle": "Modules",
"modulesNoneTitle": "No modules yet",
"modulesNoneHint": "Run `fai install <capability-name>` or check ~/.fai/modules/.",
"modulesReloadTooltip": "Reload",
"modulesRecentActivity": "RECENT ACTIVITY",
"modulesRecentActivityHint": "last {n} install/uninstall events from the audit log",
"@modulesRecentActivityHint": { "placeholders": { "n": { "type": "int" } } },
"modulesActivityInstalled": "installed",
"modulesActivityUninstalled": "uninstalled",
"modulesCapabilitiesLabel": "Capabilities",
"modulesUninstallTitle": "Uninstall module?",
"modulesUninstallBody": "Removes {name} v{version} from this hub. Flows that reference it will fail at the next run. A `module.uninstalled` audit event is recorded.",
"@modulesUninstallBody": {
"placeholders": {
"name": { "type": "String" },
"version": { "type": "String" }
}
},
"modulesUninstalledToast": "Uninstalled {name} v{version}.",
"@modulesUninstalledToast": {
"placeholders": {
"name": { "type": "String" },
"version": { "type": "String" }
}
},
"modulesUninstallFailed": "Uninstall failed: {error}",
"@modulesUninstallFailed": { "placeholders": { "error": { "type": "String" } } },
"modulesUninstalling": "Uninstalling…",
"moduleSheetFailedToLoad": "Failed to load: {error}",
"@moduleSheetFailedToLoad": { "placeholders": { "error": { "type": "String" } } },
"moduleSheetCapabilities": "Capabilities",
"moduleSheetPermissions": "Declared permissions",
"moduleSheetNoPermissions": "(none — pure-computation module)",
"flowsTitle": "Flows",
"flowsReloadTooltip": "Reload",
"flowsNoneTitle": "No saved flows",
"flowsNoneHint": "Save a flow with `fai admin flows save <name> <flow.yaml>` and it shows up here.",
"flowsRunDialogTitle": "Run {name}",
"@flowsRunDialogTitle": { "placeholders": { "name": { "type": "String" } } },
"flowsRunDialogBody": "Inputs as key=value, one per line. Plain values send as text. Prefix the value with `@` to read a file as bytes — same as `fai run --input document=@/path/to/file.pdf`.",
"flowsInputsHint": "name=World\ndocument=@/Users/me/Documents/sample.pdf\nstyle=three bullet points",
"flowsRunButton": "Run",
"flowsRunningTitle": "Running {name}",
"@flowsRunningTitle": { "placeholders": { "name": { "type": "String" } } },
"flowsRunning": "Flow running…",
"flowsNoOutputs": "Flow completed with no declared outputs.",
"approvalsTitle": "Approvals",
"approvalsTabPending": "Pending",
"approvalsTabHistory": "History",
"approvalsInboxZero": "Inbox zero",
"approvalsInboxHint": "All caught up. New `system.approval@^0` steps land here automatically.",
"approvalsReloadTooltip": "Reload",
"approvalsPillPending": "pending",
"approvalsPillApproved": "approved",
"approvalsPillRejected": "rejected",
"approvalsPillExpired": "expired",
"approvalsPayloadPreview": "PAYLOAD PREVIEW",
"approvalsApproveButton": "Approve",
"approvalsRejectButton": "Reject",
"approvalsRejectDialogTitle": "Reject approval",
"approvalsRejectReasonLabel": "Reason (recorded in audit log)",
"approvalsApprovedToast": "approved · {flow} {step}",
"@approvalsApprovedToast": {
"placeholders": {
"flow": { "type": "String" },
"step": { "type": "String" }
}
},
"approvalsRejectedToast": "rejected · {flow} {step}",
"@approvalsRejectedToast": {
"placeholders": {
"flow": { "type": "String" },
"step": { "type": "String" }
}
},
"approvalsApproveFailed": "approve failed: {error}",
"@approvalsApproveFailed": { "placeholders": { "error": { "type": "String" } } },
"approvalsRejectFailed": "reject failed: {error}",
"@approvalsRejectFailed": { "placeholders": { "error": { "type": "String" } } },
"approvalsHistoryEmpty": "No history yet",
"approvalsHistoryEmptyHint": "Decided approvals (approved / rejected / expired) appear here.\nThe audit log keeps the full hash-chained record.",
"approvalsDialogDecided": "decided",
"approvalsDialogCreated": "created",
"approvalsDialogReason": "reason",
"approvalsDialogPrompt": "PROMPT",
"approvalsExpiresIn": "{minutes}m",
"@approvalsExpiresIn": { "placeholders": { "minutes": { "type": "int" } } },
"approvalsExpiresInHours": "{hours}h",
"@approvalsExpiresInHours": { "placeholders": { "hours": { "type": "int" } } },
"doctorTitle": "Doctor",
"doctorSummaryModules": "Modules",
"doctorSummaryApprovals": "Approvals",
"doctorSummaryAudit": "Audit",
"doctorSummaryServices": "Services",
"doctorSummaryCapabilities": "{n} capabilities",
"@doctorSummaryCapabilities": { "placeholders": { "n": { "type": "int" } } },
"doctorSummaryPending": "pending",
"doctorSummaryChain": "{verified}/{total} chain",
"@doctorSummaryChain": {
"placeholders": {
"verified": { "type": "int" },
"total": { "type": "int" }
}
},
"doctorSummaryDeclared": "declared",
"doctorModulesPanelSummary": "{n} modules · {m} capabilities",
"@doctorModulesPanelSummary": {
"placeholders": {
"n": { "type": "int" },
"m": { "type": "int" }
}
},
"doctorApprovalsNone": "No pending approvals",
"doctorApprovalsCount": "{n, plural, =1{1 approval awaiting review} other{{n} approvals awaiting review}}",
"@doctorApprovalsCount": { "placeholders": { "n": { "type": "int" } } },
"doctorApprovalsAttentionPill": "attention",
"doctorServicesEmpty": "No host services declared",
"doctorServicesEmptyHint": "add to ~/.fai/config.yaml under services:",
"doctorPillLoaded": "loaded",
"doctorPillEmpty": "empty",
"doctorRecheckTooltip": "Re-check",
"doctorEventLogSection": "Event log",
"doctorModulesApprovalsSection": "Modules & approvals",
"doctorHostServicesSection": "Host services",
"doctorDaemonFilesSection": "Daemon files",
"doctorDaemonControlSection": "Daemon control",
"doctorChainIntact": "Hash chain intact",
"doctorChainIntactDetail": "{n} events · prev_event_sha256 verified end-to-end",
"@doctorChainIntactDetail": { "placeholders": { "n": { "type": "int" } } },
"doctorChainTampered": "Tampering detected",
"doctorChainTamperedDetail": "{verified} of {total} verified before mismatch at {id}",
"@doctorChainTamperedDetail": {
"placeholders": {
"verified": { "type": "int" },
"total": { "type": "int" },
"id": { "type": "String" }
}
},
"doctorChainPillOk": "WORM-1",
"doctorChainPillTamper": "TAMPER",
"doctorVerifyNow": "Verify now",
"doctorRestart": "Restart",
"doctorStart": "Start",
"doctorStop": "Stop",
"doctorStatusAction": "Status",
"doctorRunningOn": "Running on {name}: {endpoint}",
"@doctorRunningOn": {
"placeholders": {
"name": { "type": "String" },
"endpoint": { "type": "String" }
}
},
"doctorStoppedOn": "{name} daemon stopped",
"@doctorStoppedOn": { "placeholders": { "name": { "type": "String" } } },
"doctorStatusUnknown": "Daemon status: …",
"doctorPillRunning": "running",
"doctorPillStopped": "stopped",
"doctorDaemonControlHint": "Studio shells out to the platform binary — mirrors `fai daemon …` exactly so the CLI and UI stay in lockstep.",
"doctorDaemonControlWorking": "Working…",
"doctorPathLog": "Log",
"doctorPathConfig": "Config",
"doctorPathDb": "Audit DB",
"doctorPathModules": "Modules dir",
"doctorPathFlows": "Flows dir",
"doctorPathPid": "PID file",
"doctorPathsEmpty": "Daemon did not report file paths. Update the running hub via `fai daemon restart`.",
"doctorOpenError": "Could not open: {detail}",
"@doctorOpenError": { "placeholders": { "detail": { "type": "String" } } },
"doctorUpdateAvailable": "Update available — {version}",
"@doctorUpdateAvailable": { "placeholders": { "version": { "type": "String" } } },
"doctorUpdateBody": "Channel {channel} now offers {version}. Apply via the button — Studio shells out to `fai update apply --channel {channel}`.",
"@doctorUpdateBody": {
"placeholders": {
"channel": { "type": "String" },
"version": { "type": "String" }
}
},
"doctorUpdateUnreachable": "Release host unreachable",
"doctorUpdateUnreachableBody": "Could not contact the release feed for {channel}.",
"@doctorUpdateUnreachableBody": { "placeholders": { "channel": { "type": "String" } } },
"doctorReleaseNotes": "notes: {url}",
"@doctorReleaseNotes": { "placeholders": { "url": { "type": "String" } } },
"doctorPillNew": "new",
"doctorPillOffline": "offline",
"doctorApplyUpdate": "Apply update",
"doctorApplying": "Applying…",
"doctorApplyDone": "Update applied. Restart Studio to see the new daemon version.",
"mcpHeader": "MCP CLIENTS",
"mcpHint": "External MCP servers federate their tools as `mcp.<server>.<tool>` capabilities. Configure once, see them in the Store.",
"mcpEmpty": "No MCP servers configured. Click + to add one.",
"n8nHeader": "N8N ENDPOINTS",
"n8nHint": "Active n8n workflows surface as `n8n.<endpoint>.<slug>` capabilities. Configure once, see them in the Store.",
"n8nEmpty": "No n8n endpoints configured. Click + to add one.",
"hubUnreachable": "Hub unreachable",
"hubUnreachableHint": "Start the hub with `fai serve`.",
"languageEnglish": "English",
"languageGerman": "Deutsch",
"searchHint": "Jump anywhere — modules, store, flows, pages…",
"searchIndexing": "Indexing…",
"searchNoMatches": "No matches.",
"searchHintNavigate": "↑↓ navigate",
"searchHintOpen": "enter open",
"searchHintClose": "esc close",
"searchGroupPages": "Pages",
"searchGroupModules": "Modules",
"searchGroupStore": "Store",
"searchGroupFlows": "Flows",
"searchSettingsLabel": "Settings",
"searchPageHint": "page · ⌘{n}",
"@searchPageHint": { "placeholders": { "n": { "type": "int" } } },
"searchSettingsHint": "hub endpoint, channels, system AI · ⌘;",
"searchInstalledModuleHint": "installed module · v{version}",
"@searchInstalledModuleHint": { "placeholders": { "version": { "type": "String" } } },
"searchStoreUncategorized": "uncategorized",
"searchStoreHintWithTagline": "store · {tagline}",
"@searchStoreHintWithTagline": { "placeholders": { "tagline": { "type": "String" } } },
"searchStoreHintWithCategory": "store · {category}",
"@searchStoreHintWithCategory": { "placeholders": { "category": { "type": "String" } } },
"searchSavedFlowHint": "saved flow",
"systemAiTitle": "System AI",
"systemAiIntro": "The hub-internal LLM the platform itself uses for inline failure explanations and operator help. Off by default; configure here. See docs/architecture/system-ai.md for what crosses the wire.",
"systemAiProviderLabel": "Provider",
"systemAiEndpointLabel": "Endpoint URL (up to /v1)",
"systemAiApiKeyRequired": "API key env var (required)",
"systemAiApiKeyOptional": "API key env var (optional)",
"systemAiApiKeyDisclaimer": "Studio never reads or stores the key value — only its env-var name. The hub reads `${name}` at request time.",
"@systemAiApiKeyDisclaimer": { "placeholders": { "name": { "type": "String" } } },
"systemAiTestConnection": "Test connection",
"systemAiTesting": "Testing…",
"systemAiSave": "Save",
"systemAiPrivacyHeader": "PRIVACY MODE",
"systemAiPrivacyOffLabel": "Off",
"systemAiPrivacyOffDesc": "Feature disabled. No requests leave the hub.",
"systemAiPrivacyRedactedLabel": "Redacted",
"systemAiPrivacyRedactedDesc": "Only event_type / error / module names. KRITIS-friendly default.",
"systemAiPrivacyFullLabel": "Full",
"systemAiPrivacyFullDesc": "Includes the audit detail JSON (hash-only — no raw payloads).",
"systemAiConnectionOk": "Connection ok",
"systemAiConnectionFailed": "Connection failed",
"systemAiReplyPrefix": "Reply: {text}",
"@systemAiReplyPrefix": { "placeholders": { "text": { "type": "String" } } },
"systemAiModelLabel": "Model (required)",
"systemAiModelHintFallback": "model identifier the provider expects",
"systemAiModelHelperBase": "Required: pick from the list (Refresh) or type one.",
"systemAiModelHelperOllama": "Required: pick from the list (Refresh) or type one. Use Pull to download from Ollama.",
"systemAiRefresh": "Refresh",
"systemAiPull": "Pull",
"systemAiPulling": "Pulling…",
"systemAiCouldNotListModels": "Could not list models: {error}",
"@systemAiCouldNotListModels": { "placeholders": { "error": { "type": "String" } } },
"systemAiNoModelsOllama": "No models on the Ollama server yet. Type one above and click Pull.",
"systemAiNoModelsGeneric": "Provider returned no models.",
"systemAiSuitabilityRecommended": "recommended",
"systemAiSuitabilityBalanced": "balanced",
"systemAiSuitabilitySmall": "small — quality may be limited",
"systemAiSuitabilityLarge": "large — slower",
"systemAiSuitabilityHuge": "huge — likely too slow on a laptop",
"systemAiSuitabilityUnknown": "size unknown",
"systemAiHwDetected": "Detected: {summary}",
"@systemAiHwDetected": { "placeholders": { "summary": { "type": "String" } } },
"systemAiHwReviewed": " · curation reviewed {date}",
"@systemAiHwReviewed": { "placeholders": { "date": { "type": "String" } } },
"systemAiLegendRecommended": "recommended for this hardware{tier}",
"@systemAiLegendRecommended": { "placeholders": { "tier": { "type": "String" } } },
"systemAiLegendBalanced": "balanced (4-8B)",
"systemAiLegendSmallLarge": "small <3B / large 9-15B / above hardware",
"systemAiLegendHuge": "huge >15B",
"systemAiLegendUnknown": "size unknown",
"systemAiCacheRow": "Cache: {n} cached {n, plural, =1{explanation} other{explanations}}. Identical prompts hit the cache; switching model or privacy mode flushes automatically.",
"@systemAiCacheRow": { "placeholders": { "n": { "type": "int" } } },
"systemAiCacheClear": "Clear",
"systemAiCacheClearedToast": "Cleared {n} cached System-AI explanations.",
"@systemAiCacheClearedToast": { "placeholders": { "n": { "type": "int" } } },
"systemAiCacheClearFailed": "Cache clear failed: {error}",
"@systemAiCacheClearFailed": { "placeholders": { "error": { "type": "String" } } },
"systemAiPullEmptyError": "Type a model id (e.g. gemma3:4b) first.",
"systemAiPullFailedError": "Pull failed: {error}",
"@systemAiPullFailedError": { "placeholders": { "error": { "type": "String" } } }
}