@timmeck/trading-brain 1.0.0 → 1.1.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.
Files changed (138) hide show
  1. package/README.md +20 -0
  2. package/dashboard.html +480 -0
  3. package/dist/api/server.d.ts +3 -16
  4. package/dist/api/server.js +4 -123
  5. package/dist/api/server.js.map +1 -1
  6. package/dist/cli/colors.d.ts +10 -26
  7. package/dist/cli/colors.js +3 -62
  8. package/dist/cli/colors.js.map +1 -1
  9. package/dist/cli/commands/dashboard.d.ts +2 -0
  10. package/dist/cli/commands/dashboard.js +159 -0
  11. package/dist/cli/commands/dashboard.js.map +1 -0
  12. package/dist/cli/commands/peers.d.ts +2 -0
  13. package/dist/cli/commands/peers.js +38 -0
  14. package/dist/cli/commands/peers.js.map +1 -0
  15. package/dist/dashboard/renderer.d.ts +17 -0
  16. package/dist/dashboard/renderer.js +130 -0
  17. package/dist/dashboard/renderer.js.map +1 -0
  18. package/dist/dashboard/server.d.ts +15 -0
  19. package/dist/dashboard/server.js +116 -0
  20. package/dist/dashboard/server.js.map +1 -0
  21. package/dist/db/connection.d.ts +1 -2
  22. package/dist/db/connection.js +1 -18
  23. package/dist/db/connection.js.map +1 -1
  24. package/dist/hooks/post-tool-use.d.ts +2 -0
  25. package/dist/hooks/post-tool-use.js +108 -0
  26. package/dist/hooks/post-tool-use.js.map +1 -0
  27. package/dist/index.js +5 -1
  28. package/dist/index.js.map +1 -1
  29. package/dist/ipc/__tests__/protocol.test.d.ts +1 -0
  30. package/dist/ipc/__tests__/protocol.test.js +89 -0
  31. package/dist/ipc/__tests__/protocol.test.js.map +1 -0
  32. package/dist/ipc/client.d.ts +1 -16
  33. package/dist/ipc/client.js +1 -94
  34. package/dist/ipc/client.js.map +1 -1
  35. package/dist/ipc/protocol.d.ts +1 -8
  36. package/dist/ipc/protocol.js +1 -28
  37. package/dist/ipc/protocol.js.map +1 -1
  38. package/dist/ipc/router.js +8 -0
  39. package/dist/ipc/router.js.map +1 -1
  40. package/dist/ipc/server.d.ts +1 -18
  41. package/dist/ipc/server.js +1 -141
  42. package/dist/ipc/server.js.map +1 -1
  43. package/dist/mcp/http-server.d.ts +1 -7
  44. package/dist/mcp/http-server.js +6 -111
  45. package/dist/mcp/http-server.js.map +1 -1
  46. package/dist/mcp/server.js +5 -60
  47. package/dist/mcp/server.js.map +1 -1
  48. package/dist/signals/__tests__/fingerprint.test.d.ts +1 -0
  49. package/dist/signals/__tests__/fingerprint.test.js +164 -0
  50. package/dist/signals/__tests__/fingerprint.test.js.map +1 -0
  51. package/dist/signals/__tests__/wilson-score.test.d.ts +1 -0
  52. package/dist/signals/__tests__/wilson-score.test.js +65 -0
  53. package/dist/signals/__tests__/wilson-score.test.js.map +1 -0
  54. package/dist/trading-core.d.ts +1 -0
  55. package/dist/trading-core.js +6 -1
  56. package/dist/trading-core.js.map +1 -1
  57. package/dist/types/ipc.types.d.ts +1 -11
  58. package/dist/utils/__tests__/hash.test.d.ts +1 -0
  59. package/dist/utils/__tests__/hash.test.js +23 -0
  60. package/dist/utils/__tests__/hash.test.js.map +1 -0
  61. package/dist/utils/__tests__/paths.test.d.ts +1 -0
  62. package/dist/utils/__tests__/paths.test.js +60 -0
  63. package/dist/utils/__tests__/paths.test.js.map +1 -0
  64. package/dist/utils/events.d.ts +4 -8
  65. package/dist/utils/events.js +2 -14
  66. package/dist/utils/events.js.map +1 -1
  67. package/dist/utils/hash.d.ts +1 -1
  68. package/dist/utils/hash.js +1 -4
  69. package/dist/utils/hash.js.map +1 -1
  70. package/dist/utils/logger.d.ts +3 -2
  71. package/dist/utils/logger.js +8 -35
  72. package/dist/utils/logger.js.map +1 -1
  73. package/dist/utils/paths.d.ts +2 -1
  74. package/dist/utils/paths.js +4 -13
  75. package/dist/utils/paths.js.map +1 -1
  76. package/package.json +2 -1
  77. package/src/api/server.ts +0 -160
  78. package/src/cli/colors.ts +0 -80
  79. package/src/cli/commands/config.ts +0 -76
  80. package/src/cli/commands/doctor.ts +0 -62
  81. package/src/cli/commands/export.ts +0 -24
  82. package/src/cli/commands/import.ts +0 -44
  83. package/src/cli/commands/insights.ts +0 -30
  84. package/src/cli/commands/network.ts +0 -43
  85. package/src/cli/commands/query.ts +0 -28
  86. package/src/cli/commands/rules.ts +0 -27
  87. package/src/cli/commands/start.ts +0 -93
  88. package/src/cli/commands/status.ts +0 -64
  89. package/src/cli/commands/stop.ts +0 -33
  90. package/src/cli/ipc-helper.ts +0 -22
  91. package/src/config.ts +0 -103
  92. package/src/db/connection.ts +0 -22
  93. package/src/db/migrations/001_core.ts +0 -43
  94. package/src/db/migrations/002_synapses.ts +0 -44
  95. package/src/db/migrations/003_learning.ts +0 -49
  96. package/src/db/migrations/004_research.ts +0 -30
  97. package/src/db/migrations/index.ts +0 -60
  98. package/src/db/repositories/calibration.repository.ts +0 -86
  99. package/src/db/repositories/chain.repository.ts +0 -70
  100. package/src/db/repositories/graph.repository.ts +0 -103
  101. package/src/db/repositories/insight.repository.ts +0 -80
  102. package/src/db/repositories/rule.repository.ts +0 -67
  103. package/src/db/repositories/signal.repository.ts +0 -48
  104. package/src/db/repositories/synapse.repository.ts +0 -71
  105. package/src/db/repositories/trade.repository.ts +0 -97
  106. package/src/graph/weighted-graph.ts +0 -194
  107. package/src/index.ts +0 -55
  108. package/src/ipc/client.ts +0 -112
  109. package/src/ipc/protocol.ts +0 -35
  110. package/src/ipc/router.ts +0 -113
  111. package/src/ipc/server.ts +0 -150
  112. package/src/learning/calibrator.ts +0 -57
  113. package/src/learning/chain-detector.ts +0 -43
  114. package/src/learning/learning-engine.ts +0 -94
  115. package/src/learning/pattern-extractor.ts +0 -53
  116. package/src/mcp/http-server.ts +0 -118
  117. package/src/mcp/server.ts +0 -72
  118. package/src/mcp/tools.ts +0 -256
  119. package/src/research/research-engine.ts +0 -223
  120. package/src/services/analytics.service.ts +0 -68
  121. package/src/services/insight.service.ts +0 -29
  122. package/src/services/signal.service.ts +0 -109
  123. package/src/services/strategy.service.ts +0 -130
  124. package/src/services/synapse.service.ts +0 -58
  125. package/src/services/trade.service.ts +0 -139
  126. package/src/signals/fingerprint.ts +0 -93
  127. package/src/signals/wilson-score.ts +0 -17
  128. package/src/synapses/decay.ts +0 -19
  129. package/src/synapses/hebbian.ts +0 -23
  130. package/src/synapses/synapse-manager.ts +0 -112
  131. package/src/trading-core.ts +0 -285
  132. package/src/types/config.types.ts +0 -60
  133. package/src/types/ipc.types.ts +0 -8
  134. package/src/utils/events.ts +0 -42
  135. package/src/utils/hash.ts +0 -5
  136. package/src/utils/logger.ts +0 -48
  137. package/src/utils/paths.ts +0 -19
  138. package/tsconfig.json +0 -18
