[FEATURE] Headless claude status --json for current session state
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
statefield 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_versionfor forward compatibility - unavailable optional fields represented predictably as
nullor 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
statefield 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 --jsonsurface could eventually include remote-control state as an optional nested field, but that is not required for the MVP.
This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