npx skills add ...
npx skills add factory-ai/factory-plugins --skill tuistory
npx skills add factory-ai/factory-plugins --skill tuistory
Background knowledge for droid-control workflows -- not invoked directly. Tuistory driver mechanics for terminal TUI automation via virtual PTY.
The orchestrator routed you here. Use these mechanics to execute your plan.
Launch a target command in a virtual PTY with Playwright-style CLI for typing, pressing keys, waiting, snapshotting, and recording.
wait / wait-idle against the virtual screen bufferIf you need to prove what Ghostty or Kitty actually emits for a given keystroke, use true-input instead.
Optional: tmux (scrollback flows), asciinema (recordings), agg (.cast to .gif).
Note: --repo-root is mandatory for droid-dev launches โ tctl enforces it.
Always pass --env FORCE_COLOR=3 --env COLORTERM=truecolor when launching. The virtual PTY doesn't advertise color support, so Node.js apps (Ink/chalk) suppress all color escape codes without these.
| Command | Purpose |
|---|---|
launch <cmd> -s <name> --backend tuistory | Start a tuistory session |
type <text> | Send literal text |
press <key> [keys...] | Send key chord (e.g., press shift enter) |
wait <pattern> | Block until text or /regex/ appears |
wait-idle | Block until output stabilizes |
snapshot [--trim] | Print cleaned text (--trim strips trailing blanks) |
close | Tear down session |
Launch options: --cols <n>, --rows <n>, --cwd <path> (child working directory; defaults to --repo-root when set), --env KEY=VALUE, --record <path>.
Pass --record at launch. tctl wraps asciinema rec around the PTY, so recording must be set at launch time (raw tuistory cannot record):
Before/after comparison -- launch two sessions against different worktrees:
Playback: asciinema play /tmp/demo.cast
Only needed when the demo requires terminal-emulator scrollback and the app uses the standard buffer (not alternate screen). True-input sessions rarely need tmux because the real terminal owns native scrollback.
Use --tmux at launch. tctl wraps the command in tmux, starts tmux with TERM=xterm-256color, and preconfigures default-terminal=tmux-256color, terminal-features=...,xterm-256color:RGB, terminal-overrides=...,xterm-256color:Tc (fallback for tmux < 3.2), COLORTERM=truecolor (via set-environment), escape-time=50, and mode-keys=vi.
Copy-mode: ctrl-b [ to enter, g g top, shift-g bottom, ctrl-u/ctrl-d half-page, / search, q to exit (not esc).
Launch with tmux:
When recording includes tmux redraws, asciinema must wrap tmux, not the reverse.
asciinema rec: Do not call asciinema rec directly. tctl --record wraps asciinema rec around the PTY so that tuistory-relay still owns the session and interactive TUIs (Ink/React) receive stdin correctly. Calling asciinema rec manually bypasses this wiring โ stdin forwarding breaks, typed keys echo on the outer PTY instead of reaching the child, and tuistory commands (wait, snapshot, close) cannot find the session.tuistory launch with tctl flags: tuistory has no --record, --backend, --repo-root, or --env flags. Passing them crashes tuistory-relay. Use tctl for all launches.If tctl itself is broken or unavailable, you can fall back to raw tuistory for non-recording sessions only. Raw tuistory accepts only --cols, --rows, and -s โ no other flags. Do not pass --record, --backend, --repo-root, --env, or --tmux.
$TCTL launch "droid-dev" -s demo --backend tuistory \
--repo-root /path/to/worktree \
--cols 120 --rows 36 --record /tmp/demo.cast \
--env FORCE_COLOR=3 --env COLORTERM=truecolor
# ... interact ...
$TCTL -s demo close # finalizes the .cast$TCTL launch "droid-dev" -s before --backend tuistory \
--repo-root /path/to/baseline-worktree \
--cols 120 --rows 36 --record /tmp/before.cast \
--env FORCE_COLOR=3 --env COLORTERM=truecolor
$TCTL launch "droid-dev" -s after --backend tuistory \
--repo-root /path/to/candidate-worktree \
--cols 120 --rows 36 --record /tmp/after.cast \
--env FORCE_COLOR=3 --env COLORTERM=truecolor$TCTL launch "droid-dev" -s demo --backend tuistory --tmux \
--repo-root /path/to/worktree \
--cols 120 --rows 36 --record /tmp/demo.cast \
--env FORCE_COLOR=3 --env COLORTERM=truecolor$TCTL -s demo press esc # bail out of a stuck dialog
$TCTL -s demo snapshot --trim # check visible state
$TCTL -s demo close # hard resettuistory launch "my-tui-app" -s demo --cols 120 --rows 36
tuistory -s demo wait ">" --timeout 15000
tuistory -s demo snapshot --trim
tuistory -s demo close