@timmeck/trading-brain 1.2.2 → 1.3.1

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 (42) hide show
  1. package/README.md +24 -4
  2. package/dist/cli/commands/setup.d.ts +2 -0
  3. package/dist/cli/commands/setup.js +197 -0
  4. package/dist/cli/commands/setup.js.map +1 -0
  5. package/dist/cli/commands/status.js +9 -0
  6. package/dist/cli/commands/status.js.map +1 -1
  7. package/dist/db/migrations/005_memory_schema.d.ts +2 -0
  8. package/dist/db/migrations/005_memory_schema.js +44 -0
  9. package/dist/db/migrations/005_memory_schema.js.map +1 -0
  10. package/dist/db/migrations/006_memory_fts.d.ts +2 -0
  11. package/dist/db/migrations/006_memory_fts.js +54 -0
  12. package/dist/db/migrations/006_memory_fts.js.map +1 -0
  13. package/dist/db/migrations/index.js +4 -0
  14. package/dist/db/migrations/index.js.map +1 -1
  15. package/dist/db/repositories/memory.repository.d.ts +26 -0
  16. package/dist/db/repositories/memory.repository.js +124 -0
  17. package/dist/db/repositories/memory.repository.js.map +1 -0
  18. package/dist/db/repositories/session.repository.d.ts +18 -0
  19. package/dist/db/repositories/session.repository.js +80 -0
  20. package/dist/db/repositories/session.repository.js.map +1 -0
  21. package/dist/index.js +2 -0
  22. package/dist/index.js.map +1 -1
  23. package/dist/ipc/router.d.ts +2 -0
  24. package/dist/ipc/router.js +13 -1
  25. package/dist/ipc/router.js.map +1 -1
  26. package/dist/mcp/tools.js +69 -0
  27. package/dist/mcp/tools.js.map +1 -1
  28. package/dist/services/analytics.service.d.ts +5 -1
  29. package/dist/services/analytics.service.js +10 -1
  30. package/dist/services/analytics.service.js.map +1 -1
  31. package/dist/services/memory.service.d.ts +33 -0
  32. package/dist/services/memory.service.js +134 -0
  33. package/dist/services/memory.service.js.map +1 -0
  34. package/dist/trading-core.js +8 -1
  35. package/dist/trading-core.js.map +1 -1
  36. package/dist/types/memory.types.d.ts +1 -0
  37. package/dist/types/memory.types.js +2 -0
  38. package/dist/types/memory.types.js.map +1 -0
  39. package/dist/utils/events.d.ts +15 -0
  40. package/dist/utils/events.js.map +1 -1
  41. package/package.json +2 -2
  42. package/smithery.yaml +0 -10
