Skip to content

feat: 内置大肥鱼与奶蛙皮肤、设置切换及协议草案 - #431

Draft
MistEO wants to merge 5 commits into
mainfrom
docs/skin-system-design
Draft

MistEO wants to merge 5 commits into
mainfrom
docs/skin-system-design

Conversation

@MistEO

@MistEO MistEO commented Nov 6, 2026 •

Copy link
Copy Markdown
Member

在原皮肤协议设计上,新增两套可在 设置 → 外观 → 内置皮肤 中立即切换的内置角色皮肤:蓝色大肥鱼吃白饭、奶蛙。两套使用公开社区动作视频与原片截帧,不为角色设置对白;界面文字仅表达任务状态和操作。默认选项隐藏角色,明暗主题、强调色和背景图继续独立生效。

主程序行为

  • 白饭鲸鱼娘采用 PC2005-cloud/dsh-pet 的既有吃白饭动作及同源待机/错误截帧;奶蛙采用社区三维大笑视频及原片静态帧。两份视频均静音。
  • 不添加角色对白、拟声台词或额外剧情;设置中提供素材来源与许可说明。
  • 设置中可预览皮肤、开启减少动效;系统减少动态效果设置始终优先。
  • 两套角色在桌面和移动任务视图中以真实占位卡片显示,不遮住开始/停止按钮。
  • 角色只读活动实例的运行事实:执行中优先,其次整批成功/失败,其余待机。换肤不启动、停止或重置任务,不伪造暂停、取消或百分比。
  • 桌面选择沿现有项目配置保存;WebUI 选择保存在浏览器本地,其他配置保存不会覆盖桌面皮肤。
  • 同时修复首次 WebUI 外观编辑后刷新可能重置明暗、语言、强调色的问题,以及空实例配置不恢复外观的问题。
  • 新增文案覆盖五种语言。

这是随应用打包的固定 React 组件,不是通用 Manifest 解释器,也没有开放第三方皮肤导入。通用隔离、解包、恢复及锚点协商仍按协议中的接入门槛推进。

设计稿与 Review

保留原六场景,并增加大肥鱼、奶蛙两套离线交互 Demo。互动持续 2400 ms,重复触发只延长同一互动;计时器不改任务事实,视频在减效、后台、卸载及失败时停止。

Review 中最新设计稿已吸收的项目、这次实际修复,以及仍属于生产接入门槛的问题均分别记录,未将生产权限隔离描述为已解决。两套动作视频、海报与原片截帧的来源和权利状态保留在素材说明中。鲸鱼娘素材按来源注明的 CC BY-NC-SA 4.0 保留 PC2005-cloud、上善无形与 ZipZipPipe 的署名及处理记录,不套用代码许可证。

界面

以下为实际 WebUI 在受控后端下的截图,未操作真实设备。

设置选择与预览 任务主视图
内置皮肤设置 任务主视图奶蛙

验证

  • pnpm build 通过。
  • pnpm test:127 通过、0 失败、1 项既有平台跳过。
  • 设计目录 npm run check:37 组检查通过。
  • npm run check:integration:真实 App/设置的 Chromium 集成检查 11 项通过,覆盖刷新恢复、运行中切肤、真实任务反馈、静音播放、减少动效与五种视口。
  • 独立 Demo 的 18 项浏览器检查通过;受管理浏览器限制的 file:// 导航明确跳过,本地 HTTP 已验证。

原生 WebView2/WKWebView/WebKitGTK 实机和通用隔离仍待验证。

以下保留原设计稿已填写的 AI 使用记录,未改动模型字段。

AI 使用信息:

  • Agent:codex
  • 模型:gpt-6-astra
  • 思考强度:ultra

@MistEO

MistEO commented Nov 6, 2026

Copy link
Copy Markdown
Member Author

对了这个是皮肤协议,不是具体的某个皮肤。各个项目可以自己做点皮肤放进包里去(AI 糊前端代码还不轻轻松松)

这个 PR 主要讨论皮肤系统能做什么、支持哪些能力(当然 MXU 也有可能会内置几套皮肤)

