Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 9 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"prepublishOnly": "npm run build && npm test"
},
"dependencies": {
"better-sqlite3": "^11.0.0",
"better-sqlite3": "^12.4.1",
"chalk": "^5.3.0",
"commander": "^12.1.0",
"node-cron": "^3.0.3",
Expand Down
28 changes: 27 additions & 1 deletion src/storage/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,39 @@ import { homedir } from 'node:os';

const DEFAULT_DB_PATH = join(homedir(), '.youagent', 'youagent.db');

/**
* Detect failures caused by a missing or incompatible better-sqlite3
* native binding, as opposed to ordinary database errors.
*/
function isNativeModuleError(err: unknown): boolean {
if (!(err instanceof Error)) return false;
const code = (err as NodeJS.ErrnoException).code;
if (code === 'ERR_DLOPEN_FAILED' || code === 'MODULE_NOT_FOUND') return true;
return /better_sqlite3\.node|Could not locate the bindings file|NODE_MODULE_VERSION/i.test(
err.message
);
}

export class AgentDatabase {
private db: Database.Database;

constructor(dbPath?: string) {
const resolvedPath = dbPath ?? DEFAULT_DB_PATH;
mkdirSync(dirname(resolvedPath), { recursive: true });
this.db = new Database(resolvedPath);
try {
this.db = new Database(resolvedPath);
} catch (err) {
if (isNativeModuleError(err)) {
throw new Error(
'youagent could not load its SQLite engine (better-sqlite3). ' +
'The native module is missing or was built for a different Node.js version.\n' +
'To fix, run: npm rebuild better-sqlite3\n' +
'Or reinstall youagent on Node.js 20 or newer so a prebuilt binary can be used.\n' +
`Original error: ${err instanceof Error ? err.message : String(err)}`
);
}
throw err;
}

// Enable WAL mode for better concurrent read performance.
this.db.pragma('journal_mode = WAL');
Expand Down
Loading