agentcss 0.25.6 → 0.27.0

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.
Files changed (81) hide show
  1. package/01-tokens/README.md +1 -1
  2. package/01-tokens/behavior/labels.js +44 -0
  3. package/01-tokens/responsive-demo.html +1 -1
  4. package/01-tokens/tokens.core.css +1 -1
  5. package/01-tokens/tokens.css +2 -2
  6. package/02-primitives/combobox/combobox.js +26 -3
  7. package/02-primitives/date-range/date-range.js +28 -6
  8. package/02-primitives/popover/popover.js +22 -2
  9. package/02-primitives/select/select.js +23 -2
  10. package/02-primitives/timeline/demo.html +1 -1
  11. package/02-primitives/upload/upload.js +50 -17
  12. package/03-patterns/content/content.css +13 -1
  13. package/03-patterns/content/demo.html +1 -1
  14. package/03-patterns/drawer/demo.html +1 -1
  15. package/03-patterns/drawer/drawer.js +44 -6
  16. package/03-patterns/dropdown/dropdown.js +21 -1
  17. package/03-patterns/overlay/overlay.css +1 -1
  18. package/03-patterns/overlay/overlay.js +39 -2
  19. package/03-patterns/pagination/pagination.js +37 -10
  20. package/03-patterns/states/states.css +1 -1
  21. package/03-patterns/tooltip/tooltip.js +17 -2
  22. package/03-patterns/tree/tree.js +21 -1
  23. package/04-recipes/analysis-report/demo.html +1 -1
  24. package/04-recipes/app-shell/README.md +1 -1
  25. package/04-recipes/app-shell/demo.html +1 -1
  26. package/04-recipes/data-showcase/demo.html +2 -2
  27. package/04-recipes/longform/content.html +993 -78
  28. package/04-recipes/longform/longform.html +3 -3
  29. package/04-recipes/report/demo.html +3 -3
  30. package/04-recipes/table/README.md +23 -1
  31. package/04-recipes/table/demo.html +7 -7
  32. package/09-assets/bar/bar.css +1 -1
  33. package/09-assets/bar/bar.js +28 -4
  34. package/09-assets/model-viewer/model-viewer.js +45 -13
  35. package/09-assets/scientific-plot/demo.html +6 -6
  36. package/AGENTS.md +3 -1
  37. package/API.md +32 -0
  38. package/CHANGELOG.md +174 -5
  39. package/CONTRIBUTING.md +44 -3
  40. package/README.md +19 -0
  41. package/README.zh-CN.md +18 -0
  42. package/SECURITY.md +16 -4
  43. package/START-HERE.md +25 -18
  44. package/ai/START-HERE.md +40 -6
  45. package/ai/check-html.js +658 -0
  46. package/ai/cli.js +557 -67
  47. package/ai/components.json +9 -4
  48. package/ai/pdf.js +52 -10
  49. package/ai/recipes.json +86 -0
  50. package/ai/scaffold.js +195 -0
  51. package/ai/shot.js +345 -0
  52. package/ai/validate.js +65 -6
  53. package/dist/01-tokens/behavior/labels.js +11 -0
  54. package/dist/02-primitives/combobox/combobox.js +25 -3
  55. package/dist/02-primitives/date-range/date-range.js +26 -5
  56. package/dist/02-primitives/popover/popover.js +14 -1
  57. package/dist/02-primitives/select/select.js +22 -2
  58. package/dist/02-primitives/upload/upload.js +47 -17
  59. package/dist/03-patterns/content/content.css +1 -1
  60. package/dist/03-patterns/drawer/drawer.js +32 -4
  61. package/dist/03-patterns/dropdown/dropdown.js +20 -1
  62. package/dist/03-patterns/overlay/overlay.js +25 -1
  63. package/dist/03-patterns/pagination/pagination.js +34 -10
  64. package/dist/03-patterns/tooltip/tooltip.js +14 -2
  65. package/dist/03-patterns/tree/tree.js +20 -1
  66. package/dist/09-assets/bar/bar.js +23 -4
  67. package/dist/09-assets/model-viewer/model-viewer.js +38 -12
  68. package/dist/COSTS.md +20 -20
  69. package/docs/ACCESSIBILITY.md +3 -3
  70. package/docs/ARCHITECTURE.md +116 -0
  71. package/docs/L10N.md +92 -0
  72. package/docs/LAYER-BASELINE.md +2 -2
  73. package/docs/PRINT.md +3 -3
  74. package/docs/RELEASE-PROCESS.md +59 -3
  75. package/docs/STABILITY.md +1 -1
  76. package/docs/VERIFY-RELEASE.md +24 -2
  77. package/index.html +3 -3
  78. package/llms-full.txt +18 -4
  79. package/llms.txt +26 -5
  80. package/package.json +4 -2
  81. package/types/index.d.ts +218 -13
package/dist/COSTS.md CHANGED
@@ -18,42 +18,42 @@
18
18
 
19
19
  | 档 | 组件 | tokens(必付) | CSS | JS | **合计** | 源码版合计 | 差 |
20
20
  |---|---|---:|---:|---:|---:|---:|---:|
21
- | primitive | `badge` | 2.9 KB | 0.5 KB | — | **3.4 KB** | 24.7 KB | −21.2 KB |
21
+ | primitive | `badge` | 2.9 KB | 0.5 KB | — | **3.4 KB** | 24.6 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.5 KB | **9.4 KB** | 31.5 KB | −22.1 KB |
26
- | primitive | `date-range` | 2.9 KB | 0.8 KB | 2.6 KB | **6.3 KB** | 28.6 KB | −22.3 KB |
27
- | primitive | `delta` | 2.9 KB | 0.3 KB | — | **3.2 KB** | 24.7 KB | −21.5 KB |
28
- | primitive | `input` | 2.9 KB | 1.0 KB | — | **4.0 KB** | 25.8 KB | −21.9 KB |
25
+ | primitive | `combobox` | 2.9 KB | 1.0 KB | 5.7 KB | **9.6 KB** | 31.8 KB | −22.2 KB |
26
+ | primitive | `date-range` | 2.9 KB | 0.8 KB | 2.8 KB | **6.6 KB** | 28.9 KB | −22.3 KB |
27
+ | primitive | `delta` | 2.9 KB | 0.3 KB | — | **3.2 KB** | 24.6 KB | −21.4 KB |
28
+ | primitive | `input` | 2.9 KB | 1.0 KB | — | **4.0 KB** | 25.8 KB | −21.8 KB |
29
29
  | primitive | `metric` | 2.9 KB | 0.5 KB | — | **3.4 KB** | 25.1 KB | −21.7 KB |
30
- | primitive | `popover` | 2.9 KB | 0.8 KB | 2.2 KB | **5.9 KB** | 29.3 KB | −23.4 KB |
30
+ | primitive | `popover` | 2.9 KB | 0.8 KB | 2.3 KB | **6.1 KB** | 29.7 KB | −23.6 KB |
31
31
  | primitive | `progress` | 2.9 KB | 0.8 KB | — | **3.7 KB** | 26.2 KB | −22.5 KB |
