Codex Dream Skin 皮肤修复实战:Codex 26.727 兼容与持久双层部署
Codex Dream Skin 皮肤修复实战:Codex 26.727 兼容与持久双层部署
记录一次 Codex Dream Skin 皮肤在 Codex 26.727 版本更新后的完整修复过程,涵盖问题诊断、源码兼容、持久部署和验证回滚。
背景
Codex Dream Skin 是一个为 OpenAI Codex Windows 客户端定制的皮肤项目,灵感来自《Needy Girl Overdose》中的超天酱(Internet Angel)。它通过 CDP(Chrome DevTools Protocol)注入 CSS 和 JavaScript,为 Codex 界面添加动态背景插画、眨眼动画、广播装饰浮层等效果。
我一直在用这套皮肤,某天电脑重启后发现主页白屏、动画全部消失。排查下来发现是 Codex 自动更新到了 26.727 版本,旧版皮肤的选择器和路由逻辑全部对不上了。这篇文章记录了从发现问题到彻底修复的完整过程,方便以后再次遇到时快速定位。
皮肤的工作原理
皮肤的"动态背景"不是整张 GIF 或视频,而是由两部分组成:
- 一张静态 2560 × 1440 背景图
dream-reference.jpg - 渲染器叠加的 CSS/SVG 动画,包括眨眼、广播滚动条、状态模块、心跳和装饰浮层

