@timmeck/brain 2.1.2 → 2.2.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 (88) hide show
  1. package/README.md +71 -21
  2. package/brain.log +22 -0
  3. package/dist/brain.js +54 -0
  4. package/dist/brain.js.map +1 -1
  5. package/dist/cli/commands/status.js +9 -0
  6. package/dist/cli/commands/status.js.map +1 -1
  7. package/dist/db/migrations/010_memory_schema.d.ts +2 -0
  8. package/dist/db/migrations/010_memory_schema.js +52 -0
  9. package/dist/db/migrations/010_memory_schema.js.map +1 -0
  10. package/dist/db/migrations/011_memory_fts.d.ts +2 -0
  11. package/dist/db/migrations/011_memory_fts.js +54 -0
  12. package/dist/db/migrations/011_memory_fts.js.map +1 -0
  13. package/dist/db/migrations/012_decisions_changelog.d.ts +2 -0
  14. package/dist/db/migrations/012_decisions_changelog.js +97 -0
  15. package/dist/db/migrations/012_decisions_changelog.js.map +1 -0
  16. package/dist/db/migrations/013_tasks.d.ts +2 -0
  17. package/dist/db/migrations/013_tasks.js +53 -0
  18. package/dist/db/migrations/013_tasks.js.map +1 -0
  19. package/dist/db/migrations/014_project_docs.d.ts +2 -0
  20. package/dist/db/migrations/014_project_docs.js +43 -0
  21. package/dist/db/migrations/014_project_docs.js.map +1 -0
  22. package/dist/db/migrations/index.js +10 -0
  23. package/dist/db/migrations/index.js.map +1 -1
  24. package/dist/db/repositories/changelog.repository.d.ts +15 -0
  25. package/dist/db/repositories/changelog.repository.js +60 -0
  26. package/dist/db/repositories/changelog.repository.js.map +1 -0
  27. package/dist/db/repositories/decision.repository.d.ts +17 -0
  28. package/dist/db/repositories/decision.repository.js +89 -0
  29. package/dist/db/repositories/decision.repository.js.map +1 -0
  30. package/dist/db/repositories/doc.repository.d.ts +16 -0
  31. package/dist/db/repositories/doc.repository.js +85 -0
  32. package/dist/db/repositories/doc.repository.js.map +1 -0
  33. package/dist/db/repositories/memory.repository.d.ts +26 -0
  34. package/dist/db/repositories/memory.repository.js +136 -0
  35. package/dist/db/repositories/memory.repository.js.map +1 -0
  36. package/dist/db/repositories/session.repository.d.ts +18 -0
  37. package/dist/db/repositories/session.repository.js +82 -0
  38. package/dist/db/repositories/session.repository.js.map +1 -0
  39. package/dist/db/repositories/task.repository.d.ts +18 -0
  40. package/dist/db/repositories/task.repository.js +110 -0
  41. package/dist/db/repositories/task.repository.js.map +1 -0
  42. package/dist/embeddings/engine.d.ts +5 -0
  43. package/dist/embeddings/engine.js +82 -3
  44. package/dist/embeddings/engine.js.map +1 -1
  45. package/dist/hooks/post-tool-use.js +40 -18
  46. package/dist/hooks/post-tool-use.js.map +1 -1
  47. package/dist/hooks/pre-tool-use.d.ts +2 -0
  48. package/dist/hooks/pre-tool-use.js +44 -0
  49. package/dist/hooks/pre-tool-use.js.map +1 -0
  50. package/dist/ipc/router.d.ts +10 -0
  51. package/dist/ipc/router.js +37 -1
  52. package/dist/ipc/router.js.map +1 -1
  53. package/dist/mcp/tools.js +266 -0
  54. package/dist/mcp/tools.js.map +1 -1
  55. package/dist/services/analytics.service.d.ts +13 -0
  56. package/dist/services/analytics.service.js +13 -0
  57. package/dist/services/analytics.service.js.map +1 -1
  58. package/dist/services/changelog.service.d.ts +17 -0
  59. package/dist/services/changelog.service.js +77 -0
  60. package/dist/services/changelog.service.js.map +1 -0
  61. package/dist/services/decision.service.d.ts +17 -0
  62. package/dist/services/decision.service.js +64 -0
  63. package/dist/services/decision.service.js.map +1 -0
  64. package/dist/services/doc.service.d.ts +30 -0
  65. package/dist/services/doc.service.js +140 -0
  66. package/dist/services/doc.service.js.map +1 -0
  67. package/dist/services/memory.service.d.ts +44 -0
  68. package/dist/services/memory.service.js +189 -0
  69. package/dist/services/memory.service.js.map +1 -0
  70. package/dist/services/task.service.d.ts +35 -0
  71. package/dist/services/task.service.js +116 -0
  72. package/dist/services/task.service.js.map +1 -0
  73. package/dist/types/decision.types.d.ts +75 -0
  74. package/dist/types/decision.types.js +2 -0
  75. package/dist/types/decision.types.js.map +1 -0
  76. package/dist/types/doc.types.d.ts +23 -0
  77. package/dist/types/doc.types.js +2 -0
  78. package/dist/types/doc.types.js.map +1 -0
  79. package/dist/types/memory.types.d.ts +1 -0
  80. package/dist/types/memory.types.js +2 -0
  81. package/dist/types/memory.types.js.map +1 -0
  82. package/dist/types/synapse.types.d.ts +2 -2
  83. package/dist/types/task.types.d.ts +47 -0
  84. package/dist/types/task.types.js +2 -0
  85. package/dist/types/task.types.js.map +1 -0
  86. package/dist/utils/events.d.ts +47 -0
  87. package/dist/utils/events.js.map +1 -1
  88. package/package.json +2 -2
