agentps is a Linux command-line tool for inspecting local CLI coding-agent sessions. It scans live processes and on-disk session artifacts, then presents them as a ps-like inventory with resume and cleanup operations.
It currently includes built-in handlers for:
- OpenAI Codex CLI
- Claude Code
- Gemini CLI
- opencode
For an introduction and walkthrough, see the agentps blog post.
- Lists live and historical agent sessions across supported tools
- Maps a live process back to its session artifact when possible
- Shows agent, PID, user, last-used time, cwd, session id, and launch context
- Resumes a session from its recorded working directory
- Deletes orphaned sessions or duplicate copies
- Provides a curses TUI for browsing, grouping, copying resume commands, and deleting sessions
- Linux only
- Python 3.11+
agentps requires /proc and is designed around the session layouts used by the supported CLIs on a local Linux machine.
From the repository:
python -m pip install .For development:
python -m pip install -e .This package uses only the Python standard library at runtime.
List sessions:
agentps listOpen the interactive view:
agentpsPrint JSON:
agentps --json listShow recent sessions found directly in agent config directories:
agentps --traces listStop a runaway agent, or every agent under a directory:
agentps kill 9b1c6f2eJump to the tmux pane an agent is running in:
agentps attach 9b1c6f2eResume a session by id or unambiguous prefix:
agentps resume 9b1c6f2ePrint the resume command without executing it:
agentps resume --print 9b1c6f2eDelete sessions by id prefix:
agentps delete 9b1c6f2eDelete sessions whose recorded cwd no longer exists:
agentps delete --orphansDelete duplicate session copies across configured instances:
agentps delete --dupesagentps [OPTIONS] [top|list|resume|delete] [OPTIONS]
Global options are accepted on either side of the subcommand, so both of these work:
agentps --json list
agentps list --jsonSubcommands:
top: interactive TUI; also the default when no subcommand is givenlist: print the table to stdoutresume PREFIX: resume a session from its cwdattach PREFIX: switch to the tmux pane an agent is running inkill ...: signal the processes behind a session, by id prefix or cwd pathdelete ...: delete sessions by id prefix or by cwd path
Global options:
--json: emit JSON instead of the table--traces: include per-agent recent-session scans from config dirs--all: looser process detection, with higher false-positive risk-d,--delay: TUI refresh interval in seconds;0disables auto-refresh--config PATH: alternate config file; governs both the UI settings and which agent instances exist. Missing file is an error rather than a silent fallback to the default
Kill options:
-9,--force: sendSIGKILLinstead ofSIGTERM-y,--yes: skip confirmation
kill signals every process behind the matched sessions, and refuses to signal
the session agentps itself was launched from.
Delete options:
--orphans: delete sessions whose cwd no longer exists--dupes: delete duplicate copies of the same session id-y,--yes: skip confirmation
AGENT: the instance name, which is the handler name unless an[[extra]]gave it another onePID: the process holding the session, or-for a session with nothing running. A trailing+Nmeans N further processes share the same session — opencode opens one per attached client — and the number shown is the lowestS: process state —Rrunning,Ssleeping,Duninterruptible,Tstopped,ZzombieUSER: owner of the sessionLAST_USED: from the session artifact, or from the agent's own database for agents that do not keep per-session filesAGE: how long the process has been runningIDLE: time since the session was last written — the activity signal for an agent nobody is watching. A longIDLEon a running process is an agent that is waiting or stuckCWD: the recorded working directory. Sessions whose cwd no longer exists are grouped below a separator inlist, and dimmed in the TUISESSION: shortened session idWHERE: tmux pane, screen, or ssh when the process can be traced to one; otherwisevia:<name>for whatever launched it — a systemd unit, cron, or a script — which is the usual case for agents started headlessly
The TUI is a curses interface over the same inventory used by list.
Key actions:
j/kor arrow keys: moveEnteroro: open or expandSpace: mark row or groupa: switch to the agent's tmux panec: copy the resume command using OSC52K: SIGTERM the processes behind the focused or marked sessionsd: delete focused or marked sessionsg: toggle group-by-cwds: toggle sort between date and pathr: refreshh: helpqorEsc: quit
- Scans
~/.codex/sessions/ - Replays model, reasoning effort, approval mode, and sandbox mode from
state_5.sqlite - Deletion removes both the rollout file and the matching
threadsrow
- Scans
~/.claude/projects/ - Reads each session's own recorded
cwdfrom its JSONL. The encoded directory name is lossy —/home/u/my-projand/home/u/my/projencode identically — so it is only used for sessions that record nocwdof their own - Replays persisted permission mode on resume
- Scans
~/.gemini/tmp/ - Deduplicates per-project snapshot files by inner
sessionId - Replays launch-only flags such as yolo or approval settings only when a live process is available
- Gemini has no resume-by-id:
-rtakeslatestor a position within the project's sessions, so the index is only valid while that ordering holds. agentps resolves it immediately before launching, and copied or printed commands are emitted asagentps resume <id>so they re-resolve wherever they are pasted - If a session can no longer be located, resume fails with a message instead of falling back to the most recent session
- Reads
~/.local/share/opencode/opencode.db(SQLite); there are no per-session files - Archived sessions are hidden; the session id itself is used as the display id
- Replays the persisted model and agent on resume; launch-only flags such as
--dangerously-skip-permissionsonly when a live process is available - Deletion removes the
sessionrow (child rows cascade) and any leftoversession_diffblob
Default config path:
~/.config/agentps/config.toml
Supported UI settings:
[ui]
sort = "date" # "date" or "path"
date = "%m-%d-%Y" # strftime format for LAST_USED
delay = 60You can add extra agent instances, such as alternate config roots:
[[extra]]
name = "codex-api"
handler = "codex"
dir = "~/.codex-api"
[[extra]]
name = "claude-work"
handler = "claude"
dir = "~/work/.claude"
[extra.env]
EXAMPLE_FLAG = "1"Each [[extra]] entry binds a handler to another base directory and optional environment variables used during resume. dir is the handler's base directory, which is not always a dotfile config dir — for opencode it is the data dir holding opencode.db (default ~/.local/share/opencode).
User-defined handlers can be placed in:
~/.config/agentps/handlers/
Each handler module must expose a top-level HANDLER object derived from the internal Handler interface. User handlers shadow built-in handlers of the same name.
- Linux only
- Session detection depends on the supported CLIs' current on-disk layouts
- Resume fidelity varies by agent; some launch flags are reconstructable only for live sessions
--allcan match unrelated processes if their command lines look similar to a supported agent
MIT. See LICENSE.