@x-otto/tui 0.0.1-alpha.0 → 0.0.1-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/compat.js CHANGED
@@ -1,3 +1,3 @@
1
- import{n as e}from"./i18n-CznO8p1Y.js";var t=class{commands=new Map;register(e){if(this.commands.has(e.name))throw Error(`Command "/${e.name}" is already registered`);this.commands.set(e.name,e)}get(e){return this.commands.get(e)}find(e){let t=this.commands.get(e);if(t)return t;for(let t of this.commands.values())if(t.aliases?.includes(e))return t}list(){return[...this.commands.values()]}names(){return[...this.commands.keys()]}has(e){return this.commands.has(e)}unregister(e){return this.commands.delete(e)}};function n(){let n=new t;return n.register({name:`help`,description:e.t(`cmdDesc.help`),aliases:[`h`,`?`],type:`action`,source:`builtin`,execute:()=>({kind:`help`})}),n.register({name:`exit`,description:e.t(`cmdDesc.exit`),aliases:[`quit`,`q`],type:`action`,source:`builtin`,execute:e=>{let t=e?.trim()??``;return t===`--restart`||t===`-r`?{kind:`exit`,restart:!0}:{kind:`exit`}}}),n.register({name:`clear`,description:e.t(`cmdDesc.clear`),type:`action`,source:`builtin`,execute:()=>({kind:`clear`})}),n.register({name:`abort`,description:e.t(`cmdDesc.abort`),type:`action`,source:`builtin`,execute:()=>({kind:`abort`})}),n.register({name:`copy`,description:e.t(`cmdDesc.copy`),type:`action`,source:`builtin`,execute:()=>({kind:`copy`})}),n.register({name:`model`,description:e.t(`cmdDesc.model`),aliases:[`m`],type:`action`,source:`builtin`,execute:(t,n)=>{if(!n.models||n.models.length===0)return e.t(`model.noRegistry`);if(t&&n.onModelChange){let r=n.models.find(e=>e.id===t||e.name===t);return r?{kind:`model`,modelId:r.id}:e.t(`model.notFound`,{name:t})}let r=new Map;for(let e of n.models){let t=r.get(e.provider)??[];t.push(e),r.set(e.provider,t)}let i=[``];for(let[e,t]of r){i.push(` ${e}:`);for(let e of t){let t=e.id===n.currentModel?` *`:` `;i.push(` ${t} ${e.id} — ${e.name}`)}}return i.push(``,e.t(`model.listFooter`)),i.join(`
1
+ import{n as e}from"./i18n-Dju4J1Q-.js";var t=class{commands=new Map;register(e){if(this.commands.has(e.name))throw Error(`Command "/${e.name}" is already registered`);this.commands.set(e.name,e)}get(e){return this.commands.get(e)}find(e){let t=this.commands.get(e);if(t)return t;for(let t of this.commands.values())if(t.aliases?.includes(e))return t}list(){return[...this.commands.values()]}names(){return[...this.commands.keys()]}has(e){return this.commands.has(e)}unregister(e){return this.commands.delete(e)}};function n(){let n=new t;return n.register({name:`help`,description:e.t(`cmdDesc.help`),aliases:[`h`,`?`],type:`action`,source:`builtin`,execute:()=>({kind:`help`})}),n.register({name:`exit`,description:e.t(`cmdDesc.exit`),aliases:[`quit`,`q`],type:`action`,source:`builtin`,execute:e=>{let t=e?.trim()??``;return t===`--restart`||t===`-r`?{kind:`exit`,restart:!0}:{kind:`exit`}}}),n.register({name:`clear`,description:e.t(`cmdDesc.clear`),type:`action`,source:`builtin`,execute:()=>({kind:`clear`})}),n.register({name:`abort`,description:e.t(`cmdDesc.abort`),type:`action`,source:`builtin`,execute:()=>({kind:`abort`})}),n.register({name:`copy`,description:e.t(`cmdDesc.copy`),type:`action`,source:`builtin`,execute:()=>({kind:`copy`})}),n.register({name:`model`,description:e.t(`cmdDesc.model`),aliases:[`m`],type:`action`,source:`builtin`,execute:(t,n)=>{if(!n.models||n.models.length===0)return e.t(`model.noRegistry`);if(t&&n.onModelChange){let r=n.models.find(e=>e.id===t||e.name===t);return r?{kind:`model`,modelId:r.id}:e.t(`model.notFound`,{name:t})}let r=new Map;for(let e of n.models){let t=r.get(e.provider)??[];t.push(e),r.set(e.provider,t)}let i=[``];for(let[e,t]of r){i.push(` ${e}:`);for(let e of t){let t=e.id===n.currentModel?` *`:` `;i.push(` ${t} ${e.id} — ${e.name}`)}}return i.push(``,e.t(`model.listFooter`)),i.join(`
2
2
  `)}}),n.register({name:`status`,description:e.t(`cmdDesc.status`),type:`action`,source:`builtin`,execute:()=>({kind:`status`})}),n}function r(e,t,n){return Promise.resolve({command:`help`,args:``})}export{t as CommandRegistry,n as createBuiltinCommands,r as showCommandPalette};
3
3
  //# sourceMappingURL=compat.js.map
@@ -25,11 +25,11 @@ Conflicting files:
25
25
  {{joined}}`,bgJobIncomplete:`✗ Job {{id}} did not complete ({{status}}): {{message}}{{conflicts}}`,bgAutoReloadFailed:`Auto hot-reload failed (run /reload manually): {{msg}}`,modelCompactedFor:`Compacted for {{window}} window`,grillRecommendation:`
26
26
  Recommendation: {{rec}}`,grillEvidence:`
27
27
  Evidence:
28
- {{joined}}`,grillFreeformPlaceholder:`Enter your own option / extra info…`,grillAnswerPlaceholder:`Type your answer…`,titleBackgroundTask:`Background Task`,lifecycleCrossBoundaryDone:`"{{toolName}}" finished (started in a previous task — result not added to this conversation)`,lifecycleCrossBoundaryFailed:`"{{toolName}}" failed (started in a previous task — result not added to this conversation)`,titleFeedback:`Feedback`,feedbackStepTitle:`Short title for the issue`,feedbackStepRepro:`Steps to reproduce (optional)`,feedbackStepExpected:`Expected behavior (optional)`,feedbackStepActual:`Actual behavior (optional)`,feedbackConfirmTitle:`Submit feedback?`,feedbackConfirmMessage:`Title: {{title}}
28
+ {{joined}}`,grillFreeformPlaceholder:`Enter your own option / extra info…`,grillAnswerPlaceholder:`Type your answer…`,grillOptionYes:`Yes`,grillOptionNo:`No`,titleBackgroundTask:`Background Task`,lifecycleCrossBoundaryDone:`"{{toolName}}" finished (started in a previous task — result not added to this conversation)`,lifecycleCrossBoundaryFailed:`"{{toolName}}" failed (started in a previous task — result not added to this conversation)`,titleFeedback:`Feedback`,feedbackStepTitle:`Short title for the issue`,feedbackStepRepro:`Steps to reproduce (optional)`,feedbackStepExpected:`Expected behavior (optional)`,feedbackStepActual:`Actual behavior (optional)`,feedbackConfirmTitle:`Submit feedback?`,feedbackConfirmMessage:`Title: {{title}}
29
29
 
30
30
  {{bodyPreview}}`,feedbackChannelSubmitting:`Submitting…`,feedbackRepoUnresolved:`Could not resolve a target repository — set "feedback_repo" in .otto/config.json`,feedbackCreated:`Opened: {{url}}`,feedbackUnavailable:`Feedback plugin is not available (disabled or not installed)`,compatTrusted_one:`Trusted · {{count}} MCP tool`,compatTrusted_other:`Trusted · {{count}} MCP tools`,resumeProbeHiddenHint_one:`({{count}} probe session hidden, use /resume --all to view)`,resumeProbeHiddenHint_other:`({{count}} probe sessions hidden, use /resume --all to view)`,resumeArchivedHiddenHint_one:`({{count}} archived session hidden, use /resume --archived to view)`,resumeArchivedHiddenHint_other:`({{count}} archived sessions hidden, use /resume --archived to view)`,memoryDialogProjGroup_one:`Project memory (.otto/memory) · {{count}} entry`,memoryDialogProjGroup_other:`Project memory (.otto/memory) · {{count}} entries`,memoryDialogUserGroup_one:`User memory (~/.otto/memory) · {{count}} entry`,memoryDialogUserGroup_other:`User memory (~/.otto/memory) · {{count}} entries`,pluginTrusted_one:`Trusted {{id}} · {{count}} MCP tool`,pluginTrusted_other:`Trusted {{id}} · {{count}} MCP tools`,resumeRestored_one:`↻ Resumed session {{idShort}} ({{count}} past message in context; continuing from here)`,resumeRestored_other:`↻ Resumed session {{idShort}} ({{count}} past messages in context; continuing from here)`,"imageDegradationNotice_image-constraint_one":`{{count}} older image dropped (exceeded provider image limits)`,"imageDegradationNotice_image-constraint_other":`{{count}} older images dropped (exceeded provider image limits)`,imageDegradationNotice_other_one:`{{count}} older image dropped to fit context`,imageDegradationNotice_other_other:`{{count}} older images dropped to fit context`,promptBudgetExceeded_tokens:`Output-token budget exceeded ({{used}}/{{budget}}) — asked model to wrap up`,promptBudgetExceeded_other:`Time budget exceeded ({{used}}/{{budget}}) — asked model to wrap up`,sessionCostBudgetExceeded:"Session cost budget exceeded (${{used}}/${{budget}}) — not blocking, check /cost for details",memoryPressureMessage:`otto's memory usage is high ({{usedPct}}% of the heap limit). Restarting now will save all progress and continue safely, avoiding an unpredictable crash.`,authFailed:`Authentication failed — the API key for the current model{{ps}} is invalid or expired. Type /auth{{ls}} to reconfigure credentials, then retry.`,authRefreshFailed:`Login refresh failed{{ps}} — this may be a network issue or a concurrent refresh conflict across multiple otto processes. Please retry shortly; if it keeps failing, run /auth{{ls}} to re-authenticate.`,extToggled:`{{verb}} {{name}}{{seg}}`,pluginUsage:`Usage: /trust plugin {{seg}}<id>`,installedTo:`{{name}} installed to {{scope}}{{seg}}`,statusLineOccupancy:`Context occupancy: {{occ}} / {{window}}{{seg}}`,extPluginTitle:`{{name}} — {{state}} · pick an action · Esc to close`,extSkillTitle:`{{name}} — {{state}} · pick an action · Esc to close`,extAgentTitle:`{{name}} — {{state}} · pick an action · Esc to close`,bpToggled:`{{point}} {{state}}`,pluginInstalled:`{{seg}}`,pinBatchSummary:`{{seg}}`,extSkillSourceLabel:`{{seg}}`,upgradeAvailableLines:[`Current: v{{current}}`,`Latest: v{{latest}}`,``,`Hot-upgrade flow: npm install -g @x-otto/cli@latest → auto-restart`,``,`⚠ The current session will be interrupted during the upgrade.`,`Type /upgrade --force to confirm.`],extHealthSummary:`health {{hookTimeouts}} hook timeout(s) · {{toolTimeouts}} tool timeout(s)`,extHealthSummary_err:`health {{hookTimeouts}} hook timeout(s) · {{toolTimeouts}} tool timeout(s) · last error: {{lastError}}`,keybindTitle:`Keybindings`,keybindSavedRestartHint:`Saved. Restart the session for the new key to take effect.`},permission:{allowTool:`Allow tool:`,bashCommand:`Bash command`,approve:`Approve`,deny:`Deny`,alwaysAllow:`Always allow`,riskLabel_low:`low risk`,riskLabel_medium:`medium risk`,riskLabel_high:`high risk`},hint:{select:`select`,confirm:`confirm`,execute:`execute`,cancel:`cancel`,delOne:`delete one`,choose:`choose`,option:`option`,question:`question`,shortcut:`shortcut`,toInterrupt:`to interrupt`,pausedContinue:`type to continue or /continue`,steer:`steer`,queue:`queue`,history:`history`,autosuggestAccept:`accept suggestion`,autosuggestMenu:`completions`,submit:`submit`,kill:`kill`,output:`output`,apply:`apply`,switch:`switch`,delete:`delete`,close:`close`,collapse:`collapse`,retry:`Retry`,view:`view`,load:`load`,check:`check`,grab:`grab`,drop:`drop`,move:`move`,edit:`edit`,exit:`exit`,dismiss:`dismiss`,quick:`quick`,refresh:`refresh`,subagents:`agents`,tasks:`tasks`,viewDetail:`↵ view details`,back:`back`,scroll:`scroll`,find:`find`,tabSwitchOutput:`switch view`,tabFocus:`switch panel`,tabZone:`switch area`,toggle:`Toggle`,add:`add`,run:`run`,runNow:`run now`,detail:`detail`,logs:`logs`,switchField:`switch field`,discard:`discard`,confirmCancel:`confirm cancel`,confirmRemove:`confirm remove`,abort:`abort`},history:{label:`History`,capped_one:`earliest {{count}} message removed from the in-memory view (session message count limit reached; still fully kept in storage)`,capped_other:`earliest {{count}} messages removed from the in-memory view (session message count limit reached; still fully kept in storage)`,cappedBytes_one:`earliest {{count}} message removed from the in-memory view (session content exceeded the byte budget; still fully kept in storage)`,cappedBytes_other:`earliest {{count}} messages removed from the in-memory view (session content exceeded the byte budget; still fully kept in storage)`,cappedMemoryPressure_one:`earliest {{count}} message removed from the in-memory view (memory pressure tightened session residency; still fully kept in storage)`,cappedMemoryPressure_other:`earliest {{count}} messages removed from the in-memory view (memory pressure tightened session residency; still fully kept in storage)`,cappedLossy_one:`⚠ earliest {{count}} message dropped from the model context **without a summary** — the model can no longer see it (fallback trim after repeated compaction failures). The raw record is still fully kept in storage; use /history to review.`,cappedLossy_other:`⚠ earliest {{count}} messages dropped from the model context **without a summary** — the model can no longer see them (fallback trim after repeated compaction failures). Raw records are still fully kept in storage; use /history to review.`},common:{more:`more`,disabled:`disabled`,wordOr:`or`,moreLinesLabel:`… +{{n}} more lines`,thoughtLines:`Thought ({{n}} lines)`,noContentAvailable:`(no content to display)`,contentUnavailable:`(content unavailable — session was resumed, original file content was not persisted)`,cancelButton:`Cancel`,upgradeButton:`Upgrade`,escClose:`Esc close`,noMatches:`no matches`,confirmButton:`Confirm`,genericCancelButton:`Cancel`,dontRemind:`Don't remind again`,okButton:`OK`,abortButton:`Abort`,pauseButton:`Pause`,abortAndExitButton:`Abort & Exit`,abortAndRestartButton:`Abort & Restart`},model:{noneAvailable:`No usable model — first`,goLogin:`Log in`,setKey:`Set API key`,pendingCapabilities:`{{count}} provider plugin(s) awaiting authorization`,goGrantCapability:`Authorize`,noProviderPlugin:`No provider plugins installed — install one to get started.`,goInstallPlugin:`Install provider plugin`,switchedTo:`switched to {{label}}`,title:`configured model unavailable`,reasonNotFound:`Reason: model id not found (may be retired or misspelled)`,reasonUnauthenticated:`Reason: {{provider}} is not authenticated`,hint:`/auth to authenticate the provider · /model to switch`,permanent:`Switch`,login:`Go to Login`,dismiss:`Exit`,goToLoginButton:`Go to login`,goToExtensionButton:`Authorize`,forcedUpgradeTitle:`Forced Upgrade Required`,noRegistry:`No model registry available.`,notFound:`Model not found: {{name}}. Use /model to list.`,listFooter:` /model <id> to switch. * = current`,visionDelegateToast_one:`{{count}} image described by a vision model (current model has no vision input support)`,visionDelegateToast_other:`{{count}} images described by a vision model (current model has no vision input support)`,fallbackLoginToast:`Opening login for {{provider}}…`},welcome:{providerDesc:{"anthropic-provider":`Anthropic Claude — OAuth login (recommended)`,"deepseek-provider":`DeepSeek — requires DEEPSEEK_API_KEY`,"openai-codex-provider":`OpenAI Codex — requires credentials`},version:`Version`,workspace:`Workspace`,extensions:`Extensions`,msgCountLabel_one:`{{count}} msg`,msgCountLabel_other:`{{count}} msgs`,itemCountLabel_one:`{{count}} item`,itemCountLabel_other:`{{count}} items`,greeting_late:`It's late on {{wday}}{{who}} — a quiet time to think deeply.`,greeting_earlyMorning:`Rise and shine{{who}}! {{wday}} morning — fresh ideas await.`,greeting_morning:`Good {{wday}} morning{{who}} — let's build something great.`,greeting_afternoon:`Happy {{wday}} afternoon{{who}} — keep the momentum going.`,greeting_evening:`Good {{wday}} evening{{who}} — time to wrap up and reflect.`,greeting_night:`Late {{wday}} night{{who}} — the best ideas come after dark.`,tipLabel:`OTTO Tip`,shadowBadge:`SHADOW`,shadowChip:`shadow — nothing written to disk`,shadowBannerTitle:`Shadow session — zero disk footprint`,shadowGuarantee:`Guaranteed: otto state (credentials, sessions, memory, lessons, config, trace, logs) stays in memory only — nothing written to disk this session.`,shadowNotGuaranteedTitle:`NOT covered (may still leave traces):`,shadowNg1:`Files you have otto edit/write in your project (your intended output)`,shadowNg2:`Shell commands, git, MCP servers, third-party plugins writing on their own`,shadowNg3:`Provider-side logs, telemetry and billing records`,shadowNg4:`OS traces: your shell history, process list, network connections`},onboarding:{title:`Get Started`,nameQuestion:`What should I call you?`,langQuestion:`Choose your language`,namePlaceholder:`e.g. aniwei`,nameDesc:`Your nickname helps personalize conversations and notifications.`,langFootnote:`You can change this later with /preference lang.`,langOptions:{en:`English (en)`,zh:`中文 (zh)`,auto:`Auto-detect from system`},skip:`Skip`,done:`Done`,stepName:`Nickname`,stepLang:`Language`,stepTheme:`Theme`,stepCounter:`Step {{current}}/{{total}}`,langAuto:`Auto-detect from system`,themeQuestion:`Color theme`,themeFootnote:`Move the highlight to preview live; System detects your terminal background`,themeDark:`Dark`,themeLight:`Light`,themeSystem:`Follow terminal`,hintNext:`next`,hintDone:`done`,hintSkip:`skip`,hintBack:`back`,hintQuick:`quick`},prompt:{ready:`ready`,streaming:`streaming`,default:`Type a message or /help…`,working:`Agent is working — type to steer this turn…`,setup:`Not set up yet — /setup to continue where you left off`,fallback:`Type a message…`,submit:`Submit`,readySuffix:`{{n}} ready`,upgradeRequired:`Update required — /upgrade to continue`,submitButton:`Submit`,defaultTitle:`Prompt`,reviewingPlaceholder:`Reviewing history · Esc to return`,unfocused:`Input preserved — continue anytime…`},questions:{readyToSubmit:`Ready to submit your answers.`,someUnanswered:`Some questions unanswered — submit anyway?`},freeform:{tab:`Notes`,filled:`*`,empty:`-`,label:`Add notes or clarification (optional):`,placeholder:`Type your notes here…`,advance:`done (advance to submit)`},panelTitle:{memory:`memory`,editedFilesTitle:`Edited files`},inspText:{thinking:`thinking`,thinkingLabel:`Thinking…`},update:{forcedBanner:`⚡ Forced upgrade to v{{latest}} — type /upgrade now`,availableBanner:`🆕 v{{latest}} available — type /upgrade for details`},status:{failed:`failed`,interrupted:`interrupted`,done:`done`,stopped:`paused`},task:{leftLabel:`{{done}}/{{total}} · {{left}} left`,title:`Task`,collapsedHint:`collapsed`,detailTitle:`Task Detail`,turnInfo:`(turn #{{turn}}, {{shown}}/{{total}} messages)`,turnTag:`(turn #{{turn}})`,truncated:`... {{n}} more messages truncated`,statusLabel_pending:`pending`,statusLabel_in_progress:`in progress`,statusLabel_done:`done`,statusLabel_skipped:`skipped`,statusLabel_failed:`failed`},tool:{edit:`Edit`,write:`Write`,read:`Read`,tasks:`Tasks`,subagent:`Subagent`,unknown:`unknown`,fallback:`tool`,compact:`Compact`,prune:`Prune`,history:`History`,session:`Session`,run:`Run`,model:`Model`,effort:`Effort`,budgetLabel:`{{used}}/{{max}} tools`,countLabel_one:`{{count}} tool`,countLabel_other:`{{count}} tools`,chainSummary_one:`[{{count}} tool: {{names}}]`,chainSummary_other:`[{{count}} tools: {{names}}]`},diff:{modeLabel:`vs HEAD`,loading:`Loading whole-file diff…`,error:`Whole-file diff unavailable: {{message}}`,linesTotalLabel_one:`{{count}} line`,linesTotalLabel_other:`{{count}} lines`,fileCountLabel_one:`{{count}} file`,fileCountLabel_other:`{{count}} files`,fileOpLabel_edit:`modified`,fileOpLabel_write:`created`,fileOpLabel_other:`deleted`},compact:{ed:`earlier messages compacted`,pruned:`tool outputs trimmed to fit context`,ing:`Compacting context…`,edResult:`✓ Context compacted: {{before}} → {{after}} messages (full transcript preserved)`,noop:`Nothing to compact — context is already small.`,unavailable:`Compaction unavailable: memory/compaction is not enabled for this session.`,logTitle:`Compaction & Prune Log`,logEmpty:`No compaction or prune events yet this session.`,logCompactRow:`{{before}} → {{after}} ({{pct}}% kept)`,logDetailTitle:`{{kind}} · {{time}}`,logNoSummary:`No summary available for this event.`,logViewSummary:`view summary`,ingVerb:`Compacting`,logHistoryCappedRow_one:`{{count}} message removed from memory (still kept in storage)`,logHistoryCappedRow_other:`{{count}} messages removed from memory (still kept in storage)`,ionStageLabel_analyze:`Analyzing context`,ionStageLabel_summarize:`Generating summary`,ionStageLabel_finalize:`Finalizing`,logPruneRow:`saved ~{{tokensSaved}} tokens`,logPruneRow_pruned_one:`saved ~{{tokensSaved}} tokens ({{count}} tool output)`,logPruneRow_pruned_other:`saved ~{{tokensSaved}} tokens ({{count}} tool outputs)`},lease:{denied:`this turn’s changes were NOT saved — another otto process owns this session’s write lease`,restored:`write access restored — changes will save normally from now on`,deniedToastTitle:`Session read-only (changes not saved)`,deniedToastBody:`Why: another otto process is writing this session (e.g. another terminal window, or an /exit -r restart handoff that hasn’t completed).
31
31
  This window still works normally, but changes will not be saved.
32
- Fix: ① close the other otto process — this session will automatically become writable again on the next successful save; ② or exit this window and /resume a different session to continue working.`,restoredToastTitle:`Session write access restored`,restoredToastBody:`Changes will save normally from now on.`},pause:{titleRequested:`Waiting to pause`,bodyRequested:`Will pause once the current turn finishes`,titleActive:`Paused`,bodyActive:`Agent is paused — queued messages will not run`,btnCancel:`Cancel pause`,btnResume:`Resume`,footerDismiss:`Esc to dismiss overlay (pause request continues in background)`,footerActive:`Enter to accept · Esc to dismiss`,toolCount:`{{n}} tools · {{s}}s`,toolTotal:`Ran {{n}} tools this turn`},run:{messageFooter:`Type anything or /continue to resume`,resumedMessageBody:`Agent resumed`,pauseCancelledMessageBody:`Pause request cancelled — agent continues running`,messageBody:`Agent paused — queued messages will not run automatically`,messageBody_n:`Agent paused after {{n}} tools this turn — queued messages will not run automatically`},shell:{running:`running`,terminated:`terminated`,errored:`error`,exit:`exit {{code}}`,copyHint:`copy output`,copiedTitle:`Shell`,copiedBody:`Copied to clipboard`,hint:`ask AI`,exitCode:`exit code {{code}}`,askAiTerminated:`terminated by signal`,unknownError:`unknown error`,prompt:"The command `{{command}}` failed ({{errorLabel}}). Here is the output, please help diagnose:\n\n```\n{{output}}\n```",truncated:`...(truncated — press c to copy the full output to clipboard)`,viewAll_one:`view all output ({{count}} line total)`,viewAll_other:`view all output ({{count}} lines total)`,moreLines_one:`... {{count}} more line ...`,moreLines_other:`... {{count}} more lines ...`},spinner:{verbs:[`Working`,`Thinking`,`Crunching`,`Running`],outputPercent:`{{pct}}% of limit`,estimatedPercent:`~{{pct}}%`},bg:{runningVerb:`Running {{tool}}`,tasksTitle:`Delegates`,empty:`(no background tasks)`,noOutput:`(no output yet)`,live:`live`,following:`following…`,jobsLabel:`{{n}} delegates`,runningSuffix:`{{n}} running`,doneSuffix:`{{n}} done`,needInputSuffix:`{{n}} need input`,metaReady:`ready`,metaNeedsInput:`needs input`,agentStatusLabel:`{{st}}`,procStatusLabel:`{{s}}`,categoryLabel_job:`Jobs`,categoryLabel_bash:`Bash`,categoryLabel_other:`Sub-agents`,metaExited:`exited`,metaExited_code:`exited {{code}}`},subagent:{sTitle:`Subagents`,sRunning:`{{n}} running`,header:`Sub-agent @{{title}} · {{status}}`,contextEarlierLines:`↑ {{n}} lines earlier · ↵ for full scrollable transcript`,sWorking_one:`Subagent working ({{count}} subagent)`,sWorking_other:`Subagent working ({{count}} subagents)`},agent:{interruptTitle:`Interrupt agent?`,interruptMessage:`The current agent turn is still running. Interrupting will stop it and mark the turn as interrupted.`,interruptConfirm:`Interrupt`},queue:{label:`Queue`,empty:`No queued commands`,editTitle:`Edit queued item {{index}}/{{total}}`,editSendNowButton:`Send Now`,editConfirmButton:`Confirm`,editSendNowHintBusy:`Will be injected as a supplement to the current turn`,editSendNowHintIdle:`Will be sent immediately as a new message`,exitTitle:`Exit Queue Panel`,exitConfirm:`Clear and Exit`,exitMessage:`The panel has %d queued commands that will be cleared.`,popTitle:`Remove queued message?`,popMessage:`One follow-up message is queued. Remove the newest queued message instead of interrupting the running turn?`,popConfirm:`Remove queued message`,dFollowUpToast:`Model still running — queued as a follow-up, will send when it finishes`},retry:{reason:`{{reason}}`,defaultTitle:`Error details`,attempt:`Retry {{attempt}}/{{max}}`,countdown:`Retrying in {{s}}s…`,progressSep:` · `,nowButton:`Retry now`,hint:`↵/r`,stopButton:`Stop`,hintWithStop:`↵/r retry · Esc stop`},error:{typeLabel:`{{type}} limit reached`,retryNow:`Retry now`,switchModel:`Switch model`,title:`Request failed: {{reason}}`,defaultTitle:`Request failed`,exhaustedTitle:`Request failed after retries`,autoCountdown:`Attempt {{attempt}}/{{max}} · retrying in {{seconds}}s`,manualBody:`Attempt {{attempt}}/{{max}} · action required to retry`,exhaustedBody:`Retried {{max}} times, still failing`,resetsIn:`Quota resets in {{hms}}`,unknownReset:`Reset time unknown`,hint:`←/→ select · ↵ confirm · r retry now · Esc cancel`},pulse:{title:`How was this session?`,ratingGood:`Good`,ratingNeutral:`Neutral`,ratingBad:`Needs work`,commentTitle:`{{ratingLabel}} · Anything to add? (optional)`,commentPlaceholder:`Type your thoughts…`,hintRating:`←/→/Tab switch · ↵ select · Esc close`,hintComment:`↵ submit · Esc close (rating is saved either way)`},find:{inputLabel:`Find:`,matchCount:`{{current}}/{{total}}`,tabPrompt:`Prompt`,tabConversation:`Conversation`,tabDiff:`Diff`,tabDiagnostics:`Diagnostics`,searchNoMatches:`no matches`},schedule:{sLabel:`Schedules`,sEmpty:`No scheduled tasks. Create one with /schedule add`,oneShot:`one-shot`,next:`next: `,panel:{noTasks:`No scheduled tasks.`,pressToAdd:`Press {{key}} to create your first schedule.`,examples:`Examples: {{c1}} daily at 09:00 · {{c2}} every 30 minutes`,running:`running`,failedCanceled:`failed/canceled`,readonlyNet:`{{cross}} network error — cannot reach schedule service`,readonlyLease:`{{cross}} read-only — another terminal holds the fire-ownership lease`,moreAbove:`... {{n}} more above`,moreBelow:`... {{n}} more below`,failedErr:`(failed: {{err}})`,detail:{id:`ID`,status:`Status`,type:`Type`,cron:`Cron`,prompt:`Prompt`,nextFire:`Next fire`,lastFire:`Last fire`,never:`never`,jobRunning:`{{cross}} job running — {{id}}`,recent:`Recent (last {{n}})`,loadingLogs:`Loading logs...`,noLogs:`No logs yet`},logsTitle:`Logs: {{id}}`,form:{newTitle:`New Schedule`,editTitle:`Edit: {{id}}`,name:`Name`,cron:`Cron`,type:`Type`,status:`Status`,prompt:`Prompt`,preview:`Preview`,auto:`(auto)`,cronPlaceholder:`________________`,recurring:`recurring`,enabled:`enabled`,disabled:`disabled`,toggleHint:`(←/→ to toggle)`,templatesHint:`press ←/→ for templates`,templates:`templates`,previewNext:`Next fire: {{time}}`,previewJitter:`Next fire: {{time}} + 0-30min jitter`,previewJitterOnce:`Next fire: {{time}} + ~90s jitter`,previewCron:`cron: {{cron}} (recurring)`,previewCronOnce:`cron: {{cron}} (one-shot)`,previewEmpty:`enter a valid cron expression`,invalidCron:`invalid cron`,required:`Cron and prompt are required`,saving:`Saving...`,createFailed:`Failed to create`,saveFailed:`Failed to save`},confirmCancelTitle:`Cancel job?`,confirmCancelBody:`This will cancel the currently running job of {{name}}.`,confirmCancelNote:`The schedule definition will not be affected.`,confirmRemoveTitle:`Remove schedule?`,confirmRemoveBody:`This will permanently delete {{name}} ({{id}}).`,confirmRemoveWarn:`This action cannot be undone.`}},draft:{sLabel:`Drafts`,sEmpty:`No drafts. Save one with Ctrl+S`,saved:`Saved to drafts`,saveEmpty:`Nothing to save — input is empty`},prompts:{label:`Prompts`,empty:`No prompts yet`},service:{sTitle:`Services`,sEmpty:`(no running services detected)`,countLabel_one:`svc`,countLabel_other:`svcs`},scroll:{above:`↑ {{n}} lines above`,below:`↓ {{n}} lines below`,viewportLinesAbove:`lines above`,viewportLinesBelow:`lines below`},insp:{live:`live · {{n}} rows`,row:`row {{cur}}/{{total}}`,replay:`replay`,paused:`⏸ paused`,pausedBig:`⏸ PAUSED`,inspect:`inspect`,hintPause:`c continue · s step · n next · o step-out · x stop`,hintFocus:`Ctrl+G to focus`,hintBp:`↑↓ select · Tab switch · space toggle · Esc exit`,bpIdle:`▶ ⤼ ⤓ ⤴ ⏹ idle — run a prompt to pause at an enabled breakpoint`,variablesIdle:`Variables appear when paused — enable a point in Sources, then run`,breakpoints:`BREAKPOINTS`,noneInteractive:`— none (need interactive inspector) —`,noTools:`— no tool calls yet —`,noEvents:`— no trace events yet (run a prompt) —`,noUsage:`— no usage yet (run a prompt) —`,noLineage:`— no lineage —`,toolbar:`▶ continue(c) ⤼ over(n) ⤓ step(s) ⤴ out(o) ⏹ stop(x)`,variables:`VARIABLES`,editKeys:` Enter=save Esc=cancel`,injectMsg:`inject msg`,changeData:`change data: t think · [ ]temp · i inject · e sys`,budgetOverhead:`overhead`,budgetMessages:`messages`,budgetFree:`free`,budgetLastTotal:`last {{lastIn}}→{{lastOut}} · total {{totalIn}}→{{totalOut}}`,liveTag:`▸ live`,userPrefix:`user: `,thinkingFull:`thinking (full):`,toolRunning:`{{tool}} (running)`,toolCall:`{{tool}} (call)`,assistantFallback:`assistant text`,emptyPrompt:`(prompt)`,endTurn:`· end_turn`,treeThinking:`thinking ⟨{{n}} · {{chars}} chars⟩`,bpCatAgentWorkLoop:`Agent Work Loop`,bpCatWorkLoopInjection:`Work-loop Injection`,bpCatToolExecutor:`Tool Executor`,bpCatSessionPrompt:`Session Prompt Lifecycle`,bpCatLifecycleHook:`Lifecycle Hook`,bpCatTurnObservable:`Turn Observable`,bpCatCustom:`Custom`,debugCall:`Call`,debugLlmParams:`LLM Params`,debugSystemPrompt:`System Prompt`,debugMessages:`Messages ({{n}})`,debugTokens:`Tokens in {{inTokens}} · out {{outTokens}}`,debugEmpty:`(empty)`,debugEditsPending:`edits: {{parts}} (apply on resume)`,debugEditSysPrompt:`system prompt`,asstPrefix:`asst: `,thinkingPrefix:`thinking… `,noTurnData:`No turn data available.`,treeAssistantDeltas_one:`assistant ⟨{{count}} delta · {{chars}} chars⟩`,treeAssistantDeltas_other:`assistant ⟨{{count}} deltas · {{chars}} chars⟩`,hintTree:`↑↓ move · Tab switch · w why{{whySeg}} · z expand{{expandSeg}} · space fold · Esc exit`},budget:{exhaustedTitle:`Hit this turn’s tool-step budget — the task may be unfinished. Keep going?`,continue:`Keep going`,stop:`Stop`,stoppedNote:`⏸ Stopped at the tool-step budget — the task may be unfinished. Just keep instructing me to continue (each prompt resets this turn’s tool budget).`,tokensLabel_one:`{{count}} token`,tokensLabel_other:`{{count}} tokens`,tokenBudgetLabel:`{{used}}/{{budget}} tok`},cmdDesc:{help:`Show available commands`,exit:`Exit the TUI; /exit --restart to restart into the same session`,clear:`Clear screen and reset session`,abort:`Abort the current agent run`,copy:`Copy last assistant response`,model:`List models or switch with /model <id>`,setup:`Show onboarding progress (provider → login → model) with jump-to-next-step`,status:`Show session status`,inspect:`Open inspector (Events/Tools/Sources/Budget); /inspect sources|<point>|off`,replay:`Replay a session trace (/replay [<id>|off])`,delegates:`Toggle the Delegates pane (↑↓ select · k kill · o output · a apply). Aliases: /jobs /bg`,job:`Start a background agent job: /job <directive> (worktree-isolated, full tools incl. MCP). Code changes → a diff to apply; chores/research → a text result (view with o).`,extension:`Manage pluggable extensions (MCP / skills / agents): ↑↓ select · Enter toggle · Esc close`,compact:`Compact the conversation context now (summarize earlier messages to free up tokens)`,memory:`Project + user memory: /memory [user|project|<name>|forget <name>]; /memory user <text> saves a cross-project note (# writes project)`,login:`Authenticate a provider (OAuth or API key); /auth [<provider>]`,logout:`Remove stored credentials for a provider; /logout [<provider>]`,effort:`Switch reasoning effort (/effort low|medium|high|xhigh|max)`,preference:`Preferences: /preference [lang|theme]`,permissions:`View / clear the always-allow list (/permissions [clear])`,context:`Show context usage breakdown (system/tools/messages/cache/free bar)`,attach:"Attach to a session running on `otto serve`: /attach <sessionId> (read-only preview in this phase)",history:`Open input history search panel. Aliases: /hist`,prompts:`View prompt log (list of submitted prompts this session)`,notification:`Toggle the notification center panel (≡ Ctrl+N). Aliases: /notif`,pin:`Pin current session (sorts to top of /resume); batch/group: /pin [<session-id>...] [--group <name>]`,unpin:`Unpin current session`},pref:{permModeSwitched:`Permission mode → {{label}}`,languageUsage:`Usage: /preference lang <en|zh>`,languageName_zh:`中文`,languageName_other:`English`,permModeLabel_confirm:`Approve`,permModeLabel_auto:`Auto`,permModeLabel_bypass:`Autopilot`,permModeLabel:`{{context}}`,authModeLabel_oauth:`subscription`,authModeLabel_api_key:`API key`,authModeLabel_env:`API key`,authModeLabel:`{{context}}`,languageSwitched:`Language → {{name}} ({{l}})`},time:{justNow:`just now`,minAgo:`{{min}}m ago`,hourAgo:`{{hr}}h ago`,dayAgo:`{{day}}d ago`},paste:{confirmTitle:`Paste large text?`,collapseLabel:`Collapse to `,confirm:`Confirm`,cancel:`Cancel`,view:`View`,viewTitle:`Pasted content`,titlePasteExpired:`Paste expired`,expiredToast_one:`{{count}} pasted content reference expired — please paste again`,expiredToast_other:`{{count}} pasted content references expired — please paste again`,previewSummary_body:`─── Total {{lines}} {{lineWord}}, {{chars}} {{charWord}} ───`},select:{filterPlaceholder:`type to filter...`,noMatches:`no matches`,clearHint:`clear / `,matchCount_one:`{{count}} match`,matchCount_other:`{{count}} matches`},sigil:{filterPlaceholder:`type to filter...`,noMatches:`no matches`,searching:`searching…`,catAgent:`Agent`,catRecent:`Recently used`,catResource:`Custom resource`,catShortcut:`Shortcut`,catExtension:`Extension`,catPerson:`Member`,catHashtag:`Template`,catPlugin:`Plugin`,catFile:`File`,catModel:`Model`,loadingFile:`Loading file…`,readFullFile:`Read full file`,catSkill:`Skill`,titleMention:`Mention`,titleHashtag:`Hashtag`},toast:{editorError:`Editor error`},context:{tokensLabel:`{{formatted}} tokens`,title:`Context`,noData:`No context data yet — wait for the first API response.`,viewDetails:`Enter details`,systemHeading:`System context`,systemMeta:`{{tokens}}t · {{stable}} stable + {{volatile}} volatile`,laneVolatile:`volatile`,laneCache:`cache`,conversationHeading:`Conversation`,conversationMeta:`{{tokens}}t · {{turns}} turns`,earlierTurns:`{{count}} earlier turns ({{tokens}}t)`,turnRow:`turn #{{index}} · {{messages}} msg · {{tokens}}t`,totalLine:`Total {{used}} / {{window}} ({{percent}}%) · free {{free}}t`,tagPruned:`pruned`,tagCompacted:`compacted`,tagTruncated:`truncated`},transcript:{frozenNew:`new`,escToLive:`Esc back to latest`,you:`you`,assistant:`assistant`,loadingEarlier:`loading earlier history…`,emptyEarlier:`— no earlier messages — (PgUp/↑ scroll · Esc latest)`,findBar:`/{{query}} · {{count}}`},trust:{title:`Trust this folder?`,body:`Accessing workspace:
32
+ Fix: ① close the other otto process — this session will automatically become writable again on the next successful save; ② or exit this window and /resume a different session to continue working.`,restoredToastTitle:`Session write access restored`,restoredToastBody:`Changes will save normally from now on.`},pause:{titleRequested:`Waiting to pause`,bodyRequested:`Will pause once the current turn finishes`,titleActive:`Paused`,bodyActive:`Agent is paused — queued messages will not run`,btnCancel:`Cancel pause`,btnResume:`Resume`,footerDismiss:`Esc to dismiss overlay (pause request continues in background)`,footerActive:`Enter to accept · Esc to dismiss`,toolCount:`{{n}} tools · {{s}}s`,toolTotal:`Ran {{n}} tools this turn`},run:{messageFooter:`Type anything or /continue to resume`,resumedMessageBody:`Agent resumed`,pauseCancelledMessageBody:`Pause request cancelled — agent continues running`,messageBody:`Agent paused — queued messages will not run automatically`,messageBody_n:`Agent paused after {{n}} tools this turn — queued messages will not run automatically`},shell:{running:`running`,terminated:`terminated`,errored:`error`,exit:`exit {{code}}`,copyHint:`copy output`,copiedTitle:`Shell`,copiedBody:`Copied to clipboard`,hint:`ask AI`,exitCode:`exit code {{code}}`,askAiTerminated:`terminated by signal`,unknownError:`unknown error`,prompt:"The command `{{command}}` failed ({{errorLabel}}). Here is the output, please help diagnose:\n\n```\n{{output}}\n```",truncated:`...(truncated — press c to copy the full output to clipboard)`,viewAll_one:`view all output ({{count}} line total)`,viewAll_other:`view all output ({{count}} lines total)`,moreLines_one:`... {{count}} more line ...`,moreLines_other:`... {{count}} more lines ...`},spinner:{verbs:[`Working`,`Thinking`,`Crunching`,`Running`],outputPercent:`{{pct}}% of limit`,estimatedPercent:`~{{pct}}%`},bg:{runningVerb:`Running {{tool}}`,tasksTitle:`Delegates`,empty:`(no background tasks)`,noOutput:`(no output yet)`,live:`live`,following:`following…`,jobsLabel:`{{n}} delegates`,runningSuffix:`{{n}} running`,doneSuffix:`{{n}} done`,needInputSuffix:`{{n}} need input`,metaReady:`ready`,metaNeedsInput:`needs input`,agentStatusLabel:`{{st}}`,procStatusLabel:`{{s}}`,categoryLabel_job:`Jobs`,categoryLabel_bash:`Bash`,categoryLabel_other:`Sub-agents`,metaExited:`exited`,metaExited_code:`exited {{code}}`},subagent:{sTitle:`Subagents`,sRunning:`{{n}} running`,header:`Sub-agent @{{title}} · {{status}}`,contextEarlierLines:`↑ {{n}} lines earlier · ↵ for full scrollable transcript`,sWorking_one:`Subagent working ({{count}} subagent)`,sWorking_other:`Subagent working ({{count}} subagents)`},agent:{interruptTitle:`Interrupt agent?`,interruptMessage:`The current agent turn is still running. Interrupting will stop it and mark the turn as interrupted.`,interruptConfirm:`Interrupt`},queue:{label:`Queue`,empty:`No queued commands`,editTitle:`Edit queued item {{index}}/{{total}}`,editSendNowButton:`Send Now`,editConfirmButton:`Confirm`,editSendNowHintBusy:`Will be injected as a supplement to the current turn`,editSendNowHintIdle:`Will be sent immediately as a new message`,exitTitle:`Exit Queue Panel`,exitConfirm:`Clear and Exit`,exitMessage:`The panel has %d queued commands that will be cleared.`,popTitle:`Remove queued message?`,popMessage:`One follow-up message is queued. Remove the newest queued message instead of interrupting the running turn?`,popConfirm:`Remove queued message`,dFollowUpToast:`Model still running — queued as a follow-up, will send when it finishes`},retry:{reason:`{{reason}}`,defaultTitle:`Error details`,attempt:`Retry {{attempt}}/{{max}}`,countdown:`Retrying in {{s}}s…`,progressSep:` · `,nowButton:`Retry now`,hint:`↵/r`,stopButton:`Stop`,hintWithStop:`↵/r retry · Esc stop`},error:{typeLabel:`{{type}} limit reached`,retryNow:`Retry now`,switchModel:`Switch model`,title:`Request failed: {{reason}}`,defaultTitle:`Request failed`,exhaustedTitle:`Request failed after retries`,autoCountdown:`Attempt {{attempt}}/{{max}} · retrying in {{seconds}}s`,manualBody:`Attempt {{attempt}}/{{max}} · action required to retry`,exhaustedBody:`Retried {{max}} times, still failing`,resetsIn:`Quota resets in {{hms}}`,unknownReset:`Reset time unknown`,hint:`←/→ select · ↵ confirm · r retry now · Esc cancel`},pulse:{title:`How was this session?`,ratingGood:`Good`,ratingNeutral:`Neutral`,ratingBad:`Needs work`,commentTitle:`{{ratingLabel}} · Anything to add? (optional)`,commentPlaceholder:`Type your thoughts…`,hintRating:`←/→/Tab switch · ↵ select · Esc close`,hintComment:`↵ submit · Esc close (rating is saved either way)`},find:{inputLabel:`Find:`,matchCount:`{{current}}/{{total}}`,tabPrompt:`Prompt`,tabConversation:`Conversation`,tabDiff:`Diff`,tabDiagnostics:`Diagnostics`,searchNoMatches:`no matches`},schedule:{sLabel:`Schedules`,sEmpty:`No scheduled tasks. Create one with /schedule add`,oneShot:`one-shot`,next:`next: `,panel:{noTasks:`No scheduled tasks.`,pressToAdd:`Press {{key}} to create your first schedule.`,examples:`Examples: {{c1}} daily at 09:00 · {{c2}} every 30 minutes`,running:`running`,failedCanceled:`failed/canceled`,readonlyNet:`{{cross}} network error — cannot reach schedule service`,readonlyLease:`{{cross}} read-only — another terminal holds the fire-ownership lease`,moreAbove:`... {{n}} more above`,moreBelow:`... {{n}} more below`,failedErr:`(failed: {{err}})`,detail:{id:`ID`,status:`Status`,type:`Type`,cron:`Cron`,prompt:`Prompt`,nextFire:`Next fire`,lastFire:`Last fire`,never:`never`,jobRunning:`{{cross}} job running — {{id}}`,recent:`Recent (last {{n}})`,loadingLogs:`Loading logs...`,noLogs:`No logs yet`},logsTitle:`Logs: {{id}}`,form:{newTitle:`New Schedule`,editTitle:`Edit: {{id}}`,name:`Name`,cron:`Cron`,type:`Type`,status:`Status`,prompt:`Prompt`,preview:`Preview`,auto:`(auto)`,cronPlaceholder:`________________`,recurring:`recurring`,enabled:`enabled`,disabled:`disabled`,toggleHint:`(←/→ to toggle)`,templatesHint:`press ←/→ for templates`,templates:`templates`,previewNext:`Next fire: {{time}}`,previewJitter:`Next fire: {{time}} + 0-30min jitter`,previewJitterOnce:`Next fire: {{time}} + ~90s jitter`,previewCron:`cron: {{cron}} (recurring)`,previewCronOnce:`cron: {{cron}} (one-shot)`,previewEmpty:`enter a valid cron expression`,invalidCron:`invalid cron`,required:`Cron and prompt are required`,saving:`Saving...`,createFailed:`Failed to create`,saveFailed:`Failed to save`},confirmCancelTitle:`Cancel job?`,confirmCancelBody:`This will cancel the currently running job of {{name}}.`,confirmCancelNote:`The schedule definition will not be affected.`,confirmRemoveTitle:`Remove schedule?`,confirmRemoveBody:`This will permanently delete {{name}} ({{id}}).`,confirmRemoveWarn:`This action cannot be undone.`}},draft:{sLabel:`Drafts`,sEmpty:`No drafts. Save one with Ctrl+S`,saved:`Saved to drafts`,saveEmpty:`Nothing to save — input is empty`},prompts:{label:`Prompts`,empty:`No prompts yet`},service:{sTitle:`Services`,sEmpty:`(no running services detected)`,countLabel_one:`svc`,countLabel_other:`svcs`},scroll:{above:`↑ {{n}} lines above`,below:`↓ {{n}} lines below`,viewportLinesAbove:`lines above`,viewportLinesBelow:`lines below`},insp:{live:`live · {{n}} rows`,row:`row {{cur}}/{{total}}`,replay:`replay`,paused:`⏸ paused`,pausedBig:`⏸ PAUSED`,inspect:`inspect`,hintPause:`c continue · s step · n next · o step-out · x stop`,hintFocus:`Ctrl+G to focus`,hintBp:`↑↓ select · Tab switch · space toggle · Esc exit`,bpIdle:`▶ ⤼ ⤓ ⤴ ⏹ idle — run a prompt to pause at an enabled breakpoint`,variablesIdle:`Variables appear when paused — enable a point in Sources, then run`,breakpoints:`BREAKPOINTS`,noneInteractive:`— none (need interactive inspector) —`,noTools:`— no tool calls yet —`,noEvents:`— no trace events yet (run a prompt) —`,noUsage:`— no usage yet (run a prompt) —`,noLineage:`— no lineage —`,toolbar:`▶ continue(c) ⤼ over(n) ⤓ step(s) ⤴ out(o) ⏹ stop(x)`,variables:`VARIABLES`,editKeys:` Enter=save Esc=cancel`,injectMsg:`inject msg`,changeData:`change data: t think · [ ]temp · i inject · e sys`,budgetOverhead:`overhead`,budgetMessages:`messages`,budgetFree:`free`,budgetLastTotal:`last {{lastIn}}→{{lastOut}} · total {{totalIn}}→{{totalOut}}`,liveTag:`▸ live`,userPrefix:`user: `,thinkingFull:`thinking (full):`,toolRunning:`{{tool}} (running)`,toolCall:`{{tool}} (call)`,assistantFallback:`assistant text`,emptyPrompt:`(prompt)`,endTurn:`· end_turn`,treeThinking:`thinking ⟨{{n}} · {{chars}} chars⟩`,bpCatAgentWorkLoop:`Agent Work Loop`,bpCatWorkLoopInjection:`Work-loop Injection`,bpCatToolExecutor:`Tool Executor`,bpCatSessionPrompt:`Session Prompt Lifecycle`,bpCatLifecycleHook:`Lifecycle Hook`,bpCatTurnObservable:`Turn Observable`,bpCatCustom:`Custom`,debugCall:`Call`,debugLlmParams:`LLM Params`,debugSystemPrompt:`System Prompt`,debugMessages:`Messages ({{n}})`,debugTokens:`Tokens in {{inTokens}} · out {{outTokens}}`,debugEmpty:`(empty)`,debugEditsPending:`edits: {{parts}} (apply on resume)`,debugEditSysPrompt:`system prompt`,asstPrefix:`asst: `,thinkingPrefix:`thinking… `,noTurnData:`No turn data available.`,treeAssistantDeltas_one:`assistant ⟨{{count}} delta · {{chars}} chars⟩`,treeAssistantDeltas_other:`assistant ⟨{{count}} deltas · {{chars}} chars⟩`,hintTree:`↑↓ move · Tab switch · w why{{whySeg}} · z expand{{expandSeg}} · space fold · Esc exit`},budget:{exhaustedTitle:`Hit this turn’s tool-step budget — the task may be unfinished. Keep going?`,continue:`Keep going`,stop:`Stop`,stoppedNote:`⏸ Stopped at the tool-step budget — the task may be unfinished. Just keep instructing me to continue (each prompt resets this turn’s tool budget).`,tokensLabel_one:`{{count}} token`,tokensLabel_other:`{{count}} tokens`,tokenBudgetLabel:`{{used}}/{{budget}} tok`},cmdDesc:{help:`Show available commands`,exit:`Exit the TUI; /exit --restart to restart into the same session`,clear:`Clear screen and reset session`,abort:`Abort the current agent run`,copy:`Copy last assistant response`,model:`List models or switch with /model <id>`,setup:`Show onboarding progress (provider → login → model) with jump-to-next-step`,status:`Show session status`,inspect:`Open inspector (Events/Tools/Sources/Budget); /inspect sources|<point>|off`,replay:`Replay a session trace (/replay [<id>|off])`,delegates:`Toggle the Delegates pane (↑↓ select · k kill · o output · a apply). Aliases: /jobs /bg`,job:`Start a background agent job: /job <directive> (worktree-isolated, full tools incl. MCP). Code changes → a diff to apply; chores/research → a text result (view with o).`,extension:`Manage pluggable extensions (MCP / skills / agents): ↑↓ select · Enter toggle · Esc close`,compact:`Compact the conversation context now (summarize earlier messages to free up tokens)`,memory:`Project + user memory: /memory [user|project|<name>|forget <name>]; /memory user <text> saves a cross-project note (# writes project)`,login:`Authenticate a provider (OAuth or API key); /auth [<provider>]`,logout:`Remove stored credentials for a provider; /logout [<provider>]`,effort:`Switch reasoning effort (/effort low|medium|high|xhigh|max)`,preference:`Preferences: /preference [lang|theme]`,permissions:`View / clear the always-allow list (/permissions [clear])`,context:`Show context usage breakdown (system/tools/messages/cache/free bar)`,history:`Open input history search panel. Aliases: /hist`,prompts:`View prompt log (list of submitted prompts this session)`,notification:`Toggle the notification center panel (≡ Ctrl+N). Aliases: /notif`,pin:`Pin current session (sorts to top of /resume); batch/group: /pin [<session-id>...] [--group <name>]`,unpin:`Unpin current session`},pref:{permModeSwitched:`Permission mode → {{label}}`,languageUsage:`Usage: /preference lang <en|zh>`,languageName_zh:`中文`,languageName_other:`English`,permModeLabel_confirm:`Approve`,permModeLabel_auto:`Auto`,permModeLabel_bypass:`Autopilot`,permModeLabel:`{{context}}`,authModeLabel_oauth:`subscription`,authModeLabel_api_key:`API key`,authModeLabel_env:`API key`,authModeLabel:`{{context}}`,languageSwitched:`Language → {{name}} ({{l}})`},time:{justNow:`just now`,minAgo:`{{min}}m ago`,hourAgo:`{{hr}}h ago`,dayAgo:`{{day}}d ago`},paste:{confirmTitle:`Paste large text?`,collapseLabel:`Collapse to `,confirm:`Confirm`,cancel:`Cancel`,view:`View`,viewTitle:`Pasted content`,titlePasteExpired:`Paste expired`,expiredToast_one:`{{count}} pasted content reference expired — please paste again`,expiredToast_other:`{{count}} pasted content references expired — please paste again`,previewSummary_body:`─── Total {{lines}} {{lineWord}}, {{chars}} {{charWord}} ───`},select:{filterPlaceholder:`type to filter...`,noMatches:`no matches`,clearHint:`clear / `,matchCount_one:`{{count}} match`,matchCount_other:`{{count}} matches`},sigil:{filterPlaceholder:`type to filter...`,noMatches:`no matches`,searching:`searching…`,catAgent:`Agent`,catRecent:`Recently used`,catResource:`Custom resource`,catShortcut:`Shortcut`,catExtension:`Extension`,catPerson:`Member`,catHashtag:`Template`,catPlugin:`Plugin`,catFile:`File`,catModel:`Model`,loadingFile:`Loading file…`,readFullFile:`Read full file`,catSkill:`Skill`,titleMention:`Mention`,titleHashtag:`Hashtag`},toast:{editorError:`Editor error`},context:{tokensLabel:`{{formatted}} tokens`,title:`Context`,noData:`No context data yet — wait for the first API response.`,viewDetails:`Enter details`,systemHeading:`System context`,systemMeta:`{{tokens}}t · {{stable}} stable + {{volatile}} volatile`,laneVolatile:`volatile`,laneCache:`cache`,conversationHeading:`Conversation`,conversationMeta:`{{tokens}}t · {{turns}} turns`,earlierTurns:`{{count}} earlier turns ({{tokens}}t)`,turnRow:`turn #{{index}} · {{messages}} msg · {{tokens}}t`,totalLine:`Total {{used}} / {{window}} ({{percent}}%) · free {{free}}t`,tagPruned:`pruned`,tagCompacted:`compacted`,tagTruncated:`truncated`},transcript:{frozenNew:`new`,escToLive:`Esc back to latest`,you:`you`,assistant:`assistant`,loadingEarlier:`loading earlier history…`,emptyEarlier:`— no earlier messages — (PgUp/↑ scroll · Esc latest)`,findBar:`/{{query}} · {{count}}`},trust:{title:`Trust this folder?`,body:`Accessing workspace:
33
33
  {{path}}
34
34
 
35
35
  Is this a project you created or trust (your own code, a well-known
@@ -62,15 +62,15 @@ A crash report has been recorded.`,stepNameProvider:`Provider`,stepNameLogin:`Lo
62
62
  {{joined}}`,bgJobIncomplete:`✗ 应用作业 {{id}} 未完成({{status}}):{{message}}{{conflicts}}`,bgAutoReloadFailed:`自动热重载失败(可手动 /reload):{{msg}}`,modelCompactedFor:`已为 {{window}} 窗口压缩上下文`,grillRecommendation:`
63
63
  推荐:{{rec}}`,grillEvidence:`
64
64
  证据:
65
- {{joined}}`,grillFreeformPlaceholder:`输入你自己的选项 / 补充信息…`,grillAnswerPlaceholder:`输入你的回答…`,titleBackgroundTask:`后台任务`,lifecycleCrossBoundaryDone:`"{{toolName}}" 已完成(在上一个任务中启动——结果未加入本次对话)`,lifecycleCrossBoundaryFailed:`"{{toolName}}" 执行失败(在上一个任务中启动——结果未加入本次对话)`,titleFeedback:`反馈`,feedbackStepTitle:`问题简短标题`,feedbackStepRepro:`复现步骤(可选)`,feedbackStepExpected:`期望行为(可选)`,feedbackStepActual:`实际行为(可选)`,feedbackConfirmTitle:`提交反馈?`,feedbackConfirmMessage:`标题:{{title}}
65
+ {{joined}}`,grillFreeformPlaceholder:`输入你自己的选项 / 补充信息…`,grillAnswerPlaceholder:`输入你的回答…`,grillOptionYes:`是`,grillOptionNo:`否`,titleBackgroundTask:`后台任务`,lifecycleCrossBoundaryDone:`"{{toolName}}" 已完成(在上一个任务中启动——结果未加入本次对话)`,lifecycleCrossBoundaryFailed:`"{{toolName}}" 执行失败(在上一个任务中启动——结果未加入本次对话)`,titleFeedback:`反馈`,feedbackStepTitle:`问题简短标题`,feedbackStepRepro:`复现步骤(可选)`,feedbackStepExpected:`期望行为(可选)`,feedbackStepActual:`实际行为(可选)`,feedbackConfirmTitle:`提交反馈?`,feedbackConfirmMessage:`标题:{{title}}
66
66
 
67
67
  {{bodyPreview}}`,feedbackChannelSubmitting:`提交中…`,feedbackRepoUnresolved:`无法解析目标仓库——请在 .otto/config.json 中配置 "feedback_repo"`,feedbackCreated:`已打开:{{url}}`,feedbackUnavailable:`Feedback 插件不可用(已禁用或未安装)`,compatTrusted_other:`已信任 · MCP 工具 {{count}}`,resumeProbeHiddenHint_other:`(另有 {{count}} 个探针会话未显示,用 /resume --all 查看)`,resumeArchivedHiddenHint_other:`(另有 {{count}} 个已归档会话未显示,用 /resume --archived 查看)`,memoryDialogProjGroup_other:`项目记忆 (.otto/memory) · {{count}} 条`,memoryDialogUserGroup_other:`用户记忆 (~/.otto/memory) · {{count}} 条`,pluginTrusted_other:`已信任 {{id}} · MCP 工具 {{count}}`,resumeRestored_other:`↻ 已恢复会话 {{idShort}}({{count}} 条历史对话进上下文,本轮起接着聊)`,"imageDegradationNotice_image-constraint_other":`已丢弃 {{count}} 张较旧图片(超出供应商图片数量限制)`,imageDegradationNotice_other_other:`已丢弃 {{count}} 张较旧图片以适配上下文窗口`,promptBudgetExceeded_tokens:`输出 token 预算超额({{used}}/{{budget}})——已请求模型收尾`,promptBudgetExceeded_other:`时间预算超额({{used}}/{{budget}})——已请求模型收尾`,sessionCostBudgetExceeded:"会话成本超出预算(${{used}}/${{budget}})——不阻断,详情见 /cost",memoryPressureMessage:`otto 内存占用过高(已达堆上限的 {{usedPct}}%)。立即重启可保存当前全部进度并安全续接,避免不可预期的崩溃。`,authFailed:`认证失败——当前模型{{ps}}的 API Key 无效或已过期。输入 /auth{{ls}} 重新配置凭证后再重试。`,authRefreshFailed:`登录态刷新失败{{ps}}——可能是网络问题或多进程同时登录刷新冲突,请稍后重试;若持续失败请 /auth{{ls}} 重新认证。`,extToggled:`{{verb}} {{name}}{{seg}}`,pluginUsage:`用法:/trust plugin {{seg}}<id>`,installedTo:`{{name}} 已安装到{{scope}}{{seg}}`,statusLineOccupancy:`上下文占用:{{occ}} / {{window}}{{seg}}`,extPluginTitle:`{{name}} — {{state}} · 选操作 · Esc 关`,extSkillTitle:`{{name}} — {{state}} · 选操作 · Esc 关`,extAgentTitle:`{{name}} — {{state}} · 选操作 · Esc 关`,bpToggled:`{{point}} {{state}}`,pluginInstalled:`{{seg}}`,pinBatchSummary:`{{seg}}`,extSkillSourceLabel:`{{seg}}`,upgradeAvailableLines:[`当前版本: v{{current}}`,`最新版本: v{{latest}}`,``,`热升级流程:npm install -g @x-otto/cli@latest → 自动重启`,``,`⚠ 升级期间当前会话将中断。`,`输入 /upgrade --force 确认升级。`],extHealthSummary:`健康度 挂起 {{hookTimeouts}} 次 · 工具超时 {{toolTimeouts}} 次`,extHealthSummary_err:`健康度 挂起 {{hookTimeouts}} 次 · 工具超时 {{toolTimeouts}} 次 · 最近错误 {{lastError}}`,keybindTitle:`快捷键`,keybindSavedRestartHint:`已保存。新键位需重启会话后生效。`},permission:{allowTool:`允许工具:`,bashCommand:`Bash 命令`,approve:`批准`,deny:`拒绝`,alwaysAllow:`始终允许`,riskLabel_low:`低风险`,riskLabel_medium:`中风险`,riskLabel_high:`高风险`},hint:{select:`选择`,confirm:`确认`,execute:`执行`,cancel:`取消`,delOne:`删一条`,choose:`选定`,option:`选项`,question:`问题`,shortcut:`快捷`,toInterrupt:`中断`,pausedContinue:`输入继续或 /continue`,steer:`引导`,queue:`排队`,history:`历史`,autosuggestAccept:`接受建议`,autosuggestMenu:`补全菜单`,submit:`提交`,kill:`终止`,output:`输出`,apply:`应用`,switch:`切换`,delete:`删除`,close:`关闭`,collapse:`收起`,retry:`重试`,view:`查看`,load:`加载`,check:`勾选`,grab:`抓取`,drop:`放下`,move:`移动位置`,edit:`编辑`,exit:`退出`,dismiss:`消除`,quick:`快捷`,refresh:`刷新`,subagents:`子代理`,tasks:`任务`,viewDetail:`↵ 查看详情`,back:`返回`,scroll:`滚动`,find:`查找`,tabSwitchOutput:`切换视图`,tabFocus:`切换面板`,tabZone:`切换区域`,toggle:`开/关`,add:`添加`,run:`运行`,runNow:`立即运行`,detail:`详情`,logs:`日志`,switchField:`切换字段`,discard:`放弃`,confirmCancel:`确认取消`,confirmRemove:`确认删除`,abort:`取消`},history:{label:`历史`,capped_other:`最早的 {{count}} 条消息已从内存视图中移除(会话消息已达条数上限,存储中仍完整保留)`,cappedBytes_other:`最早的 {{count}} 条消息已从内存视图中移除(会话消息内存驻留超出字节预算,存储中仍完整保留)`,cappedMemoryPressure_other:`最早的 {{count}} 条消息已从内存视图中移除(内存压力收紧会话驻留,存储中仍完整保留)`,cappedLossy_other:`⚠ 最早的 {{count}} 条消息已从模型上下文中移除,且**未能生成摘要**——这部分内容模型将不再可见(自动压缩连续失败后的兜底裁剪)。原始记录仍完整保留在存储中,可用 /history 回看。`},common:{more:`更多`,disabled:`不可用`,wordOr:`或`,moreLinesLabel:`… 还有 {{n}} 行`,thoughtLines:`思考({{n}} 行)`,noContentAvailable:`(无内容)`,contentUnavailable:`(内容不可用——会话已恢复,原始文件内容未持久化)`,cancelButton:`取消`,upgradeButton:`升级`,escClose:`Esc 关闭`,noMatches:`无匹配`,confirmButton:`确认`,genericCancelButton:`取消`,dontRemind:`不再提醒`,okButton:`确定`,abortButton:`中止`,pauseButton:`暂停`,abortAndExitButton:`终止并退出`,abortAndRestartButton:`终止并重启`},model:{noneAvailable:`当前没有可用模型 — 请先`,goLogin:`登录`,setKey:`配置凭证`,pendingCapabilities:`{{count}} 个 provider 插件待授权`,goGrantCapability:`去授权`,noProviderPlugin:`当前没有可用的模型。安装 provider 插件后开始使用。`,goInstallPlugin:`安装 provider 插件`,switchedTo:`已切换到 {{label}}`,title:`配置的模型不可用`,reasonNotFound:`原因:未找到该模型 id(可能已下线或拼写有误)`,reasonUnauthenticated:`原因:{{provider}} 尚未认证`,hint:`/auth 认证该 provider · /model 切换`,permanent:`切换到此模型`,login:`去登录`,dismiss:`退出`,goToLoginButton:`去登录`,goToExtensionButton:`去授权`,forcedUpgradeTitle:`强制升级`,noRegistry:`无可用的模型注册表。`,notFound:`未找到模型: {{name}}。用 /model 列出可用模型。`,listFooter:` /model <id> 切换。* = 当前`,visionDelegateToast_other:`{{count}} 张图已由 vision 模型代述(当前模型不支持视觉输入)`,fallbackLoginToast:`去登录提供者 {{provider}}…`},welcome:{providerDesc:{"anthropic-provider":`Anthropic Claude,OAuth 登录(推荐)`,"deepseek-provider":`DeepSeek,需 DEEPSEEK_API_KEY`,"openai-codex-provider":`OpenAI Codex,需凭据`},version:`版本`,workspace:`工作目录`,extensions:`扩展`,msgCountLabel_other:`{{count}} 条消息`,itemCountLabel_other:`{{count}} 项`,greeting_late:`夜深了{{who}},周{{wday}}——万籁俱寂,正好深思。`,greeting_earlyMorning:`早安{{who}}!周{{wday}}清晨——新灵感正等着你。`,greeting_morning:`周{{wday}}上午好{{who}}——一起创造些了不起的东西吧。`,greeting_afternoon:`周{{wday}}下午好{{who}}——保持势头,继续推进。`,greeting_evening:`周{{wday}}晚上好{{who}}——收尾复盘的好时光。`,greeting_night:`深夜了{{who}},周{{wday}}——最好的灵感往往在夜深人静时迸发。`,tipLabel:`OTTO 小贴士`,shadowBadge:`影子`,shadowChip:`影子模式 — 不写入磁盘`,shadowBannerTitle:`影子会话 — 零磁盘落痕`,shadowGuarantee:`保证:otto 自有状态(凭据、会话、记忆、教训、配置、trace、日志)本次会话只在内存中,不写入磁盘。`,shadowNotGuaranteedTitle:`不保证(仍可能留痕):`,shadowNg1:`你让 otto 用 write/edit 工具改的项目文件(你的意图产物)`,shadowNg2:`shell 命令、git、MCP server、第三方插件的自主写盘`,shadowNg3:`provider 服务端的日志、遥测与账单记录`,shadowNg4:`OS 层痕迹:你的 shell 历史、进程列表、网络连接`},onboarding:{title:`开始使用`,nameQuestion:`怎么称呼你?`,langQuestion:`选择语言`,namePlaceholder:`例如:小明`,nameDesc:`昵称用于会话和通知中的个性化称呼。`,langFootnote:`之后可用 /preference lang 切换。`,langOptions:{en:`English (en)`,zh:`中文 (zh)`,auto:`跟随系统自动检测`},skip:`跳过`,done:`完成`,stepName:`昵称`,stepLang:`语言`,stepTheme:`主题`,stepCounter:`第 {{current}}/{{total}} 步`,langAuto:`跟随系统`,themeQuestion:`配色主题`,themeFootnote:`移动高亮即实时预览;跟随终端会探测你的终端背景色`,themeDark:`深色`,themeLight:`浅色`,themeSystem:`跟随终端`,hintNext:`下一步`,hintDone:`完成`,hintSkip:`跳过`,hintBack:`上一步`,hintQuick:`直选`},prompt:{ready:`就绪`,streaming:`生成中`,default:`输入消息,或 /help 查看命令…`,working:`Agent 处理中 — 输入引导当前回合…`,setup:`尚未配置完成——输入 /setup 从上次的进度继续`,fallback:`输入消息…`,unfocused:`输入保留中,随时继续…`,submit:`提交`,readySuffix:`{{n}} 个就绪`,upgradeRequired:`需要更新 — 输入 /upgrade 继续`,submitButton:`提交`,defaultTitle:`输入`,reviewingPlaceholder:`回看中 · Esc 回最新`},questions:{readyToSubmit:`可以提交答案了。`,someUnanswered:`还有问题未作答 — 仍要提交?`},freeform:{tab:`补充`,filled:`*`,empty:`-`,label:`输入补充说明(可选):`,placeholder:`在此输入补充信息…`,advance:`完成(前进至提交)`},panelTitle:{memory:`memory`,editedFilesTitle:`已编辑文件`},inspText:{thinking:`思考`,thinkingLabel:`思考中…`},update:{forcedBanner:`⚡ 强制升级至 v{{latest}} — 输入 /upgrade 现在升级`,availableBanner:`🆕 v{{latest}} 可用 — 输入 /upgrade 查看详情`},status:{failed:`失败`,interrupted:`已中断`,done:`完成`,stopped:`暂停`},task:{leftLabel:`{{done}}/{{total}} · 剩 {{left}} 项`,title:`任务`,collapsedHint:`已折叠`,detailTitle:`任务详情`,turnInfo:`(回合 #{{turn}}, {{shown}}/{{total}} 条消息)`,turnTag:`(回合 #{{turn}})`,truncated:`… 还有 {{n}} 条消息已截断`,statusLabel_pending:`待办`,statusLabel_in_progress:`进行中`,statusLabel_done:`完成`,statusLabel_skipped:`已跳过`,statusLabel_failed:`失败`},tool:{edit:`编辑`,write:`写入`,read:`读取`,tasks:`任务`,subagent:`子代理`,unknown:`未知`,fallback:`工具`,compact:`压缩`,prune:`裁剪`,history:`历史`,session:`会话`,run:`运行`,model:`模型`,effort:`投入档`,budgetLabel:`{{used}}/{{max}} 工具`,countLabel_other:`{{count}} 个工具`,chainSummary_other:`[{{count}} 个工具: {{names}}]`},diff:{modeLabel:`对比 HEAD`,loading:`整个文件 diff 加载中…`,error:`整个文件 diff 不可用:{{message}}`,linesTotalLabel_other:`{{count}} 行`,fileCountLabel_other:`{{count}} 个文件`,fileOpLabel_edit:`已修改`,fileOpLabel_write:`已创建`,fileOpLabel_other:`已删除`},compact:{ed:`更早的消息已压缩`,pruned:`工具输出已裁剪以适应上下文`,ing:`正在压缩上下文…`,edResult:`✓ 上下文已压缩:{{before}} → {{after}} 条消息(完整转录已保留)`,noop:`无需压缩——当前上下文已经很小。`,unavailable:`压缩不可用:当前会话未启用记忆/压缩。`,logTitle:`压缩/裁剪日志`,logEmpty:`本会话暂无压缩或裁剪事件。`,logCompactRow:`{{before}} → {{after}}(保留 {{pct}}%)`,logDetailTitle:`{{kind}} · {{time}}`,logNoSummary:`该事件无可用摘要。`,logViewSummary:`查看摘要`,ingVerb:`压缩中`,logHistoryCappedRow_other:`{{count}} 条消息已从内存移除(存储中仍保留)`,ionStageLabel_analyze:`分析上下文中`,ionStageLabel_summarize:`生成摘要中`,ionStageLabel_finalize:`整理结果中`,logPruneRow:`节省约 {{tokensSaved}} tokens`,logPruneRow_pruned_other:`节省约 {{tokensSaved}} tokens({{count}} 条工具输出)`},lease:{denied:`本轮改动未保存——另一 otto 进程持有此会话写权`,restored:`写权已恢复,此后改动正常保存`,deniedToastTitle:`会话只读(改动不会保存)`,deniedToastBody:`原因:另一个 otto 进程正在写这个会话(如另一个终端窗口,或 /exit -r 重启未完全交接)。
68
68
  本窗口仍可正常对话,但改动不会保存。
69
- 解决:① 关闭另一个 otto 进程后,本会话会在下次保存成功时自动恢复可写;② 或退出本窗口,/resume 换一个会话继续工作。`,restoredToastTitle:`会话已恢复可写`,restoredToastBody:`此后的改动会正常保存。`},pause:{titleRequested:`等待暂停`,bodyRequested:`将在当前回合结束后自动暂停`,titleActive:`已暂停`,bodyActive:`Agent 运行已暂停,排队消息不会自动执行`,btnCancel:`取消暂停`,btnResume:`继续运行`,footerDismiss:`Esc 关闭浮层,暂停请求仍在后台生效`,footerActive:`Enter 接受 · Esc 关闭`,toolCount:`{{n}} 工具 · {{s}}s`,toolTotal:`本回合执行了 {{n}} 个工具`},run:{messageFooter:`输入任意消息或 /continue 继续`,resumedMessageBody:`Agent 已恢复运行`,pauseCancelledMessageBody:`暂停请求已取消,Agent 继续运行`,messageBody:`Agent 运行已暂停,排队消息不会自动执行`,messageBody_n:`Agent 运行已暂停(本回合 {{n}} 个工具),排队消息不会自动执行`},shell:{running:`运行中`,terminated:`已终止`,errored:`错误`,exit:`退出码 {{code}}`,copyHint:`复制输出`,copiedTitle:`Shell`,copiedBody:`已复制到剪贴板`,hint:`问 AI`,exitCode:`退出码 {{code}}`,askAiTerminated:`被信号终止`,unknownError:`未知错误`,prompt:"命令 `{{command}}` 执行失败({{errorLabel}}),输出如下,请帮忙排查:\n\n```\n{{output}}\n```",truncated:`...(已截断,完整输出请用 c 键复制到剪贴板查看)`,viewAll_other:`查看全部输出(共 {{count}} 行)`,moreLines_other:`... 还有 {{count}} 行 ...`},spinner:{verbs:[`处理中`,`思考中`,`计算中`,`运行中`],outputPercent:`{{pct}}% 上限`,estimatedPercent:`~{{pct}}%`},bg:{runningVerb:`运行 {{tool}}`,tasksTitle:`委派`,empty:`(无后台任务)`,noOutput:`(暂无输出)`,live:`实时`,following:`跟随中…`,jobsLabel:`{{n}} 个委派`,runningSuffix:`{{n}} 个运行中`,doneSuffix:`{{n}} 个完成`,needInputSuffix:`{{n}} 个待输入`,metaReady:`就绪`,metaNeedsInput:`待输入`,agentStatusLabel:`{{st}}`,procStatusLabel:`{{s}}`,categoryLabel_job:`委派作业`,categoryLabel_bash:`Bash 命令`,categoryLabel_other:`子代理`,metaExited:`已退出`,metaExited_code:`已退出 {{code}}`},subagent:{sTitle:`子代理`,sRunning:`{{n}} 个运行中`,header:`子代理 @{{title}} · {{status}}`,contextEarlierLines:`↑ {{n}} 行更早 · ↵ 看完整可滚动转录`,sWorking_other:`子代理运行中({{count}} 个子代理)`},agent:{interruptTitle:`中断 agent?`,interruptMessage:`当前 agent 回合仍在运行。确认中断会停止本轮并标记为已中断。`,interruptConfirm:`中断`},queue:{label:`队列`,empty:`队列为空`,editTitle:`编辑队列项 {{index}}/{{total}}`,editSendNowButton:`直接发送`,editConfirmButton:`确定`,editSendNowHintBusy:`将作为补充说明注入当前回合`,editSendNowHintIdle:`将立即发送为新消息`,exitTitle:`退出排队命令面板`,exitConfirm:`清除并退出`,exitMessage:`面板中有 %d 条排队命令将被清除。`,popTitle:`移除排队消息?`,popMessage:`当前有一条追问消息排队中。是否移除最新排队消息,而不是中断正在运行的回合?`,popConfirm:`移除排队消息`,dFollowUpToast:`模型还在跑——已加入追问队列,完成后自动发送`},retry:{reason:`{{reason}}`,defaultTitle:`错误详情`,attempt:`重试 {{attempt}}/{{max}}`,countdown:`{{s}} 秒后重试…`,progressSep:`,`,nowButton:`立即重试`,hint:`↵/r`,stopButton:`停止`,hintWithStop:`↵/r 重试 · Esc 停止`},error:{typeLabel:`{{type}} 限额已达上限`,retryNow:`立即重试`,switchModel:`切换模型`,title:`请求失败:{{reason}}`,defaultTitle:`请求失败`,exhaustedTitle:`多次重试后仍失败`,autoCountdown:`第 {{attempt}}/{{max}} 次重试,{{seconds}} 秒后自动重试`,manualBody:`第 {{attempt}}/{{max}} 次重试,需先完成操作才能重试`,exhaustedBody:`已重试 {{max}} 次仍失败`,resetsIn:`配额将在 {{hms}} 后重置`,unknownReset:`重置时间未知`,hint:`←/→ 选择 · ↵ 确认 · r 立即重试 · Esc 取消`},pulse:{title:`这次体验如何?`,ratingGood:`好评`,ratingNeutral:`一般`,ratingBad:`待改进`,commentTitle:`{{ratingLabel}} · 想补充点什么吗?(可选)`,commentPlaceholder:`说点什么…`,hintRating:`←/→/Tab 切换 · ↵ 选择 · Esc 关闭`,hintComment:`↵ 提交 · Esc 关闭(评分仍会保存)`},find:{inputLabel:`查找:`,matchCount:`{{current}}/{{total}}`,tabPrompt:`提示词`,tabConversation:`对话`,tabDiff:`Diff`,tabDiagnostics:`诊断`,searchNoMatches:`无匹配`},schedule:{sLabel:`定时任务`,sEmpty:`暂无定时任务。用 /schedule add 创建`,oneShot:`单次`,next:`下次: `,panel:{noTasks:`暂无定时任务。`,pressToAdd:`按 {{key}} 创建第一个定时任务。`,examples:`示例: {{c1}} 每天 09:00 · {{c2}} 每 30 分钟`,running:`运行中`,failedCanceled:`失败/已取消`,readonlyNet:`{{cross}} 网络错误 — 无法连接调度服务`,readonlyLease:`{{cross}} 只读 — 另一个终端持有 fire-ownership 租约`,moreAbove:`... 上方 {{n}} 条`,moreBelow:`... 下方 {{n}} 条`,failedErr:`(失败: {{err}})`,detail:{id:`ID`,status:`状态`,type:`类型`,cron:`Cron`,prompt:`提示词`,nextFire:`下次触发`,lastFire:`上次触发`,never:`从未`,jobRunning:`{{cross}} 任务运行中 — {{id}}`,recent:`最近 ({{n}} 条)`,loadingLogs:`加载日志...`,noLogs:`暂无日志`},logsTitle:`日志: {{id}}`,form:{newTitle:`新建定时任务`,editTitle:`编辑: {{id}}`,name:`名称`,cron:`Cron`,type:`类型`,status:`状态`,prompt:`提示词`,preview:`预览`,auto:`(自动)`,cronPlaceholder:`________________`,recurring:`循环`,enabled:`已启用`,disabled:`已禁用`,toggleHint:`(←/→ 切换)`,templatesHint:`按 ←/→ 选择模板`,templates:`模板`,previewNext:`下次触发: {{time}}`,previewJitter:`下次触发: {{time}} + 0-30分钟抖动`,previewJitterOnce:`下次触发: {{time}} + ~90秒抖动`,previewCron:`cron: {{cron}} (循环)`,previewCronOnce:`cron: {{cron}} (单次)`,previewEmpty:`输入有效的 cron 表达式`,invalidCron:`无效 cron`,required:`Cron 和提示词为必填项`,saving:`保存中...`,createFailed:`创建失败`,saveFailed:`保存失败`},confirmCancelTitle:`取消任务?`,confirmCancelBody:`这将取消 {{name}} 当前正在运行的任务。`,confirmCancelNote:`定时任务定义不受影响。`,confirmRemoveTitle:`删除定时任务?`,confirmRemoveBody:`这将永久删除 {{name}} ({{id}})。`,confirmRemoveWarn:`此操作不可撤销。`}},draft:{sLabel:`草稿`,sEmpty:`暂无草稿。用 Ctrl+S 保存一条`,saved:`已保存到草稿`,saveEmpty:`输入为空,无内容可保存`},prompts:{label:`Prompt 记录`,empty:`暂无 Prompt 记录`},scroll:{above:`↑ 上方 {{n}} 行`,below:`↓ 下方 {{n}} 行`,viewportLinesAbove:`上方行`,viewportLinesBelow:`下方行`},service:{sTitle:`服务`,sEmpty:`(无运行中的服务)`,countLabel_other:`服务`},insp:{live:`实时 · {{n}} 行`,row:`第 {{cur}}/{{total}} 行`,replay:`回放`,paused:`⏸ 已暂停`,pausedBig:`⏸ 已暂停`,inspect:`检查`,hintPause:`c 继续 · s 单步 · n 下一步 · o 步出 · x 停止`,hintFocus:`Ctrl+G 聚焦`,hintBp:`↑↓ 选择 · Tab 切换 · space 开关 · Esc 退出`,bpIdle:`▶ ⤼ ⤓ ⤴ ⏹ 空闲 — 运行一次以在启用的断点处暂停`,variablesIdle:`变量在暂停时显示 — 去 Sources 启用一个点位再运行`,breakpoints:`断点`,noneInteractive:`— 无(需交互式 inspector)—`,noTools:`— 暂无工具调用 —`,noEvents:`— 暂无追踪事件(运行一次)—`,noUsage:`— 暂无用量(运行一次)—`,noLineage:`— 无血缘 —`,toolbar:`▶ 继续(c) ⤼ 跨过(n) ⤓ 单步(s) ⤴ 步出(o) ⏹ 停止(x)`,variables:`变量`,editKeys:` Enter=保存 Esc=取消`,injectMsg:`注入消息`,changeData:`改数据: t 思考 · [ ]温度 · i 注入 · e 系统提示`,budgetOverhead:`开销`,budgetMessages:`消息`,budgetFree:`可用`,budgetLastTotal:`上轮 {{lastIn}}→{{lastOut}} · 累计 {{totalIn}}→{{totalOut}}`,liveTag:`▸ 实时`,userPrefix:`用户: `,thinkingFull:`思考(全文):`,toolRunning:`{{tool}}(运行中)`,toolCall:`{{tool}}(调用)`,assistantFallback:`助手文本`,emptyPrompt:`(提示)`,endTurn:`· 回合结束`,treeThinking:`思考 ⟨{{n}} · {{chars}} 字符⟩`,bpCatAgentWorkLoop:`Agent 工作循环`,bpCatWorkLoopInjection:`工作循环注入`,bpCatToolExecutor:`工具执行器`,bpCatSessionPrompt:`会话提示生命周期`,bpCatLifecycleHook:`生命周期钩子`,bpCatTurnObservable:`回合可观测`,bpCatCustom:`自定义`,debugCall:`调用`,debugLlmParams:`LLM 参数`,debugSystemPrompt:`系统提示`,debugMessages:`消息 ({{n}})`,debugTokens:`Token 入 {{inTokens}} · 出 {{outTokens}}`,debugEmpty:`(空)`,debugEditsPending:`编辑: {{parts}}(恢复时应用)`,debugEditSysPrompt:`系统提示`,asstPrefix:`助手: `,thinkingPrefix:`思考… `,noTurnData:`暂无回合数据。`,treeAssistantDeltas_other:`助手 ⟨{{count}} 增量 · {{chars}} 字符⟩`,hintTree:`↑↓ 移动 · Tab 切换 · w 血缘{{whySeg}} · z 展开{{expandSeg}} · space 折叠 · Esc 退出`},budget:{exhaustedTitle:`已达本回合工具步数预算——任务可能还没干完,要我接着干完吗?`,continue:`接着跑`,stop:`先停下`,stoppedNote:`⏸ 已停在工具步数预算上限——任务可能还没全干完。需要的话直接继续指示我即可接着干(每次对话都会重置本回合工具预算)。`,tokensLabel_other:`{{count}} token`,tokenBudgetLabel:`{{used}}/{{budget}} tok`},cmdDesc:{help:`显示可用命令`,exit:`退出 TUI;/exit --restart 重启到同一会话`,clear:`清屏并重置会话`,abort:`中止当前 agent 运行`,copy:`复制上一条助手回复`,model:`列出模型或用 /model <id> 切换`,setup:`查看上手进度(provider → 登录 → 模型),带下一步直达按钮`,status:`显示会话状态`,inspect:`打开 inspector(Events/Tools/Sources/Budget);/inspect sources|<point>|off`,replay:`回放会话追踪(/replay [<id>|off])`,delegates:`开关 Delegates 面板(↑↓ 选择 · k 终止 · o 输出 · a 应用)。别名:/jobs /bg`,job:`委派后台 agent 作业:/job <指令>(worktree 隔离 + 全套工具含 MCP)。改了代码→产 diff 待 apply;整理/调研类→产文字结果(按 o 看)。`,extension:`管理可插拔扩展(MCP / 技能 / agent):↑↓ 选择 · Enter 切换 · Esc 关闭`,compact:`立即压缩对话上下文(摘要更早的消息以释放 token)`,memory:`项目+用户记忆:/memory [user|project|<名称>|forget <名称>];/memory user <内容> 记跨项目笔记(# 写项目级)`,login:`登录 provider(OAuth 或 API Key);/auth [<provider>]`,logout:`移除某 provider 的已存凭证;/logout [<provider>]`,effort:`切换推理投入档(/effort low|medium|high|xhigh|max)`,preference:`偏好设置:/preference [lang|theme]`,permissions:`查看/清空始终允许列表(/permissions [clear])`,context:`显示上下文用量分解(system/tools/messages/cache/free 分段条)`,attach:"连接到 `otto serve` 上运行的会话:/attach <sessionId>(本期只读预览)",history:`打开输入历史搜索面板。别名:/hist`,prompts:`查看 Prompt 记录(本会话已提交的 prompt 列表)`,notification:`开关通知中心面板(≡ Ctrl+N)。别名:/notif`,pin:`置顶当前会话(/resume 列表排序权重);批量/分组:/pin [<会话id>...] [--group <名称>]`,unpin:`取消置顶当前会话`},pref:{permModeSwitched:`权限模式 → {{label}}`,languageUsage:`用法:/preference lang <en|zh>`,languageName_zh:`中文`,languageName_other:`English`,permModeLabel_confirm:`批准`,permModeLabel_auto:`自动`,permModeLabel_bypass:`全自动`,permModeLabel:`{{context}}`,authModeLabel_oauth:`订阅`,authModeLabel_api_key:`密钥`,authModeLabel_env:`密钥`,authModeLabel:`{{context}}`,languageSwitched:`语言 → {{name}}({{l}})`},time:{justNow:`刚刚`,minAgo:`{{min}} 分钟前`,hourAgo:`{{hr}} 小时前`,dayAgo:`{{day}} 天前`},paste:{confirmTitle:`粘贴大段文本?`,collapseLabel:`折叠为 `,confirm:`确认`,cancel:`取消`,view:`查看`,viewTitle:`复制内容`,titlePasteExpired:`粘贴已失效`,expiredToast_other:`{{count}} 处粘贴内容已失效,请重新粘贴`,previewSummary_body:`─── 共 {{lines}} 行, {{chars}} 字符 ───`},select:{filterPlaceholder:`输入过滤…`,noMatches:`无匹配`,clearHint:`清除 / `,matchCount_other:`{{count}} 个匹配`},sigil:{filterPlaceholder:`输入过滤…`,noMatches:`无匹配`,searching:`搜索中…`,catAgent:`代理`,catRecent:`最近使用`,catResource:`自定义资源`,catShortcut:`快捷方式`,catExtension:`扩展`,catPerson:`成员`,catHashtag:`模板`,catPlugin:`插件`,catFile:`文件`,catModel:`模型`,loadingFile:`加载文件…`,readFullFile:`查看全文`,catSkill:`技能`,titleMention:`提及`,titleHashtag:`标签`},toast:{editorError:`编辑器错误`},context:{tokensLabel:`{{formatted}} token`,title:`上下文`,noData:`暂无上下文数据 — 等待首次 API 响应。`,viewDetails:`Enter 详情`,systemHeading:`系统上下文`,systemMeta:`{{tokens}}t · {{stable}} 稳定 + {{volatile}} 易变`,laneVolatile:`易变`,laneCache:`缓存`,conversationHeading:`对话`,conversationMeta:`{{tokens}}t · {{turns}} 轮`,earlierTurns:`更早 {{count}} 轮({{tokens}}t)`,turnRow:`第 {{index}} 轮 · {{messages}} 条 · {{tokens}}t`,totalLine:`合计 {{used}} / {{window}}({{percent}}%)· 空闲 {{free}}t`,tagPruned:`已裁剪`,tagCompacted:`已压缩`,tagTruncated:`已截断`},transcript:{frozenNew:`条新消息`,escToLive:`Esc 回最新`,you:`你`,assistant:`助手`,loadingEarlier:`加载更早历史…`,emptyEarlier:`— 已到最早消息 —(PgUp/↑ 滚动 · Esc 回最新)`,findBar:`/{{query}} · {{count}}`},trust:{title:`信任此文件夹?`,body:`访问工作区:
69
+ 解决:① 关闭另一个 otto 进程后,本会话会在下次保存成功时自动恢复可写;② 或退出本窗口,/resume 换一个会话继续工作。`,restoredToastTitle:`会话已恢复可写`,restoredToastBody:`此后的改动会正常保存。`},pause:{titleRequested:`等待暂停`,bodyRequested:`将在当前回合结束后自动暂停`,titleActive:`已暂停`,bodyActive:`Agent 运行已暂停,排队消息不会自动执行`,btnCancel:`取消暂停`,btnResume:`继续运行`,footerDismiss:`Esc 关闭浮层,暂停请求仍在后台生效`,footerActive:`Enter 接受 · Esc 关闭`,toolCount:`{{n}} 工具 · {{s}}s`,toolTotal:`本回合执行了 {{n}} 个工具`},run:{messageFooter:`输入任意消息或 /continue 继续`,resumedMessageBody:`Agent 已恢复运行`,pauseCancelledMessageBody:`暂停请求已取消,Agent 继续运行`,messageBody:`Agent 运行已暂停,排队消息不会自动执行`,messageBody_n:`Agent 运行已暂停(本回合 {{n}} 个工具),排队消息不会自动执行`},shell:{running:`运行中`,terminated:`已终止`,errored:`错误`,exit:`退出码 {{code}}`,copyHint:`复制输出`,copiedTitle:`Shell`,copiedBody:`已复制到剪贴板`,hint:`问 AI`,exitCode:`退出码 {{code}}`,askAiTerminated:`被信号终止`,unknownError:`未知错误`,prompt:"命令 `{{command}}` 执行失败({{errorLabel}}),输出如下,请帮忙排查:\n\n```\n{{output}}\n```",truncated:`...(已截断,完整输出请用 c 键复制到剪贴板查看)`,viewAll_other:`查看全部输出(共 {{count}} 行)`,moreLines_other:`... 还有 {{count}} 行 ...`},spinner:{verbs:[`处理中`,`思考中`,`计算中`,`运行中`],outputPercent:`{{pct}}% 上限`,estimatedPercent:`~{{pct}}%`},bg:{runningVerb:`运行 {{tool}}`,tasksTitle:`委派`,empty:`(无后台任务)`,noOutput:`(暂无输出)`,live:`实时`,following:`跟随中…`,jobsLabel:`{{n}} 个委派`,runningSuffix:`{{n}} 个运行中`,doneSuffix:`{{n}} 个完成`,needInputSuffix:`{{n}} 个待输入`,metaReady:`就绪`,metaNeedsInput:`待输入`,agentStatusLabel:`{{st}}`,procStatusLabel:`{{s}}`,categoryLabel_job:`委派作业`,categoryLabel_bash:`Bash 命令`,categoryLabel_other:`子代理`,metaExited:`已退出`,metaExited_code:`已退出 {{code}}`},subagent:{sTitle:`子代理`,sRunning:`{{n}} 个运行中`,header:`子代理 @{{title}} · {{status}}`,contextEarlierLines:`↑ {{n}} 行更早 · ↵ 看完整可滚动转录`,sWorking_other:`子代理运行中({{count}} 个子代理)`},agent:{interruptTitle:`中断 agent?`,interruptMessage:`当前 agent 回合仍在运行。确认中断会停止本轮并标记为已中断。`,interruptConfirm:`中断`},queue:{label:`队列`,empty:`队列为空`,editTitle:`编辑队列项 {{index}}/{{total}}`,editSendNowButton:`直接发送`,editConfirmButton:`确定`,editSendNowHintBusy:`将作为补充说明注入当前回合`,editSendNowHintIdle:`将立即发送为新消息`,exitTitle:`退出排队命令面板`,exitConfirm:`清除并退出`,exitMessage:`面板中有 %d 条排队命令将被清除。`,popTitle:`移除排队消息?`,popMessage:`当前有一条追问消息排队中。是否移除最新排队消息,而不是中断正在运行的回合?`,popConfirm:`移除排队消息`,dFollowUpToast:`模型还在跑——已加入追问队列,完成后自动发送`},retry:{reason:`{{reason}}`,defaultTitle:`错误详情`,attempt:`重试 {{attempt}}/{{max}}`,countdown:`{{s}} 秒后重试…`,progressSep:`,`,nowButton:`立即重试`,hint:`↵/r`,stopButton:`停止`,hintWithStop:`↵/r 重试 · Esc 停止`},error:{typeLabel:`{{type}} 限额已达上限`,retryNow:`立即重试`,switchModel:`切换模型`,title:`请求失败:{{reason}}`,defaultTitle:`请求失败`,exhaustedTitle:`多次重试后仍失败`,autoCountdown:`第 {{attempt}}/{{max}} 次重试,{{seconds}} 秒后自动重试`,manualBody:`第 {{attempt}}/{{max}} 次重试,需先完成操作才能重试`,exhaustedBody:`已重试 {{max}} 次仍失败`,resetsIn:`配额将在 {{hms}} 后重置`,unknownReset:`重置时间未知`,hint:`←/→ 选择 · ↵ 确认 · r 立即重试 · Esc 取消`},pulse:{title:`这次体验如何?`,ratingGood:`好评`,ratingNeutral:`一般`,ratingBad:`待改进`,commentTitle:`{{ratingLabel}} · 想补充点什么吗?(可选)`,commentPlaceholder:`说点什么…`,hintRating:`←/→/Tab 切换 · ↵ 选择 · Esc 关闭`,hintComment:`↵ 提交 · Esc 关闭(评分仍会保存)`},find:{inputLabel:`查找:`,matchCount:`{{current}}/{{total}}`,tabPrompt:`提示词`,tabConversation:`对话`,tabDiff:`Diff`,tabDiagnostics:`诊断`,searchNoMatches:`无匹配`},schedule:{sLabel:`定时任务`,sEmpty:`暂无定时任务。用 /schedule add 创建`,oneShot:`单次`,next:`下次: `,panel:{noTasks:`暂无定时任务。`,pressToAdd:`按 {{key}} 创建第一个定时任务。`,examples:`示例: {{c1}} 每天 09:00 · {{c2}} 每 30 分钟`,running:`运行中`,failedCanceled:`失败/已取消`,readonlyNet:`{{cross}} 网络错误 — 无法连接调度服务`,readonlyLease:`{{cross}} 只读 — 另一个终端持有 fire-ownership 租约`,moreAbove:`... 上方 {{n}} 条`,moreBelow:`... 下方 {{n}} 条`,failedErr:`(失败: {{err}})`,detail:{id:`ID`,status:`状态`,type:`类型`,cron:`Cron`,prompt:`提示词`,nextFire:`下次触发`,lastFire:`上次触发`,never:`从未`,jobRunning:`{{cross}} 任务运行中 — {{id}}`,recent:`最近 ({{n}} 条)`,loadingLogs:`加载日志...`,noLogs:`暂无日志`},logsTitle:`日志: {{id}}`,form:{newTitle:`新建定时任务`,editTitle:`编辑: {{id}}`,name:`名称`,cron:`Cron`,type:`类型`,status:`状态`,prompt:`提示词`,preview:`预览`,auto:`(自动)`,cronPlaceholder:`________________`,recurring:`循环`,enabled:`已启用`,disabled:`已禁用`,toggleHint:`(←/→ 切换)`,templatesHint:`按 ←/→ 选择模板`,templates:`模板`,previewNext:`下次触发: {{time}}`,previewJitter:`下次触发: {{time}} + 0-30分钟抖动`,previewJitterOnce:`下次触发: {{time}} + ~90秒抖动`,previewCron:`cron: {{cron}} (循环)`,previewCronOnce:`cron: {{cron}} (单次)`,previewEmpty:`输入有效的 cron 表达式`,invalidCron:`无效 cron`,required:`Cron 和提示词为必填项`,saving:`保存中...`,createFailed:`创建失败`,saveFailed:`保存失败`},confirmCancelTitle:`取消任务?`,confirmCancelBody:`这将取消 {{name}} 当前正在运行的任务。`,confirmCancelNote:`定时任务定义不受影响。`,confirmRemoveTitle:`删除定时任务?`,confirmRemoveBody:`这将永久删除 {{name}} ({{id}})。`,confirmRemoveWarn:`此操作不可撤销。`}},draft:{sLabel:`草稿`,sEmpty:`暂无草稿。用 Ctrl+S 保存一条`,saved:`已保存到草稿`,saveEmpty:`输入为空,无内容可保存`},prompts:{label:`Prompt 记录`,empty:`暂无 Prompt 记录`},scroll:{above:`↑ 上方 {{n}} 行`,below:`↓ 下方 {{n}} 行`,viewportLinesAbove:`上方行`,viewportLinesBelow:`下方行`},service:{sTitle:`服务`,sEmpty:`(无运行中的服务)`,countLabel_other:`服务`},insp:{live:`实时 · {{n}} 行`,row:`第 {{cur}}/{{total}} 行`,replay:`回放`,paused:`⏸ 已暂停`,pausedBig:`⏸ 已暂停`,inspect:`检查`,hintPause:`c 继续 · s 单步 · n 下一步 · o 步出 · x 停止`,hintFocus:`Ctrl+G 聚焦`,hintBp:`↑↓ 选择 · Tab 切换 · space 开关 · Esc 退出`,bpIdle:`▶ ⤼ ⤓ ⤴ ⏹ 空闲 — 运行一次以在启用的断点处暂停`,variablesIdle:`变量在暂停时显示 — 去 Sources 启用一个点位再运行`,breakpoints:`断点`,noneInteractive:`— 无(需交互式 inspector)—`,noTools:`— 暂无工具调用 —`,noEvents:`— 暂无追踪事件(运行一次)—`,noUsage:`— 暂无用量(运行一次)—`,noLineage:`— 无血缘 —`,toolbar:`▶ 继续(c) ⤼ 跨过(n) ⤓ 单步(s) ⤴ 步出(o) ⏹ 停止(x)`,variables:`变量`,editKeys:` Enter=保存 Esc=取消`,injectMsg:`注入消息`,changeData:`改数据: t 思考 · [ ]温度 · i 注入 · e 系统提示`,budgetOverhead:`开销`,budgetMessages:`消息`,budgetFree:`可用`,budgetLastTotal:`上轮 {{lastIn}}→{{lastOut}} · 累计 {{totalIn}}→{{totalOut}}`,liveTag:`▸ 实时`,userPrefix:`用户: `,thinkingFull:`思考(全文):`,toolRunning:`{{tool}}(运行中)`,toolCall:`{{tool}}(调用)`,assistantFallback:`助手文本`,emptyPrompt:`(提示)`,endTurn:`· 回合结束`,treeThinking:`思考 ⟨{{n}} · {{chars}} 字符⟩`,bpCatAgentWorkLoop:`Agent 工作循环`,bpCatWorkLoopInjection:`工作循环注入`,bpCatToolExecutor:`工具执行器`,bpCatSessionPrompt:`会话提示生命周期`,bpCatLifecycleHook:`生命周期钩子`,bpCatTurnObservable:`回合可观测`,bpCatCustom:`自定义`,debugCall:`调用`,debugLlmParams:`LLM 参数`,debugSystemPrompt:`系统提示`,debugMessages:`消息 ({{n}})`,debugTokens:`Token 入 {{inTokens}} · 出 {{outTokens}}`,debugEmpty:`(空)`,debugEditsPending:`编辑: {{parts}}(恢复时应用)`,debugEditSysPrompt:`系统提示`,asstPrefix:`助手: `,thinkingPrefix:`思考… `,noTurnData:`暂无回合数据。`,treeAssistantDeltas_other:`助手 ⟨{{count}} 增量 · {{chars}} 字符⟩`,hintTree:`↑↓ 移动 · Tab 切换 · w 血缘{{whySeg}} · z 展开{{expandSeg}} · space 折叠 · Esc 退出`},budget:{exhaustedTitle:`已达本回合工具步数预算——任务可能还没干完,要我接着干完吗?`,continue:`接着跑`,stop:`先停下`,stoppedNote:`⏸ 已停在工具步数预算上限——任务可能还没全干完。需要的话直接继续指示我即可接着干(每次对话都会重置本回合工具预算)。`,tokensLabel_other:`{{count}} token`,tokenBudgetLabel:`{{used}}/{{budget}} tok`},cmdDesc:{help:`显示可用命令`,exit:`退出 TUI;/exit --restart 重启到同一会话`,clear:`清屏并重置会话`,abort:`中止当前 agent 运行`,copy:`复制上一条助手回复`,model:`列出模型或用 /model <id> 切换`,setup:`查看上手进度(provider → 登录 → 模型),带下一步直达按钮`,status:`显示会话状态`,inspect:`打开 inspector(Events/Tools/Sources/Budget);/inspect sources|<point>|off`,replay:`回放会话追踪(/replay [<id>|off])`,delegates:`开关 Delegates 面板(↑↓ 选择 · k 终止 · o 输出 · a 应用)。别名:/jobs /bg`,job:`委派后台 agent 作业:/job <指令>(worktree 隔离 + 全套工具含 MCP)。改了代码→产 diff 待 apply;整理/调研类→产文字结果(按 o 看)。`,extension:`管理可插拔扩展(MCP / 技能 / agent):↑↓ 选择 · Enter 切换 · Esc 关闭`,compact:`立即压缩对话上下文(摘要更早的消息以释放 token)`,memory:`项目+用户记忆:/memory [user|project|<名称>|forget <名称>];/memory user <内容> 记跨项目笔记(# 写项目级)`,login:`登录 provider(OAuth 或 API Key);/auth [<provider>]`,logout:`移除某 provider 的已存凭证;/logout [<provider>]`,effort:`切换推理投入档(/effort low|medium|high|xhigh|max)`,preference:`偏好设置:/preference [lang|theme]`,permissions:`查看/清空始终允许列表(/permissions [clear])`,context:`显示上下文用量分解(system/tools/messages/cache/free 分段条)`,history:`打开输入历史搜索面板。别名:/hist`,prompts:`查看 Prompt 记录(本会话已提交的 prompt 列表)`,notification:`开关通知中心面板(≡ Ctrl+N)。别名:/notif`,pin:`置顶当前会话(/resume 列表排序权重);批量/分组:/pin [<会话id>...] [--group <名称>]`,unpin:`取消置顶当前会话`},pref:{permModeSwitched:`权限模式 → {{label}}`,languageUsage:`用法:/preference lang <en|zh>`,languageName_zh:`中文`,languageName_other:`English`,permModeLabel_confirm:`批准`,permModeLabel_auto:`自动`,permModeLabel_bypass:`全自动`,permModeLabel:`{{context}}`,authModeLabel_oauth:`订阅`,authModeLabel_api_key:`密钥`,authModeLabel_env:`密钥`,authModeLabel:`{{context}}`,languageSwitched:`语言 → {{name}}({{l}})`},time:{justNow:`刚刚`,minAgo:`{{min}} 分钟前`,hourAgo:`{{hr}} 小时前`,dayAgo:`{{day}} 天前`},paste:{confirmTitle:`粘贴大段文本?`,collapseLabel:`折叠为 `,confirm:`确认`,cancel:`取消`,view:`查看`,viewTitle:`复制内容`,titlePasteExpired:`粘贴已失效`,expiredToast_other:`{{count}} 处粘贴内容已失效,请重新粘贴`,previewSummary_body:`─── 共 {{lines}} 行, {{chars}} 字符 ───`},select:{filterPlaceholder:`输入过滤…`,noMatches:`无匹配`,clearHint:`清除 / `,matchCount_other:`{{count}} 个匹配`},sigil:{filterPlaceholder:`输入过滤…`,noMatches:`无匹配`,searching:`搜索中…`,catAgent:`代理`,catRecent:`最近使用`,catResource:`自定义资源`,catShortcut:`快捷方式`,catExtension:`扩展`,catPerson:`成员`,catHashtag:`模板`,catPlugin:`插件`,catFile:`文件`,catModel:`模型`,loadingFile:`加载文件…`,readFullFile:`查看全文`,catSkill:`技能`,titleMention:`提及`,titleHashtag:`标签`},toast:{editorError:`编辑器错误`},context:{tokensLabel:`{{formatted}} token`,title:`上下文`,noData:`暂无上下文数据 — 等待首次 API 响应。`,viewDetails:`Enter 详情`,systemHeading:`系统上下文`,systemMeta:`{{tokens}}t · {{stable}} 稳定 + {{volatile}} 易变`,laneVolatile:`易变`,laneCache:`缓存`,conversationHeading:`对话`,conversationMeta:`{{tokens}}t · {{turns}} 轮`,earlierTurns:`更早 {{count}} 轮({{tokens}}t)`,turnRow:`第 {{index}} 轮 · {{messages}} 条 · {{tokens}}t`,totalLine:`合计 {{used}} / {{window}}({{percent}}%)· 空闲 {{free}}t`,tagPruned:`已裁剪`,tagCompacted:`已压缩`,tagTruncated:`已截断`},transcript:{frozenNew:`条新消息`,escToLive:`Esc 回最新`,you:`你`,assistant:`助手`,loadingEarlier:`加载更早历史…`,emptyEarlier:`— 已到最早消息 —(PgUp/↑ 滚动 · Esc 回最新)`,findBar:`/{{query}} · {{count}}`},trust:{title:`信任此文件夹?`,body:`访问工作区:
70
70
  {{path}}
71
71
 
72
72
  这是你创建或信任的项目吗(你自己的代码、知名开源项目、或团队的工作)?
73
73
  otto 将在此读取、编辑、执行文件。不确定就先查看此目录,或以只读方式打开。`,optTrust:`信任 — 完整访问(读 / 改 / 执行 + 应用其配置)`,optReadonly:`只读这一会话 — 安全查看,禁写 / 执行 / 联网`,optExit:`否,退出`},parent:{title:`检测到父级 workspace`,body:`当前目录 {{currentRoot}} 没有 workspace 身份,
74
74
  但上级目录 {{parentRoot}} 已有 workspace。`,optUseParent:`使用上级 workspace — 共享会话与记忆`,optCreateNew:`在当前目录创建新 workspace — 独立身份`,optExit:`退出`},notif:{title:`通知`,readDivider:`──── 已读 ────`},confirm:{reset:`确认重置`,replace:`确认替换`,abortConfirmTitle:`中止 Agent?`,abortConfirmMessage:`Agent 正在运行中。中止后当前回合将丢失,未完成的写入操作可能不完整。`,exitConfirmTitle:`终止并退出 otto?`,exitConfirmMessage:`Agent 正在运行中。退出将中止当前回合,未完成的写入操作可能不完整。`,exitRestartConfirmTitle:`终止并重启 otto?`},cache:{sessionLabel:`会话`,lastTurnLabel:`最近一轮`},recovery:{titleProvider:`尚未安装 AI provider`,hintProvider:`otto 需要一个 provider 才能连接模型。`,ctaProvider:`运行 /setup 安装`,titleAuth:`已安装 provider,尚未连接`,hintAuth:`登录或粘贴 API key 即可继续。`,ctaAuth:`运行 /setup 连接`,titleModel:`尚无可用模型`,hintModel:`凭据可能缺失或已过期。`,ctaModel:`运行 /setup 选择模型`},setup:{wizardApiKeyPlaceholder:`输入或粘贴密钥,按 Enter 确认`,title:`设置向导`,welcomeTitle:`欢迎使用 otto,你的 AI 伙伴`,welcomeGreeting:``,welcomeDescription:`本向导将通过 4 个步骤帮你完成初始设置:选择 AI 服务商、登录、选择模型,然后开始对话。`,welcomeDontShowAgain:`不再显示此向导`,welcomeStart:`开始`,welcomeCancel:`取消`,step1Subtitle:`otto 需要至少一个 AI provider 才能工作。选择一个安装——稍后可以通过 /extension 添加更多。`,step3Subtitle:`选择 provider 的认证方式。`,step4Subtitle:`选择一个模型开始对话。`,step5Done:`一切就绪!输入消息即可开始。`,installing:`安装中…`,installed:`已安装!`,installFailed:`安装失败:{{reason}}`,loginOAuth:`通过 OAuth 登录(推荐)`,loginApiKey:`粘贴 API key`,loggingIn:`登录中…`,loginFailed:`登录失败:{{reason}}`,exitTitle:`退出向导`,exitConfirm:`退出设置向导?进度将被保存 — 稍后可用 /setup 继续。`,errorTitle:`设置出错`,errorMessage:`设置步骤 {{step}} 失败:{{msg}}
75
75
  已记录崩溃报告。`,stepNameProvider:`LLM 服务商`,stepNameLogin:`登录`,stepNameModel:`模型`,stepNameStart:`开始`,actionInstall:`安装`,actionLogin:`登录`,installPendingCapabilities:`已安装,但部分能力尚未授权——请运行 /extension 授予,否则该 provider 不会提供任何模型。`,modelRecommendedTag:`推荐`,modelRecommendedHint:`已把推荐项排在最前——随时可用 /model 更换。`,modelUnusableUnauthenticated:`需要先登录`,modelUnusableOauthRisk:`订阅方案可能被限流`,authFailedNetwork:`无法连接授权服务,可能是网络或代理问题。`,authFailedRejected:`授权未完成。`,actionOpenProxySettings:`打开代理设置`,actionRetryAuth:`重新登录`,oauthWaiting:`等待浏览器中完成授权…`,actionOpenAgain:`重新打开授权页`,actionUseApiKeyInstead:`改用 API key`,apiKeyStorageNote:`保存在本机凭据文件中——不会写入当前项目,也不会进入聊天记录。`,installFailedRecovery:`{{provider}} 安装失败。选择下一步:`,actionRetryInstall:`重试安装`,actionChooseAnotherProvider:`换一个 provider`,capabilityGranted:`已授予能力:{{caps}}`,capabilityRevokeHint:`可随时在 /extension 中撤销。`},install:{title:`正在安装 {{source}}`,phaseResolving:`解析来源…`,phaseDetecting:`检测内容…`,phaseInstalling:`安装中…`,phaseRefreshing:`刷新能力…`,reloadingDetail:`正在刷新能力…`,done:`已安装`,summaryFailed:`安装失败`,summaryPartial:`部分安装成功`,nextStepForce:`提示:加 --force 可覆盖已存在的内容`,nextStepReload:`提示:执行 /reload 手动刷新能力`,failureOverflow:`(完整列表见下方消息)`,partialCounts:`{{ok}} 个成功,{{fail}} 个失败:`},proxy:{title:`Proxy`,groupConfig:`配置`,groupAbout:`说明`,fieldUrl:`代理地址`,fieldEnabled:`启用状态`,dialogSetUrl:`设置代理地址`,dialogEditUrl:`编辑代理地址`,urlPlaceholder:`http://127.0.0.1:7890`,urlEmpty:`尚未设置 — 例如 http://127.0.0.1:7890`,stateEnabled:`已启用`,stateDisabled:`已停用`,actionClear:`清除配置`,clearTitle:`清除代理配置`,clearMessage:`确认清除代理配置?({{url}})`,clearConfirm:`清除`,aboutScope:`作用于所有出站 HTTP:模型 API、登录、网页抓取、版本检查。`,aboutLoopback:`本机地址(localhost / 127.0.0.1)始终直连。`,aboutStorage:`配置存储在 {{path}}`,aboutCommand:`命令行等效:/proxy [<url>|on|off|status|clear]`,actionTest:`测试连接`,actionAdoptEnv:`采用系统代理 {{value}}(来自 {{source}})`,probeProbing:`测试中…`,probeOk:`代理可达 — {{latency}}ms({{target}})`,probeFailedProxy:`代理不可达 — {{reason}}`,probeFailedTarget:`代理正常,但目标不可达 — {{reason}}`,probeNoModel:`请先配置模型,再测试连接`,effectiveMismatch:`当前生效:{{effective}} — 需重启会话使变更生效`,effectiveNotApplied:`尚未生效 — 需重启会话使变更生效`,envDetectedToast:`检测到 {{source}}={{value}} — 运行 /proxy 可一键采用`},crashGap:{toastTitle:`检测到上次异常退出丢失了部分对话`,toastBody:`上次进程异常终止(如内存耗尽或被强制结束)时,约 {{lostTurns}} 个回合的消息未能保存,已无法恢复。较早的对话已完整保留。`},signalBar:{tabHint:`Tab 切换`,clipboard:`剪贴板`,clipboardFailed:`复制受限 — 按住 {{modifier}} 拖拽用终端原生复制`},clipboard:{paneTitle:`剪贴板`,viewerTitle:`剪贴板内容`,charsLabel:`{{count}} 个字符`,empty:`暂无复制内容`,openHint:`查看`},mouse:{toggleTitle:`鼠标`,enabledBody:`已开启 — 拖拽即选择并复制;按住 {{modifier}} 可用终端原生选择;滚轮可滚动`,disabledBody:`已关闭 — 恢复终端原生选择,滚轮失效(可用 Alt+↑/↓ 回看)`}}}};function r(r){return e.isInitialized?e.changeLanguage(r):e.use(t).init({lng:r,fallbackLng:`en`,resources:n,defaultNS:`translation`,interpolation:{escapeValue:!1},returnNull:!1,returnEmptyString:!1}),e}r(`en`);const i=e.t.bind(e);function a(){let e=process.env.LC_ALL||process.env.LC_MESSAGES||process.env.LANG||``;return/zh/i.test(e)?`zh`:`en`}export{i,e as n,r,a as t};
76
- //# sourceMappingURL=i18n-CznO8p1Y.js.map
76
+ //# sourceMappingURL=i18n-Dju4J1Q-.js.map