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

- **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.
7 changes: 7 additions & 0 deletions .agents/rules/codemap.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ A local database (default **`.codemap.db`**) indexes structure: symbols, imports
| 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.

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 Expand Up @@ -58,6 +63,7 @@ If the question looks like any of these → use the index:
| "What keyframe animations exist?" | `css_keyframes` |
| "What fields does interface/type X have?" | `type_members` |
| "Is symbol X deprecated?" / "What does X do?" | `symbols` (`doc_comment`) |
| "What's `@internal` / `@beta` / `@alpha` / `@private`?" | `symbols.visibility` (parsed JSDoc tag — not regex) |
| "Who calls X?" / "What does X call?" | `calls` |

## When Grep / Read IS appropriate
Expand Down Expand Up @@ -98,6 +104,7 @@ bun src/index.ts query --json "<SQL>"
| 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 = '...'` |
Expand Down
47 changes: 31 additions & 16 deletions .agents/skills/codemap/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,14 @@ 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`**) 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`** — 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`**, **`markers-by-kind`**, **`deprecated-symbols`**, **`visibility-tags`**, **`barrel-files`**, **`files-hashes`** — see **`bun src/index.ts query --help`**.

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

- **`--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`**.

**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 @@ -82,21 +89,22 @@ LIMIT 10

### `symbols` — Functions, types, interfaces, enums, constants, classes

| Column | Type | Description |
| ----------------- | ---------- | --------------------------------------------------------- |
| id | INTEGER PK | Auto-increment ID |
| file_path | TEXT FK | References `files(path)` |
| name | TEXT | Symbol name |
| kind | TEXT | `function`, `class`, `type`, `interface`, `enum`, `const` |
| line_start | INTEGER | Start line (1-based) |
| line_end | INTEGER | End line (1-based) |
| signature | TEXT | Reconstructed signature with generics and return types |
| is_exported | INTEGER | 1 if exported |
| is_default_export | INTEGER | 1 if default export |
| members | TEXT | JSON enum members (NULL for non-enums) |
| doc_comment | TEXT | Leading JSDoc text (cleaned), NULL when absent |
| value | TEXT | Literal value for consts (`"ok"`, `42`, `true`, `null`) |
| parent_name | TEXT | Enclosing symbol name (class/function), NULL = top-level |
| Column | Type | Description |
| ----------------- | ---------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| id | INTEGER PK | Auto-increment ID |
| file_path | TEXT FK | References `files(path)` |
| name | TEXT | Symbol name |
| kind | TEXT | `function`, `class`, `type`, `interface`, `enum`, `const` |
| line_start | INTEGER | Start line (1-based) |
| line_end | INTEGER | End line (1-based) |
| signature | TEXT | Reconstructed signature with generics and return types |
| is_exported | INTEGER | 1 if exported |
| is_default_export | INTEGER | 1 if default export |
| members | TEXT | JSON enum members (NULL for non-enums) |
| doc_comment | TEXT | Leading JSDoc text (cleaned), NULL when absent |
| value | TEXT | Literal value for consts (`"ok"`, `42`, `true`, `null`) |
| parent_name | TEXT | Enclosing symbol name (class/function), NULL = top-level |
| visibility | TEXT | Line-leading JSDoc tag: `public` / `private` / `internal` / `alpha` / `beta`; NULL when absent. First match in document order wins |

### `calls` — Function-scoped call edges (deduped per file)

Expand Down Expand Up @@ -233,6 +241,13 @@ WHERE symbol_name = 'UserSession';
SELECT name, kind, file_path, doc_comment FROM symbols
WHERE doc_comment LIKE '%@deprecated%';

-- Visibility-tagged symbols (parsed JSDoc tag — single column, no regex)
SELECT name, kind, visibility, file_path
FROM symbols WHERE visibility IS NOT NULL ORDER BY visibility, file_path;

-- Just the @beta surface (filter on the parsed tag, not doc_comment LIKE)
SELECT name, kind, file_path FROM symbols WHERE visibility = 'beta';

-- Symbol documentation
SELECT name, signature, doc_comment FROM symbols
WHERE name = 'formatCurrency' AND doc_comment IS NOT NULL;
Expand Down
5 changes: 5 additions & 0 deletions .changeset/agents-templates-tier-a-b7.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@stainless-code/codemap": patch
---

