pi-interactive-shell 0.4.0 → 0.4.1

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.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,15 @@
2
2
 
3
3
  All notable changes to the `pi-interactive-shell` extension will be documented in this file.
4
4
 
5
+ ## [0.4.1] - 2026-01-17
6
+
7
+ ### Changed
8
+ - **Rendered output for queries** - Status queries now return rendered terminal output (last 20 lines) instead of raw stream. This eliminates TUI animation noise (spinners, progress bars) and gives clean, readable content.
9
+ - **Reduced output size** - Max 20 lines and 5KB per query (down from 100 lines and 10KB). Queries are for checking in, not dumping full output.
10
+
11
+ ### Fixed
12
+ - **TUI noise in query output** - Raw stream captured all terminal animation (spinner text fragments like "Working", "orking", "rking"). Now uses xterm rendered buffer which shows clean final state.
13
+
5
14
  ## [0.4.0] - 2026-01-17
6
15
 
7
16
  ### Added
package/SKILL.md CHANGED
@@ -110,9 +110,11 @@ interactive_shell({ sessionId: "calm-reef" })
110
110
 
111
111
  Returns:
112
112
  - `status`: "running" | "user-takeover" | "exited" | "killed" | "backgrounded"
113
- - `output`: New output since last check (incremental)
113
+ - `output`: Last 20 lines of rendered terminal (clean, no TUI animation noise)
114
114
  - `runtime`: Time elapsed in ms
115
115
 
116
+ **Don't query too frequently!** Wait 30-60 seconds between checks. The user is watching the overlay in real-time - you're just checking in periodically to see progress.
117
+
116
118
  ### Ending a Session
117
119
  ```typescript
118
120
  interactive_shell({ sessionId: "calm-reef", kill: true })
@@ -126,12 +128,12 @@ interactive_shell({ sessionId: "calm-reef", input: "/help\n" })
126
128
  interactive_shell({ sessionId: "calm-reef", input: { keys: ["ctrl+c"] } })
127
129
  ```
128
130
 
129
- ### Context Budget
131
+ ### Query Output
130
132
 
131
- Updates have a **total character budget** (default: 100KB) to prevent overwhelming your context window:
132
- - Each update includes only NEW output since the last update (not full tail)
133
- - Default: 1500 chars max per update, 100KB total budget
134
- - When budget is exhausted, updates continue but without content (status-only)
133
+ Status queries return **rendered terminal output** (what's actually on screen), not raw stream:
134
+ - Last 20 lines of the terminal, clean and readable
135
+ - No TUI animation noise (spinners, progress bars, etc.)
136
+ - Max 5KB per query to keep context manageable
135
137
  - Configure via `handsFree.maxTotalChars`
136
138
 
137
139
  ```typescript
package/index.ts CHANGED
@@ -312,10 +312,13 @@ The user sees the overlay and can:
312
312
  - Kill/background via double-Escape
313
313
 
314
314
  QUERYING SESSION STATUS:
315
- - interactive_shell({ sessionId: "calm-reef" }) - get status + new output
315
+ - interactive_shell({ sessionId: "calm-reef" }) - get status + rendered terminal output (last 20 lines)
316
316
  - interactive_shell({ sessionId: "calm-reef", kill: true }) - end session
317
317
  - interactive_shell({ sessionId: "calm-reef", input: "..." }) - send input
318
318
 
319
+ IMPORTANT: Don't query too frequently! Wait 30-60 seconds between status checks.
320
+ The user is watching the overlay in real-time - you're just checking in periodically.
321
+
319
322
  SENDING INPUT:
320
323
  - interactive_shell({ sessionId: "calm-reef", input: "/help\\n" })
321
324
  - interactive_shell({ sessionId: "calm-reef", input: { keys: ["ctrl+c"] } })
@@ -122,8 +122,7 @@ export class InteractiveShellOverlay implements Component, Focusable {
122
122
  private lastDataTime = 0;
123
123
  private quietTimer: ReturnType<typeof setTimeout> | null = null;
124
124
  private hasUnsentData = false;
125
- // Non-blocking mode: track status and output for agent queries
126
- private agentOutputPosition = 0; // Track last read position for incremental output
125
+ // Non-blocking mode: track status for agent queries
127
126
  private completionResult: InteractiveShellResult | undefined;
128
127
 
129
128
  constructor(
@@ -242,33 +241,26 @@ export class InteractiveShellOverlay implements Component, Focusable {
242
241
 
243
242
  // Public methods for non-blocking mode (agent queries)
244
243
 
245
- // Max output per status query (10KB) - prevents overwhelming agent context
246
- private static readonly MAX_STATUS_OUTPUT = 10 * 1024;
244
+ // Max output per status query (5KB) - prevents overwhelming agent context
245
+ private static readonly MAX_STATUS_OUTPUT = 5 * 1024;
246
+ // Max lines to return per query - keep small, we're just checking in
247
+ private static readonly MAX_STATUS_LINES = 20;
247
248
 
248
- /** Get output since last check (incremental, truncated if too large) */
249
+ /** Get rendered terminal output (last N lines, truncated if too large) */
249
250
  getOutputSinceLastCheck(): { output: string; truncated: boolean; totalBytes: number } {
250
- const fullOutput = this.session.getRawStream({ stripAnsi: true });
251
-
252
- // Handle case where buffer was trimmed and our position is now past the end
253
- // This happens when rawOutput exceeds 1MB and older content is discarded
254
- const clampedPosition = Math.min(this.agentOutputPosition, fullOutput.length);
255
- const newOutput = fullOutput.substring(clampedPosition);
256
- const totalBytes = newOutput.length;
257
-
258
- // Always advance position (even if truncated, we don't want to re-send old data)
259
- this.agentOutputPosition = fullOutput.length;
260
-
261
- // Truncate if too large (keep the END, which is most recent/relevant)
262
- if (newOutput.length > InteractiveShellOverlay.MAX_STATUS_OUTPUT) {
263
- const truncated = newOutput.slice(-InteractiveShellOverlay.MAX_STATUS_OUTPUT);
264
- return {
265
- output: `[...${totalBytes - InteractiveShellOverlay.MAX_STATUS_OUTPUT} bytes truncated...]\n${truncated}`,
266
- truncated: true,
267
- totalBytes,
268
- };
269
- }
251
+ // Use rendered terminal output instead of raw stream
252
+ // This gives clean, readable content without TUI animation garbage
253
+ const lines = this.session.getTailLines({
254
+ lines: InteractiveShellOverlay.MAX_STATUS_LINES,
255
+ ansi: false,
256
+ maxChars: InteractiveShellOverlay.MAX_STATUS_OUTPUT,
257
+ });
258
+
259
+ const output = lines.join("\n");
260
+ const totalBytes = output.length;
261
+ const truncated = lines.length >= InteractiveShellOverlay.MAX_STATUS_LINES;
270
262
 
271
- return { output: newOutput, truncated: false, totalBytes };
263
+ return { output, truncated, totalBytes };
272
264
  }
273
265
 
274
266
  /** Get current session status */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-interactive-shell",
3
- "version": "0.4.0",
3
+ "version": "0.4.1",
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": {