npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@cloudai-design/eslint-plugin

v0.1.2

Published

CloudAI UI 设计体系护栏 ESLint 插件(S 层确定性规则:禁硬编码颜色 / 禁串 Tailwind 版本 / 禁任意值圆角间距,token 名录随 Figma 生成)

Downloads

171

Readme

@cloudai-design/eslint-plugin

CloudAI UI 设计体系的 S 层「确定性」护栏 ESLint 插件。skill / DESIGN.md 负责「教 AI 怎么写」, 本插件负责「写错就红 + 给改法」,是设计规范里最强、可机器判定的一层约束。

规则

| 规则 | 抓什么 | | ------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | | @cloudai-design/no-hardcoded-color | 任意值颜色(bg-[#...]shadow-[..rgba(..)])、默认调色板刻度色(bg-red-500)、内联 style 颜色,以及引用了不存在的 var(--x) | | @cloudai-design/no-arbitrary-radius-spacing | 任意值圆角 / 间距 / 字号(rounded-[10px] / p-[13px] / text-[14px]),不拦布局类(w-[42px] 等) | | @cloudai-design/no-tailwind-version-mismatch | 与项目 Tailwind 大版本不符的语法(v3 项目禁 @theme / @import "tailwindcss";v4 项目禁 @tailwind base) | | @cloudai-design/classname-must-be-transformable | 类名字符串写在 prefix 转换改不到的位置(模块常量、Record 映射表、数组、模板串、JSX 外的 cn()) |

每条规则的「判真伪 / 怎么改」说明见 prompts/<rule>.md(与规则代码解耦)。

classname-must-be-transformable 只对配了 Tailwind prefix 的业务是硬需求,但它拦的写法在 任何项目里都更难维护,所以进 recommended-*。判据是启发式(单词字符串一律放过,避免打到 zod enum),精确判据是本仓库的 pnpm check:prefix-safe

用法(经典 .eslintrc

// .eslintrc.cjs
module.exports = {
  plugins: ['@cloudai-design'],
  // 项目用 Tailwind v3(本体系交付默认):
  extends: ['plugin:@cloudai-design/recommended-tailwind3'],
  rules: {
    // 报错文案要指名本品牌的 token / 圆角取值,就把 brand 告诉它:
    '@cloudai-design/no-hardcoded-color': ['error', { brand: 'aidbs' }],
    '@cloudai-design/no-arbitrary-radius-spacing': [
      'error',
      { brand: 'aidbs' },
    ],
  },
};

插件名 @cloudai-design/eslint-plugin 在 eslint 配置里简写为 @cloudai-design

没有 recommended,只有 recommended-tailwind3 / recommended-tailwind4:两者唯一的差别是 no-tailwind-version-mismatch 的方向。config 名把 tailwind 写全而不是 recommended-v3, 因为它出现在业务的 .eslintrc 里,-v3 会被读成「插件的第 3 个大版本」。

token 名录是生成物

data/<brand>.jsontools/emitters/lint-data.ts 从 token IR 发射(别手改):

{
  "cssVars": ["--accent", "--brand", "--brand-gradient", "…"], // 判定 var(--x) 是否为本体系变量
  "classKeys": ["accent", "brand", "…"], // 可写成工具类的键
  "radius": {
    "root": "0.625rem",
    "scale": { "lg": ["10px", "0.625rem"], "md": ["8px", "0.5rem"] },
  },
}

名录让规则能分辨两种长得很像的写法,不配名录的规则两边都会判错:

  • bg-[hsl(var(--brand))] 引用的是真 token,合法,不报。
  • bg-[hsl(var(--brnad))] 把变量名拼错了,浏览器里颜色直接失效,照样报。

改了 Figma 的 token,重跑 pnpm tokens:emit 名录就同步;规则代码不动。allow 选项保留, 但只服务「确无对应 token 的一次性颜色」,不再承担名录的职责。

不配 brand 时读 data/index.json(所有 brand 的并集)——宁可放宽到「任一 brand 有这个 token」, 也不在插件里猜业务用的是哪个品牌。brand 写错会当场报错并列出可选值,不会静默回落。

radius 的收益是报错能指名 token:aidbs 的 --radius = 0.625rem,于是 rounded-[10px] 的报错直接告诉你「这就是 rounded-lg」。间距 / 字号沿用 Tailwind 默认刻度、不是品牌 token, 所以无 data 可喂,报错只给方向。

已知缺口(诚实标注)

  • no-tailwind-version-mismatch 基于 ESLint,只能看到 JS/JSX/TS:CSS-in-JS 模板串与 className 里的信号能拦,但独立 .css 文件里的 @import "tailwindcss" / @theme {} 拦不到 ——那属于 CSS 维度,需 stylelint(或将来 eslint 9 flat config + @eslint/css)兜底。
  • 模板串的插值部分(`bg-${color}`)是运行时值,静态判定不了,本插件有意不猜。
  • classname-must-be-transformable 不查「属性里的第二个 cn()」这类细节(上游 transform 只取 第一个),也不验证类名真的是 utility;单词类名一律放过。这些缺口由 check:prefix-safe 的精确比对兜住。
  • v3 侧唯一足够确定的信号是 @tailwind base|components|utilities——@configtheme()、 JS 插件在 v4 里仍受支持,拿它们当版本信号会误报,故不拦。

测试

pnpm --filter @cloudai-design/eslint-plugin test

基于 eslint RuleTester,另有一组契约断言:config 名、config 里引用的规则是否存在、 tailwind 方向是否配对、brand 写错是否报错。这些错规则用例发现不了,但会让业务的 extends 直接失效。

与 react-doctor 的关系

本包只自建规则(标准 ESLint AST 规则),不自建扫描 / 评分引擎。未来 react-doctor 稳定后, 以「合并 eslint config」方式吸收同一份规则,迁移≈配置连线;prompt(独立 markdown)与度量 (从 eslint JSON 输出派生)均与引擎解耦,不会白干。

为什么是 JS 而不是 TS

本包由业务仓的 eslint 加载,Node 版本不可控,所以发布入口一律 JS、engines.node 保守到 >=18(同 @cloudai-design/cli)。规则逻辑是正则匹配与 context.report,没有可建模的领域类型, 上 TS 只换来一个构建步骤。

规则归属的一条取舍

bg-[oklch(...)]no-hardcoded-color,不归 no-tailwind-version-mismatch。oklch 是合法 CSS 颜色函数,v3 也能写,它是硬编码颜色而不是版本信号。挂在版本规则上会让 v4 项目失去 这层保护。