Skip to content

Commit 96f46a8

Browse files
committed
✨ Revamp installation script for AIDevTools Sidekick: enhanced logging, platform detection, and binary download functionality; added checks for existing installations and improved user guidance.
1 parent 19091b0 commit 96f46a8

File tree

1 file changed

+285
-78
lines changed

1 file changed

+285
-78
lines changed

install.sh

Lines changed: 285 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -1,98 +1,305 @@
11
#!/bin/bash
22

3-
# Sidekick Installation Script
4-
# Builds and installs the sidekick binary to ~/.local/bin/
3+
# AIDevTools Sidekick Installation Script
4+
# Downloads and installs the latest sidekick binary from GitHub releases
5+
# Usage: curl -sSL https://raw.githubusercontent.com/eliezedeck/AIDevTools/main/install.sh | bash
56

67
set -e
78

8-
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
9-
SIDEKICK_DIR="$SCRIPT_DIR/sidekick"
10-
INSTALL_DIR="$HOME/.local/bin"
9+
# Configuration
10+
REPO="eliezedeck/AIDevTools"
1111
BINARY_NAME="sidekick"
12-
INSTALL_PATH="$INSTALL_DIR/$BINARY_NAME"
12+
INSTALL_DIR="${INSTALL_DIR:-$HOME/.local/bin}"
13+
GITHUB_API="https://api.github.com/repos/$REPO"
14+
GITHUB_RELEASES="https://github.com/$REPO/releases"
1315

14-
echo "🚀 Sidekick Installation Script"
15-
echo "==============================="
16+
# Colors for output
17+
RED='\033[0;31m'
18+
GREEN='\033[0;32m'
19+
YELLOW='\033[1;33m'
20+
BLUE='\033[0;34m'
21+
NC='\033[0m' # No Color
1622

17-
# Check if Go is installed
18-
if ! command -v go &> /dev/null; then
19-
echo "❌ Error: Go is not installed or not in PATH"
20-
echo " Please install Go from https://golang.org/dl/"
21-
exit 1
22-
fi
23+
# Logging functions
24+
log_info() {
25+
echo -e "${BLUE}ℹ️ $1${NC}"
26+
}
2327

24-
echo "✅ Go found: $(go version)"
28+
log_success() {
29+
echo -e "${GREEN}$1${NC}"
30+
}
2531

26-
# Check if sidekick directory exists
27-
if [ ! -d "$SIDEKICK_DIR" ]; then
28-
echo "❌ Error: sidekick directory not found at $SIDEKICK_DIR"
29-
exit 1
30-
fi
32+
log_warning() {
33+
echo -e "${YELLOW}⚠️ $1${NC}"
34+
}
3135

32-
# Create ~/.local/bin if it doesn't exist
33-
if [ ! -d "$INSTALL_DIR" ]; then
34-
echo "📁 Creating directory: $INSTALL_DIR"
35-
mkdir -p "$INSTALL_DIR"
36-
fi
37-
38-
# Check if binary already exists
39-
if [ -f "$INSTALL_PATH" ]; then
40-
echo "⚠️ Sidekick binary already exists at: $INSTALL_PATH"
41-
echo -n " Do you want to overwrite it? [y/N]: "
42-
read -r response
43-
case "$response" in
44-
[yY][eE][sS]|[yY])
45-
echo " Proceeding with overwrite..."
46-
;;
47-
*)
48-
echo " Installation cancelled."
49-
exit 0
50-
;;
36+
log_error() {
37+
echo -e "${RED}$1${NC}"
38+
}
39+
40+
# Detect OS and architecture
41+
detect_platform() {
42+
local os arch
43+
44+
case "$(uname -s)" in
45+
Darwin*) os="darwin" ;;
46+
Linux*) os="linux" ;;
47+
MINGW*|MSYS*|CYGWIN*) os="windows" ;;
48+
*) log_error "Unsupported operating system: $(uname -s)"; exit 1 ;;
49+
esac
50+
51+
case "$(uname -m)" in
52+
x86_64|amd64) arch="amd64" ;;
53+
arm64|aarch64) arch="arm64" ;;
54+
*) log_error "Unsupported architecture: $(uname -m)"; exit 1 ;;
5155
esac
52-
fi
56+
57+
if [[ "$os" == "windows" ]]; then
58+
PLATFORM="${os}-${arch}"
59+
BINARY_EXT=".exe"
60+
ARCHIVE_EXT=".zip"
61+
else
62+
PLATFORM="${os}-${arch}"
63+
BINARY_EXT=""
64+
ARCHIVE_EXT=".tar.gz"
65+
fi
66+
67+
log_info "Detected platform: $PLATFORM"
68+
}
5369

54-
# Download dependencies and build the binary
55-
echo "📦 Downloading Go dependencies..."
56-
cd "$SIDEKICK_DIR"
70+
# Check if command exists
71+
command_exists() {
72+
command -v "$1" >/dev/null 2>&1
73+
}
5774

