# CLI Command: ps
List all running Claude Code processes and queued `clr` waiters in two plain-style
tables showing per-session PID, elapsed time, CPU%, RAM, state, working directory,
and last-known task.
**Syntax:**
```sh
clr ps
```
**Parameters:**
None. `ps` accepts no flags or arguments.
**Output Format:**
Two plain-style tables printed consecutively. Each table is preceded by a titled
caption rule line (e.g., `─── Active Sessions · 2 running ──────`) that names the
table and shows the item count. The column header row follows the caption.
1. **Active Sessions** — caption: `Active Sessions · N running`; columns: `#`,
`PID`, `Elapsed`, `CPU%`, `RAM`, `State`, `Absolute Path`, `Task`.
2. **Queued CLR Processes** — caption: `Queued · N waiting`; columns: `#`, `PID`,
`CWD`, `Waiting`, `Attempt`. Shows `clr` processes currently blocked in
`wait_for_session_slot()`.
Plain-style formatting: no outer borders; dash separator under header row; 2-space
column gaps. Header row uses plain text (no Unicode box-drawing characters).
**`Elapsed` column format** (active sessions) and **`Waiting` column** (queued):
- `< 60 s` → `"45s"`
- `< 1 h` → `"8m 30s"`
- `≥ 1 h` → `"2h 15m"`
**Empty-state rules:**
- No active sessions and no queued processes → prints `No active Claude Code sessions.`
and exits 0 (only this message, no tables).
- Active sessions present, no queued processes → prints active sessions table only.
- Queued processes present → prints active section (table or `No active Claude Code
sessions.`), blank line, then the queued table.
- The current `clr ps` process is never listed as a row (self-exclusion).
- Data sources: `/proc/{pid}/stat` (state, CPU, start time), `/proc/{pid}/status` (RAM),
`~/.claude/projects/` JSONL files (Task column), `/proc/{pid}/fd/0` symlink
(interactive TTY fallback for Task), `$CLR_GATE_DIR` (default `/tmp/clr-gate/`) JSON
files for queued processes.
- **Path shortening:** When the `PRO` environment variable is set and a session's working
directory starts with that path, the `Absolute Path` column (active) and `CWD` column
(queued) display the path with the `$PRO` prefix replaced by the literal string `"$PRO"`
(e.g. `$PRO/myrepo`). Falls back to the full absolute path when `PRO` is unset, empty,
or does not match.
**Gate state files:**
`gate.rs` writes a JSON state file to `$CLR_GATE_DIR/{pid}.json` when a `clr` process
enters `wait_for_session_slot()`. The file is updated each polling iteration and deleted
when the process acquires a slot or exhausts its retry budget.
File format:
```json
{"cwd": "/path/to/cwd", "since": 1720000000, "attempt": 3, "message": "waiting for session slot"}
```
- `cwd` — working directory of the waiting `clr` process
- `since` — Unix timestamp when waiting began
- `attempt` — current poll iteration (0-based)
- `message` — human-readable status string
**Exit Codes:**
| 0 | Success — table(s) printed, or no-sessions message printed |
| 1 | Error (unexpected I/O failure at startup) |
**Examples:**
```sh
# List all running sessions and queued waiters
clr ps
# Discover known subcommands (ps appears in help)
clr help
```
**Notes:**
`ps` is Linux-only; per-process metrics come from `/proc` and are not available
on macOS or Windows. On non-Linux platforms the command is not compiled in.
The Task column shows the last `"type":"user"` message from the session's JSONL
log when available (truncated to 35 chars). Falls back to `interactive (pts/N)`
when the process has a TTY stdin, or to `interactive` when neither source resolves.
`clr p` and `clr pss` trigger the "Did you mean 'ps'?" typo guard and exit 1.
The `CLR_GATE_DIR` environment variable overrides the default `/tmp/clr-gate/` gate
state directory — used in tests to isolate gate file I/O from real system state.
### Referenced Parameter Groups
None. `ps` accepts no parameters.
### Referenced User Stories
| 26 | [026_session_listing.md](../user_story/026_session_listing.md) | Developer / CI operator |