mirror of
https://github.com/anomalyco/opencode.git
synced 2026-09-06 20:04:37 +00:00
fix(desktop): stabilize bundled dev and process exit (#46523)
This commit is contained in:
parent
1bd1f72bcf
commit
48c8a308b9
8 changed files with 98 additions and 10 deletions
5
bun.lock
5
bun.lock
|
|
@ -418,7 +418,7 @@
|
|||
"electron-window-state": "^5.0.3",
|
||||
},
|
||||
"devDependencies": {
|
||||
"@brendonovich/vite-plugin-opencode": "0.1.1",
|
||||
"@brendonovich/vite-plugin-opencode": "0.1.3",
|
||||
"@effect/platform-node": "catalog:",
|
||||
"@lydell/node-pty": "catalog:",
|
||||
"@opencode-ai/app": "workspace:*",
|
||||
|
|
@ -1050,6 +1050,7 @@
|
|||
"@npmcli/agent@4.0.2": "patches/@npmcli%2Fagent@4.0.2.patch",
|
||||
"@silvia-odwyer/photon-node@0.3.4": "patches/@silvia-odwyer%2Fphoton-node@0.3.4.patch",
|
||||
"solid-js@1.9.15": "patches/solid-js@1.9.15.patch",
|
||||
"vite@8.2.2": "patches/vite@8.2.2.patch",
|
||||
"@ff-labs/fff-bun@0.10.5": "patches/@ff-labs%2Ffff-bun@0.10.5.patch",
|
||||
"@ai-sdk/google@3.0.73": "patches/@ai-sdk%2Fgoogle@3.0.73.patch",
|
||||
"@dnd-kit/dom@0.5.0": "patches/@dnd-kit%2Fdom@0.5.0.patch",
|
||||
|
|
@ -1596,7 +1597,7 @@
|
|||
|
||||
"@braintree/sanitize-url": ["@braintree/sanitize-url@7.1.2", "", {}, "sha512-jigsZK+sMF/cuiB7sERuo9V7N9jx+dhmHHnQyDSVdpZwVutaBu7WvNYqMDLSgFgfB30n452TP3vjDAvFC973mA=="],
|
||||
|
||||
"@brendonovich/vite-plugin-opencode": ["@brendonovich/vite-plugin-opencode@0.1.1", "", { "dependencies": { "@babel/core": "^7.29.0", "@opencode-ai/client": "0.0.0-beta-18050" }, "peerDependencies": { "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-aPG0ct8ctxAqndbNOx7NW0GhU6QY6sOUfi/DaKqH9c5WdxICSsUop6uSkJwPDHP9WpN9eg0dd2D2qwYpG6UdHw=="],
|
||||
"@brendonovich/vite-plugin-opencode": ["@brendonovich/vite-plugin-opencode@0.1.3", "", { "dependencies": { "@babel/core": "^7.29.0", "@opencode-ai/client": "0.0.0-beta-18050" }, "peerDependencies": { "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-iiIwlNoycOMUiaUzL1ZirLapCG3WY8cg9hSj4KgE/JYIWgqauoHikIlfUt7SdMqqGIkb4iZu6I1MxgDDJaRfBA=="],
|
||||
|
||||
"@bruits/satteri-darwin-arm64": ["@bruits/satteri-darwin-arm64@0.9.5", "", { "os": "darwin", "cpu": "arm64" }, "sha512-iw4nZgx9v30lWo/MTngQqi1pI78KI0DnkSm+lVJGYdmPLgAyDNJigVhpG42/Iq55A6c1Ll8q66ljyyRiQUxwow=="],
|
||||
|
||||
|
|
|
|||
|
|
@ -178,6 +178,7 @@
|
|||
"@pierre/trees@1.0.0-beta.4": "patches/@pierre%2Ftrees@1.0.0-beta.4.patch",
|
||||
"@modelcontextprotocol/sdk@1.29.0": "patches/@modelcontextprotocol%2Fsdk@1.29.0.patch",
|
||||
"@tanstack/virtual-core@3.17.8": "patches/@tanstack%2Fvirtual-core@3.17.8.patch",
|
||||
"@ff-labs/fff-bun@0.10.5": "patches/@ff-labs%2Ffff-bun@0.10.5.patch"
|
||||
"@ff-labs/fff-bun@0.10.5": "patches/@ff-labs%2Ffff-bun@0.10.5.patch",
|
||||
"vite@8.2.2": "patches/vite@8.2.2.patch"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ const require = __cjs_mod__.createRequire(import.meta.url);
|
|||
"import.meta.env.OPENCODE_VERSION": JSON.stringify(process.env.OPENCODE_VERSION),
|
||||
"import.meta.env.VITE_OPENCODE_CHANNEL": JSON.stringify(channel),
|
||||
},
|
||||
plugins: [{ ...picker, transformIndexHtml: undefined }, appPlugin, sentry],
|
||||
plugins: [picker, appPlugin, sentry],
|
||||
publicDir: "../../../app/public",
|
||||
root: "src/renderer",
|
||||
build: {
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
"electron-window-state": "^5.0.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@brendonovich/vite-plugin-opencode": "0.1.1",
|
||||
"@brendonovich/vite-plugin-opencode": "0.1.3",
|
||||
"@effect/platform-node": "catalog:",
|
||||
"@lydell/node-pty": "catalog:",
|
||||
"@opencode-ai/app": "workspace:*",
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { $ } from "bun"
|
||||
import { join } from "node:path"
|
||||
import { fileURLToPath } from "node:url"
|
||||
import { downloadCliToResources, windowsify } from "./utils"
|
||||
|
||||
type ServerSource = { type: "build" } | { type: "download"; version: string }
|
||||
|
|
@ -43,13 +44,18 @@ async function prepareServer(source: ServerSource) {
|
|||
if (source.type === "download")
|
||||
return downloadCliToResources(source.version, windowsify("resources/opencode-cli-dev"))
|
||||
process.env.OPENCODE_DESKTOP_CLI_DEV = join(import.meta.dirname, "../../cli")
|
||||
await $`bun run --cwd ${process.env.OPENCODE_DESKTOP_CLI_DEV} --define=OPENCODE_VERSION=${JSON.stringify(process.env.OPENCODE_VERSION)} src/index.ts --version`
|
||||
if (process.platform !== "win32") return
|
||||
process.env.OPENCODE_DESKTOP_WSL_CLI_BUILD = join(import.meta.dirname, "../../cli/script/build.ts")
|
||||
process.env.OPENCODE_DESKTOP_WSL_CLI_OUTPUT = join(import.meta.dirname, "../resources/opencode-cli-wsl")
|
||||
}
|
||||
|
||||
async function startDesktop(args: string[]) {
|
||||
await $`electron-vite dev ${args}`
|
||||
// Bun's implicit spawn environment omits values set during preparation.
|
||||
process.exitCode = await Bun.spawn(
|
||||
["node", fileURLToPath(new URL("../bin/electron-vite.js", import.meta.resolve("electron-vite"))), "dev", ...args],
|
||||
{ env: process.env, stdio: ["inherit", "inherit", "inherit"] },
|
||||
).exited
|
||||
}
|
||||
|
||||
await main()
|
||||
|
|
|
|||
2
packages/desktop/src/main/env.d.ts
vendored
2
packages/desktop/src/main/env.d.ts
vendored
|
|
@ -1,5 +1,3 @@
|
|||
declare module "virtual:vite-opencode-picker/client"
|
||||
|
||||
interface ImportMetaEnv {
|
||||
readonly OPENCODE_CHANNEL: string
|
||||
readonly OPENCODE_VERSION?: string
|
||||
|
|
|
|||
|
|
@ -20,5 +20,3 @@ startDesktopMenu(api)
|
|||
startDeepLinks(api)
|
||||
|
||||
render(() => <DesktopApp api={api} updater={updater} version={version} />, root)
|
||||
|
||||
if (import.meta.env.DEV) void import("virtual:vite-opencode-picker/client")
|
||||
|
|
|
|||
84
patches/vite@8.2.2.patch
Normal file
84
patches/vite@8.2.2.patch
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
diff --git a/dist/client/bundledDevClient.mjs b/dist/client/bundledDevClient.mjs
|
||||
index 4c4a3f6f884795001ffbae43cd3c3d6bf84169dc..b5e80b68140824e7460439b125eec8ec3fa14e8a 100644
|
||||
--- a/dist/client/bundledDevClient.mjs
|
||||
+++ b/dist/client/bundledDevClient.mjs
|
||||
@@ -1796,6 +1796,13 @@ function injectQuery(url, queryToInject) {
|
||||
if (typeof DevRuntime !== "undefined") {
|
||||
var _ref;
|
||||
class ViteDevRuntime extends DevRuntime {
|
||||
+ payloadDelivered(filename) {
|
||||
+ transport.send({
|
||||
+ type: "custom",
|
||||
+ event: "vite:bundled-dev:payload-delivered",
|
||||
+ data: { filename }
|
||||
+ });
|
||||
+ }
|
||||
createModuleHotContext(moduleId) {
|
||||
const ctx = new BundledDevHMRContext(bundledDevHmrClient, moduleId);
|
||||
ctx._internal = {
|
||||
diff --git a/dist/node/chunks/node.js b/dist/node/chunks/node.js
|
||||
index 87cfa480c3d4132f9dd1b74c6c1bbe2b90385d3f..83da417e7b9c380d06b7679d3fbfaeed998f5277 100644
|
||||
--- a/dist/node/chunks/node.js
|
||||
+++ b/dist/node/chunks/node.js
|
||||
@@ -26309,7 +26309,6 @@ function memoryFilesMiddleware(server) {
|
||||
const mime = lookup(filePath);
|
||||
if (mime) res.setHeader("Content-Type", mime);
|
||||
for (const name in headers) res.setHeader(name, headers[name]);
|
||||
- res.on("finish", () => bundledDev.markPayloadDelivered(filePath));
|
||||
return res.end(file.source);
|
||||
}
|
||||
next();
|
||||
@@ -26339,7 +26338,6 @@ function triggerLazyBundlingMiddleware(server) {
|
||||
}
|
||||
if (result == null) return next();
|
||||
res.setHeader("Content-Type", "application/javascript");
|
||||
- res.on("finish", () => bundledDev.markPayloadDelivered(result.filename));
|
||||
return res.end(result.code);
|
||||
};
|
||||
}
|
||||
@@ -35155,6 +35153,9 @@ var BundledDev = class {
|
||||
this.clients.setupIfNeeded(client, payload.clientId);
|
||||
this.devEngine.registerClient(payload.clientId);
|
||||
});
|
||||
+ this.environment.hot.on("vite:bundled-dev:payload-delivered", (payload) => {
|
||||
+ this.markPayloadDelivered(payload.filename);
|
||||
+ });
|
||||
this.environment.hot.on("vite:client:connect", (_payload, client) => {
|
||||
if (this.lastBuildError) {
|
||||
debug$1?.("REPLAY: replaying last build error to newly connected client");
|
||||
@@ -35287,12 +35288,11 @@ var BundledDev = class {
|
||||
debug$1?.(`TRIGGER-LAZY: trigger lazy bundling for module ${moduleId} for client ${clientId}`);
|
||||
const result = await this.devEngine.compileEntry(moduleId, clientId);
|
||||
this.pendingPayloadFilenames.add(result.filename);
|
||||
- return result;
|
||||
+ return { filename: result.filename, code: result.code + payloadDeliveredAck(result.filename) };
|
||||
}
|
||||
/**
|
||||
- * Called by the serving middlewares when the response for a payload completed.
|
||||
- * Only delivered payloads are recorded on the server's per-client ship map, so
|
||||
- * later chunks may omit a module only if the payload carrying it was delivered.
|
||||
+ * Called after the client evaluates a payload and registers its factories.
|
||||
+ * HTTP response completion alone does not mean the factories are available.
|
||||
*
|
||||
* Note: the payload filename is unique across all clients.
|
||||
*/
|
||||
@@ -35364,7 +35364,7 @@ var BundledDev = class {
|
||||
code: typeof hmrOutput.code === "string" ? "[code]" : hmrOutput.code
|
||||
});
|
||||
this.pendingPayloadFilenames.add(hmrOutput.filename);
|
||||
- this.memoryFiles.set(hmrOutput.filename, { source: hmrOutput.code + "\n; export {}" });
|
||||
+ this.memoryFiles.set(hmrOutput.filename, { source: hmrOutput.code + payloadDeliveredAck(hmrOutput.filename) + "\n; export {}" });
|
||||
if (hmrOutput.sourcemapFilename && hmrOutput.sourcemap) this.memoryFiles.set(hmrOutput.sourcemapFilename, { source: hmrOutput.sourcemap });
|
||||
client.send({
|
||||
type: "bundled-dev-update",
|
||||
@@ -35407,6 +35407,10 @@ var Clients = class {
|
||||
}
|
||||
}
|
||||
};
|
||||
+// Backport https://github.com/vitejs/vite/pull/23373.
|
||||
+function payloadDeliveredAck(filename) {
|
||||
+ return `\n;__rolldown_runtime__.payloadDelivered(${JSON.stringify(filename)});`;
|
||||
+}
|
||||
function debounce(time, cb) {
|
||||
let timer;
|
||||
return () => {
|
||||
Loading…
Add table
Add a link
Reference in a new issue