@icen.ai/ui 0.9.0 → 0.10.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 (281) hide show
  1. package/AGENTS.md +138 -80
  2. package/README.md +66 -91
  3. package/dist/base.css +208 -179
  4. package/dist/behaviors/accordion.mjs +8 -8
  5. package/dist/behaviors/ai-branch.d.mts +1 -1
  6. package/dist/behaviors/ai-branch.mjs +1010 -94
  7. package/dist/behaviors/ai-chat.d.mts +7 -7
  8. package/dist/behaviors/ai-chat.mjs +1071 -161
  9. package/dist/behaviors/ai-composer.d.mts +44 -12
  10. package/dist/behaviors/ai-composer.mjs +1997 -524
  11. package/dist/behaviors/ai-core.d.mts +1 -1
  12. package/dist/behaviors/ai-core.mjs +1016 -107
  13. package/dist/behaviors/ai-diff.mjs +1019 -127
  14. package/dist/behaviors/ai-feedback.d.mts +1 -1
  15. package/dist/behaviors/ai-feedback.mjs +1035 -126
  16. package/dist/behaviors/ai-panel.d.mts +8 -8
  17. package/dist/behaviors/ai-panel.mjs +1284 -266
  18. package/dist/behaviors/ai-provider.mjs +1003 -101
  19. package/dist/behaviors/ai-threads.d.mts +1 -1
  20. package/dist/behaviors/ai-threads.mjs +1068 -154
  21. package/dist/behaviors/ai-tool.d.mts +2 -2
  22. package/dist/behaviors/ai-tool.mjs +2037 -396
  23. package/dist/behaviors/ai-tools.d.mts +89 -16
  24. package/dist/behaviors/ai-tools.mjs +4448 -372
  25. package/dist/behaviors/autocomplete.d.mts +53 -0
  26. package/dist/behaviors/autocomplete.mjs +1600 -0
  27. package/dist/behaviors/back-top.d.mts +1 -1
  28. package/dist/behaviors/back-top.mjs +951 -14
  29. package/dist/behaviors/carousel.d.mts +1 -1
  30. package/dist/behaviors/carousel.mjs +906 -11
  31. package/dist/behaviors/cascader.d.mts +48 -0
  32. package/dist/behaviors/cascader.mjs +1853 -0
  33. package/dist/behaviors/charts.d.mts +72 -8
  34. package/dist/behaviors/charts.mjs +1901 -256
  35. package/dist/behaviors/code-block.d.mts +36 -0
  36. package/dist/behaviors/code-block.mjs +1611 -0
  37. package/dist/behaviors/command-palette.d.mts +9 -6
  38. package/dist/behaviors/command-palette.mjs +161 -59
  39. package/dist/behaviors/context-menu.d.mts +9 -8
  40. package/dist/behaviors/context-menu.mjs +1112 -44
  41. package/dist/behaviors/controls.d.mts +13 -13
  42. package/dist/behaviors/controls.mjs +989 -130
  43. package/dist/behaviors/copy.d.mts +21 -2
  44. package/dist/behaviors/copy.mjs +1206 -42
  45. package/dist/behaviors/datatable.d.mts +53 -3
  46. package/dist/behaviors/datatable.mjs +1963 -207
  47. package/dist/behaviors/date-picker.d.mts +0 -1
  48. package/dist/behaviors/date-picker.mjs +1340 -293
  49. package/dist/behaviors/design.d.mts +54 -0
  50. package/dist/behaviors/design.mjs +109 -0
  51. package/dist/behaviors/dropdown.d.mts +5 -6
  52. package/dist/behaviors/dropdown.mjs +262 -110
  53. package/dist/behaviors/events.d.mts +120 -3
  54. package/dist/behaviors/events.mjs +47 -2
  55. package/dist/behaviors/feedback.d.mts +30 -0
  56. package/dist/behaviors/feedback.mjs +296 -0
  57. package/dist/behaviors/focus.d.mts +8 -0
  58. package/dist/behaviors/focus.mjs +24 -0
  59. package/dist/behaviors/form-validate.d.mts +102 -0
  60. package/dist/behaviors/form-validate.mjs +6091 -0
  61. package/dist/behaviors/i18n.d.mts +789 -0
  62. package/dist/behaviors/i18n.mjs +1711 -0
  63. package/dist/behaviors/icons.d.mts +93 -0
  64. package/dist/behaviors/icons.mjs +113 -0
  65. package/dist/behaviors/input.d.mts +9 -1
  66. package/dist/behaviors/input.mjs +1056 -60
  67. package/dist/behaviors/kb-access.d.mts +1 -1
  68. package/dist/behaviors/kb-access.mjs +2129 -239
  69. package/dist/behaviors/kb-acl.d.mts +6 -6
  70. package/dist/behaviors/kb-acl.mjs +1119 -179
  71. package/dist/behaviors/kb-answer.mjs +2070 -418
  72. package/dist/behaviors/kb-audit.d.mts +1 -1
  73. package/dist/behaviors/kb-audit.mjs +1076 -154
  74. package/dist/behaviors/kb-canvas.mjs +1100 -177
  75. package/dist/behaviors/kb-chain.mjs +1022 -100
  76. package/dist/behaviors/kb-checkpoint.d.mts +1 -1
  77. package/dist/behaviors/kb-checkpoint.mjs +1319 -169
  78. package/dist/behaviors/kb-chunks.mjs +1152 -213
  79. package/dist/behaviors/kb-citation.d.mts +1 -1
  80. package/dist/behaviors/kb-citation.mjs +1201 -179
  81. package/dist/behaviors/kb-clarify.mjs +1058 -130
  82. package/dist/behaviors/kb-conflict.mjs +1041 -119
  83. package/dist/behaviors/kb-connector.mjs +1104 -176
  84. package/dist/behaviors/kb-core.d.mts +6 -1
  85. package/dist/behaviors/kb-core.mjs +1077 -162
  86. package/dist/behaviors/kb-eval.mjs +1971 -144
  87. package/dist/behaviors/kb-explain.d.mts +1 -1
  88. package/dist/behaviors/kb-explain.mjs +1024 -102
  89. package/dist/behaviors/kb-filter.mjs +2008 -178
  90. package/dist/behaviors/kb-gap.d.mts +1 -1
  91. package/dist/behaviors/kb-gap.mjs +1043 -121
  92. package/dist/behaviors/kb-hittest.d.mts +1 -1
  93. package/dist/behaviors/kb-hittest.mjs +1093 -150
  94. package/dist/behaviors/kb-metadata.mjs +1052 -130
  95. package/dist/behaviors/kb-passage.d.mts +2 -2
  96. package/dist/behaviors/kb-passage.mjs +1101 -161
  97. package/dist/behaviors/kb-pipeline.d.mts +2 -2
  98. package/dist/behaviors/kb-pipeline.mjs +1082 -162
  99. package/dist/behaviors/kb-qa.mjs +1088 -160
  100. package/dist/behaviors/kb-rerank.mjs +1047 -114
  101. package/dist/behaviors/kb-retrieval.mjs +2063 -224
  102. package/dist/behaviors/kb-review.mjs +1990 -159
  103. package/dist/behaviors/kb-sandbox.d.mts +1 -1
  104. package/dist/behaviors/kb-sandbox.mjs +1026 -104
  105. package/dist/behaviors/kb-segment.mjs +1111 -179
  106. package/dist/behaviors/kb-select.d.mts +24 -0
  107. package/dist/behaviors/kb-select.mjs +1989 -0
  108. package/dist/behaviors/kb-sources.d.mts +1 -1
  109. package/dist/behaviors/kb-sources.mjs +1084 -170
  110. package/dist/behaviors/kb-sql.d.mts +1 -1
  111. package/dist/behaviors/kb-sql.mjs +1143 -226
  112. package/dist/behaviors/kb-trace.d.mts +1 -1
  113. package/dist/behaviors/kb-trace.mjs +1042 -128
  114. package/dist/behaviors/kb-visibility.mjs +1086 -158
  115. package/dist/behaviors/kb-who-can.mjs +1974 -137
  116. package/dist/behaviors/mentions.d.mts +93 -0
  117. package/dist/behaviors/mentions.mjs +2152 -0
  118. package/dist/behaviors/modal.d.mts +4 -3
  119. package/dist/behaviors/modal.mjs +1055 -33
  120. package/dist/behaviors/nav.d.mts +1 -1
  121. package/dist/behaviors/nav.mjs +6 -6
  122. package/dist/behaviors/notification.d.mts +16 -8
  123. package/dist/behaviors/notification.mjs +1615 -265
  124. package/dist/behaviors/panel.d.mts +4 -0
  125. package/dist/behaviors/panel.mjs +994 -0
  126. package/dist/behaviors/popover.d.mts +28 -5
  127. package/dist/behaviors/popover.mjs +225 -24
  128. package/dist/behaviors/select.d.mts +5 -2
  129. package/dist/behaviors/select.mjs +1410 -117
  130. package/dist/behaviors/sidebar.d.mts +1 -1
  131. package/dist/behaviors/sidebar.mjs +13 -13
  132. package/dist/behaviors/slider.d.mts +1 -1
  133. package/dist/behaviors/slider.mjs +9 -9
  134. package/dist/behaviors/split-pane.d.mts +1 -1
  135. package/dist/behaviors/split-pane.mjs +7 -7
  136. package/dist/behaviors/suggestions.d.mts +27 -0
  137. package/dist/behaviors/suggestions.mjs +1089 -0
  138. package/dist/behaviors/svg-parse.d.mts +14 -0
  139. package/dist/behaviors/svg-parse.mjs +37 -0
  140. package/dist/behaviors/tabs.d.mts +2 -2
  141. package/dist/behaviors/tabs.mjs +25 -25
  142. package/dist/behaviors/tag-input.d.mts +23 -5
  143. package/dist/behaviors/tag-input.mjs +1359 -104
  144. package/dist/behaviors/theme-switcher.d.mts +24 -0
  145. package/dist/behaviors/theme-switcher.mjs +1981 -0
  146. package/dist/behaviors/theme.d.mts +15 -8
  147. package/dist/behaviors/theme.mjs +390 -28
  148. package/dist/behaviors/toast.d.mts +24 -25
  149. package/dist/behaviors/toast.mjs +1266 -88
  150. package/dist/behaviors/tooltip.d.mts +4 -0
  151. package/dist/behaviors/tooltip.mjs +378 -0
  152. package/dist/behaviors/tree-select.d.mts +69 -0
  153. package/dist/behaviors/tree-select.mjs +1907 -0
  154. package/dist/behaviors/tree.d.mts +1 -1
  155. package/dist/behaviors/tree.mjs +15 -15
  156. package/dist/behaviors/upload.d.mts +3 -2
  157. package/dist/behaviors/upload.mjs +1076 -66
  158. package/dist/cli.mjs +5 -6
  159. package/dist/components/ai-chat.css +666 -573
  160. package/dist/components/ai-diff.css +153 -132
  161. package/dist/components/ai-panel.css +351 -343
  162. package/dist/components/ai-tool.css +393 -238
  163. package/dist/components/autocomplete.css +61 -0
  164. package/dist/components/autocomplete.mjs +3 -0
  165. package/dist/components/back-top.css +34 -31
  166. package/dist/components/badge.css +44 -41
  167. package/dist/components/breadcrumb.css +67 -46
  168. package/dist/components/btn.css +80 -74
  169. package/dist/components/card.css +117 -106
  170. package/dist/components/cascader.css +311 -0
  171. package/dist/components/cascader.mjs +3 -0
  172. package/dist/components/chart-area.css +8 -2
  173. package/dist/components/chart-bar.css +95 -33
  174. package/dist/components/chart-gauge.css +14 -11
  175. package/dist/components/chart-graph.css +20 -17
  176. package/dist/components/chart-heatmap.css +96 -90
  177. package/dist/components/chart-line.css +8 -3
  178. package/dist/components/chart-pie.css +9 -6
  179. package/dist/components/chart-radar.css +8 -5
  180. package/dist/components/chart-scatter.css +9 -6
  181. package/dist/components/chart-sparkline.css +5 -2
  182. package/dist/components/chart-stack.css +14 -11
  183. package/dist/components/charts.css +164 -73
  184. package/dist/components/code-block.css +418 -0
  185. package/dist/components/code-block.mjs +4 -0
  186. package/dist/components/command-palette.css +138 -117
  187. package/dist/components/content.css +257 -251
  188. package/dist/components/copy.css +72 -44
  189. package/dist/components/datatable.css +423 -181
  190. package/dist/components/date-picker.css +135 -104
  191. package/dist/components/empty.css +68 -65
  192. package/dist/components/feedback.css +201 -183
  193. package/dist/components/form-validate.css +120 -0
  194. package/dist/components/form-validate.mjs +3 -0
  195. package/dist/components/form.css +150 -127
  196. package/dist/components/icon.css +102 -0
  197. package/dist/components/icon.mjs +3 -0
  198. package/dist/components/input.css +159 -104
  199. package/dist/components/kb-agent.css +188 -173
  200. package/dist/components/kb-data.css +257 -253
  201. package/dist/components/kb-ground.css +197 -185
  202. package/dist/components/kb-ingest.css +334 -350
  203. package/dist/components/kb-ops.css +265 -259
  204. package/dist/components/kb-perm.css +260 -271
  205. package/dist/components/kb-search.css +317 -360
  206. package/dist/components/kb.css +120 -109
  207. package/dist/components/layout.css +85 -82
  208. package/dist/components/material-chinese.css +73 -0
  209. package/dist/components/material-soviet.css +76 -0
  210. package/dist/components/material.css +275 -0
  211. package/dist/components/media.css +220 -166
  212. package/dist/components/mentions.css +189 -0
  213. package/dist/components/mentions.mjs +3 -0
  214. package/dist/components/menu.css +113 -105
  215. package/dist/components/modal.css +107 -112
  216. package/dist/components/nav.css +118 -115
  217. package/dist/components/notification.css +238 -174
  218. package/dist/components/pagination.css +56 -53
  219. package/dist/components/panel.css +66 -63
  220. package/dist/components/panel.mjs +1 -0
  221. package/dist/components/pill.css +81 -71
  222. package/dist/components/popover.css +67 -53
  223. package/dist/components/scroll-area.css +113 -110
  224. package/dist/components/segmented.css +146 -143
  225. package/dist/components/select.css +206 -186
  226. package/dist/components/sidebar.css +137 -127
  227. package/dist/components/slider.css +117 -114
  228. package/dist/components/split-pane.css +112 -109
  229. package/dist/components/stat.css +112 -106
  230. package/dist/components/steps.css +109 -103
  231. package/dist/components/switch.css +138 -134
  232. package/dist/components/table.css +131 -107
  233. package/dist/components/tabs.css +114 -108
  234. package/dist/components/tag-input.css +48 -133
  235. package/dist/components/tag.css +81 -71
  236. package/dist/components/theme-switcher.css +105 -0
  237. package/dist/components/theme-switcher.mjs +3 -0
  238. package/dist/components/toast.css +100 -86
  239. package/dist/components/toolbar.css +45 -42
  240. package/dist/components/tooltip.css +102 -43
  241. package/dist/components/tooltip.mjs +1 -0
  242. package/dist/components/tree-select.css +416 -0
  243. package/dist/components/tree-select.mjs +3 -0
  244. package/dist/components/upload.css +135 -92
  245. package/dist/fonts/LICENSES/ark-pixel/OFL.txt +96 -0
  246. package/dist/fonts/LICENSES/cubic-11/OFL.txt +108 -0
  247. package/dist/fonts/LICENSES/galmuri/LICENSE.txt +93 -0
  248. package/dist/fonts/OFL.txt +96 -0
  249. package/dist/fonts/README.md +14 -0
  250. package/dist/fonts/fusion-pixel-12px-zh-hans.woff2 +0 -0
  251. package/dist/index.d.mts +28 -14
  252. package/dist/index.mjs +20705 -9601
  253. package/dist/react.d.mts +91 -0
  254. package/dist/react.mjs +8208 -0
  255. package/dist/registry.json +130 -13
  256. package/dist/tokens/chinese.css +44 -0
  257. package/dist/tokens/colors.css +365 -1222
  258. package/dist/tokens/design.css +109 -0
  259. package/dist/tokens/dtcg.json +11198 -0
  260. package/dist/tokens/figma.variables.json +7017 -0
  261. package/dist/tokens/icon-masks.css +78 -0
  262. package/dist/tokens/pixel.css +50 -0
  263. package/dist/tokens/soviet.css +44 -0
  264. package/dist/tokens/style-profiles.css +36 -547
  265. package/dist/tokens/themes.json +308 -0
  266. package/dist/tokens/tokens-studio.json +6728 -0
  267. package/dist/tokens/typography.css +21 -18
  268. package/dist/tokens.css +1555 -1801
  269. package/dist/ui.css +11975 -9831
  270. package/dist/vue.d.mts +344 -0
  271. package/dist/vue.mjs +7781 -0
  272. package/docs/spec/ai-input-experience.md +75 -0
  273. package/docs/spec/ai-native.md +238 -147
  274. package/docs/spec/design-philosophy.md +189 -0
  275. package/docs/spec/design-primitives.md +196 -0
  276. package/docs/spec/kb-family.md +147 -115
  277. package/package.json +43 -8
  278. package/dist/retro-effects.css +0 -255
  279. package/dist/tokens/retro-effects.css +0 -255
  280. package/docs/research/2026-10-03-ai-kb-components.md +0 -392
  281. package/docs/research/2026-10-03-kb-permissions.md +0 -992
