# Screenshot Helper

Guide for capturing screenshots using Chrome MCP.

## Overview

This script helps capture screenshots of web interfaces for the software manual using Chrome MCP or fallback methods.

## Chrome MCP Prerequisites

### Check MCP Availability

```javascript
async function checkChromeMCPAvailability() {
  try {
    // Attempt to get Chrome version via MCP
    const version = await mcp__chrome__getVersion();
    return {
      available: true,
      browser: version.browser,
      version: version.version
    };
  } catch (error) {
    return {
      available: false,
      error: error.message
    };
  }
}
```

### MCP Configuration

Expected Claude configuration for Chrome MCP:

```json
{
  "mcpServers": {
    "chrome": {
      "command": "npx",
      "args": ["@anthropic-ai/mcp-chrome"],
      "env": {
        "CHROME_PATH": "C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe"
      }
    }
  }
}
```

## Screenshot Workflow

### Step 1: Prepare Environment

```javascript
async function prepareScreenshotEnvironment(workDir, config) {
  const screenshotDir = `${workDir}/screenshots`;

  // Create directory
  Bash({ command: `mkdir -p "${screenshotDir}"` });

  // Check Chrome MCP
  const chromeMCP = await checkChromeMCPAvailability();

  if (!chromeMCP.available) {
    console.log('Chrome MCP not available. Will generate manual guide.');
    return { mode: 'manual' };
  }

  // Start development server if needed
  if (config.screenshot_config?.dev_command) {
    const server = await startDevServer(config);
    return { mode: 'auto', server, screenshotDir };
  }

  return { mode: 'auto', screenshotDir };
}
```

### Step 2: Start Development Server

```javascript
async function startDevServer(config) {
  const devCommand = config.screenshot_config.dev_command;
  const devUrl = config.screenshot_config.dev_url;

  // Start server in background
  const server = Bash({
    command: devCommand,
    run_in_background: true
  });

  console.log(`Starting dev server: ${devCommand}`);

  // Wait for server to be ready
  const ready = await waitForServer(devUrl, 30000);

  if (!ready) {
    throw new Error(`Server at ${devUrl} did not start in time`);
  }

  console.log(`Dev server ready at ${devUrl}`);

  return server;
}

async function waitForServer(url, timeout = 30000) {
  const start = Date.now();

  while (Date.now() - start < timeout) {
    try {
      const response = await fetch(url, { method: 'HEAD' });
      if (response.ok) return true;
    } catch (e) {
      // Server not ready
    }
    await sleep(1000);
  }

  return false;
}
```

### Step 3: Capture Screenshots

```javascript
async function captureScreenshots(screenshots, config, workDir) {
  const results = {
    captured: [],
    failed: []
  };

  const devUrl = config.screenshot_config.dev_url;
  const screenshotDir = `${workDir}/screenshots`;

  for (const ss of screenshots) {
    try {
      // Build full URL
      const fullUrl = new URL(ss.url, devUrl).href;

      console.log(`Capturing: ${ss.id} (${fullUrl})`);

      // Configure capture options
      const options = {
        url: fullUrl,
        viewport: { width: 1280, height: 800 },
        fullPage: ss.fullPage || false
      };

      // Wait for specific element if specified
      if (ss.wait_for) {
        options.waitFor = ss.wait_for;
      }

      // Capture specific element if selector provided
      if (ss.selector) {
        options.selector = ss.selector;
      }

      // Add delay for animations
      await sleep(500);

      // Capture via Chrome MCP
      const result = await mcp__chrome__screenshot(options);

      // Save as PNG
      const filename = `${ss.id}.png`;
      Write(`${screenshotDir}/${filename}`, result.data, { encoding: 'base64' });

      results.captured.push({
        id: ss.id,
        file: filename,
        url: ss.url,
        description: ss.description,
        size: result.data.length
      });

    } catch (error) {
      console.error(`Failed to capture ${ss.id}:`, error.message);
      results.failed.push({
        id: ss.id,
        url: ss.url,
        error: error.message
      });
    }
  }

  return results;
}
```

### Step 4: Generate Manifest

```javascript
function generateScreenshotManifest(results, workDir) {
  const manifest = {
    generated: new Date().toISOString(),
    total: results.captured.length + results.failed.length,
    captured: results.captured.length,
    failed: results.failed.length,
    screenshots: results.captured,
    failures: results.failed
  };

  Write(`${workDir}/screenshots/screenshots-manifest.json`,
        JSON.stringify(manifest, null, 2));

  return manifest;
}
```

### Step 5: Cleanup

```javascript
async function cleanupScreenshotEnvironment(env) {
  if (env.server) {
    console.log('Stopping dev server...');
    KillShell({ shell_id: env.server.task_id });
  }
}
```

## Main Runner

```javascript
async function runScreenshotCapture(workDir, screenshots) {
  const config = JSON.parse(Read(`${workDir}/manual-config.json`));

  // Prepare environment
  const env = await prepareScreenshotEnvironment(workDir, config);

  if (env.mode === 'manual') {
    // Generate manual capture guide
    generateManualCaptureGuide(screenshots, workDir);
    return { success: false, mode: 'manual' };
  }

  try {
    // Capture screenshots
    const results = await captureScreenshots(screenshots, config, workDir);

    // Generate manifest
    const manifest = generateScreenshotManifest(results, workDir);

    // Generate manual guide for failed captures
    if (results.failed.length > 0) {
      generateManualCaptureGuide(results.failed, workDir);
    }

    return {
      success: true,
      captured: results.captured.length,
      failed: results.failed.length,
      manifest
    };

  } finally {
    // Cleanup
    await cleanupScreenshotEnvironment(env);
  }
}
```

