Skip to content
Merged
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
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# Changelog

## 0.1.1 — 2026-08-16

- Restored themed composer glass on Codex 26.803 by clearing its new opaque
semantic layout layer while preserving native controls.
- Removed the new Home top spacer that could appear as a dark horizontal band
above the themed hero.
- Added live verification gates for native composer backgrounds and modern Home
top alignment on both New Chat and active task routes.

## 0.1.0 — 2026-08-11

- Added a native, offline macOS App for applying and restoring Codex
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.1.0
0.1.1
9 changes: 8 additions & 1 deletion engine/assets/ai-themestore.css
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,13 @@ html.ai-themestore .ai-themestore-composer-surface {
overflow: visible !important;
}

/* Codex 26.803 can paint an opaque layout body inside the semantic composer
surface. Keep the native controls live while letting the themed glass show. */
html.ai-themestore .ai-themestore-composer-surface > [data-composer-layout] {
background-color: transparent !important;
background-image: none !important;
}

html.ai-themestore main.main-surface:not(.ai-themestore-home-shell)
.sticky.bottom-0
> .pointer-events-none.absolute.inset-x-0.bottom-0
Expand Down Expand Up @@ -1219,7 +1226,7 @@ html.ai-themestore .ai-themestore-home-v2 > .ai-themestore-home-banner-slot > :f
}

html.ai-themestore .ai-themestore-home-v2 > .ai-themestore-home-layout {
padding-top: 15px !important;
padding-top: 0 !important;
min-height: 100% !important;
}

