shelbymcp 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 (76) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +335 -0
  3. package/dist/config.d.ts +9 -0
  4. package/dist/config.d.ts.map +1 -0
  5. package/dist/config.js +35 -0
  6. package/dist/config.js.map +1 -0
  7. package/dist/db/database.d.ts +8 -0
  8. package/dist/db/database.d.ts.map +1 -0
  9. package/dist/db/database.js +25 -0
  10. package/dist/db/database.js.map +1 -0
  11. package/dist/db/edges.d.ts +65 -0
  12. package/dist/db/edges.d.ts.map +1 -0
  13. package/dist/db/edges.js +256 -0
  14. package/dist/db/edges.js.map +1 -0
  15. package/dist/db/fts.d.ts +25 -0
  16. package/dist/db/fts.d.ts.map +1 -0
  17. package/dist/db/fts.js +53 -0
  18. package/dist/db/fts.js.map +1 -0
  19. package/dist/db/migrations.d.ts +11 -0
  20. package/dist/db/migrations.d.ts.map +1 -0
  21. package/dist/db/migrations.js +95 -0
  22. package/dist/db/migrations.js.map +1 -0
  23. package/dist/db/thoughts.d.ts +60 -0
  24. package/dist/db/thoughts.d.ts.map +1 -0
  25. package/dist/db/thoughts.js +194 -0
  26. package/dist/db/thoughts.js.map +1 -0
  27. package/dist/db/vectors.d.ts +16 -0
  28. package/dist/db/vectors.d.ts.map +1 -0
  29. package/dist/db/vectors.js +74 -0
  30. package/dist/db/vectors.js.map +1 -0
  31. package/dist/index.d.ts +3 -0
  32. package/dist/index.d.ts.map +1 -0
  33. package/dist/index.js +24 -0
  34. package/dist/index.js.map +1 -0
  35. package/dist/mcp/server.d.ts +8 -0
  36. package/dist/mcp/server.d.ts.map +1 -0
  37. package/dist/mcp/server.js +229 -0
  38. package/dist/mcp/server.js.map +1 -0
  39. package/dist/tools/capture.d.ts +4 -0
  40. package/dist/tools/capture.d.ts.map +1 -0
  41. package/dist/tools/capture.js +79 -0
  42. package/dist/tools/capture.js.map +1 -0
  43. package/dist/tools/delete.d.ts +4 -0
  44. package/dist/tools/delete.d.ts.map +1 -0
  45. package/dist/tools/delete.js +18 -0
  46. package/dist/tools/delete.js.map +1 -0
  47. package/dist/tools/get.d.ts +4 -0
  48. package/dist/tools/get.d.ts.map +1 -0
  49. package/dist/tools/get.js +19 -0
  50. package/dist/tools/get.js.map +1 -0
  51. package/dist/tools/graph.d.ts +5 -0
  52. package/dist/tools/graph.d.ts.map +1 -0
  53. package/dist/tools/graph.js +55 -0
  54. package/dist/tools/graph.js.map +1 -0
  55. package/dist/tools/helpers.d.ts +12 -0
  56. package/dist/tools/helpers.d.ts.map +1 -0
  57. package/dist/tools/helpers.js +21 -0
  58. package/dist/tools/helpers.js.map +1 -0
  59. package/dist/tools/list.d.ts +4 -0
  60. package/dist/tools/list.d.ts.map +1 -0
  61. package/dist/tools/list.js +18 -0
  62. package/dist/tools/list.js.map +1 -0
  63. package/dist/tools/search.d.ts +4 -0
  64. package/dist/tools/search.d.ts.map +1 -0
  65. package/dist/tools/search.js +73 -0
  66. package/dist/tools/search.js.map +1 -0
  67. package/dist/tools/stats.d.ts +4 -0
  68. package/dist/tools/stats.d.ts.map +1 -0
  69. package/dist/tools/stats.js +34 -0
  70. package/dist/tools/stats.js.map +1 -0
  71. package/dist/tools/update.d.ts +4 -0
  72. package/dist/tools/update.d.ts.map +1 -0
  73. package/dist/tools/update.js +59 -0
  74. package/dist/tools/update.js.map +1 -0
  75. package/package.json +58 -0
  76. package/skills/shelby-forage/SKILL.md +85 -0
