Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
61c7748
docs: add substrate tiers 1–6 rollout plan
SutuSebastian May 19, 2026
79c69fc
feat: add call-shape metadata to calls table (schema 28)
SutuSebastian May 19, 2026
8fb98b2
feat: add async/return-type columns on symbols (schema 29)
SutuSebastian May 19, 2026
5be2260
feat: add dynamic_imports table and extractor (schema 30)
SutuSebastian May 19, 2026
026889b
feat: add files.is_barrel and has_side_effects flags (schema 31)
SutuSebastian May 19, 2026
c086bdb
feat: add re-exported resolution_kind to bindings (schema 32)
SutuSebastian May 20, 2026
3b3349c
feat: side-effect import_specifiers rows + import_id FK (schema 33)
SutuSebastian May 20, 2026
52fc02f
feat: JSX + behavioral substrate tables (schema 34)
SutuSebastian May 20, 2026
0a69232
docs: mark substrate tiers 1–6 rollout complete
SutuSebastian May 20, 2026
f9377b7
chore: add changeset for substrate tiers 1–6 (minor)
SutuSebastian May 20, 2026
d65d269
docs: retire substrate tiers 1–6 rollout plan
SutuSebastian May 20, 2026
1b5c1dc
docs: align glossary and ship status with substrate tiers 1–6
SutuSebastian May 20, 2026
7852ba2
perf(insert): batch async_calls and try_catch inserts
SutuSebastian May 20, 2026
b9ebdb8
perf(insert): batch imports in insertImportsWithSpecifiers
SutuSebastian May 20, 2026
12b40c0
perf(insert): batch jsx_attributes inserts
SutuSebastian May 20, 2026
93b2659
test(fixtures): enrich minimal corpus for full substrate coverage
SutuSebastian May 20, 2026
268de25
chore(deps): bump oxc, zod, oxlint, and dev toolchain
SutuSebastian May 20, 2026
9fe9c11
fix(extractors): address CodeRabbit fact-checked review items
SutuSebastian May 20, 2026
75a1a65
docs: sync architecture schema version and recipe frontmatter
SutuSebastian May 20, 2026
377de85
fix(ci): scope unit tests to src and rebaseline perf for schema 34
SutuSebastian May 20, 2026
4473ca4
fix(ci): scope tests to ./src not **/src/**
SutuSebastian May 20, 2026
694eb1f
fix(qa): close read-only query gap and add regression coverage
SutuSebastian May 20, 2026
3fd7c93
test(index-engine): restore console spies in finally blocks
SutuSebastian May 20, 2026
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
34 changes: 34 additions & 0 deletions .changeset/substrate-tiers-1-6.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
---
"@stainless-code/codemap": minor
---

Substrate tiers 1–6 remainder (excludes C.9 / `files.is_entry`). **Schema bump** `SCHEMA_VERSION` 27 → **34** — first run after upgrade auto-rebuilds `.codemap/index.db` via the existing version-mismatch path.

**Tier 1 — call + import precision**

- `calls.{args_count,is_method_call,is_constructor_call,is_optional_chain}`; constructor vs call dedup key fix
- `symbols.{return_type,is_async,is_generator}`
- Side-effect `import_specifiers` rows (`kind='side-effect'`) + `import_id` FK to `imports`

**Tier 2 — bindings**

- `bindings.resolution_kind='re-exported'` when resolution walks a re-export chain

**Tier 3 — JSX**

- New tables `jsx_elements` / `jsx_attributes`; extractor with per-file parent linking post-pass

**Tier 5 — behavioral**

- New tables `async_calls`, `try_catch`, `decorators`, `jsdoc_tags`; context stack for `in_loop` / `in_try`

**Tier 6 — module graph (no entry points)**

- `dynamic_imports` table + extractor
- Post-pass `files.is_barrel` and parse-time `files.has_side_effects`

**Recipes + goldens:** `find-call-sites` (extended), `find-async-functions`, `find-dynamic-imports`, `find-barrel-files`, `find-side-effect-files`, `find-re-exported-bindings`, `find-side-effect-imports`, `find-jsx-usages`, `find-await-in-loop`, `find-swallowed-errors`, `find-decorator-usage`, `find-throws-jsdoc`.

**Out of scope:** C.9 plugin layer (`files.is_entry`, reachability-from-entry); tiers 7–13.

**Migration:** No in-place DDL — rebuild on schema mismatch preserves user-data tables (`coverage`, `query_baselines`, `recipe_recency`). Re-run `codemap --full` (or any index) after upgrade.
166 changes: 86 additions & 80 deletions bun.lock

Large diffs are not rendered by default.

101 changes: 76 additions & 25 deletions docs/architecture.md

Large diffs are not rendered by default.

44 changes: 38 additions & 6 deletions docs/glossary.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,21 +43,25 @@ Two-snapshot structural-drift command: `codemap audit` diffs the live `.codemap/

Ad-hoc audit snapshot from any git committish (`origin/main`, `HEAD~5`, `<sha>`, tag, …). `git archive --format=tar <sha>` is piped through `tar -x` into `<projectRoot>/.codemap/audit-cache/<sha>/` — a plain extracted tree with no `.git` artifact and no registered git worktree, so `git clean -xdf` and `rm -rf` both sweep it without flag escalation. Codemap reindexes into the cache's `.codemap/index.db`, then per-delta canonical SQL runs on that DB vs the live one. Cache key is the **resolved sha** (`git rev-parse --verify`), so `--base origin/main` and `--base <sha>` (when they point at the same commit) share one cache entry. **Atomic populate** — per-pid temp dir + POSIX `rename`; concurrent processes resolving the same sha race-safely without lock files. Eviction: hardcoded LRU 5 entries / 500 MiB. Per-delta `base.source` is `"ref"` (vs `"baseline"`) and the delta carries `base.ref` (user-supplied string) + `base.sha` (resolved). Mutually exclusive with `--baseline <prefix>`; composes orthogonally with per-delta `--<delta>-baseline <name>` overrides. Hard error on non-git projects (no graceful fallback — there's no meaningful "ref" without git). Both transports (MCP `audit` tool's `base?` arg, HTTP `POST /tool/audit`) call the same `runAuditFromRef` engine in `application/audit-engine.ts`.

### `async_calls` (table)

One row per `AwaitExpression`. Captures `awaited_expression` source text, optional `awaited_callee_name`, and loop/try context flags (`in_loop`, `in_try`) from a visitor context stack. Joins `scopes.local_id` via `scope_local_id`. Powers `find-await-in-loop`.

---

## B

### barrel file

In Codemap usage: a file with a high number of `exports` rows — typically a public-API hub like `src/index.ts`. Surfaced by the `barrel-files` recipe. Distinct from **hub** below — barrel measures _exports out_, hub measures _imports in_.
In Codemap usage: a file whose exports are entirely re-exports with no local value symbols — surfaced as `files.is_barrel = 1` (post-pass) and by the `barrel-files` / `find-barrel-files` recipes. Distinct from **hub** below — barrel measures _exports out_, hub measures _imports in_.

### batch insert

The shared `batchInsert<T>()` helper in `src/db.ts`. Splits inserts into multi-row `INSERT … VALUES (…),(…)` statements of `BATCH_SIZE` (500) rows each, with pre-computed placeholder strings. Used by every `insertX` function.

### `bindings` (table) / bindings resolver

Per-reference resolution to the originating symbol per [R.12]. One row per non-`member`-kind `references` row, with `resolution_kind` in `{same-file, imported, global, unresolved}` and a nullable `resolved_symbol_id` joining `symbols(id)`. Resolved in a single in-memory pass (`src/application/bindings-engine.ts`) after files/symbols/imports settle. Full-rebuild only — targeted reindex skips per [R.10]. Powers `find-symbol-references` (bindings-precise rename substrate).
Per-reference resolution to the originating symbol per [R.12]. One row per non-`member`-kind `references` row, with `resolution_kind` in `{same-file, imported, re-exported, global, unresolved}` and a nullable `resolved_symbol_id` joining `symbols(id)`. Resolved in a single in-memory pass (`src/application/bindings-engine.ts`) after files/symbols/imports settle. Full-rebuild only — targeted reindex skips per [R.10]. Powers `find-symbol-references` and `find-re-exported-bindings`.

### `boundaries` (config) / `boundary_rules` (table) / `boundary-violations` (recipe)

Expand All @@ -77,7 +81,7 @@ Synchronous Node.js SQLite binding. The Node-side counterpart to `bun:sqlite`. A

### `calls` (table)

Function-scoped call edges, deduped per `(caller_scope, callee_name)` per file. **`caller_scope`** is dot-joined enclosing scope (e.g. `UserService.run`). Module-level calls are excluded. See `CallRow` for the TS shape.
Function-scoped call edges, deduped per `(caller_scope, callee_name, call_kind)` per file (`call` vs `new`). **`caller_scope`** is dot-joined enclosing scope (e.g. `UserService.run`). Module-level calls are excluded. Columns include `args_count` (NULL when a spread argument is present), `is_method_call`, `is_constructor_call`, and `is_optional_chain`. See `CallRow`.

### `CallRow`

Expand Down Expand Up @@ -183,6 +187,10 @@ CSS custom properties (`--token: value`). `scope` is `:root`, `@theme` (Tailwind

## D

### `decorators` (table)

One row per `@decorator` site on classes, methods, properties, or accessors. `target_symbol_id` links to `symbols(id)` post-insert when resolvable. Powers `find-decorator-usage`.

### DDL

Data Definition Language — the `CREATE TABLE` / `CREATE INDEX` strings in `src/db.ts`. Distinct from **schema** (the conceptual structure) and from **`SCHEMA_VERSION`** (the integer that triggers auto-rebuild on mismatch).
Expand All @@ -195,6 +203,10 @@ Resolved file-to-file edges derived from `imports.resolved_path`. Composite prim

TS shape for one row of the `dependencies` table.

### `dynamic_imports` (table)

One row per `import()` expression. `source_kind` is `literal` / `template` / `expression`; `resolved_path` filled when literal and resolvable. `in_async_fn` flags dynamic imports inside async functions. Powers `find-dynamic-imports`.

---

## E
Expand Down Expand Up @@ -225,7 +237,7 @@ Number of edges _out of_ a file — `COUNT(*) FROM dependencies WHERE from_path

### `files` (table)

Header row for every indexed file. `path` is the primary key; all other tables FK to it with `ON DELETE CASCADE`. See `FileRow`.
Header row for every indexed file. `path` is the primary key; all other tables FK to it with `ON DELETE CASCADE`. Flags: `is_barrel` (100% re-exports, no local value symbols) and `has_side_effects` (module-level call/assignment seen at parse time). See `FileRow`.

### `FileRow`

Expand Down Expand Up @@ -285,7 +297,7 @@ Symbol or file blast-radius walker. CLI: `codemap impact <target> [--direction u

### `import_specifiers` (table)

Per-specifier breakdown of the `imports.specifiers` JSON blob. One row per imported binding — `imported_name` (original) and `local_name` (renamed via `as`), `kind` in `{named, default, namespace}`, `is_type_only`, column-precise position. Powers specifier-precise rewrites and the `find-import-sites` recipe.
Per-specifier breakdown of the `imports.specifiers` JSON blob. One row per imported binding — or one `kind='side-effect'` row for bare `import "mod"`. Columns include `imported_name`, `local_name`, `kind` in `{named, default, namespace, side-effect}`, `is_type_only`, column-precise position, and `import_id` FK to `imports`. Powers `find-import-sites` and `find-side-effect-imports`.

### `imports` (table)

Expand All @@ -305,6 +317,22 @@ Public TS shape returned from `Codemap#index()` and `runCodemapIndex()`. Wall-cl

---

## J

### `jsdoc_tags` (table)

Structured JSDoc tags parsed from `symbols.doc_comment` — one row per tag per symbol (`@param`, `@throws`, `@returns`, …). FK `symbol_id` → `symbols(id)`. Powers `find-throws-jsdoc`.

### `jsx_attributes` (table)

One row per JSX attribute on a `jsx_elements` row. `value_kind` in `{string, expression, boolean, spread, element}`. Join parent via `element_id`.

### `jsx_elements` (table)

One row per JSX element or fragment in `.tsx`/`.jsx` files. `parent_element_id` linked in a per-file post-insert pass. `is_fragment = 1` for `<>…</>`. Powers `find-jsx-usages`.

---

## L

### language adapter
Expand Down Expand Up @@ -520,7 +548,7 @@ SQLite per-table option enforcing column types at insert time. Every Codemap tab

### `symbols` (table)

Functions / consts / classes / interfaces / types / enums, plus class members (`method`, `property`, `getter`, `setter`). Class members carry `parent_name`. JSDoc tags in `doc_comment` power the `deprecated-symbols` and `visibility-tags` recipes; `members` is JSON for enums. See `SymbolRow`.
Functions / consts / classes / interfaces / types / enums, plus class members (`method`, `property`, `getter`, `setter`). Class members carry `parent_name`. Function-shaped rows may carry `return_type`, `is_async`, and `is_generator`. JSDoc tags in `doc_comment` power the `deprecated-symbols` and `visibility-tags` recipes; structured tags also land in `jsdoc_tags`. `members` is JSON for enums. See `SymbolRow`.

### `SymbolRow`

Expand All @@ -530,6 +558,10 @@ TS shape for one row of the `symbols` table.

## T

### `try_catch` (table)

One row per `TryStatement`. Heuristic flags include `catch_logs_only` (catch body only calls `console.*`) and `catch_rethrows`. Powers `find-swallowed-errors`.

### `test_suites` (table)

Test metadata — describe / it / test / suite / context blocks with skip/only/todo flags and detected `framework` in `{vitest, jest, bun-test, node-test, mocha, unknown}`. Framework detection is per-file from imports (mixed-framework codebases handled automatically). `parent_suite_id` resolves nested describes. Powers `find-skipped-tests` + `tests-by-file` recipes.
Expand Down
Loading
Loading