Star 历史趋势
数据来源: GitHub API · 生成自 Stargazers.cn
README.md

pi-interactive-shell

Pi Interactive Shell

An extension for Pi coding agent that lets Pi autonomously run interactive CLIs in an observable TUI overlay. Pi controls the subprocess while you watch - take over anytime.

https://github.com/user-attachments/assets/76f56ecd-fc12-4d92-a01e-e6ae9ba65ff4

interactive_shell({ command: 'vim config.yaml' })

Important: the interactive_shell({...}) snippets in this README are tool calls made by Pi (or extension/prompt authors). End users do not type these directly into chat. As a user, ask Pi to run something (for example: "run this in dispatch mode") or use /spawn, /attach, and /dismiss commands.

Why

Some tasks need interactive CLIs - editors, REPLs, database shells, long-running processes. Pi can launch them in an overlay where:

  • User watches - See exactly what's happening in real-time
  • User takes over - Type anything to gain control
  • Agent monitors - Query status, send input, decide when done

Works with any CLI: vim, htop, psql, ssh, docker logs -f, npm run dev, git rebase -i, etc.

Install

pi install npm:pi-interactive-shell

The interactive-shell skill is automatically symlinked to ~/.pi/agent/skills/interactive-shell/.

Requires: Node.js, build tools for node-pty (Xcode CLI tools on macOS).

Modes

Three modes control how the agent engages with a session:

InteractiveHands-FreeDispatch
Agent blocked?Yes — tool call waitsNo — returns immediatelyNo — returns immediately
How agent gets outputTool return valuePolls with sessionIdNotification via triggerTurn
Overlay visible?YesYesYes (or headless with background: true)
User can interact?AlwaysType to take overType to take over
Concurrent sessions?NoOne overlay + queriesMultiple headless, one overlay
Best forEditors, REPLs, SSHDev servers, buildsDelegating to other agents

Interactive is the default. The agent's tool call blocks until the session ends — use this when the agent needs the result right away, or when the user drives the session (editors, database shells).

Hands-free returns immediately so the agent can do other work, but the agent must poll periodically to discover output and completion. Good for processes the agent needs to monitor and react to mid-flight, like watching build output and sending follow-up commands.

Dispatch also returns immediately, but the agent doesn't poll at all. When the session completes — whether by natural exit, quiet detection, timeout, or user intervention — the agent gets woken up with a notification containing the tail output. This is the right mode for delegating a task to a subagent and moving on. For fire-and-forget delegated runs and QA checks, prefer dispatch by default. Add background: true to skip the overlay entirely and run headless.

Quick Start

The examples below show agent-side tool calls. They are not chat commands for end users.

Structured Spawn

For Pi, Codex, and Claude, the agent can use structured spawn params instead of building command strings by hand:

interactive_shell({ spawn: { agent: "pi" }, mode: "interactive" }) interactive_shell({ spawn: { agent: "codex" }, mode: "dispatch" }) interactive_shell({ spawn: { agent: "claude", prompt: "Review the diffs" }, mode: "dispatch" }) interactive_shell({ spawn: { agent: "claude", worktree: true }, mode: "hands-free" }) interactive_shell({ spawn: { mode: "fork" }, mode: "interactive" }) // Pi-only

Structured spawn uses the same resolver and config defaults as the user-facing /spawn command. Raw command is still supported for arbitrary CLIs and custom launch strings.

Interactive

interactive_shell({ command: 'vim package.json' }) interactive_shell({ command: 'psql -d mydb' }) interactive_shell({ command: 'ssh user@server' })

The agent's turn is blocked until the overlay closes. User controls the session directly.

Hands-Free

// Start a long-running process interactive_shell({ command: 'npm run dev', mode: "hands-free", reason: "Dev server" }) // → { sessionId: "calm-reef", status: "running" } // Poll for output (rate-limited to 60s between queries) interactive_shell({ sessionId: "calm-reef" }) // → { status: "running", output: "Server ready on :3000", runtime: 45000 } // Send input when needed interactive_shell({ sessionId: "calm-reef", inputKeys: ["ctrl+c"] }) // Kill when done interactive_shell({ sessionId: "calm-reef", kill: true }) // → { status: "killed", output: "..." }

The overlay opens for the user to watch. The agent checks in periodically. User can type anything to take over control. After taking over a monitored hands-free or dispatch session, press Ctrl+G to return control to the agent.

Dispatch

// Fire off a task interactive_shell({ command: 'pi "Refactor the auth module"', mode: "dispatch", reason: "Auth refactor" }) // → Returns immediately: { sessionId: "calm-reef" } // → Agent ends turn or does other work.

When the session completes, the agent receives a compact notification on a new turn:

Session calm-reef completed successfully (5m 23s). 847 lines of output.

