返回 DeepSeek-Reasonix
i18n.go
根目录 / internal / i18n / i18n.go
1 // Package i18n holds the CLI's translatable strings and a small detection
2 // helper. Architecture: a single Messages struct of exported string fields
3 // (plain text or fmt format strings, suffix *Fmt flags the latter). Each
4 // language declares one Messages value in its own file. Call sites read
5 // i18n.M.SomeField; for parameterised messages they pass it to fmt.Sprintf.
6 //
7 // Adding a field requires updating every messages_*.go file — drift is caught
8 // at test time by TestCatalogsComplete via reflection, so a missing translation
9 // fails CI instead of surfacing as a blank line at runtime.
10 //
11 // Scope (v1): CLI surface only — welcome, init wizard, chat REPL banner, usage,
12 // user-facing CLI errors. System prompts, internal error wrappers, and agent
13 // runtime telemetry stay English so model behaviour and developer logs are
14 // language-stable.
15 package i18n
16
17 import (
18 "os"
19 "strings"
20 )
21
22 // Messages is the catalogue of translatable CLI strings. Plain fields are
23 // printed verbatim; *Fmt fields are fmt format strings the caller passes to
24 // fmt.Sprintf. Catalogue values do not include trailing newlines — call sites
25 // add framing whitespace, so the same field works wherever it appears.
26 type Messages struct {
27 // welcome / status screen
28 WelcomeTitleFmt string // first-run box title — %s = product name (styled)
29 NoConfigYet string // first-run cue under the welcome box
30
31 // `reasonix init` — points to the in-session /init skill + setup
32 InitHint string
33
34 // chat REPL
35 ChatTip string // tip line under the chat banner
36 TurnCancelled string // shown when Ctrl-C aborts the in-flight turn but the chat keeps running
37 InterruptedRecovery string // replay notice for a durable interrupted turn
38 FinalReadinessRecovery string // replay hint for a durable final-readiness pause
39 ReadinessContinuing string // host is automatically finishing known readiness gaps
40 RecoveryPaused string // controlled Auto retry pause; user can continue in the next message
41 CompletionUncertain string // completion validator could not confirm the result; work is kept
42 ReasoningReplayRepair string // provider rejected replayed thinking blocks; history repaired and retried once
43 ImageRequestRecovery string // current image cannot be included; request a fresh attachment
44 ExtensionRequestRecovery string // extension produced an invalid model request
45 ExtensionBlockRecovery string // actionable hint following an explicit extension block
46 ContextLimitRecovery string // automatic context recovery exhausted
47 SessionSaveRecovery string // durability failure; preserve the live conversation
48 // Host guard/recovery notices (event.Notice texts the fronts render verbatim).
49 EmptyFinal string // empty_final: no visible answer; retrying
50 ExecutorHandoff string // executor_handoff: answered without using tools
51 ToolBudget string // tool_budget: tool-call round limit reached
52 TaskBudget string // tool_budget variant: task spend budget reached
53 LoopGuard string // loop_guard: no-progress tool loop
54 ProgressGuard string // progress_guard: repeated work without new evidence
55 OperationNeedsUser string // operation_needs_user: host stopped retrying one operation
56 SoftBudgetConverge string // loop_guard: converging a long read-only investigation
57 EvidenceNudge string // evidence_nudge: unverified mutations
58 ReasoningGovernor string // reasoning_governor engaged
59 UnappliedSteerFmt string // unapplied_steer — %s = the dropped guidance
60 DeprecatedContextRetention string // agent.keep / agent.recent_keep deprecation warning
61 FinishReasonLength string
62 FinishReasonContentFilter string
63 FinishReasonRepetition string
64 StreamInterruptedIdleTimeout string
65 StreamInterruptedPrematureEOF string
66 StreamInterruptedConnectionReset string
67 ToolOutputTruncatedFmt string // %d = elided bytes, %d = original bytes
68 IncompleteReadFinishBlocked string
69 ReadContinuationRequired string
70 IncompleteReadDetected string
71 ReadStrategyRequired string
72 ReadStrategyProgress string
73 ReadStrategyResolved string
74 ReadLocalSafetyPaged string
75 ReadCompleted string
76 ReadRestrictedStrategyFmt string // %d = estimated tokens, %d = token budget
77 ContextRecoveryAdjustBudget string
78 PromptTruncatedByServerNotice string
79 ContextRecoveryCompacted string
80 PlannerFallback string
81 PlannerSafetyFallback string
82 PlannerPlanAwaitingApproval string
83 PlannerPlanNotApproved string
84 PlannerPlanOnly string
85 CapabilityProxyFmt string // %s = display name, %s = resolved target
86 ReceiptVerified string // end-of-turn receipt, nothing unproven
87 ReceiptGapsHeader string // end-of-turn receipt, header above the unproven list
88 ReceiptRisksHeader string // end-of-turn receipt, header above declared risks
89 ReceiptMore string // end-of-turn receipt, "and N more" tail
90 // ReceiptGapKinds maps a completion gap kind to its short human phrase.
91 ReceiptGapKinds map[string]string
92 NoSessionToResume string // shown when --continue / --resume finds nothing
93 ResumeRequiresTTY string // shown when --resume runs piped instead of on a terminal
94 AmbiguousResumeHint string // under the candidates of a --resume query that matched several sessions
95 PickSessionLabel string // header on the --resume picker
96
97 // in-chat /resume command
98 ResumeBusy string // shown when /resume is used mid-turn
99 ResumeBadIndexFmt string // shown when /resume gets an out-of-range index (one %d)
100 ResumeAlreadyActive string // shown when /resume targets the current session
101 ResumedTitle string // banner title after a /resume switch
102
103 RenameUsage string // /rename with no args
104 RenameNoSession string // /rename with no active session
105 RenameDoneFmt string // /rename succeeded (one %s = new title)
106 ResumePickTitle string // header in the interactive resume picker
107 ResumePickHint string // keyboard hint in the interactive resume picker
108 ResumeRecoveryBadgeFmt string // recovery-copy badge — %s = short parent session id
109
110 // chat TUI status line / approval banner.
111 ChatThinking string // live reasoning marker label, e.g. "thinking…"
112 ChatThoughtForFmt string // collapsed reasoning summary, "%d" = elapsed s
113 ChatStatusThinkingFmt string // "%s thinking… (%ds · <cancel hint>)" — %s = spinner, %d = elapsed s
114 TurnPhaseWorking string // host turn_phase label: working
115 ReadStatusReadingFmt string // read status: reading a file
116 ReadStatusCoveredFmt string // read status: covered lines
117 ReadStatusDoneFmt string // read status: finished a window
118 ReadStatusPausedFmt string // read status: paused, needs attention
119 ReadStatusRecovery string // next step after a bounded read stops
120 TurnPhaseChecking string // host turn_phase label: checking
121 TurnPhaseVerifying string // host turn_phase label: verifying
122 TurnPhaseReviewing string // host turn_phase label: reviewing
123 CompletionSummaryBlocked string // concise non-verbose alert for a blocked turn
124 CompletionSummaryNeedsAttention string // concise non-verbose alert for verification/review gaps
125 ChatToolWorkingFmt string // "%s working · %ds" under a running tool — %s = spinner, %d = elapsed s
126 ChatSubagentPhaseQueued string // sub-agent progress phase label ("queued")
127 ChatSubagentPhaseRunning string // ("running")
128 ChatSubagentPhaseReasoning string // ("reasoning")
129 ChatSubagentPhaseResponding string // ("responding")
130 ChatSubagentPhaseTool string // ("using tools")
131 ChatSubagentPhaseRetrying string // ("retrying")
132 ChatSubagentPhaseCompleted string // ("completed")
133 ChatSubagentPhaseFailed string // ("failed")
134 ChatSubagentPhaseCancelled string // ("cancelled")
135 ChatSubagentProgressFmt string // live progress line — %s = phase label, %d = elapsed s, %d = idle s ("%s · %ds · %ds ago")
136 ChatSubagentProgressDoneFmt string // terminal summary — %s = phase label, %d = duration s ("%s · %ds")
137 ChatSubagentPreviewLabel string // verbose preview marker ("▎")
138 ChatStatusRetryingFmt string // "%s retrying (%d/%d)…" — %s = spinner, %d/%d = attempt/max
139 ChatStatusCancellingFmt string // "%s stopping… (%ds · Ctrl+C exits)" — %s = spinner, %d = elapsed s
140 ChatStatusIdle string // shortcuts hint when idle
141 ChatStatusCycleHint string // plan-toggle shortcut hint shown when no modal prompt owns the status row
142 ChatStatusCycleHintCompact string // readable shortcut hint used by the persistent footer
143 ChatTurnReceiptLabel string // compact per-turn usage receipt attached to the completed assistant response
144 RateBandPeak string
145 RateBandOffPeak string
146 RateBandMixed string
147 ChatStatusModelLabel string
148 ChatStatusEffortLabel string
149 ChatStatusPresetLabel string
150 ChatStatusCacheLabel string
151 ChatStatusContextLabel string
152 ChatStatusCompactLabel string
153 ChatStatusJobsLabel string
154 ChatStatusBalanceLabel string
155 ChatStatusCostLabel string
156 ChatStatusCacheNowFmt string // cache status tag, "%s" = latest-turn hit rate with percent sign
157 ChatStatusCacheAvgFmt string // cache status tag, "%s" = session-average hit rate with percent sign
158 ChatStatusPlanApproval string // shortcuts hint while a plan is pending
159 PlanApprovalPrompt string // one-line "plan above is ready" banner shown above the input
160 PlanApprovalChoices string // start / revise / exit-without-executing choice list
161 ChatStatusToolApproval string // shortcuts hint while a tool call awaits approval
162 ToolApprovalPromptFmt string // approval banner — tool, subject suffix, source/intent detail, choices
163 ToolApprovalChoices string // standard approval choice list
164 BashPrefixChoices string // approval choice list when a bash prefix can be granted
165 PlanModeReadOnlyCommandChoices string // approval choice list for plan-mode read-only command trust
166 FreshHumanApprovalChoices string // approval choice list for prompts that cannot be remembered
167 RecoveryApprovalChoices string // one-shot Auto Guard decision list
168 RecoveryPlanChangeChoices string // material Auto plan transition decision list
169 RecoveryPlanDecisionPrompt string // neutral title for a material Auto plan transition
170 RecoveryPlanBeforeFmt string // compact previous-plan line, one %s
171 RecoveryPlanAfterFmt string // compact proposed-plan line, one %s
172 RecoveryTaskGrantChoices string // Auto Guard list with a current-task semantic grant
173 SandboxEscapeApprovalChoices string // approval choice list for OS sandbox escape prompts
174 ApprovalNeededFmt string // notification text for a pending approval, tool only
175 ApprovalNeededWithSubjectFmt string // notification text for a pending approval with subject
176 ToolApprovalSourceFmt string // "Source: %s" / "来源: %s"
177 ToolApprovalBuiltIn string // built-in tool source label
178 ToolApprovalImageUse string // image-understanding detail for understand_image-style tools
179 ApprovalToolLabelBash string // user-facing label for bash approvals
180 ApprovalToolLabelEditFile string // user-facing label for edit_file approvals
181 ApprovalToolLabelWriteFile string // user-facing label for write_file approvals
182 ApprovalToolLabelMultiEdit string // user-facing label for multi_edit approvals
183 ApprovalToolLabelMoveFile string // user-facing label for move_file approvals
184 ApprovalToolLabelWebFetch string // user-facing label for web_fetch approvals
185 ApprovalToolLabelRunSkill string // user-facing label for run_skill approvals
186 ApprovalToolLabelRemember string // user-facing label for remember approvals
187 ApprovalToolLabelForget string // user-facing label for forget approvals
188 ApprovalToolLabelSandboxEscape string // user-facing label for OS sandbox escape approvals
189 ApprovalToolLabelPlanModeReadOnly string // user-facing label for plan-mode read-only command trust approvals
190 MemoryApprovalSaveUpdate string // subject prefix for remember approval
191 MemoryApprovalBodyLabel string // label before the body excerpt in remember approval
192 MemoryApprovalArchiveFmt string // subject for forget approval, %q = memory name
193 PlanModeBashTrustSubjectFmt string // subject for bash read-only prefix trust approval, prefix + command
194 PlanModeBashTrustReason string // reason for bash read-only prefix trust approval
195 PlanModeBashTrustDeclined string // model-facing denial after bash read-only prefix rejection
196 SandboxEscapeSubjectFallback string // fallback subject for a one-shot unconfined sandbox escape approval
197 SandboxEscapeSubjectPrefix string // subject prefix before the shell command for one-shot unconfined escape approval
198 SandboxEscapeWrapReason string // reason when no OS sandbox can wrap the command
199 SandboxEscapeRuntimeReason string // fallback reason when an OS sandbox cannot start the command
200 SandboxEscapeDeclined string // model-facing denial when the user declines a one-shot unconfined retry
201 ApprovalToolLabelConfigWrite string // user-facing label for Reasonix-managed config write approvals
202 ConfigWriteSubjectPrefix string // subject prefix before the config file path for managed config write approval
203 ConfigWriteReason string // reason shown for managed config write approval
204 ConfigWriteDeclined string // model-facing denial when the user declines a managed config write
205 ConfigWriteApprovalChoices string // approval choice list for managed config write prompts
206 WriteAccessApprovalChoices string // four-choice list for extending writable roots
207 WriteAccessHomeWarning string // high-risk warning when granting the whole home directory
208 WriteAccessMergedPermissionHint string // note that the same choice also grants ordinary tool permission
209 WriteAccessProjectHint string // note that project persist edits reasonix.toml
210 PermissionSavedFmt string // permission rule saved notice: path, rule
211 PermissionAlreadyAllowedFmt string // permission rule already covered notice: path, rule
212 PermissionSaveFailedFmt string // permission rule save failure notice: rule, error
213 PlanModeReadOnlyCommandTrustSavedFmt string // plan-mode bash read-only prefix saved notice: path, prefix
214 PlanModeReadOnlyCommandTrustAlreadyFmt string // plan-mode bash read-only prefix already covered notice: path, prefix
215 PlanModeReadOnlyCommandTrustFailedFmt string // plan-mode bash read-only prefix save failure notice: prefix, error
216 DiffFoldedFmt string // "… +%d more lines" footer when a writer diff is folded
217 DiffFoldEnabledFmt string // notice when /diff-fold enables folding, %d = line limit
218 DiffFoldDisabled string // notice when /diff-fold disables folding (shows all lines)
219
220 // `ask` tool question card.
221 AskTypeSomething string // the "type your own answer" option label
222 AskTypingHint string // shown on that row while entering free text
223 AskChatInstead string // the "don't pick, just chat" option label
224 ChatStatusQuestion string // shortcuts hint while a question card is open
225 StatusResumePicker string // status tag while the resume picker is open (e.g. "select session")
226 AskSubmitTitle string // submit-tab title in the ask tool question card
227 AskUnanswered string // placeholder for an unanswered ask question
228 AskSubmitHint string // submit-tab keyboard hint
229 ElicitURLHint string // url-mode elicitation keyboard hint
230 ElicitConfirmOnly string // schema-less form elicitation hint
231 ElicitUnanswered string // placeholder for an unanswered elicitation field
232 ElicitSubmit string // elicitation submit row label
233 ElicitSubmitHint string // elicitation keyboard hint
234
235 // output style listing (/output-style).
236 OutputStyleNone string // no styles available
237 ThemeHeader string // header above the /theme listing
238 ThemeHint string // how to select a theme
239 ThemeChangedFmt string // "/theme <name>" succeeded
240 ThemeUnknownFmt string // "/theme <name>" unknown
241 LanguageHeader string // header above the /language listing
242 LanguageHint string // how to select a language
243 LanguageChangedFmt string // "/language <tag>" succeeded, %s = saved tag, %s = resolved tag
244 CurrencyHeader string // header above the /currency listing
245 CurrencyHint string // how to select a pricing currency
246 CurrencyChangedFmt string // "/currency <mode>" succeeded, %s = saved mode, %s = resolved currency
247 RuntimeRefreshBusy string // runtime-affecting setting cannot change while work is active
248 RuntimeRefreshUnavailable string // current session cannot rebuild after a runtime-affecting setting change
249
250 // context compaction card (CompactionStarted / CompactionDone events).
251 CompactionWorking string // shown while the summarizer runs
252 CompactionTitle string // card header before "· N messages · <trigger>"
253 CompactionUnit string // the noun counted, e.g. "messages"
254 CompactionAuto string // trigger label: reached the window threshold
255 CompactionManual string // trigger label: user ran /compact
256 CompactionStopping string // cancellation has been requested
257 CompactionSaving string // a committed result is being persisted
258 CompactionNoHistory string // the selected history has nothing to fold
259 CompactionStopped string // cancelled before applying a projection
260 CompactionStoppedPartial string // cancelled after at least one applied batch
261 CompactionRecoveryRequired string // persistence/cancellation state needs recovery
262 CompactionInterrupted string // a previous non-terminal operation was interrupted
263 CompactionEstimatedTokens string // label for estimated before/after token counts
264
265 // extension structured-UI surfaces (ExtensionSurface / ExtensionStatus events).
266 ExtFormFieldsHint string // form card: field values are collected through the usual prompts
267 ExtRunActionFmt string // card action hint, one %s = the /<plugin>:<action> slash name
268
269 // chat TUI slash commands.
270 SlashCompactFailed string // "/compact" errored, prefixed before the underlying error
271 SlashNewDone string // "/new" succeeded
272 SlashNewFailed string // "/new" errored
273 SlashClearPrompt string // "/clear" destructive confirmation prompt
274 SlashClearDone string // "/clear" succeeded
275 SlashClearFailed string // "/clear" errored
276 SlashClsDone string // "/cls" succeeded
277 SlashTodoCleared string // "/todo" dismissed the pinned task list
278 SlashUnknown string // shown when the user types an unrecognised "/cmd"
279 SlashUnknownSentAsMessage string // suffix: the unrecognised "/cmd" line was sent as a regular message
280 SlashPromptEmpty string // an MCP prompt returned no text to send
281 SlashMCPNone string // /mcp when no MCP servers are connected
282 CtrlCQuitHint string // shown on first Ctrl+C while idle; second press exits
283 CompHintSlash string // key hint footer under the slash-command menu
284 CompHintFile string // key hint footer under the @ file/resource menu
285 MouseCopiedHint string // transient status-line hint after a mouse/Ctrl+C selection copy
286 ClipboardCopyOSC52Hint string // copy was sent through OSC 52 because the session is remote
287 ClipboardCopyFallbackHint string // native clipboard failed and copy fell back to OSC 52
288 ClipboardTextPasteRemoteHint string // mouse paste cannot read the user's local clipboard/PRIMARY selection over SSH
289 ClipboardTextPasteFailedFmt string // text clipboard read failed, one %v
290 ClipboardImagePastingHint string // shown while an image is being read from the system clipboard
291 ClipboardPasteEmptyNotice string
292 ClipboardImagePasteFailedFmt string // image clipboard read failed, one %v
293 MouseCaptureOnHint string // "/mouse" turned in-app mouse handling back on
294 MouseCaptureOffHint string // "/mouse" released mouse capture to the terminal
295 MouseCaptureTag string // persistent status-line marker while mouse capture is off
296
297 // shell execution (! prefix).
298 ShellExecEmpty string // bare "!" with no command
299 ShellExecFailedFmt string // "shell command failed: %v"
300 ShellExecTimeoutFmt string // "shell command timed out (> %s)"
301 ShellModeHint string // status line hint when input starts with !
302
303 // slash command + sub-command descriptions shown in the menu (CLI and desktop
304 // share these via i18n.M, so both frontends localize identically).
305 CmdNew string // /new
306 CmdClear string // /clear
307 CmdCls string // /cls
308 CmdCompact string // /compact
309 CmdContinueChecks string // /continue-checks
310 CmdContext string // /context
311 CmdRewind string // /rewind
312 CmdTree string // /tree
313 CmdBranch string // /branch
314 CmdSwitchBranch string // /switch
315 CmdResume string // /resume
316 CmdRename string // /rename
317 CmdModel string // /model
318 CmdStatus string // /status
319 CmdWorkMode string // /work-mode
320 CmdDocs string // /docs
321 CmdMemory string // /memory
322 CmdMigrate string // /migrate
323 CmdGoal string // /goal
324 CmdRemember string // /remember
325 CmdForget string // /forget
326 CmdMcp string // /mcp
327 CmdRemote string // /remote
328 CmdHooks string // /hooks
329 CmdPlugins string // /plugins
330 CmdPasteImage string // /paste-image
331 CmdOutputStyle string // /output-style
332 CmdTheme string // /theme
333 CmdLanguage string // /language
334 CmdCurrency string // /currency
335 CmdSkill string // /skills
336 CmdVerbose string // /verbose
337 CmdReloadCmd string // /reload-cmd
338 CmdReload string // /reload
339 CmdDiffFold string // /diff-fold
340 CmdSandbox string // /sandbox
341 CmdEffort string // /effort
342 CmdMouse string // /mouse
343 CmdReasonLang string // /reasoning-language
344 CmdHelp string // /help
345 CmdWeb string // /web
346 CmdTodo string // /todo
347 CmdQuit string // /quit (also accepts /exit as hidden alias)
348 CmdCopy string // /copy
349 CmdExport string // /export
350 SlashCopyDone string // "/copy" succeeded
351 SlashCopyEmpty string // no assistant response to copy
352 SlashCopyListHeader string // header shown before the numbered list
353 SlashExportDoneFmt string // "/export" succeeded, %s = file path
354 SlashExportEmpty string // no messages to export
355 ArgSkillShow string // /skills show
356 ArgSkillNew string // /skills new
357 ArgSkillPaths string // /skills paths
358 ArgMcpAdd string // /mcp add
359 ArgMcpRemove string // /mcp remove
360 ArgMcpConnected string // /mcp remove <server> tag
361 ArgHooksList string // /hooks list
362 ArgModelCurrent string // /model <ref> active tag
363 ArgEffortAuto string // /effort auto
364 ArgEffortLow string // /effort low
365 ArgEffortMedium string // /effort medium
366 ArgEffortHigh string // /effort high
367 ArgEffortXHigh string // /effort xhigh
368 ArgEffortMax string // /effort max
369 ArgPresetStandard string // /preset standard
370 ArgPresetDelivery string // /preset delivery
371 ArgThemeCurrent string // /theme <style> active tag
372 ArgLanguageAuto string // /language auto
373 ArgLanguageEn string // /language en
374 ArgLanguageZh string // /language zh
375
376 // management listing notices (the Submit path: desktop / HTTP frontends)
377 ListModelsHeaderFmt string // "models (active: %s)"
378 ListModelsHint string // how to switch
379 ListMemorySaved string // "saved memories"
380 ListMemoryArchived string // "archived memories"
381 ListMemoryNone string // no memory docs
382 ListSkillsHeaderFmt string // "skills (%d)"
383 ListSkillsNone string // no skills
384 ListHooksHeaderFmt string // "hooks (%d active)"
385 ListHooksNone string // no hooks
386 ListMcpHeader string // "mcp servers"
387 ListMcpNone string // no mcp servers
388
389 // in-chat memory/model/rewind notices.
390
391 MemoryEditHint string
392 ForgetUsage string
393 ForgetDoneFmt string
394 QuickRememberEmpty string
395 QuickRememberDoneFmt string
396 GoalEmpty string
397 GoalCurrentFmt string
398 GoalSetFmt string
399 GoalCleared string
400 GoalNotRunning string
401 GoalNotPaused string
402 GoalPaused string
403 GoalPausedReason string
404 GoalPausedFmt string // %s = stop cause
405 GoalRuntimeFmt string // turns, requests, tokens, work duration
406 GoalRuntimeLastReason string
407 ModelSwitchUnavailable string
408 ModelSwitchBusy string
409 ModelAlreadyOnFmt string
410 ModelSwitchingFmt string
411 ModelSwitchedFmt string
412 ModelListHeader string
413 RuntimeSwitchPending string
414 RuntimeReloadQueued string // /reload queued behind active work; the idle drain runs it
415 RuntimeReloaded string // /reload completed (no generation available)
416 RuntimeReloadedGenerationFmt string // /reload completed; %d is the runtime build generation
417 WorkModeUsage string
418 // WorkModeDeprecatedNotice is shown once when a legacy /work-mode or
419 // /profile command is used. Prefer /preset.
420 WorkModeDeprecatedNotice string
421 // QualityFloorApplied confirms a quality floor switch.
422 QualityFloorApplied string
423 RewindNone string
424 RewindCodeConversation string
425 RewindConversationOnly string
426 RewindCodeOnly string
427 RewindFork string
428 RewindSummarizeFrom string
429 RewindSummarizeUpto string
430 RewindPickTitle string
431 RewindPickHint string
432 RewindRestoreTitleFmt string
433 RewindApplyHint string
434 RewindCoverageTitle string
435 RewindCoverageWarningFmt string
436 RewindConfirmHint string
437 RewindUnavailableFmt string
438 RewindEmpty string
439
440 // skill picker overlay (/skills interactive panel in CLI TUI)
441 SkillPickerAvailableFmt string
442 SkillPickerMatchingFmt string // "%d matching · %d total" when searching
443 SkillPickerHint string
444 SkillPickerDetailHint string
445 SkillPickerSearchEmpty string
446 SkillPickerSearchPlaceholder string
447 SkillPickerSourceTitle string
448 SkillPickerSourceActiveFmt string
449 SkillPickerSourceHint string
450 SkillPickerDiagHidden string
451 SkillPickerDiagShown string
452 SkillPickerBuiltinSource string
453 SkillPickerRescanned string
454 SkillPickerNoDescription string
455 SkillPickerScopeProject string
456 SkillPickerScopeCustom string
457 SkillPickerScopeGlobal string
458 SkillPickerScopeBuiltin string
459 SkillPickerSubagent string
460 SkillPickerAvailableLabel string
461 SkillPickerDisabledLabel string
462 SkillPickerNoChanges string
463 SkillPickerSourceSkillsHint string
464 SkillPickerSourceSkillsEmpty string
465 SkillPickerActionToggle string
466 SkillPickerActionDelete string
467 SkillPickerDeleteTitleFmt string // "Delete skill %s?"
468 SkillPickerDeleteConfirm string
469 SkillPickerDeleteCancel string
470 SkillPickerDeleteHint string
471 SkillPickerDeletedFmt string // "deleted skill %s"
472 SkillPickerMoreAboveFmt string // "↑ %d more above"
473 SkillPickerMoreBelowFmt string // "↓ %d more below"
474 SkillPickerTokenFmt string // "~%d tok"
475 SkillPickerDetailMetaFmt string // "Scope: %s Run as: %s"
476 SkillPickerSkillsUnit string // "skills" (used as "%d skills")
477 SkillPickerLinesUnit string // "lines" (used as "+N more lines")
478 SkillPickerStatusLabel string // shown in the TUI status bar while picker is open
479 SkillPickerStatusOK string // "ok" path status label
480 SkillPickerStatusMissing string // "missing" path status label
481 SkillPickerStatusNotDir string // "not-directory" path status label
482 SkillPickerStatusUnreadable string // "unreadable" path status label
483
484 // init wizard
485 EnterAPIKeysHeader string // header before the per-env-var prompts
486 WroteFileFmt string // "Wrote %s" — used for reasonix.toml and .env both
487 SetupComplete string // success line at end of init
488 SetupCancelled string // shown when the user aborts the wizard
489 TryHintFmt string // "Try: %s" — %s = command to try (styled)
490 NextHint string // non-interactive post-write hint
491 ConfirmReconfigureFmt string // "%s already exists. Reconfigure and overwrite?"
492 NotOverwritingFmt string // non-interactive overwrite refusal
493 SetupManagerTitle string
494 SetupAddOpenAI string
495 SetupAddAnthropic string
496 SetupProviderExistsFmt string
497 SetupSaveExit string
498 SetupSaveExitDesc string
499 SetupCancel string
500 SetupCancelDesc string
501 SetupModelsUnit string
502 SetupKeySet string
503 SetupKeyMissing string
504 SetupDefaultBadge string
505 SetupProviderActionsFmt string
506 SetupEditProvider string
507 SetupUpdateKey string
508 SetupTestRefresh string
509 SetupSetDefault string
510 SetupRemoveProvider string
511 SetupBack string
512 SetupPromptModels string
513 SetupSharedKeyWarningFmt string
514 SetupKeyEnvTakenFmt string
515 SetupKeyEnvStoredFmt string
516 SetupKeyEnvSettingFmt string
517 SetupKeyEnvShellFmt string
518 SetupKeyEnvRetry string
519 SetupPromptAPIKeyFmt string
520 SetupSelectDefaultModel string
521 SetupConfirmRemoveFmt string
522 SetupSummaryTitle string
523 SetupSummaryAddedFmt string
524 SetupSummaryEditedFmt string
525 SetupSummaryRemovedFmt string
526 SetupSummaryDefaultFmt string
527 SetupSummaryKeysFmt string
528 SetupSummaryNoChanges string
529 SetupConfirmSave string
530 SetupConcurrentChangeFmt string
531
532 // model fetching
533 FetchingModelsFmt string // "Fetching models for %s..."
534 FetchModelsSuccessFmt string // "Found %d models for %s"
535 FetchModelsFailedFmt string // "Failed to fetch models for %s: %v"
536 FetchModelsUsingPresetsFmt string // "Live fetch unavailable for %s, using preset model list"
537 SelectModelsLabel string // "Select models to enable for %s"
538 CustomFetchEmpty string // "/models returned an empty list — falling back to manual entry"
539 AnthropicFetchEmpty string // "/models returned an empty list — Anthropic-compatible providers usually don't expose one, falling back to manual entry"
540 APIKeyAlreadySetFmt string // "reusing existing value for %s"
541 APIKeyResetPromptFmt string // "Re-enter %s?"
542 InvalidAPIKeyEnvFmt string // "%q is not a valid API Key variable name..."
543 RepairedAPIKeyEnvFmt string // "provider %s: replaced invalid api_key_env %q with %q"
544
545 // custom provider
546 CustomProviderDesc string // "Add third-party OpenAI compatible model"
547 CustomAddMethodLabel string // "Select add method"
548 CustomMethodManual string // "Enter model name manually"
549 CustomMethodURL string // "Fetch models from URL"
550 CustomPromptModel string // "Enter model name"
551 CustomPromptBaseURL string // "Enter Base URL"
552 CustomPromptKeyEnv string // "Enter API Key env var name"
553 CustomPromptAPIKey string // "Enter API Key"
554 CustomPromptWindow string // "Enter context window in tokens"
555 CustomAddedFmt string // "Added custom model: %s"
556
557 // Anthropic compatible provider
558 AnthropicProviderDesc string // "Add Anthropic API compatible model"
559 AnthropicAddMethodLabel string // "Select add method"
560 AnthropicMethodManual string // "Enter model name manually"
561 AnthropicMethodURL string // "Fetch models from URL"
562 AnthropicPromptModel string // "Enter model name"
563 AnthropicPromptBaseURL string // "Enter Base URL"
564 AnthropicPromptKeyEnv string // "Enter API Key env var name"
565 AnthropicPromptAPIKey string // "Enter API Key"
566 AnthropicAddedFmt string // "Added Anthropic compatible model: %s"
567 AnthropicFetchingModelsFmt string // "Fetching models for %s..."
568 AnthropicFetchModelsSuccessFmt string // "Found %d models for %s"
569 AnthropicFetchModelsFailedFmt string // "Failed to fetch models for %s: %v"
570 AnthropicSelectModelsLabel string // "Select models to enable for %s"
571
572 // remote SSH module
573 RemoteConnectingFmt string // "connecting to %s…"
574 RemoteConnectedFmt string // "connected to %s"
575 RemoteReconnectingFmt string // "reconnecting to %s (attempt %d)…"
576 RemoteDegradedFmt string // "connected to %s but some forwards are down"
577 RemoteDisconnected string // "disconnected"
578 RemoteServeReadyFmt string // "remote serve ready: %s"
579 RemoteHostKeyPromptFmt string // "host %s key (%s): %s"
580 RemotePassphrasePromptFmt string // "passphrase for %s:"
581 RemotePasswordPromptFmt string // "password for %s:"
582 RemoteBootstrapStepFmt string // "remote serve: %s %s"
583 RemoteNoHostsHint string // "no remote hosts configured; add one with `reasonix remote add`"
584
585 // top-level / runAgent
586 UnknownCommandFmt string // "unknown command %q"
587 UsageRunHint string // "usage: reasonix run [--model NAME] <task>"
588 ErrorPrefix string // "error:" — prefix for fatal-error output
589 ReconfigureOnUnknownModel string // shown when the configured model no longer resolves and setup is re-run
590 WriteConfigErr string // "write config:" — prefix for write failure
591 WriteEnvErr string // "write .env:" — prefix for env-write failure
592
593 // provider HTTP error explanations — actionable, reason + fix per status code
594 ProviderErrBadRequest string // 400
595 ProviderErrContextOverflowFmt string // 400/413/422 shared-window overflow with numbers
596 ProviderErrAuth string // 401 — no key configured / sent
597 ProviderErrAuthRejected string // 401 — a key was sent but the server rejected it
598 ProviderErrModelFormatMismatch string // provider rejected the model on the selected wire format
599 ProviderErrOpenCodeGoGrokRoute string // recovery hint for OpenCode Go Grok routing
600 ProviderErrQuotaExhaustedFmt string // provider name, actual HTTP status
601 ProviderErrReasonMissing string
602 ProviderErrStreamInterruptedFmt string
603 ProviderErrDisconnectedFmt string
604 ProviderErrNonStreamingFmt string
605 SearchSourcesNotProvided string
606 SearchModelUnavailable string
607 ProtocolRecoveryLabel string
608 ProviderErrInsufficientBalance string // 402
609 ProviderErrNotFound string // 404
610 ProviderErrUnprocessable string // 422
611 ProviderErrInputSensitive string // MiniMax 1026
612 ProviderErrOutputSensitive string // MiniMax 1027
613 ProviderErrRateLimited string // 429
614 ProviderErrServer string // 500
615 ProviderErrServerBusy string // 503
616 ProviderErrWaitExhaustedFmt string // total time waited before giving up
617
618 // selection menus
619 SelectOneHint string // "(↑/↓ · Enter · q to cancel)"
620 SelectManyHint string // "(↑/↓ · Space · Enter · q)"
621 SelectMoreAboveFmt string // "↑ %d more above"
622 SelectMoreBelowFmt string // "↓ %d more below"
623 SelectSearchHint string // "/ to search · Esc to cancel"
624
625 // /provider command
626 CmdProvider string // /provider
627 ProviderListHeader string // header for /provider list
628 ProviderAlreadyOnFmt string // already on provider
629 ProviderUnknownFmt string // unknown provider
630 ProviderPickLabel string // label for provider model picker
631 ProviderNoModelsFmt string // provider has no models
632
633 // `reasonix upgrade` / `reasonix update` — self-update
634 UpgradeChecking string // "Checking for updates…"
635 UpgradeChannelDeprecated string // legacy channel selection is ignored
636 UpgradeDevBuild string // dev builds cannot self-update
637 UpgradeFetchFailed string // "failed to check for updates: %v"
638 UpgradeInvalidVersion string // remote version not valid semver
639 UpgradeAlreadyLatest string // already on the latest version
640 UpgradeForcing string // "Reinstalling the same version…"
641 UpgradeAvailableFmt string // "Current: %s → Latest: %s"
642 UpgradeNoAssetFmt string // "no binary found for %s"
643 UpgradeDownloadingFmt string // "Downloading %s (%s)…"
644 UpgradeDownloadFailed string // "download failed: %v"
645 UpgradeVerifying string // "Verifying checksum…"
646 UpgradeChecksumFailed string // "could not fetch checksum file: %v"
647 UpgradeChecksumMismatchFmt string // SHA256 mismatch detail
648 UpgradeChecksumNotFoundFmt string // asset not listed in SHA256SUMS
649 UpgradeExtractFailed string // "failed to extract binary: %v"
650 UpgradeApplying string // "Replacing binary…"
651 UpgradeApplyFailed string // "failed to apply update: %v"
652 UpgradeSuccessFmt string // "Updated %s → %s"
653
654 // `reasonix report` — local CLI crash review and explicit upload
655 ReportNoPending string
656 ReportHeaderFmt string
657 ReportCapturedFmt string
658 ReportPreviewOnlyFmt string
659 ReportSendPrompt string
660 ReportKept string
661 ReportDeletedFmt string
662 ReportSentFmt string
663 ReportConfigFailedFmt string
664 ReportUploadFailedFmt string
665 ReportSentDeleteFailedFmt string
666 ReportUsageBody string
667
668 // First eligible interactive CLI telemetry consent.
669 CLITelemetryConsentNotice string
670 CLITelemetryConsentPrompt string
671 CLITelemetryConsentInvalid string
672 CLITelemetryConsentSaveFailedFmt string
673 CLITelemetryConsentCleanupFailedFmt string
674
675 // usage / help
676 UsageBody string // full multi-line help text
677 }
678
679 // ProviderStatusMessage returns an actionable explanation for a known provider
680 // HTTP status, or "" when the status has no specific guidance.
681 func (m Messages) ProviderStatusMessage(status int) string {
682 switch status {
683 case 400:
684 return m.ProviderErrBadRequest
685 case 401, 403:
686 return m.ProviderErrAuth
687 case 402:
688 return m.ProviderErrInsufficientBalance
689 case 404:
690 return m.ProviderErrNotFound
691 case 422:
692 return m.ProviderErrUnprocessable
693 case 429:
694 return m.ProviderErrRateLimited
695 case 500:
696 return m.ProviderErrServer
697 case 503:
698 return m.ProviderErrServerBusy
699 }
700 return ""
701 }
702
703 // M is the active catalogue. DetectLanguage replaces it; English is the
704 // default so any code path that runs before detection still has text.
705 var (
706 M = English
707 currentLanguage = "en"
708 )
709
710 // CurrentLanguage returns the language tag installed by the latest
711 // DetectLanguage call. It lets frontends reuse the resolved locale without
712 // re-reading the environment and accidentally ignoring an explicit override.
713 func CurrentLanguage() string {
714 return currentLanguage
715 }
716
717 // DetectLanguage selects a catalogue from override (e.g. cfg.Language) or the
718 // environment and installs it as M. Returns the resolved tag ("en", "zh") so
719 // callers can log or expose it.
720 //
721 // Priority: override > REASONIX_LANG > LC_ALL > LC_MESSAGES > LANG > "en".
722 func DetectLanguage(override string) string {
723 for _, c := range append([]string{override}, envCandidates()...) {
724 if tag := normalize(c); tag != "" {
725 return setLanguage(tag)
726 }
727 }
728 return setLanguage("en")
729 }
730
731 func envCandidates() []string {
732 keys := []string{"REASONIX_LANG", "LC_ALL", "LC_MESSAGES", "LANG"}
733 out := make([]string, len(keys))
734 for i, k := range keys {
735 out[i] = os.Getenv(k)
736 }
737 return out
738 }
739
740 func setLanguage(tag string) string {
741 switch tag {
742 case "zh-tw", "zh-TW":
743 M = ChineseTraditional
744 currentLanguage = "zh-TW"
745 case "zh":
746 M = Chinese
747 currentLanguage = "zh"
748 default:
749 M = English
750 currentLanguage = "en"
751 }
752 return currentLanguage
753 }
754
755 // normalize maps a locale string (e.g. "zh_CN.UTF-8", "zh-Hans-CN", "Chinese
756 // (China)") to a short tag this package knows about. Returns "" for empty or
757 // unrecognised input so DetectLanguage can fall through to the next candidate.
758 func normalize(s string) string {
759 s = strings.ToLower(strings.TrimSpace(s))
760 s = strings.ReplaceAll(s, "_", "-") // zh_TW.UTF-8 → zh-tw.utf-8 (POSIX locales use underscores)
761 if s == "" {
762 return ""
763 }
764 if strings.HasPrefix(s, "zh-tw") || strings.HasPrefix(s, "zh-hant") || strings.Contains(s, "chinese traditional") || strings.Contains(s, "繁體") {
765 return "zh-TW"
766 }
767 if strings.HasPrefix(s, "zh") || strings.Contains(s, "chinese") || strings.Contains(s, "中文") {
768 return "zh"
769 }
770 if strings.HasPrefix(s, "en") || strings.Contains(s, "english") {
771 return "en"
772 }
773 return ""
774 }
775
775 lines GO