2
0
Dax Raad 2 сар өмнө
parent
commit
13a77005f1

+ 8 - 9
packages/opencode/src/bus/index.ts

@@ -7,7 +7,13 @@ import { GlobalBus } from "./global"
 export namespace Bus {
   const log = Log.create({ service: "bus" })
   type Subscription = (event: any) => void
-  const disposedEventType = "server.instance.disposed"
+
+  export const InstanceDisposed = BusEvent.define(
+    "server.instance.disposed",
+    z.object({
+      directory: z.string(),
+    }),
+  )
 
   const state = Instance.state(
     () => {
@@ -21,7 +27,7 @@ export namespace Bus {
       const wildcard = entry.subscriptions.get("*")
       if (!wildcard) return
       const event = {
-        type: disposedEventType,
+        type: InstanceDisposed.type,
         properties: {
           directory: Instance.directory,
         },
@@ -32,13 +38,6 @@ export namespace Bus {
     },
   )
 
-  export const InstanceDisposed = BusEvent.define(
-    disposedEventType,
-    z.object({
-      directory: z.string(),
-    }),
-  )
-
   export async function publish<Definition extends BusEvent.Definition>(
     def: Definition,
     properties: z.output<Definition["properties"]>,

+ 30 - 0
packages/opencode/src/server/server.ts

@@ -56,6 +56,7 @@ export namespace Server {
 
   export const Event = {
     Connected: BusEvent.define("server.connected", z.object({})),
+    Disposed: BusEvent.define("global.disposed", z.object({})),
   }
 
   const app = new Hono()
@@ -140,6 +141,35 @@ export namespace Server {
           })
         },
       )
+      .post(
+        "/global/dispose",
+        describeRoute({
+          summary: "Dispose instance",
+          description: "Clean up and dispose all OpenCode instances, releasing all resources.",
+          operationId: "global.dispose",
+          responses: {
+            200: {
+              description: "Global disposed",
+              content: {
+                "application/json": {
+                  schema: resolver(z.boolean()),
+                },
+              },
+            },
+          },
+        }),
+        async (c) => {
+          await Instance.disposeAll()
+          GlobalBus.emit("event", {
+            directory: "global",
+            payload: {
+              type: Event.Disposed.type,
+              properties: {},
+            },
+          })
+          return c.json(true)
+        },
+      )
       .use(async (c, next) => {
         const directory = c.req.query("directory") ?? c.req.header("x-opencode-directory") ?? process.cwd()
         return Instance.provide({

+ 13 - 0
packages/sdk/js/src/v2/gen/sdk.gen.ts

@@ -28,6 +28,7 @@ import type {
   FindSymbolsResponses,
   FindTextResponses,
   FormatterStatusResponses,
+  GlobalDisposeResponses,
   GlobalEventResponses,
   InstanceDisposeResponses,
   LspStatusResponses,
@@ -193,6 +194,18 @@ export class Global extends HeyApiClient {
       ...options,
     })
   }
+
+  /**
+   * Dispose instance
+   *
+   * Clean up and dispose all OpenCode instances, releasing all resources.
+   */
+  public dispose<ThrowOnError extends boolean = false>(options?: Options<never, ThrowOnError>) {
+    return (options?.client ?? this.client).post<GlobalDisposeResponses, unknown, ThrowOnError>({
+      url: "/global/dispose",
+      ...options,
+    })
+  }
 }
 
 export class Project extends HeyApiClient {

+ 24 - 0
packages/sdk/js/src/v2/gen/types.gen.ts

@@ -725,6 +725,13 @@ export type EventServerConnected = {
   }
 }
 
+export type EventGlobalDisposed = {
+  type: "global.disposed"
+  properties: {
+    [key: string]: unknown
+  }
+}
+
 export type Event =
   | EventInstallationUpdated
   | EventInstallationUpdateAvailable
@@ -759,6 +766,7 @@ export type Event =
   | EventPtyExited
   | EventPtyDeleted
   | EventServerConnected
+  | EventGlobalDisposed
 
 export type GlobalEvent = {
   directory: string
@@ -1700,6 +1708,22 @@ export type GlobalEventResponses = {
 
 export type GlobalEventResponse = GlobalEventResponses[keyof GlobalEventResponses]
 
+export type GlobalDisposeData = {
+  body?: never
+  path?: never
+  query?: never
+  url: "/global/dispose"
+}
+
+export type GlobalDisposeResponses = {
+  /**
+   * Global disposed
+   */
+  200: boolean
+}
+
+export type GlobalDisposeResponse = GlobalDisposeResponses[keyof GlobalDisposeResponses]
+
 export type ProjectListData = {
   body?: never
   path?: never