lsp-intelligence 0.2.0 → 0.2.1

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.
Files changed (148) hide show
  1. package/README.md +41 -13
  2. package/dist/analysis/pattern/collectSearchFiles.d.ts +2 -1
  3. package/dist/analysis/pattern/collectSearchFiles.js +6 -6
  4. package/dist/analysis/pattern/collectSearchFiles.js.map +1 -1
  5. package/dist/analysis/pattern/runPatternSearch.d.ts +1 -1
  6. package/dist/analysis/pattern/runPatternSearch.js +4 -2
  7. package/dist/analysis/pattern/runPatternSearch.js.map +1 -1
  8. package/dist/analysis/ts/extractUsages.js +19 -0
  9. package/dist/analysis/ts/extractUsages.js.map +1 -1
  10. package/dist/analysis/ts/parseSourceFile.d.ts +2 -1
  11. package/dist/analysis/ts/parseSourceFile.js +5 -9
  12. package/dist/analysis/ts/parseSourceFile.js.map +1 -1
  13. package/dist/analysis/ts/reactState.d.ts +9 -0
  14. package/dist/analysis/ts/reactState.js +57 -0
  15. package/dist/analysis/ts/reactState.js.map +1 -0
  16. package/dist/analysis/ts/structuralPredicates.js +31 -2
  17. package/dist/analysis/ts/structuralPredicates.js.map +1 -1
  18. package/dist/ast/parseFile.d.ts +4 -3
  19. package/dist/ast/parseFile.js +22 -5
  20. package/dist/ast/parseFile.js.map +1 -1
  21. package/dist/engine/LspEngine.js +23 -1
  22. package/dist/engine/LspEngine.js.map +1 -1
  23. package/dist/git/getBaseFileContent.d.ts +1 -0
  24. package/dist/git/getBaseFileContent.js +10 -3
  25. package/dist/git/getBaseFileContent.js.map +1 -1
  26. package/dist/git/getChangedFiles.d.ts +2 -1
  27. package/dist/git/getChangedFiles.js +11 -5
  28. package/dist/git/getChangedFiles.js.map +1 -1
  29. package/dist/git/getChangedHunks.d.ts +1 -0
  30. package/dist/git/getChangedHunks.js +15 -10
  31. package/dist/git/getChangedHunks.js.map +1 -1
  32. package/dist/git/getGitRoot.d.ts +15 -0
  33. package/dist/git/getGitRoot.js +33 -0
  34. package/dist/git/getGitRoot.js.map +1 -0
  35. package/dist/index.js +2 -0
  36. package/dist/index.js.map +1 -1
  37. package/dist/resolve/searchScope.d.ts +8 -2
  38. package/dist/resolve/searchScope.js +26 -14
  39. package/dist/resolve/searchScope.js.map +1 -1
  40. package/dist/search/adapters/config.d.ts +5 -0
  41. package/dist/search/adapters/config.js +56 -0
  42. package/dist/search/adapters/config.js.map +1 -0
  43. package/dist/search/adapters/http.d.ts +6 -0
  44. package/dist/search/adapters/http.js +58 -0
  45. package/dist/search/adapters/http.js.map +1 -0
  46. package/dist/search/adapters/react.d.ts +12 -0
  47. package/dist/search/adapters/react.js +92 -0
  48. package/dist/search/adapters/react.js.map +1 -0
  49. package/dist/search/adapters/registry.d.ts +6 -0
  50. package/dist/search/adapters/registry.js +20 -0
  51. package/dist/search/adapters/registry.js.map +1 -0
  52. package/dist/search/adapters/types.d.ts +5 -0
  53. package/dist/search/adapters/types.js +2 -0
  54. package/dist/search/adapters/types.js.map +1 -0
  55. package/dist/search/debug/trace.d.ts +6 -0
  56. package/dist/search/debug/trace.js +25 -0
  57. package/dist/search/debug/trace.js.map +1 -0
  58. package/dist/search/expand/graphExpansion.d.ts +16 -0
  59. package/dist/search/expand/graphExpansion.js +168 -0
  60. package/dist/search/expand/graphExpansion.js.map +1 -0
  61. package/dist/search/fileKinds.d.ts +13 -0
  62. package/dist/search/fileKinds.js +74 -0
  63. package/dist/search/fileKinds.js.map +1 -0
  64. package/dist/search/index/configIndex.d.ts +6 -0
  65. package/dist/search/index/configIndex.js +196 -0
  66. package/dist/search/index/configIndex.js.map +1 -0
  67. package/dist/search/index/docIndex.d.ts +7 -0
  68. package/dist/search/index/docIndex.js +116 -0
  69. package/dist/search/index/docIndex.js.map +1 -0
  70. package/dist/search/index/workspaceIndex.d.ts +6 -0
  71. package/dist/search/index/workspaceIndex.js +50 -14
  72. package/dist/search/index/workspaceIndex.js.map +1 -1
  73. package/dist/search/query/compileEffectiveSearchSpec.d.ts +24 -0
  74. package/dist/search/query/compileEffectiveSearchSpec.js +67 -0
  75. package/dist/search/query/compileEffectiveSearchSpec.js.map +1 -0
  76. package/dist/search/query/parseQuery.d.ts +1 -0
  77. package/dist/search/query/parseQuery.js +40 -0
  78. package/dist/search/query/parseQuery.js.map +1 -1
  79. package/dist/search/query/phraseRules.d.ts +10 -0
  80. package/dist/search/query/phraseRules.js +58 -0
  81. package/dist/search/query/phraseRules.js.map +1 -0
  82. package/dist/search/query/planQuery.d.ts +4 -3
  83. package/dist/search/query/planQuery.js +39 -6
  84. package/dist/search/query/planQuery.js.map +1 -1
  85. package/dist/search/ranking/assessConfidence.js +6 -0
  86. package/dist/search/ranking/assessConfidence.js.map +1 -1
  87. package/dist/search/ranking/candidateIdentity.d.ts +21 -0
  88. package/dist/search/ranking/candidateIdentity.js +29 -0
  89. package/dist/search/ranking/candidateIdentity.js.map +1 -0
  90. package/dist/search/ranking/coalesceCandidates.d.ts +9 -0
  91. package/dist/search/ranking/coalesceCandidates.js +48 -0
  92. package/dist/search/ranking/coalesceCandidates.js.map +1 -0
  93. package/dist/search/ranking/fieldedTextRanker.d.ts +26 -0
  94. package/dist/search/ranking/fieldedTextRanker.js +79 -0
  95. package/dist/search/ranking/fieldedTextRanker.js.map +1 -0
  96. package/dist/search/ranking/mergeCandidates.d.ts +3 -0
  97. package/dist/search/ranking/mergeCandidates.js +39 -0
  98. package/dist/search/ranking/mergeCandidates.js.map +1 -1
  99. package/dist/search/ranking/rankCandidates.d.ts +1 -1
  100. package/dist/search/ranking/rankCandidates.js +51 -3
  101. package/dist/search/ranking/rankCandidates.js.map +1 -1
  102. package/dist/search/retrievers/behaviorRetriever.d.ts +3 -3
  103. package/dist/search/retrievers/behaviorRetriever.js +64 -69
  104. package/dist/search/retrievers/behaviorRetriever.js.map +1 -1
  105. package/dist/search/retrievers/configRetriever.d.ts +7 -0
  106. package/dist/search/retrievers/configRetriever.js +46 -0
  107. package/dist/search/retrievers/configRetriever.js.map +1 -0
  108. package/dist/search/retrievers/docRetriever.d.ts +7 -0
  109. package/dist/search/retrievers/docRetriever.js +46 -0
  110. package/dist/search/retrievers/docRetriever.js.map +1 -0
  111. package/dist/search/retrievers/identifierRetriever.d.ts +3 -3
  112. package/dist/search/retrievers/identifierRetriever.js +7 -6
  113. package/dist/search/retrievers/identifierRetriever.js.map +1 -1
  114. package/dist/search/retrievers/structuralRetriever.d.ts +4 -6
  115. package/dist/search/retrievers/structuralRetriever.js +47 -84
  116. package/dist/search/retrievers/structuralRetriever.js.map +1 -1
  117. package/dist/search/retrievers/textPatternRetriever.d.ts +7 -0
  118. package/dist/search/retrievers/textPatternRetriever.js +90 -0
  119. package/dist/search/retrievers/textPatternRetriever.js.map +1 -0
  120. package/dist/search/structural/locators/callLocator.d.ts +6 -0
  121. package/dist/search/structural/locators/callLocator.js +57 -0
  122. package/dist/search/structural/locators/callLocator.js.map +1 -0
  123. package/dist/search/structural/locators/declarationLocator.d.ts +6 -0
  124. package/dist/search/structural/locators/declarationLocator.js +57 -0
  125. package/dist/search/structural/locators/declarationLocator.js.map +1 -0
  126. package/dist/search/structural/locators/statementLocator.d.ts +6 -0
  127. package/dist/search/structural/locators/statementLocator.js +65 -0
  128. package/dist/search/structural/locators/statementLocator.js.map +1 -0
  129. package/dist/search/structural/locators/types.d.ts +12 -0
  130. package/dist/search/structural/locators/types.js +2 -0
  131. package/dist/search/structural/locators/types.js.map +1 -0
  132. package/dist/search/structural/selectLocators.d.ts +7 -0
  133. package/dist/search/structural/selectLocators.js +21 -0
  134. package/dist/search/structural/selectLocators.js.map +1 -0
  135. package/dist/search/types.d.ts +77 -7
  136. package/dist/search/types.js.map +1 -1
  137. package/dist/tools/composites/apiGuard.js +6 -28
  138. package/dist/tools/composites/apiGuard.js.map +1 -1
  139. package/dist/tools/composites/findCode.js +92 -15
  140. package/dist/tools/composites/findCode.js.map +1 -1
  141. package/dist/tools/composites/findPattern.js +1 -1
  142. package/dist/tools/composites/findPattern.js.map +1 -1
  143. package/dist/tools/live/clearIndex.d.ts +1 -0
  144. package/dist/tools/live/clearIndex.js +19 -0
  145. package/dist/tools/live/clearIndex.js.map +1 -0
  146. package/dist/tools/primitives/callHierarchy.js +1 -1
  147. package/dist/tools/primitives/callHierarchy.js.map +1 -1
  148. package/package.json +4 -2
