Files
claude/CLAUDE.md
T
bchanot 6430ac65ec feat(mods): model-router active in every session — skills-dir link, mods suite, doctor section, CLAUDE.md
Tracked relative symlink skills/model-router -> ../mods/model-router: Claude
Code loads the mod in place as model-router@skills-dir wherever link.sh
links ~/.claude/skills (no CLAUDE_CODE_PLUGIN_DIRS: absolute paths in the
tracked settings.json). Engine-laid mods/*/tsconfig.json gitignored.
lib/tests/mods.test.sh: manifest name, link target, claude plugin validate
and test per mod, capability-probed, time-bounded, SKIP with reason.
doctor.sh: fail-soft Mods section (link by -ef, one guarded plugin list).
CLAUDE.md: mods/ section (loading, per-machine enabled:false switch,
dev-copy shadowing, tests).
2026-10-09 10:51:13 +02:00

5.1 KiB

claude-config — project instructions

Health Stack

  • shell: shellcheck *.sh hooks/*.sh lib/*.sh

rules/ maintenance

Modular instruction files loaded by Claude Code alongside the global memory. rules/ is symlinked to ~/.claude/rules by link.sh (user scope, ALL projects). One rule = one file = one concern.

A rule WITH paths: YAML frontmatter (glob list) loads lazily — only when Claude reads a file matching a glob; a rule WITHOUT it loads at session start, same cost as the global memory. Extract from CLAUDE.global.md only what can be path-scoped (the token win) or what is generated; always-on doctrine stays in CLAUDE.global.md. Exception: a standalone user-authored rule set that would bust the 320-line density budget may live here WITHOUT paths: (always-on load) — writing-style.md (BDR-085). paths: globs match against the CURRENT project's tree — a broad glob (e.g. rules/**) can fire in foreign projects; keep rule bodies tiny. Docs: https://code.claude.com/docs/en/memory.md#path-specific-rules

Machine-owned: rules/context7.md is DELETED BY DESIGN (BDR-053, 2026-07-06) — ctx7 setup --claude --cli still writes it, but install-plugins.sh STEP ctx7 purges it right after; the find-docs skill is the single ctx7 surface. If it reappears (manual ctx7 setup), delete it or re-run make plugin.

Machine-owned: the vendored graphify skill

skills/graphify/SKILL.md, skills/graphify/references/ and .graphify_version are written by graphify claude install (install-plugins.sh STEP graphify), which lands in the repo because ~/.claude/skills is a symlink to skills/. They are gitignored: a pipx upgrade graphifyy used to dirty the tree and cost a chore(graphify): sync vendored skill X -> Y commit each time.

Two graphify commands, easy to confuse, and only one restores the skill:

  • graphify install --platform claude copies SKILL.md + references/ + .graphify_version into skills/graphify/. Touches nothing else. This is the recovery command.
  • graphify claude install writes the CLAUDE.md graphify section and the .claude/settings.json PreToolUse hooks. It rewrites both guarded configs (EVAL-020, verified again 2026-09-15), so revert them after. It does NOT copy the skill.

make plugin runs both (install-plugins.sh STEP graphify) behind the guarded-config EXIT trap, so a fresh clone is covered.

Trade-off accepted: an upstream release can now change the skill's prompt with no diff to review. skills/graphify/test-prompts.json is hand-written for darwin and stays tracked.

Gotcha, learned the hard way: git rm --cached keeps the working file, but if the branch you merge into still tracks it, the merge deletes it from disk. Untrack and merge, then restore with the command above.

mods/ — function-hooks plugins (Claude Code mods)

A mod lives in mods/<name>/ (.claude-plugin/plugin.json + hooks). It loads through the tracked relative symlink skills/<name> -> ../mods/<name> (~/.claude/skills links to skills/) as <name>@skills-dir, in place, live at the next session or /reload-plugins. New mod: ln -s ../mods/<name> skills/<name> from the repo root (guard with [ -L ], a re-run nests a link). Not CLAUDE_CODE_PLUGIN_DIRS (absolute path, settings env has no $HOME expansion, settings.json is tracked), nor a local marketplace (add writes an absolute path into settings.json).

  • The engine lays mods/<name>/tsconfig.json and .claude-plugin/types/; both are gitignored.
  • Optional user config: ~/.claude/<name>.json. Its "enabled": false is the per-machine off switch (untracked). "<name>@skills-dir": false in enabledPlugins also works but lands in the TRACKED settings.json and dirties every machine's tree.
  • A dev copy of the same name (--plugin-dir, hot-reload link in ~/.claude/dev-mods/<session>/) shadows the skills-dir copy for that session: remove it before reading /reload-plugins as a test of the link.
  • Tests: make test suite=lib/tests/mods.test.sh (manifest, link, claude plugin validate, claude plugin test). doctor.sh has a Mods section.

Transient planning artifacts

docs/superpowers/specs/** and docs/superpowers/plans/** are run-time artifacts of a feature pipeline (subagent briefs, reviewer references). They are committed DURING the run (the SDD worktree + reviewers read them from disk — NOT gitignored), then AUTO-PURGED by gitflow finish on a feature/bugfix branch, before the merge, so develop's tip stays clean (BDR-065, lib/gitflow.sh _gitflow_purge_transient). The feature commits stay reachable from develop, so git show <sha>:docs/… is still the archive. Opt out with GITFLOW_PURGE_TRANSIENT=0. NOT in scope: .claude/tasks/{contracts,plans} (durable, versioned, referenced by decisions.md). Durable knowledge goes to .claude/memory/ registries, never to these files. Derived scan/audit outputs (.audit/**) are gitignored and never committed, even redacted (LRN-124).