@timmeck/brain 1.8.1 → 1.8.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/BRAIN_PLAN.md +3324 -3324
- package/LICENSE +21 -21
- package/dist/cli/commands/dashboard.js +595 -595
- package/dist/dashboard/server.js +25 -25
- package/dist/db/migrations/001_core_schema.js +115 -115
- package/dist/db/migrations/002_learning_schema.js +33 -33
- package/dist/db/migrations/003_code_schema.js +48 -48
- package/dist/db/migrations/004_synapses_schema.js +52 -52
- package/dist/db/migrations/005_fts_indexes.js +73 -73
- package/dist/db/migrations/007_feedback.js +8 -8
- package/dist/db/migrations/008_git_integration.js +33 -33
- package/dist/db/migrations/009_embeddings.js +3 -3
- package/dist/db/repositories/antipattern.repository.js +3 -3
- package/dist/db/repositories/code-module.repository.js +32 -32
- package/dist/db/repositories/notification.repository.js +3 -3
- package/dist/db/repositories/project.repository.js +21 -21
- package/dist/db/repositories/rule.repository.js +24 -24
- package/dist/db/repositories/solution.repository.js +50 -50
- package/dist/db/repositories/synapse.repository.js +18 -18
- package/dist/db/repositories/terminal.repository.js +24 -24
- package/dist/ipc/server.d.ts +8 -0
- package/dist/ipc/server.js +67 -1
- package/dist/ipc/server.js.map +1 -1
- package/dist/matching/error-matcher.js +5 -5
- package/dist/matching/fingerprint.js +6 -1
- package/dist/matching/fingerprint.js.map +1 -1
- package/dist/services/error.service.js +4 -3
- package/dist/services/error.service.js.map +1 -1
- package/dist/services/git.service.js +14 -14
- package/package.json +49 -49
- package/src/api/server.ts +395 -395
- package/src/brain.ts +266 -266
- package/src/cli/colors.ts +116 -116
- package/src/cli/commands/config.ts +169 -169
- package/src/cli/commands/dashboard.ts +755 -755
- package/src/cli/commands/doctor.ts +118 -118
- package/src/cli/commands/explain.ts +83 -83
- package/src/cli/commands/export.ts +31 -31
- package/src/cli/commands/import.ts +199 -199
- package/src/cli/commands/insights.ts +65 -65
- package/src/cli/commands/learn.ts +24 -24
- package/src/cli/commands/modules.ts +53 -53
- package/src/cli/commands/network.ts +67 -67
- package/src/cli/commands/projects.ts +42 -42
- package/src/cli/commands/query.ts +120 -120
- package/src/cli/commands/start.ts +62 -62
- package/src/cli/commands/status.ts +75 -75
- package/src/cli/commands/stop.ts +34 -34
- package/src/cli/ipc-helper.ts +22 -22
- package/src/cli/update-check.ts +63 -63
- package/src/code/fingerprint.ts +87 -87
- package/src/code/parsers/generic.ts +29 -29
- package/src/code/parsers/python.ts +54 -54
- package/src/code/parsers/typescript.ts +65 -65
- package/src/code/registry.ts +60 -60
- package/src/dashboard/server.ts +142 -142
- package/src/db/connection.ts +22 -22
- package/src/db/migrations/001_core_schema.ts +120 -120
- package/src/db/migrations/002_learning_schema.ts +38 -38
- package/src/db/migrations/003_code_schema.ts +53 -53
- package/src/db/migrations/004_synapses_schema.ts +57 -57
- package/src/db/migrations/005_fts_indexes.ts +78 -78
- package/src/db/migrations/006_synapses_phase3.ts +17 -17
- package/src/db/migrations/007_feedback.ts +13 -13
- package/src/db/migrations/008_git_integration.ts +38 -38
- package/src/db/migrations/009_embeddings.ts +8 -8
- package/src/db/repositories/antipattern.repository.ts +66 -66
- package/src/db/repositories/code-module.repository.ts +142 -142
- package/src/db/repositories/notification.repository.ts +66 -66
- package/src/db/repositories/project.repository.ts +93 -93
- package/src/db/repositories/rule.repository.ts +108 -108
- package/src/db/repositories/solution.repository.ts +154 -154
- package/src/db/repositories/synapse.repository.ts +153 -153
- package/src/db/repositories/terminal.repository.ts +101 -101
- package/src/embeddings/engine.ts +238 -238
- package/src/index.ts +63 -63
- package/src/ipc/client.ts +118 -118
- package/src/ipc/protocol.ts +35 -35
- package/src/ipc/router.ts +133 -133
- package/src/ipc/server.ts +176 -110
- package/src/learning/decay.ts +46 -46
- package/src/learning/pattern-extractor.ts +90 -90
- package/src/learning/rule-generator.ts +74 -74
- package/src/matching/error-matcher.ts +5 -5
- package/src/matching/fingerprint.ts +34 -29
- package/src/matching/similarity.ts +61 -61
- package/src/matching/tfidf.ts +74 -74
- package/src/matching/tokenizer.ts +41 -41
- package/src/mcp/auto-detect.ts +93 -93
- package/src/mcp/http-server.ts +140 -140
- package/src/mcp/server.ts +73 -73
- package/src/parsing/error-parser.ts +28 -28
- package/src/parsing/parsers/compiler.ts +93 -93
- package/src/parsing/parsers/generic.ts +28 -28
- package/src/parsing/parsers/go.ts +97 -97
- package/src/parsing/parsers/node.ts +69 -69
- package/src/parsing/parsers/python.ts +62 -62
- package/src/parsing/parsers/rust.ts +50 -50
- package/src/parsing/parsers/shell.ts +42 -42
- package/src/parsing/types.ts +47 -47
- package/src/research/gap-analyzer.ts +135 -135
- package/src/research/insight-generator.ts +123 -123
- package/src/research/research-engine.ts +116 -116
- package/src/research/synergy-detector.ts +126 -126
- package/src/research/template-extractor.ts +130 -130
- package/src/research/trend-analyzer.ts +127 -127
- package/src/services/code.service.ts +271 -271
- package/src/services/error.service.ts +4 -3
- package/src/services/git.service.ts +132 -132
- package/src/services/notification.service.ts +41 -41
- package/src/services/synapse.service.ts +59 -59
- package/src/services/terminal.service.ts +81 -81
- package/src/synapses/activation.ts +80 -80
- package/src/synapses/decay.ts +38 -38
- package/src/synapses/hebbian.ts +69 -69
- package/src/synapses/pathfinder.ts +81 -81
- package/src/synapses/synapse-manager.ts +109 -109
- package/src/types/code.types.ts +52 -52
- package/src/types/error.types.ts +67 -67
- package/src/types/ipc.types.ts +8 -8
- package/src/types/mcp.types.ts +53 -53
- package/src/types/research.types.ts +28 -28
- package/src/types/solution.types.ts +30 -30
- package/src/utils/events.ts +45 -45
- package/src/utils/hash.ts +5 -5
- package/src/utils/logger.ts +48 -48
- package/src/utils/paths.ts +19 -19
- package/tests/e2e/test_code_intelligence.py +1015 -0
- package/tests/e2e/test_error_memory.py +451 -0
- package/tests/e2e/test_full_integration.py +534 -0
- package/tests/fixtures/code-modules/modules.ts +83 -83
- package/tests/fixtures/errors/go.ts +9 -9
- package/tests/fixtures/errors/node.ts +24 -24
- package/tests/fixtures/errors/python.ts +21 -21
- package/tests/fixtures/errors/rust.ts +25 -25
- package/tests/fixtures/errors/shell.ts +15 -15
- package/tests/fixtures/solutions/solutions.ts +27 -27
- package/tests/helpers/setup-db.ts +52 -52
- package/tests/integration/code-flow.test.ts +86 -86
- package/tests/integration/error-flow.test.ts +83 -83
- package/tests/integration/ipc-flow.test.ts +166 -166
- package/tests/integration/learning-cycle.test.ts +82 -82
- package/tests/integration/synapse-flow.test.ts +117 -117
- package/tests/unit/code/analyzer.test.ts +58 -58
- package/tests/unit/code/fingerprint.test.ts +51 -51
- package/tests/unit/code/scorer.test.ts +55 -55
- package/tests/unit/learning/confidence-scorer.test.ts +60 -60
- package/tests/unit/learning/decay.test.ts +45 -45
- package/tests/unit/learning/pattern-extractor.test.ts +50 -50
- package/tests/unit/matching/error-matcher.test.ts +69 -69
- package/tests/unit/matching/fingerprint.test.ts +47 -47
- package/tests/unit/matching/similarity.test.ts +65 -65
- package/tests/unit/matching/tfidf.test.ts +71 -71
- package/tests/unit/matching/tokenizer.test.ts +83 -83
- package/tests/unit/parsing/parsers.test.ts +113 -113
- package/tests/unit/research/gap-analyzer.test.ts +45 -45
- package/tests/unit/research/trend-analyzer.test.ts +45 -45
- package/tests/unit/synapses/activation.test.ts +80 -80
- package/tests/unit/synapses/decay.test.ts +27 -27
- package/tests/unit/synapses/hebbian.test.ts +96 -96
- package/tests/unit/synapses/pathfinder.test.ts +72 -72
- package/tsconfig.json +18 -18
package/src/brain.ts
CHANGED
|
@@ -1,266 +1,266 @@
|
|
|
1
|
-
import path from 'node:path';
|
|
2
|
-
import fs from 'node:fs';
|
|
3
|
-
import type Database from 'better-sqlite3';
|
|
4
|
-
import { loadConfig } from './config.js';
|
|
5
|
-
import type { BrainConfig } from './types/config.types.js';
|
|
6
|
-
import { createLogger, getLogger } from './utils/logger.js';
|
|
7
|
-
import { getEventBus } from './utils/events.js';
|
|
8
|
-
import { createConnection } from './db/connection.js';
|
|
9
|
-
import { runMigrations } from './db/migrations/index.js';
|
|
10
|
-
|
|
11
|
-
// Repositories
|
|
12
|
-
import { ProjectRepository } from './db/repositories/project.repository.js';
|
|
13
|
-
import { ErrorRepository } from './db/repositories/error.repository.js';
|
|
14
|
-
import { SolutionRepository } from './db/repositories/solution.repository.js';
|
|
15
|
-
import { RuleRepository } from './db/repositories/rule.repository.js';
|
|
16
|
-
import { AntipatternRepository } from './db/repositories/antipattern.repository.js';
|
|
17
|
-
import { TerminalRepository } from './db/repositories/terminal.repository.js';
|
|
18
|
-
import { CodeModuleRepository } from './db/repositories/code-module.repository.js';
|
|
19
|
-
import { SynapseRepository } from './db/repositories/synapse.repository.js';
|
|
20
|
-
import { NotificationRepository } from './db/repositories/notification.repository.js';
|
|
21
|
-
import { InsightRepository } from './db/repositories/insight.repository.js';
|
|
22
|
-
|
|
23
|
-
// Services
|
|
24
|
-
import { ErrorService } from './services/error.service.js';
|
|
25
|
-
import { SolutionService } from './services/solution.service.js';
|
|
26
|
-
import { TerminalService } from './services/terminal.service.js';
|
|
27
|
-
import { PreventionService } from './services/prevention.service.js';
|
|
28
|
-
import { CodeService } from './services/code.service.js';
|
|
29
|
-
import { SynapseService } from './services/synapse.service.js';
|
|
30
|
-
import { ResearchService } from './services/research.service.js';
|
|
31
|
-
import { NotificationService } from './services/notification.service.js';
|
|
32
|
-
import { AnalyticsService } from './services/analytics.service.js';
|
|
33
|
-
import { GitService } from './services/git.service.js';
|
|
34
|
-
|
|
35
|
-
// Synapses
|
|
36
|
-
import { SynapseManager } from './synapses/synapse-manager.js';
|
|
37
|
-
|
|
38
|
-
// Engines
|
|
39
|
-
import { LearningEngine } from './learning/learning-engine.js';
|
|
40
|
-
import { ResearchEngine } from './research/research-engine.js';
|
|
41
|
-
|
|
42
|
-
// IPC
|
|
43
|
-
import { IpcRouter, type Services } from './ipc/router.js';
|
|
44
|
-
import { IpcServer } from './ipc/server.js';
|
|
45
|
-
|
|
46
|
-
// API & MCP HTTP
|
|
47
|
-
import { ApiServer } from './api/server.js';
|
|
48
|
-
import { McpHttpServer } from './mcp/http-server.js';
|
|
49
|
-
|
|
50
|
-
// Embeddings
|
|
51
|
-
import { EmbeddingEngine } from './embeddings/engine.js';
|
|
52
|
-
|
|
53
|
-
export class BrainCore {
|
|
54
|
-
private db: Database.Database | null = null;
|
|
55
|
-
private ipcServer: IpcServer | null = null;
|
|
56
|
-
private apiServer: ApiServer | null = null;
|
|
57
|
-
private mcpHttpServer: McpHttpServer | null = null;
|
|
58
|
-
private embeddingEngine: EmbeddingEngine | null = null;
|
|
59
|
-
private learningEngine: LearningEngine | null = null;
|
|
60
|
-
private researchEngine: ResearchEngine | null = null;
|
|
61
|
-
private cleanupTimer: ReturnType<typeof setInterval> | null = null;
|
|
62
|
-
private config: BrainConfig | null = null;
|
|
63
|
-
|
|
64
|
-
start(configPath?: string): void {
|
|
65
|
-
// 1. Config
|
|
66
|
-
this.config = loadConfig(configPath);
|
|
67
|
-
const config = this.config;
|
|
68
|
-
|
|
69
|
-
// 2. Ensure data dir
|
|
70
|
-
fs.mkdirSync(path.dirname(config.dbPath), { recursive: true });
|
|
71
|
-
|
|
72
|
-
// 3. Logger
|
|
73
|
-
createLogger({
|
|
74
|
-
level: config.log.level,
|
|
75
|
-
file: config.log.file,
|
|
76
|
-
maxSize: config.log.maxSize,
|
|
77
|
-
maxFiles: config.log.maxFiles,
|
|
78
|
-
});
|
|
79
|
-
const logger = getLogger();
|
|
80
|
-
|
|
81
|
-
// 4. Database
|
|
82
|
-
this.db = createConnection(config.dbPath);
|
|
83
|
-
runMigrations(this.db);
|
|
84
|
-
logger.info(`Database initialized: ${config.dbPath}`);
|
|
85
|
-
|
|
86
|
-
// 5. Repositories
|
|
87
|
-
const projectRepo = new ProjectRepository(this.db);
|
|
88
|
-
const errorRepo = new ErrorRepository(this.db);
|
|
89
|
-
const solutionRepo = new SolutionRepository(this.db);
|
|
90
|
-
const ruleRepo = new RuleRepository(this.db);
|
|
91
|
-
const antipatternRepo = new AntipatternRepository(this.db);
|
|
92
|
-
const terminalRepo = new TerminalRepository(this.db);
|
|
93
|
-
const codeModuleRepo = new CodeModuleRepository(this.db);
|
|
94
|
-
const synapseRepo = new SynapseRepository(this.db);
|
|
95
|
-
const notificationRepo = new NotificationRepository(this.db);
|
|
96
|
-
const insightRepo = new InsightRepository(this.db);
|
|
97
|
-
|
|
98
|
-
// 6. Synapse Manager
|
|
99
|
-
const synapseManager = new SynapseManager(synapseRepo, config.synapses);
|
|
100
|
-
|
|
101
|
-
// 7. Services
|
|
102
|
-
const services: Services = {
|
|
103
|
-
error: new ErrorService(errorRepo, projectRepo, synapseManager, config.matching),
|
|
104
|
-
solution: new SolutionService(solutionRepo, synapseManager),
|
|
105
|
-
terminal: new TerminalService(terminalRepo, config.terminal.staleTimeout),
|
|
106
|
-
prevention: new PreventionService(ruleRepo, antipatternRepo, synapseManager),
|
|
107
|
-
code: new CodeService(codeModuleRepo, projectRepo, synapseManager),
|
|
108
|
-
synapse: new SynapseService(synapseManager),
|
|
109
|
-
research: new ResearchService(insightRepo, errorRepo, synapseManager),
|
|
110
|
-
notification: new NotificationService(notificationRepo),
|
|
111
|
-
analytics: new AnalyticsService(
|
|
112
|
-
errorRepo, solutionRepo, codeModuleRepo,
|
|
113
|
-
ruleRepo, antipatternRepo, insightRepo,
|
|
114
|
-
synapseManager,
|
|
115
|
-
),
|
|
116
|
-
git: new GitService(this.db!, synapseManager),
|
|
117
|
-
};
|
|
118
|
-
|
|
119
|
-
// 8. Embedding Engine (local vector search)
|
|
120
|
-
if (config.embeddings.enabled) {
|
|
121
|
-
this.embeddingEngine = new EmbeddingEngine(config.embeddings, this.db!);
|
|
122
|
-
this.embeddingEngine.start();
|
|
123
|
-
// Wire embedding engine into services for hybrid search
|
|
124
|
-
services.error.setEmbeddingEngine(this.embeddingEngine);
|
|
125
|
-
services.code.setEmbeddingEngine(this.embeddingEngine);
|
|
126
|
-
logger.info('Embedding engine started (model will load in background)');
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
// 9. Learning Engine
|
|
130
|
-
this.learningEngine = new LearningEngine(
|
|
131
|
-
config.learning, errorRepo, solutionRepo,
|
|
132
|
-
ruleRepo, antipatternRepo, synapseManager,
|
|
133
|
-
);
|
|
134
|
-
this.learningEngine.start();
|
|
135
|
-
logger.info(`Learning engine started (interval: ${config.learning.intervalMs}ms)`);
|
|
136
|
-
|
|
137
|
-
// 10. Research Engine
|
|
138
|
-
this.researchEngine = new ResearchEngine(
|
|
139
|
-
config.research, errorRepo, solutionRepo, projectRepo,
|
|
140
|
-
codeModuleRepo, synapseRepo, insightRepo, synapseManager,
|
|
141
|
-
);
|
|
142
|
-
this.researchEngine.start();
|
|
143
|
-
logger.info(`Research engine started (interval: ${config.research.intervalMs}ms)`);
|
|
144
|
-
|
|
145
|
-
// Expose learning engine to IPC
|
|
146
|
-
services.learning = this.learningEngine;
|
|
147
|
-
|
|
148
|
-
// 11. IPC Server
|
|
149
|
-
const router = new IpcRouter(services);
|
|
150
|
-
this.ipcServer = new IpcServer(router, config.ipc.pipeName);
|
|
151
|
-
this.ipcServer.start();
|
|
152
|
-
|
|
153
|
-
// 11a. REST API Server
|
|
154
|
-
if (config.api.enabled) {
|
|
155
|
-
this.apiServer = new ApiServer({
|
|
156
|
-
port: config.api.port,
|
|
157
|
-
router,
|
|
158
|
-
apiKey: config.api.apiKey,
|
|
159
|
-
});
|
|
160
|
-
this.apiServer.start();
|
|
161
|
-
logger.info(`REST API enabled on port ${config.api.port}`);
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
// 11b. MCP HTTP Server (SSE transport for Cursor, Windsurf, Cline, Continue)
|
|
165
|
-
if (config.mcpHttp.enabled) {
|
|
166
|
-
this.mcpHttpServer = new McpHttpServer(config.mcpHttp.port, router);
|
|
167
|
-
this.mcpHttpServer.start();
|
|
168
|
-
logger.info(`MCP HTTP (SSE) enabled on port ${config.mcpHttp.port}`);
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
// 12. Terminal cleanup timer
|
|
172
|
-
this.cleanupTimer = setInterval(() => {
|
|
173
|
-
services.terminal.cleanup();
|
|
174
|
-
}, 60_000);
|
|
175
|
-
|
|
176
|
-
// 13. Event listeners (synapse wiring)
|
|
177
|
-
this.setupEventListeners(services, synapseManager);
|
|
178
|
-
|
|
179
|
-
// 14. PID file
|
|
180
|
-
const pidPath = path.join(path.dirname(config.dbPath), 'brain.pid');
|
|
181
|
-
fs.writeFileSync(pidPath, String(process.pid));
|
|
182
|
-
|
|
183
|
-
// 15. Graceful shutdown
|
|
184
|
-
process.on('SIGINT', () => this.stop());
|
|
185
|
-
process.on('SIGTERM', () => this.stop());
|
|
186
|
-
|
|
187
|
-
logger.info(`Brain daemon started (PID: ${process.pid})`);
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
stop(): void {
|
|
191
|
-
const logger = getLogger();
|
|
192
|
-
logger.info('Shutting down...');
|
|
193
|
-
|
|
194
|
-
if (this.cleanupTimer) {
|
|
195
|
-
clearInterval(this.cleanupTimer);
|
|
196
|
-
this.cleanupTimer = null;
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
this.researchEngine?.stop();
|
|
200
|
-
this.embeddingEngine?.stop();
|
|
201
|
-
this.learningEngine?.stop();
|
|
202
|
-
this.mcpHttpServer?.stop();
|
|
203
|
-
this.apiServer?.stop();
|
|
204
|
-
this.ipcServer?.stop();
|
|
205
|
-
this.db?.close();
|
|
206
|
-
|
|
207
|
-
// Remove PID file
|
|
208
|
-
if (this.config) {
|
|
209
|
-
const pidPath = path.join(path.dirname(this.config.dbPath), 'brain.pid');
|
|
210
|
-
try { fs.unlinkSync(pidPath); } catch { /* ignore */ }
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
logger.info('Brain daemon stopped');
|
|
214
|
-
process.exit(0);
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
private setupEventListeners(services: Services, synapseManager: SynapseManager): void {
|
|
218
|
-
const bus = getEventBus();
|
|
219
|
-
|
|
220
|
-
// Error → Project synapse
|
|
221
|
-
bus.on('error:reported', ({ errorId, projectId }) => {
|
|
222
|
-
synapseManager.strengthen(
|
|
223
|
-
{ type: 'error', id: errorId },
|
|
224
|
-
{ type: 'project', id: projectId },
|
|
225
|
-
'co_occurs',
|
|
226
|
-
);
|
|
227
|
-
});
|
|
228
|
-
|
|
229
|
-
// Solution applied → strengthen or weaken
|
|
230
|
-
bus.on('solution:applied', ({ errorId, solutionId, success }) => {
|
|
231
|
-
if (success) {
|
|
232
|
-
synapseManager.strengthen(
|
|
233
|
-
{ type: 'solution', id: solutionId },
|
|
234
|
-
{ type: 'error', id: errorId },
|
|
235
|
-
'solves',
|
|
236
|
-
);
|
|
237
|
-
} else {
|
|
238
|
-
const synapse = synapseManager.find(
|
|
239
|
-
{ type: 'solution', id: solutionId },
|
|
240
|
-
{ type: 'error', id: errorId },
|
|
241
|
-
'solves',
|
|
242
|
-
);
|
|
243
|
-
if (synapse) synapseManager.weaken(synapse.id, 0.7);
|
|
244
|
-
}
|
|
245
|
-
});
|
|
246
|
-
|
|
247
|
-
// Module registered → link to project
|
|
248
|
-
bus.on('module:registered', ({ moduleId, projectId }) => {
|
|
249
|
-
synapseManager.strengthen(
|
|
250
|
-
{ type: 'code_module', id: moduleId },
|
|
251
|
-
{ type: 'project', id: projectId },
|
|
252
|
-
'co_occurs',
|
|
253
|
-
);
|
|
254
|
-
});
|
|
255
|
-
|
|
256
|
-
// Rule learned → log
|
|
257
|
-
bus.on('rule:learned', ({ ruleId, pattern }) => {
|
|
258
|
-
getLogger().info(`New rule #${ruleId} learned: ${pattern}`);
|
|
259
|
-
});
|
|
260
|
-
|
|
261
|
-
// Insight created → log
|
|
262
|
-
bus.on('insight:created', ({ insightId, type }) => {
|
|
263
|
-
getLogger().info(`New insight #${insightId} (${type})`);
|
|
264
|
-
});
|
|
265
|
-
}
|
|
266
|
-
}
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import type Database from 'better-sqlite3';
|
|
4
|
+
import { loadConfig } from './config.js';
|
|
5
|
+
import type { BrainConfig } from './types/config.types.js';
|
|
6
|
+
import { createLogger, getLogger } from './utils/logger.js';
|
|
7
|
+
import { getEventBus } from './utils/events.js';
|
|
8
|
+
import { createConnection } from './db/connection.js';
|
|
9
|
+
import { runMigrations } from './db/migrations/index.js';
|
|
10
|
+
|
|
11
|
+
// Repositories
|
|
12
|
+
import { ProjectRepository } from './db/repositories/project.repository.js';
|
|
13
|
+
import { ErrorRepository } from './db/repositories/error.repository.js';
|
|
14
|
+
import { SolutionRepository } from './db/repositories/solution.repository.js';
|
|
15
|
+
import { RuleRepository } from './db/repositories/rule.repository.js';
|
|
16
|
+
import { AntipatternRepository } from './db/repositories/antipattern.repository.js';
|
|
17
|
+
import { TerminalRepository } from './db/repositories/terminal.repository.js';
|
|
18
|
+
import { CodeModuleRepository } from './db/repositories/code-module.repository.js';
|
|
19
|
+
import { SynapseRepository } from './db/repositories/synapse.repository.js';
|
|
20
|
+
import { NotificationRepository } from './db/repositories/notification.repository.js';
|
|
21
|
+
import { InsightRepository } from './db/repositories/insight.repository.js';
|
|
22
|
+
|
|
23
|
+
// Services
|
|
24
|
+
import { ErrorService } from './services/error.service.js';
|
|
25
|
+
import { SolutionService } from './services/solution.service.js';
|
|
26
|
+
import { TerminalService } from './services/terminal.service.js';
|
|
27
|
+
import { PreventionService } from './services/prevention.service.js';
|
|
28
|
+
import { CodeService } from './services/code.service.js';
|
|
29
|
+
import { SynapseService } from './services/synapse.service.js';
|
|
30
|
+
import { ResearchService } from './services/research.service.js';
|
|
31
|
+
import { NotificationService } from './services/notification.service.js';
|
|
32
|
+
import { AnalyticsService } from './services/analytics.service.js';
|
|
33
|
+
import { GitService } from './services/git.service.js';
|
|
34
|
+
|
|
35
|
+
// Synapses
|
|
36
|
+
import { SynapseManager } from './synapses/synapse-manager.js';
|
|
37
|
+
|
|
38
|
+
// Engines
|
|
39
|
+
import { LearningEngine } from './learning/learning-engine.js';
|
|
40
|
+
import { ResearchEngine } from './research/research-engine.js';
|
|
41
|
+
|
|
42
|
+
// IPC
|
|
43
|
+
import { IpcRouter, type Services } from './ipc/router.js';
|
|
44
|
+
import { IpcServer } from './ipc/server.js';
|
|
45
|
+
|
|
46
|
+
// API & MCP HTTP
|
|
47
|
+
import { ApiServer } from './api/server.js';
|
|
48
|
+
import { McpHttpServer } from './mcp/http-server.js';
|
|
49
|
+
|
|
50
|
+
// Embeddings
|
|
51
|
+
import { EmbeddingEngine } from './embeddings/engine.js';
|
|
52
|
+
|
|
53
|
+
export class BrainCore {
|
|
54
|
+
private db: Database.Database | null = null;
|
|
55
|
+
private ipcServer: IpcServer | null = null;
|
|
56
|
+
private apiServer: ApiServer | null = null;
|
|
57
|
+
private mcpHttpServer: McpHttpServer | null = null;
|
|
58
|
+
private embeddingEngine: EmbeddingEngine | null = null;
|
|
59
|
+
private learningEngine: LearningEngine | null = null;
|
|
60
|
+
private researchEngine: ResearchEngine | null = null;
|
|
61
|
+
private cleanupTimer: ReturnType<typeof setInterval> | null = null;
|
|
62
|
+
private config: BrainConfig | null = null;
|
|
63
|
+
|
|
64
|
+
start(configPath?: string): void {
|
|
65
|
+
// 1. Config
|
|
66
|
+
this.config = loadConfig(configPath);
|
|
67
|
+
const config = this.config;
|
|
68
|
+
|
|
69
|
+
// 2. Ensure data dir
|
|
70
|
+
fs.mkdirSync(path.dirname(config.dbPath), { recursive: true });
|
|
71
|
+
|
|
72
|
+
// 3. Logger
|
|
73
|
+
createLogger({
|
|
74
|
+
level: config.log.level,
|
|
75
|
+
file: config.log.file,
|
|
76
|
+
maxSize: config.log.maxSize,
|
|
77
|
+
maxFiles: config.log.maxFiles,
|
|
78
|
+
});
|
|
79
|
+
const logger = getLogger();
|
|
80
|
+
|
|
81
|
+
// 4. Database
|
|
82
|
+
this.db = createConnection(config.dbPath);
|
|
83
|
+
runMigrations(this.db);
|
|
84
|
+
logger.info(`Database initialized: ${config.dbPath}`);
|
|
85
|
+
|
|
86
|
+
// 5. Repositories
|
|
87
|
+
const projectRepo = new ProjectRepository(this.db);
|
|
88
|
+
const errorRepo = new ErrorRepository(this.db);
|
|
89
|
+
const solutionRepo = new SolutionRepository(this.db);
|
|
90
|
+
const ruleRepo = new RuleRepository(this.db);
|
|
91
|
+
const antipatternRepo = new AntipatternRepository(this.db);
|
|
92
|
+
const terminalRepo = new TerminalRepository(this.db);
|
|
93
|
+
const codeModuleRepo = new CodeModuleRepository(this.db);
|
|
94
|
+
const synapseRepo = new SynapseRepository(this.db);
|
|
95
|
+
const notificationRepo = new NotificationRepository(this.db);
|
|
96
|
+
const insightRepo = new InsightRepository(this.db);
|
|
97
|
+
|
|
98
|
+
// 6. Synapse Manager
|
|
99
|
+
const synapseManager = new SynapseManager(synapseRepo, config.synapses);
|
|
100
|
+
|
|
101
|
+
// 7. Services
|
|
102
|
+
const services: Services = {
|
|
103
|
+
error: new ErrorService(errorRepo, projectRepo, synapseManager, config.matching),
|
|
104
|
+
solution: new SolutionService(solutionRepo, synapseManager),
|
|
105
|
+
terminal: new TerminalService(terminalRepo, config.terminal.staleTimeout),
|
|
106
|
+
prevention: new PreventionService(ruleRepo, antipatternRepo, synapseManager),
|
|
107
|
+
code: new CodeService(codeModuleRepo, projectRepo, synapseManager),
|
|
108
|
+
synapse: new SynapseService(synapseManager),
|
|
109
|
+
research: new ResearchService(insightRepo, errorRepo, synapseManager),
|
|
110
|
+
notification: new NotificationService(notificationRepo),
|
|
111
|
+
analytics: new AnalyticsService(
|
|
112
|
+
errorRepo, solutionRepo, codeModuleRepo,
|
|
113
|
+
ruleRepo, antipatternRepo, insightRepo,
|
|
114
|
+
synapseManager,
|
|
115
|
+
),
|
|
116
|
+
git: new GitService(this.db!, synapseManager),
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
// 8. Embedding Engine (local vector search)
|
|
120
|
+
if (config.embeddings.enabled) {
|
|
121
|
+
this.embeddingEngine = new EmbeddingEngine(config.embeddings, this.db!);
|
|
122
|
+
this.embeddingEngine.start();
|
|
123
|
+
// Wire embedding engine into services for hybrid search
|
|
124
|
+
services.error.setEmbeddingEngine(this.embeddingEngine);
|
|
125
|
+
services.code.setEmbeddingEngine(this.embeddingEngine);
|
|
126
|
+
logger.info('Embedding engine started (model will load in background)');
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// 9. Learning Engine
|
|
130
|
+
this.learningEngine = new LearningEngine(
|
|
131
|
+
config.learning, errorRepo, solutionRepo,
|
|
132
|
+
ruleRepo, antipatternRepo, synapseManager,
|
|
133
|
+
);
|
|
134
|
+
this.learningEngine.start();
|
|
135
|
+
logger.info(`Learning engine started (interval: ${config.learning.intervalMs}ms)`);
|
|
136
|
+
|
|
137
|
+
// 10. Research Engine
|
|
138
|
+
this.researchEngine = new ResearchEngine(
|
|
139
|
+
config.research, errorRepo, solutionRepo, projectRepo,
|
|
140
|
+
codeModuleRepo, synapseRepo, insightRepo, synapseManager,
|
|
141
|
+
);
|
|
142
|
+
this.researchEngine.start();
|
|
143
|
+
logger.info(`Research engine started (interval: ${config.research.intervalMs}ms)`);
|
|
144
|
+
|
|
145
|
+
// Expose learning engine to IPC
|
|
146
|
+
services.learning = this.learningEngine;
|
|
147
|
+
|
|
148
|
+
// 11. IPC Server
|
|
149
|
+
const router = new IpcRouter(services);
|
|
150
|
+
this.ipcServer = new IpcServer(router, config.ipc.pipeName);
|
|
151
|
+
this.ipcServer.start();
|
|
152
|
+
|
|
153
|
+
// 11a. REST API Server
|
|
154
|
+
if (config.api.enabled) {
|
|
155
|
+
this.apiServer = new ApiServer({
|
|
156
|
+
port: config.api.port,
|
|
157
|
+
router,
|
|
158
|
+
apiKey: config.api.apiKey,
|
|
159
|
+
});
|
|
160
|
+
this.apiServer.start();
|
|
161
|
+
logger.info(`REST API enabled on port ${config.api.port}`);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// 11b. MCP HTTP Server (SSE transport for Cursor, Windsurf, Cline, Continue)
|
|
165
|
+
if (config.mcpHttp.enabled) {
|
|
166
|
+
this.mcpHttpServer = new McpHttpServer(config.mcpHttp.port, router);
|
|
167
|
+
this.mcpHttpServer.start();
|
|
168
|
+
logger.info(`MCP HTTP (SSE) enabled on port ${config.mcpHttp.port}`);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// 12. Terminal cleanup timer
|
|
172
|
+
this.cleanupTimer = setInterval(() => {
|
|
173
|
+
services.terminal.cleanup();
|
|
174
|
+
}, 60_000);
|
|
175
|
+
|
|
176
|
+
// 13. Event listeners (synapse wiring)
|
|
177
|
+
this.setupEventListeners(services, synapseManager);
|
|
178
|
+
|
|
179
|
+
// 14. PID file
|
|
180
|
+
const pidPath = path.join(path.dirname(config.dbPath), 'brain.pid');
|
|
181
|
+
fs.writeFileSync(pidPath, String(process.pid));
|
|
182
|
+
|
|
183
|
+
// 15. Graceful shutdown
|
|
184
|
+
process.on('SIGINT', () => this.stop());
|
|
185
|
+
process.on('SIGTERM', () => this.stop());
|
|
186
|
+
|
|
187
|
+
logger.info(`Brain daemon started (PID: ${process.pid})`);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
stop(): void {
|
|
191
|
+
const logger = getLogger();
|
|
192
|
+
logger.info('Shutting down...');
|
|
193
|
+
|
|
194
|
+
if (this.cleanupTimer) {
|
|
195
|
+
clearInterval(this.cleanupTimer);
|
|
196
|
+
this.cleanupTimer = null;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
this.researchEngine?.stop();
|
|
200
|
+
this.embeddingEngine?.stop();
|
|
201
|
+
this.learningEngine?.stop();
|
|
202
|
+
this.mcpHttpServer?.stop();
|
|
203
|
+
this.apiServer?.stop();
|
|
204
|
+
this.ipcServer?.stop();
|
|
205
|
+
this.db?.close();
|
|
206
|
+
|
|
207
|
+
// Remove PID file
|
|
208
|
+
if (this.config) {
|
|
209
|
+
const pidPath = path.join(path.dirname(this.config.dbPath), 'brain.pid');
|
|
210
|
+
try { fs.unlinkSync(pidPath); } catch { /* ignore */ }
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
logger.info('Brain daemon stopped');
|
|
214
|
+
process.exit(0);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
private setupEventListeners(services: Services, synapseManager: SynapseManager): void {
|
|
218
|
+
const bus = getEventBus();
|
|
219
|
+
|
|
220
|
+
// Error → Project synapse
|
|
221
|
+
bus.on('error:reported', ({ errorId, projectId }) => {
|
|
222
|
+
synapseManager.strengthen(
|
|
223
|
+
{ type: 'error', id: errorId },
|
|
224
|
+
{ type: 'project', id: projectId },
|
|
225
|
+
'co_occurs',
|
|
226
|
+
);
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
// Solution applied → strengthen or weaken
|
|
230
|
+
bus.on('solution:applied', ({ errorId, solutionId, success }) => {
|
|
231
|
+
if (success) {
|
|
232
|
+
synapseManager.strengthen(
|
|
233
|
+
{ type: 'solution', id: solutionId },
|
|
234
|
+
{ type: 'error', id: errorId },
|
|
235
|
+
'solves',
|
|
236
|
+
);
|
|
237
|
+
} else {
|
|
238
|
+
const synapse = synapseManager.find(
|
|
239
|
+
{ type: 'solution', id: solutionId },
|
|
240
|
+
{ type: 'error', id: errorId },
|
|
241
|
+
'solves',
|
|
242
|
+
);
|
|
243
|
+
if (synapse) synapseManager.weaken(synapse.id, 0.7);
|
|
244
|
+
}
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
// Module registered → link to project
|
|
248
|
+
bus.on('module:registered', ({ moduleId, projectId }) => {
|
|
249
|
+
synapseManager.strengthen(
|
|
250
|
+
{ type: 'code_module', id: moduleId },
|
|
251
|
+
{ type: 'project', id: projectId },
|
|
252
|
+
'co_occurs',
|
|
253
|
+
);
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
// Rule learned → log
|
|
257
|
+
bus.on('rule:learned', ({ ruleId, pattern }) => {
|
|
258
|
+
getLogger().info(`New rule #${ruleId} learned: ${pattern}`);
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
// Insight created → log
|
|
262
|
+
bus.on('insight:created', ({ insightId, type }) => {
|
|
263
|
+
getLogger().info(`New insight #${insightId} (${type})`);
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
}
|