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
60 changes: 32 additions & 28 deletions .agents/rules/codemap.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@ If the question looks like any of these → use the index:
| "What's structurally dead AND untested?" | `--recipe untested-and-dead` |
| "Rank files by test coverage" | `--recipe files-by-coverage` |
| "Worst-covered exported functions" | `--recipe worst-covered-exports` |
| "Which components touch deprecated APIs?" | `--recipe components-touching-deprecated` |
| "What's risky to refactor right now?" | `--recipe refactor-risk-ranking` |

## When Grep / Read IS appropriate

Expand All @@ -135,34 +137,36 @@ bun src/index.ts query --json "<SQL>"

## Quick reference queries

| I need to... | Query |
| ------------------------- | ------------------------------------------------------------------------------------------------------------ |
| Find a symbol | `SELECT name, kind, file_path, line_start, line_end, signature FROM symbols WHERE name = '...'` |
| Find a symbol (fuzzy) | `SELECT name, kind, file_path, line_start FROM symbols WHERE name LIKE '%...%'` |
| See file exports | `SELECT name, kind, is_default FROM exports WHERE file_path LIKE '%...'` |
| See file imports | `SELECT source, specifiers, is_type_only FROM imports WHERE file_path LIKE '%...'` |
| Who imports this module? | `SELECT DISTINCT file_path FROM imports WHERE source LIKE '~/some/module%'` |
| Who imports this file? | `SELECT DISTINCT from_path FROM dependencies WHERE to_path LIKE '%...'` |
| What does this depend on? | `SELECT DISTINCT to_path FROM dependencies WHERE from_path LIKE '%...'` |
| Component info | `SELECT name, props_type, hooks_used FROM components WHERE name = '...'` |
| All components | `SELECT name, file_path, props_type, hooks_used FROM components ORDER BY name` |
| TODOs in a file | `SELECT line_number, content FROM markers WHERE file_path LIKE '%...' AND kind = 'TODO'` |
| Most complex files | `SELECT from_path, COUNT(*) as deps FROM dependencies GROUP BY from_path ORDER BY deps DESC LIMIT 10` |
| CSS design tokens | `SELECT name, value, scope FROM css_variables WHERE name LIKE '--%...'` |
| CSS module classes | `SELECT name, file_path FROM css_classes WHERE is_module = 1` |
| CSS keyframes | `SELECT name, file_path FROM css_keyframes` |
| Type/interface shape | `SELECT name, type, is_optional, is_readonly FROM type_members WHERE symbol_name = '...'` |
| Deprecated symbols | `SELECT name, kind, file_path, doc_comment FROM symbols WHERE doc_comment LIKE '%@deprecated%'` |
| Visibility-tagged symbols | `SELECT name, kind, visibility, file_path FROM symbols WHERE visibility IS NOT NULL` (or `= 'beta'`, etc.) |
| Symbol docs | `SELECT name, signature, doc_comment FROM symbols WHERE name = '...' AND doc_comment IS NOT NULL` |
| Const values | `SELECT name, value, file_path FROM symbols WHERE kind = 'const' AND value IS NOT NULL AND name LIKE '%...'` |
| Class members | `SELECT name, kind, signature FROM symbols WHERE parent_name = '...'` |
| Top-level only | `SELECT name, kind, signature FROM symbols WHERE parent_name IS NULL AND file_path LIKE '%...'` |
| Who calls X? | `SELECT DISTINCT caller_name, file_path FROM calls WHERE callee_name = '...'` |
| What does X call? | `SELECT DISTINCT callee_name FROM calls WHERE caller_name = '...'` |
| Call hotspots | `SELECT callee_name, COUNT(*) as fan_in FROM calls GROUP BY callee_name ORDER BY fan_in DESC LIMIT 10` |
| Symbol coverage | `SELECT name, hit_statements, total_statements, coverage_pct FROM coverage WHERE file_path = '...'` |
| Untested + dead exports | `bun src/index.ts query --json --recipe untested-and-dead` |
| I need to... | Query |
| --------------------------------- | ------------------------------------------------------------------------------------------------------------ |
| Find a symbol | `SELECT name, kind, file_path, line_start, line_end, signature FROM symbols WHERE name = '...'` |
| Find a symbol (fuzzy) | `SELECT name, kind, file_path, line_start FROM symbols WHERE name LIKE '%...%'` |
| See file exports | `SELECT name, kind, is_default FROM exports WHERE file_path LIKE '%...'` |
| See file imports | `SELECT source, specifiers, is_type_only FROM imports WHERE file_path LIKE '%...'` |
| Who imports this module? | `SELECT DISTINCT file_path FROM imports WHERE source LIKE '~/some/module%'` |
| Who imports this file? | `SELECT DISTINCT from_path FROM dependencies WHERE to_path LIKE '%...'` |
| What does this depend on? | `SELECT DISTINCT to_path FROM dependencies WHERE from_path LIKE '%...'` |
| Component info | `SELECT name, props_type, hooks_used FROM components WHERE name = '...'` |
| All components | `SELECT name, file_path, props_type, hooks_used FROM components ORDER BY name` |
| TODOs in a file | `SELECT line_number, content FROM markers WHERE file_path LIKE '%...' AND kind = 'TODO'` |
| Most complex files | `SELECT from_path, COUNT(*) as deps FROM dependencies GROUP BY from_path ORDER BY deps DESC LIMIT 10` |
| CSS design tokens | `SELECT name, value, scope FROM css_variables WHERE name LIKE '--%...'` |
| CSS module classes | `SELECT name, file_path FROM css_classes WHERE is_module = 1` |
| CSS keyframes | `SELECT name, file_path FROM css_keyframes` |
| Type/interface shape | `SELECT name, type, is_optional, is_readonly FROM type_members WHERE symbol_name = '...'` |
| Deprecated symbols | `SELECT name, kind, file_path, doc_comment FROM symbols WHERE doc_comment LIKE '%@deprecated%'` |
| Visibility-tagged symbols | `SELECT name, kind, visibility, file_path FROM symbols WHERE visibility IS NOT NULL` (or `= 'beta'`, etc.) |
| Symbol docs | `SELECT name, signature, doc_comment FROM symbols WHERE name = '...' AND doc_comment IS NOT NULL` |
| Const values | `SELECT name, value, file_path FROM symbols WHERE kind = 'const' AND value IS NOT NULL AND name LIKE '%...'` |
| Class members | `SELECT name, kind, signature FROM symbols WHERE parent_name = '...'` |
| Top-level only | `SELECT name, kind, signature FROM symbols WHERE parent_name IS NULL AND file_path LIKE '%...'` |
| Who calls X? | `SELECT DISTINCT caller_name, file_path FROM calls WHERE callee_name = '...'` |
| What does X call? | `SELECT DISTINCT callee_name FROM calls WHERE caller_name = '...'` |
| Call hotspots | `SELECT callee_name, COUNT(*) as fan_in FROM calls GROUP BY callee_name ORDER BY fan_in DESC LIMIT 10` |
| Symbol coverage | `SELECT name, hit_statements, total_statements, coverage_pct FROM coverage WHERE file_path = '...'` |
| Untested + dead exports | `bun src/index.ts query --json --recipe untested-and-dead` |
| Components touching `@deprecated` | `bun src/index.ts query --json --recipe components-touching-deprecated` |
| Refactor-risk-ranked files | `bun src/index.ts query --json --recipe refactor-risk-ranking` |

