feat(distribution): binary release pipeline + brew + winget
- .github/workflows/release-cli.yml: build self-contained binaries via `bun build --compile` for darwin/linux/windows × x64/arm64 on every cli-v* tag, attach to GitHub Release with SHA256SUMS, auto-bump the homebrew tap on non-prerelease versions. - packaging/homebrew/claudemesh.rb.template: formula template for the homebrew-claudemesh tap. - packaging/winget/claudemesh.yaml.template: winget manifest template. - /install script now detects absence of Node and downloads the platform-appropriate binary from the GitHub Release, installs to ~/.claudemesh/bin, and shims into ~/.local/bin — zero Node required. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -30,42 +30,87 @@ say "\${BOLD}claudemesh-cli installer\${RESET}"
|
||||
say "$(printf '%.0s─' {1..40})"
|
||||
|
||||
# --- preflight ------------------------------------------------------
|
||||
# Prefer npm when Node 20+ is present. Otherwise fall back to a
|
||||
# self-contained binary download from GitHub Releases (installs to
|
||||
# ~/.claudemesh/bin and adds a shim at ~/.local/bin/claudemesh).
|
||||
|
||||
if ! command -v node >/dev/null 2>&1; then
|
||||
err "Node.js is not installed."
|
||||
say " Install Node.js 20 or newer: \${BOLD}https://nodejs.org\${RESET}"
|
||||
say " Or via nvm: \${DIM}curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash\${RESET}"
|
||||
exit 1
|
||||
detect_os() {
|
||||
case "$(uname -s)" in
|
||||
Darwin) echo darwin ;;
|
||||
Linux) echo linux ;;
|
||||
*) echo "" ;;
|
||||
esac
|
||||
}
|
||||
detect_arch() {
|
||||
case "$(uname -m)" in
|
||||
x86_64|amd64) echo x64 ;;
|
||||
arm64|aarch64) echo arm64 ;;
|
||||
*) echo "" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
install_via_binary() {
|
||||
local os arch url target dir shim
|
||||
os=$(detect_os); arch=$(detect_arch)
|
||||
if [ -z "$os" ] || [ -z "$arch" ]; then
|
||||
err "No precompiled binary for $(uname -s)/$(uname -m). Install Node 20+ or build from source."
|
||||
exit 1
|
||||
fi
|
||||
dir="\${HOME}/.claudemesh/bin"
|
||||
mkdir -p "$dir"
|
||||
target="\${dir}/claudemesh"
|
||||
url="https://github.com/alezmad/claudemesh/releases/latest/download/claudemesh-\${os}-\${arch}"
|
||||
say "Downloading \${BOLD}\${url}\${RESET}…"
|
||||
if ! curl -fsSL "$url" -o "$target"; then
|
||||
err "Download failed. Falling back to npm."
|
||||
return 1
|
||||
fi
|
||||
chmod +x "$target"
|
||||
shim="\${HOME}/.local/bin/claudemesh"
|
||||
mkdir -p "\${HOME}/.local/bin"
|
||||
printf '#!/bin/sh\\nexec "%s" "$@"\\n' "$target" > "$shim"
|
||||
chmod +x "$shim"
|
||||
ok "claudemesh binary installed → \${target}"
|
||||
case ":$PATH:" in
|
||||
*":\${HOME}/.local/bin:"*) : ;;
|
||||
*)
|
||||
say ""
|
||||
say "\${BOLD}Add \${HOME}/.local/bin to PATH\${RESET} (add to your shell rc):"
|
||||
say " export PATH=\\"\${HOME}/.local/bin:\$PATH\\""
|
||||
;;
|
||||
esac
|
||||
return 0
|
||||
}
|
||||
|
||||
install_via_npm() {
|
||||
ok "Node.js $(node -v)"
|
||||
ok "npm $(npm -v)"
|
||||
say ""
|
||||
say "Installing \${BOLD}claudemesh-cli\${RESET} from npm…"
|
||||
if ! npm install -g claudemesh-cli; then
|
||||
err "npm install failed."
|
||||
say " If this is a permissions error on macOS/Linux, try:"
|
||||
say " \${DIM}sudo npm install -g claudemesh-cli\${RESET}"
|
||||
say " or configure npm to use a user-owned prefix:"
|
||||
say " \${DIM}https://docs.npmjs.com/resolving-eacces-permissions-errors\${RESET}"
|
||||
exit 1
|
||||
fi
|
||||
ok "claudemesh-cli installed ($(claudemesh --version))"
|
||||
}
|
||||
|
||||
if command -v node >/dev/null 2>&1; then
|
||||
NODE_MAJOR=$(node -p "process.versions.node.split('.')[0]" 2>/dev/null || echo 0)
|
||||
if [ "$NODE_MAJOR" -ge 20 ] && command -v npm >/dev/null 2>&1; then
|
||||
install_via_npm
|
||||
else
|
||||
say "Node.js < 20 or no npm — using standalone binary."
|
||||
install_via_binary || install_via_npm
|
||||
fi
|
||||
else
|
||||
say "Node.js not detected — installing standalone binary (no Node required)."
|
||||
install_via_binary
|
||||
fi
|
||||
|
||||
NODE_MAJOR=$(node -p "process.versions.node.split('.')[0]")
|
||||
if [ "$NODE_MAJOR" -lt 20 ]; then
|
||||
err "Node.js $(node -v) is too old — claudemesh-cli needs >= 20."
|
||||
say " Upgrade: \${BOLD}https://nodejs.org\${RESET}"
|
||||
exit 1
|
||||
fi
|
||||
ok "Node.js $(node -v)"
|
||||
|
||||
if ! command -v npm >/dev/null 2>&1; then
|
||||
err "npm is not installed (usually ships with Node)."
|
||||
exit 1
|
||||
fi
|
||||
ok "npm $(npm -v)"
|
||||
|
||||
# --- install --------------------------------------------------------
|
||||
|
||||
say ""
|
||||
say "Installing \${BOLD}claudemesh-cli\${RESET} from npm…"
|
||||
if ! npm install -g claudemesh-cli; then
|
||||
err "npm install failed."
|
||||
say " If this is a permissions error on macOS/Linux, try:"
|
||||
say " \${DIM}sudo npm install -g claudemesh-cli\${RESET}"
|
||||
say " or configure npm to use a user-owned prefix:"
|
||||
say " \${DIM}https://docs.npmjs.com/resolving-eacces-permissions-errors\${RESET}"
|
||||
exit 1
|
||||
fi
|
||||
ok "claudemesh-cli installed ($(claudemesh --version))"
|
||||
|
||||
# --- register MCP + hooks ------------------------------------------
|
||||
|
||||
say ""
|
||||
|
||||
Reference in New Issue
Block a user