TUIOSTUIOS

Tape Scripting

Automate TUIOS workflows with tape files

Tape Scripting

TUIOS Tape is a domain-specific language (DSL) for automating terminal window management workflows. Tape scripts allow you to record, replay, and test complex TUIOS interactions programmatically.

Perfect for...

  • Recording and replaying terminal workflows
  • Automated testing
  • Demo recording
  • CI/CD automation
  • Documenting workflows

Running Tape Scripts

# Interactive mode (visible TUI) - watch automation happen
tuios tape play demo.tape

# Validate syntax
tuios tape validate demo.tape

# List saved recordings
tuios tape list

# Show a tape file
tuios tape show my-recording

Remote Execution

The tuios tape exec command runs a tape script against an already running TUIOS session, without a visible TUI. Use it when TUIOS is running in daemon mode.

# Execute against current session
tuios tape exec script.tape

# Execute against a specific session
tuios tape exec -s mysession script.tape

exec ignores all waiting

tuios tape exec silently skips every Wait and WaitUntilRegex command. They are deliberate no-ops in the remote executor, which is fire-and-forget; only the interactive playback loop behind tape play blocks on them. No warning is printed and the exit status does not change.

This matters most in CI. A tape that reads

Type "npm test"
Enter
WaitUntilRegex "Tests passed" 30000
CloseWindow

will, under exec, close the window immediately after pressing Enter. Sleep is honoured, so an unconditional Sleep is the only pacing that works under exec. If you need to wait on output, poll from the shell instead:

tuios tape exec -s ci run-tests.tape
until tuios capture-pane -s ci | grep -q "Tests passed"; do sleep 1; done

Progress Display

Remote execution shows a progress indicator:

Executing script.tape... Progress: 5/12 [███████░░░░░░░░░░░░░] 41%

Use Cases

Automation pipelines:

#!/bin/bash
set -euo pipefail

# A headless session is created immediately, so no sleep is needed
tuios new automation --detach

tuios tape exec -s automation setup.tape

# exec does not wait on output, so gate on it from the shell
until tuios capture-pane -s automation | grep -q "setup complete"; do
    sleep 1
done

tuios tape exec -s automation test-workflow.tape

tuios kill-session automation

Development workflows:

# Terminal 1: Start TUIOS
tuios new dev

# Terminal 2: Send scripts
tuios tape exec -s dev environment-setup.tape

Differences from tape play

Featuretape playtape exec
Starts TUIOSYesNo (requires running session)
Shows TUIYesNo (progress bar only)
InteractiveYesNo
Session persistenceNoYes (works with daemon)
Honours SleepYesYes
Honours Wait / WaitUntilRegexYesNo, silently skipped

Pick exec when the script is a sequence of state changes and you can pace it externally. Pick play when the script depends on terminal output.

Combining with CLI Commands

Remote tape execution composes with the other CLI commands:

# Execute script then query state
tuios tape exec setup.tape
tuios session-info --json | jq '.total_windows'

# Create window via command, then run tape
tuios run-command NewWindow "dev"
tuios tape exec dev-setup.tape

See Sessions & Remote Control for more about controlling TUIOS from external scripts.

Basic Syntax

Comments

Lines starting with # are comments:

# This is a comment
NewWindow  # Create a window

Commands

One command per line. Keyword matching is case-insensitive: NewWindow, newwindow, and NEWWINDOW all lex to the same token. The examples in this page use the canonical mixed case, and recorded tapes are written that way, but nothing enforces it.

NewWindow
Sleep 500ms
TerminalMode
Type "echo hello"
Enter

Arguments are not keywords and stay case-sensitive.

String Literals

Type "hello world"
Type 'hello world'
Type `hello world`

Durations

Sleep 500ms     # Milliseconds
Sleep 2s        # Seconds
Sleep 1.5s      # Decimal seconds

Repeat Count

Key and navigation commands accept a trailing repeat count. The key is sent that many times.

Down 5          # Press Down five times
Backspace 10
Enter 2

This works for Enter, Space, Tab, Backspace, Delete, Escape, and the six navigation keys, and nothing else.

Other commands still parse a trailing number, they just do not repeat on it, and a few then treat it as an argument. NewWindow 3 creates a single window named 3. ToggleTiling 3 toggles once. Do not add counts to non-key commands.

Delay Modifier

The grammar also accepts an optional @<duration> between a command and its count: <Command> [@<duration>] [<count>].

Down@100ms 3
NewWindow @500ms    # Whitespace around @ is allowed

@ is parsed but not applied

Outside of Sleep and Wait, the parsed delay is stored on the command and then never read, by either the interactive player or the remote executor. Down@100ms 3 sends three Down keys back to back, not one every 100ms.

Use explicit Sleep lines for pacing.

Sleep itself takes a bare duration and rejects @, so Sleep@200ms is a parse error. Write Sleep 200ms.

Mode Management

Important

TUIOS has two modes: Window Management Mode and Terminal Mode. Always switch modes explicitly before mode-specific commands!

WindowManagementMode

Switch to window management mode for managing windows.

WindowManagementMode

TerminalMode

Switch to terminal mode to send input to the focused window.

TerminalMode

Example workflow:

WindowManagementMode
NewWindow
TerminalMode
Type "ls -la"
Enter
WindowManagementMode

Window Operations

NewWindow

Create a new terminal window.

NewWindow
Sleep 500ms  # Give time for creation

CloseWindow

Close the currently focused window.

CloseWindow

NextWindow / PrevWindow

Navigate between windows.

NextWindow
Sleep 200ms

RenameWindow

Rename the focused window.

RenameWindow "My Terminal"

MinimizeWindow / RestoreWindow

Minimize and restore windows.

MinimizeWindow
Sleep 300ms
RestoreWindow

Tiling and Layout

ToggleTiling

Toggle tiling mode.

ToggleTiling

EnableTiling / DisableTiling

Explicitly control tiling mode.

EnableTiling
Sleep 300ms

Animation Control

EnableAnimations / DisableAnimations / ToggleAnimations

Control window animations during tape playback.

DisableAnimations  # Instant transitions
NewWindow
EnableAnimations   # Restore animations

Recorded Tapes

When you record a tape, TUIOS automatically prepends DisableAnimations at the start and appends EnableAnimations at the end. This ensures tape playback is reproducible regardless of the user's animation settings.

Animation Sync

Tape playback automatically waits for animations to complete before executing the next command. This ensures smooth, synchronized execution even with animations enabled.

Snap Commands

Snap windows to positions.

SnapLeft
SnapRight
SnapFullscreen

Workspace Management

TUIOS supports 9 workspaces (1-9).

SwitchWorkspace

Switch to a workspace.

SwitchWorkspace 2
Sleep 400ms

MoveToWorkspace

Move window to workspace.

MoveToWorkspace 3

MoveAndFollowWorkspace

Move and follow.

MoveAndFollowWorkspace 2

Keyboard Input

Terminal Mode Required

Keyboard commands only work in Terminal Mode!

Type

Type text into terminal.

TerminalMode
Type "echo 'Hello, World!'"

Basic Keys

Enter
Space
Tab
Backspace
Delete
Escape
Up
Down
Left
Right
Home
End

Key Combinations

Ctrl+c
Ctrl+b
Alt+1
Ctrl+Alt+t
Ctrl+Up
Shift+Left
Ctrl+Enter
Ctrl+Space

Tab, Escape, Backspace and Delete cannot be modified

After a modifier the parser accepts an identifier, a navigation key (Up, Down, Left, Right, Home, End), Enter, Space, or a number. Tab, Escape, Backspace, and Delete are their own keyword tokens and are not in that set, so Shift+Tab, Ctrl+Tab, Ctrl+Escape, and Ctrl+Backspace all fail to parse:

expected key after modifier, got Tab

The executor has handling for Shift+Tab, so this is a parser gap rather than a missing feature, but there is no way to reach it from a tape file today. If you need a modified Tab or Escape, send it through the daemon instead:

tuios send-keys "shift+tab"

Layout and Split Commands

These verbs are recognised by the lexer and act on the BSP tree. See BSP Tiling.

SmartSplit
RotateSplit
EqualizeSplits
ToggleZoom
FocusWindow 2
SaveLayout "dev"
LoadLayout "dev"
CommandPalette

FocusWindow takes a window ID or name. SaveLayout and LoadLayout take a layout name.

Commands That Parse But Do Nothing

The lexer recognises 53 command keywords, more than the executor acts on. Several of them produce a valid command that the executor has no case for, so they run without error and without effect. tuios tape validate will report them as fine.

