fix: audit findings — 3 HIGH bugs, perf, docs, cleanup#15
Conversation
- Add missing onerror handler on Bun Worker path (audit #3) — prevents promise hang when a parse worker crashes - Batch CSS imports instead of inserting one-at-a-time (audit S1) — both full-rebuild and incremental paths now pass the full array to insertImports, letting batchInsert chunk properly - Hoist inner.query() in wrap() to avoid redundant rawDb.prepare() on Node when .get()/.all() is called multiple times (audit S2) - Fix SCHEMA_VERSION comment to match actual value of 1 (audit #4) - Skip PRAGMA optimize on closeDb for read-only query paths (audit S4)
PascalCase functions in .tsx files were unconditionally indexed as components. Now maybeAddComponent checks for JSX elements/fragments in the function body or hook calls before registering — eliminates false positives like FormatCurrency(), ValidateEmail(), etc. Added negative test cases for the heuristic; updated the existing positive test to use actual JSX return.
Node's better-sqlite3 wrapper called rawDb.prepare(sql) on every run()/query() call with no caching. batchInsert re-prepares the same SQL string ~50 times per table. Added a Map<string, Statement> cache keyed by SQL string — safe because schema changes happen before inserts.
oxlint doesn't enforce @typescript-eslint/no-require-imports or @typescript-eslint/no-explicit-any — these comments were no-ops.
🦋 Changeset detectedLatest commit: 9b323fd The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
📝 WalkthroughWalkthroughThis PR fixes incremental indexing for custom extensions, refines component detection to require JSX or hooks, adds Bun worker onerror handling, batches CSS import inserts, caches prepared SQLite statements, skips PRAGMA on readonly closes, and updates docs/schema hashing to SHA-256. Changes
Sequence Diagram(s)mermaid Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Add CSS module with @Keyframes + @import, PascalCase non-component function (validates audit fix #1 false-positive rejection), FIXME marker, second CSS variable, and class selector. 7 new golden scenarios: exports, css_variables, css_classes, css_keyframes, css_imports, markers-all-kinds, components-no-false- positives. All 13 scenarios pass.
- architecture.md: component detection heuristic (JSX return or hook usage), statement cache on Node, closeDb readonly for query paths, incremental/--files accept previously-indexed custom extensions - benchmark.md: fixture description reflects enriched minimal/ - golden-queries.md: note 13-scenario Tier A coverage across all tables
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
.agents/skills/codemap/SKILL.md (1)
66-85:⚠️ Potential issue | 🟡 MinorThe skill schema still advertises a
symbols.kindvalue the index never writes.While updating this schema table,
symbols.kindstill includesvariable, butsrc/parser.tsemitsfunction,const,class,interface,type, andenum, anddocs/architecture.mdwas already corrected. Please update this copy andtemplates/agents/skills/codemap/SKILL.mdtogether so agent-authored SQL does not target a stale enum.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.agents/skills/codemap/SKILL.md around lines 66 - 85, The schema docs still list a stale `symbols.kind` value `variable`; update the documentation to match the actual enum emitted by the indexer/parser by removing `variable` and ensuring the allowed kinds are exactly `function`, `const`, `class`, `interface`, `type`, and `enum`; edit .agents/skills/codemap/SKILL.md (and the template at templates/agents/skills/codemap/SKILL.md) to remove `variable` from the table and align wording with src/parser.ts and docs/architecture.md so generated SQL and agent prompts reference the correct enum values.docs/architecture.md (1)
437-459:⚠️ Potential issue | 🟡 MinorUpdate the SQLite performance paragraph to reflect statement caching on Node.
Line 439 states "on Node,
better-sqlite3re-prepares on each call via the wrapper'srun()method"—butsrc/sqlite-db.tsnow implementsstmtCacheandcachedPrepare()to reuse prepared statements for bothrun()andquery()on Node. Update this paragraph to clarify that the wrapper caches statements on Node, not re-prepares them.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/architecture.md` around lines 437 - 459, The doc incorrectly states that on Node `better-sqlite3` re-prepares statements on each call; update the "bun:sqlite API" paragraph to reflect that `src/sqlite-db.ts` now caches prepared statements for Node using `stmtCache` and `cachedPrepare()`, so both `run()` and `query()` reuse prepared statements instead of re-preparing them. Edit the sentence referencing Node to mention `stmtCache`/`cachedPrepare()` and that the wrapper reuses cached statements for `run()` and `.query().all()`/`.get()` to match the current implementation.src/application/run-index.ts (1)
42-44:⚠️ Potential issue | 🟡 MinorUpdate
RunIndexOptions.filesdocstring to match current behavior.Line 43 says non-indexable extensions are filtered out, but
mode === "files"now forwards all provided paths. This comment is now inaccurate.Suggested doc fix
/** * Paths relative to the project root; used only when `mode === "files"`. - * Non-indexable extensions are filtered out. + * Paths are passed through as-is; non-standard extensions are indexed as text. */ files?: string[];🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/application/run-index.ts` around lines 42 - 44, Update the RunIndexOptions.files docstring to reflect current behavior: note that when mode === "files" the array of paths is forwarded verbatim (no automatic filtering of non-indexable extensions) and that callers are responsible for providing only desired paths or performing any extension filtering themselves; reference RunIndexOptions.files and the mode === "files" behavior in the text so it is clear to future readers.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/application/index-engine.ts`:
- Around line 129-134: The incremental filter currently only keeps files whose
extension is in LANG_MAP or already indexed (indexedPaths from
getAllFileHashes), which skips newly added files with custom extensions; update
the predicate used for allChanged (which filters [...diffFiles, ...statusFiles])
so it also accepts files that match configured custom extensions or otherwise
should be treated as source (e.g., a helper function isCustomExtension(file)
that checks the project's custom extensions list or workspace file existence),
i.e., change the condition from "ext in LANG_MAP || indexedPaths.has(f)" to "ext
in LANG_MAP || indexedPaths.has(f) || isCustomExtension(f)" (or equivalent
logic) so new custom-extension files are included for indexing.
In `@src/db.ts`:
- Around line 20-25: The PRAGMA calls in closeDb can throw and prevent
db.close() from running; wrap the PRAGMA block (the db.run("PRAGMA
analysis_limit = 400") and db.run("PRAGMA optimize") calls) in a try and move
db.close() into a finally so the CodemapDatabase handle is always closed even on
error; preserve the opts?.readonly short-circuit (skip PRAGMAs when readonly)
and make sure any error from the PRAGMA block is not silently swallowed (rethrow
after closing or let it bubble).
---
Outside diff comments:
In @.agents/skills/codemap/SKILL.md:
- Around line 66-85: The schema docs still list a stale `symbols.kind` value
`variable`; update the documentation to match the actual enum emitted by the
indexer/parser by removing `variable` and ensuring the allowed kinds are exactly
`function`, `const`, `class`, `interface`, `type`, and `enum`; edit
.agents/skills/codemap/SKILL.md (and the template at
templates/agents/skills/codemap/SKILL.md) to remove `variable` from the table
and align wording with src/parser.ts and docs/architecture.md so generated SQL
and agent prompts reference the correct enum values.
In `@docs/architecture.md`:
- Around line 437-459: The doc incorrectly states that on Node `better-sqlite3`
re-prepares statements on each call; update the "bun:sqlite API" paragraph to
reflect that `src/sqlite-db.ts` now caches prepared statements for Node using
`stmtCache` and `cachedPrepare()`, so both `run()` and `query()` reuse prepared
statements instead of re-preparing them. Edit the sentence referencing Node to
mention `stmtCache`/`cachedPrepare()` and that the wrapper reuses cached
statements for `run()` and `.query().all()`/`.get()` to match the current
implementation.
In `@src/application/run-index.ts`:
- Around line 42-44: Update the RunIndexOptions.files docstring to reflect
current behavior: note that when mode === "files" the array of paths is
forwarded verbatim (no automatic filtering of non-indexable extensions) and that
callers are responsible for providing only desired paths or performing any
extension filtering themselves; reference RunIndexOptions.files and the mode ===
"files" behavior in the text so it is clear to future readers.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 687b739c-2875-41f0-96dd-9029df3ee454
📒 Files selected for processing (14)
.agents/skills/codemap/SKILL.md.changeset/audit-findings.mddocs/architecture.mdsrc/application/index-engine.tssrc/application/run-index.tssrc/cli/cmd-index.tssrc/css-parser.tssrc/db.tssrc/glob-sync.tssrc/parser.test.tssrc/parser.tssrc/sqlite-db.tssrc/worker-pool.tstemplates/agents/skills/codemap/SKILL.md
💤 Files with no reviewable changes (2)
- src/glob-sync.ts
- src/css-parser.ts
…, SKILL.md kind - closeDb: wrap PRAGMA optimize in try/finally so db.close() always runs - run-index.ts: update RunIndexOptions.files docstring (no longer filtered) - SKILL.md: remove stale `variable` from symbols.kind (agents + templates)
There was a problem hiding this comment.
🧹 Nitpick comments (2)
fixtures/minimal/src/styles/button.module.css (1)
8-8: Use kebab-case for keyframe name to satisfy lint rule.Line 8 uses
fadeIn, butkeyframes-name-patternexpects kebab-case. Rename tofade-in(and update any fixture expectations referencing this name).Proposed change
-@keyframes fadeIn { +@keyframes fade-in {🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@fixtures/minimal/src/styles/button.module.css` at line 8, The keyframe name "fadeIn" in button.module.css violates the keyframes-name-pattern lint rule; rename the keyframe to kebab-case "fade-in" in the `@keyframes` declaration and update all references to that animation name (e.g., within button.module.css and any fixture expectation files that assert on "fadeIn") so they use "fade-in" instead to keep lint and tests consistent.src/application/run-index.ts (1)
42-44: Don’t hard-code the text-fallback contract in this layer.Line 43 now promises that non-standard extensions are indexed as text, but Lines 82-95 only forward raw paths into
targetedReindex(). The providedsrc/application/index-engine.ts:252-320andsrc/application/index-engine.ts:427-446snippets show no extension handling downstream either, so this shared CLI andCodemap#indexentry point is documenting behavior it doesn’t enforce. Consider moving the warning/fallback intorunCodemapIndex()/targetedReindex()or softening the docstring so both entry points keep the same contract.Also applies to: 82-95
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/application/run-index.ts` around lines 42 - 44, The docstring in run-index.ts incorrectly promises a text-fallback for non-standard extensions even though neither runCodemapIndex nor targetedReindex (and the Codemap#index entry path) enforce that behavior; either remove/soften that assertion in the comment OR implement the fallback in the runtime: add extension-to-text handling inside runCodemapIndex() or targetedReindex() so paths with non-standard extensions are normalized to the text indexing branch before calling Codemap#index; reference runCodemapIndex, targetedReindex, and Codemap#index when making the change so both the CLI surface and the shared index entrypoint have a single, consistent contract.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@fixtures/minimal/src/styles/button.module.css`:
- Line 8: The keyframe name "fadeIn" in button.module.css violates the
keyframes-name-pattern lint rule; rename the keyframe to kebab-case "fade-in" in
the `@keyframes` declaration and update all references to that animation name
(e.g., within button.module.css and any fixture expectation files that assert on
"fadeIn") so they use "fade-in" instead to keep lint and tests consistent.
In `@src/application/run-index.ts`:
- Around line 42-44: The docstring in run-index.ts incorrectly promises a
text-fallback for non-standard extensions even though neither runCodemapIndex
nor targetedReindex (and the Codemap#index entry path) enforce that behavior;
either remove/soften that assertion in the comment OR implement the fallback in
the runtime: add extension-to-text handling inside runCodemapIndex() or
targetedReindex() so paths with non-standard extensions are normalized to the
text indexing branch before calling Codemap#index; reference runCodemapIndex,
targetedReindex, and Codemap#index when making the change so both the CLI
surface and the shared index entrypoint have a single, consistent contract.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 9a88a4c9-73bd-4bfe-afba-3b6a505b02f4
📒 Files selected for processing (22)
.agents/skills/codemap/SKILL.md.changeset/audit-findings.mddocs/architecture.mddocs/benchmark.mddocs/golden-queries.mdfixtures/golden/minimal/components-no-false-positives.jsonfixtures/golden/minimal/css-classes-module.jsonfixtures/golden/minimal/css-imports.jsonfixtures/golden/minimal/css-keyframes.jsonfixtures/golden/minimal/css-variables.jsonfixtures/golden/minimal/exports-client.jsonfixtures/golden/minimal/files-count.jsonfixtures/golden/minimal/index-summary.jsonfixtures/golden/minimal/markers-all-kinds.jsonfixtures/golden/scenarios.jsonfixtures/minimal/src/components/shop/ShopButton.tsxfixtures/minimal/src/consumer.tsfixtures/minimal/src/styles/button.module.cssfixtures/minimal/src/theme.csssrc/application/run-index.tssrc/db.tstemplates/agents/skills/codemap/SKILL.md
✅ Files skipped from review due to trivial changes (15)
- fixtures/golden/minimal/components-no-false-positives.json
- fixtures/minimal/src/consumer.ts
- fixtures/golden/minimal/files-count.json
- fixtures/golden/minimal/css-classes-module.json
- fixtures/golden/minimal/markers-all-kinds.json
- fixtures/minimal/src/theme.css
- fixtures/golden/minimal/index-summary.json
- fixtures/golden/minimal/css-imports.json
- docs/golden-queries.md
- fixtures/golden/minimal/exports-client.json
- fixtures/golden/minimal/css-variables.json
- fixtures/golden/scenarios.json
- fixtures/golden/minimal/css-keyframes.json
- docs/benchmark.md
- .changeset/audit-findings.md
🚧 Files skipped from review as they are similar to previous changes (3)
- templates/agents/skills/codemap/SKILL.md
- src/db.ts
- docs/architecture.md
Summary
Addresses all actionable findings from cross-audit triangulation of three independent AI audits (Composer-2-fast, GPT-5.4-extra-high, Opus-4.6-max).
Bug fixes (3 HIGH, reproduced)
onerror— parse worker crash silently hangs the full-rebuild pipeline; addedonerrorhandler +worker.terminate().tsxunconditionally indexed as components; now requires JSX return or hook usage (5 new test cases)--filesskips custom extensions — files indexed during--fullvia custom include patterns silently go stale; now checksfilestable for previously-indexed pathsPerformance (4 SQLite improvements)
insertImportscalled once per file, not per import)Map<string, Statement>) forbetter-sqlite3run()/query()— eliminates ~2,000+ redundantprepare()callsinner.query()inwrap()— prepare once, not per.get()/.all()PRAGMA optimizeoncloseDbfor read-only query paths — avoidsSQLITE_BUSYcontentionDocs
symbols.kind:variable→const,type_alias→type;exports.kindcorrectedDatabase.query()caching claim clarified as Bun-only; Node statement cache documentedcloseDbreadonly, incremental/--filescustom extensionsTesting
fixtures/minimal/to cover all 10 indexed tables (CSS module with@keyframes+@import, non-component PascalCase export, FIXME marker, second CSS variable, class selector)Cleanup
analyzeDependencies: truefrom CSS parserfetchTableStatsacrossindex-engine.ts/run-index.tseslint-disable-next-linedirectives (oxlint doesn't enforce those rules)SCHEMA_VERSIONcomment mismatchTest plan
bun test)bun run test:golden)bun src/index.ts --full)bun src/index.ts query --json "SELECT ...")Summary by CodeRabbit
Bug Fixes
.tsxfalse positives--filesindexing include previously indexed custom-extension filesPerformance
Documentation
Tests