Skip to content

dattruongtuan/uncle-code

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

15 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

uncle-code

Robert C. Martin's Clean Code as a small set of workflow skills for Claude Code. You invoke a verb — review, tidy, refactor, lint — and it loads the rulebook (one file per chapter plus the canonical Ch. 17 ID registry) behind the scenes. Canonical rule IDs from the book (N1, G30, F3, …) are cited inline, with six-language coverage (Python, TypeScript/JavaScript, Go, Rust, C#, Java) that varies honestly by chapter.

Inspired by the layout of JuliusBrussee/caveman: terse output, one job per skill, a single bare entry point (/uncle) that dispatches to focused verbs.

Design: verbs write or emit, nouns get loaded

  • Verbs are what you invoke. Each does one job and prints a terse, one-line-per-finding result.
  • Nouns are the rulebook — chapter rules and the flat ID registry. The verbs load them; you never invoke them. They don't appear in the skill picker.

Two verbs write (uncle-tidy opportunistic, uncle-refactor directed) and two analyze (uncle-review for humans, uncle-lint for scripts). They never merge.

Skills (verbs — the only ones you call)

Skill Does
/uncle Bare entry — asks what you want, dispatches to a verb
/uncle-review Read-only audit → numbered violations, each tagged G25/F1/N7
/uncle-tidy Boy Scout Rule — one small safe cleanup in a file the current task already touched
/uncle-refactor Directed transform on a named target → applies the fix + diff summary
/uncle-lint Non-interactive lane → SARIF 2.1.0 or JSON, same rule IDs

/uncle-review is "tell me what's wrong." /uncle-refactor is "fix this specific thing." /uncle-tidy is "you're already in this file — leave it a little cleaner." /uncle-lint is the machine-readable twin of review. Different triggers, different scope — don't conflate them.

Rulebook (nouns — loaded, never invoked)

Ships inside the uncle skill folder:

  • skills/uncle/rulebook/rules.md — the flat C/E/F/G/N/T registry (all 66 Ch. 17 IDs). Single source of truth every verb cites.
  • skills/uncle/rulebook/<chapter>.md — bare rules for each of the 12 chapters (names, functions, comments, formatting, objects, error-handling, boundaries, unit-tests, classes, systems, emergent-design, concurrency).
  • skills/uncle/rulebook/references/<chapter>/<lang>.md — per-language specifics, loaded lazily only when a file matches that language.

Sample output

/uncle-review on a messy diff:

1. src/foo.py:42  🔵 N1   `x` vague → `active_user_count`.
2. src/foo.py:55  🟡 G30  `process()` does 3 things — extract fetch/transform/persist.
3. src/foo.py:78  🔴 G26  bare `except:` swallows all — catch specific.
14 violations: 3🔴 6🟡 5🔵

Install

Project scope (recommended when experimenting):

cp -r skills/* .claude/skills/

Personal scope (available in every session):

cp -r skills/* ~/.claude/skills/

Symlink (for contributors — git pull keeps every skill current):

for d in skills/*/; do ln -sfn "$PWD/$d" "$HOME/.claude/skills/$(basename "$d")"; done

The verbs load the rulebook from the sibling uncle/ folder, so install the whole skills/* set together — a lone verb without uncle/ can't find its rules.

Verify it installed: ask Claude "What skills are available?" — you should see uncle, uncle-review, uncle-tidy, uncle-refactor, uncle-lint, and not the individual chapters (they're rulebook files now, not skills).

Plugin (for distribution): plugins/uncle-code/skills/ mirrors skills/ verbatim. No registered marketplace entry yet — install via the methods above.

Contributing

Three generated artifacts must stay in sync with the rulebook: AGENTS.md, .github/copilot-instructions.md, and the plugins/uncle-code/skills/ mirror. scripts/check-generated-files.sh verifies all three without touching your working tree; scripts/generate-agent-instructions.sh (regenerates the two flat files from skills/uncle/rulebook/*.md) and scripts/sync-plugin-mirror.sh (mirrors skills/) fix any staleness it finds.

Enable the pre-commit hook once per clone:

git config core.hooksPath scripts/hooks

CI (.github/workflows/check-generated-files.yml) runs the same check on every push and PR.

GitHub Copilot / Codex (or any agent that reads a flat instructions file): use AGENTS.md or .github/copilot-instructions.md. These don't support progressive disclosure, so they're a condensed single-file version of the rulebook — no per-language material, no verbs. Generated from skills/uncle/rulebook/*.md; re-run the generator after editing a rulebook file, and don't hand-edit the generated files.

Structure

uncle-code/
├── skills/
│   ├── uncle/                    # /uncle dispatcher + the rulebook
│   │   ├── SKILL.md
│   │   ├── scripts/
│   │   │   └── detect-language.sh
│   │   └── rulebook/             # nouns — loaded, never invoked
│   │       ├── rules.md          # flat C/E/F/G/N/T registry (single source of truth)
│   │       ├── names.md … concurrency.md   # 12 bare chapter files
│   │       └── references/<chapter>/<lang>.md
│   ├── uncle-review/  SKILL.md   # verbs
│   ├── uncle-tidy/    SKILL.md
│   ├── uncle-refactor/ SKILL.md
│   └── uncle-lint/    SKILL.md
├── plugins/uncle-code/           # plugin distribution mirror of skills/
├── scripts/                      # generate + sync + check
├── AGENTS.md                     # generated: condensed rulebook for Codex
├── .github/copilot-instructions.md  # generated: same, for Copilot
└── README.md

Each SKILL.md uses YAML frontmatter per the Anthropic spec. Rulebook files are plain markdown — bare rules, no ceremony — so a verb loads only what a given diff touches.

Why this shape

  • Verbs, not a noun-router. You call an action (review, tidy, refactor, lint), not a chapter. Chapters are reference material the verb pulls in — nobody types /uncle-comments.
  • One registry, cited everywhere. rules.md holds every N4/G14/F1 in Robert Martin's own Ch. 17 numbering — the single source of truth every verb and every chapter file resolves against.
  • Auto-detected language. detect-language.sh runs against the target repo; verbs load only matching references — a Go-only repo never sees Python idioms.
  • Six languages, honest coverage. Names and Functions have all six; Error Handling, Objects, and Concurrency have four; the rest are language-neutral. The gap is documented, not hidden.
  • Terse by default. One line per finding, rule ID inline — the output reads like git diff, not an essay.
  • Works outside Claude Code. The generator derives AGENTS.md and .github/copilot-instructions.md straight from the rulebook, so Codex and Copilot users get the same rules without a hand-maintained second copy.

About

Robert Martin's clean code skills practitioners

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors