fix(sidebar+compression+tool-card): cron filter, unread dot, timer leak, tool card duplication (#3019, #3020, #2973) - #3050
mysoul12138 wants to merge 5 commits into
Conversation
…sed-timer leak (nesquena#3019, nesquena#3020, nesquena#2973) Three coordinated bugfixes: - nesquena#3019: Allow cron sessions with project_id through the sidebar filter so the "Cron Jobs" project chip can display them. Frontend filters cron rows from the default "All" view and triggers a server refetch when the cron chip is clicked. - 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. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
SummaryRead the full diff (3 files, +33/-5), pulled the worktree, and walked each of the three fixes against master. The bundling matches what was triaged in #3019, #3020, and #2973 — a small surgical set rather than three separate PRs is the right call here because they share the same #3019 — cron sessions hidden from "Cron Jobs" chipServer-side fix at if source == 'cron' or sid.startswith('cron_'):
return TrueAfter: if source == 'cron' or sid.startswith('cron_'):
return not bool(session.get('project_id'))The cron project ID gets populated at Frontend pairing at :(_activeProject
?profileFiltered.filter(s=>s.project_id===_activeProject)
:profileFiltered.filter(s=>!s.project_id||(s.source_tag!=='cron'&&!String(s.session_id||'').startsWith('cron_'))));The The refetch-on-cron-chip trigger at One small consideration: the #3020 — stale unread dot after navigating awayTwo changes work together:
The #2973 — compression timer leakThis is the one I want to push on. The change at } else {
// Completion or error: clear the elapsed-timer attributes ...
node.removeAttribute('data-compression-started-at');
node.removeAttribute('data-compression-message');
_clearCompressionElapsedTimer();
}The DOM attribute removal is correct — But
How realistic is this? Probably narrow — auto-compression usually drives the active session only, and the existing Safer shape: only clear the timer when the active session has no running compression. Something like: } else {
node.removeAttribute('data-compression-started-at');
node.removeAttribute('data-compression-message');
const activeState = _compressionStateForCurrentSession();
if (!activeState || !activeState.automatic || activeState.phase !== 'running') {
_clearCompressionElapsedTimer();
}
}That predicate matches the one already used at Test planThe PR body has a manual checklist but no test additions. For #3019 a unit test on VerdictTwo of three are ship-ready. The compression timer's unconditional |
…#2973 nesquena#3019: Add system=True flag to cron project in ensure_cron_project() so frontend can reliably identify it without fragile name matching. Backports the flag to existing cron projects on lookup. nesquena#2973: Guard _clearCompressionElapsedTimer() with active-session check in appendLiveCompressionCard(). An SSE completion for a background session must not kill the timer driving the current session's display. Matches the predicate pattern used at ui.js:5261-5262. Tests: add test_pr_3019_3020_2973.py with 5 static-analysis tests covering all three fixes. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The tool_complete SSE handler set tc.preview to result_snippet, which is the same content that buildToolCard displays in the expanded detail section (tc.snippet). This caused the tool card header and detail body to show identical text. Fix: route the result to tc.snippet only, preserving tc.preview as the last streaming progress text. For tools that send no progress events, fall back to using the result as preview so the header is not blank. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
_cliToolResultSnippet truncated to 200 chars while the backend's _tool_result_snippet uses 4000. This caused tool card details to be more aggressively truncated after session reload than during live streaming. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
Triage: HOLD — overlap with #3069 — labels: Thanks for the multi-bug bundle. This PR fixes #3019 + #3020 + #2973 and also bumps the CLI tool-result snippet length from 200 to 4000 chars. There's an overlap problem we want to flag before merging: #3069 also fixes #3019, with a different approach (introduces a We're going to ship #3069's approach for #3019. To avoid wasted work, would you mind:
The system flag on Will revisit once master moves and you've had a chance to slim this down. Thanks for the careful test coverage in |
Summary
Four coordinated bugfixes:
Cron sessions hidden from sidebar when 'Cron Jobs' project chip selected #3019: Allow cron sessions with
project_idthrough the sidebar filter so the "Cron Jobs" project chip can display them. Frontend filters cron rows from the default "All" view and triggers a server refetch when the cron chip is clicked. Cron project created withsystem: trueflag to prevent accidental rename breaking the lookup.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. The
tool_completeSSE handler settc.previewtoresult_snippet, which is the same contentbuildToolCarddisplays in the expanded detail section. Route result totc.snippetonly, preservingtc.previewas the last streaming progress text.Test plan
test_pr_3019_3020_2973.py— 5 static-analysis tests covering all fixes🤖 Generated with Claude Code