use clap::{Parser, Subcommand};
#[derive(Parser, Debug)]
#[command(
name = "mc",
about = "MissionControl CLI -- manage customers, contacts, projects, meetings, research, tasks, and proposals",
version,
after_help = "\x1b[1mExamples:\x1b[0m
mc status Show dashboard
mc list customers --status active List active customers
mc show CUST-001 Show customer details
mc new customer \"Acme Inc\" Create a new customer (interactive)
mc -y new customer \"Acme Inc\" Create with defaults (no prompts)
mc new task \"Fix bug\" --project PROJ-001 --priority 2
mc task board --project PROJ-001 Show kanban board
mc task move TASK-001 in-progress Change task status
mc task next Show next actionable task
mc validate Check repo structure
mc index Rebuild JSON indexes
mc init Initialize a new MissionControl repo
mc init --project Initialize a lightweight project repo"
)]
pub struct Cli {
#[arg(long)]
pub root: Option<String>,
#[arg(short = 'y', long = "yes")]
pub yes: bool,
#[command(subcommand)]
pub command: Command,
}
#[derive(Subcommand, Debug)]
pub enum Command {
#[command(after_help = "\x1b[1mExamples:\x1b[0m
mc new customer \"Acme Inc\"
mc new contact \"Alice Smith\" --customer CUST-001
mc new project \"Data Pipeline\" --owner alice --status active
mc new meeting \"Weekly Sync\" --date 2025-06-01 --time 14:00
mc new research \"LLM Benchmarks\" --agents claude,gemini
mc new task \"Fix login bug\" --project PROJ-001 --priority 1
mc new sprint \"2026-W05\" --start-date 2026-01-27 --end-date 2026-02-07 --goal \"Auth module\"
mc new proposal \"Use PostgreSQL\" --type architecture --author alice")]
New {
#[command(subcommand)]
entity: NewEntity,
},
#[command(after_help = "\x1b[1mExamples:\x1b[0m
mc list customers
mc list customers --status active
mc list contacts --customer CUST-001
mc list projects --tag ml
mc list meetings --status scheduled
mc list tasks --status in-progress --project PROJ-001
mc list sprints --status active
mc list proposals --status accepted")]
List {
#[command(subcommand)]
entity: ListEntity,
},
#[command(after_help = "\x1b[1mExamples:\x1b[0m
mc show CUST-001
mc show CONT-001
mc show PROJ-001
mc show MTG-001
mc show RES-001
mc show TASK-001
mc show SPR-001
mc show PROP-001")]
Show {
id: String,
},
#[command(after_help = "\x1b[1mExamples:\x1b[0m
mc index Rebuild all JSON indexes from entity files")]
Index,
#[command(after_help = "\x1b[1mExamples:\x1b[0m
mc export customer CUST-001 Export customer folder to a zip file")]
Export {
#[command(subcommand)]
entity: ExportEntity,
},
#[command(after_help = "\x1b[1mExamples:\x1b[0m
mc print meeting MTG-001 Meeting notes to PDF
mc print meeting MTG-001 -o meeting.pdf Custom output path
mc print research RES-001 Research final report to PDF
mc print research RES-001 --file report.md Specific file from final/
mc print file ./docs/architecture.md Any markdown file to PDF
mc print file ./notes/kickoff.md -t meeting Use meeting cover template")]
Print {
#[command(subcommand)]
entity: PrintEntity,
},
#[command(after_help = "\x1b[1mExamples:\x1b[0m
mc validate Check all entities for missing/invalid frontmatter fields
Prints warnings for each issue found, or \"All files valid\" if clean.")]
Validate,
#[command(after_help = "\x1b[1mExamples:\x1b[0m
mc status Show entity counts, recent activity, and task summary")]
Status,
#[command(after_help = "\x1b[1mExamples:\x1b[0m
mc serve Start on default port 5000
mc serve --port 8080 Start on port 8080
Open http://localhost:<port> in your browser to view the dashboard.")]
Serve {
#[arg(long, default_value_t = 5000)]
port: u16,
#[arg(long, default_value = "")]
base_path: String,
},
#[command(after_help = "\x1b[1mIntegration:\x1b[0m
Claude Code Add to .mcp.json: {\"mcpServers\":{\"mc\":{\"command\":\"mc\",\"args\":[\"mcp\"]}}}
Cursor Settings > MCP > Add server: command = mc, args = [\"mcp\"]
VS Code Add to .vscode/mcp.json with command \"mc\" and args [\"mcp\"]")]
Mcp,
#[command(after_help = "\x1b[1mExamples:\x1b[0m
mc init Full setup (customers, projects, meetings, etc.)
mc init --project Lightweight project setup (tasks, meetings, research)
mc init --embedded Embedded .mc/ folder in an existing project
mc init --name \"My Project\" Set the repo name
mc init /path/to/dir Initialize in a specific directory
mc -y init Skip prompts, use defaults
mc init --force Reinitialize even if config exists")]
Init {
#[arg(long)]
project: bool,
#[arg(long)]
embedded: bool,
#[arg(long)]
name: Option<String>,
path: Option<String>,
#[arg(long)]
force: bool,
},
#[command(after_help = "\x1b[1mExamples:\x1b[0m
mc task board Show kanban board
mc task board --project PROJ-001 Board for a project
mc task move TASK-001 in-progress Change task status
mc task move TASK-001 done Complete a task
mc task next Show next actionable task
mc task next --project PROJ-001 Next task for a project")]
Task {
#[command(subcommand)]
subcmd: TaskSubcommand,
},
}
#[derive(Subcommand, Debug)]
pub enum NewEntity {
#[command(after_help = "\x1b[1mExamples:\x1b[0m
mc new customer \"Acme Inc\"
mc new customer \"Acme Inc\" --owner alice --status active
mc new customer \"Acme Inc\" --tags \"enterprise,priority\"")]
Customer {
name: String,
#[arg(long)]
owner: Option<String>,
#[arg(long)]
status: Option<String>,
#[arg(long)]
tags: Option<String>,
},
#[command(after_help = "\x1b[1mExamples:\x1b[0m
mc new project \"Data Pipeline\"
mc new project \"Data Pipeline\" --owner bob --status active
mc new project \"Data Pipeline\" --customers CUST-001 --tags \"ml,infra\"")]
Project {
name: String,
#[arg(long)]
owner: Option<String>,
#[arg(long)]
status: Option<String>,
#[arg(long)]
customers: Option<String>,
#[arg(long)]
tags: Option<String>,
},
#[command(after_help = "\x1b[1mExamples:\x1b[0m
mc new meeting \"Weekly Sync\"
mc new meeting \"Sprint Review\" --date 2025-06-01 --time 14:00 --duration 1h
mc new meeting \"Client Call\" --customers CUST-001 --projects PROJ-001
mc new meeting \"Standup\" --status scheduled --tags \"recurring\"")]
Meeting {
title: String,
#[arg(long)]
date: Option<String>,
#[arg(long)]
time: Option<String>,
#[arg(long)]
duration: Option<String>,
#[arg(long)]
status: Option<String>,
#[arg(long)]
tags: Option<String>,
#[arg(long)]
customers: Option<String>,
#[arg(long)]
projects: Option<String>,
#[arg(long)]
attendees: Option<String>,
},
#[command(after_help = "\x1b[1mExamples:\x1b[0m
mc new research \"LLM Benchmarks\"
mc new research \"LLM Benchmarks\" --owner alice --agents claude,gemini
mc new research \"LLM Benchmarks\" --tags \"ai,benchmarks\"")]
Research {
title: String,
#[arg(long)]
owner: Option<String>,
#[arg(long)]
agents: Option<String>,
#[arg(long)]
tags: Option<String>,
},
#[command(after_help = "\x1b[1mExamples:\x1b[0m
mc new task \"Select motors\" --project PROJ-001 --priority 2
mc new task \"Review contract\" --customer CUST-001
mc new task \"Update CI pipeline\"
mc new task \"Write tests\" --sprint 2026-W05 --depends-on TASK-001
mc -y new task \"Quick task\" --project PROJ-001")]
Task {
title: String,
#[arg(long)]
project: Option<String>,
#[arg(long)]
customer: Option<String>,
#[arg(long)]
owner: Option<String>,
#[arg(long)]
status: Option<String>,
#[arg(long)]
priority: Option<u32>,
#[arg(long)]
tags: Option<String>,
#[arg(long)]
sprint: Option<String>,
#[arg(long)]
depends_on: Option<String>,
#[arg(long)]
due_date: Option<String>,
},
#[command(after_help = "\x1b[1mExamples:\x1b[0m
mc new sprint \"2026-W05\"
mc new sprint \"2026-W05\" --start-date 2026-01-27 --end-date 2026-02-07
mc new sprint \"2026-W05\" --goal \"Complete auth module\" --projects PROJ-001")]
Sprint {
title: String,
#[arg(long)]
owner: Option<String>,
#[arg(long)]
status: Option<String>,
#[arg(long)]
goal: Option<String>,
#[arg(long)]
start_date: Option<String>,
#[arg(long)]
end_date: Option<String>,
#[arg(long)]
projects: Option<String>,
#[arg(long)]
tags: Option<String>,
},
#[command(after_help = "\x1b[1mExamples:\x1b[0m
mc new proposal \"Use PostgreSQL for primary database\"
mc new proposal \"Adopt microservices\" --type architecture --author alice
mc new proposal \"Switch to React\" --status proposed --tags \"frontend,framework\"
mc new proposal \"New auth flow\" --supersedes PROP-001")]
Proposal {
title: String,
#[arg(long)]
author: Option<String>,
#[arg(long)]
status: Option<String>,
#[arg(long = "type")]
proposal_type: Option<String>,
#[arg(long)]
tags: Option<String>,
#[arg(long)]
supersedes: Option<String>,
},
#[command(after_help = "\x1b[1mExamples:\x1b[0m
mc new contact \"Alice Smith\" --customer CUST-001
mc new contact \"Bob Jones\" --customer CUST-001 --role \"VP Engineering\"
mc new contact \"Carol Lee\" --customer CUST-002 --email carol@example.com")]
Contact {
name: String,
#[arg(long)]
customer: String,
#[arg(long)]
role: Option<String>,
#[arg(long)]
email: Option<String>,
#[arg(long)]
phone: Option<String>,
#[arg(long)]
status: Option<String>,
#[arg(long)]
tags: Option<String>,
},
}
#[derive(Subcommand, Debug)]
pub enum ListEntity {
#[command(after_help = "\x1b[1mExamples:\x1b[0m
mc list customers
mc list customers --status active
mc list customers --tag enterprise")]
Customers {
#[arg(long)]
status: Option<String>,
#[arg(long)]
tag: Option<String>,
},
#[command(after_help = "\x1b[1mExamples:\x1b[0m
mc list projects
mc list projects --status active
mc list projects --tag ml")]
Projects {
#[arg(long)]
status: Option<String>,
#[arg(long)]
tag: Option<String>,
},
#[command(after_help = "\x1b[1mExamples:\x1b[0m
mc list meetings
mc list meetings --status scheduled
mc list meetings --tag recurring")]
Meetings {
#[arg(long)]
status: Option<String>,
#[arg(long)]
tag: Option<String>,
},
#[command(after_help = "\x1b[1mExamples:\x1b[0m
mc list research
mc list research --status draft
mc list research --tag ai")]
Research {
#[arg(long)]
status: Option<String>,
#[arg(long)]
tag: Option<String>,
},
#[command(after_help = "\x1b[1mExamples:\x1b[0m
mc list sprints
mc list sprints --status active
mc list sprints --tag q1")]
Sprints {
#[arg(long)]
status: Option<String>,
#[arg(long)]
tag: Option<String>,
},
#[command(after_help = "\x1b[1mExamples:\x1b[0m
mc list proposals
mc list proposals --status accepted
mc list proposals --tag architecture")]
Proposals {
#[arg(long)]
status: Option<String>,
#[arg(long)]
tag: Option<String>,
},
#[command(after_help = "\x1b[1mExamples:\x1b[0m
mc list contacts
mc list contacts --status active
mc list contacts --customer CUST-001
mc list contacts --tag engineering")]
Contacts {
#[arg(long)]
status: Option<String>,
#[arg(long)]
tag: Option<String>,
#[arg(long)]
customer: Option<String>,
},
#[command(after_help = "\x1b[1mExamples:\x1b[0m
mc list tasks
mc list tasks --status in-progress --project PROJ-001
mc list tasks --priority 1 --owner alice
mc list tasks --sprint 2026-W05")]
Tasks {
#[arg(long)]
status: Option<String>,
#[arg(long)]
tag: Option<String>,
#[arg(long)]
project: Option<String>,
#[arg(long)]
customer: Option<String>,
#[arg(long)]
priority: Option<u32>,
#[arg(long)]
sprint: Option<String>,
#[arg(long)]
owner: Option<String>,
},
}
#[derive(Subcommand, Debug)]
pub enum TaskSubcommand {
#[command(after_help = "\x1b[1mExamples:\x1b[0m
mc task board
mc task board --project PROJ-001
mc task board --sprint 2026-W05
mc task board --customer CUST-001")]
Board {
#[arg(long)]
project: Option<String>,
#[arg(long)]
customer: Option<String>,
#[arg(long)]
sprint: Option<String>,
},
#[command(after_help = "\x1b[1mExamples:\x1b[0m
mc task move TASK-001 in-progress
mc task move TASK-001 todo --sprint 2026-W05
mc task move TASK-003 done
mc task move TASK-003 backlog")]
Move {
id: String,
status: String,
#[arg(long)]
sprint: Option<String>,
},
#[command(after_help = "\x1b[1mExamples:\x1b[0m
mc task next
mc task next --project PROJ-001
mc task next --customer CUST-001")]
Next {
#[arg(long)]
project: Option<String>,
#[arg(long)]
customer: Option<String>,
},
}
#[derive(Subcommand, Debug)]
pub enum ExportEntity {
#[command(after_help = "\x1b[1mExamples:\x1b[0m
mc export customer CUST-001 Export by ID
mc export customer acme-inc Export by slug")]
Customer {
id: String,
},
}
#[derive(Clone, Debug, clap::ValueEnum)]
pub enum PrintTemplate {
Standard,
Meeting,
Research,
Sprint,
}
#[derive(Subcommand, Debug)]
pub enum PrintEntity {
Meeting {
id: String,
#[arg(short, long)]
output: Option<String>,
},
Research {
id: String,
#[arg(short, long)]
output: Option<String>,
#[arg(long)]
file: Option<String>,
},
File {
path: String,
#[arg(short, long)]
output: Option<String>,
#[arg(short, long, default_value = "standard")]
template: PrintTemplate,
#[arg(long)]
title: Option<String>,
},
}