#!/bin/bash set -e main() { # When run via "curl | bash", stdin is the script content, not the terminal. # Reopen stdin from /dev/tty so interactive prompts (sudo, Homebrew) work. if [ ! -t 0 ] && [ -e /dev/tty ]; then exec < /dev/tty || true fi echo "========================================" echo " OpenBoot - Custom Install" echo " Config: @fullstackjam/jam-s-packages" echo "========================================" echo "" TMPDIR="${TMPDIR:-/tmp}" OPENBOOT_BIN="$TMPDIR/openboot-$$" trap 'rm -f "$OPENBOOT_BIN"' EXIT install_xcode_clt() { if xcode-select -p &>/dev/null; then return 0 fi echo "Installing Xcode Command Line Tools..." echo "(A dialog may appear - please click 'Install')" echo "" xcode-select --install 2>/dev/null || true echo "Waiting for Xcode Command Line Tools installation..." until xcode-select -p &>/dev/null; do sleep 5 done echo "Xcode Command Line Tools installed!" echo "" } install_homebrew() { if command -v brew &>/dev/null; then return 0 fi echo "Installing Homebrew..." echo "" /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" if [ "$(uname -m)" = "arm64" ]; then eval "$(/opt/homebrew/bin/brew shellenv)" else eval "$(/usr/local/bin/brew shellenv)" fi echo "Homebrew installed!" echo "" } install_xcode_clt install_homebrew ARCH="$(uname -m)" if [ "$ARCH" = "arm64" ]; then ARCH="arm64" else ARCH="amd64" fi OPENBOOT_URL="https://github.com/openbootdotdev/openboot/releases/latest/download/openboot-darwin-${ARCH}" echo "Downloading OpenBoot..." curl -fsSL "$OPENBOOT_URL" -o "$OPENBOOT_BIN" chmod +x "$OPENBOOT_BIN" echo "Using remote config: @fullstackjam/jam-s-packages" "$OPENBOOT_BIN" --user "fullstackjam/jam-s-packages" "$@" echo "" echo "=== Running Custom Post-Install Script ===" set +e CUSTOM_SCRIPT_B64="IyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiMgMS4gSW5zdGFsbCBPaC1NeS1ac2gKIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CmlmIFsgISAtZCAiJEhPTUUvLm9oLW15LXpzaCIgXTsgdGhlbgogIGVjaG8gIkluc3RhbGxpbmcgT2gtTXktWnNoLi4uIgogIHNoIC1jICIkKGN1cmwgLWZzU0wgaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL29obXl6c2gvb2hteXpzaC9tYXN0ZXIvdG9vbHMvaW5zdGFsbC5zaCkiICIiIC0tdW5hdHRlbmRlZApmaQoKIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiMgMi4gSW5zdGFsbCB6c2ggcGx1Z2lucwojID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KWlNIX0NVU1RPTT0iJHtaU0hfQ1VTVE9NOi0kSE9NRS8ub2gtbXktenNoL2N1c3RvbX0iClBMVUdJTlNfRElSPSIkWlNIX0NVU1RPTS9wbHVnaW5zIgpta2RpciAtcCAiJFBMVUdJTlNfRElSIgoKaW5zdGFsbF9wbHVnaW4oKSB7CiAgbG9jYWwgbmFtZT0iJDEiIHJlcG89IiQyIgogIFsgISAtZCAiJFBMVUdJTlNfRElSLyRuYW1lIiBdICYmIGdpdCBjbG9uZSAtLWRlcHRoPTEgIiRyZXBvIiAiJFBMVUdJTlNfRElSLyRuYW1lIgp9CgppbnN0YWxsX3BsdWdpbiAienNoLWF1dG9zdWdnZXN0aW9ucyIgImh0dHBzOi8vZ2l0aHViLmNvbS96c2gtdXNlcnMvenNoLWF1dG9zdWdnZXN0aW9ucyIKaW5zdGFsbF9wbHVnaW4gInpzaC1zeW50YXgtaGlnaGxpZ2h0aW5nIiAiaHR0cHM6Ly9naXRodWIuY29tL3pzaC11c2Vycy96c2gtc3ludGF4LWhpZ2hsaWdodGluZyIKCiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQojIDMuIENvbmZpZ3VyZSBtYWNPUyBwcmVmZXJlbmNlcwojID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KZWNobyAiQ29uZmlndXJpbmcgbWFjT1MgcHJlZmVyZW5jZXMuLi4iCgojIERvY2sKZGVmYXVsdHMgd3JpdGUgY29tLmFwcGxlLmRvY2sgYXV0b2hpZGUgLWJvb2wgZmFsc2UKZGVmYXVsdHMgd3JpdGUgY29tLmFwcGxlLmRvY2sgYXV0b2hpZGUtZGVsYXkgLWZsb2F0IDAKZGVmYXVsdHMgd3JpdGUgY29tLmFwcGxlLmRvY2sgc2hvdy1yZWNlbnRzIC1ib29sIGZhbHNlCmRlZmF1bHRzIHdyaXRlIGNvbS5hcHBsZS5kb2NrIHRpbGVzaXplIC1pbnQgMzgKZGVmYXVsdHMgZGVsZXRlIGNvbS5hcHBsZS5kb2NrIHBlcnNpc3RlbnQtYXBwcyAyPi9kZXYvbnVsbCB8fCB0cnVlCgpET0NLX0FQUFM9KAogICIvQXBwbGljYXRpb25zL0dvb2dsZSBDaHJvbWUuYXBwIgogICIvQXBwbGljYXRpb25zL1Zpc3VhbCBTdHVkaW8gQ29kZS5hcHAiCiAgIi9BcHBsaWNhdGlvbnMvS2FrdS5hcHAiCikKCmZvciBhcHAgaW4gIiR7RE9DS19BUFBTW0BdfSI7IGRvCiAgaWYgWyAtZCAiJGFwcCIgXTsgdGhlbgogICAgZGVmYXVsdHMgd3JpdGUgY29tLmFwcGxlLmRvY2sgcGVyc2lzdGVudC1hcHBzIC1hcnJheS1hZGQgIjxkaWN0PjxrZXk+dGlsZS1kYXRhPC9rZXk+PGRpY3Q+PGtleT5maWxlLWRhdGE8L2tleT48ZGljdD48a2V5Pl9DRlVSTFN0cmluZzwva2V5PjxzdHJpbmc+JGFwcDwvc3RyaW5nPjxrZXk+X0NGVVJMU3RyaW5nVHlwZTwva2V5PjxpbnRlZ2VyPjA8L2ludGVnZXI+PC9kaWN0PjwvZGljdD48L2RpY3Q+IgogIGZpCmRvbmUKCiMgRGVza3RvcApkZWZhdWx0cyB3cml0ZSBjb20uYXBwbGUuV2luZG93TWFuYWdlciBFbmFibGVTdGFuZGFyZENsaWNrVG9TaG93RGVza3RvcCAtYm9vbCBmYWxzZQoKIyBNZW51IEJhciAtIFNvdW5kIGFsd2F5cyB2aXNpYmxlCmRlZmF1bHRzIHdyaXRlIGNvbS5hcHBsZS5jb250cm9sY2VudGVyICJOU1N0YXR1c0l0ZW0gVmlzaWJsZSBTb3VuZCIgLWJvb2wgdHJ1ZQpkZWZhdWx0cyAtY3VycmVudEhvc3Qgd3JpdGUgY29tLmFwcGxlLmNvbnRyb2xjZW50ZXIgU291bmQgLWludCAxOAoKIyBGaW5kZXIKZGVmYXVsdHMgd3JpdGUgY29tLmFwcGxlLmZpbmRlciBGWFByZWZlcnJlZFZpZXdTdHlsZSAtc3RyaW5nICJObHN2IgpkZWZhdWx0cyB3cml0ZSBjb20uYXBwbGUuZmluZGVyIE5ld1dpbmRvd1RhcmdldCAtc3RyaW5nICJQZkhtIgpkZWZhdWx0cyB3cml0ZSBjb20uYXBwbGUuZmluZGVyIEZYRGVmYXVsdFNlYXJjaFNjb3BlIC1zdHJpbmcgIlNDY2YiCgojIFRyYWNrcGFkIC0gdGFwIHRvIGNsaWNrCmRlZmF1bHRzIHdyaXRlIGNvbS5hcHBsZS5BcHBsZU11bHRpdG91Y2hUcmFja3BhZCBDbGlja2luZyAtYm9vbCB0cnVlCmRlZmF1bHRzIHdyaXRlIGNvbS5hcHBsZS5kcml2ZXIuQXBwbGVCbHVldG9vdGhNdWx0aXRvdWNoLnRyYWNrcGFkIENsaWNraW5nIC1ib29sIHRydWUKZGVmYXVsdHMgLWN1cnJlbnRIb3N0IHdyaXRlIE5TR2xvYmFsRG9tYWluIGNvbS5hcHBsZS5tb3VzZS50YXBCZWhhdmlvciAtaW50IDEKCiMgUmVzdGFydCBhZmZlY3RlZCBzZXJ2aWNlcwpraWxsYWxsIERvY2sKa2lsbGFsbCBDb250cm9sQ2VudGVyIDI+L2Rldi9udWxsIHx8IHRydWUKa2lsbGFsbCBGaW5kZXIKCnNsZWVwIDIKCiMgTG9naW4gaXRlbXMKb3Nhc2NyaXB0IDw8T1NBIDI+L2Rldi9udWxsIHx8IHRydWUKdGVsbCBhcHBsaWNhdGlvbiAiU3lzdGVtIEV2ZW50cyIKICBzZXQgYXBwcyB0byB7eyJTY3JvbGwgUmV2ZXJzZXIiLCAiL0FwcGxpY2F0aW9ucy9TY3JvbGwgUmV2ZXJzZXIuYXBwIn0sIHsiTWFjY3kiLCAiL0FwcGxpY2F0aW9ucy9NYWNjeS5hcHAifSwgeyJCZXR0ZXJEaXNwbGF5IiwgIi9BcHBsaWNhdGlvbnMvQmV0dGVyRGlzcGxheS5hcHAifX0KICByZXBlYXQgd2l0aCBhIGluIGFwcHMKICAgIHNldCBuIHRvIGl0ZW0gMSBvZiBhCiAgICBzZXQgcCB0byBpdGVtIDIgb2YgYQogICAgdHJ5CiAgICAgIGRlbGV0ZSBsb2dpbiBpdGVtIG4KICAgIGVuZCB0cnkKICAgIG1ha2UgbmV3IGxvZ2luIGl0ZW0gd2l0aCBwcm9wZXJ0aWVzIHtuYW1lOm4sIHBhdGg6cCwgaGlkZGVuOmZhbHNlfQogIGVuZCByZXBlYXQKZW5kIHRlbGwKT1NBCgplY2hvICJtYWNPUyBzZXR1cCBjb21wbGV0ZSEi" echo "$CUSTOM_SCRIPT_B64" | base64 -d | bash CUSTOM_SCRIPT_EXIT=$? set -e if [ $CUSTOM_SCRIPT_EXIT -ne 0 ]; then echo "" echo "⚠ Custom script exited with code $CUSTOM_SCRIPT_EXIT" echo " Installation will continue, but check script output above." fi echo "" echo "=== Setting up Dotfiles ===" DOTFILES_REPO="https://github.com/fullstackjam/dotfiles" DOTFILES_DIR="$HOME/.dotfiles" if [[ ! "$DOTFILES_REPO" =~ ^https:// ]]; then echo "Error: Invalid dotfiles repo URL (must use HTTPS)" exit 1 fi if [ -d "$DOTFILES_DIR" ]; then echo "Dotfiles directory already exists at $DOTFILES_DIR" echo "Pulling latest changes..." cd "$DOTFILES_DIR" && git pull else echo "Cloning dotfiles from $DOTFILES_REPO..." git clone "$DOTFILES_REPO" "$DOTFILES_DIR" fi cd "$DOTFILES_DIR" echo "Deploying dotfiles with stow..." rm -f "$HOME/.zshrc" "$HOME/.zshrc.pre-oh-my-zsh" for dir in */; do [ -d "$dir" ] && stow -v --target="$HOME" "${dir%/}" 2>/dev/null || true done echo "" echo "Installation complete!" } main "$@"