Warning: Experimental wrapper. Test against your workflow before relying on it for automation.
claude-pty-wrapper runs interactive Claude through a PTY while exposing a
print-like CLI that streams assistant text from Claude's durable session JSONL.
claude-pty-wrapper "Summarize this repository"Without wrapper output flags, claude-pty-wrapper runs Claude in a
wrapper-owned PTY and relays bytes between Claude and the current terminal.
The terminal still renders ANSI/control sequences; the wrapper does not emulate
or parse the screen.
claude-pty-wrapper --freshness-interval 60 "Summarize this repository"In passthrough mode, --freshness-interval enables optional idle prompts. If
neither Claude output nor user input is observed for the interval, the wrapper
sends the freshness message into Claude's PTY followed by Enter.
claude-pty-wrapper -p "Summarize this repository"Text mode is the default output mode. It prints assistant text blocks from the session JSONL file and ignores tool calls, tool results, sidechains, and user messages.
claude-pty-wrapper --session-jsonl "Summarize this repository"--session-jsonl streams appended raw Claude JSONL records for the wrapper
turn. This is useful for diagnostics and downstream tooling.
claude-pty-wrapper -p --output-format stream-json "Summarize this repository"--output-format stream-json emits a compatibility-oriented JSONL stream resembling
claude -p --verbose --output-format stream-json. It preserves persisted
assistant content blocks, including tool calls and reasoning-style blocks, but
cannot synthesize runtime-only metadata that Claude does not write to the
durable session file. See docs/stream-json.md.
claude-pty-wrapper -p --output-format json "Summarize this repository"--output-format json emits a single final result object, matching Claude's
print-mode JSON shape as closely as durable session files allow.
claude-pty-wrapper --resume 18a18377-217d-4b29-9a68-c70a89b79330 -p "Continue"Resume mode tails from the existing session file size before spawning Claude, so output is scoped to the resumed turn.
Wrapper-owned flags:
-p, --print Use wrapper-managed print-compatible output
--output-format <format> Wrapper output: text, json, or stream-json
--input-format <format> Wrapper input: text; stream-json is not supported yet
--session-jsonl Emit appended raw Claude session JSONL
--cwd <dir> Working directory for Claude and session path lookup
--claude-bin <path> Claude binary; defaults to CLAUDE_BIN or claude
--timeout <seconds> Wrapper turn timeout
--raw-pty-log <file> Write raw PTY output for diagnostics
--wrapper-debug Print wrapper diagnostics to stderr
--freshness-interval <sec> Passthrough idle interval; enables freshness prompts
--freshness-message <text> Passthrough idle message; defaults to "Please wait for further instructions."
--freshness-max-iterations <count>
Stop after this many freshness prompts
--freshness-max-duration <sec>
Stop freshness behavior after this session duration
All other supported Claude flags keep their Claude names and are passed through
before the prompt. Examples include --model, --effort, --name,
--session-id, --resume, --dangerously-skip-permissions, --debug, and
--verbose. Run claude-pty-wrapper --help for the full accepted flag list.
--include-partial-messages is accepted as a no-op in wrapper stream-json mode
for compatibility with tools that pass it. In passthrough mode, runtime stream
flags such as --include-partial-messages and --include-hook-events are
forwarded to Claude.
Use -p/--print for wrapper-managed text, JSON, and stream JSON output. A bare
prompt without wrapper output flags uses interactive passthrough through a
wrapper-owned PTY relay.
Freshness flags are passthrough-only. --freshness-message,
--freshness-max-iterations, and --freshness-max-duration require
--freshness-interval; max iterations and max duration are mutually exclusive.
Freshness is inactive unless --freshness-interval is set.
Install dependencies, build the CLI, and link the command into your local
PATH:
npm install
npm run build
npm linkThen run it as:
claude-pty-wrapper "Summarize this repository"
claude-pty-wrapper -p "Summarize this repository"After code changes, rerun npm run build; the linked command points at this
repo's dist/ output.
Run the full local validation suite:
npm install
npm run checknpm run check runs linting, typechecking, unit/integration tests, and smoke
tests. The smoke tests build the CLI first, then run it against a fake Claude
executable that is spawned through node-pty and writes real session JSONL
files under a temporary HOME.
To validate before linking, use:
npm install
npm run check
npm linkLive smoke tests are opt-in because they invoke the installed Claude binary and may consume Claude/API quota:
CLAUDE_PTY_WRAPPER_LIVE_SMOKE=1 npm run test:smoke:live