clawmem 0.15.0 → 0.15.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docs/troubleshooting.md +9 -0
- package/package.json +1 -1
- package/src/store.ts +74 -9
package/docs/troubleshooting.md
CHANGED
|
@@ -12,6 +12,15 @@ Common issues when running ClawMem with hooks, MCP server, or OpenClaw plugin. O
|
|
|
12
12
|
- If both snap bun (`/snap/bin/bun`) and native bun (`~/.bun/bin/bun`) are installed, `which bun` may return the snap version. Direct `bun -e` or `bun run` commands will use the wrong binary.
|
|
13
13
|
- Fix: The `bin/clawmem` wrapper handles this automatically. For manual commands, use `~/.bun/bin/bun` explicitly or add `~/.bun/bin` to PATH before `/snap/bin`.
|
|
14
14
|
|
|
15
|
+
**macOS: `bootstrap` / `doctor` fails with "does not support dynamic extension loading" (sqlite-vec on macOS)**
|
|
16
|
+
- `clawmem bootstrap` (or `clawmem doctor`) fails at the database step because macOS's built-in SQLite — which Bun uses by default — is compiled without extension-loading support, so the `sqlite-vec` vector extension cannot load. Symptom: `✗ Database: ... This build of sqlite3 does not support dynamic extension loading`. Yoloshii/ClawMem#20.
|
|
17
|
+
- Fix: install an extension-capable SQLite via Homebrew, then re-run bootstrap:
|
|
18
|
+
```bash
|
|
19
|
+
brew install sqlite
|
|
20
|
+
clawmem bootstrap ~/notes --name notes
|
|
21
|
+
```
|
|
22
|
+
- ClawMem auto-detects Homebrew's SQLite at the standard prefixes (`/opt/homebrew` on Apple Silicon, `/usr/local` on Intel) and at `brew --prefix sqlite` for non-standard prefixes — installing it is all that's required, no env var or config. If it still fails after `brew install sqlite`, run `brew reinstall sqlite` and confirm `ls $(brew --prefix sqlite)/lib/libsqlite3.dylib` resolves.
|
|
23
|
+
|
|
15
24
|
## Embedding & GPU
|
|
16
25
|
|
|
17
26
|
**"Local model download blocked" error**
|
package/package.json
CHANGED
package/src/store.ts
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
import { Database } from "bun:sqlite";
|
|
16
16
|
import { Glob } from "bun";
|
|
17
|
-
import { realpathSync } from "node:fs";
|
|
17
|
+
import { realpathSync, existsSync } from "node:fs";
|
|
18
18
|
import * as sqliteVec from "sqlite-vec";
|
|
19
19
|
import {
|
|
20
20
|
LlamaCpp,
|
|
@@ -290,14 +290,79 @@ export function toVirtualPath(db: Database, absolutePath: string): string | null
|
|
|
290
290
|
// Database initialization
|
|
291
291
|
// =============================================================================
|
|
292
292
|
|
|
293
|
-
// On macOS,
|
|
293
|
+
// On macOS, Apple's built-in libsqlite3 — which Bun uses by default — is
|
|
294
|
+
// compiled WITHOUT extension-loading support, so sqliteVec.load() fails with
|
|
295
|
+
// "This build of sqlite3 does not support dynamic extension loading" (Issue #20).
|
|
296
|
+
// Point Bun at an extension-capable SQLite (Homebrew's) via setCustomSQLite()
|
|
297
|
+
// BEFORE the first Database is opened. setCustomSQLite() must receive a path
|
|
298
|
+
// that EXISTS — an invalid path hard-crashes Bun (oven-sh/bun#18811) — so every
|
|
299
|
+
// candidate is existence-checked first. The resolved path (or null) is recorded
|
|
300
|
+
// so loadVecExtension() can emit an actionable error when no extension-capable
|
|
301
|
+
// SQLite is installed, instead of the cryptic extension-loading failure.
|
|
302
|
+
|
|
303
|
+
/** macOS only: the extension-capable SQLite activated via setCustomSQLite, or null if none was found. */
|
|
304
|
+
let macosCustomSqlitePath: string | null = null;
|
|
305
|
+
|
|
294
306
|
if (process.platform === "darwin") {
|
|
295
|
-
const
|
|
307
|
+
const candidates = [
|
|
308
|
+
"/opt/homebrew/opt/sqlite/lib/libsqlite3.dylib", // Homebrew (Apple Silicon)
|
|
309
|
+
"/usr/local/opt/sqlite/lib/libsqlite3.dylib", // Homebrew (Intel)
|
|
310
|
+
];
|
|
311
|
+
// For a non-standard Homebrew prefix, ask brew directly — but only when the
|
|
312
|
+
// standard paths are absent, so the common case pays no subprocess cost.
|
|
313
|
+
if (!candidates.some(p => existsSync(p))) {
|
|
314
|
+
try {
|
|
315
|
+
const brew = Bun.spawnSync(["brew", "--prefix", "sqlite"], { stdout: "pipe", stderr: "ignore" });
|
|
316
|
+
const prefix = brew.success ? brew.stdout.toString().trim() : "";
|
|
317
|
+
if (prefix) candidates.push(`${prefix}/lib/libsqlite3.dylib`);
|
|
318
|
+
} catch { /* brew not installed — nothing more to probe */ }
|
|
319
|
+
}
|
|
320
|
+
for (const candidate of candidates) {
|
|
321
|
+
if (!existsSync(candidate)) continue;
|
|
322
|
+
try {
|
|
323
|
+
Database.setCustomSQLite(candidate);
|
|
324
|
+
macosCustomSqlitePath = candidate;
|
|
325
|
+
break;
|
|
326
|
+
} catch { /* not usable — try the next candidate */ }
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* Translate a sqlite-vec load failure into an actionable error on macOS, where
|
|
332
|
+
* the default system SQLite cannot load extensions (Issue #20). Pure + exported
|
|
333
|
+
* for tests: pass `platform` / `foundPath` explicitly to exercise either branch.
|
|
334
|
+
* Non-macOS, or any unrelated error, is returned unchanged.
|
|
335
|
+
*/
|
|
336
|
+
export function explainVecLoadError(
|
|
337
|
+
err: unknown,
|
|
338
|
+
platform: string = process.platform,
|
|
339
|
+
foundPath: string | null = macosCustomSqlitePath,
|
|
340
|
+
): Error {
|
|
341
|
+
const original = err instanceof Error ? err : new Error(String(err));
|
|
342
|
+
const isExtensionError = /does not support dynamic extension loading/i.test(original.message);
|
|
343
|
+
if (platform !== "darwin" || !isExtensionError) return original;
|
|
344
|
+
|
|
345
|
+
const detail = foundPath === null
|
|
346
|
+
? "No Homebrew SQLite was found at the standard locations (/opt/homebrew or /usr/local)."
|
|
347
|
+
: `A custom SQLite was set from ${foundPath}, but it still cannot load extensions — try 'brew reinstall sqlite'.`;
|
|
348
|
+
return new Error(
|
|
349
|
+
"ClawMem could not load the sqlite-vec extension: macOS's built-in SQLite is " +
|
|
350
|
+
"compiled without extension support.\n" +
|
|
351
|
+
"Fix: install an extension-capable SQLite with Homebrew, then re-run:\n" +
|
|
352
|
+
" brew install sqlite\n" +
|
|
353
|
+
`${detail}\n` +
|
|
354
|
+
"More detail: docs/troubleshooting.md (\"Bun runtime\" -> sqlite-vec on macOS), Yoloshii/ClawMem#20.\n" +
|
|
355
|
+
`Original error: ${original.message}`,
|
|
356
|
+
);
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
/** Load the sqlite-vec extension, surfacing an actionable error on macOS (Issue #20). */
|
|
360
|
+
function loadVecExtension(db: Database): void {
|
|
296
361
|
try {
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
}
|
|
362
|
+
sqliteVec.load(db);
|
|
363
|
+
} catch (err) {
|
|
364
|
+
throw explainVecLoadError(err);
|
|
365
|
+
}
|
|
301
366
|
}
|
|
302
367
|
|
|
303
368
|
function initializeDatabase(db: Database): void {
|
|
@@ -312,7 +377,7 @@ function initializeDatabase(db: Database): void {
|
|
|
312
377
|
// well within the 30s Stop hook timeout. createStore() resets to operational
|
|
313
378
|
// value (5000ms or opts.busyTimeout) after DDL completes. Issue #13.
|
|
314
379
|
db.exec("PRAGMA busy_timeout = 15000");
|
|
315
|
-
|
|
380
|
+
loadVecExtension(db);
|
|
316
381
|
db.exec("PRAGMA journal_mode = WAL");
|
|
317
382
|
db.exec("PRAGMA foreign_keys = ON");
|
|
318
383
|
|
|
@@ -1283,7 +1348,7 @@ export function createStore(dbPath?: string, opts?: { readonly?: boolean; busyTi
|
|
|
1283
1348
|
// production caller in this repo currently passes readonly:true,
|
|
1284
1349
|
// but the ordering invariant should hold regardless. Issue #13.
|
|
1285
1350
|
db.exec(`PRAGMA busy_timeout = ${opts?.busyTimeout ?? 5000}`);
|
|
1286
|
-
|
|
1351
|
+
loadVecExtension(db);
|
|
1287
1352
|
db.exec("PRAGMA journal_mode = WAL");
|
|
1288
1353
|
db.exec("PRAGMA query_only = ON");
|
|
1289
1354
|
}
|