TrendShift 딥다이브 · 2026-07-02

Codex Plugin for Claude Code 딥다이브
— 경쟁사 CLI를 내 CLI 안으로 불러들이는 공식 다리

codex-plugin-ccOpenAI가 직접 만들어 배포한 Claude Code 플러그인이다. Claude Code 안에서 /codex:review·/codex:rescue 같은 슬래시 커맨드 몇 개만 치면, 로컬에 이미 설치된 OpenAI Codex를 불러와 코드 리뷰를 맡기거나 버그 조사·수정 같은 작업 자체를 통째로 위임할 수 있다. 별도 런타임이나 별도 로그인은 없다 — 같은 Codex 설치, 같은 로컬 인증, 같은 레포 체크아웃을 그대로 쓴다. 내부적으로는 Claude Code 플러그인 규격(marketplace·commands·subagent·hooks)과 codex app-server(JSON-RPC 프로토콜)를 잇는 Node.js 브로커로 동작한다. (저장소: openai/codex-plugin-cc · Apache-2.0 · JavaScript 100% · 최신 버전 v1.0.5 · TrendShift Daily 13위)
목차
  1. 프로젝트 한줄 요약
  2. 왜 주목받는가
  3. 기술 스택 전체 지도
  4. 아키텍처 심화 분석
  5. 디렉토리 구조 해부
  6. 학습 포인트 (기술별)
  7. 하드웨어 / 시스템 요구사항
  8. 직접 해볼 수 있는 실습 과제
  9. 관련 기술 심화 학습 로드맵
  10. 핵심 키워드 사전
  11. 참고 링크

1프로젝트 한줄 요약

이 저장소가 대체 무엇인가.

핵심 메시지

"경쟁사 AI를 내 AI 도구 안에 정식으로 초대장 보내기" — Claude Code의 플러그인 규격을 빌려, 로컬 Codex를 슬래시 커맨드 몇 개로 호출하는 얇은 연결 다리.

어떤 회사에 두 개의 사내 메신저(A사·B사)가 동시에 깔려 있다고 생각해 보자. 보통은 둘 중 하나만 골라 써야 하고, 다른 팀과 협업하려면 메신저를 옮겨 다녀야 한다. 그런데 만약 B사가 직접 나서서 "우리 메신저 기능을 A사 메신저 안에서도 버튼 하나로 쓸 수 있게" 공식 확장 프로그램을 만들어 배포한다면 어떨까. codex-plugin-cc가 정확히 이런 물건이다 — Codex를 만든 OpenAI가, 경쟁사 Anthropic의 도구인 Claude Code 안에서 자기네 Codex를 자연스럽게 부를 수 있는 공식 다리를 놓았다.

비유하면: Claude Code = 내가 매일 쓰는 작업 데스크, Codex = 옆 팀에 있는 다른 전문가, 이 플러그인 = 데스크에서 벨을 누르면 그 전문가가 바로 와서 코드를 검토해 주거나 대신 일을 처리해 주는 내선 전화. 자리를 옮길 필요도, 새 계정을 팔 필요도 없다 — 이미 내 컴퓨터에 설치된 Codex를 그대로 불러 쓴다.

