Forward-looking plans only — not a mirror of src/. Doc index: README.md. Design / ship: architecture.md, packaging.md. Shipped features (adapters, fixtures, codemap agents init — agents.md) live in src/ and linked docs — not enumerated here.
- Community language adapters — optional packages (e.g. Tree-sitter) with a peerDependency on
@stainless-code/codemapand a public registration API beyond built-ins insrc/adapters/. - Agent tooling — evaluate TanStack Intent for versioned skills in
node_modules(optional;codemap agents initremains the default).
| Layer | Role |
|---|---|
| Core | Schema, incremental indexing, git invalidation, dependencies, CLI, query |
| Community adapters | Future optional packages; peerDependency on @stainless-code/codemap |
Codemap stays a structural-index primitive that other tools can consume. Two layers below: Moats are load-bearing — eroding either turns codemap into yet-another-tool-in-the-cohort instead of the predicate-shaped specialist. Floors are real shape constraints but not differentiators; soft v1 product-shape preferences. Consumer-facing framing of when to reach for codemap vs alternatives lives in why-codemap.md § When to reach for something else.
Every PR reviewer defends these. The reviewer tests embedded below are the canonical filters for any new verb / column / engine.
- A. SQL is the API. Every capability is a recipe (saved query) or a primitive recipes can compose — never a pre-baked verdict. SQL is a durable, well-known query language; agents compose any predicate without us deciding which questions are important. The moment a CLI verb returns
pass/failwithout a recipe form behind it, the moat erodes — the tool becomes "yet another linter with opinions baked in" instead of "the database your agent queries." Verdicts are an OUTPUT mode (e.g.--format sarif,audit --base <ref>deltas), never a primitive. Reviewer test for any new verb: "is this also expressible asquery --recipe <id>?" - B. Extracted structure ≥ verdicts. Schema breadth is the substrate every recipe layers on. CSS (
css_variables/css_classes/css_keyframes),markers,type_members,calls.caller_scope,components.hooks_used— these are codemap-specific extractions; their richness directly determines what JOINs are expressible and which agent questions get clean answers. Slimming the schema for theoretical perf / simplicity is a regression unless the column is empirically unread. Reviewer test for any "drop column X" PR: "what recipe (bundled or hypothetical) does this kill?"
Soft constraints — describe shipped reality. Decided-but-unshipped flips live in § Backlog, not here.
- Full-text search default-on — opt-in FTS5 ships per the
--with-ftsCLI flag /fts5: trueconfig field (default OFF; populatessource_ftsvirtual table at index time). Default-on revisits a v2 size-tax measurement. - No LSP engine — no rename / go-to-definition / hover types. Read-side LSP-adjacent primitives (
show/snippet/impact) ship as CLI / MCP / HTTP verbs (see README § CLI). LSP diagnostic-push server (recipes-as-Diagnostic[]) is a separate roadmap item tracked atplans/lsp-diagnostic-push.md. - No opinionated rule engine / fix engine / severity levels — verdict-shaped lints (
knip,jscpd,eslint) are a different product class. Predicate-as-API recipes (untested-and-dead,worst-covered-exports,visibility-tags,barrel-files,deprecated-symbols, …) are in scope and shipping; they're upstream of Moat A. Suppression comments ship as opt-in substrate (// codemap-ignore-{next-line,file} <recipe-id>→suppressionstable; recipes JOIN to honor) — no severity, no suppression-by-default, no universal-honor; consumer-chosen, not policy. - No renderer runtime — skyline / ASCII art / animated diagrams; the index emits structured rows. Shape-only output formatters (
--format mermaidshipped;--format sarif/annotationsfor CI; D2 / Graphviz on demand) are in scope. - No daemon for one-shot CLI — sub-100ms cold-start floor preserved for
query/show/snippet/ etc.; they spawn no watcher. The inherently long-running modes default-ON since 2026-05:mcp/serveboot the chokidar watcher in-process so every tool reads a live index. Pass--no-watchor setCODEMAP_WATCH=0to opt out for ephemeral / fire-and-forget invocations. Standalonecodemap watchdecouples the watcher from a transport. - Embedded intent classification beyond the thin keyword classifier in
codemap context --for "<intent>"— deeper routing belongs in the agent host (Cursor / Claude Code / MCP client). - No LLM in the box — embedded intent classification, semantic search over symbol names, embedding-driven recipe routing — the agent host owns this. We supply structure; they supply meaning.
- No fix engine — we read structure. Mutating code is a different product class (codemod tools own this). Per-row
actionshints are enough — agents execute. Adjacent to Moat A. - No runtime tracing — production beacons / live execution telemetry are a different product class (live process data, not static analysis). Post-mortem coverage ingestion (
codemap ingest-coveragereading Istanbul / LCOV / V8 protocol dumps fromNODE_V8_COVERAGE=...) is the static-side adjacent capability — local-only, no SaaS aggregation. - No JS execution at index time — config files via
import()is the only exception; recipe SQL is parsed but nevereval'd. Plugin layer (tracked atplans/c9-plugin-layer.md) must respect this — plugins describe rules in static config, not by running arbitrary code. Safety floor — protects supply-chain attack surface. - No telemetry upload — codemap never sends usage data anywhere. Local recipe-recency tracking is opt-out and stays in
.codemap/index.db. Floor exists to resist accumulation pressure. - No remote-repo cloning —
codemap github.com/x/y(clone-and-index a remote URL) is demoware, not a real workflow; the user's local checkout is always the source of truth. Indexing another tree is--root <path>/CODEMAP_ROOT, never a network fetch. Rejected in PR #23.
-
historytable (deferred — revisit-triggered) — temporal queries: "when did symbol X get@deprecated?", "coverage trend over last 50 commits", "files that became dead this week".audit --base <ref>covers the most-common temporal question (PR-scoped diff) without schema growth, so the table earns its place only when bigger questions emerge. Two shapes (per-commit snapshots ~N × DB size; append-only event log heavier CTE walks); both pay an N-reindexes backfill cost (~30s per reindex). Revisit triggers: two consumers shipjq-based "audit-runs-over-time" workflows, ORquery_baselinesevolution becomes a recurring agent need. -
codemap auditverdict + thresholds (v1.x) —verdict: "pass" | "warn" | "fail"driven by anaudit.deltas[<key>].{added_max, action}field on the config object (.codemap/config.{ts,js,json}). Triggers: two consumers shipjq-based threshold scripts with similar shapes, OR one consumer asks with a concrete config sketch. Until then, raw deltas + consumer-sidejqis the CI exit-code idiom. Likely accelerant: the Marketplace Action (next item) shipping is the most plausible path to firing the trigger — once- uses: stainless-code/codemap@v1is the dominant CI path, realjqthreshold scripts will surface. - GitHub Marketplace Action —
stainless-code/codemap@v1— composite action wrappingcodemap audit --base ${{ github.base_ref }} --ci(default) + auto-detect package manager (viapackage-manager-detector) + opt-in PR-comment writer. Most primitives already shipped (PR #43 SARIF/annotations onquery, PR #26--changed-since/--group-by/--summary, PR #30 baselines, PR #52audit --base <ref>, PR #72 boundary-violations). Two genuine new CLI surfaces ship alongside:--format sarifonaudit(today only emits--json) and the--ciaggregate flag onquery+audit(alias for--format sarif+ non-zero exit + quiet). Action version stream is independent of CLI version (CLI at0.4.0; Action publishes at its ownv1.0.0). Distribution multiplier: Marketplace is the dominant discovery surface for this tool cohort and codemap is currently absent from it. Plan:plans/github-marketplace-action.md. Effort: M. -
codemap apply <recipe-id>— substrate-shaped fix engine: apply any diff hunks your SQL describes, with conflict detection (re-parse, verifybefore_patternstill matches atline_start). Reuses the existing--format diff-jsonformatter (which already emits{file_path, line_start, before_pattern, after_pattern}rows from any recipe — seerename-preview.sqlfor an exemplar). Substrate, not verdict: the consumer's recipe SQL defines the transformation; codemap is the executor. Reviewer test (Moat A): "is this also expressible asquery --recipe X --format diff-json?" — yes, because the recipe IS the SQL. Effort: ~1 week (M). Needs a plan PR before impl — design questions: dry-run mode, multi-hunk transactional apply, conflict-resolution UX. - AST-hash duplication —
symbols.body_hashcolumn (normalized AST hash via oxc, computed at parse time — Rust-native, fast) + bundledduplicates.sqlrecipe joining onbody_hash(SELECT * FROM symbols GROUP BY body_hash HAVING COUNT(*) > 1). Different shape from token-level suffix-array dupes (catches structurally-identical functions, not copy-paste with renamed variables). Substrate addition — consumer writes the JOIN that decides "this is a problem"; no severity, no suppression-by-default. Effort: ~2 weeks (M). Needs a plan PR before impl — design questions: which oxc visitor scope (function bodies only? expressions? include comments?), what counts as "structurally identical" (rename-aware? whitespace-tolerant?), schema delta. - Falsifiable benchmark CI — codemap vs
find+grep+Read-loop agent-discovery on named fixtures (zod, fastify, vue-core, next.js). Numbers land indocs/benchmark.mdand ~3 surface inMARKETPLACE.md. Replaces the unfalsifiable "sub-millisecond" claim with named-fixture comparisons that any consumer can re-run. Effort: M. - Repo-structure conversion (codemap itself: flat → monorepo) — tracked decision, not a backlog item to ship. Default bias: stay flat until a trigger fires (C.9 community plugins ship as separate packages, OR a user asks for
codemap-corelibrary export, OR a second distro emerges). Full analysis + three options + reference layouts (oxc / knip / biome / vitest) + revisit triggers inplans/lsp-diagnostic-push.md § Repo-structure tradeoffs. Don't convert preemptively. - Monorepo / workspace awareness — discover workspaces from
pnpm-workspace.yaml/package.jsonand index per-workspace dependency graphs (separate from the codemap-itself repo-structure decision above; this is about indexing user repos) - Cross-agent handoff artifact — speculative; layered prefix/delta JSON written on session-stop, read on session-start. Complementary to indexing rather than core to it; revisit if user demand emerges
- Adapter scaffolding —
codemap create-adapter --name [name]generates adapter + test + fixture boilerplate; blocked on community adapter registration API (could land with manual registration) - Config loader — two candidates: (a) c12 — battle-tested (Nuxt/Nitro), adds extends, env overrides, RC files, watching; still executes config via
jiti. (b) AST-based extraction withoxc-parser— faster, no side effects, safer in untrusted repos; can't handle async/dynamic configs, needsimport()fallback. Current: nativeimport()inconfig.ts - Optional GitHub Actions
workflow_dispatch— run golden/benchmark against a public corpus only (never private app code) - Sass / Less / SCSS: Lightning CSS is CSS-only; preprocessors need a compile step before CSS parsing — see architecture.md § CSS
- UnJS adoption — candidates:
citty(CLI builder),pathe(cross-platform paths),consola(structured logging),pkg-types(typedpackage.json/tsconfig.json),c12(config loader — see config loader item above)