kasl/lib.rs
1//! # Kasl - Key Activity Synchronization and Logging
2//!
3//! A command-line utility for tracking work activities, managing tasks,
4//! and generating productivity reports.
5//!
6//! ## Features
7//!
8//! - **Activity Monitoring**: Automatic detection of work sessions and breaks
9//! - **Productivity Analysis**: Comprehensive calculation engine with break recommendations
10//! - **Task Management**: Create, update, and track task completion
11//! - **Report Generation**: Daily and monthly productivity reports with advanced metrics
12//! - **External Integrations**: Sync with GitLab commits and Jira issues
13//! - **Data Export**: Export data to CSV, JSON, and Excel formats
14//! - **Template System**: Reusable task templates
15//! - **Tag System**: Organize tasks with custom tags
16//!
17//! ## Usage
18//!
19//! ```rust,no_run
20//! use kasl::commands::Cli;
21//!
22//! #[tokio::main]
23//! async fn main() -> anyhow::Result<()> {
24//! Cli::menu().await
25//! }
26//! ```
27
28pub mod api;
29pub mod commands;
30pub mod db;
31pub mod libs;
32
33/// Runs the CLI: the shared entry point behind both the `kasl` and `ka` binaries.
34///
35/// Sets up tracing, handles the internal `--daemon-run` mode used when the
36/// watcher spawns itself, and otherwise dispatches the parsed command.
37///
38/// # Errors
39///
40/// Propagates whatever the executed command fails with.
41pub fn run() -> anyhow::Result<()> {
42 let runtime = tokio::runtime::Runtime::new()?;
43 runtime.block_on(async {
44 // Initialize tracing only if debug mode is enabled; otherwise log output
45 // would clutter normal CLI usage.
46 if std::env::var("KASL_DEBUG").is_ok() || std::env::var("RUST_LOG").is_ok() {
47 tracing_subscriber::fmt()
48 .with_env_filter(tracing_subscriber::EnvFilter::try_from_default_env().unwrap_or_else(|_| "kasl=debug".into()))
49 .init();
50 }
51
52 // Intercepted before clap: this flag is how the background monitoring
53 // process is launched, not part of the public command surface.
54 let args: Vec<String> = std::env::args().collect();
55 if args.len() > 1 && args[1] == "--daemon-run" {
56 commands::watch::run_as_daemon().await?;
57 } else {
58 // Non-blocking; only surfaces a notification when one is due.
59 libs::update::Updater::show_update_notification().await;
60
61 commands::Cli::menu().await?;
62 }
63
64 Ok(())
65 })
66}