Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions .cursor-plugin/marketplace.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"name": "openai-codex",
"owner": {
"name": "OpenAI"
},
"metadata": {
"description": "Codex plugins to use in Cursor for delegation and code review.",
"version": "1.0.1",
"pluginRoot": "./plugins"
},
"plugins": [
{
"name": "codex",
"source": "codex",
"description": "Use Codex from Cursor to review code or delegate tasks.",
"version": "1.0.1",
"category": "developer-tools",
"tags": [
"review",
"ai",
"codex",
"code-quality"
],
"keywords": [
"codex",
"openai",
"code-review",
"delegation",
"ai-assistant"
]
}
]
}
22 changes: 18 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Codex plugin for Claude Code
# Codex plugin for Claude Code & Cursor

Use Codex from inside Claude Code for code reviews or to delegate tasks to Codex.
Use Codex from inside Claude Code or Cursor for code reviews or to delegate tasks to Codex.

This plugin is for Claude Code users who want an easy way to start using Codex from the workflow
This plugin is for Claude Code and Cursor users who want an easy way to start using Codex from the workflow
they already have.

<video src="./docs/plugin-demo.webm" controls muted playsinline autoplay></video>
Expand All @@ -21,6 +21,8 @@ they already have.

## Install

### Claude Code

Add the marketplace in Claude Code:

```bash
Expand All @@ -39,7 +41,19 @@ Reload plugins:
/reload-plugins
```

Then run:
### Cursor

Add the plugin in Cursor using the `/add-plugin` command:

```
/add-plugin openai/codex-plugin-cc
```

Alternatively, browse the [Cursor Marketplace](https://cursor.com/marketplace) and install the Codex plugin from there.

### Setup

After installing (in either Claude Code or Cursor), run:

```bash
/codex:setup
Expand Down
22 changes: 22 additions & 0 deletions plugins/codex/.cursor-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"name": "codex",
"version": "1.0.1",
"description": "Use Codex from Cursor to review code or delegate tasks.",
"author": {
"name": "OpenAI"
},
"homepage": "https://github.com/openai/codex-plugin-cc",
"repository": "https://github.com/openai/codex-plugin-cc",
"license": "Apache-2.0",
"keywords": [
"codex",
"openai",
"code-review",
"delegation",
"ai-assistant"
],
"skills": "./skills/",
"commands": "./commands/",
"agents": "./agents/",
"hooks": "./hooks/cursor-hooks.json"
}
23 changes: 23 additions & 0 deletions plugins/codex/hooks/cursor-hooks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"version": 1,
"hooks": {
"sessionStart": [
{
"command": "CLAUDE_PLUGIN_ROOT=\"${CURSOR_PLUGIN_ROOT}\" node \"${CURSOR_PLUGIN_ROOT}/scripts/cursor-session-lifecycle-hook.mjs\" sessionStart",
"timeout": 5
}
],
"sessionEnd": [
{
"command": "CLAUDE_PLUGIN_ROOT=\"${CURSOR_PLUGIN_ROOT}\" node \"${CURSOR_PLUGIN_ROOT}/scripts/session-lifecycle-hook.mjs\" SessionEnd",
"timeout": 5
}
],
"stop": [
{
"command": "CLAUDE_PLUGIN_ROOT=\"${CURSOR_PLUGIN_ROOT}\" node \"${CURSOR_PLUGIN_ROOT}/scripts/stop-review-gate-hook.mjs\"",
"timeout": 900
}
]
}
}
44 changes: 44 additions & 0 deletions plugins/codex/scripts/cursor-session-lifecycle-hook.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#!/usr/bin/env node

/**
* Cursor-specific sessionStart hook adapter.
*
* Cursor propagates env vars via the hook's JSON stdout `{ "env": { ... } }`
* rather than Claude Code's CLAUDE_ENV_FILE mechanism. This thin wrapper reads
* the Cursor hook input and emits the env vars the companion runtime needs for
* the rest of the session.
*
* sessionEnd and stop hooks reuse the original scripts directly (see
* cursor-hooks.json).
*/

import fs from "node:fs";
import process from "node:process";

const SESSION_ID_ENV = "CODEX_COMPANION_SESSION_ID";

function readHookInput() {
const raw = fs.readFileSync(0, "utf8").trim();
if (!raw) {
return {};
}
return JSON.parse(raw);
}

function main() {
const input = readHookInput();

// Emit env vars that subsequent hooks (sessionEnd, stop) will need.
const env = {};

if (input.session_id) {
env[SESSION_ID_ENV] = String(input.session_id);
}

// Cursor does not provide CLAUDE_PLUGIN_DATA; the companion runtime falls
// back to $TMPDIR/codex-companion automatically (see lib/state.mjs).

process.stdout.write(JSON.stringify({ env }));
}

main();