cc-plugin-codex 0.1.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cc_plugin_codex-0.1.4/.agents/plugins/marketplace.json +20 -0
- cc_plugin_codex-0.1.4/.codex-plugin/plugin.json +24 -0
- cc_plugin_codex-0.1.4/.github/workflows/ci.yml +75 -0
- cc_plugin_codex-0.1.4/.github/workflows/publish.yml +96 -0
- cc_plugin_codex-0.1.4/.gitignore +22 -0
- cc_plugin_codex-0.1.4/.mcp.json +21 -0
- cc_plugin_codex-0.1.4/CHANGELOG.md +24 -0
- cc_plugin_codex-0.1.4/COMPATIBILITY.md +87 -0
- cc_plugin_codex-0.1.4/LICENSE +21 -0
- cc_plugin_codex-0.1.4/PKG-INFO +223 -0
- cc_plugin_codex-0.1.4/README.md +194 -0
- cc_plugin_codex-0.1.4/SECURITY.md +24 -0
- cc_plugin_codex-0.1.4/prek.toml +69 -0
- cc_plugin_codex-0.1.4/pyproject.toml +100 -0
- cc_plugin_codex-0.1.4/skills/collaborating-with-claude/SKILL.md +54 -0
- cc_plugin_codex-0.1.4/src/cc_plugin_codex/__init__.py +5 -0
- cc_plugin_codex-0.1.4/src/cc_plugin_codex/claude.py +284 -0
- cc_plugin_codex-0.1.4/src/cc_plugin_codex/cli_contract.py +122 -0
- cc_plugin_codex-0.1.4/src/cc_plugin_codex/config.py +172 -0
- cc_plugin_codex-0.1.4/src/cc_plugin_codex/context.py +210 -0
- cc_plugin_codex-0.1.4/src/cc_plugin_codex/jobs.py +561 -0
- cc_plugin_codex-0.1.4/src/cc_plugin_codex/normalize.py +243 -0
- cc_plugin_codex-0.1.4/src/cc_plugin_codex/preflight.py +94 -0
- cc_plugin_codex-0.1.4/src/cc_plugin_codex/py.typed +0 -0
- cc_plugin_codex-0.1.4/src/cc_plugin_codex/schemas.py +344 -0
- cc_plugin_codex-0.1.4/src/cc_plugin_codex/server.py +1656 -0
- cc_plugin_codex-0.1.4/tests/conftest.py +75 -0
- cc_plugin_codex-0.1.4/tests/golden/claude_envelope.json +15 -0
- cc_plugin_codex-0.1.4/tests/test_claude.py +304 -0
- cc_plugin_codex-0.1.4/tests/test_cli_contract.py +59 -0
- cc_plugin_codex-0.1.4/tests/test_config.py +108 -0
- cc_plugin_codex-0.1.4/tests/test_context.py +161 -0
- cc_plugin_codex-0.1.4/tests/test_fingerprint.py +65 -0
- cc_plugin_codex-0.1.4/tests/test_golden_envelope.py +36 -0
- cc_plugin_codex-0.1.4/tests/test_integration.py +40 -0
- cc_plugin_codex-0.1.4/tests/test_jobs.py +414 -0
- cc_plugin_codex-0.1.4/tests/test_normalize.py +290 -0
- cc_plugin_codex-0.1.4/tests/test_preflight.py +56 -0
- cc_plugin_codex-0.1.4/tests/test_schemas.py +167 -0
- cc_plugin_codex-0.1.4/tests/test_server.py +1383 -0
- cc_plugin_codex-0.1.4/uv.lock +1761 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "cc-plugin-codex",
|
|
3
|
+
"interface": {
|
|
4
|
+
"displayName": "Claude Code (for Codex)"
|
|
5
|
+
},
|
|
6
|
+
"plugins": [
|
|
7
|
+
{
|
|
8
|
+
"name": "cc-plugin-codex",
|
|
9
|
+
"source": {
|
|
10
|
+
"source": "local",
|
|
11
|
+
"path": "./"
|
|
12
|
+
},
|
|
13
|
+
"policy": {
|
|
14
|
+
"installation": "AVAILABLE",
|
|
15
|
+
"authentication": "ON_USE"
|
|
16
|
+
},
|
|
17
|
+
"category": "Developer Tools"
|
|
18
|
+
}
|
|
19
|
+
]
|
|
20
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "cc-plugin-codex",
|
|
3
|
+
"version": "0.1.4",
|
|
4
|
+
"description": "Call Claude Code from Codex for bounded, independent code review and second opinions",
|
|
5
|
+
"author": { "name": "Brian Connelly", "url": "https://github.com/briandconnelly" },
|
|
6
|
+
"repository": "https://github.com/briandconnelly/cc-plugin-codex",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"keywords": ["claude", "code-review", "collaboration", "mcp"],
|
|
9
|
+
"skills": "./skills/",
|
|
10
|
+
"mcpServers": "./.mcp.json",
|
|
11
|
+
"interface": {
|
|
12
|
+
"displayName": "Claude Code (for Codex)",
|
|
13
|
+
"shortDescription": "Ask Claude Code to review and critique your work.",
|
|
14
|
+
"longDescription": "cc-plugin-codex lets Codex call the Claude Code CLI for bounded, independent critique — code review, adversarial review, and second opinions — with read-only safety and structured findings.",
|
|
15
|
+
"developerName": "Brian Connelly",
|
|
16
|
+
"category": "Developer Tools",
|
|
17
|
+
"capabilities": ["MCP", "Skills"],
|
|
18
|
+
"defaultPrompt": [
|
|
19
|
+
"Ask Claude to review my current diff.",
|
|
20
|
+
"Have Claude attack this plan for weaknesses.",
|
|
21
|
+
"Get an independent second opinion from Claude."
|
|
22
|
+
]
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
push:
|
|
6
|
+
branches: ["main"]
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
test:
|
|
14
|
+
name: Ruff, ty, pytest (py${{ matrix.python }})
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
strategy:
|
|
17
|
+
fail-fast: false
|
|
18
|
+
matrix:
|
|
19
|
+
python: ["3.11", "3.12", "3.13"]
|
|
20
|
+
steps:
|
|
21
|
+
- name: Check out repository
|
|
22
|
+
uses: actions/checkout@v6
|
|
23
|
+
|
|
24
|
+
- name: Install uv
|
|
25
|
+
uses: astral-sh/setup-uv@v8.2.0
|
|
26
|
+
with:
|
|
27
|
+
enable-cache: true
|
|
28
|
+
cache-dependency-glob: uv.lock
|
|
29
|
+
|
|
30
|
+
- name: Set up Python
|
|
31
|
+
uses: actions/setup-python@v6
|
|
32
|
+
with:
|
|
33
|
+
python-version: ${{ matrix.python }}
|
|
34
|
+
|
|
35
|
+
- name: Sync dependencies
|
|
36
|
+
run: uv sync --locked --python ${{ matrix.python }} --group dev
|
|
37
|
+
|
|
38
|
+
- name: Lint
|
|
39
|
+
run: uv run ruff check src tests
|
|
40
|
+
|
|
41
|
+
- name: Format check
|
|
42
|
+
run: uv run ruff format --check src tests
|
|
43
|
+
|
|
44
|
+
- name: Type check
|
|
45
|
+
run: uv run ty check
|
|
46
|
+
|
|
47
|
+
- name: Test
|
|
48
|
+
run: uv run pytest -q
|
|
49
|
+
|
|
50
|
+
live-integration:
|
|
51
|
+
name: Live Claude integration
|
|
52
|
+
if: github.event_name == 'workflow_dispatch'
|
|
53
|
+
runs-on: ubuntu-latest
|
|
54
|
+
steps:
|
|
55
|
+
- name: Check out repository
|
|
56
|
+
uses: actions/checkout@v6
|
|
57
|
+
|
|
58
|
+
- name: Install uv
|
|
59
|
+
uses: astral-sh/setup-uv@v8.2.0
|
|
60
|
+
with:
|
|
61
|
+
enable-cache: true
|
|
62
|
+
cache-dependency-glob: uv.lock
|
|
63
|
+
|
|
64
|
+
- name: Set up Python
|
|
65
|
+
uses: actions/setup-python@v6
|
|
66
|
+
with:
|
|
67
|
+
python-version: "3.12"
|
|
68
|
+
|
|
69
|
+
- name: Sync dependencies
|
|
70
|
+
run: uv sync --locked --group dev
|
|
71
|
+
|
|
72
|
+
- name: Run integration tests
|
|
73
|
+
env:
|
|
74
|
+
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
|
|
75
|
+
run: uv run pytest -m integration --no-cov
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
name: Publish
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags: ["v*.*.*"]
|
|
6
|
+
|
|
7
|
+
permissions:
|
|
8
|
+
contents: read
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
test:
|
|
12
|
+
name: Ruff, ty, pytest (py${{ matrix.python }})
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
strategy:
|
|
15
|
+
fail-fast: false
|
|
16
|
+
matrix:
|
|
17
|
+
python: ["3.11", "3.12", "3.13"]
|
|
18
|
+
steps:
|
|
19
|
+
- name: Check out repository
|
|
20
|
+
uses: actions/checkout@v6
|
|
21
|
+
|
|
22
|
+
- name: Install uv
|
|
23
|
+
uses: astral-sh/setup-uv@v8.2.0
|
|
24
|
+
with:
|
|
25
|
+
enable-cache: true
|
|
26
|
+
cache-dependency-glob: uv.lock
|
|
27
|
+
|
|
28
|
+
- name: Set up Python
|
|
29
|
+
uses: actions/setup-python@v6
|
|
30
|
+
with:
|
|
31
|
+
python-version: ${{ matrix.python }}
|
|
32
|
+
|
|
33
|
+
- name: Sync dependencies
|
|
34
|
+
run: uv sync --locked --python ${{ matrix.python }} --group dev
|
|
35
|
+
|
|
36
|
+
- name: Lint
|
|
37
|
+
run: uv run ruff check src tests
|
|
38
|
+
|
|
39
|
+
- name: Format check
|
|
40
|
+
run: uv run ruff format --check src tests
|
|
41
|
+
|
|
42
|
+
- name: Type check
|
|
43
|
+
run: uv run ty check
|
|
44
|
+
|
|
45
|
+
- name: Test
|
|
46
|
+
run: uv run pytest -q
|
|
47
|
+
|
|
48
|
+
build:
|
|
49
|
+
name: Build distributions
|
|
50
|
+
needs: test
|
|
51
|
+
runs-on: ubuntu-latest
|
|
52
|
+
steps:
|
|
53
|
+
- name: Check out repository
|
|
54
|
+
uses: actions/checkout@v6
|
|
55
|
+
|
|
56
|
+
- name: Install uv
|
|
57
|
+
uses: astral-sh/setup-uv@v8.2.0
|
|
58
|
+
with:
|
|
59
|
+
enable-cache: true
|
|
60
|
+
cache-dependency-glob: uv.lock
|
|
61
|
+
|
|
62
|
+
- name: Set up Python
|
|
63
|
+
uses: actions/setup-python@v6
|
|
64
|
+
with:
|
|
65
|
+
python-version: "3.12"
|
|
66
|
+
|
|
67
|
+
- name: Build distributions
|
|
68
|
+
run: uv build
|
|
69
|
+
|
|
70
|
+
- name: Check distributions
|
|
71
|
+
run: uvx twine check dist/*
|
|
72
|
+
|
|
73
|
+
- name: Upload distributions
|
|
74
|
+
uses: actions/upload-artifact@v4
|
|
75
|
+
with:
|
|
76
|
+
name: python-package-distributions
|
|
77
|
+
path: dist/*
|
|
78
|
+
if-no-files-found: error
|
|
79
|
+
|
|
80
|
+
publish:
|
|
81
|
+
name: Publish to PyPI
|
|
82
|
+
needs: build
|
|
83
|
+
runs-on: ubuntu-latest
|
|
84
|
+
environment: pypi
|
|
85
|
+
permissions:
|
|
86
|
+
contents: read
|
|
87
|
+
id-token: write
|
|
88
|
+
steps:
|
|
89
|
+
- name: Download distributions
|
|
90
|
+
uses: actions/download-artifact@v4
|
|
91
|
+
with:
|
|
92
|
+
name: python-package-distributions
|
|
93
|
+
path: dist/
|
|
94
|
+
|
|
95
|
+
- name: Publish distributions
|
|
96
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
.venv/
|
|
3
|
+
__pycache__/
|
|
4
|
+
*.pyc
|
|
5
|
+
.pytest_cache/
|
|
6
|
+
.ruff_cache/
|
|
7
|
+
.coverage
|
|
8
|
+
.coverage.*
|
|
9
|
+
htmlcov/
|
|
10
|
+
|
|
11
|
+
# macOS
|
|
12
|
+
.DS_Store
|
|
13
|
+
|
|
14
|
+
# Claude Code local state
|
|
15
|
+
.claude/debug/
|
|
16
|
+
.claude/settings.local.json
|
|
17
|
+
|
|
18
|
+
# Superpowers brainstorming/planning docs — kept locally, not committed
|
|
19
|
+
docs/superpowers/
|
|
20
|
+
|
|
21
|
+
# Codex local wrapper marketplace for testing this plugin checkout
|
|
22
|
+
.codex-local-marketplace/
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"mcpServers": {
|
|
3
|
+
"cc-plugin-codex": {
|
|
4
|
+
"command": "uvx",
|
|
5
|
+
"args": [
|
|
6
|
+
"--from",
|
|
7
|
+
"git+https://github.com/briandconnelly/cc-plugin-codex.git@v0.1.4",
|
|
8
|
+
"cc-plugin-codex-mcp"
|
|
9
|
+
],
|
|
10
|
+
"env_vars": [
|
|
11
|
+
"ANTHROPIC_API_KEY",
|
|
12
|
+
"CC_PLUGIN_CODEX_ACCESS",
|
|
13
|
+
"CC_PLUGIN_CODEX_CLAUDE_CONFIG",
|
|
14
|
+
"CC_PLUGIN_CODEX_EFFORT",
|
|
15
|
+
"CC_PLUGIN_CODEX_MAX_BUDGET_USD",
|
|
16
|
+
"CC_PLUGIN_CODEX_MODEL",
|
|
17
|
+
"CC_PLUGIN_CODEX_TIMEOUT_SECONDS"
|
|
18
|
+
]
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `cc-plugin-codex` will be documented in this file.
|
|
4
|
+
|
|
5
|
+
This project uses pre-1.0 semantic versioning. Minor versions may change the
|
|
6
|
+
agent-visible MCP surface; patch versions are reserved for compatible fixes.
|
|
7
|
+
|
|
8
|
+
## 0.1.4 - 2026-06-06
|
|
9
|
+
|
|
10
|
+
- Added PyPI-facing package metadata, long description, project links, and
|
|
11
|
+
classifiers.
|
|
12
|
+
- Added changelog and security policy documentation.
|
|
13
|
+
- Added a Trusted Publishing workflow for tag-triggered PyPI releases.
|
|
14
|
+
- Clarified the relationship between the Codex plugin install path and the PyPI
|
|
15
|
+
server package.
|
|
16
|
+
|
|
17
|
+
## 0.1.3 - 2026-06-05
|
|
18
|
+
|
|
19
|
+
- Added explicit Claude CLI compatibility documentation and release lockstep
|
|
20
|
+
guidance.
|
|
21
|
+
- Exposed structured readiness, review, adversarial review, second-opinion, and
|
|
22
|
+
background job tools for Codex.
|
|
23
|
+
- Added local quality gates for linting, formatting, type checking, tests, and
|
|
24
|
+
coverage.
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# Compatibility
|
|
2
|
+
|
|
3
|
+
`cc-plugin-codex` is an MCP server that the Codex CLI loads and that shells out to
|
|
4
|
+
the Claude Code `claude` CLI.
|
|
5
|
+
It therefore depends on two fast-moving upstreams: the `claude` binary (the
|
|
6
|
+
delegate it drives) and the Codex host (which loads it).
|
|
7
|
+
This document maps every external assumption to where it lives in the code, how a
|
|
8
|
+
break is detected, and what to change when it breaks.
|
|
9
|
+
|
|
10
|
+
Every `claude`-side assumption is centralized in
|
|
11
|
+
[`src/cc_plugin_codex/cli_contract.py`](./src/cc_plugin_codex/cli_contract.py).
|
|
12
|
+
Changing an assumption should be a one-file edit there.
|
|
13
|
+
|
|
14
|
+
## How the plugin degrades
|
|
15
|
+
|
|
16
|
+
The design goal is to **fail loudly and safely**, never silently weaken a
|
|
17
|
+
guarantee:
|
|
18
|
+
|
|
19
|
+
- **Guarantee-bearing flags are always sent** (`cli_contract.ALWAYS_SEND_FLAGS`).
|
|
20
|
+
If `claude` removes or renames one, it rejects the invocation at argument
|
|
21
|
+
parsing — *before any model call, so zero spend* — and the failure is reported
|
|
22
|
+
as `cli_contract_changed` with repair guidance.
|
|
23
|
+
These flags carry a security, cost, or behavioral guarantee, so they are **never**
|
|
24
|
+
gated on `--help` parsing (a parsing false-negative must never drop one).
|
|
25
|
+
- **Depth/cosmetic flags are feature-detected** (`cli_contract.HELP_GATED_FLAGS`).
|
|
26
|
+
They are dropped (and noted in `meta.compat_warnings`) when the installed
|
|
27
|
+
`claude --help` does not list them, so a minor upstream change degrades instead
|
|
28
|
+
of aborting a paid run.
|
|
29
|
+
- **Version is advisory.** A `claude` major outside the tested range warns
|
|
30
|
+
(`claude_status.version_warning`) but does not block; `ready` depends only on the
|
|
31
|
+
CLI being found and authenticated.
|
|
32
|
+
|
|
33
|
+
## `claude` CLI assumptions
|
|
34
|
+
|
|
35
|
+
| Assumption | Code (cli_contract constant) | How a break is detected | If it breaks |
|
|
36
|
+
| --- | --- | --- | --- |
|
|
37
|
+
| Binary on PATH | `CLAUDE_BIN` | `claude_status.claude_found = false` | install Claude Code |
|
|
38
|
+
| `-p --output-format json` (core) | `CORE_INVOCATION` | every call errors → `cli_contract_changed`; golden-envelope test | update `CORE_INVOCATION` + `normalize.py` |
|
|
39
|
+
| `--no-chrome` (no interactive picker) ⚠️ | `ALWAYS_SEND_FLAGS` | `cli_contract_changed` at run time | update the constant |
|
|
40
|
+
| `--append-system-prompt` (critic guardrails) ⚠️ | `ALWAYS_SEND_FLAGS` | `cli_contract_changed` | update the constant; the prompt is `config.INDEPENDENT_CRITIC_PROMPT` |
|
|
41
|
+
| `--max-budget-usd` (spend cap) ⚠️ | `ALWAYS_SEND_FLAGS` | `cli_contract_changed` | update the constant |
|
|
42
|
+
| `--tools` (read-only / no-tool guarantee) ⚠️ | `ALWAYS_SEND_FLAGS` | `cli_contract_changed` | update the constant in `config.access_flags` |
|
|
43
|
+
| `--strict-mcp-config` / `--mcp-config` (drop user MCP fleet) ⚠️ | `ALWAYS_SEND_FLAGS` | `cli_contract_changed` | update `config.config_mode_flags` |
|
|
44
|
+
| `--setting-sources` / `--bare` (mode isolation) ⚠️ | `ALWAYS_SEND_FLAGS` | `cli_contract_changed` | update `config.config_mode_flags` |
|
|
45
|
+
| `--effort` + accepted levels | `HELP_GATED_FLAGS`, `VALID_EFFORTS` | dropped with `compat_warnings`; a removed *level* → `cli_contract_changed` | update `VALID_EFFORTS` |
|
|
46
|
+
| `--model`, `--disallowed-tools`, `--no-session-persistence` | `HELP_GATED_FLAGS` | dropped with `compat_warnings` | update the constant |
|
|
47
|
+
| JSON envelope keys (`is_error`, `subtype`, `result`, `total_cost_usd`, `usage.*`, `session_id`, `modelUsage`, `permission_denials`) | `ENVELOPE_KEYS`, `USAGE_KEYS`, `SUCCESS_SUBTYPES` | golden-envelope test (`tests/test_golden_envelope.py`); cost silently null if renamed | update `normalize.py` + the golden sample |
|
|
48
|
+
| `claude --version` format (`MAJOR.MINOR.PATCH`) | `VERSION_ARGS`, `SUPPORTED_MAJORS` | `claude_status.version_supported = null` | adjust the regex in `config.version_supported` |
|
|
49
|
+
| `claude auth status --text` exit code | `AUTH_STATUS_ARGS` | `claude_status.claude_authenticated = null` | update `claude.auth_status` |
|
|
50
|
+
| `claude --help` lists long flags | `HELP_ARGS` | preflight fails open (everything assumed supported) | update `preflight._parse_supported` |
|
|
51
|
+
|
|
52
|
+
⚠️ = **security/cost/behavioral guarantee.** Losing one of these would weaken
|
|
53
|
+
read-only access, the no-MCP boundary, the spend cap, or the critic behavior — so
|
|
54
|
+
the plugin refuses to run (fails closed) rather than silently proceed.
|
|
55
|
+
|
|
56
|
+
**Residual risk:** if upstream *accepts but silently no-ops* a guarantee-bearing
|
|
57
|
+
flag (rather than rejecting it), the loss cannot be detected without behavioral
|
|
58
|
+
testing. The drift detection only catches rejection.
|
|
59
|
+
|
|
60
|
+
## Codex-host assumptions
|
|
61
|
+
|
|
62
|
+
| Assumption | Where | Notes |
|
|
63
|
+
| --- | --- | --- |
|
|
64
|
+
| Plugin manifest (`mcpServers`, `skills`) | `.codex-plugin/plugin.json` | Codex marketplace schema |
|
|
65
|
+
| MCP launch (`uvx --from git+…@tag`) | `.mcp.json` | pinned to a release tag (see below) |
|
|
66
|
+
| Entry point `cc-plugin-codex-mcp` | `pyproject.toml [project.scripts]` | |
|
|
67
|
+
| MCP roots as `file://` URIs | `server.py` `_file_roots` | already tolerant; falls back to server cwd |
|
|
68
|
+
|
|
69
|
+
## Versioning & release (lockstep)
|
|
70
|
+
|
|
71
|
+
The bundled `.mcp.json` pins the server to a **versioned release tag**
|
|
72
|
+
(`vX.Y.Z`) instead of tracking the default branch, so a breaking change no longer
|
|
73
|
+
auto-ships to installed users — they update deliberately. The trade-off is that
|
|
74
|
+
fixes (including resilience fixes) only reach users on the next tagged release.
|
|
75
|
+
|
|
76
|
+
When cutting a release, bump these **together**:
|
|
77
|
+
|
|
78
|
+
1. `pyproject.toml` `version`
|
|
79
|
+
2. `.codex-plugin/plugin.json` `version`
|
|
80
|
+
3. `FINGERPRINT` in `src/cc_plugin_codex/schemas.py` — **only** when the
|
|
81
|
+
agent-visible surface changed (tool names, input/output schemas, the
|
|
82
|
+
`ErrorCode` set, the value enums, or the capability summary)
|
|
83
|
+
4. the `@vX.Y.Z` ref in `.mcp.json`
|
|
84
|
+
5. create and push the matching `vX.Y.Z` git tag
|
|
85
|
+
|
|
86
|
+
The `.mcp.json` ref and the git tag must match, or a bundled install fails to
|
|
87
|
+
resolve.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Brian Connelly
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: cc-plugin-codex
|
|
3
|
+
Version: 0.1.4
|
|
4
|
+
Summary: Call Claude Code from Codex for bounded, independent code review and second opinions
|
|
5
|
+
Project-URL: Homepage, https://github.com/briandconnelly/cc-plugin-codex
|
|
6
|
+
Project-URL: Repository, https://github.com/briandconnelly/cc-plugin-codex
|
|
7
|
+
Project-URL: Issues, https://github.com/briandconnelly/cc-plugin-codex/issues
|
|
8
|
+
Project-URL: Changelog, https://github.com/briandconnelly/cc-plugin-codex/blob/main/CHANGELOG.md
|
|
9
|
+
Project-URL: Security, https://github.com/briandconnelly/cc-plugin-codex/blob/main/SECURITY.md
|
|
10
|
+
Author: Brian Connelly
|
|
11
|
+
License-Expression: MIT
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
Keywords: claude,code-review,codex,mcp,plugin
|
|
14
|
+
Classifier: Development Status :: 3 - Alpha
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
17
|
+
Classifier: Operating System :: OS Independent
|
|
18
|
+
Classifier: Programming Language :: Python :: 3
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
23
|
+
Classifier: Topic :: Software Development
|
|
24
|
+
Requires-Python: >=3.11
|
|
25
|
+
Requires-Dist: anyio>=4
|
|
26
|
+
Requires-Dist: fastmcp>=3.4
|
|
27
|
+
Requires-Dist: pydantic>=2
|
|
28
|
+
Description-Content-Type: text/markdown
|
|
29
|
+
|
|
30
|
+
# cc-plugin-codex
|
|
31
|
+
|
|
32
|
+
Ask Claude Code for an independent code review or second opinion, straight from Codex.
|
|
33
|
+
|
|
34
|
+
`cc-plugin-codex` is review-only: Claude reviews, critiques, and advises. It does not edit
|
|
35
|
+
your code, run shell commands, or get write tools. It is the mirror image of
|
|
36
|
+
[`openai/codex-plugin-cc`](https://github.com/openai/codex-plugin-cc), which lets Claude call
|
|
37
|
+
Codex.
|
|
38
|
+
|
|
39
|
+
## Quickstart
|
|
40
|
+
|
|
41
|
+
You need:
|
|
42
|
+
|
|
43
|
+
- Codex
|
|
44
|
+
- the `claude` CLI, installed and authenticated
|
|
45
|
+
- `uvx`
|
|
46
|
+
- `git`
|
|
47
|
+
|
|
48
|
+
Check the basics:
|
|
49
|
+
|
|
50
|
+
```sh
|
|
51
|
+
claude --version
|
|
52
|
+
claude /login
|
|
53
|
+
uvx --version
|
|
54
|
+
git --version
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Add this repository as a Codex marketplace, then install the plugin from it:
|
|
58
|
+
|
|
59
|
+
```sh
|
|
60
|
+
codex plugin marketplace add briandconnelly/cc-plugin-codex
|
|
61
|
+
codex plugin add cc-plugin-codex
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Restart Codex after installing. Then ask Codex:
|
|
65
|
+
|
|
66
|
+
> Ask Claude to run `claude_status`.
|
|
67
|
+
|
|
68
|
+
`claude_status` is free. It checks whether the `claude` CLI is installed, authenticated, and
|
|
69
|
+
compatible, and shows the defaults a paid call would use.
|
|
70
|
+
|
|
71
|
+
## Distribution
|
|
72
|
+
|
|
73
|
+
The Codex plugin install path is the primary user-facing path. The bundled MCP config pins the
|
|
74
|
+
server to a versioned Git tag so installed users update deliberately.
|
|
75
|
+
|
|
76
|
+
The Python package publishes the MCP server entry point for direct use and release provenance.
|
|
77
|
+
After a PyPI release, the server can also be launched with:
|
|
78
|
+
|
|
79
|
+
```sh
|
|
80
|
+
uvx --from cc-plugin-codex==0.1.4 cc-plugin-codex-mcp
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Use it
|
|
84
|
+
|
|
85
|
+
Once `claude_status` reports `ready: true`, ask Codex in plain language:
|
|
86
|
+
|
|
87
|
+
> Ask Claude to review my current diff. Pass `workspace_root` as this repository.
|
|
88
|
+
|
|
89
|
+
Passing `workspace_root` matters. It keeps reviews pointed at your project instead of the
|
|
90
|
+
plugin install directory when the MCP client does not provide a repo root.
|
|
91
|
+
|
|
92
|
+
Other useful prompts:
|
|
93
|
+
|
|
94
|
+
- "Ask Claude to review my staged changes for security issues."
|
|
95
|
+
- "Have Claude attack this plan for weaknesses."
|
|
96
|
+
- "Get an independent second opinion from Claude on this design."
|
|
97
|
+
- "Start a background Claude review of this branch against main."
|
|
98
|
+
|
|
99
|
+
Codex uses the plugin skill to choose the right tool and arguments. Direct MCP calls are also
|
|
100
|
+
available:
|
|
101
|
+
|
|
102
|
+
| Tool | Use | Cost |
|
|
103
|
+
| --- | --- | --- |
|
|
104
|
+
| `claude_review_changes` | Review a git diff now | paid |
|
|
105
|
+
| `claude_review_changes_async` | Start a background diff review | paid |
|
|
106
|
+
| `claude_adversarial_review` | Pressure-test a plan, claim, or change | paid |
|
|
107
|
+
| `claude_ask` | Ask for a free-form second opinion | paid |
|
|
108
|
+
| `claude_status` | Check readiness and defaults | free |
|
|
109
|
+
| `claude_review_dry_run` | Preview diff/context before a review | free |
|
|
110
|
+
|
|
111
|
+
Diff review scopes are `working_tree`, `staged`, and `branch`.
|
|
112
|
+
|
|
113
|
+
```json
|
|
114
|
+
claude_review_changes({
|
|
115
|
+
"workspace_root": "/absolute/path/to/your/repo",
|
|
116
|
+
"scope": "staged",
|
|
117
|
+
"focus": "security"
|
|
118
|
+
})
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
For a long review, launch it in the background:
|
|
122
|
+
|
|
123
|
+
```json
|
|
124
|
+
claude_review_changes_async({
|
|
125
|
+
"workspace_root": "/absolute/path/to/your/repo",
|
|
126
|
+
"scope": "branch",
|
|
127
|
+
"base": "main"
|
|
128
|
+
})
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Poll with `claude_job_status`, then fetch the result with `claude_job_result`.
|
|
132
|
+
|
|
133
|
+
## Safety and cost
|
|
134
|
+
|
|
135
|
+
- Paid tools run Claude and send code or prompts to Anthropic, billed through your existing
|
|
136
|
+
`claude` login or `ANTHROPIC_API_KEY`.
|
|
137
|
+
- Free tools only inspect local state, preflight a request, or manage background jobs.
|
|
138
|
+
- Claude never receives write or Bash tools from this plugin.
|
|
139
|
+
- `access=toolless` is the default: Claude receives gathered context as text and cannot read
|
|
140
|
+
more files. `access=readonly` lets Claude use `Read`, `Grep`, and `Glob` for extra context.
|
|
141
|
+
- Secret redaction is best-effort defense in depth. Use `access=toolless` when a workspace may
|
|
142
|
+
contain secrets.
|
|
143
|
+
- `max_budget_usd` is a best-effort Claude CLI stop threshold, not a hard cap. Results report
|
|
144
|
+
actual spend in `meta.cost_usd` when available.
|
|
145
|
+
- Reviews default to `effort=xhigh` for depth. Lower `effort` to `high` or `medium` for routine
|
|
146
|
+
reviews when cost matters.
|
|
147
|
+
|
|
148
|
+
If a requested diff scope has no changes, the review tools return a passing result without
|
|
149
|
+
invoking Claude.
|
|
150
|
+
|
|
151
|
+
## Common knobs
|
|
152
|
+
|
|
153
|
+
Every setting is optional. These are the knobs most users are likely to change:
|
|
154
|
+
|
|
155
|
+
| Variable | Default | Purpose |
|
|
156
|
+
| --- | --- | --- |
|
|
157
|
+
| `CC_PLUGIN_CODEX_ACCESS` | `toolless` | `toolless` or `readonly` |
|
|
158
|
+
| `CC_PLUGIN_CODEX_CLAUDE_CONFIG` | `inherit` | `inherit`, `scoped`, or `bare` |
|
|
159
|
+
| `CC_PLUGIN_CODEX_EFFORT` | `xhigh` | `low`, `medium`, `high`, `xhigh`, or `max` |
|
|
160
|
+
| `CC_PLUGIN_CODEX_MAX_BUDGET_USD` | `1.00` | best-effort per-call budget threshold |
|
|
161
|
+
| `CC_PLUGIN_CODEX_MODEL` | unset | Claude model; unset uses the CLI default |
|
|
162
|
+
| `CC_PLUGIN_CODEX_TIMEOUT_SECONDS` | `180` | per-call timeout, clamped to 10-600 seconds |
|
|
163
|
+
| `ANTHROPIC_API_KEY` | unset | required only for `config_mode=bare` |
|
|
164
|
+
|
|
165
|
+
Set these in the environment you launch Codex from. The bundled MCP config forwards the common
|
|
166
|
+
cost, safety, model, timeout, and API-key variables to the server.
|
|
167
|
+
|
|
168
|
+
`config_mode=inherit` uses your normal Claude environment without persisting a session.
|
|
169
|
+
`scoped` drops user-global settings and user MCP servers but keeps `CLAUDE.md`. `bare` strips
|
|
170
|
+
`CLAUDE.md`, memory, and hooks, and requires `ANTHROPIC_API_KEY`.
|
|
171
|
+
|
|
172
|
+
## Troubleshooting
|
|
173
|
+
|
|
174
|
+
Start with:
|
|
175
|
+
|
|
176
|
+
> Ask Claude to run `claude_status`.
|
|
177
|
+
|
|
178
|
+
Then:
|
|
179
|
+
|
|
180
|
+
- If `claude_authenticated` is false, run `claude /login`.
|
|
181
|
+
- If the workspace looks wrong, pass `workspace_root` explicitly.
|
|
182
|
+
- If a review is large or expensive, run `claude_review_dry_run` first.
|
|
183
|
+
- If a background job id is lost, use `claude_job_list`.
|
|
184
|
+
- If `config_mode=bare` fails, confirm `ANTHROPIC_API_KEY` is set in the environment that
|
|
185
|
+
launches Codex.
|
|
186
|
+
|
|
187
|
+
## Advanced reference
|
|
188
|
+
|
|
189
|
+
Every tool returns a structured `ok`/`error` envelope. Paid results include usage metadata and
|
|
190
|
+
cost when the Claude CLI reports it. The tool contract is experimental and pre-1.0; clients can
|
|
191
|
+
pin `meta.fingerprint` to detect agent-visible changes.
|
|
192
|
+
|
|
193
|
+
The Claude CLI compatibility assumptions are centralized in
|
|
194
|
+
[`src/cc_plugin_codex/cli_contract.py`](./src/cc_plugin_codex/cli_contract.py) and documented
|
|
195
|
+
in [`COMPATIBILITY.md`](./COMPATIBILITY.md).
|
|
196
|
+
|
|
197
|
+
## Local development
|
|
198
|
+
|
|
199
|
+
Run the MCP server from a checkout:
|
|
200
|
+
|
|
201
|
+
```sh
|
|
202
|
+
codex mcp add cc-plugin-codex -- uv run --directory "$(pwd)" cc-plugin-codex-mcp
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
Run tests:
|
|
206
|
+
|
|
207
|
+
```sh
|
|
208
|
+
uv run pytest
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
The full suite enforces a 95% coverage floor. For one-file iteration:
|
|
212
|
+
|
|
213
|
+
```sh
|
|
214
|
+
uv run pytest tests/test_jobs.py --no-cov
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
Live Claude integration tests are excluded by default:
|
|
218
|
+
|
|
219
|
+
```sh
|
|
220
|
+
uv run pytest -m integration --no-cov
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
They require the `claude` CLI and make a small paid API call.
|