Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/ci-output-formats.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@stainless-code/codemap": patch
---

Add `query --format codeclimate` (GitLab Code Quality JSON) and `query --format badge` (markdown issue-count line or `codemap-badge/v1` JSON via `--badge-style json`). Available on CLI, MCP, and HTTP query tools.
16 changes: 11 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,17 +131,23 @@ codemap audit --base v1.0.0 --files-baseline pre-release-files # mix --base wit
# non-git projects get a clean `codemap audit: --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
# --format <text|json|sarif|annotations|mermaid|diff|diff-json|codeclimate|badge> — SARIF for GitHub
# Code Scanning; annotations for GH Actions ::notice lines; codeclimate for GitLab Code Quality;
# badge for issue-count summaries; mermaid/diff for graph and edit previews. 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
# (no --summary / --group-by / baseline). SARIF / annotations / codeclimate / badge
# auto-detect file_path / path / to_path / from_path; rule.id is codemap.<recipe-id>
# (or codemap.adhoc). codeclimate/badge skip aggregate-only rows. 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
# GitLab Code Quality artifact (locatable rows only; flat minor severity):
codemap query --recipe boundary-violations --format codeclimate > gl-code-quality-report.json
# Badge summary for README paste or CI (counts locatable rows only):
codemap query --recipe boundary-violations --format badge
codemap query --recipe boundary-violations --format badge --badge-style json | jq -e '.status == "pass"'
# 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 -
Expand Down
6 changes: 3 additions & 3 deletions docs/architecture.md

Large diffs are not rendered by default.

