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 rec |
asciinema play |
vhs demo.tape |
vhs serve |
script session.log |
scriptreplay session.log |
| Input capture | Output broadcast |
| Black hole | White 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 recordervhs- Charmbracelet tape automationttyd- Web terminal streamingtmux- 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.