An interactive cartographer's atlas of your Claude Code setup. It scans ~/.claude and renders every skill, slash command, subagent, MCP server, and hook as an antique map — colour-coded by kind, inked by how recently you've used each one.
- Inventory of all your servitors (skills, commands, subagents, MCPs, hooks) across global, plugin, and project scopes.
- Heat — recency tiers (
hot≤7d,warm≤30d,cool≤90d,stale,none) derived from your transcript history, rendered as ink density. - Contested names — invocation tokens that resolve to two or more implementations (e.g. a global skill
verifyand a plugin command/verify). - Frayed lines — declared wiring whose far end doesn't exist: hook scripts that are missing,
allowed-toolsbinaries not on PATH, unresolved@imports, and/plugin:commandmentions that resolve to nothing known. - Invocation marks — user-invoked only drawn as
/name(disable-model-invocation: true), ✳ model-invoked only (user-invocable: false), scraped from skill/command frontmatter. - Regional plates — one map plate per workspace region, with a project card per project sorted by activity.
- The Astrolabe (Ctrl+K) — a sighting instrument: type to fuzzy-find any servitor, project, region or plate; Enter sails the page to it and flashes the target.
Each region of your filesystem gets its own plate. Every project card lists its local skills, commands, hooks, and MCPs, inked by heat (names below are fictitious):
Derived findings — what the map says once you stop reading it as a map: never-invoked servitors ranked by source (prune candidates), invocation concentration, contested names, and frayed lines (names below are fictitious):
Requires Node ≥ 20.
# Serve the live atlas (rebuilds on each refresh)
npx @lttr/claude-code-map
# → http://127.0.0.1:7777/Render once to a static HTML file:
npx @lttr/claude-code-map --out atlas.html| Flag | Default | Description |
|---|---|---|
-p, --port N |
7777 |
Server port |
--host HOST |
127.0.0.1 |
Bind host |
-o, --out FILE |
— | Render once to FILE (no server) |
-h, --help |
— | Show help |
src/collect.tswalks~/.claude(config dirs, plugin installs, JSONL transcripts) and builds the inventory plus usage stats.src/render.tsturns that into atlas HTML fragments.bin/cli.tseither serves them over HTTP or writes a single self-contained page.
The atlas speaks in a cartographer's voice. Shared vocabulary (servitor, plate, heat, landmark, contested name, …) lives in GLOSSARY.md.
Requires Node ≥ 23.6 (dev mode runs the TypeScript sources directly via native type stripping).
pnpm install
pnpm run dev # serve with watch/restart
pnpm run check # format + lint + typecheck
pnpm run build # emit plain-JS package to dist/Browser-side code lives in src/client/*.ts and is inlined into the page, not linked. src/shell.html carries <!-- script:name --> markers; src/inline-scripts.ts replaces each with an inline <script> whose body is the matching client file — pre-stripped .js when present (the published build), otherwise the .ts source stripped on the fly via Node's stripTypeScriptTypes. Stripping is blank-preserving, so devtools line numbers match the TS source.
Why not a bundler or plain <script src> links: --out must emit one self-contained file, so the inliner has to exist regardless — linking would only add a second delivery mechanism (script routes plus a second shell variant) whose sole benefit, browser caching, is worthless for a localhost tool. The constraint is that client scripts stay dependency-free vanilla TS: no imports, no npm packages. If they ever need those, swap loadClientScript for an esbuild call; the marker seam stays.
Commit messages follow conventional commits (feat: …, fix(scope): …), consumed by changelogen for versioning and the changelog.
pnpm run releaseRuns checks, bumps the version from commit history, writes CHANGELOG.md, commits, tags, pushes, and publishes to npm (the build runs via prepack).