CommandBehaviour
Set <key> <value>Parsed, no executor case. No-op.
Output <file>Parsed, no executor case. No-op.
Source <file>Parsed, no executor case. Does not include another tape.
Focus <id>Parsed, no executor case. Use FocusWindow instead.
SplitSee below. Always a no-op from a tape file.

Split always does nothing in a tape

The executor implements Split and branches on a horizontal or vertical argument. The parser routes Split through the basic-command path, which can only hold a trailing number, so the direction is discarded before the executor ever sees it. Split horizontal validates cleanly and then does nothing.

The direction works only through the daemon:

tuios run-command Split horizontal

Inside a tape, use SmartSplit, which needs no argument.

The same parser gap affects the by-name variants of four window commands. The executor supports NewWindow "name", CloseWindow "name", MinimizeWindow "name", and RestoreWindow "name", but the parser cannot build them. In a tape, the string argument is skipped and the command applies to the focused window:

NewWindow "editor"   # Validates. Creates an unnamed window.

To create a named window, use RenameWindow after it, or call the daemon directly with tuios run-command NewWindow "editor".

Timing

Sleep

Pause execution.

Sleep 500ms
Sleep 1s

Wait

Wait is an alias for Sleep and requires a duration. Wait on its own is a parse error.

Wait 2s

WaitUntilRegex

Wait for terminal output to match a pattern, with a timeout in milliseconds.

TerminalMode
Type "ls -la"
Enter
WaitUntilRegex "\$" 3000  # Wait for prompt

Only under tape play

Wait and WaitUntilRegex are honoured by the interactive playback loop and skipped entirely by tuios tape exec. A tape that relies on either for synchronisation will race when run remotely. See Remote Execution.

Example Scripts

Basic Workflow

# Create a new window and run commands
WindowManagementMode
NewWindow
Sleep 500ms

TerminalMode
Type "ls -la"
Enter
Sleep 1s

Type "echo 'Done'"
Enter

Multi-Workspace Setup

# Setup workspace 1 - development
WindowManagementMode
NewWindow
Sleep 500ms
TerminalMode
Type "cd ~/project"
Enter

# Switch to workspace 2 - monitoring
WindowManagementMode
SwitchWorkspace 2
Sleep 400ms

NewWindow
Sleep 500ms
TerminalMode
Type "htop"
Enter

Tiling Demo

# Create tiled layout
WindowManagementMode
EnableTiling

NewWindow
Sleep 500ms
NewWindow
Sleep 500ms
NewWindow
Sleep 500ms

# Navigate and type in each
TerminalMode
Type "echo 'Window 1'"
Enter

WindowManagementMode
NextWindow
TerminalMode
Type "echo 'Window 2'"
Enter

Development Environment Setup

# Create development workspace
WindowManagementMode
EnableTiling
# Window 1: Editor
NewWindow
Sleep 500ms
TerminalMode
Type "nvim ."
Enter
# Window 2: Server
WindowManagementMode
NewWindow
Sleep 500ms
TerminalMode
Type "npm run dev"
Enter
# Window 3: Tests
WindowManagementMode
NewWindow
Sleep 500ms
TerminalMode
Type "npm test -- --watch"
Enter
# Window 4: Git
WindowManagementMode
NewWindow
Sleep 500ms
TerminalMode
Type "git status"
Enter

Recording Tapes

You can record your interactions:

Press Ctrl+B T r to start recording

Perform your workflow normally

Press Ctrl+B T s to stop recording

Tape is saved to ~/.local/share/tuios/tapes/

View your recordings:

tuios tape list
tuios tape show my-recording

Best Practices

Always Add Delays

Give TUIOS time to process animations and state changes

NewWindow
Sleep 500ms  # Wait for creation (GOOD)

NewWindow
# No sleep - next command might execute too soon (BAD)

Explicit Mode Switching

Always switch modes explicitly before mode-specific actions

# GOOD
WindowManagementMode
NewWindow
TerminalMode
Type "ls"

# BAD (mode might be wrong)
NewWindow
Type "ls"

Use Comments

Document complex workflows

# Setup development environment
WindowManagementMode
EnableTiling

# Create editor window
NewWindow
Sleep 500ms

# Create terminal window
NewWindow
Sleep 500ms

On this page