Skip to content

fix(sessions): pick the latest custom-title from anywhere in Claude session files - #6809

Open
SailingLoong wants to merge 2 commits into
farion1231:mainfrom
SailingLoong:fix/claude-session-latest-custom-title
Open

fix(sessions): pick the latest custom-title from anywhere in Claude session files#6809
SailingLoong wants to merge 2 commits into
farion1231:mainfrom
SailingLoong:fix/claude-session-latest-custom-title

Conversation

@SailingLoong

Copy link
Copy Markdown
Contributor

Hi 👋 Small Session Manager fix from the open-issue pile.

Fixes #6787

Problem

Claude Code appends custom-title entries to the session JSONL inline at rename time, so where the entry lands in the file depends on when the rename happened. parse_session only samples the first 10 and last 30 lines (read_head_tail_lines(path, 10, 30)), so once ~30 more lines are appended after a rename — resuming the session, a long follow-up exchange — the entry falls out of the tail window and the title silently falls back to the first user message. Renamed sessions stop showing their name, as reported in #6787.

Title events genuinely have no positional home: on a real session file here, title entries are spread from line 7 to line 2131 out of 2132 total. Any fixed sampling window is the wrong tool for them.

Fix

  • Keep the head/tail sampling for the positionally stable fields (session id, cwd, first user message, last activity, summary) — those are unchanged.
  • Custom titles now come from a dedicated full-file scan that keeps the last non-empty entry, wherever it sits. A substring prefilter limits JSON parsing to candidate title lines, so the extra cost is one sequential read per session file.
  • The custom-title handling was removed from the tail loop (it would otherwise be a second, window-limited source of the same fact).

Tests

  • New parse_session_prefers_the_latest_custom_title_above_the_tail_window: two renames early in the file + 40 trailing lines → the latest name wins. Revert-verified: it fails on main with first message and passes with the fix.
  • All 11 claude provider tests green; full cargo test (14 test binaries, 0 failed), cargo fmt --check and cargo clippy --all-targets -- -D warnings clean. No frontend files touched; pnpm typecheck / pnpm format:check pass on the identical frontend tree.

Checklist / 检查清单

  • pnpm typecheck passes / 通过 TypeScript 类型检查
  • pnpm format:check passes / 通过代码格式检查
  • cargo clippy passes (if Rust code changed) / 通过 Clippy 检查(如修改了 Rust 代码)
  • Updated i18n files if user-facing text changed / 如修改了用户可见文本,已更新国际化文件

Happy to adjust.

…ession files

Claude Code appends custom-title entries inline at rename time, so the
entry can sit far above the 30-line tail window that parse_session
samples. After a rename followed by more conversation, the Session
Manager silently fell back to the first user message and the new name
never showed up.

Sample head/tail lines are kept for positionally stable metadata
(session id, cwd, first message, last activity, summary). Custom titles
now come from a dedicated full-file scan that keeps the last non-empty
entry and only JSON-parses lines passing a cheap substring prefilter.

Fixes farion1231#6787
@github-actions github-actions Bot added the backend Backend (Rust/Tauri) label Aug 25, 2026
@farion1231

Copy link
Copy Markdown
Owner

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6d51aa51ba

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".


// Claude Code appends custom-title entries inline at rename time, so they
// can sit far above the tail window sampled above; scan the whole file.
let custom_title = scan_last_custom_title(path);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Avoid rescanning every Claude transcript in full

For users with many or large Claude histories, opening or refreshing the session manager now reads the total contents of every transcript because claude::scan_sessions calls this once per discovered file, and list_sessions waits for that worker before returning any sessions. This replaces the previous bounded head/tail I/O with work proportional to the entire retained history—including potentially huge tool-result lines—even for files that have never been renamed, so the page can become extremely slow and I/O-heavy. Please cache indexed titles using file metadata or otherwise avoid an unconditional full-file pass during every listing.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair concern — the full scan is the price of correctness here (title events have no guaranteed position, which is the bug this PR fixes). Addressed the cost side in 2e26836: titles are now cached per file keyed on mtime + size, and since Claude Code only ever appends to these transcripts, unchanged metadata means the cached title is still current and the full read is skipped on every refresh. First listing still pays the full scan for files that carry titles; the substring prefilter keeps that pass cheap for the (majority of) transcripts that never had one.

Tests: a chmod-based test proves the read is skipped on a hit (stat stays readable, the full read fails, the title still comes back), and a growth test proves the entry is invalidated on append. Full suite: 2683 passed.

Listing sessions now rescans every transcript in full because the
latest custom-title can sit anywhere in the file. Claude Code only
appends to these transcripts, so unchanged mtime + size means the last
scanned title is still current and the full read can be skipped.

- stat failures (missing/unreadable metadata) fall back to an uncached
  full read, so behavior outside the listing path is unchanged
- cache-hit test proves the read is skipped (chmod 000 keeps stat
  working but fails the full read); growth test proves invalidation
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend Backend (Rust/Tauri)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Claude Code的会话历史名称没有取最新的"customTitle"

2 participants