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