use std::path::PathBuf;
use lifeloop::telemetry::PressureObservation;
use super::{CliError, print_json};
pub fn run<I: Iterator<Item = String>>(mut args: I) -> Result<(), CliError> {
let action = args
.next()
.ok_or_else(|| CliError::Usage("telemetry requires a subcommand: snapshot".to_string()))?;
match action.as_str() {
"snapshot" => run_snapshot(args),
other => Err(CliError::Usage(format!(
"telemetry: unknown subcommand `{other}` (expected: snapshot)"
))),
}
}
fn run_snapshot<I: Iterator<Item = String>>(mut args: I) -> Result<(), CliError> {
let mut host_id: Option<String> = None;
let mut repo_root: Option<PathBuf> = None;
while let Some(arg) = args.next() {
match arg.as_str() {
"--host" => {
host_id = Some(require_value(&arg, args.next())?);
}
"--repo-root" => {
repo_root = Some(PathBuf::from(require_value(&arg, args.next())?));
}
other => {
return Err(CliError::Usage(format!(
"telemetry snapshot: unknown flag `{other}`"
)));
}
}
}
let host_id = host_id
.ok_or_else(|| CliError::Usage("telemetry snapshot: --host <id> is required".into()))?;
let repo_root = repo_root.unwrap_or_else(|| std::env::current_dir().unwrap_or_default());
let observation: Option<PressureObservation> = match host_id.as_str() {
"claude" => lifeloop::telemetry::claude::current(&repo_root)
.map_err(|e| CliError::Validation(format!("telemetry source error: {e}")))?,
"codex" => lifeloop::telemetry::codex::current()
.map_err(|e| CliError::Validation(format!("telemetry source error: {e}")))?,
"gemini" => lifeloop::telemetry::gemini::current(&repo_root)
.map_err(|e| CliError::Validation(format!("telemetry source error: {e}")))?,
other => {
return Err(CliError::Validation(format!(
"telemetry snapshot: no telemetry reader for host `{other}` (have: claude, codex, gemini)"
)));
}
};
let observation = observation.ok_or_else(|| {
CliError::Validation(format!(
"telemetry snapshot: no observation available for host `{host_id}` (source missing or empty)"
))
})?;
print_json(&observation)
}
fn require_value(flag: &str, value: Option<String>) -> Result<String, CliError> {
value.ok_or_else(|| CliError::Usage(format!("flag `{flag}` requires a value")))
}