stynx-code 3.6.2

stynx-code — interactive AI coding assistant
use std::time::Instant;

const VERBS: &[&str] = &[
    "Thinking", "Reasoning", "Pondering", "Analyzing", "Considering",
    "Processing", "Working", "Computing", "Calculating", "Reflecting",
    "Contemplating", "Deliberating", "Examining", "Investigating", "Synthesizing",
];
const SPIN: &[&str] = &["·", "", "", "", "", ""];

pub struct SpinnerState {
    verb: &'static str,
    start: Instant,
    pub tokens: u64,
}

impl SpinnerState {
    pub fn new() -> Self {
        let idx = (std::time::SystemTime::now()
            .duration_since(std::time::UNIX_EPOCH)
            .map(|d| d.subsec_nanos())
            .unwrap_or(0) as usize) % VERBS.len();
        Self { verb: VERBS[idx], start: Instant::now(), tokens: 0 }
    }

    pub fn render_frame(&self, frame: usize) -> String {
        let elapsed = self.start.elapsed().as_secs();
        let spin = SPIN[frame % SPIN.len()];

        let color = if elapsed >= 15 {
            "\x1b[31m"
        } else if elapsed >= 5 {
            "\x1b[33m"
        } else {
            "\x1b[2m"
        };

        let verb = self.verb;
        let elapsed_str = if elapsed >= 3 {
            format!("  \x1b[2m{elapsed}s\x1b[0m")
        } else {
            String::new()
        };
        let token_str = if elapsed >= 30 && self.tokens > 0 {
            let t = if self.tokens >= 1000 {
                format!("{:.1}K", self.tokens as f64 / 1000.0)
            } else {
                self.tokens.to_string()
            };
            format!("  \x1b[2m↓ {t}\x1b[0m")
        } else {
            String::new()
        };

        format!("  {color}{spin}  {verb}\x1b[0m{elapsed_str}{token_str}")
    }
}