Skip to content

Commit 1ec6b14

Browse files
fix(banner): half padding on single-banner re-stream, none on multi (#47)
Single-banner loops itself on the tape so a breath between repeats reads better: lp=(w-1)//4, g=max(6,(w-1)//6) — half the originals. Multi-banner keeps lp="" and g=" "; crossfade coloring is the boundary signal between distinct conditions. Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 349a030 commit 1ec6b14

2 files changed

Lines changed: 16 additions & 2 deletions

File tree

.console/log.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
_Chronological continuity log. Decisions, stop points, what changed and why._
44
_Not a task tracker — that's backlog.md. Keep entries concise and dated._
55

6+
- Banner single-loop padding at half size (2026-05-08, on fix/banner-single-padding): Single-banner re-stream gets lp=(w-1)//4 and g=max(6,(w-1)//6) — half the original values — so there's a visible breath between loops. Multi-banner keeps lp="" and g=" " (4 spaces); the crossfade coloring is the boundary signal there.
7+
68
- Banner padding stripped (2026-05-08, on fix/banner-strip-padding): Removed leading pad (`(w-1)//2` spaces) and large gap (`max(12, (w-1)//3)` spaces) from `_build_unit` and `_banner_unit_len`. Both cases now use a fixed 4-space separator between units — the tape streams the next banner in seamlessly so the large pads were dead space.
79

810
- Multi-banner cycling system + white-on-red fix (2026-05-08, on feat/multi-banner-cycle): The single-purpose stall banner becomes a 4-level banner system. CRITICAL (white on red — fixes the previous black-on-red look from A_REVERSE), WARNING (white on yellow), INFO (white on cyan), HEALTHY (white on green). Conditions: CRITICAL = stall / SwitchBoard offline / resource gate at cap or below RAM floor. WARNING = backend at concurrency cap / queue depth ≥ 10 / free RAM within 1.2× of gate floor. INFO = first 30s after launch (readings stabilizing). HEALTHY = nothing else. Worst-first sort; cycle index advances every 15 frames (3s at 200ms tick); marquee restarts when cycling. Counter shown on banner when count > 1 ([N/M]). Banner block always renders so layout stays stable; middle_top fixed at 7. 8 new tests in TestBannerConditions; 26 watcher tests passing.

src/operator_console/watcher_status_pane.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1208,7 +1208,13 @@ def _banner_unit_len(message: str, banner_count: int, banner_index: int, w: int)
12081208
"""
12091209
counter = f" [{banner_index + 1}/{banner_count}]" if banner_count > 1 else ""
12101210
payload = f" {message}{counter} "
1211-
return len(payload) + 4
1211+
if banner_count == 1:
1212+
lp = " " * ((w - 1) // 4)
1213+
g = " " * max(6, (w - 1) // 6)
1214+
else:
1215+
lp = ""
1216+
g = " "
1217+
return len(lp) + len(payload) + len(g)
12121218

12131219

12141220
def _wrap_hints(chunks: tuple[str, ...], width: int) -> list[str]:
@@ -1278,7 +1284,13 @@ def _build_unit(b_severity: str, b_message: str, b_idx: int) -> tuple[str, str]:
12781284
"""Return (full_unit_text, severity) for one banner condition."""
12791285
ctr = f" [{b_idx + 1}/{banner_count}]" if banner_count > 1 else ""
12801286
payload = f" {b_message}{ctr} "
1281-
return payload + " ", b_severity
1287+
if banner_count == 1:
1288+
lp = " " * ((w - 1) // 4)
1289+
g = " " * max(6, (w - 1) // 6)
1290+
else:
1291+
lp = ""
1292+
g = " "
1293+
return lp + payload + g, b_severity
12821294

12831295
severity, message = current_banner
12841296
cur_unit, cur_sev = _build_unit(severity, message, banner_index)

0 commit comments

Comments
 (0)