use std::net::IpAddr;
use std::path::PathBuf;
use clap::{Parser, Subcommand, ValueEnum};
use frigg::settings::{LexicalBackendMode, SemanticRuntimeProvider, WatchMode};
use frigg::storage::{DEFAULT_RETAINED_MANIFEST_SNAPSHOTS, DEFAULT_RETAINED_PROVENANCE_EVENTS};
#[derive(Debug, Parser)]
#[command(name = "frigg", version, about = "Frigg MCP server")]
pub(crate) struct Cli {
#[arg(long, global = true)]
pub(crate) quiet: bool,
#[arg(long = "workspace-root", value_name = "PATH", global = true)]
pub(crate) workspace_roots: Vec<PathBuf>,
#[arg(
long = "max-file-bytes",
value_name = "BYTES",
env = "FRIGG_MAX_FILE_BYTES",
global = true
)]
pub(crate) max_file_bytes: Option<usize>,
#[arg(
long,
env = "FRIGG_FULL_SCIP_INGEST",
global = true,
default_value_t = true
)]
pub(crate) full_scip_ingest: bool,
#[arg(long, value_name = "PORT", global = true)]
pub(crate) mcp_http_port: Option<u16>,
#[arg(long, value_name = "HOST", global = true)]
pub(crate) mcp_http_host: Option<IpAddr>,
#[arg(long, global = true)]
pub(crate) allow_remote_http: bool,
#[arg(
long,
value_name = "TOKEN",
env = "FRIGG_MCP_HTTP_AUTH_TOKEN",
hide_env_values = true,
global = true
)]
pub(crate) mcp_http_auth_token: Option<String>,
#[arg(
long,
value_name = "BOOL",
env = "FRIGG_SEMANTIC_RUNTIME_ENABLED",
global = true
)]
pub(crate) semantic_runtime_enabled: Option<bool>,
#[arg(
long,
value_name = "PROVIDER",
env = "FRIGG_SEMANTIC_RUNTIME_PROVIDER",
global = true
)]
pub(crate) semantic_runtime_provider: Option<SemanticRuntimeProvider>,
#[arg(
long,
value_name = "MODEL",
env = "FRIGG_SEMANTIC_RUNTIME_MODEL",
global = true
)]
pub(crate) semantic_runtime_model: Option<String>,
#[arg(
long,
value_name = "BOOL",
env = "FRIGG_SEMANTIC_RUNTIME_STRICT_MODE",
global = true
)]
pub(crate) semantic_runtime_strict_mode: Option<bool>,
#[arg(long, value_name = "MODE", env = "FRIGG_WATCH_MODE", global = true)]
pub(crate) watch_mode: Option<WatchMode>,
#[arg(
long,
value_name = "MODE",
env = "FRIGG_LEXICAL_BACKEND",
global = true
)]
pub(crate) lexical_backend: Option<LexicalBackendMode>,
#[arg(
long,
value_name = "PATH",
env = "FRIGG_RIPGREP_EXECUTABLE",
global = true
)]
pub(crate) ripgrep_executable: Option<PathBuf>,
#[arg(
long,
value_name = "MILLISECONDS",
env = "FRIGG_WATCH_DEBOUNCE_MS",
global = true
)]
pub(crate) watch_debounce_ms: Option<u64>,
#[arg(
long,
value_name = "MILLISECONDS",
env = "FRIGG_WATCH_RETRY_MS",
global = true
)]
pub(crate) watch_retry_ms: Option<u64>,
#[command(subcommand)]
pub(crate) command: Option<Command>,
}
#[derive(Debug, Clone, Subcommand)]
pub(crate) enum Command {
Serve,
Init,
Verify,
Reindex {
#[arg(long, default_value_t = false)]
changed: bool,
},
RepairStorage,
PruneStorage {
#[arg(
long = "keep-manifest-snapshots",
default_value_t = DEFAULT_RETAINED_MANIFEST_SNAPSHOTS
)]
keep_manifest_snapshots: usize,
#[arg(
long = "keep-provenance-events",
default_value_t = DEFAULT_RETAINED_PROVENANCE_EVENTS
)]
keep_provenance_events: usize,
},
PlaybookHybridRun {
#[arg(long = "playbooks-root", value_name = "PATH")]
playbooks_root: PathBuf,
#[arg(long, default_value_t = false)]
enforce_targets: bool,
#[arg(long, value_name = "PATH")]
output: Option<PathBuf>,
#[arg(long = "trace-root", value_name = "PATH")]
trace_root: Option<PathBuf>,
},
ExportWorkloadCorpus {
#[arg(long, value_name = "PATH")]
output: PathBuf,
#[arg(long, value_enum, default_value_t = WorkloadCorpusExportFormat::Jsonl)]
format: WorkloadCorpusExportFormat,
#[arg(
long,
value_name = "COUNT",
default_value_t = DEFAULT_RETAINED_PROVENANCE_EVENTS
)]
limit: usize,
},
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, ValueEnum)]
pub(crate) enum WorkloadCorpusExportFormat {
Json,
Jsonl,
}
impl WorkloadCorpusExportFormat {
pub(crate) fn as_str(self) -> &'static str {
match self {
Self::Json => "json",
Self::Jsonl => "jsonl",
}
}
}