@syke1/mcp-server 1.4.17 → 1.4.18
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/dist/ai/realtime-analyzer.js +1 -1
- package/dist/git/change-coupling.d.ts +41 -0
- package/dist/git/change-coupling.js +250 -0
- package/dist/graph/incremental.d.ts +35 -0
- package/dist/graph/incremental.js +319 -0
- package/dist/graph/memo-cache.d.ts +47 -0
- package/dist/graph/memo-cache.js +176 -0
- package/dist/graph/scc.d.ts +57 -0
- package/dist/graph/scc.js +206 -0
- package/dist/graph.d.ts +6 -0
- package/dist/graph.js +17 -1
- package/dist/index.js +151 -11
- package/dist/scoring/pagerank.d.ts +67 -0
- package/dist/scoring/pagerank.js +221 -0
- package/dist/scoring/risk-scorer.d.ts +99 -0
- package/dist/scoring/risk-scorer.js +623 -0
- package/dist/tools/analyze-impact.d.ts +36 -1
- package/dist/tools/analyze-impact.js +278 -2
- package/dist/tools/gate-build.d.ts +7 -2
- package/dist/tools/gate-build.js +179 -13
- package/dist/watcher/file-cache.d.ts +9 -0
- package/dist/watcher/file-cache.js +40 -0
- package/dist/web/server.js +20 -3
- package/package.json +1 -1
|
@@ -38,6 +38,8 @@ const fs = __importStar(require("fs"));
|
|
|
38
38
|
const path = __importStar(require("path"));
|
|
39
39
|
const events_1 = require("events");
|
|
40
40
|
const plugin_1 = require("../languages/plugin");
|
|
41
|
+
const incremental_1 = require("../graph/incremental");
|
|
42
|
+
const memo_cache_1 = require("../graph/memo-cache");
|
|
41
43
|
/**
|
|
42
44
|
* FileCache: Holds ALL source files in memory.
|
|
43
45
|
* Emits "change" events when files are modified on disk.
|
|
@@ -51,6 +53,7 @@ class FileCache extends events_1.EventEmitter {
|
|
|
51
53
|
this.watcher = null;
|
|
52
54
|
this.debounceTimers = new Map();
|
|
53
55
|
this.DEBOUNCE_MS = 1500;
|
|
56
|
+
this.graph = null;
|
|
54
57
|
this.plugins = (0, plugin_1.detectLanguages)(projectRoot);
|
|
55
58
|
// Collect all extensions from detected plugins
|
|
56
59
|
const allExts = new Set();
|
|
@@ -73,6 +76,15 @@ class FileCache extends events_1.EventEmitter {
|
|
|
73
76
|
get sourceDir() {
|
|
74
77
|
return this.sourceDirs[0] || path.join(this.projectRoot, "src");
|
|
75
78
|
}
|
|
79
|
+
/**
|
|
80
|
+
* Set the dependency graph reference for incremental updates.
|
|
81
|
+
* When a graph is set, file changes will trigger incremental
|
|
82
|
+
* edge updates and memo cache invalidation instead of requiring
|
|
83
|
+
* a full graph rebuild.
|
|
84
|
+
*/
|
|
85
|
+
setGraph(graph) {
|
|
86
|
+
this.graph = graph;
|
|
87
|
+
}
|
|
76
88
|
/** Load ALL source files into memory on startup */
|
|
77
89
|
initialize() {
|
|
78
90
|
let totalLines = 0;
|
|
@@ -173,6 +185,34 @@ class FileCache extends events_1.EventEmitter {
|
|
|
173
185
|
};
|
|
174
186
|
console.error(`[syke:cache] ${type.toUpperCase()}: ${relPath} (${diff.length} changes)`);
|
|
175
187
|
this.emit("change", change);
|
|
188
|
+
// Incremental graph update (if graph is available)
|
|
189
|
+
if (this.graph) {
|
|
190
|
+
try {
|
|
191
|
+
let result;
|
|
192
|
+
if (type === "modified") {
|
|
193
|
+
result = (0, incremental_1.updateGraphForFile)(this.graph, absPath, this.projectRoot);
|
|
194
|
+
}
|
|
195
|
+
else if (type === "added") {
|
|
196
|
+
result = (0, incremental_1.addFileToGraph)(this.graph, absPath, this.projectRoot);
|
|
197
|
+
}
|
|
198
|
+
else {
|
|
199
|
+
// deleted
|
|
200
|
+
result = (0, incremental_1.removeFileFromGraph)(this.graph, absPath);
|
|
201
|
+
}
|
|
202
|
+
// Invalidate memo cache for affected files
|
|
203
|
+
if (result.edgesChanged && result.affectedFiles.length > 0) {
|
|
204
|
+
const invalidated = (0, memo_cache_1.getMemoCache)().invalidate(result.affectedFiles);
|
|
205
|
+
console.error(`[syke:incremental] ${type}: ${relPath} — ` +
|
|
206
|
+
`+${result.addedEdges.length}/-${result.removedEdges.length} edges, ` +
|
|
207
|
+
`${result.affectedFiles.length} affected, ${invalidated} cache entries invalidated`);
|
|
208
|
+
}
|
|
209
|
+
// Emit graph-updated event for downstream consumers (e.g., SSE broadcast)
|
|
210
|
+
this.emit("graph-updated", result);
|
|
211
|
+
}
|
|
212
|
+
catch (err) {
|
|
213
|
+
console.error(`[syke:incremental] Error updating graph for ${relPath}: ${err.message}`);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
176
216
|
}
|
|
177
217
|
/** Simple line-by-line diff */
|
|
178
218
|
computeDiff(oldContent, newContent) {
|
package/dist/web/server.js
CHANGED
|
@@ -292,6 +292,23 @@ function createWebServer(getGraphFn, initialFileCache, switchProjectFn, getProje
|
|
|
292
292
|
});
|
|
293
293
|
// Wire FileCache change events → SSE broadcast + AI analysis
|
|
294
294
|
function wireFileCacheEvents(cache) {
|
|
295
|
+
// Give the FileCache a reference to the current graph for incremental updates
|
|
296
|
+
const graph = getGraphFn();
|
|
297
|
+
cache.setGraph(graph);
|
|
298
|
+
// Listen for incremental graph updates (emitted after file changes update edges)
|
|
299
|
+
cache.on("graph-updated", (result) => {
|
|
300
|
+
if (result.edgesChanged) {
|
|
301
|
+
console.error(`[syke:sse] Graph incrementally updated: ${result.updatedFile} ` +
|
|
302
|
+
`(+${result.addedEdges.length}/-${result.removedEdges.length} edges, ` +
|
|
303
|
+
`${result.affectedFiles.length} affected files)`);
|
|
304
|
+
broadcastSSE("graph-incremental-update", {
|
|
305
|
+
file: path.relative(getGraphFn().sourceDir, result.updatedFile).replace(/\\/g, "/"),
|
|
306
|
+
addedEdges: result.addedEdges.length,
|
|
307
|
+
removedEdges: result.removedEdges.length,
|
|
308
|
+
affectedFiles: result.affectedFiles.length,
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
});
|
|
295
312
|
cache.on("change", async (change) => {
|
|
296
313
|
const graph = getGraphFn();
|
|
297
314
|
const absPath = path.normalize(path.join(graph.sourceDir, change.relativePath));
|
|
@@ -467,7 +484,7 @@ function createWebServer(getGraphFn, initialFileCache, switchProjectFn, getProje
|
|
|
467
484
|
res.json({ nodes, edges, totalFiles: graph.files.size, limited: !isPro && graph.files.size > FREE_GRAPH_LIMIT });
|
|
468
485
|
});
|
|
469
486
|
// GET /api/impact/:file — Impact analysis for a specific file
|
|
470
|
-
app.get("/api/impact/*splat", (req, res) => {
|
|
487
|
+
app.get("/api/impact/*splat", async (req, res) => {
|
|
471
488
|
const splat = req.params.splat;
|
|
472
489
|
const fileParam = Array.isArray(splat) ? splat.join("/") : splat;
|
|
473
490
|
if (!fileParam) {
|
|
@@ -478,7 +495,7 @@ function createWebServer(getGraphFn, initialFileCache, switchProjectFn, getProje
|
|
|
478
495
|
if (!graph.files.has(resolved)) {
|
|
479
496
|
return res.status(404).json({ error: `File not found in graph: ${fileParam}` });
|
|
480
497
|
}
|
|
481
|
-
const result = (0, analyze_impact_1.analyzeImpact)(resolved, graph);
|
|
498
|
+
const result = await (0, analyze_impact_1.analyzeImpact)(resolved, graph);
|
|
482
499
|
res.json(result);
|
|
483
500
|
});
|
|
484
501
|
// POST /api/ai-analyze — AI semantic analysis (Pro or BYOK)
|
|
@@ -508,7 +525,7 @@ function createWebServer(getGraphFn, initialFileCache, switchProjectFn, getProje
|
|
|
508
525
|
return res.status(403).json({ error: "This file exceeds the Free tier limit (50 files). Upgrade to Pro for unlimited analysis.", upgrade: "https://syke.cloud/dashboard/" });
|
|
509
526
|
}
|
|
510
527
|
}
|
|
511
|
-
const impactResult = (0, analyze_impact_1.analyzeImpact)(resolved, graph);
|
|
528
|
+
const impactResult = await (0, analyze_impact_1.analyzeImpact)(resolved, graph);
|
|
512
529
|
try {
|
|
513
530
|
const aiResult = await (0, analyzer_1.analyzeWithAI)(resolved, impactResult, graph);
|
|
514
531
|
const partial = !isPro && graph.files.size > 50;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@syke1/mcp-server",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.18",
|
|
4
4
|
"mcpName": "io.github.khalomsky/syke",
|
|
5
5
|
"description": "AI code impact analysis MCP server — dependency graphs, cascade detection, and a mandatory build gate for AI coding agents",
|
|
6
6
|
"main": "dist/index.js",
|