import type { Page, TestInfo } from '@stablyai/playwright-test' import { expect } from '@stablyai/playwright-test' import { randomUUID } from 'node:crypto' import { mkdirSync, rmSync, writeFileSync } from 'node:fs' import path from 'node:path' import { ensureTerminalVisible, getActiveWorktreeId, getAllWorktreeIds, switchToWorktree, waitForActiveWorktree, waitForSessionReady } from './helpers/store' import { getTerminalContent, sendToTerminal, waitForActivePanePtyId, waitForActiveTerminalManager } from './helpers/terminal' type HiddenPressurePane = { ptyId: string } type HiddenPressureDeps = { annotateTypingMeasurement: ( testInfo: TestInfo, type: string, paneCount: number, measurement: TMeasurement, debug: TDebug | null, scheduler: TScheduler | null, mainPressure: TMainPressure | null, ackGate: TAckGate | null ) => void ensureActiveWorktreePaneLoad: (page: Page, paneCount: number) => Promise holdTerminalAckGate: (page: Page, ptyIds: string[]) => Promise measureTypingDuringLoad: ( page: Page, scriptPath: string, ptyId: string, runId: string ) => Promise readMainPtyPressureDebug: (page: Page) => Promise readTerminalAckGateDebug: (page: Page) => Promise readTerminalOutputSchedulerDebug: (page: Page) => Promise readTerminalPtyOutputDebug: (page: Page) => Promise releaseTerminalAckGate: (page: Page) => Promise resetTerminalPtyOutputDebug: (page: Page) => Promise waitForMainPtyPressureBacklog: (page: Page) => Promise writeInteractivePromptScript: (scriptPath: string, runId: string) => void } type HiddenPressureDebug = { hiddenRendererSkipCount: number hiddenRendererSkippedChars: number } type HiddenPressureMeasurement = { medianLatencyMs: number worstLatencyMs: number maxTimerDriftMs: number } type HiddenPressureMainSnapshot = { peakPendingChars: number peakRendererInFlightChars: number ackGatedFlushSkipCount: number } type HiddenPressureAckGate = { heldAckChars: number } // Why: restore still has to finish promptly, but parallel Electron workers on // Linux CI can overshoot the 1s product target without a responsiveness regression. const MAX_HIDDEN_RESTORE_LATENCY_MS = 1_500 export function pressureOutputScript(runId: string): string { return ` const paneIndex = process.argv[2] ?? '0' const targetChars = Number(process.argv[3] ?? '0') const delayMs = Number(process.argv[4] ?? '0') const header = 'OPENCODE_PRESSURE_START_${runId}_' + paneIndex + '\\n' const chunkBody = '#'.repeat(8192) let written = 0 process.stdout.write(header) function writeMore() { let canContinue = true while (canContinue && written < targetChars) { const frame = String(written).padStart(8, '0') const chunk = '\\x1b[?2026h\\x1b[1;1Hpressure pane=' + paneIndex + ' frame=' + frame + ' ' + chunkBody + '\\x1b[?2026l\\n' written += chunk.length canContinue = process.stdout.write(chunk) } if (written < targetChars) { process.stdout.once('drain', writeMore) return } process.stdout.write('OPENCODE_PRESSURE_DONE_${runId}_' + paneIndex + '\\n') } setTimeout(writeMore, Number.isFinite(delayMs) && delayMs > 0 ? delayMs : 0) ` } export function writePressureOutputScript(scriptPath: string, runId: string): void { mkdirSync(path.dirname(scriptPath), { recursive: true }) writeFileSync(scriptPath, pressureOutputScript(runId)) } export async function runHiddenRealPtyPressureScenario< TMeasurement extends HiddenPressureMeasurement, TDebug extends HiddenPressureDebug, TMainPressure extends HiddenPressureMainSnapshot, TAckGate extends HiddenPressureAckGate, TScheduler >({ deps, annotationSuffix, hiddenPaneCount, pressureOutputChars, pressureStartDelayMs, testInfo, testRepoPath, orcaPage }: { deps: HiddenPressureDeps annotationSuffix?: string hiddenPaneCount: number pressureOutputChars: number pressureStartDelayMs: number testInfo: TestInfo testRepoPath: string orcaPage: Page }): Promise { await waitForSessionReady(orcaPage) const firstWorktreeId = await waitForActiveWorktree(orcaPage) const allWorktreeIds = await getAllWorktreeIds(orcaPage) const secondWorktreeId = allWorktreeIds.find((id) => id !== firstWorktreeId) expect(Boolean(secondWorktreeId), 'OpenCode hidden PTY pressure needs a second worktree').toBe( true ) if (!secondWorktreeId) { return } await switchToWorktree(orcaPage, secondWorktreeId) const hiddenPanes = await deps.ensureActiveWorktreePaneLoad(orcaPage, hiddenPaneCount) const runId = randomUUID() const typingScriptPath = path.join( testRepoPath, `.orca-opencode-hidden-pressure-typing-${runId}.mjs` ) const pressureScriptPath = path.join( testRepoPath, `.orca-opencode-hidden-pressure-load-${runId}.mjs` ) deps.writeInteractivePromptScript(typingScriptPath, runId) writePressureOutputScript(pressureScriptPath, runId) await deps.resetTerminalPtyOutputDebug(orcaPage) await deps.holdTerminalAckGate( orcaPage, hiddenPanes.map((pane) => pane.ptyId) ) try { await startHiddenPressureCommands({ hiddenPanes, orcaPage, pressureOutputChars, pressureScriptPath, pressureStartDelayMs }) await switchToTypingWorkspace(orcaPage, firstWorktreeId) const typingPtyId = await waitForActivePanePtyId(orcaPage) const pressureBeforeTyping = await deps.waitForMainPtyPressureBacklog(orcaPage) const measurement = await deps.measureTypingDuringLoad( orcaPage, typingScriptPath, typingPtyId, runId ) const debug = await deps.readTerminalPtyOutputDebug(orcaPage) const mainPressure = await deps.readMainPtyPressureDebug(orcaPage) const ackGate = await deps.readTerminalAckGateDebug(orcaPage) deps.annotateTypingMeasurement( testInfo, `opencode-hidden-real-pty-pressure-typing${annotationSuffix ?? ''}`, hiddenPanes.length + 1, measurement, debug, await deps.readTerminalOutputSchedulerDebug(orcaPage), mainPressure, ackGate ) expect(debug?.hiddenRendererSkipCount ?? 0).toBe(0) expect(debug?.hiddenRendererSkippedChars ?? 0).toBe(0) expect(pressureBeforeTyping.peakPendingChars).toBeGreaterThan(0) expect(pressureBeforeTyping.ackGatedFlushSkipCount).toBeGreaterThan(0) expect(mainPressure?.peakRendererInFlightChars ?? 0).toBeGreaterThanOrEqual(8 * 1024 * 1024) expect(ackGate?.heldAckChars ?? 0).toBeGreaterThan(0) expect(measurement.medianLatencyMs).toBeLessThan(75) expect(measurement.worstLatencyMs).toBeLessThan(300) expect(measurement.maxTimerDriftMs).toBeLessThan(150) await deps.releaseTerminalAckGate(orcaPage) const restoreLatencyMs = await measureHiddenOutputRestoreLatency( orcaPage, secondWorktreeId, runId ) testInfo.annotations.push({ type: `opencode-hidden-real-pty-restore${annotationSuffix ?? ''}`, description: `panes=${hiddenPanes.length + 1} restore=${restoreLatencyMs.toFixed( 1 )}ms hiddenSkippedChars=${debug?.hiddenRendererSkippedChars ?? 0} mainPeakInFlightChars=${ mainPressure?.peakRendererInFlightChars ?? 0 } heldAckChars=${ackGate?.heldAckChars ?? 0}` }) expect(restoreLatencyMs).toBeLessThan(MAX_HIDDEN_RESTORE_LATENCY_MS) } finally { await cleanupHiddenPressureScenario({ deps, firstWorktreeId, hiddenPanes, orcaPage, pressureScriptPath, secondWorktreeId, typingScriptPath }) } } async function measureHiddenOutputRestoreLatency( orcaPage: Page, worktreeId: string, runId: string ): Promise { const restoreStart = performance.now() await switchToWorktree(orcaPage, worktreeId) await expect .poll(() => getTerminalContent(orcaPage, 20_000), { timeout: 20_000, message: 'Hidden PTY output was not restored from main buffer on return' }) .toContain(`OPENCODE_PRESSURE_DONE_${runId}_`) return performance.now() - restoreStart } async function startHiddenPressureCommands({ hiddenPanes, orcaPage, pressureOutputChars, pressureScriptPath, pressureStartDelayMs }: { hiddenPanes: HiddenPressurePane[] orcaPage: Page pressureOutputChars: number pressureScriptPath: string pressureStartDelayMs: number }): Promise { await Promise.all( hiddenPanes.map((pane, paneIndex) => sendToTerminal( orcaPage, pane.ptyId, `node ${JSON.stringify(pressureScriptPath)} ${paneIndex} ${pressureOutputChars} ${pressureStartDelayMs}\r` ) ) ) } async function switchToTypingWorkspace(orcaPage: Page, worktreeId: string): Promise { await switchToWorktree(orcaPage, worktreeId) await expect.poll(() => getActiveWorktreeId(orcaPage), { timeout: 10_000 }).toBe(worktreeId) await ensureTerminalVisible(orcaPage) await waitForActiveTerminalManager(orcaPage, 30_000) } async function cleanupHiddenPressureScenario< TMeasurement, TDebug, TScheduler, TMainPressure, TAckGate >({ deps, firstWorktreeId, hiddenPanes, orcaPage, pressureScriptPath, secondWorktreeId, typingScriptPath }: { deps: HiddenPressureDeps firstWorktreeId: string hiddenPanes: HiddenPressurePane[] orcaPage: Page pressureScriptPath: string secondWorktreeId: string typingScriptPath: string }): Promise { await deps.releaseTerminalAckGate(orcaPage) await switchToWorktree(orcaPage, firstWorktreeId).catch(() => undefined) await waitForActivePanePtyId(orcaPage) .then((ptyId) => sendToTerminal(orcaPage, ptyId, '\x03')) .catch(() => undefined) await switchToWorktree(orcaPage, secondWorktreeId).catch(() => undefined) await Promise.all( hiddenPanes.map((pane) => sendToTerminal(orcaPage, pane.ptyId, '\x03').catch(() => undefined)) ) rmSync(typingScriptPath, { force: true }) rmSync(pressureScriptPath, { force: true }) }