Skip to main content

fur_cli/commands/status/
mod.rs

1pub mod core;
2pub mod render;
3
4use std::collections::HashMap;
5use std::fs;
6use std::path::Path;
7
8use colored::Colorize;
9use serde_json::{json, Value};
10
11use self::core::*;
12use self::render::*;
13
14use clap::Parser;
15
16#[derive(Parser, Debug)]
17pub struct StatusArgs {
18    /// Optional conversation override (used by `fur run` for ephemeral runs)
19    #[clap(skip)]
20    pub conversation_override: Option<String>,
21}
22
23pub fn run_status(args: StatusArgs) {
24    let fur_dir = Path::new(".fur");
25    let index_path = fur_dir.join("index.json");
26
27    if !index_path.exists() {
28        eprintln!(
29            "{}",
30            "🚨 .fur/ not found. Run `fur new` first.".red().bold()
31        );
32        return;
33    }
34
35    let avatars: Value = serde_json::from_str(
36        &fs::read_to_string(fur_dir.join("avatars.json")).unwrap_or_else(|_| "{}".to_string()),
37    )
38    .unwrap_or(json!({}));
39
40    let (index, mut conversation, mut current_msg_id) = load_index_and_conversation(&fur_dir);
41
42    if let Some(ref tid) = args.conversation_override {
43        let convo_path = fur_dir.join("tmp").join(format!("{}.json", tid));
44        if let Ok(content) = fs::read_to_string(&convo_path) {
45            if let Ok(tmp_conversation) = serde_json::from_str::<Value>(&content) {
46                conversation = tmp_conversation;
47            }
48        }
49    }
50
51    let id_to_message = load_conversation_messages(&fur_dir, &conversation);
52
53    if current_msg_id.is_empty() {
54        current_msg_id = first_message_fallback(&conversation);
55    }
56
57    render_status_ui(
58        &index,
59        &conversation,
60        &id_to_message,
61        &current_msg_id,
62        &avatars,
63    );
64}
65
66fn render_status_ui(
67    index: &Value,
68    conversation: &Value,
69    id_to_message: &HashMap<String, Value>,
70    current_msg_id: &str,
71    avatars: &Value,
72) {
73    // Active conversation
74    print_active_conversation(index, conversation);
75
76    // Current message
77    print_current_message(current_msg_id);
78
79    println!("{}", "─────────────────────────────".bright_black());
80
81    // Lineage (ancestors)
82    print_lineage(id_to_message, current_msg_id, avatars);
83
84    println!("{}", "─────────────────────────────".bright_black());
85    println!("{}", "Next messages from here:".bright_magenta().bold());
86
87    // Children + siblings
88    print_next_messages(id_to_message, conversation, current_msg_id, avatars);
89}