chub_cli/commands/
telemetry_cmd.rs1use clap::{Args, Subcommand};
2use owo_colors::OwoColorize;
3
4use chub_core::identity::get_or_create_client_id;
5use chub_core::team::analytics;
6use chub_core::telemetry::{get_telemetry_url, is_feedback_enabled, is_telemetry_enabled};
7
8#[derive(Args)]
9pub struct TelemetryArgs {
10 #[command(subcommand)]
11 command: TelemetryCommand,
12}
13
14#[derive(Subcommand)]
15enum TelemetryCommand {
16 Status,
18 Export,
20 Clear,
22}
23
24pub fn run(args: TelemetryArgs, json: bool) {
25 match args.command {
26 TelemetryCommand::Status => run_status(json),
27 TelemetryCommand::Export => run_export(),
28 TelemetryCommand::Clear => run_clear(json),
29 }
30}
31
32fn run_status(json: bool) {
33 let telemetry_enabled = is_telemetry_enabled();
34 let feedback_enabled = is_feedback_enabled();
35 let remote_url = get_telemetry_url();
36 let journal_size = analytics::journal_size_bytes();
37 let events = analytics::load_events();
38
39 if json {
40 let client_id = get_or_create_client_id();
41 println!(
42 "{}",
43 serde_json::json!({
44 "telemetry": telemetry_enabled,
45 "feedback": feedback_enabled,
46 "mode": if remote_url.is_some() { "local+remote" } else { "local" },
47 "remote_url": remote_url,
48 "client_id_prefix": client_id.as_deref().map(|s| &s[..s.len().min(8)]),
49 "journal_events": events.len(),
50 "journal_size_bytes": journal_size,
51 })
52 );
53 } else {
54 let tl = if telemetry_enabled {
55 "enabled".green().to_string()
56 } else {
57 "disabled".red().to_string()
58 };
59 let fb = if feedback_enabled {
60 "enabled".green().to_string()
61 } else {
62 "disabled".red().to_string()
63 };
64 let mode = if remote_url.is_some() {
65 "local + remote".cyan().to_string()
66 } else {
67 "local only".yellow().to_string()
68 };
69
70 eprintln!("{}", "Telemetry Status".bold());
71 eprintln!(" Telemetry: {}", tl);
72 eprintln!(" Feedback: {}", fb);
73 eprintln!(" Mode: {}", mode);
74 if let Some(ref url) = remote_url {
75 eprintln!(" Remote: {}", url);
76 } else {
77 eprintln!(
78 " Remote: {}",
79 "(not configured — set telemetry_url in config to enable)".dimmed()
80 );
81 }
82 if let Some(cid) = get_or_create_client_id() {
83 let prefix = &cid[..cid.len().min(8)];
84 eprintln!(" Client ID: {}...", prefix);
85 }
86 eprintln!(
87 " Journal: {} events, {:.1} KB",
88 events.len(),
89 journal_size as f64 / 1024.0
90 );
91
92 eprintln!("\n{}", "Configuration:".bold());
93 eprintln!(" Disable: CHUB_TELEMETRY=0 or telemetry: false in config");
94 eprintln!(" Remote: Set telemetry_url in ~/.chub/config.yaml");
95 eprintln!(" View: chub stats --days 30");
96 eprintln!(" Export: chub telemetry export > events.jsonl");
97 eprintln!(" Clear: chub telemetry clear");
98 }
99}
100
101fn run_export() {
102 print!("{}", analytics::export_raw());
103}
104
105fn run_clear(json: bool) {
106 let events = analytics::load_events();
107 let count = events.len();
108
109 if analytics::clear_journal() {
110 if json {
111 println!(
112 "{}",
113 serde_json::json!({ "status": "cleared", "events_removed": count })
114 );
115 } else {
116 eprintln!("{} ({} events removed)", "Journal cleared.".green(), count);
117 }
118 } else if json {
119 println!(
120 "{}",
121 serde_json::json!({ "status": "error", "reason": "could_not_delete" })
122 );
123 } else {
124 eprintln!("{}", "Failed to clear journal.".red());
125 }
126}