An open API service indexing awesome lists of open source software.

https://github.com/nihen/ah

Agent History — search and browse AI coding agent sessions (Claude, Codex, Gemini, Copilot, Cursor) from a single CLI
https://github.com/nihen/ah

ai-agent claude-code-cli codex-cli developer-tool rust-cli

Last synced: 16 days ago
JSON representation

Agent History — search and browse AI coding agent sessions (Claude, Codex, Gemini, Copilot, Cursor) from a single CLI

Awesome Lists containing this project

README

          

# Agent History (ah)

**A**gent **H**istory — search, inspect, and resume coding-agent sessions from a single CLI.

`ah` discovers session files from [Claude Code](https://claude.ai/), [Codex](https://github.com/openai/codex), [Gemini CLI](https://github.com/google-gemini/gemini-cli), [Cursor](https://cursor.com/), and [GitHub Copilot CLI](https://docs.github.com/en/copilot/github-copilot-in-the-cli). It works with zero config, defaults to the current directory, and gives you one place to search, inspect, and resume past work.

Read-only by default. `ah` works directly on agent session files, lets you search and inspect them, and only executes when you explicitly run `resume`.

## Demo

![Demo](demo/demo.svg)

## Quick Look

On a TTY, `ah log` outputs in `git log` style with auto-pager. Defaults to current directory:

```console
$ ah log
session a1b2c3d4-5e6f-7a8b-9c0d-e1f2a3b4c5d6
Agent: claude
Project: my-webapp
Cwd: /home/user/src/my-webapp
Date: 2026-03-23 14:00 - 2026-03-23 18:00

implement OAuth2 authentication flow

session e5f6a7b8-9c0d-1e2f-3a4b-5c6d7e8f9a0b
Agent: cursor
Project: my-webapp
Cwd: /home/user/src/my-webapp
Date: 2026-03-23 12:15 - 2026-03-23 14:22

fix memory leak in worker pool
```

Pick a session ID from the log and resume it — `ah` launches the original agent's resume command (e.g. `claude --resume`):

```console
$ ah resume a1b2c3d4-5e6f-7a8b-9c0d-e1f2a3b4c5d6
```

Want the exact command first without executing anything?

```console
$ ah resume --print a1b2c3d4-5e6f-7a8b-9c0d-e1f2a3b4c5d6
cd '/home/user/src/my-webapp' && 'claude' '--resume' 'a1b2c3d4-5e6f-7a8b-9c0d-e1f2a3b4c5d6'
```

Or browse and filter sessions with `-i` (via [fzf](https://github.com/junegunn/fzf) or compatible finder, with transcript preview):

```console
$ ah resume -i
```

Full-text search across all directories (piped output is plain TSV):

```console
$ ah log -a -q "OAuth" | head -3
claude my-webapp 2026-03-23 18:00 implement OAuth2 authentication flow ...implement OAuth2 auth... a1b2c3d4-5e6f-7a8b-9c0d-e1f2a3b4c5d6
cursor my-webapp 2026-03-23 14:22 fix memory leak in worker pool ...reviewing the OAuth token... e5f6a7b8-9c0d-1e2f-3a4b-5c6d7e8f9a0b
codex api-server 2026-03-22 11:30 add Redis caching layer ...cache OAuth tokens with 1h TTL... sess_7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b
```

Show a session transcript:

```console
$ ah show a1b2c3d4
>>> implement OAuth2 authentication flow

I'll implement the OAuth2 flow. Let me start by reading the existing auth module...
```

Sessions grouped by project:

```console
$ ah project -a
PROJECT SESSION_COUNT LAST_MODIFIED_AT AGENTS
my-webapp 18 2026-03-23 18:00 claude, codex, cursor, gemini
api-server 14 2026-03-23 09:15 claude, codex, copilot, cursor
ml-pipeline 11 2026-03-22 08:50 claude, copilot, gemini
infra 5 2026-03-20 17:40 codex, cursor
docs 3 2026-03-19 11:25 claude, gemini
```

List agent memory and instruction files across all agents:

```console
$ ah memory -a
AGENT PROJECT TYPE NAME MODIFIED_AT DESCRIPTION
claude my-webapp feedback always-run-tests 2026-03-23 18:00 Run test suite before committing
claude my-webapp instruction CLAUDE.md 2026-03-22 10:00
codex my-webapp instruction AGENTS.md 2026-03-21 15:30
```

Show session summary per agent:

```console
$ ah agent
AGENT SESSIONS LATEST
claude 50 2026-03-24 17:55
codex 42 2026-03-24 16:32
copilot 18 2026-03-23 19:00
cursor 12 2026-03-22 13:40
gemini 5 2026-03-21 10:50
```

## Support Matrix

| Agent | List | Search | Show | Resume | Running | Memory |
|-------|------|--------|------|--------|---------|--------|
| Claude | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Codex | ✓ | ✓ | ✓ | ✓ | | |
| Gemini | ✓ | ✓ | ✓ | ✓ | | |
| Copilot | ✓ | ✓ | ✓ | ✓ | | |
| Cursor | ✓ | ✓ | ✓ | ✓ | | |

## Features

- **Cross-agent** — one tool for 5 agents (see `ah list-agents`)
- **Zero-config** — scans the standard session locations for each supported CLI
- **Fast** — parallel file collection with [rayon](https://github.com/rayon-rs/rayon), regex search via [memmap2](https://github.com/RazrFalcon/memmap2-rs), no subprocesses for search/parsing
- **Resume-friendly** — `ah resume` and `ah show` can target the latest matching session without pasting IDs
- **Structured output** — `git log`-style multi-line format with auto-pager on TTY, plain TSV when piped, plus `--table`, `--json`, `--ltsv`
- **Interactive** — `-i` adds fuzzy selection with transcript preview (via [fzf](https://github.com/junegunn/fzf) or compatible finder)

## Installation

### Homebrew

```bash
brew install nihen/tap/ah
```

Supported in the tap today:
- Apple Silicon macOS
- Linux x86_64

Intel Mac users should use Cargo or a source build.

### Cargo

```bash
cargo install ah-cli
```

### From binary

Download a prebuilt binary from [GitHub Releases](https://github.com/nihen/ah/releases).

Available today:
- macOS arm64
- Linux x86_64

### From source

```bash
cargo install --git https://github.com/nihen/ah
```

### Shell completion

```bash
# zsh
mkdir -p ~/.zfunc && ah completion zsh > ~/.zfunc/_ah
# Add to .zshrc: fpath=(~/.zfunc $fpath); autoload -Uz compinit && compinit

# bash
ah completion bash > ~/.local/share/bash-completion/completions/ah

# fish
ah completion fish > ~/.config/fish/completions/ah.fish
```

## Tips

### Interactive mode (-i)

Most commands support `-i` for fuzzy selection with transcript preview. Requires [`fzf`](https://github.com/junegunn/fzf) or a compatible finder (e.g. [`sk`](https://github.com/lotabout/skim)) in `PATH`. Override with `$AH_SELECTOR`.

Useful as a shell function — pick a project, browse its sessions, resume:

```bash
ahr() { local d; d="$(ah project -i)" && ah resume -i -d "$d"; }
```

## Command-line options

### `ah -h`

```
Search, inspect, and resume coding-agent sessions from one CLI
(read-only except resume)

Defaults to the current directory. Use -a to search across all known sessions.

Usage:
ah [OPTIONS]

Commands:
log List sessions
project List known projects
show Show session transcript
resume Resume an agent session
memory List agent memory and instruction files
agent Show session summary per agent

Help / setup:
list-agents List supported agents
completion Generate shell completion script
man Generate man page

Global options:
-a, --all Show all sessions (disable default cwd filtering)
--agent Filter by agent name (e.g. claude, codex, gemini)
--project Filter by project name
-d, --dir Filter by working directory (default: current directory)
-q, --query Full-text search query (regex, case-insensitive)
-p, --prompt-only Search only user prompts (use with -q)
-n, --limit N Max session files to scan (default: 0, no limit)
-i, --interactive Interactive mode via fuzzy finder (fzf/sk)
-s Override fuzzy selector (default: $AH_SELECTOR or fzf)
--no-preview Disable preview in interactive mode
--running Show only currently running sessions (Claude only for now)
--since Show sessions newer than (e.g. "2026-03-20", "3d", "1w", "2m" = ~60 days)
--until Show sessions older than (e.g. "2026-03-20", "3d", "1w", "2m" = ~60 days)
--color Force colored output (even through pipes)
--no-color Disable colored output
--no-pager Disable automatic pager
-h, --help Show this help
-V, --version Show version

Examples:
ah log # latest sessions for the current directory
ah log -a -q "auth" # search across all known sessions
ah resume # resume the latest matching session
ah show -q "OAuth" # show the latest matching session
ah resume -i # browse sessions with fzf/sk and resume

Run `ah --help` for subcommand-specific options.
```

### `ah log --help`

```
List sessions

Usage:
ah log [OPTIONS]

Options:
-o, --fields Select output fields (replaces defaults, see --list-fields)
Default: agent, project, modified_at, title, id
With -q: agent, project, modified_at, title, matched, id
-O, --extra-fields Add fields to defaults (comma-separated)
--table Aligned table with header row
--tsv Tab-separated values (no header, no color)
--ltsv Labeled Tab-Separated Values (in -i mode: selector display format)
--json JSON Lines output
-S, --sort Sort by field (default: modified_at)
--asc Sort ascending
--desc Sort descending (default)
--transcript-limit N Max characters for transcript field (default: 500)
--title-limit N Max characters for auto-generated title (default: 50, 0 = no limit)
-L, --list-fields List available output fields and exit (use with --json for machine-readable output)

Default output (when no format flag is given):
git-log style multi-line with auto-pager on TTY, plain TSV when piped

Interactive mode:
-i, --interactive Browse sessions via fuzzy finder; prints selected path
-s Selector command (default: $AH_SELECTOR or fzf)
--no-preview Disable transcript preview (enabled by default for fzf, sk)

Global options are also available (see ah -h).
```

### `ah show --help`

```
Show session transcript

Usage:
ah show [OPTIONS] [SESSION]

If SESSION is omitted, ah shows the latest session matching stdin, -q, and other filters.

Options:
--head N Show first N messages only
--pretty Pretty-print with colors (default)
--raw Output raw session file content
--json Output normalized JSON Lines ({"role":"user","text":"..."})
--md Output as Markdown (## User / ## Assistant headers)
-f, --follow Follow session output in real-time (like tail -f)

Interactive mode:
-i, --interactive Select session via fuzzy finder then show it
-o, --fields Display fields in interactive mode (default: agent,project,modified_at,title)
-s Selector command (default: $AH_SELECTOR or fzf)
--no-preview Disable transcript preview

Global options are also available (see ah -h).
```

### `ah resume --help`

```
Resume an agent session

Usage:
ah resume [OPTIONS] [SESSION] [-- EXTRA_ARGS...]

If SESSION is omitted, ah resumes the latest session matching stdin, -q, and other filters.

Arguments after -- are passed directly to the agent command.

The only command that launches an agent process; other commands are read-only.

Options:
--print Print the resolved resume command and exit (read-only; does not execute)

Interactive mode:
-i, --interactive Select session via fuzzy finder then resume it
-o, --fields Display fields in interactive mode (default: agent,project,modified_at,title)
-s Selector command (default: $AH_SELECTOR or fzf)
--ltsv Use LTSV format for interactive selector display
--no-preview Disable transcript preview

Examples:
ah resume # resume latest matching session
ah resume --print # print the resolved resume command
ah resume a1b2c3d4 # resume by ID
ah resume -i # interactive selection
ah resume -- --dry-run # pass extra args to agent

Global options are also available (see ah -h).
```

### `ah project --help`

```
List known projects

Usage:
ah project [OPTIONS]

Options:
-o, --fields Select output fields (replaces defaults, see --list-fields)
Default: project, session_count, last_modified_at, agents
In -i mode default: cwd, project, session_count, last_modified_at
-O, --extra-fields Add fields to defaults (comma-separated)
--table Aligned table with header row
--tsv Tab-separated values (no header, no color)
--ltsv Labeled Tab-Separated Values (in -i mode: selector display format)
--json JSON Lines output
-S, --sort Sort by field (default: last_modified_at)
--asc Sort ascending
--desc Sort descending (default)
-L, --list-fields List available output fields and exit (use with --json for machine-readable output)

Default output (when no format flag is given):
Aligned table with auto-pager on TTY, plain TSV when piped

Interactive mode:
-i, --interactive Browse projects via fuzzy finder; prints selected cwd
-s Selector command (default: $AH_SELECTOR or fzf)
--no-preview Disable preview

Global options are also available (see ah -h).
```

### `ah memory --help`

```
List agent memory files

Usage:
ah memory [OPTIONS]

Options:
-o, --fields Select output fields (replaces defaults, see --list-fields)
Default: agent, project, type, name, modified_at, description
-O, --extra-fields Add fields to defaults (comma-separated)
-t, --type Filter by memory type (user/feedback/project/reference/instruction)
--table Aligned table with header row
--tsv Tab-separated values (no header, no color)
--ltsv Labeled Tab-Separated Values
--json JSON Lines output
-S, --sort Sort by field (default: modified_at)
--asc Sort ascending
--desc Sort descending (default)
-L, --list-fields List available output fields and exit (use with --json for machine-readable output)

Default output (when no format flag is given):
Aligned table with auto-pager on TTY, plain TSV when piped

Interactive mode:
-i, --interactive Browse memory files via fuzzy finder
-s Selector command (default: $AH_SELECTOR or fzf)
--no-preview Disable preview

Global options are also available (see ah -h).
```

### `ah agent --help`

```
Show session summary per agent

Usage:
ah agent [OPTIONS]

Shows how many sessions were found for each agent and the latest modified time.

Options:
--table Output as aligned table
--tsv Output as TSV (tab-separated values)
--ltsv Output as LTSV (Labeled TSV)
--json Output as JSON Lines

Default output (when no format flag is given):
Aligned table with auto-pager on TTY, plain TSV when piped

Global options are also available (see ah -h).
```

## Configuration (~/.ahrc)

`ah` works out of the box with no configuration. Optionally, create `~/.ahrc` (TOML) to customize agent settings.

### Disable an agent

```toml
[agents.codex]
disabled = true
```

### Add extra file patterns to a built-in agent

```toml
[agents.claude]
extra_patterns = ["~/claude-archive/projects/*/*.jsonl"]
```

### Add a custom agent (using an existing plugin's parser)

```toml
[agents.aider]
plugin = "claude"
file_patterns = ["~/.aider/history/*.jsonl"]
```

Available plugins: `claude`, `codex`, `gemini`, `copilot`, `cursor`. The `plugin` field tells `ah` how to parse the session files.

### Environment variables

Each built-in agent respects its CLI's config directory environment variable:

| Agent | Session Files | Env Var | Default |
|---------|---------------|--------------------|-------------|
| Claude | `projects/*/*.jsonl` | `CLAUDE_CONFIG_DIR`| `~/.claude` |
| Codex | `sessions/**/*.jsonl` | `CODEX_HOME` | `~/.codex` |
| Gemini | `tmp/*/chats/session-*.json` | `GEMINI_CLI_HOME` | `~/.gemini` |
| Copilot | `session-state/*/workspace.yaml` | `COPILOT_HOME` | `~/.copilot`|
| Cursor | `projects/*/agent-transcripts/**/*.jsonl` | `CURSOR_CONFIG_DIR`| `~/.cursor` |

Run `ah list-agents` to see the full configuration including glob patterns and capabilities.

Additional environment variables:

| Env Var | Description |
|------------|-------------|
| `AH_PAGER` | Override pager command (default: `less`). Set to empty string to disable |
| `PAGER` | Fallback pager command (used if `AH_PAGER` is not set) |
| `AH_COLOR` | Set to `1` to force colored output (like `--color`) |
| `NO_COLOR` | Set to disable colored output ([no-color.org](https://no-color.org/)) |

## Examples

### SQL with [trdsql](https://github.com/noborus/trdsql)

```bash
ah log -a --ltsv | trdsql -iltsv "SELECT * FROM - WHERE agent='claude'"
ah log -a --ltsv | trdsql -iltsv "SELECT agent, COUNT(*) as cnt FROM - GROUP BY agent"
```

### JSON with [jq](https://github.com/jqlang/jq)

```bash
ah log -a --json | jq '.project'
ah log -a --json -n 1 | jq '.'
ah project --json | jq '.project' # list project names
```

### Piping

```bash
ah log -q "auth" -o path | head -1 | ah show # show latest match
ah log -q "auth" -o path | head -1 | ah resume # resume latest match
ah log -a -o project | sort | uniq -c | sort -rn # project ranking
```

## For AI Agents (CLAUDE.md / AGENTS.md)

Add this line to your project or global instructions so your coding agent knows about `ah`:

```
`ah` — cross-agent session history CLI. Run `ah -h` for usage; key commands: `ah log` (list sessions), `ah show` (view transcript), `ah log -a -q "keyword"` (search all).
```

## Roadmap

- **Remote session aggregation** — `ssh` to a remote host running `ah`, aggregate results locally. Like rsync's remote process model: computation happens near the data, only metadata travels over the wire.

## License

[MIT](LICENSE)