Last active
January 17, 2026 06:52
-
-
Save bannzai/28441d7b101c49c2aa04ad1f5d580d4e to your computer and use it in GitHub Desktop.
install-git.sh
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/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 |
Author
Author
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
例: curl -fsSL https://gist.githubusercontent.com/bannzai/28441d7b101c49c2aa04ad1f5d580d4e/raw/install-gh.sh | bash