Add interactive layer exploration workflow for UI design

- Implemented the `/workflow:ui-design:explore-layers` command for depth-controlled UI capture.
- Defined depth levels from full-page screenshots to Shadow DOM exploration.
- Included setup, validation, and navigation phases with error handling.
- Captured screenshots at various depths and generated a comprehensive layer map.
- Added examples and usage instructions for ease of use.
This commit is contained in:
catlog22
2025-10-11 15:29:33 +08:00
parent 980f554b27
commit 9993d599f8
10 changed files with 2191 additions and 3495 deletions

View File

@@ -2,532 +2,323 @@
name: capture
description: Batch screenshot capture for UI design workflows using MCP or local fallback
usage: /workflow:ui-design:capture --url-map "<map>" [--base-path <path>] [--session <id>]
argument-hint: --url-map "target:url,..." [--base-path path] [--session id]
examples:
- /workflow:ui-design:capture --url-map "home:https://linear.app, pricing:https://linear.app/pricing"
- /workflow:ui-design:capture --session WFS-auth --url-map "dashboard:https://app.com/dash"
- /workflow:ui-design:capture --base-path ".workflow/.design/run-20250110" --url-map "hero:https://example.com#hero"
allowed-tools: TodoWrite(*), Read(*), Write(*), Bash(*), Glob(*), mcp__browser__screenshot(*)
allowed-tools: TodoWrite(*), Read(*), Write(*), Bash(*), Glob(*), ListMcpResourcesTool(*), mcp__chrome-devtools__*, mcp__playwright__*
---
# Batch Screenshot Capture Command
# Batch Screenshot Capture (/workflow:ui-design:capture)
## Overview
独立的批量截图命令支持MCP优先策略和多级降级机制。可被其他工作流复用。
Batch screenshot tool with MCP-first strategy and multi-tier fallback. Processes multiple URLs in parallel.
## Core Philosophy
- **MCP优先**优先使用mcp__browser__screenshot如果可用
- **智能降级**MCP失败 → Playwright → Chrome → 手动上传
- **批量处理**一次处理多个URL并行截图
- **结构化输出**按target_name组织截图文件
- **错误容忍**:部分失败不阻塞整体流程
**Strategy**: MCP → Playwright → Chrome → Manual
**Output**: Flat structure `screenshots/{target}.png`
## Execution Protocol
### Phase 0: 初始化和路径解析
## Phase 1: Initialize & Parse
### Step 1: Determine Base Path
```bash
# 确定base path
IF --base-path:
base_path = {provided_base_path}
ELSE IF --session:
# 查找session最新design run
session_design_dirs = Glob(".workflow/WFS-{session}/design-*")
IF session_design_dirs:
base_path = most_recent(session_design_dirs)
ELSE:
# 创建新的design run
run_id = "run-$(date +%Y%m%d-%H%M%S)"
base_path = ".workflow/WFS-{session}/design-{run_id}"
ELSE:
# Standalone模式
run_id = "run-$(date +%Y%m%d-%H%M%S)"
base_path = ".workflow/.design/{run_id}"
# Priority: --base-path > session > standalone
bash(if [ -n "$BASE_PATH" ]; then
echo "$BASE_PATH"
elif [ -n "$SESSION_ID" ]; then
find .workflow/WFS-$SESSION_ID/design-* -type d | head -1 || \
echo ".workflow/WFS-$SESSION_ID/design-run-$(date +%Y%m%d-%H%M%S)"
else
echo ".workflow/.design/run-$(date +%Y%m%d-%H%M%S)"
fi)
# 创建截图目录
screenshot_dir = "{base_path}/screenshots"
Bash(mkdir -p "{screenshot_dir}")
bash(mkdir -p $BASE_PATH/screenshots)
```
REPORT: "📸 Batch Screenshot Capture"
REPORT: " Output: {screenshot_dir}/"
# 解析url-map
url_map_string = {--url-map} # "home:https://a.com, pricing:https://a.com/pricing"
# 解析逻辑
### Step 2: Parse URL Map
```javascript
// Input: "home:https://linear.app, pricing:https://linear.app/pricing"
url_entries = []
FOR pair IN split(url_map_string, ","):
pair = pair.strip()
IF ":" NOT IN pair:
ERROR: "Invalid url-map format: '{pair}'"
ERROR: "Expected format: 'target:url'"
ERROR: "Example: 'home:https://example.com, pricing:https://example.com/pricing'"
EXIT 1
target, url = pair.split(":", 1)
target = target.strip().lower().replace(" ", "-")
url = url.strip()
FOR pair IN split(params["--url-map"], ","):
parts = pair.split(":", 1)
# 验证target名称
IF NOT regex_match(target, r"^[a-z0-9][a-z0-9_-]*$"):
ERROR: "Invalid target name: '{target}'"
ERROR: "Target names must start with alphanumeric and contain only [a-z0-9_-]"
EXIT 1
IF len(parts) != 2:
ERROR: "Invalid format: {pair}. Expected: 'target:url'"
EXIT 1
# 验证URL格式
IF NOT (url.startswith("http://") OR url.startswith("https://")):
WARN: "URL '{url}' does not start with http:// or https://"
WARN: "Prepending https:// automatically"
url = f"https://{url}"
target = parts[0].strip().lower().replace(" ", "-")
url = parts[1].strip()
url_entries.append({"target": target, "url": url})
// Validate target name
IF NOT regex_match(target, r"^[a-z0-9][a-z0-9_-]*$"):
ERROR: "Invalid target: {target}"
EXIT 1
VALIDATE: len(url_entries) > 0, "url-map must contain at least one target:url pair"
// Add https:// if missing
IF NOT url.startswith("http"):
url = f"https://{url}"
total_targets = len(url_entries)
REPORT: " Targets: {total_targets}"
FOR entry IN url_entries:
REPORT: " • {entry.target}: {entry.url}"
url_entries.append({target, url})
```
**Output**: `base_path`, `url_entries[]`
### Step 3: Initialize Todos
```javascript
TodoWrite({todos: [
{content: "Initialize and parse url-map", status: "completed", activeForm: "Initializing"},
{content: "MCP batch screenshot capture", status: "pending", activeForm: "Capturing via MCP"},
{content: "Local tool fallback (if needed)", status: "pending", activeForm: "Local fallback"},
{content: "Verify and summarize results", status: "pending", activeForm: "Verifying"}
{content: "Parse url-map", status: "completed", activeForm: "Parsing"},
{content: "Detect MCP tools", status: "in_progress", activeForm: "Detecting"},
{content: "Capture screenshots", status: "pending", activeForm: "Capturing"},
{content: "Verify results", status: "pending", activeForm: "Verifying"}
]})
```
### Phase 1: MCP批量截图优先策略
## Phase 2: Detect Screenshot Tools
```bash
REPORT: "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
REPORT: "🚀 Phase 1: MCP Batch Screenshot"
REPORT: "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
### Step 1: Check MCP Availability
```javascript
// List available MCP servers
all_resources = ListMcpResourcesTool()
available_servers = unique([r.server for r in all_resources])
# 检测MCP工具可用性
mcp_available = check_tool_availability("mcp__browser__screenshot")
// Check Chrome DevTools MCP
chrome_devtools = "chrome-devtools" IN available_servers
chrome_screenshot = check_tool_exists("mcp__chrome-devtools__take_screenshot")
success_captures = []
failed_captures = []
IF mcp_available:
REPORT: "✓ MCP browser screenshot tool detected"
# 构建MCP调用参数
urls = [entry.url for entry in url_entries]
file_prefixes = [entry.target for entry in url_entries]
TRY:
# MCP批量截图调用
REPORT: " Calling MCP for {len(urls)} URLs..."
result = mcp__browser__screenshot({
urls: urls,
output_dir: screenshot_dir,
file_prefix: file_prefixes,
full_page: true,
viewport: "1920,1080",
timeout: 30000
})
# 处理MCP返回结果
success_count = len(result.success)
failed_count = len(result.failed)
REPORT: " MCP capture complete: {success_count} succeeded, {failed_count} failed"
FOR item IN result.success:
success_captures.append(item.target)
REPORT: " ✓ {item.target}.png"
FOR item IN result.failed:
failed_captures.append({"target": item.target, "url": item.url, "error": item.error})
REPORT: " ✗ {item.target}: {item.error}"
# 如果有部分失败标记需要fallback
IF failed_count > 0:
failed_targets = [item.target for item in result.failed]
REPORT: " → {failed_count} failed, proceeding to local fallback..."
TodoWrite(mark_completed: "MCP batch screenshot capture", mark_in_progress: "Local tool fallback")
GOTO Phase 2 (fallback_targets = failed_targets)
ELSE:
REPORT: "✅ All screenshots captured via MCP"
TodoWrite(mark_completed: "MCP batch screenshot capture", mark_completed: "Local tool fallback", mark_in_progress: "Verify results")
GOTO Phase 3 (verification)
CATCH error:
REPORT: "⚠️ MCP call failed: {error}"
REPORT: " Falling back to local tools for all targets"
failed_targets = [entry.target for entry in url_entries]
TodoWrite(mark_completed: "MCP batch screenshot capture", mark_in_progress: "Local tool fallback")
GOTO Phase 2 (fallback_targets = failed_targets)
// Check Playwright MCP
playwright_mcp = "playwright" IN available_servers
playwright_screenshot = check_tool_exists("mcp__playwright__screenshot")
// Determine primary tool
IF chrome_devtools AND chrome_screenshot:
tool = "chrome-devtools"
ELSE IF playwright_mcp AND playwright_screenshot:
tool = "playwright"
ELSE:
REPORT: " MCP browser screenshot tool not available"
REPORT: " Using local tool fallback strategy"
failed_targets = [entry.target for entry in url_entries]
TodoWrite(mark_completed: "MCP batch screenshot capture", mark_in_progress: "Local tool fallback")
GOTO Phase 2 (fallback_targets = failed_targets)
tool = null
```
### Phase 2: Local工具降级Playwright → Chrome
**Output**: `tool` (chrome-devtools | playwright | null)
### Step 2: Check Local Fallback
```bash
REPORT: "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
REPORT: "🔧 Phase 2: Local Tool Fallback"
REPORT: "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
# 仅处理Phase 1失败的targets
targets_to_capture = [entry for entry in url_entries if entry.target IN fallback_targets]
REPORT: "Processing {len(targets_to_capture)} target(s) with local tools..."
# 检测本地工具(检查可执行文件,不触发安装)
playwright_path = Bash(which playwright 2>/dev/null || echo "")
chrome_path = Bash(which google-chrome 2>/dev/null || which chrome 2>/dev/null || which chromium 2>/dev/null || echo "")
playwright_available = playwright_path != ""
chrome_available = chrome_path != ""
REPORT: " Tool availability:"
REPORT: " Playwright: {playwright_available ? '✓ Available' : '✗ Not found'}"
REPORT: " Chrome: {chrome_available ? '✓ Available' : '✗ Not found'}"
local_success = []
local_failed = []
FOR entry IN targets_to_capture:
target = entry.target
url = entry.url
output_file = "{screenshot_dir}/{target}.png"
captured = false
method_used = null
# 尝试Playwright
IF playwright_available AND NOT captured:
TRY:
REPORT: " Trying Playwright for '{target}'..."
Bash({playwright_path} screenshot "{url}" "{output_file}" --full-page --timeout 30000)
IF exists(output_file) AND file_size(output_file) > 1000: # >1KB验证有效
captured = true
method_used = "Playwright"
local_success.append(target)
success_captures.append(target)
REPORT: " ✓ {target}.png (Playwright, {file_size(output_file)/1024:.1f} KB)"
CATCH error:
REPORT: " ⚠️ Playwright failed: {error}"
# 尝试Chrome
IF chrome_available AND NOT captured:
TRY:
REPORT: " Trying Chrome for '{target}'..."
Bash({chrome_path} --headless --disable-gpu --screenshot="{output_file}" --window-size=1920,1080 "{url}")
IF exists(output_file) AND file_size(output_file) > 1000:
captured = true
method_used = "Chrome"
local_success.append(target)
success_captures.append(target)
REPORT: " ✓ {target}.png (Chrome, {file_size(output_file)/1024:.1f} KB)"
CATCH error:
REPORT: " ⚠️ Chrome failed: {error}"
# 标记彻底失败
IF NOT captured:
local_failed.append(entry)
failed_captures.append({"target": target, "url": url, "error": "All local tools failed"})
REPORT: " ✗ {target}: All tools failed"
REPORT: ""
REPORT: "Local fallback summary:"
REPORT: " Succeeded: {len(local_success)}/{len(targets_to_capture)}"
REPORT: " Failed: {len(local_failed)}/{len(targets_to_capture)}"
# 如果仍有失败,进入手动模式
IF len(local_failed) > 0:
TodoWrite(mark_completed: "Local tool fallback", mark_in_progress: "Manual upload mode")
GOTO Phase 2.5 (manual_upload)
ELSE:
TodoWrite(mark_completed: "Local tool fallback", mark_in_progress: "Verify results")
GOTO Phase 3 (verification)
# Only if MCP unavailable
bash(which playwright 2>/dev/null || echo "")
bash(which google-chrome || which chrome || which chromium 2>/dev/null || echo "")
```
### Phase 2.5: 手动上传降级
**Output**: `local_tools[]`
```bash
REPORT: "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
REPORT: "⚠️ Phase 2.5: Manual Screenshot Required"
REPORT: "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
## Phase 3: Capture Screenshots
REPORT: "Failed to auto-capture {len(local_failed)} target(s):"
REPORT: ""
### Step 1: MCP Capture (If Available)
```javascript
IF tool == "chrome-devtools":
// Get or create page
pages = mcp__chrome-devtools__list_pages()
FOR entry IN local_failed:
REPORT: " {entry.target}:"
REPORT: " URL: {entry.url}"
REPORT: " Save to: {screenshot_dir}/{entry.target}.png"
REPORT: ""
IF pages.length == 0:
mcp__chrome-devtools__new_page({url: url_entries[0].url})
page_idx = 0
ELSE:
page_idx = 0
REPORT: "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
REPORT: "📋 Manual Steps:"
REPORT: " 1. Visit each URL above in your browser"
REPORT: " 2. Take full-page screenshot (Browser DevTools or extensions)"
REPORT: " 3. Save screenshot to specified path"
REPORT: " 4. Return here and choose an option"
REPORT: ""
REPORT: "Options:"
REPORT: " • Type 'ready' : I've uploaded screenshot(s), continue workflow"
REPORT: " • Type 'skip' : Skip failed screenshots, continue with available"
REPORT: " • Type 'abort' : Cancel entire capture workflow"
REPORT: "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
mcp__chrome-devtools__select_page({pageIdx: page_idx})
user_response = WAIT_FOR_USER_INPUT()
// Capture each URL
FOR entry IN url_entries:
mcp__chrome-devtools__navigate_page({url: entry.url, timeout: 30000})
bash(sleep 2)
MATCH user_response.lower():
"ready" | "done" | "ok" | "continue":
# 验证手动上传的文件
manual_uploaded = []
REPORT: "🔍 Checking for manual screenshots..."
mcp__chrome-devtools__take_screenshot({
fullPage: true,
format: "png",
quality: 90,
filePath: f"{base_path}/screenshots/{entry.target}.png"
})
FOR entry IN local_failed:
expected_path = f"{screenshot_dir}/{entry.target}.png"
IF exists(expected_path) AND file_size(expected_path) > 1000:
manual_uploaded.append(entry.target)
success_captures.append(entry.target)
REPORT: " ✓ {entry.target}.png (manual, {file_size(expected_path)/1024:.1f} KB)"
ELSE:
REPORT: " ✗ {entry.target}.png not found or invalid"
IF len(manual_uploaded) > 0:
REPORT: "✅ Detected {len(manual_uploaded)} manual screenshot(s)"
# 移除已上传的targets from failed list
failed_captures = [f for f in failed_captures if f.target NOT IN manual_uploaded]
ELSE:
REPORT: "⚠️ No valid manual screenshots detected"
REPORT: " Proceeding with available screenshots only"
TodoWrite(mark_completed: "Manual upload mode", mark_in_progress: "Verify results")
GOTO Phase 3
"skip" | "s":
REPORT: "⏭️ Skipping {len(local_failed)} failed screenshot(s)"
REPORT: " Proceeding with {len(success_captures)} available screenshot(s)"
TodoWrite(mark_completed: "Manual upload mode", mark_in_progress: "Verify results")
GOTO Phase 3
"abort" | "cancel" | "exit":
ERROR: "Workflow aborted by user"
TodoWrite(mark_failed: "Manual upload mode")
EXIT 1
_:
REPORT: "⚠️ Invalid input '{user_response}', interpreting as 'skip'"
REPORT: " Proceeding with available screenshots"
TodoWrite(mark_completed: "Manual upload mode", mark_in_progress: "Verify results")
GOTO Phase 3
ELSE IF tool == "playwright":
FOR entry IN url_entries:
mcp__playwright__screenshot({
url: entry.url,
output_path: f"{base_path}/screenshots/{entry.target}.png",
full_page: true,
timeout: 30000
})
```
### Phase 3: 验证和总结
### Step 2: Local Fallback (If MCP Failed)
```bash
REPORT: "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
REPORT: "✅ Phase 3: Verification & Summary"
REPORT: "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
# Try Playwright CLI
bash(playwright screenshot "$url" "$output_file" --full-page --timeout 30000)
# 扫描实际截图文件
captured_files = Glob("{screenshot_dir}/*.{png,jpg,jpeg,webp}")
captured_targets_actual = [extract_basename_without_ext(f) for f in captured_files]
# Try Chrome headless
bash($chrome --headless --screenshot="$output_file" --window-size=1920,1080 "$url")
```
# 与请求对比
total_requested = len(url_entries)
total_captured = len(captured_targets_actual)
missing_targets = [entry.target for entry in url_entries if entry.target NOT IN captured_targets_actual]
### Step 3: Manual Mode (If All Failed)
```
⚠️ Manual Screenshot Required
REPORT: "📊 Capture Summary:"
REPORT: " Total requested: {total_requested}"
REPORT: " Successfully captured: {total_captured}"
REPORT: " Success rate: {(total_captured / total_requested * 100):.1f}%"
Failed URLs:
home: https://linear.app
Save to: .workflow/.design/run-20250110/screenshots/home.png
IF missing_targets:
REPORT: ""
REPORT: "⚠️ Missing screenshots ({len(missing_targets)}):"
FOR target IN missing_targets:
REPORT: " • {target}"
ELSE:
REPORT: ""
REPORT: "✅ All requested screenshots captured!"
Steps:
1. Visit URL in browser
2. Take full-page screenshot
3. Save to path above
4. Type 'ready' to continue
Options: ready | skip | abort
```
## Phase 4: Verification
### Step 1: Scan Captured Files
```bash
bash(ls -1 $base_path/screenshots/*.{png,jpg,jpeg,webp} 2>/dev/null)
bash(du -h $base_path/screenshots/*.png 2>/dev/null)
```
### Step 2: Generate Metadata
```javascript
captured_files = Glob(f"{base_path}/screenshots/*.{{png,jpg,jpeg,webp}}")
captured_targets = [basename_no_ext(f) for f in captured_files]
# 生成capture元数据
metadata = {
"timestamp": current_timestamp(),
"total_requested": total_requested,
"total_captured": total_captured,
"success_rate": round(total_captured / total_requested * 100, 2),
"screenshots": []
"timestamp": current_timestamp(),
"total_requested": len(url_entries),
"total_captured": len(captured_targets),
"screenshots": []
}
FOR entry IN url_entries:
target = entry.target
url = entry.url
is_captured = target IN captured_targets_actual
is_captured = entry.target IN captured_targets
screenshot_info = {
"target": target,
"url": url,
"captured": is_captured
}
metadata.screenshots.append({
"target": entry.target,
"url": entry.url,
"captured": is_captured,
"path": f"{base_path}/screenshots/{entry.target}.png" IF is_captured ELSE null,
"size_kb": file_size_kb IF is_captured ELSE null
})
IF is_captured:
file_path = f"{screenshot_dir}/{target}.png"
screenshot_info["path"] = file_path
screenshot_info["size_kb"] = round(file_size(file_path) / 1024, 2)
# 查找捕获方法
IF target IN [s.target for s in result.success if mcp_available]:
screenshot_info["method"] = "MCP"
ELSE IF target IN local_success:
screenshot_info["method"] = "Local (Playwright/Chrome)"
ELSE:
screenshot_info["method"] = "Manual"
ELSE:
screenshot_info["path"] = null
screenshot_info["error"] = next((f.error for f in failed_captures if f.target == target), "Unknown error")
metadata.screenshots.append(screenshot_info)
# 写入元数据文件
metadata_path = "{screenshot_dir}/capture-metadata.json"
Write(metadata_path, JSON.stringify(metadata, null, 2))
REPORT: ""
REPORT: "📁 Output:"
REPORT: " Directory: {screenshot_dir}/"
REPORT: " Metadata: capture-metadata.json"
TodoWrite(mark_completed: "Verify and summarize results")
Write(f"{base_path}/screenshots/capture-metadata.json", JSON.stringify(metadata))
```
### Phase 4: 完成
**Output**: `capture-metadata.json`
## Completion
### Todo Update
```javascript
TodoWrite({todos: [
{content: "Initialize and parse url-map", status: "completed", activeForm: "Initializing"},
{content: "MCP batch screenshot capture", status: "completed", activeForm: "MCP capture"},
{content: "Local tool fallback (if needed)", status: "completed", activeForm: "Local fallback"},
{content: "Verify and summarize results", status: "completed", activeForm: "Verifying"}
]});
{content: "Parse url-map", status: "completed", activeForm: "Parsing"},
{content: "Detect MCP tools", status: "completed", activeForm: "Detecting"},
{content: "Capture screenshots", status: "completed", activeForm: "Capturing"},
{content: "Verify results", status: "completed", activeForm: "Verifying"}
]})
```
**Completion Message**:
### Output Message
```
✅ Batch Screenshot Capture Complete!
✅ Batch screenshot capture complete!
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📊 Capture Summary
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Summary:
- Requested: {total_requested}
- Captured: {total_captured}
- Success rate: {success_rate}%
- Method: {tool || "Local fallback"}
Requested: {total_requested} screenshots
Captured: {total_captured} screenshots
Success Rate: {success_rate}%
Capture Methods:
{IF mcp_available AND mcp_success_count > 0:
• MCP: {mcp_success_count} screenshot(s)
}
{IF local_success_count > 0:
• Local tools: {local_success_count} screenshot(s)
}
{IF manual_count > 0:
• Manual upload: {manual_count} screenshot(s)
}
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📂 Output Structure
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
{screenshot_dir}/
├── {target1}.png ({size1} KB)
├── {target2}.png ({size2} KB)
{FOR each captured screenshot}
Output:
{base_path}/screenshots/
├── home.png (245.3 KB)
├── pricing.png (198.7 KB)
└── capture-metadata.json
{IF missing_targets:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
⚠️ Missing Screenshots ({len(missing_targets)})
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
{FOR target IN missing_targets:
• {target} - {get_error_for_target(target)}
}
💡 Tip: Re-run capture command for failed targets:
/workflow:ui-design:capture --base-path "{base_path}" --url-map "{build_failed_url_map()}"
}
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🚀 Next Steps
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1. Extract design style from captured screenshots:
/workflow:ui-design:extract --base-path "{base_path}" --images "{screenshot_dir}/*.png" --mode imitate --variants 1
2. Or continue with full imitate workflow:
(capture is automatically called by /workflow:ui-design:imitate-auto-v3)
Next: /workflow:ui-design:extract --images "screenshots/*.png"
```
## MCP API设计假设实现
## Simple Bash Commands
```typescript
// 假设的MCP工具签名
mcp__browser__screenshot({
urls: string[], // 要截图的URL列表
output_dir: string, // 输出目录
file_prefix: string[], // 文件名前缀列表对应urls
full_page?: boolean, // 全页截图默认true
viewport?: string, // 视口大小(默认"1920,1080"
timeout?: number // 每个URL的超时默认30000ms
}): {
success: Array<{
target: string, // file_prefix对应的target名称
url: string, // 成功截图的URL
path: string // 生成的截图文件路径
}>,
failed: Array<{
target: string, // file_prefix对应的target名称
url: string, // 失败的URL
error: string // 错误信息
}>
}
### Path Operations
```bash
# Find design directory
bash(find .workflow -type d -name "design-*" | head -1)
# Create screenshot directory
bash(mkdir -p $BASE_PATH/screenshots)
```
**注意事项**
- 如果`mcp__browser__screenshot`工具不存在,命令会自动降级到本地工具
- MCP工具应该支持并行截图以提高性能
- 返回结果应该区分成功和失败,允许部分失败
### Tool Detection
```bash
# Check MCP
all_resources = ListMcpResourcesTool()
# Check local tools
bash(which playwright 2>/dev/null)
bash(which google-chrome 2>/dev/null)
```
### Verification
```bash
# List captures
bash(ls -1 $base_path/screenshots/*.png 2>/dev/null)
# File sizes
bash(du -h $base_path/screenshots/*.png)
```
## Output Structure
```
{base_path}/
└── screenshots/
├── home.png
├── pricing.png
├── about.png
└── capture-metadata.json
```
## Error Handling
- **无效url-map格式**:清晰的错误信息+格式示例
- **MCP不可用**静默降级到本地工具Playwright/Chrome
- **所有自动工具失败**:进入交互式手动上传模式
- **部分失败**:记录成功项,继续流程(非阻塞),提供重试建议
### Common Errors
```
ERROR: Invalid url-map format
→ Use: "target:url, target2:url2"
ERROR: MCP unavailable
→ Using local fallback
ERROR: All tools failed
→ Manual mode activated
```
### Recovery
- **Partial success**: Keep successful captures
- **Retry**: Re-run with failed targets only
- **Manual**: Follow interactive guidance
## Quality Checklist
- [ ] All requested URLs processed
- [ ] File sizes > 1KB (valid images)
- [ ] Metadata JSON generated
- [ ] No missing targets (or documented)
## Key Features
1. **MCP优先策略** - 使用托管工具提高可靠性和一致性
2. **多级降级机制** - MCP → Playwright → Chrome → 手动上传
3. **批量并行处理** - 一次处理多个URLMCP支持并行
4. **错误容忍设计** - 部分失败不阻塞整体流程
5. **高度可复用** - 可被imitate-auto-v3、explore-auto等工作流调用
6. **结构化输出** - capture-metadata.json记录完整捕获信息
7. **交互式降级** - 手动模式提供清晰的用户指导
8. **智能路径管理** - 支持session集成和standalone模式
- **MCP-first**: Prioritize managed tools
- **Multi-tier fallback**: 4 layers (MCP → Local → Manual)
- **Batch processing**: Parallel capture
- **Error tolerance**: Partial failures handled
- **Structured output**: Flat, predictable
## Integration Points
## Integration
- **Input**: `--url-map` (target:url pairs) + `--base-path` or `--session`
- **Output**: `{base_path}/screenshots/*.png` + `capture-metadata.json`
- **Callers**: `/workflow:ui-design:imitate-auto-v3`, potentially `/workflow:ui-design:explore-auto-v2`
- **Next Command**: `/workflow:ui-design:extract --images "{screenshot_dir}/*.png"`
**Input**: `--url-map` (multiple target:url pairs)
**Output**: `screenshots/*.png` + `capture-metadata.json`
**Called by**: `/workflow:ui-design:imitate-auto`, `/workflow:ui-design:explore-auto`
**Next**: `/workflow:ui-design:extract` or `/workflow:ui-design:explore-layers`