"我们该构建什么?"这个标题是 Codex 自身主页的 DOM 文字,不是烘焙在图片里的字体。功能卡、输入框和侧栏也都是 Codex 的真实组件,皮肤只是给它们加了分类和样式。
正确的路由分工应该是这样的:
| 页面 | 正确效果 |
|---|---|
| 新对话主页 | 完整超天酱插画、四张功能卡、广播装饰与短暂眨眼动画 |
| 普通对话/任务页 | 深色不透明阅读工作区,背景图不穿透正文 |
| 输入框 | 清晰、接近不透明;任务页不使用高成本实时模糊 |
| 左侧栏 | 保留皮肤色彩,但不能影响原生导航和点击 |
问题爆发
电脑重启后,我用旧版 Dream Skin 运行库启动,注入器倒是成功连上了渲染进程,但页面验证直接失败了。启动脚本按安全策略回滚,自动重新打开了无皮肤的官方 Codex 界面。
一通排查后,发现是三个独立问题同时存在,叠加在一起才导致全面失效。
问题一:Codex 26.727 更换了主容器标识
旧版皮肤的 CSS 选择器依赖 main.main-surface,但 Codex 26.727 把稳定主容器改成了 main[data-app-shell-main-surface]。
皮肤还能注入部分组件——侧栏、边框和功能卡看着是生效的,但主页和任务页的路由分类没有命中新主容器。结果就是主页大面积白屏,或者刷新后失效、背景错误透明。
问题二:正确图片被保存成了 custom 主题
活动图片跟作者原图的字节完全一致,但活动 theme.json 的主题 ID 被写成了 custom。渲染器只为 Internet Angel/Choten 预设启用 .dream-choten-art 类,所以眨眼和作者动态浮层被 CSS 正常隐藏了。
这里有个容易踩的坑:开发者工具里能查到动画名称存在,但这不代表动画真的在显示——隐藏元素也可以拥有 animation-name。必须同时检查主题身份、主页 class、元素 display 和实际几何位置才能确认。
问题三:启动入口和重启生命周期混淆
Windows 上同时存在好几个入口,一开始我搞混了:
| 图标 | 用途 |
|---|---|
Codex Dream Skin |
正确的日常启动/重新应用入口 |
Codex Dream Skin - Tray |
托盘主题控制器,不是主应用启动入口 |
Codex Dream Skin - Restore |
恢复官方外观并关闭皮肤会话 |
官方 Codex |
直接启动原版应用;没有皮肤 CDP 会话时会显示原版界面 |
还有个更隐蔽的坑:如果在 Codex 自己的前台 PowerShell 里执行"关闭 Codex → 安装 → 重启"流程,Codex 关闭时会把它承载的进程一并终止。结果就是只完成了关闭动作,后面的安装和重启都没执行到。解决办法是在关闭之前先启动一个独立的外部协调进程,让它来负责整个重启流程。
症状诊断表
整理了一张诊断表,方便下次遇到问题快速定位:
| 症状 | 优先检查 | 常见根因 |
|---|---|---|
| 主页大面积白色,侧栏和卡片已有皮肤 | 主容器选择器、主页类 | 新版 data-app-shell-main-surface 未兼容 |
| 主页有图但完全静态 | 活动主题 ID、.dream-choten-art、眨眼层 display |
图片被保存为 custom |
| 普通对话页背景图穿透,文字难读 | 路由分类、任务页背景、临时全局补丁 | 把主页壁纸错误应用到整个 body |
| 滚动或输入卡顿 | task composer 的 backdrop-filter、全屏 fixed wallpaper |
任务页仍在绘制壁纸和实时模糊 |
| 闪退后自动打开一个未美化应用 | 启动日志、状态文件、重复注入器、启动入口 | 启动验证回滚、前台重启被杀、打开了官方图标 |
源码兼容修复
选择器兼容
核心修改是把旧版单一选择器扩展为同时兼容新旧两种容器标记:
const SHELL_MAIN_SELECTOR = ":is(main.main-surface, main[data-app-shell-main-surface])";
const APPLICATION_HEADER_SELECTOR = ":is(header.app-header-tint, header[data-app-shell-application-menu-bar])";
这两个常量需要在所有用到主容器的地方统一引用:shell main 发现、Safe CSS 部件注册、主页/任务页路由分类、几何同步、侧边工作区发现、MutationObserver/重渲染后的重新应用。
特别要注意的是不要只改第一个 querySelector——如果 CSS 仍只匹配旧容器,主页还是白;如果路由分类仍只匹配旧容器,任务页还是会透出背景。
CSS 路由约束
全窗口背景图只能在主页存在时绘制:
html.codex-dream-skin.dream-art-wide:has(
:is(main.main-surface, main[data-app-shell-main-surface]).dream-home-shell
) body {
background-color: var(--dream-canvas) !important;
background-image: var(--dream-art) !important;
background-position: var(--dream-art-position) !important;
background-size: cover !important;
background-repeat: no-repeat !important;
background-attachment: fixed !important;
}
任务页必须重新建立不透明阅读面,并关闭 composer 的实时模糊:
html.codex-dream-skin.dream-art-wide:is(.dream-task-ambient, .dream-task-banner)
:is(main.main-surface, main[data-app-shell-main-surface]).dream-task:not(.dream-home-shell) {
background: var(--dream-surface) !important;
}
html.codex-dream-skin.dream-art-wide:is(.dream-task-ambient, .dream-task-banner):has(
:is(main.main-surface, main[data-app-shell-main-surface]).dream-task:not(.dream-home-shell)
) .composer-surface-chrome {
background: var(--dream-surface-raised) !important;
backdrop-filter: none !important;
}

主题身份恢复
活动图片和作者原图的 SHA-256 完全一致时,可以通过项目内置的 Set-DreamSkinActiveTheme 函数原子恢复预设身份。恢复后主题 ID 从 custom 变回 preset-internet-angel-default,眨眼和动态浮层重新生效。
如果哈希不一致,说明图片被替换过(可能是之前手动换的),那就保留当前主题不动,不自动覆盖。
恢复后的主题配置:
{
"id": "preset-internet-angel-default",
"appearance": "auto",
"art": {
"focusX": 0.72,
"focusY": 0.42,
"safeArea": "left",
"taskMode": "ambient"
},
"palette": {
"accent": "#ff45c8"
}
}
持久双层修复
第一次修复时我只更新了 engine(实际运行库),当时确实恢复了。但后来运行库被重新安装时,它从旧 payload(安装器持久载荷)退回了修复前的版本,皮肤又坏了。
所以最终方案是"持久双层修复":同时更新 engine 和 payload 两个位置,确保下次安装器运行时也不会覆盖掉修复。

