@esankhan3/code-search-mcp 0.0.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.
Files changed (50) hide show
  1. package/README.md +343 -248
  2. package/dist/__tests__/config-resolver.test.js +153 -0
  3. package/dist/__tests__/daemon-rpc.test.js +100 -0
  4. package/dist/__tests__/observability.test.js +69 -0
  5. package/dist/__tests__/projects.test.js +141 -0
  6. package/dist/backends/daemon-client.js +87 -0
  7. package/dist/backends/in-process.js +104 -0
  8. package/dist/backends/index.js +29 -0
  9. package/dist/cli/index.js +231 -0
  10. package/dist/core/config.js +362 -49
  11. package/dist/core/env-config.js +45 -43
  12. package/dist/daemon/index.js +119 -0
  13. package/dist/daemon/rpc-server.js +99 -0
  14. package/dist/daemon/watcher.js +105 -0
  15. package/dist/index.js +7 -0
  16. package/dist/observability/logger.js +66 -0
  17. package/dist/observability/metrics.js +138 -0
  18. package/dist/projects/registry.js +146 -0
  19. package/dist/resources/resources.js +3 -3
  20. package/dist/server.js +6 -2
  21. package/dist/tools/graph.js +1 -1
  22. package/dist/tools/index-tools.js +1 -1
  23. package/dist/tools/profile.js +2 -2
  24. package/dist/tools/search.js +1 -1
  25. package/dist/transports/http-transport.js +38 -0
  26. package/package.json +31 -12
  27. package/scripts/smoke/run-smoke.sh +167 -0
  28. package/dist/core/ast-graph-builder.js +0 -800
  29. package/dist/core/chunker.js +0 -368
  30. package/dist/core/claude-runner.js +0 -173
  31. package/dist/core/cross-repo-detector.js +0 -887
  32. package/dist/core/embedder.js +0 -334
  33. package/dist/core/file-walker.js +0 -186
  34. package/dist/core/git-diff.js +0 -160
  35. package/dist/core/graph-metrics.js +0 -233
  36. package/dist/core/indexer.js +0 -552
  37. package/dist/core/project-graph-builder.js +0 -202
  38. package/dist/core/query-classifier.js +0 -144
  39. package/dist/core/query-router.js +0 -210
  40. package/dist/core/rag-evaluator.js +0 -213
  41. package/dist/core/repo-profiler.js +0 -383
  42. package/dist/core/reranker.js +0 -218
  43. package/dist/core/retriever.js +0 -242
  44. package/dist/core/semantic-edge-detector.js +0 -147
  45. package/dist/core/service-mesh-inferrer.js +0 -241
  46. package/dist/core/structural-hasher.js +0 -316
  47. package/dist/core/tree-sitter-parser.js +0 -539
  48. package/dist/core/vector-store.js +0 -259
  49. package/dist/core/workspace-detector.js +0 -481
  50. /package/dist/{core → backends}/types.js +0 -0
