install.sh 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. #!/bin/sh
  2. # Roo Code CLI Installer
  3. # Usage: curl -fsSL https://raw.githubusercontent.com/RooCodeInc/Roo-Code/main/apps/cli/install.sh | sh
  4. #
  5. # Environment variables:
  6. # ROO_INSTALL_DIR - Installation directory (default: ~/.roo/cli)
  7. # ROO_BIN_DIR - Binary symlink directory (default: ~/.local/bin)
  8. # ROO_VERSION - Specific version to install (default: latest)
  9. set -e
  10. # Configuration
  11. INSTALL_DIR="${ROO_INSTALL_DIR:-$HOME/.roo/cli}"
  12. BIN_DIR="${ROO_BIN_DIR:-$HOME/.local/bin}"
  13. REPO="RooCodeInc/Roo-Code"
  14. MIN_NODE_VERSION=20
  15. # Color output (only if terminal supports it)
  16. if [ -t 1 ]; then
  17. RED='\033[0;31m'
  18. GREEN='\033[0;32m'
  19. YELLOW='\033[1;33m'
  20. BLUE='\033[0;34m'
  21. BOLD='\033[1m'
  22. NC='\033[0m'
  23. else
  24. RED=''
  25. GREEN=''
  26. YELLOW=''
  27. BLUE=''
  28. BOLD=''
  29. NC=''
  30. fi
  31. info() { printf "${GREEN}==>${NC} %s\n" "$1"; }
  32. warn() { printf "${YELLOW}Warning:${NC} %s\n" "$1"; }
  33. error() { printf "${RED}Error:${NC} %s\n" "$1" >&2; exit 1; }
  34. # Check Node.js version
  35. check_node() {
  36. if ! command -v node >/dev/null 2>&1; then
  37. error "Node.js is not installed. Please install Node.js $MIN_NODE_VERSION or higher.
  38. Install Node.js:
  39. - macOS: brew install node
  40. - Linux: https://nodejs.org/en/download/package-manager
  41. - Or use a version manager like fnm, nvm, or mise"
  42. fi
  43. NODE_VERSION=$(node -v | sed 's/v//' | cut -d. -f1)
  44. if [ "$NODE_VERSION" -lt "$MIN_NODE_VERSION" ]; then
  45. error "Node.js $MIN_NODE_VERSION+ required. Found: $(node -v)
  46. Please upgrade Node.js to version $MIN_NODE_VERSION or higher."
  47. fi
  48. info "Found Node.js $(node -v)"
  49. }
  50. # Detect OS and architecture
  51. detect_platform() {
  52. OS=$(uname -s | tr '[:upper:]' '[:lower:]')
  53. ARCH=$(uname -m)
  54. case "$OS" in
  55. darwin) OS="darwin" ;;
  56. linux) OS="linux" ;;
  57. mingw*|msys*|cygwin*)
  58. error "Windows is not supported by this installer. Please use WSL or install manually."
  59. ;;
  60. *) error "Unsupported OS: $OS" ;;
  61. esac
  62. case "$ARCH" in
  63. x86_64|amd64) ARCH="x64" ;;
  64. arm64|aarch64) ARCH="arm64" ;;
  65. *) error "Unsupported architecture: $ARCH" ;;
  66. esac
  67. PLATFORM="${OS}-${ARCH}"
  68. info "Detected platform: $PLATFORM"
  69. }
  70. # Get latest release version or use specified version
  71. get_version() {
  72. if [ -n "$ROO_VERSION" ]; then
  73. VERSION="$ROO_VERSION"
  74. info "Using specified version: $VERSION"
  75. return
  76. fi
  77. info "Fetching latest version..."
  78. # Try to get the latest cli release
  79. RELEASES_JSON=$(curl -fsSL "https://api.github.com/repos/$REPO/releases" 2>/dev/null) || {
  80. error "Failed to fetch releases from GitHub. Check your internet connection."
  81. }
  82. # Extract the latest cli-v* tag
  83. VERSION=$(echo "$RELEASES_JSON" |
  84. grep -o '"tag_name": "cli-v[^"]*"' |
  85. head -1 |
  86. sed 's/"tag_name": "cli-v//' |
  87. sed 's/"//')
  88. if [ -z "$VERSION" ]; then
  89. error "Could not find any CLI releases. The CLI may not have been released yet."
  90. fi
  91. info "Latest version: $VERSION"
  92. }
  93. # Download and extract
  94. download_and_install() {
  95. TARBALL="roo-cli-${PLATFORM}.tar.gz"
  96. URL="https://github.com/$REPO/releases/download/cli-v${VERSION}/${TARBALL}"
  97. info "Downloading from $URL..."
  98. # Create temp directory
  99. TMP_DIR=$(mktemp -d)
  100. trap "rm -rf $TMP_DIR" EXIT
  101. # Download with progress indicator
  102. HTTP_CODE=$(curl -fsSL -w "%{http_code}" "$URL" -o "$TMP_DIR/$TARBALL" 2>/dev/null) || {
  103. if [ "$HTTP_CODE" = "404" ]; then
  104. error "Release not found for platform $PLATFORM version $VERSION.
  105. Available at: https://github.com/$REPO/releases"
  106. fi
  107. error "Download failed. HTTP code: $HTTP_CODE"
  108. }
  109. # Verify we got something
  110. if [ ! -s "$TMP_DIR/$TARBALL" ]; then
  111. error "Downloaded file is empty. Please try again."
  112. fi
  113. # Remove old installation if exists
  114. if [ -d "$INSTALL_DIR" ]; then
  115. info "Removing previous installation..."
  116. rm -rf "$INSTALL_DIR"
  117. fi
  118. mkdir -p "$INSTALL_DIR"
  119. # Extract
  120. info "Extracting to $INSTALL_DIR..."
  121. tar -xzf "$TMP_DIR/$TARBALL" -C "$INSTALL_DIR" --strip-components=1 || {
  122. error "Failed to extract tarball. The download may be corrupted."
  123. }
  124. # Save ripgrep binary before npm install (npm install will overwrite node_modules)
  125. RIPGREP_BIN=""
  126. if [ -f "$INSTALL_DIR/node_modules/@vscode/ripgrep/bin/rg" ]; then
  127. RIPGREP_BIN="$TMP_DIR/rg"
  128. cp "$INSTALL_DIR/node_modules/@vscode/ripgrep/bin/rg" "$RIPGREP_BIN"
  129. fi
  130. # Install npm dependencies
  131. info "Installing dependencies..."
  132. cd "$INSTALL_DIR"
  133. npm install --production --silent 2>/dev/null || {
  134. warn "npm install failed, trying with --legacy-peer-deps..."
  135. npm install --production --legacy-peer-deps --silent 2>/dev/null || {
  136. error "Failed to install dependencies. Make sure npm is available."
  137. }
  138. }
  139. cd - > /dev/null
  140. # Restore ripgrep binary after npm install
  141. if [ -n "$RIPGREP_BIN" ] && [ -f "$RIPGREP_BIN" ]; then
  142. mkdir -p "$INSTALL_DIR/node_modules/@vscode/ripgrep/bin"
  143. cp "$RIPGREP_BIN" "$INSTALL_DIR/node_modules/@vscode/ripgrep/bin/rg"
  144. chmod +x "$INSTALL_DIR/node_modules/@vscode/ripgrep/bin/rg"
  145. fi
  146. # Make executable
  147. chmod +x "$INSTALL_DIR/bin/roo"
  148. # Also make ripgrep executable if it exists
  149. if [ -f "$INSTALL_DIR/bin/rg" ]; then
  150. chmod +x "$INSTALL_DIR/bin/rg"
  151. fi
  152. }
  153. # Create symlink in bin directory
  154. setup_bin() {
  155. mkdir -p "$BIN_DIR"
  156. # Remove old symlink if exists
  157. if [ -L "$BIN_DIR/roo" ] || [ -f "$BIN_DIR/roo" ]; then
  158. rm -f "$BIN_DIR/roo"
  159. fi
  160. ln -sf "$INSTALL_DIR/bin/roo" "$BIN_DIR/roo"
  161. info "Created symlink: $BIN_DIR/roo"
  162. }
  163. # Check if bin dir is in PATH and provide instructions
  164. check_path() {
  165. case ":$PATH:" in
  166. *":$BIN_DIR:"*)
  167. # Already in PATH
  168. return 0
  169. ;;
  170. esac
  171. warn "$BIN_DIR is not in your PATH"
  172. echo ""
  173. echo "Add this line to your shell profile:"
  174. echo ""
  175. # Detect shell and provide specific instructions
  176. SHELL_NAME=$(basename "$SHELL")
  177. case "$SHELL_NAME" in
  178. zsh)
  179. echo " echo 'export PATH=\"$BIN_DIR:\$PATH\"' >> ~/.zshrc"
  180. echo " source ~/.zshrc"
  181. ;;
  182. bash)
  183. if [ -f "$HOME/.bashrc" ]; then
  184. echo " echo 'export PATH=\"$BIN_DIR:\$PATH\"' >> ~/.bashrc"
  185. echo " source ~/.bashrc"
  186. else
  187. echo " echo 'export PATH=\"$BIN_DIR:\$PATH\"' >> ~/.bash_profile"
  188. echo " source ~/.bash_profile"
  189. fi
  190. ;;
  191. fish)
  192. echo " set -Ux fish_user_paths $BIN_DIR \$fish_user_paths"
  193. ;;
  194. *)
  195. echo " export PATH=\"$BIN_DIR:\$PATH\""
  196. ;;
  197. esac
  198. echo ""
  199. }
  200. # Verify installation
  201. verify_install() {
  202. if [ -x "$BIN_DIR/roo" ]; then
  203. info "Verifying installation..."
  204. # Just check if it runs without error
  205. "$BIN_DIR/roo" --version >/dev/null 2>&1 || true
  206. fi
  207. }
  208. # Print success message
  209. print_success() {
  210. echo ""
  211. printf "${GREEN}${BOLD}✓ Roo Code CLI installed successfully!${NC}\n"
  212. echo ""
  213. echo " Installation: $INSTALL_DIR"
  214. echo " Binary: $BIN_DIR/roo"
  215. echo " Version: $VERSION"
  216. echo ""
  217. echo " ${BOLD}Get started:${NC}"
  218. echo " roo --help"
  219. echo ""
  220. echo " ${BOLD}Example:${NC}"
  221. echo " export OPENROUTER_API_KEY=sk-or-v1-..."
  222. echo " roo \"What is this project?\" --workspace ~/my-project"
  223. echo ""
  224. }
  225. # Main
  226. main() {
  227. echo ""
  228. printf "${BLUE}${BOLD}"
  229. echo " ╭─────────────────────────────────╮"
  230. echo " │ Roo Code CLI Installer │"
  231. echo " ╰─────────────────────────────────╯"
  232. printf "${NC}"
  233. echo ""
  234. check_node
  235. detect_platform
  236. get_version
  237. download_and_install
  238. setup_bin
  239. check_path
  240. verify_install
  241. print_success
  242. }
  243. main "$@"