A terminal session browser for Claude Code — browse, search, group, and resume past sessions, with a built-in split-live pane (on by default).
Project description
saikai
English | 日本語
Dozens of Claude Code sessions, one searchable table. saikai scans your entire
~/.claude/projects history, lets you filter and group by date / project /
topic, and resumes any session with Enter. By default (split-live) it keeps
several sessions running live in tabs beside the list — jump between conversations
without closing anything or losing scrollback.
saikai = 再開 "resume" + 再会 "reunion" (Japanese). Complements ccmanager, which manages a live multi-agent roster; saikai is for navigating and resuming the history.
The demo uses fictional, leak-checked data. Regenerate the animated GIF
headlessly with uv run scripts/make_demo_gif.py; use
uv run scripts/record_demo.py --guide for a native-terminal recording.
Highlights
- Every session, one table — every Claude Code conversation on your machine, sorted by real last activity, grouped by date / project / topic, filtered as you type.
- Resume in place —
Enterreopens a session withclaude --resumein the working directory it was started from (worktree-aware). - Split-live panes — host several live
claudesessions in tabs beside the list; markers show at a glance who is busy~, waiting for your input?, or finished!. Quit andShift+F4restores the whole pane set later. - Session hygiene — favorite
★, hide, rename; AI one-line titles; an inferred parent/child tree and LLM topic clusters for big histories. - RAM-aware — a memory gate (commit headroom + load + physical floor) warns before a new pane would push the machine into thrashing.
- Keyboard-first — everything works without a mouse:
Spaceopens a mnemonic command menu (Space f= favorite,Space s= sort …),Alt+←/→resizes the split,?shows the live key map. The mouse is a bonus (click to sort, drag the divider), never a requirement. - Unintrusive by design — read-only over claude's own transcript files; no daemon, no database. Two Python files on top of Textual, MIT-licensed.
The live pane uses ConPTY on Windows and a POSIX PTY elsewhere — see Platform support for the per-OS verification status (Windows is the verified platform today).
Install
Requires Python ≥ 3.11. The easiest path is uv — it installs the PyPI package in an isolated environment, no manual venv:
uv tool install saikai # stable release → `saikai` on PATH
From a clone:
uv run saikai.py # run in place (deps auto-installed)
uv tool install . # install the `saikai` command on your PATH, then: saikai
Prefer pip / pipx? Both work (deps come from pyproject.toml):
pipx install saikai # isolated + on PATH
pip install saikai # into the active environment
The split-live pane needs the PTY deps (pyte, and pywinpty on Windows /
ptyprocess elsewhere); they install automatically with any command above. If
they're somehow missing, saikai still runs in list-only mode (see below).
Usage
saikai # every project, full history (the default)
saikai --here # only the current project (git repo)
saikai --days 7 # only the last 7 days (one-shot; --save-defaults persists)
saikai --table # static, non-interactive table
saikai --help
Keys — learn three things
Everything else is on screen (the footer, the dropdowns, and the ␣ menu
that pops up when you pause).
-
Keys you already know.
↑↓move ·Enterresumes ·/or just typing searches ·Tabtoggles the preview ·?full key list ·Escleaves the current context (search → list → quit). -
Spaceis the menu. PressSpacein the list, then one mnemonic letter. Hesitate afterSpaceand the whole menu appears in place, grouped by family (which-key style) — nothing to memorise:Session View Panes f★ favoritescycle sort columnnnew sessionhhideoflip sort orderprestore paneserename (edit)gcycle groupingzfreeze paneycopy prompt (yank)ttree ·cclusteranext attentionddiff (changes)lhide/show listxclose tab ·[]tabsrrefresh,settings ·/hide/show barSpacemark for batch launchSpace is a deliberate menu key, not a claim that every TUI should use a Space leader: it only arms while the session list owns focus, so search fields and live agent panes keep a literal Space. It also avoids taking a letter away from type-to-search. The trade-off is that list marking becomes
Space Space; set[keys] leader = "none"if conventional Space-to-mark is more important to you. -
Ctrl+]returns focus from a live claude pane to the list (the pane owns every other key, so claude works normally inside it).
Search tokens (combine with text and each other): :fav :hidden :open
:active :recent. The filter bar — search box plus the Group / Sort /
Status / Age dropdowns — is visible by default: Tab/Shift+Tab walk into
the dropdowns, Enter opens one, ␣/ reclaims the rows (persists).
More keyboard parity: Alt+←/→ nudges the list/pane divider (persists, like
dragging it). Every menu action also has a legacy F-key alias — ? lists
them all, including your [keys] remaps.
Don't like the defaults? In config.toml: [keys] leader = "none" turns the
mode off (Space then marks directly, as before), leader = "ctrl+g" moves it,
leader_defaults = false empties the map, and any action = "x" single-letter
entry remaps one sequence. Mouse extras (never required): click a column
header to sort, drag the divider, click rows and dropdowns.
Split-live (default)
saikai runs real interactive claude processes in tabs beside the list whenever
its PTY deps (pyte, pywinpty/ptyprocess) are present — they ship as
dependencies, so this is the default. To opt out and use the lightweight
list-only browser (Enter = full-screen takeover resume), set the env var:
SAIKAI_SPLIT_LIVE=0 saikai # also: false / no / off
| Key | Action |
|---|---|
Enter |
open / focus a live pane for the selected session |
Shift+F8 |
start a NEW claude session in any folder / git worktree |
Shift+F4 |
reopen the panes from your last session (snapshot + resume) — anytime |
F2 / F3 |
previous / next live tab |
Shift+F3 |
jump to the next pane needing attention (? waiting / ! finished) |
F4 |
hide / show the session list (full-width pane) |
Ctrl+] |
return focus from a pane back to the list (SAIKAI_RELEASE_KEY to change) |
F10 / Shift+F10 |
close the active tab / close all tabs (explicit close — not restored) |
Esc / Ctrl+C |
quit: snapshot the open panes, then kill them all (Shift+F4 reopens them next launch) |
| scroll up | freeze the pane (copy mode): select/copy while claude keeps running |
Markers in the list: ~ busy · ? waiting for input · ! finished (unanswered)
· @ open · + active · . recent · * favorite · x hidden.
Configuration (environment variables)
| Variable | Default | Meaning |
|---|---|---|
SAIKAI_SPLIT_LIVE |
on | live-pane mode; set 0/false/no/off to disable → list-only browser + full-takeover resume |
SAIKAI_AUTO_REFRESH |
off | seconds between background re-scans |
SAIKAI_SUMMARIZE_CMD |
— | command to summarize with (prompt on stdin → summary on stdout) instead of claude -p |
SAIKAI_AUTO_PERMISSION |
off | opt in to adding --permission-mode auto for frequently used workspaces |
SAIKAI_MAX_MEM_LOAD |
85 | refuse/warn opening a pane above this memory-load % (Win dwMemoryLoad; Linux/macOS derived) |
SAIKAI_MIN_COMMIT_MB |
2048 | keep this much commit headroom free — the system-freeze guard (Win/Linux) |
SAIKAI_MIN_FREE_PHYS_PCT |
8 | keep ≥ this % of physical RAM available (anti-thrash floor, machine-relative) |
SAIKAI_CLAUDE_MB |
600 | estimated RAM per live pane |
SAIKAI_MIN_FREE_MB |
0 | optional absolute physical floor (legacy; max'd with the % floor) |
SAIKAI_HARD_RAM_GATE |
off | 1 refuses (vs warns) when the gate would be crossed |
SAIKAI_MAX_LIVE |
64 | hard cap on concurrent live panes (backstop) |
SAIKAI_SCROLLBACK |
2000 | per-pane scrollback lines kept in memory. Biggest lever on the live process's RAM (a full pane ≈ cols×lines pyte cells); lower it (e.g. 1000) on a memory-tight machine, raise for deeper history |
SAIKAI_COLOR_BY |
project | what tints the session title: project / worktree / topic / none |
SAIKAI_SPLIT_RATIO |
0.34 | initial list/pane split (drag the divider to change; the dragged value persists) |
SAIKAI_RELEASE_KEY |
ctrl+] |
key that returns focus from a live pane to the list |
saikai also reads an optional TOML config file for these same knobs (with
env > config > default precedence) plus [keys] rebinds. Run saikai --init-config to write a documented template, saikai --print-config to see the
resolved location and values — or press Space , inside the app: the
Settings screen edits the list options in place and shows every config knob
with its resolved value and source (e there opens config.toml in your editor).
Claude Code is the currently integrated provider. Agent-specific launch and
status contracts live in saikai_provider.py; a Codex contract validates the
extension boundary, but Codex is not selectable until its history discovery and
live-state integration are complete. Claude history discovery respects
CLAUDE_CONFIG_DIR.
Platform support
Verified support is deliberately bounded to Windows 10 / 11 on Python ≥ 3.11. Linux, WSL2, and macOS remain implemented but experimental until their real PTY paths receive sustained native testing. Other platforms are unsupported.
saikai itself is pure Python + Textual; the split-live pane is the only platform-specific part (it drives a real PTY and the clipboard). Honest status:
| OS | Live-pane PTY | Clipboard (from a frozen pane) | RAM gate source | Status |
|---|---|---|---|---|
| Windows 10 / 11 | ConPTY (pywinpty) |
Win32 CF_UNICODETEXT (codepage-safe) |
GlobalMemoryStatusEx |
✅ developed & daily-driven (on WezTerm) |
| Linux (incl. WSL2) | POSIX PTY (ptyprocess) |
OSC-52 (terminal / tmux / SSH policy must allow it) | /proc/meminfo |
⚠️ experimental; native reviewers wanted |
| macOS | POSIX PTY (ptyprocess) |
local pbcopy; OSC-52 fallback for remote-capable terminals |
sysctl + vm_stat (load + physical; no commit limit) |
⚠️ experimental; macOS reviewers wanted |
-
Terminal-agnostic on Windows: the clipboard goes through the Win32
CF_UNICODETEXTAPI and the PTY through ConPTY, neither of which depends on the host terminal — so Windows Terminal uses the same code paths as WezTerm (verified terminal) and is expected to behave identically. -
List-only mode (
SAIKAI_SPLIT_LIVE=0) has no PTY dependency and should run anywhere Textual runs. -
The headless regression tests are platform-independent (they stub out textual / pyte / pywinpty) and pass on the dev machine — run them with plain
python(no deps needed):python tests/test_config.py python tests/test_providers.py python tests/test_sort_recency.py python tests/test_split_divider.py python tests/test_terminal_concurrency.py python tests/test_resource_bounds.py python tests/test_terminal_watchdog.py python tests/test_keyboard_leader.py python tests/test_pty_backend.py
-
Linux/WSL2/macOS reviewers are wanted. Please report the terminal, local vs SSH/tmux setup, PTY teardown result, key quirks, and clipboard behavior.
-
CI installs each OS's real PTY backend and smoke-tests spawn, resize, output, and EOF on Windows, Linux, and macOS. This is not a substitute for interactive review across terminal emulators, SSH, tmux, IMEs, and clipboard policies.
Contributing
Issues and PRs welcome — see CONTRIBUTING.md for the dev setup, how to run the test suites, and the concurrency invariants that keep the split-live pane from deadlocking (read those before touching threading code). Changes are documented in CHANGELOG.md.
Security
Please report vulnerabilities privately — see SECURITY.md. Don't open a public issue for a security problem.
License
saikai is released under the MIT License. It depends on a few
third-party packages installed separately (textual, pyte, pywinpty/ptyprocess) —
see THIRD-PARTY-NOTICES.md. Note pyte is LGPL-3.0; it
is used as an unmodified, separately-installed dependency, which keeps saikai's
own code MIT.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file saikai-0.2.1.tar.gz.
File metadata
- Download URL: saikai-0.2.1.tar.gz
- Upload date:
- Size: 137.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
678e26d07a34ff7becfad4e73fdbc6e1d0f3e5d03cfda9d62f2a739442d8b0bc
|
|
| MD5 |
da53fb506b283f64d64e2b2249f1a1ca
|
|
| BLAKE2b-256 |
6a494adb7a46b7b1291caede063b4820110ecb174ba9e9180bf200d0d7458c42
|
Provenance
The following attestation bundles were made for saikai-0.2.1.tar.gz:
Publisher:
publish.yml on m-morino/saikai
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
saikai-0.2.1.tar.gz -
Subject digest:
678e26d07a34ff7becfad4e73fdbc6e1d0f3e5d03cfda9d62f2a739442d8b0bc - Sigstore transparency entry: 1805329985
- Sigstore integration time:
-
Permalink:
m-morino/saikai@5ef62891e2281890bf072f0bc2984b6d7595a328 -
Branch / Tag:
refs/tags/v0.2.1 - Owner: https://github.com/m-morino
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@5ef62891e2281890bf072f0bc2984b6d7595a328 -
Trigger Event:
release
-
Statement type:
File details
Details for the file saikai-0.2.1-py3-none-any.whl.
File metadata
- Download URL: saikai-0.2.1-py3-none-any.whl
- Upload date:
- Size: 139.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
db04c83c330d954e63d2ba69741617521fa0d35b981ef9458327f073bec5c4be
|
|
| MD5 |
9c4646885e04e260c50ca79941e402d0
|
|
| BLAKE2b-256 |
dcea448f771256f20326475a70f4aef987b486d4c9fb67a22f0ca15c22f4a046
|
Provenance
The following attestation bundles were made for saikai-0.2.1-py3-none-any.whl:
Publisher:
publish.yml on m-morino/saikai
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
saikai-0.2.1-py3-none-any.whl -
Subject digest:
db04c83c330d954e63d2ba69741617521fa0d35b981ef9458327f073bec5c4be - Sigstore transparency entry: 1805330322
- Sigstore integration time:
-
Permalink:
m-morino/saikai@5ef62891e2281890bf072f0bc2984b6d7595a328 -
Branch / Tag:
refs/tags/v0.2.1 - Owner: https://github.com/m-morino
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@5ef62891e2281890bf072f0bc2984b6d7595a328 -
Trigger Event:
release
-
Statement type: