# Headless Terminal

> This skill provides guidance for implementing headless terminal interfaces that programmatically control shell sessions. Use this skill when implementing terminal emulation, pseudo-terminal wrappers,

- Skill: `lazyfroglol/headless-terminal` (Agent Skill)
- Install (CLI): `npx skillmds@latest add lazyfroglol/headless-terminal`
- Raw SKILL.md: https://api.skillmd.com/api/skills/lazyfroglol/headless-terminal/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: lazyfroglol (https://skillmd.com/u/lazyfroglol)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/lazyfroglol/headless-terminal

---


# Headless Terminal Implementation

## Overview

This skill guides the implementation of headless terminal interfaces—programmatic wrappers that control shell sessions without a visible terminal UI. These implementations typically involve spawning shell processes, sending input (keystrokes, commands), and capturing output.

## Approach

### Step 1: Understand the Interface Contract

Before implementing, thoroughly read and understand the interface to be implemented:

1. Identify all required methods and their signatures
2. Note return types and expected behaviors
3. Check for optional methods or features
4. Look for existing implementations or tests that clarify expected behavior

### Step 2: Select the Underlying Library

Common libraries for terminal emulation in Python:

| Library | Best For | Trade-offs |
|---------|----------|------------|
| `pexpect` | Interactive terminal emulation, pattern matching | Higher-level API, good for expect/send patterns |
| `pty` | Low-level pseudo-terminal control | More control, but more boilerplate |
| `subprocess` | Simple non-interactive commands | Limited for true terminal emulation |

**Decision criteria to document:**
- Does the task require interactive input (passwords, prompts)? → `pexpect`
- Does the task need low-level terminal control? → `pty`
- Is it purely non-interactive command execution? → `subprocess` may suffice

**Document the choice explicitly** with reasoning for future maintainability.

### Step 3: Handle Shell Configuration

When spawning a shell process, consider these configuration options:

**Interactive mode (`-i` flag):**
- Ensures startup files (`.bashrc`, `.bash_profile`) are sourced
- Affects signal handling behavior
- Required if tests verify startup file sourcing

**Echo behavior:**
- `echo=False` in pexpect prevents input from appearing in output
- Consider whether the use case needs to see echoed input

**Terminal dimensions:**
- Default `(24, 80)` is standard terminal size
- May affect output formatting for commands that detect terminal width
- Document why specific dimensions are chosen

### Step 4: Implement Core Functionality

Focus on implementing exactly what the interface requires:

1. **Process lifecycle management** - Spawn, check liveness, terminate
2. **Input handling** - Send keystrokes, handle special keys (Ctrl+C, etc.)
3. **Output capture** - Read available output, handle buffering
4. **Resource cleanup** - Proper termination, context manager support

### Step 5: Address Edge Cases

Explicitly handle these scenarios:

| Edge Case | Handling Strategy |
|-----------|-------------------|
| Shell exits unexpectedly | Check process liveness before operations |
| Long-running commands | Configurable timeouts, background execution support |
| Non-ASCII characters | Explicit encoding handling (UTF-8 typically) |
| Race conditions | Appropriate delays between send and read operations |
| Command cancellation | Proper signal handling (SIGINT for Ctrl+C) |

## Verification Strategies

### Testing Approach

Create focused tests for each capability:

1. **Basic functionality** - Import, instantiation
2. **Non-interactive commands** - Simple command execution and output
3. **Interactive commands** - Commands requiring input
4. **Signal handling** - Ctrl+C cancellation
5. **Shell state** - Variable persistence, environment
6. **Startup configuration** - Verify startup files are sourced
7. **Background execution** - Long-running command handling

### Verification Guidelines

- Run the test suite to verify all functionality
- Avoid redundant manual verification after tests pass
- If a single comprehensive test file exists, use it rather than creating separate verification scripts

## Common Pitfalls

### Scope Management

- **Implement only what is required** - Avoid adding unrequested features like extra utility methods
- If additional methods seem useful, note them but don't implement unless asked
- Context manager support is often expected but verify it's in the interface

### Efficiency

- **Avoid redundant searches** - If searching for a class, one targeted search is sufficient
- **Don't duplicate verification** - If tests pass, additional manual checks are unnecessary
- **Don't create example files** unless explicitly requested

### Documentation Gaps

Common decisions that should be documented but often aren't:

1. Why the chosen library over alternatives
2. Why specific shell flags are used
3. Why specific default values were selected
4. Thread safety considerations (or explicit statement that it's not thread-safe)

### Error Handling

Consider and document handling for:

- Invalid keystroke sequences
- Terminal process termination
- Timeout scenarios
- Permission issues

## Implementation Checklist

Before considering the implementation complete:

- [ ] All interface methods are implemented
- [ ] Library choice is documented with reasoning
- [ ] Configuration decisions are justified
- [ ] Edge cases are explicitly handled or documented as out of scope
- [ ] Tests cover all required functionality
- [ ] No unrequested features were added
- [ ] Resource cleanup is properly implemented

Overview

This skill guides implementing headless terminal interfaces that programmatically control shell sessions without a visual UI. It focuses on spawning shell processes, sending keystrokes, capturing output, and managing lifecycle and edge cases. The guidance helps choose libraries, document decisions, and verify behavior with focused tests.

How this skill works

The implementation spawns a shell process via a chosen backend (pexpect, pty, or subprocess), configures interactive flags, terminal dimensions, and echo behavior, and exposes methods to send input and read output. It includes lifecycle management (spawn, liveness checks, terminate), signal handling for cancellations (e.g., Ctrl+C), and explicit resource cleanup and encoding handling.

When to use it

Building programmatic terminal emulation or pseudo-terminal wrappers

Implementing a BaseTerminal-style interface that must send keystrokes and read shell output

Automating interactive shell tasks that require prompts or password entry

Testing shell startup configuration or environment persistence

Handling long-running commands or background shell jobs

Best practices

Document and justify the chosen underlying library (pexpect, pty, or subprocess) and why alternatives were rejected

Expose only the methods required by the interface; avoid adding unrequested features

Set and document terminal dimensions and interactive flags so test behavior is reproducible

Handle encoding explicitly (UTF-8) and validate non-ASCII behavior in tests

Provide configurable timeouts and robust liveness checks to manage long-running commands and unexpected exits

Implement and document proper resource cleanup and context manager support if the interface expects it

Example use cases

A CI runner that needs to drive interactive installers and capture prompts

A remote automation agent that runs shells and reacts to output patterns using expect/send logic

A test harness that verifies shell startup files are sourced in interactive mode

A wrapper that exposes a programmatic API for sending special keys (Ctrl+C) and cancelling commands

A logging proxy that records both sent keystrokes and terminal output for replay and debugging

FAQ

Which library should I pick for interactive shells?

Use pexpect for high-level expect/send interactions and prompts; use pty for low-level control when precise terminal semantics are required; use subprocess only for non-interactive command execution.

How should I handle unexpected shell exits?

Always check process liveness before operations, surface clear errors to callers, and provide configurable retries or timeouts for recovery; document whether automatic restarts are in-scope.

Skill score

0

Health score

i

D

65
/100

Stats

278
 stars

First Seen

2 months ago

Repository

benchflow-ai
/
skillsbench

Tag

