English | 한국어
Bookmark, search, and resume pi coding-agent sessions with a fast keyboard-driven TUI.
pi --resumelists every session you ever started. After a week that's 50+ entries with no titles, no tags, no order — just scroll and pray. pisesh adds the one thing that was missing: ⭐ favorites, instant search, and a[NOW]badge for the session you're attached to.
Real capture: ★ starred session at the top, the rest available behind the Today and All tabs. Tab cycles. f stars. Enter resumes.
Pi accumulates sessions across many working directories — your home, several project dirs, scratch tmux panes. The built-in resume picker is alphabetical-ish and forgets context. After a few weeks:
- You can't tell which session was "the one where you fixed the auth bug"
- You can't pin the 3-4 long-running threads you keep going back to
- You re-open the wrong session and pollute it with unrelated context
- You waste time searching by timestamp guessing
pisesh is a single-file Node script (no dependencies, ~600 LoC) that gives you everything pi --resume doesn't.
| Need | What you get |
|---|---|
| Mark important sessions | ⭐ Star/unstar with one keystroke; favorites persist to one global JSON |
| Find a session by what you said | / searches id + project + first user prompt |
| Know which session you're attached to | [NOW] badge on the live session (passed from pi via env var) |
| Keep your terminal clean | Alt-screen buffer — exit restores your terminal byte-for-byte (like vim) |
| Read Korean / Chinese / Japanese prompts | Display-width-aware truncation; columns never blow up on CJK |
| Open from anywhere | Run as standalone pisesh shell command, or /sesh inside pi |
| Zero install pain | No build step, no native deps, runs on Node 18+ everywhere |
| Trust it with your history | pisesh only writes one favorites file; session jsonl files are read-only |
# Install both the CLI and the /sesh slash command in one go
pi install npm:piseshThis registers pisesh as a pi extension. Inside any pi session, type /sesh.
npm install -g pisesh
piseshUse this if you want pisesh as a separate shell command and don't need the pi slash binding.
git clone https://github.com/Blue-B/pisesh.git
cd pisesh
npm link # symlink ./bin/pisesh into your global PATH
pisesh --helpPi-extension side: drop extensions/sesh.ts into ~/.pi/agent/extensions/ and run /reload inside pi.
| Key | Action |
|---|---|
↑ ↓ / j k |
move cursor |
Tab / h / l |
switch tab (★ Favorites → Today → All) |
f / Space |
star / unstar the selected session |
Enter |
resume — spawns pi --session <id> --session-dir <dir> |
d |
session details (full prompt, file, byte size, timestamps) |
/ |
search by id / project / first user prompt |
Esc |
clear search first, then quit |
q / Ctrl-C |
quit (terminal restored) |
r |
rescan session files (after pi starts a new session) |
c (in details view) |
copy session id to clipboard (clip.exe / pbcopy / xclip) |
Home End PgUp PgDn |
jump to top / bottom / ±10 |
For scripts and automation:
pisesh --list # print starred session IDs (one per line)
pisesh --json # full favorites file as JSON
pisesh --star <partial-uuid> # star a session from a script
pisesh --unstar <partial-uuid> # unstar
pisesh --help| Area | Details |
|---|---|
| Runtime | Node.js ≥ 18 (uses only built-in modules: fs, path, os, child_process, readline) |
| TUI rendering | Raw ANSI escape sequences (no blessed / ink / chalk dependency) |
| Alt screen buffer | \x1b[?1049h / \x1b[?1049l — same primitive as vim, less, htop, droid CLI |
| Input | Node's readline.emitKeypressEvents in raw mode |
| Width calculation | UAX #11 East Asian Width ranges, compressed to ~10 inline range checks |
| Pi extension | TypeScript factory using @earendil-works/pi-coding-agent extension API (ui.custom, tui.stop) |
| Storage | Single JSON file at ~/.pi/agent/favorites.json ({ ids: [...], updated: "iso" }) |
| Session discovery | Direct filesystem scan of ~/.pi/agent/sessions/<projectSlug>/*.jsonl; first 96 KB parsed |
| Process model | Slash command pauses pi's TUI, spawns pisesh with inherited stdio, restarts pi on exit |
- No
npm installfor the bundled CLI runtime — true zero-dep - No native binaries / GPU / ffmpeg / database
- No network calls, no telemetry, no analytics
- No daemon / background process
pi (session A) ── /sesh ──▶ ui.custom + tui.stop()
│
└─▶ spawn pisesh (PISESH_CURRENT_SESSION=A)
│ ↑↓ Tab f / Enter on session B
│
└─▶ spawn pi --session B --session-dir <dir>
│
│ user works in B …
│ user types q / ^D
│
◀─── inner pi exits, pisesh exits
│
◀─── tui.start() + requestRender(true)
pi (session A) continues exactly where it was
The current pi session is paused, not lost. When you finish with the resumed session, you pop back to A with full state intact.
| What | Where |
|---|---|
| Favorites | ~/.pi/agent/favorites.json |
| Sessions | ~/.pi/agent/sessions/<projectSlug>/<timestamp>_<uuid>.jsonl (pi's native layout — pisesh never writes here) |
Favorites file shape:
{
"ids": [
"019e79b9-d2c1-741f-81ea-1dcad9a2d712",
"019e6355-9957-7a30-b4ce-b9db5e3c9ac6"
],
"updated": "2026-05-31T01:33:21.234Z"
}It's a single global file (not per-project). Back it up by syncing one file.
Korean / Chinese / Japanese / fullwidth characters render 2 cells wide in terminals; pisesh measures display width (not JavaScript code-unit length) when truncating and padding. Korean prompts never wrap, columns stay aligned, and the layout looks identical whether the prompt is hello world or 안녕하세요 세상.
✓ aitapps 지금 디렉토리에 앱인토스 제출용앱을 만들었는데…
✓ 공모전 신소재 공학 관련 졸업과제 도와줘…
✓ WhisperSubTrans 이슈 #26 이전 버전 아닌가 확인…
(Previously: Korean prompts overflowed to a second line and broke the table.)
- Node.js ≥ 18 (uses optional chaining,
for…ofon strings — no transpile needed) - A terminal with ANSI escape + alternate screen buffer support — basically every modern emulator:
- Windows: Windows Terminal, WezTerm, Alacritty ✅
- macOS: iTerm2, Terminal.app, WezTerm, Alacritty, Kitty ✅
- Linux: GNOME Terminal, Konsole, xterm, Alacritty, Kitty ✅
pion$PATHfor theEnter-to-resume action
| Status | Item |
|---|---|
| ✅ | Tabs, star/unstar, search, alt-screen, CJK width, [NOW] badge, pi /sesh |
| 🚧 | n / N jump to next / previous search match (less-style) |
| 🚧 | Highlight matched substring in yellow |
| 🚧 | Filter by today/yesterday/this-week |
| 🧠 | Optional summarize first-N user prompts via local model for richer titles |
| 🧠 | Export starred sessions as a single bundle (share / archive) |
| 🧠 | Inline rename / label (n to add a custom title that overrides first prompt) |
PRs welcome for anything in the 🚧 lane.
git clone https://github.com/Blue-B/pisesh.git
cd pisesh
npm link
npm test # node --check + smoke testBranching: short-lived feature/<scope> or fix/<scope> → squash-merge into main.
Commits: Conventional Commits style (feat:, fix:, docs:, chore:).
Open a PR — the CI matrix runs on Ubuntu / macOS / Windows × Node 18 / 20 / 22.
If pisesh saves you context-switching time or just makes pi nicer to live in, supporting it directly accelerates development:
- Your support helps: bug fixes, new keybindings, more search modes, integration with other pi extensions.
- Transparency: I don't sell data; funds go to development time and a coffee or two.
- One-time sponsors are credited in README and release notes (opt-out available).
- Monthly sponsors ($3/mo via GitHub Sponsors) get best-effort priority triage for "Sponsor Request" issues.
- pi-coding-agent by @mariozechner — the agent and its extension API that make
/seshpossible. - interactive-shell example extension — pattern reference for
ui.custom+tui.stopTTY handoff. - Inspiration for the favorites + tabs UX: droid CLI and tmux's sesh.
The pi extension uses the @earendil-works/pi-coding-agent API; check pi's own license for that side. The CLI binary is pure Node and has no other licenses to worry about.
