/ install.sh
install.sh
  1  #!/usr/bin/env bash
  2  set -euo pipefail
  3  
  4  REPO="${SWARMCLAW_REPO:-swarmclawai/swarmclaw}"
  5  INSTALL_DIR="${SWARMCLAW_DIR:-$HOME/swarmclaw}"
  6  REQUESTED_VERSION="${SWARMCLAW_VERSION:-latest}"
  7  
  8  log() {
  9    printf '[install] %s\n' "$1"
 10  }
 11  
 12  fail() {
 13    printf '[install] ERROR: %s\n' "$1" >&2
 14    exit 1
 15  }
 16  
 17  need_cmd() {
 18    if ! command -v "$1" >/dev/null 2>&1; then
 19      fail "Required command not found: $1"
 20    fi
 21  }
 22  
 23  resolve_latest_release_tag() {
 24    local api_url="https://api.github.com/repos/${REPO}/releases/latest"
 25    local tag
 26  
 27    if command -v curl >/dev/null 2>&1; then
 28      tag="$(curl -fsSL "$api_url" | sed -n 's/.*"tag_name"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' | head -n1 || true)"
 29    else
 30      tag=""
 31    fi
 32  
 33    if [[ -z "$tag" ]]; then
 34      tag="$(git ls-remote --tags --sort='-v:refname' "https://github.com/${REPO}.git" 'v*' 2>/dev/null | awk -F'/' 'NR==1 { print $3 }')"
 35    fi
 36  
 37    printf '%s' "$tag"
 38  }
 39  
 40  checkout_target() {
 41    local target="$1"
 42  
 43    if [[ "$target" == "main" ]]; then
 44      git checkout main >/dev/null 2>&1 || git checkout -B main origin/main
 45      git pull --ff-only origin main
 46      return
 47    fi
 48  
 49    if ! [[ "$target" =~ ^v[0-9]+\.[0-9]+\.[0-9]+([-.+][0-9A-Za-z.-]+)?$ ]]; then
 50      fail "Resolved version is not a valid release tag: $target"
 51    fi
 52  
 53    git fetch --tags origin --quiet
 54    if ! git rev-parse "refs/tags/${target}" >/dev/null 2>&1; then
 55      fail "Release tag not found: ${target}"
 56    fi
 57    git checkout -B stable "refs/tags/${target}"
 58  }
 59  
 60  main() {
 61    need_cmd git
 62    need_cmd node
 63    need_cmd npm
 64    need_cmd sed
 65    need_cmd awk
 66  
 67    local target="$REQUESTED_VERSION"
 68    if [[ "$target" == "latest" ]]; then
 69      target="$(resolve_latest_release_tag)"
 70      if [[ -z "$target" ]]; then
 71        log "No stable release tag found yet. Falling back to main branch."
 72        target="main"
 73      fi
 74    fi
 75  
 76    log "Installing ${REPO} (${target}) into ${INSTALL_DIR}"
 77  
 78    if [[ -d "$INSTALL_DIR/.git" ]]; then
 79      log "Existing install detected; updating repository metadata."
 80      git -C "$INSTALL_DIR" remote set-url origin "https://github.com/${REPO}.git"
 81      git -C "$INSTALL_DIR" fetch --all --tags --prune --quiet
 82    else
 83      rm -rf "$INSTALL_DIR"
 84      git clone "https://github.com/${REPO}.git" "$INSTALL_DIR"
 85    fi
 86  
 87    cd "$INSTALL_DIR"
 88    checkout_target "$target"
 89  
 90    log "Installing dependencies"
 91    npm install
 92  
 93    log "Bootstrapping local environment"
 94    npm run setup:easy -- --skip-install
 95  
 96    log "Building SwarmClaw"
 97    npm run build
 98  
 99    cat <<EOF
100  
101  SwarmClaw installed successfully.
102  
103  Next steps:
104  1. cd "$INSTALL_DIR"
105  2. npm run dev
106  3. Open http://localhost:3456
107  
108  Production bundle is already built, so you can also run:
109  - npm run start
110  
111  For updates later:
112  - npm run update:easy
113  EOF
114  }
115  
116  main "$@"