fix(sessions+compression+tool-card): stale unread dot, timer leak, tool card duplication (#3020, #2973) - #3116
mysoul12138 wants to merge 2 commits into
Conversation
…esquena#3020, nesquena#2973) nesquena#3020: Sync viewed-count in the polling path for actively-viewed sessions so navigating away doesn't show a stale unread dot. Defensive clear of completion-unread marker in _setSessionViewedCount. nesquena#2973: Clear elapsed-timer attributes and interval when a live compression card transitions from running to done, preventing the orphan timer from overwriting the completed card state. Guarded by active-session check. Tool card duplication: Route tool_complete result to tc.snippet (detail) instead of tc.preview (header) to prevent identical content appearing in both the card header and expanded detail section. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Review — three changes, mixed verdictPulled the PR worktree and read all three diffs against origin/master. Two of the three look good; the third has a regression risk I want to flag before merge. #3020 (unread dot) — LGTMThe counts[sid] = next;
_saveSessionViewedCounts();
// If the viewed count is now current, any prior completion-unread marker is
// stale — clear it so _hasUnreadForSession doesn't short-circuit (#3020).
_clearSessionCompletionUnread(sid);…plus the if (completedObservedStream || completedPersistedObservedStream || completedWithNewMessages) {
if (!_isSessionActivelyViewedForList(sid)) {
_markSessionCompletionUnread(sid, s.message_count);
} else {
// Sync viewed count so we don't flag stale unread on tab switch (#3020)
_setSessionViewedCount(sid, messageCount);
}
}This matches the earlier triage prescription on #3020 exactly — sync the viewed count for actively-viewed sessions on every polling cycle, and defensively clear the completion-unread marker inside the count setter. Belt-and-braces, good. #2973 (compression timer leak) — LGTMThe const _activeCompState = _compressionStateForCurrentSession();
if (!_activeCompState || !_activeCompState.automatic || _activeCompState.phase !== 'running') {
_clearCompressionElapsedTimer();
}The active-session guard is important — Tool-card duplication — please reconsiderReading the live tool event flow:
The PR's replacement at the same site: if(d.preview){
tc.snippet=tc.snippet||d.preview;
if(!tc.preview) tc.preview=d.preview;
}Trace through the two real cases against With-progress tool (agent emitted progress text via
No-progress tool (most tools —
The "no progress" case is the common one — most non-streaming tools (shell exec, read_file, search) don't emit interim Suggested fixEither:
I'd lean toward option 1 — same effect with less branching, and it also covers the reload-path duplication at Other notes
Verdict#3020 part: LGTM. #2973 part: LGTM. Tool-card-duplication part: please reconsider — under the current shape it fixes one class of card (with-progress) by regressing another (no-progress, which is most tools). I'd be inclined to merge the first two changes now and pull the third out for revision with option 1 above. Happy to look at a v2 of just the tool-card change. |
When tc.snippet === tc.preview (common for no-progress tools where both are set to the same result_snippet), the detail block would show identical content as the header. Skip the detail block in this case. This also handles the reload-path where derived entries get snippet populated but no preview, so displaySnippet falls back to the snippet content for the header — same deduplication applies. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
Shipped in v0.51.161 (Release EG, stage-batch43) via release PR #3147 — thank you, @mysoul12138! 🎉 Your change (stale unread dot + compression-timer leak + tool-card dedup (#3020, #2973)) is now on This PR was cherry-picked onto current master (its branch base was several releases stale; a naive merge would have reverted intervening releases). GitHub didn't auto-close because the release merged the reparented commit rather than your branch's exact head SHA, so closing manually. Full diff + tests verified on |
…dedup) into stage-batch43
…quena#3116 Upstream sessions.js _setSessionViewedCount now directly calls _clearSessionCompletionUnread (PR nesquena#3116, merged via nesquena#3116 stage-batch43). Bug 1 was already removed in commit 1a7385a (upstream PR nesquena#3069). session-patches.js is now fully redundant.
…dedup) into stage-batch43
…dedup) into stage-batch43
Summary
Three bugfixes, rebased onto current master (post-#3069):
Session completion unread dot persists after navigating away from actively-viewed session #3020: Sync viewed-count in the polling path for actively-viewed sessions so navigating away doesn't show a stale unread dot. Defensive clear of completion-unread marker in
_setSessionViewedCount.Auto-compression running state keeps timing until the whole session ends #2973: Clear elapsed-timer attributes and interval when a live compression card transitions from running to done, preventing the orphan timer from overwriting the completed card state. Guarded by active-session check to avoid killing a timer driving another session's display.
Tool card duplication: Fix tool card header/detail showing identical content after tool completion. Route result to
tc.snippetonly, preservingtc.previewas the last streaming progress text.What's NOT in this PR
ensure_cron_projectsystem flag (may be a follow-up)test_pr_3019_3020_2973.py(tests need updating for new scope)Test plan
🤖 Generated with Claude Code