import { ConfigV1 } from "@opencode-ai/core/v1/config/config" import { EventV2 } from "@opencode-ai/core/event" import { EventManifest } from "@/event-manifest" import { InstanceDisposed } from "@/server/event" import "@opencode-ai/core/account" import "@/server/event" import { Schema } from "effect" import { HttpApi, HttpApiEndpoint, HttpApiError, HttpApiGroup, HttpApiSchema, OpenApi } from "effect/unstable/httpapi" import { described } from "./metadata" const GlobalHealth = Schema.Struct({ healthy: Schema.Literal(true), version: Schema.String, }) const SyncEventSchemas = EventManifest.Latest.values() .flatMap((definition) => { if (!definition.durable) return [] return [ Schema.Struct({ type: Schema.Literal("sync"), id: EventV2.ID, syncEvent: Schema.Struct({ type: Schema.Literal(EventV2.versionedType(definition.type, definition.durable.version)), id: EventV2.ID, seq: Schema.Finite, aggregateID: Schema.String, data: definition.data, }), }).annotate({ identifier: `SyncEvent.${definition.type}` }), ] }) .toArray() const GlobalEventSchema = Schema.Struct({ directory: Schema.String, project: Schema.optional(Schema.String), workspace: Schema.optional(Schema.String), payload: Schema.Union([ ...EventManifest.Latest.values() .map((definition) => Schema.Struct({ id: EventV2.ID, type: Schema.Literal(definition.type), properties: definition.data }), ) .toArray(), InstanceDisposed, ...SyncEventSchemas, ]), }).annotate({ identifier: "GlobalEvent" }) const GlobalUpgradeResult = Schema.Union([ Schema.Struct({ success: Schema.Literal(true), version: Schema.String, }), Schema.Struct({ success: Schema.Literal(false), error: Schema.String, }), ]) export const GlobalPaths = { health: "/global/health", event: "/global/event", config: "/global/config", dispose: "/global/dispose", } as const export const GlobalApi = HttpApi.make("global").add( HttpApiGroup.make("global") .add( HttpApiEndpoint.get("health", GlobalPaths.health, { success: described(GlobalHealth, "Health information"), }).annotateMerge( OpenApi.annotations({ identifier: "global.health", summary: "Get health", description: "Get health information about the Neuron server.", }), ), HttpApiEndpoint.get("event", GlobalPaths.event, { success: GlobalEventSchema, }).annotateMerge( OpenApi.annotations({ identifier: "global.event", summary: "Get global events", description: "Subscribe to global events from the Neuron system using server-sent events.", }), ), HttpApiEndpoint.get("configGet", GlobalPaths.config, { success: described(ConfigV1.Info, "Get global config info"), }).annotateMerge( OpenApi.annotations({ identifier: "global.config.get", summary: "Get global configuration", description: "Retrieve the current global Neuron configuration settings and preferences.", }), ), HttpApiEndpoint.patch("configUpdate", GlobalPaths.config, { payload: ConfigV1.Info, success: described(ConfigV1.Info, "Successfully updated global config"), error: HttpApiError.BadRequest, }).annotateMerge( OpenApi.annotations({ identifier: "global.config.update", summary: "Update global configuration", description: "Update global Neuron configuration settings and preferences.", }), ), HttpApiEndpoint.post("dispose", GlobalPaths.dispose, { success: described(Schema.Boolean, "Global disposed"), }).annotateMerge( OpenApi.annotations({ identifier: "global.dispose", summary: "Dispose instance", description: "Clean up and dispose all Neuron instances, releasing all resources.", }), ), ) .annotateMerge(OpenApi.annotations({ title: "global", description: "Global server routes." })), )