Skip to content

jarvan1/aiss

Repository files navigation

aiss — AI session search

A small, cross-platform, dependency-free binary that fuzzy-searches the session histories of multiple AI CLIs — Claude Code / Codex / Copilot CLI / Gemini CLI — and resumes the one you pick, right in its original working directory.

It's a single Go binary: no fzf, no jq, no Oh My Zsh required. (Those are what the zsh-plugin version depends on; this reimplements the scanner and the picker natively.)

╭─ claude · claude-opus-4-8 ───────────────────────╮
│ 📁 ~/plugins                                     │
│ 🕐 2026-06-22 09:39 → 06-25 01:16  (2d15h)       │
│ 💬 248 user · 507 assistant   Claude Code 2.1.170│
╰──────────────────────────────────────────────────╯

▶ USER
I want to build a zsh plugin that searches AI CLI session history…

Install

One-line install (Linux / macOS) — downloads the right binary for your OS/arch, verifies its checksum, drops it in ~/.local/bin, and adds that to your shell profile (.zshrc / .bashrc / config.fish / .profile, picked from $SHELL) if it isn't already on PATH:

curl -fsSL https://raw.githubusercontent.com/jarvan1/aiss/main/install.sh | sh

Windows (PowerShell) — installs to %LOCALAPPDATA%\Programs\aiss and adds it to your user PATH:

irm https://raw.githubusercontent.com/jarvan1/aiss/main/install.ps1 | iex

Both honor AISS_VERSION (e.g. v0.2.0) and AISS_INSTALL_DIR to pin the version or install location, and AISS_NO_MODIFY_PATH=1 to skip the PATH edit (they'll just print the line to add yourself).

Homebrew (macOS / Linux):

brew install jarvan1/tap/aiss

Pre-built binary (no toolchain needed) — grab the archive for your OS/arch from the latest release, unpack it, and put aiss on your PATH. Each release is built automatically by GitHub Actions for macOS / Linux / Windows (amd64 + arm64).

With Go:

go install github.com/jarvan1/aiss/cmd/aiss@latest   # needs Go 1.21+

Enable the hotkey (optional) — add one line to your shell rc:

eval "$(aiss init zsh)"     # or: aiss init bash | aiss init fish

On Windows (PowerShell), add this to your $PROFILE instead:

Invoke-Expression (& aiss init powershell | Out-String)

This binds Ctrl-X Ctrl-W. Without it, just run aiss.

Usage

aiss                 # open the picker; Enter resumes the selected session
aiss codex           # open with an initial filter term
aiss --print         # print the resume command instead of running it
aiss scan            # list sessions: provider, id, cwd, preview, file (for scripts)
aiss preview <p> <f> # render one session's preview (debugging)

In the picker, type to fuzzy-filter (the provider name is part of each row, so typing claude narrows to Claude), use the arrow keys to move, watch the live preview pane on the right, and press Enter to resume.

Delete a session — press Ctrl-D on the highlighted row, then y to confirm (any other key cancels). Deletion is provider-aware: for Codex it calls codex delete (which also prunes Codex's own index) and removes the rollout file; for Claude it removes the transcript plus its session-env/ and file-history/ sidecars; for Copilot and Gemini it removes the session directory. It only ever touches paths under ~ that are several levels deep, so it can't wander into ~/.claude itself.

Key binding

A binary can't, by itself, put a command on your shell's command line (this is exactly why fzf also ships shell snippets). aiss carries the integration for each shell embedded inside it — source it from your rc with one line:

eval "$(aiss init zsh)"     # zsh   → ~/.zshrc
eval "$(aiss init bash)"    # bash  → ~/.bashrc
eval "$(aiss init fish)"    # fish  → ~/.config/fish/config.fish
Invoke-Expression (& aiss init powershell | Out-String)   # PowerShell → $PROFILE

All four bind Ctrl-X Ctrl-W. zsh, fish, and PowerShell run the selected session immediately; bash places the resume command on the line for you to press Enter (readline's bind -x can't reliably auto-accept — the same reason fzf's Ctrl-R behaves this way). Override the key with AISS_KEYBIND (zsh), AISS_KEYBIND_BASH, AISS_KEYBIND_FISH, or AISS_KEYBIND_PWSH.

(Working from a source checkout instead? The same snippets live in internal/shellinit/ and can be sourced directly.)

Without any of these, just run aiss — it resumes the session directly.

How it works

For each provider, aiss reads the session files straight off disk (no external tools) and dispatches resume to the matching CLI:

Provider Scanned path Resume
Claude ~/.claude/projects/<dir>/<uuid>.jsonl claude --resume <uuid>
Codex ~/.codex/sessions/**/rollout-*.jsonl codex resume <uuid> [-m model]
Copilot ~/.copilot/session-state/<uuid>/events.jsonl copilot --resume=<uuid>
Gemini ~/.gemini/tmp/<hash>/logs.json (experimental) opens in the dir (no resume-by-id)

Resume always runs in the session's original directory (recreated if it was deleted, so resume-by-cwd lookups still match). The matching CLI only needs to be on PATH to resume; browsing and previewing work without any of them.

Sessions whose original directory no longer exists are hidden — set AISS_SHOW_MISSING=1 to keep them.

Configuration

Variable Default
AISS_CLAUDE_DIR ~/.claude/projects
AISS_CODEX_DIR ~/.codex/sessions
AISS_COPILOT_DIR ~/.copilot/session-state
AISS_GEMINI_DIR ~/.gemini/tmp
AISS_SHOW_MISSING unset (set to 1 to keep deleted-dir sessions)
AISS_KEYBIND ^X^W (only used by the optional zsh integration)

Cross-platform builds

GOOS=linux   GOARCH=amd64 go build -o dist/aiss-linux-amd64 ./cmd/aiss
GOOS=darwin  GOARCH=arm64 go build -o dist/aiss-darwin-arm64 ./cmd/aiss
GOOS=windows GOARCH=amd64 go build -o dist/aiss-windows-amd64.exe ./cmd/aiss

The picker (via tcell) works on Windows terminals too.

Development

go test ./...   # unit tests (resume command building, quoting)
go vet ./...

About

Cross-platform fuzzy picker over AI CLI session histories (Claude Code / Codex / Copilot / Gemini)

Resources

License

Stars

1 star

Watchers

0 watching

Forks

Packages

 
 
 

Contributors