SPB Git

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%
2.1 KB · 75 lines typescript
Raw Blame History
1/**2 * KHAELOR3 * File: src/tui/renderer/terminal.ts4 * Description: Terminal session guard — raw mode + bracketed paste on mount, guaranteed restore on exit and on crash.5 *6 * Author: Simon-Pierre Boucher7 * Contact: contact@spboucher.ai8 */910import {11  BRACKETED_PASTE_OFF,12  BRACKETED_PASTE_ON,13  SHOW_CURSOR,14  SYNC_OFF,15} from "./ansi.js";1617export interface TerminalSession {18  /** Restore the terminal to its pre-mount state. Idempotent. */19  restore(): void;20}2122/**23 * Enter KHAELOR's terminal state: raw mode, bracketed paste. Installs24 * process-level handlers so the terminal is restored on normal exit, on25 * SIGTERM/SIGHUP, and on crash (uncaughtException / unhandledRejection) —26 * a dead KHAELOR must never leave the user's shell in raw mode with a27 * hidden cursor (CLAUDE.md §14).28 */29export function enterTerminal(30  stdin: NodeJS.ReadStream,31  stdout: NodeJS.WriteStream,32): TerminalSession {33  const wasRaw = stdin.isTTY ? stdin.isRaw : false;34  if (stdin.isTTY) stdin.setRawMode(true);35  stdin.resume();36  stdout.write(BRACKETED_PASTE_ON);3738  let restored = false;39  const restore = (): void => {40    if (restored) return;41    restored = true;42    // Undo everything a paint could have left half-done.43    stdout.write(SYNC_OFF + SHOW_CURSOR + BRACKETED_PASTE_OFF);44    if (stdin.isTTY) stdin.setRawMode(wasRaw);45    stdin.pause();46    process.off("exit", onExit);47    process.off("SIGTERM", onSignal);48    process.off("SIGHUP", onSignal);49    process.off("uncaughtException", onFatal);50    process.off("unhandledRejection", onFatal);51  };5253  const onExit = (): void => {54    restore();55  };56  const onSignal = (): void => {57    restore();58    process.exit(1);59  };60  const onFatal = (error: unknown): void => {61    restore();62    const message = error instanceof Error ? (error.stack ?? error.message) : String(error);63    process.stderr.write(`\nkhaelor: fatal error\n${message}\n`);64    process.exit(1);65  };6667  process.on("exit", onExit);68  process.on("SIGTERM", onSignal);69  process.on("SIGHUP", onSignal);70  process.on("uncaughtException", onFatal);71  process.on("unhandledRejection", onFatal);7273  return { restore };74}75