use std::net::SocketAddr;
use clap::{Parser, Subcommand};
pub(crate) const DEFAULT_URL: &str = trusty_mpm::core::DEFAULT_DAEMON_URL;
pub(crate) const DEFAULT_ADDR: &str = trusty_mpm::core::DEFAULT_DAEMON_ADDR;
#[derive(Debug, Parser)]
#[command(name = "trusty-mpm", version, about = "trusty-mpm — unified binary")]
pub(crate) struct Cli {
#[arg(long, env = "TRUSTY_MPM_URL", default_value = DEFAULT_URL, global = true)]
pub(crate) url: String,
#[command(subcommand)]
pub(crate) command: Command,
}
#[derive(Debug, Subcommand)]
pub(crate) enum Command {
Status,
Start,
Serve {
#[arg(long)]
stdio: bool,
},
Stop,
Restart,
Project {
#[command(subcommand)]
action: ProjectAction,
},
Session {
#[command(subcommand)]
action: SessionAction,
},
Events,
Doctor,
Tui {
#[arg(long, env = "TRUSTY_MPM_URL", default_value = DEFAULT_URL)]
url: String,
#[arg(long, default_value_t = 1000)]
interval_ms: u64,
},
Gui,
Telegram {
#[command(subcommand)]
cmd: TelegramCmd,
},
Install {
#[arg(long)]
force: bool,
},
Hook,
Daemon {
#[arg(long, env = "TRUSTY_MPM_ADDR", default_value = DEFAULT_ADDR)]
addr: SocketAddr,
#[arg(long, env = "TRUSTY_MPM_TAILSCALE")]
tailscale: bool,
#[arg(long)]
mcp: bool,
},
Supervisor {
#[arg(long, env = "TRUSTY_MPM_SUPERVISOR_ADDR")]
addr: Option<SocketAddr>,
#[arg(long)]
interval: Option<u64>,
#[arg(long)]
auto_resume: bool,
#[arg(long)]
no_classify: bool,
},
Launch {
dir: Option<String>,
},
Connect {
dir: Option<String>,
},
Attach {
target: String,
#[arg(long)]
json: bool,
},
Optimizer {
#[command(subcommand)]
action: OptimizerAction,
},
Overseer {
#[command(subcommand)]
action: OverseerAction,
},
#[command(alias = "coord")]
Coordinator {
message: String,
},
Services {
#[command(subcommand)]
action: ServicesAction,
},
Repair {
#[command(subcommand)]
action: RepairAction,
},
Catalog {
#[command(subcommand)]
action: CatalogAction,
},
Ticket {
issue: String,
#[arg(default_value = "gh", value_enum)]
system: crate::commands::ticket::system::TicketSystemKind,
#[arg(long = "note", short = 'm')]
notes: Vec<String>,
#[arg(long, default_value = "claude-code", value_enum)]
runtime: trusty_mpm::runtime::RuntimeKind,
},
Issue {
#[command(subcommand)]
cmd: IssueCmd,
#[arg(long, default_value = "gh", value_enum, global = true)]
system: crate::commands::ticket::system::TicketSystemKind,
},
Watch {
#[command(subcommand)]
cmd: WatchCmd,
},
}
#[derive(Debug, Subcommand)]
pub(crate) enum WatchCmd {
Poll {
#[command(flatten)]
args: WatchArgs,
},
Listen {
#[command(flatten)]
args: WatchArgs,
},
}
#[derive(Debug, clap::Args)]
pub(crate) struct WatchArgs {
pub(crate) project: String,
#[arg(long)]
pub(crate) label: Option<String>,
#[arg(
long = "interval-secs",
help = "Poll interval in seconds (listen mode only; ignored by poll)"
)]
pub(crate) interval_secs: Option<u64>,
#[arg(long, value_enum)]
pub(crate) state: Option<crate::commands::watch::github::IssueState>,
#[arg(long)]
pub(crate) dry_run: bool,
#[arg(long)]
pub(crate) execute: bool,
#[arg(long, default_value = "claude-code", value_enum)]
pub(crate) runtime: trusty_mpm::runtime::RuntimeKind,
}
#[derive(Debug, Subcommand)]
pub(crate) enum IssueCmd {
SeedLabels {
#[arg(long)]
config: Option<std::path::PathBuf>,
#[arg(long)]
dry_run: bool,
},
Transition {
issue: u64,
to_state: String,
#[arg(long)]
config: Option<std::path::PathBuf>,
#[arg(long)]
note: Option<String>,
},
Current {
issue: u64,
#[arg(long)]
config: Option<std::path::PathBuf>,
},
States {
#[arg(long)]
config: Option<std::path::PathBuf>,
},
SeedConfig {
#[arg(long)]
force: bool,
},
Repair {
issue: u64,
#[arg(long)]
config: Option<std::path::PathBuf>,
},
}
#[derive(Debug, Subcommand)]
pub(crate) enum CatalogAction {
Sync {
#[arg(long)]
force: bool,
},
Ls {
#[arg(long)]
json: bool,
},
}
#[derive(Debug, Subcommand)]
pub(crate) enum RepairAction {
Deploy {
#[arg(long)]
force: bool,
},
}
#[derive(Debug, Subcommand)]
pub(crate) enum TelegramCmd {
Pair,
Status,
Start {
#[arg(long, env = "TRUSTY_MPM_URL", default_value = DEFAULT_URL)]
url: String,
#[arg(long)]
token: Option<String>,
#[arg(long)]
alert_chat_id: Option<i64>,
#[arg(long)]
allowed_user_id: Option<i64>,
#[arg(long)]
check: bool,
},
Stop,
}
#[derive(Debug, Subcommand)]
pub(crate) enum ProjectAction {
Init {
#[arg(long)]
dir: Option<String>,
},
List,
Info {
#[arg(long)]
dir: Option<String>,
},
}
#[derive(Debug, Subcommand)]
pub(crate) enum SessionAction {
Start {
#[arg(long)]
dir: Option<String>,
},
Stop {
id_or_name: String,
},
List {
#[arg(long)]
dir: Option<String>,
},
Clean {
#[arg(long)]
dir: Option<String>,
},
Info {
id_or_name: String,
},
Instructions {
#[arg(long)]
dir: Option<String>,
},
Events {
id_or_name: String,
},
Breakers,
Pause {
id_or_name: String,
#[arg(long)]
note: Option<String>,
},
Resume {
id_or_name: String,
},
Run {
id_or_name: String,
command: String,
#[arg(long)]
summarize: bool,
},
Output {
id_or_name: String,
#[arg(long, default_value_t = 50)]
lines: u32,
#[arg(long)]
summarize: bool,
},
New {
repo: String,
#[arg(long, default_value = "main")]
git_ref: String,
#[arg(long)]
task: String,
#[arg(long)]
name_hint: Option<String>,
#[arg(long, default_value = "claude-code", value_enum)]
runtime: trusty_mpm::runtime::RuntimeKind,
},
Ls {
#[arg(long)]
json: bool,
},
Activity {
id: String,
},
Send {
id: String,
text: String,
},
Answer {
id: String,
answer: String,
},
Attach {
id: String,
},
#[command(hide = true)]
ManagedStop {
id: String,
},
#[command(hide = true)]
RuntimeStop {
id: String,
},
#[command(hide = true)]
ManagedResume {
id: String,
},
Decommission {
id: String,
},
}
#[derive(Debug, Subcommand)]
pub(crate) enum OverseerAction {
Status,
}
#[derive(Debug, Subcommand)]
pub(crate) enum OptimizerAction {
Status,
Set {
#[arg(value_enum)]
level: CliCompressionLevel,
},
}
#[derive(Debug, Subcommand)]
pub(crate) enum ServicesAction {
List {
#[arg(long)]
json: bool,
},
Status {
name: String,
#[arg(long)]
json: bool,
},
Port {
name: String,
},
Url {
name: String,
},
Health {
name: String,
},
Log {
name: String,
},
Init {
#[arg(long)]
force: bool,
},
Restart {
name: String,
},
}
#[derive(Debug, Clone, Copy, clap::ValueEnum)]
pub(crate) enum CliCompressionLevel {
Off,
Trim,
Summarise,
Caveman,
}