From 9e8d8df98a0177d73eee791517f07e4d878d4998 Mon Sep 17 00:00:00 2001 From: multipleof4 Date: Sat, 26 Sep 2026 12:40:16 -0700 Subject: [PATCH] Refactor: Make direct-img skill instructions-only Drop the preview script (and the .gitattributes that only existed for it); the skill now describes downloading candidates with curl and viewing them with Read. Co-Authored-By: Claude Opus 5.5 --- .gitattributes | 2 -- direct-img/SKILL.md | 13 +++------- direct-img/scripts/preview.sh | 49 ----------------------------------- 3 files changed, 4 insertions(+), 60 deletions(-) delete mode 100644 .gitattributes delete mode 100755 direct-img/scripts/preview.sh diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index f8f6442..0000000 --- a/.gitattributes +++ /dev/null @@ -1,2 +0,0 @@ -# Scripts must keep LF endings to run under bash on Windows -*.sh text eol=lf diff --git a/direct-img/SKILL.md b/direct-img/SKILL.md index b3105d7..1b00fce 100644 --- a/direct-img/SKILL.md +++ b/direct-img/SKILL.md @@ -1,7 +1,6 @@ --- name: direct-img description: Find, preview and embed images with direct-img.link, where a URL like https://direct-img.link/orange+cat returns an image directly. Use when the user asks for images, pictures, photos, gifs, reaction images or illustrations, wants images embedded in markdown, HTML, READMEs, docs, slides, emails or web pages, or needs free-to-use (public domain / CC0) images for publishing via free.direct-img.link. -allowed-tools: Bash(bash ${CLAUDE_SKILL_DIR}/scripts/preview.sh *) Read --- # direct-img.link @@ -14,7 +13,7 @@ A URL is the search: `https://direct-img.link/` searches the web and retu - Percent-encode `.` as `%2E` and `/` as `%2F` (literal ones are rejected), and other special characters as usual (`'` → `%27`, `&` → `%26`). Max 200 characters. Case and extra spaces don't matter. - `?i=N` (1–20, default 1) serves the N-th working image. Broken links are skipped, so every `i` is a different image. - `https://free.direct-img.link/` serves only images marked free of restrictions (public domain / CC0), so no credit is needed. It searches Openverse, then Wikimedia Commons. Add `&src=openverse` or `&src=wikimedia` to pick one. Params work in any order. -- A generic "bad" image means no working result (or invalid params); a "limit" image means the daily search limit was hit. +- Instead of a result, you may get the site's [bad image](https://direct-img.link/assets/bad.webp) (no working result, or invalid params) or [limit image](https://direct-img.link/assets/limit.webp) (daily search limit hit). ## Which host @@ -27,13 +26,9 @@ A URL is the search: `https://direct-img.link/` searches the web and retu When the image matters (the user asked for images, or it will be published), don't blindly embed `i=1`: 1. **Write a specific query**: concrete nouns and details ("golden retriever puppy in snow", not "dog"). On free, drop filler words like "hd", "photo", "image", "high quality" (they must match image text and cause misses). Add "gif" for animated images on the main host. -2. **Preview candidates**: - ```bash - bash ${CLAUDE_SKILL_DIR}/scripts/preview.sh [--free] [--src openverse|wikimedia] [--from N] [--to N] "query" - ``` - It downloads `i=1..3` by default, flags duplicates and the bad/limit images, and prints each file's path. Open every file with the Read tool to see it. +2. **Preview candidates**: download `?i=1`, `?i=2` and `?i=3` into a temporary folder (e.g. `curl -sLo ""`) and open each file with the Read tool to see it. Stop at the bad image (there are fewer working images than that `i`) or the limit image. 3. **Judge each against the request**: right subject, fits the requested style or mood, no watermarks, text overlays or collages, sharp enough, suitable content, and an orientation that fits where it goes. -4. **If none fit**, rephrase the query (or switch `--src` on free) rather than digging deep into `i`. +4. **If none fit**, rephrase the query (or switch `src` on free) rather than digging deep into `i`. 5. **Embed the exact URL** of the winner, including `?i=` / `&src=`, e.g. `https://free.direct-img.link/orange+cat?i=2`. For quick casual images (a reaction gif in chat), skip previewing and embed a well-chosen query directly. If an image can't be displayed by Read, don't guess its content; judge the others. @@ -43,7 +38,7 @@ For quick casual images (a reaction gif in chat), skip previewing and embed a we - Every new query + `i` + `src` combination uses 1 of the user's **20 new searches per day** (per IP, shared by both hosts). Cached URLs are free. Previewing costs the same as embedding would, and warms the cache so the embed loads instantly. - Default to 3 candidates and about 10 new searches per request at most, unless the user asks for more. - On the limit image, stop and tell the user (it resets at 00:00 UTC). -- Requests are also limited to about 10 per 10 seconds; the script paces itself. +- Requests are also limited to about 10 per 10 seconds, so space downloads about a second apart. ## Embedding diff --git a/direct-img/scripts/preview.sh b/direct-img/scripts/preview.sh deleted file mode 100755 index 184147e..0000000 --- a/direct-img/scripts/preview.sh +++ /dev/null @@ -1,49 +0,0 @@ -#!/usr/bin/env bash -# Download direct-img.link candidates for a query so they can be viewed and compared. -# Usage: preview.sh [--free] [--src openverse|wikimedia] [--from N] [--to N] [--out DIR] "query" -set -eu - -host=direct-img.link src= from=1 to=3 out= -while [ $# -gt 1 ]; do - case $1 in - --free) host=free.direct-img.link; shift ;; - --src) src=$2; host=free.direct-img.link; shift 2 ;; - --from) from=$2; shift 2 ;; - --to) to=$2; shift 2 ;; - --out) out=$2; shift 2 ;; - *) echo "Unknown option: $1" >&2; exit 2 ;; - esac -done -[ $# -eq 1 ] || { sed -n 3p "$0" >&2; exit 2; } - -# Encode via stdin so UTF-8 survives on Windows; direct-img.link rejects literal dots -path=$(printf %s "$1" | curl -Gso /dev/null -w '%{url_effective}' --data-urlencode @- http://x/ | cut -d'?' -f2- | sed 's/\./%2E/g') -out=${out:-$(mktemp -d "${TMPDIR:-/tmp}/direct-img.XXXXXX")} -mkdir -p "$out" -h() { { sha256sum 2>/dev/null || shasum -a 256; } < "$1" | cut -c1-12; } - -# The site's own placeholders, to recognize "no result" and "limit reached" -curl -sf https://direct-img.link/assets/bad.webp -o "$out/.bad" && bad=$(h "$out/.bad") || bad=none -curl -sf https://direct-img.link/assets/limit.webp -o "$out/.limit" && limit=$(h "$out/.limit") || limit=none - -echo "Saved to $out (open each file with the Read tool)" -seen= -for i in $(seq "$from" "$to"); do - url="https://$host/$path?i=$i${src:+&src=$src}" - f="$out/i$i" - ct=$(curl -s -o "$f" -w '%{content_type}' "$url") || { echo "i=$i request failed: $url"; continue; } - x=$(h "$f") - case $x in - "$limit") rm -f "$f"; echo "i=$i LIMIT: daily search limit reached (resets 00:00 UTC), stopping"; break ;; - "$bad") rm -f "$f"; echo "i=$i NONE: fewer than $i working images for this query, stopping"; break ;; - esac - ext=${ct#image/}; ext=${ext%%;*} - case $ext in jpeg) ext=jpg ;; svg+xml) ext=svg ;; esac - mv "$f" "$f.$ext" - dims=$(file -b "$f.$ext" 2>/dev/null | grep -oE '[0-9]+ ?x ?[0-9]+' | tail -1 | tr -d ' ') - dup=$(printf '%s\n' $seen | grep "^$x=" | cut -d= -f2) - seen="$seen $x=$i" - echo "i=$i $url" - echo " $f.$ext ${dims:-?} $(wc -c < "$f.$ext" | tr -d ' ')B${dup:+ DUPLICATE of i=$dup}" - sleep 1 -done