Skip to content

chore: version packages#31

Open
github-actions[bot] wants to merge 1 commit intomainfrom
changeset-release/main
Open

chore: version packages#31
github-actions[bot] wants to merge 1 commit intomainfrom
changeset-release/main

Conversation

@github-actions
Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot commented May 1, 2026

This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.

Releases

@stainless-code/codemap@0.5.0

Minor Changes

  • #35 119db38 Thanks @SutuSebastian! - feat(mcp): codemap mcp — Model Context Protocol server (agent-transports v1)

    Adds the codemap mcp top-level command — boots an MCP server over
    stdio so agent hosts (Claude Code, Cursor, Codex, generic MCP clients)
    call codemap as JSON-RPC tools instead of shelling out per query.
    Eliminates the bash round-trip on every agent invocation.

    Surface (one tool per CLI verb plus query_batch, all snake_case):

    • query, query_batch, query_recipe, audit, save_baseline,
      list_baselines, drop_baseline, context, validate

    • Resources: codemap://recipes, codemap://recipes/{id},
      codemap://schema, codemap://skill (lazy-cached)

      query_batch is MCP-only — N statements in one round-trip with
      batch-wide-defaults + per-statement-overrides (items are
      string | {sql, summary?, changed_since?, group_by?}). Per-statement
      errors are isolated. save_baseline ships as one polymorphic tool
      ({name, sql? | recipe?} with runtime exclusivity check) mirroring
      the CLI's single --save-baseline=<name> verb.

      Output shape is verbatim from each tool's CLI counterpart's --json
      envelope (no re-mapping). Bootstrap once at server boot; tool
      handlers reuse existing engine entry-points (executeQuery,
      runAudit, etc.) — no duplicate business logic.

      New dep: @modelcontextprotocol/sdk.

      HTTP API (codemap serve) stays in roadmap backlog; design points
      (tool taxonomy + output shape) are reserved in docs/architecture.md § MCP wiring so HTTP inherits them when a concrete consumer asks.

  • #52 fe5a355 Thanks @SutuSebastian! - codemap audit --base <ref> — ad-hoc structural-drift audit against any git committish (origin/main, HEAD~5, <sha>, tag, …). Closes the highest-frequency post-watch agent loop: "what changed structurally between this branch and origin/main?". Replaces today's 3-step --baseline dance (switch branches, reindex, save baselines, switch back) with one verb.

    Three transports, one engine:

    • CLI: codemap audit --base <ref> [--<delta>-baseline <name>] [--summary] [--json] [--no-index]
    • MCP tool: audit with new base?: string arg
    • HTTP: POST /tool/audit (auto-wired via the existing dispatcher)

    All three dispatch the same pure runAuditFromRef engine in application/audit-engine.ts.

    How it works:

    1. git rev-parse --verify "<ref>^{commit}" resolves <ref> to a sha (clean error on non-git or unresolvable ref).
    2. Cache lookup at <projectRoot>/.codemap/audit-cache/<sha>/.codemap.db. Hit → sub-100ms; miss → continue.
    3. Atomic populategit worktree add to a per-pid temp dir + runCodemapIndex({mode: "full"}) against the worktree's .codemap.db + POSIX rename claims the final <sha>/ slot. Concurrent CI matrix runs against the same sha race-safely without lock files (loser's rename fails with EEXIST → falls through to cache hit).
    4. Run each delta's canonical SQL on the cached DB vs the live DB; diffRows (existing helper) computes {added, removed}.
    5. Compose AuditEnvelope with per-delta base.source: "ref" (new value) + base.ref (user-supplied string) + base.sha (resolved).

    Decisions worth knowing:

    • AuditBase is now a discriminated union — existing {source: "baseline", name, sha, indexed_at} rows untouched; new {source: "ref", ref, sha, indexed_at} arm. Consumers narrowing on base.source keep compiling.
    • Mutually exclusive with --baseline <prefix>. Parser + handler both guard. Per-delta --<key>-baseline overrides compose orthogonally with both, so --base origin/main --files-baseline pre-refactor-files is valid (mixed sources).
    • Eviction: hardcoded LRU 5 entries / 500 MiB; git worktree remove --force + rm -rf for each victim. Orphan .tmp.* dirs older than 10 min get swept on the next cycle. No config knobs in v1; defer to v1.x+ if real consumers ask.
    • Hard error on non-git projects. No graceful fallback — there's no meaningful "ref" without git. The other audit modes (--baseline, --<delta>-baseline) still work without git.
    • Env hygiene. All git spawns in audit-worktree.ts strip inherited GIT_* env vars so a containing git operation (e.g. running codemap from a husky hook) doesn't route worktree calls at the wrong index.

    Auto-.gitignore: codemap agents init now adds .codemap/audit-cache/ alongside .codemap.* so cached worktrees never get committed. .codemap/recipes/ stays git-tracked.

    Plan: PR #51 (merged). Implementation: PR #52.

  • #54 1313fc2 Thanks @SutuSebastian! - .codemap/ directory consolidation + self-healing files. Every codemap-managed path lives under a single configurable state directory (default .codemap/, override via --state-dir <path> or CODEMAP_STATE_DIR). Cleans up the dual-pattern surface (<root>/.codemap.db + <root>/.codemap/<thing>/) that's been growing with every cache PR; collapses the user .gitignore patching surface to zero.

    New layout:

    <root>/
    └── .codemap/                 ← override via --state-dir / CODEMAP_STATE_DIR
        ├── .gitignore            ← codemap-managed (self-healing); tracked
        ├── config.{ts,js,json}   ← was <root>/codemap.config.*; tracked
        ├── recipes/              ← user-authored SQL; tracked (existing)
        ├── index.db              ← was .codemap.db
        ├── index.db-shm          ← was .codemap.db-shm
        ├── index.db-wal          ← was .codemap.db-wal
        └── audit-cache/          ← was .codemap/audit-cache/ (existing)
    

    Self-healing files (D11): <state-dir>/.gitignore and <state-dir>/config.json are owned by idempotent ensure* reconcilers (src/application/state-dir.ts, src/application/state-config.ts) that run on every codemap boot — read → validate → reconcile → write only on drift. The setup logic IS the migration: future codemap versions add new generated artifacts to STATE_GITIGNORE_BODY (or extend the Zod schema), and every consumer's project repairs itself on the next codemap invocation. No more per-feature .gitignore patching in agents-init.ts.

    Pre-v1 — no migration shim:

    • <root>/.codemap.db<state-dir>/index.db (rename basename)
    • <root>/codemap.config.{ts,json}<state-dir>/config.{ts,js,json} (move file)
    • Existing dev clones: rm .codemap.db .codemap.db-shm .codemap.db-wal once and re-index; move codemap.config.* into .codemap/ (or set --config <old-path> to keep using the legacy location explicitly).

    New flags + env:

    • --state-dir <path> — override the state directory (resolves relative to project root).
    • CODEMAP_STATE_DIR — same, env-var form.

    Internal refactor: new src/cli/bootstrap-codemap.ts extracts the loadUserConfig + resolveCodemapConfig + initCodemap + configureResolver dance from 9 cmd-* files into one helper that also runs the self-healing reconcilers. Adding a new self-healing file is now a one-line addition there.

    Inspired by flowbite-react's .flowbite-react/.gitignore + setup-* pattern; expressed in codemap's own conventions (ensure* reconcilers, Zod schema as z.infer source of truth, pure {before, after, written} return shapes for testability).

    Plan: PR #53 (merged). Implementation: PR #54.

  • #50 90092ae Thanks @SutuSebastian! - codemap impact <target> — symbol/file blast-radius walker. Replaces hand-composed WITH RECURSIVE queries that agents struggle to write reliably with a single verb that walks the calls / dependencies / imports graphs (callers, callees, dependents, dependencies). Depth- and limit-bounded, cycle-detected.

    Three transports, one engine:

    • CLI: codemap impact <target> [--direction up|down|both] [--depth N] [--via dependencies|calls|imports|all] [--limit N] [--summary] [--json]
    • MCP tool: impact (registered alongside show / snippet)
    • HTTP: POST /tool/impact

    All three dispatch the same pure findImpact engine in application/impact-engine.ts per the post-PR #41 layering — adding tools never duplicates business logic.

    Decisions worth knowing:

    • Target auto-resolution. Contains / or matches files.path → file target; otherwise symbol (case-sensitive, exact). Symbol targets walk calls; file targets walk dependencies + imports (resolved_path only). Mismatched explicit --via choices land in skipped_backends (no error — agent sees why their selection yielded fewer rows than expected).
    • Cycle detection. SQLite has no native cycle predicate; we materialise a comma-bounded path string per row and instr it to break re-entry. Bounded depth + --limit (default 500) keep cyclic graphs cheap regardless. --depth 0 walks unbounded but stays cycle-detected and limit-capped.
    • Termination classification. summary.terminated_by: limit > depth > exhausted. CI gates can branch on it.
    • --summary shape. Trims the matches array but preserves summary.nodes — the jq '.summary.nodes' consumption pattern still works.
    • No SARIF / annotations. Impact rows are graph traversals, not findings — wrong shape for those formats.

    Engine sketch: one WITH RECURSIVE query per (direction, backend) combo, JS-side merge + dedup by (direction, kind, name?, file_path) keeping the shallowest depth, then summary.by_kind + terminated_by classification.

    Plan: PR #49 (merged). Implementation: PR #50.

  • #44 4ec51d8 Thanks @SutuSebastian! - codemap serve — HTTP server exposing the same tool taxonomy as codemap mcp over POST /tool/{name}. For non-MCP consumers (CI scripts, simple curl, IDE plugins that don't speak MCP).

    Default bind 127.0.0.1:7878 (loopback only — refuse 0.0.0.0 unless explicitly opted in via --host 0.0.0.0). Optional --token <secret> requires Authorization: Bearer <secret> on every request; GET /health is auth-exempt so liveness probes work without leaking the token. Bare node:http (no Express / Fastify dep) — runs on Bun + Node.

    Routes:

    • POST /tool/{name} — every MCP tool (query, query_recipe, query_batch, audit, context, validate, show, snippet, save_baseline, list_baselines, drop_baseline). Body {<args>}; response = same codemap query --json envelope (NOT MCP's {content: [...]} wrapper). format: "sarif" payloads ship as application/sarif+json; format: "annotations" as text/plain.
    • GET /resources/{encoded-uri} — mirror of MCP resources (codemap://recipes, codemap://recipes/{id}, codemap://schema, codemap://skill).
    • GET /health — liveness (auth-exempt); GET /tools / GET /resources — catalogs.
    • Errors: {"error": "..."} with HTTP status 400 / 401 / 404 / 500.
    • Every response carries X-Codemap-Version: <semver> so consumers can pin / detect upgrades.

    Internals: Tool bodies (application/tool-handlers.ts) and resource fetchers (application/resource-handlers.ts) are pure transport-agnostic — same handlers codemap mcp dispatches. No engine duplication; mcp-server.ts and http-server.ts both wrap the same ToolResult discriminated union.

    Security: CSRF + DNS-rebinding guard rejects requests with Sec-Fetch-Site: cross-site / same-site (modern-browser CSRF), any Origin header that isn't null (older-browser CSRF), and Host header mismatch on loopback bind (DNS rebinding) — runs on every request including auth-exempt /health. Defends against a malicious local webpage fetch-ing the API while the developer is browsing. Non-browser clients (curl, MCP hosts, CI scripts) don't send those headers and pass through. SIGINT / SIGTERM → graceful drain. 1 MiB request-body cap (DoS protection). SQLite reader concurrency handles parallel requests; PRAGMA query_only = 1 set per connection.

  • #47 5ef9ce4 Thanks @SutuSebastian! - codemap watch — long-running process that re-indexes changed files in real time so every CLI / MCP / HTTP query reads live data without a per-query reindex prelude. Eliminates the single biggest source of agent-side friction: "is the index stale right now?"

    Three shapes:

    • Standalone: codemap watch [--debounce 250] [--quiet] — foreground process; logs reindex N file(s) in Mms per batch unless --quiet. SIGINT / SIGTERM drains pending edits.
    • MCP killer combo: codemap mcp --watch [--debounce <ms>] — boots stdio MCP server + watcher in one process. Long Cursor / Claude Code sessions never hit a stale index; agents stop having to remember to reindex between edit + query.
    • HTTP killer combo: codemap serve --watch [--debounce <ms>] — same shape for non-MCP consumers (CI scripts, IDE plugins, simple curl).

    Audit prelude optimization: when watch is active, mcp audit's default incremental-index prelude becomes a no-op (the watcher already keeps the index fresh — saves the per-request reindex cost). Explicit no_index: false still forces the prelude.

    Env shortcut: CODEMAP_WATCH=1 (or "true") implies --watch for mcp / serve — useful for IDE / CI launches that can't easily edit the spawn command.

    Backend: chokidar v5 (selected via 6-watcher audit in PR #46). Pure JS — runs identically on Bun + Node, no per-runtime branching, no native compile matrix on top of bun:sqlite / better-sqlite3. Cross-platform (macOS / Linux / Windows / WSL). Atomic-write + chunked-write detection out of the box. 1 dep (readdirp), 82 KB.

    Filtering: Only paths the indexer cares about trigger a reindex (TS / TSX / JS / JSX / CSS + project-local recipes under <root>/.codemap/recipes/). node_modules / .git / dist / configured excludeDirNames are skipped.

  • #57 b5679a6 Thanks @SutuSebastian! - codemap ingest-coverage <path> — static coverage ingestion. Reads Istanbul JSON (coverage-final.json) or LCOV (lcov.info) into a new coverage table joinable to symbols, so structural queries can compose coverage filters in pure SQL — no runtime tracer, no paid coverage stack.

    Both formats land in v1 (Istanbul + LCOV) so every test runner is a first-class consumer on day one — vitest --coverage, jest --coverage, c8, nyc (Istanbul JSON), and bun test --coverage (LCOV) all work without waiting on a follow-up release.

    Bundled recipes (auto-discovered, no opt-in needed):

    • untested-and-dead — exported functions with no callers AND zero coverage; the killer recipe combining structural and runtime evidence axes.
    • files-by-coverage — files ranked ascending by statement coverage.
    • worst-covered-exports — top-20 worst-covered exported functions.

    Each recipe ships a frontmatter actions block so agents see per-row follow-up hints in --json output.

    Schema:

    • New coverage table with natural-key PK (file_path, name, line_start) — intentionally not a FK to symbols.id so coverage rows survive the symbols drop-recreate cycle on every --full reindex.
    • idx_coverage_file_name covers the typical join shape and the GROUP BY file_path scan used by the files-by-coverage recipe.
    • Three new meta keys (coverage_last_ingested_at / _path / _format) record ingest freshness.
    • SCHEMA_VERSION 5 → 6 — auto-rebuilds on next codemap run; the new table is empty until first ingest-coverage invocation. Subsequent bumps preserve coverage data via the dropAll() exclusion.

    CLI:

    codemap ingest-coverage coverage/coverage-final.json   # Istanbul (auto-detected)
    codemap ingest-coverage coverage/lcov.info             # LCOV (auto-detected)
    codemap ingest-coverage coverage --json                # directory probe (errors if both files present)
    
    codemap query --json --recipe untested-and-dead        # the killer query

    No --source flag — format is auto-detected from extension. No MCP / HTTP transport in v1 — coverage exposes as a SQL column, composable with every existing recipe and ad-hoc query through the existing query / query_recipe tools (no parallel surface).

    Plan: PR #56 (merged). Implementation: this PR.

  • #30 a309d52 Thanks @SutuSebastian! - codemap query --save-baseline / --baseline — snapshot a query result set and diff against it later. Stored in the new query_baselines table inside .codemap.db (no parallel JSON files). --baselines lists saved snapshots, --drop-baseline <name> deletes one. Diff identity is per-row JSON.stringify equality; --summary collapses to {added: N, removed: N}. Recipe actions attach to the added rows when running under --baseline. Baselines survive --full and SCHEMA rebuilds. SCHEMA_VERSION bumps from 4 to 5.

  • #37 5110b1a Thanks @SutuSebastian! - feat(recipes): recipes-as-content registry — bundled .md siblings + project-local recipes

    Two complementary capabilities:

    1. Bundled recipes get richer descriptions. Every bundled recipe in
      templates/recipes/ is now a <id>.sql file paired with an optional
      <id>.md description body (replaces the inline TypeScript map in
      src/cli/query-recipes.ts). Per-row actions templates live in YAML
      frontmatter on the .md instead of code. Same surface for end users
      (--recipe <id> / --recipes-json / codemap://recipes); single
      storage shape across bundled + project recipes.

    2. Project-local recipes — drop <id>.{sql,md} files into
      <projectRoot>/.codemap/recipes/ to ship team-internal SQL as first-
      class recipes. Auto-discovered via --recipe <id>, surfaced in
      --recipes-json and the codemap://recipes MCP resource alongside
      bundled. Project recipes win on id collision; the catalog entry
      carries shadows: true on overrides so agents reading the catalog
      at session start see when a recipe behaves differently from the
      documented bundled version (per-execution response shape stays
      unchanged — uniformity contract preserved).

    Catalog entries (--recipes-json output, codemap://recipes
    payload) gain three additive fields: body (full Markdown body),
    source ("bundled" | "project"), and shadows? (true on
    project entries that override a bundled id). Existing consumers
    that destructure {id, description, sql, actions?} keep working.

    Validation: load-time lexical scan rejects DML / DDL keywords
    (INSERT / UPDATE / DELETE / DROP / CREATE / ALTER /
    ATTACH / DETACH / REPLACE / TRUNCATE / VACUUM / PRAGMA)
    in recipe SQL with recipe-aware error messages — defence in depth
    alongside the runtime PRAGMA query_only=1 backstop in
    query-engine.ts shipped in the previous release.

    Implementation: pure transport-agnostic loader in
    src/application/recipes-loader.ts; thin shim in
    src/cli/query-recipes.ts preserves backwards-compat exports
    (QUERY_RECIPES, getQueryRecipeSql, etc.). Hand-rolled YAML
    frontmatter parser scoped to the actions shape (no js-yaml
    dependency).

    .codemap.db is gitignored as before; .codemap/recipes/ is NOT
    (verified via git check-ignore) — recipes are git-tracked source
    code authored for human review.

  • #43 4061ac3 Thanks @SutuSebastian! - codemap query --format <text|json|sarif|annotations> — pipe any recipe row-set into GitHub Code Scanning (SARIF 2.1.0) or surface findings inline on PRs (GH Actions ::notice file=…,line=…::msg). Pure output-formatter additions on top of the existing JSON pipeline; no schema impact.

    Auto-detects file-path columns (file_path / path / to_path / from_path priority) and line_start (+ optional line_end) for SARIF region. Aggregate recipes without locations (index-summary, markers-by-kind) emit results: [] + a stderr warning. Rule id is codemap.<recipe-id> for --recipe, codemap.adhoc for ad-hoc SQL. Default result.level is "note"; per-recipe overrides via <id>.md frontmatter (sarifLevel, sarifMessage, sarifRuleId) deferred to v1.x.

    --format overrides --json when both passed; --json stays as the alias for --format json. Incompatible with --summary / --group-by / baseline (different output shapes — sarif/annotations only support flat row lists).

    MCP query and query_recipe tools accept the same format: "sarif" | "annotations" argument; query_batch deferred to v1.x.

  • #39 7460b46 Thanks @SutuSebastian! - feat(show + snippet): targeted-read CLI verbs + MCP tools

    Two sibling verbs that close the "agent wants to read this thing" loop
    without composing SQL:

    • codemap show <name> — returns metadata
      (file_path:line_start-line_end + signature + kind) for the
      symbol(s) matching the exact name (case-sensitive).
    • codemap snippet <name> — same lookup; each match also carries
      source (file lines from disk), stale (true when content_hash
      drifted since indexing), missing (true when file is gone).

    Both share the same flag set (--kind <k> filter, --in <path> file
    scope — directory prefix or exact file, normalized via the existing
    toProjectRelative helper for cross-platform consistency).

    Output is the agent-friendly {matches, disambiguation?} envelope on
    both CLI --json and MCP responses (uniformity contract per the MCP
    plan). Single match → {matches: [{...}]}; multi-match adds
    disambiguation: {n, by_kind, files, hint} — structured aids so the
    agent narrows without scanning every row. Forward-extensible (future
    nearest_to_cursor / most_recently_modified / caller_count fields
    land as additive keys).

    MCP tools show and snippet register parallel to the CLI verbs and
    auto-inherit the same envelope shape.

    Stale-file behavior on snippet: source is always returned when the
    file exists; stale: true is metadata the agent reads. No refusal,
    no auto-reindex side-effects — read tool stays read-only.

    Architecturally: pure transport-agnostic engine in
    src/application/show-engine.ts (mirrors the cmd-_ ↔ _-engine seam
    from PRs #33 / #35 / #37); thin CLI verbs in src/cli/cmd-show.ts

    • src/cli/cmd-snippet.ts. Reuses findSymbolsByName, hashContent
      (from src/hash.ts), toProjectRelative (now exported from
      cmd-validate.ts), and files.content_hash — same primitives the
      existing validate command already uses for stale detection. No
      schema change.

    Test coverage: 19 engine tests (lookup variants, line slicing, stale
    detection, missing files), 13 cmd-show parser/envelope tests, 11
    cmd-snippet parser/envelope/stale tests, 8 in-process MCP integration
    tests via @modelcontextprotocol/sdk's InMemoryTransport.

Patch Changes

  • #33 114303f Thanks @SutuSebastian! - codemap audit (B.5 v1) — structural-drift command emitting {head, deltas} where each deltas[<key>] carries {base, added, removed}. Three v1 deltas: files, dependencies, deprecated. Two snapshot-source shapes — --baseline <prefix> (auto-resolves <prefix>-files / <prefix>-dependencies / <prefix>-deprecated in query_baselines) and --<delta>-baseline <name> (explicit per-delta override; composes with --baseline). Reuses B.6 baselines; no schema bump. --summary collapses to per-delta counts; --no-index skips the auto-incremental-index prelude. v1 ships no verdict / threshold config — consumers compose --json + jq for CI exit codes (v1.x slice). --base <ref> (worktree+reindex snapshot) defers to v1.x.

  • #41 0134944 Thanks @SutuSebastian! - Internal refactor — lift cli/* envelope builders + path helpers into application/* engines so application/mcp-server.ts no longer reaches sideways into cli/. Affected modules: audit-engine (added resolveAuditBaselines), new context-engine (buildContextEnvelope, classifyIntent, ContextEnvelope), new validate-engine (computeValidateRows, toProjectRelative), show-engine (added buildShowResult, buildSnippetResult, ShowResult, SnippetResult, SnippetMatch), query-recipes moved from cli/ to application/. CLI verbs stay shells (parse / help / run / render). No behavior change, no public API change — cli/cmd-* and application/* are internal modules; the published surface (api.ts, the codemap binary, the MCP server) is untouched.

@github-actions github-actions Bot force-pushed the changeset-release/main branch 25 times, most recently from 505edf2 to 99c606b Compare May 4, 2026 07:56
@github-actions github-actions Bot force-pushed the changeset-release/main branch from 99c606b to 6bdb5af Compare May 4, 2026 09:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants