tuiw 0.1.0

TUI applications wrapper with tmux for headless operation
tuiw-0.1.0 is not a library.

tuiw

Crates.io Documentation License

TUI applications wrapper with tmux for headless operation.

Overview

rust-tuiw enables headless interaction with TUI (Terminal User Interface) applications by wrapping them with tmux. This allows for programmatic control and automation of interactive terminal applications.

Architecture

Daemon/Client Model

The application operates in two modes:

  • Daemon: GraphQL server that manages tmux sessions and TUI applications
  • Client: CLI interface that communicates with the daemon via GraphQL

On first invocation, if no daemon is running, the process automatically starts as a daemon. Subsequent invocations act as clients.

Components

┌─────────────────────────────────────────────────────────┐
│                        Client                           │
│                     (GraphQL Client)                    │
└──────────────────────┬──────────────────────────────────┘
                       │ GraphQL over HTTP
                       │ SSE for subscriptions
┌──────────────────────▼──────────────────────────────────┐
│                       Daemon                            │
│                   (GraphQL Server)                      │
│  ┌─────────────────────────────────────────────────┐   │
│  │          Session Management (in-memory)         │   │
│  │  - Session ID generation                        │   │
│  │  - CWD tracking                                 │   │
│  │  - Multiple session support                     │   │
│  └─────────────────────┬───────────────────────────┘   │
│                        │                                │
│  ┌─────────────────────▼───────────────────────────┐   │
│  │           Tmux Wrapper                          │   │
│  │  - Session creation                             │   │
│  │  - Key input injection                          │   │
│  │  - Output capture (capture-pane)                │   │
│  │  - Change detection for SSE                     │   │
│  └─────────────────────┬───────────────────────────┘   │
└────────────────────────┼───────────────────────────────┘
                         │
                ┌────────▼────────┐
                │  Tmux Sessions  │
                │   ┌──────────┐  │
                │   │   TUI    │  │
                │   │   App    │  │
                │   └──────────┘  │
                └─────────────────┘

GraphQL API

Mutations

  • createSession(command: String!, cwd: String!): SessionID
  • sendKeys(sessionId: SessionID!, keys: String!): Boolean
  • closeSession(sessionId: SessionID!): Boolean

Queries

  • listSessions: [Session!]!
  • getOutput(sessionId: SessionID!): String!
  • getSessionStatus(sessionId: SessionID!): SessionStatus!

Subscriptions

  • screenChanges(sessionId: SessionID!): String! (via SSE)

Session Management

Each session maintains:

  • Unique session ID
  • Working directory (cwd) from client invocation location
  • Tmux session reference
  • Output buffer and change detection state

Multiple TUI applications can run simultaneously, each in its own session.

Use Cases

Primary: Claude Code Automation

Claude Code currently lacks a headless interaction mode. By wrapping Claude Code with rust-tuiw, you can:

  • Programmatically send commands
  • Monitor output changes
  • Automate coding workflows

General TUI Automation

Since rust-tuiw works with any TUI application, it enables automation for:

  • All coding agents (not just Claude Code)
  • Interactive CLI tools
  • Terminal-based development environments
  • Any ncurses/TUI application

Technology Stack

  • Language: Rust (edition 2024)
  • Async Runtime: tokio
  • GraphQL: async-graphql
  • HTTP Server: axum
  • CLI Parsing: clap
  • Process Management: tmux

Getting Started

Prerequisites

  • Rust toolchain (1.91.1 or later)
  • tmux
  • NixOS users: Use nix develop for development environment

Installation

git clone https://github.com/conao3/rust-tuiw.git
cd rust-tuiw
cargo build --release

The binary will be available at target/release/tuiw.

Alternatively, install via cargo:

cargo install tuiw

Basic Usage

1. Create a Session

Create a new TUI session by specifying the command to run:

tuiw create "bash"

This will output a session ID (UUID format):

Session created: a1b2c3d4-e5f6-7890-abcd-ef1234567890

You can also specify a working directory:

tuiw create "vim" --cwd /path/to/project

2. List Sessions

View all active sessions:

tuiw list

Output:

Sessions:
  a1b2c3d4-e5f6-7890-abcd-ef1234567890 - bash (/home/user)

3. Send Keys

Send keyboard input to a session:

tuiw send a1b2c3d4-e5f6-7890-abcd-ef1234567890 "echo hello"
tuiw send a1b2c3d4-e5f6-7890-abcd-ef1234567890 "Enter"

4. Get Output

Capture the current screen content:

tuiw output a1b2c3d4-e5f6-7890-abcd-ef1234567890

5. Check Status

Check if a session is running:

tuiw status a1b2c3d4-e5f6-7890-abcd-ef1234567890

6. Close Session

Terminate a session:

tuiw close a1b2c3d4-e5f6-7890-abcd-ef1234567890

Example: Automating vim

# Create a vim session
SESSION_ID=$(tuiw create "vim" | grep -oE '[0-9a-f-]{36}')

# Open a file
tuiw send $SESSION_ID ":e test.txt"
tuiw send $SESSION_ID "Enter"

# Enter insert mode and type
tuiw send $SESSION_ID "i"
tuiw send $SESSION_ID "Hello, World!"

# Save and quit
tuiw send $SESSION_ID "Escape"
tuiw send $SESSION_ID ":wq"
tuiw send $SESSION_ID "Enter"

# Close session
tuiw close $SESSION_ID

SSE for Real-time Monitoring

Subscribe to screen changes via Server-Sent Events:

curl -N http://127.0.0.1:50051/sse/<session-id>

This streams output whenever the screen content changes.

GraphQL API

The daemon exposes a GraphQL API at http://127.0.0.1:50051/graphql:

curl -X POST http://127.0.0.1:50051/graphql \
  -H "Content-Type: application/json" \
  -d '{
    "query": "query { listSessions { id command cwd } }"
  }'

Troubleshooting

Daemon not starting:

  • Check if port 50051 is available
  • Ensure tmux is installed and in PATH

Session not found:

  • The daemon is stateless and sessions are lost on restart
  • Verify the session ID is correct using rust-tuiw list

Keys not being sent:

  • Ensure the session is still running with rust-tuiw status
  • Special keys like Enter, Escape, Tab should be sent as separate commands

Development

See Makefile for available commands:

  • make build - Build the project
  • make run - Run the application
  • make test - Run tests
  • make check - Run cargo check
  • make clippy - Run clippy lints
  • make fmt - Format code

License

Apache-2.0