@@ -6,9 +6,9 @@
6
6
  ## 0. 定位与心智模型
7
7
 
8
8
  ```
9
- 通用原语(.btn/.table…) → 造任何界面
10
- ai-*(.ai-chat/.ai-tool…) → AI 的过程:「AI 在做什么」(消息/思考/工具/用量)
11
- kb-*(.kb-citation…) → 知识的证据与资产:「知识从哪来、可信吗、怎么用」
9
+ 通用原语(.icen-btn/.icen-table…) → 造任何界面
10
+ ai-*(.icen-ai-chat/.icen-ai-tool…) → AI 的过程:「AI 在做什么」(消息/思考/工具/用量)
11
+ kb-*(.icen-kb-citation…) → 知识的证据与资产:「知识从哪来、可信吗、怎么用」
12
12
  chart-* → 图形层(ChartSpec 纯 JSON)
13
13
  ```
14
14
 
@@ -17,19 +17,19 @@ chart-* → 图形层(ChartSpec 纯 JSON)
17
17
  ## 1. 设计原则(Apple 式直觉 → 本库落地)
18
18
 
19
19
  1. **一屏一个主行动**:每个视图只有一个 accent 级操作(检索 playground 的「运行」、chunk 编辑器的「保存」);其余动作沉为 ghost/图标钮。accent 是稀缺资源。
