Skip to main content

spec_driven_docs/commands/
status.rs

1//! `status` subcommand: runtime-shape.
2//!
3//! Resolves the target, asks the status service, and renders text or JSON.
4//! Status is a report, not a gate: drift never turns into a failing exit.
5
6use crate::cli::status::StatusArgs;
7use crate::context::AppContext;
8use crate::error::AppError;
9use crate::output;
10use crate::services::status::status;
11
12/// Report an instance's state.
13///
14/// # Errors
15///
16/// [`AppError::ManifestInvalid`] when a manifest exists but cannot be
17/// trusted; manifest absence reports instead of failing.
18pub fn run(ctx: &AppContext, args: StatusArgs) -> Result<(), AppError> {
19    let target = if args.target.is_absolute() {
20        args.target
21    } else if args.target == "." {
22        ctx.cwd.clone()
23    } else {
24        return Err(AppError::Usage("target must be absolute or .".to_string()));
25    };
26    let report = status(&target)?;
27    if args.json {
28        return output::json(&report);
29    }
30    if !report.instance {
31        output::line(format!("no instance at {target}"));
32        return Ok(());
33    }
34    let profile = report.profile.map_or("unknown", |profile| profile.as_str());
35    if let Some(version) = report.canon_version {
36        output::line(format!(
37            "spec-driven-docs {version} ({profile}) at {target}"
38        ));
39    }
40    if let Some(alignment) = report.alignment {
41        let word = match alignment {
42            crate::services::status::Alignment::Aligned => "aligned",
43            crate::services::status::Alignment::BinaryNewer => "binary newer; run 'sdd upgrade'",
44            crate::services::status::Alignment::InstanceNewer => "instance newer; upgrade sdd",
45        };
46        output::line(format!("alignment: {word}"));
47    }
48    output::line(format!(
49        "managed drift: {}; adopted drift: {}; failures: {}",
50        report.managed_drift, report.adopted_drift, report.failures
51    ));
52    Ok(())
53}