Use Playwright to progressively collect page data, then reproduce HTML/CSS in stages.
Prerequisites: Node.js >= 18 (Playwright + Chromium are automatically installed on first run)
Collection Script
From the skill directory, scripts/ run:
node scripts/clone.mjs <url> <command> [options]
Two Reproduction Modes
🚀 Quick Reproduction (recommended to try this first)
Suitable for quickly producing prototypes, consumes fewer tokens, and completes in a few minutes.
Collection:
node scripts/clone.mjs <url> quick -o ./clone-data --scroll
Data source priority:
- ⭐⭐⭐⭐⭐
screenshot.png— visual truth, use it as the standard - ⭐⭐⭐⭐
theme.json— design tokens such as colors, fonts, and spacing - ⭐⭐⭐
skeleton.json— DOM skeleton (to understand hierarchy and semantic tags)
Reproduction steps:
- Look at
screenshot.png, understand the overall page layout - Read
theme.json, extract key design tokens (primary color, fonts, spacing, border radius, shadows) - Skim
skeleton.json --depth=2, understand the major section divisions - In the order header → main → footer, write HTML/CSS section by section with reference to the screenshots
- Use the values in theme.json as CSS variables
# 渐进式读取数据
node scripts/query.mjs ./clone-data summary
node scripts/query.mjs ./clone-data skeleton --depth=2
🎨 High-Fidelity Reproduction
Suitable for production environments, reproducing down to the pixel level. Collect additional data on top of quick reproduction.
Collection:
# 先执行 quick(如果还没有)
node scripts/clone.mjs <url> quick -o ./clone-data --scroll
# 然后逐 section 深入采集样式
node scripts/clone.mjs <url> styles -o ./clone-data --selector "header"
node scripts/clone.mjs <url> styles -o ./clone-data --selector "main > section:nth-child(1)"
node scripts/clone.mjs <url> styles -o ./clone-data --selector "main > section:nth-child(2)"
node scripts/clone.mjs <url> styles -o ./clone-data --selector "footer"
# 需要时:交互态
node scripts/clone.mjs <url> interact -o ./clone-data --hover "nav a:first-child"
# 需要时:响应式截图
node scripts/clone.mjs <url> responsive -o ./clone-data
# 最后:下载资源
node scripts/clone.mjs <url> assets -o ./clone-data
Data source priority:
- ⭐⭐⭐⭐⭐
screenshot.png— still use the screenshots as the standard - ⭐⭐⭐⭐⭐
sections/*/nodes.json— precise DOM structure + selectors - ⭐⭐⭐⭐⭐
sections/*/styles.json— complete computedStyle - ⭐⭐⭐⭐
theme.json— design tokens - ⭐⭐⭐
sections/*/screenshot.png— single-section screenshot comparison
Reproduction steps:
- Same as quick reproduction Step 1-3
- View the collected section list:
node scripts/query.mjs ./clone-data sections - Reproduce section by section:
# 查看 section 的完整数据(DOM + 样式) node scripts/query.mjs ./clone-data section header- According to
nodes.jsoninchildren, strictly build the hierarchy - According to
styles.jsoninstyleId, apply precise styles - Compare
screenshot.pngand fine-tune
- According to
- If section styles are not precise enough, you can further narrow the selector range and collect again
- If hover/focus states are needed, use the
interactcommand to collect them - Use the images and fonts in the
assets/directory
Collection Command Quick Reference
| Command | Purpose | Output |
|---|---|---|
quick |
Quick mode = init + skeleton | screenshot + meta + theme + skeleton |
full |
Full mode = init + skeleton + responsive + assets | The above + responsive screenshots + assets |
init |
Screenshots + metadata + design tokens | screenshot.png, meta.json, theme.json |
skeleton |
DOM skeleton (without styles) | skeleton.json |
styles --selector "X" |
Complete styles for the specified region | sections/X/nodes.json + styles.json + screenshot.png |
interact |
Interactive state screenshots | interactions/*.png + *-styles.json |
responsive |
Multi-viewport screenshots | responsive/*.png |
assets |
Download images/fonts/SVG | assets/ |
Query Command Quick Reference
node scripts/query.mjs <dir> summary # 概览
node scripts/query.mjs <dir> skeleton --depth=2 # 骨架(前 2 层)
node scripts/query.mjs <dir> subtree n2 --depth=3 # 某节点子树
node scripts/query.mjs <dir> node n15 # 单节点(含已采集样式)
node scripts/query.mjs <dir> sections # 已采集的 section 列表
node scripts/query.mjs <dir> section header # 某 section 的完整数据
node scripts/query.mjs <dir> find --tag=button # 按标签查找
node scripts/query.mjs <dir> find --text="登录" # 按文本查找
node scripts/query.mjs <dir> find --interactive # 交互元素
node scripts/query.mjs <dir> file theme.json # 读取任意文件
Output Directory Structure
clone-data/
├── meta.json # 元信息(url, title, phases, sections)
├── screenshot.png # 全页截图
├── theme.json # 设计令牌
├── skeleton.json # DOM 骨架树(含 selector)
│
├── sections/ # 按 section 的样式(逐步追加)
│ ├── header/
│ │ ├── nodes.json # DOM + selector + bbox + styleId
│ │ ├── styles.json # computedStyle 去重池
│ │ └── screenshot.png
│ └── main-section-nth-child-1/
│ └── ...
│
├── interactions/ # 交互态数据
│ ├── hover-nav-a.png
│ └── hover-nav-a-styles.json
│
├── responsive/ # 多视口截图
│ ├── desktop.png
│ ├── tablet.png
│ └── mobile.png
│
└── assets/ # 下载的资源
├── images/
├── fonts/
├── svgs/
└── manifest.json
Pages that require login
# 方法 1: 连接已登录的 Chrome(推荐)
# 先启动 Chrome:
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --remote-debugging-port=9222
# 在 Chrome 中登录后运行:
node scripts/clone.mjs https://internal.site.com quick --connect-cdp http://localhost:9222
# 方法 2: 显示浏览器窗口手动登录
node scripts/clone.mjs https://internal.site.com quick --no-headless
Tips
- Screenshots are the ultimate truth — if the data conflicts with the screenshot, the screenshot prevails
- Progressive capture — no need to do a full capture all at once; run quick first to see the result, then apply styles as needed
- selector is the bridge — every node in skeleton.json has a CSS selector, used for precise targeting afterward
- Each Phase is independent — data is appended incrementally and will not overwrite existing content
- Coarse first, then fine — quickly restore the overall framework → compare with the screenshot → fine-tune