20
- 2. **证据是一等视觉元素**:数字一律等宽字体(`.kb-num`,tabular-nums);引文一律引用体(`.kb-quote`,左侧 2px 证据线);来源/分数/日期永不用装饰色——只用语义色与层级色(text / muted / faint)。
20
+ 2. **证据是一等视觉元素**:数字一律等宽字体(`.icen-kb-num`,tabular-nums);引文一律引用体(`.icen-kb-quote`,左侧 2px 证据线);来源/分数/日期永不用装饰色——只用语义色与层级色(text / muted / faint)。
21
21
  3. **渐进披露**:一切次要细节走「摘要行(状态徽章 + 时长/计数)+ muted 折叠体」两段式;摘要行承担状态机可视化;流式时展开、完成即折叠、用户展开过则不再自动收(与 ai-reasoning 同契约)。
22
- 4. **状态机先于样式**:每个组件先枚举状态(`.is-*` + `data-state`),UI 只是 state→(图标, 标签, 色阶, 动效) 的映射表。与 AI 族七态同构处直接复用语义。
23
- 5. **材料层级只用三档**:`--token-bg`(页面)→ `--token-bg-soft`(卡/行)→ 浮层(复用 popover/modal 的 portal 与 z 尺)。kb 族不自造阴影层级。
22
+ 4. **状态机先于样式**:每个组件先枚举状态(`.is-*` + `data-icen-state`),UI 只是 state→(图标, 标签, 色阶, 动效) 的映射表。与 AI 族七态同构处直接复用语义。
23
+ 5. **材料层级只用三档**:`--icen-token-bg`(页面)→ `--icen-token-bg-soft`(卡/行)→ 浮层(复用 popover/modal 的 portal 与 z 尺)。kb 族不自造阴影层级。
24
24
  6. **直接操纵**:能拖就拖(分段边界、双栏比例)、能行内编辑就行内编辑(chunk/SQL/过滤值)、能悬停预览就悬停(引用卡 300ms 防抖)。点击做深度验证,悬停做即时判读。
25
25
  7. **无死路**:每个失败态带重试(管线单文档重跑、SQL 一键修复)、每个空态带行动(无答案→建文档/加同义词、passages 空态→「引用段落将出现在这里」)。
26
26
  8. **诚实呈现边界**:截断声明(结果表 LIMIT)、无分命中(score null → 「—」)、权限受限(chunk 打码 + 申请访问)、不可逆操作前置警告(换 embedding 需重建索引)。
27
27
 
28
28
  ## 2. 视觉音调(跨域一致性的硬约束)
29
29
 
30
- - 尺寸节奏:行高 28px(.kb-row 默认)、区块间距 16px、组内 8px;密度 `data-density="compact|normal"`(compact 行高 24px)。
31
- - 圆角:容器 `--radius-md`、行内元素(角标/chip)`--radius-sm` 或全圆。
32
- - 字号:标题 13px/600、正文 13px、元信息 11.5px、徽标 10.5px;数字全部 `.kb-num`。
30
+ - 尺寸节奏:行高 28px(.icen-kb-row 默认)、区块间距 16px、组内 8px;密度 `data-icen-density="compact|normal"`(compact 行高 24px)。
31
+ - 圆角:容器 `--icen-radius-md`、行内元素(角标/chip)`--icen-radius-sm` 或全圆。
32
+ - 字号:标题 13px/600、正文 13px、元信息 11.5px、徽标 10.5px;数字全部 `.icen-kb-num`。
33
33
  - 色彩角色(族内纪律):
34
34
  - 证据域(ground)=accent(引用是主角,但角标默认弱化为 faint,hover/激活才点亮);
35
35
  - 过程域(ingest/search)=中性行 + 状态色只给状态点与徽标;
@@ -43,7 +43,7 @@ chart-* → 图形层(ChartSpec 纯 JSON)
43
43
 
44
44
  | 域 | CSS(自持) | behavior |
45
45
  |---|---|---|
46
- | 共享基座 | `components/kb.css`(.kb-row/.kb-num/.kb-score/.kb-quote/.kb-chip/徽标等,全部 kb slug 经 EXTRA_CSS 引入) | `behaviors/kb-core.ts`(类型 + 纯函数 + 注册表,无 UI 无副作用) |
46
+ | 共享基座 | `components/kb.css`(.icen-kb-row/.icen-kb-num/.icen-kb-score/.icen-kb-quote/.icen-kb-chip/徽标等,全部 kb slug 经 EXTRA_CSS 引入) | `behaviors/kb-core.ts`(类型 + 纯函数 + 注册表,无 UI 无副作用) |
47
47
  | 证据 ground | `components/kb-ground.css` | kb-citation.ts / kb-sources.ts / kb-passage.ts / kb-conflict.ts |
48
48
  | 摄取 ingest | `components/kb-ingest.css` | kb-pipeline.ts / kb-chunks.ts / kb-segment.ts / kb-connector.ts / kb-metadata.ts / kb-qa.ts |
49
49
  | 检索 search | `components/kb-search.css` | kb-retrieval.ts / kb-filter.ts / kb-rerank.ts / kb-hittest.ts |
@@ -64,19 +64,19 @@ chart-* → 图形层(ChartSpec 纯 JSON)
64
64
 
65
65
  ### 5.1 kb-citation 行内引用角标
66
66
  ```
67
- <button class="kb-citation" data-cite="3" aria-describedby?>3</button>
67
+ <button class="icen-kb-citation" data-icen-cite="3" aria-describedby?>3</button>
68
68
  ```
69
69
  - `parseInlineCitations(text)`(kb-core)把 `[3]` 文本切成段落流;`renderCitationMark(n)` 造角标。
70
- - `initKbCitation(root?)`:委托 click → `icen:kb-citation-open {citation}`;hover ≥300ms 且配置了 `getCard`/sources 时经 popover portal 浮 `.kb-citation-card`(favicon/标题/域名/citedText≤150 字/日期/徽标/受限打码)。
70
+ - `initKbCitation(root?)`:委托 click → `icen:kb-citation-open {citation}`;hover ≥300ms 且配置了 `getCard`/sources 时经 popover portal 浮 `.icen-kb-citation-card`(favicon/标题/域名/citedText≤150 字/日期/徽标/受限打码)。
71
71
  - 无效编号(>来源数)降级为纯文本角标(`.is-dead`,不可点)——「不信任模型生成编号」纪律。
72
72
 
73
73
  ### 5.2 kb-sources 来源列表
74
74
  ```
75
- <div class="kb-sources kb-sources--row|-rail">
76
- <button class="kb-source" data-kb-source-id>
77
- <span class="kb-source-icon">…svg…</span>
78
- <span class="kb-source-main"><span class="kb-source-title">…</span><span class="kb-source-sub">域名/类型 · 日期</span></span>
79
- <span class="kb-source-side">徽标组 + 被引 ×2</span>
75
+ <div class="icen-kb-sources kb-sources--row|-rail">
76
+ <button class="icen-kb-source" data-icen-kb-source-id>
77
+ <span class="icen-kb-source-icon">…svg…</span>
78
+ <span class="icen-kb-source-main"><span class="icen-kb-source-title">…</span><span class="icen-kb-source-sub">域名/类型 · 日期</span></span>
79
+ <span class="icen-kb-source-side">徽标组 + 被引 ×2</span>
80
80
  </button>…
81
81
  </div>
82
82
  ```
@@ -86,30 +86,30 @@ chart-* → 图形层(ChartSpec 纯 JSON)
86
86
 
87
87
  ### 5.3 kb-passage 原文定位查看器
88
88
  ```
89
- <aside class="kb-passage" hidden>
90
- <div class="kb-passage-head">标题 · 页码/位置 · <button data-kb-passage-close>×</button></div>
91
- <div class="kb-passage-body">原文…<mark class="kb-passage-hit">命中</mark>…<button data-kb-passage-expand>展开上下文</button></div>
89
+ <aside class="icen-kb-passage" hidden>
90
+ <div class="icen-kb-passage-head">标题 · 页码/位置 · <button data-icen-kb-passage-close>×</button></div>
91
+ <div class="icen-kb-passage-body">原文…<mark class="kb-passage-hit">命中</mark>…<button data-icen-kb-passage-expand>展开上下文</button></div>
92
92
  </aside>
93
93
  ```
94
94
  - `createKbPassage(el, opts)` → `{ open(citation|source), close(), highlight(terms), expand() }`。