@@ -1,233 +0,0 @@
1
- function isEntityNode(node) {
2
- return node.type !== "module" && node.type !== "package";
3
- }
4
- function isContainsEdge(edge) {
5
- return edge.type === "contains";
6
- }
7
- function deterministicSample(arr, n) {
8
- if (arr.length <= n) return arr;
9
- const step = arr.length / n;
10
- const result = [];
11
- for (let i = 0; i < n; i++) {
12
- result.push(arr[Math.floor(i * step)]);
13
- }
14
- return result;
15
- }
16
- function generateGraphQualityReport(graph) {
17
- const { nodes, links: edges } = graph;
18
- const edgesByType = {};
19
- for (const edge of edges) {
20
- const t = edge.type ?? "unknown";
21
- edgesByType[t] = (edgesByType[t] ?? 0) + 1;
22
- }
23
- const edgesByConfidence = { high: 0, medium: 0, low: 0, unscored: 0 };
24
- for (const edge of edges) {
25
- const conf = edge.confidence;
26
- if (conf == null) {
27
- edgesByConfidence.unscored++;
28
- } else if (conf > 0.8) {
29
- edgesByConfidence.high++;
30
- } else if (conf >= 0.5) {
31
- edgesByConfidence.medium++;
32
- } else {
33
- edgesByConfidence.low++;
34
- }
35
- }
36
- const outgoing = /* @__PURE__ */ new Map();
37
- const incoming = /* @__PURE__ */ new Map();
38
- const fullAdj = /* @__PURE__ */ new Map();
39
- for (const node of nodes) {
40
- outgoing.set(node.id, []);
41
- incoming.set(node.id, []);
42
- fullAdj.set(node.id, /* @__PURE__ */ new Set());
43
- }
44
- for (const edge of edges) {
45
- let setA = fullAdj.get(edge.source);
46
- if (!setA) {
47
- setA = /* @__PURE__ */ new Set();
48
- fullAdj.set(edge.source, setA);
49
- }
50
- setA.add(edge.target);
51
- let setB = fullAdj.get(edge.target);
52
- if (!setB) {
53
- setB = /* @__PURE__ */ new Set();
54
- fullAdj.set(edge.target, setB);
55
- }
56
- setB.add(edge.source);
57
- if (!isContainsEdge(edge)) {
58
- const out = outgoing.get(edge.source);
59
- if (out) out.push(edge.target);
60
- const inc = incoming.get(edge.target);
61
- if (inc) inc.push(edge.source);
62
- }
63
- }
64
- const nodeMap = /* @__PURE__ */ new Map();
65
- for (const node of nodes) {
66
- nodeMap.set(node.id, node);
67
- }
68
- const entityNodes = nodes.filter(isEntityNode);
69
- const orphanEntities = entityNodes.filter(
70
- (n) => (outgoing.get(n.id)?.length ?? 0) === 0
71
- );
72
- const orphanEntityCount = orphanEntities.length;
73
- const orphanEntityPercent = entityNodes.length > 0 ? Math.round(orphanEntityCount / entityNodes.length * 1e4) / 100 : 0;
74
- let totalOutDegree = 0;
75
- for (const n of entityNodes) {
76
- totalOutDegree += outgoing.get(n.id)?.length ?? 0;
77
- }
78
- const avgOutDegreeEntities = entityNodes.length > 0 ? Math.round(totalOutDegree / entityNodes.length * 100) / 100 : 0;
79
- const seeds = deterministicSample(entityNodes, 20);
80
- let sumDepth1 = 0;
81
- let sumDepth2 = 0;
82
- let sumEntityDepth2 = 0;
83
- for (const seed of seeds) {
84
- const visited = /* @__PURE__ */ new Set([seed.id]);
85
- let frontier = [seed.id];
86
- const depth1Frontier = [];
87
- for (const nid of frontier) {
88
- for (const neighbor of outgoing.get(nid) ?? []) {
89
- if (!visited.has(neighbor)) {
90
- visited.add(neighbor);
91
- depth1Frontier.push(neighbor);
92
- }
93
- }
94
- for (const neighbor of incoming.get(nid) ?? []) {
95
- if (!visited.has(neighbor)) {
96
- visited.add(neighbor);
97
- depth1Frontier.push(neighbor);
98
- }
99
- }
100
- }
101
- sumDepth1 += depth1Frontier.length;
102
- frontier = depth1Frontier;
103
- const depth2New = [];
104
- for (const nid of frontier) {
105
- for (const neighbor of outgoing.get(nid) ?? []) {
106
- if (!visited.has(neighbor)) {
107
- visited.add(neighbor);
108
- depth2New.push(neighbor);
109
- }
110
- }
111
- for (const neighbor of incoming.get(nid) ?? []) {
112
- if (!visited.has(neighbor)) {
113
- visited.add(neighbor);
114
- depth2New.push(neighbor);
115
- }
116
- }
117
- }
118
- const totalDepth2 = depth1Frontier.length + depth2New.length;
119
- sumDepth2 += totalDepth2;
120
- let entityCount = 0;
121
- for (const nid of [...depth1Frontier, ...depth2New]) {
122
- const node = nodeMap.get(nid);
123
- if (node && isEntityNode(node)) entityCount++;
124
- }
125
- sumEntityDepth2 += entityCount;
126
- }
127
- const sampleSize = seeds.length;
128
- const bfsReachability = {
129
- sampleSize,
130
- avgReachedDepth1: sampleSize > 0 ? Math.round(sumDepth1 / sampleSize * 100) / 100 : 0,
131
- avgReachedDepth2: sampleSize > 0 ? Math.round(sumDepth2 / sampleSize * 100) / 100 : 0,
132
- avgEntityReachedDepth2: sampleSize > 0 ? Math.round(sumEntityDepth2 / sampleSize * 100) / 100 : 0
133
- };
134
- const degreeList = [];
135
- for (const node of nodes) {
136
- const deg = fullAdj.get(node.id)?.size ?? 0;
137
- degreeList.push({ id: node.id, degree: deg, type: node.type ?? "unknown" });
138
- }
139
- degreeList.sort((a, b) => b.degree - a.degree);
140
- const hubNodes = degreeList.slice(0, 10);
141
- const componentVisited = /* @__PURE__ */ new Set();
142
- const componentSizes = [];
143
- for (const node of nodes) {
144
- if (componentVisited.has(node.id)) continue;
145
- let size = 0;
146
- const queue = [node.id];
147
- componentVisited.add(node.id);
148
- while (queue.length > 0) {
149
- const current = queue.pop();
150
- size++;
151
- for (const neighbor of fullAdj.get(current) ?? []) {
152
- if (!componentVisited.has(neighbor)) {
153
- componentVisited.add(neighbor);
154
- queue.push(neighbor);
155
- }
156
- }
157
- }
158
- componentSizes.push(size);
159
- }
160
- const connectedComponents = componentSizes.length;
161
- const largestComponent = componentSizes.length > 0 ? Math.max(...componentSizes) : 0;
162
- const largestComponentPercent = nodes.length > 0 ? Math.round(largestComponent / nodes.length * 1e4) / 100 : 0;
163
- return {
164
- nodeCount: nodes.length,
165
- edgeCount: edges.length,
166
- edgesByType,
167
- edgesByConfidence,
168
- orphanEntityCount,
169
- orphanEntityPercent,
170
- avgOutDegreeEntities,
171
- bfsReachability,
172
- hubNodes,
173
- connectedComponents,
174
- largestComponentPercent
175
- };
176
- }
177
- function formatQualityReport(report) {
178
- const lines = [];
179
- lines.push("# Graph Quality Report");
180
- lines.push("");
181
- lines.push("## Overview");
182
- lines.push("");
183
- lines.push(`| Metric | Value |`);
184
- lines.push(`|--------|-------|`);
185
- lines.push(`| Nodes | ${report.nodeCount} |`);
186
- lines.push(`| Edges | ${report.edgeCount} |`);
187
- lines.push(`| Connected components | ${report.connectedComponents} |`);
188
- lines.push(`| Largest component | ${report.largestComponentPercent}% of nodes |`);
189
- lines.push(`| Orphan entities | ${report.orphanEntityCount} (${report.orphanEntityPercent}%) |`);
190
- lines.push(`| Avg out-degree (entities) | ${report.avgOutDegreeEntities} |`);
191
- lines.push("");
192
- lines.push("## Edges by Type");
193
- lines.push("");
194
- lines.push("| Type | Count |");
195
- lines.push("|------|-------|");
196
- const sortedTypes = Object.entries(report.edgesByType).sort((a, b) => b[1] - a[1]);
197
- for (const [type, count] of sortedTypes) {
198
- lines.push(`| ${type} | ${count} |`);
199
- }
200
- lines.push("");
201
- lines.push("## Edges by Confidence");
202
- lines.push("");
203
- lines.push("| Bucket | Count |");
204
- lines.push("|--------|-------|");
205
- lines.push(`| High (>0.8) | ${report.edgesByConfidence.high} |`);
206
- lines.push(`| Medium (0.5-0.8) | ${report.edgesByConfidence.medium} |`);
207
- lines.push(`| Low (<0.5) | ${report.edgesByConfidence.low} |`);
208
- lines.push(`| Unscored | ${report.edgesByConfidence.unscored} |`);
209
- lines.push("");
210
- lines.push("## BFS Reachability (non-contains edges)");
211
- lines.push("");
212
- lines.push(`Sample size: ${report.bfsReachability.sampleSize} entity nodes`);
213
- lines.push("");
214
- lines.push("| Metric | Value |");
215
- lines.push("|--------|-------|");
216
- lines.push(`| Avg reached at depth 1 | ${report.bfsReachability.avgReachedDepth1} |`);
217
- lines.push(`| Avg reached at depth 2 | ${report.bfsReachability.avgReachedDepth2} |`);
218
- lines.push(`| Avg entities reached at depth 2 | ${report.bfsReachability.avgEntityReachedDepth2} |`);
219
- lines.push("");
220
- lines.push("## Hub Nodes (top 10 by degree)");
221
- lines.push("");
222
- lines.push("| Node | Degree | Type |");
223
- lines.push("|------|--------|------|");
224
- for (const hub of report.hubNodes) {
225
- lines.push(`| ${hub.id} | ${hub.degree} | ${hub.type} |`);
226
- }
227
- lines.push("");
228
- return lines.join("\n");
229
- }
230
- export {
231
- formatQualityReport,
232
- generateGraphQualityReport
233
- };