feat(tui): add Diagnostics panel for stored evidence

Toggle a Diagnostics panel with i, built on the Activity readout. It swaps
in for the Drive pane and shows the decoded critical_warning, power-on
hours, power cycles, unsafe shutdowns, media errors and available spare
with their change over the selection, and per-hour (Day) or per-day
(History) temperature min/avg/max, active/idle/powered-off/unknown split
and coverage. History bars draw reads beside writes while it is open, and a
set critical_warning shows as a badge in the endurance outlook without
affecting the projection. Counter deltas are withheld across a controller
segment change.
This commit is contained in:
xavierk
2026-10-05 21:05:44 +05:30
parent 6c517e4ecb
commit 948e097952
10 changed files with 730 additions and 43 deletions
+22
View File
@@ -50,3 +50,25 @@ def test_many_intervals_and_selection_fit_small_plot_without_losing_points():
assert len(columns) == len(points)
assert text.plain.splitlines()[-2][columns[100]] == "▼"
assert all(len(row) == 32 for row in text.plain.splitlines())
def test_secondary_series_shares_the_axis_and_colours_its_own_dots():
colors = get_graph_colors("chalktone")
writes = [VolumePoint(t, v, str(t)) for t, v in ((0, 10), (1, 10), (2, 10))]
reads = [VolumePoint(t, v, str(t)) for t, v in ((0, 100), (1, 100), (2, 100))]
text, columns, unit = volume_plot(
writes, 48, 10, -1, colors, secondary=reads)
assert "100.00" in text.plain # the larger read volume sets the ceiling
styles = {span.style for span in text.spans}
assert colors["allocated"] in styles and colors["secondary"] in styles
def test_secondary_gap_does_not_draw_or_connect():
colors = get_graph_colors("chalktone")
points = [VolumePoint(t, 5, str(t)) for t in range(3)]
reads = [VolumePoint(0, 9, "0"), VolumePoint(1, None, "1", "gap"),
VolumePoint(2, 9, "2")]
text, columns, _ = volume_plot(points, 48, 10, -1, colors, secondary=reads)
rows = text.plain.splitlines()[:-2]
top = next(r for r in rows if any(0x2801 <= ord(c) <= 0x28ff for c in r))
assert all(c == " " for c in top[columns[0] + 1:columns[-1]])