Skip to content
Back to skills

Docs Screenshot

ASecurity

Capture a 600×400 documentation screenshot from the running Silo app and composite it on the standard wallpaper. Use whenever adding or updating screenshots in apps/docs/public/img/guide/.

  • 58 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 2, 2026
ai-agentspythongobashdocumentation

Works with

  • cursor
  • cli

Security analysis

A100/100

Scanned September 2, 2026

npx -y skills add silo-code/silo --skill docs-screenshot --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Docs Screenshot?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Docs Screenshot
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/silo-code-docs-screenshot/badge)](https://www.skillsdirectory.com/skills/silo-code-docs-screenshot)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: docs-screenshot
description: Capture a 600×400 documentation screenshot from the running Silo app and composite it on the standard wallpaper. Use whenever adding or updating screenshots in apps/docs/public/img/guide/.
tools: Bash, Read
---

# Silo Docs Screenshot

Produces a **600×400 PNG** of a Silo UI region composited over the standard orange/purple
wallpaper (`apps/docs/public/img/wallpaper.jpg`), styled as a windowed screenshot floating
on the desktop — consistent with every other image in the guide.

## Quick reference

```
Corner      Desktop visible    Window bleeds    Window canvas pos      Merged geometry      Round corner
──────────  ─────────────────  ───────────────  ─────────────────────  ───────────────────  ────────────
top-left    top(65) left(80)   right, bottom    (80, 65)               +40+30               all 4
bot-left    bot(10) left(80)   top, right       (80, 0)                +40+-35              bot-left only
top-right   top(65) right(80)  left, bottom     (520-OW, 65)           +(480-OW)+30         top-right only
bot-right   bot(10) right(80)  top, left        (520-OW, 390-OH)       +(480-OW)+(355-OH)   bot-right only
center      all sides ~50px    none             ((600-OW)/2, (400-OH)/2)  +((600-OW)/2-40)+((400-OH)/2-35)  all 4
```

`top-left` — top half of app, feature on the LEFT (e.g. workspaces panel, editor).  
`bot-left` — bottom of app, feature on the LEFT (e.g. status bar menu).  
`top-right` — top half of app, feature on the RIGHT (e.g. file explorer, right side panel).  
`bot-right` — bottom of app, feature on the RIGHT (e.g. right-side status items, output panel).

## Pipeline

### 1. Take the screenshot

```bash
silo(){ curl -s -m30 -X POST http://127.0.0.1:7878/ \
  -H 'X-Silo-Automation: 1' -H 'Content-Type: application/json' \
  --data "$1"; }

# Set up any app state first (open panels, menus, etc.), then:
silo '{"op":"screenshot"}' > /tmp/shot.json
python3 -c "
import json,base64
d=json.load(open('/tmp/shot.json'))
r=d['result']
open('/tmp/silo.png','wb').write(base64.b64decode(r['png_base64']))
print(r['width'], r['height'])
"
# Typical output: 3024 1898  (2× retina — logical pixels are half)
```

### 2. Choose your crop

The source is **3024×1898 at 2× retina** (logical: 1512×949).

Pick the region of interest in 2× pixels and a window output size that fits the composition:

| Style    | Typical output window | Typical source crop | Scale  |
| -------- | --------------------- | ------------------- | ------ |
| top-left | 580×439               | 900×680 from (0,0)  | 0.644× |
| bot-left | 520×390               | 1131×848 from (0,Y) | 0.460× |

**Crop rules:**

- Source crop `W×H` and output window `w×h` must satisfy `W/H = w/h` (same aspect ratio).
- For **top-left**: start at (0,0); choose crop height to include the feature; bleed at right + bottom is automatic since `w > 600-80` and `h > 400-65`.
- For **bot-left**: start high enough (Y) that the full feature is inside the crop; the crop bottom is always `1898` (window bottom). Status bar = `y≈1050` is a safe start for a menu+statusbar shot.
- To zoom in more: use a smaller source crop (same output window size → larger apparent zoom).
- To zoom out / show more context: use a larger source crop.

### 3. Compose

```bash
WALL="apps/docs/public/img/wallpaper.jpg"
DOCS="apps/docs/public/img/guide"
APP=/tmp/silo.png   # or your saved screenshot

# ── Variables ──────────────────────────────────────────────────────────────
CORNER=top-left         # top-left | bot-left
CW=900; CH=680          # source crop width × height (2× pixels)
CX=0;   CY=0            # source crop origin (2× pixels)
OW=580; OH=439          # output window width × height (pixels)
OUT="$DOCS/feature.png" # destination

# ── Wallpaper background ───────────────────────────────────────────────────
magick "$WALL" -resize "600x400^" -gravity center -extent 600x400 /tmp/bg.png

# ── Crop + scale ───────────────────────────────────────────────────────────
magick "$APP" -crop ${CW}x${CH}+${CX}+${CY} +repage -resize ${OW}x${OH} /tmp/win-scaled.png

# ── Mouse cursor (optional) ────────────────────────────────────────────────
# Use when you want to indicate where the user should click.
# IMPORTANT: Do NOT use SVG — ImageMagick renders it as a plain white square.
# Draw the cursor natively instead. Cursor tip is at pixel (2,2) within the image.
#
# TIP_X=48; TIP_Y=265   # desired tip position in output-window coordinates
# magick -size 24x28 xc:none \
#   -fill white -stroke black -strokewidth 1.5 \
#   -draw "polygon 2,2 2,22 7,17 11,26 14,24 10,15 18,15" \
#   /tmp/cursor.png
# magick /tmp/win-scaled.png /tmp/cursor.png \
#   -geometry +$((TIP_X-2))+$((TIP_Y-2)) -composite /tmp/win-scaled.png
#
# Placement rule: subtract 2 from both axes (tip offset within cursor image).
# Place the cursor AFTER crop+scale but BEFORE rounded corners so it gets
# clipped correctly if it's near an edge.

# ── Rounded corners ────────────────────────────────────────────────────────
R=10
case "$CORNER" in
  top-left)
    # All 4 corners — top-left is the real window corner; others bleed but rounding is consistent
    magick /tmp/win-scaled.png \
      \( +clone -alpha extract -fill black -colorize 100 \
         -fill white -draw "roundrectangle 0,0 $((OW-1)),$((OH-1)) 10,10" \) \
      -alpha off -compose CopyOpacity -composite /tmp/win-rounded.png
    ;;
  bot-left)
    # Round bottom-left corner only; top bleeds off canvas, right bleeds off canvas
    magick /tmp/win-scaled.png \
      \( +clone -alpha extract -fill black -colorize 100 \
         -fill white  -draw "rectangle 0,0 $((OW-1)),$((OH-1))" \
         -fill black  -draw "rectangle 0,$((OH-R)) $((R-1)),$((OH-1))" \
         -fill white  -draw "circle ${R},$((OH-R)) 0,$((OH-R))" \
      \) -alpha off -compose CopyOpacity -composite /tmp/win-rounded.png
    ;;
  top-right)
    # Round top-right corner only; left bleeds off canvas, bottom bleeds off canvas
    magick /tmp/win-scaled.png \
      \( +clone -alpha extract -fill black -colorize 100 \
         -fill white  -draw "rectangle 0,0 $((OW-1)),$((OH-1))" \
         -fill black  -draw "rectangle $((OW-R)),0 $((OW-1)),$((R-1))" \
         -fill white  -draw "circle $((OW-R)),${R} $((OW-1)),${R}" \
      \) -alpha off -compose CopyOpacity -composite /tmp/win-rounded.png
    ;;
  bot-right)
    # Round bottom-right corner only; top bleeds off canvas, left bleeds off canvas
    magick /tmp/win-scaled.png \
      \( +clone -alpha extract -fill black -colorize 100 \
         -fill white  -draw "rectangle 0,0 $((OW-1)),$((OH-1))" \
         -fill black  -draw "rectangle $((OW-R)),$((OH-R)) $((OW-1)),$((OH-1))" \
         -fill white  -draw "circle $((OW-R)),$((OH-R)) $((OW-1)),$((OH-R))" \
      \) -alpha off -compose CopyOpacity -composite /tmp/win-rounded.png
    ;;
esac

# ── Drop shadow ────────────────────────────────────────────────────────────
# shadow 90x20+0+10 → window lands at (40,35) inside the merged image
magick /tmp/win-rounded.png \
  \( +clone -background '#00000099' -shadow 90x20+0+10 \) \
  +swap -background none -layers merge +repage /tmp/win-shadowed.png

# ── Composite onto background ──────────────────────────────────────────────
# Shadow offset: window in merged image sits at (40,35). Formula: geometry = +(canvas_x−40)+(canvas_y−35)
# top-left:  window canvas (80, 65)           → +40+30
# bot-left:  window canvas (80, 0)            → +40+-35
# top-right: window canvas (520−OW, 65)       → +(480−OW)+30
# bot-right: window canvas (520−OW, 390−OH)   → +(480−OW)+(355−OH)
case "$CORNER" in
  top-left)  GX=40;         GY=30 ;;
  bot-left)  GX=40;         GY=$((-35)) ;;
  top-right) GX=$((480-OW)); GY=30 ;;
  bot-right) GX=$((480-OW)); GY=$((355-OH)) ;;
esac
magick /tmp/bg.png /tmp/win-shadowed.png -geometry +${GX}+${GY} -composite "$OUT"

magick identify -format "%wx%h\n" "$OUT"   # must print 600x400
```

## Shadow offset math (reference)

`-shadow 90x20+0+10` with `layers merge` places the source window at **(40, 35)** inside
the merged RGBA image regardless of the window dimensions.  
Formula: **`-geometry +(canvas_x − 40)+(canvas_y − 35)`**

Verify any time the shadow params change:

```bash
magick -size 100x100 xc:red \
  \( +clone -background '#00000099' -shadow 90x20+0+10 \) \
  +swap -background none -layers merge +repage /tmp/t.png
magick identify /tmp/t.png   # merged WxH
# window_x_offset = (merged_W - 100) / 2
# window_y_offset determined empirically or via: (merged_H - 100 - 10) / 2
```

## Common shots

| Guide section       | Corner    | Source crop (2×)        | Output window | Output file                                           |
| ------------------- | --------- | ----------------------- | ------------- | ----------------------------------------------------- |
| Workspaces panel    | top-left  | 900×680 from (0,0)      | 580×439       | workspaces-panel.png                                  |
| Workspaces + button | top-left  | 900×680 from (0,0)      | 580×439       | workspaces-open.png (cursor at + button tip≈(48,265)) |
| Status bar + menu   | bot-left  | 1131×848 from (0,1050)  | 520×390       | workspaces-statusbar.png                              |
| File explorer panel | top-right | 1324×1000 from (1700,0) | 580×438       | panels-file-explorer.png                              |
| Getting started     | center    | full window (no crop)   | 480×304       | getting-started-app.png                               |

## Rules

1. Output is always **600×400** — verify with `magick identify`.
2. **Never cut the app artificially** — the window must be a real contiguous region of the app, just cropped at the canvas edge due to bleed.
3. **Zoom into the feature** — pick a crop tight enough that the relevant UI is clearly readable.
4. Close any menus or dialogs after capturing so the app is left in a clean state.
5. **Always embed with `width="400"`** — the 600px image at 400 CSS pixels gives a sharp 1.5× render on retina displays without being too small. Never use `width="600"` (blurry on retina) or `width="300"` (too small).

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.