Boy Scout Plugin for Claude Code
"Leave every piece of code a little better than you found it."
— Robert C. Martin, 97 Things Every Programmer Should Know, ch. 8
A Claude Code plugin that implements Boy Scout Rule mechanics: passively detects refactoring opportunities as you work, then surfaces them at the end of each session so nothing gets lost and nothing interrupts your flow.
⚠️ Pre-alpha version, use it at your own risk ⚠️
How It Works
During your task End of session
───────────────── ──────────────
Write / Edit a file Claude finishes responding
│ │
▼ ▼
PostToolUse hook fires Stop hook fires
│ │
▼ ▼
Detectors run on the file Reads new TODOs since last run
│ │
▼ ▼
Findings → .claude/boy-scout- Injects summary into Claude's
todos.jsonl context via systemMessage
(silent, no transcript) (inform-only, doesn't block)
Claude also records semantic opportunities it notices during work (via the record-opportunity skill), complementing the static hook-based detection.
Detectors
Ordered by priority:
| Detector | What it finds | Languages |
|---|
| Duplication | Copy-pasted code blocks (≥6 lines by default) | All supported |
| Naming clarity | Single-char identifiers, cryptic abbreviations | Rust, Elm, JS/TS, Python, Go |
| Test coverage gap | Source file changed but no test file found | Rust, Elm, JS/TS, Python, Go, Java, Kotlin |
| Function size | Functions exceeding line threshold | Python (AST), Rust, Elm, JS/TS, Go (regex) |
Language support priority: Rust → Elm → JavaScript/TypeScript → Python (others best-effort).
Installation
Copy or symlink this directory into your Claude Code plugin path, then enable the plugin in Claude Code settings.
# Option A: symlink
ln -s /path/to/boy-scout ~/.claude/plugins/boy-scout
# Option B: copy
cp -r /path/to/boy-scout ~/.claude/plugins/
Requires Python 3.10+ (no third-party dependencies).
Platform: Unix/macOS only. The plugin uses fcntl for file locking, which is not available on Windows.
Configuration
The plugin auto-creates .claude/boy-scout-config.json with defaults on first run. To customise, create or edit the file before that:
{
"detection": {
"enabled": true,
"patterns": ["duplication", "naming", "test_coverage", "function_size"],
"sensitivity": "balanced",
"ignore_paths": [
"vendor/",
"dist/",
"*.generated.ts",
"node_modules/",
"target/",
".git/"
],
"ignore_tests": false
},
"output": {
"suppress_transcript": true
},
"session": {
"auto_clear": false
}
}
Sensitivity levels
| Level | Min dup lines | Max function lines |
|---|
aggressive | 4 | 10 |
balanced (default) | 6 | 20 |
conservative | 10 | 35 |
TODO Storage
Opportunities are persisted in .claude/boy-scout-todos.jsonl (line-delimited JSON, one entry per line). Each entry follows the schema in schema/todo-item.json:
{
"id": "a3f9c12e",
"type": "duplication",
"file_path": "src/routes/auth.rs",
"locations": [{"line_start": 88, "line_end": 104}],
"description": "Block duplicated from src/routes/users.rs:45-61",
"severity": "medium",
"detected_at": 1713200000.0,
"source": "hook",
"dismissed": false
}
source is either "hook" (static detection) or "skill" (Claude's semantic observation).
The record-opportunity Skill
Claude uses this skill proactively whenever it notices an improvement during normal work. No user prompt needed — Claude silently invokes it and adds a one-line note in its response:
(Boy Scout: noted missing tests for Invoice.apply_discount() for later.)
How the Stop Hook Fires
The Stop hook fires at the end of every Claude response — not when you close the terminal. Whenever Claude finishes answering and hands control back to you, the Stop event triggers.
This means no special action is needed. The workflow is:
- Work normally — ask Claude to write or edit files
- PostToolUse runs silently on each modified file, appending any findings to
.claude/boy-scout-todos.jsonl
- Stop hook fires after Claude's response — if new findings exist since the last run, Claude's reply will end with a Boy Scout summary:
🏕️ Boy Scout report: 4 refactoring opportunities detected this session.