95
- - 定位按 kb-core `KbLocation` 三分型(char/page/block);侧栏打开不打断对话;多命中分色(`data-hit="0|1|2"`)。
95
+ - 定位按 kb-core `KbLocation` 三分型(char/page/block);侧栏打开不打断对话;多命中分色(`data-icen-hit="0|1|2"`)。
96
96
  - 事件:`icen:kb-passage-jump {citation}`、`icen:kb-passage-close {}`。
97
97
 
98
98
  ### 5.4 kb-conflict 来源冲突组
99
99
  ```
100
- <div class="kb-conflict"><div class="kb-conflict-claim">同一主张…</div>
101
- <div class="kb-conflict-versions"><div class="kb-conflict-ver [is-current|is-older]">版本卡(日期/来源/official)</div>…</div></div>
100
+ <div class="icen-kb-conflict"><div class="icen-kb-conflict-claim">同一主张…</div>
101
+ <div class="icen-kb-conflict-versions"><div class="icen-kb-conflict-ver [is-current|is-older]">版本卡(日期/来源/official)</div>…</div></div>
102
102
  ```
103
103
  - `renderKbConflict(el, groups)`;`is-current` 高亮最新/官方,其余 faded + stale 徽标。市场空白组件。
104
104
 
105
105
  ### 5.5 kb-pipeline 解析管线时间线
106
106
  ```
107
- <div class="kb-pipeline" data-document-id>
108
- <div class="kb-pipeline-head">标题 · <span class="kb-pipeline-state is-done|is-running|is-fail">…</span> · N chunks · <button data-kb-pipeline-rerun>重跑</button></div>
109
- <ol class="kb-pipeline-steps">
110
- <li class="kb-pipeline-step is-done|is-running|is-fail|is-queued">icon · 解析 · 12s · <span class="kb-step-detail">3 页/2 表</span></li>…
107
+ <div class="icen-kb-pipeline" data-icen-document-id>
108
+ <div class="icen-kb-pipeline-head">标题 · <span class="icen-kb-pipeline-state is-done|is-running|is-fail">…</span> · N chunks · <button data-icen-kb-pipeline-rerun>重跑</button></div>
109
+ <ol class="icen-kb-pipeline-steps">
110
+ <li class="icen-kb-pipeline-step is-done|is-running|is-fail|is-queued">icon · 解析 · 12s · <span class="icen-kb-step-detail">3 页/2 表</span></li>…
111
111
  </ol>
112
- <div class="kb-pipeline-error">阶段定位 + 原因</div>
112
+ <div class="icen-kb-pipeline-error">阶段定位 + 原因</div>
113
113
  </div>
114
114
  ```
115
115
  - `renderKbPipeline(el, run|runs)`;`initKbPipeline(root?)` 委托展开(steps 折叠为摘要行)+ 重跑。
@@ -118,13 +118,13 @@ chart-* → 图形层(ChartSpec 纯 JSON)
118
118
 
119
119
  ### 5.6 kb-chunks chunk 编辑器
120
120
  ```
121
- <div class="kb-chunks">
122
- <div class="kb-chunks-bar">搜索(全文|语义 segmented)+ 新增</div>
123
- <div class="kb-chunk [is-off]">
124
- <label class="kb-chunk-switch"><input type="checkbox">启用</label>
125
- <div class="kb-chunk-content" contenteditable>…</div>
126
- <div class="kb-chunk-keywords">tag-input 式 chips</div>
127
- <div class="kb-chunk-meta">#3 · 第 2 页 · 向量就绪</div>
121
+ <div class="icen-kb-chunks">
122
+ <div class="icen-kb-chunks-bar">搜索(全文|语义 segmented)+ 新增</div>
123
+ <div class="icen-kb-chunk [is-off]">
124
+ <label class="icen-kb-chunk-switch"><input type="checkbox">启用</label>
125
+ <div class="icen-kb-chunk-content" contenteditable>…</div>
126
+ <div class="icen-kb-chunk-keywords">tag-input 式 chips</div>
127
+ <div class="icen-kb-chunk-meta">#3 · 第 2 页 · 向量就绪</div>
128
128
  <div class="kb-chunk-actions">删除</div>
129
129
  </div>…
130
130
  </div>
@@ -134,9 +134,9 @@ chart-* → 图形层(ChartSpec 纯 JSON)
134
134
 
135
135
  ### 5.7 kb-segment 分段策略 + 实时预览
136
136
  ```
137
- <div class="kb-segment">
138
- <div class="kb-segment-form">模式(auto/custom/parent-child)· 分隔符 · 最大长度 · 重叠 · 清洗勾选 · locked 警示</div>
139
- <div class="kb-segment-preview"><div class="kb-segment-stats">N 段 · 均长 x · ≈y tokens</div><div class="kb-segment-block">…</div>…</div>
137
+ <div class="icen-kb-segment">
138
+ <div class="icen-kb-segment-form">模式(auto/custom/parent-child)· 分隔符 · 最大长度 · 重叠 · 清洗勾选 · locked 警示</div>
139
+ <div class="icen-kb-segment-preview"><div class="icen-kb-segment-stats">N 段 · 均长 x · ≈y tokens</div><div class="icen-kb-segment-block">…</div>…</div>
140
140
  </div>
141
141
  ```
142
142
  - `createKbSegment(el, { config, sample, onChange })` → `{ getConfig(), setConfig(), refresh(sample?) }`;预览走 kb-core `segmentText` 纯函数(真实切分非估算);模式锁定(locked)时表单禁用 + 提示。
@@ -144,7 +144,7 @@ chart-* → 图形层(ChartSpec 纯 JSON)
144
144
 
145
145
  ### 5.8 kb-connector 连接器卡
146
146
  ```
147
- <div class="kb-connector is-healthy|is-stale|is-failing|is-off">
147
+ <div class="icen-kb-connector is-healthy|is-stale|is-failing|is-off">
148
148
  头:图标 · 名称 · scope · 同步计划
149
149
  信号行(4 离散信号):状态点 · 已同步 N · 抓取率 · 变更率 · 凭证
150
150
  操作:立即同步 · 重新授权 · 编辑计划
@@ -164,10 +164,10 @@ chart-* → 图形层(ChartSpec 纯 JSON)
164
164
 
165
165
  ### 5.11 kb-retrieval 检索 playground
166
166
  ```
167
- <div class="kb-retrieval">
168
- <div class="kb-retrieval-bar">query 输入 · 模式 segmented(向量|关键词|混合)· topK stepper · alpha 滑杆 · rerank 开关 · 运行(btn-primary)</div>
167
+ <div class="icen-kb-retrieval">
168
+ <div class="icen-kb-retrieval-bar">query 输入 · 模式 segmented(向量|关键词|混合)· topK stepper · alpha 滑杆 · rerank 开关 · 运行(btn-primary)</div>
169
169
  <div class="kb-retrieval-params-text">可复制参数 JSON(DSL 双表示纪律)</div>
170
- <div class="kb-hit"><div class="kb-hit-rank">1</div><div class="kb-hit-main">标题 · <mark>命中</mark>…</div>
170
+ <div class="icen-kb-hit"><div class="icen-kb-hit-rank">1</div><div class="icen-kb-hit-main">标题 · <mark>命中</mark>…</div>
171
171
  <div class="kb-hit-score">score bar + 值 + explain</div></div>…
172
172
  </div>
173
173
  ```
@@ -183,8 +183,8 @@ chart-* → 图形层(ChartSpec 纯 JSON)
183
183
 
184
184
  ### 5.13 kb-rerank rerank A/B 对比(市场空白)
185
185
  ```
186
- <div class="kb-rerank">
187
- <div class="kb-rerank-col">before 列表</div><div class="kb-rerank-col">after 列表</div>
186
+ <div class="icen-kb-rerank">
187
+ <div class="icen-kb-rerank-col">before 列表</div><div class="icen-kb-rerank-col">after 列表</div>
188
188
  每行:rank + ↑3/↓2/—(kb-rerank-delta is-up|is-down)+ 双分数
189
189
  </div>
190
190
  ```
@@ -197,10 +197,10 @@ chart-* → 图形层(ChartSpec 纯 JSON)
197
197
 
198
198
  ### 5.15 kb-sql 生成 SQL 卡片
199
199
  ```
200
- <div class="kb-sql">
201
- <div class="kb-sql-head">标题 · 可见性徽章(admin)· 引用表 chips · 复制/编辑重跑</div>
202
- <pre class="kb-sql-code">…highlightSql 生成的着色 token…</pre>
203
- <div class="kb-sql-fix">v1↔v2 diff(复用 parseUnifiedDiff)+ 一键应用</div>
200
+ <div class="icen-kb-sql">
201
+ <div class="icen-kb-sql-head">标题 · 可见性徽章(admin)· 引用表 chips · 复制/编辑重跑</div>
202
+ <pre class="icen-kb-sql-code">…highlightSql 生成的着色 token…</pre>
203
+ <div class="icen-kb-sql-fix">v1↔v2 diff(复用 parseUnifiedDiff)+ 一键应用</div>
204
204
  </div>
205
205
  ```
