obsidian_cli_inspector/
cli.rs1use clap::{Parser, Subcommand};
2use std::path::PathBuf;
3
4const LONG_ABOUT: &str = "\
5Obsidian CLI Inspector - A local-first, read-only CLI/TUI for Obsidian vaults
6
7ABOUT:
8 This tool helps you inspect, query, and navigate your Obsidian vault from the terminal.
9 All data is stored locally in a SQLite database for fast, offline access.
10
11USE CASES:
12 • Search: Find notes quickly with full-text search across your entire vault
13 • Link Analysis: Discover backlinks, forward links, and unresolved references
14 • Tag Management: Filter and organize notes by tags with AND/OR logic
15 • Graph Exploration: Visualize note relationships and connection depths
16 • Content Quality: Identify bloated notes that may need refactoring
17 • Related Notes: Get AI-style suggestions for notes you might want to link
18 • Scripting: Integrate with shell scripts and automation workflows
19 • Interactive TUI: Browse your vault in a terminal user interface
20
21WORKFLOW:
22 1. Run 'init' to set up the database
23 2. Run 'index' to scan and parse your vault
24 3. Use query commands (search, backlinks, tags, etc.)
25 4. Re-run 'index' periodically to catch changes
26
27EXAMPLES:
28 # Initialize and index your vault
29 obsidian-cli-inspector init
30 obsidian-cli-inspector index
31
32 # Search for notes containing 'rust'
33 obsidian-cli-inspector search rust --limit 10
34
35 # Find all notes linking to 'Project Ideas'
36 obsidian-cli-inspector backlinks \"Project Ideas\"
37
38 # List all notes tagged with 'work'
39 obsidian-cli-inspector tags work
40
41 # Find large notes that might need splitting
42 obsidian-cli-inspector bloat --threshold 100000
43
44 # Launch interactive mode
45 obsidian-cli-inspector tui
46
47CONFIG:
48 Place config at ~/.config/obsidian-cli-inspector/config.toml
49 Specify vault path and database location there.
50";
51
52#[derive(Parser)]
53#[command(name = "obsidian-cli-inspector")]
54#[command(author, version)]
55#[command(about = "Local-first CLI/TUI for indexing and querying Obsidian vaults")]
56#[command(long_about = LONG_ABOUT)]
57pub struct Cli {
58 #[arg(short, long, value_name = "FILE")]
60 pub config: Option<PathBuf>,
61
62 #[command(subcommand)]
63 pub command: Commands,
64}
65
66#[derive(Subcommand)]
67pub enum Commands {
68 Init {
70 #[arg(short, long)]
72 force: bool,
73 },
74
75 Index {
77 #[arg(short = 'n', long)]
79 dry_run: bool,
80
81 #[arg(short, long)]
83 force: bool,
84
85 #[arg(short, long)]
87 verbose: bool,
88 },
89
90 Search {
92 query: String,
94
95 #[arg(short, long, default_value = "20")]
97 limit: usize,
98 },
99
100 Backlinks {
102 note: String,
104 },
105
106 Links {
108 note: String,
110 },
111
112 UnresolvedLinks,
114
115 Tags {
117 tag: Option<String>,
119
120 #[arg(short, long)]
122 all: bool,
123 },
124
125 Suggest {
127 note: String,
129
130 #[arg(short, long, default_value = "10")]
132 limit: usize,
133 },
134
135 Bloat {
137 #[arg(short, long, default_value = "50000")]
139 threshold: usize,
140
141 #[arg(short, long, default_value = "10")]
143 limit: usize,
144 },
145
146 Stats,
148
149 Tui,
151
152 Graph {
154 note: Option<String>,
156
157 #[arg(short, long, default_value = "2")]
159 depth: usize,
160 },
161
162 Describe {
164 filename: String,
166 },
167
168 DiagnoseOrphans {
170 #[arg(long)]
172 exclude_templates: bool,
173
174 #[arg(long)]
176 exclude_daily: bool,
177 },
178
179 DiagnoseBrokenLinks,
181}