package/README.md CHANGED
@@ -1,10 +1,10 @@
1
1
  # lsp-intelligence
2
2
 
3
- Type-aware code intelligence for AI agents — impact analysis, semantic diff, and context building via LSP.
3
+ Local code intelligence for real engineering workflows.
4
4
 
5
- **28 MCP tools** across 5 layers from basic navigation to "what breaks if I change this?" in one call.
5
+ **Find** implementations, API usage, structural patterns, configs, and routes. **Explain** why something broke. **Guard** the API contract before merging.
6
6
 
7
- Currently supports **TypeScript and JavaScript** projects. The architecture supports other LSP serversadditional language support is planned.
7
+ 29 MCP tools across 5 layers. Supports **TypeScript and JavaScript** (TS, TSX, JS, JSX, MJS, CJS). Local-onlyno paid API, no external calls.
8
8
 
9
9
  ## Why this exists
10
10
 
@@ -150,7 +150,7 @@ Combine LSP, AST, and Git substrates into high-level operations.
150
150
  |------|-------------|
151
151
  | `api_guard` | Detect public API contract changes — export diffs, structural classification, consumer impact, semver summary. |
152
152
  | `root_cause_trace` | Trace the root cause of a TypeScript error — find the originating declaration change, not just the symptom. |
153
- | `find_code` | Unified code search: behavior discovery, identifier/API usage search, and structural queries. Routes automatically based on the query. |
153
+ | `find_code` | Unified code search: behavior discovery, identifier/API usage, structural queries, config/route lookup, and implementation-root discovery. Routes automatically. |
154
154
  | `find_pattern` | AST structural search — find code by pattern (e.g. `useEffect($$$)`, `try { $$$ } catch ($E) { $$$ }`). |
155
155
  | `inspect_symbol` | Hover + definition + references in one call. Full context about any symbol. |
156
156
  | `batch_query` | Look up multiple symbols at once. Saves round-trips when exploring. |
@@ -178,6 +178,18 @@ Post-edit verification.
178
178
  | `find_unused_exports` | Find exported symbols with zero cross-package importers. |
179
179
  | `auto_import` | Resolve the correct import path for a symbol name. |
180
180
 
181
+ ## find_code query classes
182
+
183
+ `find_code` supports five query classes, routed automatically:
184
+
185
+ | Class | Example query | What happens |
186
+ |-------|--------------|-------------|
187
+ | **Identifier / API usage** | `useEffect`, `Promise.all` | Usage index → exact call/import sites with enclosing context |
188
+ | **Structural** | `useEffect that returns cleanup conditionally` | Identifier + structural predicates → AST evaluation on located nodes |
189
+ | **Behavior / entrypoint** | `where do we validate permissions` | Fielded BM25 over declarations + JSDoc/comments + family hints |
190
+ | **Config / route / flag** | `where is the feature flag configured` | Config index → JSON/YAML/package.json + env usage in code |
191
+ | **Implementation root** | `where is this actually implemented` | Graph expansion → wrapper detection → root promotion |
192
+
181
193
  ## Architecture
