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.
- package/README.md +41 -13
- package/dist/analysis/pattern/collectSearchFiles.d.ts +2 -1
- package/dist/analysis/pattern/collectSearchFiles.js +6 -6
- package/dist/analysis/pattern/collectSearchFiles.js.map +1 -1
- package/dist/analysis/pattern/runPatternSearch.d.ts +1 -1
- package/dist/analysis/pattern/runPatternSearch.js +4 -2
- package/dist/analysis/pattern/runPatternSearch.js.map +1 -1
- package/dist/analysis/ts/extractUsages.js +19 -0
- package/dist/analysis/ts/extractUsages.js.map +1 -1
- package/dist/analysis/ts/parseSourceFile.d.ts +2 -1
- package/dist/analysis/ts/parseSourceFile.js +5 -9
- package/dist/analysis/ts/parseSourceFile.js.map +1 -1
- package/dist/analysis/ts/reactState.d.ts +9 -0
- package/dist/analysis/ts/reactState.js +57 -0
- package/dist/analysis/ts/reactState.js.map +1 -0
- package/dist/analysis/ts/structuralPredicates.js +31 -2
- package/dist/analysis/ts/structuralPredicates.js.map +1 -1
- package/dist/ast/parseFile.d.ts +4 -3
- package/dist/ast/parseFile.js +22 -5
- package/dist/ast/parseFile.js.map +1 -1
- package/dist/engine/LspEngine.js +23 -1
- package/dist/engine/LspEngine.js.map +1 -1
- package/dist/git/getBaseFileContent.d.ts +1 -0
- package/dist/git/getBaseFileContent.js +10 -3
- package/dist/git/getBaseFileContent.js.map +1 -1
- package/dist/git/getChangedFiles.d.ts +2 -1
- package/dist/git/getChangedFiles.js +11 -5
- package/dist/git/getChangedFiles.js.map +1 -1
- package/dist/git/getChangedHunks.d.ts +1 -0
- package/dist/git/getChangedHunks.js +15 -10
- package/dist/git/getChangedHunks.js.map +1 -1
- package/dist/git/getGitRoot.d.ts +15 -0
- package/dist/git/getGitRoot.js +33 -0
- package/dist/git/getGitRoot.js.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/resolve/searchScope.d.ts +8 -2
- package/dist/resolve/searchScope.js +26 -14
- package/dist/resolve/searchScope.js.map +1 -1
- package/dist/search/adapters/config.d.ts +5 -0
- package/dist/search/adapters/config.js +56 -0
- package/dist/search/adapters/config.js.map +1 -0
- package/dist/search/adapters/http.d.ts +6 -0
- package/dist/search/adapters/http.js +58 -0
- package/dist/search/adapters/http.js.map +1 -0
- package/dist/search/adapters/react.d.ts +12 -0
- package/dist/search/adapters/react.js +92 -0
- package/dist/search/adapters/react.js.map +1 -0
- package/dist/search/adapters/registry.d.ts +6 -0
- package/dist/search/adapters/registry.js +20 -0
- package/dist/search/adapters/registry.js.map +1 -0
- package/dist/search/adapters/types.d.ts +5 -0
- package/dist/search/adapters/types.js +2 -0
- package/dist/search/adapters/types.js.map +1 -0
- package/dist/search/debug/trace.d.ts +6 -0
- package/dist/search/debug/trace.js +25 -0
- package/dist/search/debug/trace.js.map +1 -0
- package/dist/search/expand/graphExpansion.d.ts +16 -0
- package/dist/search/expand/graphExpansion.js +168 -0
- package/dist/search/expand/graphExpansion.js.map +1 -0
- package/dist/search/fileKinds.d.ts +13 -0
- package/dist/search/fileKinds.js +74 -0
- package/dist/search/fileKinds.js.map +1 -0
- package/dist/search/index/configIndex.d.ts +6 -0
- package/dist/search/index/configIndex.js +196 -0
- package/dist/search/index/configIndex.js.map +1 -0
- package/dist/search/index/docIndex.d.ts +7 -0
- package/dist/search/index/docIndex.js +116 -0
- package/dist/search/index/docIndex.js.map +1 -0
- package/dist/search/index/workspaceIndex.d.ts +6 -0
- package/dist/search/index/workspaceIndex.js +50 -14
- package/dist/search/index/workspaceIndex.js.map +1 -1
- package/dist/search/query/compileEffectiveSearchSpec.d.ts +24 -0
- package/dist/search/query/compileEffectiveSearchSpec.js +67 -0
- package/dist/search/query/compileEffectiveSearchSpec.js.map +1 -0
- package/dist/search/query/parseQuery.d.ts +1 -0
- package/dist/search/query/parseQuery.js +40 -0
- package/dist/search/query/parseQuery.js.map +1 -1
- package/dist/search/query/phraseRules.d.ts +10 -0
- package/dist/search/query/phraseRules.js +58 -0
- package/dist/search/query/phraseRules.js.map +1 -0
- package/dist/search/query/planQuery.d.ts +4 -3
- package/dist/search/query/planQuery.js +39 -6
- package/dist/search/query/planQuery.js.map +1 -1
- package/dist/search/ranking/assessConfidence.js +6 -0
- package/dist/search/ranking/assessConfidence.js.map +1 -1
- package/dist/search/ranking/candidateIdentity.d.ts +21 -0
- package/dist/search/ranking/candidateIdentity.js +29 -0
- package/dist/search/ranking/candidateIdentity.js.map +1 -0
- package/dist/search/ranking/coalesceCandidates.d.ts +9 -0
- package/dist/search/ranking/coalesceCandidates.js +48 -0
- package/dist/search/ranking/coalesceCandidates.js.map +1 -0
- package/dist/search/ranking/fieldedTextRanker.d.ts +26 -0
- package/dist/search/ranking/fieldedTextRanker.js +79 -0
- package/dist/search/ranking/fieldedTextRanker.js.map +1 -0
- package/dist/search/ranking/mergeCandidates.d.ts +3 -0
- package/dist/search/ranking/mergeCandidates.js +39 -0
- package/dist/search/ranking/mergeCandidates.js.map +1 -1
- package/dist/search/ranking/rankCandidates.d.ts +1 -1
- package/dist/search/ranking/rankCandidates.js +51 -3
- package/dist/search/ranking/rankCandidates.js.map +1 -1
- package/dist/search/retrievers/behaviorRetriever.d.ts +3 -3
- package/dist/search/retrievers/behaviorRetriever.js +64 -69
- package/dist/search/retrievers/behaviorRetriever.js.map +1 -1
- package/dist/search/retrievers/configRetriever.d.ts +7 -0
- package/dist/search/retrievers/configRetriever.js +46 -0
- package/dist/search/retrievers/configRetriever.js.map +1 -0
- package/dist/search/retrievers/docRetriever.d.ts +7 -0
- package/dist/search/retrievers/docRetriever.js +46 -0
- package/dist/search/retrievers/docRetriever.js.map +1 -0
- package/dist/search/retrievers/identifierRetriever.d.ts +3 -3
- package/dist/search/retrievers/identifierRetriever.js +7 -6
- package/dist/search/retrievers/identifierRetriever.js.map +1 -1
- package/dist/search/retrievers/structuralRetriever.d.ts +4 -6
- package/dist/search/retrievers/structuralRetriever.js +47 -84
- package/dist/search/retrievers/structuralRetriever.js.map +1 -1
- package/dist/search/retrievers/textPatternRetriever.d.ts +7 -0
- package/dist/search/retrievers/textPatternRetriever.js +90 -0
- package/dist/search/retrievers/textPatternRetriever.js.map +1 -0
- package/dist/search/structural/locators/callLocator.d.ts +6 -0
- package/dist/search/structural/locators/callLocator.js +57 -0
- package/dist/search/structural/locators/callLocator.js.map +1 -0
- package/dist/search/structural/locators/declarationLocator.d.ts +6 -0
- package/dist/search/structural/locators/declarationLocator.js +57 -0
- package/dist/search/structural/locators/declarationLocator.js.map +1 -0
- package/dist/search/structural/locators/statementLocator.d.ts +6 -0
- package/dist/search/structural/locators/statementLocator.js +65 -0
- package/dist/search/structural/locators/statementLocator.js.map +1 -0
- package/dist/search/structural/locators/types.d.ts +12 -0
- package/dist/search/structural/locators/types.js +2 -0
- package/dist/search/structural/locators/types.js.map +1 -0
- package/dist/search/structural/selectLocators.d.ts +7 -0
- package/dist/search/structural/selectLocators.js +21 -0
- package/dist/search/structural/selectLocators.js.map +1 -0
- package/dist/search/types.d.ts +77 -7
- package/dist/search/types.js.map +1 -1
- package/dist/tools/composites/apiGuard.js +6 -28
- package/dist/tools/composites/apiGuard.js.map +1 -1
- package/dist/tools/composites/findCode.js +92 -15
- package/dist/tools/composites/findCode.js.map +1 -1
- package/dist/tools/composites/findPattern.js +1 -1
- package/dist/tools/composites/findPattern.js.map +1 -1
- package/dist/tools/live/clearIndex.d.ts +1 -0
- package/dist/tools/live/clearIndex.js +19 -0
- package/dist/tools/live/clearIndex.js.map +1 -0
- package/dist/tools/primitives/callHierarchy.js +1 -1
- package/dist/tools/primitives/callHierarchy.js.map +1 -1
- package/package.json +4 -2
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { scoreFamilies } from '../families/behaviorFamilies.js';
|
|
2
|
+
import { applyPhraseRules } from './phraseRules.js';
|
|
2
3
|
// Short family names (from find_code schema) → real family IDs
|
|
3
4
|
const FAMILY_ALIASES = {
|
|
4
5
|
auth: 'auth_permission',
|
|
@@ -165,6 +166,25 @@ export function parseQuery(raw, opts) {
|
|
|
165
166
|
const resolvedFamily = FAMILY_ALIASES[opts.forcedFamily] ?? opts.forcedFamily;
|
|
166
167
|
familyScores[resolvedFamily] = (familyScores[resolvedFamily] ?? 0) + 10;
|
|
167
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
|
+
}
|
|
168
188
|
// --- Mode routing ---
|
|
169
189
|
const identifierScore = exactIdentifiers.length * 3 + dottedIdentifiers.length * 3;
|
|
170
190
|
const structuralScore = structuralPredicates.length * 2 + codeTokens.length;
|
|
@@ -218,6 +238,24 @@ export function parseQuery(raw, opts) {
|
|
|
218
238
|
routingReasons.push('no strong signals, defaulting to behavior');
|
|
219
239
|
}
|
|
220
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);
|
|
221
259
|
return {
|
|
222
260
|
raw,
|
|
223
261
|
nlTokens,
|
|
@@ -227,6 +265,8 @@ export function parseQuery(raw, opts) {
|
|
|
227
265
|
codeTokens,
|
|
228
266
|
familyScores,
|
|
229
267
|
structuralPredicates,
|
|
268
|
+
traits,
|
|
269
|
+
recipes: [], // Populated by adapters in planQuery
|
|
230
270
|
mode,
|
|
231
271
|
modeConfidence,
|
|
232
272
|
routingReasons,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parseQuery.js","sourceRoot":"","sources":["../../../src/search/query/parseQuery.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;
|
|
1
|
+
{"version":3,"file":"parseQuery.js","sourceRoot":"","sources":["../../../src/search/query/parseQuery.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEpD,+DAA+D;AAC/D,MAAM,cAAc,GAA2B;IAC7C,IAAI,EAAE,iBAAiB;IACvB,MAAM,EAAE,gBAAgB;IACxB,KAAK,EAAE,kBAAkB;IACzB,KAAK,EAAE,eAAe;IACtB,KAAK,EAAE,eAAe;IACtB,UAAU,EAAE,YAAY;IACxB,QAAQ,EAAE,UAAU;IACpB,OAAO,EAAE,SAAS;CACnB,CAAC;AAEF,8DAA8D;AAC9D,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC;IAC9B,aAAa,EAAE,eAAe,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS;IACpE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO;IACnE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS;CACxD,CAAC,CAAC;AAEH,mDAAmD;AACnD,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC;IACzB,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO;IACnE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO;IACnE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK;IACjE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ;IACnE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK;IACrD,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO;IAC9D,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;IAChE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM;IAC7D,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK;CAC1D,CAAC,CAAC;AAEH,mFAAmF;AACnF,MAAM,kBAAkB,GAAG,kGAAkG,CAAC;AAE9H,oBAAoB;AACpB,MAAM,YAAY,GAAG,WAAW,CAAC;AAEjC,8CAA8C;AAC9C,MAAM,aAAa,GAA0C;IAC3D,WAAW,EAAE,CAAC,aAAa,CAAC;IAC5B,aAAa,EAAE,CAAC,aAAa,CAAC;IAC9B,EAAE,EAAE,CAAC,aAAa,CAAC;IACnB,MAAM,EAAE,EAAE,EAAI,oEAAoE;IAClF,OAAO,EAAE,EAAE,EAAI,0CAA0C;IACzD,OAAO,EAAE,EAAE,EAAI,oDAAoD;IACnE,QAAQ,EAAE,EAAE,EAAG,2DAA2D;IAC1E,GAAG,EAAE,CAAC,eAAe,CAAC;IACtB,KAAK,EAAE,CAAC,eAAe,CAAC;IACxB,OAAO,EAAE,EAAE,EAAE,oCAAoC;IACjD,IAAI,EAAE,CAAC,eAAe,CAAC;IACvB,MAAM,EAAE,CAAC,mBAAmB,CAAC;IAC7B,OAAO,EAAE,CAAC,mBAAmB,CAAC;IAC9B,IAAI,EAAE,CAAC,aAAa,CAAC;IACrB,MAAM,EAAE,EAAE;IACV,KAAK,EAAE,EAAE;IACT,KAAK,EAAE,CAAC,eAAe,CAAC;IACxB,OAAO,EAAE,EAAE;IACX,KAAK,EAAE,EAAE;CACV,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,UAAU,CACxB,GAAW,EACX,IAIC;IAED,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAE/C,uCAAuC;IACvC,MAAM,gBAAgB,GAAa,EAAE,CAAC;IACtC,MAAM,iBAAiB,GAAa,EAAE,CAAC;IAEvC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,gBAAgB,EAAE,EAAE,CAAC,CAAC;QACjD,IAAI,CAAC,KAAK;YAAE,SAAS;QAErB,kDAAkD;QAClD,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YACnD,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC9B,SAAS;QACX,CAAC;QAED,+DAA+D;QAC/D,IAAI,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC;YACzG,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC/B,CAAC;IACH,CAAC;IAED,qCAAqC;IACrC,MAAM,oBAAoB,GAA0B,EAAE,CAAC;IACvD,MAAM,UAAU,GAAa,EAAE,CAAC;IAChC,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,KAAK,SAAS,CAAC,CAAC;IAEpE,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;QACxD,IAAI,eAAe,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YAC/B,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACvB,MAAM,KAAK,GAAG,aAAa,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;YACzC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,4BAA4B;gBAC5B,IAAI,UAAU,IAAI,IAAI,KAAK,iBAAiB,EAAE,CAAC;oBAC7C,IAAI,CAAC,oBAAoB,CAAC,QAAQ,CAAC,YAAY,CAAC;wBAAE,oBAAoB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;gBAC5F,CAAC;qBAAM,IAAI,UAAU,IAAI,IAAI,KAAK,eAAe,EAAE,CAAC;oBAClD,IAAI,CAAC,oBAAoB,CAAC,QAAQ,CAAC,cAAc,CAAC;wBAAE,oBAAoB,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;gBAChG,CAAC;qBAAM,CAAC;oBACN,IAAI,CAAC,oBAAoB,CAAC,QAAQ,CAAC,IAAI,CAAC;wBAAE,oBAAoB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC5E,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,oFAAoF;IACpF,gEAAgE;IAChE,MAAM,SAAS,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;IAEvE,IAAI,UAAU,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QACnC,IAAI,UAAU,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;YACpE,wCAAwC;YACxC,IAAI,UAAU,EAAE,CAAC;gBACf,IAAI,CAAC,oBAAoB,CAAC,QAAQ,CAAC,YAAY,CAAC;oBAAE,oBAAoB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YAC5F,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,oBAAoB,CAAC,QAAQ,CAAC,iBAAiB,CAAC;oBAAE,oBAAoB,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;YACtG,CAAC;QACH,CAAC;aAAM,IAAI,UAAU,EAAE,CAAC;YACtB,gDAAgD;YAChD,IAAI,CAAC,oBAAoB,CAAC,QAAQ,CAAC,YAAY,CAAC;gBAAE,oBAAoB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC5F,CAAC;IACH,CAAC;IAED,IAAI,UAAU,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QACpE,IAAI,UAAU,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,SAAS,EAAE,CAAC;YACjD,gDAAgD;YAChD,IAAI,CAAC,oBAAoB,CAAC,QAAQ,CAAC,kBAAkB,CAAC;gBAAE,oBAAoB,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;QACxG,CAAC;IACH,CAAC;IAED,IAAI,UAAU,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,SAAS,EAAE,CAAC;QACjD,kDAAkD;QAClD,IAAI,CAAC,oBAAoB,CAAC,QAAQ,CAAC,eAAe,CAAC;YAAE,oBAAoB,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IAClG,CAAC;IAED,0EAA0E;IAC1E,IAAI,SAAS,IAAI,oBAAoB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACjD,IAAI,CAAC,oBAAoB,CAAC,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC;YACpD,oBAAoB,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QAC7C,CAAC;IACH,CAAC;IAED,+BAA+B;IAC/B,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;QACxD,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;YAAE,SAAS;QACzC,IAAI,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC;YAAE,SAAS;QACpC,4CAA4C;QAC5C,IAAI,gBAAgB,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,iBAAiB,CAAC,QAAQ,CAAC,IAAI,CAAC;YAAE,SAAS;QAClF,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC;IAED,kBAAkB;IAClB,MAAM,OAAO,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;IAEpC,yBAAyB;IACzB,MAAM,QAAQ,GAAG,CAAC,GAAG,QAAQ,EAAE,GAAG,UAAU,CAAC,CAAC;IAC9C,IAAI,YAAY,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC;IAE3C,sDAAsD;IACtD,IAAI,IAAI,EAAE,YAAY,EAAE,CAAC;QACvB,MAAM,cAAc,GAAG,cAAc,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,IAAI,CAAC,YAAY,CAAC;QAC9E,YAAY,CAAC,cAAc,CAAC,GAAG,CAAC,YAAY,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,CAAC;IAC1E,CAAC;IAED,8CAA8C;IAC9C,+EAA+E;IAC/E,IAAI,IAAI,EAAE,WAAW,IAAI,IAAI,CAAC,WAAW,KAAK,MAAM,EAAE,CAAC;QACrD,QAAQ,IAAI,CAAC,WAAW,EAAE,CAAC;YACzB,KAAK,OAAO;gBACV,IAAI,CAAC,UAAU,GAAG,YAAY,CAAC;gBAC/B,MAAM;YACR,KAAK,gBAAgB;gBACnB,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;gBAC7B,MAAM;YACR,KAAK,SAAS;gBACZ,IAAI,CAAC,UAAU,GAAG,YAAY,CAAC;gBAC/B,MAAM;YACR,KAAK,QAAQ;gBACX,qEAAqE;gBACrE,oCAAoC;gBACpC,MAAM;QACV,CAAC;IACH,CAAC;IAED,uBAAuB;IACvB,MAAM,eAAe,GAAG,gBAAgB,CAAC,MAAM,GAAG,CAAC,GAAG,iBAAiB,CAAC,MAAM,GAAG,CAAC,CAAC;IACnF,MAAM,eAAe,GAAG,oBAAoB,CAAC,MAAM,GAAG,CAAC,GAAG,UAAU,CAAC,MAAM,CAAC;IAC5E,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IAE7E,IAAI,IAAqB,CAAC;IAC1B,IAAI,cAAyC,CAAC;IAC9C,MAAM,cAAc,GAAa,EAAE,CAAC;IAEpC,IAAI,IAAI,EAAE,UAAU,IAAI,IAAI,CAAC,UAAU,KAAK,MAAM,EAAE,CAAC;QACnD,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC;QACvB,cAAc,GAAG,MAAM,CAAC;QACxB,cAAc,CAAC,IAAI,CAAC,gBAAgB,IAAI,EAAE,CAAC,CAAC;IAC9C,CAAC;SAAM,CAAC;QACN,6BAA6B;QAC7B,MAAM,cAAc,GAAG,eAAe,GAAG,CAAC,CAAC;QAC3C,MAAM,aAAa,GAAG,eAAe,GAAG,CAAC,CAAC;QAC1C,MAAM,WAAW,GAAG,aAAa,GAAG,CAAC,CAAC;QAEtC,IAAI,cAAc,IAAI,aAAa,EAAE,CAAC;YACpC,IAAI,GAAG,YAAY,CAAC,CAAC,wFAAwF;YAC7G,cAAc,GAAG,MAAM,CAAC;YACxB,cAAc,CAAC,IAAI,CAAC,2BAA2B,EAAE,0BAA0B,CAAC,CAAC;QAC/E,CAAC;aAAM,IAAI,cAAc,IAAI,CAAC,WAAW,EAAE,CAAC;YAC1C,IAAI,GAAG,YAAY,CAAC;YACpB,cAAc,GAAG,MAAM,CAAC;YACxB,cAAc,CAAC,IAAI,CAAC,2BAA2B,EAAE,oCAAoC,CAAC,CAAC;QACzF,CAAC;aAAM,IAAI,WAAW,IAAI,aAAa,EAAE,CAAC;YACxC,IAAI,GAAG,OAAO,CAAC;YACf,cAAc,GAAG,QAAQ,CAAC;YAC1B,cAAc,CAAC,IAAI,CAAC,yBAAyB,EAAE,0BAA0B,CAAC,CAAC;QAC7E,CAAC;aAAM,IAAI,WAAW,EAAE,CAAC;YACvB,IAAI,GAAG,UAAU,CAAC;YAClB,cAAc,GAAG,aAAa,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC;YACvD,cAAc,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;QACjD,CAAC;aAAM,IAAI,aAAa,EAAE,CAAC;YACzB,IAAI,GAAG,YAAY,CAAC;YACpB,cAAc,GAAG,QAAQ,CAAC;YAC1B,cAAc,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;QAClD,CAAC;aAAM,IAAI,cAAc,EAAE,CAAC;YAC1B,IAAI,GAAG,YAAY,CAAC;YACpB,cAAc,GAAG,QAAQ,CAAC;YAC1B,cAAc,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;QAC7C,CAAC;aAAM,CAAC;YACN,IAAI,GAAG,UAAU,CAAC,CAAC,WAAW;YAC9B,cAAc,GAAG,KAAK,CAAC;YACvB,cAAc,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAAC;QACnE,CAAC;IACH,CAAC;IAED,iBAAiB;IACjB,MAAM,QAAQ,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;IACnC,MAAM,aAAa,GAAG,IAAI,EAAE,WAAW,KAAK,QAAQ,CAAC;IACrD,MAAM,iBAAiB,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;IAC9E,MAAM,MAAM,GAAgB;QAC1B,SAAS,EAAE,iBAAiB,IAAI,yCAAyC,CAAC,IAAI,CAAC,QAAQ,CAAC;QACxF,SAAS,EAAE,mDAAmD,CAAC,IAAI,CAAC,QAAQ,CAAC;QAC7E,iBAAiB,EAAE,uDAAuD,CAAC,IAAI,CAAC,QAAQ,CAAC;eACpF,sCAAsC,CAAC,IAAI,CAAC,QAAQ,CAAC;QAC1D,SAAS,EAAE,aAAa,IAAI,2CAA2C,CAAC,IAAI,CAAC,QAAQ,CAAC;QACtF,UAAU,EAAE,aAAa,IAAI,sDAAsD,CAAC,IAAI,CAAC,QAAQ,CAAC;QAClG,kBAAkB,EAAE,4EAA4E,CAAC,IAAI,CAAC,QAAQ,CAAC;QAC/G,UAAU,EAAE,sCAAsC,CAAC,IAAI,CAAC,QAAQ,CAAC;KAClE,CAAC;IAEF,4FAA4F;IAC5F,MAAM,EAAE,KAAK,EAAE,gBAAgB,EAAE,OAAO,EAAE,aAAa,EAAE,GACvD,gBAAgB,CAAC,oBAAoB,EAAE,CAAC,GAAG,QAAQ,EAAE,GAAG,UAAU,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IACxF,oBAAoB,CAAC,IAAI,CAAC,GAAG,gBAAgB,CAAC,CAAC;IAC/C,cAAc,CAAC,IAAI,CAAC,GAAG,aAAa,CAAC,CAAC;IAEtC,OAAO;QACL,GAAG;QACH,QAAQ;QACR,OAAO;QACP,gBAAgB;QAChB,iBAAiB;QACjB,UAAU;QACV,YAAY;QACZ,oBAAoB;QACpB,MAAM;QACN,OAAO,EAAE,EAAE,EAAE,qCAAqC;QAClD,IAAI;QACJ,cAAc;QACd,cAAc;KACf,CAAC;AACJ,CAAC;AAED,SAAS,cAAc,CAAC,GAAW;IACjC,oDAAoD;IACpD,MAAM,KAAK,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACzE,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC1C,OAAO,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC;IAC9C,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -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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"}
|
|
@@ -2,8 +2,9 @@ import type { QueryIR, SearchPlan } from '../types.js';
|
|
|
2
2
|
/**
|
|
3
3
|
* Plan which retrievers to use based on the parsed query IR.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
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
|
|
8
9
|
*/
|
|
9
10
|
export declare function planQuery(ir: QueryIR): SearchPlan;
|
|
@@ -1,29 +1,36 @@
|
|
|
1
|
+
import { runAdapters } from '../adapters/registry.js';
|
|
1
2
|
/**
|
|
2
3
|
* Plan which retrievers to use based on the parsed query IR.
|
|
3
4
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
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
|
|
7
9
|
*/
|
|
8
10
|
export function planQuery(ir) {
|
|
11
|
+
// Step 1: Run adapters to populate recipes
|
|
12
|
+
const recipes = runAdapters(ir);
|
|
13
|
+
ir.recipes = recipes;
|
|
9
14
|
const retrievers = [];
|
|
10
15
|
const reasons = [];
|
|
16
|
+
let expandGraph = false;
|
|
17
|
+
// Step 2: Mode-based default retrievers
|
|
11
18
|
switch (ir.mode) {
|
|
12
19
|
case 'behavior':
|
|
13
20
|
retrievers.push('behavior');
|
|
14
21
|
reasons.push('behavior family matched — searching declarations by concept');
|
|
22
|
+
retrievers.push('doc');
|
|
23
|
+
reasons.push('doc retriever for narrative/comment bridge');
|
|
15
24
|
break;
|
|
16
25
|
case 'identifier':
|
|
17
26
|
retrievers.push('identifier');
|
|
18
27
|
reasons.push('exact identifier detected — searching usage sites');
|
|
19
|
-
// Also add structural if any predicates exist
|
|
20
28
|
if (ir.structuralPredicates.length > 0) {
|
|
21
29
|
retrievers.push('structural');
|
|
22
30
|
reasons.push('structural predicates found — will filter by code shape');
|
|
23
31
|
}
|
|
24
32
|
break;
|
|
25
33
|
case 'structural':
|
|
26
|
-
// Identifier + structural: locate by identifier, filter by structure
|
|
27
34
|
if (ir.exactIdentifiers.length > 0 || ir.dottedIdentifiers.length > 0) {
|
|
28
35
|
retrievers.push('identifier');
|
|
29
36
|
reasons.push('using identifier to locate candidate sites');
|
|
@@ -34,6 +41,8 @@ export function planQuery(ir) {
|
|
|
34
41
|
case 'mixed':
|
|
35
42
|
retrievers.push('behavior');
|
|
36
43
|
reasons.push('behavior retrieval for concept matching');
|
|
44
|
+
retrievers.push('doc');
|
|
45
|
+
reasons.push('doc retriever for narrative bridge');
|
|
37
46
|
if (ir.exactIdentifiers.length > 0 || ir.dottedIdentifiers.length > 0) {
|
|
38
47
|
retrievers.push('identifier');
|
|
39
48
|
reasons.push('identifier retrieval for exact API matches');
|
|
@@ -44,15 +53,39 @@ export function planQuery(ir) {
|
|
|
44
53
|
}
|
|
45
54
|
break;
|
|
46
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
|
+
}
|
|
47
78
|
// Ensure at least one retriever
|
|
48
79
|
if (retrievers.length === 0) {
|
|
49
80
|
retrievers.push('behavior');
|
|
50
|
-
|
|
81
|
+
retrievers.push('doc');
|
|
82
|
+
reasons.push('fallback: no specific signals, using behavior + doc search');
|
|
51
83
|
}
|
|
52
84
|
return {
|
|
53
85
|
mode: ir.mode,
|
|
54
86
|
retrievers,
|
|
55
87
|
reasons,
|
|
88
|
+
expandGraph,
|
|
56
89
|
};
|
|
57
90
|
}
|
|
58
91
|
//# sourceMappingURL=planQuery.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"planQuery.js","sourceRoot":"","sources":["../../../src/search/query/planQuery.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"planQuery.js","sourceRoot":"","sources":["../../../src/search/query/planQuery.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,16 +8,22 @@ export function assessConfidence(ranked, ir, plan) {
|
|
|
8
8
|
const top = ranked[0];
|
|
9
9
|
const multiSource = top.sources.length > 1;
|
|
10
10
|
const hasStructural = top.sources.includes('structural');
|
|
11
|
+
const hasGraph = top.sources.includes('graph');
|
|
12
|
+
const hasDoc = top.sources.includes('doc');
|
|
11
13
|
const highScore = top.score >= 15;
|
|
12
14
|
const hasOverlap = top.evidence.some((e) => e.includes('overlap'));
|
|
13
15
|
if (multiSource && highScore)
|
|
14
16
|
return 'high';
|
|
15
17
|
if (hasStructural && top.score >= 10)
|
|
16
18
|
return 'high';
|
|
19
|
+
if (hasGraph && top.score >= 10)
|
|
20
|
+
return 'high';
|
|
17
21
|
if (hasOverlap)
|
|
18
22
|
return 'high';
|
|
19
23
|
if (highScore)
|
|
20
24
|
return 'medium';
|
|
25
|
+
if (hasDoc && top.score >= 8)
|
|
26
|
+
return 'medium';
|
|
21
27
|
if (ir.modeConfidence === 'low')
|
|
22
28
|
return 'low';
|
|
23
29
|
return 'medium';
|
|
@@ -1 +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,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,UAAU;QAAE,OAAO,MAAM,CAAC;IAC9B,IAAI,SAAS;QAAE,OAAO,QAAQ,CAAC;IAC/B,IAAI,EAAE,CAAC,cAAc,KAAK,KAAK;QAAE,OAAO,KAAK,CAAC;IAE9C,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
|
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[];
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Coalesce candidates that represent the same logical match.
|
|
3
|
+
* Merges doc + declaration, usage + pattern, etc. at the same location/symbol.
|
|
4
|
+
*
|
|
5
|
+
* This runs after retriever merge and before ranking, preventing
|
|
6
|
+
* duplicate entries for the same symbol from different retriever types.
|
|
7
|
+
*/
|
|
8
|
+
export function coalesceCandidates(candidates) {
|
|
9
|
+
const coalesced = new Map();
|
|
10
|
+
for (const c of candidates) {
|
|
11
|
+
const key = coalesceKey(c);
|
|
12
|
+
const existing = coalesced.get(key);
|
|
13
|
+
if (existing) {
|
|
14
|
+
// Merge: keep the higher score, combine evidence and sources
|
|
15
|
+
existing.score = Math.max(existing.score, c.score) + 2; // coalesce bonus
|
|
16
|
+
existing.evidence.push(...c.evidence, `coalesced: ${c.candidateType}`);
|
|
17
|
+
for (const s of c.sources) {
|
|
18
|
+
if (!existing.sources.includes(s))
|
|
19
|
+
existing.sources.push(s);
|
|
20
|
+
}
|
|
21
|
+
// Prefer longer snippet/context
|
|
22
|
+
if (c.snippet && (!existing.snippet || c.snippet.length > existing.snippet.length)) {
|
|
23
|
+
existing.snippet = c.snippet;
|
|
24
|
+
existing.context = c.context;
|
|
25
|
+
}
|
|
26
|
+
// Prefer declaration type over doc type
|
|
27
|
+
if (c.candidateType === 'declaration' && existing.candidateType === 'doc') {
|
|
28
|
+
existing.candidateType = 'declaration';
|
|
29
|
+
existing.kind = c.kind;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
coalesced.set(key, { ...c });
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return [...coalesced.values()];
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Coalesce key: same file + same line (within 2 lines) + same symbol.
|
|
40
|
+
* Does NOT include candidateType — that's the whole point.
|
|
41
|
+
*/
|
|
42
|
+
function coalesceKey(c) {
|
|
43
|
+
// Round line to nearest 2 to catch doc comments 1-2 lines above the declaration
|
|
44
|
+
const roundedLine = Math.floor(c.line / 3) * 3;
|
|
45
|
+
const symbol = c.symbol ?? c.matchedIdentifier ?? '';
|
|
46
|
+
return `${c.filePath}:${roundedLine}:${symbol}`;
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=coalesceCandidates.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coalesceCandidates.js","sourceRoot":"","sources":["../../../src/search/ranking/coalesceCandidates.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAAC,UAA2B;IAC5D,MAAM,SAAS,GAAG,IAAI,GAAG,EAAyB,CAAC;IAEnD,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;QAC3B,MAAM,GAAG,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;QAC3B,MAAM,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAEpC,IAAI,QAAQ,EAAE,CAAC;YACb,6DAA6D;YAC7D,QAAQ,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,iBAAiB;YACzE,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC,aAAa,EAAE,CAAC,CAAC;YACvE,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC;gBAC1B,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;oBAAE,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAC9D,CAAC;YACD,gCAAgC;YAChC,IAAI,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC,OAAO,CAAC,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;gBACnF,QAAQ,CAAC,OAAO,GAAG,CAAC,CAAC,OAAO,CAAC;gBAC7B,QAAQ,CAAC,OAAO,GAAG,CAAC,CAAC,OAAO,CAAC;YAC/B,CAAC;YACD,wCAAwC;YACxC,IAAI,CAAC,CAAC,aAAa,KAAK,aAAa,IAAI,QAAQ,CAAC,aAAa,KAAK,KAAK,EAAE,CAAC;gBAC1E,QAAQ,CAAC,aAAa,GAAG,aAAa,CAAC;gBACvC,QAAQ,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC;YACzB,CAAC;QACH,CAAC;aAAM,CAAC;YACN,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;QAC/B,CAAC;IACH,CAAC;IAED,OAAO,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC;AACjC,CAAC;AAED;;;GAGG;AACH,SAAS,WAAW,CAAC,CAAgB;IACnC,gFAAgF;IAChF,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;IAC/C,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,iBAAiB,IAAI,EAAE,CAAC;IACrD,OAAO,GAAG,CAAC,CAAC,QAAQ,IAAI,WAAW,IAAI,MAAM,EAAE,CAAC;AAClD,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fielded text scorer — lightweight BM25-inspired local ranker.
|
|
3
|
+
* Scores documents with multiple named fields against query tokens.
|
|
4
|
+
*/
|
|
5
|
+
export interface FieldedDocument {
|
|
6
|
+
id: string;
|
|
7
|
+
fields: Record<string, string[]>;
|
|
8
|
+
}
|
|
9
|
+
export interface FieldedScore {
|
|
10
|
+
id: string;
|
|
11
|
+
score: number;
|
|
12
|
+
evidence: string[];
|
|
13
|
+
}
|
|
14
|
+
export interface FieldWeights {
|
|
15
|
+
symbol: number;
|
|
16
|
+
path: number;
|
|
17
|
+
docs: number;
|
|
18
|
+
tests: number;
|
|
19
|
+
config?: number;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Score query tokens against fielded documents.
|
|
23
|
+
* Uses a simplified BM25-like scoring: term frequency within fields,
|
|
24
|
+
* weighted by field importance, with length normalization.
|
|
25
|
+
*/
|
|
26
|
+
export declare function scoreFieldedQuery(queryTokens: string[], docs: FieldedDocument[], weights?: Partial<FieldWeights>, limit?: number): FieldedScore[];
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fielded text scorer — lightweight BM25-inspired local ranker.
|
|
3
|
+
* Scores documents with multiple named fields against query tokens.
|
|
4
|
+
*/
|
|
5
|
+
const DEFAULT_WEIGHTS = {
|
|
6
|
+
symbol: 8,
|
|
7
|
+
path: 3,
|
|
8
|
+
docs: 5,
|
|
9
|
+
tests: 4,
|
|
10
|
+
config: 3,
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Score query tokens against fielded documents.
|
|
14
|
+
* Uses a simplified BM25-like scoring: term frequency within fields,
|
|
15
|
+
* weighted by field importance, with length normalization.
|
|
16
|
+
*/
|
|
17
|
+
export function scoreFieldedQuery(queryTokens, docs, weights, limit = 100) {
|
|
18
|
+
const w = { ...DEFAULT_WEIGHTS, ...weights };
|
|
19
|
+
const results = [];
|
|
20
|
+
// Compute average field lengths for normalization
|
|
21
|
+
const avgLengths = {};
|
|
22
|
+
const fieldNames = new Set();
|
|
23
|
+
for (const doc of docs) {
|
|
24
|
+
for (const [field, tokens] of Object.entries(doc.fields)) {
|
|
25
|
+
fieldNames.add(field);
|
|
26
|
+
avgLengths[field] = (avgLengths[field] ?? 0) + tokens.length;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
for (const field of fieldNames) {
|
|
30
|
+
avgLengths[field] = docs.length > 0 ? avgLengths[field] / docs.length : 1;
|
|
31
|
+
}
|
|
32
|
+
// IDF: tokens that appear in fewer docs are more valuable
|
|
33
|
+
const docFreq = {};
|
|
34
|
+
for (const tok of queryTokens) {
|
|
35
|
+
docFreq[tok] = 0;
|
|
36
|
+
for (const doc of docs) {
|
|
37
|
+
const allTokens = Object.values(doc.fields).flat();
|
|
38
|
+
if (allTokens.some((t) => t === tok || t.startsWith(tok) || tok.startsWith(t))) {
|
|
39
|
+
docFreq[tok]++;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
const N = docs.length || 1;
|
|
44
|
+
for (const doc of docs) {
|
|
45
|
+
let totalScore = 0;
|
|
46
|
+
const evidence = [];
|
|
47
|
+
for (const tok of queryTokens) {
|
|
48
|
+
const idf = Math.log((N - docFreq[tok] + 0.5) / (docFreq[tok] + 0.5) + 1);
|
|
49
|
+
for (const [field, tokens] of Object.entries(doc.fields)) {
|
|
50
|
+
const fieldWeight = w[field] ?? 1;
|
|
51
|
+
const avgLen = avgLengths[field] || 1;
|
|
52
|
+
const k1 = 1.2;
|
|
53
|
+
const b = 0.75;
|
|
54
|
+
// Count matches (exact + prefix)
|
|
55
|
+
let tf = 0;
|
|
56
|
+
for (const t of tokens) {
|
|
57
|
+
if (t === tok)
|
|
58
|
+
tf += 1;
|
|
59
|
+
else if (t.startsWith(tok) || tok.startsWith(t))
|
|
60
|
+
tf += 0.5;
|
|
61
|
+
}
|
|
62
|
+
if (tf === 0)
|
|
63
|
+
continue;
|
|
64
|
+
// BM25 TF component with length normalization
|
|
65
|
+
const lenNorm = 1 - b + b * (tokens.length / avgLen);
|
|
66
|
+
const tfScore = (tf * (k1 + 1)) / (tf + k1 * lenNorm);
|
|
67
|
+
const fieldScore = idf * tfScore * fieldWeight;
|
|
68
|
+
totalScore += fieldScore;
|
|
69
|
+
evidence.push(`${field}:${tok}(${fieldScore.toFixed(1)})`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
if (totalScore > 0) {
|
|
73
|
+
results.push({ id: doc.id, score: totalScore, evidence });
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
results.sort((a, b) => b.score - a.score);
|
|
77
|
+
return results.slice(0, limit);
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=fieldedTextRanker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fieldedTextRanker.js","sourceRoot":"","sources":["../../../src/search/ranking/fieldedTextRanker.ts"],"names":[],"mappings":"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"}
|
|
@@ -41,6 +41,45 @@ export function mergeCandidates(inputs) {
|
|
|
41
41
|
merged.set(key, { ...c });
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
|
+
// Merge regex candidates — boost on overlap
|
|
45
|
+
for (const c of inputs.regex) {
|
|
46
|
+
const key = candidateKey(c);
|
|
47
|
+
const existing = merged.get(key);
|
|
48
|
+
if (existing) {
|
|
49
|
+
existing.score += c.score + 2;
|
|
50
|
+
existing.evidence.push(...c.evidence, 'regex-overlap');
|
|
51
|
+
for (const s of c.sources) {
|
|
52
|
+
if (!existing.sources.includes(s))
|
|
53
|
+
existing.sources.push(s);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
merged.set(key, { ...c });
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
// Merge doc candidates — boost on overlap with behavior/identifier
|
|
61
|
+
for (const c of inputs.doc) {
|
|
62
|
+
const key = candidateKey(c);
|
|
63
|
+
const existing = merged.get(key);
|
|
64
|
+
if (existing) {
|
|
65
|
+
existing.score += Math.round(c.score * 0.5) + 2; // lighter boost for doc overlap
|
|
66
|
+
existing.evidence.push(...c.evidence, 'doc-overlap');
|
|
67
|
+
for (const s of c.sources) {
|
|
68
|
+
if (!existing.sources.includes(s))
|
|
69
|
+
existing.sources.push(s);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
merged.set(key, { ...c });
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
// Add config candidates (typically no overlap with code candidates)
|
|
77
|
+
for (const c of inputs.config) {
|
|
78
|
+
const key = candidateKey(c);
|
|
79
|
+
if (!merged.has(key)) {
|
|
80
|
+
merged.set(key, { ...c });
|
|
81
|
+
}
|
|
82
|
+
}
|
|
44
83
|
return [...merged.values()];
|
|
45
84
|
}
|
|
46
85
|
//# sourceMappingURL=mergeCandidates.js.map
|