lsp-intelligence 0.1.2 → 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 (208) hide show
  1. package/README.md +48 -15
  2. package/dist/analysis/pattern/collectSearchFiles.d.ts +6 -0
  3. package/dist/analysis/pattern/collectSearchFiles.js +38 -0
  4. package/dist/analysis/pattern/collectSearchFiles.js.map +1 -0
  5. package/dist/analysis/pattern/runPatternSearch.d.ts +17 -0
  6. package/dist/analysis/pattern/runPatternSearch.js +65 -0
  7. package/dist/analysis/pattern/runPatternSearch.js.map +1 -0
  8. package/dist/analysis/ts/extractDeclarations.d.ts +7 -0
  9. package/dist/analysis/ts/extractDeclarations.js +93 -0
  10. package/dist/analysis/ts/extractDeclarations.js.map +1 -0
  11. package/dist/analysis/ts/extractUsages.d.ts +7 -0
  12. package/dist/analysis/ts/extractUsages.js +139 -0
  13. package/dist/analysis/ts/extractUsages.js.map +1 -0
  14. package/dist/analysis/ts/parseSourceFile.d.ts +11 -0
  15. package/dist/analysis/ts/parseSourceFile.js +24 -0
  16. package/dist/analysis/ts/parseSourceFile.js.map +1 -0
  17. package/dist/analysis/ts/reactState.d.ts +9 -0
  18. package/dist/analysis/ts/reactState.js +57 -0
  19. package/dist/analysis/ts/reactState.js.map +1 -0
  20. package/dist/analysis/ts/snippets.d.ts +14 -0
  21. package/dist/analysis/ts/snippets.js +29 -0
  22. package/dist/analysis/ts/snippets.js.map +1 -0
  23. package/dist/analysis/ts/structuralPredicates.d.ts +10 -0
  24. package/dist/analysis/ts/structuralPredicates.js +199 -0
  25. package/dist/analysis/ts/structuralPredicates.js.map +1 -0
  26. package/dist/ast/diffDeclarationShapes.d.ts +16 -0
  27. package/dist/ast/diffDeclarationShapes.js +179 -0
  28. package/dist/ast/diffDeclarationShapes.js.map +1 -0
  29. package/dist/ast/extractExportDeclarations.d.ts +21 -0
  30. package/dist/ast/extractExportDeclarations.js +218 -0
  31. package/dist/ast/extractExportDeclarations.js.map +1 -0
  32. package/dist/ast/findNodeAtPosition.d.ts +12 -0
  33. package/dist/ast/findNodeAtPosition.js +75 -0
  34. package/dist/ast/findNodeAtPosition.js.map +1 -0
  35. package/dist/ast/parseFile.d.ts +11 -0
  36. package/dist/ast/parseFile.js +46 -0
  37. package/dist/ast/parseFile.js.map +1 -0
  38. package/dist/engine/LspEngine.js +23 -1
  39. package/dist/engine/LspEngine.js.map +1 -1
  40. package/dist/engine/waitForDiagnostics.d.ts +7 -0
  41. package/dist/engine/waitForDiagnostics.js +16 -0
  42. package/dist/engine/waitForDiagnostics.js.map +1 -0
  43. package/dist/git/getBaseFileContent.d.ts +6 -0
  44. package/dist/git/getBaseFileContent.js +23 -0
  45. package/dist/git/getBaseFileContent.js.map +1 -0
  46. package/dist/git/getChangedFiles.d.ts +5 -0
  47. package/dist/git/getChangedFiles.js +27 -0
  48. package/dist/git/getChangedFiles.js.map +1 -0
  49. package/dist/git/getChangedHunks.d.ts +14 -0
  50. package/dist/git/getChangedHunks.js +56 -0
  51. package/dist/git/getChangedHunks.js.map +1 -0
  52. package/dist/git/getGitRoot.d.ts +15 -0
  53. package/dist/git/getGitRoot.js +33 -0
  54. package/dist/git/getGitRoot.js.map +1 -0
  55. package/dist/git/getMergeBase.d.ts +5 -0
  56. package/dist/git/getMergeBase.js +23 -0
  57. package/dist/git/getMergeBase.js.map +1 -0
  58. package/dist/index.js +10 -0
  59. package/dist/index.js.map +1 -1
  60. package/dist/resolve/searchScope.d.ts +17 -0
  61. package/dist/resolve/searchScope.js +64 -0
  62. package/dist/resolve/searchScope.js.map +1 -0
  63. package/dist/resolve/targetResolver.d.ts +33 -0
  64. package/dist/resolve/targetResolver.js +84 -0
  65. package/dist/resolve/targetResolver.js.map +1 -0
  66. package/dist/search/adapters/config.d.ts +5 -0
  67. package/dist/search/adapters/config.js +56 -0
  68. package/dist/search/adapters/config.js.map +1 -0
  69. package/dist/search/adapters/http.d.ts +6 -0
  70. package/dist/search/adapters/http.js +58 -0
  71. package/dist/search/adapters/http.js.map +1 -0
  72. package/dist/search/adapters/react.d.ts +12 -0
  73. package/dist/search/adapters/react.js +92 -0
  74. package/dist/search/adapters/react.js.map +1 -0
  75. package/dist/search/adapters/registry.d.ts +6 -0
  76. package/dist/search/adapters/registry.js +20 -0
  77. package/dist/search/adapters/registry.js.map +1 -0
  78. package/dist/search/adapters/types.d.ts +5 -0
  79. package/dist/search/adapters/types.js +2 -0
  80. package/dist/search/adapters/types.js.map +1 -0
  81. package/dist/search/debug/trace.d.ts +6 -0
  82. package/dist/search/debug/trace.js +25 -0
  83. package/dist/search/debug/trace.js.map +1 -0
  84. package/dist/search/expand/graphExpansion.d.ts +16 -0
  85. package/dist/search/expand/graphExpansion.js +168 -0
  86. package/dist/search/expand/graphExpansion.js.map +1 -0
  87. package/dist/search/families/behaviorFamilies.d.ts +22 -0
  88. package/dist/search/families/behaviorFamilies.js +90 -0
  89. package/dist/search/families/behaviorFamilies.js.map +1 -0
  90. package/dist/search/fileKinds.d.ts +13 -0
  91. package/dist/search/fileKinds.js +74 -0
  92. package/dist/search/fileKinds.js.map +1 -0
  93. package/dist/search/index/configIndex.d.ts +6 -0
  94. package/dist/search/index/configIndex.js +196 -0
  95. package/dist/search/index/configIndex.js.map +1 -0
  96. package/dist/search/index/declarationIndex.d.ts +6 -0
  97. package/dist/search/index/declarationIndex.js +13 -0
  98. package/dist/search/index/declarationIndex.js.map +1 -0
  99. package/dist/search/index/docIndex.d.ts +7 -0
  100. package/dist/search/index/docIndex.js +116 -0
  101. package/dist/search/index/docIndex.js.map +1 -0
  102. package/dist/search/index/types.d.ts +1 -0
  103. package/dist/search/index/types.js +2 -0
  104. package/dist/search/index/types.js.map +1 -0
  105. package/dist/search/index/usageIndex.d.ts +6 -0
  106. package/dist/search/index/usageIndex.js +13 -0
  107. package/dist/search/index/usageIndex.js.map +1 -0
  108. package/dist/search/index/workspaceIndex.d.ts +14 -0
  109. package/dist/search/index/workspaceIndex.js +127 -0
  110. package/dist/search/index/workspaceIndex.js.map +1 -0
  111. package/dist/search/query/compileEffectiveSearchSpec.d.ts +24 -0
  112. package/dist/search/query/compileEffectiveSearchSpec.js +67 -0
  113. package/dist/search/query/compileEffectiveSearchSpec.js.map +1 -0
  114. package/dist/search/query/parseQuery.d.ts +10 -0
  115. package/dist/search/query/parseQuery.js +284 -0
  116. package/dist/search/query/parseQuery.js.map +1 -0
  117. package/dist/search/query/phraseRules.d.ts +10 -0
  118. package/dist/search/query/phraseRules.js +58 -0
  119. package/dist/search/query/phraseRules.js.map +1 -0
  120. package/dist/search/query/planQuery.d.ts +10 -0
  121. package/dist/search/query/planQuery.js +91 -0
  122. package/dist/search/query/planQuery.js.map +1 -0
  123. package/dist/search/ranking/assessConfidence.d.ts +6 -0
  124. package/dist/search/ranking/assessConfidence.js +31 -0
  125. package/dist/search/ranking/assessConfidence.js.map +1 -0
  126. package/dist/search/ranking/candidateIdentity.d.ts +21 -0
  127. package/dist/search/ranking/candidateIdentity.js +29 -0
  128. package/dist/search/ranking/candidateIdentity.js.map +1 -0
  129. package/dist/search/ranking/coalesceCandidates.d.ts +9 -0
  130. package/dist/search/ranking/coalesceCandidates.js +48 -0
  131. package/dist/search/ranking/coalesceCandidates.js.map +1 -0
  132. package/dist/search/ranking/fieldedTextRanker.d.ts +26 -0
  133. package/dist/search/ranking/fieldedTextRanker.js +79 -0
  134. package/dist/search/ranking/fieldedTextRanker.js.map +1 -0
  135. package/dist/search/ranking/mergeCandidates.d.ts +13 -0
  136. package/dist/search/ranking/mergeCandidates.js +85 -0
  137. package/dist/search/ranking/mergeCandidates.js.map +1 -0
  138. package/dist/search/ranking/rankCandidates.d.ts +12 -0
  139. package/dist/search/ranking/rankCandidates.js +106 -0
  140. package/dist/search/ranking/rankCandidates.js.map +1 -0
  141. package/dist/search/retrievers/behaviorRetriever.d.ts +7 -0
  142. package/dist/search/retrievers/behaviorRetriever.js +86 -0
  143. package/dist/search/retrievers/behaviorRetriever.js.map +1 -0
  144. package/dist/search/retrievers/configRetriever.d.ts +7 -0
  145. package/dist/search/retrievers/configRetriever.js +46 -0
  146. package/dist/search/retrievers/configRetriever.js.map +1 -0
  147. package/dist/search/retrievers/docRetriever.d.ts +7 -0
  148. package/dist/search/retrievers/docRetriever.js +46 -0
  149. package/dist/search/retrievers/docRetriever.js.map +1 -0
  150. package/dist/search/retrievers/identifierRetriever.d.ts +7 -0
  151. package/dist/search/retrievers/identifierRetriever.js +67 -0
  152. package/dist/search/retrievers/identifierRetriever.js.map +1 -0
  153. package/dist/search/retrievers/structuralRetriever.d.ts +9 -0
  154. package/dist/search/retrievers/structuralRetriever.js +104 -0
  155. package/dist/search/retrievers/structuralRetriever.js.map +1 -0
  156. package/dist/search/retrievers/textPatternRetriever.d.ts +7 -0
  157. package/dist/search/retrievers/textPatternRetriever.js +90 -0
  158. package/dist/search/retrievers/textPatternRetriever.js.map +1 -0
  159. package/dist/search/structural/locators/callLocator.d.ts +6 -0
  160. package/dist/search/structural/locators/callLocator.js +57 -0
  161. package/dist/search/structural/locators/callLocator.js.map +1 -0
  162. package/dist/search/structural/locators/declarationLocator.d.ts +6 -0
  163. package/dist/search/structural/locators/declarationLocator.js +57 -0
  164. package/dist/search/structural/locators/declarationLocator.js.map +1 -0
  165. package/dist/search/structural/locators/statementLocator.d.ts +6 -0
  166. package/dist/search/structural/locators/statementLocator.js +65 -0
  167. package/dist/search/structural/locators/statementLocator.js.map +1 -0
  168. package/dist/search/structural/locators/types.d.ts +12 -0
  169. package/dist/search/structural/locators/types.js +2 -0
  170. package/dist/search/structural/locators/types.js.map +1 -0
  171. package/dist/search/structural/selectLocators.d.ts +7 -0
  172. package/dist/search/structural/selectLocators.js +21 -0
  173. package/dist/search/structural/selectLocators.js.map +1 -0
  174. package/dist/search/types.d.ts +191 -0
  175. package/dist/search/types.js +11 -0
  176. package/dist/search/types.js.map +1 -0
  177. package/dist/tools/composites/apiGuard.d.ts +1 -0
  178. package/dist/tools/composites/apiGuard.js +172 -0
  179. package/dist/tools/composites/apiGuard.js.map +1 -0
  180. package/dist/tools/composites/explainError.js +3 -2
  181. package/dist/tools/composites/explainError.js.map +1 -1
  182. package/dist/tools/composites/findCode.d.ts +1 -0
  183. package/dist/tools/composites/findCode.js +145 -0
  184. package/dist/tools/composites/findCode.js.map +1 -0
  185. package/dist/tools/composites/findPattern.d.ts +5 -0
  186. package/dist/tools/composites/findPattern.js +41 -0
  187. package/dist/tools/composites/findPattern.js.map +1 -0
  188. package/dist/tools/composites/rootCauseTrace.d.ts +1 -0
  189. package/dist/tools/composites/rootCauseTrace.js +213 -0
  190. package/dist/tools/composites/rootCauseTrace.js.map +1 -0
  191. package/dist/tools/composites/semanticDiff.js +24 -77
  192. package/dist/tools/composites/semanticDiff.js.map +1 -1
  193. package/dist/tools/live/clearIndex.d.ts +1 -0
  194. package/dist/tools/live/clearIndex.js +19 -0
  195. package/dist/tools/live/clearIndex.js.map +1 -0
  196. package/dist/tools/live/liveDiagnostics.js +3 -2
  197. package/dist/tools/live/liveDiagnostics.js.map +1 -1
  198. package/dist/tools/primitives/callHierarchy.js +1 -1
  199. package/dist/tools/primitives/callHierarchy.js.map +1 -1
  200. package/dist/tools/primitives/diagnostics.js +2 -2
  201. package/dist/tools/primitives/diagnostics.js.map +1 -1
  202. package/dist/tools/registry.d.ts +10 -2
  203. package/dist/tools/registry.js +7 -2
  204. package/dist/tools/registry.js.map +1 -1
  205. package/package.json +11 -5
  206. package/dist/tools/primitives/typeHierarchy.d.ts +0 -1
  207. package/dist/tools/primitives/typeHierarchy.js +0 -55
  208. package/dist/tools/primitives/typeHierarchy.js.map +0 -1
