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
67set -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"
1111BINARY_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