docs(comments): rewrite comments across all crates to the guidelines

Sweep every first-party crate source (1956 .rs files) to the project comment
guidelines: delete redundant restatements, decorative banners, change
narration, and end-of-line comments; keep and tighten the crucial ones
(invariants, bug rationale, SAFETY blocks, ported-source attribution).

No functional code changed. Every edit is proven comment-only against the
prior tree by a comment-stripping lexer (string/char/raw-string aware) plus a
separate doctest-fence check. Where removing a comment made rustfmt or clippy
want to re-lay-out adjacent code, the minimal triggering comment is restored so
code tokens stay byte-identical.

Gates green: cargo fmt --all --check (0 diffs), cargo check and cargo clippy
--workspace --all-targets (0 warnings).

Adds scripts/check_codegen_comment_guidelines.py — the enforcement gate for
these guidelines (flags banners, end-of-line comments, change narration, and
commented-out code).
This commit is contained in:
2026-07-23 16:55:39 -04:00
parent ff0fb56c67
commit a02b555e66
1458 changed files with 10729 additions and 21750 deletions
@@ -102,7 +102,7 @@ pub fn set(kind: ThemeKind) {
LOADED.store(true, Ordering::Release);
}
// -- Terminal-native lock (minimal mode) --------------------------------------
// Terminal-native lock (minimal mode)
/// Whether the theme is locked to the terminal-native palette.
#[must_use]
@@ -120,7 +120,7 @@ pub fn set_terminal_native_lock(locked: bool) {
});
}
// -- Auto-mode ---------------------------------------------------------------
// Auto-mode
/// Whether auto-switching mode is active.
#[must_use]
@@ -152,7 +152,7 @@ pub fn invalidate_auto_theme_config() {
*AUTO_THEME_CONFIG.lock().unwrap_or_else(|e| e.into_inner()) = None;
}
// -- Theme resolution --------------------------------------------------------
// Theme resolution
/// Resolve the effective theme, respecting the full precedence chain.
///
@@ -218,7 +218,7 @@ pub fn resolve_initial_theme_no_osc11() -> ThemeKind {
resolve_from_config(load_from_disk(), false)
}
// -- Disk reads --------------------------------------------------------------
// Disk reads
//
// All writes go through `kigi_shell::util::config::set_theme()` (and
// friends) via `Effect::PersistSetting`. This module only READS from the
@@ -268,7 +268,7 @@ fn load_auto_theme_config() -> AutoThemeConfig {
}
}
// -- Test support ------------------------------------------------------------
// Test support
#[cfg(any(test, feature = "test-support"))]
pub fn reset_for_test() {
@@ -334,7 +334,7 @@ mod tests {
*AUTO_THEME_CONFIG.lock().unwrap_or_else(|e| e.into_inner()) = Some(config);
}
// -- Terminal-native lock (minimal mode) ----------------------------------
// Terminal-native lock (minimal mode)
#[test]
fn terminal_native_lock_pins_kind_and_blocks_apply_kind() {
@@ -393,7 +393,8 @@ mod tests {
set_terminal_native_lock(true);
assert!(color_support::detect() <= color_support::ColorLevel::Basic);
for input in [
Color::Rgb(0x26, 0x26, 0x26), // kigiday text_primary
// kigiday text_primary
Color::Rgb(0x26, 0x26, 0x26),
Color::Rgb(122, 162, 247),
Color::Indexed(141),
] {
@@ -427,7 +428,7 @@ mod tests {
});
}
// -- AUTO_MODE -----------------------------------------------------------
// AUTO_MODE
#[test]
fn auto_mode_default_is_false() {
@@ -446,7 +447,7 @@ mod tests {
});
}
// -- AutoThemeConfig -----------------------------------------------------
// AutoThemeConfig
#[test]
fn auto_theme_config_defaults_to_none() {
@@ -455,7 +456,7 @@ mod tests {
assert!(config.light_theme.is_none());
}
// -- resolve_auto --------------------------------------------------------
// resolve_auto
#[test]
fn resolve_auto_dark_system_returns_kiginight() {
@@ -484,7 +485,7 @@ mod tests {
});
}
// -- invalidate_auto_theme_config ----------------------------------------
// invalidate_auto_theme_config
#[test]
fn invalidate_clears_cached_config() {
@@ -506,7 +507,7 @@ mod tests {
});
}
// -- resolve_from_config (resolve_initial_theme inner logic) ---------------
// resolve_from_config (resolve_initial_theme inner logic)
#[test]
fn resolve_from_config_no_config_returns_kiginight() {
@@ -559,7 +560,7 @@ mod tests {
});
}
// -- resolve_auto with custom config -------------------------------------
// resolve_auto with custom config
#[test]
fn resolve_auto_with_custom_dark_config() {
@@ -585,7 +586,7 @@ mod tests {
});
}
// -- auto_theme_config filter --------------------------------------------
// auto_theme_config filter
#[test]
fn auto_theme_config_filter_rejects_auto_value() {
@@ -602,7 +603,7 @@ mod tests {
assert_eq!(parsed, Some(ThemeKind::TokyoNight));
}
// -- set / current_kind --------------------------------------------------
// set / current_kind
/// `set` followed by `current_kind` returns the set value, and the
/// `LOADED` flag flips so subsequent reads don't re-seed from disk.
@@ -60,7 +60,7 @@ impl std::fmt::Display for ColorLevel {
}
}
// ── Global singleton ─────────────────────────────────────────────────────
// Global singleton
static COLOR_LEVEL: OnceLock<ColorLevel> = OnceLock::new();
@@ -133,7 +133,7 @@ pub fn set(level: ColorLevel) -> Result<(), ColorLevel> {
COLOR_LEVEL.set(level)
}
// ── Color quantization ──────────────────────────────────────────────────
// Color quantization
/// Downgrade a [`Color`] to the highest representation the terminal supports.
///
@@ -164,7 +164,7 @@ pub fn quantize(color: Color) -> Color {
quantize_color(color, get())
}
// ── Terminal-based truecolor inference ──────────────────────────────────
// Terminal-based truecolor inference
/// Check whether the detected terminal emulator is known to support truecolor.
///
@@ -196,7 +196,7 @@ fn terminal_supports_truecolor() -> bool {
cfg!(target_os = "windows")
}
// ── 256 → 16 mapping ────────────────────────────────────────────────────
// 256 → 16 mapping
/// Map a 256-color index to the nearest basic ANSI 16 color.
fn indexed_to_ansi16(n: u8) -> Color {
@@ -209,7 +209,8 @@ fn indexed_to_ansi16(n: u8) -> Color {
4 => Color::Blue,
5 => Color::Magenta,
6 => Color::Cyan,
7 => Color::White, // actually "silver" in most terminals
// actually "silver" in most terminals
7 => Color::White,
8 => Color::DarkGray,
9 => Color::LightRed,
10 => Color::LightGreen,
@@ -248,7 +249,8 @@ fn rgb_to_ansi16(r: u8, g: u8, b: u8) -> Color {
(0, 0, 255, Color::LightBlue),
(255, 0, 255, Color::LightMagenta),
(0, 255, 255, Color::LightCyan),
(255, 255, 255, Color::White), // index 15 = bright white
// index 15 = bright white
(255, 255, 255, Color::White),
];
let mut best = Color::White;
@@ -16,38 +16,48 @@ const fn rgb(r: u8, g: u8, b: u8) -> Color {
mod palette {
use super::*;
// ── Backgrounds (neutral light grays) ────────────────────────────────
pub const BG: Color = rgb(245, 245, 245); // #f5f5f5 — brightest (terminal bg)
pub const BG_DARK: Color = rgb(240, 240, 240); // #f0f0f0
pub const BG_STORM_DARK: Color = rgb(234, 234, 234); // #eaeaea
pub const BG_STORM: Color = rgb(238, 238, 238); // #eeeeee — main bg
pub const BG_HIGHLIGHT: Color = rgb(222, 222, 222); // #dedede — highlight bg
// Backgrounds (neutral light grays)
// #f5f5f5 — brightest (terminal bg)
pub const BG: Color = rgb(245, 245, 245);
pub const BG_DARK: Color = rgb(240, 240, 240);
pub const BG_STORM_DARK: Color = rgb(234, 234, 234);
// #eeeeee — main bg
pub const BG_STORM: Color = rgb(238, 238, 238);
// #dedede — highlight bg
pub const BG_HIGHLIGHT: Color = rgb(222, 222, 222);
// ── Text / grays (neutral dark) ──────────────────────────────────────
pub const FG: Color = rgb(38, 38, 38); // #262626 — primary text
pub const FG_DARK: Color = rgb(68, 68, 68); // #444444 — secondary text
pub const FG_GUTTER: Color = rgb(178, 178, 178); // #b2b2b2 — dim
pub const COMMENT: Color = rgb(118, 118, 118); // #767676 — muted
pub const DARK3: Color = rgb(142, 142, 142); // #8e8e8e — medium gray
pub const DARK5: Color = rgb(98, 98, 98); // #626262 — bright gray
// Text / grays (neutral dark)
// #262626 — primary text
pub const FG: Color = rgb(38, 38, 38);
// #444444 — secondary text
pub const FG_DARK: Color = rgb(68, 68, 68);
pub const FG_GUTTER: Color = rgb(178, 178, 178);
// #767676 — muted
pub const COMMENT: Color = rgb(118, 118, 118);
// #8e8e8e — medium gray
pub const DARK3: Color = rgb(142, 142, 142);
// #626262 — bright gray
pub const DARK5: Color = rgb(98, 98, 98);
// ── Accent colors (deepened for light-background contrast) ───────────
pub const BLUE: Color = rgb(47, 100, 210); // #2F64D2
pub const BLUE0: Color = rgb(40, 68, 138); // #28448A
pub const BLUE1: Color = rgb(15, 135, 162); // #0F87A2
pub const CYAN: Color = rgb(0, 130, 170); // #0082AA
pub const GREEN: Color = rgb(55, 142, 35); // #378E23
pub const GREEN1: Color = rgb(12, 148, 124); // #0C947C
pub const MAGENTA: Color = rgb(125, 75, 198); // #7D4BC6
pub const ORANGE: Color = rgb(195, 105, 30); // #C3691E
pub const PURPLE: Color = rgb(108, 62, 178); // #6C3EB2
pub const RED: Color = rgb(205, 48, 72); // #CD3048
pub const RED1: Color = rgb(175, 35, 35); // #AF2323
pub const TEAL: Color = rgb(10, 142, 112); // #0A8E70
pub const YELLOW: Color = rgb(162, 118, 18); // #A27612
// Accent colors (deepened for light-background contrast)
pub const BLUE: Color = rgb(47, 100, 210);
pub const BLUE0: Color = rgb(40, 68, 138);
pub const BLUE1: Color = rgb(15, 135, 162);
pub const CYAN: Color = rgb(0, 130, 170);
pub const GREEN: Color = rgb(55, 142, 35);
pub const GREEN1: Color = rgb(12, 148, 124);
pub const MAGENTA: Color = rgb(125, 75, 198);
pub const ORANGE: Color = rgb(195, 105, 30);
pub const PURPLE: Color = rgb(108, 62, 178);
pub const RED: Color = rgb(205, 48, 72);
pub const RED1: Color = rgb(175, 35, 35);
pub const TEAL: Color = rgb(10, 142, 112);
pub const YELLOW: Color = rgb(162, 118, 18);
pub const RED_LIGHT: Color = rgb(245, 218, 222); // #F5DADE — diff delete bg
pub const GREEN_LIGHT: Color = rgb(218, 242, 220); // #DAF2DC — diff insert bg
// #F5DADE — diff delete bg
pub const RED_LIGHT: Color = rgb(245, 218, 222);
// #DAF2DC — diff insert bg
pub const GREEN_LIGHT: Color = rgb(218, 242, 220);
}
use palette::*;
@@ -74,7 +84,8 @@ impl Theme {
text_primary: FG,
text_secondary: FG_DARK,
gray_dim: rgb(165, 165, 165), // #a5a5a5 — slightly darker than FG_GUTTER
// #a5a5a5 — slightly darker than FG_GUTTER
gray_dim: rgb(165, 165, 165),
gray: COMMENT,
gray_bright: DARK5,
@@ -85,17 +96,22 @@ impl Theme {
fuzzy_accent: BLUE,
accent_plan: rgb(168, 120, 10), // #A8780A — deep golden
// #A8780A — deep golden
accent_plan: rgb(168, 120, 10),
accent_verify: rgb(120, 80, 160), // deep violet (readable on light bg)
// deep violet (readable on light bg)
accent_verify: rgb(120, 80, 160),
accent_feedback: GREEN1,
accent_remember: rgb(76, 175, 80), // #4CAF50 — Material Design green (readable on light bg)
// #4CAF50 — Material Design green (readable on light bg)
accent_remember: rgb(76, 175, 80),
selection_border: rgb(185, 185, 190),
prompt_border: rgb(200, 200, 205), // #C8C8CD — dimmer prompt chrome
prompt_border_active: rgb(165, 165, 175), // #A5A5AF — darker (more apparent) when focused
// #C8C8CD — dimmer prompt chrome
prompt_border: rgb(200, 200, 205),
// #A5A5AF — darker (more apparent) when focused
prompt_border_active: rgb(165, 165, 175),
hover_border: rgb(212, 212, 216),
accent_model: TEAL,
@@ -134,7 +150,8 @@ impl Theme {
md_muted: COMMENT,
md_code_bg: rgb(228, 228, 228),
md_text: FG_DARK,
link_fg: BLUE, // #2F64D2 -- deep blue for light bg
// #2F64D2 -- deep blue for light bg
link_fg: BLUE,
}
}
}
@@ -24,38 +24,50 @@ const fn rgb(r: u8, g: u8, b: u8) -> Color {
mod palette {
use super::*;
// ── Backgrounds ─────────────────────────────────────────────────────
pub const BG: Color = rgb(10, 10, 10); // #0a0a0a — Night (terminal bg)
pub const BG_DARK: Color = rgb(12, 12, 12); // #0c0c0c — darkest
pub const BG_STORM_DARK: Color = rgb(17, 17, 17); // #111111 — dark bg
pub const BG_STORM: Color = rgb(20, 20, 20); // #141414 — main bg
pub const BG_HIGHLIGHT: Color = rgb(36, 36, 36); // #242424 — highlight bg
// Backgrounds
// #0a0a0a — Night (terminal bg)
pub const BG: Color = rgb(10, 10, 10);
// #0c0c0c — darkest
pub const BG_DARK: Color = rgb(12, 12, 12);
// #111111 — dark bg
pub const BG_STORM_DARK: Color = rgb(17, 17, 17);
// #141414 — main bg
pub const BG_STORM: Color = rgb(20, 20, 20);
// #242424 — highlight bg
pub const BG_HIGHLIGHT: Color = rgb(36, 36, 36);
// ── Text / grays ────────────────────────────────────────────────────
pub const FG: Color = rgb(225, 225, 225); // #e1e1e1 — primary text
pub const FG_DARK: Color = rgb(200, 200, 200); // #c8c8c8 — secondary text
pub const FG_GUTTER: Color = rgb(65, 65, 65); // #414141 — dim
pub const COMMENT: Color = rgb(108, 108, 108); // #6c6c6c — muted
pub const DARK3: Color = rgb(90, 90, 90); // #5a5a5a — medium gray
pub const DARK5: Color = rgb(120, 120, 120); // #787878 — bright gray
// Text / grays
// #e1e1e1 — primary text
pub const FG: Color = rgb(225, 225, 225);
// #c8c8c8 — secondary text
pub const FG_DARK: Color = rgb(200, 200, 200);
pub const FG_GUTTER: Color = rgb(65, 65, 65);
// #6c6c6c — muted
pub const COMMENT: Color = rgb(108, 108, 108);
// #5a5a5a — medium gray
pub const DARK3: Color = rgb(90, 90, 90);
// #787878 — bright gray
pub const DARK5: Color = rgb(120, 120, 120);
// ── Accent colors (TokyoNight Night) ─────────────────────────────────
pub const BLUE: Color = rgb(122, 162, 247); // #7aa2f7
pub const BLUE0: Color = rgb(61, 89, 161); // #3d59a1
pub const BLUE1: Color = rgb(58, 149, 171); // #3A95AB
pub const CYAN: Color = rgb(125, 207, 255); // #7dcfff
pub const GREEN: Color = rgb(158, 206, 106); // #9ece6a
pub const GREEN1: Color = rgb(115, 218, 202); // #73daca
pub const MAGENTA: Color = rgb(187, 154, 247); // #bb9af7
pub const ORANGE: Color = rgb(255, 158, 100); // #ff9e64
pub const PURPLE: Color = rgb(157, 124, 216); // #9d7cd8
pub const RED: Color = rgb(247, 118, 142); // #f7768e
pub const RED1: Color = rgb(219, 75, 75); // #db4b4b
pub const TEAL: Color = rgb(26, 188, 156); // #1abc9c
pub const YELLOW: Color = rgb(224, 175, 104); // #e0af68
// Accent colors (TokyoNight Night)
pub const BLUE: Color = rgb(122, 162, 247);
pub const BLUE0: Color = rgb(61, 89, 161);
pub const BLUE1: Color = rgb(58, 149, 171);
pub const CYAN: Color = rgb(125, 207, 255);
pub const GREEN: Color = rgb(158, 206, 106);
pub const GREEN1: Color = rgb(115, 218, 202);
pub const MAGENTA: Color = rgb(187, 154, 247);
pub const ORANGE: Color = rgb(255, 158, 100);
pub const PURPLE: Color = rgb(157, 124, 216);
pub const RED: Color = rgb(247, 118, 142);
pub const RED1: Color = rgb(219, 75, 75);
pub const TEAL: Color = rgb(26, 188, 156);
pub const YELLOW: Color = rgb(224, 175, 104);
pub const RED_DARK: Color = rgb(66, 14, 20); // #420e14 — quantizes to 256-color red, not gray
pub const GREEN_DARK: Color = rgb(6, 56, 6); // #063806 — quantizes to 256-color green, not gray
// #420e14 — quantizes to 256-color red, not gray
pub const RED_DARK: Color = rgb(66, 14, 20);
// #063806 — quantizes to 256-color green, not gray
pub const GREEN_DARK: Color = rgb(6, 56, 6);
}
use palette::*;
@@ -68,7 +80,8 @@ impl Theme {
Self {
bg_base: BG_STORM,
bg_light: BG_HIGHLIGHT,
bg_dark: rgb(28, 28, 28), // lighter than bg_base for visible code blocks
// lighter than bg_base for visible code blocks
bg_dark: rgb(28, 28, 28),
bg_highlight: BG_HIGHLIGHT,
bg_hover: rgb(44, 44, 44),
bg_terminal: BG,
@@ -86,7 +99,8 @@ impl Theme {
text_primary: FG,
text_secondary: FG_DARK,
gray_dim: rgb(88, 88, 88), // #585858 — slightly brighter than FG_GUTTER
// #585858 — slightly brighter than FG_GUTTER
gray_dim: rgb(88, 88, 88),
gray: COMMENT,
gray_bright: DARK5,
@@ -97,17 +111,22 @@ impl Theme {
fuzzy_accent: BLUE,
accent_plan: rgb(255, 219, 141), // #FFDB8D — golden
// #FFDB8D — golden
accent_plan: rgb(255, 219, 141),
accent_verify: rgb(187, 154, 247), // #bb9af7 — violet
// #bb9af7 — violet
accent_verify: rgb(187, 154, 247),
accent_feedback: GREEN1, // #73daca
accent_feedback: GREEN1,
accent_remember: Color::Rgb(139, 195, 74), // #8BC34A — Material Design light green
// #8BC34A — Material Design light green
accent_remember: Color::Rgb(139, 195, 74),
selection_border: rgb(60, 60, 65),
prompt_border: rgb(50, 50, 55), // #323237 — dimmer prompt chrome
prompt_border_active: rgb(80, 80, 88), // #505058 — brighter when focused
// #323237 — dimmer prompt chrome
prompt_border: rgb(50, 50, 55),
// #505058 — brighter when focused
prompt_border_active: rgb(80, 80, 88),
hover_border: rgb(30, 30, 34),
accent_model: TEAL,
@@ -134,19 +153,21 @@ impl Theme {
md_heading_h2_mod: Modifier::BOLD,
md_heading_h3: PURPLE,
md_heading_h3_mod: Modifier::BOLD,
md_heading_h4: DARK5, // bright gray
md_heading_h4: DARK5,
md_heading_h4_mod: Modifier::BOLD,
md_heading_h5: COMMENT, // medium gray
md_heading_h5: COMMENT,
md_heading_h5_mod: Modifier::BOLD,
md_heading_h6: DARK3, // medium gray, unbold
// medium gray, unbold
md_heading_h6: DARK3,
md_heading_h6_mod: Modifier::empty(),
md_code: BLUE1,
md_task_checked: GREEN,
md_task_unchecked: FG_DARK, // text_secondary
md_task_unchecked: FG_DARK,
md_muted: COMMENT,
md_code_bg: rgb(28, 28, 28),
md_text: FG_DARK,
link_fg: rgb(122, 166, 218), // #7aa6da -- soft blue for dark bg
// #7aa6da -- soft blue for dark bg
link_fg: rgb(122, 166, 218),
}
}
}
@@ -137,7 +137,7 @@ fn build_style() -> MarkdownStyle {
inline_code_outer: fg(theme.md_code).dimmed().hidden(),
// Selection-side bar detection (kigi-tui scrollback/blocks/
// quote_bar.rs quote_bar_style) mirrors this exact style; its
// end-to-end tests fail if this line changes.
// end-to-end tests fail if this line drifts.
blockquote_outer: fg(theme.md_muted).dimmed(),
task_checked: fg(theme.md_task_checked),
task_unchecked: fg(theme.md_task_unchecked).dimmed(),
@@ -476,7 +476,7 @@ impl Theme {
// doesn't read at the same weight as secondary text.
let dim_fg = if dark { Color::DarkGray } else { Color::Gray };
// ── Polarity-aware semantic hues ────────────────────────────
// Polarity-aware semantic hues
// Normal ANSI hues (idx 17) are designed at ~50% luminance and
// read well on light backgrounds. Light variants (idx 915) are
// full saturation and read well on dark backgrounds. Pinning by
@@ -502,7 +502,7 @@ impl Theme {
};
let cyan = if dark { Color::LightCyan } else { Color::Cyan };
Self {
// ── Elevated surfaces: one step off the canvas ──────────────
// Elevated surfaces: one step off the canvas
// Hover/highlight/visual-selection rows need to read as a
// distinct "raised" band against the body. Without this every
// KigiNight bg field quantizes to Color::Black and these
@@ -512,7 +512,7 @@ impl Theme {
bg_hover: elevated_bg,
bg_visual: elevated_bg,
// ── Canvas-matching surfaces ────────────────────────────────
// Canvas-matching surfaces
// Pin to the theme's polarity, NOT Color::Reset. The truecolor
// "subtle sunken / code block" effect can't be replicated in
// 16-color, but using the theme polarity guarantees these
@@ -523,7 +523,7 @@ impl Theme {
paste_bg: canvas_bg,
scrollbar_bg: canvas_bg,
// ── Borders: dim (idle) → muted (selection) → high-contrast (active) ──
// Borders: dim (idle) → muted (selection) → high-contrast (active)
// The four-tier truecolor border hierarchy collapses onto
// three ANSI16 slots:
// - `prompt_border` (idle text-input frame) → `dim_fg`,
@@ -544,7 +544,7 @@ impl Theme {
// Scrollbar thumb stays visible against the canvas-matched track.
scrollbar_fg: muted_fg,
// ── Foreground / text hierarchy ─────────────────────────────
// Foreground / text hierarchy
md_text: high_contrast_fg,
// Selected user-prompt `>` (drives the user selection accent
// and the OSC 12 cursor color) takes max-contrast fg so the
@@ -563,7 +563,7 @@ impl Theme {
gray_bright: muted_fg,
gray_dim: dim_fg,
// ── Semantic accents: polarity-aware hue pins ───────────────
// Semantic accents: polarity-aware hue pins
// State signals (running / completed / error) and content
// categories (system / skill / etc.) get
// pinned to a hue that survives ANSI16 instead of collapsing
@@ -217,7 +217,7 @@ fn ends_with_osc_terminator(buf: &[u8]) -> bool {
mod tests {
use super::*;
// -- ends_with_osc_terminator ---------------------------------------------
// ends_with_osc_terminator
#[test]
fn unterminated_reply_is_rejected() {
@@ -230,7 +230,7 @@ mod tests {
assert!(!ends_with_osc_terminator(b""));
}
// -- parse_osc11_rgb -----------------------------------------------------
// parse_osc11_rgb
#[test]
fn parse_4digit_white() {
@@ -310,7 +310,7 @@ mod tests {
assert_eq!(parse_osc11_rgb(response), Some((15, 15, 15)));
}
// -- parse_channel -------------------------------------------------------
// parse_channel
#[test]
fn channel_4digit_max() {
@@ -337,7 +337,7 @@ mod tests {
assert_eq!(parse_channel(" ff "), Some(255));
}
// -- classify_luminance --------------------------------------------------
// classify_luminance
#[test]
fn classify_pure_black_is_dark() {
@@ -387,7 +387,7 @@ mod tests {
);
}
// -- srgb_to_linear ------------------------------------------------------
// srgb_to_linear
#[test]
fn srgb_to_linear_zero() {
@@ -416,7 +416,7 @@ mod tests {
assert!((result - expected).abs() < 1e-10);
}
// -- detect_via_osc11 (graceful degradation) -----------------------------
// detect_via_osc11 (graceful degradation)
#[test]
fn detect_returns_none_when_not_tty() {
@@ -19,38 +19,53 @@ const fn rgb(r: u8, g: u8, b: u8) -> Color {
mod palette {
use super::*;
// -- backgrounds (OKLCH hue 265 backgrounds, OKLCH hue 265) -------
pub const BASE: Color = rgb(3, 3, 4); // #030304 oklch(0.1 0.005 265)
pub const SURFACE: Color = rgb(4, 5, 7); // #040507 oklch(0.115 0.005 265)
pub const ELEVATED: Color = rgb(15, 18, 22); // #0F1216 oklch(0.18 0.01 265)
pub const PANEL: Color = rgb(4, 4, 6); // #040406 oklch(0.11 0.006 265)
// backgrounds (OKLCH hue 265 backgrounds, OKLCH hue 265)
// #030304 oklch(0.1 0.005 265)
pub const BASE: Color = rgb(3, 3, 4);
// #040507 oklch(0.115 0.005 265)
pub const SURFACE: Color = rgb(4, 5, 7);
// #0F1216 oklch(0.18 0.01 265)
pub const ELEVATED: Color = rgb(15, 18, 22);
// #040406 oklch(0.11 0.006 265)
pub const PANEL: Color = rgb(4, 4, 6);
// -- text (neutral, no color cast) ----------------------------------------
pub const TEXT: Color = rgb(228, 228, 228); // #E4E4E4 oklch(0.92 0 0)
pub const TEXT_DIM: Color = rgb(190, 190, 190); // #BEBEBE oklch(0.8 0 0)
// text (neutral, no color cast)
// #E4E4E4 oklch(0.92 0 0)
pub const TEXT: Color = rgb(228, 228, 228);
// #BEBEBE oklch(0.8 0 0)
pub const TEXT_DIM: Color = rgb(190, 190, 190);
// -- muted text (slight blue-purple tint) ---------------------------------
pub const MUTED: Color = rgb(129, 134, 143); // #81868F oklch(0.62 0.015 260)
pub const SUBTLE: Color = rgb(94, 100, 108); // #5E646C oklch(0.5 0.015 260)
// muted text (slight blue-purple tint)
// #81868F oklch(0.62 0.015 260)
pub const MUTED: Color = rgb(129, 134, 143);
// #5E646C oklch(0.5 0.015 260)
pub const SUBTLE: Color = rgb(94, 100, 108);
// -- semantic colors (from desktop action tokens) -------------------------
pub const GOLD: Color = rgb(235, 217, 110); // #EBD96E oklch(0.88 0.13 100)
pub const RED: Color = rgb(220, 90, 100); // #DC5A64 muted rose-red
pub const TEAL: Color = rgb(80, 180, 140); // #50B48C softened teal
pub const AMBER: Color = rgb(241, 189, 0); // #F1BD00 oklch(0.82 0.18 90)
// semantic colors (from desktop action tokens)
// #EBD96E oklch(0.88 0.13 100)
pub const GOLD: Color = rgb(235, 217, 110);
// #DC5A64 muted rose-red
pub const RED: Color = rgb(220, 90, 100);
// #50B48C softened teal
pub const TEAL: Color = rgb(80, 180, 140);
// #F1BD00 oklch(0.82 0.18 90)
pub const AMBER: Color = rgb(241, 189, 0);
// -- purple accent ramp (the "purple hints") ------------------------------
pub const PURPLE: Color = rgb(155, 126, 206); // #9B7ECE — signature purple
pub const PURPLE_DIM: Color = rgb(110, 90, 154); // #6E5A9A — muted purple
pub const PURPLE_BRIGHT: Color = rgb(196, 167, 231); // #C4A7E7 — vivid lavender
// purple accent ramp (the "purple hints")
// #9B7ECE — signature purple
pub const PURPLE: Color = rgb(155, 126, 206);
// #6E5A9A — muted purple
pub const PURPLE_DIM: Color = rgb(110, 90, 154);
// #C4A7E7 — vivid lavender
pub const PURPLE_BRIGHT: Color = rgb(196, 167, 231);
// -- cyan (for running indicators, links) ---------------------------------
pub const CYAN: Color = rgb(125, 207, 223); // #7DCFDF
// cyan (for running indicators, links)
pub const CYAN: Color = rgb(125, 207, 223);
// -- highlight ramp (purple-tinted grays for UI chrome) -------------------
pub const HIGHLIGHT_LOW: Color = rgb(18, 16, 28); // #12101C
pub const HIGHLIGHT_MED: Color = rgb(36, 32, 52); // #242034
pub const HIGHLIGHT_HIGH: Color = rgb(52, 48, 72); // #343048
// highlight ramp (purple-tinted grays for UI chrome)
pub const HIGHLIGHT_LOW: Color = rgb(18, 16, 28);
pub const HIGHLIGHT_MED: Color = rgb(36, 32, 52);
pub const HIGHLIGHT_HIGH: Color = rgb(52, 48, 72);
}
use palette::*;
@@ -94,7 +109,8 @@ impl Theme {
accent_feedback: TEAL,
accent_remember: rgb(139, 195, 74), // #8BC34A — Material Design light green
// #8BC34A — Material Design light green
accent_remember: rgb(139, 195, 74),
selection_border: HIGHLIGHT_HIGH,
hover_border: HIGHLIGHT_MED,
@@ -111,7 +111,8 @@ impl Theme {
md_muted: MUTED,
md_code_bg: SURFACE,
md_text: TEXT,
link_fg: FOAM, // #9ccfd8 -- teal/cyan for dark bg
// #9ccfd8 -- teal/cyan for dark bg
link_fg: FOAM,
}
}
}
@@ -112,7 +112,7 @@ const POLL_INTERVAL: Duration = Duration::from_secs(5);
#[cfg(test)]
const POLL_INTERVAL: Duration = Duration::from_millis(50);
/// Watches for system appearance changes via polling.
/// Watches for system appearance shifts via polling.
///
/// The spawned polling task only reads system state and sends via
/// `watch::channel` — it never mutates `theme_cache::CURRENT` or `AUTO_MODE`.
@@ -155,7 +155,7 @@ impl SystemAppearanceWatcher {
})
}
/// Wait for the next appearance change.
/// Wait for the next appearance shift.
pub async fn changed(&mut self) -> Result<(), watch::error::RecvError> {
self.rx.changed().await
}
@@ -173,7 +173,7 @@ impl Drop for SystemAppearanceWatcher {
}
}
// -- Test support ----------------------------------------------------------
// Test support
#[cfg(any(test, feature = "test-support"))]
use std::sync::Mutex;
@@ -306,7 +306,7 @@ mod tests {
let _ = detect();
}
// -- SystemAppearanceWatcher -----------------------------------------
// SystemAppearanceWatcher
#[tokio::test]
async fn start_if_auto_returns_none_when_not_auto() {
@@ -347,7 +347,8 @@ mod tests {
}
#[tokio::test]
#[allow(clippy::await_holding_lock)] // Deliberate: theme_cache::test_lock() serializes mock access.
// Deliberate: theme_cache::test_lock() serializes mock access.
#[allow(clippy::await_holding_lock)]
async fn watcher_detects_appearance_change() {
let _guard = theme_cache::test_lock()
.lock()
@@ -356,10 +357,10 @@ mod tests {
let mut watcher = SystemAppearanceWatcher::start_if_auto(true).unwrap();
assert_eq!(watcher.current(), Some(SystemAppearance::Dark));
// Change the mock appearance.
// Set the mock appearance.
set_mock(Some(SystemAppearance::Light));
// Wait for the watcher to detect the change (polls every 50ms in tests).
// Wait for the watcher to detect the shift (polls every 50ms in tests).
tokio::time::timeout(std::time::Duration::from_secs(2), watcher.changed())
.await
.expect("timed out waiting for change")
@@ -370,7 +371,8 @@ mod tests {
}
#[tokio::test]
#[allow(clippy::await_holding_lock)] // Deliberate: theme_cache::test_lock() serializes mock access.
// Deliberate: theme_cache::test_lock() serializes mock access.
#[allow(clippy::await_holding_lock)]
async fn watcher_does_not_send_when_unchanged() {
let _guard = theme_cache::test_lock()
.lock()
@@ -378,11 +380,11 @@ mod tests {
set_mock(Some(SystemAppearance::Dark));
let mut watcher = SystemAppearanceWatcher::start_if_auto(true).unwrap();
// Wait longer than the poll interval — no change should occur.
// Wait longer than the poll interval — Unchanged should occur.
let result =
tokio::time::timeout(std::time::Duration::from_millis(200), watcher.changed()).await;
// Should timeout because appearance didn't change.
// Should timeout because appearance stayed the same.
assert!(
result.is_err(),
"expected timeout — no change should be emitted"
@@ -392,16 +394,17 @@ mod tests {
}
#[tokio::test]
#[allow(clippy::await_holding_lock)] // Deliberate: theme_cache::test_lock() serializes mock access.
// Deliberate: theme_cache::test_lock() serializes mock access.
#[allow(clippy::await_holding_lock)]
async fn watcher_detects_recovery_from_failure() {
let _guard = theme_cache::test_lock()
.lock()
.unwrap_or_else(|e| e.into_inner());
set_mock(None); // Initially detection fails
// Initially detection fails
set_mock(None);
let mut watcher = SystemAppearanceWatcher::start_if_auto(true).unwrap();
assert_eq!(watcher.current(), None);
// Now detection succeeds.
set_mock(Some(SystemAppearance::Dark));
tokio::time::timeout(std::time::Duration::from_secs(2), watcher.changed())
@@ -4,7 +4,7 @@
//! the terminal's own canvas it can land dark-on-dark or light-on-light
//! (e.g. macOS in Light Mode + a dark terminal profile). Polarity detection
//! is not reliable either: OS appearance and OSC 11 both disagree with the
//! actual canvas in edge cases and can change mid-session. Terminal
//! actual canvas in edge cases and can differ mid-session. Terminal
//! profiles, however, tune their **default** fg/bg to be legible against
//! their own background — this is how `git` and `ls` stay readable on any
//! terminal — so a palette built from `Reset` (body) + sparse named ANSI-16
@@ -18,30 +18,32 @@ const fn rgb(r: u8, g: u8, b: u8) -> Color {
#[allow(dead_code)]
pub mod palette {
use super::*;
pub const BG: Color = rgb(26, 27, 38); // #1a1b26 - Night
pub const BG_DARK: Color = rgb(22, 22, 30); // #16161e
pub const BG_HIGHLIGHT: Color = rgb(41, 46, 66); // #292e42
pub const BG_STORM: Color = rgb(36, 40, 59); // #24283b - Storm
pub const BG_STORM_DARK: Color = rgb(31, 35, 53); // #1f2335
pub const FG: Color = rgb(192, 202, 245); // #c0caf5
pub const FG_DARK: Color = rgb(169, 177, 214); // #a9b1d6
pub const FG_GUTTER: Color = rgb(59, 66, 97); // #3b4261
pub const COMMENT: Color = rgb(86, 95, 137); // #565f89
pub const DARK3: Color = rgb(84, 92, 126); // #545c7e
pub const DARK5: Color = rgb(115, 122, 162); // #737aa2
pub const BLUE: Color = rgb(122, 162, 247); // #7aa2f7
pub const BLUE0: Color = rgb(61, 89, 161); // #3d59a1
pub const BLUE1: Color = rgb(42, 195, 222); // #2ac3de
pub const CYAN: Color = rgb(125, 207, 255); // #7dcfff
pub const GREEN: Color = rgb(158, 206, 106); // #9ece6a
pub const GREEN1: Color = rgb(115, 218, 202); // #73daca
pub const MAGENTA: Color = rgb(187, 154, 247); // #bb9af7
pub const ORANGE: Color = rgb(255, 158, 100); // #ff9e64
pub const PURPLE: Color = rgb(157, 124, 216); // #9d7cd8
pub const RED: Color = rgb(247, 118, 142); // #f7768e
pub const RED1: Color = rgb(219, 75, 75); // #db4b4b
pub const TEAL: Color = rgb(26, 188, 156); // #1abc9c
pub const YELLOW: Color = rgb(224, 175, 104); // #e0af68
// #1a1b26 - Night
pub const BG: Color = rgb(26, 27, 38);
pub const BG_DARK: Color = rgb(22, 22, 30);
pub const BG_HIGHLIGHT: Color = rgb(41, 46, 66);
// #24283b - Storm
pub const BG_STORM: Color = rgb(36, 40, 59);
pub const BG_STORM_DARK: Color = rgb(31, 35, 53);
pub const FG: Color = rgb(192, 202, 245);
pub const FG_DARK: Color = rgb(169, 177, 214);
pub const FG_GUTTER: Color = rgb(59, 66, 97);
pub const COMMENT: Color = rgb(86, 95, 137);
pub const DARK3: Color = rgb(84, 92, 126);
pub const DARK5: Color = rgb(115, 122, 162);
pub const BLUE: Color = rgb(122, 162, 247);
pub const BLUE0: Color = rgb(61, 89, 161);
pub const BLUE1: Color = rgb(42, 195, 222);
pub const CYAN: Color = rgb(125, 207, 255);
pub const GREEN: Color = rgb(158, 206, 106);
pub const GREEN1: Color = rgb(115, 218, 202);
pub const MAGENTA: Color = rgb(187, 154, 247);
pub const ORANGE: Color = rgb(255, 158, 100);
pub const PURPLE: Color = rgb(157, 124, 216);
pub const RED: Color = rgb(247, 118, 142);
pub const RED1: Color = rgb(219, 75, 75);
pub const TEAL: Color = rgb(26, 188, 156);
pub const YELLOW: Color = rgb(224, 175, 104);
}
use palette::*;
@@ -53,8 +55,10 @@ pub struct Theme {
pub bg_light: Color,
pub bg_dark: Color,
pub bg_highlight: Color,
pub bg_hover: Color, // Mouse hover row in dropdowns — between bg_highlight and bg_visual
pub bg_terminal: Color, // For terminal output blocks (currently unused, using bg_dark instead)
// Mouse hover row in dropdowns — between bg_highlight and bg_visual
pub bg_hover: Color,
// For terminal output blocks (currently unused, using bg_dark instead)
pub bg_terminal: Color,
// Accent colors (for vertical lines)
pub accent_user: Color,
@@ -64,8 +68,10 @@ pub struct Theme {
pub accent_system: Color,
pub accent_error: Color,
pub accent_success: Color,
pub accent_running: Color, // For tools that are currently running
pub accent_skill: Color, // For skill invocations (slash command skills)
// For tools that are currently running
pub accent_running: Color,
// For skill invocations (slash command skills)
pub accent_skill: Color,
// Text colors
pub text_primary: Color,
@@ -74,30 +80,42 @@ pub struct Theme {
// Gray scale (dim → medium → bright)
// Every theme defines these three; they provide a consistent hierarchy
// for secondary/meta text across all themes.
pub gray_dim: Color, // Dimmest — meta punctuation (`$`, `(+N/-M)`, etc.)
pub gray: Color, // Medium — muted text, comments, collapsed content
pub gray_bright: Color, // Brightest — tool accents, secondary labels
// Dimmest — meta punctuation (`$`, `(+N/-M)`, etc.)
pub gray_dim: Color,
// Medium — muted text, comments, collapsed content
pub gray: Color,
// Brightest — tool accents, secondary labels
pub gray_bright: Color,
// Semantic colors
pub command: Color, // Yellow for shell commands
pub path: Color, // Orange for file paths
pub running: Color, // Cyan for running indicator
pub warning: Color, // Yellow/amber for warnings
// Yellow for shell commands
pub command: Color,
// Orange for file paths
pub path: Color,
// Cyan for running indicator
pub running: Color,
// Yellow/amber for warnings
pub warning: Color,
// Search
pub fuzzy_accent: Color, // Highlight color for fuzzy search matches
// Highlight color for fuzzy search matches
pub fuzzy_accent: Color,
// Plan mode
pub accent_plan: Color, // Golden accent for plan mode indicator
// Golden accent for plan mode indicator
pub accent_plan: Color,
// Context-window overhead category (context info block)
pub accent_verify: Color, // Violet accent — distinct from plan gold and feedback teal
// Violet accent — distinct from plan gold and feedback teal
pub accent_verify: Color,
// Feedback mode
pub accent_feedback: Color, // Teal/green accent for feedback mode
// Teal/green accent for feedback mode
pub accent_feedback: Color,
// Remember mode
pub accent_remember: Color, // Green accent for # remember mode
// Green accent for # remember mode
pub accent_remember: Color,
// Selection
pub selection_border: Color,
@@ -106,7 +124,8 @@ pub struct Theme {
pub prompt_border_active: Color,
// Prompt info
pub accent_model: Color, // Model name in prompt info line
// Model name in prompt info line
pub accent_model: Color,
// Scrollbar
pub scrollbar_bg: Color,
@@ -132,25 +151,39 @@ pub struct Theme {
// blocks, inline code, links, etc. These default to the corresponding
// top-level theme colors but can be overridden per-theme to customise
// markdown appearance independently.
pub md_heading_h1: Color, // H1 headings
pub md_heading_h1_mod: Modifier, // H1 extra effects
pub md_heading_h2: Color, // H2 headings, task unchecked, tables
pub md_heading_h2_mod: Modifier, // H2 extra effects
pub md_heading_h3: Color, // H3 headings, code language tag
pub md_heading_h3_mod: Modifier, // H3 extra effects
pub md_heading_h4: Color, // H4 headings
pub md_heading_h4_mod: Modifier, // H4 extra effects
pub md_heading_h5: Color, // H5 headings, link titles
pub md_heading_h5_mod: Modifier, // H5 extra effects
pub md_heading_h6: Color, // H6 headings
pub md_heading_h6_mod: Modifier, // H6 extra effects
pub md_code: Color, // Inline code, code block delimiters
pub md_task_checked: Color, // Task checked
pub md_task_unchecked: Color, // Task unchecked
pub md_muted: Color, // Blockquotes, list items, rules, links
pub md_code_bg: Color, // Code block background
pub md_text: Color, // Default body text (plain paragraphs, strong, emphasis)
pub link_fg: Color, // Clickable link text color
pub md_heading_h1: Color,
// H1 extra effects
pub md_heading_h1_mod: Modifier,
// H2 headings, task unchecked, tables
pub md_heading_h2: Color,
// H2 extra effects
pub md_heading_h2_mod: Modifier,
// H3 headings, code language tag
pub md_heading_h3: Color,
// H3 extra effects
pub md_heading_h3_mod: Modifier,
pub md_heading_h4: Color,
// H4 extra effects
pub md_heading_h4_mod: Modifier,
// H5 headings, link titles
pub md_heading_h5: Color,
// H5 extra effects
pub md_heading_h5_mod: Modifier,
pub md_heading_h6: Color,
// H6 extra effects
pub md_heading_h6_mod: Modifier,
// Inline code, code block delimiters
pub md_code: Color,
pub md_task_checked: Color,
pub md_task_unchecked: Color,
// Blockquotes, list items, rules, links
pub md_muted: Color,
// Code block background
pub md_code_bg: Color,
// Default body text (plain paragraphs, strong, emphasis)
pub md_text: Color,
// Clickable link text color
pub link_fg: Color,
}
impl Theme {
@@ -172,7 +205,7 @@ impl Theme {
accent_error: RED,
accent_success: GREEN,
accent_running: MAGENTA,
accent_skill: rgb(100, 180, 170), // Muted teal
accent_skill: rgb(100, 180, 170),
text_primary: FG,
text_secondary: FG_DARK,
@@ -188,17 +221,24 @@ impl Theme {
fuzzy_accent: BLUE,
accent_plan: rgb(230, 180, 50), // #E6B432 — golden
// #E6B432 — golden
accent_plan: rgb(230, 180, 50),
accent_verify: MAGENTA, // #bb9af7 — violet (distinct from plan / feedback)
// #bb9af7 — violet (distinct from plan / feedback)
accent_verify: MAGENTA,
accent_feedback: GREEN1, // #73daca — warm teal/green
// #73daca — warm teal/green
accent_feedback: GREEN1,
accent_remember: Color::Rgb(139, 195, 74), // #8BC34A — Material Design light green
// #8BC34A — Material Design light green
accent_remember: Color::Rgb(139, 195, 74),
selection_border: rgb(58, 72, 115), // #3A4873 — muted tokyonight blue
prompt_border: rgb(60, 75, 120), // #323E64 — dimmer prompt chrome
prompt_border_active: rgb(75, 92, 140), // #4B5C8C — brighter when focused
// #3A4873 — muted tokyonight blue
selection_border: rgb(58, 72, 115),
// #323E64 — dimmer prompt chrome
prompt_border: rgb(60, 75, 120),
// #4B5C8C — brighter when focused
prompt_border_active: rgb(75, 92, 140),
hover_border: rgb(55, 58, 80),
accent_model: TEAL,
@@ -213,7 +253,8 @@ impl Theme {
diff_equal_fg: COMMENT,
diff_gutter_fg: COMMENT,
bg_visual: rgb(40, 52, 87), // #283457 — blue-tinted selection bg
// #283457 — blue-tinted selection bg
bg_visual: rgb(40, 52, 87),
paste_bg: BG_STORM_DARK,
paste_fg: FG_DARK,
@@ -239,7 +280,7 @@ impl Theme {
md_muted: COMMENT,
md_code_bg: BG_HIGHLIGHT,
md_text: FG,
link_fg: BLUE, // #7aa2f7
link_fg: BLUE,
}
}