From 6c7d968c4423a0cd6c85099c9377a6066313fa0a Mon Sep 17 00:00:00 2001 From: opencode Date: Fri, 6 Mar 2026 07:29:34 +0000 Subject: [PATCH 1/8] release: v1.2.20 --- bun.lock | 32 +++++++++++++------------- packages/app/package.json | 2 +- 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-electron/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/ui/package.json | 2 +- packages/util/package.json | 2 +- packages/web/package.json | 2 +- sdks/vscode/package.json | 2 +- 19 files changed, 39 insertions(+), 39 deletions(-) diff --git a/bun.lock b/bun.lock index 6539faa83..fcc0fcbbb 100644 --- a/bun.lock +++ b/bun.lock @@ -26,7 +26,7 @@ }, "packages/app": { "name": "@opencode-ai/app", - "version": "1.2.19", + "version": "1.2.20", "dependencies": { "@kobalte/core": "catalog:", "@opencode-ai/sdk": "workspace:*", @@ -76,7 +76,7 @@ }, "packages/console/app": { "name": "@opencode-ai/console-app", - "version": "1.2.19", + "version": "1.2.20", "dependencies": { "@cloudflare/vite-plugin": "1.15.2", "@ibm/plex": "6.4.1", @@ -110,7 +110,7 @@ }, "packages/console/core": { "name": "@opencode-ai/console-core", - "version": "1.2.19", + "version": "1.2.20", "dependencies": { "@aws-sdk/client-sts": "3.782.0", "@jsx-email/render": "1.1.1", @@ -137,7 +137,7 @@ }, "packages/console/function": { "name": "@opencode-ai/console-function", - "version": "1.2.19", + "version": "1.2.20", "dependencies": { "@ai-sdk/anthropic": "2.0.0", "@ai-sdk/openai": "2.0.2", @@ -161,7 +161,7 @@ }, "packages/console/mail": { "name": "@opencode-ai/console-mail", - "version": "1.2.19", + "version": "1.2.20", "dependencies": { "@jsx-email/all": "2.2.3", "@jsx-email/cli": "1.4.3", @@ -185,7 +185,7 @@ }, "packages/desktop": { "name": "@opencode-ai/desktop", - "version": "1.2.19", + "version": "1.2.20", "dependencies": { "@opencode-ai/app": "workspace:*", "@opencode-ai/ui": "workspace:*", @@ -218,7 +218,7 @@ }, "packages/desktop-electron": { "name": "@opencode-ai/desktop-electron", - "version": "1.2.19", + "version": "1.2.20", "dependencies": { "@opencode-ai/app": "workspace:*", "@opencode-ai/ui": "workspace:*", @@ -248,7 +248,7 @@ }, "packages/enterprise": { "name": "@opencode-ai/enterprise", - "version": "1.2.19", + "version": "1.2.20", "dependencies": { "@opencode-ai/ui": "workspace:*", "@opencode-ai/util": "workspace:*", @@ -277,7 +277,7 @@ }, "packages/function": { "name": "@opencode-ai/function", - "version": "1.2.19", + "version": "1.2.20", "dependencies": { "@octokit/auth-app": "8.0.1", "@octokit/rest": "catalog:", @@ -293,7 +293,7 @@ }, "packages/opencode": { "name": "opencode", - "version": "1.2.19", + "version": "1.2.20", "bin": { "opencode": "./bin/opencode", }, @@ -409,7 +409,7 @@ }, "packages/plugin": { "name": "@opencode-ai/plugin", - "version": "1.2.19", + "version": "1.2.20", "dependencies": { "@opencode-ai/sdk": "workspace:*", "zod": "catalog:", @@ -429,7 +429,7 @@ }, "packages/sdk/js": { "name": "@opencode-ai/sdk", - "version": "1.2.19", + "version": "1.2.20", "devDependencies": { "@hey-api/openapi-ts": "0.90.10", "@tsconfig/node22": "catalog:", @@ -440,7 +440,7 @@ }, "packages/slack": { "name": "@opencode-ai/slack", - "version": "1.2.19", + "version": "1.2.20", "dependencies": { "@opencode-ai/sdk": "workspace:*", "@slack/bolt": "^3.17.1", @@ -475,7 +475,7 @@ }, "packages/ui": { "name": "@opencode-ai/ui", - "version": "1.2.19", + "version": "1.2.20", "dependencies": { "@kobalte/core": "catalog:", "@opencode-ai/sdk": "workspace:*", @@ -521,7 +521,7 @@ }, "packages/util": { "name": "@opencode-ai/util", - "version": "1.2.19", + "version": "1.2.20", "dependencies": { "zod": "catalog:", }, @@ -532,7 +532,7 @@ }, "packages/web": { "name": "@opencode-ai/web", - "version": "1.2.19", + "version": "1.2.20", "dependencies": { "@astrojs/cloudflare": "12.6.3", "@astrojs/markdown-remark": "6.3.1", diff --git a/packages/app/package.json b/packages/app/package.json index 809a28537..c91a91383 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/app", - "version": "1.2.19", + "version": "1.2.20", "description": "", "type": "module", "exports": { diff --git a/packages/console/app/package.json b/packages/console/app/package.json index 269b005a8..4d20c1b8b 100644 --- a/packages/console/app/package.json +++ b/packages/console/app/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/console-app", - "version": "1.2.19", + "version": "1.2.20", "type": "module", "license": "MIT", "scripts": { diff --git a/packages/console/core/package.json b/packages/console/core/package.json index 199b5d9bd..408e2a7ac 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.2.19", + "version": "1.2.20", "private": true, "type": "module", "license": "MIT", diff --git a/packages/console/function/package.json b/packages/console/function/package.json index e771aae84..8df6594d0 100644 --- a/packages/console/function/package.json +++ b/packages/console/function/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/console-function", - "version": "1.2.19", + "version": "1.2.20", "$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 ef8d7c599..591c4bd36 100644 --- a/packages/console/mail/package.json +++ b/packages/console/mail/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/console-mail", - "version": "1.2.19", + "version": "1.2.20", "dependencies": { "@jsx-email/all": "2.2.3", "@jsx-email/cli": "1.4.3", diff --git a/packages/desktop-electron/package.json b/packages/desktop-electron/package.json index e683d185b..31321c92a 100644 --- a/packages/desktop-electron/package.json +++ b/packages/desktop-electron/package.json @@ -1,7 +1,7 @@ { "name": "@opencode-ai/desktop-electron", "private": true, - "version": "1.2.19", + "version": "1.2.20", "type": "module", "license": "MIT", "homepage": "https://opencode.ai", diff --git a/packages/desktop/package.json b/packages/desktop/package.json index 10e6df26b..da4d51bcc 100644 --- a/packages/desktop/package.json +++ b/packages/desktop/package.json @@ -1,7 +1,7 @@ { "name": "@opencode-ai/desktop", "private": true, - "version": "1.2.19", + "version": "1.2.20", "type": "module", "license": "MIT", "scripts": { diff --git a/packages/enterprise/package.json b/packages/enterprise/package.json index ef56add88..2531cf34f 100644 --- a/packages/enterprise/package.json +++ b/packages/enterprise/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/enterprise", - "version": "1.2.19", + "version": "1.2.20", "private": true, "type": "module", "license": "MIT", diff --git a/packages/extensions/zed/extension.toml b/packages/extensions/zed/extension.toml index 1637c58a4..d45bec230 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.2.19" +version = "1.2.20" schema_version = 1 authors = ["Anomaly"] repository = "https://github.com/anomalyco/opencode" @@ -11,26 +11,26 @@ name = "OpenCode" icon = "./icons/opencode.svg" [agent_servers.opencode.targets.darwin-aarch64] -archive = "https://github.com/anomalyco/opencode/releases/download/v1.2.19/opencode-darwin-arm64.zip" +archive = "https://github.com/anomalyco/opencode/releases/download/v1.2.20/opencode-darwin-arm64.zip" cmd = "./opencode" args = ["acp"] [agent_servers.opencode.targets.darwin-x86_64] -archive = "https://github.com/anomalyco/opencode/releases/download/v1.2.19/opencode-darwin-x64.zip" +archive = "https://github.com/anomalyco/opencode/releases/download/v1.2.20/opencode-darwin-x64.zip" cmd = "./opencode" args = ["acp"] [agent_servers.opencode.targets.linux-aarch64] -archive = "https://github.com/anomalyco/opencode/releases/download/v1.2.19/opencode-linux-arm64.tar.gz" +archive = "https://github.com/anomalyco/opencode/releases/download/v1.2.20/opencode-linux-arm64.tar.gz" cmd = "./opencode" args = ["acp"] [agent_servers.opencode.targets.linux-x86_64] -archive = "https://github.com/anomalyco/opencode/releases/download/v1.2.19/opencode-linux-x64.tar.gz" +archive = "https://github.com/anomalyco/opencode/releases/download/v1.2.20/opencode-linux-x64.tar.gz" cmd = "./opencode" args = ["acp"] [agent_servers.opencode.targets.windows-x86_64] -archive = "https://github.com/anomalyco/opencode/releases/download/v1.2.19/opencode-windows-x64.zip" +archive = "https://github.com/anomalyco/opencode/releases/download/v1.2.20/opencode-windows-x64.zip" cmd = "./opencode.exe" args = ["acp"] diff --git a/packages/function/package.json b/packages/function/package.json index efaae65f5..adc3bfcb0 100644 --- a/packages/function/package.json +++ b/packages/function/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/function", - "version": "1.2.19", + "version": "1.2.20", "$schema": "https://json.schemastore.org/package.json", "private": true, "type": "module", diff --git a/packages/opencode/package.json b/packages/opencode/package.json index fde3ace92..f502382ba 100644 --- a/packages/opencode/package.json +++ b/packages/opencode/package.json @@ -1,6 +1,6 @@ { "$schema": "https://json.schemastore.org/package.json", - "version": "1.2.19", + "version": "1.2.20", "name": "opencode", "type": "module", "license": "MIT", diff --git a/packages/plugin/package.json b/packages/plugin/package.json index d8911922e..7419f4ecc 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.2.19", + "version": "1.2.20", "type": "module", "license": "MIT", "scripts": { diff --git a/packages/sdk/js/package.json b/packages/sdk/js/package.json index fe3ce393d..ced7f6c05 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.2.19", + "version": "1.2.20", "type": "module", "license": "MIT", "scripts": { diff --git a/packages/slack/package.json b/packages/slack/package.json index d37e14058..fbdf202fd 100644 --- a/packages/slack/package.json +++ b/packages/slack/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/slack", - "version": "1.2.19", + "version": "1.2.20", "type": "module", "license": "MIT", "scripts": { diff --git a/packages/ui/package.json b/packages/ui/package.json index 48c668c6f..db585bb00 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/ui", - "version": "1.2.19", + "version": "1.2.20", "type": "module", "license": "MIT", "exports": { diff --git a/packages/util/package.json b/packages/util/package.json index bc84be636..b6ee1c3bf 100644 --- a/packages/util/package.json +++ b/packages/util/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/util", - "version": "1.2.19", + "version": "1.2.20", "private": true, "type": "module", "license": "MIT", diff --git a/packages/web/package.json b/packages/web/package.json index c85ba1a0b..e386f581f 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -2,7 +2,7 @@ "name": "@opencode-ai/web", "type": "module", "license": "MIT", - "version": "1.2.19", + "version": "1.2.20", "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 215143ac9..f900f1099 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.2.19", + "version": "1.2.20", "publisher": "sst-dev", "repository": { "type": "git", From b7605add5803becb0a1abd9fb5110cb636cc6d01 Mon Sep 17 00:00:00 2001 From: Luis Felipe Cordeiro Sena <61807189+luisfelipesena@users.noreply.github.com> Date: Fri, 6 Mar 2026 07:49:12 -0300 Subject: [PATCH 2/8] fix(app): enable auto-accept keybind regardless of permission config (#16259) --- packages/app/src/components/prompt-input.tsx | 12 +--- .../context/permission-auto-respond.test.ts | 41 ++++++++++- .../src/context/permission-auto-respond.ts | 12 +++- packages/app/src/context/permission.tsx | 70 ++++++++++++++++++- .../pages/session/use-session-commands.tsx | 29 +++++--- packages/opencode/script/build.ts | 6 +- 6 files changed, 145 insertions(+), 25 deletions(-) diff --git a/packages/app/src/components/prompt-input.tsx b/packages/app/src/components/prompt-input.tsx index c9c8bc6b4..40104bceb 100644 --- a/packages/app/src/components/prompt-input.tsx +++ b/packages/app/src/components/prompt-input.tsx @@ -244,7 +244,6 @@ export const PromptInput: Component = (props) => { draggingType: "image" | "@mention" | null mode: "normal" | "shell" applyingHistory: boolean - pendingAutoAccept: boolean }>({ popover: null, historyIndex: -1, @@ -253,7 +252,6 @@ export const PromptInput: Component = (props) => { draggingType: null, mode: "normal", applyingHistory: false, - pendingAutoAccept: false, }) const buttonsSpring = useSpring(() => (store.mode === "normal" ? 1 : 0), { visualDuration: 0.2, bounce: 0 }) @@ -306,12 +304,6 @@ export const PromptInput: Component = (props) => { }), ) - createEffect( - on(sessionKey, () => { - setStore("pendingAutoAccept", false) - }), - ) - const historyComments = () => { const byID = new Map(comments.all().map((item) => [`${item.file}\n${item.id}`, item] as const)) return prompt.context.items().flatMap((item) => { @@ -961,7 +953,7 @@ export const PromptInput: Component = (props) => { const variants = createMemo(() => ["default", ...local.model.variant.list()]) const accepting = createMemo(() => { const id = params.id - if (!id) return store.pendingAutoAccept + if (!id) return permission.isAutoAcceptingDirectory(sdk.directory) return permission.isAutoAccepting(id, sdk.directory) }) @@ -1336,7 +1328,7 @@ export const PromptInput: Component = (props) => { variant="ghost" onClick={() => { if (!params.id) { - setStore("pendingAutoAccept", (value) => !value) + permission.toggleAutoAcceptDirectory(sdk.directory) return } permission.toggleAutoAccept(params.id, sdk.directory) diff --git a/packages/app/src/context/permission-auto-respond.test.ts b/packages/app/src/context/permission-auto-respond.test.ts index 2e4cf4faf..755611300 100644 --- a/packages/app/src/context/permission-auto-respond.test.ts +++ b/packages/app/src/context/permission-auto-respond.test.ts @@ -1,7 +1,7 @@ import { describe, expect, test } from "bun:test" import type { PermissionRequest, Session } from "@opencode-ai/sdk/v2/client" import { base64Encode } from "@opencode-ai/util/encode" -import { autoRespondsPermission } from "./permission-auto-respond" +import { autoRespondsPermission, isDirectoryAutoAccepting } from "./permission-auto-respond" const session = (input: { id: string; parentID?: string }) => ({ @@ -60,4 +60,43 @@ describe("autoRespondsPermission", () => { expect(autoRespondsPermission(autoAccept, sessions, permission("child"), directory)).toBe(true) }) + + test("falls back to directory-level auto-accept", () => { + const directory = "/tmp/project" + const sessions = [session({ id: "root" })] + const autoAccept = { + [`${base64Encode(directory)}/*`]: true, + } + + expect(autoRespondsPermission(autoAccept, sessions, permission("root"), directory)).toBe(true) + }) + + test("session-level override takes precedence over directory-level", () => { + const directory = "/tmp/project" + const sessions = [session({ id: "root" })] + const autoAccept = { + [`${base64Encode(directory)}/*`]: true, + [`${base64Encode(directory)}/root`]: false, + } + + expect(autoRespondsPermission(autoAccept, sessions, permission("root"), directory)).toBe(false) + }) +}) + +describe("isDirectoryAutoAccepting", () => { + test("returns true when directory key is set", () => { + const directory = "/tmp/project" + const autoAccept = { [`${base64Encode(directory)}/*`]: true } + expect(isDirectoryAutoAccepting(autoAccept, directory)).toBe(true) + }) + + test("returns false when directory key is not set", () => { + expect(isDirectoryAutoAccepting({}, "/tmp/project")).toBe(false) + }) + + test("returns false when directory key is explicitly false", () => { + const directory = "/tmp/project" + const autoAccept = { [`${base64Encode(directory)}/*`]: false } + expect(isDirectoryAutoAccepting(autoAccept, directory)).toBe(false) + }) }) diff --git a/packages/app/src/context/permission-auto-respond.ts b/packages/app/src/context/permission-auto-respond.ts index 727ccc937..b206deedf 100644 --- a/packages/app/src/context/permission-auto-respond.ts +++ b/packages/app/src/context/permission-auto-respond.ts @@ -5,9 +5,19 @@ export function acceptKey(sessionID: string, directory?: string) { return `${base64Encode(directory)}/${sessionID}` } +export function directoryAcceptKey(directory: string) { + return `${base64Encode(directory)}/*` +} + function accepted(autoAccept: Record, sessionID: string, directory?: string) { const key = acceptKey(sessionID, directory) - return autoAccept[key] ?? autoAccept[sessionID] + const directoryKey = directory ? directoryAcceptKey(directory) : undefined + return autoAccept[key] ?? autoAccept[sessionID] ?? (directoryKey ? autoAccept[directoryKey] : undefined) +} + +export function isDirectoryAutoAccepting(autoAccept: Record, directory: string) { + const key = directoryAcceptKey(directory) + return autoAccept[key] ?? false } function sessionLineage(session: { id: string; parentID?: string }[], sessionID: string) { diff --git a/packages/app/src/context/permission.tsx b/packages/app/src/context/permission.tsx index 73ee08c9a..8208e46b9 100644 --- a/packages/app/src/context/permission.tsx +++ b/packages/app/src/context/permission.tsx @@ -1,4 +1,4 @@ -import { createMemo, onCleanup } from "solid-js" +import { createEffect, createMemo, onCleanup } from "solid-js" import { createStore, produce } from "solid-js/store" import { createSimpleContext } from "@opencode-ai/ui/context" import type { PermissionRequest } from "@opencode-ai/sdk/v2/client" @@ -7,7 +7,7 @@ import { useGlobalSDK } from "@/context/global-sdk" import { useGlobalSync } from "./global-sync" import { useParams } from "@solidjs/router" import { decode64 } from "@/utils/base64" -import { acceptKey, autoRespondsPermission } from "./permission-auto-respond" +import { acceptKey, directoryAcceptKey, isDirectoryAutoAccepting, autoRespondsPermission } from "./permission-auto-respond" type PermissionRespondFn = (input: { sessionID: string @@ -76,6 +76,25 @@ export const { use: usePermission, provider: PermissionProvider } = createSimple }), ) + // When config has permission: "allow", auto-enable directory-level auto-accept + createEffect(() => { + if (!ready()) return + const directory = decode64(params.dir) + if (!directory) return + const [childStore] = globalSync.child(directory) + const perm = childStore.config.permission + if (typeof perm === "string" && perm === "allow") { + const key = directoryAcceptKey(directory) + if (store.autoAccept[key] === undefined) { + setStore( + produce((draft) => { + draft.autoAccept[key] = true + }), + ) + } + } + }) + const MAX_RESPONDED = 1000 const RESPONDED_TTL_MS = 60 * 60 * 1000 const responded = new Map() @@ -119,6 +138,10 @@ export const { use: usePermission, provider: PermissionProvider } = createSimple return autoRespondsPermission(store.autoAccept, session, { sessionID }, directory) } + function isAutoAcceptingDirectory(directory: string) { + return isDirectoryAutoAccepting(store.autoAccept, directory) + } + function shouldAutoRespond(permission: PermissionRequest, directory?: string) { const session = directory ? globalSync.child(directory, { bootstrap: false })[0].session : [] return autoRespondsPermission(store.autoAccept, session, permission, directory) @@ -142,6 +165,36 @@ export const { use: usePermission, provider: PermissionProvider } = createSimple }) onCleanup(unsubscribe) + function enableDirectory(directory: string) { + const key = directoryAcceptKey(directory) + setStore( + produce((draft) => { + draft.autoAccept[key] = true + }), + ) + + globalSDK.client.permission + .list({ directory }) + .then((x) => { + if (!isAutoAcceptingDirectory(directory)) return + for (const perm of x.data ?? []) { + if (!perm?.id) continue + if (!shouldAutoRespond(perm, directory)) continue + respondOnce(perm, directory) + } + }) + .catch(() => undefined) + } + + function disableDirectory(directory: string) { + const key = directoryAcceptKey(directory) + setStore( + produce((draft) => { + draft.autoAccept[key] = false + }), + ) + } + function enable(sessionID: string, directory: string) { const key = acceptKey(sessionID, directory) const version = bumpEnableVersion(sessionID, directory) @@ -185,6 +238,7 @@ export const { use: usePermission, provider: PermissionProvider } = createSimple return shouldAutoRespond(permission, directory) }, isAutoAccepting, + isAutoAcceptingDirectory, toggleAutoAccept(sessionID: string, directory: string) { if (isAutoAccepting(sessionID, directory)) { disable(sessionID, directory) @@ -193,6 +247,13 @@ export const { use: usePermission, provider: PermissionProvider } = createSimple enable(sessionID, directory) }, + toggleAutoAcceptDirectory(directory: string) { + if (isAutoAcceptingDirectory(directory)) { + disableDirectory(directory) + return + } + enableDirectory(directory) + }, enableAutoAccept(sessionID: string, directory: string) { if (isAutoAccepting(sessionID, directory)) return enable(sessionID, directory) @@ -201,6 +262,11 @@ export const { use: usePermission, provider: PermissionProvider } = createSimple disable(sessionID, directory) }, permissionsEnabled, + isPermissionAllowAll(directory: string) { + const [childStore] = globalSync.child(directory) + const perm = childStore.config.permission + return typeof perm === "string" && perm === "allow" + }, } }, }) diff --git a/packages/app/src/pages/session/use-session-commands.tsx b/packages/app/src/pages/session/use-session-commands.tsx index 461351878..b8ddeda82 100644 --- a/packages/app/src/pages/session/use-session-commands.tsx +++ b/packages/app/src/pages/session/use-session-commands.tsx @@ -261,24 +261,35 @@ export const useSessionCommands = (actions: SessionCommandContext) => { }), ]) + const isAutoAcceptActive = () => { + const sessionID = params.id + if (sessionID) return permission.isAutoAccepting(sessionID, sdk.directory) + return permission.isAutoAcceptingDirectory(sdk.directory) + } + const permissionCommands = createMemo(() => [ permissionsCommand({ id: "permissions.autoaccept", - title: - params.id && permission.isAutoAccepting(params.id, sdk.directory) - ? language.t("command.permissions.autoaccept.disable") - : language.t("command.permissions.autoaccept.enable"), + title: isAutoAcceptActive() + ? language.t("command.permissions.autoaccept.disable") + : language.t("command.permissions.autoaccept.enable"), keybind: "mod+shift+a", - disabled: !params.id || !permission.permissionsEnabled(), + disabled: false, onSelect: () => { const sessionID = params.id - if (!sessionID) return - permission.toggleAutoAccept(sessionID, sdk.directory) + if (sessionID) { + permission.toggleAutoAccept(sessionID, sdk.directory) + } else { + permission.toggleAutoAcceptDirectory(sdk.directory) + } + const active = sessionID + ? permission.isAutoAccepting(sessionID, sdk.directory) + : permission.isAutoAcceptingDirectory(sdk.directory) showToast({ - title: permission.isAutoAccepting(sessionID, sdk.directory) + title: active ? language.t("toast.permissions.autoaccept.on.title") : language.t("toast.permissions.autoaccept.off.title"), - description: permission.isAutoAccepting(sessionID, sdk.directory) + description: active ? language.t("toast.permissions.autoaccept.on.description") : language.t("toast.permissions.autoaccept.off.description"), }) diff --git a/packages/opencode/script/build.ts b/packages/opencode/script/build.ts index 34e80d71a..b5d6e8adf 100755 --- a/packages/opencode/script/build.ts +++ b/packages/opencode/script/build.ts @@ -4,7 +4,7 @@ import { $ } from "bun" import fs from "fs" import path from "path" import { fileURLToPath } from "url" -import solidPlugin from "../node_modules/@opentui/solid/scripts/solid-plugin" +import solidPlugin from "@opentui/solid/bun-plugin" const __filename = fileURLToPath(import.meta.url) const __dirname = path.dirname(__filename) @@ -161,7 +161,9 @@ for (const item of targets) { console.log(`building ${name}`) await $`mkdir -p dist/${name}/bin` - const parserWorker = fs.realpathSync(path.resolve(dir, "./node_modules/@opentui/core/parser.worker.js")) + const localPath = path.resolve(dir, "node_modules/@opentui/core/parser.worker.js") + const rootPath = path.resolve(dir, "../../node_modules/@opentui/core/parser.worker.js") + const parserWorker = fs.realpathSync(fs.existsSync(localPath) ? localPath : rootPath) const workerPath = "./src/cli/cmd/tui/worker.ts" // Use platform-specific bunfs root path based on target OS From d4d1292a0e7c80b3f24d76e7d3bc71aa235967f0 Mon Sep 17 00:00:00 2001 From: "opencode-agent[bot]" Date: Fri, 6 Mar 2026 10:50:00 +0000 Subject: [PATCH 3/8] chore: generate --- packages/app/src/context/permission.tsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/app/src/context/permission.tsx b/packages/app/src/context/permission.tsx index 8208e46b9..672f84f82 100644 --- a/packages/app/src/context/permission.tsx +++ b/packages/app/src/context/permission.tsx @@ -7,7 +7,12 @@ import { useGlobalSDK } from "@/context/global-sdk" import { useGlobalSync } from "./global-sync" import { useParams } from "@solidjs/router" import { decode64 } from "@/utils/base64" -import { acceptKey, directoryAcceptKey, isDirectoryAutoAccepting, autoRespondsPermission } from "./permission-auto-respond" +import { + acceptKey, + directoryAcceptKey, + isDirectoryAutoAccepting, + autoRespondsPermission, +} from "./permission-auto-respond" type PermissionRespondFn = (input: { sessionID: string From eb9eb5e3349a76489f4779aefd78cffd3a42d262 Mon Sep 17 00:00:00 2001 From: D <47968994+imdzx@users.noreply.github.com> Date: Fri, 6 Mar 2026 18:46:53 +0700 Subject: [PATCH 4/8] =?UTF-8?q?feat:=20Add=20Vietnamese=20README=20and=20u?= =?UTF-8?q?pdate=20all=20language=20navigation=20links=20=E2=80=A6=20(#163?= =?UTF-8?q?22)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.ar.md | 3 +- README.bn.md | 3 +- README.br.md | 4 +- README.bs.md | 3 +- README.da.md | 4 +- README.de.md | 4 +- README.es.md | 4 +- README.fr.md | 4 +- README.gr.md | 3 +- README.it.md | 4 +- README.ja.md | 4 +- README.ko.md | 4 +- README.md | 3 +- README.no.md | 4 +- README.pl.md | 4 +- README.ru.md | 4 +- README.th.md | 4 +- README.tr.md | 4 +- README.uk.md | 3 +- README.vi.md | 141 ++++++++++++++++++++++++++++++++++++++++++++++++++ README.zh.md | 4 +- README.zht.md | 4 +- 22 files changed, 198 insertions(+), 21 deletions(-) create mode 100644 README.vi.md diff --git a/README.ar.md b/README.ar.md index 865fecb22..beb44589e 100644 --- a/README.ar.md +++ b/README.ar.md @@ -35,7 +35,8 @@ Türkçe | Українська | বাংলা | - Ελληνικά + Ελληνικά | + Tiếng Việt

[![OpenCode Terminal UI](packages/web/src/assets/lander/screenshot.png)](https://opencode.ai) diff --git a/README.bn.md b/README.bn.md index 24c083e79..c7abc7346 100644 --- a/README.bn.md +++ b/README.bn.md @@ -35,7 +35,8 @@ Türkçe | Українська | বাংলা | - Ελληνικά + Ελληνικά | + Tiếng Việt

[![OpenCode Terminal UI](packages/web/src/assets/lander/screenshot.png)](https://opencode.ai) diff --git a/README.br.md b/README.br.md index f7e82fa09..6d1de2156 100644 --- a/README.br.md +++ b/README.br.md @@ -27,6 +27,7 @@ 日本語 | Polski | Русский | + Bosanski | العربية | Norsk | Português (Brasil) | @@ -34,7 +35,8 @@ Türkçe | Українська | বাংলা | - Ελληνικά + Ελληνικά | + Tiếng Việt

[![OpenCode Terminal UI](packages/web/src/assets/lander/screenshot.png)](https://opencode.ai) diff --git a/README.bs.md b/README.bs.md index 5bba87085..2cff8e027 100644 --- a/README.bs.md +++ b/README.bs.md @@ -35,7 +35,8 @@ Türkçe | Українська | বাংলা | - Ελληνικά + Ελληνικά | + Tiếng Việt

[![OpenCode Terminal UI](packages/web/src/assets/lander/screenshot.png)](https://opencode.ai) diff --git a/README.da.md b/README.da.md index d1e686d7d..ac522f29c 100644 --- a/README.da.md +++ b/README.da.md @@ -27,6 +27,7 @@ 日本語 | Polski | Русский | + Bosanski | العربية | Norsk | Português (Brasil) | @@ -34,7 +35,8 @@ Türkçe | Українська | বাংলা | - Ελληνικά + Ελληνικά | + Tiếng Việt

[![OpenCode Terminal UI](packages/web/src/assets/lander/screenshot.png)](https://opencode.ai) diff --git a/README.de.md b/README.de.md index 7a3572324..87a670f3f 100644 --- a/README.de.md +++ b/README.de.md @@ -27,6 +27,7 @@ 日本語 | Polski | Русский | + Bosanski | العربية | Norsk | Português (Brasil) | @@ -34,7 +35,8 @@ Türkçe | Українська | বাংলা | - Ελληνικά + Ελληνικά | + Tiếng Việt

[![OpenCode Terminal UI](packages/web/src/assets/lander/screenshot.png)](https://opencode.ai) diff --git a/README.es.md b/README.es.md index b45418232..9e456af1c 100644 --- a/README.es.md +++ b/README.es.md @@ -27,6 +27,7 @@ 日本語 | Polski | Русский | + Bosanski | العربية | Norsk | Português (Brasil) | @@ -34,7 +35,8 @@ Türkçe | Українська | বাংলা | - Ελληνικά + Ελληνικά | + Tiếng Việt

[![OpenCode Terminal UI](packages/web/src/assets/lander/screenshot.png)](https://opencode.ai) diff --git a/README.fr.md b/README.fr.md index 02e66e5e8..c1fca2337 100644 --- a/README.fr.md +++ b/README.fr.md @@ -27,6 +27,7 @@ 日本語 | Polski | Русский | + Bosanski | العربية | Norsk | Português (Brasil) | @@ -34,7 +35,8 @@ Türkçe | Українська | বাংলা | - Ελληνικά + Ελληνικά | + Tiếng Việt

[![OpenCode Terminal UI](packages/web/src/assets/lander/screenshot.png)](https://opencode.ai) diff --git a/README.gr.md b/README.gr.md index 976eab5cc..2b2c2679d 100644 --- a/README.gr.md +++ b/README.gr.md @@ -35,7 +35,8 @@ Türkçe | Українська | বাংলা | - Ελληνικά + Ελληνικά | + Tiếng Việt

[![OpenCode Terminal UI](packages/web/src/assets/lander/screenshot.png)](https://opencode.ai) diff --git a/README.it.md b/README.it.md index b0d724741..3e516a902 100644 --- a/README.it.md +++ b/README.it.md @@ -27,6 +27,7 @@ 日本語 | Polski | Русский | + Bosanski | العربية | Norsk | Português (Brasil) | @@ -34,7 +35,8 @@ Türkçe | Українська | বাংলা | - Ελληνικά + Ελληνικά | + Tiếng Việt

[![OpenCode Terminal UI](packages/web/src/assets/lander/screenshot.png)](https://opencode.ai) diff --git a/README.ja.md b/README.ja.md index e381fbc60..144dc7b6f 100644 --- a/README.ja.md +++ b/README.ja.md @@ -27,6 +27,7 @@ 日本語 | Polski | Русский | + Bosanski | العربية | Norsk | Português (Brasil) | @@ -34,7 +35,8 @@ Türkçe | Українська | বাংলা | - Ελληνικά + Ελληνικά | + Tiếng Việt

[![OpenCode Terminal UI](packages/web/src/assets/lander/screenshot.png)](https://opencode.ai) diff --git a/README.ko.md b/README.ko.md index 63b9fb409..32defc0a5 100644 --- a/README.ko.md +++ b/README.ko.md @@ -27,6 +27,7 @@ 日本語 | Polski | Русский | + Bosanski | العربية | Norsk | Português (Brasil) | @@ -34,7 +35,8 @@ Türkçe | Українська | বাংলা | - Ελληνικά + Ελληνικά | + Tiếng Việt

[![OpenCode Terminal UI](packages/web/src/assets/lander/screenshot.png)](https://opencode.ai) diff --git a/README.md b/README.md index 8d9245037..79ccf8b34 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,8 @@ Türkçe | Українська | বাংলা | - Ελληνικά + Ελληνικά | + Tiếng Việt

[![OpenCode Terminal UI](packages/web/src/assets/lander/screenshot.png)](https://opencode.ai) diff --git a/README.no.md b/README.no.md index 1ccefaa76..c3348286b 100644 --- a/README.no.md +++ b/README.no.md @@ -27,6 +27,7 @@ 日本語 | Polski | Русский | + Bosanski | العربية | Norsk | Português (Brasil) | @@ -34,7 +35,8 @@ Türkçe | Українська | বাংলা | - Ελληνικά + Ελληνικά | + Tiếng Việt

[![OpenCode Terminal UI](packages/web/src/assets/lander/screenshot.png)](https://opencode.ai) diff --git a/README.pl.md b/README.pl.md index 0b246d5d5..4c5a07665 100644 --- a/README.pl.md +++ b/README.pl.md @@ -27,6 +27,7 @@ 日本語 | Polski | Русский | + Bosanski | العربية | Norsk | Português (Brasil) | @@ -34,7 +35,8 @@ Türkçe | Українська | বাংলা | - Ελληνικά + Ελληνικά | + Tiếng Việt

[![OpenCode Terminal UI](packages/web/src/assets/lander/screenshot.png)](https://opencode.ai) diff --git a/README.ru.md b/README.ru.md index ff30d380f..e507be70e 100644 --- a/README.ru.md +++ b/README.ru.md @@ -27,6 +27,7 @@ 日本語 | Polski | Русский | + Bosanski | العربية | Norsk | Português (Brasil) | @@ -34,7 +35,8 @@ Türkçe | Українська | বাংলা | - Ελληνικά + Ελληνικά | + Tiếng Việt

[![OpenCode Terminal UI](packages/web/src/assets/lander/screenshot.png)](https://opencode.ai) diff --git a/README.th.md b/README.th.md index 6a9a956a8..4a4ea62c9 100644 --- a/README.th.md +++ b/README.th.md @@ -27,6 +27,7 @@ 日本語 | Polski | Русский | + Bosanski | العربية | Norsk | Português (Brasil) | @@ -34,7 +35,8 @@ Türkçe | Українська | বাংলা | - Ελληνικά + Ελληνικά | + Tiếng Việt

[![OpenCode Terminal UI](packages/web/src/assets/lander/screenshot.png)](https://opencode.ai) diff --git a/README.tr.md b/README.tr.md index 9deedfb3c..e88b40f87 100644 --- a/README.tr.md +++ b/README.tr.md @@ -27,6 +27,7 @@ 日本語 | Polski | Русский | + Bosanski | العربية | Norsk | Português (Brasil) | @@ -34,7 +35,8 @@ Türkçe | Українська | বাংলা | - Ελληνικά + Ελληνικά | + Tiếng Việt

[![OpenCode Terminal UI](packages/web/src/assets/lander/screenshot.png)](https://opencode.ai) diff --git a/README.uk.md b/README.uk.md index dfd8fa8d7..a1a0259b6 100644 --- a/README.uk.md +++ b/README.uk.md @@ -35,7 +35,8 @@ Türkçe | Українська | বাংলা | - Ελληνικά + Ελληνικά | + Tiếng Việt

[![OpenCode Terminal UI](packages/web/src/assets/lander/screenshot.png)](https://opencode.ai) diff --git a/README.vi.md b/README.vi.md new file mode 100644 index 000000000..d54d4ab41 --- /dev/null +++ b/README.vi.md @@ -0,0 +1,141 @@ +

+ + + + + OpenCode logo + + +

+

Trợ lý lập trình AI mã nguồn mở.

+

+ Discord + npm + Build status +

+ +

+ English | + 简体中文 | + 繁體中文 | + 한국어 | + Deutsch | + Español | + Français | + Italiano | + Dansk | + 日本語 | + Polski | + Русский | + Bosanski | + العربية | + Norsk | + Português (Brasil) | + ไทย | + Türkçe | + Українська | + বাংলা | + Ελληνικά | + Tiếng Việt +

+ +[![OpenCode Terminal UI](packages/web/src/assets/lander/screenshot.png)](https://opencode.ai) + +--- + +### Cài đặt + +```bash +# YOLO +curl -fsSL https://opencode.ai/install | bash + +# Các trình quản lý gói (Package managers) +npm i -g opencode-ai@latest # hoặc bun/pnpm/yarn +scoop install opencode # Windows +choco install opencode # Windows +brew install anomalyco/tap/opencode # macOS và Linux (khuyên dùng, luôn cập nhật) +brew install opencode # macOS và Linux (công thức brew chính thức, ít cập nhật hơn) +sudo pacman -S opencode # Arch Linux (Bản ổn định) +paru -S opencode-bin # Arch Linux (Bản mới nhất từ AUR) +mise use -g opencode # Mọi hệ điều hành +nix run nixpkgs#opencode # hoặc github:anomalyco/opencode cho nhánh dev mới nhất +``` + +> [!TIP] +> Hãy xóa các phiên bản cũ hơn 0.1.x trước khi cài đặt. + +### Ứng dụng Desktop (BETA) + +OpenCode cũng có sẵn dưới dạng ứng dụng desktop. Tải trực tiếp từ [trang releases](https://github.com/anomalyco/opencode/releases) hoặc [opencode.ai/download](https://opencode.ai/download). + +| Nền tảng | Tải xuống | +| --------------------- | ------------------------------------- | +| macOS (Apple Silicon) | `opencode-desktop-darwin-aarch64.dmg` | +| macOS (Intel) | `opencode-desktop-darwin-x64.dmg` | +| Windows | `opencode-desktop-windows-x64.exe` | +| Linux | `.deb`, `.rpm`, hoặc AppImage | + +```bash +# macOS (Homebrew) +brew install --cask opencode-desktop +# Windows (Scoop) +scoop bucket add extras; scoop install extras/opencode-desktop +``` + +#### Thư mục cài đặt + +Tập lệnh cài đặt tuân theo thứ tự ưu tiên sau cho đường dẫn cài đặt: + +1. `$OPENCODE_INSTALL_DIR` - Thư mục cài đặt tùy chỉnh +2. `$XDG_BIN_DIR` - Đường dẫn tuân thủ XDG Base Directory Specification +3. `$HOME/bin` - Thư mục nhị phân tiêu chuẩn của người dùng (nếu tồn tại hoặc có thể tạo) +4. `$HOME/.opencode/bin` - Mặc định dự phòng + +```bash +# Ví dụ +OPENCODE_INSTALL_DIR=/usr/local/bin curl -fsSL https://opencode.ai/install | bash +XDG_BIN_DIR=$HOME/.local/bin curl -fsSL https://opencode.ai/install | bash +``` + +### Agents (Đại diện) + +OpenCode bao gồm hai agent được tích hợp sẵn mà bạn có thể chuyển đổi bằng phím `Tab`. + +- **build** - Agent mặc định, có toàn quyền truy cập cho công việc lập trình +- **plan** - Agent chỉ đọc dùng để phân tích và khám phá mã nguồn + - Mặc định từ chối việc chỉnh sửa tệp + - Hỏi quyền trước khi chạy các lệnh bash + - Lý tưởng để khám phá các codebase lạ hoặc lên kế hoạch thay đổi + +Ngoài ra còn có một subagent **general** dùng cho các tìm kiếm phức tạp và tác vụ nhiều bước. +Agent này được sử dụng nội bộ và có thể gọi bằng cách dùng `@general` trong tin nhắn. + +Tìm hiểu thêm về [agents](https://opencode.ai/docs/agents). + +### Tài liệu + +Để biết thêm thông tin về cách cấu hình OpenCode, [**hãy truy cập tài liệu của chúng tôi**](https://opencode.ai/docs). + +### Đóng góp + +Nếu bạn muốn đóng góp cho OpenCode, vui lòng đọc [tài liệu hướng dẫn đóng góp](./CONTRIBUTING.md) trước khi gửi pull request. + +### Xây dựng trên nền tảng OpenCode + +Nếu bạn đang làm việc trên một dự án liên quan đến OpenCode và sử dụng "opencode" như một phần của tên dự án, ví dụ "opencode-dashboard" hoặc "opencode-mobile", vui lòng thêm một ghi chú vào README của bạn để làm rõ rằng dự án đó không được xây dựng bởi đội ngũ OpenCode và không liên kết với chúng tôi dưới bất kỳ hình thức nào. + +### Các câu hỏi thường gặp (FAQ) + +#### OpenCode khác biệt thế nào so với Claude Code? + +Về mặt tính năng, nó rất giống Claude Code. Dưới đây là những điểm khác biệt chính: + +- 100% mã nguồn mở +- Không bị ràng buộc với bất kỳ nhà cung cấp nào. Mặc dù chúng tôi khuyên dùng các mô hình được cung cấp qua [OpenCode Zen](https://opencode.ai/zen), OpenCode có thể được sử dụng với Claude, OpenAI, Google, hoặc thậm chí các mô hình chạy cục bộ. Khi các mô hình phát triển, khoảng cách giữa chúng sẽ thu hẹp lại và giá cả sẽ giảm, vì vậy việc không phụ thuộc vào nhà cung cấp là rất quan trọng. +- Hỗ trợ LSP ngay từ đầu +- Tập trung vào TUI (Giao diện người dùng dòng lệnh). OpenCode được xây dựng bởi những người dùng neovim và đội ngũ tạo ra [terminal.shop](https://terminal.shop); chúng tôi sẽ đẩy giới hạn của những gì có thể làm được trên terminal lên mức tối đa. +- Kiến trúc client/server. Chẳng hạn, điều này cho phép OpenCode chạy trên máy tính của bạn trong khi bạn điều khiển nó từ xa qua một ứng dụng di động, nghĩa là frontend TUI chỉ là một trong những client có thể dùng. + +--- + +**Tham gia cộng đồng của chúng tôi** [Discord](https://discord.gg/opencode) | [X.com](https://x.com/opencode) diff --git a/README.zh.md b/README.zh.md index 9a1e1b2fb..b11d9857c 100644 --- a/README.zh.md +++ b/README.zh.md @@ -27,6 +27,7 @@ 日本語 | Polski | Русский | + Bosanski | العربية | Norsk | Português (Brasil) | @@ -34,7 +35,8 @@ Türkçe | Українська | বাংলা | - Ελληνικά + Ελληνικά | + Tiếng Việt

[![OpenCode Terminal UI](packages/web/src/assets/lander/screenshot.png)](https://opencode.ai) diff --git a/README.zht.md b/README.zht.md index 238f11289..573ca85ab 100644 --- a/README.zht.md +++ b/README.zht.md @@ -27,6 +27,7 @@ 日本語 | Polski | Русский | + Bosanski | العربية | Norsk | Português (Brasil) | @@ -34,7 +35,8 @@ Türkçe | Українська | বাংলা | - Ελληνικά + Ελληνικά | + Tiếng Việt

[![OpenCode Terminal UI](packages/web/src/assets/lander/screenshot.png)](https://opencode.ai) From f64bb91257c6381e6c2fbd099ca36ef726c46704 Mon Sep 17 00:00:00 2001 From: Kirill Tregubov Date: Fri, 6 Mar 2026 06:47:39 -0500 Subject: [PATCH 5/8] fix(app): add english to locale matchers (#16280) --- packages/app/src/context/language.tsx | 2 ++ packages/desktop-electron/src/renderer/i18n/index.ts | 1 + packages/desktop/src/i18n/index.ts | 1 + 3 files changed, 4 insertions(+) diff --git a/packages/app/src/context/language.tsx b/packages/app/src/context/language.tsx index be1a1769b..b1edd541c 100644 --- a/packages/app/src/context/language.tsx +++ b/packages/app/src/context/language.tsx @@ -146,6 +146,7 @@ const DICT: Record = { } const localeMatchers: Array<{ locale: Locale; match: (language: string) => boolean }> = [ + { locale: "en", match: (language) => language.startsWith("en") }, { locale: "zht", match: (language) => language.startsWith("zh") && language.includes("hant") }, { locale: "zh", match: (language) => language.startsWith("zh") }, { locale: "ko", match: (language) => language.startsWith("ko") }, @@ -217,6 +218,7 @@ export const { use: useLanguage, provider: LanguageProvider } = createSimpleCont ) const locale = createMemo(() => normalizeLocale(store.locale)) + console.log("locale", locale()) const intl = createMemo(() => INTL[locale()]) const dict = createMemo(() => DICT[locale()]) diff --git a/packages/desktop-electron/src/renderer/i18n/index.ts b/packages/desktop-electron/src/renderer/i18n/index.ts index 81158ad24..be87f94f9 100644 --- a/packages/desktop-electron/src/renderer/i18n/index.ts +++ b/packages/desktop-electron/src/renderer/i18n/index.ts @@ -76,6 +76,7 @@ function detectLocale(): Locale { const languages = navigator.languages?.length ? navigator.languages : [navigator.language] for (const language of languages) { if (!language) continue + if (language.toLowerCase().startsWith("en")) return "en" if (language.toLowerCase().startsWith("zh")) { if (language.toLowerCase().includes("hant")) return "zht" return "zh" diff --git a/packages/desktop/src/i18n/index.ts b/packages/desktop/src/i18n/index.ts index 7b1ebfe69..e1c1e63d9 100644 --- a/packages/desktop/src/i18n/index.ts +++ b/packages/desktop/src/i18n/index.ts @@ -77,6 +77,7 @@ function detectLocale(): Locale { const languages = navigator.languages?.length ? navigator.languages : [navigator.language] for (const language of languages) { if (!language) continue + if (language.toLowerCase().startsWith("en")) return "en" if (language.toLowerCase().startsWith("zh")) { if (language.toLowerCase().includes("hant")) return "zht" return "zh" From e1cf761d298dd704814312657a25b4130288644d Mon Sep 17 00:00:00 2001 From: "opencode-agent[bot]" Date: Fri, 6 Mar 2026 11:48:31 +0000 Subject: [PATCH 6/8] chore: generate --- README.vi.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.vi.md b/README.vi.md index d54d4ab41..0932c50f7 100644 --- a/README.vi.md +++ b/README.vi.md @@ -68,7 +68,7 @@ nix run nixpkgs#opencode # hoặc github:anomalyco/opencode cho nhánh OpenCode cũng có sẵn dưới dạng ứng dụng desktop. Tải trực tiếp từ [trang releases](https://github.com/anomalyco/opencode/releases) hoặc [opencode.ai/download](https://opencode.ai/download). -| Nền tảng | Tải xuống | +| Nền tảng | Tải xuống | | --------------------- | ------------------------------------- | | macOS (Apple Silicon) | `opencode-desktop-darwin-aarch64.dmg` | | macOS (Intel) | `opencode-desktop-darwin-x64.dmg` | From 2094e8b255fb5406c7c2af5ce0ae8673c43b5c0b Mon Sep 17 00:00:00 2001 From: Adam <2363879+adamdotdevin@users.noreply.github.com> Date: Thu, 5 Mar 2026 20:04:39 -0600 Subject: [PATCH 7/8] Revert "fix(app): stale keyed show errors" This reverts commit 7665b8e30def396059516ef6d870830baa1faedd. --- .../app/src/pages/session/message-timeline.tsx | 6 +++--- .../app/src/pages/session/session-side-panel.tsx | 4 +--- .../app/src/pages/session/terminal-panel.tsx | 16 ++++++++-------- 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/packages/app/src/pages/session/message-timeline.tsx b/packages/app/src/pages/session/message-timeline.tsx index f320a2ebb..ce6a01378 100644 --- a/packages/app/src/pages/session/message-timeline.tsx +++ b/packages/app/src/pages/session/message-timeline.tsx @@ -611,7 +611,7 @@ export function MessageTimeline(props: { - + {(id) => (
@@ -646,12 +646,12 @@ export function MessageTimeline(props: { > {language.t("common.rename")} - void archiveSession(id)}> + void archiveSession(id())}> {language.t("common.archive")} dialog.show(() => )} + onSelect={() => dialog.show(() => )} > {language.t("common.delete")} diff --git a/packages/app/src/pages/session/session-side-panel.tsx b/packages/app/src/pages/session/session-side-panel.tsx index 55c1607a0..ad802d15d 100644 --- a/packages/app/src/pages/session/session-side-panel.tsx +++ b/packages/app/src/pages/session/session-side-panel.tsx @@ -331,9 +331,7 @@ export function SessionSidePanel(props: { const path = createMemo(() => file.pathFromTab(tab)) return (
- - {(p) => } - + {(p) => }
) }} diff --git a/packages/app/src/pages/session/terminal-panel.tsx b/packages/app/src/pages/session/terminal-panel.tsx index c8bfc1405..cc4c17ee2 100644 --- a/packages/app/src/pages/session/terminal-panel.tsx +++ b/packages/app/src/pages/session/terminal-panel.tsx @@ -191,8 +191,8 @@ export function TerminalPanel() { {(id) => ( - - {(pty) => } + + {(pty) => } )} @@ -217,10 +217,10 @@ export function TerminalPanel() {
{(id) => ( - + {(pty) => (
- terminal.clone(id)} /> + terminal.clone(id)} />
)}
@@ -229,14 +229,14 @@ export function TerminalPanel() {
- + {(draggedId) => ( - + {(t) => (
{terminalTabLabel({ - title: t.title, - titleNumber: t.titleNumber, + title: t().title, + titleNumber: t().titleNumber, t: language.t as (key: string, vars?: Record) => string, })}
From eeeb21ff8638eddd960afbd8f522c87d850d6183 Mon Sep 17 00:00:00 2001 From: Adam <2363879+adamdotdevin@users.noreply.github.com> Date: Thu, 5 Mar 2026 20:08:49 -0600 Subject: [PATCH 8/8] Revert "fix(app): stale read error" This reverts commit 152df2428df84a1029be2b472b4a840cd94c966d. --- packages/app/src/pages/layout.tsx | 47 ++++++++++++++----------------- 1 file changed, 21 insertions(+), 26 deletions(-) diff --git a/packages/app/src/pages/layout.tsx b/packages/app/src/pages/layout.tsx index bd0315efb..f6165461b 100644 --- a/packages/app/src/pages/layout.tsx +++ b/packages/app/src/pages/layout.tsx @@ -10,9 +10,8 @@ import { ParentProps, Show, untrack, - type JSX, } from "solid-js" -import { A, useNavigate, useParams } from "@solidjs/router" +import { useNavigate, useParams } from "@solidjs/router" import { useLayout, LocalProject } from "@/context/layout" import { useGlobalSync } from "@/context/global-sync" import { Persist, persisted } from "@/utils/persist" @@ -20,7 +19,6 @@ import { base64Encode } from "@opencode-ai/util/encode" import { decode64 } from "@/utils/base64" import { ResizeHandle } from "@opencode-ai/ui/resize-handle" import { Button } from "@opencode-ai/ui/button" -import { Icon } from "@opencode-ai/ui/icon" import { IconButton } from "@opencode-ai/ui/icon-button" import { Tooltip } from "@opencode-ai/ui/tooltip" import { DropdownMenu } from "@opencode-ai/ui/dropdown-menu" @@ -59,7 +57,6 @@ import { Titlebar } from "@/components/titlebar" import { useServer } from "@/context/server" import { useLanguage, type Locale } from "@/context/language" import { - childMapByParent, displayName, effectiveWorkspaceOrder, errorMessage, @@ -1846,7 +1843,7 @@ export default function Layout(props: ParentProps) { }} style={{ width: panelProps.mobile ? undefined : `${Math.max(layout.sidebar.width() - 64, 0)}px` }} > - + {(p) => ( <>
@@ -1855,7 +1852,7 @@ export default function Layout(props: ParentProps) { renameProject(p, next)} + onSave={(next) => renameProject(p(), next)} class="text-14-medium text-text-strong truncate" displayClass="text-14-medium text-text-strong truncate" stopPropagation @@ -1864,7 +1861,7 @@ export default function Layout(props: ParentProps) { - {p.worktree.replace(homedir(), "~")} + {p().worktree.replace(homedir(), "~")}
@@ -1883,7 +1880,7 @@ export default function Layout(props: ParentProps) { icon="dot-grid" variant="ghost" data-action="project-menu" - data-project={base64Encode(p.worktree)} + data-project={base64Encode(p().worktree)} class="shrink-0 size-6 rounded-md data-[expanded]:bg-surface-base-active" classList={{ "opacity-0 group-hover/project:opacity-100 data-[expanded]:opacity-100": !panelProps.mobile, @@ -1892,24 +1889,24 @@ export default function Layout(props: ParentProps) { /> - showEditProjectDialog(p)}> + showEditProjectDialog(p())}> {language.t("common.edit")} toggleProjectWorkspaces(p)} + data-project={base64Encode(p().worktree)} + disabled={p().vcs !== "git" && !layout.sidebar.workspaces(p().worktree)()} + onSelect={() => toggleProjectWorkspaces(p())} > - {layout.sidebar.workspaces(p.worktree)() + {layout.sidebar.workspaces(p().worktree)() ? language.t("sidebar.workspaces.disable") : language.t("sidebar.workspaces.enable")} @@ -1920,8 +1917,8 @@ export default function Layout(props: ParentProps) { closeProject(p.worktree)} + data-project={base64Encode(p().worktree)} + onSelect={() => closeProject(p().worktree)} > {language.t("common.close")} @@ -1941,7 +1938,7 @@ export default function Layout(props: ParentProps) { size="large" icon="plus-small" class="w-full" - onClick={() => navigateWithSidebarReset(`/${base64Encode(p.worktree)}/session`)} + onClick={() => navigateWithSidebarReset(`/${base64Encode(p().worktree)}/session`)} > {language.t("command.session.new")} @@ -1949,7 +1946,7 @@ export default function Layout(props: ParentProps) {
@@ -1959,7 +1956,7 @@ export default function Layout(props: ParentProps) { > <>
-
@@ -1984,7 +1981,7 @@ export default function Layout(props: ParentProps) { @@ -2096,11 +2093,9 @@ export default function Layout(props: ParentProps) { />
- {(worktree) => ( -
- -
- )} +
+ +