3 modules. 3 hooks. Rules Claude actually needs.
Only rules that change Claude's default behavior, backed by hooks that enforce them. Nothing Claude already knows how to do.
# 1. Download and copy to your project
cp -r claude-code-starter-kit/ your-project/.claude/
# 2. Make scripts executable
chmod +x your-project/.claude/hooks/*.sh your-project/.claude/modules.sh
# 3. In Claude Code, ask:
# "Read .claude/setup/SKILL.md and run the setup skill to configure this project"Claude will ask about your project and generate a personalized CLAUDE.md + settings.json.
For alternative install methods, see Manual install.
Every module = a rule (what Claude should do) + a hook (enforcement). Toggle independently.
$ bash .claude/modules.sh
π¦ Claude Code Starter Kit β Modules
βββββββββββββββββββββββββββββββββββββ
π’ documentation enabled (1 hook) β Update docs in same session as code changes
π’ afk-mode enabled (1 hook) β Autonomous build: backup first, build without asking, stop after 3 failures
π’ git-workflow enabled (1 hook) β Conventional commits, branch strategy, secret detection
bash .claude/modules.sh help # What each module does + all commands
bash .claude/modules.sh disable afk # Fuzzy match: afk β afk-mode
bash .claude/modules.sh enable all # Re-enable everythingClaude reads modules.json at session start and only follows rules from enabled modules. Disabled module hooks silently pass through.
Problem: Claude finishes the code task and stops. Docs drift out of sync.
Rule: Update CHANGELOG.md and INFRASTRUCTURE.md in the same session as code changes. Includes trigger list (new container, port change, new endpoint...) and examples of good vs bad changelog entries.
Hook (Stop): When Claude tries to finish, doc-sync-check.sh checks git diff. If code files changed but no doc files changed β blocks Claude from stopping until docs are updated.
Problem: You give Claude a build task and step away. Claude either stops to ask confirmation, or loops forever on a failure.
Rule: Autonomous build protocol. Back up before destructive changes, build without asking, proceed through the full task. If 3 consecutive attempts at the same problem fail β stop, document what happened, move to the next task.
Hook (PostToolUse): afk-watchdog.sh counts consecutive command failures. At 3, it injects a system message forcing Claude to stop retrying and document the blocker instead.
Problem: Claude's default commits are vague ("update code", "fix stuff") and it doesn't check for leaked secrets.
Rule: Conventional Commits format, branch naming, PR description template. Includes good vs bad examples for each.
Hook (PreToolUse): pre-commit-guard.sh intercepts git commit commands. Blocks if: commit message isn't conventional format, staged files contain API keys/passwords/tokens, or .env files are staged.
Claude tries to finish a session
β Stop hook fires
β module-gate.sh: is "documentation" enabled in modules.json?
β Yes β doc-sync-check.sh: git diff shows code changed but no CHANGELOG
β exit 2 β ENFORCED
Claude must fix the issue before continuing
β No β exit 0 β Claude finishes normally
Every hook routes through module-gate.sh which reads modules.json. Disable a module = its hook becomes a no-op. No need to edit settings.json.
bash test/demo.shSimulates 6 real scenarios without calling the Claude API β instant, free, deterministic:
Scenario 1: Code changed without updating CHANGELOG
Before (without starter kit):
Claude finishes the session. CHANGELOG stays unchanged.
After (with starter kit):
π§ ENFORCED β Claude must update CHANGELOG.md before session can end
Scenario 4: Hardcoded secrets about to be committed
Before (without starter kit):
Claude writes API_KEY = "sk-1234..." and commits.
After (with starter kit):
π§ ENFORCED β Secret detected, Claude must move it to .env
All 9 checks passed.
No Claude CLI needed. Each scenario creates the situation and shows the hook response.
bash test/validate.sh your-project/22 automated tests. Pipes fake JSON into each hook and checks exit codes. Verifies the enforcement mechanism works: does the doc-sync hook actually block? Does the AFK watchdog count failures correctly? Does the pre-commit guard catch secrets?
Runs in seconds. No API calls. Use this in CI.
bash test/smoke-test.sh your-project/Runs claude -p (headless mode) with real prompts in a test project:
- "Create a Python file" β checks Claude updated CHANGELOG.md
- "Commit the changes" β checks commit message is conventional
- "Run an impossible command" β checks Claude stops after ~3 attempts
- Disable a module β checks Claude doesn't enforce disabled rules
Proves end-to-end behavior: Claude reads the rules, follows them, hooks enforce them.
cat test/scenarios.mdCopy-paste prompts for nuanced cases that are hard to automate. Each scenario has an expected outcome and a git diff or grep command to verify. Covers: infra changes triggering doc updates, secret detection forcing refactor, backup before destructive changes, module toggle taking effect mid-session.
.claude/
βββ modules.json β Single source of truth: which modules are on/off
βββ modules.sh β CLI: status, enable, disable, help
βββ rules/
β βββ documentation.md β Same-session doc sync + changelog format + examples
β βββ afk-mode.md β Autonomous build protocol + 3-strike + session log format
β βββ git-workflow.md β Conventional commits + PR template + examples
βββ hooks/
β βββ module-gate.sh β Router: checks modules.json, skips disabled modules
β βββ doc-sync-check.sh β Stop hook: blocks if docs not updated with code
β βββ afk-watchdog.sh β PostToolUse: counts failures, blocks at 3
β βββ pre-commit-guard.sh β PreToolUse: blocks secrets + bad commit messages
βββ settings.json β Hook wiring (all route through module-gate)
βββ setup/
β βββ SKILL.md β Interactive setup: asks questions, generates config
βββ test/
βββ demo.sh β Before/after: 6 scenarios, 9 checks, no API calls
βββ validate.sh β Layer 1: 22 hook tests (no Claude needed)
βββ smoke-test.sh β Layer 2: end-to-end with claude -p
βββ scenarios.md β Layer 3: manual copy-paste test prompts
# Copy files
mkdir -p your-project/.claude/{rules,hooks,setup}
cp rules/*.md your-project/.claude/rules/
cp hooks/*.sh your-project/.claude/hooks/
cp modules.json modules.sh your-project/.claude/
cp setup/SKILL.md your-project/.claude/setup/
cp CLAUDE.md.template your-project/CLAUDE.md
# Make executable
chmod +x your-project/.claude/hooks/*.sh your-project/.claude/modules.sh
# Edit CLAUDE.md β replace {{variables}} with your values
# Then add hooks to .claude/settings.json:{
"hooks": {
"PreToolUse": [{ "matcher": "Bash", "hooks": [{
"type": "command",
"command": "bash .claude/hooks/module-gate.sh git-workflow pre-commit-guard.sh"
}]}],
"PostToolUse": [{ "matcher": "Bash", "hooks": [{
"type": "command",
"command": "bash .claude/hooks/module-gate.sh afk-mode afk-watchdog.sh"
}]}],
"Stop": [{ "hooks": [{
"type": "command",
"command": "bash .claude/hooks/module-gate.sh documentation doc-sync-check.sh"
}]}]
}
}- Create
rules/your-module.mdwith the rule - (Optional) Create
hooks/your-hook.shto enforce it - Add entry to
modules.jsonwithenabled: true - Wire hook through
module-gate.shinsettings.json
The bar: "Does Claude's default behavior cause a real problem that this fixes?"
- Only rules that change behavior. If Claude already does it β not here.
- Hooks over hope. Rules are suggestions. Hooks are enforcement.
- Modular. Every module independent. Disable what you don't need.
- Zero dependencies. python3 + git + bash. No jq, no npm, no pip.
- Tested at 3 levels. Hook unit tests (fast, CI-ready), smoke tests with Claude CLI, manual scenarios for edge cases.