Skip to content

feat: global config with named vaults and default vault #5

Description

@aliou

Note

This plan was written by synthetic/hf:zai-org/GLM-5.1:low.

obsdx Global Config: Design Options

Current State

Vault resolution priority: OBSDX_VAULT env -> --vault flag -> cwd walk-up to .obsidian/. Cache lives at <vault>/.obsidian/obsdx/. No global config file exists.

XDG Paths (the defaults we'd respect)

Purpose Env var Default
Config XDG_CONFIG_HOME ~/.config
Cache XDG_CACHE_HOME ~/.cache
Data XDG_DATA_HOME ~/.local/share
State XDG_STATE_HOME ~/.local/state

Override env var: OBSDX_CONFIG_DIR (parallels GH_CONFIG_DIR, DOCKER_CONFIG).


Option A: Docker Context Model (Named Vaults + Active Vault)

Concept: Like docker context. Vaults are named entries in a config file. One is "active" (default). Switching is a sticky operation that updates the config file.

Config file: $XDG_CONFIG_HOME/obsdx/config.toml

[defaults]
vault = "personal"

[vaults.personal]
path = "/home/user/obsidian/personal"

[vaults.work]
path = "/home/user/obsidian/work"
cache_dir = "/home/user/.cache/obsdx/work"  # optional override

Command surface:

obsdx vault add <name> --path <dir>     # register a vault
obsdx vault remove <name>               # unregister
obsdx vault list                        # list named vaults
obsdx vault use <name>                  # set active default
obsdx vault show                        # print active vault name
obsdx config path                       # show config file location
obsdx config edit                        # open config in $EDITOR

Vault resolution (highest to lowest priority):

  1. --vault <path> (raw path, bypasses named vaults)
  2. --vault <name> (named vault from config) — new: overload --vault to accept names OR paths
  3. OBSDX_VAULT env var (name or path)
  4. Cwd walk-up (discover from current directory)
  5. [defaults].vault from config (the "active" vault)

Cache location: Each vault entry can optionally specify cache_dir. Default: $XDG_CACHE_HOME/obsdx/<name>/ if named, or <vault>/.obsidian/obsdx/ if discovered (backward compat).

Pros:

  • Familiar pattern (docker context users will feel at home)
  • Sticky default means zero-arg usage is smooth after one vault use
  • --vault <name> is shorter than --vault /long/path/to/vault
  • Clean separation: config is about naming, cache location is per-vault

Cons:

  • --vault overload (name vs path) adds ambiguity — must detect which
  • Sticky vault use changes state globally (all shells affected), which can surprise
  • More concepts for a single-vault user to learn

Option B: Git-Style (Cwd Discovery + Named Shortcuts)

Concept: Like git / gh. The cwd is the primary vault selector. Named vaults exist only as shortcuts to avoid typing long paths. No "active" vault — you're always in a vault (via cwd) or explicitly targeting one.

Config file: $XDG_CONFIG_HOME/obsdx/config.toml

[vaults.personal]
path = "/home/user/obsidian/personal"

[vaults.work]
path = "/home/user/obsidian/work"

No [defaults] section. No vault use.

Command surface:

obsdx vault list                         # list named vaults + paths
obsdx vault add <name> --path <dir>      # register a vault
obsdx vault remove <name>                # unregister
obsdx config path                        # show config file location
obsdx config edit                        # open config in $EDITOR

Vault resolution:

  1. --vault <path-or-name> (if name, resolve from config; if path, use directly)
  2. OBSDX_VAULT env var (name or path)
  3. Cwd walk-up (current behavior, unchanged)
  4. No fallback to config — if you're not in a vault and don't specify one, error

Cache location: Always <vault>/.obsidian/obsdx/ (current behavior). No centralization.

Pros:

  • Simplest mental model. Cwd is king. Named vaults are just bookmarks.
  • No hidden global state. No "which vault am I in?" confusion across shells.
  • Fully backward compatible. No config file = current behavior.
  • Least code to implement.

Cons:

  • Must always cd into the vault or type --vault work — no "just run obsdx from anywhere"
  • Doesn't solve the "I have one vault and want it to just work from ~" case
  • Cache stays inside vault directory (some users may want it centralized)

Option C: Hybrid — Named Vaults + Cwd Discovery + Default Vault

Concept: Combines A and B. Named vaults are shortcuts. A default vault exists for when cwd discovery fails. But cwd discovery is still first-class — if you're inside a vault, that vault wins.

Config file: $XDG_CONFIG_HOME/obsdx/config.toml

default_vault = "personal"

[vaults.personal]
path = "/home/user/obsidian/personal"
# cache_dir defaults to $XDG_CACHE_HOME/obsdx/personal/

[vaults.work]
path = "/home/user/obsidian/work"
cache_dir = "/home/user/.cache/obsdx/work"

Command surface:

obsdx config path                        # show config file path
obsdx config edit                        # open in $EDITOR
obsdx config show                        # print resolved config
obsdx vault list                         # list named vaults
obsdx vault add <name> --path <dir>      # register
obsdx vault remove <name>               # unregister
obsdx vault default [name]               # get/set default vault (no --name = print current)

vault default <name> updates the default_vault key. Unlike docker context use, this is explicitly called "default" — not "use" — to signal it's a fallback, not the primary selection mechanism.

Vault resolution (highest to lowest):

  1. --vault <path-or-name> flag
  2. OBSDX_VAULT env var (path or name)
  3. Cwd walk-up (if inside a vault, use it — this is the happy path)
  4. default_vault from config (fallback when not in a vault)
  5. Error

Cache location strategy:

  • Named vault: $XDG_CACHE_HOME/obsdx/<name>/ by default (configurable per-vault)
  • Discovered-only vault (no config entry): <vault>/.obsidian/obsdx/ (backward compat)
  • Migration: on vault add, optionally move existing .obsidian/obsdx/ to the new location

Pros:

  • Cwd discovery is first-class (you don't lose the current workflow)
  • Default vault solves the "run from anywhere" case
  • Named vaults are shortcuts + allow centralized cache
  • No --vault overload for name-vs-path needed — could add --vault-name or just detect intelligently
  • Works for both 1-vault and 5-vault users
  • Backward compatible: no config file = current behavior

Cons:

  • More surface area than B, though less stateful than A
  • Cache migration on vault add is a one-time complexity
  • Two cache locations (named vs discovered) could confuse debugging

Option D: Minimal Config (Just Default Vault Path)

Concept: No named vaults at all. Just a single default_vault path in a tiny config file. For anything else, use --vault or OBSDX_VAULT or cwd.

Config file: $XDG_CONFIG_HOME/obsdx/config.toml

default_vault = "/home/user/obsidian/personal"
cache_dir = "/home/user/.cache/obsdx"    # optional, centralize all caches

Command surface:

obsdx config path
obsdx config show
obsdx config set default_vault <path>
obsdx config set cache_dir <path>

Pros:

  • Dead simple. 2 config keys.
  • Solves the main problem (default vault for single-vault users)
  • Minimal code change

Cons:

  • No named shortcuts. --vault /long/path every time for non-default vaults.
  • Can't customize cache location per vault
  • Won't scale if you add a second vault — you'll want names

Cache Location Comparison

Approach Named vault cache Discovered vault cache Configurable?
Current N/A <vault>/.obsidian/obsdx/ No
A (Docker context) $XDG_CACHE_HOME/obsdx/<name>/ <vault>/.obsidian/obsdx/ Per-vault in config
B (Git-style) <vault>/.obsidian/obsdx/ <vault>/.obsidian/obsdx/ No
C (Hybrid) $XDG_CACHE_HOME/obsdx/<name>/ <vault>/.obsidian/obsdx/ Per-vault in config
D (Minimal) N/A <vault>/.obsidian/obsdx/ Global cache_dir only

Centralizing cache (Options A/C) has these tradeoffs:

  • Pro: Cache doesn't pollute the vault directory. Safe to gitignore-proof. Can be blown away without touching vault files.
  • Pro: Follows XDG spec properly (cache = recreatable, belongs in ~/.cache).
  • Con: Cache is no longer co-located with vault data. Two different vaults with the same name on different machines could collide.
  • Con: Migration needed for existing users who have cache inside .obsidian/obsdx/.
  • Con: Indexing a vault from a USB/network mount while cache is on local disk = mismatch.

Recommendation

Option C (Hybrid) hits the sweet spot. Here's why:

  1. Cwd discovery stays primary — the current workflow (cd into vault, run obsdx) still works perfectly. No behavioral change for existing users.
  2. Default vault as fallback — solves "I have one vault and want obsdx files list to work from ~" without introducing sticky state that changes per-shell behavior.
  3. Named vaults are bookmarks + cache config--vault work instead of --vault /home/user/Documents/Obsidian/WorkVault. Also unlocks per-vault cache directory customization.
  4. No config = current behavior — fully backward compatible.
  5. OBSDX_CONFIG_DIR override env var for the config directory (XDG-compliant).

Unresolved questions:

  1. Should --vault accept names and paths (smart detect), or should there be a separate --vault-name flag? Smart detect is nicer but can break if a name collides with a relative path.
  2. Cache migration on vault add: auto-migrate or require --migrate-cache flag?
  3. Should vault default with no args print the current default, or the resolved vault for the current cwd? (I'd suggest: print the default from config, since vault info already tells you the resolved vault.)
  4. Should the daemon (daemon start) auto-start for the default vault, or require explicit vault selection?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions