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

98 lines
5.1 KiB
Markdown

<!-- PROJECT SCOPE ONLY (claude-config repo). The user-scope GLOBAL memory is
./CLAUDE.global.md, deployed as ~/.claude/CLAUDE.md by link.sh — edit
THAT file for cross-project doctrine. -->
# 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).