---
name: map-codebase
description: Analyzes the project codebase and builds a detailed code-map.md organized by feature flow. Shows entry point → routing → logic → DB for every major feature. Run once to bootstrap navigation; re-run after major structural changes. Triggers on "map the codebase", "build code map", "create code map", "map my project", "analyze codebase structure", "create a roadmap of the code", "where does everything live".
allowed-tools: Read, Grep, Glob, Write, Bash
---

# Skill: map-codebase

**Purpose:** Scan the codebase, identify all major features/flows, and produce a `code-map.md` that traces each feature from entry point → routing → logic → DB. Makes any codebase immediately navigable without grepping.

---

## Trigger Phrases
- "map the codebase"
- "build code map" / "create code map"
- "map my project"
- "analyze codebase structure"
- "create a roadmap of the code"
- "where does everything live"

---

## Steps

### Step 1 — Detect Tech Stack
Glob and read top-level files to identify the stack and project layout:

```
Glob("**/{package.json,pom.xml,build.gradle,requirements.txt,setup.py,*.sln,web.xml}", limit=20)
```

Then read the top-level directory listing to understand the folder structure. Identify:
- **Language:** Java, JavaScript/Node, Python, .NET, Go, Ruby, etc.
- **Frontend type:** HTML + vanilla JS, React, Vue, JSP templates, etc.
- **Routing pattern:** Servlet if/else chain, Express routes, Django urlpatterns, Flask decorators, Rails routes
- **DB access pattern:** Raw SQL, JPA/Hibernate, Sequelize, SQLAlchemy, ActiveRecord

### Step 2 — Find Entry Points
Scan for where requests come in:

| Stack | Where to look |
|---|---|
| Java Servlet | `*Webservice.java`, `*Controller.java`, routing `if/else` chains |
| Express/Node | `routes/`, `app.get(`, `router.post(` |
| Django/Flask | `urls.py`, `@app.route(`, `urlpatterns` |
| Rails | `routes.rb`, `config/routes.rb` |
| HTML pages | Glob `**/*.html` — each page is a user entry point |

Also look for:
- API spec files (`openapi.yaml`, `swagger.json`) — pre-mapped routes
- URL pattern files (`.claude/rules/url-patterns.md` if it exists)

### Step 3 — Find Major Logic Files
Identify the heavy files that contain most of the business logic:

```
Bash: find files > 300 lines
Grep: look for files imported/required by many others
```

Files > 500 lines in services/, utils/, jobs/, lib/ are almost always key logic files. Read their method list (grep for `public `, `def `, `function `, `const .*=.*=>`) to understand their surface area.

### Step 4 — Find DB Access
```
Grep: "FROM ", "INSERT INTO", "UPDATE ", "CREATE TABLE" → extract table names
Grep: "models.Model", "@Entity", "@Table", "Schema(" → extract model names
Glob: "migrations/", "*.sql", "*_install.sql", "*schema*" → schema files
```

Build a list of all DB tables/models referenced in the logic files.

### Step 5 — Identify Feature Groups
Group entry points + logic + DB by feature domain. Look for naming patterns:
- `user`, `auth`, `login`, `session` → Auth/User flow
- `order`, `cart`, `checkout`, `payment` → Commerce flow
- `admin`, `dashboard`, `manage` → Admin flow
- `course`, `lesson`, `session`, `email`, `scheduler` → Course/content flow
- `api`, `webhook`, `export` → Integration flow

Aim for 5–15 feature groups depending on codebase size. Don't try to map every file — focus on the flows a developer actually needs to navigate.

### Step 6 — Trace Each Flow
For each identified feature group, read 2–3 key files to trace the full chain. Document:

```
Entry (URL / route / page)
  → Frontend (HTML element / JS function)
  → Endpoint / Route handler
  → Service / Logic method [file:approxLine]
  → DB tables read/written
```

Use `Grep` for function names and `Read` with `offset` to confirm logic without loading whole files.

### Step 7 — Build the Line Reference
For the 1–2 largest logic files (the ones developers will need to navigate most), build a method → line number table:

```
Grep: "public |def |function |  async " in the file → capture method names + line numbers
```

This is the highest-value part of the map for large files (500+ lines).

### Step 8 — Write `code-map.md`
Write to `.claude/rules/code-map.md` (create `.claude/rules/` if it doesn't exist).

**Format:**
```markdown
# [Project Name] — Code Map
> Generated by map-codebase. Re-run after major structural changes.
> `[Abbreviation]` = `path/to/main/logic/file`

---

## [Feature Name]
- **Entry** `URL or route`
- **Frontend** `file.js` → `functionName()` → `callbackName()`
- **Endpoint** `routeName` → `HandlerClass.method()`
- **Logic** `ServiceClass.method()` [L####]
- **DB** tables/models read and written

## [Feature Name 2]
...

---

## Key File Paths
| Layer | Path |
|---|---|
| [description] | `path/to/file` |

---

## [MainLogicFile] — Line Reference
| Method | Line | Purpose |
|---|---|---|
| `methodName` | #### | one-line description |
```

### Step 9 — Wire Into CLAUDE.md
Ask the user: **"Add `@rules/code-map.md` to CLAUDE.md so it auto-loads each session?"**

If yes: Edit `.claude/CLAUDE.md` to add `@rules/code-map.md` in the `@rules/` block.

If no: Tell them they can read it manually anytime or re-run `map-codebase` to refresh it.

---

## Notes
- **Line numbers drift** — they're navigation hints, not guarantees. The function names are what matters.
- **Focus on the dominant paths** — a flow that's touched in 10 places is more important than one that's touched in 1.
- **Largest logic files first** — if one file has 5000+ lines, the line reference table for that file is worth more than tracing all the smaller flows.
- **Re-run when:** new major feature added, large refactor done, new developer joining.
- **Lite version:** if the codebase is very large (50+ files), do Step 7 only for the top 2 files and summarize the rest as a file-path table.