@@ -0,0 +1 @@
1
+ {"version":3,"file":"changelog.service.js","sourceRoot":"","sources":["../../src/services/changelog.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import type { DecisionRepository } from '../db/repositories/decision.repository.js';
2
+ import type { ProjectRepository } from '../db/repositories/project.repository.js';
3
+ import type { SynapseManager } from '../synapses/synapse-manager.js';
4
+ import type { DecisionRecord, RecordDecisionInput, QueryDecisionsInput } from '../types/decision.types.js';
5
+ export declare class DecisionService {
6
+ private decisionRepo;
7
+ private projectRepo;
8
+ private synapseManager;
9
+ private logger;
10
+ constructor(decisionRepo: DecisionRepository, projectRepo: ProjectRepository, synapseManager: SynapseManager);
11
+ recordDecision(input: RecordDecisionInput): {
12
+ decisionId: number;
13
+ };
14
+ queryDecisions(input: QueryDecisionsInput): DecisionRecord[];
15
+ getById(id: number): DecisionRecord | undefined;
16
+ supersedeDecision(oldId: number, newId: number): void;
17
+ }
@@ -0,0 +1,64 @@
1
+ import { getEventBus } from '../utils/events.js';
2
+ import { getLogger } from '../utils/logger.js';
3
+ export class DecisionService {
4
+ decisionRepo;
5
+ projectRepo;
6
+ synapseManager;
7
+ logger = getLogger();
8
+ constructor(decisionRepo, projectRepo, synapseManager) {
9
+ this.decisionRepo = decisionRepo;
10
+ this.projectRepo = projectRepo;
11
+ this.synapseManager = synapseManager;
12
+ }
13
+ recordDecision(input) {
14
+ const bus = getEventBus();
15
+ let projectId = input.projectId ?? null;
16
+ if (!projectId && input.project) {
17
+ const project = this.projectRepo.findByName(input.project);
18
+ if (project)
19
+ projectId = project.id;
20
+ }
21
+ const decisionId = this.decisionRepo.create({
22
+ project_id: projectId,
23
+ session_id: input.sessionId ?? null,
24
+ title: input.title,
25
+ description: input.description,
26
+ alternatives: input.alternatives ? JSON.stringify(input.alternatives) : null,
27
+ category: input.category ?? 'architecture',
28
+ status: 'active',
29
+ superseded_by: null,
30
+ tags: input.tags ? JSON.stringify(input.tags) : null,
31
+ embedding: null,
32
+ });
33
+ if (projectId) {
34
+ this.synapseManager.strengthen({ type: 'decision', id: decisionId }, { type: 'project', id: projectId }, 'co_occurs');
35
+ }
36
+ bus.emit('decision:recorded', { decisionId, projectId, category: input.category ?? 'architecture' });
37
+ this.logger.info(`Decision #${decisionId} recorded: ${input.title}`);
38
+ return { decisionId };
39
+ }
40
+ queryDecisions(input) {
41
+ if (input.query) {
42
+ try {
43
+ return this.decisionRepo.search(input.query, input.limit ?? 20);
44
+ }
45
+ catch {
46
+ // FTS syntax error — fall back
47
+ }
48
+ }
49
+ if (input.category) {
50
+ return this.decisionRepo.findByCategory(input.category, input.projectId, input.status ?? 'active', input.limit ?? 20);
51
+ }
52
+ return this.decisionRepo.findActive(input.projectId, input.limit ?? 20);
53
+ }
54
+ getById(id) {
55
+ return this.decisionRepo.getById(id);
56
+ }
57
+ supersedeDecision(oldId, newId) {
58
+ const bus = getEventBus();
59
+ this.decisionRepo.supersede(oldId, newId);
60
+ bus.emit('decision:superseded', { oldId, newId });
61
+ this.logger.info(`Decision #${oldId} superseded by #${newId}`);
62
+ }
63
+ }
64
+ //# sourceMappingURL=decision.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decision.service.js","sourceRoot":"","sources":["../../src/services/decision.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ import type { DocRepository } from '../db/repositories/doc.repository.js';
2
+ import type { ProjectRepository } from '../db/repositories/project.repository.js';
3
+ import type { DecisionRepository } from '../db/repositories/decision.repository.js';
4
+ import type { ChangelogRepository } from '../db/repositories/changelog.repository.js';
5
+ import type { TaskRepository } from '../db/repositories/task.repository.js';
6
+ import type { SynapseManager } from '../synapses/synapse-manager.js';
7
+ import type { ProjectDocRecord, IndexProjectInput, QueryDocsInput } from '../types/doc.types.js';
8
+ export declare class DocService {
9
+ private docRepo;
10
+ private projectRepo;
11
+ private decisionRepo;
12
+ private changelogRepo;
13
+ private taskRepo;
14
+ private synapseManager;
15
+ private logger;
16
+ constructor(docRepo: DocRepository, projectRepo: ProjectRepository, decisionRepo: DecisionRepository, changelogRepo: ChangelogRepository, taskRepo: TaskRepository, synapseManager: SynapseManager);
17
+ indexProject(input: IndexProjectInput): {
18
+ indexed: number;
19
+ updated: number;
20
+ projectId: number;
21
+ };
22
+ queryDocs(input: QueryDocsInput): ProjectDocRecord[];
23
+ getById(id: number): ProjectDocRecord | undefined;
24
+ getProjectContext(projectId: number): {
25
+ docs: ProjectDocRecord[];
26
+ activeTasks: unknown[];
27
+ recentDecisions: unknown[];
28
+ recentChanges: unknown[];
29
+ };
30
+ }
@@ -0,0 +1,140 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import crypto from 'node:crypto';
4
+ import { getEventBus } from '../utils/events.js';
5
+ import { getLogger } from '../utils/logger.js';
6
+ const DOC_FILE_MAP = {
7
+ 'README.md': 'readme',
8
+ 'readme.md': 'readme',
9
+ 'CLAUDE.md': 'claude_md',
10
+ 'claude.md': 'claude_md',
11
+ 'package.json': 'package_json',
12
+ 'tsconfig.json': 'tsconfig',
13
+ 'ARCHITECTURE.md': 'architecture',
14
+ 'architecture.md': 'architecture',
15
+ 'API.md': 'api',
16
+ 'api.md': 'api',
17
+ };
18
+ export class DocService {
19
+ docRepo;
20
+ projectRepo;
21
+ decisionRepo;
22
+ changelogRepo;
23
+ taskRepo;
24
+ synapseManager;
25
+ logger = getLogger();
26
+ constructor(docRepo, projectRepo, decisionRepo, changelogRepo, taskRepo, synapseManager) {
27
+ this.docRepo = docRepo;
28
+ this.projectRepo = projectRepo;
29
+ this.decisionRepo = decisionRepo;
30
+ this.changelogRepo = changelogRepo;
31
+ this.taskRepo = taskRepo;
32
+ this.synapseManager = synapseManager;
33
+ }
34
+ indexProject(input) {
35
+ const bus = getEventBus();
36
+ let projectId = input.projectId ?? 0;
37
+ if (!input.projectId && input.project) {
38
+ let project = this.projectRepo.findByName(input.project);
39
+ if (!project) {
40
+ const id = this.projectRepo.create({ name: input.project, path: input.projectPath, language: null, framework: null });
41
+ project = this.projectRepo.getById(id);
42
+ }
43
+ if (project)
44
+ projectId = project.id;
45
+ }
46
+ let indexed = 0;
47
+ let updated = 0;
48
+ for (const [fileName, docType] of Object.entries(DOC_FILE_MAP)) {
49
+ const filePath = path.join(input.projectPath, fileName);
50
+ if (!fs.existsSync(filePath))
51
+ continue;
52
+ try {
53
+ const content = fs.readFileSync(filePath, 'utf8');
54
+ const contentHash = crypto.createHash('sha256').update(content).digest('hex');
55
+ // Check if already indexed with same hash
56
+ const existing = this.docRepo.findByPath(projectId, fileName);
57
+ if (existing && existing.content_hash === contentHash)
58
+ continue;
59
+ // Parse metadata for package.json and tsconfig.json
60
+ let parsedMetadata = null;
61
+ if (docType === 'package_json') {
62
+ try {
63
+ const pkg = JSON.parse(content);
64
+ parsedMetadata = JSON.stringify({
65
+ name: pkg.name,
66
+ version: pkg.version,
67
+ description: pkg.description,
68
+ dependencies: Object.keys(pkg.dependencies ?? {}),
69
+ devDependencies: Object.keys(pkg.devDependencies ?? {}),
70
+ scripts: Object.keys(pkg.scripts ?? {}),
71
+ });
72
+ }
73
+ catch { /* ignore parse errors */ }
74
+ }
75
+ else if (docType === 'tsconfig') {
76
+ try {
77
+ const tsconfig = JSON.parse(content);
78
+ parsedMetadata = JSON.stringify({
79
+ target: tsconfig.compilerOptions?.target,
80
+ module: tsconfig.compilerOptions?.module,
81
+ strict: tsconfig.compilerOptions?.strict,
82
+ outDir: tsconfig.compilerOptions?.outDir,
83
+ });
84
+ }
85
+ catch { /* ignore parse errors */ }
86
+ }
87
+ this.docRepo.upsert({
88
+ project_id: projectId,
89
+ file_path: fileName,
90
+ doc_type: docType,
91
+ content,
92
+ content_hash: contentHash,
93
+ parsed_metadata: parsedMetadata,
94
+ embedding: null,
95
+ });
96
+ if (existing) {
97
+ updated++;
98
+ }
99
+ else {
100
+ indexed++;
101
+ bus.emit('doc:indexed', { docId: 0, projectId, docType });
102
+ }
103
+ }
104
+ catch (err) {
105
+ this.logger.warn(`Failed to index ${filePath}: ${err}`);
106
+ }
107
+ }
108
+ this.logger.info(`Indexed project docs: ${indexed} new, ${updated} updated`);
109
+ return { indexed, updated, projectId };
110
+ }
111
+ queryDocs(input) {
112
+ if (input.query) {
113
+ try {
114
+ return this.docRepo.search(input.query, input.projectId, input.limit ?? 20);
115
+ }
116
+ catch {
117
+ // FTS syntax error
118
+ }
119
+ }
120
+ if (input.projectId && input.docType) {
121
+ return this.docRepo.findByType(input.projectId, input.docType);
122
+ }
123
+ if (input.projectId) {
124
+ return this.docRepo.findByProject(input.projectId);
125
+ }
126
+ return [];
127
+ }
128
+ getById(id) {
129
+ return this.docRepo.getById(id);
130
+ }
131
+ getProjectContext(projectId) {
132
+ const docs = this.docRepo.findByProject(projectId);
133
+ const activeTasks = this.taskRepo.findByStatus('pending', projectId, 10)
134
+ .concat(this.taskRepo.findByStatus('in_progress', projectId, 10));
135
+ const recentDecisions = this.decisionRepo.findActive(projectId, 10);
136
+ const recentChanges = this.changelogRepo.findByProject(projectId, 10);
137
+ return { docs, activeTasks, recentDecisions, recentChanges };
138
+ }
139
+ }
140
+ //# sourceMappingURL=doc.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doc.service.js","sourceRoot":"","sources":["../../src/services/doc.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ import type { MemoryRepository } from '../db/repositories/memory.repository.js';
2
+ import type { SessionRepository } from '../db/repositories/session.repository.js';
3
+ import type { ProjectRepository } from '../db/repositories/project.repository.js';
4
+ import type { SynapseManager } from '../synapses/synapse-manager.js';
5
+ import type { EmbeddingEngine } from '../embeddings/engine.js';
6
+ import type { MemoryRecord, SessionRecord, RememberInput, RecallInput, StartSessionInput, EndSessionInput } from '../types/memory.types.js';
7
+ export declare class MemoryService {
8
+ private memoryRepo;
9
+ private sessionRepo;
10
+ private projectRepo;
11
+ private synapseManager;
12
+ private embeddingEngine;
13
+ private logger;
14
+ constructor(memoryRepo: MemoryRepository, sessionRepo: SessionRepository, projectRepo: ProjectRepository, synapseManager: SynapseManager);
15
+ setEmbeddingEngine(engine: EmbeddingEngine): void;
16
+ remember(input: RememberInput & {
17
+ project?: string;
18
+ }): {
19
+ memoryId: number;
20
+ superseded?: number;
21
+ };
22
+ recall(input: RecallInput): MemoryRecord[];
23
+ forget(memoryId: number): void;
24
+ getPreferences(projectId?: number): MemoryRecord[];
25
+ getDecisions(projectId?: number): MemoryRecord[];
26
+ getGoals(projectId?: number): MemoryRecord[];
27
+ getLessons(projectId?: number): MemoryRecord[];
28
+ startSession(input: StartSessionInput & {
29
+ project?: string;
30
+ }): {
31
+ sessionId: number;
32
+ dbSessionId: string;
33
+ };
34
+ endSession(input: EndSessionInput): void;
35
+ getSessionHistory(projectId?: number, limit?: number): SessionRecord[];
36
+ getCurrentSession(sessionUuid: string): SessionRecord | undefined;
37
+ getStats(): {
38
+ active: number;
39
+ byCategory: Record<string, number>;
40
+ sessions: number;
41
+ lastSession?: string;
42
+ };
43
+ expireOldMemories(): number;
44
+ }
@@ -0,0 +1,189 @@
1
+ import crypto from 'node:crypto';
2
+ import { getEventBus } from '../utils/events.js';
3
+ import { getLogger } from '../utils/logger.js';
4
+ export class MemoryService {
5
+ memoryRepo;
6
+ sessionRepo;
7
+ projectRepo;
8
+ synapseManager;
9
+ embeddingEngine = null;
10
+ logger = getLogger();
11
+ constructor(memoryRepo, sessionRepo, projectRepo, synapseManager) {
12
+ this.memoryRepo = memoryRepo;
13
+ this.sessionRepo = sessionRepo;
14
+ this.projectRepo = projectRepo;
15
+ this.synapseManager = synapseManager;
16
+ }
17
+ setEmbeddingEngine(engine) {
18
+ this.embeddingEngine = engine;
19
+ }
20
+ // ── Core Memory Methods ──
21
+ remember(input) {
22
+ const bus = getEventBus();
23
+ // Resolve project name to ID if provided
24
+ let projectId = input.projectId ?? null;
25
+ if (!projectId && input.project) {
26
+ const project = this.projectRepo.findByName(input.project);
27
+ if (project)
28
+ projectId = project.id;
29
+ }
30
+ // Key-based upsert or plain create
31
+ let result;
32
+ if (input.key) {
33
+ result = this.memoryRepo.upsertByKey(projectId, input.key, input.content, input.category, input.importance ?? 5, input.source ?? 'explicit', input.tags);
34
+ }
35
+ else {
36
+ const memoryId = this.memoryRepo.create({
37
+ project_id: projectId,
38
+ session_id: input.sessionId ?? null,
39
+ category: input.category,
40
+ key: null,
41
+ content: input.content,
42
+ importance: input.importance ?? 5,
43
+ source: input.source ?? 'explicit',
44
+ tags: input.tags ? JSON.stringify(input.tags) : null,
45
+ expires_at: input.expiresAt ?? null,
46
+ superseded_by: null,
47
+ active: 1,
48
+ embedding: null,
49
+ });
50
+ result = { memoryId };
51
+ }
52
+ // Synapses
53
+ if (projectId) {
54
+ this.synapseManager.strengthen({ type: 'memory', id: result.memoryId }, { type: 'project', id: projectId }, 'co_occurs');
55
+ }
56
+ if (input.sessionId) {
57
+ this.synapseManager.strengthen({ type: 'session', id: input.sessionId }, { type: 'memory', id: result.memoryId }, 'remembers');
58
+ }
59
+ bus.emit('memory:created', { memoryId: result.memoryId, projectId, category: input.category });
60
+ if (result.superseded) {
61
+ bus.emit('memory:superseded', { oldId: result.superseded, newId: result.memoryId });
62
+ }
63
+ this.logger.info(`Memory #${result.memoryId} stored (${input.category})${result.superseded ? ` superseding #${result.superseded}` : ''}`);
64
+ return result;
65
+ }
66
+ recall(input) {
67
+ // FTS search
68
+ let results;
69
+ try {
70
+ results = this.memoryRepo.search(input.query, input.limit ?? 10);
71
+ }
72
+ catch {
73
+ // FTS match syntax can fail — fall back to active memories
74
+ results = this.memoryRepo.findActive(input.projectId, input.limit ?? 10);
75
+ }
76
+ // Filter by category if specified
77
+ if (input.category) {
78
+ results = results.filter(m => m.category === input.category);
79
+ }
80
+ // Filter by project if specified
81
+ if (input.projectId) {
82
+ results = results.filter(m => m.project_id === input.projectId || m.project_id === null);
83
+ }
84
+ // Filter active only (default true)
85
+ if (input.activeOnly !== false) {
86
+ results = results.filter(m => m.active === 1);
87
+ }
88
+ return results;
89
+ }
90
+ forget(memoryId) {
91
+ this.memoryRepo.deactivate(memoryId);
92
+ this.logger.info(`Memory #${memoryId} deactivated`);
93
+ }
94
+ getPreferences(projectId) {
95
+ return this.memoryRepo.findByCategory('preference', projectId);
96
+ }
97
+ getDecisions(projectId) {
98
+ return this.memoryRepo.findByCategory('decision', projectId);
99
+ }
100
+ getGoals(projectId) {
101
+ return this.memoryRepo.findByCategory('goal', projectId);
102
+ }
103
+ getLessons(projectId) {
104
+ return this.memoryRepo.findByCategory('lesson', projectId);
105
+ }
106
+ // ── Session Methods ──
107
+ startSession(input) {
108
+ const bus = getEventBus();
109
+ const uuid = input.sessionId ?? crypto.randomUUID();
110
+ // Resolve project
111
+ let projectId = input.projectId ?? null;
112
+ if (!projectId && input.project) {
113
+ let project = this.projectRepo.findByName(input.project);
114
+ if (!project) {
115
+ // Auto-create project
116
+ const id = this.projectRepo.create({ name: input.project, path: null, language: null, framework: null });
117
+ project = this.projectRepo.getById(id);
118
+ }
119
+ if (project)
120
+ projectId = project.id;
121
+ }
122
+ // Check if session already exists
123
+ const existing = this.sessionRepo.findBySessionId(uuid);
124
+ if (existing) {
125
+ return { sessionId: existing.id, dbSessionId: uuid };
126
+ }
127
+ const id = this.sessionRepo.create({
128
+ session_id: uuid,
129
+ project_id: projectId,
130
+ started_at: new Date().toISOString(),
131
+ ended_at: null,
132
+ summary: null,
133
+ goals: input.goals ? JSON.stringify(input.goals) : null,
134
+ outcome: null,
135
+ metadata: input.metadata ? JSON.stringify(input.metadata) : null,
136
+ embedding: null,
137
+ });
138
+ if (projectId) {
139
+ this.synapseManager.strengthen({ type: 'session', id }, { type: 'project', id: projectId }, 'co_occurs');
140
+ }
141
+ bus.emit('session:started', { sessionId: id, projectId });
142
+ this.logger.info(`Session #${id} started (${uuid})`);
143
+ return { sessionId: id, dbSessionId: uuid };
144
+ }
145
+ endSession(input) {
146
+ const bus = getEventBus();
147
+ this.sessionRepo.update(input.sessionId, {
148
+ summary: input.summary,
149
+ ended_at: new Date().toISOString(),
150
+ outcome: input.outcome ?? 'completed',
151
+ });
152
+ const session = this.sessionRepo.getById(input.sessionId);
153
+ bus.emit('session:ended', { sessionId: input.sessionId, summary: input.summary });
154
+ this.logger.info(`Session #${input.sessionId} ended (${input.outcome ?? 'completed'})`);
155
+ // Link memories from this session
156
+ if (session) {
157
+ const memories = this.memoryRepo.findBySession(input.sessionId);
158
+ for (const mem of memories) {
159
+ this.synapseManager.strengthen({ type: 'session', id: input.sessionId }, { type: 'memory', id: mem.id }, 'remembers');
160
+ }
161
+ }
162
+ }
163
+ getSessionHistory(projectId, limit) {
164
+ if (projectId)
165
+ return this.sessionRepo.findByProject(projectId, limit ?? 20);
166
+ return this.sessionRepo.findRecent(limit ?? 20);
167
+ }
168
+ getCurrentSession(sessionUuid) {
169
+ return this.sessionRepo.findBySessionId(sessionUuid);
170
+ }
171
+ // ── Stats ──
172
+ getStats() {
173
+ const active = this.memoryRepo.countActive();
174
+ const byCategory = this.memoryRepo.countByCategory();
175
+ const sessions = this.sessionRepo.countAll();
176
+ const last = this.sessionRepo.findLast();
177
+ return {
178
+ active,
179
+ byCategory,
180
+ sessions,
181
+ lastSession: last?.started_at,
182
+ };
183
+ }
184
+ // ── Maintenance ──
185
+ expireOldMemories() {
186
+ return this.memoryRepo.expireOld();
187
+ }
188
+ }
189
+ //# sourceMappingURL=memory.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory.service.js","sourceRoot":"","sources":["../../src/services/memory.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ import type { TaskRepository } from '../db/repositories/task.repository.js';
2
+ import type { MemoryRepository } from '../db/repositories/memory.repository.js';
3
+ import type { DecisionRepository } from '../db/repositories/decision.repository.js';
4
+ import type { ChangelogRepository } from '../db/repositories/changelog.repository.js';
5
+ import type { ProjectRepository } from '../db/repositories/project.repository.js';
6
+ import type { SynapseManager } from '../synapses/synapse-manager.js';
7
+ import type { TaskRecord, AddTaskInput, UpdateTaskInput, ListTasksInput } from '../types/task.types.js';
8
+ export declare class TaskService {
9
+ private taskRepo;
10
+ private memoryRepo;
11
+ private decisionRepo;
12
+ private changelogRepo;
13
+ private projectRepo;
14
+ private synapseManager;
15
+ private logger;
16
+ constructor(taskRepo: TaskRepository, memoryRepo: MemoryRepository, decisionRepo: DecisionRepository, changelogRepo: ChangelogRepository, projectRepo: ProjectRepository, synapseManager: SynapseManager);
17
+ addTask(input: AddTaskInput & {
18
+ project?: string;
19
+ }): {
20
+ taskId: number;
21
+ };
22
+ updateTask(id: number, input: UpdateTaskInput & {
23
+ note?: string;
24
+ }): TaskRecord | undefined;
25
+ listTasks(input?: ListTasksInput): TaskRecord[];
26
+ getById(id: number): TaskRecord | undefined;
27
+ getTaskContext(id: number): {
28
+ task: TaskRecord | undefined;
29
+ subtasks: TaskRecord[];
30
+ memories: unknown[];
31
+ decisions: unknown[];
32
+ changes: unknown[];
33
+ };
34
+ searchTasks(query: string, limit?: number): TaskRecord[];
35
+ }