Hyperframes CLI 质量门禁实战:lint、check 与 snapshot 的验证体系与源码原理
Hyperframes CLI 质量门禁实战lint、check 与 snapshot 的验证体系与源码原理【免费下载链接】hyperframesWrite HTML. Render video. Built for agents.项目地址: https://gitcode.com/GitHub_Trending/hy/hyperframes在 Hyperframes 中Write HTML. Render video. 的工作流最终要把一段 HTML 组合composition渲染成视频而在渲染之前代码质量与视觉正确性必须被自动化验证。本文基于 Hyperframes CLI 的 lint-validate-inspect.md 参考文档系统讲解三条验证命令的分工lint快速静态反馈、check浏览器内全量门禁、snapshot关键帧截图并结合packages/cli中的命令实现与检查管线源码说明每个检查项的判定规则、参数语义与底层原理。读完本文你将掌握一套先 lint、再 check、辅以 snapshot 与 motion 断言的完整质量闭环并能读懂检查报告、定位缺陷、用逃生舱标记escape hatch表达设计意图。三条命令的分工与使用纪律命令定位典型使用时机lint快速静态反馈迭代辅助每完成一轮 HTML 修改后立即运行check必需的最终门禁提交、渲染、发布前的完整验证snapshot独立截图工具不过时视觉对比、缩略图、PR 配图、缺陷放大核心纪律是不要在任何check之前再串联一次独立的lint——check第一步就会重跑同一个 linter链式调用纯属冗余。validate、inspect、layout三个命令仍然可用但已标记弃用deprecatedcheck一次调用覆盖了它们全部能力。对于动画驱动的合成motion-heavy work文档给出了明确的操作纪律第一版 HTML 写完后先跑lint获取早期反馈——它是迭代辅助工具不是独立的最终门禁第一轮完整稿后运行check --snapshots用概览帧和逐缺陷裁剪图看清审查器看到了什么在调整自动化告警之前先看 PNG——人眼能发现审查器漏掉的问题审查器也能发现人眼漏掉的问题除非快照能证明层级是刻意为之否则把布局错误当作缺陷处理并用data-layout-allow-*属性显式标记用*.motion.json旁车文件声明运动意图让check自动验证入场触发、错落顺序、画面内、活跃性——这是观看 MP4最接近的自动化代理能捕获眼睛漏掉的渲染与预览不一致缺陷。lint毫秒级静态反馈基本用法npx hyperframes lint # 检查当前目录 npx hyperframes lint ./my-project # 检查指定项目 npx hyperframes lint --verbose # 同时输出 info 级发现 npx hyperframes lint --json # 机器可读输出lint 扫描index.html与compositions/下所有文件报告三类发现errors必须修复、warnings应当修复、info仅--verbose时显示。它能捕获的问题包括缺失data-composition-id、同一data-track-index上的轨道重叠、未注册的时间线timeline、以及 GSAP 与 CSS transform 的冲突。源码视角的命令实现在 packages/cli/src/commands/lint.ts 中lint命令由defineCommand定义核心流程是通过resolveProject(args.dir)解析项目目录packages/cli/src/utils/project.ts调用lintProject(project.dir)执行实际检查packages/cli/src/utils/lintProject.ts非 JSON 模式用formatLintFindings输出人类可读结果--json模式输出包含ok、errorCount、warningCount、infoCount、findings、filesScanned的统一信封退出码由setCommandExitCode控制存在错误时退出码为 1仅警告时为 0。源码注释揭示了一个重要的实现细节命令故意使用setCommandExitCodereturn而非process.exit()因为process.exit()会在 Node 刷新异步非 TTY / 管道stdout 之前终止进程导致hyperframes lint --json | ...在 Windows 上静默丢失 JSON 负载。媒体元素的 lint 语义video/audio可以在任意嵌套深度工作包括compositions/*.html子合成或包装div内部运行时用扁平 DOM 查询发现媒体无论它在哪里都会进行 seek 和解码见packages/core/src/runtime/media.ts与packages/core/src/runtime/startResolver.ts。渲染之后对每个含视频的场景跑snapshot确认面板真的显示了画面——该播放视频处出现空白/黑面板是真缺陷不是占位符。check一次 Chrome 启动完成全量门禁完整参数清单npx hyperframes check # 当前目录完整浏览器门禁 npx hyperframes check ./my-project # 指定项目 npx hyperframes check --json # agent 可读信封 {ok, lint, runtime, layout, motion, contrast, snapshots} npx hyperframes check --snapshots # 额外写入概览帧带标注 逐缺陷裁剪图 npx hyperframes check --samples 15 # 更密集的时间线扫描默认 9 npx hyperframes check --at 1.5,4,7.25 # 显式指定英雄帧时间戳 npx hyperframes check --at-transitions # 额外采样每个 tween 起始/结束边界 npx hyperframes check --tolerance 4 # 允许的溢出像素数默认 2 npx hyperframes check --timeout 30000 # 初始渲染就绪 导航最低等待毫秒数默认 3000 / 10000 npx hyperframes check --no-contrast # 迭代期间跳过 WCAG 对比度审查 npx hyperframes check --strict # 警告也导致非零退出码默认仅错误在 packages/cli/src/commands/check.ts 中可以看到更完整的参数集包括--max-issues静态折叠后最多打印/返回的问题数默认 80、--collapse-static跨采样折叠重复静态问题默认开启、--max-transition-samples转换派生采样上限、--layout proseCoverageFloor0.05正文覆盖率下限默认 0.15、--proxy浏览器不友好的视频编解码自动转码、--browser-gpu等。所有数值参数都经过严格校验positiveInteger、nonNegativeNumber、parseNumberStrict会拒绝4px、0.05abc这类Number.parseFloat会静默接受的后缀垃圾。一次调用、一次 Chrome 启动的管线check先运行 linterlint 报告错误时直接跳过浏览器。然后它加载一次打包后的合成在导航前接线运行时监听器再扫描一个 seek 网格在每个采样点执行全部审查管线核心见 packages/cli/src/utils/checkPipeline.ts 的runCheckPipelineshouldBlockRender决定 lint 错误是否阻断浏览器阶段RuntimeJS 控制台错误、未处理异常、失败的网络请求过滤掉媒体文件的ERR_ABORTED、HTTP 4xx/5xx。Layout文本超出其容器或画布、文本被自身盒子裁剪、持久的文本重叠与遮挡含近似覆盖比例、子元素逃逸裁剪容器。Motion*.motion.json旁车文件对同一 seek 时间线的断言见下文。Contrast对可见文本做 WCAG AA 审查在 5 个网格点采样。失败是error级别每条发现携带采样的前景/背景色、实测与要求对比度之比以及同一调色方向上的合规建议色——多数对比度修复无需截图。每条发现都携带选择器、元素的data-*标识、合成源文件、bbox 和采样时间可以从 JSON 直接跳到必须修改的 HTML 并重跑。严重度是持久性感知的这是check最反直觉也最重要的设计只在单个网格采样观察到的动态问题入场/出场瞬态降级为 info永不阻塞退出码跨多个采样持续存在的问题才会门禁退出码持久的content_overlap是 error持久的、部分可见且突破画布 ≥5% 的canvas_overflow提升为 warning坐标框架类发现escaped_container、panel_out_of_canvas、connector_detached标记在一个帧中计算几何、在另一个帧中渲染的情况——远离 offset parent 的元素、卡在画布边缘的绘制面板、脱离所有节点的连接线如果 3 秒以上的合成在所有采样中显示零几何变化check以sweep_static失败——冻结的时间线会让所有绿色判定不可信因此拒绝放行。该守卫的实现见 checkPipeline.ts短于 3 秒的合成标题卡合法地全程静止、单采样运行、以及已报告motion_frozen的运行都会被跳过。指纹fingerprint包含逐元素 opacity所以纯 opacity 揭示代码打字、错落淡入也算运动——但仅在采样时刻仍处于进行中。经典陷阱是揭示过早完成然后整段剩余时长保持静态帧每个采样都落在稳定状态上运行失败。正确做法是把揭示铺满时间线或保持一个持续动画的元素存活代码打字场景中闪烁光标是惯用做法——不要为了讨好检查而硬加一个缓慢的位置漂移。逃生舱Escape Hatches在 HTML 中声明意图布局问题如果是有意为之用data-*属性标记后在 HTML 中声明意图然后重跑data-layout-allow-overflow— 溢出是有意的入场/出场位移。data-layout-allow-overlap— 刻意的文本叠加如演示光标标签压在标题上。仅作用于被标记的文本块不继承。标记具体的叠加参与方绝不标记场景/根包装器这样无关后代的碰撞仍可被审查。data-layout-allow-occlusion— 元素有意覆盖文本。data-layout-allow-caption-zone— 有意的下三分之一 / 字幕带文案位于--caption-zone之下。作用于被标记元素及其每个后代closest只静默caption_zone_collision不影响 overflow/overlap/occlusion。优先选择拥有该有意带文案的最窄包装器。data-layout-ignore— 装饰性元素永不参与审查。可选管线门禁字幕带与出帧检测npx hyperframes check --caption-zone x00;y0.82;x11;y11;severityerror;seek.25,1 npx hyperframes check --frame-check # media (img/svg/video/canvas) 出帧检测--caption-zone接受分数带几何x0/y0/x1/y1必填0–1 之间、相对于合成自身画布的分数竖屏同样适用可选severity和逗号分隔的seek分数它标记文本元素的 DOM 盒子getBoundingClientRect与带的交叠。源码中 check.ts 的 parseCaptionZone 与 checkPipeline.ts 的 captionFinding 实现了这一逻辑交叠判定为矩形相交测试caption_zone_collision的严重度由severity决定并给出距底部约pctFromBottom%的提示信息。--frame-check报告突破画布超过max(120px, 最小画布尺寸的 6%)的媒体元素——这个阈值常量FRAME_BREACH_FLOOR_PX与FRAME_BREACH_FLOOR_FRACTION定义在 checkPipeline.ts。带参数的--frame-check支持severityerror;seek.25,.75;tol4形式微调值得注意normalizeFrameCheckRawArgs的存在裸--frame-check后跟下一个选项时会被规范化避免吞掉后续参数。修复对比度错误阈值普通文本 4.5:1大文本 3:124px或 19px 加粗。发现的suggestedColor已经选了正确方向上的最近合规色深底提亮、浅底压暗应用它或在调色板家族内微调然后重跑check。源码中 buildContrastResults 还实现了与布局一致的持久性规则单个采样上的对比度失败通常是入场/出场瞬态经典形态是 1.0 时刻白底白字降级为 warning同一元素在 2 采样持续失败才是真正阻塞的 error。Motion 验证*.motion.json旁车文件check对运动意图的验证基于渲染器使用的同一 seek 时间线——这是渲染 MP4 并观看最接近的自动化代理。它能捕获布局采样无法发现的渲染与预览不一致缺陷seek 越过的入场揭示、错乱的错落顺序、tween 中途漂移出画的元素、冻结的镜头。在合成旁边放置*.motion.json旁车文件多个合成共享目录时基名与 html 匹配check自动发现它——无需标志位无需改动创作框架。没有旁车文件时check行为与之前完全一致。侧车文件的发现逻辑同名匹配优先、歧义时报错见 packages/cli/src/utils/motionSpec.ts 的 findMotionSpec。{ duration: 6, assertions: [ { kind: appearsBy, selector: #headline, bySec: 0.5 }, { kind: before, a: #headline, b: #cta }, { kind: staysInFrame, selector: .card }, { kind: keepsMoving, withinSelector: .scene } ] }断言失败条件错误码appearsBy(selector, bySec)到bySec时仍不可见opacity ≥ 0.5—motion_appears_latebefore(a, b)a没有严格先于b首次出现 —motion_out_of_orderstaysInFrame(selector)可见后其盒子离开画布 —motion_off_framekeepsMoving(withinSelector?)完全静态窗口超过maxStaticSec默认 2s—motion_frozenduration、withinSelector、maxStaticSec均可选。发现默认是 error 级别与布局发现出现在同一人类可读和--json输出中。选择器匹配不到任何元素时报motion_selector_missing而非静默通过——拼错的选择器会大声失败。规范的解析与逐字段校验appearsBy的bySec 0、keepsMoving的withinSelector不能是*、maxStaticSec必须为正数在 motionSpec.ts 的 parseMotionSpec 中实现运动采样以 20fps 网格扫描、上限 300 采样MOTION_FPS/MOTION_MAX_SAMPLES见 checkPipeline.ts。用法在反馈循环中用这个文件代替肉眼检查渲染——断言运动应该做什么让check告诉你 seek 何时偏离了意图。snapshot关键帧截图与缺陷放大npx hyperframes snapshot # 5 个关键帧 PNG npx hyperframes snapshot ./my-project # 指定项目 npx hyperframes snapshot --frames 10 # 均匀分布 N 帧从合成捕获静态 PNG用于视觉对比、缩略图或附加到 PR。当只需要几个英雄帧时比渲染整段视频快得多。输出落在项目的 snapshots 目录。它没有过时snapshot仍是独立截图工具而check --snapshots覆盖门禁自身需求带标注发现框的概览帧 每个带 bbox 的错误发现的finding-NN-code.png裁剪图。源码中 packages/cli/src/commands/snapshot.ts 还展示了几个值得了解的实现细节媒体帧处理Chrome headless 忽略程序化video.currentTime写入因此 snapshot 用 FFmpeg 提取帧并以img叠加extractVideoFrameToBuffer每个活跃视频在采样时刻解析其 clip 起点、播放速率与时长resolveSnapshotVideoClipStart/resolveSnapshotVideoPlaybackRate结尾帧保证computeSnapshotTimes会把最后一个等距点移到可读的结尾帧tailFrameTimeduration - max(0.05, duration*0.03)因为精确 seek 到data-duration会渲染空白——运行时把 t ≥ clip-end 视为结束并卸载 clip注释中记载了 8s clip 在 t8.0 时纯白、t7.76 时显示最终英雄帧的实证运行前先跑 lint若默认index.html入口为空白则中止并给出修复建议快照目录中的旧 PNG 会被清理随后生成 contact sheet 网格图contact-sheet.jpg供 AI 快速回顾。放大某个已报告的发现hyperframes check --snapshots已为每个带 bbox 的错误发现写入finding-NN-code.png裁剪图但一旦你知道要看什么同样的放大可以独立使用npx hyperframes check --snapshots # 报告发现如 #cta 上的 content_overlap npx hyperframes snapshot --zoom #cta # 裁剪元素验证缺陷3x 密度 npx hyperframes snapshot --zoom 100,50,400,300 --zoom-scale 2 # 或精确像素区域 # 修复合成 HTML 后重新检查 npx hyperframes check--zoom接受 CSS 选择器或精确的x,y,w,h像素区域且总是产生真实的高密度裁剪提高deviceScaleFactor绝不是 CSS zoom 或视口缩放因此合成的布局及其渲染确定性不受影响。选择器匹配不到任何元素是响亮错误而非静默的全帧回退目标在某一帧没有可见盒子折叠或动画出画时该帧被跳过并附注说明而不会写成一个细条。snapshot还支持更多参数见 snapshot.ts--output/-o指定输出目录、--at显式时间戳、--timeout运行时初始化等待默认 5000ms、--angle正交 3D 相机front|iso|top|side预设或yaw,pitch度数用于深度/遮挡检查、--no-end关闭自动追加结尾帧、--against参考视频同帧生成ref-*.png与 render|reference 对照 sheet、--describe用 Gemini 视觉模型逐帧分析设置GEMINI_API_KEY后默认启用--describe false退出。弃用命令的迁移validate、inspect、layout三者仍然可用、在 stderr 打印弃用通知并在--json中标记_meta.deprecated: true相关命令实现见 packages/cli/src/commands/validate.ts 与 packages/cli/src/commands/layout.ts。它们的功能全部收编进checkvalidate运行时错误 对比度→check对比度失败现在是带修复负载的门禁错误不再是警告inspect/layout布局扫描 motion 旁车→check相同标志--samples、--at、--at-transitions、--tolerance、--strict。迁移脚本时用单个check调用替换原有命令序列脚手架项目的npm run check已经指向check。结语把验证写进工作流Hyperframes 的验证哲学可以概括为一句话静态问题用 lint 快速捕获动态与视觉问题用 check 在真实浏览器里按时间线扫描肉眼复核用 snapshot运动意图用 motion.json 断言。sweep_static、持久性感知的严重度、以及选择器匹配不到就大声失败这类设计都在守卫同一个目标让每一个绿色判定都可信。把npx hyperframes check --snapshots当作渲染前的例行步骤配合逃生舱属性表达设计意图你的 HTML 合成就能在进入渲染管线之前把绝大多数缺陷挡在门外。相关参考本指南原始文档skills/hyperframes-cli/references/lint-validate-inspect.mdCLI 命令实现packages/cli/src/commands/check.ts、packages/cli/src/commands/lint.ts、packages/cli/src/commands/snapshot.ts检查管线核心packages/cli/src/utils/checkPipeline.ts、packages/cli/src/utils/motionSpec.tsCLI 总览与更多命令packages/cli/README.md【免费下载链接】hyperframesWrite HTML. Render video. Built for agents.项目地址: https://gitcode.com/GitHub_Trending/hy/hyperframes创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考