devist 0.7.0

Project bootstrap CLI for AI-assisted development. Spin up new projects from templates, manage backends, and keep your codebase comprehensible.
mod commands;
mod config;
mod git;
mod paths;
mod registry;
mod render;
mod runner;
mod scanner;
mod state;
mod template;
mod worker;

use anyhow::Result;
use clap::{Parser, Subcommand};
use std::path::PathBuf;

#[derive(Parser)]
#[command(name = "devist")]
#[command(version, about = "Project bootstrap CLI for AI-assisted development")]
struct Cli {
    #[command(subcommand)]
    command: Commands,
}

#[derive(Subcommand)]
enum Commands {
    /// Check environment dependencies
    Doctor,
    /// Show devist info
    About,
    /// Initialize ~/.devist workspace (run once)
    Setup,
    /// Manage templates
    Template {
        #[command(subcommand)]
        cmd: commands::template::TemplateCmd,
    },
    /// Manage registered projects
    Project {
        #[command(subcommand)]
        cmd: commands::project::ProjectCmd,
    },
    /// Create a new project from a template
    Init {
        /// Project name
        name: String,
        /// Template to use
        #[arg(short, long)]
        template: String,
        /// Target directory (defaults to ./<name>)
        #[arg(long)]
        path: Option<PathBuf>,
        /// Override variables: --var key=value
        #[arg(long = "var", value_name = "KEY=VALUE")]
        vars: Vec<String>,
    },
    /// Start a project's backend (stops any other active backend first)
    Start {
        /// Project name
        name: String,
        /// Also run the dev server in foreground after starting backend
        #[arg(long)]
        dev: bool,
    },
    /// Stop the active project's backend (or a specific one)
    Stop {
        /// Optional project name (defaults to currently active)
        name: Option<String>,
    },
    /// Background worker that observes monitored projects and records events
    Worker {
        #[command(subcommand)]
        cmd: commands::worker::WorkerCmd,
    },
}

fn main() -> Result<()> {
    let cli = Cli::parse();
    match cli.command {
        Commands::Doctor => commands::doctor::run(),
        Commands::About => commands::about::run(),
        Commands::Setup => commands::init_workspace::run(),
        Commands::Template { cmd } => commands::template::run(cmd),
        Commands::Project { cmd } => commands::project::run(cmd),
        Commands::Init {
            name,
            template,
            path,
            vars,
        } => commands::init::run(name, template, path, vars),
        Commands::Start { name, dev } => commands::start::run(name, dev),
        Commands::Stop { name } => commands::stop::run(name),
        Commands::Worker { cmd } => commands::worker::run(cmd),
    }
}