For the first few weeks with Claude Code, I used it like an overqualified search engine paste an error, grab the snippet, fix whatever it broke, and repeat. It got the job done, but it felt like pairing with a brilliant junior dev who suffered total amnesia every time I cleared the terminal. After getting fed up with constantly correcting the same package manager slip-ups and component styles, I spent a weekend configuring our repo's context files and hooks so it would actually stop behaving like a complete stranger in the codebase.
Table of Contents
- CLAUDE.md: The Baseline
- Rules: Hard Guardrails over General Docs
- Custom Skills for Repetitive Prompts
- Hooks as an Automated Safety Net
- The Plan-Build-Verify Loop
- What Failed (And What to Avoid)
CLAUDE.md: The Baseline
The single highest-leverage change was dropping a minimal CLAUDE.md in the repo root. Don't write a novel here. Mine is around fifteen lines covering the core stack, package manager quirks, and test commands:
# Project Context
- Next.js (App Router), TypeScript, Tailwind CSS
- Package manager: pnpm (never use npm or yarn)
- Test runner: vitest
# Code Conventions
- Prefer React Server Components unless client interactivity is required
- Strict TypeScript: no explicit `any`
- Run `pnpm lint` before marking tasks complete
Before adding this, the CLI constantly hallucinated npm install flags in our pnpm workspace and defaulted to old class-based patterns. Putting this baseline in place eliminated about 80% of trivial corrections on day one.
Rules: Hard Guardrails over General Docs
Context files set the mood, but when you need strict constraints, separate rule files work much better. I keep short instructions inside .claude/rules/ that target specific recurring mistakes:
- Never touch database migration files directly without explicit user confirmation.
- Don't leave inline comments explaining what code does unless the logic is genuinely complex.
- Run existing test suites before and after modifying shared utility functions.
Every rule in that folder exists because the model burned me on something specific. If an instruction runs longer than two or three sentences, it belongs in documentation, not a rule.
Custom Skills for Repetitive Prompts
If you find yourself typing the same multi-step prompt every morning, turn it into a skill. Skills are essentially reusable markdown prompt recipes that the CLI triggers on command.
I set up a PR review skill (.claude/skills/review-pr.md) that systematically inspects git diffs, flags missing edge cases, checks error boundaries, and surfaces security red flags before pushing. Another small one formats commit messages following our team's conventional commit schema:
# Skill: conventional-commit
When generating a commit message:
1. Use conventional commit syntax (`feat:`, `fix:`, `refactor:`, `chore:`).
2. Keep the summary line under 50 characters, present tense.
3. Include a bulleted body explaining *why* the change was made if the diff spans multiple modules.
It saves only thirty seconds each time, but across fifty commits a week, that friction adds up.
Hooks as an Automated Safety Net
Hooks run commands automatically on specific lifecycle events—like pre-tool execution or right after a file edit.
I keep two active:
- Post-edit test runner: Automatically executes affected Vitest files after Claude edits them. If tests fail, it forces the model to diagnose and patch the break immediately instead of claiming success.
-
Formatter check: Runs
prettier --writeon touched files so diffs stay clean.
A quick word of caution: don't overbuild hooks. I initially chained five separate linters and build checks, only to spend half my afternoon debugging why the CLI was hanging on background tasks. Keep them dead simple.
The Plan-Build-Verify Loop
For multi-file refactors or new features, letting an agent blindly edit files across a repository is asking for merge conflicts. I set up a custom command (/loop-feature) that enforces a strict 4-stage loop:
- Plan: Scan the relevant directory, map dependencies, and draft a plain-text implementation plan.
- Review: I inspect the plan and tweak assumptions before a single line of code is written.
- Execute: Modify files incrementally, running tests after each file change.
- Summary: Print a concise diff breakdown and note any unresolved edge cases.
Catching flawed architectural assumptions during step 1 takes twenty seconds; debugging a half-broken state machine spread across eight files takes an hour.
What Failed (And What to Avoid)
- Dumping 800-line style guides into context: The model suffers context dilution and starts ignoring the critical instructions near the middle. Keep context tight and scannable.
- Overly broad philosophical rules: Directives like "always write pure functional code" choked on our legacy object-oriented modules. Rules must be pragmatic, not ideological.
- Giant prompt templates: Any skill description longer than a single screen ended up getting skipped or partially hallucinated.
Start with just a 15-line CLAUDE.md. Don't try to build an entire automation suite upfront—just add rules and hooks as you run into actual papercuts during your daily work. Over a couple of sprints, those small adjustments compound into an assistant that genuinely matches your engineering cadence.
What’s your go-to setup for keeping CLI coding assistants from drifting off-track? Have you experimented with project-level rules or automated hooks yet? Let me know in the comments below!
Note: The core setup, rules, and configurations in this post come directly from my own workflow experiments, but I used AI to help structure and polish the presentation.
Top comments (0)