# 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 you@example.com · 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//.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.