#![deny(unsafe_code)]
#![deny(missing_docs)]
#![deny(clippy::all)]
#![deny(unreachable_pub)]
#![deny(clippy::unwrap_used)]
#![cfg_attr(test, allow(clippy::unwrap_used))]
#![expect(
dead_code,
reason = "incremental development — some plumbing used by later features"
)]
use std::process::ExitCode;
use clap::Parser;
mod admin_client;
mod bootstrap;
mod cli;
mod commands;
mod context;
mod dispatch;
mod formatter;
mod principal;
mod repl;
pub mod socket_client;
mod theme;
mod tui;
mod value_formatter;
mod workspace_layout;
#[tokio::main]
async fn main() -> ExitCode {
let parsed = match cli::Cli::try_parse() {
Ok(parsed) => parsed,
Err(error) => {
let hook_invocation = raw_args_include_hook();
let usage_error = error.use_stderr();
let exit_code = error.exit_code();
if hook_invocation && usage_error {
astrid_emit::write_continue_line();
}
let _ = error.print();
if hook_invocation && usage_error {
return commands::hook::failure_exit_code();
}
return ExitCode::from(u8::try_from(exit_code.clamp(0, 255)).unwrap_or(1));
},
};
let hook_invocation = matches!(&parsed.command, Some(cli::Commands::Hook(_)));
if !hook_invocation {
if workspace_layout::initialize(parsed.workspace_state_dir.clone()).is_err() {
eprintln!("error: workspace layout was already initialized");
return ExitCode::from(1);
}
bootstrap::init_logging(&parsed);
}
match principal::resolve_process(parsed.principal.as_deref()) {
Ok(p) => principal::set(p),
Err(e) => {
if hook_invocation {
astrid_emit::write_continue_line();
}
eprintln!("{}", theme::Theme::error(&format!("error: {e:#}")));
return if hook_invocation {
commands::hook::failure_exit_code()
} else {
ExitCode::from(1)
};
},
}
match Box::pin(dispatch::dispatch(parsed)).await {
Ok(code) => code,
Err(e) => {
if hook_invocation {
astrid_emit::write_continue_line();
}
eprintln!("{}", theme::Theme::error(&format!("error: {e:#}")));
if hook_invocation {
commands::hook::failure_exit_code()
} else {
ExitCode::from(1)
}
},
}
}
fn raw_args_include_hook() -> bool {
std::env::args().skip(1).any(|arg| arg == "hook")
}