上面的闭眼图是通过项目已有的 dream-preview-blink 类临时强制显示的,用来证明 SVG 眼皮层确实存在且位置正确。截图后这个类就移除了。日常动画按约 11.4 秒周期运行,真正闭眼只占其中很短的时间,一直盯着也可能错过。
部署流程
我采用了"暂存 → 校验 → 替换"的流程,确保每一步都可回退:
- 先把修复文件复制到独立暂存目录
- 在暂存目录执行语法检查、JSON 校验、CSS 校验和注入负载检查
- 逐个替换
payload中的对应文件,每个替换后复核 SHA-256 - 逐个替换
engine中的对应文件,同样复核哈希 - 确认两层核心文件与修复源完全一致
避免踩坑
这些临时方案不要用:
- 无条件给
body添加background-image: var(--dream-art)——会让任务页也穿透 - 把所有 task/main/message 背景改成透明——文字根本没法看
- 依赖 CSS module 生成的随机哈希类——更新后直接失效
- 只修当前页面、不处理新对话、刷新和路由切换——切个页面就白修了
- 只改
engine目录却不改payload——下次安装器跑完就回退了
验证与结果
修复后的核心文件哈希
修复后的核心文件在源码、engine 和 payload 三处 SHA-256 完全一致,确保没有遗漏:
| 文件 | SHA-256 |
|---|---|
selectors.json |
AA1528EF169EDAED0D8DCFAE367452B29196CA6319DEFAD072E55F65936A0B3 |
renderer-inject.js |
3F8A2196194DE3968F18D2E8B3DC346187283EE4B2069CFBADD2BA53603A86D9 |
dream-skin.css |
65707A1CFF52D308C780638C4A5570ABFD1414B45658211100BC5FA9065EBA96 |
最终验证
修复完成后连续观察了 90 秒,再次验证通过,没有闪退、回滚或重复启动。注入器错误日志为 0 字节。


验证结果 JSON:
{
"Success": true,
"CompletedAt": "2026-08-04T02:12:53+08:00",
"StabilityWindowSeconds": 90,
"Port": 9335,
"InjectorPid": 21528,
"InjectorAlive": true,
"ThemeId": "preset-internet-angel-default",
"ErrorLogLength": 0
}
回滚与备份
修复前建立了完整的备份链,确保任何一步出问题都能恢复:
- 备份目录:
%LOCALAPPDATA%\CodexDreamSkin\backups\persistent-dual-repair-20260804-020341-750 - 独立 ZIP:
persistent-dual-repair-20260804-020341-750.zip - ZIP SHA-256:
6D9B7D3D6F06F58C5612E6E5561FB2F6689965E755EB8B37FD2CAB442A4B4018
开机托盘快捷方式没有永久删除,归档在备份目录的 archived-startup 文件夹里了。任何部署失败都优先从备份恢复。
关键经验总结
- 不要假设旧路径仍然成立——换电脑或版本更新后,先做只读环境发现,确认当前路径、版本和状态,不要照抄旧路径
- 选择器兼容要全覆盖——不是只改第一个
querySelector就完事,CSS、路由分类、几何同步全都要同步更新 - 动画名称存在 ≠ 动画可见——隐藏元素也可以拥有
animation-name,必须检查display和实际几何 - 双层部署避免回退——只改运行库不够,安装器载荷也要同步,否则下次安装直接打回原形
- 重启必须由独立进程协调——在 Codex 前台进程里重启 Codex,会把它自己一起杀掉
- 每一步都留下证据——执行了什么、成功判据是什么、失败了从哪里回滚,不要只记个"应该好了"
项目信息
- 项目地址:EmiyaKatuz/Codex-Dream-Skin-Needy-Girl-Overdose
- 适用平台:Windows 10/11、Microsoft Store 官方 OpenAI.Codex
- 本次基线:Codex
26.727.6591.0、Dream Skin1.5.9、Node24.17.0 - 修复日期:2026-08-04