Build or adapt a local harness to drive, inspect, and profile an interactive CLI or TUI without external services.
npx -y skills add cursor/plugins --skill control-cli --agent claude-codeInstalls into .claude/skills of the current project.
Use a repeatable local harness to exercise an interactive CLI instead of poking at it manually. First reuse the repo's own test/demo harness if it exists; otherwise assemble a temporary harness from standard local tools.
tmux: managed sessions, capture-pane, send-keys, attach/detach.SESSION="cli-harness-$(date +%s)"
tmux new-session -d -s "$SESSION" -- <command-under-test>
tmux capture-pane -pt "$SESSION"
tmux send-keys -t "$SESSION" "help" Enter
tmux capture-pane -pt "$SESSION"
tmux kill-session -t "$SESSION"
For Node CLIs:
NODE_OPTIONS="--inspect=127.0.0.1:0" tmux new-session -d -s "$SESSION" -- <node-cli-command>
Read the terminal output to find the inspector URL, then use Chrome DevTools-compatible tooling if profiling is needed.
Use a PTY script when you need deterministic waits in a repo that does not have tmux or a demo harness. Keep it temporary unless the user asks to add a reusable test.
import os
import pty
import select
import subprocess
import time
master_fd, slave_fd = pty.openpty()
proc = subprocess.Popen(
["<command>", "<arg>"],
stdin=slave_fd,
stdout=slave_fd,
stderr=slave_fd,
close_fds=True,
)
os.close(slave_fd)
deadline = time.time() + 30
buffer = b""
while time.time() < deadline:
ready, _, _ = select.select([master_fd], [], [], 0.25)
if not ready:
continue
chunk = os.read(master_fd, 4096)
buffer += chunk
if b"<ready text>" in buffer:
os.write(master_fd, b"help\n")
break
print(buffer.decode(errors="replace"))
proc.terminate()
os.close(master_fd)
If the CLI needs richer terminal control, use pty.fork() or an existing PTY library.
/tmp unless the repo already has a testing/demo harness.sickn33/antigravity-awesome-skills
kubesphere/kubesphere
supercent-io/skills-template