mirror of
https://github.com/anomalyco/opencode.git
synced 2026-02-18 14:54:17 +00:00
Compare commits
2 Commits
codex-auth
...
v1.1.10
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
563b4c33f2 | ||
|
|
982b71e861 |
30
bun.lock
30
bun.lock
@@ -22,7 +22,7 @@
|
||||
},
|
||||
"packages/app": {
|
||||
"name": "@opencode-ai/app",
|
||||
"version": "1.1.8",
|
||||
"version": "1.1.10",
|
||||
"dependencies": {
|
||||
"@kobalte/core": "catalog:",
|
||||
"@opencode-ai/sdk": "workspace:*",
|
||||
@@ -70,7 +70,7 @@
|
||||
},
|
||||
"packages/console/app": {
|
||||
"name": "@opencode-ai/console-app",
|
||||
"version": "1.1.8",
|
||||
"version": "1.1.10",
|
||||
"dependencies": {
|
||||
"@cloudflare/vite-plugin": "1.15.2",
|
||||
"@ibm/plex": "6.4.1",
|
||||
@@ -98,7 +98,7 @@
|
||||
},
|
||||
"packages/console/core": {
|
||||
"name": "@opencode-ai/console-core",
|
||||
"version": "1.1.8",
|
||||
"version": "1.1.10",
|
||||
"dependencies": {
|
||||
"@aws-sdk/client-sts": "3.782.0",
|
||||
"@jsx-email/render": "1.1.1",
|
||||
@@ -125,7 +125,7 @@
|
||||
},
|
||||
"packages/console/function": {
|
||||
"name": "@opencode-ai/console-function",
|
||||
"version": "1.1.8",
|
||||
"version": "1.1.10",
|
||||
"dependencies": {
|
||||
"@ai-sdk/anthropic": "2.0.0",
|
||||
"@ai-sdk/openai": "2.0.2",
|
||||
@@ -149,7 +149,7 @@
|
||||
},
|
||||
"packages/console/mail": {
|
||||
"name": "@opencode-ai/console-mail",
|
||||
"version": "1.1.8",
|
||||
"version": "1.1.10",
|
||||
"dependencies": {
|
||||
"@jsx-email/all": "2.2.3",
|
||||
"@jsx-email/cli": "1.4.3",
|
||||
@@ -173,7 +173,7 @@
|
||||
},
|
||||
"packages/desktop": {
|
||||
"name": "@opencode-ai/desktop",
|
||||
"version": "1.1.8",
|
||||
"version": "1.1.10",
|
||||
"dependencies": {
|
||||
"@opencode-ai/app": "workspace:*",
|
||||
"@opencode-ai/ui": "workspace:*",
|
||||
@@ -202,7 +202,7 @@
|
||||
},
|
||||
"packages/enterprise": {
|
||||
"name": "@opencode-ai/enterprise",
|
||||
"version": "1.1.8",
|
||||
"version": "1.1.10",
|
||||
"dependencies": {
|
||||
"@opencode-ai/ui": "workspace:*",
|
||||
"@opencode-ai/util": "workspace:*",
|
||||
@@ -231,7 +231,7 @@
|
||||
},
|
||||
"packages/function": {
|
||||
"name": "@opencode-ai/function",
|
||||
"version": "1.1.8",
|
||||
"version": "1.1.10",
|
||||
"dependencies": {
|
||||
"@octokit/auth-app": "8.0.1",
|
||||
"@octokit/rest": "catalog:",
|
||||
@@ -247,7 +247,7 @@
|
||||
},
|
||||
"packages/opencode": {
|
||||
"name": "opencode",
|
||||
"version": "1.1.8",
|
||||
"version": "1.1.10",
|
||||
"bin": {
|
||||
"opencode": "./bin/opencode",
|
||||
},
|
||||
@@ -350,7 +350,7 @@
|
||||
},
|
||||
"packages/plugin": {
|
||||
"name": "@opencode-ai/plugin",
|
||||
"version": "1.1.8",
|
||||
"version": "1.1.10",
|
||||
"dependencies": {
|
||||
"@opencode-ai/sdk": "workspace:*",
|
||||
"zod": "catalog:",
|
||||
@@ -370,7 +370,7 @@
|
||||
},
|
||||
"packages/sdk/js": {
|
||||
"name": "@opencode-ai/sdk",
|
||||
"version": "1.1.8",
|
||||
"version": "1.1.10",
|
||||
"devDependencies": {
|
||||
"@hey-api/openapi-ts": "0.88.1",
|
||||
"@tsconfig/node22": "catalog:",
|
||||
@@ -381,7 +381,7 @@
|
||||
},
|
||||
"packages/slack": {
|
||||
"name": "@opencode-ai/slack",
|
||||
"version": "1.1.8",
|
||||
"version": "1.1.10",
|
||||
"dependencies": {
|
||||
"@opencode-ai/sdk": "workspace:*",
|
||||
"@slack/bolt": "^3.17.1",
|
||||
@@ -394,7 +394,7 @@
|
||||
},
|
||||
"packages/ui": {
|
||||
"name": "@opencode-ai/ui",
|
||||
"version": "1.1.8",
|
||||
"version": "1.1.10",
|
||||
"dependencies": {
|
||||
"@kobalte/core": "catalog:",
|
||||
"@opencode-ai/sdk": "workspace:*",
|
||||
@@ -433,7 +433,7 @@
|
||||
},
|
||||
"packages/util": {
|
||||
"name": "@opencode-ai/util",
|
||||
"version": "1.1.8",
|
||||
"version": "1.1.10",
|
||||
"dependencies": {
|
||||
"zod": "catalog:",
|
||||
},
|
||||
@@ -444,7 +444,7 @@
|
||||
},
|
||||
"packages/web": {
|
||||
"name": "@opencode-ai/web",
|
||||
"version": "1.1.8",
|
||||
"version": "1.1.10",
|
||||
"dependencies": {
|
||||
"@astrojs/cloudflare": "12.6.3",
|
||||
"@astrojs/markdown-remark": "6.3.1",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@opencode-ai/app",
|
||||
"version": "1.1.8",
|
||||
"version": "1.1.10",
|
||||
"description": "",
|
||||
"type": "module",
|
||||
"exports": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@opencode-ai/console-app",
|
||||
"version": "1.1.8",
|
||||
"version": "1.1.10",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/package.json",
|
||||
"name": "@opencode-ai/console-core",
|
||||
"version": "1.1.8",
|
||||
"version": "1.1.10",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@opencode-ai/console-function",
|
||||
"version": "1.1.8",
|
||||
"version": "1.1.10",
|
||||
"$schema": "https://json.schemastore.org/package.json",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@opencode-ai/console-mail",
|
||||
"version": "1.1.8",
|
||||
"version": "1.1.10",
|
||||
"dependencies": {
|
||||
"@jsx-email/all": "2.2.3",
|
||||
"@jsx-email/cli": "1.4.3",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@opencode-ai/desktop",
|
||||
"private": true,
|
||||
"version": "1.1.8",
|
||||
"version": "1.1.10",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@opencode-ai/enterprise",
|
||||
"version": "1.1.8",
|
||||
"version": "1.1.10",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
id = "opencode"
|
||||
name = "OpenCode"
|
||||
description = "The open source coding agent."
|
||||
version = "1.1.8"
|
||||
version = "1.1.10"
|
||||
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.1.8/opencode-darwin-arm64.zip"
|
||||
archive = "https://github.com/anomalyco/opencode/releases/download/v1.1.10/opencode-darwin-arm64.zip"
|
||||
cmd = "./opencode"
|
||||
args = ["acp"]
|
||||
|
||||
[agent_servers.opencode.targets.darwin-x86_64]
|
||||
archive = "https://github.com/anomalyco/opencode/releases/download/v1.1.8/opencode-darwin-x64.zip"
|
||||
archive = "https://github.com/anomalyco/opencode/releases/download/v1.1.10/opencode-darwin-x64.zip"
|
||||
cmd = "./opencode"
|
||||
args = ["acp"]
|
||||
|
||||
[agent_servers.opencode.targets.linux-aarch64]
|
||||
archive = "https://github.com/anomalyco/opencode/releases/download/v1.1.8/opencode-linux-arm64.tar.gz"
|
||||
archive = "https://github.com/anomalyco/opencode/releases/download/v1.1.10/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.1.8/opencode-linux-x64.tar.gz"
|
||||
archive = "https://github.com/anomalyco/opencode/releases/download/v1.1.10/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.1.8/opencode-windows-x64.zip"
|
||||
archive = "https://github.com/anomalyco/opencode/releases/download/v1.1.10/opencode-windows-x64.zip"
|
||||
cmd = "./opencode.exe"
|
||||
args = ["acp"]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@opencode-ai/function",
|
||||
"version": "1.1.8",
|
||||
"version": "1.1.10",
|
||||
"$schema": "https://json.schemastore.org/package.json",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/package.json",
|
||||
"version": "1.1.8",
|
||||
"version": "1.1.10",
|
||||
"name": "opencode",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
|
||||
@@ -97,7 +97,16 @@ async function getTerminalBackgroundColor(): Promise<"dark" | "light"> {
|
||||
})
|
||||
}
|
||||
|
||||
export function tui(input: { url: string; args: Args; directory?: string; onExit?: () => Promise<void> }) {
|
||||
import type { EventSource } from "./context/sdk"
|
||||
|
||||
export function tui(input: {
|
||||
url: string
|
||||
args: Args
|
||||
directory?: string
|
||||
fetch?: typeof fetch
|
||||
events?: EventSource
|
||||
onExit?: () => Promise<void>
|
||||
}) {
|
||||
// promise to prevent immediate exit
|
||||
return new Promise<void>(async (resolve) => {
|
||||
const mode = await getTerminalBackgroundColor()
|
||||
@@ -117,7 +126,12 @@ export function tui(input: { url: string; args: Args; directory?: string; onExit
|
||||
<KVProvider>
|
||||
<ToastProvider>
|
||||
<RouteProvider>
|
||||
<SDKProvider url={input.url} directory={input.directory}>
|
||||
<SDKProvider
|
||||
url={input.url}
|
||||
directory={input.directory}
|
||||
fetch={input.fetch}
|
||||
events={input.events}
|
||||
>
|
||||
<SyncProvider>
|
||||
<ThemeProvider mode={mode}>
|
||||
<LocalProvider>
|
||||
|
||||
@@ -3,21 +3,66 @@ import { createSimpleContext } from "./helper"
|
||||
import { createGlobalEmitter } from "@solid-primitives/event-bus"
|
||||
import { batch, onCleanup, onMount } from "solid-js"
|
||||
|
||||
export type EventSource = {
|
||||
on: (handler: (event: Event) => void) => () => void
|
||||
}
|
||||
|
||||
export const { use: useSDK, provider: SDKProvider } = createSimpleContext({
|
||||
name: "SDK",
|
||||
init: (props: { url: string; directory?: string }) => {
|
||||
init: (props: { url: string; directory?: string; fetch?: typeof fetch; events?: EventSource }) => {
|
||||
const abort = new AbortController()
|
||||
const sdk = createOpencodeClient({
|
||||
baseUrl: props.url,
|
||||
signal: abort.signal,
|
||||
directory: props.directory,
|
||||
fetch: props.fetch,
|
||||
})
|
||||
|
||||
const emitter = createGlobalEmitter<{
|
||||
[key in Event["type"]]: Extract<Event, { type: key }>
|
||||
}>()
|
||||
|
||||
let queue: Event[] = []
|
||||
let timer: Timer | undefined
|
||||
let last = 0
|
||||
|
||||
const flush = () => {
|
||||
if (queue.length === 0) return
|
||||
const events = queue
|
||||
queue = []
|
||||
timer = undefined
|
||||
last = Date.now()
|
||||
// Batch all event emissions so all store updates result in a single render
|
||||
batch(() => {
|
||||
for (const event of events) {
|
||||
emitter.emit(event.type, event)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const handleEvent = (event: Event) => {
|
||||
queue.push(event)
|
||||
const elapsed = Date.now() - last
|
||||
|
||||
if (timer) return
|
||||
// If we just flushed recently (within 16ms), batch this with future events
|
||||
// Otherwise, process immediately to avoid latency
|
||||
if (elapsed < 16) {
|
||||
timer = setTimeout(flush, 16)
|
||||
return
|
||||
}
|
||||
flush()
|
||||
}
|
||||
|
||||
onMount(async () => {
|
||||
// If an event source is provided, use it instead of SSE
|
||||
if (props.events) {
|
||||
const unsub = props.events.on(handleEvent)
|
||||
onCleanup(unsub)
|
||||
return
|
||||
}
|
||||
|
||||
// Fall back to SSE
|
||||
while (true) {
|
||||
if (abort.signal.aborted) break
|
||||
const events = await sdk.event.subscribe(
|
||||
@@ -26,36 +71,9 @@ export const { use: useSDK, provider: SDKProvider } = createSimpleContext({
|
||||
signal: abort.signal,
|
||||
},
|
||||
)
|
||||
let queue: Event[] = []
|
||||
let timer: Timer | undefined
|
||||
let last = 0
|
||||
|
||||
const flush = () => {
|
||||
if (queue.length === 0) return
|
||||
const events = queue
|
||||
queue = []
|
||||
timer = undefined
|
||||
last = Date.now()
|
||||
// Batch all event emissions so all store updates result in a single render
|
||||
batch(() => {
|
||||
for (const event of events) {
|
||||
emitter.emit(event.type, event)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
for await (const event of events.stream) {
|
||||
queue.push(event)
|
||||
const elapsed = Date.now() - last
|
||||
|
||||
if (timer) continue
|
||||
// If we just flushed recently (within 16ms), batch this with future events
|
||||
// Otherwise, process immediately to avoid latency
|
||||
if (elapsed < 16) {
|
||||
timer = setTimeout(flush, 16)
|
||||
continue
|
||||
}
|
||||
flush()
|
||||
handleEvent(event)
|
||||
}
|
||||
|
||||
// Flush any remaining events
|
||||
@@ -68,6 +86,7 @@ export const { use: useSDK, provider: SDKProvider } = createSimpleContext({
|
||||
|
||||
onCleanup(() => {
|
||||
abort.abort()
|
||||
if (timer) clearTimeout(timer)
|
||||
})
|
||||
|
||||
return { client: sdk, event: emitter, url: props.url }
|
||||
|
||||
@@ -7,11 +7,39 @@ import { UI } from "@/cli/ui"
|
||||
import { iife } from "@/util/iife"
|
||||
import { Log } from "@/util/log"
|
||||
import { withNetworkOptions, resolveNetworkOptions } from "@/cli/network"
|
||||
import type { Event } from "@opencode-ai/sdk/v2"
|
||||
import type { EventSource } from "./context/sdk"
|
||||
|
||||
declare global {
|
||||
const OPENCODE_WORKER_PATH: string
|
||||
}
|
||||
|
||||
type RpcClient = ReturnType<typeof Rpc.client<typeof rpc>>
|
||||
|
||||
function createWorkerFetch(client: RpcClient): typeof fetch {
|
||||
const fn = async (input: RequestInfo | URL, init?: RequestInit): Promise<Response> => {
|
||||
const request = new Request(input, init)
|
||||
const body = request.body ? await request.text() : undefined
|
||||
const result = await client.call("fetch", {
|
||||
url: request.url,
|
||||
method: request.method,
|
||||
headers: Object.fromEntries(request.headers.entries()),
|
||||
body,
|
||||
})
|
||||
return new Response(result.body, {
|
||||
status: result.status,
|
||||
headers: result.headers,
|
||||
})
|
||||
}
|
||||
return fn as typeof fetch
|
||||
}
|
||||
|
||||
function createEventSource(client: RpcClient): EventSource {
|
||||
return {
|
||||
on: (handler) => client.on<Event>("event", handler),
|
||||
}
|
||||
}
|
||||
|
||||
export const TuiThreadCommand = cmd({
|
||||
command: "$0 [project]",
|
||||
describe: "start opencode tui",
|
||||
@@ -80,16 +108,45 @@ export const TuiThreadCommand = cmd({
|
||||
process.on("SIGUSR2", async () => {
|
||||
await client.call("reload", undefined)
|
||||
})
|
||||
const opts = await resolveNetworkOptions(args)
|
||||
const server = await client.call("server", opts)
|
||||
|
||||
const prompt = await iife(async () => {
|
||||
const piped = !process.stdin.isTTY ? await Bun.stdin.text() : undefined
|
||||
if (!args.prompt) return piped
|
||||
return piped ? piped + "\n" + args.prompt : args.prompt
|
||||
})
|
||||
|
||||
// Check if server should be started (port or hostname explicitly set in CLI or config)
|
||||
const networkOpts = await resolveNetworkOptions(args)
|
||||
const shouldStartServer =
|
||||
process.argv.includes("--port") ||
|
||||
process.argv.includes("--hostname") ||
|
||||
process.argv.includes("--mdns") ||
|
||||
networkOpts.mdns ||
|
||||
networkOpts.port !== 0 ||
|
||||
networkOpts.hostname !== "127.0.0.1"
|
||||
|
||||
// Subscribe to events from worker
|
||||
await client.call("subscribe", { directory: cwd })
|
||||
|
||||
let url: string
|
||||
let customFetch: typeof fetch | undefined
|
||||
let events: EventSource | undefined
|
||||
|
||||
if (shouldStartServer) {
|
||||
// Start HTTP server for external access
|
||||
const server = await client.call("server", networkOpts)
|
||||
url = server.url
|
||||
} else {
|
||||
// Use direct RPC communication (no HTTP)
|
||||
url = "http://opencode.internal"
|
||||
customFetch = createWorkerFetch(client)
|
||||
events = createEventSource(client)
|
||||
}
|
||||
|
||||
const tuiPromise = tui({
|
||||
url: server.url,
|
||||
url,
|
||||
fetch: customFetch,
|
||||
events,
|
||||
args: {
|
||||
continue: args.continue,
|
||||
sessionID: args.session,
|
||||
|
||||
@@ -5,8 +5,10 @@ import { Instance } from "@/project/instance"
|
||||
import { InstanceBootstrap } from "@/project/bootstrap"
|
||||
import { Rpc } from "@/util/rpc"
|
||||
import { upgrade } from "@/cli/upgrade"
|
||||
import type { BunWebSocketData } from "hono/bun"
|
||||
import { Config } from "@/config/config"
|
||||
import { Bus } from "@/bus"
|
||||
import { GlobalBus } from "@/bus/global"
|
||||
import type { BunWebSocketData } from "hono/bun"
|
||||
|
||||
await Log.init({
|
||||
print: process.argv.includes("--print-logs"),
|
||||
@@ -29,20 +31,47 @@ process.on("uncaughtException", (e) => {
|
||||
})
|
||||
})
|
||||
|
||||
let server: Bun.Server<BunWebSocketData>
|
||||
// Subscribe to global events and forward them via RPC
|
||||
GlobalBus.on("event", (event) => {
|
||||
Rpc.emit("global.event", event)
|
||||
})
|
||||
|
||||
let server: Bun.Server<BunWebSocketData> | undefined
|
||||
|
||||
export const rpc = {
|
||||
async server(input: { port: number; hostname: string; mdns?: boolean }) {
|
||||
if (server) await server.stop(true)
|
||||
try {
|
||||
server = Server.listen(input)
|
||||
return {
|
||||
url: server.url.toString(),
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
throw e
|
||||
async fetch(input: { url: string; method: string; headers: Record<string, string>; body?: string }) {
|
||||
const request = new Request(input.url, {
|
||||
method: input.method,
|
||||
headers: input.headers,
|
||||
body: input.body,
|
||||
})
|
||||
const response = await Server.App().fetch(request)
|
||||
const body = await response.text()
|
||||
return {
|
||||
status: response.status,
|
||||
headers: Object.fromEntries(response.headers.entries()),
|
||||
body,
|
||||
}
|
||||
},
|
||||
async server(input: { port: number; hostname: string; mdns?: boolean; cors?: string[] }) {
|
||||
if (server) await server.stop(true)
|
||||
server = Server.listen(input)
|
||||
return { url: server.url.toString() }
|
||||
},
|
||||
async subscribe(input: { directory: string }) {
|
||||
return Instance.provide({
|
||||
directory: input.directory,
|
||||
init: InstanceBootstrap,
|
||||
fn: async () => {
|
||||
Bus.subscribeAll((event) => {
|
||||
Rpc.emit("event", event)
|
||||
})
|
||||
// Emit connected event
|
||||
Rpc.emit("event", { type: "server.connected", properties: {} })
|
||||
return { subscribed: true }
|
||||
},
|
||||
})
|
||||
},
|
||||
async checkUpgrade(input: { directory: string }) {
|
||||
await Instance.provide({
|
||||
directory: input.directory,
|
||||
@@ -59,9 +88,7 @@ export const rpc = {
|
||||
async shutdown() {
|
||||
Log.Default.info("worker shutting down")
|
||||
await Instance.disposeAll()
|
||||
// TODO: this should be awaited, but ws connections are
|
||||
// causing this to hang, need to revisit this
|
||||
server.stop(true)
|
||||
if (server) server.stop(true)
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -2826,6 +2826,10 @@ export namespace Server {
|
||||
host: "app.opencode.ai",
|
||||
},
|
||||
})
|
||||
response.headers.set(
|
||||
"Content-Security-Policy",
|
||||
"default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; connect-src 'self'",
|
||||
)
|
||||
return response
|
||||
}) as unknown as Hono,
|
||||
)
|
||||
|
||||
@@ -13,11 +13,16 @@ export namespace Rpc {
|
||||
}
|
||||
}
|
||||
|
||||
export function emit(event: string, data: unknown) {
|
||||
postMessage(JSON.stringify({ type: "rpc.event", event, data }))
|
||||
}
|
||||
|
||||
export function client<T extends Definition>(target: {
|
||||
postMessage: (data: string) => void | null
|
||||
onmessage: ((this: Worker, ev: MessageEvent<any>) => any) | null
|
||||
}) {
|
||||
const pending = new Map<number, (result: any) => void>()
|
||||
const listeners = new Map<string, Set<(data: any) => void>>()
|
||||
let id = 0
|
||||
target.onmessage = async (evt) => {
|
||||
const parsed = JSON.parse(evt.data)
|
||||
@@ -28,6 +33,14 @@ export namespace Rpc {
|
||||
pending.delete(parsed.id)
|
||||
}
|
||||
}
|
||||
if (parsed.type === "rpc.event") {
|
||||
const handlers = listeners.get(parsed.event)
|
||||
if (handlers) {
|
||||
for (const handler of handlers) {
|
||||
handler(parsed.data)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return {
|
||||
call<Method extends keyof T>(method: Method, input: Parameters<T[Method]>[0]): Promise<ReturnType<T[Method]>> {
|
||||
@@ -37,6 +50,17 @@ export namespace Rpc {
|
||||
target.postMessage(JSON.stringify({ type: "rpc.request", method, input, id: requestId }))
|
||||
})
|
||||
},
|
||||
on<Data>(event: string, handler: (data: Data) => void) {
|
||||
let handlers = listeners.get(event)
|
||||
if (!handlers) {
|
||||
handlers = new Set()
|
||||
listeners.set(event, handlers)
|
||||
}
|
||||
handlers.add(handler)
|
||||
return () => {
|
||||
handlers!.delete(handler)
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/package.json",
|
||||
"name": "@opencode-ai/plugin",
|
||||
"version": "1.1.8",
|
||||
"version": "1.1.10",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
@@ -25,4 +25,4 @@
|
||||
"typescript": "catalog:",
|
||||
"@typescript/native-preview": "catalog:"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/package.json",
|
||||
"name": "@opencode-ai/sdk",
|
||||
"version": "1.1.8",
|
||||
"version": "1.1.10",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
@@ -30,4 +30,4 @@
|
||||
"publishConfig": {
|
||||
"directory": "dist"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@opencode-ai/slack",
|
||||
"version": "1.1.8",
|
||||
"version": "1.1.10",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@opencode-ai/ui",
|
||||
"version": "1.1.8",
|
||||
"version": "1.1.10",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
"exports": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@opencode-ai/util",
|
||||
"version": "1.1.8",
|
||||
"version": "1.1.10",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"name": "@opencode-ai/web",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
"version": "1.1.8",
|
||||
"version": "1.1.10",
|
||||
"scripts": {
|
||||
"dev": "astro dev",
|
||||
"dev:remote": "VITE_API_URL=https://api.opencode.ai astro dev",
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"name": "opencode",
|
||||
"displayName": "opencode",
|
||||
"description": "opencode for VS Code",
|
||||
"version": "1.1.8",
|
||||
"version": "1.1.10",
|
||||
"publisher": "sst-dev",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
||||
Reference in New Issue
Block a user