#!/usr/bin/env bash # charm-pack: deals the Charm library card that fits what you're building. # A concept by Claude for a Rainbrand example, built with Charm's Gum # (https://github.com/charmbracelet/gum). Not an official Charm tool. # Needs gum v2 and a truecolor terminal. set -euo pipefail # The card is built from pieces captured with $(...), where stdout isn't a # terminal; keep Gum's colors on anyway. export CLICOLOR_FORCE=1 VIOLET="#6B50FF" CREAM="#FFFDF5" PINK="#FF6DFF" MINT="#00FFB2" LIME="#ECFD65" GREY="#3A3A3A" INK="#222222" # need|name|stat label|stat value|stars|line from charm.land|reach for it when|module CARDS=( "A whole terminal app|Bubble Tea|Flavor|Taro|45.5k|Build terminal user interfaces from the future, today.|You're building a whole terminal app, from one screen to many.|charm.land/bubbletea/v2" "Ready-made pieces for a Bubble Tea app|Bubbles|Type|Tapioca|9.0k|The Bubble Tea component toolkit.|You need a spinner, text input, table, list or progress bar inside Bubble Tea.|charm.land/bubbles/v2" "Colors, borders and layout|Lip Gloss|Glossiness|Very|12.0k|Your terminal style and layout toolkit.|You want colors, borders and layout without hand-writing escape codes.|charm.land/lipgloss/v2" "A form or a prompt|Huh|Huh?|What?|7.2k|Simple, powerful forms in the terminal.|You need inputs, selects or a yes/no. Runs alone or inside Bubble Tea.|charm.land/huh/v2" "Markdown that looks good in a terminal|Glamour|Build|Fashionable|3.7k|The stylesheet-driven markdown renderer.|Your CLI has Markdown to show, and it deserves better than raw asterisks.|charm.land/glamour/v2" "An app people open with ssh|Wish|Magical|Yes|5.6k|Make SSH apps, just like that!|You want people to open your app with plain ssh. No certificates to wrangle.|charm.land/wish/v2" "Logs people can actually read|Log|Hot|Totally|3.4k|This is fine. A happy, powerful little logger.|You want leveled, colorful logs people can read: text, JSON or logfmt.|charm.land/log/v2" "Something that springs into place|Harmonica|Smooth|Very|1.6k|A physics-based animation toolkit.|Something should spring into place instead of teleporting.|github.com/charmbracelet/harmonica" ) field() { cut -d'|' -f"$2" <<<"$1"; } needs=() for card in "${CARDS[@]}"; do needs+=("$(field "$card" 1)"); done gum join --horizontal \ "$(gum style --foreground "$CREAM" --background "$VIOLET" --bold --padding "0 2" "charm_ library pack")" \ "$(gum style --foreground "$CREAM" --faint --padding "0 2" "a concept deck, not an official Charm tool")" echo need=$(gum choose \ --header "What are you building?" \ --header.foreground "$PINK" \ --cursor "> " --cursor.foreground "$MINT" \ --item.foreground "$CREAM" \ --selected.foreground "$MINT" \ "${needs[@]}") gum spin --spinner dot --spinner.foreground "$PINK" --title "Shuffling the deck..." --title.foreground "$CREAM" -- sleep 1.4 W=52 # inner card width, in cells # A row of the card: every cell gets the cream background, so no styled # segment can leave a hole in it. cream() { gum style --background "$CREAM" --width "$W" "$@"; } pad() { gum style --background "$CREAM" "$(printf '%*s' "$1" '')"; } for card in "${CARDS[@]}"; do [[ "$(field "$card" 1)" == "$need" ]] || continue name=$(field "$card" 2); label=$(field "$card" 3); value=$(field "$card" 4) stars=$(field "$card" 5); line=$(field "$card" 6); when=$(field "$card" 7); module=$(field "$card" 8) title_text=" $name " title=$(gum join --horizontal \ "$(gum style --foreground "$CREAM" --background "$VIOLET" --bold "$title_text")" \ "$(pad $((W - ${#title_text})))") badge_text=" * $stars $label $value " # ASCII stand-in for ✦, so byte and cell counts agree in any locale badges=$(gum join --horizontal \ "$(gum style --foreground "$LIME" --background "$GREY" " ✦ ")" \ "$(gum style --foreground "$CREAM" --background "$PINK" --bold " $stars ")" \ "$(pad 2)" \ "$(gum style --foreground "$CREAM" --background "$GREY" " $label ")" \ "$(gum style --foreground "$CREAM" --background "$PINK" --bold " $value ")" \ "$(pad $((W - ${#badge_text})))") blurb=$(cream --foreground "$VIOLET" "$line") label_when=$(cream --foreground "$VIOLET" "REACH FOR IT WHEN") reach=$(cream --foreground "$GREY" "$when") install_text=" \$ go get $module " install=$(gum join --horizontal \ "$(gum style --foreground "$PINK" --background "$INK" " \$ ")" \ "$(gum style --foreground "$CREAM" --background "$INK" "go get ")" \ "$(gum style --foreground "$MINT" --background "$INK" "$module ")" \ "$(pad $((W - ${#install_text})))") gap=$(cream " ") gum style --border rounded --border-foreground "$PINK" --background "$CREAM" --padding "1 3" --margin "1 0 0 0" \ "$(gum join --vertical "$title" "$gap" "$badges" "$gap" "$blurb" "$gap" "$label_when" "$reach" "$gap" "$install")" done echo gum style --foreground "$PINK" "Found your card? go get it."