From 00f45a3827e98560f3d381d675e5972a5ca5579f Mon Sep 17 00:00:00 2001 From: Tirthraj Raval Date: Sun, 26 Jul 2026 15:17:09 +0530 Subject: [PATCH] update(scripts): fixed bugs in installer. - Now supports proper fixed size ANSI art and new fastfetch configuration. - Explicit --logo-type per terminal instead of fastfetch's --logo-type auto. On macOS Ghostty, auto-detect silently picks file-raw and dumps raw PNG bytes to the terminal, even though Ghostty implements the kitty graphics protocol correctly. We already know the terminal family from our own detection, so pick the protocol ourselves: kitty / ghostty / wezterm -> kitty-direct iTerm2 -> iterm Works identically on Linux and macOS. --- cli/install.sh | 140 +++++++++++++++++++++++-------------------------- 1 file changed, 65 insertions(+), 75 deletions(-) diff --git a/cli/install.sh b/cli/install.sh index 4ca50fa..14d5d81 100755 --- a/cli/install.sh +++ b/cli/install.sh @@ -1,38 +1,41 @@ #!/usr/bin/env bash -# install.sh — installer for hypercar-colorscripts (v0.1.1) +# install.sh — installer for hypercar-colorscripts (v0.1.4) # -# Bug-fix release. Changes vs the previous public build: +# Changes from v0.1.3: +# * Explicit --logo-type based on our own terminal detection. +# Fastfetch's auto-detect (default when --logo-type is omitted) +# is unreliable on Darwin: on macOS Ghostty it silently picks +# `file-raw` and dumps the PNG magic bytes to the terminal as +# text, even though Ghostty implements the kitty graphics +# protocol correctly. We already know which terminal family +# we're in (that's what __HC_IMG_OK==1 means), so we pick the +# protocol ourselves: +# - Kitty / Ghostty / WezTerm -> kitty-direct +# - iTerm2 -> iterm +# This works identically on Linux and macOS. # -# * ben10-colorscripts coexistence. Previously, installing hypercar -# after ben10 would leave both shell blocks active (double render). -# Now: -# - if a ben10-colorscripts shell block is already present, hypercar -# defers to it and skips writing its own render block (ben10's -# block already knows how to render both projects); -# - if only the ben10 binary is present (no ben10 block), hypercar's -# own render block includes ben10 in the mixing pool. +# Changes from v0.1.2: +# * Non-image branch renders PNG on-the-fly via `chafa --colors 256` +# instead of cat-ing pre-rendered truecolor ANSI files. +# Pre-rendered ANSI used \e[38;2;R;G;Bm escapes that Apple Terminal +# (256-color only) cannot render, producing garbled half-block +# pixels with overlaid info-card values. +# * `ls` -> `find` for image discovery. # -# * fastfetch styling: writes ~/.config/fastfetch/hypercar.jsonc -# automatically (Catppuccin+ vibrant gradient palette). Arrows now -# align perfectly (`type: name`, no icons — icons re-enabled by -# changing one field in the JSONC). Existing file is backed up. -# -# * chafa fallback: image still renders when fastfetch is not installed. -# -# * kitty logo-type detection fix (kitty-direct → kitty on older -# fastfetch builds). -# -# * macOS portability: `shuf` replaced with an awk one-liner, Ghostty -# detection via TERM_PROGRAM + TERM as well as GHOSTTY_RESOURCES_DIR. -# -# * Broader marker-deletion regex on reinstall; PATH dedupe. +# Prior fixes (from v0.1.1): +# * ben10-colorscripts coexistence (defers when ben10 block present). +# * Vibrant Catppuccin+ gradient JSONC (auto-written). +# * Portable random-line picker. +# * Ghostty detection via TERM_PROGRAM + TERM. +# * Zsh-safe mixing target picker. +# * Broader marker-deletion regex; PATH dedupe. # # Flags: # --system binary -> /usr/local/bin (sudo) # --no-shell skip all .rc modifications # --yes / -y skip confirmations # --with-vintage include vintage cars even with --yes -# --no-mix don't mix with other colorscripts (pokemon / ben10) +# --no-mix don't mix with other colorscripts # --no-ff-config skip writing ~/.config/fastfetch/hypercar.jsonc # --uninstall forward to uninstall.sh @@ -71,7 +74,7 @@ SRC_MANIFEST="$PROJECT_ROOT/manifest.json" SRC_ASSETS="$PROJECT_ROOT/assets" HELPER="$SCRIPT_DIR/_vintage_helper.py" -echo -e "${BLUE}═══ hypercar-colorscripts installer (v0.1.1) ═══${NC}" +echo -e "${BLUE}═══ hypercar-colorscripts installer (v0.1.4) ═══${NC}" # 1. Prereqs + detect other colorscripts projects step "1/9 Prerequisites" @@ -94,16 +97,10 @@ if command -v ben10-colorscripts >/dev/null 2>&1; then ok "ben10-colorscripts detected at $(command -v ben10-colorscripts)" fi -# Detect which kitty logo type this fastfetch understands. -# `kitty-direct` is newer (~2024); older builds only know `kitty`. -KITTY_LOGO_TYPE="kitty-direct" if command -v fastfetch >/dev/null 2>&1; then - if ! fastfetch --help-logo 2>/dev/null | grep -q 'kitty-direct'; then - KITTY_LOGO_TYPE="kitty" - fi - ok "fastfetch logo type: $KITTY_LOGO_TYPE" + ok "fastfetch present" else - warn "fastfetch not installed — image will still render via chafa; info card skipped" + warn "fastfetch not installed — image renders via chafa; info card skipped" fi # 2. Build @@ -124,8 +121,8 @@ step "4/9 Default rendering mode" DEFAULT_MODE="auto" if [[ $ASSUME_YES -eq 0 ]]; then echo "How to render at terminal startup:" - echo " 1) auto — real image in Kitty/Ghostty/WezTerm/iTerm2, ANSI text elsewhere" - echo " 2) ansi — always pre-rendered text" + echo " 1) auto — real image in Kitty/Ghostty/WezTerm/iTerm2, chafa-ANSI elsewhere" + echo " 2) ansi — always chafa-ANSI (works everywhere, 256-color safe)" read -rp "Choice [1]: " m case "${m:-1}" in 2) DEFAULT_MODE="ansi" ;; *) DEFAULT_MODE="auto" ;; esac fi @@ -152,7 +149,7 @@ fi # 6. Mixing step "6/9 Colorscripts mixing" -POKEMON_MIX="false" # config field name kept for backward-compat; controls all mixing now +POKEMON_MIX="false" if [[ $NO_MIX -eq 0 ]] && [[ $HAS_POKEMON -eq 1 || $HAS_BEN10 -eq 1 ]]; then MIXERS="" [[ $HAS_POKEMON -eq 1 ]] && MIXERS="${MIXERS:+$MIXERS + }pokemon" @@ -211,7 +208,7 @@ else fi ok "Binary: $BIN_DIR/$BINARY" -# 8. fastfetch styling config (vibrant Catppuccin+ gradient) +# 8. fastfetch styling config (vibrant gradient) step "8/9 fastfetch styling config" if [[ $NO_FF_CONFIG -eq 1 ]]; then warn "Skipped (--no-ff-config)" @@ -300,10 +297,7 @@ if [[ -n "$SECONDARY_RC" ]]; then fi fi -# Detect if ben10-colorscripts already owns the shell integration in ANY -# of the rc files we're about to touch. If so, we defer to it and skip -# writing hypercar's own render block (ben10's block already handles both -# projects via its coexistence logic). +# Defer to ben10-colorscripts if its block already owns the shell rc. BEN10_OWNS_SHELL=0 for RC in "${RC_FILES[@]}"; do if [[ -f "$RC" ]] && grep -qE '# >>> ben10-colorscripts.*>>>' "$RC" 2>/dev/null; then @@ -316,8 +310,7 @@ if [[ $BEN10_OWNS_SHELL -eq 1 ]]; then warn "ben10-colorscripts shell block detected" echo " ben10's block already handles rendering hypercar alongside itself." echo " Skipping hypercar shell-block write to avoid double-render." - echo " (If you want hypercar to own the block, first run ben10-colorscripts's" - echo " uninstall.sh to remove ben10's block, then re-run this installer.)" + echo " (Run ben10's uninstall.sh first if you want hypercar to own the block.)" echo echo -e "${GREEN}═══ Done ═══${NC}" [[ $INCLUDE_VINTAGE -eq 1 ]] && echo "Installed: $TOTAL_COUNT cars (modern + vintage)" || echo "Installed: $MODERN_COUNT cars" @@ -340,9 +333,6 @@ for RC in "${RC_FILES[@]}"; do BACKUP="$RC.hypercar-backup-$(date +%Y%m%d-%H%M%S)" cp "$RC" "$BACKUP" - # Broad marker cleanup — catches every past variant of our own block - # (only ours; ben10's block is left untouched — but if we got here, - # ben10's block isn't present anyway). sed -i.tmp '/# >>> hypercar-colorscripts.*>>>/,/# <<< hypercar-colorscripts.*<<> "$RC" <<'HC_BLOCK_END' # >>> hypercar-colorscripts >>> @@ -399,18 +386,12 @@ if [ -f "$__HC_CONF" ]; then unset __HC_TMP fi -# Use the hypercar fastfetch styling config if present; deleting it never -# breaks this block (fastfetch just falls back to its default output). __HC_FF_ARGS=() [ -f "$__HC_FF_CFG" ] && __HC_FF_ARGS=(-c "$__HC_FF_CFG") -# Portable random-line picker (macOS has no `shuf` by default). __hc_pick() { awk 'BEGIN{srand()} {a[NR]=$0} END{if(NR)print a[int(rand()*NR)+1]}'; } -# Mixing target selection. We use explicit slot arithmetic instead of -# shell word-splitting on a pool string, because zsh (unlike bash) does -# not word-split unquoted variables by default — which would make the -# picker collapse to always picking "car". +# Mixing target selection (explicit slots — zsh-safe, no word splitting). __HC_TARGET="car" if [ "$__HC_MIX" = "true" ]; then __HC_HAS_POKEMON=0 @@ -419,8 +400,6 @@ if [ "$__HC_MIX" = "true" ]; then command -v ben10-colorscripts >/dev/null 2>&1 && __HC_HAS_BEN10=1 __HC_TOTAL=$(( 1 + __HC_HAS_POKEMON + __HC_HAS_BEN10 )) __HC_ROLL=$(( RANDOM % __HC_TOTAL )) - # Slot 0 is always car; the installed siblings fill slots 1..N-1 - # in the order pokemon, then ben10. if [ "$__HC_ROLL" -eq 0 ]; then __HC_TARGET="car" elif [ "$__HC_ROLL" -eq 1 ] && [ "$__HC_HAS_POKEMON" -eq 1 ]; then @@ -432,6 +411,8 @@ if [ "$__HC_MIX" = "true" ]; then fi fi +# Image-capable terminal detection. These four terminal families implement +# an inline image protocol; everything else falls through to chafa-ANSI. __HC_IMG_OK=0 case "${TERM:-}" in xterm-kitty*|xterm-ghostty*) __HC_IMG_OK=1 ;; esac [ -n "${KITTY_WINDOW_ID:-}" ] && __HC_IMG_OK=1 @@ -456,48 +437,57 @@ elif [ "$__HC_TARGET" = "ben10" ]; then ben10-colorscripts --random 2>/dev/null || ben10-colorscripts fi elif [ "$__HC_IMG_OK" -eq 1 ]; then - # Car branch — image path (Kitty/Ghostty/WezTerm/iTerm2) - __HC_IMG=$(ls "$__HC_DATA/assets/images/"*.png 2>/dev/null | __hc_pick) + # Car branch — image path. Explicitly pick fastfetch's --logo-type + # based on our own terminal detection. Fastfetch's --logo-type auto + # is unreliable on Darwin: on macOS Ghostty it silently picks + # `file-raw` (dumping PNG magic bytes to the terminal) even though + # Ghostty implements the kitty graphics protocol correctly. + # + # kitty-direct → Kitty, Ghostty, WezTerm (all implement kitty graphics) + # iterm → iTerm2 (its own inline image protocol) + __HC_LOGO_TYPE="kitty-direct" + [ "${TERM_PROGRAM:-}" = "iTerm.app" ] && __HC_LOGO_TYPE="iterm" + + __HC_IMG=$(find "$__HC_DATA/assets/images" -type f -name "*.png" 2>/dev/null | __hc_pick) if [ -n "$__HC_IMG" ]; then if command -v fastfetch >/dev/null 2>&1; then - fastfetch "${__HC_FF_ARGS[@]}" --logo-type @@HC_KITTY_TYPE@@ --logo-height 14 --logo-width 28 --logo "$__HC_IMG" + fastfetch "${__HC_FF_ARGS[@]}" --logo-type "$__HC_LOGO_TYPE" --logo-height 14 --logo-width 28 --logo "$__HC_IMG" elif command -v chafa >/dev/null 2>&1; then - chafa --size 60x20 "$__HC_IMG" + chafa --size 60x20 --colors 256 "$__HC_IMG" fi fi + unset __HC_LOGO_TYPE else - # Car branch — ANSI fallback - __HC_ANSI=$(ls "$__HC_DATA/assets/ansi/"*.txt 2>/dev/null | __hc_pick) - if [ -n "$__HC_ANSI" ]; then + # Car branch — non-image terminals (Apple Terminal, plain xterm, tmux + # without truecolor, etc.). Render on-the-fly with `chafa --colors 256` + # so we never emit truecolor escapes that these terminals can't display. + __HC_IMG=$(find "$__HC_DATA/assets/images" -type f -name "*.png" 2>/dev/null | __hc_pick) + if [ -n "$__HC_IMG" ] && command -v chafa >/dev/null 2>&1; then if command -v fastfetch >/dev/null 2>&1; then - cat "$__HC_ANSI" | fastfetch "${__HC_FF_ARGS[@]}" --logo-type file-raw --logo-height 25 --logo-width 80 --logo - + chafa --size 40x18 --format symbols --colors 256 "$__HC_IMG" | \ + fastfetch "${__HC_FF_ARGS[@]}" --logo-type file-raw --logo-width 40 --logo - else - cat "$__HC_ANSI" + chafa --size 40x18 --format symbols --colors 256 "$__HC_IMG" fi fi fi unset -f __hc_pick 2>/dev/null unset __HC_DATA __HC_CONF __HC_FF_CFG __HC_FF_ARGS __HC_MODE __HC_MIX \ __HC_TARGET __HC_HAS_POKEMON __HC_HAS_BEN10 __HC_TOTAL __HC_ROLL \ - __HC_IMG_OK __HC_IMG __HC_ANSI + __HC_IMG_OK __HC_IMG # <<< hypercar-colorscripts <<< HC_BLOCK_END - # Substitute the kitty logo type placeholder - sed -i.tmp "s|@@HC_KITTY_TYPE@@|${KITTY_LOGO_TYPE}|g" "$RC" - rm -f "$RC.tmp" - AFTER=$(fsize "$RC") [[ $AFTER -gt $BEFORE ]] || fail "$RC didn't grow" grep -q '# >>> hypercar-colorscripts >>>' "$RC" || fail "$RC missing marker" - grep -q '@@HC_KITTY_TYPE@@' "$RC" && fail "placeholder substitution failed in $RC" ok "Block appended ($((AFTER - BEFORE)) bytes)" done echo echo -e "${GREEN}═══ Done ═══${NC}" [[ $INCLUDE_VINTAGE -eq 1 ]] && echo "Installed: $TOTAL_COUNT cars (modern + vintage)" || echo "Installed: $MODERN_COUNT cars" -echo "Mode: $DEFAULT_MODE Mixing: $POKEMON_MIX fastfetch logo-type: $KITTY_LOGO_TYPE" +echo "Mode: $DEFAULT_MODE Mixing: $POKEMON_MIX" [[ $NO_FF_CONFIG -eq 0 ]] && echo "fastfetch styling: $FF_CONFIG_FILE" [[ $HAS_BEN10 -eq 1 ]] && echo "ben10-colorscripts: detected, included in mixing" echo