32
- | primitive | `select` | 2.9 KB | 0.8 KB | 4.1 KB | **7.9 KB** | 32.9 KB | −24.9 KB |
32
+ | primitive | `select` | 2.9 KB | 0.8 KB | 4.3 KB | **8.1 KB** | 33.1 KB | −25.0 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.3 KB | −26.5 KB |
36
- | primitive | `timeline` | 2.9 KB | 0.5 KB | — | **3.4 KB** | 25.2 KB | −21.7 KB |
37
- | primitive | `upload` | 2.9 KB | 1.4 KB | 4.2 KB | **8.5 KB** | 39.3 KB | −30.8 KB |
35
+ | primitive | `switch` | 2.9 KB | 0.8 KB | — | **3.7 KB** | 30.2 KB | −26.5 KB |
36
+ | primitive | `timeline` | 2.9 KB | 0.5 KB | — | **3.4 KB** | 25.1 KB | −21.7 KB |
37
+ | primitive | `upload` | 2.9 KB | 1.4 KB | 4.5 KB | **8.8 KB** | 39.7 KB | −30.9 KB |
38
38
  | pattern | `accordion` | 2.9 KB | 1.3 KB | 1.8 KB | **6.0 KB** | 36.4 KB | −30.4 KB |
39
- | pattern | `content` | 2.9 KB | 1.0 KB | — | **4.0 KB** | 26.5 KB | −22.5 KB |
40
- | pattern | `drawer` | 2.9 KB | 0.8 KB | 2.6 KB | **6.3 KB** | 30.2 KB | −23.9 KB |
41
- | pattern | `dropdown` | 2.9 KB | 0.8 KB | 3.5 KB | **7.2 KB** | 31.6 KB | −24.4 KB |
39
+ | pattern | `content` | 2.9 KB | 1.0 KB | — | **4.0 KB** | 26.8 KB | −22.9 KB |
40
+ | pattern | `drawer` | 2.9 KB | 0.8 KB | 2.8 KB | **6.6 KB** | 30.8 KB | −24.3 KB |
41
+ | pattern | `dropdown` | 2.9 KB | 0.8 KB | 3.6 KB | **7.3 KB** | 31.8 KB | −24.5 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
- | pattern | `overlay` | 2.9 KB | 1.2 KB | 3.6 KB | **7.7 KB** | 38.5 KB | −30.8 KB |
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.5 KB | −22.0 KB |
45
+ | pattern | `overlay` | 2.9 KB | 1.2 KB | 3.8 KB | **7.9 KB** | 39.2 KB | −31.3 KB |
46
+ | pattern | `pagination` | 2.9 KB | 0.8 KB | 2.8 KB | **6.5 KB** | 32.7 KB | −26.3 KB |
47
+ | pattern | `reveal` | 2.9 KB | 0.3 KB | 1.2 KB | **4.4 KB** | 26.4 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
- | pattern | `tooltip` | 2.9 KB | 0.5 KB | 1.9 KB | **5.3 KB** | 28.5 KB | −23.2 KB |
51
- | pattern | `tree` | 2.9 KB | 0.6 KB | 2.9 KB | **6.5 KB** | 30.1 KB | −23.6 KB |
50
+ | pattern | `tooltip` | 2.9 KB | 0.5 KB | 2.0 KB | **5.4 KB** | 28.7 KB | −23.3 KB |
51
+ | pattern | `tree` | 2.9 KB | 0.6 KB | 3.1 KB | **6.6 KB** | 30.3 KB | −23.7 KB |
52
52
 
53
53
  ## 三、全库
54
54
 
55
- - 全部组件都用上(min,含 tokens 一份):**70.6 KB**
56
- - 源码版(带注释)全库 gzip:380.1 KB
55
+ - 全部组件都用上(min,含 tokens 一份):**72.6 KB**
56
+ - 源码版(带注释)全库 gzip:386.4 KB
57
57
 
58
58
  > ⚠️ 源码版那个数字**不是**要付的钱:它包含我们的注释(全库 CSS 有 69% 是注释,字节口径)。
59
59
  > 它的用途只有一个 —— 让人看清"dist 到底省了多少"。
@@ -5,8 +5,8 @@
5
5
 
6
6
  | 项目 | 值 |
7
7
  |---|---|
8
- | 声明适用版本 | agentcss `0.25.6` |
9
- | 声明日期 | 2026-11-04 |
8
+ | 声明适用版本 | agentcss `0.27.0` |
9
+ | 声明日期 | 2026-11-06 |
10
10
  | 复核节奏 | 每次发版前重跑(`npm run gate` 内含全部证据) |
11
11
  | 范围 | 本库交付的 CSS / JS、全部 `demo.html`(组件页 + 图表页 + 组合页)、以及文档站生成的页面 |
12
12
  | 不在范围 | 使用者拿这些组件拼出来的业务页面(那是你的无障碍责任,不是库的) |
@@ -39,7 +39,7 @@
39
39
  | 1.4.11 | 非文本对比度 | ✅ | 控件边框 / 焦点环 / 图表色阶单独实算 |
40
40
  | 1.4.12 | 文本间距 | ◐ | 组件不写死行高与段距(都用令牌),但**未**按"行高 1.5 倍 / 段距 2 倍"的极端注入逐组件验证 |
41
41
  | 1.4.13 | 内容悬停或聚焦 | ◐ | tooltip 可 Esc 关闭、可悬停保持;**未**验证"可选中提示内文字"这一分支 |
42
- | 2.1.1 | 键盘 | ✅ | `keyboard-nav.js`:Tab 顺序、Enter/Space、Esc 关闭 |
42
+ | 2.1.1 | 键盘 | ✅ | `keyboard-nav.js`:Tab 顺序、Enter/Space、Esc 关闭;**滚动容器**(`.table` / `<pre>` / 图框)在 320px 下可 Tab 进入 —— `table-check` ⑮ + `a11y-scan` 的 320px `scrollable-region-focusable` 补扫 |
43
43
  | 2.1.2 | 无键盘陷阱 | ✅ | `keyboard-nav.js`:浮层关闭后焦点可继续移动,不困在层内 |
44
44
  | 2.1.4 | 字符快捷键 | — | 库不注册单字符快捷键 |
45
45
  | 2.2.1 | 计时可调 | ◐ | toast 自动消失时长可配但有上限;**未**提供"暂停计时"控件 |
