KetraTerm
API · DevelopmentAll versions

TerminalSession

Runtime terminal session that binds core, parser, input encoding, and a transport connector.

The connector owns transport threads. This session owns parser/core mutation serialization and all host-bound write ordering.

Ordinary input and core replies share a bounded 8 MiB byte queue. Paste and text replacement retain their source and admission-time modes/policy for background encoding, bounded to 16 operations and 16 * 1024 * 1024 combined UTF-16/deletion units, including active work. One writer preserves order. submitInput and submitBytes report admission, not transport completion; the encoder interface methods discard that result. Queue exhaustion or outbound worker failure closes the session with failure; closing a session discards pending output. Custom encoders bind to session-owned mode sources and output sinks through TerminalInputEncoderFactory. Unexpected cancellation in connector writes or bulk encoding also closes the session without retrying potentially partial output, retaining the cause. Cancellation during an already claimed shutdown preserves the first termination event.

Closure freezes terminal state after already-admitted work and parser EOF finish. Late input, policy/presentation setters and render requests are ignored; resize throws IllegalStateException. Retained state remains readable, but no later presentation mutation or publication is supported. Observe state reaching TerminalSessionState.Closed to know final cleanup/publication has completed.

A session publishes one active render viewport. Independently scrolling views of the same session are unsupported: each new viewport request replaces the previous request. Separate sessions are separate terminal pipelines.

Shell metadata comes exclusively from the integration selected at construction. With no integration, shell features are unavailable. Hosts can supply their own model using TerminalShellIntegrationFactory.host, or select an optional protocol producer. Session closure stops observations without cancelling host-owned producers.

Successful construction transfers exclusive access to the mutable terminal, parser, response reader, connector, and render publisher to this session. Collaborators must describe the same terminal pipeline and must not be shared with another active session. Configure core state before construction; while the session is open, use its synchronized settings, input, and frame APIs. Direct mutation or frame reads through retained core references bypass that serialization.

Startup, geometry, host-policy/presentation setters, clearing, and close are synchronous operations for non-UI threads. They can wait for an active image decode. Use withMutationAdmission to validate captured UI ownership after that wait, and requestClose for nonblocking disposal. Frame reads and ordinary input admission remain available while decoding.

Constructors

Link copied to clipboard
constructor(terminal: TerminalBuffer, renderPublisher: TerminalRenderPublisher, renderReader: TerminalRenderFrameReader, responseReader: TerminalHostResponseReader, connector: TerminalConnector, parser: TerminalOutputParser, inputEncoderFactory: TerminalInputEncoderFactory? = null, hyperlinkResolver: TerminalHyperlinkResolver = TerminalHyperlinkResolver.NONE, hostCommandAdapter: HostCommandAdapter? = null, inputPolicy: TerminalInputPolicy = TerminalInputPolicy(), workerDispatcher: CoroutineDispatcher = Dispatchers.Default, ioDispatcher: CoroutineDispatcher = Dispatchers.IO, shellIntegration: TerminalShellIntegrationFactory? = null)

Assembles a session around a caller-supplied parser and response reader. The caller owns the parser's host-event wiring, including accepted shell events if its selected producer interprets protocols. Use create for standard parser assembly and automatic dispatch to that producer. Host-owned models supplied through TerminalShellIntegrationFactory.host need no parser callbacks.

constructor(terminal: TerminalBuffer, renderPublisher: TerminalRenderPublisher, renderReader: TerminalRenderFrameReader, responseReader: TerminalHostResponseReader, connector: TerminalConnector, parser: TerminalOutputParser, inputEncoderFactory: TerminalInputEncoderFactory? = null, hyperlinkResolver: TerminalHyperlinkResolver = TerminalHyperlinkResolver.NONE, hostCommandAdapter: HostCommandAdapter? = null, inputPolicy: TerminalInputPolicy = TerminalInputPolicy(), workerDispatcher: CoroutineDispatcher = Dispatchers.Default, ioDispatcher: CoroutineDispatcher = Dispatchers.IO, shellIntegration: TerminalShellIntegrationFactory? = null, cleanupDispatcher: CoroutineDispatcher)

Assembles a session around a caller-supplied parser and response reader. The caller owns the parser's host-event wiring, including accepted shell events if its selected producer interprets protocols. Use create for standard parser assembly and automatic dispatch to that producer. Host-owned models supplied through TerminalShellIntegrationFactory.host need no parser callbacks.

Types

Link copied to clipboard
object Companion

Properties

Link copied to clipboard

Revision of the active shell command line, tracked only while collected.

Link copied to clipboard

Remote process exit code after onClosed receives one.

