fur_cli/commands/status/
core.rs1use std::fs;
2use std::path::Path;
3use serde_json::Value;
4use std::collections::HashMap;
5
6pub fn load_index_and_conversation(fur_dir: &Path)
7 -> (Value, Value, String)
8{
9 let index_path = fur_dir.join("index.json");
10 let index: Value = read_json(&index_path);
11
12 let conversation_id = index["active_thread"].as_str().unwrap_or("");
13 let current = index["current_message"].as_str().unwrap_or("").to_string();
14
15 let convo_path = fur_dir.join("threads").join(format!("{}.json", conversation_id));
16 let conversation: Value = read_json(&convo_path);
17
18 (index, conversation, current)
19}
20
21
22pub fn load_conversation_messages(
24 fur_dir: &Path,
25 conversation: &Value
26) -> HashMap<String, Value> {
27
28 let mut id_to_message = HashMap::new();
29
30 let mut stack: Vec<String> = conversation["messages"]
31 .as_array()
32 .unwrap_or(&vec![])
33 .iter()
34 .filter_map(|id| id.as_str().map(|s| s.to_string()))
35 .collect();
36
37 let messages_dir = fur_dir.join("messages");
38
39 while let Some(mid) = stack.pop() {
40
41 let msg_path = messages_dir.join(format!("{}.json", mid));
42
43 if let Some(content) = crate::security::io::read_text_file(&msg_path) {
44
45 if let Ok(mut obj) = serde_json::from_str::<Value>(&content) {
46
47 if crate::commands::jot::upgrade_message_schema(&mut obj) {
51
52 if let Ok(serialized) = serde_json::to_string_pretty(&obj) {
54 let _ = fs::write(&msg_path, serialized);
55 }
56 }
57
58 if let Some(children) = obj["children"].as_array() {
62 for c in children {
63 if let Some(cid) = c.as_str() {
64 stack.push(cid.to_string());
65 }
66 }
67 }
68
69 if let Some(blocks) = obj["branches"].as_array() {
73 for block in blocks {
74 if let Some(arr) = block.as_array() {
75 for c in arr {
76 if let Some(cid) = c.as_str() {
77 stack.push(cid.to_string());
78 }
79 }
80 }
81 }
82 }
83
84 id_to_message.insert(mid.clone(), obj);
85 }
86 }
87 }
88
89 id_to_message
90}
91
92
93pub fn first_message_fallback(conversation: &Value) -> String {
95 conversation["messages"]
96 .as_array()
97 .and_then(|arr| arr.get(0))
98 .and_then(|v| v.as_str())
99 .unwrap_or("")
100 .to_string()
101}
102
103fn read_json(path: &Path) -> Value {
104
105 use crate::security::io::read_text_file;
106
107 serde_json::from_str(
108 &read_text_file(path)
109 .expect("❌ Project locked. Run `fur unlock`.")
110 ).unwrap()
111}