skills/zsh-path/SKILL.md
Manage and troubleshoot PATH configuration in zsh. Use when adding tools to PATH (bun, nvm, Python venv, cargo, go), diagnosing "command not found" errors, validating PATH entries, or organizing shell configuration in .zshrc and .zshrc.local files.
npx skillsauth add julianobarbosa/claude-code-skills zsh-pathInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
This skill provides comprehensive guidance for managing PATH environment variables in zsh, including troubleshooting missing commands, adding new tools, and organizing shell configuration.
Use this skill when:
# List all PATH entries
echo $PATH | tr ':' '\n'
# Check if specific command is in PATH
which bun 2>/dev/null || echo "bun not found in PATH"
# Find where a command is installed
command -v node
type -a python
# Check for broken/non-existent PATH entries
echo $PATH | tr ':' '\n' | while read p; do
[[ -d "$p" ]] || echo "MISSING: $p"
done
# Check for duplicate PATH entries
echo $PATH | tr ':' '\n' | sort | uniq -d
# Add to .zshrc
export BUN_INSTALL="$HOME/.bun"
export PATH="$BUN_INSTALL/bin:$PATH"
Default location: ~/.bun/bin/bun
# Add to .zshrc
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"
Default location: ~/.nvm/
Note: NVM is a shell function, not a binary. It modifies PATH dynamically to point to the active Node version.
# Add to .zshrc for global tools venv
export PATH="$HOME/.venv/tools3/bin:$PATH"
# For pyenv
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"
# Add to .zshrc
export PATH="$HOME/.cargo/bin:$PATH"
# Add to .zshrc
export GOPATH="$HOME/go"
export PATH="$GOPATH/bin:$PATH"
# Intel Mac
export PATH="/usr/local/bin:$PATH"
# Apple Silicon Mac
export PATH="/opt/homebrew/bin:$PATH"
eval "$(/opt/homebrew/bin/brew shellenv)"
# User-local binaries
export PATH="$HOME/.local/bin:$PATH"
export PATH="$HOME/bin:$PATH"
Keep in .zshrc:
# ===== ZSH-TOOL MANAGED SECTION BEGIN =====
# Team-wide PATH modifications
export PATH="$HOME/.local/bin:$PATH"
export PATH="$HOME/bin:$PATH"
# Bun
export BUN_INSTALL="$HOME/.bun"
export PATH="$BUN_INSTALL/bin:$PATH"
# NVM
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
# ===== ZSH-TOOL MANAGED SECTION END =====
# Load local customizations
[[ -f ~/.zshrc.local ]] && source ~/.zshrc.local
Keep in .zshrc.local:
# Machine-specific tools
export PATH="/opt/custom-tool/bin:$PATH"
# Personal integrations
if command -v atuin >/dev/null 2>&1; then
eval "$(atuin init zsh)"
fi
PATH is searched left-to-right. First match wins.
# This order means ~/.local/bin takes priority over system bins
export PATH="$HOME/.local/bin:/usr/local/bin:/usr/bin:/bin"
~/.local/bin, ~/bin)/usr/local/bin, /usr/bin)# 1. Find where tool was installed
ls -la ~/.bun/bin/bun 2>/dev/null
ls -la ~/.cargo/bin/rustc 2>/dev/null
ls -la ~/.nvm/versions/node/*/bin/node 2>/dev/null
# 2. Check if PATH includes the directory
echo $PATH | tr ':' '\n' | grep -E "(bun|cargo|nvm)"
# 3. Add missing PATH entry to .zshrc
# 4. Reload shell
source ~/.zshrc
# or
exec $SHELL
# Check which file sets the variable
grep -r "export PATH" ~/.zshrc ~/.zshrc.local ~/.zprofile 2>/dev/null
# Source the correct file
source ~/.zshrc
# Or start fresh shell
exec $SHELL
Common causes:
# Debug startup
zsh -x 2>&1 | head -100
# Check for errors in specific config
bash -n ~/.zshrc
# Remove duplicates (add to .zshrc)
typeset -U PATH path
After making PATH changes:
# Reload configuration
source ~/.zshrc
# Verify tool is accessible
which bun && bun --version
which node && node --version
command -v nvm && nvm --version
# Verify PATH includes new entries
echo $PATH | tr ':' '\n' | grep -E "(bun|nvm|venv)"
| Tool | PATH Entry | Check Command |
|------|------------|---------------|
| bun | $HOME/.bun/bin | bun --version |
| nvm | $NVM_DIR/versions/node/*/bin | nvm --version |
| cargo | $HOME/.cargo/bin | cargo --version |
| go | $GOPATH/bin | go version |
| pyenv | $PYENV_ROOT/bin | pyenv --version |
| brew (ARM) | /opt/homebrew/bin | brew --version |
| brew (Intel) | /usr/local/bin | brew --version |
# Only add if directory exists
[[ -d "$HOME/.bun/bin" ]] && export PATH="$HOME/.bun/bin:$PATH"
# Only add if command not already available
command -v bun >/dev/null || export PATH="$HOME/.bun/bin:$PATH"
# Lazy load nvm (faster shell startup)
lazy_load_nvm() {
unset -f nvm node npm npx
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
}
nvm() { lazy_load_nvm && nvm "$@"; }
node() { lazy_load_nvm && node "$@"; }
npm() { lazy_load_nvm && npm "$@"; }
npx() { lazy_load_nvm && npx "$@"; }
path= array vs PATH= env var: assigning to one without typeset -U drops uniqueness: Duplicates appear hours later as stale entries. Run typeset -U path PATH once early in .zshrc to bind them and dedupe automatically..zprofile runs only for login shells, .zshrc for interactive: Homebrew's installer suggests adding eval "$(brew shellenv)" to .zprofile — non-login interactive shells (most terminal sessions on Linux) miss it entirely. Mirror to .zshrc if commands are missing in subshells.which node lies: After nvm use, which node shows ~/.nvm/versions/node/vXX/bin/node but a fresh subshell may show nothing until nvm.sh is sourced again. Scripts run via bash -c bypass nvm entirely.npm invocations in shebangs: Scripts starting with #!/usr/bin/env node fork a new shell, which loads .zshrc, which lazy-loads nvm — adding 500ms+ per script invocation. Eager-load nvm if you run many node scripts.source ~/.zshrc doesn't undo previous PATH additions: Re-sourcing appends without dedup, so PATH grows each time. Always start a fresh shell (exec zsh) when testing PATH changes, not source./opt/homebrew/bin is invisible to Intel binaries: Rosetta-mode terminals (arch -x86_64 zsh) see /usr/local/bin instead — same machine, two different brew prefixes, two different toolchains.development
End-to-end branch delivery: commit (no AI attribution) → push → open a pull request → ensure a Board work item exists (create one per task, assigned to the configured user, if none) and link it → after merge, clean up branch and worktree. Auto-detects the platform from the remote — Azure Repos + Boards (azure-devops-node-api SDK; OAuth Bearer push fallback via `az`) or GitHub (Octokit; `gh` for auth). Scripts are TypeScript, run via `bun`. Use whenever asked to "ship", "ship it", "ship this branch", "open a PR", "push and open a PR", "raise a PR", "deliver this", "send this for review", or "create a PR and link the work item" — and when a direct push to main is blocked and the change needs to go through a PR instead.
testing
Brief description of what this skill does. Include specific triggers - when should Claude use this skill? Example triggers, file types, or keywords that indicate this skill applies.
tools
Zabbix monitoring system automation via API and Python. Use when: (1) Managing hosts, templates, items, triggers, or host groups, (2) Automating monitoring configuration, (3) Sending data via Zabbix trapper/sender, (4) Querying historical data or events, (5) Bulk operations on Zabbix objects, (6) Maintenance window management, (7) User/permission management
development
Operate YouTube Music via natural language. Search songs, artists, albums, playlists, lyrics, charts, recommendations, and control playback. Browse personal library, manage playlists, rate tracks, and inspect account info. Use this skill whenever the user asks about YouTube Music, wants to play music, manage playlists, search by song or artist name, inspect lyrics, or control playback.