1- import type { Event } from "@opencode-ai/sdk/v2/client"
1+ import {
2+ createOpencodeClient as createEventClient ,
3+ type Event as LegacyEvent ,
4+ type GlobalEvent as LegacyGlobalEvent ,
5+ } from "@opencode-ai/sdk/client"
6+ import type { Event as CurrentEvent , GlobalEvent as CurrentGlobalEvent } from "@opencode-ai/sdk/v2/client"
27import { createSimpleContext } from "@opencode-ai/ui/context"
38import { createGlobalEmitter } from "@solid-primitives/event-bus"
49import { makeEventListener } from "@solid-primitives/event-listener"
510import { batch , onCleanup , onMount } from "solid-js"
6- import { createSdkForServer } from "@/utils/server"
11+ import { authTokenFromCredentials , createSdkForServer } from "@/utils/server"
712import { useLanguage } from "./language"
813import { usePlatform } from "./platform"
914import { useServer } from "./server"
1015
1116const isAbortError = ( error : unknown ) =>
1217 error !== null && typeof error === "object" && "name" in error && error . name === "AbortError"
1318
19+ export type GlobalSDKEvent = CurrentEvent | LegacyEvent
20+ type StreamEvent = CurrentGlobalEvent | LegacyGlobalEvent
21+
1422export const { use : useGlobalSDK , provider : GlobalSDKProvider } = createSimpleContext ( {
1523 name : "GlobalSDK" ,
1624 init : ( ) => {
@@ -33,16 +41,25 @@ export const { use: useGlobalSDK, provider: GlobalSDKProvider } = createSimpleCo
3341 const currentServer = server . current
3442 if ( ! currentServer ) throw new Error ( language . t ( "error.globalSDK.noServerAvailable" ) )
3543
36- const eventSdk = createSdkForServer ( {
44+ // Keep /global/event on the legacy SDK until the EventV2 stream contract is stable.
45+ const eventSdk = createEventClient ( {
3746 signal : abort . signal ,
3847 fetch : eventFetch ,
39- server : currentServer . http ,
48+ baseUrl : currentServer . http . url ,
49+ headers : currentServer . http . password
50+ ? {
51+ Authorization : `Basic ${ authTokenFromCredentials ( {
52+ username : currentServer . http . username ,
53+ password : currentServer . http . password ,
54+ } ) } `,
55+ }
56+ : undefined ,
4057 } )
4158 const emitter = createGlobalEmitter < {
42- [ key : string ] : Event
59+ [ key : string ] : GlobalSDKEvent
4360 } > ( )
4461
45- type Queued = { directory : string ; payload : Event }
62+ type Queued = { directory : string ; payload : GlobalSDKEvent }
4663 const FLUSH_FRAME_MS = 16
4764 const STREAM_YIELD_MS = 8
4865 const RECONNECT_DELAY_MS = 250
@@ -56,7 +73,7 @@ export const { use: useGlobalSDK, provider: GlobalSDKProvider } = createSimpleCo
5673
5774 const deltaKey = ( directory : string , messageID : string , partID : string ) => `${ directory } :${ messageID } :${ partID } `
5875
59- const key = ( directory : string , payload : Event ) => {
76+ const key = ( directory : string , payload : GlobalSDKEvent ) => {
6077 if ( payload . type === "session.status" ) return `session.status:${ directory } :${ payload . properties . sessionID } `
6178 if ( payload . type === "lsp.updated" ) return `lsp.updated:${ directory } `
6279 if ( payload . type === "message.part.updated" ) {
@@ -150,15 +167,16 @@ export const { use: useGlobalSDK, provider: GlobalSDKProvider } = createSimpleCo
150167 } )
151168 let yielded = Date . now ( )
152169 resetHeartbeat ( )
153- for await ( const event of events . stream ) {
170+ const stream : AsyncIterable < StreamEvent > = events . stream
171+ for await ( const event of stream ) {
154172 resetHeartbeat ( )
155173 streamErrorLogged = false
156174 const directory = event . directory ?? "global"
157175 if ( event . payload . type === "sync" ) {
158176 continue
159177 }
160178
161- const payload = event . payload as Event
179+ const payload = event . payload
162180
163181 const k = key ( directory , payload )
164182 if ( k ) {
0 commit comments