Implement key sequence execution for tab instructions

Execute the tab instruction flow:
- Navigate to target option using arrow keys
- Send Tab to enter instruction mode
- Type the instruction text
- Send Enter to submit

The sequence runs asynchronously with proper delays between steps
(50ms between arrows, 100ms before Tab, 100ms before instruction).
This commit is contained in:
Jared Miller 2026-01-28 13:13:51 -05:00
parent 727f3e0e18
commit acd75b0303
Signed by: shmup
GPG key ID: 22B5C6D66A38B06C

View file

@ -165,12 +165,68 @@ const server = Bun.serve<SessionData>({
} 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 });
}