Agent skill
giil
Get Image [from] Internet Link - Zero-setup CLI for downloading full-resolution images from iCloud, Dropbox, Google Photos, and Google Drive share links. Four-tier capture strategy, browser automation, HEIC conversion, album support. Node.js/Playwright.
Install this agent skill to your Project
npx add-skill https://github.com/aiskillstore/marketplace/tree/main/skills/dicklesworthstone/giil
SKILL.md
GIIL — Get Image [from] Internet Link
A zero-setup CLI that downloads full-resolution images from cloud photo shares. The missing link between your iPhone screenshots and remote AI coding sessions.
Why This Exists
The primary use case: Remote AI-Assisted Debugging
You're SSH'd into a remote server running Claude Code, Codex, or another AI assistant. You need to debug a UI issue on your iPhone, but how do you get that screenshot to your remote terminal?
Without giil:
Download image locally → SCP to server → Tell AI the path
Email yourself → Download on server → Hope it works
Set up complex file sync between devices
With giil:
giil "https://share.icloud.com/photos/0a1Abc_xYz..." --json
# {"path": "/tmp/icloud_20240115_143022.jpg", "width": 1170, ...}
One command. AI sees it instantly. No file transfers, no context switching.
The Workflow
iPhone Screenshot → iCloud Sync → Photos.app Share Link → Paste to SSH → giil Downloads → AI Analyzes
Why Cloud Shares Are Hard
| Problem | Why It's Hard | How giil Solves It |
|---|---|---|
| JavaScript-heavy SPAs | Standard curl/wget can't execute JS | Headless Chromium via Playwright |
| Dynamic image loading | Images load asynchronously from CDN | Network interception captures CDN responses |
| No direct download links | URLs are session-specific and expire | Clicks Download button or intercepts live requests |
| Copy/paste loses quality | Manual screenshots compress images | Captures original resolution from source |
| HEIC format on Apple | Many tools can't process HEIC/HEIF | Platform-aware conversion (sips/heif-convert) |
Quick Start
# Install
curl -fsSL "https://raw.githubusercontent.com/Dicklesworthstone/giil/main/install.sh?v=3.0.0" | bash
# Download single image
giil "https://share.icloud.com/photos/02cD9okNHvVd-uuDnPCH3ZEEA"
# JSON output (best for AI workflows)
giil "https://share.icloud.com/photos/..." --json
# Download entire album
giil "https://share.icloud.com/photos/..." --all --output ~/album
Note: First run downloads Playwright Chromium (~200MB, cached in ~/.cache/giil/).
Supported Platforms
| Platform | URL Patterns | Method | Browser Required |
|---|---|---|---|
| iCloud | share.icloud.com/photos/*, icloud.com/photos/#* |
4-tier capture strategy | Yes |
| Dropbox | dropbox.com/s/*, dropbox.com/scl/fi/* |
Direct curl (raw=1) |
No |
| Google Photos | photos.app.goo.gl/*, photos.google.com/share/* |
URL extraction + =s0 modifier |
Yes |
| Google Drive | drive.google.com/file/d/*, drive.google.com/open?id=* |
Multi-tier with auth detection | Yes |
Dropbox Fast Path: Direct curl download with no browser overhead—typically 1-2 seconds.
Google Photos Full-Res: Automatically appends =s0 to CDN URLs for maximum resolution.
Four-Tier Capture Strategy
giil implements a fallback strategy to maximize reliability:
1. Download Button (Highest Quality)
- Locates visible Download button using 9 selector patterns
- Clicks and waits for browser download event
- Obtains original file (no re-encoding losses)
- Works with HEIC/HEIF originals
2. Network Interception (Full Resolution)
- Monitors all HTTP responses for CDN patterns (
cvws.icloud-content.com, etc.) - Filters by content-type (image formats only)
- Captures largest image buffer (>10KB threshold to skip thumbnails)
- Works even if UI elements are obscured
3. Element Screenshot
- Queries for image elements using 10 selector patterns
- Verifies element is visible and ≥100×100 pixels
- Takes PNG screenshot of the element
4. Viewport Screenshot (Last Resort)
- Captures visible viewport (1920×1080)
- Always succeeds if page loads
- Useful for debugging page state
Command Reference
Basic Usage
giil <url> [options]
Options
| Flag | Default | Description |
|---|---|---|
--output DIR |
. |
Output directory |
--preserve |
off | Keep original bytes (skip MozJPEG compression) |
--convert FMT |
— | Convert to: jpeg, png, webp |
--quality N |
85 |
JPEG quality 1-100 |
--base64 |
off | Output base64 to stdout (no file saved) |
--json |
off | Output JSON metadata |
--all |
off | Download all photos from album |
--timeout N |
60 |
Page load timeout in seconds |
--debug |
off | Save debug artifacts on failure |
--verbose |
off | Show detailed progress |
--trace |
off | Enable Playwright tracing for deep debugging |
--print-url |
off | Output resolved CDN URL (don't download) |
--debug-dir DIR |
. |
Directory for debug artifacts |
--update |
off | Force reinstall dependencies |
Output Modes
Default: File Path
giil "https://share.icloud.com/photos/XXX"
# stdout: /current/dir/icloud_20240115_143245.jpg
Scripting:
IMAGE_PATH=$(giil "..." --output ~/Downloads 2>/dev/null)
JSON Mode
giil "https://share.icloud.com/photos/XXX" --json
Success:
{
"ok": true,
"schema_version": "1",
"platform": "icloud",
"path": "/absolute/path/to/icloud_20240115_143245.jpg",
"datetime": "2024-01-15T14:32:45.000Z",
"sourceUrl": "https://cvws.icloud-content.com/...",
"method": "network",
"size": 245678,
"width": 4032,
"height": 3024
}
Error:
{
"ok": false,
"schema_version": "1",
"platform": "icloud",
"error": {
"code": "AUTH_REQUIRED",
"message": "Login required - link is not publicly shared",
"remediation": "The file is not publicly shared. The owner must enable public access."
}
}
| Field | Description |
|---|---|
method |
Capture strategy: download, network, element-screenshot, viewport-screenshot, direct |
error.code |
Error code (see Exit Codes) |
error.remediation |
Suggested fix |
Base64 Mode
# Decode to file
giil "..." --base64 | base64 -d > image.jpg
# Create data URI
echo "data:image/jpeg;base64,$(giil '...' --base64)" > uri.txt
# Pipe to API
giil "..." --base64 | curl -X POST -d @- https://api.example.com/upload
URL-Only Mode
giil "https://share.icloud.com/photos/XXX" --print-url
# stdout: https://cvws.icloud-content.com/B/...
Useful for external downloaders, caching, or debugging.
Album Mode
Download entire shared albums with --all:
giil "https://share.icloud.com/photos/XXX" --all --output ~/album
How It Works
- Load album page
- Detect thumbnail grid (11 selector strategies)
- For each thumbnail: click → capture → close → next
- Output one path/JSON per photo
Album Features
- Resilient: Continues to next photo if one fails
- Indexed filenames:
_001,_002, etc. for ordering - Rate limiting: 1 second delay between photos (polite downloading)
- Exponential backoff: Automatic retry on rate limit signals
Album Output
# Default
/path/to/album/icloud_20240115_143245_001.jpg
/path/to/album/icloud_20240115_143246_002.jpg
# With --json
{"path": "...001.jpg", "method": "download", "width": 4032, ...}
{"path": "...002.jpg", "method": "network", "width": 3024, ...}
Image Processing Pipeline
EXIF Datetime Extraction
Priority order for filename generation:
DateTimeOriginal(when photo was taken)CreateDateDateTimeDigitizedModifyDate- Current time (fallback)
HEIC/HEIF Conversion
| Platform | Tool | Notes |
|---|---|---|
| macOS | sips |
Built-in, always available |
| Linux | heif-convert |
Requires libheif-examples package |
# Install HEIC support on Linux
sudo apt-get install libheif-examples # Debian/Ubuntu
sudo dnf install libheif-tools # Fedora
MozJPEG Compression (Default)
By default, giil compresses with MozJPEG for optimal size/quality:
- 40-50% smaller than standard JPEG at equivalent quality
- Quality 85 (configurable via
--quality) - Use
--preserveto keep original bytes
Filename Format
icloud_YYYYMMDD_HHMMSS[_NNN][_counter].jpg
│ │ │
│ │ └── Collision counter (if file exists)
│ └── Album index (--all mode only)
└── Date/time from EXIF or capture time
Download Verification
giil validates downloads through three stages:
1. Content-Type Validation
Validates HTTP Content-Type matches expected image types.
2. Magic Bytes Detection
Verifies binary signature regardless of server claims:
| Format | Magic Bytes |
|---|---|
| JPEG | FF D8 FF |
| PNG | 89 50 4E 47 |
| GIF | 47 49 46 38 |
| WebP | RIFF container with WEBP |
| HEIC/HEIF | ISO base media file (ftyp box) |
3. HTML Error Page Detection
Rejects HTML content that indicates an error page instead of an image.
Exit Codes
| Code | Name | Description |
|---|---|---|
0 |
Success | Image captured and saved/output |
1 |
Capture Failure | All capture strategies failed |
2 |
Usage Error | Invalid arguments or missing URL |
3 |
Dependency Error | Node.js, Playwright, or Chromium issue |
10 |
Network Error | Timeout, DNS failure, unreachable host |
11 |
Auth Required | Login redirect, password required, not publicly shared |
12 |
Not Found | Expired link, deleted file, 404 |
13 |
Unsupported Type | Video, Google Doc, or non-image content |
20 |
Internal Error | Bug in giil (please report!) |
Scripting:
giil "https://share.icloud.com/photos/XXX" 2>/dev/null
case $? in
0) echo "Success!" ;;
10) echo "Network issue - retry later" ;;
11) echo "Link not public - ask owner to share" ;;
12) echo "Link expired" ;;
*) echo "Failed with code $?" ;;
esac
Environment Variables
Runtime Variables
| Variable | Description | Default |
|---|---|---|
XDG_CACHE_HOME |
Base cache directory | ~/.cache |
GIIL_HOME |
giil runtime directory | $XDG_CACHE_HOME/giil |
PLAYWRIGHT_BROWSERS_PATH |
Custom Chromium cache | $GIIL_HOME/ms-playwright |
GIIL_NO_GUM |
Disable gum styling | unset |
GIIL_CHECK_UPDATES |
Enable update checking | unset |
Installer Variables
| Variable | Description | Default |
|---|---|---|
DEST |
Custom install directory | ~/.local/bin |
GIIL_SYSTEM |
Install to /usr/local/bin |
unset |
GIIL_VERIFY |
Verify SHA256 checksum | unset |
GIIL_VERSION |
Install specific version | latest |
File Locations
| Path | Purpose |
|---|---|
~/.local/bin/giil |
Main script |
~/.cache/giil/ |
Runtime directory |
~/.cache/giil/node_modules/ |
Playwright, Sharp, exifr |
~/.cache/giil/extractor.mjs |
Generated Node.js script |
~/.cache/giil/ms-playwright/ |
Chromium browser cache |
Debug Artifacts (on failure with --debug)
| File | Contents |
|---|---|
giil_debug_<timestamp>.png |
Full-page screenshot |
giil_debug_<timestamp>.html |
Page DOM content |
Performance
| Phase | First Run | Subsequent |
|---|---|---|
| Chromium download | 30-60s | Skipped (cached) |
| Browser launch | 2-3s | 2-3s |
| Page load | 3-10s | 3-10s |
| Image capture | 1-5s | 1-5s |
| Total | 40-80s | 5-15s |
Dropbox: 1-2 seconds (direct curl, no browser).
Troubleshooting
"Auth required" error
The link isn't publicly shared. Owner must enable public access in their cloud settings.
Timeout errors
Increase timeout: giil "..." --timeout 120
Wrong/small image captured
Run with --debug to see page state. Report issue with debug artifacts.
HEIC conversion fails on Linux
sudo apt-get install libheif-examples # Debian/Ubuntu
sudo dnf install libheif-tools # Fedora
Chromium fails to launch
giil "..." --update
# Or manually:
cd ~/.cache/giil && npx playwright install --with-deps chromium
Debugging
# Verbose output
giil "..." --verbose
# Debug artifacts on failure
giil "..." --debug
# Playwright trace (generates trace.zip)
giil "..." --trace
npx playwright show-trace ~/.cache/giil/trace.zip
Installation
# One-liner (recommended)
curl -fsSL "https://raw.githubusercontent.com/Dicklesworthstone/giil/main/install.sh?v=3.0.0" | bash
# Verified installation
GIIL_VERIFY=1 curl -fsSL .../install.sh | bash
# System-wide
GIIL_SYSTEM=1 curl -fsSL .../install.sh | bash
# Manual
curl -fsSL https://raw.githubusercontent.com/Dicklesworthstone/giil/main/giil -o ~/.local/bin/giil
chmod +x ~/.local/bin/giil
Uninstallation
rm ~/.local/bin/giil
rm -rf ~/.cache/giil
rm -rf ~/.cache/ms-playwright # If no other Playwright tools
Security & Privacy
- Local execution: All processing happens on your machine
- No telemetry: No data sent anywhere except to cloud services
- No authentication stored: Uses public share mechanism
- No cookies saved: Browser context is ephemeral
- Temp file cleanup: Downloaded files cleaned up after processing
Integration with Flywheel
| Tool | Integration |
|---|---|
| Claude Code | Download screenshots for visual debugging via SSH |
| NTM | Share images between multi-agent sessions |
| Agent Mail | Attach downloaded images to agent messages |
| CASS | Search sessions that used giil for image context |
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
perigon-backend
Perigon ASP.NET Core + EF Core + Aspire conventions
perigon-agent
Pointers for Copilot/agents to apply Perigon conventions
perigon-angular
Angular 21+ standalone/Material/signal conventions for Perigon WebApp
fastapi-mastery
Comprehensive FastAPI development skill covering REST API creation, routing, request/response handling, validation, authentication, database integration, middleware, and deployment. Use when working with FastAPI projects, building APIs, implementing CRUD operations, setting up authentication/authorization, integrating databases (SQL/NoSQL), adding middleware, handling WebSockets, or deploying FastAPI applications. Triggered by requests involving .py files with FastAPI code, API endpoint creation, Pydantic models, or FastAPI-specific features.
context7-efficient
Token-efficient library documentation fetcher using Context7 MCP with 86.8% token savings through intelligent shell pipeline filtering. Fetches code examples, API references, and best practices for JavaScript, Python, Go, Rust, and other libraries. Use when users ask about library documentation, need code examples, want API usage patterns, are learning a new framework, need syntax reference, or troubleshooting with library-specific information. Triggers include questions like "Show me React hooks", "How do I use Prisma", "What's the Next.js routing syntax", or any request for library/framework documentation.
browser-use
Browser automation using Playwright MCP. Navigate websites, fill forms, click elements, take screenshots, and extract data. Use when tasks require web browsing, form submission, web scraping, UI testing, or any browser interaction.
Didn't find tool you were looking for?