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

Replace Instance.disposeAll/load with fixture helper (#25418)

Kit Langton 4 месяцев назад
Родитель
Сommit
4c4860fb24
59 измененных файлов с 139 добавлено и 130 удалено
  1. 2 2
      packages/opencode/src/cli/bootstrap.ts
  2. 2 1
      packages/opencode/src/cli/cmd/tui/worker.ts
  3. 9 3
      packages/opencode/src/config/config.ts
  4. 2 0
      packages/opencode/src/effect/app-runtime.ts
  5. 3 8
      packages/opencode/src/project/instance.ts
  6. 2 2
      packages/opencode/src/server/routes/global.ts
  7. 2 1
      packages/opencode/src/server/routes/instance/index.ts
  8. 1 5
      packages/opencode/src/server/routes/instance/project.ts
  9. 2 2
      packages/opencode/test/agent/agent.test.ts
  10. 2 2
      packages/opencode/test/bus/bus-effect.test.ts
  11. 3 3
      packages/opencode/test/bus/bus-integration.test.ts
  12. 4 4
      packages/opencode/test/bus/bus.test.ts
  13. 2 2
      packages/opencode/test/config/config.test.ts
  14. 2 2
      packages/opencode/test/control-plane/workspace.test.ts
  15. 3 3
      packages/opencode/test/effect/instance-state.test.ts
  16. 3 3
      packages/opencode/test/file/index.test.ts
  17. 2 2
      packages/opencode/test/file/watcher.test.ts
  18. 2 2
      packages/opencode/test/fixture/db.ts
  19. 8 0
      packages/opencode/test/fixture/fixture.ts
  20. 2 2
      packages/opencode/test/permission-task.test.ts
  21. 2 2
      packages/opencode/test/permission/next.test.ts
  22. 2 2
      packages/opencode/test/plugin/loader-shared.test.ts
  23. 2 2
      packages/opencode/test/plugin/workspace-adapter.test.ts
  24. 2 2
      packages/opencode/test/project/instance.test.ts
  25. 3 3
      packages/opencode/test/project/vcs.test.ts
  26. 2 2
      packages/opencode/test/project/worktree.test.ts
  27. 2 2
      packages/opencode/test/provider/provider.test.ts
  28. 2 2
      packages/opencode/test/question/question.test.ts
  29. 2 2
      packages/opencode/test/server/httpapi-bridge.test.ts
  30. 2 2
      packages/opencode/test/server/httpapi-config.test.ts
  31. 2 2
      packages/opencode/test/server/httpapi-event.test.ts
  32. 2 2
      packages/opencode/test/server/httpapi-experimental.test.ts
  33. 2 2
      packages/opencode/test/server/httpapi-file.test.ts
  34. 2 2
      packages/opencode/test/server/httpapi-instance-context.test.ts
  35. 2 2
      packages/opencode/test/server/httpapi-instance.legacy.test.ts
  36. 2 2
      packages/opencode/test/server/httpapi-instance.test.ts
  37. 2 2
      packages/opencode/test/server/httpapi-json-parity.test.ts
  38. 2 2
      packages/opencode/test/server/httpapi-mcp.test.ts
  39. 2 2
      packages/opencode/test/server/httpapi-provider.test.ts
  40. 2 2
      packages/opencode/test/server/httpapi-pty.test.ts
  41. 2 2
      packages/opencode/test/server/httpapi-raw-route-auth.test.ts
  42. 3 3
      packages/opencode/test/server/httpapi-sdk.test.ts
  43. 2 2
      packages/opencode/test/server/httpapi-session.test.ts
  44. 2 2
      packages/opencode/test/server/httpapi-sync.test.ts
  45. 2 2
      packages/opencode/test/server/httpapi-tui.test.ts
  46. 2 2
      packages/opencode/test/server/httpapi-workspace.test.ts
  47. 3 3
      packages/opencode/test/server/project-init-git.test.ts
  48. 2 2
      packages/opencode/test/server/session-actions.test.ts
  49. 2 2
      packages/opencode/test/server/session-list.test.ts
  50. 2 2
      packages/opencode/test/server/session-messages.test.ts
  51. 2 2
      packages/opencode/test/server/session-select.test.ts
  52. 2 2
      packages/opencode/test/snapshot/snapshot.test.ts
  53. 2 2
      packages/opencode/test/tool/edit.test.ts
  54. 2 2
      packages/opencode/test/tool/lsp.test.ts
  55. 2 2
      packages/opencode/test/tool/read.test.ts
  56. 2 2
      packages/opencode/test/tool/registry.test.ts
  57. 2 2
      packages/opencode/test/tool/skill.test.ts
  58. 2 2
      packages/opencode/test/tool/task.test.ts
  59. 2 2
      packages/opencode/test/tool/write.test.ts

+ 2 - 2
packages/opencode/src/cli/bootstrap.ts

@@ -1,5 +1,5 @@
-import { AppRuntime } from "@/effect/app-runtime"
 import { Instance } from "../project/instance"
+import { InstanceStore } from "../project/instance-store"
 
 export async function bootstrap<T>(directory: string, cb: () => Promise<T>) {
   return Instance.provide({
@@ -9,7 +9,7 @@ export async function bootstrap<T>(directory: string, cb: () => Promise<T>) {
         const result = await cb()
         return result
       } finally {
-        await Instance.dispose()
+        await InstanceStore.runtime.runPromise((s) => s.dispose(Instance.current))
       }
     },
   })

+ 2 - 1
packages/opencode/src/cli/cmd/tui/worker.ts

@@ -2,6 +2,7 @@ import { Installation } from "@/installation"
 import { Server } from "@/server/server"
 import * as Log from "@opencode-ai/core/util/log"
 import { Instance } from "@/project/instance"
+import { InstanceStore } from "@/project/instance-store"
 import { Rpc } from "@/util/rpc"
 import { upgrade } from "@/cli/upgrade"
 import { Config } from "@/config/config"
@@ -87,7 +88,7 @@ export const rpc = {
   async shutdown() {
     Log.Default.info("worker shutting down")
 
-    await Instance.disposeAll()
+    await InstanceStore.runtime.runPromise((s) => s.disposeAll())
     if (server) await server.stop(true)
   },
 }

+ 9 - 3
packages/opencode/src/config/config.ts

@@ -11,7 +11,9 @@ import { Flag } from "@opencode-ai/core/flag/flag"
 import { Auth } from "../auth"
 import { Env } from "../env"
 import { applyEdits, modify } from "jsonc-parser"
-import { Instance, type InstanceContext } from "../project/instance"
+import { type InstanceContext } from "../project/instance"
+import { InstanceStore } from "../project/instance-store"
+import { InstanceRef } from "@/effect/instance-ref"
 import { InstallationLocal, InstallationVersion } from "@opencode-ai/core/installation/version"
 import { existsSync } from "fs"
 import { GlobalBus } from "@/bus/global"
@@ -736,12 +738,16 @@ export const layer = Layer.effect(
       yield* fs
         .writeFileString(file, JSON.stringify(mergeDeep(writable(existing), writable(config)), null, 2))
         .pipe(Effect.orDie)
-      if (options?.dispose !== false) yield* Effect.promise(() => Instance.dispose())
+      if (options?.dispose !== false) {
+        const ctx = yield* InstanceRef
+        if (ctx) yield* Effect.promise(() => InstanceStore.runtime.runPromise((s) => s.dispose(ctx)))
+      }
     })
 
     const invalidate = Effect.fn("Config.invalidate")(function* (wait?: boolean) {
       yield* invalidateGlobal
-      const task = Instance.disposeAll()
+      const task = InstanceStore.runtime
+        .runPromise((s) => s.disposeAll())
         .catch(() => undefined)
         .finally(() =>
           GlobalBus.emit("event", {

+ 2 - 0
packages/opencode/src/effect/app-runtime.ts

@@ -39,6 +39,7 @@ import { Command } from "@/command"
 import { Truncate } from "@/tool/truncate"
 import { ToolRegistry } from "@/tool/registry"
 import { Format } from "@/format"
+import { InstanceStore } from "@/project/instance-store"
 import { Project } from "@/project/project"
 import { Vcs } from "@/project/vcs"
 import { Workspace } from "@/control-plane/workspace"
@@ -90,6 +91,7 @@ export const AppLayer = Layer.mergeAll(
   Truncate.defaultLayer,
   ToolRegistry.defaultLayer,
   Format.defaultLayer,
+  InstanceStore.defaultLayer,
   Project.defaultLayer,
   Vcs.defaultLayer,
   Workspace.defaultLayer,

+ 3 - 8
packages/opencode/src/project/instance.ts

@@ -6,13 +6,11 @@ export type { InstanceContext } from "./instance-context"
 export type { LoadInput } from "./instance-store"
 
 export const Instance = {
-  load(input: InstanceStore.LoadInput): Promise<InstanceContext> {
-    return InstanceStore.runtime.runPromise((store) => store.load(input))
-  },
   async provide<R>(input: { directory: string; init?: Effect.Effect<void>; fn: () => R }): Promise<R> {
-    return context.provide(await Instance.load({ directory: input.directory, init: input.init }), async () =>
-      input.fn(),
+    const ctx = await InstanceStore.runtime.runPromise((store) =>
+      store.load({ directory: input.directory, init: input.init }),
     )
+    return context.provide(ctx, async () => input.fn())
   },
   get current() {
     return context.use()
@@ -50,7 +48,4 @@ export const Instance = {
   async dispose() {
     return InstanceStore.runtime.runPromise((store) => store.dispose(Instance.current))
   },
-  async disposeAll() {
-    return InstanceStore.runtime.runPromise((store) => store.disposeAll())
-  },
 }

+ 2 - 2
packages/opencode/src/server/routes/global.ts

@@ -8,7 +8,7 @@ import { SyncEvent } from "@/sync"
 import { GlobalBus } from "@/bus/global"
 import { AppRuntime } from "@/effect/app-runtime"
 import { AsyncQueue } from "@/util/queue"
-import { Instance } from "../../project/instance"
+import { InstanceStore } from "../../project/instance-store"
 import { Installation } from "@/installation"
 import { InstallationVersion } from "@opencode-ai/core/installation/version"
 import * as Log from "@opencode-ai/core/util/log"
@@ -200,7 +200,7 @@ export const GlobalRoutes = lazy(() =>
         },
       }),
       async (c) => {
-        await Instance.disposeAll()
+        await InstanceStore.runtime.runPromise((s) => s.disposeAll())
         GlobalBus.emit("event", {
           directory: "global",
           payload: {

+ 2 - 1
packages/opencode/src/server/routes/instance/index.ts

@@ -6,6 +6,7 @@ import z from "zod"
 import { Format } from "@/format"
 import { TuiRoutes } from "./tui"
 import { Instance } from "@/project/instance"
+import { InstanceStore } from "@/project/instance-store"
 import { Vcs } from "@/project/vcs"
 import { Agent } from "@/agent/agent"
 import { Skill } from "@/skill"
@@ -62,7 +63,7 @@ export const InstanceRoutes = (upgrade: UpgradeWebSocket): Hono => {
         },
       }),
       async (c) => {
-        await Instance.dispose()
+        await InstanceStore.runtime.runPromise((s) => s.dispose(Instance.current))
         return c.json(true)
       },
     )

+ 1 - 5
packages/opencode/src/server/routes/instance/project.ts

@@ -81,11 +81,7 @@ export const ProjectRoutes = lazy(() =>
           Project.Service.use((svc) => svc.initGit({ directory: dir, project: prev })),
         )
         if (next.id === prev.id && next.vcs === prev.vcs && next.worktree === prev.worktree) return c.json(next)
-        await Instance.reload({
-          directory: dir,
-          worktree: dir,
-          project: next,
-        })
+        await Instance.reload({ directory: dir, worktree: dir, project: next })
         return c.json(next)
       },
     )

+ 2 - 2
packages/opencode/test/agent/agent.test.ts

@@ -1,7 +1,7 @@
 import { afterEach, test, expect } from "bun:test"
 import { Effect } from "effect"
 import path from "path"
-import { provideInstance, tmpdir } from "../fixture/fixture"
+import { disposeAllInstances, provideInstance, tmpdir } from "../fixture/fixture"
 import { Instance } from "../../src/project/instance"
 import { Agent } from "../../src/agent/agent"
 import { Permission } from "../../src/permission"
@@ -18,7 +18,7 @@ function load<A>(dir: string, fn: (svc: Agent.Interface) => Effect.Effect<A>) {
 }
 
 afterEach(async () => {
-  await Instance.disposeAll()
+  await disposeAllInstances()
 })
 
 test("returns default native agents when no config", async () => {

+ 2 - 2
packages/opencode/test/bus/bus-effect.test.ts

@@ -4,7 +4,7 @@ import { Bus } from "../../src/bus"
 import { BusEvent } from "../../src/bus/bus-event"
 import { Instance } from "../../src/project/instance"
 import { CrossSpawnSpawner } from "@opencode-ai/core/cross-spawn-spawner"
-import { provideInstance, provideTmpdirInstance, tmpdirScoped } from "../fixture/fixture"
+import { disposeAllInstances, provideInstance, provideTmpdirInstance, tmpdirScoped } from "../fixture/fixture"
 import { testEffect } from "../lib/effect"
 
 const TestEvent = {
@@ -151,7 +151,7 @@ describe("Bus (Effect-native)", () => {
       }).pipe(provideInstance(dir))
 
       // Dispose from OUTSIDE the instance scope
-      yield* Effect.promise(() => Instance.disposeAll())
+      yield* Effect.promise(disposeAllInstances)
       yield* Deferred.await(disposed).pipe(Effect.timeout("2 seconds"))
 
       expect(types).toContain("test.effect.ping")

+ 3 - 3
packages/opencode/test/bus/bus-integration.test.ts

@@ -3,7 +3,7 @@ import { Schema } from "effect"
 import { Bus } from "../../src/bus"
 import { BusEvent } from "../../src/bus/bus-event"
 import { Instance } from "../../src/project/instance"
-import { tmpdir } from "../fixture/fixture"
+import { disposeAllInstances, tmpdir } from "../fixture/fixture"
 
 const TestEvent = BusEvent.define("test.integration", Schema.Struct({ value: Schema.Number }))
 
@@ -12,7 +12,7 @@ function withInstance(directory: string, fn: () => Promise<void>) {
 }
 
 describe("Bus integration: acquireRelease subscriber pattern", () => {
-  afterEach(() => Instance.disposeAll())
+  afterEach(() => disposeAllInstances())
 
   test("subscriber via callback facade receives events and cleans up on unsub", async () => {
     await using tmp = await tmpdir()
@@ -78,7 +78,7 @@ describe("Bus integration: acquireRelease subscriber pattern", () => {
       await Bun.sleep(10)
     })
 
-    await Instance.disposeAll()
+    await disposeAllInstances()
     await Bun.sleep(50)
 
     expect(received).toEqual([1])

+ 4 - 4
packages/opencode/test/bus/bus.test.ts

@@ -3,7 +3,7 @@ import { Schema } from "effect"
 import { Bus } from "../../src/bus"
 import { BusEvent } from "../../src/bus/bus-event"
 import { Instance } from "../../src/project/instance"
-import { tmpdir } from "../fixture/fixture"
+import { disposeAllInstances, tmpdir } from "../fixture/fixture"
 
 const TestEvent = {
   Ping: BusEvent.define("test.ping", Schema.Struct({ value: Schema.Number })),
@@ -15,7 +15,7 @@ function withInstance(directory: string, fn: () => Promise<void>) {
 }
 
 describe("Bus", () => {
-  afterEach(() => Instance.disposeAll())
+  afterEach(() => disposeAllInstances())
 
   describe("publish + subscribe", () => {
     test("subscriber is live immediately after subscribe returns", async () => {
@@ -208,8 +208,8 @@ describe("Bus", () => {
         await Bun.sleep(10)
       })
 
-      // Instance.disposeAll triggers the finalizer which publishes InstanceDisposed
-      await Instance.disposeAll()
+      // disposeAllInstances triggers the finalizer which publishes InstanceDisposed
+      await disposeAllInstances()
       await Bun.sleep(50)
 
       expect(received).toContain("test.ping")

+ 2 - 2
packages/opencode/test/config/config.test.ts

@@ -12,7 +12,7 @@ import { Account } from "../../src/account/account"
 import { AccessToken, AccountID, OrgID } from "../../src/account/schema"
 import { AppFileSystem } from "@opencode-ai/core/filesystem"
 import { Env } from "../../src/env"
-import { provideTmpdirInstance } from "../fixture/fixture"
+import { disposeAllInstances, provideTmpdirInstance } from "../fixture/fixture"
 import { tmpdir } from "../fixture/fixture"
 import { CrossSpawnSpawner } from "@opencode-ai/core/cross-spawn-spawner"
 import { testEffect } from "../lib/effect"
@@ -108,7 +108,7 @@ async function check(map: (dir: string) => string) {
       },
     })
   } finally {
-    await Instance.disposeAll()
+    await disposeAllInstances()
     ;(Global.Path as { config: string }).config = prev
     await clear()
   }

+ 2 - 2
packages/opencode/test/control-plane/workspace.test.ts

@@ -21,7 +21,7 @@ import { ModelID, ProviderID } from "@/provider/schema"
 import { SyncEvent } from "@/sync"
 import { EventSequenceTable, EventTable } from "@/sync/event.sql"
 import { resetDatabase } from "../fixture/db"
-import { provideTmpdirInstance, tmpdir } from "../fixture/fixture"
+import { disposeAllInstances, provideTmpdirInstance, tmpdir } from "../fixture/fixture"
 import { testEffect } from "../lib/effect"
 import { registerAdapter } from "../../src/control-plane/adapters"
 import { WorkspaceID } from "../../src/control-plane/schema"
@@ -93,7 +93,7 @@ beforeEach(() => {
 
 afterEach(async () => {
   mock.restore()
-  await Instance.disposeAll()
+  await disposeAllInstances()
   Flag.OPENCODE_EXPERIMENTAL_WORKSPACES = originalWorkspacesFlag
   restoreEnv()
   await resetDatabase()

+ 3 - 3
packages/opencode/test/effect/instance-state.test.ts

@@ -4,7 +4,7 @@ import { $ } from "bun"
 import { Context, Deferred, Duration, Effect, Exit, Fiber, Layer } from "effect"
 import { InstanceState } from "@/effect/instance-state"
 import { Instance } from "../../src/project/instance"
-import { provideInstance, tmpdirScoped } from "../fixture/fixture"
+import { disposeAllInstances, provideInstance, tmpdirScoped } from "../fixture/fixture"
 import { testEffect } from "../lib/effect"
 
 const it = testEffect(CrossSpawnSpawner.defaultLayer)
@@ -19,7 +19,7 @@ const tmpdirGitScoped = Effect.gen(function* () {
 })
 
 afterEach(async () => {
-  await Instance.disposeAll()
+  await disposeAllInstances()
 })
 
 it.live("InstanceState caches values per directory", () =>
@@ -94,7 +94,7 @@ it.live("InstanceState invalidates on disposeAll", () =>
 
     yield* access(state, one)
     yield* access(state, two)
-    yield* Effect.promise(() => Instance.disposeAll())
+    yield* Effect.promise(disposeAllInstances)
 
     expect(seen.sort()).toEqual([one, two].sort())
   }),

+ 3 - 3
packages/opencode/test/file/index.test.ts

@@ -6,10 +6,10 @@ import fs from "fs/promises"
 import { File } from "../../src/file"
 import { Instance } from "../../src/project/instance"
 import { Filesystem } from "@/util/filesystem"
-import { provideInstance, tmpdir } from "../fixture/fixture"
+import { disposeAllInstances, provideInstance, tmpdir } from "../fixture/fixture"
 
 afterEach(async () => {
-  await Instance.disposeAll()
+  await disposeAllInstances()
 })
 
 const init = () => run(File.Service.use((svc) => svc.init()))
@@ -936,7 +936,7 @@ describe("file/index Filesystem patterns", () => {
         },
       })
 
-      await Instance.disposeAll()
+      await disposeAllInstances()
 
       await fs.writeFile(path.join(tmp.path, "after.ts"), "after", "utf-8")
       await fs.rm(path.join(tmp.path, "before.ts"))

+ 2 - 2
packages/opencode/test/file/watcher.test.ts

@@ -3,7 +3,7 @@ import { afterEach, describe, expect, test } from "bun:test"
 import fs from "fs/promises"
 import path from "path"
 import { ConfigProvider, Deferred, Effect, Layer, ManagedRuntime, Option } from "effect"
-import { tmpdir } from "../fixture/fixture"
+import { disposeAllInstances, tmpdir } from "../fixture/fixture"
 import { Bus } from "../../src/bus"
 import { Config } from "@/config/config"
 import { FileWatcher } from "../../src/file/watcher"
@@ -147,7 +147,7 @@ function ready(directory: string) {
 
 describeWatcher("FileWatcher", () => {
   afterEach(async () => {
-    await Instance.disposeAll()
+    await disposeAllInstances()
   })
 
   test("publishes root create, update, and delete events", async () => {

+ 2 - 2
packages/opencode/test/fixture/db.ts

@@ -1,9 +1,9 @@
 import { rm } from "fs/promises"
-import { Instance } from "../../src/project/instance"
 import { Database } from "@/storage/db"
+import { disposeAllInstances } from "./fixture"
 
 export async function resetDatabase() {
-  await Instance.disposeAll().catch(() => undefined)
+  await disposeAllInstances().catch(() => undefined)
   Database.close()
   await rm(Database.Path, { force: true }).catch(() => undefined)
   await rm(`${Database.Path}-wal`, { force: true }).catch(() => undefined)

+ 8 - 0
packages/opencode/test/fixture/fixture.ts

@@ -9,8 +9,16 @@ import { ChildProcess, ChildProcessSpawner } from "effect/unstable/process"
 import type { Config } from "@/config/config"
 import { InstanceRef } from "../../src/effect/instance-ref"
 import { Instance } from "../../src/project/instance"
+import { InstanceStore } from "../../src/project/instance-store"
 import { TestLLMServer } from "../lib/llm-server"
 
+// Test helper for tearing down all loaded instances. Used in afterEach hooks.
+// Replaces direct Instance.disposeAll() calls so the legacy promise method can be removed.
+// IMPORTANT: must use InstanceStore.runtime, not AppRuntime or a test-layer Service —
+// Instance.provide loads instances into InstanceStore.runtime's Service cache, and that
+// Service is built per-runtime (not shared via memoMap across Effect.runPromise boundaries).
+export const disposeAllInstances = () => InstanceStore.runtime.runPromise((s) => s.disposeAll())
+
 // Strip null bytes from paths (defensive fix for CI environment issues)
 function sanitizePath(p: string): string {
   return p.replace(/\0/g, "")

+ 2 - 2
packages/opencode/test/permission-task.test.ts

@@ -2,13 +2,13 @@ import { afterEach, describe, test, expect } from "bun:test"
 import { Permission } from "../src/permission"
 import { Config } from "@/config/config"
 import { Instance } from "../src/project/instance"
-import { tmpdir } from "./fixture/fixture"
+import { disposeAllInstances, tmpdir } from "./fixture/fixture"
 import { AppRuntime } from "../src/effect/app-runtime"
 
 const load = () => AppRuntime.runPromise(Config.Service.use((svc) => svc.get()))
 
 afterEach(async () => {
-  await Instance.disposeAll()
+  await disposeAllInstances()
 })
 
 describe("Permission.evaluate for permission.task", () => {

+ 2 - 2
packages/opencode/test/permission/next.test.ts

@@ -6,7 +6,7 @@ import { CrossSpawnSpawner } from "@opencode-ai/core/cross-spawn-spawner"
 import { Permission } from "../../src/permission"
 import { PermissionID } from "../../src/permission/schema"
 import { Instance } from "../../src/project/instance"
-import { provideInstance, provideTmpdirInstance, tmpdirScoped } from "../fixture/fixture"
+import { disposeAllInstances, provideInstance, provideTmpdirInstance, tmpdirScoped } from "../fixture/fixture"
 import { testEffect } from "../lib/effect"
 import { MessageID, SessionID } from "../../src/session/schema"
 
@@ -15,7 +15,7 @@ const env = Layer.mergeAll(Permission.layer.pipe(Layer.provide(bus)), bus, Cross
 const it = testEffect(env)
 
 afterEach(async () => {
-  await Instance.disposeAll()
+  await disposeAllInstances()
 })
 
 const rejectAll = (message?: string) =>

+ 2 - 2
packages/opencode/test/plugin/loader-shared.test.ts

@@ -3,7 +3,7 @@ import { Effect } from "effect"
 import fs from "fs/promises"
 import path from "path"
 import { pathToFileURL } from "url"
-import { tmpdir } from "../fixture/fixture"
+import { disposeAllInstances, tmpdir } from "../fixture/fixture"
 import { Filesystem } from "@/util/filesystem"
 
 const disableDefault = process.env.OPENCODE_DISABLE_DEFAULT_PLUGINS
@@ -24,7 +24,7 @@ afterAll(() => {
 })
 
 afterEach(async () => {
-  await Instance.disposeAll()
+  await disposeAllInstances()
 })
 
 async function load(dir: string) {

+ 2 - 2
packages/opencode/test/plugin/workspace-adapter.test.ts

@@ -3,7 +3,7 @@ import { Effect, Layer } from "effect"
 import { CrossSpawnSpawner } from "@opencode-ai/core/cross-spawn-spawner"
 import path from "path"
 import { pathToFileURL } from "url"
-import { provideTmpdirInstance } from "../fixture/fixture"
+import { disposeAllInstances, provideTmpdirInstance } from "../fixture/fixture"
 import { testEffect } from "../lib/effect"
 
 const disableDefault = process.env.OPENCODE_DISABLE_DEFAULT_PLUGINS
@@ -20,7 +20,7 @@ const experimental = Flag.OPENCODE_EXPERIMENTAL_WORKSPACES
 Flag.OPENCODE_EXPERIMENTAL_WORKSPACES = true
 
 afterEach(async () => {
-  await Instance.disposeAll()
+  await disposeAllInstances()
 })
 
 afterAll(() => {

+ 2 - 2
packages/opencode/test/project/instance.test.ts

@@ -5,13 +5,13 @@ import { InstanceRef } from "../../src/effect/instance-ref"
 import { registerDisposer } from "../../src/effect/instance-registry"
 import { Instance } from "../../src/project/instance"
 import { InstanceStore } from "../../src/project/instance-store"
-import { tmpdirScoped } from "../fixture/fixture"
+import { disposeAllInstances, tmpdirScoped } from "../fixture/fixture"
 import { testEffect } from "../lib/effect"
 
 const it = testEffect(Layer.mergeAll(InstanceStore.defaultLayer, CrossSpawnSpawner.defaultLayer))
 
 afterEach(async () => {
-  await Instance.disposeAll()
+  await disposeAllInstances()
 })
 
 describe("InstanceStore", () => {

+ 3 - 3
packages/opencode/test/project/vcs.test.ts

@@ -3,7 +3,7 @@ import { afterEach, describe, expect, test } from "bun:test"
 import { Effect } from "effect"
 import fs from "fs/promises"
 import path from "path"
-import { tmpdir } from "../fixture/fixture"
+import { disposeAllInstances, tmpdir } from "../fixture/fixture"
 import { AppRuntime } from "../../src/effect/app-runtime"
 import { FileWatcher } from "../../src/file/watcher"
 import { Instance } from "../../src/project/instance"
@@ -85,7 +85,7 @@ function nextBranchUpdate(directory: string, timeout = 10_000) {
 
 describeVcs("Vcs", () => {
   afterEach(async () => {
-    await Instance.disposeAll()
+    await disposeAllInstances()
   })
 
   test("branch() returns current branch name", async () => {
@@ -158,7 +158,7 @@ describeVcs("Vcs", () => {
 
 describe("Vcs diff", () => {
   afterEach(async () => {
-    await Instance.disposeAll()
+    await disposeAllInstances()
   })
 
   test("defaultBranch() falls back to main", async () => {

+ 2 - 2
packages/opencode/test/project/worktree.test.ts

@@ -6,7 +6,7 @@ import { Cause, Effect, Exit, Layer } from "effect"
 import { CrossSpawnSpawner } from "@opencode-ai/core/cross-spawn-spawner"
 import { Instance } from "../../src/project/instance"
 import { Worktree } from "../../src/worktree"
-import { provideInstance, provideTmpdirInstance } from "../fixture/fixture"
+import { disposeAllInstances, provideInstance, provideTmpdirInstance } from "../fixture/fixture"
 import { testEffect } from "../lib/effect"
 
 const it = testEffect(Layer.mergeAll(Worktree.defaultLayer, CrossSpawnSpawner.defaultLayer))
@@ -37,7 +37,7 @@ async function waitReady() {
 }
 
 describe("Worktree", () => {
-  afterEach(() => Instance.disposeAll())
+  afterEach(() => disposeAllInstances())
 
   describe("makeWorktreeInfo", () => {
     it.live("returns info with name, branch, and directory", () =>

+ 2 - 2
packages/opencode/test/provider/provider.test.ts

@@ -2,7 +2,7 @@ import { test, expect } from "bun:test"
 import { mkdir, unlink } from "fs/promises"
 import path from "path"
 
-import { tmpdir } from "../fixture/fixture"
+import { disposeAllInstances, tmpdir } from "../fixture/fixture"
 import { Global } from "@opencode-ai/core/global"
 import { Instance } from "../../src/project/instance"
 import { Plugin } from "../../src/plugin/index"
@@ -2557,7 +2557,7 @@ test("plugin config providers persist after instance dispose", async () => {
   expect(first[ProviderID.make("demo")]).toBeDefined()
   expect(first[ProviderID.make("demo")].models[ModelID.make("chat")]).toBeDefined()
 
-  await Instance.disposeAll()
+  await disposeAllInstances()
 
   const second = await Instance.provide({
     directory: tmp.path,

+ 2 - 2
packages/opencode/test/question/question.test.ts

@@ -2,7 +2,7 @@ import { afterEach, test, expect } from "bun:test"
 import { Question } from "../../src/question"
 import { Instance } from "../../src/project/instance"
 import { QuestionID } from "../../src/question/schema"
-import { tmpdir } from "../fixture/fixture"
+import { disposeAllInstances, tmpdir } from "../fixture/fixture"
 import { SessionID } from "../../src/session/schema"
 import { AppRuntime } from "../../src/effect/app-runtime"
 
@@ -17,7 +17,7 @@ const reply = (input: { requestID: QuestionID; answers: ReadonlyArray<Question.A
 const reject = (id: QuestionID) => AppRuntime.runPromise(Question.Service.use((svc) => svc.reject(id)))
 
 afterEach(async () => {
-  await Instance.disposeAll()
+  await disposeAllInstances()
 })
 
 /** Reject all pending questions so dangling Deferred fibers don't hang the test. */

+ 2 - 2
packages/opencode/test/server/httpapi-bridge.test.ts

@@ -12,7 +12,7 @@ import { ConfigProvider, Layer } from "effect"
 import { HttpRouter } from "effect/unstable/http"
 import { OpenApi } from "effect/unstable/httpapi"
 import { resetDatabase } from "../fixture/db"
-import { tmpdir } from "../fixture/fixture"
+import { disposeAllInstances, tmpdir } from "../fixture/fixture"
 
 void Log.init({ print: false })
 
@@ -208,7 +208,7 @@ afterEach(async () => {
   Flag.OPENCODE_EXPERIMENTAL_HTTPAPI = original.OPENCODE_EXPERIMENTAL_HTTPAPI
   Flag.OPENCODE_SERVER_PASSWORD = original.OPENCODE_SERVER_PASSWORD
   Flag.OPENCODE_SERVER_USERNAME = original.OPENCODE_SERVER_USERNAME
-  await Instance.disposeAll()
+  await disposeAllInstances()
   await resetDatabase()
 })
 

+ 2 - 2
packages/opencode/test/server/httpapi-config.test.ts

@@ -6,7 +6,7 @@ import { Instance } from "../../src/project/instance"
 import { Server } from "../../src/server/server"
 import * as Log from "@opencode-ai/core/util/log"
 import { resetDatabase } from "../fixture/db"
-import { tmpdir } from "../fixture/fixture"
+import { disposeAllInstances, tmpdir } from "../fixture/fixture"
 
 void Log.init({ print: false })
 
@@ -37,7 +37,7 @@ async function waitDisposed(directory: string) {
 
 afterEach(async () => {
   Flag.OPENCODE_EXPERIMENTAL_HTTPAPI = original
-  await Instance.disposeAll()
+  await disposeAllInstances()
   await resetDatabase()
 })
 

+ 2 - 2
packages/opencode/test/server/httpapi-event.test.ts

@@ -5,7 +5,7 @@ import { Server } from "../../src/server/server"
 import { EventPaths } from "../../src/server/routes/instance/httpapi/event"
 import * as Log from "@opencode-ai/core/util/log"
 import { resetDatabase } from "../fixture/db"
-import { tmpdir } from "../fixture/fixture"
+import { disposeAllInstances, tmpdir } from "../fixture/fixture"
 
 void Log.init({ print: false })
 
@@ -29,7 +29,7 @@ async function readFirstChunk(response: Response) {
 
 afterEach(async () => {
   Flag.OPENCODE_EXPERIMENTAL_HTTPAPI = original
-  await Instance.disposeAll()
+  await disposeAllInstances()
   await resetDatabase()
 })
 

+ 2 - 2
packages/opencode/test/server/httpapi-experimental.test.ts

@@ -10,7 +10,7 @@ import { Database } from "@/storage/db"
 import * as Log from "@opencode-ai/core/util/log"
 import { Worktree } from "../../src/worktree"
 import { resetDatabase } from "../fixture/db"
-import { tmpdir } from "../fixture/fixture"
+import { disposeAllInstances, tmpdir } from "../fixture/fixture"
 
 void Log.init({ print: false })
 
@@ -50,7 +50,7 @@ async function waitReady(directory: string) {
 
 afterEach(async () => {
   Flag.OPENCODE_EXPERIMENTAL_HTTPAPI = original
-  await Instance.disposeAll()
+  await disposeAllInstances()
   await resetDatabase()
 })
 

+ 2 - 2
packages/opencode/test/server/httpapi-file.test.ts

@@ -6,7 +6,7 @@ import { FilePaths } from "../../src/server/routes/instance/httpapi/groups/file"
 import { Instance } from "../../src/project/instance"
 import * as Log from "@opencode-ai/core/util/log"
 import { resetDatabase } from "../fixture/db"
-import { tmpdir } from "../fixture/fixture"
+import { disposeAllInstances, tmpdir } from "../fixture/fixture"
 
 void Log.init({ print: false })
 
@@ -28,7 +28,7 @@ function request(route: string, directory: string, query?: Record<string, string
 }
 
 afterEach(async () => {
-  await Instance.disposeAll()
+  await disposeAllInstances()
   await resetDatabase()
 })
 

+ 2 - 2
packages/opencode/test/server/httpapi-instance-context.test.ts

@@ -19,7 +19,7 @@ import { disposeMiddleware, markInstanceForDisposal } from "../../src/server/rou
 import { instanceRouterMiddleware } from "../../src/server/routes/instance/httpapi/middleware/instance-context"
 import { workspaceRouterMiddleware } from "../../src/server/routes/instance/httpapi/middleware/workspace-routing"
 import { resetDatabase } from "../fixture/db"
-import { tmpdirScoped } from "../fixture/fixture"
+import { disposeAllInstances, tmpdirScoped } from "../fixture/fixture"
 import { testEffect } from "../lib/effect"
 
 const testStateLayer = Layer.effectDiscard(
@@ -30,7 +30,7 @@ const testStateLayer = Layer.effectDiscard(
     yield* Effect.addFinalizer(() =>
       Effect.promise(async () => {
         Flag.OPENCODE_EXPERIMENTAL_WORKSPACES = originalWorkspaces
-        await Instance.disposeAll()
+        await disposeAllInstances()
         await resetDatabase()
       }),
     )

+ 2 - 2
packages/opencode/test/server/httpapi-instance.legacy.test.ts

@@ -6,7 +6,7 @@ import { Server } from "../../src/server/server"
 import { InstancePaths } from "../../src/server/routes/instance/httpapi/groups/instance"
 import * as Log from "@opencode-ai/core/util/log"
 import { resetDatabase } from "../fixture/db"
-import { tmpdir } from "../fixture/fixture"
+import { disposeAllInstances, tmpdir } from "../fixture/fixture"
 
 void Log.init({ print: false })
 
@@ -37,7 +37,7 @@ async function waitDisposed(directory: string) {
 
 afterEach(async () => {
   Flag.OPENCODE_EXPERIMENTAL_HTTPAPI = original
-  await Instance.disposeAll()
+  await disposeAllInstances()
   await resetDatabase()
 })
 

+ 2 - 2
packages/opencode/test/server/httpapi-instance.test.ts

@@ -7,13 +7,13 @@ import * as Socket from "effect/unstable/socket/Socket"
 import { InstancePaths } from "../../src/server/routes/instance/httpapi/groups/instance"
 import { ExperimentalHttpApiServer } from "../../src/server/routes/instance/httpapi/server"
 import { resetDatabase } from "../fixture/db"
-import { tmpdirScoped } from "../fixture/fixture"
+import { disposeAllInstances, tmpdirScoped } from "../fixture/fixture"
 import { testEffect } from "../lib/effect"
 
 // Flip the experimental HttpApi flag so backend selection telemetry on the
 // production routes reports the right backend, and reset the database around
 // the test so per-instance state does not leak between runs. resetDatabase()
-// already calls Instance.disposeAll(), so we don't repeat it.
+// already calls disposeAllInstances(), so we don't repeat it.
 const testStateLayer = Layer.effectDiscard(
   Effect.gen(function* () {
     const originalHttpApi = Flag.OPENCODE_EXPERIMENTAL_HTTPAPI

+ 2 - 2
packages/opencode/test/server/httpapi-json-parity.test.ts

@@ -15,7 +15,7 @@ import { MessageID, PartID } from "../../src/session/schema"
 import { Session } from "@/session/session"
 import * as Log from "@opencode-ai/core/util/log"
 import { resetDatabase } from "../fixture/db"
-import { provideInstance, tmpdir } from "../fixture/fixture"
+import { disposeAllInstances, provideInstance, tmpdir } from "../fixture/fixture"
 import { it } from "../lib/effect"
 
 void Log.init({ print: false })
@@ -89,7 +89,7 @@ function expectJsonParity(input: {
 
 afterEach(async () => {
   Flag.OPENCODE_EXPERIMENTAL_HTTPAPI = original
-  await Instance.disposeAll()
+  await disposeAllInstances()
   await resetDatabase()
 })
 

+ 2 - 2
packages/opencode/test/server/httpapi-mcp.test.ts

@@ -8,7 +8,7 @@ import { Instance } from "../../src/project/instance"
 import { Server } from "../../src/server/server"
 import * as Log from "@opencode-ai/core/util/log"
 import { resetDatabase } from "../fixture/db"
-import { provideInstance, tmpdir } from "../fixture/fixture"
+import { disposeAllInstances, provideInstance, tmpdir } from "../fixture/fixture"
 import { testEffect } from "../lib/effect"
 
 void Log.init({ print: false })
@@ -76,7 +76,7 @@ const readResponse = Effect.fnUntraced(function* (input: { app: TestApp; path: s
 
 afterEach(async () => {
   Flag.OPENCODE_EXPERIMENTAL_HTTPAPI = original
-  await Instance.disposeAll()
+  await disposeAllInstances()
   await resetDatabase()
 })
 

+ 2 - 2
packages/opencode/test/server/httpapi-provider.test.ts

@@ -6,7 +6,7 @@ import { Instance } from "../../src/project/instance"
 import { Server } from "../../src/server/server"
 import * as Log from "@opencode-ai/core/util/log"
 import { resetDatabase } from "../fixture/db"
-import { provideInstance } from "../fixture/fixture"
+import { disposeAllInstances, provideInstance } from "../fixture/fixture"
 import { testEffect } from "../lib/effect"
 
 void Log.init({ print: false })
@@ -98,7 +98,7 @@ function withProviderProject<A, E, R>(self: (dir: string) => Effect.Effect<A, E,
 
 afterEach(async () => {
   Flag.OPENCODE_EXPERIMENTAL_HTTPAPI = original
-  await Instance.disposeAll()
+  await disposeAllInstances()
   await resetDatabase()
 })
 

+ 2 - 2
packages/opencode/test/server/httpapi-pty.test.ts

@@ -7,7 +7,7 @@ import { Server } from "../../src/server/server"
 import { PtyPaths } from "../../src/server/routes/instance/httpapi/groups/pty"
 import * as Log from "@opencode-ai/core/util/log"
 import { resetDatabase } from "../fixture/db"
-import { tmpdir, tmpdirScoped } from "../fixture/fixture"
+import { disposeAllInstances, tmpdir, tmpdirScoped } from "../fixture/fixture"
 import { Config, Effect, Layer, Queue, Schema } from "effect"
 import { HttpClient, HttpClientRequest, HttpRouter, HttpServer } from "effect/unstable/http"
 import * as Socket from "effect/unstable/socket/Socket"
@@ -63,7 +63,7 @@ const directoryHeader = (dir: string) => HttpClientRequest.setHeader("x-opencode
 
 afterEach(async () => {
   Flag.OPENCODE_EXPERIMENTAL_HTTPAPI = original
-  await Instance.disposeAll()
+  await disposeAllInstances()
   await resetDatabase()
 })
 

+ 2 - 2
packages/opencode/test/server/httpapi-raw-route-auth.test.ts

@@ -8,7 +8,7 @@ import { PtyPaths } from "../../src/server/routes/instance/httpapi/groups/pty"
 import { ExperimentalHttpApiServer } from "../../src/server/routes/instance/httpapi/server"
 import { PtyID } from "../../src/pty/schema"
 import { resetDatabase } from "../fixture/db"
-import { tmpdir } from "../fixture/fixture"
+import { disposeAllInstances, tmpdir } from "../fixture/fixture"
 import * as Log from "@opencode-ai/core/util/log"
 
 void Log.init({ print: false })
@@ -49,7 +49,7 @@ async function cancelBody(response: Response) {
 
 afterEach(async () => {
   Flag.OPENCODE_EXPERIMENTAL_HTTPAPI = originalHttpApi
-  await Instance.disposeAll()
+  await disposeAllInstances()
   await resetDatabase()
 })
 

+ 3 - 3
packages/opencode/test/server/httpapi-sdk.test.ts

@@ -15,7 +15,7 @@ import { Session as SessionNs } from "@/session/session"
 import { TestLLMServer } from "../lib/llm-server"
 import path from "path"
 import { resetDatabase } from "../fixture/db"
-import { tmpdir } from "../fixture/fixture"
+import { disposeAllInstances, tmpdir } from "../fixture/fixture"
 import { it } from "../lib/effect"
 
 const original = {
@@ -169,7 +169,7 @@ function sessionTitles(value: unknown) {
 
 function resetState() {
   return Effect.promise(async () => {
-    await Instance.disposeAll()
+    await disposeAllInstances()
     await resetDatabase()
   })
 }
@@ -260,7 +260,7 @@ afterEach(async () => {
   Flag.OPENCODE_EXPERIMENTAL_HTTPAPI = original.OPENCODE_EXPERIMENTAL_HTTPAPI
   Flag.OPENCODE_SERVER_PASSWORD = original.OPENCODE_SERVER_PASSWORD
   Flag.OPENCODE_SERVER_USERNAME = original.OPENCODE_SERVER_USERNAME
-  await Instance.disposeAll()
+  await disposeAllInstances()
   await resetDatabase()
 })
 

+ 2 - 2
packages/opencode/test/server/httpapi-session.test.ts

@@ -20,7 +20,7 @@ import { SessionTable } from "@/session/session.sql"
 import * as Log from "@opencode-ai/core/util/log"
 import { eq } from "drizzle-orm"
 import { resetDatabase } from "../fixture/db"
-import { tmpdir } from "../fixture/fixture"
+import { disposeAllInstances, tmpdir } from "../fixture/fixture"
 import { it } from "../lib/effect"
 
 void Log.init({ print: false })
@@ -138,7 +138,7 @@ function withTmp<A, E, R>(
 afterEach(async () => {
   Flag.OPENCODE_EXPERIMENTAL_HTTPAPI = original
   Flag.OPENCODE_EXPERIMENTAL_WORKSPACES = originalWorkspaces
-  await Instance.disposeAll()
+  await disposeAllInstances()
   await resetDatabase()
 })
 

+ 2 - 2
packages/opencode/test/server/httpapi-sync.test.ts

@@ -7,7 +7,7 @@ import { SyncPaths } from "../../src/server/routes/instance/httpapi/groups/sync"
 import { Session } from "@/session/session"
 import * as Log from "@opencode-ai/core/util/log"
 import { resetDatabase } from "../fixture/db"
-import { tmpdir } from "../fixture/fixture"
+import { disposeAllInstances, tmpdir } from "../fixture/fixture"
 
 void Log.init({ print: false })
 
@@ -27,7 +27,7 @@ afterEach(async () => {
   mock.restore()
   Flag.OPENCODE_EXPERIMENTAL_HTTPAPI = originalHttpApi
   Flag.OPENCODE_EXPERIMENTAL_WORKSPACES = originalWorkspaces
-  await Instance.disposeAll()
+  await disposeAllInstances()
   await resetDatabase()
 })
 

+ 2 - 2
packages/opencode/test/server/httpapi-tui.test.ts

@@ -11,7 +11,7 @@ import { Server } from "../../src/server/server"
 import * as Log from "@opencode-ai/core/util/log"
 import { OpenApi } from "effect/unstable/httpapi"
 import { resetDatabase } from "../fixture/db"
-import { tmpdir } from "../fixture/fixture"
+import { disposeAllInstances, tmpdir } from "../fixture/fixture"
 
 void Log.init({ print: false })
 
@@ -45,7 +45,7 @@ async function expectTrue(path: string, headers: Record<string, string>, body?:
 
 afterEach(async () => {
   Flag.OPENCODE_EXPERIMENTAL_HTTPAPI = original
-  await Instance.disposeAll()
+  await disposeAllInstances()
   await resetDatabase()
 })
 

+ 2 - 2
packages/opencode/test/server/httpapi-workspace.test.ts

@@ -12,7 +12,7 @@ import { Session } from "@/session/session"
 import * as Log from "@opencode-ai/core/util/log"
 import { Server } from "../../src/server/server"
 import { resetDatabase } from "../fixture/db"
-import { provideInstance, tmpdirScoped } from "../fixture/fixture"
+import { disposeAllInstances, provideInstance, tmpdirScoped } from "../fixture/fixture"
 import { Instance } from "../../src/project/instance"
 import { Project } from "../../src/project/project"
 import { InstancePaths } from "../../src/server/routes/instance/httpapi/groups/instance"
@@ -128,7 +128,7 @@ afterEach(async () => {
   mock.restore()
   Flag.OPENCODE_EXPERIMENTAL_WORKSPACES = originalWorkspaces
   Flag.OPENCODE_EXPERIMENTAL_HTTPAPI = originalHttpApi
-  await Instance.disposeAll()
+  await disposeAllInstances()
   await resetDatabase()
 })
 

+ 3 - 3
packages/opencode/test/server/project-init-git.test.ts

@@ -8,7 +8,7 @@ import { Server } from "../../src/server/server"
 import { Filesystem } from "@/util/filesystem"
 import * as Log from "@opencode-ai/core/util/log"
 import { resetDatabase } from "../fixture/db"
-import { provideInstance, tmpdir } from "../fixture/fixture"
+import { disposeAllInstances, provideInstance, tmpdir } from "../fixture/fixture"
 
 void Log.init({ print: false })
 
@@ -69,7 +69,7 @@ describe("project.initGit endpoint", () => {
         ),
       ).toBeTruthy()
     } finally {
-      await Instance.disposeAll()
+      await disposeAllInstances()
       reloadSpy.mockRestore()
       GlobalBus.off("event", fn)
     }
@@ -114,7 +114,7 @@ describe("project.initGit endpoint", () => {
         worktree: tmp.path,
       })
     } finally {
-      await Instance.disposeAll()
+      await disposeAllInstances()
       reloadSpy.mockRestore()
       GlobalBus.off("event", fn)
     }

+ 2 - 2
packages/opencode/test/server/session-actions.test.ts

@@ -5,7 +5,7 @@ import { Server } from "../../src/server/server"
 import { Session as SessionNs } from "@/session/session"
 import type { SessionID } from "../../src/session/schema"
 import * as Log from "@opencode-ai/core/util/log"
-import { tmpdir } from "../fixture/fixture"
+import { disposeAllInstances, tmpdir } from "../fixture/fixture"
 
 void Log.init({ print: false })
 
@@ -25,7 +25,7 @@ const svc = {
 
 afterEach(async () => {
   mock.restore()
-  await Instance.disposeAll()
+  await disposeAllInstances()
 })
 
 describe("session action routes", () => {

+ 2 - 2
packages/opencode/test/server/session-list.test.ts

@@ -3,7 +3,7 @@ import { Effect } from "effect"
 import { Instance } from "../../src/project/instance"
 import { Session as SessionNs } from "@/session/session"
 import * as Log from "@opencode-ai/core/util/log"
-import { tmpdir } from "../fixture/fixture"
+import { disposeAllInstances, tmpdir } from "../fixture/fixture"
 import { Flag } from "@opencode-ai/core/flag/flag"
 import { mkdir } from "fs/promises"
 import path from "path"
@@ -30,7 +30,7 @@ const svc = {
 
 afterEach(async () => {
   Flag.OPENCODE_EXPERIMENTAL_WORKSPACES = originalWorkspaces
-  await Instance.disposeAll()
+  await disposeAllInstances()
 })
 
 describe("session.list", () => {

+ 2 - 2
packages/opencode/test/server/session-messages.test.ts

@@ -6,7 +6,7 @@ import { Session as SessionNs } from "@/session/session"
 import { MessageV2 } from "../../src/session/message-v2"
 import { MessageID, PartID, type SessionID } from "../../src/session/schema"
 import * as Log from "@opencode-ai/core/util/log"
-import { tmpdir } from "../fixture/fixture"
+import { disposeAllInstances, tmpdir } from "../fixture/fixture"
 
 void Log.init({ print: false })
 
@@ -31,7 +31,7 @@ const svc = {
 }
 
 afterEach(async () => {
-  await Instance.disposeAll()
+  await disposeAllInstances()
 })
 
 async function withoutWatcher<T>(fn: () => Promise<T>) {

+ 2 - 2
packages/opencode/test/server/session-select.test.ts

@@ -5,7 +5,7 @@ import type { SessionID } from "../../src/session/schema"
 import * as Log from "@opencode-ai/core/util/log"
 import { Instance } from "../../src/project/instance"
 import { Server } from "../../src/server/server"
-import { tmpdir } from "../fixture/fixture"
+import { disposeAllInstances, tmpdir } from "../fixture/fixture"
 
 void Log.init({ print: false })
 
@@ -24,7 +24,7 @@ const svc = {
 }
 
 afterEach(async () => {
-  await Instance.disposeAll()
+  await disposeAllInstances()
 })
 
 describe("tui.selectSession endpoint", () => {

+ 2 - 2
packages/opencode/test/snapshot/snapshot.test.ts

@@ -6,7 +6,7 @@ import { Effect } from "effect"
 import { Snapshot } from "../../src/snapshot"
 import { Instance } from "../../src/project/instance"
 import { Filesystem } from "@/util/filesystem"
-import { provideInstance, tmpdir } from "../fixture/fixture"
+import { disposeAllInstances, provideInstance, tmpdir } from "../fixture/fixture"
 
 // Git always outputs /-separated paths internally. Snapshot.patch() joins them
 // with path.join (which produces \ on Windows) then normalizes back to /.
@@ -14,7 +14,7 @@ import { provideInstance, tmpdir } from "../fixture/fixture"
 const fwd = (...parts: string[]) => path.join(...parts).replaceAll("\\", "/")
 
 afterEach(async () => {
-  await Instance.disposeAll()
+  await disposeAllInstances()
 })
 
 async function bootstrap() {

+ 2 - 2
packages/opencode/test/tool/edit.test.ts

@@ -4,7 +4,7 @@ import fs from "fs/promises"
 import { Effect, Layer, ManagedRuntime } from "effect"
 import { EditTool } from "../../src/tool/edit"
 import { Instance } from "../../src/project/instance"
-import { tmpdir } from "../fixture/fixture"
+import { disposeAllInstances, tmpdir } from "../fixture/fixture"
 import { LSP } from "@/lsp/lsp"
 import { AppFileSystem } from "@opencode-ai/core/filesystem"
 import { Format } from "../../src/format"
@@ -26,7 +26,7 @@ const ctx = {
 }
 
 afterEach(async () => {
-  await Instance.disposeAll()
+  await disposeAllInstances()
 })
 
 const runtime = ManagedRuntime.make(

+ 2 - 2
packages/opencode/test/tool/lsp.test.ts

@@ -11,11 +11,11 @@ import { MessageID, SessionID } from "../../src/session/schema"
 import { Tool } from "@/tool/tool"
 import { Truncate } from "@/tool/truncate"
 import { LspTool } from "../../src/tool/lsp"
-import { provideTmpdirInstance } from "../fixture/fixture"
+import { disposeAllInstances, provideTmpdirInstance } from "../fixture/fixture"
 import { testEffect } from "../lib/effect"
 
 afterEach(async () => {
-  await Instance.disposeAll()
+  await disposeAllInstances()
 })
 
 const ctx = {

+ 2 - 2
packages/opencode/test/tool/read.test.ts

@@ -13,13 +13,13 @@ import { ReadTool } from "../../src/tool/read"
 import { Truncate } from "@/tool/truncate"
 import { Tool } from "@/tool/tool"
 import { Filesystem } from "@/util/filesystem"
-import { provideInstance, tmpdirScoped } from "../fixture/fixture"
+import { disposeAllInstances, provideInstance, tmpdirScoped } from "../fixture/fixture"
 import { testEffect } from "../lib/effect"
 
 const FIXTURES_DIR = path.join(import.meta.dir, "fixtures")
 
 afterEach(async () => {
-  await Instance.disposeAll()
+  await disposeAllInstances()
 })
 
 const ctx = {

+ 2 - 2
packages/opencode/test/tool/registry.test.ts

@@ -5,7 +5,7 @@ import { Effect, Layer } from "effect"
 import { Instance } from "../../src/project/instance"
 import { CrossSpawnSpawner } from "@opencode-ai/core/cross-spawn-spawner"
 import { ToolRegistry } from "@/tool/registry"
-import { provideTmpdirInstance } from "../fixture/fixture"
+import { disposeAllInstances, provideTmpdirInstance } from "../fixture/fixture"
 import { testEffect } from "../lib/effect"
 
 const node = CrossSpawnSpawner.defaultLayer
@@ -13,7 +13,7 @@ const node = CrossSpawnSpawner.defaultLayer
 const it = testEffect(Layer.mergeAll(ToolRegistry.defaultLayer, node))
 
 afterEach(async () => {
-  await Instance.disposeAll()
+  await disposeAllInstances()
 })
 
 describe("tool.registry", () => {

+ 2 - 2
packages/opencode/test/tool/skill.test.ts

@@ -8,7 +8,7 @@ import type { Tool } from "@/tool/tool"
 import { Instance } from "../../src/project/instance"
 import { SkillTool } from "../../src/tool/skill"
 import { ToolRegistry } from "@/tool/registry"
-import { provideTmpdirInstance } from "../fixture/fixture"
+import { disposeAllInstances, provideTmpdirInstance } from "../fixture/fixture"
 import { SessionID, MessageID } from "../../src/session/schema"
 import { testEffect } from "../lib/effect"
 
@@ -23,7 +23,7 @@ const baseCtx: Omit<Tool.Context, "ask"> = {
 }
 
 afterEach(async () => {
-  await Instance.disposeAll()
+  await disposeAllInstances()
 })
 
 const node = CrossSpawnSpawner.defaultLayer

+ 2 - 2
packages/opencode/test/tool/task.test.ts

@@ -12,11 +12,11 @@ import { ModelID, ProviderID } from "../../src/provider/schema"
 import { TaskTool, type TaskPromptOps } from "../../src/tool/task"
 import { Truncate } from "@/tool/truncate"
 import { ToolRegistry } from "@/tool/registry"
-import { provideTmpdirInstance } from "../fixture/fixture"
+import { disposeAllInstances, provideTmpdirInstance } from "../fixture/fixture"
 import { testEffect } from "../lib/effect"
 
 afterEach(async () => {
-  await Instance.disposeAll()
+  await disposeAllInstances()
 })
 
 const ref = {

+ 2 - 2
packages/opencode/test/tool/write.test.ts

@@ -13,7 +13,7 @@ import { Tool } from "@/tool/tool"
 import { Agent } from "../../src/agent/agent"
 import { SessionID, MessageID } from "../../src/session/schema"
 import { CrossSpawnSpawner } from "@opencode-ai/core/cross-spawn-spawner"
-import { provideTmpdirInstance } from "../fixture/fixture"
+import { disposeAllInstances, provideTmpdirInstance } from "../fixture/fixture"
 import { testEffect } from "../lib/effect"
 
 const ctx = {
@@ -28,7 +28,7 @@ const ctx = {
 }
 
 afterEach(async () => {
-  await Instance.disposeAll()
+  await disposeAllInstances()
 })
 
 const it = testEffect(