**Use `DISTINCT`** on dependency and import queries — a file importing multiple specifiers from the same module produces duplicate rows.

Expand Down
2 changes: 1 addition & 1 deletion .agents/skills/codemap/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ After **`bun run build`**, **`node dist/index.mjs query …`** or a linked **`co

Replace placeholders (`'...'`) with your module path, file glob, or symbol name.

**CLI shortcuts:** **`bun src/index.ts query --json --recipe <id>`** runs bundled SQL (preferred for agents). **`bun src/index.ts query --recipe <id>`** without **`--json`** prints a table. **`bun src/index.ts query --recipes-json`** prints every bundled recipe (**`id`**, **`description`**, **`sql`**, optional **`actions`**) as JSON (no index / DB required). **`bun src/index.ts query --print-sql <id>`** prints one recipe’s SQL only. Ids include **`fan-out`**, **`fan-out-sample`** (**`GROUP_CONCAT`** samples), **`fan-out-sample-json`** (same, but **`json_group_array`** — needs SQLite JSON1), **`fan-in`**, **`index-summary`**, **`files-largest`**, **`components-by-hooks`**, **`markers-by-kind`**, **`deprecated-symbols`**, **`visibility-tags`**, **`barrel-files`**, **`files-hashes`** — see **`bun src/index.ts query --help`**.
**CLI shortcuts:** **`bun src/index.ts query --json --recipe <id>`** runs bundled SQL (preferred for agents). **`bun src/index.ts query --recipe <id>`** without **`--json`** prints a table. **`bun src/index.ts query --recipes-json`** prints every bundled recipe (**`id`**, **`description`**, **`sql`**, optional **`actions`**) as JSON (no index / DB required). **`bun src/index.ts query --print-sql <id>`** prints one recipe’s SQL only. Ids include **`fan-out`**, **`fan-out-sample`** (**`GROUP_CONCAT`** samples), **`fan-out-sample-json`** (same, but **`json_group_array`** — needs SQLite JSON1), **`fan-in`**, **`index-summary`**, **`files-largest`**, **`components-by-hooks`**, **`components-touching-deprecated`** (UNION of hook + call paths to `@deprecated` symbols), **`markers-by-kind`**, **`deprecated-symbols`**, **`refactor-risk-ranking`** (per-file `(fan_in + 1) × (100 - avg_coverage_pct)`), **`visibility-tags`**, **`barrel-files`**, **`files-hashes`** — see **`bun src/index.ts query --help`**.

**Output flags** (compose with **`--recipe`** or ad-hoc SQL):

Expand Down
12 changes: 12 additions & 0 deletions .changeset/recipes-from-research-note.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
"@stainless-code/codemap": patch
---

feat(recipes): ship two new bundled recipes from research note § 1

- **`components-touching-deprecated`** (research note § 1.1) — UNION of two paths surfacing components that touch `@deprecated` symbols: hook path (`components.hooks_used` JSON overlap) + call path (`calls.caller_name = component`, `callee_name` is `@deprecated`). Hook-only variants ship false negatives — recipe spells out the explicit UNION. Action template `review-deprecation-impact`.
- **`refactor-risk-ranking`** (research note § 1.4) — per-file ranking by `(fan_in + 1) × (100 - avg_coverage_pct)`. Three correctness fixes vs the naïve formula: orphans (`fan_in = 0`) score on coverage alone via `+1`; NULL `coverage_pct` treated as 0% via `COALESCE` (otherwise the row drops from `ORDER BY`); files with no exports excluded (no public-API surface to refactor externally). Output is per-file (not per-symbol) — empirical test showed per-symbol ranking ties on file-level fan_in. Per-symbol via `calls` is a documented tuning axis for project-local override. Action template `review-refactor-impact`.

Both recipes use only existing substrate (`components`, `calls`, `symbols`, `dependencies`, `coverage`, `files`) — no schema bump. Bundled recipe content follows the existing recipe-as-content registry pattern (PR #37); project-local overrides live at `<projectRoot>/.codemap/recipes/<id>.{sql,md}`.

Agent rule + skill lockstep updated per `docs/README.md` Rule 10 — both `templates/agents/` (ships to npm via `codemap agents init`) and `.agents/` (this clone's mirror) gain trigger-pattern entries, quick-reference rows, and recipe-id list updates.
Loading
Loading