chore: import upstream snapshot with attribution
This commit is contained in:
Executable
+220
@@ -0,0 +1,220 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# install.sh — One-line installer for codebase-memory-mcp.
|
||||
#
|
||||
# Usage:
|
||||
# curl -fsSL https://raw.githubusercontent.com/DeusData/codebase-memory-mcp/main/install.sh | bash
|
||||
# curl -fsSL ... | bash -s -- --ui # Install the UI variant
|
||||
# curl -fsSL ... | bash -s -- --dir /path # Custom install directory
|
||||
#
|
||||
# Environment:
|
||||
# CBM_DOWNLOAD_URL Override base URL for downloads (for testing)
|
||||
|
||||
# Wrap in main() to prevent partial execution from piped downloads.
|
||||
# If curl|bash is interrupted mid-transfer, bash would execute the partial
|
||||
# script. With this wrapper, the function is defined but main() is never
|
||||
# called because the final line hasn't arrived yet.
|
||||
main() {
|
||||
|
||||
REPO="DeusData/codebase-memory-mcp"
|
||||
INSTALL_DIR="$HOME/.local/bin"
|
||||
VARIANT="standard"
|
||||
SKIP_CONFIG=false
|
||||
CBM_DOWNLOAD_URL="${CBM_DOWNLOAD_URL:-https://github.com/${REPO}/releases/latest/download}"
|
||||
|
||||
# Security: reject non-HTTPS download URLs (defense-in-depth)
|
||||
case "$CBM_DOWNLOAD_URL" in
|
||||
https://*|http://localhost*|http://127.0.0.1*) ;;
|
||||
*) echo "error: refusing non-HTTPS download URL: $CBM_DOWNLOAD_URL" >&2; exit 1 ;;
|
||||
esac
|
||||
|
||||
for arg in "$@"; do
|
||||
case "$arg" in
|
||||
--ui) VARIANT="ui" ;;
|
||||
--standard) VARIANT="standard" ;;
|
||||
--dir=*) INSTALL_DIR="${arg#--dir=}" ;;
|
||||
--skip-config) SKIP_CONFIG=true ;;
|
||||
--help|-h)
|
||||
echo "Usage: install.sh [--ui] [--dir=<path>] [--skip-config]"
|
||||
echo " --ui Install the UI variant (with graph visualization)"
|
||||
echo " --standard Install the standard variant (default)"
|
||||
echo " --dir PATH Install directory (default: ~/.local/bin)"
|
||||
echo " --skip-config Skip automatic agent configuration"
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
done
|
||||
# Handle --dir <path> (space-separated)
|
||||
prev=""
|
||||
for arg in "$@"; do
|
||||
if [ "$prev" = "--dir" ]; then
|
||||
INSTALL_DIR="$arg"
|
||||
fi
|
||||
prev="$arg"
|
||||
done
|
||||
|
||||
detect_os() {
|
||||
case "$(uname -s)" in
|
||||
Darwin) echo "darwin" ;;
|
||||
Linux) echo "linux" ;;
|
||||
MINGW*|MSYS*|CYGWIN*) echo "windows" ;;
|
||||
*) echo "error: unsupported OS: $(uname -s)" >&2; exit 1 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
detect_arch() {
|
||||
local arch
|
||||
arch="$(uname -m)"
|
||||
case "$arch" in
|
||||
arm64|aarch64) echo "arm64" ;;
|
||||
x86_64|amd64)
|
||||
# Rosetta detection: shell reports x86_64 but hardware is Apple Silicon
|
||||
if [ "$(uname -s)" = "Darwin" ] && sysctl -n machdep.cpu.brand_string 2>/dev/null | grep -qi apple; then
|
||||
echo "arm64"
|
||||
else
|
||||
echo "amd64"
|
||||
fi
|
||||
;;
|
||||
*) echo "error: unsupported architecture: $arch" >&2; exit 1 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
OS=$(detect_os)
|
||||
ARCH=$(detect_arch)
|
||||
|
||||
echo "codebase-memory-mcp installer"
|
||||
echo " os: $OS"
|
||||
echo " arch: $ARCH"
|
||||
echo " variant: $VARIANT"
|
||||
echo " target: $INSTALL_DIR/codebase-memory-mcp"
|
||||
echo ""
|
||||
|
||||
# Build download URL
|
||||
if [ "$OS" = "windows" ]; then
|
||||
EXT="zip"
|
||||
else
|
||||
EXT="tar.gz"
|
||||
fi
|
||||
|
||||
# Linux ships a fully-static "-portable" build; the standard linux binary
|
||||
# dynamically links glibc 2.38+ and fails on older distros (Debian 11, RHEL 8,
|
||||
# Ubuntu 20.04). macOS/Windows have no such variant.
|
||||
PORTABLE=""
|
||||
[ "$OS" = "linux" ] && PORTABLE="-portable"
|
||||
|
||||
if [ "$VARIANT" = "ui" ]; then
|
||||
ARCHIVE="codebase-memory-mcp-ui-${OS}-${ARCH}${PORTABLE}.${EXT}"
|
||||
else
|
||||
ARCHIVE="codebase-memory-mcp-${OS}-${ARCH}${PORTABLE}.${EXT}"
|
||||
fi
|
||||
|
||||
URL="${CBM_DOWNLOAD_URL}/${ARCHIVE}"
|
||||
|
||||
# Download
|
||||
DLDIR=$(mktemp -d)
|
||||
trap 'rm -rf "$DLDIR"' EXIT
|
||||
|
||||
echo "Downloading ${ARCHIVE}..."
|
||||
if command -v curl &>/dev/null; then
|
||||
curl -fSL --progress-bar -o "$DLDIR/$ARCHIVE" "$URL"
|
||||
elif command -v wget &>/dev/null; then
|
||||
wget -q --show-progress -O "$DLDIR/$ARCHIVE" "$URL"
|
||||
else
|
||||
echo "error: curl or wget required" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Checksum verification
|
||||
CHECKSUM_URL="${CBM_DOWNLOAD_URL}/checksums.txt"
|
||||
if curl -fsSL -o "$DLDIR/checksums.txt" "$CHECKSUM_URL" 2>/dev/null; then
|
||||
EXPECTED=$(grep "$ARCHIVE" "$DLDIR/checksums.txt" | awk '{print $1}')
|
||||
if [ -n "$EXPECTED" ]; then
|
||||
if command -v sha256sum &>/dev/null; then
|
||||
ACTUAL=$(sha256sum "$DLDIR/$ARCHIVE" | awk '{print $1}')
|
||||
elif command -v shasum &>/dev/null; then
|
||||
ACTUAL=$(shasum -a 256 "$DLDIR/$ARCHIVE" | awk '{print $1}')
|
||||
else
|
||||
ACTUAL=""
|
||||
fi
|
||||
if [ -n "$ACTUAL" ] && [ "$EXPECTED" != "$ACTUAL" ]; then
|
||||
echo "error: CHECKSUM MISMATCH — download may be corrupted!" >&2
|
||||
echo " expected: $EXPECTED" >&2
|
||||
echo " actual: $ACTUAL" >&2
|
||||
exit 1
|
||||
elif [ -n "$ACTUAL" ]; then
|
||||
echo "Checksum verified."
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# Extract
|
||||
echo "Extracting..."
|
||||
cd "$DLDIR"
|
||||
if [ "$EXT" = "zip" ]; then
|
||||
unzip -q "$ARCHIVE"
|
||||
else
|
||||
tar -xzf "$ARCHIVE"
|
||||
fi
|
||||
|
||||
DLBIN="$DLDIR/codebase-memory-mcp"
|
||||
if [ ! -f "$DLBIN" ]; then
|
||||
echo "error: binary not found after extraction" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# macOS: fix signing
|
||||
if [ "$OS" = "darwin" ]; then
|
||||
echo "Fixing macOS code signing..."
|
||||
xattr -d com.apple.quarantine "$DLBIN" 2>/dev/null || true
|
||||
codesign --sign - --force "$DLBIN" 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# Install
|
||||
mkdir -p "$INSTALL_DIR"
|
||||
DEST="$INSTALL_DIR/codebase-memory-mcp"
|
||||
if [ -f "$DEST" ]; then
|
||||
rm -f "$DEST"
|
||||
fi
|
||||
cp "$DLBIN" "$DEST"
|
||||
chmod 755 "$DEST"
|
||||
|
||||
# Verify
|
||||
VERSION=$("$DEST" --version 2>&1) || {
|
||||
echo "error: installed binary failed to run" >&2
|
||||
if [ "$OS" = "darwin" ]; then
|
||||
echo " try: xattr -cr $DEST && codesign --force --sign - $DEST" >&2
|
||||
fi
|
||||
exit 1
|
||||
}
|
||||
echo "Installed: $VERSION"
|
||||
|
||||
# Configure agents
|
||||
if [ "$SKIP_CONFIG" = true ]; then
|
||||
echo ""
|
||||
echo "Skipping agent configuration (--skip-config)"
|
||||
else
|
||||
echo ""
|
||||
echo "Configuring coding agents..."
|
||||
"$DEST" install -y 2>&1 || {
|
||||
echo ""
|
||||
echo "Agent configuration failed (non-fatal)."
|
||||
echo "Run manually: codebase-memory-mcp install"
|
||||
}
|
||||
fi
|
||||
|
||||
# PATH check
|
||||
if ! echo "$PATH" | tr ':' '\n' | grep -qx "$INSTALL_DIR"; then
|
||||
echo ""
|
||||
echo "NOTE: $INSTALL_DIR is not in your PATH."
|
||||
echo "Add it to your shell config:"
|
||||
echo ""
|
||||
echo " echo 'export PATH=\"$INSTALL_DIR:\$PATH\"' >> ~/.zshrc"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Done! Restart your coding agent to start using codebase-memory-mcp."
|
||||
|
||||
} # end main()
|
||||
|
||||
main "$@"
|
||||
Reference in New Issue
Block a user