From 18fcaf9f27d03849487078b30f667c3b574e6554 Mon Sep 17 00:00:00 2001 From: Craig Jennings Date: Sun, 19 Apr 2026 11:57:23 -0500 Subject: feat: add per-project language bundles + elisp ruleset Introduces a second install mode alongside the existing global symlinks: per-project language bundles that copy a language-specific Claude Code setup (rules, hooks, settings, pre-commit) into a target project. Layout additions: languages/elisp/ - Emacs Lisp bundle (rules, hooks, settings, CLAUDE.md) scripts/install-lang.sh - shared install logic Makefile additions: make help - unified help text make install-lang LANG= PROJECT= [FORCE=1] make install-elisp PROJECT= [FORCE=1] (shortcut) make list-languages - show available bundles Elisp bundle contents: - CLAUDE.md template (seed on first install, preserved on update) - .claude/rules/elisp.md, elisp-testing.md, verification.md - .claude/hooks/validate-el.sh (check-parens, byte-compile, run matching tests) - .claude/settings.json (permission allowlist, hook wiring) - githooks/pre-commit (secret scan + staged-file paren check) - gitignore-add.txt (append .claude/settings.local.json) Hooks use \$CLAUDE_PROJECT_DIR with a script-relative fallback, so the same bundle works on any machine or clone path. Install activates git hooks via core.hooksPath=githooks automatically. Re-running install is idempotent; CLAUDE.md is never overwritten without FORCE=1. --- README.org | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 README.org (limited to 'README.org') diff --git a/README.org b/README.org new file mode 100644 index 0000000..f46eef2 --- /dev/null +++ b/README.org @@ -0,0 +1,86 @@ +#+TITLE: Rulesets +#+AUTHOR: Craig Jennings + +Claude Code skills, rules, and per-language project bundles. + +* Layout + +| Directory | Purpose | +|-----------------+------------------------------------------------------------------| +| =claude-rules/= | Generic rules symlinked into =~/.claude/rules/= (apply globally) | +| =/= | Skill directories symlinked into =~/.claude/skills/= | +| =languages/= | Per-language project bundles (rules + hooks + settings) | +| =scripts/= | Install helpers | + +* Two install modes + +** Global (machine-wide) + +Symlinks skills and generic rules into =~/.claude/=. Run once per machine. + +#+begin_src bash +make install # symlink skills and rules into ~/.claude/ +make uninstall # remove the symlinks +make list # show what's installed +#+end_src + +Skills and generic rules apply to every Claude Code session on this machine. + +** Per-project language bundles + +Copies a language-specific ruleset into a target project. Re-run to refresh. + +#+begin_src bash +make install-elisp PROJECT=~/projects/my-elisp-thing +# or, explicit: +make install-lang LANG=elisp PROJECT=~/projects/my-elisp-thing + +make list-languages # show available bundles +#+end_src + +What gets installed: +- =.claude/rules/*.md= — project-scoped rules (language-specific + verification) +- =.claude/hooks/= — PostToolUse validation scripts +- =.claude/settings.json= — permission allowlist + hook wiring +- =githooks/= — git hooks (activated via =core.hooksPath=) +- =CLAUDE.md= — seeded on first install only (use =FORCE=1= to overwrite) +- =.gitignore= — appends personal-override entries (deduped) + +The install is re-runnable. Running it again refreshes files in place; personal +tweaks live in =.claude/settings.local.json= and are not touched. + +* Available languages + +| Language | Path | Notes | +|----------+------------------+----------------------------------------------| +| elisp | =languages/elisp/= | Emacs Lisp — ERT, check-parens, byte-compile | + +Add more by creating =languages//= with the same structure. + +* Bundle structure + +Each language bundle under =languages//= follows: + +#+begin_example +languages// +├── CLAUDE.md # project instructions template (seed only) +├── claude/ # copied into /.claude/ +│ ├── rules/*.md +│ ├── hooks/*.sh +│ └── settings.json +├── githooks/ # copied into /githooks/ +│ └── pre-commit +└── gitignore-add.txt # lines appended to /.gitignore +#+end_example + +* Design principles + +- *Authoritative source*: =.claude/= and =githooks/= overwrite on every install. + If you edit them in-project, your changes will be lost on next install. Put + per-project customizations in =.claude/settings.local.json= (gitignored) or + project-specific files outside =.claude/=. +- *CLAUDE.md is precious*: it's the one file with project-specific prose, so + install never overwrites it unless =FORCE=1=. +- *Portable paths*: hooks use =$CLAUDE_PROJECT_DIR= (Claude Code sets it) with + a script-relative fallback. No hardcoded usernames or paths. +- *Idempotent*: re-running install is always safe. No state beyond file contents. -- cgit v1.2.3