Skip to content

feat: show session titles (agent-name/custom-title/ai-title) in sidebar, tabs and palette - #2

Merged
TheJavaGuy merged 1 commit into
mainfrom
feat/session-titles
Oct 10, 2026
Merged

TheJavaGuy merged 1 commit into
mainfrom
feat/session-titles

Conversation

@TheJavaGuy

Copy link
Copy Markdown
Owner

Summary

Shows a session's title instead of its first user message in the sidebar, tab labels and command palette.

This reimplements Part B of upstream matt1398#129. That PR can't be applied as-is:

  • It conflicts with current main.
  • It adds a second full read of every session file (extractCustomTitle()).
  • It only reads custom-title lines. Current Claude Code also writes {"type":"agent-name","agentName":"..."} (session name) and {"type":"ai-title","aiTitle":"..."} (auto-generated title).

Title precedence:

  1. Last non-empty agent-name / custom-title entry
  2. Otherwise the last non-empty ai-title
  3. Otherwise the first user message (the old behavior)

Changes

  • analyzeSessionFileMetadata (src/main/utils/jsonl.ts): picks up title entries in its existing single streaming pass and returns customTitle. No extra file read and no new cache.
  • Session.customTitle is filled by both ProjectScanner session builders.
  • getSessionTitle() (new src/renderer/utils/sessionTitle.ts): used by SessionItem, CommandPalette and the tab label logic.
  • Tab labels (sessionDetailSlice):
    • Synced for every tab showing the session, on initial fetch and on in-place refresh.
    • On refresh, the sync runs before the chunk-fingerprint early return. A rename only appends a title line and doesn't change chunks, so the early return would otherwise skip it.
  • Manual tab renames: renaming a tab by hand (SortableTab) now sets Tab.labelSetByUser, and the automatic sync skips flagged tabs. Without this flag, any refresh would overwrite a hand-set tab name.

Tests

  • test/main/utils/jsonl.test.ts covers title parsing:
    • agent-name, custom-title, and ai-title only
    • user title beats ai-title regardless of line order
    • last rename wins
    • empty or whitespace titles are ignored
    • no title lines gives undefined
    • title lines don't change messageCount
  • test/renderer/utils/sessionTitle.test.ts covers getSessionTitle.
  • test/renderer/store/sessionDetailSlice.test.ts covers:
    • tab label on fetch
    • label update on refresh when chunks are unchanged
    • a hand-set tab label is kept
  • pnpm typecheck, pnpm lint (no errors) and pnpm test (750 tests) pass.
  • Ran analyzeSessionFileMetadata on real session files: add-healthy-food-plugin (agent-name) and Two envelopes switching simulation (ai-title).

…ar, tabs and palette

Session list, tab labels and command palette now prefer the session title
over the first user message:
1. last non-empty agent-name / custom-title entry
2. else last non-empty ai-title
3. else first user message (previous behavior)

Titles are collected in the existing single streaming pass of
analyzeSessionFileMetadata, so no extra file read or cache is added.

Tab labels are synced on fetch and on in-place refresh (before the chunk
fingerprint early return, since a rename only appends a title line). Tabs
renamed by hand are flagged (labelSetByUser) and never overwritten.
@TheJavaGuy
TheJavaGuy merged commit aa35ef6 into main Oct 10, 2026
@TheJavaGuy
TheJavaGuy deleted the feat/session-titles branch October 10, 2026 19:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant