Commit ebd4c34
authored
feat(cli): codemap validate / context / --performance, four new query recipes, friendlier no-DB error (#23)
* chore(deps): bump runtime and dev dependencies
Routine bumps caught by lockfile drift; no functional changes.
* docs: anti-pitch, scenario-keyed token table, capability table, daily commands
- why-codemap.md: add "What Codemap is not" section (anti-pitch — preempts
"is this an LSP / agent / smart tool?" reading); replace narrative
token-savings text with scenario-keyed rows (single lookup → 50-turn
session) backed by a methodology footnote pointing at bun run benchmark:query
- README.md: add "What you get" Grep/Read vs Codemap capability table near
the top; add a "Daily commands" stripe and a "version-matched Agent Skill"
packaging line in the CLI section
- docs/research/competitive-scan-2026-04.md: capture the audit of fallow,
AZidan/codemap, and JordanCoin/codemap that drove the messaging changes
- .agents/lessons.md: add bump-policy lesson (patch by default for 0.x;
reserve minor for schema-breaking changes; strict SemVer post-1.0)
* chore(lint): tighten oxlint baseline; ignore fixtures
Add the import plugin and 11 stricter rules: prefer-const, type-import
hoisting (consistent-type-specifier-style: prefer-top-level), interface
preference for object types, no-confusing-non-null-assertion,
no-unnecessary-{boolean-literal-compare,template-expression,type-assertion},
prefer-{includes,nullish-coalescing,optional-chain}, and
unicorn/switch-case-braces.
Add fixtures/ to ignorePatterns so hand-crafted parser test corpora are
never auto-mutated (prevents golden churn — discovered when an auto-fix
on fixtures/minimal/src/consumer.ts split a mixed import and broke the
imports-consumer-alias / files-hashes / index-summary scenarios).
Source-side auto-fixes from these rules ship with the feature commits
that follow.
* feat(query): four new recipes, -r short alias, cleaner --help
Recipes (all parameterless SQL on the existing schema):
- deprecated-symbols — symbols whose JSDoc contains @deprecated; lets
agents flag callers of soon-to-be-removed APIs
- visibility-tags — symbols tagged @internal / @Private / @Alpha / @beta
- files-hashes — every indexed file with content_hash; powers the
forthcoming `codemap validate` CLI
- barrel-files — top files by export count (public-API hubs)
CLI:
- -r is now a short alias for --recipe (e.g. `codemap query -r fan-out`)
- --help is reorganized: sectioned flags, dynamic recipe-id padding,
examples for both --recipe and -r forms
Fixtures:
- @deprecated and @internal JSDoc added to fixtures/minimal/src/utils/date.ts
to give the new recipes real rows to assert on
- 4 new golden scenarios + index-summary refresh (symbols 8 → 9)
* feat(cli): codemap validate, codemap context, --performance, friendlier no-DB error; JSDoc the public type surface
CLI commands and flags
- codemap validate [--json] [paths...] — diffs disk SHA-256 against
files.content_hash; statuses: stale | missing | unindexed; exits 1 on
any drift (git-status semantics) so agents can branch on $?
- codemap context [--compact] [--for "<intent>"] — stable JSON envelope
(project metadata, top hubs, recent markers, recipe catalog). --for runs
lightweight intent classification (refactor / debug / test / feature /
explore / other) and returns matched recipe ids plus a hint
- codemap --performance — per-phase breakdown
(collect / parse / insert / index_create) plus top-10 slowest files by
parse time during full rebuild; surfaces pathological inputs
- Friendlier no-.codemap.db error — `no such table: <X>` rewrites to an
actionable hint pointing at `codemap` / `codemap --full`, on both the
JSON and human paths
- bootstrap.ts whitelists the new subcommands and flag
Public type surface (visible in dist/index.d.mts via the existing index re-exports)
- New IndexPerformanceReport; IndexRunStats.performance? field
- Per-field JSDoc on IndexResult, IndexRunStats, IndexPerformanceReport,
IndexTableStats (snake_case key note), ResolvedCodemapConfig
- Interface-level JSDoc on every db.ts row interface (FileRow, SymbolRow,
ImportRow, ExportRow, ComponentRow, DependencyRow, MarkerRow,
CssVariableRow, CssClassRow, CssKeyframeRow, CallRow, TypeMemberRow)
with cross-links to docs/architecture.md § Schema as the single source
- Per-field JSDoc on ParsedFile (clarifies error vs parseError, category
semantics, CSS-only fields, cssImportSources main-thread conversion)
- @param/@returns on getAdapterForExtension
Implementation plumbing
- ParsedFile gains optional parseMs?, populated by parse-worker-core.ts
- RunIndexOptions.performance threads through index-engine.ts and run-index.ts
- index-engine.ts times collect / parse / insert / createIndexes phases when
the flag is on; bottom-of-summary block prints the breakdown plus the
slowest_files list
Auto-fixes from the new lint baseline
- import type hoisting (consistent-type-specifier-style: prefer-top-level)
- type X = {...} → interface X {...} for object shapes (ValidateRow,
ValidateOpts, ContextEnvelope, ContextOpts)
- switch case braces in src/parser.ts (12 keyword-mapping cases) and
src/agents-init.ts
Tests
- 9 new tests for cmd-validate (parse + computeValidateRows: stale, missing,
unindexed, dedup, sort)
- 14 new tests for cmd-context (parse + classifyIntent: 6 categories + fallback)
- 2 new cases on cmd-query for -r
Changeset entered as patch (matches 0.x precedent for additive changes;
schema unchanged).
* fix(cli): address PR #23 review — recent_markers misnomer, validate TOCTOU, --compact, --for guard, README
Adopts the 7 valid items from CodeRabbit review.
A1 — `recent_markers` was alphabetical-first-20, not recency-ordered (the
markers table has no timestamp column). Rename to `sample_markers` with a
JSDoc note pointing at the proper time-ordered query (join `files.last_modified`).
A2 — `cmd-validate.ts` had a TOCTOU between existsSync and readFileSync.
Replace with a single guarded read; also drops one syscall in the common
path (open instead of stat + open).
N2 — Rename `performance` local in cmd-index.ts to `reportPerformance`
to avoid shadowing the global `performance` API.
N4 — Route the `files-hashes` golden through the bundled recipe (was
inline SQL); now exercises the recipe SQL itself and prevents drift.
Snapshot refreshed.
N5 — Add `validate` and `context` to the README "Daily commands" stripe;
they were the headline additions in this PR but weren't on the showcase.
N7 — `--for ""` was accepted as a valid intent and silently classified
as "other". Reject empty-string values with the same error as missing.
N8 — `--compact` now actually compacts: `JSON.stringify` is called
without indent in compact mode (was unconditional 2-space pretty-print).
Tests: +1 case for `--for ""` rejection. 19/19 goldens green, 24/24
cmd-context + cmd-validate tests pass.
* feat(db): tighten NOT NULL on every Row-interface non-nullable column; bump SCHEMA_VERSION 2 → 3
Closes review item N1: until now FileRow declared `size`, `line_count`,
`language`, `last_modified`, `indexed_at` as non-nullable in TypeScript,
but the SQLite schema only required `path` and `content_hash` to be
NOT NULL — so a row read back via `query<FileRow>(...)` could legally
surface null for any of those columns. The same gap applied to 8 other
tables (symbols, imports, exports, components, markers, css_variables,
css_classes, css_keyframes, type_members).
This commit aligns the SQL invariants with the existing TypeScript types:
add NOT NULL to every column whose Row-interface type is non-nullable.
The DEFAULT 0 columns gain NOT NULL too so the constraint is enforced
even when the writer omits the column. `calls` and `dependencies` were
already fully constrained — no change.
`SCHEMA_VERSION` bumps 2 → 3. The existing `createSchema()` version-
mismatch detector picks up the bump on first open and triggers a full
rebuild — verified locally (meta.schema_version = "3" after one run).
Changeset bumped to minor per .agents/lessons.md (schema-breaking
changes that force a .codemap.db rebuild are minor, even pre-1.0).
* docs: tighten JSDoc comments on public types
Concise rewrite of the JSDocs added in the previous commits. Keeps the
non-obvious facts (FK cascade, JSON-encoded fields, recipe pointers,
related-table cross-references, total_ms vs collect_ms gotcha,
snake_case key convention on IndexTableStats) and drops the boilerplate:
- 12 row interfaces in db.ts: collapse the per-table architecture.md
links (single source already lives in docs/architecture.md § Schema).
Keep the high-signal hints (FK behavior on FileRow, JSDoc-tag recipes
on SymbolRow, dependencies cross-link on ImportRow, JSON shape on
ComponentRow.hooks_used, scope semantics on CssVariableRow,
is_module/`.module.css` rule on CssClassRow, dedup keying on CallRow,
null type semantics on TypeMemberRow).
- ParsedFile: drop redundant per-field one-liners that just restated
the field name; keep error/parseError distinction, category meaning,
CSS-only grouping, cssImportSources main-thread conversion.
- SCHEMA_VERSION: drop the v3-specific @remarks paragraph (that belongs
in the changelog/changeset, not in code that lives forever).
- ResolvedCodemapConfig: tighten interface doc; per-field one-liners
unchanged.
- getAdapterForExtension: collapse multi-paragraph JSDoc to one
sentence retaining the leading-dot rule and the markers-only fallback.
application/types.ts left as-is — already balanced, and the verbose
parts there encode invariants worth keeping (snake_case keys,
total_ms != wall_time).
* fix(cli): trim --for whitespace, normalize POSIX separators in validate
Two follow-ups from PR #23 review:
C1 — `cmd-context.ts:98-109` — `--for " "` (whitespace-only) was
slipping past the `v === ""` guard added in 0fafbff and silently being
classified as "other" with `intent.input = " "`. Reject anything that
trims to empty, and store the trimmed value so leading/trailing spaces
in quoted intents don't leak into the envelope. +2 tests
(whitespace-only rejection, trim-around-content).
C2 — `cmd-validate.ts:142-145` — Cross-platform bug. The `files.path`
column always stores POSIX paths (tinyglobby and Bun.Glob normalize on
Windows; git diff emits POSIX universally), but `path.relative()` on
Windows returns backslash-separated paths. So
`codemap validate C:\proj\src\foo.ts` would build a `src\foo.ts` lookup
key that fails to match `src/foo.ts` in the index, falsely reporting a
tracked file as `unindexed`. Mirror the same `replace(/\\/g, "/")`
normalization already in `lint-staged.config.js:12,21`. No new test —
the helper is private and the `sep === "/"` short-circuit makes it a
no-op on macOS / Linux.
* docs: migrate competitive scan into roadmap, why-codemap, and the docs index
Following docs/README.md conventions ("one topic per file", no flag
duplication, single-source-of-truth):
roadmap.md
- Drop `--performance` from backlog (shipped in PR #23).
- Add 4 backlog entries that the scan flagged as still open: MCP
server, HTTP API (`codemap serve`), recipes-as-content registry +
project-local recipes, targeted-read CLI (`codemap show <symbol>`),
cross-agent handoff artifact (speculative).
- Expand "Non-goals (v1)" with the explicit list inherited from the
scan's PASS table — static analysis (fallow's class), visualization
(skyline), daemon, deep intent classification beyond `codemap context`.
Roadmap is now the canonical home for these.
why-codemap.md
- Add "Codemap vs alternatives" comparison (Codemap / fallow /
Aider RepoMap / LSP) — durable positioning material from the scan's
side-by-side. Frames the four tools as solving different problems
rather than competing for one slot.
docs/research/competitive-scan-2026-04.md
- Slim from 210 lines (full ranked adopt/watch/pass list, messaging
lessons, next steps) to 87 lines of durable narrative: dated context,
sources, positioning recap, raw side-by-side, "what shipped" appendix
linking to canonical homes, "what moved to roadmap" pointer, two
open questions still open, citations.
- Replaces sections that are now duplicates of canonical docs.
docs/README.md
- Add a `research/` row to the topic index pointing at the new folder
convention (dated snapshot notes that link back to canonical homes).
- Add "Non-goals (v1)" row to the Single Source of Truth table —
roadmap.md is canonical, why-codemap.md carries the consumer-facing
framing, research/ notes link here and never re-list.
* docs(governance): adopt rules + lifecycle from PaySpace analytics docs; add glossary, plans/ folder, and an enforcement rule
Lifts the high-signal subset of the analytics docs governance pattern:
- Rules for Agents (numbered, normative — cite by number in PR review)
- Document Lifecycle (4 doc types: Reference / Roadmap / Plan / Research)
- Existence test for whether a doc earns its place
- Top-level cap rule
- Closing rules for research notes (codifies what we did manually for
competitive-scan-2026-04.md)
docs/README.md
- Restructure into File Ownership → Rules for Agents → Single Source of
Truth → Document Lifecycle → Naming Conventions → Conventions.
- Move existing "Conventions" prose to the bottom as a stylistic
addendum to the rules above.
- Add 9 numbered rules (one source of truth, ship-flow, plans, table
freshness, relative paths, no inventory counts, no line-numbers,
research closing, glossary updates).
- Add Document Lifecycle section with 4 doc types, the existence test,
closing-research rules, and the top-level cap.
- Add `glossary.md`, `plans/`, `research/` rows to File Ownership.
- Add "Domain term definitions" + "Non-goals" rows to Single Source of
Truth (canonical = glossary.md / roadmap.md, others link).
docs/glossary.md (new)
- ~70 entries covering schema/parser/recipe/agent terminology.
- Disambiguates pairs that look similar: FileRow vs `files` table, recipe
vs query, schema vs DDL, hub vs barrel-file, fan-in vs fan-out, parser
vs adapter, plan vs research, rule vs skill.
- Links recipe + table entries back to architecture.md schema sections
for deep details (Rule 1 — one source of truth).
docs/plans/.gitkeep (new)
- Empty folder so the convention is in place for the first plan that
lands. Don't add the `-plan` suffix per the naming convention.
.agents/rules/docs-governance.md + .cursor/rules/docs-governance.mdc (new)
- alwaysApply rule pointing at docs/README.md as canonical source.
- Carries the 9-rule quick checklist + the existence test + top-level
cap so agents see them at session start without reading the full
docs/README.md every time.
- Symlinked into .cursor/rules/ per the agents-first-convention rule.
No source code touched; 185/185 tests still pass; goldens all green.
* docs: dogfood the new docs/README.md governance
Audited every doc against the 9 numbered rules in the new docs/README.md.
Three violations found and fixed; the rest pass.
Rule 2 — When a backlog item ships, document it in its canonical home
- architecture.md § CLI usage gains four new implementation-note paragraphs:
* Validate wiring (cmd-validate.ts, computeValidateRows pure function,
POSIX path normalization, exit-1 git-status semantics).
* Context wiring (buildContextEnvelope composing existing recipes,
classifyIntent regex routing, --compact behavior).
* Performance wiring (RunIndexOptions.performance, parseMs on
ParsedFile, IndexPerformanceReport assembly, total_ms gotcha).
* Friendlier no-DB error rewriting in enrichQueryError + the new -r
alias on --recipe (folded into existing Query wiring paragraph).
Rule 4 — Keep ownership tables current
- Key Files `cli/` row updated to mention `validate` / `context` modes
alongside `query` / `agents init` / index modes.
Rule 6 — No inventory counts in narrative
- golden-queries.md said "15 scenarios" — now 19 after this PR's
additions. Replaced with a qualitative descriptor + a `codemap query`
example so the doc never goes stale on count again.
Rules 1, 3, 5, 7, 8, 9 all pass — no duplicated prose, no unintended
plans, no absolute paths to in-tree files, no line-number references
(except Rule 7's own example), competitive scan already closed, every
new term from this PR is in glossary.md.1 parent 56bb673 commit ebd4c34
49 files changed
Lines changed: 2261 additions & 301 deletions
File tree
- .agents
- rules
- .changeset
- .cursor/rules
- docs
- plans
- research
- fixtures
- golden
- minimal
- minimal/src/utils
- scripts
- src
- adapters
- application
- cli
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
7 | 7 | | |
8 | 8 | | |
9 | 9 | | |
| 10 | + | |
| 11 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | | - | |
4 | | - | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
5 | 25 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
12 | 29 | | |
13 | 30 | | |
14 | 31 | | |
| |||
25 | 42 | | |
26 | 43 | | |
27 | 44 | | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
28 | 61 | | |
29 | 62 | | |
30 | 63 | | |
| |||
0 commit comments