@timmeck/brain-core 2.19.0 → 2.21.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.
@@ -0,0 +1,176 @@
1
+ import http from 'node:http';
2
+ import fs from 'node:fs';
3
+ import path from 'node:path';
4
+ import { getLogger } from '../utils/logger.js';
5
+ // ── Server ───────────────────────────────────────────────
6
+ export class UnifiedDashboardServer {
7
+ options;
8
+ server = null;
9
+ clients = new Set();
10
+ unsubscribe = null;
11
+ heartbeatTimer = null;
12
+ statusTimer = null;
13
+ dashboardHtml = null;
14
+ logger = getLogger();
15
+ constructor(options) {
16
+ this.options = options;
17
+ }
18
+ start() {
19
+ const { port, thoughtStream } = this.options;
20
+ // Load dashboard HTML
21
+ const htmlPath = path.resolve(path.dirname(new URL(import.meta.url).pathname.replace(/^\/([A-Z]:)/, '$1')), '../../unified-dashboard.html');
22
+ try {
23
+ this.dashboardHtml = fs.readFileSync(htmlPath, 'utf-8');
24
+ }
25
+ catch {
26
+ this.dashboardHtml = '<html><body><h1>Unified Dashboard HTML not found</h1></body></html>';
27
+ }
28
+ this.server = http.createServer((req, res) => {
29
+ const url = new URL(req.url ?? '/', `http://localhost:${port}`);
30
+ // CORS + Security
31
+ res.setHeader('Access-Control-Allow-Origin', '*');
32
+ res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
33
+ res.setHeader('X-Content-Type-Options', 'nosniff');
34
+ if (req.method === 'OPTIONS') {
35
+ res.writeHead(204);
36
+ res.end();
37
+ return;
38
+ }
39
+ // Dashboard
40
+ if (url.pathname === '/' || url.pathname === '/dashboard') {
41
+ res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
42
+ res.end(this.dashboardHtml);
43
+ return;
44
+ }
45
+ // Full state snapshot
46
+ if (url.pathname === '/api/state') {
47
+ try {
48
+ const state = {
49
+ overview: this.options.getOverview(),
50
+ transfer: this.options.getTransferStatus(),
51
+ attention: this.options.getAttentionStatus(),
52
+ thoughts: thoughtStream.getRecent(200),
53
+ engines: thoughtStream.getEngineActivity(),
54
+ stats: thoughtStream.getStats(),
55
+ notifications: this.options.getNotifications(),
56
+ };
57
+ res.writeHead(200, { 'Content-Type': 'application/json' });
58
+ res.end(JSON.stringify(state));
59
+ }
60
+ catch (err) {
61
+ res.writeHead(500, { 'Content-Type': 'application/json' });
62
+ res.end(JSON.stringify({ error: err.message }));
63
+ }
64
+ return;
65
+ }
66
+ // Trigger feedback cycle
67
+ if (url.pathname === '/api/trigger' && req.method === 'POST') {
68
+ if (this.options.onTriggerFeedback) {
69
+ try {
70
+ this.options.onTriggerFeedback();
71
+ res.writeHead(200, { 'Content-Type': 'application/json' });
72
+ res.end(JSON.stringify({ triggered: true }));
73
+ }
74
+ catch (err) {
75
+ res.writeHead(500, { 'Content-Type': 'application/json' });
76
+ res.end(JSON.stringify({ error: err.message }));
77
+ }
78
+ }
79
+ else {
80
+ res.writeHead(501, { 'Content-Type': 'application/json' });
81
+ res.end(JSON.stringify({ error: 'Feedback trigger not configured' }));
82
+ }
83
+ return;
84
+ }
85
+ // SSE stream
86
+ if (url.pathname === '/events') {
87
+ res.writeHead(200, {
88
+ 'Content-Type': 'text/event-stream',
89
+ 'Cache-Control': 'no-cache',
90
+ 'Connection': 'keep-alive',
91
+ });
92
+ res.write(`event: connected\ndata: ${JSON.stringify({ clients: this.clients.size + 1 })}\n\n`);
93
+ this.clients.add(res);
94
+ req.on('close', () => this.clients.delete(res));
95
+ return;
96
+ }
97
+ res.writeHead(404, { 'Content-Type': 'text/plain' });
98
+ res.end('Not Found');
99
+ });
100
+ // Subscribe to thought stream → broadcast immediately
101
+ this.unsubscribe = thoughtStream.onThought((thought) => {
102
+ this.broadcast('thought', thought);
103
+ });
104
+ // Status snapshot every 10s
105
+ this.statusTimer = setInterval(() => {
106
+ if (this.clients.size > 0) {
107
+ try {
108
+ this.broadcast('status', {
109
+ overview: this.options.getOverview(),
110
+ engines: thoughtStream.getEngineActivity(),
111
+ stats: thoughtStream.getStats(),
112
+ });
113
+ }
114
+ catch { /* ignore errors during broadcast */ }
115
+ }
116
+ }, 10_000);
117
+ // Heartbeat every 30s
118
+ this.heartbeatTimer = setInterval(() => {
119
+ if (this.clients.size > 0) {
120
+ this.broadcast('heartbeat', { time: Date.now() });
121
+ }
122
+ }, 30_000);
123
+ this.server.on('error', (err) => {
124
+ if (err.code === 'EADDRINUSE') {
125
+ this.logger.warn(`Unified dashboard port ${port} already in use — skipping`);
126
+ this.server?.close();
127
+ this.server = null;
128
+ }
129
+ else {
130
+ this.logger.error(`Unified dashboard error: ${err.message}`);
131
+ }
132
+ });
133
+ this.server.listen(port, () => {
134
+ this.logger.info(`Unified dashboard started on http://localhost:${port}`);
135
+ });
136
+ }
137
+ stop() {
138
+ if (this.unsubscribe) {
139
+ this.unsubscribe();
140
+ this.unsubscribe = null;
141
+ }
142
+ if (this.statusTimer) {
143
+ clearInterval(this.statusTimer);
144
+ this.statusTimer = null;
145
+ }
146
+ if (this.heartbeatTimer) {
147
+ clearInterval(this.heartbeatTimer);
148
+ this.heartbeatTimer = null;
149
+ }
150
+ for (const client of this.clients) {
151
+ try {
152
+ client.end();
153
+ }
154
+ catch { /* ignore */ }
155
+ }
156
+ this.clients.clear();
157
+ this.server?.close();
158
+ this.server = null;
159
+ this.logger.info('Unified dashboard stopped');
160
+ }
161
+ getClientCount() {
162
+ return this.clients.size;
163
+ }
164
+ broadcast(event, data) {
165
+ const msg = `event: ${event}\ndata: ${JSON.stringify(data)}\n\n`;
166
+ for (const client of this.clients) {
167
+ try {
168
+ client.write(msg);
169
+ }
170
+ catch {
171
+ this.clients.delete(client);
172
+ }
173
+ }
174
+ }
175
+ }
176
+ //# sourceMappingURL=unified-server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unified-server.js","sourceRoot":"","sources":["../../src/unified/unified-server.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@timmeck/brain-core",
3
- "version": "2.19.0",
3
+ "version": "2.21.0",
4
4
  "description": "Shared core infrastructure for the Brain ecosystem — IPC, MCP, CLI, DB connection, and utilities",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",