| name | codex-dream-skin-theme-injector |
| description | Theme injection tool for Codex desktop using local CDP, adding custom skins without modifying app binaries |
| triggers | ["how do I theme Codex desktop","install custom skin for Codex","change Codex appearance with Dream Skin","inject theme into Codex using CDP","customize Codex desktop background","apply Dream Skin to Codex","setup Codex theming tool","troubleshoot Codex Dream Skin"] |
Codex Dream Skin Theme Injector
Skill by ara.so โ Codex Skills collection.
Overview
Codex Dream Skin is a local CDP (Chrome DevTools Protocol) injection tool that applies custom visual themes to the Codex desktop application without modifying the official installation binaries, .app bundle, app.asar, or code signature.
Key capabilities:
- Inject custom CSS/background images into running Codex instance
- Bind CDP server to
127.0.0.1 only (local security boundary)
- One-click install, apply, restore scripts
- Platform-specific implementations for macOS and Windows
- Interactive UI elements remain native (not just a static overlay)
Security model:
- Does NOT modify official installation files
- Does NOT change API keys or base URLs
- CDP bound to localhost only
- Requires Codex to be launched with
--remote-debugging-port flag
Installation
macOS (Apple Silicon & Intel)
Located in macos/ directory.
Quick install:
cd macos
./Install\ Codex\ Dream\ Skin.command
Manual setup:
git clone https://github.com/Fei-Away/Codex-Dream-Skin.git
cd Codex-Dream-Skin/macos
chmod +x scripts/*.sh
chmod +x *.command
./Install\ Codex\ Dream\ Skin.command
The installer will:
- Check for Codex.app in
/Applications
- Install helper scripts to
~/Library/Application Support/Codex-Dream-Skin/
- Create launch wrappers
- Set up configuration directory
Windows
Located in windows/ directory.
PowerShell setup:
# 1. Navigate to windows directory
cd windows
# 2. Install (sets up scripts and config)
.\scripts\install-dream-skin.ps1
# 3. Start Dream Skin with Codex
.\scripts\start-dream-skin.ps1
What it does:
- Locates Codex installation (typically in
%LOCALAPPDATA%\Programs\Codex)
- Sets up helper scripts in
%APPDATA%\Codex-Dream-Skin
- Configures CDP port (default 9222)
- Creates theme injection scripts
Usage
Starting Codex with Dream Skin
macOS:
~/Library/Application\ Support/Codex-Dream-Skin/launch-codex-with-skin.sh
/Applications/Codex.app/Contents/MacOS/Codex --remote-debugging-port=9222 &
sleep 3
~/Library/Application\ Support/Codex-Dream-Skin/inject-theme.sh
Windows:
# Use start script
.\scripts\start-dream-skin.ps1
# Or manually:
Start-Process "$env:LOCALAPPDATA\Programs\Codex\Codex.exe" -ArgumentList "--remote-debugging-port=9222"
Start-Sleep -Seconds 3
.\scripts\inject-theme.ps1
Switching Themes
Theme structure:
themes/
my-theme/
config.json
background.jpg
custom.css
config.json example:
{
"name": "My Custom Theme",
"background": "background.jpg",
"css": "custom.css",
"opacity": 0.85,
"blur": 10
}
Apply theme (macOS):
vim ~/Library/Application\ Support/Codex-Dream-Skin/config.json
{
"theme": "~/Codex-Dream-Skin/themes/my-theme",
"cdp_port": 9222
}
~/Library/Application\ Support/Codex-Dream-Skin/launch-codex-with-skin.sh
Apply theme (Windows):
# Edit config
notepad $env:APPDATA\Codex-Dream-Skin\config.json
# Set theme path
{
"theme": "C:\\Users\\YourName\\Codex-Dream-Skin\\themes\\my-theme",
"cdp_port": 9222
}
# Restart
.\scripts\start-dream-skin.ps1
Custom CSS Injection
Example custom.css:
body::before {
content: '';
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image: url('./background.jpg');
background-size: cover;
background-position: center;
opacity: 0.15;
z-index: -1;
pointer-events: none;
}
.sidebar {
background: rgba(255, 255, 255, 0.9) !important;
backdrop-filter: blur(10px);
}
.input-container {
background: rgba(248, 249, 250, 0.95) !important;
border-radius: 12px;
box-shadow: 0 4px 12px rgba(0, 0, , );
}
{
: ;
: ;
}
CDP Injection Script (macOS)
inject-theme.sh snippet:
#!/bin/bash
CDP_PORT=${CDP_PORT:-9222}
CONFIG_DIR="$HOME/Library/Application Support/Codex-Dream-Skin"
THEME_DIR=$(jq -r '.theme' "$CONFIG_DIR/config.json")
timeout=10
while [ $timeout -gt 0 ]; do
if curl -s "http://127.0.0.1:$CDP_PORT/json" >/dev/null; then
break
fi
sleep 1
((timeout--))
done
WS_URL=$(curl -s "http://127.0.0.1:$CDP_PORT/json" | jq -r '.[0].webSocketDebuggerUrl')
CSS_CONTENT=$(cat "$THEME_DIR/custom.css" | jq -Rs .)
wscat -c "$WS_URL" -x "{\"id\":1,\"method\":\"Runtime.evaluate\",\"params\":{\"expression\":\"const style=document.createElement('style');style.textContent=$CSS_CONTENT;document.head.appendChild(style);\"}}"
CDP Injection Script (Windows)
inject-theme.ps1 snippet:
$CDP_PORT = 9222
$ConfigPath = "$env:APPDATA\Codex-Dream-Skin\config.json"
$Config = Get-Content $ConfigPath | ConvertFrom-Json
$ThemeDir = $Config.theme
# Wait for CDP
$timeout = 10
while ($timeout -gt 0) {
try {
$response = Invoke-WebRequest -Uri "http://127.0.0.1:$CDP_PORT/json" -UseBasicParsing
break
} catch {
Start-Sleep -Seconds 1
$timeout--
}
}
# Get WebSocket URL
$pages = Invoke-RestMethod -Uri "http://127.0.0.1:$CDP_PORT/json"
$wsUrl = $pages[0].webSocketDebuggerUrl
# Read CSS
$cssContent = Get-Content "$ThemeDir\custom.css" -Raw
$cssEscaped = $cssContent -replace '"', '\"' -replace "`r`n", "\n"
# Inject via WebSocket
$js = "const style=document.createElement('style');style.textContent=`"$cssEscaped`";document.head.appendChild(style);"
$payload = @{
id = 1
method = "Runtime.evaluate"
params = @{ expression = $js }
} | ConvertTo-Json -Compress
# Send via WebSocket (requires WebSocket client)
# Use wscat or custom WebSocket implementation
Configuration
Main Config File
Location:
- macOS:
~/Library/Application Support/Codex-Dream-Skin/config.json
- Windows:
%APPDATA%\Codex-Dream-Skin\config.json
Schema:
{
"theme": "/path/to/theme/directory",
"cdp_port": 9222,
"auto_inject": true,
"inject_delay": 3,
"backup_enabled": true
}
Fields:
theme: Absolute path to theme directory
cdp_port: CDP debugging port (default 9222)
auto_inject: Auto-inject on Codex launch
inject_delay: Seconds to wait before injection
backup_enabled: Keep backup of original state
Environment Variables
export CDP_PORT=9223
export CODEX_SKIN_CONFIG="$HOME/.config/codex-skin.json"
export CODEX_THEME_DIR="$HOME/my-themes/current"
Key Commands
macOS Scripts
Located in macos/scripts/:
./Install\ Codex\ Dream\ Skin.command
~/Library/Application\ Support/Codex-Dream-Skin/launch-codex-with-skin.sh
~/Library/Application\ Support/Codex-Dream-Skin/inject-theme.sh
~/Library/Application\ Support/Codex-Dream-Skin/restore-original.sh
./macos/tests/run-tests.sh
./macos/scripts/uninstall.sh
Windows Scripts
Located in windows/scripts/:
# Install
.\scripts\install-dream-skin.ps1
# Start with theme
.\scripts\start-dream-skin.ps1
# Inject to running instance
.\scripts\inject-theme.ps1
# Restore original
.\scripts\restore-original.ps1
# Verify
.\scripts\verify-installation.ps1
Common Patterns
Pattern 1: Quick Theme Switch
macOS:
#!/bin/bash
THEME_NAME=$1
CONFIG="$HOME/Library/Application Support/Codex-Dream-Skin/config.json"
THEME_BASE="$HOME/Codex-Dream-Skin/themes"
jq --arg theme "$THEME_BASE/$THEME_NAME" '.theme = $theme' "$CONFIG" > /tmp/config.json
mv /tmp/config.json "$CONFIG"
pkill -f "Codex.*remote-debugging"
~/Library/Application\ Support/Codex-Dream-Skin/launch-codex-with-skin.sh
Usage:
./switch-theme.sh pink-custom
./switch-theme.sh hatsune-miku
Pattern 2: Dynamic CSS Injection
JavaScript injected via CDP:
const injectTheme = (cssUrl, opacity = 0.85) => {
const link = document.createElement('link');
link.rel = 'stylesheet';
link.href = cssUrl;
document.head.appendChild(link);
const overlay = document.createElement('div');
overlay.style = `
position: fixed;
top: 0; left: 0;
width: 100%; height: 100%;
background: url('${cssUrl.replace('.css', '.jpg')}');
background-size: cover;
opacity: ${opacity};
z-index: -1;
pointer-events: none;
`;
document.body.prepend(overlay);
};
injectTheme('http://localhost:8080/theme.css', 0.9);
CDP command:
curl -X POST http://127.0.0.1:9222/json/new
WS_URL=$(curl -s http://127.0.0.1:9222/json | jq -r '.[0].webSocketDebuggerUrl')
echo '{
"id": 1,
"method": "Runtime.evaluate",
"params": {
"expression": "/* JS code here */"
}
}' | wscat -c "$WS_URL"
Pattern 3: Theme with Local Asset Server
Serve theme assets:
#!/bin/bash
THEME_DIR="$1"
PORT=8765
cd "$THEME_DIR"
python3 -m http.server $PORT &
SERVER_PID=$!
echo "Theme server running on http://localhost:$PORT (PID: $SERVER_PID)"
echo $SERVER_PID > /tmp/theme-server.pid
CSS references local server:
body::before {
background-image: url('http://localhost:8765/background.jpg');
}
@font-face {
font-family: 'CustomFont';
src: url('http://localhost:8765/fonts/custom.woff2');
}
Pattern 4: Automated Launch on System Startup
macOS LaunchAgent:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.codex.dreamsin</string>
<key>ProgramArguments</key>
<array>
<string>/Users/YOUR_USER/Library/Application Support/Codex-Dream-Skin/launch-codex-with-skin.sh</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<false/>
</dict>
</plist>
Load agent:
launchctl load ~/Library/LaunchAgents/com.codex.dreamkin.plist
Windows Task Scheduler:
# Create scheduled task
$action = New-ScheduledTaskAction -Execute "powershell.exe" `
-Argument "-File `"$env:APPDATA\Codex-Dream-Skin\start-dream-skin.ps1`""
$trigger = New-ScheduledTaskTrigger -AtLogOn
Register-ScheduledTask -TaskName "Codex Dream Skin" `
-Action $action -Trigger $trigger -RunLevel Highest
Troubleshooting
Issue: CDP Port Already in Use
Symptoms: Error: Address already in use when starting Codex with --remote-debugging-port
Solution:
lsof -i :9222
netstat -ano | findstr :9222
kill -9 <PID>
taskkill /PID <PID> /F
export CDP_PORT=9223
Issue: Theme Not Applying
Check CDP availability:
curl http://127.0.0.1:9222/json
Expected output:
[
{
"description": "",
"devtoolsFrontendUrl": "/devtools/inspector.html?ws=127.0.0.1:9222/devtools/page/...",
"id": "...",
"title": "Codex",
"type": "page",
"webSocketDebuggerUrl": "ws://127.0.0.1:9222/devtools/page/..."
}
]
If empty or error:
- Codex not started with
--remote-debugging-port flag
- Wrong port number
- Firewall blocking localhost
Manual injection test:
WS_URL=$(curl -s http://127.0.0.1:9222/json | jq -r '.[0].webSocketDebuggerUrl')
echo '{"id":1,"method":"Runtime.evaluate","params":{"expression":"alert(\"Test\")"}}' | \
wscat -c "$WS_URL"
Issue: Codex Won't Start
Check Codex path:
ls -la /Applications/Codex.app/Contents/MacOS/Codex
ls "$env:LOCALAPPDATA\Programs\Codex\Codex.exe"
Try manual launch:
/Applications/Codex.app/Contents/MacOS/Codex --remote-debugging-port=9222 --verbose
& "$env:LOCALAPPDATA\Programs\Codex\Codex.exe" --remote-debugging-port=9222 --verbose
Check logs:
~/Library/Logs/Codex/
~/Library/Application Support/Codex-Dream-Skin/logs/
%APPDATA%\Codex\logs\
%APPDATA%\Codex-Dream-Skin\logs\
Issue: CSS Not Loading
Verify theme directory structure:
ls -la ~/Codex-Dream-Skin/themes/my-theme/
Check CSS syntax:
npx stylelint ~/Codex-Dream-Skin/themes/my-theme/custom.css
Test CSS injection manually:
const style = document.createElement('style');
style.textContent = `
body { background: red !important; }
`;
document.head.appendChild(style);
Issue: Theme Reverts After Update
Symptoms: After Codex updates, theme stops working
Solution:
./macos/tests/run-tests.sh
.\windows\scripts\verify-installation.ps1
./Install\ Codex\ Dream\ Skin.command
.\scripts\install-dream-skin.ps1
Prevent auto-updates (optional, not recommended):
echo "0.0.0.0 update.codex.app" | sudo tee -a /etc/hosts
Issue: Security Warning on macOS
Symptoms: "Codex Dream Skin.command cannot be opened because it is from an unidentified developer"
Solution:
xattr -d com.apple.quarantine ./Install\ Codex\ Dream\ Skin.command
Issue: PowerShell Execution Policy (Windows)
Symptoms: cannot be loaded because running scripts is disabled
Solution:
# Check current policy
Get-ExecutionPolicy
# Set to RemoteSigned (for current user)
Set-ExecutionPolicy RemoteSigned -Scope CurrentUser
# Or bypass for single script
powershell -ExecutionPolicy Bypass -File .\scripts\install-dream-skin.ps1
Advanced: Creating Custom Themes
Minimal Theme Structure
my-awesome-theme/
โโโ config.json
โโโ custom.css
โโโ assets/
โโโ background.png
config.json:
{
"name": "My Awesome Theme",
"version": "1.0.0",
"author": "Your Name",
"background": "assets/background.png",
"css": "custom.css",
"settings": {
"opacity": 0.8,
"blur": 8,
"accentColor": "#6366f1"
}
}
custom.css template:
body::before {
content: '';
position: fixed;
inset: 0;
background: url('./assets/background.png') center/cover;
opacity: 0.8;
filter: blur(8px);
z-index: -2;
}
body::after {
content: '';
position: fixed;
inset: 0;
background: linear-gradient(135deg, rgba(99, 102, 241, 0.1), rgba(168, 85, 247, 0.1));
z-index: -1;
}
.panel, .sidebar, .chat-container {
background: rgba(255, 255, 255, 0.7) !important;
backdrop-filter: blur() ();
: solid (, , , );
: (, , , );
}
{
: ;
: ;
}
, {
: (--accent) ;
}
{
: (--accent-hover) ;
}
Testing Theme Locally
mkdir -p ~/Codex-Dream-Skin/themes/test-theme
cd ~/Codex-Dream-Skin/themes/test-theme
jq '.theme = "'$HOME'/Codex-Dream-Skin/themes/test-theme"' \
~/Library/Application\ Support/Codex-Dream-Skin/config.json > /tmp/cfg.json
mv /tmp/cfg.json ~/Library/Application\ Support/Codex-Dream-Skin/config.json
~/Library/Application\ Support/Codex-Dream-Skin/launch-codex-with-skin.sh
API Reference (CDP Injection)
Core CDP Methods Used
1. Runtime.evaluate
{
"id": 1,
"method": "Runtime.evaluate",
"params": {
"expression": "console.log('Injected!')",
"returnByValue": true
}
}
2. Page.addScriptToEvaluateOnNewDocument
{
"id": 2,
"method": "Page.addScriptToEvaluateOnNewDocument",
"params": {
"source": "const style = document.createElement('style'); style.textContent = '/* CSS */'; document.head.appendChild(style);"
}
}
3. CSS.createStyleSheet (if supported)
{
"id": 3,
"method": "CSS.createStyleSheet",
"params": {
"frameId": "main-frame-id"
}
}
Helper Functions
WebSocket message sender (Node.js):
const WebSocket = require('ws');
async function sendCDP(wsUrl, method, params) {
const ws = new WebSocket(wsUrl);
return new Promise((resolve, reject) => {
ws.on('open', () => {
ws.send(JSON.stringify({
id: Date.now(),
method,
params
}));
});
ws.on('message', (data) => {
const response = JSON.parse(data);
ws.close();
resolve(response);
});
ws.on('error', reject);
});
}
const wsUrl = 'ws://127.0.0.1:9222/devtools/page/...';
await sendCDP(wsUrl, 'Runtime.evaluate', {
expression: 'document.title'
});
Reference Documentation
- Platform paths:
docs/platforms.md
- Project structure:
docs/PROJECT.md
- macOS details:
macos/README.md
- Windows details:
windows/SKILL.md
- License:
macos/LICENSE (MIT)
- Notices:
macos/NOTICE.md
Remember: This tool modifies the visual appearance only via runtime injection. It does NOT change API configurations, credentials, or application binaries. Always launch Codex from trusted locations and keep CDP bound to 127.0.0.1.