169 lines
4.2 KiB
Markdown
169 lines
4.2 KiB
Markdown
# Exercise 02: Hierarchy in Action
|
|
|
|
**Concept:** CLAUDE.md (CC-010)
|
|
**Level:** Intermediate
|
|
**Time:** ~15 minutes
|
|
|
|
---
|
|
|
|
## Objective
|
|
|
|
See how global, project, and subdirectory CLAUDE.md files work together.
|
|
Claude reads all three and applies them simultaneously, with more specific
|
|
files taking precedence over broader ones.
|
|
|
|
Exercise 01 covered a single CLAUDE.md. This exercise shows the full stack.
|
|
|
|
---
|
|
|
|
## Before You Start
|
|
|
|
Confirm you have:
|
|
|
|
- [ ] Completed Exercise 01 (or understand what CLAUDE.md does)
|
|
- [ ] Claude Code open in this repo directory
|
|
|
|
**Important:** This exercise creates a file at `~/.claude/CLAUDE.md`, which
|
|
is your global Claude Code configuration. If you already have one, back it up first:
|
|
|
|
```bash
|
|
cp ~/.claude/CLAUDE.md ~/.claude/CLAUDE.md.bak
|
|
```
|
|
|
|
Restore it after the exercise with:
|
|
|
|
```bash
|
|
mv ~/.claude/CLAUDE.md.bak ~/.claude/CLAUDE.md
|
|
```
|
|
|
|
---
|
|
|
|
## Instructions
|
|
|
|
**Step 1:** Create a global CLAUDE.md with a personal preference.
|
|
|
|
This file applies to every project you open with Claude Code, everywhere.
|
|
|
|
```bash
|
|
mkdir -p ~/.claude
|
|
```
|
|
|
|
Then paste this prompt into Claude Code:
|
|
|
|
```
|
|
Create a file at ~/.claude/CLAUDE.md with exactly this content:
|
|
|
|
# Global Preferences
|
|
|
|
Always respond in British English. Use "colour" not "color",
|
|
"organise" not "organize", "realise" not "realize".
|
|
When writing prose, prefer shorter sentences.
|
|
```
|
|
|
|
**Step 2:** Create a project-level CLAUDE.md with a project rule.
|
|
|
|
This file applies only when Claude Code is open in this directory.
|
|
Paste this prompt:
|
|
|
|
```
|
|
Create a CLAUDE.md in the current directory (not ~/.claude/) with exactly this content:
|
|
|
|
# Project Rules
|
|
|
|
Language: TypeScript only. No JavaScript files.
|
|
Indentation: 2 spaces. No tabs.
|
|
Imports: named imports preferred over default imports.
|
|
```
|
|
|
|
**Step 3:** Create a subdirectory CLAUDE.md with test-specific rules.
|
|
|
|
```bash
|
|
mkdir -p tests
|
|
```
|
|
|
|
Then paste:
|
|
|
|
```
|
|
Create a file at tests/CLAUDE.md with exactly this content:
|
|
|
|
# Test Rules
|
|
|
|
Test framework: vitest only.
|
|
Pattern: describe/it blocks with descriptive names.
|
|
Assertions: use expect() with .toBe(), .toEqual(), or .toThrow().
|
|
No jest, no mocha, no chai.
|
|
```
|
|
|
|
**Step 4:** Ask Claude to create a function and a test, then observe.
|
|
|
|
Paste this prompt:
|
|
|
|
```
|
|
Write a TypeScript function called formatDate that takes a Date object
|
|
and returns a string in the format "DD Month YYYY" (e.g. "04 April 2025").
|
|
|
|
Then write a vitest test for it in tests/formatDate.test.ts.
|
|
```
|
|
|
|
Watch the output carefully. Claude should:
|
|
- Use TypeScript (project rule)
|
|
- Use 2-space indentation (project rule)
|
|
- Use named imports (project rule)
|
|
- Use vitest with describe/it (test rule)
|
|
- Write in British English where prose appears (global rule)
|
|
|
|
---
|
|
|
|
## Expected Output
|
|
|
|
After completing all four steps, you should see:
|
|
|
|
- A `formatDate.ts` file using TypeScript, 2-space indentation, named imports
|
|
- A `tests/formatDate.test.ts` file using vitest, describe/it pattern
|
|
- Any comments or prose Claude writes use British English spellings
|
|
- Claude did not ask which framework to use or what indentation to apply
|
|
|
|
**How you know hierarchy worked:**
|
|
All three levels applied at once. The test file followed both the project
|
|
rules (TypeScript, 2-space) AND the test-specific rules (vitest, describe/it).
|
|
The global preference (British English) applied throughout.
|
|
|
|
---
|
|
|
|
## What You Learned
|
|
|
|
- **Global scope:** `~/.claude/CLAUDE.md` applies to every project
|
|
- **Project scope:** `./CLAUDE.md` applies only in the current directory
|
|
- **Subdirectory scope:** `tests/CLAUDE.md` applies only when working in `tests/`
|
|
- **More specific overrides broader:** If a test-specific rule conflicts with
|
|
a project rule, the test-specific rule wins inside `tests/`
|
|
- **All levels apply simultaneously:** Claude does not choose one level.
|
|
It reads all of them and follows all of them
|
|
|
|
---
|
|
|
|
## Clean Up
|
|
|
|
```bash
|
|
rm -f CLAUDE.md formatDate.ts tests/CLAUDE.md tests/formatDate.test.ts
|
|
rmdir tests 2>/dev/null || true
|
|
```
|
|
|
|
And if you backed up your global CLAUDE.md:
|
|
|
|
```bash
|
|
mv ~/.claude/CLAUDE.md.bak ~/.claude/CLAUDE.md
|
|
```
|
|
|
|
Or remove the test global file if you created a fresh one:
|
|
|
|
```bash
|
|
rm ~/.claude/CLAUDE.md
|
|
```
|
|
|
|
---
|
|
|
|
## Next
|
|
|
|
Ready to take a bad CLAUDE.md and make it effective? Move to
|
|
[Exercise 03: Audit and Improve](./03-audit-and-improve.md).
|