From fafbc29316e7240b348db9e91e7a8e97cd803aef Mon Sep 17 00:00:00 2001 From: Luke Parker <10430890+Hona@users.noreply.github.com> Date: Thu, 12 Mar 2026 13:19:28 +1000 Subject: [PATCH 1/5] fix(ci): use dynamic bun cache path for cross-platform support (#17120) --- .github/actions/setup-bun/action.yml | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/.github/actions/setup-bun/action.yml b/.github/actions/setup-bun/action.yml index 3f06da5197..f53f20fcdb 100644 --- a/.github/actions/setup-bun/action.yml +++ b/.github/actions/setup-bun/action.yml @@ -3,14 +3,6 @@ description: "Setup Bun with caching and install dependencies" runs: using: "composite" steps: - - name: Cache Bun dependencies - uses: actions/cache@v4 - with: - path: ~/.bun/install/cache - key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lockb') }} - restore-keys: | - ${{ runner.os }}-bun- - - name: Get baseline download URL id: bun-url shell: bash @@ -31,6 +23,19 @@ runs: bun-version-file: ${{ !steps.bun-url.outputs.url && 'package.json' || '' }} bun-download-url: ${{ steps.bun-url.outputs.url }} + - name: Get cache directory + id: cache + shell: bash + run: echo "dir=$(bun pm cache)" >> "$GITHUB_OUTPUT" + + - name: Cache Bun dependencies + uses: actions/cache@v4 + with: + path: ${{ steps.cache.outputs.dir }} + key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lock') }} + restore-keys: | + ${{ runner.os }}-bun- + - name: Install setuptools for distutils compatibility run: python3 -m pip install setuptools || pip install setuptools || true shell: bash From 9fb12a906eb8b1ef5f346623d11bd86689f926b1 Mon Sep 17 00:00:00 2001 From: Dax Raad Date: Wed, 11 Mar 2026 23:24:26 -0400 Subject: [PATCH 2/5] core: remove external sourcemap generation to reduce build artifacts --- packages/opencode/script/build.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/opencode/script/build.ts b/packages/opencode/script/build.ts index 4ff610862d..8d84b206d9 100755 --- a/packages/opencode/script/build.ts +++ b/packages/opencode/script/build.ts @@ -174,7 +174,6 @@ for (const item of targets) { conditions: ["browser"], tsconfig: "./tsconfig.json", plugins: [solidPlugin], - sourcemap: "external", compile: { autoloadBunfig: false, autoloadDotenv: false, From db7bafe9177b40b22060867838d17d53cf29d81b Mon Sep 17 00:00:00 2001 From: Luke Parker <10430890+Hona@users.noreply.github.com> Date: Thu, 12 Mar 2026 13:55:16 +1000 Subject: [PATCH 3/5] fix(app): guard comment accessor in message timeline (#17126) --- .../src/pages/session/message-timeline.tsx | 54 ++++++++++--------- 1 file changed, 29 insertions(+), 25 deletions(-) diff --git a/packages/app/src/pages/session/message-timeline.tsx b/packages/app/src/pages/session/message-timeline.tsx index cb9c61918a..ab919b70e5 100644 --- a/packages/app/src/pages/session/message-timeline.tsx +++ b/packages/app/src/pages/session/message-timeline.tsx @@ -778,31 +778,35 @@ export function MessageTimeline(props: {
{(commentAccessor: () => MessageComment) => { - const comment = createMemo(() => commentAccessor()) - return ( -
-
- - {getFilename(comment().path)} - - {(selection) => ( - - {selection().startLine === selection().endLine - ? `:${selection().startLine}` - : `:${selection().startLine}-${selection().endLine}`} - - )} - -
-
- {comment().comment} -
-
- ) - }} + const comment = createMemo(() => commentAccessor()) + return ( + + {(c) => ( +
+
+ + {getFilename(c().path)} + + {(selection) => ( + + {selection().startLine === selection().endLine + ? `:${selection().startLine}` + : `:${selection().startLine}-${selection().endLine}`} + + )} + +
+
+ {c().comment} +
+
+ )} +
+ ) + }}
From 1d7fcd40b45548e20b43e29cd16b83899c8f6eb1 Mon Sep 17 00:00:00 2001 From: "opencode-agent[bot]" Date: Thu, 12 Mar 2026 03:56:04 +0000 Subject: [PATCH 4/5] chore: generate --- .../src/pages/session/message-timeline.tsx | 58 +++++++++---------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/packages/app/src/pages/session/message-timeline.tsx b/packages/app/src/pages/session/message-timeline.tsx index ab919b70e5..e64f5a7fd6 100644 --- a/packages/app/src/pages/session/message-timeline.tsx +++ b/packages/app/src/pages/session/message-timeline.tsx @@ -778,35 +778,35 @@ export function MessageTimeline(props: {
{(commentAccessor: () => MessageComment) => { - const comment = createMemo(() => commentAccessor()) - return ( - - {(c) => ( -
-
- - {getFilename(c().path)} - - {(selection) => ( - - {selection().startLine === selection().endLine - ? `:${selection().startLine}` - : `:${selection().startLine}-${selection().endLine}`} - - )} - -
-
- {c().comment} -
-
- )} -
- ) - }} + const comment = createMemo(() => commentAccessor()) + return ( + + {(c) => ( +
+
+ + {getFilename(c().path)} + + {(selection) => ( + + {selection().startLine === selection().endLine + ? `:${selection().startLine}` + : `:${selection().startLine}-${selection().endLine}`} + + )} + +
+
+ {c().comment} +
+
+ )} +
+ ) + }}
From 54e7baa6cfff86627e5555842560b4a20e4be424 Mon Sep 17 00:00:00 2001 From: Luke Parker <10430890+Hona@users.noreply.github.com> Date: Thu, 12 Mar 2026 14:19:44 +1000 Subject: [PATCH 5/5] fix(desktop-electron): fix resource loading under file:// protocol (#17125) --- .../desktop-electron/electron.vite.config.ts | 2 +- .../src/renderer/html.test.ts | 62 +++++++++++++++++++ .../desktop-electron/src/renderer/index.html | 17 +++-- .../src/renderer/loading.html | 17 +++-- packages/desktop-electron/tsconfig.json | 3 +- packages/ui/src/components/font.tsx | 7 ++- 6 files changed, 86 insertions(+), 22 deletions(-) create mode 100644 packages/desktop-electron/src/renderer/html.test.ts diff --git a/packages/desktop-electron/electron.vite.config.ts b/packages/desktop-electron/electron.vite.config.ts index 80c1d6b704..6903d5ed20 100644 --- a/packages/desktop-electron/electron.vite.config.ts +++ b/packages/desktop-electron/electron.vite.config.ts @@ -27,7 +27,7 @@ export default defineConfig({ }, renderer: { plugins: [appPlugin], - publicDir: "../app/public", + publicDir: "../../../app/public", root: "src/renderer", build: { rollupOptions: { diff --git a/packages/desktop-electron/src/renderer/html.test.ts b/packages/desktop-electron/src/renderer/html.test.ts new file mode 100644 index 0000000000..bd8281c2fb --- /dev/null +++ b/packages/desktop-electron/src/renderer/html.test.ts @@ -0,0 +1,62 @@ +import { describe, expect, test } from "bun:test" +import { join, dirname, resolve } from "node:path" +import { existsSync } from "node:fs" +import { fileURLToPath } from "node:url" + +const dir = dirname(fileURLToPath(import.meta.url)) +const root = resolve(dir, "../..") + +const html = async (name: string) => Bun.file(join(dir, name)).text() + +/** + * Electron loads renderer HTML via `win.loadFile()` which uses the `file://` + * protocol. Absolute paths like `src="/foo.js"` resolve to the filesystem root + * (e.g. `file:///C:/foo.js` on Windows) instead of relative to the app bundle. + * + * All local resource references must use relative paths (`./`). + */ +describe("electron renderer html", () => { + for (const name of ["index.html", "loading.html"]) { + describe(name, () => { + test("script src attributes use relative paths", async () => { + const content = await html(name) + const srcs = [...content.matchAll(/\bsrc=["']([^"']+)["']/g)].map((m) => m[1]) + for (const src of srcs) { + expect(src).not.toMatch(/^\/[^/]/) + } + }) + + test("link href attributes use relative paths", async () => { + const content = await html(name) + const hrefs = [...content.matchAll(/]+href=["']([^"']+)["']/g)].map((m) => m[1]) + for (const href of hrefs) { + expect(href).not.toMatch(/^\/[^/]/) + } + }) + + test("no web manifest link (not applicable in Electron)", async () => { + const content = await html(name) + expect(content).not.toContain('rel="manifest"') + }) + }) + } +}) + +/** + * Vite resolves `publicDir` relative to `root`, not the config file. + * This test reads the actual values from electron.vite.config.ts to catch + * regressions where the publicDir path no longer resolves correctly + * after the renderer root is accounted for. + */ +describe("electron vite publicDir", () => { + test("configured publicDir resolves to a directory with oc-theme-preload.js", async () => { + const config = await Bun.file(join(root, "electron.vite.config.ts")).text() + const pub = config.match(/publicDir:\s*["']([^"']+)["']/) + const rendererRoot = config.match(/root:\s*["']([^"']+)["']/) + expect(pub).not.toBeNull() + expect(rendererRoot).not.toBeNull() + const resolved = resolve(root, rendererRoot![1], pub![1]) + expect(existsSync(resolved)).toBe(true) + expect(existsSync(join(resolved, "oc-theme-preload.js"))).toBe(true) + }) +}) diff --git a/packages/desktop-electron/src/renderer/index.html b/packages/desktop-electron/src/renderer/index.html index 1756408196..dd8675ee6b 100644 --- a/packages/desktop-electron/src/renderer/index.html +++ b/packages/desktop-electron/src/renderer/index.html @@ -4,20 +4,19 @@ OpenCode - - - - - + + + + - - - + + +
- + diff --git a/packages/desktop-electron/src/renderer/loading.html b/packages/desktop-electron/src/renderer/loading.html index 8def243b49..ae3725af61 100644 --- a/packages/desktop-electron/src/renderer/loading.html +++ b/packages/desktop-electron/src/renderer/loading.html @@ -4,20 +4,19 @@ OpenCode - - - - - + + + + - - - + + +
- + diff --git a/packages/desktop-electron/tsconfig.json b/packages/desktop-electron/tsconfig.json index 160f6c3fd2..9637fe03dd 100644 --- a/packages/desktop-electron/tsconfig.json +++ b/packages/desktop-electron/tsconfig.json @@ -18,5 +18,6 @@ "types": ["vite/client", "node", "electron"] }, "references": [{ "path": "../app" }], - "include": ["src", "package.json"] + "include": ["src", "package.json"], + "exclude": ["src/**/*.test.ts"] } diff --git a/packages/ui/src/components/font.tsx b/packages/ui/src/components/font.tsx index bcb8863c89..f735747a49 100644 --- a/packages/ui/src/components/font.tsx +++ b/packages/ui/src/components/font.tsx @@ -1,3 +1,4 @@ +import { Show } from "solid-js" import { Style, Link } from "@solidjs/meta" import inter from "../assets/fonts/inter.woff2" import ibmPlexMonoRegular from "../assets/fonts/ibm-plex-mono.woff2" @@ -166,8 +167,10 @@ export const Font = () => { } ${monoNerdCss} `} - - + + + + ) }