diff --git a/AGENTS.md b/AGENTS.md index 35355dfef..1ee5be8b0 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,8 +1,6 @@ - To regenerate the JavaScript SDK, run `./packages/sdk/js/script/build.ts`. -- ALWAYS USE PARALLEL TOOLS WHEN APPLICABLE. - The default branch in this repo is `dev`. - Local `main` ref may not exist; use `dev` or `origin/dev` for diffs. -- Prefer automation: execute requested actions without confirmation unless blocked by missing info or safety/irreversibility. ## Commits and PR Titles diff --git a/bun.lock b/bun.lock index 831b0be5b..8c7f25ad7 100644 --- a/bun.lock +++ b/bun.lock @@ -29,7 +29,7 @@ }, "packages/app": { "name": "@opencode-ai/app", - "version": "1.15.10", + "version": "1.15.11", "dependencies": { "@kobalte/core": "catalog:", "@opencode-ai/core": "workspace:*", @@ -85,7 +85,7 @@ }, "packages/console/app": { "name": "@opencode-ai/console-app", - "version": "1.15.10", + "version": "1.15.11", "dependencies": { "@cloudflare/vite-plugin": "1.15.2", "@ibm/plex": "6.4.1", @@ -121,7 +121,7 @@ }, "packages/console/core": { "name": "@opencode-ai/console-core", - "version": "1.15.10", + "version": "1.15.11", "dependencies": { "@aws-sdk/client-sts": "3.782.0", "@jsx-email/render": "1.1.1", @@ -148,7 +148,7 @@ }, "packages/console/function": { "name": "@opencode-ai/console-function", - "version": "1.15.10", + "version": "1.15.11", "dependencies": { "@ai-sdk/anthropic": "3.0.64", "@ai-sdk/openai": "3.0.48", @@ -170,7 +170,7 @@ }, "packages/console/mail": { "name": "@opencode-ai/console-mail", - "version": "1.15.10", + "version": "1.15.11", "dependencies": { "@jsx-email/all": "2.2.3", "@jsx-email/cli": "1.4.3", @@ -194,7 +194,7 @@ }, "packages/console/support": { "name": "@opencode-ai/console-support", - "version": "0.0.0", + "version": "1.15.11", "dependencies": { "@cloudflare/vite-plugin": "1.15.2", "@opencode-ai/console-core": "workspace:*", @@ -214,7 +214,7 @@ }, "packages/core": { "name": "@opencode-ai/core", - "version": "1.15.10", + "version": "1.15.11", "bin": { "opencode": "./bin/opencode", }, @@ -227,8 +227,8 @@ "@ai-sdk/cohere": "3.0.27", "@ai-sdk/deepinfra": "2.0.41", "@ai-sdk/gateway": "3.0.104", - "@ai-sdk/google": "3.0.63", - "@ai-sdk/google-vertex": "4.0.131", + "@ai-sdk/google": "3.0.73", + "@ai-sdk/google-vertex": "4.0.128", "@ai-sdk/groq": "3.0.31", "@ai-sdk/mistral": "3.0.27", "@ai-sdk/openai": "3.0.53", @@ -280,7 +280,7 @@ }, "packages/desktop": { "name": "@opencode-ai/desktop", - "version": "1.15.10", + "version": "1.15.11", "dependencies": { "@zip.js/zip.js": "2.7.62", "drizzle-orm": "catalog:", @@ -335,7 +335,7 @@ }, "packages/effect-drizzle-sqlite": { "name": "@opencode-ai/effect-drizzle-sqlite", - "version": "1.15.10", + "version": "1.15.11", "dependencies": { "drizzle-orm": "catalog:", "effect": "catalog:", @@ -361,7 +361,7 @@ }, "packages/enterprise": { "name": "@opencode-ai/enterprise", - "version": "1.15.10", + "version": "1.15.11", "dependencies": { "@opencode-ai/core": "workspace:*", "@opencode-ai/ui": "workspace:*", @@ -391,7 +391,7 @@ }, "packages/function": { "name": "@opencode-ai/function", - "version": "1.15.10", + "version": "1.15.11", "dependencies": { "@octokit/auth-app": "8.0.1", "@octokit/rest": "catalog:", @@ -407,7 +407,7 @@ }, "packages/http-recorder": { "name": "@opencode-ai/http-recorder", - "version": "1.15.10", + "version": "1.15.11", "dependencies": { "@effect/platform-node": "catalog:", "effect": "catalog:", @@ -420,7 +420,7 @@ }, "packages/llm": { "name": "@opencode-ai/llm", - "version": "1.15.10", + "version": "1.15.11", "dependencies": { "@smithy/eventstream-codec": "4.2.14", "@smithy/util-utf8": "4.2.2", @@ -438,7 +438,7 @@ }, "packages/opencode": { "name": "opencode", - "version": "1.15.10", + "version": "1.15.11", "bin": { "opencode": "./bin/opencode", }, @@ -454,8 +454,8 @@ "@ai-sdk/cohere": "3.0.27", "@ai-sdk/deepinfra": "2.0.41", "@ai-sdk/gateway": "3.0.104", - "@ai-sdk/google": "3.0.63", - "@ai-sdk/google-vertex": "4.0.131", + "@ai-sdk/google": "3.0.73", + "@ai-sdk/google-vertex": "4.0.128", "@ai-sdk/groq": "3.0.31", "@ai-sdk/mistral": "3.0.27", "@ai-sdk/openai": "3.0.53", @@ -495,6 +495,7 @@ "@solid-primitives/event-bus": "1.1.2", "@solid-primitives/scheduled": "1.5.2", "@standard-schema/spec": "1.0.0", + "@types/ws": "8.18.1", "@zip.js/zip.js": "2.7.62", "ai": "catalog:", "ai-gateway-provider": "3.1.2", @@ -536,6 +537,7 @@ "vscode-jsonrpc": "8.2.1", "web-tree-sitter": "0.25.10", "which": "6.0.1", + "ws": "8.21.0", "xdg-basedir": "5.1.0", "yargs": "18.0.0", "zod": "catalog:", @@ -575,7 +577,7 @@ }, "packages/plugin": { "name": "@opencode-ai/plugin", - "version": "1.15.10", + "version": "1.15.11", "dependencies": { "@opencode-ai/sdk": "workspace:*", "effect": "catalog:", @@ -591,9 +593,9 @@ "typescript": "catalog:", }, "peerDependencies": { - "@opentui/core": ">=0.2.15", - "@opentui/keymap": ">=0.2.15", - "@opentui/solid": ">=0.2.15", + "@opentui/core": ">=0.2.16", + "@opentui/keymap": ">=0.2.16", + "@opentui/solid": ">=0.2.16", }, "optionalPeers": [ "@opentui/core", @@ -613,7 +615,7 @@ }, "packages/sdk/js": { "name": "@opencode-ai/sdk", - "version": "1.15.10", + "version": "1.15.11", "dependencies": { "cross-spawn": "catalog:", }, @@ -628,7 +630,7 @@ }, "packages/slack": { "name": "@opencode-ai/slack", - "version": "1.15.10", + "version": "1.15.11", "dependencies": { "@opencode-ai/sdk": "workspace:*", "@slack/bolt": "^3.17.1", @@ -641,7 +643,7 @@ }, "packages/stats/app": { "name": "@opencode-ai/stats-app", - "version": "1.14.50", + "version": "1.15.11", "dependencies": { "@opencode-ai/stats-core": "workspace:*", "@opencode-ai/ui": "workspace:*", @@ -664,7 +666,7 @@ }, "packages/stats/core": { "name": "@opencode-ai/stats-core", - "version": "1.14.50", + "version": "1.15.11", "dependencies": { "@aws-sdk/client-athena": "3.933.0", "@planetscale/database": "1.19.0", @@ -683,7 +685,7 @@ }, "packages/stats/server": { "name": "@opencode-ai/stats-server", - "version": "1.14.50", + "version": "1.15.11", "dependencies": { "@aws-sdk/client-firehose": "3.933.0", "@effect/platform-node": "catalog:", @@ -723,7 +725,7 @@ }, "packages/ui": { "name": "@opencode-ai/ui", - "version": "1.15.10", + "version": "1.15.11", "dependencies": { "@kobalte/core": "catalog:", "@opencode-ai/core": "workspace:*", @@ -772,7 +774,7 @@ }, "packages/web": { "name": "@opencode-ai/web", - "version": "1.15.10", + "version": "1.15.11", "dependencies": { "@astrojs/cloudflare": "12.6.3", "@astrojs/markdown-remark": "6.3.1", @@ -815,8 +817,9 @@ ], "patchedDependencies": { "solid-js@1.9.10": "patches/solid-js@1.9.10.patch", - "@ai-sdk/xai@3.0.82": "patches/@ai-sdk%2Fxai@3.0.82.patch", "virtua@0.49.1": "patches/virtua@0.49.1.patch", + "gcp-metadata@8.1.2": "patches/gcp-metadata@8.1.2.patch", + "@ai-sdk/xai@3.0.82": "patches/@ai-sdk%2Fxai@3.0.82.patch", "@standard-community/standard-openapi@0.2.9": "patches/@standard-community%2Fstandard-openapi@0.2.9.patch", "@npmcli/agent@4.0.0": "patches/@npmcli%2Fagent@4.0.0.patch", "@silvia-odwyer/photon-node@0.3.4": "patches/@silvia-odwyer%2Fphoton-node@0.3.4.patch", @@ -839,9 +842,9 @@ "@npmcli/arborist": "9.4.0", "@octokit/rest": "22.0.0", "@openauthjs/openauth": "0.0.0-20250322224806", - "@opentui/core": "0.2.15", - "@opentui/keymap": "0.2.15", - "@opentui/solid": "0.2.15", + "@opentui/core": "0.2.16", + "@opentui/keymap": "0.2.16", + "@opentui/solid": "0.2.16", "@pierre/diffs": "1.1.0-beta.18", "@playwright/test": "1.59.1", "@sentry/solid": "10.36.0", @@ -931,9 +934,9 @@ "@ai-sdk/gateway": ["@ai-sdk/gateway@3.0.104", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@ai-sdk/provider-utils": "4.0.23", "@vercel/oidc": "3.2.0" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-ZKX5n74io8VIRlhIMSLWVlvT3sXC8Z7cZ9GHuWBWZDVi96+62AIsWuLGvMfcBA1STYuSoDrp6rIziZmvrTq0TA=="], - "@ai-sdk/google": ["@ai-sdk/google@3.0.63", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@ai-sdk/provider-utils": "4.0.23" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-RfOZWVMYSPu2sPRfGajrauWAZ9BSaRopSn+AszkKWQ1MFj8nhaXvCqRHB5pBQUaHTfZKagvOmMpNfa/s3gPLgQ=="], + "@ai-sdk/google": ["@ai-sdk/google@3.0.73", "", { "dependencies": { "@ai-sdk/provider": "3.0.10", "@ai-sdk/provider-utils": "4.0.27" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-o2MuIeyvZrFIeIbnbA8Thrr63irdyUBh0uWBZ2lY6yFeXuE/tcwyXF74bDKS4KvTu84uFpQfpbS/LXHGKKXz+g=="], - "@ai-sdk/google-vertex": ["@ai-sdk/google-vertex@4.0.131", "", { "dependencies": { "@ai-sdk/anthropic": "3.0.78", "@ai-sdk/google": "3.0.75", "@ai-sdk/openai-compatible": "2.0.47", "@ai-sdk/provider": "3.0.10", "@ai-sdk/provider-utils": "4.0.27", "google-auth-library": "^10.5.0" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-Oj1X8p0rVgvEoR5OOSxWi6XgzJ3QDlE/n30MZVtpKkCiToYYDyvlvVDGXz3IqhMyUev2JhlcuUk1brScKT01kA=="], + "@ai-sdk/google-vertex": ["@ai-sdk/google-vertex@4.0.128", "", { "dependencies": { "@ai-sdk/anthropic": "3.0.77", "@ai-sdk/google": "3.0.73", "@ai-sdk/openai-compatible": "2.0.47", "@ai-sdk/provider": "3.0.10", "@ai-sdk/provider-utils": "4.0.27", "google-auth-library": "^10.5.0" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-jK8fixb4km2yfgvb9DUFQRpV/jiDB0v9gyxHoHfPydaQvz+CpAz8DTt1quyaM+Wg9G2R8Zo68CYmHbIkUqW2AA=="], "@ai-sdk/groq": ["@ai-sdk/groq@3.0.31", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@ai-sdk/provider-utils": "4.0.21" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-XbbugpnFmXGu2TlXiq8KUJskP6/VVbuFcnFIGDzDIB/Chg6XHsNnqrTF80Zxkh0Pd3+NvbM+2Uqrtsndk6bDAg=="], @@ -1733,23 +1736,23 @@ "@opentelemetry/semantic-conventions": ["@opentelemetry/semantic-conventions@1.40.0", "", {}, "sha512-cifvXDhcqMwwTlTK04GBNeIe7yyo28Mfby85QXFe1Yk8nmi36Ab/5UQwptOx84SsoGNRg+EVSjwzfSZMy6pmlw=="], - "@opentui/core": ["@opentui/core@0.2.15", "", { "dependencies": { "bun-ffi-structs": "0.2.2", "diff": "9.0.0", "marked": "17.0.1", "string-width": "7.2.0", "strip-ansi": "7.1.2", "yoga-layout": "3.2.1" }, "optionalDependencies": { "@opentui/core-darwin-arm64": "0.2.15", "@opentui/core-darwin-x64": "0.2.15", "@opentui/core-linux-arm64": "0.2.15", "@opentui/core-linux-x64": "0.2.15", "@opentui/core-win32-arm64": "0.2.15", "@opentui/core-win32-x64": "0.2.15" }, "peerDependencies": { "web-tree-sitter": "0.25.10" } }, "sha512-YGHttdZWScMcSvtYgZkLR6VhUO1OoUiQzwYjZgIusf5eCkPLD8PapH+PTMVqAiX16CHO6JxfMlkHv5qDiHAccQ=="], + "@opentui/core": ["@opentui/core@0.2.16", "", { "dependencies": { "bun-ffi-structs": "0.2.2", "diff": "9.0.0", "marked": "17.0.1", "string-width": "7.2.0", "strip-ansi": "7.1.2", "yoga-layout": "3.2.1" }, "optionalDependencies": { "@opentui/core-darwin-arm64": "0.2.16", "@opentui/core-darwin-x64": "0.2.16", "@opentui/core-linux-arm64": "0.2.16", "@opentui/core-linux-x64": "0.2.16", "@opentui/core-win32-arm64": "0.2.16", "@opentui/core-win32-x64": "0.2.16" }, "peerDependencies": { "web-tree-sitter": "0.25.10" } }, "sha512-4vWN15Zc3nsXJlOiHhhpqkBXD+wrNFKxCPtiTiillZYDRre+XsZogVTOOGUDwaBIC23OSxq7imezLmmtShVBEA=="], - "@opentui/core-darwin-arm64": ["@opentui/core-darwin-arm64@0.2.15", "", { "os": "darwin", "cpu": "arm64" }, "sha512-s25f9GmZd6wxNM5ExRmwwnLT+NLCKxnTWuO9aObOlqsXfLMGHQZrb6YwgAn/PSTua98KmH7GJCVWdPgZ/P+0RQ=="], + "@opentui/core-darwin-arm64": ["@opentui/core-darwin-arm64@0.2.16", "", { "os": "darwin", "cpu": "arm64" }, "sha512-aFb2Yp+oqDu3h6VCWi7xpQ9yjpKSQcROzGGfHgqC6Nd3U+uiLfPJBkmiI87iK0opCggCFj5TkKI004050DmGjg=="], - "@opentui/core-darwin-x64": ["@opentui/core-darwin-x64@0.2.15", "", { "os": "darwin", "cpu": "x64" }, "sha512-GyaipN+nOcEr8rcTO2mqKTGmOBk0C300I69fLtubD3BadHcMI1DVNlQrcf/J1mkQEuMYbmBTi/1hT1ybWGr2Mw=="], + "@opentui/core-darwin-x64": ["@opentui/core-darwin-x64@0.2.16", "", { "os": "darwin", "cpu": "x64" }, "sha512-KimiHE0j7EsTB5P8doW0lr1eH5iZKLPKWQO+tmy1VcdYr/TzqhdHSvGuJXrZvfTFi9/rV57Eq0d7964Ri9O0vQ=="], - "@opentui/core-linux-arm64": ["@opentui/core-linux-arm64@0.2.15", "", { "os": "linux", "cpu": "arm64" }, "sha512-h+uyufselGT4afKMP8Lg4yUl5Kp+DJBlhu3XpWXhphE5Pnq5+f0uGBr4P+34CNcWxMsDnvagSQLFRCS4rGrOWA=="], + "@opentui/core-linux-arm64": ["@opentui/core-linux-arm64@0.2.16", "", { "os": "linux", "cpu": "arm64" }, "sha512-4fCwRCfTtUgS/5QcSEkSuBjgQymSOUWXgrXG2ycrf3Swi0QhKDA/pVjwLrUJ6eF+/8mQyQSEV72T8MxMO3M2qg=="], - "@opentui/core-linux-x64": ["@opentui/core-linux-x64@0.2.15", "", { "os": "linux", "cpu": "x64" }, "sha512-jx+NImPq4wSp3Apfe7tlixiEJNnRyECTRJRWhGF6ZJz4PwFfgK2UHZKYR0DZHbV8nYawoDNQPJDXEWcoZShnMg=="], + "@opentui/core-linux-x64": ["@opentui/core-linux-x64@0.2.16", "", { "os": "linux", "cpu": "x64" }, "sha512-KgQBGjiucw4e7gM+R8qOzHWBFhjCY1IfCrGjW3Wzxv2hKUlL+mPhelaeJwnEqtNxMUdVTYjlwlu3IHxslXMJWQ=="], - "@opentui/core-win32-arm64": ["@opentui/core-win32-arm64@0.2.15", "", { "os": "win32", "cpu": "arm64" }, "sha512-2SQQLvf3sgmToxrNika9AdcccKrjPJEn5jW6sSv0oEixNBzUzW41vSZZG4LM/V3lL8eg0LoYDnRZeKLB4gwSqQ=="], + "@opentui/core-win32-arm64": ["@opentui/core-win32-arm64@0.2.16", "", { "os": "win32", "cpu": "arm64" }, "sha512-C6WqEI3VkXatXraMgSFXZjEXq0pzURGjRpFAJZYmuVDmpqE57o7E80Np2UkdZ6m5kpJDt4mRyu3krc/P825iNQ=="], - "@opentui/core-win32-x64": ["@opentui/core-win32-x64@0.2.15", "", { "os": "win32", "cpu": "x64" }, "sha512-SVMVgnC7LVEm+yVZKdmmhRBj/xAT94PanT+UCcHxaCWK+OLmv/AX+ohHq2m0odup6iXcEqj+7mAltO9fgJLFIg=="], + "@opentui/core-win32-x64": ["@opentui/core-win32-x64@0.2.16", "", { "os": "win32", "cpu": "x64" }, "sha512-kCX3CMTns6DMCFDNTDV4sjmBKyA/iEvzaVhl/jYi4JRIVT2zcy1lo+lhXT5mPgYHmJZu8Uye6j3Zi3c7Z2Me5A=="], - "@opentui/keymap": ["@opentui/keymap@0.2.15", "", { "dependencies": { "@opentui/core": "0.2.15" }, "peerDependencies": { "@opentui/react": "0.2.15", "@opentui/solid": "0.2.15", "react": ">=19.2.0", "solid-js": "1.9.12" }, "optionalPeers": ["@opentui/react", "@opentui/solid", "react", "solid-js"] }, "sha512-wqQp6y7P2jZZJiOMwupxjGryuSWCs+njjglwW/xny9J17gomBmUvTIcIIWNG0Jv+EGO9ScBzCScGlwBHFhHyYw=="], + "@opentui/keymap": ["@opentui/keymap@0.2.16", "", { "dependencies": { "@opentui/core": "0.2.16" }, "peerDependencies": { "@opentui/react": "0.2.16", "@opentui/solid": "0.2.16", "react": ">=19.2.0", "solid-js": "1.9.12" }, "optionalPeers": ["@opentui/react", "@opentui/solid", "react", "solid-js"] }, "sha512-YBLQfNLbU2kx49bjEY9rrFoNlvIoi5qNJfRcOt6frvnR3C6MLl0/8hZY+vMQ2PEQWeEiNejFnl1lQw+z4Nk2FQ=="], - "@opentui/solid": ["@opentui/solid@0.2.15", "", { "dependencies": { "@babel/core": "7.28.0", "@babel/preset-typescript": "7.27.1", "@opentui/core": "0.2.15", "babel-plugin-module-resolver": "5.0.2", "babel-preset-solid": "1.9.12", "entities": "7.0.1", "s-js": "^0.4.9" }, "peerDependencies": { "solid-js": "1.9.12" } }, "sha512-CViepAjsCWXwrLndMt+qlLo7cooVX7DXwSJHNizw7mfrRJtOPzSYJZCIk1vF4IJTWffCHygoYMe3uSeKvzAcbw=="], + "@opentui/solid": ["@opentui/solid@0.2.16", "", { "dependencies": { "@babel/core": "7.28.0", "@babel/preset-typescript": "7.27.1", "@opentui/core": "0.2.16", "babel-plugin-module-resolver": "5.0.2", "babel-preset-solid": "1.9.12", "entities": "7.0.1", "s-js": "^0.4.9" }, "peerDependencies": { "solid-js": "1.9.12" } }, "sha512-2Q+v1PPpXXr+sALi9Aj6I5Jvo7xDfbmstYjRLL7lW3Hghh9i7ONQKpt/gyDDRbhSsYrhxKYTNenF9OxgoXkTHg=="], "@oslojs/asn1": ["@oslojs/asn1@1.0.0", "", { "dependencies": { "@oslojs/binary": "1.0.0" } }, "sha512-zw/wn0sj0j0QKbIXfIlnEcTviaCzYOY3V5rAyjR6YtOByFtJiT574+8p9Wlach0lZH9fddD4yb9laEAIl4vXQA=="], @@ -5155,7 +5158,7 @@ "write-file-atomic": ["write-file-atomic@7.0.1", "", { "dependencies": { "signal-exit": "^4.0.1" } }, "sha512-OTIk8iR8/aCRWBqvxrzxR0hgxWpnYBblY1S5hDWBQfk/VFmJwzmJgQFN3WsoUKHISv2eAwe+PpbUzyL1CKTLXg=="], - "ws": ["ws@8.18.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw=="], + "ws": ["ws@8.21.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g=="], "wsl-utils": ["wsl-utils@0.3.1", "", { "dependencies": { "is-wsl": "^3.1.0", "powershell-utils": "^0.1.0" } }, "sha512-g/eziiSUNBSsdDJtCLB8bdYEUMj4jR7AGeUo96p/3dTafgjHhpF4RiCFPiRILwjQoDXx5MqkBr4fwWtR3Ky4Wg=="], @@ -5247,9 +5250,11 @@ "@ai-sdk/fireworks/@ai-sdk/openai-compatible": ["@ai-sdk/openai-compatible@2.0.41", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@ai-sdk/provider-utils": "4.0.23" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-kNAGINk71AlOXx10Dq/PXw4t/9XjdK8uxfpVElRwtSFMdeSiLVt58p9TPx4/FJD+hxZuVhvxYj9r42osxWq79g=="], - "@ai-sdk/google-vertex/@ai-sdk/anthropic": ["@ai-sdk/anthropic@3.0.78", "", { "dependencies": { "@ai-sdk/provider": "3.0.10", "@ai-sdk/provider-utils": "4.0.27" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-0OY12G20cUt6iU6htpEA1491Oz++NVxZxlmWGX4B7rSbeZ5pnDmOu6YtW9BKzdZlNx5Gn23i6WMxyZFoMKNcgA=="], + "@ai-sdk/google/@ai-sdk/provider": ["@ai-sdk/provider@3.0.10", "", { "dependencies": { "json-schema": "^0.4.0" } }, "sha512-Q3BZ27qfpYqnCYGvE3vt+Qi6LGOF9R5Nmzn+9JoM1lCRsD9mYaIhfJLkSunN48nfGXJ6n+XNV0J/XVpqGQl7Dw=="], - "@ai-sdk/google-vertex/@ai-sdk/google": ["@ai-sdk/google@3.0.75", "", { "dependencies": { "@ai-sdk/provider": "3.0.10", "@ai-sdk/provider-utils": "4.0.27" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-XAm31ftiOrzlb8NjDzT7kw0xw+4lmgFdGFn1QKM73nXFFKyN1kWLESBV75UGNfjXP8X1YJ0YydnMVqO0jaPghw=="], + "@ai-sdk/google/@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@4.0.27", "", { "dependencies": { "@ai-sdk/provider": "3.0.10", "@standard-schema/spec": "^1.1.0", "eventsource-parser": "^3.0.8" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-ubkAJ+xODouwtmN1tYlvTPphH1hPOBfZaEQe8U7skGvFAnIRs9PPpsq57bC2+Ky/MB4yzhd6YOsxTAx9sGpazw=="], + + "@ai-sdk/google-vertex/@ai-sdk/anthropic": ["@ai-sdk/anthropic@3.0.77", "", { "dependencies": { "@ai-sdk/provider": "3.0.10", "@ai-sdk/provider-utils": "4.0.27" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-ML8C2M1YvPA1ulEx4TiyF0k1xvC2ikEiPBIC1PPQ0a5xELUGrO2lAaEzsTEoJ+eCeDd8PSBuFJjs+r+9yIwQXA=="], "@ai-sdk/google-vertex/@ai-sdk/openai-compatible": ["@ai-sdk/openai-compatible@2.0.47", "", { "dependencies": { "@ai-sdk/provider": "3.0.10", "@ai-sdk/provider-utils": "4.0.27" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-Enm5UlL0zUCrW3792opk5h7hRWxZOZzDe6eQYVFqX9LUOGGCe1h8MZWAGim765nwzgnjlpeYOsuzZmLtRsTPlg=="], @@ -5511,6 +5516,8 @@ "@cloudflare/kv-asset-handler/mime": ["mime@3.0.0", "", { "bin": { "mime": "cli.js" } }, "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A=="], + "@cloudflare/vite-plugin/ws": ["ws@8.18.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw=="], + "@cspotcode/source-map-support/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.9", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" } }, "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ=="], "@develar/schema-utils/ajv": ["ajv@6.14.0", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw=="], @@ -5973,6 +5980,8 @@ "miniflare/undici": ["undici@7.14.0", "", {}, "sha512-Vqs8HTzjpQXZeXdpsfChQTlafcMQaaIwnGwLam1wudSSjlJeQ3bw1j+TLPePgrCnCpUXx7Ba5Pdpf5OBih62NQ=="], + "miniflare/ws": ["ws@8.18.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw=="], + "miniflare/zod": ["zod@3.22.3", "", {}, "sha512-EjIevzuJRiRPbVH4mGc8nApb/lVLKVpmUhAaR5R5doKGfAnGJ6Gr3CViAVjP+4FWSxCsybeWQdcgCtbX+7oZug=="], "minipass-flush/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], @@ -6089,6 +6098,8 @@ "storybook/open": ["open@10.2.0", "", { "dependencies": { "default-browser": "^5.2.1", "define-lazy-prop": "^3.0.0", "is-inside-container": "^1.0.0", "wsl-utils": "^0.1.0" } }, "sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA=="], + "storybook/ws": ["ws@8.18.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw=="], + "storybook-solidjs-vite/vite-plugin-solid": ["vite-plugin-solid@2.11.12", "", { "dependencies": { "@babel/core": "^7.23.3", "@types/babel__core": "^7.20.4", "babel-preset-solid": "^1.8.4", "merge-anything": "^5.1.7", "solid-refresh": "^0.6.3", "vitefu": "^1.0.4" }, "peerDependencies": { "@testing-library/jest-dom": "^5.16.6 || ^5.17.0 || ^6.*", "solid-js": "^1.7.2", "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" }, "optionalPeers": ["@testing-library/jest-dom"] }, "sha512-FgjPcx2OwX9h6f28jli7A4bG7PP3te8uyakE5iqsmpq3Jqi1TWLgSroC9N6cMfGRU2zXsl4Q6ISvTr2VL0QHpA=="], "string-width-cjs/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], @@ -6189,6 +6200,10 @@ "@ai-sdk/google-vertex/@ai-sdk/provider-utils/eventsource-parser": ["eventsource-parser@3.0.8", "", {}, "sha512-70QWGkr4snxr0OXLRWsFLeRBIRPuQOvt4s8QYjmUlmlkyTZkRqS7EDVRZtzU3TiyDbXSzaOeF0XUKy8PchzukQ=="], + "@ai-sdk/google/@ai-sdk/provider-utils/@standard-schema/spec": ["@standard-schema/spec@1.1.0", "", {}, "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w=="], + + "@ai-sdk/google/@ai-sdk/provider-utils/eventsource-parser": ["eventsource-parser@3.0.8", "", {}, "sha512-70QWGkr4snxr0OXLRWsFLeRBIRPuQOvt4s8QYjmUlmlkyTZkRqS7EDVRZtzU3TiyDbXSzaOeF0XUKy8PchzukQ=="], + "@ai-sdk/groq/@ai-sdk/provider-utils/@standard-schema/spec": ["@standard-schema/spec@1.1.0", "", {}, "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w=="], "@ai-sdk/mistral/@ai-sdk/provider-utils/@standard-schema/spec": ["@standard-schema/spec@1.1.0", "", {}, "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w=="], diff --git a/infra/lake.ts b/infra/lake.ts index 04a3c46ba..c62bb1556 100644 --- a/infra/lake.ts +++ b/infra/lake.ts @@ -209,8 +209,8 @@ const ingestConfig = new sst.Linkable("LakeIngestConfig", { const ingestService = new sst.aws.Service("LakeIngestService", { cluster: lakeCluster, architecture: "arm64", - cpu: "0.5 vCPU", - memory: "1 GB", + cpu: "1 vCPU", + memory: "4 GB", image: { context: ".", dockerfile: "packages/stats/server/Dockerfile", diff --git a/infra/stage.ts b/infra/stage.ts index beb3f5925..8d80eefed 100644 --- a/infra/stage.ts +++ b/infra/stage.ts @@ -5,10 +5,8 @@ export const domain = (() => { })() export const zoneID = "430ba34c138cfb5360826c4909f99be8" -// Dev owns the shared AWS lake/stats infra for all non-production stages. export const awsStage = $app.stage === "production" ? "production" : "dev" -// Temporarily omit AWS infra so SST removes the lake/stats resources. -export const deployAws = false +export const deployAws = $app.stage === awsStage new cloudflare.RegionalHostname("RegionalHostname", { hostname: domain, diff --git a/nix/hashes.json b/nix/hashes.json index ce0261833..10d281550 100644 --- a/nix/hashes.json +++ b/nix/hashes.json @@ -1,8 +1,8 @@ { "nodeModules": { - "x86_64-linux": "sha256-p8EPw6YDdAaToGibLAljdtLuuSIqQ3mVJecYOwUWqY0=", - "aarch64-linux": "sha256-G/xOunyVzqJucokje713GkysXgixJmce6jlevRht7Sc=", - "aarch64-darwin": "sha256-zMeGIyWXUb0ofrUGxTluAytZMkTtlyEydIhbu62O2VM=", - "x86_64-darwin": "sha256-ef7+QlnKmtB2fGOw3EFjlyZcgj+Q8XLbNVdPQiNNvh8=" + "x86_64-linux": "sha256-KFVkxs0jtN1EXvwuxFMOlWg6BDr8L6K/wJZ/N73p8cI=", + "aarch64-linux": "sha256-7OLglRBBt5prwb9e0I0iMTXi3MrDfDI+8xcDrxtq/JI=", + "aarch64-darwin": "sha256-Q7iE6xJyomDnvqUgsHh+FlCnJFI6vK0zJSfI9BBYitQ=", + "x86_64-darwin": "sha256-9lVsq2Bw74Vgphg6GSo/HxCtDXUyabxcS/vE1Um/Hfw=" } } diff --git a/package.json b/package.json index fcf3873d3..5fecf69ba 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "dev:desktop": "bun --cwd packages/desktop dev", "dev:web": "bun --cwd packages/app dev", "dev:console": "ulimit -n 10240 2>/dev/null; bun run --cwd packages/console/app dev", - "dev:stats": "bun run --cwd packages/stats/app dev", + "dev:stats": "bun sst shell --stage=production -- bun run --cwd packages/stats/app dev", "dev:storybook": "bun --cwd packages/storybook storybook", "lint": "oxlint", "typecheck": "bun turbo typecheck", @@ -38,9 +38,9 @@ "@types/cross-spawn": "6.0.6", "@octokit/rest": "22.0.0", "@hono/zod-validator": "0.4.2", - "@opentui/core": "0.2.15", - "@opentui/keymap": "0.2.15", - "@opentui/solid": "0.2.15", + "@opentui/core": "0.2.16", + "@opentui/keymap": "0.2.16", + "@opentui/solid": "0.2.16", "ulid": "3.0.1", "@kobalte/core": "0.13.11", "@types/luxon": "3.7.1", @@ -144,6 +144,7 @@ "@standard-community/standard-openapi@0.2.9": "patches/@standard-community%2Fstandard-openapi@0.2.9.patch", "solid-js@1.9.10": "patches/solid-js@1.9.10.patch", "virtua@0.49.1": "patches/virtua@0.49.1.patch", - "@ai-sdk/xai@3.0.82": "patches/@ai-sdk%2Fxai@3.0.82.patch" + "@ai-sdk/xai@3.0.82": "patches/@ai-sdk%2Fxai@3.0.82.patch", + "gcp-metadata@8.1.2": "patches/gcp-metadata@8.1.2.patch" } } diff --git a/packages/app/package.json b/packages/app/package.json index 40e25cc20..9f15cd763 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/app", - "version": "1.15.10", + "version": "1.15.11", "description": "", "type": "module", "exports": { diff --git a/packages/app/src/app.tsx b/packages/app/src/app.tsx index c4eadbd5f..9554a6363 100644 --- a/packages/app/src/app.tsx +++ b/packages/app/src/app.tsx @@ -14,6 +14,7 @@ import { QueryClient, QueryClientProvider } from "@tanstack/solid-query" import { Effect } from "effect" import { type Component, + createEffect, createMemo, createResource, createSignal, @@ -40,7 +41,7 @@ import { NotificationProvider } from "@/context/notification" import { PermissionProvider } from "@/context/permission" import { PromptProvider } from "@/context/prompt" import { ServerConnection, ServerProvider, serverName, useServer } from "@/context/server" -import { SettingsProvider } from "@/context/settings" +import { SettingsProvider, useSettings } from "@/context/settings" import { TerminalProvider } from "@/context/terminal" import DirectoryLayout from "@/pages/directory-layout" import Layout from "@/pages/layout" @@ -48,11 +49,6 @@ import { ErrorPage } from "./pages/error" import { useCheckServerHealth } from "./utils/server-health" import { ServersProvider } from "./context/servers" -if (import.meta.env.VITE_OPENCODE_CHANNEL !== "prod") { - document.body.classList.remove("text-12-regular") - document.body.classList.add("font-(family-name:--font-family-text)", "text-[13px]", "font-[440]") -} - const HomeRoute = lazy(() => import("@/pages/home")) const Session = lazy(() => import("@/pages/session")) @@ -97,9 +93,26 @@ function QueryProvider(props: ParentProps) { return {props.children} } +function BodyDesignClass() { + const settings = useSettings() + + createEffect(() => { + if (typeof document === "undefined") return + + const enabled = settings.general.newLayoutDesigns() + document.body.classList.toggle("text-12-regular", !enabled) + document.body.classList.toggle("font-(family-name:--font-family-text)", enabled) + document.body.classList.toggle("text-[13px]", enabled) + document.body.classList.toggle("font-[440]", enabled) + }) + + return null +} + function AppShellProviders(props: ParentProps) { return ( + diff --git a/packages/app/src/components/prompt-input.tsx b/packages/app/src/components/prompt-input.tsx index e26217c90..84fe7495f 100644 --- a/packages/app/src/components/prompt-input.tsx +++ b/packages/app/src/components/prompt-input.tsx @@ -79,8 +79,6 @@ import { pathKey } from "@/utils/path-key" import { base64Encode } from "@opencode-ai/core/util/encode" import { displayName } from "@/pages/layout/helpers" -const USE_V2_INPUT = import.meta.env.VITE_OPENCODE_CHANNEL !== "prod" - interface PromptInputProps { class?: string variant?: "dock" | "new-session" @@ -1456,7 +1454,7 @@ export const PromptInput: Component = (props) => { t={(key) => language.t(key as Parameters[0])} /> - +
= (props) => { onKeyDown={handleKeyDown} classList={{ "select-text": true, - "min-h-[52px] w-full px-4 pt-4 pb-2 focus:outline-none whitespace-pre-wrap leading-5 text-[13px] font-[440] text-v2-text-text-faint [font-family:Inter,var(--font-family-sans)]": true, + "min-h-[52px] w-full px-4 pt-4 pb-2 focus:outline-none whitespace-pre-wrap leading-5 text-[13px] font-[440] text-v2-text-text-base": true, "[&_[data-type=file]]:text-syntax-property": true, "[&_[data-type=agent]]:text-syntax-type": true, "font-mono!": store.mode === "shell", diff --git a/packages/app/src/components/session/session-header.tsx b/packages/app/src/components/session/session-header.tsx index f028f7cea..1c2cf47a7 100644 --- a/packages/app/src/components/session/session-header.tsx +++ b/packages/app/src/components/session/session-header.tsx @@ -45,8 +45,6 @@ const OPEN_APPS = [ "sublime-text", ] as const -const USE_V2_TITLEBAR = import.meta.env.VITE_OPENCODE_CHANNEL !== "prod" - type OpenApp = (typeof OPEN_APPS)[number] type OS = "macos" | "windows" | "linux" | "unknown" @@ -157,11 +155,11 @@ export function SessionHeader() { }) const hotkey = createMemo(() => command.keybind("file.open")) const os = createMemo(() => detectOS(platform)) - const isDesktopV2 = platform.platform === "desktop" && USE_V2_TITLEBAR - const search = createMemo(() => (isDesktopV2 ? settings.general.showSearch() : true)) - const tree = createMemo(() => (isDesktopV2 ? settings.general.showFileTree() : true)) - const term = createMemo(() => (isDesktopV2 ? settings.general.showTerminal() : true)) - const status = createMemo(() => (isDesktopV2 ? settings.general.showStatus() : true)) + const isDesktopV2 = createMemo(() => platform.platform === "desktop" && settings.general.newLayoutDesigns()) + const search = createMemo(() => (isDesktopV2() ? settings.general.showSearch() : true)) + const tree = createMemo(() => (isDesktopV2() ? settings.general.showFileTree() : true)) + const term = createMemo(() => (isDesktopV2() ? settings.general.showTerminal() : true)) + const status = createMemo(() => (isDesktopV2() ? settings.general.showStatus() : true)) const [exists, setExists] = createStore>>({ finder: true, diff --git a/packages/app/src/components/settings-general.tsx b/packages/app/src/components/settings-general.tsx index 243aa6c36..bd95370a6 100644 --- a/packages/app/src/components/settings-general.tsx +++ b/packages/app/src/components/settings-general.tsx @@ -399,6 +399,18 @@ export const SettingsGeneral: Component = () => { />
+ + +
+ settings.general.setNewLayoutDesigns(checked)} + /> +
+
) @@ -802,7 +814,7 @@ export const SettingsGeneral: Component = () => { - + diff --git a/packages/app/src/components/titlebar.tsx b/packages/app/src/components/titlebar.tsx index 8e69cd47a..d7a265384 100644 --- a/packages/app/src/components/titlebar.tsx +++ b/packages/app/src/components/titlebar.tsx @@ -55,7 +55,6 @@ const legacyTitlebarHeight = 40 const v2TitlebarHeight = 44 const minTitlebarZoom = 0.25 const windowsControlsBaseWidth = 138 // 3 native Windows caption buttons at 46px each. -const USE_V2_TITLEBAR = import.meta.env.VITE_OPENCODE_CHANNEL !== "prod" const makeSessionHref = (b64Dir: string, sessionId: string) => `/${b64Dir}/session/${sessionId}` @@ -75,6 +74,7 @@ export function Titlebar(props: { update?: TitlebarUpdate }) { const navigate = useNavigate() const location = useLocation() const params = useParams() + const useV2Titlebar = createMemo(() => settings.general.newLayoutDesigns()) const mac = createMemo(() => platform.platform === "desktop" && platform.os === "macos") const windows = createMemo(() => platform.platform === "desktop" && platform.os === "windows") @@ -85,7 +85,7 @@ export function Titlebar(props: { update?: TitlebarUpdate }) { const titlebarZoom = () => (windows() ? Math.max(zoom(), minTitlebarZoom) : zoom()) const counterZoom = () => (windows() && titlebarZoom() < 1 ? 1 / titlebarZoom() : 1) const minHeight = () => { - const height = USE_V2_TITLEBAR ? v2TitlebarHeight : legacyTitlebarHeight + const height = useV2Titlebar() ? v2TitlebarHeight : legacyTitlebarHeight if (mac()) return `${height / zoom()}px` if (windows()) return `${height / Math.min(titlebarZoom(), 1)}px` return undefined @@ -119,7 +119,7 @@ export function Titlebar(props: { update?: TitlebarUpdate }) { const canBack = createMemo(() => history.index > 0) const canForward = createMemo(() => history.index < history.stack.length - 1) const hasProjects = createMemo(() => layout.projects.list().length > 0) - const nav = createMemo(() => (USE_V2_TITLEBAR ? settings.general.showNavigation() : true)) + const nav = createMemo(() => (useV2Titlebar() ? settings.general.showNavigation() : true)) const updateState = createMemo(() => { const version = props.update?.version() return { @@ -222,8 +222,8 @@ export function Titlebar(props: { update?: TitlebarUpdate }) {
- + {(_) => { const serverSync = useServerSync() const navigate = useNavigate() @@ -490,7 +490,6 @@ export function Titlebar(props: { update?: TitlebarUpdate }) { project={projectForSession(tab.info, projects(), projectByID())} directory={tab.dir} onClose={() => tabsStoreActions.removeTab(tab.href)} - hideClose={tabsEnriched().length < 2} /> )} @@ -737,14 +736,13 @@ function TabNavItem(props: { title: string project?: LocalProject directory: string - hideClose?: boolean onClose: () => void }) { const match = useMatch(() => props.href) const isActive = () => !!match() return (
{props.title} -
+
} /> diff --git a/packages/app/src/context/settings.tsx b/packages/app/src/context/settings.tsx index a4e01d53a..84288d31a 100644 --- a/packages/app/src/context/settings.tsx +++ b/packages/app/src/context/settings.tsx @@ -33,6 +33,7 @@ export interface Settings { editToolPartsExpanded: boolean showSessionProgressBar: boolean showCustomAgents: boolean + newLayoutDesigns?: boolean } updates: { startup: boolean @@ -54,6 +55,7 @@ export interface Settings { export const monoDefault = "System Mono" export const sansDefault = "System Sans" export const terminalDefault = "JetBrainsMono Nerd Font Mono" +export const newLayoutDesignsDefault = import.meta.env.VITE_OPENCODE_CHANNEL !== "prod" const monoFallback = 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace' @@ -242,6 +244,10 @@ export const { use: useSettings, provider: SettingsProvider } = createSimpleCont setShowCustomAgents(value: boolean) { setStore("general", "showCustomAgents", value) }, + newLayoutDesigns: withFallback(() => store.general?.newLayoutDesigns, newLayoutDesignsDefault), + setNewLayoutDesigns(value: boolean) { + setStore("general", "newLayoutDesigns", value) + }, }, updates: { startup: withFallback(() => store.updates?.startup, defaultSettings.updates.startup), diff --git a/packages/app/src/i18n/en.ts b/packages/app/src/i18n/en.ts index f58257b07..29f662f73 100644 --- a/packages/app/src/i18n/en.ts +++ b/packages/app/src/i18n/en.ts @@ -791,6 +791,8 @@ export const dict = { "settings.general.row.showSessionProgressBar.title": "Show session progress bar", "settings.general.row.showSessionProgressBar.description": "Display the animated progress bar at the top of the session when the agent is working", + "settings.general.row.newLayoutDesigns.title": "New layout and designs", + "settings.general.row.newLayoutDesigns.description": "Enable the redesigned layout, home, composer, and session UI", "settings.general.row.pinchZoom.title": "Pinch to zoom", "settings.general.row.pinchZoom.description": "Allow trackpad pinch and Ctrl-scroll gestures to zoom", diff --git a/packages/app/src/pages/home.tsx b/packages/app/src/pages/home.tsx index 2997efa56..8e31ac391 100644 --- a/packages/app/src/pages/home.tsx +++ b/packages/app/src/pages/home.tsx @@ -31,8 +31,8 @@ import { messageAgentColor } from "@/utils/agent" import { sessionPermissionRequest } from "@/pages/session/composer/session-request-tree" import { ServerHealthIndicator } from "@/components/server/server-row" import { useServers } from "@/context/servers" +import { useSettings } from "@/context/settings" -const USE_HOME_DESIGN = import.meta.env.VITE_OPENCODE_CHANNEL !== "prod" const HOME_SESSION_LIMIT = 15 const HOME_ROW = "flex min-w-0 w-full shrink-0 cursor-default items-center rounded-[6px] border-0 bg-transparent text-left text-v2-text-text-muted transition-colors duration-[120ms] ease-in-out hover:bg-v2-overlay-simple-overlay-hover focus-visible:bg-v2-overlay-simple-overlay-hover focus-visible:outline-none" @@ -52,8 +52,12 @@ type HomeSessionGroup = { } export default function Home() { - if (USE_HOME_DESIGN) return - return + const settings = useSettings() + return ( + }> + + + ) } function HomeDesign() { @@ -68,13 +72,11 @@ function HomeDesign() { const [state, setState] = createStore({ search: "", project: undefined as string | undefined }) const projects = createMemo(() => layout.projects.list()) - const selectedProject = createMemo( - () => projects().find((project) => project.worktree === state.project) ?? projects()[0], - ) + const selectedProject = createMemo(() => projects().find((project) => project.worktree === state.project)) const directories = (project: LocalProject) => [project.worktree, ...(project.sandboxes ?? [])] const projectDirectories = createMemo(() => { const project = selectedProject() - if (!project) return [] + if (!project) return [...projects().flatMap((project) => directories(project))] return directories(project) }) const search = createMemo(() => state.search.trim()) @@ -89,8 +91,8 @@ function HomeDesign() { const projectByID = createMemo( () => new Map(projects().flatMap((project) => (project.id ? [[project.id, project] as const] : []))), ) - const records = createMemo(() => - [ + const records = createMemo(() => { + return [ ...new Map( projectDirectories() .flatMap((directory) => sortedRootSessions(sync.child(directory, { bootstrap: false })[0], Date.now())) @@ -112,8 +114,8 @@ function HomeDesign() { if (!value) return true return `${record.session.title} ${record.projectName}`.toLowerCase().includes(value) }) - .slice(0, HOME_SESSION_LIMIT), - ) + .slice(0, HOME_SESSION_LIMIT) + }) const groups = createMemo(() => groupSessions(records(), language)) function selectProject(directory: string) { @@ -220,7 +222,7 @@ function HomeDesign() { aria-label={language.t("sidebar.project.recentSessions")} > 0} fallback={ layout.projects.list()) return ( -