https://github.com/yotsuda/ccpick
Tiny fzf-based session picker for Claude Code: fuzzy-filter recent sessions and claude --resume the one you pick
https://github.com/yotsuda/ccpick
claude-code cli dotnet-tool fzf session-manager
Last synced: 3 days ago
JSON representation
Tiny fzf-based session picker for Claude Code: fuzzy-filter recent sessions and claude --resume the one you pick
- Host: GitHub
- URL: https://github.com/yotsuda/ccpick
- Owner: yotsuda
- License: mit
- Created: 2026-06-15T07:01:18.000Z (5 days ago)
- Default Branch: master
- Last Pushed: 2026-06-15T11:37:11.000Z (5 days ago)
- Last Synced: 2026-06-15T13:17:05.760Z (5 days ago)
- Topics: claude-code, cli, dotnet-tool, fzf, session-manager
- Language: C#
- Size: 59.6 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# ccpick
A tiny, fast **session picker for [Claude Code](https://github.com/anthropics/claude-code)** built around [`fzf`](https://github.com/junegunn/fzf). Launch it, fuzzy-filter your recent sessions by their summaries, hit Enter — it runs `claude --resume ` for you. (The project is `ccpick`; it installs the **`ccp`** command.)
```
ccp
```
No more copying `claude --resume ` out of a notes file, and no more scrolling the built-in picker: just type a few letters of what the session was about.
## Why
When Claude Code exits it prints something like:
```
claude --resume 863e7427-5223-455a-8b91-05fccb405d1f
```
Those GUIDs are already on disk as `~/.claude/projects//.jsonl` transcripts — there is nothing to "save". `ccpick` indexes those transcripts, derives a human-readable title from each (the first user prompt, or a session summary if present), and hands the list to `fzf` for instant fuzzy filtering.
## How it works
```
ccp list → fzf (real-time fuzzy filter + preview) → claude --resume
```
- **Reads** `~/.claude/projects//.jsonl` (top-level files only; `subagents/` internal logs are skipped).
- **Titles** come from the first real user prompt or a `summary` line — heuristic, fully local, nothing is sent anywhere.
- **Caches** results in `~/.claude/ccp-cache.json` keyed by file mtime, so only changed sessions are re-scanned. Cold scan of ~100 sessions ≈ 2 s; warm launches ≈ 0.2 s.
- **Preview** of the focused session is shown live by re-invoking `ccp show ` (a ~0.2 s spawn — cheap because the tool starts fast).
It is *not* an `fzf` plugin — `fzf` has no plugin system. `ccpick` is a small wrapper that uses `fzf` as the interactive filter, like `forgit` or `fzf-git.sh`.
## Requirements
- **.NET 8+ runtime** (the tool is a [.NET global tool](https://learn.microsoft.com/dotnet/core/tools/global-tools))
- **fzf** — `winget install fzf` / `brew install fzf` / `apt install fzf`
- **claude** on `PATH`
## Install
```sh
winget install fzf # or: brew install fzf / apt install fzf
dotnet tool install --global ccpick
```
The same one `dotnet tool` package runs on **Windows, macOS, and Linux**, and the **`ccp`** command lands on your `PATH` automatically.
> Not yet published to NuGet. Until then, install from a local build:
> ```sh
> git clone https://github.com/yotsuda/ccpick && cd ccpick
> dotnet pack -c Release
> dotnet tool install --global --add-source ./bin/Release ccpick
> ```
## Usage
| Command | What it does |
|---|---|
| `ccp` | Open the fzf picker; type to filter, **Ctrl-E** to rename, Enter to resume |
| `ccp list` | Print one row per session: `date [folder] title` |
| `ccp show []` | Print a session's id / cwd / name (the most recent session if no id) |
| `ccp name ` | Name the most recent session — the one you just exited |
| `ccp name ` | Name a specific session by id (omit `` to type it interactively) |
| `ccp name --clear` | Reset to the auto-generated title |
| `ccp -h`, `--help`, `help` | Show usage |
## Custom titles
Auto-titles are handy but generic. Press **Ctrl-E** on any row in the picker to give that session a memorable name, or use `ccp name`. Overrides are stored in `~/.claude/ccp-titles.json`, **separate from the mtime cache**, so a name you set sticks even as the session keeps growing.
**Name a session right after exiting it.** When Claude Code prints `claude --resume ` on exit, you don't even need the GUID — just run:
```sh
ccp name "what this session was about"
```
`name` labels the most recently active session, so you can tag it on the spot.
## Notes
- **UTF-8 everywhere.** The pipe to/from `fzf` is forced to UTF-8 so non-ASCII titles (Japanese, etc.) survive the round trip.
- The folder column appears only when your sessions span more than one working directory; the home dir shows as `~`.
- Auto-titles are heuristic; slash-command sessions (e.g. `/clear`) read a little oddly — rename them.
- A **legacy PowerShell version** (no .NET build needed, but pulls in `pwsh` and has no live preview) lives in [`pwsh/`](pwsh/).
## Related tools
Several Claude Code session browsers exist. `ccpick`'s niche is **fzf-powered fuzzy search + tiny footprint + one cross-platform `dotnet tool`**:
- [sasazame/ccresume](https://github.com/sasazame/ccresume) — Node/Ink custom TUI, keyboard navigation (no fuzzy search), cross-platform.
- [josephyaduvanshi/claude-history-manager](https://github.com/JosephYaduvanshi/claude-history-manager) — native macOS app with pin/tag/search.
- [davidpp/claude-session-browser](https://github.com/davidpp/claude-session-browser) — TUI that copies the resume command to the clipboard.
## Disclaimer
Unofficial, community-built. Not affiliated with, endorsed by, or supported by Anthropic. Use at your own risk.
## License
MIT