A session browser for opencode. Search every session across every project, preview the transcript, and resume in place — from your terminal or from inside the TUI.
opencode keeps a growing pile of sessions, and its native lists (<leader>l,
/sessions) are scoped to the current project. sesh shows all of them —
grouped by directory, full-text searchable, and previewable from anywhere.
❯ auth
~/code/api (8)
├ Retry the OAuth token refresh 2h
├ Login rate limiting notes 3d
└ auth middleware cleanup 11d
~/code/web (3)
├ Fix session cookie on Safari 1d
└ Redirect loop after logout 6d
- Every session, everywhere. Sessions are grouped by project directory and sorted by recency — across all your projects, not just the current one.
- Full-text search. Type to match against session titles and the text of the conversation itself. Reasoning and tool output are excluded, so the index stays clean.
- Transcript preview. Space shows the most recent messages first, rendered as
Markdown (with
glowif you have it). - Resume in place. Enter
execsopencode --session <id>in the session's own directory. Ctrl-F forks instead. Your terminal becomes the session — no tabs, no panes, no window management. - Native TUI, too. A recent-sessions section in the opencode sidebar plus a
ctrl+opicker, both themed by your opencode theme. - Fast. The database is scanned once per refresh and cached; keystrokes only re-render the last snapshot, so typing never triggers a query storm.
With npm:
npm install -g opencode-sesh
sesh installOr from source:
git clone https://github.com/ozandogrultan/opencode-sesh.git
cd opencode-sesh
bash install.shsesh install (or bash install.sh) links sesh into $XDG_BIN_HOME
(default ~/.local/bin), copies
the sesh-list tool and the TUI panel into
${XDG_CONFIG_HOME:-~/.config}/opencode, registers the panel in tui.json, and
declares the plugin dependencies (opencode installs them on next start). The
panel registers the /sesh slash command. It never edits your shell rc, and any
file it would overwrite is backed up first.
The npm package ships the same scripts and installer; the runtime tools below are still required.
Fully quit opencode and reopen it to load the panel — opencode imports plugins
once at startup, so reloading a window reuses the running process. Upgrades
refresh an already-installed panel automatically (the npm postinstall syncs
it), and sesh --check reports when the installed panel is out of date.
Then:
sesh # terminal picker/sesh # inside opencode — picker (TUI plugin)
ctrl+o # inside opencode — picker
- opencode, used at least once
bash,jq, andfzf>= 0.73sqlite3recommended — the picker queries the session DB directly in milliseconds and falls back to the sloweropencode dbCLI without itglowoptional — styles the transcript preview as Markdown; without it the preview shows the plain Markdown, unchanged otherwise
sesh uninstall # npm installs
bash install.sh --uninstall # from source| Key | Action |
|---|---|
| Type | Search titles and transcript text across all directories |
| Enter | Resume the selected session in this terminal |
| Ctrl-F | Resume as a fork (the original is untouched) |
| Ctrl-G | Toggle current-directory scope / all sessions |
| Space (empty query) | Toggle the transcript preview |
? (empty query) |
Toggle shortcut help |
| Ctrl-X | Delete the selected session |
| Escape | Exit |
Flags: --cwd (current directory only), --limit N (default: all),
--archived, --print (print id<TAB>cwd instead of resuming), --fork,
--query TEXT, --check.
Because --print just emits the id and directory, sesh doubles as a scriptable
session lookup:
read -r id cwd < <(sesh --print --query "auth")| Key | Action |
|---|---|
/sesh |
Open the full picker |
ctrl+o |
Open the full picker (also in the command palette) |
| Type | Search titles, directories and transcript text |
↑/↓, PgUp/PgDn, Home/End |
Move the selection |
| Space | Toggle the transcript preview |
| Enter | Open the selected session |
| Esc | Close |
Click the sidebar's search… box to filter recent sessions in place; click
elsewhere or press Esc to leave search.
The full picker pages through your whole global session list (no fixed window) and indexes transcript text for every session in the background, showing indexing progress under the search box. It only stops at a safety cap of 5,000 sessions, and says so when it does.
All variables are optional.
| Variable | Default | Effect |
|---|---|---|
SESH_DB |
opencode db path |
opencode SQLite database |
SESH_SQLITE |
sqlite3 |
query tool (opencode db is ~300 ms/call) |
SESH_JQ / SESH_FZF |
PATH |
explicit executable overrides |
SESH_GLOW |
first glow on PATH |
optional Markdown preview renderer |
SESH_OPENCODE |
opencode |
opencode executable (resume / delete) |
SESH_CACHE_DIR |
~/.cache/sesh |
persistent search-index cache |
bin/sesh-list.sh is the only bin/ script that reads the opencode session
store (SQLite: session / message / part). Each refresh extracts session
metadata and text-only parts into a persistent per-session cache keyed on
time_updated, part count and the latest part timestamp, then atomically
publishes a snapshot.jsonl. Every keystroke re-renders that snapshot with jq
alone, so typing never starts competing database scans. Reasoning and tool
payloads are never indexed or previewed, and session ids are validated before
any SQL interpolation.
Flat scripts back the terminal UI — the picker (sesh.sh), the refresh engine
(sesh-list.sh, driven by a per-picker sesh-refresh-worker.sh that serializes
scans), preview renderer (sesh-preview.sh), deleter (sesh-delete.sh) and
shortcut help (sesh-shortcuts.sh). The TUI panel (tui/sesh-panel.tsx) is a
SolidJS OpenTUI plugin that talks to the opencode SDK over the same store; the
sesh-list agent tool reads it through opencode db.
Does it replace opencode's native session list? No. <leader>l and the
native /sessions command are untouched; sesh is additive.
Is there an agent-facing list? Yes — the sesh-list tool lets the model list
every session across all directories (the native opencode session list only
covers the current project) and offer to resume one.
Where is my data? It reads the opencode database read-only and caches
extracted text under ~/.cache/sesh. Nothing is uploaded anywhere.
Does it work on Windows? It targets macOS and Linux. WSL should work; native Windows is untested.
Why a separate terminal picker and a TUI panel? The panel is always one keystroke away while you work. The terminal picker is fullscreen and works from any shell, including outside opencode.
Issues and PRs are welcome. See CONTRIBUTING.md for the full guide; this project follows the Code of Conduct. Run the checks before opening a PR:
bun install
bun run test # fixture-database regression suite
bun run test:picker # PTY picker suite (needs fzf >= 0.73)
bun run typecheck # tsc over tui/ and opencode/
bun run lint:sh # bash -n on every scriptHOME=/tmp/fakehome bash install.sh smoke-tests the installer without touching
your real opencode config. AGENTS.md documents the architecture and
the hard-won TUI rules.