Skip to content
libghostty-streaming logo

libghostty-vt Streaming Skill ⬜

libghostty-streaming

The **white hole** dual to libghostty-recording. Streams, plays back, and broadcasts terminal sessions. Where recording absorbs (black hole), streaming emits (white hole).

plurigrid/asi0installs67starsDevOps & CI/CD

SKILL.md

Full skill instructions

libghostty-vt Streaming Skill ⬜

Trit: 0 (ERGODIC - Coordinator) GF(3) Triad: asciinema-play (-1) ⊗ libghostty-streaming (0) ⊗ vhs-server (+1) = 0

Overview

The white hole dual to libghostty-recording. Streams, plays back, and broadcasts terminal sessions. Where recording absorbs (black hole), streaming emits (white hole).

Recording (●)  ←→  Streaming (○)
   absorb           emit
   capture          broadcast
   input            output

Playback Methods

1. Asciinema Play (Local Replay)

# Play recording at original speed
asciinema play session.cast

# Speed up 2x
asciinema play -s 2 session.cast

# Idle time limit (skip long pauses)
asciinema play -i 2 session.cast

# Play from URL
asciinema play https://asciinema.org/a/123456

2. asciinema-server (Self-Hosted Streaming)

# Run local asciinema server
docker run -d -p 3000:3000 asciinema/​asciinema-server

# Stream to self-hosted
asciinema rec -t "live session" http://localhost:3000

# Embed in docs
<script src="https://asciinema.org/a/123456.js"></​script>

3. Charmbracelet VHS Server

# Serve GIFs via HTTP
vhs serve --port 8080

# Watch for .tape changes and regenerate
vhs watch demo.tape

# Continuous output to stdout
vhs demo.tape --output -

4. libghostty-vt Stream Hooks

// Stream terminal output via libghostty
const streamer = ghostty_vt.Streamer.init(.{
    .source = .stdin,
    .format = .cast,
    .broadcast = "ws://localhost:9000/​stream",
});

// Emit frames
while (streamer.next()) |frame| {
    try websocket.send(frame.render());
}

5. ttyd (Web Terminal)

# Stream terminal to web browser
ttyd -p 7681 bash

# Read-only broadcast mode
ttyd -R -p 7681 asciinema play session.cast

# With authentication
ttyd -c user:pass -p 7681 bash

Streaming Transforms

Cast → WebSocket

# Stream .cast to WebSocket clients
cat session.cast | websocat ws-listen:127.0.0.1:9000

Cast → NATS

# Broadcast to NATS subject
asciinema play session.cast | nats pub terminal.stream

Cast → SSH (Remote Pair)

# Share session via SSH
asciinema play session.cast | ssh user@remote 'cat'

# Bidirectional with tmux
tmux new-session -d -s shared
tmux send-keys -t shared "asciinema play session.cast" Enter
# Others join: tmux attach -t shared

White Hole Architecture

┌─────────────────────────────────────────────────────────┐
│  WHITE HOLE: Terminal Emission                          │
│                                                         │
│  Sources (●→○)           Sinks (○→)                     │
│  ├── .cast files         ├── Web browsers (ttyd)        │
│  ├── Live terminals      ├── WebSocket clients          │
│  ├── tmux sessions       ├── NATS subscribers           │
│  └── libghostty-vt       ├── SSH remote                 │
│                          └── GIF/​MP4 renders            │
│                                                         │
│  GF(3): input(-1) ⊗ transform(0) ⊗ output(+1) = 0      │
└─────────────────────────────────────────────────────────┘

LLM Training Pipeline

# 1. Record sessions (black hole - absorb)
asciinema rec session.cast

# 2. Transform (ergodic - process)
cat session.cast | jq -r '.[] | select(.[0] == "o") | .[2]'

# 3. Stream to training (white hole - emit)
asciinema play session.cast | tee training-corpus.txt

Justfile Recipes

# Play latest recording
play-latest:
    asciinema play $(ls -t ~/​recordings/​*.cast | head -1)

# Stream to web
stream-web port="7681":
    ttyd -R -p {{port}} asciinema play $(ls -t ~/​recordings/​*.cast | head -1)

# Broadcast to NATS
stream-nats subject="terminal.live":
    asciinema play ~/​recordings/​latest.cast | nats pub {{subject}}

# Convert to GIF
cast-to-gif file:
    agg {{file}} {{file}}.gif

Duality Table

Recording (●)Streaming (○)
asciinema recasciinema play
vhs demo.tapevhs serve
script session.logscriptreplay session.log
Input captureOutput broadcast
Black holeWhite hole
Trit -1 (absorb)Trit +1 (emit)

Integration with Gay.jl

# Color-coded streaming sessions
using Gay
seed!(1069)

session_color = color_at(session_id)
stream_trit = trit_at(session_id)  # -1, 0, or +1

# Route by trit
if stream_trit == -1
    record_session()      # Black hole
elseif stream_trit == 0
    transform_session()   # Ergodic
else
    broadcast_session()   # White hole
end

See Also

  • libghostty-recording - The black hole dual (recording/​capture)
  • asciinema - Terminal session recorder
  • vhs - Charmbracelet tape automation
  • ttyd - Web terminal streaming
  • tmux - Terminal multiplexing for sharing

Autopoietic Marginalia

The interaction IS the skill improving itself.

Every use of this skill is an opportunity for worlding:

  • MEMORY (-1): Record what was learned
  • REMEMBERING (0): Connect patterns to other skills
  • WORLDING (+1): Evolve the skill based on use

Add Interaction Exemplars here as the skill is used.