@timmeck/brain 1.8.4 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.dockerignore +11 -0
- package/Dockerfile +21 -0
- package/README.md +2 -0
- package/assets/brain-avatar-256.png +0 -0
- package/assets/brain-avatar-512.png +0 -0
- package/assets/brain-avatar.png +0 -0
- package/assets/synapse-network.png +0 -0
- package/dist/brain.d.ts +5 -0
- package/dist/brain.js +50 -3
- package/dist/brain.js.map +1 -1
- package/dist/cli/commands/start.js +54 -17
- package/dist/cli/commands/start.js.map +1 -1
- package/gen_avatar.py +142 -0
- package/package.json +1 -1
- package/reddit_post.md +45 -0
- package/src/brain.ts +50 -3
- package/src/cli/commands/start.ts +63 -20
package/.dockerignore
ADDED
package/Dockerfile
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
FROM node:22-slim
|
|
2
|
+
|
|
3
|
+
# better-sqlite3 needs build tools
|
|
4
|
+
RUN apt-get update && apt-get install -y python3 make g++ && rm -rf /var/lib/apt/lists/*
|
|
5
|
+
|
|
6
|
+
WORKDIR /app
|
|
7
|
+
|
|
8
|
+
COPY package.json package-lock.json ./
|
|
9
|
+
RUN npm ci --omit=dev
|
|
10
|
+
|
|
11
|
+
COPY dist/ dist/
|
|
12
|
+
COPY package.json ./
|
|
13
|
+
|
|
14
|
+
# Data directory for brain.db
|
|
15
|
+
RUN mkdir -p /data
|
|
16
|
+
ENV BRAIN_DATA_DIR=/data
|
|
17
|
+
|
|
18
|
+
EXPOSE 7777 7778
|
|
19
|
+
|
|
20
|
+
ENTRYPOINT ["node", "dist/index.js"]
|
|
21
|
+
CMD ["mcp-server"]
|
package/README.md
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
**Adaptive Error Memory & Code Intelligence System for Claude Code**
|
|
4
4
|
|
|
5
|
+

|
|
6
|
+
|
|
5
7
|
Brain is an MCP server that gives Claude Code a persistent memory. It remembers every error you've encountered, every solution that worked (or didn't), and every code module across all your projects. Over time, it learns — strengthening connections between related concepts through a Hebbian synapse network, surfacing patterns, and proactively suggesting solutions before you even ask.
|
|
6
8
|
|
|
7
9
|
## Why Brain?
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/dist/brain.d.ts
CHANGED
|
@@ -8,7 +8,12 @@ export declare class BrainCore {
|
|
|
8
8
|
private researchEngine;
|
|
9
9
|
private cleanupTimer;
|
|
10
10
|
private config;
|
|
11
|
+
private configPath?;
|
|
12
|
+
private restarting;
|
|
11
13
|
start(configPath?: string): void;
|
|
14
|
+
private logCrash;
|
|
15
|
+
private cleanup;
|
|
16
|
+
restart(): void;
|
|
12
17
|
stop(): void;
|
|
13
18
|
private setupEventListeners;
|
|
14
19
|
}
|
package/dist/brain.js
CHANGED
|
@@ -50,7 +50,10 @@ export class BrainCore {
|
|
|
50
50
|
researchEngine = null;
|
|
51
51
|
cleanupTimer = null;
|
|
52
52
|
config = null;
|
|
53
|
+
configPath;
|
|
54
|
+
restarting = false;
|
|
53
55
|
start(configPath) {
|
|
56
|
+
this.configPath = configPath;
|
|
54
57
|
// 1. Config
|
|
55
58
|
this.config = loadConfig(configPath);
|
|
56
59
|
const config = this.config;
|
|
@@ -145,11 +148,30 @@ export class BrainCore {
|
|
|
145
148
|
// 15. Graceful shutdown
|
|
146
149
|
process.on('SIGINT', () => this.stop());
|
|
147
150
|
process.on('SIGTERM', () => this.stop());
|
|
151
|
+
// 16. Crash recovery — auto-restart on uncaught errors
|
|
152
|
+
process.on('uncaughtException', (err) => {
|
|
153
|
+
logger.error('Uncaught exception — restarting', { error: err.message, stack: err.stack });
|
|
154
|
+
this.logCrash('uncaughtException', err);
|
|
155
|
+
this.restart();
|
|
156
|
+
});
|
|
157
|
+
process.on('unhandledRejection', (reason) => {
|
|
158
|
+
logger.error('Unhandled rejection — restarting', { reason: String(reason) });
|
|
159
|
+
this.logCrash('unhandledRejection', reason instanceof Error ? reason : new Error(String(reason)));
|
|
160
|
+
this.restart();
|
|
161
|
+
});
|
|
148
162
|
logger.info(`Brain daemon started (PID: ${process.pid})`);
|
|
149
163
|
}
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
164
|
+
logCrash(type, err) {
|
|
165
|
+
if (!this.config)
|
|
166
|
+
return;
|
|
167
|
+
const crashLog = path.join(path.dirname(this.config.dbPath), 'crashes.log');
|
|
168
|
+
const entry = `[${new Date().toISOString()}] ${type}: ${err.message}\n${err.stack ?? ''}\n\n`;
|
|
169
|
+
try {
|
|
170
|
+
fs.appendFileSync(crashLog, entry);
|
|
171
|
+
}
|
|
172
|
+
catch { /* best effort */ }
|
|
173
|
+
}
|
|
174
|
+
cleanup() {
|
|
153
175
|
if (this.cleanupTimer) {
|
|
154
176
|
clearInterval(this.cleanupTimer);
|
|
155
177
|
this.cleanupTimer = null;
|
|
@@ -161,6 +183,31 @@ export class BrainCore {
|
|
|
161
183
|
this.apiServer?.stop();
|
|
162
184
|
this.ipcServer?.stop();
|
|
163
185
|
this.db?.close();
|
|
186
|
+
this.db = null;
|
|
187
|
+
this.ipcServer = null;
|
|
188
|
+
this.apiServer = null;
|
|
189
|
+
this.mcpHttpServer = null;
|
|
190
|
+
this.embeddingEngine = null;
|
|
191
|
+
this.learningEngine = null;
|
|
192
|
+
this.researchEngine = null;
|
|
193
|
+
}
|
|
194
|
+
restart() {
|
|
195
|
+
if (this.restarting)
|
|
196
|
+
return;
|
|
197
|
+
this.restarting = true;
|
|
198
|
+
const logger = getLogger();
|
|
199
|
+
logger.info('Restarting Brain daemon...');
|
|
200
|
+
try {
|
|
201
|
+
this.cleanup();
|
|
202
|
+
}
|
|
203
|
+
catch { /* best effort cleanup */ }
|
|
204
|
+
this.restarting = false;
|
|
205
|
+
this.start(this.configPath);
|
|
206
|
+
}
|
|
207
|
+
stop() {
|
|
208
|
+
const logger = getLogger();
|
|
209
|
+
logger.info('Shutting down...');
|
|
210
|
+
this.cleanup();
|
|
164
211
|
// Remove PID file
|
|
165
212
|
if (this.config) {
|
|
166
213
|
const pidPath = path.join(path.dirname(this.config.dbPath), 'brain.pid');
|
package/dist/brain.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"brain.js","sourceRoot":"","sources":["../src/brain.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"brain.js","sourceRoot":"","sources":["../src/brain.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,6 +5,58 @@ import path from 'node:path';
|
|
|
5
5
|
import { getDataDir } from '../../utils/paths.js';
|
|
6
6
|
import { c, icons } from '../colors.js';
|
|
7
7
|
import { checkForUpdate } from '../update-check.js';
|
|
8
|
+
const MAX_RESTARTS = 5;
|
|
9
|
+
const RESTART_WINDOW_MS = 5 * 60 * 1000; // 5 minutes
|
|
10
|
+
const BASE_BACKOFF_MS = 1000;
|
|
11
|
+
function spawnDaemon(entryPoint, args) {
|
|
12
|
+
const child = spawn(process.execPath, [entryPoint, ...args], {
|
|
13
|
+
detached: true,
|
|
14
|
+
stdio: 'ignore',
|
|
15
|
+
});
|
|
16
|
+
child.unref();
|
|
17
|
+
return child;
|
|
18
|
+
}
|
|
19
|
+
function startWatchdog(entryPoint, args, pidPath) {
|
|
20
|
+
const restartTimes = [];
|
|
21
|
+
function launch() {
|
|
22
|
+
const child = spawnDaemon(entryPoint, args);
|
|
23
|
+
console.log(`${icons.brain} ${c.info('Brain daemon starting')} ${c.dim(`(PID: ${child.pid})`)}`);
|
|
24
|
+
child.on('exit', (code) => {
|
|
25
|
+
// Normal shutdown (code 0 or SIGTERM) — don't restart
|
|
26
|
+
if (code === 0 || code === null)
|
|
27
|
+
return;
|
|
28
|
+
const now = Date.now();
|
|
29
|
+
restartTimes.push(now);
|
|
30
|
+
// Only count restarts within the window
|
|
31
|
+
const recentRestarts = restartTimes.filter((t) => now - t < RESTART_WINDOW_MS);
|
|
32
|
+
restartTimes.length = 0;
|
|
33
|
+
restartTimes.push(...recentRestarts);
|
|
34
|
+
if (recentRestarts.length > MAX_RESTARTS) {
|
|
35
|
+
console.error(`${icons.error} ${c.error(`Brain daemon crashed ${MAX_RESTARTS} times in 5 minutes — giving up.`)}`);
|
|
36
|
+
// Clean up stale PID file
|
|
37
|
+
try {
|
|
38
|
+
fs.unlinkSync(pidPath);
|
|
39
|
+
}
|
|
40
|
+
catch { /* ignore */ }
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
const backoff = BASE_BACKOFF_MS * Math.pow(2, recentRestarts.length - 1);
|
|
44
|
+
console.log(`${icons.warn} ${c.warn(`Brain daemon exited (code ${code}) — restarting in ${backoff / 1000}s...`)}`);
|
|
45
|
+
setTimeout(launch, backoff);
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
launch();
|
|
49
|
+
// Wait briefly for PID file to appear
|
|
50
|
+
setTimeout(async () => {
|
|
51
|
+
if (fs.existsSync(pidPath)) {
|
|
52
|
+
console.log(`${icons.ok} ${c.success('Brain daemon started successfully.')} ${c.dim('(watchdog active)')}`);
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
console.log(`${icons.clock} ${c.warn('Brain daemon may still be starting.')} Check: ${c.cyan('brain status')}`);
|
|
56
|
+
}
|
|
57
|
+
await checkForUpdate();
|
|
58
|
+
}, 1000);
|
|
59
|
+
}
|
|
8
60
|
export function startCommand() {
|
|
9
61
|
return new Command('start')
|
|
10
62
|
.description('Start the Brain daemon')
|
|
@@ -33,27 +85,12 @@ export function startCommand() {
|
|
|
33
85
|
});
|
|
34
86
|
return;
|
|
35
87
|
}
|
|
36
|
-
// Spawn detached daemon
|
|
88
|
+
// Spawn detached daemon with watchdog
|
|
37
89
|
const args = ['daemon'];
|
|
38
90
|
if (opts.config)
|
|
39
91
|
args.push('-c', opts.config);
|
|
40
92
|
const entryPoint = path.resolve(import.meta.dirname, '../../index.js');
|
|
41
|
-
|
|
42
|
-
detached: true,
|
|
43
|
-
stdio: 'ignore',
|
|
44
|
-
});
|
|
45
|
-
child.unref();
|
|
46
|
-
console.log(`${icons.brain} ${c.info('Brain daemon starting')} ${c.dim(`(PID: ${child.pid})`)}`);
|
|
47
|
-
// Wait briefly for PID file to appear
|
|
48
|
-
setTimeout(async () => {
|
|
49
|
-
if (fs.existsSync(pidPath)) {
|
|
50
|
-
console.log(`${icons.ok} ${c.success('Brain daemon started successfully.')}`);
|
|
51
|
-
}
|
|
52
|
-
else {
|
|
53
|
-
console.log(`${icons.clock} ${c.warn('Brain daemon may still be starting.')} Check: ${c.cyan('brain status')}`);
|
|
54
|
-
}
|
|
55
|
-
await checkForUpdate();
|
|
56
|
-
}, 1000);
|
|
93
|
+
startWatchdog(entryPoint, args, pidPath);
|
|
57
94
|
});
|
|
58
95
|
}
|
|
59
96
|
//# sourceMappingURL=start.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"start.js","sourceRoot":"","sources":["../../../src/cli/commands/start.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,KAAK,
|
|
1
|
+
{"version":3,"file":"start.js","sourceRoot":"","sources":["../../../src/cli/commands/start.ts"],"names":[],"mappings":"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"}
|
package/gen_avatar.py
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
"""Generate a circular Brain avatar for GitHub/X profile pictures."""
|
|
2
|
+
from PIL import Image, ImageDraw, ImageFilter, ImageFont
|
|
3
|
+
import math
|
|
4
|
+
import random
|
|
5
|
+
|
|
6
|
+
random.seed(42)
|
|
7
|
+
|
|
8
|
+
SIZE = 1024
|
|
9
|
+
CENTER = SIZE // 2
|
|
10
|
+
R = SIZE // 2 - 20 # circle radius
|
|
11
|
+
|
|
12
|
+
img = Image.new('RGBA', (SIZE, SIZE), (0, 0, 0, 0))
|
|
13
|
+
draw = ImageDraw.Draw(img)
|
|
14
|
+
|
|
15
|
+
# --- Background circle with dark gradient ---
|
|
16
|
+
bg = Image.new('RGBA', (SIZE, SIZE), (0, 0, 0, 0))
|
|
17
|
+
bg_draw = ImageDraw.Draw(bg)
|
|
18
|
+
for r in range(R, 0, -1):
|
|
19
|
+
t = r / R
|
|
20
|
+
c1 = (10, 12, 28) # center
|
|
21
|
+
c2 = (18, 20, 42) # edge
|
|
22
|
+
color = tuple(int(c1[i] * t + c2[i] * (1 - t)) for i in range(3))
|
|
23
|
+
bg_draw.ellipse([CENTER - r, CENTER - r, CENTER + r, CENTER + r], fill=(*color, 255))
|
|
24
|
+
img = Image.alpha_composite(img, bg)
|
|
25
|
+
|
|
26
|
+
# --- Generate synapse network nodes ---
|
|
27
|
+
node_types = {
|
|
28
|
+
'project': {'color': (255, 179, 71), 'count': 4, 'radius': (18, 28)},
|
|
29
|
+
'code_module': {'color': (180, 122, 255), 'count': 22, 'radius': (6, 12)},
|
|
30
|
+
'error': {'color': (255, 85, 119), 'count': 10, 'radius': (7, 13)},
|
|
31
|
+
'solution': {'color': (61, 255, 160), 'count': 6, 'radius': (7, 11)},
|
|
32
|
+
'rule': {'color': (91, 156, 255), 'count': 5, 'radius': (5, 9)},
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
nodes = []
|
|
36
|
+
for ntype, cfg in node_types.items():
|
|
37
|
+
for _ in range(cfg['count']):
|
|
38
|
+
# Place within circle
|
|
39
|
+
for _attempt in range(50):
|
|
40
|
+
angle = random.uniform(0, 2 * math.pi)
|
|
41
|
+
dist = random.uniform(40, R - 50)
|
|
42
|
+
x = CENTER + math.cos(angle) * dist
|
|
43
|
+
y = CENTER + math.sin(angle) * dist
|
|
44
|
+
# Check no overlap
|
|
45
|
+
too_close = False
|
|
46
|
+
for n in nodes:
|
|
47
|
+
if math.hypot(x - n['x'], y - n['y']) < 35:
|
|
48
|
+
too_close = True
|
|
49
|
+
break
|
|
50
|
+
if not too_close:
|
|
51
|
+
break
|
|
52
|
+
r = random.randint(*cfg['radius'])
|
|
53
|
+
nodes.append({'x': x, 'y': y, 'r': r, 'type': ntype, 'color': cfg['color']})
|
|
54
|
+
|
|
55
|
+
# --- Create edges between nearby nodes ---
|
|
56
|
+
edges = []
|
|
57
|
+
for i, n1 in enumerate(nodes):
|
|
58
|
+
distances = []
|
|
59
|
+
for j, n2 in enumerate(nodes):
|
|
60
|
+
if i == j:
|
|
61
|
+
continue
|
|
62
|
+
d = math.hypot(n1['x'] - n2['x'], n1['y'] - n2['y'])
|
|
63
|
+
distances.append((d, j))
|
|
64
|
+
distances.sort()
|
|
65
|
+
# Connect to 2-4 nearest
|
|
66
|
+
count = random.randint(2, 4) if n1['type'] == 'project' else random.randint(1, 3)
|
|
67
|
+
for d, j in distances[:count]:
|
|
68
|
+
if d < R * 1.2:
|
|
69
|
+
edge = tuple(sorted([i, j]))
|
|
70
|
+
if edge not in edges:
|
|
71
|
+
edges.append(edge)
|
|
72
|
+
|
|
73
|
+
# --- Draw on a separate layer for glow ---
|
|
74
|
+
glow_layer = Image.new('RGBA', (SIZE, SIZE), (0, 0, 0, 0))
|
|
75
|
+
glow_draw = ImageDraw.Draw(glow_layer)
|
|
76
|
+
|
|
77
|
+
# Edge colors by type combination
|
|
78
|
+
EDGE_COLORS = {
|
|
79
|
+
'project': (91, 156, 255, 50),
|
|
80
|
+
'code_module': (140, 100, 220, 40),
|
|
81
|
+
'error': (200, 80, 100, 40),
|
|
82
|
+
'solution': (50, 200, 130, 45),
|
|
83
|
+
'rule': (70, 130, 220, 40),
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
# Draw edges
|
|
87
|
+
for i, j in edges:
|
|
88
|
+
n1, n2 = nodes[i], nodes[j]
|
|
89
|
+
ec = EDGE_COLORS.get(n1['type'], (91, 156, 255, 40))
|
|
90
|
+
glow_draw.line([(n1['x'], n1['y']), (n2['x'], n2['y'])], fill=ec, width=2)
|
|
91
|
+
|
|
92
|
+
# Draw edge glow
|
|
93
|
+
edge_glow = glow_layer.filter(ImageFilter.GaussianBlur(4))
|
|
94
|
+
img = Image.alpha_composite(img, edge_glow)
|
|
95
|
+
img = Image.alpha_composite(img, glow_layer)
|
|
96
|
+
|
|
97
|
+
# --- Draw nodes with glow ---
|
|
98
|
+
for n in nodes:
|
|
99
|
+
color = n['color']
|
|
100
|
+
r = n['r']
|
|
101
|
+
x, y = int(n['x']), int(n['y'])
|
|
102
|
+
|
|
103
|
+
# Outer glow
|
|
104
|
+
glow = Image.new('RGBA', (SIZE, SIZE), (0, 0, 0, 0))
|
|
105
|
+
g_draw = ImageDraw.Draw(glow)
|
|
106
|
+
glow_r = r + 12
|
|
107
|
+
g_draw.ellipse([x - glow_r, y - glow_r, x + glow_r, y + glow_r],
|
|
108
|
+
fill=(*color, 40))
|
|
109
|
+
glow = glow.filter(ImageFilter.GaussianBlur(10))
|
|
110
|
+
img = Image.alpha_composite(img, glow)
|
|
111
|
+
|
|
112
|
+
# Core node
|
|
113
|
+
draw = ImageDraw.Draw(img)
|
|
114
|
+
draw.ellipse([x - r, y - r, x + r, y + r], fill=(*color, 220))
|
|
115
|
+
|
|
116
|
+
# Inner highlight
|
|
117
|
+
hr = max(2, r // 3)
|
|
118
|
+
hx, hy = x - r // 4, y - r // 4
|
|
119
|
+
draw.ellipse([hx - hr, hy - hr, hx + hr, hy + hr], fill=(255, 255, 255, 70))
|
|
120
|
+
|
|
121
|
+
# --- Circular mask ---
|
|
122
|
+
mask = Image.new('L', (SIZE, SIZE), 0)
|
|
123
|
+
mask_draw = ImageDraw.Draw(mask)
|
|
124
|
+
mask_draw.ellipse([CENTER - R, CENTER - R, CENTER + R, CENTER + R], fill=255)
|
|
125
|
+
img.putalpha(mask)
|
|
126
|
+
|
|
127
|
+
# --- Subtle border ring ---
|
|
128
|
+
draw = ImageDraw.Draw(img)
|
|
129
|
+
for offset in range(3):
|
|
130
|
+
alpha = 80 - offset * 25
|
|
131
|
+
draw.ellipse([CENTER - R + offset, CENTER - R + offset, CENTER + R - offset, CENTER + R - offset],
|
|
132
|
+
outline=(91, 156, 255, max(alpha, 10)), width=1)
|
|
133
|
+
|
|
134
|
+
# --- Save ---
|
|
135
|
+
img.save('C:/Users/mecklenburg/Desktop/brain/assets/brain-avatar.png')
|
|
136
|
+
|
|
137
|
+
# Also save smaller sizes for different platforms
|
|
138
|
+
for size, name in [(512, 'brain-avatar-512.png'), (256, 'brain-avatar-256.png')]:
|
|
139
|
+
resized = img.resize((size, size), Image.LANCZOS)
|
|
140
|
+
resized.save(f'C:/Users/mecklenburg/Desktop/brain/assets/{name}')
|
|
141
|
+
|
|
142
|
+
print(f'Generated: brain-avatar.png (1024px), brain-avatar-512.png, brain-avatar-256.png')
|
package/package.json
CHANGED
package/reddit_post.md
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Reddit Post for r/ClaudeAI
|
|
2
|
+
|
|
3
|
+
## Title:
|
|
4
|
+
I built a persistent memory system for Claude Code — it remembers every error, solution, and code module across all your projects
|
|
5
|
+
|
|
6
|
+
## Body:
|
|
7
|
+
|
|
8
|
+
Claude Code starts fresh every session. After months of hitting the same errors and rewriting the same code, I built **Brain** — an MCP server that gives Claude Code a persistent memory.
|
|
9
|
+
|
|
10
|
+
### What it does
|
|
11
|
+
|
|
12
|
+
- **Error Memory** — Brain remembers every error you've encountered and every solution that worked. Next time you hit the same bug, it suggests the fix with a confidence score.
|
|
13
|
+
- **Cross-Project Learning** — Fixed a bug in project A? Brain suggests the same fix when a similar error appears in project B.
|
|
14
|
+
- **Code Intelligence** — Before writing new code, Brain checks if similar modules already exist across your 36 projects. No more reinventing the wheel.
|
|
15
|
+
- **Hebbian Synapse Network** — 37,000+ weighted connections between errors, solutions, and code modules. Connections strengthen with use, like biological synapses.
|
|
16
|
+
- **Proactive Prevention** — Post-write hooks check your code against known antipatterns *before* errors occur.
|
|
17
|
+
- **Auto-Detect** — Hooks catch errors in real-time from Bash output and report them to Brain automatically. You don't have to do anything.
|
|
18
|
+
|
|
19
|
+
### The stack
|
|
20
|
+
|
|
21
|
+
- TypeScript, better-sqlite3, MCP SDK
|
|
22
|
+
- 13 MCP tools for Claude Code
|
|
23
|
+
- REST API (30+ endpoints) + MCP over HTTP/SSE (works with Cursor, Windsurf, Cline)
|
|
24
|
+
- Local embeddings (all-MiniLM-L6-v2) for hybrid search — no cloud, no API keys
|
|
25
|
+
- Interactive dashboard with live synapse network visualization
|
|
26
|
+
- Full CLI: `brain status`, `brain query`, `brain explain`, `brain dashboard`
|
|
27
|
+
|
|
28
|
+
### Real numbers from my setup
|
|
29
|
+
|
|
30
|
+
- 18,160 code modules indexed across 36 projects
|
|
31
|
+
- 37,277 synapse connections
|
|
32
|
+
- 4,902 research insights generated automatically
|
|
33
|
+
- 139 tests, all passing
|
|
34
|
+
|
|
35
|
+
### Install
|
|
36
|
+
|
|
37
|
+
```
|
|
38
|
+
npm install -g @timmeck/brain
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Setup takes 2 minutes — add the MCP server + hooks to your Claude Code settings and run `brain start`. That's it.
|
|
42
|
+
|
|
43
|
+
GitHub: https://github.com/timmeck/brain
|
|
44
|
+
|
|
45
|
+
MIT licensed, open source. Would love feedback — especially on what MCP tools would be most useful to add next.
|
package/src/brain.ts
CHANGED
|
@@ -60,8 +60,11 @@ export class BrainCore {
|
|
|
60
60
|
private researchEngine: ResearchEngine | null = null;
|
|
61
61
|
private cleanupTimer: ReturnType<typeof setInterval> | null = null;
|
|
62
62
|
private config: BrainConfig | null = null;
|
|
63
|
+
private configPath?: string;
|
|
64
|
+
private restarting = false;
|
|
63
65
|
|
|
64
66
|
start(configPath?: string): void {
|
|
67
|
+
this.configPath = configPath;
|
|
65
68
|
// 1. Config
|
|
66
69
|
this.config = loadConfig(configPath);
|
|
67
70
|
const config = this.config;
|
|
@@ -184,13 +187,29 @@ export class BrainCore {
|
|
|
184
187
|
process.on('SIGINT', () => this.stop());
|
|
185
188
|
process.on('SIGTERM', () => this.stop());
|
|
186
189
|
|
|
190
|
+
// 16. Crash recovery — auto-restart on uncaught errors
|
|
191
|
+
process.on('uncaughtException', (err) => {
|
|
192
|
+
logger.error('Uncaught exception — restarting', { error: err.message, stack: err.stack });
|
|
193
|
+
this.logCrash('uncaughtException', err);
|
|
194
|
+
this.restart();
|
|
195
|
+
});
|
|
196
|
+
process.on('unhandledRejection', (reason) => {
|
|
197
|
+
logger.error('Unhandled rejection — restarting', { reason: String(reason) });
|
|
198
|
+
this.logCrash('unhandledRejection', reason instanceof Error ? reason : new Error(String(reason)));
|
|
199
|
+
this.restart();
|
|
200
|
+
});
|
|
201
|
+
|
|
187
202
|
logger.info(`Brain daemon started (PID: ${process.pid})`);
|
|
188
203
|
}
|
|
189
204
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
205
|
+
private logCrash(type: string, err: Error): void {
|
|
206
|
+
if (!this.config) return;
|
|
207
|
+
const crashLog = path.join(path.dirname(this.config.dbPath), 'crashes.log');
|
|
208
|
+
const entry = `[${new Date().toISOString()}] ${type}: ${err.message}\n${err.stack ?? ''}\n\n`;
|
|
209
|
+
try { fs.appendFileSync(crashLog, entry); } catch { /* best effort */ }
|
|
210
|
+
}
|
|
193
211
|
|
|
212
|
+
private cleanup(): void {
|
|
194
213
|
if (this.cleanupTimer) {
|
|
195
214
|
clearInterval(this.cleanupTimer);
|
|
196
215
|
this.cleanupTimer = null;
|
|
@@ -204,6 +223,34 @@ export class BrainCore {
|
|
|
204
223
|
this.ipcServer?.stop();
|
|
205
224
|
this.db?.close();
|
|
206
225
|
|
|
226
|
+
this.db = null;
|
|
227
|
+
this.ipcServer = null;
|
|
228
|
+
this.apiServer = null;
|
|
229
|
+
this.mcpHttpServer = null;
|
|
230
|
+
this.embeddingEngine = null;
|
|
231
|
+
this.learningEngine = null;
|
|
232
|
+
this.researchEngine = null;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
restart(): void {
|
|
236
|
+
if (this.restarting) return;
|
|
237
|
+
this.restarting = true;
|
|
238
|
+
|
|
239
|
+
const logger = getLogger();
|
|
240
|
+
logger.info('Restarting Brain daemon...');
|
|
241
|
+
|
|
242
|
+
try { this.cleanup(); } catch { /* best effort cleanup */ }
|
|
243
|
+
|
|
244
|
+
this.restarting = false;
|
|
245
|
+
this.start(this.configPath);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
stop(): void {
|
|
249
|
+
const logger = getLogger();
|
|
250
|
+
logger.info('Shutting down...');
|
|
251
|
+
|
|
252
|
+
this.cleanup();
|
|
253
|
+
|
|
207
254
|
// Remove PID file
|
|
208
255
|
if (this.config) {
|
|
209
256
|
const pidPath = path.join(path.dirname(this.config.dbPath), 'brain.pid');
|
|
@@ -1,11 +1,70 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
|
-
import { spawn } from 'node:child_process';
|
|
2
|
+
import { spawn, type ChildProcess } from 'node:child_process';
|
|
3
3
|
import fs from 'node:fs';
|
|
4
4
|
import path from 'node:path';
|
|
5
5
|
import { getDataDir } from '../../utils/paths.js';
|
|
6
6
|
import { c, icons } from '../colors.js';
|
|
7
7
|
import { checkForUpdate } from '../update-check.js';
|
|
8
8
|
|
|
9
|
+
const MAX_RESTARTS = 5;
|
|
10
|
+
const RESTART_WINDOW_MS = 5 * 60 * 1000; // 5 minutes
|
|
11
|
+
const BASE_BACKOFF_MS = 1000;
|
|
12
|
+
|
|
13
|
+
function spawnDaemon(entryPoint: string, args: string[]): ChildProcess {
|
|
14
|
+
const child = spawn(process.execPath, [entryPoint, ...args], {
|
|
15
|
+
detached: true,
|
|
16
|
+
stdio: 'ignore',
|
|
17
|
+
});
|
|
18
|
+
child.unref();
|
|
19
|
+
return child;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function startWatchdog(entryPoint: string, args: string[], pidPath: string): void {
|
|
23
|
+
const restartTimes: number[] = [];
|
|
24
|
+
|
|
25
|
+
function launch(): void {
|
|
26
|
+
const child = spawnDaemon(entryPoint, args);
|
|
27
|
+
console.log(`${icons.brain} ${c.info('Brain daemon starting')} ${c.dim(`(PID: ${child.pid})`)}`);
|
|
28
|
+
|
|
29
|
+
child.on('exit', (code) => {
|
|
30
|
+
// Normal shutdown (code 0 or SIGTERM) — don't restart
|
|
31
|
+
if (code === 0 || code === null) return;
|
|
32
|
+
|
|
33
|
+
const now = Date.now();
|
|
34
|
+
restartTimes.push(now);
|
|
35
|
+
|
|
36
|
+
// Only count restarts within the window
|
|
37
|
+
const recentRestarts = restartTimes.filter((t) => now - t < RESTART_WINDOW_MS);
|
|
38
|
+
restartTimes.length = 0;
|
|
39
|
+
restartTimes.push(...recentRestarts);
|
|
40
|
+
|
|
41
|
+
if (recentRestarts.length > MAX_RESTARTS) {
|
|
42
|
+
console.error(`${icons.error} ${c.error(`Brain daemon crashed ${MAX_RESTARTS} times in 5 minutes — giving up.`)}`);
|
|
43
|
+
// Clean up stale PID file
|
|
44
|
+
try { fs.unlinkSync(pidPath); } catch { /* ignore */ }
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const backoff = BASE_BACKOFF_MS * Math.pow(2, recentRestarts.length - 1);
|
|
49
|
+
console.log(`${icons.warn} ${c.warn(`Brain daemon exited (code ${code}) — restarting in ${backoff / 1000}s...`)}`);
|
|
50
|
+
|
|
51
|
+
setTimeout(launch, backoff);
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
launch();
|
|
56
|
+
|
|
57
|
+
// Wait briefly for PID file to appear
|
|
58
|
+
setTimeout(async () => {
|
|
59
|
+
if (fs.existsSync(pidPath)) {
|
|
60
|
+
console.log(`${icons.ok} ${c.success('Brain daemon started successfully.')} ${c.dim('(watchdog active)')}`);
|
|
61
|
+
} else {
|
|
62
|
+
console.log(`${icons.clock} ${c.warn('Brain daemon may still be starting.')} Check: ${c.cyan('brain status')}`);
|
|
63
|
+
}
|
|
64
|
+
await checkForUpdate();
|
|
65
|
+
}, 1000);
|
|
66
|
+
}
|
|
67
|
+
|
|
9
68
|
export function startCommand(): Command {
|
|
10
69
|
return new Command('start')
|
|
11
70
|
.description('Start the Brain daemon')
|
|
@@ -36,27 +95,11 @@ export function startCommand(): Command {
|
|
|
36
95
|
return;
|
|
37
96
|
}
|
|
38
97
|
|
|
39
|
-
// Spawn detached daemon
|
|
98
|
+
// Spawn detached daemon with watchdog
|
|
40
99
|
const args = ['daemon'];
|
|
41
100
|
if (opts.config) args.push('-c', opts.config);
|
|
42
|
-
|
|
43
101
|
const entryPoint = path.resolve(import.meta.dirname, '../../index.js');
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
stdio: 'ignore',
|
|
47
|
-
});
|
|
48
|
-
child.unref();
|
|
49
|
-
|
|
50
|
-
console.log(`${icons.brain} ${c.info('Brain daemon starting')} ${c.dim(`(PID: ${child.pid})`)}`);
|
|
51
|
-
|
|
52
|
-
// Wait briefly for PID file to appear
|
|
53
|
-
setTimeout(async () => {
|
|
54
|
-
if (fs.existsSync(pidPath)) {
|
|
55
|
-
console.log(`${icons.ok} ${c.success('Brain daemon started successfully.')}`);
|
|
56
|
-
} else {
|
|
57
|
-
console.log(`${icons.clock} ${c.warn('Brain daemon may still be starting.')} Check: ${c.cyan('brain status')}`);
|
|
58
|
-
}
|
|
59
|
-
await checkForUpdate();
|
|
60
|
-
}, 1000);
|
|
102
|
+
|
|
103
|
+
startWatchdog(entryPoint, args, pidPath);
|
|
61
104
|
});
|
|
62
105
|
}
|