-
Notifications
You must be signed in to change notification settings - Fork 0
feat(onboarding): local-ai-setup one-liner loader + Claude desktop cask #53
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,167 @@ | ||
| #!/bin/bash | ||
| # local-ai-setup.sh — Retail Success AI bootstrap (public loader). | ||
| # | ||
| # Destined for abarrows/dotfiles: onboarding_bin/local-ai-setup.sh (branch: production). | ||
| # Run via: | ||
| # /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/abarrows/dotfiles/production/onboarding_bin/local-ai-setup.sh)" | ||
| # | ||
| # Thin by design: installs the apps and the Retail Success plugin, then hands | ||
| # off to the setup.sh that ships INSIDE the plugin (rides plugin autoUpdate). | ||
| # Standalone (curl-able): no repo-relative sourcing. Idempotent throughout. | ||
|
|
||
| set -u | ||
|
|
||
| BOLD=$(tput bold 2>/dev/null || true); RESET=$(tput sgr0 2>/dev/null || true) | ||
| step() { printf '\n%s==> %s%s\n' "$BOLD" "$*" "$RESET"; } | ||
| ok() { printf ' ✔ %s\n' "$*"; } | ||
| warn() { printf ' ⚠ %s\n' "$*" >&2; } | ||
| die() { printf '\n ✖ %s\n' "$*" >&2; exit 1; } | ||
|
|
||
| # =============================================================== 1. guards === | ||
| step "Checking this machine" | ||
|
|
||
| [ "$(uname -s)" = "Darwin" ] || die "macOS only. For other platforms, ask in the AI rollout channel." | ||
|
|
||
| [ "$(id -u)" -ne 0 ] || die "Don't run as root/sudo — Homebrew refuses root. Run as yourself; you'll be prompted when needed." | ||
|
|
||
| if ! groups | grep -qw admin; then | ||
| cat >&2 <<'TXT' | ||
|
|
||
| ✖ This account is not a macOS administrator, and installs need admin rights. | ||
| → Ask IT to grant temporary admin, or have an admin run this command for | ||
| you, then re-run it yourself (it's safe to run twice). | ||
| TXT | ||
| exit 1 | ||
| fi | ||
| ok "admin account" | ||
|
|
||
| ARCH=$(uname -m) | ||
| if [ "$(sysctl -n sysctl.proc_translated 2>/dev/null || echo 0)" = "1" ]; then ARCH="x86_64"; fi # Rosetta lies about arm64 | ||
| INTEL=0 | ||
| if [ "$ARCH" = "x86_64" ]; then | ||
| INTEL=1 | ||
| cat >&2 <<'TXT' | ||
|
|
||
| ⚠⚠ INTEL MAC DETECTED ⚠⚠ | ||
| The company setup targets Apple Silicon. Continuing best-effort: everything | ||
| should install, but Docker Desktop and local AI performance will be | ||
| noticeably worse. Flag your machine in the AI rollout channel for the | ||
| hardware refresh list. | ||
| TXT | ||
| else | ||
| ok "Apple Silicon" | ||
| fi | ||
|
|
||
| # Floor pinned from cask requirements at authoring time (Docker Desktop + Warp | ||
| # require ≥ 13; re-verify with `brew info --cask` when bumping). Override: | ||
| # RS_AI_SETUP_MIN_MACOS=12 ./local-ai-setup.sh | ||
| MIN_MACOS="${RS_AI_SETUP_MIN_MACOS:-13}" | ||
| MACOS_MAJOR=$(sw_vers -productVersion | cut -d. -f1) | ||
| [ "$MACOS_MAJOR" -ge "$MIN_MACOS" ] || die "macOS $MACOS_MAJOR too old (need ≥ $MIN_MACOS). Update via System Settings → General → Software Update, then re-run." | ||
| ok "macOS $(sw_vers -productVersion)" | ||
|
|
||
| curl -fsSL --max-time 10 -o /dev/null https://raw.githubusercontent.com \ | ||
| || die "Can't reach github. Check network/VPN and re-run." | ||
| ok "network reachable" | ||
|
|
||
| # ============================================================= 2. installs === | ||
| step "Xcode Command Line Tools" | ||
| if xcode-select -p >/dev/null 2>&1; then ok "already installed"; else | ||
| xcode-select --install 2>/dev/null || true | ||
| echo " Waiting for the CLT installer to finish (accept the dialog)…" | ||
| until xcode-select -p >/dev/null 2>&1; do sleep 10; done | ||
| ok "installed" | ||
| fi | ||
|
|
||
| step "Homebrew" | ||
| if ! command -v brew >/dev/null 2>&1; then | ||
| /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" || die "Homebrew install failed." | ||
| fi | ||
| # Put brew on PATH for this run (Apple Silicon vs Intel prefix). | ||
| if [ -x /opt/homebrew/bin/brew ]; then eval "$(/opt/homebrew/bin/brew shellenv)"; fi | ||
| if [ -x /usr/local/bin/brew ]; then eval "$(/usr/local/bin/brew shellenv)"; fi | ||
| command -v brew >/dev/null 2>&1 || die "brew not on PATH after install — open a new terminal and re-run." | ||
| ok "$(brew --version | head -1)" | ||
|
|
||
| step "Apps (only what's missing)" | ||
| brew_formula() { brew list --formula "$1" >/dev/null 2>&1 && ok "$1 (present)" || { brew install "$1" && ok "$1 installed" || warn "$1 failed to install"; }; } | ||
| brew_cask() { brew list --cask "$1" >/dev/null 2>&1 && ok "$1 (present)" || { brew install --cask "$1" && ok "$1 installed" || warn "$1 failed to install"; }; } | ||
| brew_formula gh | ||
| brew_cask claude # desktop app | ||
| brew_cask claude-code # CLI | ||
| brew_cask docker-desktop | ||
| brew_cask warp | ||
| brew_cask visual-studio-code | ||
|
|
||
| if command -v code >/dev/null 2>&1; then | ||
| if code --list-extensions 2>/dev/null | grep -qi '^anthropic.claude-code$'; then | ||
| ok "VS Code Claude extension (present)" | ||
| else | ||
| code --install-extension anthropic.claude-code >/dev/null 2>&1 && ok "VS Code Claude extension installed" || warn "VS Code extension install failed — install 'Claude Code' from the marketplace manually" | ||
| fi | ||
| else | ||
| warn "code CLI not on PATH — in VS Code run 'Shell Command: Install code in PATH', then re-run" | ||
| fi | ||
|
|
||
| # =============================================================== 3. gates ==== | ||
| step "GitHub auth" | ||
| if gh auth status >/dev/null 2>&1; then ok "gh authenticated"; else | ||
| echo " Opening GitHub login (choose HTTPS + browser)…" | ||
| gh auth login || die "GitHub auth is required for the private plugin repo. Re-run after 'gh auth login' succeeds." | ||
| fi | ||
|
|
||
| step "Docker Desktop + MCP Toolkit" | ||
| if ! docker info >/dev/null 2>&1; then | ||
| open -a Docker || die "Could not open Docker Desktop." | ||
| echo " Waiting for the Docker daemon (accept the first-run dialogs)…" | ||
| for _ in $(seq 1 60); do docker info >/dev/null 2>&1 && break; sleep 3; done | ||
| docker info >/dev/null 2>&1 || die "Docker daemon never came up. Finish Docker Desktop first-run setup, then re-run." | ||
| fi | ||
| ok "docker daemon running" | ||
| docker mcp --help >/dev/null 2>&1 || die "'docker mcp' unavailable — update Docker Desktop (≥ 4.42) / enable the MCP Toolkit, then re-run." | ||
| ok "MCP Toolkit available" | ||
|
|
||
| # ============================================================== 4. plugin ==== | ||
| step "Retail Success Claude plugin" | ||
| command -v claude >/dev/null 2>&1 || die "claude CLI missing after install — open a new terminal and re-run." | ||
| # CLAUDECODE='' : the plugin CLI refuses to run nested inside a Claude session. | ||
| CLAUDECODE='' claude plugin marketplace add Retail-Success/Wayroo.tools >/dev/null 2>&1 || true # idempotent: errors if present | ||
| if CLAUDECODE='' claude plugin install rs-agents@retailsuccess >/dev/null 2>&1; then | ||
| ok "rs-agents@retailsuccess" | ||
| elif CLAUDECODE='' claude plugin install rs-agents@wayroo >/dev/null 2>&1; then | ||
| ok "rs-agents@wayroo (fallback marketplace name)" | ||
| elif CLAUDECODE='' claude plugin list 2>/dev/null | grep -q 'rs-agents'; then | ||
| ok "rs-agents already installed" | ||
| else | ||
| die "Could not install the rs-agents plugin. Run 'claude plugin marketplace add Retail-Success/Wayroo.tools' then 'claude plugin install rs-agents@retailsuccess' manually." | ||
| fi | ||
|
|
||
| # ============================================================= 5. handoff ==== | ||
| step "Handing off to the plugin's setup.sh (MCP wiring + settings)" | ||
| # Name-agnostic glob over the plugin cache — layout varies across CLI versions. | ||
| SETUP_SH=$(ls -t "$HOME"/.claude/plugins/*/*/skills/local-ai-setup/setup.sh \ | ||
| "$HOME"/.claude/plugins/*/skills/local-ai-setup/setup.sh \ | ||
| 2>/dev/null | head -1) | ||
| if [ -n "${SETUP_SH:-}" ] && [ -f "$SETUP_SH" ]; then | ||
| ok "found $SETUP_SH" | ||
| bash "$SETUP_SH" || warn "setup.sh reported issues — see output above; re-run any time with: bash \"$SETUP_SH\"" | ||
| else | ||
| cat >&2 <<'TXT' | ||
| ⚠ Could not locate the plugin's setup.sh in ~/.claude/plugins. | ||
| Recovery: open a terminal, run `claude`, then type /local-ai-setup — | ||
| the skill will locate and run its own setup script. | ||
| TXT | ||
| fi | ||
|
|
||
| # ============================================================= 6. wrap-up ==== | ||
| step "Final check" | ||
| claude doctor || warn "claude doctor reported problems (see above)" | ||
| cat <<TXT | ||
|
|
||
| ── Done ────────────────────────────────────────────────────────────── | ||
| Installed/verified: Claude desktop, Claude Code (CLI + VS Code), Docker | ||
| Desktop (MCP Toolkit), Warp, VS Code, gh, rs-agents plugin. | ||
| Next: open Warp, cd into any repo, run: claude → then try /local-ai-setup | ||
| for the guided tour. Re-run this one-liner any time; it only fixes gaps. | ||
| $( [ "$INTEL" -eq 1 ] && echo " Reminder: Intel Mac — flag for hardware refresh." ) | ||
| TXT | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nitpick: The 10-second curl timeout may be too strict on slow or high-latency networks.
On some corporate or high-latency networks, connecting to GitHub can legitimately take longer than 10 seconds, causing this check to fail even when the network/VPN is fine. Consider increasing
--max-time(e.g., 30–60 seconds) or using--connect-timeoutinstead so only slow connections—not slow transfers—are treated as failures.