mirror of
https://github.com/OpenRouterTeam/spawn.git
synced 2026-04-30 12:59:32 +00:00
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>
130 lines
4.5 KiB
Bash
Executable file
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
|