design-clone 1.2.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/README.md +26 -12
  2. package/bin/commands/clone-site.js +75 -10
  3. package/bin/commands/init.js +33 -1
  4. package/bin/commands/verify.js +5 -3
  5. package/bin/utils/validate.js +24 -8
  6. package/docs/cli-reference.md +200 -2
  7. package/docs/codebase-summary.md +309 -0
  8. package/docs/design-clone-architecture.md +259 -42
  9. package/docs/pixel-perfect.md +35 -4
  10. package/docs/project-roadmap.md +382 -0
  11. package/docs/troubleshooting.md +5 -4
  12. package/package.json +10 -8
  13. package/src/ai/__pycache__/analyze-structure.cpython-313.pyc +0 -0
  14. package/src/ai/__pycache__/extract-design-tokens.cpython-313.pyc +0 -0
  15. package/src/ai/analyze-structure.py +73 -3
  16. package/src/ai/extract-design-tokens.py +356 -13
  17. package/src/ai/prompts/__pycache__/design_tokens.cpython-313.pyc +0 -0
  18. package/src/ai/prompts/__pycache__/structure_analysis.cpython-313.pyc +0 -0
  19. package/src/ai/prompts/__pycache__/ux_audit.cpython-313.pyc +0 -0
  20. package/src/ai/prompts/design_tokens.py +133 -0
  21. package/src/ai/prompts/structure_analysis.py +329 -10
  22. package/src/ai/prompts/ux_audit.py +198 -0
  23. package/src/ai/ux-audit.js +596 -0
  24. package/src/core/app-state-snapshot.js +511 -0
  25. package/src/core/content-counter.js +342 -0
  26. package/src/core/cookie-handler.js +1 -1
  27. package/src/core/css-extractor.js +4 -4
  28. package/src/core/dimension-extractor.js +93 -21
  29. package/src/core/dimension-output.js +103 -6
  30. package/src/core/discover-pages.js +242 -14
  31. package/src/core/dom-tree-analyzer.js +298 -0
  32. package/src/core/extract-assets.js +1 -1
  33. package/src/core/framework-detector.js +538 -0
  34. package/src/core/html-extractor.js +45 -4
  35. package/src/core/lazy-loader.js +7 -7
  36. package/src/core/multi-page-screenshot.js +9 -6
  37. package/src/core/page-readiness.js +8 -8
  38. package/src/core/screenshot.js +138 -9
  39. package/src/core/section-cropper.js +209 -0
  40. package/src/core/section-detector.js +386 -0
  41. package/src/core/semantic-enhancer.js +492 -0
  42. package/src/core/state-capture.js +18 -22
  43. package/src/core/tests/test-section-cropper.js +177 -0
  44. package/src/core/tests/test-section-detector.js +55 -0
  45. package/src/core/video-capture.js +152 -146
  46. package/src/route-discoverers/angular-discoverer.js +157 -0
  47. package/src/route-discoverers/astro-discoverer.js +123 -0
  48. package/src/route-discoverers/base-discoverer.js +242 -0
  49. package/src/route-discoverers/index.js +106 -0
  50. package/src/route-discoverers/next-discoverer.js +130 -0
  51. package/src/route-discoverers/nuxt-discoverer.js +138 -0
  52. package/src/route-discoverers/react-discoverer.js +139 -0
  53. package/src/route-discoverers/svelte-discoverer.js +109 -0
  54. package/src/route-discoverers/universal-discoverer.js +227 -0
  55. package/src/route-discoverers/vue-discoverer.js +118 -0
  56. package/src/utils/__init__.py +1 -1
  57. package/src/utils/__pycache__/__init__.cpython-313.pyc +0 -0
  58. package/src/utils/browser.js +11 -37
  59. package/src/utils/playwright.js +213 -0
  60. package/src/verification/generate-audit-report.js +398 -0
  61. package/src/verification/verify-footer.js +493 -0
  62. package/src/verification/verify-header.js +486 -0
  63. package/src/verification/verify-layout.js +2 -2
  64. package/src/verification/verify-menu.js +4 -20
  65. package/src/verification/verify-slider.js +533 -0
  66. package/src/utils/puppeteer.js +0 -281
