CLI that builds a queryable map of a TypeScript codebase — declarations, import graph, duplication (name + body similarity), community structure, and ranked findings. Storage is a single SQLite file so you (or an agent) can run arbitrary read-only SQL against it.
8 analyzers feed a single ranked findings table:
| Analyzer | CS Method | What it detects |
|---|---|---|
| Body clones | MinHash (128 perms) + LSH banding (32×4) + Jaccard similarity | Near-duplicate function bodies across files |
| Name clusters | Bag-of-words stemming (camelCase split, stop-word strip, alphabetical sort) | Same concept named similarly in different domains |
| Long/god functions | McCabe cyclomatic complexity + 4 other metrics (LOC, nesting, statements, local vars) | Functions exceeding per-tier thresholds (1-2 metrics = long, 3+ = god) |
| JSX duplicates | Preorder tree serialization → SHA1 structural hash | Repeated UI component structures ignoring props/text |
| Louvain communities | graphology-communities-louvain (modularity maximization) | Files whose import graph clusters them with the wrong domain |
| Git hotspots | git log --since=6.months churn × sum(cyclomatic) |
Complex files that change frequently |
| Temporal coupling | Pairwise co-change counting, normalized by min(churn_a, churn_b) | Files that always change together across domain boundaries |
| Boundary analysis | Aggregation of all above signals per domain pair | Weak/missing domain boundaries with actionable recommendations |
codemap analyze [path] [--keep-history]— walk the target repo, refresh tablescodemap schema— full data model + query recipes (deep reference, printed on demand)codemap query "<sql>"— read-only SQL against the DB (JSON output)codemap update-finding <id> [--explanation ...] [--action-hints ...]— persist analysis onto a finding
# run without installing
npx -y github:rbbydotdev/codemap-mcp analyze ./src
# or install globally, exposing the `codemap` command
npm i -g github:rbbydotdev/codemap-mcpThen map and explore a codebase:
codemap analyze ./src # scan and (re)build the map
codemap schema # print the data model + canonical query recipes
codemap query "SELECT rank, ROUND(score,2) AS score, kind, summary \
FROM findings WHERE run_id=(SELECT id FROM v_latest_run) ORDER BY rank LIMIT 20"analyze writes to a SQLite file; schema and query read from it. Piping the output into an
agent (or running the commands as tools) lets it reason over the findings and write analysis back
with codemap update-finding.
See DEV_NOTES.md for architecture details and internal design decisions.
Every file and declaration is classified before analysis thresholds apply:
logic— services, agent, workers, stores, state, hooks, lib, fs, db, themes, commands. Strictest thresholds.ui-logic— .tsx files with low JSX / high control-flow (hooks, handlers living near components).ui-presentational— JSX-heavy components; most duplication here is legitimate.test— test/spec/e2e files; excluded from cross-file clone reports by default.
Individual findings (a clone here, a coupling pair there) are symptoms. The boundary analyzer aggregates them to answer: "which domain boundaries are weak or missing?"
For every pair of domains, it accumulates evidence from all cross-domain signal types (body clones, name clusters, temporal coupling, community mismatches, JSX duplicates, imports), applies log-scaled weighted scoring, and classifies each pair:
- merge-domains — bidirectional imports + structural evidence. "These are one thing pretending to be two."
- extract-shared-module — duplication signals + shared names. "Separate concerns that share logic."
- define-api-boundary — heavy unidirectional imports. "Consumer/provider relationship needs an explicit boundary."
- move-misplaced-files — community mismatches without other signals. "A few files are on the wrong side."
- boundary-ok — everything else.
When a single domain contains >80% of files, the analyzer automatically uses subdirectories as effective domains.
Additional DB tables: domain_profiles (per-domain cohesion, fan-out, complexity load) and domain_pairs (per-pair evidence breakdown and recommendation). Schema version 3.
Default: cwd()/.codemap/codemap.sqlite (creates dir if needed).
Override: CODEMAP_DB=/path/to/db.sqlite
npm run build # tsc → dist/ + copy schema.sqlOnly dist/, README.md, LICENSE ship in the tarball (via "files" allowlist). Source, test fixtures, and data directories are excluded.
npm login
npm publish # prepublishOnly runs build automaticallybetter-sqlite3— native C++ addon; consumers neednode-gypor compatible prebuildsts-morph— bundles the TypeScript compiler (~30MB installed); core to the analysis pipelinegraphology+graphology-communities-louvain— Louvain community detection
Uses module: ESNext + moduleResolution: Bundler (not NodeNext) because graphology type exports break under strict NodeNext resolution.