Files
Henner M. Kruse 9f39a898c4 Fix setup.md: version-discovery fragility and unused argument-hint
Observed live: a stale plugin-cache version dir (1.0.0) coexisted with
the active one (1.1.0). setup.md's 'try the hardcoded version path
first' advice picked the stale one, its --install-raw-git-hook flag
failed silently, and Claude went on an unscripted forensic dig (chained
test&&echo, --help probing, grep/cat across both version dirs, cat'ing
plugin.json, stat'ing .in_use mtimes) to figure out which version was
actually active.

Fix, in both plugins' commands/setup.md:
- Never hardcode a version number. Always do one bounded
  find -maxdepth 1 -type d first; disambiguate multiple hits via the
  .in_use marker Claude Code itself writes, falling back to highest
  plugin.json version. Explicitly rule out the exploration that
  happened here (stat/mtime, --help, reading source, diffing versions)
  since setup.sh has no --help and unrecognized flags just error.
- Wire up the declared but previously-unused argument-hint
  ([repo-name] [repo-path] / [vault-path] [mode]): if the user already
  supplied it on the command line, skip asking the question that would
  just re-collect the same info.
2026-08-05 18:17:09 +00:00

108 lines
5.6 KiB
Markdown

---
description: Set up the obsidian-vault-kb skill (vault path, mode, minimal permissions whitelist)
argument-hint: [vault-path] [mode]
---
Set up the `obsidian-vault-kb` skill. As part of the `obsidian-vault-kb`
plugin, this command is automatically namespaced by Claude Code and invoked
as `/obsidian-vault-kb:setup`.
Almost everything about this setup — validating vault paths, writing the
skill's config, merging permissions into settings.json, setting executable
bits — happens inside one bundled script, `scripts/setup.sh`, which you run
as a **single** Bash call. That script also copies the wrapper scripts it
needs to a stable, self-controlled location
(`~/.agent-skills/obsidian-vault-kb/bin/`) before writing any permissions,
so the permission rules never have to change again across future plugin
updates — only this first run (and, optionally, a re-run after a plugin
update) needs to locate the plugin itself.
## 1. Ask the user — selectable questions first, vault path last
**1a. Before asking anything, check for arguments.** This command's
`argument-hint` is `[vault-path] [mode]`. Whatever was given this way
already answers that part — don't re-ask it in 1b/1c below:
- If `mode` was given and is one of `read-only`/`append`/`maintain`, skip
the mode question in 1b.
- If `vault-path` was given, skip the plain-chat vault question in 1c
entirely and use that path directly (give it a short default name, e.g.
the last path segment, unless the user's invocation also implied one).
- Whatever wasn't given this way still gets asked normally below.
**1b. First turn: remaining questions via the selection UI:**
- Mode: `read-only`, `append`, or `maintain` (as defined in SKILL.md —
explain each briefly if unsure). Omit if 1a already supplied a valid one.
- Settings scope: `project` (`.claude/settings.json` in the current
project) or `user` (`~/.claude/settings.json`).
**1c. Only if 1a didn't already supply a vault path: second turn, plain
chat message, no tool call.** Ask exactly: "What's the path to your vault?
Give it a short name too if you're registering more than one." End your
turn right after asking this, with nothing else queued up, so the user's
reply is what actually gets collected before you continue. (Only a tool
call reliably pauses for a reply in this environment; plain text followed
immediately by a tool call in the same turn does not wait — that's what
caused this question to appear skipped in an earlier version of this
command.) At least one vault is required — `setup.sh` errors out without
one — so this question is always asked unless 1a already supplied a path,
unlike the optional repos question in the git-manager plugin's setup.
## 2. Locate the plugin, then run the setup script — one command
Claude Code installs plugins added from a local marketplace at
`~/.claude/plugins/cache/<marketplace-name>/<plugin-name>/<plugin-version>/`.
**Never hardcode or guess a version number** — it changes on every release
of this plugin, and a stale directory from a previous version can still be
sitting on disk right alongside the current one. Always start with exactly
one bounded, read-only lookup instead:
```bash
find ~/.claude/plugins/cache/skill-repo/obsidian-vault-kb -maxdepth 1 -type d 2>/dev/null
```
- **Exactly one version directory found:** use it.
- **More than one found:** prefer whichever one contains a `.in_use`
marker file (Claude Code writes this into the currently-active version's
directory). If none of them has one, or more than one does, fall back to
whichever directory's `.claude-plugin/plugin.json` reports the highest
`version`. Don't disambiguate any other way — no `stat`/mtime
comparisons, no diffing scripts between versions, no probing with
`--help` (there is no `--help`; unrecognized flags just print `Error:
unknown argument`).
- **None found:** the plugin likely isn't installed under this name or
marketplace — say so and stop rather than guessing at a different path.
Then run, as a **single** Bash call (no `test -f ... &&` pre-check, no
piping through `grep`/`head` to inspect it first):
```bash
~/.claude/plugins/cache/skill-repo/obsidian-vault-kb/<version>/scripts/setup.sh \
--settings-scope <project|user> \
[--project-dir <path>] \
--mode <read-only|append|maintain> \
--vault <name>=<path> [--vault <name>=<path> ...]
```
The script itself validates each vault path exists and is a directory, and
reports an error if not — no separate validation call needed beforehand.
If this one call errors, that means the version picked above was wrong —
re-run the `find` above (and re-check `.in_use`/`plugin.json`) rather than
falling back to reading source files or trying more flags. This is
expected to prompt for approval the first time — there's no way to
pre-whitelist it before the setup that establishes the whitelist has run.
## 3. Relay the result
The script prints a JSON summary (stable script location, settings file
written, config file, mode, vaults registered, the exact permission rules
added, and a note about session reload). Present that summary to the user
in plain language — don't re-read any of those files yourself to "double
check"; the script's own output already reflects exactly what's on disk.
Do **not** follow this with a test invocation of `vault_index.sh` — Claude
Code loads permissions at session start and doesn't always pick up changes
made by its own file edits within the same session, so an immediate test
can prompt (or not) in a way that doesn't reliably indicate success either
way. If a real command later still prompts, the fix is a fresh session, not
re-running this setup — the configuration is already correctly saved.