Codemap Hooks for Claude Code

March 27, 2026 · View on GitHub

Turn Claude into a codebase-aware assistant. These hooks give Claude automatic context at every step - like GPS navigation for your code.

The Full Experience

WhenWhat Happens
Session startsClaude sees full project tree, hubs, branch diff, and last session context
After compactClaude sees the tree again (context restored)
You mention a fileClaude gets intent analysis, hub context, risk level, working set, and suggestions
Before editingClaude sees who imports the file AND what hubs it imports
After editingClaude sees the impact of what was just changed
Before memory clearsHub state is saved so Claude remembers what's important
Session endsTimeline of all edits + saves layered handoff artifacts for next agent/session

Quick Setup

Recommended (project-local hooks + config):

# install codemap (no repo clone needed)
brew tap JordanCoin/tap && brew install codemap

cd /path/to/your/project
codemap setup

Global Claude settings instead of project-local:

codemap setup --global

This command:

  • creates .codemap/config.json when 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.

Manual Hook JSON (advanced)

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)"

Project Config

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 config

Example .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 extensions
  • exclude — hides matching paths from the tree
  • depth — overrides the adaptive depth calculation
  • mode — optional hook orchestration hint (auto, structured, ad-hoc)
  • budgets — optional hook budgets (session_start_bytes, diff_bytes, max_hubs)
  • routing — prompt-submit routing hints (keyword strategy, top_k, subsystem definitions)
    • subsystems[].instructions — markdown instructions injected when this subsystem matches (e.g., domain-specific guidance for Claude)
  • drift — documentation drift detection
    • enabled — when true, prompt-submit checks if docs are stale relative to code changes
    • recent_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.


What Claude Sees

At Session Start (and after compact)

📍 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)

Before/After Editing a File

📍 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

When You Mention a File (Prompt Submit)

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.

Intent Categories

CategoryTriggered ByExtra Context
refactorrefactor, rename, move, extract, splitDependency checks, full test suite
bugfixfix, bug, broken, error, crashTest suggestions for affected package
featureadd, implement, create, new, buildHub impact if touching hub files
explorehow does, where is, what usesSubsystem routing suggestions
testtest, coverage, spec, benchmark-
docsdocument, readme, changelogDrift warnings if enabled

Risk Levels

LevelMeaning
lowNo hub files involved
medium1 hub file in scope
high2+ hub files, or a hub with 8+ importers

Working Set

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.

At Session End

📊 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

Next Session Start (Handoff Resume)

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)

Available Hooks

CommandClaude EventWhat It Shows
codemap hook session-startSessionStartFull tree, hubs, branch diff, last session context
codemap hook pre-editPreToolUse (Edit|Write)Who imports file + what hubs it imports
codemap hook post-editPostToolUse (Edit|Write)Impact of changes (same as pre-edit)
codemap hook prompt-submitUserPromptSubmitIntent classification, hub context, risk analysis, working set, route suggestions, drift warnings
codemap hook pre-compactPreCompactSaves hub state to .codemap/hubs.txt
codemap hook session-stopSessionEndEdit timeline + writes .codemap/handoff.latest.json, .codemap/handoff.prefix.json, .codemap/handoff.delta.json

Handoff Command

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 file

Why This Matters

Hub 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:

  1. Knows which files are hubs before touching them
  2. Sees the blast radius after making changes
  3. Remembers important files even after context compaction

Prerequisites

# 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@latest

Performance

Startup Latency

Session-start hook performance depends on whether the daemon is running:

StateLatencyWhat Happens
Daemon running, state fresh<100msReads .codemap/state.json from disk
Daemon running, state stale (>30s)<100msStill reads state (daemon is alive)
No daemon, small repo (<2000 files)200-500msStarts daemon + initial scan + dep graph
No daemon, medium repo (2000-5000)500ms-2sStarts daemon + scan (deps computed)
No daemon, large repo (>5000 files)500ms-1sStarts 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.

Context Budget

Hooks are budgeted to avoid context blowup:

HookTypical SizeCap
session-start4-8KB60KB hard cap
prompt-submit180-350 bytesSkill bodies not injected (pull-based)
pre/post-edit0-500 bytesOnly for files with importers
session-stop500-2KBLast 10 events
multi-repoVaries60KB total across all repos

The 8-second hook timeout prevents any single hook from blocking Claude.


Verify It Works

  1. Run codemap setup in your project
  2. Restart Claude Code (or start a new session)
  3. You should see project structure at the top
  4. Ask Claude to edit a core file - watch for hub warnings
  5. End your session and see the summary