1pub mod attention;
9pub mod classify;
10pub mod collector;
11pub mod panes;
12pub mod proc;
13pub mod session_meta;
14pub mod state;
15pub mod ui;
16
17use std::path::PathBuf;
18use std::time::SystemTime;
19
20#[derive(Debug, Clone)]
21pub struct Agent {
22 pub id: String,
25 pub pane: Option<PaneLocator>,
26 pub kind: AgentKind,
27 pub status: Status,
28 pub cwd: PathBuf,
29 pub repo_name: String,
30 pub flags: Flags,
31 pub extra: String,
32}
33
34#[derive(Debug, Clone, PartialEq, Eq)]
35pub struct PaneLocator {
36 pub session: String,
37 pub window: u32,
38 pub pane: u32,
39 pub pane_pid: u32,
40}
41
42impl PaneLocator {
43 pub fn target(&self) -> String {
44 format!("{}:{}.{}", self.session, self.window, self.pane)
45 }
46}
47
48#[derive(Debug, Clone, Copy, PartialEq, Eq)]
49pub enum AgentKind {
50 Claude,
51 Codex,
52 Shell,
53 Other,
54}
55
56impl AgentKind {
57 pub fn from_command(cmd: &str) -> Self {
58 match cmd {
59 "claude" => Self::Claude,
60 "codex" => Self::Codex,
61 "zsh" | "bash" | "fish" | "sh" => Self::Shell,
62 _ => Self::Other,
63 }
64 }
65
66 pub fn label(self) -> &'static str {
67 match self {
68 Self::Claude => "claude",
69 Self::Codex => "codex",
70 Self::Shell => "shell",
71 Self::Other => "other",
72 }
73 }
74}
75
76#[derive(Debug, Clone, Copy, PartialEq, Eq)]
77pub enum Status {
78 Working,
81 Ready,
84 AwaitingDecision,
87 Idle,
89 Background,
91}
92
93impl Status {
94 pub fn glyph(self) -> &'static str {
95 match self {
96 Self::Working => "●",
97 Self::Ready => "◐",
98 Self::AwaitingDecision => "⚠",
99 Self::Idle => "○",
100 Self::Background => "▷",
101 }
102 }
103
104 pub fn label(self) -> &'static str {
105 match self {
106 Self::Working => "working",
107 Self::Ready => "ready",
108 Self::AwaitingDecision => "decision",
109 Self::Idle => "idle",
110 Self::Background => "bg",
111 }
112 }
113}
114
115#[derive(Debug, Clone, Default, PartialEq, Eq)]
116pub struct Flags {
117 pub has_intent: bool,
118 pub blocked: bool,
119 pub reviewed_fresh: bool,
120}
121
122#[derive(Debug, Clone)]
123pub struct Snapshot {
124 pub agents: Vec<Agent>,
125 pub captured_at: SystemTime,
126 pub global_blocked: usize,
128 pub panes_error: Option<String>,
132 pub attention: Vec<attention::AttentionEntry>,
136}
137
138impl Snapshot {
139 pub fn empty() -> Self {
140 Self {
141 agents: Vec::new(),
142 captured_at: SystemTime::now(),
143 global_blocked: 0,
144 panes_error: None,
145 attention: Vec::new(),
146 }
147 }
148}
149
150pub fn run() -> anyhow::Result<()> {
151 ui::run()
152}