export default { aiChat: { // ── Multi-Agent parallel execution ── conflictsPending: '{n} conflicts to resolve', acceptA: 'Accept A', acceptB: 'Accept B', mergeBoth: 'Merge Both', manualResolve: 'Manual', // ── Conversation sidebar ── sidebarTitle: 'Chats', newConversation: 'New chat', doubleClickToRename: 'Double-click to rename', generating: 'Generating…', archive: 'Archive', unarchive: 'Unarchive', pinConversation: 'Pin', unpinConversation: 'Unpin', // UX走查 P3-1/P2-6: rename entry in the "..." menu (search-mode parity + keyboard reach) renameConversation: 'Rename', moreActions: 'More actions', archived: 'Archived', archivedCount: 'Archived ({n})', recoverableCount: 'Recoverable ({n})', recoverableHint: 'Task parked safely; click to resume', // ── Unattended engine badge (TopBar; shown while on, red badge resets the breaker) ── unattendedOn: 'Unattended', unattendedExecuting: 'working', unattendedTripped: 'Unattended halted', unattendedBadgeHint: 'Unattended mode is on. Click to open settings', unattendedResetHint: 'Auto-halted after repeated start failures. Click to reset and resume', recoverableDone: 'Task resumed, running in background', recoverableFail: 'Recover failed: {msg}', emptyConversation: 'No conversations', // UX-06 §3.1: conversation search (live title filter, Ctrl+K to focus) searchPlaceholder: 'Search chats…', searchEmpty: 'No matching chats', searchShortcutHint: 'Ctrl+K', // ── Time grouping (sidebar) ── today: 'Today', yesterday: 'Yesterday', earlier: 'Earlier', groupEmpty: 'None', // ── Header buttons ── conversationList: 'Chat list', maximize: 'Maximize', pendingApprovalCount: '{n} pending', pendingApprovalHint: 'Click to jump to the first pending approval', // UX walkthrough B1: approval card arrived while user scrolled up; no forced scroll, hint only (5s dedup in ToolCardList) newApprovalPending: 'New approval pending', restoreSidebar: 'Restore sidebar', sidebarResizeHint: 'Drag to resize sidebar', detachWindow: 'Detach window', reattachToMain: 'Reattach to main panel', closePanel: 'Close panel', dockRight: 'Dock to main window right', undock: 'Undock', pinOnTop: 'Pin on top', unpin: 'Unpin', closeWindow: 'Close window', // I9(2026-10-05) text/code file attachment pickFileTitle: 'Select text/code files', textFileFilter: 'Text/code files', fileTooLargeTruncated: 'File too large, truncated on insert', fileReadFailed: 'Failed to read file, skipped', shortcutsTitle: 'Keyboard shortcuts', scNewConv: 'New conversation', scFocusInput: 'Focus message input', scRegenerate: 'Regenerate last reply', scClearChat: 'Clear current conversation', scSearch: 'Focus conversation search', scToggleSidebar: 'Toggle sidebar', scCloseOverlay: 'Close dialog / panel', // ── Approval overlay (global top-right) ── approvalWaitingTitle: 'Approval required', approvalWaitingDesc: 'Click to review and handle', // ── System-level approval popup (standalone window, visible when app unfocused) ── popupTitle: 'Approval pending', popupTagPath: 'Path auth', popupTagRisk: 'Risk action', popupOpenPanel: 'Open approval panel', // 空态文案:正常空态会被 maybeAutoClose 即时关窗,此 hint 仅 close 失败时兜底 popupEmptyHint: 'Closing…', // ── Provider status ── clickToSwitchProvider: 'Click to switch provider', // UX walkthrough B5: topbar switching shares the same IPC as Settings "set as default" (ai_set_provider rewrites is_default), label it honestly providerSwitchSetsDefault: 'Click to switch provider (also sets it as the global default)', providerNotConfigured: 'No AI provider configured. Please add one in settings.', notConfigured: 'Not configured', // ── F-01 阶段6: model picker (auto/specify toggle + dropdown) ── autoMode: 'Auto', specifyMode: 'Specify', autoModeHint: 'Auto mode: router picks the best model per scenario', specifyModeHint: 'Specify mode: use the selected model, overriding the router (main chat only)', selectModel: 'Select model', noModels: 'No models available. Please fetch in settings.', // ── Empty states example prompt cards + no-provider guidance) ── emptyNoProvider: 'No AI provider configured', emptyNoProviderHint: 'Please add a provider in settings to start chatting', emptyTitle: 'Chat with AI assistant', emptyHint: 'Try "create a project" or "list all tasks"', // Example prompt cards: click to fill and send (4 prompts, DevFlow scenarios) examplePrompt1: 'Analyze this project’s dependencies', examplePrompt2: 'Help me write a workflow node', examplePrompt3: 'List all current tasks', examplePrompt4: 'Generate a project idea', goToSettings: 'Open settings', goToSettingsHint: 'The detached window cannot open settings directly. Configure AI providers on the main window’s Settings page.', goToTaskHint: 'The detached window cannot open tasks directly. View task details in the main window.', // ── Provider switch feedback ── providerSwitched: 'Switched to {model}', providerSwitchHint: 'Current model: {model}', // ── Back to bottom ── backToBottom: 'Back to bottom', // ── Pending queue ── queueTitle: 'Queued {n}/10', clearQueue: 'Clear', // queue item edit + send now queueEdit: 'Edit', queueSave: 'Save', queueCancel: 'Cancel', queueSendNow: 'Send now', // 3c UX batch addition (I4 queue backfill: pull a queued item back into the input box) queueBackfill: 'Backfill', // ── Skill ── clearSkill: 'Clear skill', skillBadgeTip: 'Injected full skill playbook: {name}', placeholderWithSkill: 'Skill selected. Type arguments and press Enter', placeholderDefault: "Type a message... (/ for skills, {'@'} to mention)", skillNoMatch: 'No matching skill', skillNotLoaded: 'No local skills loaded', // ── @ entity mention (@ opens popover, select inserts [Type:Name] token) ── mentionHint: "{'@'} to mention project/task", mentionGroupProject: 'Projects', mentionGroupTask: 'Tasks', mentionGroupIdea: 'Ideas', mentionNoMatch: 'No matching entity', mentionEmpty: 'No project/task to mention', // ── Send ── stopGenerating: 'Stop generating', // L2 状态机停止按钮三态(ConvState 派生) stopping: 'Stopping', stopFailedRetry: 'Stop failed, click to retry', // ── Input hint ── inputHint: 'Enter to send · Shift+Enter for newline', // ── F-260614-05 Phase 2b: image input (paste / drag-drop) ── pickImage: 'Pick image', pickImageTitle: 'Pick image (or paste / drag-drop)', imageFilter: 'Image files', removeImage: 'Remove image', imagePreviewAlt: 'Pending image', imageTooLarge: 'Image too large (max 10MB), skipped', imageLimit: 'Up to {n} images, extras ignored', imageReadFailed: 'Failed to read image', imageIgnoredWarn: 'Current model does not support images; they will be ignored on send', imageOnlyBlocked: 'Current model does not support images; switch to a vision model or add some text', // ── Confirm dialog ── confirmDeleteConversation: 'Delete chat "{title}"? This cannot be undone.', // stronger warning when deleting the currently active conversation confirmDeleteActiveConversation: '"{title}" is the chat you are currently viewing. Deleting it will clear the current view and cannot be undone. Continue?', clearChat: 'Clear', confirmClearChat: 'Are you sure you want to clear all messages in this chat? This cannot be undone.', toastSendFail: 'Send failed: {msg}', // ── Message copy ── copyMsg: 'Copy message', copied: 'Copied', copyFailed: 'Copy failed', // Copy bubble as image (html2canvas → clipboard; falls back to download) copyAsImage: 'Copy as image', copiedAsImage: 'Copied as image', copyAsImageFailed: 'Failed to copy as image', // ── Message actions bar ── // regenerateUnavailable: Ctrl+R / retry paths still call store.regenerate(); precheck toast key // (I6 revert removed the UI button only — key still referenced by useAiSend.ts, review 2026-10-05 ②) regenerateUnavailable: 'No reply to regenerate', regenerateFailed: 'Regenerate failed: {msg}', // fetch_url "Install obscura via AI" button triggers sendMessage; failure toast (mirrors editMessageFailed) sendFailed: 'Send failed: {msg}', // ── edit last user message and regenerate ── editMessage: 'Edit', editMessageFailed: 'Edit failed: {msg}', editNotLastUser: 'Only the last user message can be edited', // UX walkthrough B3: editMessage IPC takes no parts; editing would silently drop images, block at entry editImageBlocked: 'This message contains images and cannot be edited (regenerating would lose them)', placeholderEditing: 'Edit message then Enter to regenerate (Esc to cancel)', // ── Error bubble actions (UX-03 / ) ── retry: 'Retry', goToSettingsAction: 'Open settings', // ── max iterations reached pause action card ── maxRoundsReached: 'Max rounds reached. Continue?', maxRoundsHint: 'Continue runs another full round; stop ends with current results', continueLoop: 'Continue', stopLoop: 'Stop', continueLoopFailed: 'Continue failed: {msg}', stopLoopFailed: 'Stop failed: {msg}', // ── L1 help protocol (aichat experience & agent capability redesign §2.3, 2026-06-21): circuit-breaker help card ── helpRequiredAck: 'Choice noted. Please rephrase your request to try another approach / continue', // ── F-260619-03 Phase B: path authorization dialog (LLM accessing dir outside whitelist) ── dirAuthRequired: 'Path authorization required', dirAuthHint: '{tool} wants to access: {path}', dirAuthOnce: 'This time', dirAuthSession: 'This session', dirAuthAlways: 'Always', dirAuthDeny: 'Deny', dirAuthFailed: 'Authorization failed: {msg}', // M5:path deny second confirmation (deny is irreversible — tool returns Err, loop continues without retry; asymmetry with approve, prevents mis-clicks) dirAuthDenyConfirm: 'Deny authorization? The tool will fail immediately and will not be retried this round.', // Persistent bypass banner shown at the top of the chat area while "trust all directories" is on pathAuthBypassBanner: 'Authorization fully bypassed (including sensitive directories): AI can access any file directly', // ── Input Augmentation layer: mention/skill injection feedback ── // search_files blind search denied by whitelist fallback (no auth dialog; prompt user to use @mention or absolute path) searchFilesBlocked: "search_files only works inside authorized dirs. Use {'@'}[project] to reference or provide an absolute path.", // /skill hot reload (ai_reload_skills IPC) success toast skillReloaded: 'Skills reloaded', // @mention entity resolve failed (id points to a project/task/idea/skill that was deleted or unavailable) mentionUnresolved: 'The mentioned {kind} was deleted or is unavailable', // Same-name skill conflict (scan_skills returns conflicts; frontend warns, injection takes first by skills>commands>plugins priority) skillConflict: 'Skill "{name}" has multiple definitions; using skills priority', // ── ⑥.4 Phase 4: @project expansion summary (input area preview) ── enrichmentBadge: '📎 Referenced "{project}" ({tasks} tasks, {ideas} ideas)', enrichmentExpand: 'Show context preview', enrichmentCollapse: 'Hide context preview', enrichmentLabel: 'Context preview', // ── F-15 phase 2: manual context management (clear / compress) ── // Buttons (Header action area: trash + compress icon) clearContext: 'Clear context', compressContext: 'Compress context', // Confirm dialog (clear is semantically irreversible; history archived, not deleted) // Title "Clear context" folded into the lead sentence; stress irreversible + archived segment + AI no longer sees history clearContextConfirm: 'Clear context? This action is irreversible. The current chat context will be archived as a segment (the AI will no longer see these history messages). New chats are not affected.', // Danger button label for the confirm dialog (ConfirmDialog dangerLabel); falls back to common.confirm if omitted clearContextDangerLabel: 'Clear', // Collapsed separator (consecutive same-status merged into one bar; {n}=merged message count) contextArchived: 'Archived {n} messages', compressed: 'Context compressed', compressing: 'Compressing…', clearSuccess: 'Context cleared', compressSuccess: 'Context compressed', // B4: one-shot auto-compress notice (loop auto-compress no longer fully silent) autoCompressed: 'Context auto-compressed (earlier messages folded into summary)', compressError: 'Compression failed: {msg}', clearError: 'Clear failed: {msg}', initError: 'AI panel init failed: {msg} (reopen panel to retry)', initDegraded: 'List load failed, continuing in degraded mode: {msg}', // Separator expand / collapse expand: 'Expand', collapse: 'Collapse', // Compressed summary block label (before the system summary message when expanded) compressedSummaryLabel: 'Context summary', // ── TopBar bottom context badges (tooltip + L3 full context popover labels) ── viewGoals: 'View goals', runningTasks: 'Running background tasks', runningRounds: '{n} rounds running', untitledConversation: 'Untitled conversation', recoverableTask: 'Interrupted · recoverable', recoverNow: 'Resume', viewHistory: 'View history messages', viewSummary: 'View context summary', viewContext: 'View AI context', contextSystemPrompt: 'System Prompt', contextEnvironment: 'Environment', contextCompressedSummary: 'Compressed Summary', contextEnrichment: 'Enriched Context', contextCountUnit: 'items', // ── EnrichmentPanel ── enrichmentDismiss: 'Unlink', // ── AE-2025-04 Session Trust ── // Auto-approval toast (same-session already approved same-kind op: same tool + same dir) autoApprovedToast: 'Auto-approved: {tool}({dir})', // ── Skill injection feedback (success/failure light toast for /skill resolve) ── skillInjectedToast: 'Skill "{name}" injected', skillNotFoundToast: 'Skill {name} not found', // ── CIStatus.vue (commit CI checks status card) ── ciTitle: 'CI Checks', ciNFailed: '{n} failed', ciNPending: '{n} pending', ciNPassed: '{n} passed', // ── MessageList token detail popover (per-fee breakdown: input/cache hit/output/reasoning) ── tokenDetailTitle: 'Token usage details', estimated: 'estimated', tokenInLabel: 'Input (cache miss, full price)', tokenCacheLabel: 'Cache hit (low price)', tokenOutLabel: 'Output', // #12 conversation-cumulative tokens (token detail popover footer) tokenConvTotal: 'Conversation total', tokenConvTotalIn: 'Total in', tokenConvTotalOut: 'Total out', tokenReasonLabel: 'Reasoning', tokenCacheRateLabel: 'Cache hit rate', tokenModelLabel: 'Model', tokenUsageNoteLabel: 'Usage note', tokenUsageNote: 'prompt_tokens missing, shown as estimated', // ── TopBar goal/project context labels ── goalsCount: 'Goals ({n})', none: 'None', projectLabel: "{'@'}Projects", // ── 3c UX batch addition (I5 classified send-failure messages): friendly text by // error kind; {msg} keeps the raw error string for troubleshooting ── sendErrRateLimit: 'Rate limit reached, please retry later (error: {msg})', sendErrQuota: 'AI quota or balance insufficient, check your provider account (error: {msg})', sendErrNetwork: 'Network error or timeout, check your connection and retry (error: {msg})', // ── UX-P3 chat polish additions ── editEmptyBlocked: 'Edit content is empty, submission cancelled', skillNoMatchQuery: 'No skill matches "{q}", send blocked', backfillOverwriteConfirm: 'The input box has an unsent draft; backfilling will overwrite it. Continue?', }, }