// Navi's interface strings: flat slugs grouped by area, one dictionary per
// language, the same slugs in all of them. A slug a dictionary does not carry
// yet falls back to English, and the English string is the literal the code
// used to hard-code — so a language that is still being filled in changes
// nothing a test or a reader of the English interface can see.
//
// Product names (Navi, Synapse, MCP, Ollama, GitHub…) are never translated.
// Strings with markup in them are split around it: the markup stays in the
// template, the words live here.
export default {
// app shell — document titles and other chrome outside the chat itself
'app.titleSettings': 'Navi — Settings',
// the artifacts drawer — published files, links, session files, backgrounds
'artifacts.panelLabel': 'Session artifacts',
'artifacts.resize': 'Resize artifacts',
'artifacts.close': 'Close artifacts',
'artifacts.closeDetails': 'Close details',
'artifacts.tabArtifacts': 'Artifacts',
'artifacts.tabLinks': 'Links',
'artifacts.tabFiles': 'Files',
'artifacts.tabBackgrounds': 'Backgrounds',
'artifacts.viewedImages': 'Viewed images',
'artifacts.viewedImageAlt': 'Image viewed by Navi {n}',
'artifacts.emptyArtifacts': 'No published files',
'artifacts.emptyLinks': 'No links found yet',
'artifacts.emptyFiles': 'No files in session directory',
'artifacts.emptyBackgrounds': 'No background tasks or terminals',
'artifacts.openPreview': 'Open preview',
'artifacts.openRaw': 'Open raw file',
'artifacts.openInline': 'Open inline',
'artifacts.showPreview': 'Show preview',
'artifacts.showSource': 'Show source',
'artifacts.copyFileLink': 'Copy file link',
'artifacts.copyAllLinks': 'Copy all links',
'artifacts.openAllLinks': 'Open all links',
'artifacts.refreshFiles': 'Refresh files',
'artifacts.linksInSession': { one: '{n} link in session', other: '{n} links in session' },
'artifacts.loadingSource': 'Loading source...',
'artifacts.previewUnavailable': 'Preview unavailable',
'artifacts.sourceFailed': 'Failed to load source: {error}',
'artifacts.latestProgress': 'Latest progress',
'artifacts.noOutput': 'No output yet — it arrives as a note next turn.',
'artifacts.terminal': 'Terminal',
'artifacts.directory': 'Directory',
'artifacts.toolAndAge': '{tool} · {age} ago',
'artifacts.statusRunning': 'Running',
'artifacts.statusDone': 'Done',
'artifacts.statusFailed': 'Failed',
'artifacts.statusStopped': 'Stopped',
'artifacts.statusBusy': 'Busy',
'artifacts.statusIdle': 'Idle',
'artifacts.statusClosed': 'Closed',
// shared vocabulary, reused wherever the meaning is the same
'common.error': 'Something went wrong',
'common.menu': 'Menu',
'common.save': 'Save',
'common.cancel': 'Cancel',
'common.create': 'Create',
'common.add': 'Add',
'common.done': 'Done',
'common.never': 'Never',
'common.always': 'Always',
'common.you': 'You',
'common.revoke': 'Revoke',
'common.copyToClipboard': 'Copy to clipboard',
'common.download': 'Download',
'common.yes': 'Yes',
'common.no': 'No',
'common.notAvailable': 'N/A',
'common.result': 'Result',
'common.liveOutput': 'Live output',
'common.pullToRefresh': 'Pull to refresh',
'common.releaseToRefresh': 'Release to refresh',
'common.refreshing': 'Refreshing...',
'common.justNow': 'just now',
// table columns
'col.name': 'Name',
'col.key': 'Key',
'col.created': 'Created',
'col.lastUsed': 'Last used',
'col.tool': 'Tool',
'col.status': 'Status',
'col.started': 'Started',
'col.finished': 'Finished',
'col.subagentTokens': 'Sub-agent tokens',
'col.pid': 'PID',
'col.command': 'Command',
'col.cwd': 'CWD',
'col.uptime': 'Uptime',
'col.background': 'Background',
'col.reason': 'Reason',
// confirmation dialogs
'confirm.revokeKey': 'Revoke API key "{name}"? This cannot be undone.',
'confirm.revokeTarget': 'Revoke Synapse target "{target}"? This cannot be undone.',
'confirm.mcpResetAdmin': 'Reset the key for "{server}" to the shared default?',
'confirm.mcpReset':
'Remove your key for "{server}"? The server stops being connected for you.',
// the account itself
'profile.languageAuto': 'Auto (from account)',
// A language is always written in its own language, so these three are
// identical in every dictionary and must not be translated.
'profile.langEn': 'English',
'profile.langUk': 'Українська',
'profile.langRu': 'Русский',
// toasts — a title, sometimes a line of text under it
'toast.languageSaved': 'Language saved',
'toast.keyCreateFailed': 'Failed to create key',
'toast.keyRevoked': 'API key revoked',
'toast.keyRevokeFailed': 'Failed to revoke key',
'toast.notificationsDenied': 'Permission denied',
'toast.notificationsAllowApp': 'Allow notifications in the system app settings.',
'toast.notificationsAllowBrowser': 'Allow notifications in the browser site settings.',
'toast.notificationsUnavailable': 'Push unavailable',
'toast.notificationsUnavailableText':
'The server does not accept push subscriptions right now.',
'toast.notificationsFailed': 'Push error',
'toast.mcpKeySaved': 'Key saved for {server}',
'toast.mcpKeySaveFailed': 'Failed to save key',
'toast.mcpKeyReset': 'Key reset for {server}',
'toast.mcpKeyResetFailed': 'Failed to reset key',
'toast.synapseTargetAdded': 'Target added',
'toast.synapseTargetAddFailed': 'Failed to add target',
'toast.synapseTargetRevoked': 'Target revoked',
'toast.synapseTargetRevokeFailed': 'Failed to revoke target',
'toast.reactionsLoadFailed': 'Failed to load reaction settings',
'toast.saveFailed': 'Failed to save',
'toast.instructionsSaved': 'Instructions saved',
'toast.instructionsFailed': 'Failed to save instructions',
'toast.toolsReloaded': { one: 'Reloaded {n} tool', other: 'Reloaded {n} tools' },
'toast.toolsReloadErrors': 'Reload finished with errors — see the panel',
'toast.toolsReloadFailed': 'Failed to reload tools',
// settings — the shell, then one block per tab
'settings.title': 'Settings',
'settings.sectionsLabel': 'Settings sections',
'settings.tabApp': 'App',
'settings.tabAccount': 'Account',
'settings.tabNotifications': 'Notifications',
'settings.tabSynapse': 'Synapse',
'settings.tabMcp': 'MCP',
'settings.languageToolbar': 'Interface language',
'settings.languageDescription':
'Navi follows the language of your gnexus-auth account by default; a choice here overrides it for Navi only. Auto goes back to the account language.',
'settings.languageDescriptionOpen':
'Sign-in is switched off on this Navi, so the language is kept in this browser only.',
// settings — App
'settings.appTitle': 'App',
'settings.appDescription':
'Navi is a web app, but it can live on your device like a native one — either installed into this browser, or as the Android app, which wraps this same interface. They are not exclusive: the Android app is worth having on a phone, the installed web app everywhere else.',
'settings.appInstallTitle': 'Install in this browser',
'settings.appInstallText':
'Installing puts Navi in its own window with no address bar, adds an icon to your dock or home screen, and caches the interface so the app opens instantly and still shows your sessions offline. It also enables notifications for finished replies — including when the tab is closed.',
'settings.appAndroidAlert':
'You are reading this inside the Android app, which is already installed. To update it, download the APK below and install it over the old one.',
'settings.appInstalledAlert':
'Installed — Navi is running in its own window, not in a browser tab.',
'settings.appInstallAction': 'Install',
'settings.appInstallHint': 'Your browser will ask you to confirm.',
'settings.appBrowserSafari': 'Safari:',
'settings.appIosTap': 'tap',
'settings.appIosShare': 'Share, then',
'settings.appIosAddHome': 'Add to Home Screen',
'settings.appIosNote':
'Notifications there need iOS 16.4 or newer and work only in the installed app, not in a Safari tab.',
'settings.appBrowserChrome': 'Chrome or Edge:',
'settings.appChromeClick':
'click the install icon at the right end of the address bar, or open the',
'settings.appChromeMenu': 'menu and choose',
'settings.appChromeInstall': 'Install Navi',
'settings.appBrowserAndroid': 'Android:',
'settings.appAndroidOpen': 'open the',
'settings.appAndroidMenu': 'menu and choose',
'settings.appAndroidInstall': 'Install app',
'settings.appAndroidAlso': '(sometimes “Add to Home screen”)',
'settings.appHttpsBefore':
'Browsers only offer this over HTTPS or on localhost — over a plain',
'settings.appHttpsAfter':
'address the option never appears, and neither do offline mode and notifications.',
'settings.appAndroidTitle': 'Android app',
'settings.appAndroidText':
"The same Navi in a native shell. What a browser tab cannot give you: notifications while the phone is locked — a background service keeps the connection open — plus a native camera and photo picker, and links that open in your normal browser. Sessions, profiles and settings are the server's, so the app and the web client stay in step.",
'settings.appApkMissing': 'The APK is not published on this server — build it with',
'settings.appVersion': 'Version',
'settings.appSize': 'Size',
'settings.appBuilt': 'Built',
'settings.appDownloadApk': 'Download APK',
'settings.appAndroidStep1':
'Open the downloaded file on the phone. Android will ask whether to allow installing apps from this source — allow it.',
'settings.appAndroidStep2': 'On first launch the app asks for your Navi address. Enter',
'settings.appAndroidStep2Tail':
', then log in through the browser when it opens; the app returns on its own.',
'settings.appAndroidStep3':
'A newer APK installs over the old one and keeps your settings. You would only have to uninstall first if the signing key ever changed.',
// settings — API keys
'settings.keysTitle': 'API Keys',
'settings.keysCreate': 'New Key',
'settings.keysDescription':
'API keys allow headless clients (scripts, voice assistants, IoT devices) to authenticate without browser-based OAuth.',
'settings.keysNoAuthWarning':
'Authorization is currently disabled. Any keys created here are tied to the local anonymous user and grant full access to this Navi instance.',
'settings.keysLoading': 'Loading API keys',
'settings.keysEmpty': 'No API keys yet. Create one to get started.',
'settings.keyCreateTitle': 'Create API Key',
'settings.keyNamePlaceholder': 'e.g. Smart Watch, Automation Script',
'settings.keyCreatedTitle': 'API Key Created',
'settings.keyCopyNow': 'Copy this token now — it will',
'settings.keyCopyNowStrong': 'never be shown again',
// settings — notifications
'settings.notificationsTitle': 'Notifications',
'settings.notificationsBridgeText':
'The app keeps its connection open in the background and raises a native notification when a reply finishes while Navi is minimized. Notifications stop if you close the app itself.',
'settings.notificationsWebText':
'Push notifications let Navi ping you when a reply is ready — even when the tab is closed. You get one notification per finished reply, but only when no Navi window is open on that session.',
'settings.notificationsUnsupported':
'This browser does not support web push (needs HTTPS, a service worker and the Push API). Try Chrome or a recent Firefox.',
'settings.notificationsRowTitle': 'Push notifications',
'settings.notificationsOnBackground':
'Enabled — background mode holds the connection open when minimized.',
'settings.notificationsOn': 'Enabled — this device is subscribed.',
'settings.notificationsBlockedApp': 'Blocked in the system app settings.',
'settings.notificationsBlockedBrowser': 'Blocked in browser site settings.',
'settings.notificationsOff': 'Disabled.',
// settings — MCP servers
'settings.mcpTitle': 'MCP servers',
'settings.mcpDescriptionAdmin':
'Everything connected to your profiles. A server that offers a personal key slot runs under your own key — leave yours unset and it keeps using the shared key configured on this Navi.',
'settings.mcpDescription':
'Everything connected to your profiles. A server that offers a personal key slot needs',
'settings.mcpDescriptionStrong': 'your own key',
'settings.mcpDescriptionTail':
'— until you save one it is not connected for you at all. Servers without a slot are shared and always available.',
'settings.mcpLoading': 'Loading MCP servers',
'settings.mcpEmpty': 'No MCP servers are connected to any profile on this Navi.',
'settings.mcpKeySet': 'Personal key set {date} — used instead of the shared key ({location}).',
'settings.mcpKeyAbsentAdmin':
'No personal key — the shared key from the config is used ({location}).',
'settings.mcpKeyAbsent': 'No personal key — this server is not connected for you.',
'settings.mcpNoSlot': 'No personal key slot — runs on the shared config.',
'settings.mcpKeyPlaceholder': '••• saved — enter a new key to replace',
'settings.mcpKeyPlaceholderNew': 'Paste your key',
'settings.mcpReset': 'Reset to default',
// settings — Synapse deliveries
'settings.synapseTargetsTitle': 'Synapse deliveries',
'settings.synapseTargetAdd': 'Add Target',
'settings.synapseTargetsDescription':
"Deliveries from the GNEXUS Synapse notification hub arrive at this Navi's webhook and are verified against a per-user target secret. Create the target in the Synapse admin panel, then register it here to let Navi accept its deliveries.",
'settings.synapseTargetsLoading': 'Loading targets',
'settings.synapseTargetsEmpty':
'No Synapse targets registered. Add one to start receiving deliveries.',
'settings.synapseTargetColRef': 'Token ref',
'settings.synapseTargetAddTitle': 'Add Synapse Target',
'settings.synapseTargetRefPlaceholder': 'e.g. navi-main (as in the Synapse admin panel)',
'settings.synapseTargetSecret': 'Delivery secret',
'settings.synapseTargetSecretPlaceholder': 's2s secret of the Synapse target',
'settings.synapseTargetHintBefore':
'In the Synapse admin panel create a target pointing at',
'settings.synapseTargetHintAfter':
'of this Navi and paste its secret here. Navi uses it to verify that deliveries really came from Synapse.',
// settings — Synapse reactions
'settings.reactionsTitle': 'Synapse reactions',
'settings.reactionsDescription':
'When a GNEXUS Synapse event is delivered, Navi can react to it on its own: a dispatcher picks a profile by your reaction instructions, the work runs in a hidden service session, and you can browse that session later via the sidebar "Service sessions" toggle.',
'settings.reactionsNotConfigured':
'Synapse integration is not configured on this navi: options that send events to Synapse are disabled. App-only delivery keeps working.',
'settings.reactionsLoading': 'Loading reaction settings',
'settings.reactionsEnable': 'Enable reactions',
'settings.reactionsOn': 'Delivered events start a background reaction run.',
'settings.reactionsOff': 'Events are accepted and logged, but Navi does nothing.',
'settings.reactionsNotify': 'Notify me about finished reactions',
'settings.reactionsOnlyFailures': 'Only failures',
'settings.reactionsPushAlways': 'Push on every finished run.',
'settings.reactionsPushFailures': 'Push only when a run ended with errors.',
'settings.reactionsPushNever': 'No completion push.',
'settings.reactionsTarget': 'Where notifications go',
'settings.reactionsTargetNote':
"Applies to Navi's notify tool and to reaction-completion pushes.",
'settings.reactionsTargetApp': 'App only',
'settings.reactionsTargetAppSynapse': 'App + Synapse',
'settings.reactionsTargetSynapse': 'Synapse only',
'settings.reactionsInstructions': 'Reaction instructions',
'settings.reactionsInstructionsNote':
'Guidance the dispatcher uses to pick a profile and to shape the task. Both you and Navi can edit it; every change is recorded in the history below.',
'settings.reactionsInstructionsPlaceholder':
'e.g. "Todo events from gntodo go to the developer profile; junk mail goes nowhere."',
'settings.reactionsInstructionsSave': 'Save instructions',
'settings.reactionsHistory': 'Edit history',
// settings — admin tools (admins only)
'settings.adminToolsTitle': 'Tools',
'settings.adminToolsReloading': 'Reloading…',
'settings.adminToolsReload': 'Reload tools',
'settings.adminToolsDescriptionBefore': 'Re-reads the tools in',
'settings.adminToolsDescriptionAfter':
', the context providers, and reconnects every MCP server — no restart, no downtime. New tools are callable from the next message of every session. Admin only: it swaps the toolset all profiles resolve against.',
'settings.adminToolsLoaded': { one: '{n} tool loaded', other: '{n} tools loaded' },
'settings.adminToolsRegistry': '({n} in the registry)',
'settings.adminToolsMissing':
'names {names} — no such tool exists, so it is dropped from every profile.',
'settings.adminToolsMcpFailed': 'MCP reload failed: {error}',
'settings.adminToolsMcpTools': { one: '{n} MCP tool', other: '{n} MCP tools' },
'settings.adminToolsProviders': { one: '{n} context provider', other: '{n} context providers' },
}