Comment by d4rkp4ttern
1 day ago
I learned about Tmux just a few weeks ago and found out that one of the nifty features is that it is scriptable, I.e allows programmatically sending keystrokes to a specific pane. Then, inspired by some Japanese forums I asked myself if I can leverage this to have Claude Code actually interact with an interactive CLI script — we know CC can launch a script via bash but if said script waits for user input then CC can’t (easily) interact with it. Turns out yes we can leverage Tmux for this!
So I used Claude Code to build a little el tool called Tmux-cli, which gives a convenient way to have CC (or any CLI coding agent for that matter) spawn a Tmux Pane, launch a script there, and actually interact with it.
So it’s like Playwright/Puppeteer for the terminal.
You can get it via
uv tool install claude-code-tools
https://github.com/pchalasani/claude-code-tools
There are some interesting possibilities this enables:
Let CC autonomously test interactive CLI scripts, without me having to intervene and point out errors.
Have the CLI coding agent launch UI from another pane and then use Puppeteer MCP to test from a browser.
Let CC launch a cli script with a debugger enabled (e.g. Pdb) and set breakpoints etc — for token-efficient code understanding, debugging and explaining.
Let the CLI coding agent spawn and drive another instance of the same or other CLI coding agent, AND interact with it. Note this is way better than CC sub-agents which are “spawn and let go” black-boxes.
I wonder if the discussed Tmux alternatives enable building this type of tool.
> and found out that one of the nifty features is that it is scriptable, I.e allows programmatically sending keystrokes to a specific pane
In case anyone was curious, screen can do this too with the command "stuff" (read it as the verb like "stuffing something into a box").
Yup, another fun thing to do w/ this: let Claude Code talk to and control Gemini CLI, OpenCode, other CC instances, etc. in interactive mode! A different flavor of subagent. :)
Indeed, or vice versa where we leverage Gemini’s monster context length
Make sure you use the pipe operator.
Very cool ideas in this thread.
Do you find the tmux-cli wrapper to improve results?
I tell Claude to use the existing tmux CLI to send-keys, capture-pane, etc. and it works flawlessly. Literally just "never use the Bash tool, run all commands in tmux sessions" and it knows what to do from there.
One other thing I found is that when it spawns another Claude in a pane, and sends it a message, the enter key doesn’t register if sent immediately, so the other Claude doesn’t act on it. So in Tmux-cli I added a delay after experimenting with various values. I guess with plain Tmux it might run into this issue.
This is nice to know. I didn’t compare with plain Tmux but should. In Tmux-cli I set up some convenience functions and scaffolding to prevent accidentally killing itself etc. But yes if plain Tmux works well I would just use that; it’s one less context burden.
If you're interested in doing similar things but with a terminal, the Kitty remote control mechanism is pretty cool: https://sw.kovidgoyal.net/kitty/remote-control/
I'm reviewing the docs and interested in the scripting. I like that it uses python to script.
Could I have kitty send each line it receives to an external tool, say via HTTP?
I want to make a custom frontend to claude code, or any other CLI tool, and an obvious easy frontend is a web tool that communicates over HTTP, so getting claude wrapped in a HTTP control system seems like a good starting point.
I'm interested in whether things like "tmux capture-pane" which strips characters come from Kitty as well? Do I need to be cautious of control characters?
> So it’s like Playwright/Puppeteer for the terminal
I mean, a tty is just a file descriptor... there have been script(1), expect(1) and chat(8) since the 80ies. tmux is not really necessary.
And screen(1) https://linux.die.net/man/1/screen
Don't forget tmux(1) https://github.com/tmux/tmux/wiki
4 replies →
"tmux capture-pane" strips escape sequences that break the terminal and sets all the right variables; try using expect with e.g. neovim
I did use a shell script and script(1) to automate vi. Don't see the issue?
You right, it's pseudo terminal needed. The module pty of python can do this
These are all great. If you need to do something more involved, pexpect is also worth mentioning. It's a reimplementation of expect in python that's easy to be productive with quickly.
I used it in a previous job to automate configuring thousands of network devices
Your scientists were so preoccupied with whether or not they could, they didn't stop to think if they should.
Nice. Had to look it up, didn’t know it was a famous Jurassic Park quote, even though I did see it when it came out :)
Right back at you. I think its a pretty interesting application.