fur_cli/commands/
printed.rs1use crate::commands::timeline::{run_timeline, TimelineArgs};
2use colored::*;
3use serde_json::Value;
4use std::fs;
5use std::path::Path;
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 let lower_out = out_path.to_lowercase();
49 let is_pdf = lower_out.ends_with(".pdf");
50
51 let args = TimelineArgs {
53 verbose,
54 contents: true,
55 out: Some(out_path.clone()),
56 conversation_override: None,
57 };
58
59 println!(
61 "{}",
62 format!(
63 "🖨️ Printing conversation: {} ({}) → {}",
64 title, id, out_path
65 )
66 .bright_green()
67 .bold()
68 );
69
70 run_timeline(args);
72
73 println!(
74 "{}",
75 if is_pdf {
76 format!("✔️ Exported PDF: {}", out_path)
77 } else {
78 format!("✔️ Exported Markdown: {}", out_path)
79 }
80 .bright_green()
81 .bold()
82 );
83}