Codemap — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited Codemap (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Local-first code intelligence that gives AI agents and people structural awareness of codebases — combining a code graph (LSP + parsers) with semantic vector search (veclite), exposed through a CLI, an MCP server, and an interactive terminal UI.
Working on the code? Read AGENTS.md first — it is the source of truth for conventions, architecture, and gotchas.
codemap answers questions that grep and a single LSP call can't: who calls this function and which tests cover it, what's the blast radius of changing this type, find auth-like code and then show me everything that calls into it. It precomputes the structure once, then serves narrow, structured answers — so an agent spends a few tool calls instead of dozens of file reads.
(name-based by default, exact via go/types with --precise) and defines edges (file → symbol). Test coverage is derived by walking the call graph to test nodes. Stored in pure-Go SQLite, queryable offline. Indexes Go (stdlib go/parser, full call graph), TypeScript + JavaScript (one typescript-language-server, calls resolving across the .ts↔.js boundary), and Python (pyright-langserver) — the LSP-backed languages give symbols + structure always, plus a precise call graph under --precise, so callers/impact/hotspots/path work for them too. Structure-only markup (Vue/HTML/CSS/Docker) is next. Semantic search is language-agnostic.
nomic-embed-text, 768-dim)into veclite; vector + BM25 hybrid search.
impact returns a symbol's definition sites, direct callers, thetransitive blast radius (everything affected by a change), and which tests cover those paths (flagging untested code).
context <symbol> bundles definition + callers + callees +tests + blast radius in one call (no four-round-trip stitching), and status reports index freshness (files changed since indexing) so an agent reindexes before trusting a stale answer.
projects lists what'sindexed, and any query targets one project (resolved from cwd, or --path).
findings, …) to a symbol or a call path; they persist across reindex. A knowledge layer over the graph for agent harnesses (annotate / annotations, also on MCP).
(x.Close() links to every Close). One codemap index --precise resolves each call to the one it actually invokes and makes every query — callers, callees, impact, hotspots, path — exact at once, no per-query flag (e.g. a Close method that name-matching credited with 71 callers shows only its real ones). It's the unified exact-resolution pass across languages: an in-process, pure-Go go/types pass for Go, and the language server's callHierarchy for the LSP languages (TypeScript, JavaScript, Python — which have no name-based call edges, so --precise is what gives them a call graph at all). Opt-in and additive (name-based stays the default for Go); the Go pass degrades to name-based with a note when the go toolchain or module isn't available. For a one-off exact answer without reindexing, callers/callees also take --lsp (gopls callHierarchy). CLI + MCP.
provider/model/dimension changes instead of corrupting the vector space.
--json for agents), a stdio **MCPserver, and the studio** TUI for humans.
hotspots (hubs), orphans (dead-code candidates), and path(shortest call path between two symbols).
CGO_ENABLED=0, cross-compiled and shipped via Homebrew.codemap studio opens an interactive, full-screen explorer of your code (Charm v2 — Bubble Tea / Lip Gloss / Bubbles). Switch tabs with 1–4 or tab; navigate with ↑/↓.
codemap studio codemap · 509 nodes · 1849 edges · 35 files
1 Graph 2 Metrics 3 Impact 4 Search
Hubs (164) │ lspsrc.Extractor.Close
57 lspsrc.Extractor.Close │ Called by (57)
56 app.Session.Close │ ▸ main.runInit cmd/codemap/main.go:186
56 graph.Store.Close │ main.runIndex cmd/codemap/main.go:209
26 app.NewService │ Calls (9)
19 app.Open │ app.Session.Close internal/app/session.go:80
▼ 159 more │ ⟩ func runInit(cmd *cobra.Command, ...) error
↑/↓ hub · → walk · enter → impact · s source · p precise · ctrl+c quit · ? helpFully-qualified names disambiguate same-named symbols (six different Close methods above), and the selected node's signature is previewed (⟩ func runInit(...)).
points, the centered node's callers and callees on the right. Press → to focus the right pane and walk the graph — enter re-centers on a caller/callee so you can traverse the call chain; backspace steps back; s reads the selected symbol's source in a scrollable overlay, without leaving studio.
the call graph's two extremes on the right — top hubs (most-referenced) and dead-code candidates (no callers). Both lists are navigable — enter drills a row into Impact, ctrl+s reads its source.
embeddings (so it works even without Ollama).
brew install abdul-hamid-achik/tap/codemapollama pull nomic-embed-text (optional — without it, indexing is structure-only)
--lsp precise Go resultsLanguages — structure + semantic search work for all of these; a precise call graph (callers/callees/impact/hotspots/path) needs --precise:
| Language | How | Extensions | Call graph |
|---|---|---|---|
| Go | built-in go/parser (+ go/types for --precise) | .go | name-based by default; exact with --precise |
| TypeScript / JavaScript | typescript-language-server (one server, JSX/TSX-aware, resolves across the .ts↔.js boundary) | .ts .tsx .js .jsx .mjs .cjs | --precise only |
| Python | pyright-langserver | .py | --precise only |
The language servers auto-enable when installed — run codemap doctor to see which are detected, or --no-lsp to skip. Structure-only markup (Vue/HTML/CSS) is planned; other recognized languages are reported as skipped. Semantic search is language-agnostic.
git clone https://github.com/abdul-hamid-achik/codemap
cd codemap
task build # → ./bin/codemap (or: go build ./cmd/codemap)go install github.com/abdul-hamid-achik/codemap/cmd/codemap@latest# 1. Register and index a project
codemap init # registers the current directory
codemap index # extract graph + embed nodes (incremental)
codemap index --no-embed # structure only (no Ollama needed)
codemap index --precise # exact call edges (Go via go/types; TS/JS/Python via callHierarchy)
# Indexes your code, not your dependencies: node_modules, venv, vendor, dist, build,
# __pycache__, .git (and any dotdir) are skipped by default — configurable via `exclude`.
# 2. Orient on a symbol — everything in one call (definition, callers, callees, tests)
codemap context authenticateUser # the one-call overview (agents: codemap_context)
# 3. Navigate the call graph
codemap callers authenticateUser # who calls it (fast, name-based)
codemap callers authenticateUser --lsp # exact callers via gopls (Go)
codemap callees authenticateUser # what it calls
codemap path Handler Login # shortest call path between two symbols
# 4. Analyze impact and structure
codemap impact authenticateUser --depth 3 # callers + blast radius + tests
codemap hotspots --top 20 # most-referenced symbols (hubs)
codemap orphans # functions with no callers (dead-code candidates)
codemap status # stats + warns if the index is stale vs your files
# 5. Search by meaning (needs an embedded index)
codemap semantic "jwt validation middleware" --top 10
# 6. Explore visually
codemap studioAdd --json to any query command for machine-readable output (for agents/scripts).
The flagship impact answers what breaks if I change this, and what do I run to check? in one call (real output, from codemap on itself):
$ codemap impact BlastRadius --depth 2
Impact of BlastRadius (codemap)
defined: internal/graph/queries.go:140
direct callers: 3
blast radius: 11 (depth ≤ 2)
tests covering: 6
covering tests (run these):
graph.TestBlastRadius internal/graph/graph_test.go:305
graph.TestBlastRadiusCycleSafe internal/graph/graph_test.go:347
app.TestQueryResultsCarrySignature internal/app/app_test.go:175
app.TestImpactSurfacesAnnotations internal/app/app_test.go:343
app.TestImpactWarnsOnAmbiguousName internal/app/app_test.go:1250
app.TestServiceImpact internal/app/app_test.go:1427
affected (blast radius):
[1] app.Service.Impact internal/app/service.go:983
✓ [1] graph.TestBlastRadius internal/graph/graph_test.go:305
✓ [1] graph.TestBlastRadiusCycleSafe internal/graph/graph_test.go:347
[2] main.runImpact cmd/codemap/main.go:572
✓ [2] app.TestQueryResultsCarrySignature internal/app/app_test.go:175
✓ [2] app.TestImpactSurfacesAnnotations internal/app/app_test.go:343
✓ [2] app.TestImpactWarnsOnAmbiguousName internal/app/app_test.go:1250
✓ [2] app.TestServiceImpact internal/app/app_test.go:1427
[2] app.Service.Context internal/app/service.go:1322
[2] mcp.Server.handleImpact internal/mcp/server.go:320
[2] tui.Model.impactCmd internal/tui/model.go:522Long lists are capped for readability (the nearest blast-radius nodes and the first covering tests, with a … (N more) line); --json always carries the complete set.
| Command | What it does |
|---|---|
init / index / status | register, index (incremental; --reindex, --no-embed, --no-lsp, --precise), show stats |
doctor | check the environment — toolchains, language servers, embeddings — with install hints |
projects | list all registered projects and their index sizes |
callers / callees / path | call-graph navigation (--lsp on callers/callees for exact gopls results) |
symbols | list a file's symbols (structured alternative to reading it) |
find | find symbols by name (offline) |
source | print a symbol's source code (the body behind its signature) |
context | one call, everything about a symbol: definition, callers, callees, covering tests, blast radius, notes |
docs | print the agent guide to codemap (docs [topic]) |
annotate / annotations | pin / list notes + external data on a symbol or call path |
impact | blast radius + test coverage for a symbol (--depth) |
hotspots / orphans | hubs / dead-code candidates (--top) |
semantic (alias search) | meaning-based search (--top) |
serve | run the MCP server (stdio) |
studio | open the interactive TUI |
All query commands accept --json.
codemap's graph is name-based by default — instant, offline, and tolerant of broken code. It resolves calls within a package precisely (Go), but a cross-package method call like x.Close() links to every method named Close, because resolving the receiver's type needs a type-checker. codemap is honest about this rather than hiding it: callers/callees/impact flag when a name resolves to multiple definitions, and hotspots marks name-collision inflation.
For an exact graph, reindex with `codemap index --precise` (Go). It runs an in-process, pure-Go go/types pass that resolves every call to the one method it actually invokes and replaces the name-based call edges — so every query (callers, callees, impact, hotspots, path) becomes precise at once, with no per-query flag. On the codemap repo itself this collapses the Close/Error fan-out (e.g. one Close method that name-matching credited with 71 callers drops to its real ~12) and turns hotspots from name-collision noise into genuine hubs. Requirements and guarantees:
go toolchain and a buildable module. A package that doesn't type-check keeps itsname-based edges (per-package degrade); a project with no go/go.mod falls back wholesale with a note — never a hard error, and never worse than name-based.
--precise, indexing is byte-for-byte the fast name-based path.the concrete implementors.
*For TypeScript, `--precise` is the only source of call edges.* The name-based pass extracts TS structure (classes, methods, functions) but not calls, so a plain index gives TS no call graph; index --precise drives typescript-language-server callHierarchy to resolve them exactly, and the same callers/callees/impact/hotspots/path queries then work for TS with no flag of their own. Needs typescript-language-server on PATH.
For a one-off exact answer without reindexing, callers/callees also accept --lsp (gopls callHierarchy), which likewise degrades to name-based with a note when gopls can't resolve.
orphans finds call-graph dead ends. It follows functions wired by value — handlers in a table like cobra's RunE: runInit, callbacks passed to a registrar — and excludes methods that implement well-known stdlib interfaces (error, fmt.Stringer, Unwrap, the JSON/text marshalers), so those aren't flagged as dead (Go). It still can't see callers reached via custom interface dispatch or reflection, so treat its output as candidates, not proof.
codemap is a stdio MCP server. Register codemap serve with your agent — most CLIs have a one-liner:
claude mcp add codemap -- codemap serve # Claude Code (add --scope user for all projects)
codex mcp add codemap -- codemap serve # OpenAI Codex
copilot mcp add codemap -- codemap serve # GitHub Copilot CLIFor any other MCP client, add a stdio server to its config (the key may be mcpServers, mcp, or context_servers):
{
"mcpServers": {
"codemap": { "command": "codemap", "args": ["serve"] }
}
}Once connected, an agent can call codemap_docs to learn the tools and workflow on its own.
Tools (20): codemap_init, codemap_index, codemap_status, codemap_doctor, codemap_semantic, codemap_callers, codemap_callees, codemap_impact, codemap_hotspots, codemap_orphans, codemap_path, codemap_symbols, codemap_find, codemap_source, codemap_context, codemap_projects, codemap_docs, codemap_annotate, codemap_annotations, codemap_unannotate. Each takes an optional path (the project directory) and returns JSON. The two an agent reaches for first: `codemap_context <symbol>` bundles a symbol's definition, callers, callees, covering tests and blast radius in one call (instead of four), and `codemap_status` reports index freshness — a stale count of files changed/added/removed since indexing, so the agent knows to reindex before trusting results. codemap_callers / codemap_callees accept precise: true for exact, gopls-resolved results (Go); codemap_source returns a symbol's body; codemap_projects lists what's indexed; `codemap_docs` returns an agent guide so a harness can learn the tool; `codemap_annotate` / `codemap_annotations` pin notes and external data (DB rows, findings) to symbols and call paths — a knowledge layer over the graph (see below).
Results carry each symbol's signature (e.g. func (s *Store) Hotspots(projectID int64, limit int) ([]Hotspot, error)) and docstring, so an agent understands what callers/callees/hits are and what they do without a follow-up file read — and same-named symbols are easy to tell apart.
The flagship is codemap_impact — one call returns a symbol's definition sites, callers, the transitive blast radius, and which tests cover those paths, replacing many file reads.
XDG-style, with CODEMAP_* environment overrides and an ecosystem fallback:
$XDG_CONFIG_HOME/codemap/config.yaml # config (~/.config/codemap/…)
$XDG_DATA_HOME/codemap/ # graph DB, veclite, project registry
$XDG_CACHE_HOME/codemap/ # cachesIf ~/.codemap/ already exists it is used (back-compat with vecgrep/noted). codemap init --local drops a .codemap marker so a repo-local codemap.yaml is picked up from any subdirectory; the index stays central (set CODEMAP_DATA to a path inside the repo for a repo-local index). Precedence and all keys are documented in AGENTS.md. Override paths with CODEMAP_CONFIG / CODEMAP_DATA.
codemap is built on veclite and shares conventions with vecgrep (semantic code search) and noted (code notes). An agent can combine them: vecgrep/codemap to find code by meaning, codemap to learn what calls it and what breaks if it changes.
Full docs: [docs/](./docs) (VitePress). Design rationale: [SPEC.md](./SPEC.md).
MIT © 2026 Abdul Hamid Achik
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.