spb/khaelor Public
KHAELOR — a terminal-native autonomous engineering agent powered by Anthropic.
TypeScript 82.9%
HTML 14.9%
CSS 1.1%
JavaScript 0.7%
1/**2 * KHAELOR3 * File: tests/tui/input.test.ts4 * Description: Key decoder tests — control keys, escape sequences, bracketed paste across chunks, reply filtering.5 *6 * Author: Simon-Pierre Boucher7 * Contact: contact@spboucher.ai8 */910import { describe, expect, it } from "vitest";11import { KeyDecoder } from "../../src/tui/renderer/input.js";1213function decode(...chunks: string[]) {14 const d = new KeyDecoder();15 return chunks.flatMap((c) => d.push(c));16}1718describe("KeyDecoder", () => {19 it("decodes printable characters including unicode", () => {20 expect(decode("aé🎉")).toEqual([21 { type: "char", ch: "a" },22 { type: "char", ch: "é" },23 { type: "char", ch: "🎉" },24 ]);25 });2627 it("decodes enter, tab, backspace, ctrl keys", () => {28 expect(decode("\r")).toEqual([{ type: "enter" }]);29 expect(decode("\t")).toEqual([{ type: "tab" }]);30 expect(decode("\x7f")).toEqual([{ type: "backspace" }]);31 expect(decode("\x01")).toEqual([{ type: "ctrl", ch: "a" }]);32 expect(decode("\x0b")).toEqual([{ type: "ctrl", ch: "k" }]);33 expect(decode("\x1f")).toEqual([{ type: "ctrl", ch: "_" }]);34 expect(decode("\n")).toEqual([{ type: "ctrl", ch: "j" }]);35 });3637 it("decodes arrows with alt/ctrl modifiers", () => {38 expect(decode("\x1b[A")).toEqual([{ type: "arrow", key: "up", alt: false, ctrl: false }]);39 expect(decode("\x1b[1;5C")).toEqual([{ type: "arrow", key: "right", alt: false, ctrl: true }]);40 expect(decode("\x1b[1;3D")).toEqual([{ type: "arrow", key: "left", alt: true, ctrl: false }]);41 });4243 it("decodes home/end/delete variants", () => {44 expect(decode("\x1b[H")).toEqual([{ type: "home" }]);45 expect(decode("\x1b[4~")).toEqual([{ type: "end" }]);46 expect(decode("\x1b[3~")).toEqual([{ type: "delete" }]);47 expect(decode("\x1bOF")).toEqual([{ type: "end" }]);48 });4950 it("decodes alt-letter and alt-backspace", () => {51 expect(decode("\x1bb")).toEqual([{ type: "alt", ch: "b" }]);52 expect(decode("\x1b\x7f")).toEqual([{ type: "alt-backspace" }]);53 });5455 it("decodes kitty shift+enter", () => {56 expect(decode("\x1b[13;2u")).toEqual([{ type: "shift-enter" }]);57 });5859 it("treats a chunk ending on lone ESC as the Esc key", () => {60 expect(decode("\x1b")).toEqual([{ type: "esc" }]);61 });6263 it("reassembles a bracketed paste split across chunks", () => {64 expect(decode("\x1b[200~hello\nwor", "ld\x1b[201~")).toEqual([65 { type: "paste", text: "hello\nworld" },66 ]);67 });6869 it("handles a paste-end marker torn mid-sequence", () => {70 expect(decode("\x1b[200~abc\x1b[20", "1~x")).toEqual([71 { type: "paste", text: "abc" },72 { type: "char", ch: "x" },73 ]);74 });7576 it("silently drops terminal query replies (DECRQM, OSC 11)", () => {77 expect(decode("\x1b[?2026;1$y")).toEqual([]);78 expect(decode("\x1b]11;rgb:1c1c/1c1c/1c1c\x07")).toEqual([]);79 });8081 it("keeps a torn CSI across chunks and completes it", () => {82 expect(decode("\x1b[1;", "5C")).toEqual([83 { type: "arrow", key: "right", alt: false, ctrl: true },84 ]);85 });86});87