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 @@
1
+ {"version":3,"file":"compileEffectiveSearchSpec.js","sourceRoot":"","sources":["../../../src/search/query/compileEffectiveSearchSpec.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { QueryIR, SearchPlan } from '../types.js';
2
+ /**
3
+ * Parse a raw query string into a structured QueryIR.
4
+ * Extracts three channels: NL tokens, exact identifiers, structural cues.
5
+ */
6
+ export declare function parseQuery(raw: string, opts?: {
7
+ forcedMode?: SearchPlan['mode'] | 'auto';
8
+ forcedFamily?: string;
9
+ forcedFocus?: 'auto' | 'implementation' | 'usage' | 'pattern' | 'config';
10
+ }): QueryIR;
@@ -0,0 +1,284 @@
1
+ import { scoreFamilies } from '../families/behaviorFamilies.js';
2
+ import { applyPhraseRules } from './phraseRules.js';
3
+ // Short family names (from find_code schema) → real family IDs
4
+ const FAMILY_ALIASES = {
5
+ auth: 'auth_permission',
6
+ errors: 'error_handling',
7
+ state: 'state_management',
8
+ flags: 'feature_flags',
9
+ retry: 'retry_backoff',
10
+ validation: 'validation',
11
+ fetching: 'fetching',
12
+ caching: 'caching',
13
+ };
14
+ // Structural cue words — preserved, NOT removed as stop words
15
+ const STRUCTURAL_CUES = new Set([
16
+ 'conditional', 'conditionally', 'if', 'return', 'returns', 'cleanup',
17
+ 'callback', 'without', 'inside', 'nested', 'loop', 'async', 'await',
18
+ 'try', 'catch', 'switch', 'default', 'throw', 'promise',
19
+ ]);
20
+ // NL stop words — only removed from the NL channel
21
+ const STOP_WORDS = new Set([
22
+ 'a', 'an', 'the', 'is', 'are', 'was', 'were', 'be', 'been', 'being',
23
+ 'have', 'has', 'had', 'do', 'does', 'did', 'will', 'would', 'could',
24
+ 'should', 'may', 'might', 'can', 'shall', 'to', 'of', 'in', 'for',
25
+ 'on', 'with', 'at', 'by', 'from', 'as', 'into', 'through', 'during',
26
+ 'where', 'how', 'what', 'which', 'who', 'when', 'why',
27
+ 'all', 'each', 'every', 'both', 'few', 'more', 'most', 'other',
28
+ 'some', 'such', 'no', 'not', 'only', 'own', 'same', 'so', 'than',
29
+ 'too', 'very', 'just', 'we', 'they', 'i', 'my', 'our', 'that',
30
+ 'this', 'these', 'those', 'me', 'him', 'her', 'it', 'its',
31
+ ]);
32
+ // Identifier pattern: camelCase, PascalCase, dotted (Promise.all, React.useEffect)
33
+ const IDENTIFIER_PATTERN = /\b([A-Z][a-zA-Z0-9]*(?:\.[a-zA-Z][a-zA-Z0-9]*)*|[a-z][a-zA-Z0-9]*(?:\.[a-zA-Z][a-zA-Z0-9]*)*)\b/g;
34
+ // Hook name pattern
35
+ const HOOK_PATTERN = /^use[A-Z]/;
36
+ // Structural predicate mapping from cue words
37
+ const PREDICATE_MAP = {
38
+ conditional: ['conditional'],
39
+ conditionally: ['conditional'],
40
+ if: ['conditional'],
41
+ return: [], // phrase-based: only fires in combination (returns + cleanup, etc.)
42
+ returns: [], // phrase-based: only fires in combination
43
+ cleanup: [], // phrase-based: returns + cleanup → returns-cleanup
44
+ callback: [], // phrase-based: callback + hook identifier → hook-callback
45
+ try: ['has-try-catch'],
46
+ catch: ['has-try-catch'],
47
+ without: [], // modifier — inverts next predicate
48
+ loop: ['await-in-loop'],
49
+ switch: ['switch-no-default'],
50
+ default: ['switch-no-default'],
51
+ hook: ['inside-hook'],
52
+ nested: [],
53
+ async: [],
54
+ await: ['await-in-loop'],
55
+ promise: [],
56
+ throw: [],
57
+ };
58
+ /**
59
+ * Parse a raw query string into a structured QueryIR.
60
+ * Extracts three channels: NL tokens, exact identifiers, structural cues.
61
+ */
62
+ export function parseQuery(raw, opts) {
63
+ const words = raw.split(/\s+/).filter(Boolean);
64
+ // --- Channel 1: Exact identifiers ---
65
+ const exactIdentifiers = [];
66
+ const dottedIdentifiers = [];
67
+ for (const word of words) {
68
+ const clean = word.replace(/[^a-zA-Z0-9.]/g, '');
69
+ if (!clean)
70
+ continue;
71
+ // Dotted identifier: Promise.all, React.useEffect
72
+ if (clean.includes('.') && /^[A-Za-z]/.test(clean)) {
73
+ dottedIdentifiers.push(clean);
74
+ continue;
75
+ }
76
+ // CamelCase/PascalCase identifier (not a plain lowercase word)
77
+ if (/^[A-Z]/.test(clean) || (HOOK_PATTERN.test(clean)) || (/[a-z][A-Z]/.test(clean) && clean.length > 3)) {
78
+ exactIdentifiers.push(clean);
79
+ }
80
+ }
81
+ // --- Channel 2: Structural cues ---
82
+ const structuralPredicates = [];
83
+ const codeTokens = [];
84
+ const hasWithout = words.some((w) => w.toLowerCase() === 'without');
85
+ for (const word of words) {
86
+ const lower = word.toLowerCase().replace(/[^a-z]/g, '');
87
+ if (STRUCTURAL_CUES.has(lower)) {
88
+ codeTokens.push(lower);
89
+ const preds = PREDICATE_MAP[lower] ?? [];
90
+ for (const pred of preds) {
91
+ // Handle "without" modifier
92
+ if (hasWithout && pred === 'returns-cleanup') {
93
+ if (!structuralPredicates.includes('no-cleanup'))
94
+ structuralPredicates.push('no-cleanup');
95
+ }
96
+ else if (hasWithout && pred === 'has-try-catch') {
97
+ if (!structuralPredicates.includes('no-try-catch'))
98
+ structuralPredicates.push('no-try-catch');
99
+ }
100
+ else {
101
+ if (!structuralPredicates.includes(pred))
102
+ structuralPredicates.push(pred);
103
+ }
104
+ }
105
+ }
106
+ }
107
+ // Phrase-based structural inference — requires combinations, not isolated keywords.
108
+ // This prevents "returns" alone from implying returns-function.
109
+ const hasHookId = exactIdentifiers.some((id) => HOOK_PATTERN.test(id));
110
+ if (codeTokens.includes('cleanup')) {
111
+ if (codeTokens.includes('returns') || codeTokens.includes('return')) {
112
+ // "returns cleanup" or "return cleanup"
113
+ if (hasWithout) {
114
+ if (!structuralPredicates.includes('no-cleanup'))
115
+ structuralPredicates.push('no-cleanup');
116
+ }
117
+ else {
118
+ if (!structuralPredicates.includes('returns-cleanup'))
119
+ structuralPredicates.push('returns-cleanup');
120
+ }
121
+ }
122
+ else if (hasWithout) {
123
+ // "without cleanup" (no returns keyword needed)
124
+ if (!structuralPredicates.includes('no-cleanup'))
125
+ structuralPredicates.push('no-cleanup');
126
+ }
127
+ }
128
+ if (codeTokens.includes('returns') || codeTokens.includes('return')) {
129
+ if (codeTokens.includes('callback') || hasHookId) {
130
+ // "returns callback" or "useEffect ... returns"
131
+ if (!structuralPredicates.includes('returns-function'))
132
+ structuralPredicates.push('returns-function');
133
+ }
134
+ }
135
+ if (codeTokens.includes('callback') && hasHookId) {
136
+ // "useEffect callback" — hook + callback together
137
+ if (!structuralPredicates.includes('hook-callback'))
138
+ structuralPredicates.push('hook-callback');
139
+ }
140
+ // Hook identifier + any structural predicates → add hook-callback context
141
+ if (hasHookId && structuralPredicates.length > 0) {
142
+ if (!structuralPredicates.includes('hook-callback')) {
143
+ structuralPredicates.push('hook-callback');
144
+ }
145
+ }
146
+ // --- Channel 3: NL tokens ---
147
+ const nlTokens = [];
148
+ for (const word of words) {
149
+ const lower = word.toLowerCase().replace(/[^a-z]/g, '');
150
+ if (!lower || lower.length < 2)
151
+ continue;
152
+ if (STOP_WORDS.has(lower))
153
+ continue;
154
+ // Don't add exact identifiers to NL channel
155
+ if (exactIdentifiers.includes(word) || dottedIdentifiers.includes(word))
156
+ continue;
157
+ nlTokens.push(lower);
158
+ }
159
+ // --- Phrases ---
160
+ const phrases = extractPhrases(raw);
161
+ // --- Family scoring ---
162
+ const allTerms = [...nlTokens, ...codeTokens];
163
+ let familyScores = scoreFamilies(allTerms);
164
+ // Apply forced family (resolve short alias → real ID)
165
+ if (opts?.forcedFamily) {
166
+ const resolvedFamily = FAMILY_ALIASES[opts.forcedFamily] ?? opts.forcedFamily;
167
+ familyScores[resolvedFamily] = (familyScores[resolvedFamily] ?? 0) + 10;
168
+ }
169
+ // --- Focus → internal mode/trait mapping ---
170
+ // The public API uses 'focus' instead of 'mode'/'family'. Map it to internals.
171
+ if (opts?.forcedFocus && opts.forcedFocus !== 'auto') {
172
+ switch (opts.forcedFocus) {
173
+ case 'usage':
174
+ opts.forcedMode = 'identifier';
175
+ break;
176
+ case 'implementation':
177
+ opts.forcedMode = 'behavior';
178
+ break;
179
+ case 'pattern':
180
+ opts.forcedMode = 'structural';
181
+ break;
182
+ case 'config':
183
+ // Config focus doesn't map to a mode — it activates the config trait
184
+ // (handled in traits section below)
185
+ break;
186
+ }
187
+ }
188
+ // --- Mode routing ---
189
+ const identifierScore = exactIdentifiers.length * 3 + dottedIdentifiers.length * 3;
190
+ const structuralScore = structuralPredicates.length * 2 + codeTokens.length;
191
+ const behaviorScore = Object.values(familyScores).reduce((s, v) => s + v, 0);
192
+ let mode;
193
+ let modeConfidence;
194
+ const routingReasons = [];
195
+ if (opts?.forcedMode && opts.forcedMode !== 'auto') {
196
+ mode = opts.forcedMode;
197
+ modeConfidence = 'high';
198
+ routingReasons.push(`forced mode: ${mode}`);
199
+ }
200
+ else {
201
+ // Determine mode from scores
202
+ const hasIdentifiers = identifierScore > 0;
203
+ const hasStructural = structuralScore > 2;
204
+ const hasBehavior = behaviorScore > 2;
205
+ if (hasIdentifiers && hasStructural) {
206
+ mode = 'structural'; // identifier + structural = structural (use identifier to locate, predicates to filter)
207
+ modeConfidence = 'high';
208
+ routingReasons.push('exact identifier detected', 'structural cues detected');
209
+ }
210
+ else if (hasIdentifiers && !hasBehavior) {
211
+ mode = 'identifier';
212
+ modeConfidence = 'high';
213
+ routingReasons.push('exact identifier detected', 'no strong behavior-family evidence');
214
+ }
215
+ else if (hasBehavior && hasStructural) {
216
+ mode = 'mixed';
217
+ modeConfidence = 'medium';
218
+ routingReasons.push('behavior family matched', 'structural cues detected');
219
+ }
220
+ else if (hasBehavior) {
221
+ mode = 'behavior';
222
+ modeConfidence = behaviorScore > 5 ? 'high' : 'medium';
223
+ routingReasons.push('behavior family matched');
224
+ }
225
+ else if (hasStructural) {
226
+ mode = 'structural';
227
+ modeConfidence = 'medium';
228
+ routingReasons.push('structural cues detected');
229
+ }
230
+ else if (hasIdentifiers) {
231
+ mode = 'identifier';
232
+ modeConfidence = 'medium';
233
+ routingReasons.push('identifier detected');
234
+ }
235
+ else {
236
+ mode = 'behavior'; // fallback
237
+ modeConfidence = 'low';
238
+ routingReasons.push('no strong signals, defaulting to behavior');
239
+ }
240
+ }
241
+ // --- Traits ---
242
+ const allLower = raw.toLowerCase();
243
+ const isConfigFocus = opts?.forcedFocus === 'config';
244
+ const hasHookIdentifier = exactIdentifiers.some((id) => /^use[A-Z]/.test(id));
245
+ const traits = {
246
+ reactLike: hasHookIdentifier || /\b(react|component|jsx|hook|use[A-Z])\b/.test(allLower),
247
+ stateLike: /\b(state|set[A-Z]\w*|useState|reducer|dispatch)\b/.test(allLower),
248
+ previousStateLike: /\b(prev|previous|current|existing|old)\b.*\b(state)\b/.test(allLower)
249
+ || /\bbased on (prev|previous|current)\b/.test(allLower),
250
+ routeLike: isConfigFocus || /\b(route|endpoint|url|path|api|handler)\b/.test(allLower),
251
+ configLike: isConfigFocus || /\b(config|env|flag|toggle|setting|variable|secret)\b/.test(allLower),
252
+ implementationRoot: /\b(real|actual|root|implementation|where.*(handled|defined|implemented))\b/.test(allLower),
253
+ testIntent: /\b(test|spec|describe|it\s+should)\b/.test(allLower),
254
+ };
255
+ // --- Phrase rules: infer additional structural predicates from multi-word combinations ---
256
+ const { added: phrasePredicates, reasons: phraseReasons } = applyPhraseRules(structuralPredicates, [...nlTokens, ...codeTokens], phrases, traits);
257
+ structuralPredicates.push(...phrasePredicates);
258
+ routingReasons.push(...phraseReasons);
259
+ return {
260
+ raw,
261
+ nlTokens,
262
+ phrases,
263
+ exactIdentifiers,
264
+ dottedIdentifiers,
265
+ codeTokens,
266
+ familyScores,
267
+ structuralPredicates,
268
+ traits,
269
+ recipes: [], // Populated by adapters in planQuery
270
+ mode,
271
+ modeConfidence,
272
+ routingReasons,
273
+ };
274
+ }
275
+ function extractPhrases(raw) {
276
+ // Extract 2-3 word phrases that might be meaningful
277
+ const words = raw.toLowerCase().split(/\s+/).filter((w) => w.length > 2);
278
+ const phrases = [];
279
+ for (let i = 0; i < words.length - 1; i++) {
280
+ phrases.push(`${words[i]} ${words[i + 1]}`);
281
+ }
282
+ return phrases;
283
+ }
284
+ //# sourceMappingURL=parseQuery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parseQuery.js","sourceRoot":"","sources":["../../../src/search/query/parseQuery.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { StructuralPredicate, QueryTraits } from '../types.js';
2
+ /**
3
+ * Apply phrase-based rules to infer structural predicates.
4
+ * Called after token-level parsing to add predicates that require
5
+ * multi-word combinations, not isolated keywords.
6
+ */
7
+ export declare function applyPhraseRules(existingPredicates: StructuralPredicate[], tokens: string[], phrases: string[], traits: QueryTraits): {
8
+ added: StructuralPredicate[];
9
+ reasons: string[];
10
+ };
@@ -0,0 +1,58 @@
1
+ const PHRASE_RULES = [
2
+ {
3
+ match: (tok, phrases) => phrases.some((p) => p.includes('returns cleanup') || p.includes('return cleanup')),
4
+ predicates: ['returns-cleanup'],
5
+ reason: 'phrase: "returns cleanup"',
6
+ },
7
+ {
8
+ match: (tok, phrases) => phrases.some((p) => p.includes('without cleanup')),
9
+ predicates: ['no-cleanup'],
10
+ reason: 'phrase: "without cleanup"',
11
+ },
12
+ {
13
+ match: (tok, phrases) => phrases.some((p) => p.includes('without try') || p.includes('without catch') || p.includes('no try')),
14
+ predicates: ['no-try-catch'],
15
+ reason: 'phrase: "without try/catch"',
16
+ },
17
+ {
18
+ match: (tok, phrases) => phrases.some((p) => p.includes('switch without') || p.includes('without default')),
19
+ predicates: ['switch-no-default'],
20
+ reason: 'phrase: "switch without default"',
21
+ },
22
+ {
23
+ match: (tok, phrases) => phrases.some((p) => p.includes('await inside') || p.includes('await loop') || p.includes('loop await')),
24
+ predicates: ['await-in-loop'],
25
+ reason: 'phrase: "await inside loop"',
26
+ },
27
+ {
28
+ match: (_tok, _phrases, traits) => traits.previousStateLike,
29
+ predicates: ['functional-state-updater'],
30
+ reason: 'trait: previousStateLike → functional state updater pattern',
31
+ },
32
+ {
33
+ match: (tok, phrases) => phrases.some((p) => p.includes('conditional cleanup') || p.includes('conditionally return')),
34
+ predicates: ['conditional', 'returns-cleanup'],
35
+ reason: 'phrase: "conditional cleanup"',
36
+ },
37
+ ];
38
+ /**
39
+ * Apply phrase-based rules to infer structural predicates.
40
+ * Called after token-level parsing to add predicates that require
41
+ * multi-word combinations, not isolated keywords.
42
+ */
43
+ export function applyPhraseRules(existingPredicates, tokens, phrases, traits) {
44
+ const added = [];
45
+ const reasons = [];
46
+ for (const rule of PHRASE_RULES) {
47
+ if (rule.match(tokens, phrases, traits)) {
48
+ for (const pred of rule.predicates) {
49
+ if (!existingPredicates.includes(pred) && !added.includes(pred)) {
50
+ added.push(pred);
51
+ }
52
+ }
53
+ reasons.push(rule.reason);
54
+ }
55
+ }
56
+ return { added, reasons };
57
+ }
58
+ //# sourceMappingURL=phraseRules.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"phraseRules.js","sourceRoot":"","sources":["../../../src/search/query/phraseRules.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { QueryIR, SearchPlan } from '../types.js';
2
+ /**
3
+ * Plan which retrievers to use based on the parsed query IR.
4
+ *
5
+ * Steps:
6
+ * 1. Run adapters to generate recipes (mutates ir.recipes)
7
+ * 2. Merge recipe retriever requirements with mode-based defaults
8
+ * 3. Decide graph expansion from traits
9
+ */
10
+ export declare function planQuery(ir: QueryIR): SearchPlan;
@@ -0,0 +1,91 @@
1
+ import { runAdapters } from '../adapters/registry.js';
2
+ /**
3
+ * Plan which retrievers to use based on the parsed query IR.
4
+ *
5
+ * Steps:
6
+ * 1. Run adapters to generate recipes (mutates ir.recipes)
7
+ * 2. Merge recipe retriever requirements with mode-based defaults
8
+ * 3. Decide graph expansion from traits
9
+ */
10
+ export function planQuery(ir) {
11
+ // Step 1: Run adapters to populate recipes
12
+ const recipes = runAdapters(ir);
13
+ ir.recipes = recipes;
14
+ const retrievers = [];
15
+ const reasons = [];
16
+ let expandGraph = false;
17
+ // Step 2: Mode-based default retrievers
18
+ switch (ir.mode) {
19
+ case 'behavior':
20
+ retrievers.push('behavior');
21
+ reasons.push('behavior family matched — searching declarations by concept');
22
+ retrievers.push('doc');
23
+ reasons.push('doc retriever for narrative/comment bridge');
24
+ break;
25
+ case 'identifier':
26
+ retrievers.push('identifier');
27
+ reasons.push('exact identifier detected — searching usage sites');
28
+ if (ir.structuralPredicates.length > 0) {
29
+ retrievers.push('structural');
30
+ reasons.push('structural predicates found — will filter by code shape');
31
+ }
32
+ break;
33
+ case 'structural':
34
+ if (ir.exactIdentifiers.length > 0 || ir.dottedIdentifiers.length > 0) {
35
+ retrievers.push('identifier');
36
+ reasons.push('using identifier to locate candidate sites');
37
+ }
38
+ retrievers.push('structural');
39
+ reasons.push('structural predicates will filter/rank results');
40
+ break;
41
+ case 'mixed':
42
+ retrievers.push('behavior');
43
+ reasons.push('behavior retrieval for concept matching');
44
+ retrievers.push('doc');
45
+ reasons.push('doc retriever for narrative bridge');
46
+ if (ir.exactIdentifiers.length > 0 || ir.dottedIdentifiers.length > 0) {
47
+ retrievers.push('identifier');
48
+ reasons.push('identifier retrieval for exact API matches');
49
+ }
50
+ if (ir.structuralPredicates.length > 0) {
51
+ retrievers.push('structural');
52
+ reasons.push('structural predicates for shape filtering');
53
+ }
54
+ break;
55
+ }
56
+ // Step 3: Merge recipe retrievers
57
+ for (const recipe of recipes) {
58
+ for (const r of recipe.retrievers) {
59
+ if (!retrievers.includes(r)) {
60
+ retrievers.push(r);
61
+ reasons.push(`recipe ${recipe.id} → ${r} retriever`);
62
+ }
63
+ }
64
+ reasons.push(...recipe.reasons);
65
+ }
66
+ // Config retriever for route/config/flag/env queries
67
+ if (ir.traits.routeLike || ir.traits.configLike) {
68
+ if (!retrievers.includes('config')) {
69
+ retrievers.push('config');
70
+ reasons.push('config/route trait detected — searching config files');
71
+ }
72
+ }
73
+ // Graph expansion for implementation-root queries
74
+ if (ir.traits.implementationRoot) {
75
+ expandGraph = true;
76
+ reasons.push('implementation-root trait — will expand to real implementations');
77
+ }
78
+ // Ensure at least one retriever
79
+ if (retrievers.length === 0) {
80
+ retrievers.push('behavior');
81
+ retrievers.push('doc');
82
+ reasons.push('fallback: no specific signals, using behavior + doc search');
83
+ }
84
+ return {
85
+ mode: ir.mode,
86
+ retrievers,
87
+ reasons,
88
+ expandGraph,
89
+ };
90
+ }
91
+ //# sourceMappingURL=planQuery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"planQuery.js","sourceRoot":"","sources":["../../../src/search/query/planQuery.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { CodeCandidate, QueryIR, SearchPlan } from '../types.js';
2
+ /**
3
+ * Assess overall confidence of the search results.
4
+ * High = strong signals from multiple sources. Low = weak/generic matches.
5
+ */
6
+ export declare function assessConfidence(ranked: CodeCandidate[], ir: QueryIR, plan: SearchPlan): 'high' | 'medium' | 'low';
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Assess overall confidence of the search results.
3
+ * High = strong signals from multiple sources. Low = weak/generic matches.
4
+ */
5
+ export function assessConfidence(ranked, ir, plan) {
6
+ if (ranked.length === 0)
7
+ return 'low';
8
+ const top = ranked[0];
9
+ const multiSource = top.sources.length > 1;
10
+ const hasStructural = top.sources.includes('structural');
11
+ const hasGraph = top.sources.includes('graph');
12
+ const hasDoc = top.sources.includes('doc');
13
+ const highScore = top.score >= 15;
14
+ const hasOverlap = top.evidence.some((e) => e.includes('overlap'));
15
+ if (multiSource && highScore)
16
+ return 'high';
17
+ if (hasStructural && top.score >= 10)
18
+ return 'high';
19
+ if (hasGraph && top.score >= 10)
20
+ return 'high';
21
+ if (hasOverlap)
22
+ return 'high';
23
+ if (highScore)
24
+ return 'medium';
25
+ if (hasDoc && top.score >= 8)
26
+ return 'medium';
27
+ if (ir.modeConfidence === 'low')
28
+ return 'low';
29
+ return 'medium';
30
+ }
31
+ //# sourceMappingURL=assessConfidence.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assessConfidence.js","sourceRoot":"","sources":["../../../src/search/ranking/assessConfidence.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAC9B,MAAuB,EACvB,EAAW,EACX,IAAgB;IAEhB,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAEtC,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;IACtB,MAAM,WAAW,GAAG,GAAG,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;IAC3C,MAAM,aAAa,GAAG,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;IACzD,MAAM,QAAQ,GAAG,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC/C,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC3C,MAAM,SAAS,GAAG,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC;IAClC,MAAM,UAAU,GAAG,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC;IAEnE,IAAI,WAAW,IAAI,SAAS;QAAE,OAAO,MAAM,CAAC;IAC5C,IAAI,aAAa,IAAI,GAAG,CAAC,KAAK,IAAI,EAAE;QAAE,OAAO,MAAM,CAAC;IACpD,IAAI,QAAQ,IAAI,GAAG,CAAC,KAAK,IAAI,EAAE;QAAE,OAAO,MAAM,CAAC;IAC/C,IAAI,UAAU;QAAE,OAAO,MAAM,CAAC;IAC9B,IAAI,SAAS;QAAE,OAAO,QAAQ,CAAC;IAC/B,IAAI,MAAM,IAAI,GAAG,CAAC,KAAK,IAAI,CAAC;QAAE,OAAO,QAAQ,CAAC;IAC9C,IAAI,EAAE,CAAC,cAAc,KAAK,KAAK;QAAE,OAAO,KAAK,CAAC;IAE9C,OAAO,QAAQ,CAAC;AAClB,CAAC"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Canonical candidate identity key.
3
+ * Used consistently across merge, coalesce, graph expansion, and ranking.
4
+ *
5
+ * Format: filePath:line1based:symbol
6
+ * Both functions produce the same format so keys match across subsystems.
7
+ */
8
+ export declare function absoluteCandidateKey(input: {
9
+ filePath: string;
10
+ line: number;
11
+ symbol?: string;
12
+ matchedIdentifier?: string;
13
+ }): string;
14
+ /**
15
+ * Convert an LSP URI + 0-based position to the candidate key format.
16
+ * Used by graph expansion to generate keys that match candidate keys.
17
+ *
18
+ * Produces workspace-relative paths to match candidates after ranking
19
+ * (which relativizes paths via relativePath()).
20
+ */
21
+ export declare function lspLocationToKey(uri: string, line0: number, workspaceRoot: string, symbol?: string): string;
@@ -0,0 +1,29 @@
1
+ import * as path from 'path';
2
+ /**
3
+ * Canonical candidate identity key.
4
+ * Used consistently across merge, coalesce, graph expansion, and ranking.
5
+ *
6
+ * Format: filePath:line1based:symbol
7
+ * Both functions produce the same format so keys match across subsystems.
8
+ */
9
+ export function absoluteCandidateKey(input) {
10
+ const symbol = input.symbol ?? input.matchedIdentifier ?? '';
11
+ return `${input.filePath}:${input.line}:${symbol}`;
12
+ }
13
+ /**
14
+ * Convert an LSP URI + 0-based position to the candidate key format.
15
+ * Used by graph expansion to generate keys that match candidate keys.
16
+ *
17
+ * Produces workspace-relative paths to match candidates after ranking
18
+ * (which relativizes paths via relativePath()).
19
+ */
20
+ export function lspLocationToKey(uri, line0, workspaceRoot, symbol) {
21
+ let absPath = uri;
22
+ if (uri.startsWith('file://')) {
23
+ absPath = decodeURIComponent(uri.replace(/^file:\/\//, ''));
24
+ }
25
+ const rel = path.relative(workspaceRoot, absPath);
26
+ const line1 = line0 + 1;
27
+ return `${rel}:${line1}:${symbol ?? ''}`;
28
+ }
29
+ //# sourceMappingURL=candidateIdentity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"candidateIdentity.js","sourceRoot":"","sources":["../../../src/search/ranking/candidateIdentity.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAE7B;;;;;;GAMG;AACH,MAAM,UAAU,oBAAoB,CAAC,KAKpC;IACC,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,iBAAiB,IAAI,EAAE,CAAC;IAC7D,OAAO,GAAG,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,IAAI,IAAI,MAAM,EAAE,CAAC;AACrD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAC9B,GAAW,EACX,KAAa,EACb,aAAqB,EACrB,MAAe;IAEf,IAAI,OAAO,GAAG,GAAG,CAAC;IAClB,IAAI,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC9B,OAAO,GAAG,kBAAkB,CAAC,GAAG,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC,CAAC;IAC9D,CAAC;IAED,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;IAClD,MAAM,KAAK,GAAG,KAAK,GAAG,CAAC,CAAC;IACxB,OAAO,GAAG,GAAG,IAAI,KAAK,IAAI,MAAM,IAAI,EAAE,EAAE,CAAC;AAC3C,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type { CodeCandidate } from '../types.js';
2
+ /**
3
+ * Coalesce candidates that represent the same logical match.
4
+ * Merges doc + declaration, usage + pattern, etc. at the same location/symbol.
5
+ *
6
+ * This runs after retriever merge and before ranking, preventing
7
+ * duplicate entries for the same symbol from different retriever types.
8
+ */
9
+ export declare function coalesceCandidates(candidates: CodeCandidate[]): CodeCandidate[];