@voidwire/lore 2.0.0 → 2.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.
@@ -11,9 +11,9 @@
11
11
  */
12
12
 
13
13
  import { readFileSync } from "fs";
14
- import { checkPath, type IndexerContext } from "../indexer";
14
+ import { checkPath, type IndexerContext, type IndexerPlugin } from "../indexer";
15
15
 
16
- export async function indexCaptures(ctx: IndexerContext): Promise<void> {
16
+ async function indexCaptures(ctx: IndexerContext): Promise<void> {
17
17
  const logPath = `${ctx.config.paths.data}/log.jsonl`;
18
18
  if (
19
19
  !checkPath(
@@ -108,3 +108,15 @@ export async function indexCaptures(ctx: IndexerContext): Promise<void> {
108
108
  }
109
109
  }
110
110
  }
111
+
112
+ export const capturesPlugin: IndexerPlugin = {
113
+ manifest: {
114
+ name: "captures",
115
+ description: "Indexes knowledge, task, and note captures from log.jsonl",
116
+ requiredConfig: ["paths.data"],
117
+ optionalConfig: [],
118
+ rebuildExcluded: true,
119
+ },
120
+ canRun: (config) => !!config.paths?.data,
121
+ run: indexCaptures,
122
+ };
@@ -13,9 +13,9 @@
13
13
  import { readdirSync, existsSync } from "fs";
14
14
  import { join } from "path";
15
15
  import { spawnSync } from "child_process";
16
- import { checkPath, type IndexerContext } from "../indexer";
16
+ import { checkPath, type IndexerContext, type IndexerPlugin } from "../indexer";
17
17
 
18
- export async function indexCommits(ctx: IndexerContext): Promise<void> {
18
+ async function indexCommits(ctx: IndexerContext): Promise<void> {
19
19
  const projectsDir = ctx.config.paths.projects;
20
20
  if (!checkPath("commits", "paths.projects", projectsDir)) return;
21
21
 
@@ -84,3 +84,15 @@ export async function indexCommits(ctx: IndexerContext): Promise<void> {
84
84
  }
85
85
  }
86
86
  }
87
+
88
+ export const commitsPlugin: IndexerPlugin = {
89
+ manifest: {
90
+ name: "commits",
91
+ description: "Indexes git commit history from project directories",
92
+ requiredConfig: ["paths.projects"],
93
+ optionalConfig: [],
94
+ rebuildExcluded: false,
95
+ },
96
+ canRun: (config) => !!config.paths?.projects,
97
+ run: indexCommits,
98
+ };
@@ -10,9 +10,9 @@
10
10
 
11
11
  import { readdirSync, readFileSync, statSync, existsSync } from "fs";
12
12
  import { join } from "path";
13
- import { checkPath, type IndexerContext } from "../indexer";
13
+ import { checkPath, type IndexerContext, type IndexerPlugin } from "../indexer";
14
14
 
15
- export async function indexDevelopment(ctx: IndexerContext): Promise<void> {
15
+ async function indexDevelopment(ctx: IndexerContext): Promise<void> {
16
16
  const projectsDir = ctx.config.paths.projects;
17
17
  if (!checkPath("development", "paths.projects", projectsDir)) return;
18
18
 
@@ -62,3 +62,15 @@ export async function indexDevelopment(ctx: IndexerContext): Promise<void> {
62
62
  }
63
63
  }
64
64
  }
65
+
66
+ export const developmentPlugin: IndexerPlugin = {
67
+ manifest: {
68
+ name: "development",
69
+ description: "Indexes project summary files from development directories",
70
+ requiredConfig: ["paths.projects"],
71
+ optionalConfig: [],
72
+ rebuildExcluded: false,
73
+ },
74
+ canRun: (config) => !!config.paths?.projects,
75
+ run: indexDevelopment,
76
+ };
@@ -12,7 +12,7 @@
12
12
 
13
13
  import { readdirSync, readFileSync, statSync } from "fs";
14
14
  import { join, basename, dirname } from "path";
15
- import { checkPath, type IndexerContext } from "../indexer";
15
+ import { checkPath, type IndexerContext, type IndexerPlugin } from "../indexer";
16
16
 
17
17
  function walkMarkdownFiles(dir: string, files: string[] = []): string[] {
18
18
  const entries = readdirSync(dir, { withFileTypes: true });
@@ -30,7 +30,7 @@ function walkMarkdownFiles(dir: string, files: string[] = []): string[] {
30
30
  return files;
31
31
  }
32
32
 
33
- export async function indexExplorations(ctx: IndexerContext): Promise<void> {
33
+ async function indexExplorations(ctx: IndexerContext): Promise<void> {
34
34
  const explorationsDir = ctx.config.paths.explorations;
35
35
 
36
36
  if (!checkPath("explorations", "paths.explorations", explorationsDir)) return;
@@ -84,3 +84,15 @@ export async function indexExplorations(ctx: IndexerContext): Promise<void> {
84
84
  }
85
85
  }
86
86
  }
87
+
88
+ export const explorationsPlugin: IndexerPlugin = {
89
+ manifest: {
90
+ name: "explorations",
91
+ description: "Indexes markdown files from the explorations directory",
92
+ requiredConfig: ["paths.explorations"],
93
+ optionalConfig: [],
94
+ rebuildExcluded: false,
95
+ },
96
+ canRun: (config) => !!config.paths?.explorations,
97
+ run: indexExplorations,
98
+ };
@@ -14,9 +14,9 @@
14
14
 
15
15
  import { readdirSync, readFileSync, existsSync, statSync } from "fs";
16
16
  import { join, basename } from "path";
17
- import { checkPath, type IndexerContext } from "../indexer";
17
+ import { checkPath, type IndexerContext, type IndexerPlugin } from "../indexer";
18
18
 
19
- export async function indexFlux(ctx: IndexerContext): Promise<void> {
19
+ async function indexFlux(ctx: IndexerContext): Promise<void> {
20
20
  const fluxDir = ctx.config.paths.flux;
21
21
  const fluxProjectsDir = ctx.config.paths.flux_projects;
22
22
  let found = false;
@@ -141,3 +141,15 @@ function parseFluxFile(
141
141
  });
142
142
  }
143
143
  }
144
+
145
+ export const fluxPlugin: IndexerPlugin = {
146
+ manifest: {
147
+ name: "flux",
148
+ description: "Indexes todo and idea entries from flux markdown files",
149
+ requiredConfig: ["paths.flux"],
150
+ optionalConfig: [],
151
+ rebuildExcluded: false,
152
+ },
153
+ canRun: (config) => !!config.paths?.flux,
154
+ run: indexFlux,
155
+ };
@@ -1,35 +1,35 @@
1
1
  /**
2
2
  * lib/indexers/index.ts - Indexer registry
3
3
  *
4
- * Maps source names to indexer functions.
5
- * Populated by tasks 3.1, 3.2, 3.3.
4
+ * Maps source names to indexer plugins.
5
+ * Each plugin provides manifest metadata, a canRun gate, and the run function.
6
6
  */
7
7
 
8
- import type { IndexerFunction } from "../indexer";
9
- import { indexReadmes } from "./readmes";
10
- import { indexDevelopment } from "./development";
11
- import { indexCaptures } from "./captures";
12
- import { indexTeachings } from "./teachings";
13
- import { indexObservations } from "./observations";
14
- import { indexExplorations } from "./explorations";
15
- import { indexSessions } from "./sessions";
16
- import { indexFlux } from "./flux";
17
- import { indexObsidian } from "./obsidian";
18
- import { indexCommits } from "./commits";
19
- import { indexBlogs } from "./blogs";
20
- import { indexPersonal } from "./personal";
8
+ import type { IndexerPlugin } from "../indexer";
9
+ import { readmesPlugin } from "./readmes";
10
+ import { developmentPlugin } from "./development";
11
+ import { capturesPlugin } from "./captures";
12
+ import { teachingsPlugin } from "./teachings";
13
+ import { observationsPlugin } from "./observations";
14
+ import { explorationsPlugin } from "./explorations";
15
+ import { sessionsPlugin } from "./sessions";
16
+ import { fluxPlugin } from "./flux";
17
+ import { obsidianPlugin } from "./obsidian";
18
+ import { commitsPlugin } from "./commits";
19
+ import { blogsPlugin } from "./blogs";
20
+ import { personalPlugin } from "./personal";
21
21
 
22
- export const indexers: Record<string, IndexerFunction> = {
23
- readmes: indexReadmes,
24
- development: indexDevelopment,
25
- captures: indexCaptures,
26
- teachings: indexTeachings,
27
- observations: indexObservations,
28
- explorations: indexExplorations,
29
- sessions: indexSessions,
30
- flux: indexFlux,
31
- obsidian: indexObsidian,
32
- commits: indexCommits,
33
- blogs: indexBlogs,
34
- personal: indexPersonal,
22
+ export const indexers: Record<string, IndexerPlugin> = {
23
+ readmes: readmesPlugin,
24
+ development: developmentPlugin,
25
+ captures: capturesPlugin,
26
+ teachings: teachingsPlugin,
27
+ observations: observationsPlugin,
28
+ explorations: explorationsPlugin,
29
+ sessions: sessionsPlugin,
30
+ flux: fluxPlugin,
31
+ obsidian: obsidianPlugin,
32
+ commits: commitsPlugin,
33
+ blogs: blogsPlugin,
34
+ personal: personalPlugin,
35
35
  };
@@ -11,9 +11,9 @@
11
11
  */
12
12
 
13
13
  import { readFileSync } from "fs";
14
- import { checkPath, type IndexerContext } from "../indexer";
14
+ import { checkPath, type IndexerContext, type IndexerPlugin } from "../indexer";
15
15
 
16
- export async function indexObservations(ctx: IndexerContext): Promise<void> {
16
+ async function indexObservations(ctx: IndexerContext): Promise<void> {
17
17
  const logPath = `${ctx.config.paths.data}/log.jsonl`;
18
18
  if (
19
19
  !checkPath(
@@ -56,3 +56,15 @@ export async function indexObservations(ctx: IndexerContext): Promise<void> {
56
56
  }
57
57
  }
58
58
  }
59
+
60
+ export const observationsPlugin: IndexerPlugin = {
61
+ manifest: {
62
+ name: "observations",
63
+ description: "Indexes observation captures from log.jsonl",
64
+ requiredConfig: ["paths.data"],
65
+ optionalConfig: [],
66
+ rebuildExcluded: true,
67
+ },
68
+ canRun: (config) => !!config.paths?.data,
69
+ run: indexObservations,
70
+ };
@@ -13,7 +13,7 @@
13
13
 
14
14
  import { readdirSync, readFileSync, statSync } from "fs";
15
15
  import { join, basename, dirname } from "path";
16
- import { checkPath, type IndexerContext } from "../indexer";
16
+ import { checkPath, type IndexerContext, type IndexerPlugin } from "../indexer";
17
17
 
18
18
  function walkMarkdownFiles(
19
19
  dir: string,
@@ -38,7 +38,7 @@ function walkMarkdownFiles(
38
38
  return files;
39
39
  }
40
40
 
41
- export async function indexObsidian(ctx: IndexerContext): Promise<void> {
41
+ async function indexObsidian(ctx: IndexerContext): Promise<void> {
42
42
  const obsidianDir = ctx.config.paths.obsidian;
43
43
 
44
44
  if (!checkPath("obsidian", "paths.obsidian", obsidianDir)) return;
@@ -148,3 +148,15 @@ export async function indexObsidian(ctx: IndexerContext): Promise<void> {
148
148
  }
149
149
  }
150
150
  }
151
+
152
+ export const obsidianPlugin: IndexerPlugin = {
153
+ manifest: {
154
+ name: "obsidian",
155
+ description: "Indexes markdown files from the Obsidian vault",
156
+ requiredConfig: ["paths.obsidian"],
157
+ optionalConfig: [],
158
+ rebuildExcluded: false,
159
+ },
160
+ canRun: (config) => !!config.paths?.obsidian,
161
+ run: indexObsidian,
162
+ };
@@ -12,7 +12,7 @@
12
12
 
13
13
  import { readFileSync, statSync, existsSync } from "fs";
14
14
  import { join } from "path";
15
- import { checkPath, type IndexerContext } from "../indexer";
15
+ import { checkPath, type IndexerContext, type IndexerPlugin } from "../indexer";
16
16
  import { complete } from "@voidwire/llm-core";
17
17
 
18
18
  function fileMtime(path: string): string {
@@ -91,7 +91,7 @@ async function enrich(type: string, input: string): Promise<string | null> {
91
91
  }
92
92
  }
93
93
 
94
- export async function indexPersonal(ctx: IndexerContext): Promise<void> {
94
+ async function indexPersonal(ctx: IndexerContext): Promise<void> {
95
95
  enrichmentFailures = 0;
96
96
  const personalDir = ctx.config.paths.personal;
97
97
 
@@ -354,3 +354,15 @@ export async function indexPersonal(ctx: IndexerContext): Promise<void> {
354
354
  }
355
355
  }
356
356
  }
357
+
358
+ export const personalPlugin: IndexerPlugin = {
359
+ manifest: {
360
+ name: "personal",
361
+ description: "Indexes personal data JSON files (books, contacts, movies, etc.)",
362
+ requiredConfig: ["paths.personal"],
363
+ optionalConfig: [],
364
+ rebuildExcluded: false,
365
+ },
366
+ canRun: (config) => !!config.paths?.personal,
367
+ run: indexPersonal,
368
+ };
@@ -10,9 +10,9 @@
10
10
 
11
11
  import { readdirSync, readFileSync, statSync, existsSync } from "fs";
12
12
  import { join } from "path";
13
- import { checkPath, type IndexerContext } from "../indexer";
13
+ import { checkPath, type IndexerContext, type IndexerPlugin } from "../indexer";
14
14
 
15
- export async function indexReadmes(ctx: IndexerContext): Promise<void> {
15
+ async function indexReadmes(ctx: IndexerContext): Promise<void> {
16
16
  const projectsDir = ctx.config.paths.projects;
17
17
  if (!checkPath("readmes", "paths.projects", projectsDir)) return;
18
18
 
@@ -43,3 +43,15 @@ export async function indexReadmes(ctx: IndexerContext): Promise<void> {
43
43
  }
44
44
  }
45
45
  }
46
+
47
+ export const readmesPlugin: IndexerPlugin = {
48
+ manifest: {
49
+ name: "readmes",
50
+ description: "Indexes README.md files from project directories",
51
+ requiredConfig: ["paths.projects"],
52
+ optionalConfig: [],
53
+ rebuildExcluded: false,
54
+ },
55
+ canRun: (config) => !!config.paths?.projects,
56
+ run: indexReadmes,
57
+ };
@@ -12,7 +12,7 @@
12
12
 
13
13
  import { readdirSync, readFileSync } from "fs";
14
14
  import { join } from "path";
15
- import { checkPath, type IndexerContext } from "../indexer";
15
+ import { checkPath, type IndexerContext, type IndexerPlugin } from "../indexer";
16
16
 
17
17
  interface SessionData {
18
18
  project: string;
@@ -26,7 +26,7 @@ interface SessionData {
26
26
  lastTs: string;
27
27
  }
28
28
 
29
- export async function indexSessions(ctx: IndexerContext): Promise<void> {
29
+ async function indexSessions(ctx: IndexerContext): Promise<void> {
30
30
  // Check each event directory individually for clear diagnostics
31
31
  const eventDirs: string[] = [];
32
32
  for (const { name, path } of [
@@ -136,3 +136,15 @@ export async function indexSessions(ctx: IndexerContext): Promise<void> {
136
136
  });
137
137
  }
138
138
  }
139
+
140
+ export const sessionsPlugin: IndexerPlugin = {
141
+ manifest: {
142
+ name: "sessions",
143
+ description: "Indexes session event telemetry aggregated by session ID",
144
+ requiredConfig: ["paths.session_events", "paths.sable_events"],
145
+ optionalConfig: [],
146
+ rebuildExcluded: false,
147
+ },
148
+ canRun: (config) => !!config.paths?.session_events && !!config.paths?.sable_events,
149
+ run: indexSessions,
150
+ };
@@ -11,9 +11,9 @@
11
11
  */
12
12
 
13
13
  import { readFileSync } from "fs";
14
- import { checkPath, type IndexerContext } from "../indexer";
14
+ import { checkPath, type IndexerContext, type IndexerPlugin } from "../indexer";
15
15
 
16
- export async function indexTeachings(ctx: IndexerContext): Promise<void> {
16
+ async function indexTeachings(ctx: IndexerContext): Promise<void> {
17
17
  const logPath = `${ctx.config.paths.data}/log.jsonl`;
18
18
  if (
19
19
  !checkPath(
@@ -55,3 +55,15 @@ export async function indexTeachings(ctx: IndexerContext): Promise<void> {
55
55
  }
56
56
  }
57
57
  }
58
+
59
+ export const teachingsPlugin: IndexerPlugin = {
60
+ manifest: {
61
+ name: "teachings",
62
+ description: "Indexes teaching captures from log.jsonl",
63
+ requiredConfig: ["paths.data"],
64
+ optionalConfig: [],
65
+ rebuildExcluded: true,
66
+ },
67
+ canRun: (config) => !!config.paths?.data,
68
+ run: indexTeachings,
69
+ };
package/lib/info.ts CHANGED
@@ -5,9 +5,8 @@
5
5
  * Uses Bun's built-in SQLite for zero external dependencies.
6
6
  */
7
7
 
8
- import { Database } from "bun:sqlite";
9
8
  import { existsSync } from "fs";
10
- import { getDatabasePath } from "./db.js";
9
+ import { getDatabasePath, openDatabaseBasic } from "./db.js";
11
10
  import { projects as getProjects } from "./projects.js";
12
11
 
13
12
  export interface SourceInfo {
@@ -41,7 +40,7 @@ export function info(): InfoOutput {
41
40
  };
42
41
  }
43
42
 
44
- const db = new Database(dbPath, { readonly: true });
43
+ const db = openDatabaseBasic(true);
45
44
 
46
45
  try {
47
46
  // Get distinct sources with counts
package/lib/init.ts CHANGED
@@ -12,6 +12,7 @@
12
12
  import { existsSync, mkdirSync, writeFileSync } from "fs";
13
13
  import { homedir } from "os";
14
14
  import { Database } from "bun:sqlite";
15
+ import { getLoadablePath, load } from "sqlite-vec";
15
16
 
16
17
  interface DetectedPaths {
17
18
  obsidian?: string;
@@ -76,7 +77,7 @@ export async function runInit(homeOverride?: string): Promise<void> {
76
77
  }
77
78
 
78
79
  // 5. Initialize or verify database
79
- initDatabase(dbPath, detected.customSqlite, detected.sqliteVec);
80
+ initDatabase(dbPath, detected.customSqlite);
80
81
  }
81
82
 
82
83
  async function detectPaths(home: string): Promise<DetectedPaths> {
@@ -122,7 +123,15 @@ async function detectPaths(home: string): Promise<DetectedPaths> {
122
123
  function detectSqliteVec(): string | undefined {
123
124
  const ext = process.platform === "darwin" ? "dylib" : "so";
124
125
 
125
- // Strategy 1: brew --prefix sqlite-vec
126
+ // Strategy 1: npm package (preferred — self-resolves platform binary)
127
+ try {
128
+ const npmPath = getLoadablePath();
129
+ if (existsSync(npmPath)) return npmPath;
130
+ } catch {
131
+ // npm package not installed or getLoadablePath() failed — try fallbacks
132
+ }
133
+
134
+ // Strategy 2: brew --prefix sqlite-vec
126
135
  const result = Bun.spawnSync(["brew", "--prefix", "sqlite-vec"]);
127
136
  if (result.exitCode === 0) {
128
137
  const prefix = new TextDecoder().decode(result.stdout).trim();
@@ -130,11 +139,6 @@ function detectSqliteVec(): string | undefined {
130
139
  if (existsSync(candidate)) return candidate;
131
140
  }
132
141
 
133
- // Strategy 2: npm-installed sqlite-vec (node_modules)
134
- const platformPkg = `sqlite-vec-${process.platform}-${process.arch}`;
135
- const nmCandidate = `${import.meta.dir}/../node_modules/${platformPkg}/vec0.${ext}`;
136
- if (existsSync(nmCandidate)) return nmCandidate;
137
-
138
142
  // Strategy 3: common macOS/Linux system paths
139
143
  for (const p of [
140
144
  "/opt/homebrew/lib/sqlite-vec/vec0.dylib",
@@ -146,7 +150,7 @@ function detectSqliteVec(): string | undefined {
146
150
  if (existsSync(p)) return p;
147
151
  }
148
152
 
149
- // Strategy 4: pip-installed sqlite-vec (Python site-packages)
153
+ // Strategy 4: pip-installed sqlite-vec (Python site-packages — last resort)
150
154
  const pipGlob =
151
155
  process.platform === "darwin"
152
156
  ? "/opt/homebrew/lib/python3.*/site-packages/sqlite_vec/vec0.dylib"
@@ -189,7 +193,7 @@ ${pathLine("sable_events", detected.sableEvents ? "~/.local/share/sable/events"
189
193
  [database]
190
194
  sqlite = "${dbPath}"
191
195
  ${pathLine("custom_sqlite", detected.customSqlite)}
192
- ${pathLine("sqlite_vec", detected.sqliteVec)}
196
+ # sqlite_vec — no longer needed; loaded from npm package via load(db)
193
197
 
194
198
  [embedding]
195
199
  model = "nomic-ai/nomic-embed-text-v1.5"
@@ -197,11 +201,7 @@ dimensions = 768
197
201
  `;
198
202
  }
199
203
 
200
- function initDatabase(
201
- dbPath: string,
202
- customSqlite: string | undefined,
203
- vecPath: string | undefined,
204
- ): void {
204
+ function initDatabase(dbPath: string, customSqlite: string | undefined): void {
205
205
  if (customSqlite && existsSync(customSqlite)) {
206
206
  try {
207
207
  Database.setCustomSQLite(customSqlite);
@@ -215,21 +215,17 @@ function initDatabase(
215
215
  const db = new Database(dbPath);
216
216
  db.exec("PRAGMA journal_mode=WAL");
217
217
 
218
- // Load sqlite-vec for vec0 table creation
218
+ // Load sqlite-vec from npm package for vec0 table creation
219
219
  let vecLoaded = false;
220
- if (vecPath && existsSync(vecPath)) {
221
- try {
222
- db.loadExtension(vecPath);
223
- vecLoaded = true;
224
- } catch (e) {
225
- // Extension loading fails if custom_sqlite wasn't set (Bun's built-in
226
- // sqlite doesn't support extensions). Warn instead of crashing.
227
- console.warn(
228
- `sqlite-vec found at ${vecPath} but extension loading not supported — need custom_sqlite`,
229
- );
230
- }
231
- } else {
232
- console.warn("sqlite-vec not found — embeddings table not created");
220
+ try {
221
+ load(db);
222
+ vecLoaded = true;
223
+ } catch (e) {
224
+ // Extension loading fails if custom_sqlite wasn't set (Bun's built-in
225
+ // sqlite doesn't support extensions). Warn instead of crashing.
226
+ console.warn(
227
+ `sqlite-vec load failed — extension loading may not be supported without custom_sqlite`,
228
+ );
233
229
  }
234
230
 
235
231
  // Create tables (IF NOT EXISTS = idempotent)
package/lib/list.ts CHANGED
@@ -5,9 +5,8 @@
5
5
  * Uses Bun's built-in SQLite for zero external dependencies.
6
6
  */
7
7
 
8
- import { Database } from "bun:sqlite";
9
- import { existsSync } from "fs";
10
- import { getDatabasePath } from "./db.js";
8
+ import type { Database } from "bun:sqlite";
9
+ import { openDatabaseBasic } from "./db.js";
11
10
 
12
11
  // Source types - data sources that can be listed
13
12
  export type Source =
@@ -194,13 +193,7 @@ export function list(source: Source, options: ListOptions = {}): ListResult {
194
193
  );
195
194
  }
196
195
 
197
- const dbPath = getDatabasePath();
198
-
199
- if (!existsSync(dbPath)) {
200
- throw new Error(`Database not found: ${dbPath}. Run lore-db-init first.`);
201
- }
202
-
203
- const db = new Database(dbPath, { readonly: true });
196
+ const db = openDatabaseBasic(true);
204
197
 
205
198
  try {
206
199
  let entries: ListEntry[];
package/lib/projects.ts CHANGED
@@ -5,9 +5,8 @@
5
5
  * project-scoped sources.
6
6
  */
7
7
 
8
- import { Database } from "bun:sqlite";
9
8
  import { existsSync } from "fs";
10
- import { getDatabasePath } from "./db.js";
9
+ import { getDatabasePath, openDatabaseBasic } from "./db.js";
11
10
 
12
11
  const PROJECT_SOURCES = [
13
12
  "commits",
@@ -30,7 +29,7 @@ export function projects(): string[] {
30
29
  return [];
31
30
  }
32
31
 
33
- const db = new Database(dbPath, { readonly: true });
32
+ const db = openDatabaseBasic(true);
34
33
 
35
34
  try {
36
35
  const placeholders = PROJECT_SOURCES.map(() => "?").join(", ");
package/lib/realtime.ts CHANGED
@@ -15,12 +15,7 @@
15
15
  */
16
16
 
17
17
  import { Database } from "bun:sqlite";
18
- import {
19
- embedDocuments,
20
- MODEL_NAME,
21
- EMBEDDING_DIM,
22
- serializeEmbedding,
23
- } from "./semantic.js";
18
+ import { embedDocuments, MODEL_NAME, serializeEmbedding } from "./semantic.js";
24
19
  import { openDatabase } from "./db.js";
25
20
  import { hashContent, getCachedEmbedding, cacheEmbedding } from "./cache.js";
26
21
  import type { CaptureEvent } from "./capture.js";
@@ -262,7 +257,7 @@ async function embedWithCache(
262
257
  const embedding = embeddings[i];
263
258
 
264
259
  results[idx] = embedding;
265
- cacheEmbedding(db, hashContent(content), embedding, MODEL_NAME);
260
+ cacheEmbedding(db, hashContent(content), embedding, MODEL_NAME());
266
261
  }
267
262
  }
268
263