@@ -161,6 +161,11 @@ install_oh_my_zsh() {
161161 return
162162 fi
163163
164+ if ! command_exists zsh; then
165+ print_warning " zsh not installed, skipping oh-my-zsh"
166+ return
167+ fi
168+
164169 print_header " Installing oh-my-zsh..."
165170 sh -c " $( curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh) " " " --unattended
166171 print_success " oh-my-zsh installed"
@@ -219,6 +224,11 @@ install_brew_packages() {
219224 brew bundle --file=" $BREWFILE "
220225 print_success " All packages installed"
221226 fi
227+
228+ # Ensure Homebrew binaries are in PATH (important for CI)
229+ if command_exists brew; then
230+ eval " $( brew shellenv) "
231+ fi
222232}
223233
224234# Install tmux plugin manager
@@ -243,8 +253,11 @@ install_uv() {
243253 fi
244254
245255 print_header " Installing UV..."
246- curl -LsSf https://astral.sh/uv/install.sh | sh
247- print_success " UV installed"
256+ if curl -LsSf https://astral.sh/uv/install.sh | sh; then
257+ print_success " UV installed"
258+ else
259+ print_warning " UV installation failed (may not be available in this environment)"
260+ fi
248261}
249262
250263# Install Claude CLI
@@ -255,8 +268,11 @@ install_claude_cli() {
255268 fi
256269
257270 print_header " Installing Claude CLI..."
258- curl -fsSL https://claude.ai/install.sh | sh
259- print_success " Claude CLI installed"
271+ if curl -fsSL https://claude.ai/install.sh | sh; then
272+ print_success " Claude CLI installed"
273+ else
274+ print_warning " Claude CLI installation failed (may not be available in this environment)"
275+ fi
260276}
261277
262278# Install OpenCode
@@ -267,8 +283,11 @@ install_opencode() {
267283 fi
268284
269285 print_header " Installing OpenCode..."
270- curl -fsSL https://opencode.ai/install | sh
271- print_success " OpenCode installed"
286+ if curl -fsSL https://opencode.ai/install | sh; then
287+ print_success " OpenCode installed"
288+ else
289+ print_warning " OpenCode installation failed (may not be available in this environment)"
290+ fi
272291}
273292
274293# Install GitHub CLI extensions
@@ -278,6 +297,12 @@ install_gh_extensions() {
278297 return
279298 fi
280299
300+ # Check if we're authenticated (required for extension installation)
301+ if ! gh auth status > /dev/null 2>&1 ; then
302+ print_warning " gh not authenticated, skipping extensions (set GH_TOKEN in CI)"
303+ return
304+ fi
305+
281306 local extensions_file=" $DOTFILES /.config/gh/extensions"
282307
283308 if [ ! -f " $extensions_file " ]; then
@@ -329,13 +354,6 @@ stow_dotfiles() {
329354
330355 print_header " Stowing dotfiles..."
331356
332- # Navigate to parent of dotfiles directory to run stow
333- local parent_dir
334- local dotfiles_name
335- parent_dir=" $( dirname " $DOTFILES " ) "
336- dotfiles_name=" $( basename " $DOTFILES " ) "
337- cd " $parent_dir "
338-
339357 # Backup existing dotfiles that might conflict
340358 local backup_dir
341359 backup_dir=" $HOME /.dotfiles-backup-$( date +%Y%m%d-%H%M%S) "
@@ -356,12 +374,17 @@ stow_dotfiles() {
356374 fi
357375 done
358376
377+ # Get parent directory and dotfiles name for stow
378+ local parent_dir
379+ local dotfiles_name
380+ parent_dir=" $( dirname " $DOTFILES " ) "
381+ dotfiles_name=" $( basename " $DOTFILES " ) "
382+
359383 # Unstow first (in case of previous installation)
360- stow -D " $dotfiles_name " 2> /dev/null || true
384+ stow --dir= " $parent_dir " --target= " $HOME " - D " $dotfiles_name " 2> /dev/null || true
361385
362- # Stow the dotfiles directory
363- # The .stowrc in the dotfiles directory sets --target=$HOME
364- stow " $dotfiles_name "
386+ # Stow the dotfiles directory with explicit flags
387+ stow --dir=" $parent_dir " --target=" $HOME " --verbose " $dotfiles_name "
365388
366389 print_success " Dotfiles stowed"
367390
0 commit comments