import type { AgentSessionEvent, RpcCommand, RpcExtensionUIRequest, RpcExtensionUIResponse, } from "@earendil-works/pi-coding-agent"; import type { AttachHostContextRequest, AttachReadyResponse, AttachRequest, AttachRpcResponse, ErrorResponse, InstanceSummary, ListRequest, ListResponse, OrchestratorRequest, OrchestratorResponse, RpcBridgeResponse, RpcRequest, SpawnRequest, SpawnResponse, StatusRequest, StatusResponse, StopRequest, StopResponse, } from "./ipc/protocol.ts"; import { supervisor } from "./supervisor.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, sessionFile: instance.sessionFile, radiusPiId: instance.radiusPiId, }; } 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: RpcRequest): Promise; export async function handleIpcRequest(request: AttachRequest): Promise; export async function handleIpcRequest(request: OrchestratorRequest): Promise; export async function handleIpcRequest(request: OrchestratorRequest): Promise { switch (request.type) { case "spawn": { const instance = await supervisor.spawnInstance({ cwd: request.cwd, label: request.label, }); return { type: "spawn_result", ok: true, instance: toInstanceSummary(instance), }; } case "list": { return { type: "list_result", ok: true, instances: supervisor.listInstances().map(toInstanceSummary), }; } case "status": { const instance = supervisor.getInstance(request.instanceId); if (!instance) { return unknownInstanceError(request.instanceId); } return { type: "status_result", ok: true, instance: toInstanceSummary(instance), }; } case "stop": { const instance = await supervisor.stopInstance(request.instanceId); if (!instance) { return unknownInstanceError(request.instanceId); } return { type: "stop_result", ok: true, instanceId: request.instanceId, }; } case "rpc": { const response = await supervisor.handleRpc(request.instanceId, request.command); if (!response) { return unknownInstanceError(request.instanceId); } return { type: "rpc_result", ok: true, response, }; } case "attach": { const instance = supervisor.getInstance(request.instanceId); if (!instance) { return unknownInstanceError(request.instanceId); } return { type: "attach_ready", ok: true, instance: toInstanceSummary(instance), }; } } } export function attachIpcInstance( instanceId: string, onResponse: (response: AttachRpcResponse) => void, onSessionEvent: (event: AgentSessionEvent) => void, onUiRequest: (request: RpcExtensionUIRequest) => void, ): | { handleRequest( request: { type: "attach_rpc"; command: RpcCommand } | AttachHostContextRequest | RpcExtensionUIResponse, ): Promise; close(): void; } | undefined { const handle = supervisor.attachInstance(instanceId, onSessionEvent, onUiRequest); if (!handle) { return undefined; } return { async handleRequest(request): Promise { if (request.type === "attach_rpc") { const response = await handle.handleRpc(request.command); onResponse({ type: "attach_rpc_result", response }); return; } if (request.type === "attach_host_context") { handle.setHostTheme(request.theme); return; } handle.handleUiResponse(request); }, close(): void { handle.close(); }, }; }