Skip to main content

bito_lint/
lib.rs

1//! Library interface for the `bito-lint` CLI.
2//!
3//! This crate exposes the CLI's argument parser and command structure as a library,
4//! primarily for documentation generation and testing. The actual entry point is
5//! in `main.rs`.
6//!
7//! # Structure
8//!
9//! - [`Cli`] - The root argument parser (clap derive)
10//! - [`Commands`] - Available subcommands
11//! - [`commands`] - Command implementations
12//!
13//! # Documentation Generation
14//!
15//! The [`command()`] function returns the clap `Command` for generating man pages
16//! and shell completions via `xtask`.
17pub mod commands;
18
19#[cfg(feature = "mcp")]
20pub mod server;
21
22use clap::{CommandFactory, Parser, Subcommand};
23use std::path::PathBuf;
24
25/// Color output preference.
26#[derive(Debug, Clone, Copy, Default, clap::ValueEnum)]
27pub enum ColorChoice {
28    /// Detect terminal capabilities automatically.
29    #[default]
30    Auto,
31    /// Always emit colors.
32    Always,
33    /// Never emit colors.
34    Never,
35}
36
37impl ColorChoice {
38    /// Configure global color output based on this choice.
39    ///
40    /// Call this once at startup to set the color mode.
41    pub fn apply(self) {
42        match self {
43            Self::Auto => {} // owo-colors auto-detects by default
44            Self::Always => owo_colors::set_override(true),
45            Self::Never => owo_colors::set_override(false),
46        }
47    }
48}
49
50const ENV_HELP: &str = "\
51ENVIRONMENT VARIABLES:
52    RUST_LOG                Log filter (e.g., debug, bito-lint=trace)
53    BITO_LINT_LOG_PATH     Log file path (rotated daily)
54    BITO_LINT_LOG_DIR      Log directory
55    BITO_LINT_TOKENIZER    Tokenizer backend (claude, openai)
56";
57/// Command-line interface definition for bito-lint.
58#[derive(Parser)]
59#[command(name = "bito-lint")]
60#[command(about = "Quality gate tooling for building-in-the-open artifacts", long_about = None)]
61#[command(version, arg_required_else_help = true)]
62#[command(after_long_help = ENV_HELP)]
63pub struct Cli {
64    /// The subcommand to execute.
65    #[command(subcommand)]
66    pub command: Option<Commands>,
67
68    /// Print only the version number (for scripting)
69    #[arg(long)]
70    pub version_only: bool,
71
72    /// Path to configuration file (overrides discovery)
73    #[arg(short, long, global = true, value_name = "FILE")]
74    pub config: Option<PathBuf>,
75
76    /// Run as if started in DIR
77    #[arg(short = 'C', long, global = true)]
78    pub chdir: Option<PathBuf>,
79
80    /// Only print errors (suppresses warnings/info)
81    #[arg(short, long, global = true)]
82    pub quiet: bool,
83
84    /// More detail (repeatable; e.g. -vv)
85    #[arg(short, long, global = true, action = clap::ArgAction::Count)]
86    pub verbose: u8,
87
88    /// Colorize output
89    #[arg(long, global = true, value_enum, default_value_t)]
90    pub color: ColorChoice,
91
92    /// Output as JSON (for scripting)
93    #[arg(long, global = true)]
94    pub json: bool,
95}
96
97/// Available subcommands for the CLI.
98#[derive(Subcommand)]
99pub enum Commands {
100    /// Run comprehensive writing analysis
101    Analyze(commands::analyze::AnalyzeArgs),
102
103    /// Count tokens in a file
104    Tokens(commands::tokens::TokensArgs),
105
106    /// Score readability (Flesch-Kincaid Grade Level)
107    Readability(commands::readability::ReadabilityArgs),
108
109    /// Check document completeness against a template
110    Completeness(commands::completeness::CompletenessArgs),
111
112    /// Check grammar and passive voice
113    Grammar(commands::grammar::GrammarArgs),
114
115    /// Lint a file according to project rules
116    Lint(commands::lint::LintArgs),
117
118    /// Diagnose configuration and environment
119    Doctor(commands::doctor::DoctorArgs),
120    /// Show package information
121    Info(commands::info::InfoArgs),
122    /// Start MCP (Model Context Protocol) server on stdio
123    #[cfg(feature = "mcp")]
124    Serve(commands::serve::ServeArgs),
125}
126
127/// Returns the clap command for documentation generation
128pub fn command() -> clap::Command {
129    Cli::command()
130}