Cua Driver 内嵌光标主题(Cursor Theme)构建与运行时架构:从 dotLottie 规范源到有界矢量产物

发布时间:2026/9/13 5:13:33
Cua Driver 内嵌光标主题(Cursor Theme)构建与运行时架构:从 dotLottie 规范源到有界矢量产物 Cua Driver 内嵌光标主题Cursor Theme构建与运行时架构从 dotLottie 规范源到有界矢量产物【免费下载链接】cuaScale computer-use 2.0 with open-source drivers, cross-OS fleets, and benchmarks for training, evaluation, and data generation.项目地址: https://gitcode.com/GitHub_Trending/cua/cuaCua Driver 的特权浮层privileged overlay内置了一套默认光标主题用于在 Agent 执行点击、拖拽、输入、滚动等动作时给出可视化提示。这套主题并非一张固定分辨率的位图而是一条dotLottie 规范源 → 编译为有界矢量产物 → 运行时矢量光栅化的完整流水线作者用 build_default_theme.py 从零生成cua.default.lottie再用cursor-theme-cli编译出运行时唯一解析的cua.default.cua-theme。读完本文你将掌握这套主题的双文件职责划分、重新生成与校验命令、确定性构建原理以及运行时着色、浮动动画、会话徽章等渲染语义并能基于同一套产物格式为自己的 Agent 会话编写或安装自定义主题。双文件分工规范源与运行时产物在 assets 目录 中有两份文件构成主题的源-产物关系文件角色cua.default.lottiecanonical source archive规范源归档是 Cua Driver 内嵌光标的创作态产物人类可编辑、可审查cua.default.cua-themebounded runtime artifact有界运行时产物由前者编译而来被特权浮层内嵌并解码两者都由 build_default_theme.py 与cursor-theme-cli从 Rust workspace 内重新生成且保持检入checked-in状态——即这两份文件本身就随源码提交运行时通过include_bytes!直接嵌入二进制。关键约束在 theme_artifact.rs 的模块注释里写得很明确.cua-themefiles contain zstd-compressed postcard data behind a fixed header. The privileged overlay never parses Lottie, ZIP, JSON, fonts, expressions, URLs, or arbitrary source paths.也就是说特权浮层只解析.cua-theme绝不在运行时解析 dotLottie ZIP 或 Lottie JSON。这样做的直接收益是运行时没有表达式执行器、没有任意路径读取、没有字体/URL 解析面主题数据被压缩到一个严格受限、可校验的格式里。有界矢量产物为什么不是像素图集.cua-theme里装的不是一张固定分辨率的像素图而是有界的矢量几何、画笔paint、变换transform与采样动画帧sampled animation frames几何被约束在 128×128 的规范化画布坐标系内见 build_default_theme.py 的CANVAS 128与 theme_artifact.rs 的CANVAS: u32 128运行时由 Skia具体实现为tiny_skia把这些矢量命令按当前显示 backing scale 实时光栅化因此在高分屏2x/Retina上依然锐利且同一份产物在不同缩放下无需重新生成产物体积被严格压缩测试断言内嵌默认产物必须小于 100 KiB见 theme_artifact.rs 的embedded_default_is_a_compact_vector_artifact。编译产物的二进制布局在 theme_artifact.rs 中有完整定义固定 8 字节魔数CUATHEM3旧版 v1 产物为CUATHEM2解码器会拒绝并提示重建为cua.cursor-theme/2头部固定 46 字节HEADER_LEN 8 2 4 32魔数 2 字节产物版本当前3 4 字节解码后长度 32 字节source_hash负载是zstd 压缩的 postcard 序列化数据压缩级别 12解码后反序列化为CompiledTheme。与此同时解码路径实施了一整套有界校验validate_compiled_theme 与validate_animation/validate_geometry压缩/解压字节上限均为 24 MiB总帧数上限 1 000单个动画上限 120 帧单帧命令上限 128 条单命令几何上限 64 个路径点上限 512文本字段id/name/version/author/license/profile上限 200 字节theme id 必须是受限的 reverse-DNS 标识符含.、每段 ≤63 字符、仅字母数字与-/_用于拒绝../bad这类路径伪装坐标必须是有限数且绝对值 ≤4096stroke 宽度在(0, 512]opacity 在[0,1]hotspot 必须落在画布内full profile 还要求 12 个动作全部齐全CursorAction::ALLdevelopment profile 至少要求idle与click。任何一项越界都会导致解码直接失败而不是在渲染期产生未定义行为——这正是有界二字的含义。重新生成两个文件完整命令从 Rust workspace 根目录libs/cua-driver/rust/执行以下三步即可完整重建这份内嵌主题assets/README.md 中的原始命令# 1. 用 Python 标准库生成规范的 dotLottie 源归档 python3 crates/cursor-overlay/assets/build_default_theme.py # 2. 把源归档编译为有界运行时产物 cargo run -p cursor-theme-cli -- build \ crates/cursor-overlay/assets/cua.default.lottie \ --output crates/cursor-overlay/assets/cua.default.cua-theme # 3. 反解产物做完整性自检 cargo run -p cursor-theme-cli -- inspect \ crates/cursor-overlay/assets/cua.default.cua-theme三点说明第 1 步无参数时默认输出到脚本同目录下的cua.default.lottie也可用--output path显式指定见 build_default_theme.pycursor-theme-cli的二进制名是cua-cursor-theme见 cursor-theme-cli/Cargo.toml除build/inspect外还提供validate、preview、install、list、uninstall等子命令见 main.rs可用于验证与安装自定义主题inspect会走与运行时完全相同的decode_theme解码路径theme_artifact.rs因此能真实反映浮层加载该产物时的解析结果。确定性构建仅标准库的 Python 生成器build_default_theme.py刻意只使用 Python 标准库zipfile/json/pathlib这样贡献者无需 LottieFiles 账号或浏览器编辑器就能复现源归档。更重要的是它保证了构建的确定性build_default_theme.py所有 JSON 均以sort_keysTrue、紧凑分隔符写出ZIP 条目的ZipInfo时间戳固定为1980-01-01 00:00:00external_attr固定为0o100644 16压缩方式固定ZIP_DEFLATED、压缩级别 9条目写入顺序固定先manifest.json标准 dotLottie 清单再cua/theme.json语义清单最后按固定字典序写a/animation_id.json。同样的字节输入必然得到同样的归档这为源码哈希必须与检入的.lottie字节一致提供了前提。生成器内置了完整的动作语义清单semantic_manifestschema: cua.cursor-theme/2、id: cua.default、version: 2.0.0、license: MITcompatibility.profile cua-driver-actions-v2、semantics 2画布 128×128 30fps热点hotspot为(55, 30)——即指针尖端的位置12 个动作idle / observe / click / drag / scroll / text / key / navigate / app / transfer / record / system每个动作映射到一个动画文件与一个still_frame静止帧供减少动态效果模式使用。这些动画全部由纯代码的矢量图元拼装而成CURSOR_PATH定义了 8 段贝塞尔指针轮廓8 层由宽到窄、透明度递增的蓝色描边构成发光glow最上层是蓝填充 5px 白色描边的指针本体cue_layers则为一组动作提示如 click 的三条短线、text 的 I 形光标、key 的按键帽、system 的齿轮叠加扩展描边发光 白色外轮廓 彩色描边三层build_default_theme.py。完整性校验源码哈希与检入字节一致编译产物头部携带的source_hash是源归档的 SHA-256encode_theme 写入、decode_theme 校验。解码时若产物头部的哈希与负载中的theme.source_hash不一致直接bail!拒绝。对应地theme_artifact.rs 中的测试embedded_default_was_compiled_from_the_checked_in_lottie做了闭环验证let source include_bytes!(../assets/cua.default.lottie); let expected: [u8; 32] Sha256::digest(source).into(); assert_eq!(embedded_default_theme().source_hash, expected);即编译产物内部的源哈希必须与检入仓库的.lottie字节完全一致。如果某次重新生成导致.lottie与.cua-theme脱同步测试会立即失败——这正是 README 所述Rust test verifies that the source hash inside the compiled artifact matches the checked-in.lottiebytes的实现位置。配套测试还覆盖了产物往返artifact_round_trip_and_bounds、拒绝 v1 旧契约rejects_v1_artifacts_with_rebuild_guidance、full profile 必须齐全 12 动作full_profile_requires_every_action以及拒绝路径伪装 idrejects_paths_disguised_as_ids。调色板与运行时着色只有内嵌默认主题会被重染色主题使用Cua blue 作为调色板主键、白色作为轮廓指针填充色定义为[94, 192, 232, 255]即十六进制#5EC0E8theme.rs白色仅用于描边不参与重染色。运行时对颜色的处理规则在 theme_artifact.rs 的resolved_color中只有当颜色等于默认光标填充色Cua blue时才被替换为会话填充色tint白色及其余颜色原样保留。测试default_tint_preserves_white_and_replaces_blue精确验证了这一行为。更关键的是染色只作用于内嵌默认主题At runtime, only the embedded default is recolored to the stable session fill. Installed custom themes retain their authored colors.这一点在 paint_compiled_theme_with_tint 中有直接体现——tint参数仅对theme.id cua.default生效自定义主题以None传入保留作者原始配色。会话填充色是稳定且多 Agent 可区分的session_fill_rgba(session_id)theme.rs对匿名/default会话返回原始 Cua blue对命名会话则从 9 色调色板紫色、粉色、绿色、橙色、青色、洋红、红、黄绿、蓝中按稳定哈希选取一个后缀数字/字母优先否则走 FNV 式哈希保证并发运行的多 Agent 会话光标视觉上可区分同时不接受任何 Agent 可控制的样式参数。共享浮动动画与播放语义共享浮动运动shared floating motion是运行时叠加在所有动作之上的统一效果周期固定为4 秒FLOAT_DURATION_SECS: f32 4.0见 theme.rs。其实现为 shared_float_motion以elapsed_secs mod 4.0求相位输出(sin(θ)*5, 6*cos(θ)-5, 2.5°*cos(θ))的水平/垂直偏移与微旋转——一个柔和的上浮-下沉漂移。要点该浮动运动只应用于选中的动作动画且对所有 12 个动作一致测试every_action_inherits_the_same_floating_base_motion逐一断言当系统开启减少动态效果ReducedMotion::On时浮动运动完全关闭测试reduced_motion_disables_shared_floating_motion动画也回退到still_frame静止帧动画播放由 CursorVisualState 驱动区分三种播放类型Loop循环如 observe/scroll、Held保持如 text直到匹配的end才在 0.4s 缓冲后回退 idle、OneShot单次如 click播完自动回到 idle。交付与目标上下文宿主会话徽章不属于主题README 最后一句明确了职责边界Delivery and target context is painted by the host-owned session badge and is not part of theme artifacts.即交付方式delivery与目标上下文target由宿主拥有的会话徽章session badge绘制不属于主题产物。对应的实现证据CursorVisualState 中delivery前台/后台交付修饰与target像素/坐标轴目标修饰虽然是渲染状态的一部分但测试action_theme_ignores_host_owned_modifiers明确断言设置了 delivery/target 后主题绘制像素与未设置时完全一致assert_eq!(pixmap.data(), base.data())会话徽章由独立的 session_badge.rs 负责它才是呈现交付与目标上下文的载体。这保证了主题文件保持纯粹的视觉动作语言宿主相关信息由浮层自身的徽章系统按需叠加。自定义主题的查看、构建与安装虽然仓库内嵌的是默认主题但同一条编译链完全向自定义主题开放。cursor-theme-cli二进制cua-cursor-theme提供完整子命令main.rscua-cursor-theme validate source.lottie [--development] cua-cursor-theme build source.lottie --output theme.cua-theme [--development] cua-cursor-theme inspect theme.cua-theme [--json] cua-cursor-theme preview theme.cua-theme --output directory cua-cursor-theme install theme.cua-theme cua-cursor-theme list [--json] cua-cursor-theme uninstall theme-id安装的主题存放于本地主题库store按平台解析theme_store_root可通过环境变量CUA_DRIVER_CURSOR_THEME_DIR必须是绝对路径覆盖Windows%LOCALAPPDATA%\Cua Driver\cursor-themesmacOS~/Library/Application Support/Cua Driver/cursor-themesLinux$XDG_DATA_HOME/cua-driver/cursor-themes缺省为~/.local/share/cua-driver/cursor-themes。安装采用临时文件写入 原子 renameinstall_artifact加载时拒绝符号链接并缓存已解码主题load_installed_theme。内嵌的cua.default不可卸载uninstall_theme自定义主题 id 必须为合法 reverse-DNS 形式文件名即主题 id。小结这套光标主题体系的核心设计可以概括为一句话创作阶段可以充分表达dotLottie 语义清单运行阶段必须绝对受限zstdpostcard 的有界矢量产物。cua.default.lottie与cua.default.cua-theme双文件、build_default_theme.py的确定性生成、source_hash的闭环校验、仅对内嵌默认主题生效的会话重染色、4 秒共享浮动动画以及宿主会话徽章对交付/目标上下文的分担共同保证了特权浮层在任何分辨率、任何会话规模下都能以可预测、可验证的方式渲染出清晰的多 Agent 光标反馈。【免费下载链接】cuaScale computer-use 2.0 with open-source drivers, cross-OS fleets, and benchmarks for training, evaluation, and data generation.项目地址: https://gitcode.com/GitHub_Trending/cua/cua创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考