Repository navigation
The domain-free curses layer under the PATE-stack TUIs. Stdlib only, no install step.
Everything here was driven by building catnip's redesigned views on top of this layer — the additions are the primitives that turned out to be missing, and the fixes are drawing faults that only showed up once real data hit them.
Added
grids.py—heatmap()andramp_glyph(). A rows × columns intensity grid, the complement tobar_chart: bars answer "how much over time, for one series", the grid answers "which series, on which day". Clips oldest columns rather than newest, so "now" always stays on screen.grids.scrollbar()— a vertical track and thumb for any scrollable pane. Draws nothing when everything fits, and never rounds the thumb away to zero, since a zero-height thumb says "no overflow" on a four-thousand-row list.grids.diverging_bars()— signed values above and below a zero line, for series where the sign is the finding rather than the magnitude.heatmap(header_gap=…)— blank rows between column labels and the first row.interact.RowCursor— a selection index plus the scroll offset that keeps it visible, withtotal/pagesupplied per call so one cursor survives a list that shrinks under it. The precondition for any list → detail drill-down.bar_chart(geometry=...)— an optional out-dict reporting the layout actually used. A caller annotating a chart cannot derive bar positions once binning and shrinking have run. Purely additive.
Fixed
heatmap'sglyph_forreturn value was repeatedcell_wtimes, so marking one cell in a five-wide column emitted twenty-five characters and slid every later column out from under its header.heatmapcolumn labels collided at the right edge, running two dates together as0708-06. Labels are now walked newest-first and dropped rather than overlapped.- A bar carrying both
peakandvalue_labelshad its value written over the marker, so a chart whose legend promised "▲ marks this day" drew none.
Vendoring
grids.py is a new module, so the byte-identity set (framework, charts, fmt, windows) is untouched. It is optional at every vendor site, like interact.py. catnip/src/catnip/tui is registered in tools/check-vendor.sh.
80 tests pass on 3.10 and 3.14.