packages feed

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
```