diff --git a/bin/oh-my-opencode.js b/bin/oh-my-opencode.js index 4ad39550b9..cacca506fc 100644 --- a/bin/oh-my-opencode.js +++ b/bin/oh-my-opencode.js @@ -3,8 +3,9 @@ // Wrapper script that detects platform and spawns the correct binary import { spawnSync } from "node:child_process"; +import { existsSync } from "node:fs"; import { createRequire } from "node:module"; -import { getPlatformPackage, getBinaryPath } from "./platform.js"; +import { getPlatformPackage, getBinaryPath, getFallbackCliPath } from "./platform.js"; const require = createRequire(import.meta.url); @@ -46,11 +47,36 @@ function main() { try { binPath = require.resolve(binRelPath); } catch { + const fallbackCliPath = getFallbackCliPath(); + if (existsSync(fallbackCliPath)) { + const fallbackResult = spawnSync("bun", [fallbackCliPath, ...process.argv.slice(2)], { + stdio: "inherit", + }); + + if (!fallbackResult.error) { + if (fallbackResult.signal) { + const signalNum = fallbackResult.signal === "SIGTERM" ? 15 : + fallbackResult.signal === "SIGKILL" ? 9 : + fallbackResult.signal === "SIGINT" ? 2 : 1; + process.exit(128 + signalNum); + } + + process.exit(fallbackResult.status ?? 1); + } + + if (fallbackResult.error?.code !== "ENOENT") { + console.error(`\noh-my-opencode: Failed to execute Bun fallback.`); + console.error(`Error: ${fallbackResult.error.message}\n`); + process.exit(2); + } + } + console.error(`\noh-my-opencode: Platform binary not installed.`); console.error(`\nYour platform: ${platform}-${arch}${libcFamily === "musl" ? "-musl" : ""}`); console.error(`Expected package: ${pkg}`); console.error(`\nTo fix, run:`); - console.error(` npm install ${pkg}\n`); + console.error(` npm install ${pkg}`); + console.error(`\nOr install Bun to use the JS fallback.\n`); process.exit(1); } diff --git a/bin/platform.js b/bin/platform.js index ac728d3c81..180812c016 100644 --- a/bin/platform.js +++ b/bin/platform.js @@ -1,6 +1,8 @@ // bin/platform.js // Shared platform detection module - used by wrapper and postinstall +import { fileURLToPath } from "node:url"; + /** * Get the platform-specific package name * @param {{ platform: string, arch: string, libcFamily?: string | null }} options @@ -36,3 +38,7 @@ export function getBinaryPath(pkg, platform) { const ext = platform === "win32" ? ".exe" : ""; return `${pkg}/bin/oh-my-opencode${ext}`; } + +export function getFallbackCliPath() { + return fileURLToPath(new URL("../dist/cli/index.js", import.meta.url)); +} diff --git a/bin/platform.test.ts b/bin/platform.test.ts index 7755099299..765bf8a460 100644 --- a/bin/platform.test.ts +++ b/bin/platform.test.ts @@ -1,6 +1,6 @@ // bin/platform.test.ts import { describe, expect, test } from "bun:test"; -import { getPlatformPackage, getBinaryPath } from "./platform.js"; +import { getPlatformPackage, getBinaryPath, getFallbackCliPath } from "./platform.js"; describe("getPlatformPackage", () => { // #region Darwin platforms @@ -146,3 +146,13 @@ describe("getBinaryPath", () => { expect(result).toBe("oh-my-opencode-linux-x64/bin/oh-my-opencode"); }); }); + +describe("getFallbackCliPath", () => { + test("returns path to dist/cli/index.js", () => { + // #given fallback cli path + const result = getFallbackCliPath(); + + // #then returns dist cli path + expect(result).toMatch(/dist[\\/]+cli[\\/]+index\.js$/); + }); +});