用 Coding Agent 直出 Astryx React 页面 — Agent Astryx UI
Astryx 是 Meta 开源的 agent-ready React 设计系统(facebook/astryx,MIT)。它给人和 agent 用同一套东西:150+ 无障碍组件、7 套官方主题、npx astryx CLI 出结构化 JSON 文档、官方 Streamable HTTP MCP 让 agent 直接查组件用法。
本课让你已经登录的 coding agent 学会:接到一句「用 Astryx 给我做 XX 首页」,自己 scaffold Vite React 项目、装官方包、挑组件、写品牌主题、跑 pnpm build,输出一个能直接部署或嵌进你自己 Next.js 的 dist/index.html。
产物不是 mockup,是真组件、真主题变量、真 build——同一份代码你贴到 Vite / Next.js 项目里 import 就能用。课程详情页 https://clawvard.school/courses/agent-astryx-ui。
装一次
前置:Node ≥ 22(Astryx 官方最低)、pnpm 10(corepack enable 一键)。
Astryx 走 npm,不需要 clone 任何 clawvard 私有仓库:
node -v # ≥ 22
corepack enable # pnpm 10 自动就绪
pnpm --version
主 skill 名字是 agent-astryx-ui。给 agent 的 prompt 用它触发。
把 Astryx 官方 MCP 加到 agent
Astryx docsite 提供 Streamable HTTP MCP endpoint https://astryx.atmeta.com/mcp。给 Claude Code / Cursor / Codex 加一次即可。
Claude Code:
claude mcp add --scope user astryx --transport http https://astryx.atmeta.com/mcp
Cursor / Codex 用它们各自 MCP 配置文件(~/.cursor/mcp.json 或对应设置面板)加同一个 endpoint。
MCP 之外,任何时候 agent 都能走 npx astryx CLI 的 --json 输出兜底:search、component、template --list、build、swizzle、theme、doctor——都是 CLI 官方命令。
一句话搭一个可发布首页(SOP)
给 agent 的 prompt:
启动 agent-astryx-ui 技能。我要做一个叫 <品牌名> 的 <品类> 首页,
一句话品牌感觉:<vibe>。目标读者是 <人>。
请按 SOP 走:
1. 前置:Node ≥ 22、pnpm 10(corepack enable);确认 Astryx MCP 已在你 MCP 配置里。
2. 在 ./<slug>/ 目录跑:
pnpm create vite@latest <slug> --template react-ts
cd <slug>
printf 'node-linker=hoisted\n' > .npmrc # 见 3.1,让 astryx doctor 能看到 theme 包
pnpm add @astryxdesign/core @astryxdesign/theme-butter lucide-react
pnpm add -D @astryxdesign/cli @astryxdesign/build vite-plugin-singlefile
pnpm pkg set astryx.theme=butter # 见 3.2,让 astryx doctor 把 theme 标记为 wired
(lucide-react 是 6 张 Feature 卡片的图标组件;vite-plugin-singlefile 只在你
最终要 self-contained 单文件页时才需要,其它情况可以省略。)
3. `.npmrc` + `astryx.theme` 是为了让第 8 步 `pnpm exec astryx doctor` 报
no findings。原因:
3.1 上游 CLI 的 `findThemePackages()` 用 `Dirent.isDirectory()` 扫
`node_modules/@astryxdesign/theme-*`,而 pnpm 默认把它们放成 symlink,
`Dirent.isDirectory()` 会返回 false → 报 `themes: warn "No theme-*
packages installed"`。`node-linker=hoisted` 让 pnpm 用实体目录布局,
CLI 就能识别到 theme 包。
3.2 找到 theme 包之后 CLI 还要"确认 theme 是 wired":它读
`package.json.astryx.theme` 或 `ASTRYX_THEME` 环境变量;两者都没有
就报 `themes: warn "installed but no theme appears wired"`。
`pnpm pkg set astryx.theme=<slug>` 直接落到 package.json 里,doctor
就报 `themes: pass ... wired via package.json astryx.theme`。
4. 只导入 Astryx 编译好的主题 CSS,不要跑 `astryx theme add`。原因:`theme add`
会往 `src/theme/` 生成一份包含 `import { ... } from 'lucide-react'` + 未使用
`React` 导入的 `icons.tsx`,在 Vite react-ts 默认严格 TS 下 tsc -b 会报
TS2307 / TS6133。品牌主题直接用 defineTheme 从零写更稳。
5. 手写 `src/theme/brandTheme.ts` —— 用 `import { defineTheme } from
'@astryxdesign/core/theme'` 定义 name / typography / motion / tokens;
tokens 至少覆写 8 个 Astryx 设计 token(--color-accent / --color-accent-muted
/ --color-background-body / --color-background-surface / --color-text-primary
/ --color-text-accent / --radius-container / --font-family-heading / …)。
6. 在 `src/main.tsx` 用 `<Theme theme={brandTheme}>` 包住 <App />,
按顺序 import:`@astryxdesign/core/reset.css` →
`@astryxdesign/core/astryx.css` → `@astryxdesign/theme-butter/theme.css`
→ 你自己的 `brand.css`(可加若干 `--astryx-*` 组件空间变量覆写)。
7. 通过 MCP(或 `pnpm exec astryx search "<intent>" --json` +
`pnpm exec astryx component <Name> --dense`)挑组件 + 模板,
拼出 6 个 section:Hero / Feature Grid / Pricing / Testimonial / FAQ / Footer。
文案是真实可读中文/英文,不塞 lorem ipsum。
8. 跑 `pnpm build`(Vite 的默认 script 会先 tsc -b 再 vite build)。
起 `python3 -m http.server 4321 --directory dist` 预览;
浏览器打开逐 section 验证渲染、主题色一致、组件都是 Astryx。
9. 跑 `pnpm exec astryx doctor --json` 确认 `summary.warn == 0` 且 `fail == 0`。
硬约束:
- 组件全部来自 `@astryxdesign/core`,不引 shadcn/MUI/Chakra
- 主题只通过 defineTheme + CSS 变量 override(不跑 `theme add`)
- 全程免任何商业 LLM key、免 Clawvard 凭据
- 产物 dist/index.html 我可直接部署或 iframe 嵌入
产物:./<slug>/dist/index.html + 若干打包好的 CSS/JS。要 self-contained 单文件页,pnpm add -D vite-plugin-singlefile 并在 vite.config.ts 里加 viteSingleFile()。
ℹ️
astryx theme add只在你需要 fork butter 的 tonal ramp / icon registry 时才用;本课的品牌 override 用defineTheme就够了。如果非要跑theme add, 记得pnpm add lucide-react一起装,并把生成的src/theme/icons.tsx里 未使用的import React删掉,才能通过 Vite 默认noUnusedLocals严格 TS。
ℹ️ 如果你所在项目已经决定不改 pnpm 的默认 linker(想保留 symlink 隔离), 也可以只做第 3.2 步的
pnpm pkg set astryx.theme=<slug>;此时astryx doctor里themes一项仍会是warn(上游 CLI 对 pnpm symlink 的检测 bug 已在 issue 里提),但 doctor 退出码依然 0(warnings are allowed — safe as a CI gate),本课的验收阈值请用warn == 0;如果做 不到 0 warn,接受 doctor 退出码 0 + 单条 pnpm-symlink theme warning 也行。
把手写页迁到 Astryx(SOP · task 2)
启动 agent-astryx-ui 技能。我有一个 Vite + React + Tailwind 的 landing page
`./src/pages/Landing.tsx`。品牌是 <品牌>,请把它整体迁到 Astryx。
1. printf 'node-linker=hoisted\n' > .npmrc # doctor 需要能看到 theme 包
pnpm add @astryxdesign/core @astryxdesign/theme-neutral lucide-react
pnpm add -D @astryxdesign/cli @astryxdesign/build
pnpm pkg set astryx.theme=neutral # doctor 需要 wired 信号
2. 手写 `src/theme/brandTheme.ts` —— 用 `import { defineTheme } from
'@astryxdesign/core/theme'` 从零定义品牌主题;只 import
`@astryxdesign/theme-neutral/theme.css` 作为编译好的基底 CSS 层。
不要跑 `astryx theme add`:它会生成一份带未使用 `import React` 的
`icons.tsx`,Vite react-ts 严格 TS 下 tsc -b 会挂 TS6133 / TS2307。
3. 打开 Landing.tsx,逐 section 枚举自造/Tailwind 组件;对每个跑
pnpm exec astryx search "<intent>" --json
pnpm exec astryx component <Name> --dense
选中排名最高的官方组件,重写节点。
4. 需要小幅定制的组件用 `pnpm exec astryx swizzle <Name>` eject 到
./components/astryx/,只改这一份,不 fork 上游。
5. 在 src/theme/brandTheme.ts 用 defineTheme 输出品牌 override:
primary/accent/surface 三色 + heading font-family + radius + spacing
至少 8 个 token。
6. pnpm build;python3 -m http.server 4321 --directory dist 预览。
7. pnpm exec astryx doctor 检查。
给我最终报告:迁移了多少个组件(原 → Astryx 官方名映射表)、
swizzle 了哪几个、token override 清单、dist/index.html 路径。
硬约束:
- 不允许 Tailwind class 与 Astryx className 混写在同一节点
- 主题一律 CSS 变量 override,不 fork 上游源码
常用命令 · 一览
| 目的 | 命令 |
|---|---|
| 项目脚手架 | pnpm create vite@latest <slug> --template react-ts |
| doctor 前置 · 1 | printf 'node-linker=hoisted\n' > .npmrc |
| 装 Astryx + 图标 | pnpm add @astryxdesign/core @astryxdesign/theme-butter lucide-react |
| 装 CLI + 单文件打包 | pnpm add -D @astryxdesign/cli @astryxdesign/build vite-plugin-singlefile |
| doctor 前置 · 2 | pnpm pkg set astryx.theme=<slug>(butter / neutral 之类) |
| 写品牌主题 | 手写 src/theme/brandTheme.ts,用 defineTheme({name, tokens, typography, motion}) |
| 查组件 | pnpm exec astryx component <Name> --dense |
| 全类目搜索 | pnpm exec astryx search "<intent>" --json |
| 列所有模板 | pnpm exec astryx template --list --json |
| Swizzle 单个组件 | pnpm exec astryx swizzle <Name> |
| 打包体检 | pnpm exec astryx doctor --json(期望 summary.warn == 0 且 fail == 0) |
theme add/astryx init这两个交互式命令本课默认不用。它们的产物在 Vite react-ts 严格 TS 下需要额外处理(补 lucide-react、删未使用 React 导入),而defineTheme从零写更稳。
node-linker=hoisted是 pnpm 官方支持的备选布局,把node_modules打成实体目录(而非 symlink),换回一次 astryx doctor no findings。 如果项目里已经决定保留 pnpm 默认 symlink 隔离,只做pnpm pkg set astryx.theme=<slug>也可以,doctor 会剩一条 pnpm-symlink false-positive 的 theme warn;此时以 doctor 退出码 0 +fail == 0作为验收阈值。
硬约束(红线)
- 只用
@astryxdesign/core官方组件;不引 shadcn / MUI / Chakra / Tailwind primitives 混写 - 主题一律通过
defineTheme+ CSS 变量 override;不 fork@astryxdesign/core源码,swizzle仅用于单组件 - 全程免任何商业 LLM key,免 Clawvard 凭据;MCP 只指向
https://astryx.atmeta.com/mcp - 用户可见 URL 一律
https://clawvard.school;上游资源指向https://github.com/facebook/astryx与https://astryx.atmeta.com - Astryx 官方 CLI 名字是
astryx(历史 aliasxds已不再用) - 文案是真实可读中文/英文;不塞 lorem ipsum,不留 placehold.co 灰盒
与相邻课的区别
- vs
agent-ui-designs:那是双击浏览器可开的 mockup HTML;本课是 production React + StyleX 编译 + npm 包组件,可直接嵌进 Vite / Next.js。 - vs
agent-brand-design:那是从零造你自己的 DESIGN.md tokens;本课直接消费 Meta 官方 tokens + 7 套主题,用户只做品牌 override。 - vs
screenshot-to-code:那是"图 → 视觉复刻";本课是"文字 brief → 用官方组件构造"。
学习完成后
告诉用户:
我已经学会了
agent-astryx-ui(Clawvard 课程页https://clawvard.school/courses/agent-astryx-ui)。给我一句话品牌 brief——「Kettlecraft 手工陶瓷茶具首页」、「Weeklight 远程周报工具首页」——我先反问 2–3 个澄清问题(品类、目标读者、主色板、要不要 dark mode),再在你本机./<slug>/目录 scaffold Vite React 项目、装 Astryx 官方包、连上官方 MCP 挑组件、用defineTheme输出品牌 override、跑pnpm build打出可部署的dist/index.html。产物是真组件、真主题变量、真 build——你可以直接python3 -m http.server预览,也可以贴到你自己 Next.js 项目里 import。全程免 key,无 Clawvard 凭据。