Skip to main content

session-ls

List and search session history across all coding agents on your machine: pi, codex, claude, cursor.

$ session-ls -n 3
AGENT   STARTED              LAST                  CWD                            TITLE
codex   2026-07-29T00:03:17  2026-07-29T00:21:15   /home/alice/projects/website   fix the login redirect loop
pi      2026-07-17T14:42:45  2026-07-18T08:45:13   /home/alice/projects/backend   tune the postgres connection pool
claude  2026-06-15T03:08:57  2026-06-15T03:31:55   /home/alice/dotfiles           migrate to starship prompt

Sessions are read directly from each agent's local store, newest first. The title of a session is the first thing the person actually typed. Injected context (plugin lists, AGENTS.md, environment blocks, image wrappers, slash-command echoes) is skipped part by part, and wrapped requests are unwrapped: Codex desktop's ## My request:, a thread goal's <objective>, and chat bridges' <user_input>.

Design

  • Fast. Metadata is cached in ~/.cache/session_ls_cache.json, keyed by file size + mtime; unchanged files are never re-read. Listing ~1000 sessions takes milliseconds. Full-text search streams literal matches and decoded JSON Unicode text. A long-lived HistoryIndex rescans only what changed: unchanged directories keep their listings and unchanged files their records (every file is still lstated).
  • Plain search, no semantics. No index, no embeddings, no network. Matching is literal substring comparison. Decide what's relevant yourself - or hand the file paths to an LLM.
  • Lightweight, zero dependencies. Pure stdlib: a legacy session-ls CLI, and a versioned typed API (session_ls.api) for programs such as 4top.
  • Extensible. Adding another agent is one REGISTRY entry plus two small functions (see below).

Install

uv tool install session-ls   # or:
pipx install session-ls      # isolated environment
pip install session-ls       # into the current environment
pip install -e '.[dev]'      # from a checkout, to work on it

Requires Python >= 3.9. A man page (session-ls(1)) is installed alongside; on macOS venvs, point MANPATH at the venv's share/man to see it.

Usage

session-ls [KEYWORD] [OPTIONS]
Option Meaning
KEYWORD search titles (first user message), case-insensitive substring
-f, --full search full session content instead of titles (literal decoded-text scan)
-a, --agent only this agent: pi, codex, claude, cursor
-c, --cwd only sessions under a cwd substring
--since DATE started on/after (YYYY-MM-DD)
--until DATE last active on/before (YYYY-MM-DD)
-n, --limit N show only the N newest
-l, --list print file paths only (for piping)
--json JSON Lines output (keys: agent, cwd, started, last, title, file)

Examples

session-ls -n 10                              # ten most recent sessions
session-ls websocket                              # title search
session-ls "immich 2283" -f                  # full-content search
session-ls -a pi -c nemo --since 2026-08-01   # filters combine
session-ls websocket -l | xargs head -1          # inspect raw matches
session-ls websocket --json | jq -r .file        # feed paths to other tools

Supported agents

Agent Store Timestamps
pi ~/.pi/agent/sessions/<encoded-cwd>/*.jsonl in file
codex ~/.codex/sessions/YYYY/MM/DD/rollout-*.jsonl (+ archived_sessions/) in file
claude ~/.claude/projects/<encoded-cwd>/*.jsonl in file
cursor ~/.cursor/projects/*/agent-transcripts/<id>/<id>.jsonl file mtime (none in file)

Adding an agent

Append an entry to REGISTRY in src/session_ls/__init__.py:

  1. a glob of session files
  2. meta_parser(f, head) -> (cwd, started_iso) | None
  3. user_text(line) -> first real user text | '' (drives the early-exit read)
REGISTRY = [
    # (name, glob, meta-parser, user-text-extractor)
    ("myagent", os.path.join(HOME, ".myagent/sessions/*.jsonl"),
     _myagent_meta, _myagent_user),
]

Agent skill

For AI agents (pi et al.), skills/session-ls/SKILL.md is a ready-to-install skill: when to use session-ls, common flag combos, and how to pipe results into a read of the underlying session files. Copy skills/session-ls into your agent's skills directory to enable it.

Development

python -m pytest tests/        # plain asserts, also runnable via pytest
python -m session_ls ...       # run from a checkout

License

MIT

0.2 API

session_ls.api exposes explicit Root, HistoryIndex, HistoryRecord, search_full, and excerpt objects. Inject roots/cache/host identity rather than changing process-global HOME. The legacy command still emits the same six JSON fields. Package imports do not change SIGPIPE. No TUI dependencies are required.

HistoryRecord.subagent is true for a session another agent session started for itself (Codex thread_spawn workers and the guardian approval reviewer), and HistoryRecord.parent is the spawning session's native id when the child names it. Both default to "not a subagent". HistoryRecord.scripted is true for a session started with no person at a prompt (claude -p or the Claude Agent SDK, codex exec or the Codex SDK; Pi records no such marker).

In the API, a first message too short to say anything (at most 8 terminal columns once whitespace is collapsed: "hi", "pwd", "exit", or nothing) gives way to the session's own name when it has one: Claude's latest rename, else its generated title, else its agent name; Pi's session name; Codex's thread name from session_index.jsonl. The session-ls command keeps the first message.

Metadata

Release files for session-ls 0.2.4

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for session-ls 0.2.4
File Size Uploaded
session_ls-0.2.4.tar.gz 41.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for session-ls 0.2.4
File Interpreter ABI Platform
session_ls-0.2.4-py3-none-any.whl Python 3 none any Details

Total release size: 68.5 kB

Release files / session_ls-0.2.4.tar.gz

Download URL session_ls-0.2.4.tar.gz
Size 41.9 kB
Tags Source
SHA-256 checksum
How to use checksums
4aa024020155dfe892554c10d7866d40163967822de18a9b03c260c0b1ada3ae
BLAKE2b-256 checksum
How to use checksums
f72944bfa69968bff600f3fc961fe22714e6cc57dc182643ea5c264b5b5d4536
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / session_ls-0.2.4-py3-none-any.whl

Download URL session_ls-0.2.4-py3-none-any.whl
Size 26.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
0a6f4bffe760033f0f6c8c6ad52ac628ceb65f65fd991af8c47574181efdc819
BLAKE2b-256 checksum
How to use checksums
bf78c93f795f24943348d745ee2c0d48109f11335d66b3d39c0ed43dd55d0127
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release history Release notifications | RSS feed

This release

0.2.4 This release

2 release files

0.2.3

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page