diff --git a/README.ar.md b/README.ar.md index 865fecb22b..beb44589e6 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 24c083e79e..c7abc7346a 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 f7e82fa09d..6d1de21562 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 5bba870859..2cff8e0279 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 d1e686d7d7..ac522f29c4 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 7a3572324a..87a670f3fc 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 b454182328..9e456af1c0 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 02e66e5e87..c1fca23376 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 976eab5cc3..2b2c2679d8 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 b0d7247415..3e516a9027 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 e381fbc603..144dc7b6f8 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 63b9fb4091..32defc0a5e 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 8d92450374..79ccf8b349 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 1ccefaa760..c3348286b2 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 0b246d5d5a..4c5a076656 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 ff30d380fd..e507be70e6 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 6a9a956a88..4a4ea62c95 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 9deedfb3c6..e88b40f875 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 dfd8fa8d75..a1a0259b6d 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 0000000000..0932c50f78 --- /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 9a1e1b2fb6..b11d9857c9 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 238f11289f..573ca85ab4 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) diff --git a/bun.lock b/bun.lock index 6539faa830..fcc0fcbbb0 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 809a285374..c91a91383d 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/app/src/components/prompt-input.tsx b/packages/app/src/components/prompt-input.tsx index c9c8bc6b44..40104bceb9 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/language.tsx b/packages/app/src/context/language.tsx index be1a1769bf..b1edd541c3 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/app/src/context/permission-auto-respond.test.ts b/packages/app/src/context/permission-auto-respond.test.ts index 2e4cf4fafb..7556113005 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 727ccc9375..b206deedff 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 73ee08c9ac..672f84f82a 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,12 @@ 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 +81,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 +143,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 +170,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 +243,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 +252,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 +267,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/layout.tsx b/packages/app/src/pages/layout.tsx index bd0315efbf..f6165461b1 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) => ( -
- -
- )} +
+ +
- + {(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 55c1607a09..ad802d15d1 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 c8bfc14053..cc4c17ee21 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, })}
diff --git a/packages/app/src/pages/session/use-session-commands.tsx b/packages/app/src/pages/session/use-session-commands.tsx index 461351878b..b8ddeda823 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/console/app/package.json b/packages/console/app/package.json index 269b005a86..4d20c1b8bc 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 199b5d9bd6..408e2a7aca 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 e771aae844..8df6594d0b 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 ef8d7c5994..591c4bd369 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 e683d185bc..31321c92a5 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-electron/src/renderer/i18n/index.ts b/packages/desktop-electron/src/renderer/i18n/index.ts index 81158ad244..be87f94f91 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/package.json b/packages/desktop/package.json index 10e6df26b1..da4d51bcc7 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/desktop/src/i18n/index.ts b/packages/desktop/src/i18n/index.ts index 7b1ebfe696..e1c1e63d97 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" diff --git a/packages/enterprise/package.json b/packages/enterprise/package.json index ef56add880..2531cf34fb 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 1637c58a4d..d45bec2301 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 efaae65f53..adc3bfcb05 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 fde3ace92f..f502382ba7 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/opencode/script/build.ts b/packages/opencode/script/build.ts index 34e80d71a0..b5d6e8adfb 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 diff --git a/packages/plugin/package.json b/packages/plugin/package.json index d8911922ec..7419f4ecca 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 fe3ce393d6..ced7f6c05f 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 d37e140581..fbdf202fdf 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 48c668c6fb..db585bb008 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 bc84be6360..b6ee1c3bf2 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 c85ba1a0b9..e386f581f5 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 215143ac99..f900f1099c 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",