@stainless-code/codemap 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,37 @@
1
+ ---
2
+ description: When creating or moving rules/skills, always store the source file in .agents/ and symlink from .cursor/
3
+ alwaysApply: true
4
+ ---
5
+
6
+ # Agents-First File Convention
7
+
8
+ When creating **any** new rule or skill, follow this convention:
9
+
10
+ ## Rules (`.mdc` files)
11
+
12
+ 1. Create the file in `.agents/rules/<name>.mdc`
13
+ 2. Create a symlink in `.cursor/rules/`:
14
+
15
+ ```bash
16
+ ln -s ../../.agents/rules/<name>.mdc .cursor/rules/<name>.mdc
17
+ ```
18
+
19
+ ## Skills (`SKILL.md` files)
20
+
21
+ 1. Create the directory and file in `.agents/skills/<name>/SKILL.md`
22
+ 2. Create a symlink in `.cursor/skills/`:
23
+
24
+ ```bash
25
+ ln -s ../../.agents/skills/<name> .cursor/skills/<name>
26
+ ```
27
+
28
+ ## Why
29
+
30
+ - `.agents/` is the **source of truth** — it is IDE-agnostic and works across different AI coding tools.
31
+ - `.cursor/` only contains **symlinks** pointing back to `.agents/`.
32
+ - This keeps configuration portable and avoids duplication.
33
+
34
+ ## Never
35
+
36
+ - Never place original rule/skill content directly in `.cursor/rules/` or `.cursor/skills/`.
37
+ - Never create a rule or skill without both the `.agents/` file and the `.cursor/` symlink.
@@ -0,0 +1,110 @@
1
+ ---
2
+ alwaysApply: true
3
+ ---
4
+
5
+ # Codemap (structural codebase index)
6
+
7
+ > **STOP.** Before you call Grep, Glob, SemanticSearch, or Read to answer a **structural** question about this repository — query the Codemap SQLite index first. This is not optional when the question matches a trigger pattern below.
8
+
9
+ A local database (default **`.codemap.db`**) indexes structure: symbols, imports, exports, components, dependencies, markers, CSS variables, CSS classes, CSS keyframes.
10
+
11
+ **Generic defaults:** This rule is **project-agnostic**. After you vendor or symlink it (or use a future `codemap` CLI that writes agent files), **edit your copy** to add app-specific triggers and SQL — upstream text is only a baseline.
12
+
13
+ ## CLI (this repo vs installed package)
14
+
15
+ | Context | Incremental index | Query |
16
+ | ------- | ----------------- | ----- |
17
+ | Developing in this repo | `bun src/index.ts` | `bun src/index.ts query "<SQL>"` |
18
+ | After `bun link` / global `codemap` | `codemap` | `codemap query "<SQL>"` |
19
+ | Published package (when available) | `bunx @stainless-code/codemap` | `bunx @stainless-code/codemap query "<SQL>"` |
20
+
21
+ Index another project: **`--root /path/to/repo`**, or set **`CODEMAP_ROOT`** or **`CODEMAP_TEST_BENCH`** (e.g. in **`.env`** in this repo — see [docs/benchmark.md § Indexing another project](../../docs/benchmark.md#indexing-another-project)). Full rebuild: **`--full`**. Targeted re-index: **`--files path/to/a.ts path/to/b.tsx`**.
22
+
23
+ ## Session start (do this ONCE per conversation)
24
+
25
+ Run incremental indexing to catch changes made outside this session:
26
+
27
+ ```bash
28
+ bun src/index.ts
29
+ ```
30
+
31
+ ## Pre-flight check (do this EVERY time before searching)
32
+
33
+ 1. **Does the question match a trigger pattern below?**
34
+ 2. **If yes → query the index.** Do NOT use Grep/Glob/SemanticSearch/Read.
35
+ 3. **If the index result is incomplete → THEN fall back** to other tools, but always try the index first.
36
+
37
+ Violating this order is wrong even if you get the right answer — it wastes time and ignores the tool purpose-built for this.
38
+
39
+ ## Trigger patterns
40
+
41
+ If the question looks like any of these → use the index:
42
+
43
+ | Question shape | Table(s) |
44
+ | --- | --- |
45
+ | "What/which files import X?" | `imports` (by `source`) or `dependencies` (by `to_path`) |
46
+ | "Where is X defined?" | `symbols` |
47
+ | "What does file X export?" | `exports` |
48
+ | "What hooks does component X use?" / "List React components" | `components` |
49
+ | "What are the CSS variables/tokens for X?" | `css_variables` |
50
+ | "Find all TODOs/FIXMEs" | `markers` |
51
+ | "Who depends on file X?" / "What does file X depend on?" | `dependencies` |
52
+ | "How many files/symbols/components are there?" | any table with `COUNT(*)` |
53
+ | "What are the CSS classes in X?" | `css_classes` |
54
+ | "What keyframe animations exist?" | `css_keyframes` |
55
+
56
+ ## When Grep / Read IS appropriate
57
+
58
+ - Reading implementation details you need to edit
59
+ - Reviewing logic, control flow, or business rules
60
+ - Searching for patterns the index doesn't capture (string literals, inline logic, etc.)
61
+
62
+ ## How to query
63
+
64
+ ```bash
65
+ bun src/index.ts query "<SQL>"
66
+ ```
67
+
68
+ ## Quick reference queries
69
+
70
+ | I need to... | Query |
71
+ | --- | --- |
72
+ | Find a symbol | `SELECT name, kind, file_path, line_start, line_end, signature FROM symbols WHERE name = '...'` |
73
+ | Find a symbol (fuzzy) | `SELECT name, kind, file_path, line_start FROM symbols WHERE name LIKE '%...%'` |
74
+ | See file exports | `SELECT name, kind, is_default FROM exports WHERE file_path LIKE '%...'` |
75
+ | See file imports | `SELECT source, specifiers, is_type_only FROM imports WHERE file_path LIKE '%...'` |
76
+ | Who imports this module? | `SELECT DISTINCT file_path FROM imports WHERE source LIKE '~/some/module%'` |
77
+ | Who imports this file? | `SELECT DISTINCT from_path FROM dependencies WHERE to_path LIKE '%...'` |
78
+ | What does this depend on? | `SELECT DISTINCT to_path FROM dependencies WHERE from_path LIKE '%...'` |
79
+ | Component info | `SELECT name, props_type, hooks_used FROM components WHERE name = '...'` |
80
+ | All components | `SELECT name, file_path, props_type, hooks_used FROM components ORDER BY name` |
81
+ | TODOs in a file | `SELECT line_number, content FROM markers WHERE file_path LIKE '%...' AND kind = 'TODO'` |
82
+ | Most complex files | `SELECT from_path, COUNT(*) as deps FROM dependencies GROUP BY from_path ORDER BY deps DESC LIMIT 10` |
83
+ | CSS design tokens | `SELECT name, value, scope FROM css_variables WHERE name LIKE '--%...'` |
84
+ | CSS module classes | `SELECT name, file_path FROM css_classes WHERE is_module = 1` |
85
+ | CSS keyframes | `SELECT name, file_path FROM css_keyframes` |
86
+
87
+ **Use `DISTINCT`** on dependency and import queries — a file importing multiple specifiers from the same module produces duplicate rows.
88
+
89
+ For the full schema, advanced query patterns, and troubleshooting, read the skill at `.agents/skills/codemap/SKILL.md`.
90
+
91
+ ## Keeping it fresh
92
+
93
+ **After completing a step that modified source files, re-index before making any further queries.** The index only reflects the state at the time it was last built — edits you just made won't appear until you re-index.
94
+
95
+ ```bash
96
+ # Targeted — re-index only the files you just touched
97
+ bun src/index.ts --files path/to/file1.tsx path/to/file2.ts
98
+
99
+ # Incremental — auto-detects changed files via git
100
+ bun src/index.ts
101
+
102
+ # Full rebuild — after rebase, branch switch, or stale index
103
+ bun src/index.ts --full
104
+ ```
105
+
106
+ ### When to re-index
107
+
108
+ - **After editing files** — use `--files` with the paths you modified (fastest). Deleted files are auto-detected and removed from the index
109
+ - **After switching branches or rebasing** — run `--full`
110
+ - **When unsure which files changed** — run without flags to auto-detect via git
@@ -0,0 +1,312 @@
1
+ # Codemap — full reference
2
+
3
+ Query codebase structure via SQLite instead of scanning files. Use when exploring code, finding symbols, tracing dependencies, or auditing a project indexed by **Codemap**.
4
+
5
+ ## Bundled content (stay generic)
6
+
7
+ Examples below use **placeholders** (`'...'`, `getConfig`, `~/lib/api`, etc.) — not a real product tree. **Shipped skill and rules stay generic** so they apply to any repo.
8
+
9
+ **In your project:** copy or symlink these files into `.agents/` / `.cursor/` (see **`.github/CONTRIBUTING.md`**), or use a future **`codemap` CLI** that vendors agent files. Then **edit your copy** to add your team’s tsconfig aliases, directory conventions, and SQL snippets you reuse. Treat upstream updates as a reference; merge deliberately.
10
+
11
+ **Run queries**
12
+
13
+ ```bash
14
+ bun src/index.ts query "<SQL>"
15
+ ```
16
+
17
+ When the package is installed globally or via `bunx`: `codemap query "<SQL>"` or `bunx @stainless-code/codemap query "<SQL>"`. Use **`--root`** to point at another project.
18
+
19
+ ## Schema
20
+
21
+ ### `files` — Every indexed file
22
+
23
+ | Column | Type | Description |
24
+ | ------------- | ------- | -------------------------------------------------------------------------------- |
25
+ | path | TEXT PK | Relative path from project root |
26
+ | content_hash | TEXT | Wyhash fingerprint (base-36) |
27
+ | size | INTEGER | File size in bytes |
28
+ | line_count | INTEGER | Number of lines |
29
+ | language | TEXT | `ts`, `tsx`, `js`, `jsx`, `css`, `md`, `mdx`, `mdc`, `json`, `yaml`, `sh`, `txt` |
30
+ | last_modified | INTEGER | Unix timestamp (ms) |
31
+ | indexed_at | INTEGER | When this file was last indexed |
32
+
33
+ ### `symbols` — Functions, types, interfaces, enums, constants, classes
34
+
35
+ | Column | Type | Description |
36
+ | ----------------- | ---------- | --------------------------------------------------------------------- |
37
+ | id | INTEGER PK | Auto-increment ID |
38
+ | file_path | TEXT FK | References `files(path)` |
39
+ | name | TEXT | Symbol name |
40
+ | kind | TEXT | `function`, `class`, `type`, `interface`, `enum`, `const`, `variable` |
41
+ | line_start | INTEGER | Start line (1-based) |
42
+ | line_end | INTEGER | End line (1-based) |
43
+ | signature | TEXT | e.g. `createHandler()`, `type UserProps` |
44
+ | is_exported | INTEGER | 1 if exported |
45
+ | is_default_export | INTEGER | 1 if default export |
46
+
47
+ ### `imports` — Import statements
48
+
49
+ | Column | Type | Description |
50
+ | ------------- | ------- | ----------------------------------------------- |
51
+ | file_path | TEXT FK | The importing file |
52
+ | source | TEXT | Raw import source (e.g. `~/lib/utils`, `react`) |
53
+ | resolved_path | TEXT | Resolved file path, NULL for external packages |
54
+ | specifiers | TEXT | JSON array of imported names |
55
+ | is_type_only | INTEGER | 1 if `import type` |
56
+ | line_number | INTEGER | Line of the import statement |
57
+
58
+ ### `exports` — Export manifest
59
+
60
+ | Column | Type | Description |
61
+ | ---------------- | ------- | --------------------------------------------- |
62
+ | file_path | TEXT FK | The exporting file |
63
+ | name | TEXT | Exported name (`default` for default exports) |
64
+ | kind | TEXT | `value`, `type`, `re-export` |
65
+ | is_default | INTEGER | 1 if default export |
66
+ | re_export_source | TEXT | Source module for re-exports |
67
+
68
+ ### `components` — React components (TSX files)
69
+
70
+ | Column | Type | Description |
71
+ | ----------------- | ------- | ------------------------------------------------------------ |
72
+ | file_path | TEXT FK | Component file |
73
+ | name | TEXT | Component name (PascalCase) |
74
+ | props_type | TEXT | Props type/interface name, if detected |
75
+ | hooks_used | TEXT | JSON array of hooks called (e.g. `["useState", "useQuery"]`) |
76
+ | is_default_export | INTEGER | 1 if default export |
77
+
78
+ ### `dependencies` — File-to-file dependency graph
79
+
80
+ | Column | Type | Description |
81
+ | --------- | ------- | ----------------------- |
82
+ | from_path | TEXT FK | The file that imports |
83
+ | to_path | TEXT | The file being imported |
84
+
85
+ ### `markers` — TODO/FIXME/HACK/NOTE comments
86
+
87
+ | Column | Type | Description |
88
+ | ----------- | ------- | ------------------------------- |
89
+ | file_path | TEXT FK | File containing the marker |
90
+ | line_number | INTEGER | Line number (1-based) |
91
+ | kind | TEXT | `TODO`, `FIXME`, `HACK`, `NOTE` |
92
+ | content | TEXT | The marker text |
93
+
94
+ ### `css_variables` — CSS custom properties (design tokens)
95
+
96
+ | Column | Type | Description |
97
+ | ----------- | ------- | --------------------------------------------------- |
98
+ | file_path | TEXT FK | CSS file containing the variable |
99
+ | name | TEXT | Variable name (e.g. `--blue-50`, `--text-h1`) |
100
+ | value | TEXT | Parsed value (e.g. `rgb(215, 225, 242)`, `3rem`) |
101
+ | scope | TEXT | Where defined: `:root`, `@theme`, or selector scope |
102
+ | line_number | INTEGER | Line number (1-based) |
103
+
104
+ ### `css_classes` — CSS class definitions
105
+
106
+ | Column | Type | Description |
107
+ | ----------- | ------- | ------------------------------- |
108
+ | file_path | TEXT FK | CSS file containing the class |
109
+ | name | TEXT | Class name (without `.` prefix) |
110
+ | is_module | INTEGER | 1 if from a `.module.css` file |
111
+ | line_number | INTEGER | Line number (1-based) |
112
+
113
+ ### `css_keyframes` — @keyframes animation definitions
114
+
115
+ | Column | Type | Description |
116
+ | ----------- | ------- | --------------------------------- |
117
+ | file_path | TEXT FK | CSS file containing the keyframes |
118
+ | name | TEXT | Animation name |
119
+ | line_number | INTEGER | Line number (1-based) |
120
+
121
+ ### `meta` — Index metadata
122
+
123
+ | Key | Value |
124
+ | --------------------- | --------------------------------- |
125
+ | `last_indexed_commit` | Git SHA of HEAD when last indexed |
126
+ | `indexed_at` | ISO timestamp of last index |
127
+ | `file_count` | Total files indexed |
128
+ | `project_root` | Absolute path to project |
129
+ | `schema_version` | Schema version number |
130
+
131
+ ## Query patterns
132
+
133
+ ### Basic lookups
134
+
135
+ ```sql
136
+ -- Find a symbol definition
137
+ SELECT name, kind, file_path, line_start, line_end, signature
138
+ FROM symbols WHERE name = 'getConfig';
139
+
140
+ -- Fuzzy symbol search
141
+ SELECT name, kind, file_path, line_start
142
+ FROM symbols WHERE name LIKE '%Config%' ORDER BY name;
143
+
144
+ -- All exported symbols from a file
145
+ SELECT name, kind, signature
146
+ FROM symbols WHERE file_path LIKE '%settings-provider%' AND is_exported = 1;
147
+
148
+ -- File overview (imports + exports)
149
+ SELECT 'import' as dir, source as name, specifiers as detail
150
+ FROM imports WHERE file_path LIKE '%OrderRow%'
151
+ UNION ALL
152
+ SELECT 'export', name, kind FROM exports WHERE file_path LIKE '%OrderRow%';
153
+ ```
154
+
155
+ ### Dependency analysis
156
+
157
+ **Use `DISTINCT`** on dependency and import queries — a file importing multiple specifiers from the same module produces duplicate rows.
158
+
159
+ ```sql
160
+ -- Who imports a module by its alias? (matches raw import source string)
161
+ SELECT DISTINCT file_path FROM imports WHERE source LIKE '~/lib/api%';
162
+
163
+ -- Direct dependents (who imports this file? uses resolved paths)
164
+ SELECT DISTINCT from_path FROM dependencies WHERE to_path LIKE '%format-date%';
165
+
166
+ -- Direct dependencies (what does this file import?)
167
+ SELECT DISTINCT to_path FROM dependencies WHERE from_path LIKE '%OrderRow%';
168
+
169
+ -- Most-imported files (hotspots)
170
+ SELECT to_path, COUNT(*) as importers
171
+ FROM dependencies GROUP BY to_path ORDER BY importers DESC LIMIT 15;
172
+
173
+ -- Most complex files (most dependencies)
174
+ SELECT from_path, COUNT(*) as dep_count
175
+ FROM dependencies GROUP BY from_path ORDER BY dep_count DESC LIMIT 15;
176
+
177
+ -- Circular dependencies (1-hop)
178
+ SELECT a.from_path, a.to_path
179
+ FROM dependencies a
180
+ JOIN dependencies b ON a.to_path = b.from_path AND b.to_path = a.from_path;
181
+
182
+ -- Orphan files (no one imports them, excluding test and story files)
183
+ SELECT f.path FROM files f
184
+ LEFT JOIN dependencies d ON d.to_path = f.path
185
+ WHERE d.from_path IS NULL
186
+ AND f.path NOT LIKE '%.test.%'
187
+ AND f.path NOT LIKE '%.stories.%'
188
+ ORDER BY f.path;
189
+ ```
190
+
191
+ ### Component analysis
192
+
193
+ ```sql
194
+ -- Components using a specific hook
195
+ SELECT name, file_path, hooks_used
196
+ FROM components WHERE hooks_used LIKE '%useTheme%';
197
+
198
+ -- Components with most hooks (complexity indicator)
199
+ SELECT name, file_path,
200
+ json_array_length(hooks_used) as hook_count
201
+ FROM components ORDER BY hook_count DESC LIMIT 15;
202
+
203
+ -- Components with props types
204
+ SELECT name, file_path, props_type
205
+ FROM components WHERE props_type IS NOT NULL ORDER BY name;
206
+ ```
207
+
208
+ ### CSS analysis
209
+
210
+ ```sql
211
+ -- All design tokens (color palette)
212
+ SELECT name, value, scope FROM css_variables
213
+ WHERE name LIKE '--blue%' OR name LIKE '--gray%' ORDER BY name;
214
+
215
+ -- Tailwind theme tokens
216
+ SELECT name, value FROM css_variables WHERE scope = '@theme' LIMIT 20;
217
+
218
+ -- All CSS module classes in a file
219
+ SELECT name FROM css_classes
220
+ WHERE file_path LIKE '%ProductCard%' AND is_module = 1;
221
+
222
+ -- All keyframe animations
223
+ SELECT name, file_path FROM css_keyframes;
224
+
225
+ -- Token categories (grouped by prefix)
226
+ SELECT
227
+ substr(name, 1, instr(substr(name, 3), '-') + 2) as prefix,
228
+ COUNT(*) as count
229
+ FROM css_variables
230
+ GROUP BY prefix ORDER BY count DESC;
231
+ ```
232
+
233
+ ### Efficient pagination (cursor-based)
234
+
235
+ For large result sets, avoid `OFFSET` — use cursor-based pagination with the last-seen value:
236
+
237
+ ```sql
238
+ -- First page
239
+ SELECT name, kind, file_path, line_start FROM symbols
240
+ WHERE is_exported = 1
241
+ ORDER BY name LIMIT 50;
242
+
243
+ -- Next page (use last name from previous result as cursor)
244
+ SELECT name, kind, file_path, line_start FROM symbols
245
+ WHERE is_exported = 1 AND name > 'lastSeenName'
246
+ ORDER BY name LIMIT 50;
247
+ ```
248
+
249
+ ### Conditional aggregation (single query for multiple counts)
250
+
251
+ ```sql
252
+ -- Instead of multiple COUNT(*) queries, use conditional aggregation:
253
+ SELECT
254
+ (SELECT COUNT(*) FROM files) as files,
255
+ (SELECT COUNT(*) FROM symbols) as symbols,
256
+ (SELECT COUNT(*) FROM imports) as imports,
257
+ (SELECT COUNT(*) FROM components) as components,
258
+ (SELECT COUNT(*) FROM dependencies) as dependencies;
259
+ ```
260
+
261
+ ### Codebase statistics
262
+
263
+ ```sql
264
+ -- Files by language
265
+ SELECT language, COUNT(*) as count FROM files GROUP BY language;
266
+
267
+ -- Symbols by kind
268
+ SELECT kind, COUNT(*) as count FROM symbols GROUP BY kind ORDER BY count DESC;
269
+
270
+ -- Exported vs internal symbols
271
+ SELECT
272
+ SUM(is_exported) as exported,
273
+ COUNT(*) - SUM(is_exported) as internal
274
+ FROM symbols;
275
+
276
+ -- Largest files
277
+ SELECT path, line_count, size FROM files ORDER BY line_count DESC LIMIT 15;
278
+
279
+ -- All TODO/FIXME markers
280
+ SELECT kind, COUNT(*) as count FROM markers GROUP BY kind;
281
+ ```
282
+
283
+ ## Maintenance
284
+
285
+ From this repository:
286
+
287
+ ```bash
288
+ # Targeted — re-index only specific files you just modified
289
+ bun src/index.ts --files path/to/file.tsx path/to/other.ts
290
+
291
+ # Incremental — auto-detects changes via git
292
+ bun src/index.ts
293
+
294
+ # Full rebuild — after rebase, branch switch, or stale index
295
+ bun src/index.ts --full
296
+
297
+ # Check index freshness
298
+ bun src/index.ts query "SELECT key, value FROM meta"
299
+ ```
300
+
301
+ **Prefer `--files`** when you know which files you changed — it skips git diff and filesystem scanning for the rest of the tree. Deleted files passed to `--files` are auto-removed from the index.
302
+
303
+ When Codemap is installed as a package: `codemap`, `codemap --root /path/to/project`, or `bunx @stainless-code/codemap …` (same flags).
304
+
305
+ ## Troubleshooting
306
+
307
+ | Problem | Solution |
308
+ | -------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
309
+ | Stale results after rebase | Run `bun src/index.ts --full` (or `codemap --full` when installed) |
310
+ | Missing file in results | Check exclude / include globs in **`codemap.config.ts`**, **`codemap.config.json`**, or defaults in **`src/index.ts`** |
311
+ | `resolved_path` is NULL | Import is an external package (not in project) |
312
+ | Resolver errors | Verify `tsconfig.json` paths (or **`tsconfigPath`** in config) when resolving aliases |