Skip to content

Commit ce2ba29

Browse files
committed
fix(coding-agent): clear extension terminal input listeners on reset
closes #1293
1 parent 30fd99b commit ce2ba29

1 file changed

Lines changed: 22 additions & 1 deletion

File tree

packages/coding-agent/src/modes/interactive/interactive-mode.ts

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,7 @@ export class InteractiveMode {
221221
private extensionSelector: ExtensionSelectorComponent | undefined = undefined;
222222
private extensionInput: ExtensionInputComponent | undefined = undefined;
223223
private extensionEditor: ExtensionEditorComponent | undefined = undefined;
224+
private extensionTerminalInputUnsubscribers = new Set<() => void>();
224225

225226
// Extension widgets (components rendered above/below the editor)
226227
private extensionWidgetsAbove = new Map<string, Component & { dispose?(): void }>();
@@ -1237,6 +1238,7 @@ export class InteractiveMode {
12371238
this.hideExtensionEditor();
12381239
}
12391240
this.ui.hideOverlay();
1241+
this.clearExtensionTerminalInputListeners();
12401242
this.setExtensionFooter(undefined);
12411243
this.setExtensionHeader(undefined);
12421244
this.clearExtensionWidgets();
@@ -1359,6 +1361,24 @@ export class InteractiveMode {
13591361
this.ui.requestRender();
13601362
}
13611363

1364+
private addExtensionTerminalInputListener(
1365+
handler: (data: string) => { consume?: boolean; data?: string } | undefined,
1366+
): () => void {
1367+
const unsubscribe = this.ui.addInputListener(handler);
1368+
this.extensionTerminalInputUnsubscribers.add(unsubscribe);
1369+
return () => {
1370+
unsubscribe();
1371+
this.extensionTerminalInputUnsubscribers.delete(unsubscribe);
1372+
};
1373+
}
1374+
1375+
private clearExtensionTerminalInputListeners(): void {
1376+
for (const unsubscribe of this.extensionTerminalInputUnsubscribers) {
1377+
unsubscribe();
1378+
}
1379+
this.extensionTerminalInputUnsubscribers.clear();
1380+
}
1381+
13621382
/**
13631383
* Create the ExtensionUIContext for extensions.
13641384
*/
@@ -1368,7 +1388,7 @@ export class InteractiveMode {
13681388
confirm: (title, message, opts) => this.showExtensionConfirm(title, message, opts),
13691389
input: (title, placeholder, opts) => this.showExtensionInput(title, placeholder, opts),
13701390
notify: (message, type) => this.showExtensionNotify(message, type),
1371-
onTerminalInput: (handler) => this.ui.addInputListener(handler),
1391+
onTerminalInput: (handler) => this.addExtensionTerminalInputListener(handler),
13721392
setStatus: (key, text) => this.setExtensionStatus(key, text),
13731393
setWorkingMessage: (message) => {
13741394
if (this.loadingAnimation) {
@@ -4352,6 +4372,7 @@ export class InteractiveMode {
43524372
this.loadingAnimation.stop();
43534373
this.loadingAnimation = undefined;
43544374
}
4375+
this.clearExtensionTerminalInputListeners();
43554376
this.footer.dispose();
43564377
this.footerDataProvider.dispose();
43574378
if (this.unsubscribe) {

0 commit comments

Comments
 (0)