use anyhow::Result;
use clap::Parser;
use sashiko::local_review::{WorkerOptions, print_worker_json, run_worker_from_stdin};
use sashiko::prompt_bundle;
use std::io::IsTerminal;
use std::path::PathBuf;
#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
struct Args {
#[arg(long)]
json: bool,
#[arg(long)]
baseline: Option<String>,
#[arg(long)]
repo: Option<PathBuf>,
#[arg(long)]
worktree_dir: Option<PathBuf>,
#[arg(long)]
prompts: Option<PathBuf>,
#[arg(long)]
review_patch_index: Option<i64>,
#[arg(long)]
review_commit: Option<String>,
#[arg(long)]
no_ai: bool,
#[arg(long)]
reuse_worktree: Option<PathBuf>,
#[arg(long)]
ai_provider: Option<String>,
#[arg(long)]
custom_prompt: Option<String>,
#[arg(long, hide = true, value_delimiter = ',')]
stages: Option<Vec<u8>>,
}
#[tokio::main]
async fn main() -> Result<()> {
std::panic::set_hook(Box::new(|info| {
eprintln!("CRITICAL ERROR: Panic detected: {}", info);
}));
init_logging();
let args = Args::parse();
let result = run_worker_from_stdin(WorkerOptions {
settings_path: None,
baseline: args.baseline,
repo: args.repo,
worktree_dir: args.worktree_dir,
prompts: args
.prompts
.unwrap_or(prompt_bundle::default_kernel_prompts_path()?),
review_patch_index: args.review_patch_index,
review_commit: args.review_commit,
no_ai: args.no_ai,
reuse_worktree: args.reuse_worktree,
ai_provider: args.ai_provider,
custom_prompt: args.custom_prompt,
stages: args.stages,
scratch_clone: false,
current_tree: false,
})
.await?;
print_worker_json(&result)
}
fn init_logging() {
let no_color = std::env::var("NO_COLOR").is_ok();
let plain_logs = std::env::var("SASHIKO_LOG_PLAIN").is_ok();
let use_ansi = !no_color && std::io::stderr().is_terminal();
let builder = tracing_subscriber::fmt()
.with_writer(sashiko::logging::IgnoreBrokenPipe(std::io::stderr))
.with_ansi(use_ansi);
if plain_logs {
builder
.with_level(false)
.with_target(false)
.without_time()
.init();
} else {
builder.init();
}
}