use clap::{Parser, Subcommand};
use std::path::PathBuf;
#[derive(Parser)]
#[command(name = "ssh-channels-hub")]
#[command(version)]
#[command(
about = "Manage SSH port-forwarding tunnels with auto-reconnect",
long_about = None,
)]
#[command(propagate_version = true)]
#[command(arg_required_else_help = true)]
pub struct Cli {
#[command(subcommand)]
pub command: Commands,
#[arg(short, long, global = true, value_name = "FILE")]
pub config: Option<PathBuf>,
#[arg(short, long, global = true)]
pub debug: bool,
#[arg(long, global = true)]
pub no_color: bool,
}
#[derive(Subcommand)]
pub enum Commands {
#[command(long_about = "\
Bring up every channel defined in config.toml.
By default runs in the foreground until Ctrl+C; pass -D to detach.
While running, `status` / `stop` / `restart` connect over a local
IPC socket recorded next to config.toml.")]
Start {
#[arg(short = 'D', long)]
daemon: bool,
},
Stop,
Restart,
#[command(long_about = "\
Connects to the running daemon over IPC to report live state.
When no daemon is running, falls back to printing the channels
declared in config.toml so you can still see the intended setup.")]
Status,
#[command(long_about = "\
Parses config.toml and resolves every `[[channels]]` entry against
~/.ssh/config. Catches missing host aliases, missing HostName/User,
unparseable ports, and hosts that need a password but have no
[auth.<alias>] block.")]
Validate {
config: Option<PathBuf>,
},
#[command(long_about = "\
Reads ~/.ssh/config and writes a config.toml with one commented-out
`[[channels]]` template per Host alias, plus stub [auth.<alias>]
blocks for hosts that have no IdentityFile.")]
Generate {
#[arg(short, long, value_name = "FILE")]
ssh_config: Option<PathBuf>,
#[arg(short, long, value_name = "FILE")]
output: Option<PathBuf>,
},
#[command(long_about = "\
For every `local->remote` channel, try a TCP connect to the local
listen address and verify the tunnel is alive. `remote->local`
channels are skipped — those can only be verified from the SSH
server side.")]
Test {
#[arg(short, long, value_name = "FILE")]
config: Option<PathBuf>,
},
}