@syke1/mcp-server 1.4.18 → 1.4.20
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 +82 -0
- package/dist/index.js +1 -1
- package/dist/license/validator.js +1 -1
- package/dist/web/public/app.js +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -113,6 +113,88 @@ SYKE supports three AI providers for semantic analysis. Bring your own key:
|
|
|
113
113
|
**Auto-selection:** SYKE uses the first available key (Gemini > OpenAI > Anthropic).
|
|
114
114
|
**Force provider:** Set `aiProvider` in config (or `SYKE_AI_PROVIDER` env var) to override.
|
|
115
115
|
|
|
116
|
+
### Advanced Graph Algorithms
|
|
117
|
+
|
|
118
|
+
SYKE goes beyond simple dependency counting. Five production-grade algorithms work together to deliver precise, fast, and context-rich impact analysis — all running **locally with zero AI token cost**.
|
|
119
|
+
|
|
120
|
+
#### 1. SCC Condensation + Topological Sort
|
|
121
|
+
|
|
122
|
+
Circular dependencies are the #1 source of misleading impact analysis. SYKE uses **Tarjan's algorithm** to detect all Strongly Connected Components, condenses them into a clean DAG, then runs topological sort to compute correct cascade levels.
|
|
123
|
+
|
|
124
|
+
```
|
|
125
|
+
Before: "47 files affected" (inflated by cycles)
|
|
126
|
+
After: "3 files in circular cluster (Level 0) → 5 files (Level 1) → 4 files (Level 2)"
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
- O(V+E) computation — runs in single-digit milliseconds
|
|
130
|
+
- Every SCC with size > 1 is flagged as a circular dependency cluster
|
|
131
|
+
- Cascade levels are accurate even in heavily cyclic codebases
|
|
132
|
+
|
|
133
|
+
#### 2. Composite Risk Scoring
|
|
134
|
+
|
|
135
|
+
Five signals combined into a single 0–1 risk score:
|
|
136
|
+
|
|
137
|
+
| Signal | Weight | What it measures |
|
|
138
|
+
|--------|--------|-----------------|
|
|
139
|
+
| **Fan-in** | 30% | How many files depend on this one |
|
|
140
|
+
| **Stability Index** | 20% | I = Ce/(Ca+Ce) — lower = foundation file = riskier to change |
|
|
141
|
+
| **Cyclomatic Complexity** | 20% | Internal branching complexity (regex-based, 8 languages) |
|
|
142
|
+
| **Cascade Depth** | 15% | How many layers deep the impact propagates |
|
|
143
|
+
| **PageRank** | 15% | Recursive importance in the dependency graph |
|
|
144
|
+
|
|
145
|
+
```
|
|
146
|
+
auth_service.ts → Risk: 0.82 (CRITICAL)
|
|
147
|
+
Fan-in: 24, Stability: 0.12, Complexity: 47, Cascade: 4 levels, PageRank: 99th
|
|
148
|
+
|
|
149
|
+
string_utils.ts → Risk: 0.31 (LOW)
|
|
150
|
+
Fan-in: 18, Stability: 0.85, Complexity: 3, Cascade: 1 level, PageRank: 42nd
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
AI agents can now make threshold decisions: proceed if < 0.3, warn if 0.3–0.7, block if > 0.7.
|
|
154
|
+
|
|
155
|
+
#### 3. Historical Change Coupling
|
|
156
|
+
|
|
157
|
+
Static imports miss **hidden dependencies** — files that always change together but have no import relationship. SYKE mines your git history (last 500 commits) to find these logical couplings.
|
|
158
|
+
|
|
159
|
+
```
|
|
160
|
+
auth_service.ts changed →
|
|
161
|
+
[Dependency Graph] auth_provider.ts, login_screen.ts
|
|
162
|
+
[Git Coupling — Hidden Dependencies]
|
|
163
|
+
config/auth_config.json (85% confidence, 12 co-changes)
|
|
164
|
+
styles/auth.css (72% confidence, 8 co-changes)
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
- Catches 15–30% of impacted files that static analysis misses entirely
|
|
168
|
+
- Filters mega-commits (>20 files) to avoid noise
|
|
169
|
+
- 5-minute cache with auto-refresh
|
|
170
|
+
|
|
171
|
+
#### 4. PageRank for File Importance
|
|
172
|
+
|
|
173
|
+
Simple fan-in counts treat all dependents equally. **PageRank** computes recursive importance — a file imported by many *important* files ranks higher than one imported by many leaf files.
|
|
174
|
+
|
|
175
|
+
```
|
|
176
|
+
Before: utils.ts ranked #1 (25 dependents — but all are leaf components)
|
|
177
|
+
After: auth.ts ranked #1 (20 dependents — 15 of which are core modules)
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
- Standard Power Iteration with damping factor 0.85
|
|
181
|
+
- Precomputed at startup, incrementally updated on file changes
|
|
182
|
+
- Every file gets a rank position and percentile (e.g., "rank #3 of 245, 99th percentile")
|
|
183
|
+
|
|
184
|
+
#### 5. Incremental Graph Updates + Memoized Queries
|
|
185
|
+
|
|
186
|
+
For large codebases (10K+ files), full graph rebuilds are too slow. SYKE now updates **only the changed file's edges** and invalidates **only the affected cache entries**.
|
|
187
|
+
|
|
188
|
+
```
|
|
189
|
+
Before: 1 file changed → re-parse all 500 files → 2+ seconds
|
|
190
|
+
After: 1 file changed → re-parse 1 file → edge diff → 50ms
|
|
191
|
+
Same file queried again → cache hit → O(1) instant
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
- Reverse index enables O(affected) cache invalidation instead of O(cache_size)
|
|
195
|
+
- SCC and PageRank recompute after edge changes (still < 100ms for 10K files)
|
|
196
|
+
- 500-entry LRU cache with hit/miss diagnostics
|
|
197
|
+
|
|
116
198
|
### Language Support
|
|
117
199
|
|
|
118
200
|
Auto-detected, zero-config: **Dart/Flutter**, **TypeScript/JavaScript**, **Python**, **Go**, **Rust**, **Java**, **C++**, **Ruby**.
|
package/dist/index.js
CHANGED
|
@@ -704,7 +704,7 @@ async function main() {
|
|
|
704
704
|
const { app: webApp, setFileCache: setWebFileCache } = (0, server_1.createWebServer)(() => (0, graph_1.getGraph)(currentProjectRoot, currentPackageName), fileCache, switchProject, () => currentProjectRoot, () => currentPackageName, () => licenseStatus, () => !!(0, provider_1.getAIProvider)(), async (key) => {
|
|
705
705
|
// Stop existing heartbeat/session
|
|
706
706
|
await (0, validator_1.stopAndDeactivate)();
|
|
707
|
-
if (key && key.startsWith("SYKE-")) {
|
|
707
|
+
if (key && (key.startsWith("SYKE-") || key.startsWith("FOUNDING-"))) {
|
|
708
708
|
(0, config_1.setConfig)("licenseKey", key);
|
|
709
709
|
(0, validator_1.clearLicenseCache)(); // clear stale cache from previous key
|
|
710
710
|
try {
|
|
@@ -84,7 +84,7 @@ function getDeviceName() {
|
|
|
84
84
|
*/
|
|
85
85
|
function getLicenseKey() {
|
|
86
86
|
const key = (0, config_1.getConfig)("licenseKey", "SYKE_LICENSE_KEY");
|
|
87
|
-
if (key && key.startsWith("SYKE-"))
|
|
87
|
+
if (key && (key.startsWith("SYKE-") || key.startsWith("FOUNDING-")))
|
|
88
88
|
return key;
|
|
89
89
|
return null;
|
|
90
90
|
}
|
package/dist/web/public/app.js
CHANGED
|
@@ -3869,9 +3869,9 @@ function setupLicenseModal() {
|
|
|
3869
3869
|
|
|
3870
3870
|
activateBtn.addEventListener("click", async () => {
|
|
3871
3871
|
const key = input.value.trim();
|
|
3872
|
-
if (!key || !key.startsWith("SYKE-")) {
|
|
3872
|
+
if (!key || !(key.startsWith("SYKE-") || key.startsWith("FOUNDING-"))) {
|
|
3873
3873
|
statusEl.className = "error";
|
|
3874
|
-
statusEl.textContent = "Key must start with SYKE-";
|
|
3874
|
+
statusEl.textContent = "Key must start with SYKE- or FOUNDING-";
|
|
3875
3875
|
return;
|
|
3876
3876
|
}
|
|
3877
3877
|
statusEl.className = "loading";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@syke1/mcp-server",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.20",
|
|
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",
|