diff --git a/CHANGELOG.md b/CHANGELOG.md index f2cdb7d6..5c013f06 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,16 @@ --- +## [2.6.10] — 2026-03-17 + +> Windows fix: better-sqlite3 prebuilt download without node-gyp/Python/MSVC (#426). + +### 🐛 Bug Fixes + +- **fix(install/#426)**: On Windows, `npm install -g omniroute` used to fail with `better_sqlite3.node is not a valid Win32 application` because the bundled native binary was compiled for Linux. Adds **Strategy 1.5** to `scripts/postinstall.mjs`: uses `@mapbox/node-pre-gyp install --fallback-to-build=false` (bundled within `better-sqlite3`) to download the correct prebuilt binary for the current OS/arch without requiring any build tools (no node-gyp, no Python, no MSVC). Falls back to `npm rebuild` only if the download fails. Adds platform-specific error messages with clear manual fix instructions. + +--- + ## [2.6.9] — 2026-03-17 > CI fixes (t11 any-budget), bug fix #409 (file attachments via Copilot+Claude), release workflow correction. diff --git a/docs/openapi.yaml b/docs/openapi.yaml index 638a801e..e8e6f78a 100644 --- a/docs/openapi.yaml +++ b/docs/openapi.yaml @@ -1,7 +1,7 @@ openapi: 3.1.0 info: title: OmniRoute API - version: 2.6.9 + version: 2.6.10 description: | OmniRoute is a local-first AI API proxy router. It provides an OpenAI-compatible endpoint that routes requests to multiple AI providers with load balancing, diff --git a/package-lock.json b/package-lock.json index 510d2c37..f5ffb708 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "omniroute", - "version": "2.6.9", + "version": "2.6.10", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "omniroute", - "version": "2.6.9", + "version": "2.6.10", "hasInstallScript": true, "license": "MIT", "workspaces": [ diff --git a/package.json b/package.json index 95a3fd86..7ea8bad7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "omniroute", - "version": "2.6.9", + "version": "2.6.10", "description": "Smart AI Router with auto fallback — route to FREE & cheap models, zero downtime. Works with Cursor, Cline, Claude Desktop, Codex, and any OpenAI-compatible tool.", "type": "module", "bin": { diff --git a/scripts/postinstall.mjs b/scripts/postinstall.mjs index 6873ac41..612a9ae7 100644 --- a/scripts/postinstall.mjs +++ b/scripts/postinstall.mjs @@ -14,6 +14,7 @@ * * Fixes: https://github.com/diegosouzapw/OmniRoute/issues/129 * Fixes: https://github.com/diegosouzapw/OmniRoute/issues/321 + * Fixes: https://github.com/diegosouzapw/OmniRoute/issues/426 */ import { existsSync, copyFileSync, mkdirSync } from "node:fs"; @@ -80,8 +81,54 @@ if (existsSync(rootBinary)) { } } +// Strategy 1.5: Use node-pre-gyp to download the correct prebuilt binary +// This works on Windows without requiring node-gyp, Python, or MSVC. +// better-sqlite3 ships prebuilts for win32-x64, win32-arm64, darwin-x64/arm64. +console.log(" 📥 Attempting to download prebuilt binary via node-pre-gyp..."); +try { + const { execSync } = await import("node:child_process"); + // better-sqlite3 bundles @mapbox/node-pre-gyp — use it directly + const preGypBin = join( + ROOT, + "app", + "node_modules", + ".bin", + process.platform === "win32" ? "node-pre-gyp.cmd" : "node-pre-gyp" + ); + const preGypFallback = join( + ROOT, + "app", + "node_modules", + "@mapbox", + "node-pre-gyp", + "bin", + "node-pre-gyp" + ); + const preGypCmd = existsSync(preGypBin) ? preGypBin : preGypFallback; + + if (existsSync(preGypCmd)) { + execSync(`"${process.execPath}" "${preGypCmd}" install --fallback-to-build=false`, { + cwd: join(ROOT, "app", "node_modules", "better-sqlite3"), + stdio: "inherit", + timeout: 60_000, + }); + mkdirSync(dirname(appBinary), { recursive: true }); + try { + process.dlopen({ exports: {} }, appBinary); + console.log(" ✅ Prebuilt binary downloaded and loaded successfully!\n"); + process.exit(0); + } catch (loadErr) { + console.warn(` ⚠️ Downloaded binary failed to load: ${loadErr.message}`); + } + } else { + console.warn(" ⚠️ node-pre-gyp not found, skipping prebuilt download."); + } +} catch (err) { + console.warn(` ⚠️ node-pre-gyp download failed: ${err.message.split("\n")[0]}`); +} + // Strategy 2: Fall back to npm rebuild (may work if build tools are available) -console.log(" ⚠️ Root binary not available or incompatible, attempting npm rebuild..."); +console.log(" ⚠️ Attempting npm rebuild (requires build tools)..."); try { const { execSync } = await import("node:child_process"); @@ -103,14 +150,23 @@ try { } } -// If nothing worked, warn but don't fail the install — let the package stay -// installed so users can fix manually or use the pre-flight check in the CLI -console.warn(" ⚠️ Could not fix better-sqlite3 native module automatically."); +// If nothing worked, warn but don't fail the install +console.warn("\n ⚠️ Could not fix better-sqlite3 native module automatically."); console.warn(" The server may not start correctly."); -console.warn(" Try manually:"); -console.warn(` cd ${join(ROOT, "app")} && npm rebuild better-sqlite3`); -if (process.platform === "darwin") { +console.warn(" Manual fix options:"); +if (process.platform === "win32") { + console.warn(" Option A (easiest — no build tools needed):"); + console.warn(` cd "${join(ROOT, "app", "node_modules", "better-sqlite3")}"`); + console.warn(" npx @mapbox/node-pre-gyp install --fallback-to-build=false"); + console.warn(" Option B (requires Build Tools for Visual Studio):"); + console.warn(` cd "${join(ROOT, "app")}" && npm rebuild better-sqlite3`); + console.warn(" Install from: https://visualstudio.microsoft.com/visual-cpp-build-tools/"); + console.warn(" Also ensure Python is installed: https://python.org"); +} else if (process.platform === "darwin") { + console.warn(` cd ${join(ROOT, "app")} && npm rebuild better-sqlite3`); console.warn(" If build tools are missing: xcode-select --install"); +} else { + console.warn(` cd ${join(ROOT, "app")} && npm rebuild better-sqlite3`); } console.warn("");