182
194
 
183
195
  ```
@@ -189,7 +201,7 @@ Post-edit verification.
189
201
  │ gather_context, outline │
190
202
  ├─────────────────────────────────────────────────────────┤
191
203
  │ Layer 2: Intelligence Tools [read-only] │
192
- api_guard, root_cause_trace, find_code, find_pattern, │
204
+ find_code, find_pattern, root_cause_trace, api_guard, │
193
205
  │ impact_trace, semantic_diff, inspect_symbol, │
194
206
  │ batch_query, find_test_files, explain_error │
195
207
  ├─────────────────────────────────────────────────────────┤
@@ -197,9 +209,13 @@ Post-edit verification.
197
209
  │ find_references, hover, definition, call_hierarchy, │
198
210
  │ rename, diagnostics, symbols, imports, exports │
199
211
  ├─────────────────────────────────────────────────────────┤
200
- │ Layer 0: LSP Engine [infrastructure] │
201
- │ TypeScript Server spawn, monorepo preopen,
202
- symbol resolver, document manager
212
+ │ Layer 0: Analysis Substrates [infrastructure] │
213
+ LSP Engine (TypeScript Server, symbol resolver)
214
+ TypeScript AST (declarations, usages, predicates)
215
+ │ Local text/regex search (recipe-compiled patterns) │
216
+ │ Config/doc indexes (JSON, YAML, env, JSDoc, comments) │
217
+ │ Graph expansion (wrapper detection, root promotion) │
218
+ │ Git integration (semantic diff, base comparison) │
203
219
  └─────────────────────────────────────────────────────────┘
204
220
  ```
205
221
 
@@ -225,7 +241,7 @@ Requires **Node.js 20+**.
225
241
 
226
242
  ### Option 1: Claude Code plugin (recommended)
227
243
 
228
- Installs the MCP server, hooks, and skills (`/impact`, `/context`, `/check`) as a single package.
244
+ Installs the MCP server, hooks, and skills (`/find`, `/why`, `/api-check`, `/verify`, `/check`, `/impact`, `/context`, `/diff`) as a single package.
229
245
 
230
246
  ```bash
231
247
  claude plugin add perilevy/lsp-intelligence
@@ -244,7 +260,7 @@ Add to your `.mcp.json`:
244
260
  "mcpServers": {
245
261
  "lsp": {
246
262
  "command": "npx",
247
- "args": ["--registry", "https://registry.npmjs.org", "-y", "lsp-intelligence"],
263
+ "args": ["-y", "lsp-intelligence"],
248
264
  "env": {
249
265
  "LSP_WORKSPACE_ROOT": "${CLAUDE_PROJECT_DIR}"
250
266
  }
@@ -285,18 +301,30 @@ Then in `.mcp.json`:
285
301
  git clone https://github.com/perilevy/lsp-intelligence.git
286
302
  cd lsp-intelligence
287
303
  yarn install
288
- yarn build # compile TypeScript dist/
304
+ yarn build # clean build (rm -rf dist && tsc)
289
305
  yarn test # vitest
290
306
  yarn typecheck # TypeScript strict mode — no emit
307
+ yarn bench # search quality benchmarks
291
308
  ```
292
309
 
293
310
  ### Testing
294
311
 
295
- Tests verify cross-package reference resolution, symbol-name lookup, type alias tracing, impact trace traversal, context building, and output formatting — all against a self-contained 3-package fixture monorepo at `test-fixtures/monorepo/`. No external dependencies needed.
312
+ Tests verify cross-package reference resolution, symbol-name lookup, type alias tracing, impact trace traversal, search quality, context building, and output formatting — all against self-contained fixture repos at `test-fixtures/`. No external dependencies needed.
313
+
314
+ ### Benchmarks
315
+
316
+ `benchmarks/` contains reproducible quality cases for `find_code`, `root_cause_trace`, and `api_guard`. Every serious real-world failure should become a benchmark case.
317
+
318
+ ## What this is not
319
+
320
+ - **Not a universal semantic search engine.** Strong on code structure, API usage, configs, and known patterns. Does not understand arbitrary business logic.
321
+ - **Not a replacement for full-text search.** Use grep for literal string matching. `find_code` uses text patterns internally but optimizes for code-aware ranking.
322
+ - **Not an AI model.** All intelligence is local: AST analysis, LSP queries, fielded text ranking, adapter recipes. No paid API calls, no external services.
323
+ - **Does not index secret-bearing `.env` files.** Env variable usage in code (`process.env.X`, `import.meta.env.X`) is indexed and searchable. Non-secret template/example files (`.env.example`, `.env.template`) are indexed. Real `.env` files are excluded by default.
296
324
 
297
325
  ## Dependencies
298
326
 
