lsp-intelligence 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (148) hide show
  1. package/README.md +41 -13
  2. package/dist/analysis/pattern/collectSearchFiles.d.ts +2 -1
  3. package/dist/analysis/pattern/collectSearchFiles.js +6 -6
  4. package/dist/analysis/pattern/collectSearchFiles.js.map +1 -1
  5. package/dist/analysis/pattern/runPatternSearch.d.ts +1 -1
  6. package/dist/analysis/pattern/runPatternSearch.js +4 -2
  7. package/dist/analysis/pattern/runPatternSearch.js.map +1 -1
  8. package/dist/analysis/ts/extractUsages.js +19 -0
  9. package/dist/analysis/ts/extractUsages.js.map +1 -1
  10. package/dist/analysis/ts/parseSourceFile.d.ts +2 -1
  11. package/dist/analysis/ts/parseSourceFile.js +5 -9
  12. package/dist/analysis/ts/parseSourceFile.js.map +1 -1
  13. package/dist/analysis/ts/reactState.d.ts +9 -0
  14. package/dist/analysis/ts/reactState.js +57 -0
  15. package/dist/analysis/ts/reactState.js.map +1 -0
  16. package/dist/analysis/ts/structuralPredicates.js +31 -2
  17. package/dist/analysis/ts/structuralPredicates.js.map +1 -1
  18. package/dist/ast/parseFile.d.ts +4 -3
  19. package/dist/ast/parseFile.js +22 -5
  20. package/dist/ast/parseFile.js.map +1 -1
  21. package/dist/engine/LspEngine.js +23 -1
  22. package/dist/engine/LspEngine.js.map +1 -1
  23. package/dist/git/getBaseFileContent.d.ts +1 -0
  24. package/dist/git/getBaseFileContent.js +10 -3
  25. package/dist/git/getBaseFileContent.js.map +1 -1
  26. package/dist/git/getChangedFiles.d.ts +2 -1
  27. package/dist/git/getChangedFiles.js +11 -5
  28. package/dist/git/getChangedFiles.js.map +1 -1
  29. package/dist/git/getChangedHunks.d.ts +1 -0
  30. package/dist/git/getChangedHunks.js +15 -10
  31. package/dist/git/getChangedHunks.js.map +1 -1
  32. package/dist/git/getGitRoot.d.ts +15 -0
  33. package/dist/git/getGitRoot.js +33 -0
  34. package/dist/git/getGitRoot.js.map +1 -0
  35. package/dist/index.js +2 -0
  36. package/dist/index.js.map +1 -1
  37. package/dist/resolve/searchScope.d.ts +8 -2
  38. package/dist/resolve/searchScope.js +26 -14
  39. package/dist/resolve/searchScope.js.map +1 -1
  40. package/dist/search/adapters/config.d.ts +5 -0
  41. package/dist/search/adapters/config.js +56 -0
  42. package/dist/search/adapters/config.js.map +1 -0
  43. package/dist/search/adapters/http.d.ts +6 -0
  44. package/dist/search/adapters/http.js +58 -0
  45. package/dist/search/adapters/http.js.map +1 -0
  46. package/dist/search/adapters/react.d.ts +12 -0
  47. package/dist/search/adapters/react.js +92 -0
  48. package/dist/search/adapters/react.js.map +1 -0
  49. package/dist/search/adapters/registry.d.ts +6 -0
  50. package/dist/search/adapters/registry.js +20 -0
  51. package/dist/search/adapters/registry.js.map +1 -0
  52. package/dist/search/adapters/types.d.ts +5 -0
  53. package/dist/search/adapters/types.js +2 -0
  54. package/dist/search/adapters/types.js.map +1 -0
  55. package/dist/search/debug/trace.d.ts +6 -0
  56. package/dist/search/debug/trace.js +25 -0
  57. package/dist/search/debug/trace.js.map +1 -0
  58. package/dist/search/expand/graphExpansion.d.ts +16 -0
  59. package/dist/search/expand/graphExpansion.js +168 -0
  60. package/dist/search/expand/graphExpansion.js.map +1 -0
  61. package/dist/search/fileKinds.d.ts +13 -0
  62. package/dist/search/fileKinds.js +74 -0
  63. package/dist/search/fileKinds.js.map +1 -0
  64. package/dist/search/index/configIndex.d.ts +6 -0
  65. package/dist/search/index/configIndex.js +196 -0
  66. package/dist/search/index/configIndex.js.map +1 -0
  67. package/dist/search/index/docIndex.d.ts +7 -0
  68. package/dist/search/index/docIndex.js +116 -0
  69. package/dist/search/index/docIndex.js.map +1 -0
  70. package/dist/search/index/workspaceIndex.d.ts +6 -0
  71. package/dist/search/index/workspaceIndex.js +50 -14
  72. package/dist/search/index/workspaceIndex.js.map +1 -1
  73. package/dist/search/query/compileEffectiveSearchSpec.d.ts +24 -0
  74. package/dist/search/query/compileEffectiveSearchSpec.js +67 -0
  75. package/dist/search/query/compileEffectiveSearchSpec.js.map +1 -0
  76. package/dist/search/query/parseQuery.d.ts +1 -0
  77. package/dist/search/query/parseQuery.js +40 -0
  78. package/dist/search/query/parseQuery.js.map +1 -1
  79. package/dist/search/query/phraseRules.d.ts +10 -0
  80. package/dist/search/query/phraseRules.js +58 -0
  81. package/dist/search/query/phraseRules.js.map +1 -0
  82. package/dist/search/query/planQuery.d.ts +4 -3
  83. package/dist/search/query/planQuery.js +39 -6
  84. package/dist/search/query/planQuery.js.map +1 -1
  85. package/dist/search/ranking/assessConfidence.js +6 -0
  86. package/dist/search/ranking/assessConfidence.js.map +1 -1
  87. package/dist/search/ranking/candidateIdentity.d.ts +21 -0
  88. package/dist/search/ranking/candidateIdentity.js +29 -0
  89. package/dist/search/ranking/candidateIdentity.js.map +1 -0
  90. package/dist/search/ranking/coalesceCandidates.d.ts +9 -0
  91. package/dist/search/ranking/coalesceCandidates.js +48 -0
  92. package/dist/search/ranking/coalesceCandidates.js.map +1 -0
  93. package/dist/search/ranking/fieldedTextRanker.d.ts +26 -0
  94. package/dist/search/ranking/fieldedTextRanker.js +79 -0
  95. package/dist/search/ranking/fieldedTextRanker.js.map +1 -0
  96. package/dist/search/ranking/mergeCandidates.d.ts +3 -0
  97. package/dist/search/ranking/mergeCandidates.js +39 -0
  98. package/dist/search/ranking/mergeCandidates.js.map +1 -1
  99. package/dist/search/ranking/rankCandidates.d.ts +1 -1
  100. package/dist/search/ranking/rankCandidates.js +51 -3
  101. package/dist/search/ranking/rankCandidates.js.map +1 -1
  102. package/dist/search/retrievers/behaviorRetriever.d.ts +3 -3
  103. package/dist/search/retrievers/behaviorRetriever.js +64 -69
  104. package/dist/search/retrievers/behaviorRetriever.js.map +1 -1
  105. package/dist/search/retrievers/configRetriever.d.ts +7 -0
  106. package/dist/search/retrievers/configRetriever.js +46 -0
  107. package/dist/search/retrievers/configRetriever.js.map +1 -0
  108. package/dist/search/retrievers/docRetriever.d.ts +7 -0
  109. package/dist/search/retrievers/docRetriever.js +46 -0
  110. package/dist/search/retrievers/docRetriever.js.map +1 -0
  111. package/dist/search/retrievers/identifierRetriever.d.ts +3 -3
  112. package/dist/search/retrievers/identifierRetriever.js +7 -6
  113. package/dist/search/retrievers/identifierRetriever.js.map +1 -1
  114. package/dist/search/retrievers/structuralRetriever.d.ts +4 -6
  115. package/dist/search/retrievers/structuralRetriever.js +47 -84
  116. package/dist/search/retrievers/structuralRetriever.js.map +1 -1
  117. package/dist/search/retrievers/textPatternRetriever.d.ts +7 -0
  118. package/dist/search/retrievers/textPatternRetriever.js +90 -0
  119. package/dist/search/retrievers/textPatternRetriever.js.map +1 -0
  120. package/dist/search/structural/locators/callLocator.d.ts +6 -0
  121. package/dist/search/structural/locators/callLocator.js +57 -0
  122. package/dist/search/structural/locators/callLocator.js.map +1 -0
  123. package/dist/search/structural/locators/declarationLocator.d.ts +6 -0
  124. package/dist/search/structural/locators/declarationLocator.js +57 -0
  125. package/dist/search/structural/locators/declarationLocator.js.map +1 -0
  126. package/dist/search/structural/locators/statementLocator.d.ts +6 -0
  127. package/dist/search/structural/locators/statementLocator.js +65 -0
  128. package/dist/search/structural/locators/statementLocator.js.map +1 -0
  129. package/dist/search/structural/locators/types.d.ts +12 -0
  130. package/dist/search/structural/locators/types.js +2 -0
  131. package/dist/search/structural/locators/types.js.map +1 -0
  132. package/dist/search/structural/selectLocators.d.ts +7 -0
  133. package/dist/search/structural/selectLocators.js +21 -0
  134. package/dist/search/structural/selectLocators.js.map +1 -0
  135. package/dist/search/types.d.ts +77 -7
  136. package/dist/search/types.js.map +1 -1
  137. package/dist/tools/composites/apiGuard.js +6 -28
  138. package/dist/tools/composites/apiGuard.js.map +1 -1
  139. package/dist/tools/composites/findCode.js +92 -15
  140. package/dist/tools/composites/findCode.js.map +1 -1
  141. package/dist/tools/composites/findPattern.js +1 -1
  142. package/dist/tools/composites/findPattern.js.map +1 -1
  143. package/dist/tools/live/clearIndex.d.ts +1 -0
  144. package/dist/tools/live/clearIndex.js +19 -0
  145. package/dist/tools/live/clearIndex.js.map +1 -0
  146. package/dist/tools/primitives/callHierarchy.js +1 -1
  147. package/dist/tools/primitives/callHierarchy.js.map +1 -1
  148. package/package.json +4 -2
