import { TuiEvent } from "@/server/tui-event" import { TuiRequest as TuiRequestPayload } from "@/server/shared/tui-control" import { Schema } from "effect" import { HttpApi, HttpApiEndpoint, HttpApiError, HttpApiGroup, OpenApi } from "effect/unstable/httpapi" import { Authorization } from "../middleware/authorization" import { InstanceContextMiddleware } from "../middleware/instance-context" import { WorkspaceRoutingMiddleware, WorkspaceRoutingQuery } from "../middleware/workspace-routing" import { ApiNotFoundError } from "../errors" import { described } from "./metadata" const root = "/tui" export const CommandPayload = Schema.Struct({ command: Schema.String }) const EventTuiPromptAppend = Schema.Struct({ type: Schema.Literal(TuiEvent.PromptAppend.type), properties: TuiEvent.PromptAppend.data, }).annotate({ identifier: "EventTuiPromptAppend" }) const EventTuiCommandExecute = Schema.Struct({ type: Schema.Literal(TuiEvent.CommandExecute.type), properties: TuiEvent.CommandExecute.data, }).annotate({ identifier: "EventTuiCommandExecute" }) const EventTuiToastShow = Schema.Struct({ type: Schema.Literal(TuiEvent.ToastShow.type), properties: TuiEvent.ToastShow.data, }).annotate({ identifier: "EventTuiToastShow" }) const EventTuiSessionSelect = Schema.Struct({ type: Schema.Literal(TuiEvent.SessionSelect.type), properties: TuiEvent.SessionSelect.data, }).annotate({ identifier: "EventTuiSessionSelect" }) export const TuiPublishPayload = Schema.Union([ EventTuiPromptAppend, EventTuiCommandExecute, EventTuiToastShow, EventTuiSessionSelect, ]) export const TuiPaths = { appendPrompt: `${root}/append-prompt`, openHelp: `${root}/open-help`, openSessions: `${root}/open-sessions`, openThemes: `${root}/open-themes`, openModels: `${root}/open-models`, submitPrompt: `${root}/submit-prompt`, clearPrompt: `${root}/clear-prompt`, executeCommand: `${root}/execute-command`, showToast: `${root}/show-toast`, publish: `${root}/publish`, selectSession: `${root}/select-session`, controlNext: `${root}/control/next`, controlResponse: `${root}/control/response`, } as const export const TuiApi = HttpApi.make("tui") .add( HttpApiGroup.make("tui") .add( HttpApiEndpoint.post("appendPrompt", TuiPaths.appendPrompt, { query: WorkspaceRoutingQuery, payload: TuiEvent.PromptAppend.data, success: described(Schema.Boolean, "Prompt processed successfully"), error: HttpApiError.BadRequest, }).annotateMerge( OpenApi.annotations({ identifier: "tui.appendPrompt", summary: "Append TUI prompt", description: "Append prompt to the TUI.", }), ), HttpApiEndpoint.post("openHelp", TuiPaths.openHelp, { query: WorkspaceRoutingQuery, success: described(Schema.Boolean, "Help dialog opened successfully"), }).annotateMerge( OpenApi.annotations({ identifier: "tui.openHelp", summary: "Open help dialog", description: "Open the help dialog in the TUI to display user assistance information.", }), ), HttpApiEndpoint.post("openSessions", TuiPaths.openSessions, { query: WorkspaceRoutingQuery, success: described(Schema.Boolean, "Session dialog opened successfully"), }).annotateMerge( OpenApi.annotations({ identifier: "tui.openSessions", summary: "Open sessions dialog", description: "Open the session dialog.", }), ), HttpApiEndpoint.post("openThemes", TuiPaths.openThemes, { query: WorkspaceRoutingQuery, success: described(Schema.Boolean, "Theme dialog opened successfully"), }).annotateMerge( OpenApi.annotations({ identifier: "tui.openThemes", summary: "Open themes dialog", description: "Open the theme dialog.", }), ), HttpApiEndpoint.post("openModels", TuiPaths.openModels, { query: WorkspaceRoutingQuery, success: described(Schema.Boolean, "Model dialog opened successfully"), }).annotateMerge( OpenApi.annotations({ identifier: "tui.openModels", summary: "Open models dialog", description: "Open the model dialog.", }), ), HttpApiEndpoint.post("submitPrompt", TuiPaths.submitPrompt, { query: WorkspaceRoutingQuery, success: described(Schema.Boolean, "Prompt submitted successfully"), }).annotateMerge( OpenApi.annotations({ identifier: "tui.submitPrompt", summary: "Submit TUI prompt", description: "Submit the prompt.", }), ), HttpApiEndpoint.post("clearPrompt", TuiPaths.clearPrompt, { query: WorkspaceRoutingQuery, success: described(Schema.Boolean, "Prompt cleared successfully"), }).annotateMerge( OpenApi.annotations({ identifier: "tui.clearPrompt", summary: "Clear TUI prompt", description: "Clear the prompt.", }), ), HttpApiEndpoint.post("executeCommand", TuiPaths.executeCommand, { query: WorkspaceRoutingQuery, payload: CommandPayload, success: described(Schema.Boolean, "Command executed successfully"), error: HttpApiError.BadRequest, }).annotateMerge( OpenApi.annotations({ identifier: "tui.executeCommand", summary: "Execute TUI command", description: "Execute a TUI command.", }), ), HttpApiEndpoint.post("showToast", TuiPaths.showToast, { query: WorkspaceRoutingQuery, payload: TuiEvent.ToastShow.data, success: described(Schema.Boolean, "Toast notification shown successfully"), }).annotateMerge( OpenApi.annotations({ identifier: "tui.showToast", summary: "Show TUI toast", description: "Show a toast notification in the TUI.", }), ), HttpApiEndpoint.post("publish", TuiPaths.publish, { query: WorkspaceRoutingQuery, payload: TuiPublishPayload, success: described(Schema.Boolean, "Event published successfully"), error: HttpApiError.BadRequest, }).annotateMerge( OpenApi.annotations({ identifier: "tui.publish", summary: "Publish TUI event", description: "Publish a TUI event.", }), ), HttpApiEndpoint.post("selectSession", TuiPaths.selectSession, { query: WorkspaceRoutingQuery, payload: TuiEvent.SessionSelect.data, success: described(Schema.Boolean, "Session selected successfully"), error: [HttpApiError.BadRequest, ApiNotFoundError], }).annotateMerge( OpenApi.annotations({ identifier: "tui.selectSession", summary: "Select session", description: "Navigate the TUI to display the specified session.", }), ), HttpApiEndpoint.get("controlNext", TuiPaths.controlNext, { query: WorkspaceRoutingQuery, success: described(TuiRequestPayload, "Next TUI request"), }).annotateMerge( OpenApi.annotations({ identifier: "tui.control.next", summary: "Get next TUI request", description: "Retrieve the next TUI request from the queue for processing.", }), ), HttpApiEndpoint.post("controlResponse", TuiPaths.controlResponse, { query: WorkspaceRoutingQuery, payload: Schema.Unknown, success: described(Schema.Boolean, "Response submitted successfully"), }).annotateMerge( OpenApi.annotations({ identifier: "tui.control.response", summary: "Submit TUI response", description: "Submit a response to the TUI request queue to complete a pending request.", }), ), ) .annotateMerge(OpenApi.annotations({ title: "tui", description: "Experimental HttpApi TUI routes." })) .middleware(InstanceContextMiddleware) .middleware(WorkspaceRoutingMiddleware) .middleware(Authorization), ) .annotateMerge( OpenApi.annotations({ title: "opencode experimental HttpApi", version: "0.0.1", description: "Experimental HttpApi surface for selected instance routes.", }), )