@Windsland52 Windsland52 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

评审:方向可推进,但建议暂不冻结协议、暂不开放第三方导入

这份设计稿的边界和自我披露做得比多数设计 PR 好(docs-only、明确未实现、demo 与 README 声明基本一致,demo 的计时器清理、预设白名单、无 innerHTML、Flex 真实占位都实测通过)。以下 5 条按“阻断冻结 / 阻断导入”分级,证据来自对 main a05a112 的静态核验与 demo 实测;标注“需实测”的条目是还没做三平台 WebView 验证的部分。

1. [P0] 隔离壳:真正的边界不是 iframe/CSP 文本,而是本地 API 与 webview label

  • src-tauri/src/web_server.rs:353-367 本地 Axum API 无鉴权且 CORS allow_origin(Any),PUT /api/config、/api/maa/.../tasks/start、/api/system/restart-as-admin 可直接调用;皮肤脚本一旦能发请求,绕过的是“装饰越权”,等价于管理员控制面。
  • L1 的“受信任 bootstrap + allow-scripts + CSP nonce/hash”单文档方案不成立:不可信 HTML 与可信 bootstrap 同文档时 nonce 不是边界(CSP3 §7.2);srcdoc 继承父文档 CSP,而主窗 csp: null 等于无策略。
  • Tauri v2 初始化脚本当前是 main-frame-only(tauri 2.9.5 源码事实,不是安全契约),但 ACL 粒度是 webview label 而非 frame,主窗 capability 含 fs **/*、http **、opener **/*。iframe 不能当 ACL 边界。
  • 建议:L1 皮肤文档零脚本(状态单向下发 + 宿主侧 hotspot);必须用帧时用双帧(外壳宿主帧 + 内容无脚本帧);第三方导入前做独立 webview / 独立 loopback origin + 随机 token + 响应头 CSP,并补三平台实测与 CI 断言(帧内 __TAURI__、__TAURI_INTERNALS__ 为 undefined)。

2. [P1] L0 tokens 与现有主题体系有三处硬冲突

  • src/themes/index.ts:78-114 用内联样式写 <html>,皮肤 <style> :root 会被静默压掉;需要宿主统一的 token 注入通道(或写到 stage 作用域),不能靠作者 !important。
  • --color-success / --color-info 直接取 accent(src/themes/index.ts:110-111),皮肤改 accent 会连带改成功/信息色,违反 §5“成功/停止/失败分开”。另有用户自定义强调色、背景图+透明度(src/index.css:500-531)、5 个语言包,以及 dark: 跟系统而非应用主题的既有问题。
  • 建议补一张 token 准入/优先级表(宿主默认 → 皮肤明暗默认 → 用户显式覆盖;语义色/高对比/reduced-motion 宿主强制),要求明暗经宿主 data 属性下发、禁止皮肤自读 prefers-color-scheme。§9 的“沿用现有 CSS 变量”需要先变成带类型和准入的 registry,再谈实现。

3. [P1] 状态模型与 anchor/placement 契约需要在冻结前定死

  • 示例清单自相矛盾:bindings 里 running→cheer、hotspot→mischief、mischief 2.4s→idle;任务仍在 running 时 timeout 会把场景清成 idle。建议宿主派生只读 VM(带 revision)持续下发快照,bindings 只做“事件→瞬时交互态”,最终状态由宿主任务态与交互态分层合成;paused/cancelled 在 MXU 当前 store 里没有事实来源(停止被置 null),要么补宿主状态机,要么从 v0.1 状态集删除。
  • align / hitTest / layer / edge 没有枚举,outside-start-center 与 inline-start 词汇不一致,bleed 语义、坐标系、placements 由谁执行都没定义。任意 align+offset 在 5 语言、125%/150% 缩放、850×525 最小窗下会漂移;建议改成“锚点提供扩展盒 + 允许溢出区 + 命中策略”,作者在盒内排布,offset 只做小 nudge。
  • hotspot 建议由宿主按清单渲染真实可聚焦控件(本地化名称、键盘、焦点环),不要让 iframe 内元素或透明层抢事件——后者会与窗口拖动区、保护区冲突。

