Skip to main content

coding_tools/cli/
ct_check.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright 2026 Jonathan Shook
3
4//! The `ct-check` command grammar (see [`crate::cli`]); the `ct-check` bin is a
5//! thin parse-and-dispatch wrapper over this `Cli`.
6
7use std::path::PathBuf;
8
9use clap::Parser;
10
11use crate::explain::Format;
12use crate::pulse::HeartbeatOpts;
13
14#[derive(Parser, Debug)]
15#[command(
16    name = "ct-check",
17    version,
18    about = "Verify the project's recorded invariants from .ct/rules.jsonc (read-only).",
19    long_about = "ct-check runs the rule store's probes in order and reports each rule as SUCCESS, \
20                  ERROR, WARN, PENDING, or BROKEN (also reachable as `ct check`). It never writes \
21                  anything; rules are recorded with ct-rules. See `ct-check --explain` for \
22                  agent-oriented documentation."
23)]
24pub struct Cli {
25    /// Rule store. Default: the nearest .ct/rules.jsonc walking upward from the current directory.
26    #[arg(long)]
27    pub file: Option<PathBuf>,
28
29    /// Select rules whose id matches (substring->glob->regex promoted, anchored).
30    #[arg(long)]
31    pub id: Option<String>,
32
33    /// Select rules carrying any of these tags (comma-separated).
34    #[arg(long, value_delimiter = ',')]
35    pub tag: Vec<String>,
36
37    /// Stop after the first enforced violation; remaining rules are reported as skipped.
38    #[arg(long)]
39    pub fail_fast: bool,
40
41    /// Print the selected rules (id, lanes, question, tags); run nothing.
42    #[arg(long)]
43    pub list: bool,
44
45    /// Suppress per-rule lines and the default summary.
46    #[arg(long)]
47    pub quiet: bool,
48
49    /// Emit a structured JSON result instead of text (overrides the emit templates).
50    #[arg(long)]
51    pub json: bool,
52
53    /// Per-rule template written to stdout. Tokens: {RESULT} {ID} {QUESTION} {CODE} {WHY} {CMD}.
54    #[arg(long, value_name = "TEMPLATE")]
55    pub emit_each: Option<String>,
56
57    /// Summary template written to stdout. Tokens: {RESULT} {OK} {ERRORS} {WARNED} {PENDING} {BROKEN} {SKIPPED} {TOTAL} {REASON}.
58    #[arg(long, alias = "emit-stdout", value_name = "TEMPLATE")]
59    pub emit: Option<String>,
60
61    /// Summary template written to stderr (same tokens as --emit).
62    #[arg(long, value_name = "TEMPLATE")]
63    pub emit_stderr: Option<String>,
64
65    /// Default per-rule bound in seconds (fractional allowed); a rule's own timeout field overrides it. A timed-out probe is BROKEN.
66    #[arg(long, value_name = "SECS")]
67    pub timeout: Option<f64>,
68
69    #[command(flatten)]
70    pub heartbeat: HeartbeatOpts,
71
72    /// Print agent usage docs (md or json) and exit.
73    #[arg(long, value_enum, num_args = 0..=1, default_missing_value = "md")]
74    pub explain: Option<Format>,
75}