mod cli;
mod session;
use clap::{Parser, Subcommand};
use session::Ctx;
use tail_fin_common::TailFinError;
#[derive(Parser)]
#[command(name = "tail-fin", about = "Multi-site browser automation CLI")]
struct Cli {
#[command(subcommand)]
command: Commands,
#[arg(long, global = true, value_name = "HOST:PORT")]
connect: Option<String>,
#[arg(long, global = true, value_name = "PATH", num_args = 0..=1, default_missing_value = "auto", require_equals = true)]
cookies: Option<String>,
#[arg(long, global = true, default_value_t = false)]
headed: bool,
}
#[derive(Subcommand)]
enum Commands {
Twitter {
#[command(subcommand)]
action: cli::twitter::TwitterAction,
},
Grok {
#[command(subcommand)]
action: cli::grok::GrokAction,
},
Xhs {
#[command(subcommand)]
action: cli::xhs::XhsAction,
},
Instagram {
#[command(subcommand)]
action: cli::instagram::InstagramAction,
},
Youtube {
#[command(subcommand)]
action: cli::youtube::YoutubeAction,
},
#[command(name = "591")]
Rent591 {
#[command(subcommand)]
action: cli::s591::Rent591Action,
},
Sa {
#[command(subcommand)]
action: cli::sa::SeekingAlphaAction,
},
Gen {
#[command(subcommand)]
action: cli::gen::GenAction,
},
Run {
site: String,
command: String,
#[arg(trailing_var_arg = true)]
args: Vec<String>,
},
}
#[tokio::main]
async fn main() -> Result<(), TailFinError> {
let cli = Cli::parse();
if cli.connect.is_some() && cli.cookies.is_some() {
eprintln!("Error: --connect and --cookies cannot be used together.");
eprintln!(" Use --connect for browser mode, or --cookies for cookie mode.");
std::process::exit(1);
}
let ctx = Ctx {
connect: cli.connect,
cookies: cli.cookies,
headed: cli.headed,
};
match cli.command {
Commands::Twitter { action } => cli::twitter::run(action, &ctx).await?,
Commands::Grok { action } => cli::grok::run(action, &ctx).await?,
Commands::Xhs { action } => cli::xhs::run(action, &ctx).await?,
Commands::Instagram { action } => cli::instagram::run(action, &ctx).await?,
Commands::Youtube { action } => cli::youtube::run(action, &ctx).await?,
Commands::Rent591 { action } => cli::s591::run(action, &ctx).await?,
Commands::Sa { action } => cli::sa::run(action, &ctx).await?,
Commands::Gen { action } => cli::gen::run(action, &ctx).await?,
Commands::Run { site, command, args } => {
cli::gen::run_dynamic(site, command, args, &ctx).await?
}
}
Ok(())
}