14 changes: 13 additions & 1 deletion docs/glossary.md
Original file line number Diff line number Diff line change
Expand Up @@ -544,7 +544,19 @@ Long-running process that subscribes to filesystem changes via [chokidar v5](htt

### `codemap serve` / HTTP server

Long-running 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. HTTP returns each tool's native JSON payload directly (NOT MCP's `{content: [...]}` wrapper); `query` / `query_recipe` match `codemap query --json` row arrays unless `summary` / `group_by` reshape the envelope, or `baseline` returns a diff envelope (incompatible with non-`json` `format` / `group_by`; save/list/drop remain separate tools); parity twins (`query batch`, `trace`, `explore`, `node`, `file`, `schema`, `symbols`, `context`, `ingest-coverage`) always emit JSON on CLI without `--json`; other tools match their CLI `--json` payloads when that flag is set; `format: "sarif"` payloads ship as `application/sarif+json`, `format: "annotations"` / `"mermaid"` / `"diff"` as `text/plain; charset=utf-8`, `format: "diff-json"` as `application/json; charset=utf-8`. Routes: `POST /tool/{name}` (every MCP tool), `GET /resources/{encoded-uri}` (resource handler for `codemap://recipes`, `codemap://recipes/{id}`, `codemap://schema`, `codemap://skill`, `codemap://rule`, `codemap://mcp-instructions`, `codemap://files/{path}`, and `codemap://symbols/{name}`), `GET /health` (auth-exempt liveness probe — does not start the watcher), `GET /tools` / `GET /resources` (catalogs). With `--watch`, chokidar is refcount-gated per request and stops 5s after the last client (`HTTP_WATCH_RELEASE_GRACE_MS`) — distinct from MCP idle shutdown; the HTTP process keeps listening. Pure transport — same `tool-handlers.ts` / `resource-handlers.ts` MCP uses; no engine duplication. Errors → `{"error": "..."}` with HTTP status 400 / 401 / 403 / 404 / 500. SIGINT / SIGTERM → graceful drain. Every response carries `X-Codemap-Version: <semver>`. **CSRF + DNS-rebinding guard:** every request (including auth-exempt `/health`) is evaluated against `Sec-Fetch-Site` / `Origin` / `Host` when present — modern browsers send `Sec-Fetch-Site` and `Origin` on cross-origin fetches (header presence varies by request type, browser, and privacy settings), so the guard rejects browser-driven cross-origin requests like a malicious local webpage `fetch`-ing `http://127.0.0.1:7878/tool/save_baseline` to mutate `.codemap/index.db`. `Host` mismatch on a loopback bind blocks DNS rebinding (an attacker resolving `evil.com` to `127.0.0.1` post-load). Non-browser clients (curl, fetch from Node, MCP hosts, CI scripts) typically omit these headers and pass through. Implementation: `src/cli/cmd-serve.ts` (CLI shell) + `src/application/http-server.ts` (transport). See [`architecture.md` § HTTP wiring](./architecture.md#cli-usage).
Long-running 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. HTTP returns each tool's native JSON payload directly (NOT MCP's `{content: [...]}` wrapper); `query` / `query_recipe` match `codemap query --json` row arrays unless `summary` / `group_by` reshape the envelope, or `baseline` returns a diff envelope (incompatible with non-`json` `format` / `group_by`; save/list/drop remain separate tools); parity twins (`query batch`, `trace`, `explore`, `node`, `file`, `schema`, `symbols`, `context`, `ingest-coverage`) always emit JSON on CLI without `--json`; other tools match their CLI `--json` payloads when that flag is set; `format: "sarif"` payloads ship as `application/sarif+json`, `format: "annotations"` / `"mermaid"` / `"diff"` / `"badge"` (markdown) as `text/plain; charset=utf-8`, `format: "diff-json"` / `"codeclimate"` / `"badge"` + `badge_style: "json"` as `application/json; charset=utf-8`. Routes: `POST /tool/{name}` (every MCP tool), `GET /resources/{encoded-uri}` (resource handler for `codemap://recipes`, `codemap://recipes/{id}`, `codemap://schema`, `codemap://skill`, `codemap://rule`, `codemap://mcp-instructions`, `codemap://files/{path}`, and `codemap://symbols/{name}`), `GET /health` (auth-exempt liveness probe — does not start the watcher), `GET /tools` / `GET /resources` (catalogs). With `--watch`, chokidar is refcount-gated per request and stops 5s after the last client (`HTTP_WATCH_RELEASE_GRACE_MS`) — distinct from MCP idle shutdown; the HTTP process keeps listening. Pure transport — same `tool-handlers.ts` / `resource-handlers.ts` MCP uses; no engine duplication. Errors → `{"error": "..."}` with HTTP status 400 / 401 / 403 / 404 / 500. SIGINT / SIGTERM → graceful drain. Every response carries `X-Codemap-Version: <semver>`. **CSRF + DNS-rebinding guard:** every request (including auth-exempt `/health`) is evaluated against `Sec-Fetch-Site` / `Origin` / `Host` when present — modern browsers send `Sec-Fetch-Site` and `Origin` on cross-origin fetches (header presence varies by request type, browser, and privacy settings), so the guard rejects browser-driven cross-origin requests like a malicious local webpage `fetch`-ing `http://127.0.0.1:7878/tool/save_baseline` to mutate `.codemap/index.db`. `Host` mismatch on a loopback bind blocks DNS rebinding (an attacker resolving `evil.com` to `127.0.0.1` post-load). Non-browser clients (curl, fetch from Node, MCP hosts, CI scripts) typically omit these headers and pass through. Implementation: `src/cli/cmd-serve.ts` (CLI shell) + `src/application/http-server.ts` (transport). See [`architecture.md` § HTTP wiring](./architecture.md#cli-usage).

### Code Climate format (`codeclimate`)

GitLab [Code Quality](https://docs.gitlab.com/ee/ci/testing/code_quality.html) JSON array emitted by `codemap query --format codeclimate` (MCP/HTTP: `format: "codeclimate"`). One object per locatable row (`file_path` / `path` / `to_path` / `from_path` + optional `line_start`); flat `severity: "minor"` in v1; `location.lines.begin` defaults to `1` without `line_start`; stable SHA-256 fingerprints (recipe + path + line + check name + row message) for GitLab dedup. Aggregate recipes emit `[]` + stderr warning. Incompatible with `--summary` / `--group-by` / baseline.

### Badge format (`badge`)

Issue-count presentation derived from locatable-row count only — not a triage primitive. CLI: `codemap query --format badge` prints `codemap: N issues` / `codemap: clean`; `--badge-style json` emits `codemap-badge/v1` (`{schema, label, message, count, status}`). MCP/HTTP: `format: "badge"` + optional `badge_style`. Agents should triage via JSON query rows or `--summary`, not badge stdout.

### `codemap-badge/v1`

JSON schema for structured badge output (`badge_style: "json"`). Fields: `schema`, `label` (`"codemap"`), `message`, `count`, `status` (`pass` when `count === 0`). Intended for CI gates (`jq -e '.status == "pass"'`).

### SARIF

Expand Down
102 changes: 0 additions & 102 deletions docs/plans/ci-output-formats.md

This file was deleted.

1 change: 0 additions & 1 deletion docs/roadmap.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,6 @@ Predicate-as-API only — enrich row shape and audit deltas; no standalone pass/
- [ ] **Tiered lookup fast paths** — `show` / exact-name recipe paths hit covering indexes first; document latency expectations in MCP tool descriptions. FTS and broad scans remain explicit fallbacks. Effort: S–M.
- [ ] **Graph-estimated CRAP recipe** — bundled `high-crap-score`: CRAP = `CC² × (1 - coverage/100)³ + CC` using `symbols.complexity`; **measured** `coverage` when ingested, else **graph-estimated** tiers (85% / 40% / 0% from test-file reachability over `dependencies` / `calls` / `test_suites`). Rows expose `coverage_source: measured | estimated`. Complements `high-complexity-untested` when no coverage file exists. Plan: [`plans/graph-estimated-crap.md`](./plans/graph-estimated-crap.md). Effort: M.
- [ ] **Coverage-confirmed dead recipe** — bundled `coverage-confirmed-dead`: JOIN static dead-code predicate (uncalled exports, suppression-aware) with ingested `coverage` — rows carry `confidence: high` when callers = 0 and `coverage_pct = 0`, `medium` when coverage not ingested. Predicate columns only, no verdict primitive ([Moat A](./roadmap.md#moats-load-bearing)). Plan: [`plans/coverage-deletion-confidence.md`](./plans/coverage-deletion-confidence.md). Effort: L–M.
- [ ] **CI output formats (CodeClimate + badge)** — `query --format codeclimate` (GitLab Code Quality JSON array + stable fingerprints) and `query --format badge` (compact issue-count line for README/CI summary). Same location contract as SARIF/annotations. Plan: [`plans/ci-output-formats.md`](./plans/ci-output-formats.md). Effort: S–M.

### Distribution & evaluation depth

Expand Down
Loading
Loading