Skip to content

Feature Request: Add list-vaults command to discover registered Obsidian vaults #97

@petems

Description

@petems

Is your feature request related to a problem? Please describe.

I was trying to use notesmd-cli and needed to pass a vault name to set-default, but I had no idea what my vaults were actually called. I assumed there'd be some kind of listing command, but there isn't one - the only way to find out is to manually track down obsidian.json and parse it yourself.

As someone who is inherently lazy, that felt like exactly the kind of thing a CLI should do for me...

Describe the solution you'd like

A new list-vaults command (alias lv) that reads the Obsidian config and prints all registered vaults with their names and paths.

Default output - tab-separated, sorted alphabetically:

$ notesmd-cli list-vaults
Personal    /Users/me/Documents/Personal
PromptsAndSnippets    /Users/me/Documents/PromptsAndSnippets
Work    /Users/me/Documents/Work

JSON output for scripting:

$ notesmd-cli list-vaults --json
[
  {"name": "Personal", "path": "/Users/me/Documents/Personal"},
  {"name": "PromptsAndSnippets", "path": "/Users/me/Documents/PromptsAndSnippets"},
  {"name": "Work", "path": "/Users/me/Documents/Work"}
]

Paths only:

$ notesmd-cli list-vaults --path-only
/Users/me/Documents/Personal
/Users/me/Documents/PromptsAndSnippets
/Users/me/Documents/Work

Then you can actually use set-default without guessing:

$ notesmd-cli set-default Work

Describe alternatives you've considered

  • Manually finding and parsing obsidian.json - works, but defeats the purpose of having a CLI and misses out on some scripting and automation we can do from being able to list current Vaults
  • Adding vault listing to print-default - Considered, but print-default is specifically about the current default vault; listing all vaults is a different concern
  • A --verbose flag on set-default that shows available vaults on error - would help, but only at the point of failure rather than proactively

Additional context

I've gone ahead and implemented an MVP in a spike branch, some notes on the current approach:

  • Reuses all existing building blocks (ObsidianConfigFile(), ObsidianVaultConfig, WSL path adjustment) so no reinventing the wheel
  • Vault names are derived from filepath.Base(path), which matches what Obsidian displays
  • Three new files, no modifications to existing functionality (other than one small improvement, see below)
  • 7 test cases covering: multiple vaults, empty config, error propagation, invalid JSON, WSL paths, and single vault
  • Follows existing patterns from print-default command and vault_path_test.go

Bonus: Numbered Snap directory support

While looking at the config discovery logic against the Obsidian docs on data storage, I noticed the code checks ~/snap/obsidian/current/ but not numbered subdirectories like ~/snap/obsidian/x1/ which can exist when multiple snap versions are installed or the current symlink is missing.

Added a glob-based fallback for this - benefits all commands, not just list-vaults. But happy to remove if not needed!

AI Disclosure

This Github Issue and initial work on MVP implementation was developed with assistance from Claude Code in Opus 4.6 mode:

  1. Planning - Claude Code was used to explore the codebase, understand existing patterns, and draft the feature plan
  2. Implementation - Claude Code wrote the initial code following the agreed plan
  3. Multi-model review - A Mixture-of-Models approach using ChatGPT 5.2, Gemini 3.1, and Opus 4.6 will be used to review the code and reach consensus on any improvements (Using the very neat PAL MCP)
  4. Manual review - All code will be manually reviewed by myself, a humble human 👨‍💻
    My focus was on using AI for the legwork - codebase exploration, boilerplate, test scaffolding - but keeping HumanOps for the parts that matter: Writing this issue description, making sure the feature is actually wanted, and implementing it in a way that keeps the bar low for the maintainer to accept.

The goal was to make reviewing and merging this as painless as possible, not to throw AI-generated code over the fence and hope for the best.

I hope I will achieve that when I open the PR 🫡

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions