@timmeck/brain-core 1.0.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 (60) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +144 -0
  3. package/dist/api/server.d.ts +29 -0
  4. package/dist/api/server.js +183 -0
  5. package/dist/api/server.js.map +1 -0
  6. package/dist/cli/colors.d.ts +47 -0
  7. package/dist/cli/colors.js +93 -0
  8. package/dist/cli/colors.js.map +1 -0
  9. package/dist/db/connection.d.ts +2 -0
  10. package/dist/db/connection.js +19 -0
  11. package/dist/db/connection.js.map +1 -0
  12. package/dist/index.d.ts +18 -0
  13. package/dist/index.js +19 -0
  14. package/dist/index.js.map +1 -0
  15. package/dist/ipc/client.d.ts +16 -0
  16. package/dist/ipc/client.js +100 -0
  17. package/dist/ipc/client.js.map +1 -0
  18. package/dist/ipc/protocol.d.ts +8 -0
  19. package/dist/ipc/protocol.js +29 -0
  20. package/dist/ipc/protocol.js.map +1 -0
  21. package/dist/ipc/server.d.ts +22 -0
  22. package/dist/ipc/server.js +156 -0
  23. package/dist/ipc/server.js.map +1 -0
  24. package/dist/mcp/http-server.d.ts +23 -0
  25. package/dist/mcp/http-server.js +126 -0
  26. package/dist/mcp/http-server.js.map +1 -0
  27. package/dist/mcp/server.d.ts +15 -0
  28. package/dist/mcp/server.js +66 -0
  29. package/dist/mcp/server.js.map +1 -0
  30. package/dist/types/ipc.types.d.ts +11 -0
  31. package/dist/types/ipc.types.js +2 -0
  32. package/dist/types/ipc.types.js.map +1 -0
  33. package/dist/utils/events.d.ts +18 -0
  34. package/dist/utils/events.js +27 -0
  35. package/dist/utils/events.js.map +1 -0
  36. package/dist/utils/hash.d.ts +1 -0
  37. package/dist/utils/hash.js +5 -0
  38. package/dist/utils/hash.js.map +1 -0
  39. package/dist/utils/logger.d.ts +16 -0
  40. package/dist/utils/logger.js +43 -0
  41. package/dist/utils/logger.js.map +1 -0
  42. package/dist/utils/paths.d.ts +8 -0
  43. package/dist/utils/paths.js +23 -0
  44. package/dist/utils/paths.js.map +1 -0
  45. package/package.json +59 -0
  46. package/src/api/server.ts +210 -0
  47. package/src/cli/colors.ts +105 -0
  48. package/src/db/connection.ts +22 -0
  49. package/src/index.ts +31 -0
  50. package/src/ipc/client.ts +117 -0
  51. package/src/ipc/protocol.ts +35 -0
  52. package/src/ipc/server.ts +170 -0
  53. package/src/mcp/http-server.ts +148 -0
  54. package/src/mcp/server.ts +84 -0
  55. package/src/types/ipc.types.ts +8 -0
  56. package/src/utils/events.ts +30 -0
  57. package/src/utils/hash.ts +5 -0
  58. package/src/utils/logger.ts +67 -0
  59. package/src/utils/paths.ts +24 -0
  60. package/tsconfig.json +18 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Tim Mecklenburg
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,144 @@
1
+ # Brain Core
2
+
3
+ [![npm version](https://img.shields.io/npm/v/@timmeck/brain-core)](https://www.npmjs.com/package/@timmeck/brain-core)
4
+ [![npm downloads](https://img.shields.io/npm/dm/@timmeck/brain-core)](https://www.npmjs.com/package/@timmeck/brain-core)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
6
+ [![GitHub stars](https://img.shields.io/github/stars/timmeck/brain-core)](https://github.com/timmeck/brain-core)
7
+
8
+ **Shared infrastructure for the Brain ecosystem — IPC, MCP, CLI, DB, and utilities.**
9
+
10
+ Brain Core extracts the common infrastructure used across all Brain MCP servers ([Brain](https://github.com/timmeck/brain), [Trading Brain](https://github.com/timmeck/trading-brain), [Marketing Brain](https://github.com/timmeck/marketing-brain)) into a single, reusable package.
11
+
12
+ ## What's Included
13
+
14
+ | Module | Description |
15
+ |--------|-------------|
16
+ | **IPC Protocol** | Length-prefixed JSON frames over named pipes (Windows) / Unix sockets |
17
+ | **IPC Server** | Named pipe server with auto-recovery of stale pipes |
18
+ | **IPC Client** | Client with request/response, timeouts, and notification support |
19
+ | **MCP Server** | Stdio transport for Claude Code with auto-daemon-start |
20
+ | **MCP HTTP Server** | SSE transport for Cursor, Windsurf, Cline, Continue |
21
+ | **REST API Server** | Base HTTP server with CORS, auth, SSE events, batch RPC |
22
+ | **DB Connection** | SQLite (better-sqlite3) with WAL mode, foreign keys, caching |
23
+ | **CLI Colors** | Shared color palette, formatting helpers (header, table, badges) |
24
+ | **Logger** | Winston-based structured logging with file rotation |
25
+ | **Event Bus** | Generic typed event emitter |
26
+ | **Utils** | Path normalization, data dir resolution, SHA-256 hashing |
27
+
28
+ ## Installation
29
+
30
+ ```bash
31
+ npm install @timmeck/brain-core
32
+ ```
33
+
34
+ ## Usage
35
+
36
+ ### Building a new Brain
37
+
38
+ ```typescript
39
+ import {
40
+ createLogger,
41
+ getDataDir,
42
+ getPipeName,
43
+ createConnection,
44
+ IpcServer,
45
+ IpcClient,
46
+ startMcpServer,
47
+ McpHttpServer,
48
+ BaseApiServer,
49
+ TypedEventBus,
50
+ c, header, keyValue,
51
+ } from '@timmeck/brain-core';
52
+
53
+ // 1. Configure for your brain
54
+ const dataDir = getDataDir('MY_BRAIN_DATA_DIR', '.my-brain');
55
+ createLogger({ envVar: 'MY_BRAIN_LOG_LEVEL', dataDir, defaultFilename: 'my-brain.log' });
56
+
57
+ // 2. Database
58
+ const db = createConnection(`${dataDir}/my-brain.db`);
59
+
60
+ // 3. Typed events
61
+ interface MyBrainEvents {
62
+ 'item:created': { itemId: number };
63
+ 'item:updated': { itemId: number };
64
+ }
65
+ const bus = new TypedEventBus<MyBrainEvents>();
66
+ bus.on('item:created', ({ itemId }) => console.log(`Item ${itemId} created`));
67
+
68
+ // 4. IPC Server
69
+ const router = new MyRouter(services); // implements IpcRouter interface
70
+ const ipcServer = new IpcServer(router, getPipeName('my-brain'), 'my-brain');
71
+ ipcServer.start();
72
+
73
+ // 5. REST API (extend BaseApiServer for custom routes)
74
+ class MyApiServer extends BaseApiServer {
75
+ protected buildRoutes() {
76
+ return [
77
+ { method: 'GET', pattern: /^\/api\/v1\/items$/, ipcMethod: 'item.list',
78
+ extractParams: () => ({}) },
79
+ ];
80
+ }
81
+ }
82
+
83
+ // 6. MCP Server (stdio)
84
+ await startMcpServer({
85
+ name: 'my-brain',
86
+ version: '1.0.0',
87
+ entryPoint: import.meta.filename,
88
+ registerTools: (server, ipc) => { /* register MCP tools */ },
89
+ });
90
+
91
+ // 7. CLI output
92
+ console.log(header('My Brain Status'));
93
+ console.log(keyValue('Items', 42));
94
+ console.log(c.success('All systems operational'));
95
+ ```
96
+
97
+ ### IPC Router Interface
98
+
99
+ Your brain must implement the `IpcRouter` interface:
100
+
101
+ ```typescript
102
+ import type { IpcRouter } from '@timmeck/brain-core';
103
+
104
+ class MyRouter implements IpcRouter {
105
+ handle(method: string, params: unknown): unknown {
106
+ switch (method) {
107
+ case 'item.list': return this.itemService.list();
108
+ case 'item.get': return this.itemService.get(params);
109
+ default: throw new Error(`Unknown method: ${method}`);
110
+ }
111
+ }
112
+
113
+ listMethods(): string[] {
114
+ return ['item.list', 'item.get'];
115
+ }
116
+ }
117
+ ```
118
+
119
+ ## Architecture
120
+
121
+ ```
122
+ @timmeck/brain-core
123
+ ├── Types ─── IpcMessage
124
+ ├── Utils ─── hash, logger, paths, events
125
+ ├── DB ────── SQLite connection (WAL mode)
126
+ ├── IPC ───── protocol, server, client
127
+ ├── MCP ───── stdio server, HTTP/SSE server
128
+ ├── CLI ───── colors, formatting helpers
129
+ └── API ───── BaseApiServer (CORS, auth, RPC, SSE)
130
+ ```
131
+
132
+ ## Brain Ecosystem
133
+
134
+ | Brain | Purpose | Ports |
135
+ |-------|---------|-------|
136
+ | [Brain](https://github.com/timmeck/brain) | Error memory & code intelligence | 7777/7778 |
137
+ | [Trading Brain](https://github.com/timmeck/trading-brain) | Adaptive trading intelligence | 7779/7780 |
138
+ | [Marketing Brain](https://github.com/timmeck/marketing-brain) | Content strategy & social media | 7781/7782 |
139
+
140
+ All three brains are standalone — brain-core is an **optional** shared dependency that eliminates code duplication.
141
+
142
+ ## License
143
+
144
+ [MIT](LICENSE)
@@ -0,0 +1,29 @@
1
+ import http from 'node:http';
2
+ import type { IpcRouter } from '../ipc/server.js';
3
+ export interface ApiServerOptions {
4
+ port: number;
5
+ router: IpcRouter;
6
+ apiKey?: string;
7
+ }
8
+ export interface RouteDefinition {
9
+ method: string;
10
+ pattern: RegExp;
11
+ ipcMethod: string;
12
+ extractParams: (match: RegExpMatchArray, query: URLSearchParams, body?: unknown) => unknown;
13
+ }
14
+ export declare class BaseApiServer {
15
+ protected options: ApiServerOptions;
16
+ private server;
17
+ protected logger: import("winston").Logger;
18
+ private routes;
19
+ protected sseClients: Set<http.ServerResponse>;
20
+ constructor(options: ApiServerOptions);
21
+ start(): void;
22
+ stop(): void;
23
+ /** Override to add domain-specific RESTful routes */
24
+ protected buildRoutes(): RouteDefinition[];
25
+ private handleRequest;
26
+ protected json(res: http.ServerResponse, status: number, data: unknown): void;
27
+ protected readBody(req: http.IncomingMessage): Promise<string>;
28
+ protected broadcastSSE(data: unknown): void;
29
+ }
@@ -0,0 +1,183 @@
1
+ import http from 'node:http';
2
+ import { getLogger } from '../utils/logger.js';
3
+ export class BaseApiServer {
4
+ options;
5
+ server = null;
6
+ logger = getLogger();
7
+ routes;
8
+ sseClients = new Set();
9
+ constructor(options) {
10
+ this.options = options;
11
+ this.routes = this.buildRoutes();
12
+ }
13
+ 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'] ??
26
+ req.headers.authorization?.replace('Bearer ', '');
27
+ if (provided !== apiKey) {
28
+ this.json(res, 401, { error: 'Unauthorized', message: 'Invalid or missing API key' });
29
+ return;
30
+ }
31
+ }
32
+ this.handleRequest(req, res).catch((err) => {
33
+ this.logger.error('API error:', err);
34
+ this.json(res, 500, {
35
+ error: 'Internal Server Error',
36
+ message: err instanceof Error ? err.message : String(err),
37
+ });
38
+ });
39
+ });
40
+ this.server.listen(port, () => {
41
+ this.logger.info(`REST API server started on http://localhost:${port}`);
42
+ });
43
+ }
44
+ stop() {
45
+ for (const client of this.sseClients) {
46
+ try {
47
+ client.end();
48
+ }
49
+ catch { /* ignore */ }
50
+ }
51
+ this.sseClients.clear();
52
+ this.server?.close();
53
+ this.server = null;
54
+ this.logger.info('REST API server stopped');
55
+ }
56
+ /** Override to add domain-specific RESTful routes */
57
+ buildRoutes() {
58
+ return [];
59
+ }
60
+ async handleRequest(req, res) {
61
+ const url = new URL(req.url ?? '/', 'http://localhost');
62
+ const pathname = url.pathname;
63
+ const method = req.method ?? 'GET';
64
+ const query = url.searchParams;
65
+ // Health check
66
+ if (pathname === '/api/v1/health') {
67
+ this.json(res, 200, { status: 'ok', timestamp: new Date().toISOString() });
68
+ return;
69
+ }
70
+ // SSE event stream
71
+ if (pathname === '/api/v1/events' && method === 'GET') {
72
+ res.writeHead(200, {
73
+ 'Content-Type': 'text/event-stream',
74
+ 'Cache-Control': 'no-cache',
75
+ 'Connection': 'keep-alive',
76
+ });
77
+ res.write('data: {"type":"connected"}\n\n');
78
+ this.sseClients.add(res);
79
+ req.on('close', () => this.sseClients.delete(res));
80
+ return;
81
+ }
82
+ // List all available methods
83
+ if (pathname === '/api/v1/methods' && method === 'GET') {
84
+ const methods = this.options.router.listMethods();
85
+ this.json(res, 200, {
86
+ methods,
87
+ rpcEndpoint: '/api/v1/rpc',
88
+ usage: 'POST /api/v1/rpc with body { "method": "<method>", "params": {...} }',
89
+ });
90
+ return;
91
+ }
92
+ // Generic RPC endpoint
93
+ if (pathname === '/api/v1/rpc' && method === 'POST') {
94
+ const body = await this.readBody(req);
95
+ if (!body) {
96
+ this.json(res, 400, { error: 'Bad Request', message: 'Empty request body' });
97
+ return;
98
+ }
99
+ const parsed = JSON.parse(body);
100
+ // Batch RPC support
101
+ if (Array.isArray(parsed)) {
102
+ const results = parsed.map((call) => {
103
+ try {
104
+ const result = this.options.router.handle(call.method, call.params ?? {});
105
+ return { id: call.id, result };
106
+ }
107
+ catch (err) {
108
+ return { id: call.id, error: err instanceof Error ? err.message : String(err) };
109
+ }
110
+ });
111
+ this.json(res, 200, results);
112
+ return;
113
+ }
114
+ if (!parsed.method) {
115
+ this.json(res, 400, { error: 'Bad Request', message: 'Missing "method" field' });
116
+ return;
117
+ }
118
+ try {
119
+ const result = this.options.router.handle(parsed.method, parsed.params ?? {});
120
+ this.json(res, 200, { result });
121
+ }
122
+ catch (err) {
123
+ this.json(res, 400, { error: err instanceof Error ? err.message : String(err) });
124
+ }
125
+ return;
126
+ }
127
+ // RESTful routes
128
+ let body = undefined;
129
+ if (method === 'POST' || method === 'PUT') {
130
+ try {
131
+ const raw = await this.readBody(req);
132
+ body = raw ? JSON.parse(raw) : {};
133
+ }
134
+ catch {
135
+ this.json(res, 400, { error: 'Bad Request', message: 'Invalid JSON body' });
136
+ return;
137
+ }
138
+ }
139
+ for (const route of this.routes) {
140
+ if (route.method !== method)
141
+ continue;
142
+ const match = pathname.match(route.pattern);
143
+ if (!match)
144
+ continue;
145
+ try {
146
+ const params = route.extractParams(match, query, body);
147
+ const result = this.options.router.handle(route.ipcMethod, params);
148
+ this.json(res, method === 'POST' ? 201 : 200, { result });
149
+ }
150
+ catch (err) {
151
+ const msg = err instanceof Error ? err.message : String(err);
152
+ const status = msg.startsWith('Unknown method') ? 404 : 400;
153
+ this.json(res, status, { error: msg });
154
+ }
155
+ return;
156
+ }
157
+ this.json(res, 404, { error: 'Not Found', message: `No route for ${method} ${pathname}` });
158
+ }
159
+ json(res, status, data) {
160
+ res.writeHead(status, { 'Content-Type': 'application/json' });
161
+ res.end(JSON.stringify(data));
162
+ }
163
+ readBody(req) {
164
+ return new Promise((resolve, reject) => {
165
+ const chunks = [];
166
+ req.on('data', (chunk) => chunks.push(chunk));
167
+ req.on('end', () => resolve(Buffer.concat(chunks).toString('utf8')));
168
+ req.on('error', reject);
169
+ });
170
+ }
171
+ broadcastSSE(data) {
172
+ const msg = `data: ${JSON.stringify(data)}\n\n`;
173
+ for (const client of this.sseClients) {
174
+ try {
175
+ client.write(msg);
176
+ }
177
+ catch {
178
+ this.sseClients.delete(client);
179
+ }
180
+ }
181
+ }
182
+ }
183
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/api/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
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
+ };
18
+ export declare const baseIcons: {
19
+ check: string;
20
+ cross: string;
21
+ arrow: string;
22
+ dot: string;
23
+ circle: string;
24
+ bar: string;
25
+ barLight: string;
26
+ dash: string;
27
+ pipe: string;
28
+ corner: string;
29
+ tee: string;
30
+ star: string;
31
+ bolt: string;
32
+ gear: string;
33
+ chart: string;
34
+ synapse: string;
35
+ insight: string;
36
+ warn: string;
37
+ error: string;
38
+ ok: string;
39
+ clock: string;
40
+ };
41
+ export declare function header(title: string, icon?: string): string;
42
+ export declare function keyValue(key: string, value: string | number, indent?: number): string;
43
+ export declare function statusBadge(status: string): string;
44
+ export declare function progressBar(current: number, total: number, width?: number): string;
45
+ export declare function divider(width?: number): string;
46
+ export declare function table(rows: string[][], colWidths?: number[]): string;
47
+ export declare function stripAnsi(str: string): string;
@@ -0,0 +1,93 @@
1
+ import chalk from 'chalk';
2
+ // Shared brand color palette — identical across all brains
3
+ export const c = {
4
+ // Primary palette
5
+ blue: chalk.hex('#5b9cff'),
6
+ purple: chalk.hex('#b47aff'),
7
+ cyan: chalk.hex('#47e5ff'),
8
+ green: chalk.hex('#3dffa0'),
9
+ red: chalk.hex('#ff5577'),
10
+ orange: chalk.hex('#ffb347'),
11
+ dim: chalk.hex('#8b8fb0'),
12
+ dimmer: chalk.hex('#4a4d6e'),
13
+ // Semantic
14
+ label: chalk.hex('#8b8fb0'),
15
+ value: chalk.white.bold,
16
+ heading: chalk.hex('#5b9cff').bold,
17
+ success: chalk.hex('#3dffa0').bold,
18
+ error: chalk.hex('#ff5577').bold,
19
+ warn: chalk.hex('#ffb347').bold,
20
+ info: chalk.hex('#47e5ff'),
21
+ };
22
+ // Shared base icons — each brain extends with domain-specific icons
23
+ export const baseIcons = {
24
+ check: '\u2713',
25
+ cross: '\u2717',
26
+ arrow: '\u2192',
27
+ dot: '\u25CF',
28
+ circle: '\u25CB',
29
+ bar: '\u2588',
30
+ barLight: '\u2591',
31
+ dash: '\u2500',
32
+ pipe: '\u2502',
33
+ corner: '\u2514',
34
+ tee: '\u251C',
35
+ star: '\u2605',
36
+ bolt: '\u26A1',
37
+ gear: '\u2699',
38
+ chart: '\uD83D\uDCCA',
39
+ synapse: '\uD83D\uDD17',
40
+ insight: '\uD83D\uDCA1',
41
+ warn: '\u26A0',
42
+ error: '\u274C',
43
+ ok: '\u2705',
44
+ clock: '\u23F1',
45
+ };
46
+ export function header(title, icon) {
47
+ const prefix = icon ? `${icon} ` : '';
48
+ const line = c.dimmer(baseIcons.dash.repeat(40));
49
+ return `\n${line}\n${prefix}${c.heading(title)}\n${line}`;
50
+ }
51
+ export function keyValue(key, value, indent = 2) {
52
+ const pad = ' '.repeat(indent);
53
+ return `${pad}${c.label(key + ':')} ${c.value(String(value))}`;
54
+ }
55
+ export function statusBadge(status) {
56
+ switch (status.toLowerCase()) {
57
+ case 'resolved':
58
+ case 'active':
59
+ case 'running':
60
+ return c.green(`[${status.toUpperCase()}]`);
61
+ case 'open':
62
+ case 'unresolved':
63
+ return c.red(`[${status.toUpperCase()}]`);
64
+ case 'warning':
65
+ return c.warn(`[${status.toUpperCase()}]`);
66
+ default:
67
+ return c.dim(`[${status.toUpperCase()}]`);
68
+ }
69
+ }
70
+ export function progressBar(current, total, width = 20) {
71
+ const pct = Math.min(1, current / Math.max(1, total));
72
+ const filled = Math.round(pct * width);
73
+ const empty = width - filled;
74
+ return c.cyan(baseIcons.bar.repeat(filled)) + c.dimmer(baseIcons.barLight.repeat(empty));
75
+ }
76
+ export function divider(width = 40) {
77
+ return c.dimmer(baseIcons.dash.repeat(width));
78
+ }
79
+ export function table(rows, colWidths) {
80
+ if (rows.length === 0)
81
+ return '';
82
+ const widths = colWidths ?? rows[0].map((_, i) => Math.max(...rows.map(r => stripAnsi(r[i] ?? '').length)));
83
+ return rows.map(row => row.map((cell, i) => {
84
+ const stripped = stripAnsi(cell);
85
+ const pad = Math.max(0, (widths[i] ?? stripped.length) - stripped.length);
86
+ return cell + ' '.repeat(pad);
87
+ }).join(' ')).join('\n');
88
+ }
89
+ export function stripAnsi(str) {
90
+ // eslint-disable-next-line no-control-regex
91
+ return str.replace(/\x1b\[[0-9;]*m/g, '');
92
+ }
93
+ //# sourceMappingURL=colors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"colors.js","sourceRoot":"","sources":["../../src/cli/colors.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import Database from 'better-sqlite3';
2
+ export declare function createConnection(dbPath: string): Database.Database;
@@ -0,0 +1,19 @@
1
+ import Database from 'better-sqlite3';
2
+ import fs from 'node:fs';
3
+ import path from 'node:path';
4
+ import { getLogger } from '../utils/logger.js';
5
+ export function createConnection(dbPath) {
6
+ const logger = getLogger();
7
+ const dir = path.dirname(dbPath);
8
+ if (!fs.existsSync(dir)) {
9
+ fs.mkdirSync(dir, { recursive: true });
10
+ }
11
+ logger.info(`Opening database at ${dbPath}`);
12
+ const db = new Database(dbPath);
13
+ db.pragma('journal_mode = WAL');
14
+ db.pragma('synchronous = NORMAL');
15
+ db.pragma('cache_size = 10000');
16
+ db.pragma('foreign_keys = ON');
17
+ return db;
18
+ }
19
+ //# sourceMappingURL=connection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection.js","sourceRoot":"","sources":["../../src/db/connection.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AACtC,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE/C,MAAM,UAAU,gBAAgB,CAAC,MAAc;IAC7C,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACjC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACxB,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACzC,CAAC;IAED,MAAM,CAAC,IAAI,CAAC,uBAAuB,MAAM,EAAE,CAAC,CAAC;IAC7C,MAAM,EAAE,GAAG,IAAI,QAAQ,CAAC,MAAM,CAAC,CAAC;IAEhC,EAAE,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;IAChC,EAAE,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC;IAClC,EAAE,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;IAChC,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC;IAE/B,OAAO,EAAE,CAAC;AACZ,CAAC"}
@@ -0,0 +1,18 @@
1
+ export type { IpcMessage } from './types/ipc.types.js';
2
+ export { sha256 } from './utils/hash.js';
3
+ export { createLogger, getLogger, resetLogger } from './utils/logger.js';
4
+ export type { LoggerOptions } from './utils/logger.js';
5
+ export { normalizePath, getDataDir, getPipeName } from './utils/paths.js';
6
+ export { TypedEventBus } from './utils/events.js';
7
+ export { createConnection } from './db/connection.js';
8
+ export { encodeMessage, MessageDecoder } from './ipc/protocol.js';
9
+ export { IpcServer } from './ipc/server.js';
10
+ export type { IpcRouter } from './ipc/server.js';
11
+ export { IpcClient } from './ipc/client.js';
12
+ export { startMcpServer } from './mcp/server.js';
13
+ export type { McpServerOptions } from './mcp/server.js';
14
+ export { McpHttpServer } from './mcp/http-server.js';
15
+ export type { McpHttpServerOptions } from './mcp/http-server.js';
16
+ export { c, baseIcons, header, keyValue, statusBadge, progressBar, divider, table, stripAnsi } from './cli/colors.js';
17
+ export { BaseApiServer } from './api/server.js';
18
+ export type { ApiServerOptions, RouteDefinition } from './api/server.js';
package/dist/index.js ADDED
@@ -0,0 +1,19 @@
1
+ // ── Utils ──────────────────────────────────────────────────
2
+ export { sha256 } from './utils/hash.js';
3
+ export { createLogger, getLogger, resetLogger } from './utils/logger.js';
4
+ export { normalizePath, getDataDir, getPipeName } from './utils/paths.js';
5
+ export { TypedEventBus } from './utils/events.js';
6
+ // ── DB ─────────────────────────────────────────────────────
7
+ export { createConnection } from './db/connection.js';
8
+ // ── IPC ────────────────────────────────────────────────────
9
+ export { encodeMessage, MessageDecoder } from './ipc/protocol.js';
10
+ export { IpcServer } from './ipc/server.js';
11
+ export { IpcClient } from './ipc/client.js';
12
+ // ── MCP ────────────────────────────────────────────────────
13
+ export { startMcpServer } from './mcp/server.js';
14
+ export { McpHttpServer } from './mcp/http-server.js';
15
+ // ── CLI ────────────────────────────────────────────────────
16
+ export { c, baseIcons, header, keyValue, statusBadge, progressBar, divider, table, stripAnsi } from './cli/colors.js';
17
+ // ── API ────────────────────────────────────────────────────
18
+ export { BaseApiServer } from './api/server.js';
19
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,8DAA8D;AAC9D,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEzE,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC1E,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAElD,8DAA8D;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD,8DAA8D;AAC9D,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAClE,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,8DAA8D;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEjD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAGrD,8DAA8D;AAC9D,OAAO,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,WAAW,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEtH,8DAA8D;AAC9D,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,16 @@
1
+ import type { IpcMessage } from '../types/ipc.types.js';
2
+ export declare class IpcClient {
3
+ private pipeName;
4
+ private timeout;
5
+ private socket;
6
+ private decoder;
7
+ private pending;
8
+ private onNotification?;
9
+ constructor(pipeName?: string, timeout?: number);
10
+ connect(): Promise<void>;
11
+ request(method: string, params?: unknown): Promise<unknown>;
12
+ setNotificationHandler(handler: (msg: IpcMessage) => void): void;
13
+ disconnect(): void;
14
+ get connected(): boolean;
15
+ private handleMessage;
16
+ }