Merge branch 'dev' into fix-webfetch-test

pull/21398/head
Aiden Cline 2026-04-07 23:15:24 -05:00 committed by GitHub
commit 78fb003379
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
24 changed files with 78 additions and 90 deletions

View File

@ -27,7 +27,7 @@
}, },
"packages/app": { "packages/app": {
"name": "@opencode-ai/app", "name": "@opencode-ai/app",
"version": "1.3.17", "version": "1.4.0",
"dependencies": { "dependencies": {
"@kobalte/core": "catalog:", "@kobalte/core": "catalog:",
"@opencode-ai/sdk": "workspace:*", "@opencode-ai/sdk": "workspace:*",
@ -81,7 +81,7 @@
}, },
"packages/console/app": { "packages/console/app": {
"name": "@opencode-ai/console-app", "name": "@opencode-ai/console-app",
"version": "1.3.17", "version": "1.4.0",
"dependencies": { "dependencies": {
"@cloudflare/vite-plugin": "1.15.2", "@cloudflare/vite-plugin": "1.15.2",
"@ibm/plex": "6.4.1", "@ibm/plex": "6.4.1",
@ -115,7 +115,7 @@
}, },
"packages/console/core": { "packages/console/core": {
"name": "@opencode-ai/console-core", "name": "@opencode-ai/console-core",
"version": "1.3.17", "version": "1.4.0",
"dependencies": { "dependencies": {
"@aws-sdk/client-sts": "3.782.0", "@aws-sdk/client-sts": "3.782.0",
"@jsx-email/render": "1.1.1", "@jsx-email/render": "1.1.1",
@ -142,7 +142,7 @@
}, },
"packages/console/function": { "packages/console/function": {
"name": "@opencode-ai/console-function", "name": "@opencode-ai/console-function",
"version": "1.3.17", "version": "1.4.0",
"dependencies": { "dependencies": {
"@ai-sdk/anthropic": "3.0.64", "@ai-sdk/anthropic": "3.0.64",
"@ai-sdk/openai": "3.0.48", "@ai-sdk/openai": "3.0.48",
@ -166,7 +166,7 @@
}, },
"packages/console/mail": { "packages/console/mail": {
"name": "@opencode-ai/console-mail", "name": "@opencode-ai/console-mail",
"version": "1.3.17", "version": "1.4.0",
"dependencies": { "dependencies": {
"@jsx-email/all": "2.2.3", "@jsx-email/all": "2.2.3",
"@jsx-email/cli": "1.4.3", "@jsx-email/cli": "1.4.3",
@ -190,7 +190,7 @@
}, },
"packages/desktop": { "packages/desktop": {
"name": "@opencode-ai/desktop", "name": "@opencode-ai/desktop",
"version": "1.3.17", "version": "1.4.0",
"dependencies": { "dependencies": {
"@opencode-ai/app": "workspace:*", "@opencode-ai/app": "workspace:*",
"@opencode-ai/ui": "workspace:*", "@opencode-ai/ui": "workspace:*",
@ -223,7 +223,7 @@
}, },
"packages/desktop-electron": { "packages/desktop-electron": {
"name": "@opencode-ai/desktop-electron", "name": "@opencode-ai/desktop-electron",
"version": "1.3.17", "version": "1.4.0",
"dependencies": { "dependencies": {
"@opencode-ai/app": "workspace:*", "@opencode-ai/app": "workspace:*",
"@opencode-ai/ui": "workspace:*", "@opencode-ai/ui": "workspace:*",
@ -255,7 +255,7 @@
}, },
"packages/enterprise": { "packages/enterprise": {
"name": "@opencode-ai/enterprise", "name": "@opencode-ai/enterprise",
"version": "1.3.17", "version": "1.4.0",
"dependencies": { "dependencies": {
"@opencode-ai/ui": "workspace:*", "@opencode-ai/ui": "workspace:*",
"@opencode-ai/util": "workspace:*", "@opencode-ai/util": "workspace:*",
@ -284,7 +284,7 @@
}, },
"packages/function": { "packages/function": {
"name": "@opencode-ai/function", "name": "@opencode-ai/function",
"version": "1.3.17", "version": "1.4.0",
"dependencies": { "dependencies": {
"@octokit/auth-app": "8.0.1", "@octokit/auth-app": "8.0.1",
"@octokit/rest": "catalog:", "@octokit/rest": "catalog:",
@ -300,7 +300,7 @@
}, },
"packages/opencode": { "packages/opencode": {
"name": "opencode", "name": "opencode",
"version": "1.3.17", "version": "1.4.0",
"bin": { "bin": {
"opencode": "./bin/opencode", "opencode": "./bin/opencode",
}, },
@ -436,7 +436,7 @@
}, },
"packages/plugin": { "packages/plugin": {
"name": "@opencode-ai/plugin", "name": "@opencode-ai/plugin",
"version": "1.3.17", "version": "1.4.0",
"dependencies": { "dependencies": {
"@opencode-ai/sdk": "workspace:*", "@opencode-ai/sdk": "workspace:*",
"zod": "catalog:", "zod": "catalog:",
@ -470,7 +470,7 @@
}, },
"packages/sdk/js": { "packages/sdk/js": {
"name": "@opencode-ai/sdk", "name": "@opencode-ai/sdk",
"version": "1.3.17", "version": "1.4.0",
"dependencies": { "dependencies": {
"cross-spawn": "catalog:", "cross-spawn": "catalog:",
}, },
@ -485,7 +485,7 @@
}, },
"packages/slack": { "packages/slack": {
"name": "@opencode-ai/slack", "name": "@opencode-ai/slack",
"version": "1.3.17", "version": "1.4.0",
"dependencies": { "dependencies": {
"@opencode-ai/sdk": "workspace:*", "@opencode-ai/sdk": "workspace:*",
"@slack/bolt": "^3.17.1", "@slack/bolt": "^3.17.1",
@ -520,7 +520,7 @@
}, },
"packages/ui": { "packages/ui": {
"name": "@opencode-ai/ui", "name": "@opencode-ai/ui",
"version": "1.3.17", "version": "1.4.0",
"dependencies": { "dependencies": {
"@kobalte/core": "catalog:", "@kobalte/core": "catalog:",
"@opencode-ai/sdk": "workspace:*", "@opencode-ai/sdk": "workspace:*",
@ -569,7 +569,7 @@
}, },
"packages/util": { "packages/util": {
"name": "@opencode-ai/util", "name": "@opencode-ai/util",
"version": "1.3.17", "version": "1.4.0",
"dependencies": { "dependencies": {
"zod": "catalog:", "zod": "catalog:",
}, },
@ -580,7 +580,7 @@
}, },
"packages/web": { "packages/web": {
"name": "@opencode-ai/web", "name": "@opencode-ai/web",
"version": "1.3.17", "version": "1.4.0",
"dependencies": { "dependencies": {
"@astrojs/cloudflare": "12.6.3", "@astrojs/cloudflare": "12.6.3",
"@astrojs/markdown-remark": "6.3.1", "@astrojs/markdown-remark": "6.3.1",

View File

@ -1,6 +1,6 @@
{ {
"name": "@opencode-ai/app", "name": "@opencode-ai/app",
"version": "1.3.17", "version": "1.4.0",
"description": "", "description": "",
"type": "module", "type": "module",
"exports": { "exports": {

View File

@ -1,6 +1,6 @@
{ {
"name": "@opencode-ai/console-app", "name": "@opencode-ai/console-app",
"version": "1.3.17", "version": "1.4.0",
"type": "module", "type": "module",
"license": "MIT", "license": "MIT",
"scripts": { "scripts": {

View File

@ -1,7 +1,7 @@
{ {
"$schema": "https://json.schemastore.org/package.json", "$schema": "https://json.schemastore.org/package.json",
"name": "@opencode-ai/console-core", "name": "@opencode-ai/console-core",
"version": "1.3.17", "version": "1.4.0",
"private": true, "private": true,
"type": "module", "type": "module",
"license": "MIT", "license": "MIT",

View File

@ -1,6 +1,6 @@
{ {
"name": "@opencode-ai/console-function", "name": "@opencode-ai/console-function",
"version": "1.3.17", "version": "1.4.0",
"$schema": "https://json.schemastore.org/package.json", "$schema": "https://json.schemastore.org/package.json",
"private": true, "private": true,
"type": "module", "type": "module",

View File

@ -1,6 +1,6 @@
{ {
"name": "@opencode-ai/console-mail", "name": "@opencode-ai/console-mail",
"version": "1.3.17", "version": "1.4.0",
"dependencies": { "dependencies": {
"@jsx-email/all": "2.2.3", "@jsx-email/all": "2.2.3",
"@jsx-email/cli": "1.4.3", "@jsx-email/cli": "1.4.3",

View File

@ -1,7 +1,7 @@
{ {
"name": "@opencode-ai/desktop-electron", "name": "@opencode-ai/desktop-electron",
"private": true, "private": true,
"version": "1.3.17", "version": "1.4.0",
"type": "module", "type": "module",
"license": "MIT", "license": "MIT",
"homepage": "https://opencode.ai", "homepage": "https://opencode.ai",

View File

@ -1,7 +1,7 @@
{ {
"name": "@opencode-ai/desktop", "name": "@opencode-ai/desktop",
"private": true, "private": true,
"version": "1.3.17", "version": "1.4.0",
"type": "module", "type": "module",
"license": "MIT", "license": "MIT",
"scripts": { "scripts": {

View File

@ -1,6 +1,6 @@
{ {
"name": "@opencode-ai/enterprise", "name": "@opencode-ai/enterprise",
"version": "1.3.17", "version": "1.4.0",
"private": true, "private": true,
"type": "module", "type": "module",
"license": "MIT", "license": "MIT",

View File

@ -1,7 +1,7 @@
id = "opencode" id = "opencode"
name = "OpenCode" name = "OpenCode"
description = "The open source coding agent." description = "The open source coding agent."
version = "1.3.17" version = "1.4.0"
schema_version = 1 schema_version = 1
authors = ["Anomaly"] authors = ["Anomaly"]
repository = "https://github.com/anomalyco/opencode" repository = "https://github.com/anomalyco/opencode"
@ -11,26 +11,26 @@ name = "OpenCode"
icon = "./icons/opencode.svg" icon = "./icons/opencode.svg"
[agent_servers.opencode.targets.darwin-aarch64] [agent_servers.opencode.targets.darwin-aarch64]
archive = "https://github.com/anomalyco/opencode/releases/download/v1.3.17/opencode-darwin-arm64.zip" archive = "https://github.com/anomalyco/opencode/releases/download/v1.4.0/opencode-darwin-arm64.zip"
cmd = "./opencode" cmd = "./opencode"
args = ["acp"] args = ["acp"]
[agent_servers.opencode.targets.darwin-x86_64] [agent_servers.opencode.targets.darwin-x86_64]
archive = "https://github.com/anomalyco/opencode/releases/download/v1.3.17/opencode-darwin-x64.zip" archive = "https://github.com/anomalyco/opencode/releases/download/v1.4.0/opencode-darwin-x64.zip"
cmd = "./opencode" cmd = "./opencode"
args = ["acp"] args = ["acp"]
[agent_servers.opencode.targets.linux-aarch64] [agent_servers.opencode.targets.linux-aarch64]
archive = "https://github.com/anomalyco/opencode/releases/download/v1.3.17/opencode-linux-arm64.tar.gz" archive = "https://github.com/anomalyco/opencode/releases/download/v1.4.0/opencode-linux-arm64.tar.gz"
cmd = "./opencode" cmd = "./opencode"
args = ["acp"] args = ["acp"]
[agent_servers.opencode.targets.linux-x86_64] [agent_servers.opencode.targets.linux-x86_64]
archive = "https://github.com/anomalyco/opencode/releases/download/v1.3.17/opencode-linux-x64.tar.gz" archive = "https://github.com/anomalyco/opencode/releases/download/v1.4.0/opencode-linux-x64.tar.gz"
cmd = "./opencode" cmd = "./opencode"
args = ["acp"] args = ["acp"]
[agent_servers.opencode.targets.windows-x86_64] [agent_servers.opencode.targets.windows-x86_64]
archive = "https://github.com/anomalyco/opencode/releases/download/v1.3.17/opencode-windows-x64.zip" archive = "https://github.com/anomalyco/opencode/releases/download/v1.4.0/opencode-windows-x64.zip"
cmd = "./opencode.exe" cmd = "./opencode.exe"
args = ["acp"] args = ["acp"]

View File

@ -1,6 +1,6 @@
{ {
"name": "@opencode-ai/function", "name": "@opencode-ai/function",
"version": "1.3.17", "version": "1.4.0",
"$schema": "https://json.schemastore.org/package.json", "$schema": "https://json.schemastore.org/package.json",
"private": true, "private": true,
"type": "module", "type": "module",

View File

@ -1,6 +1,6 @@
{ {
"$schema": "https://json.schemastore.org/package.json", "$schema": "https://json.schemastore.org/package.json",
"version": "1.3.17", "version": "1.4.0",
"name": "opencode", "name": "opencode",
"type": "module", "type": "module",
"license": "MIT", "license": "MIT",

View File

@ -8,7 +8,6 @@ import { createDialogProviderOptions, DialogProvider } from "./dialog-provider"
import { DialogVariant } from "./dialog-variant" import { DialogVariant } from "./dialog-variant"
import { useKeybind } from "../context/keybind" import { useKeybind } from "../context/keybind"
import * as fuzzysort from "fuzzysort" import * as fuzzysort from "fuzzysort"
import { consoleManagedProviderLabel } from "@tui/util/provider-origin"
export function useConnected() { export function useConnected() {
const sync = useSync() const sync = useSync()
@ -47,11 +46,7 @@ export function DialogModel(props: { providerID?: string }) {
key: item, key: item,
value: { providerID: provider.id, modelID: model.id }, value: { providerID: provider.id, modelID: model.id },
title: model.name ?? item.modelID, title: model.name ?? item.modelID,
description: consoleManagedProviderLabel( description: provider.name,
sync.data.console_state.consoleManagedProviders,
provider.id,
provider.name,
),
category, category,
disabled: provider.id === "opencode" && model.id.includes("-nano"), disabled: provider.id === "opencode" && model.id.includes("-nano"),
footer: model.cost?.input === 0 && provider.id === "opencode" ? "Free" : undefined, footer: model.cost?.input === 0 && provider.id === "opencode" ? "Free" : undefined,
@ -89,9 +84,7 @@ export function DialogModel(props: { providerID?: string }) {
description: favorites.some((item) => item.providerID === provider.id && item.modelID === model) description: favorites.some((item) => item.providerID === provider.id && item.modelID === model)
? "(Favorite)" ? "(Favorite)"
: undefined, : undefined,
category: connected() category: connected() ? provider.name : undefined,
? consoleManagedProviderLabel(sync.data.console_state.consoleManagedProviders, provider.id, provider.name)
: undefined,
disabled: provider.id === "opencode" && model.includes("-nano"), disabled: provider.id === "opencode" && model.includes("-nano"),
footer: info.cost?.input === 0 && provider.id === "opencode" ? "Free" : undefined, footer: info.cost?.input === 0 && provider.id === "opencode" ? "Free" : undefined,
onSelect() { onSelect() {
@ -142,7 +135,7 @@ export function DialogModel(props: { providerID?: string }) {
const title = createMemo(() => { const title = createMemo(() => {
const value = provider() const value = provider()
if (!value) return "Select model" if (!value) return "Select model"
return consoleManagedProviderLabel(sync.data.console_state.consoleManagedProviders, value.id, value.name) return value.name
}) })
function onSelect(providerID: string, modelID: string) { function onSelect(providerID: string, modelID: string) {

View File

@ -13,7 +13,7 @@ import { DialogModel } from "./dialog-model"
import { useKeyboard } from "@opentui/solid" import { useKeyboard } from "@opentui/solid"
import { Clipboard } from "@tui/util/clipboard" import { Clipboard } from "@tui/util/clipboard"
import { useToast } from "../ui/toast" import { useToast } from "../ui/toast"
import { CONSOLE_MANAGED_ICON, isConsoleManagedProvider } from "@tui/util/provider-origin" import { isConsoleManagedProvider } from "@tui/util/provider-origin"
const PROVIDER_PRIORITY: Record<string, number> = { const PROVIDER_PRIORITY: Record<string, number> = {
opencode: 0, opencode: 0,
@ -49,11 +49,7 @@ export function createDialogProviderOptions() {
}[provider.id], }[provider.id],
footer: consoleManaged ? sync.data.console_state.activeOrgName : undefined, footer: consoleManaged ? sync.data.console_state.activeOrgName : undefined,
category: provider.id in PROVIDER_PRIORITY ? "Popular" : "Other", category: provider.id in PROVIDER_PRIORITY ? "Popular" : "Other",
gutter: consoleManaged ? ( gutter: connected ? <text fg={theme.success}></text> : undefined,
<text fg={theme.textMuted}>{CONSOLE_MANAGED_ICON}</text>
) : connected ? (
<text fg={theme.success}></text>
) : undefined,
async onSelect() { async onSelect() {
if (consoleManaged) return if (consoleManaged) return

View File

@ -36,7 +36,6 @@ import { useToast } from "../../ui/toast"
import { useKV } from "../../context/kv" import { useKV } from "../../context/kv"
import { useTextareaKeybindings } from "../textarea-keybindings" import { useTextareaKeybindings } from "../textarea-keybindings"
import { DialogSkill } from "../dialog-skill" import { DialogSkill } from "../dialog-skill"
import { CONSOLE_MANAGED_ICON, consoleManagedProviderLabel } from "@tui/util/provider-origin"
export type PromptProps = { export type PromptProps = {
sessionID?: string sessionID?: string
@ -96,15 +95,8 @@ export function Prompt(props: PromptProps) {
const list = createMemo(() => props.placeholders?.normal ?? []) const list = createMemo(() => props.placeholders?.normal ?? [])
const shell = createMemo(() => props.placeholders?.shell ?? []) const shell = createMemo(() => props.placeholders?.shell ?? [])
const [auto, setAuto] = createSignal<AutocompleteRef>() const [auto, setAuto] = createSignal<AutocompleteRef>()
const activeOrgName = createMemo(() => sync.data.console_state.activeOrgName) const currentProviderLabel = createMemo(() => local.model.parsed().provider)
const canSwitchOrgs = createMemo(() => sync.data.console_state.switchableOrgCount > 1) const hasRightContent = createMemo(() => Boolean(props.right))
const currentProviderLabel = createMemo(() => {
const current = local.model.current()
const provider = local.model.parsed().provider
if (!current) return provider
return consoleManagedProviderLabel(sync.data.console_state.consoleManagedProviders, current.providerID, provider)
})
const hasRightContent = createMemo(() => Boolean(props.right || activeOrgName()))
function promptModelWarning() { function promptModelWarning() {
toast.show({ toast.show({
@ -1120,17 +1112,6 @@ export function Prompt(props: PromptProps) {
<Show when={hasRightContent()}> <Show when={hasRightContent()}>
<box flexDirection="row" gap={1} alignItems="center"> <box flexDirection="row" gap={1} alignItems="center">
{props.right} {props.right}
<Show when={activeOrgName()}>
<text
fg={theme.textMuted}
onMouseUp={() => {
if (!canSwitchOrgs()) return
command.trigger("console.org.switch")
}}
>
{`${CONSOLE_MANAGED_ICON} ${activeOrgName()}`}
</text>
</Show>
</box> </box>
</Show> </Show>
</box> </box>
@ -1162,7 +1143,7 @@ export function Prompt(props: PromptProps) {
} }
/> />
</box> </box>
<box flexDirection="row" justifyContent="space-between"> <box width="100%" flexDirection="row" justifyContent="space-between">
<Show when={status().type !== "idle"} fallback={props.hint ?? <text />}> <Show when={status().type !== "idle"} fallback={props.hint ?? <text />}>
<box <box
flexDirection="row" flexDirection="row"

View File

@ -1,5 +1,3 @@
export const CONSOLE_MANAGED_ICON = "⌂"
const contains = (consoleManagedProviders: string[] | ReadonlySet<string>, providerID: string) => const contains = (consoleManagedProviders: string[] | ReadonlySet<string>, providerID: string) =>
Array.isArray(consoleManagedProviders) Array.isArray(consoleManagedProviders)
? consoleManagedProviders.includes(providerID) ? consoleManagedProviders.includes(providerID)
@ -7,14 +5,3 @@ const contains = (consoleManagedProviders: string[] | ReadonlySet<string>, provi
export const isConsoleManagedProvider = (consoleManagedProviders: string[] | ReadonlySet<string>, providerID: string) => export const isConsoleManagedProvider = (consoleManagedProviders: string[] | ReadonlySet<string>, providerID: string) =>
contains(consoleManagedProviders, providerID) contains(consoleManagedProviders, providerID)
export const consoleManagedProviderSuffix = (
consoleManagedProviders: string[] | ReadonlySet<string>,
providerID: string,
) => (contains(consoleManagedProviders, providerID) ? ` ${CONSOLE_MANAGED_ICON}` : "")
export const consoleManagedProviderLabel = (
consoleManagedProviders: string[] | ReadonlySet<string>,
providerID: string,
providerName: string,
) => `${providerName}${consoleManagedProviderSuffix(consoleManagedProviders, providerID)}`

View File

@ -98,6 +98,37 @@ describe("tool.registry", () => {
}), }),
) )
await Bun.write(
path.join(opencodeDir, "package-lock.json"),
JSON.stringify({
name: "custom-tools",
lockfileVersion: 3,
packages: {
"": {
dependencies: {
"@opencode-ai/plugin": "^0.0.0",
cowsay: "^1.6.0",
},
},
},
}),
)
const cowsayDir = path.join(opencodeDir, "node_modules", "cowsay")
await fs.mkdir(cowsayDir, { recursive: true })
await Bun.write(
path.join(cowsayDir, "package.json"),
JSON.stringify({
name: "cowsay",
type: "module",
exports: "./index.js",
}),
)
await Bun.write(
path.join(cowsayDir, "index.js"),
["export function say({ text }) {", " return `moo ${text}`", "}", ""].join("\n"),
)
await Bun.write( await Bun.write(
path.join(toolsDir, "cowsay.ts"), path.join(toolsDir, "cowsay.ts"),
[ [

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": "1.3.17", "version": "1.4.0",
"type": "module", "type": "module",
"license": "MIT", "license": "MIT",
"scripts": { "scripts": {

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": "1.3.17", "version": "1.4.0",
"type": "module", "type": "module",
"license": "MIT", "license": "MIT",
"scripts": { "scripts": {

View File

@ -1,6 +1,6 @@
{ {
"name": "@opencode-ai/slack", "name": "@opencode-ai/slack",
"version": "1.3.17", "version": "1.4.0",
"type": "module", "type": "module",
"license": "MIT", "license": "MIT",
"scripts": { "scripts": {

View File

@ -1,6 +1,6 @@
{ {
"name": "@opencode-ai/ui", "name": "@opencode-ai/ui",
"version": "1.3.17", "version": "1.4.0",
"type": "module", "type": "module",
"license": "MIT", "license": "MIT",
"exports": { "exports": {

View File

@ -1,6 +1,6 @@
{ {
"name": "@opencode-ai/util", "name": "@opencode-ai/util",
"version": "1.3.17", "version": "1.4.0",
"private": true, "private": true,
"type": "module", "type": "module",
"license": "MIT", "license": "MIT",

View File

@ -2,7 +2,7 @@
"name": "@opencode-ai/web", "name": "@opencode-ai/web",
"type": "module", "type": "module",
"license": "MIT", "license": "MIT",
"version": "1.3.17", "version": "1.4.0",
"scripts": { "scripts": {
"dev": "astro dev", "dev": "astro dev",
"dev:remote": "VITE_API_URL=https://api.opencode.ai astro dev", "dev:remote": "VITE_API_URL=https://api.opencode.ai astro dev",

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": "1.3.17", "version": "1.4.0",
"publisher": "sst-dev", "publisher": "sst-dev",
"repository": { "repository": {
"type": "git", "type": "git",