pub enum Msg<'a> {
// WelcomeWizard
WelcomeBannerLine1,
WelcomeBannerLine2,
WelcomeOptionCodingPlan,
WelcomeOptionCodingPlanHint,
WelcomeOptionConfigureManually,
WelcomeOptionConfigureManuallyHint,
WelcomeOptionSkip,
WelcomeOptionSkipHint,
// ── /login (full setup flow) ──
CodingPlanSetupFailed { error: &'a str },
/// Emitted inline by `/login` and `atomcode login` when the stored
/// OAuth token comes back 401 from the CodingPlan API mid-flow.
/// We re-run the OAuth dance, save the fresh token, and retry the
/// whole setup once — this line tells the user that's what's about
/// to happen so the second "Open this URL in any browser…" block
/// isn't a surprise.
CpReauthAfter401,
/// Emitted by the OpenAI provider when an AtomGit-gateway chat
/// request returns 401 and our one automatic refresh_token attempt
/// either failed or the retried request still came back 401. The
/// raw server message ("Gitcode auth: token rejected") is not
/// useful to end users — this replaces it with an actionable hint
/// pointing at `/login`. Non-atomgit gateways still surface the
/// verbatim server error so user-supplied API keys (sk-...) get
/// the diagnostic detail.
ChatAuthExpired,
// SetupReport renderer (core/coding_plan/setup.rs)
CpSetupHeader,
CpLoggedIn { who: &'a str, username: &'a str, email: &'a str },
CpStepSkipped { reason: &'a str },
CpLoginFailed { error: &'a str },
CpClaimed { message: &'a str, plan_type: &'a str },
CpClaimSuccessFallback,
CpAlreadyClaimed { reason: &'a str },
CpClaimFailed { error: &'a str },
/// Same as `CpClaimFailed` but with no trailing detail body.
/// Used in the rare edge case where every tier returned success=
/// false with an empty server message AND no transport error
/// text — there's nothing to put after `— `, so the line stops
/// at the prefix.
CpClaimFailedBare,
/// Per-tier cascade row — winning tier, fresh claim.
/// Example (zh-CN): ` ✓ CodingPlan Lite 领取成功`
CpClaimTierSucceeded { tier: &'a str },
/// Per-tier cascade row — winning tier, server reported the user
/// already holds this tier or higher (`duplicate=true`).
CpClaimTierAlreadyHeld { tier: &'a str },
/// Per-tier cascade row — tier was refused (2xx with success=
/// false / 5xx / transport). `reason` is the server's human-
/// readable message (e.g. `额度已满`, `暂无开放`) or a short
/// rendering of the transport error.
CpClaimTierFailed { tier: &'a str, reason: &'a str },
CpAddedProviders { count: usize, plural_s: &'a str },
/// Locked-model row. `name` is expected to be pre-decorated with
/// U+0336 combining strikethrough by the caller (see
/// `coding_plan::setup::strikethrough`), so the template itself
/// stays a plain `format!` and survives every renderer's CSI
/// scrubber without needing SGR escapes.
CpLocked { name: &'a str },
CpProviderRow { provider: &'a str, model: &'a str, default_suffix: &'a str },
CpDefaultSuffix,
CpVisionAuto { kind: &'a str },
CpVisionUserSupplied { kind: &'a str },
CpVisionCleared,
CpModelsSkipped { reason: &'a str },
CpModelsFailed { error: &'a str },
CpStatusHeader,
CpPlanPending { plan: &'a str },
CpPlanActive {
plan: &'a str,
expires_at: &'a str,
remaining_days: i32,
total_days: i32,
},
CpUsageLine { usage: &'a str, reset_at: &'a str, duration: &'a str },
CpMonthlyQuotaExhausted { duration: &'a str },
CpWindowQuotaExhausted,
CpWindowQuotaHint { hint: &'a str },
CpStatusFetchSkipped { reason: &'a str },
CpStatusFetchFailed { error: &'a str },
/// Open-source build attempted to use a CodingPlan provider. The
/// signing capability is not present in this build, so the request
/// can't reach the AtomGit LLM gateway. Surface a clear hint
/// pointing to the official Releases page.
CpOfficialBuildRequired,
/// Official build, but no stored auth (or auth has empty
/// `user.id` / `access_token`). The signing path needs these
/// fields to derive a per-user key; without them the request
/// can't be signed. Surface a "please run `/codingplan` to log
/// in" hint instead of the misleading "official build required"
/// message — the user IS on an official build.
CpAuthRequired,
/// Server returned `ATOMCODE_SIG_STALE` — the request's signed
/// timestamp is outside the ±5min window the gateway accepts.
/// Typically caused by an unsynced local clock.
CpSignStaleClockSkew,
/// Server returned `ATOMCODE_SIG_REPLAY` even after the client's
/// one automatic retry with a fresh nonce. Surface a "please retry
/// the command" hint — usually self-heals on the next attempt.
CpSignReplayPersisted,
/// Server returned `ATOMCODE_SIG_INVALID` AND the alg_version is
/// no longer in the server's `accepted_versions` set — the client
/// binary is too old. Force-upgrade hint.
CpSignVersionTooOld,
/// Server returned `426 Upgrade Required` — emergency rotation
/// playbook in progress; this build cannot continue without
/// upgrading.
CpUpgradeRequired,
// i18n self-errors
ErrUnsupportedLocale { input: &'a str },
// ── Status bar (build_status) ──
StatusNoProvider,
/// Open-source build with an AtomGit-gateway provider configured.
/// Sending any chat will fail with `CpOfficialBuildRequired`; this
/// hint surfaces the same diagnosis up-front so the user doesn't
/// have to type a message to discover the dead-end.
StatusOfficialBuildRequired,
StatusUpgradeHint { version: &'a str },
/// Right-aligned status-row hint, HarmonyBrew variant: a newer version
/// exists, upgrade via the package manager rather than `/upgrade`.
StatusUpgradeHintPm { version: &'a str },
StatusModelNotConfigured,
/// macOS / Linux variant: "Image in clipboard · ctrl+v to paste".
/// Ctrl+V is intercepted by Windows Terminal / conhost before
/// reaching atomcode, so Windows builds emit
/// `StatusClipboardImageHintSlash` instead.
StatusClipboardImageHint,
/// Windows variant: "Image in clipboard · /paste". Tells the
/// user to fall back on the `/paste` slash command, which works
/// in every terminal regardless of host keybinds.
StatusClipboardImageHintSlash,
/// Lowest-priority status-row fallback: nudge the user toward the
/// `/webui` command (browser UI) when no higher-priority hint
/// (warnings / usage / upgrade) is competing for the slot.
StatusWebuiHint,
// ── /status command body ──
StatusBody { model: &'a str, dir: &'a str, config: &'a str, tokens: usize },
StatusCpNotSignedIn,
StatusCpFetchFailed { error: &'a str },
StatusCpNoActive,
StatusCpLine {
plan: &'a str,
expires_at: &'a str,
remaining_days: i32,
total_days: i32,
},
StatusCpUsage { usage: &'a str, reset_at: &'a str, duration: &'a str },
StatusCpMonthlyExhausted { duration: &'a str },
StatusCpWindowExhausted,
StatusCpWindowHint { hint: &'a str },
StatusInstructionFilesHeader,
StatusInstructionPresent { path: &'a str, label: &'a str },
StatusInstructionMissing { label: &'a str },
// ── Help / commands ──
HelpAvailableCommands,
/// Full keyboard-shortcuts reference dumped to scrollback by the
/// `/keys` slash command. Carries every line of the panel as a
/// single multi-line string so translators can adjust column
/// alignment per locale without rebuilding rows in Rust.
KeybindingsHelp,
// ── Provider wizard ──
ProviderWizardHeader,
ProviderWizardCancelled,
ProviderMenuAdd,
ProviderMenuAddDesc,
ProviderMenuEdit,
ProviderMenuEditDesc,
ProviderMenuDelete,
ProviderMenuDeleteDesc,
ProviderMenuSetDefault,
ProviderMenuSetDefaultDesc,
ProviderImportPrompt,
ProviderImportParsed { base_url: &'a str, type_name: &'a str, model: &'a str },
ProviderImportFailed,
ProviderNoProviders,
ProviderDeleteConfirm { name: &'a str },
ProviderDeleted { name: &'a str },
ProviderDeleteKept,
ProviderDefaultSet { name: &'a str },
ProviderAdded { name: &'a str, model: &'a str },
ProviderUpdated { name: &'a str },
ProviderStepName,
ProviderStepType,
ProviderStepTypeWithHint { current: &'a str },
ProviderStepBaseUrl,
ProviderStepBaseUrlWithHint { current: &'a str },
ProviderDefaultHint,
ProviderStepApiKey,
ProviderStepApiKeyWithHint { hint: &'a str },
ProviderStepApiKeySet,
ProviderStepApiKeyUnset,
ProviderStepModel,
ProviderStepModelWithHint { current: &'a str },
ProviderNameEmpty,
ProviderBaseUrlEmpty,
ProviderUnknownType,
ProviderUnknownTypeEdit,
ProviderModelEmpty,
ProviderEditKeep,
ProviderTypeInferred { type_name: &'a str },
ProviderStepNameDefault { default: &'a str },
ProviderStepProgress { current: usize, total: usize },
// ── Model picker ──
ModelSwitched { provider: &'a str, model: &'a str },
// ── Session picker ──
SessionLoadFailed { error: &'a str },
SessionResumedLabel { name: &'a str },
SessionTimeJustNow,
SessionTimeMinAgo { n: u64 },
SessionTimeHourAgo { n: u64 },
SessionTimeDayAgo { n: u64 },
SessionMsgCount { count: usize },
SessionNameEmpty,
SessionNameTooLong { max: usize },
SessionNameControlChars,
SessionListFailed { error: &'a str },
SessionRenamed { old: &'a str, new: &'a str },
SessionSaveFailed { error: &'a str },
SessionNoneSelected,
SessionRenameEditing { buffer: &'a str },
// ── Dir picker ──
DirCurrent,
DirNotExists { path: &'a str },
DirChanged { path: &'a str },
DirNotADirectory { path: &'a str },
// ── Issue wizard ──
IssueCancelled,
IssueNewOn { owner: &'a str, repo: &'a str },
IssueStep1,
IssueStep2,
IssueTitleConfirmed { title: &'a str },
IssueRequiredField { field: &'a str },
IssueCreated { number: u64, title: &'a str, url: &'a str },
IssueCreateFailed { error: &'a str },
// ── Language ──
/// Confirmation rendered to scrollback after the user picks a
/// locale via `/language` (modal or arg). Already includes the
/// leading " " indent and trailing "\n" so the call site is just
/// `renderer.render(UiLine::CommandOutput(t(Msg::LanguageSwitched
/// { ... }).into_owned()))`.
LanguageSwitched { label: &'a str, locale: &'a str },
// ── Idle / onboarding hints ──
/// "type something, or press " (text before the slash)
IdleHintPrefix,
/// "/" (the slash shortcut itself — kept separate for accent styling)
IdleHintSlash,
/// " to browse commands" (text after the slash)
IdleHintSuffix,
/// Complete plain-text version: "type something, or press / to browse commands"
IdleHintFull,
/// "/provider" command label
IdleHintProvider,
/// "to add a custom model" (text after /provider)
IdleHintProviderSuffix,
/// Complete plain-text version: "/provider to add a custom model"
IdleHintProviderFull,
/// "/codingplan" command label
IdleHintCodingplan,
/// "to claim a free token quota" (text after /codingplan)
IdleHintCodingplanSuffix,
/// Complete plain-text version: "/codingplan to claim a free token quota"
IdleHintCodingplanFull,
/// "/webui" command label
IdleHintWebui,
/// "open a synced session in the browser" (text after /webui)
IdleHintWebuiSuffix,
/// Complete plain-text version: "/webui open a synced session in the browser"
IdleHintWebuiFull,
// ── Slash-command high-frequency messages ──
CmdSwitchedPlanMode,
CmdSwitchedBuildMode,
CmdNewSession,
CmdNoProviders,
CmdNoSessions,
CmdUnknownCommand { name: &'a str },
CmdLoginFailed { error: &'a str },
CmdLogoutDone,
CmdLogoutFailed { error: &'a str },
CmdWhoamiNotSignedIn,
CmdReloadDone { provider: &'a str, model: &'a str },
CmdReloadFailed { error: &'a str },
CmdUndoNotSupported,
CmdUndoDone { target: usize, last: usize },
CmdUndoDiskWarning,
CmdUndoNoTurns,
CmdUndoOutOfRange { requested: usize, available: usize },
CmdUndoBusy,
CmdUndoBadArg,
CmdNoChanges,
CmdCheckingUpdate,
CmdNoActiveProvider,
// ── Approval prompt ──
ApprovalPromptAlt { tool: &'a str, detail: &'a str },
ApprovalWaitingLabel,
ApprovalAllow,
ApprovalAlways,
ApprovalDeny,
// ── Cancelled / Error prefix ──
Cancelled,
ErrorPrefix { msg: &'a str },
// ── Upgrade messages ──
UpgradeSuccess { from: &'a str, to: &'a str },
UpgradeManifestFetched { version: &'a str },
UpgradeDownloading { pct: i32, bytes: u64, total: u64 },
UpgradeVerifying,
UpgradeReplacing,
UpgradeDone { version: &'a str, backup: &'a str },
UpgradeAlreadyLatest { current: &'a str, latest: &'a str },
UpgradeFailed { error: &'a str },
UpgradeRolledBack { exe: &'a str, backup: &'a str },
// ── Terminal keyboard hints ──
KbdHintMacos,
KbdHintOther,
// ── Background task ──
BackgroundComplete { turns: usize },
BackgroundFailed { turns: usize },
BackgroundFilesEdited,
// ── /config command ──
ConfigProviderLabel { provider: &'a str, path: &'a str },
// ── /cost command ──
CostReport {
prompt: usize,
completion: usize,
cached: usize,
cache_rate: usize,
total: usize,
cost: &'a str,
},
// ── /think command ──
ThinkStatus { status: &'a str, budget: u32, provider: &'a str },
ThinkEnabled { budget: u32 },
ThinkDisabled,
ThinkBudgetSet { n: u32 },
ThinkBudgetTooSmall { n: u32 },
ThinkBudgetUsage,
ThinkUsage,
// ── /remember, /forget ──
RememberUsage,
ForgetUsage,
// ── /background ──
BackgroundUsage,
// ── /init ──
InitAlreadyExists { path: &'a str },
InitWrote { path: &'a str, bytes: usize },
InitFailed { error: &'a str },
// ── /cd ──
CdWorkingDir { cwd: &'a str },
// ── /diff ──
DiffFailed { error: &'a str },
// ── /upgrade ──
/// Shown when `/upgrade` (or rollback) is invoked in a HarmonyBrew-managed
/// build: self-update is disabled, point the user at `brew upgrade`.
UpgradePackageManaged,
UpgradeUnknownArg { arg: &'a str },
// ── /skills ──
SkillsNone,
SkillsAvailable,
SkillUnknown { name: &'a str },
// ── /mcp ──
McpReloading { count: usize },
McpConnecting,
McpConnectingServer { name: &'a str },
McpNoServersConfigured,
McpClearedReconnecting { removed: usize },
McpClearedNoServers { removed: usize },
McpToolsUsage,
McpToolsListing { server: &'a str },
McpNoRegistry,
McpServersHeader,
McpReloadFailed { error: &'a str },
// /mcp login / logout
McpOAuthLoginUsage,
McpOAuthLogoutUsage,
McpOAuthLoadConfigFailed { error: &'a str },
McpOAuthServerNotFound { server: &'a str },
McpOAuthStarting { server: &'a str },
McpOAuthSaved { provider: &'a str, server: &'a str },
McpOAuthFailed { error: &'a str },
McpOAuthTokenRemoved { server: &'a str },
McpOAuthNoToken { server: &'a str },
McpOAuthLogoutFailed { error: &'a str },
// MCP / LSP server connect feedback (event handler output)
McpServerConnected { name: &'a str },
McpServerFailed { name: &'a str, error: &'a str },
LspServerStarted { name: &'a str, ext: &'a str },
LspServerFailed { name: &'a str, ext: &'a str, error: &'a str },
// ── /worktree ──
WorktreeUsage,
WorktreeCreateUsage,
WorktreeCreated { branch: &'a str, base: &'a str, path: &'a str },
WorktreeCreateFailed { error: &'a str },
WorktreeNoActive,
WorktreeListFailed { error: &'a str },
WorktreeActiveHeader,
WorktreeHasChanges,
WorktreeClean,
WorktreeCurrent,
WorktreeDoneBack { path: &'a str },
WorktreeDoneMergeHint { branch: &'a str },
WorktreeNoSession,
WorktreeCleanupUsage,
WorktreeCleaned { branch: &'a str },
WorktreeCleanedSwitched { path: &'a str },
WorktreeCleanupUncommitted { branch: &'a str },
WorktreeCleanupFailed { error: &'a str },
// ── /help commands (custom commands subcommand) ──
HelpCustomCommandsHeader,
HelpCustomNone,
HelpCustomCreateHint,
HelpSourceGlobal,
HelpSourceProject,
// ── /setup ──
/// Header line: "✅ Setup complete — 3 installed, 1 skipped, 0 failed · 120ms"
SetupHeader { installed: usize, skipped: usize, failed: usize, duration_ms: u64 },
/// "Installed:" section label in setup report.
SetupInstalledLabel,
/// "Skipped:" section label in setup report.
SetupSkippedLabel,
/// "Failed:" section label in setup report.
SetupFailedLabel,
/// Per-item installed row: " ✓ skill:atomcode-automation-recommender → /path"
SetupInstalledRow { kind: &'a str, slug: &'a str, path: &'a str },
/// Per-item skipped row: " - skill:xyz (hash match)"
SetupSkippedRow { kind: &'a str, slug: &'a str, reason: &'a str },
/// Per-item failed row: " × mcp:xyz — error message"
SetupFailedRow { kind: &'a str, slug: &'a str, error: &'a str },
/// "💡 Tip: Run /setup …" — first-run hint shown above the prompt
/// when the project has no setup state yet.
CmdSetupTip,
/// "Running atomcode setup..." — shown while setup is in progress.
CmdSetupRunning,
/// "Skills reloaded — N available" — after setup completes and skills are reloaded.
CmdSetupSkillsReloaded { count: usize },
/// "setup error: {e}" — when setup::run returns an error.
CmdSetupError { error: &'a str },
/// "Running setup skill..." — after seeds installed and skill is auto-invoked.
CmdSetupRunningSkill,
/// "Setup skill not found..." — when the setup skill cannot be resolved or expanded.
CmdSetupSkillMissing,
// ── /plugin ──
PluginUsage,
PluginMarketplaceUsage,
PluginInstallUsage,
PluginInstallNotFound { plugin: &'a str },
PluginInstallAmbiguous { plugin: &'a str },
PluginUninstallUsage,
PluginUninstallNotFound { plugin: &'a str },
PluginUninstallAmbiguous { plugin: &'a str },
PluginNoMarketplaces,
PluginMarketplacesHeader,
PluginNoInstalled,
PluginInstalledHeader,
PluginMarketplaceCloning { url: &'a str },
PluginMarketplaceRemoved { name: &'a str },
PluginMarketplaceRemoveFailed { error: &'a str },
PluginMarketplaceUpdating { name: &'a str },
PluginMarketplaceListFailed { error: &'a str },
PluginInstalling { plugin: &'a str, marketplace: &'a str },
PluginInstallingByName { plugin: &'a str },
PluginAlreadyInstalled { id: &'a str },
// Interactive `/plugin` manager modal.
PluginMgrBrowse,
PluginMgrAdd,
PluginMgrRemove,
PluginMgrInstalled { count: usize },
PluginMgrInstalledMark,
PluginMgrHintNav,
PluginMgrHintToggle,
PluginMgrHintRemove,
PluginMgrHintUninstall,
PluginMgrHintUrl,
PluginMgrHintPending,
PluginMgrInstallingLabel,
PluginMgrEmptyMarketplaces,
PluginMgrEmptyPlugins,
PluginMgrEmptyInstalled,
PluginMgrCloning,
PluginMgrInstalling { plugin: &'a str },
PluginMgrEscToCancel,
// Scope selection screen.
PluginScopeUser,
PluginScopeUserDesc,
PluginScopeProject,
PluginScopeProjectDesc,
PluginScopeLocal,
PluginScopeLocalDesc,
PluginScopeHint,
PluginUninstalled { plugin: &'a str, marketplace: &'a str },
PluginUninstallFailed { error: &'a str },
PluginListFailed { error: &'a str },
PluginReloadDone { skills: usize, warnings: usize },
/// Git not found on the system — marketplace auto-install and auto-update
/// are disabled. Shown as a friendly hint (not an error) at startup.
PluginGitNotFound,
/// Marketplace `add` completion toast. Emitted by `handle_plugin_job_event`
/// for both manual `/plugin marketplace add` and the detached
/// startup-bootstrap auto-install. `count` is the number of plugins the
/// marketplace exposes after cloning.
PluginMarketplaceAdded { name: &'a str, commit: &'a str, count: usize },
/// Marketplace `update` completion toast — HEAD actually moved. No-op
/// pulls (HEAD unchanged) emit no toast at all so a quiet `git pull`
/// doesn't spam the body region.
PluginMarketplaceUpdated { name: &'a str, commit: &'a str },
/// Plugin `install` completion toast. `skipped` counts skills that the
/// loader rejected (bad SKILL.md frontmatter, namespace collision, etc.);
/// `show_details_hint` flips on the trailing "(Ctrl+O for details)"
/// nudge when warnings exist and verbose mode is off.
PluginInstallDone {
plugin: &'a str,
marketplace: &'a str,
loaded: usize,
skipped: usize,
show_details_hint: bool,
},
SetupAutoReloaded { skills: usize, warnings: usize },
// ── Command descriptions (for help_text dynamic lookup) ──
CmdDescWebui,
CmdDescSetup,
CmdDescResume,
CmdDescRename,
CmdDescLogin,
CmdDescLogout,
CmdDescWhoami,
CmdDescModel,
CmdDescProvider,
CmdDescStatus,
CmdDescConfig,
CmdDescReload,
CmdDescCd,
CmdDescInit,
CmdDescBg,
CmdDescBackground,
CmdDescDiff,
CmdDescClear,
CmdDescSession,
CmdDescCost,
CmdDescContext,
CmdDescCompact,
CmdDescRemember,
CmdDescForget,
CmdDescMemory,
CmdDescMcp,
CmdDescUndo,
CmdDescWorktree,
CmdDescUpgrade,
CmdDescIssue,
CmdDescPlan,
CmdDescBuild,
CmdDescThink,
CmdDescHelp,
CmdDescKeys,
CmdDescLanguage,
CmdDescQuit,
CmdDescSkills,
CmdDescPlugin,
/// Description for the `/paste` slash command — pulls a clipboard
/// image and attaches it as `[Image #N]`. Exists for Windows
/// users whose Ctrl+V is swallowed by Windows Terminal / conhost
/// before reaching the app, but works on every platform.
CmdDescPaste,
/// Description for the `/guide` slash command — asks atomcode-guide a question.
CmdDescGuide,
/// `/guide` menu header: "📖 AtomCode Guide — type /guide <question>"
GuideMenuHeader,
/// `/guide` menu: "Common topics:" section label
GuideMenuTopics,
/// `/guide` menu topic: getting started
GuideMenuGettingStarted,
/// `/guide` menu topic: switching models
GuideMenuSwitchModel,
/// `/guide` menu topic: using MCP
GuideMenuMcp,
/// `/guide` menu topic: skills and plugins
GuideMenuSkills,
/// `/guide` menu topic: memory feature
GuideMenuMemory,
/// `/guide` menu topic: background tasks
GuideMenuBackground,
/// `/guide` menu topic: context management
GuideMenuContext,
/// `/guide` menu topic: keyboard shortcuts
GuideMenuKeybindings,
/// `/guide` menu topic: configuration
GuideMenuConfig,
/// /guide menu tip: hint for users to type a question
GuideMenuTip,
/// /guide menu: documentation URL
GuideMenuDocUrl,
/// `/guide`: ask skill install already in progress, please wait
CmdGuideInstalling,
/// `/guide`: ask skill not installed, triggering auto-install
CmdGuideAutoInstall,
/// `/guide`: auto-invoke completed, now answering
CmdGuideAutoInvoke { topic: &'a str },
/// `/guide`: install succeeded but ask skill still not found
CmdGuideSkillNotFound,
/// `/guide`: install failed, suggest manual install
CmdGuideInstallFailed { error: &'a str },
/// `/paste` failed because the clipboard holds no image. Shown
/// in scrollback as an error line so the user isn't left
/// wondering whether the command did anything.
CmdPasteNoImage,
// ── config save failed ──
ConfigSaveFailed { error: &'a str },
// ── OnboardingWizard (multi-step first-run + `/welcome`). Spec:
// docs/superpowers/specs/2026-05-11-welcome-wizard-redesign-design.md
OnboardingStepHeaderWelcome,
OnboardingStepHeaderLanguage,
OnboardingStepHeaderSetup,
OnboardingPanelTitle,
OnboardingIntroVersionLine { v: &'a str },
OnboardingIntroBullet1,
OnboardingIntroBullet2,
OnboardingIntroBullet3,
OnboardingIntroPressEnter,
OnboardingIntroCtrlC,
OnboardingIntroCompactTagline,
OnboardingLanguageTitleBilingual,
OnboardingLanguagePrompt,
OnboardingLanguageOptionAuto,
OnboardingLanguageOptionEn,
OnboardingLanguageOptionZhCn,
OnboardingSetupTitle,
OnboardingNavHint,
OnboardingConfirmClear,
CmdWelcomeDescription,
/// Vision preprocessor success banner. Shown as a body line right
/// after a VL turn finishes, in the form
/// `✓ VL recognised image, returned N chars`
/// (English) /
/// `✓ VL 识别图片成功,返回 N chars`
/// (zh-CN). The model key trails as a dim suffix in the renderer
/// — kept out of this message so the wrapper styling stays
/// renderer-side.
VisionPreprocessSuccess { char_count: usize },
/// TurnComplete separator summary, e.g.
/// `✓ Shipped · 3 rounds · 2 tools · 6.8s · 285 tokens`
/// `done` is a playful English verb from `DONE_LABELS` — kept
/// English in every locale because translated cute verbs read
/// awkward; the structural words (`rounds`/`tools`/`tokens`)
/// localise. `duration` is a pre-formatted human string (e.g.
/// "6.8s").
TurnSummary {
done: &'a str,
turn_count: usize,
tool_call_count: usize,
duration: &'a str,
total_tokens: usize,
},
/// Turn-end summary when the turn terminated in an error (the red
/// error line is rendered separately, just above this). Same stats
/// as `TurnSummary` but with a ✗ marker and a neutral "stopped"
/// label instead of a celebratory verb — otherwise an errored turn
/// reads as `✓ Nailed it` right under its own error message.
TurnSummaryError {
turn_count: usize,
tool_call_count: usize,
duration: &'a str,
total_tokens: usize,
},
// ── OAuth login chrome (/login + /codingplan share these) ──
/// Header above the QR block when scanning with WeChat is the
/// expected flow. Includes the leading " " indent and trailing
/// "\n\n" paragraph break that the caller used to inline.
LoginQrHeader,
/// Separator + URL prelude shown below the QR block when both
/// QR and URL fallback are available. Leading "\n\n " and
/// trailing "\n " are part of the template.
LoginUrlAfterQr,
/// QR + URL both unavailable (Unicode-incapable terminal AND a
/// platform where URL-based login doesn't work, e.g. OHOS).
LoginNoQrNoUrl,
/// URL-only header when QR can't render but URL login works.
/// Leading " " indent and trailing "\n " before the URL.
LoginUrlOnly,
/// Footer line: "Press ESC to cancel" with surrounding
/// blank-line padding.
LoginCancelHint,
// ── /context report ──
CtxUsageHeader,
CtxUsageNoTurns,
CtxUsageWaiting,
CtxProvider,
CtxCtxName,
CtxLabelSystemPrompt,
CtxLabelToolDefs,
CtxLabelColdZone,
CtxLabelMessages,
CtxLabelFree,
CtxMessagesInWindow { n: usize },
CtxSystemPromptHeader,
CtxSystemPromptEmpty,
/// Used in the "used/window tokens (pct)" line below the bar.
CtxTokensSuffix,
// ── /compact ──
CompactNothingShort,
CompactStarting,
CompactNothingNoSavings { before: &'a str, after: &'a str },
CompactDropped { messages: usize, before: &'a str, after: &'a str },
/// Surfaced when the user pastes/attaches an image but the active
/// model can't accept images AND no `vision_preprocessor_provider`
/// is configured. `model` is the current model identifier.
ModelNoImageSupport { model: &'a str },
// ── --dangerously-skip-permissions / -y ──
/// Scrollback warning banner when --dangerously-skip-permissions is active
/// in TUI mode. Includes leading "⚠ " and trailing "\n".
BypassWarningBanner,
/// Headless-mode stderr warning when --dangerously-skip-permissions is active.
BypassWarningHeadless,
/// Status-bar badge text shown when --dangerously-skip-permissions is
/// active. Typically "⚠ BYPASS" — kept short for the status row.
BypassBadge,
/// Confirmation hint after the first Ctrl+C on an empty buffer.
/// " (press Ctrl+C again to exit)\n" — leading indent + trailing
/// newline are part of the template.
CtrlCAgainToExit,
/// Startup hint shown on terminals where Kitty CSI-u keyboard
/// disambiguation isn't available, telling the user the
/// guaranteed-works `\<Enter>` multi-line trick. Multi-line
/// payload with leading indent + trailing paragraph break.
HintMultiLineInput,
// ── /bg (background sessions) ──
/// Help text for `/bg help`. Multi-line string with leading indent
/// and trailing newlines baked in.
BgHelp,
/// Empty state for `/bg list`.
BgListEmpty,
/// Table header for `/bg list`. Trailing newline baked in.
BgListHeader,
/// Row format for `/bg list`. `state` is the localised state label,
/// `age` is the humanised age string, `summary` is the session name.
BgListRow { slot: usize, short_id: &'a str, state: &'a str, age: &'a str, summary: &'a str },
/// Localised label for `RuntimeState::Running`.
BgStateRunning,
/// Localised label for `RuntimeState::Idle`.
BgStateIdle,
/// Localised label for `RuntimeState::Done`.
BgStateDone,
/// Localised label for `RuntimeState::Cancelled`.
BgStateCancelled,
/// Localised label for `RuntimeState::Error`.
BgStateError,
/// Age string: less than 60 seconds.
BgAgeNow,
/// Age string: minutes. `n` is the number of minutes.
BgAgeMinutes { n: u64 },
/// Age string: hours. `n` is the number of hours.
BgAgeHours { n: u64 },
/// Age string: days. `n` is the number of days.
BgAgeDays { n: u64 },
/// Error: too many background slots. `max` is the slot limit.
BgSlotLimitReached { max: usize },
/// Output after `/bg` sends the current session to background.
/// `new_id` is the new foreground session short id,
/// `slot` is the background slot number,
/// `old_id` is the backgrounded session short id,
/// `state` is the localised runtime state.
BgBackgroundCurrent { new_id: &'a str, slot: usize, old_id: &'a str, state: &'a str },
/// Error: invalid slot number. `slot` is the requested slot,
/// `available` is the number of available slots.
BgInvalidSlot { slot: usize, available: usize },
/// Error: background slot has no runtime client.
BgNoRuntimeClient,
/// Output after `/bg <N>` resumes a background session.
/// `slot` is the resumed slot, `short_id` is the session short id.
BgResumed { slot: usize, short_id: &'a str },
/// When resuming moves the previous foreground into a background slot.
/// `slot` is the new background slot number.
BgPreviousForegroundMoved { slot: usize },
/// Output after `/bg drop <N>`. `slot` is the dropped slot,
/// `short_id` is the session short id.
BgDropped { slot: usize, short_id: &'a str },
/// Output after `/background <task>` starts a one-shot task.
/// `slot` is the background slot, `short_id` is the session short id.
BgTaskStarted { slot: usize, short_id: &'a str },
/// Background task timed out. `secs` is the timeout in seconds.
BgTaskTimedOut { secs: u64 },
/// Background task internal error. `error` is the error message.
BgTaskError { error: &'a str },
/// Background task was cancelled.
BgTaskCancelled,
/// Background task finished but produced no summary text.
BgTaskNoSummary,
}