@@ -0,0 +1,116 @@
1
+ # agentcss 是怎么组成的
2
+
3
+ > 写给第一次接触这个项目的人。不需要先懂前端工程,读完能回答三个问题:
4
+ > 这是什么、东西怎么组织、靠什么保证不出乱子。
5
+
6
+ **一句话**:这是一个给手机网页用的**现成零件库**——按钮、表格、抽屉、整页版式都有,
7
+ 拿来就能用。它有三个少见的特点:
8
+
9
+ - **不装任何依赖**。把这个库装进项目,你的 `node_modules` 不会多出任何别的东西。
10
+ - **类名就是说明书**。样式全靠类名控制,不要求写初始化脚本、不绑定任何框架。
11
+ - **专门照顾 AI 编码助手**。每个组件都有一份机器可读的"说明书",AI 先读它再写代码,
12
+ 写完还能用配套命令自己检查。
13
+
14
+ 规模:40 个组件(全部稳定可用)、约 1 MB 的 npm 包、全库样式总量锁死在 172 KB 以内。
15
+
16
+ ## 一张图看懂
17
+
18
+ ```mermaid
19
+ flowchart TD
20
+ subgraph lib["组件本体 —— 依赖自上而下"]
21
+ direction TB
22
+ R["整页配方 recipes · 5 个<br/>拿来就是一页完整版式"]
23
+ P["组合模式 patterns · 14 个<br/>抽屉、弹层、时间线…"]
24
+ B["基础件 primitives · 17 个<br/>按钮、表格、下拉框…"]
25
+ T["设计令牌 tokens + 行为核 · 6 个<br/>颜色字号间距 + 少量交互脚本"]
26
+ R --> P --> B --> T
27
+ end
28
+
29
+ subgraph use["两种用法"]
30
+ H["给人:复制 demo 改内容"]
31
+ A["给 AI:先读机器说明书,写完自检"]
32
+ end
33
+
34
+ subgraph out["三个出口"]
35
+ NPM["npm 包"]
36
+ WEB["文档站(40 个组件页)"]
37
+ REPO["GitHub 仓库(检查系统全部公开)"]
38
+ end
39
+
40
+ H --> NPM
41
+ A --> NPM
42
+ NPM -.-> WEB
43
+ NPM -.-> REPO
44
+ ```
45
+
46
+ 读法:想用一个小按钮,拿 `02-primitives` 里的就行;想要一整页报表,直接拿
47
+ `04-recipes`。上面的层会用到下面的层,反过来不会——所以拆哪儿都拆得动。
48
+
49
+ ## 四层组件,像盖房子
50
+
51
+ | 层 | 是什么 | 打个比方 | 数量 |
52
+ |---|---|---|---|
53
+ | `01-tokens` | 颜色、字号、间距这些"数值表",浅色/深色两套主题;附 6 个小交互脚本(弹窗关闭、焦点归位这类) | 调色盘和刻度尺 | 1 套 |
54
+ | `02-primitives` | 最小的独立组件:按钮、卡片、表格、下拉框 | 砖和预制板 | 17 |
55
+ | `03-patterns` | 需要多个组件配合的场景:抽屉、弹层、标签页、时间线 | 预制房间 | 14 |
56
+ | `04-recipes` | 一整页的成品版式:报表页、应用外壳、财务页 | 样板房 | 5 |
57
+
58
+ 另有 `09-assets`(4 个独立小资产,比如图表底座),不属于这套分层,按需取用。
59
+
60
+ ## 目录地图
61
+
62
+ | 目录 | 放什么 |
63
+ |---|---|
64
+ | `01-tokens/` … `04-recipes/`、`09-assets/` | 上面说的组件本体,每个组件自带可打开的 demo 页和说明 |
65
+ | `ai/` | 给 AI 看的机器说明书(4 份 JSON)和一个命令行工具 |
66
+ | `05-audit/` | 自动检查系统(下节讲),全部公开、任何人可以运行 |
67
+ | `docs/` | 设计与工程文档(本文在这里) |
68
+ | `dist/`、`esm/`、`types/` | 构建产物,由源码自动生成,不许手改 |
69
+
70
+ ## 修改一处,处处自动跟上
71
+
72
+ 这个项目最讲究的一件事:**同一份数据只存一个地方,别的都由它自动生成。**
73
+
74
+ - 40 个组件的清单(类名、状态、无障碍属性)只写在 `ai/components.json` 一处。
75
+ 文档站的 46 个页面、给 AI 的摘要文本,全部由这份清单自动生成——
76
+ 有一个自动检查专门盯着"生成物和清单是否一致",改了清单忘了重新生成就会红。
77
+ - 关键数字同理:文档里写的组件数、检查数,都有自动检查对着源头核。
78
+
79
+ 好处很直接:文档不会和实现"各说各话",因为大部分文档本来就是实现生成的。
80
+
81
+ ## 怎么保证不出乱子:一个自动验收系统
82
+
83
+ 仓库里有一套自动检查(这个项目里叫"门禁"),共 **251 项**,像三道验收:
84
+
85
+ | 什么时候跑 | 跑多少 | 多快 | 查什么 |
86
+ |---|---|---|---|
87
+ | 每次提交前 | 5 项 | 约 7 秒 | 说明书、页面结构、文案、类型有没有被改坏 |
88
+ | 每次推送时 | 128 项 | 约 3.5 分钟 | 以上全部,外加所有不需要浏览器的检查 |
89
+ | 发布之前 | 251 项 | 约 10 分钟 | 再加真浏览器实测、逐像素视觉比对、安装包体检 |
90
+
91
+ 三条规矩让它长期可信:
92
+
93
+ 1. **每个检查先证明自己能抓到问题**——故意弄坏一个组件,检查必须变红;
94
+ 把检查关掉后问题必须重新出现。做不到这一点的检查不算数。
95
+ 2. **"跳过"不等于"通过"**——环境缺浏览器就明确标"本次没查",绝不悄悄变绿。
96
+ 3. **没测过就说没测**——真机只在 5 类环境验证过,其余内核明说"未验证",不写"应该没问题"。
97
+
98
+ ## 给 AI 编码助手怎么用
99
+
100
+ 机器说明书在 `ai/` 目录,四份 JSON 覆盖:每个组件的类名与状态、已知的坑、
101
+ 设计数值、交互脚本的行为。配套命令行工具(装完这个包就能用):
102
+
103
+ ```bash
104
+ npx agentcss ai components --json # 列出全部 40 个组件
105
+ npx agentcss ai check page.html --json # 检查你写出来的页面合不合规范
106
+ npx agentcss ai shot page.html --width=390,1440 # 按真实手机宽度截图
107
+ npx agentcss ai scaffold report/finance # 生成一页报表的最小骨架
108
+ ```
109
+
110
+ 流程就是:**读说明书 → 出骨架 → 填内容 → 自己检查**。最后一步不是可选项——
111
+ "写完了"和"写对了"是两件事。
112
+
113
+ ---
114
+
115
+ *本文数字的出处:组件数来自 `ai/components.json`;检查项数以 `05-audit/check-all.sh`
116
+ 实际注册为准;样式预算见 `docs/BUDGET.md`。均为 2026-11-05 的实测值。*
package/docs/L10N.md ADDED
@@ -0,0 +1,92 @@
1
+ # 本地化(L10N)文案覆盖
2
+
3
+ > **一句话**:库默认输出中文;把 `labels` 传进去就能换掉**用户看得见、读屏会念到**的文案。
4
+ > 不传时输出与 0.25.x **逐字相同** —— 升级不会静默改变界面文字。
5
+
6
+ ```html
7
+ <script src="03-patterns/pagination/pagination.js"></script>
8
+ <script>
9
+ Pagination.create(document.querySelector('[data-pagination]'), {
10
+ labels: { prev: 'Previous', next: 'Next',
11
+ page: function (p, cur) { return 'Page ' + p + (cur ? ' (current)' : ''); } }
12
+ });
13
+ </script>
14
+ ```
15
+
16
+ 值可以是字符串,也可以是函数(动态量用函数,例如页码、百分比)。
17
+
18
+ ---
19
+
20
+ ## 一、哪些文案**在**覆盖范围内
21
+
22
+ | 组件 | 入口 | 键 |
23
+ |---|---|---|
24
+ | `overlay` | `Overlay.toast({ labels })` | `closeToast` |
25
+ | `drawer` | `Drawer.open({ labels })` | `dialog`(无标题时的名字)、`close` |
26
+ | `pagination` | `Pagination.create(node, { labels })` | `nav`、`prev`、`next`、`page(p, isCurrent)`、`status(page, pages)`、`live(page, pages)` |
27
+ | `upload` | `new Upload(root, { labels })` | `pending`、`done`、`error`、`remove(name)`、`uploading(pct)`、`countMax(n)`、`sizeMax(limit)`、`type`、`folder`、`none(reason)`、`noDrop`、`noDropShort`、`summary(added,total,rejected)`、`removed(name,rest)` |
28
+ | `select` | `Select.create(root, { labels })` | `option`、`placeholder` |
29
+ | `combobox` | `Combobox.create(root, { labels })` | `suggest`、`input`、`noMatch(query)`、`empty` |
30
+ | `date-range` | `DateRange.create(root, { labels })` | `requiredEnd`、`requiredStart`、`order(from,to)`、`min(min)`、`max(max)` |
31
+ | `dropdown` | `Dropdown.create(root, { labels })` | `menu` |
32
+ | `tree` | `Tree.create(root, { labels })` | `tree` |
33
+ | `nav` | `Nav.attach(root, { labels })` | `open`、`close` |
34
+ | `tooltip` | `Tooltip.setLabels({ region })` | `region` |
35
+ | `model-viewer` | `ModelViewer.setLabels({ … })` | `load`、`placeholder`、`retry`、`preparing`、`preparingEngine`、`hintBefore`、`hintBetween`、`hintStrong`、`hintTail`、`downloading(pct)`、`noWebGL` |
36
+ | `bar` | `Bar.draw({ text })` ⚠️ | `series(i)`、`clipped(n, isStack, max)` |
37
+
38
+ `label` / `ariaLabel` 这类**单值**参数仍然有效,且优先于 `labels` ——
39
+ 它们是既有 API,不为统一而破坏兼容。
40
+
41
+ ### ⚠️ `bar` 为什么叫 `text` 而不是 `labels`
42
+
43
+ `bar.draw` 的 `labels` **早就是「X 轴标签」这个数据参数**(`labels: string[]`)。
44
+ 把同一个名字改成文案对象是破坏性变更,所以这里的文案覆盖用 `text`。
45
+ 全库只此一处例外,`types/index.d.ts` 里 `BarText` 有同样的注释。
46
+
47
+ ### 没有逐实例入口的组件
48
+
49
+ `tooltip` 与 `model-viewer` 由属性自动初始化(`data-tooltip` / `data-mv`),
50
+ 没有"传 opts 的地方",所以用**模块级**的 `setLabels()`。
51
+ 设置一次影响该页面上后续创建的所有实例;已经创建的不受影响。
52
+
53
+ ---
54
+
55
+ ## 二、哪些**不在**覆盖范围内(不假装已做完)
56
+
57
+ 1. **开发期错误信息**:`throw new Error('upload: 缺少 .upload__input …')`。
58
+ 它们面向调用方(写代码的人),不经过 UI,也不该由终端用户看到。
59
+ 要统一英文请改源码 —— 这不属于 L10N。
60
+ 2. **`model-viewer` 的失败说明与底部说明句**:
61
+ `fail()` 的几条错误文案、`mv__cap` 里的「引擎就绪耗时 … ms」。
62
+ 它们含 `<b>` 结构与多个动态量,要安全本地化得先改成节点拼装,
63
+ 属独立改造,**当前仍是中文**。
64
+ 3. **`echarts-adapter` 的控制台提示**:`[frontend-lib] 系列数 …`,
65
+ 属开发者提示,同上。
66
+
67
+ 这份清单由 `05-audit/i18n-labels-gate.js` 守着:库代码里再出现
68
+ 「中文字面量直接进 `aria-label` / `textContent` / `el()` 文本位」就红,
69
+ 要新增必须先回答"用户会看到吗"。
70
+
71
+ ---
72
+
73
+ ## 三、为什么默认不改英文
74
+
75
+ - **不制造惊喜**:升级补丁版本就换掉界面语言,是比"没本地化"更糟的破坏。
76
+ - **不猜语言环境**:`navigator.language` 在 SSR、WebView、隐私模式下都不可靠,
77
+ 自动切换会让同一份代码在不同机器上显示不同语言,问题极难复现。
78
+ - **真要做多语言**,正确做法是调用方在启动时按自己的语言包调 `setLabels` /
79
+ 传 `labels` —— 词汇表由产品决定,不由组件库猜。
80
+
81
+ ---
82
+
83
+ ## 四、门禁
84
+
85
+ | 门禁 | 判什么 |
86
+ |---|---|
87
+ | `i18n-labels` | 静态:库代码 0 处硬编码用户文案(注释与 `throw` 不在视野) |
88
+ | `i18n-labels`(运行时) | 真浏览器里传 `labels` ⇒ DOM 真的变了;不传 ⇒ 仍是各组件的中文默认值 |
89
+ | `i18n-labels-rev` | 判据自检:三种写法都要抓到;变量/注释/`throw` 不误报;元反向 |
90
+
91
+ 运行时那半条**必须先看默认值**:只断言"覆盖后等于测试串"是不够的 ——
92
+ 如果把测试串直接写进源码,那条断言照样绿。
@@ -34,7 +34,7 @@
34
34
  不是手抄的,也不是推测的:探针页把结果 **POST 回采集端**,落成 JSON 后原样贴进表格。
