spawn/cli/install.sh
Sprite 39ee858943 security: fix SC2064 trap quoting to prevent early variable expansion
Changed trap commands from double quotes to single quotes so variables
expand at trap execution time instead of definition time. This prevents
security issues where variables could be tampered with between trap
definition and execution.

Fixed 3 instances:
- cli/install.sh (2 instances): trap 'rm -rf "$tmpdir"' EXIT
- test/run.sh (1 instance): trap 'cleanup' EXIT

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-08 01:29:56 +00:00

130 lines
4.5 KiB
Bash
Executable file

#!/bin/bash
# Installer for the spawn CLI
#
# Usage:
# curl -fsSL https://raw.githubusercontent.com/OpenRouterTeam/spawn/main/cli/install.sh | bash
#
# This installs spawn via bun (preferred) or npm. If neither is available,
# it falls back to downloading the bundled JS file and creating a runner script.
#
# Override install directory (for fallback method):
# SPAWN_INSTALL_DIR=/usr/local/bin curl -fsSL ... | bash
set -eo pipefail
SPAWN_REPO="OpenRouterTeam/spawn"
SPAWN_RAW_BASE="https://raw.githubusercontent.com/$SPAWN_REPO/main"
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BOLD='\033[1m'
DIM='\033[2m'
NC='\033[0m'
log_info() { echo -e "${GREEN}[spawn]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[spawn]${NC} $1"; }
log_error() { echo -e "${RED}[spawn]${NC} $1"; }
# --- Method 1: bun install -g (preferred) ---
if command -v bun &>/dev/null; then
log_info "Installing spawn via bun..."
# Clone/download the cli directory and install from it
tmpdir=$(mktemp -d)
trap 'rm -rf "$tmpdir"' EXIT
log_info "Downloading CLI package..."
mkdir -p "$tmpdir/cli/src"
curl -fsSL "$SPAWN_RAW_BASE/cli/package.json" -o "$tmpdir/cli/package.json"
curl -fsSL "$SPAWN_RAW_BASE/cli/tsconfig.json" -o "$tmpdir/cli/tsconfig.json"
curl -fsSL "$SPAWN_RAW_BASE/cli/src/index.ts" -o "$tmpdir/cli/src/index.ts"
curl -fsSL "$SPAWN_RAW_BASE/cli/src/manifest.ts" -o "$tmpdir/cli/src/manifest.ts"
curl -fsSL "$SPAWN_RAW_BASE/cli/src/commands.ts" -o "$tmpdir/cli/src/commands.ts"
curl -fsSL "$SPAWN_RAW_BASE/cli/src/version.ts" -o "$tmpdir/cli/src/version.ts"
cd "$tmpdir/cli"
bun install
bun link 2>/dev/null || bun install -g . 2>/dev/null || {
# If global install fails, build and copy binary
log_warn "Global install failed, building binary..."
bun build src/index.ts --compile --outfile spawn
INSTALL_DIR="${SPAWN_INSTALL_DIR:-$HOME/.local/bin}"
mkdir -p "$INSTALL_DIR"
mv spawn "$INSTALL_DIR/spawn"
log_info "Installed spawn binary to $INSTALL_DIR/spawn"
}
log_info "spawn installed successfully!"
echo ""
if command -v spawn &>/dev/null; then
spawn version
echo ""
log_info "Run ${BOLD}spawn${NC}${GREEN} to get started${NC}"
fi
exit 0
fi
# --- Method 2: npm install -g ---
if command -v npm &>/dev/null && command -v node &>/dev/null; then
log_info "Installing spawn via npm..."
tmpdir=$(mktemp -d)
trap 'rm -rf "$tmpdir"' EXIT
log_info "Downloading CLI package..."
mkdir -p "$tmpdir/cli/src"
curl -fsSL "$SPAWN_RAW_BASE/cli/package.json" -o "$tmpdir/cli/package.json"
curl -fsSL "$SPAWN_RAW_BASE/cli/tsconfig.json" -o "$tmpdir/cli/tsconfig.json"
curl -fsSL "$SPAWN_RAW_BASE/cli/src/index.ts" -o "$tmpdir/cli/src/index.ts"
curl -fsSL "$SPAWN_RAW_BASE/cli/src/manifest.ts" -o "$tmpdir/cli/src/manifest.ts"
curl -fsSL "$SPAWN_RAW_BASE/cli/src/commands.ts" -o "$tmpdir/cli/src/commands.ts"
curl -fsSL "$SPAWN_RAW_BASE/cli/src/version.ts" -o "$tmpdir/cli/src/version.ts"
cd "$tmpdir/cli"
npm install
npm install -g . 2>/dev/null || {
log_warn "npm global install requires permissions. Try:"
echo ""
echo " sudo npm install -g ."
echo ""
exit 1
}
log_info "spawn installed successfully!"
echo ""
if command -v spawn &>/dev/null; then
spawn version
echo ""
log_info "Run ${BOLD}spawn${NC}${GREEN} to get started${NC}"
fi
exit 0
fi
# --- Method 3: Direct download fallback (bash wrapper) ---
log_warn "Neither bun nor npm found. Installing bash fallback..."
INSTALL_DIR="${SPAWN_INSTALL_DIR:-$HOME/.local/bin}"
mkdir -p "$INSTALL_DIR"
if ! curl -fsSL "$SPAWN_RAW_BASE/cli/spawn.sh" -o "$INSTALL_DIR/spawn"; then
log_error "Failed to download spawn CLI"
exit 1
fi
chmod +x "$INSTALL_DIR/spawn"
log_info "Installed spawn (bash) to $INSTALL_DIR/spawn"
# Check if install dir is in PATH
if ! echo "$PATH" | tr ':' '\n' | grep -qx "$INSTALL_DIR"; then
log_warn "$INSTALL_DIR is not in your PATH"
echo ""
echo "Add it by running one of:"
echo ""
case "${SHELL:-/bin/bash}" in
*/zsh) echo " echo 'export PATH=\"$INSTALL_DIR:\$PATH\"' >> ~/.zshrc && source ~/.zshrc" ;;
*/fish) echo " fish_add_path $INSTALL_DIR" ;;
*) echo " echo 'export PATH=\"$INSTALL_DIR:\$PATH\"' >> ~/.bashrc && source ~/.bashrc" ;;
esac
echo ""
else
log_info "Run ${BOLD}spawn${NC}${GREEN} to get started${NC}"
fi