yuanlang12/openpipal/design-system-authoring
Claude Code and agent skill by yuanlang12/openpipal
- community
Checking that the SKILL.md file is still in the repository.
把一套设计系统做成 ~/.openpipal/design-systems/<名>/ 下的文件夹交付物——目录蓝图、tokens、组件三件套(jsx + .d.ts + .prompt.md)、@dsCard 预览卡、UI kit、编译产物与画廊评审闭环。用户说"做一套设计系统 / UI kit / 品牌规范库 / 组件库",或要修订、增补、重新编译已有的那一套时必读。只是要给单个交付物定色板和字体,读 design-tokens 就够,不用读这份。
Install
npx vskill@latest install yuanlang12/openpipal/design-system-authoringSKILL.md
design-system-authoring
这份技能管怎么把一套设计系统组织成一个文件夹,并让宿主把它编译成能用的东西。
- 色值怎么推、字号刻度怎么定、token 该叫什么名字 →
design-tokens,本篇不重复。 - 单个页面的版式与观感判断不在本篇范围。
一、交付物是一个文件夹,不是 artifact
- 落点
~/.openpipal/design-systems/<系统名>/,kebab-case。 - 本交付豁免"整页 HTML 走 artifact"的规则:设计系统就是一堆文件,用 write 逐个文件写。
- `SKILL.md` 存在 = 注册完成。 宿主列举设计系统时只认一件事:目录下有一个真实的、非软链的
SKILL.md(role-manager.ts:352-367)。没有它,这套系统在新建任务界面里等于不存在; 有了它,不需要任何别的登记动作。
- 系统名会被校验:非空、≤128 字符、首尾无空白、不以
.开头、不含/\..\0
(design-system-resource.ts:198-210);系统目录本身不能是软链(同文件 13-33)。
SKILL.mdfrontmatter 的name/description就是画廊页眉的标题与副标题
(role-manager.ts:449-469,逐行解析、只抓这两个键,不是 YAML 解析器)。
谁会读这个文件夹——这决定了它该怎么组织
用户在新建任务界面勾选一套系统后,它以 category="design-system" 加绝对路径进入那个会话的上下文 (RolePreflowPanel.tsx:517)。那个会话拿到的指令是固定的(agent-runtime/openpipal-prompt-core.ts:181-182): 先读 SKILL.md → 按它的指引读 README / tokens / 组件文件 → 要用哪个组件先读它的 .prompt.md → 交 dc 产物时把 token 文件的 :root { --… } 块原样拷进 helmet `<style>`。
三条推论,直接决定蓝图:
SKILL.md是唯一入口,必须写清阅读顺序,不能只写一句"看 README"就完事;- 每个组件的
.prompt.md是它的权威用法说明,不是可选装饰; - 每个 token 文件要能被单独整块拷走——语义别名和它依赖的基础值放同一个文件里,
跨文件 var() 引用在拷贝后会断链,下游拿到的是一堆解析不出来的变量名。
二、目录蓝图
以 _ 或 . 开头的目录不进任何扫描;ui_kits assets fonts node_modules screenshots shared 不进卡片扫描(role-manager.ts:446、ds-compile.ts:171)。品牌方有自己的目录惯例时从其惯例, 但 SKILL.md / styles.css / components/ / ui_kits/ 这四个位置是硬约定,改了扫描就找不到。
三、骨架:能直接抄的三个最小件
预览卡(一张一个 .html)
首行必须是 @dsCard(见 §5)。styles.css 走相对路径,深度按卡片所在目录算: guidelines/ 用 ../,components/core/ 用 ../../。卡内不写标题不加外框——卡名由画廊渲染在卡外。
组件三件套
这个例子走 className,那就意味着 .btn / .btn-primary 等必须在被 styles.css @import 的 CSS 里 真实定义(§10);不想维护类名就全用内联 style + var(--token),两条路都行,混着走最容易漏。
组件卡(消费编译产物)
普通 <script> + React.createElement,不用 text/babel、不用任何远程地址(见 §6)。 组件或 token 改了,这张卡重编译后会跟着变——这是它比手写 CSS 复刻更保真的原因。
四、编译:一次工具调用,落四件产物
create_artifact({ type: 'design-system', title: '<显示名>', content: '{"name":"<文件夹名>"}' }) 既是"把画廊交给用户"的手势,也是编译触发器(openpipal-product-tools.ts:1155-1187)。它落四件:
| 产物 | 是什么 | 出处 | |
|---|---|---|---|
_vendor/react*.production.min.js | React 18.3.1 UMD 两件,每次编译都刷新 | ds-compile.ts:108-115、741-745 | |
_ds_manifest.json | 12 键机器索引:namespace components cards tokens globalCssPaths fonts brandFonts hasThumbnailHtml source,另有恒为空的 startingPoints templates themes | ds-compile.ts:789-809 | |
_ds_bundle.js | format 4 预编译包,挂到 window.<namespace> | ds-compile.ts:811-886 | |
_adherence.oxlintrc.json | 从 .d.ts 生成的 oxlint 规则 | ds-compile.ts:888-895 |
- namespace =
PascalCase(文件夹名)_sha1(文件夹名)前6位(ds-compile.ts:121-132)。确定性、同名可复现;
首字符是数字时前缀 Ds。别自己编,编完了从 _ds_manifest.json 里读。
- best-effort:单件失败不阻断其余,错误随工具返回值回来(前 6 条),比如某个 jsx 的 esbuild 语法错。
看到 ⚠️ 设计系统编译告警 就修,那是编译器在指你的语法错。
- 时序:写完组件三件套 → 先调一次
create_artifact(type='design-system')让_vendor/和
_ds_bundle.js 落盘 → 再写并自检消费真组件的卡 → 收尾用同一个 id 再调一次刷新画廊。 第一次编译之前,任何引用 _ds_bundle.js 的卡都是白板。
- 同一套系统反复发布:带历史里那个画廊 artifact 的原 id。不带 id 且标题相近会被拦
(只和同 type 比对,artifact-store.ts:544-556),拒绝消息里给的 id 就是本系统的画廊,带上它重发。 force_new: true 只在用户明确要"另做一份留着对比"时用。
- 没有 jsx 组件的系统照样能编(
components为空壳),画廊走@dsCard派生,不受影响。
_ds_bundle.js 怎么编出来的——这决定了 jsx 怎么写
transformComponentSource(ds-compile.ts:493-531)在交给 esbuild 之前剥掉所有 import 行:
import React from 'react'→ 剥。React 由_vendor/提供的全局承接。- `import { useState } from 'react'` 也被剥,且不做任何补偿。 组件里写裸
useState就是渲染期
ReferenceError。一律 `React.useState` / `React.useEffect` / `React.useMemo`。
import { Icon } from './Icon.jsx'→ 剥,并把这个文件里所有独立出现的Icon改写成
__ds_scope.Icon(ds-compile.ts:843-845)。求值时解析,文件先后顺序无关。
- 任何 npm 依赖 → 静默剥掉。组件只能靠 React + CSS 变量,不能有第三方包。
暴露规则:只有 components/** 的具名导出挂上 window.<namespace>;ui_kits/** 的 jsx 照样编译进包, 但只进 unexposedExports,卡片里取不到(ds-compile.ts:854-861)。要被 kit 复用的东西必须住在 `components/`。 每个模块单独 try/catch,出错记进 window.<namespace>.__errors (ds-compile.ts:849-853)——卡片渲染不出来时先打这个数组。
_adherence.oxlintrc.json 怎么来的
buildAdherence(ds-compile.ts:602-707)用 TypeScript 解析 components/**/*.d.ts:
- 只认 `interface` 声明,
type X = {…}不算。XProps→ 组件X;不带Props后缀的接口名会被
原样当成组件名,所以数据形状接口别塞进组件的 .d.ts。
- 每个 interface 的属性名 → 该组件的 prop 白名单,额外放行
keyrefclassNamestylechildren
(ds-compile.ts:623)。
- 纯字符串字面量联合(
'primary' | 'ghost')→ 枚举校验;掺进任何非字面量类型就整条不算枚举。 - 三条全局禁令,全
warn级(ds-compile.ts:627-641):裸 hex 色值 / 裸px数值 /
不在 brandFonts 里的 font-family。第三条只在 `brandFonts` 非空时才生成。
这份文件没有宿主在跑。 全仓只有 ds-compile.ts 提到 oxlint,应用里没有任何地方执行它—— 落盘只为互操作,给外部工具和人读。所以那三条禁令没有机制兜底,是纪律不是门闩,靠你自己守。
五、@dsCard:画廊的驱动元数据
每张预览卡首行一条注释,属性顺序任意、单双引号都容(ds-compile.ts:188-210、role-manager.ts:551-571):
viewport="WxH"→ 画廊 iframe 的实际渲染尺寸(DesignSystemGallery.tsx:345-352)。
缺省 700×400;高度被静默夹到 640 上限(role-manager.ts:569),写 900 会得到 640。
group→ 归入哪个分组。缺省用卡片所在的顶层目录名,根目录下的卡兜底成general。
组名用 Title Case,全套一致(Colors / Type / Spacing / Motion / Components / Brand)。
name缺省由文件名标题化——先去.html再去.card,-_.转空格后首字母大写
(buttons.card.html → Buttons,type-scale.html → Type Scale);subtitle 缺省空。
- 分组顺序按首次出现,组内按文件名排序。
缺 `@dsCard` 不报错:卡照样进画廊,只是掉进兜底分组、尺寸也是兜底值。缺标签视为这张卡没做完。
尺寸纪律:宁多张小卡,不做一张大卡。主色 / 中性色 / 语义色分开,display / body / mono 分开, 间距 token 和间距实例分开。一套系统典型 12–20 张。
UI kit 不吃 viewport:ui_kits/<目录>/index.html 在画廊里恒为全宽 × 640 高 (DesignSystemGallery.tsx:394-400),给 kit 写 @dsCard 只影响 _ds_manifest.json 的 cards 条目。
六、画廊预览是严格断网的沙箱
卡片和 UI kit 在画廊里通过本地回环 HTTP 以 iframe 加载,响应头带一条严格 CSP (design-system-resource.ts:73-102,http-server.ts:1312-1346):
能加载的只有本设计系统目录内的文件,加上内存里的 data: / blob:。落到实处:
- 字体必须是本地文件 + `@font-face`。 没有 Google Fonts、没有任何字体 CDN、没有
@import url(https://…)。
这条和 dc-authoring 的字体口径是同一条。可伺服的字体后缀只有 .woff2 .woff .ttf .otf (design-system-resource.ts:182-188),别的后缀直接 404。缺正版字体就用系统字体栈替身并打旗标(§10)。
- 远程图标、远程图片、远程脚本一律被拒。素材拷进
assets/再相对引用。 connect-src 'none'→fetch/XMLHttpRequest/ WebSocket /sendBeacon全断。UI kit 的"数据"
只能是写死在页面里的常量。
- 沙箱不含
allow-same-origin→ 文档处于不透明源:**localStorage/sessionStorage一碰就抛
SecurityError**;alert / confirm(无 allow-modals)、表单提交(无 allow-forms 且 form-action 'none')、嵌套 iframe(frame-src 'none')都不可用。交互状态只能放在内存里。
- 没有
'unsafe-eval'→ 别在卡片里eval/new Function/text/babel现场编 JSX。JSX 由
_ds_bundle.js 预编译,这是它存在的理由。
- 单个文件超过 8MB 不伺服(
design-system-resource.ts:7)。大图先压。
不能通过放宽预览的安全策略来兼容外部依赖。 把依赖拷进目录里,并在 README 记来源。
七、宿主已经替你做了什么
这些不用你写,写了也是白写:
- 不用手写 token 清单、分类、品牌字体清单、lint 规则。 编译器静态解析你的 CSS 与
.d.ts自动生成。 - 不用手写 `_ds_manifest.json` / `_ds_bundle.js` / `_adherence.oxlintrc.json` / `_vendor/`。
手写就是和编译器打架——下次发布会被整个覆盖。你只写源:jsx / d.ts / prompt.md / css / card.html / README.md / SKILL.md。
- 不用手动登记系统。
SKILL.md落地即被列举,新建任务界面自动出现。 - 不用维护评审台账。
_review.json由画廊读写(role-manager.ts:375-418),下次发布时宿主自动
把"仍被踩且未解决"的项列到工具返回值里。别手写、别删。
- 不用自己截图。
render_artifact自检会渲染页面、回传 console 错误/警告、跑一遍文本重叠检测
(最多 5 条)、抓一段页面文本摘要,并把截图作为 image block 直接内联在工具结果里回给你 (openpipal-product-tools.ts:730-784;截图同时存到本会话的 ~/.openpipal/outputs/<会话id>/.self-check/(路径在结果里), 那份是给人看的)。你不需要、也不应该去 read 那个 png 文件。 两种降级会明说:模型不支持看图、或图太大(base64 超 600KB)时只给文本摘要。
- 不用给画廊单独做缩略图。 根目录的
thumbnail.html只被记进 manifest 的hasThumbnailHtml,
画廊不消费它。
八、约束与静默失败
不知道就会踩、踩了不报错的:
This is the start of the file. Read the full SKILL.md on GitHub.
Security
- Security scanPassed, 96 of 100Pattern checks on the skill's files.
- Model reviewNot runA model review is scheduled for the next rescan.
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingresources/skills/design-system-authoring/SKILL.md
Popularity
- Repository stars
- 52
- Repository forks
- 6
- 7-day trend score
- 0
Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/yuanlang12/openpipal/design-system-authoring)