35
35
  手机访问 `http://<电脑内网地址>:端口` 属于**非安全上下文**,
36
36
  `navigator.clipboard` 在那里根本不存在 —— 所以页面提供的是"发送到电脑"(同源 POST)作为主路径,
37
- 剪贴板只作备用(详见 `ERRORS.md` E47)。
37
+ 剪贴板只作备用。
38
38
 
39
39
  ---
40
40
 
@@ -163,7 +163,7 @@ Android 上 Chrome ≠ 系统 WebView ≠ 各家 App 内置 WebView。**入口
163
163
 
164
164
  「iOS 16.4 才支持某个特性」这类说法在本文件里没有位置,原因很直接:
165
165
  我没有在真机上验证过它,写下来就会被下一个人当成事实引用
166
- (`ERRORS.md` E13 记过一类同源事故:文档里的结论没人回来复核,最后整份文档都在骗人)。
166
+ (一类同源事故:文档里的结论没人回来复核,最后整份文档都在骗人)。
167
167
 
168
168
  ⇒ 需要版本结论时,**跑一次探针页**,用那一次的 UA 与结果说话。
169
169
  UA 是证据,版本传闻不是。
package/docs/PRINT.md CHANGED
@@ -291,8 +291,8 @@ L3 声明→生效 在真浏览器的 print 媒体下量标本页的计算值
291
291
  ```
292
292
 
293
293
  反向控制 7 条(覆盖四条腿),其中两条是历史事故的**逐字复刻**:
294
- E254(去掉 `.tabs ` 前缀,让组件 CSS 同特异性盖掉它)与
295
- E255(只删 `visibility: visible`,display 与高度全对、一个字不印)。
294
+ 去掉 `.tabs ` 前缀,让组件 CSS 同特异性盖掉它;以及
295
+ 只删 `visibility: visible`,display 与高度全对、一个字不印。
296
296
 
297
297
  ### 内容完整性是**硬判据**(2026-11-02 起)
298
298
 
@@ -356,7 +356,7 @@ npx agentcss pdf report.html --out report.pdf --max-pages=8
356
356
 
357
357
  `--paper` 支持 `a4` / `letter` / `a5` / `a3` / `legal`。边距是 CSS 简写
358
358
  (`18mm`、`"18mm 15mm"`、四段都认)。这两个参数靠**注入一条 `@page` 规则**实现,
359
- 注入位置在使用者样式之后 —— 否则同特异性会被盖掉(E254 的同一个病)。
359
+ 注入位置在使用者样式之后 —— 否则同特异性会被盖掉(同一个病)。
360
360
 
361
361
  零运行时依赖:用使用者机器上**已装好的** Chrome / Chromium / Edge。
362
362
  找不到就明确报错(退出码 3),不静默降级成空文件。指定位置:
@@ -132,7 +132,7 @@ pack-smoke.sh # npm pack → 装进空项目 → 解析入口
132
132
 
133
133
  工作流按这个顺序落地:
134
134
 
135
- 1. 校验 tag 名 == `package.json.version`,检查 `NPM_TOKEN`;
135
+ 1. 校验 tag 名 == `package.json.version`,并确认 npm 足够新(OIDC 需 ≥ 11.5.1);
136
136
  2. `npm ci`;
137
137
  3. **probe**(只读):输出 `npm=… release=… provenance=…`;
138
138
  4. `publish:check`;
@@ -156,7 +156,7 @@ pack-smoke.sh # npm pack → 装进空项目 → 解析入口
156
156
 
157
157
  ⚠️ 第 8 步的回执必须**等 registry 索引**。`npm publish` 返回 0 之后,版本端点还要几十秒才可见;
158
158
  回执在发布后立刻跑,会拿到 `npm=absent` 并把一次成功的发布报成「未完成」。
159
- `release-run.sh verify` 现在对 `absent` 重试(默认 18 次 × 10 秒),
159
+ `release-run.sh verify` 现在对 `absent` 重试(默认 42 次 × 10 秒 = 420 秒),
160
160
  对 `unreadable` **不重试**(那是接口/网络问题,等下去也不会变)。
161
161
 
162
162
  这条不是推演,是 `v0.24.2` 第三次运行的现场:npm 与 Release 都建好了,
@@ -164,6 +164,56 @@ pack-smoke.sh # npm pack → 装进空项目 → 解析入口
164
164
  registry `integrity` 与 attestation `subject` 全部一致——产物是对的,
165
165
  错的是**回执比索引快**。
166
166
 
167
+ ⚠️ 预算必须**明显大于**实测最大值,不能贴着它设。`v0.26.0`(2026-11-05)是第二次:
168
+ `npm publish` 在 `08:15:34` 返回成功,registry 到 `08:18:40` 才索引到——**186 秒**,
169
+ 而当时的上界是 `17 × 10 = 170` 秒,回执在 `08:18:38` 放弃,比真相早 2 秒。
170
+ 后果:包已经发出去了,回执却写 `npm=absent`,要再跑一遍 14 分钟的门禁才能拿到绿。
171
+ ⇒ 现在的 420 秒是实测量级的 6 倍:慢只是多等,错判是回执说谎。
172
+
173
+ ### 5.1.1 事后改包(dist-tag 等):走 trusted publishing,不要走令牌
174
+
175
+ 发布完成后要改**包管理类**的状态(例如删一个 dist-tag),**不要**想着用发布令牌去做:
176
+
177
+ - 勾了「绕过两步验证」的细粒度令牌(GAT)自 2026-07 起只能发布写,做包管理删除会被
178
+ `403 Granular access tokens that bypass two-factor authentication may not perform this action` 挡住;
179
+ - npm 网页里**没有** dist-tag 管理入口(`/package/<pkg>/dist-tags` 是 404,
180
+ Versions 的 Current Tags 只有只读表格);
181
+ - 剩下唯一合法的口子是 **trusted publishing**:它的 Allowed actions 里明确有 `npm dist-tag`。
182
+
183
+ 本仓的落地方式(一次性运维,不影响发版):
184
+
185
+ 1. npm 包设置 → Trusted Publisher → GitHub Actions,
186
+ 仓库标识(`owner/repo`,见 `package.json` 的 `repository`)与 `release.yml`,
187
+ 勾 `npm publish` 与 `npm dist-tag`;
188
+ 2. `release.yml` 里的 `dist-tag-cleanup` job:只在 `workflow_dispatch` 且填了
189
+ `dist_tag_rm` 时跑;`id-token: write` 换 OIDC 凭证;先 `npm i -g npm@latest`
190
+ (OIDC 需 ≥ 11.5.1);**不要**给 `setup-node` 传 `registry-url`
191
+ (它会写一条空的 `_authToken` 行,值指向 `NODE_AUTH_TOKEN`,先撞 ENEEDAUTH,轮不到 OIDC);
192
+ 3. 触发:
193
+
194
+ ```bash
195
+ gh workflow run release.yml -f dist_tag_rm=<tag 名>
196
+ ```
197
+
198
+ 2026-11-05 实测:run 41997717147 success,`probe-2fa` 删除后只剩 `latest`。
199
+ 这条作业**不会**被 tag 推送触发(条件是 `github.event_name == 'workflow_dispatch'` 且输入非空)。
200
+
201
+ ### 5.1.2 发版本身的凭据:OIDC,没有任何长期令牌
202
+
203
+ 发版与上面的包管理动作共用同一套信任关系:npm 侧把 `release.yml` 登记为
204
+ trusted publisher(`Status: Valid`),工作流用 `id-token: write` 现换一次短期凭证。
205
+ **仓库里不再有任何 npm 令牌 secret**,也没有 7 天/90 天到期的东西会悄悄断掉发布。
206
+
207
+ 两条硬约束(都实测踩过,`release-gate.py` 的 `workflow_problems` 逐条守着):
208
+
209
+ 1. `setup-node` **不传** `registry-url` —— 它会写一行空的 `_authToken`(值指向
210
+ `NODE_AUTH_TOKEN`),npm 先撞 `ENEEDAUTH`,根本轮不到 OIDC;
211
+ 2. 必须 `npm install -g npm@latest` —— Node 22 自带 npm 10.x,OIDC 需要 ≥ 11.5.1。
212
+
213
+ `workflow_problems` 同时**反向**断言:谁把 `NPM_TOKEN` / `NODE_AUTH_TOKEN` /
214
+ `registry-url` 加回来,门禁立刻红。这不是风格检查——长期令牌模型在 2027-01
215
+ 会连直接发布权一起失效,留着它只是把断点推迟到下一次发版。
216
+
167
217
  ### 5.2 站点链(主分支触发)
168
218
 
169
219
  | 态 | 含义 | 探测方式 |
@@ -264,7 +314,13 @@ npm 与 Release 都是 absent ⇒ 删 tag、修夹具、在同一提交树上重
264
314
 
265
315
  ### 7.3 下一次真实发布要验的六条(提前固定,不许事后放宽)
266
316
 
267
- 回执的重试逻辑还没被真实发布走过。下一次打 tag 时,按这张表逐条判定:
317
+ `0.25.6` 的真实发布走通了**第 2 条**:`npm publish` 成功后 registry 索引延迟,
318
+ 回执对 `absent` 连续重试 13 次(每次约 10 秒)后拿到
319
+ `npm=present provenance=ok release=present`,退出码 0;既没误入
320
+ `unreadable` 分支,也没把重试次数用尽。这是这条修复第一次被真实发布走过。
321
+
322
+ 其余五条**仍只有 `release-run.sh --selftest` 的合成用例**,没有真实样本 ——
323
+ "没被触发过"不等于"验过了"。后续打 tag 继续按这张表逐条判定:
268
324
 
269
325
  | # | 场景 | 通过条件 |
270
326
  |---|---|---|
package/docs/STABILITY.md CHANGED
@@ -30,7 +30,7 @@
30
30
  | JS 成员不消失 | `Select.open()`、`AccordionOptions.duration` 这类名字 | `deprecation-gate.py` ⑦ + `api-contract-gate.py`(d.ts ↔ 运行时**实测**比对) |
31
31
  | 声明的名字真的存在 | 不许出现"文档里有、代码里没有"的幻觉 API | `gen-ai-contract.py --check`、`dead-class-gate.py` |
32
32
  | 行为事件名不消失 | `fl:select` 这类事件名 | 只记在基线里,**没有运行时探针**(见 §6) |
33
- | CLI 子命令与 `--json` 形状 | `agentcss ai <cmd> --json` 的 11 个子命令、失败也是 JSON | `ai-layer-gate.js` ⑥′⑥″ |
33
+ | CLI 子命令与 `--json` 形状 | `agentcss ai <cmd> --json` 的 14 个子命令、失败也是 JSON | `ai-layer-gate.js` ⑥′⑥″、`facts-gate.py`(计数从 `ai/cli.js` 现算) |
34
34
  | 契约文件字段 | `ai/components.json` / `pitfalls*.json` / `behaviors.json` | `gen-ai-contract --check`、`ai-layer-gate` ⑦ |
35
35
  | 文件路径 | `02-primitives/button/button.css` 这类 `<link>` 直接指向的路径 | `dist-parity-check`、`pack-smoke.sh`、`assets-catalog-gate.py` |
36
36
  | 体积承诺 | 全库生效 CSS ≤ 172 KB,常规增长不涨价 | `perf-gate.py` + `budget-selftest.py`(见 [BUDGET.md](BUDGET.md)) |
@@ -110,12 +110,17 @@ gh api 'repos/{owner}/{repo}/deployments?environment=github-pages&per_page=1' \
110
110
  |---|---|---|---|
111
111
  | L0 声明 | 「我声明它来自 X」 | 文档、CHANGELOG、tag 消息 | 声明是否为真 |
112
112
  | L1 抽样 | 「我抽查了 N 个文件,都与 X 一致」 | 有人做过小样本抽查 | 未抽查的文件是否一致 |
113
- | L2 全量 | 「每一个文件都与 X 的对应文件一致」 | **不存在** | 构建过程是否被污染 |
113
+ | L2 全量 | 「每一个文件都与 X 的对应文件一致」 | `0.25.6` 起:npm 包的 335 个文件与提交树逐字节比对,0 处不一致;**站点全量仍未做** | 构建过程是否被污染 |
114
114
  | L3 密码学 | 「这个 tarball 由这条 workflow、这个提交构建」 | npm provenance(SLSA provenance v1) | 仓库之外的东西 |
115
115
 
116
116
  三条必须说清的话:
117
117
 
118
- 1. **没有 L2。** 既没有逐个文件比对过 tarball 与提交,也没有比对过站点全量。因此「包内每个文件都来自该提交」这句话目前**说不出口**。
118
+ 1. **L2 只覆盖 npm 包,而且锚定在版本快照上。** `0.25.6` 发布后把真 tarball
119
+ 的 335 个文件逐个与 `0668838…` 提交树比对,0 处不一致 ⇒ 对**那一版**
120
+ 可以说「包内每个文件都来自该提交」。两个边界必须一起说清:
121
+ ① 站点全量从来没有比过;② 主分支后续的文档修正属于滚动更新,
122
+ 不改变已发布快照,也不让这句结论自动延伸到以后的版本。
123
+ 每次发布都要重新做一次全量比对,不能拿上一次的结果顶。
119
124
  2. **站点不是 npm 包的镜像。** 两个渠道发布的文件集本来就不同(包里有 `dist/`、没有 `guide/`;站点有 `guide/` 与演示页、没有构建清单)。
120
125
  3. **同一版本号不保证同一内容。** 历史上出现过一次,见下一节。
121
126
 
@@ -165,3 +170,20 @@ a3d36f35ee748632ba05705e669ce950260dd81a3d32b5f3f46fadae0bd084ef # npm 包内
165
170
  ## 6. 更早的版本
166
171
 
167
172
  provenance 不是从第一个版本就有的。实测 `0.10.0` 的 attestation 接口返回 404 —— 这类版本只能核对 `gitHead`(L0),不要把它当作签名证据。
173
+
174
+ ---
175
+
176
+ ## 7. 已知偏差:2026-11-05 的历史重写
177
+
178
+ | 项 | 内容 |
179
+ |---|---|
180
+ | 发生了什么 | 仓库提交历史被重写一次,用于移除早期版本里误留的真实项目代号与本机用户名 |
181
+ | 受影响范围 | **`0.26.0` 及更早**的 provenance 里记录的 `gitCommit` |
182
+ | 具体表现 | 那个 SHA 在重写后的仓库里**不再是任何分支的祖先**;`git cat-file -p <sha>` 会报 `Not a valid object` |
183
+ | 仍然成立的部分 | npm 上的 attestation 本身**没有被改动**(sigstore 签名是不可变的)。它仍然能证明:这个 tarball 由本仓库的 `release.yml` 在某个提交上构建 |
184
+ | 从什么时候恢复正常 | `0.27.0` 起,provenance 的 `gitCommit` 与仓库历史一致 |
185
+ | GitHub 侧 | 旧提交会以**不可达对象**状态保留一段时间,知道 SHA 仍能按地址访问;之后由平台 GC。仓库已无任何 ref 指向它们 |
186
+
187
+ 核验旧版本时正确的读法:**签名证明"构建来源与工作流",不证明"那个提交现在还在仓库里"**。
188
+ 这两件事在重写前是重合的,重写后必须分开看 —— 本文件不打算把这一点藏起来。
189
+
package/index.html CHANGED
@@ -39,7 +39,7 @@ li a:active { background: var(--surface-sunken); }
39
39
  <li><a href="02-primitives/choice/demo.html">checkbox / radio / select</a><span class="r__p">单选/多选/原生 select 外观的统一控件</span></li>
40
40
  <li><a href="02-primitives/combobox/demo.html">combobox · 组合框 / 标签输入</a><span class="r__p">可搜索 + 可多选标签的输入控件</span></li>
41
41
  <li><a href="02-primitives/date-range/demo.html">date-range · 日期区间</a><span class="r__p">日期区间选择,含预设快捷范围</span></li>
42
- <li><a href="02-primitives/delta/demo.html">delta · 变化量</a><span class="r__p">变化量:涨跌方向 + 符号 + 颜色。只描述往哪边变,不判断好坏(等于好恶是 badge 的事,会计正负是 ta</span></li>
42
+ <li><a href="02-primitives/delta/demo.html">delta · 变化量</a><span class="r__p">变化量:涨跌方向 + 符号 + 颜色。</span></li>
43
43
  <li><a href="02-primitives/input/demo.html">input / field</a><span class="r__p">文本输入及其标签/帮助/错误三件套</span></li>
44
44
  <li><a href="02-primitives/metric/demo.html">metric · 指标块</a><span class="r__p">指标块:一个标签 + 一个值 + 一句上下文。数字等宽、单位分离、缺数是一等状态</span></li>
45
45
  <li><a href="02-primitives/popover/demo.html">popover · 气泡卡片</a><span class="r__p">锚定到触发元素的浮层</span></li>
@@ -48,7 +48,7 @@ li a:active { background: var(--surface-sunken); }
48
48
  <li><a href="02-primitives/separator/demo.html">separator · 分隔线</a><span class="r__p">分隔线,可带中间文字</span></li>
49
49
  <li><a href="02-primitives/skeleton/demo.html">skeleton · 骨架屏</a><span class="r__p">加载占位骨架</span></li>
50
50
  <li><a href="02-primitives/switch/demo.html">switch · 开关</a><span class="r__p">开关切换</span></li>
51
- <li><a href="02-primitives/timeline/demo.html">timeline · 时间轴</a><span class="r__p">时间轴:按时间排的事件序列(公告 / 大事记 / 版本记录)。顺序即信息,用 ol;状态交给 badge,颜色在</span></li>
51
+ <li><a href="02-primitives/timeline/demo.html">timeline · 时间轴</a><span class="r__p">时间轴:按时间排的事件序列(公告 / 大事记 / 版本记录)。</span></li>
52
52
  <li><a href="02-primitives/upload/demo.html">upload · 文件上传</a><span class="r__p">文件上传:零 JS 的原生形态 + 拖放/多文件/校验的增强形态</span></li>
53
53
  </ul>
54
54
 
@@ -97,7 +97,7 @@ li a:active { background: var(--surface-sunken); }
97
97
  </p>
98
98
  </main>
99
99
  <footer class="wrap">
100
- <p class="note">0.25.6 · 零第三方运行时依赖</p>
100
+ <p class="note">0.27.0 · 零第三方运行时依赖</p>
101
101
  </footer>
102
102
  </body>
103
103
  </html>
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.6**.
3
+ > Generated from `ai/components.json` + `ai/pitfalls*.json` + `ai/behaviors.json` at version **0.27.0**.
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
 
@@ -16,10 +16,24 @@ npx agentcss ai pitfalls --json --component=table
16
16
  npx agentcss ai tokens --json --set=dark
17
17
  npx agentcss ai tree --json --set=dark --cat=color
18
18
  npx agentcss ai validate <file> --schema=components --json
19
- npx agentcss ai check <doc.json> --profile=strict --json
19
+ npx agentcss ai check <doc.json> --profile=strict --json # the plan
20
+ npx agentcss ai check <page.html> --json # the artifact
21
+ npx agentcss ai scaffold report/finance --out report.html # skeleton only
22
+ npx agentcss ai shot <page.html> --out shot-{width}.png --width=390,1440 --full
23
+ npx agentcss ai pdf <page.html> --out page.pdf # zero deps: your Chrome
20
24
  ```
21
25
 
22
- Every subcommand accepts `--json`; failures print `{"ok":false,...}` and exit non-zero.
26
+ Every subcommand accepts `--json`. On failure it prints *one* JSON document —
27
+ `{"ok":false,"command":"…","error":{"kind":"…","message":"…"}}` — so a pipeline can
28
+ never mistake an error for data. Exit codes are one table for the whole CLI:
29
+ `0` pass · `1` the thing you checked is bad (a verdict, not a tool failure) ·
30
+ `2` bad flag or value (unknown flag, unknown enum value, empty value, repeated flag) ·
31
+ `3` environment missing · `4` render failed · `5` over budget · `6` tool bug.
32
+ `check <page.html>` is static (no network, no browser) and reports undefined class names,
33
+ stylesheets that were never linked, missing `img alt` / table name / `th scope`, skipped
34
+ heading levels and the per-layout obligations in `ai/recipes.json`. `shot` drives your
35
+ installed Chrome over a debugging pipe: the viewport is exactly the width you asked for,
36
+ and it reports horizontal overflow plus JS errors.
23
37
 
24
38
  ## 2 · Components (40)
25
39
 
@@ -32,7 +46,7 @@ Every subcommand accepts `--json`; failures print `{"ok":false,...}` and exit no
32
46
  | `scientific-plot` | `splot` | asset | stable | 3.9 KB | `scientific-plot.js` | 二维科学绘图:折线/区间带/对数轴,纯令牌驱动、零依赖 | `chart-multiline-label` |