299
- All dependencies are installed automatically. Under the hood: [`typescript-language-server`](https://github.com/typescript-language-server/typescript-language-server) for LSP, [`@modelcontextprotocol/sdk`](https://github.com/modelcontextprotocol/typescript-sdk) for MCP, and supporting libraries from Microsoft. Uses your project's own TypeScript version.
327
+ All dependencies are installed automatically. Under the hood: [`typescript-language-server`](https://github.com/typescript-language-server/typescript-language-server) for LSP, [`@modelcontextprotocol/sdk`](https://github.com/modelcontextprotocol/typescript-sdk) for MCP, [`@ast-grep/napi`](https://github.com/ast-grep/ast-grep) for structural patterns. Uses your project's own TypeScript version.
300
328
 
301
329
  ## License
302
330
 
@@ -1,5 +1,6 @@
1
1
  import type { SearchScope } from '../../search/types.js';
2
2
  /**
3
- * Collect files matching a language within a search scope.
3
+ * Collect files matching a set of extensions within a search scope.
4
+ * Skips dot-prefixed dirs, build output, minified/bundled files, and oversized files.
4
5
  */
5
6
  export declare function collectSearchFiles(scope: SearchScope, extensions: string[], maxFiles: number): string[];
@@ -1,9 +1,9 @@
1
1
  import * as fs from 'fs';
2
2
  import * as path from 'path';
3
- import { SKIP_DIRS } from '../../engine/types.js';
4
- const TEST_PATTERN = /\.(spec|test|stories)\.(ts|tsx|js|jsx)$/;
3
+ import { isTestFile, shouldSkipDir, shouldSkipFile } from '../../search/fileKinds.js';
5
4
  /**
6
- * Collect files matching a language within a search scope.
5
+ * Collect files matching a set of extensions within a search scope.
6
+ * Skips dot-prefixed dirs, build output, minified/bundled files, and oversized files.
7
7
  */
8
8
  export function collectSearchFiles(scope, extensions, maxFiles) {
9
9
  const files = [];
@@ -19,15 +19,15 @@ function walkDir(dir, files, extensions, includeTests, maxFiles, depth) {
19
19
  return;
20
20
  try {
21
21
  for (const entry of fs.readdirSync(dir)) {
22
- if (SKIP_DIRS.has(entry))
22
+ if (shouldSkipDir(entry))
23
23
  continue;
24
24
  const full = path.join(dir, entry);
25
25
  const stat = fs.statSync(full);
26
26
  if (stat.isDirectory()) {
27
27
  walkDir(full, files, extensions, includeTests, maxFiles, depth + 1);
28
28
  }
29
- else if (extensions.some((e) => entry.endsWith(e)) && !entry.endsWith('.d.ts')) {
30
- if (!includeTests && TEST_PATTERN.test(entry))
29
+ else if (extensions.some((e) => entry.endsWith(e)) && !shouldSkipFile(full, stat.size)) {
30
+ if (!includeTests && isTestFile(full))
31
31
  continue;
32
32
  files.push(full);
33
33
  }
@@ -1 +1 @@
1
- {"version":3,"file":"collectSearchFiles.js","sourceRoot":"","sources":["../../../src/analysis/pattern/collectSearchFiles.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAE7B,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAElD,MAAM,YAAY,GAAG,yCAAyC,CAAC;AAE/D;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAChC,KAAkB,EAClB,UAAoB,EACpB,QAAgB;IAEhB,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAC/B,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,CAAC,YAAY,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC;QAClE,IAAI,KAAK,CAAC,MAAM,IAAI,QAAQ;YAAE,MAAM;IACtC,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,OAAO,CACd,GAAW,EACX,KAAe,EACf,UAAoB,EACpB,YAAqB,EACrB,QAAgB,EAChB,KAAa;IAEb,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,CAAC,MAAM,IAAI,QAAQ;QAAE,OAAO;IAClD,IAAI,CAAC;QACH,KAAK,MAAM,KAAK,IAAI,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC;YACxC,IAAI,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC;gBAAE,SAAS;YACnC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YACnC,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YAC/B,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;gBACvB,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,QAAQ,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;YACtE,CAAC;iBAAM,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;gBACjF,IAAI,CAAC,YAAY,IAAI,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC;oBAAE,SAAS;gBACxD,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACnB,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC,CAAA,CAAC;AACZ,CAAC"}
1
+ {"version":3,"file":"collectSearchFiles.js","sourceRoot":"","sources":["../../../src/analysis/pattern/collectSearchFiles.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAE7B,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAEtF;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAChC,KAAkB,EAClB,UAAoB,EACpB,QAAgB;IAEhB,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAC/B,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,CAAC,YAAY,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC;QAClE,IAAI,KAAK,CAAC,MAAM,IAAI,QAAQ;YAAE,MAAM;IACtC,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,OAAO,CACd,GAAW,EACX,KAAe,EACf,UAAoB,EACpB,YAAqB,EACrB,QAAgB,EAChB,KAAa;IAEb,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,CAAC,MAAM,IAAI,QAAQ;QAAE,OAAO;IAClD,IAAI,CAAC;QACH,KAAK,MAAM,KAAK,IAAI,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC;YACxC,IAAI,aAAa,CAAC,KAAK,CAAC;gBAAE,SAAS;YACnC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YACnC,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YAC/B,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;gBACvB,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,QAAQ,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;YACtE,CAAC;iBAAM,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBACzF,IAAI,CAAC,YAAY,IAAI,UAAU,CAAC,IAAI,CAAC;oBAAE,SAAS;gBAChD,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACnB,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC,CAAA,CAAC;AACZ,CAAC"}
@@ -5,7 +5,7 @@ import type { SearchScope, PatternMatch } from '../../search/types.js';
5
5
  */
6
6
  export declare function runPatternSearch(input: {
7
7
  pattern: string;
8
- language: 'typescript' | 'tsx' | 'javascript';
8
+ language: 'typescript' | 'tsx' | 'javascript' | 'jsx';
9
9
  scope: SearchScope;
10
10
  maxResults: number;
11
11
  contextLines: number;
@@ -6,11 +6,13 @@ const LANG_MAP = {
6
6
  typescript: Lang.TypeScript,
7
7
  tsx: Lang.Tsx,
8
8
  javascript: Lang.JavaScript,
9
+ jsx: Lang.Tsx, // ast-grep uses Tsx parser for JSX
9
10
  };
10
11
  const EXT_MAP = {
11
- typescript: ['.ts'],
12
+ typescript: ['.ts', '.mjs', '.cjs'],
12
13
  tsx: ['.tsx', '.ts'],
13
- javascript: ['.js'],
14
+ javascript: ['.js', '.mjs', '.cjs'],
15
+ jsx: ['.jsx', '.js'],
14
16
  };
15
17
  /**
16
18
  * Run an ast-grep pattern search across files in scope.
@@ -1 +1 @@
1
- {"version":3,"file":"runPatternSearch.js","sourceRoot":"","sources":["../../../src/analysis/pattern/runPatternSearch.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"runPatternSearch.js","sourceRoot":"","sources":["../../../src/analysis/pattern/runPatternSearch.ts"],"names":[],"mappings":"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"}
@@ -83,6 +83,25 @@ export function extractUsages(sf) {
83
83
  entries.push(makeUsage(tagName.text, tagName.text, 'jsx-tag', node, sf, filePath, pathToks, enclosingSymbol, enclosingKind));
84
84
  }
85
85
  }
86
+ // Env usage: process.env.X, import.meta.env.X
87
+ // Only match the exact env access (3 parts for process.env.X, 4 for import.meta.env.X)
88
+ // Skip if parent is also a PropertyAccessExpression (e.g. process.env.X.includes → skip, let process.env.X match)
89
+ if (ts.isPropertyAccessExpression(node) && !ts.isPropertyAccessExpression(node.parent)) {
90
+ const text = getPropertyAccessText(node);
91
+ const parts = text.split('.');
92
+ if (parts[0] === 'process' && parts[1] === 'env' && parts.length === 3) {
93
+ const envKey = parts[2];
94
+ const entry = makeUsage(`process.env.${envKey}`, envKey.toLowerCase(), 'env-usage', node, sf, filePath, pathToks, enclosingSymbol, enclosingKind);
95
+ entry.metadata = { envKey };
96
+ entries.push(entry);
97
+ }
98
+ else if (parts[0] === 'import' && parts[1] === 'meta' && parts[2] === 'env' && parts.length === 4) {
99
+ const envKey = parts[3];
100
+ const entry = makeUsage(`import.meta.env.${envKey}`, envKey.toLowerCase(), 'env-usage', node, sf, filePath, pathToks, enclosingSymbol, enclosingKind);
101
+ entry.metadata = { envKey };
102
+ entries.push(entry);
103
+ }
104
+ }
86
105
  ts.forEachChild(node, visit);
87
106
  // Restore enclosing context on unwind
88
107
  enclosingSymbol = prevSymbol;
@@ -1 +1 @@
1
- {"version":3,"file":"extractUsages.js","sourceRoot":"","sources":["../../../src/analysis/ts/extractUsages.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"extractUsages.js","sourceRoot":"","sources":["../../../src/analysis/ts/extractUsages.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  import ts from 'typescript';
2
2
  /**
3
- * Parse a TypeScript/TSX file into a ts.SourceFile using the TypeScript compiler API.
3
+ * Parse a TypeScript/JavaScript file into a ts.SourceFile using the TypeScript compiler API.
4
+ * Supports: .ts, .tsx, .js, .jsx, .mjs, .cjs
4
5
  * Returns null if the file doesn't exist or can't be parsed.
5
6
  */
6
7
  export declare function parseSourceFile(filePath: string): ts.SourceFile | null;
@@ -1,16 +1,15 @@
1
1
  import ts from 'typescript';
2
2
  import * as fs from 'fs';
3
+ import { scriptKindForFile } from '../../search/fileKinds.js';
3
4
  /**
4
- * Parse a TypeScript/TSX file into a ts.SourceFile using the TypeScript compiler API.
5
+ * Parse a TypeScript/JavaScript file into a ts.SourceFile using the TypeScript compiler API.
6
+ * Supports: .ts, .tsx, .js, .jsx, .mjs, .cjs
5
7
  * Returns null if the file doesn't exist or can't be parsed.
6
8
  */
7
9
  export function parseSourceFile(filePath) {
8
10
  try {
9
11
  const content = fs.readFileSync(filePath, 'utf-8');
10
- const scriptKind = filePath.endsWith('.tsx') ? ts.ScriptKind.TSX
11
- : filePath.endsWith('.jsx') ? ts.ScriptKind.JSX
12
- : ts.ScriptKind.TS;
13
- return ts.createSourceFile(filePath, content, ts.ScriptTarget.Latest, true, scriptKind);
12
+ return ts.createSourceFile(filePath, content, ts.ScriptTarget.Latest, true, scriptKindForFile(filePath));
14
13
  }
15
14
  catch {
16
15
  return null;
@@ -20,9 +19,6 @@ export function parseSourceFile(filePath) {
20
19
  * Parse source content directly (for base-version comparison).
21
20
  */
22
21
  export function parseSourceContent(content, fileName) {
23
- const scriptKind = fileName.endsWith('.tsx') ? ts.ScriptKind.TSX
24
- : fileName.endsWith('.jsx') ? ts.ScriptKind.JSX
25
- : ts.ScriptKind.TS;
26
- return ts.createSourceFile(fileName, content, ts.ScriptTarget.Latest, true, scriptKind);
22
+ return ts.createSourceFile(fileName, content, ts.ScriptTarget.Latest, true, scriptKindForFile(fileName));
27
23
  }
28
24
  //# sourceMappingURL=parseSourceFile.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"parseSourceFile.js","sourceRoot":"","sources":["../../../src/analysis/ts/parseSourceFile.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AAEzB;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,QAAgB;IAC9C,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACnD,MAAM,UAAU,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG;YAC9D,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG;gBAC/C,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC;QACrB,OAAO,EAAE,CAAC,gBAAgB,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,CAAC,YAAY,CAAC,MAAM,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC;IAC1F,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAAe,EAAE,QAAgB;IAClE,MAAM,UAAU,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG;QAC9D,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG;YAC/C,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC;IACrB,OAAO,EAAE,CAAC,gBAAgB,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,CAAC,YAAY,CAAC,MAAM,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC;AAC1F,CAAC"}
1
+ {"version":3,"file":"parseSourceFile.js","sourceRoot":"","sources":["../../../src/analysis/ts/parseSourceFile.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAE9D;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,QAAgB;IAC9C,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACnD,OAAO,EAAE,CAAC,gBAAgB,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,CAAC,YAAY,CAAC,MAAM,EAAE,IAAI,EAAE,iBAAiB,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC3G,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAAe,EAAE,QAAgB;IAClE,OAAO,EAAE,CAAC,gBAAgB,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,CAAC,YAAY,CAAC,MAAM,EAAE,IAAI,EAAE,iBAAiB,CAAC,QAAQ,CAAC,CAAC,CAAC;AAC3G,CAAC"}
@@ -0,0 +1,9 @@
1
+ import ts from 'typescript';
2
+ /**
3
+ * Detect if a node contains a functional state updater pattern.
4
+ * Matches: setState(prev => ...), setCount(current => current + 1), etc.
5
+ *
6
+ * Only matches when the updater parameter is actually used in the body.
7
+ * Does NOT match: setState(() => 1) — that's a constant updater.
8
+ */
9
+ export declare function hasFunctionalStateUpdater(node: ts.Node): boolean;
@@ -0,0 +1,57 @@
1
+ import ts from 'typescript';
2
+ /**
3
+ * Detect if a node contains a functional state updater pattern.
4
+ * Matches: setState(prev => ...), setCount(current => current + 1), etc.
5
+ *
6
+ * Only matches when the updater parameter is actually used in the body.
7
+ * Does NOT match: setState(() => 1) — that's a constant updater.
8
+ */
9
+ export function hasFunctionalStateUpdater(node) {
10
+ let found = false;
11
+ function walk(n) {
12
+ if (found)
13
+ return;
14
+ // Look for calls like setFoo(param => ...)
15
+ if (ts.isCallExpression(n) && ts.isIdentifier(n.expression)) {
16
+ const callee = n.expression.text;
17
+ // Must start with "set" and have PascalCase after (setState, setCount, setItems)
18
+ if (/^set[A-Z]/.test(callee) && n.arguments.length >= 1) {
19
+ const arg = n.arguments[0];
20
+ if (ts.isArrowFunction(arg) || ts.isFunctionExpression(arg)) {
21
+ // Must have exactly one parameter
22
+ if (arg.parameters.length === 1) {
23
+ const paramName = arg.parameters[0].name;
24
+ if (ts.isIdentifier(paramName)) {
25
+ // Check if the parameter is actually used in the body
26
+ if (isIdentifierUsedInBody(paramName.text, arg.body)) {
27
+ found = true;
28
+ return;
29
+ }
30
+ }
31
+ }
32
+ }
33
+ }
34
+ }
35
+ ts.forEachChild(n, walk);
36
+ }
37
+ walk(node);
38
+ return found;
39
+ }
40
+ function isIdentifierUsedInBody(name, body) {
41
+ let used = false;
42
+ function walk(n) {
43
+ if (used)
44
+ return;
45
+ if (ts.isIdentifier(n) && n.text === name) {
46
+ // Make sure it's not the parameter declaration itself
47
+ if (!ts.isParameter(n.parent)) {
48
+ used = true;
49
+ return;
50
+ }
51
+ }
52
+ ts.forEachChild(n, walk);
53
+ }
54
+ walk(body);
55
+ return used;
56
+ }
57
+ //# sourceMappingURL=reactState.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reactState.js","sourceRoot":"","sources":["../../../src/analysis/ts/reactState.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B;;;;;;GAMG;AACH,MAAM,UAAU,yBAAyB,CAAC,IAAa;IACrD,IAAI,KAAK,GAAG,KAAK,CAAC;IAElB,SAAS,IAAI,CAAC,CAAU;QACtB,IAAI,KAAK;YAAE,OAAO;QAElB,2CAA2C;QAC3C,IAAI,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE,CAAC;YAC5D,MAAM,MAAM,GAAG,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC;YACjC,iFAAiF;YACjF,IAAI,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;gBACxD,MAAM,GAAG,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;gBAC3B,IAAI,EAAE,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,oBAAoB,CAAC,GAAG,CAAC,EAAE,CAAC;oBAC5D,kCAAkC;oBAClC,IAAI,GAAG,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;wBAChC,MAAM,SAAS,GAAG,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;wBACzC,IAAI,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,EAAE,CAAC;4BAC/B,sDAAsD;4BACtD,IAAI,sBAAsB,CAAC,SAAS,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;gCACrD,KAAK,GAAG,IAAI,CAAC;gCACb,OAAO;4BACT,CAAC;wBACH,CAAC;oBACH,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAED,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IAC3B,CAAC;IAED,IAAI,CAAC,IAAI,CAAC,CAAC;IACX,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,sBAAsB,CAAC,IAAY,EAAE,IAAa;IACzD,IAAI,IAAI,GAAG,KAAK,CAAC;IACjB,SAAS,IAAI,CAAC,CAAU;QACtB,IAAI,IAAI;YAAE,OAAO;QACjB,IAAI,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;YAC1C,sDAAsD;YACtD,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC9B,IAAI,GAAG,IAAI,CAAC;gBACZ,OAAO;YACT,CAAC;QACH,CAAC;QACD,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IAC3B,CAAC;IACD,IAAI,CAAC,IAAI,CAAC,CAAC;IACX,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import ts from 'typescript';
2
+ import { hasFunctionalStateUpdater } from './reactState.js';
2
3
  /**
3
4
  * Evaluate structural predicates on a TS AST node.
4
5
  * Returns which predicates matched and evidence strings.
@@ -37,6 +38,8 @@ function evaluatePredicate(sf, node, pred) {
37
38
  return isInsideHookCall(node) ? 'inside a React hook call' : null;
38
39
  case 'hook-callback':
39
40
  return isHookCallback(node) ? 'is a callback argument to a hook' : null;
41
+ case 'functional-state-updater':
42
+ return hasFunctionalStateUpdater(node) ? 'contains functional state updater (e.g. setState(prev => ...))' : null;
40
43
  default:
41
44
  return null;
42
45
  }
@@ -83,6 +86,8 @@ function isCallbackLike(node) {
83
86
  return getFirstCallbackArg(node) !== null;
84
87
  }
85
88
  function containsTryCatch(node) {
89
+ if (ts.isTryStatement(node))
90
+ return true;
86
91
  let found = false;
87
92
  function walk(n) {
88
93
  if (found)
@@ -97,6 +102,10 @@ function containsTryCatch(node) {
97
102
  return found;
98
103
  }
99
104
  function hasSwitchWithoutDefault(node) {
105
+ // Check node itself first (statementLocator passes the SwitchStatement directly)
106
+ if (ts.isSwitchStatement(node)) {
107
+ return !node.caseBlock.clauses.some((c) => ts.isDefaultClause(c));
108
+ }
100
109
  let found = false;
101
110
  function walk(n) {
102
111
  if (found)
@@ -114,19 +123,39 @@ function hasSwitchWithoutDefault(node) {
114
123
  return found;
115
124
  }
116
125
  function hasAwaitInLoop(node) {
126
+ const isLoop = (n) => ts.isForStatement(n) || ts.isForOfStatement(n) || ts.isForInStatement(n) || ts.isWhileStatement(n) || ts.isDoStatement(n);
127
+ // If node itself is a loop, check its body for await
128
+ if (isLoop(node)) {
129
+ let found = false;
130
+ function walkBody(n) {
131
+ if (found)
132
+ return;
133
+ if (ts.isAwaitExpression(n)) {
134
+ found = true;
135
+ return;
136
+ }
137
+ if (ts.isFunctionDeclaration(n) || ts.isArrowFunction(n) || ts.isFunctionExpression(n))
138
+ return;
139
+ ts.forEachChild(n, walkBody);
140
+ }
141
+ ts.forEachChild(node, walkBody);
142
+ return found;
143
+ }
144
+ // Otherwise search descendants for loop-with-await
117
145
  let insideLoop = false;
118
146
  let found = false;
119
147
  function walk(n) {
120
148
  if (found)
121
149
  return;
122
150
  const wasInsideLoop = insideLoop;
123
- if (ts.isForStatement(n) || ts.isForOfStatement(n) || ts.isForInStatement(n) || ts.isWhileStatement(n) || ts.isDoStatement(n)) {
151
+ if (isLoop(n))
124
152
  insideLoop = true;
125
- }
126
153
  if (insideLoop && ts.isAwaitExpression(n)) {
127
154
  found = true;
128
155
  return;
129
156
  }
157
+ if (ts.isFunctionDeclaration(n) || ts.isArrowFunction(n) || ts.isFunctionExpression(n))
158
+ return;
130
159
  ts.forEachChild(n, walk);
131
160
  insideLoop = wasInsideLoop;
132
161
  }
@@ -1 +1 @@
1
- {"version":3,"file":"structuralPredicates.js","sourceRoot":"","sources":["../../../src/analysis/ts/structuralPredicates.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAG5B;;;GAGG;AACH,MAAM,UAAU,4BAA4B,CAC1C,EAAiB,EACjB,IAAa,EACb,UAAiC;IAEjC,MAAM,OAAO,GAA0B,EAAE,CAAC;IAC1C,MAAM,QAAQ,GAAa,EAAE,CAAC;IAE9B,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;QAC9B,MAAM,MAAM,GAAG,iBAAiB,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;QACjD,IAAI,MAAM,EAAE,CAAC;YACX,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACnB,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACxB,CAAC;IACH,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC;AAC/B,CAAC;AAED,SAAS,iBAAiB,CAAC,EAAiB,EAAE,IAAa,EAAE,IAAyB;IACpF,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,aAAa;YAChB,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,6BAA6B,CAAC,CAAC,CAAC,IAAI,CAAC;QAErE,KAAK,kBAAkB;YACrB,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,+BAA+B,CAAC,CAAC,CAAC,IAAI,CAAC;QAExE,KAAK,iBAAiB;YACpB,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,qCAAqC,CAAC,CAAC,CAAC,IAAI,CAAC;QAE7E,KAAK,YAAY;YACf,OAAO,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,kCAAkC,CAAC,CAAC,CAAC,IAAI,CAAC;QAEnG,KAAK,eAAe;YAClB,OAAO,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAAC,CAAC,IAAI,CAAC;QAEpE,KAAK,cAAc;YACjB,OAAO,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,IAAI,CAAC;QAElE,KAAK,mBAAmB;YACtB,OAAO,uBAAuB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,uCAAuC,CAAC,CAAC,CAAC,IAAI,CAAC;QAExF,KAAK,eAAe;YAClB,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC,IAAI,CAAC;QAEhE,KAAK,aAAa;YAChB,OAAO,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAAC,CAAC,IAAI,CAAC;QAEpE,KAAK,eAAe;YAClB,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,kCAAkC,CAAC,CAAC,CAAC,IAAI,CAAC;QAE1E;YACE,OAAO,IAAI,CAAC;IAChB,CAAC;AACH,CAAC;AAED,oCAAoC;AAEpC,SAAS,cAAc,CAAC,IAAa;IACnC,IAAI,KAAK,GAAG,KAAK,CAAC;IAClB,SAAS,IAAI,CAAC,CAAU;QACtB,IAAI,KAAK;YAAE,OAAO;QAClB,IAAI,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,uBAAuB,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC,EAAE,CAAC;YACpF,KAAK,GAAG,IAAI,CAAC;YACb,OAAO;QACT,CAAC;QACD,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IAC3B,CAAC;IACD,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC5B,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,eAAe,CAAC,IAAa;IACpC,IAAI,KAAK,GAAG,KAAK,CAAC;IAClB,SAAS,IAAI,CAAC,CAAU;QACtB,IAAI,KAAK;YAAE,OAAO;QAClB,IAAI,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,CAAC;YAC5C,IAAI,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,oBAAoB,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE,CAAC;gBAC9E,KAAK,GAAG,IAAI,CAAC;gBACb,OAAO;YACT,CAAC;QACH,CAAC;QACD,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IAC3B,CAAC;IACD,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC5B,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,cAAc,CAAC,IAAa;IACnC,oEAAoE;IACpE,MAAM,QAAQ,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;IAC3C,IAAI,CAAC,QAAQ;QAAE,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC;IAC5C,OAAO,eAAe,CAAC,QAAQ,CAAC,CAAC;AACnC,CAAC;AAED,SAAS,cAAc,CAAC,IAAa;IACnC,OAAO,mBAAmB,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC;AAC5C,CAAC;AAED,SAAS,gBAAgB,CAAC,IAAa;IACrC,IAAI,KAAK,GAAG,KAAK,CAAC;IAClB,SAAS,IAAI,CAAC,CAAU;QACtB,IAAI,KAAK;YAAE,OAAO;QAClB,IAAI,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,CAAC;YAAC,KAAK,GAAG,IAAI,CAAC;YAAC,OAAO;QAAC,CAAC;QACnD,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IAC3B,CAAC;IACD,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC5B,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,uBAAuB,CAAC,IAAa;IAC5C,IAAI,KAAK,GAAG,KAAK,CAAC;IAClB,SAAS,IAAI,CAAC,CAAU;QACtB,IAAI,KAAK;YAAE,OAAO;QAClB,IAAI,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC,EAAE,CAAC;YAC5B,MAAM,UAAU,GAAG,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC;YAC1E,IAAI,CAAC,UAAU,EAAE,CAAC;gBAAC,KAAK,GAAG,IAAI,CAAC;gBAAC,OAAO;YAAC,CAAC;QAC5C,CAAC;QACD,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IAC3B,CAAC;IACD,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC5B,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,cAAc,CAAC,IAAa;IACnC,IAAI,UAAU,GAAG,KAAK,CAAC;IACvB,IAAI,KAAK,GAAG,KAAK,CAAC;IAClB,SAAS,IAAI,CAAC,CAAU;QACtB,IAAI,KAAK;YAAE,OAAO;QAClB,MAAM,aAAa,GAAG,UAAU,CAAC;QACjC,IAAI,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC;YAC9H,UAAU,GAAG,IAAI,CAAC;QACpB,CAAC;QACD,IAAI,UAAU,IAAI,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC,EAAE,CAAC;YAAC,KAAK,GAAG,IAAI,CAAC;YAAC,OAAO;QAAC,CAAC;QACpE,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;QACzB,UAAU,GAAG,aAAa,CAAC;IAC7B,CAAC;IACD,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC5B,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,gBAAgB,CAAC,IAAa;IACrC,IAAI,OAAO,GAAwB,IAAI,CAAC;IACxC,OAAO,OAAO,EAAE,CAAC;QACf,IAAI,EAAE,CAAC,gBAAgB,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,YAAY,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;YACxE,IAAI,UAAU,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC;gBAAE,OAAO,IAAI,CAAC;QACvD,CAAC;QACD,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC;IAC3B,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,cAAc,CAAC,IAAa;IACnC,qEAAqE;IACrE,IAAI,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;QAClE,OAAO,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IAC1C,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,UAAU,CAAC,IAAY;IAC9B,OAAO,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAChC,CAAC;AAED;;;GAGG;AACH,SAAS,mBAAmB,CAAC,IAAa;IACxC,IAAI,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3D,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;QAChC,IAAI,EAAE,CAAC,eAAe,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,oBAAoB,CAAC,KAAK,CAAC,EAAE,CAAC;YAChE,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
1
+ {"version":3,"file":"structuralPredicates.js","sourceRoot":"","sources":["../../../src/analysis/ts/structuralPredicates.ts"],"names":[],"mappings":"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"}
@@ -1,10 +1,11 @@
1
1
  import { type SgNode } from '@ast-grep/napi';
2
2
  /**
3
- * Parse a TypeScript/TSX file into an ast-grep root node.
4
- * Returns null if parsing fails.
3
+ * Parse a source file into an ast-grep root node.
4
+ * Supports TS, TSX, JS, JSX, MJS, CJS.
5
5
  */
6
6
  export declare function parseFile(filePath: string): SgNode | null;
7
7
  /**
8
8
  * Parse source content directly.
9
+ * Pass the file path or extension to determine the correct language.
9
10
  */
10
- export declare function parseSource(content: string, isTsx?: boolean): SgNode | null;
11
+ export declare function parseSource(content: string, filePathOrTsx?: string | boolean): SgNode | null;
@@ -1,13 +1,22 @@
1
1
  import * as fs from 'fs';
2
2
  import { parse, Lang } from '@ast-grep/napi';
3
+ const LANG_MAP = {
4
+ '.ts': Lang.TypeScript,
5
+ '.tsx': Lang.Tsx,
6
+ '.js': Lang.JavaScript,
7
+ '.jsx': Lang.Tsx, // ast-grep uses Tsx for JSX
8
+ '.mjs': Lang.JavaScript,
9
+ '.cjs': Lang.JavaScript,
10
+ };
3
11
  /**
4
- * Parse a TypeScript/TSX file into an ast-grep root node.
5
- * Returns null if parsing fails.
12
+ * Parse a source file into an ast-grep root node.
13
+ * Supports TS, TSX, JS, JSX, MJS, CJS.
6
14
  */
7
15
  export function parseFile(filePath) {
8
16
  try {
9
17
  const content = fs.readFileSync(filePath, 'utf-8');
10
- const lang = filePath.endsWith('.tsx') ? Lang.Tsx : Lang.TypeScript;
18
+ const ext = filePath.match(/\.[^.]+$/)?.[0] ?? '.ts';
19
+ const lang = LANG_MAP[ext] ?? Lang.TypeScript;
11
20
  return parse(lang, content).root();
12
21
  }
13
22
  catch {
@@ -16,10 +25,18 @@ export function parseFile(filePath) {
16
25
  }
17
26
  /**
18
27
  * Parse source content directly.
28
+ * Pass the file path or extension to determine the correct language.
19
29
  */
20
- export function parseSource(content, isTsx = false) {
30
+ export function parseSource(content, filePathOrTsx = false) {
21
31
  try {
22
- const lang = isTsx ? Lang.Tsx : Lang.TypeScript;
32
+ let lang;
33
+ if (typeof filePathOrTsx === 'string') {
34
+ const ext = filePathOrTsx.match(/\.[^.]+$/)?.[0] ?? '.ts';
35
+ lang = LANG_MAP[ext] ?? Lang.TypeScript;
36
+ }
37
+ else {
38
+ lang = filePathOrTsx ? Lang.Tsx : Lang.TypeScript;
39
+ }
23
40
  return parse(lang, content).root();
24
41
  }
25
42
  catch {
@@ -1 +1 @@
1
- {"version":3,"file":"parseFile.js","sourceRoot":"","sources":["../../src/ast/parseFile.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,EAAE,KAAK,EAAE,IAAI,EAAe,MAAM,gBAAgB,CAAC;AAE1D;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,QAAgB;IACxC,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACnD,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC;QACpE,OAAO,KAAK,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,OAAe,EAAE,KAAK,GAAG,KAAK;IACxD,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC;QAChD,OAAO,KAAK,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"parseFile.js","sourceRoot":"","sources":["../../src/ast/parseFile.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,EAAE,KAAK,EAAE,IAAI,EAAe,MAAM,gBAAgB,CAAC;AAE1D,MAAM,QAAQ,GAAyB;IACrC,KAAK,EAAE,IAAI,CAAC,UAAU;IACtB,MAAM,EAAE,IAAI,CAAC,GAAG;IAChB,KAAK,EAAE,IAAI,CAAC,UAAU;IACtB,MAAM,EAAE,IAAI,CAAC,GAAG,EAAE,4BAA4B;IAC9C,MAAM,EAAE,IAAI,CAAC,UAAU;IACvB,MAAM,EAAE,IAAI,CAAC,UAAU;CACxB,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,QAAgB;IACxC,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACnD,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC;QACrD,MAAM,IAAI,GAAG,QAAQ,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC;QAC9C,OAAO,KAAK,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,OAAe,EAAE,gBAAkC,KAAK;IAClF,IAAI,CAAC;QACH,IAAI,IAAU,CAAC;QACf,IAAI,OAAO,aAAa,KAAK,QAAQ,EAAE,CAAC;YACtC,MAAM,GAAG,GAAG,aAAa,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC;YAC1D,IAAI,GAAG,QAAQ,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC;QAC1C,CAAC;aAAM,CAAC;YACN,IAAI,GAAG,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC;QACpD,CAAC;QACD,OAAO,KAAK,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
@@ -331,9 +331,31 @@ export class LspEngine {
331
331
  this.connection.sendNotification('exit');
332
332
  }
333
333
  catch { }
334
+ }
335
+ // Wait for the process to exit gracefully after receiving 'exit' notification.
336
+ // If it doesn't exit within 3s, force-kill.
337
+ if (this.process) {
338
+ await new Promise((resolve) => {
339
+ const timeout = setTimeout(() => {
340
+ this.process?.kill();
341
+ resolve();
342
+ }, 3000);
343
+ this.process.on('exit', () => {
344
+ clearTimeout(timeout);
345
+ resolve();
346
+ });
347
+ // If process already exited, resolve immediately
348
+ if (this.process.exitCode !== null) {
349
+ clearTimeout(timeout);
350
+ resolve();
351
+ }
352
+ });
353
+ }
354
+ // Dispose connection after process is gone — no more writes possible
355
+ if (this.connection) {
334
356
  this.connection.dispose();
357
+ this.connection = null;
335
358
  }
336
- this.process?.kill();
337
359
  }
338
360
  }
339
361
  //# sourceMappingURL=LspEngine.js.map