Sfoglia il codice sorgente

refactor: rename workspace adapters (#25272)

Kit Langton 3 mesi fa
parent
commit
8c79c58c4d
25 ha cambiato i file con 225 aggiunte e 225 eliminazioni
  1. 2 2
      packages/opencode/specs/effect/http-api.md
  2. 1 1
      packages/opencode/specs/effect/schema.md
  3. 8 8
      packages/opencode/src/cli/cmd/tui/component/dialog-workspace-create.tsx
  4. 45 0
      packages/opencode/src/control-plane/adapters/index.ts
  5. 2 2
      packages/opencode/src/control-plane/adapters/worktree.ts
  6. 0 45
      packages/opencode/src/control-plane/adaptors/index.ts
  7. 3 3
      packages/opencode/src/control-plane/types.ts
  8. 13 13
      packages/opencode/src/control-plane/workspace.ts
  9. 5 5
      packages/opencode/src/plugin/index.ts
  10. 9 9
      packages/opencode/src/server/routes/control/workspace.ts
  11. 7 7
      packages/opencode/src/server/routes/instance/httpapi/groups/workspace.ts
  12. 4 4
      packages/opencode/src/server/routes/instance/httpapi/handlers/workspace.ts
  13. 3 3
      packages/opencode/src/server/routes/instance/httpapi/middleware/workspace-routing.ts
  14. 3 3
      packages/opencode/src/server/workspace.ts
  15. 12 12
      packages/opencode/test/control-plane/adapters.test.ts
  16. 51 51
      packages/opencode/test/control-plane/workspace.test.ts
  17. 2 2
      packages/opencode/test/plugin/workspace-adapter.test.ts
  18. 4 4
      packages/opencode/test/server/httpapi-instance-context.test.ts
  19. 4 4
      packages/opencode/test/server/httpapi-session.test.ts
  20. 10 10
      packages/opencode/test/server/httpapi-workspace-routing.test.ts
  21. 14 14
      packages/opencode/test/server/httpapi-workspace.test.ts
  22. 2 2
      packages/plugin/src/index.ts
  23. 9 9
      packages/sdk/js/src/v2/gen/sdk.gen.ts
  24. 6 6
      packages/sdk/js/src/v2/gen/types.gen.ts
  25. 6 6
      packages/sdk/openapi.json

+ 2 - 2
packages/opencode/specs/effect/http-api.md

@@ -198,7 +198,7 @@ Use raw Effect HTTP routes where `HttpApi` does not fit. The goal is deleting Ho
 | `project`                 | `bridged`         | list, current, git init, update                                            |
 | `file`                    | `bridged` partial | find text/file/symbol, list/content/status                                 |
 | `mcp`                     | `bridged`         | status, add, OAuth, connect/disconnect                                     |
-| `workspace`               | `bridged`         | adaptor/list/status/create/remove/session-restore                          |
+| `workspace`               | `bridged`         | adapter/list/status/create/remove/session-restore                          |
 | top-level instance routes | `bridged`         | path, vcs, command, agent, skill, lsp, formatter, dispose                  |
 | experimental JSON routes  | `bridged`         | console, tool, worktree list/mutations, global session list, resource list |
 | `session`                 | `bridged`         | read, lifecycle, prompt, message/part mutations, revert, permission reply  |
@@ -290,7 +290,7 @@ This checklist tracks bridge parity only. Checked routes are available through t
 
 ### Workspace Routes
 
-- [x] `GET /experimental/workspace/adaptor` - list workspace adaptors.
+- [x] `GET /experimental/workspace/adapter` - list workspace adapters.
 - [x] `POST /experimental/workspace` - create workspace.
 - [x] `GET /experimental/workspace` - list workspaces.
 - [x] `GET /experimental/workspace/status` - workspace status.

+ 1 - 1
packages/opencode/specs/effect/schema.md

@@ -353,7 +353,7 @@ piecewise.
 - [ ] `src/cli/cmd/tui/event.ts`
 - [ ] `src/cli/ui.ts`
 - [ ] `src/command/index.ts`
-- [x] `src/control-plane/adaptors/worktree.ts`
+- [x] `src/control-plane/adapters/worktree.ts`
 - [x] `src/control-plane/types.ts`
 - [x] `src/control-plane/workspace.ts`
 - [ ] `src/file/index.ts`

+ 8 - 8
packages/opencode/src/cli/cmd/tui/component/dialog-workspace-create.tsx

@@ -10,7 +10,7 @@ import { errorMessage } from "@/util/error"
 import { useSDK } from "../context/sdk"
 import { useToast } from "../ui/toast"
 
-type Adaptor = {
+type Adapter = {
   type: string
   name: string
   description: string
@@ -108,26 +108,26 @@ export function DialogWorkspaceCreate(props: { onSelect: (workspaceID: string) =
   const sdk = useSDK()
   const toast = useToast()
   const [creating, setCreating] = createSignal<string>()
-  const [adaptors, setAdaptors] = createSignal<Adaptor[]>()
+  const [adapters, setAdapters] = createSignal<Adapter[]>()
 
   onMount(() => {
     dialog.setSize("medium")
     void (async () => {
       const dir = sync.path.directory || sdk.directory
-      const url = new URL("/experimental/workspace/adaptor", sdk.url)
+      const url = new URL("/experimental/workspace/adapter", sdk.url)
       if (dir) url.searchParams.set("directory", dir)
       const res = await sdk
         .fetch(url)
-        .then((x) => x.json() as Promise<Adaptor[]>)
+        .then((x) => x.json() as Promise<Adapter[]>)
         .catch(() => undefined)
       if (!res) {
         toast.show({
-          message: "Failed to load workspace adaptors",
+          message: "Failed to load workspace adapters",
           variant: "error",
         })
         return
       }
-      setAdaptors(res)
+      setAdapters(res)
     })()
   })
 
@@ -142,13 +142,13 @@ export function DialogWorkspaceCreate(props: { onSelect: (workspaceID: string) =
         },
       ]
     }
-    const list = adaptors()
+    const list = adapters()
     if (!list) {
       return [
         {
           title: "Loading workspaces...",
           value: "loading" as const,
-          description: "Fetching available workspace adaptors",
+          description: "Fetching available workspace adapters",
         },
       ]
     }

+ 45 - 0
packages/opencode/src/control-plane/adapters/index.ts

@@ -0,0 +1,45 @@
+import type { ProjectID } from "@/project/schema"
+import type { WorkspaceAdapter, WorkspaceAdapterEntry } from "../types"
+import { WorktreeAdapter } from "./worktree"
+
+const BUILTIN: Record<string, WorkspaceAdapter> = {
+  worktree: WorktreeAdapter,
+}
+
+const state = new Map<ProjectID, Map<string, WorkspaceAdapter>>()
+
+export function getAdapter(projectID: ProjectID, type: string): WorkspaceAdapter {
+  const custom = state.get(projectID)?.get(type)
+  if (custom) return custom
+
+  const builtin = BUILTIN[type]
+  if (builtin) return builtin
+
+  throw new Error(`Unknown workspace adapter: ${type}`)
+}
+
+export async function listAdapters(projectID: ProjectID): Promise<WorkspaceAdapterEntry[]> {
+  const builtin = await Promise.all(
+    Object.entries(BUILTIN).map(async ([type, adapter]) => {
+      return {
+        type,
+        name: adapter.name,
+        description: adapter.description,
+      }
+    }),
+  )
+  const custom = [...(state.get(projectID)?.entries() ?? [])].map(([type, adapter]) => ({
+    type,
+    name: adapter.name,
+    description: adapter.description,
+  }))
+  return [...builtin, ...custom]
+}
+
+// Plugins can be loaded per-project so we need to scope them. If you
+// want to install a global one pass `ProjectID.global`
+export function registerAdapter(projectID: ProjectID, type: string, adapter: WorkspaceAdapter) {
+  const adapters = state.get(projectID) ?? new Map<string, WorkspaceAdapter>()
+  adapters.set(type, adapter)
+  state.set(projectID, adapters)
+}

+ 2 - 2
packages/opencode/src/control-plane/adaptors/worktree.ts → packages/opencode/src/control-plane/adapters/worktree.ts

@@ -1,5 +1,5 @@
 import { Schema } from "effect"
-import { type WorkspaceAdaptor, WorkspaceInfo } from "../types"
+import { type WorkspaceAdapter, WorkspaceInfo } from "../types"
 
 const WorktreeConfig = Schema.Struct({
   name: WorkspaceInfo.fields.name,
@@ -13,7 +13,7 @@ async function loadWorktree() {
   return { AppRuntime, Worktree }
 }
 
-export const WorktreeAdaptor: WorkspaceAdaptor = {
+export const WorktreeAdapter: WorkspaceAdapter = {
   name: "Worktree",
   description: "Create a git worktree",
   async configure(info) {

+ 0 - 45
packages/opencode/src/control-plane/adaptors/index.ts

@@ -1,45 +0,0 @@
-import type { ProjectID } from "@/project/schema"
-import type { WorkspaceAdaptor, WorkspaceAdaptorEntry } from "../types"
-import { WorktreeAdaptor } from "./worktree"
-
-const BUILTIN: Record<string, WorkspaceAdaptor> = {
-  worktree: WorktreeAdaptor,
-}
-
-const state = new Map<ProjectID, Map<string, WorkspaceAdaptor>>()
-
-export function getAdaptor(projectID: ProjectID, type: string): WorkspaceAdaptor {
-  const custom = state.get(projectID)?.get(type)
-  if (custom) return custom
-
-  const builtin = BUILTIN[type]
-  if (builtin) return builtin
-
-  throw new Error(`Unknown workspace adaptor: ${type}`)
-}
-
-export async function listAdaptors(projectID: ProjectID): Promise<WorkspaceAdaptorEntry[]> {
-  const builtin = await Promise.all(
-    Object.entries(BUILTIN).map(async ([type, adaptor]) => {
-      return {
-        type,
-        name: adaptor.name,
-        description: adaptor.description,
-      }
-    }),
-  )
-  const custom = [...(state.get(projectID)?.entries() ?? [])].map(([type, adaptor]) => ({
-    type,
-    name: adaptor.name,
-    description: adaptor.description,
-  }))
-  return [...builtin, ...custom]
-}
-
-// Plugins can be loaded per-project so we need to scope them. If you
-// want to install a global one pass `ProjectID.global`
-export function registerAdaptor(projectID: ProjectID, type: string, adaptor: WorkspaceAdaptor) {
-  const adaptors = state.get(projectID) ?? new Map<string, WorkspaceAdaptor>()
-  adaptors.set(type, adaptor)
-  state.set(projectID, adaptors)
-}

+ 3 - 3
packages/opencode/src/control-plane/types.ts

@@ -17,12 +17,12 @@ export const WorkspaceInfo = Schema.Struct({
   .pipe(withStatics((s) => ({ zod: zod(s) })))
 export type WorkspaceInfo = DeepMutable<Schema.Schema.Type<typeof WorkspaceInfo>>
 
-export const WorkspaceAdaptorEntry = Schema.Struct({
+export const WorkspaceAdapterEntry = Schema.Struct({
   type: Schema.String,
   name: Schema.String,
   description: Schema.String,
 }).pipe(withStatics((s) => ({ zod: zod(s) })))
-export type WorkspaceAdaptorEntry = Schema.Schema.Type<typeof WorkspaceAdaptorEntry>
+export type WorkspaceAdapterEntry = Schema.Schema.Type<typeof WorkspaceAdapterEntry>
 
 export type Target =
   | {
@@ -35,7 +35,7 @@ export type Target =
       headers?: HeadersInit
     }
 
-export type WorkspaceAdaptor = {
+export type WorkspaceAdapter = {
   name: string
   description: string
   configure(info: WorkspaceInfo): WorkspaceInfo | Promise<WorkspaceInfo>

+ 13 - 13
packages/opencode/src/control-plane/workspace.ts

@@ -16,7 +16,7 @@ import { Filesystem } from "@/util/filesystem"
 import { ProjectID } from "@/project/schema"
 import { Slug } from "@opencode-ai/core/util/slug"
 import { WorkspaceTable } from "./workspace.sql"
-import { getAdaptor } from "./adaptors"
+import { getAdapter } from "./adapters"
 import { type WorkspaceInfo, WorkspaceInfo as WorkspaceInfoSchema } from "./types"
 import { WorkspaceID } from "./schema"
 import { Session } from "@/session/session"
@@ -335,8 +335,8 @@ export const layer = Layer.effect(
     })
 
     const syncWorkspaceLoop = Effect.fn("Workspace.syncWorkspaceLoop")(function* (space: Info) {
-      const adaptor = getAdaptor(space.projectID, space.type)
-      const target = yield* Effect.promise(() => Promise.resolve(adaptor.target(space)))
+      const adapter = getAdapter(space.projectID, space.type)
+      const target = yield* Effect.promise(() => Promise.resolve(adapter.target(space)))
 
       if (target.type === "local") return
 
@@ -419,8 +419,8 @@ export const layer = Layer.effect(
     const startSync = Effect.fn("Workspace.startSync")(function* (space: Info) {
       if (!Flag.OPENCODE_EXPERIMENTAL_WORKSPACES) return
 
-      const adaptor = getAdaptor(space.projectID, space.type)
-      const target = yield* Effect.promise(() => Promise.resolve(adaptor.target(space)))
+      const adapter = getAdapter(space.projectID, space.type)
+      const target = yield* Effect.promise(() => Promise.resolve(adapter.target(space)))
 
       if (target.type === "local") {
         setStatus(space.id, (yield* Effect.promise(() => Filesystem.exists(target.directory))) ? "connected" : "error")
@@ -458,9 +458,9 @@ export const layer = Layer.effect(
 
     const create = Effect.fn("Workspace.create")(function* (input: CreateInput) {
       const id = WorkspaceID.ascending(input.id)
-      const adaptor = getAdaptor(input.projectID, input.type)
+      const adapter = getAdapter(input.projectID, input.type)
       const config = yield* Effect.promise(() =>
-        Promise.resolve(adaptor.configure({ ...input, id, name: Slug.create(), directory: null })),
+        Promise.resolve(adapter.configure({ ...input, id, name: Slug.create(), directory: null })),
       )
 
       const info: Info = {
@@ -496,7 +496,7 @@ export const layer = Layer.effect(
         OTEL_RESOURCE_ATTRIBUTES: process.env.OTEL_RESOURCE_ATTRIBUTES,
       }
 
-      yield* Effect.promise(() => adaptor.create(config, env))
+      yield* Effect.promise(() => adapter.create(config, env))
       yield* Effect.all(
         [
           waitEvent({
@@ -531,8 +531,8 @@ export const layer = Layer.effect(
             workspaceID: input.workspaceID,
           })
 
-        const adaptor = getAdaptor(space.projectID, space.type)
-        const target = yield* Effect.promise(() => Promise.resolve(adaptor.target(space)))
+        const adapter = getAdapter(space.projectID, space.type)
+        const target = yield* Effect.promise(() => Promise.resolve(adapter.target(space)))
 
         yield* sync.run(Session.Event.Updated, {
           sessionID: input.sessionID,
@@ -726,12 +726,12 @@ export const layer = Layer.effect(
       const info = fromRow(row)
       yield* Effect.catch(
         Effect.gen(function* () {
-          const adaptor = getAdaptor(info.projectID, row.type)
-          yield* Effect.tryPromise(() => Promise.resolve(adaptor.remove(info)))
+          const adapter = getAdapter(info.projectID, row.type)
+          yield* Effect.tryPromise(() => Promise.resolve(adapter.remove(info)))
         }),
         () =>
           Effect.sync(() => {
-            log.error("adaptor not available when removing workspace", { type: row.type })
+            log.error("adapter not available when removing workspace", { type: row.type })
           }),
       )
 

+ 5 - 5
packages/opencode/src/plugin/index.ts

@@ -3,7 +3,7 @@ import type {
   PluginInput,
   Plugin as PluginInstance,
   PluginModule,
-  WorkspaceAdaptor as PluginWorkspaceAdaptor,
+  WorkspaceAdapter as PluginWorkspaceAdapter,
 } from "@opencode-ai/plugin"
 import { Config } from "@/config/config"
 import { Bus } from "../bus"
@@ -24,8 +24,8 @@ import { InstanceState } from "@/effect/instance-state"
 import { errorMessage } from "@/util/error"
 import { PluginLoader } from "./loader"
 import { parsePluginSpecifier, readPluginId, readV1Plugin, resolvePluginId } from "./shared"
-import { registerAdaptor } from "@/control-plane/adaptors"
-import type { WorkspaceAdaptor } from "@/control-plane/types"
+import { registerAdapter } from "@/control-plane/adapters"
+import type { WorkspaceAdapter } from "@/control-plane/types"
 
 const log = Log.create({ service: "plugin" })
 
@@ -138,8 +138,8 @@ export const layer = Layer.effect(
           worktree: ctx.worktree,
           directory: ctx.directory,
           experimental_workspace: {
-            register(type: string, adaptor: PluginWorkspaceAdaptor) {
-              registerAdaptor(ctx.project.id, type, adaptor as WorkspaceAdaptor)
+            register(type: string, adapter: PluginWorkspaceAdapter) {
+              registerAdapter(ctx.project.id, type, adapter as WorkspaceAdapter)
             },
           },
           get serverUrl(): URL {

+ 9 - 9
packages/opencode/src/server/routes/control/workspace.ts

@@ -2,10 +2,10 @@ import { Hono } from "hono"
 import { describeRoute, resolver, validator } from "hono-openapi"
 import z from "zod"
 import { Effect } from "effect"
-import { listAdaptors } from "@/control-plane/adaptors"
+import { listAdapters } from "@/control-plane/adapters"
 import { Workspace } from "@/control-plane/workspace"
 import { AppRuntime } from "@/effect/app-runtime"
-import { WorkspaceAdaptorEntry } from "@/control-plane/types"
+import { WorkspaceAdapterEntry } from "@/control-plane/types"
 import { zodObject } from "@/util/effect-zod"
 import { Instance } from "@/project/instance"
 import { errors } from "../../error"
@@ -18,24 +18,24 @@ const log = Log.create({ service: "server.workspace" })
 export const WorkspaceRoutes = lazy(() =>
   new Hono()
     .get(
-      "/adaptor",
+      "/adapter",
       describeRoute({
-        summary: "List workspace adaptors",
-        description: "List all available workspace adaptors for the current project.",
-        operationId: "experimental.workspace.adaptor.list",
+        summary: "List workspace adapters",
+        description: "List all available workspace adapters for the current project.",
+        operationId: "experimental.workspace.adapter.list",
         responses: {
           200: {
-            description: "Workspace adaptors",
+            description: "Workspace adapters",
             content: {
               "application/json": {
-                schema: resolver(z.array(zodObject(WorkspaceAdaptorEntry))),
+                schema: resolver(z.array(zodObject(WorkspaceAdapterEntry))),
               },
             },
           },
         },
       }),
       async (c) => {
-        return c.json(await listAdaptors(Instance.project.id))
+        return c.json(await listAdapters(Instance.project.id))
       },
     )
     .post(

+ 7 - 7
packages/opencode/src/server/routes/instance/httpapi/groups/workspace.ts

@@ -1,5 +1,5 @@
 import { Workspace } from "@/control-plane/workspace"
-import { WorkspaceAdaptorEntry } from "@/control-plane/types"
+import { WorkspaceAdapterEntry } from "@/control-plane/types"
 import { NonNegativeInt } from "@/util/schema"
 import { Schema, Struct } from "effect"
 import { HttpApi, HttpApiEndpoint, HttpApiError, HttpApiGroup, OpenApi } from "effect/unstable/httpapi"
@@ -16,7 +16,7 @@ export const SessionRestoreResponse = Schema.Struct({
 })
 
 export const WorkspacePaths = {
-  adaptors: `${root}/adaptor`,
+  adapters: `${root}/adapter`,
   list: root,
   status: `${root}/status`,
   remove: `${root}/:id`,
@@ -27,13 +27,13 @@ export const WorkspaceApi = HttpApi.make("workspace")
   .add(
     HttpApiGroup.make("workspace")
       .add(
-        HttpApiEndpoint.get("adaptors", WorkspacePaths.adaptors, {
-          success: described(Schema.Array(WorkspaceAdaptorEntry), "Workspace adaptors"),
+        HttpApiEndpoint.get("adapters", WorkspacePaths.adapters, {
+          success: described(Schema.Array(WorkspaceAdapterEntry), "Workspace adapters"),
         }).annotateMerge(
           OpenApi.annotations({
-            identifier: "experimental.workspace.adaptor.list",
-            summary: "List workspace adaptors",
-            description: "List all available workspace adaptors for the current project.",
+            identifier: "experimental.workspace.adapter.list",
+            summary: "List workspace adapters",
+            description: "List all available workspace adapters for the current project.",
           }),
         ),
         HttpApiEndpoint.get("list", WorkspacePaths.list, {

+ 4 - 4
packages/opencode/src/server/routes/instance/httpapi/handlers/workspace.ts

@@ -1,4 +1,4 @@
-import { listAdaptors } from "@/control-plane/adaptors"
+import { listAdapters } from "@/control-plane/adapters"
 import { Workspace } from "@/control-plane/workspace"
 import * as InstanceState from "@/effect/instance-state"
 import { Effect } from "effect"
@@ -10,9 +10,9 @@ export const workspaceHandlers = HttpApiBuilder.group(InstanceHttpApi, "workspac
   Effect.gen(function* () {
     const workspace = yield* Workspace.Service
 
-    const adaptors = Effect.fn("WorkspaceHttpApi.adaptors")(function* () {
+    const adapters = Effect.fn("WorkspaceHttpApi.adapters")(function* () {
       const instance = yield* InstanceState.context
-      return yield* Effect.promise(() => listAdaptors(instance.project.id))
+      return yield* Effect.promise(() => listAdapters(instance.project.id))
     })
 
     const list = Effect.fn("WorkspaceHttpApi.list")(function* () {
@@ -51,7 +51,7 @@ export const workspaceHandlers = HttpApiBuilder.group(InstanceHttpApi, "workspac
     })
 
     return handlers
-      .handle("adaptors", adaptors)
+      .handle("adapters", adapters)
       .handle("list", list)
       .handle("create", create)
       .handle("status", status)

+ 3 - 3
packages/opencode/src/server/routes/instance/httpapi/middleware/workspace-routing.ts

@@ -1,4 +1,4 @@
-import { getAdaptor } from "@/control-plane/adaptors"
+import { getAdapter } from "@/control-plane/adapters"
 import { WorkspaceID } from "@/control-plane/schema"
 import type { Target } from "@/control-plane/types"
 import { Workspace } from "@/control-plane/workspace"
@@ -89,8 +89,8 @@ function missingWorkspaceResponse(id: WorkspaceID): HttpServerResponse.HttpServe
 
 function resolveTarget(workspace: Workspace.Info): Effect.Effect<Target> {
   return Effect.gen(function* () {
-    const adaptor = yield* Effect.sync(() => getAdaptor(workspace.projectID, workspace.type))
-    return yield* Effect.promise(() => Promise.resolve(adaptor.target(workspace)))
+    const adapter = yield* Effect.sync(() => getAdapter(workspace.projectID, workspace.type))
+    return yield* Effect.promise(() => Promise.resolve(adapter.target(workspace)))
   })
 }
 

+ 3 - 3
packages/opencode/src/server/workspace.ts

@@ -1,6 +1,6 @@
 import type { MiddlewareHandler } from "hono"
 import type { UpgradeWebSocket } from "hono/ws"
-import { getAdaptor } from "@/control-plane/adaptors"
+import { getAdapter } from "@/control-plane/adapters"
 import { WorkspaceID } from "@/control-plane/schema"
 import { WorkspaceContext } from "@/control-plane/workspace-context"
 import { Workspace } from "@/control-plane/workspace"
@@ -91,8 +91,8 @@ export function WorkspaceRouterMiddleware(upgrade: UpgradeWebSocket): Middleware
       return next()
     }
 
-    const adaptor = getAdaptor(workspace.projectID, workspace.type)
-    const target = await adaptor.target(workspace)
+    const adapter = getAdapter(workspace.projectID, workspace.type)
+    const target = await adapter.target(workspace)
 
     if (target.type === "local") {
       return WorkspaceContext.provide({

+ 12 - 12
packages/opencode/test/control-plane/adaptors.test.ts → packages/opencode/test/control-plane/adapters.test.ts

@@ -1,5 +1,5 @@
 import { describe, expect, test } from "bun:test"
-import { getAdaptor, registerAdaptor } from "../../src/control-plane/adaptors"
+import { getAdapter, registerAdapter } from "../../src/control-plane/adapters"
 import { ProjectID } from "../../src/project/schema"
 import type { WorkspaceInfo } from "../../src/control-plane/types"
 
@@ -15,7 +15,7 @@ function info(projectID: WorkspaceInfo["projectID"], type: string): WorkspaceInf
   }
 }
 
-function adaptor(dir: string) {
+function adapter(dir: string) {
   return {
     name: dir,
     description: dir,
@@ -33,19 +33,19 @@ function adaptor(dir: string) {
   }
 }
 
-describe("control-plane/adaptors", () => {
-  test("isolates custom adaptors by project", async () => {
+describe("control-plane/adapters", () => {
+  test("isolates custom adapters by project", async () => {
     const type = `demo-${Math.random().toString(36).slice(2)}`
     const one = ProjectID.make(`project-${Math.random().toString(36).slice(2)}`)
     const two = ProjectID.make(`project-${Math.random().toString(36).slice(2)}`)
-    registerAdaptor(one, type, adaptor("/one"))
-    registerAdaptor(two, type, adaptor("/two"))
+    registerAdapter(one, type, adapter("/one"))
+    registerAdapter(two, type, adapter("/two"))
 
-    expect(await (await getAdaptor(one, type)).target(info(one, type))).toEqual({
+    expect(await (await getAdapter(one, type)).target(info(one, type))).toEqual({
       type: "local",
       directory: "/one",
     })
-    expect(await (await getAdaptor(two, type)).target(info(two, type))).toEqual({
+    expect(await (await getAdapter(two, type)).target(info(two, type))).toEqual({
       type: "local",
       directory: "/two",
     })
@@ -54,16 +54,16 @@ describe("control-plane/adaptors", () => {
   test("latest install wins within a project", async () => {
     const type = `demo-${Math.random().toString(36).slice(2)}`
     const id = ProjectID.make(`project-${Math.random().toString(36).slice(2)}`)
-    registerAdaptor(id, type, adaptor("/one"))
+    registerAdapter(id, type, adapter("/one"))
 
-    expect(await (await getAdaptor(id, type)).target(info(id, type))).toEqual({
+    expect(await (await getAdapter(id, type)).target(info(id, type))).toEqual({
       type: "local",
       directory: "/one",
     })
 
-    registerAdaptor(id, type, adaptor("/two"))
+    registerAdapter(id, type, adapter("/two"))
 
-    expect(await (await getAdaptor(id, type)).target(info(id, type))).toEqual({
+    expect(await (await getAdapter(id, type)).target(info(id, type))).toEqual({
       type: "local",
       directory: "/two",
     })

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

@@ -23,10 +23,10 @@ import { EventSequenceTable, EventTable } from "@/sync/event.sql"
 import { resetDatabase } from "../fixture/db"
 import { provideTmpdirInstance, tmpdir } from "../fixture/fixture"
 import { testEffect } from "../lib/effect"
-import { registerAdaptor } from "../../src/control-plane/adaptors"
+import { registerAdapter } from "../../src/control-plane/adapters"
 import { WorkspaceID } from "../../src/control-plane/schema"
 import { WorkspaceTable } from "../../src/control-plane/workspace.sql"
-import type { Target, WorkspaceAdaptor, WorkspaceInfo } from "../../src/control-plane/types"
+import type { Target, WorkspaceAdapter, WorkspaceInfo } from "../../src/control-plane/types"
 import * as WorkspaceOld from "../../src/control-plane/workspace"
 import { AppRuntime } from "@/effect/app-runtime"
 
@@ -53,8 +53,8 @@ type RecordedCreate = {
   from?: WorkspaceInfo
 }
 
-type RecordedAdaptor = {
-  adaptor: WorkspaceAdaptor
+type RecordedAdapter = {
+  adapter: WorkspaceAdapter
   calls: {
     configure: WorkspaceInfo[]
     create: RecordedCreate[]
@@ -165,13 +165,13 @@ function eventuallyEffect(effect: Effect.Effect<void>, timeout = 1500) {
   })
 }
 
-function recordedAdaptor(input: {
+function recordedAdapter(input: {
   target: (info: WorkspaceInfo) => Target | Promise<Target>
   configure?: (info: WorkspaceInfo) => WorkspaceInfo | Promise<WorkspaceInfo>
   create?: (info: WorkspaceInfo, env: Record<string, string | undefined>, from?: WorkspaceInfo) => Promise<void>
   remove?: (info: WorkspaceInfo) => Promise<void>
-}): RecordedAdaptor {
-  const calls: RecordedAdaptor["calls"] = {
+}): RecordedAdapter {
+  const calls: RecordedAdapter["calls"] = {
     configure: [],
     create: [],
     remove: [],
@@ -180,7 +180,7 @@ function recordedAdaptor(input: {
 
   return {
     calls,
-    adaptor: {
+    adapter: {
       name: "recorded",
       description: "recorded",
       configure(info) {
@@ -207,8 +207,8 @@ function recordedAdaptor(input: {
   }
 }
 
-function localAdaptor(dir: string, input?: { createDir?: boolean; remove?: (info: WorkspaceInfo) => Promise<void> }) {
-  return recordedAdaptor({
+function localAdapter(dir: string, input?: { createDir?: boolean; remove?: (info: WorkspaceInfo) => Promise<void> }) {
+  return recordedAdapter({
     configure(info) {
       return { ...info, directory: dir }
     },
@@ -223,8 +223,8 @@ function localAdaptor(dir: string, input?: { createDir?: boolean; remove?: (info
   })
 }
 
-function remoteAdaptor(url: string, input?: { directory?: string | null; headers?: HeadersInit }) {
-  return recordedAdaptor({
+function remoteAdapter(url: string, input?: { directory?: string | null; headers?: HeadersInit }) {
+  return recordedAdapter({
     configure(info) {
       return { ...info, directory: input?.directory ?? info.directory }
     },
@@ -429,7 +429,7 @@ describe("workspace-old CRUD", () => {
       const workspaceID = WorkspaceID.ascending("wrk_create_local")
       const type = unique("create-local")
       const targetDir = path.join(dir, "created-local")
-      const recorded = recordedAdaptor({
+      const recorded = recordedAdapter({
         configure(info) {
           return {
             ...info,
@@ -446,7 +446,7 @@ describe("workspace-old CRUD", () => {
           return { type: "local", directory: targetDir }
         },
       })
-      registerAdaptor(Instance.project.id, type, recorded.adaptor)
+      registerAdapter(Instance.project.id, type, recorded.adapter)
 
       const info = await createWorkspace({
         id: workspaceID,
@@ -489,17 +489,17 @@ describe("workspace-old CRUD", () => {
   test("create propagates configure failures and does not insert a workspace", async () => {
     await withInstance(async () => {
       const type = unique("configure-failure")
-      registerAdaptor(
+      registerAdapter(
         Instance.project.id,
         type,
-        recordedAdaptor({
+        recordedAdapter({
           configure() {
             throw new Error("configure exploded")
           },
           target() {
             return { type: "local", directory: "/unused" }
           },
-        }).adaptor,
+        }).adapter,
       )
 
       await expect(
@@ -509,10 +509,10 @@ describe("workspace-old CRUD", () => {
     })
   })
 
-  test("create leaves the inserted row when adaptor create fails", async () => {
+  test("create leaves the inserted row when adapter create fails", async () => {
     await withInstance(async () => {
       const type = unique("create-failure")
-      const recorded = recordedAdaptor({
+      const recorded = recordedAdapter({
         async create() {
           throw new Error("create exploded")
         },
@@ -520,7 +520,7 @@ describe("workspace-old CRUD", () => {
           return { type: "local", directory: "/unused" }
         },
       })
-      registerAdaptor(Instance.project.id, type, recorded.adaptor)
+      registerAdapter(Instance.project.id, type, recorded.adapter)
 
       await expect(
         createWorkspace({ type, branch: "branch", projectID: Instance.project.id, extra: { x: 1 } }),
@@ -538,8 +538,8 @@ describe("workspace-old CRUD", () => {
     await withInstance(async (dir) => {
       const type = unique("local-error")
       const missing = path.join(dir, "missing-local-target")
-      const recorded = localAdaptor(missing, { createDir: false })
-      registerAdaptor(Instance.project.id, type, recorded.adaptor)
+      const recorded = localAdapter(missing, { createDir: false })
+      registerAdapter(Instance.project.id, type, recorded.adapter)
 
       const info = await createWorkspace({ type, branch: null, projectID: Instance.project.id, extra: null })
 
@@ -576,8 +576,8 @@ describe("workspace-old CRUD", () => {
           Effect.gen(function* () {
             const workspace = yield* WorkspaceOld.Service
             const type = unique("remote-create")
-            const recorded = remoteAdaptor(`${url}/base/?ignored=1#hash`, { directory: dir })
-            registerAdaptor(Instance.project.id, type, recorded.adaptor)
+            const recorded = remoteAdapter(`${url}/base/?ignored=1#hash`, { directory: dir })
+            registerAdapter(Instance.project.id, type, recorded.adapter)
 
             const info = yield* workspace.create({ type, branch: null, projectID: Instance.project.id, extra: null })
 
@@ -603,11 +603,11 @@ describe("workspace-old CRUD", () => {
     })
   })
 
-  test("remove deletes the workspace, associated sessions, adaptor resources, and status", async () => {
+  test("remove deletes the workspace, associated sessions, adapter resources, and status", async () => {
     await withInstance(async (dir) => {
       const type = unique("remove-local")
-      const recorded = localAdaptor(path.join(dir, "remove-local"))
-      registerAdaptor(Instance.project.id, type, recorded.adaptor)
+      const recorded = localAdapter(path.join(dir, "remove-local"))
+      registerAdapter(Instance.project.id, type, recorded.adapter)
       const info = await createWorkspace({ type, branch: null, projectID: Instance.project.id, extra: null })
       const one = await AppRuntime.runPromise(SessionNs.Service.use((svc) => svc.create({})))
       const two = await AppRuntime.runPromise(SessionNs.Service.use((svc) => svc.create({})))
@@ -628,21 +628,21 @@ describe("workspace-old CRUD", () => {
     })
   })
 
-  test("remove still deletes the row when the adaptor cannot remove resources", async () => {
+  test("remove still deletes the row when the adapter cannot remove resources", async () => {
     await withInstance(async () => {
       const type = unique("remove-throws")
       const info = workspaceInfo(Instance.project.id, type, { id: WorkspaceID.ascending("wrk_remove_throws") })
-      registerAdaptor(
+      registerAdapter(
         Instance.project.id,
         type,
-        recordedAdaptor({
+        recordedAdapter({
           async remove() {
             throw new Error("remove exploded")
           },
           target() {
             return { type: "local", directory: "/unused" }
           },
-        }).adaptor,
+        }).adapter,
       )
       insertWorkspace(info)
 
@@ -661,7 +661,7 @@ describe("workspace-old sync state", () => {
       const session = await AppRuntime.runPromise(SessionNs.Service.use((svc) => svc.create({})))
       attachSessionToWorkspace(session.id, info.id)
       insertWorkspace(info)
-      registerAdaptor(Instance.project.id, type, localAdaptor(path.join(dir, "flag-disabled")).adaptor)
+      registerAdapter(Instance.project.id, type, localAdapter(path.join(dir, "flag-disabled")).adapter)
 
       startWorkspaceSyncing(Instance.project.id)
       await delay(25)
@@ -682,8 +682,8 @@ describe("workspace-old sync state", () => {
       await fs.mkdir(withoutSessionDir, { recursive: true })
       insertWorkspace(withSession)
       insertWorkspace(withoutSession)
-      registerAdaptor(Instance.project.id, withSessionType, localAdaptor(withSessionDir).adaptor)
-      registerAdaptor(Instance.project.id, withoutSessionType, localAdaptor(withoutSessionDir).adaptor)
+      registerAdapter(Instance.project.id, withSessionType, localAdapter(withSessionDir).adapter)
+      registerAdapter(Instance.project.id, withoutSessionType, localAdapter(withoutSessionDir).adapter)
       attachSessionToWorkspace(
         (await AppRuntime.runPromise(SessionNs.Service.use((svc) => svc.create({})))).id,
         withSession.id,
@@ -707,10 +707,10 @@ describe("workspace-old sync state", () => {
       const type = unique("missing-local")
       const info = workspaceInfo(Instance.project.id, type)
       insertWorkspace(info)
-      registerAdaptor(
+      registerAdapter(
         Instance.project.id,
         type,
-        localAdaptor(path.join(dir, "missing-target"), { createDir: false }).adaptor,
+        localAdapter(path.join(dir, "missing-target"), { createDir: false }).adapter,
       )
       attachSessionToWorkspace(
         (await AppRuntime.runPromise(SessionNs.Service.use((svc) => svc.create({})))).id,
@@ -738,7 +738,7 @@ describe("workspace-old sync state", () => {
         const target = path.join(dir, "dedupe-local")
         await fs.mkdir(target, { recursive: true })
         insertWorkspace(info)
-        registerAdaptor(Instance.project.id, type, localAdaptor(target).adaptor)
+        registerAdapter(Instance.project.id, type, localAdapter(target).adapter)
         attachSessionToWorkspace(
           (await AppRuntime.runPromise(SessionNs.Service.use((svc) => svc.create({})))).id,
           info.id,
@@ -795,7 +795,7 @@ describe("workspace-old sync state", () => {
               const type = unique("remote-start")
               const info = workspaceInfo(Instance.project.id, type)
               insertWorkspace(info)
-              registerAdaptor(Instance.project.id, type, remoteAdaptor(`${url}/sync`).adaptor)
+              registerAdapter(Instance.project.id, type, remoteAdapter(`${url}/sync`).adapter)
               attachSessionToWorkspace((yield* sessionSvc.create({})).id, info.id)
 
               yield* workspace.startWorkspaceSyncing(Instance.project.id)
@@ -850,7 +850,7 @@ describe("workspace-old sync state", () => {
             const type = unique("remote-connect-fail")
             const info = workspaceInfo(Instance.project.id, type)
             insertWorkspace(info)
-            registerAdaptor(Instance.project.id, type, remoteAdaptor(`${url}/failed`).adaptor)
+            registerAdapter(Instance.project.id, type, remoteAdapter(`${url}/failed`).adapter)
             attachSessionToWorkspace((yield* sessionSvc.create({})).id, info.id)
 
             yield* workspace.startWorkspaceSyncing(Instance.project.id)
@@ -890,7 +890,7 @@ describe("workspace-old sync state", () => {
             const type = unique("remote-history-fail")
             const info = workspaceInfo(Instance.project.id, type)
             insertWorkspace(info)
-            registerAdaptor(Instance.project.id, type, remoteAdaptor(`${url}/history-failed`).adaptor)
+            registerAdapter(Instance.project.id, type, remoteAdapter(`${url}/history-failed`).adapter)
             attachSessionToWorkspace((yield* sessionSvc.create({})).id, info.id)
 
             yield* workspace.startWorkspaceSyncing(Instance.project.id)
@@ -947,7 +947,7 @@ describe("workspace-old sync state", () => {
               const type = unique("history-replay")
               const info = workspaceInfo(Instance.project.id, type)
               insertWorkspace(info)
-              registerAdaptor(Instance.project.id, type, remoteAdaptor(`${url}/history`).adaptor)
+              registerAdapter(Instance.project.id, type, remoteAdapter(`${url}/history`).adapter)
               const session = yield* sessionSvc.create({ title: "before history" })
               attachSessionToWorkspace(session.id, info.id)
               historySessionID = session.id
@@ -1014,7 +1014,7 @@ describe("workspace-old sync state", () => {
               const type = unique("sse-forward")
               const info = workspaceInfo(Instance.project.id, type)
               insertWorkspace(info)
-              registerAdaptor(Instance.project.id, type, remoteAdaptor(`${url}/sse-forward`).adaptor)
+              registerAdapter(Instance.project.id, type, remoteAdapter(`${url}/sse-forward`).adapter)
               attachSessionToWorkspace((yield* sessionSvc.create({})).id, info.id)
 
               yield* workspace.startWorkspaceSyncing(Instance.project.id)
@@ -1095,7 +1095,7 @@ describe("workspace-old sync state", () => {
               const type = unique("sse-sync")
               const info = workspaceInfo(Instance.project.id, type)
               insertWorkspace(info)
-              registerAdaptor(Instance.project.id, type, remoteAdaptor(`${url}/sse-sync`).adaptor)
+              registerAdapter(Instance.project.id, type, remoteAdapter(`${url}/sse-sync`).adapter)
               const session = yield* sessionSvc.create({ title: "before sse" })
               attachSessionToWorkspace(session.id, info.id)
               sseSessionID = session.id
@@ -1232,7 +1232,7 @@ describe("workspace-old sessionRestore", () => {
       const type = unique("restore-missing-session")
       const info = workspaceInfo(Instance.project.id, type, { directory: dir })
       insertWorkspace(info)
-      registerAdaptor(Instance.project.id, type, localAdaptor(dir).adaptor)
+      registerAdapter(Instance.project.id, type, localAdapter(dir).adapter)
 
       await expect(
         restoreWorkspaceSession({ workspaceID: info.id, sessionID: SessionID.descending("ses_missing_restore") }),
@@ -1273,13 +1273,13 @@ describe("workspace-old sessionRestore", () => {
               const type = unique("restore-remote")
               const info = workspaceInfo(Instance.project.id, type, { directory: dir })
               insertWorkspace(info)
-              registerAdaptor(
+              registerAdapter(
                 Instance.project.id,
                 type,
-                remoteAdaptor(`${url}/restore/?ignored=1#hash`, {
+                remoteAdapter(`${url}/restore/?ignored=1#hash`, {
                   directory: dir,
                   headers: { authorization: "Bearer restore" },
-                }).adaptor,
+                }).adapter,
               )
               const session = yield* sessionSvc.create({ title: "restore remote" })
               replaceSessionEvents(session.id, 24)
@@ -1353,7 +1353,7 @@ describe("workspace-old sessionRestore", () => {
             const type = unique("restore-null-dir")
             const info = workspaceInfo(Instance.project.id, type, { directory: null })
             insertWorkspace(info)
-            registerAdaptor(Instance.project.id, type, remoteAdaptor(`${url}/null-dir`, { directory: null }).adaptor)
+            registerAdapter(Instance.project.id, type, remoteAdapter(`${url}/null-dir`, { directory: null }).adapter)
             const session = yield* sessionSvc.create({ title: "null dir" })
             replaceSessionEvents(session.id, 0)
 
@@ -1397,7 +1397,7 @@ describe("workspace-old sessionRestore", () => {
               const type = unique("restore-remote-fail")
               const info = workspaceInfo(Instance.project.id, type, { directory: dir })
               insertWorkspace(info)
-              registerAdaptor(Instance.project.id, type, remoteAdaptor(`${url}/fail`, { directory: dir }).adaptor)
+              registerAdapter(Instance.project.id, type, remoteAdapter(`${url}/fail`, { directory: dir }).adapter)
               const session = yield* sessionSvc.create({ title: "restore fail" })
               replaceSessionEvents(session.id, 11)
 
@@ -1437,7 +1437,7 @@ describe("workspace-old sessionRestore", () => {
             const type = unique("restore-local")
             const info = workspaceInfo(Instance.project.id, type, { directory: dir })
             insertWorkspace(info)
-            registerAdaptor(Instance.project.id, type, localAdaptor(dir).adaptor)
+            registerAdapter(Instance.project.id, type, localAdapter(dir).adapter)
             const session = yield* sessionSvc.create({ title: "restore local" })
             replaceSessionEvents(session.id, 20)
 
@@ -1488,7 +1488,7 @@ describe("workspace-old sessionRestore", () => {
             const type = unique("restore-real-events")
             const info = workspaceInfo(Instance.project.id, type, { directory: dir })
             insertWorkspace(info)
-            registerAdaptor(Instance.project.id, type, remoteAdaptor(`${url}/real`, { directory: dir }).adaptor)
+            registerAdapter(Instance.project.id, type, remoteAdapter(`${url}/real`, { directory: dir }).adapter)
             const session = yield* sessionSvc.create({ title: "real events" })
             for (let i = 0; i < 3; i++) {
               const msg = yield* sessionSvc.updateMessage({

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

@@ -34,7 +34,7 @@ afterAll(() => {
 })
 
 describe("plugin.workspace", () => {
-  it.live("plugin can install a workspace adaptor", () =>
+  it.live("plugin can install a workspace adapter", () =>
     provideTmpdirInstance((dir) =>
       Effect.gen(function* () {
         const type = `plug-${Math.random().toString(36).slice(2)}`
@@ -48,7 +48,7 @@ describe("plugin.workspace", () => {
               "export default async ({ experimental_workspace }) => {",
               `  experimental_workspace.register(${JSON.stringify(type)}, {`,
               '    name: "plug",',
-              '    description: "plugin workspace adaptor",',
+              '    description: "plugin workspace adapter",',
               "    configure(input) {",
               `      return { ...input, name: "plug", branch: "plug/main", directory: ${JSON.stringify(space)} }`,
               "    },",

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

@@ -7,8 +7,8 @@ import { HttpClient, HttpClientRequest, HttpRouter, HttpServerResponse } from "e
 import * as Socket from "effect/unstable/socket/Socket"
 import { mkdir } from "node:fs/promises"
 import path from "node:path"
-import { registerAdaptor } from "../../src/control-plane/adaptors"
-import type { WorkspaceAdaptor } from "../../src/control-plane/types"
+import { registerAdapter } from "../../src/control-plane/adapters"
+import type { WorkspaceAdapter } from "../../src/control-plane/types"
 import { Workspace } from "../../src/control-plane/workspace"
 import { InstanceRef, WorkspaceRef } from "../../src/effect/instance-ref"
 import { Instance } from "../../src/project/instance"
@@ -49,7 +49,7 @@ const instanceContextTestLayer = instanceRouterMiddleware
   .combine(workspaceRouterMiddleware)
   .layer.pipe(Layer.provide(Socket.layerWebSocketConstructorGlobal))
 
-const localAdaptor = (directory: string): WorkspaceAdaptor => ({
+const localAdapter = (directory: string): WorkspaceAdapter => ({
   name: "Local Test",
   description: "Create a local test workspace",
   configure: (info) => ({ ...info, name: "local-test", directory }),
@@ -63,7 +63,7 @@ const localAdaptor = (directory: string): WorkspaceAdaptor => ({
 const createLocalWorkspace = (input: { projectID: Project.Info["id"]; type: string; directory: string }) =>
   Effect.acquireRelease(
     Effect.gen(function* () {
-      registerAdaptor(input.projectID, input.type, localAdaptor(input.directory))
+      registerAdapter(input.projectID, input.type, localAdapter(input.directory))
       const workspace = yield* Workspace.Service
       return yield* workspace.create({
         type: input.type,

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

@@ -3,8 +3,8 @@ import { mkdir } from "node:fs/promises"
 import path from "node:path"
 import { Effect } from "effect"
 import { Flag } from "@opencode-ai/core/flag/flag"
-import { registerAdaptor } from "../../src/control-plane/adaptors"
-import type { WorkspaceAdaptor } from "../../src/control-plane/types"
+import { registerAdapter } from "../../src/control-plane/adapters"
+import type { WorkspaceAdapter } from "../../src/control-plane/types"
 import { Workspace } from "../../src/control-plane/workspace"
 import { PermissionID } from "../../src/permission/schema"
 import { ModelID, ProviderID } from "../../src/provider/schema"
@@ -82,7 +82,7 @@ function createTextMessage(directory: string, sessionID: SessionID, text: string
   )
 }
 
-const localAdaptor = (directory: string): WorkspaceAdaptor => ({
+const localAdapter = (directory: string): WorkspaceAdapter => ({
   name: "Local Test",
   description: "Create a local test workspace",
   configure: (info) => ({ ...info, name: "local-test", directory }),
@@ -95,7 +95,7 @@ const localAdaptor = (directory: string): WorkspaceAdaptor => ({
 
 const createLocalWorkspace = (input: { projectID: Project.Info["id"]; type: string; directory: string }) =>
   Effect.gen(function* () {
-    registerAdaptor(input.projectID, input.type, localAdaptor(input.directory))
+    registerAdapter(input.projectID, input.type, localAdapter(input.directory))
     return yield* Workspace.Service.use((svc) =>
       svc.create({
         type: input.type,

+ 10 - 10
packages/opencode/test/server/httpapi-workspace-routing.test.ts

@@ -15,9 +15,9 @@ import * as Socket from "effect/unstable/socket/Socket"
 import Http from "node:http"
 import { mkdir } from "node:fs/promises"
 import path from "node:path"
-import { registerAdaptor } from "../../src/control-plane/adaptors"
+import { registerAdapter } from "../../src/control-plane/adapters"
 import { WorkspaceID } from "../../src/control-plane/schema"
-import type { WorkspaceAdaptor } from "../../src/control-plane/types"
+import type { WorkspaceAdapter } from "../../src/control-plane/types"
 import { Workspace } from "../../src/control-plane/workspace"
 import { WorkspaceTable } from "../../src/control-plane/workspace.sql"
 import { Project } from "../../src/project/project"
@@ -82,7 +82,7 @@ const listenAdditionalServer = <E, R>(handler: TestHandler<E, R>) =>
     return HttpServer.formatAddress(server.address)
   })
 
-const localAdaptor = (directory: string): WorkspaceAdaptor => ({
+const localAdapter = (directory: string): WorkspaceAdapter => ({
   name: "Local Test",
   description: "Create a local test workspace",
   configure: (info) => ({ ...info, name: "local-test", directory }),
@@ -93,7 +93,7 @@ const localAdaptor = (directory: string): WorkspaceAdaptor => ({
   target: () => ({ type: "local" as const, directory }),
 })
 
-const remoteAdaptor = (directory: string, url: string, headers?: HeadersInit): WorkspaceAdaptor => ({
+const remoteAdapter = (directory: string, url: string, headers?: HeadersInit): WorkspaceAdapter => ({
   name: "Remote Test",
   description: "Create a remote test workspace",
   configure: (info) => ({ ...info, name: "remote-test", directory }),
@@ -116,10 +116,10 @@ const syncResponse = (request: HttpServerRequest.HttpServerRequest) => {
   return undefined
 }
 
-const createWorkspace = (input: { projectID: Project.Info["id"]; type: string; adaptor: WorkspaceAdaptor }) =>
+const createWorkspace = (input: { projectID: Project.Info["id"]; type: string; adapter: WorkspaceAdapter }) =>
   Effect.acquireRelease(
     Effect.gen(function* () {
-      registerAdaptor(input.projectID, input.type, input.adaptor)
+      registerAdapter(input.projectID, input.type, input.adapter)
       const workspace = yield* Workspace.Service
       return yield* workspace.create({
         type: input.type,
@@ -144,14 +144,14 @@ const createRemoteWorkspace = (input: {
   createWorkspace({
     projectID: input.projectID,
     type: input.type,
-    adaptor: remoteAdaptor(path.join(input.dir, `.${input.type}`), input.url, input.headers),
+    adapter: remoteAdapter(path.join(input.dir, `.${input.type}`), input.url, input.headers),
   })
 
 const createLocalWorkspace = (input: { projectID: Project.Info["id"]; type: string; directory: string }) =>
   createWorkspace({
     projectID: input.projectID,
     type: input.type,
-    adaptor: localAdaptor(input.directory),
+    adapter: localAdapter(input.directory),
   })
 
 const insertRemoteWorkspaceWithoutSync = (input: {
@@ -162,7 +162,7 @@ const insertRemoteWorkspaceWithoutSync = (input: {
 }) =>
   Effect.sync(() => {
     const id = WorkspaceID.ascending()
-    registerAdaptor(input.projectID, input.type, remoteAdaptor(path.join(input.dir, `.${input.type}`), input.url))
+    registerAdapter(input.projectID, input.type, remoteAdapter(path.join(input.dir, `.${input.type}`), input.url))
     Database.use((db) => db.insert(WorkspaceTable).values({ id, type: input.type, project_id: input.projectID }).run())
     return id
   })
@@ -237,7 +237,7 @@ describe("HttpApi workspace routing middleware", () => {
           { status: 201, headers: { "x-remote": "yes" } },
         )
       })
-      // The adaptor target tells the middleware where to proxy selected remote
+      // The adapter target tells the middleware where to proxy selected remote
       // workspace requests. Appending /probe to this base should produce
       // `${remoteUrl}/base/probe` on the fake remote server above.
       const workspace = yield* createRemoteWorkspace({

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

@@ -4,8 +4,8 @@ import { mkdir } from "node:fs/promises"
 import path from "node:path"
 import { Effect, Layer } from "effect"
 import { Flag } from "@opencode-ai/core/flag/flag"
-import { registerAdaptor } from "../../src/control-plane/adaptors"
-import type { WorkspaceAdaptor } from "../../src/control-plane/types"
+import { registerAdapter } from "../../src/control-plane/adapters"
+import type { WorkspaceAdapter } from "../../src/control-plane/types"
 import { Workspace } from "../../src/control-plane/workspace"
 import { WorkspacePaths } from "../../src/server/routes/instance/httpapi/groups/workspace"
 import { Session } from "@/session/session"
@@ -36,7 +36,7 @@ function request(path: string, directory: string, init: RequestInit = {}) {
   })
 }
 
-function localAdaptor(directory: string): WorkspaceAdaptor {
+function localAdapter(directory: string): WorkspaceAdapter {
   return {
     name: "Local Test",
     description: "Create a local test workspace",
@@ -60,7 +60,7 @@ function localAdaptor(directory: string): WorkspaceAdaptor {
   }
 }
 
-function remoteAdaptor(directory: string, url: string, headers?: HeadersInit): WorkspaceAdaptor {
+function remoteAdapter(directory: string, url: string, headers?: HeadersInit): WorkspaceAdapter {
   return {
     name: "Remote Test",
     description: "Create a remote test workspace",
@@ -137,14 +137,14 @@ describe("workspace HttpApi", () => {
     Effect.gen(function* () {
       const dir = yield* tmpdirScoped({ git: true })
 
-      const [adaptors, workspaces, status] = yield* Effect.all([
-        request(WorkspacePaths.adaptors, dir),
+      const [adapters, workspaces, status] = yield* Effect.all([
+        request(WorkspacePaths.adapters, dir),
         request(WorkspacePaths.list, dir),
         request(WorkspacePaths.status, dir),
       ])
 
-      expect(adaptors.status).toBe(200)
-      expect(yield* Effect.promise(() => adaptors.json())).toContainEqual({
+      expect(adapters.status).toBe(200)
+      expect(yield* Effect.promise(() => adapters.json())).toContainEqual({
         type: "worktree",
         name: "Worktree",
         description: "Create a git worktree",
@@ -163,7 +163,7 @@ describe("workspace HttpApi", () => {
       Flag.OPENCODE_EXPERIMENTAL_WORKSPACES = true
       const dir = yield* tmpdirScoped({ git: true })
       const project = yield* Project.use.fromDirectory(dir)
-      registerAdaptor(project.project.id, "local-test", localAdaptor(path.join(dir, ".workspace")))
+      registerAdapter(project.project.id, "local-test", localAdapter(path.join(dir, ".workspace")))
 
       const created = yield* request(WorkspacePaths.list, dir, {
         method: "POST",
@@ -201,7 +201,7 @@ describe("workspace HttpApi", () => {
       const dir = yield* tmpdirScoped({ git: true })
       const workspaceDir = path.join(dir, ".workspace-local")
       const project = yield* Project.use.fromDirectory(dir)
-      registerAdaptor(project.project.id, "local-target", localAdaptor(workspaceDir))
+      registerAdapter(project.project.id, "local-target", localAdapter(workspaceDir))
       const created = yield* request(WorkspacePaths.list, dir, {
         method: "POST",
         headers: { "content-type": "application/json" },
@@ -250,10 +250,10 @@ describe("workspace HttpApi", () => {
       })
 
       const project = yield* Project.use.fromDirectory(dir)
-      registerAdaptor(
+      registerAdapter(
         project.project.id,
         "remote-target",
-        remoteAdaptor(path.join(dir, ".remote"), `http://127.0.0.1:${remote.port}/base`, {
+        remoteAdapter(path.join(dir, ".remote"), `http://127.0.0.1:${remote.port}/base`, {
           "x-target-auth": "secret",
         }),
       )
@@ -319,10 +319,10 @@ describe("workspace HttpApi", () => {
       })
 
       const project = yield* Project.use.fromDirectory(dir)
-      registerAdaptor(
+      registerAdapter(
         project.project.id,
         "remote-session-target",
-        remoteAdaptor(path.join(dir, ".remote-session"), `http://127.0.0.1:${remote.port}/base`),
+        remoteAdapter(path.join(dir, ".remote-session"), `http://127.0.0.1:${remote.port}/base`),
       )
       const created = yield* request(WorkspacePaths.list, dir, {
         method: "POST",

+ 2 - 2
packages/plugin/src/index.ts

@@ -45,7 +45,7 @@ export type WorkspaceTarget =
       headers?: HeadersInit
     }
 
-export type WorkspaceAdaptor = {
+export type WorkspaceAdapter = {
   name: string
   description: string
   configure(config: WorkspaceInfo): WorkspaceInfo | Promise<WorkspaceInfo>
@@ -60,7 +60,7 @@ export type PluginInput = {
   directory: string
   worktree: string
   experimental_workspace: {
-    register(type: string, adaptor: WorkspaceAdaptor): void
+    register(type: string, adapter: WorkspaceAdapter): void
   }
   serverUrl: URL
   $: BunShell

+ 9 - 9
packages/sdk/js/src/v2/gen/sdk.gen.ts

@@ -29,7 +29,7 @@ import type {
   ExperimentalConsoleSwitchOrgResponses,
   ExperimentalResourceListResponses,
   ExperimentalSessionListResponses,
-  ExperimentalWorkspaceAdaptorListResponses,
+  ExperimentalWorkspaceAdapterListResponses,
   ExperimentalWorkspaceCreateErrors,
   ExperimentalWorkspaceCreateResponses,
   ExperimentalWorkspaceListResponses,
@@ -512,11 +512,11 @@ export class App extends HeyApiClient {
   }
 }
 
-export class Adaptor extends HeyApiClient {
+export class Adapter extends HeyApiClient {
   /**
-   * List workspace adaptors
+   * List workspace adapters
    *
-   * List all available workspace adaptors for the current project.
+   * List all available workspace adapters for the current project.
    */
   public list<ThrowOnError extends boolean = false>(
     parameters?: {
@@ -536,8 +536,8 @@ export class Adaptor extends HeyApiClient {
         },
       ],
     )
-    return (options?.client ?? this.client).get<ExperimentalWorkspaceAdaptorListResponses, unknown, ThrowOnError>({
-      url: "/experimental/workspace/adaptor",
+    return (options?.client ?? this.client).get<ExperimentalWorkspaceAdapterListResponses, unknown, ThrowOnError>({
+      url: "/experimental/workspace/adapter",
       ...options,
       ...params,
     })
@@ -731,9 +731,9 @@ export class Workspace extends HeyApiClient {
     })
   }
 
-  private _adaptor?: Adaptor
-  get adaptor(): Adaptor {
-    return (this._adaptor ??= new Adaptor({ client: this.client }))
+  private _adapter?: Adapter
+  get adapter(): Adapter {
+    return (this._adapter ??= new Adapter({ client: this.client }))
   }
 }
 

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

@@ -2430,19 +2430,19 @@ export type AppLogResponses = {
 
 export type AppLogResponse = AppLogResponses[keyof AppLogResponses]
 
-export type ExperimentalWorkspaceAdaptorListData = {
+export type ExperimentalWorkspaceAdapterListData = {
   body?: never
   path?: never
   query?: {
     directory?: string
     workspace?: string
   }
-  url: "/experimental/workspace/adaptor"
+  url: "/experimental/workspace/adapter"
 }
 
-export type ExperimentalWorkspaceAdaptorListResponses = {
+export type ExperimentalWorkspaceAdapterListResponses = {
   /**
-   * Workspace adaptors
+   * Workspace adapters
    */
   200: Array<{
     type: string
@@ -2451,8 +2451,8 @@ export type ExperimentalWorkspaceAdaptorListResponses = {
   }>
 }
 
-export type ExperimentalWorkspaceAdaptorListResponse =
-  ExperimentalWorkspaceAdaptorListResponses[keyof ExperimentalWorkspaceAdaptorListResponses]
+export type ExperimentalWorkspaceAdapterListResponse =
+  ExperimentalWorkspaceAdapterListResponses[keyof ExperimentalWorkspaceAdapterListResponses]
 
 export type ExperimentalWorkspaceListData = {
   body?: never

+ 6 - 6
packages/sdk/openapi.json

@@ -415,9 +415,9 @@
         ]
       }
     },
-    "/experimental/workspace/adaptor": {
+    "/experimental/workspace/adapter": {
       "get": {
-        "operationId": "experimental.workspace.adaptor.list",
+        "operationId": "experimental.workspace.adapter.list",
         "parameters": [
           {
             "in": "query",
@@ -434,11 +434,11 @@
             }
           }
         ],
-        "summary": "List workspace adaptors",
-        "description": "List all available workspace adaptors for the current project.",
+        "summary": "List workspace adapters",
+        "description": "List all available workspace adapters for the current project.",
         "responses": {
           "200": {
-            "description": "Workspace adaptors",
+            "description": "Workspace adapters",
             "content": {
               "application/json": {
                 "schema": {
@@ -466,7 +466,7 @@
         "x-codeSamples": [
           {
             "lang": "js",
-            "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.experimental.workspace.adaptor.list({\n  ...\n})"
+            "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.experimental.workspace.adapter.list({\n  ...\n})"
           }
         ]
       }