33
47
  | `sparkline` | `sparkline` | asset | stable | 7.2 KB | `sparkline.js` | 迷你趋势图:无坐标轴、纯形状,适合表格内嵌的一行走势 | `chart-multiline-label` |
34
48
  | `accordion` | `accordion` | pattern | stable | 18.0 KB | `accordion.js` | 可折叠分组 | — |
35
- | `content` | `prose` | pattern | stable | 11.1 KB | — | 长文排版容器(标题/段落/列表/引用/代码) | `single-scroll-container` `line-height-constant-sync` |
49
+ | `content` | `prose` | pattern | stable | 11.9 KB | — | 长文排版容器(标题/段落/列表/引用/代码) | `single-scroll-container` `line-height-constant-sync` |
36
50
  | `drawer` | `drawer` | pattern | stable | 5.9 KB | `drawer.js` | 侧边抽屉,含遮罩 | `fixed-element-inventory` |
37
51
  | `dropdown` | `dd` | pattern | stable | 3.9 KB | `dropdown.js` | 下拉菜单 | `popover-measure-after-render` |
38
52
  | `form-validation` | `form` | pattern | stable | 11.8 KB | — | 表单校验反馈与错误汇总 | — |
package/llms.txt CHANGED
@@ -21,22 +21,43 @@ npx agentcss ai tokens --json --set=dark
21
21
  npx agentcss ai pitfalls --json --component=table
