122 lines
4.0 KiB
TypeScript
122 lines
4.0 KiB
TypeScript
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." })),
|
|
)
|