diff --git a/src/server.ts b/src/server.ts index 66407cc..63107c8 100644 --- a/src/server.ts +++ b/src/server.ts @@ -165,12 +165,68 @@ const server = Bun.serve({ } 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}"`, + // Execute key sequence for tab instructions with delays: + // 1. Navigate to selected_option (up/down arrows) + // 2. Wait 100ms + // 3. Send Tab key + // 4. Wait 100ms + // 5. Write instruction text + // 6. Send Enter key + + const promptData = prompt.prompt_json; + if (!promptData || promptData.prompt_type !== "permission") { + return new Response("Tab instructions only valid for permission prompts", { status: 400 }); + } + + const currentOption = promptData.selected_option; + const targetOption = answer.selected_option; + + // Mark as responded in DB first + respondToPrompt( + promptId, + `tab:${answer.selected_option}`, ); + + // Broadcast to dashboards + broadcastSSE({ + type: "prompt_response", + prompt_id: promptId, + response: answer.selected_option === 1 ? "approve" : "reject", + }); + + // Get WebSocket for async execution + const ws = sessionWebSockets.get(prompt.session_id); + if (!ws) { + return new Response("Session WebSocket not found", { status: 404 }); + } + + // Execute key sequence asynchronously with delays + (async () => { + const sendInput = (data: string) => { + const message: ServerMessage = { type: "input", data }; + ws.send(JSON.stringify(message)); + }; + + // Navigate to target option + const diff = targetOption - currentOption; + const arrow = diff > 0 ? '\x1b[B' : '\x1b[A'; + for (let i = 0; i < Math.abs(diff); i++) { + sendInput(arrow); + await Bun.sleep(50); // Small delay between arrows + } + + await Bun.sleep(100); + sendInput('\t'); // Tab key + + await Bun.sleep(100); + sendInput(answer.instruction); // Instruction text + sendInput('\n'); // Enter key + })().catch((err) => { + console.error("Error executing tab instruction sequence:", err); + }); + + // Return immediately (async execution continues in background) + return Response.json({ success: true }); } else { return new Response("Invalid response type", { status: 400 }); }