engineering/skills/full-page-screenshot/SKILL.md
Use when the user asks to capture a full-page screenshot, long screenshot, or complete page capture of a web page. Handles SPA scroll containers, lazy-loaded images, and very tall pages via Chrome DevTools Protocol with zero external dependencies.
npx skillsauth add alirezarezvani/claude-skills full-page-screenshotInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Capture a full-page screenshot of any web page via Chrome DevTools Protocol. Produces a single PNG that includes all content — even portions that require scrolling. Zero external dependencies beyond Node.js 22+ and Chrome with remote debugging enabled.
WebSocket)Check environment readiness:
node "${SKILL_DIR}/scripts/full-page-screenshot.mjs" --check
If Chrome check fails, instruct user to open chrome://inspect/#remote-debugging and enable "Allow remote debugging for this browser instance".
node "${SKILL_DIR}/scripts/full-page-screenshot.mjs" --list
node "${SKILL_DIR}/scripts/full-page-screenshot.mjs" <targetId> /tmp/screenshot.png --width 1200 --dpr 1
node "${SKILL_DIR}/scripts/full-page-screenshot.mjs" --url "https://example.com" /tmp/screenshot.png --width 1200 --dpr 1 --wait 15000
Note:
--urlmode creates a background tab. Pages requiring authentication (SSO, login walls) should use Option A instead.
| Parameter | Description | Default |
|-----------|-------------|---------|
| output | Output PNG file path | /tmp/screenshot.png |
| --width | Viewport width in CSS pixels (articles: 1200, dashboards: 1440-1920) | 1200 |
| --dpr | Device pixel ratio (2 = Retina, but 4x file size) | 1 |
| --wait | Page load timeout in ms (--url mode only) | 15000 |
| --css | Custom CSS to inject before capture (e.g., hide elements) | — |
# macOS
sips -g pixelWidth -g pixelHeight /tmp/screenshot.png
# Linux
file /tmp/screenshot.png
SPA scroll container expansion — Detects overflow-y: auto/scroll containers, scrolls through them to trigger lazy-loading, then removes overflow constraints (including Tailwind h-[calc(...)]) so all content renders in a single pass.
DOM stability detection — After readyState=complete, monitors DOM element count until it stabilizes. This ensures SPA frameworks finish rendering dynamic content.
Lazy-load triggering — Scrolls the viewport incrementally to fire IntersectionObserver callbacks, then waits for all <img> elements to complete loading.
Tiled capture for very tall pages — Pages exceeding 16,000px are captured in 8,000px tiles and automatically stitched using Python PIL. Falls back to saving tiles separately if PIL is unavailable.
Auto-discovery of Chrome — Reads DevToolsActivePort file to find the debugging port. Falls back to probing ports 9222, 9229, 9333.
CDP Proxy fallback — When a CDP proxy holds the browser WebSocket, the script falls back to proxy API endpoints (/eval, /screenshot, /scroll) for capture.
1. Discover Chrome debugging port
2. Connect via WebSocket (CDP)
3. Attach to target / create background tab
4. Set viewport width via Emulation domain
5. Wait: readyState + DOM stability
6. Detect & expand scroll containers
7. Scroll through page (trigger lazy-load)
8. Wait for images to complete
9. Measure final content height
10. Page.captureScreenshot (or tiled capture)
11. Stitch tiles if needed (PIL)
12. Restore viewport, detach, clean up
| Do NOT | Do instead |
|--------|-----------|
| Use --dpr 2 on pages > 10,000px tall | Use --dpr 1 to avoid Chrome memory issues |
| Use --url for authenticated/SSO pages | Use --list + targetId on a tab where user is logged in |
| Set --wait below 5000 for SPAs | SPAs need time to fetch data and render; use 10000-15000 |
| Capture without checking --check first | Always verify Chrome debugging is available |
| Hardcode viewport widths for all pages | Use 1200 for articles, 1440+ for dashboards/tables |
| Skip output verification | Always verify with sips or file command after capture |
| Symptom | Cause | Fix |
|---------|-------|-----|
| "Cannot find Chrome debugging port" | Remote debugging not enabled | Open chrome://inspect/#remote-debugging, enable it |
| "WebSocket connection timeout" | CDP proxy holding the connection | Script auto-falls back to proxy API |
| Blank/white screenshot | Page not loaded yet | Increase --wait value |
| Truncated at bottom | Scroll container not expanded | Script handles this automatically; file an issue if it persists |
| Out of memory | Very tall page + high DPR | Reduce --dpr to 1 and/or reduce --width |
| "PIL not available for stitching" | Python Pillow not installed | Install with pip3 install Pillow or accept separate tile files |
engineering/browser-automation — General browser automation patterns via CDP/Playwrightengineering/performance-profiler — Performance analysis that may complement visual capturesdevelopment
Use when someone wants to run a weekly review, close open loops, audit stalled projects and commitments, get their system back to trusted, restart a lapsed review habit, or says "/cs:weekly-review". Walks David Allen's three-phase loop — GET CLEAR, GET CURRENT, GET CREATIVE — with deterministic scripts that inventory open loops, gate the checklist with named gaps, and score commitment health 0-100.
development
Use when someone wants to decide whether a meeting is worth calling, price a meeting in dollars, build a timeboxed agenda with desired outcomes, or turn messy meeting notes into owned action items — or says "should this be a meeting", "/cs:meeting-prep", or "/cs:meeting-actions". Runs a cost gate (ASYNC / NOT-READY / MEET), builds a decision-first agenda, and extracts an owner + due-date checklist that flags every orphan.
development
Convert a rambling description of a desired outcome into one polished, autonomous /goal prompt ready to paste into a fresh session. Use when the user says "/fable-goal", "turn this into a goal prompt", "write me a fable prompt", "write the prompt that builds X", or rambles about something they want made and asks for the prompt that makes it happen. The output is a single copy-paste prompt, never the build itself. Do NOT use when the user wants the thing built right now in this session — only when they want the PROMPT that will make it happen in a fresh session.
development
Use when someone wants to plan a deep work day, time-block their calendar or task list, budget or cut shallow work, protect focus hours, track deep-work sessions and streaks, run an end-of-day shutdown ritual, or says "/deep-work" or "/time-block". Classifies tasks deep vs shallow, builds an energy-first time-blocked schedule that refuses deep demand past the 4-hour ceiling, batches shallow work into at most two windows, and logs focus sessions against a weekly target.