[FEATURE] Headless claude status --json for current session state

Resolved 💬 4 comments Opened Apr 24, 2026 by YitzhakMizrahi Closed May 29, 2026

Preflight Checklist

  • [x] I searched existing requests before filing. The closest prior request is #38184, which was closed as stale with guidance to open a new issue if still relevant. #40589 is related but narrower: it asks for a state field in statusline JSON, not a headless query surface.
  • [x] This is a single feature request.

Problem Statement

Claude Code exposes useful session metadata to the custom statusline command, but that data is only available inside the live TUI/statusline refresh path. External tools do not have a supported way to ask a running Claude Code session: "what is your current state right now?"

This makes multi-session and headless workflows rely on fragile inference, such as:

  • scraping tmux panes for prompt/spinner/timer text
  • watching transcript JSONL modification times
  • maintaining sidecar state through hooks
  • parsing terminal UI output that may change between releases

Those workarounds are inherently lossy. They can miss state transitions, get stuck after restarts, or report stale state when the statusline is not refreshing independently.

The TUI already appears to know enough to render statusline/session state. The gap is a stable, machine-readable way for external tooling to query that state without depending on the visual terminal representation.

Proposed Solution

Add a headless status command that returns a point-in-time JSON snapshot for the current or selected Claude Code session:

claude status --json
claude status --json --session <session-id>

Possible output shape:

{
  "schema_version": 1,
  "session_id": "...",
  "cwd": "/path/to/project",
  "state": "idle",
  "model": "...",
  "permission_mode": "...",
  "last_activity_at": "2026-04-24T12:34:56Z",
  "transcript_path": "/path/to/session.jsonl",
  "context_window": {
    "used_tokens": 12345,
    "limit_tokens": 200000,
    "used_percent": 6.2
  }
}

The most important field is state. Suggested initial enum:

idle
working
running_tool
waiting_for_input
waiting_for_permission
waiting_for_subagent
unknown

A smaller MVP would still be valuable:

{
  "schema_version": 1,
  "session_id": "...",
  "state": "idle",
  "updated_at": "2026-04-24T12:34:56Z"
}

Suggested behavior:

  • 0: status read successfully
  • nonzero documented exit codes for no active session, unknown session, not logged in, or status unavailable
  • no prompt text, transcript content, tool output, file contents, or secrets in the default output
  • stable top-level keys with schema_version for forward compatibility
  • unavailable optional fields represented predictably as null or omitted by documented rule

Alternative Solutions

Current alternatives all have reliability issues:

  • Custom statusline JSON: useful for display, but tied to the statusline execution/refresh lifecycle and not directly queryable from another process.
  • Hooks writing state files: can miss transitions, become stale, and require every user to build their own state machine.
  • Transcript JSONL/file mtimes: show that something happened, not the current runtime state.
  • Tmux/screen scraping: depends on terminal rendering details and breaks when UI text, spinner characters, or layout changes.
  • IPC/socket/state file: also viable, but a CLI JSON command is easier to script, document, and stabilize incrementally.

Priority

High - Significant impact on productivity.

This is especially useful for people running multiple Claude Code sessions, headless sessions, tmux-based workflows, dashboards, status bars, watchdog scripts, or orchestration tools.

Feature Category

CLI commands and flags.

Use Case Example

I run multiple long-lived Claude Code sessions in terminal panes. An external supervisor/dashboard needs to know whether each session is idle, actively working, waiting for a permission decision, or waiting for input before deciding whether to deliver more work or notify the user.

Today that requires scraping terminal output and guessing from rendered text. With a supported command, the workflow becomes simple and robust:

state=$(claude status --json --session "$session_id" | jq -r '.state')
case "$state" in
  idle) deliver_next_message ;;
  waiting_for_permission) notify_user ;;
  working|running_tool|waiting_for_subagent) keep_waiting ;;
  *) mark_unknown_and_retry ;;
esac

This also enables clean integrations for statuslines, terminal titles, monitoring dashboards, and automation without coupling those tools to Claude Code's visual TUI implementation.

Additional Context

Related issues:

  • #38184 requested a reliable session-state detection API and mentioned a CLI query as one option. It was closed stale, but the need still exists.
  • #40589 asks for a state field in statusline JSON. This request is complementary: it asks for the same kind of state to be queryable headlessly from outside the statusline refresh path.
  • #31840 asks for remote-control status via state file or CLI flag. A general claude status --json surface could eventually include remote-control state as an optional nested field, but that is not required for the MVP.

View original on GitHub ↗

This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