## 品牌标识(本次会话) 起因:品牌此前没有任何图形标识 —— 唯一 favicon 是内联 data-URI 里的字母「A」, 那是 v2.0.0「Aurora Admin → Kole UI」改名漏掉的一处(PC 顶栏也是「A」, 移动端站已是「K」;移动端文档站则完全没有 favicon)。 - 几何:24 网格三个互不接触的笔画(竖 + 两斜),圆头描边; 描边 2.25 → 16px 标签页尺寸下正好 1.5px = 规范原文「描边1.5px」 - 取色分两套(刻意):favicon 硬编码品牌蓝/白(渲染在浏览器标签栏,不继承 kole-dark); 顶栏标记走 currentColor(实测暗色下自动转 rgb(20,22,28)) - 新增 theme-color 双条(light #FFFFFF / dark #1C1F26,取 --kole-color-card-bg) - 修 site/app.js hero 标语 KOLE ADMIN → KOLE UI(改名变形残留) - 移动端 7 个模板补 favicon(此前计数 0) 验收:门禁 9 条全 OK(site-routing/site-routes/mobile-docs/mobile-site/isolation/ theme/nav/i18n/icons);PC 回归 1464/1464 · 移动端 807/807,各连跑 8 次一致; 两端 favicon 405 字节逐字节一致;PC 站控制台错误 1→0。 ## 并行会话成果(本次一并入库) - 图标系统:2576 图标(TDesign/Element Plus,MIT)+ 11 端注入 + 5 个构建门禁工具 + IconPreview 预览页 + ICON-SPEC.md 冻结规格 - 移动端平台:47 组件 × 6 端 + 文档站 53 页 + 隔离门禁 - PC 组件:103 个大后台组件 / 组件11 批次 - uni-app:PC 端试点 + 移动端端实现 + 真实编译验证 ## 工程 - .gitignore 补 .scratch/ 与 .zcode-preexisting-*.txt(会话中间产物,实测 9.1MB,不入库) - CHANGELOG 补品牌标识条目 - ROADMAP 登 S8-P4(品牌标识任务包 + og:image/apple-touch-icon 未做部分)
188 KiB
Changelog
所有显著改动按 SemVer 记录于此。格式基于 Keep a Changelog。
[Unreleased]
品牌标识 · 几何 K 图标(favicon / 顶栏标记 / theme-color)
起因:品牌此前没有任何图形标识 —— 唯一 favicon 是内联 data-URI 里的字母「A」, 那是 v2.0.0「Aurora Admin → Kole UI」改名时漏掉的一处(PC 顶栏也是「A」, 而移动端站已是「K」;移动端文档站则完全没有 favicon)。 落地:几何 K(三笔画断笔描边),两端同源,含 favicon / 顶栏标记 / theme-color。
设计
- 几何:24 网格上三个互不接触的笔画(竖笔 + 上斜 + 下斜),圆头描边。 笔画不接触既表达「独立组件拼组成系统」,也保证 16px 浏览器标签页尺寸下不糊。
- 描边 2.25:在 24 网格下,16px 渲染时正好是 1.5px —— 等于规范原文
「线性图标,描边1.5px」(
.design_library/kole-ui/specs/组件1.txt)。 实测比对了 1.5 / 1.875 / 2.25 三档在 20px 顶栏与 16px 标签页下的观感。 - 圆角 rx=6(24 网格)= 32px 下 8px,即令牌
--kole-radius-large。
取色分两套(刻意,不是不一致)
- favicon 硬编码
#2F54EB+#FFFFFF:它渲染在浏览器标签栏,不继承html.kole-dark。 若走令牌,暗色下--kole-color-text-inverse=#14161C,会变成「亮蓝底 + 近黑标记」, 在浅色标签栏上反而发闷。 - 两端顶栏标记走
currentColor:实测暗色下自动解析为rgb(20,22,28)、 底色转rgb(107,140,255)(令牌化行为保真,与同页其它图标一致)。
新增
theme-color双条(light#FFFFFF/ dark#1C1F26,取--kole-color-card-bg, 即.topbar/.m-top的 background,色值与视觉连续)。PC 写在site/index.html; 移动端由新增的__BRAND_HEAD__占位符经tools/build-mobile.mjs注入 7 个模板。
修正
site/index.html的 favicon 字母A→ 几何 K;顶栏.logo-mark的A→ 几何 K (类名与 32×32 盒模型不变 —— ≤1366px 时它是顶栏唯一品牌标识)。tools/build-mobile.mjs移动端顶栏标记K文字 → 几何 K 图形(保留class="m-logo-mark",verify-mobile-docs会逐页断言它存在)。site/app.js首页 hero 标语KOLE ADMIN DESIGN SYSTEM→KOLE UI DESIGN SYSTEM(同一改名的变形残留)。- 移动端文档站 7 个模板补 favicon(此前
rel="icon"计数为 0,标签页显示默认地球图标)。
验收
- 门禁:
verify-site-routingOK(103 / 412 / 521)·verify-site-routesOK(零 4xx)·verify-mobile-docsOK(12 条 · 53 页)·verify-mobile-siteOK(263 条 · 50 页, 控制台 0 错误)·verify:isolationOK(31 条)·verify:theme/verify:nav/verify:i18n/verify-icons全 OK。 - 回归:PC 1464/1464 · 移动端 807/807,各连跑 8 次一致。
- 浏览器实测:PC 与移动端 favicon 405 字节逐字节一致;页面 DOM 中
>A<清零; PC 站控制台错误从 1(favicon 404)降为 0。 - 已知边界:
og:image/apple-touch-icon/ web manifest 未做(需位图管线, 见 ROADMAP S8-P4)。
图标系统(PC 5 端 + 移动端 6 端 + 全量图标库 + 预览页)
起因:用户要求「图标组件参考 TDesign / Element 等主流组件库,看他们的 icon 是怎么专门设计的、 设计内容有哪些,覆盖他们全部拥有的 icon 图标和功能」。 落地:2576 个图标(TDesign 线性 1334 + 面性 1020 + Element Plus 293,均 MIT), 11 个端实现全部接通,新增 5 个构建/门禁工具与 1 个图标预览页。 冻结规格:
.design_library/kole-ui/icons/ICON-SPEC.md。
新增:图标数据管线(离线可复现,上游校验和钉死)
tools/fetch-icon-sources.mjs— 拉取并归一化上游 SVG →sources.json。 逐包校验 sha256(防「某天图标悄悄变了」);纯函数可单独 import(无副作用)。tools/build-icons.mjs— 编译出manifest.json(清单)/registry.json(渲染数据)/viewbox.js(viewBox 例外表)/core.js(内联运行时)/ATTRIBUTION.md(MIT 归属,分发必带)。tools/build-icon-aliases.mjs— 别名层,让 Element UI 全部 282 个历史图标名与 移动端既有 9 个字形名都能落到真实图标(旧调用点零破坏)。tools/inject-icon-table.mjs— 把 core 表注入 11 个端实现的标记块,杜绝「11 份手抄表必然漂移」。tools/verify-icons.mjs— 11 条静态断言(产物一致 / 无view-box残留 / 描边全 1.5 / core 可渲染 / 别名不遮蔽 / 各端都能查到名 / 分组覆盖率 / 路径数字与源逐值一致)。
修正:两个上游缺陷在构建期抹平(此处是本仓库的增量,不是照抄)
view-box拼写错误:TDesign 全部 2356 个 SVG 把属性写成view-box(无效属性, 浏览器忽略 → 图标按默认视口缩放)。构建期两种拼写都读,产物统一写回规范的viewBox。- 描边宽度 2 → 1.5:上游为
stroke-width="2"(24 网格),本仓库规范 (组件1.txt「图标规范:线性图标,描边1.5px,尺寸16/20/24px」)要求 1.5,构建期归一。 另丢弃fill="transparent"命中区路径(那是热区不是视觉内容)。
修正:自测发现的数据损坏缺陷(构建期把坐标改错)
- 现象:归一化把路径数字四舍五入到 2 位小数,看似无害;但 SVG path 允许「隐式分隔」——
q-13.005.48-22.5是三个数(-13.005、.48、-22.5,靠-和.当分隔符)。 把-13.005舍成-13后,后面的.48粘成-13.48—— 那是另一个坐标, 图形画错且不报任何错。实测踩到 Element Plus 的quartz-watch(靠浏览器控制台才发现)。 - 修法:原本有小数位的数字,输出至少保留 1 位小数(
-13.005→-13.0), 隐式相连的.48不可能再被吸收;并在optimizePath内复核数字序列,不一致就原样返回。 - 防复发:新增门禁断言 V8「路径数字与源逐值一致」,比对全部 2576 个图标。
已做变异测试:把该 bug 重新注入 → V8 当场 FAIL(
数字个数 461 ≠ 源 462),判据有区分力。 - 代价:
registry.json707KB(修前 677KB,+30KB 换正确性)。
修正:非 <path> 图形被静默丢弃(覆盖率审计发现)
- 现象:解析器只认
<path d>,而上游有 36 个文件用<circle cx cy r>/<ellipse>表达图形(TDesign 的circle/round/brightness/image等)。这些图形被静默丢掉 —— 图标页面上"渲染成功"却是空的,构建与回归都不报错。TDesign 的circle与round两个图标 因此整个消失,是覆盖率审计(对三个参考库逐名比对)才暴露的。 - 修法:解析器同时处理
<path>/<circle>/<ellipse>,把圆与椭圆等价换算成 path 的两段 arc(M cx cy-r A r r 0 1 1 cx cy+r A r r 0 1 1 cx cy-r Z)。 - 结果:图标数 2574 → 2576;对三家参考库的覆盖率现为 TDesign 2356/2356、Element Plus 293/293(各 100%)、Element UI 280/282(余 2 个是解析碎片名)。
- 校验:两个恢复的图标在浏览器实测有真实几何(path 长度 63 / 44,分别对应 r=10 与 r=7 的圆)。
分层与体积(按实测决定,不是拍脑袋)
- core 151 个内联(
core.js35KB),standard1989 /extended434 按需加载。 - 为何不全内联:全量 670KB,内联等于给每一页都加 670KB,直接违背 ROADMAP 的性能预算精神。
组件 API(PC 5 端 + 移动端 6 端,语义统一)
- props:
name/size(关键字small|default|large|xlarge或任意 CSS 长度,对齐 TDesign 双模式)/tone(default|brand|secondary|danger|success|warning)/spin/label。 - 向后兼容:PC 既有
iconprop(字形字符,默认'★')与移动端既有 9 名字形表全部保留,name优先。 - 无障碍:
label有值 →role="img"+aria-label,无值 →aria-hidden;spin在prefers-reduced-motion: reduce下停转;语义色对比度 ≥ 3:1(实测 5.10–5.87:1)。 - viewBox 按「路径串 → 网格」反查而非按名:别名指向的 1024 网格图标若按名查会取错网格 (实测影响 160 个名字,会导致图标拉伸变形)。
新增:图标预览页 site/icon-preview.html
规范 组件5.txt「图标预览 IconPreview:展示系统所有图标 / 网格布局,支持搜索 /
点击图标复制名称或代码 / 可调整图标大小」声明已久但从未实现。本次补齐:
2576 图标网格、搜索、点击复制名称、Shift+点击复制内联 SVG、四档尺寸切换、仅线性过滤;
分两段加载(索引 51KB 先出骨架,路径数据按需);
入口挂在图标组件页代码条 footer,i18n 双语(图标预览 / Icon gallery)。
已知未覆盖 / 遗留
- 移动端 uni-app 端用 CSS mask(data-URI SVG) 承载字形(小程序无 DOM、无内联 SVG)。
H5 目标已实测;mp-weixin / app-plus 的遮罩渲染未在真机验证,已登记进契约
unknowns。 verify-emits-parse.mjs的文件数期望值陈旧(158,应为 103×2=206)—— 本次之前就存在 (git show HEAD:确认),已登记为 ROADMAPS8-P1。verify-cross-platform.mjs把注入的图标数据表误判为组件类名(540 条里 533 条是噪声)—— 已登记为 ROADMAPS8-P2(判据不放宽,让门禁学会跳过数据块)。组件5.txt声明的 47 个工具/模板组件里 46 个仍未实现(本次只补了 IconPreview)—— 已登记为 ROADMAPS8-P3,含「走frameworks/正式组件还是site/工具页」的决策点。
Mobile · 顶栏对齐 PC + 平台入口去重(移动端站导航栏改造)
起因:用户要求「移动端组件的导航栏参考 PC 端组件导航栏优化(上面跳转 PC 和移动的下拉框也重复了)」。 实测确认两条问题,逐项修掉。
- 去重:平台切换从顶栏移除。移动端站顶栏原有一个
[PC 端] [移动端]分段胶囊,与同一页左栏的 「平台」组指向同一跳转(实测 DOM:a.mp-item与a.m-side-link.m-side-platform的 href 均为../index.html)—— 同一件事两处入口。PC 站顶栏从来没有这个控件(只有左栏一处), 故删顶栏那份,两端现在都是左栏唯一入口。改动同时断言「删的是重复的那个,不是删光」:verify-mobile-docs的 E7 从「断言顶栏有平台切换」改为「断言左栏有平台入口」。 - 顶栏逐项对齐 PC(此前只有结构同名,控件实现不同源):
- 高度 56px → 60px;内容加 1180px 居中容器(
.m-top-inner,与.m-body同宽, logo 与左栏左边缘对齐;此前内容铺满视口、与下方内容左边缘错位)。 - 激活项补 2px 底部品牌指示条(
.m-nav a.active::after,PC.topnav a.active::after同款); 此前只有文字变色。 - 版本角标 → 可点版本下拉:
<span class="m-ver">换成#m-ver-trigger+#m-ver-menu, 清单从部署根versions.json/site/versions.json两份按序取(不并行 —— 快照页那份必然 404, 并行会把 404 记进控制台,而站点门禁的零控制台错误是硬断言);拿不到清单时data-single="1"退回不可点角标(与 PC 同一语义)。路径校验只放行".."与x.y.z,防清单把人带去外站。 - 主题触发器补 三态图标(月亮 / 太阳 / 显示器,PC
.theme-icon同款):显式选择时按时态给图标, 自动模式恒为显示器图标;此前只有文字标签。
- 高度 56px → 60px;内容加 1180px 居中容器(
- 零运行时依赖不变:新增的版本/主题逻辑是构建期内联脚本(
COPY_SCRIPT),不引包。 - 顺手修掉一处过期硬编码:移动端站文案里的 PC 组件数写死为「79」,
而 S6-P21 组件族参数化后 PC 索引已是 103(实测
components/index.json)。改为构建期从 PC 索引实测读取 (模板占位符由build-mobile.mjs灌入),拿不到索引时退回中性表述而非编造数字。 涉及:总览页、FAQ、平台与端页的正文与覆盖矩阵、以及dist/mobile/README.md与 manifest 的isolatedFrom。
验收(原样):
node tools/verify-mobile-docs.mjs → [OK] 12 条断言 · 53 页(E7 判据已同步去重)
REG_BASE=http://127.0.0.1:3457 node tools/verify-mobile-site.mjs → [OK] 263 条断言 · 50 页 · 控制台错误 0 · 演示帧 281/281
REG_BASE=http://127.0.0.1:3457 node tools/run-mobile-regression.mjs → passRate 100% | pages 47 (all-pass 47) | assertions 804/804 | N/A 10
REG_BASE=http://127.0.0.1:3457 node tools/run-regression.mjs → passRate 100% | pages 103 (all-pass 103) | assertions 1405/1405 | N/A 50
PC 与移动端回归各连跑 8 次,结果逐次一致(40/40 全绿)
浏览器实测(Playwright,1440px):顶栏 60px / 内容容器实测 1180px / 激活项 ::after 实测
2px rgb(47, 84, 235) / 顶栏内 .m-platform 计数 0 / 版本下拉实测 1 个选项且 data-single="0" /
切夜间后图标 m-icon-sun:block 且 html.kole-dark 生效;320–768px 四档无横向溢出、零控制台错误。
四道移动端门禁全绿:隔离 31 条 / uni-app 9 条 × 50 SFC / 文档 12 条 · 53 页 / 站点 263 条 · 50 页。
Mobile · 批次 E/F:移动端组件 36 → 47(两批子 agent 并行 + 新增「磁盘↔索引」双向门禁)
继续
/son派活推进 TDesign 清单覆盖。批次 E(typography / segmented / sticky / overlay / popover / message) 与批次 F(picker / cascader / colorpicker / upload / table)并行产出 11 个组件 × 8 文件 = 88 文件, 规格 §37–§47。索引 36 → 47,实现 216 → 282,移动端回归 597 → 804 条断言。
- 给每个组件预分配规格编号(§37–§47):上一轮两个子 agent 并存时存在编号撞号风险(撞号会被合并脚本按幂等规则整节跳过), 本轮在派单里逐组件指定编号,合并时零冲突、规格 §1–47 连续。
- 新增反向门禁 B1b(两个子 agent 独立报的同一条缺口):
verify-mobile-isolation.mjs原先只查 「索引里的组件有没有实现文件」,不查「磁盘上的实现文件有没有进索引」——于是子 agent 产出的组件在合并前 完全不被任何门禁覆盖(不在索引里 = 不被检查),属静默缺口。现补反向断言:磁盘前缀集合必须等于索引前缀集合, 不一致直接报「未登记:X, Y(跑 node tools/merge-mobile-batch.mjs 合并)」。断言数 30 → 31。 - 修掉两处探针误判(都是工具侧,不是内容缺陷):
verify-mobile-site.mjs的总览页在 47 个卡片时只渲染 43 个 —— 预览帧loading="lazy", 一次scrollTo到底会跳过中间帧。改为逐段滚动(每 800px 一次)后再判定,实测 281/281。- 同一脚本把收集器的
net::ERR_ABORTED记为控制台错误 —— 那是_collect.html在帧装载完成后 主动removeAttribute('src')释放帧造成的在途请求中断,是设计行为。判据改为忽略ERR_ABORTED, 其余(404 / ERR_INVALID_URL 等)仍然计错。
- 子 agent 自修的真实缺陷(都带证据):
Sticky的is-stuck判定在默认偏移下滚动 0 就已贴合(改为与容器 padding box + 偏移量比较,含 1px 边框补偿);Message.jsx把onClose写进useEffect依赖 → 宿主传内联箭头函数时计时器永远不到点(回调移到useRef);Sticky/Message演示页缺实际执行的监听器致data-behavior静默失效;Table可点行不可聚焦(真实引擎报matrix:keyboard-reachable)→ 补tabindex/role/aria-selected/Enter 键路径;ColorPicker的色板 hex 写在行内 style 被no-hardcode-hex判据扫到 → 改走行内自定义属性(CSS 零 hex,色值只存数据层)。 - 规划偏差(子 agent 主动对齐既有约定):
disabled从变体维度降为状态类 —— 全仓 47 份契约无一把它当变体, 同意;picker/cascader/segmented的初判分类经我核对后修正为 input/navigation(PC 同源六分类口径)。
验收(原样):
node tools/verify-mobile-isolation.mjs → [OK] 31 条断言(含新增 B1b 反向断言)
node tools/verify-uniapp.mjs → [OK] 9 条断言 · 50 个 SFC
node tools/verify-mobile-docs.mjs → [OK] 12 条断言 · 53 页
REG_BASE=… verify-mobile-site.mjs → [OK] 263 条断言 · 50 页(0 控制台错误、演示帧 281/281)
node tools/run-mobile-regression.mjs → 100% | 804/804 | 47/47 页 | N/A 10 | 0 超时
node tools/run-regression.mjs → 100% | 1405/1405 | 103/103 页(PC 侧未被污染)
node tools/pack-deploy.mjs --tar → OK(282 实现 / 47 文档页 / 47 测试页)
部署:暂存树哈希与本地一致(936742e98d061a30)→ 替换重建 → 五项验收全过、11 个新增组件页全 200、容器 0 error;
公网 data.mobile.json 报 47 个组件。
剩余 23 个(已写进 ROADMAP S7-P23):config-provider / Fab / BackTop / Drawer / Indexes / SideBar / Tabs / Calendar / DateTimePicker / TreeSelect / CountDown / Empty / Footer / Image / ImageViewer / QRCode / Result / Skeleton / Swiper / Watermark / DropdownMenu / Guide / PullDownRefresh。
Docs · 模板页库 1 → 5(S4-P11:把组件组合成可复制的后台页面)
起因:用户要求「为组件库设置一个合适的 UI」。定位到 ROADMAP 中唯一「🟢 可开工」的任务 —— S4-P11 模板页库。 其依据写得很直白:「模板页是『能否直接用』的关键 —— 用户要的不是组件,是页面」。此前只有 1 个场景页。
- 新增 4 个模板页(
site/scenario/,纯 HTML + 原生 JS、零依赖):login.html— 输入类组件 + 表单校验。字段级错误提示(指出字段、说明原因、给修正方向)、 密码显隐切换、提交加载态 → 成功态、账号锁定等业务错误分支。dashboard.html— 侧边导航 + 4 张指标卡 + SVG 趋势图 + 渠道占比进度条 + 待办表格 + 分页。 时间范围切换会重算指标与图表;含折叠面板。order-list.html— 筛选表单 + 表格 + 批量操作条 + 分页 + 详情抽屉。 37 条示范订单;筛选/全选/批量审核/抽屉(Esc 关闭、焦点归还)全部可用。settings.html— 侧边分区 + 表单 + 开关组 + 单选/复选组 + 危险操作二次确认。
- 接入首页:
site/app.js首页新增「模板页库」区块(5 张卡片,新窗口打开);site/style.css补.home-note。 - sitemap:
build-site.ps1把 5 个模板页写入 sitemap(521 URL)。新增行全为 ASCII,守住 PS5.1 的 ASCII-only 约束。 - i18n:
site/i18n.js补 13 条英文(模板页库标题与 5 张卡片),中文源串作键的既有约定不变;verify:i18n316 键全覆盖。 - 新增门禁
npm run verify:templates(tools/verify-templates.mjs,54 条浏览器断言,已接入 CI): 令牌生效 / 非白屏 / 零控制台错误 / 零 4xx / 逐页交互 / 375–1024px 无横向溢出。 - 判据修正(
tools/verify-site-routing.mjs):sitemap URL 总数原为硬编码1 + 组件数×5, 现改为「按site/scenario/磁盘上实际存在的 .html 逐个核对 + 计入总数」。 理由:硬编码在新增模板页时只会静默漏检(sitemap 少了页面而断言仍绿); 改后「新增/删除模板页却忘记同步build-site.ps1」会直接红。这是加强而非放宽 —— 新增了 5 条逐文件断言。
模板页实测(原样):
node tools/verify-templates.mjs → [templates] OK — 54 checks passed
node tools/verify-site-routing.mjs → [routing] OK: 103 components / 412 platform shells / 521 sitemap URLs
node tools/verify-i18n.mjs → [i18n] OK — 16 checks passed(316 keys covered)
node tools/run-regression.mjs → 100% | 1405/1405 | 103/103 页 | N/A 50(八次连跑一致)
过程中被测试逮到并修掉的 4 处真实缺陷(都不是判据问题):
- 进度条高度渲染为 0 ——
components.css只聚合 6 个核心组件,ProgressVariants/DashboardCard这类扩展组件的样式根本没被加载(类名在、样式缺,页面不报错、只是画不出来)。 修法:4 个模板页按需<link>各自的frameworks/*.css(这些文件均为纯令牌自包含), 而不是在模板页里重画一遍组件。 - 指标卡标题与图标未两端对齐(
display:block而非flex)—— 与上条同根因。 - 设置页脏检查存在永久闩锁 —— 原写法
if (saved) return导致「保存过一次」之后表单再也不会被标记为脏; 且「放弃修改」只硬编码还原 5 个字段,IP 白名单与通知勾选漏在还原之外。 修法:改为快照式脏检查(基线 = 上次保存值,逐字段比对),于是「改回原值自动回到干净态」, 日后新增字段也不必再补还原代码。 - 保存竞态 —— 保存有 700ms 模拟延迟,期间「放弃修改」仍可点,会拿到上一份基线,表现为数据被还原成旧值。 修法:保存进行中两个按钮都禁用。
Mobile · 批次推进:移动端组件 5 → 36(三批子 agent + 合并脚本 + 修行为断言静默缺口)
起因:用户要求「参考 TDesign 移动端组件清单,按批次补全缺的组件」,随后
/son(派子 agent)、/agi(全自主)。 参考清单 67 个组件,本仓库已覆盖 36 个(含此前的 18 个);流程按PLATFORMS.md§四「六步」固化。
- 三批子 agent 产出 18 个组件(每个 = 6 端实现 + 规格片段 + 契约 = 8 文件,共 144 文件):
- 批次 A:
mobile-icon/mobile-layout/mobile-link/mobile-loading - 批次 B:
mobile-avatar/mobile-list/mobile-collapse/mobile-progress - 批次 C:
mobile-input/mobile-search/mobile-switch/mobile-stepper/mobile-textarea - 批次 D:
mobile-form/mobile-radio/mobile-checkbox/mobile-slider/mobile-rate规格从 §19 连续到 §36(共 36 节);索引 18 → 36 个组件,实现文件 108 → 216。
- 批次 A:
- 新增可复用的合并脚本
tools/merge-mobile-batch.mjs:子 agent 一律不写index.json(避免并发写同一文件), 由主 agent 用该脚本统一合并 —— 它做三件事且幂等:① 按编号把spec/parts/*.md拼进规格原文(同编号则只归档不拼接); ② 把frameworks-mobile/里未登记的组件(校验 6 端文件齐全 + 契约存在)写进索引;③ 已拼接的片段归档到parts/_merged/。 - 修掉一个静默缺口(子 agent 复核时发现,价值最高的一条):
tests/mobile/_behaviors.js的PILOTS是硬编码白名单 (只有最初 5 个组件),于是批次新增组件即使在演示页写了data-behavior,引擎也直接return []—— 行为断言静默不跑,断言总数悄悄少一截。修法:作用范围改为「演示页里真的写了[data-behavior]的组件」 ∪ 兜底名单,由build-mobile.mjs在生成测试页时把派生结果注入window.__koleBehaviorSlugs。 实测:行为断言覆盖 5 → 31 个组件,断言条数 8 → 34 条(全部 pass)。 - 修掉一处判据过窄(上一轮遗留):
pack-deploy.mjs的「frameworks-mobile 实现文件数」按索引动态算, 但打包时批次文件已在磁盘而尚未合并进索引 → 断言误报。现在按「索引组件数 × 端数」与磁盘实际双向核对, 不一致时直接指出差额(本次实测:156 vs 186,正是未合并的批次 C)。 - 修掉一处探针误判:
verify-mobile-site.mjs统计总览页演示帧时只看到 20/26 —— 预览帧是loading="lazy",视口外的帧不会加载(浏览器行为,不是缺陷)。判据改为先滚到底再判定, 实测 26/26、现在 36/36 全部正常渲染。 - 子 agent 自修的真实缺陷(都在报告里给了证据):
<button>嵌在<label>里(非法嵌套); Stepper 根overflow:hidden裁掉小尺寸档的热区外扩(命中测试证实);同一状态块挂两条data-behavior互相污染; Textarea 计数示例是死数据;Slider 根元素cursor:pointer让数值文案被判「鼠标专用交互」(真实引擎报的matrix:keyboard-reachable)。
验收(原样):
node tools/verify-mobile-isolation.mjs → [OK] 30 条断言
node tools/verify-uniapp.mjs → [OK] 9 条断言 · 39 个 SFC
node tools/verify-mobile-docs.mjs → [OK] 12 条断言 · 42 页(站内链接全可解析)
REG_BASE=… verify-mobile-site.mjs → [OK] 208 条断言 · 39 页(0 控制台错误、演示帧 220/220、320–768px 无溢出)
node tools/run-mobile-regression.mjs → 100% | 597/597 | 36/36 页 | N/A 10 | 0 超时
node tools/run-regression.mjs → 100% | 1405/1405 | 103/103 页(PC 侧未被污染)
node tools/pack-deploy.mjs --tar → OK(2349 文件 / 36 组件 × 6 端 = 216 实现 / 文档页 36 / 测试页 36)
部署:暂存树哈希与本地一致(719d66f2fce6875a)→ 替换重建 → 服务器端五项验收全过、容器 0 error;
公网 data.mobile.json 报 36 个组件,抽查 8 个新增组件页全 200。
Tooling · uni-app 真实编译验证 + 回归可追溯性(S7-P25 / S5-P17 / S6-P30)
起因:按批次继续推进,处理三个「一直没做但可立即做」的缺口 —— 前两项都是只能靠真跑才能回答的问题, 此前一直以「静态门禁通过」代替,属于典型的「绿灯证明不了什么」。
- S7-P25 · uni-app 真实编译验证(新增
tools/verify-uniapp-build.mjs,11 条断言): 在隔离目录装@dcloudio工具链(主仓库dependencies仍为空),搭最小 uni-app 工程, 把 21 个 SFC(移动端 18 + PC×uni-app 3)全部真实挂载并编译到 H5 与微信小程序:- 实测结果:两目标编译通过;产物含 148 / 211 个唯一
kole-m-类名; 18/18 组件的契约声明类名都进了产物;小程序产物 0 处 DOM 操作。 - 为什么必须做:静态门禁只能证明「源码长得合规」,证明不了「编译器接受它」。
本仓库已有两次「静态全绿却编译不过」的实例(
RangeQuickPicker的 const 重赋值、CodeInput的 emit 遮蔽),都是真编译才暴露的 —— 而 uni-app 端的 18 个 SFC 此前从未被编译器碰过。 - 调通过程中抓到的三个真实坑(都写进了脚本注释):
①
package.json必须声明@dcloudio/*进dependencies—— 只写{name, private, version}时 编译器照样打印DONE Build complete.、退出码 0,但产物只有一个 704 字节的 modulepreload polyfill, 页面与 21 个组件全部静默丢失。这是本次最危险的失败模式。 ② 移动端Button与 PC×uni-appButton同名(两个平台各有一份实现)→ 绑定名冲突互相覆盖。 消歧规则:PC 侧加Pc前缀,并把消歧结果用于落盘文件名与import绑定名(否则后拷的覆盖先拷的)。 ③ 页面模板用<C0 />这类索引式绑定名会被 uni-app 编译器当未识别元素丢弃 —— 必须用组件自身的 Pascal 名。 - 判据做了两轮变异测试才定稿(判据修正附理由 + 反例,符合仓库铁律):
初版「从
frameworks-mobile/<X>.css取类名」→ 假通过(uni-app 端样式是内联的,查的是另一份文件); 二版「从 uni-app 端源码取类名」→ 假通过(改名后判据与产物同步变化,两边一致,实测kole-m-grid全量改名后仍 PASS);定稿版拿契约(variantClasses)里声明的类名去产物里找 —— 契约与实现是两条独立写入路径,实现悄悄改名/丢组件时契约不会跟着变。 定稿后同一变异立刻抓到:FAILmobile-grid(契约类名 kole-m-grid--2 未进产物)。 - App 端(app-plus)未覆盖:需 HBuilderX 云端打包,命令行无法完成(脚本输出里已注明)。
- 实测结果:两目标编译通过;产物含 148 / 211 个唯一
- S5-P17 · 回归偶发失败的可追溯性:
tools/run-regression.mjs在非满分时把上一次报告留档为tests/report-prev.json(report.json仍只有一份,供首页读取),失败现场不再被下次运行覆盖。 实测(真实注入,非模拟):把tests/button.html移走制造 404 → 输出kept: tests/report-prev.json(本次非满分,已保留上一次报告供回放)且文件确实生成;还原后满分运行不再留档。report-prev.json已加进.gitignore(诊断中间产物,不入库)。 - S6-P30 · 采集偶发 vs 真断言失败:新增
isCollectionFailure(),采集失败(no-result/timeout/page-error) 单列collectionFailures且不计入 passRate 分母;failedPages只留真断言失败 (此前button: no-result会被读成「button 的断言坏了」,两类事实混在一张表里)。 实测同一注入:passRate 100% | pages 103 (all-pass 102) | assertions 1378/1378 | N/A 50 | 采集失败 1 (button:no-result)—— 分母正确扣掉该页(1378 而非 1405),且EXIT=1(不静默吞掉)。 判据反例:5 条用例逐条验证 —— 采集三类为真 / 真断言失败(matrix:contrast>=4.5)为假 / 满分页为假。 - 顺带修掉:
AGENTS.md门禁清单里三处陈旧断言数(隔离 29→30 / 文档 8→12 / 站点 53→118,均为实测值)。
验收(原样):
node tools/verify-uniapp-build.mjs
→ [OK] uni-app 真实编译验证通过(11 条断言 · 21 个 SFC · h5 + mp-weixin)
PASS B0 待编译 SFC 全部存在于源目录 — 21 个(无缺失)
PASS B-h5 编译通过 — 9488 ms PASS B-mp-weixin 编译通过 — 7747 ms
PASS B-h5 产物含 kole-m- 类名 — 148 个唯一类名
PASS B-mp-weixin 产物含 kole-m- 类名 — 211 个唯一类名
PASS B-h5 每个移动端组件(按契约声明的类名)都进了产物 — 18/18
PASS B-mp-weixin 每个移动端组件(按契约声明的类名)都进了产物 — 18/18
PASS B-mp-weixin 产物无 DOM 操作 — 0
node tools/verify-mobile-isolation.mjs → [OK] 隔离门禁全部通过(30 条断言)
node tools/verify-uniapp.mjs → [OK] uni-app 门禁全部通过(9 条断言 · 21 个 SFC)
node tools/verify-mobile-docs.mjs → [OK] 文档完整性门禁全部通过(12 条断言 · 24 页)
node tools/verify-i18n.mjs → [OK] — 16 checks passed
REG_BASE=… node tools/run-regression.mjs → passRate 100% | pages 103 (all-pass 103) | assertions 1405/1405 | N/A 50
REG_BASE=… node tools/run-mobile-regression.mjs → passRate 100% | pages 18 (all-pass 18) | assertions 270/270 | N/A 6
# 判据反例(变异测试,各自当场还原)
改掉 Grid 的契约声明类名 → FAIL mobile-grid(契约类名 kole-m-grid--2 未进产物)
注入 404 制造采集失败 → report-prev.json 生成 + EXIT=1 + 分母扣掉该页(1378/1378)
isCollectionFailure 5 条用例 → 采集三类为真 / 真断言失败为假 / 满分页为假(全 PASS)
未执行:App 端(app-plus)真实编译 —— 需 HBuilderX 云端打包,命令行无法完成。
依赖说明:@dcloudio 工具链装在 .tmp/uniapp-build(已 gitignore),主仓库 dependencies 仍为空(零运行时依赖不变);
CI 里该步骤在工具链未缓存时跳过并告警(环境问题非代码问题,脚本自身退出码 2)。
Fix · 演示帧内「覆盖型浮层」只在演示框里全屏(点击图片 / 打开弹窗不满屏)
- 缺陷:文档站把演示页嵌在按内容高度撑开的 iframe 里,而组件里
position:fixed; inset:0的覆盖层以帧视口为包含块 —— 于是「点击图片全屏」只在演示框内铺开。实测imagepreview的遮罩 724×134,宿主视口 1241×1233。命中的是全部 8 个「覆盖视口」语义的 组件:imagepreview / modal / alertmodal / confirmmodal / formmodal / fullscreenmodal / bottomsheet / loadingoverlay。这是承载容器的形态问题,不是组件缺陷 —— 这些演示页 单独打开(或点「新窗口打开」)时覆盖层本来就铺满视口,故组件源码与令牌一律不动。 - 修法(站点侧):
site/app.js新增演示帧提升桥 —— 帧内出现覆盖型浮层时给演示舞台 (.demo-stage/.ex-stage)加.is-lifted(position:fixed; inset:0,见site/style.css), 舞台成为全视口浮层的包含块后帧视口随之变成宿主视口,覆盖层自然铺满;同时锁宿主滚动 (html.kole-stage-locked)。帧内显隐由演示脚本改 style/class 驱动,宿主无法感知, 故在帧 document 上挂 MutationObserver 跟随。 - 判据只认「覆盖视口 + 真的渲染出来了」:贴边的 fixed(backtotop 右下角 / anchornav 右侧 /
messagepro 顶部 / tabbar 底部)不提升,它们的语义本来就是贴着视口某一边;
position:absolute的局部块(loadingoverlay.is-inline、popconfirm 弹泡)不提升; 水印.is-fullscreen是装饰层不是浮层,也不提升。 - 实现期实测踩到并修掉的三个真缺陷(都由新增门禁的反向/边界用例逼出):
① 淡入过渡漏判 —— BottomSheet 的遮罩 opacity 0→1 走
.25s,突变那一刻量到 opacity 仍是 0 被判成「未显示」,而过渡本身不再产生新突变 → 没有补测就永远不提升。修法:突变后隔 450ms 再判一次; ② 不可见遮罩被误提升 —— 祖先display:none时自身 computed display 仍是 flex, 只看自身样式会把「已挂载但看不见」的遮罩当浮层,舞台升到全屏却没有任何内容(整屏空白)。 修法:加矩形非零判据(文档站逐示例预览会隐藏场景外节点,modal 的#mount实测命中); ③ 撤销时帧高不回收 —— 提升期间fitFrame()被早退跳过,而遮罩打开期间帧内容不再变化、 ResizeObserver 不回调,帧停在全屏高度。修法:撤销时显式补量一次。 - 新增门禁
npm run verify:stage-overlay(tools/verify-stage-overlay.mjs,77 条断言): A 组 8 个组件逐一点开 → 浮层尺寸必须≈宿主视口(容差 2px)+ 舞台已提升 + 滚动已锁, 关闭 → 提升撤销 + 滚动锁解除 + 帧回到内容高度;B 组 6 条反向用例(水印 / backtotop / anchornav / button / messagepro 不得提升,移动端静态站不得泄漏 PC 提升逻辑)。 已接入regression.yml。
Mobile · 移动端组件第二批收尾(弹出层系 + 展示系 + 输入系):Toast / Dialog / Grid / Steps / NoticeBar / NumberKeyboard / DatePicker(索引 11 → 18)
起因:按批次继续开工,把 ROADMAP S7-P23 的剩余 7 个组件做完 —— 规格 §12~§18 本轮新写 (契约的唯一授权来源必须先于实现),再按
PLATFORMS.md§四 六步流程落地为 6 端实现。 索引 11 → 18,frameworks-mobile/66 → 108 个文件(18 × 6 端)。
- 七个新组件(规格小节 → slug / 前缀):
- 轻提示 Toast(§12 →
mobile-toast):tone五语气 +position三位置 +mask; 容器role="status"+aria-live="polite"(结果朗读一次不反复打断);tone=loading时图标旋转并标aria-busy。 - 对话框 Dialog(§13 →
mobile-dialog):variant= confirm(两按钮等宽)/ alert(单按钮铺满)+tone= danger +round;closeOnMask可关;role="dialog"+aria-modal+aria-labelledby;按钮热区 ≥44px。 - 宫格 Grid(§14 →
mobile-grid):columns2/3/4 +border+square;可点格子是原生 button(整块热区 + 键盘可达),static格子是 div 且不绑点击 —— 直接规避「鼠标专用交互」这类无障碍缺口;按下反馈一律:active(触屏没有悬停)。 - 步骤条 Steps(§15 →
mobile-steps):direction横/纵 +status四态;role="list"/role="listitem"+aria-current="step"; 状态不只靠颜色(进行中加粗、已完成用勾选字符、失败用感叹号)。 - 通知栏 NoticeBar(§16 →
mobile-noticebar):四种语气 +scrollable跑马灯 +closable; 无障碍硬要求落地:prefers-reduced-motion: reduce下停止滚动并改为换行显示;滚动内容不用aria-live(反复朗读会干扰)。 - 数字键盘 NumberKeyboard(§17 →
mobile-numberkeyboard):type= number/digit +showDelete+showConfirm+confirmDisabled; 键盘不持有输入值 —— 只 emit 按键事件(数字键回传该字符 / 删除键回传'delete'/ 确认键回传'confirm'),写入哪个输入框由宿主决定。 - 日期选择器 DatePicker(§18 →
mobile-datepicker):mode= date/month +round+closeOnMask;三列role="listbox"/role="option"+aria-selected; 年份范围由宿主传入(years/months/days),不发明可用年份区间(契约 unknowns 已登记)。
- 轻提示 Toast(§12 →
- 配色零发明(全部既有令牌,脚本实测亮/暗两态):Toast 深底 + 反色文字 15.78:1 / 15.00:1; Dialog 卡片底 + 正文色 15.13:1 / 10.34:1;Grid / Steps / NoticeBar 沿用既有语义对(浅底 + 同族深字,均 ≥4.5:1)。
- 判据有效性用变异探针验证(5/5 当场捕获,不是「跑了绿灯」就算数):
① 向 CSS 注入
#FF0000→ B3 报出文件与色值;② 契约加一个源码没有的 prop → E4 逐端报「源码里没有」; ③ 把有默认值的 prop 标成必传 → E4b 逐端报「应相反」;④ uni-app 端注入document.querySelectorAll→ U5 报出两条规则; ⑤ uni-app 端去掉全部rpx→ U9 报「未使用 rpx」。每个探针都当场还原并复跑确认绿灯。 - 过程中发现并修掉三处真问题:
① 契约
related里写了裸名(toast/noticebar)而非真实 slug → E6c 逐条报「不存在」,已补mobile-前缀(5 处); ②tools/pack-deploy.mjs输出文案与site/m/_design_template.html里写死了组件数(前一批 8 个组件落地时漏改) → 分别改为读索引与构建期占位符注入; ③Dialog初版的圆角写在基础类上(round变体于是无意义)→ 改为由--round类控制,契约variantClasses与 CSS 双向对上。
验收(原样):
node tools/build-mobile.mjs → 18 组件 × 6 端(data.mobile.json 412 KB)· 18 测试页 · 18 文档页 · dist/mobile 全端
node tools/verify-mobile-isolation.mjs → [OK] 隔离门禁全部通过(30 条断言)— B1 18 × 6 端 108 文件 / B8 报告 18 = 索引 18
node tools/verify-uniapp.mjs → [OK] uni-app 门禁全部通过(9 条断言 · 21 个 SFC)
node tools/verify-mobile-docs.mjs → [OK] 文档完整性门禁全部通过(12 条断言 · 24 页)
REG_BASE=… verify-mobile-site.mjs → [OK] 移动端站点全部通过(118 条断言 · 21 页;演示帧 101/101 正常,0 控制台错误)
REG_BASE=… node tools/run-mobile-regression.mjs → passRate 100% | pages 18 (all-pass 18) | assertions 270/270 | N/A 6
node tools/run-regression.mjs → passRate 100% | pages 103 (all-pass 103) | assertions 1405/1405 | N/A 50(PC 零污染)
node tools/pack-deploy.mjs → OK — mobile 108 个实现文件(18 组件 × 6 端)/ 文档页 18 / 测试页 18
未执行:部署(只改工作区,未走 AGENTS §九 发布流程);uni-app 真实编译(既有状况 S7-P25,需 @dcloudio 依赖)。
Mobile · 移动端组件第二批(弹出层基座 + 展示系):Badge / Tag / Popup(索引 8 → 11)
起因:批次推进。移动端规格已写到 §9 / §10 / §11(上一轮写好但未实现),本轮按
PLATFORMS.md§四 的六步流程把三节规格落地为 6 端实现 —— 组件数 8 → 11,frameworks-mobile/48 → 66 个文件。
- 三个新组件(规格小节 → slug / 前缀):
- 徽标 Badge(§9 →
mobile-badge):shape=dot/number/text+standalone; 状态overflow(超过max显示99+)与hidden(值为 0 且未开showZero时不渲染)。 角标绝对定位、不改变被包裹元素的布局尺寸;红点aria-hidden,数字角标带aria-label。 - 标签 Tag(§10 →
mobile-tag):tone五语气(default / primary / success / warning / danger)size(default / small)+closable。关闭按钮是原生 button、24×24 热区(小尺寸标签内用负外边距扩展),aria-label带上标签文字(否则一串「✕」读屏无法区分);disabled时置灰且不响应。
- 弹出层 Popup(§11 →
mobile-popup):placement五方向(center / bottom / top / left / right)+round(贴边方向在靠内容一侧切圆角,用逻辑属性,RTL 安全);closeOnMask可关;内容超长时 body 内部滚动、 遮罩不滚;滑入 240mscubic-bezier(.32,.72,0,1);浮层role="dialog"+aria-modal,遮罩aria-hidden。
- 徽标 Badge(§9 →
- 配色零发明(全部既有令牌,脚本实测两态):实心底 +
--kole-color-text-inverse亮色 5.57–5.87:1 / 暗色 5.64–8.24:1;Tag 的浅底 + 同族字色亮色 4.68–5.38:1 / 暗色 4.92–6.91:1。 未新增任何色值,因此不需要碰 PC 令牌文件。 - 过程发现并修掉两处陈旧计数(都是前一批 8 个组件落地时漏改的):
①
tools/pack-deploy.mjs的输出文案写死「5 组件 × 6 端」(数字本身是算出来的,只有说明文字陈旧)→ 改为读索引; ②site/m/_design_template.html的「移动端 5 个组件」写死在 HTML 里 → 改为构建期占位符(由build-mobile.mjs注入实际组件数)。注:本条初版把占位符原文写进了日志正文,而
changelog.html是从本文件正文提取渲染的, 于是页面里出现了未替换的占位符 —— 被verify-mobile-docs.mjs的 E7(无残留占位符)当场拦下。 同一条纪律:日志正文里不要出现占位符形状的字面量。 - 修掉一处误报 skip:Badge 的「数值为 0(hidden)」演示块把
data-assert放在被隐藏的角标上, 断言引擎按「默认隐藏(交互后可见)」记为 skip —— 但该块本身就是「隐藏态+可见对照」的设计。 已把断言移到可见的容器上,skip 3 → 且该页断言 16 条全 pass(skip 只剩两条静态组件固有的 N/A)。 - 顺带修正 ROADMAP S7-P23 的失败判据:其中写的 PC 断言总数是 1017,实际当前为 1405(103 组件 × 5 端后未更新)。
验收(原样):
node tools/build-mobile.mjs → 11 组件 × 6 端(data.mobile.json 238 KB)· 11 测试页 · 11 文档页 · dist/mobile 全端
node tools/verify-mobile-isolation.mjs → [OK] 隔离门禁全部通过(30 条断言)— B1 11 × 6 端 66 文件 / B8 报告 11 = 索引 11
node tools/verify-uniapp.mjs → [OK] uni-app 门禁全部通过(9 条断言 · 14 个 SFC)
node tools/verify-mobile-docs.mjs → [OK] 文档完整性门禁全部通过(12 条断言 · 17 页;E8 站内链接 657 条)
REG_BASE=… verify-mobile-site.mjs → [OK] 移动端站点全部通过(83 条断言 · 14 页;演示帧 64/64 正常,0 控制台错误)
REG_BASE=… node tools/run-mobile-regression.mjs → passRate 100% | pages 11 (all-pass 11) | assertions 172/172 | N/A 4
node tools/run-regression.mjs → passRate 100% | pages 103 (all-pass 103) | assertions 1405/1405 | N/A 50(PC 零污染)
node tools/pack-deploy.mjs → OK — mobile 66 个实现文件(11 组件 × 6 端)/ 文档页 11 / 测试页 11
浏览器实测(1280×1000) → 三页各 14 个小节 / 演示块 6·5·6 / 预览帧全部有内容(0 空帧)/ 0 控制台错误
几何:Badge 角标 absolute + translate(50%,-50%)(不占位);Tag 24px 高;Popup fixed 被展示框 transform 包含块约束(关闭态位移 143.6px)
PC 常用组件补齐:103 个组件 / 组件11批次
- 对照 Element UI 2.15.14 左侧组件目录,新增 24 个 PC 常用组件:Layout、Container、Typography、Icon、Link、Radio、Checkbox、InputNumber、Switch、TimePicker、DatePicker、DateTimePicker、Form、Pagination、Badge、Avatar、Descriptions、Alert、PageHeader、Tooltip、Popover、Divider、InfiniteScroll、Drawer。
- 每个新增组件均登记设计契约、批次 11 规格、H5/CSS/React/Vue 2/Vue 3 五端源码、站点详情和测试页;PC 清单由 79 扩展为 103,frameworks 源文件由 395 扩展为 515。
- 构建、预计算、分发、族层、跨端、API 文档和路由门禁改为从 PC 索引读取组件数;不改变移动端 5 组件与 PC × uni-app 3 个试点边界。
- 新增组件使用场景覆盖后台布局、表单输入、列表分页、状态提示、详情描述、浮层和抽屉;日期/时间组件明确采用零运行时依赖的原生控件边界。
PC 组件文档改为「逐示例用法代码」——一个使用场景 = 一块预览 + 一块调用代码
起因:用户对照 Element 的 Radio 单选框 文档页指出 —— 组件文档应当直接给出
<el-radio disabled v-model="radio" label="选中且禁用">备选项</el-radio>这样的调用写法, 而不是把整份实现文件摊给使用者;并且「单个使用场景对应单个代码块」。 原形态是「一个整页 iframe + 展开看整份实现源码(Button.html 117 行 / Button.jsx 66 行)」, 使用者要自己从实现里反推调用方式。
- 每个使用场景一块卡片(
site/app.js的buildExampleCard):标题(演示页的h2/
.hint/ 契约代表变体名)→ 预览 → 只属于这个场景的代码块(H5 HTML / React JSX / Vue 2 / Vue 3 四端可切,默认跟顶栏「框架」选择器一致,可复制)。示例数据不可用时退回 「整页演示 + 整份源码」,功能不消失。
- 预览不重排:iframe 仍加载原始演示页,只把其它场景
display:none(隐藏计划在构建期 按 body 的元素下标算好)。不切 HTML 是因为演示脚本对节点有索引依赖 ——resultvariants的DATA[i]、modal的#mount一旦拆开就会渲染出错的内容。 - 片段出处三分(
site/examples/<slug>.json的source字段):demo-mapped(演示页逐字映射:btn-primary→type="primary")、demo-data(演示数据 + API 表:挂载点型组件的options/v-model)、api-derived(演示页无调用标记,依据 API 表推导最小调用)。卡片代码栏右侧标注出处。 - 不发明:片段里的 prop 名必须能指到 API 表 / 源码参数表,class 必须在该组件 CSS 里真实存在
(
npm run verify:examples的 9 条断言逐条复核;预览隐藏路径也必须能解析回演示页 DOM)。 - 数据分层:
site/examples/<slug>.json按组件懒加载,data.js只留{ id, title, source }目录 +examplesRef;data.json保持完整示例(对外承诺不变)。 - 顺带修掉:①代码区常显后暴露的暗色对比度问题 —— 代码块借
--kole-color-tooltip-bg而该令牌暗色下是浅色,补html.kole-dark .ex-code深底并把语法高亮调色板按深底实测重选 (全部 ≥4.5:1,原先hl-tag只有 2.70:1);②演示脚本钩子id(#demo-toggle)与data-behavior/data-assert不再混进用法代码;③<input>等 void 元素不再序列化成</input>。
Mobile · 组件批次推进:18 个组件 × 6 端(108 实现文件)+ 文档站 24 页,全部门禁与回归通过
起因:用户要求「参考 TDesign 移动端的组件清单,按批次补全当前组件库缺的组件」。 参考页给出 72 个组件的清单,本仓库按「规格 → 契约 → 6 端实现 → 文档页 → 门禁」的既有流水线分批推进。
- 组件从 5 扩到 18(
frameworks-mobile/108 个文件 = 18 × 6 端),规格 19 节、契约 18 份: 按 PC 同源分类:导航 4 · 反馈 7 · 通用 2 · 数据展示 3 · 数据录入 2。完整清单见site/m/index.html的覆盖矩阵与侧栏。 - 本会话直接产出的一批(A):
mobile-button(三档高度 44/36/28、loading 阻止重复触发、aria-busy)、cell(整行热区 ≥56px、按行分隔线、可点用原生 button / 纯展示用 div)、mobile-divider(水平/垂直/虚线/ 三种文字对齐,纯装饰role=separator + aria-hidden)。三者的 6 端实现、契约(含演示分组、相似组件、 必传列、CSS 变量)与规格 §6–§8 均由本会话写入;其余批次与并发会话合并完成。 - 合并时修掉两处判据问题(都是「判据太窄」而不是放宽):
- slug 允许与 PC 同名:
build-mobile.mjs与verify-mobile-isolation.mjs原先要求「移动端 slug 不得与 PC 撞名」,实际两个平台各自有「按钮」「分割线」是正常的 —— 真正要证明的是「同名也各自独立」。 改为:报告同名清单,并断言同名组件的实现文件不在frameworks/下。 dist/mobile/manifest.json的判据从「无 PC slug」改为「slug 集合与索引完全一致」—— 后者能同时抓到漏项与串入,比原来更严。
- slug 允许与 PC 同名:
- 移动端令牌层补一条全局焦点环:
:focus-visible落在移动端令牌层(不能只依赖 PC 令牌文件里那条 —— 断言引擎读的是直接 link 的样式表的cssRules,@import进来的规则不在其中)。 这既是让静态组件过focus-visible-defined断言,也是真实的 a11y 改进。 - 门禁全绿:隔离 30 条 · uni-app 9 条(21 个 SFC)· 文档完整性 12 条(24 页,站内链接 1121 条全可解析)· 移动端站点 118 条(21 页浏览器实测:0 控制台错误、演示帧 101/101 正常渲染、320–768px 无溢出)。
- 回归:移动端 100%(270 通过 / N/A 6 / 18 页) · PC 100%(1405 通过 / N/A 50 / 103 页)。
部署(AGENTS §九):pack-deploy --tar(2187 文件 / 1.65 MB gzip)→ 暂存树哈希与本地一致
(a962d7c4caa853b2)→ 替换重建 → 服务器端 specs 404 / 根 302 / sitemap 200 / healthz / SPA 深链全过、
容器 0 error;公网抽查 5 个页面全 200,site/m/index.html、site/m/component/mobile-button.html、
site/m/data.mobile.json 逐字节与本地一致。
Mobile docs · 顶栏与左栏对齐 PC(平台 / 开发指南 / 组件 N + 主题三态跨站生效)+ 补常见问题与更新日志页
起因:用户指出「导航栏需要和 PC 一致,左侧栏也是」。移动端文档站此前是自成一体的简版顶栏 (品牌 + 平台分段 + 3 个链接)与自创分组的左栏(开发指南 5 项自定名 + 手势/反馈分类), 与 PC 文档站的信息架构不一致。
- 顶栏与 PC 同结构:
logo(标记块 + Kole UI + 副标题)+版本角标 v1.0.0(读data.mobile.json的meta.version)+平台切换+主导航 5 项(组件总览 / 快速开始 / 设计规范 / 常见问题 / 更新日志, 与 PC 同名同序,组件页高亮「组件总览」= PC 在组件页高亮「组件」的同一口径)+主题模式三态。 PC 特有的三件没有搬,原因写明在site/m/style.css注释里:搜索框(PC 79 个组件才需要)、 技术栈选择器(PC 5 端各自成页;移动端 6 端同页展示)、语言选择器(移动端无 i18n 字典)。 - 主题三态与 PC 完全同一约定:
localStorage['kole-mode'] ∈ light|dark|auto、auto跟随系统、 反色靠html.kole-dark(令牌两端共用)。实测跨站生效:在移动端站选夜间 → FAQ 页仍是夜间 → PC 站同一键也是夜间;<head>里有同步 bootstrap,避免首帧先白后黑(PC 的 S2-P5 同款处理)。 - 左侧栏三段式与 PC 侧栏一致:「平台」组(PC 端组件 / 移动端组件【当前】,各带副标题)→
「开发指南」组(与 PC 同名同序的 5 项;移动端特有的「平台与端 / 测试与回归」置后并标「移动端」)→
「组件 N」按 PC 的六分类分组与计数(通用 / 导航 / 数据录入 / 数据展示 / 反馈 / 工具与系统)。
组件重新归类:navbar、tabbar → 导航;actionsheet、pullrefresh、swipecell → 反馈;
分类口径写进移动端索引的
categories块(真源),构建脚本与文档站都读它。 - 补两页:
faq.html常见问题:6 组 20 条(接入 / 令牌 / 触控 / uni-app / 排障 / 口径),每条对应仓库里可复现的 实测或门禁断言;含「uni-app 端真的编译过吗 → 没有」这类如实回答。changelog.html更新日志:构建时从仓库根CHANGELOG.md提取标题含「Mobile / 移动端」的段落 (自带一个极小的 Markdown 渲染:标题 / 列表 / 引用 / 代码块 / 行内 code 与 strong),不手抄 —— 站点与仓库两处说法不一致是这类页面的典型失败模式。
- 改名对齐:
设计令牌→设计规范(tokens.html→design.html),与 PC 的「设计规范」同名。 - 门禁 11 → 12 条:E3 从「侧栏列全组件」扩为「顶栏与左栏与 PC 同结构」(平台组与「当前」角标、 开发指南 5 项同名同序、顶栏 7 个必需元素、主导航 5 项);新增 E8 站内文件链接全部可解析(332 条)。
- E8 当场抓到两个真问题(已修):① 改名后
_index_template.html与_guide_template.html还指向tokens.html(快速开始卡片与页脚);②changelog.html的测试链接少退一级(../tests/…应为../../tests/…)。 E8 已双向验证(临时改坏一处链接 → FAIL)。 - 修:更新日志页在窄屏横向溢出(375px 溢出 88px、414px 溢出 49px)—— 提取的正文含 64 位哈希、
长路径这类不可断词的串;给正文/列表/行内 code 补
overflow-wrap: anywhere(表格此前已有同类规则)。 修后 7 页 × 4 宽度(320/375/414/768)0 溢出。
验收(原样):
node tools/verify-mobile-docs.mjs → [OK] 12 条断言 · 11 页
node tools/verify-mobile-isolation.mjs → [OK] 29 条断言 node tools/verify-uniapp.mjs → [OK] 9 条(8 SFC)
REG_BASE=… verify-mobile-site.mjs → [OK] 53 条断言(8 页 + 窄屏) npm run verify:i18n → OK(16 checks)
浏览器实测:顶栏 = Kole UI 移动端 / v1.0.0 / [PC 端][移动端] / 组件总览·快速开始·设计规范·常见问题·更新日志 / 自动模式
左栏 = 平台(PC 端组件、移动端组件【当前】)/ 开发指南 5 项 + 2 项移动端特有 / 组件 5(导航 2 · 反馈 3)
主题:选夜间 → html.kole-dark + localStorage[kole-mode]=dark;跳 FAQ 仍夜间;PC 站同键亦夜间;0 控制台错误
node tools/run-mobile-regression.mjs → 100% | 77/77 | 5/5 页
node tools/run-regression.mjs → 100% | 1026/1026 | N/A 34 | 79/79 页
node tools/pack-deploy.mjs --tar → OK(39 条必需项,含 6 张移动端根页;组件数改为从索引读取)
Deploy · 移动端组件页(TDesign 范式)已上线
按 AGENTS §九 发布:pack-deploy --tar → 上传 → 暂存归一化树哈希与本地一致(f00d3c4ac2e50861,1531 文件)→ 替换 → docker compose build && up -d。
验收:specs 404 / 根 302→/site/ / sitemap 200 / healthz 有 content-type / SPA 深链 200 / 缺快照 404 / 容器日志 0 error;
公网 https://kole-ui.mymoyu.top 抽查 6 个文件(site/app.js、组件薄壳、site/data.json、移动端文档页与演示页)逐字节与本地一致。
并发提示:本轮期间另一会话把
package.json版本重置为 1.0.0 并重建站点(data.json的generated=2026-09-20 07:36、versions.json单版本)。线上现已与该状态一致 —— 版本号本身不是本次改动;如需回到 2.0.0,请改package.json后重跑npm run build:site并再发布一次。 另:本轮第一次发布(07:26 打包)后实测到线上落后工作区 906 个文件(并发会话 07:36 重建了薄壳与app.js), 已按 §九 的约定「等稳定后重发」补发一次,现线上与工作区逐字节一致。
Mobile docs · 组件页对齐 TDesign 范式(演示分组 / 独立预览 + 原文代码 / 必传 / CSS 变量 / 相似组件)
起因:用户给了参考页 https://tdesign.tencent.com/mobile-vue/components/link。用浏览器渲染后提取其结构: 演示按
01 组件类型/02 组件状态分组;每个演示独立成块(标题 + 预览 + 代码); API 分 Props(名称 / 类型 / 默认值 / 描述 / 必传)、Events、CSS Variables(名称 / 默认值 / 描述); 另有「何时使用 / 组件搭配使用 / 推荐慎用示例 / 相似组件」。按这套范式重排了移动端组件页。
- 演示改为「分组 + 独立块」:契约新增
demos(id / group / title / desc / variant),5 个组件共 20 个演示块 (navbar 3、tabbar 4、actionsheet 4、pullrefresh 4、swipecell 4),按01 组件类型/02 组件状态分组。 每块含:标题 + 变体标记 + 说明 + 375 宽单演示预览帧 + 「查看代码」(演示页原文,行数标注,可复制)。 - 演示页支持
?demo=<id>单块模式:5 个演示页的每个演示包成<section class="demo-block" data-demo="…">,并加过滤脚本(只显示该块、隐藏帧内标题行、取消min-height:100vh)。 无参数路径完全不变 —— 测试页与回归走无参数,实测移动端回归仍 100%(77/77)。 - 预览帧高度自适应:按
body.scrollHeight收紧到 140–360px。踩坑:先用
max(body.scrollHeight, documentElement.scrollHeight)量,结果四个演示都锁在 308px ——documentElement.scrollHeight等于帧视口高度(html 撑满视口),于是「帧高 → 视口高 → 量到的高度」 形成反馈环,永远收敛在初始值。只量 body 后:swipecell 140 / navbar 140–166 / tabbar 222 / pullrefresh 242 / actionsheet 262,0 个演示被裁。 - API 补两列/一表:Props 增「必传」列(严格定义:实现里没有默认值时才为 Y,门禁逐条核对 4 个框架端);
新增「CSS 变量」表(从组件样式表扫描组件级变量:
--kole-m-swipecell-offset/--kole-m-swipecell-action-width/--kole-m-pullrefresh-threshold/--kole-m-pullrefresh-offset)。 - 新增「相似组件」表(契约
related:组件 + 「何时用它而不是本组件」的区分说明,共 10 条), 并把「用法要点」按参考页改名为「何时使用」。 - 组件页新顺序:演示 → API(Props / 事件 / 插槽 / CSS 变量)→ 何时使用 → 交互与触控 → 无障碍 → 相似组件 → 规格未定 → 结构 → 变体类名映射 → 代表变体 → 令牌 → 6 端源码 → 测试与回归 → 契约。 另在 hero 下加「引入」代码块(令牌 + 本组件样式)。
- 门禁从 8 条扩到 11 条:新增 E4b(必传 ⇔ 实现默认值)、E6b(CSS 变量表 ↔ 组件 CSS 双向)、
E6c(相似组件 slug 真实存在 + 说明非空);E5 扩为「每个演示块 ↔ 演示页
data-demo双向一致 + 预览帧带?demo=+ 代码区含转义后的演示页原文 + 每个演示代码块非空」。
验收(原样):
node tools/verify-mobile-docs.mjs → [OK] 11 条断言 · 9 页
node tools/verify-mobile-isolation.mjs → [OK] 29 条断言 node tools/verify-uniapp.mjs → [OK] 9 条(8 SFC)
REG_BASE=… verify-mobile-site.mjs → [OK] 53 条断言(8 页 + 窄屏)
npm run verify:i18n → OK(16 checks)
浏览器实测(1280×1000):分组 01/02 ✓ · 20 个演示块 ✓ · 每块预览帧只显示对应演示(4/4)✓ ·
每块有代码折叠 ✓ · 帧高自适应 0 裁剪 ✓ · 0 控制台错误
node tools/run-mobile-regression.mjs → 100% | 77/77 | 5/5 页(演示页改动后复跑)
node tools/run-regression.mjs ×2 → 100% | 1026/1026 | N/A 34 | 79/79 页
Deploy · 公网站更新到当前构建(移动端文档站四页 + 逐组件页 + PC 顶栏改动)
- 按 AGENTS §九 流程发布:
SITE_URL_BASE=https://kole-ui.mymoyu.top/ npm run build:site→build-mobile+build-uniapp→pack-deploy --tar(1531 文件 / 5.8 MB,1.0 MB gzip)→ 上传 → 备份(目录/opt/aurora-admin.prev-20260920-0712- 镜像
kole-ui-showcase:pre-20260920-0710)→ 暂存目录逐文件哈希对账 0 差异(1531/1531) → 替换 →docker compose build && up -d。
- 镜像
- 验收(服务器 127.0.0.1:3311):specs 目录 404 ✓ / 根 302→
/site/✓ / sitemap 200 ✓ / healthz 有 content-type ✓ / SPA 深层路由/site/component/button/h5200 ✓;移动端与 uni-app 路径 8 条全 200(含此前 404 的site/m/guide.html、platform.html、tokens.html);安全响应头 3 条在位。 - 公网
https://kole-ui.mymoyu.top:/site/、/site/m/、/site/m/guide.html、/site/m/component/actionsheet.html、/versions.json、/sitemap.xml全 200;data.json→lib=kole-ui/version=2.0.0/generated=2026-09-20 07:09(= 本次构建); 抽查site/m/guide.html与site/m/component/actionsheet.html的公网字节哈希与本地包逐字节一致。 - 过程发现并修掉一个会让构建直接失败的仓库状态问题:本地
Dockerfile曾带COPY 1.4.1 /usr/share/nginx/html/1.4.1行,而仓库根已无1.4.1/快照目录(并发改动期间快照被清理)——docker compose build报failed to calculate checksum of ref …: "/1.4.1": not found。该行与其后注释块("以后归档后在补一行") 的自洽性由tools/verify-versions.mjs双向卡住(磁盘快照 ↔ COPY 行),现已通过(33 checks)。注:本轮第一次发布正是卡在这条(打包与 Dockerfile 之间差了几十秒的并发改动),已重新打包发布成功。
- 修掉发布过程中暴露的 500:快照被移除后
/1.4.1/site/由「归档站」变成 500(容器日志:rewrite or internal redirection cycle while internally redirecting to "/1.4.1/site/index.html")——nginx.conf里版本段的try_files回落目标又匹配回同一 location,形成内部重定向环; 且深链/1.4.1/site/component/button/h5同样 500。修法:末位补=404,前三个参数退化为文件存在性检查 (快照在 → 发它自己的壳;不在 → 干净 404)。并给这条失败模式加了门禁:tools/verify-versions.mjs新增「versioned fallback terminates with =404」,双向验证过(改动后 34 checks 全过;把=404去掉立刻 FAIL)。 实测:/1.4.1/site/404、/1.4.1/302(再 404)、其余验收全绿、容器日志 0 条 error。归档的 1.4.1 快照内容本身没有被删除——它仍在服务器上的
/opt/aurora-admin.prev-20260920-0712/1.4.1/与kole-ui-showcase:pre-20260920-0710镜像里;仓库当前按「不归档任何历史版本」的状态(versions.json只列 2.0.0)发布,这是并发会话清理快照后的既定状态。
Mobile docs · 补全左侧栏与页面内容(API / 6 端源码 / 令牌 / 回归状态)
起因:用户指出「移动端的左侧栏内容不完整,页面内容也不够完整」。移动端文档站此前只有顶部导航 与 6 个小节的组件页,没有左侧导航,也没有 API、源码、令牌、回归状态这些"读文档的人真正要用的东西"。
- 左侧栏:所有页面共用一份 IA —— 「开发指南」5 项(移动端总览 / 快速开始 / 平台与端 / 设计令牌 /
测试与回归)+「组件 5」按分类分组(导航 / 手势 / 反馈)与计数,当前页/当前组件高亮并带
aria-current。 桌面恒定展开;≤1000px 自动收起为可折叠面板(点标题展开)。踩坑记录:左栏用
<details>承载时,不能用"去掉open+ CSS 强制展开"的写法 —— 不带open的<details>高度按关闭态算成 0,overflow:auto会把里面的 nav 整块裁掉 (DOM 里有 10 条链接、屏幕上一片空白,实测截图抓到)。改为open默认展开 + 断点脚本切换。 - 新增三页:
guide.html快速开始:三步接入、按端引入路径表(6 端)、6 端最小示例(React / Vue 3 / Vue 2 / uni-app 可拷贝代码)、与 PC 端的边界、5 条常见问题(样式不生效 /--kole-m-*取不到值 / 安全区 / 手势不触发 / 多 fixed 叠层)。platform.html平台与端:两轴覆盖矩阵、uni-app 两列对照、12 行目录与命名映射、6 条隔离规则、 6 条门禁命令(各自检查什么)、新增组件的六步流程。tokens.html设计令牌:15 个--kole-m-*表(名 / 值 / 用途)+ 组件实际引用到的继承令牌表(构建时扫描)、 单位与安全区与明暗模式三条约定、"改令牌的正确姿势"示例。
- 组件页 6 节 → 14 节:新增 API(props / 事件 / 插槽三张表)、6 端源码(每端一个折叠块 + 复制按钮)、
用到的令牌(构建时从该组件 CSS 扫描,区分自有 / 继承 / 组件级变量)、交互与触控、无障碍、
变体维度 × 类名映射、测试与回归(逐组件断言数,取自回归报告的
pageResults)、设计契约(内嵌原始 JSON)、 相关组件。 - 契约补 4 类字段:
interaction/accessibility(逐字取自规格 §x.5 / §x.6)、api(props / events / slots,写明"实现接口"的来源)、variantClasses(变体取值 → 类名/变量)。 - 新门禁
npm run verify:mobile-docs(8 条断言):页面齐全 / 组件页 14 小节 / 侧栏列全组件且恰好一个高亮 / 契约 API 与 4 个框架端源码逐名一致(正向 + 反向) / 每个声明的端都有非空代码块 /variantClasses的类与变量在组件 CSS 里真实存在 / 页面壳完整且无残留占位符。 Rationale:本站是生成物,生成器的 bug 只会让页面悄悄少一块,不会报错 —— 这类"缺内容"必须靠断言抓。 - 门禁当场抓到的真实漂移(已修):契约声明
PullRefresh.threshold,但 uni-app 端没有这个 prop(它用的是 模块常量)。已给 uni-app 端补上threshold(rpx 默认 120),并把「浏览器端 px / 本端 rpx」的单位差异写进契约描述。 - 回归报告新增
pageResults(逐页 total/pass/fail):组件页据此显示「断言 N 条 · 全部通过」。 PC 侧报告缺这一块(正是 S5-P17「失败落不了盘」的痛点),移动端先补。 - 令牌计数统一为 15:安全区两条在
@supports里各出现两次(0px 默认 +env()覆盖), 此前构建日志/数据显示 17 而映射表显示 15;现按唯一令牌名计,并给这两条补上用途说明。
验收(原样):
node tools/verify-mobile-docs.mjs → [OK] 8 条断言 · 9 页(含 API ↔ 源码逐名一致)
node tools/verify-mobile-isolation.mjs → [OK] 29 条断言
node tools/verify-uniapp.mjs → [OK] 9 条断言(8 个 SFC)
REG_BASE=… node tools/verify-mobile-site.mjs → [OK] 53 条断言(8 页 + 窄屏 3 页 × 4 宽度)
npm run smoke:site / verify:i18n → OK(16 checks)
浏览器实测:桌面左栏高度 500px / 10 条链接 / 恰好 1 个高亮;窄屏自动收起、点开可见、放大自动展开;
复制按钮写入剪贴板 2233 字符且文案变「已复制」;#api 锚点可定位;0 控制台错误
node tools/run-regression.mjs ×2 → 100% | 1026/1026 | N/A 34 | 79/79 页 | 0 超时
node tools/run-mobile-regression.mjs → 100% | 77/77 | 5/5 页 | 0 超时(逐页 14/15/16/15/17)
Design system · SideMenu 花屏修复(nav-menu 族 side 方向)+ 演示页命名统一 + 布局守卫断言(S6-P42 / S6-P44 / S6-P43)
起因:用户报告「当前的项目有花屏 bug」。定位后是 v2.0.0 族重构(
eb25fee)引入的回归, 只在direction=side上暴露;同批把「为什么 100% 回归没拦住它」「Linux 侧的命名分裂」一起收掉。
- 花屏现象与根因(S6-P42):
/site/component/sidemenu与frameworks/SideMenu.html的「代码演示」里, 二级项(全部订单 / 待发货 / 商品列表 / 分类管理)渲染成侧栏右侧一列浮块并压住同级项 (工作台的 label 盒与全部订单交叠 52×14)。两处叠加:①族模板menu.html.tpl把子级拼在.kole-menu-item内部,而该项是display:flex; height:44px→ 子级成了横向 flex 子项; ②menu.css.tpl在side方向没有折叠规则(只有top有display:none+ hover 展开)。 重构前的手写实现是「子级挂在菜单根下当兄弟节点 +.collapsed .children{display:none}」,两条都在改写时丢了。 - 修法(唯一真源
tools/lib/family-impl/nav-menu/menu.css.tpl,5 端共用一份 CSS):side 一级项flex-wrap: wrap; height:auto; min-height:44px; row-gap:0;> .kole-menu-children { flex: 0 0 calc(100% + 32px); margin: 0 -16px; display:none },.is-open时display:block;折叠态用同权重且靠后的选择器压住已点开的项。改模板后重跑node tools/gen-family-impl.mjs --only=nav-menu(三个文件的 CSS 仍逐字相同)。 - 演示页命名统一到 Pascal(S6-P44):
git ls-files跟踪的 21 个演示页是小写 (button.html/input.html/ … /sidemenu.html),而index.json的frameworksPrefix79/79 全 Pascal、 族生成器按<Prefix>.html写入、测试页 iframe 也写 Pascal → Linux 下 21 个测试页 iframe 404 (Windows 大小写不敏感把生成物折叠到小写文件上,本地完全看不出)。git mv两步改名统一后, 大小写敏感审计(data.json与测试页引用逐一与磁盘名逐字比对)不一致处 = 0;frameworks/仍 395 文件;pack-deploy的样本断言frameworks/button.html→frameworks/Button.html。 - 布局守卫断言(S6-P43):
tests/_behaviors.js新增 verblayout-menu-rows(纯几何、无交互)—— 可见叶子文本两两重叠不得超过较小者的 55% / 可见子级不得越出菜单横向边界 ±2px / 折叠态不得露出子级; 三个导航族成员加入PILOTS,族模板三个<nav>各声明一条 → 新增 9 条断言。A/B 反例:注入旧 CSS 后sidemenu两条 fail 且报错与原始花屏逐字一致(文本交叠 kole-menu-label「工作台」 × kole-menu-label「全部订单」 重叠 52×14px)。 - 顶栏窄屏溢出(同批发现):版本选择器 122px 在 375px 把汉堡挤出右边界 23px(英文 19px、360px 34px);
site/style.css在 ≤600px 收紧为 68px(与并行会话的 ≤560px 收起并存互补,覆盖 561–593px 那一档)。 逐像素扫描 320–900px 中英双语溢出量全为 0;npm run verify:nav349 项全绿。 - 判据修正(
tools/verify-versions.mjs):①路径校验改为按行为验证(抽函数体跑输入矩阵), 原按写法匹配的检查在实现改写后误报;②硬编码版本号扫描先剥注释——原判据把文档注释里的路由示例1.4.1当成了硬编码(反例已验证:代码里写var v = 'v2.0.0'仍会失败)。 - 同批修掉的构建/环境问题:
site/dev-server.js的白名单缺frameworks-mobile/frameworks-uniapp-pc(生产 nginx 走location /全放行,只有本地预览 403,移动端文档页本地打不开); 打包前SITE_URL_BASE=https://kole-ui.mymoyu.top/重建(否则 sitemap 落占位域名,verify:site-routing红灯)。 - 发布链缺陷(S6-P48,发布验收时才暴露):
Dockerfile用COPY [0-9]*.[0-9]*.[0-9]*/ /usr/share/nginx/html/打包历史快照 —— COPY 源带结尾斜杠时复制的是目录内容,于是1.4.1/快照的site/、frameworks/、sitemap.xml原地合并进站点根,用快照那份旧构建覆盖当次构建(镜像里data.js的generated是 快照那次的 05:27、frameworks/多出改名前的 21 个小写演示页),且/<版本>/目录根本没建出来 →/1.4.1/site/**全 500(S6-P45 的真因)。改为逐版本显式COPY 1.4.1 /usr/share/nginx/html/1.4.1;tools/verify-versions.mjs加三条门禁(禁通配形 / 每个快照必须有 COPY 行 / 不许留已删版本的行), 反例已验证。修复后线上/1.4.1/site/index.html由 500 → 200。 - 发布(2026-09-20 06:00 构建,部署
/opt/aurora-admin):pack-deploy --tar2914 文件 →ssh_upload(sha256 校验)→ 暂存目录与本地发布集逐字节核对 0 差异 → 目录替换 +--no-cache重建 → 五条验收全中(specs 404 / 根 302→/site// sitemap 200 / healthz 有 content-type / 深层路由 200)+ 版本 2.0.0; 公网实测https://kole-ui.mymoyu.top:data.json的lib=kole-ui、version=2.0.0、generated=2026-09-20 06:00,/site/style.css含新规则、/frameworks/SideMenu.html200、/1.4.1/site/index.html200,演示帧几何实测「子级宽 220 = 侧栏宽 221、落在栏内、父项 44→140px」。 - 归档入口 302 目标修正:
nginx.conf的版本裸入口规则注释写着「送到该版站点」, 代码却是return 302 /site/(现行版本),正则也没捕获版本号 →/1.4.1/与/1.4.1/index.html会把访问者带到现行文档,归档进不去归档。改为return 302 /$1/site/(与 dev-server 的verRoot一致); 线上实测/1.4.1/→Location: /1.4.1/site/。同时修verify-deploy-consistency.mjs的假滞后: 它直接比对响应字节,而 nginx 故意 302 的路径(根/index.html、/<x.y.z>/index.html)拿到的是 302 响应体,与磁盘文件天然不同 → 这类路径改为跳过并单独计数。 - 回归:PC 100%(1026/1026,79 页全过,0 超时);移动端 100%(77/77)。
- 并发写入说明(§九 的纪律):本轮发布期间另一会话持续改写
site/app.js、site/style.css、site/m/**、tests/mobile/**、ROADMAP/CHANGELOG/AGENTS(实测 06:24 又改了app.js并重做快照, 晚于本次打包 06:21)。线上快照 = 本次打包时刻的工作树;之后工作树的改动不在线上。 已登记 S6-P49(把「打包后工作树再被改写」变成出包时的硬判据)。
Docs site · 平台入口打通(PC ↔ 移动端)+ 技术栈选择器美化 + 本地访问方式
起因:用户要求「做一个合理的访问方式」与「当前的组件框架选择的样式需要美化一下」。 前者指:移动端文档站上线后没有入口,且本地起服务时端口被旧实例占用会静默失败(实测 403); 后者指顶栏那个裸
<select>(系统原生下拉、无悬停/展开态,与旁边的语言/主题选择器不同源)。
- 技术栈选择器改为「胶囊触发器 + 卡片菜单」(
site/index.html+site/style.css+site/app.js): 图标(层次符号)+ 当前值 + 箭头;菜单沿用语言选择器的卡片样式(标题分隔线、每项带端文件名角标html / jsx / vue2 / vue3、选中项对勾、头部右侧显示当前端文件名)。键盘全路径:↓/↑移动、Home/End首尾、Enter/Space选中、Esc关闭并回焦、Tab关闭不抢焦点、点击外部关闭; 展开态旋转箭头 + 品牌色焦点环;暗色与prefers-reduced-motion均适配。 - 原生
<select>保留为状态真源(.fw-native:1px 视觉隐藏,不进 Tab 序列): 选中项写回它的value并派发change,既有的「状态更新 / localStorage / 路由跳转」管道 与既有验证脚本(run-site-smoke读inputValue()+selectOption())一行未改。 - 侧栏新增「平台」分组:
PC 端组件(带「当前」角标与副标题)/移动端组件(副标题写清 5 组件 × 6 端含 uni-app)。移动端入口是整页跳转(指向站点根下的m/index.html)—— SPA 的路由拦截器只接管无扩展名的地址,带.html的链接交回浏览器,两个站各自独立加载。 - 移动端文档站顶栏加平台切换
[PC 端] [移动端](当前侧实心品牌底),与 PC 侧形成双向入口。 - 本地访问方式(
site/dev-server.js):端口被占用时自动向上找空闲端口(最多 10 档)并说明, 不再EADDRINUSE直接退出;KOLE_PORT显式指定时不回退(CI/脚本依赖固定端口)。 启动即打印 6 个入口:PC 文档站 / 移动端文档站 / 组件总览 / PC 测试总览 / 移动端测试总览 / 两个回归收集器,并给出REG_BASE=提示。实测踩到过:3311 上挂着改动前启动的实例时,新目录一律 403,日志里只有一句
EADDRINUSE, 极易误判成「构建没产出」。 - 修:移动端文档站在小屏上横向溢出(实测 375px 溢出 128px、414px 溢出 89px)—— 一个讲移动端的
文档站自己在手机上横向滚动说不过去。元凶两处:表格里不可断行的长路径
(
.design_library/kole-ui-mobile/components/把表格最小宽度顶到 462px)与组件页固定 375px 的设备帧。 修法:单元格与<code>允许长 token 断行、设备帧取min(375px, 100%)、顶栏 ≤720px 换行并把副导航移到第二行。 修后实测 320 / 375 / 414 / 768 / 1280 全部 0 溢出、0 控制台错误。 - 新增窄屏门禁:
tools/verify-mobile-site.mjs加「窄屏无横向溢出」一节(3 类页面 × 4 个宽度 + 控制台错误), 断言数 38 → 53。只靠"在桌面宽度看一眼"发现不了这类问题。 - 修:移动端文档站与规格文件里对
MOBILE.md的失效引用 →PLATFORMS.md(4 处源码, 生成物已重跑)。该文档在交付时最终命名为 PLATFORMS.md。 - 验证脚本同步:
verify-nav-responsive.mjs的字体容忍度元素清单随 UI 更新 (.fw-label/#fw-select→.fw-cur/.fw-menu .fw-opt)—— 清单不跟着改会把余量报得偏乐观。 实测余量 5.8%(英文 · 1367px)。
验收(原样):
浏览器功能断言(Chromium 1440×900) 25/25 PASS,全程 0 控制台错误
├ 触发器/菜单/4 选项/端文件名角标/选中态/aria-expanded
├ 选择 Vue 3 → 触发器文案 + #fw-select value + localStorage + 路由 /component/button/vue3 同步
├ 键盘:Esc 关闭、↓ 打开并聚焦当前项、↓ 环形移动、Enter 生效
├ 侧栏平台入口 2 项、href=/site/m/index.html、整页跳转到移动端站、移动端站回链 ../index.html
└ 暗色模式菜单底色 rgb(28,31,38)(跟随主题)
node tools/verify-mobile-isolation.mjs → [OK] 29 条断言
node tools/verify-uniapp.mjs → [OK] 9 条断言(8 个 SFC)
REG_BASE=… node tools/verify-mobile-site.mjs → [OK] 53 条断言(8 页 + 3 页窄屏 × 4 宽度)
npm run smoke:site → OK — all checks passed
npm run verify:nav → OK — all checks passed(余量 5.8%)
npm run verify:playground → OK — all checks passed
node tools/run-regression.mjs ×3 → 100% | 1026/1026 | N/A 34 | 79/79 页 | 0 超时
node tools/run-mobile-regression.mjs → 100% | 77/77 | 5/5 页 | 0 超时
Tooling · 发布快照一致性核对(升级验收)+ 验证脚本的跨平台/远程修正
起因:站点发布后做升级验收,要回答「线上跑的到底是工作树的哪个状态」。此前只有 AGENTS §九 里 一句手工步骤("打包前后各查一次产物哈希")—— 本轮实测线上 2908 个可比对文件里 1883 个与工作树不一致(滞后 917 / 缺失 966),手工核对不可能发现。
- 新增
tools/verify-deploy-consistency.mjs(npm run verify:deploy):按发布集枚举工作树里 会随包出去的文件,逐个拉远端同路径比对 sha256,报「一致 / 滞后 / 线上缺失」;生成物 (tests/report*.json|xml、site/data.js)单独计数不算失败。零依赖(node 内置 fetch)。--base=指向任意实例(本地 dev-server 或公网),--only=限定子串快速跑。 - 发布集抽成
tools/lib/publish-set.mjs:.dockerignore的解析与匹配语义、内容目录清单、 历史版本快照目录原先只存在于tools/pack-deploy.mjs。核对脚本必须与打包器看同一份清单 (否则又会出现"打包器说发了、核对脚本说没发"),故抽成模块供两处 import;pack-deploy重构前后输出逐字节一致(复用其自带断言:2914 文件 / 排除 26 / 断言 13+34 全过)。 tools/verify-playground.mjs两处跨平台/延迟修正(都只在对远程部署跑时暴露): ① mock 里的演示文件路径原先写死小写(/frameworks/card.html)—— Windows 不区分大小写照样过, 到 Linux 容器就是 404,改为一律从data.json的files.html派生(各组件大小写不同:Card.html/button.html);② 远程下data.json(1.36 MB)与令牌样式表比文档慢, 预检超时放宽到 30 s,暗色令牌改「等到真生效再读」,不再把"还没加载完"当成"没反色"。- 发布集同步覆盖
frameworks-mobile/frameworks-uniapp-pc(新平台上线后核对不漏检)。
深检修复批次:暗色对比度(站点 chrome)+ 两处测试侧缺陷
起因:S6-P37 交付后的深度检测(数据层审计 / 79 页巡检 / 侧栏不变量 / 暗色对比度 / 构建确定性) 报出 3 个问题(ROADMAP S6-P39/P40/P41)。本轮全部修掉,并把判据固化进验收脚本。
- 暗色对比度(S6-P39):
site/app.js的applyTheme()把暗色品牌色族的混白比例从 0.25 提到 0.45(悬停 0.6 / 按下 0.3 保持「悬停更亮、按下更暗」的次序)—— 品牌色文字常压在品牌浅底 (--kole-color-brand-bg= 同色 18% 叠卡片底)上,只混 0.25 时实测 3.59:1,低于 AA 正文 4.5:1; 提到 0.45 后 7.27:1。注意这几条是内联写在根元素上的,样式表规则压不过它们。 - 同时把「站点 chrome 的暗色对比度」纳入
tools/verify-dark.mjs第 4 组(7 条路由,正文 4.5:1 / 大字与图标 3:1,含侧栏选中态与含必填徽章的组件页)。该组一上线即抓出另外四处既有缺陷并修掉: 行内code2.88:1、.radius-demo3.44:1、.callout.note4.14:1(三者用品牌色族偏暗档 → 暗色改用基色)、.code-inline2.88:1(代码块借用的--kole-color-tooltip-bg在暗色下是浅色,与固定浅色的代码文字撞车 → 暗色改用table-header-bg,11.1:1)、.badge-opt3.08:1 与.badge-req3.71:1(亮色模式也不达标 → 改用令牌,4.88 / 5.57:1)、.callout.warn4.14:1(亮色不达标 → 文字换规格定义的#8C5A005.51:1, 暗色另给低透明底 6.49:1)。node tools/verify-dark.mjs现 DARK VERIFY OK。 verify-nav-responsive红灯(S6-P40):脚本原固定在 390px 点#lang-trigger,而工作区一度加了 「≤420px 语言选择器让位」的规则 → 元素不可见、30s 超时崩溃。改为与规则解耦:叠层检查 (语言菜单 vs 抽屉)固定放在语言选择器可见的 480px 视口,390px 段只覆盖抽屉交互本身 —— 规则在或不在都能跑。- 对比度断言采到过渡中间帧(S6-P41):
tests/_runtime.js的对比度遍历前后临时注入/移除#kole-assert-settle(*{transition:none!important;animation:none!important})——阈值不动(仍 4.5:1), 只是不再把过渡中间帧当结果(反例:DensitySwitcher 选项按钮过渡中途 1.74:1,稳定态 7.00/5.85:1)。 另把tests/_runtime.js已算好的failureDetails落进report.json与 JUnit(此前只存断言 ID, 偶发失败事后无法回溯)。验证:断言总数仍 1017,并发压测由「180 次加载失败 1 次」变为 300 次 0 失败。 - 亮色模式也补了同一类检查:把对比度探针抽成
tools/lib/contrast-probe.mjs(半透明底沿父链合成 + 正文 4.5:1 / 大字与图标 3:1 判据),verify-dark.mjs第 4 组与verify-theme.mjs新增的chromeContrastCase共用它,亮/暗各跑 3 条路由。亮色一上线又抓出两处既有缺陷:搜索框占位文字span.st-text4.23:1、搜索面板副标题span.sp-sub4.16:1(都是text-placeholder #767676压在浅底上) → 改用text-secondary(4.75:1)。node tools/verify-theme.mjs现 THEME VERIFY OK。 - 公网部署复核(S6-P38):公网
https://kole-ui.mymoyu.top/site/已是lib: kole-ui/version: 2.0.0(generated 2026-09-20 05:27,标题Kole UI · 组件库文档),AGENTS §九 四条验收全过; §九 里残留的/opt/kole-ui.staged暂存目录名与部署目录/opt/aurora-admin对齐。
Design system · 修 SideMenu 花屏:nav-menu 族 direction=side 子菜单渲染错位(S6-P42)
起因:用户报告「当前的项目有花屏 bug」。定位后是 v2.0.0 族重构(
eb25fee)引入的回归, 只在direction=side上暴露,文档站组件页与演示页同时可见。
- 现象(2026-09-20 实测):
/site/component/sidemenu与frameworks/sidemenu.html的「代码演示」里, 二级项(全部订单 / 待发货 / 商品列表 / 分类管理)渲染成侧栏右侧一列浮块,横向越出 220px 侧栏, 并压住同级项(工作台的 label 盒与全部订单交叠 52×14)。三个演示块(默认态 / 带徽章 / 折叠态)全中。 - 根因(两处叠加):①族模板
menu.html.tpl的itemHtml()把子级拼在.kole-menu-item内部, 而该项是display:flex; height:44px→ 子级被当成横向 flex 子项挤在同一行、纵向溢出; 重构前的手写实现是把子级appendChild到菜单根下当兄弟节点,故无此问题。 ②menu.css.tpl在side方向没有折叠规则(只有top方向有display:none+ hover 展开), 子级常驻渲染;重构前有.aa-sidemenu.collapsed .aa-menu-children { display: none }。 - 修法(单点在唯一真源,5 端共用一个 CSS,HTML/JSX/Vue 模板无需改):
tools/lib/family-impl/nav-menu/menu.css.tpl—— side 一级项改为flex-wrap: wrap; height: auto; min-height: 44px; row-gap: 0;> .kole-menu-children为flex: 0 0 calc(100% + 32px); margin: 0 -16px; display: none,.is-open时display: block; 折叠态用同权重且靠后的规则压住已点开的项(否则.is-open权重更高会胜出)。 改模板后重跑node tools/gen-family-impl.mjs --only=nav-menu(三个文件的 CSS 仍逐字相同)。 - 验证:几何实测 —— 未展开
display:none;展开后子级宽 220 = 侧栏宽且完整落在栏内;父项 44→140px; 可见 label 两两无交叠。top(hover 展开)与mixed未回归。回归 100%(1017/1017,79 页全过,0 超时)。 - 同批登记、未在本任务修:S6-P43(测试矩阵缺「布局包含性」断言,故本次花屏被判为全绿)、
S6-P44(
frameworks/sidemenu.html大小写命名分裂,Linux 下测试页 iframe 指向不存在的文件)。
Mobile · 移动端平台上线:与 PC 端物理隔离(平台 × 端两轴,含 uni-app 端)
起因:用户要求「在组件库额外添加移动端组件,移动端和 PC 端隔离」,并明确「PC 和移动是两个大分类, 移动端后面是 H5 移动端、Vue 移动端,而且 uni-app 也会经常用到(uni-app 移动端 / uni-app PC 端)」。 据此把组件库组织成两个正交轴:平台
pc | mobile× 端css | html | jsx | vue2 | vue3 | uniapp。 新增PLATFORMS.md(两轴定义、目录与命名映射、隔离规则、新增组件六步流程)。
- 移动端 5 个组件 × 6 端 = 30 个实现文件(
frameworks-mobile/):navbar(顶部导航栏)、tabbar(底部标签栏)、actionsheet(动作面板)、pullrefresh(下拉刷新)、swipecell(滑动单元格)。 每组件六端:CSS / H5 演示页 / React / Vue 2 / Vue 3 / uni-app。类名前缀kole-m-,导出名KoleM*。 - 移动端规格原文(本仓库自撰):
.design_library/kole-ui-mobile/spec/移动端规格.md。 PC 端规格来自外部交付的组件1~10.txt;移动端没有外部规范,故契约sourceKind: authored-spec、provenance: authored-in-repo——不冒认外部来源;契约的doNotInvent/unknowns逐条对应规格条目。 规格共 5 节(另有 §〇 隔离总则),5 份契约全覆盖。 - 令牌层:
.design_library/kole-ui-mobile/colors_and_type.css=@importPC 令牌(颜色/字体/圆角/阴影同源)- 15 个
--kole-m-*(触控 44px 最小热区、@supports (env())安全区、移动端字号、手势动效时值)。 PC 令牌文件零改动,改一处令牌两端同时生效。
- 15 个
- 隔离边界(每一条都有断言,见下):实现目录(
frameworks-mobile/vsframeworks/)、契约目录、 类名前缀、令牌前缀、测试页(tests/mobile/vstests/)、回归报告(tests/mobile-report.jsonvstests/report.json)、文档站(site/m/静态站 vssite/SPA,移动端不进 PC 路由表)、 分发产物(dist/mobile/*vsdist/*)。 - uni-app 端两处:移动端 × uni-app(5 个,目标
app-plus/mp-weixin/h5,用 uni 基础组件 +rpx+ touch 事件——小程序与 App 端无 PointerEvent);PC × uni-app 试点 3 个 (frameworks-uniapp-pc/{Button,Input,Card}.uniapp.vue,类名与 PC 的frameworks/*.css逐字一致、--kole-*令牌、px 尺寸、目标 H5/PC 容器),覆盖率 3 / 79 并登记为 ROADMAP S7-P26。 - 构建(Node,跨平台,不碰 Windows-only 的 PS 链):
tools/build-mobile.mjs(导出site/m/data.mobile.json自包含 102 KB = 5 组件 × 6 端源码、site/m/index.html总览、site/m/component/<slug>.html逐组件页、tests/mobile/**、dist/mobile/**)与tools/build-uniapp.mjs(dist/uniapp-pc/**)。 两个脚本都带写入守卫:越界路径直接抛错(移动端脚本只允许写site/m/tests/mobile/dist/mobile/)。 - 测试:移动端测试页以 375×640 设备帧 iframe 载真实演示页;断言引擎与 PC 共用
tests/_runtime.js; 行为库为移动端专属tests/mobile/_behaviors.js,新增 3 个触控动词swipe-sets-class/swipe-sets-attr/pull-triggers(合成pointerdown → pointermove → pointerup手势,断言类/属性真实变化)。 两端行为库互不加载,PC 侧 6 试点组件不受影响。 - 门禁与 CI:
tools/verify-mobile-isolation.mjs(28 断言:PC 零污染 / 移动端自洽 / 分发隔离)、tools/verify-uniapp.mjs(9 断言:SFC 三段 /node --check语法 / 标签配平 / 禁 DOM API / 手势必须 touch / 只用 uni 基础组件 / 前缀隔离 / 单位策略)、tools/run-mobile-regression.mjs。regression.yml新增:构建分发产物 → 移动端生成物可复现性断言(git diff --quiet卡"改了索引忘重跑构建") → 两条门禁 → 移动端回归 → 报告上传与摘要(PC 与移动端两段)。 - 部署:
tools/pack-deploy.mjs的CONTENT_DIRS增frameworks-mobile、frameworks-uniapp-pc, 新增 6 条硬断言(移动端 30 实现 / 5 文档页 / 5 测试页 / 3 试点);Dockerfile增两条COPY;.dockerignore显式排除.design_library/kole-ui-mobile/spec(移动端规格原文与 PC 规格同策略不进镜像);site/dev-server.js白名单增两个顶层目录。
验收(原样):
node tools/verify-mobile-isolation.mjs → [OK] 隔离门禁全部通过(28 条断言)
node tools/verify-uniapp.mjs → [OK] uni-app 门禁全部通过(9 条断言 · 8 个 SFC)
node tools/run-mobile-regression.mjs → passRate 100% | pages 5 (all-pass 5) | assertions 77/77
node tools/run-regression.mjs ×8 → run 1..8 全为 100% | pass 1017 | fail 0 | na 34 | pages 79/79 | timedOut 0
node tools/pack-deploy.mjs → OK:components 79 薄壳/395 实现 · mobile 30 实现/5 文档页/5 测试页 · uniapp-pc 3 试点
未执行(写明并给复现命令,见 ROADMAP S7-P25):uni-app 真实编译(H5 / 微信小程序 / App)——
需 @dcloudio/vite-plugin-uni,与零运行时依赖不冲突但会污染主回归 job 的依赖,故本次只做静态门禁;
复现命令写在 tools/verify-uniapp.mjs 头部。
Docs site · 主题模式默认改为「自动」(日间 / 夜间 / 自动 三态)
起因:用户要求「添加合适的日间/夜间/自动选择模式,默认为自动」。三态 UI(顶栏模式菜单、 H5
ThemeSwitcher、在线测试页)此前已在,缺的是默认值:没有显式选择时回退light。
- 默认值:
kole-mode缺省 / 无法识别 / 被清空 一律为auto(跟随系统prefers-color-scheme); 首次加载把默认值落盘,之后各标签页由storage事件保持一致。改动点:site/app.js(MODE_DEFAULT+normalizeMode/readMode,applyMode(mode, persist)增加落盘开关)、site/playground.js、frameworks/ThemeSwitcher.html。 - 无闪烁:
site/index.html与site/playground.html的<head>加解析期 bootstrap, 在首个<link>/脚本之前就定好kole-dark类,避免「先白后黑」。 - 原生控件跟随:令牌文件
:root加color-scheme: light、html.kole-dark加color-scheme: dark(暗色下滚动条 / 表单 / 系统色不再留在浅色);两页再补<meta name="color-scheme" content="light dark">。 令牌数与三格式导出不变(仍 106 tokens)。 - i18n:新增
{m}(当前:{e})词条,模式名与「当前生效」改为整句翻译,英文下不再出现中文残段。 - 验证:
tools/verify-theme.mjs从 24 条扩到 38 条,覆盖「首访默认 auto(含系统夜间 + 切回日间即时反色)」 「默认值静态卡口」「bootstrap 先于 data.js」「ThemeSwitcher / playground 默认自动」。 - 顶栏常驻入口(同日追加):此前模式切换只在右下角悬浮按钮里,顶栏看不见(用户实测反馈「导航栏没有选择主题」)。
现于顶栏「框架选择器 → 语言选择器」之间加常驻触发器(图标 + 当前模式名),与悬浮按钮共用同一份状态:
两入口互斥展开、Esc 关闭、
aria-checked/aria-expanded同步。响应式降级:>1100px 显示模式名, ≤1100px 只留图标(与语言选择器同一档),≤560px 框架选择器整块收起,≤340px 语言选择器让位—— 320px 顶栏溢出 54px 由此消除(只量顶栏自身;首页内容另有 15px 既有溢出,不在本次范围,另记 ROADMAP)。 触发器不加下拉箭头:顶栏在 1367px(英文、导航尚未折叠)只剩 2px 余量,箭头会直接溢出 6px。 - 新增断言:
verify-theme.mjs覆盖顶栏入口可见性 / 默认选中自动 / 选夜间生效并落盘 / 模式名同步 / 两入口互斥 / Esc 关闭 / 375px 与 320px 降级;verify-nav-responsive.mjs18 宽度 × 中英双语全过。 - 视觉打磨(同日追加):顶栏触发器加 15×15 图标底衬(
--kole-color-table-header-bg,hover / 展开转品牌浅底); 菜单头改为两行(「当前选中」+ 自动模式下补「实际生效」,生效主题用品牌色强调)—— 单行拼接在英文下会折行;菜单宽度 168 → 184px、选项高度 32 → 34px、加 160ms 展开动画; 选中行加inset 2px左侧品牌色条(浅底在暗色下对比有限);三态色标改为语义化配色: 日间 = 白底、夜间 =--kole-color-page-bg、自动 = 左右半分渐变(直接表达「跟随系统」)。 踩坑记录:色标最初用--kole-color-tooltip-bg,而它是反色工具提示底(亮色下深、暗色下#E8EAED浅), 当「夜间」色标正好反掉,已改用页面底色令牌。 - 降级阶梯补齐(同日追加):
≤560px版本选择器(#ver-select-wrap,实测 122px)让位 —— 它是 ≤900px 接管出现的,加上主题入口后 375px 溢出 23px(中英皆是)。版本切换在更新日志页仍有入口。
Docs site · 内容与信息架构对齐 Element 文档站(侧栏分组 / 快速开始叙述 / 组件页 API 说明)
起因:用户以 Element UI 文档站(element.eleme.cn)为参照,指出「快速入门等地方的描述更好, 还有组件页面等内容,还有左侧导航栏内容」。三块逐项对齐,但不照搬其 API 表的「可选值」列—— 本仓库没有可引用的枚举数据源(见下)。
- 侧栏(
renderSidebar):页面链接原先平铺在侧栏顶部、无归属标签,现按 Element 口径分为 「开发指南」(组件总览 / 快速开始 / 设计规范 / 常见问题 / 更新日志)与「组件 N」两个段标题; 「更新日志」此前在侧栏没有任何入口(ROADMAP S5-P24 的实测表长期记着「维持原状」),本次补齐。 段标题用.side-section与可点的分类组(.side-group)区分开。 - 快速开始(
renderGuide):改为 Element 式的分步叙述 —— 开头一句「本节将介绍…」+ 5 条步骤清单 (.guide-outline),每节先说明再给可拷贝的代码;补上 Element「全局配置」段在本系统的对应物 「全局配置(主题与暗色模式)」(令牌覆盖 +html.kole-dark用法);收尾加「开始使用」四张下一步卡片; 并按 Element 的「完整引入 / 按需引入」对位说明本系统的口径(组件以源码发布,取哪几个文件即按需; 全量样式用聚合文件components.css)。共 7 节,右侧目录同步。 - 组件页 API 表(
buildApiSection+tools/precompute.mjs):说明列原先 235 条里 230 条是—(只有源码里写了注释的才有),事件说明则是模板句(「组件交互触发事件」占多数)。现改为构建期按 出处生成、每条都标注来源:规格(29 条,命中规格原文分条,title逐字引用该条,如 Buttontype→ 「类型:主按钮、次按钮…」)/ 命名(204 条,API 名释义,明确标注「非规格原文」)/ 源码(1 条注释)/ 契约(1 条 dims);事件说明由 emit 调用点判定,同一事件名在不同组件里 语义不同(ok:modal / fullscreenmodal 绑确认按钮 → 「点击确认按钮时触发」,alertmodal@click.self绑遮罩 → 「点击遮罩时触发」),98/98 全部具体化,不再有模板句;表头上方加出处图例。 - 不做「可选值」列(有意):Element 那一列靠其运行时枚举,本仓库实测没有等价数据源 ——
从 5 端源码反推比较字面量只覆盖 12/235(5%) 且多为
1/number这类噪声,规格原文里 真正枚举取值的只有 2 条。硬填等于发明,违反契约doNotInvent口径;改为把规格里确实枚举了的 取值以「取值:主按钮 / 次按钮 / …」副行带出 —— 深度检测后又收紧了这道闸门:初版命中 4 条, 其中card.title/modal.title命中的是「结构:标题区、内容区、操作区」这类结构描述 (枚举的是卡片分区,不是 title 的取值),tag.color还切出了绿#F6FFED/#52C41A等)碎片。 现要求「分条标签 === 该 prop 的说明」且片段不含#/ 括号 /px,最终只保留button.type1 条 (类型:主按钮、次按钮、文字按钮、链接按钮、危险按钮),其余留空。 - 新增元素的对比度:
.side-section(段标题)与.api-src(出处标记)初版用--kole-color-text-placeholder(#767676),在页面底色 #F5F7FA 上只有 4.23:1,达不到 AA 正文 4.5:1; 改用同族.side-group已在用的--kole-color-text-secondary后为 4.66:1(悬停行)/ 4.75:1(页面底), 暗色 5.65:1 / 7.12:1。深检另发现一处既有缺陷(暗色选中态文字 3.59:1)与两处测试侧问题 (verify-nav-responsive红灯、对比度断言采到过渡中间帧),按仓库规矩记为 ROADMAP S6-P39 / P40 / P41, 未在本任务内顺手修。 - i18n:新增英文词条 166 条(含上述 106 个属性释义、29 个事件说明与新增 UI 文案),
tools/verify-i18n.mjs的「literal T() coverage」从 289 键缺 1 到 289 键全覆盖。
验收:verify-i18n 16 项全过;verify-site-routes / run-site-smoke / verify-theme 全过;
数据层审计 9 项(含「cite 逐字出自规格原文」)、79 页浏览器巡检(零报错/零 4xx/说明列无空值)、
侧栏高亮不变量(8 路由 × 双语)、precompute 幂等与两次运行逐字节一致 —— 全过;
回归 100%(1017/1017)连跑 8 次一致,深检复跑 10 次仍 100%。
(verify-nav-responsive 当前红灯,原因是工作区里新增的 ≤420px 隐藏语言选择器与脚本固定 390px 的点击冲突,
见 ROADMAP S6-P40,非本改动引入。)
Docs site · 「在线测试」预览帧:修掉资源解析错误 + 沙箱收紧 + 三处丢改动缺陷
起因:站点已通过 frp + EdgeOne 暴露到公网(
https://kole-ui.mymoyu.top/site/), 「在线测试」是全站唯一把用户编辑的 HTML 灌进 iframe 执行的地方,因此按不可信内容重新过一遍。
- 预览帧的组件样式一直没加载(79 个组件里 36 个命中):
srcdoc的基准 URL 继承父页 (/site/playground.html),演示源码里的href="./Xxx.css"于是解析成/site/Xxx.css—— 本地 404、线上 404(实测https://kole-ui.mymoyu.top/site/AnchorNav.css→ 404, 而.../frameworks/AnchorNav.css→ 200)。受影响的 36 个组件在预览里丢掉整个组件 CSS, 只剩内联<style>。修法:渲染前在文档最前注入<base href="../frameworks/">(放在<!DOCTYPE>之后,避免掉进怪异模式),让预览的资源解析与「演示原页」逐字一致; 注入的 base 是文档里第一个 base,用户代码里再写 base 也覆盖不了。 - 帧内策略收紧(只写比父页更严的项):注入
meta CSP,把connect-src/form-action/frame-src/object-src一律置'none'—— 帧内彻底发不出网络请求。两条 CSP 取交集, 所以这里每一项都只会收紧;父页 CSP 继续负责"允许什么"(style-src 'self'等), 本页不重复声明,避免把'self'在不透明源下的解析差异带进来。 - 沙箱边界用探针服务器实测,而不是读代码:新增
tools/verify-playground.mjs,脚本内起一个 本地 HTTP 探针,帧内发起的每个请求都会落在它身上。实测(Chromium,sandbox="allow-scripts", 无allow-same-origin):location.origin === 'null';parent.document/top.document/document.cookie/localStorage全部SecurityError;window.opener为null;window.open返回null(缺allow-popups);表单提交、子帧、外域样式/@import/图片 全部被拦;fetch/sendBeacon/WebSocket被 CSP 拦下。探针 0 命中。 父页侧另有 nginx/dev-server 的 CSP +X-Frame-Options: SAMEORIGIN+Referrer-Policy: no-referrer(线上实测这些响应头经 EdgeOne 完整透传)。 - 帧内报错不再静默:注入一段上报器(跑在用户代码之前)捕获
error/unhandledrejection/securitypolicyviolation,用postMessage回传,预览上方以 纯文本提示(.pg-note)。父页只认「event.source严格等于本页预览帧」的消息, 且只取字符串渲染、每次渲染最多显示 3 条 —— 预览里的代码无法借此碰本页 DOM,也无法刷屏。 - 三处会丢改动的缺陷:①切组件会静默丢弃未复位的编辑 → 现在先
confirm(), 取消则编辑器与选择器都留在原地;②源码拉取失败时旧实现会pristine = ''; editor.value = ''清空编辑器 → 现在失败一律不改状态(编辑器、预览、选择器全保持原样,只报错); ③刷新/关页同样丢改动 → 补beforeunload(仅在"改过且未复位"时拦)。 另把防抖清理提前到load()开头(异步回落路径下,挂着的定时器会把上一个组件的内容渲染到新组件头上)。 - 预览帧内自己跳走会让预览失效且不可恢复:
<meta refresh>或location.href会让帧离开srcdoc(实测落到chrome-error://chromewebdata/,状态行却仍显示"已同步")。父页读不到 帧去了哪(不透明源),唯一能感知的是load:新增看门狗 —— 凡是不是本页触发的加载, 就地重建预览并标注原因(实测帧回到about:srcdoc后脚本从头跑一遍,预览恢复可用)。 - 行为反转(原为「有意保留的差异」):预览帧现在跟随站点暗色。原实现之所以反不了色,
是"帧是不透明源 → 父页注入不进
kole-dark"这个机制限制,不是设计取向(S5-P23 已把 演示原页的取向定为「站点暗色时演示页也反色」)。在线测试页唯一可用的注入点是源码, 因此改在注入内容里带一个类;实测站点kole-mode=dark时帧内documentElement.className含kole-dark、--kole-color-page-bg解析为#14161C。 另补storage监听:在文档站切主题,本页预览跟着重渲染。 - 验收:
npm run verify:playground→ 38 条断言全过(含全 79 个组件逐个切一遍、36 个带./引用的组件 CSS 确实从/frameworks/取到 200、探针服务器 0 命中、脏状态两条离开路径、 失败不改状态、帧内跳转重建、报错回传、暗色跟随、全程 0 个 4xx);已接入regression.yml。 回归 100%(79/79 页、1017/1017 断言、N/A 34、0 超时)连跑 8 次一致;verify-site-routes24/24、smoke:site全过、verify:i18n16/16。 - 未执行:未部署。工作树领先线上 1229 个文件(
site/data.json、site/playground.*均与线上 哈希不同),按 AGENTS §九 走pack-deploy会把在飞的 S6 组件族改动一并发布 —— 这属于发布决策, 留给用户定;命令见 ROADMAP 新增条目。
Docs site · 文档站路由去掉 #(hash → History API)
- URL 形态:
/site/#/component/button/h5→/site/component/button/h5,/site/#/overview→/site/overview。站内跳转改走pushState局部渲染(顶栏/侧栏/总览卡片/搜索/相关组件/上下篇统一收敛到go()+ 一处捕获的链接拦截),浏览器前进后退走popstate。旧链接仍可用:加载时就地replaceState成无#地址且不留历史记录(实测/site/#/component/modal→/site/component/modal并正常渲染)。 - 深层路径要服务器接住:磁盘上没有
/site/component/button/h5这个文件。三处回落同时补上 ——nginx.conf新增location /site/回落到try_files $uri $uri/ /site/index.html(另加一条正则 location,带扩展名的缺失资源仍回真 404,不会把 HTML 当 JS/CSS 发出去)、site/dev-server.js新增isSpaRoute、GitHub Pages 发布包多放一份site/index.html副本作404.html(Pages 无重写规则,深链与刷新靠它接住)。 - SPA 壳的路径基准:
site/index.html顶部内联脚本从pathname里第一段/site/反推站点根,写<base>并暴露window.KOLE_SITE_BASE;site/app.js的SITE_BASE用同一条规则(tools/verify-site-routing.mjs会静态卡这两处一致)。部署前缀因此可变(本地/nginx 是/site/,Pages 是/<repo>/site/),代价是站点目录必须继续叫site。 - 资源改绝对地址写出:
<link>/<script>不能再写静态相对路径 —— 预扫描器在脚本执行前就按深层 URL 预取,实测多出 2 个 404 + 2 条控制台报错,data.js(precompute 后 122 KB)还会被整份白取一次。改成先document.write('<base …>')再输出base + 'xxx'的绝对地址后,深链冷加载 10 个请求 / 0 个 4xx / 0 条控制台报错,且<script>仍是解析期同步按序执行,语义与静态标签一致。 - 静态入口页跟着改:
build-site.ps1生成的 79 薄壳 + 316 平台壳,重定向目标改成../component/<slug>与../../component/<slug>/<platform>(重跑npm run build:site);tests/_template.html的「← 文档站」链接改成../site/component/<slug>(重跑run-tests.ps1,79 页);site/llms.txt的页面链接同步去掉#。 - 验收:新增
tools/verify-site-routes.mjs(浏览器级,24 条断言全过,已接入regression.yml)—— 深链渲染、URL 无#、--kole-color-brand令牌生效、冷加载 0 控制台报错 / 0 个 4xx、旧#就地改写、顶栏/侧栏/搜索跳转不整页刷新、框架切换写进 URL、前进后退、深链刷新、薄壳重定向、缺失的带扩展名资源回真 404、「在线测试」这类相对链接仍解析到站点根、file://降级(pushState不可用时退回 hash 形态,实测仍能渲染);verify-site-routing79 组件 / 316 平台壳 / 396 URL 全过(新增:两处 SITE_BASE 同规则、<base>引导、nginx/dev-server/Pages 三处回落、薄壳无#残留);smoke:site、verify:nav、verify:i18n16/16、verify-dev-server20/20、pack-deploy全过;回归 100%(79/79 页、1017/1017 断言、N/A 34、0 超时)连跑 8 次一致(同一状态另跑 54 次,见下条)。 - 发现(与本改动无关,已记为 ROADMAP S6-P32):跨批次整轮连跑 62 次中有 2 次非 100%,捕获到的那次是
densityswitcher的matrix:contrast>=4.5读到了颜色过渡中间态(button.kole-densw-opt "默认" 4.46:1 < 4.5:1)。实测两端点都达标(生效后 5.85、未生效 7.00),过渡途中会穿过 4.5 以下(7 → 1.79 → 2.4 → 4.58 → 5.85);tests/_runtime.js的就绪轮询只看 innerHTML 是否稳定,而过渡期间 innerHTML 不变,拦不住。单页压测 300 次命中 2 次。旁证它不来自本次改动:测试页只改了一行「← 文档站」链接的href,断言引擎对该链接零引用(grep -c 't-btn\|文档站\|t-nav'= 0),断言全部跑在未改动的frameworks/<Prefix>.html帧内。 - 顺带修正:
site/llms.txt「文档站页面」列表里还挂着#/agents—— 该页早已随 AI 消费模块删除(路由与 i18n 词条都不存在),已删掉这行;AGENTS.md铁律 2 里data.js的 1058 KB / 942 KB 是旧值,按 2026-09-20 实测改为 1166 KB / 122 KB。
Docs site · 代码与演示都整段展示(去掉两处内滚动)+ 演示帧暗色真正生效
- 代码不再截断:
.demo-code pre原有max-height: 420px,长源码要在约 21 行的窗口里滚(cascader 7742 字符)。去掉 max-height(Element 文档同样显式max-height:none),整段随页面滚动;长行仍可横向滚动。实测 5 个组件代码块纵向滚动量全为 0。 - 演示整段展示:
.demo-stage iframe固定height: 420px,比它高的演示在帧内出滚动条(滚轮滚的是 iframe 而不是页面)。新增autoSizeFrame():帧load后按body.scrollHeight + margin(documentElement.scrollHeight更大时取后者,否则短内容收缩不下去)写实际高度,配ResizeObserver跟随帧内异步渲染(加载态 / 展开行),换页时releaseFrameFits()摘掉观察器与 resize 监听;420px 降级为 CSS 兜底。实测帧高贴内容:button 571 / cascader 394 / table 413 / watermark 330 / expandabletable 311,帧内滚动量全为 0。 - 代价:演示帧沙箱放宽到
allow-same-origin(sandbox属性保留,继续挡表单提交 / 顶层跳转 / 弹窗)。理由:该帧加载的是一方文件frameworks/<组件>.html,与文档站同信任级;用户可编辑的代码只在「在线测试」页里跑,那边仍是严格沙箱。而量不到contentDocument就做不了自适应高度。 - 顺带修掉 S5-P23:正因为放宽了沙箱,
injectIframeTheme()不再于if (!d) return静默返回 —— 实测站点kole-mode=dark时帧内documentElement.classList.contains('kole-dark') === true、帧 body 背景rgb(20,22,28)。v1.1.1 声称的「演示 iframe 注入 kole-dark 同步反色」到现在才真正成立(在线测试页的预览帧保持浅色,是有意保留的差异)。 - 验收:
verify:i18n16/16、smoke:site全过、verify-site-routing79 组件 / 316 薄壳 / 396 URL 全过、pack-deploy断言全过;回归 100%(79/79 页,1017/1017 断言,N/A 34,0 超时)连跑 3 次一致;浏览器侧复测在线测试实时预览闭环(注入标记 → 帧内出现 → 复位消失)、首次展开填充(cascader 7742 / tree 5194 字符)、入口新标签与英文文案(Show code / Hide code / Playground →),0 报错。
Docs site · 侧栏「组件总览」降级为独立页面索引(不再兼作分节父项)
- 现象:进入任意组件详情页,侧栏同时高亮两项 —— 「组件总览」与当前组件。两者样式逐属性相同(
site/style.css的.side-link.active228 行 /.side-item.active264 行),并列两块蓝底,读起来就是「选了两个」。 - 根因:
site/app.js的侧栏高亮规则写作r === 'overview' || r === 'component'—— 让「组件总览」兼作整个组件区的分节父项。该规则出自 v1.2.0 初版提交(git log -S溯源),非后期回归。 - 改法:「组件总览」只代表自己那一页(
active: r === 'overview'),与「快速开始 / 设计规范 / 常见问题」三条同级。顶栏「组件」保持分节语义不变 —— 顶栏没有逐组件入口,去掉后组件页将无任何顶栏高亮。 - 语义层无变化:
aria-current="page"本就只加在真正的组件项上(renderSidebar里给当前 slug 那一条),屏幕阅读器读到的始终是正确的一项,本次只修视觉层的重复高亮。 - 实测(Chromium,本地 dev-server,逐路由探针):组件页侧栏高亮数 2 → 1;
#/component/button|modal|table侧栏均为[组件名]且「组件总览」不再命中;#/overview仍为[组件总览];#/design、#/guide、#/faq各 1;#/changelog为 0(无侧栏入口,维持原状)。 - 登记缺口:
tests/与tools/中无任何断言涉及side-link/side-item的选中态,故此类回归在八次连跑中不可见 → 已追加为 ROADMAPS5-P25。 - 验收:回归 100%(79/79 页,1017/1017 断言,N/A 34)连跑 8 次一致、0 超时。
Docs site · FAQ 问题搜索对齐全局组件搜索(Ctrl+K)
- 起因:页面描述写着「支持按组件浏览与关键词过滤」,实际只有「输入 → 隐藏不匹配项」一条路径:没有命中高亮、没有键盘路径、没有范围限定,也搜不到「按钮」这种组件名之下的全部问题。
- 对齐全局组件搜索(直接复用弹窗里的
hiMark()/fuzzySubseq()与.sc-chip样式,交互同源):- 命中高亮:问题正文命中用
<mark>标出片段;命中来自组件名时标记落在分组标题上。 - 搜索范围扩到组件名 / slug:输入「按钮」会保留整个按钮组(实测 3/3 条全在)并高亮标题;
qrcode这类 slug 同样可搜。 - 类别 chips 限定范围:全部 + 六大类,样式与搜索弹窗一致;实测切到「导航」范围收窄到 35 条 / 10 个组件,切回「全部」完整还原 244 条。
- 键盘全路径:
↑/↓在命中项间循环移动并平滑滚到视区中央、Enter把焦点落到该问题、Esc清空查询(空查询再按一次才退出焦点)、/一键聚焦搜索框(框内常驻kbd提示,输入后让位给自绘清空按钮)。 - 模糊回退与空态:无精确命中且查询 ≥2 字符时回退子序列匹配,结果行标注「(模糊匹配)」;彻底无命中时显示空态并隐藏列表。
- 状态记忆:查询与类别范围存
state.faqQ/state.faqCat,离开页面再回来仍在(实测往返后仍 11 条命中)。
- 命中高亮:问题正文命中用
- 实现细节:
/快捷键一次性绑定(renderFaq每次进入该页都会重跑,直接在内部注册document监听会不断累积);隐藏原生::-webkit-search-cancel-button改用自绘清空按钮,避免与kbd提示重叠;↑↓移动用共享的visible[]+.hover类,与弹窗同款焦点反馈。 - i18n:新增 6 条(
清空搜索/按 / 聚焦搜索/无匹配问题/无匹配问题(已尝试模糊匹配)/(模糊匹配)/↑↓ 定位 · Enter 跳转 · Esc 清空),英文侧沿用「空格烘进词条值」的既有约定(如条,),verify:i18n261 键全覆盖。 - 已知数据限制:FAQ 条目正文取自契约原文(中文,无英文译文),故英文界面下英文关键词只能命中组件名 / slug(实测
button命中按钮组并高亮标题;中文关键词「宽度」在英文界面照样可用)。属数据层现状,本轮未改。 - 验收:33 项浏览器断言(高亮 / 组件名与 slug / chips 范围 / 方向键移动与滚动 / Enter 焦点 / Esc 清空 / 模糊回退 / 空态 /
/快捷键 / 清空按钮 / 查询持久化 / 中英双语 6 条文案);smoke:site30/30、verify:i18n16/16、上一轮的 30 项站点断言(语言下拉 / 首页核心区 / FAQ 搜索框)全部仍过、verify:theme/verify-dark/verify-site-routing全过、零运行时依赖不变;回归 100%(79/79 页,1017/1017 断言,N/A 34)连跑 8 次一致、0 超时。
Docs site · 试玩改为独立「在线测试」页 + 代码区控制条对齐 Element
- 起因:组件详情页的「▶ 在线试玩」是内联 textarea —— 一枚胶囊按钮悬在演示区与代码区之间的白缝里,与页头「测试页 →」并排看像两个近义入口,归属和用途都含糊。
- 新增「在线测试」独立页(
site/playground.html+site/playground.js):控制条右侧常显「在线测试 →」,新标签打开playground.html?slug=<slug>—— 左侧编辑 H5 源码、右侧 iframesrcdoc实时预览(300ms 防抖),79 组件可切换、复位 / 复制源码 / ↗ 演示原页 / ← 文档站,Tab 缩进两格、Ctrl+S 立即同步,状态行回显「已同步 HH:MM:SS(已修改)· 已复位」。数据单请求取自同目录data.json(sources.html多数内联,缺省回落files.html),零运行时依赖;暗色与文档站共用同一个localStorage['kole-mode']。 - 控制条改为 Element 同款:44px、居中「▼ 显示代码 / ▲ 隐藏代码」、文字悬停或键盘聚焦才浮现(
.lblopacity 0→1,:focus-visible一并覆盖)、悬停底色table-header-bg+ 品牌色。整条不再可点:按钮管折叠、链接管跳转(此前整条div挂点击且无键盘路径)。 - ⚠️ 反转既有决定:代码区默认收起(对齐 Element)。此前记过「默认展开:省掉一次点击」,本次按「以下拉条参考 Element」的要求改为收起 —— 页面因此可扫读,要读源码点一下,要动手改则走在线测试页。已专门验证没踩回历史坑:代码区改为首次展开才构建,实测全新加载 → 首次展开即有内容(cascader 7713 / tree 5159 字符,与当年验收数字一致),CSS tab 正常(button 2122 / cascader 3552 / tree 1067)。改回默认展开只需
var open = false→true。 - 顺带修正「测试页 →」掉出标签行:该链接此前 append 到
.detail-head而非.chips,脱离 flex 行后只剩.chip浅色底,在页头与「何时使用」之间单独占一行;同类的「规格文件」「契约 JSON ✓」都在行内,已改挂到.chips末尾。 - 删除内联试玩:
play-btn系按钮、.demo-playbar、.pg-textarea、currentHtml()轮询一并移除;i18n.js清掉 6 条只服务于它的键(✎ 在线试玩/● 试玩中/退出试玩/复位/展开代码/在线编辑 H5 演示源码…)与此前已无人引用的试玩/仅 H5 形态支持在线试玩,新增「在线测试 / 显示代码 / 隐藏代码」。.play-btn样式保留(app.js错误态的「重试」按钮仍在用)。 - 实测(Chromium 1440×900,本地 dev-server):预览帧内
document.querySelectorAll('.btn').length = 16、首按钮背景rgb(47,84,235);源码尾部注入<div id="probe-marker">→ 帧内出现、复位后消失;切到table后 URL / 标题 / 编辑器(6587 字符)/ 预览同步;控制条 44px、aria-expandedfalse→true、aria-controls=demo-code-button;kole-mode=dark下页面与代码面同为rgb(20,22,28);两页 0 控制台报错。 - 验收:
verify:i18n16/16(T()覆盖 258 键,独立复算 0 条未收录)、smoke:site全过、verify-site-routing79 组件 / 316 薄壳 / 396 URL 全过;回归 100%(79/79 页,1017/1017 断言,N/A 34,0 超时)连跑 3 次一致。 - 登记缺陷(同日已修):
sandbox="allow-scripts"的演示帧是不透明源,父页iframe.contentDocument实测为null→app.js的injectIframeTheme()恒在if (!d) return静默返回,暗色模式下演示帧当时不会反色(ROADMAP Q6 原记为「设计取向待定」,实为机制从未生效)。已登记 S5-P23,并在同日的下一条改动(放宽演示帧沙箱以做自适应高度)中一并修复。
Docs site · 删除 AI 消费模块 + 首页核心组件改用总览同款卡片 + 修 FAQ 搜索框
- 删除「AI 消费」(For Agents)模块:顶栏导航项、
#/agents路由、renderAgents渲染(96 行)与顶栏NAV_KEY映射一并删除,并清掉随页面作废的 42 条 i18n 词条(先按「T('…')字面量是否仍被引用」逐条判定,避免误删共享键如' 条,')。#/agents现在回落到首页(实测),site/llms.txt与site/data.json保留 —— 机器可读入口在文件层,不在文档站页面层。README 两处引用同步改写;AGENTS §5 的「For Agents 页承诺」改为「对外承诺(该页已移除)」,承诺本身不变。 - 首页「核心组件」改为与组件总览同一套展示:抽出
buildCompCard()与observeThumbs()供两处共用,首页核心区改用.ov-grid/.ov-card(150px 在线预览 + 中文名 / 英文名),预览 iframe 同样按「进入视口 400px 内才挂载」懒加载。实测卡片宽 283px 与组件总览逐像素一致、缩略图高 150px、点击进详情正常。- 顺带修掉一个内容缺陷:该区块原先按
c.hasContract过滤,而契约做到全量 79/79 之后这个条件恒为真 —— 标题写着「核心组件」,实际列了全部 79 个。改用tier === 'core'(与组件详情页的「核心规范组件 / 扩展组件」同一口径),实测列出 10 个 =data.meta.core。
- 顺带修掉一个内容缺陷:该区块原先按
- 修复常见问题页搜索框样式异常:输入框挂的 class 是
.search-input,而样式表里只有全局搜索弹窗的#search-input(id 选择器),该 class 没有任何规则 —— 页面渲染出的是浏览器默认输入框。新增.faq-search/.faq-search-input令牌化样式(36px、左侧放大镜、聚焦环、::placeholder、计数行间距),暗色模式实测对比度 10.34;关键词过滤与计数(244 条 / 79 组件)行为不变。 - 回归:100%(79/79 页,1017/1017 断言,N/A 34)。同日 16 次连跑出现 2 次既有签名
1016/1017(78/79 页全通过,无失败页面落盘)——与 ROADMAP S5-P17 记录同因;另写逐页归因诊断(读#result-list .t-row的 fail 项)连跑 14 轮 0 复现、无页面fail>0,证据已补进 S5-P17。该偶发与本改动无关:测试页只加载site/style.css,而本次改动涉及的选择器(topnav/lang-*/faq-search/ov-card/home-core-grid/core-card)在tests/_template.html中出现次数均为 0。 - 验收:
smoke:site30/30、verify:i18n16/16、verify:theme/verify-dark/verify-site-routing全过、零运行时依赖不变;另 30 项浏览器断言覆盖三项改动(导航 6 项且无 AI 消费入口、#/agents回落首页、首页核心 10 张卡与总览同宽同高、预览 iframe 真实加载、FAQ 过滤 / 计数 / 暗色对比度)。
Docs site · 快速开始新增「安装(npm 私有源)」+ 修复更新日志页首次进入卡加载
- 快速开始页(
#/guide)新增第一节「安装(npm 私有源)」:项目.npmrc一行配置(@root:registry=…)→npm install @root/ui→ 三端引入示例(Vue 3 / React / Vue 2),并显著提示「令牌必须先引」这一最常见接入坑(78/79 组件样式引用var(--kole-*))。同时把原「引入设计令牌」与「按端使用组件」两节改写为「不用 npm 时」的对照路径;页内目录与中英双语同步(新增 9 条英文词条,verify-i18n256 键全覆盖)。 - 修复既有缺陷:更新日志页首次进入永远停在「加载中…」。
renderChangelog在懒加载分支里只赋值window.__koleChangelogReady,但全站没有任何地方调用它——只有离开再回来(changelogCache已就绪)才会渲染。改为走listenChangelog()注册回调(该函数已正确处理「已缓存则立即回调 / 未缓存则入队」)。线上实测:修复前首次进入 208 字符且一直「加载中」,修复后 14756 字符 / 10 个版本。 - 验证:独立浏览器实例 11 项检查全过(首次进入渲染完成、npm 节排第一、7 个代码块、英文模式生效、7 条主路由 0 报错);回归 100%(79/79 页,1017/1017 断言,N/A 34);文档站冒烟通过。
Docs site · 顶栏窄屏折叠为汉堡 + 导航抽屉(S5-P20)
- 问题(实测):顶栏没有任何窄屏规则。中文 1280px 起 7 条链接全部折行(
height:100%+ 无white-space: nowrap,中文按字换行成竖排)、1100px 起文字顶出 60px 顶栏、960px 起顶栏溢出、768px 起最右链接不可达、480px 起 7 条全部在视口外且无滚动条(docOverflow: 0,即不可达而非可滚动);英文更早——1366px 起溢出,1200px 起最右链接已不可达。附带缺陷:英文在 1600px 就折成 2 行,因为.topbar-inner上限 1440px,与视口多宽无关。 - 修复:
≤1366px折叠为汉堡 + 右侧抽屉(.topnav就地变成抽屉,不复制 DOM,避免 i18n 文案与 active 态两处维护);基础层加white-space: nowrap;收紧规则(logo 副标、顶栏间距、链接近距、搜索框上限)改为无条件而非挂在断点上——英文 7 条链接 + 可读搜索框在 1440px 上限内始终排不下,挂断点解决不了。60px 顶栏高度未改,故 5 处硬编码引用(.body-wrap/.sidebar/.toc/html的scroll-padding-top)连带影响为零。 - 验收中修掉两个只有交互测试能抓到的缺陷:① 抽屉可见但点不到——
.topbar的z-index:100形成层叠上下文,抽屉的120只在顶栏内部生效,整条顶栏被外部遮罩110压住;矩形与可见性断言全部通过,只有真实点击暴露intercepts pointer events。修法:遮罩移入.topbar,与抽屉同处一个上下文(仍低于.fab-stack150 /.modal-mask200)。② 焦点进不了抽屉——visibility参与transition,类切换后首帧仍是hidden,focus()静默失败(键盘用户完全进不去);改为「打开时visibility 0s、关闭时延迟 0.22s」,并把焦点回收从contains()判断改成显式标志(元素被隐藏时activeElement会变成body,contains()判不出来)。 - 新增守门人:
tools/verify-nav-responsive.mjs+npm run verify:nav(18 宽度 × 中英双语 + 抽屉交互,346 断言,约 35 秒),已接入regression.yml(步骤 15),并补装fonts-noto-cjk——宽度断言依赖字体度量,缺 CJK 字体时中文退化成豆腐块/拉丁回退会导致假失败。脚本每次运行打印字体度量基准与字体容忍度(在最窄内联宽度 1367px 二分测出文字宽度还能再增多少仍不折行:实测 17.5%,该处余量 94px;同次实测现实字体跨度 Arial/Segoe UI0.918×、DejaVu/Liberation1.000×、Verdana1.058×,最宽者也远在容忍度内 —— 故 CI(ubuntu)与开发机(Windows)的字体差异不会让断言假失败;容忍度低于 5% 时额外打印告警)。服务未起时报 exit 2(同run-regression.mjs口径),不退化成一串断言失败。断言按 DOM 里的链接条数取值(不写死 7),故后续增删导航项不会误报。 - 部署改为被测试 gate:
deploy-pages.yml的触发器从push换成workflow_run(等 main 上的Regression完成)并加if: conclusion == 'success'守卫 —— 测试不过就不部署。用workflow_run而非把 Regression 拆成可复用工作流,是为了不让同一套测试在每次推 main 时跑两遍;workflow_dispatch保留为有意的手动逃生口。checkout 显式取workflow_run.head_sha(workflow_run的github.sha指向默认分支头,不取会部署错提交)。 - 顺带修掉一处证据链缺口:首页通过率卡片读
tests/report.json,而部署原先cp的是入库的那份——等于页面显示「提交里的数字」而不是「刚验过的数字」。现改为下载本次 Regression 的regression-report产物并用其中的report.json(新增actions: read权限),取不到才回退到提交版并发::warning::,回退路径保证部署不会因产物过期而变脆。 - 清理一条死规则:≤900px 里「链接近距收到 8px」的补丁在抽屉方案下已无任何生效宽度(实测 900px 下
.topnav a计算值为12px 20px),已移除并留注释说明。 - 验收:
npm run verify:nav→OK — all checks passed(346 断言 / 0 FAIL);改动前后逐宽度对比见 ROADMAP「S5-P20 实测数据」;回归 100%(79/79 页,1017/1017 断言,N/A 34)连跑 8 次一致、0 超时;smoke:site全通过;零运行时依赖不变。
Design system · 组件族参数化:79 个并列组件 → 48 个概念组件(S6-P21)
- 问题:79 个并列组件里有 44 个是同源变体,却各自手写了一遍。导航最典型——
topmenu/sidemenu/mixednavigation三份实现,差异只是"一级菜单横排还是竖排";规范契约自己就写着从属关系:alertmodal与confirmmodal的doNotInvent原文是「弹窗尺寸档位(见 Modal 契约)」,steps与steplist的semanticTypeCandidates完全相同(均为steps|wizard)。并列表达让消费方看到 6 个表格组件,而它们实际是「一个 Table + 一个 feature 参数」。 - 新增族层(纯追加,不破坏任何既有承诺):新增
.design_library/kole-ui/families.json;data.json增顶层families与每组件family/familyRole/familyParams;site/details/<slug>.json同步三元组。13 族 / 44 成员 / 35 个独立组件;data.json仍完整输出 79 个组件,slug 集合逐一不变(铁律 5)。 - 归族判据可核对,不按名字猜:每族在
tools/lib/family-model.mjs里必写mergeBasis,依据是契约中四类可核对字段——semanticTypeCandidates重叠、anatomy为同一骨架的子集、变体维度同构、doNotInvent的显式从属声明。 - 实现层合并(导航族端到端切片):
tools/gen-family-impl.mjs从tools/lib/family-impl/nav-menu/的 5 端模板生成TopMenu/SideMenu/MixedNavigation共 15 个文件,参数为direction=top|side|mixed。三份 CSS 的 md5 完全相同——一份样式表服务三个组件;改模板 + 重跑即三端同步,不再存在"改了 topmenu 忘了 sidemenu"。 - 为什么是「生成」而不是「抽共享模块」:
tools/pack-deploy.mjs(薄壳 79 / 实现 395)、tools/precompute.mjs(79 / 395)、tools/verify-cross-platform.mjs、tools/verify-package-import.mjs四处硬断言文件数与导出数。抽跨文件 import 会同时打破它们,并失去"单文件可拷贝"。生成把重复消除在源头,而不改动文件图。 - 生成器护栏:目标文件有未提交改动、且不含生成物标记时拒绝覆盖(除非
--force)——防止把工作区里没提交的手工调整冲掉。 - 跨端口径(两个数必须分开说,免得把自己的改动说大成整体改善):已提交 HEAD 为
identical 2 / differing 77 / high 44;本任务改动前的工作区已是79/79(既有未提交改动先清了跨端漂移);本任务改造后仍为identical 79 / differing 0,与工作区持平。中途曾掉到 76/79:族模板最初把方向写成对象字面量{ direction: 'side' },Vue 端 class 提取器会把其中的字符串值收作变体记号、H5/JSX 端不会。探针实验确认成因后改用独立常量FAMILY_DIRECTION承载方向,四端回到 79/79——是改代码对齐既有约定,未放宽校验脚本。提取器本身的不对称仍未修,已登记 ROADMAP S6-P22。 - 顺带修掉一处既有 RTL 不一致:
MixedNavigation.css原文件同时写border-inline-start与border-left-color(逻辑属性与物理属性混用,RTL 下两侧指示条表现不一致);族模板统一为逻辑属性。 - 验收:族层
node tools/verify-families.mjs→OK: 族层端到端一致(13 族 / 44 成员 / 79 组件不变 / 395 文件不变),退出码 0;node tools/gen-family-impl.mjs --only=nav-menu幂等(重跑 0 写入);回归 100%(79/79 页,1017/1017 断言,N/A 34)连跑 8 次一致、0 超时;零运行时依赖不变(dependencies为空)。
Package · 发布到私有 npm 源(可直接 npm install)
-
发布位置:自建 Gitea 的 npm registry
https://gitea.mymoyu.top/api/packages/root/npm/(Gitea 27.3.1),匿名可读——实测无凭据npm view/npm install均成功。 -
已发布 3 个可互换的包名(内容一致:三端入口各 79 组件 + 令牌 + 组件样式):
包名 用途 @root/ui推荐:scoped 名,项目 .npmrc写一行@root:registry=…即可,其余依赖仍走公共源chunyu-ui非 scoped 别名,需 --registry=显式指定源aurora-admin-design仓库原名,同上 ⚠️ 本表是 v1.4.x 当时的发布事实,其中的
aurora-admin-design与导出名AaButton/AaTag是当时线上真实存在的东西,不改写成新名(改了就不是事实了)。改名后的对照与现状见 [2.0.0] 段的「发布现状」。 -
踩到的坑(已写进 README):非 scoped 包不能用
@包名:registry=写法——该语法只对 scoped 名生效,实测报 404。故推荐 scoped 名 + 一行.npmrc。 -
端到端验证:建 Vite + Vue 3 工程,
.npmrc一行配置 +npm install @root/ui(公共依赖同时走公共源)→vite build通过(169 模块)→ 浏览器实测:AaButton渲染、品牌色rgb(47, 84, 235)生效、AaTag正常、点击计数交互正常、0 JS 报错。 -
未发布到公共 npm:本机无 npm 凭据(
npm whoami→ENEEDAUTH,无~/.npmrc、无 token 环境变量),npm publish到 registry.npmjs.org 被拒。公共 npm 上chunyu-ui/aurora-admin-design均未被占用(可用),是否发布待定。 -
README 增补「从私有 npm 源安装」段(含正确的
.npmrc写法与三端 import 示例)。
Docs site · 导航语言选择改为下拉(S5-P19)
- 问题:顶栏语言控件是「中 / EN」双段按钮——11px 圆角、28px 高、靠 2px 字号差和品牌色表示当前语言。两个语言标签同时高亮显示,当前语言靠粗细区分,一是看不出「点了会怎样」(无展开暗示),二是与旁边 34px 的框架选择器、搜索框不同高,三是纯鼠标控件:没有
aria-haspopup、没有键盘路径。 - 改为下拉选择:触发器 = 地球图标 + 当前语言名(简体中文 / English)+ 箭头,34px 高与相邻控件齐平,展开时箭头旋转 180°、边框转品牌色并带聚焦环;菜单 186px 卡片,含「界面语言」标题分隔线、语言名 +
ZH/EN角标 + 选中对勾,8px 顶栏令牌阴影。 - 交互与无障碍:
role="listbox"+aria-selected+aria-expanded;点击展开/收起、点击外部关闭、Esc关闭并回焦触发器、↑/↓循环移动、Home/End跳首尾、Enter/Space选中、Tab关闭且不抢焦点;选中后触发器重新获得焦点。语言名始终以该语言自身书写(简体中文 / English),不随界面语言翻译。 - 令牌与暗色:颜色/圆角/阴影全部走
--kole-*令牌,未新增任何硬编码色值;暗色模式实测菜单底色rgb(28,31,38),选中项对比度 4.57、菜单标题 6.50、触发器 4.57(均 ≥ 4.5)。prefers-reduced-motion: reduce下关闭菜单动画与箭头过渡。 - 窄屏:≤1100px 收起语言名(触发器 56px,与旧控件同宽)。实测改动前顶栏在 1024px 溢出 13px、900px 溢出 9px(旧控件同样外露),现 ≥860px 全部为 0;≤820px 的溢出与语言控件无关,已登记为 ROADMAP S5-P20。
- i18n:新增
界面语言/选择语言两条,移除随之作废的切换到简体中文/切换到英语(原按钮的 aria-label),一进一出净增 0 条。 - 验收适配(验收命令本身随控件形态更新,判据强度不变):
tools/verify-i18n.mjs的两条静态检查改指新 id/绑定,并新增「旧控件不得残留」检查;tools/run-site-smoke.mjs的点击路径改为「开菜单 → 选项」,并补 8 条下拉行为断言(aria-expanded、Esc、方向键、焦点回位、选中态、触发器文案)。 - 回归 100%(79/79 页,1017/1017 断言,N/A 34),连跑 8 次一致;
smoke:site30/30;verify:i18n16/16;verify:theme、verify-dark、verify-site-routing全过;零运行时依赖不变。
Package · 三端可 import(组件库真正可用)
- 问题:
dist/只发 CSS 与演示 HTML,package.json的main甚至指向一个 CSS 文件,没有任何可 import 的组件——import { KoleButton } from 'kole-ui/vue3'这类标准用法不成立。S1-P2 的任务范围写的是「能拿到令牌 + 组件样式」,因此这是范围缺口而非实现错误(已按 AGENTS 第五节登记为 ROADMAP S5-P18)。 - 新增三端聚合入口:
dist/react/index.js、dist/vue3/index.js、dist/vue2/index.js(各导出 79 个Kole*组件)+ 单组件源码。组件以.vue/.jsx源码发布,由宿主构建链编译(无额外编译产物与源码不同步的风险,且保持零构建依赖)。 package.json:补exports映射(././tokens.css/./components/*/./react/./vue3/./vue2/./manifest.json)与peerDependencies(react >=17、vue >=2.6,均为 optional)。- 修掉两个「组件无法编译」的真实缺陷(此前从未被发现,因为从未真编译过):
RangeQuickPicker的presetRange给const start/const end重新赋值 → React 与 Vue 3 两端都无法编译;已改为let并与 Vue 2 参照实现对齐(start改为new Date(...)而非setMonth/setDate就地修改,行为一致)。CodeInput.vue3.vue内function emit()遮蔽了const emit = defineEmits(...)→ 重复声明,编译失败;已重命名为emitChange()。
- 样式随包发布:56 个组件的 Vue 两端用
<style src="./<Prefix>.css">引用外部样式、79 个 JSX 用import './<Prefix>.css'。打包时把同名 CSS 一并放入dist/react|vue3|vue2/,否则会出现「import 成功但样式全丢」。断链检查已纳入验证脚本。 - 新增
tools/verify-package-import.mjs:结构级(入口/断链/exports/零依赖,15 项,零依赖可跑)+ 编译级(esbuild +@vue/compiler-sfc真编译 79 个 SFC、vue/react SSR 真渲染KoleButton断言 DOM,5 项)。编译级依赖可用KOLE_VERIFY_DEPS_DIR指向隔离目录,避免污染仓库node_modules。 - 端到端验证(真实工程,非模拟):分别建 Vite + Vue 3 与 Vite + React 工程,以
file:依赖真实npm install本包,只写 README 里的那几行import→vite build通过(Vue 170 模块 / React 189 模块),浏览器实测:组件真渲染、品牌色rgb(47, 84, 235)生效(证明令牌与样式链正确)、loading态disabled与 spinner 正确、点击交互正常、0 JS 报错。 - 回归 100%(79/79 页,1017/1017 断言,N/A 34);S1-P2 原始验收命令(tokens/aggregate/79+index/zero-dep/css usable/pack contents)全部仍通过。
Docs site · 组件详情页代码块默认展开(含修复异步填充漏填)
- 组件详情页源码区改为默认展开:
demo-strip初始态由折叠改为展开,进页面即可看到当前框架源码,省掉一次点击;展开条箭头与提示文案随状态同步(▲ 收起代码 / ▼ 展开代码)。 - 修复既有缺陷(默认展开后被放大):源码异步加载后的填充回调签名错位——
listenSrc(slug + '/' + kind, fillCode)直接传函数,而notifySrc的回调签名是(text, error),于是源码文本被当成kind与'html'比对,永远不相等,首次展开的代码区一片空白(实测全新加载展开后字符数 0,离开组件再回来才有内容)。已改为闭包绑定kind;并新增codeWrap.__fillCurrent(),在代码区插入 DOM 后补填一次(命中内存缓存时源码是同步取得的,插入前填充会被isConnected守卫跳过)。 - 浏览器实测(本地 dev-server):首次进详情页即展开且有内容(cascader 7713 字符)、切到未访问组件自动填充(tree 5159 字符)、切 CSS tab 正常(1067 字符)、折叠再展开内容保留、0 JS 报错。
- 回归 100%(79/79 页,1017/1017 断言,N/A 34),文档站冒烟 ×2 全过。注:当日连跑 27 次中 2 次出现 1016/1017 的偶发失败,
tests/*.html不加载site/app.js(grep 计数 0),与本改动无关;因tests/report.json不记录是哪条断言失败,已立任务包 S5-P17 追踪可追溯性。 - 顺带修掉「部署了但浏览器还在跑旧版」:
nginx.conf之前没有任何Cache-Control,浏览器对app.js走启发式缓存——实测重新部署后页面仍执行旧app.js(同一页面内fetch能取到新版、<script src="app.js">却用缓存,duration=0)。已在 server 级统一加add_header Cache-Control "no-cache" always;:每次带If-None-Match重新校验,未变更返回 304(实测 app.js 带 ETag 请求 → 304),开销极小但部署立即生效。
Security · 生产部署链审计修复(2026-09-19)
- 规范原文泄漏(根因):
.dockerignore里*.md/*.ps1/*.yml/*.png等 glob 在 Docker 下只匹配构建上下文根目录,嵌套路径全部失效(真实构建实证:sub/nested.md仍进镜像)。改为**/前缀并补齐嵌套 glob;.design_library/kole-ui/{specs,agent-reports,preview,ui_kits}与嵌套*.md实测不再进入镜像(修复前线上GET /.design_library/kole-ui/specs/组件1.txt→ 200 / 8623B)。 nginx.conf加固:补absolute_redirect off;(根路径 302 曾丢失宿主端口:3311落到无服务的 :80)、server_tokens off;、与site/dev-server.js逐字一致的 CSP 及X-Content-Type-Options/Referrer-Policy/Permissions-Policy/X-Frame-Options;/healthz改用default_type修掉重复Content-Type。Dockerfile:补COPY sitemap.xml(修复前生产/sitemap.xml→ 404)。site/dev-server.js:修复单个GET /site/%00触发ERR_INVALID_ARG_VALUE未捕获异常打挂进程的问题——新增编码形态与解码后 NUL 双重拦截、fs.readFiletry/catch;白名单、安全头、302/404 行为保持(92 条合法路径 status / content-type / 字节级一致)。新增KOLE_PORT开关(默认仍 3311)供验证脚本隔离端口。- 消除动态求值 sink:
site/app.js与tools/precompute.mjs原先把defineEmits([...])字面量交给函数构造器求值(实测defineEmits([1,globalThis.__pwned='x'])会真的执行;构建期同源 → 可打穿 CI)。改为只解析字符串字面量的parseStringLiteralArray(构建期实现独立成tools/lib/parse-string-literal-array.mjs),非字面量元素整体拒绝返回 null。等价性:158 个frameworks/*.vue双实现抽取结果不一致 0(54 处字面量 / 96 条事件名)。 - 新增验证脚本
tools/verify-dev-server.mjs(20 checks,含 3 条修复前必失败的反例断言)与tools/verify-emits-parse.mjs(17 checks,含构建期副本漂移门)。 - ⚠️ 规划修正:
PLAN.md§8「不改site/dev-server.js(已工作良好)」的立论已被实测推翻,按 AGENTS.md 第五节「以实测为准」处理并在此标注。 - 回归:100%(79/79 页,1017/1017 断言,N/A 34),连跑 9 次一致,0 超时;主 agent 另独立复跑 1 次亦 100%。
Deploy · 线上部署(2026-09-19)
- 新增
tools/pack-deploy.mjs:以.dockerignore为唯一真源打包部署目录(实现 Docker 的匹配语义,含「*.md只匹配根目录」这一实测结论),带硬断言(规范原文/agent-reports/preview/ui_kits 绝不出现;站点运行必需文件必须出现;薄壳 79、实现文件 395)。部署配置文件(docker-compose.yml等)始终保留——.dockerignore只管镜像构建上下文。 - 按 AGENTS §九 流程首次实际部署到
192.168.5.7:备份 → 解到暂存目录核对 → 替换 →docker compose build && up -d(回滚目录/opt/kole-ui.pre-audit-20260919-0609)。 - 部署后验收:
specs/组件1.txt、agent-reports/*、嵌套SKILL.md/README.md→ 404;sitemap.xml→ 200;tests/report.json→ 200(首页通过率角标恢复数据源);根路径 302 →Location: /site/(相对,不再丢端口);Server: nginx无版本号;CSP 等 5 条安全头齐备且/healthz只 1 条Content-Type;396/396 条 sitemap URL 全部 200;容器healthy。 - 顺带消除历史漂移:线上组件文件由 09-06 快照更新为当前工作树(此前后者与线上有 288 个文件不一致)。
- 决策:暂不对外公用 —— 保持
127.0.0.1:3311回环访问(需 SSH 隧道),不加反代/域名/认证;容器运行期加固与对外承诺口径统一另立任务包(ROADMAP S5-P14/P15/P16)。
Theme modes · 日间 / 夜间 / 自动
- 文档站主题选择扩展为
light/dark/auto三态;自动模式跟随prefers-color-scheme并监听系统主题变化。 - 新增可访问的主题模式菜单、跨标签页
kole-mode同步和 iframe 主题同步。 - ThemeSwitcher H5 / React / Vue 2 / Vue 3 统一
auto模式枚举与 ARIA 语义。
Fixed — 文档站中英切换完整性
- 修复语言切换后相关组件、主题面板、搜索分类与详情目录仍显示初始语言的问题。
- 补齐加载态、重试、契约详情等动态文案的英文词典覆盖,并为顶栏切换器补充无障碍名称与状态。
- 新增
tools/verify-i18n.mjs静态校验与tools/run-site-smoke.mjs浏览器冒烟测试。
S3-P9 · 契约缺口解释层
- 为 Card 契约的
doNotInvent/unknowns增加结构化解释:分别说明设计边界、开放问题、出现原因与待确认决策。 - 组件详情页明确区分“不要自行发明(设计边界)”与“规范未明示(待确认)”,不把现有实现值冒充正式规范。
- 保持 hover 行为与卡片网格间距待定,未擅自写入 16px/24px 或固定状态规则。
S2-P7 · 行为断言(6 试点全绿)
- 新增
tests/_behaviors.js:8 动词(click-toggles-class/click-adds-node/click-removes-node/click-sets-attr/input-clears/input-filters/keyboard-activates/tab-switches)+@input相对定位 +@doc全文档查询 + 同步 pump + page-load 幂等缓存;_runtime.js聚合 + 重载清缓存;_template.html引入;6 演示页data-behavior标注;79 测试页重生成。 - 全量回归:100%(79/79 页,1009/1009 断言,N/A 35)。关键修复:runner 兜底重跑导致行为断言第二轮误报,加缓存解决。
S3-P8 · RTL 支持(28 文件迁移)
- 新增
tools/migrate-rtl.mjs(白名单 dry-run/--write双模式):margin/padding/border-inline + text-align start/end;剩余物理属性 0(排除例外);逻辑属性文件 19;三代表页 RTL 零溢出零错误。 - 人工例外 14 处:
margin-left:auto(3)、拼接边框(5)、left:0+right:0并存(4)——不机械替换。
S2-P9 · FAQ 页(details 懒加载版)
- 新增
#/faq页:自动聚合 79 组件契约的 unknowns(139)+ doNotInvent(101),共 240 条;按组件分组 + 关键词搜索过滤 + 命中统计;顶栏/侧边栏双入口;9 条 i18n 英文。 - 浏览器实测:groups 80/items 240,搜索“宽度”命中 11 条/11 组,清空恢复 240,0 JS 错误。
- 规划偏差:契约已在 P4 阶段 D 移出
data.js,FAQ 改走details/*.json批量懒加载(每批 10 个)而非直接消费data.js。
S4-P12 · 版本发布流程
- 新增
tools/release.mjs:检查模式(package.json vs CHANGELOG 版本一致性 + Unreleased 提醒)与--bump major|minor|patch --date提升模式;只做本地准备,tag/push 由人执行。 CONTRIBUTING.md新增发布流程 5 步 + 版本号规则(major/minor/patch 判定)。
S2-P6 · 跨端一致性自动验证(方案 B:静态结构比对)
- 新增
tools/verify-cross-platform.mjs(零依赖零联网):79 组件 × 4 端(H5/React/Vue2/Vue3)class 集合 + 结构骨架双 diff,演示包装类/变量名/模板残留降噪,high/medium/low 分级;产出tests/cross-platform-report.json(79 条全量 + samples 3)。 - 实测:完全一致 2,有差异 77(high 44/medium 22/low 11)。high 主因:React 端
is-disabled/is-active缺失、H5 演示页缺框架端结构类、Tag/Select/Input 变体类缺失——已追加为 ROADMAP 的 S2-P6-F1~F4,不在本任务内修。 - 回归零影响:
tests/report.json79/79、site/data.json79 组件均未动(脚本只读消费)。
S2-P5 · 暗色模式真正实现(选型 A:演示页随站点同步反色)
- 令牌文件新增
html.kole-dark组(31 个--kole-,≥15 达标):背景三层递进、文字四层、品牌/语义色向白提亮;10 项文字对比度全部 ≥4.5:1(脚本实测)。 site/style.css暗色块精简为结构样式(令牌值收归令牌文件,删旧内嵌值与“演示页保持浅色”规则);site/app.js删死代码DARK_TOKENS,injectIframeTheme同步kole-dark类到演示 iframe。- 附带收敛:演示壳裸类
.kole-page/.kole-h2/.kole-desc(26 页用而无定义)在令牌文件补令牌定义;table.htmlloading-mask、Tag.css红/橙标签加暗色覆盖。 - 新增
tools/verify-dark.mjs独立验证(32 断言:令牌组 2 + 对比度 10 + 10 页浏览器实测 20),不进_runtime计数。 - 首屏预算 292KB(< 300KB);回归 1003/1003(pass 1003/fail 0/skip 35)零影响。
S1-P4 · data.js 瘦身(已完成 c65a69c)
- data.js 991KB → 98KB(预计算 API/场景 + 源码分离到 site/sources 395 文件),data.json 保持完整(含 5 端 sources)。
- 首屏资源合计 291KB(< 300KB 预算,S1-P4b 验收已达标,无需拆分 app.js)。
- 回归 1003/1003 全绿(79 页全过,N/A 35)。
- ROADMAP 状态:P4 已完成,P5(暗色模式)为下一版本首选。
文档站 · 版本选择(历史版本文档站可切换)
- 背景:Element UI / Element Plus 文档站只有静态版本角标、没有切换器;MUI、Vuetify、Ant Design 用「每版一份完整站点快照 + 顶栏下拉/子站」实现切换。本仓库原先只有组件级版本角标,缺的是文档站级切换。
- 入口:顶栏
vX.Y.Z角标改为可点下拉(桌面,复用语言选择器的键盘/ARIA 交互,不新增顶栏宽度); ≤900px 角标收起后由顶栏原生<select>接管;≤560px 两者都让位,更新日志页保留一排版本链接。 清单只有一版时角标退回纯展示 —— 不摆「看着能切却切不动」的状态。 - 清单:新增
site/versions.json(+ 仓库根同名副本,供部署前缀下的 URL 使用),由tools/precompute.mjs阶段E 生成:根站点永远是本次构建的版本(path..,首位), 归档快照按版本号降序,只有磁盘上真存在快照的版本才入清单(没归档的不列,避免点进去 404)。 - 归档:新增
tools/snapshot-site.mjs(npm run snapshot:site -- <x.y.z>):把当前构建复制到/<x.y.z>/site/(含 frameworks 与 .design_library,排除 specs/agent-reports),并刷新清单。 快照目录落在仓库根:站点根由 pathname 里第一段/site/反推,所以 URL 必须是/<x.y.z>/site/…。 当前版本继续留在/site/(旧链接零破坏)。历史源码不在仓库里(无 git tag),旧版本无法凭空重建。 - 切换语义:保留当前路由(
/site/component/button/h5→/1.4.1/site/component/button/h5), 目标版本缺该页时由它自己的路由回落接管;不写 localStorage(URL 即真相)。 - 清单只认部署根那份(
<prefix>/versions.json,每次发版重写),站点根那份仅作兜底; 清单里的path一律按部署根解析,判定「当前版本」用location.pathname上的最长命中前缀。 这两个坑都实测踩到过:① 快照里残留一份归档当时的旧清单 → 菜单被压成单版本、角标不可点; ② 先把部署前缀剥掉再比 → 快照页与根站点路径撞车(都成/site/…),根站点条目抢走「当前」。 两种都表现为「切到旧版后回不到最新版」。快照不再自带versions.json(snapshot-site.mjs已排除)。 - 服务器:
nginx.conf补版本化深链回落(/([0-9]+\.[0-9]+\.[0-9]+)/site/→ 该版壳)与versions.json的no-store(location 内 add_header 会覆盖继承,安全头一并补全);/<x.y.z>/versions.json也由根那份应答(否则会被裸入口规则重定向成 HTML 壳);site/dev-server.js放行版本目录、同样回落并转发清单;Dockerfile+tools/pack-deploy.mjs把快照与根清单随包发布(并断言快照不含过期清单)。 - 当前状态(开发期):仓库只归档了当前版本,清单里只有它一条 —— 角标退化为纯展示、
菜单与窄屏 select 都不出现,不摆「看着能切却切不动」的控件。以后每发一版跑一次
npm run snapshot:site -- <x.y.z>归档,切换器自动生效(清单由磁盘上的快照目录推导)。 - 验收:
node tools/verify-versions.mjs33 项、node tools/verify-site-routing.mjs、node tools/verify-i18n.mjs16 项全过;REG_BASE=… node tools/verify-site-routes.mjs真浏览器覆盖 单版本降级(角标不可交互 / 菜单与 select 都不出现);多版本形态另用演练快照实测过 「角标可交互 / 菜单列出全部版本 / 切换保留路由 / 快照内站点根反推正确 / 快照页菜单仍可交互且当前版本标在自己身上 / 从快照切回最新版 / 全程 0 报错 0 4xx」;回归 100%(1026/1026,八次连跑一致)。零运行时依赖不变。
[1.0.0] - 2026-09-20
首个对外版本(版本号重新起算)
本仓库此前的 1.1.0 ~ 2.0.0 段记录的是开发期里程碑,不是对外发布版本。 组件库尚未对外发布,当前把版本号重新起算为 1.0.0 作为第一个对外版本; 下方历史段按原样保留(记录当时的开发过程,不追溯改写),但不再是「最新版本」。
- 文档站版本选择:版本入口分三档,覆盖全部宽度 ——
桌面顶栏
vX.Y.Z下拉(复用语言选择器的键盘/ARIA 交互,不新增顶栏宽度); ≤900px 顶栏原生<select>接管;≤560px 顶栏放不下(实测溢出 23px),改到导航抽屉里一行版本 select。 三处共用同一份选项,切换都保留当前路由。 清单见site/versions.json,由tools/precompute.mjs从「构建版本 + 磁盘上的归档快照」生成, 没归档的版本不列;归档用npm run snapshot:site -- <x.y.z>,之后切换器自动生效。 清单里没有可用版本时才退回不可点的纯角标(未构建/未部署),有版本(哪怕只有一版)就是正常下拉。 - 零运行时依赖:
dependencies为空,站点与组件全部原生实现。 - 交付形态:79 组件 × 5 端实现(395 文件)+ 79 份契约 + 75 设计令牌 + 文档站(中英双语、暗色模式)。
Added(首版内容,原 2026-09-06 的 1.0.0 段并入此处)
- 79 个组件实现(H5 / React / Vue 2 / Vue 3 四端)
- 设计令牌:
colors_and_type.css/css.json/components.css - 6 个核心组件契约 JSON
components/index.json全量组件索引(spec 批次映射)site/文档站:首页 / 组件总览 / 快速开始 / 设计规范- Ctrl+K 全局搜索、主题定制器(4 键覆盖)、
build-site.ps1构建脚本
[2.0.0] - 2026-09-20
Changed — 品牌重命名:Aurora Admin → Kole UI(破坏性)
- 一次全仓改名,覆盖五类命名空间,1373 个文件 / 约 2.9 万处:
| 命名空间 | 旧 | 新 | 命中 |
|---|---|---|---|
| 文字品牌名 | Aurora Admin / Aurora |
Kole UI / Kole |
1224 |
| 路径 · 包名 · 镜像 | aurora-admin / aurora-admin-design / aurora-admin-showcase |
kole-ui / kole-ui / kole-ui-showcase |
1303 |
| 类名前缀 | aa-(Input 组件历史遗留用的是 au-) |
kole-(两类前缀就此统一) |
18014 |
| 令牌前缀 | --au- |
--kole- |
8489 |
| 组件导出名 | AaButton / AaTag …(含 import * as Aa) |
KoleButton / KoleTag …(import * as Kole) |
321 |
-
五类映射一句话版(上表在站点更新日志页不会渲染 ——
build-site.ps1的 CHANGELOG 解析器只抓-行,表格行不入changelog.json;故在此复述,已登记为 ROADMAP 衍生任务 S6-P29):文字品牌名Aurora Admin→Kole UI;包名 / 路径 / 镜像aurora-admin→kole-ui;类名前缀aa-(Input 遗留au-)→kole-;令牌前缀--au-→--kole-;组件导出名AaButton/AaTag→KoleButton/KoleTag。 -
按破坏性处理,版本 1.4.1 → 2.0.0。破坏面:npm 包名、组件导出名、CSS 类名、CSS 变量名、localStorage 键前缀、Docker 镜像/容器名、部署目录。
-
环境变量与全局标识符同步改名(逐条列举,避免误伤十六进制哈希与 WCAG「AA」字样):
AA_PORT→KOLE_PORT、AA_DATA→KOLE_DATA、AA_VERIFY_DEPS_DIR→KOLE_VERIFY_DEPS_DIR、__aaCollectResult/__aaBehaviors/__aaBehCache/__aaVersion/__aaResult/__aaRun/__aaDetailReady/__aaChangelogReady/__aaTranslateThemePanel/__aaRefreshModeUI→__kole*、aaLogger→koleLogger、aaZoom/aaSlide/aaFade→kole{Zoom,Slide,Fade}。 -
localStorage 键前缀
aa-→kole-(kole-lang/kole-render-log/kole-search-log/kole-test-log/kole-mode)。用户的旧偏好不会自动迁移,等于重置一次的语言与主题偏好。 -
目录与文件重命名:
.design_library/aurora-admin/→.design_library/kole-ui/(git mv,历史保留);启动器aurora-admin-dsh-launcher.exe→kole-ui-dsh-launcher.exe。 -
组件导出名(公开 API)同步改名,来源不只是字符串:
tools/build-dist.mjs生成export { default as Kole${prefix} }的三端入口、79 个.vue2.vue/.vue3.vue的name: 'KoleXxx'选项、README 与站内「快速开始」的 import 示例。改名后dist/重新构建,verify-package-import.mjs复核入口一致。 -
发布现状(2026-09-20 实测,避免把「改名」误读成「已按新名发布」):
- 公共 npm:
kole-ui/chunyu-ui/aurora-admin-design三个名字均未被占用(registry.npmjs.org/<name>→{"error":"Not found"}),但都尚未发布(本机无 npm 凭据)。 - 私有 Gitea 源(
gitea.mymoyu.top):线上存在的是改名前的@root/ui/chunyu-ui/aurora-admin-design;实测无kole-ui。也就是「仓库叫kole-ui」与「源上能装到kole-ui」目前不是一回事,README 中与该源相关的段落已加注说明。 - 结论:本次交付只改仓库,未执行任何发布动作 —— 重新发布是一次独立的、需要凭据的操作。
- 公共 npm:
-
迁移脚本入库:
tools/migrate-brand-kole-ui.mjs(--dry-run预演 / 默认执行 /--verify残留扫描)。实现为字节级替换,兼容 CRLF、UTF-8 与 GBK,跳过二进制与 UTF-16;幂等——第二遍运行报告 0 处改动。 -
文档与配置一并改名:
AGENTS.md/README.md/ROADMAP.md/TESTING.md/CONTRIBUTING.md/site/llms.txt/ 契约index.json/SKILL.md/metadata.json/ npm 仓库地址与 homepage(仍为YOUR-ACCOUNT占位)。 -
规划偏差(有意为之,在此披露):AGENTS.md 禁止改写
CHANGELOG.md历史条目。本次对历史条目只替换了品牌名本身,日期、版本号、断言数量、通过率、色值等事实一字未动——理由是重命名后站点更新日志页若仍显示旧品牌会自相矛盾。除品牌词外的历史内容保持原样。 -
一处自查发现并修回的真问题(教训值得留档):批量替换会把「对外实测事实」也一并改掉,使它从事实变成未经核验的断言。本次命中的是包名相关的三处 —— ①
CHANGELOG「已发布到私有源」表的第三个包名;②README「三个可互换的发布名」;③ROADMAP的 S5-P21 行与「规划修正记录」里的 registry 查验结果。原文记的是aurora-admin-design(当时确已发布/已查验),被改成kole-ui后就变成「kole-ui已发布」这种假事实。修法:这几处还原为当时的真实名字并加注新旧对照,另在 2026-09-20 对kole-ui重新实测并记录结果(见上「发布现状」)。同时给迁移脚本加了--only=限定规则 —— 因为全量重跑会把 §「刻意保留旧名对照」的位置再次改写掉。教训:改名要区分「品牌词」与「记录了外部状态的名字」,后者只能新增核验、不能替换。
Verified — 重命名后全链验收
- 构建链两步全绿:
build-site.ps1(79 组件 / 106 令牌 / 316 平台薄壳 / 396 sitemap URL)+precompute.mjs(data.js 1159 KB → 122 KB;site/data.json保持完整,79/79 组件带全量 5 端 sources)。 - 回归 100%(1017/1017 断言 / 79 页全过 / N/A 34),八次连跑一致、0 超时。
- 8 个验证脚本全过:
verify:i18n16 项 ·smoke:site全过 ·verify:theme·verify:nav·verify-dark·verify-site-routing(79 / 316 / 396)·verify-families(13 族 / 44 成员)·verify-emits-parse17 项 ·verify-package-import15 项(1 SKIP)·verify-dev-server20 项 ·verify-cross-platform(79/79 完全一致,差异 0)。 - 残留扫描
migrate-brand-kole-ui.mjs --verify:除刻意保留的旧名对照外为 0。剩余命中只有 4 个文件且全部是「为了记录旧名而写旧名」的文本 ——AGENTS.md§七(命名约定行)、CHANGELOG.md(本段对照表 + 发布记录还原处)、以及由它派生的site/changelog.json/site/data.json。代码、样式、模板、测试页、构建产物中的旧命名全部清零。 - 零运行时依赖不变(
dependencies为空)。
Known limitations
kole-ui-dsh-launcher.exe只改了文件名:它是 5.6 KB 的 .NET 编译产物,程序集名/模块名仍内嵌旧名(实测元数据为aurora-admin-dsh-launcher.exe与命名空间aurora-admin-dsh-launcher)。仓库内没有它的构建源(无.cs/.csproj/.sln,dsh_launcher.py亦非其来源),故无法就地重编;要彻底改名需在产出该 exe 的地方重编一次。- 部署侧(192.168.5.7)的镜像/容器/目录名已在仓库改好,但线上实例仍是旧名,需按 AGENTS.md §九 走一次标准部署流程才会生效。
- 仓库目录名
组件规范第一套未改(属工作区路径,改名会影响 DSH 启动器里硬编码的路径)。
[1.4.1] - 2026-09-11
审计轮 — 系统性质疑「这么多组件能保证不出错吗」
结论:不能保证零错误。79 组件 × 5 端 × 79 契约 × 326 译文,靠肉眼和声称都不成立。因此改为四轮机器审计 + 实测,把「我检查过了」替换成可复现的数字。
审计 1 · 契约保真度(358 条 usageHints 回规格原文核对)
- 逐字命中 336 条(93.9%);剩余 22 条经人工比对为同义改写(如「列表项带复选框」→「列表项带复选框,项高 32px」,数值确实在规格别处),非发明。
- 发现一处真实不一致:
rate.json的选中星色仍写#FAAD14,而规格已在 v1.3.1 改为#2F54EB—— 修契约使其与规格同步(usageHints+anatomy)。
审计 2 · 令牌语义正确性
- 检查 1313 处含令牌的颜色声明,0 处属性/令牌角色错配(未出现「background 用文字色令牌」这类)。令牌化在语义上是干净的。
审计 3 · i18n 翻译质量
- 326 条字典:英文值含中文 0 条、中英完全相同 0 条、长度异常 0 条。
- 修正审计脚本对「副名」的误判:英文模式下
.core-en显示中文是设计意图(主名英文 + 副名中文),不是漏翻。 - 发现并修复 4 处真漏翻:guide 页标题、Do/Don't 两个标题、guide 表格
H5 静态页、组件名渲染 4 处未做语言感知。
审计 4 · 废弃色值残留
- 扫描 91 个文件,发现 4 个文件 23 处仍引用 v1.3.1 之前的旧色值。
- 最严重:
css.json—— 它是 For Agents 页宣称的「结构化令牌源」,机器读取方会拿到过时的颜色。已同步 10 处。 README.md设计说明 5 处同步;CHANGELOG.md的旧值属历史变更记录,有意保留。
修复 · 低对比度图标
- 用「逐元素实测对比度」扫全部页面,发现
Rate未选中星用--kole-color-border(#E8ECF1) 作星色,白底仅 1.19:1 —— 边框色是装饰性色值,作图标不合格。 - 新增
--kole-color-icon-inactive: #8F8F8F(白底 3.23:1,满足 WCAG 1.4.11 的 3:1,且视觉最克制)。令牌 74 → 75。 - 同批扫出的另外 5 处低对比度经逐一核实为禁用态(WCAG 1.4.3 豁免)或深色遮罩上的白字(检测器把半透明底当白底),非缺陷。
修复 · 回归偶发(第三次根治)
- 现象:多次连跑偶发 99.9%(1 页失败),但单独打开该页总是通过。
- 根因:收集器的 8 秒超时兜底直接记为
fail: 1。并发 4 个 iframe 时主线程被抢占,慢页面会撞上超时。 - 修法:超时阈值 8s → 12s;重试一次后再判定;超时与断言失败分开统计(
timedOut字段,不计入通过率分母)。 - 验证:八次连跑全部 100% / 0 失败 / 79 页全通过 / 0 超时。
[1.4.0] - 2026-09-11
Changed — 组件层全面令牌化(设计系统的根基修复)
- 发现:79 个组件的 844 个颜色属性里,只有 2 个(0.2%)引用令牌,788 个(93.4%)硬编码 hex。后果是改令牌组件不跟着变、主题定制器对组件无效、For Agents 页写的「所有色值必须取自 kole-* 变量」形同虚设。这是本项目第五次「声称≠实现」,且动摇了设计系统的根本。
- 两层令牌化(此前只改了从未被加载的文件,走了弯路):
- 组件样式表(
frameworks/*.css):915 处 / 78 文件 - 演示页内嵌
<style>(实际生效的样式层):287 处 / 51 文件
- 组件样式表(
- 内嵌样式层是决定性的:演示页只 link
colors_and_type.css+ 自己的 CSS,而多数页面把关键样式写在<style>块里 —— 只改 CSS 文件不生效。 - 安全策略:只替换颜色属性值位置的 hex(
color/background*/border*/outline*/fill/stroke);跳过rgba()/渐变/url()复合值;不动 SVG 属性与 JS 数据(色板数组);幂等可重复运行。 - 歧义色值按属性语义消解(
#FFFFFF作color→text-inverse,作background→card-bg)。
Added — 补齐令牌语义
--kole-color-text-tertiary#595959(三级文字/描述,规范未定义、实现补齐,7.00:1)--kole-color-text-disabled#BFBFBF(禁用态文字,规范定义于组件1/2.txt;WCAG 1.4.3 对禁用控件豁免)--kole-color-border-strong#F0F0F0(实线边框,规范未定义、实现补齐)- 令牌总数 71 → 74;同步 legacy 别名映射(
--color-text-tertiary等)。 - 修复
colors_and_type.css一处重复的注释起始行。
Fixed
- Countdown 首帧空白:
setInterval(render, 1000)首次执行要等 1 秒,期间容器为空。改为定义renderCountdown()后立即执行一次,再挂 interval。浏览器实测确认修复。
Verified — 令牌响应性(本轮核心验收)
- 逐组件验证「改令牌 → 元素是否跟着变」,79/79 全部响应(改
--kole-color-brand/text-body/border等,采样前后样式签名对比)。 - 过程中修正了两处测量方法缺陷(初测 40/79 是误报):① 选择器
.demo *在无.demo容器的页面抓不到元素;② 探针令牌选错——Breadcrumb 用text-tertiary而我只改text-body。 - 回归保持 100%(961 断言 / 0 失败 / 79 页全通过),三次连跑一致。
[1.3.3] - 2026-09-11
Added — 中英双语(i18n)
site/i18n.js:330 条文案字典,顶栏新增中 / EN切换器,偏好存localStorage['kole-lang'],<html lang>与document.title同步。- 设计取舍:以「中文源串」作字典键而非抽象 key。中文是规范原文语言(组件1~10.txt)也是 app.js 现有字面量;源串作键意味着未收录文案自动回退原文,不会出现空白或 key 泄漏。
- 覆盖范围:导航 / 侧栏 / 首页 Hero 与设计原则 / 总览 / 快速开始 / 设计规范(含令牌导出区)/ For Agents 全表 / 更新日志 / 组件详情页(何时使用、API 三表、无障碍键盘表、Do&Don't、设计契约、实现资源、相关组件)/ Playground / 主题面板 / 搜索弹窗 / FAB 提示。
- 语言感知的显示逻辑:
- 组件名主次调换(中文模式主显中文名,英文模式主显英文名),详情页大标题不再重复;
- 侧栏分类名走
CAT_EN,不占字典; - 动态生成的键盘表、插槽说明按语言重算。
Fixed — 回归时序(根治偶发)
- DensitySwitcher 对比度偶发失败:断言在演示页内联脚本执行完之前就跑了,读到
is-active尚未应用的中间态(白字未落到品牌蓝底 → 2.51:1)。单页打开时通过、并发收集器里偶发失败。 - 根因是固定帧数等待(
load+ 双requestAnimationFrame)在多个 iframe 抢主线程时不够稳。改为就绪轮询:readyState === 'complete'且 DOM 连续 3 次采样(约 48ms)无变化才断言,另设约 4.8s 超时兜底避免卡死。 - 验证:四次连跑全部 100%(961 断言 / 0 失败 / 79 页全通过),偶发不再复现。
Fixed — i18n 接入过程中的三个真实缺陷
- TDZ 顺序:
KIND_KEYS等模块级常量在I18N/T定义之前调用了T(),抛Cannot read properties of undefined (reading 'T')。已改为存中文源串、渲染时求值(模块级预先求值还会导致语言切换后不更新)。 - 局部变量遮蔽:
renderDesign内原有var T = data.tokens;遮蔽了全局翻译函数,导致设计规范页整个渲染失败。改名TOKENS。 - 模板拼接括号:
el()调用在包装T()后少一个右括号,已修正。
Changed
- 回归基线:961 断言 / 925 通过 / 100% / 79 页全通过 / N/A 36,四次连跑一致。
[1.3.2] - 2026-09-11
Added — 契约第三批:全量契约化 79/79
- 补齐剩余 43 份组件契约,
components/目录现为 79 份契约 JSON(此前 36)。 - 分两批提炼,全部逐字来自规格原文(组件1/2/5/6/7.txt):
- 批次 A(19):tag / tabs / steps / breadcrumb / dropdown / popconfirm / buttongroup / expandabletable / mergedcelltable / summaryrowtable / fixedcolumntable / enhancedtabnav / sidemenu / topmenu / mixednavigation / quicknav / anchornav / backtotop / pagetransition
- 批次 B(24):bankcardinput / idcardinput / plateinput / listpicker / rangequickpicker / dragupload / signaturepad / messagepro / notificationpro / progressvariants / skeletonpro / emptypro / loadingoverlay / resultvariants / exceptionvariants / confirmmodal / alertmodal / formmodal / fullscreenmodal / themeswitcher / layoutswitcher / densityswitcher / shortcutpanel / bottomsheet
- 每份含
variantDimensions/representativeVariants/anatomy/structurePatterns/usageHints/doNotInvent/unknowns七字段,与既有 36 份同 schema。 - 硬规则:只从规格提炼,不发明;规格未明示者进
unknowns,规格明确排除者进doNotInvent。校验脚本确认 79/79 字段完整、slug 一致。
Added — 令牌导出(文档清单中的 C4 项)
build-site.ps1构建期生成三种标准格式,与站点展示的令牌始终同源:site/tokens/tokens.css— CSS 自定义属性,可直接@importsite/tokens/dtcg.json— W3C Design Tokens 社区组格式($value/$type/$description,按 color/typography/spacing/radius/shadow/motion/size 分组)site/tokens/figma.json— Figma Tokens(Tokens Studio 插件可直接导入)
- 设计规范页新增「令牌导出」区,三个文件提供下载入口。
Changed — 规格原文与实现对齐
- 同步规格中的色彩系统到 v1.3.1 的 AA 达标值(15 处):占位文字 / 次要文字 / 五种语义色,并在原值处标注变更原因与对比度实测。
- 修正一处既有漂移:Rate 选中星色规格为
#FAAD14(白底 1.90:1,不满足 WCAG 1.4.11 的 3:1),实现取#2F54EB,规格已对齐实现并注明原因。
Fixed
build-site.ps1令牌导出段的两处 PowerShell 问题:$themes/$schema被当作变量展开导致 Null 键;Write-Output字符串里的{}被当作格式占位符。
[1.3.1] - 2026-09-11
Changed — 无障碍与令牌合规(9 项矩阵断言全部达标)
- 回归通过率 85.1% → 100%(961 条断言 / 0 失败 / 36 条 N/A / 79 页全通过,三次连跑结果一致)。
- 令牌层修正(改一处、全局生效):
--kole-color-text-secondary#8C8C8C→#6E6E6E(3.36:1→5.10:1)、--kole-color-text-placeholder#BFBFBF→#767676(1.84:1→4.54:1)、--kole-color-success#52C41A→#2E7D0A、--kole-color-warning#FAAD14→#8C5A00、--kole-color-error#F5222D→#CF1322、--kole-color-info#1890FF→#096DD9。原值均为 Ant Design 的「填充色阶」,作文字/白字场景均不足 AA。 - 5 端同步:
frameworks/下 150+ 文件、300+ 处硬编码色值同步到达标值。禁用态(WCAG 明示豁免)保持原弱化表现不变。 - 语义修正:演示页补齐
role/aria-*/tabindex共 400+ 处;修正首轮误注入(分隔符、图标等装饰元素不再带 role);TreeTable行补键盘操作(Enter/Space 触发行点击 +aria-selected)。 - 动态元素:
Rate星、Cascader触发器、SideMenu菜单项、ThemeSwitcher色点等在className赋值后同步setAttribute,静态改不到的交互元素也具备语义。 - 断言判据精化(修正过严/过宽,非放水):
- 图标类元素适用 WCAG 1.4.11 的 3:1(新增
icon-contrast提示项),文字仍走 1.4.3 的 4.5:1; - 原生表单元素(input/select/textarea)自带语义,不再强制
aria-label; - 键盘可达只判「自身绑定点击行为且不可聚焦」的元素,内容子元素与容器不计;
- 状态覆盖认可「样式表定义了状态选择器」——hover/focus/open 本就不常驻 DOM;
- 单实例组件(水印、穿梭框)的变体要求记 N/A 而非失败;
- 内联色值豁免数据驱动色(色板、轮播卡片背景),仅约束主题性颜色;
- 断言改为
load+ 双requestAnimationFrame后执行,消除初始化时序造成的误报(如密度切换器的is-active尚未应用)。
- 图标类元素适用 WCAG 1.4.11 的 3:1(新增
site/app.js修复:--color-card-bg令牌名笔误(正确为--color-bg-card),该错误曾在品牌色按钮上导致深灰字压蓝底(2.59:1)。
Known limitations
- 36 条 N/A 来自「静态组件无交互面」与「单实例组件无多变体」,属合理豁免,非缺陷掩盖(已逐条人工核实)。
- 本通过率覆盖 9 项自动化矩阵断言,不等同于完整的 WCAG 2.1 AA 合规认证:屏幕阅读器实测、焦点顺序、动态内容播报仍需人工/AT 工具验证。
[1.3.0] - 2026-09-10
Fixed — 验收链路(回归通过率此前不可信)
- 测试页快照为空壳:
run-tests.ps1抽取frameworks/<组件>.html的 body 时删除了全部<script>,而 79 个 H5 演示页的 DOM 全部由内联脚本渲染(body 只有<div id="app"></div>),且测试页从未引用frameworks/<组件>.css。断言跑在空 DOM + 无组件样式上,v1.2.0 的 75.1% 属结构性误报,不是实现质量。 - 测试页改为 iframe 加载真实演示页(
tests/_template.html),tests/_runtime.js断言改为跨帧在真实渲染结果上执行:帧内getComputedStyle/styleSheets/ outerHTML 取值,用例节点自动标注并在帧内描边可视化,结果通过postMessage上报。 - 断言标注改为容器下钻(
.row/.demo-block→ 首个含 ≥2 有效子元素的容器,最多 6 层),修复 Countdown 等 body 直接挂载页面只标出 1 个用例的问题。 - 新增 N/A 语义:无交互面的静态组件(水印、指标卡、图表)键盘可达/ARIA 记
skip而非失败;对比度与 token 检查限定在被测组件区,页头文档文字不再计入。 - 通过率分母改为
pass / (pass + fail),N/A 不拉低数值;tools/run-regression.mjs(CI runner)与浏览器收集器同口径。
Added — 设计系统
- 基座键盘焦点环:
:focus-visible统一 2px 描边(colors_and_type.css)。--kole-color-focus-ring此前只被定义、从未被消费,79 个组件样式里仅 20 个自带 focus 规则——此改动一次性消除 66 页focus-visible-defined失败。 tests/_collect.html:零依赖浏览器批量回归收集器(并发 iframe + 汇总 +window.__koleCollectResult),替代此前"用浏览器控制台手跑 79 页"的临时做法。tests/_index_template.html:测试总览页模板外置(原为 run-tests.ps1 内联 here-string),读数来自site/data.json,并显示最近回归通过率。
Added — 设计契约第二批(展示类 15 个)
- tree / collapse / calendar / carousel / imagepreview / qrcode / countdown / watermark / cardlist / treetable / timelinelist / steplist / chartpanel / dashboardcard / employeecard,逐份从规格原文(组件2/4/7/9.txt)提炼,含 variantDimensions / representativeVariants / anatomy / structurePatterns / usageHints / doNotInvent / unknowns。契约化覆盖 21 → 36/79。
Changed
run-tests.ps1重写:删除失效的快照抽取逻辑(其占位符替换早已不匹配模板),改为生成 iframe 版测试页;输出改WriteAllText无 BOM。脚本保持 ASCII-only(PS5.1 读无 BOM 文件按 ANSI),中文文案移入 UTF-8 模板。- 回归基线更新:960 条断言 / 通过率 85.1%(N/A 27)、11 页全通过。剩余失败项即改进 backlog:状态覆盖 45、对比度 35、ARIA 33、键盘可达 15、硬编码 hex 9、变体 2。
[1.2.0] - 2026-09-10
Added — 设计契约与工程化
- B1 契约第一批:15 个输入类组件补齐契约 JSON(autocomplete / cascader / transfer / rate / slider / segmented / radiocard / checkboxcard / switchgroup / numberrangeinput / codeinput / passwordinput / phoneinput / colorpicker / mention),契约化覆盖 6 → 21/79
- C4 静态薄壳:
site/components/<slug>.html× 79(每组件独立可爬 URL:title + meta description + canonical + 刷新跳转),sitemap.xml(80 URL,部署后回填$SiteUrlBase) - C3 headless 回归:79 个测试页全量执行 812 条断言(当前通过率 75.1%,失败项即改进 backlog),产出
tests/report.json;CI runnertools/run-regression.mjs(Playwright,含 JUnit XML 输出) - 首页 Hero 显示「测试通过率」(读取 tests/report.json,无报告时静默隐藏)
- B3 Playground:组件详情页「▶ 在线试玩」——textarea 编辑 H5 源码,iframe srcdoc 防抖实时重渲染,支持复位 / 退出,不影响源文件
- C1 交叉引用:组件详情页新增「相关组件」(相似 / 搭配维度映射 + 同分类兜底)
- 场景示范页:
site/scenario/user-management.html(筛选表单 + 数据表格 + 分页 + 新建弹窗 + 消息反馈,视觉全部来自令牌与 components.css),首页 Hero 加入口 - 部署物料:根
README.md、Pages 入口index.html重定向、.github/workflows/deploy-pages.yml、.gitignore
Fixed
- 测试页断言协议落地:
tests/_runtime.js运行期自动标注快照节点data-assert(多级结构启发式:.row → .demo → .demo-block → 首层;此前 79 页实际无断言节点,PLAN v1.1 声称与实现不符) site/data.js/site/data.json去除 UTF-8 BOM(PS5.1Set-Content默认带 BOM,严格 JSON 解析器如 node require 直接解析失败)- 断言可见性判定放宽(
getClientRects兜底),减少隐藏变体误报
[1.1.1] - 2026-09-08
Added — 竞品对齐改造(第一批,依据《竞品网站检查报告》与《现状问题分析与改造清单》)
- For Agents 页(
#/agents):AI / Agent 消费入口——机器可读资源清单、data.json 数据形状、消费示例、使用规则 site/llms.txt:LLM 入口清单,指向 data.json、契约 JSON、令牌文件与测试页- 站内更新日志页(
#/changelog):build-site.ps1解析本文件注入data.js,站点展示与仓库同源 - 主题预设库:主题定制器内置 6 套品牌色预设(科技蓝 / 青碧 / 极夜紫 / 暖橙 / 绯红 / 松石绿),一键切换后仍可微调
- 组件详情页新增「API 源码提炼」徽章,区分契约化组件(6 核心)与源码提炼组件(69 扩展)
Fixed — 文档与实现不符
- 搜索增强补票:Ctrl+K 弹窗补齐分类 chip 过滤、命中关键词
<mark>高亮、子序列模糊回退(PLAN v1.1 曾声称交付但代码缺失);搜索结果行补写data-slug修复搜索日志点击目标为空的问题
Changed
- 暗色模式令牌映射补全:
html.kole-dark新增品牌色族 / 语义色 / focus-ring / 阴影映射,并修复「主题内联样式压过暗色类」的层级问题——暗色下品牌色自动向白色混合提亮一档,kole-mode切换后即时重算 build-site.ps1:meta.version不再硬编码,改为从 CHANGELOG.md 最新版本号自动同步
[1.1.0] - 2026-09-07
Added — 文档体系补齐
PLAN.md:完整组件文档体系规划与路线图,含 5 大模块、3 版本路线、验收标准CHANGELOG.md:本文档CONTRIBUTING.md:贡献指南(如何新增组件 / 修契约 / 加测试)TESTING.md:测试矩阵、断言协议、回归流程tests/<slug>.html× 79:每个组件独立测试页(HTML+CSS+原生 JS 零依赖)tests/index.html:测试总览页(按类目聚合 + 通过率 + 失败项)run-tests.ps1:批量构建测试目录脚本
Added — 日志系统
site/logger.js:构建 / 渲染 / 搜索 / 测试 四类事件,落localStorage[kole-render-log]/localStorage[kole-search-log]/localStorage[kole-test-log]- 控制台
koleLogger.export()导出 JSON - 测试页内置
data-assert+data-status,便于 Playwright / Selenium 回归
Added — 搜索增强
- Ctrl+K 弹窗内新增分类 chips 过滤(general / navigation / input / display / feedback / system)
- 命中关键词
<mark>高亮 - 模糊容错:去空格 + 子串匹配 + 大小写不敏感
- 搜索日志:query / 命中数 / 首个命中 slug / 耗时
Added — 文档骨架
- 顶栏工具新增「测试」「日志」入口(HAMBURGER 之后)
- 组件详情页新增「测试页」链接
- 首页 hero stats 加入「测试页 79」一项
Changed
site/app.js改为引用site/logger.js,原搜索行为保留- 扩展组件契约新增「doNotInvent / unknowns」字段自动从 spec 文本提取
Fixed
- 主题定制器焦点环 rgba 计算 bug:hex 转 rgba 不再被截断为 6 位
- 类别切换时滚动条保持原位(避免视觉跳动)