From c2eaba990b89086337f264270d89f99f5fcd7c2e Mon Sep 17 00:00:00 2001 From: DodgyBadger <4453217+DodgyBadger@users.noreply.github.com> Date: Sun, 20 Sep 2026 04:37:45 +0000 Subject: [PATCH] fix(mobile): release echo passthrough after compose --- src/web/public/keyboard-accessory.js | 1 + test/mobile-prompt-composer.test.ts | 14 ++++++++++++++ 2 files changed, 15 insertions(+) diff --git a/src/web/public/keyboard-accessory.js b/src/web/public/keyboard-accessory.js index 80c9f25d..8a629dfe 100644 --- a/src/web/public/keyboard-accessory.js +++ b/src/web/public/keyboard-accessory.js @@ -1276,6 +1276,7 @@ const KeyboardAccessoryBar = { const send = () => { const text = textarea.value; if (!text || !this._sendComposedPrompt(sessionId, text)) return; + app._echoPassthroughSessions?.delete(sessionId); this._composerDrafts.delete(sessionId); this._syncComposerDraftIndicator(); close({ preserveDraft: false }); diff --git a/test/mobile-prompt-composer.test.ts b/test/mobile-prompt-composer.test.ts index 8a827c36..5b16d120 100644 --- a/test/mobile-prompt-composer.test.ts +++ b/test/mobile-prompt-composer.test.ts @@ -38,6 +38,7 @@ function loadComposer(sessionId = 'session-1') { _localEchoOverlay: localEcho, _flushedOffsets: new Map(), _flushedTexts: new Map(), + _echoPassthroughSessions: new Set(), _predictiveEcho: { clearPredictions: vi.fn() }, _sendInputAsync: vi.fn(), _uploadAndInsertImages: vi.fn(async () => ['/tmp/image-one.png']), @@ -248,6 +249,19 @@ describe('mobile prompt composer', () => { expect(app._sendInputAsync).toHaveBeenLastCalledWith('session-1', '\r', { useMux: true }); }); + it('releases echo passthrough after a composed prompt is queued', () => { + const { app, bar, document } = loadComposer(); + app._echoPassthroughSessions.add('session-1'); + app._echoPassthroughSessions.add('session-2'); + bar.composePrompt(); + textarea(document).value = 'send from composer'; + + (document.querySelector('.paste-send') as HTMLButtonElement).click(); + + expect(app._echoPassthroughSessions.has('session-1')).toBe(false); + expect(app._echoPassthroughSessions.has('session-2')).toBe(true); + }); + it('preserves the draft and focuses xterm when Use terminal keyboard is chosen', () => { const { app, bar, document, localEcho, runTimers } = loadComposer(); const composeButton = mountComposeButton(bar, document);