206
206
  - `renderKbSql(el, query, opts?)`;`initKbSql(root?)`;导出纯函数 `highlightSql(sql): Node`(零依赖关键词/字符串/注释着色)。
@@ -209,13 +209,13 @@ chart-* → 图形层(ChartSpec 纯 JSON)
209
209
 
210
210
  ### 5.16 kb-answer 问数答案容器
211
211
  ```
212
- <article class="kb-answer">
213
- <div class="kb-answer-badges">认证徽章(trusted,命中资产说明 + 参数可改重跑)/ 权限提示</div>
214
- <div class="kb-answer-body">答案(可含 kb-citation 角标)…</div>
215
- <div class="kb-answer-clarify">…kb-clarify…</div>
216
- <div class="kb-answer-explain">…kb-explain 折叠…</div>
217
- <div class="kb-answer-results">结果表(datatable)+ 截断声明 + 导出</div>
218
- <div class="kb-answer-chart">图表 + 类型切换 + 追问改图</div>
212
+ <article class="icen-kb-answer">
213
+ <div class="icen-kb-answer-badges">认证徽章(trusted,命中资产说明 + 参数可改重跑)/ 权限提示</div>
214
+ <div class="icen-kb-answer-body">答案(可含 kb-citation 角标)…</div>
215
+ <div class="icen-kb-answer-clarify">…kb-clarify…</div>
216
+ <div class="icen-kb-answer-explain">…kb-explain 折叠…</div>
217
+ <div class="icen-kb-answer-results">结果表(datatable)+ 截断声明 + 导出</div>
218
+ <div class="icen-kb-answer-chart">图表 + 类型切换 + 追问改图</div>
219
219
  </article>
220
220
  ```
221
221
  - `renderKbAnswer(el, model)` 组合渲染;认证优先于生成的徽章逻辑;`permissionNotice` 行级/脱敏提示。
@@ -231,11 +231,11 @@ chart-* → 图形层(ChartSpec 纯 JSON)
231
231
 
232
232
  ### 5.19 kb-trace trace 树
233
233
  ```
234
- <div class="kb-trace"><div class="kb-span is-<kind> [is-open]" data-span-id style="--depth:1">
235
- <span class="kb-span-caret"></span><span class="kb-span-kind">检索</span><span class="kb-span-name">hybrid search</span>
236
- <i class="kb-span-bar" style="width:34%"></i><span class="kb-num">212ms</span></div>…</div>
234
+ <div class="icen-kb-trace"><div class="kb-span is-<kind> [is-open]" data-icen-span-id style="--depth:1">
235
+ <span class="icen-kb-span-caret"></span><span class="icen-kb-span-kind">检索</span><span class="icen-kb-span-name">hybrid search</span>
236
+ <i class="icen-kb-span-bar" style="width:34%"></i><span class="icen-kb-num">212ms</span></div>…</div>
237
237
  ```
238
- - `renderKbTrace(el, spans)`;`initKbTrace(root?)`:嵌套缩进(--depth)、时长条按兄弟占比、retrieval span 内嵌 hits 迷你列表(复用 .kb-hit)、io 折叠。
238
+ - `renderKbTrace(el, spans)`;`initKbTrace(root?)`:嵌套缩进(--depth)、时长条按兄弟占比、retrieval span 内嵌 hits 迷你列表(复用 .icen-kb-hit)、io 折叠。
239
239
  - 事件:`icen:kb-trace-select {spanId}`、`icen:kb-trace-toggle {spanId, open}`。
240
240
 
241
241
  ### 5.20 kb-review 标注队列
@@ -256,7 +256,7 @@ chart-* → 图形层(ChartSpec 纯 JSON)
256
256
 
257
257
  ### 5.24 kb-checkpoint 检查点(P2)
258
258
  ```
259
- <button class="kb-checkpoint" data-checkpoint-id>时钟icon · 14:32 · 批量改写前</button>
259
+ <button class="icen-kb-checkpoint" data-icen-checkpoint-id>时钟icon · 14:32 · 批量改写前</button>
260
260
  ```
261
261
  - `renderKbCheckpoints(el, items)`;`initKbCheckpoint(root?)`:点击弹恢复菜单,scope 三选(内容/对话/两者)——默认「只回滚内容、保留对话」(Cursor 语义,审计友好)。
262
262
  - 事件:`icen:kb-checkpoint-restore {checkpointId, scope}`。
@@ -267,7 +267,7 @@ chart-* → 图形层(ChartSpec 纯 JSON)
267
267
 
268
268
  ### 5.26 kb-chain 工具链条
269
269
  ```
270
- <div class="kb-chain"><span class="kb-chain-step is-done">检索</span><i class="kb-chain-link"></i><span class="kb-chain-step is-running">重排</span>…</div>
270
+ <div class="icen-kb-chain"><span class="icen-kb-chain-step is-done">检索</span><i class="icen-kb-chain-link"></i><span class="icen-kb-chain-step is-running">重排</span>…</div>
271
271
  ```
272
272
  - `renderKbChain(el, steps)`;横向摘要条(与 ai-tool-call 单卡互补);点击 step → `icen:kb-chain-step {index, step}`。
273
273
 
@@ -290,16 +290,16 @@ chart-* → 图形层(ChartSpec 纯 JSON)
290
290
  - 渲染:textContent-only;SVG 过 svgIcon;流式路径 append-only(不整树重建);数据快照切换才允许整段重建。
291
291
  - 交互:init* 幂等 + 销毁函数;document 级委托;滚动/指针监听 passive;拖拽 rAF 批处理。
292
292
  - CSS:无 JS 依赖的纯样式状态优先(.is-* 驱动);动效 ≤240ms;不引第三方字体/图标。
293
- - 自定义:`registerKbSourceType(kind, {label, icon})`(来源类型开放注册,镜像 registerAiKind);每组件暴露 `--kb-*` 微调变量与 `data-density`;渲染槽位(opts.renderCard / renderHit 等)+ 事件/handle 双通道;浮层一律走 popover 的 PanelSizing。
293
+ - 自定义:`registerKbSourceType(kind, {label, icon})`(来源类型开放注册,镜像 registerAiKind);每组件暴露 `--kb-*` 微调变量与 `data-icen-density`;渲染槽位(opts.renderCard / renderHit 等)+ 事件/handle 双通道;浮层一律走 popover 的 PanelSizing。
294
294
  - kit:`bunx @icen.ai/ui add kb` 一条拿到全家;域级 slug 自持(EXTRA_CSS 只补 kb.css)。
295
295
 
296
296
  ## 8. 验收
297
297
 
298
- - `bun run build` 绿(tsc + tsup + dts-ext + build-css assertSrc);`kit/kb-citation` 等 32 个新 kit 入口可独立安装(v0.9.1 权限域 +5:kb-acl/kb-who-can/kb-access/kb-audit/kb-visibility)。
298
+ - `bun run build` 绿(tsc + tsup + dts-ext + build-css assertSrc);`kit/kb-citation` 等 32 个 kit 入口可独立安装(含权限域 kb-acl/kb-who-can/kb-access/kb-audit/kb-visibility)。
299
299
  - 文档站:新增「知识库」分组(每组件 API + demo 页)+ `/kb` 最佳实践工作台页(问答+引用溯源 / 摄取管线 / 检索调试 / 问数 / 观测 / 权限 / Agent / 参考 八标签全流程演示)。
300
300
  - AGENTS.md / README / CHANGELOG 同步。
301
301
 
302
- ## 9. 权限域 kb-perm(v0.9.1 增补;调研依据 docs/research/2026-10-03-kb-permissions.md)
302
+ ## 9. 权限域 kb-perm(调研依据 docs/research/2026-10-03-kb-permissions.md)
303
303
 
304
304
  > 心法:**ai 族描述思考,kb 族呈现证据;权限域呈现边界**——知识从哪来、可信吗、怎么用之后第三问:**谁能看到什么,以及为什么**。
305
305
  > 五组件一域文件:`kb-perm.css`;slug:`kb-acl` / `kb-who-can` / `kb-access` / `kb-audit` / `kb-visibility`(EXTRA_CSS = kb.css + kb-perm.css;`kb` umbrella 追加 kb-perm.css)。
@@ -318,23 +318,23 @@ chart-* → 图形层(ChartSpec 纯 JSON)
318
318
  ### 9.1 kb-acl 文档权限面板(SharePoint 权限页范式)
319
319
 
