Skip to content

Commit 598dd07

Browse files
committed
fix: harden cross-platform community themes
1 parent 98e308a commit 598dd07

30 files changed

Lines changed: 1356 additions & 147 deletions

TASK_PROGRESS.md

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,93 @@
11
# Task Progress
22

3+
## Windows Codex 26.727.4816 final worktree acceptance (2026-07-31)
4+
5+
- [verified] The official Store package is `OpenAI.Codex_26.727.4816.0`; the
6+
installed DreamSkin engine was replaced from this exact worktree under
7+
`RemoteSigned`, and its CSS, renderer, selector, validator, and importer
8+
hashes match the repository copies.
9+
- [verified] A real `dreamskin://apply` transaction downloaded and applied
10+
Lyn-in's complete `juzizhoutou` package through the native confirmation UI.
11+
The result confirmed size/SHA-256, ZIP, manifest, and Safe CSS validation.
12+
- [verified] Three current complete community themes from different creators
13+
(`juzizhoutou`, `taishan-wuyue-duzun`, and `cecilylove002`) render in the real
14+
Codex Home/task UI. Home reports `L1` with `missingL1=[]`; task navigation
15+
refreshes to `thread/L1`; sidebar, header, message region, composer, toolbar,
16+
background, and controls remain visible and interactive with no overflow.
17+
- [fixed] Real rendering exposed two final shared-runtime gaps. A root Safe CSS
18+
background color now also clears the body's canonical image, and Codex
19+
26.727's user/assistant conversation anchors now map to the public `message`
20+
part while retaining the legacy selector. Real task inspection found 8/8
21+
message anchors inside the thread and zero sidebar matches.
22+
- [verified] Final real screenshots are under
23+
`%TEMP%\dreamskin-pr324-final-live`. Focused 34/34 Node regressions, selector
24+
doctor, renderer runtime, asset sync, PowerShell 5.1/7 parsing, installer
25+
static checks, and `git diff --check` pass. Full dual-PowerShell CI remains
26+
the post-push gate; no merge, Release, or Issue mutation is authorized.
27+
28+
## Windows continuation after macOS 26.727 fix — in progress (2026-07-31)
29+
30+
- [verified] Draft PR #324 and the local branch are both at `98e308a`; the
31+
macOS follow-up commits `9098060`/`98e308a` are present. The shared selector
32+
change keeps the legacy anchors and adds Codex 26.727 app-shell attributes,
33+
so its compatibility direction is appropriate for Windows as well. Real
34+
Windows 26.727 acceptance is still pending.
35+
- [verified] On real Windows Codex `26.721.11231.0`, the updated selector
36+
contract still reaches Home at `L1` with `missingL1=[]`. The new CSS parses
37+
in the Windows Chromium 150 renderer, and shared macOS/Windows selector,
38+
renderer, and CSS assets are byte-identical.
39+
- [reproduced] Full community-theme Safe CSS loads but loses the cascade for
40+
sidebar, header, composer, home typography, and toolbar colors because the
41+
canonical runtime uses `!important` while the untrusted Safe CSS contract
42+
correctly rejects author-supplied `!important`. Root font-family is one of
43+
the few declarations that currently wins.
44+
- [in progress] Keep the Safe CSS input contract unchanged, compile only the
45+
already-validated declarations to a controlled runtime priority, synchronize
46+
both platform assets, and add cascade regressions. Also tighten generic
47+
composer/Home verification false positives before reinstalling the exact
48+
worktree engine and repeating real Windows community-theme checks.
49+
- [fixed] The shared parser now recompiles only validated part/property/value
50+
rules into the `dreamskin-community` cascade layer with client-owned
51+
priority. Author CSS still rejects `!important`; original bytes remain the
52+
semantic/fingerprint input. A higher-priority accessibility layer preserves
53+
`prefers-reduced-motion` behavior.
54+
- [fixed] Generic composer fallback now requires an explicit composer/prompt
55+
semantic owner and never marks a plain form or bare textbox. Home verification
56+
fails when runtime scope claims Home but the real Home identity/surface is
57+
absent; thread/settings routes retain their existing acceptance boundaries.
58+
- [verified] Shared runtime sync, renderer fixture, Windows readiness 10/10,
59+
Safe CSS 9/9, and macOS/Windows payload tests 12/12 pass. macOS and Windows
60+
generated CSS, renderer, and validator assets remain synchronized.
61+
- [in progress] Run the complete Node and Windows PowerShell 5.1/7 suites,
62+
including the preserved same-ID, reserved-ID, long-path, legacy-suffix, and
63+
rollback import cases. Then deploy the exact worktree engine and repeat real
64+
Windows Codex computed-style and community-theme interaction checks.
65+
- [preserved] Existing uncommitted cross-platform importer changes remain in
66+
the four macOS/Windows import implementation/test files. They are not being
67+
reverted or overwritten. No merge, Release, Issue edit, or publish is in
68+
scope until explicit authorization.
69+
- [fixed] A theme whose destination passed the final semantic fingerprint is
70+
now treated as committed on both platforms even when obsolete backup cleanup
71+
fails. The import returns `cleanupWarning`/`CleanupWarning`; manual import and
72+
one-click apply show a bounded local warning without exposing the raw path or
73+
rolling back the new theme.
74+
- [fixed] Invalid or Windows-reserved source IDs use one cross-platform stable
75+
identity mapping. The fixed `con.theme` vector is
76+
`import-931599c2985393be807cf0ed` on macOS and Windows, so a later package with
77+
the same source ID updates in place instead of creating another directory.
78+
- [verified] Windows PowerShell 5.1 completed the full focused ZIP-import suite,
79+
including same-ID replacement, exact duplicate, conservative legacy cleanup,
80+
unrelated suffix preservation, file collision, pre-commit rollback,
81+
committed cleanup warning and long-path cases. Focused macOS publisher,
82+
community-link, Safe CSS, dual payload, renderer-runtime, readiness and asset
83+
sync checks pass; the macOS immutable-backup cleanup case remains a macOS CI
84+
execution because this worktree is on Windows.
85+
- [fixed] The trusted Safe CSS compiler now clears a core background image when
86+
a validated part supplies `background-color`, bridges bounded root typography
87+
and color to `body`, passes composer-toolbar color to its registered buttons,
88+
and marks the real `game-source` node as `home-hero` when present. SPA DOM
89+
mutations refresh both public parts and verification scope.
90+
391
## Codex 26.727 real-renderer visual follow-up — in progress (2026-07-31)
492

