Skip to content
| Marketplace
Sign in
Visual Studio Code>Other>Session Rail for Claude CodeNew to Visual Studio Code? Get it now.
Session Rail for Claude Code

Session Rail for Claude Code

Ali Ahnaf

|
4 installs
| (1) | Free
Shows every running Claude Code session on the machine as a nested sidebar tree: project, session, subagent, task.
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

Session Rail icon

Session Rail

VS Marketplace version Installs Rating License: MIT VS Code ^1.90.0 Zero runtime dependencies

Session Rail shows every Claude Code session running on your machine as a nested sidebar tree in VS Code — project, session, subagent, task — so you can see what every claude process is doing without hunting through terminal tabs.

It is a handy tool for both halves of the way people work with Claude Code today. If you lean on multi-agent orchestration and write little code by hand, Session Rail is the control tower: every session, every nested subagent, every task, in one tree you can watch and steer. If you have no interest in living inside a prompt, you keep coding in your editor while a glance at the sidebar tells you which sessions are running, which are generating, and which are done, with a click to jump into any of them. Same tool, both worlds.

The Sessions view docked on the right of a VS Code window: projects grouped by working directory, the open project expanded to show one green live session and a run of red exited ones, each labelled with its Claude Code title and age

Demo

Watch the demo — the tree filling in as sessions start, a subagent nesting under its parent, and a click jumping into a running session.

Quick start

  1. Install

    From a local build of this repo:

    npm install && npm run package
    

    Or, once it is published to the Marketplace:

    code --install-extension AliAhnaf.session-rail
    
  2. Open the view — click Sessions in the Activity Bar (the rail icon).

  3. Wait a beat. Nothing to configure. Any claude running anywhere on the machine — in VS Code, in iTerm, over SSH — appears within one poll interval (2 s by default). A brand-new session shows up once it has registered itself under ~/.claude, so give it a second or two.

What you see

The tree has four levels:

  • Project — a working directory (or git root, per sessionRail.groupBy) with one or more sessions. Pinned ones are lifted into a Pinned section at the top — see Pinned folders.
  • Session — one claude process, live or past.
  • Subagent — a Task/Agent-tool invocation, nested under whatever spawned it, to any depth.
  • Task — one to-do item from the session's todo list, when it has one and sessionRail.showTasks is on.

Reading a row

Every row packs its detail into the greyed-out text after the label. Hover for a full tooltip (session id, pid, cwd, entrypoint, Claude Code version, agent task description).

Row Label Grey description
Project folder name number of live sessions, 4 past when none are running, or no sessions for a pinned folder with nothing in the tree
Pinned (section) Pinned how many folders are pinned
Session (live) Claude Code's own session title, or its derived name until a title exists name · branch · model · effort · timer — timer is the elapsed run time while generating, idle 04:12 otherwise
Session (past) same exited · 3d ago
Subagent agent type, plugin prefix stripped d2 (spawn depth) plus its run time once finished
Task the to-do subject done when completed

Fields that Claude Code did not write are simply absent — a session with no branch shows no branch.

Icons and colors

Icon Meaning
🟢 filled circle session is live and idle
🟠 filled circle session or subagent is generating right now
🔴 filled circle session has exited
✓ check subagent finished
○ / 🕐 / ✓ task pending / in progress / completed

Colors are themeable: sessionRail.live, sessionRail.working, sessionRail.exited, sessionRail.waiting. They are semantic, not branding. sessionRail.waiting is reserved — a waiting state is not derivable from disk, so no row is currently colored with it.

Actions

Click a session row → Open Terminal.

Inline icons (hover a row, right end):

Icon On Does
+ project starts a new claude in that directory
pin / pinned project Pin Folder / Unpin Folder
terminal any session Open Terminal
output past sessions opens the transcript viewer
folder-opened project, session Show in Explorer

Right-click menu adds, per row type:

  • Open Transcript — also available here for live sessions and for subagents, which have no inline icon for it.
  • Reveal Working Folder — opens the folder in Finder/your file manager. A different action from Show in Explorer; deliberately menu-only.
  • Copy Session ID.
  • Pin Folder / Unpin Folder — project rows; see Pinned folders.
  • Stop Session — SIGTERM, behind a modal confirm. Live rows only.

View title bar: search · clear search (appears only while a search is active) · + new session in this window's folder (it asks which one in a multi-root workspace, and falls back to your home directory when no folder is open) · refresh · show/hide exited (one toggle, two icons, so the icon shows the current state).

Opening a session that is running somewhere else

Two processes cannot share one transcript — that corrupts it. So when you click a live session whose terminal this window cannot see, Session Rail asks first:

  • Move here — stops that process (SIGTERM) and resumes the session in a new terminal here. Same session id, same row. Anything it had not written to disk is lost.
  • Fork instead — leaves it running and continues the conversation under a new session id, which shows up as a second row.

Set sessionRail.openLiveSession to adopt or fork to skip the prompt. A session already hosted in this window is simply focused; an exited session always resumes in place with no prompt.

Pinned folders

