From 2f73b16b57d734b1d40089996975784cb6d6e770 Mon Sep 17 00:00:00 2001 From: Adam <2363879+adamdotdevin@users.noreply.github.com> Date: Wed, 26 Nov 2025 05:29:31 -0600 Subject: [PATCH 01/14] deps: update pierre diffs --- bun.lock | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bun.lock b/bun.lock index d10b145c5..a1fbd7c6f 100644 --- a/bun.lock +++ b/bun.lock @@ -439,7 +439,7 @@ "@hono/zod-validator": "0.4.2", "@kobalte/core": "0.13.11", "@openauthjs/openauth": "0.0.0-20250322224806", - "@pierre/precision-diffs": "0.5.5", + "@pierre/precision-diffs": "0.5.7", "@solidjs/meta": "0.29.4", "@solidjs/router": "0.15.4", "@solidjs/start": "https://pkg.pr.new/@solidjs/start@dfb2020", @@ -1214,7 +1214,7 @@ "@petamoriken/float16": ["@petamoriken/float16@3.9.3", "", {}, "sha512-8awtpHXCx/bNpFt4mt2xdkgtgVvKqty8VbjHI/WWWQuEw+KLzFot3f4+LkQY9YmOtq7A5GdOnqoIC8Pdygjk2g=="], - "@pierre/precision-diffs": ["@pierre/precision-diffs@0.5.5", "", { "dependencies": { "@shikijs/core": "3.15.0", "@shikijs/transformers": "3.15.0", "diff": "8.0.2", "fast-deep-equal": "3.1.3", "hast-util-to-html": "9.0.5", "shiki": "3.15.0" }, "peerDependencies": { "react": "^18.3.1 || ^19.0.0", "react-dom": "^18.3.1 || ^19.0.0" } }, "sha512-mmDHEWWQ6fmXY5qRNHqodzOxHPwLqVNbbnO/MOpXteOTjd0nVIGy5IcaNwU2WSxhxQRwaUepKyx5+wwPcZLEmw=="], + "@pierre/precision-diffs": ["@pierre/precision-diffs@0.5.7", "", { "dependencies": { "@shikijs/core": "3.15.0", "@shikijs/transformers": "3.15.0", "diff": "8.0.2", "fast-deep-equal": "3.1.3", "hast-util-to-html": "9.0.5", "shiki": "3.15.0" }, "peerDependencies": { "react": "^18.3.1 || ^19.0.0", "react-dom": "^18.3.1 || ^19.0.0" } }, "sha512-Y+e4kJ9pT2I4NS5fE39KdoiXtwMkVPRvrwLM6O2IqO7PDCRWLBS7CYxcSgSyngEndccUll2krx66I2QnfO0Ovg=="], "@pkgjs/parseargs": ["@pkgjs/parseargs@0.11.0", "", {}, "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg=="], diff --git a/package.json b/package.json index 94b43d833..6de81dc24 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ "@tsconfig/bun": "1.0.9", "@cloudflare/workers-types": "4.20251008.0", "@openauthjs/openauth": "0.0.0-20250322224806", - "@pierre/precision-diffs": "0.5.5", + "@pierre/precision-diffs": "0.5.7", "@tailwindcss/vite": "4.1.11", "diff": "8.0.2", "ai": "5.0.97", From 9a8b8f26ac955c8c59b2bc1222edd3fb4e6be0be Mon Sep 17 00:00:00 2001 From: Github Action Date: Wed, 26 Nov 2025 11:31:37 +0000 Subject: [PATCH 02/14] Update Nix flake.lock and hashes --- flake.lock | 6 +++--- nix/hashes.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/flake.lock b/flake.lock index 1f7349683..231ac606b 100644 --- a/flake.lock +++ b/flake.lock @@ -2,11 +2,11 @@ "nodes": { "nixpkgs": { "locked": { - "lastModified": 1763934636, - "narHash": "sha256-9glbI7f1uU+yzQCq5LwLgdZqx6svOhZWkd4JRY265fc=", + "lastModified": 1764081664, + "narHash": "sha256-sUoHmPr/EwXzRMpv1u/kH+dXuvJEyyF2Q7muE+t0EU4=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "ee09932cedcef15aaf476f9343d1dea2cb77e261", + "rev": "dc205f7b4fdb04c8b7877b43edb7b73be7730081", "type": "github" }, "original": { diff --git a/nix/hashes.json b/nix/hashes.json index d764ca59b..b907f5c5e 100644 --- a/nix/hashes.json +++ b/nix/hashes.json @@ -1,3 +1,3 @@ { - "nodeModules": "sha256-cieNNPXZd4Bg9bZtRq2H8L99e24U8p5d+d76SE7SeJc=" + "nodeModules": "sha256-XFJXjBWbHIUWKdSOZkGW7VmUPBVtGRgLHM2/1xVThFc=" } From cd4fabd11b9abcf0f64c6ffa8cca026e76060b9b Mon Sep 17 00:00:00 2001 From: Adam <2363879+adamdotdevin@users.noreply.github.com> Date: Wed, 26 Nov 2025 05:58:19 -0600 Subject: [PATCH 03/14] fix: scroll gutter padding --- packages/desktop/src/pages/session.tsx | 4 ++-- .../enterprise/src/routes/share/[shareID].tsx | 21 ++++++++++++------- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/packages/desktop/src/pages/session.tsx b/packages/desktop/src/pages/session.tsx index 40acac663..60f9e9ef5 100644 --- a/packages/desktop/src/pages/session.tsx +++ b/packages/desktop/src/pages/session.tsx @@ -333,7 +333,7 @@ export default function Page() { flex: layout.review.state() === "pane", }} > -
+
@@ -364,7 +364,7 @@ export default function Page() {
diff --git a/packages/enterprise/src/routes/share/[shareID].tsx b/packages/enterprise/src/routes/share/[shareID].tsx index fd6638a5f..271fb290a 100644 --- a/packages/enterprise/src/routes/share/[shareID].tsx +++ b/packages/enterprise/src/routes/share/[shareID].tsx @@ -190,8 +190,8 @@ export default function () { ) const turns = () => ( -
- {title()} +
+
{title()}
{(message) => ( @@ -202,18 +202,20 @@ export default function () { root: "min-w-0 w-full relative", content: "flex flex-col justify-between !overflow-visible [&_[data-slot=session-turn-message-header]]:top-[-32px]", + container: "px-4", }} /> )}
-
+
) const wide = createMemo(() => diffs().length === 0) + const columnPadding = () => (wide() ? "px-6" : "px-21 @4xl:px-6") return (
@@ -245,11 +247,10 @@ export default function () {
- {title()} +
{title()}
1}> <> @@ -285,9 +286,13 @@ export default function () { -
+
From 30d6a26e3e9a606550bf5757129c5a0009e15aa7 Mon Sep 17 00:00:00 2001 From: Adam <2363879+adamdotdevin@users.noreply.github.com> Date: Wed, 26 Nov 2025 06:03:13 -0600 Subject: [PATCH 04/14] fix: useData --- packages/ui/src/components/message-progress.tsx | 10 ++++++---- packages/ui/src/components/session-turn.tsx | 12 ++++++------ packages/ui/src/context/data.tsx | 2 +- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/packages/ui/src/components/message-progress.tsx b/packages/ui/src/components/message-progress.tsx index adb245ab4..efe4dfd8f 100644 --- a/packages/ui/src/components/message-progress.tsx +++ b/packages/ui/src/components/message-progress.tsx @@ -7,7 +7,7 @@ import type { AssistantMessage as AssistantMessageType, ToolPart } from "@openco export function MessageProgress(props: { assistantMessages: () => AssistantMessageType[]; done?: boolean }) { const data = useData() const sanitizer = createMemo(() => (data.directory ? new RegExp(`${data.directory}/`, "g") : undefined)) - const parts = createMemo(() => props.assistantMessages().flatMap((m) => data.part[m.id])) + const parts = createMemo(() => props.assistantMessages().flatMap((m) => data.store.part[m.id])) const done = createMemo(() => props.done ?? false) const currentTask = createMemo( () => @@ -27,8 +27,10 @@ export function MessageProgress(props: { assistantMessages: () => AssistantMessa let resolved = parts() const task = currentTask() if (task && task.state && "metadata" in task.state && task.state.metadata?.sessionId) { - const messages = data.message[task.state.metadata.sessionId as string]?.filter((m) => m.role === "assistant") - resolved = messages?.flatMap((m) => data.part[m.id]) ?? parts() + const messages = data.store.message[task.state.metadata.sessionId as string]?.filter( + (m) => m.role === "assistant", + ) + resolved = messages?.flatMap((m) => data.store.part[m.id]) ?? parts() } return resolved }) @@ -149,7 +151,7 @@ export function MessageProgress(props: { assistantMessages: () => AssistantMessa {(p) => { const part = p() as ToolPart const message = createMemo(() => - data.message[part.sessionID].find((m) => m.id === part.messageID), + data.store.message[part.sessionID].find((m) => m.id === part.messageID), ) return (
diff --git a/packages/ui/src/components/session-turn.tsx b/packages/ui/src/components/session-turn.tsx index d146bae95..c61b23068 100644 --- a/packages/ui/src/components/session-turn.tsx +++ b/packages/ui/src/components/session-turn.tsx @@ -28,11 +28,11 @@ export function SessionTurn( }>, ) { const data = useData() - const match = Binary.search(data.session, props.sessionID, (s) => s.id) + const match = Binary.search(data.store.session, props.sessionID, (s) => s.id) if (!match.found) throw new Error(`Session ${props.sessionID} not found`) const sanitizer = createMemo(() => (data.directory ? new RegExp(`${data.directory}/`, "g") : undefined)) - const messages = createMemo(() => (props.sessionID ? (data.message[props.sessionID] ?? []) : [])) + const messages = createMemo(() => (props.sessionID ? (data.store.message[props.sessionID] ?? []) : [])) const userMessages = createMemo(() => messages() .filter((m) => m.role === "user") @@ -45,7 +45,7 @@ export function SessionTurn( const status = createMemo( () => - data.session_status[props.sessionID] ?? { + data.store.session_status[props.sessionID] ?? { type: "idle", }, ) @@ -65,9 +65,9 @@ export function SessionTurn( const assistantMessages = createMemo(() => { return messages()?.filter((m) => m.role === "assistant" && m.parentID == msg().id) as AssistantMessage[] }) - const assistantMessageParts = createMemo(() => assistantMessages()?.flatMap((m) => data.part[m.id])) + const assistantMessageParts = createMemo(() => assistantMessages()?.flatMap((m) => data.store.part[m.id])) const error = createMemo(() => assistantMessages().find((m) => m?.error)?.error) - const parts = createMemo(() => data.part[msg().id]) + const parts = createMemo(() => data.store.part[msg().id]) const lastTextPart = createMemo(() => assistantMessageParts() .filter((p) => p?.type === "text") @@ -212,7 +212,7 @@ export function SessionTurn(
{(assistantMessage) => { - const parts = createMemo(() => data.part[assistantMessage.id]) + const parts = createMemo(() => data.store.part[assistantMessage.id]) const last = createMemo(() => parts() .filter((p) => p?.type === "text") diff --git a/packages/ui/src/context/data.tsx b/packages/ui/src/context/data.tsx index ad5a212ab..728202a09 100644 --- a/packages/ui/src/context/data.tsx +++ b/packages/ui/src/context/data.tsx @@ -24,6 +24,6 @@ type Data = { export const { use: useData, provider: DataProvider } = createSimpleContext({ name: "Data", init: (props: { data: Data; directory: string }) => { - return { ...props.data, directory: props.directory } + return { store: props.data, directory: props.directory } }, }) From 51455e2a1e182cf91e321ac180476232df932853 Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Wed, 26 Nov 2025 12:04:44 +0000 Subject: [PATCH 05/14] ignore: update download stats 2025-11-26 --- STATS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/STATS.md b/STATS.md index 234ef4132..b58a8f1c5 100644 --- a/STATS.md +++ b/STATS.md @@ -151,3 +151,4 @@ | 2025-11-23 | 846,609 (+9,340) | 795,069 (+14,073) | 1,641,678 (+23,413) | | 2025-11-24 | 856,733 (+10,124) | 804,033 (+8,964) | 1,660,766 (+19,088) | | 2025-11-25 | 869,423 (+12,690) | 817,339 (+13,306) | 1,686,762 (+25,996) | +| 2025-11-26 | 881,414 (+11,991) | 832,518 (+15,179) | 1,713,932 (+27,170) | From 8963b536eee2ff7b46b9751b534e648a5e2a31cc Mon Sep 17 00:00:00 2001 From: Yug Agarwal <148035793+yug49@users.noreply.github.com> Date: Wed, 26 Nov 2025 22:14:05 +0530 Subject: [PATCH 06/14] docs: IO.NET Provider (#4762) --- packages/web/src/content/docs/providers.mdx | 38 +++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/packages/web/src/content/docs/providers.mdx b/packages/web/src/content/docs/providers.mdx index 3d6bd614e..54a4f2397 100644 --- a/packages/web/src/content/docs/providers.mdx +++ b/packages/web/src/content/docs/providers.mdx @@ -652,6 +652,44 @@ The `global` region improves availability and reduces errors at no extra cost. U --- +### IO.NET + +IO.NET offers 17 models optimized for various use cases: + +1. Head over to the [IO.NET console](https://ai.io.net/), create an account, and generate an API key. + +2. Run `opencode auth login` and select **IO.NET**. + + ```bash + $ opencode auth login + + ┌ Add credential + │ + ◆ Select provider + │ ● IO.NET + │ ... + └ + ``` + +3. Enter your IO.NET API key. + + ```bash + $ opencode auth login + + ┌ Add credential + │ + ◇ Select provider + │ IO.NET + │ + ◇ Enter your API key + │ _ + └ + ``` + +4. Run the `/models` command to select a model. + +--- + ### LM Studio You can configure opencode to use local models through LM Studio. From 33f004d4b6c8750c2b74b9790ec55ff883e42656 Mon Sep 17 00:00:00 2001 From: Jensen Date: Thu, 27 Nov 2025 00:49:55 +0800 Subject: [PATCH 07/14] fix(tui): show bootstrap errors instead of {} to trace (#4779) Co-authored-by: Github Action --- .../opencode/src/cli/cmd/tui/context/exit.tsx | 8 +++++--- .../opencode/src/cli/cmd/tui/context/sync.tsx | 6 ++++++ packages/opencode/src/cli/error.ts | 15 +++++++++++++++ 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/packages/opencode/src/cli/cmd/tui/context/exit.tsx b/packages/opencode/src/cli/cmd/tui/context/exit.tsx index 612c39157..3e23f718c 100644 --- a/packages/opencode/src/cli/cmd/tui/context/exit.tsx +++ b/packages/opencode/src/cli/cmd/tui/context/exit.tsx @@ -1,6 +1,6 @@ import { useRenderer } from "@opentui/solid" import { createSimpleContext } from "./helper" -import { FormatError } from "@/cli/error" +import { FormatError, FormatUnknownError } from "@/cli/error" export const { use: useExit, provider: ExitProvider } = createSimpleContext({ name: "Exit", @@ -10,8 +10,10 @@ export const { use: useExit, provider: ExitProvider } = createSimpleContext({ renderer.destroy() await input.onExit?.() if (reason) { - const formatted = FormatError(reason) ?? JSON.stringify(reason) - process.stderr.write(formatted + "\n") + const formatted = FormatError(reason) ?? FormatUnknownError(reason) + if (formatted) { + process.stderr.write(formatted + "\n") + } } process.exit(0) } diff --git a/packages/opencode/src/cli/cmd/tui/context/sync.tsx b/packages/opencode/src/cli/cmd/tui/context/sync.tsx index 80884c73a..0293abace 100644 --- a/packages/opencode/src/cli/cmd/tui/context/sync.tsx +++ b/packages/opencode/src/cli/cmd/tui/context/sync.tsx @@ -23,6 +23,7 @@ import { createSimpleContext } from "./helper" import type { Snapshot } from "@/snapshot" import { useExit } from "./exit" import { batch, onMount } from "solid-js" +import { Log } from "@/util/log" export const { use: useSync, provider: SyncProvider } = createSimpleContext({ name: "Sync", @@ -290,6 +291,11 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({ }) }) .catch(async (e) => { + Log.Default.error("tui bootstrap failed", { + error: e instanceof Error ? e.message : String(e), + name: e instanceof Error ? e.name : undefined, + stack: e instanceof Error ? e.stack : undefined, + }) await exit(e) }) } diff --git a/packages/opencode/src/cli/error.ts b/packages/opencode/src/cli/error.ts index 77f4cec6b..07a53d293 100644 --- a/packages/opencode/src/cli/error.ts +++ b/packages/opencode/src/cli/error.ts @@ -38,3 +38,18 @@ export function FormatError(input: unknown) { if (UI.CancelledError.isInstance(input)) return "" } + +export function FormatUnknownError(input: unknown): string { + if (input instanceof Error) { + return input.stack ?? `${input.name}: ${input.message}` + } + + if (typeof input === "object" && input !== null) { + try { + const json = JSON.stringify(input, null, 2) + if (json && json !== "{}") return json + } catch {} + } + + return String(input) +} From c33920f59d36e899b0589f039ada37797823225e Mon Sep 17 00:00:00 2001 From: opencode Date: Wed, 26 Nov 2025 16:57:35 +0000 Subject: [PATCH 08/14] release: v1.0.115 --- 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 a1fbd7c6f..41d88a231 100644 --- a/bun.lock +++ b/bun.lock @@ -19,7 +19,7 @@ }, "packages/console/app": { "name": "@opencode-ai/console-app", - "version": "1.0.114", + "version": "1.0.115", "dependencies": { "@cloudflare/vite-plugin": "1.15.2", "@ibm/plex": "6.4.1", @@ -47,7 +47,7 @@ }, "packages/console/core": { "name": "@opencode-ai/console-core", - "version": "1.0.114", + "version": "1.0.115", "dependencies": { "@aws-sdk/client-sts": "3.782.0", "@jsx-email/render": "1.1.1", @@ -74,7 +74,7 @@ }, "packages/console/function": { "name": "@opencode-ai/console-function", - "version": "1.0.114", + "version": "1.0.115", "dependencies": { "@ai-sdk/anthropic": "2.0.0", "@ai-sdk/openai": "2.0.2", @@ -98,7 +98,7 @@ }, "packages/console/mail": { "name": "@opencode-ai/console-mail", - "version": "1.0.114", + "version": "1.0.115", "dependencies": { "@jsx-email/all": "2.2.3", "@jsx-email/cli": "1.4.3", @@ -122,7 +122,7 @@ }, "packages/desktop": { "name": "@opencode-ai/desktop", - "version": "1.0.114", + "version": "1.0.115", "dependencies": { "@kobalte/core": "catalog:", "@opencode-ai/sdk": "workspace:*", @@ -163,7 +163,7 @@ }, "packages/enterprise": { "name": "@opencode-ai/enterprise", - "version": "1.0.114", + "version": "1.0.115", "dependencies": { "@opencode-ai/ui": "workspace:*", "@opencode-ai/util": "workspace:*", @@ -191,7 +191,7 @@ }, "packages/function": { "name": "@opencode-ai/function", - "version": "1.0.114", + "version": "1.0.115", "dependencies": { "@octokit/auth-app": "8.0.1", "@octokit/rest": "22.0.0", @@ -207,7 +207,7 @@ }, "packages/opencode": { "name": "opencode", - "version": "1.0.114", + "version": "1.0.115", "bin": { "opencode": "./bin/opencode", }, @@ -294,7 +294,7 @@ }, "packages/plugin": { "name": "@opencode-ai/plugin", - "version": "1.0.114", + "version": "1.0.115", "dependencies": { "@opencode-ai/sdk": "workspace:*", "zod": "catalog:", @@ -314,7 +314,7 @@ }, "packages/sdk/js": { "name": "@opencode-ai/sdk", - "version": "1.0.114", + "version": "1.0.115", "devDependencies": { "@hey-api/openapi-ts": "0.81.0", "@tsconfig/node22": "catalog:", @@ -325,7 +325,7 @@ }, "packages/slack": { "name": "@opencode-ai/slack", - "version": "1.0.114", + "version": "1.0.115", "dependencies": { "@opencode-ai/sdk": "workspace:*", "@slack/bolt": "^3.17.1", @@ -338,7 +338,7 @@ }, "packages/tauri": { "name": "@opencode-ai/tauri", - "version": "1.0.114", + "version": "1.0.115", "dependencies": { "@tauri-apps/api": "^2", "@tauri-apps/plugin-opener": "^2", @@ -351,7 +351,7 @@ }, "packages/ui": { "name": "@opencode-ai/ui", - "version": "1.0.114", + "version": "1.0.115", "dependencies": { "@kobalte/core": "catalog:", "@opencode-ai/sdk": "workspace:*", @@ -383,7 +383,7 @@ }, "packages/util": { "name": "@opencode-ai/util", - "version": "1.0.114", + "version": "1.0.115", "dependencies": { "zod": "catalog:", }, @@ -393,7 +393,7 @@ }, "packages/web": { "name": "@opencode-ai/web", - "version": "1.0.114", + "version": "1.0.115", "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 76b333dff..367d17691 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.114", + "version": "1.0.115", "type": "module", "scripts": { "typecheck": "tsgo --noEmit", diff --git a/packages/console/core/package.json b/packages/console/core/package.json index ad2dcdf4a..377d31bbf 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.114", + "version": "1.0.115", "private": true, "type": "module", "dependencies": { diff --git a/packages/console/function/package.json b/packages/console/function/package.json index f0e09c25c..86b988e0c 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.114", + "version": "1.0.115", "$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 de270f8ff..3a5e37d33 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.114", + "version": "1.0.115", "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 a98738c4c..3d76b42ad 100644 --- a/packages/desktop/package.json +++ b/packages/desktop/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/desktop", - "version": "1.0.114", + "version": "1.0.115", "description": "", "type": "module", "scripts": { diff --git a/packages/enterprise/package.json b/packages/enterprise/package.json index 965e58db5..4117c2490 100644 --- a/packages/enterprise/package.json +++ b/packages/enterprise/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/enterprise", - "version": "1.0.114", + "version": "1.0.115", "private": true, "type": "module", "scripts": { diff --git a/packages/extensions/zed/extension.toml b/packages/extensions/zed/extension.toml index 2dc3c7a1b..057373f4b 100644 --- a/packages/extensions/zed/extension.toml +++ b/packages/extensions/zed/extension.toml @@ -1,7 +1,7 @@ id = "opencode" name = "OpenCode" description = "The AI coding agent built for the terminal" -version = "1.0.114" +version = "1.0.115" 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.114/opencode-darwin-arm64.zip" +archive = "https://github.com/sst/opencode/releases/download/v1.0.115/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.114/opencode-darwin-x64.zip" +archive = "https://github.com/sst/opencode/releases/download/v1.0.115/opencode-darwin-x64.zip" cmd = "./opencode" args = ["acp"] [agent_servers.opencode.targets.linux-aarch64] -archive = "https://github.com/sst/opencode/releases/download/v1.0.114/opencode-linux-arm64.zip" +archive = "https://github.com/sst/opencode/releases/download/v1.0.115/opencode-linux-arm64.zip" cmd = "./opencode" args = ["acp"] [agent_servers.opencode.targets.linux-x86_64] -archive = "https://github.com/sst/opencode/releases/download/v1.0.114/opencode-linux-x64.zip" +archive = "https://github.com/sst/opencode/releases/download/v1.0.115/opencode-linux-x64.zip" cmd = "./opencode" args = ["acp"] [agent_servers.opencode.targets.windows-x86_64] -archive = "https://github.com/sst/opencode/releases/download/v1.0.114/opencode-windows-x64.zip" +archive = "https://github.com/sst/opencode/releases/download/v1.0.115/opencode-windows-x64.zip" cmd = "./opencode.exe" args = ["acp"] diff --git a/packages/function/package.json b/packages/function/package.json index 2868abcd3..a72a8b901 100644 --- a/packages/function/package.json +++ b/packages/function/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/function", - "version": "1.0.114", + "version": "1.0.115", "$schema": "https://json.schemastore.org/package.json", "private": true, "type": "module", diff --git a/packages/opencode/package.json b/packages/opencode/package.json index e75542083..8d5bf4967 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.114", + "version": "1.0.115", "name": "opencode", "type": "module", "private": true, diff --git a/packages/plugin/package.json b/packages/plugin/package.json index c08186b20..c60104e87 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.114", + "version": "1.0.115", "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 1d8ae6371..0566b19d2 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.114", + "version": "1.0.115", "type": "module", "scripts": { "typecheck": "tsgo --noEmit", @@ -26,4 +26,4 @@ "publishConfig": { "directory": "dist" } -} +} \ No newline at end of file diff --git a/packages/slack/package.json b/packages/slack/package.json index 8f6af596f..693608844 100644 --- a/packages/slack/package.json +++ b/packages/slack/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/slack", - "version": "1.0.114", + "version": "1.0.115", "type": "module", "scripts": { "dev": "bun run src/index.ts", diff --git a/packages/tauri/package.json b/packages/tauri/package.json index 9363c50b4..c200e2138 100644 --- a/packages/tauri/package.json +++ b/packages/tauri/package.json @@ -1,7 +1,7 @@ { "name": "@opencode-ai/tauri", "private": true, - "version": "1.0.114", + "version": "1.0.115", "type": "module", "scripts": { "dev": "vite", diff --git a/packages/ui/package.json b/packages/ui/package.json index eb126a6fa..caa9e5963 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/ui", - "version": "1.0.114", + "version": "1.0.115", "type": "module", "exports": { "./*": "./src/components/*.tsx", diff --git a/packages/util/package.json b/packages/util/package.json index d99bdae17..bbfe743f4 100644 --- a/packages/util/package.json +++ b/packages/util/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/util", - "version": "1.0.114", + "version": "1.0.115", "private": true, "type": "module", "exports": { diff --git a/packages/web/package.json b/packages/web/package.json index 95c4850ad..2baace04c 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -1,7 +1,7 @@ { "name": "@opencode-ai/web", "type": "module", - "version": "1.0.114", + "version": "1.0.115", "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 35506a804..9d6598590 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.114", + "version": "1.0.115", "publisher": "sst-dev", "repository": { "type": "git", From 382758790c00fbea8c2ec6a4b2dab0e1959320fd Mon Sep 17 00:00:00 2001 From: "Tommy D. Rossi" Date: Wed, 26 Nov 2025 18:26:05 +0100 Subject: [PATCH 09/14] fix(tui): dedupe file references in prompt (#4775) --- packages/opencode/src/session/prompt.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/opencode/src/session/prompt.ts b/packages/opencode/src/session/prompt.ts index a9c85caf1..9152fc99b 100644 --- a/packages/opencode/src/session/prompt.ts +++ b/packages/opencode/src/session/prompt.ts @@ -150,9 +150,12 @@ export namespace SessionPrompt { }, ] const files = ConfigMarkdown.files(template) + const seen = new Set() await Promise.all( files.map(async (match) => { const name = match[1] + if (seen.has(name)) return + seen.add(name) const filepath = name.startsWith("~/") ? path.join(os.homedir(), name.slice(2)) : path.resolve(Instance.worktree, name) From e8e474597cbdacf67970465699752ea360cea79b Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Wed, 26 Nov 2025 17:26:46 +0000 Subject: [PATCH 10/14] chore: format code --- 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 c60104e87..90159f73b 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 0566b19d2..af95a2193 100644 --- a/packages/sdk/js/package.json +++ b/packages/sdk/js/package.json @@ -26,4 +26,4 @@ "publishConfig": { "directory": "dist" } -} \ No newline at end of file +} From 98031173b6cbf91aa20b110c07b2f18526b14d03 Mon Sep 17 00:00:00 2001 From: Dax Raad Date: Wed, 26 Nov 2025 12:34:48 -0500 Subject: [PATCH 11/14] lil branch refactor --- packages/opencode/src/cli/cmd/tui/app.tsx | 2 +- .../opencode/src/cli/cmd/tui/context/sync.tsx | 2 +- packages/opencode/src/project/vcs.ts | 9 ++++++++ packages/opencode/src/server/server.ts | 22 ++----------------- packages/sdk/js/src/gen/types.gen.ts | 7 +----- 5 files changed, 14 insertions(+), 28 deletions(-) diff --git a/packages/opencode/src/cli/cmd/tui/app.tsx b/packages/opencode/src/cli/cmd/tui/app.tsx index 13b02154e..7c72274ad 100644 --- a/packages/opencode/src/cli/cmd/tui/app.tsx +++ b/packages/opencode/src/cli/cmd/tui/app.tsx @@ -480,7 +480,7 @@ function App() { {process.cwd().replace(Global.Path.home, "~")} - {sync.data.vcs?.vcs?.branch ? `:${sync.data.vcs.vcs.branch}` : ""} + {sync.data.vcs?.branch ? `:${sync.data.vcs.branch}` : ""} diff --git a/packages/opencode/src/cli/cmd/tui/context/sync.tsx b/packages/opencode/src/cli/cmd/tui/context/sync.tsx index 0293abace..b7ef8a221 100644 --- a/packages/opencode/src/cli/cmd/tui/context/sync.tsx +++ b/packages/opencode/src/cli/cmd/tui/context/sync.tsx @@ -244,7 +244,7 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({ } case "vcs.branch.updated": { - setStore("vcs", "vcs", { branch: event.properties.branch }) + setStore("vcs", { branch: event.properties.branch }) break } } diff --git a/packages/opencode/src/project/vcs.ts b/packages/opencode/src/project/vcs.ts index 59b2f99b7..c3b21f3be 100644 --- a/packages/opencode/src/project/vcs.ts +++ b/packages/opencode/src/project/vcs.ts @@ -18,6 +18,15 @@ export namespace Vcs { ), } + export const Info = z + .object({ + branch: z.string(), + }) + .meta({ + ref: "VcsInfo", + }) + export type Info = z.infer + async function currentBranch() { return $`git rev-parse --abbrev-ref HEAD` .quiet() diff --git a/packages/opencode/src/server/server.ts b/packages/opencode/src/server/server.ts index 1c8d2a003..7743e3dbb 100644 --- a/packages/opencode/src/server/server.ts +++ b/packages/opencode/src/server/server.ts @@ -376,22 +376,7 @@ export namespace Server { description: "VCS info", content: { "application/json": { - schema: resolver( - z - .object({ - worktree: z.string(), - directory: z.string(), - projectID: z.string(), - vcs: z - .object({ - branch: z.string(), - }) - .optional(), - }) - .meta({ - ref: "VcsInfo", - }), - ), + schema: resolver(Vcs.Info), }, }, }, @@ -400,10 +385,7 @@ export namespace Server { async (c) => { const branch = await Vcs.branch() return c.json({ - worktree: Instance.worktree, - directory: Instance.directory, - projectID: Instance.project.id, - vcs: Instance.project.vcs ? { branch } : undefined, + branch, }) }, ) diff --git a/packages/sdk/js/src/gen/types.gen.ts b/packages/sdk/js/src/gen/types.gen.ts index 08335dd39..efa5c9946 100644 --- a/packages/sdk/js/src/gen/types.gen.ts +++ b/packages/sdk/js/src/gen/types.gen.ts @@ -1264,12 +1264,7 @@ export type Path = { } export type VcsInfo = { - worktree: string - directory: string - projectID: string - vcs?: { - branch: string - } + branch: string } export type NotFoundError = { From 4d07034930a3ffed418b6b67e70469be2855af47 Mon Sep 17 00:00:00 2001 From: Aiden Cline Date: Wed, 26 Nov 2025 12:38:48 -0600 Subject: [PATCH 12/14] fix: svg paste bug --- .../cli/cmd/tui/component/prompt/index.tsx | 81 ++++++++++--------- 1 file changed, 45 insertions(+), 36 deletions(-) diff --git a/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx b/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx index 7249091e9..19986f8b6 100644 --- a/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx +++ b/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx @@ -496,6 +496,40 @@ export function Prompt(props: PromptProps) { } const exit = useExit() + function pasteText(text: string, virtualText: string) { + const currentOffset = input.visualCursor.offset + const extmarkStart = currentOffset + const extmarkEnd = extmarkStart + virtualText.length + + input.insertText(virtualText + " ") + + const extmarkId = input.extmarks.create({ + start: extmarkStart, + end: extmarkEnd, + virtual: true, + styleId: pasteStyleId, + typeId: promptPartTypeId, + }) + + setStore( + produce((draft) => { + const partIndex = draft.prompt.parts.length + draft.prompt.parts.push({ + type: "text" as const, + text, + source: { + text: { + start: extmarkStart, + end: extmarkEnd, + value: virtualText, + }, + }, + }) + draft.extmarkToPartIndex.set(extmarkId, partIndex) + }), + ) + } + async function pasteImage(file: { filename?: string; content: string; mime: string }) { const currentOffset = input.visualCursor.offset const extmarkStart = currentOffset @@ -709,12 +743,21 @@ export function Prompt(props: PromptProps) { if (!isUrl) { try { const file = Bun.file(filepath) + // Handle SVG as raw text content, not as base64 image + if (file.type === "image/svg+xml") { + event.preventDefault() + const content = await file.text().catch(() => {}) + if (content) { + pasteText(content, `[SVG: ${file.name ?? "image"}]`) + return + } + } if (file.type.startsWith("image/")) { event.preventDefault() const content = await file .arrayBuffer() .then((buffer) => Buffer.from(buffer).toString("base64")) - .catch(console.error) + .catch(() => {}) if (content) { await pasteImage({ filename: file.name, @@ -733,41 +776,7 @@ export function Prompt(props: PromptProps) { !sync.data.config.experimental?.disable_paste_summary ) { event.preventDefault() - const currentOffset = input.visualCursor.offset - const virtualText = `[Pasted ~${lineCount} lines]` - const textToInsert = virtualText + " " - const extmarkStart = currentOffset - const extmarkEnd = extmarkStart + virtualText.length - - input.insertText(textToInsert) - - const extmarkId = input.extmarks.create({ - start: extmarkStart, - end: extmarkEnd, - virtual: true, - styleId: pasteStyleId, - typeId: promptPartTypeId, - }) - - const part = { - type: "text" as const, - text: pastedContent, - source: { - text: { - start: extmarkStart, - end: extmarkEnd, - value: virtualText, - }, - }, - } - - setStore( - produce((draft) => { - const partIndex = draft.prompt.parts.length - draft.prompt.parts.push(part) - draft.extmarkToPartIndex.set(extmarkId, partIndex) - }), - ) + pasteText(pastedContent, `[Pasted ~${lineCount} lines]`) return } }} From 1854245bd35901a91a243e8e0a07d8db961a7192 Mon Sep 17 00:00:00 2001 From: rosmur <89332196+rosmur@users.noreply.github.com> Date: Wed, 26 Nov 2025 11:10:15 -0800 Subject: [PATCH 13/14] docs: add llama.cpp provider for local LLM inference (#4769) Co-authored-by: Aiden Cline <63023139+rekram1-node@users.noreply.github.com> --- packages/web/src/content/docs/providers.mdx | 38 +++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/packages/web/src/content/docs/providers.mdx b/packages/web/src/content/docs/providers.mdx index 54a4f2397..716402b88 100644 --- a/packages/web/src/content/docs/providers.mdx +++ b/packages/web/src/content/docs/providers.mdx @@ -652,6 +652,44 @@ The `global` region improves availability and reduces errors at no extra cost. U --- +### llama.cpp + +You can configure opencode to use local models through [llama.cpp's](https://github.com/ggml-org/llama.cpp) llama-server utility + +```json title="opencode.json" "llama.cpp" {5, 6, 8, 10-14} +{ + "$schema": "https://opencode.ai/config.json", + "provider": { + "llama.cpp": { + "npm": "@ai-sdk/openai-compatible", + "name": "llama-server (local)", + "options": { + "baseURL": "http://127.0.0.1:8080/v1" + }, + "models": { + "qwen3-coder:a3b": { + "name": "Qwen3-Coder: a3b-30b (local)" + } + }, + "limit": { + "context": 128000, + "output": 65536 + } + } + } +} +``` + +In this example: + +- `llama.cpp` is the custom provider ID. This can be any string you want. +- `npm` specifies the package to use for this provider. Here, `@ai-sdk/openai-compatible` is used for any OpenAI-compatible API. +- `name` is the display name for the provider in the UI. +- `options.baseURL` is the endpoint for the local server. +- `models` is a map of model IDs to their configurations. The model name will be displayed in the model selection list. + +--- + ### IO.NET IO.NET offers 17 models optimized for various use cases: From 4d2b265dc4a944cdf885672d0d04baee8827e253 Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Wed, 26 Nov 2025 19:10:51 +0000 Subject: [PATCH 14/14] chore: format code --- packages/web/src/content/docs/providers.mdx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/web/src/content/docs/providers.mdx b/packages/web/src/content/docs/providers.mdx index 716402b88..0e8019082 100644 --- a/packages/web/src/content/docs/providers.mdx +++ b/packages/web/src/content/docs/providers.mdx @@ -671,9 +671,9 @@ You can configure opencode to use local models through [llama.cpp's](https://git "name": "Qwen3-Coder: a3b-30b (local)" } }, - "limit": { - "context": 128000, - "output": 65536 + "limit": { + "context": 128000, + "output": 65536 } } }