593
- [verified] Official Codex/ChatGPT `26.727.40816` is running with this Draft
@@ -461,3 +549,19 @@ Updated: 2026-07-31 14:29 HKT (Asia/Hong_Kong)
461549
approved `applyCompatible: true` package. Existing approved legacy
462550
production packages are intentionally preview/download-only.
463551
- Real Windows PowerShell 5.1 and Setup.exe protocol install require Windows CI/host verification.
552+
## Codex 26.727.4816 Message Bridge (2026-07-31)
553+
554+
- [complete] Read-only inspection of the real Windows Codex 26.727.4816 task
555+
renderer found zero `[data-message-author-role]` nodes. The current semantic
556+
boundaries are four `[data-local-conversation-user-anchor]` nodes and four
557+
`[data-local-conversation-final-assistant]` nodes; all eight are inside the
558+
thread surface and none is in the sidebar.
559+
- [complete] The shared selector contract now retains the legacy message role
560+
attribute and adds those two current semantic attributes. Core styling uses
561+
the existing public `data-ds-part="message"` bridge, and generated macOS and
562+
Windows selector/renderer/CSS assets are synchronized.
563+
- [verified] Selector doctor, both renderer runtime suites, both payload
564+
integrity suites, runtime asset sync, JavaScript syntax, focused
565+
`git diff --check`, and a second real-DOM read-only cardinality check pass.
566+
No installed runtime, Codex process, active theme, PR, issue, commit, or push
567+
was changed by this focused task.

