/** * S-03 — send-keys input route. * * POST /sessions/:id/input * * Body (IC-1 ClientToServer subset, but as HTTP POST for non-WS clients): * { type: "key"; name: string } * { type: "keys"; data: string } * { type: "paste"; data: string } * * Response: 204 No Content on success, 400 on bad input, 404 if session missing. * * Note: the primary path for send-keys is via WS (T-1.5 stream route handles * key/keys/paste messages inline). This HTTP endpoint is for clients that * don't have an open stream (e.g. one-shot CLI tools). * * Owner: T-1.5 */ import type { IncomingMessage, ServerResponse } from "node:http"; import { sendKey, sendKeys, sendPaste } from "../../tmux/input.js"; import { getSession } from "../../tmux/manager.js"; import { readBody, sendJson } from "../util.js"; export async function handleInput( req: IncomingMessage, res: ServerResponse, sessionId: string, ): Promise { const session = await getSession(sessionId).catch(() => null); if (!session) { sendJson(res, 404, { error: "session_not_found", message: `Session "${sessionId}" not found`, }); return; } let body: unknown; try { body = JSON.parse(await readBody(req)); } catch { sendJson(res, 400, { error: "bad_request", message: "Invalid JSON body" }); return; } if (!body || typeof body !== "object") { sendJson(res, 400, { error: "bad_request", message: "Body must be a JSON object", }); return; } const m = body as Record; try { switch (m.type) { case "key": { if (typeof m.name !== "string") { sendJson(res, 400, { error: "bad_request", message: "key.name must be a string", }); return; } await sendKey(sessionId, m.name); break; } case "keys": { if (typeof m.data !== "string") { sendJson(res, 400, { error: "bad_request", message: "keys.data must be a string", }); return; } await sendKeys(sessionId, m.data); break; } case "paste": { if (typeof m.data !== "string") { sendJson(res, 400, { error: "bad_request", message: "paste.data must be a string", }); return; } await sendPaste(sessionId, m.data); break; } default: sendJson(res, 400, { error: "bad_request", message: `Unknown type: ${String(m.type)}`, }); return; } } catch (err) { sendJson(res, 500, { error: "internal_error", message: String(err) }); return; } res.writeHead(204).end(); }