Create a Codex theme
Create a reversible decorative theme without modifying
, the signed app bundle, WindowsApps, user tasks, or authentication data. Preserve native layout and interaction behavior unless the chosen layout mode explicitly permits a bounded composition change.
Authority boundary
Use this skill as the sole design and QA authority for a new Codex theme. Do not read, copy, or combine another installed theme skill, finished theme manifest, finished theme CSS, or local theme collection unless the user explicitly names that source. Do not describe the workflow as combining this skill with “local theme conventions.” Start from this skill's matching skeleton and the user's brief or reference image.
This skill is standalone. Its TypeScript scripts own scaffolding, validation, reversible session application, and restore. Never detect, invoke, read configuration from, or claim a dependency on CodeDrobe, Dream/Fiona, or another theme injector unless the user explicitly asks to use that product. Do not reuse their marker names or runtime data. The only required local tools are Node.js,
, and the official Codex desktop app.
Managed storage
Keep every generated theme file in the managed library
unless the user explicitly requests another location:
- editable source and artwork:
~/.codexthemes/themes/<theme-id>/
- previews:
~/.codexthemes/themes/<theme-id>/previews/
- shareable packages:
- runtime state:
Never create a staging, scratch, or temporary copy of theme files in or near the current workspace (for example a
directory). If the sandbox or permission mode blocks writing to
, ask the user to approve writing there instead of writing somewhere else first and moving files later.
Read the required references
Before creating or substantially redesigning a theme, read these files completely:
references/design-playbook.md
: layout modes, semantic palette, selectors, and surface coverage.
references/qa-checklist.md
: real-app acceptance matrix and hard failures.
references/theme-schema.md
: manifest and portable package contract.
references/asset-rights.md
: user-material handling and submission handoff.
Do not begin artwork or CSS until the design contract below is written.
Gate 1: write the design contract
Record:
- light or dark mode and the reason
- artwork focal point and text-safe region
- semantic palette
- surfaces allowed to change
- native geometry and states that must remain unchanged
- target desktop and narrow viewports
Choose the layout mode in this order:
- Use as the default when the user supplies a reference image or names a visual world (a game, film, anime, brand, season, or other strong art direction): keep the native layout and deliver coordinated sidebar, card, menu, composer, settings, diff, and terminal materials plus the decoration menu in
references/design-playbook.md
.
- Use only when the user explicitly restricts the theme to a background change.
- Use only when the reference clearly requires a bounded portrait, product, or campaign hero with a different home composition.
- Use when no dominant artwork is required.
Record
as
,
, or
. Default to
when the reference has a strong art direction and
otherwise; use
only when the user explicitly asks for a background-only or quiet theme. The design playbook defines the element coverage each density requires. A theme that ships one background image and a veil does not satisfy
or
.
Default
to
. Use
only when the user explicitly wants artwork on normal task and conversation pages. Never infer a conversation page merely because the page is not home; settings and system pages must not inherit task artwork.
Do not default to dark mode. Match an explicit request or the reference luminance. Ambiguous editorial, floral, portrait, stationery, lifestyle, productivity, and pastel concepts default to light.
Gate 2: capture the native contract
Inspect the unmodified live app at the same viewport and record evidence for:
- home heading, native suggestion cards, project selector, and composer
- populated conversation and activity rows
- settings and profile pages
- personal menu, dropdown, dialog, and tooltip
- attachments, file cards, changed-files/diff, and output panels
- terminal before and after xterm mounts
- sidebar idle, hover, selected, project hover, long titles, and row actions
- header actions at narrow and wide widths
Treat geometry, visibility, hit targets, keyboard focus, and hover-only actions as invariants unless the design contract explicitly permits a change.
Gate 3: scaffold the correct skeleton
Run from the installed skill directory:
bash
npx tsx scripts/scaffold-theme.ts \
--id <safe-slug> \
--name "<display name>" \
--layout-mode <native-background|native-immersive|editorial-showcase|palette-only> \
--background-scope <home|workspace> \
[--art /absolute/artwork.png]
The default source location is
~/.codexthemes/themes/<safe-slug>/
. Always use that managed library unless the user explicitly requests another location; only then pass
--output /absolute/theme-parent
. Never use the current workspace merely because it is writable.
Never start by copying a finished theme that uses another layout mode.
Gate 4: implement in controlled layers
Build CSS in this order:
- semantic tokens
- shell surfaces
- exact route-scoped backgrounds
- native component roots
- interaction states
- non-interactive decoration
- responsive and reduced-motion rules
Restraint applies to geometry and interaction, not to coverage: implement every surface material and decoration element the contracted
requires (see the playbook's decoration menu). A theme that only swaps the background and leaves native cards, composer, sidebar, header, typography, and scrollbars untouched is unfinished at
or
density. Use stable roles, test IDs, verified component classes, and narrowly anchored
. Avoid localized text selectors when a structural hook exists.
Never apply broad
,
,
,
,
, or
overrides to
,
, generic
, or broad descendant groups. Never use descendant
to repair contrast; it exposes hidden row actions.
Define one owner for every divider, outline, sidebar edge, card boundary, and header boundary. Use a solid readable header surface; keep gradients and artwork behind content rather than behind low-contrast toolbar controls. Keep all decoration below native controls with
.
For light themes, keep settings, menus, dialogs, output/diff panels, code surfaces, and terminal hosts in the same light semantic system unless the contract deliberately defines a contrast panel. Theme terminal host, xterm viewport, and xterm screen together.
Changing a surface's background does not restyle its text. The native app (especially in dark mode) sets
explicit light text colors on many descendants, and an inherited
on
,
, or
never overrides an explicit descendant color. Whenever a background flips luminance (a light theme over the native dark mode, or the reverse), override the text tokens on the same descendants that carry them — message bodies, markdown content, list items, buttons, labels — not just the container. This is the single most common way a theme ships unreadable.
Install the stylesheet before asynchronously decoding large artwork so cold launch does not flash the native page and then jump to a different layout.
Increment the manifest version after every visible change.
Gate 5: validate before application
Run:
bash
npx tsx scripts/validate-theme.ts /absolute/theme-directory
Fix every error. Treat warnings as unresolved until checked against the design contract. Static validation does not replace visual verification.
Generate a self-contained preview at both 1440x900 and a narrow viewport. Save previews in
~/.codexthemes/themes/<theme-id>/previews/
(the scaffold already creates this directory); never write them to the workspace or a staging directory. Label each one as a design preview, never as a verified Codex screenshot.
Every preview must show the full themed workspace — sidebar, header, and home content in one frame — never the background artwork alone. Keep the primary desktop preview as a raster file (PNG, JPEG, or WebP; for example
previews/home-1440x900.png
): it becomes the theme's gallery and detail image on codexthemes.ai. After Gate 6 verification, replace it with a real screenshot of the applied theme.
Gate 6: apply and verify the real app
Ask for explicit permission before applying a theme or restarting Codex. Use this skill's own reversible TypeScript runtime; do not search for or prefer an external theme program.
If Codex is already exposing a local debugging endpoint, apply without restarting:
bash
npx tsx scripts/apply-theme.ts apply /absolute/theme-directory
If no endpoint exists, ask specifically for permission to restart Codex, then use the standalone launcher:
bash
npx tsx scripts/apply-theme.ts apply /absolute/theme-directory --launch
When no endpoint is live,
prints
and hands the quit → relaunch → inject sequence to a detached helper that survives the restart. This is required because an agent hosted inside Codex dies together with Codex; expect the current tool call (and possibly the session) to be interrupted by the restart. Never work around the restart yourself: do not write shell wrappers, launchd or scheduled tasks, copies of the script, or any other relaunch mechanism — the
helper already survives the restart.
The launcher supports macOS and Windows (on Windows it locates the Codex/ChatGPT executable, closes it gracefully with
— never
— and relaunches it with the debugging flags; pass
with the full
path if detection fails). If the endpoint never appears after a Windows relaunch, that installed build (for example a Microsoft Store package) drops the debugging flags — report that limitation plainly and finish source, preview, validation, and packaging instead; never modify files under
.
is not success. After Codex is back, verify before reporting anything:
bash
npx tsx scripts/apply-theme.ts status
probes every live Codex page and reports
with the injected theme id only when the style element is really in the DOM. If it reports
, read
~/.codexthemes/state/launch.log
for the helper's result and error.
If an old theme keeps re-appearing after a successful apply (a stale session from an earlier task is still re-injecting it), get the user's restart permission and force a clean relaunch with
apply ... --launch --relaunch
— never ask the user to quit the app by hand and never invent your own restart mechanism.
For later one-command switching between finished themes, hand off to the
skill; this skill's apply runtime is for creation-time QA.
The launcher binds debugging to
, injects only an owned
element and CodexThemes page markers, does not modify the signed application bundle, and keeps the theme active across SPA route changes and renderer reloads for the current app session. A full application quit requires reapplying the theme (again with
). Restore at any time with:
bash
npx tsx scripts/apply-theme.ts restore
If standalone application is unavailable on the current platform, finish the source, preview, validation, and package. State the application limitation plainly; never silently fall back to another installed injector.
Immediately after every apply — hot swap or post-restart — run the automated readability gate before anything else:
bash
npx tsx scripts/qa-contrast.ts
It hard-fails (exit 1) when visible text is unreadable, using two independent measurements: computed-style composition over verified opaque backdrops, and
real screenshot pixels (
), which also judge text sitting over artwork and transparent layers. A
means the theme is unreadable right now: fix the text tokens or artwork veils (or switch back to the previous theme) before doing anything else, and never leave a failing theme active or report it as applied. A
is necessary but not sufficient; continue with the full matrix:
Verify independently:
- structure: native sidebar, cards, project selector, composer, task content, settings, and terminal work
- scope: home and conversation artwork appears only where contracted
- palette: every changed surface belongs to one semantic system
- mode independence: the full native sweep is present, so the theme renders identically whether the user's Codex starts in native light or native dark mode (see the playbook's native token sweep)
- state: idle, hover, selected, disabled, focus-visible, loading, running, expanded, and open
- geometry: no clipping, overflow, duplicate borders, text/icon overlap, or sidebar action collision
- lifecycle: cold launch, route change, renderer reload, theme switch, restore, and reapply
Capture real screenshots and computed-style/geometry evidence. A successful build, injection marker, static mockup, or one home screenshot is not completion. When a P0 check fails, fix selector or token ownership and rerun the complete matrix instead of adding an emergency override.
Gate 7: package only after signoff
Package only verified local files. A
package must be UTF-8 JSON, contain no absolute paths, external CSS resources, scripts, tracking, secrets, or private references, and stay under 30 MB. Follow
references/theme-schema.md
.
Export the shareable package with:
bash
npx tsx scripts/export-theme.ts ~/.codexthemes/themes/<theme-id>
The default output is
~/.codexthemes/exports/<theme-id>.codex-theme
. Do not place export packages in a project workspace or inside the editable theme source. Use
only when the user explicitly requests a different export directory.
The export embeds a workspace preview (manifest
, or the best raster in
) that codexthemes.ai uses as the gallery and detail image. Before exporting, confirm that image shows the themed workspace with the sidebar — not the raw artwork — and re-export after replacing it with a verified screenshot.
Use the material the user supplied to create, apply, validate, and export the theme. Do not investigate ownership, demand replacement artwork, or block local packaging because the subject is a game, film, anime, public figure, brand, or other third-party work. Do not make legal conclusions or claim that the user owns the material.
After export, offer the user both submission paths:
- Manual: submit the package and a clear preview at
https://codexthemes.ai/submit
.
- Agent-assisted: tell the user they can reply with a prompt like
Use $codex-theme-submitter to submit ~/.codexthemes/exports/<theme-id>.codex-theme to codexthemes.ai
, and that if is not installed they can add it with npx skills add codexthemes/skills --skill codex-theme-submitter -g -a codex
.
State that submission asks the uploader to confirm they may share the material; leave that confirmation to the user and the submission workflow. Do not run the submission yourself unless the user asks for it.
Completion standard
Reject an almost-complete theme. A polished home page does not compensate for broken conversations, settings, menus, terminal, sidebar states, narrow windows, or cold launch. Report separately what was designed, statically validated, applied, visually verified, and packaged. Always report the canonical source and export paths.