diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..6fc7b7d --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,62 @@ +# clownware/plugins — repo instructions for Claude Code + +The clownware Claude Code plugin marketplace. Catalog: `.claude-plugin/marketplace.json`. +In-repo plugins live at `plugins//` (`.claude-plugin/plugin.json`, `skills//SKILL.md`, +`hooks/`). `product-dev` is externally sourced (`git-subdir`) and is released in its own repo. + +Read [`docs/MAINTAINING.md`](docs/MAINTAINING.md) before changing a skill or cutting a release. +Open decisions live as GitHub issues and in [`docs/ROADMAP.md`](docs/ROADMAP.md). + +## Gate (run all before calling a change complete; CI runs the same) + +```bash +python3 scripts/validate_plugins.py +python3 -m unittest discover -s scripts -p 'test_*.py' +find plugins -path "*/hooks/*.sh" -print0 | xargs -0 -r shellcheck +``` + +CI also runs `claude plugin validate plugins/` with a pinned Claude Code version. + +## Releases + +- Use `/plugin-release` (supports `--dry-run`). One release = one plugin = one commit, no drive-by edits. +- The version lives in `plugin.json` only. Never add `version` to a marketplace entry; it silently loses. +- A release syncs three surfaces in the same commit: `plugin.json` description, the + `marketplace.json` entry description, and the README plugin and skill tables. +- The commit body is derived from `git log ..HEAD -- plugins//`. Empty delta = no release. +- Commit form: `type(): summary; vX.Y.Z`. Other scopes: `ci`, `audit`, `manifests`, `roadmap`. +- Never bump an externally sourced plugin from here. + +## Shipping (overrides the global default) + +History is linear with no merge commits. Merge PRs with **rebase**, never squash: squashing +destroys the per-plugin release commits. + +## Skill authoring (MAINTAINING.md "Skill authoring standards", in short) + +- Pre-fetch lines use capture-then-default: `out=$(...); echo "${out:-fallback}"`. No unquoted + globs, no apostrophes inside `${var:-...}`. +- Verify every pre-fetch by running it in bash and zsh against hit, miss and unrelated + contexts, with zero stderr leaks. +- Descriptions carry trigger phrases and name the stack. +- Audit skills are assessment-only and never edit the tree. `/audit-fix` is the only skill that applies findings. +- A new skill gets a blind validation run (`/skill-validate`) before release; fixtures and + worktrees live outside the working tree. + +## Hooks + +Hook scripts never fail the turn: exit 0 and stay silent when the tool or config is absent +(the convention in every `hooks/*.sh` header). They must pass shellcheck. Formatting on +edit is one dispatcher, `plugins/code-tools/hooks/format-file.sh`, routed by extension; +add a new stack there, not as a new per-plugin hook. + +## Audit records + +- Never put a resolved `OPS_INGEST_TOKEN` in a report, command argument or committed file. +- Never record absent behavioural tests as zero failures, and never use a partial audit to clear unreviewed findings. + +## Working on the starters from here + +Sessions in this repo often inspect the sibling starters +(`../astro-performance-starter`, `../go-performance-starter`). Read-only checks there are +fine; changes to a starter go through that repo's own branch, gate and PR.