320
320
  ```
321
- <section class="kb-acl">
322
- <header class="kb-acl-head">
323
- <div class="kb-acl-title">资源名 + <span class="kb-badge kb-badge--restricted">受限</span></div>
324
- <button class="kb-acl-act" data-acl-break|data-acl-restore>停止继承 / 恢复继承</button>
321
+ <section class="icen-kb-acl">
322
+ <header class="icen-kb-acl-head">
323
+ <div class="icen-kb-acl-title">资源名 + <span class="icen-kb-badge icen-kb-badge--restricted">受限</span></div>
324
+ <button class="icen-kb-acl-act" data-icen-acl-break|data-icen-acl-restore>停止继承 / 恢复继承</button>
325
325
  </header>
326
- <div class="kb-acl-inherit [.is-broken|.is-partial]"> <!-- 继承 banner 三态:继承(含父链)/ 已断(警示)/ 例外 N 项 -->
326
+ <div class="icen-kb-acl-inherit [.is-broken|.is-partial]"> <!-- 继承 banner 三态:继承(含父链)/ 已断(警示)/ 例外 N 项 -->
327
327
  </div>
328
- <div class="kb-acl-grants"> <!-- Direct access 区 -->
329
- <div class="kb-acl-grant [.is-deny|.is-system|.is-expiring]">
330
- <span class="kb-acl-subject" data-kind="user|group|org|anyone|link">主体(组带成员数/「由 IT 管理」note)</span>
331
- <span class="kb-acl-role kb-chip">Viewer|Commenter|Editor|Owner|拒绝</span>
332
- <span class="kb-acl-meta">继承自 X · 2026-11-01 到期 · 系统管理</span>
333
- <button class="kb-acl-remove" data-acl-remove aria-label="移除">×</button>
328
+ <div class="icen-kb-acl-grants"> <!-- Direct access 区 -->
329
+ <div class="icen-kb-acl-grant [.is-deny|.is-system|.is-expiring]">
330
+ <span class="icen-kb-acl-subject" data-icen-kind="user|group|org|anyone|link">主体(组带成员数/「由 IT 管理」note)</span>
331
+ <span class="icen-kb-acl-role icen-kb-chip">Viewer|Commenter|Editor|Owner|拒绝</span>
332
+ <span class="icen-kb-acl-meta">继承自 X · 2026-11-01 到期 · 系统管理</span>
333
+ <button class="icen-kb-acl-remove" data-icen-acl-remove aria-label="移除">×</button>
334
334
  </div>…
335
335
  </div>
336
- <div class="kb-acl-links">…同 grant 行,data-kind=link,带范围(特定人员/组织内/任何人)+ 过期…</div>
337
- <footer class="kb-acl-foot"><button data-acl-grant>授予访问</button><span class="kb-meta">对 N 人可见</span></footer>
336
+ <div class="icen-kb-acl-links">…同 grant 行,data-icen-kind=link,带范围(特定人员/组织内/任何人)+ 过期…</div>
337
+ <footer class="icen-kb-acl-foot"><button data-icen-acl-grant>授予访问</button><span class="icen-kb-meta">对 N 人可见</span></footer>
338
338
  </section>
339
339
  ```
340
340
  - `renderKbAcl(el, model, opts?) → el`(快照);`KbAclModel = { resource, parentChain: string[], broken, exceptions?, entries: KbAclEntry[], links: KbAclEntry[], exposureCount? }`;opts: onGrant/onRemove/onBreak/onRestore。
@@ -344,18 +344,18 @@ chart-* → 图形层(ChartSpec 纯 JSON)
344
344
  ### 9.2 kb-who-can 有效权限检查器(view-as,差异化组件)
345
345
 
346
346
  ```
347
- <div class="kb-whocan">
348
- <div class="kb-whocan-bar"><select class="kb-whocan-user">…固定身份集…</select><button data-whocan-check>检查</button></div>
349
- <div class="kb-whocan-result [.is-allowed|.is-denied]">
350
- <div class="kb-whocan-verdict">可编辑(Editor) / 无权限</div>
351
- <div class="kb-whocan-deniedby">被策略拒绝:DLP-外发管控</div> <!-- deny 一票否决置顶 -->
352
- <ul class="kb-whocan-chain">
353
- <li class="kb-whocan-reason [.is-inherit|.is-direct|.is-link|.is-deny]">
354
- <span class="kb-badge">继承</span> 财务部空间 · finance-team · Editor
355
- <span class="kb-meta">24 成员 · 由 IT 管理</span>
347
+ <div class="icen-kb-whocan">
348
+ <div class="icen-kb-whocan-bar"><icen-select class="icen-kb-whocan-user">…固定身份集(弹层选择器,kb-select 构建器)…</icen-select><button data-icen-whocan-check>检查</button></div>
349
+ <div class="icen-kb-whocan-result [.is-allowed|.is-denied]">
350
+ <div class="icen-kb-whocan-verdict">可编辑(Editor) / 无权限</div>
351
+ <div class="icen-kb-whocan-deniedby">被策略拒绝:DLP-外发管控</div> <!-- deny 一票否决置顶 -->
352
+ <ul class="icen-kb-whocan-chain">
353
+ <li class="icen-kb-whocan-reason [.is-inherit|.is-direct|.is-link|.is-deny]">
354
+ <span class="icen-kb-badge">继承</span> 财务部空间 · finance-team · Editor
355
+ <span class="icen-kb-meta">24 成员 · 由 IT 管理</span>
356
356
  </li>…
357
357
  </ul>
358
- <div class="kb-whocan-rule">叠加规则:多来源并集 → Editor;无 Deny 生效</div>
358
+ <div class="icen-kb-whocan-rule">叠加规则:多来源并集 → Editor;无 Deny 生效</div>
359
359
  </div>
360
360
  </div>
361
361
  ```
@@ -366,11 +366,11 @@ chart-* → 图形层(ChartSpec 纯 JSON)
366
366
  ### 9.3 kb-access 访问申请流(被拒五件套 + 状态机)
367
367
 
368
368
  ```
369
- <div class="kb-access" data-state="idle|requested|granted|expiring|expired|revoked">
370
- <div class="kb-access-denied"> <!-- 五件套:资源名 / 原因 / owner / 申请 / 切换身份 -->
371
- <div class="kb-access-form" hidden> <!-- 理由(可必填)+ 角色 + 时长 + 路由提示「请求将发送给:内容 owner 李四」 -->
372
- <div class="kb-access-state"> <!-- 状态徽章族:.is-requested/.is-granted(+倒计时)/.is-expiring/.is-expired(重交)/.is-revoked -->
373
- <div class="kb-access-queue" hidden?> <!-- 审批方视角(mode='approver'):请求卡 + 批准(选权限级)/拒绝(附留言) + 历史 -->
369
+ <div class="icen-kb-access" data-icen-state="idle|requested|granted|expiring|expired|revoked">
370
+ <div class="icen-kb-access-denied"> <!-- 五件套:资源名 / 原因 / owner / 申请 / 切换身份 -->
371
+ <div class="icen-kb-access-form" hidden> <!-- 理由(可必填)+ 角色 + 时长 + 路由提示「请求将发送给:内容 owner 李四」 -->
372
+ <div class="icen-kb-access-state"> <!-- 状态徽章族:.is-requested/.is-granted(+倒计时)/.is-expiring/.is-expired(重交)/.is-revoked -->
373
+ <div class="icen-kb-access-queue" hidden?> <!-- 审批方视角(mode='approver'):请求卡 + 批准(选权限级)/拒绝(附留言) + 历史 -->
374
374
  </div>
375
375
  ```
376
376
  - `createKbAccess(el, { request, mode?: 'requester'|'approver', onRequest?, onDecide? }) → handle { setState(next), getState() }`。
@@ -380,20 +380,20 @@ chart-* → 图形层(ChartSpec 纯 JSON)
380
380
  ### 9.4 kb-audit 权限审计时间线(Box/Purview 骨架 + 权限异味)
381
381
 
382
382
  ```
383
- <div class="kb-audit">
384
- <div class="kb-audit-bar">
385
- <div class="kb-audit-channels">全部/读取/权限变更/申请/系统(chip 组 data-channel)</div>
386
- <button data-audit-export>导出 CSV</button>
383
+ <div class="icen-kb-audit">
384
+ <div class="icen-kb-audit-bar">
385
+ <div class="icen-kb-audit-channels">全部/读取/权限变更/申请/系统(chip 组 data-icen-channel)</div>
386
+ <button data-icen-audit-export>导出 CSV</button>
387
387
  </div>
388
- <div class="kb-audit-hygiene"> <!-- 权限异味节(admin):6 枚举见 kb-core -->
389
- <div class="kb-hygiene [.is-high|.is-medium|.is-low]"><span class="kb-badge">过度共享</span>…<button data-hygiene-act>处置</button></div>
388
+ <div class="icen-kb-audit-hygiene"> <!-- 权限异味节(admin):6 枚举见 kb-core -->
389
+ <div class="icen-kb-hygiene [.is-high|.is-medium|.is-low]"><span class="icen-kb-badge">过度共享</span>…<button data-icen-hygiene-act>处置</button></div>
390
390
  </div>
391
- <ol class="kb-audit-list">
392
- <li class="kb-audit-entry [.is-breakglass]">
393
- <span class="kb-audit-at kb-num">10-03 14:22</span>
394
- <span class="kb-audit-actor" data-kind="human|app|system">张三 / …系统</span>
395
- <span class="kb-audit-action kb-chip">读取|权限变更|授予|收回|申请|批准|委派|应急</span>
396
- <span class="kb-audit-detail">…</span>
391
+ <ol class="icen-kb-audit-list">
392
+ <li class="icen-kb-audit-entry [.is-breakglass]">
393
+ <span class="icen-kb-audit-at icen-kb-num">10-03 14:22</span>
394
+ <span class="icen-kb-audit-actor" data-icen-kind="human|app|system">张三 / …系统</span>
395
+ <span class="icen-kb-audit-action icen-kb-chip">读取|权限变更|授予|收回|申请|批准|委派|应急</span>
396
+ <span class="icen-kb-audit-detail">…</span>
397
397
  </li>…
398
398
  </ol>
399
399
  </div>
@@ -407,19 +407,19 @@ chart-* → 图形层(ChartSpec 纯 JSON)
407
407
  > 组件头常驻警示条:命中差异对照对普通用户构成泄露(判据:任何随受限集合变化的可观察量都是侧信道),**仅 admin 审计/教学视图**。
408
408
 
409
409
  ```
