From bc3c3442e3b98f8c3d9813352f19376e65d9f6f0 Mon Sep 17 00:00:00 2001 From: Chris Tunbridge Date: Sat, 20 Dec 2025 08:24:40 -0700 Subject: [PATCH 01/37] feat(vscode): add attach mode for connecting to existing server --- sdks/vscode/README.md | 10 ++++++++++ sdks/vscode/package.json | 22 +++++++++++++++++++++- sdks/vscode/src/extension.ts | 30 +++++++++++++++++++++--------- 3 files changed, 52 insertions(+), 10 deletions(-) diff --git a/sdks/vscode/README.md b/sdks/vscode/README.md index 1ca5078ce5c..974501eac46 100644 --- a/sdks/vscode/README.md +++ b/sdks/vscode/README.md @@ -13,6 +13,16 @@ This extension requires the [opencode CLI](https://opencode.ai) to be installed - **Context Awareness**: Automatically share your current selection or tab with opencode. - **File Reference Shortcuts**: Use `Cmd+Option+K` (Mac) or `Alt+Ctrl+K` (Linux/Windows) to insert file references. For example, `@File#L37-42`. +## Configuration + +| Setting | Default | Description | +| ------------------------- | ----------- | ------------------------------------------------------------------------ | +| `opencode.attach.enabled` | `false` | Attach to an existing OpenCode server instead of spawning a new instance | +| `opencode.attach.host` | `localhost` | Host of the OpenCode server | +| `opencode.attach.port` | `4096` | Port of the OpenCode server | + +**Attach Mode**: Useful when OpenCode is already running (e.g., in cloud workspaces like Coder). Enable attach mode to connect to the existing server instead of starting a new one. + ## Support This is an early release. If you encounter issues or have feedback, please create an issue at https://github.com/sst/opencode/issues. diff --git a/sdks/vscode/package.json b/sdks/vscode/package.json index 25916d486bd..9d90b92d989 100644 --- a/sdks/vscode/package.json +++ b/sdks/vscode/package.json @@ -78,7 +78,27 @@ "win": "ctrl+alt+K", "linux": "ctrl+alt+K" } - ] + ], + "configuration": { + "title": "OpenCode", + "properties": { + "opencode.attach.enabled": { + "type": "boolean", + "default": false, + "description": "Attach to an existing OpenCode server instead of spawning a new instance" + }, + "opencode.attach.host": { + "type": "string", + "default": "localhost", + "description": "Host of the OpenCode server to attach to" + }, + "opencode.attach.port": { + "type": "number", + "default": 4096, + "description": "Port of the OpenCode server to attach to" + } + } + } }, "scripts": { "vscode:prepublish": "bun run package", diff --git a/sdks/vscode/src/extension.ts b/sdks/vscode/src/extension.ts index 63d8d332e40..0758128a47f 100644 --- a/sdks/vscode/src/extension.ts +++ b/sdks/vscode/src/extension.ts @@ -34,8 +34,12 @@ export function activate(context: vscode.ExtensionContext) { if (terminal.name === TERMINAL_NAME) { // @ts-ignore - const port = terminal.creationOptions.env?.["_EXTENSION_OPENCODE_PORT"] - port ? await appendPrompt(parseInt(port), fileRef) : terminal.sendText(fileRef) + const env = terminal.creationOptions.env + const port = env?.["_EXTENSION_OPENCODE_PORT"] + const host = env?.["_EXTENSION_OPENCODE_HOST"] ?? "localhost" + if (port) { + await appendPrompt(parseInt(port), fileRef, host) + } terminal.show() } }) @@ -43,8 +47,14 @@ export function activate(context: vscode.ExtensionContext) { context.subscriptions.push(openTerminalDisposable, addFilepathDisposable) async function openTerminal() { - // Create a new terminal in split screen - const port = Math.floor(Math.random() * (65535 - 16384 + 1)) + 16384 + const config = vscode.workspace.getConfiguration("opencode") + const attachEnabled = config.get("attach.enabled", false) + const attachHost = config.get("attach.host", "localhost") + const attachPort = config.get("attach.port", 4096) + + const host = attachEnabled ? attachHost : "localhost" + const port = attachEnabled ? attachPort : Math.floor(Math.random() * (65535 - 16384 + 1)) + 16384 + const terminal = vscode.window.createTerminal({ name: TERMINAL_NAME, iconPath: { @@ -57,12 +67,14 @@ export function activate(context: vscode.ExtensionContext) { }, env: { _EXTENSION_OPENCODE_PORT: port.toString(), + _EXTENSION_OPENCODE_HOST: host, OPENCODE_CALLER: "vscode", }, }) terminal.show() - terminal.sendText(`opencode --port ${port}`) + const command = attachEnabled ? `opencode attach http://${host}:${port}` : `opencode --port ${port}` + terminal.sendText(command) const fileRef = getActiveFile() if (!fileRef) { @@ -75,7 +87,7 @@ export function activate(context: vscode.ExtensionContext) { do { await new Promise((resolve) => setTimeout(resolve, 200)) try { - await fetch(`http://localhost:${port}/app`) + await fetch(`http://${host}:${port}/app`) connected = true break } catch (e) {} @@ -85,13 +97,13 @@ export function activate(context: vscode.ExtensionContext) { // If connected, append the prompt to the terminal if (connected) { - await appendPrompt(port, `In ${fileRef}`) + await appendPrompt(port, `In ${fileRef}`, host) terminal.show() } } - async function appendPrompt(port: number, text: string) { - await fetch(`http://localhost:${port}/tui/append-prompt`, { + async function appendPrompt(port: number, text: string, host = "localhost") { + await fetch(`http://${host}:${port}/tui/append-prompt`, { method: "POST", headers: { "Content-Type": "application/json", From 049bc4d56af7a3088d70d3520ced5ac56175a604 Mon Sep 17 00:00:00 2001 From: Chris Tunbridge Date: Sat, 20 Dec 2025 14:02:37 -0700 Subject: [PATCH 02/37] Apply suggestions from code review Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- sdks/vscode/src/extension.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sdks/vscode/src/extension.ts b/sdks/vscode/src/extension.ts index 0758128a47f..6281ae78a2f 100644 --- a/sdks/vscode/src/extension.ts +++ b/sdks/vscode/src/extension.ts @@ -39,8 +39,16 @@ export function activate(context: vscode.ExtensionContext) { const host = env?.["_EXTENSION_OPENCODE_HOST"] ?? "localhost" if (port) { await appendPrompt(parseInt(port), fileRef, host) + const env = terminal.creationOptions.env + const port = env?.["_EXTENSION_OPENCODE_PORT"] + const host = env?.["_EXTENSION_OPENCODE_HOST"] ?? "localhost" + if (port) { + await appendPrompt(parseInt(port), fileRef, host) + } else { + terminal.sendText(fileRef) } terminal.show() + terminal.show() } }) From 41f70db146b5f6e1c534065b440fe504aca79fd1 Mon Sep 17 00:00:00 2001 From: Adam <2363879+adamdotdevin@users.noreply.github.com> Date: Sat, 20 Dec 2025 19:52:12 -0600 Subject: [PATCH 03/37] feat(desktop): new layout --- packages/desktop/src/context/layout.tsx | 27 +- packages/desktop/src/pages/session.tsx | 464 ++++++++++-------------- 2 files changed, 202 insertions(+), 289 deletions(-) diff --git a/packages/desktop/src/context/layout.tsx b/packages/desktop/src/context/layout.tsx index 0d3de568358..8bfc8aa217b 100644 --- a/packages/desktop/src/context/layout.tsx +++ b/packages/desktop/src/context/layout.tsx @@ -46,8 +46,8 @@ export const { use: useLayout, provider: LayoutProvider } = createSimpleContext( opened: false, height: 280, }, - review: { - state: "pane" as "pane" | "tab", + session: { + width: 600, }, sessionTabs: {} as Record, }), @@ -156,13 +156,14 @@ export const { use: useLayout, provider: LayoutProvider } = createSimpleContext( setStore("terminal", "height", height) }, }, - review: { - state: createMemo(() => store.review?.state ?? "closed"), - pane() { - setStore("review", "state", "pane") - }, - tab() { - setStore("review", "state", "tab") + session: { + width: createMemo(() => store.session?.width ?? 600), + resize(width: number) { + if (!store.session) { + setStore("session", { width }) + } else { + setStore("session", "width", width) + } }, }, tabs(sessionKey: string) { @@ -186,14 +187,6 @@ export const { use: useLayout, provider: LayoutProvider } = createSimpleContext( } }, async open(tab: string) { - if (tab === "chat") { - if (!store.sessionTabs[sessionKey]) { - setStore("sessionTabs", sessionKey, { all: [], active: undefined }) - } else { - setStore("sessionTabs", sessionKey, "active", undefined) - } - return - } const current = store.sessionTabs[sessionKey] ?? { all: [] } if (tab !== "review") { if (!current.all.includes(tab)) { diff --git a/packages/desktop/src/pages/session.tsx b/packages/desktop/src/pages/session.tsx index 6e993ff8f8f..796b5b0c760 100644 --- a/packages/desktop/src/pages/session.tsx +++ b/packages/desktop/src/pages/session.tsx @@ -22,7 +22,6 @@ import { IconButton } from "@opencode-ai/ui/icon-button" import { Icon } from "@opencode-ai/ui/icon" import { Tooltip } from "@opencode-ai/ui/tooltip" import { DiffChanges } from "@opencode-ai/ui/diff-changes" -import { ProgressCircle } from "@opencode-ai/ui/progress-circle" import { ResizeHandle } from "@opencode-ai/ui/resize-handle" import { Tabs } from "@opencode-ai/ui/tabs" import { useCodeComponent } from "@opencode-ai/ui/context/code" @@ -50,7 +49,7 @@ import { DialogSelectFile } from "@/components/dialog-select-file" import { DialogSelectModel } from "@/components/dialog-select-model" import { useCommand } from "@/context/command" import { useNavigate, useParams } from "@solidjs/router" -import { AssistantMessage, UserMessage } from "@opencode-ai/sdk/v2" +import { UserMessage } from "@opencode-ai/sdk/v2" import { useSDK } from "@/context/sdk" import { usePrompt } from "@/context/prompt" import { extractPromptFromParts } from "@/utils/prompt" @@ -118,27 +117,8 @@ export default function Page() { setActiveMessage(msgs[targetIndex]) } - const last = createMemo( - () => messages().findLast((x) => x.role === "assistant" && x.tokens.output > 0) as AssistantMessage, - ) - const model = createMemo(() => - last() ? sync.data.provider.all.find((x) => x.id === last().providerID)?.models[last().modelID] : undefined, - ) const diffs = createMemo(() => (params.id ? (sync.data.session_diff[params.id] ?? []) : [])) - const tokens = createMemo(() => { - if (!last()) return - const t = last().tokens - return t.input + t.output + t.reasoning + t.cache.read + t.cache.write - }) - - const context = createMemo(() => { - const total = tokens() - const limit = model()?.limit.context - if (!total || !limit) return 0 - return Math.round((total / limit) * 100) - }) - const [store, setStore] = createStore({ clickTimer: undefined as number | undefined, activeDraggable: undefined as string | undefined, @@ -551,273 +531,213 @@ export default function Page() { ) } - const wide = createMemo(() => layout.review.state() === "tab" || !diffs().length) + const showTabs = createMemo(() => diffs().length > 0 || tabs().all().length > 0) return (
-
- + {/* Session pane - always visible */} +
- - - -
- - -
-
Session
- - -
{context() ?? 0}%
-
+
+ + +
+ + + setStore("stepsExpanded", (x) => !x)} + onUserInteracted={() => setStore("userInteracted", true)} + classes={{ + root: "pb-20 flex-1 min-w-0", + content: "pb-20", + container: + "w-full " + + (!showTabs() + ? "max-w-200 mx-auto px-6" + : visibleUserMessages().length > 1 + ? "pr-6 pl-18" + : "px-6"), + }} + /> + +
+
+ +
+
New session
+
+ +
+ {getDirectory(sync.data.path.directory)} + {getFilename(sync.data.path.directory)} +
- - - - - - } - > -
- - - -
-
Review
- -
- {info()?.summary?.files ?? 0} -
-
+ + {(project) => ( +
+ +
+ Last modified  + + {DateTime.fromMillis(project().time.updated ?? project().time.created).toRelative()} + +
-
- - - - - {(tab) => } - - -
- - dialog.show(() => )} - /> - + )} +
- + + +
+
+
+ { + inputRef = el + }} + />
- + + + +
+ + {/* Tabs pane - visible when there are diffs or file tabs */} + +
+ -
-
- - -
- - - setStore("stepsExpanded", (x) => !x)} - onUserInteracted={() => setStore("userInteracted", true)} - classes={{ - root: "pb-20 flex-1 min-w-0", - content: "pb-20", - container: - "w-full " + - (wide() - ? "max-w-200 mx-auto px-6" - : visibleUserMessages().length > 1 - ? "pr-6 pl-18" - : "px-6"), - }} - /> - -
-
- -
-
New session
-
- -
- {getDirectory(sync.data.path.directory)} - {getFilename(sync.data.path.directory)} + + + +
+ + + +
+ + + +
+
Review
+ +
+ {info()?.summary?.files ?? 0} +
+
- - {(project) => ( -
- -
- Last modified  - - {DateTime.fromMillis(project().time.updated ?? project().time.created).toRelative()} - -
-
- )} -
-
- - -
-
- { - inputRef = el + + + + + {(tab) => } + + +
+ + dialog.show(() => )} + /> + +
+ +
+ + +
+
-
-
- -
- - { - layout.review.tab() - tabs().setActive("review") - }} - /> - - } - /> -
+
-
- - - -
+ {(tab) => { + const [file] = createResource( + () => tab, + async (tab) => { + if (tab.startsWith("file://")) { + return local.file.node(tab.replace("file://", "")) + } + return undefined + }, + ) + return ( + + + + {(f) => ( + + )} + + + + ) }} - > - -
-
-
- - {(tab) => { - const [file] = createResource( - () => tab, - async (tab) => { - if (tab.startsWith("file://")) { - return local.file.node(tab.replace("file://", "")) - } - return undefined - }, - ) - return ( - - - - {(f) => ( - - )} - - - - ) - }} - - - - - {(draggedFile) => { - const [file] = createResource( - () => draggedFile(), - async (tab) => { - if (tab.startsWith("file://")) { - return local.file.node(tab.replace("file://", "")) - } - return undefined - }, - ) - return ( -
- {(f) => } -
- ) - }} -
-
- - -
- { - inputRef = el - }} - /> + + + + + {(draggedFile) => { + const [file] = createResource( + () => draggedFile(), + async (tab) => { + if (tab.startsWith("file://")) { + return local.file.node(tab.replace("file://", "")) + } + return undefined + }, + ) + return ( +
+ {(f) => } +
+ ) + }} +
+
+
From 518a65af0b58b820f123bdd0c6168b24f935d2a3 Mon Sep 17 00:00:00 2001 From: Adam <2363879+adamdotdevin@users.noreply.github.com> Date: Sat, 20 Dec 2025 20:02:40 -0600 Subject: [PATCH 04/37] fix(desktop): layout --- packages/desktop/src/pages/session.tsx | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/packages/desktop/src/pages/session.tsx b/packages/desktop/src/pages/session.tsx index 796b5b0c760..508fbc9c227 100644 --- a/packages/desktop/src/pages/session.tsx +++ b/packages/desktop/src/pages/session.tsx @@ -538,7 +538,7 @@ export default function Page() {
{/* Session pane - always visible */}
@@ -601,7 +601,12 @@ export default function Page() {
-
+
{ inputRef = el From 3bb75948d975ad129ed04c797e169c932c9001fd Mon Sep 17 00:00:00 2001 From: opencode Date: Sun, 21 Dec 2025 02:06:25 +0000 Subject: [PATCH 05/37] release: v1.0.181 --- bun.lock | 30 +++++++++++++------------- packages/console/app/package.json | 2 +- packages/console/core/package.json | 2 +- packages/console/function/package.json | 2 +- packages/console/mail/package.json | 2 +- packages/desktop/package.json | 2 +- packages/enterprise/package.json | 2 +- packages/extensions/zed/extension.toml | 12 +++++------ packages/function/package.json | 2 +- packages/opencode/package.json | 2 +- packages/plugin/package.json | 4 ++-- packages/sdk/js/package.json | 4 ++-- packages/slack/package.json | 2 +- packages/tauri/package.json | 2 +- packages/ui/package.json | 2 +- packages/util/package.json | 2 +- packages/web/package.json | 2 +- sdks/vscode/package.json | 2 +- 18 files changed, 39 insertions(+), 39 deletions(-) diff --git a/bun.lock b/bun.lock index 089de5002b4..047970137c6 100644 --- a/bun.lock +++ b/bun.lock @@ -20,7 +20,7 @@ }, "packages/console/app": { "name": "@opencode-ai/console-app", - "version": "1.0.180", + "version": "1.0.181", "dependencies": { "@cloudflare/vite-plugin": "1.15.2", "@ibm/plex": "6.4.1", @@ -48,7 +48,7 @@ }, "packages/console/core": { "name": "@opencode-ai/console-core", - "version": "1.0.180", + "version": "1.0.181", "dependencies": { "@aws-sdk/client-sts": "3.782.0", "@jsx-email/render": "1.1.1", @@ -75,7 +75,7 @@ }, "packages/console/function": { "name": "@opencode-ai/console-function", - "version": "1.0.180", + "version": "1.0.181", "dependencies": { "@ai-sdk/anthropic": "2.0.0", "@ai-sdk/openai": "2.0.2", @@ -99,7 +99,7 @@ }, "packages/console/mail": { "name": "@opencode-ai/console-mail", - "version": "1.0.180", + "version": "1.0.181", "dependencies": { "@jsx-email/all": "2.2.3", "@jsx-email/cli": "1.4.3", @@ -123,7 +123,7 @@ }, "packages/desktop": { "name": "@opencode-ai/desktop", - "version": "1.0.180", + "version": "1.0.181", "dependencies": { "@kobalte/core": "catalog:", "@opencode-ai/sdk": "workspace:*", @@ -171,7 +171,7 @@ }, "packages/enterprise": { "name": "@opencode-ai/enterprise", - "version": "1.0.180", + "version": "1.0.181", "dependencies": { "@opencode-ai/ui": "workspace:*", "@opencode-ai/util": "workspace:*", @@ -200,7 +200,7 @@ }, "packages/function": { "name": "@opencode-ai/function", - "version": "1.0.180", + "version": "1.0.181", "dependencies": { "@octokit/auth-app": "8.0.1", "@octokit/rest": "catalog:", @@ -216,7 +216,7 @@ }, "packages/opencode": { "name": "opencode", - "version": "1.0.180", + "version": "1.0.181", "bin": { "opencode": "./bin/opencode", }, @@ -308,7 +308,7 @@ }, "packages/plugin": { "name": "@opencode-ai/plugin", - "version": "1.0.180", + "version": "1.0.181", "dependencies": { "@opencode-ai/sdk": "workspace:*", "zod": "catalog:", @@ -328,7 +328,7 @@ }, "packages/sdk/js": { "name": "@opencode-ai/sdk", - "version": "1.0.180", + "version": "1.0.181", "devDependencies": { "@hey-api/openapi-ts": "0.88.1", "@tsconfig/node22": "catalog:", @@ -339,7 +339,7 @@ }, "packages/slack": { "name": "@opencode-ai/slack", - "version": "1.0.180", + "version": "1.0.181", "dependencies": { "@opencode-ai/sdk": "workspace:*", "@slack/bolt": "^3.17.1", @@ -352,7 +352,7 @@ }, "packages/tauri": { "name": "@opencode-ai/tauri", - "version": "1.0.180", + "version": "1.0.181", "dependencies": { "@opencode-ai/desktop": "workspace:*", "@solid-primitives/storage": "catalog:", @@ -379,7 +379,7 @@ }, "packages/ui": { "name": "@opencode-ai/ui", - "version": "1.0.180", + "version": "1.0.181", "dependencies": { "@kobalte/core": "catalog:", "@opencode-ai/sdk": "workspace:*", @@ -414,7 +414,7 @@ }, "packages/util": { "name": "@opencode-ai/util", - "version": "1.0.180", + "version": "1.0.181", "dependencies": { "zod": "catalog:", }, @@ -425,7 +425,7 @@ }, "packages/web": { "name": "@opencode-ai/web", - "version": "1.0.180", + "version": "1.0.181", "dependencies": { "@astrojs/cloudflare": "12.6.3", "@astrojs/markdown-remark": "6.3.1", diff --git a/packages/console/app/package.json b/packages/console/app/package.json index 4e8d3fd59e6..4405438f8bd 100644 --- a/packages/console/app/package.json +++ b/packages/console/app/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/console-app", - "version": "1.0.180", + "version": "1.0.181", "type": "module", "scripts": { "typecheck": "tsgo --noEmit", diff --git a/packages/console/core/package.json b/packages/console/core/package.json index 4418597d6ea..cf38791252f 100644 --- a/packages/console/core/package.json +++ b/packages/console/core/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "@opencode-ai/console-core", - "version": "1.0.180", + "version": "1.0.181", "private": true, "type": "module", "dependencies": { diff --git a/packages/console/function/package.json b/packages/console/function/package.json index 250e2cdabd5..343a07d4659 100644 --- a/packages/console/function/package.json +++ b/packages/console/function/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/console-function", - "version": "1.0.180", + "version": "1.0.181", "$schema": "https://json.schemastore.org/package.json", "private": true, "type": "module", diff --git a/packages/console/mail/package.json b/packages/console/mail/package.json index 1f18ce31455..6259d72f947 100644 --- a/packages/console/mail/package.json +++ b/packages/console/mail/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/console-mail", - "version": "1.0.180", + "version": "1.0.181", "dependencies": { "@jsx-email/all": "2.2.3", "@jsx-email/cli": "1.4.3", diff --git a/packages/desktop/package.json b/packages/desktop/package.json index c1cf191d4e8..f982a8ea113 100644 --- a/packages/desktop/package.json +++ b/packages/desktop/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/desktop", - "version": "1.0.180", + "version": "1.0.181", "description": "", "type": "module", "exports": { diff --git a/packages/enterprise/package.json b/packages/enterprise/package.json index acb03ed8e2a..497cd6ba674 100644 --- a/packages/enterprise/package.json +++ b/packages/enterprise/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/enterprise", - "version": "1.0.180", + "version": "1.0.181", "private": true, "type": "module", "scripts": { diff --git a/packages/extensions/zed/extension.toml b/packages/extensions/zed/extension.toml index 446839565c4..dbcff25c594 100644 --- a/packages/extensions/zed/extension.toml +++ b/packages/extensions/zed/extension.toml @@ -1,7 +1,7 @@ id = "opencode" name = "OpenCode" description = "The open source coding agent." -version = "1.0.180" +version = "1.0.181" schema_version = 1 authors = ["Anomaly"] repository = "https://github.com/sst/opencode" @@ -11,26 +11,26 @@ name = "OpenCode" icon = "./icons/opencode.svg" [agent_servers.opencode.targets.darwin-aarch64] -archive = "https://github.com/sst/opencode/releases/download/v1.0.180/opencode-darwin-arm64.zip" +archive = "https://github.com/sst/opencode/releases/download/v1.0.181/opencode-darwin-arm64.zip" cmd = "./opencode" args = ["acp"] [agent_servers.opencode.targets.darwin-x86_64] -archive = "https://github.com/sst/opencode/releases/download/v1.0.180/opencode-darwin-x64.zip" +archive = "https://github.com/sst/opencode/releases/download/v1.0.181/opencode-darwin-x64.zip" cmd = "./opencode" args = ["acp"] [agent_servers.opencode.targets.linux-aarch64] -archive = "https://github.com/sst/opencode/releases/download/v1.0.180/opencode-linux-arm64.tar.gz" +archive = "https://github.com/sst/opencode/releases/download/v1.0.181/opencode-linux-arm64.tar.gz" cmd = "./opencode" args = ["acp"] [agent_servers.opencode.targets.linux-x86_64] -archive = "https://github.com/sst/opencode/releases/download/v1.0.180/opencode-linux-x64.tar.gz" +archive = "https://github.com/sst/opencode/releases/download/v1.0.181/opencode-linux-x64.tar.gz" cmd = "./opencode" args = ["acp"] [agent_servers.opencode.targets.windows-x86_64] -archive = "https://github.com/sst/opencode/releases/download/v1.0.180/opencode-windows-x64.zip" +archive = "https://github.com/sst/opencode/releases/download/v1.0.181/opencode-windows-x64.zip" cmd = "./opencode.exe" args = ["acp"] diff --git a/packages/function/package.json b/packages/function/package.json index b18a0f5f424..162b714094a 100644 --- a/packages/function/package.json +++ b/packages/function/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/function", - "version": "1.0.180", + "version": "1.0.181", "$schema": "https://json.schemastore.org/package.json", "private": true, "type": "module", diff --git a/packages/opencode/package.json b/packages/opencode/package.json index 90427b7f87d..01ce4472996 100644 --- a/packages/opencode/package.json +++ b/packages/opencode/package.json @@ -1,6 +1,6 @@ { "$schema": "https://json.schemastore.org/package.json", - "version": "1.0.180", + "version": "1.0.181", "name": "opencode", "type": "module", "private": true, diff --git a/packages/plugin/package.json b/packages/plugin/package.json index 647bcb563eb..f131648e25b 100644 --- a/packages/plugin/package.json +++ b/packages/plugin/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "@opencode-ai/plugin", - "version": "1.0.180", + "version": "1.0.181", "type": "module", "scripts": { "typecheck": "tsgo --noEmit", @@ -24,4 +24,4 @@ "typescript": "catalog:", "@typescript/native-preview": "catalog:" } -} +} \ No newline at end of file diff --git a/packages/sdk/js/package.json b/packages/sdk/js/package.json index 665499a6e90..52712ebfd88 100644 --- a/packages/sdk/js/package.json +++ b/packages/sdk/js/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "@opencode-ai/sdk", - "version": "1.0.180", + "version": "1.0.181", "type": "module", "scripts": { "typecheck": "tsgo --noEmit", @@ -29,4 +29,4 @@ "publishConfig": { "directory": "dist" } -} +} \ No newline at end of file diff --git a/packages/slack/package.json b/packages/slack/package.json index 7964da49bb3..b3a62693375 100644 --- a/packages/slack/package.json +++ b/packages/slack/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/slack", - "version": "1.0.180", + "version": "1.0.181", "type": "module", "scripts": { "dev": "bun run src/index.ts", diff --git a/packages/tauri/package.json b/packages/tauri/package.json index 537c3f3d50c..ec2bc72cdd5 100644 --- a/packages/tauri/package.json +++ b/packages/tauri/package.json @@ -1,7 +1,7 @@ { "name": "@opencode-ai/tauri", "private": true, - "version": "1.0.180", + "version": "1.0.181", "type": "module", "scripts": { "typecheck": "tsgo -b", diff --git a/packages/ui/package.json b/packages/ui/package.json index 2f42e536d02..8a758b6fe7a 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/ui", - "version": "1.0.180", + "version": "1.0.181", "type": "module", "exports": { "./*": "./src/components/*.tsx", diff --git a/packages/util/package.json b/packages/util/package.json index 19b21e7a050..dc4ee807e4e 100644 --- a/packages/util/package.json +++ b/packages/util/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/util", - "version": "1.0.180", + "version": "1.0.181", "private": true, "type": "module", "exports": { diff --git a/packages/web/package.json b/packages/web/package.json index 160b2781769..f9f9e087568 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -1,7 +1,7 @@ { "name": "@opencode-ai/web", "type": "module", - "version": "1.0.180", + "version": "1.0.181", "scripts": { "dev": "astro dev", "dev:remote": "VITE_API_URL=https://api.opencode.ai astro dev", diff --git a/sdks/vscode/package.json b/sdks/vscode/package.json index 34b1d01b701..c73fd4fc8ef 100644 --- a/sdks/vscode/package.json +++ b/sdks/vscode/package.json @@ -2,7 +2,7 @@ "name": "opencode", "displayName": "opencode", "description": "opencode for VS Code", - "version": "1.0.180", + "version": "1.0.181", "publisher": "sst-dev", "repository": { "type": "git", From 3bb9c68eb05e4bd07f066ccf2cea3ba5b0e5f52b Mon Sep 17 00:00:00 2001 From: Aiden Cline Date: Sat, 20 Dec 2025 21:04:37 -0600 Subject: [PATCH 06/37] fix: regression where config would error despite valid agents --- packages/opencode/src/config/config.ts | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/packages/opencode/src/config/config.ts b/packages/opencode/src/config/config.ts index 1158d67f4cc..031bdd31bab 100644 --- a/packages/opencode/src/config/config.ts +++ b/packages/opencode/src/config/config.ts @@ -141,17 +141,6 @@ export namespace Config { if (!result.keybinds) result.keybinds = Info.shape.keybinds.parse({}) - // Only validate if user has configured agents - if none configured, built-in agents will be used - if (Object.keys(result.agent).length > 0) { - const primaryAgents = Object.values(result.agent).filter((a) => a.mode !== "subagent" && !a.hidden && !a.disable) - if (primaryAgents.length === 0) { - throw new InvalidError({ - path: "config", - message: "No primary agents are available. Please configure at least one agent with mode 'primary' or 'all'.", - }) - } - } - return { config: result, directories, From c4561f4478e93c73e961f962b5a3d363f6ef6106 Mon Sep 17 00:00:00 2001 From: opencode Date: Sun, 21 Dec 2025 03:07:26 +0000 Subject: [PATCH 07/37] release: v1.0.182 --- bun.lock | 30 +++++++++++++------------- packages/console/app/package.json | 2 +- packages/console/core/package.json | 2 +- packages/console/function/package.json | 2 +- packages/console/mail/package.json | 2 +- packages/desktop/package.json | 2 +- packages/enterprise/package.json | 2 +- packages/extensions/zed/extension.toml | 12 +++++------ packages/function/package.json | 2 +- packages/opencode/package.json | 2 +- packages/plugin/package.json | 2 +- packages/sdk/js/package.json | 2 +- packages/slack/package.json | 2 +- packages/tauri/package.json | 2 +- packages/ui/package.json | 2 +- packages/util/package.json | 2 +- packages/web/package.json | 2 +- sdks/vscode/package.json | 2 +- 18 files changed, 37 insertions(+), 37 deletions(-) diff --git a/bun.lock b/bun.lock index 047970137c6..8027d29f016 100644 --- a/bun.lock +++ b/bun.lock @@ -20,7 +20,7 @@ }, "packages/console/app": { "name": "@opencode-ai/console-app", - "version": "1.0.181", + "version": "1.0.182", "dependencies": { "@cloudflare/vite-plugin": "1.15.2", "@ibm/plex": "6.4.1", @@ -48,7 +48,7 @@ }, "packages/console/core": { "name": "@opencode-ai/console-core", - "version": "1.0.181", + "version": "1.0.182", "dependencies": { "@aws-sdk/client-sts": "3.782.0", "@jsx-email/render": "1.1.1", @@ -75,7 +75,7 @@ }, "packages/console/function": { "name": "@opencode-ai/console-function", - "version": "1.0.181", + "version": "1.0.182", "dependencies": { "@ai-sdk/anthropic": "2.0.0", "@ai-sdk/openai": "2.0.2", @@ -99,7 +99,7 @@ }, "packages/console/mail": { "name": "@opencode-ai/console-mail", - "version": "1.0.181", + "version": "1.0.182", "dependencies": { "@jsx-email/all": "2.2.3", "@jsx-email/cli": "1.4.3", @@ -123,7 +123,7 @@ }, "packages/desktop": { "name": "@opencode-ai/desktop", - "version": "1.0.181", + "version": "1.0.182", "dependencies": { "@kobalte/core": "catalog:", "@opencode-ai/sdk": "workspace:*", @@ -171,7 +171,7 @@ }, "packages/enterprise": { "name": "@opencode-ai/enterprise", - "version": "1.0.181", + "version": "1.0.182", "dependencies": { "@opencode-ai/ui": "workspace:*", "@opencode-ai/util": "workspace:*", @@ -200,7 +200,7 @@ }, "packages/function": { "name": "@opencode-ai/function", - "version": "1.0.181", + "version": "1.0.182", "dependencies": { "@octokit/auth-app": "8.0.1", "@octokit/rest": "catalog:", @@ -216,7 +216,7 @@ }, "packages/opencode": { "name": "opencode", - "version": "1.0.181", + "version": "1.0.182", "bin": { "opencode": "./bin/opencode", }, @@ -308,7 +308,7 @@ }, "packages/plugin": { "name": "@opencode-ai/plugin", - "version": "1.0.181", + "version": "1.0.182", "dependencies": { "@opencode-ai/sdk": "workspace:*", "zod": "catalog:", @@ -328,7 +328,7 @@ }, "packages/sdk/js": { "name": "@opencode-ai/sdk", - "version": "1.0.181", + "version": "1.0.182", "devDependencies": { "@hey-api/openapi-ts": "0.88.1", "@tsconfig/node22": "catalog:", @@ -339,7 +339,7 @@ }, "packages/slack": { "name": "@opencode-ai/slack", - "version": "1.0.181", + "version": "1.0.182", "dependencies": { "@opencode-ai/sdk": "workspace:*", "@slack/bolt": "^3.17.1", @@ -352,7 +352,7 @@ }, "packages/tauri": { "name": "@opencode-ai/tauri", - "version": "1.0.181", + "version": "1.0.182", "dependencies": { "@opencode-ai/desktop": "workspace:*", "@solid-primitives/storage": "catalog:", @@ -379,7 +379,7 @@ }, "packages/ui": { "name": "@opencode-ai/ui", - "version": "1.0.181", + "version": "1.0.182", "dependencies": { "@kobalte/core": "catalog:", "@opencode-ai/sdk": "workspace:*", @@ -414,7 +414,7 @@ }, "packages/util": { "name": "@opencode-ai/util", - "version": "1.0.181", + "version": "1.0.182", "dependencies": { "zod": "catalog:", }, @@ -425,7 +425,7 @@ }, "packages/web": { "name": "@opencode-ai/web", - "version": "1.0.181", + "version": "1.0.182", "dependencies": { "@astrojs/cloudflare": "12.6.3", "@astrojs/markdown-remark": "6.3.1", diff --git a/packages/console/app/package.json b/packages/console/app/package.json index 4405438f8bd..e13b96f38c7 100644 --- a/packages/console/app/package.json +++ b/packages/console/app/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/console-app", - "version": "1.0.181", + "version": "1.0.182", "type": "module", "scripts": { "typecheck": "tsgo --noEmit", diff --git a/packages/console/core/package.json b/packages/console/core/package.json index cf38791252f..6da120dc92c 100644 --- a/packages/console/core/package.json +++ b/packages/console/core/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "@opencode-ai/console-core", - "version": "1.0.181", + "version": "1.0.182", "private": true, "type": "module", "dependencies": { diff --git a/packages/console/function/package.json b/packages/console/function/package.json index 343a07d4659..7ae216136df 100644 --- a/packages/console/function/package.json +++ b/packages/console/function/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/console-function", - "version": "1.0.181", + "version": "1.0.182", "$schema": "https://json.schemastore.org/package.json", "private": true, "type": "module", diff --git a/packages/console/mail/package.json b/packages/console/mail/package.json index 6259d72f947..830400591ad 100644 --- a/packages/console/mail/package.json +++ b/packages/console/mail/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/console-mail", - "version": "1.0.181", + "version": "1.0.182", "dependencies": { "@jsx-email/all": "2.2.3", "@jsx-email/cli": "1.4.3", diff --git a/packages/desktop/package.json b/packages/desktop/package.json index f982a8ea113..a41ed60c321 100644 --- a/packages/desktop/package.json +++ b/packages/desktop/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/desktop", - "version": "1.0.181", + "version": "1.0.182", "description": "", "type": "module", "exports": { diff --git a/packages/enterprise/package.json b/packages/enterprise/package.json index 497cd6ba674..54ce9e17f10 100644 --- a/packages/enterprise/package.json +++ b/packages/enterprise/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/enterprise", - "version": "1.0.181", + "version": "1.0.182", "private": true, "type": "module", "scripts": { diff --git a/packages/extensions/zed/extension.toml b/packages/extensions/zed/extension.toml index dbcff25c594..8e7f26f1e5c 100644 --- a/packages/extensions/zed/extension.toml +++ b/packages/extensions/zed/extension.toml @@ -1,7 +1,7 @@ id = "opencode" name = "OpenCode" description = "The open source coding agent." -version = "1.0.181" +version = "1.0.182" schema_version = 1 authors = ["Anomaly"] repository = "https://github.com/sst/opencode" @@ -11,26 +11,26 @@ name = "OpenCode" icon = "./icons/opencode.svg" [agent_servers.opencode.targets.darwin-aarch64] -archive = "https://github.com/sst/opencode/releases/download/v1.0.181/opencode-darwin-arm64.zip" +archive = "https://github.com/sst/opencode/releases/download/v1.0.182/opencode-darwin-arm64.zip" cmd = "./opencode" args = ["acp"] [agent_servers.opencode.targets.darwin-x86_64] -archive = "https://github.com/sst/opencode/releases/download/v1.0.181/opencode-darwin-x64.zip" +archive = "https://github.com/sst/opencode/releases/download/v1.0.182/opencode-darwin-x64.zip" cmd = "./opencode" args = ["acp"] [agent_servers.opencode.targets.linux-aarch64] -archive = "https://github.com/sst/opencode/releases/download/v1.0.181/opencode-linux-arm64.tar.gz" +archive = "https://github.com/sst/opencode/releases/download/v1.0.182/opencode-linux-arm64.tar.gz" cmd = "./opencode" args = ["acp"] [agent_servers.opencode.targets.linux-x86_64] -archive = "https://github.com/sst/opencode/releases/download/v1.0.181/opencode-linux-x64.tar.gz" +archive = "https://github.com/sst/opencode/releases/download/v1.0.182/opencode-linux-x64.tar.gz" cmd = "./opencode" args = ["acp"] [agent_servers.opencode.targets.windows-x86_64] -archive = "https://github.com/sst/opencode/releases/download/v1.0.181/opencode-windows-x64.zip" +archive = "https://github.com/sst/opencode/releases/download/v1.0.182/opencode-windows-x64.zip" cmd = "./opencode.exe" args = ["acp"] diff --git a/packages/function/package.json b/packages/function/package.json index 162b714094a..6f0fa372c49 100644 --- a/packages/function/package.json +++ b/packages/function/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/function", - "version": "1.0.181", + "version": "1.0.182", "$schema": "https://json.schemastore.org/package.json", "private": true, "type": "module", diff --git a/packages/opencode/package.json b/packages/opencode/package.json index 01ce4472996..11bc4b0cb9e 100644 --- a/packages/opencode/package.json +++ b/packages/opencode/package.json @@ -1,6 +1,6 @@ { "$schema": "https://json.schemastore.org/package.json", - "version": "1.0.181", + "version": "1.0.182", "name": "opencode", "type": "module", "private": true, diff --git a/packages/plugin/package.json b/packages/plugin/package.json index f131648e25b..3385d68f5a2 100644 --- a/packages/plugin/package.json +++ b/packages/plugin/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "@opencode-ai/plugin", - "version": "1.0.181", + "version": "1.0.182", "type": "module", "scripts": { "typecheck": "tsgo --noEmit", diff --git a/packages/sdk/js/package.json b/packages/sdk/js/package.json index 52712ebfd88..a4ef941e572 100644 --- a/packages/sdk/js/package.json +++ b/packages/sdk/js/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "@opencode-ai/sdk", - "version": "1.0.181", + "version": "1.0.182", "type": "module", "scripts": { "typecheck": "tsgo --noEmit", diff --git a/packages/slack/package.json b/packages/slack/package.json index b3a62693375..b44f1505cde 100644 --- a/packages/slack/package.json +++ b/packages/slack/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/slack", - "version": "1.0.181", + "version": "1.0.182", "type": "module", "scripts": { "dev": "bun run src/index.ts", diff --git a/packages/tauri/package.json b/packages/tauri/package.json index ec2bc72cdd5..34a013a51e4 100644 --- a/packages/tauri/package.json +++ b/packages/tauri/package.json @@ -1,7 +1,7 @@ { "name": "@opencode-ai/tauri", "private": true, - "version": "1.0.181", + "version": "1.0.182", "type": "module", "scripts": { "typecheck": "tsgo -b", diff --git a/packages/ui/package.json b/packages/ui/package.json index 8a758b6fe7a..df5031fb45d 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/ui", - "version": "1.0.181", + "version": "1.0.182", "type": "module", "exports": { "./*": "./src/components/*.tsx", diff --git a/packages/util/package.json b/packages/util/package.json index dc4ee807e4e..5d796ef52ff 100644 --- a/packages/util/package.json +++ b/packages/util/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/util", - "version": "1.0.181", + "version": "1.0.182", "private": true, "type": "module", "exports": { diff --git a/packages/web/package.json b/packages/web/package.json index f9f9e087568..d22646849a9 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -1,7 +1,7 @@ { "name": "@opencode-ai/web", "type": "module", - "version": "1.0.181", + "version": "1.0.182", "scripts": { "dev": "astro dev", "dev:remote": "VITE_API_URL=https://api.opencode.ai astro dev", diff --git a/sdks/vscode/package.json b/sdks/vscode/package.json index c73fd4fc8ef..050b66e5148 100644 --- a/sdks/vscode/package.json +++ b/sdks/vscode/package.json @@ -2,7 +2,7 @@ "name": "opencode", "displayName": "opencode", "description": "opencode for VS Code", - "version": "1.0.181", + "version": "1.0.182", "publisher": "sst-dev", "repository": { "type": "git", From 5dbd8c8659fc9b5a8eee523a42dee315239da479 Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Sun, 21 Dec 2025 03:05:21 +0000 Subject: [PATCH 08/37] chore: generate --- packages/plugin/package.json | 2 +- packages/sdk/js/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/plugin/package.json b/packages/plugin/package.json index 3385d68f5a2..a4753726dcb 100644 --- a/packages/plugin/package.json +++ b/packages/plugin/package.json @@ -24,4 +24,4 @@ "typescript": "catalog:", "@typescript/native-preview": "catalog:" } -} \ No newline at end of file +} diff --git a/packages/sdk/js/package.json b/packages/sdk/js/package.json index a4ef941e572..f23970060f3 100644 --- a/packages/sdk/js/package.json +++ b/packages/sdk/js/package.json @@ -29,4 +29,4 @@ "publishConfig": { "directory": "dist" } -} \ No newline at end of file +} From e0dcfd703b2902e9904ead0863968a2196ec466d Mon Sep 17 00:00:00 2001 From: Aiden Cline <63023139+rekram1-node@users.noreply.github.com> Date: Sat, 20 Dec 2025 19:36:22 -0800 Subject: [PATCH 09/37] core: add verification that at least 1 primary agent is enabled, add regression tests (#5881) --- packages/opencode/src/agent/agent.ts | 8 + packages/opencode/test/agent/agent.test.ts | 146 +++++++++++++++++++ packages/opencode/test/config/config.test.ts | 32 ++++ 3 files changed, 186 insertions(+) create mode 100644 packages/opencode/test/agent/agent.test.ts diff --git a/packages/opencode/src/agent/agent.ts b/packages/opencode/src/agent/agent.ts index 26f241fabbf..90c8594cd77 100644 --- a/packages/opencode/src/agent/agent.ts +++ b/packages/opencode/src/agent/agent.ts @@ -262,6 +262,14 @@ export namespace Agent { } } + const hasPrimaryAgents = Object.values(result).filter((a) => a.mode !== "subagent" && !a.hidden).length > 0 + if (!hasPrimaryAgents) { + throw new Config.InvalidError({ + path: "config", + message: "No primary agents are available. Please configure at least one agent with mode 'primary' or 'all'.", + }) + } + return result }) diff --git a/packages/opencode/test/agent/agent.test.ts b/packages/opencode/test/agent/agent.test.ts new file mode 100644 index 00000000000..222bf8367e6 --- /dev/null +++ b/packages/opencode/test/agent/agent.test.ts @@ -0,0 +1,146 @@ +import { test, expect } from "bun:test" +import path from "path" +import fs from "fs/promises" +import { tmpdir } from "../fixture/fixture" +import { Instance } from "../../src/project/instance" +import { Agent } from "../../src/agent/agent" + +test("loads built-in agents when no custom agents configured", async () => { + await using tmp = await tmpdir() + await Instance.provide({ + directory: tmp.path, + fn: async () => { + const agents = await Agent.list() + const names = agents.map((a) => a.name) + expect(names).toContain("build") + expect(names).toContain("plan") + }, + }) +}) + +test("custom subagent works alongside built-in primary agents", async () => { + await using tmp = await tmpdir({ + init: async (dir) => { + const opencodeDir = path.join(dir, ".opencode") + await fs.mkdir(opencodeDir, { recursive: true }) + const agentDir = path.join(opencodeDir, "agent") + await fs.mkdir(agentDir, { recursive: true }) + + await Bun.write( + path.join(agentDir, "helper.md"), + `--- +model: test/model +mode: subagent +--- +Helper subagent prompt`, + ) + }, + }) + await Instance.provide({ + directory: tmp.path, + fn: async () => { + const agents = await Agent.list() + const helper = agents.find((a) => a.name === "helper") + expect(helper).toBeDefined() + expect(helper?.mode).toBe("subagent") + + // Built-in primary agents should still exist + const build = agents.find((a) => a.name === "build") + expect(build).toBeDefined() + expect(build?.mode).toBe("primary") + }, + }) +}) + +test("throws error when all primary agents are disabled", async () => { + await using tmp = await tmpdir({ + init: async (dir) => { + await Bun.write( + path.join(dir, "opencode.json"), + JSON.stringify({ + $schema: "https://opencode.ai/config.json", + agent: { + build: { disable: true }, + plan: { disable: true }, + }, + }), + ) + }, + }) + await Instance.provide({ + directory: tmp.path, + fn: async () => { + try { + await Agent.list() + expect(true).toBe(false) // should not reach here + } catch (e: any) { + expect(e.data?.message).toContain("No primary agents are available") + } + }, + }) +}) + +test("does not throw when at least one primary agent remains", async () => { + await using tmp = await tmpdir({ + init: async (dir) => { + await Bun.write( + path.join(dir, "opencode.json"), + JSON.stringify({ + $schema: "https://opencode.ai/config.json", + agent: { + build: { disable: true }, + }, + }), + ) + }, + }) + await Instance.provide({ + directory: tmp.path, + fn: async () => { + const agents = await Agent.list() + const plan = agents.find((a) => a.name === "plan") + expect(plan).toBeDefined() + expect(plan?.mode).toBe("primary") + }, + }) +}) + +test("custom primary agent satisfies requirement when built-ins disabled", async () => { + await using tmp = await tmpdir({ + init: async (dir) => { + const opencodeDir = path.join(dir, ".opencode") + await fs.mkdir(opencodeDir, { recursive: true }) + const agentDir = path.join(opencodeDir, "agent") + await fs.mkdir(agentDir, { recursive: true }) + + await Bun.write( + path.join(agentDir, "custom.md"), + `--- +model: test/model +mode: primary +--- +Custom primary agent`, + ) + + await Bun.write( + path.join(dir, "opencode.json"), + JSON.stringify({ + $schema: "https://opencode.ai/config.json", + agent: { + build: { disable: true }, + plan: { disable: true }, + }, + }), + ) + }, + }) + await Instance.provide({ + directory: tmp.path, + fn: async () => { + const agents = await Agent.list() + const custom = agents.find((a) => a.name === "custom") + expect(custom).toBeDefined() + expect(custom?.mode).toBe("primary") + }, + }) +}) diff --git a/packages/opencode/test/config/config.test.ts b/packages/opencode/test/config/config.test.ts index 2ff8c01cdb0..6f43cab6174 100644 --- a/packages/opencode/test/config/config.test.ts +++ b/packages/opencode/test/config/config.test.ts @@ -450,6 +450,38 @@ test("merges plugin arrays from global and local configs", async () => { }) }) +test("does not error when only custom agent is a subagent", async () => { + await using tmp = await tmpdir({ + init: async (dir) => { + const opencodeDir = path.join(dir, ".opencode") + await fs.mkdir(opencodeDir, { recursive: true }) + const agentDir = path.join(opencodeDir, "agent") + await fs.mkdir(agentDir, { recursive: true }) + + await Bun.write( + path.join(agentDir, "helper.md"), + `--- +model: test/model +mode: subagent +--- +Helper subagent prompt`, + ) + }, + }) + await Instance.provide({ + directory: tmp.path, + fn: async () => { + const config = await Config.get() + expect(config.agent?.["helper"]).toEqual({ + name: "helper", + model: "test/model", + mode: "subagent", + prompt: "Helper subagent prompt", + }) + }, + }) +}) + test("deduplicates duplicate plugins from global and local configs", async () => { await using tmp = await tmpdir({ init: async (dir) => { From f20dcca5822b650ec0fdd5e6998747b462600357 Mon Sep 17 00:00:00 2001 From: Christopher Tso Date: Sun, 21 Dec 2025 17:09:58 +1100 Subject: [PATCH 10/37] Make CLI build script Windows-friendly (#5835) --- packages/opencode/package.json | 2 +- packages/opencode/script/build.ts | 15 ++++++++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/packages/opencode/package.json b/packages/opencode/package.json index 11bc4b0cb9e..2592553e759 100644 --- a/packages/opencode/package.json +++ b/packages/opencode/package.json @@ -7,7 +7,7 @@ "scripts": { "typecheck": "tsgo --noEmit", "test": "bun test", - "build": "./script/build.ts", + "build": "bun run script/build.ts", "dev": "bun run --conditions=browser ./src/index.ts", "random": "echo 'Random script updated at $(date)' && echo 'Change queued successfully' && echo 'Another change made' && echo 'Yet another change' && echo 'One more change' && echo 'Final change' && echo 'Another final change' && echo 'Yet another final change'", "clean": "echo 'Cleaning up...' && rm -rf node_modules dist", diff --git a/packages/opencode/script/build.ts b/packages/opencode/script/build.ts index a85fde9e207..f51cb292411 100755 --- a/packages/opencode/script/build.ts +++ b/packages/opencode/script/build.ts @@ -16,6 +16,7 @@ import pkg from "../package.json" import { Script } from "@opencode-ai/script" const singleFlag = process.argv.includes("--single") +const baselineFlag = process.argv.includes("--baseline") const skipInstall = process.argv.includes("--skip-install") const allTargets: { @@ -78,7 +79,19 @@ const allTargets: { ] const targets = singleFlag - ? allTargets.filter((item) => item.os === process.platform && item.arch === process.arch) + ? allTargets.filter((item) => { + if (item.os !== process.platform || item.arch !== process.arch) { + return false + } + + // When building for the current platform, prefer a single native binary by default. + // Baseline binaries require additional Bun artifacts and can be flaky to download. + if (item.avx2 === false) { + return baselineFlag + } + + return true + }) : allTargets await $`rm -rf dist` From 28392248729df0f5a0847276c3eefc0f968b925b Mon Sep 17 00:00:00 2001 From: Github Action Date: Sun, 21 Dec 2025 06:11:08 +0000 Subject: [PATCH 11/37] Update Nix flake.lock and hashes --- flake.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/flake.lock b/flake.lock index 1272626682f..e1c4419dcbd 100644 --- a/flake.lock +++ b/flake.lock @@ -2,11 +2,11 @@ "nodes": { "nixpkgs": { "locked": { - "lastModified": 1766025857, - "narHash": "sha256-Lav5jJazCW4mdg1iHcROpuXqmM94BWJvabLFWaJVJp0=", + "lastModified": 1766125104, + "narHash": "sha256-l/YGrEpLromL4viUo5GmFH3K5M1j0Mb9O+LiaeCPWEM=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "def3da69945bbe338c373fddad5a1bb49cf199ce", + "rev": "7d853e518814cca2a657b72eeba67ae20ebf7059", "type": "github" }, "original": { From c2b7200277ae6da8e3005eb517ddecee6fe21510 Mon Sep 17 00:00:00 2001 From: Adam <2363879+adamdotdevin@users.noreply.github.com> Date: Sun, 21 Dec 2025 04:01:55 -0600 Subject: [PATCH 12/37] fix(desktop): file loading errors --- packages/desktop/src/context/local.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/desktop/src/context/local.tsx b/packages/desktop/src/context/local.tsx index f5697383547..69807a2f443 100644 --- a/packages/desktop/src/context/local.tsx +++ b/packages/desktop/src/context/local.tsx @@ -360,7 +360,7 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({ const init = async (path: string) => { const relativePath = relative(path) if (!store.node[relativePath]) await fetch(path) - if (store.node[relativePath].loaded) return + if (store.node[relativePath]?.loaded) return return load(relativePath) } @@ -380,7 +380,7 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({ context.addActive() if (options?.pinned) setStore("node", path, "pinned", true) if (options?.view && store.node[relativePath].view === undefined) setStore("node", path, "view", options.view) - if (store.node[relativePath].loaded) return + if (store.node[relativePath]?.loaded) return return load(relativePath) } From 2f078e30de9c40baf64c5e436f9ddae9ce44d54f Mon Sep 17 00:00:00 2001 From: Adam <2363879+adamdotdevin@users.noreply.github.com> Date: Sun, 21 Dec 2025 04:06:10 -0600 Subject: [PATCH 13/37] fix(desktop): non-latin file paths failed --- packages/util/src/encode.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/util/src/encode.ts b/packages/util/src/encode.ts index cc40fbe9d00..fc1f783bf27 100644 --- a/packages/util/src/encode.ts +++ b/packages/util/src/encode.ts @@ -1,9 +1,13 @@ export function base64Encode(value: string) { - return btoa(value).replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "") + const bytes = new TextEncoder().encode(value) + const binary = Array.from(bytes, (b) => String.fromCharCode(b)).join("") + return btoa(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "") } export function base64Decode(value: string) { - return atob(value.replace(/-/g, "+").replace(/_/g, "/")) + const binary = atob(value.replace(/-/g, "+").replace(/_/g, "/")) + const bytes = Uint8Array.from(binary, (c) => c.charCodeAt(0)) + return new TextDecoder().decode(bytes) } export async function hash(content: string, algorithm = "SHA-256"): Promise { From 24d9e3c1a1da4071945fe44ae4d6d0256feb720d Mon Sep 17 00:00:00 2001 From: Adam <2363879+adamdotdevin@users.noreply.github.com> Date: Sun, 21 Dec 2025 04:11:09 -0600 Subject: [PATCH 14/37] fix(desktop): better error reporting --- packages/desktop/src/pages/error.tsx | 30 +++++++++++++++++++++++----- packages/desktop/vite.config.ts | 1 + 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/packages/desktop/src/pages/error.tsx b/packages/desktop/src/pages/error.tsx index 352b9f3e8e9..c7330c29884 100644 --- a/packages/desktop/src/pages/error.tsx +++ b/packages/desktop/src/pages/error.tsx @@ -62,12 +62,32 @@ function formatInitError(error: InitError): string { } } -function formatError(error: unknown): string { +function formatErrorChain(error: unknown, depth = 0): string { if (!error) return "Unknown error" - if (isInitError(error)) return formatInitError(error) - if (error instanceof Error) return `${error.name}: ${error.message}\n\n${error.stack}` - if (typeof error === "string") return error - return JSON.stringify(error, null, 2) + + const indent = depth > 0 ? `\n${"─".repeat(40)}\nCaused by:\n` : "" + + if (isInitError(error)) { + return indent + formatInitError(error) + } + + if (error instanceof Error) { + const parts = [indent + `${error.name}: ${error.message}`] + if (error.stack) { + parts.push(error.stack) + } + if (error.cause) { + parts.push(formatErrorChain(error.cause, depth + 1)) + } + return parts.join("\n\n") + } + + if (typeof error === "string") return indent + error + return indent + JSON.stringify(error, null, 2) +} + +function formatError(error: unknown): string { + return formatErrorChain(error, 0) } interface ErrorPageProps { diff --git a/packages/desktop/vite.config.ts b/packages/desktop/vite.config.ts index a388884cd54..57071a894fa 100644 --- a/packages/desktop/vite.config.ts +++ b/packages/desktop/vite.config.ts @@ -10,5 +10,6 @@ export default defineConfig({ }, build: { target: "esnext", + sourcemap: true, }, }) From d97ca78ec2191f7427d7bc72aa508f566f1e2352 Mon Sep 17 00:00:00 2001 From: opencode Date: Sun, 21 Dec 2025 10:14:41 +0000 Subject: [PATCH 15/37] release: v1.0.183 --- bun.lock | 30 +++++++++++++------------- packages/console/app/package.json | 2 +- packages/console/core/package.json | 2 +- packages/console/function/package.json | 2 +- packages/console/mail/package.json | 2 +- packages/desktop/package.json | 2 +- packages/enterprise/package.json | 2 +- packages/extensions/zed/extension.toml | 12 +++++------ packages/function/package.json | 2 +- packages/opencode/package.json | 2 +- packages/plugin/package.json | 4 ++-- packages/sdk/js/package.json | 4 ++-- packages/slack/package.json | 2 +- packages/tauri/package.json | 2 +- packages/ui/package.json | 2 +- packages/util/package.json | 2 +- packages/web/package.json | 2 +- sdks/vscode/package.json | 2 +- 18 files changed, 39 insertions(+), 39 deletions(-) diff --git a/bun.lock b/bun.lock index 8027d29f016..0a3252e4112 100644 --- a/bun.lock +++ b/bun.lock @@ -20,7 +20,7 @@ }, "packages/console/app": { "name": "@opencode-ai/console-app", - "version": "1.0.182", + "version": "1.0.183", "dependencies": { "@cloudflare/vite-plugin": "1.15.2", "@ibm/plex": "6.4.1", @@ -48,7 +48,7 @@ }, "packages/console/core": { "name": "@opencode-ai/console-core", - "version": "1.0.182", + "version": "1.0.183", "dependencies": { "@aws-sdk/client-sts": "3.782.0", "@jsx-email/render": "1.1.1", @@ -75,7 +75,7 @@ }, "packages/console/function": { "name": "@opencode-ai/console-function", - "version": "1.0.182", + "version": "1.0.183", "dependencies": { "@ai-sdk/anthropic": "2.0.0", "@ai-sdk/openai": "2.0.2", @@ -99,7 +99,7 @@ }, "packages/console/mail": { "name": "@opencode-ai/console-mail", - "version": "1.0.182", + "version": "1.0.183", "dependencies": { "@jsx-email/all": "2.2.3", "@jsx-email/cli": "1.4.3", @@ -123,7 +123,7 @@ }, "packages/desktop": { "name": "@opencode-ai/desktop", - "version": "1.0.182", + "version": "1.0.183", "dependencies": { "@kobalte/core": "catalog:", "@opencode-ai/sdk": "workspace:*", @@ -171,7 +171,7 @@ }, "packages/enterprise": { "name": "@opencode-ai/enterprise", - "version": "1.0.182", + "version": "1.0.183", "dependencies": { "@opencode-ai/ui": "workspace:*", "@opencode-ai/util": "workspace:*", @@ -200,7 +200,7 @@ }, "packages/function": { "name": "@opencode-ai/function", - "version": "1.0.182", + "version": "1.0.183", "dependencies": { "@octokit/auth-app": "8.0.1", "@octokit/rest": "catalog:", @@ -216,7 +216,7 @@ }, "packages/opencode": { "name": "opencode", - "version": "1.0.182", + "version": "1.0.183", "bin": { "opencode": "./bin/opencode", }, @@ -308,7 +308,7 @@ }, "packages/plugin": { "name": "@opencode-ai/plugin", - "version": "1.0.182", + "version": "1.0.183", "dependencies": { "@opencode-ai/sdk": "workspace:*", "zod": "catalog:", @@ -328,7 +328,7 @@ }, "packages/sdk/js": { "name": "@opencode-ai/sdk", - "version": "1.0.182", + "version": "1.0.183", "devDependencies": { "@hey-api/openapi-ts": "0.88.1", "@tsconfig/node22": "catalog:", @@ -339,7 +339,7 @@ }, "packages/slack": { "name": "@opencode-ai/slack", - "version": "1.0.182", + "version": "1.0.183", "dependencies": { "@opencode-ai/sdk": "workspace:*", "@slack/bolt": "^3.17.1", @@ -352,7 +352,7 @@ }, "packages/tauri": { "name": "@opencode-ai/tauri", - "version": "1.0.182", + "version": "1.0.183", "dependencies": { "@opencode-ai/desktop": "workspace:*", "@solid-primitives/storage": "catalog:", @@ -379,7 +379,7 @@ }, "packages/ui": { "name": "@opencode-ai/ui", - "version": "1.0.182", + "version": "1.0.183", "dependencies": { "@kobalte/core": "catalog:", "@opencode-ai/sdk": "workspace:*", @@ -414,7 +414,7 @@ }, "packages/util": { "name": "@opencode-ai/util", - "version": "1.0.182", + "version": "1.0.183", "dependencies": { "zod": "catalog:", }, @@ -425,7 +425,7 @@ }, "packages/web": { "name": "@opencode-ai/web", - "version": "1.0.182", + "version": "1.0.183", "dependencies": { "@astrojs/cloudflare": "12.6.3", "@astrojs/markdown-remark": "6.3.1", diff --git a/packages/console/app/package.json b/packages/console/app/package.json index e13b96f38c7..515aff90357 100644 --- a/packages/console/app/package.json +++ b/packages/console/app/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/console-app", - "version": "1.0.182", + "version": "1.0.183", "type": "module", "scripts": { "typecheck": "tsgo --noEmit", diff --git a/packages/console/core/package.json b/packages/console/core/package.json index 6da120dc92c..3eadd2e4e9d 100644 --- a/packages/console/core/package.json +++ b/packages/console/core/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "@opencode-ai/console-core", - "version": "1.0.182", + "version": "1.0.183", "private": true, "type": "module", "dependencies": { diff --git a/packages/console/function/package.json b/packages/console/function/package.json index 7ae216136df..c14a107ffa4 100644 --- a/packages/console/function/package.json +++ b/packages/console/function/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/console-function", - "version": "1.0.182", + "version": "1.0.183", "$schema": "https://json.schemastore.org/package.json", "private": true, "type": "module", diff --git a/packages/console/mail/package.json b/packages/console/mail/package.json index 830400591ad..095dd6f2568 100644 --- a/packages/console/mail/package.json +++ b/packages/console/mail/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/console-mail", - "version": "1.0.182", + "version": "1.0.183", "dependencies": { "@jsx-email/all": "2.2.3", "@jsx-email/cli": "1.4.3", diff --git a/packages/desktop/package.json b/packages/desktop/package.json index a41ed60c321..d70f13add92 100644 --- a/packages/desktop/package.json +++ b/packages/desktop/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/desktop", - "version": "1.0.182", + "version": "1.0.183", "description": "", "type": "module", "exports": { diff --git a/packages/enterprise/package.json b/packages/enterprise/package.json index 54ce9e17f10..bad614e4163 100644 --- a/packages/enterprise/package.json +++ b/packages/enterprise/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/enterprise", - "version": "1.0.182", + "version": "1.0.183", "private": true, "type": "module", "scripts": { diff --git a/packages/extensions/zed/extension.toml b/packages/extensions/zed/extension.toml index 8e7f26f1e5c..dfd7bdffe68 100644 --- a/packages/extensions/zed/extension.toml +++ b/packages/extensions/zed/extension.toml @@ -1,7 +1,7 @@ id = "opencode" name = "OpenCode" description = "The open source coding agent." -version = "1.0.182" +version = "1.0.183" schema_version = 1 authors = ["Anomaly"] repository = "https://github.com/sst/opencode" @@ -11,26 +11,26 @@ name = "OpenCode" icon = "./icons/opencode.svg" [agent_servers.opencode.targets.darwin-aarch64] -archive = "https://github.com/sst/opencode/releases/download/v1.0.182/opencode-darwin-arm64.zip" +archive = "https://github.com/sst/opencode/releases/download/v1.0.183/opencode-darwin-arm64.zip" cmd = "./opencode" args = ["acp"] [agent_servers.opencode.targets.darwin-x86_64] -archive = "https://github.com/sst/opencode/releases/download/v1.0.182/opencode-darwin-x64.zip" +archive = "https://github.com/sst/opencode/releases/download/v1.0.183/opencode-darwin-x64.zip" cmd = "./opencode" args = ["acp"] [agent_servers.opencode.targets.linux-aarch64] -archive = "https://github.com/sst/opencode/releases/download/v1.0.182/opencode-linux-arm64.tar.gz" +archive = "https://github.com/sst/opencode/releases/download/v1.0.183/opencode-linux-arm64.tar.gz" cmd = "./opencode" args = ["acp"] [agent_servers.opencode.targets.linux-x86_64] -archive = "https://github.com/sst/opencode/releases/download/v1.0.182/opencode-linux-x64.tar.gz" +archive = "https://github.com/sst/opencode/releases/download/v1.0.183/opencode-linux-x64.tar.gz" cmd = "./opencode" args = ["acp"] [agent_servers.opencode.targets.windows-x86_64] -archive = "https://github.com/sst/opencode/releases/download/v1.0.182/opencode-windows-x64.zip" +archive = "https://github.com/sst/opencode/releases/download/v1.0.183/opencode-windows-x64.zip" cmd = "./opencode.exe" args = ["acp"] diff --git a/packages/function/package.json b/packages/function/package.json index 6f0fa372c49..06a5a51ad6c 100644 --- a/packages/function/package.json +++ b/packages/function/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/function", - "version": "1.0.182", + "version": "1.0.183", "$schema": "https://json.schemastore.org/package.json", "private": true, "type": "module", diff --git a/packages/opencode/package.json b/packages/opencode/package.json index 2592553e759..321a466ee9f 100644 --- a/packages/opencode/package.json +++ b/packages/opencode/package.json @@ -1,6 +1,6 @@ { "$schema": "https://json.schemastore.org/package.json", - "version": "1.0.182", + "version": "1.0.183", "name": "opencode", "type": "module", "private": true, diff --git a/packages/plugin/package.json b/packages/plugin/package.json index a4753726dcb..7a6f61fd92c 100644 --- a/packages/plugin/package.json +++ b/packages/plugin/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "@opencode-ai/plugin", - "version": "1.0.182", + "version": "1.0.183", "type": "module", "scripts": { "typecheck": "tsgo --noEmit", @@ -24,4 +24,4 @@ "typescript": "catalog:", "@typescript/native-preview": "catalog:" } -} +} \ No newline at end of file diff --git a/packages/sdk/js/package.json b/packages/sdk/js/package.json index f23970060f3..78f5c8806e6 100644 --- a/packages/sdk/js/package.json +++ b/packages/sdk/js/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "@opencode-ai/sdk", - "version": "1.0.182", + "version": "1.0.183", "type": "module", "scripts": { "typecheck": "tsgo --noEmit", @@ -29,4 +29,4 @@ "publishConfig": { "directory": "dist" } -} +} \ No newline at end of file diff --git a/packages/slack/package.json b/packages/slack/package.json index b44f1505cde..128413bfed7 100644 --- a/packages/slack/package.json +++ b/packages/slack/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/slack", - "version": "1.0.182", + "version": "1.0.183", "type": "module", "scripts": { "dev": "bun run src/index.ts", diff --git a/packages/tauri/package.json b/packages/tauri/package.json index 34a013a51e4..4098150aea3 100644 --- a/packages/tauri/package.json +++ b/packages/tauri/package.json @@ -1,7 +1,7 @@ { "name": "@opencode-ai/tauri", "private": true, - "version": "1.0.182", + "version": "1.0.183", "type": "module", "scripts": { "typecheck": "tsgo -b", diff --git a/packages/ui/package.json b/packages/ui/package.json index df5031fb45d..863206b13e6 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/ui", - "version": "1.0.182", + "version": "1.0.183", "type": "module", "exports": { "./*": "./src/components/*.tsx", diff --git a/packages/util/package.json b/packages/util/package.json index 5d796ef52ff..95863c57701 100644 --- a/packages/util/package.json +++ b/packages/util/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/util", - "version": "1.0.182", + "version": "1.0.183", "private": true, "type": "module", "exports": { diff --git a/packages/web/package.json b/packages/web/package.json index d22646849a9..cc623c1f5c2 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -1,7 +1,7 @@ { "name": "@opencode-ai/web", "type": "module", - "version": "1.0.182", + "version": "1.0.183", "scripts": { "dev": "astro dev", "dev:remote": "VITE_API_URL=https://api.opencode.ai astro dev", diff --git a/sdks/vscode/package.json b/sdks/vscode/package.json index 050b66e5148..68065e60704 100644 --- a/sdks/vscode/package.json +++ b/sdks/vscode/package.json @@ -2,7 +2,7 @@ "name": "opencode", "displayName": "opencode", "description": "opencode for VS Code", - "version": "1.0.182", + "version": "1.0.183", "publisher": "sst-dev", "repository": { "type": "git", From 429cd5b5e05545f5f01918966c6c13a790d3858d Mon Sep 17 00:00:00 2001 From: Adam <2363879+adamdotdevin@users.noreply.github.com> Date: Sun, 21 Dec 2025 04:35:09 -0600 Subject: [PATCH 16/37] fix(desktop): incorrect state dir on macos --- packages/tauri/src-tauri/src/lib.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/tauri/src-tauri/src/lib.rs b/packages/tauri/src-tauri/src/lib.rs index ffefbabf6b6..3c08841ab83 100644 --- a/packages/tauri/src-tauri/src/lib.rs +++ b/packages/tauri/src-tauri/src/lib.rs @@ -6,7 +6,7 @@ use std::{ sync::{Arc, Mutex}, time::{Duration, Instant}, }; -use tauri::{AppHandle, LogicalSize, Manager, RunEvent, WebviewUrl, WebviewWindow}; +use tauri::{AppHandle, LogicalSize, Manager, RunEvent, WebviewUrl, WebviewWindow, path::BaseDirectory}; use tauri_plugin_clipboard_manager::ClipboardExt; use tauri_plugin_dialog::{DialogExt, MessageDialogButtons, MessageDialogResult}; use tauri_plugin_shell::process::{CommandChild, CommandEvent}; @@ -97,6 +97,11 @@ fn spawn_sidecar(app: &AppHandle, port: u32) -> CommandChild { let log_state = app.state::(); let log_state_clone = log_state.inner().clone(); + let state_dir = app + .path() + .resolve("", BaseDirectory::AppLocalData) + .expect("Failed to resolve app local data dir"); + #[cfg(target_os = "windows")] let (mut rx, child) = app .shell() @@ -104,6 +109,7 @@ fn spawn_sidecar(app: &AppHandle, port: u32) -> CommandChild { .unwrap() .env("OPENCODE_EXPERIMENTAL_ICON_DISCOVERY", "true") .env("OPENCODE_CLIENT", "desktop") + .env("XDG_STATE_HOME", &state_dir) .args(["serve", &format!("--port={port}")]) .spawn() .expect("Failed to spawn opencode"); @@ -120,6 +126,7 @@ fn spawn_sidecar(app: &AppHandle, port: u32) -> CommandChild { .command(&shell) .env("OPENCODE_EXPERIMENTAL_ICON_DISCOVERY", "true") .env("OPENCODE_CLIENT", "desktop") + .env("XDG_STATE_HOME", &state_dir) .args([ "-il", "-c", From 75f2a7bd4f49509754bf79fd216ffa48cc3ebcbd Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Sun, 21 Dec 2025 10:36:43 +0000 Subject: [PATCH 17/37] chore: generate --- packages/plugin/package.json | 2 +- packages/sdk/js/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/plugin/package.json b/packages/plugin/package.json index 7a6f61fd92c..d7aec1eb4a0 100644 --- a/packages/plugin/package.json +++ b/packages/plugin/package.json @@ -24,4 +24,4 @@ "typescript": "catalog:", "@typescript/native-preview": "catalog:" } -} \ No newline at end of file +} diff --git a/packages/sdk/js/package.json b/packages/sdk/js/package.json index 78f5c8806e6..bb5699a5359 100644 --- a/packages/sdk/js/package.json +++ b/packages/sdk/js/package.json @@ -29,4 +29,4 @@ "publishConfig": { "directory": "dist" } -} \ No newline at end of file +} From df3b477fa29bf4c54fe0fa996002128369f66255 Mon Sep 17 00:00:00 2001 From: Adam <2363879+adamdotdevin@users.noreply.github.com> Date: Sun, 21 Dec 2025 04:39:46 -0600 Subject: [PATCH 18/37] fix(desktop): allow text selection --- packages/tauri/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/tauri/index.html b/packages/tauri/index.html index 8de2d21d01a..faeb1a1fde0 100644 --- a/packages/tauri/index.html +++ b/packages/tauri/index.html @@ -14,7 +14,7 @@ - +