From 7b13b57b4ecf8d38285999a011ea7a0b351f4aba Mon Sep 17 00:00:00 2001 From: CodeWhale Bot Date: Wed, 2 Sep 2026 11:36:11 -0700 Subject: [PATCH 1/4] tui: carry custom themes inside the typed theme value UiThemeValue::Custom now holds its full custom: selector, the same single string /theme and the persisted theme setting use, so the typed /config document round-trips a custom theme without the sibling custom_theme_name field. No disk migration: that key was typed-UI only and was never persisted. --- crates/tui/src/config_ui.rs | 106 +++++++++++++++++++----------------- 1 file changed, 56 insertions(+), 50 deletions(-) diff --git a/crates/tui/src/config_ui.rs b/crates/tui/src/config_ui.rs index b95c045ed0..578a5eb694 100644 --- a/crates/tui/src/config_ui.rs +++ b/crates/tui/src/config_ui.rs @@ -84,13 +84,11 @@ pub struct SettingsSection { description = "Locale used by the TUI. Every shipped locale pack holds full English parity; nothing falls back." )] pub locale: UiLocale, - pub theme: UiThemeValue, #[schemars( - title = "Custom theme name", - description = "Theme slug from the fixed Codewhale themes directory; used only when theme is custom." + title = "Theme", + description = "Compiled theme name, or custom: for a theme from the Codewhale themes directory." )] - #[serde(default, skip_serializing_if = "Option::is_none")] - pub custom_theme_name: Option, + pub theme: UiThemeValue, #[schemars( title = "Background color", description = "Optional Blue Stage background override as #RRGGBB. Leave empty to keep the named theme." @@ -252,7 +250,7 @@ pub enum UiLocale { Uk, } -#[derive(Debug, Clone, Copy, Serialize, Deserialize, JsonSchema, PartialEq, Eq)] +#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)] #[serde(rename_all = "kebab-case")] pub enum UiThemeValue { Terminal, @@ -266,7 +264,9 @@ pub enum UiThemeValue { GruvboxDark, Matrix, Uwu, - Custom, + /// User theme carried as its full `custom:` selector — the same + /// single string `/theme` and the persisted `theme` setting use. + Custom(String), } #[derive(Debug, Clone, Copy, Serialize, Deserialize, JsonSchema, PartialEq, Eq)] @@ -453,13 +453,6 @@ pub fn build_document(app: &App, config: &Config) -> Result { inline_diffs: settings.inline_diffs.as_str().into(), locale: UiLocale::from_setting(&settings.locale)?, theme: UiThemeValue::from_setting(&settings.theme)?, - custom_theme_name: crate::palette::normalize_user_theme_selector(&settings.theme) - .map_err(anyhow::Error::msg)? - .map(|selector| { - selector - .trim_start_matches(crate::palette::USER_THEME_PREFIX) - .to_string() - }), background_color: settings.background_color.clone(), bracketed_paste: settings.bracketed_paste, composer_density: settings.composer_density.as_str().into(), @@ -860,19 +853,7 @@ fn validate_document(doc: &ConfigUiDocument, app: &App, config: &Config) -> Resu } fn theme_setting_for_document(doc: &ConfigUiDocument) -> Result { - let setting = if doc.settings.theme == UiThemeValue::Custom { - let name = doc - .settings - .custom_theme_name - .as_deref() - .map(str::trim) - .filter(|name| !name.is_empty()) - .ok_or_else(|| anyhow::anyhow!("custom theme requires custom_theme_name"))?; - format!("{}{}", crate::palette::USER_THEME_PREFIX, name) - } else { - doc.settings.theme.as_setting().to_string() - }; - crate::palette::resolve_theme_setting(&setting, None) + crate::palette::resolve_theme_setting(&doc.settings.theme.as_setting(), None) .map(|(normalized, _, _)| normalized) .map_err(anyhow::Error::msg) } @@ -1092,29 +1073,30 @@ impl UiLocale { } impl UiThemeValue { - fn as_setting(self) -> &'static str { + /// Canonical settings string. `Custom` carries its own full + /// `custom:` selector, so it round-trips without a sibling field. + fn as_setting(&self) -> std::borrow::Cow<'static, str> { match self { - Self::Terminal => "terminal", - Self::System => "system", - Self::Dark => "dark", - Self::Light => "light", - Self::Grayscale => "grayscale", - Self::CatppuccinMocha => "catppuccin-mocha", - Self::TokyoNight => "tokyo-night", - Self::Dracula => "dracula", - Self::GruvboxDark => "gruvbox-dark", - Self::Matrix => "matrix", - Self::Uwu => "uwu", - Self::Custom => "custom", + Self::Terminal => "terminal".into(), + Self::System => "system".into(), + Self::Dark => "dark".into(), + Self::Light => "light".into(), + Self::Grayscale => "grayscale".into(), + Self::CatppuccinMocha => "catppuccin-mocha".into(), + Self::TokyoNight => "tokyo-night".into(), + Self::Dracula => "dracula".into(), + Self::GruvboxDark => "gruvbox-dark".into(), + Self::Matrix => "matrix".into(), + Self::Uwu => "uwu".into(), + Self::Custom(selector) => std::borrow::Cow::Owned(selector.clone()), } } fn from_setting(value: &str) -> Result { - if crate::palette::normalize_user_theme_selector(value) - .map_err(anyhow::Error::msg)? - .is_some() + if let Some(selector) = + crate::palette::normalize_user_theme_selector(value).map_err(anyhow::Error::msg)? { - return Ok(Self::Custom); + return Ok(Self::Custom(selector)); } match crate::palette::normalize_theme_name(value) { Some("terminal") => Ok(Self::Terminal), @@ -1760,8 +1742,20 @@ background_color = "#1A1B26" let mut app = app(); let mut config = Config::default(); let doc = build_document(&app, &config).expect("document"); - assert_eq!(doc.settings.theme, UiThemeValue::Custom); - assert_eq!(doc.settings.custom_theme_name.as_deref(), Some("ocean")); + assert_eq!( + doc.settings.theme, + UiThemeValue::Custom("custom:ocean".to_string()) + ); + + // The typed document must survive its wire form untouched: the custom + // selector lives inside `theme` itself, with no sibling field and no + // disk migration. + let doc = parse_document(serde_json::to_value(&doc).expect("serialize document")) + .expect("parse document"); + assert_eq!( + doc.settings.theme, + UiThemeValue::Custom("custom:ocean".to_string()) + ); apply_document(doc, &mut app, &mut config, false).expect("apply custom theme"); assert_eq!( @@ -1839,9 +1833,17 @@ background_color = "#1A1B26" &serde_json::json!(expected_locales), "UiLocale schema must match Locale::shipped()" ); - let theme = &schema["$defs"]["UiThemeValue"]["enum"]; + let theme = &schema["$defs"]["UiThemeValue"]; + // `Custom` carries its `custom:` selector inline, so schemars + // renders oneOf: the named themes stay a string enum and the custom + // variant becomes a single-key object. + let theme_variants = theme + .get("oneOf") + .and_then(|ones| ones.as_array()) + .expect("UiThemeValue oneOf"); + let named = &theme_variants[0]["enum"]; assert_eq!( - theme, + named, &serde_json::json!([ "terminal", "system", @@ -1853,10 +1855,14 @@ background_color = "#1A1B26" "dracula", "gruvbox-dark", "matrix", - "uwu", - "custom" + "uwu" ]) ); + assert_eq!( + theme_variants[1]["properties"]["custom"], + serde_json::json!({"type": "string"}), + "custom theme selector must ride inside the theme value" + ); } #[test] From 091f1337dcb707db10d7c8e9f0c234b8094642f6 Mon Sep 17 00:00:00 2001 From: CodeWhale Bot Date: Wed, 2 Sep 2026 11:40:32 -0700 Subject: [PATCH 2/4] tui: drop orphaned launch-screen and sidebar locale keys ConfigLabelLaunchScreen belonged to the retired launch_screen setting (load already accepts and drops it) and ConfigLabelSidebarWidth / ConfigLabelSidebarFocus belonged to sidebar load-only shims that were never schema keys and had no hints. Remove the MessageIds and every pack entry; all 15 packs stay in parity. No behavior change. --- crates/tui/locales/ca.json | 3 --- crates/tui/locales/de.json | 3 --- crates/tui/locales/en.json | 3 --- crates/tui/locales/es-419.json | 3 --- crates/tui/locales/fr.json | 3 --- crates/tui/locales/hi.json | 3 --- crates/tui/locales/id.json | 3 --- crates/tui/locales/ja.json | 3 --- crates/tui/locales/ko.json | 3 --- crates/tui/locales/pt-BR.json | 3 --- crates/tui/locales/ru.json | 3 --- crates/tui/locales/uk.json | 3 --- crates/tui/locales/vi.json | 3 --- crates/tui/locales/zh-Hans.json | 3 --- crates/tui/locales/zh-Hant.json | 3 --- crates/tui/src/localization.rs | 6 ------ 16 files changed, 51 deletions(-) diff --git a/crates/tui/locales/ca.json b/crates/tui/locales/ca.json index f78307df25..2a0034f2eb 100644 --- a/crates/tui/locales/ca.json +++ b/crates/tui/locales/ca.json @@ -270,7 +270,6 @@ "ConfigLabelCalmMode": "Transcripció tranquil·la", "ConfigLabelLowMotion": "Reduir el moviment", "ConfigLabelFancyAnimations": "Moviment de la interfície en viu", - "ConfigLabelLaunchScreen": "Pantalla d'inici", "ScreenModeFullscreenNotice": "Pantalla: pantalla completa (pantalla alternativa).", "ScreenModeInlineNotice": "Pantalla: en línia — el terminal conserva el seu historial. La transcripció es manté a la finestra; encara no s'escriu a l'historial.", "ScreenModeMouseCaptureOn": "Captura del ratolí activada.", @@ -296,8 +295,6 @@ "ConfigLabelMentionMenuBehavior": "Comportament del menú de mencions", "ConfigLabelMentionWalkDepth": "Profunditat de mencions de fitxers", "ConfigLabelWorkspaceFollowSymlinks": "Seguir enllaços simbòlics", - "ConfigLabelSidebarWidth": "Amplada de la barra lateral", - "ConfigLabelSidebarFocus": "Focus de la barra lateral", "ConfigLabelContextPanel": "Panell de context", "ConfigLabelAutoCompact": "Compactació automàtica", "ConfigLabelAutoCompactThreshold": "Llindar de compactació", diff --git a/crates/tui/locales/de.json b/crates/tui/locales/de.json index 2970704094..d60b7374ac 100644 --- a/crates/tui/locales/de.json +++ b/crates/tui/locales/de.json @@ -270,7 +270,6 @@ "ConfigLabelCalmMode": "Ruhiges Transkript", "ConfigLabelLowMotion": "Bewegung reduzieren", "ConfigLabelFancyAnimations": "Animierte UI", - "ConfigLabelLaunchScreen": "Startbildschirm", "ScreenModeFullscreenNotice": "Bildschirm: Vollbild (alternativer Bildschirm).", "ScreenModeInlineNotice": "Bildschirm: Inline — das Terminal behält seinen eigenen Scrollback. Das Transkript bleibt im Ansichtsbereich; bisher wird nichts in den Scrollback geschrieben.", "ScreenModeMouseCaptureOn": "Mausaufnahme aktiviert.", @@ -296,8 +295,6 @@ "ConfigLabelMentionMenuBehavior": "Mention-Menü-Verhalten", "ConfigLabelMentionWalkDepth": "Datei-Mention-Tiefe", "ConfigLabelWorkspaceFollowSymlinks": "Symlinks folgen", - "ConfigLabelSidebarWidth": "Seitenleisten-Breite", - "ConfigLabelSidebarFocus": "Seitenleisten-Fokus", "ConfigLabelContextPanel": "Kontext-Panel", "ConfigLabelAutoCompact": "Auto-Komprimierung", "ConfigLabelAutoCompactThreshold": "Komprimierungs-Schwelle", diff --git a/crates/tui/locales/en.json b/crates/tui/locales/en.json index f456091566..603b7f5b40 100644 --- a/crates/tui/locales/en.json +++ b/crates/tui/locales/en.json @@ -270,7 +270,6 @@ "ConfigLabelCalmMode": "Quiet transcript", "ConfigLabelLowMotion": "Reduce motion", "ConfigLabelFancyAnimations": "Live UI motion", - "ConfigLabelLaunchScreen": "Launch screen", "ScreenModeFullscreenNotice": "Screen: fullscreen (alternate screen).", "ScreenModeInlineNotice": "Screen: inline — the terminal keeps its own scrollback. The transcript stays in the viewport; nothing is written into scrollback yet.", "ScreenModeMouseCaptureOn": "Mouse capture on.", @@ -296,8 +295,6 @@ "ConfigLabelMentionMenuBehavior": "Mention menu behavior", "ConfigLabelMentionWalkDepth": "File mention depth", "ConfigLabelWorkspaceFollowSymlinks": "Follow symlinks", - "ConfigLabelSidebarWidth": "Sidebar width", - "ConfigLabelSidebarFocus": "Sidebar focus", "ConfigLabelContextPanel": "Context panel", "ConfigLabelSessionsRail": "Sessions rail", "ConfigLabelSessionAutoResume": "Auto-resume last session", diff --git a/crates/tui/locales/es-419.json b/crates/tui/locales/es-419.json index 24d12465e0..5f024d3a11 100644 --- a/crates/tui/locales/es-419.json +++ b/crates/tui/locales/es-419.json @@ -270,7 +270,6 @@ "ConfigLabelCalmMode": "Conversación tranquila", "ConfigLabelLowMotion": "Reducir movimiento", "ConfigLabelFancyAnimations": "Movimiento de la interfaz en vivo", - "ConfigLabelLaunchScreen": "Pantalla de inicio", "ScreenModeFullscreenNotice": "Pantalla: pantalla completa (pantalla alternativa).", "ScreenModeInlineNotice": "Pantalla: en línea — la terminal conserva su propio historial. La transcripción permanece en la ventana; todavía no se escribe en el historial.", "ScreenModeMouseCaptureOn": "Captura del mouse activada.", @@ -296,8 +295,6 @@ "ConfigLabelMentionMenuBehavior": "Comportamiento del menú de menciones", "ConfigLabelMentionWalkDepth": "Profundidad de menciones de archivos", "ConfigLabelWorkspaceFollowSymlinks": "Seguir enlaces simbólicos", - "ConfigLabelSidebarWidth": "Ancho de barra lateral", - "ConfigLabelSidebarFocus": "Enfoque de barra lateral", "ConfigLabelContextPanel": "Panel de contexto", "ConfigLabelSessionsRail": "Barra de sesiones", "ConfigLabelSessionAutoResume": "Reanudar automáticamente la última sesión", diff --git a/crates/tui/locales/fr.json b/crates/tui/locales/fr.json index 84142ea359..e6e9961ef0 100644 --- a/crates/tui/locales/fr.json +++ b/crates/tui/locales/fr.json @@ -270,7 +270,6 @@ "ConfigLabelCalmMode": "Transcription calme", "ConfigLabelLowMotion": "Réduire les animations", "ConfigLabelFancyAnimations": "Animations de l'interface", - "ConfigLabelLaunchScreen": "Écran de lancement", "ScreenModeFullscreenNotice": "Écran : plein écran (écran alternatif).", "ScreenModeInlineNotice": "Écran : intégré — le terminal conserve son propre historique. La transcription reste dans la fenêtre d’affichage ; rien n’est encore écrit dans l’historique.", "ScreenModeMouseCaptureOn": "Capture de la souris activée.", @@ -296,8 +295,6 @@ "ConfigLabelMentionMenuBehavior": "Comportement du menu de mentions", "ConfigLabelMentionWalkDepth": "Profondeur des mentions de fichiers", "ConfigLabelWorkspaceFollowSymlinks": "Suivre les liens symboliques", - "ConfigLabelSidebarWidth": "Largeur de la barre latérale", - "ConfigLabelSidebarFocus": "Focus de la barre latérale", "ConfigLabelContextPanel": "Panneau de contexte", "ConfigLabelAutoCompact": "Compaction automatique", "ConfigLabelAutoCompactThreshold": "Seuil de compaction", diff --git a/crates/tui/locales/hi.json b/crates/tui/locales/hi.json index 75546f4af2..27e7361d5a 100644 --- a/crates/tui/locales/hi.json +++ b/crates/tui/locales/hi.json @@ -270,7 +270,6 @@ "ConfigLabelCalmMode": "शांत ट्रांसक्रिप्ट", "ConfigLabelLowMotion": "गति कम करें", "ConfigLabelFancyAnimations": "लाइव UI गति", - "ConfigLabelLaunchScreen": "लॉन्च स्क्रीन", "ScreenModeFullscreenNotice": "स्क्रीन: पूर्ण स्क्रीन (वैकल्पिक स्क्रीन)।", "ScreenModeInlineNotice": "स्क्रीन: इनलाइन — टर्मिनल अपना स्क्रॉलबैक रखता है। ट्रांसक्रिप्ट व्यूपोर्ट में रहता है; अभी स्क्रॉलबैक में कुछ नहीं लिखा जाता।", "ScreenModeMouseCaptureOn": "माउस कैप्चर चालू।", @@ -296,8 +295,6 @@ "ConfigLabelMentionMenuBehavior": "मेंशन मेनू व्यवहार", "ConfigLabelMentionWalkDepth": "फ़ाइल मेंशन गहराई", "ConfigLabelWorkspaceFollowSymlinks": "सिमलिंक फ़ॉलो करें", - "ConfigLabelSidebarWidth": "साइडबार चौड़ाई", - "ConfigLabelSidebarFocus": "साइडबार फ़ोकस", "ConfigLabelContextPanel": "संदर्भ पैनल", "ConfigLabelAutoCompact": "ऑटो कॉम्पैक्ट", "ConfigLabelAutoCompactThreshold": "कॉम्पैक्ट सीमा", diff --git a/crates/tui/locales/id.json b/crates/tui/locales/id.json index 532bb4d859..9f2b903e7d 100644 --- a/crates/tui/locales/id.json +++ b/crates/tui/locales/id.json @@ -270,7 +270,6 @@ "ConfigLabelCalmMode": "Transkrip hening", "ConfigLabelLowMotion": "Kurangi gerakan", "ConfigLabelFancyAnimations": "Gerakan UI langsung", - "ConfigLabelLaunchScreen": "Layar pembuka", "ScreenModeFullscreenNotice": "Layar: layar penuh (layar alternatif).", "ScreenModeInlineNotice": "Layar: inline — terminal mempertahankan scrollback-nya sendiri. Transkrip tetap di viewport; belum ada yang ditulis ke scrollback.", "ScreenModeMouseCaptureOn": "Penangkapan mouse aktif.", @@ -296,8 +295,6 @@ "ConfigLabelMentionMenuBehavior": "Perilaku menu mention", "ConfigLabelMentionWalkDepth": "Kedalaman mention file", "ConfigLabelWorkspaceFollowSymlinks": "Ikuti symlink", - "ConfigLabelSidebarWidth": "Lebar bilah sisi", - "ConfigLabelSidebarFocus": "Fokus bilah sisi", "ConfigLabelContextPanel": "Panel konteks", "ConfigLabelAutoCompact": "Padatkan otomatis", "ConfigLabelAutoCompactThreshold": "Ambang pemadatan", diff --git a/crates/tui/locales/ja.json b/crates/tui/locales/ja.json index 9c34e0ad74..fc4951dcd2 100644 --- a/crates/tui/locales/ja.json +++ b/crates/tui/locales/ja.json @@ -270,7 +270,6 @@ "ConfigLabelCalmMode": "静かな会話表示", "ConfigLabelLowMotion": "動きを減らす", "ConfigLabelFancyAnimations": "ライブ UI モーション", - "ConfigLabelLaunchScreen": "起動画面", "ScreenModeFullscreenNotice": "画面:フルスクリーン(代替画面)。", "ScreenModeInlineNotice": "画面:インライン — ターミナルは独自のスクロールバックを保持します。トランスクリプトはビューポート内に残り、まだスクロールバックには書き込まれません。", "ScreenModeMouseCaptureOn": "マウスキャプチャ:オン。", @@ -296,8 +295,6 @@ "ConfigLabelMentionMenuBehavior": "メンションメニュー動作", "ConfigLabelMentionWalkDepth": "ファイル探索深度", "ConfigLabelWorkspaceFollowSymlinks": "シンボリックリンクを追跡", - "ConfigLabelSidebarWidth": "サイドバー幅", - "ConfigLabelSidebarFocus": "サイドバーフォーカス", "ConfigLabelContextPanel": "コンテキストパネル", "ConfigLabelSessionsRail": "セッションレール", "ConfigLabelSessionAutoResume": "前回のセッションを自動再開", diff --git a/crates/tui/locales/ko.json b/crates/tui/locales/ko.json index b2f9a9cc8a..ca79888ef6 100644 --- a/crates/tui/locales/ko.json +++ b/crates/tui/locales/ko.json @@ -270,7 +270,6 @@ "ConfigLabelCalmMode": "차분한 대화 기록", "ConfigLabelLowMotion": "동작 줄이기", "ConfigLabelFancyAnimations": "실시간 UI 동작", - "ConfigLabelLaunchScreen": "시작 화면", "ScreenModeFullscreenNotice": "화면: 전체 화면(대체 화면).", "ScreenModeInlineNotice": "화면: 인라인 — 터미널이 자체 스크롤백을 유지합니다. 트랜스크립트는 뷰포트에 남으며 아직 스크롤백에 기록되지 않습니다.", "ScreenModeMouseCaptureOn": "마우스 캡처 켜짐.", @@ -296,8 +295,6 @@ "ConfigLabelMentionMenuBehavior": "멘션 메뉴 동작", "ConfigLabelMentionWalkDepth": "파일 멘션 깊이", "ConfigLabelWorkspaceFollowSymlinks": "심볼릭 링크 따라가기", - "ConfigLabelSidebarWidth": "사이드바 너비", - "ConfigLabelSidebarFocus": "사이드바 포커스", "ConfigLabelContextPanel": "컨텍스트 패널", "ConfigLabelSessionsRail": "세션 레일", "ConfigLabelSessionAutoResume": "마지막 세션 자동 재개", diff --git a/crates/tui/locales/pt-BR.json b/crates/tui/locales/pt-BR.json index f3aa2e3a1e..1192f37945 100644 --- a/crates/tui/locales/pt-BR.json +++ b/crates/tui/locales/pt-BR.json @@ -270,7 +270,6 @@ "ConfigLabelCalmMode": "Conversa tranquila", "ConfigLabelLowMotion": "Reduzir movimento", "ConfigLabelFancyAnimations": "Movimento da interface ao vivo", - "ConfigLabelLaunchScreen": "Tela de inicialização", "ScreenModeFullscreenNotice": "Tela: tela cheia (tela alternativa).", "ScreenModeInlineNotice": "Tela: integrada — o terminal mantém seu próprio histórico. A transcrição permanece na área de visualização; nada é escrito no histórico ainda.", "ScreenModeMouseCaptureOn": "Captura do mouse ativada.", @@ -296,8 +295,6 @@ "ConfigLabelMentionMenuBehavior": "Comportamento do menu de menções", "ConfigLabelMentionWalkDepth": "Profundidade de menções de arquivos", "ConfigLabelWorkspaceFollowSymlinks": "Seguir links simbólicos", - "ConfigLabelSidebarWidth": "Largura da barra lateral", - "ConfigLabelSidebarFocus": "Foco da barra lateral", "ConfigLabelContextPanel": "Painel de contexto", "ConfigLabelSessionsRail": "Trilho de sessões", "ConfigLabelSessionAutoResume": "Retomar a última sessão automaticamente", diff --git a/crates/tui/locales/ru.json b/crates/tui/locales/ru.json index 8963869513..8b442bdb8f 100644 --- a/crates/tui/locales/ru.json +++ b/crates/tui/locales/ru.json @@ -270,7 +270,6 @@ "ConfigLabelCalmMode": "Спокойная лента", "ConfigLabelLowMotion": "Меньше анимаций", "ConfigLabelFancyAnimations": "Живые анимации UI", - "ConfigLabelLaunchScreen": "Экран запуска", "ScreenModeFullscreenNotice": "Экран: полноэкранный режим (альтернативный экран).", "ScreenModeInlineNotice": "Экран: встроенный — терминал сохраняет собственный буфер прокрутки. Транскрипция остаётся в области просмотра; пока в буфер прокрутки ничего не записывается.", "ScreenModeMouseCaptureOn": "Захват мыши включён.", @@ -296,8 +295,6 @@ "ConfigLabelMentionMenuBehavior": "Поведение меню упоминаний", "ConfigLabelMentionWalkDepth": "Глубина упоминаний файлов", "ConfigLabelWorkspaceFollowSymlinks": "Следовать симлинкам", - "ConfigLabelSidebarWidth": "Ширина боковой панели", - "ConfigLabelSidebarFocus": "Фокус боковой панели", "ConfigLabelContextPanel": "Панель контекста", "ConfigLabelAutoCompact": "Автосжатие", "ConfigLabelAutoCompactThreshold": "Порог сжатия", diff --git a/crates/tui/locales/uk.json b/crates/tui/locales/uk.json index 9d29fb084c..045531e716 100644 --- a/crates/tui/locales/uk.json +++ b/crates/tui/locales/uk.json @@ -270,7 +270,6 @@ "ConfigLabelCalmMode": "Спокійний транскрипт", "ConfigLabelLowMotion": "Зменшити анімацію", "ConfigLabelFancyAnimations": "Жива анімація інтерфейсу", - "ConfigLabelLaunchScreen": "Екран запуску", "ScreenModeFullscreenNotice": "Екран: повноекранний режим (альтернативний екран).", "ScreenModeInlineNotice": "Екран: вбудований — термінал зберігає власний буфер прокручування. Транскрипція залишається в області перегляду; поки що до буфера прокручування нічого не записується.", "ScreenModeMouseCaptureOn": "Захоплення миші ввімкнено.", @@ -296,8 +295,6 @@ "ConfigLabelMentionMenuBehavior": "Поведінка меню згадок", "ConfigLabelMentionWalkDepth": "Глибина згадок файлів", "ConfigLabelWorkspaceFollowSymlinks": "Переходити за симпосиланнями", - "ConfigLabelSidebarWidth": "Ширина бічної панелі", - "ConfigLabelSidebarFocus": "Фокус бічної панелі", "ConfigLabelContextPanel": "Панель контексту", "ConfigLabelAutoCompact": "Автостиснення", "ConfigLabelAutoCompactThreshold": "Поріг стиснення", diff --git a/crates/tui/locales/vi.json b/crates/tui/locales/vi.json index a3fb2c92ed..682641bc30 100644 --- a/crates/tui/locales/vi.json +++ b/crates/tui/locales/vi.json @@ -270,7 +270,6 @@ "ConfigLabelCalmMode": "Bản ghi yên tĩnh", "ConfigLabelLowMotion": "Giảm chuyển động", "ConfigLabelFancyAnimations": "Chuyển động giao diện trực tiếp", - "ConfigLabelLaunchScreen": "Màn hình khởi động", "ScreenModeFullscreenNotice": "Màn hình: toàn màn hình (màn hình thay thế).", "ScreenModeInlineNotice": "Màn hình: nội tuyến — thiết bị đầu cuối giữ vùng cuộn riêng. Bản ghi vẫn ở khung nhìn; hiện chưa có gì được ghi vào vùng cuộn.", "ScreenModeMouseCaptureOn": "Đã bật bắt chuột.", @@ -296,8 +295,6 @@ "ConfigLabelMentionMenuBehavior": "Hành vi menu đề cập", "ConfigLabelMentionWalkDepth": "Độ sâu đề cập tệp", "ConfigLabelWorkspaceFollowSymlinks": "Theo liên kết tượng trưng", - "ConfigLabelSidebarWidth": "Chiều rộng thanh bên", - "ConfigLabelSidebarFocus": "Tiêu điểm thanh bên", "ConfigLabelContextPanel": "Bảng ngữ cảnh", "ConfigLabelSessionsRail": "Thanh phiên", "ConfigLabelSessionAutoResume": "Tự động tiếp tục phiên gần nhất", diff --git a/crates/tui/locales/zh-Hans.json b/crates/tui/locales/zh-Hans.json index 167ea863f8..a44e79db03 100644 --- a/crates/tui/locales/zh-Hans.json +++ b/crates/tui/locales/zh-Hans.json @@ -270,7 +270,6 @@ "ConfigLabelCalmMode": "简洁对话", "ConfigLabelLowMotion": "减少动态效果", "ConfigLabelFancyAnimations": "实时界面动态", - "ConfigLabelLaunchScreen": "启动画面", "ScreenModeFullscreenNotice": "屏幕:全屏(备用屏幕)。", "ScreenModeInlineNotice": "屏幕:内嵌 — 终端保留自己的滚动缓冲区。记录会留在视口中;暂时不会写入滚动缓冲区。", "ScreenModeMouseCaptureOn": "鼠标捕获已开启。", @@ -296,8 +295,6 @@ "ConfigLabelMentionMenuBehavior": "提及菜单行为", "ConfigLabelMentionWalkDepth": "文件提及深度", "ConfigLabelWorkspaceFollowSymlinks": "跟随符号链接", - "ConfigLabelSidebarWidth": "侧栏宽度", - "ConfigLabelSidebarFocus": "侧栏焦点", "ConfigLabelContextPanel": "上下文面板", "ConfigLabelSessionsRail": "会话栏", "ConfigLabelSessionAutoResume": "自动恢复上次会话", diff --git a/crates/tui/locales/zh-Hant.json b/crates/tui/locales/zh-Hant.json index d9ff2e5768..26a2898e94 100644 --- a/crates/tui/locales/zh-Hant.json +++ b/crates/tui/locales/zh-Hant.json @@ -549,7 +549,6 @@ "ConfigLabelFleetSpawnDepth": "Pod 遞歸深度", "ConfigLabelGoalCommand": "目標命令", "ConfigLabelInlineDiffs": "內聯檔案更改", - "ConfigLabelLaunchScreen": "啟動畫面", "ScreenModeFullscreenNotice": "畫面:全螢幕(替代畫面)。", "ScreenModeInlineNotice": "畫面:內嵌 — 終端機保留自己的捲動緩衝區。記錄會留在檢視區;目前不會寫入捲動緩衝區。", "ScreenModeMouseCaptureOn": "滑鼠擷取已開啟。", @@ -586,8 +585,6 @@ "ConfigLabelShowThinking": "對話中顯示模型推理", "ConfigLabelShowToolDetails": "工具詳情級別", "ConfigLabelSideWidth": "側欄寬度", - "ConfigLabelSidebarFocus": "側欄焦點", - "ConfigLabelSidebarWidth": "側欄寬度", "ConfigLabelStatusIndicator": "狀態指示器", "ConfigLabelStreamTimeout": "流式逾時", "ConfigLabelSynchronizedOutput": "輸出節奏", diff --git a/crates/tui/src/localization.rs b/crates/tui/src/localization.rs index 1a8e71609c..22e3884819 100644 --- a/crates/tui/src/localization.rs +++ b/crates/tui/src/localization.rs @@ -288,7 +288,6 @@ pub enum MessageId { ConfigLabelCalmMode, ConfigLabelLowMotion, ConfigLabelFancyAnimations, - ConfigLabelLaunchScreen, ConfigLabelShowThinking, ConfigLabelThinkingHighlight, ConfigLabelShowToolDetails, @@ -308,8 +307,6 @@ pub enum MessageId { ConfigLabelMentionMenuBehavior, ConfigLabelMentionWalkDepth, ConfigLabelWorkspaceFollowSymlinks, - ConfigLabelSidebarWidth, - ConfigLabelSidebarFocus, ConfigLabelContextPanel, ConfigLabelSessionsRail, ConfigLabelSessionAutoResume, @@ -2403,7 +2400,6 @@ pub const ALL_MESSAGE_IDS: &[MessageId] = &[ MessageId::ConfigLabelCalmMode, MessageId::ConfigLabelLowMotion, MessageId::ConfigLabelFancyAnimations, - MessageId::ConfigLabelLaunchScreen, MessageId::ConfigLabelShowThinking, MessageId::ConfigLabelThinkingHighlight, MessageId::ConfigLabelShowToolDetails, @@ -2423,8 +2419,6 @@ pub const ALL_MESSAGE_IDS: &[MessageId] = &[ MessageId::ConfigLabelMentionMenuBehavior, MessageId::ConfigLabelMentionWalkDepth, MessageId::ConfigLabelWorkspaceFollowSymlinks, - MessageId::ConfigLabelSidebarWidth, - MessageId::ConfigLabelSidebarFocus, MessageId::ConfigLabelContextPanel, MessageId::ConfigLabelSessionsRail, MessageId::ConfigLabelSessionAutoResume, From 01ec884f45a699e9f97e510b6af44019339412a9 Mon Sep 17 00:00:00 2001 From: CodeWhale Bot Date: Wed, 2 Sep 2026 12:01:34 -0700 Subject: [PATCH 3/4] tui: align typed config and schema with the live value spaces MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - work_surface_placement: the live default is bottom and Settings::set accepts top|bottom|left|right|off, but the schema offered top|left|right|off defaulting to left, and WorkSurfacePlacementValue only had Top|Left|Right — a persisted bottom round-tripped as top through the typed /config document and corrupted the setting on save. Schema gains bottom (default bottom); the typed enum gains Bottom and Off so every live value round-trips. - rail_panel: the schema offered tasks|agents|context|pinned while the dock cycles eight panels and Settings::set rejected five of them. Schema and set() now accept tasks, agents, background, files, notepad, context, git, price; pinned stays an accepted alias that folds into tasks like the load-time migration. - status_indicator: drop the retired whale choice from the schema; the whale|🐳|🐋 → cw load migration stays. - UiThemeValue gains claude and solarized-light (SELECTABLE_THEMES entries the typed document could not round-trip) and a test pins the typed value space to every selectable theme. - packs: widen the two value-enumeration hints, add the bottom placement copy, and drop the retired choice keys from all 15 packs. Test updates: rail_panel_persists_tasks_agents_context_and_pinned encoded the old four-panel set() and its pinned-verbatim persistence; it now covers all eight panels and the pinned→tasks fold. --- crates/config/src/settings_schema.rs | 22 ++++--- crates/tui/locales/ca.json | 9 ++- crates/tui/locales/de.json | 9 ++- crates/tui/locales/en.json | 9 ++- crates/tui/locales/es-419.json | 9 ++- crates/tui/locales/fr.json | 9 ++- crates/tui/locales/hi.json | 9 ++- crates/tui/locales/id.json | 9 ++- crates/tui/locales/ja.json | 9 ++- crates/tui/locales/ko.json | 9 ++- crates/tui/locales/pt-BR.json | 9 ++- crates/tui/locales/ru.json | 9 ++- crates/tui/locales/uk.json | 9 ++- crates/tui/locales/vi.json | 9 ++- crates/tui/locales/zh-Hans.json | 9 ++- crates/tui/locales/zh-Hant.json | 9 ++- crates/tui/src/config_ui.rs | 94 +++++++++++++++++++++++++++- crates/tui/src/localization.rs | 10 ++- crates/tui/src/settings.rs | 39 ++++++++++-- 19 files changed, 205 insertions(+), 95 deletions(-) diff --git a/crates/config/src/settings_schema.rs b/crates/config/src/settings_schema.rs index ce8fc54022..049cae65ed 100644 --- a/crates/config/src/settings_schema.rs +++ b/crates/config/src/settings_schema.rs @@ -239,8 +239,9 @@ const INLINE_DIFFS: &[SettingOption] = &[ ]; const STATUS_INDICATOR: &[SettingOption] = &[ + // `whale` is retired: load migrates whale | 🐳 | 🐋 to the typographic + // mark, so the editor no longer offers it. SettingOption::new("cw", "ConfigChoiceStatusCw", ""), - SettingOption::new("whale", "ConfigChoiceStatusWhale", ""), SettingOption::new("dots", "ConfigChoiceStatusDots", ""), SettingOption::new("off", "ConfigValueOff", ""), ]; @@ -284,6 +285,11 @@ const WORK_SURFACE_PLACEMENT: &[SettingOption] = &[ "ConfigChoicePlacementTop", "ConfigChoiceDetailPlacementTop", ), + SettingOption::new( + "bottom", + "ConfigChoicePlacementBottom", + "ConfigChoiceDetailPlacementBottom", + ), SettingOption::new( "left", "ConfigChoicePlacementLeft", @@ -298,6 +304,8 @@ const WORK_SURFACE_PLACEMENT: &[SettingOption] = &[ ]; const RAIL_PANEL: &[SettingOption] = &[ + // The dock's own grammar is lowercase nouns, so the panels the classic + // sidebar never named ride on their raw value (`RailPanel::title`). SettingOption::new( "tasks", "ConfigChoiceRailTasks", @@ -308,16 +316,16 @@ const RAIL_PANEL: &[SettingOption] = &[ "ConfigChoiceRailAgents", "ConfigChoiceDetailRailAgents", ), + SettingOption::new("background", "", ""), + SettingOption::new("files", "", ""), + SettingOption::new("notepad", "", ""), SettingOption::new( "context", "ConfigChoiceRailContext", "ConfigChoiceDetailRailContext", ), - SettingOption::new( - "pinned", - "ConfigChoiceRailPinned", - "ConfigChoiceDetailRailPinned", - ), + SettingOption::new("git", "", ""), + SettingOption::new("price", "", ""), ]; /// Rail tab ids. @@ -681,7 +689,7 @@ pub const SETTINGS_SCHEMA: &[SettingDef] = &[ def( "work_surface_placement", SettingKind::Enum(WORK_SURFACE_PLACEMENT), - "left", + "bottom", ui( TAB_WORK, "sidebar", diff --git a/crates/tui/locales/ca.json b/crates/tui/locales/ca.json index 2a0034f2eb..16b662f2f1 100644 --- a/crates/tui/locales/ca.json +++ b/crates/tui/locales/ca.json @@ -1926,14 +1926,13 @@ "ConfigChoiceModePlan": "Planifica (només lectura)", "ConfigChoiceModeOperate": "Opera", "ConfigChoicePlacementTop": "A dalt", + "ConfigChoicePlacementBottom": "Barra inferior", "ConfigChoicePlacementLeft": "Barra lateral esquerra", "ConfigChoicePlacementRight": "Barra lateral dreta", "ConfigChoiceRailTasks": "Tasques", "ConfigChoiceRailAgents": "Agents", "ConfigChoiceRailContext": "Context", - "ConfigChoiceRailPinned": "Fixats", "ConfigChoiceStatusCw": "Marca Codewhale", - "ConfigChoiceStatusWhale": "Balena animada", "ConfigChoiceStatusDots": "Punts animats", "ConfigChoiceDiffFull": "Diff complet", "ConfigChoiceDiffSummary": "Resum", @@ -1946,13 +1945,13 @@ "ConfigChoiceDetailModePlan": "Comença en un espai de planificació de només lectura.", "ConfigChoiceDetailModeOperate": "Operate converteix la teva petició en un objectiu i hi treballa en paral·lel: workers en segon pla per als fluxos separables, verificats abans d'aturar-se.", "ConfigChoiceDetailPlacementTop": "Mostra Tasques, Pendents i Workers damunt de la transcripció.", + "ConfigChoiceDetailPlacementBottom": "Mostra Tasques, Pendents i Workers sota el redactor.", "ConfigChoiceDetailPlacementLeft": "Mostra Tasques, Pendents i Workers en una barra lateral esquerra quan el terminal és prou ample.", "ConfigChoiceDetailPlacementRight": "Mostra Tasques, Pendents i Workers en una barra lateral dreta quan el terminal és prou ample.", "ConfigChoiceDetailPlacementOff": "Amaga el rail del tot.", "ConfigChoiceDetailRailTasks": "El rail mostra la llista en viu de Tasques / Pendents / Workers.", "ConfigChoiceDetailRailAgents": "El rail mostra els subagents i l'estat de distribució.", "ConfigChoiceDetailRailContext": "El rail mostra el context d'espai de treball, tokens i cost.", - "ConfigChoiceDetailRailPinned": "El rail mostra l'objectiu fixat i el resum de la llista de verificació.", "ConfigChoiceDetailLowMotionOn": "Atura el moviment de l'estat en viu sense canviar la sortida del model.", "ConfigChoiceDetailLowMotionOff": "Permet el moviment triat als altres ajustos d'aparença.", "ConfigChoiceDetailFancyOn": "Anima amb fidelitat l'estat en viu d'eines, estat i oceà.", @@ -1978,8 +1977,8 @@ "ConfigHintInlineDiffs": "full | summary | off; el canvi exacte es manté als detalls d'Alt/Option+V", "ConfigHintToolCollapse": "compact | expanded | calm", "ConfigHintBackgroundColor": "#RRGGBB | default", - "ConfigHintWorkSurfacePlacement": "top | left | right | off · els rails laterals requereixen el mode Ocean i almenys 72 columnes", - "ConfigHintRailPanel": "tasks | agents | context | pinned · quin tauler mostra el rail", + "ConfigHintWorkSurfacePlacement": "bottom | top | left | right | off · els rails laterals requereixen el mode Ocean i almenys 72 columnes", + "ConfigHintRailPanel": "tasks | agents | background | files | notepad | context | git | price · quin tauler mostra el rail", "ConfigHintWorkSurfaceTopHeight": "5..=16 files · també ajustable arrossegant el divisor", "ConfigHintWorkSurfaceSideWidth": "26..=80 columnes · també ajustable arrossegant el divisor", "ConfigHintBaseUrl": "rebut de ruta de només lectura de l'endpoint en viu · canvia proveïdor, credencial i endpoint junts amb /provider", diff --git a/crates/tui/locales/de.json b/crates/tui/locales/de.json index d60b7374ac..7609cc5c82 100644 --- a/crates/tui/locales/de.json +++ b/crates/tui/locales/de.json @@ -1926,14 +1926,13 @@ "ConfigChoiceModePlan": "Planen (nur lesen)", "ConfigChoiceModeOperate": "Steuern", "ConfigChoicePlacementTop": "Oben", + "ConfigChoicePlacementBottom": "Untere Leiste", "ConfigChoicePlacementLeft": "Linke Seitenleiste", "ConfigChoicePlacementRight": "Rechte Seitenleiste", "ConfigChoiceRailTasks": "Aufgaben", "ConfigChoiceRailAgents": "Agenten", "ConfigChoiceRailContext": "Kontext", - "ConfigChoiceRailPinned": "Angeheftet", "ConfigChoiceStatusCw": "Codewhale-Marke", - "ConfigChoiceStatusWhale": "Animierter Wal", "ConfigChoiceStatusDots": "Animierte Punkte", "ConfigChoiceDiffFull": "Vollständiger Diff", "ConfigChoiceDiffSummary": "Zusammenfassung", @@ -1946,13 +1945,13 @@ "ConfigChoiceDetailModePlan": "Startet in einem schreibgeschützten Planungsbereich.", "ConfigChoiceDetailModeOperate": "Operate macht aus Ihrer Eingabe ein Ziel und arbeitet es parallel ab: Hintergrund-Worker für trennbare Stränge, verifiziert bevor es stoppt.", "ConfigChoiceDetailPlacementTop": "Zeigt Aufgaben, To-do und Worker über dem Transkript.", + "ConfigChoiceDetailPlacementBottom": "Zeigt Aufgaben, To-do und Worker unter dem Composer.", "ConfigChoiceDetailPlacementLeft": "Zeigt Aufgaben, To-do und Worker in einer linken Seitenleiste, wenn das Terminal breit genug ist.", "ConfigChoiceDetailPlacementRight": "Zeigt Aufgaben, To-do und Worker in einer rechten Seitenleiste, wenn das Terminal breit genug ist.", "ConfigChoiceDetailPlacementOff": "Blendet die Leiste vollständig aus.", "ConfigChoiceDetailRailTasks": "Die Leiste zeigt die Live-Liste Aufgaben / To-do / Worker.", "ConfigChoiceDetailRailAgents": "Die Leiste zeigt Sub-Agenten und den Verteilungsstatus.", "ConfigChoiceDetailRailContext": "Die Leiste zeigt Arbeitsbereichs-, Token- und Kostenkontext.", - "ConfigChoiceDetailRailPinned": "Die Leiste zeigt das angeheftete Ziel und die Checklisten-Zusammenfassung.", "ConfigChoiceDetailLowMotionOn": "Stoppt Live-Bewegung, ohne die Modellausgabe zu ändern.", "ConfigChoiceDetailLowMotionOff": "Erlaubt die in den anderen Darstellungseinstellungen gewählte Bewegung.", "ConfigChoiceDetailFancyOn": "Animiert wahrheitsgetreu den Live-Zustand von Werkzeugen, Status und Ozean.", @@ -1978,8 +1977,8 @@ "ConfigHintInlineDiffs": "full | summary | off; die exakte Änderung bleibt in den Alt/Option+V-Details", "ConfigHintToolCollapse": "compact | expanded | calm", "ConfigHintBackgroundColor": "#RRGGBB | default", - "ConfigHintWorkSurfacePlacement": "top | left | right | off · Seitenleisten brauchen den Ocean-Modus und mindestens 72 Spalten", - "ConfigHintRailPanel": "tasks | agents | context | pinned · welches Panel die Leiste zeigt", + "ConfigHintWorkSurfacePlacement": "bottom | top | left | right | off · Seitenleisten brauchen den Ocean-Modus und mindestens 72 Spalten", + "ConfigHintRailPanel": "tasks | agents | background | files | notepad | context | git | price · welches Panel die Leiste zeigt", "ConfigHintWorkSurfaceTopHeight": "5..=16 Zeilen · auch durch Ziehen des Trenners einstellbar", "ConfigHintWorkSurfaceSideWidth": "26..=80 Spalten · auch durch Ziehen des Trenners einstellbar", "ConfigHintBaseUrl": "schreibgeschützter Routenbeleg des Live-Endpunkts · Anbieter, Zugangsdaten und Endpunkt gemeinsam mit /provider ändern", diff --git a/crates/tui/locales/en.json b/crates/tui/locales/en.json index 603b7f5b40..0d6eaca4c9 100644 --- a/crates/tui/locales/en.json +++ b/crates/tui/locales/en.json @@ -1926,14 +1926,13 @@ "ConfigChoiceModePlan": "Plan (read only)", "ConfigChoiceModeOperate": "Operate", "ConfigChoicePlacementTop": "Top", + "ConfigChoicePlacementBottom": "Bottom bar", "ConfigChoicePlacementLeft": "Left sidebar", "ConfigChoicePlacementRight": "Right sidebar", "ConfigChoiceRailTasks": "Tasks", "ConfigChoiceRailAgents": "Agents", "ConfigChoiceRailContext": "Context", - "ConfigChoiceRailPinned": "Pinned", "ConfigChoiceStatusCw": "Codewhale mark", - "ConfigChoiceStatusWhale": "Animated whale", "ConfigChoiceStatusDots": "Animated dots", "ConfigChoiceDiffFull": "Full diff", "ConfigChoiceDiffSummary": "Summary", @@ -1946,13 +1945,13 @@ "ConfigChoiceDetailModePlan": "Start in a read-only planning workspace.", "ConfigChoiceDetailModeOperate": "Operate turns your prompt into a goal and works it in parallel: background workers for separable streams, verified before it stops.", "ConfigChoiceDetailPlacementTop": "Show Tasks, To-do, and Workers above the transcript.", + "ConfigChoiceDetailPlacementBottom": "Show Tasks, To-do, and Workers under the composer.", "ConfigChoiceDetailPlacementLeft": "Show Tasks, To-do, and Workers in a left sidebar when the terminal is wide enough.", "ConfigChoiceDetailPlacementRight": "Show Tasks, To-do, and Workers in a right sidebar when the terminal is wide enough.", "ConfigChoiceDetailPlacementOff": "Hide the rail entirely.", "ConfigChoiceDetailRailTasks": "Rail shows the live Tasks / To-do / Workers list.", "ConfigChoiceDetailRailAgents": "Rail shows sub-agents and fan-out state.", "ConfigChoiceDetailRailContext": "Rail shows workspace, token, and cost context.", - "ConfigChoiceDetailRailPinned": "Rail shows the pinned goal and checklist summary.", "ConfigChoiceDetailLowMotionOn": "Stops live-state movement without changing model output.", "ConfigChoiceDetailLowMotionOff": "Allows motion selected by the other appearance settings.", "ConfigChoiceDetailFancyOn": "Animates truthful tool, status, and ocean live state.", @@ -1978,8 +1977,8 @@ "ConfigHintInlineDiffs": "full | summary | off; exact change remains in Alt/Option+V details", "ConfigHintToolCollapse": "compact | expanded | calm", "ConfigHintBackgroundColor": "#RRGGBB | default", - "ConfigHintWorkSurfacePlacement": "top | left | right | off · side rails require Ocean mode and at least 72 columns", - "ConfigHintRailPanel": "tasks | agents | context | pinned · which panel the rail shows", + "ConfigHintWorkSurfacePlacement": "bottom | top | left | right | off · side rails require Ocean mode and at least 72 columns", + "ConfigHintRailPanel": "tasks | agents | background | files | notepad | context | git | price · which panel the rail shows", "ConfigHintWorkSurfaceTopHeight": "5..=16 rows · also adjustable by dragging the divider", "ConfigHintWorkSurfaceSideWidth": "26..=80 columns · also adjustable by dragging the divider", "ConfigHintBaseUrl": "read-only route receipt for the live endpoint · change provider, credential, and endpoint together with /provider", diff --git a/crates/tui/locales/es-419.json b/crates/tui/locales/es-419.json index 5f024d3a11..40285c521a 100644 --- a/crates/tui/locales/es-419.json +++ b/crates/tui/locales/es-419.json @@ -1926,14 +1926,13 @@ "ConfigChoiceModePlan": "Planificar (solo lectura)", "ConfigChoiceModeOperate": "Operar", "ConfigChoicePlacementTop": "Arriba", + "ConfigChoicePlacementBottom": "Barra inferior", "ConfigChoicePlacementLeft": "Barra lateral izquierda", "ConfigChoicePlacementRight": "Barra lateral derecha", "ConfigChoiceRailTasks": "Tareas", "ConfigChoiceRailAgents": "Agentes", "ConfigChoiceRailContext": "Contexto", - "ConfigChoiceRailPinned": "Fijados", "ConfigChoiceStatusCw": "Marca Codewhale", - "ConfigChoiceStatusWhale": "Ballena animada", "ConfigChoiceStatusDots": "Puntos animados", "ConfigChoiceDiffFull": "Diff completo", "ConfigChoiceDiffSummary": "Resumen", @@ -1946,13 +1945,13 @@ "ConfigChoiceDetailModePlan": "Empieza en un espacio de planificación de solo lectura.", "ConfigChoiceDetailModeOperate": "Operate convierte tu pedido en una meta y la trabaja en paralelo: workers en segundo plano para flujos separables, verificados antes de detenerse.", "ConfigChoiceDetailPlacementTop": "Muestra Tareas, Pendientes y Workers encima de la transcripción.", + "ConfigChoiceDetailPlacementBottom": "Muestra Tareas, Pendientes y Workers debajo del editor.", "ConfigChoiceDetailPlacementLeft": "Muestra Tareas, Pendientes y Workers en una barra lateral izquierda cuando la terminal es lo bastante ancha.", "ConfigChoiceDetailPlacementRight": "Muestra Tareas, Pendientes y Workers en una barra lateral derecha cuando la terminal es lo bastante ancha.", "ConfigChoiceDetailPlacementOff": "Oculta el riel por completo.", "ConfigChoiceDetailRailTasks": "El riel muestra la lista en vivo de Tareas / Pendientes / Workers.", "ConfigChoiceDetailRailAgents": "El riel muestra subagentes y el estado de distribución.", "ConfigChoiceDetailRailContext": "El riel muestra el contexto de workspace, tokens y costo.", - "ConfigChoiceDetailRailPinned": "El riel muestra el objetivo fijado y el resumen de la lista de verificación.", "ConfigChoiceDetailLowMotionOn": "Detiene el movimiento del estado en vivo sin cambiar la salida del modelo.", "ConfigChoiceDetailLowMotionOff": "Permite el movimiento elegido en los otros ajustes de apariencia.", "ConfigChoiceDetailFancyOn": "Anima con fidelidad el estado en vivo de herramientas, estado y océano.", @@ -1978,8 +1977,8 @@ "ConfigHintInlineDiffs": "full | summary | off; el cambio exacto permanece en los detalles de Alt/Option+V", "ConfigHintToolCollapse": "compact | expanded | calm", "ConfigHintBackgroundColor": "#RRGGBB | default", - "ConfigHintWorkSurfacePlacement": "top | left | right | off · los rieles laterales requieren el modo Ocean y al menos 72 columnas", - "ConfigHintRailPanel": "tasks | agents | context | pinned · qué panel muestra el riel", + "ConfigHintWorkSurfacePlacement": "bottom | top | left | right | off · los rieles laterales requieren el modo Ocean y al menos 72 columnas", + "ConfigHintRailPanel": "tasks | agents | background | files | notepad | context | git | price · qué panel muestra el riel", "ConfigHintWorkSurfaceTopHeight": "5..=16 filas · también ajustable arrastrando el divisor", "ConfigHintWorkSurfaceSideWidth": "26..=80 columnas · también ajustable arrastrando el divisor", "ConfigHintBaseUrl": "recibo de ruta de solo lectura del endpoint en vivo · cambia proveedor, credencial y endpoint juntos con /provider", diff --git a/crates/tui/locales/fr.json b/crates/tui/locales/fr.json index e6e9961ef0..0d69e90dec 100644 --- a/crates/tui/locales/fr.json +++ b/crates/tui/locales/fr.json @@ -1926,14 +1926,13 @@ "ConfigChoiceModePlan": "Planifier (lecture seule)", "ConfigChoiceModeOperate": "Piloter", "ConfigChoicePlacementTop": "En haut", + "ConfigChoicePlacementBottom": "Barre inférieure", "ConfigChoicePlacementLeft": "Barre latérale gauche", "ConfigChoicePlacementRight": "Barre latérale droite", "ConfigChoiceRailTasks": "Tâches", "ConfigChoiceRailAgents": "Agents", "ConfigChoiceRailContext": "Contexte", - "ConfigChoiceRailPinned": "Épinglés", "ConfigChoiceStatusCw": "Marque Codewhale", - "ConfigChoiceStatusWhale": "Baleine animée", "ConfigChoiceStatusDots": "Points animés", "ConfigChoiceDiffFull": "Diff complet", "ConfigChoiceDiffSummary": "Résumé", @@ -1946,13 +1945,13 @@ "ConfigChoiceDetailModePlan": "Démarre dans un espace de planification en lecture seule.", "ConfigChoiceDetailModeOperate": "Operate transforme votre demande en objectif et y travaille en parallèle : workers en arrière-plan pour les flux séparables, vérifiés avant de s'arrêter.", "ConfigChoiceDetailPlacementTop": "Affiche Tâches, À faire et Workers au-dessus de la transcription.", + "ConfigChoiceDetailPlacementBottom": "Affiche Tâches, À faire et Workers sous le composer.", "ConfigChoiceDetailPlacementLeft": "Affiche Tâches, À faire et Workers dans une barre latérale gauche quand le terminal est assez large.", "ConfigChoiceDetailPlacementRight": "Affiche Tâches, À faire et Workers dans une barre latérale droite quand le terminal est assez large.", "ConfigChoiceDetailPlacementOff": "Masque entièrement le rail.", "ConfigChoiceDetailRailTasks": "Le rail affiche la liste en direct Tâches / À faire / Workers.", "ConfigChoiceDetailRailAgents": "Le rail affiche les sous-agents et l'état de distribution.", "ConfigChoiceDetailRailContext": "Le rail affiche le contexte d'espace de travail, de jetons et de coût.", - "ConfigChoiceDetailRailPinned": "Le rail affiche l'objectif épinglé et le résumé de la liste de contrôle.", "ConfigChoiceDetailLowMotionOn": "Arrête le mouvement de l'état en direct sans changer la sortie du modèle.", "ConfigChoiceDetailLowMotionOff": "Autorise le mouvement choisi dans les autres réglages d'apparence.", "ConfigChoiceDetailFancyOn": "Anime fidèlement l'état en direct des outils, du statut et de l'océan.", @@ -1978,8 +1977,8 @@ "ConfigHintInlineDiffs": "full | summary | off ; le changement exact reste dans les détails Alt/Option+V", "ConfigHintToolCollapse": "compact | expanded | calm", "ConfigHintBackgroundColor": "#RRGGBB | default", - "ConfigHintWorkSurfacePlacement": "top | left | right | off · les rails latéraux exigent le mode Ocean et au moins 72 colonnes", - "ConfigHintRailPanel": "tasks | agents | context | pinned · le panneau affiché par le rail", + "ConfigHintWorkSurfacePlacement": "bottom | top | left | right | off · les rails latéraux exigent le mode Ocean et au moins 72 colonnes", + "ConfigHintRailPanel": "tasks | agents | background | files | notepad | context | git | price · le panneau affiché par le rail", "ConfigHintWorkSurfaceTopHeight": "5..=16 lignes · réglable aussi en faisant glisser le séparateur", "ConfigHintWorkSurfaceSideWidth": "26..=80 colonnes · réglable aussi en faisant glisser le séparateur", "ConfigHintBaseUrl": "reçu de route en lecture seule du point de terminaison en direct · changez fournisseur, identifiants et point de terminaison ensemble avec /provider", diff --git a/crates/tui/locales/hi.json b/crates/tui/locales/hi.json index 27e7361d5a..502a8aa70f 100644 --- a/crates/tui/locales/hi.json +++ b/crates/tui/locales/hi.json @@ -1926,14 +1926,13 @@ "ConfigChoiceModePlan": "योजना (केवल पढ़ने योग्य)", "ConfigChoiceModeOperate": "संचालन", "ConfigChoicePlacementTop": "ऊपर", + "ConfigChoicePlacementBottom": "निचली पट्टी", "ConfigChoicePlacementLeft": "बायाँ साइडबार", "ConfigChoicePlacementRight": "दायाँ साइडबार", "ConfigChoiceRailTasks": "कार्य सूची", "ConfigChoiceRailAgents": "एजेंट", "ConfigChoiceRailContext": "संदर्भ", - "ConfigChoiceRailPinned": "पिन किए गए", "ConfigChoiceStatusCw": "Codewhale चिह्न", - "ConfigChoiceStatusWhale": "चलती व्हेल", "ConfigChoiceStatusDots": "चलते बिंदु", "ConfigChoiceDiffFull": "पूरा diff", "ConfigChoiceDiffSummary": "सारांश", @@ -1946,13 +1945,13 @@ "ConfigChoiceDetailModePlan": "केवल पढ़ने योग्य योजना क्षेत्र में शुरू होता है।", "ConfigChoiceDetailModeOperate": "Operate आपके प्रॉम्प्ट को लक्ष्य बनाकर उस पर समानांतर काम करता है: अलग की जा सकने वाली धाराओं के लिए पृष्ठभूमि worker, रुकने से पहले सत्यापित।", "ConfigChoiceDetailPlacementTop": "कार्य, करने योग्य और Worker को ट्रांसक्रिप्ट के ऊपर दिखाता है।", + "ConfigChoiceDetailPlacementBottom": "कार्य, करने योग्य और Worker को कम्पोज़र के नीचे दिखाता है।", "ConfigChoiceDetailPlacementLeft": "टर्मिनल पर्याप्त चौड़ा होने पर कार्य, करने योग्य और Worker को बाएँ साइडबार में दिखाता है।", "ConfigChoiceDetailPlacementRight": "टर्मिनल पर्याप्त चौड़ा होने पर कार्य, करने योग्य और Worker को दाएँ साइडबार में दिखाता है।", "ConfigChoiceDetailPlacementOff": "रेल को पूरी तरह छिपाता है।", "ConfigChoiceDetailRailTasks": "रेल लाइव कार्य / करने योग्य / Worker सूची दिखाती है।", "ConfigChoiceDetailRailAgents": "रेल उप-एजेंट और वितरण स्थिति दिखाती है।", "ConfigChoiceDetailRailContext": "रेल कार्यक्षेत्र, टोकन और लागत का संदर्भ दिखाती है।", - "ConfigChoiceDetailRailPinned": "रेल पिन किया गया लक्ष्य और चेकलिस्ट सारांश दिखाती है।", "ConfigChoiceDetailLowMotionOn": "मॉडल आउटपुट बदले बिना लाइव स्थिति की गति रोकता है।", "ConfigChoiceDetailLowMotionOff": "अन्य रूप सेटिंग में चुनी गई गति की अनुमति देता है।", "ConfigChoiceDetailFancyOn": "टूल, स्थिति और समुद्र की लाइव स्थिति को सच्चाई से एनिमेट करता है।", @@ -1978,8 +1977,8 @@ "ConfigHintInlineDiffs": "full | summary | off; सटीक बदलाव Alt/Option+V विवरण में बना रहता है", "ConfigHintToolCollapse": "compact | expanded | calm", "ConfigHintBackgroundColor": "#RRGGBB | default", - "ConfigHintWorkSurfacePlacement": "top | left | right | off · साइड रेल के लिए Ocean मोड और कम से कम 72 स्तंभ चाहिए", - "ConfigHintRailPanel": "tasks | agents | context | pinned · रेल कौन सा पैनल दिखाए", + "ConfigHintWorkSurfacePlacement": "bottom | top | left | right | off · साइड रेल के लिए Ocean मोड और कम से कम 72 स्तंभ चाहिए", + "ConfigHintRailPanel": "tasks | agents | background | files | notepad | context | git | price · रेल कौन सा पैनल दिखाए", "ConfigHintWorkSurfaceTopHeight": "5..=16 पंक्तियाँ · विभाजक खींचकर भी समायोजित कर सकते हैं", "ConfigHintWorkSurfaceSideWidth": "26..=80 स्तंभ · विभाजक खींचकर भी समायोजित कर सकते हैं", "ConfigHintBaseUrl": "लाइव endpoint की केवल पढ़ने योग्य रूट रसीद · प्रदाता, क्रेडेंशियल और endpoint को /provider से एक साथ बदलें", diff --git a/crates/tui/locales/id.json b/crates/tui/locales/id.json index 9f2b903e7d..be461923b8 100644 --- a/crates/tui/locales/id.json +++ b/crates/tui/locales/id.json @@ -1926,14 +1926,13 @@ "ConfigChoiceModePlan": "Rencana (hanya-baca)", "ConfigChoiceModeOperate": "Operasikan", "ConfigChoicePlacementTop": "Atas", + "ConfigChoicePlacementBottom": "Bilah bawah", "ConfigChoicePlacementLeft": "Bilah samping kiri", "ConfigChoicePlacementRight": "Bilah samping kanan", "ConfigChoiceRailTasks": "Tugas", "ConfigChoiceRailAgents": "Agen", "ConfigChoiceRailContext": "Konteks", - "ConfigChoiceRailPinned": "Disematkan", "ConfigChoiceStatusCw": "Tanda Codewhale", - "ConfigChoiceStatusWhale": "Paus animasi", "ConfigChoiceStatusDots": "Titik animasi", "ConfigChoiceDiffFull": "Diff lengkap", "ConfigChoiceDiffSummary": "Ringkasan", @@ -1946,13 +1945,13 @@ "ConfigChoiceDetailModePlan": "Mulai di ruang perencanaan hanya-baca.", "ConfigChoiceDetailModeOperate": "Operate mengubah prompt Anda menjadi tujuan dan mengerjakannya secara paralel: worker latar belakang untuk alur yang bisa dipisah, diverifikasi sebelum berhenti.", "ConfigChoiceDetailPlacementTop": "Menampilkan Tugas, Daftar tugas, dan Worker di atas transkrip.", + "ConfigChoiceDetailPlacementBottom": "Menampilkan Tugas, Daftar tugas, dan Worker di bawah komposer.", "ConfigChoiceDetailPlacementLeft": "Menampilkan Tugas, Daftar tugas, dan Worker di bilah samping kiri saat terminal cukup lebar.", "ConfigChoiceDetailPlacementRight": "Menampilkan Tugas, Daftar tugas, dan Worker di bilah samping kanan saat terminal cukup lebar.", "ConfigChoiceDetailPlacementOff": "Menyembunyikan rel sepenuhnya.", "ConfigChoiceDetailRailTasks": "Rel menampilkan daftar langsung Tugas / Daftar tugas / Worker.", "ConfigChoiceDetailRailAgents": "Rel menampilkan sub-agen dan status penyebaran.", "ConfigChoiceDetailRailContext": "Rel menampilkan konteks ruang kerja, token, dan biaya.", - "ConfigChoiceDetailRailPinned": "Rel menampilkan tujuan yang disematkan dan ringkasan daftar periksa.", "ConfigChoiceDetailLowMotionOn": "Menghentikan gerakan status langsung tanpa mengubah keluaran model.", "ConfigChoiceDetailLowMotionOff": "Mengizinkan gerakan yang dipilih oleh pengaturan tampilan lain.", "ConfigChoiceDetailFancyOn": "Menganimasikan status langsung alat, status, dan lautan secara jujur.", @@ -1978,8 +1977,8 @@ "ConfigHintInlineDiffs": "full | summary | off; perubahan persis tetap ada di detail Alt/Option+V", "ConfigHintToolCollapse": "compact | expanded | calm", "ConfigHintBackgroundColor": "#RRGGBB | default", - "ConfigHintWorkSurfacePlacement": "top | left | right | off · rel samping memerlukan mode Ocean dan minimal 72 kolom", - "ConfigHintRailPanel": "tasks | agents | context | pinned · panel yang ditampilkan rel", + "ConfigHintWorkSurfacePlacement": "bottom | top | left | right | off · rel samping memerlukan mode Ocean dan minimal 72 kolom", + "ConfigHintRailPanel": "tasks | agents | background | files | notepad | context | git | price · panel yang ditampilkan rel", "ConfigHintWorkSurfaceTopHeight": "5..=16 baris · juga bisa diatur dengan menyeret pembatas", "ConfigHintWorkSurfaceSideWidth": "26..=80 kolom · juga bisa diatur dengan menyeret pembatas", "ConfigHintBaseUrl": "tanda terima rute hanya-baca untuk endpoint langsung · ubah penyedia, kredensial, dan endpoint bersama lewat /provider", diff --git a/crates/tui/locales/ja.json b/crates/tui/locales/ja.json index fc4951dcd2..f9d838a6bd 100644 --- a/crates/tui/locales/ja.json +++ b/crates/tui/locales/ja.json @@ -1926,14 +1926,13 @@ "ConfigChoiceModePlan": "計画 (読み取り専用)", "ConfigChoiceModeOperate": "オペレート", "ConfigChoicePlacementTop": "上部", + "ConfigChoicePlacementBottom": "下部バー", "ConfigChoicePlacementLeft": "左サイドバー", "ConfigChoicePlacementRight": "右サイドバー", "ConfigChoiceRailTasks": "タスク", "ConfigChoiceRailAgents": "エージェント", "ConfigChoiceRailContext": "コンテキスト", - "ConfigChoiceRailPinned": "ピン留め", "ConfigChoiceStatusCw": "Codewhale マーク", - "ConfigChoiceStatusWhale": "アニメーションのクジラ", "ConfigChoiceStatusDots": "アニメーションのドット", "ConfigChoiceDiffFull": "完全な差分", "ConfigChoiceDiffSummary": "要約", @@ -1946,13 +1945,13 @@ "ConfigChoiceDetailModePlan": "読み取り専用の計画ワークスペースで開始します。", "ConfigChoiceDetailModeOperate": "Operate はプロンプトを目標にして並列で進めます。分離できる流れはバックグラウンドワーカーに任せ、停止前に検証します。", "ConfigChoiceDetailPlacementTop": "タスク・To-do・ワーカーをトランスクリプトの上に表示します。", + "ConfigChoiceDetailPlacementBottom": "タスク・To-do・ワーカーを入力欄の下に表示します。", "ConfigChoiceDetailPlacementLeft": "端末が十分に広いとき、タスク・To-do・ワーカーを左サイドバーに表示します。", "ConfigChoiceDetailPlacementRight": "端末が十分に広いとき、タスク・To-do・ワーカーを右サイドバーに表示します。", "ConfigChoiceDetailPlacementOff": "レールを完全に隠します。", "ConfigChoiceDetailRailTasks": "レールにライブのタスク / To-do / ワーカー一覧を表示します。", "ConfigChoiceDetailRailAgents": "レールにサブエージェントとファンアウト状態を表示します。", "ConfigChoiceDetailRailContext": "レールにワークスペース・トークン・コストのコンテキストを表示します。", - "ConfigChoiceDetailRailPinned": "レールにピン留めした目標とチェックリストの要約を表示します。", "ConfigChoiceDetailLowMotionOn": "モデル出力を変えずにライブ状態の動きを止めます。", "ConfigChoiceDetailLowMotionOff": "他の外観設定で選んだ動きを許可します。", "ConfigChoiceDetailFancyOn": "ツール・状態・海のライブ状態を忠実にアニメーションします。", @@ -1978,8 +1977,8 @@ "ConfigHintInlineDiffs": "full | summary | off。正確な変更は Alt/Option+V の詳細に残ります", "ConfigHintToolCollapse": "compact | expanded | calm", "ConfigHintBackgroundColor": "#RRGGBB | default", - "ConfigHintWorkSurfacePlacement": "top | left | right | off · サイドレールには Ocean モードと 72 列以上が必要です", - "ConfigHintRailPanel": "tasks | agents | context | pinned · レールに表示するパネル", + "ConfigHintWorkSurfacePlacement": "bottom | top | left | right | off · サイドレールには Ocean モードと 72 列以上が必要です", + "ConfigHintRailPanel": "tasks | agents | background | files | notepad | context | git | price · レールに表示するパネル", "ConfigHintWorkSurfaceTopHeight": "5..=16 行 · 区切り線のドラッグでも調整できます", "ConfigHintWorkSurfaceSideWidth": "26..=80 列 · 区切り線のドラッグでも調整できます", "ConfigHintBaseUrl": "ライブエンドポイントの読み取り専用ルートレシート · プロバイダー・資格情報・エンドポイントは /provider でまとめて変更します", diff --git a/crates/tui/locales/ko.json b/crates/tui/locales/ko.json index ca79888ef6..b4211c9722 100644 --- a/crates/tui/locales/ko.json +++ b/crates/tui/locales/ko.json @@ -1926,14 +1926,13 @@ "ConfigChoiceModePlan": "계획 (읽기 전용)", "ConfigChoiceModeOperate": "운영", "ConfigChoicePlacementTop": "상단", + "ConfigChoicePlacementBottom": "하단 바", "ConfigChoicePlacementLeft": "왼쪽 사이드바", "ConfigChoicePlacementRight": "오른쪽 사이드바", "ConfigChoiceRailTasks": "작업", "ConfigChoiceRailAgents": "에이전트", "ConfigChoiceRailContext": "컨텍스트", - "ConfigChoiceRailPinned": "고정됨", "ConfigChoiceStatusCw": "Codewhale 마크", - "ConfigChoiceStatusWhale": "움직이는 고래", "ConfigChoiceStatusDots": "움직이는 점", "ConfigChoiceDiffFull": "전체 diff", "ConfigChoiceDiffSummary": "요약", @@ -1946,13 +1945,13 @@ "ConfigChoiceDetailModePlan": "읽기 전용 계획 작업 공간에서 시작합니다.", "ConfigChoiceDetailModeOperate": "Operate는 프롬프트를 목표로 바꿔 병렬로 진행합니다. 분리 가능한 흐름은 백그라운드 작업자에게 맡기고, 멈추기 전에 검증합니다.", "ConfigChoiceDetailPlacementTop": "작업, 할 일, 작업자를 대화 기록 위에 표시합니다.", + "ConfigChoiceDetailPlacementBottom": "작업, 할 일, 작업자를 작성기 아래에 표시합니다.", "ConfigChoiceDetailPlacementLeft": "터미널이 충분히 넓을 때 작업, 할 일, 작업자를 왼쪽 사이드바에 표시합니다.", "ConfigChoiceDetailPlacementRight": "터미널이 충분히 넓을 때 작업, 할 일, 작업자를 오른쪽 사이드바에 표시합니다.", "ConfigChoiceDetailPlacementOff": "레일을 완전히 숨깁니다.", "ConfigChoiceDetailRailTasks": "레일에 실시간 작업 / 할 일 / 작업자 목록을 표시합니다.", "ConfigChoiceDetailRailAgents": "레일에 하위 에이전트와 팬아웃 상태를 표시합니다.", "ConfigChoiceDetailRailContext": "레일에 작업 공간, 토큰, 비용 컨텍스트를 표시합니다.", - "ConfigChoiceDetailRailPinned": "레일에 고정된 목표와 체크리스트 요약을 표시합니다.", "ConfigChoiceDetailLowMotionOn": "모델 출력을 바꾸지 않고 실시간 상태의 움직임을 멈춥니다.", "ConfigChoiceDetailLowMotionOff": "다른 모양 설정에서 선택한 움직임을 허용합니다.", "ConfigChoiceDetailFancyOn": "도구, 상태, 바다의 실시간 상태를 사실대로 애니메이션합니다.", @@ -1978,8 +1977,8 @@ "ConfigHintInlineDiffs": "full | summary | off. 정확한 변경은 Alt/Option+V 세부 정보에 남음", "ConfigHintToolCollapse": "compact | expanded | calm", "ConfigHintBackgroundColor": "#RRGGBB | default", - "ConfigHintWorkSurfacePlacement": "top | left | right | off · 사이드 레일은 Ocean 모드와 72열 이상 필요", - "ConfigHintRailPanel": "tasks | agents | context | pinned · 레일에 표시할 패널", + "ConfigHintWorkSurfacePlacement": "bottom | top | left | right | off · 사이드 레일은 Ocean 모드와 72열 이상 필요", + "ConfigHintRailPanel": "tasks | agents | background | files | notepad | context | git | price · 레일에 표시할 패널", "ConfigHintWorkSurfaceTopHeight": "5..=16행 · 구분선을 끌어서도 조정 가능", "ConfigHintWorkSurfaceSideWidth": "26..=80열 · 구분선을 끌어서도 조정 가능", "ConfigHintBaseUrl": "실시간 엔드포인트의 읽기 전용 경로 영수증 · 제공자, 자격 증명, 엔드포인트는 /provider로 함께 변경", diff --git a/crates/tui/locales/pt-BR.json b/crates/tui/locales/pt-BR.json index 1192f37945..5626e9d3d7 100644 --- a/crates/tui/locales/pt-BR.json +++ b/crates/tui/locales/pt-BR.json @@ -1926,14 +1926,13 @@ "ConfigChoiceModePlan": "Planejar (somente leitura)", "ConfigChoiceModeOperate": "Operar", "ConfigChoicePlacementTop": "Topo", + "ConfigChoicePlacementBottom": "Barra inferior", "ConfigChoicePlacementLeft": "Barra lateral esquerda", "ConfigChoicePlacementRight": "Barra lateral direita", "ConfigChoiceRailTasks": "Tarefas", "ConfigChoiceRailAgents": "Agentes", "ConfigChoiceRailContext": "Contexto", - "ConfigChoiceRailPinned": "Fixados", "ConfigChoiceStatusCw": "Marca Codewhale", - "ConfigChoiceStatusWhale": "Baleia animada", "ConfigChoiceStatusDots": "Pontos animados", "ConfigChoiceDiffFull": "Diff completo", "ConfigChoiceDiffSummary": "Resumo", @@ -1946,13 +1945,13 @@ "ConfigChoiceDetailModePlan": "Começa em um espaço de planejamento somente leitura.", "ConfigChoiceDetailModeOperate": "Operate transforma seu pedido em uma meta e trabalha nela em paralelo: workers em segundo plano para fluxos separáveis, verificados antes de parar.", "ConfigChoiceDetailPlacementTop": "Mostra Tarefas, A fazer e Workers acima da transcrição.", + "ConfigChoiceDetailPlacementBottom": "Mostra Tarefas, A fazer e Workers abaixo do editor.", "ConfigChoiceDetailPlacementLeft": "Mostra Tarefas, A fazer e Workers em uma barra lateral esquerda quando o terminal é largo o bastante.", "ConfigChoiceDetailPlacementRight": "Mostra Tarefas, A fazer e Workers em uma barra lateral direita quando o terminal é largo o bastante.", "ConfigChoiceDetailPlacementOff": "Oculta o trilho por completo.", "ConfigChoiceDetailRailTasks": "O trilho mostra a lista ao vivo de Tarefas / A fazer / Workers.", "ConfigChoiceDetailRailAgents": "O trilho mostra subagentes e o estado de distribuição.", "ConfigChoiceDetailRailContext": "O trilho mostra o contexto de workspace, tokens e custo.", - "ConfigChoiceDetailRailPinned": "O trilho mostra o objetivo fixado e o resumo da lista de verificação.", "ConfigChoiceDetailLowMotionOn": "Para o movimento do estado ao vivo sem alterar a saída do modelo.", "ConfigChoiceDetailLowMotionOff": "Permite o movimento escolhido nas outras configurações de aparência.", "ConfigChoiceDetailFancyOn": "Anima com fidelidade o estado ao vivo de ferramentas, status e oceano.", @@ -1978,8 +1977,8 @@ "ConfigHintInlineDiffs": "full | summary | off; a mudança exata permanece nos detalhes de Alt/Option+V", "ConfigHintToolCollapse": "compact | expanded | calm", "ConfigHintBackgroundColor": "#RRGGBB | default", - "ConfigHintWorkSurfacePlacement": "top | left | right | off · trilhos laterais exigem o modo Ocean e pelo menos 72 colunas", - "ConfigHintRailPanel": "tasks | agents | context | pinned · qual painel o trilho mostra", + "ConfigHintWorkSurfacePlacement": "bottom | top | left | right | off · trilhos laterais exigem o modo Ocean e pelo menos 72 colunas", + "ConfigHintRailPanel": "tasks | agents | background | files | notepad | context | git | price · qual painel o trilho mostra", "ConfigHintWorkSurfaceTopHeight": "5..=16 linhas · também ajustável arrastando o divisor", "ConfigHintWorkSurfaceSideWidth": "26..=80 colunas · também ajustável arrastando o divisor", "ConfigHintBaseUrl": "recibo de rota somente leitura do endpoint ao vivo · mude provedor, credencial e endpoint juntos com /provider", diff --git a/crates/tui/locales/ru.json b/crates/tui/locales/ru.json index 8b442bdb8f..da0ec681b9 100644 --- a/crates/tui/locales/ru.json +++ b/crates/tui/locales/ru.json @@ -1926,14 +1926,13 @@ "ConfigChoiceModePlan": "Планировать (только чтение)", "ConfigChoiceModeOperate": "Управлять", "ConfigChoicePlacementTop": "Сверху", + "ConfigChoicePlacementBottom": "Нижняя панель", "ConfigChoicePlacementLeft": "Левая боковая панель", "ConfigChoicePlacementRight": "Правая боковая панель", "ConfigChoiceRailTasks": "Задачи", "ConfigChoiceRailAgents": "Агенты", "ConfigChoiceRailContext": "Контекст", - "ConfigChoiceRailPinned": "Закреплённое", "ConfigChoiceStatusCw": "Знак Codewhale", - "ConfigChoiceStatusWhale": "Анимированный кит", "ConfigChoiceStatusDots": "Анимированные точки", "ConfigChoiceDiffFull": "Полный diff", "ConfigChoiceDiffSummary": "Сводка", @@ -1946,13 +1945,13 @@ "ConfigChoiceDetailModePlan": "Начинает в пространстве планирования только для чтения.", "ConfigChoiceDetailModeOperate": "Operate превращает запрос в цель и ведёт её параллельно: фоновые исполнители для разделимых потоков, проверка перед остановкой.", "ConfigChoiceDetailPlacementTop": "Показывает задачи, список дел и исполнителей над стенограммой.", + "ConfigChoiceDetailPlacementBottom": "Показывает задачи, список дел и исполнителей под полем ввода.", "ConfigChoiceDetailPlacementLeft": "Показывает задачи, список дел и исполнителей в левой боковой панели, когда терминал достаточно широк.", "ConfigChoiceDetailPlacementRight": "Показывает задачи, список дел и исполнителей в правой боковой панели, когда терминал достаточно широк.", "ConfigChoiceDetailPlacementOff": "Полностью скрывает панель.", "ConfigChoiceDetailRailTasks": "Панель показывает живой список задач / дел / исполнителей.", "ConfigChoiceDetailRailAgents": "Панель показывает субагентов и состояние распараллеливания.", "ConfigChoiceDetailRailContext": "Панель показывает контекст рабочей области, токенов и стоимости.", - "ConfigChoiceDetailRailPinned": "Панель показывает закреплённую цель и сводку чек-листа.", "ConfigChoiceDetailLowMotionOn": "Останавливает движение живого состояния, не меняя вывод модели.", "ConfigChoiceDetailLowMotionOff": "Разрешает движение, выбранное другими настройками оформления.", "ConfigChoiceDetailFancyOn": "Честно анимирует живое состояние инструментов, статуса и океана.", @@ -1978,8 +1977,8 @@ "ConfigHintInlineDiffs": "full | summary | off; точное изменение остаётся в подробностях по Alt/Option+V", "ConfigHintToolCollapse": "compact | expanded | calm", "ConfigHintBackgroundColor": "#RRGGBB | default", - "ConfigHintWorkSurfacePlacement": "top | left | right | off · боковым панелям нужны режим Ocean и не меньше 72 столбцов", - "ConfigHintRailPanel": "tasks | agents | context | pinned · какую панель показывать", + "ConfigHintWorkSurfacePlacement": "bottom | top | left | right | off · боковым панелям нужны режим Ocean и не меньше 72 столбцов", + "ConfigHintRailPanel": "tasks | agents | background | files | notepad | context | git | price · какую панель показывать", "ConfigHintWorkSurfaceTopHeight": "5..=16 строк · также настраивается перетаскиванием разделителя", "ConfigHintWorkSurfaceSideWidth": "26..=80 столбцов · также настраивается перетаскиванием разделителя", "ConfigHintBaseUrl": "квитанция маршрута только для чтения для живого адреса · провайдер, учётные данные и адрес меняются вместе через /provider", diff --git a/crates/tui/locales/uk.json b/crates/tui/locales/uk.json index 045531e716..ed2222474c 100644 --- a/crates/tui/locales/uk.json +++ b/crates/tui/locales/uk.json @@ -1926,14 +1926,13 @@ "ConfigChoiceModePlan": "Планувати (лише читання)", "ConfigChoiceModeOperate": "Керувати", "ConfigChoicePlacementTop": "Угорі", + "ConfigChoicePlacementBottom": "Нижня панель", "ConfigChoicePlacementLeft": "Ліва бічна панель", "ConfigChoicePlacementRight": "Права бічна панель", "ConfigChoiceRailTasks": "Завдання", "ConfigChoiceRailAgents": "Агенти", "ConfigChoiceRailContext": "Контекст", - "ConfigChoiceRailPinned": "Закріплене", "ConfigChoiceStatusCw": "Знак Codewhale", - "ConfigChoiceStatusWhale": "Анімований кит", "ConfigChoiceStatusDots": "Анімовані крапки", "ConfigChoiceDiffFull": "Повний diff", "ConfigChoiceDiffSummary": "Зведення", @@ -1946,13 +1945,13 @@ "ConfigChoiceDetailModePlan": "Починає в просторі планування лише для читання.", "ConfigChoiceDetailModeOperate": "Operate перетворює запит на ціль і веде її паралельно: фонові виконавці для розділюваних потоків, перевірка перед зупинкою.", "ConfigChoiceDetailPlacementTop": "Показує завдання, список справ і виконавців над стенограмою.", + "ConfigChoiceDetailPlacementBottom": "Показує завдання, список справ і виконавців під композером.", "ConfigChoiceDetailPlacementLeft": "Показує завдання, список справ і виконавців у лівій бічній панелі, коли термінал достатньо широкий.", "ConfigChoiceDetailPlacementRight": "Показує завдання, список справ і виконавців у правій бічній панелі, коли термінал достатньо широкий.", "ConfigChoiceDetailPlacementOff": "Повністю ховає панель.", "ConfigChoiceDetailRailTasks": "Панель показує живий список завдань / справ / виконавців.", "ConfigChoiceDetailRailAgents": "Панель показує субагентів і стан розпаралелення.", "ConfigChoiceDetailRailContext": "Панель показує контекст робочого простору, токенів і вартості.", - "ConfigChoiceDetailRailPinned": "Панель показує закріплену ціль і зведення чеклиста.", "ConfigChoiceDetailLowMotionOn": "Зупиняє рух живого стану, не змінюючи вивід моделі.", "ConfigChoiceDetailLowMotionOff": "Дозволяє рух, вибраний іншими налаштуваннями оформлення.", "ConfigChoiceDetailFancyOn": "Чесно анімує живий стан інструментів, статусу та океану.", @@ -1978,8 +1977,8 @@ "ConfigHintInlineDiffs": "full | summary | off; точна зміна залишається в подробицях за Alt/Option+V", "ConfigHintToolCollapse": "compact | expanded | calm", "ConfigHintBackgroundColor": "#RRGGBB | default", - "ConfigHintWorkSurfacePlacement": "top | left | right | off · бічним панелям потрібні режим Ocean і щонайменше 72 стовпці", - "ConfigHintRailPanel": "tasks | agents | context | pinned · яку панель показувати", + "ConfigHintWorkSurfacePlacement": "bottom | top | left | right | off · бічним панелям потрібні режим Ocean і щонайменше 72 стовпці", + "ConfigHintRailPanel": "tasks | agents | background | files | notepad | context | git | price · яку панель показувати", "ConfigHintWorkSurfaceTopHeight": "5..=16 рядків · також налаштовується перетягуванням роздільника", "ConfigHintWorkSurfaceSideWidth": "26..=80 стовпців · також налаштовується перетягуванням роздільника", "ConfigHintBaseUrl": "квитанція маршруту лише для читання для живої адреси · провайдер, облікові дані та адреса змінюються разом через /provider", diff --git a/crates/tui/locales/vi.json b/crates/tui/locales/vi.json index 682641bc30..d2829a9742 100644 --- a/crates/tui/locales/vi.json +++ b/crates/tui/locales/vi.json @@ -1926,14 +1926,13 @@ "ConfigChoiceModePlan": "Lập kế hoạch (chỉ đọc)", "ConfigChoiceModeOperate": "Vận hành", "ConfigChoicePlacementTop": "Trên cùng", + "ConfigChoicePlacementBottom": "Thanh dưới", "ConfigChoicePlacementLeft": "Thanh bên trái", "ConfigChoicePlacementRight": "Thanh bên phải", "ConfigChoiceRailTasks": "Tác vụ", "ConfigChoiceRailAgents": "Tác nhân", "ConfigChoiceRailContext": "Ngữ cảnh", - "ConfigChoiceRailPinned": "Đã ghim", "ConfigChoiceStatusCw": "Dấu Codewhale", - "ConfigChoiceStatusWhale": "Cá voi động", "ConfigChoiceStatusDots": "Dấu chấm động", "ConfigChoiceDiffFull": "Diff đầy đủ", "ConfigChoiceDiffSummary": "Tóm tắt", @@ -1946,13 +1945,13 @@ "ConfigChoiceDetailModePlan": "Bắt đầu trong không gian lập kế hoạch chỉ đọc.", "ConfigChoiceDetailModeOperate": "Operate biến yêu cầu của bạn thành mục tiêu và làm song song: worker nền cho các luồng tách được, được xác minh trước khi dừng.", "ConfigChoiceDetailPlacementTop": "Hiện Tác vụ, Việc cần làm và Worker phía trên bản ghi.", + "ConfigChoiceDetailPlacementBottom": "Hiện Tác vụ, Việc cần làm và Worker dưới ô soạn thảo.", "ConfigChoiceDetailPlacementLeft": "Hiện Tác vụ, Việc cần làm và Worker ở thanh bên trái khi terminal đủ rộng.", "ConfigChoiceDetailPlacementRight": "Hiện Tác vụ, Việc cần làm và Worker ở thanh bên phải khi terminal đủ rộng.", "ConfigChoiceDetailPlacementOff": "Ẩn hoàn toàn thanh ray.", "ConfigChoiceDetailRailTasks": "Thanh ray hiện danh sách trực tiếp Tác vụ / Việc cần làm / Worker.", "ConfigChoiceDetailRailAgents": "Thanh ray hiện tác nhân con và trạng thái phân tán.", "ConfigChoiceDetailRailContext": "Thanh ray hiện ngữ cảnh workspace, token và chi phí.", - "ConfigChoiceDetailRailPinned": "Thanh ray hiện mục tiêu đã ghim và tóm tắt danh sách kiểm tra.", "ConfigChoiceDetailLowMotionOn": "Dừng chuyển động của trạng thái trực tiếp mà không đổi đầu ra của mô hình.", "ConfigChoiceDetailLowMotionOff": "Cho phép chuyển động do các cài đặt giao diện khác chọn.", "ConfigChoiceDetailFancyOn": "Hoạt hóa trung thực trạng thái trực tiếp của công cụ, trạng thái và đại dương.", @@ -1978,8 +1977,8 @@ "ConfigHintInlineDiffs": "full | summary | off; thay đổi chính xác vẫn ở chi tiết Alt/Option+V", "ConfigHintToolCollapse": "compact | expanded | calm", "ConfigHintBackgroundColor": "#RRGGBB | default", - "ConfigHintWorkSurfacePlacement": "top | left | right | off · thanh ray bên cần chế độ Ocean và ít nhất 72 cột", - "ConfigHintRailPanel": "tasks | agents | context | pinned · bảng mà thanh ray hiển thị", + "ConfigHintWorkSurfacePlacement": "bottom | top | left | right | off · thanh ray bên cần chế độ Ocean và ít nhất 72 cột", + "ConfigHintRailPanel": "tasks | agents | background | files | notepad | context | git | price · bảng mà thanh ray hiển thị", "ConfigHintWorkSurfaceTopHeight": "5..=16 hàng · cũng chỉnh được bằng cách kéo vạch chia", "ConfigHintWorkSurfaceSideWidth": "26..=80 cột · cũng chỉnh được bằng cách kéo vạch chia", "ConfigHintBaseUrl": "biên nhận tuyến chỉ đọc của endpoint trực tiếp · đổi nhà cung cấp, thông tin xác thực và endpoint cùng nhau bằng /provider", diff --git a/crates/tui/locales/zh-Hans.json b/crates/tui/locales/zh-Hans.json index a44e79db03..407dcd84a4 100644 --- a/crates/tui/locales/zh-Hans.json +++ b/crates/tui/locales/zh-Hans.json @@ -1926,14 +1926,13 @@ "ConfigChoiceModePlan": "规划(只读)", "ConfigChoiceModeOperate": "运营", "ConfigChoicePlacementTop": "顶部", + "ConfigChoicePlacementBottom": "底部栏", "ConfigChoicePlacementLeft": "左侧边栏", "ConfigChoicePlacementRight": "右侧边栏", "ConfigChoiceRailTasks": "任务", "ConfigChoiceRailAgents": "代理", "ConfigChoiceRailContext": "上下文", - "ConfigChoiceRailPinned": "已固定", "ConfigChoiceStatusCw": "Codewhale 标记", - "ConfigChoiceStatusWhale": "动画鲸鱼", "ConfigChoiceStatusDots": "动画圆点", "ConfigChoiceDiffFull": "完整差异", "ConfigChoiceDiffSummary": "摘要", @@ -1946,13 +1945,13 @@ "ConfigChoiceDetailModePlan": "在只读的规划工作区中开始。", "ConfigChoiceDetailModeOperate": "Operate 把你的提示变成目标并行推进:可拆分的流交给后台工作者,停止前先验证。", "ConfigChoiceDetailPlacementTop": "在对话记录上方显示任务、待办和工作者。", + "ConfigChoiceDetailPlacementBottom": "在输入框下方显示任务、待办和工作者。", "ConfigChoiceDetailPlacementLeft": "终端足够宽时,在左侧边栏显示任务、待办和工作者。", "ConfigChoiceDetailPlacementRight": "终端足够宽时,在右侧边栏显示任务、待办和工作者。", "ConfigChoiceDetailPlacementOff": "完全隐藏侧栏。", "ConfigChoiceDetailRailTasks": "侧栏显示实时的任务 / 待办 / 工作者列表。", "ConfigChoiceDetailRailAgents": "侧栏显示子代理和扇出状态。", "ConfigChoiceDetailRailContext": "侧栏显示工作区、令牌和成本上下文。", - "ConfigChoiceDetailRailPinned": "侧栏显示固定的目标和清单摘要。", "ConfigChoiceDetailLowMotionOn": "停止实时状态的动效,不改变模型输出。", "ConfigChoiceDetailLowMotionOff": "允许其他外观设置所选的动效。", "ConfigChoiceDetailFancyOn": "如实为工具、状态和海洋的实时状态添加动画。", @@ -1978,8 +1977,8 @@ "ConfigHintInlineDiffs": "full | summary | off;精确更改仍在 Alt/Option+V 详情中", "ConfigHintToolCollapse": "compact | expanded | calm", "ConfigHintBackgroundColor": "#RRGGBB | default", - "ConfigHintWorkSurfacePlacement": "top | left | right | off · 侧栏需要 Ocean 模式且至少 72 列", - "ConfigHintRailPanel": "tasks | agents | context | pinned · 侧栏显示的面板", + "ConfigHintWorkSurfacePlacement": "bottom | top | left | right | off · 侧栏需要 Ocean 模式且至少 72 列", + "ConfigHintRailPanel": "tasks | agents | background | files | notepad | context | git | price · 侧栏显示的面板", "ConfigHintWorkSurfaceTopHeight": "5..=16 行 · 也可拖动分隔线调整", "ConfigHintWorkSurfaceSideWidth": "26..=80 列 · 也可拖动分隔线调整", "ConfigHintBaseUrl": "实时端点的只读路由回执 · 通过 /provider 一起更改提供商、凭据和端点", diff --git a/crates/tui/locales/zh-Hant.json b/crates/tui/locales/zh-Hant.json index 26a2898e94..2b741827c8 100644 --- a/crates/tui/locales/zh-Hant.json +++ b/crates/tui/locales/zh-Hant.json @@ -1926,14 +1926,13 @@ "ConfigChoiceModePlan": "規劃(唯讀)", "ConfigChoiceModeOperate": "營運", "ConfigChoicePlacementTop": "頂部", + "ConfigChoicePlacementBottom": "底部欄", "ConfigChoicePlacementLeft": "左側欄", "ConfigChoicePlacementRight": "右側欄", "ConfigChoiceRailTasks": "任務", "ConfigChoiceRailAgents": "代理", "ConfigChoiceRailContext": "情境", - "ConfigChoiceRailPinned": "已釘選", "ConfigChoiceStatusCw": "Codewhale 標記", - "ConfigChoiceStatusWhale": "動畫鯨魚", "ConfigChoiceStatusDots": "動畫圓點", "ConfigChoiceDiffFull": "完整差異", "ConfigChoiceDiffSummary": "摘要", @@ -1946,13 +1945,13 @@ "ConfigChoiceDetailModePlan": "在唯讀的規劃工作區中開始。", "ConfigChoiceDetailModeOperate": "Operate 把你的提示變成目標並行推進:可拆分的流交給背景工作者,停止前先驗證。", "ConfigChoiceDetailPlacementTop": "在對話記錄上方顯示任務、待辦和工作者。", + "ConfigChoiceDetailPlacementBottom": "在輸入框下方顯示任務、待辦和工作者。", "ConfigChoiceDetailPlacementLeft": "終端機夠寬時,在左側欄顯示任務、待辦和工作者。", "ConfigChoiceDetailPlacementRight": "終端機夠寬時,在右側欄顯示任務、待辦和工作者。", "ConfigChoiceDetailPlacementOff": "完全隱藏側欄。", "ConfigChoiceDetailRailTasks": "側欄顯示即時的任務 / 待辦 / 工作者清單。", "ConfigChoiceDetailRailAgents": "側欄顯示子代理和扇出狀態。", "ConfigChoiceDetailRailContext": "側欄顯示工作區、權杖和成本情境。", - "ConfigChoiceDetailRailPinned": "側欄顯示釘選的目標和檢查清單摘要。", "ConfigChoiceDetailLowMotionOn": "停止即時狀態的動態效果,不改變模型輸出。", "ConfigChoiceDetailLowMotionOff": "允許其他外觀設定所選的動態效果。", "ConfigChoiceDetailFancyOn": "如實為工具、狀態和海洋的即時狀態加上動畫。", @@ -1978,8 +1977,8 @@ "ConfigHintInlineDiffs": "full | summary | off;精確變更仍在 Alt/Option+V 詳情中", "ConfigHintToolCollapse": "compact | expanded | calm", "ConfigHintBackgroundColor": "#RRGGBB | default", - "ConfigHintWorkSurfacePlacement": "top | left | right | off · 側欄需要 Ocean 模式且至少 72 欄", - "ConfigHintRailPanel": "tasks | agents | context | pinned · 側欄顯示的面板", + "ConfigHintWorkSurfacePlacement": "bottom | top | left | right | off · 側欄需要 Ocean 模式且至少 72 欄", + "ConfigHintRailPanel": "tasks | agents | background | files | notepad | context | git | price · 側欄顯示的面板", "ConfigHintWorkSurfaceTopHeight": "5..=16 列 · 也可拖曳分隔線調整", "ConfigHintWorkSurfaceSideWidth": "26..=80 欄 · 也可拖曳分隔線調整", "ConfigHintBaseUrl": "即時端點的唯讀路由回條 · 透過 /provider 一起變更提供者、憑證和端點", diff --git a/crates/tui/src/config_ui.rs b/crates/tui/src/config_ui.rs index 578a5eb694..2e79f8c4cd 100644 --- a/crates/tui/src/config_ui.rs +++ b/crates/tui/src/config_ui.rs @@ -262,7 +262,9 @@ pub enum UiThemeValue { TokyoNight, Dracula, GruvboxDark, + Claude, Matrix, + SolarizedLight, Uwu, /// User theme carried as its full `custom:` selector — the same /// single string `/theme` and the persisted `theme` setting use. @@ -327,8 +329,10 @@ pub enum InlineDiffValue { #[serde(rename_all = "snake_case")] pub enum WorkSurfacePlacementValue { Top, + Bottom, Left, Right, + Off, } #[derive(Debug, Clone, Copy, Serialize, Deserialize, JsonSchema, PartialEq, Eq)] @@ -1086,7 +1090,9 @@ impl UiThemeValue { Self::TokyoNight => "tokyo-night".into(), Self::Dracula => "dracula".into(), Self::GruvboxDark => "gruvbox-dark".into(), + Self::Claude => "claude".into(), Self::Matrix => "matrix".into(), + Self::SolarizedLight => "solarized-light".into(), Self::Uwu => "uwu".into(), Self::Custom(selector) => std::borrow::Cow::Owned(selector.clone()), } @@ -1108,7 +1114,9 @@ impl UiThemeValue { Some("tokyo-night") => Ok(Self::TokyoNight), Some("dracula") => Ok(Self::Dracula), Some("gruvbox-dark") => Ok(Self::GruvboxDark), + Some("claude") => Ok(Self::Claude), Some("matrix") => Ok(Self::Matrix), + Some("solarized-light") => Ok(Self::SolarizedLight), Some("uwu") => Ok(Self::Uwu), Some(other) => bail!("unsupported theme '{other}'"), None => bail!("invalid theme '{value}'"), @@ -1234,8 +1242,10 @@ impl WorkSurfacePlacementValue { fn as_setting(self) -> &'static str { match self { Self::Top => "top", + Self::Bottom => "bottom", Self::Left => "left", Self::Right => "right", + Self::Off => "off", } } } @@ -1243,9 +1253,14 @@ impl WorkSurfacePlacementValue { impl From<&str> for WorkSurfacePlacementValue { fn from(value: &str) -> Self { match value.trim().to_ascii_lowercase().as_str() { + "top" => Self::Top, + "bottom" => Self::Bottom, "left" => Self::Left, "right" => Self::Right, - _ => Self::Top, + "off" => Self::Off, + // Mirror `normalize_work_surface_placement`: the bar's home is + // under the composer. + _ => Self::Bottom, } } } @@ -1854,7 +1869,9 @@ background_color = "#1A1B26" "tokyo-night", "dracula", "gruvbox-dark", + "claude", "matrix", + "solarized-light", "uwu" ]) ); @@ -1865,6 +1882,81 @@ background_color = "#1A1B26" ); } + #[test] + fn ui_theme_value_covers_every_selectable_theme() { + // The typed /config document must round-trip every theme the /theme + // picker can persist, so the typed value space tracks + // `SELECTABLE_THEMES`. Drift here silently rewrote a saved theme on + // save (claude and solarized-light used to fall out). + for theme in crate::palette::SELECTABLE_THEMES { + let name = theme.name(); + let value = UiThemeValue::from_setting(name) + .unwrap_or_else(|err| panic!("UiThemeValue must accept theme {name}: {err}")); + assert_eq!( + value.as_setting(), + name, + "UiThemeValue must round-trip theme {name}" + ); + let serialized = serde_json::to_value(&value) + .unwrap_or_else(|err| panic!("serialize theme {name}: {err}")); + assert_eq!(serialized, serde_json::json!(name)); + } + } + + #[test] + fn work_surface_placement_round_trips_bottom_and_off_through_typed_document() { + // A persisted `bottom` used to deserialize as `Top` — saving the + // typed document silently moved the work surface. Every placement + // `Settings::set` accepts must survive the typed document. + assert_eq!( + WorkSurfacePlacementValue::from("bottom"), + WorkSurfacePlacementValue::Bottom + ); + assert_eq!( + WorkSurfacePlacementValue::from("off"), + WorkSurfacePlacementValue::Off + ); + for placement in ["bottom", "top", "left", "right", "off"] { + let value = WorkSurfacePlacementValue::from(placement); + assert_eq!(value.as_setting(), placement); + let serialized = serde_json::to_value(&value) + .unwrap_or_else(|err| panic!("serialize placement {placement}: {err}")); + assert_eq!( + serde_json::from_value::(serialized) + .unwrap_or_else(|err| panic!("deserialize placement {placement}: {err}")), + value + ); + } + + let _lock = lock_test_env(); + let temp_root = tempfile::tempdir().expect("isolated Codewhale home"); + let codewhale_home = temp_root.path().join(".codewhale"); + fs::create_dir_all(&codewhale_home).expect("settings dir"); + let settings_path = codewhale_home.join("settings.toml"); + fs::write(&settings_path, "work_surface_placement = \"bottom\"\n").expect("settings"); + let _home = EnvVarGuard::set("CODEWHALE_HOME", &codewhale_home); + let _codewhale_config = EnvVarGuard::remove("CODEWHALE_CONFIG_PATH"); + let _deepseek_config = EnvVarGuard::remove("DEEPSEEK_CONFIG_PATH"); + + let mut app = app(); + let mut config = Config::default(); + let doc = build_document(&app, &config).expect("document"); + assert_eq!( + doc.settings.work_surface_placement, + WorkSurfacePlacementValue::Bottom, + "the live bottom default must not degrade to top in the typed document" + ); + let doc = parse_document(serde_json::to_value(&doc).expect("serialize document")) + .expect("parse document"); + assert_eq!( + doc.settings.work_surface_placement, + WorkSurfacePlacementValue::Bottom + ); + // Applying session-only must validate: `Settings::set` accepts + // bottom, so the typed document never corrupts it. + apply_document(doc, &mut app, &mut config, false).expect("apply placement"); + } + #[test] fn ui_locale_round_trips_every_shipped_locale() { for locale in crate::localization::Locale::shipped() { diff --git a/crates/tui/src/localization.rs b/crates/tui/src/localization.rs index 22e3884819..d4790b5263 100644 --- a/crates/tui/src/localization.rs +++ b/crates/tui/src/localization.rs @@ -2137,14 +2137,13 @@ pub enum MessageId { ConfigChoiceModePlan, ConfigChoiceModeOperate, ConfigChoicePlacementTop, + ConfigChoicePlacementBottom, ConfigChoicePlacementLeft, ConfigChoicePlacementRight, ConfigChoiceRailTasks, ConfigChoiceRailAgents, ConfigChoiceRailContext, - ConfigChoiceRailPinned, ConfigChoiceStatusCw, - ConfigChoiceStatusWhale, ConfigChoiceStatusDots, ConfigChoiceDiffFull, ConfigChoiceDiffSummary, @@ -2157,13 +2156,13 @@ pub enum MessageId { ConfigChoiceDetailModePlan, ConfigChoiceDetailModeOperate, ConfigChoiceDetailPlacementTop, + ConfigChoiceDetailPlacementBottom, ConfigChoiceDetailPlacementLeft, ConfigChoiceDetailPlacementRight, ConfigChoiceDetailPlacementOff, ConfigChoiceDetailRailTasks, ConfigChoiceDetailRailAgents, ConfigChoiceDetailRailContext, - ConfigChoiceDetailRailPinned, ConfigChoiceDetailLowMotionOn, ConfigChoiceDetailLowMotionOff, ConfigChoiceDetailFancyOn, @@ -4164,14 +4163,13 @@ pub const ALL_MESSAGE_IDS: &[MessageId] = &[ MessageId::ConfigChoiceModePlan, MessageId::ConfigChoiceModeOperate, MessageId::ConfigChoicePlacementTop, + MessageId::ConfigChoicePlacementBottom, MessageId::ConfigChoicePlacementLeft, MessageId::ConfigChoicePlacementRight, MessageId::ConfigChoiceRailTasks, MessageId::ConfigChoiceRailAgents, MessageId::ConfigChoiceRailContext, - MessageId::ConfigChoiceRailPinned, MessageId::ConfigChoiceStatusCw, - MessageId::ConfigChoiceStatusWhale, MessageId::ConfigChoiceStatusDots, MessageId::ConfigChoiceDiffFull, MessageId::ConfigChoiceDiffSummary, @@ -4184,13 +4182,13 @@ pub const ALL_MESSAGE_IDS: &[MessageId] = &[ MessageId::ConfigChoiceDetailModePlan, MessageId::ConfigChoiceDetailModeOperate, MessageId::ConfigChoiceDetailPlacementTop, + MessageId::ConfigChoiceDetailPlacementBottom, MessageId::ConfigChoiceDetailPlacementLeft, MessageId::ConfigChoiceDetailPlacementRight, MessageId::ConfigChoiceDetailPlacementOff, MessageId::ConfigChoiceDetailRailTasks, MessageId::ConfigChoiceDetailRailAgents, MessageId::ConfigChoiceDetailRailContext, - MessageId::ConfigChoiceDetailRailPinned, MessageId::ConfigChoiceDetailLowMotionOn, MessageId::ConfigChoiceDetailLowMotionOff, MessageId::ConfigChoiceDetailFancyOn, diff --git a/crates/tui/src/settings.rs b/crates/tui/src/settings.rs index c02fcb1795..5b7140a955 100644 --- a/crates/tui/src/settings.rs +++ b/crates/tui/src/settings.rs @@ -1369,15 +1369,25 @@ impl Settings { } "rail_panel" | "rail" => { let normalized = value.trim().to_ascii_lowercase(); + // `pinned` stays accepted as a setting word; it folds into + // the tasks view exactly like the load-time migration. if !matches!( normalized.as_str(), - "tasks" | "agents" | "context" | "pinned" + "tasks" + | "agents" + | "background" + | "files" + | "notepad" + | "context" + | "git" + | "price" + | "pinned" ) { anyhow::bail!( - "Failed to update setting: invalid rail panel '{value}'. Expected: tasks, agents, context, or pinned." + "Failed to update setting: invalid rail panel '{value}'. Expected: tasks, agents, background, files, notepad, context, git, or price." ); } - self.rail_panel = normalized; + self.rail_panel = normalize_rail_panel(&normalized).to_string(); self.rail_panel_explicit = true; } "work_surface_top_height" | "work_top_height" => { @@ -3205,11 +3215,22 @@ mod tests { } #[test] - fn rail_panel_persists_tasks_agents_context_and_pinned() { + fn rail_panel_persists_every_dock_panel_and_folds_pinned_into_tasks() { let mut settings = Settings::default(); assert_eq!(settings.rail_panel, "tasks"); - for panel in ["agents", "context", "pinned", "tasks"] { + // Every panel the dock cycles through must survive `set` and a + // settings.toml round trip — the dock persists all eight. + for panel in [ + "tasks", + "agents", + "background", + "files", + "notepad", + "context", + "git", + "price", + ] { settings.set("rail_panel", panel).expect("valid panel"); assert_eq!(settings.rail_panel, panel); let body = toml::to_string(&settings).expect("serialize settings"); @@ -3217,12 +3238,18 @@ mod tests { assert_eq!(restored.rail_panel, panel); } + // `pinned` stays accepted as a setting word but persists as the + // canonical tasks view, matching the load-time migration. + settings.set("rail_panel", "agents").expect("reset panel"); + settings.set("rail_panel", "pinned").expect("pinned alias"); + assert_eq!(settings.rail_panel, "tasks"); + let err = settings .set("rail_panel", "auto") .expect_err("auto-collapse was dropped with the legacy sidebar"); assert!( err.to_string() - .contains("tasks, agents, context, or pinned") + .contains("tasks, agents, background, files, notepad, context, git, or price") ); assert_eq!(settings.rail_panel, "tasks"); } From 9a29726a8576693e0a023297d2d6e226f7bb3551 Mon Sep 17 00:00:00 2001 From: CodeWhale Bot Date: Wed, 2 Sep 2026 15:33:01 -0700 Subject: [PATCH 4/4] fix: drop needless borrow flagged by clippy 1.98 in placement round-trip test Signed-off-by: Hunter Bown --- crates/tui/src/config_ui.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/tui/src/config_ui.rs b/crates/tui/src/config_ui.rs index 2e79f8c4cd..ef588bdaa2 100644 --- a/crates/tui/src/config_ui.rs +++ b/crates/tui/src/config_ui.rs @@ -1919,7 +1919,7 @@ background_color = "#1A1B26" for placement in ["bottom", "top", "left", "right", "off"] { let value = WorkSurfacePlacementValue::from(placement); assert_eq!(value.as_setting(), placement); - let serialized = serde_json::to_value(&value) + let serialized = serde_json::to_value(value) .unwrap_or_else(|err| panic!("serialize placement {placement}: {err}")); assert_eq!( serde_json::from_value::(serialized)