410
- <div class="kb-visibility">
411
- <div class="kb-visibility-warn">admin 审计视图——勿嵌入终端用户界面</div>
412
- <div class="kb-visibility-bar">身份 chip 组 · 查询回显 · 过滤层徽标(pre ✓ / post ⚠ / none ✕)</div>
413
- <div class="kb-visibility-grid"> <!-- 每身份一列 -->
414
- <div class="kb-visibility-col">
410
+ <div class="icen-kb-visibility">
411
+ <div class="icen-kb-visibility-warn">admin 审计视图——勿嵌入终端用户界面</div>
412
+ <div class="icen-kb-visibility-bar">身份 chip 组 · 查询回显 · 过滤层徽标(pre ✓ / post ⚠ / none ✕)</div>
413
+ <div class="icen-kb-visibility-grid"> <!-- 每身份一列 -->
414
+ <div class="icen-kb-visibility-col">
415
415
  <header>身份 + 有效角色</header>
416
- <div class="kb-visibility-count kb-num">安全计数 n</div> <!-- 授权集合内 -->
417
- <div class="kb-visibility-hits">
416
+ <div class="icen-kb-visibility-count icen-kb-num">安全计数 n</div> <!-- 授权集合内 -->
417
+ <div class="icen-kb-visibility-hits">
418
418
  <!-- hidden 级不出现;metadata = 锁+标题+摘要打码+申请;summary = AI 摘要+原文不可用;full 正常 -->
419
419
  </div>
420
420
  </div>…
421
421
  </div>
422
- <div class="kb-visibility-lesson"> <!-- 教学段(admin):fail-open 警告 / post-filter 分数可观察 / 计数差异=volume leakage(padding 缓解) -->
422
+ <div class="icen-kb-visibility-lesson"> <!-- 教学段(admin):fail-open 警告 / post-filter 分数可观察 / 计数差异=volume leakage(padding 缓解) -->
423
423
  </div>
