fur_cli/commands/
printed.rs1use std::fs;
2use std::path::Path;
3use serde_json::Value;
4use colored::*;
5use crate::commands::timeline::{run_timeline, TimelineArgs};
6
7pub fn run_printed(out: Option<String>, verbose: bool) {
9 let fur_dir = Path::new(".fur");
10 let index_path = fur_dir.join("index.json");
11
12 if !index_path.exists() {
13 eprintln!("🚨 .fur/ not found. Run `fur new` first.");
14 return;
15 }
16
17 let index: Value = serde_json::from_str(&fs::read_to_string(&index_path).unwrap()).unwrap();
19 let active_id = index["active_thread"].as_str().unwrap_or_default();
20 if active_id.is_empty() {
21 eprintln!("❌ No active conversation found.");
22 return;
23 }
24
25 let convo_path = fur_dir.join("threads").join(format!("{}.json", active_id));
27 let conversation_json: Value =
28 serde_json::from_str(&fs::read_to_string(&convo_path).unwrap()).unwrap();
29
30 let title = conversation_json["title"].as_str().unwrap_or("untitled");
31 let id = conversation_json["id"].as_str().unwrap_or("unknown");
32
33 let out_path = match out {
35 Some(p) => p,
36 None => {
37 let all_caps = title.to_uppercase().replace(' ', "_");
39
40 let short_id = id.split('-').next().unwrap_or(id);
42
43 format!("{}_{}.md", all_caps, short_id)
44 }
45 };
46
47
48 let lower_out = out_path.to_lowercase();
50 let is_pdf = lower_out.ends_with(".pdf");
51
52 let args = TimelineArgs {
54 verbose,
55 contents: true,
56 out: Some(out_path.clone()),
57 conversation_override: None,
58 };
59
60 println!(
62 "{}",
63 format!(
64 "🖨️ Printing conversation: {} ({}) → {}",
65 title, id, out_path
66 )
67 .bright_green()
68 .bold()
69 );
70
71 run_timeline(args);
73
74 println!(
75 "{}",
76 if is_pdf {
77 format!("✔️ Exported PDF: {}", out_path)
78 } else {
79 format!("✔️ Exported Markdown: {}", out_path)
80 }
81 .bright_green()
82 .bold()
83 );
84}