fix(mobile): separate the terminal-mode image attach path too (STA-4847)

The dock attach button wrote a bare bracketed paste, so the user's next
keystroke glued onto the path -- the ticket's exact `...pngadd`, reproduced
on device. Attach-then-type is the whole interaction here, so unlike native
chat there is no following text to test: always separate.

Desktop's twin of this button is terminal-drop-path-writer, which #15820
already routed through the shared helper. Terminal clipboard paste stays
bare on both platforms, tracked separately (desktop: STA-5258).
This commit is contained in:
Merge Sim
2026-09-04 01:50:59 -07:00
parent 4313a66f6a
commit 8af67c6b99
2 changed files with 8 additions and 2 deletions
@@ -50,7 +50,9 @@ describe('attachMobileImageToTerminal', () => {
const sendCall = client.calls.find((c) => c.method === 'terminal.send')
expect(sendCall?.params).toEqual({
terminal: 'term-1',
text: '\x1b[200~/tmp/orca-attach.png\x1b[201~',
// Trailing space: the user types on this same line next, so a bare
// `…\x1b[201~` would arrive as `…pngadd` (STA-4847).
text: '\x1b[200~/tmp/orca-attach.png\x1b[201~ ',
enter: false,
client: { id: 'device-9', type: 'mobile' }
})
@@ -1,4 +1,5 @@
import type { RpcClient } from '../transport/rpc-client'
import { separateImagePasteFromFollowingText } from '../../../src/shared/image-paste-following-text'
import {
buildMobileImagePastePayload,
saveMobileClipboardImageAsTempFile
@@ -47,7 +48,10 @@ export async function attachMobileImageToTerminal(
})
// Why: a generated image path is terminal image injection, so it's always
// bracketed (matching desktop paste) regardless of terminal mode.
const payload = buildMobileImagePastePayload(imagePath)
// Always separated: attach-then-type is the whole interaction here, so the user's
// next keystroke would otherwise glue onto the path (`…pngadd`). Unlike native
// chat there is no batch to look ahead in, and a trailing space is inert.
const payload = separateImagePasteFromFollowingText(buildMobileImagePastePayload(imagePath), true)
if (beforeTerminalSend && !(await beforeTerminalSend(terminal))) {
return false
}