use agentic_navigation_guide::dumper::Dumper;
use agentic_navigation_guide::errors::{AppError, Result};
use agentic_navigation_guide::types::Config;
use clap::Args;
use std::path::PathBuf;
const DEFAULT_VCS_EXCLUDES: &[&str] = &[".git", ".svn", ".hg", ".bzr", "CVS", "_darcs"];
#[derive(Args, Debug)]
pub struct InitArgs {
#[arg(short, long)]
pub output: PathBuf,
#[arg(short, long)]
pub depth: Option<usize>,
#[arg(short, long)]
pub exclude: Vec<String>,
#[arg(short, long, default_value = "2")]
pub indent: usize,
#[arg(short, long, env = "AGENTIC_NAVIGATION_GUIDE_ROOT")]
pub root: Option<PathBuf>,
#[arg(long)]
pub include_vcs_directories: bool,
}
impl InitArgs {
pub fn execute(self, _config: &Config) -> Result<()> {
if self.output.exists() {
return Err(AppError::Other(format!(
"File already exists: {}. Use --force to overwrite.",
self.output.display()
)));
}
let root_path = self
.root
.unwrap_or_else(|| std::env::current_dir().expect("Failed to get current directory"));
log::info!("Initializing navigation guide for: {}", root_path.display());
let mut exclude_patterns = Vec::new();
if !self.include_vcs_directories {
exclude_patterns.extend(DEFAULT_VCS_EXCLUDES.iter().map(|s| s.to_string()));
}
exclude_patterns.extend(self.exclude);
let dumper = Dumper::new(&root_path)
.with_max_depth(self.depth)
.with_exclude_patterns(&exclude_patterns)?
.with_indent_size(self.indent);
let output = dumper.dump_with_wrapper()?;
let full_output = format!(
r#"# Agentic Navigation Guide
This navigation guide helps AI coding assistants understand the structure of this project.
The listing below may be incomplete and highlights key files and directories.
{output}
Note: This guide was automatically generated and may need manual adjustments.
"#
);
log::info!("Writing navigation guide to: {}", self.output.display());
std::fs::write(&self.output, full_output)?;
println!("Navigation guide created at: {}", self.output.display());
Ok(())
}
}