diff --git a/CHANGELOG.md b/CHANGELOG.md index cc84a244..e483f10f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,13 @@ ## [Unreleased] +## [v0.51.373] — 2026-06-12 — Release ML (sidebar lineage + source-count fixes) + +### Fixed + +- **Expanded lineage segments no longer collapse when the session list refreshes mid-stream (#4005).** While a turn was streaming, each sidebar refresh wiped the lineage-report cache and re-collapsed any expanded lineage row. The cache is now pruned to only the rows that left the visible set (kept for still-visible rows), the in-flight report request is identity-guarded so a stale response can't overwrite a newer one, and an expanded row that still needs its report fetches and re-renders in place. (#4005) +- **The sidebar source-filter counts (WebUI / CLI) now match the number of rows actually shown (#3966).** The chip counts were computed from pre-collapse session totals, so they could disagree with the collapsed/grouped rows rendered in the list. Counts are now derived from the same collapse-and-attach pass used to render each source's rows. (#3966) + ## [v0.51.372] — 2026-06-12 — Release MK (markdown link-label inline code, /use skill autocomplete, mobile Worklog overflow) ### Fixed diff --git a/static/sessions.js b/static/sessions.js index 9db59379..51e723fc 100644 --- a/static/sessions.js +++ b/static/sessions.js @@ -4249,10 +4249,25 @@ function _clearLineageReportCache(){ function _pruneLineageReportCacheToVisibleSessions(sessions){ const visibleKeys=new Set(); - for(const s of (Array.isArray(sessions)?sessions:[])){ + const rows=Array.isArray(sessions)?sessions:[]; + for(const s of rows){ const key=_sidebarLineageKeyForRow(s); if(key) visibleKeys.add(key); } + // Also retain the cache keys derived from the COLLAPSED/rendered rows. The + // render loop keys the lineage-report cache by _sidebarLineageKeyForRow on + // the COLLAPSED row (see renderSessionListFromCache), and collapse can merge + // segments so a collapsed row's key differs from any single raw input row's + // key. Mirroring the precedent in _resolveSessionIdFromSidebarLineage, fold + // the collapsed rows' keys in so a still-visible expanded row is never evicted + // (and re-fetched every payload) on a chain the raw keys alone wouldn't cover. + try{ + for(const row of _collapseSessionLineageForSidebar(rows)){ + if(!row||_isChildSession(row)) continue; + const key=_lineageReportCacheKey(row,_sidebarLineageKeyForRow(row)); + if(key) visibleKeys.add(key); + } + }catch(_){ /* defensive: never let a prune-key derivation break list apply */ } for(const key of Array.from(_lineageReportCache.keys())){ if(!visibleKeys.has(key)) _lineageReportCache.delete(key); } diff --git a/uv.lock b/uv.lock new file mode 100644 index 00000000..9431a635 --- /dev/null +++ b/uv.lock @@ -0,0 +1,3 @@ +version = 1 +revision = 3 +requires-python = ">=3.11"