diff --git a/packages/cli/src/commands/init.ts b/packages/cli/src/commands/init.ts index 9206817..5dcf188 100644 --- a/packages/cli/src/commands/init.ts +++ b/packages/cli/src/commands/init.ts @@ -219,6 +219,23 @@ const initWorkspaceCommand = defineCommand({ }, }); +async function tryRequireSqlite(nerveRoot: string): Promise { + 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 { const nerveRoot = getNerveRoot(); @@ -242,20 +259,36 @@ async function runInitWorkspace(force: boolean): Promise { ); 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"))) {