main
1#!/usr/bin/env bash
2# Review a GitHub PR/issue with an AI tool on a remote machine via shpool
3# Usage: gh-news-review [-d|--detach] [-y|--yolo] [-t|--tool TOOL] <url>
4# -d, --detach Start session in background and return immediately
5# -y, --yolo Skip permission prompts (auto-accept all tool calls)
6# -t, --tool TOOL AI tool to use: claude, pi (default: claude)
7
8set -euo pipefail
9
10DETACH=false
11YOLO=false
12TOOL="claude"
13
14while [[ $# -gt 0 ]]; do
15 case "$1" in
16 -d | --detach)
17 DETACH=true
18 shift
19 ;;
20 -y | --yolo)
21 YOLO=true
22 shift
23 ;;
24 -t | --tool)
25 TOOL="$2"
26 shift 2
27 ;;
28 -*)
29 echo "Unknown option: $1" >&2
30 echo "Usage: gh-news-review [-d|--detach] [-y|--yolo] [-t|--tool TOOL] <url>" >&2
31 exit 1
32 ;;
33 *)
34 break
35 ;;
36 esac
37done
38
39URL="${1:-}"
40if [[ -z "$URL" ]]; then
41 echo "Usage: gh-news-review [-d|--detach] [-y|--yolo] [-t|--tool TOOL] <url>" >&2
42 exit 1
43fi
44
45# Validate tool
46case "$TOOL" in
47claude | pi) ;;
48*)
49 echo "Error: Invalid tool '$TOOL'. Must be one of: claude, pi" >&2
50 exit 1
51 ;;
52esac
53
54# Extract session name from URL (e.g., pull-123 or issues-456)
55SESSION_NAME="${TOOL}-review-$(echo "$URL" | grep -oE '(pull|issues)/[0-9]+' | tr '/' '-')"
56
57if [[ -z "$SESSION_NAME" || "$SESSION_NAME" == "${TOOL}-review-" ]]; then
58 echo "Error: Could not extract PR/issue number from URL: $URL" >&2
59 exit 1
60fi
61
62# Detect if this is a nixpkgs PR for more specific instructions
63IS_NIXPKGS=false
64if [[ "$URL" == *"NixOS/nixpkgs"* ]]; then
65 IS_NIXPKGS=true
66fi
67
68# Build the prompt based on the type of review
69if [[ "$IS_NIXPKGS" == "true" ]]; then
70 case "$TOOL" in
71 claude)
72 PROMPT="Review $URL using the Nixpkgs skill (~/.config/claude/skills), and the Review workflow. Use GPT-5.2-Codex or Opus 4.5 model if available.
73
74For nixpkgs PRs:
751. Load and follow the Nixpkgs skill workflow
762. Use nixpkgs-review to build and test the changes when appropriate
773. When approving, use a concise message (e.g., 'LGTM, tested with nixpkgs-review')
784. If I'm a maintainer of the touched packages, use the auto-merge-pr script to build, approve, and trigger merge-bot
79
80At the end, save the session (in ~/.config/claude/history/sessions/)"
81 ;;
82 pi)
83 PROMPT="Review $URL using the Nixpkgs skill (~/.config/claude/skills), and the Review workflow. Use GPT-5.2-Codex or Opus 4.5 model if available.
84
85For nixpkgs PRs:
861. Load and follow the Nixpkgs skill workflow
872. Use nixpkgs-review to build and test the changes when appropriate
883. When approving, use a concise message (e.g., 'LGTM, tested with nixpkgs-review')
894. If I'm a maintainer of the touched packages, use the auto-merge-pr script to build, approve, and trigger merge-bot
90
91At the end, save the session (in ~/.config/claude/history/sessions/) with the command /save-session"
92 ;;
93 esac
94else
95 case "$TOOL" in
96 claude)
97 PROMPT="Review $URL, and load the proper skill as needed (e.g. nixpkgs skills and workflows if it is a pr from NixOS/nixpkgs)"
98 ;;
99 pi)
100 PROMPT="Review $URL, and load the proper skill as needed (e.g. nixpkgs skills and workflows if it is a pr from NixOS/nixpkgs)"
101 ;;
102 esac
103fi
104
105# Build command based on tool and optional yolo mode
106case "$TOOL" in
107claude)
108 AI_CMD="cr"
109 if [[ "$YOLO" == "true" ]]; then
110 AI_CMD="cr --dangerously-skip-permissions"
111 fi
112 ;;
113pi)
114 AI_CMD="pi"
115 if [[ "$YOLO" == "true" ]]; then
116 AI_CMD="pi --dangerously-skip-permissions"
117 fi
118 ;;
119esac
120
121# Encode prompt in base64 to avoid all quoting issues
122PROMPT_B64=$(printf '%s' "$PROMPT" | base64 -w0)
123
124if [[ "$DETACH" == "true" ]]; then
125 # Write a temp script on remote and execute it in shpool
126 # Using heredoc avoids all nested quoting issues
127 # shellcheck disable=SC2029,SC2087 # Intentional client-side expansion
128 ssh aomi.sbr.pm "cat > /tmp/review-cmd-$SESSION_NAME.sh && chmod +x /tmp/review-cmd-$SESSION_NAME.sh && nohup shpool attach -f -c '/run/current-system/sw/bin/bash -l /tmp/review-cmd-$SESSION_NAME.sh' $SESSION_NAME > /dev/null 2>&1 &" <<EOF
129cd ~/src/nixpkgs
130$AI_CMD "\$(echo '$PROMPT_B64' | base64 -d)"
131EOF
132 echo "Started review session: $SESSION_NAME (using $TOOL)"
133 echo "Attach with: ssh -t aomi.sbr.pm 'shpool attach $SESSION_NAME'"
134else
135 # Interactive: write temp script and run
136 # shellcheck disable=SC2029,SC2087 # Intentional client-side expansion
137 ssh aomi.sbr.pm "cat > /tmp/review-cmd-$SESSION_NAME.sh && chmod +x /tmp/review-cmd-$SESSION_NAME.sh" <<EOF
138cd ~/src/nixpkgs
139$AI_CMD "\$(echo '$PROMPT_B64' | base64 -d)"
140EOF
141 exec ssh -t aomi.sbr.pm "shpool attach -f -c '/run/current-system/sw/bin/bash -l /tmp/review-cmd-$SESSION_NAME.sh' $SESSION_NAME"
142fi