pi-interactive-shell 0.4.3 → 0.4.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +109 -120
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,17 +1,31 @@
1
- # Pi Interactive Shell Overlay
1
+ # Pi Interactive Shell
2
2
 
3
- An extension for [pi-coding-agent](https://github.com/badlogic/pi-mono/) that runs AI coding agents (Claude Code, Gemini CLI, Codex, Aider, etc.) as **foreground subagents** inside a TUI overlay. The user sees the agent working in real-time and can take over control at any time.
3
+ An extension for [Pi coding agent](https://github.com/badlogic/pi-mono/) that lets Pi run any interactive CLI in a TUI overlay - including other AI agents. Drive Claude, Gemini, Codex, Cursor directly from Pi. Watch it work, take over anytime. Real PTY, full terminal emulation, no tmux needed.
4
4
 
5
- This is distinct from **background subagents** (the `subagent` tool) which run pi instances invisibly.
5
+ ```typescript
6
+ interactive_shell({ command: 'agent "fix all the bugs"', mode: "hands-free" })
7
+ // Returns immediately with sessionId
8
+ // User watches in overlay, you query for status
9
+ // Session auto-closes when agent finishes
10
+ ```
11
+
12
+ ## Why
13
+
14
+ AI agents delegating to other AI agents is powerful but messy:
15
+
16
+ - **Visibility** - What's the subagent doing? Is it stuck?
17
+ - **Control** - User needs to intervene. How?
18
+ - **Integration** - When does the parent agent check in?
19
+
20
+ Interactive Shell solves all three:
6
21
 
7
- ## Foreground vs Background Subagents
22
+ **Real-Time Overlay** - User sees the subprocess in a TUI overlay. Full terminal emulation via xterm-headless. ANSI colors, cursor movement, everything.
8
23
 
9
- | | Foreground (`interactive_shell`) | Background (`subagent`) |
10
- |---|---|---|
11
- | **Visibility** | User sees overlay | Hidden |
12
- | **Agents** | Any CLI agent | Pi only |
13
- | **Output** | Incremental updates | Full capture |
14
- | **User control** | Can intervene | None |
24
+ **Seamless Takeover** - Type anything to take control. Scroll with Shift+Up/Down. Double-Escape to detach.
25
+
26
+ **Non-Blocking API** - Start a session, get a sessionId, query for status. Rate-limited to prevent spam. Auto-exits when output stops.
27
+
28
+ **Any CLI** - Not just AI agents. Run `htop`, `vim`, `psql`, `ssh` - anything interactive.
15
29
 
16
30
  ## Install
17
31
 
@@ -19,153 +33,111 @@ This is distinct from **background subagents** (the `subagent` tool) which run p
19
33
  npx pi-interactive-shell
20
34
  ```
21
35
 
22
- This installs the extension to `~/.pi/agent/extensions/interactive-shell/`, runs `npm install` for dependencies, and creates the skill symlink.
23
-
24
- **Requirements:** `node-pty` requires build tools (Xcode Command Line Tools on macOS).
36
+ Installs to `~/.pi/agent/extensions/interactive-shell/`.
25
37
 
26
- **Manual install:** If you prefer, clone/copy the files manually and run `npm install` in the extension directory.
38
+ **Requires:** Node.js, build tools for `node-pty` (Xcode CLI tools on macOS).
27
39
 
28
- ## Usage
40
+ ## Quick Start
29
41
 
30
- ### Tool: `interactive_shell`
42
+ ### Hands-Free (Agent-to-Agent)
31
43
 
32
- **Start a new session:**
33
- - `command` (string, required): CLI agent command
34
- - `cwd` (string): working directory
35
- - `name` (string): session name (used in sessionId)
36
- - `reason` (string): shown in overlay header (UI-only, not passed to subprocess)
37
- - `mode` (string): `"interactive"` (default) or `"hands-free"`
38
- - `timeout` (number): auto-kill after N milliseconds (for TUI commands that don't exit)
39
- - `handsFree` (object): options for hands-free mode
40
- - `updateMode` (string): `"on-quiet"` (default) or `"interval"`
41
- - `updateInterval` (number): max ms between updates, fallback for on-quiet (default: 60000)
42
- - `quietThreshold` (number): ms of silence before emitting update in on-quiet mode (default: 5000)
43
- - `updateMaxChars` (number): max chars per update (default: 1500)
44
- - `maxTotalChars` (number): total char budget for all updates (default: 100000)
45
- - `handoffPreview` (object): tail preview in tool result
46
- - `handoffSnapshot` (object): write transcript to file
44
+ ```typescript
45
+ // Start - returns immediately
46
+ interactive_shell({
47
+ command: 'pi "Refactor the auth module"',
48
+ mode: "hands-free"
49
+ })
50
+ // { sessionId: "calm-reef", status: "running" }
47
51
 
48
- **Send input to active session:**
49
- - `sessionId` (string, required): session ID from hands-free updates
50
- - `input` (string | object): input to send
51
- - As string: raw text/keystrokes (e.g., `"/model\n"`)
52
- - As object: `{ text?, keys?, hex?, paste? }`
52
+ // Query status (rate-limited to 60s)
53
+ interactive_shell({ sessionId: "calm-reef" })
54
+ // { status: "running", output: "...", runtime: 45000 }
53
55
 
54
- **Change settings mid-session:**
55
- - `sessionId` (string, required): session ID
56
- - `settings` (object): `{ updateInterval?, quietThreshold? }`
56
+ // Get more output
57
+ interactive_shell({ sessionId: "calm-reef", outputLines: 100 })
57
58
 
58
- **Query session status:**
59
- - `sessionId` (string, required): session ID
60
- - `outputLines` (number): lines to return (default: 20, max: 200)
61
- - `outputMaxChars` (number): max chars to return (default: 5KB, max: 50KB)
62
- - `kill` (boolean): kill the session and return final output
59
+ // Kill when done (or let autoExitOnQuiet handle it)
60
+ interactive_shell({ sessionId: "calm-reef", kill: true })
61
+ ```
63
62
 
64
- ### Command: `/attach`
63
+ ### Interactive (User Control)
65
64
 
66
- Reattach to background sessions:
65
+ ```typescript
66
+ interactive_shell({ command: 'vim package.json' })
67
67
  ```
68
- /attach
69
- /attach <id>
68
+
69
+ ### Send Input
70
+
71
+ ```typescript
72
+ interactive_shell({ sessionId: "calm-reef", input: "/help\n" })
73
+ interactive_shell({ sessionId: "calm-reef", input: { keys: ["ctrl+c"] } })
74
+ interactive_shell({ sessionId: "calm-reef", input: { keys: ["down", "down", "enter"] } })
70
75
  ```
71
76
 
72
- ## Modes
77
+ ## CLI Reference
73
78
 
74
- ### Interactive (default)
79
+ | Agent | Interactive | With Prompt | Headless (use bash) |
80
+ |-------|-------------|-------------|---------------------|
81
+ | `claude` | `claude` | `claude "prompt"` | `claude -p "prompt"` |
82
+ | `gemini` | `gemini` | `gemini -i "prompt"` | `gemini "prompt"` |
83
+ | `codex` | `codex` | `codex "prompt"` | `codex exec "prompt"` |
84
+ | `agent` | `agent` | `agent "prompt"` | `agent -p "prompt"` |
85
+ | `pi` | `pi` | `pi "prompt"` | `pi -p "prompt"` |
75
86
 
76
- User supervises and controls the session directly.
87
+ ## Features
77
88
 
78
- ```typescript
79
- interactive_shell({ command: 'pi "Review this code"' })
80
- ```
89
+ ### Auto-Exit on Quiet
81
90
 
82
- ### Hands-Free (Foreground Subagent)
91
+ Sessions auto-close after 5s of silence. Disable with `handsFree: { autoExitOnQuiet: false }`.
83
92
 
84
- Agent monitors with periodic updates. User sees the overlay and can take over by typing. **Default to `pi`** unless user requests a different agent.
93
+ ### Timeout for TUI Capture
85
94
 
86
95
  ```typescript
87
96
  interactive_shell({
88
- command: 'pi "Fix all lint errors in src/"',
97
+ command: "pi --help",
89
98
  mode: "hands-free",
90
- reason: "Fixing lint errors"
99
+ timeout: 5000 // Kill after 5s, return captured output
91
100
  })
92
101
  ```
93
102
 
94
- **Update modes:**
95
- - `on-quiet` (default): Emit update after 5s of output silence. Perfect for agent-to-agent delegation.
96
- - `interval`: Emit on fixed schedule (every 60s). Use when continuous output is expected.
97
-
98
- **Context budget:**
99
- - Updates include only NEW output since last update (incremental)
100
- - Default: 1500 chars per update, 100KB total budget
101
- - When budget exhausted, updates continue but without content
102
-
103
- **Status updates (all include `sessionId`):**
104
- - Initial update - sent immediately when session starts
105
- - `status: "running"` - incremental output
106
- - `status: "user-takeover"` - user typed something
107
- - `status: "exited"` - process finished
108
-
109
- ### Sending Input to Active Sessions
110
-
111
- Use `sessionId` from updates to send input:
103
+ ### Configurable Output
112
104
 
113
105
  ```typescript
114
- // Text input
115
- interactive_shell({ sessionId: "calm-reef", input: "/help\n" })
106
+ // Default: 20 lines, 5KB
107
+ interactive_shell({ sessionId: "calm-reef" })
116
108
 
117
- // Named keys
118
- interactive_shell({ sessionId: "calm-reef", input: { text: "/model", keys: ["enter"] } })
109
+ // More lines (max: 200)
110
+ interactive_shell({ sessionId: "calm-reef", outputLines: 100 })
119
111
 
120
- // Navigate menus
121
- interactive_shell({ sessionId: "calm-reef", input: { keys: ["down", "down", "enter"] } })
122
-
123
- // Hex bytes for raw escape sequences
124
- interactive_shell({ sessionId: "calm-reef", input: { hex: ["0x1b", "0x5b", "0x41"] } })
125
-
126
- // Bracketed paste (prevents auto-execution)
127
- interactive_shell({ sessionId: "calm-reef", input: { paste: "multi\nline\ntext" } })
112
+ // More content (max: 50KB)
113
+ interactive_shell({ sessionId: "calm-reef", outputMaxChars: 30000 })
128
114
  ```
129
115
 
130
- **Named keys:** `up`, `down`, `left`, `right`, `enter`, `escape`, `tab`, `backspace`, `delete`, `home`, `end`, `pageup`, `pagedown`, `f1`-`f12`, `ctrl+c`, `ctrl+d`, etc.
131
-
132
- **Keypad keys:** `kp0`-`kp9`, `kp/`, `kp*`, `kp-`, `kp+`, `kp.`, `kpenter`
116
+ ### Input Methods
133
117
 
134
- **tmux-style aliases:** `ppage`/`npage` (PageUp/PageDown), `ic`/`dc` (Insert/Delete), `bspace` (Backspace), `btab` (Shift+Tab)
118
+ | Method | Example |
119
+ |--------|---------|
120
+ | Text | `input: "/model\n"` |
121
+ | Keys | `input: { keys: ["enter", "ctrl+c"] }` |
122
+ | Hex | `input: { hex: ["0x1b", "0x5b", "0x41"] }` |
123
+ | Paste | `input: { paste: "multi\nline" }` |
135
124
 
136
- **Modifiers:** `ctrl+x`, `alt+x`, `shift+tab`, `ctrl+alt+delete` (or shorthand: `c-x`, `m-x`, `s-tab`)
125
+ ### Background Sessions
137
126
 
138
- ### Change Settings Mid-Session
139
-
140
- ```typescript
141
- interactive_shell({ sessionId: "calm-reef", settings: { updateInterval: 30000 } })
142
- interactive_shell({ sessionId: "calm-reef", settings: { quietThreshold: 3000 } })
143
- ```
127
+ 1. Double-Escape "Run in background"
128
+ 2. `/attach` or `/attach <id>` to reattach
144
129
 
145
130
  ## Config
146
131
 
147
- Global: `~/.pi/agent/interactive-shell.json`
148
- Project: `<cwd>/.pi/interactive-shell.json`
132
+ `~/.pi/agent/interactive-shell.json`
149
133
 
150
134
  ```json
151
135
  {
152
- "doubleEscapeThreshold": 300,
153
- "exitAutoCloseDelay": 10,
154
- "overlayWidthPercent": 95,
155
136
  "overlayHeightPercent": 45,
137
+ "overlayWidthPercent": 95,
156
138
  "scrollbackLines": 5000,
157
- "ansiReemit": true,
158
- "handoffPreviewEnabled": true,
159
- "handoffPreviewLines": 30,
160
- "handoffPreviewMaxChars": 2000,
161
- "handoffSnapshotEnabled": false,
162
- "handoffSnapshotLines": 200,
163
- "handoffSnapshotMaxChars": 12000,
164
- "handsFreeUpdateMode": "on-quiet",
165
- "handsFreeUpdateInterval": 60000,
166
- "handsFreeQuietThreshold": 5000,
167
- "handsFreeUpdateMaxChars": 1500,
168
- "handsFreeMaxTotalChars": 100000
139
+ "minQueryIntervalSeconds": 60,
140
+ "handsFreeQuietThreshold": 5000
169
141
  }
170
142
  ```
171
143
 
@@ -173,7 +145,24 @@ Project: `<cwd>/.pi/interactive-shell.json`
173
145
 
174
146
  | Key | Action |
175
147
  |-----|--------|
176
- | `Esc` twice | Detach dialog (kill/background/cancel) |
177
- | `Shift+Up/Down` | Scroll (no takeover in hands-free) |
178
- | `Ctrl+C` | Forwarded to subprocess |
179
- | Any other key (hands-free) | Triggers user takeover |
148
+ | Double-Escape | Detach dialog |
149
+ | Shift+Up/Down | Scroll history |
150
+ | Any key (hands-free) | Take over control |
151
+
152
+ ## How It Works
153
+
154
+ ```
155
+ interactive_shell → node-pty → subprocess
156
+
157
+ xterm-headless (terminal emulation)
158
+
159
+ TUI overlay (pi rendering)
160
+ ```
161
+
162
+ Full PTY. The subprocess thinks it's in a real terminal.
163
+
164
+ ## Limitations
165
+
166
+ - macOS tested, Linux experimental
167
+ - 60s rate limit between queries (configurable)
168
+ - Some TUI apps may have rendering quirks
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-interactive-shell",
3
- "version": "0.4.3",
3
+ "version": "0.4.5",
4
4
  "description": "Run AI coding agents as foreground subagents in pi TUI overlays with hands-free monitoring",
5
5
  "type": "module",
6
6
  "bin": {