package/README.md CHANGED
@@ -1,10 +1,15 @@
1
- # Design Clone Skill for Claude Code
2
-
3
- Clone website designs with multi-viewport screenshots, HTML/CSS extraction, and Gemini AI analysis.
4
-
5
- [![npm](https://img.shields.io/npm/v/design-clone)](https://www.npmjs.com/package/design-clone)
6
- [![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
7
- [![Node](https://img.shields.io/badge/node-%3E%3D18-brightgreen.svg)](https://nodejs.org)
1
+ <div align="center">
2
+ <img src="logo.svg" alt="design-clone" width="120" height="120">
3
+ <h1>Design Clone</h1>
4
+ <p><strong>Clone website designs with multi-viewport screenshots, HTML/CSS extraction, and Gemini AI analysis.</strong></p>
5
+ <p>
6
+ <a href="https://www.npmjs.com/package/design-clone"><img src="https://img.shields.io/npm/v/design-clone" alt="npm"></a>
7
+ <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="License"></a>
8
+ <a href="https://nodejs.org"><img src="https://img.shields.io/badge/node-%3E%3D18-brightgreen.svg" alt="Node"></a>
9
+ </p>
10
+ </div>
11
+
12
+ ---
8
13
 
9
14
  ## Features
10
15
 
@@ -112,7 +117,7 @@ Get your API key at: https://aistudio.google.com/apikey
112
117
 
113
118
  - Node.js 18+
114
119
  - Python 3.9+ (for AI analysis)
115
- - Chrome or Chromium (auto-detected)
120
+ - Playwright (auto-installed with browsers)
116
121
 
117
122
  ## CLI Commands
118
123
 
@@ -145,14 +150,17 @@ pip install google-genai
145
150
  pip3 install -r requirements.txt
146
151
  ```
147
152
 
148
- ### Puppeteer issues
153
+ ### Playwright issues
149
154
 
150
155
  ```bash
151
- # Install Puppeteer if not present
152
- npm install puppeteer
156
+ # Install Playwright if not present
157
+ npm install playwright
158
+
159
+ # Install browsers
160
+ npx playwright install chromium
153
161
 
154
162
  # For Docker/CI environments
155
- export PUPPETEER_NO_SANDBOX=1
163
+ export PLAYWRIGHT_BROWSERS_PATH=/tmp/pw-browsers
156
164
  ```
157
165
 
158
166
  See full troubleshooting guide: [docs/troubleshooting.md](docs/troubleshooting.md)
@@ -172,3 +180,9 @@ MIT - See [LICENSE](LICENSE)
172
180
  ## Credits
173
181
 
174
182
  Built for use with [Claude Code](https://claude.ai/code) by Anthropic.
183
+
184
+ ---
185
+
186
+ <div align="center">
187
+ <sub>Made with ❤️ for the Claude Code community</sub>
188
+ </div>
@@ -12,6 +12,7 @@
12
12
  * --viewports <list> Viewport list (default: desktop,tablet,mobile)
13
13
  * --yes Skip confirmation prompt
14
14
  * --output <dir> Custom output directory
15
+ * --ux-audit Run UX audit using Gemini Vision (requires GEMINI_API_KEY)
15
16
  */
16
17
 
17
18
  import fs from 'fs/promises';
@@ -23,6 +24,7 @@ import { captureMultiplePages } from '../../src/core/multi-page-screenshot.js';
23
24
  import { mergeCssFiles } from '../../src/core/merge-css.js';
24
25
  import { rewriteLinks, createPageManifest, rewriteAllLinks } from '../../src/core/rewrite-links.js';
25
26
  import { extractDesignTokens } from '../../src/core/design-tokens.js';
27
+ import { runUXAudit } from '../../src/ai/ux-audit.js';
26
28
 
27
29
  /**
28
30
  * Generate output directory name
@@ -53,7 +55,8 @@ export function parseArgs(args) {
53
55
  viewports: ['desktop', 'tablet', 'mobile'],
54
56
  skipConfirm: false,
55
57
  output: null,
56
- ai: false
58
+ ai: false,
59
+ uxAudit: false
57
60
  };
58
61
 
59
62
  for (let i = 0; i < args.length; i++) {
@@ -71,6 +74,8 @@ export function parseArgs(args) {
71
74
  options.output = args[++i];
72
75
  } else if (arg === '--ai') {
73
76
  options.ai = true;
77
+ } else if (arg === '--ux-audit') {
78
+ options.uxAudit = true;
74
79
  } else if (!arg.startsWith('--') && !options.url) {
75
80
  options.url = arg;
76
81
  }
@@ -93,7 +98,8 @@ export async function cloneSite(url, options = {}) {
93
98
  viewports = ['desktop', 'tablet', 'mobile'],
94
99
  skipConfirm = false,
95
100
  output,
96
- ai = false
101
+ ai = false,
102
+ uxAudit = false
97
103
  } = options;
98
104
 
99
105
  // Validate URL
@@ -111,7 +117,7 @@ export async function cloneSite(url, options = {}) {
111
117
  console.error(`[clone-site] Output: ${outputDir}`);
112
118
 
113
119
  // Step 1: Discover or use manual pages
114
- console.error('\n[1/6] Discovering pages...');
120
+ console.error('\n[1/7] Discovering pages...');
115
121
 
116
122
  let pageList;
117
123
  if (manualPages && manualPages.length > 0) {
@@ -141,7 +147,7 @@ export async function cloneSite(url, options = {}) {
141
147
  }
142
148
 
143
149
  // Step 2: Capture all pages
144
- console.error('\n[2/6] Capturing pages...');
150
+ console.error('\n[2/7] Capturing pages...');
145
151
 
146
152
  const captureResult = await captureMultiplePages(pageList.pages, {
147
153
  outputDir,
@@ -159,7 +165,7 @@ export async function cloneSite(url, options = {}) {
159
165
  console.error(` Screenshots: ${captureResult.stats.totalScreenshots}`);
160
166
 
161
167
  // Step 3: Merge CSS files (prefer filtered CSS)
162
- console.error('\n[3/6] Merging CSS...');
168
+ console.error('\n[3/7] Merging CSS...');
163
169
 
164
170
  const mergedCssPath = path.join(outputDir, 'styles.css');
165
171
  let mergeResult = { success: false };
@@ -184,7 +190,7 @@ export async function cloneSite(url, options = {}) {
184
190
  }
185
191
 
186
192
  // Step 4: Extract design tokens (if --ai flag)
187
- console.error('\n[4/6] Extracting design tokens...');
193
+ console.error('\n[4/7] Extracting design tokens...');
188
194
 
189
195
  let hasTokens = false;
190
196
  if (ai) {
@@ -207,8 +213,64 @@ export async function cloneSite(url, options = {}) {
207
213
  console.error(' Skipped (use --ai flag to enable)');
208
214
  }
209
215
 
210
- // Step 5: Rewrite links
211
- console.error('\n[5/6] Rewriting links...');
216
+ // Step 5: UX Audit (if --ux-audit flag)
217
+ console.error('\n[5/7] Running UX audit...');
218
+
219
+ let uxAuditResult = null;
220
+ if (uxAudit) {
221
+ if (process.env.GEMINI_API_KEY || process.env.GOOGLE_API_KEY) {
222
+ // Find homepage screenshots for audit
223
+ const screenshotDir = path.join(outputDir, 'screenshots');
224
+ const screenshotPaths = {};
225
+
226
+ for (const viewport of viewports) {
227
+ const screenshotPath = path.join(screenshotDir, `index-${viewport}.png`);
228
+ try {
229
+ await fs.access(screenshotPath);
230
+ screenshotPaths[viewport] = screenshotPath;
231
+ } catch {
232
+ // Try alternative naming
233
+ const altPath = path.join(screenshotDir, `${viewport}.png`);
234
+ try {
235
+ await fs.access(altPath);
236
+ screenshotPaths[viewport] = altPath;
237
+ } catch {
238
+ // Skip this viewport
239
+ }
240
+ }
241
+ }
242
+
243
+ if (Object.keys(screenshotPaths).length > 0) {
244
+ const analysisDir = path.join(outputDir, 'analysis');
245
+ await fs.mkdir(analysisDir, { recursive: true });
246
+
247
+ uxAuditResult = await runUXAudit(screenshotPaths, {
248
+ output: analysisDir,
249
+ verbose: true,
250
+ url
251
+ });
252
+
253
+ if (uxAuditResult.success) {
254
+ console.error(` UX Score: ${uxAuditResult.summary.uxScore}%`);
255
+ console.error(` Accessibility: ${uxAuditResult.summary.accessibilityScore}%`);
256
+ console.error(` Issues: ${uxAuditResult.summary.issueCount} (${uxAuditResult.summary.criticalCount} critical)`);
257
+ console.error(` Report: analysis/ux-audit.md`);
258
+ } else {
259
+ console.error(` Warning: UX audit failed - ${uxAuditResult.error}`);
260
+ }
261
+ } else {
262
+ console.error(' Skipped: No screenshots found for audit');
263
+ }
264
+ } else {
265
+ console.error(' Skipped: GEMINI_API_KEY not set');
266
+ console.error(' Hint: Set GEMINI_API_KEY in ~/.claude/.env for UX audit');
267
+ }
268
+ } else {
269
+ console.error(' Skipped (use --ux-audit flag to enable)');
270
+ }
271
+
272
+ // Step 6: Rewrite links
273
+ console.error('\n[6/7] Rewriting links...');
212
274
 
213
275
  const manifest = createPageManifest(pageList.pages, {
214
276
  hasTokens,
@@ -241,8 +303,8 @@ export async function cloneSite(url, options = {}) {
241
303
  }
242
304
  }
243
305
 
244
- // Step 6: Generate manifest
245
- console.error('\n[6/6] Generating manifest...');
306
+ // Step 7: Generate manifest
307
+ console.error('\n[7/7] Generating manifest...');
246
308
 
247
309
  const manifestPath = path.join(outputDir, 'manifest.json');
248
310
  await fs.writeFile(manifestPath, JSON.stringify(manifest, null, 2));
@@ -261,6 +323,7 @@ export async function cloneSite(url, options = {}) {
261
323
  manifest,
262
324
  captureResult,
263
325
  mergeResult,
326
+ uxAuditResult,
264
327
  totalTimeMs: totalTime
265
328
  };
266
329
  }
@@ -281,12 +344,14 @@ Options:
281
344
  --yes Skip confirmation prompt
282
345
  --output <dir> Custom output directory
283
346
  --ai Extract design tokens using Gemini AI (requires GEMINI_API_KEY)
347
+ --ux-audit Run UX audit using Gemini Vision (requires GEMINI_API_KEY)
284
348
 
285
349
  Examples:
286
350
  design-clone clone-site https://example.com
287
351
  design-clone clone-site https://example.com --max-pages 5
288
352
  design-clone clone-site https://example.com --pages /,/about,/contact
289
353
  design-clone clone-site https://example.com --ai
354
+ design-clone clone-site https://example.com --ux-audit
290
355
  `);
291
356
  }
292
357
 
@@ -50,7 +50,7 @@ export async function init(args) {
50
50
  }
51
51
 
52
52
  if (!checks.chrome.ok) {
53
- console.warn('Warning: Chrome not found. Screenshots may not work without Puppeteer\'s bundled Chromium.');
53
+ console.warn('Warning: Chrome not found. Playwright will download Chromium during installation.');
54
54
  }
55
55
 
56
56
  // Check existing installation
@@ -129,6 +129,38 @@ export async function init(args) {
129
129
  console.warn(` Warning: npm install failed: ${error.message}`);
130
130
  }
131
131
 
132
+ // Install Playwright
133
+ console.log('Installing Playwright...');
134
+ try {
135
+ // Check if playwright is already installed
136
+ let playwrightInstalled = false;
137
+ try {
138
+ await exec('node -e "require.resolve(\'playwright\')"', { cwd: SKILL_DEST });
139
+ playwrightInstalled = true;
140
+ console.log(' Playwright already installed');
141
+ } catch {
142
+ // Need to install
143
+ }
144
+
145
+ if (!playwrightInstalled) {
146
+ await exec('npm install playwright', { cwd: SKILL_DEST });
147
+ console.log(' Playwright installed');
148
+ }
149
+
150
+ // Install Playwright browsers (chromium only for smaller footprint)
151
+ console.log('Installing Playwright browsers...');
152
+ try {
153
+ await exec('npx playwright install chromium', { cwd: SKILL_DEST, timeout: 300000 });
154
+ console.log(' Chromium browser installed');
155
+ } catch (browserError) {
156
+ console.warn(` Warning: Browser install failed: ${browserError.message}`);
157
+ console.warn(' Run manually: npx playwright install chromium');
158
+ }
159
+ } catch (error) {
160
+ console.warn(` Warning: Playwright install failed: ${error.message}`);
161
+ console.warn(' Run manually: npm install playwright && npx playwright install chromium');
162
+ }
163
+
132
164
  // Python dependencies
133
165
  if (checks.python.ok) {
134
166
  console.log('Installing Python dependencies...');
@@ -63,11 +63,13 @@ export async function verify() {
63
63
  console.log('\nEnvironment:');
64
64
  const checks = await runAllChecks();
65
65
 
66
- console.log(` Node.js: ${checks.node.ok ? '✓' : '✗'} ${checks.node.message}`);
67
- console.log(` Python: ${checks.python.ok ? '✓' : '✗'} ${checks.python.message}`);
68
- console.log(` Chrome: ${checks.chrome.ok ? '✓' : '✗'} ${checks.chrome.message}`);
66
+ console.log(` Node.js: ${checks.node.ok ? '✓' : '✗'} ${checks.node.message}`);
67
+ console.log(` Python: ${checks.python.ok ? '✓' : '✗'} ${checks.python.message}`);
68
+ console.log(` Playwright: ${checks.playwright.ok ? '✓' : '✗'} ${checks.playwright.message}`);
69
+ console.log(` Chrome: ${checks.chrome.ok ? '✓' : '○'} ${checks.chrome.message}${checks.playwright.ok ? ' (optional with Playwright)' : ''}`);
69
70
 
70
71
  if (!checks.node.ok) allOk = false;
72
+ if (!checks.playwright.ok && !checks.chrome.ok) allOk = false;
71
73
 
72
74
  // Check Gemini API key
73
75
  console.log('\nOptional:');
@@ -94,15 +94,31 @@ export async function checkChrome() {
94
94
  }
95
95
 
96
96
  /**
97
- * Check Puppeteer
97
+ * Check Playwright
98
98
  * @returns {Promise<{ok: boolean, message: string}>}
99
99
  */
100
- export async function checkPuppeteer() {
100
+ export async function checkPlaywright() {
101
101
  try {
102
- await import('puppeteer');
103
- return { ok: true, message: 'Puppeteer installed' };
102
+ const playwright = await import('playwright');
103
+ // Check if browsers are installed by checking chromium executable
104
+ if (playwright.chromium?.executablePath) {
105
+ try {
106
+ const fs = await import('fs/promises');
107
+ await fs.access(playwright.chromium.executablePath());
108
+ return { ok: true, message: 'Playwright installed with browsers' };
109
+ } catch {
110
+ return { ok: true, message: 'Playwright installed (browsers may need install)' };
111
+ }
112
+ }
113
+ return { ok: true, message: 'Playwright installed' };
104
114
  } catch {
105
- return { ok: false, message: 'Puppeteer not installed (optional)' };
115
+ // Try playwright-core
116
+ try {
117
+ await import('playwright-core');
118
+ return { ok: true, message: 'playwright-core installed (needs Chrome)' };
119
+ } catch {
120
+ return { ok: false, message: 'Playwright not installed' };
121
+ }
106
122
  }
107
123
  }
108
124
 
@@ -111,12 +127,12 @@ export async function checkPuppeteer() {
111
127
  * @returns {Promise<Object>}
112
128
  */
113
129
  export async function runAllChecks() {
114
- const [node, python, chrome, puppeteer] = await Promise.all([
130
+ const [node, python, chrome, playwright] = await Promise.all([
115
131
  checkNode(),
116
132
  checkPython(),
117
133
  checkChrome(),
118
- checkPuppeteer()
134
+ checkPlaywright()
119
135
  ]);
120
136
 
121
- return { node, python, chrome, puppeteer };
137
+ return { node, python, chrome, playwright };
122
138
  }
@@ -25,11 +25,49 @@ node src/core/screenshot.js [options]
25
25
  | --extract-animations | bool | true* | Extract @keyframes and transitions (enabled with --extract-css) |
26
26
  | --filter-unused | bool | true | Filter CSS to remove unused selectors |
27
27
  | --capture-hover | bool | false | Capture hover state screenshots and generate :hover CSS |
28
+ | --no-semantic | bool | false | Disable WordPress semantic HTML enhancement (Phase 3) |
28
29
  | --verbose | bool | false | Verbose logging |
29
30
 
30
31
  *Default true when --extract-css is enabled, can be disabled with `--extract-animations false`
31
32
 
32
- **Output**: JSON with screenshot paths and metadata. Includes `browserRestarts` count tracking for stability monitoring. When `--capture-hover` is enabled, also includes hover state results in output.
33
+ **Output**: JSON with screenshot paths and metadata. Includes `browserRestarts` count tracking for stability monitoring. When `--capture-hover` is enabled, also includes hover state results in output. When semantic enhancement is enabled (default), output includes `semanticStats` with enhancement details (sections enhanced, IDs/classes/roles added).
34
+
35
+ ### Semantic HTML Enhancement (Phase 3)
36
+
37
+ Semantic HTML enhancement is enabled by default when extracting HTML. It injects WordPress-compatible semantic IDs, classes, and ARIA roles into the extracted HTML.
38
+
39
+ **What's Added**:
40
+ - **IDs**: `site-header`, `main-content`, `site-footer`, `site-navigation`, `primary-sidebar`, `hero-section`
41
+ - **Classes**: `site-header`, `main-navigation`, `nav-menu`, `site-main`, `content-area`, `widget-area`, `sidebar`, `site-footer`, `hero`
42
+ - **ARIA Roles**: `banner` (header), `navigation` (nav), `main`, `complementary` (sidebar), `contentinfo` (footer)
43
+
44
+ **Detection Priority**:
45
+ 1. Semantic HTML tags (`<header>`, `<nav>`, `<main>`, `<aside>`, `<footer>`)
46
+ 2. ARIA role attributes (`banner`, `navigation`, `main`, `complementary`, `contentinfo`)
47
+ 3. Class patterns (header, nav, main, sidebar, footer, hero)
48
+
49
+ **Usage**:
50
+ ```bash
51
+ # Enable semantic enhancement (default)
52
+ node src/core/screenshot.js --url https://example.com --output ./out --extract-html
53
+
54
+ # Disable semantic enhancement
55
+ node src/core/screenshot.js --url https://example.com --output ./out --extract-html --no-semantic
56
+ ```
57
+
58
+ **Example Output Metadata**:
59
+ ```json
60
+ {
61
+ "html": "path/to/source.html",
62
+ "semanticStats": {
63
+ "sectionsEnhanced": 5,
64
+ "idsAdded": 3,
65
+ "classesAdded": 4,
66
+ "rolesAdded": 2,
67
+ "warnings": []
68
+ }
69
+ }
70
+ ```
33
71
 
34
72
  ## filter-css.js
35
73
 
@@ -86,9 +124,62 @@ node src/core/extract-assets.js --url URL --output DIR
86
124
  Validate navigation structure.
87
125
 
88
126
  ```bash
89
- node src/verification/verify-menu.js --html FILE
127
+ node src/verification/verify-menu.js --html FILE [--url URL] [--output DIR] [--verbose]
128
+ ```
129
+
130
+ | Option | Description |
131
+ |--------|-------------|
132
+ | --html | Path to HTML file |
133
+ | --url | URL to test (alternative to --html) |
134
+ | --output | Output directory for screenshots |
135
+ | --verbose | Show detailed progress |
136
+
137
+ ## verify-header.js
138
+
139
+ Verify header components (Phase 1).
140
+
141
+ ```bash
142
+ node src/verification/verify-header.js --html FILE [--url URL] [--output DIR] [--verbose]
143
+ ```
144
+
145
+ Tests: logo presence, navigation visibility, CTA buttons, sticky/fixed behavior, z-index layering, height consistency.
146
+
147
+ ## verify-footer.js
148
+
149
+ Verify footer components (Phase 1).
150
+
151
+ ```bash
152
+ node src/verification/verify-footer.js --html FILE [--url URL] [--output DIR] [--verbose]
153
+ ```
154
+
155
+ Tests: position at bottom, multi-column layout, link sections, copyright text, social icons, background contrast.
156
+
157
+ ## verify-slider.js
158
+
159
+ Verify slider/carousel components (Phase 1).
160
+
161
+ ```bash
162
+ node src/verification/verify-slider.js --html FILE [--url URL] [--output DIR] [--verbose]
163
+ ```
164
+
165
+ Tests: library detection (Swiper, Slick, Owl, native), navigation arrows, pagination dots, autoplay behavior, current slide indicator.
166
+
167
+ ## generate-audit-report.js
168
+
169
+ Aggregate verification results into consolidated report (Phase 1).
170
+
171
+ ```bash
172
+ node src/verification/generate-audit-report.js --dir DIR [--output FILE] [--verbose]
90
173
  ```
91
174
 
175
+ | Option | Description |
176
+ |--------|-------------|
177
+ | --dir | Directory containing verification JSON results |
178
+ | --output | Output path for report (default: component-audit.md) |
179
+ | --verbose | Show detailed progress |
180
+
181
+ Output: Markdown report with summary table, side-by-side screenshots, responsive analysis, CSS suggestions.
182
+
92
183
  ## verify-layout.js
93
184
 
94
185
  Verify layout consistency.
@@ -116,3 +207,110 @@ Used internally by screenshot.js with `--capture-hover` flag.
116
207
  - Automatic screenshot pair generation (normal + hover states)
117
208
  - CSS rule generation from detected style changes
118
209
  - Validates selectors and skips hidden/invisible elements
210
+
211
+ ## ux-audit.js
212
+
213
+ UX quality assessment using Gemini Vision AI (Phase 2).
214
+
215
+ ```bash
216
+ node src/ai/ux-audit.js --screenshots <dir> [--output <dir>] [--url <url>] [--verbose]
217
+ ```
218
+
219
+ | Option | Required | Description |
220
+ |--------|----------|-------------|
221
+ | --screenshots | yes | Directory containing viewport screenshots (desktop.png, tablet.png, mobile.png) |
222
+ | --output | no | Output directory for report and JSON results (default: same as screenshots) |
223
+ | --url | no | Original URL (for report metadata) |
224
+ | --verbose | no | Show detailed progress |
225
+
226
+ **Requires**: GEMINI_API_KEY or GOOGLE_API_KEY environment variable
227
+
228
+ **Output**:
229
+ - `ux-audit.md`: Markdown report with scores, issues, and recommendations
230
+ - `ux-audit.json`: Structured results (aggregated scores, viewport breakdown, issues, recommendations)
231
+
232
+ **Evaluation Categories** (0-100 score each):
233
+ 1. Visual Hierarchy - Content prominence, scanning patterns, call-to-action visibility
234
+ 2. Navigation - Touch targets, menu discoverability, current page indicator
235
+ 3. Typography - Text size, line height, contrast ratio, readability
236
+ 4. Spacing - Padding/margins, element breathing room, touch target spacing
237
+ 5. Interactive Elements - Button affordance, link distinguishability, focus states
238
+ 6. Responsive - Content reflow, no horizontal scroll, text truncation, breakpoint transitions
239
+
240
+ **Viewport Analysis**: Evaluates all three viewports (desktop: 1920×1080, tablet: 768×1024, mobile: 375×812) and generates weighted scores (desktop 40%, tablet 30%, mobile 30%).
241
+
242
+ **Issue Severity Levels**:
243
+ - Critical (0-30 score): Blocks tasks or causes confusion
244
+ - Major (31-60 score): Degrades experience significantly
245
+ - Minor (61-80 score): Polish improvements
246
+
247
+ **Scoring Scale**:
248
+ - 90-100: Excellent, industry-leading UX
249
+ - 70-89: Good, meets modern standards
250
+ - 50-69: Adequate, room for improvement
251
+ - 30-49: Poor, significant issues
252
+ - 0-29: Critical, requires immediate attention
253
+
254
+ ## clone-site.js
255
+
256
+ Clone multiple pages from website with integrated UX audit (Phase 2).
257
+
258
+ ```bash
259
+ design-clone clone-site <url> [options]
260
+ ```
261
+
262
+ | Option | Description |
263
+ |--------|-------------|
264
+ | --pages <paths> | Comma-separated paths (e.g., /,/about,/contact) |
265
+ | --max-pages <n> | Maximum pages to auto-discover (default: 10) |
266
+ | --viewports <list> | Viewport list (default: desktop,tablet,mobile) |
267
+ | --output <dir> | Custom output directory |
268
+ | --ai | Extract design tokens using Gemini AI (requires GEMINI_API_KEY) |
269
+ | --ux-audit | Run UX audit using Gemini Vision (requires GEMINI_API_KEY) |
270
+ | --yes, -y | Skip confirmation prompt |
271
+
272
+ **Integrated Workflow** (when using --ux-audit):
273
+ 1. Discover or use manual pages
274
+ 2. Capture screenshots across viewports
275
+ 3. Merge CSS files
276
+ 4. Extract design tokens (with --ai)
277
+ 5. **Run UX audit** (with --ux-audit) - Analyzes homepage screenshots via Gemini Vision
278
+ 6. Rewrite links
279
+ 7. Generate manifest
280
+
281
+ **UX Audit Output**: When enabled, generates `analysis/ux-audit.md` and `analysis/ux-audit.json` in output directory.
282
+
283
+ **Examples**:
284
+ ```bash
285
+ design-clone clone-site https://example.com --ux-audit
286
+ design-clone clone-site https://example.com --pages /,/about,/contact --ux-audit
287
+ design-clone clone-site https://example.com --ai --ux-audit
288
+ ```
289
+
290
+ ## ux_audit.py
291
+
292
+ Python module providing UX audit prompts for Gemini Vision integration.
293
+
294
+ ```python
295
+ from src.ai.prompts.ux_audit import build_ux_audit_prompt, build_aggregation_prompt
296
+
297
+ # Build viewport-specific prompt
298
+ prompt = build_ux_audit_prompt(viewport='mobile')
299
+
300
+ # Build aggregation prompt for multiple viewports
301
+ aggregation = build_aggregation_prompt(desktop_results, tablet_results, mobile_results)
302
+ ```
303
+
304
+ **Functions**:
305
+ - `build_ux_audit_prompt(viewport)` - Build prompt with viewport-specific checks (mobile/tablet/desktop)
306
+ - `build_aggregation_prompt(desktop, tablet, mobile)` - Combine viewport results into unified assessment
307
+
308
+ **Constants**:
309
+ - `UX_AUDIT_PROMPT` - Base UX evaluation prompt (6 categories)
310
+ - `VIEWPORT_CONTEXT` - Dictionary of viewport-specific evaluation criteria
311
+ - `AGGREGATION_PROMPT` - Template for combining viewport results with weighted averaging
312
+
313
+ **Viewport Weighting**:
314
+ - Desktop: 40% (primary interaction model)
315
+ - Tablet: 30% (hybrid interaction)
316
+ - Mobile: 30% (touch-first)