claude-e is a PTY-backed execution wrapper for Claude Code.
It gives Claude a claude -p-style command surface while still driving the
interactive Claude Code runtime underneath. That matters when an agent system
needs the real interactive Claude behavior, but also needs a predictable
single-command interface, JSON output, timeouts, resume wiring, and explicit
binary resolution.
npm install -g claude-e
claude-e "your prompt here"
claude-e p --model opus "explain quicksort to a 10-year-old"
claude-e --tool "use 10 tools and summarize the results"
claude-e --output-format json "summarize this commit" < commit.diff
claude-e --output-format stream-json "audit src/" --verbose | jq .| Surface | Link | Status |
|---|---|---|
| npm package | claude-e |
public package |
| Repository | lidge-jun/claude-e |
public source |
| Docs landing page | docs/index.html |
local Pages entrypoint, deploys after an authorized push |
| Runtime contract | structure/runtime_contract.md |
JSONL, transcript, timeout, and exit-code source |
| CLI surface | structure/cli_surface.md |
command aliases, flags, and compatibility names |
GitHub Pages is documented as ready, not live in this local state because
the GitHub Pages API currently returns 404 for this repository. The added Pages
workflow publishes /docs once the owner authorizes a push.
Claude Code is strongest as an interactive tool. Agent runtimes often need the opposite shape: spawn one process, send one prompt, collect structured output, classify failures, and move on.
claude-e bridges that gap:
| Need | What claude-e does |
|---|---|
claude -p-like usage |
Accepts prompt args, piped stdin, p / print, -p, and --print. |
| Real Claude Code behavior | Uses a PTY and injects the prompt through the interactive path. |
| Agent-friendly output | Normalizes transcript replay into text, json, or stream-json. |
| Embedding stability | Supports run / exec, JSONL runtime events, timeout exit codes, and resume. |
| Launchd/server safety | Lets callers pass an explicit --claude-bin instead of relying on PATH. |
| Unattended tools | Enables Claude permission bypass and workspace/folder trust handling by default. |
| Terminal progress | --tool, --t, or -t prints compact tool-use lines on stderr. |
| cli-jaw migration | Keeps claude-exec, claude-i, and jaw-claude-i compatibility bins. |
npm install -g claude-eAfter installation, the CLI is available directly:
claude-e "your prompt here"
claude-e --tool "use 10 tools"
claude-e --helpOptional one-shot usage without a global install:
npx claude-e "your prompt here"From source:
git clone https://github.com/lidge-jun/claude-e.git
cd claude-e
npm install
cargo build --release --lockedThe npm package builds the Rust release binary during postinstall. It also
asks once for a GitHub star when npm is running interactively with an
authenticated gh CLI; non-interactive installs print the repository URL
instead. Set CLAUDE_E_SKIP_STAR_PROMPT=1 to suppress the star request.
Set CLAUDE_E_SKIP_POSTINSTALL=1 to skip all postinstall work. Set
CLAUDE_E_SKIP_BUILD=1 or CLAUDE_EXEC_SKIP_BUILD=1 only when another
packaging layer provides the binary; the star request can still run in that
mode unless it is skipped separately.
The short command is the public face:
claude-e "your prompt here"
claude-e p "your prompt here"
claude-e print "your prompt here"
claude-e -p "your prompt here"The long command remains available for compatibility:
claude-exec "your prompt here"
claude-exec run --claude-bin "$(command -v claude)" -- --model opus
claude-exec exec --claude-bin "$(command -v claude)" -- --model opusThe package currently exposes four bins from the same Rust entrypoint:
| Bin | Status | Purpose |
|---|---|---|
claude-e |
Primary | Short npm command and claude -p-style surface. |
claude-exec |
Compatibility | Long descriptive alias retained for existing integrations. |
claude-i |
Transitional | Existing cli-jaw provider/runtime compatibility. |
jaw-claude-i |
Legacy | Existing cli-jaw helper name compatibility. |
agent / orchestrator
-> claude-e npm bin
-> Rust wrapper
-> PTY session
-> interactive Claude Code runtime
-> normalized text/json/stream-json output
compatibility bins
-> claude-exec
-> claude-i
-> jaw-claude-i
claude-e keeps stdout reserved for user-facing output and writes progress,
resume hints, and wrapper diagnostics to stderr. That separation is the main
reason it can fit into pipelines, JSON consumers, and cli-jaw runtime adapters.
Use these local gates before claiming a release or command-surface change:
npm run fmt:check
npm run check
npm run test
npm run publish:dry-run
npm run verifyCurrent remote CI signal: the Tests workflow is passing on main across
Ubuntu and macOS. Publishing remains manual unless a workflow dispatch is
explicitly requested.
- The wrapper preserves the stdout contract so JSON consumers do not receive progress chatter.
--claude-binexists for launchd/server environments where PATH is not trustworthy.- Timeouts and prompt sanitization have explicit exit codes instead of silent fallbacks.
- The runtime can enable Claude permission bypass for unattended tool use, so only run it inside workspaces you intend Claude Code to operate on.
- The npm package is MIT licensed and this repository includes a root
LICENSEfile.
Plain text:
claude-e "write a two-line commit summary"Terminal tool progress:
claude-e --tool "use 10 tools and summarize what happened"
claude-e --t --model opus "inspect this repo with tools"--tool / --t / -t prints compact tool_use and tool_result progress
lines to stderr. Stdout stays reserved for the final answer or selected output
format, so pipes and JSON consumers are not broken.
JSON result:
git diff --cached | claude-e --output-format json "summarize this staged diff"Stream JSON:
claude-e --output-format stream-json "audit src/" --verbose | jq .For streaming UIs, prefer --output-format stream-json. It preserves the
Claude-like assistant/user records, including tool calls, tool results, and the
final synthesized result event. Claude rate_limit_event records are passed
through so callers can wait instead of treating transient 429 pacing as a
fallback-worthy failure.
Explicit Claude binary:
CLAUDE_EXEC_CLAUDE_BIN="$(command -v claude)" \
claude-e --model opus "explain this repo architecture"Session-shaped run:
claude-e \
--session-id 00000000-0000-4000-8000-000000000001 \
--output-format stream-json \
"continue this investigation from the existing Claude session"Every print-compatible run tracks the Claude session id. In text mode,
claude-e prints a resume footer to stderr:
[claude-e] session: 6a304357-e92d-47e7-a56d-c54065e12be1
[claude-e] resume: claude-e --resume 6a304357-e92d-47e7-a56d-c54065e12be1 "your next prompt"
Resume with:
claude-e --resume 6a304357-e92d-47e7-a56d-c54065e12be1 "continue from there"Use --no-session-footer when the terminal footer is not wanted.
Agent systems can use the explicit runtime command:
printf 'Say hello in one short sentence.\n' \
| claude-e run \
--jsonl \
--output-format stream-json \
--idle-timeout-ms 600000 \
--hard-timeout-ms 3600000 \
--claude-bin "$(command -v claude)" \
-- \
--model claude-opus-4-6exec is a visible alias for run:
printf 'Say hello.\n' \
| claude-e exec --claude-bin "$(command -v claude)" -- --model opusWrapper-owned flags:
| Flag | Behavior |
|---|---|
--input-format text|stream-json |
Reads plain stdin or extracts user text from JSONL messages. |
--output-format text|json|stream-json |
Selects transcript output normalization. |
--idle-timeout-ms |
No-activity timeout in milliseconds. Transcript activity refreshes it; active tools suppress idle timeout until a tool result is observed. |
--hard-timeout-ms |
Absolute runtime cap in milliseconds. |
--timeout-ms |
Backward-compatible alias for --idle-timeout-ms. |
--claude-bin |
Claude CLI binary or absolute path. |
--cwd |
Working directory for the Claude PTY process. |
--cols, --rows |
PTY dimensions. |
--session-id |
Uses a specific session id in print-compatible mode. |
--resume, -r |
Resumes a Claude session in the PTY path. |
--no-session-persistence |
Suppresses generated session ids. |
--json-schema |
Appends a JSON-only schema instruction to the prompt. |
--auto-accept-workspace-trust |
Accepts Claude's pre-SessionStart workspace/folder trust prompt. Enabled by default. |
--no-auto-accept-workspace-trust |
Disables automatic workspace/folder trust handling in print-compatible mode. |
--tool, --t, -t |
Prints compact terminal tool progress to stderr. |
--no-session-footer |
Hides the final stderr resume footer in print-compatible mode. |
Forwarded Claude flags include --model, --effort, --permission-mode,
--add-dir, --allowed-tools, --disallowed-tools, --tools, --mcp-config,
--settings, --system-prompt, --append-system-prompt, --plugin-dir,
--plugin-url, browser flags, MCP debug flags, and related Claude global
controls.
Print-only compatibility flags such as --verbose,
--include-partial-messages, --include-hook-events,
--replay-user-messages, --fallback-model, and --max-budget-usd are
accepted so command shapes port cleanly from print-mode Claude.
Unless the caller already supplied --permission-mode,
--permission-mode=..., --dangerously-skip-permissions, or
--allow-dangerously-skip-permissions, claude-e appends
--dangerously-skip-permissions to the underlying Claude invocation. This keeps
non-interactive tool use from hanging on permission prompts.
Default print-compatible mode suppresses wrapper diagnostics from stdout and returns the requested user-facing format.
Explicit run / exec mode emits JSONL. Runtime lifecycle records use the
existing cli-jaw compatibility envelope:
{"type":"jaw_runtime","event":"runtime_started","runId":"run_12345678"}Claude transcript records are tailed and normalized into Claude-like stream JSON. On completion, the wrapper can synthesize a result record from the last assistant message.
| Code | Meaning |
|---|---|
0 |
Normal completion. |
1 |
Underlying Claude exited unsuccessfully without a more specific wrapper classification. |
2 |
Graceful interrupt; session metadata can be resumable. |
4 |
Claude spawn or PTY write failure. |
5 |
SessionStart hook failure, timeout, or early Claude exit before SessionStart. |
6 |
Runtime timeout. |
7 |
Prompt injection transcript verification failure. |
11 |
Claude StopFailure hook. |
13 |
Hook temp dir or settings generation failure. |
16 |
stdin read, size, empty prompt, or prompt sanitization failure. |
npm run fmt:check
npm run test
npm run build
npm run verifySmoke test with local Claude auth:
bash scripts/smoke.shDry-run the exact npm publish surface:
npm run publish:dry-runRelease helpers:
npm run release:check # full local release dry run
npm run release:npm # publish the current package version
npm run release:patch # bump patch, commit, tag, publish, create GitHub Release
npm run release:minor # bump minor, commit, tag, publish, create GitHub Release
npm run release:major # bump major, commit, tag, publish, create GitHub Release
npm run release:preview # publish preview dist-tag prereleaseGitHub Actions only runs Rust verification and npm dry-runs. Actual npm
publishing is intentionally local-only: run npm run release:npm for the
current version or a semver release helper when you explicitly want to publish.
When npm is not authenticated, the release scripts start npm login --auth-type=web so npm can use its normal browser login flow in your local
terminal before publishing.
The main claude-e package declares one optional platform package per supported
OS/architecture. The main package version, every optionalDependencies version,
and every platform-packages/*/package.json version must match before a release
is considered publishable. npm run test:postinstall checks this contract, and
scripts/sync-package-versions.mjs <version> updates all package metadata for a
workflow release version.
The GitHub release workflow also syncs Cargo metadata to the requested workflow version before building platform packages and before publishing the main package. This prevents the main package from pointing at platform package versions that were never built.
- structure/INDEX.md
- structure/cli_surface.md
- structure/runtime_contract.md
- structure/cli_jaw_migration.md
- devlog/_plan/260516_claude_exec_extraction/00_overview.md
MIT