@@ -1,41 +1,9 @@
1
- import http from 'node:http';
2
- import { getLogger } from '../utils/logger.js';
1
+ import { BaseApiServer } from '@timmeck/brain-core';
3
2
  import { getEventBus } from '../utils/events.js';
4
- export class ApiServer {
5
- options;
6
- server = null;
7
- logger = getLogger();
8
- sseClients = new Set();
3
+ export class ApiServer extends BaseApiServer {
9
4
  statsTimer = null;
10
- constructor(options) {
11
- this.options = options;
12
- }
13
5
  start() {
14
- const { port, apiKey } = this.options;
15
- this.server = http.createServer((req, res) => {
16
- res.setHeader('Access-Control-Allow-Origin', '*');
17
- res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
18
- res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization, X-API-Key');
19
- if (req.method === 'OPTIONS') {
20
- res.writeHead(204);
21
- res.end();
22
- return;
23
- }
24
- if (apiKey) {
25
- const provided = req.headers['x-api-key'] ?? req.headers.authorization?.replace('Bearer ', '');
26
- if (provided !== apiKey) {
27
- this.json(res, 401, { error: 'Unauthorized' });
28
- return;
29
- }
30
- }
31
- this.handleRequest(req, res).catch((err) => {
32
- this.logger.error('API error:', err);
33
- this.json(res, 500, { error: err instanceof Error ? err.message : String(err) });
34
- });
35
- });
36
- this.server.listen(port, () => {
37
- this.logger.info(`REST API server started on http://localhost:${port}`);
38
- });
6
+ super.start();
39
7
  this.setupSSE();
40
8
  }
41
9
  stop() {
@@ -43,83 +11,7 @@ export class ApiServer {
43
11
  clearInterval(this.statsTimer);
44
12
  this.statsTimer = null;
45
13
  }
46
- for (const client of this.sseClients) {
47
- try {
48
- client.end();
49
- }
50
- catch { /* ignore */ }
51
- }
52
- this.sseClients.clear();
53
- this.server?.close();
54
- this.server = null;
55
- this.logger.info('REST API server stopped');
56
- }
57
- async handleRequest(req, res) {
58
- const url = new URL(req.url ?? '/', 'http://localhost');
59
- const pathname = url.pathname;
60
- const method = req.method ?? 'GET';
61
- if (pathname === '/api/v1/health') {
62
- this.json(res, 200, { status: 'ok', timestamp: new Date().toISOString() });
63
- return;
64
- }
65
- if (pathname === '/api/v1/events' && method === 'GET') {
66
- res.writeHead(200, { 'Content-Type': 'text/event-stream', 'Cache-Control': 'no-cache', 'Connection': 'keep-alive' });
67
- res.write('data: {"type":"connected"}\n\n');
68
- this.sseClients.add(res);
69
- req.on('close', () => this.sseClients.delete(res));
70
- return;
71
- }
72
- if (pathname === '/api/v1/methods' && method === 'GET') {
73
- const methods = this.options.router.listMethods();
74
- this.json(res, 200, { methods, rpcEndpoint: '/api/v1/rpc' });
75
- return;
76
- }
77
- if (pathname === '/api/v1/rpc' && method === 'POST') {
78
- const body = await this.readBody(req);
79
- if (!body) {
80
- this.json(res, 400, { error: 'Empty request body' });
81
- return;
82
- }
83
- const parsed = JSON.parse(body);
84
- if (Array.isArray(parsed)) {
85
- const results = parsed.map((call) => {
86
- try {
87
- const result = this.options.router.handle(call.method, call.params ?? {});
88
- return { id: call.id, result };
89
- }
90
- catch (err) {
91
- return { id: call.id, error: err instanceof Error ? err.message : String(err) };
92
- }
93
- });
94
- this.json(res, 200, results);
95
- return;
96
- }
97
- if (!parsed.method) {
98
- this.json(res, 400, { error: 'Missing "method" field' });
99
- return;
100
- }
101
- try {
102
- const result = this.options.router.handle(parsed.method, parsed.params ?? {});
103
- this.json(res, 200, { result });
104
- }
105
- catch (err) {
106
- this.json(res, 400, { error: err instanceof Error ? err.message : String(err) });
107
- }
108
- return;
109
- }
110
- this.json(res, 404, { error: `No route for ${method} ${pathname}` });
111
- }
112
- json(res, status, data) {
113
- res.writeHead(status, { 'Content-Type': 'application/json' });
114
- res.end(JSON.stringify(data));
115
- }
116
- readBody(req) {
117
- return new Promise((resolve, reject) => {
118
- const chunks = [];
119
- req.on('data', (chunk) => chunks.push(chunk));
120
- req.on('end', () => resolve(Buffer.concat(chunks).toString('utf8')));
121
- req.on('error', reject);
122
- });
14
+ super.stop();
123
15
  }
124
16
  setupSSE() {
125
17
  const bus = getEventBus();
@@ -142,16 +34,5 @@ export class ApiServer {
142
34
  }
143
35
  }, 30_000);
144
36
  }
145
- broadcastSSE(data) {
146
- const msg = `data: ${JSON.stringify(data)}\n\n`;
147
- for (const client of this.sseClients) {
148
- try {
149
- client.write(msg);
150
- }
151
- catch {
152
- this.sseClients.delete(client);
153
- }
154
- }
155
- }
156
37
  }
157
38
  //# sourceMappingURL=server.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/api/server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/api/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAyB,MAAM,qBAAqB,CAAC;AAC3E,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAIjD,MAAM,OAAO,SAAU,SAAQ,aAAa;IAClC,UAAU,GAA0C,IAAI,CAAC;IAEjE,KAAK;QACH,KAAK,CAAC,KAAK,EAAE,CAAC;QACd,IAAI,CAAC,QAAQ,EAAE,CAAC;IAClB,CAAC;IAED,IAAI;QACF,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,aAAa,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAC/B,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACzB,CAAC;QACD,KAAK,CAAC,IAAI,EAAE,CAAC;IACf,CAAC;IAEO,QAAQ;QACd,MAAM,GAAG,GAAG,WAAW,EAAE,CAAC;QAC1B,MAAM,UAAU,GAAG;YACjB,gBAAgB,EAAE,iBAAiB,EAAE,cAAc;YACnD,gBAAgB,EAAE,iBAAiB,EAAE,qBAAqB;SAClD,CAAC;QAEX,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;YACnC,GAAG,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,IAAa,EAAE,EAAE;gBAClC,IAAI,CAAC,YAAY,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAC/D,CAAC,CAAC,CAAC;QACL,CAAC;QAED,IAAI,CAAC,UAAU,GAAG,WAAW,CAAC,GAAG,EAAE;YACjC,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;gBAC7B,IAAI,CAAC;oBACH,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,mBAAmB,EAAE,EAAE,CAAC,CAAC;oBACpE,IAAI,CAAC,YAAY,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;gBAC9D,CAAC;gBAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;YAC1B,CAAC;QACH,CAAC,EAAE,MAAM,CAAC,CAAC;IACb,CAAC;CACF"}
@@ -1,46 +1,30 @@
1
- export declare const c: {
2
- blue: import("chalk").ChalkInstance;
3
- purple: import("chalk").ChalkInstance;
4
- cyan: import("chalk").ChalkInstance;
5
- green: import("chalk").ChalkInstance;
6
- red: import("chalk").ChalkInstance;
7
- orange: import("chalk").ChalkInstance;
8
- dim: import("chalk").ChalkInstance;
9
- dimmer: import("chalk").ChalkInstance;
10
- label: import("chalk").ChalkInstance;
11
- value: import("chalk").ChalkInstance;
12
- heading: import("chalk").ChalkInstance;
13
- success: import("chalk").ChalkInstance;
14
- error: import("chalk").ChalkInstance;
15
- warn: import("chalk").ChalkInstance;
16
- info: import("chalk").ChalkInstance;
17
- };
1
+ import { c, header, keyValue, statusBadge, progressBar, divider, table, stripAnsi } from '@timmeck/brain-core';
2
+ export { c, header, keyValue, statusBadge, progressBar, divider, table, stripAnsi };
18
3
  export declare const icons: {
19
4
  brain: string;
20
- chart: string;
5
+ search: string;
6
+ trade: string;
7
+ rule: string;
8
+ chain: string;
21
9
  check: string;
22
10
  cross: string;
23
11
  arrow: string;
24
12
  dot: string;
13
+ circle: string;
25
14
  bar: string;
26
15
  barLight: string;
27
16
  dash: string;
28
17
  pipe: string;
18
+ corner: string;
19
+ tee: string;
29
20
  star: string;
30
21
  bolt: string;
31
- search: string;
32
22
  gear: string;
23
+ chart: string;
33
24
  synapse: string;
34
25
  insight: string;
35
26
  warn: string;
36
27
  error: string;
37
28
  ok: string;
38
29
  clock: string;
39
- trade: string;
40
- rule: string;
41
- chain: string;
42
30
  };
43
- export declare function header(title: string, icon?: string): string;
44
- export declare function keyValue(key: string, value: string | number, indent?: number): string;
45
- export declare function divider(width?: number): string;
46
- export declare function table(rows: string[][], colWidths?: number[]): string;
@@ -1,70 +1,11 @@
1
- import chalk from 'chalk';
2
- export const c = {
3
- blue: chalk.hex('#5b9cff'),
4
- purple: chalk.hex('#b47aff'),
5
- cyan: chalk.hex('#47e5ff'),
6
- green: chalk.hex('#3dffa0'),
7
- red: chalk.hex('#ff5577'),
8
- orange: chalk.hex('#ffb347'),
9
- dim: chalk.hex('#8b8fb0'),
10
- dimmer: chalk.hex('#4a4d6e'),
11
- label: chalk.hex('#8b8fb0'),
12
- value: chalk.white.bold,
13
- heading: chalk.hex('#5b9cff').bold,
14
- success: chalk.hex('#3dffa0').bold,
15
- error: chalk.hex('#ff5577').bold,
16
- warn: chalk.hex('#ffb347').bold,
17
- info: chalk.hex('#47e5ff'),
18
- };
1
+ import { c, baseIcons, header, keyValue, statusBadge, progressBar, divider, table, stripAnsi } from '@timmeck/brain-core';
2
+ export { c, header, keyValue, statusBadge, progressBar, divider, table, stripAnsi };
19
3
  export const icons = {
4
+ ...baseIcons,
20
5
  brain: '🧠',
21
- chart: '📊',
22
- check: '✓',
23
- cross: '✗',
24
- arrow: '→',
25
- dot: '●',
26
- bar: '█',
27
- barLight: '░',
28
- dash: '─',
29
- pipe: '│',
30
- star: '★',
31
- bolt: '⚡',
32
6
  search: '🔍',
33
- gear: '⚙',
34
- synapse: '🔗',
35
- insight: '💡',
36
- warn: '⚠',
37
- error: '❌',
38
- ok: '✅',
39
- clock: '⏱',
40
7
  trade: '💹',
41
8
  rule: '📋',
42
9
  chain: '⛓',
43
10
  };
44
- export function header(title, icon) {
45
- const prefix = icon ? `${icon} ` : '';
46
- const line = c.dimmer(icons.dash.repeat(40));
47
- return `\n${line}\n${prefix}${c.heading(title)}\n${line}`;
48
- }
49
- export function keyValue(key, value, indent = 2) {
50
- const pad = ' '.repeat(indent);
51
- return `${pad}${c.label(key + ':')} ${c.value(String(value))}`;
52
- }
53
- export function divider(width = 40) {
54
- return c.dimmer(icons.dash.repeat(width));
55
- }
56
- function stripAnsi(str) {
57
- // eslint-disable-next-line no-control-regex
58
- return str.replace(/\x1b\[[0-9;]*m/g, '');
59
- }
60
- export function table(rows, colWidths) {
61
- if (rows.length === 0)
62
- return '';
63
- const widths = colWidths ?? rows[0].map((_, i) => Math.max(...rows.map(r => stripAnsi(r[i] ?? '').length)));
64
- return rows.map(row => row.map((cell, i) => {
65
- const stripped = stripAnsi(cell);
66
- const pad = Math.max(0, (widths[i] ?? stripped.length) - stripped.length);
67
- return cell + ' '.repeat(pad);
68
- }).join(' ')).join('\n');
69
- }
70
11
  //# sourceMappingURL=colors.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"colors.js","sourceRoot":"","sources":["../../src/cli/colors.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"colors.js","sourceRoot":"","sources":["../../src/cli/colors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,WAAW,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAE1H,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,WAAW,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;AAEpF,MAAM,CAAC,MAAM,KAAK,GAAG;IACnB,GAAG,SAAS;IACZ,KAAK,EAAE,IAAI;IACX,MAAM,EAAE,IAAI;IACZ,KAAK,EAAE,IAAI;IACX,IAAI,EAAE,IAAI;IACV,KAAK,EAAE,GAAG;CACX,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { Command } from 'commander';
2
+ export declare function dashboardCommand(): Command;
@@ -0,0 +1,159 @@
1
+ import { Command } from 'commander';
2
+ import fs from 'node:fs';
3
+ import path from 'node:path';
4
+ import { fileURLToPath } from 'node:url';
5
+ import { withIpc } from '../ipc-helper.js';
6
+ import { c, icons, header, divider } from '../colors.js';
7
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
8
+ const DASHBOARD_HTML = path.resolve(__dirname, '../../../dashboard.html');
9
+ function escapeHtml(str) {
10
+ return str.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
11
+ }
12
+ export function dashboardCommand() {
13
+ return new Command('dashboard')
14
+ .description('Open the trading dashboard in browser')
15
+ .option('-o, --output <path>', 'Output HTML file path')
16
+ .option('--no-open', 'Generate HTML but do not open in browser')
17
+ .action(async (opts) => {
18
+ await withIpc(async (client) => {
19
+ console.log(`${icons.chart} ${c.info('Generating dashboard...')}`);
20
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
21
+ const summary = await client.request('analytics.summary', {});
22
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
23
+ const recentTrades = await client.request('trade.recent', { limit: 10 });
24
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
25
+ const rules = await client.request('rule.list', {});
26
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
27
+ const chains = await client.request('chain.list', { limit: 20 });
28
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
29
+ const insights = await client.request('insight.list', { limit: 200 });
30
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
31
+ const synapseStats = await client.request('synapse.stats', {});
32
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
33
+ const calibration = await client.request('calibration.get', {});
34
+ const s = summary;
35
+ // Read template
36
+ let html = fs.readFileSync(DASHBOARD_HTML, 'utf-8');
37
+ // Stats
38
+ html = html.replace('{{TRADES}}', String(s.trades?.total ?? 0));
39
+ html = html.replace('{{RULES}}', String(s.rules?.total ?? 0));
40
+ html = html.replace('{{CHAINS}}', String(s.chains?.total ?? 0));
41
+ html = html.replace('{{INSIGHTS}}', String(s.insights?.total ?? 0));
42
+ html = html.replace('{{SYNAPSES}}', String(s.network?.synapses ?? 0));
43
+ html = html.replace('{{GRAPH_NODES}}', String(s.network?.graphNodes ?? 0));
44
+ // Win rate
45
+ const winRate = Math.round(s.trades?.recentWinRate ?? 0);
46
+ html = html.replace('{{WIN_RATE}}', String(winRate));
47
+ const gaugeOffset = ((1 - winRate / 100) * 251.2).toFixed(1);
48
+ html = html.replace('{{GAUGE_OFFSET}}', gaugeOffset);
49
+ // Activity
50
+ const activity = Math.min(100, Math.round(((s.trades?.total ?? 0) * 3 +
51
+ (s.rules?.total ?? 0) * 15 +
52
+ (s.chains?.total ?? 0) * 5 +
53
+ (s.insights?.total ?? 0) * 5 +
54
+ (s.network?.synapses ?? 0) * 2) / 2));
55
+ html = html.replace(/\{\{ACTIVITY\}\}/g, String(activity));
56
+ html = html.replace('{{VERSION}}', '1.0.0');
57
+ // Recent trades
58
+ const trades = Array.isArray(recentTrades) ? recentTrades : [];
59
+ let tradesHtml = '';
60
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
61
+ for (const trade of trades) {
62
+ const win = trade.win ? 'win' : 'loss';
63
+ const resultLabel = trade.win ? 'WIN' : 'LOSS';
64
+ tradesHtml += `<div class="trade-card ${win}"><div class="trade-meta"><span class="trade-result ${win}">${resultLabel}</span><strong>${escapeHtml(trade.pair ?? '')}</strong></div><p>${escapeHtml(trade.fingerprint ?? '')}</p><div class="trade-details"><span>${escapeHtml(trade.bot_type ?? '')}</span><span>${escapeHtml(trade.created_at?.slice(0, 10) ?? '')}</span></div></div>\n`;
65
+ }
66
+ if (!tradesHtml)
67
+ tradesHtml = '<p class="empty">No trades recorded yet.</p>';
68
+ html = html.replace('{{RECENT_TRADES}}', tradesHtml);
69
+ // Chains
70
+ const chainsList = Array.isArray(chains) ? chains : (s.chains?.recent ?? []);
71
+ let chainsHtml = '';
72
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
73
+ for (const chain of chainsList) {
74
+ const type = chain.type === 'win' ? 'win' : 'loss';
75
+ const icon = chain.type === 'win' ? '&#128293;' : '&#10060;';
76
+ chainsHtml += `<div class="chain-card"><div class="chain-icon">${icon}</div><div class="chain-info"><div class="chain-pair">${escapeHtml(chain.pair ?? '')}</div><div class="chain-type">${type} streak</div></div><div class="chain-length ${type}">${chain.length}x</div></div>\n`;
77
+ }
78
+ if (!chainsHtml)
79
+ chainsHtml = '<p class="empty">No chains detected yet.</p>';
80
+ html = html.replace('{{CHAINS_LIST}}', chainsHtml);
81
+ // Rules
82
+ const rulesList = Array.isArray(rules) ? rules : [];
83
+ let rulesHtml = '';
84
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
85
+ for (const rule of rulesList) {
86
+ const conf = Math.round((rule.confidence ?? 0) * 100);
87
+ const wr = Math.round((rule.win_rate ?? 0) * 100);
88
+ rulesHtml += `<div class="rule-card"><div class="rule-pattern">${escapeHtml(rule.pattern ?? '')}</div><div class="rule-recommendation">Win rate: ${wr}% (${rule.sample_count ?? 0} trades)</div><div class="rule-confidence"><span>Confidence:</span><div class="confidence-bar"><div class="confidence-fill" data-width="${conf}"></div></div><span>${conf}%</span></div></div>\n`;
89
+ }
90
+ if (!rulesHtml)
91
+ rulesHtml = '<p class="empty">No rules learned yet.</p>';
92
+ html = html.replace('{{RULES_LIST}}', rulesHtml);
93
+ // Calibration
94
+ const cal = calibration ?? {};
95
+ const stage = (cal.outcomeCount ?? 0) < 20 ? '1' : (cal.outcomeCount ?? 0) < 100 ? '2' : (cal.outcomeCount ?? 0) < 500 ? '3' : '4';
96
+ html = html.replace('{{CAL_STAGE}}', stage);
97
+ html = html.replace('{{CAL_LEARNING_RATE}}', String(cal.learningRate ?? '0.3'));
98
+ html = html.replace('{{CAL_WILSON_Z}}', String(cal.wilsonZ ?? '1.0'));
99
+ html = html.replace('{{CAL_DECAY}}', String((cal.decayHalfLifeDays ?? 60) + 'd'));
100
+ // Insights
101
+ const allInsights = Array.isArray(insights) ? insights : [];
102
+ const insightsByType = {
103
+ trend: [], gap: [], synergy: [], performance: [], regime_shift: [],
104
+ };
105
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
106
+ for (const ins of allInsights) {
107
+ const type = ins.type ?? 'performance';
108
+ if (insightsByType[type])
109
+ insightsByType[type].push(ins);
110
+ else
111
+ insightsByType.performance.push(ins);
112
+ }
113
+ const typeColors = {
114
+ trend: 'cyan', gap: 'orange', synergy: 'green', performance: 'blue', regime_shift: 'red',
115
+ };
116
+ const pluralMap = {
117
+ trend: 'TRENDS', gap: 'GAPS', synergy: 'SYNERGIES',
118
+ performance: 'PERFORMANCE', regime_shift: 'REGIMES',
119
+ };
120
+ for (const [type, items] of Object.entries(insightsByType)) {
121
+ const plural = pluralMap[type] ?? `${type.toUpperCase()}S`;
122
+ html = html.replace(`{{${plural}_COUNT}}`, String(items.length));
123
+ let insHtml = '';
124
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
125
+ for (const ins of items) {
126
+ const sev = ins.severity === 'high' ? 'high' : ins.severity === 'medium' ? 'medium' : 'low';
127
+ insHtml += `<div class="insight-card ${typeColors[type] ?? 'blue'}"><div class="insight-header"><span class="prio prio-${sev}">${escapeHtml(ins.severity ?? 'low')}</span><strong>${escapeHtml(ins.title ?? '')}</strong></div><p>${escapeHtml(ins.description ?? '')}</p></div>\n`;
128
+ }
129
+ if (!insHtml)
130
+ insHtml = '<p class="empty">No insights in this category yet.</p>';
131
+ html = html.replace(`{{${plural}}}`, insHtml);
132
+ }
133
+ // Graph edges (from synapse stats)
134
+ const strongest = synapseStats?.strongest ?? [];
135
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
136
+ const graphEdges = strongest.map((e) => ({
137
+ s: `${e.source_type ?? 'node'}:${e.source_id ?? ''}`,
138
+ t: `${e.target_type ?? 'node'}:${e.target_id ?? ''}`,
139
+ type: e.synapse_type ?? 'related',
140
+ w: e.weight ?? 0.5,
141
+ }));
142
+ html = html.replace('{{GRAPH_EDGES}}', JSON.stringify(graphEdges));
143
+ // Write output
144
+ const outputPath = opts.output ?? path.join(process.env['TEMP'] ?? '/tmp', 'trading-brain-dashboard.html');
145
+ fs.writeFileSync(outputPath, html, 'utf-8');
146
+ console.log(`${icons.ok} ${c.success('Dashboard generated:')} ${c.dim(outputPath)}`);
147
+ console.log(header('Trading Brain Dashboard', icons.trade));
148
+ console.log(` Trades: ${c.value(s.trades?.total ?? 0)} | Win Rate: ${c.green(winRate + '%')} | Rules: ${c.value(s.rules?.total ?? 0)}`);
149
+ console.log(` Chains: ${c.value(s.chains?.total ?? 0)} | Insights: ${c.value(s.insights?.total ?? 0)} | Synapses: ${c.value(s.network?.synapses ?? 0)}`);
150
+ console.log(divider());
151
+ if (opts.open !== false) {
152
+ const { exec } = await import('node:child_process');
153
+ const cmd = process.platform === 'win32' ? 'start' : process.platform === 'darwin' ? 'open' : 'xdg-open';
154
+ exec(`${cmd} "${outputPath}"`);
155
+ }
156
+ });
157
+ });
158
+ }
159
+ //# sourceMappingURL=dashboard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashboard.js","sourceRoot":"","sources":["../../../src/cli/commands/dashboard.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { Command } from 'commander';
2
+ export declare function peersCommand(): Command;
@@ -0,0 +1,38 @@
1
+ import { Command } from 'commander';
2
+ import { CrossBrainClient } from '@timmeck/brain-core';
3
+ import { c, icons, header, keyValue, divider } from '../colors.js';
4
+ export function peersCommand() {
5
+ return new Command('peers')
6
+ .description('Show status of peer brains in the ecosystem')
7
+ .action(async () => {
8
+ console.log(header('Brain Ecosystem', icons.synapse));
9
+ const cross = new CrossBrainClient('trading-brain');
10
+ const peerNames = cross.getPeerNames();
11
+ console.log(` ${c.dim('Checking')} ${peerNames.length} ${c.dim('peers...')}\n`);
12
+ const available = await cross.getAvailablePeers();
13
+ const statuses = await cross.broadcast('status');
14
+ for (const name of peerNames) {
15
+ const isUp = available.includes(name);
16
+ const status = statuses.find(s => s.name === name);
17
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
18
+ const info = status?.result;
19
+ if (isUp && info) {
20
+ console.log(` ${icons.check} ${c.green.bold(name)} ${c.dim('— running')}`);
21
+ console.log(keyValue('Version', info.version ?? '?', 6));
22
+ console.log(keyValue('Uptime', `${info.uptime ?? 0}s`, 6));
23
+ console.log(keyValue('PID', info.pid ?? '?', 6));
24
+ console.log(keyValue('Methods', info.methods ?? '?', 6));
25
+ }
26
+ else if (isUp) {
27
+ console.log(` ${icons.check} ${c.green.bold(name)} ${c.dim('— running (no status)')}`);
28
+ }
29
+ else {
30
+ console.log(` ${icons.cross} ${c.dim(name)} ${c.red('— offline')}`);
31
+ }
32
+ console.log();
33
+ }
34
+ console.log(` ${c.label('Self:')} ${c.blue.bold('trading-brain')} ${c.dim('(this instance)')}`);
35
+ console.log(`\n${divider()}`);
36
+ });
37
+ }
38
+ //# sourceMappingURL=peers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"peers.js","sourceRoot":"","sources":["../../../src/cli/commands/peers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import type { AnalyticsService } from '../services/analytics.service.js';
2
+ import type { InsightService } from '../services/insight.service.js';
3
+ import type { RuleRepository } from '../db/repositories/rule.repository.js';
4
+ import type { ChainRepository } from '../db/repositories/chain.repository.js';
5
+ import type { CalibrationRepository } from '../db/repositories/calibration.repository.js';
6
+ import type { SynapseManager } from '../synapses/synapse-manager.js';
7
+ import type { TradeRepository } from '../db/repositories/trade.repository.js';
8
+ export interface DashboardServices {
9
+ analytics: AnalyticsService;
10
+ insight: InsightService;
11
+ ruleRepo: RuleRepository;
12
+ chainRepo: ChainRepository;
13
+ calRepo: CalibrationRepository;
14
+ synapseManager: SynapseManager;
15
+ tradeRepo: TradeRepository;
16
+ }
17
+ export declare function renderDashboard(template: string, services: DashboardServices): string;