Download scripts/gh.sh from SaylorTwift/claude-code: direct link, hf CLI and curl.
- Browser
- Download file 3.11 kB
-
https://huggingface.co/SaylorTwift/claude-code/resolve/main/scripts/gh.sh
- Command line
-
hf download hf://SaylorTwift/claude-code/scripts/gh.sh
-
curl -L -o gh.sh https://huggingface.co/SaylorTwift/claude-code/resolve/main/scripts/gh.sh
3.11 kB
| set -euo pipefail | |
| # Wrapper around gh CLI that only allows specific subcommands and flags. | |
| # All commands are scoped to the current repository via GH_REPO or GITHUB_REPOSITORY. | |
| # | |
| # Usage: | |
| # ./scripts/gh.sh issue view 123 | |
| # ./scripts/gh.sh issue view 123 --comments | |
| # ./scripts/gh.sh issue list --state open --limit 20 | |
| # ./scripts/gh.sh search issues "search query" --limit 10 | |
| # ./scripts/gh.sh label list --limit 100 | |
| export GH_HOST=github.com | |
| REPO="${GH_REPO:-${GITHUB_REPOSITORY:-}}" | |
| if [[ -z "$REPO" || "$REPO" == */*/* || "$REPO" != */* ]]; then | |
| echo "Error: GH_REPO or GITHUB_REPOSITORY must be set to owner/repo format (e.g., GITHUB_REPOSITORY=anthropics/claude-code)" >&2 | |
| exit 1 | |
| fi | |
| export GH_REPO="$REPO" | |
| ALLOWED_FLAGS=(--comments --state --limit --label) | |
| FLAGS_WITH_VALUES=(--state --limit --label) | |
| SUB1="${1:-}" | |
| SUB2="${2:-}" | |
| CMD="$SUB1 $SUB2" | |
| case "$CMD" in | |
| "issue view"|"issue list"|"search issues"|"label list") | |
| ;; | |
| *) | |
| echo "Error: only 'issue view', 'issue list', 'search issues', 'label list' are allowed (e.g., ./scripts/gh.sh issue view 123)" >&2 | |
| exit 1 | |
| ;; | |
| esac | |
| shift 2 | |
| # Separate flags from positional arguments | |
| POSITIONAL=() | |
| FLAGS=() | |
| skip_next=false | |
| for arg in "$@"; do | |
| if [[ "$skip_next" == true ]]; then | |
| FLAGS+=("$arg") | |
| skip_next=false | |
| elif [[ "$arg" == -* ]]; then | |
| flag="${arg%%=*}" | |
| matched=false | |
| for allowed in "${ALLOWED_FLAGS[@]}"; do | |
| if [[ "$flag" == "$allowed" ]]; then | |
| matched=true | |
| break | |
| fi | |
| done | |
| if [[ "$matched" == false ]]; then | |
| echo "Error: only --comments, --state, --limit, --label flags are allowed (e.g., ./scripts/gh.sh issue list --state open --limit 20)" >&2 | |
| exit 1 | |
| fi | |
| FLAGS+=("$arg") | |
| # If flag expects a value and isn't using = syntax, skip next arg | |
| if [[ "$arg" != *=* ]]; then | |
| for vflag in "${FLAGS_WITH_VALUES[@]}"; do | |
| if [[ "$flag" == "$vflag" ]]; then | |
| skip_next=true | |
| break | |
| fi | |
| done | |
| fi | |
| else | |
| POSITIONAL+=("$arg") | |
| fi | |
| done | |
| if [[ "$CMD" == "search issues" ]]; then | |
| QUERY="${POSITIONAL[0]:-}" | |
| QUERY_LOWER=$(echo "$QUERY" | tr '[:upper:]' '[:lower:]') | |
| if [[ "$QUERY_LOWER" == *"repo:"* || "$QUERY_LOWER" == *"org:"* || "$QUERY_LOWER" == *"user:"* ]]; then | |
| echo "Error: search query must not contain repo:, org:, or user: qualifiers (e.g., ./scripts/gh.sh search issues \"bug report\" --limit 10)" >&2 | |
| exit 1 | |
| fi | |
| gh "$SUB1" "$SUB2" "$QUERY" --repo "$REPO" "${FLAGS[@]}" | |
| elif [[ "$CMD" == "issue view" ]]; then | |
| if [[ ${#POSITIONAL[@]} -ne 1 ]] || ! [[ "${POSITIONAL[0]}" =~ ^[0-9]+$ ]]; then | |
| echo "Error: issue view requires exactly one numeric issue number (e.g., ./scripts/gh.sh issue view 123)" >&2 | |
| exit 1 | |
| fi | |
| gh "$SUB1" "$SUB2" "${POSITIONAL[0]}" "${FLAGS[@]}" | |
| else | |
| if [[ ${#POSITIONAL[@]} -ne 0 ]]; then | |
| echo "Error: issue list and label list do not accept positional arguments (e.g., ./scripts/gh.sh issue list --state open, ./scripts/gh.sh label list --limit 100)" >&2 | |
| exit 1 | |
| fi | |
| gh "$SUB1" "$SUB2" "${FLAGS[@]}" | |
| fi | |