import { Context } from "effect" import { HttpApi, HttpApiGroup, HttpApiMiddleware, OpenApi } from "effect/unstable/httpapi" import { SchemaErrorMiddleware } from "./middleware/schema-error.js" import { GenerateGroup } from "./groups/generate.js" import { MessageGroup } from "./groups/message.js" import { ModelGroup } from "./groups/model.js" import { ProviderGroup } from "./groups/provider.js" import { makeSessionGroup } from "./groups/session.js" import { makePermissionGroup } from "./groups/permission.js" import { FileSystemGroup } from "./groups/fs.js" import { makeFormGroup } from "./groups/form.js" import { CommandGroup } from "./groups/command.js" import { SkillGroup } from "./groups/skill.js" import { EventGroup, makeEventGroup } from "./groups/event.js" import type { Definition } from "@opencode-ai/schema/event" import { AgentGroup } from "./groups/agent.js" import { PluginGroup } from "./groups/plugin.js" import { HealthGroup } from "./groups/health.js" import { ServerGroup } from "./groups/server.js" import { DebugGroup } from "./groups/debug.js" import { PtyGroup } from "./groups/pty.js" import { ShellGroup } from "./groups/shell.js" import { makeQuestionGroup } from "./groups/question.js" import { ReferenceGroup } from "./groups/reference.js" import { Authorization } from "./middleware/authorization.js" import { LocationGroup } from "./groups/location.js" import { IntegrationGroup } from "./groups/integration.js" import { McpGroup } from "./groups/mcp.js" import { CredentialGroup } from "./groups/credential.js" import { ProjectGroup } from "./groups/project.js" import { ProjectCopyGroup } from "./groups/project-copy.js" import { VcsGroup } from "./groups/vcs.js" type LocationGroups = | HttpApiGroup.AddMiddleware | HttpApiGroup.AddMiddleware | HttpApiGroup.AddMiddleware | HttpApiGroup.AddMiddleware | HttpApiGroup.AddMiddleware | HttpApiGroup.AddMiddleware | HttpApiGroup.AddMiddleware | HttpApiGroup.AddMiddleware | HttpApiGroup.AddMiddleware | HttpApiGroup.AddMiddleware | HttpApiGroup.AddMiddleware | HttpApiGroup.AddMiddleware | HttpApiGroup.AddMiddleware | HttpApiGroup.AddMiddleware | HttpApiGroup.AddMiddleware | HttpApiGroup.AddMiddleware | HttpApiGroup.AddMiddleware | HttpApiGroup.AddMiddleware type SessionGroups = | ReturnType> | HttpApiGroup.AddMiddleware type FormGroups< LocationId extends HttpApiMiddleware.AnyId, LocationService, FormLocationId extends HttpApiMiddleware.AnyId, FormLocationService, > = ReturnType> type MixedMiddlewareGroups< LocationId extends HttpApiMiddleware.AnyId, LocationService, SessionLocationId extends HttpApiMiddleware.AnyId, SessionLocationService, > = | ReturnType> | ReturnType> type ApiGroups< LocationId extends HttpApiMiddleware.AnyId, LocationService, FormLocationId extends HttpApiMiddleware.AnyId, FormLocationService, SessionLocationId extends HttpApiMiddleware.AnyId, SessionLocationService, Event extends HttpApiGroup.Constraint, > = | typeof HealthGroup | typeof ServerGroup | typeof DebugGroup | LocationGroups | FormGroups | SessionGroups | MixedMiddlewareGroups | Event type EventGroupFor> = ReturnType> export type Api< LocationId extends HttpApiMiddleware.AnyId, LocationService, FormLocationId extends HttpApiMiddleware.AnyId, FormLocationService, SessionLocationId extends HttpApiMiddleware.AnyId, SessionLocationService, Event extends HttpApiGroup.Constraint, > = HttpApi.HttpApi< "server", HttpApiGroup.AddMiddleware< HttpApiGroup.AddMiddleware< ApiGroups< LocationId, LocationService, FormLocationId, FormLocationService, SessionLocationId, SessionLocationService, Event >, Authorization >, SchemaErrorMiddleware > > // Protocol owns middleware placement, while Server injects concrete keys so Core service identities stay downstream. const makeApiFromGroup = < const Group extends HttpApiGroup.Constraint, LocationId extends HttpApiMiddleware.AnyId, LocationService, FormLocationId extends HttpApiMiddleware.AnyId, FormLocationService, SessionLocationId extends HttpApiMiddleware.AnyId, SessionLocationService, >( eventGroup: Group, locationMiddleware: Context.Key, formLocationMiddleware: Context.Key, sessionLocationMiddleware: Context.Key, ): Api< LocationId, LocationService, FormLocationId, FormLocationService, SessionLocationId, SessionLocationService, Group > => HttpApi.make("server") .add(HealthGroup) .add(ServerGroup) .add(LocationGroup.middleware(locationMiddleware)) .add(AgentGroup.middleware(locationMiddleware)) .add(PluginGroup.middleware(locationMiddleware)) .add(makeSessionGroup(sessionLocationMiddleware)) .add(MessageGroup.middleware(sessionLocationMiddleware)) .add(ModelGroup.middleware(locationMiddleware)) .add(GenerateGroup.middleware(locationMiddleware)) .add(ProviderGroup.middleware(locationMiddleware)) .add(IntegrationGroup.middleware(locationMiddleware)) .add(McpGroup.middleware(locationMiddleware)) .add(CredentialGroup.middleware(locationMiddleware)) .add(ProjectGroup.middleware(locationMiddleware)) .add(makeFormGroup(locationMiddleware, formLocationMiddleware)) .add(makePermissionGroup(locationMiddleware, sessionLocationMiddleware)) .add(FileSystemGroup.middleware(locationMiddleware)) .add(CommandGroup.middleware(locationMiddleware)) .add(SkillGroup.middleware(locationMiddleware)) .add(eventGroup) .add(PtyGroup.middleware(locationMiddleware)) .add(ShellGroup.middleware(locationMiddleware)) .add(makeQuestionGroup(locationMiddleware, sessionLocationMiddleware)) .add(ReferenceGroup.middleware(locationMiddleware)) .add(ProjectCopyGroup.middleware(locationMiddleware)) .add(VcsGroup.middleware(locationMiddleware)) .add(DebugGroup) .annotateMerge( OpenApi.annotations({ title: "opencode HttpApi", version: "0.0.1", description: "Experimental HttpApi surface for selected instance routes.", }), ) .middleware(Authorization) .middleware(SchemaErrorMiddleware) export const makeApi = < const Definitions extends ReadonlyArray, LocationId extends HttpApiMiddleware.AnyId, LocationService, FormLocationId extends HttpApiMiddleware.AnyId, FormLocationService, SessionLocationId extends HttpApiMiddleware.AnyId, SessionLocationService, >(options: { readonly definitions: Definitions readonly locationMiddleware: Context.Key readonly formLocationMiddleware: Context.Key readonly sessionLocationMiddleware: Context.Key }): Api< LocationId, LocationService, FormLocationId, FormLocationService, SessionLocationId, SessionLocationService, EventGroupFor > => makeApiFromGroup( makeEventGroup(options.definitions), options.locationMiddleware, options.formLocationMiddleware, options.sessionLocationMiddleware, ) export const makeDefaultApi = < LocationId extends HttpApiMiddleware.AnyId, LocationService, FormLocationId extends HttpApiMiddleware.AnyId, FormLocationService, SessionLocationId extends HttpApiMiddleware.AnyId, SessionLocationService, >(options: { readonly locationMiddleware: Context.Key readonly formLocationMiddleware: Context.Key readonly sessionLocationMiddleware: Context.Key }): Api< LocationId, LocationService, FormLocationId, FormLocationService, SessionLocationId, SessionLocationService, typeof EventGroup > => makeApiFromGroup( EventGroup, options.locationMiddleware, options.formLocationMiddleware, options.sessionLocationMiddleware, )