From eb30104732754a4012708521caa1e7ec1e169ca7 Mon Sep 17 00:00:00 2001 From: Brendan Allan Date: Mon, 6 Apr 2026 11:28:05 +0800 Subject: [PATCH] electron: bundle node-pty properly (#21148) --- package.json | 3 ++- .../desktop-electron/electron.vite.config.ts | 10 ++++++++++ packages/desktop-electron/package.json | 11 ++++++++++- packages/desktop-electron/scripts/prebuild.ts | 9 +++++++++ packages/desktop-electron/scripts/prepare.ts | 8 +------- packages/opencode/package.json | 2 +- packages/opencode/script/build-node.ts | 16 +--------------- 7 files changed, 34 insertions(+), 25 deletions(-) create mode 100644 packages/desktop-electron/scripts/prebuild.ts diff --git a/package.json b/package.json index 4ce36d17ec..07d37ccd50 100644 --- a/package.json +++ b/package.json @@ -71,7 +71,8 @@ "@solidjs/router": "0.15.4", "@solidjs/start": "https://pkg.pr.new/@solidjs/start@dfb2020", "solid-js": "1.9.10", - "vite-plugin-solid": "2.11.10" + "vite-plugin-solid": "2.11.10", + "@lydell/node-pty": "1.2.0-beta.10" } }, "devDependencies": { diff --git a/packages/desktop-electron/electron.vite.config.ts b/packages/desktop-electron/electron.vite.config.ts index b4244a74c7..73e8c4eda3 100644 --- a/packages/desktop-electron/electron.vite.config.ts +++ b/packages/desktop-electron/electron.vite.config.ts @@ -10,6 +10,8 @@ const channel = (() => { const OPENCODE_SERVER_DIST = "../opencode/dist/node" +const nodePtyPkg = `@lydell/node-pty-${process.platform}-${process.arch}` + export default defineConfig({ main: { define: { @@ -19,8 +21,16 @@ export default defineConfig({ rollupOptions: { input: { index: "src/main/index.ts" }, }, + externalizeDeps: { include: [nodePtyPkg] }, }, plugins: [ + { + name: "opencode:node-pty-narrower", + enforce: "pre", + resolveId(s) { + if (s === "@lydell/node-pty") return nodePtyPkg + }, + }, { name: "opencode:virtual-server-module", enforce: "pre", diff --git a/packages/desktop-electron/package.json b/packages/desktop-electron/package.json index 83a8666010..e4c05f0b3e 100644 --- a/packages/desktop-electron/package.json +++ b/packages/desktop-electron/package.json @@ -13,7 +13,7 @@ "typecheck": "tsgo -b", "predev": "bun ./scripts/predev.ts", "dev": "electron-vite dev", - "prebuild": "bun ./scripts/copy-icons.ts", + "prebuild": "bun ./scripts/prebuild.ts", "build": "electron-vite build", "preview": "electron-vite preview", "package": "electron-builder --config electron-builder.config.ts", @@ -45,6 +45,7 @@ }, "devDependencies": { "@actions/artifact": "4.0.0", + "@lydell/node-pty": "catalog:", "@types/bun": "catalog:", "@types/node": "catalog:", "@typescript/native-preview": "catalog:", @@ -53,5 +54,13 @@ "electron-vite": "^5", "typescript": "~5.6.2", "vite": "catalog:" + }, + "optionalDependencies": { + "@lydell/node-pty-darwin-arm64": "1.2.0-beta.10", + "@lydell/node-pty-darwin-x64": "1.2.0-beta.10", + "@lydell/node-pty-linux-arm64": "1.2.0-beta.10", + "@lydell/node-pty-linux-x64": "1.2.0-beta.10", + "@lydell/node-pty-win32-arm64": "1.2.0-beta.10", + "@lydell/node-pty-win32-x64": "1.2.0-beta.10" } } diff --git a/packages/desktop-electron/scripts/prebuild.ts b/packages/desktop-electron/scripts/prebuild.ts new file mode 100644 index 0000000000..46a2475ea5 --- /dev/null +++ b/packages/desktop-electron/scripts/prebuild.ts @@ -0,0 +1,9 @@ +#!/usr/bin/env bun +import { $ } from "bun" + +import { resolveChannel } from "./utils" + +const channel = resolveChannel() +await $`bun ./scripts/copy-icons.ts ${channel}` + +await $`cd ../opencode && bun script/build-node.ts` diff --git a/packages/desktop-electron/scripts/prepare.ts b/packages/desktop-electron/scripts/prepare.ts index 0097d62a48..0dfd5a35cb 100755 --- a/packages/desktop-electron/scripts/prepare.ts +++ b/packages/desktop-electron/scripts/prepare.ts @@ -1,15 +1,9 @@ #!/usr/bin/env bun -import { $ } from "bun" - import { Script } from "@opencode-ai/script" -import { resolveChannel } from "./utils" -const channel = resolveChannel() -await $`bun ./scripts/copy-icons.ts ${channel}` +await import("./prebuild") const pkg = await Bun.file("./package.json").json() pkg.version = Script.version await Bun.write("./package.json", JSON.stringify(pkg, null, 2) + "\n") console.log(`Updated package.json version to ${Script.version}`) - -await $`cd ../opencode && bun script/build-node.ts` diff --git a/packages/opencode/package.json b/packages/opencode/package.json index b88ba974f2..6b81696256 100644 --- a/packages/opencode/package.json +++ b/packages/opencode/package.json @@ -106,7 +106,7 @@ "@hono/node-ws": "1.3.0", "@hono/standard-validator": "0.1.5", "@hono/zod-validator": "catalog:", - "@lydell/node-pty": "1.2.0-beta.10", + "@lydell/node-pty": "catalog:", "@modelcontextprotocol/sdk": "1.27.1", "@npmcli/arborist": "9.4.0", "@octokit/graphql": "9.0.2", diff --git a/packages/opencode/script/build-node.ts b/packages/opencode/script/build-node.ts index b32f57eae5..709c8f5abb 100755 --- a/packages/opencode/script/build-node.ts +++ b/packages/opencode/script/build-node.ts @@ -1,6 +1,5 @@ #!/usr/bin/env bun -import { $ } from "bun" import { Script } from "@opencode-ai/script" import fs from "fs" import path from "path" @@ -9,15 +8,6 @@ import { fileURLToPath } from "url" const __filename = fileURLToPath(import.meta.url) const __dirname = path.dirname(__filename) const dir = path.resolve(__dirname, "..") -const root = path.resolve(dir, "../..") - -function linker(): "hoisted" | "isolated" { - // jsonc-parser is only declared in packages/opencode, so its install location - // tells us whether Bun used a hoisted or isolated workspace layout. - if (fs.existsSync(path.join(dir, "node_modules", "jsonc-parser"))) return "isolated" - if (fs.existsSync(path.join(root, "node_modules", "jsonc-parser"))) return "hoisted" - throw new Error("Could not detect Bun linker from jsonc-parser") -} process.chdir(dir) @@ -51,17 +41,13 @@ const migrations = await Promise.all( ) console.log(`Loaded ${migrations.length} migrations`) -const link = linker() - -await $`bun install --linker=${link} --os="*" --cpu="*" @lydell/node-pty@1.2.0-beta.10` - await Bun.build({ target: "node", entrypoints: ["./src/node.ts"], outdir: "./dist/node", format: "esm", sourcemap: "linked", - external: ["jsonc-parser"], + external: ["jsonc-parser", "@lydell/node-pty"], define: { OPENCODE_MIGRATIONS: JSON.stringify(migrations), OPENCODE_CHANNEL: `'${Script.channel}'`,