Step 9 of 10
Step 10 of 10
All tasks completed.

Attach to review full output: interactive_shell({ attach: "calm-reef" })

The notification includes a brief tail (last 5 lines) and a reattach instruction. The PTY is preserved for 5 minutes so the agent can attach to review full scrollback.

Dispatch defaults autoExitOnQuiet: true — the session gets a 15s startup grace period, then is killed after output goes silent (8s by default), which signals completion for task-oriented subagents. Tune the grace period with handsFree: { gracePeriod: 60000 } or opt out entirely with handsFree: { autoExitOnQuiet: false }.

The overlay still shows for the user, who can Ctrl+T to transfer output, Ctrl+B to background, take over by typing, or Ctrl+Q for more options. Ctrl+G only becomes meaningful after the user has taken over a monitored hands-free or dispatch session.

Background Dispatch (Headless)

// No overlay — runs completely invisibly interactive_shell({ command: 'pi "Fix all lint errors"', mode: "dispatch", background: true }) // → { sessionId: "calm-reef" } // → User can /attach calm-reef to peek // → Agent notified on completion, same as regular dispatch

Multiple headless dispatches can run concurrently alongside a single interactive overlay. This is how you parallelize subagent work — fire off three background dispatches and process results as each completion notification arrives.

Timeout

Capture output from TUI apps that don't exit cleanly:

