design-clone 2.1.0 → 2.3.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 (177) hide show
  1. package/README.md +13 -34
  2. package/SKILL.md +69 -45
  3. package/bin/cli.js +22 -4
  4. package/bin/commands/clone-site.js +31 -171
  5. package/bin/commands/help.js +19 -6
  6. package/bin/commands/init.js +9 -86
  7. package/bin/commands/uninstall.js +105 -0
  8. package/bin/commands/update.js +70 -0
  9. package/bin/commands/verify.js +7 -14
  10. package/bin/utils/paths.js +28 -0
  11. package/bin/utils/validate.js +2 -22
  12. package/bin/utils/version.js +23 -0
  13. package/docs/code-standards.md +789 -0
  14. package/docs/codebase-summary.md +533 -286
  15. package/docs/index.md +74 -0
  16. package/docs/project-overview-pdr.md +797 -0
  17. package/docs/system-architecture.md +718 -0
  18. package/package.json +14 -17
  19. package/src/ai/prompts/design-tokens/basic.md +80 -0
  20. package/src/ai/prompts/design-tokens/section-with-css.md +41 -0
  21. package/src/ai/prompts/design-tokens/section.md +48 -0
  22. package/src/ai/prompts/design-tokens/with-css.md +87 -0
  23. package/src/ai/prompts/structure-analysis/basic.md +55 -0
  24. package/src/ai/prompts/structure-analysis/with-context.md +59 -0
  25. package/src/ai/prompts/structure-analysis/with-dimensions.md +63 -0
  26. package/src/ai/prompts/structure-analysis/with-hierarchy.md +73 -0
  27. package/src/ai/prompts/ux-audit/aggregation.md +42 -0
  28. package/src/ai/prompts/ux-audit/desktop.md +92 -0
  29. package/src/ai/prompts/ux-audit/mobile.md +93 -0
  30. package/src/ai/prompts/ux-audit/tablet.md +92 -0
  31. package/src/core/animation/animation-extractor-ast.js +183 -0
  32. package/src/core/animation/animation-extractor-output.js +152 -0
  33. package/src/core/animation/animation-extractor.js +178 -0
  34. package/src/core/animation/state-capture-detection.js +200 -0
  35. package/src/core/animation/state-capture.js +193 -0
  36. package/src/core/capture/browser-context-pool.js +96 -0
  37. package/src/core/capture/multi-page-screenshot-page.js +110 -0
  38. package/src/core/capture/multi-page-screenshot.js +208 -0
  39. package/src/core/capture/screenshot-extraction.js +186 -0
  40. package/src/core/capture/screenshot-helpers.js +175 -0
  41. package/src/core/capture/screenshot-orchestrator.js +174 -0
  42. package/src/core/capture/screenshot-viewport.js +93 -0
  43. package/src/core/capture/screenshot.js +192 -0
  44. package/src/core/content/content-counter-dom.js +191 -0
  45. package/src/core/content/content-counter.js +76 -0
  46. package/src/core/css/breakpoint-detector.js +66 -0
  47. package/src/core/css/chromium-defaults.json +23 -0
  48. package/src/core/css/computed-style-extractor.js +102 -0
  49. package/src/core/css/css-chunker.js +103 -0
  50. package/src/core/css/filter-css-dead-code.js +120 -0
  51. package/src/core/css/filter-css-html-analyzer.js +110 -0
  52. package/src/core/css/filter-css-selector-matcher.js +172 -0
  53. package/src/core/css/filter-css.js +206 -0
  54. package/src/core/css/merge-css-atrule-processor.js +158 -0
  55. package/src/core/css/merge-css-file-io.js +68 -0
  56. package/src/core/css/merge-css.js +148 -0
  57. package/src/core/detection/framework-detector-routing.js +68 -0
  58. package/src/core/detection/framework-detector-signals.js +65 -0
  59. package/src/core/detection/framework-detector.js +198 -0
  60. package/src/core/dimension/dimension-extractor-card-detector.js +82 -0
  61. package/src/core/dimension/dimension-extractor.js +317 -0
  62. package/src/core/dimension/dimension-output-ai-summary.js +111 -0
  63. package/src/core/dimension/dimension-output.js +173 -0
  64. package/src/core/dimension/dom-tree-analyzer-tree-builders.js +95 -0
  65. package/src/core/dimension/dom-tree-analyzer.js +191 -0
  66. package/src/core/discovery/app-state-snapshot-capture.js +195 -0
  67. package/src/core/discovery/app-state-snapshot-utils.js +178 -0
  68. package/src/core/discovery/app-state-snapshot.js +131 -0
  69. package/src/core/discovery/discover-pages-routes.js +84 -0
  70. package/src/core/discovery/discover-pages-utils.js +177 -0
  71. package/src/core/discovery/discover-pages.js +191 -0
  72. package/src/core/html/html-extractor-inline-styler.js +70 -0
  73. package/src/core/html/html-extractor.js +147 -0
  74. package/src/core/html/semantic-enhancer-mappings.js +200 -0
  75. package/src/core/html/semantic-enhancer-page.js +148 -0
  76. package/src/core/html/semantic-enhancer.js +135 -0
  77. package/src/core/links/rewrite-links-css-rewriter.js +53 -0
  78. package/src/core/links/rewrite-links.js +173 -0
  79. package/src/core/media/asset-validator.js +118 -0
  80. package/src/core/media/extract-assets-downloader.js +187 -0
  81. package/src/core/media/extract-assets-page-scraper.js +115 -0
  82. package/src/core/media/extract-assets.js +159 -0
  83. package/src/core/media/video-capture-convert.js +200 -0
  84. package/src/core/media/video-capture.js +201 -0
  85. package/src/core/{lazy-loader.js → page-prep/lazy-loader.js} +37 -39
  86. package/src/core/section/section-cropper-helpers.js +43 -0
  87. package/src/core/{section-cropper.js → section/section-cropper.js} +11 -88
  88. package/src/core/section/section-detector-strategies.js +139 -0
  89. package/src/core/section/section-detector-utils.js +100 -0
  90. package/src/core/section/section-detector.js +88 -0
  91. package/src/core/tests/test-section-cropper.js +2 -2
  92. package/src/core/tests/test-section-detector.js +2 -2
  93. package/src/post-process/enhance-assets.js +29 -4
  94. package/src/post-process/fetch-images-unsplash-client.js +123 -0
  95. package/src/post-process/fetch-images.js +60 -263
  96. package/src/post-process/inject-gosnap.js +88 -0
  97. package/src/post-process/inject-icons-svg-replacer.js +76 -0
  98. package/src/post-process/inject-icons.js +47 -200
  99. package/src/route-discoverers/base-discoverer-utils.js +137 -0
  100. package/src/route-discoverers/base-discoverer.js +29 -118
  101. package/src/route-discoverers/index.js +1 -1
  102. package/src/shared/config.js +38 -0
  103. package/src/shared/error-codes.js +31 -0
  104. package/src/shared/viewports.js +46 -0
  105. package/src/utils/browser.js +0 -7
  106. package/src/utils/helpers.js +4 -0
  107. package/src/utils/log.js +12 -0
  108. package/src/utils/playwright-loader.js +76 -0
  109. package/src/utils/playwright.js +3 -69
  110. package/src/utils/progress.js +32 -0
  111. package/src/verification/generate-audit-report-css-fixes.js +52 -0
  112. package/src/verification/generate-audit-report-sections.js +158 -0
  113. package/src/verification/generate-audit-report.js +5 -281
  114. package/src/verification/quality-scorer.js +92 -0
  115. package/src/verification/verify-footer-checks.js +103 -0
  116. package/src/verification/verify-footer-helpers.js +178 -0
  117. package/src/verification/verify-footer.js +23 -381
  118. package/src/verification/verify-header-checks.js +104 -0
  119. package/src/verification/verify-header-helpers.js +156 -0
  120. package/src/verification/verify-header.js +23 -365
  121. package/src/verification/verify-layout-report.js +101 -0
  122. package/src/verification/verify-layout.js +13 -259
  123. package/src/verification/verify-menu-checks.js +104 -0
  124. package/src/verification/verify-menu-helpers.js +112 -0
  125. package/src/verification/verify-menu.js +17 -285
  126. package/src/verification/verify-slider-checks.js +115 -0
  127. package/src/verification/verify-slider-constants.js +65 -0
  128. package/src/verification/verify-slider-helpers.js +164 -0
  129. package/src/verification/verify-slider.js +23 -414
  130. package/.env.example +0 -14
  131. package/docs/basic-clone.md +0 -63
  132. package/docs/cli-reference.md +0 -316
  133. package/docs/design-clone-architecture.md +0 -492
  134. package/docs/pixel-perfect.md +0 -117
  135. package/docs/project-roadmap.md +0 -382
  136. package/docs/troubleshooting.md +0 -170
  137. package/requirements.txt +0 -5
  138. package/src/ai/__pycache__/analyze-structure.cpython-313.pyc +0 -0
  139. package/src/ai/__pycache__/extract-design-tokens.cpython-313.pyc +0 -0
  140. package/src/ai/analyze-structure.py +0 -375
  141. package/src/ai/extract-design-tokens.py +0 -782
  142. package/src/ai/prompts/__init__.py +0 -2
  143. package/src/ai/prompts/__pycache__/__init__.cpython-313.pyc +0 -0
  144. package/src/ai/prompts/__pycache__/design_tokens.cpython-313.pyc +0 -0
  145. package/src/ai/prompts/__pycache__/structure_analysis.cpython-313.pyc +0 -0
  146. package/src/ai/prompts/__pycache__/ux_audit.cpython-313.pyc +0 -0
  147. package/src/ai/prompts/design_tokens.py +0 -316
  148. package/src/ai/prompts/structure_analysis.py +0 -592
  149. package/src/ai/prompts/ux_audit.py +0 -198
  150. package/src/ai/ux-audit.js +0 -596
  151. package/src/core/animation-extractor.js +0 -526
  152. package/src/core/app-state-snapshot.js +0 -511
  153. package/src/core/content-counter.js +0 -342
  154. package/src/core/design-tokens.js +0 -103
  155. package/src/core/dimension-extractor.js +0 -438
  156. package/src/core/dimension-output.js +0 -305
  157. package/src/core/discover-pages.js +0 -542
  158. package/src/core/dom-tree-analyzer.js +0 -298
  159. package/src/core/extract-assets.js +0 -468
  160. package/src/core/filter-css.js +0 -499
  161. package/src/core/framework-detector.js +0 -538
  162. package/src/core/html-extractor.js +0 -212
  163. package/src/core/merge-css.js +0 -407
  164. package/src/core/multi-page-screenshot.js +0 -380
  165. package/src/core/rewrite-links.js +0 -226
  166. package/src/core/screenshot.js +0 -701
  167. package/src/core/section-detector.js +0 -386
  168. package/src/core/semantic-enhancer.js +0 -492
  169. package/src/core/state-capture.js +0 -598
  170. package/src/core/video-capture.js +0 -546
  171. package/src/utils/__init__.py +0 -16
  172. package/src/utils/__pycache__/__init__.cpython-313.pyc +0 -0
  173. package/src/utils/__pycache__/env.cpython-313.pyc +0 -0
  174. package/src/utils/env.py +0 -134
  175. /package/src/core/{css-extractor.js → css/css-extractor.js} +0 -0
  176. /package/src/core/{cookie-handler.js → page-prep/cookie-handler.js} +0 -0
  177. /package/src/core/{page-readiness.js → page-prep/page-readiness.js} +0 -0
