diff --git a/bun.lock b/bun.lock index 325eeb15f5..2638e6b722 100644 --- a/bun.lock +++ b/bun.lock @@ -26,7 +26,7 @@ }, "packages/app": { "name": "@opencode-ai/app", - "version": "1.2.18", + "version": "1.2.19", "dependencies": { "@kobalte/core": "catalog:", "@opencode-ai/sdk": "workspace:*", @@ -76,7 +76,7 @@ }, "packages/console/app": { "name": "@opencode-ai/console-app", - "version": "1.2.18", + "version": "1.2.19", "dependencies": { "@cloudflare/vite-plugin": "1.15.2", "@ibm/plex": "6.4.1", @@ -110,7 +110,7 @@ }, "packages/console/core": { "name": "@opencode-ai/console-core", - "version": "1.2.18", + "version": "1.2.19", "dependencies": { "@aws-sdk/client-sts": "3.782.0", "@jsx-email/render": "1.1.1", @@ -137,7 +137,7 @@ }, "packages/console/function": { "name": "@opencode-ai/console-function", - "version": "1.2.18", + "version": "1.2.19", "dependencies": { "@ai-sdk/anthropic": "2.0.0", "@ai-sdk/openai": "2.0.2", @@ -161,7 +161,7 @@ }, "packages/console/mail": { "name": "@opencode-ai/console-mail", - "version": "1.2.18", + "version": "1.2.19", "dependencies": { "@jsx-email/all": "2.2.3", "@jsx-email/cli": "1.4.3", @@ -185,7 +185,7 @@ }, "packages/desktop": { "name": "@opencode-ai/desktop", - "version": "1.2.18", + "version": "1.2.19", "dependencies": { "@opencode-ai/app": "workspace:*", "@opencode-ai/ui": "workspace:*", @@ -218,7 +218,7 @@ }, "packages/desktop-electron": { "name": "@opencode-ai/desktop-electron", - "version": "1.2.18", + "version": "1.2.19", "dependencies": { "@opencode-ai/app": "workspace:*", "@opencode-ai/ui": "workspace:*", @@ -248,7 +248,7 @@ }, "packages/enterprise": { "name": "@opencode-ai/enterprise", - "version": "1.2.18", + "version": "1.2.19", "dependencies": { "@opencode-ai/ui": "workspace:*", "@opencode-ai/util": "workspace:*", @@ -277,7 +277,7 @@ }, "packages/function": { "name": "@opencode-ai/function", - "version": "1.2.18", + "version": "1.2.19", "dependencies": { "@octokit/auth-app": "8.0.1", "@octokit/rest": "catalog:", @@ -293,7 +293,7 @@ }, "packages/opencode": { "name": "opencode", - "version": "1.2.18", + "version": "1.2.19", "bin": { "opencode": "./bin/opencode", }, @@ -407,7 +407,7 @@ }, "packages/plugin": { "name": "@opencode-ai/plugin", - "version": "1.2.18", + "version": "1.2.19", "dependencies": { "@opencode-ai/sdk": "workspace:*", "zod": "catalog:", @@ -427,7 +427,7 @@ }, "packages/sdk/js": { "name": "@opencode-ai/sdk", - "version": "1.2.18", + "version": "1.2.19", "devDependencies": { "@hey-api/openapi-ts": "0.90.10", "@tsconfig/node22": "catalog:", @@ -438,7 +438,7 @@ }, "packages/slack": { "name": "@opencode-ai/slack", - "version": "1.2.18", + "version": "1.2.19", "dependencies": { "@opencode-ai/sdk": "workspace:*", "@slack/bolt": "^3.17.1", @@ -473,7 +473,7 @@ }, "packages/ui": { "name": "@opencode-ai/ui", - "version": "1.2.18", + "version": "1.2.19", "dependencies": { "@kobalte/core": "catalog:", "@opencode-ai/sdk": "workspace:*", @@ -519,7 +519,7 @@ }, "packages/util": { "name": "@opencode-ai/util", - "version": "1.2.18", + "version": "1.2.19", "dependencies": { "zod": "catalog:", }, @@ -530,7 +530,7 @@ }, "packages/web": { "name": "@opencode-ai/web", - "version": "1.2.18", + "version": "1.2.19", "dependencies": { "@astrojs/cloudflare": "12.6.3", "@astrojs/markdown-remark": "6.3.1", diff --git a/github/index.ts b/github/index.ts index da310178a7..1a0a992622 100644 --- a/github/index.ts +++ b/github/index.ts @@ -8,6 +8,7 @@ import type { Context as GitHubContext } from "@actions/github/lib/context" import type { IssueCommentEvent, PullRequestReviewCommentEvent } from "@octokit/webhooks-types" import { createOpencodeClient } from "@opencode-ai/sdk" import { spawn } from "node:child_process" +import { setTimeout as sleep } from "node:timers/promises" type GitHubAuthor = { login: string @@ -281,7 +282,7 @@ async function assertOpencodeConnected() { connected = true break } catch (e) {} - await Bun.sleep(300) + await sleep(300) } while (retry++ < 30) if (!connected) { diff --git a/packages/app/package.json b/packages/app/package.json index 37ccd9b53a..809a285374 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/app", - "version": "1.2.18", + "version": "1.2.19", "description": "", "type": "module", "exports": { diff --git a/packages/console/app/package.json b/packages/console/app/package.json index 67a7eafa7c..269b005a86 100644 --- a/packages/console/app/package.json +++ b/packages/console/app/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/console-app", - "version": "1.2.18", + "version": "1.2.19", "type": "module", "license": "MIT", "scripts": { diff --git a/packages/console/core/package.json b/packages/console/core/package.json index 37c94aecbb..199b5d9bd6 100644 --- a/packages/console/core/package.json +++ b/packages/console/core/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "@opencode-ai/console-core", - "version": "1.2.18", + "version": "1.2.19", "private": true, "type": "module", "license": "MIT", diff --git a/packages/console/function/package.json b/packages/console/function/package.json index bb7caccc58..e771aae844 100644 --- a/packages/console/function/package.json +++ b/packages/console/function/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/console-function", - "version": "1.2.18", + "version": "1.2.19", "$schema": "https://json.schemastore.org/package.json", "private": true, "type": "module", diff --git a/packages/console/mail/package.json b/packages/console/mail/package.json index 00e7378fe5..ef8d7c5994 100644 --- a/packages/console/mail/package.json +++ b/packages/console/mail/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/console-mail", - "version": "1.2.18", + "version": "1.2.19", "dependencies": { "@jsx-email/all": "2.2.3", "@jsx-email/cli": "1.4.3", diff --git a/packages/desktop-electron/package.json b/packages/desktop-electron/package.json index 41791066ea..e683d185bc 100644 --- a/packages/desktop-electron/package.json +++ b/packages/desktop-electron/package.json @@ -1,7 +1,7 @@ { "name": "@opencode-ai/desktop-electron", "private": true, - "version": "1.2.18", + "version": "1.2.19", "type": "module", "license": "MIT", "homepage": "https://opencode.ai", diff --git a/packages/desktop/package.json b/packages/desktop/package.json index 49699ff85e..10e6df26b1 100644 --- a/packages/desktop/package.json +++ b/packages/desktop/package.json @@ -1,7 +1,7 @@ { "name": "@opencode-ai/desktop", "private": true, - "version": "1.2.18", + "version": "1.2.19", "type": "module", "license": "MIT", "scripts": { diff --git a/packages/enterprise/package.json b/packages/enterprise/package.json index 065015bc50..ef56add880 100644 --- a/packages/enterprise/package.json +++ b/packages/enterprise/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/enterprise", - "version": "1.2.18", + "version": "1.2.19", "private": true, "type": "module", "license": "MIT", diff --git a/packages/extensions/zed/extension.toml b/packages/extensions/zed/extension.toml index efd12836ee..1637c58a4d 100644 --- a/packages/extensions/zed/extension.toml +++ b/packages/extensions/zed/extension.toml @@ -1,7 +1,7 @@ id = "opencode" name = "OpenCode" description = "The open source coding agent." -version = "1.2.18" +version = "1.2.19" schema_version = 1 authors = ["Anomaly"] repository = "https://github.com/anomalyco/opencode" @@ -11,26 +11,26 @@ name = "OpenCode" icon = "./icons/opencode.svg" [agent_servers.opencode.targets.darwin-aarch64] -archive = "https://github.com/anomalyco/opencode/releases/download/v1.2.18/opencode-darwin-arm64.zip" +archive = "https://github.com/anomalyco/opencode/releases/download/v1.2.19/opencode-darwin-arm64.zip" cmd = "./opencode" args = ["acp"] [agent_servers.opencode.targets.darwin-x86_64] -archive = "https://github.com/anomalyco/opencode/releases/download/v1.2.18/opencode-darwin-x64.zip" +archive = "https://github.com/anomalyco/opencode/releases/download/v1.2.19/opencode-darwin-x64.zip" cmd = "./opencode" args = ["acp"] [agent_servers.opencode.targets.linux-aarch64] -archive = "https://github.com/anomalyco/opencode/releases/download/v1.2.18/opencode-linux-arm64.tar.gz" +archive = "https://github.com/anomalyco/opencode/releases/download/v1.2.19/opencode-linux-arm64.tar.gz" cmd = "./opencode" args = ["acp"] [agent_servers.opencode.targets.linux-x86_64] -archive = "https://github.com/anomalyco/opencode/releases/download/v1.2.18/opencode-linux-x64.tar.gz" +archive = "https://github.com/anomalyco/opencode/releases/download/v1.2.19/opencode-linux-x64.tar.gz" cmd = "./opencode" args = ["acp"] [agent_servers.opencode.targets.windows-x86_64] -archive = "https://github.com/anomalyco/opencode/releases/download/v1.2.18/opencode-windows-x64.zip" +archive = "https://github.com/anomalyco/opencode/releases/download/v1.2.19/opencode-windows-x64.zip" cmd = "./opencode.exe" args = ["acp"] diff --git a/packages/function/package.json b/packages/function/package.json index 162b564ad9..efaae65f53 100644 --- a/packages/function/package.json +++ b/packages/function/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/function", - "version": "1.2.18", + "version": "1.2.19", "$schema": "https://json.schemastore.org/package.json", "private": true, "type": "module", diff --git a/packages/opencode/package.json b/packages/opencode/package.json index 5edfca7e19..30af3c347c 100644 --- a/packages/opencode/package.json +++ b/packages/opencode/package.json @@ -1,6 +1,6 @@ { "$schema": "https://json.schemastore.org/package.json", - "version": "1.2.18", + "version": "1.2.19", "name": "opencode", "type": "module", "license": "MIT", diff --git a/packages/opencode/src/acp/agent.ts b/packages/opencode/src/acp/agent.ts index 8b338f1b57..d518dd12a1 100644 --- a/packages/opencode/src/acp/agent.ts +++ b/packages/opencode/src/acp/agent.ts @@ -31,6 +31,7 @@ import { import { Log } from "../util/log" import { pathToFileURL } from "bun" import { Filesystem } from "../util/filesystem" +import { Hash } from "../util/hash" import { ACPSessionManager } from "./session" import type { ACPConfig } from "./types" import { Provider } from "../provider/provider" @@ -281,7 +282,7 @@ export namespace ACP { const output = this.bashOutput(part) const content: ToolCallContent[] = [] if (output) { - const hash = String(Bun.hash(output)) + const hash = Hash.fast(output) if (part.tool === "bash") { if (this.bashSnapshots.get(part.callID) === hash) { await this.connection diff --git a/packages/opencode/src/cli/cmd/auth.ts b/packages/opencode/src/cli/cmd/auth.ts index a7300e0293..38fba0ce70 100644 --- a/packages/opencode/src/cli/cmd/auth.ts +++ b/packages/opencode/src/cli/cmd/auth.ts @@ -13,6 +13,7 @@ import { Instance } from "../../project/instance" import type { Hooks } from "@opencode-ai/plugin" import { Process } from "../../util/process" import { text } from "node:stream/consumers" +import { setTimeout as sleep } from "node:timers/promises" type PluginAuth = NonNullable @@ -47,7 +48,7 @@ async function handlePluginAuth(plugin: { auth: PluginAuth }, provider: string, const method = plugin.auth.methods[index] // Handle prompts for all auth types - await Bun.sleep(10) + await sleep(10) const inputs: Record = {} if (method.prompts) { for (const prompt of method.prompts) { diff --git a/packages/opencode/src/cli/cmd/debug/lsp.ts b/packages/opencode/src/cli/cmd/debug/lsp.ts index d83c4ed8a4..4b8a3e7d45 100644 --- a/packages/opencode/src/cli/cmd/debug/lsp.ts +++ b/packages/opencode/src/cli/cmd/debug/lsp.ts @@ -3,6 +3,7 @@ import { bootstrap } from "../../bootstrap" import { cmd } from "../cmd" import { Log } from "../../../util/log" import { EOL } from "os" +import { setTimeout as sleep } from "node:timers/promises" export const LSPCommand = cmd({ command: "lsp", @@ -19,7 +20,7 @@ const DiagnosticsCommand = cmd({ async handler(args) { await bootstrap(process.cwd(), async () => { await LSP.touchFile(args.file, true) - await Bun.sleep(1000) + await sleep(1000) process.stdout.write(JSON.stringify(await LSP.diagnostics(), null, 2) + EOL) }) }, diff --git a/packages/opencode/src/cli/cmd/github.ts b/packages/opencode/src/cli/cmd/github.ts index 672e73d49a..2491abc567 100644 --- a/packages/opencode/src/cli/cmd/github.ts +++ b/packages/opencode/src/cli/cmd/github.ts @@ -28,6 +28,7 @@ import { Bus } from "../../bus" import { MessageV2 } from "../../session/message-v2" import { SessionPrompt } from "@/session/prompt" import { $ } from "bun" +import { setTimeout as sleep } from "node:timers/promises" type GitHubAuthor = { login: string @@ -353,7 +354,7 @@ export const GithubInstallCommand = cmd({ } retries++ - await Bun.sleep(1000) + await sleep(1000) } while (true) s.stop("Installed GitHub app") @@ -1372,7 +1373,7 @@ Co-authored-by: ${actor} <${actor}@users.noreply.github.com>"` } catch (e) { if (retries > 0) { console.log(`Retrying after ${delayMs}ms...`) - await Bun.sleep(delayMs) + await sleep(delayMs) return withRetry(fn, retries - 1, delayMs) } throw e diff --git a/packages/opencode/src/cli/cmd/run.ts b/packages/opencode/src/cli/cmd/run.ts index 61bc609bb7..d74eb2aa4c 100644 --- a/packages/opencode/src/cli/cmd/run.ts +++ b/packages/opencode/src/cli/cmd/run.ts @@ -6,6 +6,7 @@ import { cmd } from "./cmd" import { Flag } from "../../flag/flag" import { bootstrap } from "../bootstrap" import { EOL } from "os" +import { text as streamText } from "node:stream/consumers" import { Filesystem } from "../../util/filesystem" import { createOpencodeClient, type Message, type OpencodeClient, type ToolPart } from "@opencode-ai/sdk/v2" import { Server } from "../../server/server" @@ -337,7 +338,7 @@ export const RunCommand = cmd({ } } - if (!process.stdin.isTTY) message += "\n" + (await Bun.stdin.text()) + if (!process.stdin.isTTY) message += "\n" + (await streamText(process.stdin)) if (message.trim().length === 0 && !args.command) { UI.error("You must provide a message or a command") diff --git a/packages/opencode/src/cli/cmd/tui/thread.ts b/packages/opencode/src/cli/cmd/tui/thread.ts index f53cc39255..57acfd199e 100644 --- a/packages/opencode/src/cli/cmd/tui/thread.ts +++ b/packages/opencode/src/cli/cmd/tui/thread.ts @@ -3,6 +3,7 @@ import { tui } from "./app" import { Rpc } from "@/util/rpc" import { type rpc } from "./worker" import path from "path" +import { text as streamText } from "node:stream/consumers" import { fileURLToPath } from "url" import { UI } from "@/cli/ui" import { Log } from "@/util/log" @@ -53,7 +54,7 @@ async function target() { } async function input(value?: string) { - const piped = process.stdin.isTTY ? undefined : await Bun.stdin.text() + const piped = process.stdin.isTTY ? undefined : await streamText(process.stdin) if (!value) return piped if (!piped) return value return piped + "\n" + value diff --git a/packages/opencode/src/cli/cmd/tui/worker.ts b/packages/opencode/src/cli/cmd/tui/worker.ts index e63f10ba80..4452d6d764 100644 --- a/packages/opencode/src/cli/cmd/tui/worker.ts +++ b/packages/opencode/src/cli/cmd/tui/worker.ts @@ -10,6 +10,7 @@ import { GlobalBus } from "@/bus/global" import { createOpencodeClient, type Event } from "@opencode-ai/sdk/v2" import type { BunWebSocketData } from "hono/bun" import { Flag } from "@/flag/flag" +import { setTimeout as sleep } from "node:timers/promises" await Log.init({ print: process.argv.includes("--print-logs"), @@ -75,7 +76,7 @@ const startEventStream = (directory: string) => { ).catch(() => undefined) if (!events) { - await Bun.sleep(250) + await sleep(250) continue } @@ -84,7 +85,7 @@ const startEventStream = (directory: string) => { } if (!signal.aborted) { - await Bun.sleep(250) + await sleep(250) } } })().catch((error) => { diff --git a/packages/opencode/src/cli/ui.ts b/packages/opencode/src/cli/ui.ts index f242a77f6c..39396997c6 100644 --- a/packages/opencode/src/cli/ui.ts +++ b/packages/opencode/src/cli/ui.ts @@ -25,12 +25,12 @@ export namespace UI { export function println(...message: string[]) { print(...message) - Bun.stderr.write(EOL) + process.stderr.write(EOL) } export function print(...message: string[]) { blank = false - Bun.stderr.write(message.join(" ")) + process.stderr.write(message.join(" ")) } let blank = false @@ -44,7 +44,7 @@ export namespace UI { const result: string[] = [] const reset = "\x1b[0m" const left = { - fg: Bun.color("gray", "ansi") ?? "", + fg: "\x1b[90m", shadow: "\x1b[38;5;235m", bg: "\x1b[48;5;235m", } diff --git a/packages/opencode/src/config/config.ts b/packages/opencode/src/config/config.ts index 28c5b239a4..6b4242a225 100644 --- a/packages/opencode/src/config/config.ts +++ b/packages/opencode/src/config/config.ts @@ -1240,7 +1240,7 @@ export namespace Config { if (!parsed.data.$schema && isFile) { parsed.data.$schema = "https://opencode.ai/config.json" const updated = original.replace(/^\s*\{/, '{\n "$schema": "https://opencode.ai/config.json",') - await Bun.write(options.path, updated).catch(() => {}) + await Filesystem.write(options.path, updated).catch(() => {}) } const data = parsed.data if (data.plugin && isFile) { @@ -1401,3 +1401,5 @@ export namespace Config { return state().then((x) => x.directories) } } +Filesystem.write +Filesystem.write diff --git a/packages/opencode/src/config/migrate-tui-config.ts b/packages/opencode/src/config/migrate-tui-config.ts index b426e4fbd1..dbe33ffb42 100644 --- a/packages/opencode/src/config/migrate-tui-config.ts +++ b/packages/opencode/src/config/migrate-tui-config.ts @@ -70,7 +70,7 @@ export async function migrateTuiConfig(input: MigrateInput) { if (extracted.keybinds !== undefined) payload.keybinds = extracted.keybinds if (tui) Object.assign(payload, tui) - const wrote = await Bun.write(target, JSON.stringify(payload, null, 2)) + const wrote = await Filesystem.write(target, JSON.stringify(payload, null, 2)) .then(() => true) .catch((error) => { log.warn("failed to write tui migration target", { from: file, to: target, error }) @@ -104,7 +104,7 @@ async function backupAndStripLegacy(file: string, source: string) { const hasBackup = await Filesystem.exists(backup) const backed = hasBackup ? true - : await Bun.write(backup, source) + : await Filesystem.write(backup, source) .then(() => true) .catch((error) => { log.warn("failed to backup source config during tui migration", { path: file, backup, error }) @@ -123,7 +123,7 @@ async function backupAndStripLegacy(file: string, source: string) { return applyEdits(acc, edits) }, source) - return Bun.write(file, text) + return Filesystem.write(file, text) .then(() => { log.info("stripped tui keys from server config", { path: file, backup }) return true diff --git a/packages/opencode/src/mcp/oauth-callback.ts b/packages/opencode/src/mcp/oauth-callback.ts index bb3b56f2e9..db8e621d6c 100644 --- a/packages/opencode/src/mcp/oauth-callback.ts +++ b/packages/opencode/src/mcp/oauth-callback.ts @@ -1,3 +1,4 @@ +import { createConnection } from "net" import { Log } from "../util/log" import { OAUTH_CALLBACK_PORT, OAUTH_CALLBACK_PATH } from "./oauth-provider" @@ -160,21 +161,12 @@ export namespace McpOAuthCallback { export async function isPortInUse(): Promise { return new Promise((resolve) => { - Bun.connect({ - hostname: "127.0.0.1", - port: OAUTH_CALLBACK_PORT, - socket: { - open(socket) { - socket.end() - resolve(true) - }, - error() { - resolve(false) - }, - data() {}, - close() {}, - }, - }).catch(() => { + const socket = createConnection(OAUTH_CALLBACK_PORT, "127.0.0.1") + socket.on("connect", () => { + socket.destroy() + resolve(true) + }) + socket.on("error", () => { resolve(false) }) }) diff --git a/packages/opencode/src/plugin/codex.ts b/packages/opencode/src/plugin/codex.ts index 56931b2ed6..5c0140e570 100644 --- a/packages/opencode/src/plugin/codex.ts +++ b/packages/opencode/src/plugin/codex.ts @@ -4,6 +4,7 @@ import { Installation } from "../installation" import { Auth, OAUTH_DUMMY_KEY } from "../auth" import os from "os" import { ProviderTransform } from "@/provider/transform" +import { setTimeout as sleep } from "node:timers/promises" const log = Log.create({ service: "plugin.codex" }) @@ -361,6 +362,7 @@ export async function CodexAuthPlugin(input: PluginInput): Promise { "gpt-5.1-codex-max", "gpt-5.1-codex-mini", "gpt-5.2", + "gpt-5.4", "gpt-5.2-codex", "gpt-5.3-codex", "gpt-5.1-codex", @@ -602,7 +604,7 @@ export async function CodexAuthPlugin(input: PluginInput): Promise { return { type: "failed" as const } } - await Bun.sleep(interval + OAUTH_POLLING_SAFETY_MARGIN_MS) + await sleep(interval + OAUTH_POLLING_SAFETY_MARGIN_MS) } }, } diff --git a/packages/opencode/src/plugin/copilot.ts b/packages/opencode/src/plugin/copilot.ts index 39ea0d00d2..3945c63ce2 100644 --- a/packages/opencode/src/plugin/copilot.ts +++ b/packages/opencode/src/plugin/copilot.ts @@ -1,6 +1,7 @@ import type { Hooks, PluginInput } from "@opencode-ai/plugin" import { Installation } from "@/installation" import { iife } from "@/util/iife" +import { setTimeout as sleep } from "node:timers/promises" const CLIENT_ID = "Ov23li8tweQw6odWQebz" // Add a small safety buffer when polling to avoid hitting the server @@ -270,7 +271,7 @@ export async function CopilotAuthPlugin(input: PluginInput): Promise { } if (data.error === "authorization_pending") { - await Bun.sleep(deviceData.interval * 1000 + OAUTH_POLLING_SAFETY_MARGIN_MS) + await sleep(deviceData.interval * 1000 + OAUTH_POLLING_SAFETY_MARGIN_MS) continue } @@ -286,13 +287,13 @@ export async function CopilotAuthPlugin(input: PluginInput): Promise { newInterval = serverInterval * 1000 } - await Bun.sleep(newInterval + OAUTH_POLLING_SAFETY_MARGIN_MS) + await sleep(newInterval + OAUTH_POLLING_SAFETY_MARGIN_MS) continue } if (data.error) return { type: "failed" as const } - await Bun.sleep(deviceData.interval * 1000 + OAUTH_POLLING_SAFETY_MARGIN_MS) + await sleep(deviceData.interval * 1000 + OAUTH_POLLING_SAFETY_MARGIN_MS) continue } }, diff --git a/packages/opencode/src/provider/provider.ts b/packages/opencode/src/provider/provider.ts index 8170383652..b4836ae047 100644 --- a/packages/opencode/src/provider/provider.ts +++ b/packages/opencode/src/provider/provider.ts @@ -6,9 +6,10 @@ import { mapValues, mergeDeep, omit, pickBy, sortBy } from "remeda" import { NoSuchModelError, type Provider as SDK } from "ai" import { Log } from "../util/log" import { BunProc } from "../bun" +import { Hash } from "../util/hash" import { Plugin } from "../plugin" -import { ModelsDev } from "./models" import { NamedError } from "@opencode-ai/util/error" +import { ModelsDev } from "./models" import { Auth } from "../auth" import { Env } from "../env" import { Instance } from "../project/instance" @@ -795,7 +796,7 @@ export namespace Provider { const modelLoaders: { [providerID: string]: CustomModelLoader } = {} - const sdk = new Map() + const sdk = new Map() log.info("init") @@ -1085,7 +1086,7 @@ export namespace Provider { ...model.headers, } - const key = Bun.hash.xxHash32(JSON.stringify({ providerID: model.providerID, npm: model.api.npm, options })) + const key = Hash.fast(JSON.stringify({ providerID: model.providerID, npm: model.api.npm, options })) const existing = s.sdk.get(key) if (existing) return existing diff --git a/packages/opencode/src/shell/shell.ts b/packages/opencode/src/shell/shell.ts index e7b7cdb3e4..4779cfef75 100644 --- a/packages/opencode/src/shell/shell.ts +++ b/packages/opencode/src/shell/shell.ts @@ -3,6 +3,7 @@ import { lazy } from "@/util/lazy" import { Filesystem } from "@/util/filesystem" import path from "path" import { spawn, type ChildProcess } from "child_process" +import { setTimeout as sleep } from "node:timers/promises" const SIGKILL_TIMEOUT_MS = 200 @@ -22,13 +23,13 @@ export namespace Shell { try { process.kill(-pid, "SIGTERM") - await Bun.sleep(SIGKILL_TIMEOUT_MS) + await sleep(SIGKILL_TIMEOUT_MS) if (!opts?.exited?.()) { process.kill(-pid, "SIGKILL") } } catch (_e) { proc.kill("SIGTERM") - await Bun.sleep(SIGKILL_TIMEOUT_MS) + await sleep(SIGKILL_TIMEOUT_MS) if (!opts?.exited?.()) { proc.kill("SIGKILL") } diff --git a/packages/opencode/src/snapshot/index.ts b/packages/opencode/src/snapshot/index.ts index cf254b4cef..1acbdba092 100644 --- a/packages/opencode/src/snapshot/index.ts +++ b/packages/opencode/src/snapshot/index.ts @@ -1,6 +1,7 @@ import { $ } from "bun" import path from "path" import fs from "fs/promises" +import { Filesystem } from "../util/filesystem" import { Log } from "../util/log" import { Flag } from "../flag/flag" import { Global } from "../global" @@ -271,13 +272,12 @@ export namespace Snapshot { const target = path.join(git, "info", "exclude") await fs.mkdir(path.join(git, "info"), { recursive: true }) if (!file) { - await Bun.write(target, "") + await Filesystem.write(target, "") return } - const text = await Bun.file(file) - .text() - .catch(() => "") - await Bun.write(target, text) + const text = await Filesystem.readText(file).catch(() => "") + + await Filesystem.write(target, text) } async function excludes() { diff --git a/packages/opencode/src/util/hash.ts b/packages/opencode/src/util/hash.ts new file mode 100644 index 0000000000..680e0f40bc --- /dev/null +++ b/packages/opencode/src/util/hash.ts @@ -0,0 +1,7 @@ +import { createHash } from "crypto" + +export namespace Hash { + export function fast(input: string | Buffer): string { + return createHash("sha1").update(input).digest("hex") + } +} diff --git a/packages/opencode/test/preload.ts b/packages/opencode/test/preload.ts index 41028633e8..caac3bb0de 100644 --- a/packages/opencode/test/preload.ts +++ b/packages/opencode/test/preload.ts @@ -3,6 +3,7 @@ import os from "os" import path from "path" import fs from "fs/promises" +import { setTimeout as sleep } from "node:timers/promises" import { afterAll } from "bun:test" // Set XDG env vars FIRST, before any src/ imports @@ -15,7 +16,7 @@ afterAll(async () => { typeof error === "object" && error !== null && "code" in error && error.code === "EBUSY" const rm = async (left: number): Promise => { Bun.gc(true) - await Bun.sleep(100) + await sleep(100) return fs.rm(dir, { recursive: true, force: true }).catch((error) => { if (!busy(error)) throw error if (left <= 1) throw error diff --git a/packages/opencode/test/pty/pty-output-isolation.test.ts b/packages/opencode/test/pty/pty-output-isolation.test.ts index 44858a0ed2..ec1bbd4690 100644 --- a/packages/opencode/test/pty/pty-output-isolation.test.ts +++ b/packages/opencode/test/pty/pty-output-isolation.test.ts @@ -2,6 +2,7 @@ import { describe, expect, test } from "bun:test" import { Instance } from "../../src/project/instance" import { Pty } from "../../src/pty" import { tmpdir } from "../fixture/fixture" +import { setTimeout as sleep } from "node:timers/promises" describe("pty", () => { test("does not leak output when websocket objects are reused", async () => { @@ -43,7 +44,7 @@ describe("pty", () => { // Output from a must never show up in b. Pty.write(a.id, "AAA\n") - await Bun.sleep(100) + await sleep(100) expect(outB.join("")).not.toContain("AAA") } finally { @@ -88,7 +89,7 @@ describe("pty", () => { } Pty.write(a.id, "AAA\n") - await Bun.sleep(100) + await sleep(100) expect(outB.join("")).not.toContain("AAA") } finally { @@ -128,7 +129,7 @@ describe("pty", () => { ctx.connId = 2 Pty.write(a.id, "AAA\n") - await Bun.sleep(100) + await sleep(100) expect(out.join("")).toContain("AAA") } finally { diff --git a/packages/opencode/test/session/retry.test.ts b/packages/opencode/test/session/retry.test.ts index 6768e72d95..eba4a99505 100644 --- a/packages/opencode/test/session/retry.test.ts +++ b/packages/opencode/test/session/retry.test.ts @@ -1,6 +1,7 @@ import { describe, expect, test } from "bun:test" import type { NamedError } from "@opencode-ai/util/error" import { APICallError } from "ai" +import { setTimeout as sleep } from "node:timers/promises" import { SessionRetry } from "../../src/session/retry" import { MessageV2 } from "../../src/session/message-v2" @@ -135,7 +136,7 @@ describe("session.message-v2.fromError", () => { new ReadableStream({ async pull(controller) { controller.enqueue("Hello,") - await Bun.sleep(10000) + await sleep(10000) controller.enqueue(" World!") controller.close() }, diff --git a/packages/plugin/package.json b/packages/plugin/package.json index e57e83d051..d8911922ec 100644 --- a/packages/plugin/package.json +++ b/packages/plugin/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "@opencode-ai/plugin", - "version": "1.2.18", + "version": "1.2.19", "type": "module", "license": "MIT", "scripts": { diff --git a/packages/sdk/js/package.json b/packages/sdk/js/package.json index 22993464e3..fe3ce393d6 100644 --- a/packages/sdk/js/package.json +++ b/packages/sdk/js/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "@opencode-ai/sdk", - "version": "1.2.18", + "version": "1.2.19", "type": "module", "license": "MIT", "scripts": { diff --git a/packages/slack/package.json b/packages/slack/package.json index 1407c0e4a9..d37e140581 100644 --- a/packages/slack/package.json +++ b/packages/slack/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/slack", - "version": "1.2.18", + "version": "1.2.19", "type": "module", "license": "MIT", "scripts": { diff --git a/packages/ui/package.json b/packages/ui/package.json index 0adc4c57f1..48c668c6fb 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/ui", - "version": "1.2.18", + "version": "1.2.19", "type": "module", "license": "MIT", "exports": { diff --git a/packages/util/package.json b/packages/util/package.json index 87cf20591e..bc84be6360 100644 --- a/packages/util/package.json +++ b/packages/util/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/util", - "version": "1.2.18", + "version": "1.2.19", "private": true, "type": "module", "license": "MIT", diff --git a/packages/web/package.json b/packages/web/package.json index 4e7ac7cd8b..c85ba1a0b9 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -2,7 +2,7 @@ "name": "@opencode-ai/web", "type": "module", "license": "MIT", - "version": "1.2.18", + "version": "1.2.19", "scripts": { "dev": "astro dev", "dev:remote": "VITE_API_URL=https://api.opencode.ai astro dev", diff --git a/sdks/vscode/package.json b/sdks/vscode/package.json index 64307f053d..215143ac99 100644 --- a/sdks/vscode/package.json +++ b/sdks/vscode/package.json @@ -2,7 +2,7 @@ "name": "opencode", "displayName": "opencode", "description": "opencode for VS Code", - "version": "1.2.18", + "version": "1.2.19", "publisher": "sst-dev", "repository": { "type": "git",