Sandbox
@EliasOenal/term-cli

tmux terminal sessions for agent workflows

term-cli runs interactive commands in detached tmux sessions so an agent can wait for prompts, send keys, capture output, and transfer files. term-assist lets a human join the same session to handle secrets, MFA, and other steps the agent should not do alone.

102 stars10 forksPythonUpdated 1mo ago
Who it's for

Builders who want their agent to work through SSH prompts, debuggers, installers, and other interactive terminal flows.

What it delivers

You can keep agent-led work moving through terminals that would otherwise block on prompts, TUIs, or MFA.

What it does

Detached interactive sessions

Create, run, inspect, and kill tmux-backed sessions with commands like `start`, `run`, `capture`, and `wait`.

Human handoff

Use `request` and `term-assist` when passwords, MFA, or manual confirmation need a person at the keyboard.

Terminal input control

Send text, special keys, mouse clicks, stdin, and resize events into a live session.

File transfer

Upload and download files through a session with compression, checksum verification, and pipe support.

Session observation

Wait for prompts, wait for idle output, or wait for text patterns before the next agent action.

Agent skill support

Ships a skill in `skills/term-cli/` and installs it for supported agents.

How to get it

  1. 1Requires Python 3.8+ and tmux.
    # Install tmux first (if not already installed)
    brew install tmux        # macOS
    apt install tmux         # Debian/Ubuntu
    
    # Install the latest stable term-cli, term-assist, and agent skill files
    curl -fsSL https://github.com/EliasOenal/term-cli/releases/latest/download/install.sh | bash
  2. 2Or from a cloned repo
    git clone https://github.com/EliasOenal/term-cli.git && cd term-cli && ./install.sh
  3. 3Run
    curl -LO https://github.com/EliasOenal/term-cli/releases/latest/download/term-cli
    curl -LO https://github.com/EliasOenal/term-cli/releases/latest/download/term-assist
    chmod +x term-cli term-assist

README

term-cli term-cli challenge demo

term-cli: unlock interactive terminals for AI agents

If it blocks in a terminal, it blocks your agent.

Run interactive programs from your AI coding agent without blocking. Dev servers, debuggers, REPLs, databases, editors, SSH sessions, TUIs, long-running watchers, and interactive installers.

More examples

Dev servers (npm run dev), debuggers (pdb, gdb), REPLs (python, node), databases (psql, mysql), editors (vim, nano), SSH sessions, TUIs (htop, less), log watchers (tail -f, journalctl), terminal browsers (carbonyl, browsh, lynx), IRC clients (irssi, weechat), packet capture (termshark), package manager prompts (apt, brew, pacman), EULAs and interactive wizards.

Hand control to humans for passwords and MFA prompts. Or flip it: human drives while the agent watches, advises, and learns—a pair programmer, rubber duck, or observer looking over your shoulder.

  • term-cli: Agents run interactive programs in detached terminal sessions (tmux-backed)
  • term-assist: Humans collaborate, enter passwords, handle MFA, prepare sessions

Single-file Python. No dependencies beyond tmux. 700+ tests, CI on every commit. BSD licensed.

The Problem

Agents can run shell commands, but interactive programs block forever:

vim config.yaml           # millions of developers trapped, now agents join them
npm run dev               # blocks, need to see output
python -m pdb script.py   # blocks, need to interact
gdb ./crash               # blocks, need to step through
ssh user@server           # needs password
apt-get install nginx     # needs Y/n confirmation
certbot certonly          # interactive wizard
tail -f /var/log/app.log  # runs forever, need to watch

The Solution

term-cli start --session debug && term-cli run --session debug "python -m pdb script.py" --wait
term-cli send-text --session debug "b main" --enter && term-cli wait --session debug
term-cli send-text -s debug "c" --enter && term-cli wait -s debug   # continue
term-cli capture --session debug                                    # see where we are
term-cli kill --session debug

Agents run commands in detached tmux sessions. Humans join when needed via term-assist.

TTY-first workflows you can’t --yes away

