Skip to content
Closed
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions TASK_PROGRESS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,61 @@
# Task Progress

## Codex composer and Pet surface compatibility (2026-08-18)

- [goal] Fix current Codex renderer drift where the composer fallback binds to
`_ComposerLayoutFooter_` instead of `_ComposerLayoutRoot_`, and prevent Dream
Skin from injecting wallpaper/CSS into `/avatar-overlay` and Pet composition
surfaces that must remain transparent.
- [scope] Isolated clone
`/Users/huangjinnan/Desktop/Codex-Dream-Skin-pr-composer-pet-fix`, branch
`codex/fix-composer-pet-scope`, based on exact `origin/main@95423d8` (v1.5.14).
Shared runtime source, generated dual-platform assets, focused regressions,
and this progress record are in scope. User-specific theme colors are not.
Comment thread
hjnnjh marked this conversation as resolved.
Outdated
- [field evidence] Live macOS Codex exposed `_ComposerLayoutRoot_*` around the
active ProseMirror while the v1.5.14 fallback marked `_ComposerLayoutFooter_*`.
The avatar overlay plus Pet composition surfaces carried
`data-dream-skin="active"`; three bodies had the theme wallpaper instead of a
transparent background. Local runtime guards and explicit cleanup restored
all five Pet-related surfaces to transparent without changing Pet assets.
- [implemented] Canonical selector contract now accepts both legacy
`.composer-surface-chrome` and `_ComposerLayoutRoot_`, with the matching
toolbar selector. The generic fallback also prefers `_ComposerLayoutRoot_`
before broad composer/prompt ownership so `_ComposerLayoutFooter_` cannot
capture the public composer part.
- [implemented] Shared renderer payload self-excludes `/avatar-overlay` and
Pet composition-surface routes before installing style/art state, cleaning a
previous payload first when present. Both platform injectors classify those
targets explicitly, and one-shot plus watcher discovery reuse the existing
remove-and-verify path to clean already contaminated Pet renderers.
- [tests] Shared renderer regressions cover fresh Pet exclusion, cleanup after
prior injection, ComposerLayoutRoot selection, and footer non-selection.
macOS/Windows bootstrap regressions cover probe exclusion and require both
discovery paths to call verified cleanup. Focused dual-platform renderer,
bootstrap, selector-doctor, syntax, sync, payload, and diff checks pass.
- [tests] Portable Node set passes 102/103 in the default sandbox; the sole
Swift bounded-HTTP test was blocked by module-cache permission/toolchain
setup there and passes when rerun outside the sandbox, yielding 103/103
covered tests. The complete macOS wrapper passes outside the sandbox with
its documented signed-runtime, full-Xcode, and Doctor branches skipped.
- [skill] User Skill `~/.codex/skills/dream-skin-repair` is installed. Its
read-only audit reports the main renderer themed, all five Pet-related
targets transparent/unmarked, and no anomalies; `quick_validate.py` passes.
- [review] Independent code/spec/security review found no Critical, High,
Medium, or Low issues. It confirmed renderer self-exclusion, verified cleanup
in one-shot and watcher paths, ComposerLayoutRoot selection, generated asset
synchronization, and focused dual-platform coverage.
- [committed/pushed] Implementation and test commit
`c4c3a7e90c0def8c4a6961ca013ec2ac36ca15b8` plus changelog commit
`c1433be12252b868b4a0cabc338ed03afdf04a9f` are pushed to
`hjnnjh/Codex-Dream-Skin:codex/fix-composer-pet-scope`. The public compare is
3 commits ahead of upstream after this progress checkpoint and 0 behind.
- [blocked] PR title/body and template evidence are prepared, but the final
GitHub web submission is blocked because the macOS session locked while
Safari held the authenticated GitHub state. No PR exists yet.
- [next] Unlock the Mac, open a Ready PR against `Fei-Away/main`, then record
the PR URL and require exact-head CI. Native Windows PowerShell 5.1/7 remains
a CI gate.

## Issue #352 fix and v1.5.14 release (2026-08-12)

- [fix merged] PR #360 (`e3787857953998a1916c39b10942ac6c15978a25`) passed exact-head CI run `31558654733`: Static, macOS repository regressions plus universal DMG, Windows PowerShell 7, and Windows PowerShell 5.1 plus Setup.exe. It was squash-merged with the authorized same-owner review bypass at `2026-08-12T03:06:37Z` as `main@69a5a2e4b68174b1c0c70a2fa62adf1aca1eff2a`.
Expand Down
1 change: 1 addition & 0 deletions macos/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

