@rangerchaz/aimem 0.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 (163) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +380 -0
  3. package/dist/cli/commands/git.d.ts +6 -0
  4. package/dist/cli/commands/git.d.ts.map +1 -0
  5. package/dist/cli/commands/git.js +298 -0
  6. package/dist/cli/commands/git.js.map +1 -0
  7. package/dist/cli/commands/hook-session-end.d.ts +7 -0
  8. package/dist/cli/commands/hook-session-end.d.ts.map +1 -0
  9. package/dist/cli/commands/hook-session-end.js +109 -0
  10. package/dist/cli/commands/hook-session-end.js.map +1 -0
  11. package/dist/cli/commands/hook-session-start.d.ts +7 -0
  12. package/dist/cli/commands/hook-session-start.d.ts.map +1 -0
  13. package/dist/cli/commands/hook-session-start.js +116 -0
  14. package/dist/cli/commands/hook-session-start.js.map +1 -0
  15. package/dist/cli/commands/import.d.ts +14 -0
  16. package/dist/cli/commands/import.d.ts.map +1 -0
  17. package/dist/cli/commands/import.js +527 -0
  18. package/dist/cli/commands/import.js.map +1 -0
  19. package/dist/cli/commands/init.d.ts +2 -0
  20. package/dist/cli/commands/init.d.ts.map +1 -0
  21. package/dist/cli/commands/init.js +32 -0
  22. package/dist/cli/commands/init.js.map +1 -0
  23. package/dist/cli/commands/mcp-serve.d.ts +2 -0
  24. package/dist/cli/commands/mcp-serve.d.ts.map +1 -0
  25. package/dist/cli/commands/mcp-serve.js +5 -0
  26. package/dist/cli/commands/mcp-serve.js.map +1 -0
  27. package/dist/cli/commands/query.d.ts +8 -0
  28. package/dist/cli/commands/query.d.ts.map +1 -0
  29. package/dist/cli/commands/query.js +83 -0
  30. package/dist/cli/commands/query.js.map +1 -0
  31. package/dist/cli/commands/setup.d.ts +10 -0
  32. package/dist/cli/commands/setup.d.ts.map +1 -0
  33. package/dist/cli/commands/setup.js +504 -0
  34. package/dist/cli/commands/setup.js.map +1 -0
  35. package/dist/cli/commands/start.d.ts +8 -0
  36. package/dist/cli/commands/start.d.ts.map +1 -0
  37. package/dist/cli/commands/start.js +90 -0
  38. package/dist/cli/commands/start.js.map +1 -0
  39. package/dist/cli/commands/status.d.ts +2 -0
  40. package/dist/cli/commands/status.d.ts.map +1 -0
  41. package/dist/cli/commands/status.js +85 -0
  42. package/dist/cli/commands/status.js.map +1 -0
  43. package/dist/cli/commands/stop.d.ts +7 -0
  44. package/dist/cli/commands/stop.d.ts.map +1 -0
  45. package/dist/cli/commands/stop.js +46 -0
  46. package/dist/cli/commands/stop.js.map +1 -0
  47. package/dist/cli/commands/visualize.d.ts +8 -0
  48. package/dist/cli/commands/visualize.d.ts.map +1 -0
  49. package/dist/cli/commands/visualize.js +96 -0
  50. package/dist/cli/commands/visualize.js.map +1 -0
  51. package/dist/cli/index.d.ts +3 -0
  52. package/dist/cli/index.d.ts.map +1 -0
  53. package/dist/cli/index.js +114 -0
  54. package/dist/cli/index.js.map +1 -0
  55. package/dist/db/index.d.ts +55 -0
  56. package/dist/db/index.d.ts.map +1 -0
  57. package/dist/db/index.js +464 -0
  58. package/dist/db/index.js.map +1 -0
  59. package/dist/db/schema.d.ts +4 -0
  60. package/dist/db/schema.d.ts.map +1 -0
  61. package/dist/db/schema.js +200 -0
  62. package/dist/db/schema.js.map +1 -0
  63. package/dist/extractor/index.d.ts +27 -0
  64. package/dist/extractor/index.d.ts.map +1 -0
  65. package/dist/extractor/index.js +227 -0
  66. package/dist/extractor/index.js.map +1 -0
  67. package/dist/git/extractor.d.ts +30 -0
  68. package/dist/git/extractor.d.ts.map +1 -0
  69. package/dist/git/extractor.js +126 -0
  70. package/dist/git/extractor.js.map +1 -0
  71. package/dist/git/hooks.d.ts +36 -0
  72. package/dist/git/hooks.d.ts.map +1 -0
  73. package/dist/git/hooks.js +142 -0
  74. package/dist/git/hooks.js.map +1 -0
  75. package/dist/git/index.d.ts +69 -0
  76. package/dist/git/index.d.ts.map +1 -0
  77. package/dist/git/index.js +250 -0
  78. package/dist/git/index.js.map +1 -0
  79. package/dist/indexer/index.d.ts +20 -0
  80. package/dist/indexer/index.d.ts.map +1 -0
  81. package/dist/indexer/index.js +173 -0
  82. package/dist/indexer/index.js.map +1 -0
  83. package/dist/indexer/parsers/base.d.ts +19 -0
  84. package/dist/indexer/parsers/base.d.ts.map +1 -0
  85. package/dist/indexer/parsers/base.js +46 -0
  86. package/dist/indexer/parsers/base.js.map +1 -0
  87. package/dist/indexer/parsers/cpp.d.ts +3 -0
  88. package/dist/indexer/parsers/cpp.d.ts.map +1 -0
  89. package/dist/indexer/parsers/cpp.js +180 -0
  90. package/dist/indexer/parsers/cpp.js.map +1 -0
  91. package/dist/indexer/parsers/go.d.ts +3 -0
  92. package/dist/indexer/parsers/go.d.ts.map +1 -0
  93. package/dist/indexer/parsers/go.js +98 -0
  94. package/dist/indexer/parsers/go.js.map +1 -0
  95. package/dist/indexer/parsers/java.d.ts +3 -0
  96. package/dist/indexer/parsers/java.d.ts.map +1 -0
  97. package/dist/indexer/parsers/java.js +204 -0
  98. package/dist/indexer/parsers/java.js.map +1 -0
  99. package/dist/indexer/parsers/javascript.d.ts +3 -0
  100. package/dist/indexer/parsers/javascript.d.ts.map +1 -0
  101. package/dist/indexer/parsers/javascript.js +157 -0
  102. package/dist/indexer/parsers/javascript.js.map +1 -0
  103. package/dist/indexer/parsers/kotlin.d.ts +3 -0
  104. package/dist/indexer/parsers/kotlin.d.ts.map +1 -0
  105. package/dist/indexer/parsers/kotlin.js +182 -0
  106. package/dist/indexer/parsers/kotlin.js.map +1 -0
  107. package/dist/indexer/parsers/php.d.ts +3 -0
  108. package/dist/indexer/parsers/php.d.ts.map +1 -0
  109. package/dist/indexer/parsers/php.js +190 -0
  110. package/dist/indexer/parsers/php.js.map +1 -0
  111. package/dist/indexer/parsers/python.d.ts +3 -0
  112. package/dist/indexer/parsers/python.d.ts.map +1 -0
  113. package/dist/indexer/parsers/python.js +101 -0
  114. package/dist/indexer/parsers/python.js.map +1 -0
  115. package/dist/indexer/parsers/ruby.d.ts +3 -0
  116. package/dist/indexer/parsers/ruby.d.ts.map +1 -0
  117. package/dist/indexer/parsers/ruby.js +92 -0
  118. package/dist/indexer/parsers/ruby.js.map +1 -0
  119. package/dist/indexer/parsers/rust.d.ts +3 -0
  120. package/dist/indexer/parsers/rust.d.ts.map +1 -0
  121. package/dist/indexer/parsers/rust.js +190 -0
  122. package/dist/indexer/parsers/rust.js.map +1 -0
  123. package/dist/indexer/watcher-daemon.d.ts +2 -0
  124. package/dist/indexer/watcher-daemon.d.ts.map +1 -0
  125. package/dist/indexer/watcher-daemon.js +27 -0
  126. package/dist/indexer/watcher-daemon.js.map +1 -0
  127. package/dist/indexer/watcher.d.ts +7 -0
  128. package/dist/indexer/watcher.d.ts.map +1 -0
  129. package/dist/indexer/watcher.js +77 -0
  130. package/dist/indexer/watcher.js.map +1 -0
  131. package/dist/mcp/server.d.ts +2 -0
  132. package/dist/mcp/server.d.ts.map +1 -0
  133. package/dist/mcp/server.js +241 -0
  134. package/dist/mcp/server.js.map +1 -0
  135. package/dist/proxy/interceptor-mockttp.d.ts +27 -0
  136. package/dist/proxy/interceptor-mockttp.d.ts.map +1 -0
  137. package/dist/proxy/interceptor-mockttp.js +274 -0
  138. package/dist/proxy/interceptor-mockttp.js.map +1 -0
  139. package/dist/proxy/proxy-daemon.d.ts +5 -0
  140. package/dist/proxy/proxy-daemon.d.ts.map +1 -0
  141. package/dist/proxy/proxy-daemon.js +26 -0
  142. package/dist/proxy/proxy-daemon.js.map +1 -0
  143. package/dist/query/index.d.ts +32 -0
  144. package/dist/query/index.d.ts.map +1 -0
  145. package/dist/query/index.js +135 -0
  146. package/dist/query/index.js.map +1 -0
  147. package/dist/types/index.d.ts +89 -0
  148. package/dist/types/index.d.ts.map +1 -0
  149. package/dist/types/index.js +3 -0
  150. package/dist/types/index.js.map +1 -0
  151. package/dist/visualize/index.d.ts +144 -0
  152. package/dist/visualize/index.d.ts.map +1 -0
  153. package/dist/visualize/index.js +707 -0
  154. package/dist/visualize/index.js.map +1 -0
  155. package/dist/visualize/server.d.ts +7 -0
  156. package/dist/visualize/server.d.ts.map +1 -0
  157. package/dist/visualize/server.js +77 -0
  158. package/dist/visualize/server.js.map +1 -0
  159. package/dist/visualize/template.d.ts +3 -0
  160. package/dist/visualize/template.d.ts.map +1 -0
  161. package/dist/visualize/template.js +3465 -0
  162. package/dist/visualize/template.js.map +1 -0
  163. package/package.json +56 -0