macos/assets/dream-skin.css

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
/* Canonical cross-platform skin. Run tools/sync-runtime-assets.mjs after editing. */
2+
@layer dreamskin-accessibility, dreamskin-community;
3+
24
:root[data-dream-skin="active"] {
35
color-scheme: dark !important;
46
--ds-bg: #111318;
@@ -1275,7 +1277,7 @@ html[data-dream-skin="active"] button[class~="bg-token-foreground"] {
12751277
}
12761278

12771279
html[data-dream-skin="active"] article,
1278-
html[data-dream-skin="active"] [data-message-author-role] { border-radius: 16px; }
1280+
html[data-dream-skin="active"] [data-ds-part="message"] { border-radius: 16px; }
12791281

12801282
@media (max-width: 1120px) {
12811283
html[data-dream-skin="active"]
@@ -1303,13 +1305,15 @@ html[data-dream-skin="active"] [data-message-author-role] { border-radius: 16px;
13031305
html[data-dream-skin="active"] [role="main"]:has([data-testid="home-icon"]) .group\/home-suggestions button { min-height: 112px !important; font-size: 12px !important; }
13041306
}
13051307

1306-
@media (prefers-reduced-motion: reduce) {
1307-
html[data-dream-skin="active"] *,
1308-
html[data-dream-skin="active"] *::before,
1309-
html[data-dream-skin="active"] *::after {
1310-
scroll-behavior: auto !important;
1311-
transition-duration: .01ms !important;
1312-
animation-duration: .01ms !important;
1313-
animation-iteration-count: 1 !important;
1308+
@layer dreamskin-accessibility {
1309+
@media (prefers-reduced-motion: reduce) {
1310+
html[data-dream-skin="active"] *,
1311+
html[data-dream-skin="active"] *::before,
1312+
html[data-dream-skin="active"] *::after {
1313+
scroll-behavior: auto !important;
1314+
transition-duration: .01ms !important;
1315+
animation-duration: .01ms !important;
1316+
animation-iteration-count: 1 !important;
1317+
}
13141318
}
13151319
}

macos/assets/renderer-inject.js

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// Canonical cross-platform renderer. Run tools/sync-runtime-assets.mjs after editing.
22
((cssText, artDataUrl, themeConfig) => {
3-
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":"[data-message-author-role]","tier":"L2","scope":"thread","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"]};
3+
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":"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"]};
44
const STATE_KEY = "__CODEX_DREAM_SKIN_STATE__";
55
const DISABLED_KEY = "__CODEX_DREAM_SKIN_DISABLED__";
66
const STYLE_REGISTRY_KEY = "__CODEX_DREAM_SKIN_STYLE_SHEETS__";
@@ -610,9 +610,10 @@
610610
const input = genericInputNodes().find((node) => !main || main.contains?.(node));
611611
if (!input) return [];
612612
const owner = input.closest?.(
613-
'form, [data-testid*="composer" i], [class*="composer" i], [class*="prompt" i]',
613+
'[data-testid*="composer" i], [data-testid*="prompt" i], ' +
614+
'[class*="composer" i], [class*="prompt" i]',
614615
);
615-
return [owner && (!main || main.contains?.(owner)) ? owner : input];
616+
return owner && (!main || main.contains?.(owner)) ? [owner] : [];
616617
})();
617618
const addPart = (desired, part, nodes) => {
618619
for (const node of nodes) {
@@ -637,7 +638,8 @@
637638
addPart(desired, "composer", [...selectorNodes("composer-chrome"), ...fallbackComposerNodes()]);
638639
addPart(desired, "composer-toolbar", selectorNodes("composer-toolbar"));
639640
addPart(desired, "dialog", selectorNodes("overlay-dialog"));
640-
const homeHero = selectorNodes("home-icon")[0]?.parentElement;
641+
const homeHero = selectorNodes("game-source")[0] ??
642+
selectorNodes("home-icon")[0]?.parentElement;
641643
addPart(desired, "home-hero", homeHero ? [homeHero] : []);
642644

643645
for (const node of partNodes) {
@@ -775,7 +777,10 @@
775777
};
776778
if (typeof MutationObserver === "function") {
777779
rootObserver = new MutationObserver(() => scheduleEnsure({ root: true }));
778-
partObserver = new MutationObserver(() => scheduleEnsure({ parts: true }, 80));
780+
// SPA route changes are observable as DOM mutations even when Chromium's
781+
// Navigation API emits no event. Keep verification scope and public parts
782+
// derived from the same post-mutation tree.
783+
partObserver = new MutationObserver(() => scheduleEnsure({ scope: true, parts: true }, 80));
779784
}
780785

781786
let mediaQuery = null;
@@ -845,7 +850,7 @@
845850
bodyReadyHandler = () => {
846851
if (!window[DISABLED_KEY]) {
847852
observeBody();
848-
scheduleEnsure({ parts: true }, 0);
853+
scheduleEnsure({ scope: true, parts: true }, 0);
849854
}
850855
};
851856
document.addEventListener("DOMContentLoaded", bodyReadyHandler, { once: true });

0 commit comments

Comments
 (0)