cctally 1.51.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,22 @@ 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
+
14
+ ## [1.52.0] - 2026-06-19
15
+
16
+ ### Added
17
+ - **Dashboard (mobile) — prev/next day stepper on the Daily modal.** On a phone the Daily modal's thirty selectable day bars don't fit, so the modal now shows ‹ prev / next › day-stepper controls at the mobile breakpoint (desktop keeps the full bar row and the existing ↑↓ keyboard nav, which the stepper shares its `stepDay()` helper with) (#214).
18
+
19
+ ### Fixed
20
+ - **Dashboard (mobile) — modal & overlay correctness.** Opening any of the seven overlays (modal, share, composer, settings, update, doctor, help) now locks page scroll on both `<html>` and `<body>`, so the page no longer scrolls behind the overlay, and each overlay's own scroll region contains its overscroll. The Session and Block detail modals reflow their token grid two-up so an 8-digit CACHE READ value no longer clips, long modal titles ellipsize to one line, and the share composer preview is framed as a labeled "Preview · <theme>" document (#214).
21
+ - **Dashboard (mobile) — touch-target ergonomics.** Controls that fell below the 44×44px touch-target minimum at phone widths — session-list buttons, the open-conversation affordance, the sortable column header, the doctor chip, and settings checkboxes/radios — are lifted to ≥44px, and the session-row model chip is edge-anchored so it no longer steals taps meant for the row's project link (#214).
22
+ - **Dashboard (mobile) — single-column layout & content flow.** Panels now size to their content instead of reserving the desktop 320px floor, so sparse panels (Projects, Cache Report, Recent Alerts) stop showing large dead space; every panel header stays on one line; the Daily heatmap cell is `$`-prefixed; the session card uses a deterministic two-row grid (project + cost, then started · duration · model); and the Projects panel gives the name column the flexible track so common names are no longer clipped. All changes are gated to ≤640px, so desktop output is byte-unchanged (#214).
23
+
8
24
  ## [1.51.0] - 2026-06-19
9
25
 
10
26
  ### 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,