Compare commits

..
38 Commits
Author SHA1 Message Date
opencode 5b5bd146ea release: v0.5.25 2025-08-25 16:38:24 +00:00
adamdotdevin 836c2060c7 fix(tui): sort custom commands lower 2025-08-25 11:32:15 -05:00
adamdotdevin 6357136ca5 fix(tui): sort custom commands lower 2025-08-25 11:29:56 -05:00
adamdotdevin 0a0b363587 feat(tui): grok free 2025-08-25 11:27:58 -05:00
Jay V f5f6167146 docs: edit 2025-08-25 12:11:02 -04:00
adamdotdevin f1684c9e15 fix(tui): fix logo color 2025-08-25 10:08:52 -05:00
adamdotdevin f597b7287b chore: cleanup 2025-08-25 10:08:10 -05:00
GitHub Action 95fabc1407 ignore: update download stats 2025-08-25 2025-08-25 12:04:21 +00:00
Aiden Cline 315c366e11 docs: fix shell examples (#2236) 2025-08-24 23:53:39 -05:00
opencode 5d68a7c2e0 release: v0.5.24 2025-08-24 23:01:00 +00:00
Dax Raad 1b2d3bf659 ci: tweak 2025-08-24 18:55:44 -04:00
opencode 24e4f5b051 release: v0.5.23 2025-08-24 22:53:37 +00:00
Dax Raad 2992c5a6bf ci: retry clone 2025-08-24 18:48:03 -04:00
Dax Raad ca2660ccf8 ci: ignore 2025-08-24 18:31:44 -04:00
Frank 6b4bd590ac Add opencode workflow 2025-08-25 06:16:21 +08:00
Frank 60ba42af15 Add opencode workflow 2025-08-25 06:14:47 +08:00
Frank f22827bdfa Add opencode workflow 2025-08-25 03:39:11 +08:00
Frank f9b5b6d129 Add opencode workflow 2025-08-25 03:38:02 +08:00
Aiden Cline cc66e06101 fix: command model selection (#2219) 2025-08-24 12:06:48 -05:00
GitHub Action d4c8d95ec6 ignore: update download stats 2025-08-24 2025-08-24 12:03:59 +00:00
Aiden Cline 0fd312346b docs: fix plan agent docs (#2215) 2025-08-23 14:52:02 -05:00
OpeOginniandrekram1-node b80046120c docs: document editor --wait flag (#2209)
Co-authored-by: rekram1-node <aidenpcline@gmail.com>
2025-08-23 14:43:20 -05:00
Aiden Cline 07ed2a8391 docs: document out of box lsps (#2213) 2025-08-23 14:22:22 -05:00
opencode e9f52934e9 release: v0.5.18 2025-08-23 16:27:02 +00:00
Dax Raad 732b67f8ce ci: stuff 2025-08-23 12:21:58 -04:00
Dax Raad d47bb96784 ci: ignore 2025-08-23 12:10:08 -04:00
Johnny 6456350564 docs: fix nodejs installation commands (#2193) 2025-08-23 08:23:24 -05:00
GitHub Action c5c0a2ca6e ignore: update download stats 2025-08-23 2025-08-23 12:03:48 +00:00
Vasiliy Kulikovandrekram1-node 3706b2bca7 feat(lsp): option to disable lsps installing automatically (#1997)
Co-authored-by: rekram1-node <aidenpcline@gmail.com>
2025-08-22 22:39:19 -05:00
Aiden Cline 1f57b9a70f fix: count reasoning tokens (#2187) 2025-08-22 18:21:39 -05:00
Aiden Cline 004f53f741 ignore: update json schema for better lsp dx (#2186) 2025-08-22 17:59:18 -05:00
Jay V cf29ec0a59 docs: edit 2025-08-22 18:36:17 -04:00
Jay V b5e08acdf7 docs: update 2025-08-22 18:34:35 -04:00
Dax Raad 7ddeeeb4f8 ignore: typecheck 2025-08-22 18:31:51 -04:00
Dax Raad 0f1697b2ab add sse streaming to sdk 2025-08-22 18:30:25 -04:00
Lubos 6e626afdcb chore(openapi): set correct content type for server-sent events (#2045) 2025-08-22 17:51:24 -04:00
Dax Raad 0fe94c1616 docs: add file names to code block titles in commands.mdx 2025-08-22 17:23:59 -04:00
Dax Raad a42b004c72 docs: add commands page to sidebar 2025-08-22 17:23:59 -04:00
36 changed files with 245 additions and 136 deletions
+6 -8
View File
@@ -8,22 +8,20 @@ jobs:
opencode: opencode:
if: | if: |
contains(github.event.comment.body, ' /oc') || contains(github.event.comment.body, ' /oc') ||
startsWith(github.event.comment.body, '/oc') || contains(github.event.comment.body, ' /opencode')
contains(github.event.comment.body, ' /opencode') ||
startsWith(github.event.comment.body, '/opencode')
runs-on: ubuntu-latest runs-on: ubuntu-latest
permissions: permissions:
contents: read
id-token: write id-token: write
contents: read
pull-requests: read
issues: read
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4 uses: actions/checkout@v4
with:
fetch-depth: 1
- name: Run opencode - name: Run opencode
uses: sst/opencode/github@latest uses: sst/opencode/github@latest
env: env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} OPENCODE_API_KEY: ${{ secrets.OPENCODE_API_KEY }}
with: with:
model: anthropic/claude-sonnet-4-20250514 model: opencode/sonic
+1 -1
View File
@@ -107,4 +107,4 @@ The other confusingly named repo has no relation to this one. You can [read the
--- ---
**Join our community** [Discord](https://discord.gg/opencode) | [YouTube](https://www.youtube.com/c/sst-dev) | [X.com](https://x.com/SST_dev) **Join our community** [Discord](https://discord.gg/opencode) | [YouTube](https://www.youtube.com/c/sst-dev) | [X.com](https://x.com/anomaly_inv)
+3
View File
@@ -56,3 +56,6 @@
| 2025-08-20 | 214,497 (+4,683) | 191,481 (+1,813) | 405,978 (+6,496) | | 2025-08-20 | 214,497 (+4,683) | 191,481 (+1,813) | 405,978 (+6,496) |
| 2025-08-21 | 220,465 (+5,968) | 194,784 (+3,303) | 415,249 (+9,271) | | 2025-08-21 | 220,465 (+5,968) | 194,784 (+3,303) | 415,249 (+9,271) |
| 2025-08-22 | 225,899 (+5,434) | 197,204 (+2,420) | 423,103 (+7,854) | | 2025-08-22 | 225,899 (+5,434) | 197,204 (+2,420) | 423,103 (+7,854) |
| 2025-08-23 | 229,005 (+3,106) | 199,238 (+2,034) | 428,243 (+5,140) |
| 2025-08-24 | 232,098 (+3,093) | 201,157 (+1,919) | 433,255 (+5,012) |
| 2025-08-25 | 236,607 (+4,509) | 202,650 (+1,493) | 439,257 (+6,002) |
+17 -12
View File
@@ -26,7 +26,7 @@
}, },
"cloud/core": { "cloud/core": {
"name": "@opencode/cloud-core", "name": "@opencode/cloud-core",
"version": "0.5.13", "version": "0.5.15",
"dependencies": { "dependencies": {
"@aws-sdk/client-sts": "3.782.0", "@aws-sdk/client-sts": "3.782.0",
"drizzle-orm": "0.41.0", "drizzle-orm": "0.41.0",
@@ -40,7 +40,7 @@
}, },
"cloud/function": { "cloud/function": {
"name": "@opencode/cloud-function", "name": "@opencode/cloud-function",
"version": "0.5.13", "version": "0.5.15",
"dependencies": { "dependencies": {
"@ai-sdk/anthropic": "2.0.0", "@ai-sdk/anthropic": "2.0.0",
"@ai-sdk/openai": "2.0.2", "@ai-sdk/openai": "2.0.2",
@@ -60,7 +60,7 @@
}, },
"cloud/web": { "cloud/web": {
"name": "@opencode/cloud-web", "name": "@opencode/cloud-web",
"version": "0.5.13", "version": "0.5.15",
"dependencies": { "dependencies": {
"@kobalte/core": "0.13.9", "@kobalte/core": "0.13.9",
"@openauthjs/solid": "0.0.0-20250322224806", "@openauthjs/solid": "0.0.0-20250322224806",
@@ -79,7 +79,7 @@
}, },
"packages/function": { "packages/function": {
"name": "@opencode/function", "name": "@opencode/function",
"version": "0.5.13", "version": "0.5.15",
"dependencies": { "dependencies": {
"@octokit/auth-app": "8.0.1", "@octokit/auth-app": "8.0.1",
"@octokit/rest": "22.0.0", "@octokit/rest": "22.0.0",
@@ -94,7 +94,7 @@
}, },
"packages/opencode": { "packages/opencode": {
"name": "opencode", "name": "opencode",
"version": "0.5.13", "version": "0.5.15",
"bin": { "bin": {
"opencode": "./bin/opencode", "opencode": "./bin/opencode",
}, },
@@ -144,19 +144,22 @@
}, },
"packages/plugin": { "packages/plugin": {
"name": "@opencode-ai/plugin", "name": "@opencode-ai/plugin",
"version": "0.5.13", "version": "0.5.15",
"dependencies": { "dependencies": {
"@opencode-ai/sdk": "workspace:*", "@opencode-ai/sdk": "workspace:*",
}, },
"devDependencies": { "devDependencies": {
"@hey-api/openapi-ts": "0.80.1", "@hey-api/openapi-ts": "0.81.0",
"@tsconfig/node22": "catalog:", "@tsconfig/node22": "catalog:",
"typescript": "catalog:", "typescript": "catalog:",
}, },
}, },
"packages/sdk/js": { "packages/sdk/js": {
"name": "@opencode-ai/sdk", "name": "@opencode-ai/sdk",
"version": "0.5.13", "version": "0.5.15",
"dependencies": {
"@hey-api/openapi-ts": "0.80.1",
},
"devDependencies": { "devDependencies": {
"@hey-api/openapi-ts": "0.80.1", "@hey-api/openapi-ts": "0.80.1",
"@tsconfig/node22": "catalog:", "@tsconfig/node22": "catalog:",
@@ -165,7 +168,7 @@
}, },
"packages/web": { "packages/web": {
"name": "@opencode/web", "name": "@opencode/web",
"version": "0.5.13", "version": "0.5.15",
"dependencies": { "dependencies": {
"@astrojs/cloudflare": "12.6.3", "@astrojs/cloudflare": "12.6.3",
"@astrojs/markdown-remark": "6.3.1", "@astrojs/markdown-remark": "6.3.1",
@@ -187,7 +190,7 @@
"sharp": "0.32.5", "sharp": "0.32.5",
"shiki": "3.4.2", "shiki": "3.4.2",
"solid-js": "1.9.7", "solid-js": "1.9.7",
"toolbeam-docs-theme": "0.4.5", "toolbeam-docs-theme": "0.4.6",
}, },
"devDependencies": { "devDependencies": {
"@types/node": "catalog:", "@types/node": "catalog:",
@@ -492,7 +495,7 @@
"@hey-api/json-schema-ref-parser": ["@hey-api/json-schema-ref-parser@1.0.6", "", { "dependencies": { "@jsdevtools/ono": "^7.1.3", "@types/json-schema": "^7.0.15", "js-yaml": "^4.1.0", "lodash": "^4.17.21" } }, "sha512-yktiFZoWPtEW8QKS65eqKwA5MTKp88CyiL8q72WynrBs/73SAaxlSWlA2zW/DZlywZ5hX1OYzrCC0wFdvO9c2w=="], "@hey-api/json-schema-ref-parser": ["@hey-api/json-schema-ref-parser@1.0.6", "", { "dependencies": { "@jsdevtools/ono": "^7.1.3", "@types/json-schema": "^7.0.15", "js-yaml": "^4.1.0", "lodash": "^4.17.21" } }, "sha512-yktiFZoWPtEW8QKS65eqKwA5MTKp88CyiL8q72WynrBs/73SAaxlSWlA2zW/DZlywZ5hX1OYzrCC0wFdvO9c2w=="],
"@hey-api/openapi-ts": ["@hey-api/openapi-ts@0.80.1", "", { "dependencies": { "@hey-api/json-schema-ref-parser": "1.0.6", "ansi-colors": "4.1.3", "c12": "2.0.1", "color-support": "1.1.3", "commander": "13.0.0", "handlebars": "4.7.8", "open": "10.1.2", "semver": "7.7.2" }, "peerDependencies": { "typescript": "^5.5.3" }, "bin": { "openapi-ts": "bin/index.cjs" } }, "sha512-AC478kg36vmmrseLZNFonZ/cmXXmDzW5yWz4PVg1S8ebJsRtVRJ/QU+mtnXfzf9avN2P0pz/AO4WAe4jyFY2gA=="], "@hey-api/openapi-ts": ["@hey-api/openapi-ts@0.81.0", "", { "dependencies": { "@hey-api/json-schema-ref-parser": "1.0.6", "ansi-colors": "4.1.3", "c12": "2.0.1", "color-support": "1.1.3", "commander": "13.0.0", "handlebars": "4.7.8", "js-yaml": "4.1.0", "open": "10.1.2", "semver": "7.7.2" }, "peerDependencies": { "typescript": "^5.5.3" }, "bin": { "openapi-ts": "bin/index.cjs" } }, "sha512-PoJukNBkUfHOoMDpN33bBETX49TUhy7Hu8Sa0jslOvFndvZ5VjQr4Nl/Dzjb9LG1Lp5HjybyTJMA6a1zYk/q6A=="],
"@hono/zod-validator": ["@hono/zod-validator@0.4.2", "", { "peerDependencies": { "hono": ">=3.9.0", "zod": "^3.19.1" } }, "sha512-1rrlBg+EpDPhzOV4hT9pxr5+xDVmKuz6YJl+la7VCwK6ass5ldyKm5fD+umJdV2zhHD6jROoCCv8NbTwyfhT0g=="], "@hono/zod-validator": ["@hono/zod-validator@0.4.2", "", { "peerDependencies": { "hono": ">=3.9.0", "zod": "^3.19.1" } }, "sha512-1rrlBg+EpDPhzOV4hT9pxr5+xDVmKuz6YJl+la7VCwK6ass5ldyKm5fD+umJdV2zhHD6jROoCCv8NbTwyfhT0g=="],
@@ -2808,7 +2811,7 @@
"toml": ["toml@3.0.0", "", {}, "sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w=="], "toml": ["toml@3.0.0", "", {}, "sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w=="],
"toolbeam-docs-theme": ["toolbeam-docs-theme@0.4.5", "", { "peerDependencies": { "@astrojs/starlight": "^0.34.3", "astro": "^5.7.13" } }, "sha512-8yu1Q57pYujy1EnQuZ5JzrV6uzTWwUAcTkBkkujtFNNUBC8jTASWp5WypiViVMd59oFqzedy1PR0G9nBBhZvRQ=="], "toolbeam-docs-theme": ["toolbeam-docs-theme@0.4.6", "", { "peerDependencies": { "@astrojs/starlight": "^0.34.3", "astro": "^5.7.13" } }, "sha512-s4yKn3PYnmPCl6MHPkQ2MedSgVh7FMAP64DiXnAfCls/H/RR6iTe0/SFgPTprz+HXXaKvv2iPo3XuvmDRY6cxQ=="],
"tr46": ["tr46@0.0.3", "", {}, "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="], "tr46": ["tr46@0.0.3", "", {}, "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="],
@@ -3208,6 +3211,8 @@
"@openauthjs/solid/@openauthjs/openauth": ["@openauthjs/openauth@0.4.2", "", { "dependencies": { "@standard-schema/spec": "1.0.0-beta.3", "aws4fetch": "1.0.20", "jose": "5.9.6" }, "peerDependencies": { "arctic": "^2.2.2", "hono": "^4.0.0" } }, "sha512-8+Bia559iffrZXfQ0LWXrVVVriochS88pDtB8indyQ1S+40MQgDBu8aBzKt+fgSrTmoQGCTT+wlOXgbjc9qIcw=="], "@openauthjs/solid/@openauthjs/openauth": ["@openauthjs/openauth@0.4.2", "", { "dependencies": { "@standard-schema/spec": "1.0.0-beta.3", "aws4fetch": "1.0.20", "jose": "5.9.6" }, "peerDependencies": { "arctic": "^2.2.2", "hono": "^4.0.0" } }, "sha512-8+Bia559iffrZXfQ0LWXrVVVriochS88pDtB8indyQ1S+40MQgDBu8aBzKt+fgSrTmoQGCTT+wlOXgbjc9qIcw=="],
"@opencode-ai/sdk/@hey-api/openapi-ts": ["@hey-api/openapi-ts@0.80.1", "", { "dependencies": { "@hey-api/json-schema-ref-parser": "1.0.6", "ansi-colors": "4.1.3", "c12": "2.0.1", "color-support": "1.1.3", "commander": "13.0.0", "handlebars": "4.7.8", "open": "10.1.2", "semver": "7.7.2" }, "peerDependencies": { "typescript": "^5.5.3" }, "bin": { "openapi-ts": "bin/index.cjs" } }, "sha512-AC478kg36vmmrseLZNFonZ/cmXXmDzW5yWz4PVg1S8ebJsRtVRJ/QU+mtnXfzf9avN2P0pz/AO4WAe4jyFY2gA=="],
"@opencode/cloud-web/solid-js": ["solid-js@1.9.5", "", { "dependencies": { "csstype": "^3.1.0", "seroval": "^1.1.0", "seroval-plugins": "^1.1.0" } }, "sha512-ogI3DaFcyn6UhYhrgcyRAMbu/buBJitYQASZz5WzfQVPP10RD2AbCoRZ517psnezrasyCbWzIxZ6kVqet768xw=="], "@opencode/cloud-web/solid-js": ["solid-js@1.9.5", "", { "dependencies": { "csstype": "^3.1.0", "seroval": "^1.1.0", "seroval-plugins": "^1.1.0" } }, "sha512-ogI3DaFcyn6UhYhrgcyRAMbu/buBJitYQASZz5WzfQVPP10RD2AbCoRZ517psnezrasyCbWzIxZ6kVqet768xw=="],
"@opentelemetry/instrumentation-grpc/@opentelemetry/semantic-conventions": ["@opentelemetry/semantic-conventions@1.27.0", "", {}, "sha512-sAay1RrB+ONOem0OZanAR1ZI/k7yDpnOQSQmTMuGImUQb2y8EbSaCJ94FQluM74xoU03vlb2d2U90hZluL6nQg=="], "@opentelemetry/instrumentation-grpc/@opentelemetry/semantic-conventions": ["@opentelemetry/semantic-conventions@1.27.0", "", {}, "sha512-sAay1RrB+ONOem0OZanAR1ZI/k7yDpnOQSQmTMuGImUQb2y8EbSaCJ94FQluM74xoU03vlb2d2U90hZluL6nQg=="],
+1 -1
View File
@@ -5,7 +5,7 @@
"dev": "vinxi dev --host 0.0.0.0", "dev": "vinxi dev --host 0.0.0.0",
"build": "vinxi build", "build": "vinxi build",
"start": "vinxi start", "start": "vinxi start",
"version": "0.5.15" "version": "0.5.25"
}, },
"dependencies": { "dependencies": {
"@ibm/plex": "6.4.1", "@ibm/plex": "6.4.1",
+1 -1
View File
@@ -1,7 +1,7 @@
{ {
"$schema": "https://json.schemastore.org/package.json", "$schema": "https://json.schemastore.org/package.json",
"name": "@opencode/cloud-core", "name": "@opencode/cloud-core",
"version": "0.5.15", "version": "0.5.25",
"private": true, "private": true,
"type": "module", "type": "module",
"dependencies": { "dependencies": {
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@opencode/cloud-function", "name": "@opencode/cloud-function",
"version": "0.5.15", "version": "0.5.25",
"$schema": "https://json.schemastore.org/package.json", "$schema": "https://json.schemastore.org/package.json",
"private": true, "private": true,
"type": "module", "type": "module",
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@opencode/cloud-web", "name": "@opencode/cloud-web",
"version": "0.5.15", "version": "0.5.25",
"private": true, "private": true,
"description": "", "description": "",
"type": "module", "type": "module",
@@ -1,15 +0,0 @@
{
"keep": {
"days": true,
"amount": 14
},
"auditLog": "/Users/adam/code/opencode/dev/logs/.496fc674ed58d31f8b883da41cc2adb4564aad58-audit.json",
"files": [
{
"date": 1755891797740,
"name": "/Users/adam/code/opencode/dev/logs/mcp-puppeteer-2025-08-22.log",
"hash": "dd9b1f2e98b661ba2f56b91dd9afbdb25e50adbdd52ed1b0eef1d2045235d17c"
}
],
"hashType": "sha256"
}
-6
View File
@@ -1,6 +0,0 @@
{"level":"info","message":"Starting MCP server","service":"mcp-puppeteer","timestamp":"2025-08-22 14:43:17.765"}
{"level":"info","message":"MCP server started successfully","service":"mcp-puppeteer","timestamp":"2025-08-22 14:43:17.766"}
{"level":"info","message":"Starting MCP server","service":"mcp-puppeteer","timestamp":"2025-08-22 14:46:45.539"}
{"level":"info","message":"MCP server started successfully","service":"mcp-puppeteer","timestamp":"2025-08-22 14:46:45.540"}
{"level":"info","message":"Starting MCP server","service":"mcp-puppeteer","timestamp":"2025-08-22 14:53:08.159"}
{"level":"info","message":"MCP server started successfully","service":"mcp-puppeteer","timestamp":"2025-08-22 14:53:08.160"}
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@opencode/function", "name": "@opencode/function",
"version": "0.5.15", "version": "0.5.25",
"$schema": "https://json.schemastore.org/package.json", "$schema": "https://json.schemastore.org/package.json",
"private": true, "private": true,
"type": "module", "type": "module",
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"$schema": "https://json.schemastore.org/package.json", "$schema": "https://json.schemastore.org/package.json",
"version": "0.5.15", "version": "0.5.25",
"name": "opencode", "name": "opencode",
"type": "module", "type": "module",
"private": true, "private": true,
+52 -5
View File
@@ -97,11 +97,11 @@ if (!snapshot) {
const macX64Sha = await $`sha256sum ./dist/opencode-darwin-x64.zip | cut -d' ' -f1`.text().then((x) => x.trim()) const macX64Sha = await $`sha256sum ./dist/opencode-darwin-x64.zip | cut -d' ' -f1`.text().then((x) => x.trim())
const macArm64Sha = await $`sha256sum ./dist/opencode-darwin-arm64.zip | cut -d' ' -f1`.text().then((x) => x.trim()) const macArm64Sha = await $`sha256sum ./dist/opencode-darwin-arm64.zip | cut -d' ' -f1`.text().then((x) => x.trim())
const pkgbuild = [ const binaryPkgbuild = [
"# Maintainer: dax", "# Maintainer: dax",
"# Maintainer: adam", "# Maintainer: adam",
"", "",
"pkgname='${pkg}'", "pkgname='opencode-bin'",
`pkgver=${version.split("-")[0]}`, `pkgver=${version.split("-")[0]}`,
"options=('!debug' '!strip')", "options=('!debug' '!strip')",
"pkgrel=1", "pkgrel=1",
@@ -125,11 +125,58 @@ if (!snapshot) {
"", "",
].join("\n") ].join("\n")
for (const pkg of ["opencode-bin"]) { // Source-based PKGBUILD for opencode
const sourcePkgbuild = [
"# Maintainer: dax",
"# Maintainer: adam",
"",
"pkgname='opencode'",
`pkgver=${version.split("-")[0]}`,
"options=('!debug' '!strip')",
"pkgrel=1",
"pkgdesc='The AI coding agent built for the terminal.'",
"url='https://github.com/sst/opencode'",
"arch=('aarch64' 'x86_64')",
"license=('MIT')",
"provides=('opencode')",
"conflicts=('opencode-bin')",
"depends=('fzf' 'ripgrep')",
"makedepends=('git' 'bun-bin' 'go')",
"",
`source=("opencode-\${pkgver}.tar.gz::https://github.com/sst/opencode/archive/v${version}.tar.gz")`,
`sha256sums=('SKIP')`,
"",
"build() {",
` cd "opencode-\${pkgver}"`,
` bun install`,
" cd packages/tui",
` CGO_ENABLED=0 go build -ldflags="-s -w -X main.Version=\${pkgver}" -o tui cmd/opencode/main.go`,
" cd ../opencode",
` bun build --define OPENCODE_TUI_PATH="'$(realpath ../tui/tui)'" --define OPENCODE_VERSION="'\${pkgver}'" --compile --target=bun-linux-x64 --outfile=opencode ./src/index.ts`,
"}",
"",
"package() {",
` cd "opencode-\${pkgver}/packages/opencode"`,
' install -Dm755 ./opencode "${pkgdir}/usr/bin/opencode"',
"}",
"",
].join("\n")
for (const [pkg, pkgbuild] of [
["opencode-bin", binaryPkgbuild],
["opencode", sourcePkgbuild],
]) {
await $`rm -rf ./dist/aur-${pkg}` await $`rm -rf ./dist/aur-${pkg}`
await $`git clone ssh://aur@aur.archlinux.org/${pkg}.git ./dist/aur-${pkg}` while (true) {
try {
await $`git clone ssh://aur@aur.archlinux.org/${pkg}.git ./dist/aur-${pkg}`
break
} catch (e) {
continue
}
}
await $`cd ./dist/aur-${pkg} && git checkout master` await $`cd ./dist/aur-${pkg} && git checkout master`
await Bun.file(`./dist/aur-${pkg}/PKGBUILD`).write(pkgbuild.replace("${pkg}", pkg)) await Bun.file(`./dist/aur-${pkg}/PKGBUILD`).write(pkgbuild)
await $`cd ./dist/aur-${pkg} && makepkg --printsrcinfo > .SRCINFO` await $`cd ./dist/aur-${pkg} && makepkg --printsrcinfo > .SRCINFO`
await $`cd ./dist/aur-${pkg} && git add PKGBUILD .SRCINFO` await $`cd ./dist/aur-${pkg} && git add PKGBUILD .SRCINFO`
await $`cd ./dist/aur-${pkg} && git commit -m "Update to v${version}"` await $`cd ./dist/aur-${pkg} && git commit -m "Update to v${version}"`
+9 -1
View File
@@ -32,5 +32,13 @@ const result = zodToJsonSchema(Config.Info, {
return jsonSchema return jsonSchema
}, },
}) }) as Record<string, unknown> & {
allowComments?: boolean
allowTrailingCommas?: boolean
}
// used for json lsps since config supports jsonc
result.allowComments = true
result.allowTrailingCommas = true
await Bun.write(file, JSON.stringify(result, null, 2)) await Bun.write(file, JSON.stringify(result, null, 2))
+1
View File
@@ -5,6 +5,7 @@ export namespace Flag {
export const OPENCODE_DISABLE_AUTOUPDATE = truthy("OPENCODE_DISABLE_AUTOUPDATE") export const OPENCODE_DISABLE_AUTOUPDATE = truthy("OPENCODE_DISABLE_AUTOUPDATE")
export const OPENCODE_PERMISSION = process.env["OPENCODE_PERMISSION"] export const OPENCODE_PERMISSION = process.env["OPENCODE_PERMISSION"]
export const OPENCODE_DISABLE_DEFAULT_PLUGINS = truthy("OPENCODE_DISABLE_DEFAULT_PLUGINS") export const OPENCODE_DISABLE_DEFAULT_PLUGINS = truthy("OPENCODE_DISABLE_DEFAULT_PLUGINS")
export const OPENCODE_DISABLE_LSP_DOWNLOAD = truthy("OPENCODE_DISABLE_LSP_DOWNLOAD")
function truthy(key: string) { function truthy(key: string) {
const value = process.env[key]?.toLowerCase() const value = process.env[key]?.toLowerCase()
+11
View File
@@ -7,6 +7,7 @@ import { BunProc } from "../bun"
import { $ } from "bun" import { $ } from "bun"
import fs from "fs/promises" import fs from "fs/promises"
import { Filesystem } from "../util/filesystem" import { Filesystem } from "../util/filesystem"
import { Flag } from "../flag/flag"
export namespace LSPServer { export namespace LSPServer {
const log = Log.create({ service: "lsp.server" }) const log = Log.create({ service: "lsp.server" })
@@ -95,6 +96,7 @@ export namespace LSPServer {
"vue-language-server.js", "vue-language-server.js",
) )
if (!(await Bun.file(js).exists())) { if (!(await Bun.file(js).exists())) {
if (Flag.OPENCODE_DISABLE_LSP_DOWNLOAD) return
await Bun.spawn([BunProc.which(), "install", "@vue/language-server"], { await Bun.spawn([BunProc.which(), "install", "@vue/language-server"], {
cwd: Global.Path.bin, cwd: Global.Path.bin,
env: { env: {
@@ -148,6 +150,7 @@ export namespace LSPServer {
if (!eslint) return if (!eslint) return
const serverPath = path.join(Global.Path.bin, "vscode-eslint", "server", "out", "eslintServer.js") const serverPath = path.join(Global.Path.bin, "vscode-eslint", "server", "out", "eslintServer.js")
if (!(await Bun.file(serverPath).exists())) { if (!(await Bun.file(serverPath).exists())) {
if (Flag.OPENCODE_DISABLE_LSP_DOWNLOAD) return
log.info("downloading and building VS Code ESLint server") log.info("downloading and building VS Code ESLint server")
const response = await fetch("https://github.com/microsoft/vscode-eslint/archive/refs/heads/main.zip") const response = await fetch("https://github.com/microsoft/vscode-eslint/archive/refs/heads/main.zip")
if (!response.ok) return if (!response.ok) return
@@ -200,6 +203,8 @@ export namespace LSPServer {
}) })
if (!bin) { if (!bin) {
if (!Bun.which("go")) return if (!Bun.which("go")) return
if (Flag.OPENCODE_DISABLE_LSP_DOWNLOAD) return
log.info("installing gopls") log.info("installing gopls")
const proc = Bun.spawn({ const proc = Bun.spawn({
cmd: ["go", "install", "golang.org/x/tools/gopls@latest"], cmd: ["go", "install", "golang.org/x/tools/gopls@latest"],
@@ -241,6 +246,7 @@ export namespace LSPServer {
log.info("Ruby not found, please install Ruby first") log.info("Ruby not found, please install Ruby first")
return return
} }
if (Flag.OPENCODE_DISABLE_LSP_DOWNLOAD) return
log.info("installing ruby-lsp") log.info("installing ruby-lsp")
const proc = Bun.spawn({ const proc = Bun.spawn({
cmd: ["gem", "install", "ruby-lsp", "--bindir", Global.Path.bin], cmd: ["gem", "install", "ruby-lsp", "--bindir", Global.Path.bin],
@@ -276,6 +282,7 @@ export namespace LSPServer {
if (!binary) { if (!binary) {
const js = path.join(Global.Path.bin, "node_modules", "pyright", "dist", "pyright-langserver.js") const js = path.join(Global.Path.bin, "node_modules", "pyright", "dist", "pyright-langserver.js")
if (!(await Bun.file(js).exists())) { if (!(await Bun.file(js).exists())) {
if (Flag.OPENCODE_DISABLE_LSP_DOWNLOAD) return
await Bun.spawn([BunProc.which(), "install", "pyright"], { await Bun.spawn([BunProc.which(), "install", "pyright"], {
cwd: Global.Path.bin, cwd: Global.Path.bin,
env: { env: {
@@ -323,6 +330,7 @@ export namespace LSPServer {
return return
} }
if (Flag.OPENCODE_DISABLE_LSP_DOWNLOAD) return
log.info("downloading elixir-ls from GitHub releases") log.info("downloading elixir-ls from GitHub releases")
const response = await fetch("https://github.com/elixir-lsp/elixir-ls/archive/refs/heads/master.zip") const response = await fetch("https://github.com/elixir-lsp/elixir-ls/archive/refs/heads/master.zip")
@@ -372,6 +380,7 @@ export namespace LSPServer {
return return
} }
if (Flag.OPENCODE_DISABLE_LSP_DOWNLOAD) return
log.info("downloading zls from GitHub releases") log.info("downloading zls from GitHub releases")
const releaseResponse = await fetch("https://api.github.com/repos/zigtools/zls/releases/latest") const releaseResponse = await fetch("https://api.github.com/repos/zigtools/zls/releases/latest")
@@ -475,6 +484,7 @@ export namespace LSPServer {
return return
} }
if (Flag.OPENCODE_DISABLE_LSP_DOWNLOAD) return
log.info("installing csharp-ls via dotnet tool") log.info("installing csharp-ls via dotnet tool")
const proc = Bun.spawn({ const proc = Bun.spawn({
cmd: ["dotnet", "tool", "install", "csharp-ls", "--tool-path", Global.Path.bin], cmd: ["dotnet", "tool", "install", "csharp-ls", "--tool-path", Global.Path.bin],
@@ -527,6 +537,7 @@ export namespace LSPServer {
PATH: process.env["PATH"] + ":" + Global.Path.bin, PATH: process.env["PATH"] + ":" + Global.Path.bin,
}) })
if (!bin) { if (!bin) {
if (Flag.OPENCODE_DISABLE_LSP_DOWNLOAD) return
log.info("downloading clangd from GitHub releases") log.info("downloading clangd from GitHub releases")
const releaseResponse = await fetch("https://api.github.com/repos/clangd/clangd/releases/latest") const releaseResponse = await fetch("https://api.github.com/repos/clangd/clangd/releases/latest")
+1 -1
View File
@@ -103,7 +103,7 @@ export namespace Server {
200: { 200: {
description: "Event stream", description: "Event stream",
content: { content: {
"application/json": { "text/event-stream": {
schema: resolver( schema: resolver(
Bus.payloads().openapi({ Bus.payloads().openapi({
ref: "Event", ref: "Event",
+9 -5
View File
@@ -1171,12 +1171,16 @@ export namespace Session {
export async function command(input: CommandInput) { export async function command(input: CommandInput) {
const command = await Command.get(input.command) const command = await Command.get(input.command)
const agent = input.agent ?? command.agent ?? "build" const agent = command.agent ?? input.agent ?? "build"
const fmtModel = (model: { providerID: string; modelID: string }) => `${model.providerID}/${model.modelID}`
const model = const model =
input.model ??
command.model ?? command.model ??
(await Agent.get(agent).then((x) => (x.model ? `${x.model.providerID}/${x.model.modelID}` : undefined))) ?? (command.agent && (await Agent.get(command.agent).then((x) => (x.model ? fmtModel(x.model) : undefined)))) ??
(await Provider.defaultModel().then((x) => `${x.providerID}/${x.modelID}`)) input.model ??
(input.agent && (await Agent.get(input.agent).then((x) => (x.model ? fmtModel(x.model) : undefined)))) ??
fmtModel(await Provider.defaultModel())
let template = command.template.replace("$ARGUMENTS", input.arguments) let template = command.template.replace("$ARGUMENTS", input.arguments)
const bash = Array.from(template.matchAll(bashRegex)) const bash = Array.from(template.matchAll(bashRegex))
@@ -1680,7 +1684,7 @@ export namespace Session {
const tokens = { const tokens = {
input: usage.inputTokens ?? 0, input: usage.inputTokens ?? 0,
output: usage.outputTokens ?? 0, output: usage.outputTokens ?? 0,
reasoning: 0, reasoning: usage?.reasoningTokens ?? 0,
cache: { cache: {
write: (metadata?.["anthropic"]?.["cacheCreationInputTokens"] ?? write: (metadata?.["anthropic"]?.["cacheCreationInputTokens"] ??
// @ts-expect-error // @ts-expect-error
+4 -4
View File
@@ -1,7 +1,7 @@
{ {
"$schema": "https://json.schemastore.org/package.json", "$schema": "https://json.schemastore.org/package.json",
"name": "@opencode-ai/plugin", "name": "@opencode-ai/plugin",
"version": "0.5.15", "version": "0.5.25",
"type": "module", "type": "module",
"scripts": { "scripts": {
"typecheck": "tsc --noEmit" "typecheck": "tsc --noEmit"
@@ -19,8 +19,8 @@
"@opencode-ai/sdk": "workspace:*" "@opencode-ai/sdk": "workspace:*"
}, },
"devDependencies": { "devDependencies": {
"typescript": "catalog:", "@hey-api/openapi-ts": "0.81.0",
"@hey-api/openapi-ts": "0.80.1", "@tsconfig/node22": "catalog:",
"@tsconfig/node22": "catalog:" "typescript": "catalog:"
} }
} }
+5
View File
@@ -6,6 +6,11 @@
"module": "preserve", "module": "preserve",
"declaration": true, "declaration": true,
"moduleResolution": "bundler", "moduleResolution": "bundler",
"lib": [
"es2022",
"dom",
"dom.iterable"
],
"customConditions": [ "customConditions": [
"development" "development"
] ]
+2 -2
View File
@@ -1,4 +1,4 @@
configured_endpoints: 41 configured_endpoints: 41
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/opencode%2Fopencode-d5200eaa145f567a58daa78941ab1141dd63f5f0cfe1596d5c9ecf12d34fea35.yml openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/opencode%2Fopencode-6d8e9dfd438cac63fc7d689ea29adfff81ff8880c2d8e1e10fc36f375a721594.yml
openapi_spec_hash: abeb66291dc158f2cdc90bf9945e283e openapi_spec_hash: 7ac6028dd5957c67a98d91e790863c80
config_hash: fb625e876313a9f8f31532348fa91f59 config_hash: fb625e876313a9f8f31532348fa91f59
+1
View File
@@ -41,6 +41,7 @@ func (r *EventService) ListStreaming(ctx context.Context, opts ...option.Request
err error err error
) )
opts = append(r.Options[:], opts...) opts = append(r.Options[:], opts...)
opts = append([]option.RequestOption{option.WithHeader("Accept", "text/event-stream")}, opts...)
path := "event" path := "event"
err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, nil, &raw, opts...) err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, nil, &raw, opts...)
return ssestream.NewStream[EventListResponse](ssestream.NewDecoder(raw), err) return ssestream.NewStream[EventListResponse](ssestream.NewDecoder(raw), err)
+4 -1
View File
@@ -1,7 +1,7 @@
{ {
"$schema": "https://json.schemastore.org/package.json", "$schema": "https://json.schemastore.org/package.json",
"name": "@opencode-ai/sdk", "name": "@opencode-ai/sdk",
"version": "0.5.15", "version": "0.5.25",
"type": "module", "type": "module",
"scripts": { "scripts": {
"typecheck": "tsc --noEmit" "typecheck": "tsc --noEmit"
@@ -27,5 +27,8 @@
"typescript": "catalog:", "typescript": "catalog:",
"@hey-api/openapi-ts": "0.80.1", "@hey-api/openapi-ts": "0.80.1",
"@tsconfig/node22": "catalog:" "@tsconfig/node22": "catalog:"
},
"dependencies": {
"@hey-api/openapi-ts": "0.80.1"
} }
} }
+1 -1
View File
@@ -17,7 +17,7 @@ export async function createOpencodeServer(config?: ServerConfig) {
config ?? {}, config ?? {},
) )
const proc = spawn(`opencode`, [`servel`, `--hostname=${config.hostname}`, `--port=${config.port}`], { const proc = spawn(`opencode`, [`serve`, `--hostname=${config.hostname}`, `--port=${config.port}`], {
signal: config.signal, signal: config.signal,
}) })
+2
View File
@@ -820,6 +820,8 @@ func (a *App) SendCommand(ctx context.Context, command string, args string) (*Ap
opencode.SessionCommandParams{ opencode.SessionCommandParams{
Command: opencode.F(command), Command: opencode.F(command),
Arguments: opencode.F(args), Arguments: opencode.F(args),
Agent: opencode.F(a.Agents[a.AgentIndex].Name),
Model: opencode.F(a.State.Provider + "/" + a.State.Model),
}, },
) )
if err != nil { if err != nil {
@@ -92,6 +92,12 @@ func (r CommandRegistry) Sorted() []Command {
if b.Name == AppExitCommand { if b.Name == AppExitCommand {
return -1 return -1
} }
if a.Custom && !b.Custom {
return 1
}
if !a.Custom && b.Custom {
return -1
}
return strings.Compare(string(a.Name), string(b.Name)) return strings.Compare(string(a.Name), string(b.Name))
}) })
+14 -5
View File
@@ -915,9 +915,10 @@ func (a Model) Cleanup() {
func (a Model) home() (string, int, int) { func (a Model) home() (string, int, int) {
t := theme.CurrentTheme() t := theme.CurrentTheme()
effectiveWidth := a.width - 4 effectiveWidth := a.width - 4
baseStyle := styles.NewStyle().Background(t.Background()) baseStyle := styles.NewStyle().Foreground(t.Text()).Background(t.Background())
base := baseStyle.Render base := baseStyle.Render
muted := styles.NewStyle().Foreground(t.TextMuted()).Background(t.Background()).Render muted := styles.NewStyle().Foreground(t.TextMuted()).Background(t.Background()).Render
highlight := styles.NewStyle().Foreground(t.Accent()).Background(t.Background()).Render
open := ` open := `
@@ -952,9 +953,9 @@ func (a Model) home() (string, int, int) {
) )
// Use limit of 4 for vscode, 6 for others // Use limit of 4 for vscode, 6 for others
limit := 6 limit := 4
if util.IsVSCode() { if util.IsVSCode() {
limit = 4 limit = 2
} }
showVscode := util.IsVSCode() showVscode := util.IsVSCode()
@@ -971,15 +972,23 @@ func (a Model) home() (string, int, int) {
styles.WhitespaceStyle(t.Background()), styles.WhitespaceStyle(t.Background()),
) )
grok := highlight("Try Grok Code free for a limited time")
grok = lipgloss.PlaceHorizontal(
effectiveWidth,
lipgloss.Center,
grok,
styles.WhitespaceStyle(t.Background()),
)
lines := []string{} lines := []string{}
lines = append(lines, "") lines = append(lines, "")
lines = append(lines, "")
lines = append(lines, logoAndVersion) lines = append(lines, logoAndVersion)
lines = append(lines, "") lines = append(lines, "")
lines = append(lines, "")
lines = append(lines, cmds) lines = append(lines, cmds)
lines = append(lines, "") lines = append(lines, "")
lines = append(lines, "") lines = append(lines, "")
lines = append(lines, grok)
lines = append(lines, "")
mainHeight := lipgloss.Height(strings.Join(lines, "\n")) mainHeight := lipgloss.Height(strings.Join(lines, "\n"))
+1
View File
@@ -78,6 +78,7 @@ export default defineConfig({
"docs/models", "docs/models",
"docs/themes", "docs/themes",
"docs/keybinds", "docs/keybinds",
"docs/commands",
"docs/formatters", "docs/formatters",
"docs/permissions", "docs/permissions",
"docs/lsp", "docs/lsp",
+2 -2
View File
@@ -1,7 +1,7 @@
{ {
"name": "@opencode/web", "name": "@opencode/web",
"type": "module", "type": "module",
"version": "0.5.15", "version": "0.5.25",
"scripts": { "scripts": {
"dev": "astro dev", "dev": "astro dev",
"dev:remote": "sst shell --stage=dev --target=Web astro dev", "dev:remote": "sst shell --stage=dev --target=Web astro dev",
@@ -31,7 +31,7 @@
"sharp": "0.32.5", "sharp": "0.32.5",
"shiki": "3.4.2", "shiki": "3.4.2",
"solid-js": "1.9.7", "solid-js": "1.9.7",
"toolbeam-docs-theme": "0.4.5" "toolbeam-docs-theme": "0.4.6"
}, },
"devDependencies": { "devDependencies": {
"opencode": "workspace:*", "opencode": "workspace:*",
@@ -58,12 +58,11 @@ Build is the **default** primary agent with all tools enabled. This is the stand
_Mode_: `primary` _Mode_: `primary`
A restricted agent designed for planning and analysis. In the plan agent, the following tools are disabled by default: A restricted agent designed for planning and analysis. We use a permission system to give you more control and prevent unintended changes.
By default, all of the following are set to `ask`:
- `write` - Cannot create new files - `file edits`: All writes, patches, and edits
- `edit` - Cannot modify existing files - `bash`: All bash commands
- `patch` - Cannot apply patches
- `bash` - Cannot execute shell commands
This agent is useful when you want the LLM to analyze code, suggest changes, or create plans without making any actual modifications to your codebase. This agent is useful when you want the LLM to analyze code, suggest changes, or create plans without making any actual modifications to your codebase.
+19 -30
View File
@@ -13,7 +13,7 @@ Create markdown files in the `command/` directory to define custom commands.
Create `.opencode/command/test.md`: Create `.opencode/command/test.md`:
```md ```md title=".opencode/command/test.md"
--- ---
description: Run tests with coverage description: Run tests with coverage
agent: build agent: build
@@ -34,32 +34,13 @@ Use the command by typing `/` followed by the command name.
--- ---
## Create command files
For complex commands, create markdown files in the `command/` directory.
Create `.opencode/command/test.md`:
```md
---
description: Run tests with coverage
agent: build
model: anthropic/claude-3-5-sonnet-20241022
---
Run the full test suite with coverage report and show any failures.
Focus on the failing tests and suggest fixes.
```
The frontmatter defines command properties. The content becomes the template.
---
## Use arguments ## Use arguments
Pass arguments to commands using the `$ARGUMENTS` placeholder. Pass arguments to commands using the `$ARGUMENTS` placeholder.
```md Create `.opencode/command/component.md`:
```md title=".opencode/command/component.md"
--- ---
description: Create a new component description: Create a new component
--- ---
@@ -78,26 +59,30 @@ Run the command with arguments:
## Inject shell output ## Inject shell output
Use `!`command`` to inject shell command output into your prompt. Use !`command` to inject shell command output into your prompt.
```md Create `.opencode/command/analyze-coverage.md`:
```md title=".opencode/command/analyze-coverage.md"
--- ---
description: Analyze test coverage description: Analyze test coverage
--- ---
Here are the current test results: Here are the current test results:
`!npm test` !`npm test`
Based on these results, suggest improvements to increase coverage. Based on these results, suggest improvements to increase coverage.
``` ```
```md Create `.opencode/command/review-changes.md`:
```md title=".opencode/command/review-changes.md"
--- ---
description: Review recent changes description: Review recent changes
--- ---
Recent git commits: Recent git commits:
`!git log --oneline -10` !`git log --oneline -10`
Review these changes and suggest any improvements. Review these changes and suggest any improvements.
``` ```
@@ -110,7 +95,9 @@ Commands run in your project's root directory and their output becomes part of t
Include files in your command using `@` followed by the filename. Include files in your command using `@` followed by the filename.
```md Create `.opencode/command/review-component.md`:
```md title=".opencode/command/review-component.md"
--- ---
description: Review component description: Review component
--- ---
@@ -131,7 +118,9 @@ Configure commands with these optional frontmatter properties:
- **agent**: Agent to use (defaults to "build") - **agent**: Agent to use (defaults to "build")
- **model**: Specific model to use for this command - **model**: Specific model to use for this command
```md Create `.opencode/command/code-review.md`:
```md title=".opencode/command/code-review.md"
--- ---
description: Code review assistant description: Code review assistant
agent: build agent: build
@@ -9,7 +9,7 @@ you to use opencode at your organization.
To get started, we recommend: To get started, we recommend:
1. Do a trial internally with your team. 1. Do a trial internally with your team.
2. [**Contact us**](mailto:hello@sst.dev) to discuss pricing and implementation options. 2. [**Contact us**](mailto:hello@anoma.ly) to discuss pricing and implementation options.
--- ---
@@ -55,7 +55,7 @@ We recommend you disable this for your trial.
## Deployment ## Deployment
Once you have completed your trial and you are ready to self-host opencode at Once you have completed your trial and you are ready to self-host opencode at
your organization, you can [**contact us**](mailto:hello@sst.dev) to discuss your organization, you can [**contact us**](mailto:hello@anoma.ly) to discuss
pricing and implementation options. pricing and implementation options.
--- ---
+20 -4
View File
@@ -41,10 +41,26 @@ You can also install it with the following:
- **Using Node.js** - **Using Node.js**
<Tabs> <Tabs>
<TabItem label="npm">```bash npm install -g opencode-ai ```</TabItem> <TabItem label="npm">
<TabItem label="Bun">```bash bun install -g opencode-ai ```</TabItem> ```bash
<TabItem label="pnpm">```bash pnpm install -g opencode-ai ```</TabItem> npm install -g opencode-ai
<TabItem label="Yarn">```bash yarn global add opencode-ai ```</TabItem> ```
</TabItem>
<TabItem label="Bun">
```bash
bun install -g opencode-ai
```
</TabItem>
<TabItem label="pnpm">
```bash
pnpm install -g opencode-ai
```
</TabItem>
<TabItem label="Yarn">
```bash
yarn global add opencode-ai
```
</TabItem>
</Tabs> </Tabs>
- **Using Homebrew on macOS and Linux** - **Using Homebrew on macOS and Linux**
+17 -10
View File
@@ -11,19 +11,26 @@ opencode integrates with your Language Server Protocol (LSP) to help the LLM int
opencode comes with several built-in LSP servers for popular languages: opencode comes with several built-in LSP servers for popular languages:
| LSP Server | Extensions | Requirements | | LSP Server | Extensions | Requirements |
| ---------- | -------------------------------------------- | ----------------------------------- | | ---------- | ---------------------------------------------------- | ----------------------------------- |
| typescript | .ts, .tsx, .js, .jsx, .mjs, .cjs, .mts, .cts | `typescript` dependency in project | | typescript | .ts, .tsx, .js, .jsx, .mjs, .cjs, .mts, .cts | `typescript` dependency in project |
| eslint | .ts, .tsx, .js, .jsx, .mjs, .cjs, .mts, .cts | `eslint` dependency in project | | eslint | .ts, .tsx, .js, .jsx, .mjs, .cjs, .mts, .cts, .vue | `eslint` dependency in project |
| gopls | .go | `go` command available | | gopls | .go | `go` command available |
| ruby-lsp | .rb, .rake, .gemspec, .ru | `ruby` and `gem` commands available | | ruby-lsp | .rb, .rake, .gemspec, .ru | `ruby` and `gem` commands available |
| pyright | .py, .pyi | `pyright` dependency installed | | pyright | .py, .pyi | `pyright` dependency installed |
| elixir-ls | .ex, .exs | `elixir` command available | | elixir-ls | .ex, .exs | `elixir` command available |
| zls | .zig, .zon | `zig` command available | | zls | .zig, .zon | `zig` command available |
| csharp | .cs | `.NET SDK` installed | | csharp | .cs | `.NET SDK` installed |
| vue | .vue | Auto-installs for Vue projects |
| rust | .rs | `rust-analyzer` command available |
| clangd | .c, .cpp, .cc, .cxx, .c++, .h, .hpp, .hh, .hxx, .h++ | Auto-installs for C/C++ projects |
LSP servers are automatically enabled when one of the above file extensions are detected and the requirements are met. LSP servers are automatically enabled when one of the above file extensions are detected and the requirements are met.
:::note
You can disable automatic LSP server downloads by setting the `OPENCODE_DISABLE_LSP_DOWNLOAD` environment variable to `true`.
:::
--- ---
## How It Works ## How It Works
+24 -9
View File
@@ -254,37 +254,52 @@ Both the `/editor` and `/export` commands use the editor specified in your `EDIT
<Tabs> <Tabs>
<TabItem label="Linux/macOS"> <TabItem label="Linux/macOS">
```bash ```bash
export EDITOR=nano # or vim, code, etc. # Example for nano or vim
export EDITOR=nano
export EDITOR=vim
# For GUI editors (VS Code, Cursor, VSCodium, Windsurf, Zed, etc.) include --wait
export EDITOR="code --wait"
``` ```
To make it permanent, add this to your shell profile; To make it permanent, add this to your shell profile;
`~/.bashrc`, `~/.zshrc`, etc. `~/.bashrc`, `~/.zshrc`, etc.
</TabItem> </TabItem>
<TabItem label="Windows (CMD)"> <TabItem label="Windows (CMD)">
```bash ```bash
set EDITOR=notepad # or code, vim, etc. set EDITOR=notepad
# For GUI editors (VS Code, Cursor, VSCodium, Windsurf, Zed, etc.) include --wait
set EDITOR=code --wait
``` ```
To make it permanent, use **System Properties** > **Environment To make it permanent, use **System Properties** > **Environment
Variables**. Variables**.
</TabItem> </TabItem>
<TabItem label="Windows (PowerShell)"> <TabItem label="Windows (PowerShell)">
```bash ```powershell
$env:EDITOR = "notepad" # or "code", "vim", etc. $env:EDITOR = "notepad"
# For GUI editors (VS Code, Cursor, VSCodium, Windsurf, Zed, etc.) include --wait
$env:EDITOR = "code --wait"
``` ```
To make it permanent, add this to your PowerShell To make it permanent, add this to your PowerShell profile.
profile.
</TabItem> </TabItem>
</Tabs> </Tabs>
Popular editor options include: Popular editor options include:
- `code` - Visual Studio Code - `code` - Visual Studio Code
- `cursor` - Cursor
- `windsurf` - Windsurf
- `vim` - Vim editor - `vim` - Vim editor
- `nano` - Nano editor - `nano` - Nano editor
- `notepad` - Windows Notepad - `notepad` - Windows Notepad
- `subl` - Sublime Text - `subl` - Sublime Text
:::tip
Some editors need command-line arguments to run in blocking mode. The --wait flag makes the editor process block until closed, which is necessary for opencode to function correctly.
:::
+1 -1
View File
@@ -2,7 +2,7 @@
"name": "opencode", "name": "opencode",
"displayName": "opencode", "displayName": "opencode",
"description": "opencode for VS Code", "description": "opencode for VS Code",
"version": "0.5.15", "version": "0.5.25",
"publisher": "sst-dev", "publisher": "sst-dev",
"repository": { "repository": {
"type": "git", "type": "git",