Created
September 11, 2025 19:05
-
-
Save wookiehangover/7554f60b1ba044816c3a245dfff7cec7 to your computer and use it in GitHub Desktop.
Revisions
-
wookiehangover created this gist
Sep 11, 2025 .There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,210 @@ #!/bin/bash # Exit if no prompt is provided if [ -z "$1" ]; then echo "Usage: $0 <your instruction for a shell command>" exit 1 fi # --- Configuration --- # TODO: Replace with your actual Anthropic API key TOKEN="" MODEL="claude-sonnet-4-20250514" MAX_TOKENS=1024 # --- Platform Detection --- detect_platform() { case "$(uname -s)" in Darwin*) echo "macOS" ;; Linux*) if [ -f /etc/os-release ]; then . /etc/os-release echo "$NAME" else echo "Linux" fi ;; CYGWIN*|MINGW*|MSYS*) echo "Windows" ;; *) echo "Unix-like" ;; esac } PLATFORM=$(detect_platform) # --- Prompt --- # A clear system prompt for the AI PROMPT="You are an expert at writing shell commands for $PLATFORM. Your responses must contain ONLY the shell command(s). Do not include any explanations, introductory text, or markdown formatting. The commands should be separated by semicolons if there are multiple. Here is the task: $@" # --- Build JSON Payload Safely --- # Use jq to handle special characters in the prompt and prevent JSON errors JSON_PAYLOAD=$(jq -n \ --arg model "$MODEL" \ --arg prompt "$PROMPT" \ --argjson max_tokens "$MAX_TOKENS" \ '{ "model": $model, "max_tokens": $max_tokens, "messages": [{"role": "user", "content": $prompt}] }') # --- Loading Spinner Function --- show_spinner() { local pid=$1 local delay=0.1 local spinstr='|/-\' tput civis # Hide cursor while [ "$(ps a | awk '{print $1}' | grep $pid)" ]; do local temp=${spinstr#?} printf "\r\033[1;34m[%c] Waiting for Claude to respond...\033[0m" "$spinstr" local spinstr=$temp${spinstr%"$temp"} sleep $delay done printf "\r\033[K" # Clear line tput cnorm # Show cursor } # --- Retry Function --- retry_with_error() { local failed_command="$1" local error_output="$2" local exit_code="$3" # Build retry prompt with error context RETRY_PROMPT="You are an expert at writing shell commands for $PLATFORM. The previous command failed. Please provide a corrected command. Previous command: $failed_command Exit code: $exit_code Error output: $error_output Your response must contain ONLY the corrected shell command(s). Do not include any explanations, introductory text, or markdown formatting." # Build JSON payload for retry RETRY_JSON_PAYLOAD=$(jq -n \ --arg model "$MODEL" \ --arg prompt "$RETRY_PROMPT" \ --argjson max_tokens "$MAX_TOKENS" \ '{ "model": $model, "max_tokens": $max_tokens, "messages": [{"role": "user", "content": $prompt}] }') echo "" echo "Sending error context to Claude..." curl -s -X POST "https://api.anthropic.com/v1/messages" \ -H "x-api-key: $TOKEN" \ -H "anthropic-version: 2023-06-01" \ -H "content-type: application/json" \ -d "$RETRY_JSON_PAYLOAD" > /tmp/claude_retry_response.json & # Show spinner while waiting for retry response show_spinner $! wait $! # Parse the retry response RETRY_RESULT=$(jq -r '.content[0].text // .error.message // "Error: Could not parse API response."' /tmp/claude_retry_response.json) rm -f /tmp/claude_retry_response.json # Check for errors from the API call if [[ "$RETRY_RESULT" == "Error:"* ]]; then echo "$RETRY_RESULT" return 1 fi # Display the corrected command echo "" echo "┌─────────────────────────────────────────────────────────────────┐" echo "│ Corrected Command │" echo "├─────────────────────────────────────────────────────────────────┤" # Split commands by semicolon and display each on its own line IFS=';' read -ra RETRY_COMMANDS <<< "$RETRY_RESULT" for cmd in "${RETRY_COMMANDS[@]}"; do cmd=$(echo "$cmd" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//') if [ -n "$cmd" ]; then printf "│ \033[1;32m%s\033[0m\n" "$cmd" fi done echo "└─────────────────────────────────────────────────────────────────┘" echo "" read -rp "Execute corrected command? (y/N): " retry_exec_input if [[ "${retry_exec_input:0:1}" =~ ^[Yy]$ ]]; then echo "Executing corrected command..." bash -c "$RETRY_RESULT" else echo "Execution cancelled." fi } # --- API Call --- # Call the Anthropic API and parse the response with jq echo "Sending request to Claude..." curl -s -X POST "https://api.anthropic.com/v1/messages" \ -H "x-api-key: $TOKEN" \ -H "anthropic-version: 2023-06-01" \ -H "content-type: application/json" \ -d "$JSON_PAYLOAD" > /tmp/claude_response.json & # Show spinner while waiting for response show_spinner $! wait $! # Parse the response RESULT=$(jq -r '.content[0].text // .error.message // "Error: Could not parse API response."' /tmp/claude_response.json) rm -f /tmp/claude_response.json # --- User Confirmation --- # Check for errors from the API call if [[ "$RESULT" == "Error:"* ]]; then echo "$RESULT" exit 1 fi # Display the command with improved formatting echo "" echo "┌─────────────────────────────────────────────────────────────────┐" echo "│ Suggested Command │" echo "├─────────────────────────────────────────────────────────────────┤" # Split commands by semicolon and display each on its own line with syntax highlighting IFS=';' read -ra COMMANDS <<< "$RESULT" for cmd in "${COMMANDS[@]}"; do # Trim whitespace cmd=$(echo "$cmd" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//') if [ -n "$cmd" ]; then printf "│ \033[1;36m%s\033[0m\n" "$cmd" fi done echo "└─────────────────────────────────────────────────────────────────┘" echo "" read -rp "Execute? (y/N): " input_var if [[ "${input_var:0:1}" =~ ^[Yy]$ ]]; then echo "Executing..." # Execute the command and capture both stdout and stderr EXEC_OUTPUT=$(bash -c "$RESULT" 2>&1) EXIT_CODE=$? # Show the output if [ -n "$EXEC_OUTPUT" ]; then echo "$EXEC_OUTPUT" fi # If command failed, offer to retry with error context if [ $EXIT_CODE -ne 0 ]; then echo "" echo -e "\033[1;31mCommand failed with exit code $EXIT_CODE\033[0m" read -rp "Send error back to Claude to try again? (y/N): " retry_input if [[ "${retry_input:0:1}" =~ ^[Yy]$ ]]; then retry_with_error "$RESULT" "$EXEC_OUTPUT" "$EXIT_CODE" fi fi else echo "Execution cancelled." fi