lsals for agent sessions. List every session from every coding agent on the
machine, newest first. Resume the conversation, watch it work in the
background, print it or continue it in another agent.

Like ls, lsa on its own lists the sessions started in the current
directory. -a lists them all. Listing takes about as long as ls -l.
One command, on macOS or Linux:
curl -fLO https://github.com/jakemanger/lsa/releases/latest/download/lsa && sudo install lsa /usr/local/bin/
Downloads lsa and installs it with executable permissions.
Oh My Zsh? Replace its default lsa='ls -lah' alias with the lsa command:
printf '\nunalias lsa 2>/dev/null\n' >> ~/.zshrc && source ~/.zshrc
Needs bash 3.2 or later, grep, sed, awk, find, stat and ps. lsa show also
needs jq 1.6 or later, and the database-backed agents need sqlite3.
Homebrew (macOS and Linux):
brew install jakemanger/tap/lsa
Debian / Ubuntu:
sudo mkdir -p /etc/apt/keyrings
sudo curl -fsSL https://jakemanger.github.io/lsa/apt/lsa.asc -o /etc/apt/keyrings/lsa.asc
sudo curl -fsSL https://jakemanger.github.io/lsa/apt/lsa.sources -o /etc/apt/sources.list.d/lsa.sources
sudo apt update && sudo apt install lsa
Add the repository once; subsequent updates come through sudo apt upgrade.
Fedora / RHEL:
curl -fLO https://github.com/jakemanger/lsa/releases/latest/download/lsa.rpm
sudo dnf install ./lsa.rpm
Arch Linux:
curl -fLO https://github.com/jakemanger/lsa/releases/latest/download/lsa.pkg.tar.zst
sudo pacman -U ./lsa.pkg.tar.zst
The Homebrew tap supports brew upgrade lsa. RPM and Arch packages are
release downloads; use the same commands to update them. All package managers
install the required dependencies.
| Agent | List | Show | Resume | Tested | |
|---|---|---|---|---|---|
| Claude Code | ✳ | ✓ | ✓ | ✓ | ✓ |
| Codex | ⌘ | ✓ | ✓ | ✓ | ✓ |
| pi | π | ✓ | ✓ | ✓ | ✓ |
| Qwen Code | ❯ | ✓ | ✓ | ✓ | ✓ |
| OpenCode | ◐ | ✓ | ✓ | ✓ | ✓ |
| Goose | 🪿 | ✓ | ✓ | ✓ | ✓ |
| Cline | ⌬ | ✓ | ✓ | ✓ | ✓ |
| Muse Code (Meta) | ◈ | ✓ | ✓ | ✓ | ✓ |
| OpenClaw | 🦞 | ✓ | ✓ | ✓ | ✓ |
| Gemini CLI | ✦ | ✓ | ✓ | ✓ | from source |
Tested means I installed the agent, ran a session and checked that lsa
listed it, printed it and reopened it. Gemini CLI needs a Google account
I do not have, so its reader was written from the CLI’s own source and
the fixture matches what that code writes.
Resume runs the agent’s own command (claude --resume, codex resume,
muse resume, and so on) from the directory the session was started in,
because most agents only find a session from there. lsa -l adds the full
working directory and transcript path as columns on the same row.
OpenClaw sessions
are chats rather than projects, so their directory column shows the session
key instead.
Tools like herdr, Claude Squad and cmux are new terminal multiplexers built
for agents: a pane each, with a live view of which one is blocked. The part
most people actually want is to get back into a session and leave it
running. That is already possible with simple Unix tools: tmux keeps the
agents running, and lsa finds and resumes their sessions.
lsa aims to follow the Unix philosophy: do one job well, and work with
other programs through text streams. Its output is plain text you can pipe
to grep, less or awk.
If all you wanted from a session manager was to find the conversation you were
in and pick it up again, this is one that is one more letter than ls.
Already use tmux? lsa resume 0 attaches to the pane the session is
already running in rather than starting a second agent on the same
transcript, and ctrl-b d leaves it running in the background. To check on
it, lsa shows whether it is still working and lsa show 0 prints what it
has done since.
lsa sessions started in this directory
lsa -a every session
lsa ~/code/foo sessions started in another directory
lsa -t codex -n 5 the five newest Codex sessions here
lsa -l add full directory and transcript path columns
lsa show 659c print a transcript as plain text
lsa path 659c print where the transcript lives
lsa resume 659c reopen it in its own agent
lsa resume 0 the same by index, like tmux attach -t 0
lsa handoff 0 codex continue the newest session in Codex

