Created
September 11, 2025 19:05
-
-
Save wookiehangover/7554f60b1ba044816c3a245dfff7cec7 to your computer and use it in GitHub Desktop.
god mode for bash via claude
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
#!/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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment