Files

1.9 KiB

Sessions sidebar

Status: Implemented · Code: Scripts/sidebar.js, Scripts/sessions-store.js

Two sections: Claude (account, model, permission mode) and Sessions (the project's conversations, newest first, each expanding into its actions).

Claude
  Account          [email protected] · Pro
  Model            Opus
  Permissions      Plan only
Sessions
  ▾ fix the parser bug                    2h ago
      Copy Resume Command
      Copy Resume + Remote Control
      Reveal Session File

Where sessions come from

Claude Code stores one JSONL transcript per session:

~/.claude/projects/<slug>/<session-id>.jsonl

The slug is the project path with / and . flattened to - (/Users/me/git.example.ca/thing-Users-me-git-example-ca-thing). Files are sorted by mtime; firstPrompt() reads up to 40 lines looking for the first non-meta, non-synthetic user message to use as the row's label, falling back to the short session id.

Sessions started in a terminal appear here too — it is the CLI's own store, not something this extension maintains.

Refreshing

Sessions live in ~/.claude, outside the workspace, so nova.fs.watch would never fire for them (and would cost a callback on every project file change). Instead the list is rescanned when the Sessions section becomes visible, plus on demand from the header's refresh button.

Row plumbing

  • TreeItem.command fires on double-click. A session row copies its resume command; an action row runs its own action via claudenova.sessionAction, which reads sessionsView.selection[0].
  • Session rows are Collapsed by default — with 25 rows, expanding all of them would bury the list.
  • getParent() returns the session for action rows so reveal() works.

Gotchas

  • firstPrompt() uses readline() and stops early: transcripts reach megabytes.
  • Zero-byte and non-.jsonl entries are skipped.