use clap::{Parser, Subcommand};
use std::path::PathBuf;
const LONG_ABOUT: &str = "\
Obsidian CLI Inspector - A local-first, read-only CLI/TUI for Obsidian vaults
ABOUT:
This tool helps you inspect, query, and navigate your Obsidian vault from the terminal.
All data is stored locally in a SQLite database for fast, offline access.
USE CASES:
• Search: Find notes quickly with full-text search across your entire vault
• Link Analysis: Discover backlinks, forward links, and unresolved references
• Tag Management: Filter and organize notes by tags with AND/OR logic
• Graph Exploration: Visualize note relationships and connection depths
• Content Quality: Identify bloated notes that may need refactoring
• Related Notes: Get AI-style suggestions for notes you might want to link
• Scripting: Integrate with shell scripts and automation workflows
• Interactive TUI: Browse your vault in a terminal user interface
WORKFLOW:
1. Run 'init' to set up the database
2. Run 'index' to scan and parse your vault
3. Use query commands (search, backlinks, tags, etc.)
4. Re-run 'index' periodically to catch changes
EXAMPLES:
# Initialize and index your vault
obsidian-cli-inspector init
obsidian-cli-inspector index
# Search for notes containing 'rust'
obsidian-cli-inspector search rust --limit 10
# Find all notes linking to 'Project Ideas'
obsidian-cli-inspector backlinks \"Project Ideas\"
# List all notes tagged with 'work'
obsidian-cli-inspector tags work
# Find large notes that might need splitting
obsidian-cli-inspector bloat --threshold 100000
# Launch interactive mode
obsidian-cli-inspector tui
CONFIG:
Place config at ~/.config/obsidian-cli-inspector/config.toml
Specify vault path and database location there.
";
#[derive(Parser)]
#[command(name = "obsidian-cli-inspector")]
#[command(author, version)]
#[command(about = "Local-first CLI/TUI for indexing and querying Obsidian vaults")]
#[command(long_about = LONG_ABOUT)]
pub struct Cli {
#[arg(short, long, value_name = "FILE")]
pub config: Option<PathBuf>,
#[command(subcommand)]
pub command: Commands,
}
#[derive(Subcommand)]
pub enum Commands {
Init {
#[arg(short, long)]
force: bool,
},
Index {
#[arg(short = 'n', long)]
dry_run: bool,
#[arg(short, long)]
force: bool,
#[arg(short, long)]
verbose: bool,
},
Search {
query: String,
#[arg(short, long, default_value = "20")]
limit: usize,
},
Backlinks {
note: String,
},
Links {
note: String,
},
UnresolvedLinks,
Tags {
tag: Option<String>,
#[arg(short, long)]
all: bool,
},
Suggest {
note: String,
#[arg(short, long, default_value = "10")]
limit: usize,
},
Bloat {
#[arg(short, long, default_value = "50000")]
threshold: usize,
#[arg(short, long, default_value = "10")]
limit: usize,
},
Stats,
Tui,
Graph {
note: Option<String>,
#[arg(short, long, default_value = "2")]
depth: usize,
},
Describe {
filename: String,
},
DiagnoseOrphans {
#[arg(long)]
exclude_templates: bool,
#[arg(long)]
exclude_daily: bool,
},
DiagnoseBrokenLinks,
}