{"id":50705948,"url":"https://github.com/johan-lindahl/session-explorer","last_synced_at":"2026-06-11T15:01:34.065Z","repository":{"id":360490035,"uuid":"1250396976","full_name":"johan-lindahl/session-explorer","owner":"johan-lindahl","description":"A Claude Code plugin that turns your ~/.claude session transcripts into a file-explorer TUI — browse, rename, organize into folders, add notes, and resume sessions from one slash command.","archived":false,"fork":false,"pushed_at":"2026-06-09T10:16:43.000Z","size":6634,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-09T12:24:17.451Z","etag":null,"topics":["ai","anthropic","claude","claude-code","cli","developer-tools","llm","plugin","productivity","python","session-manager","terminal","textual","tui"],"latest_commit_sha":null,"homepage":"https://github.com/johan-lindahl/session-explorer#readme","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/johan-lindahl.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-26T15:34:19.000Z","updated_at":"2026-06-09T10:27:26.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/johan-lindahl/session-explorer","commit_stats":null,"previous_names":["johan-lindahl/session-explorer"],"tags_count":25,"template":false,"template_full_name":null,"purl":"pkg:github/johan-lindahl/session-explorer","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johan-lindahl%2Fsession-explorer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johan-lindahl%2Fsession-explorer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johan-lindahl%2Fsession-explorer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johan-lindahl%2Fsession-explorer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/johan-lindahl","download_url":"https://codeload.github.com/johan-lindahl/session-explorer/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johan-lindahl%2Fsession-explorer/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34204181,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-11T02:00:06.485Z","response_time":57,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai","anthropic","claude","claude-code","cli","developer-tools","llm","plugin","productivity","python","session-manager","terminal","textual","tui"],"created_at":"2026-06-09T12:00:26.081Z","updated_at":"2026-06-11T15:01:34.059Z","avatar_url":"https://github.com/johan-lindahl.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# session-explorer\n\n[![CI](https://github.com/johan-lindahl/session-explorer/actions/workflows/ci.yml/badge.svg)](https://github.com/johan-lindahl/session-explorer/actions/workflows/ci.yml)\n\nA Claude Code plugin that turns `~/.claude/projects/*.jsonl` transcripts into a\nfile-explorer-style listing: browse, organize, and resume sessions from a single\nslash command.\n\nThe Textual TUI gives you arrow navigation, expand/collapse, rename, move,\ndelete, notes, a preview pane, live filter, and a live indicator showing which\nsessions are running right now. The text-mode `list` subcommand remains for\nscripting.\n\nSee [`SPEC.md`](./SPEC.md) for the full design.\n\n## What it looks like\n\nSessions are grouped by project, then by the `/`-separated folders encoded in\ntheir names. Stat columns show age, approximate context size, the share of the\ncontext window used, and message count.\n\n![The session-explorer tree view](docs/images/tree.png)\n\nPress `Space` for a preview pane with the full name, project, branch, notes,\nfirst prompt, and transcript path:\n\n![The preview pane](docs/images/preview.png)\n\nPress `h` for the built-in help (it also auto-opens on first launch):\n\n![The help overlay](docs/images/help.png)\n\n### Side by side with your session\n\nWhen tmux is available, resuming doesn't take over the terminal. The explorer\nstays in the **left** pane and the session you resume docks in a pane on the\n**right**, so you watch the tree and the running session at once. `F9` flips\nfocus between the two panes (or click either one), `F12` zooms the focused pane\nfullscreen, and the tmux status line keeps those hints visible even when a pane\nis zoomed. Selecting a different session swaps it in; the others keep running\noff-screen. Press `c` to start a brand-new session, which docks the same way.\n\n![The explorer and a live claude session side by side](docs/images/split.png)\n\nWithout tmux, resume instead hands the whole terminal straight to `claude`.\n\n### Live sessions\n\nSessions running right now are flagged in the left column — an animated green\nspinner for a session actively working, a dim `○` for one that's open but idle —\nand the subtitle shows `● N active`. Live rows refresh from their transcript\nabout every 2 seconds, so the first prompt, message count, tokens, and context %\nfill in and tick up as the agent works. Live sessions appear even when unnamed.\n\n![Live-session indicator](docs/images/live.png)\n\n\u003e Screenshots use sample data.\n\n## Install\n\nThis GitHub repo **is** the plugin marketplace — there's no separate packaging\nor publishing step. Installing and distributing are the same two commands.\n\n### Option A — Claude Code marketplace (recommended; also how you share it)\n\nRun these inside Claude Code:\n\n```\n/plugin marketplace add johan-lindahl/session-explorer\n/plugin install session-explorer@session-explorer\n```\n\n`session-explorer@session-explorer` is `\u003cplugin-name\u003e@\u003cmarketplace-name\u003e`; both\nhappen to be `session-explorer` here.\n\n**Distributing to colleagues:** the repo is public, so just send them those two\nlines — no access grants needed. When you push a new version, they update with:\n\n```\n/plugin marketplace update session-explorer\n/plugin install session-explorer@session-explorer\n```\n\n### Option B — plain shell installer (local development)\n\n```bash\ngit clone https://github.com/johan-lindahl/session-explorer.git\ncd session-explorer\n./install.sh\n```\n\nBoth paths register session-explorer's lifecycle hooks (session indexing plus\nthe live-session indicator). Neither touches your Claude Code settings: managing\nsession retention (which changes `cleanupPeriodDays`) is **opt-in** — the\nexplorer asks the first time you open it. See\n[Cleanup \u0026 retention](#cleanup--retention).\n\n\u003e **Platform note:** `/session-explorer:open` opens the TUI in a new terminal\n\u003e window — **macOS** (Terminal.app) and **Linux** (your `$TERMINAL` or a known\n\u003e emulator) are supported directly. On **Windows, use WSL**: the plugin runs as\n\u003e a Linux app there, and the launcher opens a Windows Terminal window back into\n\u003e your distro when `wt.exe` is available. If no launcher is found on any\n\u003e platform, the command to run is printed so you can paste it into a terminal\n\u003e yourself. Native (non-WSL) Windows is not supported.\n\n### Add to your Dock (macOS)\n\nOnce installed (either path above), create a clickable Dock launcher:\n\n```\nsession-explorer install-app\n```\n\nThis builds `~/Applications/Session Explorer.app` with the explorer icon and\npins it to your Dock. Clicking it opens the explorer in a new Terminal window —\n**with tmux**, the same as `/session-explorer:open`. If automatic pinning\ndoesn't take, drag the app from `~/Applications` onto your Dock yourself.\n\nTo remove it later, run the uninstall (it removes the app and unpins it):\n\n```\nsession-explorer uninstall\n```\n\n## Usage\n\nAfter install, start any new Claude Code session in any project. The hook\nrecords the session into `~/.claude/session-explorer-index.json` automatically.\n\nFrom inside Claude:\n\n```\n/session-explorer:open\n```\n\n(Plugin commands are always namespaced as `\u003cplugin-name\u003e:\u003ccommand\u003e` — there's\nno way to drop the prefix.)\n\nThis opens a new Terminal.app window showing your sessions grouped by project\nand folder. Quit the TUI with `q` to close the window.\n\nFrom a regular shell:\n\n```bash\nsession-explorer list      # text listing\nsession-explorer launch    # open in a new Terminal window\nsession-explorer tui       # run the TUI in the current terminal\n```\n\n## TUI keybindings\n\n| Key | Action |\n|---|---|\n| `↑` `↓` | Move between rows |\n| `←` `→` | Collapse / expand the current folder or project |\n| `Enter` | Resume the selected session — when tmux-hosted, docks it in a pane beside the tree and focuses it so you can type; without tmux, hands the terminal to `claude --resume \u003cid\u003e` |\n| `c` | Create a new session in the selected project (prompts for a name, working directory, and optional git worktree; docks it like a resume). **Leave the name blank** to start a throwaway *unnamed* session — it's hidden by default and auto-reaped by `--gc`. The tree cursor jumps to the new session once it appears. |\n| `Space` | Toggle the preview pane (full name, project, folder, branch, age, created, messages, context, session id, notes, first prompt, path) |\n| `r` / `F2` | Rename a session (also moves it between folders), or rename a folder's last segment in place — folder renames cascade across the whole subtree |\n| `n` | Create an empty folder |\n| `m` | Move a session to a folder, or re-parent a whole folder under another path (`(ungroup)` for top level) |\n| `d` | Delete the selected session (confirms; removes the JSONL too), or an empty folder (refuses if it still contains sessions) |\n| `e` | Edit notes (Ctrl+S to save) |\n| `Tab` | Cycle the view: **named + active** (default) → **active only** (just the running sessions) → **all** (including unnamed) → back |\n| `z` | Collapse the tree to project roots, then drill into the one you want; press again to expand everything. Drill-down sticks across refreshes |\n| `g` | Toggle a live subscription-usage bar (current 5-hour limit) in the tmux status line — off by default, tmux-hosted only; toggling off then on is the manual force-refresh |\n| `F5` | Rescan `~/.claude/projects/` — import sessions not yet tracked (shows a progress bar) |\n| `F9` | *(tmux-hosted)* Switch focus between the explorer and the docked session pane — also by mouse click |\n| `F12` | *(tmux-hosted)* Zoom the focused pane fullscreen and back |\n| `/` | Live filter across name, notes, first prompt, summary |\n| `h` | Show help (auto-opens once on first launch) |\n| `Esc` | Close the preview pane / help (or clear an active filter) |\n| `q` | Quit |\n\n\u003e The leftmost column shows live state: an animated spinner (working), a dim `○`\n\u003e (idle), or blank (inactive). The rename / move / new-folder / new-session /\n\u003e notes dialogs appear as centered overlays matching the help screen. `F9` and\n\u003e `F12` are tmux-server keybindings — they work from either pane (even a zoomed\n\u003e one), and their hints live in the tmux status line.\n\n## How sessions are organized\n\nSession names map to folders via `/`-separated paths:\n\n| Session name | Folder path | Display name |\n|---|---|---|\n| `planning/sprint14` | `planning` | `sprint14` |\n| `audits/q1-review` | `audits` | `q1-review` |\n| `team/planning/q1` | `team/planning` | `q1` |\n| `sprint14` | *(none)* | `sprint14` |\n\nDashes are plain characters with no special meaning. Multiple `/` segments\ncreate nested folders of any depth. Rename a session with Claude's built-in\n`/rename` command; the next session start (or `session-explorer index\n--refresh`) reflects the change.\n\n## Cleanup \u0026 retention\n\nRetention is **opt-in**. The first time you open the explorer, it asks whether\nto let session-explorer manage retention. This is the *only* time the plugin\nmodifies your Claude Code settings — the hooks never touch them.\n\n- **If you say yes:** your current `cleanupPeriodDays` is backed up to\n  `~/.claude/.session-explorer.backup` and set to `36500`, disabling Claude's\n  native expiry so the plugin handles it. `uninstall` restores your original\n  value. Old-session GC (below) is then active.\n- **If you say no:** nothing is changed — Claude's native cleanup stays in\n  charge, and the plugin just browses/organizes/resumes. (You won't be asked\n  again; delete `~/.claude/.session-explorer.retention-declined` to re-trigger\n  the prompt.)\n\nOnce enabled, `session-explorer index --gc` deletes **unnamed** sessions idle\nlonger than the retention window (default 30 days). Named (renamed) sessions are\nnever touched, and sessions that look live — a transcript modified in the last\n60 seconds, or one holding an active lock — are skipped. You don't have to run\nit manually: while retention is enabled, the `SessionStart` hook fires `--gc` at\nmost once every 24 hours, in the background.\n\n```bash\nsession-explorer index --gc                   # delete now (defaults)\nsession-explorer index --gc --dry-run         # show what would be deleted\nsession-explorer index --gc --retention-days 7\n```\n\n`--dry-run` reports the count (and how many live sessions it skipped) without\ndeleting anything.\n\n## Uninstall\n\nUninstalling restores your original `cleanupPeriodDays` (saved when you enabled\nretention, if you did) and removes session-explorer's files. **Run the teardown\nfirst, then remove the plugin** — `/plugin uninstall` deletes the binary, so the\norder matters.\n\nYour session index and folder data (names, notes, folders) are **kept by\ndefault** so a reinstall restores them. Add `--purge` to delete those too.\n\n### Marketplace install\n\nRun the teardown (this resolver locates the installed binary, which isn't on your\nshell `PATH`), then remove the plugin inside Claude Code:\n\n```bash\nbash -c 'F=\"$HOME/.claude/plugins/installed_plugins.json\"; CLI=$(python3 -c \"import json,sys,os; d=json.load(open(sys.argv[1])) if os.path.exists(sys.argv[1]) else {}; e=d.get(\\\"plugins\\\",{}).get(\\\"session-explorer@session-explorer\\\",[]); print((e[0].get(\\\"installPath\\\",\\\"\\\")+\\\"/bin/session-explorer\\\") if e else \\\"\\\")\" \"$F\"); [ -x \"$CLI\" ] || CLI=$(command -v session-explorer); \"$CLI\" uninstall'\n```\n\n```\n/plugin uninstall session-explorer\n```\n\n### Plain install\n\n```bash\n./uninstall.sh            # add --purge to also delete the index + folders\n```\n\n## Status\n\n**v1.17.4.** Released and installable from the Claude Code marketplace. Textual\nTUI with a live-session indicator (animated spinner = working, dim `○` = idle,\n`● N active` subtitle, live-refreshing stats) and centered-overlay dialogs\n(including the rescan progress); rename/move on both sessions and whole folders\n(folder ops cascade across the subtree); folders/delete/notes; preview pane;\nlive filtering; rescan (`F5`); opt-in `--gc` retention with a once-daily\nauto-trigger; `session-explorer uninstall`; model-aware context sizing;\nmacOS/Linux/WSL launchers (native Windows out of scope); tmux-backed\nsplit-pane interaction (explorer left / docked claude right, `F9` switch focus,\n`F12` zoom fullscreen, background sessions, live preview snapshots,\ncontext-aware Enter, quit-guard); new-session creation from the tree (`c`);\nopt-in subscription-usage bar in the tmux status line (`g` toggle, 5-min\nrefresh, `SESSION_EXPLORER_PROBE` hook bail-out); reversible worktree cleanup\n(`w` to reclaim a stopped worktree's directory, an offer when a docked worktree\nsession exits clean, and `--gc` pruning of idle worktrees — branch + transcript\nalways kept, resume rebuilds); and a shared-resource lease engine (see note below) with a read-only **Queues\npane** (`q`), a per-project **\"Shared installed root\"** setup dialog (`q` → `s`),\nnew-session worktree auto-slug, plus a location-based `PreToolUse` deny hook\n(`root_guard.py`) that blocks worktree sessions from touching the shared root\nthrough tools, and a SessionStart usage hint.\n\n\u003e ⚠️ **Experimental.** The shared-resource queue is enforced for Claude tool\n\u003e calls; non-Claude writers (scripts, the user's own terminal, runtime-computed\n\u003e paths) remain advisory. The dirty-root refusal is the backstop for those.\n\nTested by pytest + bats in CI on ubuntu + macOS across Python 3.11–3.13.\n\n### Running the tests\n\n```bash\npython3 -m pytest test/ -q                                   # Python logic + CLI/TUI\nbats test/install.bats test/uninstall.bats test/hook.bats    # shell scripts + hook\n```\n\npytest needs `pytest` + `pytest-asyncio` (`pip install -r test/requirements-dev.txt`);\nTextual is vendored, so nothing else is required. `bats` is [bats-core](https://github.com/bats-core/bats-core).\n\n## License\n\n[MIT](./LICENSE) — © 2026 Johan Lindahl. Permissive: copy, modify, and\nredistribute freely; just keep the copyright notice.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjohan-lindahl%2Fsession-explorer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjohan-lindahl%2Fsession-explorer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjohan-lindahl%2Fsession-explorer/lists"}