cctally 1.52.0 → 1.52.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,12 @@ based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
5
5
 
6
6
  ## [Unreleased]
7
7
 
8
+ ## [1.52.1] - 2026-06-20
9
+
10
+ ### Fixed
11
+ - **Shareable reports — the right-most x-axis tick label on line charts (e.g. the `$ / day` current-week chart) no longer clips at the chart's right edge.** The final tick sits exactly on the inner-plot right edge, and centering its label there pushed the right half past the chart's narrow right padding into the SVG viewport boundary — most visible for wide labels (the 10-character ISO dates the `$ / day` chart uses) and at narrow render widths such as the mobile share composer preview (390px). Edge ticks are now right-aligned (interior ticks stay centered) so the full label stays inside the plot in every HTML/SVG share output (#215).
12
+ - **Dashboard conversation viewer — `Latest ↓` now follows live-streamed turns instead of landing on a stale entry-time message.** The jump-to-latest control (and the `End` key) jumps to the conversation's final rendered turn. While a conversation was open and live-tailing, new turns streamed in but the control kept jumping to whichever turn was newest at the moment you opened the conversation — the live-tail merge refreshed the message list and header totals but never advanced the recorded "latest turn" pointer (or the last-activity timestamp). Both now track each appended turn, so `Latest ↓` / `End` always lands on the genuinely newest message in a live session.
13
+
8
14
  ## [1.52.0] - 2026-06-19
9
15
 
10
16
  ### Added
package/bin/_lib_share.py CHANGED
@@ -539,10 +539,22 @@ def _render_line_chart_svg(chart: LineChart, *, palette: dict,
539
539
  elements.append(f'<polyline {_serialize_attrs(attrs)}/>')
540
540
 
541
541
  # X-tick labels (one per primary sample, positioned by x_value).
542
+ # The right-most sample lands at the inner-box right edge (ix + iw). A
543
+ # centered (anchor="middle") label there overflows the chart's right
544
+ # padding and is clipped at the SVG viewBox boundary — most visible for
545
+ # wide labels (10-char ISO dates, as the `$ / day` current-week chart
546
+ # uses) at narrow render widths (#215). Right-align (anchor="end") any tick
547
+ # that lands on the right edge so its full width stays inside the plot;
548
+ # interior + left-edge ticks stay centered. Position-based (not index-based)
549
+ # so a forecast chart whose last *primary* sample sits mid-plot — with a
550
+ # projected ray extending past it via multi_series — keeps that tick
551
+ # centered rather than mis-anchoring a non-edge label.
552
+ right_edge_x = ix + iw
542
553
  for p in pts:
543
554
  tx = ix + scale_x(p.x_value)
555
+ anchor = "end" if tx >= right_edge_x - 1e-6 else "middle"
544
556
  elements.append(svg_text(tx, iy + ih + 14, p.x_label,
545
- font_size=10, fill=palette["muted"], anchor="middle"))
557
+ font_size=10, fill=palette["muted"], anchor=anchor))
546
558
 
547
559
  # Y-axis label.
548
560
  elements.append(svg_text(ix - 10, iy + ih / 2, chart.y_label,