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