Something went wrong. Try again.
Monorepo for Aesthetic.Computer aesthetic.computer
Something went wrong. Try again.
JavaScript
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297// split.mjs — Side-by-side PTY split view for AC native// Left pane: system.pty (default: claude)// Right pane: system.pty2 (default: /bin/sh)// Ctrl+N: toggle focus | Ctrl+W: exit to prompt
let leftGrid = null, rightGrid = null;let leftCols = 0, rightCols = 0;let rows = 0;const cellW = 6, cellH = 10;const CELL_SIZE = 10;let activePane = 0; // 0=left, 1=rightlet shiftHeld = false, ctrlHeld = false, altHeld = false;let cursorBlink = 0;let leftStarted = false, rightStarted = false;let leftLastExitCode = -1, rightLastExitCode = -1;let leftCmd = "/bin/claude", rightCmd = "/bin/sh";
// ANSI 16-color paletteconst COLORS = [ [0, 0, 0], [170, 0, 0], [0, 170, 0], [170, 85, 0], [0, 0, 170], [170, 0, 170], [0, 170, 170], [170, 170, 170], [85, 85, 85], [255, 85, 85], [85, 255, 85], [255, 255, 85], [85, 85, 255], [255, 85, 255], [85, 255, 255], [255, 255, 255],];const DEFAULT_FG = [170, 170, 170];const DEFAULT_BG = [0, 0, 0];
function fgColor(idx, bold, r, g, b) { if (idx === 255) return [r, g, b]; if (idx === 16) return bold ? COLORS[15] : DEFAULT_FG; if (idx >= 0 && idx < 8 && bold) return COLORS[idx + 8]; if (idx >= 0 && idx < 16) return COLORS[idx]; return DEFAULT_FG;}
function bgColor(idx, r, g, b) { if (idx === 255) return [r, g, b]; if (idx === 16) return DEFAULT_BG; if (idx >= 0 && idx < 16) return COLORS[idx]; return DEFAULT_BG;}
const UNICODE_MAP = { 0x2500:"-",0x2502:"|",0x250C:"+",0x2510:"+",0x2514:"+",0x2518:"+", 0x251C:"+",0x2524:"+",0x252C:"+",0x2534:"+",0x253C:"+", 0x2550:"=",0x2551:"|",0x2554:"+",0x2557:"+",0x255A:"+",0x255D:"+", 0x2560:"+",0x2563:"+",0x2566:"+",0x2569:"+",0x256C:"+", 0x256D:"+",0x256E:"+",0x256F:"+",0x2570:"+", 0x2588:"#",0x2591:".",0x2592:":",0x2593:"#", 0x2190:"<",0x2191:"^",0x2192:">",0x2193:"v", 0x2022:"*",0x25CF:"*",0x25A0:"#",0x25B2:"^",0x25B6:">",0x25BC:"v", 0x2714:"+",0x2715:"x",0x2713:"+",0x2717:"x", 0x2026:"...",0x2018:"'",0x2019:"'",0x201C:'"',0x201D:'"', 0x2013:"-",0x2014:"--", 0x280B:"|",0x2819:"/",0x2838:"-",0x2830:"\\", 0x2826:"|",0x2807:"/",0x280E:"-",0x2821:"\\",};
function charReplace(ch) { if (ch >= 32 && ch < 127) return String.fromCharCode(ch); const mapped = UNICODE_MAP[ch]; if (mapped) return mapped; if (ch >= 0x2800 && ch <= 0x28FF) return "."; if (ch >= 0x2500 && ch <= 0x257F) return "+"; if (ch >= 0x2580 && ch <= 0x259F) return "#"; if (ch >= 0x25A0 && ch <= 0x25FF) return "*"; if (ch >= 0x2700 && ch <= 0x27BF) return "*"; if (ch >= 0x1F000) return " "; if (ch > 127) return " "; return null;}
function cmdToArgs(cmd) { // "/bin/claude" → ["/bin/claude", "claude"] // "/bin/sh" → ["/bin/sh", "sh"] const name = cmd.split("/").pop(); return [cmd, name];}
function boot({ system, screen, params }) { // params[0] = left cmd name (e.g. "claude"), params[1] = right cmd name const lname = (params && params[0]) || "claude"; const rname = (params && params[1]) || "sh"; leftCmd = lname.startsWith("/") ? lname : "/bin/" + lname; rightCmd = rname.startsWith("/") ? rname : "/bin/" + rname;
const halfW = Math.floor((screen.width - 1) / 2); leftCols = Math.floor(halfW / cellW); rightCols = Math.floor((screen.width - halfW - 1) / cellW); rows = Math.floor(screen.height / cellH);
const [lcmd, larg] = cmdToArgs(leftCmd); const [rcmd, rarg] = cmdToArgs(rightCmd); system.pty.spawn(lcmd, [larg], leftCols, rows); system.pty2.spawn(rcmd, [rarg], rightCols, rows); leftStarted = rightStarted = true; activePane = 0;}
function renderPane(pty, grid, xOff, paneCols, paneRows, isActive, ink, box, write) { const T = __theme.update();
if (!pty.active) { ink(T.fgDim, T.fgDim, T.fgDim); write("terminal exited", { x: xOff + 4, y: 4, font: 1 }); return; }
if (!grid) return;
const useCols = pty.cols || paneCols; const useRows = pty.rows || paneRows;
for (let y = 0; y < useRows; y++) { for (let x = 0; x < useCols; x++) { const i = (y * useCols + x) * CELL_SIZE; const ch = grid[i]; const fg = grid[i + 1]; const bg = grid[i + 2]; const bold = grid[i + 3]; const fg_r = grid[i + 4], fg_g = grid[i + 5], fg_b = grid[i + 6]; const bg_r = grid[i + 7], bg_g = grid[i + 8], bg_b = grid[i + 9];
const px = xOff + x * cellW; const py = y * cellH;
const [br, bg2, bb] = bgColor(bg, bg_r, bg_g, bg_b); if (br !== 0 || bg2 !== 0 || bb !== 0) { ink(br, bg2, bb); box(px, py, cellW, cellH); } if (ch > 32) { const rep = charReplace(ch); if (rep) { const [fr, fg2, fb] = fgColor(fg, bold, fg_r, fg_g, fg_b); ink(fr, fg2, fb); write(rep, { x: px, y: py, font: 1 }); } } } }
// Blinking cursor — only when PTY reports cursor visible (?25h) if (isActive && pty.cursorVisible !== false && Math.floor(cursorBlink / 30) % 2 === 0) { const cx = xOff + (pty.cursorX || 0) * cellW; const cy = (pty.cursorY || 0) * cellH; ink(T.fg, T.fg, T.fg, 180); box(cx, cy, cellW, cellH); }}
function paint({ wipe, ink, box, write, system, screen }) { const T = __theme.update(); const w = screen.width, h = screen.height; wipe(T.bgDim[0], T.bgDim[1], T.bgDim[2]); cursorBlink++;
const halfW = Math.floor((w - 1) / 2);
// Cache grids if (system.pty.grid) leftGrid = system.pty.grid; if (system.pty2.grid) rightGrid = system.pty2.grid;
// Resize check — left const newLeftCols = Math.floor(halfW / cellW); const newRightCols = Math.floor((w - halfW - 1) / cellW); const newRows = Math.floor(h / cellH); if (newLeftCols !== leftCols || newRows !== rows) { leftCols = newLeftCols; rows = newRows; if (leftCols > 0 && rows > 0) system.pty.resize(leftCols, rows); } if (newRightCols !== rightCols) { rightCols = newRightCols; if (rightCols > 0 && rows > 0) system.pty2.resize(rightCols, rows); }
// Render left pane renderPane(system.pty, leftGrid, 0, leftCols, rows, activePane === 0, ink, box, write);
// Divider const divX = halfW; ink(activePane === 0 ? 80 : 40, activePane === 0 ? 160 : 80, activePane === 1 ? 160 : 80); box(divX, 0, 1, h);
// Render right pane renderPane(system.pty2, rightGrid, halfW + 1, rightCols, rows, activePane === 1, ink, box, write);
// Status bar hint (bottom of divider) ink(60, 60, 70); write("^N:swap ^W:exit", { x: divX - 44, y: h - 10, font: 1 });}
const SHIFT_MAP = { "1":"!","2":"@","3":"#","4":"$","5":"%", "6":"^","7":"&","8":"*","9":"(","0":")", "-":"_","=":"+","[":"{","]":"}","\\":"|", ";":":","'":'"',",":"<",".":">","/":"?","`":"~",};
function keyToAnsi(key) { if (key === "arrowup") return "\x1b[A"; if (key === "arrowdown") return "\x1b[B"; if (key === "arrowright") return "\x1b[C"; if (key === "arrowleft") return "\x1b[D"; if (key === "home") return "\x1b[H"; if (key === "end") return "\x1b[F"; if (key === "pageup") return "\x1b[5~"; if (key === "pagedown") return "\x1b[6~"; if (key === "insert") return "\x1b[2~"; if (key === "delete") return "\x1b[3~"; if (key === "enter" || key === "return") return "\r"; if (key === "backspace") return "\x7f"; if (key === "tab") return "\t"; if (key === "escape") return "\x1b"; if (key === "f1") return "\x1bOP"; if (key === "f2") return "\x1bOQ"; if (key === "f3") return "\x1bOR"; if (key === "f4") return "\x1bOS"; if (key === "f5") return "\x1b[15~"; if (key === "f6") return "\x1b[17~"; if (key === "f7") return "\x1b[18~"; if (key === "f8") return "\x1b[19~"; if (key === "f9") return "\x1b[20~"; if (key === "f10") return "\x1b[21~"; if (key === "f11") return "\x1b[23~"; if (key === "f12") return "\x1b[24~"; return null;}
function act({ event: e, system }) { if (e.is("keyboard:down:shift")) { shiftHeld = true; return; } if (e.is("keyboard:up:shift")) { shiftHeld = false; return; } if (e.is("keyboard:down:control")) { ctrlHeld = true; return; } if (e.is("keyboard:up:control")) { ctrlHeld = false; return; } if (e.is("keyboard:down:alt")) { altHeld = true; return; } if (e.is("keyboard:up:alt")) { altHeld = false; return; }
if (!e.is("keyboard:down")) return; const key = e.key; if (!key) return;
// Ctrl+N — toggle active pane if (ctrlHeld && key === "n") { activePane = activePane === 0 ? 1 : 0; return; }
// Ctrl+W — exit to prompt if (ctrlHeld && key === "w") { system.jump("prompt"); return; }
const activePty = activePane === 0 ? system.pty : system.pty2;
// Ctrl+key → control character if (ctrlHeld && key.length === 1) { const code = key.toLowerCase().charCodeAt(0); if (code >= 97 && code <= 122) { activePty.write(String.fromCharCode(code - 96)); return; } }
const ansi = keyToAnsi(key); if (ansi) { activePty.write(ansi); cursorBlink = 0; return; }
if (key === "space") { activePty.write(" "); cursorBlink = 0; return; }
if (key.length === 1) { let ch = key; if (shiftHeld) { if (SHIFT_MAP[ch]) ch = SHIFT_MAP[ch]; else ch = ch.toUpperCase(); } activePty.write(ch); cursorBlink = 0; }}
function leave({ system }) { if (system.pty.active) system.pty.kill(); if (system.pty2.active) system.pty2.kill();}
export { boot, paint, act, leave };