Compare commits

...

1 Commits

Author SHA1 Message Date
xingyue f93e6901ac fix(init): auto-verify and retry better-sqlite3 native build
After pnpm install, verify better-sqlite3 actually loads by spawning
a test process. If it fails, rebuild up to 2 times. On final failure,
print actionable fix commands instead of a vague warning.

Closes #44
2026-04-23 08:11:44 +08:00
+41 -8
View File
@@ -219,6 +219,23 @@ const initWorkspaceCommand = defineCommand({
},
});
async function tryRequireSqlite(nerveRoot: string): Promise<boolean> {
try {
const modulePath = join(nerveRoot, "node_modules", "better-sqlite3");
// Use a child process to test if the native module loads
const { execFile } = await import("node:child_process");
const { promisify } = await import("node:util");
const execFileAsync = promisify(execFile);
await execFileAsync("node", ["-e", `require(${JSON.stringify(modulePath)})`], {
cwd: nerveRoot,
timeout: 10_000,
});
return true;
} catch {
return false;
}
}
async function runInitWorkspace(force: boolean): Promise<void> {
const nerveRoot = getNerveRoot();
@@ -242,20 +259,36 @@ async function runInitWorkspace(force: boolean): Promise<void> {
);
process.stdout.write("Installing dependencies…\n");
const { cmd, installArgs } = await detectPackageManager();
try {
const { cmd, installArgs } = await detectPackageManager();
await runCommand(cmd, installArgs, nerveRoot);
} catch {
process.stdout.write(
`⚠️ Install failed. Try manually:\n cd ${nerveRoot} && ${cmd} ${installArgs.join(" ")}\n`,
);
}
process.stdout.write("Rebuilding native module better-sqlite3…\n");
try {
await runCommand(cmd, ["rebuild", "better-sqlite3"], nerveRoot);
} catch {
// Verify better-sqlite3 native module — rebuild up to 2 times if broken
const sqlitePath = join(nerveRoot, "node_modules", "better-sqlite3");
if (existsSync(sqlitePath)) {
for (let attempt = 1; attempt <= 2; attempt++) {
if (await tryRequireSqlite(nerveRoot)) break;
process.stdout.write(
"⚠️ rebuild better-sqlite3 failed — if the daemon fails to start, reinstall from the workspace directory.\n",
`${attempt === 1 ? "Building" : "Retrying build of"} native module better-sqlite3 (attempt ${attempt}/2)…\n`,
);
try {
await runCommand(cmd, ["rebuild", "better-sqlite3"], nerveRoot);
} catch {
// will be caught by the verify below
}
}
if (!(await tryRequireSqlite(nerveRoot))) {
process.stdout.write(
`⚠️ better-sqlite3 native module is not working. The daemon will fail to start.\n` +
` Fix: cd ${nerveRoot} && ${cmd} rebuild better-sqlite3\n` +
` Or: npm install --build-from-source better-sqlite3\n`,
);
}
} catch {
process.stdout.write("⚠️ Install failed — you may need to install dependencies manually.\n");
}
if (!existsSync(join(nerveRoot, ".git"))) {