
Security News
/Research
Popular node-ipc npm Package Infected with Credential Stealer
Socket detected malicious node-ipc versions with obfuscated stealer/backdoor behavior in a developing npm supply chain attack.
@stainless-code/codemap
Advanced tools
Query your codebase. Codemap builds a local SQLite index of structural metadata (symbols, imports, exports, components, dependencies, CSS tokens, markers, and more) so AI agents and tools can answer βwhere / what / whoβ questions with SQL instead of scanning the whole tree.
ripgrep / your IDE for raw text matches. Codemap ships opt-in FTS5 (--with-fts / fts5: true) when you want body matches that JOIN with symbols / coverage / markers in one SQL.Documentation: docs/README.md is the hub (topic index + single-source rules). Topics: architecture, agents (codemap agents init), benchmark, golden queries, packaging, roadmap, why Codemap. Bundled rules/skills: .agents/rules/, .agents/skills/codemap/SKILL.md. Consumers: .github/CONTRIBUTING.md.
Structural questions answered in one SQL round-trip instead of 3β5 file reads:
| Question | Grep / Read (today) | Codemap |
|---|---|---|
| Find a symbol by exact name | Glob + Read + filter by hand | SELECT name, file_path, line_start FROM symbols WHERE name = 'X' |
Who imports ~/utils/date? | Grep + resolve tsconfig aliases manually | SELECT DISTINCT from_path FROM dependencies WHERE to_path LIKE '%utils/date%' |
Components using the useQuery hook | Grep useQuery + filter to component files | SELECT name, file_path FROM components WHERE hooks_used LIKE '%useQuery%' |
| Heaviest files by import fan-out | Impractical without a parser | SELECT from_path, COUNT(*) AS n FROM dependencies GROUP BY from_path ORDER BY n DESC |
| All CSS keyframes / design tokens / module classes | Grep @keyframes, --var-, .module.css then disambiguate | One SELECT against css_keyframes / css_variables / css_classes |
Deprecated symbols (@deprecated JSDoc) | Grep @deprecated + cross-reference symbol | SELECT name, kind FROM symbols WHERE doc_comment LIKE '%@deprecated%' |
Full schema and recipe catalog: docs/architecture.md Β§ Schema Β· docs/why-codemap.md Β· codemap query --recipes-json.
bun add @stainless-code/codemap
# or: npm install @stainless-code/codemap
Engines: Node ^20.19.0 || >=22.12.0 and/or Bun >=1.0.0 β see package.json and docs/packaging.md.
codemap, bunx @stainless-code/codemap, or node node_modules/@stainless-code/codemap/dist/index.mjsbun src/index.ts (same flags)codemap # incremental index (run once per session)
codemap dead-code --json # outcome alias β query --recipe untested-and-dead
codemap query --json --recipe fan-out # bundled SQL via recipe id (alias: -r)
codemap query --json "SELECT name, file_path FROM symbols WHERE name = 'foo'" # ad-hoc SQL
codemap --files src/a.ts src/b.tsx # targeted re-index after edits
codemap validate --json # detect stale / missing / unindexed files
codemap context --compact --for "refactor auth" # JSON envelope + intent-matched recipes
codemap ingest-coverage coverage/coverage-final.json --json # Istanbul / LCOV (auto-detected) β coverage table; joins with symbols
NODE_V8_COVERAGE=.cov bun test && codemap ingest-coverage .cov --runtime --json # V8 protocol (per-process dumps); local-only
codemap agents init # scaffold .agents/ rules + skills
Version-matched agent guidance: the published npm package ships templates/agents/ (rules + skills) keyed to that version, so codemap agents init writes guidance that matches the CLI you installed. See docs/agents.md.
# Index project root (optional <state-dir>/config.{ts,js,json}; --state-dir overrides .codemap/)
codemap
# Version (also: codemap --version, codemap -V)
codemap version
# Full rebuild
codemap --full
# SQL against the index (after at least one index run). Bundled agent rules/skills use --json first; omit it for console.table in a terminal.
codemap query --json "SELECT name, file_path FROM symbols LIMIT 10"
# With --json: JSON array on success; {"error":"..."} on stdout for bad SQL, DB open, or query bootstrap (config/resolver)
codemap query "SELECT name, file_path FROM symbols LIMIT 10"
# Query is not row-capped β add LIMIT in SQL for large selects
# Bundled SQL (same as skill examples): fan-out rankings
codemap query --json --recipe fan-out
codemap query --json --recipe fan-out-sample
# Outcome aliases β thin wrappers over `query --recipe <id>`; every query flag passes through.
# Capped at 5 to avoid alias-sprawl.
codemap dead-code --json # β query --recipe untested-and-dead
codemap deprecated --ci # β query --recipe deprecated-symbols --ci
codemap boundaries --format sarif > boundary-findings.sarif # β query --recipe boundary-violations --format sarif
codemap hotspots --json --group-by directory # β query --recipe fan-in --json --group-by directory
codemap coverage-gaps --json --summary # β query --recipe worst-covered-exports --json --summary
# Parametrised recipes validate params from <id>.md frontmatter before SQL binding.
codemap query --json --recipe find-symbol-by-kind --params kind=function,name_pattern=%Query%
codemap query --recipe rename-preview --params old=usePermissions,new=useAccess,kind=function --format diff
# Architecture-boundary rules (declare in .codemap/config.ts):
# boundaries: [{ name: "ui-cant-touch-server", from_glob: "src/ui/**", to_glob: "src/server/**" }]
# Default action is "deny"; the table is reconciled from config on every index pass.
codemap query --recipe boundary-violations --format sarif > boundary-findings.sarif
# Counts only (skip the rows) β pairs well with --recipe for dashboards / agent context windows
codemap query --json --summary -r deprecated-symbols
# PR-scoped: filter result rows to those touching files changed since <ref>
codemap query --json --changed-since origin/main -r fan-out
codemap query --json --summary --changed-since HEAD~5 "SELECT file_path FROM symbols"
# Group rows by directory, CODEOWNERS owner, or workspace package
codemap query --json --summary --group-by directory -r fan-in
codemap query --json --group-by owner -r deprecated-symbols
codemap query --json --summary --group-by package "SELECT file_path FROM symbols"
# Snapshot a result, refactor, then diff (saved inside .codemap/index.db, no JSON files)
codemap query --save-baseline -r visibility-tags # save under name "visibility-tags"
codemap query --json --baseline -r visibility-tags # full diff: {baseline, current_row_count, added, removed}
codemap query --json --summary --baseline -r visibility-tags # counts only: {baseline, current_row_count, added: N, removed: N}
codemap query --save-baseline=pre-refactor "SELECT file_path FROM symbols" # ad-hoc SQL needs an explicit =<name>
codemap query --baseline=pre-refactor "SELECT file_path FROM symbols"
codemap query --baselines # list saved baselines
codemap query --drop-baseline visibility-tags # delete
# --group-by is mutually exclusive with --save-baseline / --baseline (different output shapes)
# Diff per-delta baselines vs current β files / dependencies / deprecated drift in one envelope
codemap query --save-baseline=base-files "SELECT path FROM files"
codemap query --save-baseline=base-dependencies "SELECT from_path, to_path FROM dependencies"
codemap query --save-baseline=base-deprecated -r deprecated-symbols
codemap audit --baseline base # auto-resolves base-{files,dependencies,deprecated}
codemap audit --json --summary --baseline base # counts-only β useful for CI dashboards
codemap audit --files-baseline base-files # explicit per-delta β runs only the slots provided
codemap audit --baseline base --files-baseline hotfix-files # mixed β auto-resolve deps + deprecated; override files
codemap audit --baseline base --no-index # skip the auto-incremental-index prelude (frozen-DB CI)
codemap audit --base origin/main --json # ad-hoc β worktree+reindex against any committish; no --save-baseline needed
codemap audit --base origin/main --format sarif # emit SARIF 2.1.0 directly (Code Scanning); also: --ci alias
codemap audit --base origin/main --ci # CI shortcut: --format sarif + non-zero exit on additions + quiet
codemap audit --base v1.0.0 --files-baseline pre-release-files # mix --base with per-delta override
# --base materialises <ref> via `git worktree add` to .codemap/audit-cache/<sha>/, reindexes into
# a temp DB, then diffs. Cache hit on second run against same sha is sub-100ms. Requires git;
# non-git projects get a clean `--base requires a git repository` error.
# Recipes that define per-row action templates append "actions" hints (kebab-case verb +
# description) in --json output; ad-hoc SQL never carries actions. Inspect via --recipes-json.
# --format <text|json|sarif|annotations|mermaid|diff|diff-json> β pipe results into GitHub Code Scanning
# (SARIF 2.1.0), surface findings inline on PRs (GH Actions ::notice file=β¦,line=β¦::msg), or
# render edge-shaped recipes as Mermaid `flowchart LR`, or preview edits as unified diffs. All
# formatted outputs require a flat row list
# (no --summary / --group-by / baseline). SARIF / annotations auto-detect file_path /
# path / to_path / from_path; rule.id is codemap.<recipe-id> (or codemap.adhoc). Mermaid
# requires {from, to, label?, kind?} rows and rejects unbounded inputs (>50 edges) with a
# scope-suggestion error β alias columns via SELECT col AS "from", col2 AS "to".
codemap query --recipe deprecated-symbols --format sarif > findings.sarif
codemap query --recipe deprecated-symbols --ci # CI shortcut: --format sarif + non-zero exit + quiet
codemap query --recipe deprecated-symbols --format annotations # one ::notice per row
# Render any audit/SARIF output as a markdown PR-summary comment (for repos without
# Code Scanning / aggregate audit deltas / bot-context seeding):
codemap audit --base origin/main --json | codemap pr-comment - | gh pr comment <PR> -F -
codemap query --format mermaid 'SELECT from_path AS "from", to_path AS "to" FROM dependencies LIMIT 50'
codemap query --format diff 'SELECT "README.md" AS file_path, 1 AS line_start, "# Codemap" AS before_pattern, "# Codemap Preview" AS after_pattern'
codemap query --format diff-json 'SELECT "README.md" AS file_path, 1 AS line_start, "# Codemap" AS before_pattern, "# Codemap Preview" AS after_pattern' | jq '.summary'
# --with-fts β opt-in FTS5 virtual table populated at index time. Default OFF (preserves
# .codemap/index.db size); CLI flag wins over .codemap/config.ts `fts5` field. Toggle change
# auto-detects and forces a full rebuild so `source_fts` stays consistent.
codemap --with-fts --full
codemap query --recipe text-in-deprecated-functions # demonstrates FTS5 β¨― symbols β¨― coverage JOIN
# HTTP API β same tool taxonomy as `codemap mcp`, exposed over POST /tool/{name} for
# non-MCP consumers (CI scripts, curl, IDE plugins). Loopback default; optional --token.
TOKEN=$(openssl rand -hex 32)
codemap serve --port 7878 --token "$TOKEN" &
curl -s -X POST http://127.0.0.1:7878/tool/query \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer $TOKEN" \
-d '{"sql":"SELECT name, file_path FROM symbols LIMIT 5"}'
# Watch mode β long-running process; debounced reindex on file changes (default 250ms).
# `mcp` / `serve` boot the watcher in-process by default since 2026-05 β every tool
# reads a live index without per-request prelude:
codemap mcp # default-ON watcher
codemap serve --port 7878 # default-ON watcher
codemap watch --quiet # standalone (decoupled from a transport)
codemap mcp --no-watch # opt out for one-shot fire-and-forget calls
CODEMAP_WATCH=0 codemap mcp # env-var opt-out (mirrors --no-watch)
# List bundled recipes as JSON, or print one recipe's SQL (no DB required)
codemap query --recipes-json
codemap query --print-sql fan-out
# `components-by-hooks` ranks by hook count without SQLite JSON1 (comma-based count on the stored JSON array).
# Project-local recipes β drop SQL files into .codemap/recipes/ to make them discoverable across the team
# Bundled recipes live in templates/recipes/ in the npm package; project recipes win on id collision
# (shadowing is signalled via a `shadows: true` field in --recipes-json so agents notice the override)
mkdir -p .codemap/recipes
echo "SELECT path FROM files WHERE language IN ('ts', 'tsx') AND line_count > 500" \
> .codemap/recipes/big-ts-files.sql
codemap query --recipe big-ts-files # auto-discovered alongside bundled
# Targeted reads β precise lookup by symbol name without composing SQL
codemap show runQueryCmd # metadata: file:line + signature
codemap show foo --kind function --in src/cli # narrow ambiguous matches
codemap snippet runQueryCmd # same lookup + source text from disk
codemap snippet foo --json # {matches: [{...metadata, source, stale, missing}]}
# Output envelope is always {matches, disambiguation?} β single match β {matches: [{...}]};
# multi-match adds disambiguation: {n, by_kind, files, hint} for agent-friendly narrowing.
# Impact analysis β symbol/file blast-radius walker (callers, callees, dependents, dependencies)
codemap impact handleQuery # both directions, depth 3, all compatible graphs
codemap impact src/db.ts --direction up # what depends on db.ts (file-level, deps + imports)
codemap impact handleAudit --depth 1 --via calls # direct callers via the calls table only
codemap impact runWatchLoop --json --summary | jq '.summary.nodes' # CI-gate fan-in score
# Replaces hand-composed `WITH RECURSIVE` queries. Cycle-detected, depth-bounded
# (default 3, --depth 0 = unbounded), limit-capped (default 500). Result envelope:
# {target, matches: [{depth, edge, kind, name?, file_path}], summary: {nodes, terminated_by}}.
# MCP server (Model Context Protocol) β for agent hosts (Claude Code, Cursor, Codex, generic MCP clients)
codemap mcp # JSON-RPC on stdio; one tool per CLI verb plus query_batch
# Tools: query, query_batch (MCP-only β N statements in one round-trip), query_recipe, audit,
# save_baseline, list_baselines, drop_baseline, context, validate, show, snippet, impact
# Resources: codemap://recipes, codemap://recipes/{id}, codemap://schema, codemap://skill (lazy-cached)
# Output shape verbatim from `--json` envelopes (no re-mapping). Snake_case throughout.
# Another project
codemap --root /path/to/repo --full
# Explicit config
codemap --config /path/to/config.json --full
# Override the state directory (default `.codemap/`):
codemap --state-dir .cm --full # or: CODEMAP_STATE_DIR=.cm codemap --full
# Re-index only given paths (relative to project root)
codemap --files src/a.ts src/b.tsx
# Scaffold .agents/ from bundled templates β full matrix: docs/agents.md
codemap agents init
codemap agents init --force
codemap agents init --interactive # -i; IDE wiring + symlink vs copy
Environment / flags: --root overrides CODEMAP_ROOT / CODEMAP_TEST_BENCH, then process.cwd(). Indexing a project outside this clone: docs/benchmark.md Β§ Indexing another project.
Configuration: optional <state-dir>/config.{ts,js,json} (default .codemap/config.*; default export object or async factory). Shape: codemap.config.example.json. Runtime validation (Zod, strict keys) and API surface: docs/architecture.md Β§ User config. When developing inside this repo you can use defineConfig from @stainless-code/codemap or ./src/config. If you set include, it replaces the default glob list entirely. Self-healing files (D11): <state-dir>/.gitignore is rewritten to canonical on every codemap boot; JSON config gets unknown-key pruning + key-sort drift; TS/JS configs are validate-only.
import { createCodemap } from "@stainless-code/codemap";
const cm = await createCodemap({ root: "/path/to/repo" });
await cm.index({ mode: "incremental" });
await cm.index({ mode: "full" });
await cm.index({ mode: "files", files: ["src/a.ts"] });
await cm.index({ quiet: true });
const rows = cm.query("SELECT name FROM symbols LIMIT 5");
createCodemap configures a process-global runtime (initCodemap); only one active project per process is supported. Advanced: runCodemapIndex for an open DB handle. Module layout: docs/architecture.md Β§ Layering.
Tooling: Oxfmt, Oxlint, tsgo (@typescript/native-preview).
| Command | Purpose |
|---|---|
bun run dev | Run the CLI from source (same as bun src/index.ts) |
bun run check | Build, format check, lint, tests, typecheck β run before pushing |
bun run fix | Apply lint fixes, then format |
bun run test / bun run typecheck | Focused checks |
bun run test:golden | SQL snapshot regression on fixtures/minimal (included in check) |
bun run test:golden:external | Tier B: local tree via CODEMAP_* / --root (not in default check) |
bun run benchmark:query | Compare console.table vs --json stdout size (needs local .codemap/index.db; docs/benchmark.md Β§ Query stdout) |
bun run qa:external | Index + sanity checks + benchmark on CODEMAP_ROOT / CODEMAP_TEST_BENCH |
bun install
bun run check # build + format:check + lint + test + typecheck
bun run fix # oxlint --fix, then oxfmt
Readability & DX: Prefer clear names and small functions; keep JSDoc on public exports. .github/CONTRIBUTING.md has contributor workflow and conventions.
Use a real project path (the repo must exist on disk). See docs/benchmark.md Β§ Indexing another project.
CODEMAP_ROOT=/absolute/path/to/indexed-repo bun src/benchmark.ts
Optional CODEMAP_BENCHMARK_CONFIG for repo-specific scenarios: docs/benchmark.md Β§ Custom scenarios.
To compare query stdout size (console.table vs --json) on an existing index, see docs/benchmark.md Β§ Query stdout (bun run benchmark:query).
Developed under stainless-code on GitHub.
MIT β see LICENSE.
FAQs
Query your codebase β structural SQLite index for AI agents
We found that @stainless-code/codemap demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago.Β It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
/Research
Socket detected malicious node-ipc versions with obfuscated stealer/backdoor behavior in a developing npm supply chain attack.

Security News
TeamPCP and BreachForums are promoting a Shai-Hulud supply chain attack contest with a $1,000 prize for the biggest package compromise.

Security News
Packagist urges PHP projects to update Composer after a GitHub token format change exposed some GitHub Actions tokens in CI logs.