Files
custom-claude-skills/CLAUDE.md
Paul O'Reilly 3b954ff02a Add review-plan and review-spec skills
Two new read-only skills that review plans and specs against best practices:
- /review-plan: Checks plans against 6 areas (security, API design, LLM code
  security, spec-driven dev, TDD, operational readiness). Outputs scorecard
  with critical gaps and recommendations.
- /review-spec: Checks specs for structure quality, requirement testability,
  security coverage, and API design patterns. Scores 5 dimensions and
  identifies missing requirements and scenarios.

Both load api-design.md, llm-code-security.md, spec-driven-development.md,
test-driven-development.md, and security-architecture.md from best-practices.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 11:11:28 +13:00

3.9 KiB

Custom Claude Skills

Reusable Claude Code skills shared across all projects via symlinks into ~/.claude/skills/.

Repository Structure

custom-claude-skills/
├── CLAUDE.md              # This file
├── MEMORY.md              # Learnings about skill development
├── FUTURE.md              # Future skill ideas
├── README.md              # Setup instructions and skill catalogue
├── scripts/
│   └── install.sh         # Symlinks all skills into ~/.claude/skills/
└── skills/
    ├── context-load/SKILL.md       # Reload project context
    ├── decompose/SKILL.md          # Task decomposition for container agents
    ├── distill-best-practices/SKILL.md # Cross-project best practices
    ├── housekeeping/SKILL.md       # Cross-project health check
    ├── linter/SKILL.md             # Format/lint audit and execution
    ├── log/SKILL.md                # End-of-session logging
    ├── orchestrate/SKILL.md        # Container agent dispatch with git worktrees
    ├── reflect/SKILL.md            # Milestone reflection
    ├── reflect-logs/SKILL.md       # Process logs into memory
    ├── review-plan/SKILL.md        # Review plan against best practices
    └── review-spec/SKILL.md        # Review spec against best practices

Conventions

  • Each skill lives in skills/<skill-name>/SKILL.md
  • Skills should be project-agnostic where possible — use dynamic context injection (!command``) to adapt to the current project
  • The scripts/install.sh script creates symlinks from ~/.claude/skills/<name> → this repo's skills/<name>/
  • After adding a new skill, run ./scripts/install.sh to register it
  • Skills that are only useful for one project should live in that project's .claude/skills/ instead
  • Every skill must have a corresponding memory/skill-<name>.md in claude-foundations with purpose, usage, how it works, and gotchas — update the claude-foundations/MEMORY.md index as part of the same commit

Skill Development Guidelines

  • Inline by default — only use context: fork if the skill genuinely doesn't need conversation history
  • Pre-fetch context with !command`` injection to reduce tool calls during execution
  • Restrict tools with allowed-tools to the minimum needed — this reduces permission prompts
  • Use $ARGUMENTS for user input, $0, $1 etc. for positional args
  • Dynamic commands in !command`` run at skill load time, not during Claude's execution

!command`` Gotchas

The !command`` syntax in SKILL.md runs shell commands at skill load time to pre-gather context. These commands go through Claude Code's Bash permission checker against the allowed-tools patterns. Key constraints:

  • No $() command substitution — the permission checker rejects commands containing $() even if the outer command matches an allowed pattern. This means you cannot nest subshells (e.g., git log --since="$(git log ...)" will fail).
  • No complex shell pipelines relying on subshells — keep !command`` commands simple and self-contained. If you need complex logic, have the skill instructions tell Claude to run it via tool calls instead.
  • allowed-tools patterns must match the command binaryBash(git *) allows any git subcommand, but Bash(cat *), Bash(sed *), Bash(ls *) must be listed separately if those commands appear in !command`` blocks.
  • Prefer specific tool patterns over broad onesBash(git log *), Bash(git diff *) is safer than Bash(git *) to avoid accidentally allowing destructive git commands (e.g., git reset, git push --force).
  • Fallback to tool instructions for dynamic paths — if a command needs $ARGUMENTS to compute a file path (e.g., cat scripts/verify-m${N}.sh), replace the !command`` with a plain-text instruction telling Claude to use the Read tool. This avoids $() substitution and is more reliable.