mirror of
https://github.com/stablyai/orca.git
synced 2026-10-31 00:57:45 +00:00
fix(terminal): keep desktop history when a hidden pane is revealed (#33534)
Main built its copy of a hidden pane from the renderer's xterm at the phone's 1000-row limit, and the hidden-output reveal repaints the pane from that copy, so a restored pane with more history lost all but its last 1000 rows on first reveal.
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
import { expect, it, vi } from 'vitest'
|
||||
import { createHydrationRuntime, PTY_ID, SIZE } from './headless-hydration-ownership-test-fixture'
|
||||
|
||||
const LINES = Array.from({ length: 1500 }, (_, i) => `L${String(i + 1).padStart(4, '0')} line`)
|
||||
|
||||
it('hydrates main from the renderer at desktop depth so a hidden-output reveal keeps history', async () => {
|
||||
const runtime = createHydrationRuntime()
|
||||
const serialize = vi.fn(async (_ptyId: string, opts?: { scrollbackRows?: number }) => ({
|
||||
data: LINES.slice(-((opts?.scrollbackRows ?? 0) + SIZE.rows)).join('\r\n'),
|
||||
...SIZE
|
||||
}))
|
||||
runtime.setPtyController({
|
||||
write: () => true,
|
||||
kill: () => true,
|
||||
getForegroundProcess: async () => null,
|
||||
getSize: () => SIZE,
|
||||
hasRendererSerializer: () => true,
|
||||
serializeBuffer: serialize
|
||||
})
|
||||
|
||||
runtime.onPtyData(PTY_ID, '\r\n$ ', 1)
|
||||
await runtime.model().writeChain
|
||||
|
||||
expect(serialize).toHaveBeenCalledWith(PTY_ID, { scrollbackRows: 5000 })
|
||||
const snapshot = await runtime.serializeHiddenOutputRecoveryBuffer(PTY_ID, {
|
||||
scrollbackRows: 5000
|
||||
})
|
||||
const restored = `${snapshot?.scrollbackAnsi ?? ''}${snapshot?.data ?? ''}`
|
||||
expect(restored.match(/L\d{4} line/g)).toHaveLength(1500)
|
||||
expect(restored).toContain('L0001 line')
|
||||
})
|
||||
@@ -1,3 +1,3 @@
|
||||
// Bound desktop xterm hydration for phones: replaying the full 50k-row buffer across IPC/headless emulation is expensive (docs/mobile-prefer-renderer-scrollback.md).
|
||||
// Bound phone snapshots: replaying the full 50k-row buffer across IPC/headless emulation is expensive (docs/mobile-prefer-renderer-scrollback.md).
|
||||
export const MOBILE_SUBSCRIBE_SCROLLBACK_ROWS = 1000
|
||||
export const MOBILE_SNAPSHOT_BYTE_BUDGET = 512 * 1024
|
||||
|
||||
@@ -3,7 +3,7 @@ import { splitFreebuffScreenUpdates } from '../../../../shared/freebuff-screen-s
|
||||
import { OrcaRuntimeWithSerializeMainTerminalBuffer } from './terminal-buffer-operations'
|
||||
import { observeFreebuffTerminalStatus } from '../../freebuff-terminal-status'
|
||||
import { observeCodexCapacityTerminalStatus } from '../../codex-capacity-terminal-status'
|
||||
import { MOBILE_SUBSCRIBE_SCROLLBACK_ROWS } from '../../scrollback-limits'
|
||||
import { DESKTOP_TERMINAL_SCROLLBACK_ROWS_DEFAULT } from '../../../../shared/terminal-scrollback-policy'
|
||||
import {
|
||||
detectAgentStatusFromTitle,
|
||||
normalizeTerminalTitle
|
||||
@@ -57,8 +57,9 @@ export abstract class OrcaRuntimeWithMaybeHydrateHeadlessFromRenderer extends Or
|
||||
}
|
||||
try {
|
||||
// Retain normal-buffer scrollback while a TUI is in alt-screen so pre-TUI history remains restorable (#6106).
|
||||
// Desktop depth (this emulator's retention): a hidden-output reveal repaints the pane from this model.
|
||||
const rendered = await controller.serializeBuffer!(ptyId, {
|
||||
scrollbackRows: MOBILE_SUBSCRIBE_SCROLLBACK_ROWS
|
||||
scrollbackRows: DESKTOP_TERMINAL_SCROLLBACK_ROWS_DEFAULT
|
||||
})
|
||||
if (
|
||||
this.headlessTerminals.get(ptyId) !== state ||
|
||||
|
||||
Reference in New Issue
Block a user