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
2 changes: 2 additions & 0 deletions .agents/lessons.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,5 @@ Each entry is a single bullet: `- **<topic>** — <lesson>`. Newest entries at t

- **changesets bump policy (pre-v1)** — while in `0.x`, default to **patch** for everything (additive features, fixes, docs, internal refactors); reserve **minor** for schema-breaking changes that force a `.codemap.db` rebuild (matches 0.2.0 precedent: new tables/columns/`SCHEMA_VERSION` bump). Strict SemVer kicks in only after `1.0.0`. Don't propose `minor` just because new CLI commands or public types were added.
- **agent rule + skill maintenance** — when shipping a CLI flag, recipe id, recipe `actions` template, schema column, or any agent-queryable surface, update **both** copies of the codemap rule + skill in the **same PR** per [docs/README.md Rule 10](../docs/README.md): `templates/agents/rules/codemap.md` + `templates/agents/skills/codemap/SKILL.md` (ships to npm) **and** `.agents/rules/codemap.md` + `.agents/skills/codemap/SKILL.md` (this clone's mirror). Drift between the two pairs should be CLI-prefix-only (`codemap` vs `bun src/index.ts`). Forgetting this leaves installed agents with a stale view of the CLI — that's how `--summary` / `--changed-since` / `--group-by` / `actions` / `symbols.visibility` shipped without any `templates/agents/` mention until PR #29 retro-fixed it.
- **backticks inside SQL or help-text template literals** — never put a literal backtick inside a `` `...` `` template-literal string. `db.ts` SQL DDL strings (multi-line CREATE TABLE templates) and `printQueryCmdHelp()` (multi-line help text) are both `` `...` `` template literals; an inner backtick — typically a Markdown-style code-fence around a flag like `` `--full` `` — terminates the literal early and the parser blows up several lines later with cryptic "expected `,` or `)`" errors. **Use plain prose in those strings** (`--full` not `` `--full` ``), or escape (`` \` ``) if you really need the character. Hit twice (B.7 + B.6 PR #30); the lesson is general — applies to any TS template literal that gets pasted prose later, not just SQL / help text.
- **STOP-before-Grep applies to symbol lookups too** — `Grep` for symbol names like `printQueryResult`, `getCurrentCommit`, `dropAll` violates the [`codemap` rule](rules/codemap.md). The codemap query `SELECT file_path, line_start FROM symbols WHERE name = '<X>'` answers it faster and without scanning. Reach for `Grep` only when the question is content-shaped (regex over file bodies, finding pattern usages inside function bodies, etc.) — not when it's "where is X defined / who calls X / what does file Y export." This was a PR #30 self-correction.
28 changes: 16 additions & 12 deletions .agents/rules/codemap.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,22 @@ A local database (default **`.codemap.db`**) indexes structure: symbols, imports

## CLI (this repository)

| Context | Incremental index | Query |
| ------------------------------ | ------------------ | ------------------------------------------------------------------------------------------ |
| **Default** — from this clone | `bun src/index.ts` | `bun src/index.ts query --json "<SQL>"` |
| Same entry | `bun run dev` | (same as first row) |
| Query (ASCII table — optional) | — | `bun src/index.ts query "<SQL>"` |
| Recipe | — | `bun src/index.ts query --json --recipe fan-out` (see **`bun src/index.ts query --help`**) |
| Recipe catalog / SQL | — | `bun src/index.ts query --recipes-json` · `bun src/index.ts query --print-sql fan-out` |
| Counts only | — | `bun src/index.ts query --json --summary -r deprecated-symbols` |
| PR-scoped rows | — | `bun src/index.ts query --json --changed-since origin/main -r fan-out` |
| Bucket by owner / dir / pkg | — | `bun src/index.ts query --json --group-by directory -r fan-in` |

**Recipe `actions`:** with **`--json`**, recipes that define an `actions` template append it to every row (kebab-case verb + description — e.g. `fan-out` → `review-coupling`). Inspect via **`--recipes-json`**. Ad-hoc SQL never carries actions.
| Context | Incremental index | Query |
| ------------------------------ | ------------------ | --------------------------------------------------------------------------------------------------------- |
| **Default** — from this clone | `bun src/index.ts` | `bun src/index.ts query --json "<SQL>"` |
| Same entry | `bun run dev` | (same as first row) |
| Query (ASCII table — optional) | — | `bun src/index.ts query "<SQL>"` |
| Recipe | — | `bun src/index.ts query --json --recipe fan-out` (see **`bun src/index.ts query --help`**) |
| Recipe catalog / SQL | — | `bun src/index.ts query --recipes-json` · `bun src/index.ts query --print-sql fan-out` |
| Counts only | — | `bun src/index.ts query --json --summary -r deprecated-symbols` |
| PR-scoped rows | — | `bun src/index.ts query --json --changed-since origin/main -r fan-out` |
| Bucket by owner / dir / pkg | — | `bun src/index.ts query --json --group-by directory -r fan-in` |
| Save / diff a baseline | — | `bun src/index.ts query --save-baseline -r visibility-tags` then `… --json --baseline -r visibility-tags` |
| List / drop baselines | — | `bun src/index.ts query --baselines` · `bun src/index.ts query --drop-baseline <name>` |

**Recipe `actions`:** with **`--json`**, recipes that define an `actions` template append it to every row (kebab-case verb + description — e.g. `fan-out` → `review-coupling`). Under `--baseline`, actions attach to the **`added`** rows only. Inspect via **`--recipes-json`**. Ad-hoc SQL never carries actions.

**Baselines** (`query_baselines` table inside `.codemap.db`, no parallel JSON files): `--save-baseline[=<name>]` snapshots a result set; `--baseline[=<name>]` diffs the current result against it (added / removed rows; identity = `JSON.stringify(row)`). Name defaults to the `--recipe` id; ad-hoc SQL needs an explicit `=<name>`. Survives `--full` and SCHEMA bumps.

After **`bun run build`**, **`node dist/index.mjs`** matches the published **`codemap`** binary (same flags). **`bun link`** / global **`codemap`** also work when testing the packaged CLI.

Expand Down
21 changes: 19 additions & 2 deletions .agents/skills/codemap/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,11 @@ Replace placeholders (`'...'`) with your module path, file glob, or symbol name.

- **`--summary`** — counts only. With **`--json`**: **`{"count": N}`**. With **`--group-by`**: **`{"group_by": "<mode>", "groups": [{key, count}]}`**.
- **`--changed-since <ref>`** — post-filter rows by **`path`** / **`file_path`** / **`from_path`** / **`to_path`** / **`resolved_path`** against **`git diff --name-only <ref>...HEAD ∪ git status --porcelain`**. Rows with no recognised path column pass through.
- **`--group-by owner|directory|package`** — partition into buckets and emit **`{"group_by", "groups": [{key, count, rows}]}`**. **`owner`** reads CODEOWNERS (last matching rule wins); **`directory`** is the first path segment; **`package`** uses **`package.json`** **`workspaces`** or **`pnpm-workspace.yaml`**.
- **Per-row recipe `actions`** — recipes that define an **`actions: [{type, auto_fixable?, description?}]`** template append it to every row in **`--json`** output (recipe-only; ad-hoc SQL never carries actions). Inspect via **`--recipes-json`**.
- **`--group-by owner|directory|package`** — partition into buckets and emit **`{"group_by", "groups": [{key, count, rows}]}`**. **`owner`** reads CODEOWNERS (last matching rule wins); **`directory`** is the first path segment; **`package`** uses **`package.json`** **`workspaces`** or **`pnpm-workspace.yaml`**. **Mutually exclusive with `--save-baseline` / `--baseline`.**
- **`--save-baseline[=<name>]`** — snapshot the result rows to the **`query_baselines`** table inside `.codemap.db` (no parallel JSON files; survives `--full` and SCHEMA bumps). Name defaults to the `--recipe` id; ad-hoc SQL needs an explicit `=<name>`. Re-saving with the same name overwrites in place.
- **`--baseline[=<name>]`** — diff the current result against the saved baseline. Output `{baseline:{...}, current_row_count, added: [...], removed: [...]}` (with `--json`) or a two-section terminal dump. Identity = per-row multiset equality (canonical `JSON.stringify` keyed frequency map; duplicates preserved). Pair with `--summary` for `{baseline:{...}, current_row_count, added: N, removed: N}`. **Mutually exclusive with `--group-by`.**
- **`--baselines`** lists saved baselines (no `rows_json` payload); **`--drop-baseline <name>`** deletes one. Both reject every other flag — they're list-only / drop-only operations.
- **Per-row recipe `actions`** — recipes that define an **`actions: [{type, auto_fixable?, description?}]`** template append it to every row in **`--json`** output (recipe-only; ad-hoc SQL never carries actions). Under `--baseline`, actions attach to the **`added`** rows only (the rows the agent should act on). Inspect via **`--recipes-json`**.

**Determinism:** Bundled recipes use stable secondary **`ORDER BY`** tie-breakers (and ordered inner **`LIMIT`** samples where applicable). Prefer **`--recipe`** over pasting SQL when you need the maintained ordering. **Canonical SQL** is **`src/cli/query-recipes.ts`** (`QUERY_RECIPES`).

Expand Down Expand Up @@ -212,6 +215,20 @@ LIMIT 10
| `project_root` | Absolute path to project |
| `schema_version` | Schema version number |

### `query_baselines` — Saved query result snapshots (user data)

User-facing baselines saved by `codemap query --save-baseline`, replayed by `codemap query --baseline`. **Survives `--full` and SCHEMA bumps** — intentionally absent from `dropAll()`.

| Column | Type | Description |
| ---------- | ------- | ---------------------------------------------------------------------------------------- |
| name | TEXT PK | User-supplied name; defaults to the `--recipe` id (ad-hoc SQL requires an explicit name) |
| recipe_id | TEXT | The `--recipe` id when known; NULL for ad-hoc SQL |
| sql | TEXT | The SQL that produced the snapshot |
| rows_json | TEXT | Canonical `JSON.stringify(rows)` — multiset diff identity (duplicate rows preserved) |
| row_count | INTEGER | Cached number of rows in the saved result set |
| git_ref | TEXT | `git rev-parse HEAD` at save time, or NULL when not a git working tree |
| created_at | INTEGER | `Date.now()` at save time (epoch ms) |

## Query patterns

### Basic lookups
Expand Down
5 changes: 5 additions & 0 deletions .changeset/query-baselines.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@stainless-code/codemap": minor
---

`codemap query --save-baseline` / `--baseline` — snapshot a query result set and diff against it later. Stored in the new `query_baselines` table inside `.codemap.db` (no parallel JSON files). `--baselines` lists saved snapshots, `--drop-baseline <name>` deletes one. Diff identity is per-row `JSON.stringify` equality; `--summary` collapses to `{added: N, removed: N}`. Recipe `actions` attach to the `added` rows when running under `--baseline`. Baselines survive `--full` and SCHEMA rebuilds. `SCHEMA_VERSION` bumps from 4 to 5.
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,15 @@ codemap query --json --summary --changed-since HEAD~5 "SELECT file_path FROM sym
codemap query --json --summary --group-by directory -r fan-in
codemap query --json --group-by owner -r deprecated-symbols
codemap query --json --summary --group-by package "SELECT file_path FROM symbols"
# Snapshot a result, refactor, then diff (saved inside .codemap.db, no JSON files)
codemap query --save-baseline -r visibility-tags # save under name "visibility-tags"
codemap query --json --baseline -r visibility-tags # full diff: {baseline, current_row_count, added, removed}
codemap query --json --summary --baseline -r visibility-tags # counts only: {baseline, current_row_count, added: N, removed: N}
codemap query --save-baseline=pre-refactor "SELECT file_path FROM symbols" # ad-hoc SQL needs an explicit =<name>
codemap query --baseline=pre-refactor "SELECT file_path FROM symbols"
codemap query --baselines # list saved baselines
codemap query --drop-baseline visibility-tags # delete
Comment thread
coderabbitai[bot] marked this conversation as resolved.
# --group-by is mutually exclusive with --save-baseline / --baseline (different output shapes)
# 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.
# List bundled recipes as JSON, or print one recipe's SQL (no DB required)
Expand Down
Loading
Loading