Просмотр исходного кода

tui: fix SDK context usage and server port fallback

- Update SDK context to return client instead of event for proper usage
- Add server port fallback to 4096 when port 0 is specified but unavailable
- Fix SDK event listener usage in TUI app
Dax Raad 2 месяцев назад
Родитель
Сommit
2536e9f45b

+ 16 - 7
packages/opencode/src/cli/cmd/tui/app.tsx

@@ -169,7 +169,7 @@ function App() {
   const local = useLocal()
   const local = useLocal()
   const kv = useKV()
   const kv = useKV()
   const command = useCommandDialog()
   const command = useCommandDialog()
-  const { event } = useSDK()
+  const sdk = useSDK()
   const toast = useToast()
   const toast = useToast()
   const { theme, mode, setMode } = useTheme()
   const { theme, mode, setMode } = useTheme()
   const sync = useSync()
   const sync = useSync()
@@ -417,6 +417,15 @@ function App() {
       },
       },
       category: "System",
       category: "System",
     },
     },
+    {
+      title: "Open WebUI",
+      value: "webui.open",
+      onSelect: () => {
+        open(sdk.url).catch(() => {})
+        dialog.clear()
+      },
+      category: "System",
+    },
     {
     {
       title: "Exit the app",
       title: "Exit the app",
       value: "app.exit",
       value: "app.exit",
@@ -487,11 +496,11 @@ function App() {
     }
     }
   })
   })
 
 
-  event.on(TuiEvent.CommandExecute.type, (evt) => {
+  sdk.event.on(TuiEvent.CommandExecute.type, (evt) => {
     command.trigger(evt.properties.command)
     command.trigger(evt.properties.command)
   })
   })
 
 
-  event.on(TuiEvent.ToastShow.type, (evt) => {
+  sdk.event.on(TuiEvent.ToastShow.type, (evt) => {
     toast.show({
     toast.show({
       title: evt.properties.title,
       title: evt.properties.title,
       message: evt.properties.message,
       message: evt.properties.message,
@@ -500,7 +509,7 @@ function App() {
     })
     })
   })
   })
 
 
-  event.on(SessionApi.Event.Deleted.type, (evt) => {
+  sdk.event.on(SessionApi.Event.Deleted.type, (evt) => {
     if (route.data.type === "session" && route.data.sessionID === evt.properties.info.id) {
     if (route.data.type === "session" && route.data.sessionID === evt.properties.info.id) {
       route.navigate({ type: "home" })
       route.navigate({ type: "home" })
       toast.show({
       toast.show({
@@ -510,7 +519,7 @@ function App() {
     }
     }
   })
   })
 
 
-  event.on(SessionApi.Event.Error.type, (evt) => {
+  sdk.event.on(SessionApi.Event.Error.type, (evt) => {
     const error = evt.properties.error
     const error = evt.properties.error
     const message = (() => {
     const message = (() => {
       if (!error) return "An error occured"
       if (!error) return "An error occured"
@@ -531,7 +540,7 @@ function App() {
     })
     })
   })
   })
 
 
-  event.on(Installation.Event.Updated.type, (evt) => {
+  sdk.event.on(Installation.Event.Updated.type, (evt) => {
     toast.show({
     toast.show({
       variant: "success",
       variant: "success",
       title: "Update Complete",
       title: "Update Complete",
@@ -540,7 +549,7 @@ function App() {
     })
     })
   })
   })
 
 
-  event.on(Installation.Event.UpdateAvailable.type, (evt) => {
+  sdk.event.on(Installation.Event.UpdateAvailable.type, (evt) => {
     toast.show({
     toast.show({
       variant: "info",
       variant: "info",
       title: "Update Available",
       title: "Update Available",

+ 1 - 2
packages/opencode/src/cli/cmd/tui/context/sdk.tsx

@@ -2,7 +2,6 @@ import { createOpencodeClient, type Event } from "@opencode-ai/sdk/v2"
 import { createSimpleContext } from "./helper"
 import { createSimpleContext } from "./helper"
 import { createGlobalEmitter } from "@solid-primitives/event-bus"
 import { createGlobalEmitter } from "@solid-primitives/event-bus"
 import { batch, onCleanup, onMount } from "solid-js"
 import { batch, onCleanup, onMount } from "solid-js"
-import { iife } from "@/util/iife"
 
 
 export const { use: useSDK, provider: SDKProvider } = createSimpleContext({
 export const { use: useSDK, provider: SDKProvider } = createSimpleContext({
   name: "SDK",
   name: "SDK",
@@ -70,6 +69,6 @@ export const { use: useSDK, provider: SDKProvider } = createSimpleContext({
       abort.abort()
       abort.abort()
     })
     })
 
 
-    return { client: sdk, event: emitter }
+    return { client: sdk, event: emitter, url: props.url }
   },
   },
 })
 })

+ 10 - 4
packages/opencode/src/server/server.ts

@@ -2601,13 +2601,19 @@ export namespace Server {
   }
   }
 
 
   export function listen(opts: { port: number; hostname: string }) {
   export function listen(opts: { port: number; hostname: string }) {
-    const server = Bun.serve({
-      port: opts.port,
+    const args = {
       hostname: opts.hostname,
       hostname: opts.hostname,
       idleTimeout: 0,
       idleTimeout: 0,
       fetch: App().fetch,
       fetch: App().fetch,
       websocket: websocket,
       websocket: websocket,
-    })
-    return server
+    } as const
+    if (opts.port === 0) {
+      try {
+        return Bun.serve({ ...args, port: 4096 })
+      } catch {
+        // port 4096 not available, fall through to use port 0
+      }
+    }
+    return Bun.serve({ ...args, port: opts.port })
   }
   }
 }
 }