refactor: clarify internal workspace adapter type

This commit is contained in:
Kit Langton 2026-05-01 18:13:31 -04:00
parent aaeff9b3ef
commit 38a44903c5
3 changed files with 14 additions and 19 deletions

View file

@ -1,25 +1,25 @@
import type { ProjectID } from "@/project/schema"
import { Effect, Schema } from "effect"
import type { WorkspaceAdapter as PluginWorkspaceAdapter } from "@opencode-ai/plugin"
import type { WorkspaceAdapter as PluginWorkspaceAdapter, WorkspaceInfo as PluginWorkspaceInfo } from "@opencode-ai/plugin"
import { EffectBridge } from "@/effect/bridge"
import { errorMessage } from "@/util/error"
import { type WorkspaceAdapter, WorkspaceAdapterError, type WorkspaceAdapterEntry, WorkspaceInfo } from "../types"
import { type InternalWorkspaceAdapter, WorkspaceAdapterError, type WorkspaceAdapterEntry, WorkspaceInfo } from "../types"
import type { Interface as WorktreeService } from "@/worktree"
import { WorktreeAdapterEntry, worktreeAdapter } from "./worktree"
const BUILTIN: WorkspaceAdapterEntry[] = [{ type: "worktree", ...WorktreeAdapterEntry }]
export const makeBuiltinAdapters = (worktree: WorktreeService) =>
new Map<string, WorkspaceAdapter>([["worktree", worktreeAdapter(worktree)]])
new Map<string, InternalWorkspaceAdapter>([["worktree", worktreeAdapter(worktree)]])
const plugins = new Map<ProjectID, Map<string, WorkspaceAdapter>>()
const emptyBuiltinAdapters = new Map<string, WorkspaceAdapter>()
const plugins = new Map<ProjectID, Map<string, InternalWorkspaceAdapter>>()
const emptyBuiltinAdapters = new Map<string, InternalWorkspaceAdapter>()
export function getAdapter(
projectID: ProjectID,
type: string,
builtin: ReadonlyMap<string, WorkspaceAdapter> = emptyBuiltinAdapters,
): WorkspaceAdapter {
builtin: ReadonlyMap<string, InternalWorkspaceAdapter> = emptyBuiltinAdapters,
): InternalWorkspaceAdapter {
const custom = plugins.get(projectID)?.get(type)
if (custom) return custom
@ -39,13 +39,8 @@ export async function listAdapters(projectID: ProjectID): Promise<WorkspaceAdapt
}
const adapterError = (cause: unknown) => new WorkspaceAdapterError({ message: errorMessage(cause), cause })
const decodeWorkspaceInfo = Schema.decodeUnknownSync(WorkspaceInfo)
const decodeInfo = (value: unknown) =>
Effect.try({
try: () => decodeWorkspaceInfo(value),
catch: adapterError,
})
const decodeInfo = (value: PluginWorkspaceInfo) =>
Schema.decodeEffect(WorkspaceInfo)(value).pipe(Effect.mapError(adapterError))
function runPromiseAdapter<A>(fn: () => A | Promise<A>) {
return Effect.gen(function* () {
@ -57,7 +52,7 @@ function runPromiseAdapter<A>(fn: () => A | Promise<A>) {
})
}
function fromPromiseAdapter(adapter: PluginWorkspaceAdapter): WorkspaceAdapter {
function fromPromiseAdapter(adapter: PluginWorkspaceAdapter): InternalWorkspaceAdapter {
return {
name: adapter.name,
description: adapter.description,
@ -71,7 +66,7 @@ function fromPromiseAdapter(adapter: PluginWorkspaceAdapter): WorkspaceAdapter {
export function registerAdapter(projectID: ProjectID, type: string, adapter: PluginWorkspaceAdapter) {
// Plugins can be loaded per-project so we need to scope them. If you
// want to install a global one pass `ProjectID.global`.
const adapters = plugins.get(projectID) ?? new Map<string, WorkspaceAdapter>()
const adapters = plugins.get(projectID) ?? new Map<string, InternalWorkspaceAdapter>()
adapters.set(type, fromPromiseAdapter(adapter))
plugins.set(projectID, adapters)
}

View file

@ -1,6 +1,6 @@
import { Cause, Effect, Schema } from "effect"
import type { Interface as WorktreeService } from "@/worktree"
import { type WorkspaceAdapter, WorkspaceAdapterError, WorkspaceInfo } from "../types"
import { type InternalWorkspaceAdapter, WorkspaceAdapterError, WorkspaceInfo } from "../types"
const WorktreeConfig = Schema.Struct({
name: WorkspaceInfo.fields.name,
@ -29,7 +29,7 @@ const decodeConfig = (info: WorkspaceInfo) =>
catch: (cause) => adapterError(cause instanceof Error ? cause.message : String(cause), cause),
})
export function worktreeAdapter(worktree: WorktreeService): WorkspaceAdapter {
export function worktreeAdapter(worktree: WorktreeService): InternalWorkspaceAdapter {
return {
...WorktreeAdapterEntry,
configure(info) {

View file

@ -40,7 +40,7 @@ export class WorkspaceAdapterError extends Schema.TaggedErrorClass<WorkspaceAdap
cause: Schema.optional(Schema.Defect),
}) {}
export type WorkspaceAdapter = {
export type InternalWorkspaceAdapter = {
name: string
description: string
configure(info: WorkspaceInfo): Effect.Effect<WorkspaceInfo, WorkspaceAdapterError>