@@ -0,0 +1,464 @@
1
+ import Database from 'better-sqlite3';
2
+ import { homedir } from 'os';
3
+ import { join } from 'path';
4
+ import { mkdirSync, existsSync } from 'fs';
5
+ import { SCHEMA, MIGRATIONS, COMMIT_LINKS_SCHEMA } from './schema.js';
6
+ const DATA_DIR = join(homedir(), '.aimem');
7
+ const DB_PATH = join(DATA_DIR, 'aimem.db');
8
+ let db = null;
9
+ export function getDataDir() {
10
+ return DATA_DIR;
11
+ }
12
+ export function ensureDataDir() {
13
+ if (!existsSync(DATA_DIR)) {
14
+ mkdirSync(DATA_DIR, { recursive: true });
15
+ }
16
+ }
17
+ function applyMigrations(database) {
18
+ // Apply each migration, ignoring errors for already-applied ones
19
+ for (const migration of MIGRATIONS) {
20
+ try {
21
+ database.exec(migration);
22
+ }
23
+ catch {
24
+ // Column already exists or other expected error
25
+ }
26
+ }
27
+ // Apply commit_links schema
28
+ database.exec(COMMIT_LINKS_SCHEMA);
29
+ }
30
+ export function getDb() {
31
+ if (!db) {
32
+ ensureDataDir();
33
+ db = new Database(DB_PATH);
34
+ db.pragma('journal_mode = WAL');
35
+ db.pragma('foreign_keys = ON');
36
+ db.exec(SCHEMA);
37
+ applyMigrations(db);
38
+ }
39
+ return db;
40
+ }
41
+ export function closeDb() {
42
+ if (db) {
43
+ db.close();
44
+ db = null;
45
+ }
46
+ }
47
+ // Project operations
48
+ export function createProject(path, name) {
49
+ const db = getDb();
50
+ const stmt = db.prepare('INSERT INTO projects (path, name) VALUES (?, ?) RETURNING *');
51
+ return stmt.get(path, name);
52
+ }
53
+ export function getProject(id) {
54
+ const db = getDb();
55
+ return db.prepare('SELECT * FROM projects WHERE id = ?').get(id);
56
+ }
57
+ export function getProjectByPath(path) {
58
+ const db = getDb();
59
+ return db.prepare('SELECT * FROM projects WHERE path = ?').get(path);
60
+ }
61
+ export function getAllProjects() {
62
+ const db = getDb();
63
+ return db.prepare('SELECT * FROM projects ORDER BY created_at DESC').all();
64
+ }
65
+ // File operations
66
+ export function upsertFile(projectId, path, hash) {
67
+ const db = getDb();
68
+ const stmt = db.prepare(`
69
+ INSERT INTO files (project_id, path, hash, last_indexed)
70
+ VALUES (?, ?, ?, datetime('now'))
71
+ ON CONFLICT(project_id, path) DO UPDATE SET
72
+ hash = excluded.hash,
73
+ last_indexed = datetime('now')
74
+ RETURNING *
75
+ `);
76
+ return stmt.get(projectId, path, hash);
77
+ }
78
+ export function getFile(id) {
79
+ const db = getDb();
80
+ return db.prepare('SELECT * FROM files WHERE id = ?').get(id);
81
+ }
82
+ export function getFileByPath(projectId, path) {
83
+ const db = getDb();
84
+ return db.prepare('SELECT * FROM files WHERE project_id = ? AND path = ?').get(projectId, path);
85
+ }
86
+ export function deleteFile(id) {
87
+ const db = getDb();
88
+ db.prepare('DELETE FROM files WHERE id = ?').run(id);
89
+ }
90
+ export function getProjectFiles(projectId) {
91
+ const db = getDb();
92
+ return db.prepare('SELECT * FROM files WHERE project_id = ?').all(projectId);
93
+ }
94
+ // Structure operations
95
+ export function insertStructure(fileId, type, name, lineStart, lineEnd, signature, rawContent, metadata = {}) {
96
+ const db = getDb();
97
+ const stmt = db.prepare(`
98
+ INSERT INTO structures (file_id, type, name, line_start, line_end, signature, raw_content, metadata)
99
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?)
100
+ RETURNING *
101
+ `);
102
+ return stmt.get(fileId, type, name, lineStart, lineEnd, signature, rawContent, JSON.stringify(metadata));
103
+ }
104
+ export function deleteFileStructures(fileId) {
105
+ const db = getDb();
106
+ db.prepare('DELETE FROM structures WHERE file_id = ?').run(fileId);
107
+ }
108
+ export function searchStructures(query, limit = 20, projectId) {
109
+ const db = getDb();
110
+ if (projectId) {
111
+ return db.prepare(`
112
+ SELECT s.* FROM structures s
113
+ JOIN structures_fts fts ON s.id = fts.rowid
114
+ JOIN files f ON s.file_id = f.id
115
+ WHERE structures_fts MATCH ? AND f.project_id = ?
116
+ ORDER BY rank
117
+ LIMIT ?
118
+ `).all(query, projectId, limit);
119
+ }
120
+ return db.prepare(`
121
+ SELECT s.* FROM structures s
122
+ JOIN structures_fts fts ON s.id = fts.rowid
123
+ WHERE structures_fts MATCH ?
124
+ ORDER BY rank
125
+ LIMIT ?
126
+ `).all(query, limit);
127
+ }
128
+ export function getStructuresByName(name, projectId) {
129
+ const db = getDb();
130
+ if (projectId) {
131
+ return db.prepare(`
132
+ SELECT s.* FROM structures s
133
+ JOIN files f ON s.file_id = f.id
134
+ WHERE s.name = ? AND f.project_id = ?
135
+ `).all(name, projectId);
136
+ }
137
+ return db.prepare('SELECT * FROM structures WHERE name = ?').all(name);
138
+ }
139
+ // Find project by checking if cwd is inside any project path
140
+ export function findProjectForPath(targetPath) {
141
+ const projects = getAllProjects();
142
+ // Sort by path length descending to find most specific match
143
+ projects.sort((a, b) => b.path.length - a.path.length);
144
+ for (const project of projects) {
145
+ if (targetPath.startsWith(project.path)) {
146
+ return project;
147
+ }
148
+ }
149
+ return undefined;
150
+ }
151
+ // Conversation operations
152
+ export function insertConversation(rawContent, projectId = null, model = null, tool = null, summary = null) {
153
+ const db = getDb();
154
+ const stmt = db.prepare(`
155
+ INSERT INTO conversations (project_id, model, tool, summary, raw_content)
156
+ VALUES (?, ?, ?, ?, ?)
157
+ RETURNING *
158
+ `);
159
+ return stmt.get(projectId, model, tool, summary, rawContent);
160
+ }
161
+ export function searchConversations(query, limit = 20, projectId) {
162
+ const db = getDb();
163
+ if (projectId) {
164
+ return db.prepare(`
165
+ SELECT c.* FROM conversations c
166
+ JOIN conversations_fts fts ON c.id = fts.rowid
167
+ WHERE conversations_fts MATCH ? AND c.project_id = ?
168
+ ORDER BY rank
169
+ LIMIT ?
170
+ `).all(query, projectId, limit);
171
+ }
172
+ return db.prepare(`
173
+ SELECT c.* FROM conversations c
174
+ JOIN conversations_fts fts ON c.id = fts.rowid
175
+ WHERE conversations_fts MATCH ?
176
+ ORDER BY rank
177
+ LIMIT ?
178
+ `).all(query, limit);
179
+ }
180
+ // Link operations
181
+ export function createLink(sourceType, sourceId, targetType, targetId, linkType) {
182
+ const db = getDb();
183
+ const stmt = db.prepare(`
184
+ INSERT OR IGNORE INTO links (source_type, source_id, target_type, target_id, link_type)
185
+ VALUES (?, ?, ?, ?, ?)
186
+ RETURNING *
187
+ `);
188
+ return stmt.get(sourceType, sourceId, targetType, targetId, linkType);
189
+ }
190
+ export function getLinksFrom(sourceType, sourceId) {
191
+ const db = getDb();
192
+ return db.prepare('SELECT * FROM links WHERE source_type = ? AND source_id = ?').all(sourceType, sourceId);
193
+ }
194
+ export function getLinksTo(targetType, targetId) {
195
+ const db = getDb();
196
+ return db.prepare('SELECT * FROM links WHERE target_type = ? AND target_id = ?').all(targetType, targetId);
197
+ }
198
+ // Extraction operations
199
+ export function insertExtraction(conversationId, type, content, metadata = {}) {
200
+ const db = getDb();
201
+ const stmt = db.prepare(`
202
+ INSERT INTO extractions (conversation_id, type, content, metadata)
203
+ VALUES (?, ?, ?, ?)
204
+ RETURNING *
205
+ `);
206
+ return stmt.get(conversationId, type, content, JSON.stringify(metadata));
207
+ }
208
+ export function getConversationExtractions(conversationId) {
209
+ const db = getDb();
210
+ return db.prepare('SELECT * FROM extractions WHERE conversation_id = ?').all(conversationId);
211
+ }
212
+ export function getExtraction(id) {
213
+ const db = getDb();
214
+ return db.prepare('SELECT * FROM extractions WHERE id = ?').get(id);
215
+ }
216
+ export function searchExtractions(query, limit = 20, projectId) {
217
+ const db = getDb();
218
+ const searchTerm = `%${query}%`;
219
+ if (projectId) {
220
+ return db.prepare(`
221
+ SELECT e.* FROM extractions e
222
+ JOIN conversations c ON e.conversation_id = c.id
223
+ WHERE e.content LIKE ? AND c.project_id = ?
224
+ ORDER BY e.id DESC
225
+ LIMIT ?
226
+ `).all(searchTerm, projectId, limit);
227
+ }
228
+ return db.prepare(`
229
+ SELECT * FROM extractions
230
+ WHERE content LIKE ?
231
+ ORDER BY id DESC
232
+ LIMIT ?
233
+ `).all(searchTerm, limit);
234
+ }
235
+ export function isDuplicateExtraction(content, projectId, windowSeconds = 300) {
236
+ const db = getDb();
237
+ // Check for duplicate extraction content within the last N seconds
238
+ const stmt = db.prepare(`
239
+ SELECT COUNT(*) as count FROM extractions e
240
+ JOIN conversations c ON e.conversation_id = c.id
241
+ WHERE e.content = ?
242
+ AND (c.project_id = ? OR (c.project_id IS NULL AND ? IS NULL))
243
+ AND datetime(c.timestamp) > datetime('now', '-' || ? || ' seconds')
244
+ `);
245
+ const result = stmt.get(content.trim(), projectId, projectId, windowSeconds);
246
+ return result.count > 0;
247
+ }
248
+ // Stats
249
+ export function getStats() {
250
+ const db = getDb();
251
+ const projects = db.prepare('SELECT COUNT(*) as count FROM projects').get().count;
252
+ const files = db.prepare('SELECT COUNT(*) as count FROM files').get().count;
253
+ const structures = db.prepare('SELECT COUNT(*) as count FROM structures').get().count;
254
+ const conversations = db.prepare('SELECT COUNT(*) as count FROM conversations').get().count;
255
+ const links = db.prepare('SELECT COUNT(*) as count FROM links').get().count;
256
+ return { projects, files, structures, conversations, links };
257
+ }
258
+ // Check if entity exists (for hallucination checking)
259
+ export function structureExists(name) {
260
+ const db = getDb();
261
+ const result = db.prepare('SELECT 1 FROM structures WHERE name = ? LIMIT 1').get(name);
262
+ return result !== undefined;
263
+ }
264
+ export function fileExists(path) {
265
+ const db = getDb();
266
+ const result = db.prepare('SELECT 1 FROM files WHERE path = ? LIMIT 1').get(path);
267
+ return result !== undefined;
268
+ }
269
+ // Get a conversation by ID with full content
270
+ export function getConversationById(id) {
271
+ const db = getDb();
272
+ return db.prepare('SELECT * FROM conversations WHERE id = ?').get(id);
273
+ }
274
+ // Get full conversations for a project (for long-term memory)
275
+ export function getFullConversations(projectId, limit = 50, offset = 0) {
276
+ const db = getDb();
277
+ return db.prepare(`
278
+ SELECT * FROM conversations
279
+ WHERE project_id = ?
280
+ ORDER BY timestamp DESC
281
+ LIMIT ? OFFSET ?
282
+ `).all(projectId, limit, offset);
283
+ }
284
+ // Search conversations and return full content
285
+ export function searchFullConversations(query, limit = 20, projectId) {
286
+ const db = getDb();
287
+ if (projectId) {
288
+ return db.prepare(`
289
+ SELECT c.* FROM conversations c
290
+ JOIN conversations_fts fts ON c.id = fts.rowid
291
+ WHERE conversations_fts MATCH ? AND c.project_id = ?
292
+ ORDER BY rank
293
+ LIMIT ?
294
+ `).all(query, projectId, limit);
295
+ }
296
+ return db.prepare(`
297
+ SELECT c.* FROM conversations c
298
+ JOIN conversations_fts fts ON c.id = fts.rowid
299
+ WHERE conversations_fts MATCH ?
300
+ ORDER BY rank
301
+ LIMIT ?
302
+ `).all(query, limit);
303
+ }
304
+ // Get all structures for a project with file paths
305
+ export function getAllProjectStructures(projectId) {
306
+ const db = getDb();
307
+ return db.prepare(`
308
+ SELECT s.*, f.path as file_path
309
+ FROM structures s
310
+ JOIN files f ON s.file_id = f.id
311
+ WHERE f.project_id = ?
312
+ ORDER BY f.path, s.line_start
313
+ `).all(projectId);
314
+ }
315
+ // Get all links for a project
316
+ export function getAllProjectLinks(projectId) {
317
+ const db = getDb();
318
+ return db.prepare(`
319
+ SELECT DISTINCT l.* FROM links l
320
+ LEFT JOIN structures s ON l.source_type = 'structure' AND l.source_id = s.id
321
+ LEFT JOIN files f ON s.file_id = f.id
322
+ LEFT JOIN conversations c ON l.source_type = 'conversation' AND l.source_id = c.id
323
+ WHERE f.project_id = ? OR c.project_id = ?
324
+ `).all(projectId, projectId);
325
+ }
326
+ // Get all extractions for a project
327
+ export function getAllProjectExtractions(projectId) {
328
+ const db = getDb();
329
+ return db.prepare(`
330
+ SELECT e.* FROM extractions e
331
+ JOIN conversations c ON e.conversation_id = c.id
332
+ WHERE c.project_id = ?
333
+ ORDER BY c.timestamp DESC
334
+ `).all(projectId);
335
+ }
336
+ // ============ Git Operations ============
337
+ // Commit operations
338
+ export function upsertCommit(projectId, hash, shortHash, authorName, authorEmail, timestamp, subject, body, parentHashes = []) {
339
+ const db = getDb();
340
+ const stmt = db.prepare(`
341
+ INSERT INTO commits (project_id, hash, short_hash, author_name, author_email, timestamp, subject, body, parent_hashes)
342
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
343
+ ON CONFLICT(project_id, hash) DO UPDATE SET
344
+ short_hash = excluded.short_hash,
345
+ author_name = excluded.author_name,
346
+ author_email = excluded.author_email,
347
+ subject = excluded.subject,
348
+ body = excluded.body,
349
+ parent_hashes = excluded.parent_hashes
350
+ RETURNING *
351
+ `);
352
+ return stmt.get(projectId, hash, shortHash, authorName, authorEmail, timestamp, subject, body, JSON.stringify(parentHashes));
353
+ }
354
+ export function getCommitByHash(projectId, hash) {
355
+ const db = getDb();
356
+ return db.prepare('SELECT * FROM commits WHERE project_id = ? AND hash = ?').get(projectId, hash);
357
+ }
358
+ export function getCommitById(id) {
359
+ const db = getDb();
360
+ return db.prepare('SELECT * FROM commits WHERE id = ?').get(id);
361
+ }
362
+ export function searchCommits(query, limit = 20, projectId) {
363
+ const db = getDb();
364
+ if (projectId) {
365
+ return db.prepare(`
366
+ SELECT c.* FROM commits c
367
+ JOIN commits_fts fts ON c.id = fts.rowid
368
+ WHERE commits_fts MATCH ? AND c.project_id = ?
369
+ ORDER BY rank
370
+ LIMIT ?
371
+ `).all(query, projectId, limit);
372
+ }
373
+ return db.prepare(`
374
+ SELECT c.* FROM commits c
375
+ JOIN commits_fts fts ON c.id = fts.rowid
376
+ WHERE commits_fts MATCH ?
377
+ ORDER BY rank
378
+ LIMIT ?
379
+ `).all(query, limit);
380
+ }
381
+ export function getRecentCommits(projectId, limit = 50) {
382
+ const db = getDb();
383
+ return db.prepare(`
384
+ SELECT * FROM commits WHERE project_id = ?
385
+ ORDER BY timestamp DESC LIMIT ?
386
+ `).all(projectId, limit);
387
+ }
388
+ // Commit link operations
389
+ export function createCommitLink(commitId, targetType, targetId, linkType) {
390
+ const db = getDb();
391
+ const stmt = db.prepare(`
392
+ INSERT OR IGNORE INTO commit_links (commit_id, target_type, target_id, link_type)
393
+ VALUES (?, ?, ?, ?)
394
+ RETURNING *
395
+ `);
396
+ return stmt.get(commitId, targetType, targetId, linkType);
397
+ }
398
+ export function getCommitLinks(commitId) {
399
+ const db = getDb();
400
+ return db.prepare('SELECT * FROM commit_links WHERE commit_id = ?').all(commitId);
401
+ }
402
+ export function getLinksToCommit(targetType, targetId) {
403
+ const db = getDb();
404
+ return db.prepare('SELECT * FROM commit_links WHERE target_type = ? AND target_id = ?').all(targetType, targetId);
405
+ }
406
+ export function getCommitsForStructure(structureId) {
407
+ const db = getDb();
408
+ return db.prepare(`
409
+ SELECT c.* FROM commits c
410
+ JOIN commit_links cl ON c.id = cl.commit_id
411
+ WHERE cl.target_type = 'structure' AND cl.target_id = ?
412
+ ORDER BY c.timestamp DESC
413
+ `).all(structureId);
414
+ }
415
+ export function getCommitsForExtraction(extractionId) {
416
+ const db = getDb();
417
+ return db.prepare(`
418
+ SELECT c.* FROM commits c
419
+ JOIN commit_links cl ON c.id = cl.commit_id
420
+ WHERE cl.target_type = 'extraction' AND cl.target_id = ?
421
+ ORDER BY c.timestamp DESC
422
+ `).all(extractionId);
423
+ }
424
+ // Update structure authorship
425
+ export function updateStructureAuthorship(structureId, author, authorEmail, commitHash) {
426
+ const db = getDb();
427
+ db.prepare(`
428
+ UPDATE structures SET
429
+ last_author = ?,
430
+ last_author_email = ?,
431
+ last_commit_hash = ?
432
+ WHERE id = ?
433
+ `).run(author, authorEmail, commitHash, structureId);
434
+ }
435
+ // Get uncommitted decisions (extractions created since last commit)
436
+ export function getUncommittedExtractions(projectId, sinceCommitHash) {
437
+ const db = getDb();
438
+ if (sinceCommitHash) {
439
+ // Get extractions created after the specified commit's timestamp
440
+ return db.prepare(`
441
+ SELECT e.* FROM extractions e
442
+ JOIN conversations c ON e.conversation_id = c.id
443
+ WHERE c.project_id = ?
444
+ AND c.timestamp > (
445
+ SELECT timestamp FROM commits WHERE project_id = ? AND hash = ?
446
+ )
447
+ AND e.id NOT IN (
448
+ SELECT target_id FROM commit_links WHERE target_type = 'extraction'
449
+ )
450
+ ORDER BY c.timestamp DESC
451
+ `).all(projectId, projectId, sinceCommitHash);
452
+ }
453
+ // Get all extractions not linked to any commit
454
+ return db.prepare(`
455
+ SELECT e.* FROM extractions e
456
+ JOIN conversations c ON e.conversation_id = c.id
457
+ WHERE c.project_id = ?
458
+ AND e.id NOT IN (
459
+ SELECT target_id FROM commit_links WHERE target_type = 'extraction'
460
+ )
461
+ ORDER BY c.timestamp DESC
462
+ `).all(projectId);
463
+ }
464
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export declare const SCHEMA = "\n-- Projects table\nCREATE TABLE IF NOT EXISTS projects (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n path TEXT NOT NULL UNIQUE,\n name TEXT NOT NULL,\n created_at TEXT DEFAULT (datetime('now'))\n);\n\n-- Files table\nCREATE TABLE IF NOT EXISTS files (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n project_id INTEGER NOT NULL,\n path TEXT NOT NULL,\n hash TEXT NOT NULL,\n last_indexed TEXT DEFAULT (datetime('now')),\n FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE,\n UNIQUE(project_id, path)\n);\n\n-- Structures table (functions, classes, methods, etc.)\nCREATE TABLE IF NOT EXISTS structures (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n file_id INTEGER NOT NULL,\n type TEXT NOT NULL CHECK (type IN ('function', 'class', 'method', 'interface', 'type', 'variable', 'module')),\n name TEXT NOT NULL,\n line_start INTEGER NOT NULL,\n line_end INTEGER NOT NULL,\n signature TEXT,\n raw_content TEXT NOT NULL,\n metadata TEXT DEFAULT '{}',\n FOREIGN KEY (file_id) REFERENCES files(id) ON DELETE CASCADE\n);\n\n-- Conversations table\nCREATE TABLE IF NOT EXISTS conversations (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n project_id INTEGER,\n timestamp TEXT DEFAULT (datetime('now')),\n model TEXT,\n tool TEXT,\n summary TEXT,\n raw_content TEXT NOT NULL,\n FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE SET NULL\n);\n\n-- Links table (graph edges)\nCREATE TABLE IF NOT EXISTS links (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n source_type TEXT NOT NULL CHECK (source_type IN ('file', 'structure', 'conversation', 'extraction')),\n source_id INTEGER NOT NULL,\n target_type TEXT NOT NULL CHECK (target_type IN ('file', 'structure', 'conversation', 'extraction')),\n target_id INTEGER NOT NULL,\n link_type TEXT NOT NULL CHECK (link_type IN ('decision', 'touched', 'rejected', 'calls', 'called_by', 'references')),\n UNIQUE(source_type, source_id, target_type, target_id, link_type)\n);\n\n-- Extractions table (decisions, patterns, rejections from conversations)\nCREATE TABLE IF NOT EXISTS extractions (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n conversation_id INTEGER NOT NULL,\n type TEXT NOT NULL CHECK (type IN ('decision', 'pattern', 'rejection', 'question')),\n content TEXT NOT NULL,\n metadata TEXT DEFAULT '{}',\n FOREIGN KEY (conversation_id) REFERENCES conversations(id) ON DELETE CASCADE\n);\n\n-- Indexes for common queries\nCREATE INDEX IF NOT EXISTS idx_files_project ON files(project_id);\nCREATE INDEX IF NOT EXISTS idx_files_path ON files(path);\nCREATE INDEX IF NOT EXISTS idx_structures_file ON structures(file_id);\nCREATE INDEX IF NOT EXISTS idx_structures_name ON structures(name);\nCREATE INDEX IF NOT EXISTS idx_structures_type ON structures(type);\nCREATE INDEX IF NOT EXISTS idx_conversations_project ON conversations(project_id);\nCREATE INDEX IF NOT EXISTS idx_links_source ON links(source_type, source_id);\nCREATE INDEX IF NOT EXISTS idx_links_target ON links(target_type, target_id);\nCREATE INDEX IF NOT EXISTS idx_extractions_conversation ON extractions(conversation_id);\nCREATE INDEX IF NOT EXISTS idx_extractions_type ON extractions(type);\n\n-- Full-text search for structures\nCREATE VIRTUAL TABLE IF NOT EXISTS structures_fts USING fts5(\n name,\n signature,\n raw_content,\n content='structures',\n content_rowid='id'\n);\n\n-- Triggers to keep FTS in sync\nCREATE TRIGGER IF NOT EXISTS structures_ai AFTER INSERT ON structures BEGIN\n INSERT INTO structures_fts(rowid, name, signature, raw_content)\n VALUES (new.id, new.name, new.signature, new.raw_content);\nEND;\n\nCREATE TRIGGER IF NOT EXISTS structures_ad AFTER DELETE ON structures BEGIN\n INSERT INTO structures_fts(structures_fts, rowid, name, signature, raw_content)\n VALUES ('delete', old.id, old.name, old.signature, old.raw_content);\nEND;\n\nCREATE TRIGGER IF NOT EXISTS structures_au AFTER UPDATE ON structures BEGIN\n INSERT INTO structures_fts(structures_fts, rowid, name, signature, raw_content)\n VALUES ('delete', old.id, old.name, old.signature, old.raw_content);\n INSERT INTO structures_fts(rowid, name, signature, raw_content)\n VALUES (new.id, new.name, new.signature, new.raw_content);\nEND;\n\n-- Full-text search for conversations\nCREATE VIRTUAL TABLE IF NOT EXISTS conversations_fts USING fts5(\n summary,\n raw_content,\n content='conversations',\n content_rowid='id'\n);\n\nCREATE TRIGGER IF NOT EXISTS conversations_ai AFTER INSERT ON conversations BEGIN\n INSERT INTO conversations_fts(rowid, summary, raw_content)\n VALUES (new.id, new.summary, new.raw_content);\nEND;\n\nCREATE TRIGGER IF NOT EXISTS conversations_ad AFTER DELETE ON conversations BEGIN\n INSERT INTO conversations_fts(conversations_fts, rowid, summary, raw_content)\n VALUES ('delete', old.id, old.summary, old.raw_content);\nEND;\n\nCREATE TRIGGER IF NOT EXISTS conversations_au AFTER UPDATE ON conversations BEGIN\n INSERT INTO conversations_fts(conversations_fts, rowid, summary, raw_content)\n VALUES ('delete', old.id, old.summary, old.raw_content);\n INSERT INTO conversations_fts(rowid, summary, raw_content)\n VALUES (new.id, new.summary, new.raw_content);\nEND;\n\n-- Git commits table\nCREATE TABLE IF NOT EXISTS commits (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n project_id INTEGER NOT NULL,\n hash TEXT NOT NULL,\n short_hash TEXT,\n author_name TEXT,\n author_email TEXT,\n timestamp TEXT NOT NULL,\n subject TEXT NOT NULL,\n body TEXT,\n parent_hashes TEXT,\n FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE,\n UNIQUE(project_id, hash)\n);\n\nCREATE INDEX IF NOT EXISTS idx_commits_project ON commits(project_id);\nCREATE INDEX IF NOT EXISTS idx_commits_hash ON commits(hash);\nCREATE INDEX IF NOT EXISTS idx_commits_timestamp ON commits(timestamp);\n\n-- Full-text search for commits\nCREATE VIRTUAL TABLE IF NOT EXISTS commits_fts USING fts5(\n subject,\n body,\n content='commits',\n content_rowid='id'\n);\n\nCREATE TRIGGER IF NOT EXISTS commits_ai AFTER INSERT ON commits BEGIN\n INSERT INTO commits_fts(rowid, subject, body)\n VALUES (new.id, new.subject, new.body);\nEND;\n\nCREATE TRIGGER IF NOT EXISTS commits_ad AFTER DELETE ON commits BEGIN\n INSERT INTO commits_fts(commits_fts, rowid, subject, body)\n VALUES ('delete', old.id, old.subject, old.body);\nEND;\n\nCREATE TRIGGER IF NOT EXISTS commits_au AFTER UPDATE ON commits BEGIN\n INSERT INTO commits_fts(commits_fts, rowid, subject, body)\n VALUES ('delete', old.id, old.subject, old.body);\n INSERT INTO commits_fts(rowid, subject, body)\n VALUES (new.id, new.subject, new.body);\nEND;\n";
2
+ export declare const MIGRATIONS: string[];
3
+ export declare const COMMIT_LINKS_SCHEMA = "\nCREATE TABLE IF NOT EXISTS commit_links (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n commit_id INTEGER NOT NULL,\n target_type TEXT NOT NULL CHECK (target_type IN ('structure', 'file', 'extraction', 'conversation')),\n target_id INTEGER NOT NULL,\n link_type TEXT NOT NULL CHECK (link_type IN ('modified', 'committed_in', 'introduced')),\n FOREIGN KEY (commit_id) REFERENCES commits(id) ON DELETE CASCADE,\n UNIQUE(commit_id, target_type, target_id, link_type)\n);\n\nCREATE INDEX IF NOT EXISTS idx_commit_links_commit ON commit_links(commit_id);\nCREATE INDEX IF NOT EXISTS idx_commit_links_target ON commit_links(target_type, target_id);\n";
4
+ //# sourceMappingURL=schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/db/schema.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,MAAM,g9MA+KlB,CAAC;AAGF,eAAO,MAAM,UAAU,UAKtB,CAAC;AAGF,eAAO,MAAM,mBAAmB,8oBAa/B,CAAC"}