Link copied to clipboard

The first startup, transport, outbound worker, or cleanup failure. An initiating failure is available as soon as shutdown begins; cleanup failures are retained before state reaches TerminalSessionState.Closed. Null means no known failure.

Link copied to clipboard
val foregroundProcessName: StateFlow<String?>

Best-effort foreground executable name, or null when unavailable.

Link copied to clipboard

Returns true after either local shutdown, remote closure, or transport failure has made the session unable to accept more input. This becomes true when shutdown starts; state reaches Closed after cleanup.

Link copied to clipboard

Detached durable mode state, sampled under session serialization and readable after closure.

Link copied to clipboard

Current immutable effective palette, read under the session mutation lock.

Link copied to clipboard

Current OSC 22 pointer override, or null for host defaults. Safe from any thread; closed sessions and custom pipelines without a HostCommandAdapter expose no override. Updated presentation is observed with render publication, including output that changes only host metadata.

Link copied to clipboard

Immutable startup expectation supplied by the selected shell producer. True permits reserving prompt presentation space before metadata arrives; false means no expectation was supplied, including sessions without a producer. This does not report current prompt readiness or identify a running shell.

Link copied to clipboard
val renderGeneration: StateFlow<Long>

Latest successfully published render generation, or -1 before the first frame is available.

Link copied to clipboard

Bounded projection supplied by the selected shell producer, or an empty model when absent.

Link copied to clipboard

Retained startup submission outcome, or null when no command was configured.

Link copied to clipboard
val state: StateFlow<TerminalSessionState>

Lifecycle state retained for current and future collectors. Closed is published after cleanup and the final frame publication attempt, so a successful final frame is available to both early and late observers.

Functions

Link copied to clipboard

Returns the active shell command-line snapshot, or null after closure or when no trustworthy editing context is available.

Link copied to clipboard

Captures a conditional-edit context from the selected authoritative shell producer. Returns null before start, during shutdown or output processing, while the writer has pending/active work, when editing is unavailable, or for a producer without atomic revision support (including the legacy StateFlow-only host factory).

Link copied to clipboard

Clears the active screen and its history without sending input to the connector.

Link copied to clipboard
open override fun close()

Stops accepting input, releases the connector, flushes parser EOF, and synchronously publishes the last requested viewport, including synchronized output. Publication waits for active frame-copy callbacks and available render buffers; do not call from a render-reader or leased-cache callback.

Link copied to clipboard

Returns the latest recorded current-working-directory URI.

Link copied to clipboard
open override fun encodeFocus(event: TerminalFocusEvent)
Link copied to clipboard
open override fun encodeKey(event: TerminalKeyEvent)
Link copied to clipboard
open override fun encodeMouse(event: TerminalMouseEvent)
Link copied to clipboard
open override fun encodePaste(event: TerminalPasteEvent)
Link copied to clipboard
Link copied to clipboard
open override fun getInputModeBits(): Long

Returns one coherent primitive snapshot of input modes under session serialization, without allocation. The retained modes remain readable after closure through TerminalInputState's decoding helpers.

Link copied to clipboard
fun hyperlinkUri(hyperlinkId: Int): String?

Resolves a primitive render-frame hyperlink id to a target URI.

Link copied to clipboard
open override fun onBytes(bytes: ByteArray, offset: Int, length: Int)

Consumes host bytes synchronously, mutating parser/core before returning. Output callbacks must not reenter this operation. Parser or callback failures stop the input call and propagate unchanged. The connector must stop delivery and report the failure through onError.

Link copied to clipboard
open override fun onClosed(exitCode: Int?)

Records remote closure, releases the connector, and finalizes parser/render state exactly once. The connector must deliver its final bytes first.

Link copied to clipboard
open override fun onError(error: Throwable)

Records transport failure and treats it as remote closure without a process exit code.

Link copied to clipboard
inline fun <T> readPublishedFrame(block: (TerminalRenderCache) -> T): T?

Borrows the latest copied render cache, or returns null before first publication.

Link copied to clipboard
open override fun readRenderFrame(consumer: TerminalRenderFrameConsumer)

Reads a short-lived render frame while holding the terminal mutation lock.

open override fun readRenderFrame(scrollbackOffset: Int, consumer: TerminalRenderFrameConsumer)

Reads a render frame with a specified scrollback offset.

open override fun readRenderFrame(scrollbackOffset: Int, viewportRows: Int, consumer: TerminalRenderFrameConsumer)

Reads a render frame with a specified scrollback offset and viewport rows limit.

Link copied to clipboard
open override fun readRenderFrameForAbsoluteRange(startAbsoluteRow: Long, endAbsoluteRow: Long, consumer: TerminalRenderFrameConsumer)

Reads an absolute terminal row range while holding the mutation lock.

Link copied to clipboard

Claims local shutdown immediately and performs cleanup on the cleanup dispatcher. Suitable for UI disposal: it never waits for graphics mutation admission. Cleanup has its own lifetime and survives cancellation of session workers. Observe state for completed cleanup and any retained cleanup failure. The configured cleanup dispatcher must dispatch blocking work off UI threads independently of potentially blocked connector writes. Repeated requests are harmless and preserve the first close event.

Link copied to clipboard
fun requestRender(scrollbackOffset: Int)

Requests a render-cache publication for a caller-owned scrollback viewport.

fun requestRender(scrollbackOffset: Int, viewportRows: Int)

Requests a render-cache publication with optional render-only viewport overscan rows.

Link copied to clipboard
fun resize(columns: Int, rows: Int, oldScrollbackOffset: Int = 0): Pair<Int, Int>

Resizes core and the active connector, then requests a new published frame.

Link copied to clipboard
fun resizeViewport(columns: Int, rows: Int, oldScrollbackOffset: Int = 0): TerminalViewportResizeResult

Resizes the terminal and connector and captures the viewport anchor and history baseline under the same mutation lock. This keeps viewport resizes ordered with application-requested column switches.

Link copied to clipboard

Updates the current and default cursor shape for the session.

Link copied to clipboard

Updates the active host security policy dynamically.

Link copied to clipboard
open override fun setInputPolicy(policy: TerminalInputPolicy)

Updates the active terminal input policy dynamically.

Link copied to clipboard

Updates only the active paste control-character policy.

Link copied to clipboard

Sets the theme-configured color palette for the session.

Link copied to clipboard

Applies the host's East Asian Ambiguous width policy for future writes.

Link copied to clipboard
fun setWindowMinimized(minimized: Boolean)

Records host window minimization for terminal window reports; ignored after closure. Synchronous mutation admission requires a non-UI caller.

Link copied to clipboard
fun start(columns: Int, rows: Int)

Starts the connector after resizing core and transport to columns x rows. This synchronous call permits one attempt. Concurrent or reentrant attempts throw IllegalStateException, as does starting a closed session.

Link copied to clipboard
fun submitBytes(bytes: ByteArray, offset: Int = 0, length: Int = bytes.size - offset): TerminalInputAdmission

Copies exactly length bytes starting at offset into the ordered writer. The caller must keep the range stable until return and may then reuse it. Bytes are neither decoded nor sanitized, encoded, or framed as paste. Use submitInput for keyboard, mouse, IME, or paste semantics.

Link copied to clipboard

Admits one immutable semantic event with explicit lifecycle/capacity feedback. Keys, focus and mouse encode synchronously into the byte queue. Paste and replacement retain source text and admission-time modes/policy for the background encoder within the shared bulk budget (16 operations and 16,777,216 UTF-16/deletion units, including active work).

Admits events as one indivisible outbound operation, copying the list before return. Keep the list stable during the call; event values are immutable. All events use one admission-time mode/policy snapshot on the background encoder. Later keys, bytes and replies cannot interleave even when this operation spans native writes. Closure/failure may still interrupt its prefix.

Atomically validates expected and admits the complete semantic events. Checks session identity, cancellation, producer revision/snapshot and all intervening input/output/resize under mutation, producer and admission serialization. Rejection sends no prefix and does not consume capacity. Success uses the same bounds, mode/policy capture and writer as submitInput.

Link copied to clipboard
fun tryResizeViewport(columns: Int, rows: Int, oldScrollbackOffset: Int = 0): TerminalViewportResizeResult?

Attempts the same terminal reflow as resizeViewport.

fun tryResizeViewport(columns: Int, rows: Int, oldScrollbackOffset: Int, pixelWidth: Int, pixelHeight: Int): TerminalViewportResizeResult?

Atomically resizes the grid and records its text-area pixel dimensions.

Link copied to clipboard
fun tryUpdateViewportPixels(columns: Int, rows: Int, pixelWidth: Int, pixelHeight: Int): Boolean

Updates text-area pixels only if the open session still has the expected grid.

Link copied to clipboard
fun <T> withMutationAdmission(isCurrent: () -> Boolean, action: () -> T): T?

Runs captured host work only if its owner is still current at mutation admission. This synchronous boundary can wait for graphics decoding; call it off UI threads. Nested session setters share the admission. Frame reads and input do not wait for this gate. The callbacks must be prompt, must not access UI state, and must never wait for UI work or close the session.