feat(claude): add idempotent installer for openai/codex-plugin-cc
One-liner script that: - Verifies/installs Node.js >= 18, git, codex CLI - Adds 'openai-codex' marketplace (github.com/openai/codex-plugin-cc) - Installs/updates 'codex@openai-codex' plugin - Verifies result via 'claude plugin list' Re-runs are safe — auto-detects what is already installed and only fills gaps or pulls newer plugin versions. Three platforms covered: Linux (apt/dnf/yum), macOS (brew), Windows (winget) via .sh and .ps1 wrappers + CMD entry-point. Plugin commands inside Claude Code: /codex:review, /codex:adversarial-review, /codex:rescue, /codex:status, /codex:result, /codex:cancel Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
105
claude/CODEX_PLUGIN.md
Normal file
105
claude/CODEX_PLUGIN.md
Normal file
@@ -0,0 +1,105 @@
|
||||
# OpenAI Codex Plugin for Claude Code
|
||||
|
||||
Официальный plugin от OpenAI ([github.com/openai/codex-plugin-cc](https://github.com/openai/codex-plugin-cc)),
|
||||
который добавляет в Claude Code команды `/codex:review`, `/codex:rescue` и т.д. для делегирования
|
||||
задач OpenAI Codex прямо изнутри Claude Code.
|
||||
|
||||
## Установка одной командой
|
||||
|
||||
> Установщик идемпотентен — при повторном запуске обновит plugin до последней версии,
|
||||
> компоненты которые уже стоят (Node.js, git, codex CLI) пропустит.
|
||||
|
||||
**Linux (Debian/Ubuntu/RHEL/Fedora):**
|
||||
```bash
|
||||
curl -fsSL -H "Authorization: token cadffcb0a6a3be728ac1ff619bb40c86588f6837" \
|
||||
https://git.sensey24.ru/aibot777/unlimitedcoding/raw/branch/master/claude/install_codex_plugin.sh \
|
||||
-o /tmp/install_codex_plugin.sh && sudo bash /tmp/install_codex_plugin.sh
|
||||
```
|
||||
|
||||
**macOS:**
|
||||
```bash
|
||||
curl -fsSL -H "Authorization: token cadffcb0a6a3be728ac1ff619bb40c86588f6837" \
|
||||
https://git.sensey24.ru/aibot777/unlimitedcoding/raw/branch/master/claude/install_codex_plugin.sh \
|
||||
-o /tmp/install_codex_plugin.sh && bash /tmp/install_codex_plugin.sh
|
||||
```
|
||||
|
||||
**Windows (PowerShell as Administrator):**
|
||||
```powershell
|
||||
$h=@{Authorization="token cadffcb0a6a3be728ac1ff619bb40c86588f6837"}
|
||||
Set-ExecutionPolicy Bypass -Scope Process -Force
|
||||
iwr "https://git.sensey24.ru/aibot777/unlimitedcoding/raw/branch/master/claude/install_codex_plugin.ps1" -OutFile "$env:TEMP\install_codex_plugin.ps1" -Headers $h
|
||||
. "$env:TEMP\install_codex_plugin.ps1"
|
||||
```
|
||||
|
||||
**Windows (CMD as Administrator):**
|
||||
```cmd
|
||||
powershell -NoProfile -ExecutionPolicy Bypass -Command "$h=@{Authorization='token cadffcb0a6a3be728ac1ff619bb40c86588f6837'}; iwr 'https://git.sensey24.ru/aibot777/unlimitedcoding/raw/branch/master/claude/install_codex_plugin.ps1' -OutFile \"$env:TEMP\install_codex_plugin.ps1\" -Headers $h; & \"$env:TEMP\install_codex_plugin.ps1\""
|
||||
```
|
||||
|
||||
## Алгоритм установки (что делает скрипт)
|
||||
|
||||
| # | Шаг | Что проверяет / устанавливает |
|
||||
|---|-----|------------------------------|
|
||||
| 1 | **Node.js >= 18** | `node -v`. Если нет — apt/dnf/brew/winget. Если версия < 18 — exit 1. |
|
||||
| 2 | **Claude Code CLI** | `claude --version`. Если нет — exit с инструкцией поставить. |
|
||||
| 3 | **git** | `git --version`. Если нет — apt/dnf/brew/winget. |
|
||||
| 4 | **Codex CLI** (`@openai/codex`) | `codex --version`. Если нет — `npm install -g @openai/codex`. |
|
||||
| 5 | **Marketplace `openai-codex`** | `claude plugin marketplace list`. Если нет — `claude plugin marketplace add https://github.com/openai/codex-plugin-cc`. |
|
||||
| 6 | **Plugin `codex@openai-codex`** | `claude plugin list`. Если нет — `claude plugin install codex@openai-codex`. Если есть — `claude plugin update`. |
|
||||
| 7 | **Verify** | повторный `claude plugin list` + grep на `codex@openai-codex`. |
|
||||
|
||||
### Где что лежит после установки
|
||||
|
||||
| Компонент | Путь |
|
||||
|-----------|------|
|
||||
| Plugin manifest | `~/.claude/plugins/cache/openai-codex/codex/<VERSION>/.claude-plugin/plugin.json` |
|
||||
| Installed registry | `~/.claude/plugins/installed_plugins.json` |
|
||||
| Marketplace registry | `~/.claude/plugins/known_marketplaces.json` |
|
||||
| Codex CLI | `$(npm root -g)/@openai/codex/` + бинарь в PATH |
|
||||
|
||||
### Идемпотентность
|
||||
|
||||
Скрипт безопасно перезапускается:
|
||||
- если Node.js / git уже стоят — шаги 1, 3 пропускаются
|
||||
- если Codex CLI стоит — `npm install -g` не запускается
|
||||
- если marketplace добавлен — `marketplace add` пропускается
|
||||
- если plugin установлен — выполняется `plugin update` (подтянет более свежую версию из репо)
|
||||
|
||||
Версия плагина определяется upstream'ом (`openai/codex-plugin-cc` на GitHub). На момент написания
|
||||
последняя — 1.0.4 (commit `807e03a`). При выходе 1.0.5+ повторный запуск установщика обновит.
|
||||
|
||||
## Команды плагина внутри Claude Code
|
||||
|
||||
После установки и перезапуска `claude` доступны slash-команды:
|
||||
|
||||
| Команда | Действие |
|
||||
|---------|----------|
|
||||
| `/codex:review` | стандартное code review текущего diff |
|
||||
| `/codex:adversarial-review` | проверка дизайна и неявных предположений |
|
||||
| `/codex:rescue` | делегирование задачи в Codex (фикс / большой рефакторинг) |
|
||||
| `/codex:status` | статус background-jobs |
|
||||
| `/codex:result` | получение результата завершённого job |
|
||||
| `/codex:cancel` | отмена running job |
|
||||
|
||||
## Аутентификация
|
||||
|
||||
Plugin использует **существующую auth Codex CLI** — отдельной auth не нужно.
|
||||
- Если уже выполнен `codex login` — plugin работает
|
||||
- Либо установлен `OPENAI_API_KEY` env var
|
||||
|
||||
На пропатченной нашей сборке Codex (через `ucodex_install.sh/.ps1`) уже настроен `OPENAI_BASE_URL`
|
||||
на наш AI proxy — plugin будет ходить туда же, без прямого обращения к OpenAI.
|
||||
|
||||
## Удаление
|
||||
|
||||
```bash
|
||||
claude plugin uninstall codex@openai-codex
|
||||
claude plugin marketplace remove openai-codex
|
||||
npm uninstall -g @openai/codex
|
||||
```
|
||||
|
||||
## Источники
|
||||
|
||||
- Репозиторий plugin: https://github.com/openai/codex-plugin-cc
|
||||
- Anthropic plugins docs: https://docs.claude.com/en/docs/claude-code/plugins
|
||||
- Community announcement: https://community.openai.com/t/introducing-codex-plugin-for-claude-code/1378186
|
||||
121
claude/install_codex_plugin.ps1
Normal file
121
claude/install_codex_plugin.ps1
Normal file
@@ -0,0 +1,121 @@
|
||||
# Install OpenAI Codex Plugin for Claude Code (Windows)
|
||||
# Idempotent - safe to re-run; auto-installs missing prereqs.
|
||||
#
|
||||
# Usage (PowerShell as Administrator):
|
||||
# $h=@{Authorization="token cadffcb0a6a3be728ac1ff619bb40c86588f6837"}
|
||||
# Set-ExecutionPolicy Bypass -Scope Process -Force
|
||||
# iwr "https://git.sensey24.ru/aibot777/unlimitedcoding/raw/branch/master/claude/install_codex_plugin.ps1" -OutFile "$env:TEMP\install_codex_plugin.ps1" -Headers $h
|
||||
# . "$env:TEMP\install_codex_plugin.ps1"
|
||||
|
||||
$ErrorActionPreference = "Continue"
|
||||
|
||||
$PLUGIN_NAME = "codex"
|
||||
$MARKETPLACE_NAME = "openai-codex"
|
||||
$MARKETPLACE_URL = "https://github.com/openai/codex-plugin-cc"
|
||||
$CODEX_NPM = "@openai/codex"
|
||||
|
||||
Write-Host ""
|
||||
Write-Host " +------------------------------------------+" -ForegroundColor Cyan
|
||||
Write-Host " | Codex Plugin for Claude Code installer |" -ForegroundColor Cyan
|
||||
Write-Host " +------------------------------------------+" -ForegroundColor Cyan
|
||||
Write-Host ""
|
||||
|
||||
function Test-Cmd($n) { return [bool](Get-Command $n -ErrorAction SilentlyContinue) }
|
||||
function Refresh-Path {
|
||||
$env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" +
|
||||
[System.Environment]::GetEnvironmentVariable("Path","User")
|
||||
}
|
||||
|
||||
# ---- 1. Prereqs ----
|
||||
|
||||
if (-not (Test-Cmd "node")) {
|
||||
Write-Host " Node.js not found, installing via winget..." -ForegroundColor Yellow
|
||||
if (Test-Cmd "winget") {
|
||||
winget install OpenJS.NodeJS.LTS --accept-package-agreements --accept-source-agreements -e 2>$null
|
||||
Refresh-Path
|
||||
} else {
|
||||
Write-Host " winget unavailable. Install Node.js manually: https://nodejs.org/" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
$nodeMajor = [int](((node --version 2>$null) -replace '^v','') -split '\.')[0]
|
||||
if ($nodeMajor -lt 18) {
|
||||
Write-Host " Node.js >= 18 required (found v$nodeMajor). Upgrade manually." -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
Write-Host " Node.js v$nodeMajor.x OK" -ForegroundColor Green
|
||||
|
||||
if (-not (Test-Cmd "claude")) {
|
||||
Write-Host " Claude Code CLI not found. Install it first:" -ForegroundColor Red
|
||||
Write-Host ' npm config set "@anthropic-ai:registry" "https://npm.sensey24.ru/"' -ForegroundColor Yellow
|
||||
Write-Host " npm install -g @anthropic-ai/claude-code" -ForegroundColor Yellow
|
||||
exit 1
|
||||
}
|
||||
Write-Host (" Claude Code: " + (claude --version 2>$null)) -ForegroundColor Green
|
||||
|
||||
if (-not (Test-Cmd "git")) {
|
||||
Write-Host " git not found, installing via winget..." -ForegroundColor Yellow
|
||||
if (Test-Cmd "winget") {
|
||||
winget install Git.Git --accept-package-agreements --accept-source-agreements -e 2>$null
|
||||
Refresh-Path
|
||||
} else {
|
||||
Write-Host " Install git manually: https://git-scm.com/download/win" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
Write-Host (" git: " + (git --version)) -ForegroundColor Green
|
||||
|
||||
# ---- 2. Codex CLI ----
|
||||
|
||||
if (-not (Test-Cmd "codex")) {
|
||||
Write-Host " Codex CLI not found, installing..." -ForegroundColor Cyan
|
||||
npm install -g $CODEX_NPM 2>&1 | Select-Object -Last 3
|
||||
Refresh-Path
|
||||
}
|
||||
$codexVer = (codex --version 2>$null) -replace '[^0-9.]+',' ' -split ' ' | Where-Object { $_ -match '^\d+\.\d+\.\d+' } | Select-Object -First 1
|
||||
if (-not $codexVer) { $codexVer = "unknown" }
|
||||
Write-Host " Codex CLI v$codexVer" -ForegroundColor Green
|
||||
|
||||
# ---- 3. Marketplace ----
|
||||
|
||||
$marketList = claude plugin marketplace list 2>&1 | Out-String
|
||||
if ($marketList -match $MARKETPLACE_NAME) {
|
||||
Write-Host " Marketplace '$MARKETPLACE_NAME' already configured" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host " Adding marketplace: $MARKETPLACE_URL" -ForegroundColor Cyan
|
||||
claude plugin marketplace add $MARKETPLACE_URL 2>&1 | Select-Object -Last 3
|
||||
}
|
||||
|
||||
# ---- 4. Plugin install / update ----
|
||||
|
||||
$pluginList = claude plugin list 2>&1 | Out-String
|
||||
$fullName = "${PLUGIN_NAME}@${MARKETPLACE_NAME}"
|
||||
if ($pluginList -match [regex]::Escape($fullName)) {
|
||||
Write-Host " Plugin already installed - checking for updates..." -ForegroundColor Cyan
|
||||
claude plugin update $fullName 2>&1 | Select-Object -Last 3
|
||||
} else {
|
||||
Write-Host " Installing plugin: $fullName" -ForegroundColor Cyan
|
||||
claude plugin install $fullName 2>&1 | Select-Object -Last 5
|
||||
}
|
||||
|
||||
# ---- 5. Verify ----
|
||||
|
||||
$verify = claude plugin list 2>&1 | Out-String
|
||||
if ($verify -match [regex]::Escape($fullName)) {
|
||||
Write-Host ""
|
||||
Write-Host " === Codex plugin installed! ===" -ForegroundColor Green
|
||||
Write-Host ""
|
||||
Write-Host " Commands inside Claude Code:"
|
||||
Write-Host " /codex:review - standard code review"
|
||||
Write-Host " /codex:adversarial-review - design + assumption review"
|
||||
Write-Host " /codex:rescue - delegate task to Codex for fix"
|
||||
Write-Host " /codex:status - check background jobs"
|
||||
Write-Host " /codex:result - fetch job results"
|
||||
Write-Host " /codex:cancel - cancel a running job"
|
||||
Write-Host ""
|
||||
Write-Host " Auth: run 'codex login' (or set OPENAI_API_KEY)" -ForegroundColor Yellow
|
||||
Write-Host ""
|
||||
} else {
|
||||
Write-Host " Plugin install verification failed. Run: claude plugin list" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
121
claude/install_codex_plugin.sh
Normal file
121
claude/install_codex_plugin.sh
Normal file
@@ -0,0 +1,121 @@
|
||||
#!/usr/bin/env bash
|
||||
# Install OpenAI Codex Plugin for Claude Code
|
||||
# Idempotent — safe to re-run; auto-installs missing prereqs.
|
||||
#
|
||||
# Usage:
|
||||
# curl -fsSL -H "Authorization: token cadffcb0a6a3be728ac1ff619bb40c86588f6837" \
|
||||
# https://git.sensey24.ru/aibot777/unlimitedcoding/raw/branch/master/claude/install_codex_plugin.sh \
|
||||
# -o /tmp/install_codex_plugin.sh && sudo bash /tmp/install_codex_plugin.sh
|
||||
set -euo pipefail
|
||||
|
||||
PLUGIN_NAME="codex"
|
||||
MARKETPLACE_NAME="openai-codex"
|
||||
MARKETPLACE_URL="https://github.com/openai/codex-plugin-cc"
|
||||
CODEX_NPM="@openai/codex"
|
||||
|
||||
GREEN="\033[92m"; YELLOW="\033[93m"; RED="\033[91m"; CYAN="\033[96m"; BOLD="\033[1m"; RESET="\033[0m"
|
||||
log() { echo -e "${GREEN}[+]${RESET} $*"; }
|
||||
warn() { echo -e "${YELLOW}[~]${RESET} $*"; }
|
||||
err() { echo -e "${RED}[!]${RESET} $*" >&2; }
|
||||
info() { echo -e "${CYAN}[i]${RESET} $*"; }
|
||||
|
||||
OS="$(uname -s)"
|
||||
IS_MACOS=false
|
||||
[ "$OS" = "Darwin" ] && IS_MACOS=true
|
||||
|
||||
echo -e "${BOLD}"
|
||||
echo " +------------------------------------------+"
|
||||
echo " | Codex Plugin for Claude Code installer |"
|
||||
echo " +------------------------------------------+"
|
||||
echo -e "${RESET}"
|
||||
|
||||
# ---- 1. Prereqs ----
|
||||
|
||||
install_pkg() {
|
||||
if command -v apt-get >/dev/null 2>&1; then apt-get update -qq && apt-get install -y -qq "$@"
|
||||
elif command -v dnf >/dev/null 2>&1; then dnf install -y -q "$@"
|
||||
elif command -v yum >/dev/null 2>&1; then yum install -y -q "$@"
|
||||
elif command -v brew >/dev/null 2>&1; then brew install "$@"
|
||||
else err "No package manager found. Install $* manually."; return 1
|
||||
fi
|
||||
}
|
||||
|
||||
if ! command -v node >/dev/null 2>&1; then
|
||||
info "Node.js not found, installing..."
|
||||
if $IS_MACOS; then brew install node
|
||||
elif command -v apt-get >/dev/null 2>&1; then curl -fsSL https://deb.nodesource.com/setup_24.x | bash - && apt-get install -y nodejs
|
||||
else install_pkg nodejs npm
|
||||
fi
|
||||
fi
|
||||
NODE_MAJOR=$(node -v | sed 's/v//' | cut -d. -f1)
|
||||
if [ "$NODE_MAJOR" -lt 18 ]; then
|
||||
err "Node.js >= 18 required (found v$NODE_MAJOR). Upgrade manually."
|
||||
exit 1
|
||||
fi
|
||||
log "Node.js $(node -v)"
|
||||
|
||||
if ! command -v claude >/dev/null 2>&1; then
|
||||
err "Claude Code CLI not found. Install it first:"
|
||||
err " npm config set @anthropic-ai:registry https://npm.sensey24.ru/"
|
||||
err " npm install -g @anthropic-ai/claude-code"
|
||||
exit 1
|
||||
fi
|
||||
log "Claude Code $(claude --version 2>&1 | head -1)"
|
||||
|
||||
if ! command -v git >/dev/null 2>&1; then
|
||||
info "git not found, installing..."
|
||||
install_pkg git
|
||||
fi
|
||||
log "git $(git --version | awk '{print $3}')"
|
||||
|
||||
# ---- 2. Codex CLI ----
|
||||
|
||||
if ! command -v codex >/dev/null 2>&1; then
|
||||
info "Codex CLI not found, installing..."
|
||||
npm install -g "$CODEX_NPM" 2>&1 | tail -3
|
||||
fi
|
||||
CODEX_VER=$(codex --version 2>&1 | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1 || echo "unknown")
|
||||
log "Codex CLI v$CODEX_VER"
|
||||
|
||||
# ---- 3. Marketplace ----
|
||||
|
||||
if claude plugin marketplace list 2>&1 | grep -q "$MARKETPLACE_NAME"; then
|
||||
log "Marketplace '$MARKETPLACE_NAME' already configured"
|
||||
else
|
||||
info "Adding marketplace: $MARKETPLACE_URL"
|
||||
claude plugin marketplace add "$MARKETPLACE_URL" 2>&1 | tail -3
|
||||
log "Marketplace added"
|
||||
fi
|
||||
|
||||
# ---- 4. Plugin install / update ----
|
||||
|
||||
if claude plugin list 2>&1 | grep -q "${PLUGIN_NAME}@${MARKETPLACE_NAME}"; then
|
||||
info "Plugin already installed — checking for updates..."
|
||||
claude plugin update "${PLUGIN_NAME}@${MARKETPLACE_NAME}" 2>&1 | tail -3 || warn "Update skipped (already latest)"
|
||||
else
|
||||
info "Installing plugin: ${PLUGIN_NAME}@${MARKETPLACE_NAME}"
|
||||
claude plugin install "${PLUGIN_NAME}@${MARKETPLACE_NAME}" 2>&1 | tail -5
|
||||
fi
|
||||
|
||||
# ---- 5. Verify ----
|
||||
|
||||
echo ""
|
||||
PLUGIN_INFO=$(claude plugin list 2>&1 | grep -A2 "${PLUGIN_NAME}@${MARKETPLACE_NAME}" || true)
|
||||
if [ -n "$PLUGIN_INFO" ]; then
|
||||
echo -e "${GREEN}${BOLD}=== Codex plugin installed! ===${RESET}"
|
||||
echo "$PLUGIN_INFO"
|
||||
echo ""
|
||||
echo "Available commands inside Claude Code:"
|
||||
echo " /codex:review — standard code review"
|
||||
echo " /codex:adversarial-review — design + assumption review"
|
||||
echo " /codex:rescue — delegate task to Codex for fix"
|
||||
echo " /codex:status — check background jobs"
|
||||
echo " /codex:result — fetch job results"
|
||||
echo " /codex:cancel — cancel a running job"
|
||||
echo ""
|
||||
echo -e "${YELLOW}Auth required:${RESET} run 'codex login' (or set OPENAI_API_KEY)"
|
||||
echo " Plugin uses your existing Codex CLI auth — same as 'codex exec'."
|
||||
else
|
||||
err "Plugin install verification failed. Run: claude plugin list"
|
||||
exit 1
|
||||
fi
|
||||
Reference in New Issue
Block a user