sc/lib.rs
1//! SaveContext CLI - The OS for AI coding agents
2//!
3//! This crate provides the core functionality for the `sc` CLI tool.
4//!
5//! # Architecture
6//!
7//! - [`cli`] - Command-line interface using clap
8//! - [`model`] - Data types (Session, Issue, ContextItem, Checkpoint, Plan)
9//! - [`storage`] - SQLite database layer
10//! - [`sync`] - JSONL import/export operations
11//! - [`config`] - Configuration management
12//! - [`embeddings`] - Embedding providers (Ollama, HuggingFace)
13//! - [`error`] - Error types and handling
14
15#![forbid(unsafe_code)]
16#![warn(clippy::pedantic)]
17#![allow(clippy::module_name_repetitions)]
18
19pub mod cli;
20pub mod config;
21pub mod embeddings;
22pub mod error;
23pub mod model;
24pub mod storage;
25pub mod sync;
26pub mod validate;
27
28pub use error::{Error, Result};
29
30/// Global silent mode flag for `--silent` output.
31///
32/// When set, create/mutate commands print only the ID or key
33/// instead of full output. Avoids threading a `silent` bool
34/// through every handler signature.
35pub static SILENT: std::sync::atomic::AtomicBool = std::sync::atomic::AtomicBool::new(false);
36
37/// Global dry-run flag for `--dry-run`.
38///
39/// When set, mutate commands preview what would happen without writing.
40pub static DRY_RUN: std::sync::atomic::AtomicBool = std::sync::atomic::AtomicBool::new(false);
41
42/// Global CSV output flag (set when `--format csv`).
43pub static CSV_OUTPUT: std::sync::atomic::AtomicBool = std::sync::atomic::AtomicBool::new(false);
44
45/// Check if silent mode is active.
46#[inline]
47pub fn is_silent() -> bool {
48 SILENT.load(std::sync::atomic::Ordering::Relaxed)
49}
50
51/// Check if dry-run mode is active.
52#[inline]
53pub fn is_dry_run() -> bool {
54 DRY_RUN.load(std::sync::atomic::Ordering::Relaxed)
55}
56
57/// Check if CSV output is requested.
58#[inline]
59pub fn is_csv() -> bool {
60 CSV_OUTPUT.load(std::sync::atomic::Ordering::Relaxed)
61}
62
63/// Escape a value for CSV output (wrap in quotes if it contains commas, quotes, or newlines).
64pub fn csv_escape(s: &str) -> String {
65 if s.contains(',') || s.contains('"') || s.contains('\n') {
66 format!("\"{}\"", s.replace('"', "\"\""))
67 } else {
68 s.to_string()
69 }
70}