A session whose agent is still working on a turn shows a green ● and how
long that turn has been running in place of its age:
0 claude ● 2m 3e1f add a --dry-run flag to the deploy script
1 codex 15m ago 01a0c7d the flaky test in api/test_auth.py
Use a session’s index or short id. Index 0 is the newest session.
Indexes stay the same when filtering.
Any unique prefix of the full id also works.
Page, search or save a transcript:
lsa show 659c | less
lsa show 659c | grep -n 'TODO'
lsa show 659c > transcript.txt
Continue a session in another agent:
lsa handoff 0 codex
lsa handoff 659c claude
lsa handoff 659c pi
handoff rewrites the conversation in the new agent’s own session format and
resumes it there, as if that agent had recorded it. The history shows and the
agent waits for your next message. Tool calls and results come across as text.
If an agent’s session format has changed, handoff starts it with the
conversation as its first message instead.
You can also pipe a session from any supported agent into another agent’s
non-interactive mode. Run these from the session’s project directory:
lsa show 659c | claude -p "Continue this conversation from where it left off."
lsa show 659c | pi -p "Continue this conversation from where it left off."
These examples run non-interactively; use handoff to keep chatting.
| Agent | Where | Override |
|---|---|---|
| Claude Code | ~/.claude/projects/*/*.jsonl |
CLAUDE_CONFIG_DIR |
| Codex | ~/.codex/sessions/YYYY/MM/DD/*.jsonl |
CODEX_HOME |
| pi | ~/.pi/agent/sessions/*/*.jsonl |
PI_CODING_AGENT_DIR, PI_CODING_AGENT_SESSION_DIR, sessionDir |
| Qwen Code | ~/.qwen/projects/*/chats/*.jsonl |
QWEN_HOME, QWEN_RUNTIME_DIR |
| Gemini CLI | ~/.gemini/tmp/*/chats/session-*.jsonl + projects.json |
GEMINI_CLI_HOME |
| Cline | ~/.cline/data/sessions/*/*.json |
CLINE_DIR, CLINE_DATA_DIR, CLINE_SESSION_DATA_DIR |
| OpenCode | ~/.local/share/opencode/opencode.db |
XDG_DATA_HOME, OPENCODE_DB |
| Goose | ~/.local/share/goose/sessions/sessions.db |
XDG_DATA_HOME, GOOSE_PATH_ROOT |
| Muse Code | ~/.local/share/muse/session-index.db |
XDG_DATA_HOME |
| OpenClaw | ~/.openclaw/agents/*/agent/openclaw-agent.sqlite |
OPENCLAW_STATE_DIR, OPENCLAW_HOME |
These are the same on macOS and Linux. Overrides are followed when they are
absolute paths; a relative one depends on the directory the agent starts in.
The last four are SQLite databases and are read with the sqlite3 binary
that ships with macOS and most Linux distributions; without it those
agents are silently skipped.
A session’s directory and first prompt never change, so they are cached in
~/.cache/lsa/ after the first run. Listing is then one directory scan,
one stat and one awk, about the cost of ls -l on the same files.
Delete the index cache if you ever want a rescan. Listing and showing sessions
only read local data. handoff also writes a new session into the destination
agent’s store and launches it.
Open an issue with the agent’s name and where it keeps its sessions. Pull
requests welcome.
make test run the fixture tests
make lint ShellCheck, workflow lint and formula syntax
make packages build .deb, .rpm and Arch packages (needs nFPM)
make check-packages check the release files locally
make formula refresh the Homebrew formula's version and checksum
make install copy to /usr/local/bin
demo/record.sh re-record the gifs (asciinema + agg, Goose over ollama,
and an authenticated Claude Code for the handoff)
If lsa saves you time, you can sponsor its development.
MIT.
Made with ❤️ and ☕ by Jake Manger