All features

A docked Claude session panel and tab hover cards

Try the real interface

Explore this workspace.

Real Torbie UI · mock sessions
Tab bar
Loading Torbie…
Technical background

A panel docked to any edge of the window lists every Claude Code session on the machine — what it is doing, what it last asked, how much of its context window is gone — and a tab's hover card says the same about the session running in that tab. Tabs are joined to sessions by launch directory, never by PID, because a session inside WSL reports Linux PIDs that can never match Tabby's conpty PIDs.

The problem

Running several Claude Code sessions across several terminals means the interesting state — which one is waiting for you, which one is nearly out of context, what one of them last asked — lives in whichever tab you are not looking at.

How it works

A panel docked to any edge of the window lists every session on the machine, and a tab's hover card says the same about the session running in that tab. It rests on two new generic extension points in tabby-core, both add-only files: SidePanelProvider contributes a panel to a dock host that owns the header, the edge picker and the resize handle, and TabHoverProvider contributes a rich hover card for a tab header, falling back to the plain title tooltip when no provider applies.

Settings
  • sidePanel.enabled: false

    Show the docked panel.

  • sidePanel.side: 'right'

    left, right, top or bottom. Moving it never re-creates the component — it is a CSS grid area.

  • sidePanel.size: 320

    Width when docked left/right, height when top/bottom.

  • claude.stithURL: 'https://stith.lvh.me'

    The session registry the panel reads.

  • claude.pollIntervalMs: 2000

    How often the registry is asked.

  • claude.readTranscripts: true

    Derive context-window usage from the transcript tail.

  • claude.hover.enabled: true

    Show the tab hover card.

  • claude.clickAction: 'focus'

    What clicking a session in the panel does.

Details
  • Tabs are joined to sessions by directory, never by PID. A session inside WSL reports Linux PIDs that can never match Tabby's Windows conpty PIDs. Only an unambiguous 1:1 pairing is trusted — a card on the wrong tab is worse than no card.
  • The join key is the launch directory, not cwd. A session's reported cwd follows every cd the agent makes; measured live, 2 of 13 sessions had already drifted. The launch directory is recoverable from the transcript's project folder name, whose encoding is lossy — so it is never decoded: the tab's directory is encoded the same way and the encoded forms compared, which is exact. Verified against the live registry: 11 of 13 reproduce, and the 2 that do not are exactly the drifted ones.
  • The launch directory can be recovered by walking a drifted cwd's ancestors until one encodes to the project key. claude --resume only finds a session from its launch directory, so this is what makes Resume work at all.
  • Data comes from the session registry, not from the hook spool. The spool is consume-and-delete, so a second reader would steal events from the plugin that owns audio and tab decoration. Reading the registry means zero conflict and no plugin changes.
  • Transcripts reach 160 MB, so one is never read whole — a 256 KB tail is enough, verified against every live session.
What this does not claim
  • getWorkingDirectory() alone never matches Windows tabs: tabby-local deliberately returns null when the shell's live directory still equals the one it launched in — i.e. the common case of opening a terminal in a repo and running claude. The profile's cwd and the tab's initial cwd are used as fallbacks.
  • The panel depends on a local session registry service being reachable. With nothing answering at claude.stithURL the panel is empty, which is the honest result rather than an error.
Source commits
Claude CodeAdded 2026-08-0966 files+3,944 / −140 lines