Expand Down
9 changes: 9 additions & 0 deletions engine/scripts/codex-shell-probe.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,15 @@ export function resolveComposerSurfaceDocument(documentRef, scopeRef = documentR
export const COMPOSER_SURFACE_RESOLVER_EXPRESSION =
`(${resolveComposerSurfaceDocument.toString()})(document)`;

export function composerNativeLayerCoveragePass(layers) {
return layers.every((layer) =>
layer.backgroundAlpha <= 0.035 &&
(layer.backgroundImage === "none" || layer.backgroundImage === null));
}

export const COMPOSER_NATIVE_LAYER_COVERAGE_EXPRESSION =
`(${composerNativeLayerCoveragePass.toString()})`;

export function resolveChatPaneDocument(documentRef) {
const marked = documentRef.querySelector("aside.ai-themestore-chat-pane");
if (marked) return marked;
Expand Down
19 changes: 18 additions & 1 deletion engine/scripts/injector.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
CHAT_PANE_DIVIDER_PARITY_EXPRESSION,
CHAT_PANE_RESOLVER_EXPRESSION,
CODEX_SHELL_PROBE_EXPRESSION,
COMPOSER_NATIVE_LAYER_COVERAGE_EXPRESSION,
COMPOSER_SURFACE_RESOLVER_EXPRESSION,
OPTIONAL_SIDEBAR_VISIBILITY_EXPRESSION,
SHELL_MAIN_RESOLVER_EXPRESSION,
Expand Down Expand Up @@ -555,11 +556,25 @@ async function verifySession(session, expected = null) {
const placeholder = editor?.querySelector('.placeholder') ?? null;
const composerSurfaceMetric = (node) => {
const style = node ? getComputedStyle(node) : null;
const nativeLayers = node
? [...node.children]
.filter((child) => child.matches('[data-composer-layout]'))
.map((child) => {
const childStyle = getComputedStyle(child);
return {
backgroundColor: childStyle.backgroundColor,
backgroundAlpha: backgroundAlpha(childStyle.backgroundColor),
backgroundImage: childStyle.backgroundImage,
};
})
: [];
return {
backgroundColor: style?.backgroundColor ?? null,
backgroundAlpha: style ? backgroundAlpha(style.backgroundColor) : null,
backdropFilter: style?.backdropFilter ?? null,
borderRadius: style?.borderRadius ?? null,
nativeLayers,
nativeLayersClear: ${COMPOSER_NATIVE_LAYER_COVERAGE_EXPRESSION}(nativeLayers),
pass: false,
};
};
Expand Down Expand Up @@ -814,7 +829,8 @@ async function verifySession(session, expected = null) {
metric.backgroundAlpha != null &&
Math.abs(metric.backgroundAlpha - expectedComposerAlpha) <= 0.035 &&
metric.backdropFilter?.includes('blur(18px)') &&
metric.borderRadius === '21px'
metric.borderRadius === '21px' &&
metric.nativeLayersClear
);
result.composerSurface.pass = composerSurfacePass(result.composerSurface);
result.chatPaneCoverage.composerSurface.pass = !result.chatPaneCoverage.expected ||
Expand Down Expand Up @@ -957,6 +973,7 @@ async function verifySession(session, expected = null) {
const modernHomeLayoutPass = !result.modernHome || Boolean(
result.homeBox?.visible && result.hero?.visible && result.composer?.visible &&
result.hero.y >= result.homeBox.y - 2 &&
result.hero.y - result.homeBox.y <= 2 &&
result.hero.y + result.hero.height <= result.homeBox.y + result.homeBox.height + 2 &&
result.composer.y >= result.homeBox.y - 2 &&
result.composer.y + result.composer.height <= result.homeBox.y + result.homeBox.height + 2 &&
Expand Down
16 changes: 16 additions & 0 deletions tests/codex-shell-probe.test.mjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import assert from "node:assert/strict";
import {
chatPaneDividerParityPass,
composerNativeLayerCoveragePass,
optionalSidebarVisibilityPass,
probeCodexShellDocument,
resolveChatPaneDocument,
Expand Down Expand Up @@ -206,6 +207,21 @@ const semanticComposerScope = {
assert.equal(resolveComposerSurfaceDocument(semanticComposerScope), semanticComposerSurface,
"Codex 26.730 semantic composer surface must resolve through stable data attributes");

assert.equal(composerNativeLayerCoveragePass([]), true,
"legacy composers without a semantic native body must remain supported");
assert.equal(composerNativeLayerCoveragePass([{
backgroundAlpha: 0,
backgroundImage: "none",
}]), true, "a transparent Codex semantic composer body must preserve theme glass");
assert.equal(composerNativeLayerCoveragePass([{
backgroundAlpha: 0.864706,
backgroundImage: "none",
}]), false, "an opaque Codex semantic composer body must fail verification");
assert.equal(composerNativeLayerCoveragePass([{
backgroundAlpha: 0,
backgroundImage: "linear-gradient(rgb(0, 0, 0), rgb(0, 0, 0))",
}]), false, "a native composer background image must fail verification");

assert.equal(chatPaneDividerParityPass({ chatPanePresent: false }), true,
"absent Ask pane must not require divider verification");
assert.equal(chatPaneDividerParityPass({
Expand Down
15 changes: 15 additions & 0 deletions tests/run-tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,21 @@ for script in "$ROOT"/engine/scripts/*.mjs "$ROOT"/engine/assets/*.js; do
"$NODE" --check "$script" >/dev/null
done

/usr/bin/grep -F -q '.ai-themestore-composer-surface > [data-composer-layout]' \
"$ROOT/engine/assets/ai-themestore.css" || {
printf 'Theme CSS must clear the opaque Codex semantic composer body.\n' >&2
exit 1
}
/usr/bin/grep -F -q 'metric.nativeLayersClear' "$ROOT/engine/scripts/injector.mjs" || {
printf 'Live verification must reject opaque native layers inside the composer.\n' >&2
exit 1
}
/usr/bin/grep -F -q 'result.hero.y - result.homeBox.y <= 2' \
"$ROOT/engine/scripts/injector.mjs" || {
printf 'Live verification must reject the modern Home top spacer regression.\n' >&2
exit 1
}

"$NODE" -e '
const fs = require("node:fs");
const path = require("node:path");
Expand Down
Loading