| name | codemap-skill | |||||||
|---|---|---|---|---|---|---|---|---|
| description | Generates and maintains a layered codemap (table of contents) for large codebases, enabling agents to navigate efficiently without flooding context windows. Use when user says "codemap init", "generate codemap", "map this codebase", "codemap update", or when hook output contains "CODEMAP_UPDATE_NEEDED". | |||||||
| tools |
|
Generates a layered table of contents for a codebase so agents can navigate large projects without reading every file upfront.
This skill uses a two-layer approach to codebase navigation:
- Layer 0 (Always in context): A
<CODEMAP>block in CLAUDE.md containing a compact table of major areas with 1-line descriptions. Agents always know WHERE to look. - Layer 1 (On-demand): Detailed sub-documents in
.codemap/that break down each area with key files, patterns, and conventions. Agents read these when they need to work in a specific area. - Layer 2 (Source code): The actual files. Agents read these only when making changes.
The <CODEMAP> block is the entry point. It tells the agent what exists and where. The agent drills into .codemap/ sub-documents only when it needs deeper context for a specific area.
-
Scan the project structure. Run
lsat the project root. UseGlobto understand what's inside each top-level directory. -
Find the meaningful boundaries. Areas are the directories where distinct responsibilities live — not necessarily top-level directories. Many projects have a wrapper directory (
src/,lib/,packages/,apps/,internal/,cmd/) that is just a container, not an area itself. The agent must descend into containers to find the real boundaries.How to identify a container vs. an area:
- A container has a generic name (
src,lib,pkg,internal,cmd,packages,apps) AND contains multiple subdirectories with distinct purposes. Do not list it as an area — list its children instead. - An area has a specific name (
auth,billing,components) OR contains files that serve a single cohesive purpose, even if its name is generic.
Common project layouts and where areas live:
Layout Container Areas at Flat ( api/,models/,tests/)none top-level Standard ( src/api/,src/models/)src/src/*/Feature-based ( src/features/auth/,src/features/billing/)src/,src/features/src/features/*/Monorepo ( packages/api/,packages/web/)packages/packages/*/Go-style ( cmd/server/,internal/auth/)cmd/,internal/cmd/*/,internal/*/Mixed varies varies — use judgment The agent should produce areas at mixed depths when the project calls for it. For example, a Next.js app might have areas at
app/api/,components/,lib/auth/, andprisma/— all different depths. The path in the codemap table is the full relative path, not just one segment. - A container has a generic name (
-
Group into areas. For each area, read 2-3 representative files to understand its purpose. Focus on what a developer would need to know to navigate — not implementation details.
-
Determine area descriptions. Each description must be specific and useful. Good: "REST endpoints for user management, billing, and webhook ingestion." Bad: "API stuff." Include the key domains or responsibilities contained in each area.
-
Write the top-level codemap. Insert a
<CODEMAP>block into the project's CLAUDE.md. If CLAUDE.md does not exist, create it. If it already has content, append the codemap block — never overwrite existing content.Use this exact format:
<CODEMAP> Before working in an unfamiliar area, read its sub-map in `.codemap/` for file-level detail. | Area | Path | Description | |------|------|-------------| | {Area Name} | `{path}/` | {1-line description of what's here} | </CODEMAP> -
Generate sub-documents. For each area in the top-level table, create
.codemap/{area-slug}.mdwith this structure:# {Area Name} — `{path}/` {2-3 sentence overview of this area's responsibility and role in the system.} ## Structure | Path | Purpose | |------|---------| | `{relative-path}` | {what this file or subdirectory does} | ## Key Concepts - {important patterns, naming conventions, or architectural decisions} - {relationships to other areas} ## Entry Points - {main files a developer would start reading to understand this area}
If an area is large, the sub-document can reference further nested sub-documents (e.g.,
.codemap/backend/api.md). Use judgment on when to nest — the goal is that each document is useful on its own without being overwhelming. -
Add
.codemap/to.gitignoreunless the user explicitly wants to track it. The codemap is a generated artifact that can be regenerated. -
Install the post-tool-use hook. This enables automatic codemap updates when new files are created.
a. Create
.claude/hooks/codemap-hook.shby writing the contents ofscripts/post-edit-hook.shfrom this skill's install directory into the project. The agent can locate the script relative to this SKILL.md file, or if that path is unavailable, read the script content and write it directly. Make it executable withchmod +x.b. Add the PostToolUse hook to
.claude/settings.json. If the file already exists, merge into the existinghooksconfig — do not overwrite other hooks. If it does not exist, create it:{ "hooks": { "PostToolUse": [ { "matcher": "Write", "hooks": [ { "type": "command", "command": ".claude/hooks/codemap-hook.sh", "timeout": 10 } ] } ] } }c. Both
.claude/hooks/and.claude/settings.jsonshould be tracked in git so teammates get the hook automatically. Do not add them to.gitignore.
- Check that a
<CODEMAP>block exists in CLAUDE.md and.codemap/exists. If either is missing, inform the user and runcodemap initinstead. - Read the existing
<CODEMAP>block from CLAUDE.md. - Scan the current project structure.
- Compare against the codemap:
- New directories not in the codemap: add to the table, generate sub-documents.
- Removed directories: remove from the table, delete orphaned sub-documents.
- Changed areas (new or removed files): update the relevant sub-document.
- Do not reorganize areas that have not changed. Preserve existing descriptions unless they are now inaccurate.
When the post-tool-use hook detects a structural change, it outputs CODEMAP_UPDATE_NEEDED with the affected path. Handle this with a lightweight update:
- Parse the hook output to identify the affected file path.
- Determine which codemap area the file belongs to.
- If it belongs to an existing area: update only that area's sub-document in
.codemap/. - If it creates a new top-level area: add a row to the
<CODEMAP>table and generate a new sub-document. - Do NOT do a full rescan. Only update what changed.
- The
<CODEMAP>block is a high-level TOC, not an exhaustive listing. It should be scannable at a glance. Use judgment on how many entries make sense for the project — the goal is orientation, not completeness. - Sub-documents can nest. When an area is large enough that its sub-document would itself become unwieldy, break it into further sub-documents in a subdirectory (e.g.,
.codemap/backend/api.md,.codemap/backend/auth.md). There is no fixed depth limit — nest as deep as the codebase requires. - Never modify content outside the
<CODEMAP>tags in CLAUDE.md. Other content in CLAUDE.md belongs to the user. - Use relative paths from the project root in all codemap entries.
- Never map secrets or sensitive files. Do not include
.envfiles, credentials, API keys, private keys, tokens, or any file that could contain secrets — in the top-level table or in sub-documents. If an entire directory exists to hold secrets or credentials, omit it from the codemap entirely. - Skip ephemeral and generated content. Use judgment to exclude build artifacts, caches, compiled output, and dependency directories — not just the common ones (
node_modules/,dist/,build/, etc.) but anything that is generated, transient, or not human-authored source code. If you're unsure whether a directory is source or output, check for a build tool config that targets it. - Descriptions must be specific enough to help an agent decide whether to drill deeper. Generic labels like "utilities" or "helpers" must include what kind.
Input:
user: codemap init
Expected output in CLAUDE.md:
<CODEMAP>
Before working in an unfamiliar area, read its sub-map in `.codemap/` for file-level detail.
| Area | Path | Description |
|------|------|-------------|
| App Routes | `app/` | Next.js App Router pages: dashboard, auth flows, settings, and public marketing pages |
| API Routes | `app/api/` | REST endpoints for users CRUD, Stripe webhooks, file uploads, and team invitations |
| Components | `components/` | React components: ui primitives (Button, Modal, Input), feature widgets (UserCard, PlanSelector), and layout shells |
| Database | `prisma/` | Prisma schema with User, Team, Subscription, and Invoice models; migrations and seed scripts |
| Auth | `lib/auth/` | NextAuth.js config with Google and GitHub providers, session helpers, role-based access checks |
| Server Actions | `lib/actions/` | Form handlers for profile updates, team management, billing operations |
| Utilities | `lib/utils/` | Date formatters, currency helpers, Zod validation schemas, shared TypeScript types |
| Config | `config/` | Shared configuration: next.config.js, tailwind.config.ts, tsconfig.json, environment variable schemas |
</CODEMAP>
Expected sub-document .codemap/api-routes.md:
# API Routes — `app/api/`
REST API layer handling external integrations, user-facing CRUD operations, and webhook ingestion. All routes use Next.js Route Handlers with middleware for auth and rate limiting.
## Structure
| Path | Purpose |
|------|---------|
| `users/route.ts` | User CRUD — list, create, update, delete with pagination |
| `users/[id]/route.ts` | Single user operations — get, patch, delete by ID |
| `webhooks/stripe/route.ts` | Stripe webhook handler — subscription lifecycle events |
| `uploads/route.ts` | File upload to S3 with presigned URLs |
| `teams/route.ts` | Team management — create, list, invite members |
| `teams/[id]/members/route.ts` | Team member operations — add, remove, change role |
## Key Concepts
- All routes validate input with Zod schemas from `lib/utils/schemas.ts`
- Auth middleware applied via `lib/auth/middleware.ts` — checks session + role
- Stripe webhook route skips auth but validates webhook signature
- Error responses follow `{ error: string, code: string }` shape
## Entry Points
- `users/route.ts` — simplest CRUD example, good starting point for API patterns
- `webhooks/stripe/route.ts` — shows webhook signature validation patternHook output:
CODEMAP_UPDATE_NEEDED: src/services/notifications.ts was created
Expected behavior:
Agent checks if src/services/ is in the codemap. If yes, adds notifications.ts to .codemap/services.md. If src/services/ is a new area, adds a row to the <CODEMAP> table and creates .codemap/services.md.
Input:
user: codemap update
Expected behavior: Agent diffs the current directory structure against the existing codemap. Adds new areas, removes deleted ones, refreshes sub-documents for changed areas. Does not touch unchanged areas.
references/hook-setup.md— Instructions for configuring the post-tool-use hook in Claude Code settings