interactive_shell({ command: "htop", mode: "hands-free", timeout: 3000 // Kill after 3s, return captured output })

Features

Auto-Exit on Quiet

For fire-and-forget single-task delegations, enable auto-exit to kill the session after 8s of output silence:

interactive_shell({ command: 'cursor-agent -f "Fix the bug in auth.ts"', mode: "hands-free", handsFree: { autoExitOnQuiet: true } })

A 15s startup grace period prevents the session from being killed before the subprocess has time to produce output. Customize it per-call with gracePeriod:

interactive_shell({ command: 'pi "Run the full test suite"', mode: "hands-free", handsFree: { autoExitOnQuiet: true, gracePeriod: 60000 } })

The default grace period is also configurable globally via autoExitGracePeriod in the config file.

For multi-turn sessions where you need back-and-forth interaction, leave it disabled (default) and use kill: true when done.

Send Input

// Text interactive_shell({ sessionId: "calm-reef", input: "SELECT * FROM users;\n" }) // Named keys interactive_shell({ sessionId: "calm-reef", inputKeys: ["ctrl+c"] }) interactive_shell({ sessionId: "calm-reef", inputKeys: ["down", "down", "enter"] }) // Bracketed paste (multiline without execution) interactive_shell({ sessionId: "calm-reef", inputPaste: "line1\nline2\nline3" }) // Hex bytes (raw escape sequences) interactive_shell({ sessionId: "calm-reef", inputHex: ["0x1b", "0x5b", "0x41"] }) // Combine text with keys interactive_shell({ sessionId: "calm-reef", input: "y", inputKeys: ["enter"] })

Configurable Output

// Default: 20 lines, 5KB interactive_shell({ sessionId: "calm-reef" }) // More lines (max: 200) interactive_shell({ sessionId: "calm-reef", outputLines: 100 }) // Incremental pagination (server tracks position) interactive_shell({ sessionId: "calm-reef", outputLines: 50, incremental: true }) // Drain mode (raw stream since last query) interactive_shell({ sessionId: "calm-reef", drain: true })

Transfer Output to Agent

When a subagent finishes work, press Ctrl+T to capture its output and send it directly to the main agent:

[Subagent finishes work]
        ↓
[Press Ctrl+T]
        ↓
[Overlay closes, main agent receives full output]

The main agent then has the subagent's response in context and can continue working with that information.

Configuration:

  • transferLines: Max lines to capture (default: 200)
  • transferMaxChars: Max characters (default: 20KB)

Background Sessions

Sessions can be backgrounded by the user (Ctrl+B, or Ctrl+Q → "Run in background") or by the agent:

// Agent backgrounds an active session interactive_shell({ sessionId: "calm-reef", background: true }) // → Overlay closes, process keeps running // List background sessions interactive_shell({ listBackground: true }) // Reattach with a specific mode interactive_shell({ attach: "calm-reef" }) // interactive (blocking) interactive_shell({ attach: "calm-reef", mode: "hands-free" }) // hands-free (poll) interactive_shell({ attach: "calm-reef", mode: "dispatch" }) // dispatch (notified) // Dismiss background sessions interactive_shell({ dismissBackground: true }) // all sessions interactive_shell({ dismissBackground: "calm-reef" }) // specific session

User can also /spawn to launch the configured default spawn agent, /spawn codex, /spawn claude, /spawn pi, /spawn fork, or /spawn pi fork. Add --worktree to spawn in a separate git worktree, for example /spawn codex --worktree or /spawn pi fork --worktree. Plain /spawn claude stays a normal interactive overlay. fork is Pi-only. Worktrees are left in place and the overlay will tell you where they were created. /attach or /attach <id> reattaches, and /dismiss or /dismiss <id> cleans up from the chat. The keyboard spawn shortcut is separate from /spawn and uses spawn.shortcut.

Prompt-Bearing /spawn

Quoted prompt text plus --hands-free or --dispatch turns /spawn into a monitored delegated run instead of a plain interactive overlay. This shares the same resolver and defaults as structured interactive_shell({ spawn: ... }). Plain /spawn stays interactive. Ctrl+G only applies after you take over one of these monitored sessions.

/spawn claude "review the diffs" --dispatch /spawn codex "fix the failing tests" --hands-free /spawn pi fork "continue from here" --dispatch

Keys

KeyAction
Ctrl+TTransfer & close - capture output and send to main agent
Ctrl+BBackground session (dismiss overlay, keep running)
Ctrl+QSession menu (transfer/background/kill/cancel)
Shift+Up/DownScroll history
Alt+Shift+F (default)Toggle focus between overlay and main chat (focusShortcut)
Ctrl+GReturn to agent monitoring (only after taking over a monitored hands-free or dispatch session)
Alt+Shift+P (default)Launch the configured default spawn agent (spawn.shortcut)
Any key (hands-free)Take over control

Config

Configuration files (project overrides global):

  • Global: ~/.pi/agent/interactive-shell.json
  • Project: .pi/interactive-shell.json

Shortcut settings are pinned at startup. If you change focusShortcut or spawn.shortcut, reload or restart Pi to apply them.

{ "overlayWidthPercent": 95, "overlayHeightPercent": 60, "focusShortcut": "alt+shift+f", "spawn": { "defaultAgent": "pi", "shortcut": "alt+shift+p", "commands": { "pi": "pi", "codex": "codex", "claude": "claude" }, "defaultArgs": { "pi": [], "codex": [], "claude": [] }, "worktree": false, "worktreeBaseDir": "../repo-worktrees" }, "scrollbackLines": 5000, "exitAutoCloseDelay": 10, "minQueryIntervalSeconds": 60, "transferLines": 200, "transferMaxChars": 20000, "completionNotifyLines": 50, "completionNotifyMaxChars": 5000, "handsFreeUpdateMode": "on-quiet", "handsFreeUpdateInterval": 60000, "handsFreeQuietThreshold": 8000, "autoExitGracePeriod": 15000, "handsFreeUpdateMaxChars": 1500, "handsFreeMaxTotalChars": 100000, "handoffPreviewEnabled": true, "handoffPreviewLines": 30, "handoffPreviewMaxChars": 2000, "handoffSnapshotEnabled": false, "ansiReemit": true }
SettingDefaultDescription
overlayWidthPercent95Overlay width (10-100%)
overlayHeightPercent60Overlay height (20-90%)
focusShortcut"alt+shift+f"Toggle focus between overlay and main chat
spawn.defaultAgent"pi"Configured default spawn agent for /spawn, the spawn shortcut, and agent-side structured spawn
spawn.shortcut"alt+shift+p"Keyboard shortcut that launches the configured default spawn agent
spawn.commands.<agent>pi / codex / claudeExecutable or path override per spawn agent
spawn.defaultArgs.<agent>[]Extra default CLI args per spawn agent
spawn.worktreefalseLaunch spawns in a separate git worktree by default
spawn.worktreeBaseDirunsetOptional base directory for generated worktrees
scrollbackLines5000Terminal scrollback buffer
exitAutoCloseDelay10Seconds before auto-close after exit
minQueryIntervalSeconds60Rate limit between agent queries
transferLines200Lines to capture on Ctrl+T transfer (10-1000)
transferMaxChars20000Max chars for transfer (1KB-100KB)
completionNotifyLines50Lines in dispatch completion notification (10-500)
completionNotifyMaxChars5000Max chars in completion notification (1KB-50KB)
handsFreeUpdateMode"on-quiet""on-quiet" or "interval"
handsFreeQuietThreshold8000Silence duration before update (ms)
autoExitGracePeriod15000Startup grace before autoExitOnQuiet kill (ms)
handsFreeUpdateInterval60000Max interval between updates (ms)
handsFreeUpdateMaxChars1500Max chars per update
handsFreeMaxTotalChars100000Total char budget for updates
handoffPreviewEnabledtrueInclude tail in tool result
handoffPreviewLines30Lines in tail preview (0-500)
handoffPreviewMaxChars2000Max chars in tail preview (0-50KB)
handoffSnapshotEnabledfalseWrite transcript on detach/exit
ansiReemittruePreserve ANSI colors in output

How It Works

interactive_shell → node-pty → subprocess
                  ↓
            xterm-headless (terminal emulation)
                  ↓
            TUI overlay (pi rendering)

Full PTY. The subprocess thinks it's in a real terminal.

Example Workflow: Plan, Implement, Review

The examples/prompts/ directory includes three prompt templates that chain together into a complete development workflow using Codex CLI. Each template now loads the bundled gpt-5-4-prompting skill by default, falls back to codex-5-3-prompting when the user explicitly asks for Codex 5.3, and launches Codex in an interactive overlay.

The Pipeline

Write a plan
    ↓
/codex-review-plan path/to/plan.md        ← Codex verifies every assumption against the codebase
    ↓
/codex-implement-plan path/to/plan.md     ← Codex implements the reviewed plan faithfully
    ↓
/codex-review-impl path/to/plan.md        ← Codex reviews the diff against the plan, fixes issues

Installing the Templates

Install the package first so pi can discover the bundled prompt and skill directories via the package metadata:

pi install npm:pi-interactive-shell

If you want your own slash commands and local skill copies, copy the examples into your agent config:

# Prompt templates (slash commands) cp ~/.pi/agent/extensions/interactive-shell/examples/prompts/*.md ~/.pi/agent/prompts/ # Skills used by the templates cp -r ~/.pi/agent/extensions/interactive-shell/examples/skills/codex-cli ~/.pi/agent/skills/ cp -r ~/.pi/agent/extensions/interactive-shell/examples/skills/gpt-5-4-prompting ~/.pi/agent/skills/ cp -r ~/.pi/agent/extensions/interactive-shell/examples/skills/codex-5-3-prompting ~/.pi/agent/skills/

Usage

Say you have a plan at docs/auth-redesign-plan.md:

Step 1: Review the plan — Codex reads your plan, then verifies every file path, API shape, data flow, and integration point against the actual codebase. Fixes issues directly in the plan file.

/codex-review-plan docs/auth-redesign-plan.md
/codex-review-plan docs/auth-redesign-plan.md pay attention to the migration steps

Step 2: Implement the plan — Codex reads all relevant code first, then implements bottom-up: shared utilities first, then dependent modules, then integration code. No stubs, no TODOs.

/codex-implement-plan docs/auth-redesign-plan.md
/codex-implement-plan docs/auth-redesign-plan.md skip test files for now

Step 3: Review the implementation — Codex diffs the changes, reads every changed file in full (plus imports and dependents), traces code paths across file boundaries, and fixes every issue it finds. Pass the plan to verify completeness, or omit it to just review the diff.

/codex-review-impl docs/auth-redesign-plan.md              # review diff against plan
/codex-review-impl docs/auth-redesign-plan.md check cleanup ordering
/codex-review-impl                                          # just review the diff, no plan
/codex-review-impl focus on error handling and race conditions

How They Work

These templates demonstrate a "meta-prompt generation" pattern:

  1. Pi gathers context — reads the plan, runs git diff, and loads the local gpt-5-4-prompting or codex-5-3-prompting skill
  2. Pi generates a calibrated prompt — tailored to the specific plan/diff, following the selected skill's best practices
  3. Pi launches Codex in the overlay — defaulting to -m gpt-5.4 -a never and switching to -m gpt-5.3-codex -a never only when the user explicitly asks for Codex 5.3

The user watches Codex work in the overlay and can take over anytime (type to intervene, Ctrl+T to transfer output back to pi, Ctrl+Q for options).

Customizing

These are starting points. Fork them and adjust:

  • Model/flags — swap gpt-5.3-codex for another model, change reasoning effort
  • Review criteria — add project-specific checks (security policies, style rules)
  • Implementation rules — change the 500-line file limit, add framework-specific patterns
  • Other agents — adapt the pattern for Claude (claude "prompt"), Gemini (gemini -i "prompt"), or any CLI

See the pi prompt templates docs for the full $1, $@ placeholder syntax.

Advanced: Multi-Agent Workflows

For orchestrating multi-agent chains (scout → planner → worker → reviewer) with file-based handoff and auto-continue support, see:

pi-foreground-chains - A separate skill that builds on interactive-shell for complex agent workflows.

Limitations

  • macOS tested, Linux experimental
  • 60s rate limit between queries (configurable)
  • Some TUI apps may have rendering quirks

关于 About

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.

语言 Languages

TypeScript98.3%
JavaScript1.7%

提交活跃度 Commit Activity

代码提交热力图
过去 52 周的开发活跃度
52
Total Commits
峰值: 26次/周
Less
More

核心贡献者 Contributors