4. [P1] 现状集成:壳层/图层/锚点/存储/启动时序需要先改造

  • src/App.tsx 有三个互斥顶层 return(设置/加载/主界面),没有统一壳层;主界面裁切祖先是 App.tsx:2223 的 overflow-hidden,relative z-10 是独立层叠上下文——单个根级 SkinStage 无法同时“在内容上、在模态下”;六层合成顺序在当前 z-50 / z-[100] / z-[9999] / portal 混用下映射不了,emergency-controls 在代码里不存在。
  • Toolbar 被挂载 3 次(含设置页 display:none 副本,且仍在注册全局快捷键 handler),唯一钩子是 data-role="start-stop-button";建议锚点加 ref/id、过滤不可见实例,保护区包含窗口拖动区、右侧 resizer、Schedule/权限弹窗。
  • 皮肤偏好现在只能落到每项目 mxu-{项目}.json(切项目会换皮),WebUI 用 localStorage;需要先定 activeSkinId 的存储域与多客户端 revision 策略。
  • 窗口 visible:false,showWindow() 在前端主题应用之后调用(src/utils/windowUtils.ts:135-142):“崩溃后下次启动禁用皮肤”必须发生在 Rust setup 的 show() 之前,否则皮肤卡死会让窗口永不显示、用户无法自救。
  • 缺少 prefers-reduced-motion/动效设置、DOM/几何测试设施;锚点、占位、保护区这类能力需要 static layout harness(至少 850×525 + 125%/150% 两档)才能验收。

5. [P1] 打包/更新/供应链与建议节奏

  • 现有 extract_zip(src-tauri/src/commands/update.rs:127-206)不能复用:tar.gz 分支会建符号链接,无大小/条目预算,无 symlink/大小写/重复路径检测;更新清单里的 sha256(src/services/updateService.ts:115)从未被校验。
  • 建议皮肤导入独立解包器(仅 ZIP、symlink/大小写/重复路径/保留名拒绝、按实际写入字节计数)、版本目录 + current 指针原子启用、最近 2 版回滚,且回滚目录不被启动清理(src-tauri/src/lib.rs:183-206)误删;v0.1 不做自动/静默皮肤更新。
  • 建议节奏:v0.1 = L0 token(含内置 token-only 皮肤)+ 壳层/图层/VM 契约;v0.1.x = 内置 L1;v0.2 = 第三方导入(五项阻断:隔离壳实测、网络出口切断、专用解包器、Rust 启动恢复、不静默更新+锁版本)。
  • 明确 v0.1 不做的事情也有价值:WebUI 浏览器模式默认不加载第三方皮肤;L2 只预留,且“关闭 L2 不等于隔离成立”。

不阻塞的小问题

  • protocol.html 与 protocol.md 手写重复(HTML 漏了 §11、CSS 示例与 md 冲突);ideas.md 与 ideas.js 24 条重复且编号顺序不一致;建议 md 生成 HTML、ideas 单一 JSON 源,并加一个 check 脚本让“已检查”可复现。
  • demo:状态文字 7px、对比度 2.3–3.2:1(demo/style.css:579-589);mecha 场景 visibility:hidden 隐藏宿主设备面板(含“已完成 x/3”),与 §8 承诺冲突;进度条缺 progressbar/live region;hotspot 未被 demo 证明;只有成功路径,没有 error/cancelled。

…ings

Add bundled skins, independent motion controls and settings previews while preserving task state and WebUI/desktop appearance isolation.

Extend the skin design demo and reconcile review feedback with reproducible DOM and browser checks.
@MistEO MistEO changed the title docs: 皮肤系统协议与概念 Demo(设计讨论) feat: 内置大肥鱼与奶蛙皮肤、设置切换及协议草案 Nov 12, 2026
@Windsland52

Copy link
Copy Markdown
Member

这大肥鱼不是很像

Replace generated portraits with attributed community clips and source frames. Keep character actions intact, remove fictional lines from both locales and demo, and preserve motion and task-state behavior.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants