My personal-knowledge-system, with deeply integrated task tracking and long term goal planning capabilities.
1//! Filaments
2//! My (suri.codes) personal-knowledge-system, with deeply integrated task tracking and long term goal planning capabilities.
3//!
4
5use std::{process, sync::Arc};
6
7use crate::{
8 cli::Cli,
9 config::Config,
10 tui::TuiApp,
11 types::{Deimos, Kasten, KastenHandle},
12 viz::FilViz,
13};
14use clap::Parser;
15use tokio::sync::{RwLock, mpsc};
16use tracing::debug;
17
18mod cli;
19mod config;
20mod errors;
21mod logging;
22mod lsp;
23mod tui;
24mod types;
25mod viz;
26
27fn main() -> color_eyre::Result<()> {
28 errors::init()?;
29 logging::init()?;
30
31 let args = Cli::parse();
32
33 // create a new tokio runtime, shared behind arc
34 let rt = Arc::new(tokio::runtime::Runtime::new()?);
35
36 // if there are any commands, run those and exit
37 if let Some(command) = args.command {
38 return rt.block_on(async { command.process().await });
39 }
40
41 // create the kasten handle
42 let kh: KastenHandle = rt.block_on(async {
43 let cfg = Config::parse()?;
44
45 debug!("Config: {cfg:#?}");
46
47 Ok::<KastenHandle, color_eyre::Report>(Arc::new(RwLock::new(
48 Kasten::instansiate(cfg.fil_dir).await?,
49 )))
50 })?;
51
52 debug!("Kasten Handle: {kh:#?}");
53
54 let (signal_tx, signal_rx) = mpsc::unbounded_channel();
55
56 // then we spawn the tui on its own thread
57 let tui_handle = std::thread::spawn({
58 // arc stuff
59 let tui_rt = rt.clone();
60 let kh = kh.clone();
61 let signal_tx = signal_tx.clone();
62
63 // closure to run the tui
64 move || -> color_eyre::Result<()> {
65 // block the tui on the same runtime as above
66 tui_rt.block_on(async {
67 let mut tui = TuiApp::new(args.tick_rate, args.frame_rate, kh, signal_tx)?;
68 tui.run().await?;
69 // just close everything as soon as the tui is done running
70 process::exit(0);
71 })
72 }
73 });
74
75 // if they asked for the visualizer, we give them the visualizer
76 if args.visualizer {
77 // enter the guard so egui_async works properly
78 let _rt_guard = rt.enter();
79
80 // spawn deimos
81 {
82 let kh = kh.clone();
83 rt.spawn(async {
84 let deimos = Deimos::new(kh, signal_tx);
85 deimos.watch().await
86 });
87 }
88
89 let index = rt.block_on(async { kh.read().await.index.clone() });
90
91 FilViz::run(kh, signal_rx, &index)?;
92 }
93
94 // join on the tui
95 tui_handle.join().unwrap()?;
96 Ok(())
97}