Some workflows have no reliable non-interactive mode: serial consoles, boot menus, installers, and full-screen TUIs. term-cli lets agents wait for prompts, send keys, capture state, and hand off to humans only when needed.

  • Professional network gear and console access

    • SSH sessions: interactive prompts for passwords/MFA and stateful CLI workflows.

    • Paged output (“more”): keypress to continue on long command output.

    • Serial console sessions: run tools like screen or picocom on USB-serial adapters (lab devices, console servers, remote hands).

    • BMC Serial-over-LAN (SOL): interactive console access via IPMI/iDRAC/iLO-style SOL when the OS is down or pre-boot.

    • Virtual machine consoles: QEMU/virsh console/hypervisor consoles are terminal-first and commonly explored interactively.

    • Vendor examples
      • Cisco IOS / IOS XE and Cisco NX-OS: first-boot setup wizard/utility with interactive yes/no and field entry.
      • Juniper Junos: password setup with enter and confirm a second time.
  • Embedded, SoC, and lab bring-up

    • Bootloaders: U-Boot autoboot interrupt, boot menus, environment editing, netboot and flash flows over serial.
    • Manufacturing and validation firmware: text menus for tests, calibration, burn-in loops, operator prompts.
    • JTAG/SWD debugging: GDB interactive stepping and inspection loops (you can script parts, but engineers usually explore interactively).
  • System recovery and pre-OS troubleshooting

    • Boot repair shells: GRUB rescue and bootloader menus when the system won’t boot normally.
    • Initramfs and emergency modes: dracut, BusyBox, systemd emergency shell workflows that require live interaction.
    • Filesystem repair and recovery: tools like fsck that ask repeated fix/skip prompts (optionally with human approval).
  • Linux installers and package configuration prompts

    • Debconf TUIs: timezone (tzdata), locales, keyboard, mail setup (postfix), database setup wizards.
    • License/EULA accept flows: “scroll and accept” installers that block on keypress.
    • Config-file conflicts during upgrades: keep local vs maintainer config prompts (dpkg/apt).

Installation

Requires Python 3.8+ and tmux.

# Install tmux first (if not already installed)
brew install tmux        # macOS
apt install tmux         # Debian/Ubuntu

# Install the latest stable term-cli, term-assist, and agent skill files
curl -fsSL https://github.com/EliasOenal/term-cli/releases/latest/download/install.sh | bash

Or from a cloned repo:

git clone https://github.com/EliasOenal/term-cli.git && cd term-cli && ./install.sh
Install options
# System-wide install (to /usr/local/bin, requires sudo)
./install.sh --system

# Custom install directory
./install.sh --prefix ~/bin

# Skip skill file installation
./install.sh --no-skill

# Install skills only for specific agents
./install.sh --skill opencode,claude

# Uninstall
./install.sh --uninstall
Manual installation
curl -LO https://github.com/EliasOenal/term-cli/releases/latest/download/term-cli
curl -LO https://github.com/EliasOenal/term-cli/releases/latest/download/term-assist
chmod +x term-cli term-assist

Agent Skills

Agent Skills are instructions and resources that agents discover and load on demand to work more accurately. term-cli includes a skill in skills/term-cli/. The installer automatically installs it for all known agents.

Skills vs MCP: Skills suit coding agents—concise CLI commands keep context lean when balancing automation with large codebases. MCP servers suit specialized loops that benefit from persistent state and rich introspection. term-cli is CLI-native; no MCP server needed.

No skill? No problem. Point your agent at term-cli --help and let it figure things out. The CLI is self-documenting.

Manual skill installation

Install to your home directory so it works across projects.

# GitHub Copilot (VS Code / Copilot CLI)
mkdir -p ~/.copilot/skills && cp -r skills/term-cli ~/.copilot/skills/

# Gemini CLI
mkdir -p ~/.gemini/skills && cp -r skills/term-cli ~/.gemini/skills/

# OpenAI Codex CLI
mkdir -p ~/.agents/skills && cp -r skills/term-cli ~/.agents/skills/

# OpenClaw
mkdir -p ~/.openclaw/skills && cp -r skills/term-cli ~/.openclaw/skills/

