diff --git a/src/server.ts b/src/server.ts index 17621a0..66fd947 100644 --- a/src/server.ts +++ b/src/server.ts @@ -14,7 +14,12 @@ import { respondToPrompt, updateLastSeen, } from "./db"; -import type { ClientMessage, ServerMessage, SSEEvent } from "./types"; +import type { + AnswerResponse, + ClientMessage, + ServerMessage, + SSEEvent, +} from "./types"; // Server state const sseClients = new Set>(); @@ -133,6 +138,67 @@ const server = Bun.serve({ return new Response("Invalid prompt ID", { status: 400 }); } + // New unified answer endpoint + if (url.pathname.endsWith("/answer") && req.method === "POST") { + const prompt = getPrompt(promptId); + if (!prompt) { + return new Response("Prompt not found", { status: 404 }); + } + if (prompt.response !== null) { + return new Response("Prompt already responded", { status: 400 }); + } + + const body = (await req.json()) as { response?: unknown }; + if (!body.response || typeof body.response !== "object") { + return new Response("Missing or invalid response", { status: 400 }); + } + + const answer = body.response as AnswerResponse; + let inputData: string; + + // Handle each response type + if (answer.type === "option") { + inputData = `${answer.value}\n`; + } else if (answer.type === "text") { + inputData = `${answer.value}\n`; + } else if (answer.type === "tab_instructions") { + // TODO: Implement proper key sequence handling for tab instructions + // For now, just send the selected option number + inputData = `${answer.selected_option}\n`; + console.debug( + `TODO: tab_instructions needs key sequence implementation - instruction: "${answer.instruction}"`, + ); + } else { + return new Response("Invalid response type", { status: 400 }); + } + + // Mark as responded in DB + respondToPrompt( + promptId, + answer.type === "option" ? answer.value : "custom", + ); + + // Notify CLI via WebSocket + const ws = sessionWebSockets.get(prompt.session_id); + if (ws) { + const message: ServerMessage = { type: "input", data: inputData }; + ws.send(JSON.stringify(message)); + } + + // Broadcast to dashboards + broadcastSSE({ + type: "prompt_response", + prompt_id: promptId, + response: + answer.type === "option" && answer.value === "1" + ? "approve" + : "reject", + }); + + return Response.json({ success: true }); + } + + // Legacy approve endpoint (backward compatibility) if (url.pathname.endsWith("/approve") && req.method === "POST") { const prompt = getPrompt(promptId); if (!prompt) { @@ -144,10 +210,10 @@ const server = Bun.serve({ respondToPrompt(promptId, "approve"); - // Notify CLI via WebSocket + // Notify CLI via WebSocket (using "1\n" for option 1) const ws = sessionWebSockets.get(prompt.session_id); if (ws) { - const message: ServerMessage = { type: "input", data: "y\n" }; + const message: ServerMessage = { type: "input", data: "1\n" }; ws.send(JSON.stringify(message)); } @@ -161,6 +227,7 @@ const server = Bun.serve({ return Response.json({ success: true }); } + // Legacy reject endpoint (backward compatibility) if (url.pathname.endsWith("/reject") && req.method === "POST") { const prompt = getPrompt(promptId); if (!prompt) { @@ -172,10 +239,10 @@ const server = Bun.serve({ respondToPrompt(promptId, "reject"); - // Notify CLI via WebSocket + // Notify CLI via WebSocket (using "3\n" for option 3) const ws = sessionWebSockets.get(prompt.session_id); if (ws) { - const message: ServerMessage = { type: "input", data: "n\n" }; + const message: ServerMessage = { type: "input", data: "3\n" }; ws.send(JSON.stringify(message)); }