Files
2026-08-04 14:24:21 +00:00

130 lines
6.7 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## What this repo is
`skill-repo`: a private collection of tool-neutral [Agent Skills](https://agentskills.io)
(`SKILL.md` + `scripts/`), currently two plugins for Claude Code:
- **`git-manager`** — routes all git operations through one wrapper script
(`skills/git-manager/scripts/git_cmd.sh`) so multi-repo work never needs
`cd` or shell chaining (`&&`, `;`, `|`), which is what breaks Bash
permission whitelisting.
- **`obsidian-vault-kb`** — turns an Obsidian vault into a searchable
knowledge base via three wrapper scripts (`vault_index.sh`,
`vault_search.sh`, `vault_backlinks.sh`).
There is no build, lint, or test tooling in this repo — it's shell scripts
plus Markdown/JSON, exercised by running the wrapper scripts directly (e.g.
`skills/git-manager/scripts/git_cmd.sh status --repo <name>`) or by
installing the plugin in Claude Code and running its `/plugin:setup`
command.
## If you're operating from the `skills` local checkout wrapper
If this repo is checked out at `<workspace>/repo/` with a sibling
`<workspace>/.claude/` holding local, un-versioned Claude Code settings
(that's the standard local layout for this repo), the working directory
Claude Code starts in is `<workspace>`, one level above this repo root —
**use the `git-manager` skill for all git operations** (`status`, `commit`,
`push`, etc.), not raw `git`/`cd`, registered there with `--repo skills`
pointing at this directory. Raw `git -C <workspace>/repo ...` or
`cd <workspace>/repo && git ...` works mechanically but bypasses the
whitelisted wrapper that setup is built around.
## Architecture: `skills/` vs `vendor/`
The repo (see `ARCHITECTURE.md`) deliberately splits tool-neutral skill
content from host-tool-specific plumbing:
```
.
├── skills/<name>/ # canonical, tool-neutral — SKILL.md, scripts/, references/
└── vendor/claude-code/plugins/<name>/ # Claude Code-specific adapter
├── .claude-plugin/plugin.json
├── skills/<name> -> ../../../../../skills/<name> (symlink, not a copy)
├── commands/setup.md # -> /<name>:setup
├── permissions-whitelist.template.json
└── hooks/ # git-manager only, currently
```
- `skills/<name>/` is the *only* place skill content lives. It assumes
nothing about the host tool: config is read from
`~/.agent-skills/<name>/config.json`, never a Claude-specific path, so the
same `SKILL.md` works unmodified in other Agent-Skills-compatible tools.
- `vendor/claude-code/plugins/<name>/` holds everything Claude Code-specific:
plugin manifest, `Bash(...)` permission whitelist, the `/setup` slash
command, and (for git-manager) `PreToolUse` hooks. Its `skills/<name>` is
a symlink back into the top-level `skills/` dir — never a duplicated copy
that can drift.
- `.claude-plugin/marketplace.json` lists both plugins and must live at the
repo root (Claude Code convention, not `vendor/claude-code/`).
Adding a third host tool (e.g. Codex) means adding a new `vendor/<tool>/`
tree symlinked back to the same `skills/<name>/`, without touching skill
content.
## The permission-whitelisting philosophy (applies to every plugin here)
This is the design constraint that shapes almost every file in this repo —
worth understanding before editing any wrapper script, `setup.sh`, or
`permissions-whitelist.template.json`:
- **Never whitelist a generic command.** No `Bash(git:*)`, `Bash(find:*)`,
`Bash(cd:*)`. Each plugin whitelists exactly one (or a few) wrapper
script(s), pinned by exact absolute path. The wrapper enforces its own
scope (allowed subcommands, vault boundaries) — the whitelist entry just
says "this specific, self-limiting script may run without asking."
- **Wrapper scripts never accept a raw filesystem path from the caller.**
They resolve everything (repo path, vault path) from a config file at
`~/.agent-skills/<name>/config.json` by *name*. This is what makes
whitelisting the script by path safe — it can't be pointed at an arbitrary
directory.
- **Setup copies scripts to a stable, self-owned location before writing any
permission rule** — `~/.agent-skills/<name>/bin/`, never Claude Code's
internal plugin cache path (`~/.claude/plugins/cache/.../<version>/`),
which changes on every plugin version bump. This is why each `setup.sh`
does "copy scripts → write permissions → write config" in that order, and
why permission rules are written in **tilde form** (`~/...`), matching the
literal unexpanded command text Claude Code matches against — not the
resolved `$HOME` path.
- **Nothing destructive is silently whitelisted.** Config-file writes
(registering a new repo/vault) and anything outside the fixed
subcommand/action allowlist always fall through to a normal confirmation
prompt.
- **Optional `PreToolUse` hooks are advisory, never blocking.** They only
ever emit `permissionDecision: "ask"` (never `"deny"`, never `"allow"`) —
see `force-ask-on-chaining.sh` and `force-ask-on-raw-git.sh` in
`vendor/claude-code/plugins/git-manager/hooks/`. If `jq` is missing they
fail open (no output) rather than block every Bash call.
## Adding a new skill
Documented in full in `ARCHITECTURE.md`; short version:
1. `skills/<new-name>/` with `SKILL.md` (+ `scripts/`/`references/` as
needed). Config path: `~/.agent-skills/<new-name>/config.json`.
2. `vendor/claude-code/plugins/<new-name>/` with `.claude-plugin/plugin.json`,
a `skills/<new-name>` symlink back to the top-level skill dir, and — if
the skill needs restricted shell access — `commands/setup.md` plus
`permissions-whitelist.template.json` following the existing plugins'
pattern (wrapper scripts that resolve scope from config, whitelisted only
by exact absolute path).
3. Add an entry to `.claude-plugin/marketplace.json`.
4. Bump `version` in both the plugin's `plugin.json` and its
`marketplace.json` entry on any update.
## Gotchas specific to this repo
- Symlinks (`vendor/.../skills/<name> -> ../../../../../skills/<name>`)
assume POSIX; this repo doesn't try to be Windows-checkout-friendly.
- `permissions-whitelist.template.json` files are **reference/documentation
only** — the actual rules are generated and written by each plugin's
`scripts/setup.sh`, not read from the template at runtime.
- git-manager's wrapper deliberately rejects `stash`, `merge`, `rebase`,
`reset`, and arbitrary `git config` — these can rewrite/discard
history or working-tree state irreversibly. Raw `git` remains a valid,
visible fallback for those (nudged, not blocked, by
`force-ask-on-raw-git.sh` if that hook is installed).