oc-session 0.1.0

Global OpenCode session browser and resume tool
use clap::{Args, Parser, Subcommand};
use std::path::PathBuf;

#[derive(Parser)]
#[command(name = "oc-session")]
#[command(about = "Global OpenCode session browser and resume tool")]
#[command(version)]
#[command(
    after_help = "Examples:\n  oc-session\n  oc-session --search project\n  oc-session search \"session recovery\"\n  oc-session recent --limit 20\n  oc-session print ses_abc123\n  oc-session copy ses_abc123\n  oc-session doctor"
)]
pub struct Cli {
    #[command(subcommand)]
    pub command: Option<Command>,

    #[arg(short, long, global = true, help = "Path to config.toml")]
    pub config: Option<PathBuf>,

    #[arg(
        short,
        long,
        value_name = "QUERY",
        help = "Open the picker filtered by keywords"
    )]
    pub search: Option<String>,

    #[arg(long, global = true, help = "Include OpenCode child/subagent sessions")]
    pub include_children: bool,
}

#[derive(Subcommand)]
pub enum Command {
    #[command(about = "Search sessions and open the picker")]
    Search(SearchArgs),
    #[command(about = "Print recent sessions")]
    Recent(RecentArgs),
    #[command(about = "Resume or print the latest session")]
    Last(LastArgs),
    #[command(about = "Resume a session by id")]
    Resume(ResumeArgs),
    #[command(about = "Print the resume command for a session")]
    Print(PrintArgs),
    #[command(about = "Copy the resume command for a session")]
    Copy(CopyArgs),
    #[command(about = "Scan the home directory for OpenCode databases")]
    Scan(ScanArgs),
    #[command(about = "Show discovery and database diagnostics")]
    Doctor,
    #[command(about = "Manage the bundled OpenCode agent skill")]
    Skill(SkillArgs),
}

#[derive(Args)]
pub struct SkillArgs {
    #[command(subcommand)]
    pub command: SkillCommand,
}

#[derive(Subcommand)]
pub enum SkillCommand {
    #[command(about = "Install the bundled skill into OpenCode")]
    Install(SkillInstallArgs),
    #[command(about = "Print the bundled skill contents")]
    Print,
    #[command(about = "Print the OpenCode skill install path")]
    Path,
}

#[derive(Args)]
pub struct SkillInstallArgs {
    #[arg(long, help = "Overwrite an existing installed skill")]
    pub force: bool,
}

#[derive(Args)]
pub struct SearchArgs {
    #[arg(help = "Keywords to search for")]
    pub query: Vec<String>,

    #[arg(short, long, default_value_t = 100, help = "Maximum sessions to show")]
    pub limit: usize,

    #[arg(long, help = "Print results instead of opening the picker")]
    pub no_tui: bool,
}

#[derive(Args)]
pub struct RecentArgs {
    #[arg(
        short,
        long,
        default_value_t = 50,
        value_name = "N",
        help = "Maximum sessions to print"
    )]
    pub limit: usize,

    #[arg(long, help = "Output machine-readable JSON")]
    pub json: bool,
}

#[derive(Args)]
pub struct LastArgs {
    #[arg(long, help = "Print the resume command instead of running it")]
    pub print: bool,
}

#[derive(Args)]
pub struct ResumeArgs {
    #[arg(value_name = "SESSION_ID", help = "OpenCode session id")]
    pub id: String,
}

#[derive(Args)]
pub struct PrintArgs {
    #[arg(value_name = "SESSION_ID", help = "OpenCode session id")]
    pub id: String,
}

#[derive(Args)]
pub struct CopyArgs {
    #[arg(value_name = "SESSION_ID", help = "OpenCode session id")]
    pub id: String,
}

#[derive(Args)]
pub struct ScanArgs {
    #[arg(
        long,
        value_name = "PATH",
        help = "Additional directory or database path to scan"
    )]
    pub include: Vec<PathBuf>,
}