58-
# Download and verify dependencies
59-
go mod download
60-
if [ $? -ne 0 ]; then
61-
echo "❌ Failed to download dependencies!"
62-
exit 1
63-
fi
75+
# Get latest release version
76+
get_latest_version() {
77+
log_info "Fetching latest release information..."
78+
79+
if command_exists curl; then
80+
VERSION=$(curl -s "$GITHUB_API/releases/latest" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/')
81+
elif command_exists wget; then
82+
VERSION=$(wget -qO- "$GITHUB_API/releases/latest" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/')
83+
else
84+
log_error "Neither curl nor wget found. Please install one of them."
85+
exit 1
86+
fi
87+
88+
if [[ -z "$VERSION" ]]; then
89+
log_error "Failed to fetch latest version. Trying fallback to v0.1.0..."
90+
VERSION="v0.1.0"
91+
fi
92+
93+
log_success "Latest version: $VERSION"
94+
}
95+
96+
# Download and extract binary
97+
download_binary() {
98+
local archive_name="${BINARY_NAME}-${PLATFORM}${ARCHIVE_EXT}"
99+
local download_url="${GITHUB_RELEASES}/download/${VERSION}/${archive_name}"
100+
local temp_dir
101+
temp_dir=$(mktemp -d)
102+
103+
log_info "Downloading $archive_name..."
104+
105+
if command_exists curl; then
106+
if ! curl -sL "$download_url" -o "$temp_dir/$archive_name"; then
107+
log_error "Failed to download from $download_url"
108+
return 1
109+
fi
110+
elif command_exists wget; then
111+
if ! wget -q "$download_url" -O "$temp_dir/$archive_name"; then
112+
log_error "Failed to download from $download_url"
113+
return 1
114+
fi
115+
fi
116+
117+
log_success "Downloaded successfully"
118+
119+
# Extract archive
120+
log_info "Extracting archive..."
121+
cd "$temp_dir"
122+
123+
if [[ "$ARCHIVE_EXT" == ".tar.gz" ]]; then
124+
if ! tar -xzf "$archive_name"; then
125+
log_error "Failed to extract tar.gz archive"
126+
return 1
127+
fi
128+
elif [[ "$ARCHIVE_EXT" == ".zip" ]]; then
129+
if command_exists unzip; then
130+
if ! unzip -q "$archive_name"; then
131+
log_error "Failed to extract zip archive"
132+
return 1
133+
fi
134+
else
135+
log_error "unzip command not found. Please install unzip."
136+
return 1
137+
fi
138+
fi
139+
140+
# Find the binary
141+
local binary_file="${BINARY_NAME}-${PLATFORM}${BINARY_EXT}"
142+
if [[ ! -f "$binary_file" ]]; then
143+
log_error "Binary file $binary_file not found in archive"
144+
return 1
145+
fi
146+
147+
# Move binary to install directory
148+
mkdir -p "$INSTALL_DIR"
149+
if ! mv "$binary_file" "$INSTALL_DIR/$BINARY_NAME"; then
150+
log_error "Failed to move binary to $INSTALL_DIR"
151+
return 1
152+
fi
153+
154+
chmod +x "$INSTALL_DIR/$BINARY_NAME"
155+
log_success "Binary installed to $INSTALL_DIR/$BINARY_NAME"
156+
157+
# Cleanup
158+
rm -rf "$temp_dir"
159+
}
64160

65-
echo "✅ Dependencies downloaded successfully!"
161+
# Build from source as fallback
162+
build_from_source() {
163+
log_warning "Pre-built binary not available. Attempting to build from source..."
164+
165+
if ! command_exists go; then
166+
log_error "Go is not installed. Please install Go from https://golang.org/dl/"
167+
log_error "Or wait for pre-built binaries to be available for your platform."
168+
exit 1
169+
fi
170+
171+
if ! command_exists git; then
172+
log_error "Git is not installed. Please install Git."
173+
exit 1
174+
fi
175+
176+
local temp_dir
177+
temp_dir=$(mktemp -d)
178+
179+
log_info "Cloning repository..."
180+
if ! git clone "https://github.com/$REPO.git" "$temp_dir/AIDevTools"; then
181+
log_error "Failed to clone repository"
182+
exit 1
183+
fi
184+
185+
log_info "Building from source..."
186+
cd "$temp_dir/AIDevTools/sidekick"
187+
188+
if ! go mod download; then
189+
log_error "Failed to download Go dependencies"
190+
exit 1
191+
fi
192+
193+
mkdir -p "$INSTALL_DIR"
194+
if ! go build -ldflags="-s -w" -o "$INSTALL_DIR/$BINARY_NAME" main.go processes.go notifications.go; then
195+
log_error "Failed to build binary"
196+
exit 1
197+
fi
198+
199+
chmod +x "$INSTALL_DIR/$BINARY_NAME"
200+
log_success "Binary built and installed to $INSTALL_DIR/$BINARY_NAME"
201+
202+
# Cleanup
203+
rm -rf "$temp_dir"
204+
}
66205

67-
echo "🔨 Building sidekick binary..."
68-
# Build with all Go files
69-
go build -o "$INSTALL_PATH" main.go processes.go notifications.go
206+
# Check if PATH includes install directory
207+
check_path() {
208+
if [[ ":$PATH:" != *":$INSTALL_DIR:"* ]]; then
209+
log_warning "$INSTALL_DIR is not in your PATH"
210+
echo ""
211+
echo "Add the following line to your shell configuration file:"
212+
echo " ~/.bashrc (Bash) or ~/.zshrc (Zsh) or ~/.config/fish/config.fish (Fish)"
213+
echo ""
214+
echo " export PATH=\"\$PATH:$INSTALL_DIR\""
215+
echo ""
216+
echo "Or run this command now:"
217+
echo " echo 'export PATH=\"\$PATH:$INSTALL_DIR\"' >> ~/.$(basename "$SHELL")rc"
218+
echo ""
219+
echo "Then restart your shell or run: source ~/.$(basename "$SHELL")rc"
220+
echo ""
221+
fi
222+
}
70223

71-
if [ $? -eq 0 ]; then
72-
echo "✅ Binary built successfully!"
73-
else
74-
echo "❌ Build failed!"
75-
exit 1
76-
fi
224+
# Verify installation
225+
verify_installation() {
226+
if [[ -x "$INSTALL_DIR/$BINARY_NAME" ]]; then
227+
log_success "Installation successful!"
228+
echo ""
229+
echo "📍 Binary location: $INSTALL_DIR/$BINARY_NAME"
230+
231+
# Try to get version
232+
if "$INSTALL_DIR/$BINARY_NAME" --version >/dev/null 2>&1; then
233+
echo "🔢 Version: $("$INSTALL_DIR/$BINARY_NAME" --version 2>/dev/null || echo "unknown")"
234+
fi
235+
236+
echo ""
237+
echo "🚀 Next steps:"
238+
echo " 1. Add to Claude Code:"
239+
echo " claude mcp add sidekick $INSTALL_DIR/$BINARY_NAME"
240+
echo ""
241+
echo " 2. Verify MCP registration:"
242+
echo " claude mcp list"
243+
echo ""
244+
echo " 3. Test in Claude Code:"
245+
echo " Ask Claude to spawn a simple process!"
246+
echo ""
247+
248+
check_path
249+
250+
log_success "Ready to use with Claude Code! 🎉"
251+
else
252+
log_error "Installation failed - binary not found or not executable"
253+
exit 1
254+
fi
255+
}
77256

78-
# Make binary executable
79-
chmod +x "$INSTALL_PATH"
257+
# Check for existing installation
258+
check_existing() {
259+
if [[ -f "$INSTALL_DIR/$BINARY_NAME" ]]; then
260+
log_warning "Sidekick is already installed at $INSTALL_DIR/$BINARY_NAME"
261+
echo -n "Do you want to reinstall/update? [y/N]: "
262+
read -r response
263+
case "$response" in
264+
[yY][eE][sS]|[yY])
265+
log_info "Proceeding with reinstallation..."
266+
return 0
267+
;;
268+
*)
269+
log_info "Installation cancelled."
270+
exit 0
271+
;;
272+
esac
273+
fi
274+
}
80275

