arcature-cli 2026.1.1

Developer lifecycle CLI for Arcature applications.
Documentation
//! `arc routes` — list all application routes (side-effect-free).
//!
//! Loads the metadata artifact (no application boot) and prints a route
//! table or JSON. Mirrors the `arc routes` output contract from PROGRAM.md
//! §"arc routes": METHOD, PATH, NAME, HANDLER. Supports `--json`.

use crate::cli::OutputFormat;
use crate::error::CommandError;
use crate::metadata::{RouteEntry, Uag};
use crate::project;
use serde::Serialize;

pub(crate) fn execute(format: OutputFormat) -> Result<(), CommandError> {
    let project = project::discover()?;
    let artifact = crate::metadata::load(&project).map_err(CommandError::Metadata)?;
    let routes: Vec<&RouteEntry> = artifact.routes.iter().collect();
    match format {
        OutputFormat::Human => print_human(&routes),
        OutputFormat::Json => print_json(&artifact)?,
    }
    Ok(())
}

fn print_human(routes: &[&RouteEntry]) {
    println!("{:<8} {:<20} {:<20} HANDLER", "METHOD", "PATH", "NAME");
    for route in routes {
        println!(
            "{:<8} {:<20} {:<20} {}",
            route.method.to_uppercase(),
            route.path,
            route.name,
            route.handler
        );
    }
}

fn print_json(artifact: &Uag) -> Result<(), CommandError> {
    #[derive(Serialize)]
    struct Out<'a> {
        routes: &'a [RouteEntry],
    }
    println!(
        "{}",
        serde_json::to_string_pretty(&Out {
            routes: &artifact.routes
        })?
    );
    Ok(())
}