agentleFS
bongartzdiazbongartzdiaz/agent-skills/skills/ray-so-code-snippet/SKILL.md

ray-so-code-snippet

Skill0 starsChanged 10 months agoCC0-1.0View on GitHub

Generate beautiful code snippet images using ray.so. This skill should be used when the user asks to create a code image, code screenshot, code snippet image, or wants to make their code look pretty for sharing. Saves images locally to the current working directory or a user-specified path.

The file

Show its rules and text

We split this skill into the rules it gives an agent

21 rules. About 0 are common, 12 are distinctive, and 9 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈12

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 9

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    MUST ask the user for ALL styling parameters before generating, presenting ALL available options

    line 13
  2. Very specific:

    MUST use agent-browser for screenshot capture (check availability first)

    line 14
  3. Very specific:

    Before proceeding, verify that agent-browser is available:

    line 20
  4. Very specific:

    If agent-browser is not found in the PATH, inform the user that this skill requires agent-browser and cannot proceed without it.

    line 26
  5. Distinctive:

    MUST use AskUserQuestion to ask for EVERY parameter, presenting ALL available options.

    line 42
  6. Distinctive:

    Only ask this question if the language cannot be confidently inferred:

    line 66
  7. Very specific:

    Note on width: Do NOT include the width parameter unless you specifically need a fixed width.

    line 165
  8. Very specific:

    MUST use agent-browser (verified in Step 1).

    line 183
  9. Very specific:

    IMPORTANT: Always use a unique session name with --session to avoid stale session issues.

    line 185
  10. Distinctive:

    No ImageMagick required - pure browser-based rendering at high resolution

    line 222
  11. Very specific:

    Check which agent-browser - confirmed available

    line 240
  12. Distinctive:

    Ask user for parameters via AskUserQuestion:

    line 247
  13. Distinctive:

    Default: 4x native resolution (frame auto-sizes to content, then rendered at 4x)

    line 296
  14. Distinctive:

    No unnecessary empty space (frame auto-sizes to fit code)

    line 299
  15. Very specific:

    Only add &width=NUMBER to the URL if you need a fixed width (e.g., for consistent sizing across multiple images)

    line 306
  16. Distinctive:

    If curl fails to fetch themes/languages, use these common defaults:

    line 311
  17. Distinctive:

    If parameters aren't applied: Ensure ALL parameters are in the URL hash (after #), not the query string

    line 314
  18. Distinctive:

    If html-to-image fails to load: Check network connectivity.

    line 316
  19. Distinctive:

    If the page doesn't load properly, increase the wait time (try 4000ms or more)

    line 319
  20. Very specific:

    If you get a blank page: Use a fresh unique session name with --session flag

    line 320
  21. Distinctive:

    If data URL is malformed: Ensure quotes and newlines are stripped before base64 decoding

    line 321

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

ray.so Code Snippet Image Generator

Generate beautiful code snippet images using ray.so and save them locally.

Requirements

  • The user MUST provide the code snippet, either directly or by pointing to a file/selection in context
  • MUST ask the user for ALL styling parameters before generating, presenting ALL available options
  • MUST use agent-browser for screenshot capture (check availability first)

Workflow

Step 1: Verify agent-browser Availability

Before proceeding, verify that agent-browser is available:

which agent-browser

If agent-browser is not found in the PATH, inform the user that this skill requires agent-browser and cannot proceed without it.

Step 2: Fetch Available Options

Fetch the current themes and languages from ray.so's GitHub repository using curl:

# Fetch and parse available themes
curl -s "https://raw.githubusercontent.com/raycast/ray-so/main/app/(navigation)/(code)/store/themes.ts" | grep -oE 'id:\s*"[^"]+"' | sed 's/id:\s*"//;s/"//' | sort -u

# Fetch and parse available languages
curl -s "https://raw.githubusercontent.com/raycast/ray-so/main/app/(navigation)/(code)/util/languages.ts" | grep -oE '^[[:space:]]*"?[a-zA-Z0-9+#-]+"?\s*:\s*\{' | sed 's/[[:space:]]*"//g;s/".*//;s/:.*//' | sort -u

Step 3: Ask User for ALL Parameters

MUST use AskUserQuestion to ask for EVERY parameter, presenting ALL available options. Ask for parameters in this order:

3.1 Theme Selection

Present ALL available themes. In the question, list every theme fetched from step 2. Example:

Question: "Which theme would you like?"
Description: "Available themes: [list ALL themes from curl output]"
Options (pick 4 popular ones for quick select):
- breeze (default, purple gradient)
- midnight (cyan-blue)
- vercel (minimalist dark)
- sunset (warm orange)
Note: User can select "Other" to type any theme from the full list

3.2 Language Selection

Infer the language when possible. Skip this question if:

  • The user explicitly specified a language
  • The code comes from a file with a clear extension (e.g., .py → python, .js → javascript, .ts → typescript, .rs → rust, .go → go, etc.)
  • The syntax is unmistakably identifiable (e.g., def/import → python, func/package → go, fn/let mut → rust)

