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}