Agent skill
tuistory
Test and automate TUI applications using tuistory (Playwright for terminals). PREFERRED over tmux-tui for most cases. Use when you need reliable TUI automation with proper wait conditions instead of sleep hacks.
Install this agent skill to your Project
npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/data/tuistory
SKILL.md
tuistory - Terminal UI Testing
Automate and test terminal applications using tuistory, a TypeScript library that works like Playwright but for TUIs.
Prefer tuistory over tmux-tui for most TUI automation. It has proper waitForText synchronization instead of unreliable sleep commands.
Prerequisites
- Bun must be installed (
brew install oven-sh/bun/bunon macOS) - No other setup needed - Bun auto-installs dependencies on first run
Quick Start
Create a script and run with bun script.ts:
// No bun add needed - Bun auto-installs on import!
import { launchTerminal } from 'tuistory';
const session = await launchTerminal({
command: 'my-cli',
args: ['--interactive'],
cols: 120,
rows: 40,
});
// Wait for app to be ready (no more sleep guessing!)
await session.waitForText('Ready', { timeout: 5000 });
// Type input
await session.type('hello world');
await session.press(['enter']);
// Check output
const output = await session.text();
console.log(output);
// Clean up
await session.close();
API Reference
launchTerminal(options)
| Option | Type | Description |
|---|---|---|
command |
string | CLI command to run |
args |
string[] | Command arguments |
cols |
number | Terminal width (default: 80) |
rows |
number | Terminal height (default: 24) |
cwd |
string? | Working directory |
env |
object? | Environment variables |
session.type(text)
Type text character by character:
await session.type('search query');
session.press(keys)
Press keys or key combinations:
// Single keys
await session.press(['enter']);
await session.press(['tab']);
await session.press(['esc']);
await session.press(['up']);
await session.press(['down']);
// Key combinations
await session.press(['ctrl', 'c']);
await session.press(['ctrl', 'shift', 'a']);
await session.press(['alt', 'f']);
Available keys: enter, esc, tab, space, backspace, delete, up, down, left, right, home, end, pageup, pagedown
Modifiers: ctrl, alt, shift, meta
session.waitForText(pattern, options?)
Wait for text to appear (much better than sleep!):
// Wait for exact text
await session.waitForText('Loading complete');
// Wait for regex pattern
await session.waitForText(/error|success/i);
// With timeout
await session.waitForText('Ready', { timeout: 10000 });
session.text(options?)
Get current terminal content:
// Get all text
const output = await session.text();
// Filter by style
const boldText = await session.text({ bold: true });
const redText = await session.text({ foreground: 'red' });
session.click(pattern, options?)
Click on text matching a pattern:
// Click on text
await session.click('Submit');
// Click first match
await session.click(/button/i, { first: true });
session.close()
Clean up the terminal session:
await session.close();
Complete Example
import { launchTerminal } from 'tuistory';
async function testMyCLI() {
const session = await launchTerminal({
command: 'my-interactive-cli',
cols: 100,
rows: 30,
});
try {
// Wait for startup
await session.waitForText('Main Menu', { timeout: 5000 });
console.log('✓ CLI started');
// Navigate menu
await session.press(['down']);
await session.press(['down']);
await session.press(['enter']);
// Wait for submenu
await session.waitForText('Settings', { timeout: 2000 });
console.log('✓ Entered settings');
// Type in a field
await session.type('new-value');
await session.press(['enter']);
// Verify result
await session.waitForText('Saved');
console.log('✓ Settings saved');
// Get final state
const output = await session.text();
console.log('Final output:', output);
} finally {
await session.close();
}
}
testMyCLI();
Inline Usage
For quick one-off automation, use bun's eval:
bun -e "
import { launchTerminal } from 'tuistory';
const s = await launchTerminal({ command: 'my-cli' });
await s.waitForText('ready');
await s.type('test');
console.log(await s.text());
await s.close();
"
Version Pinning
Pin versions directly in import statements (no package.json needed):
import { launchTerminal } from 'tuistory@1.0.0'; // exact version
import { launchTerminal } from 'tuistory@^1.0.0'; // semver range
import { launchTerminal } from 'tuistory@latest'; // explicit latest
Bun caches packages globally and checks for updates every 24h for latest.
When to Use tmux-tui Instead
Fall back to tmux-tui skill when:
- You need to visually attach to the session for debugging (
tmux attach -t name) - Bun is not available in the environment
- You're doing very quick one-off interactions where synchronization doesn't matter
Debugging Tips
- Use
console.log(await session.text())liberally to see current state - Increase timeout values if the app is slow to respond
- Check
colsandrowsmatch what the app expects - For apps that clear the screen, capture output before navigation
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
agent-ops-spec
Manage specification documents in .agent/specs/. Use when user provides requirements, acceptance criteria, or feature descriptions that need to be tracked and validated against implementation.
agent-ops-state
Maintain .agent state files. Use at session start, after meaningful steps, and before concluding: read/update constitution/memory/focus/issues/baseline consistently.
agent-ops-spec
Manage specification documents in .agent/specs/. Use when user provides requirements, acceptance criteria, or feature descriptions that need to be tracked and validated against implementation.
agent-ops-testing
Test strategy, execution, and coverage analysis. Use when designing tests, running test suites, or analyzing test results beyond baseline checks.
agent-ops-testing
Test strategy, execution, and coverage analysis. Use when designing tests, running test suites, or analyzing test results beyond baseline checks.
agent-ops-state
Maintain .agent state files. Use at session start, after meaningful steps, and before concluding: read/update constitution/memory/focus/issues/baseline consistently.
Didn't find tool you were looking for?