Only ask this question if the language cannot be confidently inferred:

Question: "Which language for syntax highlighting?"
Description: "Available languages: [list ALL languages from curl output]"
Options:
- auto (auto-detect)
- javascript
- python
- typescript
Note: User can select "Other" to type any language from the full list

3.3 Dark/Light Mode

Question: "Dark or light mode?"
Options:
- Dark mode (default)
- Light mode

3.4 Background

Question: "Show the gradient background?"
Options:
- Yes, show background (default)
- No, transparent/minimal background

3.5 Padding

Question: "How much padding around the code?"
Options:
- 16 (compact)
- 32 (small)
- 64 (medium, default)
- 128 (large)

3.6 Line Numbers

Question: "Show line numbers?"
Options:
- No (default)
- Yes

3.7 Title

Question: "Add a title above the code? (e.g., filename)"
Options:
- No title (default)
- Yes, add title
If yes, ask for the title text.

Note: Do NOT ask about output path/filename. Save to the current working directory with a sensible filename (e.g., rayso-snippet.png, or based on the title if provided like fibonacci.png). Only use a different path if the user explicitly specifies one in their original request.

Step 4: Build the ray.so URL

CRITICAL: ALL parameters must be in the URL hash (after #), NOT in the query string.

Build the URL using shell commands:

# 1. Base64 encode the code
CODE_BASE64=$(echo -n 'YOUR_CODE_HERE' | base64)

# 2. URL encode the base64 string
CODE_ENCODED=$(python3 -c "import urllib.parse; print(urllib.parse.quote('$CODE_BASE64'))")

# 3. Build the URL with ALL parameters in the hash
# Format: https://ray.so/#param1=value1&param2=value2&code=ENCODED_CODE
# Do NOT include width parameter - let ray.so auto-size to fit content
URL="https://ray.so/#theme=THEME&padding=PADDING&background=BACKGROUND&darkMode=DARKMODE&language=LANGUAGE&code=${CODE_ENCODED}"

# Add optional parameters if needed:
# If lineNumbers: add "&lineNumbers=true" before &code=
# If title: add "&title=URL_ENCODED_TITLE" before &code=

URL Hash Parameters:

ParameterValuesDefault
themeAny theme from listbreeze
padding16, 32, 64, 12864
backgroundtrue, falsetrue
darkModetrue, falsetrue
languageAny language from list, or "auto"auto
lineNumberstrue, falsefalse
titleURL-encoded string(none)
widthNumber (pixels)auto
codeBase64-encoded, then URL-encoded(required)

Note on width: Do NOT include the width parameter unless you specifically need a fixed width. Without it, ray.so auto-sizes the frame to fit the code content, avoiding unnecessary empty space.

Example URL construction:

# For code: for i in range(23):\n    print(i)
# Theme: midnight, Padding: 64, Dark mode: true, Background: true, Language: python, Title: test.py

CODE='for i in range(23):
    print(i)'
CODE_BASE64=$(echo -n "$CODE" | base64)
CODE_ENCODED=$(python3 -c "import urllib.parse; print(urllib.parse.quote('$CODE_BASE64'))")
TITLE_ENCODED=$(python3 -c "import urllib.parse; print(urllib.parse.quote('test.py'))")
URL="https://ray.so/#theme=midnight&padding=64&background=true&darkMode=true&language=python&title=${TITLE_ENCODED}&code=${CODE_ENCODED}"
echo "$URL"

Step 5: Capture High-Quality Image with agent-browser

MUST use agent-browser (verified in Step 1). This approach uses the html-to-image library (same as ray.so's internal export) with high pixelRatio for crisp, sharp text rendering.

IMPORTANT: Always use a unique session name with --session to avoid stale session issues.

# Generate unique session name
SESSION="rayso-$(date +%s)"

# 1. Set viewport
agent-browser --session $SESSION set viewport 1400 900

# 2. Open the URL
agent-browser --session $SESSION open "$URL"

# 3. Wait for the page to fully render
agent-browser --session $SESSION wait --load networkidle
agent-browser --session $SESSION wait 3000

# 4. Load html-to-image library (same library ray.so uses internally)
agent-browser --session $SESSION eval 'new Promise((r,e)=>{const s=document.createElement("script");s.src="https://cdn.jsdelivr.net/npm/html-to-image@1.11.11/dist/html-to-image.js";s.onload=r;s.onerror=e;document.head.appendChild(s)})'

# 5. Capture at 4x resolution using html-to-image (produces crisp text)
agent-browser --session $SESSION eval 'htmlToImage.toPng(document.querySelector("#frame > div"),{pixelRatio:4,skipAutoScale:true})' > /tmp/rayso-dataurl-$SESSION.txt

# 6. Close the browser
agent-browser --session $SESSION close

# 7. Convert data URL to PNG file
DATAURL=$(cat /tmp/rayso-dataurl-$SESSION.txt | tr -d '"' | tr -d '\n')
echo "$DATAURL" | sed 's/data:image\/png;base64,//' | base64 -d > /path/to/output.png

# 8. Clean up temp file
rm /tmp/rayso-dataurl-$SESSION.txt

Critical notes:

  • Uses html-to-image library which is what ray.so uses for its own export feature
  • pixelRatio: 4 produces high-DPI images with crisp, sharp text (4x native resolution)
  • The data URL is captured directly from the library, not from a screenshot
  • No ImageMagick required - pure browser-based rendering at high resolution
  • Output is correctly sized with no extra whitespace

Step 6: Confirm Output and STOP

Report the saved file location to the user. The task is complete - do not perform any additional checks, explorations, or verifications after the screenshot is saved.

Complete Example

User: "Create a code snippet image of this Python function"

def fibonacci(n):
    if n <= 1:
        return n
    return fibonacci(n-1) + fibonacci(n-2)
  1. Check which agent-browser - confirmed available
  2. Fetch themes and languages:
curl -s "https://raw.githubusercontent.com/raycast/ray-so/main/app/(navigation)/(code)/store/themes.ts" | grep -oE 'id:\s*"[^"]+"' | sed 's/id:\s*"//;s/"//' | sort -u
  1. Ask user for parameters via AskUserQuestion:
    • Theme: user selects "midnight"
    • Language: inferred as python from def syntax - not asked
    • Dark mode: user selects "Dark mode"
    • Background: user selects "Yes"
    • Padding: user selects "64"
    • Line numbers: user selects "No"
    • Title: user selects "No title"
  2. Build URL (all params in hash, no width for auto-sizing):
CODE='def fibonacci(n):
    if n <= 1:
        return n
    return fibonacci(n-1) + fibonacci(n-2)'
CODE_BASE64=$(echo -n "$CODE" | base64)
CODE_ENCODED=$(python3 -c "import urllib.parse; print(urllib.parse.quote('$CODE_BASE64'))")
URL="https://ray.so/#theme=midnight&padding=64&background=true&darkMode=true&language=python&code=${CODE_ENCODED}"
  1. Capture high-quality image:
SESSION="rayso-$(date +%s)"

agent-browser --session $SESSION set viewport 1400 900
agent-browser --session $SESSION open "$URL"
agent-browser --session $SESSION wait --load networkidle
agent-browser --session $SESSION wait 3000

# Load html-to-image library
agent-browser --session $SESSION eval 'new Promise((r,e)=>{const s=document.createElement("script");s.src="https://cdn.jsdelivr.net/npm/html-to-image@1.11.11/dist/html-to-image.js";s.onload=r;s.onerror=e;document.head.appendChild(s)})'

# Capture at 4x resolution
agent-browser --session $SESSION eval 'htmlToImage.toPng(document.querySelector("#frame > div"),{pixelRatio:4,skipAutoScale:true})' > /tmp/rayso-dataurl-$SESSION.txt
agent-browser --session $SESSION close

# Save as PNG
DATAURL=$(cat /tmp/rayso-dataurl-$SESSION.txt | tr -d '"' | tr -d '\n')
echo "$DATAURL" | sed 's/data:image\/png;base64,//' | base64 -d > ./fibonacci.png
rm /tmp/rayso-dataurl-$SESSION.txt
  1. Report: "Saved code snippet image to ./fibonacci.png"

Image Resolution and Quality

This skill uses the html-to-image library with pixelRatio: 4 to produce high-quality images with crisp, sharp text. This is the same rendering approach that ray.so uses for its built-in export feature.

Output quality:

  • Default: 4x native resolution (frame auto-sizes to content, then rendered at 4x)
  • Text is rendered at high DPI, not upscaled from low resolution
  • Gradient backgrounds and all CSS styling are preserved
  • No unnecessary empty space (frame auto-sizes to fit code)

Adjusting resolution:

  • For smaller files: Change pixelRatio:4 to pixelRatio:2 in the eval command
  • For maximum quality: Use pixelRatio:6 (same as ray.so's "6x" export option)

Forcing a specific width:

  • Only add &width=NUMBER to the URL if you need a fixed width (e.g., for consistent sizing across multiple images)

Troubleshooting

  • If agent-browser is not available: Inform the user and do not proceed
  • If curl fails to fetch themes/languages, use these common defaults:
    • Themes: breeze, midnight, candy, crimson, falcon, meadow, raindrop, sunset, vercel, supabase, tailwind
    • Languages: auto, javascript, typescript, python, rust, go, java, ruby, swift, kotlin, css, html, json, yaml, bash
  • If parameters aren't applied: Ensure ALL parameters are in the URL hash (after #), not the query string
  • If title isn't showing: The title parameter must be in the hash: #title=filename.py&code=...
  • If html-to-image fails to load: Check network connectivity; the library loads from jsdelivr CDN
  • If capture returns empty: The frame selector #frame > div may have changed; inspect the page structure
  • For very long code snippets, ray.so may truncate; consider splitting into multiple images
  • If the page doesn't load properly, increase the wait time (try 4000ms or more)
  • If you get a blank page: Use a fresh unique session name with --session flag
  • If data URL is malformed: Ensure quotes and newlines are stripped before base64 decoding

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.