Skip to content

Instantly share code, notes, and snippets.

@bannzai
Last active January 17, 2026 06:52
Show Gist options
  • Select an option

  • Save bannzai/28441d7b101c49c2aa04ad1f5d580d4e to your computer and use it in GitHub Desktop.

Select an option

Save bannzai/28441d7b101c49c2aa04ad1f5d580d4e to your computer and use it in GitHub Desktop.
install-git.sh
#!/usr/bin/env bash
# SessionStart hook: install/update GitHub CLI (gh) on Claude Code on the Web
set -euo pipefail
LOG_PREFIX="[gh-setup]"
log(){ echo "$LOG_PREFIX $*" >&2; }
# Only run in Claude Code on the Web
if [[ "${CLAUDE_CODE_REMOTE:-}" != "true" ]]; then
log "Not a remote session, skipping."
exit 0
fi
LOCAL_BIN="${HOME}/.local/bin"
mkdir -p "$LOCAL_BIN"
ensure_path() {
if [[ ":${PATH}:" != *":${LOCAL_BIN}:"* ]]; then
export PATH="${LOCAL_BIN}:${PATH}"
fi
if [[ -n "${CLAUDE_ENV_FILE:-}" ]]; then
if ! grep -q 'export PATH="'"${LOCAL_BIN}"':\$PATH"' "$CLAUDE_ENV_FILE" 2>/dev/null; then
echo 'export PATH="'"${LOCAL_BIN}"':$PATH"' >> "$CLAUDE_ENV_FILE"
log "PATH persisted to CLAUDE_ENV_FILE"
fi
if [[ -n "${GITHUB_TOKEN:-}" && -z "${GH_TOKEN:-}" ]]; then
if ! grep -q 'export GH_TOKEN=' "$CLAUDE_ENV_FILE" 2>/dev/null; then
echo 'export GH_TOKEN="${GITHUB_TOKEN}"' >> "$CLAUDE_ENV_FILE"
log "GH_TOKEN persisted (from GITHUB_TOKEN)"
fi
export GH_TOKEN="${GITHUB_TOKEN}"
fi
fi
}
# If gh already exists, use it
if command -v gh >/dev/null 2>&1; then
ensure_path
log "gh already available: $(gh --version | head -1)"
exit 0
fi
if [[ -x "${LOCAL_BIN}/gh" ]]; then
ensure_path
log "gh found in ${LOCAL_BIN}: $(${LOCAL_BIN}/gh --version | head -1)"
exit 0
fi
need() { command -v "$1" >/dev/null 2>&1 || { log "Missing dependency: $1"; exit 0; }; }
need curl
need tar
need jq
ARCH="$(uname -m)"
case "$ARCH" in
x86_64|amd64) GH_ARCH="amd64" ;;
aarch64|arm64) GH_ARCH="arm64" ;;
*) log "Unsupported architecture: $ARCH"; exit 0 ;;
esac
OS_NAME="linux"
API="https://api.github.com/repos/cli/cli/releases/latest"
auth_header=()
if [[ -n "${GITHUB_TOKEN:-}" ]]; then
auth_header=(-H "Authorization: Bearer ${GITHUB_TOKEN}")
elif [[ -n "${GH_TOKEN:-}" ]]; then
auth_header=(-H "Authorization: Bearer ${GH_TOKEN}")
fi
TMP_DIR="$(mktemp -d)"
trap 'rm -rf "$TMP_DIR"' EXIT
log "Remote session detected. Installing gh into ${LOCAL_BIN} ..."
RELEASE_JSON="${TMP_DIR}/latest.json"
if ! curl -fsSL ${auth_header[@]+"${auth_header[@]}"} "$API" -o "$RELEASE_JSON"; then
log "Failed to fetch latest release metadata (GitHub API)."
exit 0
fi
if [[ ! -s "$RELEASE_JSON" ]]; then
log "GitHub API returned empty response."
exit 0
fi
TAG="$(jq -r '.tag_name' "$RELEASE_JSON")"
if [[ -z "$TAG" || "$TAG" == "null" ]]; then
log "Could not parse tag_name from release."
exit 0
fi
VER="${TAG#v}"
TARBALL="gh_${VER}_${OS_NAME}_${GH_ARCH}.tar.gz"
ASSET_URL="$(jq -r --arg name "$TARBALL" '.assets[] | select(.name == $name) | .browser_download_url' "$RELEASE_JSON")"
if [[ -z "$ASSET_URL" || "$ASSET_URL" == "null" ]]; then
log "Could not find asset for ${TARBALL} in latest release."
exit 0
fi
log "Latest release: ${TAG}"
log "Downloading: ${TARBALL}"
if ! curl -fL --retry 3 --retry-delay 1 "$ASSET_URL" -o "${TMP_DIR}/${TARBALL}"; then
log "Failed to download gh tarball."
exit 0
fi
log "Extracting..."
if ! tar -xzf "${TMP_DIR}/${TARBALL}" -C "$TMP_DIR"; then
log "Failed to extract."
exit 0
fi
BIN_PATH="$(find "$TMP_DIR" -type f -path "*/bin/gh" | head -n 1)"
if [[ -z "$BIN_PATH" ]]; then
log "gh binary not found after extract."
exit 0
fi
install -m 0755 "$BIN_PATH" "${LOCAL_BIN}/gh"
ensure_path
log "gh installed: $(gh --version | head -1)"
exit 0
@bannzai
Copy link
Author

bannzai commented Jan 17, 2026

@bannzai
Copy link
Author

bannzai commented Jan 17, 2026

Edit: ~/.claude/settings.json

 "hooks": {
    "SessionStart": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "curl -fsSL https://gist.githubusercontent.com/bannzai/28441d7b101c49c2aa04ad1f5d580d4e/raw/install-gh.sh | bash"
          }
        ]
      }
    ]
  }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment