Validate Skills in CI
Run validate-skills.sh and doctor.sh on every PR via GitHub Actions, so a broken skill never lands on main.
The kit ships two validation scripts:
./scripts/validate-skills.sh— checks every.claude/skills/*/SKILL.mdfor required frontmatter, required sections, description length, and code examples../scripts/doctor.sh— checks installation health (missing files, broken hooks, invalid settings).
Running them locally is good. Running them in CI on every PR is better — a broken skill never lands on main.
Goal
# Pull request opened → validate-skills.sh + doctor.sh run → ✅ or ❌If either script fails, the PR is blocked from merging.
Recipe — GitHub Actions
Create .github/workflows/validate.yml:
name: Validate
on:
pull_request:
branches: [main]
push:
branches: [main]
jobs:
validate:
name: Validate kit installation
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Make scripts executable
run: chmod +x scripts/*.sh .claude/hooks/*.sh
- name: Validate skills
run: ./scripts/validate-skills.sh
- name: Doctor check
run: ./scripts/doctor.shThat's it. ~25 lines, no dependencies, no external services.
What this catches
| Type of break | Caught by |
|---|---|
Skill missing name: or description: in frontmatter | validate-skills.sh |
| Skill description too long (>200 chars) — won't match well in semantic search | validate-skills.sh (warning) |
Missing required ## When to Use / ## Process / ## Output Format sections | validate-skills.sh |
| Skill has no code examples | validate-skills.sh (warning) |
| Hook script not executable | doctor.sh |
.claude/settings.json invalid JSON | doctor.sh |
| Required directory missing | doctor.sh |
Add CODEBASE_MAP validation
If you also want to verify CODEBASE_MAP.md placeholders aren't unfilled:
- name: Validate CODEBASE_MAP
run: ./scripts/validate.sh CODEBASE_MAP.mdThis catches commits where someone added a section but forgot to fill in the [Your Project] placeholder.
Branch protection
Once the workflow is running, require it for merges:
- Settings → Branches → Add rule for
main - ✅ Require a pull request before merging
- ✅ Require status checks to pass before merging
- Add
Validate kit installation(the job name) as required
Now PRs that fail validation can't merge until fixed.
Run on a schedule
If you want a daily sanity check (catches drift from manual edits to main):
on:
schedule:
- cron: '0 4 * * *' # daily at 04:00 UTC
pull_request:
branches: [main]
push:
branches: [main]Run locally as a pre-commit hook
If you don't want to wait for CI:
# .git/hooks/pre-commit (chmod +x after creating)
#!/usr/bin/env bash
./scripts/validate-skills.sh && ./scripts/doctor.shNow git commit blocks if validation fails. (.git/hooks/ isn't tracked — every contributor needs to set this up locally, or use husky to share.)
Run in npm scripts
If your repo has a package.json:
{
"scripts": {
"kit:validate": "./scripts/validate-skills.sh && ./scripts/doctor.sh",
"precommit": "pnpm run kit:validate"
}
}Then pnpm run kit:validate (or your equivalent) runs both checks locally.
What if validate-skills.sh is too strict?
The validator is intentionally opinionated. If it's flagging skills you consider intentional:
- Description length warnings — usually right, trim them
- Missing required sections — add them or set
user-invocable: falsein frontmatter (validator is more lenient on non-user-invocable skills) - No code examples warning — add a
\``text` example output block
If a check is genuinely wrong for your use case, fork validate-skills.sh to scripts/project/validate-skills.sh and adjust thresholds. Don't edit the kit-managed copy — it'll get overwritten on --upgrade.
Verification
After adding the workflow:
- Push a PR
- GitHub Actions tab → confirm "Validate kit installation" runs and passes
- Branch protection: confirm it's listed as a required check
- Try breaking a skill (delete a required section) → confirm CI fails
Related
- Skills guide — what makes a skill valid
- Scripts reference — full list of kit scripts
- Hooks guide — the kit's other validation layer (runtime instead of CI)
Customize CLAUDE.project.md
Add stack-specific rules that override kit defaults and survive --upgrade. The project overlay is where your team's idiosyncrasies live.
Migrate from Cursor Rules
Coming from .cursorrules? Here's how to port your conventions to Claude Code Kit's CLAUDE.md / project overlay / agent_docs structure.