Files
pi-config/extensions/pi-interactive-shell/CHANGELOG.md

45 KiB

Changelog

All notable changes to the pi-interactive-shell extension will be documented in this file.

[Unreleased]

[0.13.0] - 2026-04-23

Changed

  • Bundled runtime skills now live under skills/, with only the canonical pi-interactive-shell skill auto-registered. The Codex workflow skills remain packaged under examples/skills/ as opt-in copies alongside the example prompt templates.
  • Codex docs now include gpt-image-2 guidance across the optional codex-cli example skill plus the shared README and interactive-shell skill, covering natural-language prompting, $imagegen, and -i reference-image workflows.
  • Replaced the legacy @sinclair/typebox runtime dependency with typebox.
  • Upgraded zigpty from ^0.0.6 to ^0.1.6 to pick up newer PTY prebuilds, including the Linux x64 path affected by the reported SIGILL crash.
  • Added first-class Cursor spawn support (spawn.agent: "cursor" and /spawn cursor) mapped to the Cursor CLI agent executable by default, with default args set to --model composer-2-fast, fresh/worktree support, and Pi-only fork preserved.
  • Added an optional examples/skills/cursor-cli reference skill and updated spawn docs/tool help/tests so Cursor is treated as a peer to Pi/Codex/Claude in structured spawn flows.
  • Updated the optional codex-cli example skill to prefer gpt-5.5 for Codex CLI work.

Fixed

  • Migrated the interactive-shell tool schema from @sinclair/typebox to typebox 1.x so packaged installs follow Pi's current extension runtime contract.

Removed

  • Removed the legacy npm bin installer (scripts/install.js) and its package metadata. pi install npm:pi-interactive-shell is now the only supported installation path.

[0.12.0] - 2026-04-12

Added

  • Inline threshold trigger support for regex monitors via threshold: { captureGroup, op, value } with lt, lte, gt, and gte operators.
  • First-class file-watch monitor strategy with monitor.fileWatch config (path, recursive, events) and compact event lines (EVENT path).
  • Monitor lifecycle notifications (interactive-shell-monitor-lifecycle) with explicit terminal reasons: stream-ended, script-failed, stopped, and timed-out.
  • New monitor query fields: monitorStatus, monitorSinceEventId, and monitorTriggerId.

Changed

  • Monitor mode now allows generated internal commands for file-watch, so users can start file watchers without providing a shell command.
  • Monitor validation is now stricter for strategy-specific config (fileWatch and poll usage) and threshold trigger requirements.
  • Monitor coordinator now tracks per-session monitor state (status, strategy, trigger ids, event count, last event metadata, terminal reason).
  • Background session UI/listing now renders monitor sessions with monitor-specific context (strategy/event count) instead of plain generic running/exited labels.

[0.11.1] - 2026-04-12

Changed

  • Monitor event callback now guards against emitting after the monitor is disposed, preventing stale queued notifications from a dismissed session.
  • Poll-diff strategy now wraps the command in a recurring loop and diffs per-interval samples instead of accumulating full PTY output.
  • Monitor event history cleanup retries until referenced monitor/session/active entries are gone, preventing history leaks from one-shot timers firing too early.

Fixed

  • Fixed await on already-resolved detector command promise (removed unnecessary await on non-async return).

[0.11.0] - 2026-04-11

Added

  • New mode: "monitor" for interactive_shell to run headless background commands and wake the agent only when output lines match monitorFilter.
  • New monitorFilter tool parameter supporting plain-text substring matching and /regex/flags matching.
  • Monitor event notifications now wake the agent with triggerTurn and include sessionId, matched text, and the matched line.
  • Regression coverage for monitor mode startup validation and ANSI-stripped line matching.
  • Regression coverage for suppressing repeated wakeups when the exact same cleaned matching line is emitted more than once in a single monitor session.

Changed

  • README, tool help, and the bundled examples/skills/interactive-shell/SKILL.md now document monitor mode usage, event-driven behavior, and monitor session lifecycle with existing background-session APIs.
  • Monitor mode now suppresses repeated wakeups for the exact same cleaned matching line within a single monitor session, while still waking on distinct matching lines.

Fixed

  • Slash-prefixed plain-text filters like /tmp/log are now treated as literal text instead of being misparsed as regex literals.
  • Invalid monitor regex errors now preserve the underlying parser message for easier debugging.

[0.10.8] - 2026-04-09

Added

  • submit tool parameter for interactive_shell session input so the agent can type text and press Enter in one call, avoiding the common failure mode where commands are left sitting in editor-based TUIs like pi.
  • Regression tests covering submit: true for plain text input and bracketed paste input.

Changed

  • PTY backend switched from node-pty to zigpty in pty-session.ts, keeping the existing PtyTerminalSession behavior and higher-level interactive_shell API unchanged.
  • Input docs now explicitly state that raw input only types text and does not submit it.
  • README, SKILL.md, and tool help now prefer submit: true or inputKeys: ["enter"] over relying on \n for command submission.
  • The registered interactive_shell prompt snippet now nudges agents to use submit=true when sending slash commands or prompts to an existing session.
  • Structured input now emits bracketed paste content before trailing key presses, so combinations like paste-plus-Enter submit in the expected order.