## Manual Capture Fallback

When Chrome MCP is unavailable:

```javascript
function generateManualCaptureGuide(screenshots, workDir) {
  const guide = `
# Manual Screenshot Capture Guide

Chrome MCP is not available. Please capture screenshots manually.

## Prerequisites

1. Start your development server
2. Open a browser
3. Use a screenshot tool (Snipping Tool, Screenshot, etc.)

## Screenshots Required

${screenshots.map((ss, i) => `
### ${i + 1}. ${ss.id}

- **URL**: ${ss.url}
- **Description**: ${ss.description}
- **Save as**: \`screenshots/${ss.id}.png\`
${ss.selector ? `- **Capture area**: \`${ss.selector}\` element only` : '- **Type**: Full page or viewport'}
${ss.wait_for ? `- **Wait for**: \`${ss.wait_for}\` to be visible` : ''}

**Steps:**
1. Navigate to ${ss.url}
${ss.wait_for ? `2. Wait for ${ss.wait_for} to appear` : ''}
${ss.selector ? `2. Capture only the ${ss.selector} area` : '2. Capture the full viewport'}
3. Save as \`${ss.id}.png\`
`).join('\n')}

## After Capturing

1. Place all PNG files in the \`screenshots/\` directory
2. Ensure filenames match exactly (case-sensitive)
3. Run Phase 5 (HTML Assembly) to continue

## Screenshot Specifications

- **Format**: PNG
- **Width**: 1280px recommended
- **Quality**: High
- **Annotations**: None (add in post-processing if needed)
`;

  Write(`${workDir}/screenshots/MANUAL_CAPTURE.md`, guide);
}
```

## Advanced Options

### Viewport Sizes

```javascript
const viewportPresets = {
  desktop: { width: 1280, height: 800 },
  tablet: { width: 768, height: 1024 },
  mobile: { width: 375, height: 667 },
  wide: { width: 1920, height: 1080 }
};

async function captureResponsive(ss, config, workDir) {
  const results = [];

  for (const [name, viewport] of Object.entries(viewportPresets)) {
    const result = await mcp__chrome__screenshot({
      url: ss.url,
      viewport
    });

    const filename = `${ss.id}-${name}.png`;
    Write(`${workDir}/screenshots/${filename}`, result.data, { encoding: 'base64' });

    results.push({ viewport: name, file: filename });
  }

  return results;
}
```

### Before/After Comparisons

```javascript
async function captureInteraction(ss, config, workDir) {
  const baseUrl = config.screenshot_config.dev_url;
  const fullUrl = new URL(ss.url, baseUrl).href;

  // Capture before state
  const before = await mcp__chrome__screenshot({
    url: fullUrl,
    viewport: { width: 1280, height: 800 }
  });
  Write(`${workDir}/screenshots/${ss.id}-before.png`, before.data, { encoding: 'base64' });

  // Perform interaction (click, type, etc.)
  if (ss.interaction) {
    await mcp__chrome__click({ selector: ss.interaction.click });
    await sleep(500);
  }

  // Capture after state
  const after = await mcp__chrome__screenshot({
    url: fullUrl,
    viewport: { width: 1280, height: 800 }
  });
  Write(`${workDir}/screenshots/${ss.id}-after.png`, after.data, { encoding: 'base64' });

  return {
    before: `${ss.id}-before.png`,
    after: `${ss.id}-after.png`
  };
}
```

### Screenshot Annotation

```javascript
function generateAnnotationGuide(screenshots, workDir) {
  const guide = `
# Screenshot Annotation Guide

For screenshots requiring callouts or highlights:

## Tools
- macOS: Preview, Skitch
- Windows: Snipping Tool, ShareX
- Cross-platform: Greenshot, Lightshot

## Annotation Guidelines

1. **Callouts**: Use numbered circles (1, 2, 3)
2. **Highlights**: Use semi-transparent rectangles
3. **Arrows**: Point from text to element
4. **Text**: Use sans-serif font, 12-14pt

## Color Scheme

- Primary: #0d6efd (blue)
- Secondary: #6c757d (gray)
- Success: #198754 (green)
- Warning: #ffc107 (yellow)
- Danger: #dc3545 (red)

## Screenshots Needing Annotation

${screenshots.filter(s => s.annotate).map(ss => `
- **${ss.id}**: ${ss.description}
  - Highlight: ${ss.annotate.highlight || 'N/A'}
  - Callouts: ${ss.annotate.callouts?.join(', ') || 'N/A'}
`).join('\n')}
`;

  Write(`${workDir}/screenshots/ANNOTATION_GUIDE.md`, guide);
}
```

## Troubleshooting

### Chrome MCP Not Found

1. Check Claude MCP configuration
2. Verify Chrome is installed
3. Check CHROME_PATH environment variable

### Screenshots Are Blank

1. Increase wait time before capture
2. Check if page requires authentication
3. Verify URL is correct

### Elements Not Visible

1. Scroll element into view
2. Expand collapsed sections
3. Wait for animations to complete

### Server Not Starting

1. Check if port is already in use
2. Verify dev command is correct
3. Check for startup errors in logs
