Skip to content

Make pi -p show what it’s doing (live output in print mode) #808

Description

@prathamdby

Right now pi -p feels like a black box: it runs the prompt, sits silently, then prints the final assistant text and exits. Other CLIs (e.g. OpenCode) stream realtime progress even in their “print” / non-interactive mode: partial assistant output, tool calls, tool output, errors, etc.

I want the same experience in pi, without breaking the current “final-only” behavior that people rely on in scripts.

Current behavior

  • pi -p "prompt" (text mode): waits for completion, prints only the final assistant text, exits
  • pi --mode json "prompt": prints the full JSON event stream in realtime

What I want

Add a streaming option to print mode that emits human-readable realtime output.

CLI behavior

  • New flag: --stream (-s)
  • Defaulting:
    • If stdout is a TTY and --stream is not specified: streaming should be auto-enabled
    • If stdout is non-TTY (piped/redirected) and --stream is not specified: keep the existing final-only output (backwards compatible)
  • --mode json stays exactly as-is (raw JSON events)

Output format (human-readable)

  • Plain text by default (minimal/no ANSI), with stable prefixes for non-text events:
    • [thinking] ...
    • [tool <name>] calling...
    • [tool <name>] output:
    • [error] ...
  • Partial assistant text should stream as it arrives (append to stdout)
  • Tool output should use sane truncation defaults:
    • truncate very large outputs
    • clearly mark truncation ([truncated])
    • if there’s a known “full output path” available, print it

Important: no duplicate final output

If partial assistant text is streamed, the final assistant response should not be printed again in full at the end. (No double-printing.)

Where this likely lives

  • packages/coding-agent/src/cli/args.ts — add --stream / -s
  • packages/coding-agent/src/main.ts — wire flag into print mode
  • packages/coding-agent/src/modes/print-mode.ts — subscribe to session events and render them to stdout
  • packages/coding-agent/test/* — add tests for streaming + deduplication
  • packages/coding-agent/README.md — document --stream
  • packages/coding-agent/CHANGELOG.md — Unreleased entry

Implementation sketch

  1. Parse --stream / -s and decide:
    • streamingEnabled = parsed.stream || (process.stdout.isTTY && parsed.stream !== false)
  2. In runPrintMode():
    • If streamingEnabled: subscribe to session events and print as they arrive
      • incremental text chunks → write to stdout
      • tool call start/end/results → prefixed lines/blocks
      • thinking/progress → brief lines
      • errors/aborts → stderr, non-zero exit on error
    • If not enabled: keep current final-only behavior
  3. Ensure stdout is drained before exit (avoid losing the tail of streamed output)

Acceptance criteria

  • pi -p --stream "prompt" streams:
    • partial assistant text live
    • tool calls + tool output in chronological order with clear prefixes
    • thinking/progress lines
    • errors/aborts to stderr; non-zero exit on error
    • no duplicate final assistant output
  • pi -p "prompt" > out.txt stays final-only unless --stream is explicitly passed
  • pi --mode json "prompt" unchanged
  • Tests cover streaming and deduplication

Examples

  • Human (live): pi -p --stream "summarize my repo"
  • Script (unchanged): pi -p "summarize my repo" > result.txt
  • JSON (unchanged): pi --mode json "summarize my repo"

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions