diff --git a/ui/src/app/app-host.ts b/ui/src/app/app-host.ts index 01008654621e..d5a95bb889d4 100644 --- a/ui/src/app/app-host.ts +++ b/ui/src/app/app-host.ts @@ -940,7 +940,7 @@ class OpenClawShell extends OpenClawLightDomElement { ", + itemCount: "[{count} item]", + itemCountPlural: "[{count} items]", + form: "Form", + raw: "Raw", + formUnsafeTitle: "Form view can't safely edit some fields", + rawTitle: "Edit raw JSON/JSON5 config", + rawUnavailableTitle: "Raw mode unavailable for this snapshot", + unsavedChange: "{count} unsaved change", + unsavedChanges: "{count} unsaved changes", + noChanges: "No changes", + rawDisabled: "Raw mode disabled (snapshot cannot safely round-trip raw text).", + open: "Open", + clear: "Clear", + apply: "Apply", + applying: "Applying…", + update: "Update", + updating: "Updating…", + searchPlaceholder: "Search settings...", + search: "Search settings", + clearSearch: "Clear search", + invalidConfig: "Your configuration is invalid. Some settings may not work as expected.", + dismissWarning: "Don't remind again", + viewPendingChange: "View {count} pending change", + viewPendingChanges: "View {count} pending changes", + viewPendingChangesRaw: "View pending changes", + rawDiffUnavailable: "Changes detected (JSON diff not available)", + hideEnvValues: "Hide env values", + revealEnvValues: "Reveal env values", + peek: "Peek", + loadingSchema: "Loading schema…", + formUnsafe: + "Your config contains fields the form editor can't safely represent. Use Raw mode to edit those entries.", + rawConfig: "Raw config (JSON/JSON5)", + secretCount: "{count} secret", + secretCountPlural: "{count} secrets", + redacted: "redacted", + visible: "visible", + revealSensitive: "Reveal sensitive values", + hideSensitive: "Hide sensitive values", + toggleRawRedaction: "Toggle raw config redaction", + sensitiveHidden: + "{count} sensitive value hidden. Use the reveal button above to edit the raw config.", + sensitiveHiddenPlural: + "{count} sensitive values hidden. Use the reveal button above to edit the raw config.", }, execApproval: { expiresIn: "expires in {time}", @@ -560,7 +1286,136 @@ export const en: TranslationMap = { connected: "Connected", channelSource: "Channel: {id}", channel: "Channel", - builtIn: "Built-in", + builtIn: "Built-In", + plugin: "Plugin: {id}", + optional: "Optional", + liveNow: "Live Now", + disabledByOverride: "Disabled by agent override.", + enabledByProfile: "Enabled by the current profile.", + enabledByOverride: "Enabled by agent override.", + notIncluded: "Not included in the current profile.", + overrideOff: "Override Off", + enabled: "Enabled", + overrideOn: "Override On", + profileOff: "Profile Off", + notLive: "Not Live", + otherAgent: "Other Agent", + title: "Tool Access", + subtitle: "Profile + per-tool overrides for this agent.", + enabledSummary: "{enabled}/{total} enabled.", + enableAll: "Enable All", + disableAll: "Disable All", + loadConfig: "Load the gateway config to adjust tool profiles.", + explicitAllowlist: + "This agent is using an explicit allowlist in config. Tool overrides are managed in the Config tab.", + globalAllowlist: + "Global tools.allow is set. Agent overrides cannot enable tools that are globally blocked.", + loadingCatalog: "Loading runtime tool catalog…", + catalogFallback: "Could not load runtime tool catalog. Showing built-in fallback list instead.", + availableNow: "Available Right Now", + availableNowSubtitle: "What this agent can use in the current chat session.", + noSession: "no session", + switchAgent: "Switch chat to this agent to view its live runtime tools.", + loadingAvailable: "Loading available tools…", + availableError: "Could not load available tools for this session.", + noAvailable: "No tools are available for this session right now.", + moreLiveTitle: "{count} more live tools are available in the groups below.", + moreLive: "+{count} more live tools", + quickPresets: "Quick Presets", + inherit: "Inherit", + profile: "Profile", + source: "Source", + live: "Live", + status: "Status", + profileSourceAgent: "agent override", + profileSourceGlobal: "global default", + profileSourceDefault: "default", + statusSaving: "saving…", + statusUnsaved: "unsaved", + statusSaved: "saved", + toolPreview: "Tool preview", + more: "+{count} more", + toolsOne: "{count} Tool", + tools: "{count} Tools", + enabledToolsOne: "{count} Enabled Tool", + enabledTools: "{count} Enabled Tools", + liveToolsOne: "{count} Live Tool", + liveTools: "{count} Live Tools", + access: "Access", + session: "Current Session", + disableNamed: "Disable {name}", + enableNamed: "Enable {name}", + defaultPresets: "Default Presets", + availableVia: "Available now via {source}.", + unavailableSession: "Not available in this chat session right now.", + inspectAgent: "Switch chat to this agent to inspect live availability.", + linkTool: "Link to This Tool", + }, + skillGroups: { + workspace: "Workspace Skills", + builtIn: "Built-in Skills", + installed: "Installed Skills", + extra: "Extra Skills", + other: "Other Skills", + }, + skillsPage: { + title: "Skills", + subtitle: "Installed skills and their status.", + tabs: { + all: "All", + ready: "Ready", + needsSetup: "Needs Setup", + disabled: "Disabled", + }, + defaultAgent: "{name} (default)", + filterPlaceholder: "Filter installed skills", + shown: "{count} shown", + clawHub: "ClawHub", + clawHubSubtitle: "Search and install skills from the registry", + searchClawHub: "Search ClawHub skills…", + searching: "Searching…", + acknowledgeRisk: "Acknowledge risk and install", + disconnected: "Not connected to gateway.", + empty: "No skills found.", + noClawHubResults: "No skills found on ClawHub.", + install: "Install", + installing: "Installing…", + close: "Close", + by: "By", + latest: "Latest: v{version}", + platforms: "Platforms: {platforms}", + installNamed: "Install {name}", + notFound: "Skill not found.", + invalidLink: "ClawHub link invalid", + overview: "Overview", + skillCard: "Skill Card", + missingRequirements: "Missing requirements", + reason: "Reason: {reasons}", + disabled: "Disabled", + enabled: "Enabled", + apiKey: "API key", + getKey: "Get your key:", + saveKey: "Save key", + source: "Source:", + refreshing: "Refreshing…", + fullSecurityReport: "Full security report", + loadingSkillCard: "Loading Skill Card…", + skillCardNotLoaded: "Skill Card not loaded.", + verdict: { + unavailable: "Unavailable", + clean: "Clean", + pending: "Pending", + blocked: "Blocked", + review: "Review", + }, + }, + skillStatus: { + bundled: "bundled", + eligible: "eligible", + blocked: "blocked", + disabled: "disabled", + blockedAllowlist: "blocked by allowlist", + blockedAgentFilter: "blocked by agent filter", }, nav: { chat: "Chat", @@ -574,6 +1429,7 @@ export const en: TranslationMap = { settingsSearchNoResults: "No matching settings.", settingsSearchClear: "Clear settings search", exitSettings: "Back to app", + close: "Close navigation", expand: "Expand sidebar", collapse: "Collapse sidebar", resize: "Resize sidebar", @@ -711,6 +1567,21 @@ export const en: TranslationMap = { }, mcpPage: { manageServersLink: "Manage servers on the Plugins page.", + servers: "Servers", + oauth: "OAuth", + filtered: "Filtered", + configuredServers: "Configured servers", + noServers: "No MCP servers configured.", + operatorCommands: "MCP operator commands", + operatorCommandsHint: "Status, diagnostics, auth, probing, and runtime reload.", + runtimeHint: + "Runtime changes apply after save and publish; active agents rebuild MCP runtimes on next use.", + toolFilter: "tool filter", + parallel: "parallel", + missingTransport: "missing transport", + tlsVerifyOff: "TLS verify off", + mtls: "mTLS", + publishing: "Publishing...", }, pluginsPage: { searchLabel: "Search plugins", @@ -736,6 +1607,8 @@ export const en: TranslationMap = { connectorGroupDev: "Coding & infrastructure", connectorGroupHome: "Home & media", connectorGroupLife: "Everyday life", + mcp: "MCP", + oauth: "OAuth", connectorMcpNote: "One-click MCP server", connectorClawHubNote: "Community plugins on ClawHub", connectorAdd: "Add", @@ -745,6 +1618,36 @@ export const en: TranslationMap = { connectorAddedEndpoint: "Added {name}. Update the endpoint and credentials in MCP settings before use.", connectorAddedReady: "Added {name}. New agent sessions can use it right away.", + connectorDescriptions: { + notion: "Search, create, and update pages and databases in your Notion workspace.", + linear: "Triage issues, update cycles, and file bugs straight from chat.", + todoist: "Read, add, and complete tasks and projects in Todoist.", + airtable: "Query and update records, tables, and bases in Airtable.", + jira: "Create, search, and triage Jira tickets from chat.", + canva: "Create and edit Canva designs, manage assets, and export results.", + stripe: "Check payments, customers, invoices, and subscriptions in your Stripe account.", + googleCalendar: "Read, create, and get briefed on events — your agent owns your schedule.", + email: "Mailbox triage, summaries, and drafts with send-on-approval.", + pdf: "Extract, merge, convert, and OCR PDF documents.", + transcription: "Turn audio and video into clean, structured transcripts.", + github: "PR review queues, issue triage, and repo Q&A through the official GitHub MCP.", + sentry: "Crash alerts explained and triaged the moment they fire.", + context7: "Version-specific library docs and code examples while coding. No signup needed.", + deepwiki: "Ask questions about any public GitHub repo. Free, no account needed.", + huggingFace: "Search models, datasets, and papers; run Spaces as tools.", + grafana: "Grafana know-how and community connectors for dashboards and alerts.", + kubernetes: "Cluster operations and troubleshooting from chat.", + homeAssistant: "Control lights, climate, and automations across your whole home.", + spotify: "Search, queue, and soundtrack your day with mood-based playlists.", + sonos: "Whole-home audio: play, group rooms, and queue by chat.", + reddit: "Browse, search, and summarize subreddits and threads.", + markets: "Live stocks and crypto with price alerts and daily digests.", + travel: "Flight and hotel search with fare watching and trip memory.", + news: "A personalized daily briefing: news, weather, and tasks in one message.", + maps: "Places, routing, and travel-time answers.", + translation: "Translate and localize text and documents.", + notes: "Capture notes to Markdown, Obsidian, Notion, or Bear.", + }, noInstalledTitle: "No optional plugins installed", noInstalledBody: "Discover a featured plugin or search ClawHub to extend OpenClaw.", noInstalledMatchTitle: "No installed plugins match", @@ -911,11 +1814,124 @@ export const en: TranslationMap = { }, }, skillWorkshop: { + title: "Skill Workshop", header: { useCurrentChat: "Use current chat", useCurrentChatAria: "Use current chat for revision requests", useCurrentChatTooltip: "Send revision requests to the current chat session instead of the proposal's workshop session.", + view: "Workshop view", + board: "Board", + today: "Today", + }, + status: { + all: "All", + pending: "Pending", + applied: "Applied", + rejected: "Rejected", + quarantined: "Quarantined", + stale: "Stale", + }, + recency: { + today: "Today", + yesterday: "Yesterday", + earlier: "Earlier this week", + }, + previewContext: "in {slug}", + actions: { + close: "Close", + cancel: "Cancel", + previous: "Previous", + next: "Next", + apply: "Apply", + applying: "Applying…", + revise: "Revise", + tweak: "Tweak", + opening: "Opening…", + reject: "Reject", + rejecting: "Rejecting…", + sending: "Sending…", + }, + revision: { + title: "{verb} proposal", + description: + "Tell the agent what should change. The proposal stays pending and the workshop will create a revised version.", + placeholder: + "Example: Make this use Gmail labels instead of unread search, and add a safer dry-run step.", + preparing: "Preparing revision handoff", + send: "Send revision", + }, + queue: { + resize: "Resize proposal list", + search: "Search proposals…", + loadError: "Could not load proposals.", + loading: "Loading proposals…", + noStatus: "No {status} proposals.", + noMatch: "No proposals match the current filter.", + }, + detail: { + edited: "Edited {time}", + created: "Created {time}", + supportFiles: "{count} support files", + noSupportFiles: "0 support files", + loading: "Loading proposal…", + supportFilesTitle: "Support files", + clickToPreview: "· click to preview", + }, + empty: { + searchTitle: "No matching proposals", + searchBody: "Clear the search or try a different keyword.", + pendingTitle: "No pending proposals", + pendingBody: "New drafts will appear here when they need review.", + appliedTitle: "Nothing applied yet", + appliedBody: "Use a pending proposal and it will appear here as a live skill.", + rejectedTitle: "No rejected proposals", + rejectedBody: "Skipped proposals will stay here for a clean review history.", + quarantinedTitle: "Nothing quarantined", + quarantinedBody: "Scanner-blocked or safety-held proposals will appear here.", + staleTitle: "No stale proposals", + staleBody: "Proposals that can no longer apply cleanly will appear here.", + allTitle: "No proposals here", + allBody: "Skill Workshop proposals will appear here when your agent drafts them.", + defaultAgent: "Your agent", + noProposalsAria: "No Skill Workshop proposals", + noProposalsTitle: "No proposals yet", + noProposalsBody: "{agent} hasn't drafted any skill proposals.", + noProposalsFooter: "New proposals will appear here for review.", + }, + today: { + emptyTitle: "Nothing waiting today", + emptyBody: "Your agent hasn't drafted anything new. Switch to Board to browse history.", + new: "NEW", + waiting: "WAITING", + reviewed: "REVIEWED", + agent: "agent", + proposalsWaiting: "{count} proposals waiting", + browseApplied: "Browse what's already applied.", + progress: "{current} of {total}", + draftedBy: "Drafted by", + supportFile: "{count} support file", + supportFiles: "{count} support files", + comeWithIt: "come with it.", + useIt: "Use it", + addToSkills: "Add to your skills", + tweakIt: "Tweak it", + askAgent: "Ask the agent to change something", + skipping: "Skipping…", + skip: "Skip", + notForMe: "Not for me", + upNext: "Up next · {count} more waiting", + seeAll: "See all proposals →", + collection: "Your collection · {count} in use", + manage: "Manage →", + workflowHeading: "How the agent will use it", + applicabilityHeading: "When the agent should use it", + }, + relative: { + secondsAgo: "{count}s ago", + minutesAgo: "{count} minutes ago", + hoursAgo: "{count}h ago", + daysAgo: "{count}d ago", }, }, activity: { @@ -1252,6 +2268,18 @@ export const en: TranslationMap = { pr_review: "PR review", plugin: "Plugin", }, + templateDraft: { + bugfixTitle: "Fix: ", + bugfixNotes: "Symptom:\nCause:\nAcceptance:\nProof:", + docsTitle: "Docs: ", + docsNotes: "Page:\nChange:\nSource proof:", + releaseTitle: "Release: ", + releaseNotes: "Scope:\nVerification:\nCloseout:", + prReviewTitle: "Review PR ", + prReviewNotes: "Surface:\nRisks:\nProof:", + pluginTitle: "Plugin: ", + pluginNotes: "Boundary:\nConfig/docs:\nTests:", + }, badgeAttempts: "{count} attempts", badgeFailures: "{count} failed", badgeComments: "{count} comments", @@ -1394,6 +2422,7 @@ export const en: TranslationMap = { descriptions: { shellCommand: "Run shell", debugMode: "Toggle debug", + verboseMode: "Toggle verbose mode.", }, footer: { navigate: "navigate", @@ -1495,6 +2524,52 @@ export const en: TranslationMap = { reload: "Reload", reloading: "Reloading…", }, + wiki: { + previewFallbackTitle: "Wiki page", + close: "Close", + loadingPage: "Loading wiki page…", + dreamsTab: "Dreams", + insightsTab: "Imported Insights", + palaceTab: "Memory Palace", + dreamsExplainer: + "This is the raw dream diary the system writes while replaying and consolidating memory; use it to inspect what the memory system is noticing, and where it still looks noisy or thin.", + insightsExplainer: + "These are imported insights clustered from external history; use them to review what imports surfaced before any of it graduates into durable memory.", + palaceExplainer: + "This is the compiled memory wiki surface the system can search and reason over; use it to inspect actual memory pages, claims, open questions, and contradictions rather than raw imported source chats.", + copyArchivePath: "Copy archive path", + loadingInsights: "Loading imported insights…", + noInsights: "No imported insights yet", + noInsightsHint: + "Run a ChatGPT import with apply to surface clustered imported insights here.", + candidateSignals: "Potentially useful signals", + corrections: "Corrections or revisions", + importDetails: "Import details", + startedWith: "Started with:", + endedOn: "Ended on:", + messages: "Messages:", + riskReasons: "Risk reasons:", + labels: "Labels:", + openSourcePage: "Open source page", + loadingPalace: "Loading memory palace…", + emptyPalace: "Memory palace is not populated yet", + emptyPalaceHint: + "Right now the wiki mostly has raw source imports and operational reports. This tab becomes useful once syntheses, entities, or concepts start getting written.", + claims: "Claims", + openQuestions: "Open questions", + contradictions: "Contradictions", + pageDetails: "Page details", + wikiPage: "Wiki page:", + id: "Id:", + openWikiPage: "Open wiki page", + unavailable: "Memory Wiki is not enabled", + unavailablePluginPrefix: "Imported Insights and Memory Palace are provided by the bundled", + unavailablePluginSuffix: "plugin.", + enablePrefix: "Enable", + enableSuffix: ", then reload this tab.", + openConfig: "Open Config", + howToEnable: "How to enable", + }, phrases: { consolidatingMemories: "consolidating memories…", tidyingKnowledgeGraph: "tidying the knowledge graph…", @@ -1602,6 +2677,9 @@ export const en: TranslationMap = { clear: "Clear", clearAll: "Clear All", remove: "Remove filter", + removeDays: "Remove days filter", + removeHours: "Remove hours filter", + removeSession: "Remove session filter", all: "All", days: "Days", hours: "Hours", @@ -1780,6 +2858,8 @@ export const en: TranslationMap = { toolResult: "Tool result", hasTools: "Has tools", searchConversation: "Search conversation", + filterByRole: "Filter by role", + filterByTool: "Filter by tool", you: "You", noMessagesMatch: "No messages match the filters.", }, @@ -1966,6 +3046,39 @@ export const en: TranslationMap = { updating: "Updating…", dismissUpdateBanner: "Dismiss update banner", switchedSession: "Switched to {session}", + actions: { + dismissError: "Dismiss error", + exitFocusMode: "Exit focus mode", + scrollToLatest: "Scroll to latest", + }, + compaction: { + label: "Compacted history", + description: + "The compacted transcript is preserved as a checkpoint. Open session checkpoints to branch or restore from that compacted view.", + openCheckpoints: "Open checkpoints", + }, + commands: { + arguments: "Command arguments", + menu: "Slash commands", + instant: "instant", + optionCount: "{count} options", + showMoreOne: "Show 1 more command", + showMoreMany: "Show {count} more commands", + navigate: "navigate", + fill: "fill", + run: "run", + select: "select", + close: "close", + clearDescription: "Clear chat history", + redirectDescription: "Abort and restart with a new message", + steerDescription: "Inject a message into the active run", + categories: { + session: "Session", + model: "Model", + agents: "Agents", + tools: "Tools", + }, + }, splitView: { open: "Open split view", splitRight: "Split right", @@ -2015,6 +3128,62 @@ export const en: TranslationMap = { retry: "Retry", retrySend: "Retry send", retryQueuedMessage: "Retry queued message", + steer: "Steer", + steered: "Steered", + steerQueuedMessage: "Steer queued message", + removeQueuedMessage: "Remove queued message", + }, + goals: { + edit: "Edit goal", + pause: "Pause goal", + resume: "Resume goal", + clear: "Clear goal", + }, + messages: { + activity: "Activity", + deleteMessage: "Delete message", + openInCanvas: "Open in canvas", + unknownDate: "Unknown date", + voiceNote: "Voice note", + }, + modelControls: { + default: "Default", + reasoning: "Reasoning", + speed: "Speed", + }, + sideChat: { + title: "Side chat", + notSaved: "Not saved to chat history", + thinking: "Thinking…", + clear: "Clear side chat", + close: "Close side chat", + followUp: "Follow up…", + followUpLabel: "Follow up in side chat", + sendFollowUp: "Send follow-up", + }, + detailPanel: { + close: "Close sidebar", + copyPath: "Copy path", + discard: "Discard", + editFile: "Edit file", + searchInFile: "Search in file", + showInFiles: "Show in Files", + previousMatch: "Previous match", + nextMatch: "Next match", + overwrite: "Overwrite", + viewRawText: "View Raw Text", + renderedMarkdown: "Rendered Markdown", + renderedMarkdownHint: "Sanitized rich-text preview for quick reading.", + noPreviewableMarkdown: "No previewable markdown content.", + noContent: "No content available", + }, + thread: { + search: "Search messages", + searchPlaceholder: "Search messages...", + closeSearch: "Close search", + unpin: "Unpin", + loading: "Loading chat", + noMatches: "No matching messages", }, pairingQrExpired: { title: "Pairing QR expired", @@ -2025,6 +3194,16 @@ export const en: TranslationMap = { placeholder: "Message {name}", placeholderWithAttachments: "Add a message or paste more images...", placeholderDisconnected: "Connect to the gateway to start chatting...", + preparingModel: "Preparing model...", + responding: "{name} is responding...", + sendingMessage: "Sending message...", + working: "{name} is working...", + runDone: "Done", + runInterrupted: "Interrupted", + runStatus: "Run status: {status}", + cancelReply: "Cancel reply", + compactRecommendedContext: "Compact recommended session context", + removeAttachment: "Remove attachment", addAttachment: "Add attachment", attachPhoto: "Photo", attachFile: "Attach file", @@ -2096,11 +3275,14 @@ export const en: TranslationMap = { }, toolCards: { tool: "Tool", + canvas: "Canvas", summary: "Summary", toolInput: "Tool input", toolOutput: "Tool output", toolError: "Tool error", rawDetails: "Raw details", + openFile: "Open file", + openDetails: "Open tool details in side panel", fileChanges: "File changes", attemptedChanges: "Attempted changes", failed: "failed", @@ -2482,18 +3664,42 @@ export const en: TranslationMap = { deleteAfterRunHelp: "Best for one-shot reminders that should auto-clean up.", clearAgentOverride: "Clear agent override", clearAgentHelp: "Force this job to use the gateway default assistant.", + sessionKey: "Session key", + sessionKeyHelp: "Optional routing key for job delivery and wake routing.", exactTiming: "Exact timing (no stagger)", exactTimingHelp: "Run on exact cron boundaries with no spread.", staggerWindow: "Stagger window", staggerUnit: "Stagger unit", staggerPlaceholder: "30", seconds: "Seconds", + accountId: "Account ID", + accountIdHelp: "Optional channel account ID for multi-account setups.", + lightContext: "Light context", + lightContextHelp: "Use lightweight bootstrap context for this agent job.", model: "Model", modelPlaceholder: "openai/gpt-5.2", modelHelp: "Start typing to pick a known model, or enter a custom one.", thinking: "Thinking", thinkingPlaceholder: "low", thinkingHelp: "Use a suggested level or enter a provider-specific value.", + failureAlerts: "Failure alerts", + failureAlertInherit: "Inherit global setting", + failureAlertDisabled: "Disable for this job", + failureAlertCustom: "Custom per-job settings", + failureAlertsHelp: "Control when this job sends repeated-failure alerts.", + failureAlertAfter: "Alert after", + failureAlertAfterHelp: "Consecutive errors before alerting.", + failureAlertCooldown: "Cooldown (seconds)", + failureAlertCooldownHelp: "Minimum seconds between alerts.", + failureAlertChannel: "Alert channel", + failureAlertTo: "Alert to", + failureAlertToPlaceholder: "+1555... or chat id", + failureAlertToHelp: "Optional recipient override for failure alerts.", + failureAlertMode: "Alert mode", + failureAlertAnnounce: "Announce (via channel)", + failureAlertWebhook: "Webhook (HTTP POST)", + failureAlertAccountId: "Alert account ID", + failureAlertAccountPlaceholder: "Account ID for multi-account setups", bestEffortDelivery: "Best effort delivery", bestEffortHelp: "Do not fail the job if delivery itself fails.", cantAddYet: "Can't add job yet",