agentcss 0.25.2 → 0.25.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/01-tokens/tokens.css +1 -1
- package/API.md +13 -5
- package/CHANGELOG.md +145 -0
- package/CONTRIBUTING.md +5 -5
- package/README.zh-CN.md +3 -3
- package/ai/components.json +1 -1
- package/ai/tokens.json +100 -99
- package/ai/tokens.schema.json +96 -50
- package/dist/COSTS.md +7 -7
- package/docs/ACCESSIBILITY.md +1 -1
- package/docs/GUIDANCE.md +82 -0
- package/docs/LESSONS.md +182 -0
- package/index.html +1 -1
- package/llms-full.txt +1 -1
- package/package.json +4 -2
package/ai/tokens.schema.json
CHANGED
|
@@ -1,58 +1,104 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
"
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"$id": "https://frontend-lib.dev/ai/tokens.schema.json",
|
|
4
|
+
"title": "frontend-lib 令牌契约",
|
|
5
|
+
"$comment": [
|
|
6
|
+
"描述 ai/tokens.json 的形状,由 05-audit/gen-ai-contract.py 生成。",
|
|
7
|
+
"",
|
|
8
|
+
"🔴 为什么用 $value / $type 这种写法:",
|
|
9
|
+
" 这是 W3C Design Tokens 草案的形状,Open Props 与 Primer 都在用。",
|
|
10
|
+
" 好处是 Figma / Style Dictionary / 各类构建工具能**直接消费**,",
|
|
11
|
+
" 不需要我们再写一层的适配。对标的意义就在这里 —— 不是更好看,是更少重复。",
|
|
12
|
+
"",
|
|
13
|
+
"🔴 真值方向:tokens.css 是真值,本文件是导出物,",
|
|
14
|
+
" 一致性由 gen-ai-contract.py --check 保证(单向,不双向同步)。"
|
|
15
|
+
],
|
|
16
|
+
"type": "object",
|
|
17
|
+
"required": [
|
|
18
|
+
"schemaVersion",
|
|
19
|
+
"source",
|
|
20
|
+
"sets"
|
|
21
|
+
],
|
|
22
|
+
"properties": {
|
|
23
|
+
"schemaVersion": {
|
|
24
|
+
"type": "string"
|
|
25
|
+
},
|
|
26
|
+
"source": {
|
|
27
|
+
"type": "string"
|
|
28
|
+
},
|
|
29
|
+
"sets": {
|
|
30
|
+
"type": "object",
|
|
31
|
+
"properties": {
|
|
32
|
+
"light": {
|
|
33
|
+
"$ref": "#/definitions/tokenSet"
|
|
28
34
|
},
|
|
29
|
-
"
|
|
30
|
-
|
|
31
|
-
"properties": {
|
|
32
|
-
"lightCount": { "type": "number" },
|
|
33
|
-
"darkCount": { "type": "number" },
|
|
34
|
-
"onlyInDark": { "type": "array", "items": { "type": "string" } },
|
|
35
|
-
"onlyInLight": { "type": "array", "items": { "type": "string" } }
|
|
36
|
-
}
|
|
35
|
+
"dark": {
|
|
36
|
+
"$ref": "#/definitions/tokenSet"
|
|
37
37
|
}
|
|
38
|
+
},
|
|
39
|
+
"required": [
|
|
40
|
+
"light",
|
|
41
|
+
"dark"
|
|
42
|
+
]
|
|
38
43
|
},
|
|
39
|
-
"
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
44
|
+
"coverage": {
|
|
45
|
+
"type": "object",
|
|
46
|
+
"properties": {
|
|
47
|
+
"lightCount": {
|
|
48
|
+
"type": "number"
|
|
49
|
+
},
|
|
50
|
+
"darkCount": {
|
|
51
|
+
"type": "number"
|
|
52
|
+
},
|
|
53
|
+
"onlyInDark": {
|
|
54
|
+
"type": "array",
|
|
55
|
+
"items": {
|
|
56
|
+
"type": "string"
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
"onlyInLight": {
|
|
60
|
+
"type": "array",
|
|
61
|
+
"items": {
|
|
62
|
+
"type": "string"
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
"definitions": {
|
|
69
|
+
"tokenSet": {
|
|
70
|
+
"type": "object",
|
|
71
|
+
"additionalProperties": {
|
|
72
|
+
"$ref": "#/definitions/token"
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
"token": {
|
|
76
|
+
"type": "object",
|
|
77
|
+
"required": [
|
|
78
|
+
"$value"
|
|
79
|
+
],
|
|
80
|
+
"properties": {
|
|
81
|
+
"$value": {
|
|
82
|
+
"type": "string"
|
|
83
|
+
},
|
|
84
|
+
"$type": {
|
|
85
|
+
"type": "string",
|
|
86
|
+
"enum": [
|
|
87
|
+
"color",
|
|
88
|
+
"dimension",
|
|
89
|
+
"number",
|
|
90
|
+
"duration",
|
|
91
|
+
"cubicBezier",
|
|
92
|
+
"alias",
|
|
93
|
+
"other"
|
|
94
|
+
]
|
|
43
95
|
},
|
|
44
|
-
"
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
"$value": { "type": "string" },
|
|
49
|
-
"$type": {
|
|
50
|
-
"type": "string",
|
|
51
|
-
"enum": ["color", "dimension", "number", "duration",
|
|
52
|
-
"cubicBezier", "alias", "other"]
|
|
53
|
-
},
|
|
54
|
-
"$description": { "type": "string" }
|
|
55
|
-
}
|
|
96
|
+
"$description": {
|
|
97
|
+
"type": "string",
|
|
98
|
+
"maxLength": 400,
|
|
99
|
+
"$comment": "必须描述**本令牌**,且必须来自它与相邻注释(前导或同行尾注释)。归属由 05-audit/ai-token-desc-gate.py 判定:分隔线 / 空串 / 半句话 / 超过 400 字 / 错位一位 都会红。"
|
|
56
100
|
}
|
|
101
|
+
}
|
|
57
102
|
}
|
|
103
|
+
}
|
|
58
104
|
}
|
package/dist/COSTS.md
CHANGED
|
@@ -18,13 +18,13 @@
|
|
|
18
18
|
|
|
19
19
|
| 档 | 组件 | tokens(必付) | CSS | JS | **合计** | 源码版合计 | 差 |
|
|
20
20
|
|---|---|---:|---:|---:|---:|---:|---:|
|
|
21
|
-
| primitive | `badge` | 2.9 KB | 0.5 KB | — | **3.4 KB** | 24.
|
|
21
|
+
| primitive | `badge` | 2.9 KB | 0.5 KB | — | **3.4 KB** | 24.7 KB | −21.2 KB |
|
|
22
22
|
| primitive | `button` | 2.9 KB | 1.0 KB | — | **3.9 KB** | 28.3 KB | −24.4 KB |
|
|
23
23
|
| primitive | `card` | 2.9 KB | 0.9 KB | — | **3.9 KB** | 26.0 KB | −22.1 KB |
|
|
24
24
|
| primitive | `choice` | 2.9 KB | 1.1 KB | — | **4.1 KB** | 28.1 KB | −24.0 KB |
|
|
25
|
-
| primitive | `combobox` | 2.9 KB | 1.0 KB | 5.4 KB | **9.3 KB** | 31.4 KB | −22.
|
|
25
|
+
| primitive | `combobox` | 2.9 KB | 1.0 KB | 5.4 KB | **9.3 KB** | 31.4 KB | −22.2 KB |
|
|
26
26
|
| primitive | `date-range` | 2.9 KB | 0.8 KB | 2.5 KB | **6.3 KB** | 28.4 KB | −22.1 KB |
|
|
27
|
-
| primitive | `delta` | 2.9 KB | 0.3 KB | — | **3.2 KB** | 24.
|
|
27
|
+
| primitive | `delta` | 2.9 KB | 0.3 KB | — | **3.2 KB** | 24.7 KB | −21.5 KB |
|
|
28
28
|
| primitive | `input` | 2.9 KB | 1.0 KB | — | **4.0 KB** | 25.8 KB | −21.9 KB |
|
|
29
29
|
| primitive | `metric` | 2.9 KB | 0.5 KB | — | **3.4 KB** | 25.1 KB | −21.7 KB |
|
|
30
30
|
| primitive | `popover` | 2.9 KB | 0.8 KB | 2.2 KB | **5.9 KB** | 29.2 KB | −23.3 KB |
|
|
@@ -32,19 +32,19 @@
|
|
|
32
32
|
| primitive | `select` | 2.9 KB | 0.8 KB | 4.1 KB | **7.9 KB** | 32.9 KB | −24.9 KB |
|
|
33
33
|
| primitive | `separator` | 2.9 KB | 0.2 KB | — | **3.2 KB** | 23.2 KB | −20.0 KB |
|
|
34
34
|
| primitive | `skeleton` | 2.9 KB | 0.5 KB | — | **3.4 KB** | 23.8 KB | −20.4 KB |
|
|
35
|
-
| primitive | `switch` | 2.9 KB | 0.8 KB | — | **3.7 KB** | 30.
|
|
36
|
-
| primitive | `timeline` | 2.9 KB | 0.5 KB | — | **3.4 KB** | 25.
|
|
35
|
+
| primitive | `switch` | 2.9 KB | 0.8 KB | — | **3.7 KB** | 30.3 KB | −26.5 KB |
|
|
36
|
+
| primitive | `timeline` | 2.9 KB | 0.5 KB | — | **3.4 KB** | 25.2 KB | −21.7 KB |
|
|
37
37
|
| primitive | `upload` | 2.9 KB | 1.4 KB | 4.2 KB | **8.5 KB** | 39.3 KB | −30.8 KB |
|
|
38
38
|
| pattern | `accordion` | 2.9 KB | 1.3 KB | 1.8 KB | **6.0 KB** | 36.4 KB | −30.4 KB |
|
|
39
39
|
| pattern | `content` | 2.9 KB | 1.0 KB | — | **4.0 KB** | 26.5 KB | −22.5 KB |
|
|
40
40
|
| pattern | `drawer` | 2.9 KB | 0.8 KB | 2.6 KB | **6.3 KB** | 30.1 KB | −23.8 KB |
|
|
41
|
-
| pattern | `dropdown` | 2.9 KB | 0.8 KB | 3.5 KB | **7.2 KB** | 31.
|
|
41
|
+
| pattern | `dropdown` | 2.9 KB | 0.8 KB | 3.5 KB | **7.2 KB** | 31.6 KB | −24.4 KB |
|
|
42
42
|
| pattern | `form-validation` | 2.9 KB | 0.8 KB | — | **3.7 KB** | 26.8 KB | −23.1 KB |
|
|
43
43
|
| pattern | `list` | 2.9 KB | 0.6 KB | — | **3.5 KB** | 24.3 KB | −20.8 KB |
|
|
44
44
|
| pattern | `nav` | 2.9 KB | 1.2 KB | 2.6 KB | **6.8 KB** | 33.0 KB | −26.2 KB |
|
|
45
45
|
| pattern | `overlay` | 2.9 KB | 1.2 KB | 3.6 KB | **7.7 KB** | 38.5 KB | −30.8 KB |
|
|
46
46
|
| pattern | `pagination` | 2.9 KB | 0.8 KB | 2.6 KB | **6.3 KB** | 32.4 KB | −26.1 KB |
|
|
47
|
-
| pattern | `reveal` | 2.9 KB | 0.3 KB | 1.2 KB | **4.4 KB** | 26.
|
|
47
|
+
| pattern | `reveal` | 2.9 KB | 0.3 KB | 1.2 KB | **4.4 KB** | 26.5 KB | −22.0 KB |
|
|
48
48
|
| pattern | `states` | 2.9 KB | 0.9 KB | — | **3.8 KB** | 26.3 KB | −22.5 KB |
|
|
49
49
|
| pattern | `tabs` | 2.9 KB | 0.7 KB | 2.0 KB | **5.6 KB** | 29.1 KB | −23.5 KB |
|
|
50
50
|
| pattern | `tooltip` | 2.9 KB | 0.5 KB | 1.9 KB | **5.3 KB** | 28.5 KB | −23.2 KB |
|
package/docs/ACCESSIBILITY.md
CHANGED
package/docs/GUIDANCE.md
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# GUIDANCE · 建议层
|
|
2
|
+
|
|
3
|
+
> **这一层的地位**:`docs/INVARIANT.md` 写物理事实,`ai/*.json` 写机器契约,
|
|
4
|
+
> 这一份写**工作方式与品味**。它随时可以整份作废 —— 判据是
|
|
5
|
+
> INVARIANT 里那句:「如果明天出现一个无限强的模型,这句话还成立吗?」
|
|
6
|
+
> 这里的话**不成立**,所以它们必须待在这一层,不许往上渗。
|
|
7
|
+
|
|
8
|
+
**为什么要有这一层**:把建议混进事实层,会让事实层变成"随时会变的规矩";
|
|
9
|
+
把建议删干净,又会让每次都重新踩同一批坑。分层的意义是 ——
|
|
10
|
+
事实层永不变,契约层可协商,建议层可作废。
|
|
11
|
+
|
|
12
|
+
> ⚠️ **公开面的边界**:这一份只收「工作方式与品味」。
|
|
13
|
+
> 发布凭证、账号二次因子、内部排期与到期日**不进这里**,也不进任何公开文档 ——
|
|
14
|
+
> 0.11.4 曾因此把四份文档(含本文件)整份移进内部目录。
|
|
15
|
+
> 现在的做法是:**只公开可以公开的那一部分**,而不是让三层体系缺一层。
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## 一、动手之前
|
|
20
|
+
|
|
21
|
+
| 建议 | 为什么 |
|
|
22
|
+
|---|---|
|
|
23
|
+
| 先跑 `python 05-audit/impact-report.py` 看这次改动会波及哪些门禁 | 事后被 20 道门禁同时判红,比事前花 10 秒看影响面贵得多 |
|
|
24
|
+
| 改 CSS 前先确认它是不是"生成物"(`dist/` 下的一律是) | 改产物会被 `build-dist --check` 判新鲜度失败,白改 |
|
|
25
|
+
| 新增组件前先搜一遍现有组件能不能改 | 44 个组件的维护成本远高于 43 个 |
|
|
26
|
+
| 动 `01-tokens/` 之前,先读 `docs/BUDGET.md` 的储备与棘轮 | 令牌层的改动会同时推动体积、对比度、暗色三组判据 |
|
|
27
|
+
|
|
28
|
+
## 二、写代码
|
|
29
|
+
|
|
30
|
+
| 建议 | 为什么 |
|
|
31
|
+
|---|---|
|
|
32
|
+
| 不要写魔法数字:能进令牌的进令牌,进不去的写一行注释说清来历 | 令牌化的价值在于"改一处、全场一致";散落的数字会把这点吃掉 |
|
|
33
|
+
| 组件之间不要 `@import` 互相依赖 | 一旦互相依赖,单独引一个组件就不可能了,包体也会失控 |
|
|
34
|
+
| 状态一律走 `data-state`,不要新造状态类 | 类名会被使用者复制粘贴,属性化的状态更容易被脚本和测试读到 |
|
|
35
|
+
| 只用逻辑属性(`inline-start` / `block-end`),不写 `left` / `right` | 物理属性是 RTL 的唯一来源;`rtl-render` 门禁会拦住,但改起来比重写便宜得多 |
|
|
36
|
+
| 注释写"为什么",不写"是什么" | 本库注释占比约七成,其中绝大部分是"这个取舍放弃了什么" |
|
|
37
|
+
| 加一条门禁时,同时加一条**反向控制** | 见下节 |
|
|
38
|
+
|
|
39
|
+
## 三、关于门禁
|
|
40
|
+
|
|
41
|
+
| 建议 | 为什么 |
|
|
42
|
+
|---|---|
|
|
43
|
+
| 新判据必须配一条"注入反例 ⇒ 必须变红"的自检 | 没有反向控制的判据无法证明自己有牙;仓库里 85 条自检就是为此存在 |
|
|
44
|
+
| 判据红的时候,先怀疑**判据自己**,再怀疑代码 | 历史上多次"红得很有道理"其实是参照物取错、作用域取宽、单位取混 |
|
|
45
|
+
| 每一条判据都要能回答"它圈中的对象是否都能按同一标准评价" | 圈不干净就会误报;误报比漏报贵,因为它会让人放弃信任门禁 |
|
|
46
|
+
| 别用"文本匹配"证明"渲染了" | 类名可以由运行时拼串产生,grep 不到不等于没渲染 |
|
|
47
|
+
| 度量型判据必须写清"两个数各自是什么" | 拿列容器当行长、拿字节当体积,都会让判据永远给出同一个结论 |
|
|
48
|
+
|
|
49
|
+
## 四、AI 协作
|
|
50
|
+
|
|
51
|
+
| 建议 | 为什么 |
|
|
52
|
+
|---|---|
|
|
53
|
+
| 让 AI 先读 `llms.txt`,再按需读 `ai/components.json` | 全量读 352 KB 的 CHANGELOG 是浪费上下文 |
|
|
54
|
+
| 用 `node ai/cli.js` 校验它产出的契约,而不是相信它说"改好了" | `check` / `diff` / `patch` 三个子命令就是给这件事用的 |
|
|
55
|
+
| AI 报告的"已完成"要能被一条命令复核 | 不能复核的完成,等于没完成 |
|
|
56
|
+
| 不要让它替你做"要不要发版"这种不可撤回的决定 | 这条是本仓库的惯例,不是技术约束 |
|
|
57
|
+
|
|
58
|
+
## 五、提交与发布
|
|
59
|
+
|
|
60
|
+
| 建议 | 为什么 |
|
|
61
|
+
|---|---|
|
|
62
|
+
| 提交前跑 `npm run gate:fast`,收尾跑 `npm run gate` | `fast` 是纯静态层,秒级;`full` 才是那 9 分钟 |
|
|
63
|
+
| 打 tag 之前,先确认**tag 将要指向的那棵树**能过发布门禁 | 本地工作区通过 ≠ tag 快照通过;两者差一个"未提交的基线"就够红一轮 |
|
|
64
|
+
| 顺序是:先让 CI 绿 → 再打 tag → 再推 tag | 反过来等于拿发版当试验 |
|
|
65
|
+
| 发版失败先查 npm 是否已吃进版本,再决定重试还是回滚 | 有些失败只到 Release 那一步,npm 上其实已经有包了 |
|
|
66
|
+
| 移动 tag 之后要重新核对 provenance 里的 `gitCommit` | tag 是发布物与提交之间唯一的锚点,移了就得重新验 |
|
|
67
|
+
|
|
68
|
+
## 六、什么不该进这一层
|
|
69
|
+
|
|
70
|
+
- **能机器判定的 → 进契约**(`ai/*.json`),不要写成建议;
|
|
71
|
+
- **物理机制的 → 进 `INVARIANT.md`**,不要写成建议;
|
|
72
|
+
- **随版本变的数字 → 进 `docs/FACTS.md` 或 `ai/components.json`**,不要手抄进文档。
|
|
73
|
+
|
|
74
|
+
三层的边界一旦松动,最先坏掉的不是文档,而是**门禁判据的可信度**。
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## 附:这一层为什么可以被整份删掉
|
|
79
|
+
|
|
80
|
+
以上每一条都是"在某个能力水平下、某种协作方式里"的经验。
|
|
81
|
+
换成更强的模型、更成熟的团队、更严格的 CI,其中相当一部分会变成多余的动作。
|
|
82
|
+
把它们写在这一层,就是为了**将来能干净地删掉它们**,而不必动到事实层和契约层。
|
package/docs/LESSONS.md
ADDED
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
# LESSONS · 门禁与工程的可复用教训
|
|
2
|
+
|
|
3
|
+
> 这份文件从维护者的内部错误登记里挑出**可以公开、可以复用**的部分。
|
|
4
|
+
> 每条都是真实红过的门禁、或真实做错过的事,不是假想。
|
|
5
|
+
>
|
|
6
|
+
> 为什么不直接公开完整登记:完整版含内部路径、工单代号与排期,
|
|
7
|
+
> 那部分不出门。这里保留的是**规则本身** —— 换一个项目也用得上。
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## 一、判据的错法(比代码错更难查)
|
|
12
|
+
|
|
13
|
+
### 1. 作用域取宽了:把"不是它的对象"也抓进来审
|
|
14
|
+
|
|
15
|
+
**症状** 给表单加了一个"校验中…"的提示,可访问性判据立刻红:
|
|
16
|
+
「错误文案太含糊:正在检查是否可用…」。
|
|
17
|
+
|
|
18
|
+
**根因** 判据本意是"错误文案要说人话",取数却是「所有被 `aria-describedby`
|
|
19
|
+
关联的文本」—— 帮助文字、加载提示全被当成错误文案审。
|
|
20
|
+
|
|
21
|
+
**规则**
|
|
22
|
+
```
|
|
23
|
+
写判据前先问:这个选择器圈中的对象,是不是都能按同一标准评价。
|
|
24
|
+
圈不干净就缩范围(只取 .field__error / role=alert / aria-invalid 指向的),
|
|
25
|
+
不要用"所有 describedby"这种顺手的写法。
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### 2. 阈值从数据里反推:判的是"短",不是"含糊"
|
|
29
|
+
|
|
30
|
+
**症状** 同一条判据里还有一条更隐蔽的:用「长度 ≤ 最长含糊词 + 2」判含糊。
|
|
31
|
+
最长词是 `invalid`(7)⇒ 阈值 9 ⇒ 凡是 ≤9 字的文案一律判含糊,
|
|
32
|
+
而 20 个字的废话照样过。
|
|
33
|
+
|
|
34
|
+
**根因** 把长度当成了"含糊"的代理指标,而阈值又是从词表长度推出来的,
|
|
35
|
+
两个不相干的量被乘在一起。
|
|
36
|
+
|
|
37
|
+
**规则**
|
|
38
|
+
```
|
|
39
|
+
代理指标必须与被判对象有因果关系。判"含糊"就判构成(整句只由含糊词组成),
|
|
40
|
+
不要判长度。任何阈值型判据都要配一条反向控制:喂一个真含糊的样本,必须转红。
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### 3. 参照物取错了一层:拿容器当行宽
|
|
44
|
+
|
|
45
|
+
**症状** 判"宽通道是否真的越过了正文行长",量的是宽块与**列容器**的宽度,
|
|
46
|
+
得到 420 vs 544,判"没打开"—— 而实际上是打开的。
|
|
47
|
+
|
|
48
|
+
**根因** 行长只施加在内容块上,列容器是满宽的。两个数不是同一种东西。
|
|
49
|
+
|
|
50
|
+
**规则**
|
|
51
|
+
```
|
|
52
|
+
差值型判据先写清"两个数各自是什么",参照物必须与被判对象同一层
|
|
53
|
+
(文本块 vs 文本块,容器 vs 容器)。拿不准就用探针:
|
|
54
|
+
同一元素"加类前 / 加类后"各量一次,差值归零才是真的没生效。
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### 4. 指标名与定义不一致:「未渲染」其实是「文本没被提到」
|
|
58
|
+
|
|
59
|
+
**症状** 覆盖率门禁把 41 个类记成"未渲染",逐个去看,其中 10 个每次交互都在渲染。
|
|
60
|
+
|
|
61
|
+
**根因** 判据是文本匹配,而类名可以由 JS 拼串产生(`'tooltip--' + pos`),
|
|
62
|
+
源码里没有完整字面量 ⇒ 渲染了也搜不到。
|
|
63
|
+
|
|
64
|
+
**规则**
|
|
65
|
+
```
|
|
66
|
+
指标名必须能被它的实现完整解释;做不到就换名字("未被文本引用"而不是"未渲染")。
|
|
67
|
+
类名、事件名、storage key 这类字符串契约一律写完整字面量,不拼前缀 ——
|
|
68
|
+
拼串的代价不是多打几个字,是所有静态检查都看不见它。
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### 5. 零文件即通过:判据在没有对象时静默变绿
|
|
72
|
+
|
|
73
|
+
**症状** 某道扫描类门禁,路径写错导致一个文件都没扫到,结论是 PASS。
|
|
74
|
+
|
|
75
|
+
**规则**
|
|
76
|
+
```
|
|
77
|
+
凡是"扫描 / 遍历 / 统计"型判据,必须先断言"扫到了东西",
|
|
78
|
+
再断言"扫到的东西都合格"。零对象一律判失败,不判通过。
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## 二、删除与清理
|
|
84
|
+
|
|
85
|
+
### 6. 「清理」不等于「释放空间」
|
|
86
|
+
|
|
87
|
+
**症状** 某台机器上每次跑完整门禁,回收站就多 2.3 GB;8 轮攒了 16.86 GB。
|
|
88
|
+
门禁一直是全绿的。
|
|
89
|
+
|
|
90
|
+
**根因** 该环境的删除被改写成"移进回收站"(bash 的 `rm` 是个函数、
|
|
91
|
+
Python 的 `os.unlink` 被替换)。而回收站与仓库**同一块盘** ⇒
|
|
92
|
+
"清理"只是换了目录继续占着,一个字节都没释放。
|
|
93
|
+
|
|
94
|
+
**规则**
|
|
95
|
+
```
|
|
96
|
+
① 脚本清理自己创建的临时大目录时,确认删除动作真的删了,
|
|
97
|
+
而不是被平台接管(可以看回收站大小、看卷空闲空间)。
|
|
98
|
+
② 「清理」必须度量:跑前跑后各量一次,差值才是证据。
|
|
99
|
+
命令返回 0 只证明调用成功。
|
|
100
|
+
③ 用户说"我习惯了"不是验收通过,是问题被默许的信号。
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### 7. 临时目录的位置会改变测试的语义
|
|
104
|
+
|
|
105
|
+
**症状** 为了省事,把 `TEMP` 指到仓库内的 `.git/tmp`,结果三道
|
|
106
|
+
"模拟无 git 环境"的反向控制全红 —— 它们期望在空目录里只看到一个文件,
|
|
107
|
+
却看到了整个仓库的 966 个文件。
|
|
108
|
+
|
|
109
|
+
**根因** 临时目录在 `.git/` 内部,git 向上就能找到仓库,"这里没有仓库"的前提失效。
|
|
110
|
+
|
|
111
|
+
**规则**
|
|
112
|
+
```
|
|
113
|
+
临时目录的边界必须与仓库边界互斥。改全局环境变量(TEMP/TMPDIR/PATH)之前,
|
|
114
|
+
先枚举谁会读它 —— 测试代码最常拿这类变量当"干净空间"的锚点。
|
|
115
|
+
修一个问题,用最小作用域;不要顺手改跨层的锚点。
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### 8. 删目录前,先列过它
|
|
119
|
+
|
|
120
|
+
**症状** 一个临时目录被建到了盘符根下(路径格式错误导致的),发现后直接删了整个目录。
|
|
121
|
+
事后无法证明它原本是空的。
|
|
122
|
+
|
|
123
|
+
**规则**
|
|
124
|
+
```
|
|
125
|
+
`rm -rf <dir>` 的作用域是整棵子树,而"我知道里面有什么"不等于"我列出过里面有什么"。
|
|
126
|
+
删除前先 ls 目标**本身**,并核对"这一层应该只有我刚造的那一个东西"。
|
|
127
|
+
拿不出这句话,就不删。
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## 三、发布与版本
|
|
133
|
+
|
|
134
|
+
### 9. tag 打在"代码对了"的提交上,但发布门禁看的是 tag 快照
|
|
135
|
+
|
|
136
|
+
**症状** 功能提交打完 tag 就推,半小时后补的那批视觉基线没跟着走,
|
|
137
|
+
发布工作流当场红(页面尺寸变了)。
|
|
138
|
+
|
|
139
|
+
**根因** 本地的门禁跑的是**工作区**(含未提交的基线),CI 跑的是 **tag 指向的那棵树**。
|
|
140
|
+
两者差一个未提交的文件就够红一轮。
|
|
141
|
+
|
|
142
|
+
**规则**
|
|
143
|
+
```
|
|
144
|
+
打 tag 前问的是「tag 将要指向的那棵树能过发布门禁吗」,
|
|
145
|
+
而不是「我刚跑过的门禁过了吗」。
|
|
146
|
+
顺序:先让主干 CI 绿 → 再打 tag → 再推 tag。
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### 10. 对外文档里的数字,单位必须同量纲
|
|
150
|
+
|
|
151
|
+
**症状** 更新日志写「16 页有变化(浅色 16 / 暗色 16 / RTL 8)」——
|
|
152
|
+
三个数各自都对,但前面说"页"、括号里列"张",40 张图对应 16 个页面,
|
|
153
|
+
读者按字面算不出 16。
|
|
154
|
+
|
|
155
|
+
**规则**
|
|
156
|
+
```
|
|
157
|
+
一句话里出现两个以上的数,先确认它们同一个单位;不同单位就分开写。
|
|
158
|
+
对外数字必须能被一条命令复算,复算命令记在提交说明里。
|
|
159
|
+
已发布的文档不做"偷偷改"—— 改历史条目会让仓库领先于发布物。
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## 四、这套文档的分层为什么重要
|
|
165
|
+
|
|
166
|
+
上面十条里,前五条属于**判据的错法**,第六到八条属于**运行时副作用**,
|
|
167
|
+
第九、十条属于**发布语义**。它们有一个共同点:
|
|
168
|
+
|
|
169
|
+
> **都是门禁自己看不见的错。**
|
|
170
|
+
|
|
171
|
+
代码写错,门禁会红;判据写错、清理没释放空间、tag 指错树 ——
|
|
172
|
+
这些是"尺子本身的问题",而尺子不会量自己。
|
|
173
|
+
|
|
174
|
+
所以本库的做法是:
|
|
175
|
+
|
|
176
|
+
- 每条新判据都配一条**反向控制**(注入反例 ⇒ 必须变红),
|
|
177
|
+
证明它有牙,而不是证明它存在;
|
|
178
|
+
- 定期做**元检查**:门禁的参照物、作用域、量纲、零对象行为;
|
|
179
|
+
- 把每一次"红得没有道理"和"绿得没有道理"都登记下来,变成常驻判据。
|
|
180
|
+
|
|
181
|
+
这也是 `docs/GUIDANCE.md` 里那条建议的出处:
|
|
182
|
+
**判据红的时候,先怀疑判据自己,再怀疑代码。**
|
package/index.html
CHANGED
package/llms-full.txt
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# agentcss — full reference (one file)
|
|
2
2
|
|
|
3
|
-
> Generated from `ai/components.json` + `ai/pitfalls*.json` + `ai/behaviors.json` at version **0.25.
|
|
3
|
+
> Generated from `ai/components.json` + `ai/pitfalls*.json` + `ai/behaviors.json` at version **0.25.3**.
|
|
4
4
|
> Do not edit by hand: run `python 05-audit/gen-llms.py` (freshness is gated).
|
|
5
5
|
> Short version: `llms.txt`. Machine contract: `ai/*.json`.
|
|
6
6
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agentcss",
|
|
3
|
-
"version": "0.25.
|
|
3
|
+
"version": "0.25.3",
|
|
4
4
|
"description": "移动 Web 组件库:CSS + 可选行为脚本,零第三方运行时依赖。样式用 bundler 引入,交互行为用 script 标签引入。",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"css",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"exports": {
|
|
21
21
|
".": {
|
|
22
22
|
"types": "./types/index.d.ts",
|
|
23
|
-
"default": "./index.
|
|
23
|
+
"default": "./esm/index.mjs"
|
|
24
24
|
},
|
|
25
25
|
"./tokens.css": "./dist/01-tokens/tokens.css",
|
|
26
26
|
"./typography.css": "./dist/01-tokens/typography.css",
|
|
@@ -29,7 +29,9 @@
|
|
|
29
29
|
"types": "./types/index.d.ts",
|
|
30
30
|
"default": "./esm/index.mjs"
|
|
31
31
|
},
|
|
32
|
+
"./esm/*.mjs": "./esm/*.mjs",
|
|
32
33
|
"./esm/*": "./esm/*.mjs",
|
|
34
|
+
"./ai/*": "./ai/*",
|
|
33
35
|
"./primitives/*": "./dist/02-primitives/*",
|
|
34
36
|
"./patterns/*": "./dist/03-patterns/*",
|
|
35
37
|
"./recipes/*": "./dist/04-recipes/*",
|