From 0a7e51db03631213d0151672b7804a5ae7e19c62 Mon Sep 17 00:00:00 2001 From: Quickbeard Date: Mon, 10 Aug 2026 11:42:15 +0700 Subject: [PATCH 1/2] fix(desktop): install the Electron binary before dev Electron 42 dropped the postinstall hook that downloaded the platform binary and exposes it as an `install-electron` bin the consumer has to call, so `bun install` left `node_modules/electron` without a `dist/` and `bun dev:desktop` died with `Error: Electron uninstall` before the app could launch. `predev` now runs the installer; it short-circuits once the binary matches package.json, so repeat runs are free. Co-Authored-By: Claude Opus 5 (1M context) --- DIVERGENCES.md | 1 + README.md | 18 ++++++++++++++++++ packages/desktop/scripts/predev.ts | 6 ++++++ 3 files changed, 25 insertions(+) diff --git a/DIVERGENCES.md b/DIVERGENCES.md index 8b3632680b..bc577a15d3 100644 --- a/DIVERGENCES.md +++ b/DIVERGENCES.md @@ -191,6 +191,7 @@ from the squash message first, or use a plain merge. | `script/publish.ts` | The `if (Script.release)` block calling `packages/desktop/scripts/finalize-latest-{json,yml}.ts` removed, replaced by a comment. | Both finalizers existed to assemble update metadata into a GitHub release, which the fork no longer publishes to. electron-builder already writes a correct per-platform `latest*.yml` next to each installer, and the fork builds one arch per platform (macOS is universal — see the universal-builds row), so there is nothing left to merge. | Keep removed. If upstream adds further desktop release steps here, drop them unless they target the bucket. | | `packages/desktop/scripts/finalize-latest-json.ts`, `packages/desktop/scripts/finalize-latest-yml.ts` | Deleted. | Both `gh release upload` into a GitHub release the fork does not use. `finalize-latest-yml.ts` merged per-arch `latest*.yml` from an upstream build matrix the fork does not run; `finalize-latest-json.ts` additionally built a Tauri-style `latest.json` signed with `@tauri-apps/cli signer` that nothing in the Electron updater path ever reads, and had gone stale besides — it hardcoded `opencode-desktop-mac-{x64,arm64}.app.tar.gz`, an artifact name and format this fork never produces. Leaving them in place is a trap: they look like the release path and upload to the wrong place. | Keep deleted (`git rm` the upstream side of modify/delete conflicts). If a future build matrix produces two `latest.yml` files for one platform (Windows x64 + arm64), write a bucket-targeted merge step rather than restoring these. | | `packages/desktop/src/renderer/index.tsx` | Desktop notification icon `https://opencode.ai/favicon-96x96-v3.png` → the relative `./favicon-96x96-v3.png`. The renderer's `publicDir` is `packages/app/public`, whose `favicon-96x96-v3.png` symlinks to the rebranded `packages/ui/src/assets/favicon/` mark, so the file is emitted next to `index.html` and resolves against the renderer origin (`oc://renderer/` packaged, the vite dev server otherwise) — the same asset and the same relative form `src/renderer/index.html` already uses for ``. | A desktop app should not reach out to a remote host to draw its own notification icon (it fails offline and leaks a request per notification), and the remote file is upstream-branded while the bundled one is the codev mark. | Keep our relative path. If upstream changes the URL, re-point it at the bundled asset rather than taking a new remote host. `packages/app/src/entry.tsx` and `pages/layout/helpers.ts` keep their remote `opencode.ai/favicon*` sources — same bug class, not yet fixed. | +| `packages/desktop/scripts/predev.ts` | Runs `bun run install-electron` before the existing icon copy and node-sidecar build. | `bun dev:desktop` was dead on a fresh clone: Electron 42 removed the `postinstall` hook that downloaded the platform binary and exposes it as an `install-electron` bin the consumer must call (electron 41's manifest still had `"postinstall": "node install.js"`; 42.3.3's has no `scripts` field at all), so `bun install` leaves `node_modules/electron` with no `dist/` and `electron-vite dev` aborts with `Error: Electron uninstall` from `getElectronPath`. `predev` is the right hook rather than the root `postinstall`: only someone actually launching the desktop app pays the ~100 MB download, and `install.js` short-circuits once `dist/version` and `path.txt` match, so repeat runs cost nothing. Not added to `prebuild`/`package` — `electron-vite build` never spawns Electron, and `electron-builder` fetches its own copy through `@electron/get`. | Keep our installer line at the top; take upstream's other steps. Drop the line if upstream adds its own binary-install step or pins Electron back below 42. | | `packages/ui/src/assets/favicon/` (favicon-v3.svg, favicon-v3.ico, site.webmanifest, favicon-96x96-v3.png, apple-touch-icon-v3.png, web-app-manifest-192/512.png) | New codev mark: the blocky "C" in brand red `#ee0033` on a white tile, generated from the same geometry as the app icon by `packages/desktop/scripts/generate-icons.ts` (4x5 grid, one-unit stroke, unit = 120/1024, corner radius 229/1024); `favicon-v3.svg` is the hand-written 512-unit source of that geometry. The tab and `.ico` icons keep the rounded tile so they read as an app icon; `apple-touch-icon-v3.png` and the two maskable `web-app-manifest-*` icons are square and full-bleed, because iOS and PWA launchers apply their own mask and a pre-rounded icon leaves transparent corners that render black. Manifest name "CoDev Code"/"codev"; its `theme_color`/`background_color` stay `#080808` — those describe the PWA's chrome and splash, not the icon. **Was `#00cdcd` on a dark tile** until this row was rewritten: PR #10 pinned the favicon to the then-cyan TUI banner accent, that banner later moved to the navy/red wordmark, and the favicon was left behind as the only cyan in the tree — visibly so on desktop, where the dock icon was red while the window and notification icons were cyan. | Every surface that draws the mark should draw the same mark: the dock icon, the tab, notifications, the `codev --mini` badge and the landing page icon are now one geometry in one red. Cyan on `#131010` was the higher-contrast tile at 16px (~9.4:1 versus red's ~4.2:1) — a real cost, accepted so the brand reads consistently. | Keep our assets (binary: take ours wholesale). Regenerate with the script rather than hand-editing, and edit `icons/icon.svg` + `favicon-v3.svg` together if the geometry ever changes. | | `AGENTS.md` | Default-branch note: `dev` → `main` (single merged line; upstream has two lines saying local `main` may not exist); added fork bullets requiring every upstream-file change to get a `DIVERGENCES.md` row (and matching en + es doc updates) in the same PR, and pointing agents at this file's Divergence policy (prefer config/plugins, then `packages/codev-*`, upstream edits last) and Syncing with upstream sections | The fork's default branch is `main` (see the workflow-triggers row); agents kept basing diffs on a nonexistent `dev`. Agents edit upstream files without recording the divergence — and don't apply the placement policy or sync runbook — unless the instructions file says to. | Keep our lines; take upstream's other guidance. | | `README.md` | Replaced with fork README | Fork identity, sync + divergence policy. | Keep ours entirely. | diff --git a/README.md b/README.md index 1b1573be5c..daf752607b 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,24 @@ The upstream sync procedure and the divergence policy live in [DIVERGENCES.md](D ```sh bun install bun dev # run the CLI from source +bun dev:desktop # run the Electron desktop app from source bun typecheck # all packages, via turbo cd packages/opencode && bun test # tests must run from a package dir, never the repo root ``` + +### `bun dev:desktop` fails with "Error: Electron uninstall" + +`bun install` does not download the Electron binary. Electron 42 dropped the `postinstall` +hook that used to fetch it and ships it as an `install-electron` bin you have to invoke +yourself, so `node_modules/electron` arrives with no `dist/` and `electron-vite dev` aborts +before it can launch anything. `predev` now runs the installer, so `bun dev:desktop` fixes +itself on the next run; to fetch the binary on its own (~100 MB, cached in +`~/.cache/electron`), run: + +```sh +bun --cwd packages/desktop run install-electron +``` + +The installer is idempotent — it exits immediately once `node_modules/electron/dist` matches +the version in `package.json`. If a download was interrupted and left a partial `dist/`, +delete `node_modules/electron/dist` and `node_modules/electron/path.txt` and run it again. diff --git a/packages/desktop/scripts/predev.ts b/packages/desktop/scripts/predev.ts index 4f0d3340ff..90b22de5bc 100644 --- a/packages/desktop/scripts/predev.ts +++ b/packages/desktop/scripts/predev.ts @@ -1,5 +1,11 @@ import { $ } from "bun" +// Electron 42 dropped the postinstall hook that downloaded the platform binary and exposes +// it as the `install-electron` bin instead, so `bun install` alone leaves node_modules/electron +// without a dist/ and `electron-vite dev` dies with "Error: Electron uninstall". The installer +// exits immediately once the binary matches package.json, so this is a no-op after the first run. +await $`bun run install-electron` + await $`bun ./scripts/copy-icons.ts ${process.env.CODEV_CHANNEL ?? "dev"}` await $`cd ../opencode && bun script/build-node.ts` From 69c92ac2f785f4859ff19c32e02defd13cd3ea09 Mon Sep 17 00:00:00 2001 From: Quickbeard Date: Wed, 12 Aug 2026 15:05:34 +0700 Subject: [PATCH 2/2] docs: drop the Electron install troubleshooting section The predev hook now installs the binary automatically, so the failure the section documented no longer reaches a fresh clone. Co-Authored-By: Claude Opus 5 (1M context) --- README.md | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/README.md b/README.md index daf752607b..cd436e0b48 100644 --- a/README.md +++ b/README.md @@ -61,20 +61,3 @@ bun dev:desktop # run the Electron desktop app from source bun typecheck # all packages, via turbo cd packages/opencode && bun test # tests must run from a package dir, never the repo root ``` - -### `bun dev:desktop` fails with "Error: Electron uninstall" - -`bun install` does not download the Electron binary. Electron 42 dropped the `postinstall` -hook that used to fetch it and ships it as an `install-electron` bin you have to invoke -yourself, so `node_modules/electron` arrives with no `dist/` and `electron-vite dev` aborts -before it can launch anything. `predev` now runs the installer, so `bun dev:desktop` fixes -itself on the next run; to fetch the binary on its own (~100 MB, cached in -`~/.cache/electron`), run: - -```sh -bun --cwd packages/desktop run install-electron -``` - -The installer is idempotent — it exits immediately once `node_modules/electron/dist` matches -the version in `package.json`. If a download was interrupted and left a partial `dist/`, -delete `node_modules/electron/dist` and `node_modules/electron/path.txt` and run it again.