File size: 5,208 Bytes
2cf7040 9432271 2cf7040 9432271 2cf7040 9432271 2cf7040 9432271 2cf7040 9432271 2cf7040 9432271 2cf7040 9432271 2cf7040 9432271 2cf7040 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 | """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))
|