# Claude Code
mkdir -p ~/.claude/skills && cp -r skills/term-cli ~/.claude/skills/

# OpenCode
mkdir -p ~/.config/opencode/skills && cp -r skills/term-cli ~/.config/opencode/skills/

Works with

Agents and tools

Works with Claude Code, Gemini CLI, Cursor, Aider, OpenCode, Cline, Kilo Code, Windsurf, Amazon Q, Augment Code, Moltbot, OpenHands, and any agent that can run shell commands.

term-cli Commands (for agents)

CommandDescription
start --session NAMECreate session
kill --session NAMEDestroy session
listList sessions
status --session NAMEShow state and process tree
run --session NAME "cmd" --wait --timeout 60Run command, wait for prompt
send-text --session NAME "text" --enterSend text (--enter for Enter key)
send-key --session NAME C-cSend special key
send-mouse --session NAME --text "Item"Click a visible TUI item (alternate screen mode)
send-mouse --session NAME --text "Item" --scroll-down 3Scroll at a visible TUI item
send-stdin --session NAME < file.txtSend multiline content
capture --session NAMECapture screen (auto-annotates active TUIs; --tail/--scrollback for more)
wait --session NAME --timeout 30Wait for prompt
wait-idle --session NAME --idle 2Wait for output to settle
wait-for --session NAME "pattern"Wait for text to appear (--print-match/--print-match-context N)
resize --session NAME --cols 120 --rows 40Resize terminal
scroll --session NAME -50Scroll viewport (negative=up)
pipe-log --session NAME /tmp/out.logStream output to file
unpipe --session NAMEStop streaming
upload --session NAME local.txt remote.txtUpload file to session (gzip-compressed, SHA-256 verified)
download --session NAME remote.txt local.txtDownload file from session (gzip-compressed, SHA-256 verified)
request --session NAME --message "help"Request human assistance
request-wait --session NAMEWait for human to complete
request-status --session NAMECheck if request pending
request-cancel --session NAMECancel pending request

Session names may contain ASCII letters, digits, dashes, and underscores.

Run term-cli --help or term-cli <command> --help for details.

Keys

C-c C-d C-z C-u C-l (ctrl), Enter Escape Tab Space BSpace, Up Down Left Right, Home End PPage NPage, F1-F12

term-assist Commands (for humans)

CommandDescription
listList all sessions (highlights pending requests)
attach --session NAMEJoin session with status bar UI
attach --session NAME --readonlyObserve without typing
done --session NAMEMark request complete (with optional message)
detachDetach from current session
start --session NAMECreate session for agent to use later
kill --session NAMEKill session
kill --allKill all sessions
lock --session NAMELock session (agent read-only)
unlock --session NAMEUnlock session

Key Bindings (when attached)

