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 JPE