package/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  [![npm version](https://img.shields.io/npm/v/@timmeck/trading-brain)](https://www.npmjs.com/package/@timmeck/trading-brain)
4
4
  [![npm downloads](https://img.shields.io/npm/dm/@timmeck/trading-brain)](https://www.npmjs.com/package/@timmeck/trading-brain)
5
5
  [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
6
- [![GitHub stars](https://img.shields.io/github/stars/timmeck/trading-brain)](https://github.com/timmeck/trading-brain)
6
+ [![GitHub stars](https://img.shields.io/github/stars/timmeck/trading-brain?style=social)](https://github.com/timmeck/trading-brain)
7
7
 
8
8
  **Adaptive Trading Intelligence & Signal Learning System for Claude Code**
9
9
 
@@ -45,6 +45,14 @@ Without Trading Brain, every trading decision starts from zero. With Trading Bra
45
45
  - **Performance Analysis** — Ranks pairs and strategies by statistical confidence
46
46
  - **Regime Shift Detection** — Alerts when a pair's recent performance deviates from its baseline
47
47
 
48
+ ### Never Forget — Memory & Sessions
49
+ - **Persistent Memory** — Store preferences, decisions, context, facts, goals, and lessons learned
50
+ - **Key-Based Upsert** — Update existing memories by unique key, auto-superseding old values
51
+ - **Full-Text Search** — Natural language recall with FTS5-powered search
52
+ - **Session Tracking** — Track conversation goals, summaries, and outcomes
53
+ - **Importance Scoring** — 1–10 importance scale with category-based organization
54
+ - **Soft Deletes** — Deactivate memories without losing history
55
+
48
56
  ### Strategy Recommendations
49
57
  - **DCA Multiplier** — Brain-recommended multiplier (0.3x–2.5x) based on regime and RSI context
50
58
  - **Grid Parameters** — Volatility-aware grid spacing with historical performance adjustment
@@ -208,6 +216,11 @@ These tools are available to Claude Code (and other MCP clients) when Trading Br
208
216
  | `trading_reset` | Reset all data (use with caution) |
209
217
  | `trading_ecosystem_status` | Get status of all brains in the ecosystem |
210
218
  | `trading_query_peer` | Query another brain in the ecosystem (method + params) |
219
+ | `trading_remember` | Store a memory (preference, decision, context, fact, goal, lesson) |
220
+ | `trading_recall` | Search memories by natural language query |
221
+ | `trading_session_start` | Start a session with optional goals |
222
+ | `trading_session_end` | End a session with summary and outcome |
223
+ | `trading_session_history` | List past sessions with summaries |
211
224
  | `trading_error_context` | Query Brain for errors that correlate with trade failures |
212
225
 
213
226
  ## REST API
@@ -317,10 +330,10 @@ Trading Brain is part of the **Brain Ecosystem** — a family of standalone MCP
317
330
 
318
331
  | Brain | Purpose | Ports |
319
332
  |-------|---------|-------|
320
- | [Brain](https://github.com/timmeck/brain) | Error memory & code intelligence | 7777 / 7778 |
321
- | **Trading Brain** | Adaptive trading intelligence | **7779** / 7780 |
333
+ | [Brain](https://github.com/timmeck/brain) v2.2.0 | Error memory, code intelligence & persistent context | 7777 / 7778 |
334
+ | **Trading Brain** v1.3.0 | Adaptive trading intelligence with memory & sessions | **7779** / 7780 |
322
335
  | [Marketing Brain](https://github.com/timmeck/marketing-brain) | Content strategy & engagement | 7781 / 7782 |
323
- | [Brain Core](https://github.com/timmeck/brain-core) v1.5.0 | Shared infrastructure (IPC, MCP, REST, CLI, math, synapses) | — |
336
+ | [Brain Core](https://github.com/timmeck/brain-core) v1.6.0 | Shared infrastructure (IPC, MCP, REST, CLI, math, synapses, memory) | — |
324
337
  | [Brain Hub](https://timmeck.github.io/brain-hub/) | Ecosystem landing page | — |
325
338
 
326
339
  Each brain is **fully standalone** — [Brain Core](https://www.npmjs.com/package/@timmeck/brain-core) provides shared infrastructure (IPC, MCP, REST API, CLI, math, synapse algorithms) used by all brains, eliminating ~2,800 lines of duplicated code.
@@ -333,6 +346,13 @@ Brains discover and query each other at runtime via IPC named pipes. Use `tradin
333
346
 
334
347
  The interactive HTML dashboard (`trading dashboard`) includes an Ecosystem Peers section showing the live status of all connected brains.
335
348
 
349
+ ## Support
350
+
351
+ If Trading Brain helps you, consider giving it a star — it helps others discover the project and keeps development going.
352
+
353
+ [![Star this repo](https://img.shields.io/github/stars/timmeck/trading-brain?style=social)](https://github.com/timmeck/trading-brain)
354
+ [![Sponsor](https://img.shields.io/badge/Sponsor-Support%20Development-ea4aaa)](https://github.com/sponsors/timmeck)
355
+
336
356
  ## License
337
357
 
338
358
  [MIT](LICENSE)
@@ -0,0 +1,2 @@
1
+ import { Command } from 'commander';
2
+ export declare function setupCommand(): Command;
@@ -0,0 +1,197 @@
1
+ import { Command } from 'commander';
2
+ import fs from 'node:fs';
3
+ import path from 'node:path';
4
+ import os from 'node:os';
5
+ import { getDataDir } from '../../utils/paths.js';
6
+ import { c, icons, header, divider } from '../colors.js';
7
+ function pass(label, detail) {
8
+ const extra = detail ? ` ${c.dim(detail)}` : '';
9
+ console.log(` ${c.green(icons.check)} ${label}${extra}`);
10
+ }
11
+ function fail(label, detail) {
12
+ const extra = detail ? ` ${c.dim(detail)}` : '';
13
+ console.log(` ${c.red(icons.cross)} ${label}${extra}`);
14
+ }
15
+ function skip(label, detail) {
16
+ const extra = detail ? ` ${c.dim(detail)}` : '';
17
+ console.log(` ${c.dim(icons.arrow)} ${label}${extra}`);
18
+ }
19
+ function step(n, label) {
20
+ console.log(`\n ${c.cyan(`[${n}/5]`)} ${c.value(label)}`);
21
+ }
22
+ function readSettings(settingsPath) {
23
+ try {
24
+ const raw = fs.readFileSync(settingsPath, 'utf8');
25
+ return JSON.parse(raw);
26
+ }
27
+ catch {
28
+ return {};
29
+ }
30
+ }
31
+ function ensureDir(dir) {
32
+ if (!fs.existsSync(dir)) {
33
+ fs.mkdirSync(dir, { recursive: true });
34
+ }
35
+ }
36
+ export function setupCommand() {
37
+ return new Command('setup')
38
+ .description('One-command setup: configures MCP and starts the daemon')
39
+ .option('--no-daemon', 'Skip starting the daemon')
40
+ .option('--dry-run', 'Show what would be done without making changes')
41
+ .action(async (opts) => {
42
+ console.log(header('Trading Brain Setup', icons.brain));
43
+ console.log();
44
+ console.log(` ${c.dim('Platform:')} ${c.value(process.platform)} ${c.dim('Node:')} ${c.value(process.version)} ${c.dim('Arch:')} ${c.value(process.arch)}`);
45
+ const settingsPath = path.join(os.homedir(), '.claude', 'settings.json');
46
+ const dataDir = getDataDir();
47
+ let settingsChanged = false;
48
+ let allGood = true;
49
+ // -- Step 1: Data Directory --
50
+ step(1, 'Data Directory');
51
+ if (fs.existsSync(dataDir)) {
52
+ pass('Data directory exists', dataDir);
53
+ }
54
+ else if (opts.dryRun) {
55
+ skip('Would create data directory', dataDir);
56
+ }
57
+ else {
58
+ ensureDir(dataDir);
59
+ pass('Created data directory', dataDir);
60
+ }
61
+ // -- Step 2: Claude Code settings.json --
62
+ step(2, 'MCP Server Configuration');
63
+ const claudeDir = path.join(os.homedir(), '.claude');
64
+ if (!opts.dryRun) {
65
+ ensureDir(claudeDir);
66
+ }
67
+ const settings = readSettings(settingsPath);
68
+ if (!settings.mcpServers) {
69
+ settings.mcpServers = {};
70
+ }
71
+ const mcpServers = settings.mcpServers;
72
+ if (mcpServers['trading-brain']) {
73
+ pass('MCP server already configured');
74
+ }
75
+ else if (opts.dryRun) {
76
+ skip('Would add MCP server entry', '"trading-brain" -> trading mcp-server');
77
+ }
78
+ else {
79
+ mcpServers['trading-brain'] = {
80
+ command: 'trading',
81
+ args: ['mcp-server'],
82
+ };
83
+ settingsChanged = true;
84
+ pass('Added MCP server entry', '"trading-brain" -> trading mcp-server');
85
+ }
86
+ // -- Step 3: Save Configuration --
87
+ step(3, 'Save Configuration');
88
+ if (settingsChanged && !opts.dryRun) {
89
+ try {
90
+ fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + '\n', 'utf8');
91
+ pass('Saved settings.json', settingsPath);
92
+ }
93
+ catch (err) {
94
+ fail('Failed to save settings.json', err instanceof Error ? err.message : String(err));
95
+ allGood = false;
96
+ }
97
+ }
98
+ else if (opts.dryRun && settingsChanged) {
99
+ skip('Would save settings.json', settingsPath);
100
+ }
101
+ else {
102
+ pass('No changes needed', 'settings.json already up to date');
103
+ }
104
+ // -- Step 4: Start Daemon --
105
+ step(4, 'Start Daemon');
106
+ if (opts.daemon === false) {
107
+ skip('Skipped daemon start', '--no-daemon');
108
+ }
109
+ else if (opts.dryRun) {
110
+ skip('Would start Trading Brain daemon');
111
+ }
112
+ else {
113
+ const pidPath = path.join(dataDir, 'trading-brain.pid');
114
+ let alreadyRunning = false;
115
+ if (fs.existsSync(pidPath)) {
116
+ const pid = parseInt(fs.readFileSync(pidPath, 'utf8').trim(), 10);
117
+ try {
118
+ process.kill(pid, 0);
119
+ alreadyRunning = true;
120
+ pass('Daemon already running', `PID ${pid}`);
121
+ }
122
+ catch {
123
+ fs.unlinkSync(pidPath);
124
+ }
125
+ }
126
+ if (!alreadyRunning) {
127
+ try {
128
+ const { spawn } = await import('node:child_process');
129
+ const entryPoint = path.resolve(import.meta.dirname, '../../index.js');
130
+ const child = spawn(process.execPath, [entryPoint, 'daemon'], {
131
+ detached: true,
132
+ stdio: 'ignore',
133
+ });
134
+ child.unref();
135
+ await new Promise((resolve) => setTimeout(resolve, 1500));
136
+ if (fs.existsSync(pidPath)) {
137
+ const pid = fs.readFileSync(pidPath, 'utf8').trim();
138
+ pass('Daemon started', `PID ${pid}`);
139
+ }
140
+ else {
141
+ pass('Daemon starting', 'may take a moment');
142
+ }
143
+ }
144
+ catch (err) {
145
+ fail('Failed to start daemon', err instanceof Error ? err.message : String(err));
146
+ allGood = false;
147
+ }
148
+ }
149
+ }
150
+ // -- Step 5: Health Check --
151
+ step(5, 'Health Check');
152
+ if (opts.dryRun) {
153
+ skip('Would run health checks');
154
+ }
155
+ else {
156
+ const dbPath = path.join(dataDir, 'trading-brain.db');
157
+ if (fs.existsSync(dbPath)) {
158
+ const stat = fs.statSync(dbPath);
159
+ pass('Database', `${(stat.size / 1024 / 1024).toFixed(1)} MB`);
160
+ }
161
+ else {
162
+ skip('Database', 'will be created on first daemon start');
163
+ }
164
+ const pidPath = path.join(dataDir, 'trading-brain.pid');
165
+ if (fs.existsSync(pidPath)) {
166
+ const pid = parseInt(fs.readFileSync(pidPath, 'utf8').trim(), 10);
167
+ try {
168
+ process.kill(pid, 0);
169
+ pass('Daemon reachable', `PID ${pid}`);
170
+ }
171
+ catch {
172
+ fail('Daemon not reachable');
173
+ allGood = false;
174
+ }
175
+ }
176
+ }
177
+ // -- Summary --
178
+ console.log();
179
+ if (opts.dryRun) {
180
+ console.log(` ${icons.brain} ${c.cyan('Dry run complete.')} No changes were made.`);
181
+ }
182
+ else if (allGood) {
183
+ console.log(` ${icons.ok} ${c.success('Trading Brain is ready!')} All systems configured.`);
184
+ console.log();
185
+ console.log(` ${c.dim('Next steps:')}`);
186
+ console.log(` ${c.dim('1.')} Restart Claude Code to load the MCP server`);
187
+ console.log(` ${c.dim('2.')} Run ${c.cyan('trading status')} to check stats`);
188
+ console.log(` ${c.dim('3.')} Run ${c.cyan('trading doctor')} for a full health check`);
189
+ }
190
+ else {
191
+ console.log(` ${icons.warn} ${c.warn('Setup completed with warnings.')} Check the items above.`);
192
+ console.log(` Run ${c.cyan('trading doctor')} for a detailed health check.`);
193
+ }
194
+ console.log(`\n${divider()}`);
195
+ });
196
+ }
197
+ //# sourceMappingURL=setup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.js","sourceRoot":"","sources":["../../../src/cli/commands/setup.ts"],"names":[],"mappings":"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"}
@@ -50,6 +50,15 @@ export function statusCommand() {
50
50
  console.log(` ${icons.insight} ${c.orange.bold('Research')}`);
51
51
  console.log(` ${c.label('Insights:')} ${c.value(summary.insights?.total ?? 0)}`);
52
52
  console.log(` ${c.label('Chains:')} ${c.value(summary.chains?.total ?? 0)}`);
53
+ console.log();
54
+ console.log(` ${icons.brain} ${c.purple.bold('Memory')}`);
55
+ console.log(` ${c.label('Memories:')} ${c.value(summary.memory?.active ?? 0)} active`);
56
+ console.log(` ${c.label('Sessions:')} ${c.value(summary.memory?.sessions ?? 0)}`);
57
+ const cats = summary.memory?.byCategory;
58
+ if (cats && Object.keys(cats).length > 0) {
59
+ const catStr = Object.entries(cats).map(([k, v]) => `${k}: ${v}`).join(', ');
60
+ console.log(` ${c.label('Categories:')} ${c.dim(catStr)}`);
61
+ }
53
62
  console.log(`\n${divider()}`);
54
63
  });
55
64
  });
@@ -1 +1 @@
1
- {"version":3,"file":"status.js","sourceRoot":"","sources":["../../../src/cli/commands/status.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../../src/cli/commands/status.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import type Database from 'better-sqlite3';
2
+ export declare function up(db: Database.Database): void;
@@ -0,0 +1,44 @@
1
+ export function up(db) {
2
+ db.exec(`
3
+ -- Sessions: Conversation lifecycle tracking
4
+ CREATE TABLE IF NOT EXISTS sessions (
5
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
6
+ session_id TEXT NOT NULL UNIQUE,
7
+ started_at TEXT NOT NULL DEFAULT (datetime('now')),
8
+ ended_at TEXT,
9
+ summary TEXT,
10
+ goals TEXT,
11
+ outcome TEXT,
12
+ metadata TEXT
13
+ );
14
+
15
+ -- Memories: Universal remember-anything store
16
+ CREATE TABLE IF NOT EXISTS memories (
17
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
18
+ session_id INTEGER,
19
+ category TEXT NOT NULL,
20
+ key TEXT,
21
+ content TEXT NOT NULL,
22
+ importance INTEGER NOT NULL DEFAULT 5,
23
+ source TEXT NOT NULL DEFAULT 'explicit',
24
+ tags TEXT,
25
+ expires_at TEXT,
26
+ superseded_by INTEGER,
27
+ active INTEGER NOT NULL DEFAULT 1,
28
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
29
+ updated_at TEXT NOT NULL DEFAULT (datetime('now')),
30
+ FOREIGN KEY (session_id) REFERENCES sessions(id) ON DELETE SET NULL,
31
+ FOREIGN KEY (superseded_by) REFERENCES memories(id) ON DELETE SET NULL
32
+ );
33
+
34
+ -- Indexes
35
+ CREATE UNIQUE INDEX IF NOT EXISTS idx_memories_key
36
+ ON memories(key) WHERE key IS NOT NULL AND active = 1;
37
+ CREATE INDEX IF NOT EXISTS idx_sessions_started ON sessions(started_at);
38
+ CREATE INDEX IF NOT EXISTS idx_memories_category ON memories(category);
39
+ CREATE INDEX IF NOT EXISTS idx_memories_session ON memories(session_id);
40
+ CREATE INDEX IF NOT EXISTS idx_memories_active ON memories(active);
41
+ CREATE INDEX IF NOT EXISTS idx_memories_importance ON memories(importance DESC);
42
+ `);
43
+ }
44
+ //# sourceMappingURL=005_memory_schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"005_memory_schema.js","sourceRoot":"","sources":["../../../src/db/migrations/005_memory_schema.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,EAAE,CAAC,EAAqB;IACtC,EAAE,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCP,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type Database from 'better-sqlite3';
2
+ export declare function up(db: Database.Database): void;
@@ -0,0 +1,54 @@
1
+ export function up(db) {
2
+ db.exec(`
3
+ -- Full-text search for memories
4
+ CREATE VIRTUAL TABLE IF NOT EXISTS memories_fts USING fts5(
5
+ category, key, content, tags,
6
+ content='memories',
7
+ content_rowid='id'
8
+ );
9
+
10
+ -- Sync triggers for memories_fts
11
+ CREATE TRIGGER IF NOT EXISTS memories_ai AFTER INSERT ON memories BEGIN
12
+ INSERT INTO memories_fts(rowid, category, key, content, tags)
13
+ VALUES (new.id, new.category, new.key, new.content, new.tags);
14
+ END;
15
+
16
+ CREATE TRIGGER IF NOT EXISTS memories_ad AFTER DELETE ON memories BEGIN
17
+ INSERT INTO memories_fts(memories_fts, rowid, category, key, content, tags)
18
+ VALUES ('delete', old.id, old.category, old.key, old.content, old.tags);
19
+ END;
20
+
21
+ CREATE TRIGGER IF NOT EXISTS memories_au AFTER UPDATE ON memories BEGIN
22
+ INSERT INTO memories_fts(memories_fts, rowid, category, key, content, tags)
23
+ VALUES ('delete', old.id, old.category, old.key, old.content, old.tags);
24
+ INSERT INTO memories_fts(rowid, category, key, content, tags)
25
+ VALUES (new.id, new.category, new.key, new.content, new.tags);
26
+ END;
27
+
28
+ -- Full-text search for sessions
29
+ CREATE VIRTUAL TABLE IF NOT EXISTS sessions_fts USING fts5(
30
+ summary, goals,
31
+ content='sessions',
32
+ content_rowid='id'
33
+ );
34
+
35
+ -- Sync triggers for sessions_fts
36
+ CREATE TRIGGER IF NOT EXISTS sessions_ai AFTER INSERT ON sessions BEGIN
37
+ INSERT INTO sessions_fts(rowid, summary, goals)
38
+ VALUES (new.id, new.summary, new.goals);
39
+ END;
40
+
41
+ CREATE TRIGGER IF NOT EXISTS sessions_ad AFTER DELETE ON sessions BEGIN
42
+ INSERT INTO sessions_fts(sessions_fts, rowid, summary, goals)
43
+ VALUES ('delete', old.id, old.summary, old.goals);
44
+ END;
45
+
46
+ CREATE TRIGGER IF NOT EXISTS sessions_au AFTER UPDATE ON sessions BEGIN
47
+ INSERT INTO sessions_fts(sessions_fts, rowid, summary, goals)
48
+ VALUES ('delete', old.id, old.summary, old.goals);
49
+ INSERT INTO sessions_fts(rowid, summary, goals)
50
+ VALUES (new.id, new.summary, new.goals);
51
+ END;
52
+ `);
53
+ }
54
+ //# sourceMappingURL=006_memory_fts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"006_memory_fts.js","sourceRoot":"","sources":["../../../src/db/migrations/006_memory_fts.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,EAAE,CAAC,EAAqB;IACtC,EAAE,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDP,CAAC,CAAC;AACL,CAAC"}
@@ -3,11 +3,15 @@ import { up as coreSchema } from './001_core.js';
3
3
  import { up as synapsesSchema } from './002_synapses.js';
4
4
  import { up as learningSchema } from './003_learning.js';
5
5
  import { up as researchSchema } from './004_research.js';
6
+ import { up as memorySchema } from './005_memory_schema.js';
7
+ import { up as memoryFts } from './006_memory_fts.js';
6
8
  const migrations = [
7
9
  { version: 1, name: '001_core', up: coreSchema },
8
10
  { version: 2, name: '002_synapses', up: synapsesSchema },
9
11
  { version: 3, name: '003_learning', up: learningSchema },
10
12
  { version: 4, name: '004_research', up: researchSchema },
13
+ { version: 5, name: '005_memory_schema', up: memorySchema },
14
+ { version: 6, name: '006_memory_fts', up: memoryFts },
11
15
  ];
12
16
  function ensureMigrationsTable(db) {
13
17
  db.exec(`
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/db/migrations/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,EAAE,IAAI,UAAU,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,EAAE,IAAI,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,EAAE,IAAI,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,EAAE,IAAI,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAQzD,MAAM,UAAU,GAAgB;IAC9B,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,UAAU,EAAE;IAChD,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,EAAE,EAAE,cAAc,EAAE;IACxD,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,EAAE,EAAE,cAAc,EAAE;IACxD,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,EAAE,EAAE,cAAc,EAAE;CACzD,CAAC;AAEF,SAAS,qBAAqB,CAAC,EAAqB;IAClD,EAAE,CAAC,IAAI,CAAC;;;;;;GAMP,CAAC,CAAC;AACL,CAAC;AAED,SAAS,iBAAiB,CAAC,EAAqB;IAC9C,MAAM,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,gDAAgD,CAAC,CAAC,GAAG,EAA4C,CAAC;IACzH,OAAO,GAAG,EAAE,OAAO,IAAI,CAAC,CAAC;AAC3B,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,EAAqB;IACjD,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,qBAAqB,CAAC,EAAE,CAAC,CAAC;IAE1B,MAAM,cAAc,GAAG,iBAAiB,CAAC,EAAE,CAAC,CAAC;IAC7C,MAAM,OAAO,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,GAAG,cAAc,CAAC,CAAC;IAEnE,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,MAAM,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;QACtC,OAAO;IACT,CAAC;IAED,MAAM,CAAC,IAAI,CAAC,WAAW,OAAO,CAAC,MAAM,8BAA8B,cAAc,EAAE,CAAC,CAAC;IAErF,MAAM,MAAM,GAAG,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE;QACjC,KAAK,MAAM,SAAS,IAAI,OAAO,EAAE,CAAC;YAChC,MAAM,CAAC,IAAI,CAAC,sBAAsB,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC;YACpD,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;YACjB,EAAE,CAAC,OAAO,CAAC,sDAAsD,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;QAC5G,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,MAAM,EAAE,CAAC;IACT,MAAM,CAAC,IAAI,CAAC,uCAAuC,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAE,CAAC,OAAO,EAAE,CAAC,CAAC;AAC7F,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/db/migrations/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,EAAE,IAAI,UAAU,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,EAAE,IAAI,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,EAAE,IAAI,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,EAAE,IAAI,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,EAAE,IAAI,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,EAAE,IAAI,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAQtD,MAAM,UAAU,GAAgB;IAC9B,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,UAAU,EAAE;IAChD,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,EAAE,EAAE,cAAc,EAAE;IACxD,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,EAAE,EAAE,cAAc,EAAE;IACxD,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,EAAE,EAAE,cAAc,EAAE;IACxD,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,mBAAmB,EAAE,EAAE,EAAE,YAAY,EAAE;IAC3D,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,EAAE,EAAE,SAAS,EAAE;CACtD,CAAC;AAEF,SAAS,qBAAqB,CAAC,EAAqB;IAClD,EAAE,CAAC,IAAI,CAAC;;;;;;GAMP,CAAC,CAAC;AACL,CAAC;AAED,SAAS,iBAAiB,CAAC,EAAqB;IAC9C,MAAM,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,gDAAgD,CAAC,CAAC,GAAG,EAA4C,CAAC;IACzH,OAAO,GAAG,EAAE,OAAO,IAAI,CAAC,CAAC;AAC3B,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,EAAqB;IACjD,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,qBAAqB,CAAC,EAAE,CAAC,CAAC;IAE1B,MAAM,cAAc,GAAG,iBAAiB,CAAC,EAAE,CAAC,CAAC;IAC7C,MAAM,OAAO,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,GAAG,cAAc,CAAC,CAAC;IAEnE,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,MAAM,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;QACtC,OAAO;IACT,CAAC;IAED,MAAM,CAAC,IAAI,CAAC,WAAW,OAAO,CAAC,MAAM,8BAA8B,cAAc,EAAE,CAAC,CAAC;IAErF,MAAM,MAAM,GAAG,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE;QACjC,KAAK,MAAM,SAAS,IAAI,OAAO,EAAE,CAAC;YAChC,MAAM,CAAC,IAAI,CAAC,sBAAsB,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC;YACpD,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;YACjB,EAAE,CAAC,OAAO,CAAC,sDAAsD,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;QAC5G,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,MAAM,EAAE,CAAC;IACT,MAAM,CAAC,IAAI,CAAC,uCAAuC,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAE,CAAC,OAAO,EAAE,CAAC,CAAC;AAC7F,CAAC"}
@@ -0,0 +1,26 @@
1
+ import type Database from 'better-sqlite3';
2
+ import type { MemoryRecord, MemoryCategory, MemoryRepoInterface } from '../../types/memory.types.js';
3
+ type CreateMemoryData = Omit<MemoryRecord, 'id' | 'created_at' | 'updated_at' | 'project_id' | 'embedding'>;
4
+ export declare class MemoryRepository implements MemoryRepoInterface {
5
+ private db;
6
+ private stmts;
7
+ constructor(db: Database.Database);
8
+ create(data: CreateMemoryData): number;
9
+ getById(id: number): MemoryRecord | undefined;
10
+ findByKey(_projectId: number | null, key: string): MemoryRecord | undefined;
11
+ findByCategory(category: MemoryCategory, _projectId?: number, limit?: number): MemoryRecord[];
12
+ findActive(_projectId?: number, limit?: number): MemoryRecord[];
13
+ search(query: string, limit?: number): MemoryRecord[];
14
+ supersede(oldId: number, newId: number): void;
15
+ deactivate(id: number): void;
16
+ expireOld(): number;
17
+ update(id: number, data: Partial<MemoryRecord>): void;
18
+ findBySession(sessionId: number): MemoryRecord[];
19
+ upsertByKey(key: string, content: string, category: MemoryCategory, importance?: number, source?: string, tags?: string[]): {
20
+ memoryId: number;
21
+ superseded?: number;
22
+ };
23
+ countActive(): number;
24
+ countByCategory(): Record<string, number>;
25
+ }
26
+ export {};
@@ -0,0 +1,124 @@
1
+ export class MemoryRepository {
2
+ db;
3
+ stmts;
4
+ constructor(db) {
5
+ this.db = db;
6
+ this.stmts = {
7
+ create: this.db.prepare(`
8
+ INSERT INTO memories (session_id, category, key, content, importance, source, tags, expires_at, superseded_by, active)
9
+ VALUES (@session_id, @category, @key, @content, @importance, @source, @tags, @expires_at, @superseded_by, @active)
10
+ `),
11
+ getById: this.db.prepare('SELECT * FROM memories WHERE id = ?'),
12
+ findByKey: this.db.prepare('SELECT * FROM memories WHERE key = ? AND active = 1'),
13
+ findByCategoryAll: this.db.prepare('SELECT * FROM memories WHERE category = ? AND active = 1 ORDER BY importance DESC LIMIT ?'),
14
+ findActiveAll: this.db.prepare('SELECT * FROM memories WHERE active = 1 ORDER BY updated_at DESC LIMIT ?'),
15
+ search: this.db.prepare(`
16
+ SELECT m.* FROM memories m
17
+ JOIN memories_fts ON m.id = memories_fts.rowid
18
+ WHERE memories_fts MATCH ? AND m.active = 1
19
+ ORDER BY rank
20
+ LIMIT ?
21
+ `),
22
+ supersede: this.db.prepare("UPDATE memories SET superseded_by = ?, active = 0, updated_at = datetime('now') WHERE id = ?"),
23
+ deactivate: this.db.prepare("UPDATE memories SET active = 0, updated_at = datetime('now') WHERE id = ?"),
24
+ expireOld: this.db.prepare("UPDATE memories SET active = 0 WHERE expires_at IS NOT NULL AND expires_at < datetime('now') AND active = 1"),
25
+ update: this.db.prepare(`
26
+ UPDATE memories
27
+ SET content = COALESCE(@content, content),
28
+ importance = COALESCE(@importance, importance),
29
+ tags = COALESCE(@tags, tags),
30
+ expires_at = COALESCE(@expires_at, expires_at),
31
+ updated_at = datetime('now')
32
+ WHERE id = @id
33
+ `),
34
+ findBySession: this.db.prepare('SELECT * FROM memories WHERE session_id = ? AND active = 1 ORDER BY created_at'),
35
+ countActive: this.db.prepare('SELECT COUNT(*) as count FROM memories WHERE active = 1'),
36
+ countByCategory: this.db.prepare('SELECT category, COUNT(*) as count FROM memories WHERE active = 1 GROUP BY category'),
37
+ };
38
+ }
39
+ create(data) {
40
+ const result = this.stmts.create.run({
41
+ session_id: data.session_id ?? null,
42
+ category: data.category,
43
+ key: data.key ?? null,
44
+ content: data.content,
45
+ importance: data.importance ?? 5,
46
+ source: data.source ?? 'explicit',
47
+ tags: data.tags ?? null,
48
+ expires_at: data.expires_at ?? null,
49
+ superseded_by: data.superseded_by ?? null,
50
+ active: data.active ?? 1,
51
+ });
52
+ return result.lastInsertRowid;
53
+ }
54
+ getById(id) {
55
+ return this.stmts.getById.get(id);
56
+ }
57
+ findByKey(_projectId, key) {
58
+ return this.stmts.findByKey.get(key);
59
+ }
60
+ findByCategory(category, _projectId, limit = 50) {
61
+ return this.stmts.findByCategoryAll.all(category, limit);
62
+ }
63
+ findActive(_projectId, limit = 50) {
64
+ return this.stmts.findActiveAll.all(limit);
65
+ }
66
+ search(query, limit = 20) {
67
+ return this.stmts.search.all(query, limit);
68
+ }
69
+ supersede(oldId, newId) {
70
+ this.stmts.supersede.run(newId, oldId);
71
+ }
72
+ deactivate(id) {
73
+ this.stmts.deactivate.run(id);
74
+ }
75
+ expireOld() {
76
+ const result = this.stmts.expireOld.run();
77
+ return result.changes;
78
+ }
79
+ update(id, data) {
80
+ this.stmts.update.run({
81
+ id,
82
+ content: data.content ?? null,
83
+ importance: data.importance ?? null,
84
+ tags: data.tags ?? null,
85
+ expires_at: data.expires_at ?? null,
86
+ });
87
+ }
88
+ findBySession(sessionId) {
89
+ return this.stmts.findBySession.all(sessionId);
90
+ }
91
+ upsertByKey(key, content, category, importance = 5, source = 'explicit', tags) {
92
+ const existing = this.findByKey(null, key);
93
+ const newId = this.create({
94
+ session_id: null,
95
+ category,
96
+ key,
97
+ content,
98
+ importance,
99
+ source: source,
100
+ tags: tags ? JSON.stringify(tags) : null,
101
+ expires_at: null,
102
+ superseded_by: null,
103
+ active: 1,
104
+ });
105
+ if (existing) {
106
+ this.supersede(existing.id, newId);
107
+ return { memoryId: newId, superseded: existing.id };
108
+ }
109
+ return { memoryId: newId };
110
+ }
111
+ countActive() {
112
+ const row = this.stmts.countActive.get();
113
+ return row.count;
114
+ }
115
+ countByCategory() {
116
+ const rows = this.stmts.countByCategory.all();
117
+ const result = {};
118
+ for (const row of rows) {
119
+ result[row.category] = row.count;
120
+ }
121
+ return result;
122
+ }
123
+ }
124
+ //# sourceMappingURL=memory.repository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory.repository.js","sourceRoot":"","sources":["../../../src/db/repositories/memory.repository.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import type Database from 'better-sqlite3';
2
+ import type { SessionRecord, SessionRepoInterface } from '../../types/memory.types.js';
3
+ type CreateSessionData = Omit<SessionRecord, 'id' | 'project_id' | 'embedding'>;
4
+ export declare class SessionRepository implements SessionRepoInterface {
5
+ private db;
6
+ private stmts;
7
+ constructor(db: Database.Database);
8
+ create(data: CreateSessionData): number;
9
+ getById(id: number): SessionRecord | undefined;
10
+ findBySessionId(sessionId: string): SessionRecord | undefined;
11
+ findByProject(_projectId: number, limit?: number): SessionRecord[];
12
+ findRecent(limit?: number): SessionRecord[];
13
+ update(id: number, data: Partial<SessionRecord>): void;
14
+ search(query: string, limit?: number): SessionRecord[];
15
+ countAll(): number;
16
+ findLast(): SessionRecord | undefined;
17
+ }
18
+ export {};