mirror of
https://github.com/stablyai/orca.git
synced 2026-10-03 16:02:11 +00:00
Keep SSH typing replies inside narrow split terminal panes (#24682)
This commit is contained in:
@@ -15,7 +15,7 @@ export function remoteTypingLoadScript(runId: string): string {
|
||||
' for (const char of chunk) {',
|
||||
" if (char === '\\r' || char === '\\n') continue",
|
||||
' seq += 1',
|
||||
` process.stdout.write('\\x1b[' + statusRow + ';2H\\x1b[2KREMOTE_KEY_${runId}_' + seq + '_' + char)`,
|
||||
` process.stdout.write('\\x1b[' + statusRow + ';2H\\x1b[2KKEY_${runId}_' + seq + '_' + char)`,
|
||||
' }',
|
||||
'})'
|
||||
].join(';')
|
||||
|
||||
@@ -2,20 +2,31 @@ import '../../../src/main/daemon/xterm-env-polyfill'
|
||||
import { EventEmitter } from 'node:events'
|
||||
import { runInNewContext } from 'node:vm'
|
||||
import { Terminal } from '@xterm/headless'
|
||||
import { SerializeAddon } from '@xterm/addon-serialize'
|
||||
import { expect, it } from 'vitest'
|
||||
import { remoteTypingLoadScript } from './remote-typing-load-script'
|
||||
|
||||
it.each([12, 24, 40])(
|
||||
'keeps typed output visible through background pressure at %i rows',
|
||||
async (rows) => {
|
||||
const terminal = new Terminal({ rows, cols: 80, scrollback: 1000, allowProposedApi: true })
|
||||
it.each([
|
||||
{ rows: 12, cols: 80 },
|
||||
{ rows: 24, cols: 80 },
|
||||
{ rows: 40, cols: 80 },
|
||||
{ rows: 12, cols: 35 },
|
||||
{ rows: 24, cols: 35 },
|
||||
{ rows: 40, cols: 35 }
|
||||
])(
|
||||
'keeps typed output visible through background pressure at $rows rows and $cols columns',
|
||||
async ({ rows, cols }) => {
|
||||
const terminal = new Terminal({ rows, cols, scrollback: 1000, allowProposedApi: true })
|
||||
const serializer = new SerializeAddon()
|
||||
terminal.loadAddon(serializer)
|
||||
const runId = cols === 80 ? 'test' : '1790930671681_active'
|
||||
const input = new EventEmitter()
|
||||
const chunks: string[] = []
|
||||
let background = (): void => {
|
||||
throw new Error('Background pressure did not start')
|
||||
}
|
||||
try {
|
||||
runInNewContext(remoteTypingLoadScript('test'), {
|
||||
runInNewContext(remoteTypingLoadScript(runId), {
|
||||
process: {
|
||||
stdin: {
|
||||
isTTY: true,
|
||||
@@ -24,7 +35,7 @@ it.each([12, 24, 40])(
|
||||
resume() {},
|
||||
on: input.on.bind(input)
|
||||
},
|
||||
stdout: { rows, write: (chunk: string) => chunks.push(chunk) },
|
||||
stdout: { rows, cols, write: (chunk: string) => chunks.push(chunk) },
|
||||
exit() {}
|
||||
},
|
||||
setTimeout: (callback: () => void) => callback(),
|
||||
@@ -34,7 +45,7 @@ it.each([12, 24, 40])(
|
||||
},
|
||||
clearInterval() {}
|
||||
})
|
||||
input.emit('data', 'ab\r\ncd')
|
||||
input.emit('data', cols === 80 ? 'ab\r\ncd' : 'abcdefghij\r\n')
|
||||
for (let frame = 0; frame < 40; frame += 1) {
|
||||
background()
|
||||
}
|
||||
@@ -48,7 +59,9 @@ it.each([12, 24, 40])(
|
||||
.getLine(terminal.buffer.active.baseY + row)
|
||||
?.translateToString(true) ?? ''
|
||||
).join('\n')
|
||||
expect(screen).toContain('REMOTE_KEY_test_4_d')
|
||||
const reply = cols === 80 ? 'KEY_test_4_d' : `KEY_${runId}_10_j`
|
||||
expect(screen).toContain(reply)
|
||||
expect(serializer.serialize()).toContain(reply)
|
||||
} finally {
|
||||
terminal.dispose()
|
||||
}
|
||||
|
||||
@@ -86,7 +86,7 @@ async function measureRemoteTyping(
|
||||
const latencies: number[] = []
|
||||
for (let index = 0; index < KEY_LATENCY_SAMPLES.length; index += 1) {
|
||||
const char = KEY_LATENCY_SAMPLES[index]
|
||||
const marker = `REMOTE_KEY_${runId}_${index + 1}_${char}`
|
||||
const marker = `KEY_${runId}_${index + 1}_${char}`
|
||||
const started = performance.now()
|
||||
await page.evaluate(({ ptyId, char }) => window.api.pty.write(ptyId, char, 'driving'), {
|
||||
ptyId,
|
||||
|
||||
Reference in New Issue
Block a user