Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Source layout and item kinds

A source is a git repo mind melds. It offers items, discovered by convention or declared in a mind.toml. The convention layout, which works on any repo with no config:

<repo>/
  skills/<name>/SKILL.md     a skill (the whole directory is the item)
  agents/<name>.md           an agent
  rules/<name>.md            a rule
  commands/<name>.md         a slash command
  workflows/<name>.js        a workflow the harness runs
  tools/<name>/              a tool (the whole directory; no anchor file)
  resources/<entry>          a resource: a file or directory other items read
  mind.toml                  optional: metadata, export control, odd layouts

The kinds:

  • skill: a directory with a SKILL.md anchor. Bundled files (a resources/ dir, scripts) ship with it.
  • agent / rule / command: a single markdown file. A command is what the harness offers at the prompt as /<name>.
  • workflow: a single .js file the harness loads from workflows/ and offers to its Workflow tool. See Workflows.
  • tool: a directory of helper scripts or a compiled binary. A tool is store-only: other items reference it, and by default it is not linked into an agent home (a tool can opt in with an explicit link, see Share helper scripts).
  • resource: one file or directory under resources/, named by its full file name (resources/allowlist.json is resource:allowlist.json). Store-only like a tool, and offered only when another item in the source references it with {{resources:name}}. See Share data files.

The command scan is flat: commands/<name>.md, no subdirectories. Claude Code reads a grouped commands/frontend/component.md as /frontend:component, and you get the same command name from a flat file by putting the colon in the name (commands/frontend:component.md), which is also what a mind namespace produces (jk:review links as commands/jk:review.md and runs as /jk:review). Keep a real subdirectory only if you need it for Claude users directly; then declare the item in mind.toml with a full [[items]] entry (kind, name, path, and a link that preserves the nested path). Note that adding any [[items]] or [discover] entry makes the manifest authoritative for the whole repo: convention scanning turns off and only what the manifest lists is offered, so a one-entry manifest silently drops every other item. Declare everything you ship, or reach the nested file another way. See The mind.toml file. Note that Claude Code now treats custom commands as skills: a commands/ file and a skills/<name>/SKILL.md both produce /<name>, and a skill is the better shape for something new. See Commands for what happens when a source ships both.

A group segment must not be a reserved kind word (skill, agent, rule, command, workflow, tool, resource). commands/tool:build.md installs as tool:build, which an item ref reads as kind tool, name build, so mind learn tool:build fails with a not-found error naming build. Spell it command:tool:build, or pick another group name.

A mind.toml is optional enrichment, never a gate. It carries source metadata, a namespace prefix, and (when you need it) explicit [[items]] or [discover] globs for non-standard or monorepo layouts. See examples/.

A repo published for Claude Code’s plugin system needs no changes either: a .claude-plugin/plugin.json or .claude-plugin/marketplace.json is read as a discovery input. The manifest supplies the plugin’s name and metadata; mind maps the plugin root’s conventional skills/, agents/, commands/, and workflows/ directories to items. See Claude plugins and marketplaces.

Where shared helpers belong

A helper used by a single skill lives in that skill’s own directory and is addressed with {{self}}:

skills/review/
  SKILL.md           # ... run {{self}}/resources/pr.py ...
  resources/pr.py

A helper used by more than one item has two good homes. Either:

  • An install hook puts it in a known location. Declare a [[hooks]] install entry to run your install script, which installs the shared tooling wherever you want, and have your items call it there. This suits anything with a build step or a dependency to fetch, and a source onboards its build once.
  • A tool item shares it through the store. Put it once under tools/<name>/ and reference it by token ({{tools:name}}). mind carries it in the store and expands the token at install.
tools/detect/detect          # the shared script, shipped once
skills/a/SKILL.md            # ... {{tools:detect}} ...
skills/b/SKILL.md            # ... {{tools:detect}} ...

Copying a byte-identical helper into several items works too; mind review and mind init-source note it as a duplicate-tooling advisory (informational, not a defect) in case you would rather share it once.

Referencing items and resources

To reference one item from another, mind provides tokens it expands at install. They are useful mainly under a namespace prefix (which renames items) or across multiple agent homes; an unprefixed single-home source can often just use the name or a bundled path.

tokenexpands to
{{ns:name}}a sibling item’s effective name (use in prose, e.g. “hand off to {{ns:dev}}”)
{{self}}the item’s own store directory (its bundled resources)
{{tools:name}}a sibling tool’s entrypoint
{{resources:name}}a sibling resource’s store path (the file, or the directory)
{{path:ref}}a sibling item’s store directory, for a non-entrypoint file ({{path:tool:detect}}/lib.sh)

References resolve within the same source only: ship a tool or resource in the same source as the items that use it. Every token except {{self}} is also a dependency, so mind learn of one skill installs the tools and resources it names.

A token expands in a file when the file has a markdown extension, or the item is of the workflow kind, or the file is on the item’s expand: list. A token in an ordinary bundled script (a resources/pr.py) is left literal by default; list the file in the item’s expand: frontmatter to expand it there, so a script can locate its tooling without a language-specific self-locate; see Share helper scripts.

The workflow kind’s grant cuts both ways for an author. A workflow’s meta.name is not frontmatter – it is a plain JS object field – so nothing stops you from writing it as a literal string instead of a {{ns:}} token; do that under a namespace prefix and the reference silently diverges from the installed effective name, rather than failing loudly, until review/upgrade catches it. The opposite mistake also becomes possible: a literal {{ns:...}}-shaped string elsewhere in the file’s JS, written with no intention of it being a token (a template string, a comment, test fixture data), is now expanded and validated like any other reference, so an unresolvable name there is a hard BadReference install failure rather than inert text. The usual remedy for an unwanted expansion in a bundled non-markdown file – omit the file from expand: – does not apply here, since a workflow’s .js has no frontmatter to carry an expand: key in the first place; the grant is unconditional for the whole file.

Hardcoded paths

mind learn copies an item into the store (~/.mind/store/<kind>/<name>) and symlinks it into each agent home (~/.claude/skills/<name>, agents/<name>.md, rules/<name>.md, commands/<name>.md, workflows/<name>.js). Tools and resources are the exception: they are store-only and, by default, not linked into an agent home.

A path you control is fine: pointing at a location your install hook populates works as long as your hook and your items agree on it. What is fragile is hardcoding mind’s OWN install layout, since that layout shifts under you. mind review classifies those as the advisory hardcoded-path finding:

  • A skill referencing its own resources by an agent-home path (~/.claude/skills/<self>/resources/x) resolves through the skill’s symlink today, but breaks the moment a prefix renames the item (<prefix>:<self>) or a second agent home is configured. {{self}} generalizes it. Fragile, not broken.
  • A reference to a tool item by an agent-home path never resolves: a tool is not linked there. Use {{tools:name}} (or install it elsewhere via a hook).
  • Any reference under a prefix points at the wrong effective name, since a literal path does not track the rename.

A token keeps a leading ~ when the store is under your home, so a Claude settings.json permission glob such as Bash(~/.mind/store/**) matches the expansion.

mind review recognizes these install paths written with ~, $HOME, ${HOME}, or an absolute /home/<user> / /Users/<user> root, and mind review --fix rewrites the ones that map confidently to a token. The finding is advisory, so a deliberate fixed-location-via-install-hook layout is your call.