lsp-intelligence 0.1.2 → 0.2.0
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 +12 -7
- package/dist/analysis/pattern/collectSearchFiles.d.ts +5 -0
- package/dist/analysis/pattern/collectSearchFiles.js +38 -0
- package/dist/analysis/pattern/collectSearchFiles.js.map +1 -0
- package/dist/analysis/pattern/runPatternSearch.d.ts +17 -0
- package/dist/analysis/pattern/runPatternSearch.js +63 -0
- package/dist/analysis/pattern/runPatternSearch.js.map +1 -0
- package/dist/analysis/ts/extractDeclarations.d.ts +7 -0
- package/dist/analysis/ts/extractDeclarations.js +93 -0
- package/dist/analysis/ts/extractDeclarations.js.map +1 -0
- package/dist/analysis/ts/extractUsages.d.ts +7 -0
- package/dist/analysis/ts/extractUsages.js +120 -0
- package/dist/analysis/ts/extractUsages.js.map +1 -0
- package/dist/analysis/ts/parseSourceFile.d.ts +10 -0
- package/dist/analysis/ts/parseSourceFile.js +28 -0
- package/dist/analysis/ts/parseSourceFile.js.map +1 -0
- package/dist/analysis/ts/snippets.d.ts +14 -0
- package/dist/analysis/ts/snippets.js +29 -0
- package/dist/analysis/ts/snippets.js.map +1 -0
- package/dist/analysis/ts/structuralPredicates.d.ts +10 -0
- package/dist/analysis/ts/structuralPredicates.js +170 -0
- package/dist/analysis/ts/structuralPredicates.js.map +1 -0
- package/dist/ast/diffDeclarationShapes.d.ts +16 -0
- package/dist/ast/diffDeclarationShapes.js +179 -0
- package/dist/ast/diffDeclarationShapes.js.map +1 -0
- package/dist/ast/extractExportDeclarations.d.ts +21 -0
- package/dist/ast/extractExportDeclarations.js +218 -0
- package/dist/ast/extractExportDeclarations.js.map +1 -0
- package/dist/ast/findNodeAtPosition.d.ts +12 -0
- package/dist/ast/findNodeAtPosition.js +75 -0
- package/dist/ast/findNodeAtPosition.js.map +1 -0
- package/dist/ast/parseFile.d.ts +10 -0
- package/dist/ast/parseFile.js +29 -0
- package/dist/ast/parseFile.js.map +1 -0
- package/dist/engine/waitForDiagnostics.d.ts +7 -0
- package/dist/engine/waitForDiagnostics.js +16 -0
- package/dist/engine/waitForDiagnostics.js.map +1 -0
- package/dist/git/getBaseFileContent.d.ts +5 -0
- package/dist/git/getBaseFileContent.js +16 -0
- package/dist/git/getBaseFileContent.js.map +1 -0
- package/dist/git/getChangedFiles.d.ts +4 -0
- package/dist/git/getChangedFiles.js +21 -0
- package/dist/git/getChangedFiles.js.map +1 -0
- package/dist/git/getChangedHunks.d.ts +13 -0
- package/dist/git/getChangedHunks.js +51 -0
- package/dist/git/getChangedHunks.js.map +1 -0
- package/dist/git/getMergeBase.d.ts +5 -0
- package/dist/git/getMergeBase.js +23 -0
- package/dist/git/getMergeBase.js.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -1
- package/dist/resolve/searchScope.d.ts +11 -0
- package/dist/resolve/searchScope.js +52 -0
- package/dist/resolve/searchScope.js.map +1 -0
- package/dist/resolve/targetResolver.d.ts +33 -0
- package/dist/resolve/targetResolver.js +84 -0
- package/dist/resolve/targetResolver.js.map +1 -0
- package/dist/search/families/behaviorFamilies.d.ts +22 -0
- package/dist/search/families/behaviorFamilies.js +90 -0
- package/dist/search/families/behaviorFamilies.js.map +1 -0
- package/dist/search/index/declarationIndex.d.ts +6 -0
- package/dist/search/index/declarationIndex.js +13 -0
- package/dist/search/index/declarationIndex.js.map +1 -0
- package/dist/search/index/types.d.ts +1 -0
- package/dist/search/index/types.js +2 -0
- package/dist/search/index/types.js.map +1 -0
- package/dist/search/index/usageIndex.d.ts +6 -0
- package/dist/search/index/usageIndex.js +13 -0
- package/dist/search/index/usageIndex.js.map +1 -0
- package/dist/search/index/workspaceIndex.d.ts +8 -0
- package/dist/search/index/workspaceIndex.js +91 -0
- package/dist/search/index/workspaceIndex.js.map +1 -0
- package/dist/search/query/parseQuery.d.ts +9 -0
- package/dist/search/query/parseQuery.js +244 -0
- package/dist/search/query/parseQuery.js.map +1 -0
- package/dist/search/query/planQuery.d.ts +9 -0
- package/dist/search/query/planQuery.js +58 -0
- package/dist/search/query/planQuery.js.map +1 -0
- package/dist/search/ranking/assessConfidence.d.ts +6 -0
- package/dist/search/ranking/assessConfidence.js +25 -0
- package/dist/search/ranking/assessConfidence.js.map +1 -0
- package/dist/search/ranking/mergeCandidates.d.ts +10 -0
- package/dist/search/ranking/mergeCandidates.js +46 -0
- package/dist/search/ranking/mergeCandidates.js.map +1 -0
- package/dist/search/ranking/rankCandidates.d.ts +12 -0
- package/dist/search/ranking/rankCandidates.js +58 -0
- package/dist/search/ranking/rankCandidates.js.map +1 -0
- package/dist/search/retrievers/behaviorRetriever.d.ts +7 -0
- package/dist/search/retrievers/behaviorRetriever.js +91 -0
- package/dist/search/retrievers/behaviorRetriever.js.map +1 -0
- package/dist/search/retrievers/identifierRetriever.d.ts +7 -0
- package/dist/search/retrievers/identifierRetriever.js +66 -0
- package/dist/search/retrievers/identifierRetriever.js.map +1 -0
- package/dist/search/retrievers/structuralRetriever.d.ts +11 -0
- package/dist/search/retrievers/structuralRetriever.js +141 -0
- package/dist/search/retrievers/structuralRetriever.js.map +1 -0
- package/dist/search/types.d.ts +121 -0
- package/dist/search/types.js +11 -0
- package/dist/search/types.js.map +1 -0
- package/dist/tools/composites/apiGuard.d.ts +1 -0
- package/dist/tools/composites/apiGuard.js +194 -0
- package/dist/tools/composites/apiGuard.js.map +1 -0
- package/dist/tools/composites/explainError.js +3 -2
- package/dist/tools/composites/explainError.js.map +1 -1
- package/dist/tools/composites/findCode.d.ts +1 -0
- package/dist/tools/composites/findCode.js +68 -0
- package/dist/tools/composites/findCode.js.map +1 -0
- package/dist/tools/composites/findPattern.d.ts +5 -0
- package/dist/tools/composites/findPattern.js +41 -0
- package/dist/tools/composites/findPattern.js.map +1 -0
- package/dist/tools/composites/rootCauseTrace.d.ts +1 -0
- package/dist/tools/composites/rootCauseTrace.js +213 -0
- package/dist/tools/composites/rootCauseTrace.js.map +1 -0
- package/dist/tools/composites/semanticDiff.js +24 -77
- package/dist/tools/composites/semanticDiff.js.map +1 -1
- package/dist/tools/live/liveDiagnostics.js +3 -2
- package/dist/tools/live/liveDiagnostics.js.map +1 -1
- package/dist/tools/primitives/diagnostics.js +2 -2
- package/dist/tools/primitives/diagnostics.js.map +1 -1
- package/dist/tools/registry.d.ts +10 -2
- package/dist/tools/registry.js +7 -2
- package/dist/tools/registry.js.map +1 -1
- package/package.json +8 -4
- package/dist/tools/primitives/typeHierarchy.d.ts +0 -1
- package/dist/tools/primitives/typeHierarchy.js +0 -55
- package/dist/tools/primitives/typeHierarchy.js.map +0 -1
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Behavior families — redesigned with classifier/expansion split.
|
|
3
|
+
*
|
|
4
|
+
* classifierTerms: strong terms only. Weak words (use, get, set, call, run, make)
|
|
5
|
+
* must NEVER appear here. These drive mode routing.
|
|
6
|
+
*
|
|
7
|
+
* expansionTerms: broader lexical expansion for recall. May include weaker terms.
|
|
8
|
+
*/
|
|
9
|
+
export const BEHAVIOR_FAMILIES = [
|
|
10
|
+
{
|
|
11
|
+
id: 'auth_permission',
|
|
12
|
+
classifierTerms: ['permission', 'auth', 'authorize', 'guard', 'access', 'role', 'acl'],
|
|
13
|
+
expansionTerms: ['can', 'allow', 'deny', 'policy', 'privilege', 'protect', 'secure'],
|
|
14
|
+
fileHints: ['auth', 'permission', 'guard', 'access', 'policy', 'acl'],
|
|
15
|
+
symbolHints: ['permission', 'guard', 'authorize', 'protect', 'allow'],
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
id: 'validation',
|
|
19
|
+
classifierTerms: ['valid', 'validate', 'verify', 'assert', 'sanitize', 'schema'],
|
|
20
|
+
expansionTerms: ['parse', 'conform', 'ensure', 'require', 'constraint', 'check'],
|
|
21
|
+
fileHints: ['valid', 'verify', 'assert', 'sanitize', 'schema'],
|
|
22
|
+
symbolHints: ['valid', 'verify', 'assert', 'schema'],
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
id: 'error_handling',
|
|
26
|
+
classifierTerms: ['error', 'exception', 'boundary', 'recover', 'fallback'],
|
|
27
|
+
expansionTerms: ['fail', 'throw', 'sentinel', 'catch', 'handle'],
|
|
28
|
+
fileHints: ['error', 'handler', 'boundary', 'fallback', 'recovery'],
|
|
29
|
+
symbolHints: ['error', 'handle', 'recover', 'fallback', 'boundary'],
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
id: 'fetching',
|
|
33
|
+
classifierTerms: ['fetch', 'endpoint', 'api', 'request', 'http'],
|
|
34
|
+
expansionTerms: ['load', 'query', 'download', 'post', 'ajax', 'invoke'],
|
|
35
|
+
fileHints: ['api', 'fetch', 'service', 'client', 'endpoint', 'request'],
|
|
36
|
+
symbolHints: ['fetch', 'api', 'endpoint', 'request', 'service'],
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
id: 'state_management',
|
|
40
|
+
classifierTerms: ['redux', 'store', 'reducer', 'slice', 'dispatch'],
|
|
41
|
+
expansionTerms: ['action', 'thunk', 'selector', 'middleware', 'subscribe', 'state'],
|
|
42
|
+
fileHints: ['store', 'reducer', 'slice', 'duck', 'redux'],
|
|
43
|
+
symbolHints: ['reducer', 'slice', 'dispatch', 'selector', 'thunk'],
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
id: 'feature_flags',
|
|
47
|
+
classifierTerms: ['feature', 'flag', 'toggle', 'experiment', 'launch'],
|
|
48
|
+
expansionTerms: ['switch', 'variant', 'rollout', 'canary', 'gate', 'dark'],
|
|
49
|
+
fileHints: ['feature', 'flag', 'toggle', 'gate', 'experiment'],
|
|
50
|
+
symbolHints: ['feature', 'flag', 'toggle', 'gate', 'enabled'],
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
id: 'retry_backoff',
|
|
54
|
+
classifierTerms: ['retry', 'backoff', 'debounce', 'throttle', 'ratelimit'],
|
|
55
|
+
expansionTerms: ['exponential', 'delay', 'cooldown', 'timeout', 'interval', 'limit'],
|
|
56
|
+
fileHints: ['retry', 'backoff', 'throttle', 'debounce', 'rate'],
|
|
57
|
+
symbolHints: ['retry', 'backoff', 'debounce', 'throttle', 'delay'],
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
id: 'caching',
|
|
61
|
+
classifierTerms: ['cache', 'memoize', 'persist', 'ttl', 'lru'],
|
|
62
|
+
expansionTerms: ['memo', 'invalidate', 'expire', 'warm', 'preload', 'stale', 'store'],
|
|
63
|
+
fileHints: ['cache', 'memo', 'persist', 'storage'],
|
|
64
|
+
symbolHints: ['cache', 'memo', 'memoize', 'persist'],
|
|
65
|
+
},
|
|
66
|
+
];
|
|
67
|
+
/**
|
|
68
|
+
* Score a set of tokens against all families.
|
|
69
|
+
* Uses only classifierTerms for strong matching.
|
|
70
|
+
* Returns per-family scores.
|
|
71
|
+
*/
|
|
72
|
+
export function scoreFamilies(tokens) {
|
|
73
|
+
const scores = {};
|
|
74
|
+
for (const family of BEHAVIOR_FAMILIES) {
|
|
75
|
+
let score = 0;
|
|
76
|
+
for (const token of tokens) {
|
|
77
|
+
// Classifier terms: strong match
|
|
78
|
+
for (const ct of family.classifierTerms) {
|
|
79
|
+
if (ct === token)
|
|
80
|
+
score += 3;
|
|
81
|
+
else if (ct.startsWith(token) || token.startsWith(ct))
|
|
82
|
+
score += 1;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
if (score > 0)
|
|
86
|
+
scores[family.id] = score;
|
|
87
|
+
}
|
|
88
|
+
return scores;
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=behaviorFamilies.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"behaviorFamilies.js","sourceRoot":"","sources":["../../../src/search/families/behaviorFamilies.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { parseSourceFile } from '../../analysis/ts/parseSourceFile.js';
|
|
2
|
+
import { extractDeclarations } from '../../analysis/ts/extractDeclarations.js';
|
|
3
|
+
/**
|
|
4
|
+
* Build declaration index entries for a single file.
|
|
5
|
+
* Uses TypeScript compiler AST, not regex.
|
|
6
|
+
*/
|
|
7
|
+
export function indexFileDeclarations(filePath) {
|
|
8
|
+
const sf = parseSourceFile(filePath);
|
|
9
|
+
if (!sf)
|
|
10
|
+
return [];
|
|
11
|
+
return extractDeclarations(sf);
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=declarationIndex.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"declarationIndex.js","sourceRoot":"","sources":["../../../src/search/index/declarationIndex.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AACvE,OAAO,EAAE,mBAAmB,EAAE,MAAM,0CAA0C,CAAC;AAG/E;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CAAC,QAAgB;IACpD,MAAM,EAAE,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;IACrC,IAAI,CAAC,EAAE;QAAE,OAAO,EAAE,CAAC;IACnB,OAAO,mBAAmB,CAAC,EAAE,CAAC,CAAC;AACjC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type { DeclarationIndexEntry, UsageIndexEntry, IndexedFile, WorkspaceIndex, } from '../types.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/search/index/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { UsageIndexEntry } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Build usage index entries for a single file.
|
|
4
|
+
* Indexes call expressions, member calls, imports, JSX tags using TS compiler AST.
|
|
5
|
+
*/
|
|
6
|
+
export declare function indexFileUsages(filePath: string): UsageIndexEntry[];
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { parseSourceFile } from '../../analysis/ts/parseSourceFile.js';
|
|
2
|
+
import { extractUsages } from '../../analysis/ts/extractUsages.js';
|
|
3
|
+
/**
|
|
4
|
+
* Build usage index entries for a single file.
|
|
5
|
+
* Indexes call expressions, member calls, imports, JSX tags using TS compiler AST.
|
|
6
|
+
*/
|
|
7
|
+
export function indexFileUsages(filePath) {
|
|
8
|
+
const sf = parseSourceFile(filePath);
|
|
9
|
+
if (!sf)
|
|
10
|
+
return [];
|
|
11
|
+
return extractUsages(sf);
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=usageIndex.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usageIndex.js","sourceRoot":"","sources":["../../../src/search/index/usageIndex.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AACvE,OAAO,EAAE,aAAa,EAAE,MAAM,oCAAoC,CAAC;AAGnE;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,QAAgB;IAC9C,MAAM,EAAE,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;IACrC,IAAI,CAAC,EAAE;QAAE,OAAO,EAAE,CAAC;IACnB,OAAO,aAAa,CAAC,EAAE,CAAC,CAAC;AAC3B,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { SearchScope, WorkspaceIndex } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Get or build a workspace index for the given scope.
|
|
4
|
+
* Uses per-file mtime to invalidate stale entries — no TTL.
|
|
5
|
+
*/
|
|
6
|
+
export declare function getWorkspaceIndex(scope: SearchScope, opts?: {
|
|
7
|
+
forceRefresh?: boolean;
|
|
8
|
+
}): WorkspaceIndex;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import * as fs from 'fs';
|
|
2
|
+
import { collectScopeFiles } from '../../resolve/searchScope.js';
|
|
3
|
+
import { indexFileDeclarations } from './declarationIndex.js';
|
|
4
|
+
import { indexFileUsages } from './usageIndex.js';
|
|
5
|
+
// Per-workspace cache with per-file mtime invalidation
|
|
6
|
+
let cachedIndex = null;
|
|
7
|
+
/**
|
|
8
|
+
* Get or build a workspace index for the given scope.
|
|
9
|
+
* Uses per-file mtime to invalidate stale entries — no TTL.
|
|
10
|
+
*/
|
|
11
|
+
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;
|
|
17
|
+
}
|
|
18
|
+
// Incremental: check mtime per file, re-index changed files
|
|
19
|
+
const scopeFiles = collectScopeFiles(scope);
|
|
20
|
+
let changed = false;
|
|
21
|
+
for (const filePath of scopeFiles) {
|
|
22
|
+
try {
|
|
23
|
+
const mtime = fs.statSync(filePath).mtimeMs;
|
|
24
|
+
const existing = cachedIndex.files.get(filePath);
|
|
25
|
+
if (!existing || existing.mtimeMs !== mtime) {
|
|
26
|
+
// File is new or changed — re-index
|
|
27
|
+
const declarations = indexFileDeclarations(filePath);
|
|
28
|
+
const usages = indexFileUsages(filePath);
|
|
29
|
+
cachedIndex.files.set(filePath, { filePath, mtimeMs: mtime, declarations, usages });
|
|
30
|
+
changed = true;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
// File may have been deleted
|
|
35
|
+
if (cachedIndex.files.has(filePath)) {
|
|
36
|
+
cachedIndex.files.delete(filePath);
|
|
37
|
+
changed = true;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
// Remove files no longer in scope
|
|
42
|
+
const scopeSet = new Set(scopeFiles);
|
|
43
|
+
for (const key of cachedIndex.files.keys()) {
|
|
44
|
+
if (!scopeSet.has(key)) {
|
|
45
|
+
cachedIndex.files.delete(key);
|
|
46
|
+
changed = true;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
// Rebuild flat arrays if anything changed
|
|
50
|
+
if (changed) {
|
|
51
|
+
rebuildFlatArrays(cachedIndex);
|
|
52
|
+
}
|
|
53
|
+
return cachedIndex;
|
|
54
|
+
}
|
|
55
|
+
function buildFreshIndex(scope) {
|
|
56
|
+
const root = scope.roots[0] ?? '';
|
|
57
|
+
const files = new Map();
|
|
58
|
+
const scopeFiles = collectScopeFiles(scope);
|
|
59
|
+
for (const filePath of scopeFiles) {
|
|
60
|
+
try {
|
|
61
|
+
const mtime = fs.statSync(filePath).mtimeMs;
|
|
62
|
+
const declarations = indexFileDeclarations(filePath);
|
|
63
|
+
const usages = indexFileUsages(filePath);
|
|
64
|
+
files.set(filePath, { filePath, mtimeMs: mtime, declarations, usages });
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
// Skip files that can't be read/parsed
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
const index = {
|
|
71
|
+
root,
|
|
72
|
+
builtAt: Date.now(),
|
|
73
|
+
files,
|
|
74
|
+
declarations: [],
|
|
75
|
+
usages: [],
|
|
76
|
+
};
|
|
77
|
+
rebuildFlatArrays(index);
|
|
78
|
+
return index;
|
|
79
|
+
}
|
|
80
|
+
function rebuildFlatArrays(index) {
|
|
81
|
+
const declarations = [];
|
|
82
|
+
const usages = [];
|
|
83
|
+
for (const file of index.files.values()) {
|
|
84
|
+
declarations.push(...file.declarations);
|
|
85
|
+
usages.push(...file.usages);
|
|
86
|
+
}
|
|
87
|
+
index.declarations = declarations;
|
|
88
|
+
index.usages = usages;
|
|
89
|
+
index.builtAt = Date.now();
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=workspaceIndex.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspaceIndex.js","sourceRoot":"","sources":["../../../src/search/index/workspaceIndex.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
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
|
+
}): QueryIR;
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
import { scoreFamilies } from '../families/behaviorFamilies.js';
|
|
2
|
+
// Short family names (from find_code schema) → real family IDs
|
|
3
|
+
const FAMILY_ALIASES = {
|
|
4
|
+
auth: 'auth_permission',
|
|
5
|
+
errors: 'error_handling',
|
|
6
|
+
state: 'state_management',
|
|
7
|
+
flags: 'feature_flags',
|
|
8
|
+
retry: 'retry_backoff',
|
|
9
|
+
validation: 'validation',
|
|
10
|
+
fetching: 'fetching',
|
|
11
|
+
caching: 'caching',
|
|
12
|
+
};
|
|
13
|
+
// Structural cue words — preserved, NOT removed as stop words
|
|
14
|
+
const STRUCTURAL_CUES = new Set([
|
|
15
|
+
'conditional', 'conditionally', 'if', 'return', 'returns', 'cleanup',
|
|
16
|
+
'callback', 'without', 'inside', 'nested', 'loop', 'async', 'await',
|
|
17
|
+
'try', 'catch', 'switch', 'default', 'throw', 'promise',
|
|
18
|
+
]);
|
|
19
|
+
// NL stop words — only removed from the NL channel
|
|
20
|
+
const STOP_WORDS = new Set([
|
|
21
|
+
'a', 'an', 'the', 'is', 'are', 'was', 'were', 'be', 'been', 'being',
|
|
22
|
+
'have', 'has', 'had', 'do', 'does', 'did', 'will', 'would', 'could',
|
|
23
|
+
'should', 'may', 'might', 'can', 'shall', 'to', 'of', 'in', 'for',
|
|
24
|
+
'on', 'with', 'at', 'by', 'from', 'as', 'into', 'through', 'during',
|
|
25
|
+
'where', 'how', 'what', 'which', 'who', 'when', 'why',
|
|
26
|
+
'all', 'each', 'every', 'both', 'few', 'more', 'most', 'other',
|
|
27
|
+
'some', 'such', 'no', 'not', 'only', 'own', 'same', 'so', 'than',
|
|
28
|
+
'too', 'very', 'just', 'we', 'they', 'i', 'my', 'our', 'that',
|
|
29
|
+
'this', 'these', 'those', 'me', 'him', 'her', 'it', 'its',
|
|
30
|
+
]);
|
|
31
|
+
// Identifier pattern: camelCase, PascalCase, dotted (Promise.all, React.useEffect)
|
|
32
|
+
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;
|
|
33
|
+
// Hook name pattern
|
|
34
|
+
const HOOK_PATTERN = /^use[A-Z]/;
|
|
35
|
+
// Structural predicate mapping from cue words
|
|
36
|
+
const PREDICATE_MAP = {
|
|
37
|
+
conditional: ['conditional'],
|
|
38
|
+
conditionally: ['conditional'],
|
|
39
|
+
if: ['conditional'],
|
|
40
|
+
return: [], // phrase-based: only fires in combination (returns + cleanup, etc.)
|
|
41
|
+
returns: [], // phrase-based: only fires in combination
|
|
42
|
+
cleanup: [], // phrase-based: returns + cleanup → returns-cleanup
|
|
43
|
+
callback: [], // phrase-based: callback + hook identifier → hook-callback
|
|
44
|
+
try: ['has-try-catch'],
|
|
45
|
+
catch: ['has-try-catch'],
|
|
46
|
+
without: [], // modifier — inverts next predicate
|
|
47
|
+
loop: ['await-in-loop'],
|
|
48
|
+
switch: ['switch-no-default'],
|
|
49
|
+
default: ['switch-no-default'],
|
|
50
|
+
hook: ['inside-hook'],
|
|
51
|
+
nested: [],
|
|
52
|
+
async: [],
|
|
53
|
+
await: ['await-in-loop'],
|
|
54
|
+
promise: [],
|
|
55
|
+
throw: [],
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* Parse a raw query string into a structured QueryIR.
|
|
59
|
+
* Extracts three channels: NL tokens, exact identifiers, structural cues.
|
|
60
|
+
*/
|
|
61
|
+
export function parseQuery(raw, opts) {
|
|
62
|
+
const words = raw.split(/\s+/).filter(Boolean);
|
|
63
|
+
// --- Channel 1: Exact identifiers ---
|
|
64
|
+
const exactIdentifiers = [];
|
|
65
|
+
const dottedIdentifiers = [];
|
|
66
|
+
for (const word of words) {
|
|
67
|
+
const clean = word.replace(/[^a-zA-Z0-9.]/g, '');
|
|
68
|
+
if (!clean)
|
|
69
|
+
continue;
|
|
70
|
+
// Dotted identifier: Promise.all, React.useEffect
|
|
71
|
+
if (clean.includes('.') && /^[A-Za-z]/.test(clean)) {
|
|
72
|
+
dottedIdentifiers.push(clean);
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
// CamelCase/PascalCase identifier (not a plain lowercase word)
|
|
76
|
+
if (/^[A-Z]/.test(clean) || (HOOK_PATTERN.test(clean)) || (/[a-z][A-Z]/.test(clean) && clean.length > 3)) {
|
|
77
|
+
exactIdentifiers.push(clean);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
// --- Channel 2: Structural cues ---
|
|
81
|
+
const structuralPredicates = [];
|
|
82
|
+
const codeTokens = [];
|
|
83
|
+
const hasWithout = words.some((w) => w.toLowerCase() === 'without');
|
|
84
|
+
for (const word of words) {
|
|
85
|
+
const lower = word.toLowerCase().replace(/[^a-z]/g, '');
|
|
86
|
+
if (STRUCTURAL_CUES.has(lower)) {
|
|
87
|
+
codeTokens.push(lower);
|
|
88
|
+
const preds = PREDICATE_MAP[lower] ?? [];
|
|
89
|
+
for (const pred of preds) {
|
|
90
|
+
// Handle "without" modifier
|
|
91
|
+
if (hasWithout && pred === 'returns-cleanup') {
|
|
92
|
+
if (!structuralPredicates.includes('no-cleanup'))
|
|
93
|
+
structuralPredicates.push('no-cleanup');
|
|
94
|
+
}
|
|
95
|
+
else if (hasWithout && pred === 'has-try-catch') {
|
|
96
|
+
if (!structuralPredicates.includes('no-try-catch'))
|
|
97
|
+
structuralPredicates.push('no-try-catch');
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
if (!structuralPredicates.includes(pred))
|
|
101
|
+
structuralPredicates.push(pred);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
// Phrase-based structural inference — requires combinations, not isolated keywords.
|
|
107
|
+
// This prevents "returns" alone from implying returns-function.
|
|
108
|
+
const hasHookId = exactIdentifiers.some((id) => HOOK_PATTERN.test(id));
|
|
109
|
+
if (codeTokens.includes('cleanup')) {
|
|
110
|
+
if (codeTokens.includes('returns') || codeTokens.includes('return')) {
|
|
111
|
+
// "returns cleanup" or "return cleanup"
|
|
112
|
+
if (hasWithout) {
|
|
113
|
+
if (!structuralPredicates.includes('no-cleanup'))
|
|
114
|
+
structuralPredicates.push('no-cleanup');
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
if (!structuralPredicates.includes('returns-cleanup'))
|
|
118
|
+
structuralPredicates.push('returns-cleanup');
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
else if (hasWithout) {
|
|
122
|
+
// "without cleanup" (no returns keyword needed)
|
|
123
|
+
if (!structuralPredicates.includes('no-cleanup'))
|
|
124
|
+
structuralPredicates.push('no-cleanup');
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
if (codeTokens.includes('returns') || codeTokens.includes('return')) {
|
|
128
|
+
if (codeTokens.includes('callback') || hasHookId) {
|
|
129
|
+
// "returns callback" or "useEffect ... returns"
|
|
130
|
+
if (!structuralPredicates.includes('returns-function'))
|
|
131
|
+
structuralPredicates.push('returns-function');
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
if (codeTokens.includes('callback') && hasHookId) {
|
|
135
|
+
// "useEffect callback" — hook + callback together
|
|
136
|
+
if (!structuralPredicates.includes('hook-callback'))
|
|
137
|
+
structuralPredicates.push('hook-callback');
|
|
138
|
+
}
|
|
139
|
+
// Hook identifier + any structural predicates → add hook-callback context
|
|
140
|
+
if (hasHookId && structuralPredicates.length > 0) {
|
|
141
|
+
if (!structuralPredicates.includes('hook-callback')) {
|
|
142
|
+
structuralPredicates.push('hook-callback');
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
// --- Channel 3: NL tokens ---
|
|
146
|
+
const nlTokens = [];
|
|
147
|
+
for (const word of words) {
|
|
148
|
+
const lower = word.toLowerCase().replace(/[^a-z]/g, '');
|
|
149
|
+
if (!lower || lower.length < 2)
|
|
150
|
+
continue;
|
|
151
|
+
if (STOP_WORDS.has(lower))
|
|
152
|
+
continue;
|
|
153
|
+
// Don't add exact identifiers to NL channel
|
|
154
|
+
if (exactIdentifiers.includes(word) || dottedIdentifiers.includes(word))
|
|
155
|
+
continue;
|
|
156
|
+
nlTokens.push(lower);
|
|
157
|
+
}
|
|
158
|
+
// --- Phrases ---
|
|
159
|
+
const phrases = extractPhrases(raw);
|
|
160
|
+
// --- Family scoring ---
|
|
161
|
+
const allTerms = [...nlTokens, ...codeTokens];
|
|
162
|
+
let familyScores = scoreFamilies(allTerms);
|
|
163
|
+
// Apply forced family (resolve short alias → real ID)
|
|
164
|
+
if (opts?.forcedFamily) {
|
|
165
|
+
const resolvedFamily = FAMILY_ALIASES[opts.forcedFamily] ?? opts.forcedFamily;
|
|
166
|
+
familyScores[resolvedFamily] = (familyScores[resolvedFamily] ?? 0) + 10;
|
|
167
|
+
}
|
|
168
|
+
// --- Mode routing ---
|
|
169
|
+
const identifierScore = exactIdentifiers.length * 3 + dottedIdentifiers.length * 3;
|
|
170
|
+
const structuralScore = structuralPredicates.length * 2 + codeTokens.length;
|
|
171
|
+
const behaviorScore = Object.values(familyScores).reduce((s, v) => s + v, 0);
|
|
172
|
+
let mode;
|
|
173
|
+
let modeConfidence;
|
|
174
|
+
const routingReasons = [];
|
|
175
|
+
if (opts?.forcedMode && opts.forcedMode !== 'auto') {
|
|
176
|
+
mode = opts.forcedMode;
|
|
177
|
+
modeConfidence = 'high';
|
|
178
|
+
routingReasons.push(`forced mode: ${mode}`);
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
// Determine mode from scores
|
|
182
|
+
const hasIdentifiers = identifierScore > 0;
|
|
183
|
+
const hasStructural = structuralScore > 2;
|
|
184
|
+
const hasBehavior = behaviorScore > 2;
|
|
185
|
+
if (hasIdentifiers && hasStructural) {
|
|
186
|
+
mode = 'structural'; // identifier + structural = structural (use identifier to locate, predicates to filter)
|
|
187
|
+
modeConfidence = 'high';
|
|
188
|
+
routingReasons.push('exact identifier detected', 'structural cues detected');
|
|
189
|
+
}
|
|
190
|
+
else if (hasIdentifiers && !hasBehavior) {
|
|
191
|
+
mode = 'identifier';
|
|
192
|
+
modeConfidence = 'high';
|
|
193
|
+
routingReasons.push('exact identifier detected', 'no strong behavior-family evidence');
|
|
194
|
+
}
|
|
195
|
+
else if (hasBehavior && hasStructural) {
|
|
196
|
+
mode = 'mixed';
|
|
197
|
+
modeConfidence = 'medium';
|
|
198
|
+
routingReasons.push('behavior family matched', 'structural cues detected');
|
|
199
|
+
}
|
|
200
|
+
else if (hasBehavior) {
|
|
201
|
+
mode = 'behavior';
|
|
202
|
+
modeConfidence = behaviorScore > 5 ? 'high' : 'medium';
|
|
203
|
+
routingReasons.push('behavior family matched');
|
|
204
|
+
}
|
|
205
|
+
else if (hasStructural) {
|
|
206
|
+
mode = 'structural';
|
|
207
|
+
modeConfidence = 'medium';
|
|
208
|
+
routingReasons.push('structural cues detected');
|
|
209
|
+
}
|
|
210
|
+
else if (hasIdentifiers) {
|
|
211
|
+
mode = 'identifier';
|
|
212
|
+
modeConfidence = 'medium';
|
|
213
|
+
routingReasons.push('identifier detected');
|
|
214
|
+
}
|
|
215
|
+
else {
|
|
216
|
+
mode = 'behavior'; // fallback
|
|
217
|
+
modeConfidence = 'low';
|
|
218
|
+
routingReasons.push('no strong signals, defaulting to behavior');
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
return {
|
|
222
|
+
raw,
|
|
223
|
+
nlTokens,
|
|
224
|
+
phrases,
|
|
225
|
+
exactIdentifiers,
|
|
226
|
+
dottedIdentifiers,
|
|
227
|
+
codeTokens,
|
|
228
|
+
familyScores,
|
|
229
|
+
structuralPredicates,
|
|
230
|
+
mode,
|
|
231
|
+
modeConfidence,
|
|
232
|
+
routingReasons,
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
function extractPhrases(raw) {
|
|
236
|
+
// Extract 2-3 word phrases that might be meaningful
|
|
237
|
+
const words = raw.toLowerCase().split(/\s+/).filter((w) => w.length > 2);
|
|
238
|
+
const phrases = [];
|
|
239
|
+
for (let i = 0; i < words.length - 1; i++) {
|
|
240
|
+
phrases.push(`${words[i]} ${words[i + 1]}`);
|
|
241
|
+
}
|
|
242
|
+
return phrases;
|
|
243
|
+
}
|
|
244
|
+
//# 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,9 @@
|
|
|
1
|
+
import type { QueryIR, SearchPlan } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Plan which retrievers to use based on the parsed query IR.
|
|
4
|
+
*
|
|
5
|
+
* Key design rule: the planner can choose ['identifier', 'structural']
|
|
6
|
+
* WITHOUT behavior retrieval. This is the core fix for queries like
|
|
7
|
+
* "useEffect that returns a cleanup callback conditionally".
|
|
8
|
+
*/
|
|
9
|
+
export declare function planQuery(ir: QueryIR): SearchPlan;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plan which retrievers to use based on the parsed query IR.
|
|
3
|
+
*
|
|
4
|
+
* Key design rule: the planner can choose ['identifier', 'structural']
|
|
5
|
+
* WITHOUT behavior retrieval. This is the core fix for queries like
|
|
6
|
+
* "useEffect that returns a cleanup callback conditionally".
|
|
7
|
+
*/
|
|
8
|
+
export function planQuery(ir) {
|
|
9
|
+
const retrievers = [];
|
|
10
|
+
const reasons = [];
|
|
11
|
+
switch (ir.mode) {
|
|
12
|
+
case 'behavior':
|
|
13
|
+
retrievers.push('behavior');
|
|
14
|
+
reasons.push('behavior family matched — searching declarations by concept');
|
|
15
|
+
break;
|
|
16
|
+
case 'identifier':
|
|
17
|
+
retrievers.push('identifier');
|
|
18
|
+
reasons.push('exact identifier detected — searching usage sites');
|
|
19
|
+
// Also add structural if any predicates exist
|
|
20
|
+
if (ir.structuralPredicates.length > 0) {
|
|
21
|
+
retrievers.push('structural');
|
|
22
|
+
reasons.push('structural predicates found — will filter by code shape');
|
|
23
|
+
}
|
|
24
|
+
break;
|
|
25
|
+
case 'structural':
|
|
26
|
+
// Identifier + structural: locate by identifier, filter by structure
|
|
27
|
+
if (ir.exactIdentifiers.length > 0 || ir.dottedIdentifiers.length > 0) {
|
|
28
|
+
retrievers.push('identifier');
|
|
29
|
+
reasons.push('using identifier to locate candidate sites');
|
|
30
|
+
}
|
|
31
|
+
retrievers.push('structural');
|
|
32
|
+
reasons.push('structural predicates will filter/rank results');
|
|
33
|
+
break;
|
|
34
|
+
case 'mixed':
|
|
35
|
+
retrievers.push('behavior');
|
|
36
|
+
reasons.push('behavior retrieval for concept matching');
|
|
37
|
+
if (ir.exactIdentifiers.length > 0 || ir.dottedIdentifiers.length > 0) {
|
|
38
|
+
retrievers.push('identifier');
|
|
39
|
+
reasons.push('identifier retrieval for exact API matches');
|
|
40
|
+
}
|
|
41
|
+
if (ir.structuralPredicates.length > 0) {
|
|
42
|
+
retrievers.push('structural');
|
|
43
|
+
reasons.push('structural predicates for shape filtering');
|
|
44
|
+
}
|
|
45
|
+
break;
|
|
46
|
+
}
|
|
47
|
+
// Ensure at least one retriever
|
|
48
|
+
if (retrievers.length === 0) {
|
|
49
|
+
retrievers.push('behavior');
|
|
50
|
+
reasons.push('fallback: no specific signals, using behavior search');
|
|
51
|
+
}
|
|
52
|
+
return {
|
|
53
|
+
mode: ir.mode,
|
|
54
|
+
retrievers,
|
|
55
|
+
reasons,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=planQuery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"planQuery.js","sourceRoot":"","sources":["../../../src/search/query/planQuery.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,MAAM,UAAU,SAAS,CAAC,EAAW;IACnC,MAAM,UAAU,GAA6B,EAAE,CAAC;IAChD,MAAM,OAAO,GAAa,EAAE,CAAC;IAE7B,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC;QAChB,KAAK,UAAU;YACb,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAC5B,OAAO,CAAC,IAAI,CAAC,6DAA6D,CAAC,CAAC;YAC5E,MAAM;QAER,KAAK,YAAY;YACf,UAAU,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YAC9B,OAAO,CAAC,IAAI,CAAC,mDAAmD,CAAC,CAAC;YAClE,8CAA8C;YAC9C,IAAI,EAAE,CAAC,oBAAoB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACvC,UAAU,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;gBAC9B,OAAO,CAAC,IAAI,CAAC,yDAAyD,CAAC,CAAC;YAC1E,CAAC;YACD,MAAM;QAER,KAAK,YAAY;YACf,qEAAqE;YACrE,IAAI,EAAE,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,iBAAiB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACtE,UAAU,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;gBAC9B,OAAO,CAAC,IAAI,CAAC,4CAA4C,CAAC,CAAC;YAC7D,CAAC;YACD,UAAU,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YAC9B,OAAO,CAAC,IAAI,CAAC,gDAAgD,CAAC,CAAC;YAC/D,MAAM;QAER,KAAK,OAAO;YACV,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAC5B,OAAO,CAAC,IAAI,CAAC,yCAAyC,CAAC,CAAC;YACxD,IAAI,EAAE,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,iBAAiB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACtE,UAAU,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;gBAC9B,OAAO,CAAC,IAAI,CAAC,4CAA4C,CAAC,CAAC;YAC7D,CAAC;YACD,IAAI,EAAE,CAAC,oBAAoB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACvC,UAAU,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;gBAC9B,OAAO,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAAC;YAC5D,CAAC;YACD,MAAM;IACV,CAAC;IAED,gCAAgC;IAChC,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC5B,OAAO,CAAC,IAAI,CAAC,sDAAsD,CAAC,CAAC;IACvE,CAAC;IAED,OAAO;QACL,IAAI,EAAE,EAAE,CAAC,IAAI;QACb,UAAU;QACV,OAAO;KACR,CAAC;AACJ,CAAC"}
|
|
@@ -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';
|