
Astryx 的 shadcn Registry 兼容层系统规范解读在不复制设计系统实现的前提下让 970 个组件、示例、Block 与页面模板通过标准 Registry 协议可安装【免费下载链接】astryxAn open source design system thats fully customizable and agent ready项目地址: https://gitcode.com/GitHub_Trending/as/astryxAstryx 通过 docs/specs/AST-026/spec.md 这份system-spec定义了它与 shadcn Registry 生态的兼容层让开发者能在现有 shadcn 工作流中直接安装 Astryx 的组件、组件展示showcase、示例块example block与整页模板同时绝不把 Astryx 变成基于 shadcn 的库也不在普通安装中把组件实现源码复制进消费者仓库。本文将完整解读该规范的意图、非目标、FR/IR 需求契约、970 条目的当前状态、验证矩阵与七条决策日志并结合仓库内的生成器、receipt 契约、升级引擎与全量目录 CI 源码深入剖析「复制组合、不复制实现」「稳定身份路由」「可升级的复制组合」等关键机制的底层实现。规范定位为什么是「兼容协议」而不是「新注册表」AST-026 的 Intent 非常明确让构建者通过标准 shadcn Registry 协议安装 Astryx 组件、组件展示、示例块和页面模板但 Astryx 自身不成为 shadcn 系库也不把 Astryx 组件实现复制进消费者仓库。兼容层在既有 shadcn 工作流内部与构建者相遇Astryx CLI 仍然是更丰富的首选接口承担发现discovery、组合composition、集成integrations、主题themes、校验validation与升级upgrades职责。该记录治理的是已批准的兼容基础。实现可以合并在 canary 文档站docsite之后而「复制组合的可升级能力」则是生产端点和对外公告的发布门槛launch gate。规范同时列出了明确非目标避免边界漂移用 shadcn CLI 取代 Astryx CLI定义第二套 Astryx 专属 registry 格式在普通安装中复制 Core 或 Lab 组件实现源码把生成的示例、Block 或页面当作字节稳定的公共 API发布不受支持的 SLA或让复制组合成为包管控的实现源码改变显式的astryx swizzle深定制逃生口。从实现侧看这一意图体现在 apps/docsite/scripts/generate-shadcn-registry.mjs 顶部的文件说明中它是「Astryx 目录与 shadcn 客户端之间的构建期序列化器」保持 Astryx 包为真实依赖组件/hook 条目只创建公共 re-exportBlock 与页面复制已导入发布包路径的应用级组合源码并附带相邻 receipt 供 Astryx 在后续版本中协调而无需接管用户编辑。需求契约全景FR1–FR10 与 IR1–IR5规范以十条功能需求FR和五条实现需求IR锁定兼容层的行为边界这里逐条给出原文要义并标注仓库内的落地证据。功能需求FRFR1 — 标准协议每个 registry 条目必须通过标准 shadcn Registry schema 校验并使用标准条目类型标准 shadcn 客户端无需任何 Astryx 专属代码即可读取与安装。实现上generate-shadcn-registry.mjs 固定使用https://ui.shadcn.com/schema/registry.json与registry-item.json两个 schema并用shadcn/schema的registryItemSchema/registrySchema做safeParse强校验。FR2 — 保留包边界组件安装必须新增已发布的 Astryx 包依赖只生成消费者可用的 import/re-export 源码绝不复制组件实现、私有 helper 或未编译的 StyleX 源码。生成器中的componentItem仅产出export * from importPath一行测试 generate-shadcn-registry.test.mjs 断言组件条目文件内容恰为export * from astryxdesign/core/Button;\n。FR3 — 完整请求的目录实验必须覆盖 CLI 与 docsite 同一目录中的每个公共组件或 hook、每个组件展示与示例块、其他所有 Block以及每个就绪页面模板见下文「一个目录、两种客户端」。FR4 — 可编辑组合展示、示例、Block 与页面条目可以复制应用级组合源码但该源码必须通过发布包路径导入 Astryx、声明全部非 React 包依赖且不得包含逃逸出所复制条目的相对导入。生成器的dependenciesForSource遇到./或../开头且逃逸的导入会直接抛错relative import ... registry compositions must use published package paths。FR5 — 确定性、稳定身份条目名、组织化 URL 路径、目标路径、依赖列表与 JSON 输出必须确定且无碰撞身份必须源自稳定的 doc/catalog 字段而非显示标签或源文件名显示名变更不得改变安装 URL已发布的改名必须保留旧路由为别名。FR6 — 一个目录、两个客户端shadcn 客户端消费标准字段Astryx CLI 可以读取原始 JSON 中的可选astryx元数据用于集成、来源provenance与升级指引标准客户端丢弃该元数据不影响安装。生成器为每个条目写入astryx: {kind, path, aliases, packageName, importPath, hidden, ...}元数据块测试专门验证「原始 JSON 保留 Astryx 元数据而标准客户端可剥离」。FR7 — 可发现的兼容性公开 docsite 必须描述兼容边界并在每个适用的组件、示例、Block、页面表面的末尾展示一个可复制的次要安装命令普通 Astryx 文档仍是人类浏览体验原始/shadcn/路径保持机器端点。FR8 — 分阶段发布预览构建必须从自己的/shadcn源提供完整 registry 并使用canary包依赖生产必须使用精确发布版本且在复制组合升级能力就绪前保持禁用。FR9 — 可升级安全的复制组合每个被复制的展示、示例、Block、页面必须安装相邻的机器可读 receipt其中包含稳定条目路由、复制目标、精确安装字节及其哈希。astryx upgrade只对匹配已安装 Astryx 版本的规范条目生效自动更新未改动文件、三路合并用户编辑、编辑冲突时保留原文件并且绝不重建被删除或移动的文件。FR10 — 必需的全量目录 CI必选 PR CI 必须生成完整预览目录、在发布前拒绝生产输出、通过固定 shadcn 客户端安装每个规范条目、校验每个路由与精确写入文件并针对当前 Astryx 包导出编译每个已安装源码。实现需求IRIR1 — 从当前源码生成registry 输出必须来自既有 docsite 与 CLI 目录绝不使用并行的手写条目列表。生成器输入就是 docsite 数据产物package、component、block、page 记录注释明言「增加的是覆盖既有目录的序列化器而不是第二套发现系统」。IR2 — 构建期静态输出docsite 构建必须在单一 registry 根下生成静态 JSON可被干净构建复现的生成 JSON 不得提交入库。IR3 — 失败要响亮缺失源码、重复名称、非法 schema、未解析的包版本、逃逸相对导入、过期生成输出都必须让生成或校验失败。生成器在assertUniqueItemNames、assertUniqueItemPaths与 schema 校验阶段全部抛错终止。IR4 — 端到端证据必选校验必须在干净的 shadcn 风格应用中通过固定 stock 客户端安装每个规范组件、hook、展示、示例、Block 与页面校验精确写入字节与声明的依赖并编译每个写入的源文件别名路由必须解析到同一规范条目的字节。IR5 — 稳定路由契约生成的条目名与规范路径必须匹配已评审的路由锁显示名编辑不得改变它们有意的改名必须通过registry.aliases保留旧路径除非另行评审的破坏性变更批准移除。平台支持边界规范对支持面给出了明确约定功能/引擎下限为当前 Astryx Node floor 与实验所用固定 shadcn 版本仓库测试确认固定为shadcn 4.19.0见 apps/docsite/src/lib/shadcnRegistry.mjs 的SHADCN_CLI_VERSION。不支持的行为包括未经显式astryx swizzle复制 Astryx 实现源码、安装隐藏/不完整/不可解析的目录条目。浏览器证据方面在提议发布前一个有代表性的已安装页面必须在真实 Chrome 中以亮色与暗色两种模式渲染通过。当前状态影响一个目录、两种客户端970 个条目的事实基线规范用「Current-state impact」记录了兼容层启动时的真实基线这是理解整个实验规模的关键事实CLI 已可交付组件、数百个示例与展示、页面模板docsite 生成器已发现组件、独立展示与示例、Block、页面、包版本与源码。兼容层是在既有目录上增加序列化器而非第二套发现系统。当前目录生成970 个条目。其中700 份复制组合各自携带相邻 receipt且其 base 与 stock shadcn 写入的精确字节一致。必选 CI 通过shadcn 4.19.0把全部 970 个条目安装进一个干净消费者校验全部1,670 个写入的源文件与 receipt 文件并编译全部970 个源码入口。有14 个组合在生成期作者本地 StyleXstylex.create被预编译为无编译器的 JSX其余组合源码保持带类型的 TSX。组件实现的复制尝试曾因私有导入与未编译 StyleX 跨越包边界而失败——这正是 FR2 拒绝该路径、改为「安装包 只建公共 re-export」的直接动因。这一「一个目录、两种客户端」的模型对应 FR6shadcn 客户端消费标准字段完成安装Astryx CLI 额外读取astryx元数据获得集成/来源/升级指引。规范在 docs/specs/AST-026/spec.md 中同时记录了早期的配套叙事在一个干净的 shadcn Vite 应用中通过 shadcn CLI 安装 Button 条目、Button 展示、Button 示例与完整 analytics dashboard 后CLI 安装了 Astryx 包与其他依赖、写入所需 CSS、将四个文件落入应用且应用构建成功。注册表生成器实现在既有目录之上加一层序列化器生成器 apps/docsite/scripts/generate-shadcn-registry.mjs 是兼容层的核心实现其输入是 docsite 生成好的 package、component、block、page 记录输出是配置目录下的标准 registry JSON。关键机制如下。分阶段门控generateShadcnRegistryForTargetFR8 的落地是 generate-shadcn-registry.mjs 中的generateShadcnRegistryForTarget只有当target canary时才生成 registry任何非 canary 目标如latest都会先删除输出目录并返回null。这保证了生产构建无法暴露/shadcn。配套的 internal/shadcn-registry/verify-production-gate.mjs 是一个无需网络的 CI 断言预置一个带stale.json的shadcn目录调用该函数后断言返回null且目录整体被删除。组件条目只生成 re-exportcomponentItem依据component.name.startsWith(use) || component.params ! null判定 hook进而选择registry:hook/registry:component类型与hooks/astryx/components/astryx目标根没有公共导入路径的组件直接抛错。条目文件内容恒为export * from astryxdesign/core/Button;组件条目的依赖由dependenciesForPackages从包清单递归展开自动纳入 peerDependenciesReact/ReactDOM 除外并为每个条目统一注入两条 CSS 导入const ASTRYX_CSS { import astryxdesign/core/reset.css: {}, import astryxdesign/core/astryx.css: {}, };Block 与页面条目复制应用级组合 相邻 receiptBlock 条目blockItem读取 CLI 资产目录packages/cli/assets/templates/blocks/category/dirName.tsx页面条目pageItem读取packages/cli/assets/templates/pages/slug/page.tsx。两者都会剥离版权头、预编译本地 StyleX见下、提取依赖、审计相对导入然后用withCompositionReceipt在源文件旁追加 receipt 文件并在astryx元数据中记录receipt.schemaVersion与receipt.target。值得注意的一个 shadcn 4.19.0 兼容细节shadcn 4.19.0 会静默跳过类型为registry:page的文件因此页面条目保持type: registry:page语义但其中的源文件使用可工作的registry:block类型测试 generate-shadcn-registry.test.mjs 明确断言了这一 workaround 的存在与目标路径app/astryx/dashboard/page.tsx。依赖提取与相对导入审计readImportSpecifiers用 TypeScript AST 扫描 import/export 声明与动态import()dependenciesForSource对每个非相对、非 React、非node:的 specifier 归一到包名并通过 BFS 展开 peerDependencies。任何以.开头的相对导入都会立即抛错——这实现了 FR4/IR3 中「组合源码不得有逃逸相对导入」的强制。StyleX 预编译管线precompileStylexSource检测stylex.create如果源码包含 StyleX就用babel/corestylexjs/babel-plugindev: false, runtimeInjection: true编译若结果中仍有stylex.create则抛错。预编译产物通过transformShadcnJavaScriptSource归一化幂等以.jsx扩展名发布并附带一个窄声明文件*.astryx.d.mts内容为declare module *suffix { const Component: import(react).ComponentType; export default Component; }。receipt 中该文件的 variants 为空数组——预编译 JSX 不再有 JS 变体。确定性校验生成结束后依次执行assertUniqueItemNames重复条目名抛错、assertUniqueItemPaths规范路径与别名全部无碰撞、逐条目registryItemSchema.safeParse、最终registrySchema.safeParse。任何失败都会让生成终止IR3。稳定身份与路由契约名字与路径是公共 APIFR5/IR5 的「确定性、稳定身份」由 apps/docsite/src/lib/shadcnRegistry.mjs 统一实现该模块是生成与 docsite UI 之间共享的契约。六条路径族DEC-4 决定按条目类型组织 URLcomponentRegistryIdentity/blockRegistryIdentity/pageRegistryIdentity分别生成条目类型name 前缀路径族示例来自测试组件component-components/slugcomponent-button→components/buttonHookhook-hooks/slughook-use-app-shell-mobile→hooks/use-app-shell-mobile展示showcase-showcases/component/slugshowcase-button-variants→showcases/button/variants示例example-examples/component/slugexample-button-leading-icon→examples/button/leading-icon独立 Blockblock-blocks/slugblock-filter-toolbar→blocks/filter-toolbar页面template-templates/slugtemplate-analytics-dashboard→templates/analytics-dashboard非 Core 包会再插入包 slug 段如components/richtext/slug。Block 的身份派生规则无exampleFor时是独立 Block有exampleFor且isShowcase时是 showcase否则是 example块名若以父 slug 为前缀则裁剪出叶子 slug如Button — Leading IconButton→leading-icon否则叶子为default。独立的 showcase 标记无exampleFor会被拒绝测试断言blockRegistryIdentity(Hero Layout, null, true)抛requires exampleFor。registry.slug覆盖与registry.aliases文档可在其 frontmatter 中用registry.slug覆盖叶子 slug用registry.aliases保留旧相对路径。该模块用SLUG_PATTERN小写 kebab-case与RELATIVE_PATH_PATTERN严格校验拒绝大写、非法字段REGISTRY_IDENTITY_KEYS只允许slug/aliases以及别名与规范路径相同的配置别名会去重排序。改名场景下旧路径以别名形式继续解析到同一规范条目的字节IR4/IR5。路由锁与安装命令routes.lock.jsoninternal/shadcn-registry/routes.lock.json记录了全部已评审条目与别名任何改名若未同步更新锁文件即可能破坏既有安装命令。安装命令由shadcnInstallCommand生成并固定客户端版本npx shadcn4.19.0 add registry-origin/components/button.jsonresolveShadcnRegistryOrigin支持三档源选择显式NEXT_PUBLIC_ASTRYX_REGISTRY_ORIGIN环境变量最优先其次是 Vercel 预览部署 URL拼接到/shadcn最后回落到https://astryx.atmeta.com/shadcn。测试还断言SHADCN_CLI_VERSION必须与 apps/docsite/package.json 的devDependencies.shadcn一致——receipt 的 JS 变体与该客户端转换器同步安装命令必须固定被测试的客户端。可升级的复制组合receipt 契约与三路合并FR9 是整个兼容层最精巧的部分复制组合必须可升级但用户的编辑永远不能被覆盖。其实现横跨三个文件。receipt schema v2packages/cli/authoring/shadcn/receipt.mjs 定义 receipt 契约当前schemaVersion: 2兼容 v1。每个 receipt 是一个放在源文件同目录.astryx/item-name.json的严格 JSONitem稳定 name、path、aliases、kindshowcase/example/block/page 之一source{package: astryxdesign/cli, version: canary 或精确 semver}标识该组合来源于哪个 CLI 版本files每个文件含id如primary/types、相对目标、registry 目标、registry 路径、sha256与完整安装字节 contentv2 还增加variantsformat: javascript的精确 JS 字节与哈希。Schema 用 zod 严格校验.strict()要求 target 只指向一个相邻源文件、路径全部为正则小写路径、各文件 id/路径/目标唯一、SHA-256 为 64 位十六进制。为什么 receipt 必须存完整字节而非仅哈希DEC-6 明确否决了哈希-only receipt因为用户编辑文件后无法从哈希重建合并基线merge base也否决了升级时用 CLI 模板资产重建最新组合因为 StyleX 预编译条目必须使用 registry 中已编译的字节。精确复刻 shadcn 的 JS 转换packages/cli/authoring/shadcn/source-variants.mjs 用babel/parserrecast复刻 shadcn 4.19 在components.json配置tsx: false时的 JavaScript 转换shadcnJavaScriptTarget把.tsx→.jsx、.ts→.js。由于这是兼容边界注释明确「保持小而由真实 stock-client 安装测试覆盖而不是导入 shadcn 包内部私有 chunk」。shadcnJavaScriptSourcesEquivalent通过 AST 归一化识别「仅打印器差异」的 JS 等价性保护 receipt 免受兼容 formatter 漂移影响。测试会真实地以tsx: false跑 stock shadcn 安装断言写入的.jsx字节与 receipt variants 完全一致、且不含ReactNode等类型残留。astryx upgrade --registry的协调引擎packages/cli/api/upgrade/registry/registry.mjs 实现 FR9 的完整语义discoverRegistryReceipts递归扫描.astryx目录收集 receipt跳过node_modules、.next等。fetchLatestReceipt从 registry 源按稳定路由拉取最新条目严格校验条目必须包含恰好一个有效 Astryx receiptreceipt 的source.version必须匹配已安装的 Astryx 版本canary与 canary 发布版本互相兼容条目身份必须与 receipt 一致receipt 存放位置必须正确文件哈希必须匹配。对每个已安装文件先做字节比较原样未改→update直接写入新字节已是最新→current用户改过且旧版新版→user-modified保留用户改过且最新当前→receipt-only只刷新 receipt否则进入三路合并以「当前项目文件 / 已安装版本字节 / 最新版本字节」为三端用node-diff3执行 diff3 合并excludeFalseConflicts: true。合并有冲突时冲突内容写入独立的.astryx-conflictartifactatomicWrite绝不替换用户文件文件被删除或移动则标记missing且不重建目标是符号链接等异常情况标记invalid不动。applyPlan写入前会再次校验 receipt 与文件是否被并发修改写入失败时回滚全部变更并恢复旧 receipt。reconcileRegistryCompositions汇总current/update/merge/receipt-only/conflict/missing/invalid/failed各类计数并返回 dry-run 或 apply 摘要。升级测试端到端验证了这条链路先用旧版条目通过 stock shadcn 安装再启动本地 HTTP registry 服务提供新版条目执行reconcileRegistryCompositions({apply: true, path: src}, {registryOrigin, expectedVersion: 0.7.0})断言updated: 1, conflicts: 0且文件内容升级到新版、receipt 版本刷新。CLI 侧命令为astryx upgrade --registrydry-run与astryx upgrade --registry --apply应用registryUpgrade会先探测已安装的astryxdesign/core版本作为expectedVersion并强制要求。全量目录 CIFR10/IR4 的落地证据internal/shadcn-registry/verify-full-catalog.mjs 是必选 PR CI 的完整实现直译了 FR10 的每一项要求加载目录读取apps/docsite/public/shadcn/registry.json校验每个条目 name 安全小写 kebab、无重复、规范路由文件存在且与registry.json身份一致、每个别名路由文件与规范字节完全一致alias route ... drifted from canonical item、target 互不重叠、文件形状合法复制类条目必须「一个源 一个 receipt 仅预编译时一个声明」组件类必须仅一个 re-export 文件。干净消费者为 TStsx: true与 JStsx: false两种模式各创建一个临时消费者项目components.json采用style: novaAstryx 包依赖被替换为本地工作区包file:引用使新组件能在 npm 尚无对应版本时即证明其导出第三方依赖保持目录声明的版本。单进程安装全部条目把 970 个条目一次性传给固定 shadcn 客户端add paths --yes --overwrite --silent。DEC-7 明确否决「每条目一个客户端进程」重复安装数百次且不增加协议覆盖与「只校验代表性子集」源或目标缺陷可能只存在于某个组合。字节级校验逐一比对写入文件与 registry 字节JS 模式用转换后的期望字节校验依赖是否被 shadcn 安装进 manifest校验index.css是否包含两条 Astryx CSS 导入最后用 esbuild 编译全部写入的源文件。预编译声明类型检查对 14 个 StyleX 预编译条目生成一个 harness 导入全部 JSX 组合用独立 tsconfig 做 strict 类型检查。输出如Verified 970 items and N routes in TypeScript: X files, Y compiled sources; JavaScript: ...。这套 CI 同时是「970 条目 / 1,670 文件 / 970 源码入口」基线的唯一权威证明。此外单元测试 internal/shadcn-registry/generate-shadcn-registry.test.mjs 覆盖了身份派生、别名写入、canary 依赖、StyleX 预编译、receipt 相邻性、stock shadcn 安装 receipt 字节一致性、页面 workaround、嵌套依赖 URL 解析、逃逸相对导入拒绝与升级三路合并等关键路径。决策日志七条关键决策的取舍规范附带的决策日志是理解兼容层设计哲学的第一手资料DEC-1 — 把 shadcn 当作兼容协议而非 Astryx 的基础2026-09-02josephfarina生成标准 registry JSON 让既有 shadcn 用户无需更换工具即可安装 AstryxAstryx CLI 仍是主产品与更丰富知识/维护行为的来源。否决了自定义 Astryx registry 格式——它对第三方客户端无互操作性要求先采用 Astryx 才能被发现。DEC-2 — 复制组合不复制组件实现2026-09-02普通安装把astryxdesign/core或所属 Astryx 包保持为真实依赖组件条目只建公共 re-export展示/Block/页面复制可编辑的组合代码。否决了复制 Core 实现源码——它破坏包管控升级并跨越私有导入与未编译 StyleX 边界。DEC-3 — 在 canary docsite 之后分阶段发布2026-09-09端到端验证后合并兼容基础但生产 registry 与广泛公告在复制组合升级就绪前保持禁用。DEC-4 — 身份源自文档、URL 按条目类型组织2026-09-03发布前就把 registry 名字与路径当作公共 API身份派生自稳定的组件/hook 名、Block 的nameexampleFor、既有模板 slugdisplayName仅作编辑用路径族固定为components、hooks、showcases/component、examples/component、blocks、templates。文档可用registry.slug覆盖叶子、用registry.aliases保留旧相对路径所有名字与路径对照已评审的锁文件。DEC-5 — 使用/shadcn、精确发布版与 canary 预览2026-09-09https://astryx.atmeta.com/shadcn为规范生产根/r预留给未来的 Astryx 原生协议生产条目钉住精确发布的 Astryx 版本预览条目使用对应预览源与canary依赖。DEC-6 — 安装相邻 receipt 并从规范 registry 协调2026-09-10每个复制组合携带唯一 JSON receipt 于源码旁存储安装基字节与哈希稳定条目路由解析该发布版本的已编译源码。astryx upgrade --registry拒绝与已安装 Astryx 版本不匹配的条目然后更新未改动文件或执行真实三路合并不把可编辑的应用代码当作包自有实现冲突写入独立 artifact 绝不覆盖用户文件删除或移动的文件保持删除/移动。否决了哈希-only receipt无法在用户编辑后重建合并基线与升级时从原始 CLI 模板资产重建最新组合StyleX 预编译条目需要 registry 的编译字节。DEC-7 — 所有条目都过一个干净消费者2026-09-10必选 PR CI 先证明发布通道选择器为生产移除兼容输出再把每个规范预览条目交给固定 shadcn 客户端于一个干净消费者内安装消费者把 Astryx 包钉替换为当前本地包构建使新组件能在 npm 发布前证明其导出第三方依赖保留目录声明版本。CI 逐文件比对字节并编译全部源码。否决了每条目一个客户端进程与只校验代表性条目。开放问题规范目前保留了一个开放问题Open questionsOQ1 — 目录可见性human-design隐藏或未就绪的目录条目应保持可 URL 寻址还是完全省略这属于产品设计决策将影响/shadcn机器端点的暴露面。结语一份「边界即契约」的兼容层系统规范AST-026 的核心价值不在于新增了多少功能而在于它把「兼容」定义为一系列可校验的边界标准协议FR1与包边界FR2共同保证了「Astryx 不是 shadcn 的附庸也不是一坨被复制的源码」稳定身份与路由锁FR5/IR5让名字与路径成为发布即承诺的公共 APIreceipt 三路合并FR9让「复制出来的组合」依然可被版本协调全量目录 CIFR10/IR4则用「一个干净消费者装下全部 970 条并逐字节比对」这一朴素而残酷的检验把任何孤立条目的缺陷挡在发布之前。七条决策日志反复出现的主题只有一句话复制组合是正常的应用开发复制设计系统实现则是事故——这条边界正是 Astryx shadcn 兼容层设计得最严谨的地方。对希望在既有 shadcn 工作流中按需引入 Astryx 组件与模板的团队而言理解这份规范及其在 docs/specs/AST-026/spec.md 的权威表述是评估与使用该能力的第一步。【免费下载链接】astryxAn open source design system thats fully customizable and agent ready项目地址: https://gitcode.com/GitHub_Trending/as/astryx创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考