Skip to content

Instantly share code, notes, and snippets.

@statik
Created August 11, 2026 20:33
Show Gist options
  • Select an option

  • Save statik/4c025a4cd252059826704ded969f1052 to your computer and use it in GitHub Desktop.

Select an option

Save statik/4c025a4cd252059826704ded969f1052 to your computer and use it in GitHub Desktop.
install-workbench-session-dev-tools
#!/usr/bin/env bash
# Installs uv, nvm, aws-cli, gh, claude, and just into ~/.local/bin (no sudo required).
# Safe to re-run: each installer is skipped if already present.
set -euo pipefail
BIN_DIR="$HOME/.local/bin"
mkdir -p "$BIN_DIR"
export PATH="$BIN_DIR:$PATH"
log() { printf '\n\033[1;34m==>\033[0m %s\n' "$1"; }
detect_arch() {
case "$(uname -m)" in
x86_64) echo "x86_64" ;;
aarch64|arm64) echo "aarch64" ;;
*) echo "unsupported machine arch: $(uname -m)" >&2; exit 1 ;;
esac
}
require_cmd() {
command -v "$1" >/dev/null 2>&1 || { echo "missing required command: $1" >&2; exit 1; }
}
install_uv() {
if [[ -x "$BIN_DIR/uv" ]]; then
log "uv already installed at $BIN_DIR/uv, skipping"
return
fi
log "Installing uv into $BIN_DIR"
curl -LsSf https://astral.sh/uv/install.sh | env UV_INSTALL_DIR="$BIN_DIR" INSTALLER_NO_MODIFY_PATH=1 sh
}
install_just() {
if [[ -x "$BIN_DIR/just" ]]; then
log "just already installed at $BIN_DIR/just, skipping"
return
fi
log "Installing just into $BIN_DIR"
curl --proto '=https' --tlsv1.2 -sSf https://just.systems/install.sh | bash -s -- --to "$BIN_DIR"
}
install_claude() {
if [[ -x "$BIN_DIR/claude" ]]; then
log "claude already installed at $BIN_DIR/claude, skipping"
return
fi
log "Installing Claude Code CLI into $BIN_DIR"
curl -fsSL https://claude.ai/install.sh | bash
if [[ ! -x "$BIN_DIR/claude" ]]; then
log "Warning: claude binary not found at $BIN_DIR/claude — check the installer output above"
fi
}
install_nvm() {
# nvm is a shell function sourced from ~/.nvm/nvm.sh, not a standalone executable,
# so it can't literally live in ~/.local/bin. It installs to its standard home
# (~/.nvm) and this function makes sure your shell rc sources it.
if [[ -s "$HOME/.nvm/nvm.sh" ]]; then
log "nvm already installed at $HOME/.nvm, skipping"
return
fi
log "Installing nvm into \$HOME/.nvm (check https://github.com/nvm-sh/nvm for the latest version tag)"
curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
}
install_gh() {
if [[ -x "$BIN_DIR/gh" ]]; then
log "gh already installed at $BIN_DIR/gh, skipping"
return
fi
require_cmd jq
log "Installing GitHub CLI into $BIN_DIR"
local arch os_arch tmpdir url version
arch="$(detect_arch)"
case "$arch" in
x86_64) os_arch="amd64" ;;
aarch64) os_arch="arm64" ;;
esac
version="$(curl -fsSL https://api.github.com/repos/cli/cli/releases/latest | jq -r '.tag_name' | sed 's/^v//')"
url="https://github.com/cli/cli/releases/download/v${version}/gh_${version}_linux_${os_arch}.tar.gz"
tmpdir="$(mktemp -d)"
trap 'rm -rf "$tmpdir"' RETURN
curl -fsSL "$url" -o "$tmpdir/gh.tar.gz"
tar -xzf "$tmpdir/gh.tar.gz" -C "$tmpdir"
cp "$tmpdir/gh_${version}_linux_${os_arch}/bin/gh" "$BIN_DIR/gh"
chmod +x "$BIN_DIR/gh"
}
install_aws() {
if [[ -x "$BIN_DIR/aws" ]]; then
log "aws already installed at $BIN_DIR/aws, skipping"
return
fi
require_cmd unzip
log "Installing AWS CLI v2 into $BIN_DIR"
local arch tmpdir url
arch="$(detect_arch)"
url="https://awscli.amazonaws.com/awscli-exe-linux-${arch}.zip"
tmpdir="$(mktemp -d)"
trap 'rm -rf "$tmpdir"' RETURN
curl -fsSL "$url" -o "$tmpdir/awscliv2.zip"
unzip -q "$tmpdir/awscliv2.zip" -d "$tmpdir"
"$tmpdir/aws/install" --install-dir "$HOME/.local/aws-cli" --bin-dir "$BIN_DIR" --update
}
ensure_path() {
local rc
for rc in "$HOME/.bashrc" "$HOME/.zshrc"; do
[[ -f "$rc" ]] || continue
if ! grep -qs '\.local/bin' "$rc"; then
log "Adding $BIN_DIR to PATH in $rc"
printf '\nexport PATH="$HOME/.local/bin:$PATH"\n' >> "$rc"
fi
done
}
main() {
ensure_path
install_uv
install_just
install_claude
install_gh
install_aws
install_nvm
log "Done. Open a new shell (or 'source ~/.bashrc') to pick up PATH changes."
log "Installed versions:"
"$BIN_DIR/uv" --version 2>/dev/null || true
"$BIN_DIR/just" --version 2>/dev/null || true
"$BIN_DIR/claude" --version 2>/dev/null || true
"$BIN_DIR/gh" --version 2>/dev/null || true
"$BIN_DIR/aws" --version 2>/dev/null || true
}
main "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment