tuispec-0.1.0.0: SKILL.md
# REPL Workflow Skill for `tuispec`
This skill explains how to use `tuispec` as a REPL-like driver for TUIs:
1. launch a TUI
2. send commands/keys
3. periodically dump current view snapshots
4. render those snapshots as text/PNG
## What was added for REPL ergonomics
Use these APIs from `TuiSpec`:
- `withTuiSession`:
creates an ad-hoc PTY session outside `tasty`
- `sendLine`:
sends text + `Enter`
- `currentView`:
returns current visible viewport text
- `dumpView`:
writes the current screen to `<name>.ansi.txt` + `<name>.meta.json`
Relevant implementation:
- `src/TuiSpec/Runner.hs`
- `src/TuiSpec/Render.hs`
## Minimal REPL script
Create a Haskell program (for example `scratch/ReplDemo.hs`):
```haskell
{-# LANGUAGE OverloadedStrings #-}
module Main where
import Control.Concurrent (threadDelay)
import TuiSpec
main :: IO ()
main =
withTuiSession
defaultRunOptions
{ artifactsDir = "artifacts/repl"
, terminalCols = 134
, terminalRows = 40
}
"demo-session"
$ \tui -> do
launch tui (App "sh" ["-lc", "tui-demo"])
_ <- dumpView tui "00-initial"
press tui (CharKey 'b')
_ <- dumpView tui "01-board"
sendLine tui "/help"
_ <- dumpView tui "02-help"
view <- currentView tui
putStrLn "Current viewport:"
putStrLn (take 1000 (show view))
-- optional short settle pause between interactions
threadDelay (150 * 1000)
press tui (CharKey 'q')
```
Run it:
```bash
cabal run runghc -- -isrc scratch/ReplDemo.hs
```
## Where dumps go
For session name `demo-session` and `artifactsDir = artifacts/repl`:
- `artifacts/repl/sessions/demo-session/snapshots/00-initial.ansi.txt`
- `artifacts/repl/sessions/demo-session/snapshots/00-initial.meta.json`
- `artifacts/repl/sessions/demo-session/snapshots/01-board.ansi.txt`
- `...`
## Render dumps while iterating
Render to PNG:
```bash
cabal run tuispec -- render artifacts/repl/sessions/demo-session/snapshots/01-board.ansi.txt
```
Render to visible plain text:
```bash
cabal run tuispec -- render-text artifacts/repl/sessions/demo-session/snapshots/01-board.ansi.txt
```
Both commands auto-read rows/cols from `.meta.json`.
## Practical loop
1. run your REPL script
2. inspect generated `.txt`/`.png`
3. tweak interactions
4. run again
`withTuiSession` resets the session output directory each run, keeping artifact output simple and deterministic.
## JSONRPC server workflow
You can also orchestrate a TUI from an external client using:
```bash
cabal run tuispec -- server --artifact-dir artifacts/server
```
### Request format
- Send one JSON-RPC request per line on stdin.
- Read one JSON-RPC response per line on stdout.
### Shutdown semantics
- `server.shutdown` is a hard shutdown:
- kills active TUI child process group with `SIGKILL`
- exits server immediately (no graceful wait)
- On `SIGHUP`, the server does the same hard shutdown behavior:
- `SIGKILL` to active child process group
- immediate process exit
### Example session
Start server:
```bash
cabal run tuispec -- server --artifact-dir artifacts/server
```
Then send requests like:
```json
{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"name":"demo"}}
{"jsonrpc":"2.0","id":2,"method":"launch","params":{"command":"sh","args":["-lc","tui-demo"]}}
{"jsonrpc":"2.0","id":3,"method":"sendKey","params":{"key":"ArrowDown"}}
{"jsonrpc":"2.0","id":4,"method":"sendKey","params":{"key":"Enter"}}
{"jsonrpc":"2.0","id":5,"method":"dumpView","params":{"name":"after-enter"}}
{"jsonrpc":"2.0","id":6,"method":"currentView","params":null}
{"jsonrpc":"2.0","id":7,"method":"server.shutdown","params":null}
```
### Supported key strings for `sendKey`
- `Enter`, `Esc`, `Tab`, `Backspace`
- `ArrowUp`, `ArrowDown`, `ArrowLeft`, `ArrowRight`
- `F1`..`F12`
- `Ctrl+X`, `Alt+X`, `Shift+X`
- single character like `"a"`
### Dump locations
For `initialize` name `demo`:
- `artifacts/server/sessions/demo/snapshots/<name>.ansi.txt`
- `artifacts/server/sessions/demo/snapshots/<name>.meta.json`
### Rendering dumped views
```bash
cabal run tuispec -- render artifacts/server/sessions/demo/snapshots/after-enter.ansi.txt
cabal run tuispec -- render-text artifacts/server/sessions/demo/snapshots/after-enter.ansi.txt
```