Skip to main content

linesmith_core/segments/
agent.rs

1//! Agent segment: renders Claude Code's active sub-agent name from
2//! `agent.name`. Hidden when the payload doesn't carry it. Opt-in: not
3//! in the default segment list.
4
5use super::{RenderContext, RenderResult, RenderedSegment, Segment, SegmentDefaults};
6use crate::data_context::DataContext;
7use crate::theme::Role;
8
9pub struct AgentSegment;
10
11/// Informational; drops before cost (192), kept past rate-limit (96).
12const PRIORITY: u8 = 160;
13
14impl Segment for AgentSegment {
15    fn render(&self, ctx: &DataContext, _rc: &RenderContext) -> RenderResult {
16        let Some(name) = ctx.status.agent_name.as_deref() else {
17            crate::lsm_debug!("agent: status.agent_name absent; hiding");
18            return Ok(None);
19        };
20        Ok(Some(RenderedSegment::new(name).with_role(Role::Muted)))
21    }
22
23    fn defaults(&self) -> SegmentDefaults {
24        SegmentDefaults::with_priority(PRIORITY)
25    }
26}
27
28#[cfg(test)]
29mod tests {
30    use super::*;
31    use crate::input::{ModelInfo, StatusContext, Tool, WorkspaceInfo};
32    use std::path::PathBuf;
33    use std::sync::Arc;
34
35    fn rc() -> RenderContext {
36        RenderContext::new(80)
37    }
38
39    fn ctx(agent_name: Option<String>) -> DataContext {
40        DataContext::new(StatusContext {
41            tool: Tool::ClaudeCode,
42            model: Some(ModelInfo {
43                display_name: "X".into(),
44            }),
45            workspace: Some(WorkspaceInfo {
46                project_dir: PathBuf::from("/repo"),
47                git_worktree: None,
48            }),
49            context_window: None,
50            cost: None,
51            effort: None,
52            vim: None,
53            output_style: None,
54            agent_name,
55            version: None,
56            raw: Arc::new(serde_json::Value::Null),
57        })
58    }
59
60    #[test]
61    fn renders_active_agent() {
62        assert_eq!(
63            AgentSegment
64                .render(&ctx(Some("research".into())), &rc())
65                .unwrap(),
66            Some(RenderedSegment::new("research").with_role(Role::Muted))
67        );
68    }
69
70    #[test]
71    fn hidden_when_absent() {
72        assert_eq!(AgentSegment.render(&ctx(None), &rc()).unwrap(), None);
73    }
74
75    #[test]
76    fn defaults_use_expected_priority() {
77        assert_eq!(AgentSegment.defaults().priority, PRIORITY);
78    }
79}