chain-studio/lib/l10n/app_en.arb
flemming-it a7e2eb101a feat(studio): drop Modules tab, fold its content into Store detail (v0.35.0)
Modules-as-a-tab was redundant with the Store after the
"Installed" filter and the federation work landed. Two pieces
of unique content kept it alive: the per-module declared
permissions list and the on-disk module directory. Both now
live inside the Store detail sheet.

Changes:

- Sidebar nav loses the Modules entry. `_pages` no longer
  carries a `'modules'` slot. The unused `import
  'pages/modules.dart'` is dropped from main.dart. Smoke test
  updated to skip the Modules-text expectation.

- Store detail sheet (`_StoreDetailSheet`) gains two new
  sections, rendered only when the entry is installed and the
  hub returned `ModuleDetail` for it:

    Declared permissions  →  same icon-prefixed list the
                              old Modules sheet shipped
                              (`net:`, `fs.read:`, `fs.write:`,
                              `env:`, `hub:`).
    Module directory      →  selectable mono path so the
                              operator can paste it into a
                              shell.

  An async `moduleInfo` fetch fires from `initState` only when
  `widget.item.installed` is true, so the regular
  not-installed detail-sheet path takes no extra round-trip.
  Failures stay silent — the sections just hide.

- The `FaiModuleSheet` widget stays intact. Cmd+K still uses
  it as a quick-info modal for installed modules; the
  longer-form Store detail sheet covers the same data plus
  the description, screenshots, and docs that operators
  reach for in the Store.

Three new ARB keys: `storeSectionPermissions`,
`storeSectionDirectory`, `storeSectionPermissionsNone`.

Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
2026-05-08 14:57:51 +02:00

594 lines
28 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." },
"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. All values are sent as text payloads. For binary inputs use the `fai run` CLI.",
"flowsInputsHint": "name=World\ntarget_language=English\nsummary_style=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" } } }
}