diff --git a/.github/workflows/review.yml b/.github/workflows/review.yml index c0e3a5deb15..44bfeb33661 100644 --- a/.github/workflows/review.yml +++ b/.github/workflows/review.yml @@ -64,7 +64,7 @@ jobs: Please check all the code changes in this pull request against the style guide, also look for any bugs if they exist. Diffs are important but make sure you read the entire file to get proper context. Make it clear the suggestions are merely suggestions and the human can decide what to do When critiquing code against the style guide, be sure that the code is ACTUALLY in violation, don't complain about else statements if they already use early returns there. You may complain about excessive nesting though, regardless of else statement usage. - When critiquing code style don't be a zealot, we don't like "let" statements but sometimes they are the simpliest option, if someone does a bunch of nesting with let, they should consider using iife (see packages/opencode/src/util.iife.ts) + When critiquing code style don't be a zealot, we don't like "let" statements but sometimes they are the simplest option, if someone does a bunch of nesting with let, they should consider using iife (see packages/opencode/src/util.iife.ts) Use the gh cli to create comments on the files for the violations. Try to leave the comment on the exact line number. If you have a suggested fix include it in a suggestion code block. If you are writing suggested fixes, BE SURE THAT the change you are recommending is actually valid typescript, often I have seen missing closing "}" or other syntax errors. diff --git a/.github/workflows/stale-issues.yml b/.github/workflows/stale-issues.yml new file mode 100644 index 00000000000..d41e8e60c50 --- /dev/null +++ b/.github/workflows/stale-issues.yml @@ -0,0 +1,29 @@ +name: "Auto-close stale issues" + +on: + schedule: + - cron: "30 1 * * *" # Daily at 1:30 AM + workflow_dispatch: + +jobs: + stale: + runs-on: ubuntu-latest + permissions: + issues: write + steps: + - uses: actions/stale@v10 + with: + days-before-stale: 90 + days-before-close: 7 + stale-issue-label: "stale" + close-issue-message: | + [automated] Closing due to 90+ days of inactivity. + + Feel free to reopen if you still need this! + stale-issue-message: | + [automated] This issue has had no activity for 90 days. + + It will be closed in 7 days if there's no new activity. + remove-stale-when-updated: true + exempt-issue-labels: "pinned,security,feature-request,on-hold" + start-date: "2025-12-27" diff --git a/.github/workflows/sync-zed-extension.yml b/.github/workflows/sync-zed-extension.yml index a504582c3c8..9e647b8d941 100644 --- a/.github/workflows/sync-zed-extension.yml +++ b/.github/workflows/sync-zed-extension.yml @@ -2,8 +2,8 @@ name: "sync-zed-extension" on: workflow_dispatch: - # release: - # types: [published] + release: + types: [published] jobs: zed: @@ -31,4 +31,4 @@ jobs: run: | ./script/sync-zed.ts ${{ steps.get_tag.outputs.tag }} env: - GITHUB_TOKEN: ${{ secrets.SST_GITHUB_TOKEN }} + ZED_EXTENSIONS_PAT: ${{ secrets.ZED_EXTENSIONS_PAT }} diff --git a/.opencode/agent/docs.md b/.opencode/agent/docs.md index 7e5307ea0b2..21cfc6a16e0 100644 --- a/.opencode/agent/docs.md +++ b/.opencode/agent/docs.md @@ -1,5 +1,6 @@ --- description: ALWAYS use this when writing docs +color: "#38A3EE" --- You are an expert technical documentation writer diff --git a/.opencode/agent/triage.md b/.opencode/agent/triage.md index b2db100e9cf..539be154917 100644 --- a/.opencode/agent/triage.md +++ b/.opencode/agent/triage.md @@ -2,6 +2,7 @@ mode: primary hidden: true model: opencode/claude-haiku-4-5 +color: "#44BA81" tools: "*": false "github-triage": true diff --git a/README.md b/README.md index 5295810b6f0..b68195abdbe 100644 --- a/README.md +++ b/README.md @@ -79,7 +79,7 @@ you can switch between these using the `Tab` key. - Asks permission before running bash commands - Ideal for exploring unfamiliar codebases or planning changes -Also, included is a **general** subagent for complex searches and multi-step tasks. +Also, included is a **general** subagent for complex searches and multistep tasks. This is used internally and can be invoked using `@general` in messages. Learn more about [agents](https://opencode.ai/docs/agents). @@ -98,7 +98,7 @@ If you are working on a project that's related to OpenCode and is using "opencod ### FAQ -#### How is this different than Claude Code? +#### How is this different from Claude Code? It's very similar to Claude Code in terms of capability. Here are the key differences: diff --git a/STATS.md b/STATS.md index d3c6f57ad40..6c155da05ad 100644 --- a/STATS.md +++ b/STATS.md @@ -181,3 +181,6 @@ | 2025-12-23 | 1,286,548 (+24,026) | 1,186,439 (+17,318) | 2,472,987 (+41,344) | | 2025-12-24 | 1,309,323 (+22,775) | 1,203,767 (+17,328) | 2,513,090 (+40,103) | | 2025-12-25 | 1,333,032 (+23,709) | 1,217,283 (+13,516) | 2,550,315 (+37,225) | +| 2025-12-26 | 1,352,411 (+19,379) | 1,227,615 (+10,332) | 2,580,026 (+29,711) | +| 2025-12-27 | 1,371,771 (+19,360) | 1,238,236 (+10,621) | 2,610,007 (+29,981) | +| 2025-12-28 | 1,390,388 (+18,617) | 1,245,690 (+7,454) | 2,636,078 (+26,071) | diff --git a/bun.lock b/bun.lock index 796cd5661e4..b8e6b86e9f6 100644 --- a/bun.lock +++ b/bun.lock @@ -5,13 +5,6 @@ "": { "name": "opencode", "dependencies": { - "@ai-sdk/cerebras": "1.0.33", - "@ai-sdk/cohere": "2.0.21", - "@ai-sdk/deepinfra": "1.0.30", - "@ai-sdk/gateway": "2.0.23", - "@ai-sdk/groq": "2.0.33", - "@ai-sdk/perplexity": "2.0.22", - "@ai-sdk/togetherai": "1.0.30", "@aws-sdk/client-s3": "3.933.0", "@opencode-ai/plugin": "workspace:*", "@opencode-ai/script": "workspace:*", @@ -29,7 +22,7 @@ }, "packages/app": { "name": "@opencode-ai/app", - "version": "1.0.203", + "version": "1.0.207", "dependencies": { "@kobalte/core": "catalog:", "@opencode-ai/sdk": "workspace:*", @@ -77,7 +70,7 @@ }, "packages/console/app": { "name": "@opencode-ai/console-app", - "version": "1.0.203", + "version": "1.0.207", "dependencies": { "@cloudflare/vite-plugin": "1.15.2", "@ibm/plex": "6.4.1", @@ -105,7 +98,7 @@ }, "packages/console/core": { "name": "@opencode-ai/console-core", - "version": "1.0.203", + "version": "1.0.207", "dependencies": { "@aws-sdk/client-sts": "3.782.0", "@jsx-email/render": "1.1.1", @@ -132,7 +125,7 @@ }, "packages/console/function": { "name": "@opencode-ai/console-function", - "version": "1.0.203", + "version": "1.0.207", "dependencies": { "@ai-sdk/anthropic": "2.0.0", "@ai-sdk/openai": "2.0.2", @@ -156,7 +149,7 @@ }, "packages/console/mail": { "name": "@opencode-ai/console-mail", - "version": "1.0.203", + "version": "1.0.207", "dependencies": { "@jsx-email/all": "2.2.3", "@jsx-email/cli": "1.4.3", @@ -180,7 +173,7 @@ }, "packages/desktop": { "name": "@opencode-ai/desktop", - "version": "1.0.203", + "version": "1.0.207", "dependencies": { "@opencode-ai/app": "workspace:*", "@solid-primitives/storage": "catalog:", @@ -207,7 +200,7 @@ }, "packages/enterprise": { "name": "@opencode-ai/enterprise", - "version": "1.0.203", + "version": "1.0.207", "dependencies": { "@opencode-ai/ui": "workspace:*", "@opencode-ai/util": "workspace:*", @@ -236,7 +229,7 @@ }, "packages/function": { "name": "@opencode-ai/function", - "version": "1.0.203", + "version": "1.0.207", "dependencies": { "@octokit/auth-app": "8.0.1", "@octokit/rest": "catalog:", @@ -252,7 +245,7 @@ }, "packages/opencode": { "name": "opencode", - "version": "1.0.203", + "version": "1.0.207", "bin": { "opencode": "./bin/opencode", }, @@ -263,14 +256,21 @@ "@ai-sdk/amazon-bedrock": "3.0.57", "@ai-sdk/anthropic": "2.0.50", "@ai-sdk/azure": "2.0.73", + "@ai-sdk/cerebras": "1.0.33", + "@ai-sdk/cohere": "2.0.21", + "@ai-sdk/deepinfra": "1.0.30", + "@ai-sdk/gateway": "2.0.23", "@ai-sdk/google": "2.0.44", "@ai-sdk/google-vertex": "3.0.81", + "@ai-sdk/groq": "2.0.33", "@ai-sdk/mcp": "0.0.8", "@ai-sdk/mistral": "2.0.26", "@ai-sdk/openai": "2.0.71", "@ai-sdk/openai-compatible": "1.0.27", + "@ai-sdk/perplexity": "2.0.22", "@ai-sdk/provider": "2.0.0", "@ai-sdk/provider-utils": "3.0.18", + "@ai-sdk/togetherai": "1.0.30", "@ai-sdk/xai": "2.0.42", "@clack/prompts": "1.0.0-alpha.1", "@hono/standard-validator": "0.1.5", @@ -292,6 +292,7 @@ "@standard-schema/spec": "1.0.0", "@zip.js/zip.js": "2.7.62", "ai": "catalog:", + "bonjour-service": "1.3.0", "bun-pty": "0.4.2", "chokidar": "4.0.3", "clipboardy": "4.0.0", @@ -346,7 +347,7 @@ }, "packages/plugin": { "name": "@opencode-ai/plugin", - "version": "1.0.203", + "version": "1.0.207", "dependencies": { "@opencode-ai/sdk": "workspace:*", "zod": "catalog:", @@ -366,7 +367,7 @@ }, "packages/sdk/js": { "name": "@opencode-ai/sdk", - "version": "1.0.203", + "version": "1.0.207", "devDependencies": { "@hey-api/openapi-ts": "0.88.1", "@tsconfig/node22": "catalog:", @@ -377,7 +378,7 @@ }, "packages/slack": { "name": "@opencode-ai/slack", - "version": "1.0.203", + "version": "1.0.207", "dependencies": { "@opencode-ai/sdk": "workspace:*", "@slack/bolt": "^3.17.1", @@ -390,7 +391,7 @@ }, "packages/ui": { "name": "@opencode-ai/ui", - "version": "1.0.203", + "version": "1.0.207", "dependencies": { "@kobalte/core": "catalog:", "@opencode-ai/sdk": "workspace:*", @@ -425,7 +426,7 @@ }, "packages/util": { "name": "@opencode-ai/util", - "version": "1.0.203", + "version": "1.0.207", "dependencies": { "zod": "catalog:", }, @@ -436,7 +437,7 @@ }, "packages/web": { "name": "@opencode-ai/web", - "version": "1.0.203", + "version": "1.0.207", "dependencies": { "@astrojs/cloudflare": "12.6.3", "@astrojs/markdown-remark": "6.3.1", @@ -1081,6 +1082,8 @@ "@kurkle/color": ["@kurkle/color@0.3.4", "", {}, "sha512-M5UknZPHRu3DEDWoipU6sE8PdkZ6Z/S+v4dD+Ke8IaNlpdSQah50lz1KtcFBa2vsdOnwbbnxJwVM4wty6udA5w=="], + "@leichtgewicht/ip-codec": ["@leichtgewicht/ip-codec@2.0.5", "", {}, "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw=="], + "@mdx-js/mdx": ["@mdx-js/mdx@3.1.1", "", { "dependencies": { "@types/estree": "^1.0.0", "@types/estree-jsx": "^1.0.0", "@types/hast": "^3.0.0", "@types/mdx": "^2.0.0", "acorn": "^8.0.0", "collapse-white-space": "^2.0.0", "devlop": "^1.0.0", "estree-util-is-identifier-name": "^3.0.0", "estree-util-scope": "^1.0.0", "estree-walker": "^3.0.0", "hast-util-to-jsx-runtime": "^2.0.0", "markdown-extensions": "^2.0.0", "recma-build-jsx": "^1.0.0", "recma-jsx": "^1.0.0", "recma-stringify": "^1.0.0", "rehype-recma": "^1.0.0", "remark-mdx": "^3.0.0", "remark-parse": "^11.0.0", "remark-rehype": "^11.0.0", "source-map": "^0.7.0", "unified": "^11.0.0", "unist-util-position-from-estree": "^2.0.0", "unist-util-stringify-position": "^4.0.0", "unist-util-visit": "^5.0.0", "vfile": "^6.0.0" } }, "sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ=="], "@mixmark-io/domino": ["@mixmark-io/domino@2.2.0", "", {}, "sha512-Y28PR25bHXUg88kCV7nivXrP2Nj2RueZ3/l/jdx6J9f8J4nsEGcgX0Qe6lt7Pa+J79+kPiJU3LguR6O/6zrLOw=="], @@ -2003,6 +2006,8 @@ "body-parser": ["body-parser@1.20.3", "", { "dependencies": { "bytes": "3.1.2", "content-type": "~1.0.5", "debug": "2.6.9", "depd": "2.0.0", "destroy": "1.2.0", "http-errors": "2.0.0", "iconv-lite": "0.4.24", "on-finished": "2.4.1", "qs": "6.13.0", "raw-body": "2.5.2", "type-is": "~1.6.18", "unpipe": "1.0.0" } }, "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g=="], + "bonjour-service": ["bonjour-service@1.3.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "multicast-dns": "^7.2.5" } }, "sha512-3YuAUiSkWykd+2Azjgyxei8OWf8thdn8AITIog2M4UICzoqfjlqr64WIjEXZllf/W6vK1goqleSR6brGomxQqA=="], + "boolbase": ["boolbase@1.0.0", "", {}, "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="], "bottleneck": ["bottleneck@2.19.5", "", {}, "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw=="], @@ -2247,6 +2252,8 @@ "dlv": ["dlv@1.1.3", "", {}, "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA=="], + "dns-packet": ["dns-packet@5.6.1", "", { "dependencies": { "@leichtgewicht/ip-codec": "^2.0.1" } }, "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw=="], + "dom-serializer": ["dom-serializer@2.0.0", "", { "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.2", "entities": "^4.2.0" } }, "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg=="], "domelementtype": ["domelementtype@2.3.0", "", {}, "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw=="], @@ -3023,6 +3030,8 @@ "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], + "multicast-dns": ["multicast-dns@7.2.5", "", { "dependencies": { "dns-packet": "^5.2.2", "thunky": "^1.0.2" }, "bin": { "multicast-dns": "cli.js" } }, "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg=="], + "mustache": ["mustache@4.2.0", "", { "bin": { "mustache": "bin/mustache" } }, "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ=="], "mysql2": ["mysql2@3.14.4", "", { "dependencies": { "aws-ssl-profiles": "^1.1.1", "denque": "^2.1.0", "generate-function": "^2.3.1", "iconv-lite": "^0.7.0", "long": "^5.2.1", "lru.min": "^1.0.0", "named-placeholders": "^1.1.3", "seq-queue": "^0.0.5", "sqlstring": "^2.3.2" } }, "sha512-Cs/jx3WZPNrYHVz+Iunp9ziahaG5uFMvD2R8Zlmc194AqXNxt9HBNu7ZsPYrUtmJsF0egETCWIdMIYAwOGjL1w=="], @@ -3595,6 +3604,8 @@ "three": ["three@0.177.0", "", {}, "sha512-EiXv5/qWAaGI+Vz2A+JfavwYCMdGjxVsrn3oBwllUoqYeaBO75J63ZfyaQKoiLrqNHoTlUc6PFgMXnS0kI45zg=="], + "thunky": ["thunky@1.1.0", "", {}, "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA=="], + "tiny-inflate": ["tiny-inflate@1.0.3", "", {}, "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw=="], "tiny-invariant": ["tiny-invariant@1.3.3", "", {}, "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg=="], diff --git a/flake.lock b/flake.lock index 4ff2c1d0e11..dcc8c594a70 100644 --- a/flake.lock +++ b/flake.lock @@ -2,11 +2,11 @@ "nodes": { "nixpkgs": { "locked": { - "lastModified": 1766532406, - "narHash": "sha256-acLU/ag9VEoKkzOD202QASX25nG1eArXg5A0mHjKgxM=", + "lastModified": 1766840161, + "narHash": "sha256-Ss/LHpJJsng8vz1Pe33RSGIWUOcqM1fjrehjUkdrWio=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "8142186f001295e5a3239f485c8a49bf2de2695a", + "rev": "3edc4a30ed3903fdf6f90c837f961fa6b49582d1", "type": "github" }, "original": { diff --git a/install b/install index e89ca9fb70f..702fb4a534c 100755 --- a/install +++ b/install @@ -155,8 +155,18 @@ if [ -z "$requested_version" ]; then exit 1 fi else + # Strip leading 'v' if present + requested_version="${requested_version#v}" url="https://github.com/sst/opencode/releases/download/v${requested_version}/$filename" specific_version=$requested_version + + # Verify the release exists before downloading + http_status=$(curl -sI -o /dev/null -w "%{http_code}" "https://github.com/sst/opencode/releases/tag/v${requested_version}") + if [ "$http_status" = "404" ]; then + echo -e "${RED}Error: Release v${requested_version} not found${NC}" + echo -e "${MUTED}Available releases: https://github.com/sst/opencode/releases${NC}" + exit 1 + fi fi print_message() { diff --git a/nix/hashes.json b/nix/hashes.json index 66c0baaf791..f43b14684c3 100644 --- a/nix/hashes.json +++ b/nix/hashes.json @@ -1,3 +1,3 @@ { - "nodeModules": "sha256-hotsyeWJA6/dP6DvZTN1Ak2RSKcsyvXlXPI/jexBHME=" + "nodeModules": "sha256-lloUZt5mLyNWAcbQrJB4wGUKvKu24WFEhOLfZD5/FMg=" } diff --git a/package.json b/package.json index 7346a4ca853..aa7031bec72 100644 --- a/package.json +++ b/package.json @@ -67,13 +67,6 @@ "turbo": "2.5.6" }, "dependencies": { - "@ai-sdk/cerebras": "1.0.33", - "@ai-sdk/cohere": "2.0.21", - "@ai-sdk/deepinfra": "1.0.30", - "@ai-sdk/gateway": "2.0.23", - "@ai-sdk/groq": "2.0.33", - "@ai-sdk/perplexity": "2.0.22", - "@ai-sdk/togetherai": "1.0.30", "@aws-sdk/client-s3": "3.933.0", "@opencode-ai/plugin": "workspace:*", "@opencode-ai/script": "workspace:*", diff --git a/packages/app/index.html b/packages/app/index.html index 2c3a0eabd40..ea423780448 100644 --- a/packages/app/index.html +++ b/packages/app/index.html @@ -1,5 +1,5 @@ - +
@@ -13,14 +13,39 @@ - - - + + diff --git a/packages/app/package.json b/packages/app/package.json index 4fc9678e70e..01721f6e498 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/app", - "version": "1.0.203", + "version": "1.0.207", "description": "", "type": "module", "exports": { diff --git a/packages/app/src/app.tsx b/packages/app/src/app.tsx index 11216643e5b..bf5ba956622 100644 --- a/packages/app/src/app.tsx +++ b/packages/app/src/app.tsx @@ -8,6 +8,7 @@ import { DiffComponentProvider } from "@opencode-ai/ui/context/diff" import { CodeComponentProvider } from "@opencode-ai/ui/context/code" import { Diff } from "@opencode-ai/ui/diff" import { Code } from "@opencode-ai/ui/code" +import { ThemeProvider } from "@opencode-ai/ui/theme" import { GlobalSyncProvider } from "@/context/global-sync" import { LayoutProvider } from "@/context/layout" import { GlobalSDKProvider } from "@/context/global-sdk" @@ -38,55 +39,57 @@ const url = iife(() => { if (import.meta.env.DEV) return `http://${import.meta.env.VITE_OPENCODE_SERVER_HOST ?? "localhost"}:${import.meta.env.VITE_OPENCODE_SERVER_PORT ?? "4096"}` - return "http://localhost:4096" + return window.location.origin }) export function App() { return (