@@ -0,0 +1,256 @@
1
+ import { v4 as uuidv4 } from "uuid";
2
+ // --- Types ---
3
+ export const VALID_EDGE_TYPES = [
4
+ "refines",
5
+ "cites",
6
+ "refuted_by",
7
+ "tags",
8
+ "related",
9
+ "follows",
10
+ ];
11
+ // --- Helpers ---
12
+ function parseMetadata(raw) {
13
+ if (raw === null || raw === undefined)
14
+ return null;
15
+ try {
16
+ return JSON.parse(raw);
17
+ }
18
+ catch {
19
+ return null;
20
+ }
21
+ }
22
+ function toEdgeRecord(row) {
23
+ return {
24
+ id: row.id,
25
+ source_id: row.source_id,
26
+ target_id: row.target_id,
27
+ edge_type: row.edge_type,
28
+ metadata: parseMetadata(row.metadata),
29
+ created_at: row.created_at,
30
+ };
31
+ }
32
+ // --- Functions ---
33
+ /**
34
+ * Create an edge between two thoughts. Returns the new edge's UUID.
35
+ * Throws if source or target don't exist, or if a duplicate edge exists.
36
+ */
37
+ export function linkThoughts(db, input) {
38
+ const { source_id, target_id, edge_type, metadata } = input;
39
+ if (!VALID_EDGE_TYPES.includes(edge_type)) {
40
+ throw new Error(`Invalid edge type "${edge_type}". Must be one of: ${VALID_EDGE_TYPES.join(", ")}`);
41
+ }
42
+ // Verify both thoughts exist
43
+ const sourceExists = db.db
44
+ .prepare("SELECT 1 FROM thoughts WHERE id = ?")
45
+ .get(source_id);
46
+ if (!sourceExists) {
47
+ throw new Error(`Source thought "${source_id}" does not exist`);
48
+ }
49
+ const targetExists = db.db
50
+ .prepare("SELECT 1 FROM thoughts WHERE id = ?")
51
+ .get(target_id);
52
+ if (!targetExists) {
53
+ throw new Error(`Target thought "${target_id}" does not exist`);
54
+ }
55
+ const id = uuidv4();
56
+ const now = new Date().toISOString();
57
+ const metadataJson = metadata ? JSON.stringify(metadata) : null;
58
+ try {
59
+ db.db
60
+ .prepare(`INSERT INTO edges (id, source_id, target_id, edge_type, metadata, created_at)
61
+ VALUES (?, ?, ?, ?, ?, ?)`)
62
+ .run(id, source_id, target_id, edge_type, metadataJson, now);
63
+ }
64
+ catch (err) {
65
+ const message = err instanceof Error ? err.message : String(err);
66
+ if (message.includes("UNIQUE constraint failed")) {
67
+ throw new Error(`Edge already exists: ${source_id} -[${edge_type}]-> ${target_id}`);
68
+ }
69
+ throw err;
70
+ }
71
+ return id;
72
+ }
73
+ /**
74
+ * Remove an edge between two thoughts. Returns true if an edge was deleted.
75
+ */
76
+ export function unlinkThoughts(db, source_id, target_id, edge_type) {
77
+ const result = db.db
78
+ .prepare("DELETE FROM edges WHERE source_id = ? AND target_id = ? AND edge_type = ?")
79
+ .run(source_id, target_id, edge_type);
80
+ return result.changes > 0;
81
+ }
82
+ /**
83
+ * Get a single edge by ID.
84
+ */
85
+ export function getEdge(db, id) {
86
+ const row = db.db
87
+ .prepare("SELECT * FROM edges WHERE id = ?")
88
+ .get(id);
89
+ return row ? toEdgeRecord(row) : null;
90
+ }
91
+ /**
92
+ * Get all edges between two specific thoughts (any type).
93
+ */
94
+ export function getEdgesBetween(db, source_id, target_id) {
95
+ const rows = db.db
96
+ .prepare("SELECT * FROM edges WHERE source_id = ? AND target_id = ?")
97
+ .all(source_id, target_id);
98
+ return rows.map(toEdgeRecord);
99
+ }
100
+ /**
101
+ * Get direct connections for a thought (both outgoing and incoming).
102
+ * Optionally filter by edge types.
103
+ */
104
+ export function getConnections(db, thought_id, edge_types) {
105
+ const results = [];
106
+ // Build edge type filter clause
107
+ let typeFilter = "";
108
+ const typeParams = [];
109
+ if (edge_types && edge_types.length > 0) {
110
+ const placeholders = edge_types.map(() => "?").join(", ");
111
+ typeFilter = `AND e.edge_type IN (${placeholders})`;
112
+ typeParams.push(...edge_types);
113
+ }
114
+ // Outgoing edges: this thought is the source
115
+ const outgoing = db.db
116
+ .prepare(`SELECT t.id AS thought_id, t.summary, t.type, e.id AS edge_id, e.edge_type
117
+ FROM edges e
118
+ JOIN thoughts t ON t.id = e.target_id
119
+ WHERE e.source_id = ? ${typeFilter}`)
120
+ .all(thought_id, ...typeParams);
121
+ for (const row of outgoing) {
122
+ results.push({
123
+ thought_id: row.thought_id,
124
+ summary: row.summary ?? null,
125
+ type: row.type,
126
+ edge_id: row.edge_id,
127
+ edge_type: row.edge_type,
128
+ direction: "outgoing",
129
+ });
130
+ }
131
+ // Incoming edges: this thought is the target
132
+ const incoming = db.db
133
+ .prepare(`SELECT t.id AS thought_id, t.summary, t.type, e.id AS edge_id, e.edge_type
134
+ FROM edges e
135
+ JOIN thoughts t ON t.id = e.source_id
136
+ WHERE e.target_id = ? ${typeFilter}`)
137
+ .all(thought_id, ...typeParams);
138
+ for (const row of incoming) {
139
+ results.push({
140
+ thought_id: row.thought_id,
141
+ summary: row.summary ?? null,
142
+ type: row.type,
143
+ edge_id: row.edge_id,
144
+ edge_type: row.edge_type,
145
+ direction: "incoming",
146
+ });
147
+ }
148
+ return results;
149
+ }
150
+ /**
151
+ * BFS traversal from a starting thought up to max_depth (capped at 5).
152
+ * Returns all discovered nodes with their depth and edges.
153
+ */
154
+ export function traverseGraph(db, thought_id, max_depth, edge_types) {
155
+ const effectiveDepth = Math.min(Math.max(max_depth, 0), 5);
156
+ // Verify starting thought exists
157
+ const startRow = db.db
158
+ .prepare("SELECT id, summary, type FROM thoughts WHERE id = ?")
159
+ .get(thought_id);
160
+ if (!startRow) {
161
+ return [];
162
+ }
163
+ const visited = new Map();
164
+ const queue = [
165
+ { id: thought_id, depth: 0 },
166
+ ];
167
+ // Initialize root node
168
+ visited.set(thought_id, {
169
+ id: thought_id,
170
+ summary: startRow.summary ?? null,
171
+ type: startRow.type,
172
+ depth: 0,
173
+ edges: [],
174
+ });
175
+ // Build edge type filter
176
+ let typeFilter = "";
177
+ const typeParams = [];
178
+ if (edge_types && edge_types.length > 0) {
179
+ const placeholders = edge_types.map(() => "?").join(", ");
180
+ typeFilter = `AND e.edge_type IN (${placeholders})`;
181
+ typeParams.push(...edge_types);
182
+ }
183
+ while (queue.length > 0) {
184
+ const current = queue.shift();
185
+ if (current.depth >= effectiveDepth)
186
+ continue;
187
+ // Outgoing edges
188
+ const outgoing = db.db
189
+ .prepare(`SELECT e.id AS edge_id, e.edge_type, e.target_id,
190
+ t.id AS thought_id, t.summary, t.type
191
+ FROM edges e
192
+ JOIN thoughts t ON t.id = e.target_id
193
+ WHERE e.source_id = ? ${typeFilter}`)
194
+ .all(current.id, ...typeParams);
195
+ for (const row of outgoing) {
196
+ const neighborId = row.target_id;
197
+ const edgeId = row.edge_id;
198
+ const edgeType = row.edge_type;
199
+ // Record edge on current node
200
+ const currentNode = visited.get(current.id);
201
+ currentNode.edges.push({
202
+ edge_id: edgeId,
203
+ edge_type: edgeType,
204
+ connected_to: neighborId,
205
+ direction: "outgoing",
206
+ });
207
+ // Discover new node
208
+ if (!visited.has(neighborId)) {
209
+ const newNode = {
210
+ id: neighborId,
211
+ summary: row.summary ?? null,
212
+ type: row.type,
213
+ depth: current.depth + 1,
214
+ edges: [],
215
+ };
216
+ visited.set(neighborId, newNode);
217
+ queue.push({ id: neighborId, depth: current.depth + 1 });
218
+ }
219
+ }
220
+ // Incoming edges
221
+ const incoming = db.db
222
+ .prepare(`SELECT e.id AS edge_id, e.edge_type, e.source_id,
223
+ t.id AS thought_id, t.summary, t.type
224
+ FROM edges e
225
+ JOIN thoughts t ON t.id = e.source_id
226
+ WHERE e.target_id = ? ${typeFilter}`)
227
+ .all(current.id, ...typeParams);
228
+ for (const row of incoming) {
229
+ const neighborId = row.source_id;
230
+ const edgeId = row.edge_id;
231
+ const edgeType = row.edge_type;
232
+ // Record edge on current node
233
+ const currentNode = visited.get(current.id);
234
+ currentNode.edges.push({
235
+ edge_id: edgeId,
236
+ edge_type: edgeType,
237
+ connected_to: neighborId,
238
+ direction: "incoming",
239
+ });
240
+ // Discover new node
241
+ if (!visited.has(neighborId)) {
242
+ const newNode = {
243
+ id: neighborId,
244
+ summary: row.summary ?? null,
245
+ type: row.type,
246
+ depth: current.depth + 1,
247
+ edges: [],
248
+ };
249
+ visited.set(neighborId, newNode);
250
+ queue.push({ id: neighborId, depth: current.depth + 1 });
251
+ }
252
+ }
253
+ }
254
+ return Array.from(visited.values());
255
+ }
256
+ //# sourceMappingURL=edges.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"edges.js","sourceRoot":"","sources":["../../src/db/edges.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import type Database from "better-sqlite3";
2
+ export interface SearchResult {
3
+ id: string;
4
+ summary: string | null;
5
+ type: string;
6
+ topics: string[];
7
+ created_at: string;
8
+ rank: number;
9
+ }
10
+ export interface SearchOptions {
11
+ query: string;
12
+ limit?: number;
13
+ offset?: number;
14
+ type?: string;
15
+ project?: string;
16
+ }
17
+ export interface SearchListResult {
18
+ results: SearchResult[];
19
+ total_count: number;
20
+ has_more: boolean;
21
+ offset: number;
22
+ }
23
+ export declare function sanitizeFTSQuery(query: string): string;
24
+ export declare function searchThoughts(db: Database.Database, options: SearchOptions): SearchListResult;
25
+ //# sourceMappingURL=fts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fts.d.ts","sourceRoot":"","sources":["../../src/db/fts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAE3C,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB;AAKD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAMtD;AAED,wBAAgB,cAAc,CAC5B,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,OAAO,EAAE,aAAa,GACrB,gBAAgB,CAwDlB"}
package/dist/db/fts.js ADDED
@@ -0,0 +1,53 @@
1
+ const FTS_SPECIAL_CHARS = /["\*\(\)\+\-\^:\{\}\[\]]/g;
2
+ const FTS_KEYWORDS = /\b(AND|OR|NOT|NEAR)\b/g;
3
+ export function sanitizeFTSQuery(query) {
4
+ let sanitized = query.replace(FTS_SPECIAL_CHARS, " ");
5
+ sanitized = sanitized.replace(FTS_KEYWORDS, " ");
6
+ const tokens = sanitized.split(/\s+/).filter((t) => t.length > 0);
7
+ if (tokens.length === 0)
8
+ return "";
9
+ return tokens.map((t) => `"${t}"*`).join(" ");
10
+ }
11
+ export function searchThoughts(db, options) {
12
+ const sanitized = sanitizeFTSQuery(options.query);
13
+ if (sanitized === "") {
14
+ return { results: [], total_count: 0, has_more: false, offset: 0 };
15
+ }
16
+ const limit = Math.max(1, Math.min(options.limit ?? 20, 100));
17
+ const offset = options.offset ?? 0;
18
+ const whereClauses = ["thoughts_fts MATCH ?"];
19
+ const params = [sanitized];
20
+ if (options.type) {
21
+ whereClauses.push("t.type = ?");
22
+ params.push(options.type);
23
+ }
24
+ if (options.project) {
25
+ whereClauses.push("t.project = ?");
26
+ params.push(options.project);
27
+ }
28
+ const whereSQL = whereClauses.join(" AND ");
29
+ // Count total matches
30
+ const countSQL = `SELECT COUNT(*) as cnt FROM thoughts_fts JOIN thoughts t ON thoughts_fts.rowid = t.rowid WHERE ${whereSQL}`;
31
+ const countRow = db.prepare(countSQL).get(...params);
32
+ const total_count = countRow.cnt;
33
+ // Fetch results with BM25 ranking
34
+ const selectSQL = `SELECT t.id, t.summary, t.type, t.topics, t.created_at, rank FROM thoughts_fts JOIN thoughts t ON thoughts_fts.rowid = t.rowid WHERE ${whereSQL} ORDER BY rank LIMIT ? OFFSET ?`;
35
+ const rows = db
36
+ .prepare(selectSQL)
37
+ .all(...params, limit, offset);
38
+ const results = rows.map((row) => ({
39
+ id: row.id,
40
+ summary: row.summary,
41
+ type: row.type,
42
+ topics: row.topics ? JSON.parse(row.topics) : [],
43
+ created_at: row.created_at,
44
+ rank: -row.rank, // Negate so higher = more relevant
45
+ }));
46
+ return {
47
+ results,
48
+ total_count,
49
+ has_more: offset + results.length < total_count,
50
+ offset,
51
+ };
52
+ }
53
+ //# sourceMappingURL=fts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fts.js","sourceRoot":"","sources":["../../src/db/fts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type Database from "better-sqlite3";
2
+ export interface Migration {
3
+ version: number;
4
+ description: string;
5
+ up: (db: Database.Database) => void;
6
+ }
7
+ export declare function getSchemaVersion(db: Database.Database): number;
8
+ export declare function setSchemaVersion(db: Database.Database, version: number): void;
9
+ export declare function runMigrations(db: Database.Database): void;
10
+ export declare function getMigrations(): Migration[];
11
+ //# sourceMappingURL=migrations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrations.d.ts","sourceRoot":"","sources":["../../src/db/migrations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAE3C,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,EAAE,EAAE,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,KAAK,IAAI,CAAC;CACrC;AAwED,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,GAAG,MAAM,CAG9D;AAED,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAE7E;AAED,wBAAgB,aAAa,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,GAAG,IAAI,CAmBzD;AAED,wBAAgB,aAAa,IAAI,SAAS,EAAE,CAE3C"}
@@ -0,0 +1,95 @@
1
+ const migrations = [
2
+ {
3
+ version: 1,
4
+ description: "Initial schema — thoughts, FTS5, edges",
5
+ up: (db) => {
6
+ db.exec(`
7
+ CREATE TABLE IF NOT EXISTS thoughts (
8
+ id TEXT PRIMARY KEY,
9
+ content TEXT NOT NULL,
10
+ summary TEXT,
11
+ type TEXT NOT NULL DEFAULT 'note',
12
+ source TEXT NOT NULL DEFAULT 'unknown',
13
+ project TEXT,
14
+ topics TEXT,
15
+ people TEXT,
16
+ visibility TEXT NOT NULL DEFAULT 'personal',
17
+ metadata TEXT,
18
+ embedding BLOB,
19
+ created_at TEXT NOT NULL,
20
+ updated_at TEXT NOT NULL,
21
+ consolidated_into TEXT,
22
+ reinforcement_count INTEGER NOT NULL DEFAULT 0
23
+ );
24
+
25
+ CREATE INDEX IF NOT EXISTS idx_thoughts_type ON thoughts(type);
26
+ CREATE INDEX IF NOT EXISTS idx_thoughts_project ON thoughts(project);
27
+ CREATE INDEX IF NOT EXISTS idx_thoughts_created ON thoughts(created_at);
28
+ CREATE INDEX IF NOT EXISTS idx_thoughts_updated ON thoughts(updated_at);
29
+ CREATE INDEX IF NOT EXISTS idx_thoughts_consolidated ON thoughts(consolidated_into);
30
+
31
+ CREATE VIRTUAL TABLE IF NOT EXISTS thoughts_fts USING fts5(
32
+ content,
33
+ content=thoughts,
34
+ content_rowid=rowid,
35
+ tokenize='porter unicode61'
36
+ );
37
+
38
+ CREATE TRIGGER IF NOT EXISTS thoughts_ai AFTER INSERT ON thoughts BEGIN
39
+ INSERT INTO thoughts_fts(rowid, content) VALUES (new.rowid, new.content);
40
+ END;
41
+
42
+ CREATE TRIGGER IF NOT EXISTS thoughts_ad AFTER DELETE ON thoughts BEGIN
43
+ INSERT INTO thoughts_fts(thoughts_fts, rowid, content) VALUES ('delete', old.rowid, old.content);
44
+ END;
45
+
46
+ CREATE TRIGGER IF NOT EXISTS thoughts_au AFTER UPDATE OF content ON thoughts BEGIN
47
+ INSERT INTO thoughts_fts(thoughts_fts, rowid, content) VALUES ('delete', old.rowid, old.content);
48
+ INSERT INTO thoughts_fts(rowid, content) VALUES (new.rowid, new.content);
49
+ END;
50
+
51
+ CREATE TABLE IF NOT EXISTS edges (
52
+ id TEXT PRIMARY KEY,
53
+ source_id TEXT NOT NULL,
54
+ target_id TEXT NOT NULL,
55
+ edge_type TEXT NOT NULL DEFAULT 'related',
56
+ metadata TEXT,
57
+ created_at TEXT NOT NULL,
58
+ FOREIGN KEY (source_id) REFERENCES thoughts(id) ON DELETE CASCADE,
59
+ FOREIGN KEY (target_id) REFERENCES thoughts(id) ON DELETE CASCADE,
60
+ UNIQUE(source_id, target_id, edge_type)
61
+ );
62
+
63
+ CREATE INDEX IF NOT EXISTS idx_edges_source ON edges(source_id);
64
+ CREATE INDEX IF NOT EXISTS idx_edges_target ON edges(target_id);
65
+ CREATE INDEX IF NOT EXISTS idx_edges_type ON edges(edge_type);
66
+ `);
67
+ },
68
+ },
69
+ ];
70
+ export function getSchemaVersion(db) {
71
+ const row = db.pragma("user_version", { simple: true });
72
+ return typeof row === "number" ? row : 0;
73
+ }
74
+ export function setSchemaVersion(db, version) {
75
+ db.pragma(`user_version = ${version}`);
76
+ }
77
+ export function runMigrations(db) {
78
+ const currentVersion = getSchemaVersion(db);
79
+ const pending = migrations
80
+ .filter((m) => m.version > currentVersion)
81
+ .sort((a, b) => a.version - b.version);
82
+ for (const migration of pending) {
83
+ console.error(`[INFO] Running migration v${migration.version}: ${migration.description}`);
84
+ const runInTransaction = db.transaction(() => {
85
+ migration.up(db);
86
+ setSchemaVersion(db, migration.version);
87
+ });
88
+ runInTransaction();
89
+ console.error(`[INFO] Migration v${migration.version} complete`);
90
+ }
91
+ }
92
+ export function getMigrations() {
93
+ return migrations;
94
+ }
95
+ //# sourceMappingURL=migrations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrations.js","sourceRoot":"","sources":["../../src/db/migrations.ts"],"names":[],"mappings":"AAQA,MAAM,UAAU,GAAgB;IAC9B;QACE,OAAO,EAAE,CAAC;QACV,WAAW,EAAE,wCAAwC;QACrD,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE;YACT,EAAE,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA4DP,CAAC,CAAC;QACL,CAAC;KACF;CACF,CAAC;AAEF,MAAM,UAAU,gBAAgB,CAAC,EAAqB;IACpD,MAAM,GAAG,GAAG,EAAE,CAAC,MAAM,CAAC,cAAc,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IACxD,OAAO,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AAC3C,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,EAAqB,EAAE,OAAe;IACrE,EAAE,CAAC,MAAM,CAAC,kBAAkB,OAAO,EAAE,CAAC,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,EAAqB;IACjD,MAAM,cAAc,GAAG,gBAAgB,CAAC,EAAE,CAAC,CAAC;IAE5C,MAAM,OAAO,GAAG,UAAU;SACvB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,GAAG,cAAc,CAAC;SACzC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC;IAEzC,KAAK,MAAM,SAAS,IAAI,OAAO,EAAE,CAAC;QAChC,OAAO,CAAC,KAAK,CAAC,6BAA6B,SAAS,CAAC,OAAO,KAAK,SAAS,CAAC,WAAW,EAAE,CAAC,CAAC;QAE1F,MAAM,gBAAgB,GAAG,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE;YAC3C,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;YACjB,gBAAgB,CAAC,EAAE,EAAE,SAAS,CAAC,OAAO,CAAC,CAAC;QAC1C,CAAC,CAAC,CAAC;QAEH,gBAAgB,EAAE,CAAC;QAEnB,OAAO,CAAC,KAAK,CAAC,qBAAqB,SAAS,CAAC,OAAO,WAAW,CAAC,CAAC;IACnE,CAAC;AACH,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,OAAO,UAAU,CAAC;AACpB,CAAC"}
@@ -0,0 +1,60 @@
1
+ import type Database from "better-sqlite3";
2
+ export interface ThoughtInput {
3
+ content: string;
4
+ summary?: string;
5
+ type?: string;
6
+ source?: string;
7
+ project?: string;
8
+ topics?: string[];
9
+ people?: string[];
10
+ visibility?: string;
11
+ metadata?: Record<string, unknown>;
12
+ }
13
+ export interface ThoughtRecord {
14
+ id: string;
15
+ content: string;
16
+ summary: string | null;
17
+ type: string;
18
+ source: string;
19
+ project: string | null;
20
+ topics: string[];
21
+ people: string[];
22
+ visibility: string;
23
+ metadata: Record<string, unknown> | null;
24
+ embedding: Buffer | null;
25
+ created_at: string;
26
+ updated_at: string;
27
+ consolidated_into: string | null;
28
+ reinforcement_count: number;
29
+ }
30
+ export interface ThoughtSummary {
31
+ id: string;
32
+ summary: string | null;
33
+ type: string;
34
+ topics: string[];
35
+ created_at: string;
36
+ }
37
+ export interface ListOptions {
38
+ type?: string;
39
+ project?: string;
40
+ topic?: string;
41
+ person?: string;
42
+ source?: string;
43
+ since?: string;
44
+ until?: string;
45
+ limit?: number;
46
+ offset?: number;
47
+ }
48
+ export interface ListResult {
49
+ results: ThoughtSummary[];
50
+ total_count: number;
51
+ has_more: boolean;
52
+ offset: number;
53
+ }
54
+ export declare function insertThought(db: Database.Database, input: ThoughtInput): string;
55
+ export declare function getThought(db: Database.Database, id: string): ThoughtRecord | null;
56
+ export declare function updateThought(db: Database.Database, id: string, updates: Partial<ThoughtInput>): boolean;
57
+ export declare function deleteThought(db: Database.Database, id: string): boolean;
58
+ export declare function listThoughts(db: Database.Database, options?: ListOptions): ListResult;
59
+ export declare function countThoughts(db: Database.Database): number;
60
+ //# sourceMappingURL=thoughts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"thoughts.d.ts","sourceRoot":"","sources":["../../src/db/thoughts.ts"],"names":[],"mappings":"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"}