#!/usr/bin/env bash # Coder workspace first-run CLI setup wizard. # # Meant to be `source`d from a new interactive shell (e.g. via .bashrc). It asks, # once per user per workspace, whether to install and log into a few optional # AI coding CLIs. It re-runs on every new terminal until the user lets it finish # (or explicitly skips it for good), then gets out of the way. # # VS Code / code-server extensions are intentionally NOT asked about here - # they're installed declaratively by the Coder template itself (the # `code-server` module's `extensions` input, populated from the matching # profile-templates/*.code-profile file at template-push time). # # Manual re-run: bash /opt/coder/cli-setup-wizard.sh --force set -u WIZARD_DONE_FILE="${HOME}/.cache/coder-cli-wizard/done" FORCE=0 [ "${1:-}" = "--force" ] && FORCE=1 export BUN_INSTALL="${HOME}/.bun" export PATH="${BUN_INSTALL}/bin:${HOME}/.local/bin:${PATH}" # Only bother interactive shells with a real terminal attached, and only until # the user marks the wizard as done. if [ "$FORCE" -ne 1 ]; then case "$-" in *i*) : ;; *) return 0 2>/dev/null || exit 0 ;; esac [ -t 0 ] || { return 0 2>/dev/null || exit 0; } [ -f "$WIZARD_DONE_FILE" ] && { return 0 2>/dev/null || exit 0; } fi mkdir -p "$(dirname "$WIZARD_DONE_FILE")" ask_yes_no() { local prompt="$1" reply read -r -p "$prompt [y/N] " reply case "$reply" in [Yy]*) return 0 ;; *) return 1 ;; esac } echo "" echo "===================================================================" echo " Coder workspace setup wizard" echo " Runs once per new terminal until you finish it. Ctrl+C any time" echo " to skip for now - it'll ask again next terminal." echo "===================================================================" # --- GitHub Copilot CLI --- if command -v copilot >/dev/null 2>&1; then echo "GitHub Copilot CLI already installed, skipping." elif command -v bun >/dev/null 2>&1; then if ask_yes_no "Install GitHub Copilot CLI and log in?"; then if bun install -g @github/copilot; then copilot login || echo "Install succeeded but login didn't complete. Retry any time with: copilot login" else echo "Copilot CLI install failed. Retry later with: bun install -g @github/copilot && copilot login" fi fi else echo "Skipping GitHub Copilot CLI: bun not found on this workspace image." fi # --- Google Antigravity CLI (agy) --- if command -v agy >/dev/null 2>&1; then echo "Antigravity CLI already installed, skipping." else if ask_yes_no "Install Google Antigravity CLI (agy) and log in?"; then if curl -fsSL https://antigravity.google/cli/install.sh | bash; then echo "Launching 'agy' once to complete sign-in (exit with /logout or Ctrl+D when done)..." agy || echo "Sign-in didn't complete. Retry any time by running: agy" else echo "Antigravity CLI install failed. Retry later with: curl -fsSL https://antigravity.google/cli/install.sh | bash" fi fi fi # --- Claude Code CLI --- if command -v claude >/dev/null 2>&1; then echo "Claude Code CLI already installed, skipping." elif command -v bun >/dev/null 2>&1; then if ask_yes_no "Install Claude Code CLI and log in?"; then if bun install -g @anthropic-ai/claude-code; then echo "Launching 'claude' once to complete sign-in (use /login if not prompted; Ctrl+C to exit when done)..." claude || echo "Sign-in didn't complete. Retry any time by running: claude" else echo "Claude Code CLI install failed. Retry later with: bun install -g @anthropic-ai/claude-code" fi fi else echo "Skipping Claude Code CLI: bun not found on this workspace image." fi echo "" if ask_yes_no "Mark setup wizard as complete so it stops asking on new terminals?"; then touch "$WIZARD_DONE_FILE" echo "Done. Re-run any time with: bash /opt/coder/cli-setup-wizard.sh --force" else echo "OK, this'll ask again next time you open a terminal." fi return 0 2>/dev/null || exit 0