Skip to content

Commit 2c4ef78

Browse files
committed
Merge branch 'dev' into fix/server-error-reporting
2 parents 798c356 + b5a4439 commit 2c4ef78

File tree

45 files changed

+694
-1273
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+694
-1273
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,5 @@ node_modules
55
.env
66
.idea
77
.vscode
8+
app.log
9+
gopls.log

README.md

Lines changed: 51 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,24 @@
1-
[![OpenCode Terminal UI](screenshot.png)](https://github.com/sst/opencode)
1+
<p align="center">
2+
<a href="https://opencode.ai">
3+
<picture>
4+
<source srcset="packages/web/src/assets/logo-dark.svg" media="(prefers-color-scheme: dark)">
5+
<source srcset="packages/web/src/assets/logo-light.svg" media="(prefers-color-scheme: light)">
6+
<img src="packages/web/src/assets/logo-light.svg" alt="opencode logo">
7+
</picture>
8+
</a>
9+
</p>
10+
<p align="center">
11+
<a href="https://www.npmjs.com/package/opencode-ai"><img alt="npm" src="https://img.shields.io/npm/v/opencode-ai?style=flat-square" /></a>
12+
<a href="https://github.com/sst/opencode/actions/workflows/publish.yml"><img alt="Build status" src="https://img.shields.io/github/actions/workflow/status/sst/opencode/publish.yml?style=flat-square&branch=dev" /></a>
13+
</p>
14+
15+
---
216

317
AI coding agent, built for the terminal.
418

5-
⚠️ **Note:** version 0.1.x is a full rewrite, and we do not have proper documentation for it yet. Should have this out week of June 17th 2025 📚
19+
**Note:** Version 0.1.x is a full rewrite, and we do not have proper documentation for it yet. Should have this out week of June 17th 2025.
20+
21+
[![opencode Terminal UI](screenshot.png)](https://opencode.ai)
622

723
### Installation
824

@@ -16,13 +32,13 @@ brew install sst/tap/opencode # macOS
1632
paru -S opencode-bin # Arch Linux
1733
```
1834

19-
> **Note:** Remove previous versions < 0.1.x first if installed
35+
> **Note:** Remove versions older than 0.1.x before installing
2036
2137
### Providers
2238

23-
The recommended approach is to sign up for claude pro or max and do `opencode auth login` and select Anthropic. It is the most cost-effective way to use this tool.
39+
The recommended approach is to sign up for Claude Pro or Max, run `opencode auth login`, and select Anthropic. It's the most cost-effective way to use opencode.
2440

25-
Additionally, opencode is powered by the provider list at [models.dev](https://models.dev) so you can use `opencode auth login` to configure api keys for any provider you'd like to use. This is stored in `~/.local/share/opencode/auth.json`
41+
opencode is powered by the provider list at [Models.dev](https://models.dev), so you can use `opencode auth login` to configure API keys for any provider you'd like to use. This is stored in `~/.local/share/opencode/auth.json`.
2642

2743
```bash
2844
$ opencode auth login
@@ -41,13 +57,13 @@ $ opencode auth login
4157
4258
```
4359

44-
The models.dev dataset is also used to detect common environment variables like `OPENAI_API_KEY` to autoload that provider.
60+
The Models.dev dataset is also used to detect common environment variables like `OPENAI_API_KEY` to autoload that provider.
4561

46-
If there are additional providers you want to use you can submit a PR to the [models.dev repo](https://github.com/sst/models.dev). If configuring just for yourself check out the Config section below
62+
If there are additional providers you want to use you can submit a PR to the [Models.dev repo](https://github.com/sst/models.dev). If configuring just for yourself check out the Config section below.
4763

4864
### Project Config
4965

50-
Project configuration is optional. You can place an `opencode.json` file in the root of your repo, and it will be loaded.
66+
Project configuration is optional. You can place an `opencode.json` file in the root of your repo, and it'll be loaded.
5167

5268
```json title="opencode.json"
5369
{
@@ -78,14 +94,14 @@ Project configuration is optional. You can place an `opencode.json` file in the
7894

7995
#### Providers
8096

81-
You can use opencode with any provider listed at [here](https://ai-sdk.dev/providers/ai-sdk-providers). Use the npm package name as the key in your config. Note we use v5 of the ai-sdk and not all providers support that yet.
97+
You can use opencode with any provider listed at [here](https://ai-sdk.dev/providers/ai-sdk-providers). Be sure to specify the npm package to use to load the provider.
8298

8399
```json title="opencode.json"
84100
{
85101
"$schema": "https://opencode.ai/config.json",
86102
"provider": {
87-
"@ai-sdk/openai-compatible": {
88-
"name": "ollama",
103+
"ollama": {
104+
"npm": "@ai-sdk/openai-compatible",
89105
"options": {
90106
"baseURL": "http://localhost:11434/v1"
91107
},
@@ -101,30 +117,31 @@ You can use opencode with any provider listed at [here](https://ai-sdk.dev/provi
101117

102118
### Contributing
103119

104-
To run opencode locally you need
120+
To run opencode locally you need.
105121

106-
- bun
107-
- golang 1.24.x
122+
- Bun
123+
- Golang 1.24.x
108124

109-
To run
125+
To run.
110126

111-
```
127+
```bash
112128
$ bun install
113129
$ cd packages/opencode
114130
$ bun run src/index.ts
115131
```
116132

117133
### FAQ
118134

119-
#### How do I use this with OpenRouter
135+
#### How do I use this with OpenRouter?
120136

121-
OpenRouter is not yet in the models.dev database, but you can configure it manually.
137+
OpenRouter is not in the Models.dev database yet, but you can configure it manually.
122138

123139
```json title="opencode.json"
124140
{
125141
"$schema": "https://opencode.ai/config.json",
126142
"provider": {
127-
"@openrouter/ai-sdk-provider": {
143+
"openrouter": {
144+
"npm": "@openrouter/ai-sdk-provider",
128145
"name": "OpenRouter",
129146
"options": {
130147
"apiKey": "sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
@@ -139,15 +156,23 @@ OpenRouter is not yet in the models.dev database, but you can configure it manua
139156
}
140157
```
141158

142-
#### How is this different than claude code?
159+
#### How is this different than Claude Code?
143160

144-
It is very similar to claude code in terms of capability - here are the key differences:
161+
It's very similar to Claude Code in terms of capability. Here are the key differences:
145162

146163
- 100% open source
147-
- Not coupled to any provider. Although anthropic is recommended opencode can be used with openai, google or even local models. As models evolve the gaps between them will close and pricing will drop so being provider agnostic is important.
148-
- TUI focus - opencode is built by neovim users and the creators of https://terminal.shop - we are going to push the limits of what's possible in the terminal
149-
- client/server architecture - this means the tui frontend is just the first of many. For example, opencode can run on your computer and you can drive it remotely from a mobile app
164+
- Not coupled to any provider. Although Anthropic is recommended, opencode can be used with OpenAI, Google or even local models. As models evolve the gaps between them will close and pricing will drop so being provider agnostic is important.
165+
- A focus on TUI. opencode is built by neovim users and the creators of [terminal.shop](https://terminal.shop); we are going to push the limits of what's possible in the terminal.
166+
- A client/server architecture. This for example can allow opencode to run on your computer, while you can drive it remotely from a mobile app. Meaning that the TUI frontend is just one of the possible clients.
167+
168+
#### What about Windows support?
169+
170+
There are some minor problems blocking opencode from working on windows. We are working on on them now. You'll need to use WSL for now.
171+
172+
#### What's the other repo?
173+
174+
The other confusingly named repo has no relation to this one. You can [read the story behind it here](https://x.com/thdxr/status/1933561254481666466).
150175

151-
#### Windows Support
176+
---
152177

153-
There are some minor problems blocking opencode from working on windows. We will fix them soon - would need to use wsl for now.
178+
**Join our community** [YouTube](https://www.youtube.com/c/sst-dev) | [X.com](https://x.com/SST_dev)

infra/app.ts

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -31,17 +31,6 @@ export const api = new sst.cloudflare.Worker("Api", {
3131
},
3232
})
3333

34-
// new sst.cloudflare.StaticSite("Web", {
35-
// path: "packages/web",
36-
// domain,
37-
// environment: {
38-
// VITE_API_URL: api.url,
39-
// },
40-
// build: {
41-
// command: "bun run build",
42-
// output: "dist",
43-
// },
44-
// })
4534
new sst.cloudflare.x.Astro("Web", {
4635
domain,
4736
path: "packages/web",

opencode.json

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,5 @@
11
{
22
"$schema": "https://opencode.ai/config.json",
3-
"provider": {
4-
"@ai-sdk/openai-compatible": {
5-
"name": "ollama",
6-
"options": {
7-
"baseURL": "http://localhost:11434/v1"
8-
},
9-
"models": {
10-
"qwen3": {},
11-
"deepseek-r1": {},
12-
"llama2": {}
13-
}
14-
}
15-
}
3+
"mcp": {},
4+
"provider": {}
165
}

packages/opencode/AGENTS.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,14 @@
1919

2020
## IMPORTANT
2121

22-
- Try to keep things in one function unless composable or reusablte
22+
- Try to keep things in one function unless composable or reusable
2323
- DO NOT do unnecessary destructuring of variables
24-
- DO NOT use else statements unless necessary
25-
- DO NOT use try catch if it can be avoided
26-
- AVOID try catch where possible
27-
- AVOID else statements
24+
- DO NOT use `else` statements unless necessary
25+
- DO NOT use `try`/`catch` if it can be avoided
26+
- AVOID `try`/`catch` where possible
27+
- AVOID `else` statements
2828
- AVOID using `any` type
29-
- AVOID let statements
29+
- AVOID `let` statements
3030
- PREFER single word variable names where possible
3131
- Use as many bun apis as possible like Bun.file()
3232

packages/opencode/config.schema.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@
2121
"id": {
2222
"type": "string"
2323
},
24+
"npm": {
25+
"type": "string"
26+
},
2427
"models": {
2528
"type": "object",
2629
"additionalProperties": {

packages/opencode/script/publish.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ const targets = [
2929
["linux", "x64"],
3030
["darwin", "x64"],
3131
["darwin", "arm64"],
32-
["windows", "x64"],
32+
// ["windows", "x64"],
3333
]
3434

3535
await $`rm -rf dist`

packages/opencode/src/auth/anthropic.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { generatePKCE } from "@openauthjs/openauth/pkce"
2-
import fs from "fs/promises"
32
import { Auth } from "./index"
43

54
export namespace AuthAnthropic {

packages/opencode/src/bun/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ export namespace BunProc {
4343
version: z.string(),
4444
}),
4545
)
46+
4647
export async function install(pkg: string, version = "latest") {
4748
const mod = path.join(Global.Path.cache, "node_modules", pkg)
4849
const pkgjson = Bun.file(path.join(Global.Path.cache, "package.json"))

packages/opencode/src/cli/cmd/auth.ts

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import * as prompts from "@clack/prompts"
55
import open from "open"
66
import { UI } from "../ui"
77
import { ModelsDev } from "../../provider/models"
8-
import { map, pipe, sort, sortBy, values } from "remeda"
8+
import { map, pipe, sortBy, values } from "remeda"
99

1010
export const AuthCommand = cmd({
1111
command: "auth",
@@ -16,7 +16,7 @@ export const AuthCommand = cmd({
1616
.command(AuthLogoutCommand)
1717
.command(AuthListCommand)
1818
.demandCommand(),
19-
async handler(args) {},
19+
async handler() {},
2020
})
2121

2222
export const AuthListCommand = cmd({
@@ -78,9 +78,16 @@ export const AuthLoginCommand = cmd({
7878

7979
if (provider === "other") {
8080
provider = await prompts.text({
81-
message: "Enter provider - must match @ai-sdk/<provider>",
81+
message: "Enter provider id",
82+
validate: (x) =>
83+
x.match(/^[a-z-]+$/) ? undefined : "a-z and hyphens only",
8284
})
8385
if (prompts.isCancel(provider)) throw new UI.CancelledError()
86+
provider = provider.replace(/^@ai-sdk\//, "")
87+
if (prompts.isCancel(provider)) throw new UI.CancelledError()
88+
prompts.log.warn(
89+
`This only stores a credential for ${provider} - you will need configure it in opencode.json, check the docs for examples.`,
90+
)
8491
}
8592

8693
if (provider === "amazon-bedrock") {
@@ -115,7 +122,9 @@ export const AuthLoginCommand = cmd({
115122
try {
116123
await open(url)
117124
} catch (e) {
118-
prompts.log.error("Failed to open browser perhaps you are running without a display or X server, please open the following URL in your browser:")
125+
prompts.log.error(
126+
"Failed to open browser perhaps you are running without a display or X server, please open the following URL in your browser:",
127+
)
119128
}
120129
prompts.log.info(url)
121130

packages/opencode/src/cli/cmd/run.ts

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,9 @@ import { Share } from "../../share/share"
77
import { Message } from "../../session/message"
88
import { UI } from "../ui"
99
import { VERSION } from "../version"
10-
11-
const COLOR = [
12-
UI.Style.TEXT_SUCCESS_BOLD,
13-
UI.Style.TEXT_INFO_BOLD,
14-
UI.Style.TEXT_HIGHLIGHT_BOLD,
15-
UI.Style.TEXT_WARNING_BOLD,
16-
]
10+
import { cmd } from "./cmd"
11+
import { GlobalConfig } from "../../global/config"
12+
import { Flag } from "../../flag/flag"
1713

1814
const TOOL: Record<string, [string, string]> = {
1915
opencode_todowrite: ["Todo", UI.Style.TEXT_WARNING_BOLD],
@@ -27,7 +23,7 @@ const TOOL: Record<string, [string, string]> = {
2723
opencode_write: ["Write", UI.Style.TEXT_SUCCESS_BOLD],
2824
}
2925

30-
export const RunCommand = {
26+
export const RunCommand = cmd({
3127
command: "run [message..]",
3228
describe: "Run OpenCode with a message",
3329
builder: (yargs: Argv) => {
@@ -42,12 +38,12 @@ export const RunCommand = {
4238
describe: "Session ID to continue",
4339
type: "string",
4440
})
41+
.option("share", {
42+
type: "boolean",
43+
describe: "Share the session",
44+
})
4545
},
46-
handler: async (args: {
47-
message: string[]
48-
session?: string
49-
printLogs?: boolean
50-
}) => {
46+
handler: async (args) => {
5147
const message = args.message.join(" ")
5248
await App.provide(
5349
{
@@ -60,14 +56,27 @@ export const RunCommand = {
6056
? await Session.get(args.session)
6157
: await Session.create()
6258

63-
UI.println(UI.Style.TEXT_HIGHLIGHT_BOLD + "◍ OpenCode", VERSION)
59+
UI.empty()
60+
UI.println(UI.logo())
6461
UI.empty()
6562
UI.println(UI.Style.TEXT_NORMAL_BOLD + "> ", message)
6663
UI.empty()
64+
65+
const cfg = await GlobalConfig.get()
66+
if (cfg.autoshare || Flag.OPENCODE_AUTO_SHARE || args.share) {
67+
await Session.share(session.id)
68+
UI.println(
69+
UI.Style.TEXT_INFO_BOLD +
70+
"~ https://dev.opencode.ai/s/" +
71+
session.id.slice(-8),
72+
)
73+
}
74+
UI.empty()
75+
76+
const { providerID, modelID } = await Provider.defaultModel()
6777
UI.println(
68-
UI.Style.TEXT_INFO_BOLD +
69-
"~ https://dev.opencode.ai/s/" +
70-
session.id.slice(-8),
78+
UI.Style.TEXT_NORMAL_BOLD + "@ ",
79+
UI.Style.TEXT_NORMAL + `${providerID}/${modelID}`,
7180
)
7281
UI.empty()
7382

@@ -113,8 +122,6 @@ export const RunCommand = {
113122
printEvent(UI.Style.TEXT_NORMAL_BOLD, "Text", part.text)
114123
}
115124
})
116-
117-
const { providerID, modelID } = await Provider.defaultModel()
118125
await Session.chat({
119126
sessionID: session.id,
120127
providerID,
@@ -130,4 +137,4 @@ export const RunCommand = {
130137
},
131138
)
132139
},
133-
}
140+
})

0 commit comments

Comments
 (0)