use clap::{Parser, Subcommand, ValueEnum};
use std::path::PathBuf;
use crate::models::ReasoningLevel;
#[derive(Parser, Debug)]
#[command(name = "mermaid")]
#[command(version)]
#[command(about = "An open-source, model-agnostic AI pair programmer", long_about = None)]
#[command(after_help = TOP_LEVEL_HELP_AFTER)]
pub struct Cli {
#[arg(short, long)]
pub model: Option<String>,
#[arg(long)]
pub reasoning: Option<ReasoningLevel>,
#[arg(short, long)]
pub path: Option<PathBuf>,
#[arg(short, long)]
pub verbose: bool,
#[arg(long, conflicts_with = "continue_session")]
pub sessions: bool,
#[arg(long = "continue", conflicts_with = "sessions")]
pub continue_session: bool,
#[arg(long, value_name = "FILE")]
pub record: Option<PathBuf>,
#[arg(long, global = true, conflicts_with = "system_prompt_file")]
pub system_prompt: Option<String>,
#[arg(
long,
value_name = "FILE",
global = true,
conflicts_with = "system_prompt"
)]
pub system_prompt_file: Option<PathBuf>,
#[arg(long, global = true)]
pub append_system_prompt: Option<String>,
#[arg(long, value_name = "FILE", global = true)]
pub append_system_prompt_file: Option<PathBuf>,
#[command(subcommand)]
pub command: Option<Commands>,
}
const TOP_LEVEL_HELP_AFTER: &str = "\
Common first run:
mermaid doctor Check model, tools, safety, and project readiness
mermaid Start the full-screen terminal coding agent
mermaid run \"inspect this repo\" Run one prompt headlessly
mermaid self-test Run fast deterministic Mermaid self-tests
Command groups:
Everyday: chat, run, doctor, status, list, self-test
Model/context: models, model-info, --model, --reasoning, --system-prompt*
Safety/recovery: approvals, approve, deny, checkpoints, restore
Integrations: add, remove, mcp, cloud-setup, plugin, pr
Advanced runtime: daemon, tasks, task, processes, logs, stop, restart, ports, pair";
#[derive(Subcommand, Debug)]
pub enum Commands {
Init,
List,
Models,
ModelInfo {
model: String,
},
Chat,
Version,
Status,
Doctor {
#[arg(short, long, value_enum, default_value_t = OutputFormat::Text)]
format: OutputFormat,
},
SelfTest {
#[arg(short, long, value_enum, default_value_t = OutputFormat::Text)]
format: OutputFormat,
#[arg(long)]
keep_workspace: bool,
},
Tasks {
#[arg(short, long, default_value_t = 20)]
limit: usize,
},
Task {
id: String,
},
Processes {
#[arg(short, long, default_value_t = 20)]
limit: usize,
},
Logs {
id: String,
},
Stop {
id: String,
},
Restart {
id: String,
},
Open {
target: String,
},
Ports,
Approvals,
Approve {
id: String,
},
Deny {
id: String,
},
ToolRuns {
#[arg(short, long, default_value_t = 20)]
limit: usize,
},
Checkpoints {
#[arg(short, long, default_value_t = 20)]
limit: usize,
},
Restore {
id: String,
},
Memory {
#[arg(long)]
project: Option<PathBuf>,
},
Remember {
key: String,
value: String,
#[arg(long)]
project: Option<PathBuf>,
},
Forget {
id: String,
},
MemoryEdit {
id: String,
value: String,
},
Plugin {
#[command(subcommand)]
command: PluginCommand,
},
Daemon {
#[command(subcommand)]
command: DaemonCommand,
},
Pair {
#[arg(long)]
label: Option<String>,
},
#[command(hide = true)]
Qa {
#[command(subcommand)]
command: QaCommand,
},
Add {
name: String,
},
Remove {
name: String,
},
Mcp,
Pr {
#[command(subcommand)]
command: PrCommand,
},
CloudSetup,
Run {
prompt: String,
#[arg(short, long, value_enum, default_value_t = OutputFormat::Text)]
format: OutputFormat,
#[arg(long)]
max_tokens: Option<usize>,
#[arg(long)]
no_execute: bool,
},
}
#[derive(Subcommand, Debug)]
pub enum PluginCommand {
Install {
path: PathBuf,
},
List,
Enable {
id: String,
},
Disable {
id: String,
},
Audit {
path: PathBuf,
},
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, ValueEnum)]
pub enum GitHost {
Github,
Gitlab,
}
#[derive(Subcommand, Debug)]
pub enum PrCommand {
Create {
#[arg(short, long)]
title: Option<String>,
#[arg(short, long)]
body: Option<String>,
#[arg(long, value_name = "FILE", conflicts_with = "body")]
summary: Option<PathBuf>,
#[arg(long)]
base: Option<String>,
#[arg(long)]
draft: bool,
#[arg(long)]
web: bool,
#[arg(long, value_enum)]
provider: Option<GitHost>,
},
}
#[derive(Subcommand, Debug)]
pub enum DaemonCommand {
Install {
#[arg(long)]
start: bool,
#[arg(long)]
force: bool,
},
Uninstall,
Start,
Stop,
Restart,
Status,
Logs {
#[arg(short, long)]
follow: bool,
#[arg(short = 'n', long, default_value_t = 100)]
lines: usize,
},
PrintUnit,
}
#[derive(Subcommand, Debug)]
pub enum QaCommand {
CompactSmoke {
#[arg(long, default_value_t = 6)]
turns: usize,
#[arg(short, long, value_enum, default_value_t = OutputFormat::Json)]
format: OutputFormat,
},
}
#[derive(Debug, Clone, Copy, ValueEnum)]
pub enum OutputFormat {
Text,
Json,
Markdown,
}