mirror of
https://github.com/Significant-Gravitas/AutoGPT.git
synced 2026-04-08 03:00:28 -04:00
## Summary - Adds `/pr-test` skill for automated E2E testing of PRs using docker compose, agent-browser, and API calls - Covers full environment setup (copy .env, configure copilot auth, ARM64 Docker fix) - Includes browser UI testing, direct API testing, screenshot capture, and test report generation - Has `--fix` mode for auto-fixing bugs found during testing (similar to `/pr-address`) - **Screenshot uploads use GitHub Git API** (blobs → tree → commit → ref) — no local git operations, safe for worktrees - **Subscription mode improvements:** - Extract subscription auth logic to `sdk/subscription.py` — uses SDK's bundled CLI binary instead of requiring `npm install -g @anthropic-ai/claude-code` - Auto-provision `~/.claude/.credentials.json` from `CLAUDE_CODE_OAUTH_TOKEN` env var on container startup — no `claude login` needed in Docker - Add `scripts/refresh_claude_token.sh` — cross-platform helper (macOS/Linux/Windows) to extract OAuth tokens from host and update `backend/.env` ## Test plan - [x] Validated skill on multiple PRs (#12482, #12483, #12499, #12500, #12501, #12440, #12472) — all test scenarios passed - [x] Confirmed screenshot upload via GitHub Git API renders correctly on all 7 PRs - [x] Verified subscription mode E2E in Docker: `refresh_claude_token.sh` → `docker compose up` → copilot chat responds correctly with no API keys (pure OAuth subscription) - [x] Verified auto-provisioning of credentials file inside container from `CLAUDE_CODE_OAUTH_TOKEN` env var - [x] Confirmed bundled CLI detection (`claude_agent_sdk._bundled/claude`) works without system-installed `claude` - [x] `poetry run pytest backend/copilot/sdk/service_test.py` — 24/24 tests pass
124 lines
3.9 KiB
Bash
Executable File
124 lines
3.9 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# refresh_claude_token.sh — Extract Claude OAuth tokens and update backend/.env
|
|
#
|
|
# Works on macOS (keychain), Linux (~/.claude/.credentials.json),
|
|
# and Windows/WSL (~/.claude/.credentials.json or PowerShell fallback).
|
|
#
|
|
# Usage:
|
|
# ./scripts/refresh_claude_token.sh # auto-detect OS
|
|
# ./scripts/refresh_claude_token.sh --env-file /path/to/.env # custom .env path
|
|
#
|
|
# Prerequisite: You must have run `claude login` at least once on the host.
|
|
|
|
set -euo pipefail
|
|
|
|
# --- Parse arguments ---
|
|
ENV_FILE=""
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
--env-file) ENV_FILE="$2"; shift 2 ;;
|
|
*) echo "Unknown option: $1"; exit 1 ;;
|
|
esac
|
|
done
|
|
|
|
# Default .env path: relative to this script's location
|
|
if [[ -z "$ENV_FILE" ]]; then
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
ENV_FILE="$SCRIPT_DIR/../.env"
|
|
fi
|
|
|
|
# --- Extract tokens by platform ---
|
|
ACCESS_TOKEN=""
|
|
REFRESH_TOKEN=""
|
|
|
|
extract_from_credentials_file() {
|
|
local creds_file="$1"
|
|
if [[ -f "$creds_file" ]]; then
|
|
ACCESS_TOKEN=$(jq -r '.claudeAiOauth.accessToken // ""' "$creds_file" 2>/dev/null)
|
|
REFRESH_TOKEN=$(jq -r '.claudeAiOauth.refreshToken // ""' "$creds_file" 2>/dev/null)
|
|
fi
|
|
}
|
|
|
|
case "$(uname -s)" in
|
|
Darwin)
|
|
# macOS: extract from system keychain
|
|
CREDS_JSON=$(security find-generic-password -s "Claude Code-credentials" -w 2>/dev/null || true)
|
|
if [[ -n "$CREDS_JSON" ]]; then
|
|
ACCESS_TOKEN=$(echo "$CREDS_JSON" | jq -r '.claudeAiOauth.accessToken // ""' 2>/dev/null)
|
|
REFRESH_TOKEN=$(echo "$CREDS_JSON" | jq -r '.claudeAiOauth.refreshToken // ""' 2>/dev/null)
|
|
else
|
|
# Fallback to credentials file (e.g. if keychain access denied)
|
|
extract_from_credentials_file "$HOME/.claude/.credentials.json"
|
|
fi
|
|
;;
|
|
Linux)
|
|
# Linux (including WSL): read from credentials file
|
|
extract_from_credentials_file "$HOME/.claude/.credentials.json"
|
|
;;
|
|
MINGW*|MSYS*|CYGWIN*)
|
|
# Windows Git Bash / MSYS2 / Cygwin
|
|
APPDATA_PATH="${APPDATA:-$USERPROFILE/AppData/Roaming}"
|
|
extract_from_credentials_file "$APPDATA_PATH/claude/.credentials.json"
|
|
# Fallback to home dir
|
|
if [[ -z "$ACCESS_TOKEN" ]]; then
|
|
extract_from_credentials_file "$HOME/.claude/.credentials.json"
|
|
fi
|
|
;;
|
|
*)
|
|
echo "Unsupported platform: $(uname -s)"
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
# --- Validate ---
|
|
if [[ -z "$ACCESS_TOKEN" ]]; then
|
|
echo "ERROR: Could not extract Claude OAuth token."
|
|
echo ""
|
|
echo "Make sure you have run 'claude login' at least once."
|
|
echo ""
|
|
echo "Locations checked:"
|
|
echo " macOS: Keychain ('Claude Code-credentials')"
|
|
echo " Linux: ~/.claude/.credentials.json"
|
|
echo " Windows: %APPDATA%/claude/.credentials.json"
|
|
exit 1
|
|
fi
|
|
|
|
echo "Found Claude OAuth token: ${ACCESS_TOKEN:0:20}..."
|
|
[[ -n "$REFRESH_TOKEN" ]] && echo "Found refresh token: ${REFRESH_TOKEN:0:20}..."
|
|
|
|
# --- Update .env file ---
|
|
update_env_var() {
|
|
local key="$1" value="$2" file="$3"
|
|
if grep -q "^${key}=" "$file" 2>/dev/null; then
|
|
# Replace existing value (works on both macOS and Linux sed)
|
|
if [[ "$(uname -s)" == "Darwin" ]]; then
|
|
sed -i '' "s|^${key}=.*|${key}=${value}|" "$file"
|
|
else
|
|
sed -i "s|^${key}=.*|${key}=${value}|" "$file"
|
|
fi
|
|
elif grep -q "^# *${key}=" "$file" 2>/dev/null; then
|
|
# Uncomment and set
|
|
if [[ "$(uname -s)" == "Darwin" ]]; then
|
|
sed -i '' "s|^# *${key}=.*|${key}=${value}|" "$file"
|
|
else
|
|
sed -i "s|^# *${key}=.*|${key}=${value}|" "$file"
|
|
fi
|
|
else
|
|
# Append
|
|
echo "${key}=${value}" >> "$file"
|
|
fi
|
|
}
|
|
|
|
if [[ ! -f "$ENV_FILE" ]]; then
|
|
echo "WARNING: $ENV_FILE does not exist, creating it."
|
|
touch "$ENV_FILE"
|
|
fi
|
|
|
|
update_env_var "CLAUDE_CODE_OAUTH_TOKEN" "$ACCESS_TOKEN" "$ENV_FILE"
|
|
[[ -n "$REFRESH_TOKEN" ]] && update_env_var "CLAUDE_CODE_REFRESH_TOKEN" "$REFRESH_TOKEN" "$ENV_FILE"
|
|
update_env_var "CHAT_USE_CLAUDE_CODE_SUBSCRIPTION" "true" "$ENV_FILE"
|
|
|
|
echo ""
|
|
echo "Updated $ENV_FILE with Claude subscription tokens."
|
|
echo "Run 'docker compose up -d copilot_executor' to apply."
|