Removed

  • Removed the node-pty macOS spawn-helper permission workaround from runtime and install scripts (spawn-helper.ts, scripts/fix-spawn-helper.cjs, and the postinstall hook).

[0.10.7] - 2026-04-04

Added

  • Prompt-bearing monitored spawn for /spawn, so users can launch delegated hands-free or dispatch sessions like /spawn claude "review the diffs" --dispatch without dropping down to raw tool calls.
  • Native startup prompt support on structured interactive_shell spawn params via spawn.prompt for Pi, Codex, and Claude.

Changed

  • /spawn now parses quoted positional prompt text plus --hands-free or --dispatch, while plain /spawn remains an interactive overlay launch.
  • README and tool docs now spell out that /spawn and structured spawn share the same resolver semantics, and that Ctrl+G only applies after taking over a genuinely monitored session.
  • README now includes a dedicated prompt-bearing /spawn subsection so the interactive vs monitored split is easier to find.

[0.10.6] - 2026-04-04

Added

  • Multi-agent spawn support for pi, Codex CLI, and Claude Code. /spawn can now launch the configured default agent, accept explicit agent overrides like /spawn codex, and support --worktree for spawning into a separate git worktree.
  • First-class spawn params on the interactive_shell tool so the agent can use the same spawn abstraction directly instead of building raw command strings by hand.
  • Regression coverage for dispatch background recovery when a backgrounded session cannot be looked up after overlay teardown.

Changed

  • Spawn config now lives under a nested spawn object with defaultAgent, shortcut, commands, defaultArgs, worktree, and worktreeBaseDir.
  • The spawn shortcut now launches the configured default spawn agent instead of always launching Pi.
  • Pi-only fork validation is shared between /spawn and the interactive_shell tool, so fork now fails fast with a clear error for Codex and Claude.
  • README and tool schema examples now document structured spawn usage, multi-agent /spawn commands, and worktree settings.

Fixed

  • Pi fork now validates the persisted source session before creating a worktree, so failed fork attempts no longer leave stray worktrees behind.
  • Dispatch background recovery now releases the source session and disposes stale monitor state if the expected background session entry is missing after handoff.
  • Generated worktree paths now include enough uniqueness to avoid collisions during rapid repeated spawns.

[0.10.5] - 2026-04-04

Added

  • spawnShortcut config setting for the fresh-session overlay shortcut. Defaults to alt+shift+p and is pinned at startup like focusShortcut, so changes apply on reload or restart.

Changed

  • Fresh-session shortcut registration now reads from config at startup instead of a hardcoded constant, so custom spawnShortcut values are applied consistently.
  • Docs and config parity tests now cover spawnShortcut defaults and README alignment.

Fixed

  • Overlay row/header rendering now clamps metadata and row content at narrow widths, preventing visual overflow when focus badge + PID metadata are wider than the available space.

[0.10.4] - 2026-04-04

