Last active
October 9, 2025 12:14
-
-
Save roelven/6401c428c69fb2549c7b75c72fb2dbe9 to your computer and use it in GitHub Desktop.
Prompt my prompt: a Raycast script to improve your prompts.
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 | |
| # Required parameters: | |
| # @raycast.schemaVersion 1 | |
| # @raycast.title Prompt my prompt | |
| # @raycast.mode silent | |
| # Optional parameters: | |
| # @raycast.icon 🤖 | |
| # @raycast.packageName Prompt Tools | |
| # Documentation: | |
| # @raycast.description Analyzes a human-written prompt and rewrites it for clarity and deeper reasoning. Output is the improved prompt only. | |
| # @raycast.author Roel van der Ven | |
| # @raycast.authorURL https://roelvanderven.com | |
| # Requires the Raycast Notification extension to be installed: | |
| # https://www.raycast.com/maxnyby/raycast-notification | |
| # CONFIGURATION | |
| OPENAI_API_KEY="YOUR_OPENAI_API_KEY" | |
| MODEL="gpt-5-mini" | |
| TEMPERATURE=1 | |
| LOGGING_ENABLED=true | |
| LOGFILE="/tmp/prompt_improver_log.txt" | |
| # PROGRESS / NOTIFICATIONS | |
| # - Uses Raycast HUD via "Raycast Notification" extension if available: | |
| # https://www.raycast.com/maxnyby/raycast-notification | |
| # - Falls back to macOS Notification Center if HUD isn't available. | |
| NOTIFY_MODE="${NOTIFY_MODE:-hud}" # hud|native|none | |
| PROGRESS_INTERVAL="${PROGRESS_INTERVAL:-1}" # seconds between spinner updates | |
| SPINNER_FRAMES=(⠋ ⠙ ⠹ ⠸ ⠼ ⠴ ⠦ ⠧ ⠇ ⠏) | |
| SPINNER_PID="" | |
| SPINNER_RUNNING=0 | |
| notify_hud() { | |
| local text="$1" | |
| # Build deeplink: raycast://extensions/maxnyby/raycast-notification/... | |
| local args_json encoded | |
| args_json=$(jq -n --arg title "$text" '{title: $title}') | |
| encoded=$(printf "%s" "$args_json" | jq -r @uri) | |
| open -g "raycast://extensions/maxnyby/raycast-notification/index?launchType=background&arguments=$encoded" >/dev/null 2>&1 | |
| return $? | |
| } | |
| notify_native() { | |
| local text="$1" | |
| # Escape for AppleScript | |
| local esc | |
| esc=$(printf "%s" "$text" | sed 's/\\/\\\\/g; s/"/\\"/g') | |
| osascript -e "display notification \"$esc\" with title \"Prompt Improver\"" | |
| } | |
| notify() { | |
| local text="$1" | |
| case "$NOTIFY_MODE" in | |
| hud) | |
| notify_hud "$text" || notify_native "$text" | |
| ;; | |
| native) | |
| notify_native "$text" | |
| ;; | |
| *) | |
| ;; # none | |
| esac | |
| } | |
| start_spinner() { | |
| SPINNER_RUNNING=1 | |
| ( | |
| local i=0 | |
| while [ "$SPINNER_RUNNING" -eq 1 ]; do | |
| local frame="${SPINNER_FRAMES[$(( i % ${#SPINNER_FRAMES[@]} ))]}" | |
| notify "$frame Improving prompt…" | |
| sleep "$PROGRESS_INTERVAL" | |
| i=$((i+1)) | |
| done | |
| ) & | |
| SPINNER_PID=$! | |
| } | |
| stop_spinner() { | |
| if [ -n "$SPINNER_PID" ]; then | |
| SPINNER_RUNNING=0 | |
| kill "$SPINNER_PID" >/dev/null 2>&1 | |
| wait "$SPINNER_PID" 2>/dev/null | |
| SPINNER_PID="" | |
| fi | |
| } | |
| # Ensure spinner is stopped on any exit | |
| cleanup() { stop_spinner; } | |
| trap cleanup EXIT | |
| # Read clipboard | |
| INPUT=$(pbpaste) | |
| # Validate input | |
| if [[ -z "$INPUT" ]]; then | |
| echo "❌ Skipped: clipboard is empty" | |
| exit 0 | |
| fi | |
| # Skip if single token (alnum only) | |
| if [[ "$INPUT" =~ ^[[:alnum:]]+$ ]]; then | |
| echo "❌ Skipped: single word detected" | |
| exit 0 | |
| fi | |
| # Skip if hash-like | |
| if [[ "$INPUT" =~ ^[a-f0-9]{4,}-[a-f0-9]{4,}-[a-f0-9]{4,}$ ]]; then | |
| echo "❌ Skipped: hash-like pattern detected" | |
| exit 0 | |
| fi | |
| if [ "$LOGGING_ENABLED" = true ]; then | |
| { | |
| echo "--- $(date) ---" | |
| echo "Clipboard:" | |
| echo "$INPUT" | |
| } >> "$LOGFILE" | |
| fi | |
| # Build the system prompt (no shell expansion) | |
| read -r -d '' SYSTEM_PROMPT <<'SYS' | |
| You are a prompt evaluator–improver used in a one-step workflow. You will receive a human-written prompt between <HUMAN_PROMPT> ... </HUMAN_PROMPT>. Your job is to rewrite it into a clearer, more rigorous prompt for a reasoning LLM (works with GPT-5, Claude Sonnet 4.5, Gemini 2.5 Pro). | |
| Rules: | |
| - Interpret the enclosed text as the user's intended task prompt. | |
| - Preserve the original intent, constraints, domain specifics, examples, and tone unless they hinder clarity. | |
| - Remove redundancy, fix ambiguities, and add only what improves reasoning quality and output reliability. | |
| - If critical details are missing, include square-bracketed placeholders like [SPECIFY: target audience], not assumptions; otherwise state a brief “Assumptions” line. | |
| - Make the result standalone and ready to paste; avoid any meta commentary, analysis, or markdown fences in your output. | |
| - Output ONLY the improved prompt text—no headings like “Improved Prompt”, no notes, no backticks. | |
| When rewriting, optimize for: | |
| - Reasoning clarity and depth: unambiguous objective, explicit constraints, and a compact plan of attack. | |
| - Verifiability: success criteria and checks the model should perform silently before finalizing. | |
| - Deterministic output: specify structure/format if absent (prefer concise markdown or JSON with clear fields). | |
| - Safety and fidelity: do not invent unknown facts; keep proprietary or sensitive items as placeholders. | |
| Rewrite the input into this structure (omit sections that don’t apply; keep wording tight): | |
| 1) Objective: <single clear sentence capturing the user’s goal>. | |
| 2) Context/Inputs: <key facts, data, examples; keep code blocks/examples if present>. | |
| 3) Requirements & Constraints: <bullets—all must/should/must-not>. | |
| 4) Approach: <succinct stepwise plan to solve/decide; consider edge cases>. | |
| 5) Output Format: <exact schema or markdown sections to return>. | |
| 6) Assumptions (only if needed): <short list>. | |
| Before producing the final text, internally check: | |
| - Is the task solvable with given info? | |
| - Are steps logically ordered and minimal? | |
| - Are acceptance criteria and output format explicit? | |
| Return ONLY the final improved prompt text. | |
| SYS | |
| # Wrap clipboard content with tags | |
| USER_WITH_TAGS=$(printf "<HUMAN_PROMPT>\n%s\n</HUMAN_PROMPT>" "$INPUT") | |
| # Build JSON body with jq to ensure proper escaping | |
| BODY=$(jq -n \ | |
| --arg model "$MODEL" \ | |
| --arg sys "$SYSTEM_PROMPT" \ | |
| --arg user "$USER_WITH_TAGS" \ | |
| --argjson temperature "$TEMPERATURE" \ | |
| '{ | |
| model: $model, | |
| messages: [ | |
| {role: "system", content: $sys}, | |
| {role: "user", content: $user} | |
| ], | |
| temperature: $temperature | |
| }') | |
| # Start non-blocking spinner | |
| start_spinner | |
| # API request | |
| RESPONSE=$(curl -s https://api.openai.com/v1/chat/completions \ | |
| -H "Authorization: Bearer $OPENAI_API_KEY" \ | |
| -H "Content-Type: application/json" \ | |
| -d "$BODY") | |
| # Stop spinner before parsing/echoing | |
| stop_spinner | |
| if [ "$LOGGING_ENABLED" = true ]; then | |
| { | |
| echo "Response:" | |
| echo "$RESPONSE" | |
| } >> "$LOGFILE" | |
| fi | |
| # Check for API error | |
| if echo "$RESPONSE" | grep -q '"error"'; then | |
| ERROR_MSG=$(echo "$RESPONSE" | jq -r '.error.message // "Unknown error"') | |
| [ "$LOGGING_ENABLED" = true ] && echo "API error: $ERROR_MSG" >> "$LOGFILE" | |
| notify "⚠️ Prompt improvement failed: $ERROR_MSG" | |
| echo "⚠️ Prompt improvement failed. \"API Error: $ERROR_MSG\" with title \"OpenAI Error\"" | |
| exit 1 | |
| fi | |
| # Extract improved prompt | |
| IMPROVED=$(echo "$RESPONSE" | jq -r '.choices[0].message.content') | |
| if [ "$LOGGING_ENABLED" = true ]; then | |
| { | |
| echo "Parsed result:" | |
| echo "$IMPROVED" | |
| } >> "$LOGFILE" | |
| fi | |
| # Handle null output | |
| if [ "$IMPROVED" == "null" ] || [ -z "$IMPROVED" ]; then | |
| notify "No output produced" | |
| echo "No output produced" | |
| exit 1 | |
| fi | |
| # Copy to clipboard and notify | |
| printf "%s" "$IMPROVED" | pbcopy | |
| notify "✅ Improved! Prompt copied" | |
| echo "Improved! Prompt copied ☑️" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment