From 041c3dc0028bdba5d7ca4e58c00bf3bafc3ea52b Mon Sep 17 00:00:00 2001 From: "tao.chen" <93983997+taochen-ct@users.noreply.github.com> Date: Mon, 6 Jul 2026 13:39:20 +0800 Subject: [PATCH] fix(web): clear terminal on workspace change; disable Mac Option as Meta - terminal: on workspaceId change call terminal.clear() and terminal.reset() so the previous workspace's scrollback is wiped before the new shell's output appears. - terminal: set macOptionIsMeta: false. With the default (true), Mac Option+key sequences (e.g. Option+[ emits ESC) leak a literal 0x1b into the shell's stdin, which crashes downstream REPLs like Python's with "invalid non-printable character U+001B". --- web/src/components/terminal/TerminalPanel.tsx | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/web/src/components/terminal/TerminalPanel.tsx b/web/src/components/terminal/TerminalPanel.tsx index 94ca9be..0d411d1 100644 --- a/web/src/components/terminal/TerminalPanel.tsx +++ b/web/src/components/terminal/TerminalPanel.tsx @@ -38,6 +38,12 @@ export function TerminalPanel({ workspaceId }: TerminalPanelProps) { terminal = new Terminal({ cursorBlink: true, convertEol: true, + // Prevent Mac Option+key from emitting ESC. Without this, typing + // Option+[ etc. leaks a literal 0x1b into the shell's stdin, which + // can break downstream programs that don't interpret escape + // sequences (e.g. Python's REPL reports "invalid non-printable + // character U+001B"). + macOptionIsMeta: false, fontFamily: 'Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace', fontSize: 12, @@ -102,6 +108,10 @@ export function TerminalPanel({ workspaceId }: TerminalPanelProps) { hasWelcomedRef.current = false; isDeadRef.current = false; setIsDead(false); + // Clear the previous workspace's scrollback so the user does not see + // shell output from another workspace in the new one. + terminal.clear(); + terminal.reset(); const removeInputHandler = terminal.onData((input) => { if (!isDeadRef.current) {