@@ -0,0 +1,92 @@
1
+ const HOOK_PATTERN = /^use[A-Z]/;
2
+ /**
3
+ * React adapter — emits search recipes for React hook/component queries.
4
+ *
5
+ * Recipes:
6
+ * - react.useeffect.conditional-cleanup
7
+ * - react.useeffect.functional-state-updater
8
+ * - react.usememo.computation
9
+ * - react.usecallback.memoized-handler
10
+ * - react.hook.general (fallback for any hook query)
11
+ */
12
+ export const reactAdapter = {
13
+ id: 'react',
14
+ detect(ir) {
15
+ if (!ir.traits.reactLike)
16
+ return [];
17
+ const recipes = [];
18
+ const hookIds = ir.exactIdentifiers.filter((id) => HOOK_PATTERN.test(id));
19
+ const hasUseEffect = hookIds.includes('useEffect');
20
+ const hasUseMemo = hookIds.includes('useMemo');
21
+ const hasUseCallback = hookIds.includes('useCallback');
22
+ // useEffect + conditional cleanup
23
+ if (hasUseEffect && (ir.structuralPredicates.includes('conditional') ||
24
+ ir.structuralPredicates.includes('returns-cleanup') ||
25
+ ir.codeTokens.includes('cleanup'))) {
26
+ recipes.push({
27
+ id: 'react.useeffect.conditional-cleanup',
28
+ adapter: 'react',
29
+ retrievers: ['identifier', 'structural', 'regex'],
30
+ exactIdentifiers: ['useEffect'],
31
+ structuralPredicates: ['returns-cleanup', 'conditional'],
32
+ regexes: [
33
+ { id: 'conditional-return', pattern: 'if\\s*\\([^)]*\\)\\s*\\{[^}]*return\\s*\\(\\)', flags: 'g' },
34
+ { id: 'useeffect-cleanup', pattern: 'useEffect\\s*\\(\\s*\\(\\)\\s*=>\\s*\\{[\\s\\S]*?return\\s', flags: 'g' },
35
+ ],
36
+ scoreBoost: 3,
37
+ reasons: ['React adapter: useEffect + conditional cleanup pattern'],
38
+ });
39
+ }
40
+ // useEffect + functional state updater (based on previous state)
41
+ if (hasUseEffect && ir.traits.previousStateLike) {
42
+ recipes.push({
43
+ id: 'react.useeffect.functional-state-updater',
44
+ adapter: 'react',
45
+ retrievers: ['identifier', 'structural', 'regex'],
46
+ exactIdentifiers: ['useEffect'],
47
+ structuralPredicates: ['functional-state-updater'],
48
+ regexes: [
49
+ { id: 'functional-updater', pattern: 'set\\w+\\s*\\(\\s*(?:prev|current|existing|old)\\w*\\s*=>', flags: 'g' },
50
+ { id: 'updater-arrow', pattern: 'set\\w+\\s*\\(\\s*\\w+\\s*=>\\s*\\w+', flags: 'g' },
51
+ ],
52
+ scoreBoost: 4,
53
+ reasons: ['React adapter: useEffect + functional state updater'],
54
+ });
55
+ }
56
+ // useMemo computation
57
+ if (hasUseMemo) {
58
+ recipes.push({
59
+ id: 'react.usememo.computation',
60
+ adapter: 'react',
61
+ retrievers: ['identifier'],
62
+ exactIdentifiers: ['useMemo'],
63
+ scoreBoost: 1,
64
+ reasons: ['React adapter: useMemo computation'],
65
+ });
66
+ }
67
+ // useCallback memoized handler
68
+ if (hasUseCallback) {
69
+ recipes.push({
70
+ id: 'react.usecallback.memoized-handler',
71
+ adapter: 'react',
72
+ retrievers: ['identifier'],
73
+ exactIdentifiers: ['useCallback'],
74
+ scoreBoost: 1,
75
+ reasons: ['React adapter: useCallback memoized handler'],
76
+ });
77
+ }
78
+ // General hook query (fallback)
79
+ if (hookIds.length > 0 && recipes.length === 0) {
80
+ recipes.push({
81
+ id: 'react.hook.general',
82
+ adapter: 'react',
83
+ retrievers: ['identifier'],
84
+ exactIdentifiers: hookIds,
85
+ scoreBoost: 0,
86
+ reasons: [`React adapter: general hook query for ${hookIds.join(', ')}`],
87
+ });
88
+ }
89
+ return recipes;
90
+ },
91
+ };
92
+ //# sourceMappingURL=react.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"react.js","sourceRoot":"","sources":["../../../src/search/adapters/react.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { QueryIR, SearchRecipe } from '../types.js';
2
+ /**
3
+ * Run all registered adapters against a parsed query IR.
4
+ * Returns all emitted recipes.
5
+ */
6
+ export declare function runAdapters(ir: QueryIR): SearchRecipe[];
@@ -0,0 +1,20 @@
1
+ import { reactAdapter } from './react.js';
2
+ import { httpAdapter } from './http.js';
3
+ import { configAdapter } from './config.js';
4
+ const ADAPTERS = [
5
+ reactAdapter,
6
+ httpAdapter,
7
+ configAdapter,
8
+ ];
9
+ /**
10
+ * Run all registered adapters against a parsed query IR.
11
+ * Returns all emitted recipes.
12
+ */
13
+ export function runAdapters(ir) {
14
+ const recipes = [];
15
+ for (const adapter of ADAPTERS) {
16
+ recipes.push(...adapter.detect(ir));
17
+ }
18
+ return recipes;
19
+ }
20
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../src/search/adapters/registry.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,MAAM,QAAQ,GAAoB;IAChC,YAAY;IACZ,WAAW;IACX,aAAa;CACd,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,EAAW;IACrC,MAAM,OAAO,GAAmB,EAAE,CAAC;IACnC,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;IACtC,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { QueryIR, SearchRecipe } from '../types.js';
2
+ export interface SearchAdapter {
3
+ id: string;
4
+ detect(ir: QueryIR): SearchRecipe[];
5
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/search/adapters/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,6 @@
1
+ import type { QueryIR, SearchPlan, CodeCandidate, FindCodeDebugInfo } from '../types.js';
2
+ /**
3
+ * Build debug trace info for find_code results.
4
+ * Only called when debug=true — no overhead on normal queries.
5
+ */
6
+ export declare function buildDebugTrace(ir: QueryIR, plan: SearchPlan, candidates: CodeCandidate[], retrieverCounts: Record<string, number>): FindCodeDebugInfo;
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Build debug trace info for find_code results.
3
+ * Only called when debug=true — no overhead on normal queries.
4
+ */
5
+ export function buildDebugTrace(ir, plan, candidates, retrieverCounts) {
6
+ return {
7
+ recipes: [
8
+ `mode: ${ir.mode} (confidence: ${ir.modeConfidence})`,
9
+ ...ir.routingReasons.map((r) => `routing: ${r}`),
10
+ ...plan.reasons.map((r) => `plan: ${r}`),
11
+ ...(ir.traits.routeLike ? ['trait: routeLike'] : []),
12
+ ...(ir.traits.configLike ? ['trait: configLike'] : []),
13
+ ...(ir.traits.implementationRoot ? ['trait: implementationRoot'] : []),
14
+ ...(ir.traits.testIntent ? ['trait: testIntent'] : []),
15
+ ...(plan.expandGraph ? ['graphExpansion: enabled'] : []),
16
+ ],
17
+ retrieverStats: retrieverCounts,
18
+ scoreBreakdown: candidates.slice(0, 15).map((c) => ({
19
+ candidateKey: `${c.filePath}:${c.line}:${c.symbol ?? c.matchedIdentifier ?? ''}`,
20
+ score: c.score,
21
+ evidence: c.evidence,
22
+ })),
23
+ };
24
+ }
25
+ //# sourceMappingURL=trace.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trace.js","sourceRoot":"","sources":["../../../src/search/debug/trace.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,UAAU,eAAe,CAC7B,EAAW,EACX,IAAgB,EAChB,UAA2B,EAC3B,eAAuC;IAEvC,OAAO;QACL,OAAO,EAAE;YACP,SAAS,EAAE,CAAC,IAAI,iBAAiB,EAAE,CAAC,cAAc,GAAG;YACrD,GAAG,EAAE,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,EAAE,CAAC;YAChD,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC;YACxC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACpD,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACtD,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,2BAA2B,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACtE,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACtD,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,yBAAyB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;SACzD;QACD,cAAc,EAAE,eAAe;QAC/B,cAAc,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAClD,YAAY,EAAE,GAAG,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,iBAAiB,IAAI,EAAE,EAAE;YAChF,KAAK,EAAE,CAAC,CAAC,KAAK;YACd,QAAQ,EAAE,CAAC,CAAC,QAAQ;SACrB,CAAC,CAAC;KACJ,CAAC;AACJ,CAAC"}
@@ -0,0 +1,16 @@
1
+ import type { CodeCandidate } from '../types.js';
2
+ import type { LspEngine } from '../../engine/LspEngine.js';
3
+ export interface GraphExpansionResult {
4
+ promoted: Map<string, {
5
+ scoreDelta: number;
6
+ evidence: string[];
7
+ }>;
8
+ derived: CodeCandidate[];
9
+ warnings: string[];
10
+ }
11
+ /**
12
+ * Expand top candidates toward implementation roots.
13
+ * Detects wrappers, follows definitions, and promotes likely real implementations.
14
+ * Derived candidates are returned for merging back into ranking.
15
+ */
16
+ export declare function expandToImplementationRoots(candidates: CodeCandidate[], engine: LspEngine, maxSeeds?: number): Promise<GraphExpansionResult>;
@@ -0,0 +1,168 @@
1
+ import ts from 'typescript';
2
+ import { parseSourceFile } from '../../analysis/ts/parseSourceFile.js';
3
+ import { absoluteCandidateKey, lspLocationToKey } from '../ranking/candidateIdentity.js';
4
+ import { buildSnippetFromFile } from '../../analysis/ts/snippets.js';
5
+ /** Builtins and framework symbols that should never be promoted as implementation roots. */
6
+ const BUILTIN_DENYLIST = new Set([
7
+ 'useState', 'useEffect', 'useMemo', 'useCallback', 'useRef', 'useContext',
8
+ 'useReducer', 'useLayoutEffect', 'useImperativeHandle', 'useDebugValue',
9
+ 'fetch', 'console', 'setTimeout', 'setInterval', 'clearTimeout', 'clearInterval',
10
+ 'Promise', 'JSON', 'Math', 'Object', 'Array', 'Map', 'Set', 'Date', 'Error',
11
+ 'require', 'import', 'exports', 'module',
12
+ 'document', 'window', 'process', 'global', 'globalThis',
13
+ 'addEventListener', 'removeEventListener', 'dispatchEvent',
14
+ 'createElement', 'createContext', 'createRef', 'forwardRef', 'memo', 'lazy',
15
+ ]);
16
+ /**
17
+ * Expand top candidates toward implementation roots.
18
+ * Detects wrappers, follows definitions, and promotes likely real implementations.
19
+ * Derived candidates are returned for merging back into ranking.
20
+ */
21
+ export async function expandToImplementationRoots(candidates, engine, maxSeeds = 5) {
22
+ const promoted = new Map();
23
+ const derived = [];
24
+ const warnings = [];
25
+ const seeds = candidates.slice(0, maxSeeds);
26
+ for (const candidate of seeds) {
27
+ try {
28
+ // Use absolute path for wrapper detection (candidates may be relative at this point)
29
+ const absPath = candidate.filePath.startsWith('/')
30
+ ? candidate.filePath
31
+ : `${engine.workspaceRoot}/${candidate.filePath}`;
32
+ const wrapperInfo = detectWrapper(absPath, candidate.line);
33
+ if (!wrapperInfo)
34
+ continue;
35
+ // Skip if the call target is a builtin/framework symbol — not a real root
36
+ const leafTarget = wrapperInfo.callTarget.split('.').pop() ?? wrapperInfo.callTarget;
37
+ if (BUILTIN_DENYLIST.has(leafTarget))
38
+ continue;
39
+ // Demote wrapper
40
+ const wrapperKey = absoluteCandidateKey(candidate);
41
+ promoted.set(wrapperKey, {
42
+ scoreDelta: -2,
43
+ evidence: [`wrapper-of: ${wrapperInfo.callTarget}`, `body-size: ${wrapperInfo.bodySize}`],
44
+ });
45
+ // Try to resolve the wrapped function via LSP and promote it
46
+ try {
47
+ const loc = await engine.resolveSymbol(wrapperInfo.callTarget);
48
+ if (loc) {
49
+ // Only promote if the resolved location is inside the workspace (project-local)
50
+ const resolvedPath = loc.uri.startsWith('file://')
51
+ ? decodeURIComponent(loc.uri.replace(/^file:\/\//, ''))
52
+ : loc.uri;
53
+ if (!resolvedPath.startsWith(engine.workspaceRoot))
54
+ continue;
55
+ const derivedKey = lspLocationToKey(loc.uri, loc.position.line, engine.workspaceRoot, wrapperInfo.callTarget);
56
+ if (!promoted.has(derivedKey)) {
57
+ promoted.set(derivedKey, {
58
+ scoreDelta: 4,
59
+ evidence: ['implementation-root', `wrapped-by: ${candidate.symbol ?? 'unknown'}`],
60
+ });
61
+ // Create a derived candidate so it can be merged into results
62
+ const derivedPath = loc.uri.startsWith('file://')
63
+ ? decodeURIComponent(loc.uri.replace(/^file:\/\//, ''))
64
+ : loc.uri;
65
+ const derivedLine = loc.position.line + 1;
66
+ const { snippet, context } = buildSnippetFromFile(derivedPath, derivedLine, 1);
67
+ derived.push({
68
+ candidateType: 'declaration',
69
+ filePath: derivedPath,
70
+ line: derivedLine,
71
+ symbol: wrapperInfo.callTarget,
72
+ kind: 'function',
73
+ snippet,
74
+ context,
75
+ score: candidate.score + 4,
76
+ evidence: ['implementation-root', `wrapped-by: ${candidate.symbol ?? 'unknown'}`, 'graph-derived'],
77
+ sources: ['graph'],
78
+ });
79
+ }
80
+ }
81
+ }
82
+ catch {
83
+ // LSP resolution failed — skip
84
+ }
85
+ }
86
+ catch (err) {
87
+ warnings.push(`graph-expand failed for ${candidate.symbol}: ${err?.message ?? 'unknown'}`);
88
+ }
89
+ }
90
+ return { promoted, derived, warnings };
91
+ }
92
+ function detectWrapper(filePath, line) {
93
+ const sf = parseSourceFile(filePath);
94
+ if (!sf)
95
+ return null;
96
+ const targetLine = line - 1;
97
+ let foundNode = null;
98
+ function visit(node) {
99
+ if (foundNode)
100
+ return;
101
+ const nodeLine = sf.getLineAndCharacterOfPosition(node.getStart(sf)).line;
102
+ if (nodeLine >= targetLine - 1 && nodeLine <= targetLine + 1) {
103
+ if (ts.isFunctionDeclaration(node) || ts.isArrowFunction(node) || ts.isFunctionExpression(node)) {
104
+ foundNode = node;
105
+ return;
106
+ }
107
+ }
108
+ if (ts.isVariableDeclaration(node) && node.initializer) {
109
+ const initLine = sf.getLineAndCharacterOfPosition(node.initializer.getStart(sf)).line;
110
+ if (initLine >= targetLine - 1 && initLine <= targetLine + 1) {
111
+ if (ts.isArrowFunction(node.initializer) || ts.isFunctionExpression(node.initializer)) {
112
+ foundNode = node.initializer;
113
+ return;
114
+ }
115
+ }
116
+ }
117
+ ts.forEachChild(node, visit);
118
+ }
119
+ visit(sf);
120
+ if (!foundNode)
121
+ return null;
122
+ const body = getBody(foundNode);
123
+ if (!body)
124
+ return null;
125
+ const statements = ts.isBlock(body) ? body.statements : [];
126
+ const bodySize = statements.length;
127
+ if (bodySize > 5 || bodySize === 0)
128
+ return null;
129
+ const callTargets = [];
130
+ for (const stmt of statements) {
131
+ findCallTargets(stmt, callTargets);
132
+ }
133
+ if (callTargets.length === 0 || callTargets.length > 3)
134
+ return null;
135
+ return { callTarget: callTargets[0], bodySize };
136
+ }
137
+ function getBody(node) {
138
+ if (ts.isFunctionDeclaration(node) || ts.isFunctionExpression(node))
139
+ return node.body ?? null;
140
+ if (ts.isArrowFunction(node))
141
+ return node.body;
142
+ return null;
143
+ }
144
+ function findCallTargets(node, targets) {
145
+ if (ts.isCallExpression(node)) {
146
+ const expr = node.expression;
147
+ if (ts.isIdentifier(expr)) {
148
+ targets.push(expr.text);
149
+ }
150
+ else if (ts.isPropertyAccessExpression(expr)) {
151
+ const parts = [expr.name.text];
152
+ let current = expr.expression;
153
+ while (ts.isPropertyAccessExpression(current)) {
154
+ parts.unshift(current.name.text);
155
+ current = current.expression;
156
+ }
157
+ if (ts.isIdentifier(current))
158
+ parts.unshift(current.text);
159
+ targets.push(parts.join('.'));
160
+ }
161
+ }
162
+ if (ts.isReturnStatement(node) && node.expression) {
163
+ findCallTargets(node.expression, targets);
164
+ return;
165
+ }
166
+ ts.forEachChild(node, (child) => findCallTargets(child, targets));
167
+ }
168
+ //# sourceMappingURL=graphExpansion.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graphExpansion.js","sourceRoot":"","sources":["../../../src/search/expand/graphExpansion.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import ts from 'typescript';
2
+ export declare const CODE_EXTENSIONS: readonly [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"];
3
+ export declare const CONFIG_EXTENSIONS: readonly [".json", ".yaml", ".yml", ".toml"];
4
+ export declare function shouldSkipDir(dirName: string): boolean;
5
+ export declare function shouldSkipFile(filePath: string, sizeBytes?: number): boolean;
6
+ /** Real .env files that may contain secrets. Excluded from indexing by default. */
7
+ export declare function isSecretEnvFile(filePath: string): boolean;
8
+ /** Non-secret env template/example files. Safe to index. */
9
+ export declare function isSafeEnvTemplateFile(filePath: string): boolean;
10
+ export declare function isCodeFile(filePath: string): boolean;
11
+ export declare function isConfigFile(filePath: string): boolean;
12
+ export declare function isTestFile(filePath: string): boolean;
13
+ export declare function scriptKindForFile(filePath: string): ts.ScriptKind;
@@ -0,0 +1,74 @@
1
+ import * as path from 'path';
2
+ import ts from 'typescript';
3
+ export const CODE_EXTENSIONS = ['.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs'];
4
+ export const CONFIG_EXTENSIONS = ['.json', '.yaml', '.yml', '.toml'];
5
+ const TEST_PATTERN = /\.(spec|test|stories)\.(ts|tsx|js|jsx|mjs|cjs)$/;
6
+ // --- Directory exclusion ---
7
+ const SKIP_DIR_NAMES = new Set([
8
+ 'node_modules', 'dist', 'build', 'es', 'coverage',
9
+ '__pycache__', '__generated__', '__mocks__',
10
+ ]);
11
+ export function shouldSkipDir(dirName) {
12
+ if (dirName.startsWith('.'))
13
+ return true;
14
+ return SKIP_DIR_NAMES.has(dirName);
15
+ }
16
+ // --- File exclusion ---
17
+ const SKIP_FILE_PATTERNS = [
18
+ /\.min\.(js|cjs|mjs)$/,
19
+ /\.bundle\.(js|cjs|mjs)$/,
20
+ /\.map$/,
21
+ /\.lock$/,
22
+ /-lock\.json$/,
23
+ ];
24
+ const MAX_FILE_SIZE = 500_000;
25
+ export function shouldSkipFile(filePath, sizeBytes) {
26
+ const basename = path.basename(filePath);
27
+ if (basename.endsWith('.d.ts'))
28
+ return true;
29
+ if (SKIP_FILE_PATTERNS.some((p) => p.test(basename)))
30
+ return true;
31
+ if (sizeBytes !== undefined && sizeBytes > MAX_FILE_SIZE)
32
+ return true;
33
+ return false;
34
+ }
35
+ // --- Env file classification ---
36
+ /** Real .env files that may contain secrets. Excluded from indexing by default. */
37
+ export function isSecretEnvFile(filePath) {
38
+ const basename = path.basename(filePath);
39
+ if (!basename.startsWith('.env'))
40
+ return false;
41
+ // Allow safe templates/examples
42
+ if (isSafeEnvTemplateFile(filePath))
43
+ return false;
44
+ return true;
45
+ }
46
+ /** Non-secret env template/example files. Safe to index. */
47
+ export function isSafeEnvTemplateFile(filePath) {
48
+ const basename = path.basename(filePath).toLowerCase();
49
+ return basename === '.env.example' ||
50
+ basename === '.env.template' ||
51
+ basename === '.env.sample';
52
+ }
53
+ // --- Code/config/test classification ---
54
+ export function isCodeFile(filePath) {
55
+ if (shouldSkipFile(filePath))
56
+ return false;
57
+ return CODE_EXTENSIONS.some((ext) => filePath.endsWith(ext));
58
+ }
59
+ export function isConfigFile(filePath) {
60
+ return CONFIG_EXTENSIONS.some((ext) => filePath.endsWith(ext));
61
+ }
62
+ export function isTestFile(filePath) {
63
+ return TEST_PATTERN.test(path.basename(filePath));
64
+ }
65
+ export function scriptKindForFile(filePath) {
66
+ if (filePath.endsWith('.tsx'))
67
+ return ts.ScriptKind.TSX;
68
+ if (filePath.endsWith('.jsx'))
69
+ return ts.ScriptKind.JSX;
70
+ if (filePath.endsWith('.mjs') || filePath.endsWith('.cjs') || filePath.endsWith('.js'))
71
+ return ts.ScriptKind.JS;
72
+ return ts.ScriptKind.TS;
73
+ }
74
+ //# sourceMappingURL=fileKinds.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fileKinds.js","sourceRoot":"","sources":["../../src/search/fileKinds.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAU,CAAC;AACvF,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAU,CAAC;AAE9E,MAAM,YAAY,GAAG,iDAAiD,CAAC;AAEvE,8BAA8B;AAE9B,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC;IAC7B,cAAc,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU;IACjD,aAAa,EAAE,eAAe,EAAE,WAAW;CAC5C,CAAC,CAAC;AAEH,MAAM,UAAU,aAAa,CAAC,OAAe;IAC3C,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACzC,OAAO,cAAc,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;AACrC,CAAC;AAED,yBAAyB;AAEzB,MAAM,kBAAkB,GAAG;IACzB,sBAAsB;IACtB,yBAAyB;IACzB,QAAQ;IACR,SAAS;IACT,cAAc;CACf,CAAC;AAEF,MAAM,aAAa,GAAG,OAAO,CAAC;AAE9B,MAAM,UAAU,cAAc,CAAC,QAAgB,EAAE,SAAkB;IACjE,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACzC,IAAI,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,CAAC;IAC5C,IAAI,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAClE,IAAI,SAAS,KAAK,SAAS,IAAI,SAAS,GAAG,aAAa;QAAE,OAAO,IAAI,CAAC;IACtE,OAAO,KAAK,CAAC;AACf,CAAC;AAED,kCAAkC;AAElC,mFAAmF;AACnF,MAAM,UAAU,eAAe,CAAC,QAAgB;IAC9C,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACzC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,MAAM,CAAC;QAAE,OAAO,KAAK,CAAC;IAC/C,gCAAgC;IAChC,IAAI,qBAAqB,CAAC,QAAQ,CAAC;QAAE,OAAO,KAAK,CAAC;IAClD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,4DAA4D;AAC5D,MAAM,UAAU,qBAAqB,CAAC,QAAgB;IACpD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC;IACvD,OAAO,QAAQ,KAAK,cAAc;QAChC,QAAQ,KAAK,eAAe;QAC5B,QAAQ,KAAK,aAAa,CAAC;AAC/B,CAAC;AAED,0CAA0C;AAE1C,MAAM,UAAU,UAAU,CAAC,QAAgB;IACzC,IAAI,cAAc,CAAC,QAAQ,CAAC;QAAE,OAAO,KAAK,CAAC;IAC3C,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;AAC/D,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,QAAgB;IAC3C,OAAO,iBAAiB,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;AACjE,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,QAAgB;IACzC,OAAO,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;AACpD,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,QAAgB;IAChD,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC;QAAE,OAAO,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC;IACxD,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC;QAAE,OAAO,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC;IACxD,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC;QACpF,OAAO,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC;IAC1B,OAAO,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC;AAC1B,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type { ConfigIndexEntry, SearchScope } from '../types.js';
2
+ /**
3
+ * Index configuration files in the workspace.
4
+ * Extracts key-value entries from JSON, YAML-like, and env files.
5
+ */
6
+ export declare function indexConfigFiles(scope: SearchScope): ConfigIndexEntry[];