koda-cli 0.2.10

A high-performance AI coding agent for macOS and Linux
Documentation
//! Session picker dropdown — thin wrapper around the generic dropdown.
//!
//! Appears when the user types `/sessions` with no args.

use super::dropdown::DropdownItem;

/// A session item for the dropdown.
#[derive(Clone, Debug)]
pub struct SessionItem {
    pub id: String,
    pub short_id: String,
    pub created_at: String,
    pub message_count: i64,
    pub total_tokens: i64,
    pub is_current: bool,
    pub title: Option<String>,
}

impl DropdownItem for SessionItem {
    fn label(&self) -> &str {
        &self.short_id
    }
    fn description(&self) -> String {
        let mut desc = if let Some(title) = &self.title {
            let t: String = title.chars().take(30).collect();
            format!("{t}  {} msgs", self.message_count)
        } else {
            format!(
                "{}  {} msgs  {}k tok",
                self.created_at,
                self.message_count,
                self.total_tokens / 1000
            )
        };
        if self.is_current {
            desc.push_str(" \u{25c0} current");
        }
        desc
    }
    fn matches_filter(&self, filter: &str) -> bool {
        let f = filter.to_lowercase();
        self.id.to_lowercase().contains(&f)
            || self.created_at.to_lowercase().contains(&f)
            || self
                .title
                .as_deref()
                .is_some_and(|t| t.to_lowercase().contains(&f))
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn current_shows_marker() {
        let item = SessionItem {
            id: "abc12345".into(),
            short_id: "abc12345".into(),
            created_at: "2026-03-08".into(),
            message_count: 5,
            total_tokens: 12000,
            is_current: true,
            title: None,
        };
        assert!(item.description().contains('\u{25c0}'));
    }

    #[test]
    fn filter_by_id_and_date() {
        let item = SessionItem {
            id: "abc12345".into(),
            short_id: "abc12345".into(),
            created_at: "2026-03-08".into(),
            message_count: 5,
            total_tokens: 12000,
            is_current: false,
            title: Some("refactor auth module".into()),
        };
        assert!(item.matches_filter("abc"));
        assert!(item.matches_filter("2026"));
        assert!(item.matches_filter("refactor"));
        assert!(!item.matches_filter("xyz"));
    }
}