Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
5 changes: 5 additions & 0 deletions apps/codex-plus-launcher/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ repository.workspace = true
name = "codex-plus-plus"
path = "src/main.rs"

# Keep the pre-1.2.43 launcher name available for older manager builds and shortcuts.
[[bin]]
name = "codex-plus"
path = "src/main.rs"

[dependencies]
anyhow.workspace = true
async-trait = "0.1"
Expand Down
43 changes: 22 additions & 21 deletions apps/codex-plus-manager/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2564,8 +2564,8 @@ export function App() {
if (!current) return current;
if (isWindowsPlatform) {
const config = { ...current.config };
delete config.colors;
delete config.palette;
config.colors = defaultDreamSkinColors();
return { ...current, config };
}
const defaults = defaultDreamSkinTheme();
Expand Down Expand Up @@ -3630,15 +3630,6 @@ function DreamSkinScreen({
const themeAppearance = theme.appearance === "light" || theme.appearance === "dark"
? theme.appearance
: "auto";
const windowsAccent = typeof theme.palette?.accent === "string" ? theme.palette.accent : "";
const updateWindowsAccent = (value: string) => {
const palette = { ...(theme.palette ?? {}) };
if (value.trim()) palette.accent = value;
else delete palette.accent;
const next: DreamSkinThemeConfig = { ...theme, palette };
if (!Object.keys(palette).length) delete next.palette;
updateTheme(next);
};
const companion = theme.companion;
const companionDataUrl = typeof companion?.dataUrl === "string" ? companion.dataUrl : "";
const companionEnabled = Boolean(companionDataUrl) && companion?.enabled !== false;
Expand Down Expand Up @@ -3946,7 +3937,7 @@ function DreamSkinScreen({
<Info className="h-4 w-4" />
<span>
{isWindowsPlatform
? t("Windows 使用亮暗模式、图片取色和可选强调色;完整色板仅在 macOS 生效。")
? t("Windows 现在会读取主题中的完整 colors 色板;清除色板后将恢复从图片自适应配色。")
: t("macOS 会应用主题中的图片、文字和颜色配置。")}
</span>
</div>
Expand Down Expand Up @@ -4108,24 +4099,34 @@ function DreamSkinScreen({
))}
</div>
</Field>
<div className="dream-skin-windows-accent">
<DreamSkinColorField
label={t("强调色")}
value={windowsAccent}
onChange={updateWindowsAccent}
/>
<div className="dream-skin-colors">
{dreamSkinColorFields().map(([key, label]) => (
<DreamSkinColorField
key={key}
label={label}
value={String(themeColors[key])}
onChange={(value) => updateThemeColor(key, value)}
/>
))}
</div>
<Toolbar>
<Button
disabled={!windowsAccent.trim()}
onClick={() => updateWindowsAccent("")}
disabled={!theme.colors}
onClick={() => {
const next = { ...theme };
delete next.colors;
delete next.palette;
updateTheme(next);
}}
size="sm"
variant="outline"
>
<RotateCcw className="h-4 w-4" />
{t("跟随图片配色")}
</Button>
</div>
</Toolbar>
<small className="dream-skin-windows-theme-note">
{t("亮暗模式直接控制 Codex 外观;强调色留空时自动从主题图片提取。")}
{t("Windows 现在会读取主题中的完整 colors 色板;清除色板后将恢复从图片自适应配色。")}
</small>
</div>
) : (
Expand Down
38 changes: 23 additions & 15 deletions apps/codex-plus-manager/src/dream-skin.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ describe("dream skin theme helpers", () => {
assert.match(assets, /__GLASS_VISION_CSS_JSON__/);
assert.match(renderer, /__CODEX_PLUS_EXTERNAL_DREAM_SKIN_RUNTIME__/);
assert.match(renderer, /__CODEX_PLUS_CLEAR_DREAM_SKIN__/);
assert.match(renderer, /data-codex-plus-dream-skin-main-compat/);
assert.match(renderer, /classList\.add\("main-surface"\)/);
});

it("preserves target-only theme fields without rewriting them", () => {
Expand Down Expand Up @@ -116,17 +118,20 @@ describe("dream skin theme helpers", () => {
assert.match(app, /Math\.max\(-160, Math\.min\(160, Number\(event\.currentTarget\.value\) \|\| 0\)\)/);
});

it("keeps the Windows skin active when the sidebar is hidden", async () => {
it("keeps the modern Dream Skin runtime active when the sidebar is hidden", async () => {
const renderer = await readFile(
new URL("../../../assets/inject/upstream/dream-skin/windows/renderer-inject.js", import.meta.url),
"utf8",
);

assert.match(renderer, /const shellMain = document\.querySelector\("main\.main-surface"\)/);
assert.match(renderer, /main\.main-surface/);
assert.match(renderer, /data-dream-skin/);
assert.match(renderer, /data-dream-shell/);
assert.match(renderer, /ensure\(\{ root: true/);
assert.doesNotMatch(renderer, /!shellMain\s*\|\|\s*!shellSidebar/);
});

it("extends the Windows wallpaper treatment to right and bottom dock panels", async () => {
it("uses the stable selector contract for the full Codex shell", async () => {
const renderer = await readFile(
new URL("../../../assets/inject/upstream/dream-skin/windows/renderer-inject.js", import.meta.url),
"utf8",
Expand All @@ -136,15 +141,18 @@ describe("dream skin theme helpers", () => {
"utf8",
);

assert.match(renderer, /\[data-app-shell-tabs="true"\]/);
assert.match(renderer, /dream-aux-panel-layer/);
assert.match(renderer, /dream-aux-panel-right/);
assert.match(renderer, /dream-aux-panel-bottom/);
assert.match(renderer, /clearAuxiliaryPanelClasses/);
assert.match(css, /\.dream-aux-panel-layer/);
assert.match(css, /\.dream-aux-panel-right/);
assert.match(css, /\.dream-aux-panel-bottom/);
assert.match(css, /\[data-codex-terminal="true"\]/);
assert.match(renderer, /codex-dream-skin-selectors\/1/);
assert.match(renderer, /app-shell-left-panel/);
assert.match(renderer, /home-route/);
assert.match(renderer, /adoptedStyleSheets/);
assert.match(renderer, /MutationObserver/);
assert.match(renderer, /data-codex-plus-dream-skin-main-compat/);
assert.match(renderer, /ensureShellMainCompatibility/);
assert.match(css, /html\[data-dream-skin="active"\]/);
assert.match(css, /main\.main-surface/);
assert.match(css, /_MainContentTopFade_/);
assert.match(css, /aside\.app-shell-left-panel/);
assert.match(css, /\.composer-surface-chrome/);
});

it("exposes companion image controls in the theme editor", async () => {
Expand Down Expand Up @@ -256,7 +264,7 @@ describe("dream skin theme helpers", () => {
const css = await readFile(new URL("./styles.css", import.meta.url), "utf8");

assert.match(app, /dream-skin-theme-library/);
assert.match(app, /Windows 使用亮暗模式、图片取色和可选强调色/);
assert.match(app, /Windows 现在会读取主题中的完整 colors 色板/);
assert.match(css, /\.dream-skin-market-grid\s*\{[^}]*grid-template-columns:\s*repeat\(3,/s);
assert.match(css, /\.dream-skin-theme-list\s*\{[^}]*grid-template-columns:\s*repeat\(3,/s);
assert.match(css, /@media \(max-width:\s*760px\)[\s\S]*\.dream-skin-theme-list\s*\{[^}]*grid-template-columns:\s*1fr/s);
Expand Down Expand Up @@ -286,7 +294,7 @@ describe("dream skin theme helpers", () => {
assert.match(customizer, /t\("恢复 Codex 默认配色"\)/);
});

it("exposes only effective Windows appearance and accent controls", async () => {
it("exposes Windows appearance and complete color controls", async () => {
const app = await readFile(new URL("./App.tsx", import.meta.url), "utf8");

assert.match(app, /dream-skin-windows-theme-controls/);
Expand All @@ -295,7 +303,7 @@ describe("dream skin theme helpers", () => {
assert.match(app, /暗色/);
assert.match(app, /跟随图片配色/);
assert.match(app, /isWindowsPlatform \? \([\s\S]*dream-skin-windows-theme-controls[\s\S]*dream-skin-colors/);
assert.match(app, /if \(isWindowsPlatform\) \{[\s\S]*delete config\.colors;[\s\S]*delete config\.palette;/);
assert.doesNotMatch(app, /if \(isWindowsPlatform\) \{[\s\S]*delete config\.colors;/);
});

it("separates the remote marketplace from local theme editing", async () => {
Expand Down
1 change: 1 addition & 0 deletions apps/codex-plus-manager/src/dream-skin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ export function defaultDreamSkinTheme(): DreamSkinThemeConfig {
projectLabel: "◉ 选择项目",
statusText: "DREAM SKIN ONLINE",
quote: "MAKE SOMETHING WONDERFUL",
colors: defaultDreamSkinColors(),
image: "dream-reference.jpg",
appearance: "auto",
art: {
Expand Down
6 changes: 2 additions & 4 deletions apps/codex-plus-manager/src/i18n-en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,6 @@ export const EN_PLAIN: Record<string, string> = {
"亮色": "Light",
"暗色": "Dark",
"跟随图片配色": "Use image colors",
"亮暗模式直接控制 Codex 外观;强调色留空时自动从主题图片提取。":
"The appearance mode directly controls Codex. Leave the accent empty to derive it from the theme image.",
"主题市场": "Theme marketplace",
"主题视图": "Theme view",
"社区主题": "Community themes",
Expand Down Expand Up @@ -115,8 +113,8 @@ export const EN_PLAIN: Record<string, string> = {
"主题操作": "Theme actions",
"重命名": "Rename",
"正在加载主题库…": "Loading theme library...",
"Windows 使用亮暗模式、图片取色和可选强调色;完整色板仅在 macOS 生效。":
"Windows uses appearance mode, image-derived colors, and an optional accent; the full palette applies only on macOS.",
"Windows 现在会读取主题中的完整 colors 色板;清除色板后将恢复从图片自适应配色。":
"Windows uses the theme image, appearance mode, and complete colors palette.",
"macOS 会应用主题中的图片、文字和颜色配置。":
"macOS applies the image, text, and color settings from the theme.",
"Dream Skin 图片预览": "Dream Skin image preview",
Expand Down
15 changes: 1 addition & 14 deletions apps/codex-plus-manager/src/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -5245,8 +5245,7 @@ select {
padding-top: 2px;
}

.dream-skin-windows-theme-controls > .field,
.dream-skin-windows-accent .field {
.dream-skin-windows-theme-controls > .field {
min-width: 0;
margin: 0;
}
Expand All @@ -5255,17 +5254,6 @@ select {
grid-template-columns: repeat(3, minmax(0, 1fr));
}

.dream-skin-windows-accent {
display: grid;
grid-template-columns: minmax(0, 1fr) auto;
gap: 10px;
align-items: end;
}

.dream-skin-windows-accent > button {
min-height: 36px;
}

.dream-skin-windows-theme-note {
color: hsl(var(--muted-foreground));
font-size: 12px;
Expand Down Expand Up @@ -5456,7 +5444,6 @@ select {

.dream-skin-text-grid,
.dream-skin-colors,
.dream-skin-windows-accent,
.dream-skin-companion-fields,
.dream-skin-diagnostics-grid,
.dream-skin-verification-meta {
Expand Down
10 changes: 10 additions & 0 deletions assets/inject/renderer-inject.js
Original file line number Diff line number Diff line change
Expand Up @@ -1770,6 +1770,10 @@
document.querySelectorAll(".dream-home-shell").forEach((node) => node.classList.remove("dream-home-shell"));
document.querySelectorAll(".dream-skin-home").forEach((node) => node.classList.remove("dream-skin-home"));
document.querySelectorAll(".dream-skin-home-shell").forEach((node) => node.classList.remove("dream-skin-home-shell"));
document.querySelectorAll('main[data-codex-plus-dream-skin-main-compat="true"]').forEach((node) => {
node.classList.remove("main-surface");
node.removeAttribute("data-codex-plus-dream-skin-main-compat");
});
document.querySelectorAll("[class]").forEach((node) => {
for (const className of [...node.classList]) {
if (
Expand Down Expand Up @@ -1933,6 +1937,12 @@
clearDreamSkinPresentation();
return;
}
// Codex 26.727 moved the shell's stable class behind CSS Modules. Keep
// the DreamSkin selector contract working without changing Codex's DOM.
if (!shellMain.classList.contains("main-surface")) {
shellMain.classList.add("main-surface");
shellMain.setAttribute("data-codex-plus-dream-skin-main-compat", "true");
}

root.classList.add(descriptor.rootClass);
root.setAttribute("data-codex-plus-dream-skin", "true");
Expand Down
Loading