Pin Folder (the pin icon on any project row) lifts that folder into a Pinned accordion at the top of the tree. Unpin from the same spot.

  • Pinned folders keep the order you pinned them in — the section does not reshuffle itself when a session starts somewhere.
  • A pin outlives its sessions. Pin a folder and it stays listed even with nothing running in it, showing no sessions, with its + ready to start one. That is the point: it is a shortcut to the folders you work in.
  • Collapse the section and it stays collapsed.
  • Pins live in the extension's own storage, per machine — they are not a setting, so they are never synced to another machine, where the paths would mean nothing.
  • A pinned folder that no longer exists still shows; starting a session in it tells you it is gone.

Searching

Click the Search sessions… row at the top of the tree, or the magnifier in the view title. The tree filters as you type, matching the session title (or its name when it has no title yet).

  • Escape restores whatever was active before you opened the box.
  • Emptying the box clears the filter.
  • The search row shows the match count, and survives at zero matches — an empty tree would look like the machine has no sessions at all.
  • no matches · exited hidden means the query only searched live sessions. Turn on Show Exited Sessions to widen it.

The query is transient: it dies with the window and is never written to settings.

Past sessions

Turn on sessionRail.showExited to include sessions that are no longer running, and sessionRail.historyDays (7 by default) to say how far back to look.

Two things worth knowing:

  • History comes from transcripts, not from the session registry — the registry only tracks live processes. So history rows are deliberately shallow: no subagents, no tasks, no branch/model/effort. They keep their title, their age, and their transcript.
  • An empty exited list is not a broken toggle. Depending on the Claude Code version, session records may be cleaned up the moment a process exits, and any transcript older than historyDays is out of scope.

Transcript viewer

Open Transcript opens a read-only webview of the conversation: user turns, assistant turns, tool calls and results. It shows the last 512 KB of the transcript (they reach many megabytes) and has a Reload button to pull in whatever has been appended since.

Status bar

One item on the left summarizes the machine: 3 live, or a spinner and 1 generating when something is producing output, plus · 2 agents when subagents are running. Hover for a per-project breakdown; click to reveal the view. It hides itself when nothing is live.

Settings

Setting Type Default Description
sessionRail.refreshInterval number (500–30000) 2000 How often to poll ~/.claude for changes, in milliseconds. Lower values cost more CPU.
sessionRail.showTasks boolean true Show task nodes under a session or subagent that has a todo list.
sessionRail.showExited boolean false Show sessions that have exited. Their transcripts survive, so they can still be opened for review.
sessionRail.historyDays number (0–90) 7 Days of past sessions to recover from transcripts when exited sessions are shown. 0 shows only what the session registry still knows about.
sessionRail.groupBy cwd | gitRoot "cwd" Group projects by working directory, or by git repository root (folding subdirectory sessions into their repo).
sessionRail.terminalLocation editor | panel "editor" Where a terminal that Session Rail opens appears. A session already running in this window is focused where it is.
sessionRail.openLiveSession ask | adopt | fork "ask" What to do when you open a session that is live in a terminal this window cannot see. adopt stops it and resumes under the same id; fork leaves it alone and continues under a new id.
sessionRail.claudeHome string "" Overrides the location of ~/.claude. Mainly for testing; leave empty for the default.

Troubleshooting

The tree is empty but claude is running. A session registers itself under ~/.claude shortly after start — press Refresh. If it still does not appear, run Session Rail: Show Log and check for read errors; a nonstandard CLAUDE_CONFIG_DIR needs sessionRail.claudeHome pointed at it.

Clicking a session opens a new terminal instead of focusing the old one. Terminal linking walks process ancestry with ps, which is POSIX-only. On Windows you get a "started elsewhere" notice and a resume instead.

Rows look wrong after upgrading Claude Code. ~/.claude is private, unversioned state with no compatibility guarantee. Its shape does change between releases, and Session Rail may show stale or partial data until it is updated to match. Please open an issue with the version.

What it writes

Nothing under ~/.claude — no writes, no moves, no deletes. The one thing it stores is your list of pinned folders, in VS Code's own per-machine extension storage. Three actions have effects outside it, all user-initiated:

  • Stop Session sends SIGTERM to the session's process (modal confirm first).
  • New Session Here / New Session in Workspace Folder open a terminal and run claude in it — that process writes its own state, as any session does.
  • Show in Explorer appends a workspace folder, which VS Code persists to your .code-workspace (or an untitled workspace). It is add-only — it never removes a root you arranged by hand, and it asks first for your home directory or the filesystem root.

Development

npm install
npm run watch

Then press F5 in VS Code to launch an Extension Development Host with Session Rail loaded. If F5 does not work:

# for macOS, adjust the path to your VS Code installation:
"/Applications/Visual Studio Code.app/Contents/Resources/app/bin/code" \
  --extensionDevelopmentPath="$PWD" --new-window

Other scripts: npm run build (production bundle), npm run typecheck, npm run lint, npm run package (.vsix).

CLAUDE.md documents the architecture, the frozen contracts, and the invariants worth not breaking.

  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
© 2026 Microsoft