agentjido / agentjido/term_ui

Add a web backend and optional Ghostty terminal sessions

Open
#70 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Elixir
Stars
205
Forks
16
Avg merge
27m
Merged PRs (30d)
5

Description

Summary

Add a browser delivery path for TermUI applications, and evaluate an optional Ghostty-powered terminal session that can appear inside a TermUI frame.

These are two related but separate capabilities:

  1. A TermUI.WebBackend displays normal TermUI.Frame output in a browser and converts browser input into TermUI.Event values.
  2. An optional Ghostty integration runs a real shell or terminal program and converts its emulated screen into frame content.

Ghostty must not become the web backend itself. It must remain an optional source of terminal-session content.

Motivation

TermUI v2 already has a backend contract for local TTY, raw terminal, SSH, and deterministic test delivery. A browser backend would let the same Elm application, widgets, layout, frame model, and event model run in a web browser.

Some applications, including Jido Console, can also benefit from an embedded terminal pane. This pane must support real terminal programs such as shells, IEx, vim, and top. The ghostty Hex package provides a BEAM wrapper for libghostty-vt, a PTY, terminal emulation, scrollback, resize reflow, cursor state, key encoding, and mouse encoding.

Proposed architecture

TermUI application
        |
        v
   TermUI.Frame
        |
        v
TermUI.WebBackend
        |
 WebSocket or LiveView
        |
        v
 Browser renderer

An optional embedded terminal follows this path:

Shell / IEx / terminal program
              |
         Ghostty.PTY
              |
         VT output bytes
              |
       Ghostty.Terminal
              |
      render state / cells
              |
       TermUI.Frame region
              |
       TermUI.WebBackend

The normal TermUI frame remains the only browser rendering contract.

Design constraints

  • Keep the existing TermUI.Backend contract focused on the host display and input transport.
  • Do not replace TermUI.Backend.Raw, TermUI.Backend.TTY, or the current escape parser with Ghostty.
  • Keep Ghostty optional. TermUI must continue to work without native Ghostty binaries.
  • Keep the widget model pure. A parent application or session owner process must own Ghostty.Terminal and Ghostty.PTY processes.
  • Preserve the deterministic backend and current frame-based test path.
  • Do not require Ghostty for normal TermUI applications in a browser.
  • Provide a clear unsupported-platform result. Ghostty currently has precompiled binaries for Linux x86-64, Linux ARM64, and macOS ARM64, but not Windows or Intel macOS.
  • Avoid two permanent browser renderers. Ghostty's LiveView component can be reference code or a prototype, but normal and embedded-terminal content should converge on the TermUI frame renderer.

Proposed phases

Phase 1: Browser backend prototype
  • Define a wire representation for full frames, cell or row changes, cursor state, and terminal dimensions.
  • Send browser keyboard, mouse, paste, focus, and resize input as normalized TermUI.Event values.
  • Implement a simple DOM renderer first.
  • Support connection setup, cleanup, and resize.
  • Add deterministic protocol tests that do not require a browser.
Phase 2: Browser integration tests
  • Run a small TermUI application in a real browser.
  • Verify keyboard input, mouse input, paste, focus, resize, Unicode, wide cells, colors, cursor state, and shutdown.
  • Measure full-frame and incremental-frame performance.
  • Decide whether DOM rendering is sufficient or Canvas is necessary.
Phase 3: Optional Ghostty terminal session
  • Add a session owner that manages one Ghostty.Terminal and one Ghostty.PTY.
  • Route PTY output into the terminal emulator.
  • Route terminal query responses back to the PTY.
  • Convert Ghostty cells, styles, cursor state, and wide-cell tails into a TermUI.Frame region.
  • Convert applicable TermUI.Event values into Ghostty key, mouse, and focus input.
  • Resize the PTY and emulator together.
  • Support scrollback and terminal-session shutdown.
  • Ensure that multiple sessions have unambiguous message ownership.

Acceptance criteria

  • A TermUI v2 application can render in a supported web browser without changes to its Elm application callbacks.
  • The browser path uses TermUI.Frame as its rendering contract.
  • Browser input is normalized to existing TermUI.Event values.
  • Resize, Unicode, wide cells, colors, attributes, and cursor state work.
  • The backend has automated protocol tests and at least one browser integration test.
  • Ghostty is an optional dependency or a separate integration package.
  • A Ghostty session can run a shell and at least one alternate-screen application.
  • A Ghostty session renders through the same TermUI frame path as other widgets.
  • Local TTY, raw, SSH, and deterministic backends continue to work without Ghostty.
  • Unsupported Ghostty platforms fail clearly without affecting normal TermUI use.

Open decisions

  • Use Phoenix LiveView, Phoenix Channels, or a transport-neutral WebSocket protocol for the first backend.
  • Put the Ghostty adapter in TermUI as an optional integration or publish a separate term_ui_ghostty package.
  • Send row changes, cell changes, or encoded frame operations over the wire.
  • Use a DOM renderer or Canvas after the prototype measurements.

Reference

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reading the existing TermUI.Backend contract, Raw and TTY backends, current escape parser, deterministic backend, Frame model, and Event model. Define the first browser transport and frame protocol before evaluating the Ghostty.PTY and Ghostty.Terminal references. Done requires a tested browser backend, browser integration coverage, and an optional Ghostty session that preserves existing backends.

Written by the indexing model from the issue text.

Assessment

Tech stack
elixir
Domain
backend, testing-qa, web-dev
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Needs clarification
Newbie friendliness
18/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.