424
424
  ```
425
425
  - `renderKbVisibility(el, { query, identities, hits, evaluateHit }) → handle { setFilterLayer(l), getVisibility(id, hit) }`;evaluateHit = `(hit, identity) => KbVisibility`(缺省走宿主给的 visibility 字段)。
@@ -427,12 +427,12 @@ chart-* → 图形层(ChartSpec 纯 JSON)
427
427
 
428
428
  ### 9.6 kb-core 契约增补(全部在此,域文件不重复定义)
429
429
 
430
- `KbRole`(viewer|commenter|editor|owner,权限序单调)/`KB_ROLES`/`kbRoleLabel`;`KbVisibility`(hidden|metadata|restricted|summary|full)/`KB_VISIBILITIES`/`kbVisibilityLabel`;`KbSubject`(kind: user|group|org|anyone|link + label + note);`KbAclEntry`(subject+role+inheritedFrom?+expiresAt?+deny?+system?);`KbIdentity`(user+groups[]+label?);`KbVisibilityPolicy`(discoverable? 缺省 true=企业内部「知道存在」常态;summaryAllowed? 缺省 false);`visibilityForRole(role, policy?)`;`KbAclDecision`(role|null、visibility、chain[]、deniedBy?、expiresAt?);`evaluateAcl(entries, identity)`(先 deny→并集→默认拒绝,纯函数);`KbAccessState`/`KB_ACCESS_STATES`/`kbAccessStateLabel`/`normalizeAccessRequest`;`KbAccessRequest`(含 approverNote 路由明示);`KbAuditAction`/`KB_AUDIT_ACTIONS`/`KbAuditEntry`/`KbAuditChannel`/`auditChannelOf`/`normalizeAuditEntry`;`KbHygieneKind`(org_wide_link|broad_group|sensitive_mismatch|broken_inheritance|orphaned_owner|overexposed)/`KB_HYGIENE_KINDS`/`kbHygieneLabel`/`KbHygieneIssue`/`normalizeHygieneIssue`。
430
+ `KbRole`(viewer|commenter|editor|owner,权限序单调)/`KB_ROLES`/`kbRoleLabel`;`KbVisibility`(hidden|metadata|restricted|summary|full)/`KB_VISIBILITIES`/`kbVisibilityLabel`;`KbSubject`(kind: user|group|org|anyone|link + label + note);`KbAclEntry`(subject+role+inheritedFrom?+expiresAt?+deny?+system?);`KbIdentity`(user+groups[]+label?);`KbVisibilityPolicy`(discoverable? 缺省 true=企业内部「知道存在」常态;summaryAllowed? 缺省 false);`visibilityForRole(role, policy?)`;`KbAclDecision`(role|null、visibility、chain[]、deniedBy?、expiresAt?);`evaluateAcl(entries, identity, policy?, now?)`(**先 deny→并集→默认拒绝,纯函数**——`now` 可注入(Date|number,缺省 `new Date()`)保证求值可复现可测试;**expiresAt 求值语义 = 到期自动回收**:已过期的条目不计入求值——deny/allow 并集/原因链全部视同不存在,全过期 = 无授权 → fail-closed;不可解析的 expiresAt 视为永不过期;decision.expiresAt 携带存活授权中最近的将来到期(倒计时呈现数据源),deny 分支无到期);`KbAccessState`/`KB_ACCESS_STATES`/`kbAccessStateLabel`/`normalizeAccessRequest`;`KbAccessRequest`(含 approverNote 路由明示);`KbAuditAction`/`KB_AUDIT_ACTIONS`/`KbAuditEntry`/`KbAuditChannel`/`auditChannelOf`/`normalizeAuditEntry`;`KbHygieneKind`(org_wide_link|broad_group|sensitive_mismatch|broken_inheritance|orphaned_owner|overexposed)/`KB_HYGIENE_KINDS`/`kbHygieneLabel`/`KbHygieneIssue`/`normalizeHygieneIssue`。
431
431
 
432
- ### 9.7 存量增强与修正(v0.9.0 的泄露式文案修正)
432
+ ### 9.7 存量增强与修正
433
433
 
434
434
  - **kb-retrieval**:参数栏加「检索身份」(固定身份集,见总纲 8);过滤层徽标三态可切换(pre ✓ 默认 / post ⚠「分数已可观察——缺陷层」/ none ✕「fail-open 危险——Kendra 教训」);命中计数只显示授权集合内安全计数;hit 的 ACL 元数据徽标行仅 `opts.admin` 模式。
435
- - **kb-trace / 工作台 mock**:guard span 文案改恒定事实「pre-filter 已按身份裁剪候选集」——删除一切被裁数量表述(v0.9.0 的「1 条 L4 块已剔除」「命中 5 块(4 有分+1 受限无分)」均为泄露式文案,全部修正;受限块 score:null 保留)。
435
+ - **kb-trace / 工作台 mock**:guard span 文案改恒定事实「pre-filter 已按身份裁剪候选集」——删除一切被裁数量表述(「1 条 L4 块已剔除」「命中 5 块(4 有分+1 受限无分)」式文案均为泄露,禁止出现;受限块 score:null 保留)。
436
436
  - **kb-sources**:`permission` 三级映射五级(requestable→metadata+申请通道;hidden=不渲染该行);打码两形态(文档场景=锁+标题+申请;数据列场景=打码条),默认前者。
437
437
  - **kb-citation**:注释补引用白名单纪律;新增 `.is-revoked` 中性态(「来源已不可用」,权限收回后的历史引用)。
438
438
 
@@ -441,3 +441,35 @@ chart-* → 图形层(ChartSpec 纯 JSON)
441
441
  - build 绿 + 5 个新 kit 独立安装;文档站 5 张新组件页 + `/kb` 新增「权限」标签(身份切换检索对照 / ACL 面板 / who-can 原因链 / 申请流状态机走查 / 审计时间线含 break-glass / 可见性对照器 admin 模式)。
442
442
  - **安全文案全局 grep**:`grep -rn "剔除\|被过滤.*条\|被隐藏.*条" src/ site/src/` 零残留(kb-visibility 教学段与 CHANGELOG 例外)。
443
443
  - AGENTS.md / README / CHANGELOG 同步。
444
+
445
+ ### 9.9 纪律即代码(从「文档纪律」到「测试强制执行的工程契约」)
446
+
447
+ §9.0 的八条总纲不再只是评审清单——每一条都有自动化证明,**违规即 CI 红**(`bun test` / `bun run guard`)。本节是映射表的单一事实源;改组件行为必须先改测试预期,禁止反手放松断言。
448
+
449
+ **八条总纲 → 自动化映射表**
450
+
451
+ | # | 总纲(§9.0) | 自动化证明 | 位置 |
452
+ | --- | --- | --- | --- |
453
+ | 1 | 检索期隔离 = query-time pre-filter | 过滤层徽标三态(pre 默认 / post ⚠ / none ✕)渲染与警示 notice 快照测试 | kb-conformance「分数纪律」组同文件检索用例;呈现层由 kb-retrieval 徽标测试覆盖 |
454
+ | 2 | 对授权侧诚实、对受限侧沉默 | 泄露文案守卫:3 组「被裁数量」模式(剔除 N 条 / 被过滤·隐藏·裁剪 N 条 / N 条无权限·受限)扫 `src/behaviors/kb-*` + `site/src/lib/kb-*`,命中即红(豁免:行尾 `guard:allow-honesty 理由`) | `scripts/guard/kb-honesty.ts` |
455
+ | 3 | 「不知道」与「不能说」不可区分 | kb-sources `hidden` 整行不渲染且标题不出现在 DOM 任何文本节点;kb-visibility `hidden` 命中列内不渲染;kb-access 原因恒定文案零信息增量 | kb-conformance「打码纪律」「权限域呈现」组 |
456
+ | 4 | 先 deny → allow 并集 → 默认拒绝(fail-closed) | evaluateAcl 语义矩阵:deny 优先于一切 allow(含 inherited)、多 allow 并集取最高角色(KB_ROLES 单调序)、无匹配 → null、空身份集 fail-closed | `tests/unit/kb-acl.test.ts` |
457
+ | 5 | 唯一允许的裁剪提示 = 恒定文案 | 同 #2 守卫(条件分支文案属模式库覆盖面);kb-answer 权限提示为「已按你的数据权限过滤」恒定文案(无计数分支) | kb-conformance「权限域呈现」组 |
458
+ | 6 | 引用白名单 / revoked 中性态 | 无效编号降级 `.is-dead` 纯文本(非按钮、aria-hidden);revoked hover 卡中性「来源已不可用」chip、无 href、无 citedText | kb-conformance「引用白名单」组 |
459
+ | 7 | 到期一等公民 | expiresAt 求值语义锁定:过期条目(deny/allow/原因链)不计入、全过期视同无权限、过期 deny 不再否决、decision 携带最近将来到期、now 可注入复现;**纯函数形态钉死**(签名有 now 参数、函数体禁 Date.now 直读——守卫强制) | `tests/unit/kb-acl.test.ts` + `tests/unit/kb-core.test.ts` + `scripts/guard/kb-honesty.ts` 规则 2 |
460
+ | 8 | 身份来自服务端固定身份集 | evaluateAcl 身份矩阵:groups 组匹配、org 全员、anyone 任意、link 不参与求值、user 不串他人;缺字段 normalize 诚实收敛;kb-who-can select 只给固定身份集(无自由输入) | `tests/unit/kb-acl.test.ts` + kb-conformance「权限域呈现」组 |
461
+
462
+ **全族横向纪律(组件层 DOM 断言)**
463
+
464
+ - **分数纪律**:score=null/缺失 → 「—」且不渲染 `.icen-kb-score-bar`(kb-retrieval / kb-rerank / kb-trace 全命中);l2 距离自动反转呈现(0.1 → 条宽 90%);轨道定宽(域 CSS `flex: 0 0 64px` + `width: 64px`,长度只经内联 i 宽度——静态断言钉死 kb-search.css / kb-ops.css)。kb-eval / kb-hittest 的 null 均分/命中率渲染「—」不是 0。
465
+ - **截断声明**:kb-answer `truncated=true` 必须渲染 `.icen-kb-result-truncated`(显示 N/总数 + LIMIT),未截断不谎报。
466
+ - **DSL 诚实**:kb-filter 无效规则(空字段)不进 mongo/odata 序列化输出,DOM 内 DSL 镜像同纪律。
467
+
468
+ **新组件进权限域的评审 checklist**
469
+
470
+ 1. 受限侧零信号:无被裁条数/标题/分数/排名位移/「若权限不同」对照——文案先过 `scripts/guard/kb-honesty.ts` 模式库(新泄露句式先补进模式库再写组件)。
471
+ 2. 每个分数呈现点过 `scorePercent`(l2 反转/null→不渲染条),轨道进域 CSS 定宽清单。
472
+ 3. 每条 grant 呈现 expiresAt 三态之一(永不过期 / 倒计时+续期 / 已过期+重交);求值一律走 `evaluateAcl(entries, identity, policy?, now)`,now 从宿主时钟注入。
473
+ 4. 引用只生成自过滤后集合;权限收回态走 `.is-revoked` 中性呈现(不删不留裸链)。
474
+ 5. admin 对照类组件(kb-visibility 范式)头常驻警示条,事件与呈现都标 admin-only。
475
+ 6. 新增 DOM 断言进 `tests/kb-conformance.test.ts`;求值语义进 `tests/unit/kb-acl.test.ts`——**先写测试再写组件**。
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@icen.ai/ui",
3
- "version": "0.9.0",
4
- "description": "Icen Design System — 设计 tokens(6 预设 × 明暗)+ 无框架组件 CSS/行为 JS + AI 原生组件族(7 态状态机/多模态/定价审计)+ 图表通用层(ChartSpec 纯 JSON)+ AI 工具体系",
3
+ "version": "0.10.0",
4
+ "description": "Icen Design System — 设计 tokens(8 主题 × 4 原语 × 明暗)+ 无框架组件 CSS/行为 JS + AI 原生组件族(7 态状态机/多模态/定价审计)+ 图表通用层(ChartSpec 纯 JSON)+ AI 工具体系",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "git+https://github.com/icen-ai/ui.git"
@@ -10,12 +10,14 @@
10
10
  "type": "module",
11
11
  "exports": {
12
12
  ".": "./dist/index.mjs",
13
+ "./react": "./dist/react.mjs",
14
+ "./vue": "./dist/vue.mjs",
13
15
  "./behaviors/*": "./dist/behaviors/*.mjs",
14
16
  "./kit/*": "./dist/components/*.mjs",
15
17
  "./tokens.css": "./dist/tokens.css",
18
+ "./tokens/dtcg.json": "./dist/tokens/dtcg.json",
16
19
  "./ui.css": "./dist/ui.css",
17
20
  "./base.css": "./dist/base.css",
18
- "./retro-effects.css": "./dist/retro-effects.css",
19
21
  "./tokens/*": "./dist/tokens/*",
20
22
  "./components/*": "./dist/components/*",
21
23
  "./registry.json": "./dist/registry.json"
@@ -26,23 +28,56 @@
26
28
  "sideEffects": [
27
29
  "**/*.css"
28
30
  ],
31
+ "peerDependencies": {
32
+ "react": ">=18",
33
+ "react-dom": ">=18",
34
+ "vue": ">=3.3"
35
+ },
36
+ "peerDependenciesMeta": {
37
+ "react": {
38
+ "optional": true
39
+ },
40
+ "react-dom": {
41
+ "optional": true
42
+ },
43
+ "vue": {
44
+ "optional": true
45
+ }
46
+ },
29
47
  "files": [
30
48
  "dist",
31
49
  "AGENTS.md",
32
- "docs"
50
+ "docs/spec"
33
51
  ],
34
52
  "license": "MIT",
35
53
  "publishConfig": {
36
54
  "access": "public"
37
55
  },
38
56
  "scripts": {
39
- "build": "tsup && bun scripts/dts-ext.mjs && bun scripts/build-css.ts",
40
- "prepublishOnly": "bun run build"
57
+ "build": "tsup && bun scripts/react-use-client.mjs && bun scripts/dts-ext.mjs && bun scripts/build-css.ts && bun scripts/dtcg.mjs && bun scripts/design-tokens.mjs",
58
+ "dtcg": "bun scripts/dtcg.mjs",
59
+ "design-tokens": "bun scripts/design-tokens.mjs",
60
+ "guard": "bun scripts/guard/index.ts",
61
+ "prepublishOnly": "bun run build",
62
+ "pretest:e2e": "cd site && bun run build",
63
+ "test": "bun test",
64
+ "test:e2e": "playwright test",
65
+ "verify": "bunx tsc --noEmit && bun run guard && bun test && bun run build",
66
+ "colors": "bun scripts/theme-colors.mjs"
41
67
  },
42
68
  "devDependencies": {
69
+ "@happy-dom/global-registrator": "^20.14.5",
70
+ "@playwright/test": "^1.63.0",
43
71
  "@types/node": "^20.14.0",
72
+ "@types/react": "^19.3.0",
73
+ "@types/react-dom": "^19.3.0",
74
+ "axe-core": "^4.14.0",
75
+ "happy-dom": "^20.14.5",
76
+ "react": "^19.3.0",
77
+ "react-dom": "^19.3.0",
44
78
  "tsup": "^8.3.0",
45
- "typescript": "^5.5.0"
79
+ "typescript": "^5.5.0",
80
+ "vue": "^3.5.43"
46
81
  },
47
82
  "keywords": [
48
83
  "design-system",
@@ -52,4 +87,4 @@
52
87
  "css",
53
88
  "tokens"
54
89
  ]
55
- }
90
+ }