Skip to content

Commit edee493

Browse files
committed
docs: sweep stale watch / params / diff references after PR #71 merge
Fact-checked docs/ against the post-merge codebase. - docs/roadmap.md: Floors entry for "No daemon by default" rewritten — mcp / serve watcher is default-ON since 2026-05; opt out with --no-watch or CODEMAP_WATCH=0. The advisory unused-type-members backlog item now reads "re-evaluate the overlap with the now-shipped rename-preview" instead of the stale "ship after rename-preview lands". - docs/architecture.md: Watch wiring no longer claims `mcp --watch` / `serve --watch` are the "killer combo" — both are default-ON, and CODEMAP_WATCH=1 is now a backwards-compat no-op. HTTP wiring lists diff / diff-json content-types alongside sarif / annotations / mermaid. - docs/glossary.md: watch glossary entry reflects the default-ON flip; CODEMAP_WATCH=0 documented as the env-shortcut opt-out. - docs/research/non-goals-reassessment-2026-05.md: § 1 "Shipped since this inventory" gains rows for § 1.10 rename-preview + parametrised recipes (PR #71) and § 6 Q1 daemon-default flip (commit 31479a5). § 5 cadence marks the same items ✅. § 7 "Lifted to" rows updated from "(pending)" / "(resolved-but-unshipped)" to shipped destinations. No code changes. Closed historical research notes (fallow.md, competitive-scan-2026-04.md) preserved as-is per docs-governance.
1 parent fc6790b commit edee493

4 files changed

Lines changed: 38 additions & 36 deletions

File tree

docs/architecture.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,9 +137,9 @@ A local SQLite database (`.codemap/index.db`) indexes the project tree and store
137137

138138
**MCP wiring:** **`src/cli/cmd-mcp.ts`** (argv — `--help` only; bootstrap absorbs `--root`/`--config`) + **`src/application/mcp-server.ts`** (transport — tool / resource registry, SDK glue). Mirrors the `cmd-audit.ts ↔ audit-engine.ts` seam — CLI parses + lifecycle; engine owns the SDK. **`runMcpServer`** bootstraps codemap once at server boot (config + resolver + DB access become module-level state), instantiates `McpServer` from **`@modelcontextprotocol/sdk`**, attaches a **`StdioServerTransport`**, and resolves when stdin closes (clean shutdown). Tool handlers reuse the existing engine entry-points: **`query`** + **`query_recipe`** call **`executeQuery`** in **`src/application/query-engine.ts`** (a pure transport-agnostic engine extracted from `printQueryResult`'s JSON branch — same `[...rows]` / `{count}` / `{group_by, groups}` envelope `--json` would print); **`query_batch`** loops via **`executeQueryBatch`** with batch-wide-defaults + per-statement-overrides (items are `string | {sql, summary?, changed_since?, group_by?}`); **`audit`** runs `resolveAuditBaselines` + `runAudit` from PR #33 unchanged; **`context`** / **`validate`** call `buildContextEnvelope` / `computeValidateRows` from **`src/application/context-engine.ts`** + **`src/application/validate-engine.ts`** (lifted out of `src/cli/cmd-*.ts` in PR #41 — see § Tool / resource handlers above). **`save_baseline`** is one polymorphic tool (`{name, sql? | recipe?}`) with a runtime exclusivity check — mirrors the CLI's single `--save-baseline=<name>` verb. **Tool naming**: snake_case throughout — Codemap convention matching the patterns in MCP spec examples and reference servers (GitHub MCP, Cursor built-ins); the spec itself doesn't mandate it. CLI stays kebab — translation lives at the MCP-arg layer. **Resources** (`codemap://recipes`, `codemap://recipes/{id}`, `codemap://schema`, `codemap://skill`) use **lazy memoisation** — first `read_resource` populates a per-server-instance cache; constant for the server-process lifetime so eager-vs-lazy produce identical observable behavior. `codemap://schema` queries `sqlite_schema` live; `codemap://skill` reads from `resolveAgentsTemplateDir() + skills/codemap/SKILL.md`. Output shape uniformity (plan § 4): every tool returns the JSON envelope its CLI counterpart's `--json` flag prints, surfaced via `content: [{type: "text", text: JSON.stringify(payload)}]`. `--changed-since` git lookups are memoised per `(root, ref)` pair across batch items so a `query_batch` of N items sharing the same ref does one git invocation, not N. Per-statement errors in `query_batch` are isolated — failed statements return `{error}` in their slot while siblings still execute.
139139

140-
**HTTP wiring:** **`src/cli/cmd-serve.ts`** (argv — `--host` / `--port` / `--token`; bootstrap absorbs `--root`/`--config`) + **`src/application/http-server.ts`** (transport — bare `node:http`; routes `POST /tool/{name}` to `tool-handlers`, `GET /resources/{encoded-uri}` to `resource-handlers`, plus `GET /health` / `GET /tools` / `GET /resources`). 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. **CSRF + DNS-rebinding guard** (`csrfCheck`) runs before every route — rejects `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). Non-browser clients (curl, fetch from Node, MCP hosts, CI scripts) don't send those headers and pass through. The guard runs even on `/health` so a malicious local webpage can't probe for liveness. Output shape uniformity (plan § D5): every tool returns the same `codemap query --json` envelope (NOT MCP's `{content: [...]}` wrapper — HTTP doesn't need that transport artifact); `format: "sarif"` payloads ship as `application/sarif+json`, `format: "annotations"` as `text/plain`, JSON otherwise. Per-request DB lifecycle: open / `PRAGMA query_only = 1` / close per call (SQLite reader concurrency); 1 MiB request-body cap rejects trivial DoS. SIGINT / SIGTERM → graceful drain via `server.close()`. Every response carries **`X-Codemap-Version: <semver>`** so consumers can pin / detect upgrades.
140+
**HTTP wiring:** **`src/cli/cmd-serve.ts`** (argv — `--host` / `--port` / `--token`; bootstrap absorbs `--root`/`--config`) + **`src/application/http-server.ts`** (transport — bare `node:http`; routes `POST /tool/{name}` to `tool-handlers`, `GET /resources/{encoded-uri}` to `resource-handlers`, plus `GET /health` / `GET /tools` / `GET /resources`). 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. **CSRF + DNS-rebinding guard** (`csrfCheck`) runs before every route — rejects `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). Non-browser clients (curl, fetch from Node, MCP hosts, CI scripts) don't send those headers and pass through. The guard runs even on `/health` so a malicious local webpage can't probe for liveness. Output shape uniformity (plan § D5): every tool returns the same `codemap query --json` envelope (NOT MCP's `{content: [...]}` wrapper — HTTP doesn't need that transport artifact); `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`, JSON otherwise. Per-request DB lifecycle: open / `PRAGMA query_only = 1` / close per call (SQLite reader concurrency); 1 MiB request-body cap rejects trivial DoS. SIGINT / SIGTERM → graceful drain via `server.close()`. Every response carries **`X-Codemap-Version: <semver>`** so consumers can pin / detect upgrades.
141141

142-
**Watch wiring:** **`src/cli/cmd-watch.ts`** (argv — `--debounce <ms>` / `--quiet`; bootstrap absorbs `--root`/`--config`) + **`src/application/watcher.ts`** (engine — pure debouncer + glob filter + injectable backend; production wires [chokidar v5](https://github.com/paulmillr/chokidar) selected via the 6-watcher audit in PR #46 — pure JS, runs identically on Bun + Node, ~30M repos use it). On every change/add/unlink event chokidar emits, the engine filters via `shouldIndexPath` (same indexed extensions as the indexer + project-local recipes; skips `node_modules` / `.git` / `dist`), debounces with a sliding window (default 250 ms), then calls `createReindexOnChange` which opens a DB, runs `runCodemapIndex({mode: 'files', files: [...changed]})`, closes the DB, and logs `reindex N file(s) in Mms` to stderr unless `--quiet`. SIGINT / SIGTERM drains pending edits via `flushNow()` before the watcher closes. **Killer combo:** `mcp --watch` and `serve --watch` (also `CODEMAP_WATCH=1`) boot the transport AND the watcher in one process — eliminates the per-request reindex prelude every MCP / HTTP query rides on. **Audit prelude optimization:** module-level `watchActive` flag; `handleAudit` skips its incremental-index prelude when active (and marks the close as readonly to avoid a wasted checkpoint). Explicit `no_index: false` still forces the prelude.
142+
**Watch wiring:** **`src/cli/cmd-watch.ts`** (argv — `--debounce <ms>` / `--quiet`; bootstrap absorbs `--root`/`--config`) + **`src/application/watcher.ts`** (engine — pure debouncer + glob filter + injectable backend; production wires [chokidar v5](https://github.com/paulmillr/chokidar) selected via the 6-watcher audit in PR #46 — pure JS, runs identically on Bun + Node, ~30M repos use it). On every change/add/unlink event chokidar emits, the engine filters via `shouldIndexPath` (same indexed extensions as the indexer + project-local recipes; skips `node_modules` / `.git` / `dist`), debounces with a sliding window (default 250 ms), then calls `createReindexOnChange` which opens a DB, runs `runCodemapIndex({mode: 'files', files: [...changed]})`, closes the DB, and logs `reindex N file(s) in Mms` to stderr unless `--quiet`. SIGINT / SIGTERM drains pending edits via `flushNow()` before the watcher closes. **Default-ON for `mcp` / `serve` since 2026-05:** both transports boot the watcher in-process so every tool reads a live index — eliminates the per-request reindex prelude. Opt out with `--no-watch` or `CODEMAP_WATCH=0` (`CODEMAP_WATCH=1` still parses for backwards-compat but is now a no-op since it matches the default). Standalone `codemap watch` runs the watcher decoupled from a transport for users wiring it next to a separate MCP / HTTP process. **Audit prelude optimization:** module-level `watchActive` flag; `handleAudit` skips its incremental-index prelude when active (and marks the close as readonly to avoid a wasted checkpoint). Explicit `no_index: false` still forces the prelude.
143143

144144
**Performance wiring:** **`--performance`** plumbs through **`RunIndexOptions.performance`****`indexFiles({ performance, collectMs })`**. `parse-worker-core.ts` records per-file **`parseMs`** on each `ParsedFile`; main thread times the four phases (`collect`, `parse`, `insert`, `index_create`) and assembles **`IndexPerformanceReport`** under `IndexRunStats.performance`. Note: `total_ms` is `indexFiles` wall-clock, **not** end-to-end run wall — `collect_ms` happens before `indexFiles` and is reported separately.
145145

docs/glossary.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -436,10 +436,10 @@ Integer constant in `src/db.ts`. Bumped whenever the DDL changes. `createSchema(
436436
Long-running process that subscribes to filesystem changes via [chokidar v5](https://github.com/paulmillr/chokidar) and re-indexes only the changed files via `runCodemapIndex({mode: 'files'})`. Eliminates the "is the index stale?" friction every CLI / MCP / HTTP query rides on today: agents in long sessions or multi-step refactors can `query` immediately after editing without remembering to reindex. Debounced (default 250 ms) so a burst — `git checkout`, `npm install`, multi-file save — collapses to one reindex call. Filters event paths the same way the indexer does (TS / TSX / JS / JSX / CSS + project-local recipes; skips `node_modules`, `.git`, `dist`, etc.). SIGINT / SIGTERM drains pending edits before exit. Three shapes:
437437

438438
- **Standalone**: `codemap watch` — foreground process; logs `reindex N file(s) in Mms` per batch unless `--quiet`.
439-
- **Combined with MCP**: `codemap mcp --watch` — boots stdio MCP server + watcher in one process; agents never hit a stale index.
440-
- **Combined with HTTP**: `codemap serve --watch` — boots HTTP server + watcher; CI scripts / IDE plugins read live data.
439+
- **Combined with MCP**: `codemap mcp` — boots stdio MCP server + watcher in one process by default since 2026-05; agents never hit a stale index. Pass `--no-watch` to disable.
440+
- **Combined with HTTP**: `codemap serve` — boots HTTP server + watcher by default; CI scripts / IDE plugins read live data. Pass `--no-watch` to disable.
441441

442-
`CODEMAP_WATCH=1` env var is shorthand for adding `--watch` to either `codemap mcp` or `codemap serve` (useful for IDE / CI launches that can't easily edit the spawn command). When watch is active, the audit tool's incremental-index prelude becomes a no-op on both transports (the watcher already keeps the index fresh — saves the per-request reindex cost on every `mcp audit` and every `POST /tool/audit`). Implementation: `src/cli/cmd-watch.ts` (CLI shell) + `src/application/watcher.ts` (engine — pure debouncer + chokidar backend; injectable backend for tests). See [`architecture.md` § Watch wiring](./architecture.md#cli-usage).
442+
`CODEMAP_WATCH=0` (or `"false"`) is the env-shortcut for opting out of the default-ON watcher on `codemap mcp` / `codemap serve` useful for IDE / CI launches that can't easily edit the spawn command. `CODEMAP_WATCH=1` still parses for backwards-compat but is now a no-op (it matches the new default). When watch is active, the audit tool's incremental-index prelude becomes a no-op on both transports (the watcher already keeps the index fresh — saves the per-request reindex cost on every `mcp audit` and every `POST /tool/audit`). Implementation: `src/cli/cmd-watch.ts` (CLI shell) + `src/application/watcher.ts` (engine — pure debouncer + chokidar backend; injectable backend for tests). See [`architecture.md` § Watch wiring](./architecture.md#cli-usage).
443443

444444
### `codemap serve` / HTTP server
445445

0 commit comments

Comments
 (0)