chore: version packages#31
Open
github-actions[bot] wants to merge 1 commit intomainfrom
Open
Conversation
505edf2 to
99c606b
Compare
99c606b to
6bdb5af
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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
119db38Thanks @SutuSebastian! - feat(mcp):codemap mcp— Model Context Protocol server (agent-transports v1)Adds the
codemap mcptop-level command — boots an MCP server overstdio 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,validateResources:
codemap://recipes,codemap://recipes/{id},codemap://schema,codemap://skill(lazy-cached)query_batchis MCP-only — N statements in one round-trip withbatch-wide-defaults + per-statement-overrides (items are
string | {sql, summary?, changed_since?, group_by?}). Per-statementerrors are isolated.
save_baselineships as one polymorphic tool(
{name, sql? | recipe?}with runtime exclusivity check) mirroringthe CLI's single
--save-baseline=<name>verb.Output shape is verbatim from each tool's CLI counterpart's
--jsonenvelope (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 wiringso HTTP inherits them when a concrete consumer asks.#52
fe5a355Thanks @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 andorigin/main?". Replaces today's 3-step--baselinedance (switch branches, reindex, save baselines, switch back) with one verb.Three transports, one engine:
codemap audit --base <ref> [--<delta>-baseline <name>] [--summary] [--json] [--no-index]auditwith newbase?: stringargPOST /tool/audit(auto-wired via the existing dispatcher)All three dispatch the same pure
runAuditFromRefengine inapplication/audit-engine.ts.How it works:
git rev-parse --verify "<ref>^{commit}"resolves<ref>to a sha (clean error on non-git or unresolvable ref).<projectRoot>/.codemap/audit-cache/<sha>/.codemap.db. Hit → sub-100ms; miss → continue.git worktree addto a per-pid temp dir +runCodemapIndex({mode: "full"})against the worktree's.codemap.db+ POSIXrenameclaims 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).diffRows(existing helper) computes{added, removed}.AuditEnvelopewith per-deltabase.source: "ref"(new value) +base.ref(user-supplied string) +base.sha(resolved).Decisions worth knowing:
AuditBaseis now a discriminated union — existing{source: "baseline", name, sha, indexed_at}rows untouched; new{source: "ref", ref, sha, indexed_at}arm. Consumers narrowing onbase.sourcekeep compiling.--baseline <prefix>. Parser + handler both guard. Per-delta--<key>-baselineoverrides compose orthogonally with both, so--base origin/main --files-baseline pre-refactor-filesis valid (mixed sources).git worktree remove --force+rm -rffor 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.--baseline,--<delta>-baseline) still work without git.audit-worktree.tsstrip inheritedGIT_*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 initnow 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
1313fc2Thanks @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>orCODEMAP_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.gitignorepatching surface to zero.New layout:
Self-healing files (D11):
<state-dir>/.gitignoreand<state-dir>/config.jsonare owned by idempotentensure*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 toSTATE_GITIGNORE_BODY(or extend the Zod schema), and every consumer's project repairs itself on the nextcodemapinvocation. No more per-feature.gitignorepatching inagents-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)rm .codemap.db .codemap.db-shm .codemap.db-walonce and re-index; movecodemap.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.tsextracts theloadUserConfig + resolveCodemapConfig + initCodemap + configureResolverdance 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 asz.infersource of truth, pure{before, after, written}return shapes for testability).Plan: PR #53 (merged). Implementation: PR #54.
#50
90092aeThanks @SutuSebastian! -codemap impact <target>— symbol/file blast-radius walker. Replaces hand-composedWITH RECURSIVEqueries 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:
codemap impact <target> [--direction up|down|both] [--depth N] [--via dependencies|calls|imports|all] [--limit N] [--summary] [--json]impact(registered alongsideshow/snippet)POST /tool/impactAll three dispatch the same pure
findImpactengine inapplication/impact-engine.tsper the post-PR #41 layering — adding tools never duplicates business logic.Decisions worth knowing:
/or matchesfiles.path→ file target; otherwise symbol (case-sensitive, exact). Symbol targets walkcalls; file targets walkdependencies+imports(resolved_pathonly). Mismatched explicit--viachoices land inskipped_backends(no error — agent sees why their selection yielded fewer rows than expected).instrit to break re-entry. Bounded depth +--limit(default 500) keep cyclic graphs cheap regardless.--depth 0walks unbounded but stays cycle-detected and limit-capped.summary.terminated_by:limit>depth>exhausted. CI gates can branch on it.--summaryshape. Trims thematchesarray but preservessummary.nodes— thejq '.summary.nodes'consumption pattern still works.Engine sketch: one
WITH RECURSIVEquery per (direction, backend) combo, JS-side merge + dedup by(direction, kind, name?, file_path)keeping the shallowest depth, thensummary.by_kind+terminated_byclassification.Plan: PR #49 (merged). Implementation: PR #50.
#44
4ec51d8Thanks @SutuSebastian! -codemap serve— HTTP server exposing the same tool taxonomy ascodemap mcpoverPOST /tool/{name}. For non-MCP consumers (CI scripts, simplecurl, IDE plugins that don't speak MCP).Default bind
127.0.0.1:7878(loopback only — refuse0.0.0.0unless explicitly opted in via--host 0.0.0.0). Optional--token <secret>requiresAuthorization: Bearer <secret>on every request;GET /healthis auth-exempt so liveness probes work without leaking the token. Barenode: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 = samecodemap query --jsonenvelope (NOT MCP's{content: [...]}wrapper).format: "sarif"payloads ship asapplication/sarif+json;format: "annotations"astext/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.{"error": "..."}with HTTP status 400 / 401 / 404 / 500.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 handlerscodemap mcpdispatches. No engine duplication;mcp-server.tsandhttp-server.tsboth wrap the sameToolResultdiscriminated union.Security: CSRF + DNS-rebinding guard rejects requests with
Sec-Fetch-Site: cross-site/same-site(modern-browser CSRF), anyOriginheader that isn'tnull(older-browser CSRF), andHostheader mismatch on loopback bind (DNS rebinding) — runs on every request including auth-exempt/health. Defends against a malicious local webpagefetch-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 = 1set per connection.#47
5ef9ce4Thanks @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:
codemap watch [--debounce 250] [--quiet]— foreground process; logsreindex N file(s) in Mmsper batch unless--quiet. SIGINT / SIGTERM drains pending edits.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.codemap serve --watch [--debounce <ms>]— same shape for non-MCP consumers (CI scripts, IDE plugins, simplecurl).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). Explicitno_index: falsestill forces the prelude.Env shortcut:
CODEMAP_WATCH=1(or"true") implies--watchformcp/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/ configuredexcludeDirNamesare skipped.#57
b5679a6Thanks @SutuSebastian! -codemap ingest-coverage <path>— static coverage ingestion. Reads Istanbul JSON (coverage-final.json) or LCOV (lcov.info) into a newcoveragetable joinable tosymbols, 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), andbun 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
actionsblock so agents see per-row follow-up hints in--jsonoutput.Schema:
coveragetable with natural-key PK(file_path, name, line_start)— intentionally not a FK tosymbols.idso coverage rows survive thesymbolsdrop-recreate cycle on every--fullreindex.idx_coverage_file_namecovers the typical join shape and theGROUP BY file_pathscan used by thefiles-by-coveragerecipe.metakeys (coverage_last_ingested_at/_path/_format) record ingest freshness.SCHEMA_VERSION5 → 6 — auto-rebuilds on nextcodemaprun; the new table is empty until firstingest-coverageinvocation. Subsequent bumps preserve coverage data via thedropAll()exclusion.CLI:
No
--sourceflag — 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 existingquery/query_recipetools (no parallel surface).Plan: PR #56 (merged). Implementation: this PR.
#30
a309d52Thanks @SutuSebastian! -codemap query --save-baseline/--baseline— snapshot a query result set and diff against it later. Stored in the newquery_baselinestable inside.codemap.db(no parallel JSON files).--baselineslists saved snapshots,--drop-baseline <name>deletes one. Diff identity is per-rowJSON.stringifyequality;--summarycollapses to{added: N, removed: N}. Recipeactionsattach to theaddedrows when running under--baseline. Baselines survive--fulland SCHEMA rebuilds.SCHEMA_VERSIONbumps from 4 to 5.#37
5110b1aThanks @SutuSebastian! - feat(recipes): recipes-as-content registry — bundled .md siblings + project-local recipesTwo complementary capabilities:
Bundled recipes get richer descriptions. Every bundled recipe in
templates/recipes/is now a<id>.sqlfile paired with an optional<id>.mddescription body (replaces the inline TypeScript map insrc/cli/query-recipes.ts). Per-rowactionstemplates live in YAMLfrontmatter on the
.mdinstead of code. Same surface for end users(
--recipe <id>/--recipes-json/codemap://recipes); singlestorage shape across bundled + project recipes.
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-jsonand thecodemap://recipesMCP resource alongsidebundled. Project recipes win on id collision; the catalog entry
carries
shadows: trueon overrides so agents reading the catalogat 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-jsonoutput,codemap://recipespayload) gain three additive fields:
body(full Markdown body),source("bundled" | "project"), andshadows?(true onproject 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=1backstop inquery-engine.tsshipped in the previous release.Implementation: pure transport-agnostic loader in
src/application/recipes-loader.ts; thin shim insrc/cli/query-recipes.tspreserves backwards-compat exports(
QUERY_RECIPES,getQueryRecipeSql, etc.). Hand-rolled YAMLfrontmatter parser scoped to the
actionsshape (nojs-yamldependency).
.codemap.dbis gitignored as before;.codemap/recipes/is NOT(verified via
git check-ignore) — recipes are git-tracked sourcecode authored for human review.
#43
4061ac3Thanks @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_pathpriority) andline_start(+ optionalline_end) for SARIF region. Aggregate recipes without locations (index-summary,markers-by-kind) emitresults: []+ a stderr warning. Rule id iscodemap.<recipe-id>for--recipe,codemap.adhocfor ad-hoc SQL. Defaultresult.levelis"note"; per-recipe overrides via<id>.mdfrontmatter (sarifLevel,sarifMessage,sarifRuleId) deferred to v1.x.--formatoverrides--jsonwhen both passed;--jsonstays as the alias for--format json. Incompatible with--summary/--group-by/ baseline (different output shapes — sarif/annotations only support flat row lists).MCP
queryandquery_recipetools accept the sameformat: "sarif" | "annotations"argument;query_batchdeferred to v1.x.#39
7460b46Thanks @SutuSebastian! - feat(show + snippet): targeted-read CLI verbs + MCP toolsTwo 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 thesymbol(s) matching the exact name (case-sensitive).
codemap snippet <name>— same lookup; each match also carriessource(file lines from disk),stale(true when content_hashdrifted since indexing),
missing(true when file is gone).Both share the same flag set (
--kind <k>filter,--in <path>filescope — directory prefix or exact file, normalized via the existing
toProjectRelativehelper for cross-platform consistency).Output is the agent-friendly
{matches, disambiguation?}envelope onboth CLI
--jsonand MCP responses (uniformity contract per the MCPplan). Single match →
{matches: [{...}]}; multi-match addsdisambiguation: {n, by_kind, files, hint}— structured aids so theagent narrows without scanning every row. Forward-extensible (future
nearest_to_cursor/most_recently_modified/caller_countfieldsland as additive keys).
MCP tools
showandsnippetregister parallel to the CLI verbs andauto-inherit the same envelope shape.
Stale-file behavior on snippet:
sourceis always returned when thefile exists;
stale: trueis 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 seamfrom PRs #33 / #35 / #37); thin CLI verbs in
src/cli/cmd-show.tssrc/cli/cmd-snippet.ts. ReusesfindSymbolsByName,hashContent(from
src/hash.ts),toProjectRelative(now exported fromcmd-validate.ts), andfiles.content_hash— same primitives theexisting
validatecommand already uses for stale detection. Noschema 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'sInMemoryTransport.Patch Changes
#33
114303fThanks @SutuSebastian! -codemap audit(B.5 v1) — structural-drift command emitting{head, deltas}where eachdeltas[<key>]carries{base, added, removed}. Three v1 deltas:files,dependencies,deprecated. Two snapshot-source shapes —--baseline <prefix>(auto-resolves<prefix>-files/<prefix>-dependencies/<prefix>-deprecatedinquery_baselines) and--<delta>-baseline <name>(explicit per-delta override; composes with--baseline). Reuses B.6 baselines; no schema bump.--summarycollapses to per-delta counts;--no-indexskips the auto-incremental-index prelude. v1 ships noverdict/ threshold config — consumers compose--json+jqfor CI exit codes (v1.x slice).--base <ref>(worktree+reindex snapshot) defers to v1.x.#41
0134944Thanks @SutuSebastian! - Internal refactor — liftcli/*envelope builders + path helpers intoapplication/*engines soapplication/mcp-server.tsno longer reaches sideways intocli/. Affected modules:audit-engine(addedresolveAuditBaselines), newcontext-engine(buildContextEnvelope,classifyIntent,ContextEnvelope), newvalidate-engine(computeValidateRows,toProjectRelative),show-engine(addedbuildShowResult,buildSnippetResult,ShowResult,SnippetResult,SnippetMatch),query-recipesmoved fromcli/toapplication/. CLI verbs stay shells (parse / help / run / render). No behavior change, no public API change —cli/cmd-*andapplication/*are internal modules; the published surface (api.ts, thecodemapbinary, the MCP server) is untouched.