Update bundled `templates/agents/` rule and skill to cover the recent CLI surface — `codemap query --summary` / `--changed-since <ref>` / `--group-by owner|directory|package`, per-row recipe `actions`, and the new `symbols.visibility` column. The dev-side `.agents/` mirror is updated in lockstep so this clone stays self-consistent.
4 changes: 4 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ These rules are normative — cite them by number in PR review. Ordered by how o
7. **No line-number references** — line numbers (e.g. `parser.ts:241`) rot on every edit. Reference by function name, section heading, or symbol from `codemap query` instead. Methodology tables in [benchmark.md](./benchmark.md) are exempt.
8. **Research notes get closed** — when a research scan's adopt items ship, slim the note to a "What shipped" appendix linking to canonical homes (see [research/competitive-scan-2026-04.md](./research/competitive-scan-2026-04.md) as the precedent). Rejected items keep a `Status: Rejected (date) — <one-line reason>` header.
9. **New term ⇒ update [glossary.md](./glossary.md) in the same PR** — when a PR introduces a new domain noun / verb / acronym (table name, recipe id, parser name, schema column), add or update its entry. Disambiguations (e.g. `FileRow` TS shape vs `files` SQLite table) take priority over single defs.
10. **Core surface change ⇒ update bundled agent rule + skill in the same PR** — when a PR adds / changes a CLI flag, recipe id, recipe `actions` template, schema column, or any other surface an agent would query, update **both** copies of the codemap rule + skill so installed agents and this clone stay in lockstep:
- **`templates/agents/rules/codemap.md`** + **`templates/agents/skills/codemap/SKILL.md`** (ships to npm via `codemap agents init`).
- **`.agents/rules/codemap.md`** + **`.agents/skills/codemap/SKILL.md`** (this clone's dev-side mirror — keeps my own session view of the CLI accurate).
Drift between the two pairs should be **CLI-prefix-only** (`codemap` vs `bun src/index.ts`) — anything else means content has diverged. Schema-version bumps and new recipes are the most common trigger; output flags (e.g. `--summary`, `--changed-since`, `--group-by`) come second. Patch changeset suffices when the underlying feature already shipped its own changeset (templates/agents/ is the only ship-affecting surface in such a PR).

---

Expand Down
2 changes: 2 additions & 0 deletions docs/agents.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

The published package ships **`templates/agents/`** (rules + skills). This repo also has [`.agents/`](../.agents/) for **Codemap development** (CLI from source); it is **not** identical to **`templates/agents/`** for every file (e.g. the **codemap** rule/skill). The command **`codemap agents init`** writes each bundled template file into **`<project>/.agents/`** with per-file copies (not a wholesale directory sync) — the **canonical** copy consumers edit (SQL, team conventions, paths).

**Maintenance discipline:** Core CLI / schema / recipe changes must update **both** copies of the codemap rule + skill in the same PR — see [README.md Rule 10](./README.md). Drift between `templates/agents/` and `.agents/` should be CLI-prefix-only (`codemap` vs `bun src/index.ts`).

**Query examples** in the bundled **codemap** rule and skill lead with **`codemap query --json`** (agents and automation). Omit **`--json`** when you want **`console.table`** in a terminal — see [README.md § CLI](../README.md#cli).

```bash
Expand Down
7 changes: 7 additions & 0 deletions templates/agents/rules/codemap.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ Install **[@stainless-code/codemap](https://www.npmjs.com/package/@stainless-cod
| Query (recipe) | `codemap query --json --recipe fan-out` (see **`codemap query --help`**) |
| Recipe catalog (JSON) | `codemap query --recipes-json` |
| Print one recipe’s SQL | `codemap query --print-sql fan-out` |
| Counts only | `codemap query --json --summary -r deprecated-symbols` |
| PR-scoped rows | `codemap query --json --changed-since origin/main -r fan-out` |
| Bucket by owner / dir / pkg | `codemap 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.

**Bundled rules/skills:** **`codemap agents init`** writes **`.agents/`** from the package (see [docs/agents.md](../../../docs/agents.md)).

Expand Down Expand Up @@ -67,6 +72,7 @@ If the question looks like any of these → use the index:
| "What keyframe animations exist?" | `css_keyframes` |
| "What fields does interface/type X have?" | `type_members` |
| "Is symbol X deprecated?" / "What does X do?" | `symbols` (`doc_comment`) |
| "What's `@internal` / `@beta` / `@alpha` / `@private`?" | `symbols.visibility` (parsed JSDoc tag — not regex) |
| "Who calls X?" / "What does X call?" | `calls` |

## When Grep / Read IS appropriate
Expand Down Expand Up @@ -107,6 +113,7 @@ codemap query --json "<SQL>"
| 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 = '...'` |
Expand Down
Loading
Loading