mod config;
mod doctor;
mod error;
mod help;
mod json;
mod new;
mod probes;
mod review;
mod shell;
mod skill;
mod version;
use std::process::ExitCode;
use project_canon_core::{Archetype, EnvConfig, Model, Questionnaire};
use crate::error::{fail, json_requested, CliError};
fn main() -> ExitCode {
let mut args: Vec<String> = std::env::args().skip(1).collect();
normalize_version_alias(&mut args);
if let Some(status) = help::render_if_requested(&args) {
return status;
}
match args.first().map(String::as_str) {
Some("config") => config::run(&args[1..]),
Some("doctor") => doctor::run(&args[1..]),
Some("new") => new::run(&args[1..]),
Some("review") => review::run(&args[1..]),
Some("skill") => skill::run(&args[1..]),
Some("version") => version::run(&args[1..]),
None | Some("--help") => smoke_summary(&args),
Some(other) => {
fail(
json_requested(&args),
CliError::actionable(
"usage_error",
format!(
"unknown subcommand or flag: {other:?}; known verbs: config, doctor, new, review, skill, version"
),
),
)
}
}
}
fn normalize_version_alias(args: &mut [String]) {
match args {
[json, alias, ..] if json == "--json" && alias == "--version" => {
*json = "version".to_string();
*alias = "--json".to_string();
}
[alias, ..] if alias == "--version" => *alias = "version".to_string(),
_ => {}
}
}
fn smoke_summary(_args: &[String]) -> ExitCode {
let model = Model::standard();
let cli_sections = model
.resolve(
&Questionnaire::builder(Archetype::Cli)
.all_conditionals_yes()
.build(),
)
.canon_section_set(&model)
.len();
let cfg = match config::resolve() {
Ok(config) => config,
Err(error) => return fail(json_requested(_args), error.into_cli()),
};
let home = std::env::var("HOME").unwrap_or_else(|_| "~".to_string());
eprintln!(
"project-canon {}: model loaded ({} base dimensions; cli profile covers {} canon sections).",
env!("CARGO_PKG_VERSION"),
model.base_members().len(),
cli_sections,
);
eprintln!(
"env layer resolved (gh: {}; repo root: {}; {} family repos).",
cfg.gh_account.as_deref().unwrap_or("not configured"),
cfg.repo_root
.as_deref()
.map(|root| EnvConfig::expand_home(root, &home))
.unwrap_or_else(|| "not configured".to_string()),
cfg.family_repos().len(),
);
eprintln!(
"Run `project-canon doctor --help`, `project-canon new --help`, `project-canon review --help`, `project-canon skill --help`, or `project-canon version --help`."
);
ExitCode::SUCCESS
}