@@ -0,0 +1,196 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ import { shouldSkipDir, isSecretEnvFile, isSafeEnvTemplateFile } from '../fileKinds.js';
4
+ // Config file extensions to index. Does NOT include .env (handled separately).
5
+ const CONFIG_EXTENSIONS = ['.json', '.yaml', '.yml', '.toml'];
6
+ const CONFIG_FILENAMES = [
7
+ 'package.json', 'tsconfig.json', 'next.config.js', 'next.config.ts',
8
+ 'vite.config.ts', 'vite.config.js', 'jest.config.ts', 'jest.config.js',
9
+ 'vitest.config.ts',
10
+ // Safe env templates (no secrets)
11
+ '.env.example', '.env.template', '.env.sample',
12
+ ];
13
+ const ROUTE_KEYS = new Set(['routes', 'route', 'api', 'endpoint', 'endpoints', 'path', 'paths', 'handler', 'handlers', 'url', 'urls']);
14
+ const FLAG_KEYS = new Set(['features', 'feature', 'flags', 'flag', 'toggles', 'toggle', 'experiments', 'gates']);
15
+ /**
16
+ * Index configuration files in the workspace.
17
+ * Extracts key-value entries from JSON, YAML-like, and env files.
18
+ */
19
+ export function indexConfigFiles(scope) {
20
+ const entries = [];
21
+ const maxFiles = 200;
22
+ const files = [];
23
+ for (const root of scope.roots) {
24
+ collectConfigFiles(root, files, maxFiles, 0);
25
+ }
26
+ for (const filePath of files) {
27
+ try {
28
+ const ext = path.extname(filePath);
29
+ const basename = path.basename(filePath);
30
+ if (basename === 'package.json') {
31
+ entries.push(...indexPackageJson(filePath));
32
+ }
33
+ else if (ext === '.json') {
34
+ entries.push(...indexJsonFile(filePath));
35
+ }
36
+ else if (basename.startsWith('.env')) {
37
+ entries.push(...indexEnvFile(filePath));
38
+ }
39
+ else if (ext === '.yaml' || ext === '.yml') {
40
+ entries.push(...indexYamlLikeFile(filePath));
41
+ }
42
+ }
43
+ catch {
44
+ // Skip files that can't be read/parsed
45
+ }
46
+ }
47
+ return entries;
48
+ }
49
+ function collectConfigFiles(dir, files, maxFiles, depth) {
50
+ if (depth > 4 || files.length >= maxFiles)
51
+ return;
52
+ try {
53
+ for (const entry of fs.readdirSync(dir)) {
54
+ const full = path.join(dir, entry);
55
+ const stat = fs.statSync(full);
56
+ if (stat.isDirectory()) {
57
+ if (shouldSkipDir(entry))
58
+ continue;
59
+ collectConfigFiles(full, files, maxFiles, depth + 1);
60
+ }
61
+ else if (CONFIG_FILENAMES.includes(entry) ||
62
+ CONFIG_EXTENSIONS.some((e) => entry.endsWith(e)) ||
63
+ isSafeEnvTemplateFile(full)) {
64
+ // Exclude secret-bearing .env files
65
+ if (isSecretEnvFile(full))
66
+ continue;
67
+ files.push(full);
68
+ }
69
+ }
70
+ }
71
+ catch { }
72
+ }
73
+ function indexPackageJson(filePath) {
74
+ const content = JSON.parse(fs.readFileSync(filePath, 'utf-8'));
75
+ const entries = [];
76
+ // Scripts
77
+ if (content.scripts) {
78
+ for (const [key, value] of Object.entries(content.scripts)) {
79
+ entries.push({
80
+ filePath, line: 1, kind: 'package',
81
+ keyPath: ['scripts', key],
82
+ text: `${key}: ${value}`,
83
+ tokens: tokenize(`${key} ${value}`),
84
+ });
85
+ }
86
+ }
87
+ // Dependencies
88
+ for (const depKey of ['dependencies', 'devDependencies', 'peerDependencies']) {
89
+ if (content[depKey]) {
90
+ for (const pkg of Object.keys(content[depKey])) {
91
+ entries.push({
92
+ filePath, line: 1, kind: 'package',
93
+ keyPath: [depKey, pkg],
94
+ text: `${depKey}: ${pkg}`,
95
+ tokens: tokenize(pkg),
96
+ });
97
+ }
98
+ }
99
+ }
100
+ return entries;
101
+ }
102
+ function indexJsonFile(filePath) {
103
+ const content = fs.readFileSync(filePath, 'utf-8');
104
+ const entries = [];
105
+ try {
106
+ const obj = JSON.parse(content);
107
+ flattenJson(obj, [], filePath, entries, 0);
108
+ }
109
+ catch { }
110
+ return entries;
111
+ }
112
+ function flattenJson(obj, keyPath, filePath, entries, depth) {
113
+ if (depth > 4 || entries.length > 100)
114
+ return;
115
+ if (typeof obj !== 'object' || obj === null)
116
+ return;
117
+ for (const [key, value] of Object.entries(obj)) {
118
+ const path = [...keyPath, key];
119
+ if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
120
+ // Classify by key path
121
+ const kind = classifyConfigKind(path);
122
+ entries.push({
123
+ filePath, line: 1, kind,
124
+ keyPath: path,
125
+ text: `${path.join('.')}: ${value}`,
126
+ tokens: tokenize(`${key} ${value}`),
127
+ });
128
+ }
129
+ else if (typeof value === 'object' && value !== null) {
130
+ flattenJson(value, path, filePath, entries, depth + 1);
131
+ }
132
+ }
133
+ }
134
+ function indexEnvFile(filePath) {
135
+ const content = fs.readFileSync(filePath, 'utf-8');
136
+ const entries = [];
137
+ for (const [i, rawLine] of content.split('\n').entries()) {
138
+ const line = rawLine.trim();
139
+ if (!line || line.startsWith('#'))
140
+ continue;
141
+ const eqIdx = line.indexOf('=');
142
+ if (eqIdx < 1)
143
+ continue;
144
+ const key = line.substring(0, eqIdx).trim();
145
+ const value = line.substring(eqIdx + 1).trim();
146
+ entries.push({
147
+ filePath, line: i + 1, kind: 'env',
148
+ keyPath: [key],
149
+ text: `${key}=${value}`,
150
+ tokens: tokenize(`${key} ${value}`),
151
+ });
152
+ }
153
+ return entries;
154
+ }
155
+ function indexYamlLikeFile(filePath) {
156
+ // Simple line-based YAML indexing — not a full parser
157
+ const content = fs.readFileSync(filePath, 'utf-8');
158
+ const entries = [];
159
+ for (const [i, rawLine] of content.split('\n').entries()) {
160
+ const line = rawLine.trim();
161
+ if (!line || line.startsWith('#'))
162
+ continue;
163
+ const colonIdx = line.indexOf(':');
164
+ if (colonIdx < 1)
165
+ continue;
166
+ const key = line.substring(0, colonIdx).trim();
167
+ const value = line.substring(colonIdx + 1).trim();
168
+ if (value) {
169
+ entries.push({
170
+ filePath, line: i + 1, kind: 'config',
171
+ keyPath: [key],
172
+ text: `${key}: ${value}`,
173
+ tokens: tokenize(`${key} ${value}`),
174
+ });
175
+ }
176
+ }
177
+ return entries;
178
+ }
179
+ function classifyConfigKind(keyPath) {
180
+ for (const k of keyPath) {
181
+ const lower = k.toLowerCase();
182
+ if (ROUTE_KEYS.has(lower))
183
+ return 'route';
184
+ if (FLAG_KEYS.has(lower))
185
+ return 'config';
186
+ }
187
+ return 'config';
188
+ }
189
+ function tokenize(text) {
190
+ return text
191
+ .toLowerCase()
192
+ .replace(/[^a-z0-9\s-_]/g, ' ')
193
+ .split(/[\s-_]+/)
194
+ .filter((t) => t.length > 1);
195
+ }
196
+ //# sourceMappingURL=configIndex.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configIndex.js","sourceRoot":"","sources":["../../../src/search/index/configIndex.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { DeclarationIndexEntry } from '../types.js';
2
+ /**
3
+ * Build declaration index entries for a single file.
4
+ * Uses TypeScript compiler AST, not regex.
5
+ */
6
+ export declare function indexFileDeclarations(filePath: string): DeclarationIndexEntry[];
@@ -0,0 +1,13 @@
1
+ import { parseSourceFile } from '../../analysis/ts/parseSourceFile.js';
2
+ import { extractDeclarations } from '../../analysis/ts/extractDeclarations.js';
3
+ /**
4
+ * Build declaration index entries for a single file.
5
+ * Uses TypeScript compiler AST, not regex.
6
+ */
7
+ export function indexFileDeclarations(filePath) {
8
+ const sf = parseSourceFile(filePath);
9
+ if (!sf)
10
+ return [];
11
+ return extractDeclarations(sf);
12
+ }
13
+ //# sourceMappingURL=declarationIndex.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"declarationIndex.js","sourceRoot":"","sources":["../../../src/search/index/declarationIndex.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AACvE,OAAO,EAAE,mBAAmB,EAAE,MAAM,0CAA0C,CAAC;AAG/E;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CAAC,QAAgB;IACpD,MAAM,EAAE,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;IACrC,IAAI,CAAC,EAAE;QAAE,OAAO,EAAE,CAAC;IACnB,OAAO,mBAAmB,CAAC,EAAE,CAAC,CAAC;AACjC,CAAC"}
@@ -0,0 +1,7 @@
1
+ import ts from 'typescript';
2
+ import type { DocIndexEntry } from '../types.js';
3
+ /**
4
+ * Extract doc/narrative entries from a TypeScript source file.
5
+ * Indexes: JSDoc on exported declarations, leading comments, describe/it/test titles.
6
+ */
7
+ export declare function indexFileDocs(sf: ts.SourceFile): DocIndexEntry[];
@@ -0,0 +1,116 @@
1
+ import ts from 'typescript';
2
+ /**
3
+ * Extract doc/narrative entries from a TypeScript source file.
4
+ * Indexes: JSDoc on exported declarations, leading comments, describe/it/test titles.
5
+ */
6
+ export function indexFileDocs(sf) {
7
+ const entries = [];
8
+ const filePath = sf.fileName;
9
+ function visit(node) {
10
+ // JSDoc on exported declarations
11
+ if (isExportedDeclaration(node)) {
12
+ const name = getDeclarationName(node);
13
+ const jsdoc = getJSDocText(node, sf);
14
+ if (jsdoc) {
15
+ const line = sf.getLineAndCharacterOfPosition(node.getStart(sf)).line + 1;
16
+ entries.push({
17
+ filePath,
18
+ line,
19
+ kind: 'jsdoc',
20
+ text: jsdoc,
21
+ tokens: tokenize(jsdoc),
22
+ attachedSymbol: name,
23
+ });
24
+ }
25
+ // Leading comment (non-JSDoc) above exported declarations
26
+ const leadingComment = getLeadingComment(node, sf);
27
+ if (leadingComment && leadingComment !== jsdoc) {
28
+ const line = sf.getLineAndCharacterOfPosition(node.getStart(sf)).line + 1;
29
+ entries.push({
30
+ filePath,
31
+ line,
32
+ kind: 'comment',
33
+ text: leadingComment,
34
+ tokens: tokenize(leadingComment),
35
+ attachedSymbol: name,
36
+ });
37
+ }
38
+ }
39
+ // Test titles: describe('...'), it('...'), test('...')
40
+ if (ts.isCallExpression(node) && ts.isIdentifier(node.expression)) {
41
+ const callee = node.expression.text;
42
+ if ((callee === 'describe' || callee === 'it' || callee === 'test') && node.arguments.length > 0) {
43
+ const firstArg = node.arguments[0];
44
+ if (ts.isStringLiteral(firstArg) || ts.isNoSubstitutionTemplateLiteral(firstArg)) {
45
+ const line = sf.getLineAndCharacterOfPosition(node.getStart(sf)).line + 1;
46
+ entries.push({
47
+ filePath,
48
+ line,
49
+ kind: 'test-title',
50
+ text: firstArg.text,
51
+ tokens: tokenize(firstArg.text),
52
+ });
53
+ }
54
+ }
55
+ }
56
+ ts.forEachChild(node, visit);
57
+ }
58
+ visit(sf);
59
+ return entries;
60
+ }
61
+ function isExportedDeclaration(node) {
62
+ const mods = ts.canHaveModifiers(node) ? ts.getModifiers(node) : undefined;
63
+ if (!mods)
64
+ return false;
65
+ return mods.some((m) => m.kind === ts.SyntaxKind.ExportKeyword);
66
+ }
67
+ function getDeclarationName(node) {
68
+ if (ts.isFunctionDeclaration(node) && node.name)
69
+ return node.name.text;
70
+ if (ts.isClassDeclaration(node) && node.name)
71
+ return node.name.text;
72
+ if (ts.isVariableStatement(node)) {
73
+ for (const decl of node.declarationList.declarations) {
74
+ if (ts.isIdentifier(decl.name))
75
+ return decl.name.text;
76
+ }
77
+ }
78
+ if (ts.isInterfaceDeclaration(node))
79
+ return node.name.text;
80
+ if (ts.isTypeAliasDeclaration(node))
81
+ return node.name.text;
82
+ if (ts.isEnumDeclaration(node))
83
+ return node.name.text;
84
+ return undefined;
85
+ }
86
+ function getJSDocText(node, sf) {
87
+ const jsdocs = node.jsDoc;
88
+ if (!jsdocs || jsdocs.length === 0)
89
+ return undefined;
90
+ const comment = jsdocs[0].comment;
91
+ if (typeof comment === 'string')
92
+ return comment;
93
+ if (Array.isArray(comment))
94
+ return comment.map((c) => c.text ?? '').join('');
95
+ return undefined;
96
+ }
97
+ function getLeadingComment(node, sf) {
98
+ const fullText = sf.getFullText();
99
+ const ranges = ts.getLeadingCommentRanges(fullText, node.getFullStart());
100
+ if (!ranges || ranges.length === 0)
101
+ return undefined;
102
+ // Take last comment before the node
103
+ const range = ranges[ranges.length - 1];
104
+ let text = fullText.substring(range.pos, range.end);
105
+ // Strip comment markers
106
+ text = text.replace(/^\/\*\*?\s*|\s*\*\/$/g, '').replace(/^\s*\/\/\s*/gm, '').replace(/^\s*\*\s?/gm, '').trim();
107
+ return text || undefined;
108
+ }
109
+ function tokenize(text) {
110
+ return text
111
+ .toLowerCase()
112
+ .replace(/[^a-z0-9\s]/g, ' ')
113
+ .split(/\s+/)
114
+ .filter((t) => t.length > 2);
115
+ }
116
+ //# sourceMappingURL=docIndex.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"docIndex.js","sourceRoot":"","sources":["../../../src/search/index/docIndex.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export type { DeclarationIndexEntry, UsageIndexEntry, IndexedFile, WorkspaceIndex, } from '../types.js';
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/search/index/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,6 @@
1
+ import type { UsageIndexEntry } from '../types.js';
2
+ /**
3
+ * Build usage index entries for a single file.
4
+ * Indexes call expressions, member calls, imports, JSX tags using TS compiler AST.
5
+ */
6
+ export declare function indexFileUsages(filePath: string): UsageIndexEntry[];
@@ -0,0 +1,13 @@
1
+ import { parseSourceFile } from '../../analysis/ts/parseSourceFile.js';
2
+ import { extractUsages } from '../../analysis/ts/extractUsages.js';
3
+ /**
4
+ * Build usage index entries for a single file.
5
+ * Indexes call expressions, member calls, imports, JSX tags using TS compiler AST.
6
+ */
7
+ export function indexFileUsages(filePath) {
8
+ const sf = parseSourceFile(filePath);
9
+ if (!sf)
10
+ return [];
11
+ return extractUsages(sf);
12
+ }
13
+ //# sourceMappingURL=usageIndex.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usageIndex.js","sourceRoot":"","sources":["../../../src/search/index/usageIndex.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AACvE,OAAO,EAAE,aAAa,EAAE,MAAM,oCAAoC,CAAC;AAGnE;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,QAAgB;IAC9C,MAAM,EAAE,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;IACrC,IAAI,CAAC,EAAE;QAAE,OAAO,EAAE,CAAC;IACnB,OAAO,aAAa,CAAC,EAAE,CAAC,CAAC;AAC3B,CAAC"}
@@ -0,0 +1,14 @@
1
+ import type { SearchScope, WorkspaceIndex } from '../types.js';
2
+ /** Force-clear the in-memory workspace index. Next query will rebuild from scratch. */
3
+ export declare function clearWorkspaceIndex(): {
4
+ cleared: boolean;
5
+ hadEntries: number;
6
+ };
7
+ /**
8
+ * Get or build a workspace index for the given scope.
9
+ * Uses per-file mtime to invalidate stale entries — no TTL.
10
+ * Cache keys by normalized scope (sorted roots + includeTests) + INDEX_VERSION.
11
+ */
12
+ export declare function getWorkspaceIndex(scope: SearchScope, opts?: {
13
+ forceRefresh?: boolean;
14
+ }): WorkspaceIndex;
@@ -0,0 +1,127 @@
1
+ import * as fs from 'fs';
2
+ import { collectScopeFiles, collectScopeFilesWithMeta } from '../../resolve/searchScope.js';
3
+ import { indexFileDeclarations } from './declarationIndex.js';
4
+ import { indexFileUsages } from './usageIndex.js';
5
+ import { indexFileDocs } from './docIndex.js';
6
+ import { indexConfigFiles } from './configIndex.js';
7
+ import { parseSourceFile } from '../../analysis/ts/parseSourceFile.js';
8
+ // Bump this when discovery/exclusion rules change to invalidate stale caches.
9
+ const INDEX_VERSION = 2;
10
+ let cachedEntry = null;
11
+ function scopeCacheKey(scope) {
12
+ return JSON.stringify({
13
+ roots: [...scope.roots].sort(),
14
+ includeTests: scope.includeTests,
15
+ });
16
+ }
17
+ /** Force-clear the in-memory workspace index. Next query will rebuild from scratch. */
18
+ export function clearWorkspaceIndex() {
19
+ const hadEntries = cachedEntry?.index.files.size ?? 0;
20
+ cachedEntry = null;
21
+ return { cleared: true, hadEntries };
22
+ }
23
+ /**
24
+ * Get or build a workspace index for the given scope.
25
+ * Uses per-file mtime to invalidate stale entries — no TTL.
26
+ * Cache keys by normalized scope (sorted roots + includeTests) + INDEX_VERSION.
27
+ */
28
+ export function getWorkspaceIndex(scope, opts) {
29
+ const key = scopeCacheKey(scope);
30
+ // Full refresh if scope changed, forced, or index version changed
31
+ if (!cachedEntry || cachedEntry.scopeKey !== key || cachedEntry.version !== INDEX_VERSION || opts?.forceRefresh) {
32
+ const index = buildFreshIndex(scope);
33
+ cachedEntry = { index, version: INDEX_VERSION, scopeKey: key };
34
+ return index;
35
+ }
36
+ const cachedIndex = cachedEntry.index;
37
+ // Incremental: check mtime per file, re-index changed files
38
+ const scopeFiles = collectScopeFiles(scope);
39
+ let changed = false;
40
+ for (const filePath of scopeFiles) {
41
+ try {
42
+ const mtime = fs.statSync(filePath).mtimeMs;
43
+ const existing = cachedIndex.files.get(filePath);
44
+ if (!existing || existing.mtimeMs !== mtime) {
45
+ // File is new or changed — re-index
46
+ const declarations = indexFileDeclarations(filePath);
47
+ const usages = indexFileUsages(filePath);
48
+ const docs = indexFileDocsForFile(filePath);
49
+ cachedIndex.files.set(filePath, { filePath, mtimeMs: mtime, declarations, usages, docs });
50
+ changed = true;
51
+ }
52
+ }
53
+ catch {
54
+ // File may have been deleted
55
+ if (cachedIndex.files.has(filePath)) {
56
+ cachedIndex.files.delete(filePath);
57
+ changed = true;
58
+ }
59
+ }
60
+ }
61
+ // Remove files no longer in scope
62
+ const scopeSet = new Set(scopeFiles);
63
+ for (const key of cachedIndex.files.keys()) {
64
+ if (!scopeSet.has(key)) {
65
+ cachedIndex.files.delete(key);
66
+ changed = true;
67
+ }
68
+ }
69
+ // Rebuild flat arrays if anything changed
70
+ if (changed) {
71
+ rebuildFlatArrays(cachedIndex, scope);
72
+ }
73
+ return cachedIndex;
74
+ }
75
+ function buildFreshIndex(scope) {
76
+ const root = scope.roots[0] ?? '';
77
+ const files = new Map();
78
+ const scopeMeta = collectScopeFilesWithMeta(scope);
79
+ const scopeFiles = scopeMeta.files;
80
+ for (const filePath of scopeFiles) {
81
+ try {
82
+ const mtime = fs.statSync(filePath).mtimeMs;
83
+ const declarations = indexFileDeclarations(filePath);
84
+ const usages = indexFileUsages(filePath);
85
+ const docs = indexFileDocsForFile(filePath);
86
+ files.set(filePath, { filePath, mtimeMs: mtime, declarations, usages, docs });
87
+ }
88
+ catch {
89
+ // Skip files that can't be read/parsed
90
+ }
91
+ }
92
+ const index = {
93
+ root,
94
+ builtAt: Date.now(),
95
+ files,
96
+ declarations: [],
97
+ usages: [],
98
+ docs: [],
99
+ configs: [],
100
+ scopeCapped: scopeMeta.capped,
101
+ capReason: scopeMeta.capReason,
102
+ };
103
+ rebuildFlatArrays(index, scope);
104
+ return index;
105
+ }
106
+ function rebuildFlatArrays(index, scope) {
107
+ const declarations = [];
108
+ const usages = [];
109
+ const docs = [];
110
+ for (const file of index.files.values()) {
111
+ declarations.push(...file.declarations);
112
+ usages.push(...file.usages);
113
+ docs.push(...file.docs);
114
+ }
115
+ index.declarations = declarations;
116
+ index.usages = usages;
117
+ index.docs = docs;
118
+ index.configs = indexConfigFiles(scope);
119
+ index.builtAt = Date.now();
120
+ }
121
+ function indexFileDocsForFile(filePath) {
122
+ const sf = parseSourceFile(filePath);
123
+ if (!sf)
124
+ return [];
125
+ return indexFileDocs(sf);
126
+ }
127
+ //# sourceMappingURL=workspaceIndex.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspaceIndex.js","sourceRoot":"","sources":["../../../src/search/index/workspaceIndex.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import type { QueryIR, SearchPlan, StructuralPredicate, RegExpSpec, QueryTraits } from '../types.js';
2
+ /**
3
+ * Effective search spec — the single merged execution contract.
4
+ * All retrievers consume this instead of raw IR.
5
+ * Merges parser-derived signals with adapter recipe intent.
6
+ */
7
+ export interface EffectiveSearchSpec {
8
+ exactIdentifiers: string[];
9
+ dottedIdentifiers: string[];
10
+ behaviorTerms: string[];
11
+ structuralPredicates: StructuralPredicate[];
12
+ regexes: RegExpSpec[];
13
+ routeTerms: string[];
14
+ configTerms: string[];
15
+ implementationRoot: boolean;
16
+ traits: QueryTraits;
17
+ /** Recipe IDs that contributed to this spec — for debug/evidence */
18
+ recipeIds: string[];
19
+ }
20
+ /**
21
+ * Compile an effective search spec by merging parser-derived signals with recipe intent.
22
+ * This is the ONLY place where parser output + recipe output are unified.
23
+ */
24
+ export declare function compileEffectiveSearchSpec(ir: QueryIR, plan: SearchPlan): EffectiveSearchSpec;
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Compile an effective search spec by merging parser-derived signals with recipe intent.
3
+ * This is the ONLY place where parser output + recipe output are unified.
4
+ */
5
+ export function compileEffectiveSearchSpec(ir, plan) {
6
+ const exactIdentifiers = [...ir.exactIdentifiers];
7
+ const dottedIdentifiers = [...ir.dottedIdentifiers];
8
+ const structuralPredicates = [...ir.structuralPredicates];
9
+ const regexes = [];
10
+ const behaviorTerms = [...ir.nlTokens, ...ir.codeTokens];
11
+ const routeTerms = [];
12
+ const configTerms = [];
13
+ const recipeIds = [];
14
+ // Extract route/config terms from NL tokens
15
+ const ROUTE_WORDS = new Set(['route', 'endpoint', 'url', 'path', 'api', 'handler']);
16
+ const CONFIG_WORDS = new Set(['config', 'env', 'flag', 'toggle', 'setting', 'variable', 'secret', 'feature']);
17
+ for (const tok of ir.nlTokens) {
18
+ if (ROUTE_WORDS.has(tok))
19
+ routeTerms.push(tok);
20
+ if (CONFIG_WORDS.has(tok))
21
+ configTerms.push(tok);
22
+ }
23
+ // Merge recipe contributions
24
+ for (const recipe of ir.recipes) {
25
+ recipeIds.push(recipe.id);
26
+ if (recipe.exactIdentifiers) {
27
+ for (const id of recipe.exactIdentifiers) {
28
+ if (!exactIdentifiers.includes(id))
29
+ exactIdentifiers.push(id);
30
+ }
31
+ }
32
+ if (recipe.structuralPredicates) {
33
+ for (const pred of recipe.structuralPredicates) {
34
+ if (!structuralPredicates.includes(pred))
35
+ structuralPredicates.push(pred);
36
+ }
37
+ }
38
+ if (recipe.regexes) {
39
+ for (const r of recipe.regexes) {
40
+ if (!regexes.some((existing) => existing.id === r.id))
41
+ regexes.push(r);
42
+ }
43
+ }
44
+ // Recipes from config/http adapters contribute route/config terms
45
+ if (recipe.adapter === 'config' || recipe.adapter === 'http') {
46
+ for (const reason of recipe.reasons) {
47
+ if (reason.includes('route') || reason.includes('endpoint'))
48
+ routeTerms.push('route');
49
+ if (reason.includes('flag') || reason.includes('env') || reason.includes('config'))
50
+ configTerms.push('config');
51
+ }
52
+ }
53
+ }
54
+ return {
55
+ exactIdentifiers,
56
+ dottedIdentifiers,
57
+ behaviorTerms,
58
+ structuralPredicates,
59
+ regexes,
60
+ routeTerms: [...new Set(routeTerms)],
61
+ configTerms: [...new Set(configTerms)],
62
+ implementationRoot: ir.traits.implementationRoot || plan.expandGraph,
63
+ traits: ir.traits,
64
+ recipeIds,
65
+ };
66
+ }
67
+ //# sourceMappingURL=compileEffectiveSearchSpec.js.map