#!/bin/sh # Canon Protocol installer # Usage: curl -fsSL get.canonprotocol.org | sh set -eu REPO="canon-ai-protocol/canon-protocol" BINARY="canon" INSTALL_DIR="${CANON_INSTALL_DIR:-$HOME/.local/bin}" main() { detect_platform fetch_latest_tag download_and_verify install_binary print_success } detect_platform() { OS="$(uname -s)" ARCH="$(uname -m)" case "$OS" in Darwin) OS_TARGET="apple-darwin" ;; Linux) OS_TARGET="unknown-linux-gnu" ;; *) echo "Error: unsupported OS: $OS" >&2 exit 1 ;; esac case "$ARCH" in x86_64|amd64) ARCH_TARGET="x86_64" ;; arm64|aarch64) ARCH_TARGET="aarch64" ;; *) echo "Error: unsupported architecture: $ARCH" >&2 exit 1 ;; esac TARGET="${ARCH_TARGET}-${OS_TARGET}" ARTIFACT="${BINARY}-${TARGET}" echo "Detected platform: ${TARGET}" } fetch_latest_tag() { echo "Fetching latest release..." TAG=$(curl -fsSL "https://api.github.com/repos/${REPO}/releases/latest" \ | grep '"tag_name"' | head -1 | sed 's/.*"tag_name": *"//;s/".*//') if [ -z "$TAG" ]; then echo "Error: could not determine latest release tag" >&2 exit 1 fi echo "Latest release: ${TAG}" DOWNLOAD_BASE="https://github.com/${REPO}/releases/download/${TAG}" } download_and_verify() { TMPDIR=$(mktemp -d) trap 'rm -rf "$TMPDIR"' EXIT echo "Downloading ${ARTIFACT}..." curl -fsSL -o "${TMPDIR}/${ARTIFACT}" "${DOWNLOAD_BASE}/${ARTIFACT}" echo "Downloading checksums..." curl -fsSL -o "${TMPDIR}/checksums.txt" "${DOWNLOAD_BASE}/checksums.txt" echo "Verifying checksum..." EXPECTED=$(grep "${ARTIFACT}$" "${TMPDIR}/checksums.txt" | awk '{print $1}') if [ -z "$EXPECTED" ]; then echo "Error: checksum not found for ${ARTIFACT}" >&2 exit 1 fi if command -v sha256sum >/dev/null 2>&1; then ACTUAL=$(sha256sum "${TMPDIR}/${ARTIFACT}" | awk '{print $1}') elif command -v shasum >/dev/null 2>&1; then ACTUAL=$(shasum -a 256 "${TMPDIR}/${ARTIFACT}" | awk '{print $1}') else echo "Warning: no sha256sum or shasum found, skipping verification" >&2 return fi if [ "$EXPECTED" != "$ACTUAL" ]; then echo "Error: checksum mismatch" >&2 echo " expected: ${EXPECTED}" >&2 echo " actual: ${ACTUAL}" >&2 exit 1 fi echo "Checksum verified." } install_binary() { mkdir -p "$INSTALL_DIR" mv "${TMPDIR}/${ARTIFACT}" "${INSTALL_DIR}/${BINARY}" chmod +x "${INSTALL_DIR}/${BINARY}" echo "Installed to ${INSTALL_DIR}/${BINARY}" } print_success() { case ":${PATH}:" in *":${INSTALL_DIR}:"*) ;; *) echo "" echo "Add ${INSTALL_DIR} to your PATH:" echo " export PATH=\"${INSTALL_DIR}:\$PATH\"" echo "" echo "To make it permanent, add that line to your ~/.bashrc or ~/.zshrc" ;; esac echo "" echo "Run 'canon' to get started." } main