Config
init writes the machine config, and you can edit it by hand. Commands that change it keep every other line as you wrote it.
Files
| What | Where |
|---|---|
| Machine config | ~/.config/shuhari/config.toml |
| Tool-managed clones | ~/.local/share/shuhari/sources/<name> |
The XDG_CONFIG_HOME, XDG_DATA_HOME and XDG_STATE_HOME variables move these locations, on both macOS and Linux.
A full example
machine = "fukiBookPro-Max" scan_roots = [] [targets] claude = { kind = "host", path = "~/.claude/skills" } agents = { kind = "host", path = "~/.agents/skills" } [sources.agent-skills] path = "~/Projects/agent-skills" git = "git@github.com:you/agent-skills.git" skills = ["personal/*"] import_dir = "personal" [sources.superpowers] git = "https://github.com/obra/superpowers.git" skills = ["skills/*"] rev = "b55764852ac78870e65c6565fb585b6cd8b3c5c9" # a pinned source: a full commit ID [tags] lang = ["agent-skills:rust-*", "agent-skills:go"] [[install]] skills = ["agent-skills:rust-style", "superpowers:brainstorming"] targets = ["claude"] [[install]] tags = ["lang"] targets = ["claude", "agents"] [[exclude]] skill = "agent-skills:go" targets = ["agents"] # optional; omitted means every target [local] "~/.claude/skills/ontology-design" = { kind = "wip", review_after = 2026-11-15, note = "still changing" } "~/.claude/skills/things" = { kind = "machine", note = "macOS Things app" }
Top-level keys
| Key | Meaning |
|---|---|
machine | The machine name. init converts the system's display name; init --machine sets another. |
scan_roots | Directories that scan walks for project skills in .claude/skills and .agents/skills. It does not follow symlinks, and skips .git and node_modules. |
[targets]
One entry per target: a name, then kind and path. The kind is host. Two targets cannot resolve to the same directory.
[sources.<name>]
| Key | Meaning |
|---|---|
path | A directory you work in. With path, the source is a working-copy source. |
git | The remote URL. With git only, the source is a tool-managed source. A working-copy source with git must have origin equal to it. |
skills | A list of skill patterns. Not absolute, no ... An empty list is valid, and the source then has no skills. |
rev | A full commit ID. It pins the source. |
import_dir | Where import writes new skills. It needs path. |
A source needs path, git, or both. Two entries for the same source are an error: the same source means path values that resolve to the same directory, or, without path, equal git strings.
[tags]
Each key is a tag name, and its value is a list of selectors. Use a tag in an install choice with tags = ["<name>"], or as the selector tag:<name>.
[[install]]
Each entry has skills (selectors), tags, or both, and targets. shuhari add and shuhari remove edit these entries.
[[exclude]]
Each entry names one skill as source:skill. With targets, it applies to those targets only. Without it, it applies everywhere. shuhari exclude writes these entries.
[local]
Keyed by path. Each entry has kind, wip or machine, and an optional note. A wip entry accepts review_after. shuhari keep writes these entries. A declaration covers only that path: the same skill in another target is not covered.
Configs in the 1.0 format
A config with a [catalog] table uses the shuhari 1.0 format, which release 0.2.0 writes. Every command except init and doctor stops on it with exit code 2. Run shuhari init to convert it. The conversion is part of the change list, and nothing is written before you confirm.