22
22
  npx agentcss ai validate ai/components.json --schema=components --json
23
23
  npx agentcss ai check page.json --profile=strict --json
24
+ npx agentcss ai check page.html --json # check the page you actually wrote
25
+ npx agentcss ai scaffold report/finance --out report.html # minimal shell (skeleton, no content)
26
+ npx agentcss ai shot page.html --out shot-{width}.png --width=390,1440 --full
27
+ # PNG at exact viewport widths
24
28
  npx agentcss ai pdf page.html --out page.pdf --max-pages=8 # HTML → PDF (zero deps: uses your Chrome)
25
29
  ```
26
30
 
31
+ `check <doc.json>` and `check <page.html>` answer **different** questions: the JSON one
32
+ validates the *plan* (node kinds, component maturity, paper obligations), the HTML one
33
+ validates the *artifact* — class names that the library does not define, stylesheets that
34
+ were never linked, missing `img alt` / table name / `th scope`, skipped heading levels,
35
+ and the per-layout obligations in `ai/recipes.json`. Both are static: no network, no browser.
36
+
37
+ `shot` drives your installed Chrome over a debugging pipe (no port, no bundled browser) so
38
+ the viewport is **exactly** the width you asked for, and reports horizontal overflow plus
39
+ JS errors. Same machine + same flags ⇒ byte-identical PNG (that is what the gate checks).
40
+
27
41
  Print / PDF: `--medium=paper` is the obligation switch — only then are `printPolicy`
28
42
  and `pageBudget` enforced. Per-component paper behaviour lives in
29
43
  `ai/components.json` → `printPolicy`. `@page` is owned by the exporter, not the library.
30
44
 
31
- Every subcommand accepts `--json`. On failure it prints
32
- `{"ok":false,"command":"…","error":{"kind":"…","message":"…"}}` and exits non-zero,
33
- so a pipeline can never mistake an error for data.
45
+ Every subcommand accepts `--json`. On failure it prints *one* JSON document —
46
+ `{"ok":false,"command":"…","error":{"kind":"…","message":"…"}}` — and exits non-zero,
47
+ so a pipeline can never mistake an error for data. There is exactly one failure shape;
48
+ the `kind` values map to exit codes: `1` verdict-negative (`findings`), `2` bad usage,
49
+ `3` environment missing, `4` render failed, `5` over budget, `6` tool bug.
50
+
51
+ Enum flags (`--set`, `--cat`, `--maturity`, `--profile`, `--medium`, `--recipe`) reject
52
+ an unknown value, an empty value, and a repeated occurrence with exit `2`. Flags a
53
+ subcommand does not understand are rejected too — they are never silently ignored.
34
54
 
35
55
  `pitfalls` needs `agentcss@0.21.0+`: `npx` resolves the *published* version, which can lag
36
56
  this repository. If a subcommand is missing, check `npx agentcss --version` first.
37
57
 
38
- There is **no MCP server**: the CLI is the whole interface (read-only queries, no daemon,
39
- no second copy of the contract to keep in sync). See `ai/START-HERE.md` §7.
58
+ There is **no MCP server**: the CLI is the whole interface (no daemon, no network,
59
+ no second copy of the contract to keep in sync). `scaffold` and `shot` write only the file
60
+ you name; every other subcommand is a read-only query. See `ai/START-HERE.md` §7.
40
61
 
41
62
  ## Use it in a page
42
63
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentcss",
3
- "version": "0.25.6",
3
+ "version": "0.27.0",
4
4
  "description": "移动 Web 组件库:CSS + 可选行为脚本,零第三方运行时依赖。样式用 bundler 引入,交互行为用 script 标签引入。",
5
5
  "keywords": [
6
6
  "css",
@@ -20,6 +20,7 @@
20
20
  "exports": {
21
21
  ".": {
22
22
  "types": "./types/index.d.ts",
23
+ "import": "./esm/index.mjs",
23
24
  "default": "./esm/index.mjs"
24
25
  },
25
26
  "./tokens.css": "./dist/01-tokens/tokens.css",
@@ -93,6 +94,7 @@
93
94
  "scripts": {
94
95
  "test": "node --test 05-audit/unit.test.mjs 05-audit/behavior-cores.test.mjs",
95
96
  "gate": "bash 05-audit/check-all.sh",
97
+ "gate:pre-commit": "bash 05-audit/check-all.sh --pre-commit",
96
98
  "gate:fast": "bash 05-audit/check-all.sh --fast",
97
99
  "gate:timing": "bash 05-audit/check-all.sh --timing",
98
100
  "ci:observe": "python3 05-audit/nightly-observe.py",
@@ -116,7 +118,7 @@
116
118
  "pixelmatch": "^5.3.0",
117
119
  "playwright": "^1.49.1",
118
120
  "pngjs": "^7.0.0",
119
- "puppeteer-core": "^23.11.1",
121
+ "puppeteer-core": "^25.16.0",
120
122
  "typescript": "^5.9.3",
121
123
  "yaml": "^2.9.1"
122
124
  },