1e52c837c8
- Added native addon distribution and installation support to the CLI update mechanism, enabling platform-specific native modules to be downloaded and installed alongside the main binary. - Added platform validation in native addon loader to verify supported platforms (linux-x64, linux-arm64, darwin-x64, darwin-arm64, win32-x64) with helpful error messages for unsupported configurations. - Enhanced native addon loading error messages to provide platform-specific troubleshooting guidance for both npm/bun installations and local development environments. - Updated installation scripts (install.sh, install.ps1) to download and install native addon files alongside the main binary during CLI installation.
272 lines
6.8 KiB
Bash
Executable File
272 lines
6.8 KiB
Bash
Executable File
#!/bin/sh
|
|
set -e
|
|
|
|
# OMP Coding Agent Installer
|
|
# Usage: curl -fsSL https://raw.githubusercontent.com/can1357/oh-my-pi/main/scripts/install.sh | sh
|
|
#
|
|
# Options:
|
|
# --source Install via bun (installs bun if needed)
|
|
# --binary Always install prebuilt binary
|
|
# --ref <ref> Install specific tag/commit/branch
|
|
# -r <ref> Shorthand for --ref
|
|
|
|
REPO="can1357/oh-my-pi"
|
|
PACKAGE="@oh-my-pi/pi-coding-agent"
|
|
INSTALL_DIR="${OMP_INSTALL_DIR:-$HOME/.local/bin}"
|
|
MIN_BUN_VERSION="1.3.7"
|
|
|
|
# Parse arguments
|
|
MODE=""
|
|
REF=""
|
|
while [ $# -gt 0 ]; do
|
|
case "$1" in
|
|
--source)
|
|
MODE="source"
|
|
shift
|
|
;;
|
|
--binary)
|
|
MODE="binary"
|
|
shift
|
|
;;
|
|
--ref)
|
|
shift
|
|
if [ -z "$1" ]; then
|
|
echo "Missing value for --ref"
|
|
exit 1
|
|
fi
|
|
REF="$1"
|
|
shift
|
|
;;
|
|
--ref=*)
|
|
REF="${1#*=}"
|
|
if [ -z "$REF" ]; then
|
|
echo "Missing value for --ref"
|
|
exit 1
|
|
fi
|
|
shift
|
|
;;
|
|
-r)
|
|
shift
|
|
if [ -z "$1" ]; then
|
|
echo "Missing value for -r"
|
|
exit 1
|
|
fi
|
|
REF="$1"
|
|
shift
|
|
;;
|
|
*)
|
|
echo "Unknown option: $1"
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
|
|
# If a ref is provided, default to source install
|
|
if [ -n "$REF" ] && [ -z "$MODE" ]; then
|
|
MODE="source"
|
|
fi
|
|
|
|
# Check if bun is available
|
|
has_bun() {
|
|
command -v bun >/dev/null 2>&1
|
|
}
|
|
|
|
version_ge() {
|
|
current="$1"
|
|
minimum="$2"
|
|
|
|
IFS=. set -- $current
|
|
current_major=${1:-0}
|
|
current_minor=${2:-0}
|
|
current_patch=${3:-0}
|
|
|
|
IFS=. set -- $minimum
|
|
minimum_major=${1:-0}
|
|
minimum_minor=${2:-0}
|
|
minimum_patch=${3:-0}
|
|
|
|
if [ "$current_major" -ne "$minimum_major" ]; then
|
|
[ "$current_major" -gt "$minimum_major" ]
|
|
return $?
|
|
fi
|
|
|
|
if [ "$current_minor" -ne "$minimum_minor" ]; then
|
|
[ "$current_minor" -gt "$minimum_minor" ]
|
|
return $?
|
|
fi
|
|
|
|
[ "$current_patch" -ge "$minimum_patch" ]
|
|
}
|
|
|
|
require_bun_version() {
|
|
version_raw=$(bun --version 2>/dev/null || true)
|
|
if [ -z "$version_raw" ]; then
|
|
echo "Failed to read bun version"
|
|
exit 1
|
|
fi
|
|
|
|
version_clean=${version_raw%%-*}
|
|
if ! version_ge "$version_clean" "$MIN_BUN_VERSION"; then
|
|
echo "Bun ${MIN_BUN_VERSION} or newer is required. Current version: ${version_clean}"
|
|
echo "Upgrade Bun at https://bun.sh/docs/installation"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# Check if git is available
|
|
has_git() {
|
|
command -v git >/dev/null 2>&1
|
|
}
|
|
|
|
# Install bun
|
|
install_bun() {
|
|
echo "Installing bun..."
|
|
if command -v bash >/dev/null 2>&1; then
|
|
curl -fsSL https://bun.sh/install | bash
|
|
else
|
|
echo "bash not found; attempting install with sh..."
|
|
curl -fsSL https://bun.sh/install | sh
|
|
fi
|
|
export BUN_INSTALL="$HOME/.bun"
|
|
export PATH="$BUN_INSTALL/bin:$PATH"
|
|
require_bun_version
|
|
}
|
|
|
|
# Check if git-lfs is available
|
|
has_git_lfs() {
|
|
command -v git-lfs >/dev/null 2>&1
|
|
}
|
|
|
|
# Install via bun
|
|
install_via_bun() {
|
|
echo "Installing via bun..."
|
|
if [ -n "$REF" ]; then
|
|
if ! has_git; then
|
|
echo "git is required for --ref when installing from source"
|
|
exit 1
|
|
fi
|
|
|
|
TMP_DIR="$(mktemp -d)"
|
|
trap 'rm -rf "$TMP_DIR"' EXIT
|
|
|
|
if git clone --depth 1 --branch "$REF" "https://github.com/${REPO}.git" "$TMP_DIR" >/dev/null 2>&1; then
|
|
:
|
|
else
|
|
git clone "https://github.com/${REPO}.git" "$TMP_DIR"
|
|
(cd "$TMP_DIR" && git checkout "$REF")
|
|
fi
|
|
|
|
# Pull LFS files
|
|
if has_git_lfs; then
|
|
(cd "$TMP_DIR" && git lfs pull)
|
|
fi
|
|
|
|
if [ ! -d "$TMP_DIR/packages/coding-agent" ]; then
|
|
echo "Expected package at ${TMP_DIR}/packages/coding-agent"
|
|
exit 1
|
|
fi
|
|
|
|
bun install -g "$TMP_DIR/packages/coding-agent" || {
|
|
echo "Failed to install from source"
|
|
exit 1
|
|
}
|
|
else
|
|
bun install -g "$PACKAGE" || {
|
|
echo "Failed to install $PACKAGE"
|
|
exit 1
|
|
}
|
|
fi
|
|
echo ""
|
|
echo "✓ Installed omp via bun"
|
|
echo "Run 'omp' to get started!"
|
|
}
|
|
|
|
# Install binary from GitHub releases
|
|
install_binary() {
|
|
# Detect platform
|
|
OS="$(uname -s)"
|
|
ARCH="$(uname -m)"
|
|
|
|
case "$OS" in
|
|
Linux) PLATFORM="linux" ;;
|
|
Darwin) PLATFORM="darwin" ;;
|
|
*) echo "Unsupported OS: $OS"; exit 1 ;;
|
|
esac
|
|
|
|
case "$ARCH" in
|
|
x86_64|amd64) ARCH="x64" ;;
|
|
arm64|aarch64) ARCH="arm64" ;;
|
|
*) echo "Unsupported architecture: $ARCH"; exit 1 ;;
|
|
esac
|
|
|
|
BINARY="omp-${PLATFORM}-${ARCH}"
|
|
NATIVE_ADDON="pi_natives.${PLATFORM}-${ARCH}.node"
|
|
|
|
# Get release tag
|
|
if [ -n "$REF" ]; then
|
|
echo "Fetching release $REF..."
|
|
if RELEASE_JSON=$(curl -fsSL "https://api.github.com/repos/${REPO}/releases/tags/${REF}"); then
|
|
LATEST=$(echo "$RELEASE_JSON" | grep '"tag_name"' | sed -E 's/.*"([^"]+)".*/\1/')
|
|
else
|
|
echo "Release tag not found: $REF"
|
|
echo "For branch/commit installs, use --source with --ref."
|
|
exit 1
|
|
fi
|
|
else
|
|
echo "Fetching latest release..."
|
|
RELEASE_JSON=$(curl -fsSL "https://api.github.com/repos/${REPO}/releases/latest")
|
|
LATEST=$(echo "$RELEASE_JSON" | grep '"tag_name"' | sed -E 's/.*"([^"]+)".*/\1/')
|
|
fi
|
|
if [ -z "$LATEST" ]; then
|
|
echo "Failed to fetch release tag"
|
|
exit 1
|
|
fi
|
|
echo "Using version: $LATEST"
|
|
|
|
mkdir -p "$INSTALL_DIR"
|
|
|
|
# Download binary
|
|
BINARY_URL="https://github.com/${REPO}/releases/download/${LATEST}/${BINARY}"
|
|
echo "Downloading ${BINARY}..."
|
|
curl -fsSL "$BINARY_URL" -o "${INSTALL_DIR}/omp"
|
|
chmod +x "${INSTALL_DIR}/omp"
|
|
|
|
# Download native addon
|
|
NATIVE_URL="https://github.com/${REPO}/releases/download/${LATEST}/${NATIVE_ADDON}"
|
|
echo "Downloading ${NATIVE_ADDON}..."
|
|
curl -fsSL "$NATIVE_URL" -o "${INSTALL_DIR}/${NATIVE_ADDON}"
|
|
|
|
echo ""
|
|
echo "✓ Installed omp to ${INSTALL_DIR}/omp"
|
|
echo "✓ Installed native addon to ${INSTALL_DIR}/${NATIVE_ADDON}"
|
|
|
|
# Check if in PATH
|
|
case ":$PATH:" in
|
|
*":$INSTALL_DIR:"*) echo "Run 'omp' to get started!" ;;
|
|
*) echo "Add ${INSTALL_DIR} to your PATH, then run 'omp'" ;;
|
|
esac
|
|
}
|
|
|
|
# Main logic
|
|
case "$MODE" in
|
|
source)
|
|
if ! has_bun; then
|
|
install_bun
|
|
fi
|
|
require_bun_version
|
|
install_via_bun
|
|
;;
|
|
binary)
|
|
install_binary
|
|
;;
|
|
*)
|
|
# Default: use bun if available, otherwise binary
|
|
if has_bun; then
|
|
require_bun_version
|
|
install_via_bun
|
|
else
|
|
install_binary
|
|
fi
|
|
;;
|
|
esac
|