Files
orca/src/main/runtime/rpc/terminal-source-range-validation.ts
T
JinjingandOrcaWin 5f7807497e feat(ssh): bound relay PTY output end to end (#11005)
* docs: design SSH relay PTY backpressure

* fix(ssh): bound relay frame decoding

* fix(relay): bound PTY output publication

* fix(ssh): bound PTY model admission

* fix(ssh): settle closed model admissions

* feat(ssh): negotiate bounded PTY consumer sessions

* fix(ssh): fence exit on renderer settlement

* feat(ssh): track PTY source credit end to end

* fix(ssh): recover bounded PTY output across reconnect

* feat(ssh): complete relay PTY output backpressure

* fix(ssh): close final PTY source credit races

* docs(ssh): record final backpressure validation

* feat(ssh): complete relay PTY source-credit lifecycle

* test(ssh): complete provider notification fixture

* fix(ssh): preserve terminal source credit across rotation

* fix(ssh): fail closed on recovery cancellation

* fix(ssh): prioritize mux control writes after drain

* fix(ssh): retire canceled relay restore deliveries

* fix(ssh): order exit cancellation cleanup

* fix(ssh): gate provisional source activation

* test(ssh): register mux drain-priority coverage

* fix(ssh): type stale owner recovery mismatches

* fix(ssh): close projection replacement races

* fix(relay): contain streaming edge failures

* fix(ssh): secure relay endpoint credentials

* docs(ssh): reconcile final backpressure lifecycle

* fix(ssh): bound main IPC output lifecycle

* fix(ssh): close recovery ownership gaps

* docs(ssh): record exact artifact validation

* fix(ssh): reject reclaimed snapshot replacements

* fix(ssh): fence model admission across reconnect

* fix(ssh): contain migration failure per PTY

* docs(ssh): record final exact-head validation

* test(ssh): align deploy fixtures with credential publication

* feat(ssh): add per-target bounded output setting

* fix(ssh): close source recovery review gaps

* fix(ssh): latch source credit environment override

* feat(ssh): make PTY source credit the default

* docs(ssh): record always-on relay validation

* docs(ssh): bind validation to current main

* test(ssh): grant source credit in IPC fixture

* test(ssh): grant source credit in fake relay

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-07-29 17:03:15 -07:00

100 lines
2.7 KiB
TypeScript

import {
assertTerminalOutputSourceRange,
sameTerminalOutputSourceIdentity,
type TerminalOutputSourceRange
} from '../../../shared/terminal-output-source-range'
export type TerminalSourceRangeFrame = Readonly<{
encodedStartByte: number
encodedEndByte: number
displayLength: number
outputSeq?: number
sourceRanges: readonly TerminalOutputSourceRange[]
}>
export function freezeTerminalOutputSourceRanges(
ranges: readonly TerminalOutputSourceRange[]
): readonly TerminalOutputSourceRange[] {
return Object.freeze(
ranges.map((range) =>
Object.freeze({
...range,
transform: Object.freeze({ ...range.transform })
})
)
)
}
export function validateTerminalSourceRangeFrame(
displayLength: number,
ranges: readonly TerminalOutputSourceRange[]
): boolean {
if (!Number.isSafeInteger(displayLength) || displayLength < 0) {
return false
}
if (ranges.length === 0) {
return true
}
try {
for (const range of ranges) {
assertTerminalOutputSourceRange(range)
}
} catch {
return false
}
const first = ranges[0]!
let previous = first
for (const range of ranges.slice(1)) {
if (
!sameTerminalOutputSourceIdentity(first, range) ||
range.sourceStartSu !== previous.sourceEndSu ||
range.displayStart !== previous.displayEnd
) {
return false
}
previous = range
}
return previous.displayEnd - first.displayStart === displayLength
}
export function replaceTerminalSourceRangeFrames(
frames: readonly TerminalSourceRangeFrame[],
snapshotSeq: number
): Readonly<{
frames: TerminalSourceRangeFrame[]
mappingMode: 'mapped' | null
boundRange: TerminalOutputSourceRange | null
mappedSourceEndSu: number | null
mappedDisplayEnd: number | null
}> {
const replaced = frames.map((frame) =>
typeof frame.outputSeq === 'number' && frame.outputSeq <= snapshotSeq
? Object.freeze({ ...frame, sourceRanges: Object.freeze([]) })
: frame
)
const remainingRanges = replaced.flatMap((frame) => frame.sourceRanges)
const last = remainingRanges.at(-1)
return Object.freeze({
frames: replaced,
mappingMode: remainingRanges.length > 0 ? 'mapped' : null,
boundRange: last ?? null,
mappedSourceEndSu: last?.sourceEndSu ?? null,
mappedDisplayEnd: last?.displayEnd ?? null
})
}
export function canPlanTerminalSourceRangeReplacement(
frames: readonly TerminalSourceRangeFrame[],
snapshotSeq: number
): boolean {
return (
Number.isSafeInteger(snapshotSeq) &&
snapshotSeq >= 0 &&
frames.every(
(frame) =>
frame.sourceRanges.length === 0 ||
(typeof frame.outputSeq === 'number' && frame.outputSeq <= snapshotSeq)
)
)
}