fivocell 6.0.0 → 6.0.2
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/__tests__/memory-compact.test.js +4 -5
- package/dist/__tests__/memory-compact.test.js.map +1 -1
- package/dist/walls/06-memory/archive/memory-archive.d.ts.map +1 -1
- package/dist/walls/06-memory/archive/memory-archive.js +25 -7
- package/dist/walls/06-memory/archive/memory-archive.js.map +1 -1
- package/dist/walls/06-memory/archive/memory-compact.d.ts +1 -1
- package/dist/walls/06-memory/archive/memory-compact.d.ts.map +1 -1
- package/dist/walls/06-memory/archive/memory-compact.js +4 -18
- package/dist/walls/06-memory/archive/memory-compact.js.map +1 -1
- package/dist/walls/06-memory/database/database.d.ts.map +1 -1
- package/dist/walls/06-memory/database/database.js +45 -39
- package/dist/walls/06-memory/database/database.js.map +1 -1
- package/dist/walls/06-memory/database/migrations.d.ts.map +1 -1
- package/dist/walls/06-memory/database/migrations.js +35 -0
- package/dist/walls/06-memory/database/migrations.js.map +1 -1
- package/dist/walls/06-memory/stores/memory-event-store.d.ts +1 -1
- package/dist/walls/06-memory/stores/memory-event-store.d.ts.map +1 -1
- package/dist/walls/06-memory/stores/memory-event-store.js +40 -9
- package/dist/walls/06-memory/stores/memory-event-store.js.map +1 -1
- package/dist/walls/06-memory/stores/memory-health.d.ts +1 -0
- package/dist/walls/06-memory/stores/memory-health.d.ts.map +1 -1
- package/dist/walls/06-memory/stores/memory-health.js +13 -4
- package/dist/walls/06-memory/stores/memory-health.js.map +1 -1
- package/dist/walls/06-memory/stores/memory-search.d.ts.map +1 -1
- package/dist/walls/06-memory/stores/memory-search.js +72 -4
- package/dist/walls/06-memory/stores/memory-search.js.map +1 -1
- package/dist/walls/06-memory/stores/summary-generator.d.ts +6 -0
- package/dist/walls/06-memory/stores/summary-generator.d.ts.map +1 -1
- package/dist/walls/06-memory/stores/summary-generator.js +219 -0
- package/dist/walls/06-memory/stores/summary-generator.js.map +1 -1
- package/dist/walls/06-memory/stores/sync-engine.d.ts.map +1 -1
- package/dist/walls/06-memory/stores/sync-engine.js +33 -12
- package/dist/walls/06-memory/stores/sync-engine.js.map +1 -1
- package/dist/walls/07-runtime/daemon/server.d.ts.map +1 -1
- package/dist/walls/07-runtime/daemon/server.js +96 -133
- package/dist/walls/07-runtime/daemon/server.js.map +1 -1
- package/dist/walls/07-runtime/watcher/live-watcher.d.ts.map +1 -1
- package/dist/walls/07-runtime/watcher/live-watcher.js +34 -0
- package/dist/walls/07-runtime/watcher/live-watcher.js.map +1 -1
- package/package.json +1 -1
|
@@ -136,7 +136,7 @@ function getCloudConfig() {
|
|
|
136
136
|
}
|
|
137
137
|
const app = (0, express_1.default)();
|
|
138
138
|
exports.app = app;
|
|
139
|
-
// All 40 modules instantiated
|
|
139
|
+
// All 40 modules instantiated — verifies they work in daemon context
|
|
140
140
|
const sharedPatternStore = new pattern_store_1.PatternStore(CELL_DIR);
|
|
141
141
|
const engines = {
|
|
142
142
|
signalCapture: new signal_capture_1.SignalCapture(),
|
|
@@ -215,17 +215,17 @@ app.post('/signal', (req, res) => {
|
|
|
215
215
|
res.status(400).json({ error: 'type required' });
|
|
216
216
|
return;
|
|
217
217
|
}
|
|
218
|
-
//
|
|
218
|
+
// ─── Behavioral Signals ───────────────────────────────────────
|
|
219
219
|
if (type === 'error') {
|
|
220
220
|
const { logError, getErrorPatterns } = require('../../03-knowledge/decisions/');
|
|
221
221
|
const r = logError({ project, file, errorType, errorMessage, line });
|
|
222
|
-
// Check if repeat mistake
|
|
222
|
+
// Check if repeat mistake — send warning
|
|
223
223
|
let warning = null;
|
|
224
224
|
try {
|
|
225
225
|
const patterns = getErrorPatterns(project);
|
|
226
226
|
const match = patterns.find((p) => p.error_type === errorType);
|
|
227
227
|
if (match && match.count >= 2) {
|
|
228
|
-
warning =
|
|
228
|
+
warning = `âš Repeat mistake! "${errorType}" has occurred ${match.count}x before. Fix the root cause.`;
|
|
229
229
|
}
|
|
230
230
|
}
|
|
231
231
|
catch { }
|
|
@@ -290,7 +290,7 @@ app.post('/signal', (req, res) => {
|
|
|
290
290
|
res.json({ recorded: true });
|
|
291
291
|
return;
|
|
292
292
|
}
|
|
293
|
-
//
|
|
293
|
+
// ─── IDE Signals ──────────────────────────────────────────────
|
|
294
294
|
if (type === 'model_use') {
|
|
295
295
|
// Track AI model interaction
|
|
296
296
|
try {
|
|
@@ -318,7 +318,7 @@ app.post('/signal', (req, res) => {
|
|
|
318
318
|
res.json({ recorded: true, type });
|
|
319
319
|
return;
|
|
320
320
|
}
|
|
321
|
-
//
|
|
321
|
+
// ─── Legacy Signals ──────────────────────────────────────────
|
|
322
322
|
const ctx = context || {};
|
|
323
323
|
let signal;
|
|
324
324
|
let patternsExtracted = 0;
|
|
@@ -425,7 +425,7 @@ app.get('/confidence/:patternId', (req, res) => {
|
|
|
425
425
|
}
|
|
426
426
|
res.json({ patternId: p.patternId, description: p.description, confidence: p.confidence, tier: engines.confidenceEngine.getTier(p.confidence) });
|
|
427
427
|
});
|
|
428
|
-
//
|
|
428
|
+
// ─── IMPACT TRACKING ──────────────────────────────────
|
|
429
429
|
const impactLog = [];
|
|
430
430
|
function persistImpact(entry) {
|
|
431
431
|
try {
|
|
@@ -475,7 +475,7 @@ app.get('/impact/weekly', (_req, res) => {
|
|
|
475
475
|
}).length,
|
|
476
476
|
});
|
|
477
477
|
});
|
|
478
|
-
//
|
|
478
|
+
// ─── CONFIG INFERENCE (Onboarding) ────────────────────
|
|
479
479
|
app.post('/onboarding/scan', (req, res) => {
|
|
480
480
|
const dir = process.cwd();
|
|
481
481
|
const insights = [];
|
|
@@ -484,7 +484,7 @@ app.post('/onboarding/scan', (req, res) => {
|
|
|
484
484
|
if (fs.existsSync(tsconfigPath)) {
|
|
485
485
|
const tsconfig = JSON.parse(fs.readFileSync(tsconfigPath, 'utf-8'));
|
|
486
486
|
if (tsconfig.compilerOptions?.strict)
|
|
487
|
-
insights.push('TypeScript strict mode
|
|
487
|
+
insights.push('TypeScript strict mode → You likely prefer const over let');
|
|
488
488
|
}
|
|
489
489
|
}
|
|
490
490
|
catch (e) {
|
|
@@ -498,7 +498,7 @@ app.post('/onboarding/scan', (req, res) => {
|
|
|
498
498
|
try {
|
|
499
499
|
const eslint = JSON.parse(fs.readFileSync(eslintPath, 'utf-8'));
|
|
500
500
|
if (JSON.stringify(eslint).includes('singlequote') || JSON.stringify(eslint).includes('single'))
|
|
501
|
-
insights.push('ESLint single quotes
|
|
501
|
+
insights.push('ESLint single quotes → You prefer \' over \"');
|
|
502
502
|
}
|
|
503
503
|
catch (e) {
|
|
504
504
|
logger_1.logger.warn('Failed to parse eslint config: ' + String(e));
|
|
@@ -516,17 +516,17 @@ app.post('/onboarding/scan', (req, res) => {
|
|
|
516
516
|
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
|
|
517
517
|
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
518
518
|
if (deps.react)
|
|
519
|
-
insights.push('React detected
|
|
519
|
+
insights.push('React detected → You likely prefer functional components');
|
|
520
520
|
if (deps.next)
|
|
521
|
-
insights.push('Next.js project
|
|
521
|
+
insights.push('Next.js project → You likely prefer SSR patterns');
|
|
522
522
|
if (deps.tailwindcss)
|
|
523
|
-
insights.push('Tailwind CSS
|
|
523
|
+
insights.push('Tailwind CSS → You prefer utility-first styling');
|
|
524
524
|
if (deps.typescript)
|
|
525
|
-
insights.push('TypeScript project
|
|
525
|
+
insights.push('TypeScript project → You prefer type safety');
|
|
526
526
|
if (deps.vitest)
|
|
527
|
-
insights.push('Vitest
|
|
527
|
+
insights.push('Vitest → You prefer fast unit testing');
|
|
528
528
|
if (deps.zod)
|
|
529
|
-
insights.push('Zod
|
|
529
|
+
insights.push('Zod → You prefer schema validation');
|
|
530
530
|
}
|
|
531
531
|
}
|
|
532
532
|
catch (e) {
|
|
@@ -534,42 +534,11 @@ app.post('/onboarding/scan', (req, res) => {
|
|
|
534
534
|
}
|
|
535
535
|
res.json({ insights, count: insights.length, projectPath: dir });
|
|
536
536
|
});
|
|
537
|
-
//
|
|
537
|
+
// ─── LOCAL DASHBOARD HTML ─────────────────────────────
|
|
538
538
|
function escapeHtml(str) {
|
|
539
539
|
return str.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/'/g, ''');
|
|
540
540
|
}
|
|
541
|
-
|
|
542
|
-
const patterns = engines.patternStore.getAllPatterns();
|
|
543
|
-
const strong = patterns.filter((p) => engines.confidenceEngine.getTier(p.confidence) === 'strong');
|
|
544
|
-
const moderate = patterns.filter((p) => engines.confidenceEngine.getTier(p.confidence) === 'moderate');
|
|
545
|
-
const signals = engines.signalCapture.getAllSignals().length;
|
|
546
|
-
const rows = patterns.slice(0, 50).map((p) => `<tr><td>${escapeHtml(p.description)}</td><td>${escapeHtml(p.from)} → ${escapeHtml(p.to)}</td><td>${p.confidence?.mean?.toFixed(2) || '0'}</td><td>${engines.confidenceEngine.getTier(p.confidence)}</td><td>${p.signals?.total || 0}</td></tr>`).join('');
|
|
547
|
-
res.send(`<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Cell — Dashboard</title>
|
|
548
|
-
<style>*{margin:0;padding:0;box-sizing:border-box}body{font-family:-apple-system,BlinkMacSystemFont,sans-serif;background:#F7F4F0;color:#2E3138;padding:24px;min-height:100vh;display:flex;flex-direction:column}
|
|
549
|
-
h1{font-size:24px;margin-bottom:8px}h1 span{color:#FF5A4E}.stats{display:flex;gap:16px;margin:20px 0}
|
|
550
|
-
.stat{background:#fff;border:1px solid #e8e5e0;border-radius:8px;padding:16px;flex:1;text-align:center;box-shadow:0 2px 8px rgba(255,90,78,0.06)}
|
|
551
|
-
.stat .num{font-size:28px;font-weight:700;color:#FF5A4E}.stat .label{font-size:12px;color:#8b8b8b;margin-top:4px}
|
|
552
|
-
table{width:100%;border-collapse:collapse;margin-top:20px;background:#fff;border-radius:8px;overflow:hidden;box-shadow:0 2px 8px rgba(0,0,0,0.04)}
|
|
553
|
-
th,td{padding:10px 12px;text-align:left;border-bottom:1px solid #f0ede8}th{background:#faf8f5;font-weight:600;font-size:13px;color:#2E3138}
|
|
554
|
-
tr:hover{background:#fff5f3}.tier{display:inline-block;padding:2px 8px;border-radius:12px;font-size:11px;font-weight:600}
|
|
555
|
-
.tier-strong{background:#FF5A4E18;color:#FF5A4E}.tier-moderate{background:#FFB3A730;color:#d4770a}.tier-weak{background:#f0ede8;color:#8b8b8b}
|
|
556
|
-
.footer{margin-top:auto;padding:16px 0;text-align:center;font-size:12px;color:#8b8b8b;border-top:1px solid #f0ede8}
|
|
557
|
-
.footer a{color:#FF5A4E;text-decoration:none}.footer a:hover{text-decoration:underline}
|
|
558
|
-
.glow{position:fixed;top:-100px;right:-100px;width:300px;height:300px;background:radial-gradient(circle,#FFB3A720,#FFD7D010,transparent 70%);pointer-events:none;z-index:0}
|
|
559
|
-
</style></head><body>
|
|
560
|
-
<div class="glow"></div>
|
|
561
|
-
<h1>🧠 <span>Cell</span> — Dashboard</h1>
|
|
562
|
-
<div class="stats">
|
|
563
|
-
<div class="stat"><div class="num">${patterns.length}</div><div class="label">Total Patterns</div></div>
|
|
564
|
-
<div class="stat"><div class="num">${strong.length}</div><div class="label">Strong (>0.80)</div></div>
|
|
565
|
-
<div class="stat"><div class="num">${moderate.length}</div><div class="label">Moderate</div></div>
|
|
566
|
-
<div class="stat"><div class="num">${signals}</div><div class="label">Signals</div></div>
|
|
567
|
-
</div>
|
|
568
|
-
<table><thead><tr><th>Pattern</th><th>Change</th><th>Confidence</th><th>Tier</th><th>Signals</th></tr></thead><tbody>${rows}</tbody></table>
|
|
569
|
-
<div class="footer"><a href="https://github.com/thevinsoni/cell" target="_blank">FIVO Cell</a> — Open source. Local-first. Free forever.</div>
|
|
570
|
-
</body></html>`);
|
|
571
|
-
});
|
|
572
|
-
// ─── CROSS-LANGUAGE MAPPINGS ──────────────────────────
|
|
541
|
+
// ─── CROSS-LANGUAGE MAPPINGS ──────────────────────────
|
|
573
542
|
app.get('/cross-language/transfer', (req, res) => {
|
|
574
543
|
const source = req.query.source || '';
|
|
575
544
|
const target = req.query.target || '';
|
|
@@ -580,7 +549,7 @@ app.get('/cross-language/transfer', (req, res) => {
|
|
|
580
549
|
res.json({ source, target, concepts: (0, cross_language_mappings_1.getTransferableConcepts)(source, target) });
|
|
581
550
|
});
|
|
582
551
|
app.get('/cross-language/languages', (_req, res) => { res.json({ languages: (0, cross_language_mappings_1.getSupportedLanguages)() }); });
|
|
583
|
-
//
|
|
552
|
+
// ─── WORKFLOW SUCCESS PREDICTION ──────────────────────
|
|
584
553
|
app.get('/workflow/active', (_req, res) => {
|
|
585
554
|
res.json({ workflows: (0, workflow_tracker_1.getActiveWorkflows)() });
|
|
586
555
|
});
|
|
@@ -618,7 +587,7 @@ app.get('/workflow/history', (req, res) => {
|
|
|
618
587
|
const limit = req.query.limit ? parseInt(req.query.limit) : 50;
|
|
619
588
|
res.json({ outcomes: (0, outcome_recorder_1.getOutcomeHistory)(limit) });
|
|
620
589
|
});
|
|
621
|
-
//
|
|
590
|
+
// ─── FAILURE MEMORY ───────────────────────────────────
|
|
622
591
|
app.get('/failure/suggestions', (req, res) => {
|
|
623
592
|
const minRate = req.query.minRate ? parseFloat(req.query.minRate) : 0.5;
|
|
624
593
|
res.json({ suggestions: (0, failure_memory_1.getAvoidSuggestions)(minRate) });
|
|
@@ -637,14 +606,14 @@ app.get('/failure/records/:patternId', (req, res) => {
|
|
|
637
606
|
}
|
|
638
607
|
res.json(record);
|
|
639
608
|
});
|
|
640
|
-
//
|
|
609
|
+
// ─── TIME SAVED DASHBOARD ────────────────────────────────
|
|
641
610
|
app.get('/time-saved/stats', (_req, res) => {
|
|
642
611
|
res.json((0, time_saved_1.getTimeSavedStats)());
|
|
643
612
|
});
|
|
644
613
|
app.get('/time-saved/pattern/:patternId', (req, res) => {
|
|
645
614
|
res.json((0, time_saved_1.getTimeSavedByPattern)(req.params.patternId));
|
|
646
615
|
});
|
|
647
|
-
//
|
|
616
|
+
// ─── EXPLAINABILITY ─────────────────────────────────────
|
|
648
617
|
app.get('/explain/pattern/:patternId', (req, res) => {
|
|
649
618
|
const patterns = engines.patternStore.getAllPatterns();
|
|
650
619
|
const pattern = patterns.find((p) => p.patternId === req.params.patternId);
|
|
@@ -664,7 +633,7 @@ app.post('/explain/patterns', (req, res) => {
|
|
|
664
633
|
const matched = allPatterns.filter((p) => patternIds.includes(p.patternId));
|
|
665
634
|
res.json({ explanations: (0, explainability_1.explainPatternList)(matched) });
|
|
666
635
|
});
|
|
667
|
-
//
|
|
636
|
+
// ─── AI MEMORY ──────────────────────────────────────────
|
|
668
637
|
app.get('/memory/stats', (_req, res) => {
|
|
669
638
|
res.json((0, ai_memory_1.getMemoryStats)());
|
|
670
639
|
});
|
|
@@ -686,7 +655,7 @@ app.delete('/memory/clear', (_req, res) => {
|
|
|
686
655
|
(0, ai_memory_1.clearAllMemory)();
|
|
687
656
|
res.json({ cleared: true });
|
|
688
657
|
});
|
|
689
|
-
//
|
|
658
|
+
// ─── PROJECT DNA ────────────────────────────────────────
|
|
690
659
|
app.post('/project/build', (req, res) => {
|
|
691
660
|
const { projectId, name } = req.body;
|
|
692
661
|
if (!projectId) {
|
|
@@ -755,7 +724,7 @@ app.get('/project/dna-compare', (req, res) => {
|
|
|
755
724
|
app.delete('/project/dna/:projectId', (req, res) => {
|
|
756
725
|
res.json({ deleted: (0, project_dna_1.deleteDNA)(req.params.projectId) });
|
|
757
726
|
});
|
|
758
|
-
//
|
|
727
|
+
// ─── KNOWLEDGE GRAPH ────────────────────────────────────
|
|
759
728
|
app.post('/graph/rebuild', (_req, res) => {
|
|
760
729
|
const patterns = engines.patternStore.getAllPatterns();
|
|
761
730
|
const g = (0, knowledge_graph_1.buildKnowledgeGraph)(patterns.map((p) => ({
|
|
@@ -788,14 +757,14 @@ app.get('/graph/related/:patternId', (req, res) => {
|
|
|
788
757
|
app.get('/graph/full', (_req, res) => {
|
|
789
758
|
res.json((0, knowledge_graph_1.getKnowledgeGraph)());
|
|
790
759
|
});
|
|
791
|
-
//
|
|
760
|
+
// ─── CONVENTION DETECTOR ────────────────────────────────
|
|
792
761
|
app.post('/conventions/detect', (req, res) => {
|
|
793
762
|
const { projectId } = req.body;
|
|
794
763
|
const patterns = engines.patternStore.getAllPatterns();
|
|
795
764
|
const report = (0, convention_detector_1.detectConventions)(projectId || 'default', patterns);
|
|
796
765
|
res.json(report);
|
|
797
766
|
});
|
|
798
|
-
//
|
|
767
|
+
// ─── AI COST OPTIMIZATION ──────────────────────────────
|
|
799
768
|
app.get('/cost/models', (_req, res) => {
|
|
800
769
|
res.json({ models: (0, cost_optimizer_1.getAvailableModels)() });
|
|
801
770
|
});
|
|
@@ -833,7 +802,7 @@ app.delete('/cost/clear', (_req, res) => {
|
|
|
833
802
|
(0, cost_optimizer_1.clearCostLog)();
|
|
834
803
|
res.json({ cleared: true });
|
|
835
804
|
});
|
|
836
|
-
//
|
|
805
|
+
// ─── REPUTATION ─────────────────────────────────────────
|
|
837
806
|
app.post('/reputation/init', (req, res) => {
|
|
838
807
|
const { deviceId, displayName } = req.body;
|
|
839
808
|
if (!deviceId) {
|
|
@@ -867,7 +836,7 @@ app.get('/reputation/leaderboard', (req, res) => {
|
|
|
867
836
|
app.get('/reputation/badges', (_req, res) => {
|
|
868
837
|
res.json({ badges: (0, reputation_1.getAllBadges)() });
|
|
869
838
|
});
|
|
870
|
-
//
|
|
839
|
+
// ─── PLAYBOOK GENERATOR ──────────────────────────────────
|
|
871
840
|
app.post('/playbook/generate', (req, res) => {
|
|
872
841
|
const { projectId } = req.body;
|
|
873
842
|
if (!projectId) {
|
|
@@ -893,7 +862,7 @@ app.get('/playbook/:projectId', (req, res) => {
|
|
|
893
862
|
app.get('/playbook/list', (_req, res) => {
|
|
894
863
|
res.json({ playbooks: (0, playbook_generator_1.listPlaybooks)() });
|
|
895
864
|
});
|
|
896
|
-
//
|
|
865
|
+
// ─── PHASE 8: ONBOARDING + PROMOTION ──────────────────
|
|
897
866
|
app.get('/onboarding/banner', (_req, res) => {
|
|
898
867
|
const signals = engines.signalCapture.getAllSignals().length;
|
|
899
868
|
const patterns = engines.patternStore.getAllPatterns();
|
|
@@ -915,7 +884,7 @@ app.get('/impact/weekly-card', (_req, res) => {
|
|
|
915
884
|
topPatterns: patterns.slice(0, 3).map((p) => ({ description: p.description, confidence: p.confidence?.mean?.toFixed(2) })),
|
|
916
885
|
});
|
|
917
886
|
});
|
|
918
|
-
//
|
|
887
|
+
// ─── GLOBAL PATTERN INTELLIGENCE NETWORK (STREAMING) ──
|
|
919
888
|
app.get('/streaming/status', (_req, res) => {
|
|
920
889
|
res.json({
|
|
921
890
|
connected: (0, ws_client_1.isStreamingConnected)(),
|
|
@@ -937,13 +906,7 @@ app.post('/streaming/stop', (_req, res) => {
|
|
|
937
906
|
app.get('/sync/queue-status', (_req, res) => {
|
|
938
907
|
res.json({ pending: engines.offlineQueue.getPendingCount?.() || 0, lastFlush: engines.offlineQueue.getLastFlush?.() || null });
|
|
939
908
|
});
|
|
940
|
-
|
|
941
|
-
res.json({ pending: engines.offlineQueue.getPendingCount?.() || 0, lastFlush: engines.offlineQueue.getLastFlush?.() || null });
|
|
942
|
-
});
|
|
943
|
-
app.get('/sync/queue-status', (_req, res) => {
|
|
944
|
-
res.json({ pending: engines.offlineQueue.getPendingCount?.() || 0, lastFlush: engines.offlineQueue.getLastFlush?.() || null });
|
|
945
|
-
});
|
|
946
|
-
// ─── PHASE 9 ENDPOINTS ──────────────────────────────
|
|
909
|
+
// ─── PHASE 9 ENDPOINTS ──────────────────────────────
|
|
947
910
|
app.get('/models/insights', (req, res) => {
|
|
948
911
|
const model = req.query.model;
|
|
949
912
|
if (model) {
|
|
@@ -954,7 +917,7 @@ app.get('/models/insights', (req, res) => {
|
|
|
954
917
|
res.json({ models: (0, model_intelligence_1.compareModels)() });
|
|
955
918
|
});
|
|
956
919
|
app.get('/models/compare', (_req, res) => { res.json({ models: (0, model_intelligence_1.compareModels)() }); });
|
|
957
|
-
//
|
|
920
|
+
// ─── MCP ENDPOINTS ────────────────────────────────────
|
|
958
921
|
app.get('/predict/next-action', (req, res) => {
|
|
959
922
|
const patterns = engines.patternStore.getAllPatterns();
|
|
960
923
|
const actions = engines.nextActionPredictor.predictNext(patterns);
|
|
@@ -984,7 +947,7 @@ app.get('/identity/status', (_req, res) => {
|
|
|
984
947
|
const identity = (0, identity_resolver_1.createIdentityPayload)('daemon');
|
|
985
948
|
res.json({ fingerprint: identity.fingerprint, tool: identity.tool });
|
|
986
949
|
});
|
|
987
|
-
//
|
|
950
|
+
// ─── MARKETPLACE ─────────────────────────────────────
|
|
988
951
|
app.get('/marketplace/packages', (_req, res) => { res.json({ packages: (0, marketplace_1.getAllPackages)() }); });
|
|
989
952
|
app.get('/marketplace/search', (req, res) => { res.json({ results: (0, marketplace_1.searchPackages)(String(req.query.q || '')) }); });
|
|
990
953
|
app.get('/marketplace/package/:id', (req, res) => { const p = (0, marketplace_1.getPackage)(req.params.id); if (!p) {
|
|
@@ -1002,7 +965,7 @@ app.post('/marketplace/package/:id/rate', (req, res) => { const { author, rating
|
|
|
1002
965
|
} res.json(p); });
|
|
1003
966
|
app.get('/marketplace/package/:id/reviews', (req, res) => { res.json({ reviews: (0, marketplace_1.getReviews)(req.params.id) }); });
|
|
1004
967
|
app.get('/marketplace/stats', (_req, res) => { res.json((0, marketplace_1.getMarketplaceStats)()); });
|
|
1005
|
-
//
|
|
968
|
+
// ─── ORGANIZATION MEMORY ─────────────────────────────
|
|
1006
969
|
app.post('/org/create', (req, res) => { const { name, creatorDeviceId } = req.body; res.json((0, organization_memory_1.createOrganization)(name, creatorDeviceId)); });
|
|
1007
970
|
app.get('/org/:id', (req, res) => { const o = (0, organization_memory_1.getOrganization)(req.params.id); if (!o) {
|
|
1008
971
|
res.status(404).json({ error: 'not found' });
|
|
@@ -1026,14 +989,14 @@ app.post('/org/:id/team/:teamId/add', (req, res) => { const { deviceId, actorDev
|
|
|
1026
989
|
} res.json(o); });
|
|
1027
990
|
app.get('/org/:id/audit', (req, res) => { res.json({ log: (0, organization_memory_1.getAuditLog)(Number(req.query.limit) || 50) }); });
|
|
1028
991
|
app.get('/orgs/list', (_req, res) => { res.json({ organizations: (0, organization_memory_1.listOrganizations)() }); });
|
|
1029
|
-
//
|
|
992
|
+
// ─── WORKFLOW OUTCOME GRAPH ─────────────────────────
|
|
1030
993
|
app.post('/outcome-graph/record', (req, res) => { (0, workflow_outcome_graph_1.recordOutcome)(req.body); res.json({ success: true }); });
|
|
1031
994
|
app.post('/outcome-graph/sequence', (req, res) => { (0, workflow_outcome_graph_1.recordStepSequence)(req.body); res.json({ success: true }); });
|
|
1032
995
|
app.get('/outcome-graph/nodes', (_req, res) => { res.json({ nodes: (0, workflow_outcome_graph_1.getNodes)() }); });
|
|
1033
996
|
app.get('/outcome-graph/edges', (_req, res) => { res.json({ edges: (0, workflow_outcome_graph_1.getEdges)() }); });
|
|
1034
997
|
app.get('/outcome-graph/paths', (req, res) => { const { from, to } = req.query; res.json({ paths: (0, workflow_outcome_graph_1.getPathProbabilities)(String(from), String(to)) }); });
|
|
1035
998
|
app.get('/outcome-graph/stats', (_req, res) => { res.json((0, workflow_outcome_graph_1.getGraphStats)()); });
|
|
1036
|
-
//
|
|
999
|
+
// ─── AI MEMORY UPGRADE ───────────────────────────────
|
|
1037
1000
|
app.post('/memory/search/index', (_req, res) => { (0, ai_memory_1.indexMemoryForSearch)(); res.json({ success: true }); });
|
|
1038
1001
|
app.get('/memory/search', (req, res) => { res.json({ results: (0, ai_memory_1.searchMemory)(String(req.query.q || ''), Number(req.query.limit) || 5) }); });
|
|
1039
1002
|
app.post('/memory/context/add', (req, res) => {
|
|
@@ -1053,11 +1016,11 @@ catch (e) {
|
|
|
1053
1016
|
res.status(500).json({ error: String(e) });
|
|
1054
1017
|
} });
|
|
1055
1018
|
app.post('/memory/ai/cost-estimate', (req, res) => { res.json({ estimatedCost: (0, ai_memory_1.estimateQueryCost)(String(req.body.prompt), req.body.model) }); });
|
|
1056
|
-
//
|
|
1019
|
+
// ─── KNOWLEDGE GRAPH UPGRADE ─────────────────────────
|
|
1057
1020
|
app.post('/graph/extract-entities', (req, res) => { res.json({ entities: (0, knowledge_graph_1.extractEntities)(req.body.patterns || []) }); });
|
|
1058
1021
|
app.post('/graph/infer-relationships', (req, res) => { res.json({ relationships: (0, knowledge_graph_1.inferRelationships)(req.body.patterns || []) }); });
|
|
1059
1022
|
app.get('/graph/paths', (req, res) => { const { from, to, maxDepth } = req.query; res.json({ paths: (0, knowledge_graph_1.findPaths)(String(from), String(to), Number(maxDepth) || 4) }); });
|
|
1060
|
-
//
|
|
1023
|
+
// ─── COST OPTIMIZER UPGRADE ──────────────────────────
|
|
1061
1024
|
app.post('/cost/benchmark', (req, res) => { (0, cost_optimizer_1.recordBenchmark)(req.body); res.json({ success: true }); });
|
|
1062
1025
|
app.get('/cost/benchmark/best', (req, res) => { const { taskType, prioritize } = req.query; const b = (0, cost_optimizer_1.getBestModelForTask)(String(taskType), prioritize); if (!b) {
|
|
1063
1026
|
res.json({ message: 'insufficient data' });
|
|
@@ -1065,11 +1028,11 @@ app.get('/cost/benchmark/best', (req, res) => { const { taskType, prioritize } =
|
|
|
1065
1028
|
} res.json(b); });
|
|
1066
1029
|
app.get('/cost/benchmark/stats', (_req, res) => { res.json((0, cost_optimizer_1.getBenchmarkStats)()); });
|
|
1067
1030
|
app.post('/cost/route/smart', (req, res) => { res.json((0, cost_optimizer_1.smartRouteTask)(req.body)); });
|
|
1068
|
-
//
|
|
1031
|
+
// ─── PROJECT DNA UPGRADE ─────────────────────────────
|
|
1069
1032
|
app.post('/project/architecture', (req, res) => { res.json((0, project_dna_1.inferArchitecture)(req.body.patterns || [])); });
|
|
1070
1033
|
app.post('/project/testing-style', (req, res) => { res.json((0, project_dna_1.detectTestingStyle)(req.body.patterns || [])); });
|
|
1071
1034
|
app.post('/project/conventions', (req, res) => { res.json({ suggestions: (0, project_dna_1.generateConventions)(req.body.profile) }); });
|
|
1072
|
-
//
|
|
1035
|
+
// ─── PRIVACY ENDPOINTS ────────────────────────────────
|
|
1073
1036
|
app.get('/privacy/mode', (_req, res) => { res.json({ mode: privacyManager.getMode() }); });
|
|
1074
1037
|
app.post('/privacy/mode', (req, res) => { const { mode } = req.body; if (!mode || !['private', 'community', 'organization'].includes(mode)) {
|
|
1075
1038
|
res.status(400).json({ error: 'invalid mode' });
|
|
@@ -1078,7 +1041,7 @@ app.post('/privacy/mode', (req, res) => { const { mode } = req.body; if (!mode |
|
|
|
1078
1041
|
app.get('/privacy/preview', (_req, res) => { res.json({ preview: privacyManager.getSharingPreview() }); });
|
|
1079
1042
|
app.post('/privacy/validate', (req, res) => { res.json(privacyManager.validatePayload(req.body || {})); });
|
|
1080
1043
|
app.get('/privacy/forbidden-fields', (_req, res) => { res.json({ fields: privacyManager.getForbiddenFields() }); });
|
|
1081
|
-
//
|
|
1044
|
+
// ─── OUTCOME ENGINE (Ch3) ──────────────────────────────
|
|
1082
1045
|
const outcomeStore = new outcome_store_1.OutcomeStore(CELL_DIR);
|
|
1083
1046
|
const outcomeEngine = new outcome_engine_1.OutcomeEngine(outcomeStore);
|
|
1084
1047
|
app.post('/outcomes/record', (req, res) => {
|
|
@@ -1113,7 +1076,7 @@ app.get('/outcomes/trends', (req, res) => {
|
|
|
1113
1076
|
});
|
|
1114
1077
|
res.json({ trends });
|
|
1115
1078
|
});
|
|
1116
|
-
//
|
|
1079
|
+
// ─── DEVELOPER PROFILE (Ch2) ──────────────────────────
|
|
1117
1080
|
app.post('/developer/profile', (req, res) => {
|
|
1118
1081
|
const { developerId, patterns, outcomesMap } = req.body;
|
|
1119
1082
|
if (!developerId || !patterns) {
|
|
@@ -1124,7 +1087,7 @@ app.post('/developer/profile', (req, res) => {
|
|
|
1124
1087
|
const profile = (0, developer_profile_1.buildProfile)(developerId, patterns, oMap);
|
|
1125
1088
|
res.json(profile);
|
|
1126
1089
|
});
|
|
1127
|
-
//
|
|
1090
|
+
// ─── RECOMMENDATION ENGINE (Ch4) ──────────────────────
|
|
1128
1091
|
app.post('/recommendations', (req, res) => {
|
|
1129
1092
|
const { developerId, patterns, outcomesMap, allProfiles } = req.body;
|
|
1130
1093
|
if (!developerId || !patterns) {
|
|
@@ -1154,7 +1117,7 @@ app.post('/recommendations/feedback', (req, res) => {
|
|
|
1154
1117
|
(0, recommendation_engine_1.recordFeedback)(store, developerId, patternId, action);
|
|
1155
1118
|
res.json({ recorded: true });
|
|
1156
1119
|
});
|
|
1157
|
-
//
|
|
1120
|
+
// ─── COMMUNITY INTELLIGENCE V2 (Ch7) ──────────────────
|
|
1158
1121
|
app.get('/community/v2/stats', (_req, res) => {
|
|
1159
1122
|
res.json((0, community_intelligence_1.getCommunityStats)());
|
|
1160
1123
|
});
|
|
@@ -1216,7 +1179,7 @@ app.post('/community/v2/reset', (_req, res) => {
|
|
|
1216
1179
|
(0, community_intelligence_1.resetCommunity)();
|
|
1217
1180
|
res.json({ reset: true });
|
|
1218
1181
|
});
|
|
1219
|
-
//
|
|
1182
|
+
// ─── ORGANIZATION INTELLIGENCE V2 (Ch8) ───────────────
|
|
1220
1183
|
app.post('/org/v2/ensure', (req, res) => {
|
|
1221
1184
|
const { orgId } = req.body;
|
|
1222
1185
|
if (!orgId) {
|
|
@@ -1298,7 +1261,7 @@ app.post('/org/v2/:orgId/reset', (req, res) => {
|
|
|
1298
1261
|
(0, org_intelligence_1.resetOrg)(req.params.orgId);
|
|
1299
1262
|
res.json({ reset: true });
|
|
1300
1263
|
});
|
|
1301
|
-
//
|
|
1264
|
+
// ─── CROSS-LAYER INTELLIGENCE (Ch9) ───────────────────
|
|
1302
1265
|
app.post('/intelligence/context', (req, res) => {
|
|
1303
1266
|
if (!req.body) {
|
|
1304
1267
|
res.status(400).json({ error: 'body required' });
|
|
@@ -1394,7 +1357,7 @@ app.post('/intelligence/reset', (_req, res) => {
|
|
|
1394
1357
|
(0, cross_layer_intelligence_1.resetCrossLayer)();
|
|
1395
1358
|
res.json({ reset: true });
|
|
1396
1359
|
});
|
|
1397
|
-
//
|
|
1360
|
+
// ─── CONTEXT INJECTION ───────────────────────────────
|
|
1398
1361
|
const prompt_builder_1 = require("../../01-context/context/prompt-builder");
|
|
1399
1362
|
const session_memory_1 = require("../../01-context/sessions/session-memory");
|
|
1400
1363
|
const sessionMemory = new session_memory_1.SessionMemory();
|
|
@@ -1599,7 +1562,7 @@ app.get('/ide/insights', (_req, res) => {
|
|
|
1599
1562
|
res.json(getIDEInsights());
|
|
1600
1563
|
}).catch(e => res.status(500).json({ error: String(e) }));
|
|
1601
1564
|
});
|
|
1602
|
-
//
|
|
1565
|
+
// ─── CODE SCANNER (Deep Learning) ──────────────────────
|
|
1603
1566
|
app.post('/scan/codebase', (req, res) => {
|
|
1604
1567
|
const { dir, project } = req.body;
|
|
1605
1568
|
if (!dir) {
|
|
@@ -1615,7 +1578,7 @@ app.get('/scan/profile/:project', (req, res) => {
|
|
|
1615
1578
|
Promise.resolve().then(() => __importStar(require('../../02-scanner/blindspots/code-scanner'))).then(({ getDeveloperProfile }) => {
|
|
1616
1579
|
const profile = getDeveloperProfile(req.params.project);
|
|
1617
1580
|
if (!profile) {
|
|
1618
|
-
res.status(404).json({ error: 'no profile
|
|
1581
|
+
res.status(404).json({ error: 'no profile — run scan first' });
|
|
1619
1582
|
return;
|
|
1620
1583
|
}
|
|
1621
1584
|
res.json(profile);
|
|
@@ -1634,7 +1597,7 @@ app.get('/scan/report/:project', (req, res) => {
|
|
|
1634
1597
|
res.json({ project: req.params.project, profile, patterns, patternCount: patterns.length });
|
|
1635
1598
|
}).catch(e => res.status(500).json({ error: String(e) }));
|
|
1636
1599
|
});
|
|
1637
|
-
//
|
|
1600
|
+
// ─── BEHAVIORAL TRACKING ──────────────────────────────────────
|
|
1638
1601
|
app.get('/behavior/summary', (req, res) => {
|
|
1639
1602
|
const { getBehaviorSummary } = require('../../03-knowledge/decisions/');
|
|
1640
1603
|
res.json(getBehaviorSummary(String(req.query.project || undefined)));
|
|
@@ -1655,11 +1618,11 @@ app.get('/behavior/stuck', (req, res) => {
|
|
|
1655
1618
|
const { getStuckPatterns } = require('../../03-knowledge/decisions/');
|
|
1656
1619
|
res.json({ stuck: getStuckPatterns(String(req.query.project || undefined)) });
|
|
1657
1620
|
});
|
|
1658
|
-
//
|
|
1621
|
+
// ─── Session Bridge Helper ────────────────────────────────────────────────
|
|
1659
1622
|
function formatSessionBridge(fromTool, toTool, context, decisions, options) {
|
|
1660
1623
|
const lines = [];
|
|
1661
|
-
lines.push(
|
|
1662
|
-
lines.push(`From: ${fromTool}
|
|
1624
|
+
lines.push(`â•â•â• CROSS-SESSION BRIDGE â•â•â•`);
|
|
1625
|
+
lines.push(`From: ${fromTool} → To: ${toTool}`);
|
|
1663
1626
|
if (context)
|
|
1664
1627
|
lines.push(`Last context: ${context}`);
|
|
1665
1628
|
if (decisions && decisions !== 'none' && decisions !== '[]' && decisions !== 'undefined') {
|
|
@@ -1667,33 +1630,33 @@ function formatSessionBridge(fromTool, toTool, context, decisions, options) {
|
|
|
1667
1630
|
}
|
|
1668
1631
|
if (options?.triedApproaches && options.triedApproaches.length > 0) {
|
|
1669
1632
|
lines.push('');
|
|
1670
|
-
lines.push('
|
|
1633
|
+
lines.push('🔄 TRIED ALREADY (don\'t suggest these):');
|
|
1671
1634
|
for (const a of options.triedApproaches.slice(0, 5)) {
|
|
1672
1635
|
const countSuffix = a.count > 1 ? ` (${a.count}x)` : '';
|
|
1673
|
-
lines.push(`
|
|
1636
|
+
lines.push(` → ${a.approach} — ${a.status}${countSuffix}`);
|
|
1674
1637
|
}
|
|
1675
1638
|
}
|
|
1676
1639
|
if (options?.openQuestions && options.openQuestions.length > 0) {
|
|
1677
1640
|
lines.push('');
|
|
1678
|
-
lines.push('
|
|
1641
|
+
lines.push('💠OPEN QUESTIONS (unresolved):');
|
|
1679
1642
|
for (const q of options.openQuestions.slice(0, 5)) {
|
|
1680
|
-
lines.push(`
|
|
1643
|
+
lines.push(` → [${q.priority}] ${q.question}`);
|
|
1681
1644
|
}
|
|
1682
1645
|
}
|
|
1683
1646
|
if (options?.hotFiles && options.hotFiles.length > 0) {
|
|
1684
1647
|
lines.push('');
|
|
1685
|
-
lines.push('
|
|
1648
|
+
lines.push('🔥 HOT FILES (recently active):');
|
|
1686
1649
|
for (const f of options.hotFiles.slice(0, 5)) {
|
|
1687
|
-
lines.push(`
|
|
1650
|
+
lines.push(` → ${f.filePath} (${f.touchCount} touches)`);
|
|
1688
1651
|
}
|
|
1689
1652
|
}
|
|
1690
1653
|
lines.push('');
|
|
1691
1654
|
lines.push(`Cell remembers. No need to re-explain.`);
|
|
1692
1655
|
return lines.join('\n');
|
|
1693
1656
|
}
|
|
1694
|
-
//
|
|
1657
|
+
// ─── MCP ENDPOINTS (merged from mcp-server.ts) ─────────────────────────────
|
|
1695
1658
|
const MCP_TOOLS = [
|
|
1696
|
-
{ name: 'cell_get_dev_profile', description: 'Developer profile
|
|
1659
|
+
{ name: 'cell_get_dev_profile', description: 'Developer profile — naming, style, errors, architecture', inputSchema: { type: 'object', properties: { project: { type: 'string' } }, required: ['project'] } },
|
|
1697
1660
|
{ name: 'cell_get_code_patterns', description: 'Code patterns by category', inputSchema: { type: 'object', properties: { project: { type: 'string' }, category: { type: 'string' } }, required: ['project'] } },
|
|
1698
1661
|
{ name: 'cell_deep_scan', description: 'Deep scan codebase', inputSchema: { type: 'object', properties: { dir: { type: 'string' }, project: { type: 'string' } }, required: ['dir'] } },
|
|
1699
1662
|
{ name: 'cell_scan_report', description: 'Full scan report', inputSchema: { type: 'object', properties: { project: { type: 'string' } }, required: ['project'] } },
|
|
@@ -1706,48 +1669,48 @@ const MCP_TOOLS = [
|
|
|
1706
1669
|
{ name: 'cell_log_decision', description: 'Log a coding decision', inputSchema: { type: 'object', properties: { project: { type: 'string' }, file: { type: 'string' }, decision: { type: 'string' }, approach: { type: 'string' }, worked: { type: 'boolean' } }, required: ['decision'] } },
|
|
1707
1670
|
{ name: 'cell_log_context', description: 'Log current context', inputSchema: { type: 'object', properties: { project: { type: 'string' }, task: { type: 'string' }, files: { type: 'array', items: { type: 'string' } } }, required: ['task'] } },
|
|
1708
1671
|
{ name: 'cell_log_stuck', description: 'Log when stuck', inputSchema: { type: 'object', properties: { project: { type: 'string' }, file: { type: 'string' }, description: { type: 'string' } }, required: ['description'] } },
|
|
1709
|
-
{ name: 'cell_session_bridge', description: 'Cross-session memory bridge
|
|
1710
|
-
{ name: 'cell_session_end', description: 'End a session
|
|
1711
|
-
{ name: 'cell_session_log', description: 'Log session activity
|
|
1712
|
-
{ name: 'cell_session_start', description: 'Start a new session explicitly
|
|
1713
|
-
{ name: 'cell_session_status', description: 'Get current status of a session
|
|
1672
|
+
{ name: 'cell_session_bridge', description: 'Cross-session memory bridge — get last session context when switching tools', inputSchema: { type: 'object', properties: { project: { type: 'string' }, tool: { type: 'string' } }, required: ['project'] } },
|
|
1673
|
+
{ name: 'cell_session_end', description: 'End a session — save final files, decisions, context snapshot', inputSchema: { type: 'object', properties: { sessionId: { type: 'number' }, filesTouched: { type: 'array', items: { type: 'string' } }, keyDecisions: { type: 'array', items: { type: 'string' } }, contextSnapshot: { type: 'string' } }, required: ['sessionId'] } },
|
|
1674
|
+
{ name: 'cell_session_log', description: 'Log session activity — approach (tried/failed), file (touched), question (open), resolve (answered)', inputSchema: { type: 'object', properties: { type: { type: 'string' }, sessionId: { type: 'number' }, project: { type: 'string' }, approach: { type: 'string' }, status: { type: 'string' }, reason: { type: 'string' }, filePath: { type: 'string' }, question: { type: 'string' }, priority: { type: 'string' }, questionId: { type: 'number' }, answer: { type: 'string' } }, required: ['type'] } },
|
|
1675
|
+
{ name: 'cell_session_start', description: 'Start a new session explicitly — returns session ID for tracking', inputSchema: { type: 'object', properties: { project: { type: 'string' }, tool: { type: 'string' } }, required: ['project', 'tool'] } },
|
|
1676
|
+
{ name: 'cell_session_status', description: 'Get current status of a session — files, approaches, active state', inputSchema: { type: 'object', properties: { sessionId: { type: 'number' } }, required: ['sessionId'] } },
|
|
1714
1677
|
{ name: 'cell_session_recent', description: 'Get recent sessions for a project (or all projects)', inputSchema: { type: 'object', properties: { project: { type: 'string' }, limit: { type: 'number' } }, required: [] } },
|
|
1715
|
-
{ name: 'cell_session_recommendations', description: 'Get AI guidance
|
|
1678
|
+
{ name: 'cell_session_recommendations', description: 'Get AI guidance — what to avoid, open questions, hot files for context', inputSchema: { type: 'object', properties: { project: { type: 'string' } }, required: ['project'] } },
|
|
1716
1679
|
{ name: 'cell_list_projects', description: 'List all registered projects in the workspace', inputSchema: { type: 'object', properties: {} } },
|
|
1717
|
-
{ name: 'cell_get_project', description: 'Get full metadata for a project
|
|
1680
|
+
{ name: 'cell_get_project', description: 'Get full metadata for a project — stack, file count, last scan', inputSchema: { type: 'object', properties: { name: { type: 'string' } }, required: ['name'] } },
|
|
1718
1681
|
{ name: 'cell_detect_project', description: 'Auto-detect project from current working directory path', inputSchema: { type: 'object', properties: { cwd: { type: 'string' } }, required: ['cwd'] } },
|
|
1719
1682
|
{ name: 'cell_register_project', description: 'Register a new project explicitly (auto-detected on scan too)', inputSchema: { type: 'object', properties: { name: { type: 'string' }, path: { type: 'string' }, stack: { type: 'string' }, fileCount: { type: 'number' } }, required: ['name', 'path'] } },
|
|
1720
1683
|
{ name: 'cell_graph_files', description: 'Get file dependency graph (complexity, coupling, risk) for project', inputSchema: { type: 'object', properties: { project: { type: 'string' }, limit: { type: 'number', description: 'Max files to return (default 20)' } }, required: ['project'] } },
|
|
1721
|
-
{ name: 'cell_graph_blast_radius', description: 'Compute blast radius
|
|
1684
|
+
{ name: 'cell_graph_blast_radius', description: 'Compute blast radius — which files break if I change this one?', inputSchema: { type: 'object', properties: { project: { type: 'string' }, file: { type: 'string' } }, required: ['project', 'file'] } },
|
|
1722
1685
|
{ name: 'cell_graph_tech', description: 'Show technology proficiency (languages, frameworks, architecture)', inputSchema: { type: 'object', properties: { project: { type: 'string' } }, required: ['project'] } },
|
|
1723
1686
|
{ name: 'cell_graph_stats', description: 'Get knowledge graph statistics (file + pattern + tech nodes/edges)', inputSchema: { type: 'object', properties: { project: { type: 'string' } }, required: ['project'] } },
|
|
1724
1687
|
{ name: 'cell_team_silos', description: 'Detect knowledge silos (bus factor risks) in the team', inputSchema: { type: 'object', properties: {} } },
|
|
1725
|
-
{ name: 'cell_team_bus_factor', description: 'Calculate bus factor report
|
|
1688
|
+
{ name: 'cell_team_bus_factor', description: 'Calculate bus factor report — who knows what, single points of failure', inputSchema: { type: 'object', properties: {} } },
|
|
1726
1689
|
{ name: 'cell_team_health', description: 'Team health score (bus factor, silos, skill gaps, strengths)', inputSchema: { type: 'object', properties: { project: { type: 'string' } } } },
|
|
1727
1690
|
{ name: 'cell_team_onboard', description: 'Generate onboarding doc for new team member', inputSchema: { type: 'object', properties: { teamName: { type: 'string' }, project: { type: 'string' } }, required: ['teamName'] } },
|
|
1728
1691
|
{ name: 'cell_team_retro', description: 'Sprint retrospective (commits, files, contributors, key decisions)', inputSchema: { type: 'object', properties: { days: { type: 'number', description: 'Days to look back (default 14)' }, project: { type: 'string' } } } },
|
|
1729
1692
|
{ name: 'cell_team_handoff', description: 'Generate handoff context when transferring work between team members', inputSchema: { type: 'object', properties: { from: { type: 'string' }, to: { type: 'string' }, project: { type: 'string' } }, required: ['from', 'to', 'project'] } },
|
|
1730
1693
|
{ name: 'cell_team_knowledge_transfer', description: 'Suggest knowledge transfer pairs to reduce bus factor risk', inputSchema: { type: 'object', properties: {} } },
|
|
1731
1694
|
{ name: 'cell_team_style', description: 'Compose team coding style (languages, patterns, conventions)', inputSchema: { type: 'object', properties: { project: { type: 'string' } } } },
|
|
1732
|
-
{ name: 'cell_team_dashboard', description: 'Combined team intelligence
|
|
1695
|
+
{ name: 'cell_team_dashboard', description: 'Combined team intelligence — silos, bus factor, health, style, all in one call', inputSchema: { type: 'object', properties: { project: { type: 'string' } } } },
|
|
1733
1696
|
{ name: 'cell_community_stats', description: 'Community-wide stats: total patterns, insights, benchmarks, top contributors', inputSchema: { type: 'object', properties: {} } },
|
|
1734
1697
|
{ name: 'cell_community_share', description: 'Share an anonymized pattern with the community (privacy-validated)', inputSchema: { type: 'object', properties: { category: { type: 'string' }, rule: { type: 'string' }, language: { type: 'string' }, framework: { type: 'string' }, successRate: { type: 'number' } }, required: ['category', 'rule'] } },
|
|
1735
1698
|
{ name: 'cell_community_patterns', description: 'Browse community patterns (top voted, by category, by language)', inputSchema: { type: 'object', properties: { category: { type: 'string' }, language: { type: 'string' }, minVotes: { type: 'number' }, limit: { type: 'number' } } } },
|
|
1736
1699
|
{ name: 'cell_community_vote', description: 'Upvote or downvote a community pattern', inputSchema: { type: 'object', properties: { patternId: { type: 'string' }, upvote: { type: 'boolean' } }, required: ['patternId', 'upvote'] } },
|
|
1737
1700
|
{ name: 'cell_community_insights', description: 'Get community insights (failure patterns, security warnings, best practices)', inputSchema: { type: 'object', properties: { severity: { type: 'string', enum: ['critical', 'warning', 'info'] }, category: { type: 'string' }, limit: { type: 'number' } } } },
|
|
1738
|
-
{ name: 'cell_community_benchmarks', description: 'Get benchmarks
|
|
1739
|
-
{ name: 'cell_community_trends', description: 'Technology evolution signals
|
|
1740
|
-
{ name: 'cell_community_failures', description: 'Failure pattern library
|
|
1701
|
+
{ name: 'cell_community_benchmarks', description: 'Get benchmarks — your code vs community averages', inputSchema: { type: 'object', properties: { category: { type: 'string' }, limit: { type: 'number' } } } },
|
|
1702
|
+
{ name: 'cell_community_trends', description: 'Technology evolution signals — adoption phase, 30d/90d trends, migrations', inputSchema: { type: 'object', properties: {} } },
|
|
1703
|
+
{ name: 'cell_community_failures', description: 'Failure pattern library — most common errors by language with mitigations', inputSchema: { type: 'object', properties: { language: { type: 'string' }, limit: { type: 'number' } } } },
|
|
1741
1704
|
{ name: 'cell_community_validate', description: 'Validate a rule string for privacy safety before sharing', inputSchema: { type: 'object', properties: { rule: { type: 'string' } }, required: ['rule'] } },
|
|
1742
|
-
{ name: 'cell_community_dashboard', description: 'Combined community dashboard
|
|
1705
|
+
{ name: 'cell_community_dashboard', description: 'Combined community dashboard — stats + trends + insights + benchmarks', inputSchema: { type: 'object', properties: {} } },
|
|
1743
1706
|
{ name: 'cell_usage_decision_log', description: 'Log a decision with outcome (was it the right call?)', inputSchema: { type: 'object', properties: { project: { type: 'string' }, technology: { type: 'string' }, reason: { type: 'string' }, outcome: { type: 'string' }, wasRight: { type: 'boolean' }, confidence: { type: 'number' } }, required: ['project', 'technology', 'wasRight'] } },
|
|
1744
|
-
{ name: 'cell_usage_decision_patterns', description: 'Detect decision patterns
|
|
1745
|
-
{ name: 'cell_usage_repeat_mistakes', description: 'Find repeated error patterns
|
|
1746
|
-
{ name: 'cell_usage_ai_stats', description: 'AI interaction stats
|
|
1747
|
-
{ name: 'cell_usage_productivity', description: 'Productivity signals
|
|
1748
|
-
{ name: 'cell_usage_skills', description: 'Skill progression map
|
|
1707
|
+
{ name: 'cell_usage_decision_patterns', description: 'Detect decision patterns — e.g. always picks MongoDB, always regrets it', inputSchema: { type: 'object', properties: { project: { type: 'string' } }, required: ['project'] } },
|
|
1708
|
+
{ name: 'cell_usage_repeat_mistakes', description: 'Find repeated error patterns — "you keep making this mistake" alerts', inputSchema: { type: 'object', properties: { project: { type: 'string' } }, required: ['project'] } },
|
|
1709
|
+
{ name: 'cell_usage_ai_stats', description: 'AI interaction stats — acceptance rate, iterations, recommendations per model', inputSchema: { type: 'object', properties: { project: { type: 'string' } }, required: ['project'] } },
|
|
1710
|
+
{ name: 'cell_usage_productivity', description: 'Productivity signals — flow state, friction, context switches', inputSchema: { type: 'object', properties: { project: { type: 'string' }, signalType: { type: 'string', enum: ['flow', 'friction', 'context_switch', 'long_session'] }, durationMinutes: { type: 'number' }, filesTouched: { type: 'number' }, contextSwitches: { type: 'number' } }, required: ['project'] } },
|
|
1711
|
+
{ name: 'cell_usage_skills', description: 'Skill progression map — improving/regressing/plateau per technology', inputSchema: { type: 'object', properties: { project: { type: 'string' } }, required: ['project'] } },
|
|
1749
1712
|
{ name: 'cell_usage_burnout', description: 'Burnout risk detection from session patterns and friction signals', inputSchema: { type: 'object', properties: { project: { type: 'string' } }, required: ['project'] } },
|
|
1750
|
-
{ name: 'cell_usage_dashboard', description: 'Combined usage intelligence dashboard
|
|
1713
|
+
{ name: 'cell_usage_dashboard', description: 'Combined usage intelligence dashboard — decisions + mistakes + AI + productivity + skills + burnout', inputSchema: { type: 'object', properties: { project: { type: 'string' } }, required: ['project'] } },
|
|
1751
1714
|
{ name: 'cell_watch_start', description: 'Start live file watcher for a project directory', inputSchema: { type: 'object', properties: { project: { type: 'string' }, dir: { type: 'string' } }, required: ['project', 'dir'] } },
|
|
1752
1715
|
{ name: 'cell_watch_stop', description: 'Stop the live file watcher for a project', inputSchema: { type: 'object', properties: { project: { type: 'string' } }, required: ['project'] } },
|
|
1753
1716
|
{ name: 'cell_watch_status', description: 'Get watcher status (active, event count, last event)', inputSchema: { type: 'object', properties: { project: { type: 'string' } } } },
|
|
@@ -1757,9 +1720,9 @@ const MCP_TOOLS = [
|
|
|
1757
1720
|
{ name: 'cell_blindspots_scan', description: 'Scan a directory for 15+ types of blind spots (error handling, null safety, perf, quality, etc.)', inputSchema: { type: 'object', properties: { dir: { type: 'string' }, maxFiles: { type: 'number' } } } },
|
|
1758
1721
|
{ name: 'cell_blindspots_report', description: 'Get a formatted blind spot report with severity groupings and recommendations', inputSchema: { type: 'object', properties: { dir: { type: 'string' }, maxFiles: { type: 'number' } } } },
|
|
1759
1722
|
{ name: 'cell_blindspots_summary', description: 'Get blind spot counts by category only (quick check)', inputSchema: { type: 'object', properties: { dir: { type: 'string' } } } },
|
|
1760
|
-
{ name: 'cell_predict', description: 'Predictive intelligence
|
|
1761
|
-
{ name: 'cell_model_track', description: 'Track AI model interaction
|
|
1762
|
-
{ name: 'cell_model_recommend', description: 'Get AI model recommendations
|
|
1723
|
+
{ name: 'cell_predict', description: 'Predictive intelligence — repeat mistakes, decision regret, energy warnings, complexity traps', inputSchema: { type: 'object', properties: { project: { type: 'string' } }, required: [] } },
|
|
1724
|
+
{ name: 'cell_model_track', description: 'Track AI model interaction — which tool was used, what task, accepted/rejected', inputSchema: { type: 'object', properties: { modelName: { type: 'string' }, taskType: { type: 'string' }, accepted: { type: 'boolean' }, responseTimeMs: { type: 'number' }, project: { type: 'string' }, suggestion: { type: 'string' } }, required: ['modelName', 'taskType', 'accepted'] } },
|
|
1725
|
+
{ name: 'cell_model_recommend', description: 'Get AI model recommendations — which tool works best for which task', inputSchema: { type: 'object', properties: {} } },
|
|
1763
1726
|
{ name: 'cell_handoff_current', description: 'Get current handoff context (max 200 lines, auto-rotation)', inputSchema: { type: 'object', properties: { project: { type: 'string' } } } },
|
|
1764
1727
|
{ name: 'cell_handoff_log', description: 'Log a handoff entry with title, summary, status', inputSchema: { type: 'object', properties: { project: { type: 'string' }, title: { type: 'string' }, summary: { type: 'string' }, status: { type: 'string', enum: ['done', 'in-progress', 'blocked', 'pending'] }, filesChanged: { type: 'array', items: { type: 'string' } }, why: { type: 'string' }, nextSteps: { type: 'string' } }, required: ['title', 'summary', 'status'] } },
|
|
1765
1728
|
{ name: 'cell_handoff_history', description: 'Get handoff history for a month (YYYY-MM)', inputSchema: { type: 'object', properties: { project: { type: 'string' }, month: { type: 'string' } } } },
|
|
@@ -1769,7 +1732,7 @@ const MCP_TOOLS = [
|
|
|
1769
1732
|
{ name: 'cell_memory_record', description: 'Record a memory event (edit, decision, error, fix, etc.)', inputSchema: { type: 'object', properties: { project: { type: 'string' }, type: { type: 'string', enum: ['file_event', 'edit', 'decision', 'error', 'fix', 'verification', 'publish', 'handoff', 'pattern', 'style', 'session', 'branch', 'risk', 'question', 'ai_work'] }, topic: { type: 'string' }, summary: { type: 'string' }, files: { type: 'array', items: { type: 'string' } }, importance: { type: 'number' }, tool: { type: 'string' }, model: { type: 'string' } }, required: ['type', 'summary'] } },
|
|
1770
1733
|
{ name: 'cell_style_get', description: 'Get developer and project style profiles', inputSchema: { type: 'object', properties: { project: { type: 'string' } }, required: ['project'] } },
|
|
1771
1734
|
{ name: 'cell_style_update', description: 'Update developer style preference', inputSchema: { type: 'object', properties: { project: { type: 'string' }, key: { type: 'string' }, value: { type: 'string' } }, required: ['project', 'key', 'value'] } },
|
|
1772
|
-
{ name: 'cell_memory_compact', description: 'Compact memory
|
|
1735
|
+
{ name: 'cell_memory_compact', description: 'Compact memory — merge old events and archive chunks', inputSchema: { type: 'object', properties: { project: { type: 'string' }, olderThanDays: { type: 'number' } } } },
|
|
1773
1736
|
{ name: 'cell_memory_health', description: 'Get full memory health report (events, archive, handoff)', inputSchema: { type: 'object', properties: { project: { type: 'string' } }, required: ['project'] } },
|
|
1774
1737
|
{ name: 'cell_memory_summary', description: 'Generate daily or weekly memory summary', inputSchema: { type: 'object', properties: { project: { type: 'string' }, period: { type: 'string', enum: ['daily', 'weekly'] } }, required: ['project'] } },
|
|
1775
1738
|
{ name: 'cell_memory_insights', description: 'Get proactive memory insights (trends, risks, recommendations)', inputSchema: { type: 'object', properties: { project: { type: 'string' }, days: { type: 'number' } }, required: ['project'] } },
|
|
@@ -1811,7 +1774,7 @@ async function handleMCPToolCall(name, args) {
|
|
|
1811
1774
|
const { getDeveloperProfile } = require('../code-scanner');
|
|
1812
1775
|
const profile = getDeveloperProfile(args.project);
|
|
1813
1776
|
if (!profile)
|
|
1814
|
-
return { error: 'no profile
|
|
1777
|
+
return { error: 'no profile — run cell scan first' };
|
|
1815
1778
|
return { project: args.project, profile };
|
|
1816
1779
|
}
|
|
1817
1780
|
case 'cell_get_code_patterns': {
|
|
@@ -1845,8 +1808,8 @@ async function handleMCPToolCall(name, args) {
|
|
|
1845
1808
|
case 'cell_get_context': {
|
|
1846
1809
|
const { buildContext, formatContextForTool } = require('../../01-context/context/prompt-builder');
|
|
1847
1810
|
// Auto-detect project name when AI doesn't know it. Order of resolution:
|
|
1848
|
-
// 1. args.project (explicit)
|
|
1849
|
-
// 2. args.cwd (IDE's current dir basename)
|
|
1811
|
+
// 1. args.project (explicit) — highest priority
|
|
1812
|
+
// 2. args.cwd (IDE's current dir basename) — Antigravity/Cursor pass this
|
|
1850
1813
|
// 3. process.cwd() of the daemon (last resort)
|
|
1851
1814
|
// If still nothing, return a helpful error listing registered projects.
|
|
1852
1815
|
const explicitProject = args.project;
|
|
@@ -1882,7 +1845,7 @@ async function handleMCPToolCall(name, args) {
|
|
|
1882
1845
|
const known = projects.find((p) => p.name === resolvedProject || p.path === path.resolve(resolvedProject || ''));
|
|
1883
1846
|
if (!known) {
|
|
1884
1847
|
// Project name might still work if it matches `cwd` of a previous scan
|
|
1885
|
-
// or if it's the same as a directory basename. Don't error out
|
|
1848
|
+
// or if it's the same as a directory basename. Don't error out — just
|
|
1886
1849
|
// let buildContext handle the empty-data case naturally.
|
|
1887
1850
|
}
|
|
1888
1851
|
}
|
|
@@ -2615,7 +2578,7 @@ async function handleMCPToolCall(name, args) {
|
|
|
2615
2578
|
mistakes: mistakes.slice(0, 20),
|
|
2616
2579
|
message: mistakes.length > 0
|
|
2617
2580
|
? `Found ${mistakes.length} repeated error patterns`
|
|
2618
|
-
: 'No repeated mistakes
|
|
2581
|
+
: 'No repeated mistakes — clean track record',
|
|
2619
2582
|
};
|
|
2620
2583
|
}
|
|
2621
2584
|
catch (err) {
|
|
@@ -3169,7 +3132,7 @@ async function handleMCPToolCall(name, args) {
|
|
|
3169
3132
|
app.post('/mcp', async (req, res) => {
|
|
3170
3133
|
// Wrap entire handler in try/catch so uncaught errors don't 500 silently
|
|
3171
3134
|
try {
|
|
3172
|
-
//
|
|
3135
|
+
// ─── Security: rate limit + input validation ─────────────────────────
|
|
3173
3136
|
const { checkRateLimit, getClientId, validateToolArgs, securityHeaders } = require('../../05-community/privacy/security');
|
|
3174
3137
|
for (const [k, v] of Object.entries(securityHeaders()))
|
|
3175
3138
|
res.setHeader(k, v);
|
|
@@ -3247,10 +3210,10 @@ app.use((err, _req, res, _next) => {
|
|
|
3247
3210
|
}
|
|
3248
3211
|
catch { /* noop */ }
|
|
3249
3212
|
});
|
|
3250
|
-
//
|
|
3213
|
+
// ─── Self-Healing ──────────────────────────────────────────────────────
|
|
3251
3214
|
process.on('uncaughtException', (err) => {
|
|
3252
3215
|
console.error('[cell] Uncaught:', err.message);
|
|
3253
|
-
// Don't exit
|
|
3216
|
+
// Don't exit — keep serving
|
|
3254
3217
|
});
|
|
3255
3218
|
process.on('unhandledRejection', (reason) => {
|
|
3256
3219
|
console.error('[cell] Unhandled rejection:', String(reason));
|
|
@@ -3261,7 +3224,7 @@ try {
|
|
|
3261
3224
|
catch (e) {
|
|
3262
3225
|
console.error('AI memory init failed:', e);
|
|
3263
3226
|
}
|
|
3264
|
-
//
|
|
3227
|
+
// ─── Phase 10: Web Dashboard ──────────────────────────────────────────────
|
|
3265
3228
|
app.get('/dashboard', (_req, res) => {
|
|
3266
3229
|
const htmlPath = require('path').join(__dirname, 'dashboard.html');
|
|
3267
3230
|
try {
|
|
@@ -3357,7 +3320,7 @@ app.get('/api/dashboard', async (_req, res) => {
|
|
|
3357
3320
|
res.status(500).json({ error: err.message });
|
|
3358
3321
|
}
|
|
3359
3322
|
});
|
|
3360
|
-
//
|
|
3323
|
+
// ─── Start with port conflict handling ─────────────────────────────────
|
|
3361
3324
|
const server = app.listen(PORT, () => {
|
|
3362
3325
|
console.log(`Cell Daemon running on http://localhost:${PORT}`);
|
|
3363
3326
|
console.log(`MCP endpoint: POST http://localhost:${PORT}/mcp`);
|