Agent view for every CLI — one screen for parallel Copilot, Claude, Codex, Qwen, Gemini, Kimi background sessions.
- Where is my running agent? —
Enteron any 🟡 Needs input / 🟢 Working session to attach / focus its terminal tab - Too many tabs — every background session in one view with clear status badges
- Which needs my input? — 🟡 Needs input vs 🟢 Working vs 💤 Resumable at a glance
- Finding that one session —
/to search. Hybrid ranking fuses keyword (BM25) + semantic embeddings + lexical scoring via Reciprocal Rank Fusion, so typos, paraphrases, and half-remembered phrases all land the right session. Indexes titles, summaries, compaction summaries, and your own messages - Hundreds of sessions piling up —
gto assign to groups;Shift+Tabto view by group; optional AI auto-suggest - Close without worry — shut down anytime; all sessions remain discoverable + resumable
- Resume after reboot — summaries, last activity, full last response so you can pick up the right one
Claude Code's claude agents is single-vendor and only shows sessions it dispatched. This TUI does more:
| What we add | |
|---|---|
| Multi-CLI | One screen for Copilot · Claude · Codex · Qwen · Gemini · Kimi |
| Sees every session, not just backgrounded ones | Plain claude and claude agents are two disjoint pools today — sessions you ran with claude (interactive) never appear in claude agents, past or future, unless you explicitly background them. This TUI reads each CLI's own session directory, so every session shows up regardless of how it was started |
| Hybrid content search | BM25 keyword + semantic embeddings + lexical scoring fused via Reciprocal Rank Fusion. Tolerates typos and paraphrases without penalizing exact matches. Searches titles, summaries, and your own messages mid-transcript |
| Thematic groups | g to tag any session into a named group; Shift+Tab to browse by group |
| AI-suggested groups | Optional ACP-driven auto-clustering of ungrouped sessions |
- Resume after reboot — summaries, last activity, full last response so you can pick up the right one
Intelligent Terminal is an experimental fork of Windows Terminal with native agent integration — the terminal that hosts your agent CLI. This TUI is the cross-CLI switchboard for everything those agents leave behind.
| What we add | |
|---|---|
| Cross-CLI, not single-host | Intelligent Terminal hosts one agent per pane. This TUI surfaces every session from every provider — Copilot, Claude, Codex, Qwen, Gemini, Kimi — in one list |
| Hybrid content search | BM25 + semantic embeddings + lexical, fused via RRF. Find a session by typo, paraphrase, or half-remembered phrase across every provider at once |
| Thematic groups across providers | Group sessions by project or theme regardless of which CLI ran them; optional AI-suggested clustering |
| Runs anywhere | Pure ratatui TUI — works inside Intelligent Terminal, Windows Terminal, tmux, or any plain terminal on Windows / Linux / macOS |
Use them together: Intelligent Terminal for the conversation, this TUI for the catalog.
┌─────────────────────────────────────────────────────────────┐
│ TUI (ratatui + crossterm) │
│ Session List │ Session Detail │ Activity Log │
│ Hybrid RRF Search (BM25 + semantic + lexical) · Tab Focus │
├─────────────────────────────────────────────────────────────┤
│ SessionViewModel (incremental merge, phased loading) │
│ Supervisor (tokio — parallel provider scans, non-blocking) │
│ Discovery · Process matching · Launch/Resume (config-driven)│
├─────────────────────────────────────────────────────────────┤
│ Provider plugins (data-only — read from each CLI's state) │
│ Copilot │ Claude │ Codex │ Qwen │ Gemini │ Kimi │ (more…) │
├─────────────────────────────────────────────────────────────┤
│ Shared infrastructure │
│ Process detection │ Semantic DLL (optional) │ Archive store │
└─────────────────────────────────────────────────────────────┘
No internal database. Providers read directly from each CLI's own state directory (read-only). All providers scan in parallel for fast refresh. The SessionViewModel merges results incrementally per-provider for progressive loading.
Three states, mirroring claude agents vocabulary:
| Badge | This TUI | claude agents |
Meaning |
|---|---|---|---|
| 🟢 | Running | Working | Actively running tools or generating a response |
| 🟡 | Waiting | Needs input | Finished — waiting for your reply / permission |
| 💤 | Resumable | Completed | Not currently running — attach / resume anytime |
Enter on Running / Waiting attaches (focuses existing terminal tab). Enter on Resumable relaunches.
| Key | Action |
|---|---|
↑/↓ or j/k |
Navigate sessions |
Enter (⏎) |
Resume selected session — focuses the WT tab if Running, launches otherwise |
n |
New session (launches default provider) |
a |
Archive session (instantly hidden) |
g |
Assign current session to a group (← → pick from existing, type to add new) |
s |
Run AI grouping on the top ungrouped sessions (Grouped view) — see AI Auto-Grouping |
y / n / e |
Accept / dismiss / edit pending AI suggestion (cursor must be on a session with a 🤖 shadow) |
/ |
Search (type to filter, ↑/↓ to browse, Enter to resume, Esc to cancel) |
Shift+Tab |
Cycle Active → Grouped → Hidden views |
Tab |
Switch panel focus (works for all 5 providers) |
PgUp/PgDn |
Scroll detail panel |
Esc |
Cancel search |
q / Ctrl+C |
Quit |
Native mouse text selection works (click-drag to highlight and copy).
| Provider | State Dir | Session Format |
|---|---|---|
| Copilot CLI | ~/.copilot/session-state/ |
workspace.yaml + events.jsonl + lock files |
| Claude Code | ~/.claude/projects/ |
<encoded-cwd>/<session-id>.jsonl |
| Codex CLI | ~/.codex/sessions/ |
Session directories with state files |
| Qwen CLI | ~/.qwen/projects/ |
<encoded-cwd>/chats/<session-id>.jsonl |
| Gemini CLI | ~/.gemini/tmp/ |
<project>/chats/session-*.jsonl + subdirs |
| Kimi | ~/.kimi/sessions/ |
Session JSONL files |
Copy config.toml.example next to the binary and rename to config.toml:
data_dir = '~/.local/share/agent-session-tui'
poll_interval_ms = 2000
log_max_lines = 500
[providers.copilot]
enabled = true
default = true # 'n' launches this provider
command = "copilot"
default_args = []
state_dir = '~/.copilot/session-state'
resume_flag = "--resume"
launch_method = "wt" # "wt" | "pwsh" | "cmd"
launch_fallback = "cmd" # optional — fallback if primary not found
[providers.claude]
enabled = true
command = "claude"
default_args = []
state_dir = '~/.claude/projects'
resume_flag = "--resume"
launch_method = "wt"For full control over launch commands, use custom launcher fields:
# Windows — open in a new Windows Terminal tab
launch_cmd = "wt"
launch_args = ["-w", "0", "new-tab", "--startingDirectory", "{cwd}", "cmd", "/k", "{command}"]
# Linux/macOS — open in a new tmux window
# launch_cmd = "tmux"
# launch_args = ["new-window", "-c", "{cwd}", "{command}"]Placeholders: {cwd} → working directory, {command} → the agent CLI command.
Config search order: next to exe → %APPDATA%/agent-session-tui/config.toml → built-in defaults.
Search is a hybrid ranker. Three independent signals score every session, then Reciprocal Rank Fusion (RRF) combines their ranked lists into a single ordering:
| Signal | What it catches |
|---|---|
| BM25 (Tantivy full-text index) | Exact keywords, multi-word phrases, weighted titles |
| Semantic (cached embeddings, optional DLL) | Paraphrases — "improve grammar" finds "Polish English Writing" |
| Lexical (substring + fuzzy) | Typos and partial recall — "iteation revew" still finds "Iteration Review" |
On top of fusion: an exact-title substring lock pins any session whose title literally contains your query to rank 1, so remembering the query correctly is never penalized. State and recency act as soft tie-breakers.
30-query benchmark over ~780 sessions, comparing the previous additive scorer with the current RRF default:
| Additive | RRF (default) | |
|---|---|---|
| MRR | 0.696 | 0.802 |
| P@1 | 53% | 73% |
| Recall@10 | 93% | 90% |
Per-category P@1 jumps: exact-title 33% → 100%, person-name 50% → 100%, semantic-only 38% → 62%, typo 0% → 33%. Keyword and partial-recall queries hold their ground.
- No flags, no opt-in — RRF is the default scorer
- The semantic signal needs the optional
semantic_search.dll/.so/.dylibplugin; without it, the ranker degrades gracefully to BM25 + lexical - Embeddings are pre-computed and cached per session — search itself never embeds
- Status bar shows 🧠 when the semantic plugin is loaded
- Indexes are incremental — only changed sessions are re-indexed on each scan
- No index migration needed when upgrading: schema, fingerprints, and embedding cache are unchanged
agent-session-tui --search-bench "iteration review" --expect <session_id> --top 10
agent-session-tui --search-eval --report eval/runs/today.jsonReads a gitignored eval/search-queries.toml of (query, expected session) pairs and reports MRR / P@1 / Recall@K, per-category and overall. Useful for catching ranking regressions before they ship.
The semantic plugin lives in semantic-plugin/. See CONTRIBUTING.md § Semantic Search Plugin for the build + install steps.
Optional. Asks an AI agent (GitHub Copilot CLI by default) to suggest thematic groups for your ungrouped sessions. Off by default — opt in via config.toml.
- Sends each ungrouped session's title, summary, and updated_at timestamp (never file contents) to the AI in batches of 30.
- The AI proposes a group name + score for each session, or skips it.
- Suggestions render inline as a dim
· ⟨group⟩shadow under the session row in the Active view. - Press
yto accept,nto dismiss, oreto edit the group name before saving.
| Mode | How to trigger | What happens |
|---|---|---|
| Manual | s in Grouped view |
One batch, results open in a popup so you can step through y/n/e |
| Auto | auto_suggest = true in config |
Runs in the background after the initial session load. Chains batches automatically until every ungrouped session has been analyzed. No popup — suggestions appear inline as shadows. |
copilotCLI installed on PATH and authenticated (copilot login)prompts/group-suggest.mdtemplate next to the binary (shipped in the release zip)
[acp]
command = "copilot"
extra_args = ["--effort", "low"] # ~30% faster than default; quality unchanged for this task
auto_suggest = false # set to true for background auto-suggest
timeout_secs = 180 # bump if your model is slow
# prompt_template = '~/.config/agent-session-tui/group-suggest.md'- ~25–45s per 30-session batch with
--effort low - Each batch counts against your Copilot CLI usage quota
- Auto-suggest chains batches: ~1 minute per 30 sessions until all are processed
g— assign the selected session to an existing group (← → to pick) or type a new one
Groups are sorted by most-recent member activity, frozen on entry to the Grouped view to avoid jitter on the 2-second scan refresh. To refresh the order, leave and re-enter the view via Shift+Tab.
| Package | Size | Contents |
|---|---|---|
| Core | ~1.1 MB | agent-session-tui binary only |
| Semantic | ~26 MB | Core + semantic_search_plugin DLL |
Built for x64 and arm64 across all three platforms (Windows, Linux, macOS).
See .github/instructions/plugin.instructions.md for the full guide.
Implement the Provider trait (data-only — no launch/resume logic needed):
pub trait Provider: Send + Sync {
fn name(&self) -> &str;
fn key(&self) -> &str;
fn capabilities(&self) -> ProviderCapabilities;
fn discover_sessions(&self) -> Result<Vec<Session>>;
fn match_processes(&self, sessions: &mut [Session]) -> Result<()>;
// Optional: discover_sessions_paged(), session_detail(), activity_sources(),
// infer_state(), tab_title()
}Launch/resume/kill are handled by the framework from config.toml. Register your provider in main.rs::create_provider().
Requires the MSVC toolchain on Windows (for the windows crate used by tab focus):
rustup override set stable-x86_64-pc-windows-msvc # Windows only
cargo build --release
# Binary: target/release/agent-session-tui(.exe)# Unit tests only (runs on CI)
cargo test --lib
# All tests including provider integration tests (needs real session data)
cargo test -- --nocapture
# Specific provider
cargo test --test copilot_lifecycle_test -- --nocapture
cargo test --test claude_lifecycle_test -- --nocapture
cargo test --test qwen_lifecycle_test -- --nocapture
cargo test --test gemini_lifecycle_test -- --nocapture
cargo test --test codex_lifecycle_test -- --nocaptureSee CONTRIBUTING.md for how to get started — adding providers, building the semantic plugin, and code standards.
For project internals, design decisions, and AI agent context, see AGENTS.md.
