sibyllabs's picture
sibyl-memory-cli v0.3.6: sibyl update command + monorepo source catch-up
9432271
"""ASCII banner for sibyl-memory-cli.
Prints the SIBYL wordmark in ANSI Shadow boxchars with a 24-bit truecolor
vertical gradient flowing from cream/white at the top through warm gold
to deep ochre at the bottom β€” aligned with the lab visual identity per
the operator's brand-discipline rule (creme palette, deep-ochre accent).
Gracefully degrades:
- NO_COLOR env var set β†’ plain text fallback
- stdout is not a TTY β†’ plain text fallback (or skip entirely)
- TERM=dumb β†’ plain text fallback
Truecolor support is detected via $COLORTERM (truecolor / 24bit) β€” most
modern terminals (iTerm2, Alacritty, Kitty, wezterm, Windows Terminal,
modern xterm builds, Ghostty) advertise it. Falls back to 256-color
gradient when not available.
"""
from __future__ import annotations
import os
import sys
# ANSI Shadow rendering of "SIBYL" β€” 6 rows, 41 cols. Each row gets its
# own gradient color (top = pale cream/white, bottom = deep ochre).
_LINES = (
"β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— ",
"β–ˆβ–ˆβ•”β•β•β•β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘ ",
"β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•‘ ",
"β•šβ•β•β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•‘ ",
"β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—",
"β•šβ•β•β•β•β•β•β•β•šβ•β•β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β•β•β•β•β•β•",
)
# Vertical gradient Β· cream β†’ gold β†’ deep ochre. One RGB tuple per row.
# Tuned against the SIBYL palette: --paper #f5f1e6 (top blend),
# --accent #8a6a2a (mid-bottom), with extra highlight + shadow stops
# to give the wordmark visible dimension.
_GRADIENT = (
(253, 251, 245), # almost white, slight cream (top highlight)
(244, 229, 184), # pale gold (upper)
(224, 194, 119), # mid gold (upper-mid)
(184, 146, 73), # rich ochre gold (mid)
(138, 106, 42), # deep ochre Β· brand --accent (lower)
(106, 79, 31), # deepest (bottom shadow)
)
_TAGLINE = "memory you can hold in your hand"
_ATTRIBUTION = "a Sibyl Labs LLC Product. Agentic Infrastructure and Memory Products"
def _supports_truecolor() -> bool:
"""Detect 24-bit color support. Conservative β€” fall back gracefully."""
if os.environ.get("NO_COLOR"):
return False
if os.environ.get("TERM", "").lower() == "dumb":
return False
if not sys.stdout.isatty():
return False
colorterm = os.environ.get("COLORTERM", "").lower()
if "truecolor" in colorterm or "24bit" in colorterm:
return True
# Many modern terminals don't set COLORTERM but do support truecolor.
# Recognize the well-behaved emitters.
term_program = os.environ.get("TERM_PROGRAM", "").lower()
if term_program in {"iterm.app", "wezterm", "ghostty", "vscode", "tabby"}:
return True
term = os.environ.get("TERM", "").lower()
if any(k in term for k in ("256color", "kitty", "alacritty", "xterm-direct")):
return True
return False
def _color_supported() -> bool:
"""Plain ANSI color (3/4-bit). Stricter than truecolor."""
if os.environ.get("NO_COLOR"):
return False
if os.environ.get("TERM", "").lower() == "dumb":
return False
return sys.stdout.isatty()
def _rgb(r: int, g: int, b: int) -> str:
return f"\033[38;2;{r};{g};{b}m"
_RESET = "\033[0m"
def render_banner(*, force_color: bool | None = None) -> str:
"""Return the banner as a string ready to print.
Args:
force_color: Override auto-detection. None = auto, True = force
truecolor, False = force plain text. Useful for testing.
"""
use_truecolor = force_color if force_color is not None else _supports_truecolor()
if not use_truecolor:
# Plain text β€” still visually clean, just no color.
body = "\n".join(" " + line for line in _LINES)
tagline = f"\n {_TAGLINE}"
attribution = f"\n {_ATTRIBUTION}\n"
return body + tagline + attribution
# Colored β€” apply per-row gradient.
colored_lines = []
for line, (r, g, b) in zip(_LINES, _GRADIENT):
colored_lines.append(f" {_rgb(r, g, b)}{line}{_RESET}")
body = "\n".join(colored_lines)
# Tagline in the deepest gold β€” present, but not competing with the wordmark.
r, g, b = _GRADIENT[-1]
tagline = f"\n {_rgb(r, g, b)}{_TAGLINE}{_RESET}"
# Attribution dimmer still β€” a half-step below the tagline so the hierarchy
# reads SIBYL > tagline > attribution at a glance. ANSI dim (\033[2m) gives
# ~55% perceived opacity across the supported terminals.
attribution = f"\n \033[2m{_rgb(r, g, b)}{_ATTRIBUTION}{_RESET}\n"
return body + tagline + attribution
def print_banner(*, force_color: bool | None = None) -> None:
"""Print the banner. Safe to call unconditionally; honors NO_COLOR + TTY checks."""
print(render_banner(force_color=force_color))