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
@@ -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,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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"}
@@ -1,7 +1,13 @@
1
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
+ };
2
7
  /**
3
8
  * Get or build a workspace index for the given scope.
4
9
  * Uses per-file mtime to invalidate stale entries — no TTL.
10
+ * Cache keys by normalized scope (sorted roots + includeTests) + INDEX_VERSION.
5
11
  */
6
12
  export declare function getWorkspaceIndex(scope: SearchScope, opts?: {
7
13
  forceRefresh?: boolean;
@@ -1,20 +1,39 @@
1
1
  import * as fs from 'fs';
2
- import { collectScopeFiles } from '../../resolve/searchScope.js';
2
+ import { collectScopeFiles, collectScopeFilesWithMeta } from '../../resolve/searchScope.js';
3
3
  import { indexFileDeclarations } from './declarationIndex.js';
4
4
  import { indexFileUsages } from './usageIndex.js';
5
- // Per-workspace cache with per-file mtime invalidation
6
- let cachedIndex = null;
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
+ }
7
23
  /**
8
24
  * Get or build a workspace index for the given scope.
9
25
  * Uses per-file mtime to invalidate stale entries — no TTL.
26
+ * Cache keys by normalized scope (sorted roots + includeTests) + INDEX_VERSION.
10
27
  */
11
28
  export function getWorkspaceIndex(scope, opts) {
12
- const root = scope.roots[0] ?? '';
13
- // Full refresh if root changed or forced
14
- if (!cachedIndex || cachedIndex.root !== root || opts?.forceRefresh) {
15
- cachedIndex = buildFreshIndex(scope);
16
- return cachedIndex;
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;
17
35
  }
36
+ const cachedIndex = cachedEntry.index;
18
37
  // Incremental: check mtime per file, re-index changed files
19
38
  const scopeFiles = collectScopeFiles(scope);
20
39
  let changed = false;
@@ -26,7 +45,8 @@ export function getWorkspaceIndex(scope, opts) {
26
45
  // File is new or changed — re-index
27
46
  const declarations = indexFileDeclarations(filePath);
28
47
  const usages = indexFileUsages(filePath);
29
- cachedIndex.files.set(filePath, { filePath, mtimeMs: mtime, declarations, usages });
48
+ const docs = indexFileDocsForFile(filePath);
49
+ cachedIndex.files.set(filePath, { filePath, mtimeMs: mtime, declarations, usages, docs });
30
50
  changed = true;
31
51
  }
32
52
  }
@@ -48,20 +68,22 @@ export function getWorkspaceIndex(scope, opts) {
48
68
  }
49
69
  // Rebuild flat arrays if anything changed
50
70
  if (changed) {
51
- rebuildFlatArrays(cachedIndex);
71
+ rebuildFlatArrays(cachedIndex, scope);
52
72
  }
53
73
  return cachedIndex;
54
74
  }
55
75
  function buildFreshIndex(scope) {
56
76
  const root = scope.roots[0] ?? '';
57
77
  const files = new Map();
58
- const scopeFiles = collectScopeFiles(scope);
78
+ const scopeMeta = collectScopeFilesWithMeta(scope);
79
+ const scopeFiles = scopeMeta.files;
59
80
  for (const filePath of scopeFiles) {
60
81
  try {
61
82
  const mtime = fs.statSync(filePath).mtimeMs;
62
83
  const declarations = indexFileDeclarations(filePath);
63
84
  const usages = indexFileUsages(filePath);
64
- files.set(filePath, { filePath, mtimeMs: mtime, declarations, usages });
85
+ const docs = indexFileDocsForFile(filePath);
86
+ files.set(filePath, { filePath, mtimeMs: mtime, declarations, usages, docs });
65
87
  }
66
88
  catch {
67
89
  // Skip files that can't be read/parsed
@@ -73,19 +95,33 @@ function buildFreshIndex(scope) {
73
95
  files,
74
96
  declarations: [],
75
97
  usages: [],
98
+ docs: [],
99
+ configs: [],
100
+ scopeCapped: scopeMeta.capped,
101
+ capReason: scopeMeta.capReason,
76
102
  };
77
- rebuildFlatArrays(index);
103
+ rebuildFlatArrays(index, scope);
78
104
  return index;
79
105
  }
80
- function rebuildFlatArrays(index) {
106
+ function rebuildFlatArrays(index, scope) {
81
107
  const declarations = [];
82
108
  const usages = [];
109
+ const docs = [];
83
110
  for (const file of index.files.values()) {
84
111
  declarations.push(...file.declarations);
85
112
  usages.push(...file.usages);
113
+ docs.push(...file.docs);
86
114
  }
87
115
  index.declarations = declarations;
88
116
  index.usages = usages;
117
+ index.docs = docs;
118
+ index.configs = indexConfigFiles(scope);
89
119
  index.builtAt = Date.now();
90
120
  }
121
+ function indexFileDocsForFile(filePath) {
122
+ const sf = parseSourceFile(filePath);
123
+ if (!sf)
124
+ return [];
125
+ return indexFileDocs(sf);
126
+ }
91
127
  //# sourceMappingURL=workspaceIndex.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"workspaceIndex.js","sourceRoot":"","sources":["../../../src/search/index/workspaceIndex.ts"],"names":[],"mappings":"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"}
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
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compileEffectiveSearchSpec.js","sourceRoot":"","sources":["../../../src/search/query/compileEffectiveSearchSpec.ts"],"names":[],"mappings":"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"}
@@ -6,4 +6,5 @@ import type { QueryIR, SearchPlan } from '../types.js';
6
6
  export declare function parseQuery(raw: string, opts?: {
7
7
  forcedMode?: SearchPlan['mode'] | 'auto';
8
8
  forcedFamily?: string;
9
+ forcedFocus?: 'auto' | 'implementation' | 'usage' | 'pattern' | 'config';
9
10
  }): QueryIR;