Files
webshot/CLAUDE.md
2025-11-04 18:39:56 +01:00

6.6 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Overview

WebShot is a CLI tool built with Node.js and Puppeteer for capturing screenshots, videos, and full HTML snapshots of websites. It features an interactive "shoot mode" with pastel-themed terminal UI, custom automation scripts, and support for multiple export formats (PNG, JPG, WEBP, PDF, MP4, HTML).

Architecture

Core Components

Main executable (webshot):

  • Single-file CLI application with shebang (#!/usr/bin/env node)
  • Self-contained with all functionality in ~800 lines
  • Uses Puppeteer for browser automation
  • Built-in debug mode with Node.js inspector support (restarts process with --inspect)

Key architectural patterns:

  • Spinner class (webshot:79-114): Animated terminal progress indicator with rotating frames and pastel colors
  • Export functions (webshot:202-470): Modular export handlers for each format (PNG, JPG, WEBP, PDF, MP4, HTML)
  • MP4 recording (webshot:243-400): Fast screenshot-loop method that captures JPEG frames and uses ffmpeg to create video (supports both MP4 with H.264 and WebM with VP9)
  • HTML export (webshot:403-470): Downloads complete page with all assets (images, CSS, JS) into assets/ subdirectory
  • Interactive shoot mode (webshot:149-200): Race between spacebar press and countdown timer

Custom Script System

WebShot supports custom Puppeteer automation scripts via -s/--script flag. Scripts are evaluated with access to the page object and can manipulate the page before capture.

Example scripts (examples/):

  • scroll-animation.js - Smoothly scrolls to bottom and back to top
  • dark-mode.js - Attempts to enable dark mode using multiple detection methods
  • interact-form.js - Fills out forms with demo data
  • hover-effects.js - Simulates hover states on interactive elements
  • mobile-view.js - Switches to mobile viewport (375x667, iPhone SE)
  • animated-sections.js - Scrolls through sections to trigger scroll-based animations

Scripts are executed via eval() in an async context with access to page, console, and other webshot internals (webshot:722-727).

Commands

Basic Usage

# Install dependencies
pnpm install

# Make executable (if needed)
chmod +x webshot

# Run from anywhere (if in PATH)
webshot -u https://github.com --help

Common Workflows

# Screenshot with interactive shoot mode
webshot -u https://example.com

# Screenshot without delay
webshot -u https://example.com --no-delay

# High quality WEBP
webshot -u https://example.com -f webp --quality 95

# Record 10 second video (MP4)
webshot -u https://bruno-simon.com -f mp4 --duration 10000 --fps 30

# Record as WebM instead
webshot -u https://bruno-simon.com -f mp4 -o output.webm --duration 10000

# Export as PDF
webshot -u https://github.com/features -f pdf

# Download complete HTML with assets
webshot -u https://stripe.com -f html -o stripe/index.html

# Use custom automation script
webshot -u https://example.com -s examples/dark-mode.js

# Custom viewport
webshot -u https://example.com -w 1280 -h 720

# Custom shoot delay (5 seconds)
webshot -u https://example.com 5000

Debug Mode

# Enable debug logging and Node.js inspector
webshot -u https://example.com --debug

# Connect debugger on custom port
DEBUG_PORT=9230 webshot -u https://example.com --debug

# Debug with specific wait strategy (for slow sites)
webshot -u https://example.com --debug --wait-until load --timeout 60000

Debug mode:

  • Prints detailed logs prefixed with [DEBUG] in magenta (webshot:36-40)
  • Enables Puppeteer dumpio for browser console output (webshot:669)
  • Listens for page console messages, errors, and failed requests (webshot:677-682)
  • Restarts process with --inspect if not already in debug mode (webshot:7-19)

Wait Strategies

The --wait-until flag controls when navigation is considered complete:

  • load - Wait for window.load event (fastest, may miss dynamic content)
  • domcontentloaded - Wait for DOM to be ready
  • networkidle2 (default) - Wait until 2 or fewer network connections remain for 500ms
  • networkidle0 - Wait until 0 network connections remain (slowest, most complete)

Use --timeout <ms> to increase navigation timeout for slow sites (default: 30000ms).

Format-Specific Details

MP4/WebM Video Recording

Video recording uses a fast screenshot-loop method:

  1. Captures JPEG screenshots as fast as possible (quality: 60 for speed)
  2. Saves frames to temporary directory (.webshot-frames-<timestamp>/)
  3. Uses ffmpeg to convert frames to video
  4. Automatically detects output format based on file extension (.mp4 → H.264, .webm → VP9)
  5. Duplicates frames to reach target FPS using ffmpeg -r flag
  6. Cleans up temporary frames after conversion

Requires ffmpeg to be installed and available in PATH.

HTML Export

HTML export downloads a complete snapshot:

  1. Extracts all resource URLs (images, CSS, JS, favicon)
  2. Downloads each resource using Puppeteer's page.goto()
  3. Saves resources to assets/ subdirectory relative to output file
  4. Rewrites HTML to use local asset paths
  5. Returns to original page after downloading

Package Structure

  • Package manager: pnpm (uses pnpm-workspace)
  • Main entry: webshot (executable script, also set as bin in package.json)
  • Only dependency: puppeteer (uses bundled Chromium)
  • Keywords: pupeteer (sic), cli, record, screeencast (sic), shoot

Color Palette

Terminal UI uses pastel ANSI colors defined in colors object (webshot:43-63):

  • Pastels: pink (217), lavender (183), mint (158), peach (223), sky (153), coral (210), sage (151)
  • Standard: green, yellow, red, cyan, gray
  • Modifiers: bright, dim, reset

ASCII banner uses mint → sky → lavender gradient (webshot:66-76).

Important Notes

  • Single file architecture: All code lives in the webshot executable - no separate modules
  • No README: Project lacks a README.md file, all documentation is in --help output
  • No tests: No test directory or test files present
  • Script evaluation security: Custom scripts are evaluated with eval() and have full access to Node.js APIs - only use trusted scripts
  • ffmpeg dependency: MP4/WebM recording requires ffmpeg to be installed separately
  • Viewport defaults: 1920x1080 at 2x device scale factor (webshot:684-688)
  • Interactive mode: Uses raw terminal input with keypress events (webshot:152-154)
  • File overwrite: Always prompts before overwriting existing files (webshot:129-146)
  • Fonts ready: Waits for document.fonts.ready before capturing (webshot:716)