From 83e8c3d39ba6576e3c902f8777ec3d95b05a74bd Mon Sep 17 00:00:00 2001 From: Cristina Poncela Cubeiro <140309543+cristinaponcela@users.noreply.github.com> Date: Thu, 18 Jun 2026 13:14:01 +0200 Subject: [PATCH] feat: handler --- packages/orchestrator/src/handler.ts | 96 +++++++++++++++++++++++++ packages/orchestrator/src/index.ts | 1 + packages/orchestrator/src/ipc/server.ts | 18 ++++- 3 files changed, 113 insertions(+), 2 deletions(-) create mode 100644 packages/orchestrator/src/handler.ts diff --git a/packages/orchestrator/src/handler.ts b/packages/orchestrator/src/handler.ts new file mode 100644 index 00000000..894308bb --- /dev/null +++ b/packages/orchestrator/src/handler.ts @@ -0,0 +1,96 @@ +import { randomUUID } from "node:crypto"; +import type { + ErrorResponse, + InstanceSummary, + ListRequest, + ListResponse, + OrchestratorRequest, + OrchestratorResponse, + SpawnRequest, + SpawnResponse, + StatusRequest, + StatusResponse, + StopRequest, + StopResponse, +} from "./ipc/protocol.ts"; +import { getInstance, loadInstances, removeInstance, upsertInstance } from "./storage.ts"; +import type { InstanceRecord } from "./types.ts"; + +function toInstanceSummary(instance: InstanceRecord): InstanceSummary { + return { + id: instance.id, + status: instance.status, + cwd: instance.cwd, + label: instance.label, + sessionId: instance.sessionId, + }; +} + +function unknownInstanceError(instanceId: string): ErrorResponse { + return { + type: "error", + ok: false, + error: `Unknown instance: ${instanceId}`, + }; +} + +// Overhead types +export async function handleIpcRequest(request: SpawnRequest): Promise; +export async function handleIpcRequest(request: ListRequest): Promise; +export async function handleIpcRequest(request: StopRequest): Promise; +export async function handleIpcRequest(request: StatusRequest): Promise; +export async function handleIpcRequest(request: OrchestratorRequest): Promise { + switch (request.type) { + case "spawn": { + const instance: InstanceRecord = { + id: randomUUID(), + status: "starting", + cwd: request.cwd, + createdAt: new Date().toISOString(), + lastSeenAt: new Date().toISOString(), + label: request.label, + }; + upsertInstance(instance); + return { + type: "spawn_result", + ok: true, + instance: toInstanceSummary(instance), + }; + } + + case "list": { + return { + type: "list_result", + ok: true, + instances: loadInstances().map(toInstanceSummary), + }; + } + + case "status": { + const instance = getInstance(request.instanceId); + if (!instance) { + return unknownInstanceError(request.instanceId); + } + + return { + type: "status_result", + ok: true, + instance: toInstanceSummary(instance), + }; + } + + case "stop": { + const instance = getInstance(request.instanceId); + if (!instance) { + return unknownInstanceError(request.instanceId); + } + + removeInstance(request.instanceId); + return { + type: "stop_result", + ok: true, + instanceId: request.instanceId, + }; + } + } +} diff --git a/packages/orchestrator/src/index.ts b/packages/orchestrator/src/index.ts index 4f017322..e16fbc5f 100644 --- a/packages/orchestrator/src/index.ts +++ b/packages/orchestrator/src/index.ts @@ -1,4 +1,5 @@ export * from "./config.ts"; +export * from "./handler.ts"; export * from "./ipc/client.ts"; export * from "./ipc/protocol.ts"; export * from "./ipc/server.ts"; diff --git a/packages/orchestrator/src/ipc/server.ts b/packages/orchestrator/src/ipc/server.ts index 59d91b57..860181b9 100644 --- a/packages/orchestrator/src/ipc/server.ts +++ b/packages/orchestrator/src/ipc/server.ts @@ -4,12 +4,26 @@ import { getSocketPath } from "../config.ts"; import { type ErrorResponse, encodeMessage, + type ListRequest, + type ListResponse, type OrchestratorRequest, + type OrchestratorResponse, parseRequestLine, - type ResponseFor, + type SpawnRequest, + type SpawnResponse, + type StatusRequest, + type StatusResponse, + type StopRequest, + type StopResponse, } from "./protocol.ts"; -export type IpcRequestHandler = (request: T) => Promise> | ResponseFor; +export interface IpcRequestHandler { + (request: SpawnRequest): Promise | SpawnResponse | ErrorResponse; + (request: ListRequest): Promise | ListResponse | ErrorResponse; + (request: StopRequest): Promise | StopResponse | ErrorResponse; + (request: StatusRequest): Promise | StatusResponse | ErrorResponse; + (request: OrchestratorRequest): Promise | OrchestratorResponse; +} export async function startIpcServer(handler: IpcRequestHandler): Promise { const socketPath = getSocketPath();