### 修复

- 修复新版 Codex 把输入框壳迁移到 `_ComposerLayoutRoot_` 后,Dream Skin 误把 `_ComposerLayoutFooter_` 标记为 composer、导致主题输入框样式只落在底部工具栏的问题;同时排除 `/avatar-overlay` 与 Pet composition surface,并在发现旧注入时执行移除与验证,避免主题壁纸污染透明 Pet 窗口形成矩形背景。
- 修复透明或极端显式强调色下按钮文字对比度不稳定的问题:共享渲染器现在按真实 composer 面板表面和最坏背景计算前景色,并正确处理 alpha 与 RGB 夹取(#351)。
- 修复菜单栏「重新应用皮肤」与「打开 ChatGPT」入口语义不一致的问题(#341):重新应用现在会先尝试热重载,失败才回退到完整重启;打开 ChatGPT 复用已安装的 Dream Skin 启动脚本而不是直接原生拉起。
- 渲染器可见性校验加固(#294):从仅检查宽高与 `display` 改为同时校验 `checkVisibility()`、`opacity`、`content-visibility` 与视口相交,减少"校验通过但皮肤实际不可见"的假阳性。已核实社区主题的 Safe CSS 沙盒不允许 `opacity` 低于 0.65、且不开放 `display`/`visibility`/`position`,不会被这次加固误伤。
Expand Down
26 changes: 13 additions & 13 deletions macos/assets/dream-skin.css
Original file line number Diff line number Diff line change
Expand Up @@ -428,7 +428,7 @@ html[data-dream-skin="active"]:is([data-dream-task-mode="ambient"], [data-dream-
}

html[data-dream-skin="active"]:is([data-dream-task-mode="ambient"], [data-dream-art-task-mode="ambient"], [data-dream-task-mode="banner"], [data-dream-art-task-mode="banner"])[data-dream-art-wide="true"]:has(main:is(.main-surface, [data-app-shell-main-surface], [class*="_MainContentSurface_"])):not(:has(main:is(.main-surface, [data-app-shell-main-surface], [class*="_MainContentSurface_"]) [role="main"]))
.composer-surface-chrome {
:is(.composer-surface-chrome, [class*="_ComposerLayoutRoot_"]) {
background: var(--ds-immersive-composer-solid) !important;
border: 0 !important;
box-shadow:
Expand Down Expand Up @@ -890,7 +890,7 @@ html[data-dream-skin="active"] [role="main"]:has([data-testid="home-icon"]) .gro
html[data-dream-skin="active"] [role="main"]:has([data-testid="home-icon"]) .group\/home-suggestions button > span:first-child { justify-content: center !important; }
html[data-dream-skin="active"] [role="main"]:has([data-testid="home-icon"]) .group\/home-suggestions button > span:last-child { align-items: center !important; text-align: center !important; }

html[data-dream-skin="active"] .composer-surface-chrome {
html[data-dream-skin="active"] :is(.composer-surface-chrome, [class*="_ComposerLayoutRoot_"]) {
overflow: visible !important;
border: 1px solid rgb(var(--ds-muted-rgb) / .18) !important;
border-radius: 22px !important;
Expand All @@ -899,7 +899,7 @@ html[data-dream-skin="active"] .composer-surface-chrome {
backdrop-filter: blur(16px) saturate(108%) !important;
}

html[data-dream-skin="active"] .composer-surface-chrome::before { content: none !important; }
html[data-dream-skin="active"] :is(.composer-surface-chrome, [class*="_ComposerLayoutRoot_"])::before { content: none !important; }

/* Newer app shells may no longer expose the selector contract above. The
renderer assigns these parts only from one coherent main/composer/sidebar
Expand Down Expand Up @@ -1082,7 +1082,7 @@ html[data-dream-skin="active"][data-dream-art-wide="true"] main:is(.main-surface
backdrop-filter: blur(8px) saturate(104%) !important;
}

html[data-dream-skin="active"][data-dream-art-wide="true"] .composer-surface-chrome {
html[data-dream-skin="active"][data-dream-art-wide="true"] :is(.composer-surface-chrome, [class*="_ComposerLayoutRoot_"]) {
background: var(--ds-immersive-composer-solid) !important;
border: 0 !important;
box-shadow:
Expand All @@ -1093,7 +1093,7 @@ html[data-dream-skin="active"][data-dream-art-wide="true"] .composer-surface-chr
}

html[data-dream-skin="active"][data-dream-shell="light"][data-dream-art-wide="true"]
.composer-surface-chrome {
:is(.composer-surface-chrome, [class*="_ComposerLayoutRoot_"]) {
box-shadow:
0 10px 28px rgb(var(--ds-bg-rgb) / .14),
inset 0 0 0 1px var(--ds-immersive-line),
Expand All @@ -1102,7 +1102,7 @@ html[data-dream-skin="active"][data-dream-shell="light"][data-dream-art-wide="tr
}

html[data-dream-skin="active"][data-dream-shell="light"]
.composer-surface-chrome p.placeholder::after {
:is(.composer-surface-chrome, [class*="_ComposerLayoutRoot_"]) p.placeholder::after {
color: rgb(var(--ds-muted-rgb) / .78) !important;
opacity: 1 !important;
}
Expand All @@ -1125,7 +1125,7 @@ html[data-dream-skin="active"] [class*="_homeUtilityBar_"] {
}

html[data-dream-skin="active"] [role="main"]:has([data-testid="home-icon"]):has([class*="_homeUtilityBar_"])
.composer-surface-chrome {
:is(.composer-surface-chrome, [class*="_ComposerLayoutRoot_"]) {
border: 0 !important;
border-radius: 0 0 22px 22px !important;
box-shadow:
Expand All @@ -1145,7 +1145,7 @@ html[data-dream-skin="active"][data-dream-art-wide="true"] [class*="_homeUtility
}

html[data-dream-skin="active"][data-dream-art-wide="true"]
[role="main"]:has([data-testid="home-icon"]):has([class*="_homeUtilityBar_"]) .composer-surface-chrome {
[role="main"]:has([data-testid="home-icon"]):has([class*="_homeUtilityBar_"]) :is(.composer-surface-chrome, [class*="_ComposerLayoutRoot_"]) {
box-shadow:
0 10px 30px rgb(var(--ds-bg-rgb) / .20),
inset 1px 0 var(--ds-immersive-line),
Expand All @@ -1163,27 +1163,27 @@ html[data-dream-skin="active"][data-dream-shell="light"][data-dream-art-wide="tr
}

html[data-dream-skin="active"] [class*="_homeUtilityBar_"] button,
html[data-dream-skin="active"] .composer-surface-chrome button:not([class~="bg-token-foreground"]) {
html[data-dream-skin="active"] :is(.composer-surface-chrome, [class*="_ComposerLayoutRoot_"]) button:not([class~="bg-token-foreground"]) {
color: var(--ds-muted) !important;
}

html[data-dream-skin="active"] [class*="_homeUtilityBar_"] button svg,
html[data-dream-skin="active"] .composer-surface-chrome button svg {
html[data-dream-skin="active"] :is(.composer-surface-chrome, [class*="_ComposerLayoutRoot_"]) button svg {
color: currentColor !important;
}

html[data-dream-skin="active"] [class*="_homeUtilityBar_"] button *,
html[data-dream-skin="active"] .composer-surface-chrome button:not([class~="bg-token-foreground"]) * {
html[data-dream-skin="active"] :is(.composer-surface-chrome, [class*="_ComposerLayoutRoot_"]) button:not([class~="bg-token-foreground"]) * {
color: currentColor !important;
}

html[data-dream-skin="active"] [class*="_homeUtilityBar_"] button:hover,
html[data-dream-skin="active"] .composer-surface-chrome button:not([class~="bg-token-foreground"]):hover {
html[data-dream-skin="active"] :is(.composer-surface-chrome, [class*="_ComposerLayoutRoot_"]) button:not([class~="bg-token-foreground"]):hover {
color: var(--ds-text) !important;
background: rgb(var(--ds-accent-rgb) / .10) !important;
}

html[data-dream-skin="active"] .composer-surface-chrome p.placeholder::after {
html[data-dream-skin="active"] :is(.composer-surface-chrome, [class*="_ComposerLayoutRoot_"]) p.placeholder::after {
color: rgb(var(--ds-muted-rgb) / .82) !important;
opacity: 1 !important;
}
Expand Down
17 changes: 16 additions & 1 deletion macos/assets/renderer-inject.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Canonical cross-platform renderer. Run tools/sync-runtime-assets.mjs after editing.
((cssText, artDataUrl, themeConfig) => {
const SELECTOR_CONTRACT = {"schema":"codex-dream-skin-selectors/1","selectors":[{"key":"shell-main","selector":"main:is(.main-surface, [data-app-shell-main-surface], [class*=\"_MainContentSurface_\"])","tier":"L1","scope":"all","required":true},{"key":"left-panel","selector":"aside.app-shell-left-panel","tier":"L1","scope":"all","required":true},{"key":"header-tint","selector":"header:is(.app-header-tint, [data-app-shell-header-edge-scroll], [class*=\"_Header_\"])","tier":"L1","scope":"all","required":true},{"key":"main-content-top-fade","selector":":is(.app-shell-main-content-top-fade, [data-app-shell-main-content-top-fade], [class*=\"_MainContentTopFade_\"])","tier":"L2","scope":"all","required":false},{"key":"home-icon","selector":"[data-testid=\"home-icon\"]","tier":"L1","scope":"home","required":true},{"key":"home-route","selector":"[role=\"main\"]:has([data-testid=\"home-icon\"])","tier":"L1","scope":"home","required":true},{"key":"home-route-css","selector":"[role=\"main\"]","tier":"L1","scope":"home","required":true},{"key":"home-banners","selector":".home-banners","tier":"L2","scope":"home","required":false},{"key":"composer-chrome","selector":".composer-surface-chrome","tier":"L2","scope":"home+thread","required":false},{"key":"composer-toolbar","selector":".composer-surface-chrome [class*=\"_footer_\"]","tier":"L2","scope":"home+thread","required":false},{"key":"home-utility","selector":"[class*=\"_homeUtilityBar_\"]","tier":"L2","scope":"home","required":false},{"key":"game-source","selector":"[data-feature=\"game-source\"]","tier":"L2","scope":"home","required":false},{"key":"home-suggestions","selector":".group\\/home-suggestions","tier":"L2","scope":"home","required":false},{"key":"project-selector","selector":".group\\/project-selector","tier":"L2","scope":"home config","required":false},{"key":"markdown","selector":"[class*=\"_markdown\"]","tier":"L2","scope":"thread","required":false},{"key":"thread-surface","selector":".thread-scroll-container","tier":"L2","scope":"thread","required":false},{"key":"message","selector":":is([data-message-author-role], [data-local-conversation-user-anchor], [data-local-conversation-final-assistant])","tier":"L2","scope":"thread","required":false},{"key":"settings-panel","selector":"[data-settings-panel-slug=\"general-settings\"]","tier":"L2","scope":"settings","required":false},{"key":"appearance-radio","selector":"input[name=\"appearance-theme\"]","tier":"L2","scope":"settings","required":false},{"key":"overlay-menu","selector":"[role=\"menu\"]","tier":"L2","scope":"overlay","required":false},{"key":"overlay-dialog","selector":"[role=\"dialog\"]","tier":"L2","scope":"overlay","required":false},{"key":"overlay-popper","selector":"[data-radix-popper-content-wrapper]","tier":"L2","scope":"overlay","required":false}],"stableTestids":["app-shell-header-context-menu-surface","home-icon","theme-preview"]};
const SELECTOR_CONTRACT = {"schema":"codex-dream-skin-selectors/1","selectors":[{"key":"shell-main","selector":"main:is(.main-surface, [data-app-shell-main-surface], [class*=\"_MainContentSurface_\"])","tier":"L1","scope":"all","required":true},{"key":"left-panel","selector":"aside.app-shell-left-panel","tier":"L1","scope":"all","required":true},{"key":"header-tint","selector":"header:is(.app-header-tint, [data-app-shell-header-edge-scroll], [class*=\"_Header_\"])","tier":"L1","scope":"all","required":true},{"key":"main-content-top-fade","selector":":is(.app-shell-main-content-top-fade, [data-app-shell-main-content-top-fade], [class*=\"_MainContentTopFade_\"])","tier":"L2","scope":"all","required":false},{"key":"home-icon","selector":"[data-testid=\"home-icon\"]","tier":"L1","scope":"home","required":true},{"key":"home-route","selector":"[role=\"main\"]:has([data-testid=\"home-icon\"])","tier":"L1","scope":"home","required":true},{"key":"home-route-css","selector":"[role=\"main\"]","tier":"L1","scope":"home","required":true},{"key":"home-banners","selector":".home-banners","tier":"L2","scope":"home","required":false},{"key":"composer-chrome","selector":":is(.composer-surface-chrome, [class*=\"_ComposerLayoutRoot_\"])","tier":"L2","scope":"home+thread","required":false},{"key":"composer-toolbar","selector":":is(.composer-surface-chrome [class*=\"_footer_\"], [class*=\"_ComposerLayoutRoot_\"] [class*=\"_ComposerLayoutFooter_\"])","tier":"L2","scope":"home+thread","required":false},{"key":"home-utility","selector":"[class*=\"_homeUtilityBar_\"]","tier":"L2","scope":"home","required":false},{"key":"game-source","selector":"[data-feature=\"game-source\"]","tier":"L2","scope":"home","required":false},{"key":"home-suggestions","selector":".group\\/home-suggestions","tier":"L2","scope":"home","required":false},{"key":"project-selector","selector":".group\\/project-selector","tier":"L2","scope":"home config","required":false},{"key":"markdown","selector":"[class*=\"_markdown\"]","tier":"L2","scope":"thread","required":false},{"key":"thread-surface","selector":".thread-scroll-container","tier":"L2","scope":"thread","required":false},{"key":"message","selector":":is([data-message-author-role], [data-local-conversation-user-anchor], [data-local-conversation-final-assistant])","tier":"L2","scope":"thread","required":false},{"key":"settings-panel","selector":"[data-settings-panel-slug=\"general-settings\"]","tier":"L2","scope":"settings","required":false},{"key":"appearance-radio","selector":"input[name=\"appearance-theme\"]","tier":"L2","scope":"settings","required":false},{"key":"overlay-menu","selector":"[role=\"menu\"]","tier":"L2","scope":"overlay","required":false},{"key":"overlay-dialog","selector":"[role=\"dialog\"]","tier":"L2","scope":"overlay","required":false},{"key":"overlay-popper","selector":"[data-radix-popper-content-wrapper]","tier":"L2","scope":"overlay","required":false}],"stableTestids":["app-shell-header-context-menu-surface","home-icon","theme-preview"]};
const STATE_KEY = "__CODEX_DREAM_SKIN_STATE__";
const DISABLED_KEY = "__CODEX_DREAM_SKIN_DISABLED__";
const STYLE_REGISTRY_KEY = "__CODEX_DREAM_SKIN_STYLE_SHEETS__";
Expand All @@ -13,6 +13,19 @@
"data-dream-art-safe-area", "data-dream-art-task-mode", "data-dream-art-aspect",
"data-dream-art-ready",
];
const initialRoute = new URLSearchParams(String(location.search || ""))
.get("initialRoute") || "";
const pathname = String(location.pathname || "");
const excludedPetSurface = location.protocol === "app:" && (
pathname.endsWith("/avatar-overlay-composition-surface.html") ||
initialRoute === "/avatar-overlay" || initialRoute.startsWith("/avatar-overlay/")
);
if (excludedPetSurface) {
const previous = window[STATE_KEY];
if (typeof previous?.cleanup === "function") previous.cleanup();
window[DISABLED_KEY] = true;
return;
}
const VERSION = __DREAM_SKIN_VERSION_JSON__;
const STYLE_REVISION = __DREAM_SKIN_STYLE_REVISION_JSON__;
const PAYLOAD_REVISION = __DREAM_SKIN_PAYLOAD_REVISION_JSON__;
Expand Down Expand Up @@ -670,6 +683,8 @@
const main = resolvedMainNode();
for (const input of genericInputNodes()) {
if (main && !main.contains?.(input)) continue;
const layoutRoot = input.closest?.('[class*="_ComposerLayoutRoot_"]');
if (layoutRoot && (!main || main.contains?.(layoutRoot))) return [layoutRoot];
const owner = input.closest?.(
'[data-testid*="composer" i], [data-testid*="prompt" i], ' +
'[class*="composer" i], [class*="prompt" i]',
Expand Down
Loading