ah
Health Uyari
- License — License: MIT
- Description — Repository has a description
- Active repo — Last push 0 days ago
- Low visibility — Only 8 GitHub stars
Code Basarisiz
- rm -rf — Recursive force deletion command in demo/setup.sh
- rm -rf — Recursive force deletion command in demo/teardown.sh
Permissions Gecti
- Permissions — No dangerous permissions requested
Bu listing icin henuz AI raporu yok.
Agent History — search and browse AI coding agent sessions (Claude, Codex, Gemini, Copilot, Cursor) from a single CLI
Agent History (ah)
Agent History — search, inspect, and resume coding-agent sessions from a single CLI.
ah discovers session files from Claude Code, Codex, Gemini CLI, Cursor, GitHub Copilot CLI, Antigravity CLI (agy), Grok CLI (grok), and opencode (opencode). 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
Quick Look
On a TTY, ah log outputs in git log style with auto-pager. Defaults to current directory:
$ 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):
$ ah resume a1b2c3d4-5e6f-7a8b-9c0d-e1f2a3b4c5d6
Want the exact command first without executing anything?
$ 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 or compatible finder, with transcript preview):
$ ah resume -i
Full-text search across all directories (piped output is plain TSV). -q searches the conversation — user and assistant messages plus tool calls (commands, arguments, file paths) and tool output — not JSON keys or injected instructions. Use -p to search only your prompts, or --raw-search to match the raw session files including metadata:
$ 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
Find the actual passages instead of just the sessions:
ah search 'OAuth' # every occurrence in the current directory
ah search 'OAuth' -a --json # JSON Lines across all directories
ah search '認証' -p # user prompts only
ah search 'error' --max-matches 20
ah search 'OAuth' --verbose # full log paths and match positions on TTY
ah search 'OAuth' --kind user,assistant # conversation text only
ah search 'error' --kind tool-output # tool results only
ah search 'OAuth' -i # pick a hit, preview context, Enter to show
log -q returns one row per session with its first matching excerpt.search returns one row per non-overlapping regex occurrence, including
multiple occurrences in a single message and matches in tool input/output.
It uses the same case-insensitive regex and content extraction as log -q.
No index or external search service is required.
On a terminal, passages are grouped by session with an automatic pager.
Like rg --heading or git grep --heading --break, the default display puts
one heading above each group of passages and a blank line between sessions.
Session headings are cyan and bold, titles are bold, and dates are dim.
Each passage appears on its own indented line with a structural kind label
(user, assistant, tool-input, tool-output, or unknown), with the current occurrence
highlighted in bold yellow. Full log paths and position labels are omitted by
default so the passages stay compact. Remote session headings keep aremote:NAME label to distinguish hosts.
Use -v / --verbose to show the full log path and a dim position line before
each passage. Positions are labeled text #N bytes START..END: text #N
is a search-fragment index, not a transcript line number. Verbose output
also includes an opaque at POSITION token and separates passages with blank lines. This flag only affects terminal
output; JSON/TSV retain all their existing fields and formatting.
If a match is clipped by the snippet limit, only its visible portion is
highlighted. --no-color andNO_COLOR disable styling; NO_COLOR takes precedence over --color, as with
other commands. JSON/TSV output never receives display colors.
Piped output is TSV without a header, with these columns:path, agent, project, id, text_index, match_start, match_end, snippet, kind, position.
Tabs, newlines, carriage returns, and backslashes are escaped as \t, \n,\r, and \\. JSON Lines contains the same fields plus modified_at andtitle, with numbers represented as JSON numbers.
text_indexis a 1-based index of nonempty search fragments, counted before
kind filtering. It is not a transcript message number. One tool call can yield
several fragments. Useposition, not this index, for navigation.kindis derived from log structure, never inferred from the text. Ambiguous
records remainunknown(for example, Antigravity's generic model records).--kindaccepts a comma-separated union; the default includes every kind.-pis shorthand for--kind userand includes all user text parts, but not
tool results stored in user-role containers. It cannot be combined with other
kinds.log -p -qkeeps its existing prompt extraction behavior.positionis an opaque versioned location within the session identified bypath. It includes a fingerprint of the searchable source prefix. Do not
construct it yourself. Filtering and snippet length do not change positions;
appending records preserves them. An edited/reordered prefix requires a new
search instead of silently opening a different occurrence.match_start/match_endare 0-based UTF-8 byte offsets, with an exclusive
end, in the decoded fragment (not the snippet or raw file).- Snippets contain at most
--snippet-lengthUnicode characters (default 240),
including ellipses. Even a match longer than the limit is truncated; offsets
still describe the full match. - Sessions sort by
modified_atdescending, then path ascending for ties.
Occurrences within a session follow source order. This is not relevance order
or individual-message timestamp order. --max-matchescaps occurrences across all sessions and hosts (default 100;0means unlimited).-nstill limits session files scanned, not results.
The cap does not guarantee fewer files scanned; the existing session pipeline
first finds candidates, then search enumerates their occurrences.-a,-d,--agent,--project,--since,--until,--running,--no-archived, and--subagentsretain their existing filtering semantics.--remote/-Arun search on the remote host, which also needs this version
ofah. Remote failures are errors, not silently incomplete results.- Supply either a positional pattern or
-q, not both. Empty queries and invalid
regexes are errors; no matches is success with empty output. --raw-searchremains available throughlog, notsearch.
Open an occurrence with context
ah show <session-id-or-path> --at <position-from-search> -C 2
ah search 'OAuth' -i
show --at displays the selected source record and, by default, two searchable
records on either side. -C 0 displays only the selected record. A record is a
message or tool event; it may contain multiple text/argument fragments. Context
is not counted in lines and is not restricted by the search kind filter. Tool
inputs and outputs are displayed even though ordinary show omits them. The
selected fragment is marked >; its exact occurrence is highlighted when color
is enabled. Zero-width occurrences select the fragment without coloring a
character. JSON output with --at has record, fragment, kind, text,selected, match_start, and match_end (offsets are null on context fragments).
Ordinary show and its existing JSON schema are unchanged.
search -i uses the existing selector setting (-s, $AH_SELECTOR, or fzf).
The fzf/sk preview opens the same position with context; Enter displays it and
Esc cancels. --no-preview disables the preview. Structured result formats
(--json, --tsv) cannot be combined with -i. Remotes execute both search and
position display on the host that owns the data; both hosts need this version.
Search output migration: kind and position are new JSON fields and are
appended as TSV columns 9 and 10; existing columns remain in positions 1–8. text_index
now counts nonempty fragments in the unfiltered stream, including with -p.
Consumers requiring the previous eight-column schema should select those
columns explicitly. -p now searches all user text parts, not just the legacy
transcript reader's first/combined prompt representation.
Compatibility: search used to be a hidden alias for log. For the old
session-list output and its field-selection options, use ah log explicitly.
Show a session transcript:
$ 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:
$ 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:
$ 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
shared my-webapp instruction AGENTS.md 2026-03-21 15:30
A project-level AGENTS.md is read by several agents, so it is listed as shared and matches any --agent filter.
Files listed per agent (global paths honor each agent's env var; project paths are looked up in the current directory and, inside a git repository, every directory up to its root; -a does this for every known project):
| Agent | Global | Project |
|---|---|---|
| Claude | ~/.claude/CLAUDE.md, rules/**/*.md, agent-memory/*/*.md, auto memory projects/*/memory/*.md |
CLAUDE.md, CLAUDE.local.md, .claude/CLAUDE.md, .claude/rules/**/*.md, .claude/agent-memory{,-local}/*/*.md |
| Codex | ~/.codex/AGENTS.md, AGENTS.override.md, memories/**/*.md |
AGENTS.override.md |
| Gemini | ~/.gemini/GEMINI.md (or context.fileName in settings.json) |
same file names |
| Copilot | ~/.copilot/copilot-instructions.md |
.github/copilot-instructions.md, .github/instructions/**/*.instructions.md |
| Cursor | ~/.cursor/rules/**/*.mdc |
.cursorrules, .cursor/rules/**/*.mdc |
| Antigravity (agy) | ~/.gemini/config/rules/*.md |
.agents/rules/*.md, .agent/rules/*.md |
| Grok | ~/.grok/AGENTS.md, rules/*.md, memory/MEMORY.md, memory topics memory-v2/{global,workspaces/*}/topics/*.md |
.grok/rules/*.md |
| opencode | ~/.config/opencode/AGENTS.md, instructions in opencode.json(c) |
instructions in opencode.json(c) |
| shared | — | AGENTS.md |
Types: instruction (always-loaded files), rule, memory (or the type in a memory file's frontmatter, such as feedback), and skill. Skills (SKILL.md under skills/*/ of Claude, Codex, and agy, and .agents/skills/*/) are listed only with -t skill.
Show session summary per agent:
$ 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 | ✓ | ✓ | ✓ | ✓ | ✓ | |
| Antigravity (agy) | ✓ | ✓ | ✓ | ✓ | ✓ | |
| Grok | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| opencode | ✓ | ✓ | ✓ | ✓ | ✓ |
Running detection reads each agent's own bookkeeping: Claude's sessions/<pid>.json (checking procStart so a reused PID is not reported), Grok's active_sessions.json, Copilot's session-state/<id>/inuse.<pid>.lock, and Codex's thread-writer-locks/<id>.lock. ¹ Codex is detected on Linux only, from the kernel lock table (/proc/locks); its PID is the lock holder, which for the interactive TUI is the Codex app-server. Running detection needs a PID liveness check, which is not implemented on Windows.
Features
- Cross-agent — one tool for 8 agents (see
ah list-agents) - Zero-config — scans the standard session locations for each supported CLI
- Fast — parallel file collection with rayon, regex search via memmap2, no subprocesses for search/parsing
- Resume-friendly —
ah resumeandah showcan 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 —
-iadds fuzzy selection with transcript preview (via fzf or compatible finder) - MCP server —
ah mcpexposes the same search and transcript access as tools for Claude Code, Codex, Gemini CLI, Cursor and other MCP clients
Installation
Homebrew
brew install nihen/tap/ah
Supported in the tap: macOS (Apple Silicon and Intel) and Linux (x86_64 and arm64).
Cargo
cargo install ah-cli
From binary
Download a prebuilt binary from GitHub Releases.
Available for macOS (arm64, x86_64) and Linux (x86_64, arm64). The Linux binaries are statically linked (musl).
From source
cargo install --git https://github.com/nihen/ah
Shell completion
# 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 or a compatible finder (e.g. sk) in PATH. Override with $AH_SELECTOR.
fzf compatibility:
- Selection and transcript preview work with older fzf too, including 0.44 from Debian/Ubuntu apt.
- Preview search (the query is highlighted in the preview and the preview scrolls to the first match;
ctrl-sswitches list filtering on and off) needs fzf 0.62 or newer. On older fzf it is turned off automatically. fzf 0.63+ calculates the scroll position in the background so typing stays responsive.
Useful as a shell function — pick a project, browse its sessions, resume:
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 <COMMAND> [OPTIONS]
Commands:
log List sessions
search Show matching passages
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
mcp Serve sessions to MCP clients over stdio
completion Generate shell completion script
man Generate man page
Global options:
-a, --all Show all sessions (disable default cwd filtering)
-A Show all sessions including all configured remotes
--agent <NAME> Filter by agent name (e.g. claude, codex, gemini)
--project <NAME> Filter by project name
-d, --dir <PATH> Filter by working directory (default: current directory)
-q, --query <REGEX> Search messages and tool input/output (regex, case-insensitive)
-p, --prompt-only Search only user prompts (use with -q)
--raw-search Search raw session files incl. metadata (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 <CMD> Override fuzzy selector (default: $AH_SELECTOR or fzf)
--no-preview Disable preview in interactive mode
--interactive-display <FIELDS> Override fuzzy selector display columns (log -i / show -i only)
--running Show only currently running sessions (Claude, Codex, Copilot, Grok)
--no-archived Hide sessions the agent has archived (Codex)
--subagents Include subagent sessions (spawned by another session)
--remote <NAME> Include sessions from remote host (requires ah on remote; see ~/.ahrc [remotes.*])
--since <SPEC> Show sessions newer than (e.g. "2026-03-20", "3d", "1w", "2m" = ~60 days)
--until <SPEC> 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 log -A # all sessions including all remotes
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 <COMMAND> --help` for subcommand-specific options.
Configuration:
~/.ahrc (TOML) — optional config file for agent customization and remote hosts.
See https://github.com/nihen/ah#configuration-ahrc for details.
ah log --help
List sessions
Usage:
ah log [OPTIONS]
Options:
-o, --fields <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 <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 <FIELD> 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
With -o: prints selected fields as TSV instead of path
--interactive-display <FIELDS> Override display columns in fuzzy finder
-s <CMD> 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 search --help
Show matching passages from conversations and tool input/output
Usage:
ah search [OPTIONS] <PATTERN>
ah search [OPTIONS] -q <REGEX>
Options:
--json One JSON object per occurrence (JSON Lines)
--tsv TSV without a header (default when piped)
--kind <KINDS> Comma-separated: user,assistant,tool-input,tool-output,unknown
-i, --interactive Select an occurrence, preview context, then show it
-v, --verbose Show full log paths and match positions on TTY
--max-matches N Maximum occurrences across sessions/hosts (default: 100, 0 = unlimited)
--snippet-length N Maximum Unicode characters per snippet (default: 240, minimum: 1)
One result per non-overlapping regex occurrence, not per session.
Sessions are ordered by modified_at descending; occurrences are in source order.
Default: session headings and compact passages with auto-pager on TTY;
plain TSV when piped. Paths and positions are hidden on TTY unless --verbose.
Verbose positions use "text #N" for search fragments, not transcript line numbers.
--verbose does not change JSON or TSV output.
TSV columns: path, agent, project, id, text_index, match_start, match_end, snippet, kind, position.
Text indices count nonempty source fragments before kind filtering (not transcript messages).
Use position with `ah show SESSION --at POSITION -C 2` to open the source.
Match offsets are 0-based UTF-8 byte offsets within the decoded search fragment.
Empty search fragments are skipped. No matches is successful with empty output.
Use PATTERN or -q, not both. Empty queries are rejected.
-p is shorthand for --kind user (all user text parts, excluding tool results).
-i uses fzf (or -s / $AH_SELECTOR); --no-preview disables the context preview.
-i cannot be combined with --json or --tsv. --raw-search is not supported;
use `ah log -q ... --raw-search` instead.
The former `search` alias for `log` is now this command; use `log` for session lists.
Examples:
ah search 'OAuth' # matching passages in the current directory
ah search 'OAuth' -a --json # occurrences across all directories
ah search -p '認証' # user prompts only
Global options:
-a, --all Show all sessions (disable default cwd filtering)
-A Show all sessions including all configured remotes
--agent <NAME> Filter by agent name (e.g. claude, codex, gemini)
--project <NAME> Filter by project name
-d, --dir <PATH> Filter by working directory (default: current directory)
-q, --query <REGEX> Search messages and tool input/output (regex, case-insensitive)
-p, --prompt-only Search only user prompts (use with -q)
--raw-search Search raw session files incl. metadata (use with -q)
-n, --limit N Max session files to scan (default: 0, no limit)
--since <SPEC> Show sessions newer than (e.g. "2026-03-20", "3d", "1w", "2m" = ~60 days)
--until <SPEC> Show sessions older than (e.g. "2026-03-20", "3d", "1w", "2m" = ~60 days)
--running Show only currently running sessions (Claude, Codex, Copilot, Grok)
--no-archived Hide sessions the agent has archived (Codex)
--subagents Include subagent sessions (spawned by another session)
--remote <NAME> Include sessions from remote host (requires ah on remote; see ~/.ahrc [remotes.*])
--color Force colored output (even through pipes)
--no-color Disable colored output
--no-pager Disable automatic pager
--debug Show debug info (glob expansion, scan counts, timing) on stderr
ah show --help
Show session transcript
Usage:
ah show [OPTIONS] [SESSION]
If SESSION is omitted, ah reads it from piped stdin (first line); if stdin is
a terminal or empty, ah shows the latest session matching -q and other filters.
Use - as SESSION to read it from stdin explicitly. An empty SESSION is an error.
Transcript output:
--head N Show first N messages only
--at <POSITION> Open a search position, including tool input/output
-C, --context N Surrounding source records with --at (default: 2, max: 1000)
--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)
--highlight <PATTERN> Highlight matching text in pretty output (case-insensitive; requires color)
With --at, context counts nonempty searchable source records (a message or tool
event), not lines. Positions remain stable across kind filters and appends;
changed source prefixes require a new search. JSON emits record, fragment, kind,
text, selected, match_start, and match_end. --at conflicts with --head, --follow,
--raw, metadata output, and --highlight. Ordinary show output is unchanged.
Metadata output:
-o, --fields <FIELDS> Output session metadata as TSV instead of transcript
--tsv Metadata mode without -o (default field: title)
Interactive mode:
-i, --interactive Select session via fuzzy finder then show it
--interactive-display <FIELDS> Override display columns in fuzzy finder
-s <CMD> Selector command (default: $AH_SELECTOR or fzf)
--no-preview Disable transcript preview
ctrl-s (fzf only) Toggle preview search: highlight + scroll to match / reset
Examples:
ah show # show latest session transcript
ah show -o title # output title of latest session
ah show -o agent,title # output agent and title as TSV
ah show -i -o title # select session, output title
Global options:
-a, --all Show all sessions (disable default cwd filtering)
-A Show all sessions including all configured remotes
--agent <NAME> Filter by agent name (e.g. claude, codex, gemini)
--project <NAME> Filter by project name
-d, --dir <PATH> Filter by working directory (default: current directory)
-q, --query <REGEX> Search messages and tool input/output (regex, case-insensitive)
-p, --prompt-only Search only user prompts (use with -q)
--raw-search Search raw session files incl. metadata (use with -q)
-n, --limit N Max session files to scan (default: 0, no limit)
--since <SPEC> Show sessions newer than (e.g. "2026-03-20", "3d", "1w", "2m" = ~60 days)
--until <SPEC> Show sessions older than (e.g. "2026-03-20", "3d", "1w", "2m" = ~60 days)
--running Show only currently running sessions (Claude, Codex, Copilot, Grok)
--no-archived Hide sessions the agent has archived (Codex)
--subagents Include subagent sessions (spawned by another session)
--remote <NAME> Include sessions from remote host (requires ah on remote; see ~/.ahrc [remotes.*])
--color Force colored output (even through pipes)
--no-color Disable colored output
--no-pager Disable automatic pager
--debug Show debug info (glob expansion, scan counts, timing) on stderr
ah resume --help
Resume an agent session
Usage:
ah resume [OPTIONS] [SESSION] [-- EXTRA_ARGS...]
If SESSION is omitted, ah reads it from piped stdin (first line); if stdin is
a terminal or empty, ah resumes the latest session matching -q and other filters.
Use - as SESSION to read it from stdin explicitly. An empty SESSION is an error.
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 <FIELDS> Display fields in interactive mode (default: agent,project,modified_at,title)
-s <CMD> 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 <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 <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 <FIELD> 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 <CMD> 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 <FIELDS> Select output fields (replaces defaults, see --list-fields)
Default: agent, project, type, name, modified_at, description
-O, --extra-fields <FIELDS> Add fields to defaults (comma-separated)
-t, --type <TYPE> Filter by memory type (instruction/rule/memory/skill, or a memory's own type such as feedback)
--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 <FIELD> 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
A project-level AGENTS.md is listed as agent `shared` and matches any --agent filter.
Skills (SKILL.md) are listed only with -t skill.
Interactive mode:
-i, --interactive Browse memory files via fuzzy finder
-s <CMD> 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).
ah mcp --help
Serve sessions to MCP clients over stdio
Usage:
ah mcp [GLOBAL OPTIONS]
Runs a Model Context Protocol server that reads JSON-RPC from stdin and
writes to stdout. Register it in an MCP client, e.g.:
claude mcp add ah -- ah mcp
[mcp_servers.ah] command = "ah" args = ["mcp"] (~/.codex/config.toml)
Tools: log, search, show, project, memory, agent, list_agents. Their
arguments mirror the CLI flags (query, dir, all, agent, since, ...).
Global filters (-a, -d, --agent, --project, --since, --until, --running,
--no-archived, --subagents, -n) become the tools' default scope; a tool
argument overrides them per call (dir clears all and vice versa).
-q, -p, --raw-search, -i, --color, --remote and -A are rejected.
Tool calls run one at a time and can be cancelled with
notifications/cancelled. Sessions default to the server's working
directory; every result includes the applied scope. Remote hosts are not
supported: run ah mcp where the sessions live.
Examples:
ah mcp # scope: the client's working directory
ah mcp -a # scope: every project
ah mcp --agent claude # only Claude sessions by default
MCP server
ah mcp runs a Model Context Protocol server over stdio, so a coding agent can search its own (and other agents') history as structured data instead of parsing CLI output. Register it once:
| Client | Setup |
|---|---|
| Claude Code | claude mcp add ah -- ah mcp (or add it to .mcp.json) |
| Codex | ~/.codex/config.toml: [mcp_servers.ah] command = "ah" args = ["mcp"] |
| Gemini CLI | settings.json: "mcpServers": {"ah": {"command": "ah", "args": ["mcp"]}} |
| Cursor | .cursor/mcp.json: {"mcpServers": {"ah": {"command": "ah", "args": ["mcp"]}}} |
The server speaks both the initialize handshake of protocol revisions 2025-06-18 and 2025-11-25 and the per-request metadata style of 2026-07-28 (server/discover).
Tools
| Tool | What it returns | Arguments (besides the common filters) |
|---|---|---|
log |
Sessions newest first: {scope, sessions, total, truncated} |
query, prompt_only, raw_search, fields, sort, order, max_results (default 50), transcript_limit, title_limit |
search |
Occurrences with snippets and positions: {scope, hits, truncated} |
pattern (required), kind, prompt_only, max_matches (default 100), snippet_length |
show |
One transcript as Markdown (format: md, the default) or {role, text} messages (json), or with at the records around a search hit |
session (required), format, head, at, context (default 2), max_chars (default 100000) |
project |
Known projects: {scope, projects} |
fields, sort, order |
memory |
Memory and instruction files: {scope, memory, truncated}; add body to fields for contents |
fields, type, query, sort, order, max_chars |
agent |
Session counts per agent: {scope, agents} |
— |
list_agents |
Supported agents and capabilities: {agents} |
— |
Common filters, where the tool applies them: all, dir, agent, project, since, until, running, no_archived, subagents, limit (limit bounds the files scanned, like -n; max_results bounds the result). all and dir are exclusive: dir narrows to one working directory, all: true covers every project. The project argument narrows within that directory scope, like --project on the CLI; combine it with all: true to look across every directory. The project tool covers every directory unless dir applies (all: true only clears a dir inherited from the startup flags); memory takes all, dir, agent, project, since and until. Arguments a tool does not apply are rejected rather than ignored.
Results come back as structuredContent (the JSON described above) and as a text block holding the same data as JSON Lines: the first line carries scope, total, truncated and the like, then one compact object per session, hit, project, file, agent, message or record. show with format: md (and without at) returns the Markdown itself as text. When a result is truncated, a second text block carries a short note; the first block stays JSON Lines. log, search, project, memory and agent include scope: {dir, all}, the directory scope that was actually applied, so an empty result can be told from a wrong scope. Input errors (an invalid regex, an unknown session, an argument the tool does not take) are returned as tool errors (isError: true) with the message; an unknown tool name is a JSON-RPC error. Empty results are successes with empty arrays.
Scope and defaults
Sessions default to the server's working directory, which the client decides (Claude Code starts stdio servers in the project directory). The global filters given to ah mcp become the defaults of every tool: ah mcp -a makes every tool cover all projects unless a call passes dir, and ah mcp --agent claude restricts the defaults to Claude sessions. A tool argument always wins over the startup default, including all: false and running: false. -q, -p, --raw-search, -i, --color, --remote and -A are rejected at startup; remote hosts are not supported, so run ah mcp on the host that holds the sessions.
Limits
- Tool calls run one at a time; a long search delays the next call. A waiting or running call can be cancelled with
notifications/cancelledand gets no response. resumeis not offered. Theresume_cmdfield ofloggives the shell command.logtruncates tomax_resultsandshow/memorytomax_charsand reporttruncated: true. Markdown is cut on a character boundary;jsonmessages andmemorybodies are dropped from the end; withat, context records farthest from the hit go first and the hit itself is cut to a window around the match.- Stdout carries only protocol messages;
--debuglogs to stderr.
Configuration (~/.ahrc)
ah works out of the box with no configuration. Optionally, create ~/.ahrc (TOML) to customize agent settings and remote hosts.
File format
~/.ahrc has two top-level sections: [agents.*] for agent configuration and [remotes.*] for SSH remote hosts.
# ~/.ahrc — ah configuration file (TOML)
# --- Agent configuration ---
# Disable a built-in agent
[agents.codex]
disabled = true
# Add extra session file locations to a built-in agent
[agents.claude]
extra_patterns = ["~/claude-archive/projects/*/*.jsonl"]
# Define a custom agent using an existing plugin's parser
[agents.mybot]
plugin = "claude"
file_patterns = ["~/.mybot/sessions/*.jsonl"]
# --- Remote hosts for SSH session aggregation ---
[remotes.mydev]
host = "mydev" # SSH host name (as in ~/.ssh/config)
ah_path = "/usr/local/bin/ah" # path to ah binary on remote (optional, default: "ah")
Agent fields
| Field | Required | Description |
|---|---|---|
disabled |
No | Set to true to hide this agent from all commands |
extra_patterns |
No | Additional glob patterns to scan (built-in agents only) |
plugin |
Yes* | Parser to use: claude, codex, gemini, copilot, cursor, agy, grok, opencode (*required for custom agents) |
file_patterns |
Yes* | Glob patterns for session files (*required for custom agents) |
All glob patterns must start with ~/ or / (absolute paths only). ~ is expanded to the home directory.
Disable an agent
[agents.codex]
disabled = true
Add extra file patterns to a built-in agent
[agents.claude]
extra_patterns = ["~/claude-archive/projects/*/*.jsonl"]
Sessions found through extra_patterns are attributed to the agent by the pattern's literal part (before the first glob character), so keep each agent's extra files in a dedicated directory or under a distinct name prefix. If the literal part cannot be told apart from your home directory or another agent's default directory (e.g. ~/*.jsonl, ~/.c*.db, ~/backup-*/x.db), ah warns and uses only the matches that fall inside the agent's own locations (e.g. ~/*/.claude/projects/*/*.jsonl still maps to Claude via its default .claude directory; with CLAUDE_CONFIG_DIR set, only paths under that directory do); other matches are skipped.
Add a custom agent (using an existing plugin's parser)
[agents.mybot]
plugin = "claude"
file_patterns = ["~/.mybot/sessions/*.jsonl"]
The plugin field tells ah how to parse the session files. Available plugins: claude, codex, gemini, copilot, cursor, agy, grok, opencode.
Remote hosts
Aggregate sessions from remote machines over SSH. The remote host must have ah installed.
[remotes.mydev]
host = "mydev" # SSH host (must be reachable via `ssh <host>`)
ah_path = "/usr/local/bin/ah" # optional, default: "ah"
[remotes.prod-bastion]
host = "bastion.example.com"
| Field | Required | Description |
|---|---|---|
host |
Yes | SSH host name (as configured in ~/.ssh/config or a hostname) |
ah_path |
No | Absolute path to ah on the remote host or a bare command name (default: "ah"). ~/bin/ah and other ~/... paths are not supported |
Use --remote <name> to include a specific remote, or -A to include all configured remotes:
ah log --remote mydev # include sessions from mydev
ah log -A # include all configured remotes
ah log -A -q "deploy" # search across local + all remotes
Environment variables
Each built-in agent respects the environment variable its CLI uses to relocate session storage:
| Agent | Session Files | Env Var | Default |
|---|---|---|---|
| Claude | projects/*/*.jsonl |
CLAUDE_CONFIG_DIR |
~/.claude |
| Codex | sessions/**/*.jsonl |
CODEX_HOME |
~/.codex |
| Gemini | tmp/*/chats/session-*.jsonl (.json before v0.39) |
GEMINI_CLI_HOME |
~/.gemini |
| Copilot | session-state/*/workspace.yaml |
COPILOT_HOME |
~/.copilot |
| Cursor | projects/*/agent-transcripts/**/*.jsonl |
CURSOR_DATA_DIR |
~/.cursor |
| Antigravity (agy) | antigravity-cli/brain/*/.system_generated/logs/transcript.jsonl |
— | ~/.gemini |
| Grok | sessions/*/*/chat_history.jsonl |
GROK_HOME |
~/.grok |
| opencode | opencode/opencode*.db (SQLite) |
XDG_DATA_HOME |
~/.local/share |
opencode stores all sessions in one SQLite database. ah reads it read-only and lists each session under the virtual path <db>/<session-id>, which works with ah show, ah resume, and -o path like a regular session file. ah show --raw prints one JSON line per message with its parts.
Codex sessions archived with codex archive stay listed and resumable (codex resume still finds them). They carry archived=true (-o archived); hide them with --no-archived.
Subagent sessions (started by another session, e.g. Claude's Task tool) are hidden from log, project, and agent unless --subagents is given; -o parent_id shows the session that spawned them. A subagent's id or path still works with ah show directly. Claude, Cursor, and Gemini subagent transcripts cannot be resumed on their own, so they have no resume command.
| Agent | Subagent sessions | parent_id |
|---|---|---|
| Claude | projects/*/<parent>/subagents/agent-<id>.jsonl (id is the agent id) |
✓ |
| Codex | sessions whose session_meta source is a subagent |
✓ (spawned threads) |
| Gemini | tmp/*/chats/<parent>/<id>.json(l) |
✓ |
| Cursor | projects/*/agent-transcripts/<parent>/subagents/*.jsonl |
✓ |
| Grok | summary.json with session_kind: subagent |
not recorded |
| opencode | child sessions (parent_id column) |
✓ |
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) |
Examples
SQL with trdsql
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
ah log -a --json | jq '.project'
ah log -a --json -n 1 | jq '.'
ah project --json | jq '.project' # list project names
Piping
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).
Or register ah mcp as an MCP server (see MCP server) so the agent gets the same data as tools.
License
Yorumlar (0)
Yorum birakmak icin giris yap.
Yorum birakSonuc bulunamadi