81-
# Check if ~/.local/bin is in PATH
82-
if [[ ":$PATH:" != *":$INSTALL_DIR:"* ]]; then
83-
echo ""
84-
echo "⚠️ Warning: $INSTALL_DIR is not in your PATH"
85-
echo " Add the following line to your ~/.bashrc, ~/.zshrc, or equivalent:"
86-
echo " export PATH=\"\$PATH:$INSTALL_DIR\""
87-
echo ""
88-
echo " Or run this command now:"
89-
echo " echo 'export PATH=\"\$PATH:$INSTALL_DIR\"' >> ~/.$(basename $SHELL)rc"
276+
# Main installation function
277+
main() {
278+
echo "🚀 AIDevTools Sidekick Installer"
279+
echo "=================================="
90280
echo ""
91-
fi
92-
93-
echo "🎉 Installation complete!"
94-
echo " Binary installed at: $INSTALL_PATH"
95-
echo " You can now use: claude mcp add sidekick $INSTALL_PATH"
96-
echo ""
97-
echo "🔍 Verify installation:"
98-
echo " $INSTALL_PATH --help"
281+
282+
# Check for existing installation
283+
check_existing
284+
285+
# Detect platform
286+
detect_platform
287+
288+
# Get latest version
289+
get_latest_version
290+
291+
# Try to download binary, fallback to building from source
292+
if ! download_binary; then
293+
log_warning "Failed to download pre-built binary"
294+
build_from_source
295+
fi
296+
297+
# Verify installation
298+
verify_installation
299+
}
300+
301+
# Handle interruption
302+
trap 'log_error "Installation interrupted"; exit 130' INT
303+
304+
# Run main function
305+
main "$@"

0 commit comments

Comments
 (0)