use clap::{Parser, Subcommand}; #[derive(Parser)] #[command(name = "momentry")] #[command(about = "Digital asset management system with video analysis and RAG")] #[command(version = env!("BUILD_VERSION"))] pub struct Cli { #[command(subcommand)] pub command: Commands, } #[derive(Subcommand)] pub enum Commands { /// Register a video file Register { /// Video file path or URL path: String, }, /// Process video (generate all JSON files) Process { /// UUID or path target: String, /// Modules to process (comma separated: asr,cut,asrx,yolo,ocr,face,pose,story,caption) /// If not specified, processes all modules #[arg(short, long, value_delimiter = ',')] modules: Option>, /// Modules to process via cloud (comma separated) /// Example: --cloud asr,yolo #[arg(long, value_delimiter = ',')] cloud: Option>, /// Force reprocess even if JSON exists (skip completeness check) #[arg(long, default_value = "false")] force: bool, /// Resume from last checkpoint if processing was interrupted #[arg(long, default_value = "false")] resume: bool, }, /// Generate chunks and store in database Chunk { /// UUID uuid: String, }, /// Generate story for cut scenes Story { /// UUID uuid: String, }, /// Vectorize chunks Vectorize { /// UUID (or 'all' for all) uuid: String, }, /// Play video with overlays Play { /// Video path or UUID target: String, }, /// Start watching directories Watch { /// Directories to watch (comma separated) directories: Option, }, /// Check system resources and recommend processing strategy System { /// Show detailed GPU info (NVIDIA/MPS) #[arg(long)] gpu: bool, }, /// Start API server Server { /// Host #[arg(long, default_value = "127.0.0.1")] host: String, /// Port (defaults to MOMENTRY_SERVER_PORT env var, or 3002 for production) #[arg(long)] port: Option, }, /// Start job worker Worker { /// Max concurrent processors #[arg(long)] max_concurrent: Option, /// Poll interval in seconds #[arg(long)] poll_interval: Option, /// Batch size #[arg(long)] batch_size: Option, }, /// Query using RAG Query { /// Query text query: String, }, /// Lookup UUID from path Lookup { /// File path path: String, }, /// Resolve path from UUID Resolve { /// UUID uuid: String, }, /// Generate thumbnails for videos Thumbnails { /// UUID (optional, generates for all if not specified) uuid: Option, /// Number of thumbnails per video #[arg(short, long, default_value = "6")] count: u32, }, /// Show storage status report Status { /// UUID (optional, shows all if not specified) uuid: Option, }, /// Manage output backups Backup { /// Action: list, cleanup action: String, /// Days to keep (for cleanup) days: Option, }, /// Manage API keys ApiKey { /// Action: create, list, validate, revoke, rotate, stats #[arg(value_enum)] action: ApiKeyAction, /// Key name (for create) name: Option, /// Key type (system, user, service, integration, emergency) #[arg(long)] key_type: Option, /// TTL in days (for create) #[arg(long)] ttl: Option, /// API key to validate/revoke #[arg(long)] key: Option, }, /// Manage Gitea API tokens Gitea { /// Action: create, list, delete, verify #[arg(value_enum)] action: GiteaAction, /// Gitea username #[arg(long)] username: Option, /// Gitea password (for create/list/delete) #[arg(long)] password: Option, /// Token name (for create/delete) #[arg(long)] token_name: Option, /// Token scopes (comma separated: read:repository,write:issue) #[arg(long)] scopes: Option, }, /// Manage n8n API keys N8n { /// Action: create, list, delete, verify #[arg(value_enum)] action: N8nAction, /// n8n API key (for create/list/delete) #[arg(long)] api_key: Option, /// API key label (for create/delete) #[arg(long)] label: Option, /// Expiration days (for create) #[arg(long)] expires_in_days: Option, }, } #[derive(clap::ValueEnum, Clone, Debug)] pub enum ApiKeyAction { Create, List, Validate, Revoke, Rotate, Stats, } #[derive(clap::ValueEnum, Clone, Debug)] pub enum GiteaAction { Create, List, Delete, Verify, } #[derive(clap::ValueEnum, Clone, Debug)] pub enum N8nAction { Create, List, Delete, Verify, } /// Parse key type from string pub fn parse_key_type(s: Option<&str>) -> momentry_core::core::api_key::ApiKeyType { use momentry_core::core::api_key::ApiKeyType; match s.map(|s| s.to_lowercase()).as_deref() { Some("system") => ApiKeyType::System, Some("user") => ApiKeyType::User, Some("service") => ApiKeyType::Service, Some("integration") => ApiKeyType::Integration, Some("emergency") => ApiKeyType::Emergency, _ => ApiKeyType::User, } }