Fixed

  • Focus shortcut handling now uses a terminal input listener while the overlay is open, so the configured focusShortcut toggles focus/unfocus reliably even when editor-level shortcuts would not fire. The default shortcut is now alt+shift+f instead of `alt+`` for better terminal compatibility on macOS and to avoid Pi keybinding conflicts.
  • Overlay shortcut interception now ignores raw key release and key repeat events, which prevents the focus toggle from firing twice on Kitty-enabled terminals and cancelling itself out.
  • Overlay focus state is now more obvious visually: the shell shows a persistent SHELL FOCUSED or EDITOR FOCUSED badge and switches to a stronger border treatment when focused.
  • alt+/ side chat is blocked while pi-interactive-shell is open and shows a warning instead of opening on top of the shell overlay.

[0.10.3] - 2026-04-04

Changed

  • Added a promptSnippet for interactive_shell so Pi 0.59+ includes the tool in the default prompt tool list and keeps delegation guidance explicit (dispatch preferred by default).

[0.10.2] - 2026-04-04

Added

  • Focus switching — configurable focusShortcut (default alt+shift+f) toggles focus between overlay and main chat. Same shortcut inside the overlay unfocuses back. Overlay uses nonCapturing mode with handle-based focus control.
  • /spawn command — launch pi in an overlay with /spawn (fresh session) or /spawn fork (fork current session with platform-aware shell quoting).
  • Alt+Shift+P shortcut — quick-launch a fresh pi session overlay.
  • Return-to-agent control — after taking over a hands-free session, press Ctrl+G or select "Return control to agent" from the Ctrl+Q menu to resume agent monitoring. Re-registers session in streaming mode and restarts hands-free update timers.
  • agent-resumed status — new HandsFreeUpdate.status value emitted when the user returns control to the agent. Handled in both streaming and non-blocking notification paths.
  • Transfer output from commandsCtrl+T transfer results from /spawn and /attach now flow back into the agent conversation via shared emitTransferredOutput() helper, matching the tool-call behavior.
  • Per-session completion suppressionagentHandledCompletion moved from a single flag to a Set<string> on the coordinator, so concurrent sessions can't interfere with each other's notification paths.
  • Stale monitor cleanupdisposeStaleMonitor() helper cleans up orphan headless monitors and their active-session registrations when a background session has already been removed.
  • 3 new test files (10 tests): spawn-command.test.ts (fresh, fork, quoting, persist guard, transfer forwarding), command-session-selection.test.ts (IDs containing delimiters), kill-session-suppression.test.ts (conditional mark on incomplete/complete sessions).

Changed

  • /attach and /dismiss selection uses structured { id, label } option mapping with .find() instead of parsing rendered label strings by delimiter. Session IDs containing - or ( no longer break selection.
  • Kill suppression is conditional on completion state — markAgentHandledCompletion only set when session.getResult() is not yet available, preventing leaked suppression tokens for already-completed sessions.
  • spawn-helper.ts uses inline ENOENT narrowing instead of single-use getErrnoCode helper.
  • Dynamic dialog footer height (dialogOptions.length + 2) in the overlay accommodates the variable return-to-agent option. Reattach overlay keeps the static FOOTER_LINES_DIALOG constant (always 4 options).
  • Flattened nested if/else in footer rendering for both overlay components.
  • createOverlayUiOptions() deduplicates overlay UI configuration across all call sites.
  • runtime-coordinator.ts manages overlay focus via OverlayHandle (focus, unfocus, set, clear).
  • Config parse errors now pass the full error object to console.error instead of String(error).
  • Shutdown kill failure preserves slug reservation to prevent ID collision with potentially still-running sessions.
  • Removed legacy session_switch lifecycle setup and rely on immutable-session session_start reinitialization for background widget setup.

Fixed

  • Duplicate completion notifications on monitored attach + transfer (transfer now marks agentHandledCompletion before monitor fires).
  • Cancelled dispatch sessions reported as "completed" — now correctly reports "was killed".
  • Stale headless monitors leaked when the corresponding background session was already cleaned up.
  • Zombie active-session registrations left behind on stale monitor disposal.
  • PTY event handlers not reset on attach failure recovery, causing stale overlay callbacks on disposed components.

[0.10.1] - 2026-03-13

Fixed

  • Skill name mismatch - SKILL.md declared name: interactive-shell but pi expects it to match the parent directory pi-interactive-shell. Fixed skill name to match package name.

[0.10.0] - 2026-03-13

Added

  • Test harness - Added vitest with 20 tests covering session queries, key encoding, notification formatting, headless monitor lifecycle, session manager, config/docs parity, and module loading.
  • gpt-5-4-prompting skill - New bundled skill with GPT-5.4 prompting best practices for Codex workflows.

Changed

  • Architecture refactor - Extracted shared logic into focused modules for better maintainability:
    • session-query.ts - Unified output/query logic (rate limiting, incremental, drain, offset modes)
    • notification-utils.ts - Message formatting for dispatch/hands-free notifications
    • handoff-utils.ts - Snapshot/preview capture on session exit/transfer
    • runtime-coordinator.ts - Centralized overlay/monitor/widget state management
    • pty-log.ts - Raw output trimming and line slicing
    • pty-protocol.ts - DSR cursor position query handling
    • spawn-helper.ts - macOS node-pty permission fix
    • background-widget.ts - TUI widget for background sessions
  • README, SKILL.md, install output, and the packaged Codex workflow examples now tell the same story about dispatch being the recommended delegated mode, the current 8s quiet threshold / 15s grace-period defaults, and the bundled prompt-skill surface.
  • The Codex workflow docs now point at the packaged gpt-5-4-prompting, codex-5-3-prompting, and codex-cli skills instead of describing a runtime fetch of the old 5.2 prompting guide.
  • Example prompts and skill docs are aligned around gpt-5.4 as the default Codex model, with gpt-5.3-codex remaining the explicit opt-in fallback.
  • Renamed codex-5.3-promptingcodex-5-3-prompting example skill (filesystem-friendly path).

Fixed

  • Map iteration bug - Fixed disposeAllMonitors() modifying Map during iteration, which could cause unpredictable behavior.
  • Array iteration bug - Fixed PTY listener notifications modifying arrays during iteration if a listener unsubscribed itself.
  • Missing runtime dependency - Added @sinclair/typebox to dependencies (was imported but not declared).
  • Documented the packaged prompt/skill onboarding path more clearly so users can either rely on the exported package metadata or copy the bundled examples into their own prompt and skill directories.

[0.9.0] - 2026-02-23

Added

  • examples/skills/codex-5.3-prompting/ skill with GPT-5.3-Codex prompting guide -- self-contained best practices for verbosity control, scope discipline, forced upfront reading, plan mode, mid-task steering, context management, and reasoning effort recommendations.
  • interactive-shell:update event — All hands-free update callbacks now emit pi.events.emit("interactive-shell:update", update) with the full HandsFreeUpdate payload. Extensions can listen for quiet, exit, kill, and user-takeover events regardless of which code path started the session (blocking, non-blocking, or reattach).
  • triggerTurn on terminal events — Non-blocking hands-free sessions now send pi.sendMessage with triggerTurn: true when the session exits, is killed, or the user takes over. Periodic "running" updates emit only on the event bus (cheap for extensions) without waking the agent.

Fixed

  • Quiet detection broken for TUI apps — Ink-based CLIs (Claude Code, etc.) emit periodic ANSI-only PTY data (cursor blink, frame redraws) that reset the quiet timer on every event, preventing quiet detection from ever triggering. Now filters data through stripVTControlCharacters and only resets the quiet timer when there's visible content. Fixed in both the overlay (overlay-component.ts) and headless dispatch monitor (headless-monitor.ts). Also seeds the quiet timer at startup when autoExitOnQuiet is enabled, so sessions that never produce visible output still get killed after the grace period.
  • Lifecycle guard decoupled from callback — The overlay used onHandsFreeUpdate presence as a proxy for "blocking tool call" to decide whether to unregister sessions on completion. Wiring the callback in non-blocking paths (for event emission) would cause premature session cleanup. Introduced streamingMode flag to separate "has update callback" from "should unregister on completion," so non-blocking sessions stay queryable after the callback fires.
  • autoExitOnQuiet broken in interval update mode — The onData handler only reset the quiet timer in on-quiet mode, so autoExitOnQuiet never fired with updateMode: "interval". Also, the interval timer's safety-net flush unconditionally stopped the quiet timer, preventing autoExitOnQuiet from firing if the interval flushed before the quiet threshold. Both fixed: data handler now resets the timer whenever autoExitOnQuiet is enabled regardless of update mode, and the interval flush restarts (rather than stops) the quiet timer when autoExitOnQuiet is active.
  • RangeError on narrow terminalsrender() computed width - 2 for border strings without a lower bound, causing String.prototype.repeat() to throw with negative counts when terminal width < 4. Clamped in both the main overlay and reattach overlay. Fixes #2.
  • Hardcoded ~/.pi/agent path — Config loading, snapshot writing, and the install script all hardcoded ~/.pi/agent, ignoring PI_CODING_AGENT_DIR. Now uses getAgentDir() from pi's API in all runtime paths and reads the env var in the install script. Fixes #1.

Changed

  • Default handsFreeQuietThreshold increased from 5000ms to 8000ms and autoExitGracePeriod reduced from 30000ms to 15000ms. Both remain adjustable per-call via handsFree.quietThreshold and handsFree.gracePeriod, and via config file.
  • Dispatch mode is now the recommended default for delegated Codex runs. Updated README.md, SKILL.md, tool-schema.ts, examples/skills/codex-cli/SKILL.md, and all three codex prompt templates to prefer mode: "dispatch" over hands-free for fire-and-forget delegations.
  • Rewrote codex-5.3-prompting skill from a descriptive model-behavior guide into a directive prompt-construction reference. Cut behavioral comparison, mid-task steering, and context management prose sections; reframed each prompt block with a one-line "include when X" directive so the agent knows what to inject and when.
  • Added "Backwards compatibility hedging" section to codex-5.3-prompting skill covering the "cutover" keyword trick -- GPT-5.3-Codex inserts compatibility shims and fallback code even when told not to; using "cutover" + "no backwards compatibility" + "do not preserve legacy code" produces cleaner breaks than vague "don't worry about backwards compatibility" phrasing.
  • Example prompts (codex-implement-plan, codex-review-impl, codex-review-plan) updated for GPT-5.3-Codex: load codex-5.3-prompting and codex-cli skills instead of fetching the 5.2 guide URL at runtime, added scope fencing instructions to counter 5.3's aggressive refactoring, added "don't ask clarifying questions" and "brief updates" constraints, strengthened codex-review-plan to force reading codebase files referenced in the plan and constrain edit scope.

[0.8.2] - 2026-02-10

Added

  • examples/prompts/ with three Codex CLI prompt templates: codex-review-plan, codex-implement-plan, codex-review-impl. Demonstrates a plan → implement → review workflow using meta-prompt generation and interactive shell overlays.
  • examples/skills/codex-cli/ skill that teaches pi Codex CLI flags, config, sandbox caveats, and interactive_shell usage patterns.
  • README section documenting the workflow pipeline, installation, usage examples, and customization.

[0.8.1] - 2026-02-08

Fixed

  • README: documented handsFree.gracePeriod tool parameter and startup grace period behavior in Auto-Exit on Quiet and Dispatch sections.
  • README: added missing handoffPreviewLines and handoffPreviewMaxChars to config settings table.

[0.8.0] - 2026-02-08

Added

  • autoExitGracePeriod config option (default: 30000ms, clamped 5000-120000ms) and handsFree.gracePeriod tool parameter override for startup quiet-kill grace control.

Changed

  • Default overlayHeightPercent increased from 45 to 60 for improved usable terminal rows on smaller displays.
  • Overlay sizing now uses dynamic footer chrome: compact 2-line footer in normal states and full 6-line footer in detach dialog, increasing terminal viewport height during normal operation.

Fixed

  • Dispatch/hands-free autoExitOnQuiet no longer kills sessions during startup silence; quiet timer now re-arms during grace period and applies auto-kill only after grace expires.
  • README config table missing handoffPreviewLines and handoffPreviewMaxChars entries despite appearing in the JSON example.

[0.7.1] - 2026-02-03

Changed

  • Added demo video and pi.video field to package.json for pi package browser.

[0.7.0] - 2026-02-03

Added

  • Dispatch mode (mode: "dispatch") - Fire-and-forget sessions where the agent is notified on completion via triggerTurn instead of polling. Defaults autoExitOnQuiet: true.
  • Background dispatch (mode: "dispatch", background: true) - Headless sessions with no overlay. Multiple can run concurrently alongside an interactive overlay.
  • Agent-initiated background (sessionId, background: true) - Dismiss an active overlay while keeping the process running.
  • Attach (attach: "session-id") - Reattach to background sessions with any mode (interactive, hands-free, dispatch).
  • List background sessions (listBackground: true) - Query all background sessions with status and duration.
  • Ctrl+B shortcut - Direct keyboard shortcut to background a session (dismiss overlay, keep process running) without navigating the Ctrl+Q menu.
  • HeadlessDispatchMonitor - Lightweight monitor for background PTY sessions handling quiet timer, timeout, exit detection, and output capture.
  • Completion output capture - completionOutput captured before PTY disposal in all finishWith* methods for dispatch notifications.
  • completionNotifyLines and completionNotifyMaxChars config options for notification output size.
  • Dismiss background sessions - /dismiss [id] user command and dismissBackground tool param to kill running / remove exited sessions without opening an overlay.
  • Background sessions widget - Persistent widget below the editor showing all background sessions with status indicators ( running / exited), session ID, command, reason, and live duration. Auto-appears/disappears. Responsive layout wraps to two lines on narrow terminals.
  • Additive listeners on PtyTerminalSession - addDataListener() and addExitListener() allow multiple subscribers alongside the primary setEventHandlers(). Headless monitor and overlay coexist without conflicts.

Changed

  • sessionManager.add() now accepts optional { id, noAutoCleanup } options for headless dispatch sessions.
  • sessionManager.take() removes sessions from background registry without disposing PTY (for attach flow).
  • ActiveSession interface now includes background() method.
  • Overlay onExit handler broadened: non-blocking modes (dispatch and hands-free) auto-close immediately on exit instead of showing countdown.
  • finishWithBackground() reuses sessionId as backgroundId for non-blocking modes.
  • getOutputSinceLastCheck() returns completionOutput as fallback when session is finished.
  • /attach command coordinates with headless monitors via additive listeners (monitor stays active during overlay).
  • Headless dispatch completion notifications are compact: status line, duration, 5-line tail, and reattach instruction. Full output available via details.completionOutput or by reattaching.
  • Completed headless sessions preserve their PTY for 5 minutes (scheduleCleanup) instead of disposing immediately, allowing the agent to reattach and review full scrollback.
  • Notification tail strips trailing blank lines from terminal buffer before slicing.

Fixed

  • Interval timer in startHandsFreeUpdates() and setUpdateInterval() no longer kills autoExitOnQuiet detection in dispatch mode (guarded on-quiet branch with onHandsFreeUpdate null check).
  • Hands-free non-blocking polls returning empty output for completed sessions now return captured completionOutput.

[0.6.4] - 2026-02-01

Fixed

  • Adapt execute signature to pi v0.51.0: insert signal as 3rd parameter

[0.6.3] - 2026-01-30

Fixed

  • Garbled output on Ctrl+T transfer - Transfer and handoff preview captured raw PTY output via getRawStream(), which includes every intermediate frame of TUI spinners (e.g., Codex's "Working" spinner produced WorkingWorking•orking•rking•king•ing...). Switched both captureTransferOutput() and maybeBuildHandoffPreview() to use getTailLines() which reads from the xterm terminal emulator buffer. The emulator correctly processes carriage returns and cursor movements, so only the final rendered state of each line is captured. Fixed in both overlay-component.ts and reattach-overlay.ts.
  • Removed dead code - Cleaned up unused private fields (timedOut, lastDataTime) and unreachable method (getSessionId()) from InteractiveShellOverlay.

[0.6.2] - 2026-01-28

Fixed

  • Ctrl+T transfer now works in hands-free mode - When using Ctrl+T to transfer output in non-blocking hands-free mode, the captured output is now properly sent back to the main agent using pi.sendMessage() with triggerTurn: true. Previously, the transfer data was captured but never delivered to the agent because the tool had already returned. The fix uses the event bus pattern to wake the agent with the transferred content.
  • Race condition when Ctrl+T during polling - Added guard in getOutputSinceLastCheck() to return empty output if the session is finished. This prevents errors when a query races with Ctrl+T transfer (PTY disposed before query completes).

Added

  • New event: interactive-shell:transfer - Emitted via pi.events when Ctrl+T transfer occurs, allowing other extensions to hook into transfer events.

[0.6.1] - 2026-01-27

Added

  • Banner image - Added fancy banner to README for consistent branding with other pi extensions

[0.6.0] - 2026-01-27

Added

  • Transfer output to agent (Ctrl+T) - New action to capture subagent output and send it directly to the main agent. When a subagent finishes work, press Ctrl+T to close the overlay and transfer the output as primary content (not buried in details). The main agent immediately has the subagent's response in context.
  • Transfer option in Ctrl+Q menu - "Transfer output to agent" is now the first option in the session menu, making it the default selection.
  • Configurable transfer settings - transferLines (default: 200, range: 10-1000) and transferMaxChars (default: 20KB, range: 1KB-100KB) control how much output is captured.

Changed

  • Ctrl+Q menu redesigned - Options are now: Transfer output → Run in background → Kill process → Cancel. Transfer is the default selection since it's the most common action when a subagent finishes.
  • Footer hints updated - Now shows "Ctrl+T transfer • Ctrl+Q menu" for discoverability.

[0.5.3] - 2026-01-26

Changed

  • Added pi-package keyword for npm discoverability (pi v0.50.0 package system)

[0.5.2] - 2026-01-23

Fixed

  • npx installation missing files - The install script had a hardcoded file list that was missing 4 critical files (key-encoding.ts, types.ts, tool-schema.ts, reattach-overlay.ts). Now reads from package.json's files array as the single source of truth, ensuring all files are always copied.
  • Broken symlink handling - Fixed skill symlink creation failing when a broken symlink already existed at the target path. existsSync() returns false for broken symlinks, causing the old code to skip removal. Now unconditionally attempts removal, correctly handling broken symlinks.

[0.5.1] - 2026-01-22

Fixed

  • Prevent overlay stacking - Starting a new interactive_shell session or using /attach while an overlay is already open now returns an error instead of causing undefined behavior with stacked/stuck overlays.

[0.5.0] - 2026-01-22

Changed

  • BREAKING: Split input into separate fields for Vertex AI compatibility - The input parameter which previously accepted either a string or an object with text/keys/hex/paste fields has been split into separate parameters:

    • input - Raw text/keystrokes (string only)
    • inputKeys - Named keys array (e.g., ["ctrl+c", "enter"])
    • inputHex - Hex bytes array for raw escape sequences
    • inputPaste - Text for bracketed paste mode

    This change was required because Claude's Vertex AI API (google-antigravity provider) rejects anyOf JSON schemas with mixed primitive/object types.

Migration

// Before (0.4.x)
interactive_shell({ sessionId: "abc", input: { keys: ["ctrl+c"] } })
interactive_shell({ sessionId: "abc", input: { paste: "code" } })

// After (0.5.0)
interactive_shell({ sessionId: "abc", inputKeys: ["ctrl+c"] })
interactive_shell({ sessionId: "abc", inputPaste: "code" })

// Combining text with keys (still works)
interactive_shell({ sessionId: "abc", input: "y", inputKeys: ["enter"] })

[0.4.9] - 2026-01-21

Fixed

  • Multi-line command overflow in header - Commands containing newlines (e.g., long prompts passed via -f flag) now properly collapse to a single line in the overlay header instead of overflowing and leaking behind the overlay.
  • Reason field overflow - The reason field in the hint line is also sanitized to prevent newline overflow.
  • Session list overflow - The /attach command's session list now sanitizes command and reason fields for proper display.

[0.4.8] - 2026-01-19

Changed

  • node-pty ^1.1.0 - Updated minimum version to 1.1.0 which includes prebuilt binaries for macOS (arm64, x64) and Windows (x64, arm64). No more Xcode or Visual Studio required for installation on these platforms. Linux still requires build tools (build-essential, python3).

[0.4.7] - 2026-01-18

Added

  • Incremental mode - New incremental: true parameter for server-tracked pagination. Agent calls repeatedly and server tracks position automatically. Returns hasMore to indicate when more output is available.
  • hasMore in offset mode - Offset pagination now returns hasMore field so agents can know when they've finished reading all output.

Fixed

  • Session ID leak on user takeover - In streaming mode, session ID was unregistered but never released when user took over. Now properly releases ID since agent was notified and won't query.
  • Session ID leak in dispose() - When overlay was disposed without going through finishWith* methods (error cases), session ID was never released. Now releases ID in all cleanup paths.

Changed

  • autoExitOnQuiet now defaults to false - Sessions stay alive for multi-turn interaction by default. Enable with handsFree: { autoExitOnQuiet: true } for fire-and-forget single-task delegations.
  • Config documentation - Fixed incorrect config path in README. Config files are ~/.pi/agent/interactive-shell.json (global) and .pi/interactive-shell.json (project), not under settings.json. Added full settings table with all options documented.
  • Detach key - Changed from double-Escape to Ctrl+Q for more reliable detection.

[0.4.6] - 2026-01-18

Added

  • Offset/limit pagination - New outputOffset parameter for reading specific ranges of output:
    • outputOffset: 0, outputLines: 50 reads lines 0-49
    • outputOffset: 50, outputLines: 50 reads lines 50-99
    • Returns totalLines in response for pagination
  • Drain mode for incremental output - New drain: true parameter returns only NEW output since last query:
    • More token-efficient than re-reading the tail each time
    • Ideal for repeated polling of long-running sessions
  • Token Efficiency section in README - Documents advantages over tmux workflow:
    • Incremental aggregation vs full capture-pane
    • Tail by default (20 lines, not full history)
    • ANSI stripping before sending to agent
    • Drain mode for only-new-output

Changed

  • getLogSlice() method in pty-session - New low-level method for offset/limit pagination through raw output buffer

[0.4.3] - 2026-01-18

Added

  • Configurable output limits - New outputLines and outputMaxChars parameters when querying sessions:
    • outputLines: Request more lines (default: 20, max: 200)
    • outputMaxChars: Request more content (default: 5KB, max: 50KB)
    • Example: interactive_shell({ sessionId: "calm-reef", outputLines: 50 })
  • Escape hint feedback - After pressing first Escape, shows "Press Escape again to detach..." in footer for 300ms

Fixed

  • Escape hint not showing - Fixed bug where clearEscapeHint() was immediately resetting showEscapeHint to false after setting it to true
  • Negative output limits - Added clamping to ensure outputLines and outputMaxChars are at least 1
  • Reduced flickering during rapid output - Three improvements:
    1. Scroll position calculated at render time via followBottom flag (not on each data event)
    2. Debounced render requests (16ms) to batch rapid updates before drawing
    3. Explicit scroll-to-bottom after resize to prevent flash to top during dimension changes

[0.4.2] - 2026-01-17

Added

  • Query rate limiting - Queries are limited to once every 60 seconds by default. If you query too soon, the tool automatically waits until the limit expires before returning (blocking behavior). Configurable via minQueryIntervalSeconds in settings (range: 5-300 seconds). Note: Rate limiting does not apply to completed sessions or kills - you can always query the final result immediately.

Changed

  • autoExitOnQuiet now defaults to true - In hands-free mode, sessions auto-kill when output stops (~5s of quiet). Set handsFree: { autoExitOnQuiet: false } to disable.
  • Smaller default overlay - Height reduced from 90% to 45%. Configurable via overlayHeightPercent in settings (range: 20-90%).

Fixed

  • Rate limit wait now interruptible - When waiting for rate limit, the wait is interrupted immediately if the session completes (user kills, process exits, etc.). Uses Promise.race with onComplete callback instead of blocking sleep.
  • scrollbackLines NaN handling - Config now uses clampInt like other numeric fields, preventing NaN from breaking xterm scrollback.
  • autoExitOnQuiet status mismatch - Now sends "killed" status (not "exited") to match finishWithKill() behavior.
  • hasNewOutput semantics - Renamed to hasOutput since we use tail-based output, not incremental tracking.
  • dispose() orphaned sessions - Now kills running processes before unregistering to prevent orphaned sessions.
  • killAll() premature ID release - IDs now released via natural cleanup after process exit, not immediately after kill() call.

[0.4.1] - 2026-01-17

Changed

  • 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.
  • 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.

Fixed

  • 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.

[0.4.0] - 2026-01-17

Added

  • Non-blocking hands-free mode - Major change: mode: "hands-free" now returns immediately with a sessionId. The overlay opens for the user but the agent gets control back right away. Use interactive_shell({ sessionId }) to query status/output and interactive_shell({ sessionId, kill: true }) to end the session when done.
  • Session status queries - Query active session with just sessionId to get current status and any new output since last check.
  • Kill option - interactive_shell({ sessionId, kill: true }) to programmatically end a session.
  • autoExitOnQuiet option - Auto-kill session when output stops (after quietThreshold). Use handsFree: { autoExitOnQuiet: true } for sessions that should end when the nested agent goes quiet.
  • Output truncation - Status queries now truncate output to 10KB (keeping the most recent content) to prevent overwhelming agent context. Truncation is indicated in the response.

Fixed

  • Non-blocking mode session lifecycle - Sessions now stay registered after completion so agent can query final status. Previously, sessions were unregistered before agent could query completion result.
  • User takeover in non-blocking mode - Agent can now see "user-takeover" status when querying. Previously, session was immediately unregistered when user took over.
  • Type mismatch in registerActive - Fixed getOutput return type to match OutputResult interface.
  • Agent output position after buffer trim - Fixed agentOutputPosition becoming stale when raw buffer is trimmed. When the 1MB buffer limit is exceeded and old content discarded, the agent query position is now clamped to prevent returning empty output or missing data.
  • killAll() map iteration - Fixed modifying maps during iteration in killAll(). Now collects IDs/entries first to avoid unpredictable behavior when killing sessions triggers unregistration callbacks.
  • ActiveSessionResult type - Fixed type mismatch where output field was required but never populated. Updated interface to match actual return type from getResult().
  • Unbounded raw output growth - rawOutput buffer now capped at 1MB, trimming old content to prevent memory growth in long-running sessions
  • Session ID reuse - IDs are only released when session fully terminates, preventing reuse while session still running after takeover
  • DSR cursor responses - Fixed stale cursor position when DSR appears mid-chunk; now processes chunks in order, writing to xterm before responding
  • Active sessions on shutdown - Hands-free sessions are now killed on session_shutdown, preventing orphan processes
  • Quiet threshold timer - Changing threshold now restarts any active quiet timer with the new value
  • Empty string input - Now shows "(empty)" instead of blank in success message
  • Hands-free auto-close on exit - Overlay now closes immediately when process exits in hands-free mode, returning control to the agent instead of waiting for countdown
  • Handoff preview now uses raw output stream instead of xterm buffer. TUI apps using alternate screen buffer (like Codex, Claude, etc.) would show misleading/stale content in the preview.

[0.3.0] - 2026-01-17

Added

  • Hands-free mode (mode: "hands-free") for agent-driven monitoring with periodic tail updates.
  • User can take over hands-free sessions by typing anything (except scroll keys).
  • Configurable update settings for hands-free mode (defaults: on-quiet mode, 5s quiet threshold, 60s max interval, 1500 chars/update, 100KB total budget).
  • Input injection: Send input to active hands-free sessions via sessionId + input parameters.
  • Named key support: up, down, enter, escape, ctrl+c, etc.
  • "Foreground subagents" terminology to distinguish from background subagents (the subagent tool).
  • sessionId now available in the first update (before overlay opens) for immediate input injection.
  • Timeout: Auto-kill process after N milliseconds via timeout parameter. Useful for TUI commands that don't exit cleanly (e.g., pi --help).
  • DSR handling: Automatically responds to cursor position queries (ESC[6n / ESC[?6n) with actual xterm cursor position. Prevents TUI apps from hanging when querying cursor.
  • Enhanced key encoding: Full modifier support (ctrl+alt+x, shift+tab, c-m-delete), hex bytes (hex: ["0x1b"]), bracketed paste mode (paste: "text"), and all F1-F12 keys.
  • Human-readable session IDs: Sessions now get memorable names like calm-reef, swift-cove instead of shell-1, shell-2.
  • Process tree killing: Kill entire process tree on termination, preventing orphan child processes.
  • Session name derivation: Better display names in /attach list showing command summary.
  • Write queue: Ordered writes to terminal emulator prevent race conditions.
  • Raw output streaming: getRawStream() method for incremental output reading with sinceLast option.
  • Exit message in terminal: Process exit status appended to terminal buffer when process exits.
  • EOL conversion: Added convertEol: true to xterm for consistent line ending handling.
  • Incremental updates: Hands-free updates now send only NEW output since last update, not full tail. Dramatically reduces context bloat.
  • Activity-driven updates (on-quiet mode): Default behavior now waits for 5s of output silence before emitting update. Perfect for agent-to-agent delegation where you want complete "thoughts" not fragments.
  • Update modes: handsFree.updateMode can be "on-quiet" (default) or "interval". On-quiet emits when output stops; interval emits on fixed schedule.
  • Context budget: Total character budget (default: 100KB, configurable via handsFree.maxTotalChars). Updates stop including content when exhausted.
  • Dynamic settings: Change update interval and quiet threshold mid-session via settings: { updateInterval, quietThreshold }.
  • Keypad keys: Added kp0-kp9, kp/, kp*, kp-, kp+, kp., kpenter for numpad input.
  • tmux-style key aliases: Added ppage/npage (PageUp/PageDown), ic/dc (Insert/Delete), bspace (Backspace) for compatibility.

Changed

  • ANSI stripping now uses Node.js built-in stripVTControlCharacters for cleaner, more robust output processing.

Fixed

  • Double unregistration in hands-free session cleanup (now idempotent via sessionUnregistered flag).
  • Potential double done() call when timeout fires and process exits simultaneously (added finished guard).
  • ReattachOverlay: untracked setTimeout for initial countdown could fire after dispose (now tracked).
  • Input type annotation missing hex and paste fields.
  • Background session auto-cleanup could dispose session while user is viewing it via /attach (now cancels timer on reattach).
  • On-quiet mode now flushes pending output before sending "exited" or "user-takeover" notifications (prevents data loss).
  • Interval mode now also flushes pending output on user takeover (was missing the || updateMode === "interval" check).
  • Timeout in hands-free mode now flushes pending output and sends "exited" notification before returning.
  • Exit handler now waits for writeQueue to drain, ensuring exit message is in rawOutput before notification is sent.

Removed

  • handsFree.updateLines option (was defined but unused after switch to incremental char-based updates).

[0.2.0] - 2026-01-17

Added

  • Interactive shell overlay tool interactive_shell for supervising interactive CLI agent sessions.
  • Detach dialog (double Esc) with kill/background/cancel.
  • Background session reattach command: /attach.
  • Scroll support: Shift+Up / Shift+Down.
  • Tail handoff preview included in tool result (bounded).
  • Optional snapshot-to-file transcript handoff (disabled by default).

Fixed

  • Prevented TUI width crashes by avoiding unbounded terminal escape rendering.
  • Reduced flicker by sanitizing/redrawing in a controlled overlay viewport.