ah-cli 0.1.0

Agent History Search - cross-agent session full-text search CLI
# ah - Agent History

Cross-agent session search CLI written in Rust.

## Build & Install

```bash
make install                    # local build + install
```

After changing code, always run `make install` to update the binary.

## Architecture

```
src/
  main.rs        -- entry point: clap subcommand dispatch + agent/list-* commands
  cli.rs         -- clap derive CLI definition (Cli, Commands, FilterArgs, ProjectField) + help text
  config.rs      -- ~/.ahrc (TOML) parsing, agent registry (OnceLock<Vec<AgentDef>>)
  agents/        -- built-in agent plugins + registry + shared helpers
  session.rs     -- Session struct
  collector.rs   -- glob expansion + rayon parallel stat + BinaryHeap top-N
  projects.rs    -- project aggregation (shared by `ah project` and `ah fuzzy project`)
  resolver.rs    -- plugin-driven metadata extraction and transcript shaping
  search.rs      -- mmap+regex full-text / plugin prompt-only search
  memory.rs      -- `ah memory` subcommand: memory + instruction file listing
  output.rs      -- TSV/LTSV/JSON output for log, project, and memory listing
  color.rs       -- color mode detection (--color/--no-color/TTY auto)
  show.rs        -- `ah show` subcommand: pretty-print transcript
  resume.rs      -- `ah resume` subcommand: exec agent resume command
  fuzzy.rs       -- `ah fuzzy log` / `ah fuzzy project` / `ah fuzzy memory` interactive browse
  subcmd.rs      -- shared session resolver (stdin pipe, session ID/path, query, filters)
```

## Key Design Decisions

- No external tools for search/parsing (all indexing and query logic in-process; no rg/jq/sed)
- Parallel stat + metadata resolution via rayon
- memmap2 for searching large JSONL files without copying
- Regex compiled once via LazyLock (no recompilation in hot paths)
- Single-pass filter_map for search filtering + metadata resolution
- Default cwd filtering: all subcommands filter by current directory, `-a` for global
  - Exception: `project` defaults to all (no cwd filter)
- Global options via Cli struct flatten, not per-subcommand
- log, `ah project`, and `ah memory` share the same output system (TSV/LTSV/JSON, -f field selection)
  but use separate Field enums (Field for log, ProjectField for projects, MemoryField for memory)
  Field selection via `-o/--fields` and `-O/--extra-fields`

## Configuration

- `~/.ahrc` (TOML) — optional, merge with built-in defaults
- No config = all 5 built-in agents active
- `config.rs` separates "plugins" (parse logic, static) from "agents" (config, runtime)
- `OnceLock<Vec<AgentDef>>` global registry, initialized once at startup
- Environment variables (CLAUDE_CONFIG_DIR etc.) override base directories

## Adding a New Agent

### Via ~/.ahrc (no code change)

```toml
[agents.myagent]
plugin = "claude"   # reuse existing parser (must match file format)
file_patterns = ["~/.myagent/sessions/*.jsonl"]
```

### Via code (new plugin)

1. Add a plugin under `src/agents/`
2. Register it in `src/agents/mod.rs` (PLUGINS array)
3. Implement `AgentPlugin` trait: `id`, `description`, `glob_patterns`, `path_markers`, `iter_messages`
4. Optionally implement: `resolve_cwd`, `resolve_project`, `resolve_title`, `resume_args`, `features`, `project_desc`

## Testing

```bash
cargo test
time ah -a log -n 100 > /dev/null
time ah -a -q "query" log -n 100 > /dev/null
```

## Release

```bash
make release      # git tag vX.Y.Z && push → GitHub Actions builds binaries
```