@@ -1,2 +0,0 @@
1
- # Design Clone AI Prompts
2
- # Extracted from main Python files for better maintainability
@@ -1,316 +0,0 @@
1
- """
2
- Design Token Extraction Prompts
3
-
4
- Prompts for extracting design tokens from screenshots using Gemini Vision.
5
- """
6
-
7
- # Design token extraction prompt (basic - screenshot only)
8
- EXTRACTION_PROMPT = """Analyze these website screenshots (desktop, tablet, mobile) and extract design tokens.
9
-
10
- Return ONLY valid JSON in this exact format:
11
-
12
- {
13
- "colors": {
14
- "primary": "#hex",
15
- "secondary": "#hex",
16
- "accent": "#hex",
17
- "background": "#hex",
18
- "surface": "#hex",
19
- "text": {
20
- "primary": "#hex",
21
- "secondary": "#hex",
22
- "muted": "#hex"
23
- },
24
- "border": "#hex"
25
- },
26
- "typography": {
27
- "fontFamily": {
28
- "heading": "Font Name, sans-serif",
29
- "body": "Font Name, sans-serif"
30
- },
31
- "fontSize": {
32
- "xs": "12px",
33
- "sm": "14px",
34
- "base": "16px",
35
- "lg": "18px",
36
- "xl": "20px",
37
- "2xl": "24px",
38
- "3xl": "30px",
39
- "4xl": "36px"
40
- },
41
- "fontWeight": {
42
- "normal": 400,
43
- "medium": 500,
44
- "semibold": 600,
45
- "bold": 700
46
- },
47
- "lineHeight": {
48
- "tight": 1.25,
49
- "normal": 1.5,
50
- "relaxed": 1.75
51
- }
52
- },
53
- "spacing": {
54
- "1": "4px",
55
- "2": "8px",
56
- "3": "12px",
57
- "4": "16px",
58
- "6": "24px",
59
- "8": "32px",
60
- "12": "48px",
61
- "16": "64px"
62
- },
63
- "borderRadius": {
64
- "sm": "4px",
65
- "md": "8px",
66
- "lg": "16px",
67
- "full": "9999px"
68
- },
69
- "shadows": {
70
- "sm": "0 1px 2px rgba(0,0,0,0.05)",
71
- "md": "0 4px 6px rgba(0,0,0,0.1)",
72
- "lg": "0 10px 15px rgba(0,0,0,0.1)"
73
- },
74
- "notes": []
75
- }
76
-
77
- RULES:
78
- 1. Use exact 6-digit hex codes (#RRGGBB), not color names
79
- 2. Identify Google Fonts: Inter, Roboto, Open Sans, Poppins, Montserrat, Lato, Nunito, Raleway, Playfair Display, Merriweather
80
- 3. If font unknown, use reasonable fallback (sans-serif or serif)
81
- 4. Extract observed values; use sensible defaults if unclear
82
- 5. Detect spacing patterns (8px grid common)
83
- 6. Add any observations or accessibility concerns to notes array"""
84
-
85
-
86
- # Enhanced prompt when CSS context is available
87
- EXTRACTION_PROMPT_WITH_CSS = """Extract design tokens from the provided CSS and screenshots.
88
-
89
- You have access to:
90
- 1. Screenshots showing the visual design
91
- 2. The actual CSS used on the page
92
-
93
- CRITICAL: Extract EXACT values from the CSS. Do not estimate colors or fonts.
94
-
95
- ## Source CSS
96
- ```css
97
- {css_content}
98
- ```
99
-
100
- ---
101
-
102
- Based on the CSS above, return ONLY valid JSON:
103
-
104
- {{
105
- "colors": {{
106
- "primary": "[exact hex from CSS, look for primary/brand colors]",
107
- "secondary": "[exact hex from CSS]",
108
- "accent": "[exact hex for accent/highlight colors]",
109
- "background": "[exact hex, usually body background]",
110
- "surface": "[exact hex for cards/sections]",
111
- "text": {{
112
- "primary": "[exact hex, usually body color]",
113
- "secondary": "[exact hex for muted text]",
114
- "muted": "[exact hex for very light text]"
115
- }},
116
- "border": "[exact hex for borders]"
117
- }},
118
- "typography": {{
119
- "fontFamily": {{
120
- "heading": "[exact font-family from CSS h1-h6 rules]",
121
- "body": "[exact font-family from CSS body rule]"
122
- }},
123
- "fontSize": {{
124
- "xs": "[smallest font-size from CSS]",
125
- "sm": "[small font-size]",
126
- "base": "[body font-size]",
127
- "lg": "[larger font-size]",
128
- "xl": "[heading font-size]",
129
- "2xl": "[h3 font-size]",
130
- "3xl": "[h2 font-size]",
131
- "4xl": "[h1 font-size]"
132
- }},
133
- "fontWeight": {{
134
- "normal": [normal weight from CSS],
135
- "medium": [medium weight],
136
- "semibold": [semibold weight],
137
- "bold": [bold weight from CSS]
138
- }},
139
- "lineHeight": {{
140
- "tight": [tight line-height, usually 1.2-1.3],
141
- "normal": [normal line-height, usually 1.5-1.6],
142
- "relaxed": [relaxed line-height, usually 1.7-1.8]
143
- }}
144
- }},
145
- "spacing": {{
146
- "1": "[4px or smallest spacing]",
147
- "2": "[8px]",
148
- "3": "[12px]",
149
- "4": "[16px - common padding]",
150
- "6": "[24px]",
151
- "8": "[32px]",
152
- "12": "[48px - section padding]",
153
- "16": "[64px - large section padding]"
154
- }},
155
- "borderRadius": {{
156
- "sm": "[small radius from CSS]",
157
- "md": "[medium radius]",
158
- "lg": "[large radius]",
159
- "full": "9999px"
160
- }},
161
- "shadows": {{
162
- "sm": "[small shadow from CSS box-shadow]",
163
- "md": "[medium shadow]",
164
- "lg": "[large shadow]"
165
- }},
166
- "notes": ["List exact CSS custom properties/variables if found", "Note any @import URLs"]
167
- }}
168
-
169
- RULES:
170
- 1. Extract EXACT hex codes from CSS, not approximate
171
- 2. Copy font-family values exactly as written
172
- 3. Extract actual px/rem values, convert rem to px if needed (1rem = 16px)
173
- 4. Look for CSS custom properties (--color-*, --font-*, --space-*)
174
- 5. If a value isn't in CSS, use screenshot to estimate"""
175
-
176
-
177
- def build_extraction_prompt(css_content: str = None) -> str:
178
- """Build prompt with or without CSS context."""
179
- if css_content:
180
- # Truncate if too long (15KB limit)
181
- css_snippet = css_content[:15000] if len(css_content) > 15000 else css_content
182
- return EXTRACTION_PROMPT_WITH_CSS.format(css_content=css_snippet)
183
- return EXTRACTION_PROMPT
184
-
185
-
186
- # Section-specific extraction prompt
187
- SECTION_EXTRACTION_PROMPT = """Analyze this {section_type} section screenshot and extract design tokens.
188
-
189
- Focus on elements visible in THIS section only:
190
- - Background colors and gradients
191
- - Text colors (headings, body, links)
192
- - Typography (font family, sizes, weights)
193
- - Spacing patterns (padding, margins, gaps)
194
- - Border radius and shadows
195
- - Any accent or highlight colors
196
-
197
- Return ONLY valid JSON:
198
-
199
- {{
200
- "colors": {{
201
- "background": "#hex or null if transparent",
202
- "text": "#hex for main text",
203
- "heading": "#hex for headings",
204
- "accent": "#hex for buttons/links/highlights",
205
- "border": "#hex if borders visible"
206
- }},
207
- "typography": {{
208
- "fontFamily": "observed font or best guess",
209
- "headingSize": "largest heading size in px",
210
- "bodySize": "body text size in px",
211
- "fontWeight": {{
212
- "heading": 700,
213
- "body": 400
214
- }}
215
- }},
216
- "spacing": {{
217
- "sectionPadding": "vertical padding estimate",
218
- "elementGap": "gap between elements",
219
- "containerPadding": "horizontal padding"
220
- }},
221
- "borderRadius": "observed radius or null",
222
- "shadow": "observed shadow or null",
223
- "notes": ["observations about this section"]
224
- }}
225
-
226
- RULES:
227
- 1. Use exact 6-digit hex codes (#RRGGBB)
228
- 2. If a value is not visible/applicable, use null
229
- 3. Focus only on what's visible in this section image
230
- 4. Add section-specific observations to notes"""
231
-
232
-
233
- SECTION_EXTRACTION_PROMPT_WITH_CSS = """Analyze this {section_type} section screenshot with CSS context.
234
-
235
- ## Source CSS (excerpt)
236
- ```css
237
- {css_content}
238
- ```
239
-
240
- ---
241
-
242
- Extract design tokens visible in THIS section. Use EXACT values from CSS when possible.
243
-
244
- Return ONLY valid JSON:
245
-
246
- {{
247
- "colors": {{
248
- "background": "#exact-hex from CSS or screenshot",
249
- "text": "#exact-hex for text color",
250
- "heading": "#exact-hex for heading color",
251
- "accent": "#exact-hex for accent/CTA",
252
- "border": "#exact-hex if borders visible"
253
- }},
254
- "typography": {{
255
- "fontFamily": "exact font-family from CSS",
256
- "headingSize": "exact font-size for headings",
257
- "bodySize": "exact body font-size",
258
- "fontWeight": {{
259
- "heading": "exact weight from CSS",
260
- "body": "exact weight from CSS"
261
- }}
262
- }},
263
- "spacing": {{
264
- "sectionPadding": "exact padding from CSS",
265
- "elementGap": "exact gap/margin",
266
- "containerPadding": "exact container padding"
267
- }},
268
- "borderRadius": "exact radius from CSS or null",
269
- "shadow": "exact box-shadow from CSS or null",
270
- "notes": ["list any CSS custom properties found"]
271
- }}
272
-
273
- RULES:
274
- 1. Extract EXACT hex codes from CSS
275
- 2. Use null for values not visible in this section
276
- 3. Note any CSS variables (--color-*, --space-*)"""
277
-
278
-
279
- def build_section_prompt(section_name: str, css_content: str = None) -> str:
280
- """Build prompt for single section analysis."""
281
- # Extract section type from name (e.g., "section-0-header" -> "header")
282
- parts = section_name.replace('.png', '').split('-')
283
- section_type = parts[-1] if len(parts) > 2 else 'content'
284
-
285
- # Map common section names to descriptive types
286
- type_mapping = {
287
- 'header': 'header/navigation',
288
- 'footer': 'footer',
289
- 'hero': 'hero/banner',
290
- 'nav': 'navigation',
291
- 'cta': 'call-to-action',
292
- 'services': 'services/features',
293
- 'features': 'features',
294
- 'about': 'about',
295
- 'contact': 'contact',
296
- 'testimonials': 'testimonials',
297
- 'pricing': 'pricing',
298
- 'faq': 'FAQ',
299
- 'viewport': 'page content'
300
- }
301
-
302
- # Get descriptive type
303
- for key, desc in type_mapping.items():
304
- if key in section_type.lower():
305
- section_type = desc
306
- break
307
-
308
- if css_content:
309
- # Truncate CSS for section prompt (5KB limit per section)
310
- css_snippet = css_content[:5000] if len(css_content) > 5000 else css_content
311
- return SECTION_EXTRACTION_PROMPT_WITH_CSS.format(
312
- section_type=section_type,
313
- css_content=css_snippet
314
- )
315
-
316
- return SECTION_EXTRACTION_PROMPT.format(section_type=section_type)