Turn Claude into a codebase-aware assistant. These hooks give Claude automatic context at every step - like GPS navigation for your code.
| When | What Happens |
|---|---|
| Session starts | Claude sees full project tree, hubs, branch diff, and last session context |
| After compact | Claude sees the tree again (context restored) |
| You mention a file | Claude gets intent analysis, hub context, risk level, working set, and suggestions |
| Before editing | Claude sees who imports the file AND what hubs it imports |
| After editing | Claude sees the impact of what was just changed |
| Before memory clears | Hub state is saved so Claude remembers what's important |
| Session ends | Timeline of all edits + saves layered handoff artifacts for next agent/session |
Recommended (project-local hooks + config):
# install codemap (no repo clone needed)
brew tap JordanCoin/tap && brew install codemap
cd /path/to/your/project
codemap setupGlobal Claude settings instead of project-local:
codemap setup --globalThis command:
- creates
.codemap/config.jsonwhen missing - inserts codemap hook commands into Claude settings (without removing existing hooks)
- keeps hook setup idempotent (safe to run more than once)
Important: run codemap setup from the git repo root. Hook commands run relative to the current working directory; starting Claude from a nested folder can prevent codemap from finding .git and .codemap.
If you want to manage Claude settings manually, add this hooks object to .claude/settings.local.json (or ~/.claude/settings.json):
{
"hooks": {
"SessionStart": [
{
"hooks": [
{
"type": "command",
"command": "codemap hook session-start"
}
]
}
],
"PreToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "codemap hook pre-edit"
}
]
}
],
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "codemap hook post-edit"
}
]
}
],
"UserPromptSubmit": [
{
"hooks": [
{
"type": "command",
"command": "codemap hook prompt-submit"
}
]
}
],
"PreCompact": [
{
"hooks": [
{
"type": "command",
"command": "codemap hook pre-compact"
}
]
}
],
"SessionEnd": [
{
"hooks": [
{
"type": "command",
"command": "codemap hook session-stop"
}
]
}
]
}
}Restart Claude Code. You should immediately see project context at session start.
If you intentionally run Claude from subdirectories, pass the repo root explicitly:
codemap hook session-start "$(git rev-parse --show-toplevel)"Hooks automatically respect .codemap/config.json when present. This lets you filter what Claude sees at session start without replacing the hook command.
codemap config init # Auto-detect top extensions and create config
codemap config show # View current configExample .codemap/config.json:
{
"only": ["rs", "sh", "sql", "toml", "yml"],
"exclude": ["docs/reference", "docs/research"],
"depth": 4,
"mode": "auto",
"budgets": {
"session_start_bytes": 30000,
"diff_bytes": 15000,
"max_hubs": 8
},
"routing": {
"retrieval": { "strategy": "keyword", "top_k": 3 },
"subsystems": [
{
"id": "watching",
"paths": ["watch/**"],
"keywords": ["hook", "daemon", "events"],
"docs": ["docs/HOOKS.md"],
"agents": ["codemap-hook-triage"],
"instructions": "This subsystem manages file watching. Check daemon state before modifying events."
}
]
},
"drift": {
"enabled": true,
"recent_commits": 10,
"require_docs_for": ["watching"]
}
}All fields are optional. When set:
only— session-start tree shows only files with these extensionsexclude— hides matching paths from the treedepth— overrides the adaptive depth calculationmode— optional hook orchestration hint (auto,structured,ad-hoc)budgets— optional hook budgets (session_start_bytes,diff_bytes,max_hubs)routing— prompt-submit routing hints (keywordstrategy,top_k, subsystem definitions)subsystems[].instructions— markdown instructions injected when this subsystem matches (e.g., domain-specific guidance for Claude)
drift— documentation drift detectionenabled— when true, prompt-submit checks if docs are stale relative to code changesrecent_commits— how far back to look in git history (default: 10)require_docs_for— subsystem IDs whose documentation freshness should be checked
CLI flags (--only, --exclude, --depth) always override config values. The bare codemap command also respects this config.
📍 Project Context:
╭────────────────────────────── myproject ──────────────────────────────╮
│ Files: 85 | Size: 1.2MB │
│ Top Extensions: .go (25), .yml (22), .md (10), .sh (8) │
╰───────────────────────────────────────────────────────────────────────╯
myproject
├── cmd/
│ └── hooks hooks_test
├── render/
│ └── colors depgraph skyline tree
├── scanner/
│ └── astgrep deps filegraph types walker
└── main.go go.mod README.md
⚠️ High-impact files (hubs):
⚠️ HUB FILE: scanner/types.go (imported by 10 files)
⚠️ HUB FILE: scanner/walker.go (imported by 8 files)
📝 Changes on branch 'feature-x' vs main:
M scanner/types.go (+15, -3)
A cmd/new_feature.go
🕐 Last session worked on:
• scanner/types.go (write)
• main.go (write)
• cmd/hooks.go (create)
📍 File: cmd/hooks.go
Imported by 1 file(s): main.go
Imports 16 hub(s): scanner/types.go, scanner/walker.go, watch/daemon.go...
Or if it's a hub:
⚠️ HUB FILE: scanner/types.go
Imported by 10 files - changes have wide impact!
Dependents:
• main.go
• mcp/main.go
• watch/watch.go
... and 7 more
The prompt-submit hook now performs intent classification — it analyzes what you're trying to do and surfaces relevant code intelligence.
<!-- codemap:intent {"category":"refactor","confidence":1,"risk":"high",...} -->
📍 Context for mentioned files:
⚠️ scanner/types.go is a HUB (imported by 10 files)
💡 Suggestions (risk: high):
• [review-hub] scanner/types.go — hub file imported by 10 files — changes have wide impact
• [check-deps] scanner/types.go — verify dependents still compile after changes
• [run-tests] . — run full test suite after refactoring
<!-- codemap:routes [{"id":"scanning","score":3,"docs":["docs/MCP.md"]}] -->
📚 Suggested context routes:
• scanning (score=3) docs=docs/MCP.md
🔧 Working set: 3 files (1 hubs)
• scanner/types.go (5 edits, +15 lines ⚠️HUB)
• cmd/hooks.go (3 edits, +42 lines)
📊 Session so far: 5 files edited, 2 hub edits
Structured markers (<!-- codemap:intent -->, <!-- codemap:routes -->) are machine-readable JSON that tools can parse. The human-readable output is always shown alongside them.
| Category | Triggered By | Extra Context |
|---|---|---|
refactor |
refactor, rename, move, extract, split | Dependency checks, full test suite |
bugfix |
fix, bug, broken, error, crash | Test suggestions for affected package |
feature |
add, implement, create, new, build | Hub impact if touching hub files |
explore |
how does, where is, what uses | Subsystem routing suggestions |
test |
test, coverage, spec, benchmark | - |
docs |
document, readme, changelog | Drift warnings if enabled |
| Level | Meaning |
|---|---|
low |
No hub files involved |
medium |
1 hub file in scope |
high |
2+ hub files, or a hub with 8+ importers |
The working set tracks files you've edited during the current session. It shows edit count, net line delta, and hub status — giving Claude awareness of your active work context.
📊 Session Summary
==================
Edit Timeline:
14:23:15 WRITE scanner/types.go +15 ⚠️HUB
14:25:42 WRITE main.go +3
14:30:11 CREATE cmd/new_feature.go +45
Stats: 8 events, 3 files touched, +63 lines, 1 hub edits
🤝 Saved handoff to .codemap/handoff.latest.json
If a recent handoff exists for the current branch, session start includes a compact resume block:
🤝 Recent handoff:
Branch: feature-x
Base ref: main
Changed files: 6
Top changes:
• cmd/hooks.go
• mcp/main.go
Risk files:
⚠️ scanner/types.go (10 importers)
| Command | Claude Event | What It Shows |
|---|---|---|
codemap hook session-start |
SessionStart |
Full tree, hubs, branch diff, last session context |
codemap hook pre-edit |
PreToolUse (Edit|Write) |
Who imports file + what hubs it imports |
codemap hook post-edit |
PostToolUse (Edit|Write) |
Impact of changes (same as pre-edit) |
codemap hook prompt-submit |
UserPromptSubmit |
Intent classification, hub context, risk analysis, working set, route suggestions, drift warnings |
codemap hook pre-compact |
PreCompact |
Saves hub state to .codemap/hubs.txt |
codemap hook session-stop |
SessionEnd |
Edit timeline + writes .codemap/handoff.latest.json, .codemap/handoff.prefix.json, .codemap/handoff.delta.json |
Use handoff directly when switching between agents:
codemap handoff . # build + save handoff
codemap handoff --latest . # read latest saved handoff
codemap handoff --json . # JSON payload for tooling
codemap handoff --prefix . # stable prefix layer only
codemap handoff --delta . # dynamic delta layer only
codemap handoff --detail a.go . # lazy-load full detail for one changed fileHub files are imported by 3+ other files. When Claude edits them:
- More code paths are affected
- Bugs ripple further
- Tests may break in unexpected places
With these hooks, Claude:
- Knows which files are hubs before touching them
- Sees the blast radius after making changes
- Remembers important files even after context compaction
# macOS/Linux
brew tap JordanCoin/tap && brew install codemap
# Windows
scoop bucket add codemap https://github.com/JordanCoin/scoop-codemap
scoop install codemap
# Go
go install github.com/JordanCoin/codemap@latestSession-start hook performance depends on whether the daemon is running:
| State | Latency | What Happens |
|---|---|---|
| Daemon running, state fresh | <100ms | Reads .codemap/state.json from disk |
| Daemon running, state stale (>30s) | <100ms | Still reads state (daemon is alive) |
| No daemon, small repo (<2000 files) | 200-500ms | Starts daemon + initial scan + dep graph |
| No daemon, medium repo (2000-5000) | 500ms-2s | Starts daemon + scan (deps computed) |
| No daemon, large repo (>5000 files) | 500ms-1s | Starts daemon + scan (deps skipped) |
The daemon is started automatically on session-start and persists across prompts. Subsequent hooks read from the cached state file, so only the first hook invocation pays the startup cost.
Hooks are budgeted to avoid context blowup:
| Hook | Typical Size | Cap |
|---|---|---|
| session-start | 4-8KB | 60KB hard cap |
| prompt-submit | 180-350 bytes | Skill bodies not injected (pull-based) |
| pre/post-edit | 0-500 bytes | Only for files with importers |
| session-stop | 500-2KB | Last 10 events |
| multi-repo | Varies | 60KB total across all repos |
The 8-second hook timeout prevents any single hook from blocking Claude.
- Run
codemap setupin your project - Restart Claude Code (or start a new session)
- You should see project structure at the top
- Ask Claude to edit a core file - watch for hub warnings
- End your session and see the summary