agentcss 0.25.2 → 0.25.4
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 +199 -0
- package/CONTRIBUTING.md +5 -5
- package/README.zh-CN.md +3 -3
- package/ai/cli.js +5 -1
- 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/types/index.d.ts +126 -2
package/01-tokens/tokens.css
CHANGED
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
|
|
26
26
|
ℹ️ 边界(别夸大它的能力):这是"取值层",**不是**与语义解耦的色阶标尺
|
|
27
27
|
(gray-50 / gray-100 那种)。真正的色阶标尺需要先做一次颜色聚类与命名
|
|
28
|
-
|
|
28
|
+
决策,是独立的后续工程(内部排期不在公开面维护,别在这里找编号)。
|
|
29
29
|
本层解决的是"换肤只改一处 + 暗色不可能漏"这两件事。
|
|
30
30
|
---------------------------------------------------------------- */
|
|
31
31
|
--raw-paper: #f6f7f8;
|
package/API.md
CHANGED
|
@@ -29,23 +29,31 @@
|
|
|
29
29
|
除了 `<script src>`,16 个交互组件的脚本还有一个 ESM 入口:
|
|
30
30
|
|
|
31
31
|
```js
|
|
32
|
-
//
|
|
32
|
+
// 只要一个(推荐:只引入这一个脚本,体积最小)
|
|
33
33
|
import { Accordion } from 'agentcss/esm/accordion.mjs';
|
|
34
34
|
|
|
35
|
-
//
|
|
35
|
+
// 或者一次拿全 —— ⚠️ 不会摇树,17 个行为脚本全部进产物
|
|
36
36
|
import { Accordion, Tabs, Select } from 'agentcss/esm';
|
|
37
37
|
```
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
四条容易踩的:
|
|
40
40
|
|
|
41
41
|
1. **入口是包装,不是第二份实现**。`esm/*.mjs` 只做
|
|
42
42
|
「导入副作用 + 把全局上那个对象 re-export」,所以
|
|
43
43
|
`Accordion === window.Accordion` 恒成立(门禁 `behavior-api` 断言这一点)。
|
|
44
44
|
它由 `05-audit/gen-esm.py` 生成,改源码后要重新生成,`esm-gen` 门禁会拦住漂移。
|
|
45
|
-
2.
|
|
45
|
+
2. **聚合入口不会摇树**(0.25.3 更正)。`esm/*.mjs` 的形式是
|
|
46
|
+
「先 `import` 目标脚本(副作用:把对象挂到全局),再把它 re-export」——
|
|
47
|
+
模块体本身就有副作用,打包器无法判断哪个导出没被用到,只能整包收下。
|
|
48
|
+
实测(esbuild):`import { Select } from 'agentcss/esm'` 产物 **190 KB**,
|
|
49
|
+
而 `import { Select } from 'agentcss/esm/select'` 只有 **20.8 KB**(约 9 倍)。
|
|
50
|
+
`package.json` 的 `sideEffects` 把 `**/*.js` / `**/*.mjs` 标成有副作用,
|
|
51
|
+
**这是按事实写的、是对的** —— 错的是 0.25.2 之前本文档那句"会按需摇树"。
|
|
52
|
+
⇒ 要体积就逐个 `import 'agentcss/esm/<组件>'`。
|
|
53
|
+
3. **无 DOM 环境可以直接 import**(SSR 安全)。但自动初始化会被跳过 ——
|
|
46
54
|
服务端没有 DOM 可扫,到浏览器里再调 `init()`/构造函数。16 个脚本
|
|
47
55
|
在 Node 里 `require` 全部成功(门禁的判据 A)。
|
|
48
|
-
|
|
56
|
+
4. **重复初始化是安全的**。`init()` 与构造函数都做了幂等处理:
|
|
49
57
|
同一 root 只会有一个实例,不会出现「点一次切换两次」。
|
|
50
58
|
|
|
51
59
|
### 四种接入形态
|
package/CHANGELOG.md
CHANGED
|
@@ -16,6 +16,205 @@
|
|
|
16
16
|
|
|
17
17
|
(无)
|
|
18
18
|
|
|
19
|
+
## [0.25.4] - 2026-11-03
|
|
20
|
+
|
|
21
|
+
**修订版:把「类型里看不见的那 8 个全局」补上,并让这件事以后有人管。
|
|
22
|
+
不改组件行为、不改类名、不改令牌值。**
|
|
23
|
+
|
|
24
|
+
### 修复:8 个挂在 `window` 上的对象没有类型(E297)
|
|
25
|
+
|
|
26
|
+
源码里有 **24 个** `window.X =` / `global.X =`,`types/index.d.ts` 只声明了 **16 个**:
|
|
27
|
+
|
|
28
|
+
| 缺的 | 后果 |
|
|
29
|
+
|---|---|
|
|
30
|
+
| `Theme` / `Chart` / `ChartAdapter` / `ModelViewer` | TS 项目里 `window.Theme.set('dark')` 直接报"属性不存在" |
|
|
31
|
+
| `Bar` / `ScientificPlot` / `ShellNav` | 同上(审计报告没点到这三个) |
|
|
32
|
+
| `Upload` | 最刺眼:`esm/upload.mjs` **存在**,运行时能 import,类型里却看不见 |
|
|
33
|
+
|
|
34
|
+
用户遇到这种情况只有两条路:`(window as any)` 或 `@ts-expect-error` —— **两条都绕开了类型系统**,
|
|
35
|
+
而这个库最反对的就是绕过契约。
|
|
36
|
+
|
|
37
|
+
修法:把 8 个对象的真实形状补进 `FrontendLibGlobal`(形状是逐个读源码确认的,
|
|
38
|
+
不是照抄 README);只有 `Upload` 加了具名导出 `export declare const Upload`,
|
|
39
|
+
因为只有它在 `esm/` 里有包装模块。声明一个运行时取不到的具名导出,
|
|
40
|
+
正是本库最反对的「幻觉 API」。
|
|
41
|
+
|
|
42
|
+
### 更正:一句替门禁吹牛的注释
|
|
43
|
+
|
|
44
|
+
`types/index.d.ts` 里原来写着「behavior-api 门禁核对源码 / esm 入口 / **本文件声明**
|
|
45
|
+
三者集合相等」。核实:`behavior-api-gate.js` 里**一次都没出现** `index.d.ts`,
|
|
46
|
+
它只比源码与 `esm/`。`check-all.sh` 里对同一道门禁的描述也有同样的问题。
|
|
47
|
+
|
|
48
|
+
⇒ 两处都改成实话,并补上真正做这件事的门禁(下一条)。
|
|
49
|
+
**注释替门禁承诺了它没做的事,比没有门禁更危险** —— 你会以为有人在看。
|
|
50
|
+
|
|
51
|
+
### 新增门禁:类型与运行时必须对齐
|
|
52
|
+
|
|
53
|
+
`05-audit/types-globals-gate.py`,三条判据:
|
|
54
|
+
|
|
55
|
+
1. 源码里每个 `window.X =` / `global.X =`(排除 `==` / `===`)都必须在
|
|
56
|
+
`FrontendLibGlobal` 里有声明;
|
|
57
|
+
2. 反过来,每条声明都必须能在源码里找到赋值 ⇒ 防「幻觉类型」;
|
|
58
|
+
3. 每个 `export declare const X` 必须有 `esm/<kebab>.mjs` ⇒ 防「幻觉导出」。
|
|
59
|
+
|
|
60
|
+
反向控制五项:新增一个没声明的全局 / 删掉 `Theme` 的声明 / 声明一个源码里没有的成员 /
|
|
61
|
+
声明一个没有 esm 的具名导出 / 真实仓库必须全绿。
|
|
62
|
+
|
|
63
|
+
### 修复:`--schema=behaviors` 不可用(E298)
|
|
64
|
+
|
|
65
|
+
`ai/behaviors.schema.json` 一直都在,`ai/cli.js` 的 `SCHEMAS` 映射里却没有 `behaviors`
|
|
66
|
+
⇒ `node ai/cli.js validate ai/behaviors.json --schema=behaviors` 报「未知 schema」。
|
|
67
|
+
|
|
68
|
+
后果是这份契约**没有任何工具能校验**:`behaviors.json` 是稳定性承诺里的微行为矩阵,
|
|
69
|
+
写错了只能靠人看。补一行映射即可,已验证能通过也能报错。
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## [0.25.3] - 2026-11-03
|
|
74
|
+
|
|
75
|
+
**修订版:修掉四个「照着文档写会直接失败」的入口问题,并补上三层规范里缺失的那一层。
|
|
76
|
+
不改组件行为、不改类名、不改任何令牌值。**
|
|
77
|
+
|
|
78
|
+
### 修复:文档承诺的导入路径与实际不符(4 处)
|
|
79
|
+
|
|
80
|
+
| 症状 | 根因 | 影响 |
|
|
81
|
+
|---|---|---|
|
|
82
|
+
| `import 'agentcss/esm/accordion.mjs'` → 解析到 `accordion.mjs.mjs` | `"./esm/*": "./esm/*.mjs"` 把扩展名又拼了第二次 | 按 API.md 接入的打包项目直接构建失败 |
|
|
83
|
+
| `import { Select } from 'agentcss'` → `ERR_UNKNOWN_FILE_EXTENSION .html` | `exports["."]` 指向 `index.html` | 类型层承诺了根导入,运行时却把 HTML 当模块 |
|
|
84
|
+
| `import 'agentcss/ai/components.json'` → `ERR_PACKAGE_PATH_NOT_EXPORTED` | 没有 `./ai/*` 导出 | 想通过包名读契约的工具只能猜文件系统路径 |
|
|
85
|
+
| `import 'agentcss/01-tokens/tokens.css'`(README 教的"可读版") | 该入口不存在,可读版在 `agentcss/src/...` | 读者复制即失败 |
|
|
86
|
+
|
|
87
|
+
**修法**:`exports["."]` 改指 `./esm/index.mjs`;补 `./esm/*.mjs` 与 `./ai/*`;
|
|
88
|
+
README 的可读版入口改成 `agentcss/src/01-tokens/tokens.css`。
|
|
89
|
+
|
|
90
|
+
### 新增门禁:文档里的 import 路径必须真能解析
|
|
91
|
+
|
|
92
|
+
`05-audit/doc-imports.js`,接进 `pack-smoke`。它把 6 份对外文档里出现的每个
|
|
93
|
+
`agentcss/...` 字面路径,拿到消费者环境里真解析一次(只解析、不执行)。
|
|
94
|
+
|
|
95
|
+
**为什么以前没抓到**:`entry-resolve` 判的是「**exports 声明的**入口」——
|
|
96
|
+
它遍历 `package.json` 的 key、用包内文件套通配符;`pack-closure` 只判"文件在不在";
|
|
97
|
+
`node --check` 只判语法。三者的共同点是:**"读文档的那一方"从来没有被测过**。
|
|
98
|
+
这道门禁上线当天就抓出了上表最后一行(报告里没有的第 4 处)。
|
|
99
|
+
|
|
100
|
+
### 更正:聚合 ESM 入口不会摇树
|
|
101
|
+
|
|
102
|
+
0.25.2 之前 API.md 写「Vite/Rollup 会按需摇树」,**这是错的**。
|
|
103
|
+
`esm/*.mjs` 的形式是「副作用导入 + 把全局对象 re-export」,模块体本身就有副作用,
|
|
104
|
+
打包器无法判断哪个导出没被用到。`sideEffects` 里 `**/*.js` / `**/*.mjs`
|
|
105
|
+
是**按事实写的、是对的** —— 错的是那句文档。
|
|
106
|
+
|
|
107
|
+
实测(esbuild):`import { Select } from 'agentcss/esm'` 产物 **190 KB**,
|
|
108
|
+
`import { Select } from 'agentcss/esm/select'` 只有 **20.8 KB**(约 9 倍)。
|
|
109
|
+
文档已改成「要体积就逐个 `agentcss/esm/<组件>`」。
|
|
110
|
+
|
|
111
|
+
### 补齐:三层规范缺失的第三层
|
|
112
|
+
|
|
113
|
+
`docs/INVARIANT.md` 与 `docs/AI-CONTRACT.md` 一直把 `docs/GUIDANCE.md` 当作
|
|
114
|
+
"建议层"来引用,但那份文件在 0.11.4 被整份移进内部目录(含发布凭证类内容),
|
|
115
|
+
公开面于是只剩两层。现在补一份**只含可公开部分**的 `docs/GUIDANCE.md`,
|
|
116
|
+
并在文首写明边界:凭证、账号二次因子、内部排期一律不进公开面。
|
|
117
|
+
|
|
118
|
+
### 新增:可公开的教训集
|
|
119
|
+
|
|
120
|
+
`docs/LESSONS.md` —— 从内部错误登记里挑出 10 条可复用规则
|
|
121
|
+
(判据的错法 / 删除与清理 / 发布语义),脱敏后公开。
|
|
122
|
+
README 里「想知道我们踩过哪些坑」的指向,从内部文件改到这里。
|
|
123
|
+
|
|
124
|
+
### 修复:9 处指向不存在文件的引用
|
|
125
|
+
|
|
126
|
+
`ERRORS.md`(在内部目录,不入库)、`docs/ROADMAP.md`、`docs/GUIDANCE.md` 被
|
|
127
|
+
README / CONTRIBUTING / 05-audit/README 引用,但文件不存在。
|
|
128
|
+
现在全部改指向真实文件,或去掉编号(内部条号对外部读者没有意义)。
|
|
129
|
+
|
|
130
|
+
### 修复:AI 契约里的令牌描述**认错了令牌**(E294)
|
|
131
|
+
|
|
132
|
+
这是本库最值钱的差异化(机器可读契约)里最难察觉的一类错。
|
|
133
|
+
|
|
134
|
+
`parse_block` 只有一个 `pending_note`:`--a: 1; /* A 的说明 */` 里的注释被
|
|
135
|
+
**下一个**声明吃掉。而 `tokens.css` 里有 **101 条尾注释** ⇒ 最多 100 个令牌的
|
|
136
|
+
描述整体错位一位。生成的 JSON 里因此出现了:
|
|
137
|
+
|
|
138
|
+
| 令牌 | 原来的 `$description` | 那是谁的 |
|
|
139
|
+
|---|---|---|
|
|
140
|
+
| `--scrollbar-radius`(5px) | `hover 更深一档 · 4.06:1` | `--scrollbar-thumb-hov` 的 |
|
|
141
|
+
| `--scrollbar-thumb-hov` | `中性**冷**灰(非品牌色…)` | `--scrollbar-thumb` 的 |
|
|
142
|
+
| `--paper` | `-------- 基底`(分隔线) | 没有人,是分组标题 |
|
|
143
|
+
| `--text-on-solid` | `🔴 新增( H9 期间由暗色门禁逼出来):` | 半句话,正文在后面几行 |
|
|
144
|
+
|
|
145
|
+
**这比缺描述更糟**:机器读者拿到的是一段**真实存在、但属于别人**的话 ——
|
|
146
|
+
缺失时它会去查,错挂时它会照做。
|
|
147
|
+
|
|
148
|
+
修法(三条都是机械规则):
|
|
149
|
+
1. 同一行 `;` 之后的注释归**前一个**声明(尾注释),换行之后的才是前导注释;
|
|
150
|
+
2. 块首是分隔线 ⇒ 那是分组注释:紧随的一行是组名,丢掉;正文只有**提到本令牌名**
|
|
151
|
+
才归本令牌,否则不算它的描述(`--text-primary` 的块讲的是"三档够用",不是它);
|
|
152
|
+
3. 前导 + 尾注释都收,去重后拼接,超过 400 字按整句截断。
|
|
153
|
+
|
|
154
|
+
顺带修掉暗色段的同类错:`@media` 里的 `:root…{` **选择器上方**挂着解释选择器的
|
|
155
|
+
注释(「⚠️ `:not([data-theme="light"])` 让强制亮压过系统暗色」),旧实现解析整个
|
|
156
|
+
media 体 ⇒ 它成了块内第一个声明的描述(实测 `dark/--paper` 拿到的就是这句)。
|
|
157
|
+
现在只解析 `:root` 内层块。
|
|
158
|
+
|
|
159
|
+
结果:147 个令牌里 **99 个有准确描述**(原 95 个,其中 19 个是分隔线);
|
|
160
|
+
其余 48 个确实没有注释,就**不写这个字段**,而不是塞一句别人的话。
|
|
161
|
+
|
|
162
|
+
### 新增门禁:令牌描述必须认对令牌
|
|
163
|
+
|
|
164
|
+
`05-audit/ai-token-desc-gate.py`,五条判据:① 无分隔线 ② 不写空串
|
|
165
|
+
③ 不以冒号结尾/不是纯符号 ④ ≤ 400 字 ⑤ **归属** ——
|
|
166
|
+
每条描述必须能在**本令牌自己的相邻注释**里找到出处。
|
|
167
|
+
|
|
168
|
+
**为什么 `ai-contract --check` 抓不到**:它保证「JSON 与生成器一致」,
|
|
169
|
+
生成器错了它也全绿。这正是 0.25.2 的实际状态。
|
|
170
|
+
|
|
171
|
+
**它自己的反向控制也翻过一次车**:第一版判据⑤ 在 0.25.2 的数据上**一条都抓不到**,
|
|
172
|
+
因为"上一行的尾注释"被它当成"下一行的前导注释"—— 和它要抓的 bug 是同一种形状。
|
|
173
|
+
修掉后同一份历史数据报出 **74 条**(19 分隔线 + 50 错位 + 5 半句话)。
|
|
174
|
+
之后才加进 `check-all.sh`:判据必须先证明自己会红。
|
|
175
|
+
|
|
176
|
+
### 修复:发布前门禁的动效采样在慢机器上误红(E295)
|
|
177
|
+
|
|
178
|
+
0.25.3 第一次发版就栽在这里:`selftest-all` 判「基准不通过,自检无意义」,
|
|
179
|
+
而 `motion-concurrency.js` 正是基准那一条 —— 于是**整条发布流程被挡下**,
|
|
180
|
+
npm 上什么都没发出去。
|
|
181
|
+
|
|
182
|
+
根因不是判据错,是**采样方式**:过渡只有 180ms,旧实现「切状态 → 等 2 帧 →
|
|
183
|
+
`getAnimations()` 取一次快照」。2 核 runner 被 6 路门禁抢 CPU 时,两次 rAF
|
|
184
|
+
之间就跨过了整个过渡 ⇒ 读到空数组 ⇒ 判「没有动画」。
|
|
185
|
+
|
|
186
|
+
对照:0.25.2 那次 `selftest-all` **90 秒通过**;这次 **131 秒红**。差别只是机器更慢。
|
|
187
|
+
|
|
188
|
+
修法(**不放宽任何阈值**):
|
|
189
|
+
- 改成**窗口内求并集**:挂 `transitionrun` / `animationstart` 监听 + 240ms 轮询,
|
|
190
|
+
只要窗口里出现过动画就算数;
|
|
191
|
+
- 切换前 `void el.offsetWidth` 强制一次样式结算 —— 否则同一帧里的
|
|
192
|
+
`remove` + `set` 会被浏览器合并成"没变化",一条动画都不产生(这个坑是修的时候
|
|
193
|
+
自己踩出来的,第一版把判据① 从"偶发红"改成了"稳定红")。
|
|
194
|
+
|
|
195
|
+
反向控制仍是「注入 `*{transition:none}` ⇒ 判据① 必须红」,仍然通过。
|
|
196
|
+
连跑 5 次稳定。
|
|
197
|
+
|
|
198
|
+
### 修复:打印门禁量的是「iframe 起没起来」(E296)
|
|
199
|
+
|
|
200
|
+
同一轮里 `print` 也红了一次:`guide-button/light` 报 `pages=4`(基线 8)、
|
|
201
|
+
`runs=1679`(基线 2321)—— 版面少了一半,但页面本身一个字节没改。
|
|
202
|
+
|
|
203
|
+
根因:44 个 `guide/*.html` 每个都嵌了 `<iframe loading="lazy" src="…/demo.html">`,
|
|
204
|
+
**打印产物包含 iframe 的内容**。并发 6 路时那个 iframe 可能整页没开始加载,
|
|
205
|
+
版面就腰斩了 —— 而 `loadStyled()` 当时的两个信号(CSS 请求失败、顶层 `<link>`
|
|
206
|
+
全没挂上)**都看不见 iframe**:顶层文档的样式表好得很。
|
|
207
|
+
|
|
208
|
+
加第三个信号:强制 `loading=eager`、触发未开始的加载,然后等每个 frame
|
|
209
|
+
`readyState==='complete'` **且挂上至少一张带 href 的样式表**。
|
|
210
|
+
不是放宽判据 —— 真内容缺失时页数照样对不上,只是不再把"iframe 没起来"
|
|
211
|
+
算成"库改坏了"。
|
|
212
|
+
|
|
213
|
+
反向控制:正常 iframe → 不误伤(`bad=0`);404 的 iframe → 变红(`bad=1`)。
|
|
214
|
+
稳定性:4 路 CPU 抢占下连跑仍是 8 页 / 2321 runs。
|
|
215
|
+
|
|
216
|
+
---
|
|
217
|
+
|
|
19
218
|
## [0.25.2] - 2026-11-03
|
|
20
219
|
|
|
21
220
|
**修订版:把覆盖率门禁里 41 个「只被 README 认领」的类全部变成真的渲染。
|
package/CONTRIBUTING.md
CHANGED
|
@@ -29,7 +29,7 @@ npm run gate # 全量:含浏览器类
|
|
|
29
29
|
npm run gate:fast # 只跑静态层,不用装浏览器
|
|
30
30
|
```
|
|
31
31
|
|
|
32
|
-
全量是 **
|
|
32
|
+
全量是 **235 道门禁**(默认 `min(核数, 6)` 路并发,实测 583 秒 / 退出码 0;
|
|
33
33
|
单道耗时累加 1658 秒,并发效率约 2.8×。组件层要起浏览器,还要逐张比 **109 张**视觉截图 ——
|
|
34
34
|
47 浅色 + 47 暗色 + 15 RTL,按平台分集,只比本平台那套)。
|
|
35
35
|
只想确认没改坏静态契约的话用 `gate:fast`,几秒到几分钟。
|
|
@@ -150,7 +150,7 @@ RTL 视觉基线**故意不是全量**(纯文本页在 RTL 下与 LTR 是同
|
|
|
150
150
|
- 改令牌 ⇒ `token-parse` / `token-tree` / `cascade-layer` 三道都会看
|
|
151
151
|
- 改文档 ⇒ `doc-facts` 会核对里面的数字与仓库是否一致
|
|
152
152
|
- **只跑相关的几道是不够的** —— 曾经有一批门禁在自己的调用方式下扫 0 个文件
|
|
153
|
-
仍判通过(`
|
|
153
|
+
仍判通过(`docs/LESSONS.md`「零文件即通过」),所以现在每道门禁都有「零文件即失败」的守卫
|
|
154
154
|
|
|
155
155
|
## 提交信息怎么写
|
|
156
156
|
|
|
@@ -172,11 +172,11 @@ fix: <一句话说清改了什么、为什么>
|
|
|
172
172
|
|
|
173
173
|
1. **一次性迁移脚本用完即删。** 别留在仓库里 ——
|
|
174
174
|
本库曾有一个 `leak-fix-paths.py`,它的正则匹配任意引号字符串,
|
|
175
|
-
一次运行把 **80
|
|
175
|
+
一次运行把 **80 个文件**的每个字符串字面量都改了。
|
|
176
176
|
2. **新增门禁必须带反向控制。** 一道不会红的门禁不算门禁。
|
|
177
177
|
写法见 `05-audit/token-parse-gate.py` 的 `selftest()`。
|
|
178
178
|
3. **同一个判定不要写两遍。** 判据分散在两个文件里必然漂移
|
|
179
|
-
|
|
179
|
+
(同一个判定写两遍必然漂移)。要复用就 import,不要复制。
|
|
180
180
|
4. **修门禁前先证明它现在真的会红。** 用 `--dir <目录>` 与无参各跑一次,
|
|
181
181
|
两者的差别就是问题的形状(这正是 E41 的发现方式)。
|
|
182
182
|
5. **豁免要写清理由,并列举式。** 「这份代码的使用者控制不了它」是唯一的豁免理由;
|
|
@@ -220,7 +220,7 @@ fix: <一句话说清改了什么、为什么>
|
|
|
220
220
|
- [ ] 改动涉及 UI ⇒ 在 `10-review/shots/` 里有截图对比
|
|
221
221
|
- [ ] 改了行为 ⇒ `ai/components.json` 已重新生成(`npm run ai`)
|
|
222
222
|
- [ ] 改了令牌或组件 ⇒ `npm run dist` 已重建,dist 与源码一致
|
|
223
|
-
- [ ] 有踩坑 ⇒
|
|
223
|
+
- [ ] 有踩坑 ⇒ 记进内部错误登记(症状 / 根因 / 规则三件套);可复用的规则同步进 `docs/LESSONS.md`
|
|
224
224
|
|
|
225
225
|
## 代码风格
|
|
226
226
|
|
package/README.zh-CN.md
CHANGED
|
@@ -70,7 +70,7 @@ npm install https://github.com/owain323/frontend-lib/releases/download/v<版本>
|
|
|
70
70
|
npm install github:owain323/frontend-lib
|
|
71
71
|
```
|
|
72
72
|
|
|
73
|
-
> 历史说明:0.9.0
|
|
73
|
+
> 历史说明:0.9.0 曾发布成功、两分钟后被误删;此后一段时间
|
|
74
74
|
> registry 上没有可安装版本,靠 GitHub Release 附件分发(当时的分发路径记在
|
|
75
75
|
> `CHANGELOG.md` 的 0.11.2 一节)。自 0.11.2 起这条通路已恢复。
|
|
76
76
|
|
|
@@ -291,7 +291,7 @@ dist/01-tokens/tokens.css ← 拷这个
|
|
|
291
291
|
```js
|
|
292
292
|
import 'agentcss/dist/01-tokens/tokens.css'; // 压缩版
|
|
293
293
|
import 'agentcss/dist/02-primitives/button/button.css';
|
|
294
|
-
//
|
|
294
|
+
// 要可读版(源码,注释齐全):import 'agentcss/src/01-tokens/tokens.css';
|
|
295
295
|
```
|
|
296
296
|
|
|
297
297
|
> ⚠️ **不再有 `*.min.css`**。此前 `dist/` 同时产出 `x.css`(去注释)与 `x.min.css`(压缩),
|
|
@@ -397,7 +397,7 @@ bash 05-audit/check-all.sh # 全量门禁约 130 项,本机约 8 分钟
|
|
|
397
397
|
`node 05-audit/scientific-plot-check.js`。
|
|
398
398
|
- 想看每道门禁**自己有没有牙**:`bash 05-audit/behavior-reverse.sh`
|
|
399
399
|
(对门禁做突变,验证它会红、且只红该红的那一条)。
|
|
400
|
-
- 想知道**我们踩过哪些坑**:`
|
|
400
|
+
- 想知道**我们踩过哪些坑**:`docs/LESSONS.md`。只记真的红过的门禁和真的做错过的事,
|
|
401
401
|
每条写清症状 → 根因 → 纠正规则,规则都能照着执行。
|
|
402
402
|
|
|
403
403
|
### 经过实际验证的
|
package/ai/cli.js
CHANGED
|
@@ -151,7 +151,11 @@ var SCHEMAS = {
|
|
|
151
151
|
tokensAudience: 'tokens.audience.schema.json',
|
|
152
152
|
tokensTree: 'tokens.tree.schema.json',
|
|
153
153
|
deprecations: 'deprecations.schema.json',
|
|
154
|
-
patch: 'patch.schema.json'
|
|
154
|
+
patch: 'patch.schema.json',
|
|
155
|
+
/* behaviors 是稳定性承诺里的核心契约(微行为矩阵),
|
|
156
|
+
它的 schema 文件一直都在,但这里漏登记 ⇒ `--schema=behaviors` 报
|
|
157
|
+
"未知 schema",等于这份契约**没有任何工具能校验**(E298)。 */
|
|
158
|
+
behaviors: 'behaviors.schema.json'
|
|
155
159
|
};
|
|
156
160
|
|
|
157
161
|
function cmdValidate(args) {
|
package/ai/components.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": "1.0.0",
|
|
3
3
|
"generatedBy": "05-audit/gen-ai-contract.py",
|
|
4
|
-
"libraryVersion": "0.25.
|
|
4
|
+
"libraryVersion": "0.25.4",
|
|
5
5
|
"$comment": "机器可读的组件契约。slots = BEM 元素名(在本库里元素名就是插槽名),states.enum = 组件会在 DOM 上写出的 data-* 取值,states.legacyClass = 仍未收敛到 data 属性的历史状态类(INVARIANT I-8 未达标)。printPolicy = 这个组件在纸上会发生什么(空数组 = 原样保留);pagination = 内容是否被分页裁过(server 不许与 expand 同时出现,否则展开的只是当前一页)。",
|
|
6
6
|
"maturityCriteria": {
|
|
7
7
|
"alpha": "缺 demo.html 或缺 05-audit 下的专属门禁 ⇒ 还没被机器验证过,不要用",
|