KeyAction
Ctrl+B EnterComplete request (prompt for optional message to agent)
Ctrl+B dDetach (if request still pending, agent's request-wait fails)

Example: Dev Server

term-cli start --session server && term-cli run --session server "npm run dev"
term-cli wait-idle --session server --timeout 15 && term-cli capture --session server
# ... later ...
term-cli send-key --session server C-c && term-cli wait --session server
term-cli kill --session server

Example: Python Debugger

term-cli start --session debug && term-cli run --session debug "python3 -m pdb script.py"
term-cli wait -s debug && term-cli send-text -s debug "b 42" --enter && term-cli wait -s debug
term-cli send-text -s debug "c" --enter && term-cli wait -s debug && term-cli capture -s debug

Example: File Transfer (over SSH)

term-cli start --session remote && term-cli run --session remote "ssh user@server" --wait
term-cli upload --session remote ./deploy.tar.gz /tmp/deploy.tar.gz
term-cli download --session remote /var/log/app.log ./app.log
# Pipe support
cat config.json | term-cli upload --session remote - /app/config.json
term-cli download --session remote /app/data.csv - | head -5

Example: SSH with Password (Agent + Human)

Agent side:

term-cli start --session remote && term-cli run --session remote "ssh user@server"
term-cli wait --session remote && term-cli capture --session remote
# If password prompt shown, request human help; if shell prompt, key auth succeeded
term-cli request --session remote --message "Please enter SSH password"
term-cli request-wait --session remote && term-cli capture --session remote
term-cli run --session remote "ls -la" --wait

Human side:

term-assist list                        # See: "remote: Please enter SSH password"
term-assist attach --session remote     # Join, see status bar with message
# (enter password)
# Press Ctrl+B Enter, then type optional message or just Enter to complete

Example: Human Prepares Session for Agent

Human side:

term-assist start --session prod --locked
term-assist attach --session prod
# (login to server, set up environment, etc.)
# Press Ctrl+B d to detach when ready
term-assist unlock --session prod

Agent side:

term-cli capture --session prod         # See current state
term-cli run --session prod "deploy.sh" --wait --timeout 300
term-cli kill --session prod

Key Features

  • Explicit errors: start fails if session exists; kill fails if not exists
  • Wait strategies: wait (prompt), wait-idle (output settles), wait-for (pattern)
  • Human collaboration: request/request-wait + term-assist for passwords, MFA prompts, manual steps
  • Locked sessions: Human controls, agent observes (start with --locked or use term-assist lock)
  • Dimension preservation: Human joining doesn't resize agent's terminal
  • File transfer: upload/download with gzip compression, SHA-256 verification, and pipe support (- for stdin/stdout)
  • Clean output: Visible screen only, whitespace trimmed, --scrollback N for history
  • Self-documenting: --help on every command

Exit Codes

CodeMeaning
0Success
1Runtime error
2Invalid input
3Timeout
4Human detached while request pending
5Session locked (agent read-only)
127tmux not found

Design Philosophy

  • Two tools: term-cli for agents, term-assist for humans
  • Single files: No dependencies beyond Python stdlib + tmux
  • Self-documenting: Point at --help and go

Versioning

term-cli follows Semantic Versioning. Run term-cli --version or term-assist --version to identify an installation. Releases and their notes are available on GitHub; the maintainer process is documented in RELEASING.md.

Requirements

  • Python 3.8+
  • tmux

License

BSD License — see LICENSE

Contributing

Issues and PRs welcome. This is a small, focused tool: simplicity is a feature.

Files in the repo

Repository payload19 top-level entries
  • .github
  • assets
  • skills
  • tests
  • .gitignore
  • AGENTS.md
  • install.sh
  • LICENSE
  • pyproject.toml
  • pytest.ini
  • README.md
  • release.sh
  • RELEASING.md
  • repro-tmux-manual-size.sh
  • requirements-test.txt
  • run-tests.sh
  • term-assist
  • term-cli
  • VERSION

Discussion (0)

Ask about usage, or say what you built with it

Sign in to join the discussion.

No comments yet. Be the first to say what this is good for.

More tools

JuliusBrussee/
caveman

🪨 why use many token when few token do trick — Claude Code skill that cuts 65% of tokens by talking like caveman

105k
1 add
MemPalace/
mempalace

The best-benchmarked open-source AI memory system. And it's free.

59k
stablyai/
orca

Orca is the ADE for working with a fleet of parallel agents. Run any coding agent with your own subscription. Available on desktop, mobile and remote runtime.

66k

A cross-platform desktop All-in-One assistant for Claude Code, Codex, OpenCode, OpenClaw, Grok Build & Hermes Agent. Only official website: ccswitch.io

132k

Never stop coding. Free MIT AI gateway: one endpoint, 352 providers (150+ free), 1200+ models Kimi, Claude, GPT, Gemini, GLM, DeepSeek, MiniMax. Works with Claude Code, Codex, Cursor, OpenCode, Cline & Copilot. Quota-aware auto-fallback, RTK+Caveman compression saves 15-95% tokens, MCP/A2A, Desktop/PWA. Built by 550+ contributors

64k
headroomlabs-ai/
headroom

Compress tool outputs, logs, files, and RAG chunks before they reach the LLM. 20% fewer tokens for coding agents, 60-95% fewer tokens for JSON, same answers. Library, proxy, MCP server.

71k