File size: 3,624 Bytes
5ef3875 | 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 | """The YCode start-up banner.
The art is assembled from per-letter glyphs (ANSI Shadow style) so every row
has exactly the same width and the letters always line up. A plain-ASCII
fallback is used when the terminal cannot encode box-drawing characters.
"""
from __future__ import annotations
from dataclasses import dataclass
_GLYPHS: dict[str, tuple[str, ...]] = {
"Y": (
"βββ βββ",
"ββββ ββββ",
" βββββββ ",
" βββββ ",
" βββ ",
" βββ ",
),
"C": (
" βββββββ",
"ββββββββ",
"βββ ",
"βββ ",
"ββββββββ",
" βββββββ",
),
"O": (
" βββββββ ",
"βββββββββ",
"βββ βββ",
"βββ βββ",
"βββββββββ",
" βββββββ ",
),
"D": (
"βββββββ ",
"ββββββββ",
"βββ βββ",
"βββ βββ",
"ββββββββ",
"βββββββ ",
),
"E": (
"ββββββββ",
"ββββββββ",
"ββββββ ",
"ββββββ ",
"ββββββββ",
"ββββββββ",
),
}
_ASCII_FALLBACK = (
"__ __ ____ _ ",
"\\ \\ / // ___|___ __| | ___ ",
" \\ V /| | / _ \\ / _` |/ _ \\",
" | | | |__| (_) | (_| | __/",
" |_| \\____\\___/ \\__,_|\\___|",
)
TAGLINE = "AI Coding Agent"
def render_word(word: str = "YCODE", gap: str = "") -> list[str]:
"""Render ``word`` with the block glyphs; returns one string per row."""
letters = [_GLYPHS[ch] for ch in word.upper()]
height = len(letters[0])
return [gap.join(letter[row] for letter in letters) for row in range(height)]
def banner_lines(*, unicode: bool = True) -> list[str]:
return render_word("YCODE") if unicode else list(_ASCII_FALLBACK)
def supports_unicode(encoding: str | None) -> bool:
if not encoding:
return False
try:
"βββββββ".encode(encoding)
except (LookupError, UnicodeEncodeError):
return False
return True
@dataclass(frozen=True)
class BannerInfo:
version: str
model: str
directory: str
branch: str | None = None
project_types: tuple[str, ...] = ()
approval_mode: str = "normal"
instructions_loaded: bool = False
def info_lines(info: BannerInfo) -> list[tuple[str, str]]:
"""Key/value rows shown under the banner. Never includes secrets."""
rows = [
("YCode", f"v{info.version}"),
("Model", info.model),
("Directory", info.directory),
]
if info.branch:
rows.append(("Git branch", info.branch))
if info.project_types:
rows.append(("Project", ", ".join(info.project_types)))
rows.append(("Approvals", info.approval_mode))
if info.instructions_loaded:
rows.append(("Instructions", "YCODE.md loaded"))
return rows
def render_banner_text(info: BannerInfo, *, unicode: bool = True) -> str:
"""Plain-text banner (used by tests and non-rich output)."""
lines = banner_lines(unicode=unicode)
width = max(len(line) for line in lines)
out = list(lines)
out.append(TAGLINE.center(width).rstrip())
out.append("")
out.extend(f"{key + ':':<13} {value}" for key, value in info_lines(info))
return "\n".join(out)
|