Codex Dream Skin은 "공식 Codex 데스크톱 앱의 얼굴만 갈아입히는 겉옷"이다. 프로젝트의 한 줄 표어가 정확히 이걸 말한다 — "给 Codex 桌面端换一张会呼吸的脸"(Codex 데스크톱에 숨 쉬는 얼굴 한 장을 입히자). 사용자가 자기가 고른 이미지 한 장을 넣으면, 그 이미지가 Codex 창 전체를 덮는 끊김 없는 16:9 배경이 되고, 그 위로 Codex의 원래 사이드바·입력창·프로젝트 카드가 여전히 진짜로 작동하는 채 얹힌다.
codex CLI를 꾸미는 게 아니다"Codex"라는 이름 때문에 검은 터미널 화면을 떠올리기 쉽지만, 이 도구가 상대하는 건 OpenAI Codex의 데스크톱 앱이다(macOS의 com.openai.codex.app, Windows의 Microsoft Store OpenAI.Codex 패키지). 이 앱은 속을 보면 Electron — 즉 크롬(Chromium)을 껍데기로 쓴 웹앱이다. 그래서 웹페이지처럼 CSS·JS를 주입해 꾸밀 수 있다. 텍스트만 그리는 터미널 TUI였다면 이 방식 자체가 불가능하다. 문서 전체에서 "Codex 앱"은 이 Electron 데스크톱 앱을 뜻한다.
핵심 동작을 한 문장으로 요약하면 이렇다. 공식 Codex 앱을 "원격 디버깅 포트"를 열고 실행 → 그 포트에 웹소켓으로 붙어 → 미리 만든 CSS(배경·색)와 JS(DOM 정리)를 앱 안으로 밀어 넣는다. 이 통로가 바로 CDP(Chrome DevTools Protocol)다. 브라우저 개발자도구가 페이지를 조종할 때 쓰는 바로 그 프로토콜을, 이 도구는 "테마를 입히는 손"으로 재활용한다(자세한 흐름은 §4).
중요한 건 "하지 않는 것"의 목록이다. 이 도구는 Codex의 설치 파일(.app/app.asar/WindowsApps)을 고치지 않고, 코드 서명도 건드리지 않으며, 당신의 API 키·모델 주소도 만지지 않고, 당신의 이미지를 어디에도 업로드하지 않는다. 모든 변경은 당신 컴퓨터 안(loopback)에서 런타임에만 일어나고, 클릭 한 번(Restore)으로 원상 복구된다. "공식 앱을 안 부수면서 겉만 바꾼다"가 설계 철학이다.
--remote-debugging-port=9341 같은 옵션으로 켜면, 그 포트에 웹소켓으로 접속해 "이 자바스크립트를 실행해라(Runtime.evaluate)", "새 문서가 뜰 때마다 이 스크립트를 먼저 심어라(Page.addScriptToEvaluateOnNewDocument)" 같은 명령을 보낼 수 있다. 원래는 개발자도구·자동화 테스트(Puppeteer 등)가 쓰는 통로인데, Codex Dream Skin은 이걸 "공식 앱을 부수지 않고 스타일을 얹는 안전한 주입구"로 쓴다. 그래서 앱 바이너리를 패치하는 위험한 방식(예: app.asar 뜯기)을 피할 수 있다.Codex Dream Skin은 차体를 뜯어고치는 튜닝이 아니라, 유리창에 정교한 시트지를 붙이는 작업에 가깝다. 운전대(사이드바)·페달(입력창)·계기판(카드)은 손대지 않아 그대로 작동하고, 그 뒤·주변으로 원하는 풍경(배경 이미지)이 깔린다. 필름은 언제든 떼면(Restore) 원래 유리로 돌아온다.
필름을 "붙이는 손"이 바로 CDP라는 규격화된 주입구다. 차 문을 부수고 들어가는 게 아니라, 제조사가 열어 둔 정비 포트(원격 디버깅)로 얌전히 접속한다. "공식 앱을 안 건드리면서 겉을 바꾼다"는 이 프로젝트의 안전 설계가 여기서 나온다(§4).
이 저장소가 하루 만에 TrendShift Daily #2(모멘텀 5.2k)로 치고 올라온 데는 기술만큼이나 "이야기"가 있다. 발단은 이렇다 — 중국 중고거래 앱 闲鱼(셴위)에서 누군가 "Codex 앱 테마 스킨"을 한 개 66위안, 99위안에 팔고 있었다. 이를 본 개발자들이 "이건 chatgpt-image(gpt-image)로 이미지 몇 장 뽑고 CSS 몇 줄 얹으면 되는 걸 파는, 妥妥的智商税(전형적인 호갱 상술)"라며 동작하는 오픈소스 스킬을 그냥 무료로 공개해 버렸다. Codex Dream Skin이 바로 그 결과물이다.
여기에 "예쁜 화면"이 불을 붙였다. 소셜에는 玫瑰金(로즈골드) 배색, 인물 立绘(일러스트) 배치, 사이드바·입력창·버튼까지 통일된 핑크 계열, "우리 무엇을 만들까?" 환영 화면까지 다시 칠한 스크린샷이 돌았다. "그냥 벽지 한 장 붙인 게 아니라 완결된 비주얼 경험"이라는 반응이 커뮤니티를 자극했다.
| 포인트 | 내용 |
|---|---|
| 정체 | 공식 Codex 데스크톱 앱(Electron)용 비공식 스킨. 앱을 원격 디버깅으로 띄워 CDP로 CSS·JS를 런타임 주입. 앱 바이너리·서명은 불변. |
| 왜 화제 | 闲鱼에서 유료(66~99위안)로 팔리던 Codex 스킨을 상대로 나온 무료 MIT 오픈소스 대안. "호갱 상술 vs 오픈소스"라는 서사 + 예쁜 스크린샷. |
| 범주 | 단순 벽지가 아니라 에이전트 스킬(Agent Skill)로도 포장됨 — SKILL.md 2개(mac/win). "내 이미지로 테마 깔아줘"라고 Codex 에이전트에 시키면 스스로 설치. |
| 두 OS 완비 | macos/(Bash+Node)와 windows/(PowerShell+Node)가 같은 설계를 각자 재구현. 트레이/메뉴바 관리 앱까지 양쪽 다 제공. |
| 안전 지향 | loopback(127.0.0.1) 전용 CDP, 원자적(atomic) 설정 백업·복구, 프로세스 신원 검증 — "겉옷인데 안전 엔지니어링이 진짜배기"(§6). |
서드파티 앱을 꾸미는 흔한 방법은 app.asar(Electron 앱의 압축된 소스)를 뜯어 파일을 갈아치우는 것이다. 하지만 그러면 코드 서명이 깨지고, 앱 업데이트 때마다 다시 뜯어야 하고, 잘못하면 앱이 안 뜬다. Codex Dream Skin은 이 위험을 통째로 피한다. 설치 파일에 손대는 대신, 앱을 원격 디버깅 모드로 켜서 CDP로 스타일만 얹는다. 최악의 경우라도 "그냥 배경이 안 맞는" 화면일 뿐, 앱이 망가지지 않는다. 복구는 클릭 한 번. 서드파티 데스크톱 앱을 안전하게 커스터마이즈하는 정석적 패턴이다.
배경 이미지를 UI 뒤에 깔면 보통 글자가 안 보인다. 이 프로젝트의 진짜 기술은 이미지를 그냥 깔지 않고, 반투명 그라데이션 장막(scrim)을 알파값을 조절해 겹쳐 Codex의 원래 글자·버튼이 계속 읽히게 만드는 CSS다(1,079줄). 게다가 주입된 JS가 브라우저 Canvas로 이미지의 대표색·밝기·초점을 분석해 그 이미지에 어울리는 UI 색을 자동으로 뽑아낸다 — 이 모든 걸 서버 없이, 업로드 없이 당신 컴퓨터 안에서.
이 저장소는 단순 스크립트 모음이 아니라 Agent Skill 형식(SKILL.md + YAML 머리말)으로도 포장돼 있다. 그래서 폴더를 통째로 자기 Codex 에이전트에게 건네고 "내 사진으로 테마 설치하고 검증까지 해줘"라고 말하면, 에이전트가 설치→커스터마이즈→검증→(원하면)복구 절차를 스스로 수행한다. "사람이 쓰는 도구"이자 "에이전트가 실행하는 스킬"인 이중 포장이다.
기본 대표 프리셋(preset-romantic-rose)과 Windows 기본 배경은 실존 일본 배우 桥本有菜(하시모토 아리나)의 실사 이미지이고, 저장소의 NOTICE.md는 이 이미지들을 MIT 라이선스에서 명시적으로 제외하며 "재배포·상업적 이용 전 별도 권리 검토가 필요하다"고 경고한다. 홍보 문구에는 迪丽热巴(디리러바)·千玺·Miku·KUN 등 유명인·IP 예시도 "테마 예시일 뿐"이라는 단서와 함께 등장한다. 또 AI 프롬프트는 모두 "명백한 성인(clearly adult)"을 강제하고 미성년 묘사를 금지한다. 이 문서는 CDP 주입·안전 설계 같은 기술적 학습 가치에 초점을 맞추되, 실제로 쓸 때는 초상권·상표권을 반드시 확인해야 함을 분명히 해 둔다.
GitHub 언어 통계는 이 저장소를 Shell(18개 .sh + 9개 .ps1)로 분류하지만, 그건 겉포장일 뿐이다. 실제 로직은 Node로 짠 CDP 주입기(injector.mjs), 1,079줄짜리 테마 CSS, 786줄짜리 렌더러 주입 JS에 들어 있다. 스택은 "① 어떻게 앱에 붙는가(주입) → ② 무엇을 그리는가(테마) → ③ 어떻게 관리하는가(트레이/설정)"의 세 축으로 보면 깔끔하다.
| 요소 | 내용 |
|---|---|
| 주입 통로 | CDP(Chrome DevTools Protocol) — 공식 Codex 앱을 --remote-debugging-port로 띄우고 웹소켓으로 접속. 포트 기본값 mac 9341 / win 9335(충돌 시 빈 포트 자동 탐색). |
| 주입 엔진 | injector.mjs(mac 891줄 / win 993줄) — 순수 Node. 표준 WebSocket·fetch·crypto.subtle만 써서 CDP Runtime.enable/Page.enable 후 페이로드 주입. |
| 런타임 | 전역 Node 불필요 — mac은 Codex가 품고 있는 서명된 번들 Node.js ≥20을 검증 후 재사용. win은 PATH의 Node ≥22 + Windows PowerShell 5.1+. |
| 실행 껍데기 | mac: 더블클릭 .command 6종(Install/Customize/Verify/Restore/Start/Install Menu Bar). win: .ps1 + 트레이 앱. |
| 요소 | 내용 |
|---|---|
| 테마 데이터 | theme.json(schemaVersion:1) — 색(background/panel/accent…), 이미지, 초점(focusX/Y·safeArea), 밝기모드(auto/light/dark)를 JSON으로 기술. 색 포맷은 JSON. |
| 스타일 | dream-skin.css(1,079줄) — 이미지를 CSS 변수 --dream-skin-art로 받아, 그 위에 알파 그라데이션 장막(scrim)을 겹쳐 가독성 확보. 라이트/다크 변수 블록 분리. |
| 렌더러 주입 JS | renderer-inject.js(786줄) — <html>에 클래스 부여, <style> 삽입, 수십 개 CSS 커스텀 속성 설정, 라이트/다크 자동 감지, 라우트(홈/작업) 인식, 정리(cleanup) 훅 보관. |
| 색 자동 추출 | 주입된 렌더러가 브라우저 Canvas로 이미지를 24색 구간으로 다운샘플 → 대표 accent·휘도·초점·안전변(좌/우) 추출 → UI 팔레트를 이미지로부터 자동 유도(업로드·API 없음). |
| 요소 | 내용 |
|---|---|
| 관리 앱(win) | tray-dream-skin.ps1 — 순수 PowerShell + WinForms NotifyIcon(외부 의존성 0). 우클릭 메뉴로 적용/일시정지/배경교체/테마저장/저장테마 전환/완전복구. Mutex로 중복 실행 방지. |
| 관리 앱(mac) | codex_dream_skin.10s.sh — SwiftBar 메뉴바 플러그인(10초 갱신). 상태(ON/일시정지/OFF)·현재 테마 표시 + 저장 테마·불러온 이미지 목록. |
| 설정 패치 | theme-config.mjs(314줄, mac) / config-utf8.ps1(520줄, win) — Codex의 ~/.codex/config.toml(TOML)에서 외형 키 2개만 백업/설정. 원자적 쓰기 + 신원 검증(§6). |
| 프리셋 생성 | generate-presets.mjs(116줄) — 의존성 0으로 PNG를 직접 인코딩(자체 CRC32·zlib deflate)해 추상 그라데이션 배경 6종을 결정적으로 생성. |
.sh·.ps1이 많은 이 저장소를 "Shell"로 표시한다. 하지만 셸 스크립트들은 대부분 "Codex를 찾아 검증하고, 포트를 정하고, Node 주입기를 띄우는" 오케스트레이션 껍데기다. 진짜 두뇌는 Node .mjs와 CSS/JS다. 주입 방식도 영리하다 — renderer-inject.js는 __DREAM_SKIN_CSS_JSON__ 같은 자리표시자(placeholder)가 박힌 템플릿이고, 주입기가 실제 CSS·이미지(base64 data URL)·테마 JSON을 JSON.stringify로 안전하게 문자열 치환해 완성한 뒤 Runtime.evaluate로 한 방에 실행한다.스택이 흩어져 보여도 역할은 셋이다. 설치·주입 팀(셸 + injector.mjs)은 공식 Codex를 정비 포트 열고 켠 뒤 몰래 무대에 들어가고, 무대미술 팀(dream-skin.css + renderer-inject.js)은 배경막을 걸고 조명(색)을 이미지에 맞춰 잡으며, 운영 팀(트레이/메뉴바 + theme-config.mjs)은 공연 중 배경을 바꾸거나 막을 내린다(복구). 이 셋이 CDP라는 하나의 문으로 드나든다.
가장 빠른 이해법은 "당신이 고른 사진"이 어떤 부품을 거쳐 "Codex 창의 배경"으로 나타나는지 따라가는 것이다. 핵심은 공식 Codex를 원격 디버깅으로 켜고, 그 창(렌더러)에 CSS+JS를 주입하는 한 줄기 파이프라인이다.
주입기가 처음 하는 일은 붙을 대상(CDP 타깃)이 정말 내 컴퓨터 안의 Codex 렌더러가 맞는지 깐깐하게 검증하는 것이다. 조금이라도 이상하면(외부 호스트, 포트 불일치, 계정정보 포함, app://가 아닌 URL 등) 즉시 거부한다. 원격 디버깅 포트는 인증이 없기 때문에, 이 형태 검사가 사실상의 방어선이다.
// injector.mjs — CDP 웹소켓 타깃을 loopback·포트·경로 형태로 검증(요지)
function validatedDebuggerUrl(target, port) {
const url = new URL(target.webSocketDebuggerUrl);
const pathIsValid = /^\/devtools\/page\/[A-Za-z0-9._-]{1,200}$/.test(url.pathname);
if (url.protocol !== "ws:" || !LOOPBACK_HOSTS.has(url.hostname)
|| Number(url.port) !== port || url.username || url.password
|| url.search || url.hash || !pathIsValid)
throw new Error("Rejected a CDP WebSocket URL outside the allowed loopback page endpoint shape");
return url.href;
}
포인트는 "허용 목록(loopback 호스트) + 엄격한 경로 정규식 + 군더더기(쿼리·해시·인증정보) 전면 금지"를 한꺼번에 요구한다는 것이다. 이렇게 "정상 모양"을 아주 좁게 정의해 두면, 예상치 못한 형태는 전부 걸러진다. 서드파티 앱을 자동으로 조종할 때 "붙을 대상부터 의심하라"는 교과서적 방어다.
검증을 통과하면 주입기가 loadPayload()로 재료를 모은다 — dream-skin.css, 렌더러 JS 템플릿, 테마 이미지(base64 data: URL), theme.json. 그리고 템플릿의 자리표시자를 JSON.stringify로 안전하게 치환해 하나의 실행 문자열을 만든다.
// injector.mjs — 자리표시자를 실제 값으로 치환해 페이로드 완성(요지)
const payload = template
.replace("__DREAM_SKIN_CSS_JSON__", JSON.stringify(css))
.replace("__DREAM_SKIN_ART_JSON__", JSON.stringify(artDataUrl)) // 이미지=base64
.replace("__DREAM_SKIN_THEME_JSON__", JSON.stringify(theme));
// 즉시 적용: 현재 세션에서 실행
await session.evaluate(payload); // = CDP Runtime.evaluate
// 지속 적용: 새 문서가 로드되기 "전에" 미리 심어 깜빡임 방지
await session.send("Page.addScriptToEvaluateOnNewDocument", { source: payload });
여기 watch 모드의 영리함이 있다. 단순히 지금 화면에 Runtime.evaluate로 한 번 칠하면, 앱이 페이지를 새로고침(라우팅·리로드)할 때 스킨이 잠깐 벗겨졌다가 다시 칠해져 깜빡인다. 그래서 Page.addScriptToEvaluateOnNewDocument로 "새 문서가 뜰 때마다 이 스크립트를 가장 먼저 실행"하도록 예약해, Codex 자신의 로드가 끝나기 전에 배경이 이미 깔려 있게 한다. 여기에 테마 폴더를 fs.watch로 감시해, 이미지·색을 바꾸면 내용 해시(revision) 비교로 멱등하게 핫 리로드한다.
renderer-inject.js(786줄)는 Codex 창(렌더러) 안에서 이렇게 동작한다. ① <html>에 codex-dream-skin 클래스를 붙이고 전용 <style>을 삽입한다. ② --ds-bg·--dream-skin-art·--dream-art-focus-x/y 같은 수십 개의 CSS 변수를 세팅해 배경·색·초점을 제어한다. ③ Codex 자신의 라이트/다크 토글(input[name="appearance-theme"]:checked)을 읽어 밝기 모드를 자동으로 따라간다. ④ 홈 화면인지 작업 화면인지(main.main-surface·홈 라우트 표식) 감지해, 홈은 표현적으로·작업 페이지는 차분하게 배경 강도를 바꾼다. ⑤ 모든 상태를 window.__CODEX_DREAM_SKIN_STATE__에 보관해, 복구 시 cleanup()으로 완전히 원복한다.배경 이미지를 그냥 깔면 글자가 묻힌다. dream-skin.css는 이미지를 CSS 변수로 받아, 그 위에 배경색을 알파값으로 단계 조절한 그라데이션 장막(scrim)을 겹친다. 왼쪽(글자·입력창이 있는 쪽)은 진하게 덮어 가독성을 지키고, 오른쪽(인물·풍경 쪽)은 투명하게 열어 이미지를 보여주는 식이다.
/* dream-skin.css — 작업 화면 배경: 장막 + 그늘 + 이미지를 겹쳐 쌓기 */
main.main-surface:not(.dream-skin-home-shell)::before {
background-image: var(--ds-task-fade), var(--ds-task-shade), var(--dream-skin-art);
}
/* 왼쪽 90% 불투명 → 오른쪽 0%로 열리는 장막 = 글자쪽만 진하게 덮음 */
--ds-hero-scrim: linear-gradient(90deg,
rgb(var(--ds-bg-rgb)/.90) 0%, rgb(var(--ds-bg-rgb)/.76) 50%,
rgb(var(--ds-bg-rgb)/.18) 84%, transparent 100%);
이미지의 초점 위치도 데이터로 잡는다 — theme.json의 art.focusX/Y(0~1)를 background-position %로 바꿔, 인물의 얼굴이 오른쪽 "안전지대"에 오도록 배치한다. 그래서 사실 이 프로젝트에는 별도의 "인물 그리기" 레이어가 없다 — 인물은 그냥 배경 이미지 한 장에 이미 들어 있고, CSS는 그걸 focusX≈0.72 + safeArea:"left"로 오른쪽에 놓아 Codex의 원래 글자·입력창이 왼쪽 여백에 얹히게 만들 뿐이다. 사이드바·입력창도 Codex의 원래 DOM을 반투명 색으로 다시 칠하는 정도다.
스킨이 Codex 설정(config.toml)에서 손대는 건 외형 키 2개뿐이지만, 그 최소 편집조차 사고 없이 하려고 theme-config.mjs는 세 겹의 방어를 건다. 이 부분이 "겉옷 주제에 안 어울리게 진지한" 이 저장소의 백미다.
여기에 엄격한 UTF-8 처리(Buffer.from(content).equals(bytes)로 인코딩 왕복 검증)까지 더해진다. Windows 쪽은 같은 걸 config-utf8.ps1로 옮겼는데, 최신 커밋(2026-07-17, #71)이 바로 "PowerShell 5.1에서 원자적 교체 지원"을 고친 것이다 — 이 방어를 얼마나 진지하게 여기는지 보여주는 대목이다.
① 앱 불변: 설치 파일·서명을 안 건드리고 CDP로 런타임에만 얹는다. ② 대상 검증: loopback·포트·경로 형태를 좁게 정의해 엉뚱한 창엔 주입 안 함. ③ 지속 주입: addScriptToEvaluateOnNewDocument + fs.watch로 재로드에도 깜빡임 없이 유지. ④ 완전 가역: 렌더러 cleanup() + 원자적 config 백업/복구로 클릭 한 번에 원복. 네 원칙 모두 "공식 앱을 부수지 않는 겉옷"이라는 목표에 직결된다.
저장소는 크지 않지만(추적 파일 133개) 규칙적이다. 뼈대는 같은 설계를 각자 재구현한 두 제품 — macos/(Bash+Node)와 windows/(PowerShell+Node) — 그리고 둘이 공유하는 docs/다. 아래는 "무엇을 먼저 읽어야 하는가" 관점의 지도다.
| 핵심 파일 | 역할 |
|---|---|
| scripts/injector.mjs | CDP 주입 엔진. 타깃 검증 → 페이로드 조립 → Runtime.evaluate + watch 모드. mac 891줄 / win 993줄. |
| assets/dream-skin.css | 테마의 얼굴. 배경 이미지 + scrim 그라데이션 + 라이트/다크 변수(1,079줄). |
| assets/renderer-inject.js | 렌더러 안에서 클래스·스타일·CSS 변수 주입 + 라이트/다크·라우트 감지 + Canvas 색 분석(786줄). |
| scripts/theme-config.mjs | 서드파티 config.toml 안전 패치 — 원자적 쓰기·신원검증·락(314줄). |
| scripts/tray-dream-skin.ps1 | Windows 트레이 관리 앱 — 순수 PowerShell WinForms(외부 의존성 0). |
| presets/generate-presets.mjs | 의존성 0으로 PNG 직접 인코딩해 프리셋 배경 생성(116줄). |
| SKILL.md ×2 | 에이전트용 절차서(설치→커스터마이즈→검증→복구). mac/win 각 1개. |
| docs/background-generation-prompts.md | AI로 UI 없는 배경을 만드는 정밀 프롬프트 8종 + 범용 템플릿. |
macos/와 windows/는 같은 설계도로 지은 쌍둥이 빌딩이다 — 층 구성(주입기·CSS·렌더러·설정 패처·관리 앱)이 똑같고, 자재만 다르다(Bash+Node vs PowerShell+Node). 그래서 한쪽을 이해하면 다른 쪽이 그대로 읽힌다. 공용 로비가 docs/이고, 특히 background-generation-prompts.md가 "어떤 이미지를 넣어야 이 UI에 어울리나"의 설명서다.
이 저장소의 최고 교재 가치. 원격 디버깅 포트로 Electron 앱을 켜고 → 웹소켓 타깃을 형태 검증하고 → Runtime.evaluate로 주입하고 → addScriptToEvaluateOnNewDocument로 재로드에 대비하고 → window.__…_STATE__의 cleanup으로 완전히 원복하는 흐름은, "가역적 런타임 스킨"의 정석 아키텍처다. 앱 바이너리·서명을 안 건드리므로 업데이트에도 강하다. 다른 Electron 앱(에디터·메신저)을 꾸미고 싶을 때 그대로 응용된다.
theme-config.mjs(314줄)는 그 자체로 하나의 마스터클래스다. ① 대상 테이블([desktop])만 다시 쓰고 여러 줄 문자열·배열·중복 키·심볼릭 링크는 거부, ② 임시 파일 + fs.rename의 원자적 쓰기, ③ lstat dev/ino 신원 확인 + 교체 직전 바이트 재검증, ④ 죽은 소유자를 kill(pid,0)으로 감지하는 디렉토리 락, 여기에 엄격한 UTF-8 왕복 검증까지. "남의 설정 파일을 안전하게 만지는" 모든 요령이 한 파일에 압축돼 있다.
generate-presets.mjs(116줄)는 외부 라이브러리 없이 PNG를 손으로 인코딩한다 — 자체 CRC32 테이블, IHDR/IDAT/IEND 청크, zlib.deflateSync. 여기에 밴딩을 없애는 자체 value-noise 디더링과 screen 블렌드로 은은한 오로라 배경을 결정적으로(byte-identical) 생성한다. 재실행해도 커밋된 에셋과 완전히 같아 diff가 안정적이고, 실사 이미지의 초상권 문제도 우회한다. "포맷을 이해하면 라이브러리 없이도 만든다"의 좋은 예.
주입된 렌더러가 브라우저 Canvas로 배경 이미지를 24색 구간으로 다운샘플해 대표 accent·휘도·초점·안전변(좌/우)을 추출하고, 그걸로 UI 팔레트를 자동 유도한다. 서버·업로드·API 키가 전혀 없어 프라이버시를 지키면서 "이미지 → 어울리는 테마"를 실현한다. 색 이론과 Canvas API를 실전에서 어떻게 엮는지 배우는 표본.
같은 도구를 사람이 더블클릭으로도, 에이전트가 스킬로도 쓰게 만든 이중 포장. SKILL.md의 YAML 머리말(name·description) + 절차 본문은 Anthropic/Claude 스킬 관례와 같은데, 이 저장소는 그걸 agents/openai.yaml로 Codex에 등록한다(.claude-plugin/marketplace.json은 없음 — Claude 플러그인이 아니라 Codex 스킬). "한 형식으로 여러 에이전트 생태계에 얹기"의 사례다.
저장된 PID·경로를 절대 그냥 믿지 않는다. 프로세스를 멈추거나 재사용하기 전에 PID + 실행 파일 + 명령줄 + 시작 시각(mac) 또는 패키지 신원(win)이 모두 일치해야만 진행한다. "PID는 재사용된다"는 함정을 아는 설계로, 어떤 데몬 관리자에게나 값진 패턴이다.
테마가 핑크든 오로라든, 남는 원칙은 보편적이다. CDP로 가역 주입하고, 서드파티 설정은 원자적·신원검증으로 고치고, 에셋은 의존성 없이 결정적으로 만들고, 색은 클라이언트에서 뽑고, 프로세스는 신원으로 검증하라. Electron 앱 하나라도 만져 본 사람이라면, 이 6가지가 "예쁜 화면"보다 훨씬 오래 남는 자산이다.
이 도구는 자기 앱이 아니라 이미 설치된 공식 Codex 데스크톱 앱에 얹히는 것이라, 요구사항의 절반은 "Codex가 먼저 있어야 한다"이다. 이미지 생성은 이 저장소가 하지 않으므로(§아래 주의) gpt-image 크레딧 같은 것도 이 도구 자체엔 필요 없다.
| 항목 | 요구/수치 |
|---|---|
| 대전제 | 공식 Codex 데스크톱 앱이 설치·최초 1회 실행돼 있을 것(그래야 ~/.codex/config.toml이 존재). mac=com.openai.codex 앱, win=Store OpenAI.Codex 패키지. |
| macOS | 전역 Node 불필요 — Codex가 품은 서명된 번들 Node.js ≥20을 서명·TeamID·아키텍처·버전 검증 후 재사용. ImageMagick·jq·Python 불필요. SwiftBar는 메뉴바용 선택. |
| Windows | Store OpenAI.Codex 패키지 + Node.js ≥22(PATH) + Windows PowerShell 5.1+. 관리자 권한 불필요. |
| 이미지 제약 | PNG/JPEG/HEIC/TIFF/WebP. 원본 ≤50MB, 준비본 ≤16MB·≤16384px/변·≤50MP. 권장 마스터 2560×1440(16:9), 폭 ≥2000. |
| 비용·키 | 유료 API 키·gpt-image 크레딧은 이 도구엔 불필요(배경 이미지는 사용자가 외부에서 준비). 유일한 상업적 언급은 후원사 Passion8이며 "테마와 API 설정은 서로 독립"이라 명시. |
| 안전 제약 | CDP는 127.0.0.1에만 바인딩. 테마 실행 중에는 출처 불명 로컬 프로그램 실행 자제 권장(디버그 포트는 무인증). 다 쓰면 Restore 권장. |
비유하면 이 도구는 이미 산 냉장고(공식 Codex) 위에 씌우는 맞춤 커버다. 냉장고가 없으면 커버도 의미가 없다(대전제=Codex 선설치). 커버 자체는 천 한 장이라 무겁지 않지만(전역 Node조차 앱 것을 빌려 씀), "어떤 무늬 천을 씌울지"(배경 이미지)는 당신이 밖에서 구해 와야 한다 — 저장소는 그 천을 만들어 주지 않고, 잘 어울리는 무늬를 뽑는 프롬프트만 알려 준다.
먼저 설치. 공식 Codex 데스크톱 앱이 이미 있다는 전제하에, macOS 기준 흐름이 가장 직관적이다.
# macOS — 저장소에서 설치 후 프리셋 적용
cd macos
./scripts/install-dream-skin-macos.sh --no-launch # ~/.codex/…에 설치
~/.codex/codex-dream-skin-studio/scripts/switch-theme-macos.sh --id preset-romantic-rose
# 이후 바탕화면의 "Codex Dream Skin.command" 더블클릭 → 스킨 켠 채 Codex 실행
# Windows
powershell -ExecutionPolicy Bypass -File .\windows\scripts\install-dream-skin.ps1
powershell -ExecutionPolicy Bypass -File .\windows\scripts\start-dream-skin.ps1
기본 프리셋(예: preset-midnight-aurora)을 적용해 Codex 창에 배경이 깔리는 걸 확인하고, 사이드바·입력창이 그대로 클릭되는지 눌러 본다. 그런 다음 Restore(복구)를 눌러 원래 화면으로 완전히 돌아오는지 확인한다. "얹었다 뗐다"가 되는 가역 스킨의 감을 잡는 게 목표.
16:9 이미지 한 장을 준비해 커스터마이즈(mac customize-theme-macos.sh / win 트레이 "更换背景图")로 넣는다. 렌더러가 이미지에서 뽑아낸 색으로 UI가 물드는지 관찰하고, 저장 후 트레이/메뉴바에서 프리셋과 내 테마를 오가며 전환해 본다. docs/background-generation-prompts.md의 프롬프트로 "UI 없는 배경"을 만들어 넣으면 더 잘 어울린다.
git clone --depth 1로 소스를 받아 macos/scripts/injector.mjs를 연다. 타깃 검증(validatedDebuggerUrl) → 페이로드 조립(loadPayload) → Runtime.evaluate → watch 모드가 §4-1 흐름도와 어떻게 대응되는지 짚어 본다. Chrome DevTools Protocol 문서에서 Runtime.evaluate·Page.addScriptToEvaluateOnNewDocument가 실제로 뭘 하는지도 찾아 읽는다.
theme-config.mjs에서 임시파일+fs.rename 원자적 쓰기, lstat dev/ino 신원 검증, 디렉토리 락이 각각 어떤 사고를 막는지 주석 없이 설명해 본다. "이 세 방어 중 하나를 빼면 어떤 나쁜 일이 생길까?"를 스스로 시나리오로 써 보면 이해가 깊어진다. Windows config-utf8.ps1의 최신 커밋(#71)이 왜 필요했는지도 추적.
presets/generate-presets.mjs를 읽고, CRC32·IDAT 청크·deflateSync로 PNG가 어떻게 바이트 단위로 조립되는지 이해한 뒤, 아주 작은(예: 8×8 단색) PNG를 직접 인코딩해 본다. 여유가 되면 renderer-inject.js의 24색 다운샘플 색분석을 별도 <canvas>에서 흉내 내, 임의 이미지의 대표 accent를 뽑아 본다. "포맷과 색이론을 알면 의존성이 필요 없다"를 몸으로 확인.
| 주차 | 주제 · 목표 |
|---|---|
| 1주차 | CDP 기본기. Chrome DevTools Protocol의 Runtime·Page 도메인, 원격 디버깅 포트, 웹소켓 세션. 목표: 아무 Electron 앱을 디버그 포트로 띄워 Runtime.evaluate로 document.title을 바꿔 보기. |
| 2주차 | Electron 앱 해부. 메인/렌더러 프로세스, app.asar 구조, 왜 CDP 주입이 바이너리 패치보다 안전한가. Codex 앱이 왜 웹 기술로 꾸며지는지 이해. |
| 3주차 | 안전한 파일 편집. 원자적 쓰기(temp+rename), 파일 신원(dev/ino), 락과 죽은 소유자 감지, 엄격한 UTF-8. theme-config.mjs를 다른 언어로 이식해 보며 체득. |
| 4주차 | 이미지·색 처리. PNG 포맷(청크·CRC·zlib), Canvas 다운샘플 색추출, 휘도·대비와 가독성(scrim). "이미지에서 어울리는 UI 색을 뽑는" 파이프라인을 직접 구현. |
| 5주차 | 에이전트 스킬 패키징. SKILL.md YAML 머리말·프로그레시브 디스클로저, agents/openai.yaml로 Codex에 등록, Claude 스킬과의 이식성. "내 도구를 에이전트가 실행하게" 만들기. |
| 용어 | 뜻 |
|---|---|
| Codex 데스크톱 앱 | OpenAI Codex의 GUI 앱(Electron/Chromium 기반). 터미널 codex CLI가 아님 — 이 스킨이 상대하는 대상. |
| CDP | Chrome DevTools Protocol. 원격 디버깅 포트로 크롬/Electron을 조종하는 규격. 이 도구의 "주입구". |
| 런타임 주입 | 앱 파일을 안 고치고, 실행 중인 창에 CSS·JS를 Runtime.evaluate로 밀어 넣어 겉모습을 바꾸는 방식. |
| renderer-inject.js | 렌더러 안에서 클래스·스타일·CSS 변수 주입, 라이트/다크·라우트 감지, Canvas 색분석을 수행하는 786줄 페이로드. |
| scrim | 배경 이미지 위에 겹치는 반투명 그라데이션 장막. 글자 쪽은 진하게 덮어 가독성 확보, 이미지 쪽은 열어 둠. |
| theme.json | 테마 데이터(JSON) — 색·이미지·초점(focusX/Y·safeArea)·밝기모드. 색 포맷은 TOML이 아니라 JSON. |
| watch 모드 | addScriptToEvaluateOnNewDocument + fs.watch로 재로드·이동에도 스킨이 깜빡임 없이 유지되게 하는 지속 주입. |
| 원자적 쓰기 | 임시 파일에 먼저 쓰고 fs.rename으로 교체 — 중간에 죽어도 원본이 반쯤 망가지지 않음. 설정 패처의 핵심. |
| 프로세스 신원 | PID만 믿지 않고 실행파일·명령줄·시작시각(또는 패키지 신원)까지 일치할 때만 프로세스를 멈춤/재사용. |
| SKILL.md · Agent Skill | YAML 머리말(name/description)+절차 본문으로 된 에이전트용 스킬 문서. 여기선 agents/openai.yaml로 Codex에 등록. |
| NOTICE.md | 실존 인물(桥本有菜) 이미지를 MIT에서 제외하고 재배포·상업이용 전 권리 검토를 요구하는 고지 파일. |
| 智商税(즈샹수이) | "호갱 상술". 闲鱼에서 Codex 스킨을 유료로 팔던 것을 겨냥 — 이 저장소가 무료 오픈소스로 대체한 배경. |
공식
· GitHub 저장소: github.com/Fei-Away/Codex-Dream-Skin (MIT © 2026 · v1.2.0 · ★5.2k · GitHub 언어=Shell)
· TrendShift 카드: trendshift.io/repositories/84043 (Daily #2 · #AI skills)
· 설치: 저장소 클론 후 macos/scripts/install-dream-skin-macos.sh 또는 windows/scripts/install-dream-skin.ps1
저장소 안에서 꼭 읽을 것
· macos/scripts/injector.mjs — CDP 주입 엔진(타깃 검증·페이로드·watch)
· macos/scripts/theme-config.mjs — 서드파티 설정 안전 패치(원자적·신원검증·락)
· macos/assets/dream-skin.css · renderer-inject.js — 테마 CSS + 렌더러 주입/색분석
· macos/presets/generate-presets.mjs — 의존성 0 PNG 인코더
· macos/SKILL.md · windows/SKILL.md — 에이전트 절차서 + agents/openai.yaml 등록
· docs/background-generation-prompts.md — UI 없는 배경을 만드는 AI 프롬프트 8종
곁들여 학습
· Chrome DevTools Protocol 문서 — Runtime·Page 도메인
· Electron 앱 구조(메인/렌더러·app.asar)와 안전한 커스터마이즈
· PNG 포맷(청크·CRC32·zlib) · Canvas 색추출 · CSS 그라데이션/가독성
· Agent Skill(SKILL.md) 패키징 — Codex(agents/openai.yaml) vs Claude Code 이식성
· 이미 분석한 다른 Claude/Codex 스킬 딥다이브들과 비교(§인덱스 cat-claude-skills)
① 이 도구는 비공식이며 OpenAI 제품이 아니다 — Codex가 DOM 클래스명을 바꾸는 업데이트를 하면 선택자가 어긋날 수 있어, 업데이트 후 재설치가 필요할 수 있다(다만 앱은 안 부수므로 최악이 "배경 어긋남"). ② 원격 디버그 포트는 무인증이라 127.0.0.1에만 열지만, 테마 실행 중 출처 불명 로컬 프로그램 실행은 자제하고 다 쓰면 Restore를 권장한다. ③ 기본 프리셋·홍보의 실존 인물·유명 IP 이미지는 MIT에서 제외돼 있어(NOTICE.md) 재배포·상업 이용 전 초상권·상표권을 반드시 확인해야 한다. ④ 이미지 생성은 이 저장소가 하지 않는다(외부 gpt-image 등으로 준비). ⑤ 이 문서 수치는 분석 시점 최신 커밋(2026-07-17, c6118a7) 기준이며, 트렌딩 특성상 순위·지표는 계속 바뀐다.