关于 design-import
design-import 将 Claude Design 交接包转为 React 组件脚手架,并处理设计令牌协调、组件去重和来源记录。它面向将设计导入现有项目,不负责创建 PR 或运行测试。
主要功能
- 01接收交接 URL 或本地文件
- 02验证并规范化交接包
- 03协调设计令牌
- 04复用或调整现有组件
- 05生成 React 组件脚手架
- 06记录导入组件的来源
适用场景
- 01将 Claude Design 导出导入 React 项目
- 02在生成脚手架前解决令牌差异
- 03避免重复创建代码库中已有的组件
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ yonatangross/ orchestkit --skill design-import安装后在 Claude Code 中输入/design-import确认已加载。
详细介绍
设计导入
将 Claude Design 交接包转换为脚手架 React 组件,并记录来源信息,与现有代码库进行去重。
design-import https://claude.ai/design/abc123 # From handoff URL
design-import /tmp/handoff-bundle.json # From local file
适用场景
从 claude.ai/design 导出交接包后使用。此技能是入口——它不会创建 PR、运行测试或部署。若要执行端到端流程(导入 → 测试 → PR),请使用 design-ship。
流程
Handoff bundle (URL or file)
│
▼
┌──────────────────────────────┐
│ 1. PARSE + VALIDATE │ via claude-design-orchestrator agent
│ - Fetch bundle │ Schema validation
│ - Compute bundle_id (sha) │ Surface deviations
└──────────┬───────────────────┘
│
▼
┌──────────────────────────────┐
│ 2. RECONCILE TOKENS │ Diff bundle tokens vs project tokens
│ - Read project tokens │ Conflicts → AskUserQuestion
│ - Apply additions │ Additions → write to design-tokens.json
└──────────┬───────────────────┘
│
▼
┌──────────────────────────────┐
│ 3. DEDUP COMPONENTS │ For each proposed component:
│ Storybook MCP first │ • exact match → reuse (skip)
│ 21st.dev next │ • similar match → adapt
│ Filesystem grep last │ • no match → scaffold
└──────────┬───────────────────┘
│
▼
┌──────────────────────────────┐
│ 4. SCAFFOLD │ Delegate to design-to-code per component
│ (skipped components │ Use bundle's tsx_scaffold as seed
│ logged but not touched) │ Apply project tokens
└──────────┬───────────────────┘
│
▼
┌──────────────────────────────┐
│ 5. WRITE PROVENANCE │ .claude/design-handoffs/<bundle_id>.json
│ Bundle → files → (PR) │ PR field empty until design-ship
└──────────┬───────────────────┘
│
▼
Import manifest (stdout)
参数解析
ARG = "$1" # First positional argument
if ARG.startswith("http://") or ARG.startswith("https://"):
bundle_source = "url"
bundle_input = ARG
elif Path(ARG).exists():
bundle_source = "file"
bundle_input = ARG
else:
AskUserQuestion(questions=[{
"question": "I couldn't resolve that as a URL or file. What is it?",
"header": "Bundle source",
"options": [
{"label": "Paste handoff URL", "description": "claude.ai/design URL"},
{"label": "Paste file path", "description": "Local handoff JSON"},
{"label": "Cancel", "description": "Abort import"}
],
"multiSelect": False
}])
阶段 1 — 解析与验证
委托给编排 Agent。Agent 会获取并解压 tarball,读取 README 和聊天记录,解析 HTML 原型,并生成规范化负载。不要在此重新实现解析逻辑——实际的 tarball 格式 schema 由 Agent 负责。
Agent(
subagent_type="ork:claude-design-orchestrator",
description="Parse and normalize handoff bundle",
prompt=f"""Parse the Claude Design handoff bundle at {bundle_input}.
This is a gzipped tarball (NOT a JSON manifest). Layout:
<project>/README.md ← read first
<project>/chats/*.md ← read all (load-bearing)
<project>/project/*.html ← prototypes (may be absent if incomplete)
Tasks:
1. Fetch the bundle (WebFetch if URL → saved .bin path; Read if local file)
2. Extract: `tar -xzf <bin> -C /tmp/<scratch>/`
3. Read README.md, then every chats/*.md (intent + clarifications live here)
4. Compute bundle_id = sha256(canonical bundle URL or absolute path)
5. If project/ is MISSING → return status="incomplete" with the assistant's
last unanswered question; do NOT crash. Surface "what user should do".
6. If project/ exists → pick primary HTML:
- Prefer the file matching the URL's ?open_file= query param
- Else first alphabetical
7. From the primary HTML, extract:
- Inline `:root { --... }` CSS custom properties as design tokens
- Component sections (named via class/id/data-screen-label)
- Asset references (<link>, <img>) — keep as URLs, do not download
- EDITMODE JSON block (design-time state — capture as ANNOTATION only)
8. Produce normalized output payload (see agent spec)
9. Write provenance to .claude/design-handoffs/<bundle_id>.json:
- bundle_url, bundle_id, fetched_at, status, components: [], pr: null
10. Return the normalized payload as JSON
Surface any deviations from the expected tarball layout explicitly.
Never expect a JSON `components[]` field — that was the old (wrong) shape.
"""
)
阶段 2 — 协调设计令牌
读取 Agent 负载中的规范化 token_diff。
| 差异字段 | 操作 |
|---|---|
added | 追加到项目的 design-tokens.json(或 Tailwind 配置)中。无需提示——新增项安全无虞。 |
modified | 显示差异。通过 AskUserQuestion 询问:保留项目值、接受交接包中的值,还是打开编辑器。 |
conflicts | 阻止生成脚手架。通过 AskUserQuestion 在继续之前解决冲突。 |
if token_diff["conflicts"]:
AskUserQuestion(questions=[{
"question": f"Token conflict on {conflict.path}. Project says {conflict.project}, bundle says {conflict.bundle}. Resolve?",
"header": "Token conflict",
"options": [
{"label": "Keep project value", "description": "Bundle adapts to project"},
{"label": "Accept bundle value", "description": "Project adapts to bundle (writes new token)"},
{"label": "Both — namespace bundle's", "description": f"Add as {conflict.path}.imported"}
],
"multiSelect": False
}])
阶段 3 — 组件去重
Agent 已对每个组件运行 component-search。读取规范化负载中的决策:
decision | 行为 |
|---|---|
reuse | 记录“已跳过(现有组件:)”——不对磁盘进行任何操作 |
adapt | 使用 --adapt-from <existing-path> 上下文,通过 ork:design-to-code 处理 |
scaffold | 使用交接包中的 tsx_scaffold 作为种子,通过 ork:design-to-code 处理 |
阶段 4 — 生成脚手架
对每个决策为 scaffold 或 adapt 的组件,调用 design-to-code。
各个任务会同时在后台运行,因此每个任务都需要自己的
工作树(isolation="worktree",#4557):ork Agent 不带 frontmatter
隔离设置;若不设置,每个组件都会同时写入你的代码树。
for component in payload["components"]:
if component["decision"] in ("scaffold", "adapt"):
# Compose, don't reimplement — design-to-code owns the EXTRACT/MATCH/ADAPT/RENDER pipeline
Agent(
subagent_type="ork:frontend-ui-developer",
name=f"scaffold-{component['name']}",
description=f"Scaffold {component['name']} from bundle",
prompt=f"""Use the design-to-code skill to scaffold this component.
Source: handoff bundle {payload['bundle_id']}
Component: {component['name']}
Target path: {component['target_path']}
Bundle scaffold seed:
```tsx
{component['tsx_scaffold']}
```
Resolved tokens: {component['tokens_resolved']}
Decision: {component['decision']}
{f"Adapt from: {component['existing_match']}" if component['decision'] == 'adapt' else ''}
Write the component, mirror existing project file structure, use project tokens.
Commit it in your worktree before you return, and end your reply with
your branch name and commit sha. Uncommitted files are not merged.
""",
run_in_background=True,
isolation="worktree",
max_turns=25,
)
收集并合并组件工作树
在进入阶段 5 之前,等待所有脚手架 Agent 返回。对每个 Agent:
- 检查其工作树是否干净:
git -C <worktree> status --porcelain不应有 输出。如果有输出文件,请在该工作树中提交,并在报告中注明。 - 将其分支合并到当前分支。若发生冲突,说明两个组件写入了同一个文件:停止并报告这两个路径。
- 确认合并后
component['target_path']确实存在。Agent 失败或写入其他位置的组件应加入failed_components:仅报告,不记录为已写入。
阶段 5 — 来源信息
使用实际写入的文件路径更新来源信息文件:
provenance = Read(payload["provenance_path"])
provenance["components"] = [
{"name": c["name"], "decision": c["decision"], "path": c["target_path"]}
for c in payload["components"]
if c["name"] not in failed_components # from "Collect and merge" step 3
]
provenance["imported_at"] = now()
Write(payload["provenance_path"], provenance)
输出 — 导入清单
打印简洁的摘要(不要输出一大段 JSON):
Imported bundle <bundle_id>
Source: <bundle_url>
Provenance: .claude/design-handoffs/<bundle_id>.json
Components:
✓ PricingCard scaffold src/components/pricing/PricingCard.tsx
↻ Button reuse existing: src/components/ui/Button.tsx
⤳ Hero adapt adapted from: src/components/Hero.tsx
Tokens:
+ 3 new (added to design-tokens.json)
~ 1 modified (user accepted bundle value)
✗ 0 conflicts unresolved
Next: design-ship <bundle_id> # to open PR
expect # to verify
Hooks
- 完成后,
post-design-importhook 会推荐使用expect(非阻塞,详情见 hook)。
组合关系
| 技能 | 职责 |
|---|---|
design-to-code | 负责实际的脚手架流程(EXTRACT/MATCH/ADAPT/RENDER)。此技能会针对每个组件委托给它。 |
component-search | 供编排 Agent 去重时使用 |
design-context-extract | 交接包缺少 design_tokens 块时使用 |
design-system-tokens | 令牌协调参考 |
remember / memory | 来源信息与先前导入检测 |
此技能不负责的事项
| 事项 | 负责方 |
|---|---|
| 创建 PR | design-ship |
| 运行测试 | post-design-import hook → expect |
| 生成 Storybook stories | cover(由 design-ship 调用) |
| 再次向 Claude Design 提示 | 暂不支持——没有公开 API |
限制
- Claude Design 尚无公开 API:资源包是一次性导出。若要迭代,请从 claude.ai/design 重新导出并重新导入。反向流程(漂移检测 + 优化提示词)已列入 M124 跟踪——Claude Design Drift Sync (Bet B):#1391、#1393、#1394、#1395、#1397。
- 架构暂定:Claude Design 尚未发布稳定的资源包架构。编排 Agent 会适配偏差,但格式稳定后可能需要更新。
- 仅引用资源 URL,不下载资源:资源包中的
asset_urls会原样保留。如果需要将其放入仓库,请单独运行同步步骤。
评论
支持 Markdown