19k+ 스타. OpenAI Codex 앱의 회의 삭제 버튼·플러그인 잠금 해제 같은 불편을 외부 launcher 한 개로 해결한다. app.asar를 패치하지 않는다. Chromium DevTools Protocol(원격 디버깅 포트 9229)로 렌더러 프로세스에 스크립트를 주입하는 방식 — Codex 앱은 자신이 변형됐다는 사실조차 모른다. 초기 Python 묘수에서 Rust + Tauri로 전면 재작성된 데스크탑 도구.
CLI 도구가 아니라 OpenAI가 만든 데스크탑 GUI 앱이다.
흔히 말하는 Codex는 두 가지다 — 하나는 터미널에서 쓰는 codex CLI(VS Code Copilot CLI 같은 것), 다른 하나는 OpenAI가 2025년 후반부터 배포한 Codex 데스크탑 GUI 앱이다. CodexPlusPlus가 향상하려는 대상은 후자, 즉 데스크탑 GUI 앱이다.
Electron 앱은 메인 프로세스(Node.js)와 렌더러 프로세스(Chromium)로 나뉜다. 렌더러는 사실상 우리가 매일 보는 브라우저 탭이다 — DOM이 있고, JavaScript가 돌고, CSS로 스타일링된다. 즉 웹페이지를 향상시키는 방법(자바스크립트 주입, DOM 조작)이 그대로 통한다. 이게 CodexPlusPlus가 가능한 이유다.
"외부에서 Codex를 살짝 들춰서 화면만 살짝 고친다."
Codex 앱의 회의 목록에 삭제 버튼이 없고, API Key 사용자에게는 플러그인 입구가 잠겨 있는 두 가지 불편을 해결한다. 핵심 트릭 — Codex를 평소처럼 실행하지 않고 --remote-debugging-port=9229 옵션을 붙여 실행한 뒤, 그 포트로 들어가서 렌더러 화면에 renderer-inject.js를 슬쩍 주입한다.
설치 디렉토리에 DLL을 던지지도, app.asar를 패치하지도 않는다. Codex 자체는 "원본 그대로". 그래서 Codex가 자동 업데이트돼도 깨지지 않을 가능성이 크다.
실용적 불편함의 해결 + 우아한 비침습 설계 + 중국 커뮤니티 영향력의 3박자.
2026년 5월 기준 TrendShift 15위까지 오른 이유는 단순한 기능 그 이상이다. 비슷한 시기에 또 다른 codex-plusplus(b-nnett 작품, TrendShift 19위에서 별도 분석됨)가 있는데, 그 쪽은 app.asar를 직접 패치하고 SHA-256 무결성을 우회하는 더 공격적인 접근이다. CodexPlusPlus(BigPizzaV3)는 같은 문제에 정반대 답을 낸다.
Electron 앱의 코드는 보통 app.asar라는 가상 아카이브에 묶여 있다. b-nnett 식 접근은 그 아카이브를 풀어서 코드를 바꾸고 다시 묶는다. CodexPlusPlus는 아카이브를 절대 만지지 않는다. 외부 launcher가 Codex를 디버그 모드로 실행하고, 살아있는 렌더러에 스크립트만 주입한다. Codex가 업데이트돼도 launcher는 영향 없다.
Codex 데스크탑의 플러그인 입구는 ChatGPT 로그인이 필요하다고 안내한다. API Key만으로 쓰는 개발자(즉, 자기 OpenAI 계정에서 사용량을 따로 결제하는 사람)는 플러그인을 못 쓴다. CodexPlusPlus는 그 입구를 강제로 활성화해 API Key 모드에서도 플러그인을 쓸 수 있게 한다.
네이티브 Codex 앱은 "보관(Archive)"만 있고 삭제 옵션이 없다. CodexPlusPlus는 회의 목록의 항목에 hover 시 삭제 버튼을 노출하고, 클릭하면 (1) 서버사이드 삭제를 먼저 시도, (2) 안 되면 로컬 SQLite(~/.codex/state_5.sqlite)에서 직접 레코드를 삭제, (3) 삭제 전 백업해서 실행 취소까지 지원한다.
상단 메뉴 바에 Codex++ 항목이 추가되고, 클릭하면 설정 패널이 뜬다. 3가지 토글 — ① 플러그인 옵션 잠금 해제, ② 특수 플러그인 강제 설치, ③ 회의 삭제 — 을 켜고 끄며 사용한다. Windows 단축키 설치/제거, macOS 앱 번들(/Applications/Codex++.app) 자동 생성도 지원.
본인의 게임 콘솔을 해킹하지 않고, 화면 위에 투명 오버레이를 띄워 게임에 없는 정보를 보여주는 외부 도구를 생각해 보자. 게임 ROM은 원본 그대로다. ROM이 업데이트돼도 오버레이만 다시 맞추면 된다. CodexPlusPlus의 철학이 정확히 그것이다 — Codex의 ROM(app.asar)은 절대 안 만지고, 화면 위에 추가 UI만 띄운다.
Rust Cargo workspace + TypeScript/React(Tauri 관리 도구) + JavaScript(renderer-inject.js) + Chromium DevTools Protocol.
초기 Python 구현에서 Rust 기반으로 전면 재작성됐다. Cargo.toml(workspace root)의 주요 크레이트는 다음과 같다.
관리 도구(Codex++ Manager)는 apps/codex-plus-manager에 있으며, Tauri 2 + React 19 + TypeScript로 구현된 GUI 앱이다. 설치·제거·업데이트·설정·로그·진단 기능을 제공하는 독립 애플리케이션으로, macOS에서는 런처 앱(Codex++.app)과 관리 도구(Codex++ 관리 도구.app) 두 개가 별도로 설치된다.
--remote-debugging-port=9229로 띄우면 그 대화가 외부에 노출된다. Puppeteer·Playwright·Selenium 같은 자동화 도구가 다 이 위에서 돌아간다.Codex 앱은 Electron(=Chromium 임베드) 위에 만들어졌으니까, Codex 본체에 디버그 포트만 열면 외부에서 CDP로 들어가서 "이 페이지에 이 JavaScript를 실행해 줘" 같은 명령을 던질 수 있다. Runtime.evaluate, Page.addScriptToEvaluateOnNewDocument 같은 CDP 메서드들이 그 일을 해준다.
주입한 스크립트가 곧바로 fetch('http://localhost:57321/...')를 부르면 Codex 페이지의 Content-Security-Policy(CSP)가 막을 가능성이 크다. CodexPlusPlus는 이를 우회하기 위해 CDP bridge 패턴을 쓴다.
렌더러 JS는 네트워크 요청을 직접 하지 않는다. 대신 특별한 형식의 로그를 찍거나 전역 변수를 쓰고, Rust launcher가 CDP로 그것을 읽어서 실제 HTTP 요청을 대신 보낸다(tokio 비동기 런타임 기반). 응답이 오면 Runtime.evaluate로 결과를 다시 렌더러에 주입한다. 네트워크는 launcher 프로세스가 책임지고, 렌더러는 함수 호출처럼 보이는 인터페이스만 본다.
서버사이드 삭제 API가 (1) 없거나 (2) API Key 모드에서 막혀 있으면, CodexPlusPlus는 Codex의 로컬 데이터베이스를 직접 건드린다.
| 위치 | 역할 |
|---|---|
~/.codex/state_5.sqlite | Codex가 회의 목록·상태·이력을 저장하는 SQLite DB |
~/.codex-session-delete/backups/ | 삭제 전 백업 — 실행 취소가 가능한 이유 |
~/.codex-session-delete/launcher.log | 숨겨진 시작 실패 로그 |
Codex 앱이 실행 중일 때 SQLite를 동시에 쓰면 락(lock) 충돌이 날 수 있다. CodexPlusPlus는 crates/codex-plus-data/src/storage.rs에서 rusqlite 기반 트랜잭션/락 처리를 하지만, Codex 앱 측이 스키마를 바꾸면(state_5가 state_6이 되거나) 이 코드가 깨진다. 그래서 "Codex 자체가 업데이트되면 storage 크레이트도 같이 손봐야 한다"는 한계가 있다.
사용자가 별도 런타임(Python 등)을 설치하지 않아도 된다. GitHub Releases에서 플랫폼별 설치 파일을 내려받아 실행하면 끝이다.
CodexPlusPlus-*-windows-x64-setup.exe NSIS 인스톨러 — 실행하면 Codex++ 런처와 관리 도구가 함께 설치된다. scripts/installer/windows/에 빌드 스크립트가 있다.CodexPlusPlus-*-macos-*.dmg — 드래그 앤 드롭으로 /Applications/에 설치. Codex++.app(런처)와 Codex++ 관리 도구.app(Manager) 두 앱이 별도로 설치된다.Rust launcher → CDP → 렌더러 → CDP bridge → Rust bridge → Tauri Manager의 협업.
이 프로젝트는 핵심 컴포넌트가 정확히 어떻게 협력하는지가 전부다. 그림으로 보자.
Codex 설치 디렉토리에 단 한 바이트도 쓰지 않는다. Rust launcher 바이너리와 inject 스크립트는 모두 ~/.codex-session-delete/와 사용자 홈 디렉토리에만 산다. Codex가 자동 업데이트돼도 launcher는 다음 실행 시 새 Codex.exe를 그대로 인자만 붙여서 띄울 뿐이다. 결합도가 "프로세스 인자 + 페이지 DOM 셀렉터" 두 곳으로 좁아져서 깨지는 표면적이 작다.
일반적인 자바스크립트 주입은 페이지의 CSP에 막힌다. 즉, Content-Security-Policy: connect-src 'self'면 외부 localhost로 fetch가 안 된다. CodexPlusPlus는 "네트워크 호출을 console.log로 둔갑시켜서 Rust launcher가 대신 한다"는 우회로 이 문제를 푼다. 페이지 측에서는 그저 콘솔에 로그를 찍을 뿐이고, 어떤 외부 출처도 호출하지 않으니 CSP는 발동하지 않는다.
학교에서 "수업 중 휴대폰 사용 금지"라는 규칙이 있을 때, 학생이 직접 통화하면 걸리지만 옆자리 친구한테 종이쪽지로 부탁하면 안 걸린다. 친구는 쉬는 시간에 대신 전화를 걸어 준다. CDP bridge가 그 쪽지 시스템이다 — 렌더러(학생)는 규칙을 어기지 않고, 외부 프로세스(친구)가 대신 행동한다.
SQLite 레코드를 지우기 전에 항상 백업한다(crates/codex-plus-data/src/backup.rs). ~/.codex-session-delete/backups/<timestamp>_<session-id>.json 형식으로 원본 행 전체를 JSON으로 떠 놓는다. UI에서 "삭제 직후 5초간 실행 취소" 토스트가 뜨는 것은 이 백업 덕분이다.
Rust Cargo workspace — 2개 crate + 2개 앱 + JS 인젝션 스크립트.
| 파일 / 모듈 | 책임 |
|---|---|
apps/codex-plus-launcher/src/main.rs | CLI 진입점. launch 명령 처리 — launcher.rs를 호출해 Codex를 디버그 모드로 실행. |
crates/codex-plus-core/src/launcher.rs | 모든 컴포넌트를 한 자리에 모은다. 포트 확인, bridge 시동, Codex 프로세스 spawn, CDP 연결 대기, 인젝션 트리거. |
crates/codex-plus-core/src/cdp.rs | tokio-tungstenite로 CDP 엔드포인트와 대화. Runtime.evaluate, Page.addScriptToEvaluateOnNewDocument, Console.messageAdded 등 핵심 메서드 래핑. |
crates/codex-plus-core/src/bridge.rs | Rust 내장 HTTP bridge. 127.0.0.1 바인딩. 회의 삭제·실행 취소 요청을 렌더러 대신 처리(CSP 우회). |
crates/codex-plus-core/src/storage_adapter.rs | Codex의 SQLite 파일을 안전하게 열고 닫는다. rusqlite 기반 트랜잭션·동시성 처리. |
crates/codex-plus-data/src/backup.rs | 삭제 전 원본 행 전체를 JSON으로 백업. 실행 취소 시 복구 경로 제공. |
assets/inject/renderer-inject.js | DOM 감시 → 회의 목록에 hover 시 삭제 버튼 추가 → 상단 메뉴 바에 Codex++ 항목 추가 → 플러그인 잠금 해제. 이 한 파일이 사용자 눈에 보이는 모든 변화의 출처. |
apps/codex-plus-manager/ | Tauri 2 + React 19 GUI 관리 도구. 설치·제거·업데이트·설정·로그·진단 기능. macOS에서는 별도 앱으로 설치. |
데스크탑 자동화·CDP·CSP 우회·SQLite 조작·OS별 설치자.
이 프로젝트의 핵심 학습 자산이다. Puppeteer/Playwright 같은 라이브러리 없이 tokio-tungstenite만으로 CDP를 직접 다루는 Rust 코드가 300줄 내외다. CDP 공식 문서(chromedevtools.github.io/devtools-protocol/)와 crates/codex-plus-core/src/cdp.rs를 나란히 놓고 읽으면 자동화 도구들의 내부가 보인다.
cdp.rs의 WebSocket 연결 부분을 참고해 다른 Electron 앱(Discord, Slack)에 같은 방식으로 디버그 포트를 열고 DOM에 빨간 테두리를 그리는 Rust 미니 프로그램을 만들어 보자.주입한 스크립트가 CSP에 막힐 때 console.log를 통신 채널로 둔갑시키는 패턴은 그대로 다른 곳에도 쓰인다. 예를 들어 회사 보안이 강한 SaaS의 페이지에 외부 데이터를 끌어오고 싶을 때, 같은 트릭이 활용된다(허가된 범위 안에서).
crates/codex-plus-data/src/backup.rs의 "삭제 전 무조건 백업, 실행 취소 시 백업으로 복구" 패턴은 어떤 종류의 위험한 작업에도 일반화 가능한 안전망이다. Git의 --soft reset, macOS의 휴지통도 같은 원리.
apps/codex-plus-manager는 Tauri 2 + React 19 + TypeScript의 실전 예제다. Rust 백엔드와 React 프론트엔드가 Tauri IPC로 통신하는 패턴, NSIS(Windows) / DMG(macOS) 인스톨러 빌드 파이프라인을 직접 참고할 수 있다. Electron 대비 바이너리 크기와 메모리 사용량을 비교해 보는 것도 좋은 학습이다.
같은 문제(Codex 향상)에 두 방향의 답이 있다. b-nnett는 ROM 패치, BigPizzaV3는 외부 오버레이. 업데이트 안정성·재배포 난이도·기능 완전성의 트레이드오프를 코드 두 개를 비교하면서 배우는 것은 흔치 않은 기회다.
Codex 앱이 깔린 Windows 또는 macOS. 별도 런타임 불필요 — GitHub Releases 바이너리 설치.
| 항목 | 요구 |
|---|---|
| OS | Windows 10/11 또는 macOS Intel/ARM (Linux 미지원 — Codex 데스크탑 자체가 미배포) |
| 설치 방법 | GitHub Releases에서 플랫폼별 설치 파일 다운로드 후 실행. Windows: CodexPlusPlus-*-windows-x64-setup.exe / macOS: CodexPlusPlus-*-macos-*.dmg. 별도 런타임(Python·Node 등) 불필요. |
| Codex App | 설치돼 있어야 함. 자동 탐색 경로: /Applications/Codex.app, /Applications/OpenAI Codex.app(macOS), C:\Program Files\WindowsApps\OpenAI.Codex_xxx\app(Windows) |
| 포트 | 9229(디버그) + bridge 포트 기본값 — 충돌 시 설정에서 변경 가능 |
| 저장 공간 | 설치 파일 포함 수십 MB (Rust 바이너리 + Tauri Manager) |
난이도별로 정리.
CodexPlusPlus-*-windows-x64-setup.exe 또는 macOS DMG)을 내려받아 실행. Codex 앱에 Codex++ 메뉴가 뜨는지 확인.--remote-debugging-port=9229로 직접 실행하고, 브라우저에서 http://localhost:9229에 접속해서 어떤 페이지가 보이는지 관찰.bridge.rs에 새 엔드포인트를 추가한다.git clone 후 cargo build --release로 빌드. Rust 컴파일 경고와 크레이트 의존성 해소 과정을 살펴본다. apps/codex-plus-manager는 npm install && npm run tauri build로 별도 빌드.3주 코스로 정리.
example.com 에서 모든 링크 텍스트를 console.log 가로채기로 수집launcher.rs → cdp.rs → bridge.rs 순으로 코드 읽기renderer-inject.js 브레이크포인트 디버깅 — Codex 앱을 디버그 모드로 띄우고 DevTools에서 변수 inspectcrates/codex-plus-data/src/backup.rs·storage.rs의 SQLite 트랜잭션 코드와 백업 전략 분석이 프로젝트를 이해하는 데 필요한 용어들.
--remote-debugging-port=N 옵션으로 N 포트에 노출시킨다. Puppeteer·Playwright의 기반..sqlite)에 데이터를 저장한다. Electron 앱들이 로컬 데이터(설정·캐시·세션)를 저장할 때 자주 쓴다./Applications/Codex.app 또는 OpenAI Codex.app가 있는지, Windows는 시작 메뉴에서 검색.CodexPlusPlus-*-windows-x64-setup.exe / macOS: CodexPlusPlus-*-macos-*.dmg./Applications/에 드래그. Codex++ 런처와 관리 도구(Manager)가 함께 설치된다.Codex++ 항목이 추가돼 있어야 한다.