pi-interactive-shell: letting a coding agent drive a real terminal
Pi coding agent extension that allows Pi to autonomously control interactive CLIs in an observable overlay. Full PTY emulation, no tmux, token efficient. User can take over anytime.
At a glance
- What is it?
- pi-interactive-shell is an extension for the Pi coding agent that runs interactive CLIs inside an observable overlay, with full PTY emulation rather than tmux, and four supervision modes that decide how output reaches the agent. The user can type at any moment and take the session over, and the whole toolchain is six runtime dependencies.
- Who is it for?
- Adopt pi-interactive-shell if you drive coding agents that need real terminal programs rather than shell scripts, and you want to watch the session, interrupt it, and decide when the agent has finished. Do not adopt it if your workload is unattended delegation with no human watching, because the overlay and the supervision modes assume a person is present, and note that the licence is not recorded, which matters if you intend to modify it.
- Can I use it commercially?
- Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
- Is it still maintained?
- Yes. The repository last received commits 2 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The problem is that some tools only work with a terminal
Some tasks need interactive CLIs, and the readme names them: editors, REPLs, database shells and long-running processes. A coding agent that can only run a command and read its output is stuck with the subset of tools that cooperate with that, and the tools that would be most useful, an editor, a REPL, an interactive rebase, are exactly the ones that do not.
The fix here is a real pseudo-terminal rather than a workaround. The extension gives Pi a TUI overlay containing the subprocess, and three things happen at once. The user watches, seeing exactly what is happening in real time. The user takes over, typing anything to gain control. And the agent monitors, querying status, sending input and deciding when the job is done.
That last one is the interesting design goal. The agent is not blocked waiting for a command to exit, it is a participant in the session, which is what makes an interactive program usable as a delegated task.
The readme lists what it works with: vim, htop, psql, ssh, docker logs -f, npm run dev and git rebase -i, among others. The project description adds that it is token efficient and uses no tmux, and the token efficiency claim is a consequence of the architecture rather than an optimisation: the agent can be told to wait for a specific event and only be woken then, instead of receiving a stream of output it has to read and discard.
A single call starts a session:
interactive_shell({ command: 'vim config.yaml' })One caveat about that snippet, which the readme is careful about: the interactive_shell calls shown in the documentation are tool calls made by Pi, or written by extension and prompt authors. End users do not type them into chat. A user asks Pi to run something, for example to run this in dispatch mode, or uses the slash commands.
Four modes, and the table is the design
The modes table is the centre of the project, and reading it tells you how the tool thinks about supervision.
Interactive is the default. The agent does not wait, and output reaches the agent through a stable sessionId used for input and status. It is for editors, REPLs and SSH, when the agent or the user will drive the shell.
Hands-free also does not have the agent wait, but output reaches it by polling with the sessionId plus quiet updates. It is for dev servers and builds, where you want to react mid-flight, send input, check logs, or cancel supervision locally when you are ready.
Dispatch returns immediately with no polling at all. The agent is woken via triggerTurn only when the session completes or local supervision ends, whether that is a natural exit, a timeout, quiet detection or user cancellation, and the notification includes a captured tail of the output. This is the default for delegating work to subagents, and adding background: true skips the overlay entirely.
Monitor is also immediate, and the agent is woken when a configured monitor trigger emits an event and when the monitor lifecycle stops. It supports stream triggers, poll-diff checks, first-class file watching, optional cooldowns, persistence controls, detector commands and event history queries, and it runs headless with the option to attach in order to inspect.
The column that says whether the agent waits reads No for all four, and that is the point worth understanding. The agent never blocks on a subprocess in any mode. What varies is how much attention the session demands and how often the agent is interrupted with output it may not need.
Dispatch and Monitor are the token efficient ones, because the agent is only woken on completion or on a specific event. Interactive and Hands-free are the ones where the agent is in a conversation with the program.
Structured spawn, and the warning about running agents in your working tree
The structured spawn mechanism is the most interesting design choice in the readme, and it comes with a caution.
For Pi, Codex, Claude and Cursor, the agent can use structured spawn parameters instead of building command strings by hand:
// User says: "Spawn pi so I can edit files interactively"
interactive_shell({ spawn: { agent: "pi" }, mode: "interactive" })
// User says: "Delegate this refactor to codex and notify me when it's done"
interactive_shell({ spawn: { agent: "codex" }, mode: "dispatch" })The rationale is that a structured spawn lets the extension know what it is launching, so it can apply the right isolation, working directory and notification behaviour. Raw command strings cannot carry that intent.
The caution follows immediately. Structured spawn uses the same resolver and config defaults as the user-facing /spawn command, and raw command is still supported for arbitrary CLIs and custom launch strings. But for unattended coding-agent work in a repository, the readme says to prefer structured spawn with worktree: true or to set an explicitly isolated cwd, because a raw agent command runs in the supplied working directory and can change its Git state.
That is a real hazard, and the readme states it plainly rather than leaving it to be discovered. An agent asked to refactor a repository, given a raw command and pointed at your working tree, can leave the tree in a state you did not want. The worktree option exists to give the spawned agent its own checkout, and the isolated cwd is the fallback for the cases where a worktree is not what you want.
The extension is also extensible in the same way. Any extra key you add under spawn.commands becomes a first-class spawn agent, usable as spawn: { agent: "aider" } and /spawn aider, with its own spawn.defaultArgs entry, worktree support and prompt passthrough. The reserved names are fresh and fork, because those are /spawn keywords, and agent names must start with a letter or digit and may contain letters, digits, dots, underscores and hyphens. Forking your current session stays Pi-only.
PTY emulation without a node-gyp toolchain
The installation is one command, and the dependency choice underneath it is the detail that decides whether this works on your machine.
pi install npm:pi-interactive-shellThe interactive-shell skill is automatically symlinked into the agent's skills directory, and the requirement is Node.js. What the readme stresses is that PTY support uses zigpty prebuilt binaries, so no node-gyp toolchain is required on supported platforms. That is the difference between this working on a fresh machine and not, because a native module that needs compilation brings a compiler, headers and Python into the setup for a tool whose whole purpose is to be installed in seconds.
The runtime dependencies are six, and they explain the design. zigpty provides the pseudo-terminal, the xterm headless package and its serialize addon provide the terminal emulation that renders the subprocess into the overlay, re2js is a regular expression engine with linear time guarantees, and the typesafe AI SDK is there for the semantic features.
The re2js dependency is worth a second look, because it points at a known problem in this space. The tool has a semantic layer, with modules named for semantic actions, events, a supervisor, a policy, a corpus, an evaluator and diagnostics, and a selector for output with its own corpus and evaluator, and an output source store and a selection runtime. A regular expression engine with predictable performance is what you want when the system is inspecting terminal output streams and matching patterns against them, because a backtracking engine on adversarial or merely unusual output can hang.
The peer dependencies are the Pi agent and Pi TUI packages, both at any version, which is the normal arrangement for an extension that has to track a fast moving host. The engines field requires Node 22.19.0 or newer.
A repository with far more files than a small extension needs
The top level of the repository is unusual for an extension, and it is worth understanding what it implies.
The file list is long, and it is organised by concern rather than by layer. The PTY machinery is split across pty-process, pty-session, pty-protocol and pty-log, which is a clean separation of the process handling, the session state, the wire protocol between them and the output capture. The overlay itself is overlay-component with reattach-overlay for reconnecting to a session you have stepped away from.
Then there is a semantic layer with a dozen files: semantic-actions, semantic-events, semantic-supervisor, semantic-policy, semantic-corpus, semantic-evaluator, semantic-diagnostics, plus launch-policy and terminal-observation. Alongside it sits an output selection layer with output-selector, output-source-store, output-selection-runtime and a selector corpus and evaluator. The names jev-client and the scripts evaluate-jev and evaluate-jev-selector point to this being called JEV somewhere in the design, and the presence of a corpus and an evaluator for both layers tells you they are validated against recorded cases rather than being ad hoc heuristics.
The rest of the root is the plumbing: session-manager, session-query, runtime-coordinator, spawn, tool-schema, config, types, key-encoding, notification-utils, handoff-utils, background-widget and a headless-monitor.
The published files list in the manifest mirrors that structure almost exactly, which means the package ships a lot of its own source rather than only a bundle, and the pi field in the manifest registers the extension entry point and the skills directory, plus a video reference for the marketplace listing.
The practical reading is that this is a project with a substantial internal model of what a terminal session is, what the agent should notice about it and what output is worth forwarding. That is where the token efficiency comes from, and it is also why the repository looks larger than the feature list suggests.
Editorial conclusion
Adopt pi-interactive-shell if you drive coding agents that need real terminal programs rather than shell scripts, and you want to watch the session, interrupt it, and decide when the agent has finished. Do not adopt it if your workload is unattended delegation with no human watching, because the overlay and the supervision modes assume a person is present, and note that the licence is not recorded, which matters if you intend to modify it. Before you commit, install it with the pi install command, try the interactive mode with a harmless command like vim on a scratch file, and read the mode table so you pick the right supervision level for each task.
Frequently asked questions
What does pi-interactive-shell do?
It is an extension for the Pi coding agent that lets Pi autonomously run interactive CLIs in an observable TUI overlay. Pi controls the subprocess while you watch, and you can take over at any time. It works with any CLI, including vim, htop, psql, ssh, docker logs -f, npm run dev and git rebase -i.
How do I install pi-interactive-shell?
With pi install npm:pi-interactive-shell. The interactive-shell skill is then automatically symlinked into the agent's skills directory. Node.js is required, and PTY support uses zigpty prebuilt binaries, so no node-gyp toolchain is needed on supported platforms.
What are the supervision modes?
There are four. Interactive is the default, with a stable sessionId for input and status, for editors, REPLs and SSH. Hands-free polls with the sessionId plus quiet updates, for dev servers and builds. Dispatch returns immediately and wakes the agent on completion via triggerTurn, with a captured tail of the output. Monitor wakes the agent on structured monitor trigger events and runs headless.
What is structured spawn and why does the readme warn about it?
Structured spawn lets the agent launch a known agent such as pi, codex, claude or cursor with named parameters instead of a hand built command string. The readme warns that for unattended work in a repository you should prefer structured spawn with worktree: true or an explicitly isolated cwd, because a raw agent command runs in the supplied working directory and can change its Git state.
Do I type the interactive_shell calls into the chat?
No. The readme is explicit that those snippets are tool calls made by Pi or written by extension and prompt authors. As a user you ask Pi to run something, for example to run it in dispatch mode, or you use the slash commands.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/nicobailon-pi-interactive-shell)Was this useful?