templates/template.sh
templates/template.shBrowse 2 files
2,364 tokens
8,582 bytes
Token encoding: o200k_base
Snapshot 24fd22b
← Back to SKILL.md
1#!/usr/bin/env bash2#3# A wizard walks a human through a manual procedure, step by step.4# Generated by the setup-wizard-generator skill.5#6# Everything above the "STAGES" marker is the wizard library: do not hand-edit7# it. Author the per-step stages below the marker.8 9set -euo pipefail10 11# ──────────────────────────────────────────────────────────────────────────12# Wizard library: delightful, consistent UX, identical across every wizard.13# ──────────────────────────────────────────────────────────────────────────14 15if [[ -t 1 ]] && command -v tput >/dev/null 2>&1 && [[ "$(tput colors 2>/dev/null || echo 0)" -ge 8 ]]; then16 BOLD=$(tput bold); DIM=$(tput dim); RESET=$(tput sgr0)17 BLUE=$(tput setaf 4); GREEN=$(tput setaf 2); YELLOW=$(tput setaf 3); RED=$(tput setaf 1)18else19 BOLD=""; DIM=""; RESET=""; BLUE=""; GREEN=""; YELLOW=""; RED=""20fi21 22# Author sets this at the top of the stages section.23TOTAL_STAGES=024 25_STAGE_INDEX=026ENV_FILE="${ENV_FILE:-.env}"27WRITTEN_ENV=() # KEYs written to ENV_FILE this run28WRITTEN_SECRET=() # secret NAMEs set this run29SKIPPED=() # things we couldn't do (e.g. gh missing)30 31# _clear wipes the terminal so only the current step is on screen. No-op when32# output isn't a terminal, so piped logs stay readable.33_clear() {34 [[ -t 1 ]] || return 035 if command -v tput >/dev/null 2>&1; then tput clear; else printf '\033[2J\033[3J\033[H'; fi36}37 38# banner "Title" shows the opening frame: what this wizard does.39banner() {40 _clear41 printf '\n%s%s %s%s\n' "$BOLD" "$BLUE" "$1" "$RESET"42 printf '%s %s stages%s\n\n' "$DIM" "$TOTAL_STAGES" "$RESET"43 printf '%s You drive the browser; this wizard tells you exactly what to do and\n' "$DIM"44 printf ' captures the values you copy back. Stop any time with Ctrl-C and re-run\n'45 printf ' later, since it remembers values already saved.%s\n' "$RESET"46 pause "Ready to start?"47}48 49# stage "Name" clears the screen, then announces a stage and shows progress.50# Clearing keeps only the current step on screen.51stage() {52 _clear53 _STAGE_INDEX=$((_STAGE_INDEX + 1))54 printf '\n%s%s▸ Stage %s/%s · %s%s\n' \55 "$BOLD" "$BLUE" "$_STAGE_INDEX" "$TOTAL_STAGES" "$1" "$RESET"56}57 58# say "..." prints a plain instruction line.59say() { printf ' %s\n' "$1"; }60# step "..." is a numbered-feeling action the human takes in the browser.61step() { printf ' %s•%s %s\n' "$BLUE" "$RESET" "$1"; }62note() { printf ' %s%s%s\n' "$DIM" "$1" "$RESET"; }63warn() { printf ' %s⚠ %s%s\n' "$YELLOW" "$1" "$RESET"; }64 65# open_url URL opens it in the human's browser, cross-platform incl. WSL.66open_url() {67 local url="$1"68 printf ' %s↗ opening%s %s\n' "$GREEN" "$RESET" "$url"69 { if command -v wslview >/dev/null 2>&1; then wslview "$url"70 elif command -v explorer.exe >/dev/null 2>&1; then explorer.exe "$url"71 elif command -v xdg-open >/dev/null 2>&1; then xdg-open "$url"72 elif command -v open >/dev/null 2>&1; then open "$url"73 else warn "couldn't open a browser; visit it manually: $url"; fi74 } >/dev/null 2>&1 || warn "couldn't open a browser, so visit it manually: $url"75}76 77# pause "msg" waits for the human to confirm they've done the manual part.78pause() {79 printf ' %s%s%s ' "$DIM" "${1:-Press Enter to continue}" "$RESET"80 read -r _ || true81}82 83# confirm "question" is a y/N gate; returns success on yes.84confirm() {85 local reply=""86 printf ' %s? %s [y/N] ' "$YELLOW" "$1"87 read -r reply || true88 [[ "$reply" =~ ^[Yy] ]]89}90 91# _existing KEY: current value of KEY in ENV_FILE, if any.92_existing() {93 [[ -f "$ENV_FILE" ]] || return 194 local line; line=$(grep -E "^${1}=" "$ENV_FILE" | tail -n1) || return 195 printf '%s' "${line#*=}"96}97 98# ask KEY "Prompt" reads a value into $KEY. Offers the existing .env value as99# a default on re-runs (Enter keeps it). Visible input (non-secret).100ask() {101 local key="$1" prompt="$2" current input102 current=$(_existing "$key" || true)103 if [[ -n "$current" ]]; then104 printf ' %s%s%s %s[Enter keeps current]%s ' "$BOLD" "$prompt" "$RESET" "$DIM" "$RESET"105 else106 printf ' %s%s%s ' "$BOLD" "$prompt" "$RESET"107 fi108 read -r input || true109 [[ -z "$input" && -n "$current" ]] && input="$current"110 printf -v "$key" '%s' "$input"111}112 113# ask_secret KEY "Prompt" is like ask, but input is hidden.114ask_secret() {115 local key="$1" prompt="$2" current input116 current=$(_existing "$key" || true)117 if [[ -n "$current" ]]; then118 printf ' %s%s%s %s[Enter keeps current]%s ' "$BOLD" "$prompt" "$RESET" "$DIM" "$RESET"119 else120 printf ' %s%s%s ' "$BOLD" "$prompt" "$RESET"121 fi122 read -rs input || true123 printf '\n'124 [[ -z "$input" && -n "$current" ]] && input="$current"125 printf -v "$key" '%s' "$input"126}127 128# write_env KEY VALUE upserts KEY=VALUE into ENV_FILE (creates it; replaces129# any existing line). Idempotent.130write_env() {131 local key="$1" value="$2" tmp132 touch "$ENV_FILE"133 tmp=$(mktemp)134 grep -vE "^${key}=" "$ENV_FILE" > "$tmp" || true135 printf '%s=%s\n' "$key" "$value" >> "$tmp"136 mv "$tmp" "$ENV_FILE"137 WRITTEN_ENV+=("$key")138 printf ' %s✓ wrote%s %s → %s\n' "$GREEN" "$RESET" "$key" "$ENV_FILE"139}140 141# set_secret NAME VALUE sets a GitHub Actions repo secret via gh. Falls back142# to a warning (and records it) if gh is unavailable or unauthenticated.143set_secret() {144 local name="$1" value="$2"145 if command -v gh >/dev/null 2>&1 && gh auth status >/dev/null 2>&1; then146 if printf '%s' "$value" | gh secret set "$name" >/dev/null 2>&1; then147 WRITTEN_SECRET+=("$name")148 printf ' %s✓ set%s GitHub secret %s\n' "$GREEN" "$RESET" "$name"149 return150 fi151 fi152 SKIPPED+=("GitHub secret $name (set it manually: gh secret set $name)")153 warn "skipped GitHub secret $name: gh not ready; set it later"154}155 156# set_var NAME VALUE sets a GitHub Actions repo variable (non-secret).157set_var() {158 local name="$1" value="$2"159 if command -v gh >/dev/null 2>&1 && gh auth status >/dev/null 2>&1; then160 if gh variable set "$name" --body "$value" >/dev/null 2>&1; then161 printf ' %s✓ set%s GitHub variable %s\n' "$GREEN" "$RESET" "$name"162 return163 fi164 fi165 SKIPPED+=("GitHub variable $name")166 warn "skipped GitHub variable $name, gh not ready; set it later"167}168 169# finish clears, then shows a closing summary of everything configured.170finish() {171 _clear172 printf '\n%s%s ✓ Setup complete%s\n' "$BOLD" "$GREEN" "$RESET"173 (( ${#WRITTEN_ENV[@]} )) && note "wrote ${#WRITTEN_ENV[@]} value(s) to $ENV_FILE: ${WRITTEN_ENV[*]}"174 (( ${#WRITTEN_SECRET[@]} )) && note "set ${#WRITTEN_SECRET[@]} GitHub secret(s): ${WRITTEN_SECRET[*]}"175 if (( ${#SKIPPED[@]} )); then176 printf '\n'; warn "still to do by hand:"177 for s in "${SKIPPED[@]}"; do note " - $s"; done178 fi179 printf '\n'180}181 182# ──────────────────────────────────────────────────────────────────────────183# STAGES: author this section. One stage() per step the human takes.184# Replace the example below. Set TOTAL_STAGES to match the stages you write.185# ──────────────────────────────────────────────────────────────────────────186 187TOTAL_STAGES=1188 189banner "Stripe setup"190 191# ── Example stage: replace with your real steps ───────────────────────────192stage "Stripe: API keys"193say "We'll grab your Stripe test keys and store them for local dev + CI."194open_url "https://dashboard.stripe.com/test/apikeys"195step "On the API keys page, copy the Publishable key (starts pk_test_)."196ask STRIPE_PUBLISHABLE_KEY "Paste the publishable key:"197step "Click 'Reveal test key' on the Secret key row, then copy it."198ask_secret STRIPE_SECRET_KEY "Paste the secret key:"199write_env STRIPE_PUBLISHABLE_KEY "$STRIPE_PUBLISHABLE_KEY"200write_env STRIPE_SECRET_KEY "$STRIPE_SECRET_KEY"201set_secret STRIPE_SECRET_KEY "$STRIPE_SECRET_KEY" # CI needs this one202# ──────────────────────────────────────────────────────────────────────────203 204finish205 Referenced from SKILL.md
SKILL.mdView in source ↗
Source excerpt starting at line 36.SKILL.mdView in source ↗36- `bash`; `gh` CLI only if stages write GitHub secrets/variables37- The library template: `templates/template.sh` in this skill's directory
Source excerpt starting at line 68.68Copy `templates/template.sh` (from this skill's directory) to the target69path. Replace the example stage with one `stage` per step, in dependency