package.json의 description은 이렇게 딱 한 줄이다: "Use Codex from Claude Code to review code or delegate tasks." 실제로 레포를 열어 보면 이 한 줄이 과장이 아니다. Claude Code의 공식 플러그인 규격(.claude-plugin/marketplace.json·commands/*.md·agents/*.md·hooks/hooks.json·skills/)을 정석대로 따르는 하나의 완결된 플러그인이며, 그 안에서 실제 작업은 Node.js 스크립트가 로컬 codex CLI를 자식 프로세스로 띄워 JSON-RPC로 대화하는 방식으로 처리된다.

제공하는 슬래시 커맨드는 총 8개다: /codex:review(읽기전용 일반 리뷰), /codex:adversarial-review(설계·트레이드오프에 도전하는 조종형 리뷰), /codex:rescue(버그 조사·수정·작업 위임), /codex:transfer(현재 Claude Code 세션을 재개 가능한 Codex 스레드로 변환 — 브리프에는 없던 커맨드), /codex:status·/codex:result·/codex:cancel(백그라운드 잡 관리), /codex:setup(설치·인증 점검 + 선택적 리뷰 게이트 토글). 여기에 /agents에 등록되는 codex:codex-rescue 서브에이전트와, 그 서브에이전트 전용으로 잠긴 3개의 내부 스킬(codex-cli-runtime·codex-result-handling·gpt-5-4-prompting)이 딸려 있다.

용어
위임(Delegate) vs 리뷰(Review)
이 플러그인이 반복해서 구분하는 두 가지 모드다. 리뷰(/codex:review, /codex:adversarial-review)는 코드를 고치지 않고 "이 코드 어때?"만 진단하는 읽기전용 작업이다. 위임(/codex:rescue)은 "이 버그를 대신 조사하고 고쳐 줘"처럼 실제 쓰기 작업을 Codex에게 넘기는 것이다. 두 모드는 코드 상으로도 완전히 분리돼 있다 — 리뷰 계열은 allowed-tools에 파일 수정 도구가 없고, rescue 서브에이전트는 기본값이 --write(쓰기 가능)로 설정된다.

2왜 주목받는가

경쟁사가 만든 공식 플러그인이라는 상징성 · 단독 Codex CLI 대비 이점 · 멀티-에이전트 협업의 실물 사례.

이 저장소가 TrendShift에서 주목받는 진짜 이유는 기능 목록이 화려해서가 아니다. OpenAI라는 이름이 저장소 소유자(owner)에 박혀 있고, 그 회사가 만든 도구(Codex)를 경쟁사 Anthropic의 제품(Claude Code) 안에서 쓰기 좋게 만드는 통합 플러그인을 직접, 공식적으로 배포했다는 사실 자체가 이례적이다. 보통 이런 "타사 도구 연동"은 커뮤니티가 리버스 엔지니어링해서 만들거나, 아예 존재하지 않는 경우가 많다. OpenAI가 스스로 Claude Code의 플러그인 API(marketplace·슬래시 커맨드·서브에이전트·훅)를 배워 자사 CLI를 얹었다는 것은, "사용자가 이미 있는 워크플로를 떠나지 않게 하는 것"이 경쟁 우위보다 우선한다는 실용적 신호로 읽힌다.

단독 Codex CLI를 그냥 쓰는 것과 무엇이 다른가

비교 축터미널에서 codex 직접 실행codex-plugin-cc로 Claude Code 안에서
컨텍스트 전환Claude Code 창 ↔ 별도 터미널을 오가야 함한 창 안에서 슬래시 커맨드로 바로 호출
세션 연속성Claude와 대화한 맥락을 Codex가 모름/codex:transfer현재 Claude 세션을 Codex 스레드로 이관 가능
백그라운드 관리별도 터미널 탭·프로세스 관리 필요/codex:status·/codex:result·/codex:cancelClaude Code 잡 시스템에 통합
리뷰 자동화수동으로 언제 돌릴지 챙겨야 함선택적 Stop 훅 리뷰 게이트로 세션 종료 시점에 자동 검문 가능
재사용 비용매번 CLI를 새로 기동브로커 프로세스codex app-server 연결을 재사용해 반복 호출이 가벼움
학습 곡선Codex CLI 고유 명령·플래그를 새로 익혀야 함Claude Code에서 이미 쓰던 슬래시 커맨드 패턴 그대로
주목 포인트 — 진짜로 "같은 Codex"를 쓴다
별도 런타임 없음, 로컬 인증·설정 그대로 재사용

README의 FAQ는 이 질문에 명확히 답한다: "Does the plugin use a separate Codex runtime? No." 이 플러그인은 새로운 실행 환경을 만들지 않는다. 사용자 컴퓨터에 이미 설치된 전역 codex 바이너리, 이미 로그인된 인증 상태, 이미 체크아웃된 같은 레포를 그대로 사용한다. 설정도 ~/.codex/config.toml(사용자 전역)과 .codex/config.toml(프로젝트별, trusted일 때만)을 계층적으로 읽어 Codex를 터미널에서 직접 쓸 때와 완전히 동일한 동작을 보장한다. "래핑"이라는 단어가 과장이 아니라는 뜻이다.

기대치 조정 — 리뷰 게이트는 양날의 검
"can create a long-running Claude/Codex loop and may drain usage limits quickly"

README는 리뷰 게이트 기능에 직접 경고 문구(⚠️ WARNING)를 달아 둔다. /codex:setup --enable-review-gate를 켜면, Claude가 응답을 마칠 때마다(Stop 이벤트) 자동으로 Codex 리뷰가 돌고, 문제가 발견되면 세션 종료 자체를 막아 Claude가 먼저 고치게 만든다. 편리하지만 Claude가 고치고 → Codex가 다시 걸고 → 또 고치는 루프가 길어질 수 있고, 두 AI를 번갈아 돌리는 만큼 사용량(usage limit)도 평소보다 빠르게 소진된다. "적극적으로 지켜볼 계획일 때만 켜라"는 저자들의 조언이 붙어 있다.

멀티-에이전트 협업의 실물 사례
"에이전트가 에이전트를 도구로 부른다"

이 레포는 요즘 자주 언급되는 크로스벤더 멀티-에이전트 협업 패턴을 코드로 확인할 수 있는 드문 공개 사례다. Claude(오케스트레이터 역할)가 codex:codex-rescue라는 서브에이전트를 통해 Codex(실행자 역할)를 도구처럼 호출하고, 결과를 그대로 사용자에게 돌려준다. 두 회사의 서로 다른 모델이 "리뷰어와 구현자", "1차 의견과 2차 의견"처럼 역할을 나눠 협업하는 구조를, README의 데모 영상 하나 없이도 소스 코드 레벨에서 그대로 뜯어볼 수 있다.

3기술 스택 전체 지도

Claude Code 플러그인 규격 + Codex CLI/app-server + Node.js 브로커 + 인증 위임 구조.

이 레포의 스택은 화려한 프레임워크가 아니라 "두 개의 서로 다른 CLI 생태계를 잇는 접착제"에 가깝다. 순수 JavaScript(ESM, type: "module") + Node.js 내장 모듈만으로 짜여 있고, 런타임 의존성이 0개다(package.jsondependencies 항목 자체가 없다 — devDependencies에 TypeScript 타입 체크용 도구만 있다). 대신 그 자리를 Claude Code 플러그인 규격Codex app-server 프로토콜이라는 두 개의 "외부 계약"이 채운다.

레이어기술 / 규격역할
플러그인 마켓플레이스.claude-plugin/marketplace.jsonClaude Code에 "이 저장소가 플러그인을 배포한다"고 선언. /plugin marketplace add가 읽는 진입점
플러그인 매니페스트plugins/codex/.claude-plugin/plugin.json플러그인 이름·버전·설명. ${CLAUDE_PLUGIN_ROOT} 환경변수의 기준점이 됨
슬래시 커맨드commands/*.md (frontmatter + 지시문)8개 커맨드 정의. YAML frontmatter로 allowed-tools·인자 힌트 등을 선언
서브에이전트agents/codex-rescue.md/agents에 노출되는 독립 에이전트. 전용 스킬 2개만 장착한 "얇은 전달자"
훅(Hooks)hooks/hooks.jsonSessionStart·SessionEnd·Stop 세 이벤트에 스크립트 연결
내부 전용 스킬skills/*/SKILL.md (user-invocable: false)사용자가 직접 못 부르고, 서브에이전트 안에서만 참조되는 "내부 계약서" 3종
런타임Node.js ≥ 18.18.0 (ESM, node --test)스크립트 실행 + 자체 테스트 러너. 외부 프레임워크 없음
대상 CLIcodex (전역 설치된 OpenAI Codex CLI)이 플러그인이 감싸는 실제 작업자. codex app-server 서브커맨드가 핵심
통신 프로토콜JSON-RPC (line-delimited)Node 스크립트 ↔ codex app-server 사이의 대화 방식. initialize/initialized 핸드셰이크
프로세스 간 통신Unix 도메인 소켓 / Windows 네임드 파이프브로커 프로세스가 여는 로컬 소켓. 여러 커맨드 호출이 하나의 app-server 연결을 공유
타입 검증TypeScript (JSDoc 기반) + tsc런타임엔 JS만 돌지만, .d.ts로 app-server 프로토콜 타입을 체크
인증ChatGPT 구독 또는 OpenAI API 키 (로컬 위임)플러그인이 자체 인증을 만들지 않고, 이미 로그인된 codex CLI의 인증을 그대로 사용
설정 계층config.toml (user + project)~/.codex/config.toml.codex/config.toml(trusted 프로젝트만) 순으로 병합
용어
app server (Codex 앱 서버)
codex app-server는 Codex CLI가 제공하는 별도 실행 모드로, 터미널 대화형 UI 대신 JSON-RPC로 요청·응답을 주고받는 백엔드 프로세스로 동작한다. 사람이 아니라 다른 프로그램(이 플러그인 같은)이 Codex를 프로그래밍적으로 조종할 수 있게 열어 둔 문이다. VS Code 확장이 tsserver를 자식 프로세스로 띄우고 JSON으로 대화하는 것과 같은 패턴이라고 생각하면 이해가 쉽다.
용어
인증 위임 (Delegated Authentication)
이 플러그인은 로그인 화면도, API 키 입력창도 만들지 않는다. 대신 "이미 로컬에 설치되고 로그인된 codex CLI가 있다"는 전제 위에서, 그 CLI가 들고 있는 인증 토큰을 그대로 빌려 쓴다. codex-companion.mjs는 매 명령 실행 전 getCodexAvailability()·getCodexAuthStatus()로 "codex가 설치돼 있고 로그인돼 있는가"만 확인할 뿐, 인증 로직 자체를 재구현하지 않는다. 덕분에 API 키가 플러그인 코드나 로그에 노출될 일이 구조적으로 없다.

4아키텍처 심화 분석

/codex:review 입력 한 번이 브로커 → app-server → 백그라운드 잡까지 흐르는 전체 경로 + Stop 훅 리뷰 게이트 루프.

이 플러그인의 핵심 설계는 한 문장으로 요약된다: "슬래시 커맨드는 얇은 지시문일 뿐, 진짜 로직은 전부 codex-companion.mjs라는 하나의 Node 스크립트에 모여 있다." 커맨드 파일(commands/*.md)들은 판단·분기를 거의 하지 않고, 대부분 이 한 줄로 수렴한다.

// commands/review.md 안의 실제 실행 지시문
node "${CLAUDE_PLUGIN_ROOT}/scripts/codex-companion.mjs" review "$ARGUMENTS"

즉 Claude Code는 "이 명령을 실행하고 결과를 그대로 사용자에게 보여줘"라는 오케스트레이션만 맡고, 인자 파싱·Codex 호출·잡 상태 관리·결과 포매팅은 전부 스크립트 쪽 책임이다. 이 구조 덕분에 8개 커맨드가 하나의 런타임(codex-companion.mjs 1,073줄 + lib/codex.mjs 1,219줄)을 공유한다.

① 전체 흐름 — /codex:review 한 번이 지나가는 길

사용자: /codex:review --background │ ▼ ① Claude Code가 commands/review.md의 지시문을 읽음 "--background가 있으니 묻지 않고 백그라운드로 실행" │ ▼ ② Bash(run_in_background: true)로 아래를 실행 node codex-companion.mjs review --background │ ▼ ③ codex-companion.mjs 내부 ┌─────────────────────────────────────────────┐ │ resolveReviewTarget() ── git diff/상태로 │ │ "무엇을 리뷰할지" │ │ 대상 확정 │ │ ensureBrokerSession() ── 브로커가 이미 떠 │ │ 있으면 재사용, │ │ 없으면 새로 기동 │ └─────────────────────────────────────────────┘ │ ▼ ④ 브로커(app-server-broker.mjs)가 없으면: spawn("codex", ["app-server"]) ← 실제 Codex CLI 자식 프로세스 기동 JSON-RPC "initialize" ↔ "initialized" 핸드셰이크 Unix 소켓(윈도우는 네임드 파이프)으로 대기 시작 │ ▼ ⑤ 브로커 소켓으로 review/start 요청 전송 codex app-server가 실제로 diff를 읽고 리뷰를 수행 진행 알림(notification)이 소켓을 타고 계속 흘러들어옴 │ ▼ ⑥ 잡 상태를 state.mjs가 로컬 파일(.codex-companion/ 상태 디렉터리)에 기록 job 상태: queued → running → completed/failed │ ▼ ⑦ 사용자가 나중에 /codex:status, /codex:result 로 폴링 render.mjs가 저장된 잡 결과를 Markdown 표/텍스트로 렌더링 Codex의 원문 출력을 "그대로(verbatim)" 사용자에게 전달
이런 상황을 상상해봐

콜센터에 전화를 걸 때마다 상담원이 매번 새로 출근해서 컴퓨터를 부팅한다면 얼마나 느릴까. 대신 상담원은 이미 근무 중이고, 전화가 올 때마다 그 상담원에게 내선으로 연결만 해 주면 훨씬 빠르다. 브로커(app-server-broker.mjs)가 바로 그 "이미 근무 중인 상담원"이다 — codex app-server를 한 번 띄워 두고, /codex:review·/codex:rescue·/codex:status 같은 서로 다른 커맨드 호출이 모두 같은 살아있는 연결을 재사용한다. 매번 새 프로세스를 기동하는 비용을 줄이는 것이 이 설계의 핵심 동기다.

② 백그라운드 vs 포그라운드 — 실제로 "백그라운드"를 만드는 건 누구인가

커맨드 md 파일들의 지시문을 자세히 보면 흥미로운 분업이 보인다. codex-companion.mjs 스크립트 자체는 --background·--wait 플래그를 파싱만 한다 — 실제로 그 프로세스를 백그라운드로 떼어내는 주체는 Claude Code의 Bash 도구다. 커맨드 지시문이 명시적으로 이렇게 적어 둔다.

// commands/review.md 발췌 — 백그라운드 실행 지시
Bash({
  command: `node "${CLAUDE_PLUGIN_ROOT}/scripts/codex-companion.mjs" review "$ARGUMENTS"`,
  description: "Codex review",
  run_in_background: true  // 이 옵션이 진짜 "백그라운드"를 만든다
})
// 이번 턴에서 BashOutput을 부르거나 완료를 기다리지 않음

즉 "백그라운드로 돈다"는 것은 스크립트의 내부 기능이 아니라, Claude Code가 그 Bash 호출을 어떻게 감독하느냐의 문제다. 스크립트는 그저 상태 파일에 진행 상황을 계속 남기고, 나중에 /codex:status가 그 상태 파일을 읽어 보고할 뿐이다. 리뷰 계열 커맨드(review·adversarial-review)는 실행 전 git status/git diff --shortstat로 변경 규모를 가늠해, "1~2개 파일 수준으로 작으면 대기(wait) 추천, 그 외엔 백그라운드 추천"이라는 휴리스틱 판단까지 커맨드 지시문 안에 박혀 있다.

③ Stop 훅 리뷰 게이트 — Claude가 스스로 멈추지 못하게 막는 장치

/codex:setup --enable-review-gate로 켜면, Claude Code의 Stop 이벤트(한 턴의 응답을 끝내려는 시점)마다 stop-review-gate-hook.mjs가 끼어든다. 이 훅은 단순 로그가 아니라 Claude의 턴 종료 자체를 막을 수 있는 결정권을 가진다.

Claude가 한 턴의 응답을 마치려는 순간 (Stop 이벤트 발생) │ ▼ stop-review-gate-hook.mjs 실행 (최대 15분 타임아웃) │ ├─ config.stopReviewGate가 꺼져 있으면 → 그냥 통과 (아무 개입 없음) │ ▼ (켜져 있는 경우) 직전 Claude 응답 텍스트를 stop-review-gate.md 프롬프트에 끼워 넣어 codex-companion.mjs task 로 Codex에 "이 턴, 정말 이대로 끝내도 되나?" 질의 │ ▼ Codex 응답의 첫 줄을 파싱 ┌───────────────────────┬─────────────────────────────┐ │ "ALLOW: ..."로 시작 │ "BLOCK: 사유"로 시작 │ │ → 훅이 조용히 통과 │ → {"decision":"block", │ │ (다음 턴으로) │ "reason":"..."} 를 stdout│ │ │ 에 출력 │ │ │ → Claude Code가 이 JSON을 읽고│ │ │ 턴 종료를 거부, Claude는 │ │ │ 문제를 먼저 고쳐야 함 │ └───────────────────────┴─────────────────────────────┘ │ ▼ (BLOCK인 경우, 다음 턴에서) Claude가 지적된 문제를 고침 → 다시 응답 종료 시도 → 다시 Stop 훅 발동 … 문제가 사라질 때까지 이 루프가 반복될 수 있음 (README가 명시적으로 경고하는 지점)

주목할 부분은 프롬프트(prompts/stop-review-gate.md) 안의 안전장치다. "직전 턴이 실제 코드 변경을 만들었을 때만 리뷰하고, 단순 상태 조회·요약·셋업 확인이면 즉시 ALLOW하라"는 지침이 못박혀 있다. 그렇지 않으면 /codex:status만 실행한 턴까지 매번 리뷰가 걸려 오탐과 루프를 만들기 때문이다. 또 {"decision":"block","reason":"..."}라는 JSON을 표준출력(stdout)에 한 줄 내보내는 것이, Claude Code 훅 프로토콜에서 "이 턴을 끝내지 마라"는 신호로 해석된다는 점도 훅 시스템을 이해하는 핵심이다.

용어
Stop 훅 (Stop Hook)
Claude Code가 한 턴의 응답을 마무리하려는 시점에 실행되는 후크(hook)다. 이 스크립트가 특정 형식의 JSON({"decision":"block", "reason": "..."})을 표준출력으로 내보내면, Claude Code는 그 턴을 종료하지 않고 reason 내용을 Claude에게 다시 보여준 뒤 이어서 작업하게 만든다. "끝내려는 순간 문지기가 한 번 더 검문한다"는 그림을 떠올리면 된다. SessionStart/SessionEnd 훅과 달리, Stop 훅은 턴의 흐름 자체를 바꿀 수 있는 몇 안 되는 훅이다.

④ SessionStart/SessionEnd 훅 — /codex:transfer를 위한 조용한 준비

브리프에는 없었지만 소스를 열어 보면 hooks.jsonSessionStart·SessionEnd 훅도 등록돼 있다(session-lifecycle-hook.mjs, 133줄). 이들은 리뷰 게이트처럼 화려하게 개입하지 않고, 현재 Claude Code 세션의 트랜스크립트 경로를 기록해 두는 조용한 역할을 한다. 이 값이 나중에 /codex:transfer가 "지금 이 대화를 Codex로 그대로 옮겨 줘"라고 할 때 --source 인자를 사람이 직접 안 채워도 되게 해 주는 배경 장치다.

5디렉토리 구조 해부

실제 클론해서 확인한 .claude-plugin/·plugins/codex/ 전체 구성.

codex-plugin-cc/ ├── .claude-plugin/ │ └── marketplace.json # "이 레포가 마켓플레이스다"라는 선언. /plugin marketplace add 가 읽음 ├── package.json # @openai/codex-plugin-cc, Node>=18.18, 런타임 의존성 0개 ├── README.md # 설치·사용법·FAQ (320줄, 데모 영상 포함) ├── docs/ # plugin-demo.webm 등 시연 자료 ├── scripts/ # 레포 레벨 도구 (버전 범프/체크) │ └── bump-version.mjs ├── tests/ # node --test 로 돌리는 자체 테스트 9종 │ ├── commands.test.mjs · runtime.test.mjs · render.test.mjs │ ├── git.test.mjs · state.test.mjs · process.test.mjs │ ├── broker-endpoint.test.mjs · fake-codex-fixture.mjs · helpers.mjs │ └── plugins/codex/ # 진짜 플러그인 본체 (source = 여기) ├── .claude-plugin/ │ └── plugin.json # name/version/description/author — ${CLAUDE_PLUGIN_ROOT} 기준점 ├── CHANGELOG.md · LICENSE(Apache-2.0) · NOTICE │ ├── commands/ # 8개 슬래시 커맨드 (모두 얇은 지시문 .md) │ ├── review.md · adversarial-review.md │ ├── rescue.md · transfer.md │ ├── status.md · result.md · cancel.md │ └── setup.md │ ├── agents/ │ └── codex-rescue.md # /agents 에 노출되는 서브에이전트. tools: Bash 하나뿐 │ ├── hooks/ │ └── hooks.json # SessionStart · SessionEnd · Stop 세 이벤트 등록 │ ├── skills/ # 서브에이전트 전용 내부 스킬 (user-invocable: false) │ ├── codex-cli-runtime/ # "task 딱 한 번만 불러라" 포워딩 규칙 │ ├── codex-result-handling/ # Codex 결과를 어떻게 보여줄지 규칙 (자동수정 금지 등) │ └── gpt-5-4-prompting/ # Codex용 프롬프트를 다듬는 법 (references/ 3개 문서 포함) │ ├── prompts/ # Codex에게 실제로 보내는 프롬프트 템플릿 │ ├── adversarial-review.md │ └── stop-review-gate.md # ALLOW/BLOCK 출력 계약이 정의된 곳 │ ├── schemas/ │ └── review-output.schema.json # Codex 리뷰 결과의 구조화 스키마 │ └── scripts/ # 진짜 로직이 모여있는 곳 (총 ~5,400줄) ├── codex-companion.mjs # 1,073줄 — 모든 커맨드의 단일 진입점 ├── app-server-broker.mjs # 252줄 — 소켓 서버로 app-server 연결 재사용 ├── session-lifecycle-hook.mjs # SessionStart/SessionEnd 처리 ├── stop-review-gate-hook.mjs # 184줄 — 리뷰 게이트의 실체 └── lib/ # 재사용 모듈 13개 ├── codex.mjs (1,219줄★최대) # Codex 가용성·인증·app-server 호출 총괄 ├── app-server.mjs (354줄) # JSON-RPC 클라이언트 (spawn "codex app-server") ├── render.mjs (465줄) # 잡 결과를 사람이 읽을 텍스트/표로 변환 ├── git.mjs (346줄) # 리뷰 대상(working-tree/branch) 판별 ├── job-control.mjs (308줄) # 잡 상태 조회/취소/정렬 ├── tracked-jobs.mjs (204줄) # 잡 실행 추적 + 세션ID 태깅 ├── broker-lifecycle.mjs (209줄) # 브로커 기동/재사용/종료 ├── state.mjs (191줄) # 로컬 상태 파일 저장소 ├── process.mjs · args.mjs · fs.mjs ├── broker-endpoint.mjs · claude-session-transfer.mjs · workspace.mjs · prompts.mjs
한눈에 읽는 법

구조가 정확히 "규격 준수 계층""실제 작동 계층" 둘로 나뉜다. .claude-plugin/·commands/·agents/·hooks/·skills/는 Claude Code가 "이게 뭘 제공하는 플러그인인지" 읽기 위한 선언적 규격이고, 그 안의 실제 지시문은 거의 전부 scripts/codex-companion.mjs 한 곳으로 수렴한다. 처음 읽는다면 README.mdcommands/review.md(가장 단순한 커맨드) → scripts/codex-companion.mjsreview 서브커맨드 처리부 → lib/codex.mjs·lib/app-server.mjs 순으로 내려가는 것이 가장 자연스럽다. 8개 커맨드 md 파일은 서로 패턴이 비슷하니, 하나를 완전히 이해하면 나머지는 빠르게 읽힌다.

6학습 포인트 (기술별)

이 저장소에서 실제로 무엇을 배울 수 있는가 + 각 주제 실습 아이디어.

학습 1 · Claude Code 플러그인 만드는 법

"마켓플레이스 → 플러그인 → 커맨드"의 최소 뼈대

.claude-plugin/marketplace.jsonplugins/codex/.claude-plugin/plugin.json을 나란히 놓고 보면, 플러그인을 배포하는 데 필요한 최소 파일이 몇 개 안 된다는 걸 알 수 있다. 마켓플레이스는 "어떤 플러그인들을 제공하는가"의 목록이고, 플러그인 매니페스트는 "이 플러그인 자체가 무엇인가"를 담는다. ${CLAUDE_PLUGIN_ROOT} 환경변수가 모든 커맨드 지시문에서 반복 등장하는데, 이게 "플러그인이 설치된 실제 경로"를 가리켜 스크립트 절대경로 문제를 해결해 준다.

실습: 아주 작은 나만의 슬래시 커맨드 플러그인(예: /hello:greet가 현재 시각을 인사말과 함께 출력)을 만들어 로컬 마켓플레이스로 설치해 보기.

학습 2 · 슬래시 커맨드를 "얇게" 설계하기

커맨드 md는 로직이 아니라 지시문이다

8개 커맨드 파일을 비교해 보면 공통 패턴이 보인다: YAML frontmatter로 description·argument-hint·allowed-tools를 선언하고, 본문은 "무엇을 실행하고 어떻게 출력할지"를 자연어로 지시할 뿐, 실제 파싱·분기 로직은 전부 외부 스크립트에 위임한다. disable-model-invocation: true 같은 frontmatter 필드로 "이 커맨드는 모델이 스스로 판단해서 부르면 안 되고 사용자가 명시적으로 쳐야 한다"는 제약까지 선언적으로 건다. 이런 분리 덕분에 커맨드는 짧고, 진짜 복잡도는 테스트 가능한 일반 스크립트에 머문다.

실습: allowed-tools를 의도적으로 좁혀서(예: Bash(git:*)만 허용) "리뷰 전용, 절대 파일을 못 고치는" 커맨드를 만들어 보고 실제로 제약이 걸리는지 확인.

학습 3 · 서브에이전트를 "얇은 전달자"로 좁게 설계하기

codex-rescue.md가 보여주는 극단적 역할 제한

agents/codex-rescue.mdtools: Bash 딱 하나만 갖고, "Bash를 정확히 한 번만 호출하고, 그 외엔 아무것도 하지 마라"는 규칙을 반복해서 못박는다. 파일을 읽지도, grep하지도, 스스로 문제를 풀려고 시도하지도 말라고 명시한다. 이것은 서브에이전트 설계에서 흔한 함정(에이전트가 "친절하게" 자기 판단을 섞으려는 경향)을 정면으로 막는 접근이다 — 서브에이전트의 역할을 최대한 좁게 정의할수록 예측 가능성이 올라간다는 교훈을 준다.

실습: 내 프로젝트에서 "무조건 A 스크립트만 실행하고 결과를 그대로 반환"하는 초-제약 서브에이전트를 하나 만들어, 일반 서브에이전트와 응답 일관성을 비교.

학습 4 · 훅(Hook)으로 턴의 흐름 자체를 제어하기

Stop 훅의 {"decision":"block"} 계약

stop-review-gate-hook.mjs는 훅이 단순 로깅을 넘어 Claude Code의 실행 흐름을 실제로 바꿀 수 있다는 걸 보여주는 좋은 예제다. 표준출력에 특정 형식의 JSON을 내보내는 것만으로 "이 턴을 끝내지 마라"는 제어를 행사한다. 동시에 오탐 방지 로직(직전 턴이 실제 코드 변경을 했는지 먼저 확인)이 얼마나 중요한지도 함께 배울 수 있다 — 훅이 너무 자주 개입하면 사용자 경험을 해친다.

실습: "커밋 메시지에 'WIP'가 들어 있으면 세션 종료를 막고 경고"하는 미니 Stop 훅을 만들어 decision: block 프로토콜을 직접 손으로 익히기.

학습 5 · 에이전트 위임(Delegate) 패턴 — Rescue vs Review 분리

"읽기전용 진단"과 "쓰기 가능 위임"을 코드 레벨에서 갈라놓기

codex-cli-runtime 스킬은 rescue 서브에이전트에 "기본값으로 --write를 붙여라, 사용자가 명시적으로 읽기전용을 요구하지 않는 한"이라고 지시한다. 반대로 review 계열 커맨드는 애초에 allowed-tools에 편집 도구가 없다. "리뷰는 절대 고치지 않는다, 위임은 기본적으로 고친다"는 원칙이 프롬프트 문구뿐 아니라 도구 권한 자체로 이중 강제되는 구조다. 멀티-에이전트 시스템에서 "이 에이전트가 무엇을 할 수 있는가"를 프롬프트로만 믿지 않고 권한으로도 막는 것이 안전한 설계임을 보여준다.

실습: 같은 작업을 "읽기전용 진단 에이전트"와 "쓰기 가능 실행 에이전트"로 나눠 구현하고, 실행 에이전트가 진단 에이전트의 도구로는 절대 파일을 못 건드리는지 검증.

학습 6 · app-server 래핑 — CLI를 JSON-RPC로 프로그래밍적으로 조종하기

사람용 CLI를 프로그램용 API로 바꾸는 표준 패턴

lib/app-server.mjsspawn("codex", ["app-server"]) + readline + JSON-RPC 핸드셰이크(initializeinitialized)는, 대화형 CLI 도구를 다른 프로그램이 제어 가능한 형태로 감싸는 범용 패턴이다. Language Server Protocol(LSP)을 쓰는 에디터, tsserver를 자식 프로세스로 띄우는 IDE, 이번 레포처럼 AI CLI를 감싸는 플러그인까지 전부 같은 뼈대를 쓴다. 여기에 더해 브로커(단일 연결 재사용)까지 얹은 것은 "매번 새 프로세스를 켜는 비용"을 최적화하는 실전 기법이다.

실습: 아무 CLI 도구나 골라(예: python -i, sqlite3) 자식 프로세스로 띄우고 stdin/stdout으로 명령을 넣고 응답을 파싱하는 최소 래퍼를 만들어 보기.

7시스템 요구사항

순수 소프트웨어 플러그인이지만, 계정·인증·전제 조건이 실질적 "요구사항"이다.

항목요구사항
Claude Code플러그인 마켓플레이스(/plugin marketplace add) 기능을 지원하는 버전
Node.js18.18.0 이상 (package.json engines 명시) — Codex CLI 자체 요구사항이기도 함
Codex CLI전역 설치된 codex 바이너리 (npm install -g @openai/codex로 설치 가능)
계정 / 인증ChatGPT 구독(무료 플랜 포함) 또는 OpenAI API 키 중 하나. codex login으로 로그인
사용량 과금이 플러그인을 통한 호출도 Codex 사용량 한도(usage limit)에 그대로 반영됨
운영체제Node.js가 도는 곳이면 어디나 — 브로커가 Unix 소켓(POSIX)과 네임드 파이프(Windows)를 모두 지원
패키지 매니저npm (Codex 자동 설치 제안 시 /codex:setup이 사용)
런타임 의존성0개package.jsondependencies 항목 자체가 없음
라이선스Apache-2.0 — 상업적 사용·수정·재배포 자유롭게 가능
용어
trusted 프로젝트 (Trusted Project)
Codex는 프로젝트별 설정 파일(.codex/config.toml)을 아무 폴더에서나 무조건 읽지 않는다. 사용자가 "이 폴더는 신뢰한다"고 명시적으로 표시한 경우에만 프로젝트 레벨 설정을 반영한다. 낯선 레포를 열었을 때 그 안의 설정 파일이 몰래 모델을 바꾸거나 위험한 옵션을 켜는 걸 막기 위한 안전장치로, "이 폴더의 설정 파일을 믿고 실행해도 되는가"를 사람이 한 번 확인하게 만드는 구조다.

8직접 해볼 수 있는 실습 과제

난이도별 5단계 — 설치하고, 불러 보고, 뜯어보고, 나만의 플러그인 만들기.

과제 1 · 설치하고 첫 리뷰 돌려보기 난이도 ★☆☆☆☆

README가 안내하는 순서 그대로 따라 한다. /plugin marketplace add openai/codex-plugin-cc/plugin install codex@openai-codex/reload-plugins/codex:setup. 이후 아무 로컬 레포에서 파일 하나를 살짝 고친 뒤 /codex:review --wait를 실행해, Codex가 실제로 diff를 읽고 코멘트를 돌려주는 과정을 처음부터 끝까지 체험하는 것이 목표.

# 설치 4단계 (README 그대로)
/plugin marketplace add openai/codex-plugin-cc
/plugin install codex@openai-codex
/reload-plugins
/codex:setup
# Codex가 없으면 여기서 설치를 제안함 → npm install -g @openai/codex
# 로그인 안 돼 있으면: !codex login

과제 2 · 백그라운드 잡 생명주기 관찰 난이도 ★★☆☆☆

일부러 파일을 여러 개 고쳐 리뷰 대상을 크게 만든 뒤 /codex:review --background로 실행하고, 곧바로 /codex:statusqueuedrunningcompleted 상태 전이를 관찰한다. 마지막엔 /codex:result로 저장된 최종 결과를 불러온다. 도중에 /codex:cancel로 취소도 시도해, 취소된 잡이 상태에 어떻게 기록되는지 확인하는 것이 목표.

과제 3 · 조종형 리뷰(adversarial-review)로 설계 결정 도전받기 난이도 ★★☆☆☆

/codex:adversarial-reviewfocus 텍스트를 붙여, 최근 작업한 기능의 특정 위험 지점(예: 동시성, 롤백, 인증 흐름)을 콕 집어 Codex에게 "이 설계가 맞는지 도전하라"고 요청해 본다. /codex:review의 담백한 결함 리스트와, 조종형 리뷰의 "이 접근이 최선인가?"라는 질문 톤이 어떻게 다른지 나란히 비교하는 것이 목표.

/codex:adversarial-review --base main challenge whether this caching strategy is safe under concurrent writes

과제 4 · /codex:rescue로 실제 위임 작업 시켜보기 난이도 ★★★☆☆

일부러 작은 버그(예: off-by-one, 잘못된 조건문)를 하나 심어 두고 /codex:rescue investigate and fix the failing test를 실행한다. codex:codex-rescue 서브에이전트가 /agents 목록에 뜨는지, 그리고 결과가 "Claude가 요약한 것"이 아니라 Codex의 원문 그대로인지 확인하는 것이 핵심. 이어서 /codex:rescue --resume dig deeper로 같은 스레드를 이어가는 것도 시도.

과제 5 · 나만의 슬래시 커맨드 플러그인 만들기 난이도 ★★★★☆

이 레포의 최소 구조(.claude-plugin/marketplace.json + plugins/<name>/.claude-plugin/plugin.json + commands/*.md)를 그대로 본떠, 아주 단순한 나만의 플러그인을 만들어 로컬 마켓플레이스로 설치해 본다. 커맨드 하나는 외부 CLI(예: jq, curl)를 감싸는 형태로 만들어, "커맨드 md는 얇게, 로직은 스크립트로" 원칙을 직접 적용하는 것이 목표. 여유가 되면 hooks/hooks.json에 간단한 SessionStart 훅도 하나 추가해 본다.

9관련 기술 심화 학습 로드맵

"플러그인을 쓰는 사람"에서 "플러그인을 설계하는 사람"으로 — 5주 계획.

주차주제할 일
1주차Claude Code 플러그인 기초공식 플러그인 문서 정독. marketplace.json/plugin.json 스키마 이해. 과제 1·5 착수
2주차슬래시 커맨드 & frontmatterallowed-tools·argument-hint·disable-model-invocation 등 frontmatter 필드 전수 조사. 8개 커맨드 md를 전부 비교하며 공통 패턴 뽑아보기
3주차서브에이전트 & 훅 설계agents/codex-rescue.mdhooks/hooks.json을 정독. Stop/SessionStart/SessionEnd 훅의 입출력 계약 이해. 과제 4 진행
4주차프로세스 간 통신 & JSON-RPCLSP(Language Server Protocol) 기초 학습으로 JSON-RPC 패턴 익히기. lib/app-server.mjs의 spawn+readline 구조를 직접 손으로 재현. 과제 6-학습6
5주차멀티-에이전트 협업 패턴Rescue(위임)와 Review(진단)의 권한 분리 원칙을 정리. 다른 멀티-에이전트 오케스트레이션 사례(예: 다른 CLI 플러그인)와 비교 분석. 나만의 플러그인 완성(과제 5)
학습 순서 팁

이 레포는 "새로운 언어나 프레임워크"를 배우는 자료가 아니라 "이미 아는 도구(슬래시 커맨드, 서브에이전트, 훅)를 실전 수준으로 조합하는 법"을 배우는 자료에 가깝다. 그래서 순서도 선언적 규격(marketplace/plugin.json) → 얇은 지시문(커맨드) → 권한이 딸린 실행 단위(서브에이전트·훅) → 그 밑을 받치는 프로세스 통신(app-server) 순으로 밖에서 안으로 파고드는 것이 자연스럽다. 처음부터 lib/codex.mjs(1,219줄)를 열면 막막할 수 있으니, 커맨드 md 8개를 먼저 다 읽고 "이게 어떤 스크립트를 어떤 인자로 부르는가"부터 지도를 그린 뒤 내부로 들어가는 게 좋다.

10핵심 키워드 사전

이 문서와 저장소에 나온 주요 용어 정리.

용어의미
Claude Code 플러그인슬래시 커맨드·서브에이전트·훅·스킬을 한 묶음으로 배포해, Claude Code 사용자가 /plugin install로 손쉽게 설치할 수 있게 만든 확장 패키지.
마켓플레이스(Marketplace)플러그인들의 목록을 선언하는 marketplace.json. /plugin marketplace add owner/repo로 등록한다.
슬래시 커맨드(Slash Command)/codex:review처럼 /로 시작하는 사용자 호출 명령. frontmatter가 딸린 .md 파일로 정의된다.
서브에이전트(Subagent)메인 대화와 분리된, 좁은 역할·좁은 도구 권한을 가진 독립 에이전트. codex:codex-rescue가 예시.
훅(Hook) — SessionStart/SessionEnd세션이 시작되거나 끝날 때 실행되는 스크립트. 이 레포에서는 세션 트랜스크립트 경로 기록에 쓰인다.
훅(Hook) — StopClaude의 한 턴이 끝나려는 시점에 실행되며, {"decision":"block"}을 출력해 턴 종료를 막을 수 있는 특수 훅.
app server (앱 서버)codex app-server: Codex CLI를 JSON-RPC로 프로그래밍적으로 조종할 수 있게 여는 백엔드 모드.
브로커(Broker)app-server-broker.mjs가 띄우는 로컬 소켓 서버. 여러 커맨드 호출이 하나의 app-server 연결을 공유하게 해 준다.
위임(Delegate) / rescue진단에 그치지 않고 실제 코드 수정까지 Codex에 맡기는 것. /codex:rescue가 담당하며 기본적으로 쓰기 가능(--write)하다.
리뷰 게이트(Review Gate)Stop 훅을 이용해 세션 종료 시점마다 Codex 리뷰를 강제로 돌리는 선택적 기능. /codex:setup --enable-review-gate로 켠다.
전송(Transfer)/codex:transfer: 현재 Claude Code 세션 트랜스크립트를 Codex의 재개 가능한 스레드로 변환하는 기능.
MCP (Model Context Protocol)AI 모델이 외부 도구·데이터 소스와 표준화된 방식으로 통신하도록 만든 프로토콜. 이 레포가 직접 MCP 서버는 아니지만, "AI가 다른 시스템을 표준 프로토콜로 조종한다"는 점에서 app-server 래핑과 사상이 닿아 있다.
config.toml 계층Codex 설정이 ~/.codex/config.toml(전역) → .codex/config.toml(프로젝트, trusted일 때)의 순서로 병합되는 구조.
gpt-5.3-codex-spark--model spark로 요청했을 때 실제로 매핑되는 더 빠르고 가벼운 Codex 모델명.

11참고 링크

공식 저장소 · Codex 문서 · Claude Code 플러그인 문서.

구분링크
GitHub 저장소github.com/openai/codex-plugin-cc
Codex app server 문서developers.openai.com/codex/app-server
Codex CLI 레퍼런스developers.openai.com/codex/cli
Codex 설정(config) 기초developers.openai.com/codex/config-basic
Codex 설정(config) 고급 / trusted 프로젝트developers.openai.com/codex/config-advanced
Codex 요금/사용량developers.openai.com/codex/pricing
라이선스Apache-2.0 (상업적 사용 가능)