Skip to Content
InternalsTerminal Session and Viewport

Terminal Session and Viewport

Ansiq’s surface layer does not own business state, and it does not own widget semantics.

It owns something else:

the transformation of a plain terminal session into a managed runtime viewport.

Without that layer, the runtime quickly runs into two problems:

  • it does not know which region of terminal space it truly controls
  • it cannot coordinate committed history, live viewport space, and exit cursor placement in a predictable way

What the surface layer is responsible for

Today the surface layer manages:

  • entering and leaving raw mode
  • viewport reservation
  • reanchor and resize plans
  • safe exit row handling

This may look like low-level terminal plumbing, but in practice it is a major architectural boundary.

Why a viewport is not just “some rect to draw into”

In a GUI, an app usually owns a full window by default.

In a terminal, that is not true:

  • the app may be launched inline from an existing shell session
  • the user may want earlier terminal output to remain visible above it
  • when the app exits, the shell prompt should land in a sensible place

So Ansiq cannot assume it naturally owns the whole screen. It needs explicit viewport semantics:

  • where the live area begins
  • how tall it is
  • how it changes under resize
  • how it is reanchored after history commits
How the surface layer establishes a managed viewport
1enter the terminal session
2resolve the initial viewport from ViewportPolicy
3draw the live shell inside that viewport
4apply resize or reanchor plans on resize/history commit
5restore terminal state and cursor placement on exit

Why session semantics belong in surface

It is tempting to say:

the app understands its layout best, so maybe the app should also control viewport and history behavior

But that quickly leads to fragmentation:

  • each app reinvents terminal session handling
  • runtime no longer has a stable contract for patching or exit behavior
  • history and live viewport semantics drift across examples and apps

Ansiq instead uses a stronger split:

  • the app decides what its shell looks like
  • the surface decides how that shell is hosted inside a real terminal session

Current viewport policies

Today the common policies are:

  • PreserveVisible
  • ReservePreferred
  • ReserveFitContent

These are not just cosmetic options. They answer different product questions.

PreserveVisible

Focuses on:

  • preserving existing terminal output as much as possible

Useful for:

  • small tools
  • transient UIs
  • interfaces that do not want a long-lived reserved workspace

ReservePreferred

Focuses on:

  • giving the live viewport a preferred working height
  • but returning to that preferred height after history commit or reanchor

This fits:

  • conversation UIs
  • shells with sticky footers or composers

ReserveFitContent

Focuses on:

  • letting viewport height follow content within a constrained range

Useful for:

  • examples
  • lighter embedded UIs

Why resize and reanchor are expressed as plans

Ansiq has been moving more of this behavior into pure planning helpers such as:

  • resize_viewport_plan
  • reanchor_viewport_plan

This matters because:

  • the behavior becomes testable without a real terminal
  • terminal semantics can be computed before ANSI commands are emitted
  • the system becomes easier to reason about under edge cases

This is part of a broader hardening direction in Ansiq:

terminal behavior that can be expressed as pure computation should be separated from the imperative act of writing to the terminal

Why history commits should not permanently preserve a temporarily expanded viewport

One important recent semantic is this:

  • the live viewport may temporarily grow to fit active content
  • but history commit or reanchor should not automatically treat that expanded height as the new steady state

Otherwise a typical failure mode appears:

  • the first conversation turn looks fine
  • the second and third turns make the viewport taller and taller
  • eventually the app appears to occupy the entire terminal as a live workspace

That is why ReservePreferred now returns to its preferred height after commit/reanchor.

Why exit behavior belongs here too

Users often judge the quality of a terminal framework by moments such as:

  • does launch disturb my shell unexpectedly?
  • does resize behave predictably?
  • does the prompt return to a sane place on exit?

That means exit_row, clamping, and raw mode restoration are not minor implementation details. They are product-facing behavior, and they belong in the surface layer.

The conclusion of this page

Terminal session and viewport behavior is not a side effect of runtime, and it is not an app-shell detail.

It is a distinct system boundary in Ansiq:

  • runtime owns updates and patching
  • the app owns scenario structure
  • surface owns the safe, predictable hosting of that structure inside a real terminal session

This layer must remain terminal-native. It should not absorb application shell semantics, but it also cannot collapse into a thin wrapper over a few ANSI commands.

Last updated on