DevelopmentAll versions
On this page

KetraTerm Terminal Pipeline Architecture

KetraTerm separates terminal parsing, state mutation, input encoding, transport, and presentation into JVM modules. TerminalSession coordinates the running pipeline; applications choose the transport, host services, optional shell producer, and presentation.

This guide describes the module boundaries and runtime ownership. Detailed terminal behavior and deferred scope belong to the feature map and gap map.

Data flow

flowchart LR
    connector[TerminalConnector] -->|ordered output bytes| parser[Parser]
    parser -->|semantic commands| host[HostCommandAdapter]
    host -->|mutations| core[Core grid]
    core -->|Render API reads| publication[Session frame publication]
    publication -->|leased copied frame| cache[Renderer-owned cache]
    cache -->|prepared cells| view[Swing painting]

The session serializes inbound parser/core work. The parser recognizes byte sequences and assembles text; the host adapter maps commands; core owns cell width, cursor movement, margins, buffer storage, and reflow. Transport implementations supply ordered bytes without interpreting terminal protocols.

Outbound intent enters the session before encoding:

flowchart LR
    intent[Key / mouse / paste intent] --> admission[Session admission]
    admission --> encoder[Input encoder]
    encoder --> queue[Ordered outbound writer]
    replies[Permitted terminal replies] --> queue
    queue --> connector[TerminalConnector.write]

The input encoder reads stable mode state and produces host-bound bytes. The session admits input and terminal replies to the same ordered writer. submitInput and submitBytes report admission, not completed transport output. Transport failures are reflected in session lifecycle state.

Modules

Published libraries

Module Responsibility
protocol Dependency-free protocol constants and shared vocabulary.
parser Streaming bytes, UTF-8, escape sequences, charsets, and grapheme assembly.
core Headless grid, scrollback, modes, width policy, and resize/reflow.
host Parser-command mapping, host effects, and hyperlink registration.
input Keyboard, paste, focus, mouse, and host-output encoding.
render-api Dependency-free primitive rendering contracts and attributes.
render-cache Copied render storage and leased frame publication.
transport-api Ordered raw-byte connector and lifecycle contracts.
session Runtime synchronization, outbound ordering, lifecycle, and neutral shell contracts.
shell-integration Optional OSC metadata interpretation and bounded command extraction.
pty Local process/connector lifecycle and convenience session assembly.
ui-swing Reusable Java2D rendering and Swing interaction.
completion Completion context, source evaluation, ranking, and bounded learning.
completion-host Host-neutral directory/path access for completion.
ui-swing-host Host actions, popup presentation, and completion adapters.

ketraterm-headless exposes session dependencies; ketraterm-swing exposes Swing dependencies. Both publish dependency metadata without adding runtime code. ketraterm-bom supplies version constraints for the published dependency set. See library compatibility for the publication boundary.

Products and development modules

Module Responsibility
completion-persistence Product-owned sanitized, versioned learning persistence.
workspace Profiles, local sessions, tabs, and workspace lifecycle.
app Standalone desktop product, configuration, and window wiring.
intellij-plugin IntelliJ-specific product integration in a separate build.
testkit Reusable connector fakes, test fixtures, and verification campaigns.
benchmarks JMH measurements for terminal hot paths.

Concurrency

Core, parser, and standalone encoders require caller serialization. A session provides the synchronization boundary for its assembled pipeline:

  • Parser execution, core mutation, resizing, and borrowed render reads are serialized so readers cannot observe partially mutated state.
  • Outbound admission protects mode/policy capture, encoder scratch, and the bounded writer queue. One I/O worker writes admitted input and replies in order. Native writes and bulk encoding do not hold the admission monitor.
  • A conflated render worker extracts copied frames under the mutation boundary and publishes them through TerminalRenderPublisher. Generation notifications signal available work; they are not a log of every intermediate frame.
  • Swing owns its presentation state on the EDT. It consumes published frames into reusable local storage, prepares rendering data, and paints that storage.

Direct render frames and their backing arrays are borrowed. Keep them inside their documented callback or lease; copy data that must outlive that scope. No UI code should retain live core lines or mutate session-owned core state outside the session boundary.

See session concurrency, render-frame lifecycle, and publication buffering.

Storage and rendering

Cells use parallel primitive arrays and a shared cluster arena. Scrollback rows are allocated incrementally and recycled at capacity. Core owns width, wrapping, and resize/reflow; renderers consume its public frame projection.

The Swing renderer reuses copied cell planes and layout caches. Font selection and Java2D painting stay in the UI layer. See the storage layout and Swing rendering guide.

Lifecycle and Host Ownership

The caller owns a created session and must close it even if startup fails or it is never started. Register host state before starting output delivery when callbacks can observe that state. Disposing a Swing view releases the view's resources and binding; it does not close the shared session.

Hosts own clipboard access, terminal-initiated action policy, settings and theme resolution, completion I/O, and shell-hook installation. Session shell contracts allow host-owned metadata producers; the optional OSC producer is one implementation. PTY assembly does not automatically install a shell integration producer.

Testing

Tests assert terminal state and exact outbound bytes. Controlled schedulers and explicit handshakes cover concurrency and lifecycle; connector fakes exercise complete sessions without a local shell. Native PTY tests and external differential campaigns have their own opt-in requirements.

See testkit, conformance testing, and Contributing for the relevant commands and validation boundaries.