Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

claude-sessions.nvim

Shows every Claude Code session on your machine as colored dots in your statusline. Whatever project you're in, one glance tells you which session is working, which is done, and which one is waiting for your permission.

statusline dots

  • 🟡 waiting — needs your permission
  • 🔴 busy — working (the dot animates)
  • 🟢 idle — done, waiting for input

Sessions running in your current project show dimmed, since you can already see those. If there are more than max_dots, the rest collapse into a +N.

It also pairs with tmux-claude-session-manager: hit a key, get a picker with every session, and jump to one — or approve/reject its permission prompt right there, without leaving your buffer. That works even when Claude runs inside a sidekick.nvim split.

How does it know all this? Claude Code writes a small state file for every session it runs (~/.claude/sessions/*.json). The plugin just reads those. No hooks, no CLI calls, nothing to set up on the Claude side.

Requirements

  • Neovim ≥ 0.10
  • Claude Code ≥ 2.1.139 (older versions don't write the session files)
  • A Nerd Font for the default icons

Optional:

  • tmux-claude-session-manager under tmux, if you want the picker. The statusline works without it.
  • sidekick.nvim, if you run Claude inside nvim and want the picker to preview and approve those sessions too.

Install

With lazy.nvim:

{
  "rashedInt32/claude-sessions.nvim",
  event = "VeryLazy",
  opts = {},
}

Setup

All options with their defaults:

require("claude-sessions").setup({
  dir = "~/.claude/sessions", -- honors $CLAUDE_CONFIG_DIR
  poll_ms = 1000,             -- how often to re-read the session files
  spin_ms = 120,              -- busy animation speed (only runs while busy)

  statusline = {
    max_dots = 10,     -- show at most this many dots, then `+N`
    dim_own = true,    -- dim sessions running in this nvim's own cwd
    dim_alpha = 0.55,  -- how much color the dimmed dots keep
    bg = nil,          -- background behind the dots; nil = same as StatusLine
    colors = {
      waiting = "#f5d76e",
      busy = "#f2555a",
      idle = "#7fe08a",
      more = "#9f9ca6",
    },
    icons = {
      waiting = "󰝥",
      idle = "󰝥",
      busy = { "󰪞", "󰪟", "󰪠", "󰪡", "󰪢", "󰪣", "󰪤", "󰪥" },
    },
  },

  picker = {
    -- where tmux-claude-session-manager lives
    script = "~/.tmux/plugins/tmux-claude-session-manager/scripts/list.sh",
  },

  repaint = {
    -- Fixes a rendering bug: after switching tmux sessions, Claude's TUI can
    -- leave stale text painted over its input box (claude-code#62740). When
    -- enabled, the plugin sends Ctrl-L to embedded Claude terminals whenever
    -- nvim regains focus, which makes Claude redraw cleanly. Turn it on if
    -- you run Claude in sidekick under tmux.
    enabled = false,
  },
})

Lualine

require("lualine").setup({
  sections = {
    lualine_x = { require("claude-sessions").lualine() },
  },
})

Not on lualine? status() returns a plain statusline string (with %#…# highlights baked in) and has_sessions() tells you when there's something to show.

Keymap

The plugin doesn't set any keymaps. Here's one that works well:

vim.keymap.set("n", "<leader>au", function()
  require("claude-sessions").pick()
end, { desc = "Pick Claude session" })

How it works with tmux-claude-session-manager

The two are halves of one workflow:

  • The tmux plugin owns the picker popup: jump to a session, watch it live, ctrl-y approve / ctrl-r reject a permission prompt, ctrl-x kill.
  • This plugin puts the dots in your statusline and opens that picker from nvim. It also handles the picker's requests for sessions running inside nvim: their tmux pane belongs to the editor, so the picker can't preview or type into them directly — instead it asks nvim, and this plugin passes the keystroke (or the conversation text) to the right terminal.

Each works on its own. Together, you can sit in one buffer and manage every Claude session on the machine.

API

Function What it does
setup(opts) Apply config, define highlights, start polling
status() The statusline string (empty when nothing runs)
has_sessions() True if any session is running
lualine() Ready-made lualine component
pick() Open the tmux picker (also :ClaudeSessions)
permit(action, pid) Approve or reject an embedded session's permission prompt
preview(pid, lines?) The tail of an embedded session's conversation

permit and preview exist for the picker's scripts, which call them over nvim's RPC socket. You won't call these yourself.

Health

:checkhealth claude-sessions

Checks the session directory, tmux, the picker script, and sidekick.

License

MIT

About

Every Claude Code agent on your machine, in your nvim statusline — plus picker integration to jump, preview, and approve permission prompts without leaving your buffer

Resources

Stars

5 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages