pub(crate) use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet, VecDeque};
pub(crate) use std::path::{Path, PathBuf};
pub(crate) use candor_report::{report_entries_counted, report_files, ReportEntry, EFFECTS};
pub(crate) use regex::Regex;
pub(crate) use serde::Serialize;
mod load;
mod matching;
mod audit;
mod show;
mod callers;
mod policy;
mod diff;
mod containment;
mod state;
mod fix;
pub(crate) use load::*;
pub(crate) use matching::*;
pub(crate) use audit::*;
pub(crate) use show::*;
pub(crate) use callers::*;
pub(crate) use policy::*;
pub(crate) use diff::*;
pub(crate) use containment::*;
pub(crate) use state::*;
pub(crate) use fix::*;
fn main() {
let args: Vec<String> = std::env::args().skip(1).collect();
let cmd = args.first().map(String::as_str).unwrap_or("");
if cmd == "-V" || cmd == "--version" {
print_version();
std::process::exit(0);
}
if cmd == "-h" || cmd == "--help" {
print_help();
std::process::exit(0);
}
let rest = &args[args.len().min(1)..];
let code = match cmd {
"audit" => cmd_audit(rest),
"show" => cmd_show(rest),
"where" => cmd_where(rest),
"callers" => cmd_callers(rest),
"map" => cmd_map(rest),
"diff" => cmd_diff(rest),
"containment" => cmd_containment(rest),
"reachable" => cmd_reachable(rest),
"path" => cmd_path(rest),
"impact" => cmd_impact(rest),
"blindspots" => cmd_blindspots(rest),
"whatif" => cmd_whatif(rest),
"fix" => cmd_fix(rest),
"fix-gate" => cmd_fix_gate(rest),
"rewire" => cmd_rewire(rest),
"receipt" => cmd_receipt(rest),
"gains" => cmd_gains(rest),
"state" => cmd_state(rest),
"reports" => cmd_reports(rest),
"locate" => cmd_locate(rest),
"gate-verdict" => cmd_gate_verdict(rest),
"engine-version" => cmd_engine_version(rest),
"merge-hook" => cmd_merge_hook(rest),
"parsepolicy" => cmd_parsepolicy(rest),
"--agents" | "agents" => {
println!("<!-- candor-query {} · the agent contract for this installed version -->", env!("CARGO_PKG_VERSION"));
print!("{}", include_str!("../AGENTS.md"));
0
}
other => {
eprintln!(
"candor-query: unknown command '{other}' \
(audit|show|where|callers|map|diff|containment|reachable|path|impact|blindspots|whatif|fix|fix-gate|rewire|parsepolicy|receipt|gains|state|reports|locate|gate-verdict|engine-version|merge-hook|--agents)"
);
2
}
};
std::process::exit(code);
}
fn print_version() {
println!("candor-query {} (spec {})", env!("CARGO_PKG_VERSION"), candor_report::SPEC_VERSION);
println!("upgrade: cargo install candor-query --force");
}
fn print_help() {
println!(
"candor-query {} — read-only effect-report queries over candor's reports (candor-spec {})",
env!("CARGO_PKG_VERSION"),
candor_report::SPEC_VERSION
);
println!();
println!("USAGE: candor-query <command> [args…]");
println!(" candor-query --version | --help");
println!();
println!("COMMANDS:");
let rows: &[(&str, &str)] = &[
("audit <prefix> <engine_ver> <suspect_file> [--coverage]", "at-a-glance effect profile across the crates"),
("show <prefix> <query> <0|1>", "the effects a function performs (direct vs via a callee)"),
("where <prefix> <Effect> <0|1>", "which functions perform an effect (directly / inherited)"),
("callers <prefix> <query> <0|1> [--include-unknown]", "who reaches a function — its blast radius"),
("map <prefix> <0|1>", "per-module effect map (effects + function counts)"),
("diff <cur_prefix> <base_prefix> <0|1> <bver> <ever>", "per-function effect changes vs a baseline"),
("containment <prefix> [baseline_prefix] [--json]", "effects at the entry points, optionally vs a baseline"),
("reachable <prefix> [--json]", "the effects the program actually performs at runtime"),
("path <prefix> <fn-substring> <Effect> [--json]", "the call chain by which a fn comes to perform an effect"),
("impact <prefix> <fn-substring> [--json]", "the blast radius of a fn: effectful callers + entry points"),
("blindspots <prefix> [--json]", "the Unknown sources, ranked by their Unknown blast radius"),
("whatif <prefix> <fn> <Effect> [policy] [0|1]", "pre-edit verdict: blast radius + policy violations"),
("fix <prefix> <fn> <Effect> [policy] [0|1]", "the boundary fix: where the effect belongs + the hoist refactor"),
("fix-gate <prefix> [policy] [0|1]", "a fix for EVERY boundary crossing — the loop's block-message remedy"),
("rewire <cur_prefix> <base_prefix> [0|1]", "call edges a function DROPPED vs a baseline (de-wiring)"),
("parsepolicy <policy-file>", "dump a parsed CANDOR_POLICY as canonical JSON (conformance)"),
("receipt <prefix>", "the Claude Code receipt's report-derived fields (key<TAB>value)"),
("gains <cur_prefix> <base_prefix> [--json]", "every effect a fn gained since the baseline (self-review)"),
("state [<root>]", "a stable content hash of the .rs tree (source-freshness key)"),
("reports <prefix> [--exists|--backend|--clear-other <scan|lint>]", "list/probe/clean the report artifacts for a prefix"),
("locate <lib|scan> <dir>…", "print the newest matching report file under the dirs"),
("gate-verdict <parts-file> <out|->", "assemble the §3.3 gate verdict from NDJSON violation records"),
("engine-version <lib-path>", "print the candor-build-version tag embedded in a binary"),
("merge-hook <settings.json> <hook-command>", "idempotently merge candor's Stop hook into a settings file"),
("--agents", "print the agent contract embedded in this installed build"),
];
let w = rows.iter().map(|(u, _)| u.len()).max().unwrap_or(0);
for (usage, desc) in rows {
println!(" {usage:<w$} {desc}");
}
println!();
println!(" -V, --version print the installed build + spec contract (offline) and the upgrade line");
println!(" -h, --help print this help");
println!();
println!("See https://github.com/tombaldwin/candor");
}
#[cfg(test)]
mod tests;