sc/cli/commands/
status.rs1use crate::config::{current_git_branch, resolve_db_path, resolve_session_id};
4use crate::error::{Error, Result};
5use crate::storage::SqliteStorage;
6use serde::Serialize;
7use std::path::PathBuf;
8
9#[derive(Serialize)]
11struct StatusOutput {
12 session: Option<SessionInfo>,
13 project_path: Option<String>,
14 git_branch: Option<String>,
15 item_count: usize,
16 high_priority_count: usize,
17 categories: CategoryBreakdown,
18}
19
20#[derive(Serialize)]
21struct SessionInfo {
22 id: String,
23 name: String,
24 status: String,
25 created_at: i64,
26 updated_at: i64,
27}
28
29#[derive(Serialize)]
30struct CategoryBreakdown {
31 reminder: usize,
32 decision: usize,
33 progress: usize,
34 note: usize,
35}
36
37pub fn execute(db_path: Option<&PathBuf>, session_id: Option<&str>, json: bool) -> Result<()> {
42 let db_path = resolve_db_path(db_path.map(|p| p.as_path()))
43 .ok_or(Error::NotInitialized)?;
44
45 if !db_path.exists() {
46 return Err(Error::NotInitialized);
47 }
48
49 let storage = SqliteStorage::open(&db_path)?;
50 let git_branch = current_git_branch();
51
52 let session = match resolve_session_id(session_id) {
54 Ok(sid) => storage.get_session(&sid)?,
55 Err(_) => None,
56 };
57
58 let project_path = session.as_ref()
60 .and_then(|s| s.project_path.clone());
61
62 let (item_count, high_priority_count, categories) = if let Some(ref s) = session {
63 let items = storage.get_context_items(&s.id, None, None, Some(1000))?;
65
66 let high = items.iter().filter(|i| i.priority == "high").count();
67 let reminder = items.iter().filter(|i| i.category == "reminder").count();
68 let decision = items.iter().filter(|i| i.category == "decision").count();
69 let progress = items.iter().filter(|i| i.category == "progress").count();
70 let note = items.iter().filter(|i| i.category == "note").count();
71
72 (
73 items.len(),
74 high,
75 CategoryBreakdown {
76 reminder,
77 decision,
78 progress,
79 note,
80 },
81 )
82 } else {
83 (
84 0,
85 0,
86 CategoryBreakdown {
87 reminder: 0,
88 decision: 0,
89 progress: 0,
90 note: 0,
91 },
92 )
93 };
94
95 if json {
96 let output = StatusOutput {
97 session: session.map(|s| SessionInfo {
98 id: s.id.clone(),
99 name: s.name.clone(),
100 status: s.status.clone(),
101 created_at: s.created_at,
102 updated_at: s.updated_at,
103 }),
104 project_path,
105 git_branch: git_branch.clone(),
106 item_count,
107 high_priority_count,
108 categories,
109 };
110 println!("{}", serde_json::to_string(&output)?);
111 } else {
112 println!("SaveContext Status");
113 println!("==================");
114 println!();
115
116 if let Some(ref path) = project_path {
117 println!("Project: {path}");
118 }
119 if let Some(ref branch) = git_branch {
120 println!("Branch: {branch}");
121 }
122 println!();
123
124 if let Some(ref s) = session {
125 println!("Active Session: {}", s.name);
126 println!(" ID: {}", s.id);
127 println!(" Status: {}", s.status);
128 println!();
129 println!("Context Items: {item_count}");
130 if high_priority_count > 0 {
131 println!(" High Priority: {high_priority_count}");
132 }
133 println!(" Reminders: {}", categories.reminder);
134 println!(" Decisions: {}", categories.decision);
135 println!(" Progress: {}", categories.progress);
136 println!(" Notes: {}", categories.note);
137 } else {
138 println!("No active session.");
139 println!();
140 println!("Start one with: sc session start \"Session Name\"");
141 }
142 }
143
144 Ok(())
145}