init: huashu-design skill v1.0

花叔设计工作台 —— AI 驱动的 HTML 设计工作流,支持 Claude Code / Codex /
Cursor / Trae / OpenClaw / Hermes Agent 等任意 skill-compatible agent。

四条主干能力:
- HTML 高保真视觉产出(原型/App/幻灯片/动画/变体/信息图)
- 设计方向顾问 Fallback(5 流派 × 20 设计哲学 × 24 预制 showcase)
- Junior Designer 工作流(先 show 假设再迭代)
- 专家级 5 维度评审(哲学/层级/执行/功能/创新)

工程工具链:
- HTML → 25fps/60fps MP4 + palette GIF,含 6 首场景化 BGM
- HTML → PDF / PPTX 导出
- Playwright 截图 + 控制台错误验证
- iOS/Android/macOS/Browser 设备边框 + Stage/Sprite 动画引擎

初版包含 SKILL.md + 13 份 references + 7 个 scripts + 18 类 assets。

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
alchainandClaude Opus 4.7 committed 2026-04-19 22:41:51 +08:00
commit 7d7bab4a82
89 files changed
+19270

No files matched your search

+154
View File
@@ -0,0 +1,154 @@
#!/usr/bin/env python3
"""
verify.py — Playwright封装,用于验证claude-design产出的HTML
Usage:
python verify.py path/to/design.html # 基础:打开+截图+抓控制台错误
python verify.py design.html --viewports 1920x1080,375x667 # 多viewport
python verify.py deck.html --slides 10 # 幻灯片逐页截(前10张)
python verify.py design.html --output ./screenshots/ # 输出目录
python verify.py design.html --show # 非headless,打开真实浏览器
依赖:
pip install playwright
playwright install chromium
"""
import argparse
import sys
import os
import time
from pathlib import Path
def parse_viewport(s):
w, h = s.split('x')
return {'width': int(w), 'height': int(h)}
def verify_html(html_path, viewports=None, slides=0, output_dir=None, show=False, wait=2000):
try:
from playwright.sync_api import sync_playwright
except ImportError:
print("ERROR: playwright未安装。")
print("运行: pip install playwright && playwright install chromium")
sys.exit(1)
html_path = Path(html_path).resolve()
if not html_path.exists():
print(f"ERROR: 文件不存在: {html_path}")
sys.exit(1)
if output_dir is None:
output_dir = html_path.parent / 'screenshots'
output_dir = Path(output_dir)
output_dir.mkdir(parents=True, exist_ok=True)
file_url = html_path.as_uri()
stem = html_path.stem
if viewports is None:
viewports = [{'width': 1440, 'height': 900}]
console_errors = []
page_errors = []
with sync_playwright() as p:
browser = p.chromium.launch(headless=not show)
for viewport in viewports:
context = browser.new_context(viewport=viewport, device_scale_factor=2)
page = context.new_page()
page.on("console", lambda msg: console_errors.append(f"[{msg.type}] {msg.text}") if msg.type in ("error", "warning") else None)
page.on("pageerror", lambda err: page_errors.append(str(err)))
print(f"\n→ 打开 {file_url} @ {viewport['width']}x{viewport['height']}")
page.goto(file_url, wait_until='networkidle')
page.wait_for_timeout(wait)
if slides > 0:
for i in range(slides):
screenshot_path = output_dir / f"{stem}-slide-{str(i + 1).zfill(2)}.png"
page.screenshot(path=str(screenshot_path), full_page=False)
print(f" ✓ slide {i+1} → {screenshot_path.name}")
if i < slides - 1:
page.keyboard.press('ArrowRight')
page.wait_for_timeout(500)
else:
suffix = f"-{viewport['width']}x{viewport['height']}" if len(viewports) > 1 else ""
screenshot_path = output_dir / f"{stem}{suffix}.png"
page.screenshot(path=str(screenshot_path), full_page=False)
print(f" ✓ 截图 → {screenshot_path.name}")
full_path = output_dir / f"{stem}{suffix}-full.png"
page.screenshot(path=str(full_path), full_page=True)
print(f" ✓ 完整页 → {full_path.name}")
if show:
print(" (浏览器窗口保持打开,按Enter关闭...)")
input()
context.close()
browser.close()
print("\n" + "=" * 50)
print("验证报告")
print("=" * 50)
if page_errors:
print(f"\n❌ Page Errors ({len(page_errors)}):")
for e in page_errors:
print(f" - {e}")
else:
print("\n✅ 无JavaScript错误")
if console_errors:
print(f"\n⚠️ Console Errors/Warnings ({len(console_errors)}):")
for e in console_errors[:20]:
print(f" - {e}")
if len(console_errors) > 20:
print(f" ... 还有{len(console_errors) - 20}条")
else:
print("✅ Console干净")
print(f"\n📸 截图保存至: {output_dir}")
return 0 if not page_errors else 1
def main():
parser = argparse.ArgumentParser(
description="Verify HTML design outputs with Playwright",
formatter_class=argparse.RawDescriptionHelpFormatter,
)
parser.add_argument("html_path", help="HTML file path")
parser.add_argument("--viewports", default="1440x900",
help="逗号分隔的viewport列表,格式 WxH(默认 1440x900)")
parser.add_argument("--slides", type=int, default=0,
help="幻灯片模式:截取前N张(需要HTML支持ArrowRight翻页)")
parser.add_argument("--output", default=None,
help="输出目录(默认HTML所在目录的screenshots/)")
parser.add_argument("--show", action="store_true",
help="非headless,打开真实浏览器窗口")
parser.add_argument("--wait", type=int, default=2000,
help="打开页面后等待的毫秒数(默认2000)")
args = parser.parse_args()
viewports = [parse_viewport(v) for v in args.viewports.split(",")]
return verify_html(
html_path=args.html_path,
viewports=viewports,
slides=args.slides,
output_dir=args.output,
show=args.show,
wait=args.wait,
)
if __name__ == "__main__":
sys.exit(main())