Guide 5 min read

Claude Code Said "Ran 3 Commands": How to See Which Ones

Claude Code folds tool calls into "Ran 3 commands". Expand the summary, read a past session's commands from its transcript with jq, or record every command an agent runs.

Madhubalan Appachi Madhubalan Appachi · Published

When Claude Code runs several tools in a row, it folds them into one line that starts with Ran: "Ran 3 commands", "Ran 1 shell command". That keeps the conversation readable, but the line doesn't say which commands ran, in which directory, or whether they succeeded. This guide shows three ways to find out: expanding the summary in the session you are in, reading the transcript of a past session, and recording every command as it runs so you never have to dig.

Review note: I build Suvadu, the tool in the last section. On 20 October 2026 I checked the Claude Code steps against Claude Code 2.1.270 and its transcript files, the Codex notes against Codex CLI 0.154, and the Suvadu commands against Suvadu 0.5.1.

In the session you are in: expand it

In the Claude Code terminal, press Ctrl+O, which Claude Code offers as "ctrl+o to expand". It switches to the full transcript, where each tool call shows its exact input, including the whole command, and its output. Press it again to go back.

That answers "what did it just run?" for the session on screen. It doesn't help once the session is closed, across several sessions, or when you want to ask "what failed in this project yesterday?"

In a past session: read the transcript

Claude Code writes each session to a JSON Lines file under ~/.claude/projects/, in a folder named after the project's path with each / replaced by -, as <session-id>.jsonl. Every shell command is a tool_use block named Bash. With jq, this prints the commands of the newest session in a project, in order:

cd ~/.claude/projects/-Users-you-code-my-app   # your project's folder
f=$(ls -t *.jsonl | head -1)                     # newest session
jq -r 'select(.type=="assistant") | .message.content[]?
       | select(.type=="tool_use" and .name=="Bash") | .input.command' "$f"

What this can't give you:

  • Exit status is not on the command. The result is in a separate tool_result block that you would have to match by id.
  • One session at a time. Searching every session for one command means looping over files in every project folder.
  • Only Claude Code. Other agents keep different files, or none you can query.

Codex CLI keeps sessions in ~/.codex/sessions/YYYY/MM/DD/rollout-*.jsonl. Recent versions run shell work through a script tool, so its commands are wrapped in script text rather than stored one per entry, and there is no reliable one-line query for them. Cursor shows the commands in its chat view while the conversation is open.

From now on: record every command as it runs

Most coding agents can call a program after each tool they run. Suvadu uses those hooks to record each command an agent runs, with its directory, exit code, duration and git branch, in a local SQLite database next to your own shell history. It covers Claude Code, Codex, Cursor, OpenCode and pi.dev that way, and Antigravity, which has no such hook, through a small capture script its agent's shells load.

brew tap AppachiTech/suvadu && brew install suvadu
suv init claude-code      # or: suv init codex, suv init cursor, suv init antigravity

Restart the agent, let it work, then ask your history instead of the transcript:

suv history --executor claude-code --after today   # every command it ran today, with exit codes
suv agent prompts                                   # each prompt and the commands it triggered
suv agent report --executor claude-code             # today's agent commands with risk flags
suv sessions                                        # whole sessions: prompts, responses, commands

The executor names are claude-code, openai-codex, cursor, opencode, pi and antigravity; --executor agent shows all of them. Agent commands stay out of your own Ctrl+R and Up-arrow recall unless you ask for them, and an agent connected to Suvadu's read-only MCP server can look them up too: "what failed in this project yesterday?"

Two limits to know:

  • Recording starts when the hook is installed. Commands an agent ran before that are not added. suv agent import-session <transcript.jsonl> brings in a past Claude Code or Codex session's conversation.
  • Only what the agent reports. Suvadu records what the agent's hooks pass on. For Claude Code that is every Bash tool call; see what each integration captures.

For a full walkthrough of tracing a failed agent run back to its prompt, its error and the files it changed, see Claude Code audit log: record every shell command it runs.

Try Suvadu with your own history

For macOS or Linux with Zsh 5.1+ or Bash 4+. Install the CLI, enable your shell, then try Ctrl+R.

1. Install the CLI

With Homebrew:

brew tap AppachiTech/suvadu && brew install suvadu
Other install methods

Install script. Works on macOS and Linux, Intel and ARM. Downloads a binary for your operating system and architecture, verifies its checksum, and installs to /usr/local/bin, using sudo only if that directory is not writable. End the command with bash -s -- --user instead to install into ~/.local/bin without sudo.

curl -fsSL https://downloads.appachi.tech/suvadu/install.sh | bash

Read the installer source.

Cargo. Requires Rust 1.95 or newer. Compiles from source, which can take a few minutes; cargo binstall suvadu installs the pre-built binaries instead. Make sure ~/.cargo/bin is on your PATH.

cargo install suvadu

2. Enable recording in your shell

Homebrew and Cargo do not activate shell recording, and the install script adds the hook line only if you answer y when it offers. Open the instructions for the shell you use. If another history tool owns Ctrl+R, disable its history binding before enabling Suvadu; keep your existing history data.

Zsh setup

Add this line once to ~/.zshrc. Keep the existing line if it is already present:

eval "$(suv init zsh)"

Save the file, then activate it in your Zsh terminal:

source ~/.zshrc
Bash setup

Add this line once to ~/.bashrc. Keep the existing line if it is already present:

eval "$(suv init bash)"

Save the file, then activate it in your Bash terminal:

source ~/.bashrc

Bash 4+ is required. For a login shell, make sure ~/.bash_profile sources ~/.bashrc, or use the startup file your shell reads. Shell setup details.

3. Check setup and try a search

suv doctor

Run echo hello, press Ctrl + R, and search for hello. Select a result to put it in your prompt; press Enter to run it. Agent and MCP setup are optional.

Import existing Zsh or Bash history, an Atuin database (read-only), or a Suvadu JSONL export.

Installation help · Troubleshooting · Update or uninstall

Madhubalan Appachi
Madhubalan Appachi

Builder of Suvadu. Writes Rust, thinks about shell history more than most people, and believes developer tools should be local-first.