From e7c1370075549f274bcff6dc26f3c58fc5b92169 Mon Sep 17 00:00:00 2001 From: Tarandeep Singh Juneja Date: Fri, 3 Apr 2026 13:40:59 +0530 Subject: [PATCH] fix(terminal): prevent duplicate input on shell restart Fixes #2 - When the agent shell restarted (e.g., after gitclaw exited), user keystrokes were duplicated because onData handlers accumulated. Typing 'hi' appeared as 'hhii'. Changes: - Register xterm.onData listener ONCE in constructor - Store callback in dataHandler property - onData() now replaces handler instead of stacking new ones --- src/terminal.ts | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/terminal.ts b/src/terminal.ts index acdb859..b5571bc 100644 --- a/src/terminal.ts +++ b/src/terminal.ts @@ -5,6 +5,7 @@ export class TerminalManager { readonly xterm: Terminal; private readonly fitAddon: FitAddon; private resizeObserver: ResizeObserver | null = null; + private dataHandler: ((data: string) => void) | null = null; constructor() { this.xterm = new Terminal({ @@ -39,6 +40,11 @@ export class TerminalManager { this.fitAddon = new FitAddon(); this.xterm.loadAddon(this.fitAddon); + + // Register onData once in constructor to prevent duplicate handlers on restart + this.xterm.onData((data: string) => { + this.dataHandler?.(data); + }); } /** Mount the terminal into a DOM element and start auto-resize. */ @@ -61,9 +67,11 @@ export class TerminalManager { this.xterm.write(data); } - /** Register a handler for user keystrokes (sent to shell stdin). */ + /** Register a handler for user keystrokes (sent to shell stdin). + * Only one handler can be registered at a time; subsequent calls replace the previous handler. + */ onData(handler: (data: string) => void): void { - this.xterm.onData(handler); + this.dataHandler = handler; } /** Current terminal dimensions for pty resize. */