Compare commits

..

22 Commits

Author SHA1 Message Date
opencode a071a2b7f4 release: v0.4.27 2025-08-12 12:58:53 +00:00
adamdotdevin b2f2c9ac37 fix: use real cursor instead of virtual cursor 2025-08-12 07:52:19 -05:00
GitHub Action 631722213b ignore: update download stats 2025-08-12 2025-08-12 12:04:42 +00:00
Camden Clark 80b25c79bb fix: preserve process.env when spawning formatter commands (#1850) 2025-08-12 02:05:26 -04:00
Dax 3d9c5b4adf Update guidelines-check.yml 2025-08-12 00:34:34 -04:00
Dax a3064e2c32 Update duplicate-issues.yml 2025-08-12 00:34:16 -04:00
Dax Raad 275bc4d2c8 ci: add guidelines check workflow for PRs 2025-08-12 00:01:59 -04:00
Dax Raad 39106718ed ci: tweak 2025-08-11 23:52:16 -04:00
Dax Raad 02cfdfbf5b ci: add duplicate issue detection workflow 2025-08-11 23:51:08 -04:00
Dax Raad 1ec71e419b support wildcard matching tool names in config 2025-08-11 23:37:09 -04:00
opencode 5fbbdcaf64 release: v0.4.26 2025-08-12 03:25:36 +00:00
Dax Raad 2b6afe90d0 fix azure reasoningEffort 2025-08-11 23:20:19 -04:00
Dax Raad 5f34dcc792 azure reasoning effort 2025-08-11 23:04:32 -04:00
opencode 681abcbf2d release: v0.4.25 2025-08-12 02:51:32 +00:00
Dax Raad 603e81ef5a Simplify git-committer agent definition for better maintainability 2025-08-11 22:45:40 -04:00
Dax Raad fb0a200ecf refactor: replace OPENCODE_AGENTS env var with HTTP API call
Replace environment variable passing of agent data from Node.js to TUI
with proper HTTP API call to /agent endpoint. This improves architecture
by eliminating env var dependencies and allows dynamic agent data fetching.
2025-08-11 22:42:25 -04:00
opencode 3ec670784d release: v0.4.24 2025-08-12 02:33:35 +00:00
Dax Raad e6f3cf0839 fix pyright 2025-08-11 22:27:24 -04:00
opencode 9437cf4ff6 release: v0.4.23 2025-08-12 02:04:53 +00:00
Dax Raad 7d095d19f6 fix undo/redo when opencode is run in nested folders 2025-08-11 21:59:12 -04:00
Dax Raad 0ca10ec2f5 ignore: log 2025-08-11 21:52:05 -04:00
Dax Raad f03fae03e5 switch back to didUpdate instead of closing and opening file 2025-08-11 21:36:05 -04:00
28 changed files with 199 additions and 98 deletions
+1
View File
@@ -6,3 +6,4 @@ node_modules
.vscode
openapi.json
playground
tmp
+10
View File
@@ -0,0 +1,10 @@
---
description: Use this agent when you are saked to commit and push code changes to a git repository.
mode: subagent
---
You commit and push to git
Commit messages should be brief since they are used to generate release notes.
Messages should say WHY the change was made and not WHAT was changed.
+46 -45
View File
@@ -1,47 +1,48 @@
# Download Stats
| Date | GitHub Downloads | npm Downloads | Total |
| ---------- | ---------------- | ---------------- | ---------------- |
| 2025-06-29 | 18,789 (+0) | 39,420 (+0) | 58,209 (+0) |
| 2025-06-30 | 20,127 (+1,338) | 41,059 (+1,639) | 61,186 (+2,977) |
| 2025-07-01 | 22,108 (+1,981) | 43,745 (+2,686) | 65,853 (+4,667) |
| 2025-07-02 | 24,814 (+2,706) | 46,168 (+2,423) | 70,982 (+5,129) |
| 2025-07-03 | 27,834 (+3,020) | 49,955 (+3,787) | 77,789 (+6,807) |
| 2025-07-04 | 30,608 (+2,774) | 54,758 (+4,803) | 85,366 (+7,577) |
| 2025-07-05 | 32,524 (+1,916) | 58,371 (+3,613) | 90,895 (+5,529) |
| 2025-07-06 | 33,766 (+1,242) | 59,694 (+1,323) | 93,460 (+2,565) |
| 2025-07-08 | 38,052 (+4,286) | 64,468 (+4,774) | 102,520 (+9,060) |
| 2025-07-09 | 40,924 (+2,872) | 67,935 (+3,467) | 108,859 (+6,339) |
| 2025-07-10 | 43,796 (+2,872) | 71,402 (+3,467) | 115,198 (+6,339) |
| 2025-07-11 | 46,982 (+3,186) | 77,462 (+6,060) | 124,444 (+9,246) |
| 2025-07-12 | 49,302 (+2,320) | 82,177 (+4,715) | 131,479 (+7,035) |
| 2025-07-13 | 50,803 (+1,501) | 86,394 (+4,217) | 137,197 (+5,718) |
| 2025-07-14 | 53,283 (+2,480) | 87,860 (+1,466) | 141,143 (+3,946) |
| 2025-07-15 | 57,590 (+4,307) | 91,036 (+3,176) | 148,626 (+7,483) |
| 2025-07-16 | 62,313 (+4,723) | 95,258 (+4,222) | 157,571 (+8,945) |
| 2025-07-17 | 66,684 (+4,371) | 100,048 (+4,790) | 166,732 (+9,161) |
| 2025-07-18 | 70,379 (+3,695) | 102,587 (+2,539) | 172,966 (+6,234) |
| 2025-07-19 | 73,497 (+3,117) | 105,904 (+3,317) | 179,401 (+6,434) |
| 2025-07-20 | 76,453 (+2,956) | 109,044 (+3,140) | 185,497 (+6,096) |
| 2025-07-21 | 80,197 (+3,744) | 113,537 (+4,493) | 193,734 (+8,237) |
| 2025-07-22 | 84,251 (+4,054) | 118,073 (+4,536) | 202,324 (+8,590) |
| 2025-07-23 | 88,589 (+4,338) | 121,436 (+3,363) | 210,025 (+7,701) |
| 2025-07-24 | 92,469 (+3,880) | 124,091 (+2,655) | 216,560 (+6,535) |
| 2025-07-25 | 96,417 (+3,948) | 126,985 (+2,894) | 223,402 (+6,842) |
| 2025-07-26 | 100,646 (+4,229) | 131,411 (+4,426) | 232,057 (+8,655) |
| 2025-07-27 | 102,644 (+1,998) | 134,736 (+3,325) | 237,380 (+5,323) |
| 2025-07-28 | 105,446 (+2,802) | 136,016 (+1,280) | 241,462 (+4,082) |
| 2025-07-29 | 108,998 (+3,552) | 137,542 (+1,526) | 246,540 (+5,078) |
| 2025-07-30 | 113,544 (+4,546) | 140,317 (+2,775) | 253,861 (+7,321) |
| 2025-07-31 | 118,339 (+4,795) | 143,344 (+3,027) | 261,683 (+7,822) |
| 2025-08-01 | 123,539 (+5,200) | 146,680 (+3,336) | 270,219 (+8,536) |
| 2025-08-02 | 127,864 (+4,325) | 149,236 (+2,556) | 277,100 (+6,881) |
| 2025-08-03 | 131,397 (+3,533) | 150,451 (+1,215) | 281,848 (+4,748) |
| 2025-08-04 | 136,266 (+4,869) | 153,260 (+2,809) | 289,526 (+7,678) |
| 2025-08-05 | 141,596 (+5,330) | 155,752 (+2,492) | 297,348 (+7,822) |
| 2025-08-06 | 147,067 (+5,471) | 158,309 (+2,557) | 305,376 (+8,028) |
| 2025-08-07 | 152,591 (+5,524) | 160,889 (+2,580) | 313,480 (+8,104) |
| 2025-08-08 | 158,187 (+5,596) | 163,448 (+2,559) | 321,635 (+8,155) |
| 2025-08-09 | 162,770 (+4,583) | 165,721 (+2,273) | 328,491 (+6,856) |
| 2025-08-10 | 165,695 (+2,925) | 167,109 (+1,388) | 332,804 (+4,313) |
| 2025-08-11 | 169,297 (+3,602) | 167,953 (+844) | 337,250 (+4,446) |
| Date | GitHub Downloads | npm Downloads | Total |
| ---------- | ---------------- | ---------------- | ----------------- |
| 2025-06-29 | 18,789 (+0) | 39,420 (+0) | 58,209 (+0) |
| 2025-06-30 | 20,127 (+1,338) | 41,059 (+1,639) | 61,186 (+2,977) |
| 2025-07-01 | 22,108 (+1,981) | 43,745 (+2,686) | 65,853 (+4,667) |
| 2025-07-02 | 24,814 (+2,706) | 46,168 (+2,423) | 70,982 (+5,129) |
| 2025-07-03 | 27,834 (+3,020) | 49,955 (+3,787) | 77,789 (+6,807) |
| 2025-07-04 | 30,608 (+2,774) | 54,758 (+4,803) | 85,366 (+7,577) |
| 2025-07-05 | 32,524 (+1,916) | 58,371 (+3,613) | 90,895 (+5,529) |
| 2025-07-06 | 33,766 (+1,242) | 59,694 (+1,323) | 93,460 (+2,565) |
| 2025-07-08 | 38,052 (+4,286) | 64,468 (+4,774) | 102,520 (+9,060) |
| 2025-07-09 | 40,924 (+2,872) | 67,935 (+3,467) | 108,859 (+6,339) |
| 2025-07-10 | 43,796 (+2,872) | 71,402 (+3,467) | 115,198 (+6,339) |
| 2025-07-11 | 46,982 (+3,186) | 77,462 (+6,060) | 124,444 (+9,246) |
| 2025-07-12 | 49,302 (+2,320) | 82,177 (+4,715) | 131,479 (+7,035) |
| 2025-07-13 | 50,803 (+1,501) | 86,394 (+4,217) | 137,197 (+5,718) |
| 2025-07-14 | 53,283 (+2,480) | 87,860 (+1,466) | 141,143 (+3,946) |
| 2025-07-15 | 57,590 (+4,307) | 91,036 (+3,176) | 148,626 (+7,483) |
| 2025-07-16 | 62,313 (+4,723) | 95,258 (+4,222) | 157,571 (+8,945) |
| 2025-07-17 | 66,684 (+4,371) | 100,048 (+4,790) | 166,732 (+9,161) |
| 2025-07-18 | 70,379 (+3,695) | 102,587 (+2,539) | 172,966 (+6,234) |
| 2025-07-19 | 73,497 (+3,117) | 105,904 (+3,317) | 179,401 (+6,434) |
| 2025-07-20 | 76,453 (+2,956) | 109,044 (+3,140) | 185,497 (+6,096) |
| 2025-07-21 | 80,197 (+3,744) | 113,537 (+4,493) | 193,734 (+8,237) |
| 2025-07-22 | 84,251 (+4,054) | 118,073 (+4,536) | 202,324 (+8,590) |
| 2025-07-23 | 88,589 (+4,338) | 121,436 (+3,363) | 210,025 (+7,701) |
| 2025-07-24 | 92,469 (+3,880) | 124,091 (+2,655) | 216,560 (+6,535) |
| 2025-07-25 | 96,417 (+3,948) | 126,985 (+2,894) | 223,402 (+6,842) |
| 2025-07-26 | 100,646 (+4,229) | 131,411 (+4,426) | 232,057 (+8,655) |
| 2025-07-27 | 102,644 (+1,998) | 134,736 (+3,325) | 237,380 (+5,323) |
| 2025-07-28 | 105,446 (+2,802) | 136,016 (+1,280) | 241,462 (+4,082) |
| 2025-07-29 | 108,998 (+3,552) | 137,542 (+1,526) | 246,540 (+5,078) |
| 2025-07-30 | 113,544 (+4,546) | 140,317 (+2,775) | 253,861 (+7,321) |
| 2025-07-31 | 118,339 (+4,795) | 143,344 (+3,027) | 261,683 (+7,822) |
| 2025-08-01 | 123,539 (+5,200) | 146,680 (+3,336) | 270,219 (+8,536) |
| 2025-08-02 | 127,864 (+4,325) | 149,236 (+2,556) | 277,100 (+6,881) |
| 2025-08-03 | 131,397 (+3,533) | 150,451 (+1,215) | 281,848 (+4,748) |
| 2025-08-04 | 136,266 (+4,869) | 153,260 (+2,809) | 289,526 (+7,678) |
| 2025-08-05 | 141,596 (+5,330) | 155,752 (+2,492) | 297,348 (+7,822) |
| 2025-08-06 | 147,067 (+5,471) | 158,309 (+2,557) | 305,376 (+8,028) |
| 2025-08-07 | 152,591 (+5,524) | 160,889 (+2,580) | 313,480 (+8,104) |
| 2025-08-08 | 158,187 (+5,596) | 163,448 (+2,559) | 321,635 (+8,155) |
| 2025-08-09 | 162,770 (+4,583) | 165,721 (+2,273) | 328,491 (+6,856) |
| 2025-08-10 | 165,695 (+2,925) | 167,109 (+1,388) | 332,804 (+4,313) |
| 2025-08-11 | 169,297 (+3,602) | 167,953 (+844) | 337,250 (+4,446) |
| 2025-08-12 | 176,307 (+7,010) | 171,876 (+3,923) | 348,183 (+10,933) |
+1 -1
View File
@@ -1,7 +1,7 @@
{
"$schema": "https://json.schemastore.org/package.json",
"name": "@opencode/cloud-core",
"version": "0.4.22",
"version": "0.4.27",
"private": true,
"type": "module",
"dependencies": {
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@opencode/cloud-function",
"version": "0.4.22",
"version": "0.4.27",
"$schema": "https://json.schemastore.org/package.json",
"private": true,
"type": "module",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@opencode/cloud-web",
"version": "0.4.22",
"version": "0.4.27",
"private": true,
"description": "",
"type": "module",
+3
View File
@@ -1,5 +1,8 @@
{
"$schema": "https://opencode.ai/config.json",
"agent": {
"build": {}
},
"mcp": {
"context7": {
"type": "remote",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@opencode/function",
"version": "0.4.22",
"version": "0.4.27",
"$schema": "https://json.schemastore.org/package.json",
"private": true,
"type": "module",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"$schema": "https://json.schemastore.org/package.json",
"version": "0.4.22",
"version": "0.4.27",
"name": "opencode",
"type": "module",
"private": true,
+1 -2
View File
@@ -12,7 +12,7 @@ import { Bus } from "../../bus"
import { Log } from "../../util/log"
import { FileWatcher } from "../../file/watch"
import { Ide } from "../../ide"
import { Agent } from "../../agent/agent"
import { Flag } from "../../flag/flag"
import { Session } from "../../session"
@@ -141,7 +141,6 @@ export const TuiCommand = cmd({
CGO_ENABLED: "0",
OPENCODE_SERVER: server.url.toString(),
OPENCODE_APP_INFO: JSON.stringify(app),
OPENCODE_AGENTS: JSON.stringify(await Agent.list()),
},
onExit: () => {
server.stop()
+1 -1
View File
@@ -71,7 +71,7 @@ export namespace Format {
const proc = Bun.spawn({
cmd: item.command.map((x) => x.replace("$FILE", file)),
cwd: App.info().path.cwd,
env: item.environment,
env: { ...process.env, ...item.environment },
stdout: "ignore",
stderr: "ignore",
})
+1 -1
View File
@@ -27,7 +27,7 @@ await Promise.all([
fs.mkdir(Global.Path.log, { recursive: true }),
])
const CACHE_VERSION = "6"
const CACHE_VERSION = "7"
const version = await Bun.file(path.join(Global.Path.cache, "version"))
.text()
+18 -11
View File
@@ -126,19 +126,26 @@ export namespace LSPClient {
input.path = path.isAbsolute(input.path) ? input.path : path.resolve(app.path.cwd, input.path)
const file = Bun.file(input.path)
const text = await file.text()
const version = files[input.path]
if (version !== undefined) {
diagnostics.delete(input.path)
await connection.sendNotification("textDocument/didClose", {
textDocument: {
uri: `file://` + input.path,
},
})
}
log.info("textDocument/didOpen", input)
diagnostics.delete(input.path)
const extension = path.extname(input.path)
const languageId = LANGUAGE_EXTENSIONS[extension] ?? "plaintext"
const version = files[input.path]
if (version !== undefined) {
const next = version + 1
files[input.path] = next
log.info("textDocument/didChange", { path: input.path, version: next })
await connection.sendNotification("textDocument/didChange", {
textDocument: {
uri: `file://` + input.path,
version: next,
},
contentChanges: [{ text }],
})
return
}
log.info("textDocument/didOpen", input)
diagnostics.delete(input.path)
await connection.sendNotification("textDocument/didOpen", {
textDocument: {
uri: `file://` + input.path,
+18 -1
View File
@@ -210,7 +210,24 @@ export namespace LSPServer {
extensions: [".py", ".pyi"],
root: NearestRoot(["pyproject.toml", "setup.py", "setup.cfg", "requirements.txt", "Pipfile", "pyrightconfig.json"]),
async spawn(_, root) {
const proc = spawn(BunProc.which(), ["x", "pyright-langserver", "--stdio"], {
let binary = Bun.which("pyright-langserver")
const args = []
if (!binary) {
const js = path.join(Global.Path.bin, "node_modules", "pyright", "dist", "pyright-langserver.js")
if (!(await Bun.file(js).exists())) {
await Bun.spawn([BunProc.which(), "install", "pyright"], {
cwd: Global.Path.bin,
env: {
...process.env,
BUN_BE_BUN: "1",
},
}).exited
}
binary = BunProc.which()
args.push(...["run", js])
}
args.push("--stdio")
const proc = spawn(binary, args, {
cwd: root,
env: {
...process.env,
+1 -2
View File
@@ -87,8 +87,7 @@ export namespace ProviderTransform {
if (modelID.includes("gpt-5")) {
if (providerID === "azure") {
return {
reasoning_effort: "minimal",
text_verbosity: "verbose",
reasoningEffort: "minimal",
}
}
return {
+3 -2
View File
@@ -42,6 +42,7 @@ import { ToolRegistry } from "../tool/registry"
import { Plugin } from "../plugin"
import { Agent } from "../agent/agent"
import { Permission } from "../permission"
import { Wildcard } from "../util/wildcard"
export namespace Session {
const log = Log.create({ service: "session" })
@@ -768,7 +769,7 @@ export namespace Session {
mergeDeep(input.tools ?? {}),
)
for (const item of await ToolRegistry.tools(input.providerID, input.modelID)) {
if (enabledTools[item.id] === false) continue
if (Wildcard.all(item.id, enabledTools) === false) continue
tools[item.id] = tool({
id: item.id as any,
description: item.description,
@@ -829,7 +830,7 @@ export namespace Session {
}
for (const [key, item] of Object.entries(await MCP.tools())) {
if (enabledTools[key] === false) continue
if (Wildcard.all(key, enabledTools) === false) continue
const execute = item.execute
if (!execute) continue
item.execute = async (args, opts) => {
+2 -1
View File
@@ -43,6 +43,7 @@ export namespace Snapshot {
}
await $`git --git-dir ${git} add .`.quiet().cwd(app.path.cwd).nothrow()
const hash = await $`git --git-dir ${git} write-tree`.quiet().cwd(app.path.cwd).nothrow().text()
log.info("tracking", { hash, cwd: app.path.cwd, git })
return hash.trim()
}
@@ -64,7 +65,7 @@ export namespace Snapshot {
.split("\n")
.map((x) => x.trim())
.filter(Boolean)
.map((x) => path.join(app.path.cwd, x)),
.map((x) => path.join(app.path.root, x)),
}
}
+14
View File
@@ -1,3 +1,5 @@
import { sortBy, pipe } from "remeda"
export namespace Wildcard {
export function match(str: string, pattern: string) {
const regex = new RegExp(
@@ -11,4 +13,16 @@ export namespace Wildcard {
)
return regex.test(str)
}
export function all(input: string, patterns: Record<string, any>) {
const sorted = pipe(patterns, Object.entries, sortBy([([key]) => key.length, "asc"], [([key]) => key, "asc"]))
let result = undefined
for (const [pattern, value] of sorted) {
if (match(input, pattern)) {
result = value
continue
}
}
return result
}
}
+1 -1
View File
@@ -1,7 +1,7 @@
{
"$schema": "https://json.schemastore.org/package.json",
"name": "@opencode-ai/plugin",
"version": "0.4.22",
"version": "0.4.27",
"type": "module",
"scripts": {
"typecheck": "tsc --noEmit"
+1 -1
View File
@@ -1,7 +1,7 @@
{
"$schema": "https://json.schemastore.org/package.json",
"name": "@opencode-ai/sdk",
"version": "0.4.22",
"version": "0.4.27",
"type": "module",
"scripts": {
"typecheck": "tsc --noEmit"
+13 -9
View File
@@ -45,14 +45,6 @@ func main() {
os.Exit(1)
}
agentsStr := os.Getenv("OPENCODE_AGENTS")
var agents []opencode.Agent
err = json.Unmarshal([]byte(agentsStr), &agents)
if err != nil {
slog.Error("Failed to unmarshal modes", "error", err)
os.Exit(1)
}
stat, err := os.Stdin.Stat()
if err != nil {
slog.Error("Failed to stat stdin", "error", err)
@@ -81,13 +73,25 @@ func main() {
option.WithBaseURL(url),
)
// Fetch agents from the /agent endpoint
agentsPtr, err := httpClient.App.Agents(context.Background())
if err != nil {
slog.Error("Failed to fetch agents", "error", err)
os.Exit(1)
}
if agentsPtr == nil {
slog.Error("No agents returned from server")
os.Exit(1)
}
agents := *agentsPtr
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
apiHandler := util.NewAPILogHandler(ctx, httpClient, "tui", slog.LevelDebug)
logger := slog.New(apiHandler)
slog.SetDefault(logger)
slog.Debug("TUI launched", "app", appInfoStr, "modes", agentsStr, "url", url)
slog.Debug("TUI launched", "app", appInfoStr, "agents_count", len(agents), "url", url)
go func() {
err = clipboard.Init()
@@ -31,6 +31,7 @@ type EditorComponent interface {
tea.Model
tea.ViewModel
Content() string
Cursor() *tea.Cursor
Lines() int
Value() string
Length() int
@@ -407,6 +408,10 @@ func (m *editorComponent) Content() string {
return content
}
func (m *editorComponent) Cursor() *tea.Cursor {
return m.textarea.Cursor()
}
func (m *editorComponent) View() string {
width := m.width
if m.app.Session.ID == "" {
@@ -694,6 +699,7 @@ func NewEditorComponent(app *app.App) EditorComponent {
ta.Prompt = " "
ta.ShowLineNumbers = false
ta.CharLimit = -1
ta.VirtualCursor = false
ta = updateTextareaStyles(ta)
m := &editorComponent{
+35 -13
View File
@@ -59,6 +59,8 @@ const interruptDebounceTimeout = 1 * time.Second
const exitDebounceTimeout = 1 * time.Second
type Model struct {
tea.Model
tea.CursorModel
width, height int
app *app.App
modal layout.Modal
@@ -748,15 +750,17 @@ func (a Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
return a, tea.Batch(cmds...)
}
func (a Model) View() string {
func (a Model) View() (string, *tea.Cursor) {
t := theme.CurrentTheme()
var mainLayout string
var editorX int
var editorY int
if a.app.Session.ID == "" {
mainLayout = a.home()
mainLayout, editorX, editorY = a.home()
} else {
mainLayout = a.chat()
mainLayout, editorX, editorY = a.chat()
}
mainLayout = styles.NewStyle().
Background(t.Background()).
@@ -780,7 +784,12 @@ func (a Model) View() string {
if theme.CurrentThemeUsesAnsiColors() {
mainLayout = util.ConvertRGBToAnsi16Colors(mainLayout)
}
return mainLayout + "\n" + a.status.View()
cursor := a.editor.Cursor()
cursor.Position.X += editorX
cursor.Position.Y += editorY
return mainLayout + "\n" + a.status.View(), cursor
}
func (a Model) Cleanup() {
@@ -807,7 +816,7 @@ func (a Model) openFile(filepath string) (tea.Model, tea.Cmd) {
return a, cmd
}
func (a Model) home() string {
func (a Model) home() (string, int, int) {
t := theme.CurrentTheme()
effectiveWidth := a.width - 4
baseStyle := styles.NewStyle().Background(t.Background())
@@ -899,14 +908,21 @@ func (a Model) home() string {
styles.WhitespaceStyle(t.Background()),
)
editorX := (effectiveWidth - editorWidth) / 2
editorX := max(0, (effectiveWidth-editorWidth)/2)
editorY := (a.height / 2) + (mainHeight / 2) - 2
if editorLines > 1 {
content := a.editor.Content()
editorHeight := lipgloss.Height(content)
if editorY+editorHeight > a.height {
difference := (editorY + editorHeight) - a.height
editorY -= difference
}
mainLayout = layout.PlaceOverlay(
editorX,
editorY,
a.editor.Content(),
content,
mainLayout,
)
}
@@ -924,10 +940,10 @@ func (a Model) home() string {
)
}
return mainLayout
return mainLayout, editorX + 5, editorY + 2
}
func (a Model) chat() string {
func (a Model) chat() (string, int, int) {
effectiveWidth := a.width - 4
t := theme.CurrentTheme()
editorView := a.editor.View()
@@ -944,14 +960,20 @@ func (a Model) chat() string {
)
mainLayout := messagesView + "\n" + editorView
editorX := (effectiveWidth - editorWidth) / 2
editorX := max(0, (effectiveWidth-editorWidth)/2)
editorY := a.height - editorHeight
if lines > 1 {
editorY := a.height - editorHeight
content := a.editor.Content()
editorHeight := lipgloss.Height(content)
if editorY+editorHeight > a.height {
difference := (editorY + editorHeight) - a.height
editorY -= difference
}
mainLayout = layout.PlaceOverlay(
editorX,
editorY,
a.editor.Content(),
content,
mainLayout,
)
}
@@ -970,7 +992,7 @@ func (a Model) chat() string {
)
}
return mainLayout
return mainLayout, editorX + 5, editorY + 2
}
func (a Model) executeCommand(command commands.Command) (tea.Model, tea.Cmd) {
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@opencode/web",
"type": "module",
"version": "0.4.22",
"version": "0.4.27",
"scripts": {
"dev": "astro dev",
"dev:remote": "sst shell --stage=dev --target=Web astro dev",
+17 -1
View File
@@ -318,6 +318,22 @@ Control which tools are available in this agent with the `tools` config. You can
}
```
You can also use wildcards to control multiple tools at once. For example, to disable all tools from an MCP server:
```json title="opencode.json"
{
"agent": {
"readonly": {
"tools": {
"mymcp_*": false,
"write": false,
"edit": false
}
}
}
}
```
If no tools are specified, all tools are enabled by default.
---
@@ -371,7 +387,7 @@ For example, with OpenAI's reasoning models, you can control the reasoning effor
"agent": {
"deep-thinker": {
"description": "Agent that uses high reasoning effort for complex problems",
"model": "openai/gpt-5-turbo",
"model": "openai/gpt-5-turbo",
"reasoningEffort": "high",
"textVerbosity": "low"
}
+1 -1
View File
@@ -2,7 +2,7 @@
"name": "opencode",
"displayName": "opencode",
"description": "opencode for VS Code",
"version": "0.4.22",
"version": "0.4.27",
"publisher": "sst-dev",
"repository": {
"type": "git",