Use workspace service in HTTP routes (#25139)

This commit is contained in:
Kit Langton
2026-04-30 13:57:25 -04:00
committed by GitHub
parent feeebbe7d4
commit 19271fca2d
2 changed files with 21 additions and 24 deletions

View File

@@ -1,58 +1,53 @@
import { listAdaptors } from "@/control-plane/adaptors" import { listAdaptors } from "@/control-plane/adaptors"
import { Workspace } from "@/control-plane/workspace" import { Workspace } from "@/control-plane/workspace"
import * as InstanceState from "@/effect/instance-state" import * as InstanceState from "@/effect/instance-state"
import { Instance } from "@/project/instance"
import { Effect } from "effect" import { Effect } from "effect"
import { HttpApiBuilder } from "effect/unstable/httpapi" import { HttpApiBuilder, HttpApiError } from "effect/unstable/httpapi"
import { InstanceHttpApi } from "../api" import { InstanceHttpApi } from "../api"
import { CreatePayload, SessionRestorePayload } from "../groups/workspace" import { CreatePayload, SessionRestorePayload } from "../groups/workspace"
export const workspaceHandlers = HttpApiBuilder.group(InstanceHttpApi, "workspace", (handlers) => export const workspaceHandlers = HttpApiBuilder.group(InstanceHttpApi, "workspace", (handlers) =>
Effect.gen(function* () { Effect.gen(function* () {
const workspace = yield* Workspace.Service
const adaptors = Effect.fn("WorkspaceHttpApi.adaptors")(function* () { const adaptors = Effect.fn("WorkspaceHttpApi.adaptors")(function* () {
const instance = yield* InstanceState.context const instance = yield* InstanceState.context
return yield* Effect.promise(() => listAdaptors(instance.project.id)) return yield* Effect.promise(() => listAdaptors(instance.project.id))
}) })
const list = Effect.fn("WorkspaceHttpApi.list")(function* () { const list = Effect.fn("WorkspaceHttpApi.list")(function* () {
return Workspace.list((yield* InstanceState.context).project) return yield* workspace.list((yield* InstanceState.context).project)
}) })
const create = Effect.fn("WorkspaceHttpApi.create")(function* (ctx: { payload: typeof CreatePayload.Type }) { const create = Effect.fn("WorkspaceHttpApi.create")(function* (ctx: { payload: typeof CreatePayload.Type }) {
const instance = yield* InstanceState.context const instance = yield* InstanceState.context
return yield* Effect.promise(() => return yield* workspace
Instance.restore(instance, () => .create({
Workspace.create({ ...ctx.payload,
...ctx.payload, projectID: instance.project.id,
projectID: instance.project.id, })
}), .pipe(Effect.mapError(() => new HttpApiError.BadRequest({})))
),
)
}) })
const status = Effect.fn("WorkspaceHttpApi.status")(function* () { const status = Effect.fn("WorkspaceHttpApi.status")(function* () {
const ids = new Set(Workspace.list((yield* InstanceState.context).project).map((item) => item.id)) const ids = new Set((yield* workspace.list((yield* InstanceState.context).project)).map((item) => item.id))
return Workspace.status().filter((item) => ids.has(item.workspaceID)) return (yield* workspace.status()).filter((item) => ids.has(item.workspaceID))
}) })
const remove = Effect.fn("WorkspaceHttpApi.remove")(function* (ctx: { params: { id: Workspace.Info["id"] } }) { const remove = Effect.fn("WorkspaceHttpApi.remove")(function* (ctx: { params: { id: Workspace.Info["id"] } }) {
const instance = yield* InstanceState.context return yield* workspace.remove(ctx.params.id)
return yield* Effect.promise(() => Instance.restore(instance, () => Workspace.remove(ctx.params.id)))
}) })
const sessionRestore = Effect.fn("WorkspaceHttpApi.sessionRestore")(function* (ctx: { const sessionRestore = Effect.fn("WorkspaceHttpApi.sessionRestore")(function* (ctx: {
params: { id: Workspace.Info["id"] } params: { id: Workspace.Info["id"] }
payload: typeof SessionRestorePayload.Type payload: typeof SessionRestorePayload.Type
}) { }) {
const instance = yield* InstanceState.context return yield* workspace
return yield* Effect.promise(() => .sessionRestore({
Instance.restore(instance, () => workspaceID: ctx.params.id,
Workspace.sessionRestore({ sessionID: ctx.payload.sessionID,
workspaceID: ctx.params.id, })
sessionID: ctx.payload.sessionID, .pipe(Effect.mapError(() => new HttpApiError.BadRequest({})))
}),
),
)
}) })
return handlers return handlers

View File

@@ -35,6 +35,7 @@ import { ToolRegistry } from "@/tool/registry"
import { lazy } from "@/util/lazy" import { lazy } from "@/util/lazy"
import { Vcs } from "@/project/vcs" import { Vcs } from "@/project/vcs"
import { Worktree } from "@/worktree" import { Worktree } from "@/worktree"
import { Workspace } from "@/control-plane/workspace"
import { isAllowedCorsOrigin } from "@/server/cors" import { isAllowedCorsOrigin } from "@/server/cors"
import { InstanceHttpApi, RootHttpApi } from "./api" import { InstanceHttpApi, RootHttpApi } from "./api"
import { ServerAuthConfig, authorizationLayer } from "./middleware/authorization" import { ServerAuthConfig, authorizationLayer } from "./middleware/authorization"
@@ -149,6 +150,7 @@ export const routes = Layer.mergeAll(rootApiRoutes, instanceRoutes).pipe(
Todo.defaultLayer, Todo.defaultLayer,
ToolRegistry.defaultLayer, ToolRegistry.defaultLayer,
Vcs.defaultLayer, Vcs.defaultLayer,
Workspace.defaultLayer,
Worktree.defaultLayer, Worktree.defaultLayer,
Bus.layer, Bus.layer,
HttpServer.layerServices, HttpServer.layerServices,