cc-plugin-codex 0.1.4__tar.gz → 0.2.0__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.
Files changed (47) hide show
  1. {cc_plugin_codex-0.1.4 → cc_plugin_codex-0.2.0}/.agents/plugins/marketplace.json +1 -1
  2. cc_plugin_codex-0.2.0/.codex-plugin/plugin.json +24 -0
  3. cc_plugin_codex-0.2.0/.github/dependabot.yml +11 -0
  4. cc_plugin_codex-0.2.0/.github/workflows/ci.yml +120 -0
  5. cc_plugin_codex-0.2.0/.github/workflows/publish.yml +177 -0
  6. cc_plugin_codex-0.1.4/.github/workflows/ci.yml → cc_plugin_codex-0.2.0/.github/workflows/test.yml +3 -32
  7. cc_plugin_codex-0.2.0/.mcp.json +21 -0
  8. {cc_plugin_codex-0.1.4 → cc_plugin_codex-0.2.0}/CHANGELOG.md +13 -0
  9. {cc_plugin_codex-0.1.4 → cc_plugin_codex-0.2.0}/COMPATIBILITY.md +10 -2
  10. {cc_plugin_codex-0.1.4 → cc_plugin_codex-0.2.0}/PKG-INFO +44 -17
  11. {cc_plugin_codex-0.1.4 → cc_plugin_codex-0.2.0}/README.md +43 -16
  12. {cc_plugin_codex-0.1.4 → cc_plugin_codex-0.2.0}/SECURITY.md +5 -0
  13. {cc_plugin_codex-0.1.4 → cc_plugin_codex-0.2.0/plugins/cc-plugin-codex}/skills/collaborating-with-claude/SKILL.md +1 -1
  14. {cc_plugin_codex-0.1.4 → cc_plugin_codex-0.2.0}/pyproject.toml +1 -1
  15. cc_plugin_codex-0.2.0/skills/collaborating-with-claude/SKILL.md +54 -0
  16. {cc_plugin_codex-0.1.4 → cc_plugin_codex-0.2.0}/src/cc_plugin_codex/cli_contract.py +1 -1
  17. {cc_plugin_codex-0.1.4 → cc_plugin_codex-0.2.0}/src/cc_plugin_codex/config.py +50 -0
  18. {cc_plugin_codex-0.1.4 → cc_plugin_codex-0.2.0}/src/cc_plugin_codex/jobs.py +3 -0
  19. {cc_plugin_codex-0.1.4 → cc_plugin_codex-0.2.0}/src/cc_plugin_codex/schemas.py +10 -1
  20. {cc_plugin_codex-0.1.4 → cc_plugin_codex-0.2.0}/src/cc_plugin_codex/server.py +30 -12
  21. {cc_plugin_codex-0.1.4 → cc_plugin_codex-0.2.0}/tests/test_claude.py +2 -3
  22. {cc_plugin_codex-0.1.4 → cc_plugin_codex-0.2.0}/tests/test_cli_contract.py +1 -0
  23. {cc_plugin_codex-0.1.4 → cc_plugin_codex-0.2.0}/tests/test_config.py +32 -0
  24. {cc_plugin_codex-0.1.4 → cc_plugin_codex-0.2.0}/tests/test_fingerprint.py +1 -1
  25. {cc_plugin_codex-0.1.4 → cc_plugin_codex-0.2.0}/tests/test_schemas.py +15 -1
  26. {cc_plugin_codex-0.1.4 → cc_plugin_codex-0.2.0}/tests/test_server.py +58 -2
  27. {cc_plugin_codex-0.1.4 → cc_plugin_codex-0.2.0}/uv.lock +1 -1
  28. cc_plugin_codex-0.1.4/.github/workflows/publish.yml +0 -96
  29. {cc_plugin_codex-0.1.4 → cc_plugin_codex-0.2.0}/.gitignore +0 -0
  30. {cc_plugin_codex-0.1.4 → cc_plugin_codex-0.2.0}/LICENSE +0 -0
  31. {cc_plugin_codex-0.1.4 → cc_plugin_codex-0.2.0/plugins/cc-plugin-codex}/.codex-plugin/plugin.json +0 -0
  32. {cc_plugin_codex-0.1.4 → cc_plugin_codex-0.2.0/plugins/cc-plugin-codex}/.mcp.json +0 -0
  33. {cc_plugin_codex-0.1.4 → cc_plugin_codex-0.2.0}/prek.toml +0 -0
  34. {cc_plugin_codex-0.1.4 → cc_plugin_codex-0.2.0}/src/cc_plugin_codex/__init__.py +0 -0
  35. {cc_plugin_codex-0.1.4 → cc_plugin_codex-0.2.0}/src/cc_plugin_codex/claude.py +0 -0
  36. {cc_plugin_codex-0.1.4 → cc_plugin_codex-0.2.0}/src/cc_plugin_codex/context.py +0 -0
  37. {cc_plugin_codex-0.1.4 → cc_plugin_codex-0.2.0}/src/cc_plugin_codex/normalize.py +0 -0
  38. {cc_plugin_codex-0.1.4 → cc_plugin_codex-0.2.0}/src/cc_plugin_codex/preflight.py +0 -0
  39. {cc_plugin_codex-0.1.4 → cc_plugin_codex-0.2.0}/src/cc_plugin_codex/py.typed +0 -0
  40. {cc_plugin_codex-0.1.4 → cc_plugin_codex-0.2.0}/tests/conftest.py +0 -0
  41. {cc_plugin_codex-0.1.4 → cc_plugin_codex-0.2.0}/tests/golden/claude_envelope.json +0 -0
  42. {cc_plugin_codex-0.1.4 → cc_plugin_codex-0.2.0}/tests/test_context.py +0 -0
  43. {cc_plugin_codex-0.1.4 → cc_plugin_codex-0.2.0}/tests/test_golden_envelope.py +0 -0
  44. {cc_plugin_codex-0.1.4 → cc_plugin_codex-0.2.0}/tests/test_integration.py +0 -0
  45. {cc_plugin_codex-0.1.4 → cc_plugin_codex-0.2.0}/tests/test_jobs.py +0 -0
  46. {cc_plugin_codex-0.1.4 → cc_plugin_codex-0.2.0}/tests/test_normalize.py +0 -0
  47. {cc_plugin_codex-0.1.4 → cc_plugin_codex-0.2.0}/tests/test_preflight.py +0 -0
@@ -8,7 +8,7 @@
8
8
  "name": "cc-plugin-codex",
9
9
  "source": {
10
10
  "source": "local",
11
- "path": "./"
11
+ "path": "./plugins/cc-plugin-codex"
12
12
  },
13
13
  "policy": {
14
14
  "installation": "AVAILABLE",
@@ -0,0 +1,24 @@
1
+ {
2
+ "name": "cc-plugin-codex",
3
+ "version": "0.2.0",
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,11 @@
1
+ version: 2
2
+
3
+ updates:
4
+ - package-ecosystem: "uv"
5
+ directory: "/"
6
+ schedule:
7
+ interval: "weekly"
8
+ - package-ecosystem: "github-actions"
9
+ directory: "/"
10
+ schedule:
11
+ interval: "weekly"
@@ -0,0 +1,120 @@
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
+ concurrency:
13
+ group: ci-${{ github.workflow }}-${{ github.ref }}
14
+ cancel-in-progress: true
15
+
16
+ jobs:
17
+ test:
18
+ uses: ./.github/workflows/test.yml
19
+
20
+ release-lockstep:
21
+ name: Release lockstep
22
+ runs-on: ubuntu-latest
23
+ steps:
24
+ - name: Check out repository
25
+ uses: actions/checkout@v6
26
+
27
+ - name: Validate release metadata consistency
28
+ run: |
29
+ set -euo pipefail
30
+
31
+ version="$(sed -n 's/^version = "\(.*\)"/\1/p' pyproject.toml)"
32
+ tag="v${version}"
33
+
34
+ if [[ ! "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
35
+ echo "pyproject.toml version must be X.Y.Z; got ${version}" >&2
36
+ exit 1
37
+ fi
38
+
39
+ grep -Fq "\"version\": \"${version}\"" .codex-plugin/plugin.json
40
+ grep -Fq "@${tag}" .mcp.json
41
+ grep -Fq "cc-plugin-codex==${version}" README.md
42
+ grep -Fq "## ${version} -" CHANGELOG.md
43
+
44
+ package:
45
+ name: Package checks
46
+ runs-on: ubuntu-latest
47
+ steps:
48
+ - name: Check out repository
49
+ uses: actions/checkout@v6
50
+
51
+ - name: Install uv
52
+ uses: astral-sh/setup-uv@v8.2.0
53
+ with:
54
+ enable-cache: true
55
+ cache-dependency-glob: uv.lock
56
+
57
+ - name: Set up Python
58
+ uses: actions/setup-python@v6
59
+ with:
60
+ python-version: "3.12"
61
+
62
+ - name: Sync dependencies
63
+ run: uv sync --locked --python 3.12 --group dev
64
+
65
+ - name: Build distributions
66
+ run: uv build --no-sources
67
+
68
+ - name: Check distributions
69
+ run: uvx twine check dist/*
70
+
71
+ - name: Smoke test installed wheel
72
+ run: |
73
+ set -euo pipefail
74
+
75
+ python -m venv .smoke
76
+ .smoke/bin/python -m pip install --upgrade pip
77
+ .smoke/bin/python -m pip install dist/cc_plugin_codex-*.whl
78
+ .smoke/bin/python - <<'PY'
79
+ from importlib.metadata import distribution
80
+
81
+ import cc_plugin_codex
82
+
83
+ dist = distribution("cc-plugin-codex")
84
+ scripts = [
85
+ ep
86
+ for ep in dist.entry_points
87
+ if ep.group == "console_scripts" and ep.name == "cc-plugin-codex-mcp"
88
+ ]
89
+
90
+ assert cc_plugin_codex.__version__ == dist.version
91
+ assert scripts, "cc-plugin-codex-mcp console script is missing"
92
+ scripts[0].load()
93
+ PY
94
+
95
+ live-integration:
96
+ name: Live Claude integration
97
+ if: github.event_name == 'workflow_dispatch'
98
+ runs-on: ubuntu-latest
99
+ steps:
100
+ - name: Check out repository
101
+ uses: actions/checkout@v6
102
+
103
+ - name: Install uv
104
+ uses: astral-sh/setup-uv@v8.2.0
105
+ with:
106
+ enable-cache: true
107
+ cache-dependency-glob: uv.lock
108
+
109
+ - name: Set up Python
110
+ uses: actions/setup-python@v6
111
+ with:
112
+ python-version: "3.12"
113
+
114
+ - name: Sync dependencies
115
+ run: uv sync --locked --group dev
116
+
117
+ - name: Run integration tests
118
+ env:
119
+ ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
120
+ run: uv run pytest -m integration --no-cov
@@ -0,0 +1,177 @@
1
+ name: Publish
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ inputs:
6
+ version:
7
+ description: Version to release, with or without leading v
8
+ required: true
9
+ type: string
10
+ push:
11
+ tags: ["v*.*.*"]
12
+
13
+ permissions:
14
+ contents: read
15
+
16
+ concurrency:
17
+ group: publish-${{ github.ref_name }}-${{ inputs.version }}
18
+ cancel-in-progress: false
19
+
20
+ jobs:
21
+ release-metadata:
22
+ name: Validate release metadata
23
+ runs-on: ubuntu-latest
24
+ outputs:
25
+ tag: ${{ steps.metadata.outputs.tag }}
26
+ version: ${{ steps.metadata.outputs.version }}
27
+ steps:
28
+ - name: Check out repository
29
+ uses: actions/checkout@v6
30
+ with:
31
+ fetch-depth: 0
32
+
33
+ - name: Validate version references
34
+ id: metadata
35
+ env:
36
+ EVENT_NAME: ${{ github.event_name }}
37
+ INPUT_VERSION: ${{ inputs.version }}
38
+ REF_NAME: ${{ github.ref_name }}
39
+ GITHUB_REF: ${{ github.ref }}
40
+ run: |
41
+ set -euo pipefail
42
+
43
+ if [[ "$EVENT_NAME" == "workflow_dispatch" ]]; then
44
+ if [[ "$GITHUB_REF" != "refs/heads/main" ]]; then
45
+ echo "Manual releases must run from main; got $GITHUB_REF" >&2
46
+ exit 1
47
+ fi
48
+ version="${INPUT_VERSION#v}"
49
+ tag="v${version}"
50
+ if git ls-remote --exit-code --tags origin "refs/tags/${tag}" >/dev/null 2>&1; then
51
+ echo "Tag ${tag} already exists" >&2
52
+ exit 1
53
+ fi
54
+ else
55
+ tag="$REF_NAME"
56
+ version="${tag#v}"
57
+ fi
58
+
59
+ if [[ ! "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
60
+ echo "Version must be X.Y.Z; got ${version}" >&2
61
+ exit 1
62
+ fi
63
+
64
+ grep -Fq "version = \"${version}\"" pyproject.toml
65
+ grep -Fq "\"version\": \"${version}\"" .codex-plugin/plugin.json
66
+ grep -Fq "@${tag}" .mcp.json
67
+ grep -Fq "cc-plugin-codex==${version}" README.md
68
+ grep -Fq "## ${version} -" CHANGELOG.md
69
+
70
+ {
71
+ echo "tag=${tag}"
72
+ echo "version=${version}"
73
+ } >> "$GITHUB_OUTPUT"
74
+
75
+ test:
76
+ needs: release-metadata
77
+ uses: ./.github/workflows/test.yml
78
+
79
+ build:
80
+ name: Build distributions
81
+ needs: test
82
+ runs-on: ubuntu-latest
83
+ steps:
84
+ - name: Check out repository
85
+ uses: actions/checkout@v6
86
+
87
+ - name: Install uv
88
+ uses: astral-sh/setup-uv@v8.2.0
89
+ with:
90
+ enable-cache: true
91
+ cache-dependency-glob: uv.lock
92
+
93
+ - name: Set up Python
94
+ uses: actions/setup-python@v6
95
+ with:
96
+ python-version: "3.12"
97
+
98
+ - name: Build distributions
99
+ run: uv build --no-sources
100
+
101
+ - name: Check distributions
102
+ run: uvx twine check dist/*
103
+
104
+ - name: Upload distributions
105
+ uses: actions/upload-artifact@v7
106
+ with:
107
+ name: python-package-distributions
108
+ path: dist/*
109
+ if-no-files-found: error
110
+
111
+ publish:
112
+ name: Publish to PyPI
113
+ needs: build
114
+ runs-on: ubuntu-latest
115
+ environment: pypi
116
+ permissions:
117
+ contents: read
118
+ id-token: write
119
+ steps:
120
+ - name: Download distributions
121
+ uses: actions/download-artifact@v8
122
+ with:
123
+ name: python-package-distributions
124
+ path: dist/
125
+
126
+ - name: Publish distributions
127
+ uses: pypa/gh-action-pypi-publish@release/v1
128
+
129
+ github-release:
130
+ name: Create GitHub Release
131
+ needs: [release-metadata, publish]
132
+ runs-on: ubuntu-latest
133
+ permissions:
134
+ contents: write
135
+ steps:
136
+ - name: Check out repository
137
+ uses: actions/checkout@v6
138
+ with:
139
+ fetch-depth: 0
140
+
141
+ - name: Download distributions
142
+ uses: actions/download-artifact@v8
143
+ with:
144
+ name: python-package-distributions
145
+ path: dist/
146
+
147
+ - name: Create tag if needed
148
+ env:
149
+ TAG: ${{ needs.release-metadata.outputs.tag }}
150
+ run: |
151
+ set -euo pipefail
152
+
153
+ if git ls-remote --exit-code --tags origin "refs/tags/${TAG}" >/dev/null 2>&1; then
154
+ echo "Tag ${TAG} already exists."
155
+ exit 0
156
+ fi
157
+
158
+ git config user.name "github-actions[bot]"
159
+ git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
160
+ git tag -a "$TAG" -m "cc-plugin-codex ${TAG}" "$GITHUB_SHA"
161
+ git push origin "$TAG"
162
+
163
+ - name: Create release
164
+ env:
165
+ GH_TOKEN: ${{ github.token }}
166
+ TAG: ${{ needs.release-metadata.outputs.tag }}
167
+ run: |
168
+ set -euo pipefail
169
+
170
+ if gh release view "$TAG" >/dev/null 2>&1; then
171
+ echo "GitHub Release ${TAG} already exists."
172
+ exit 0
173
+ fi
174
+
175
+ gh release create "$TAG" dist/* \
176
+ --title "cc-plugin-codex ${TAG}" \
177
+ --notes "See CHANGELOG.md for release notes."
@@ -1,10 +1,7 @@
1
- name: CI
1
+ name: Test
2
2
 
3
3
  on:
4
- pull_request:
5
- push:
6
- branches: ["main"]
7
- workflow_dispatch:
4
+ workflow_call:
8
5
 
9
6
  permissions:
10
7
  contents: read
@@ -16,7 +13,7 @@ jobs:
16
13
  strategy:
17
14
  fail-fast: false
18
15
  matrix:
19
- python: ["3.11", "3.12", "3.13"]
16
+ python: ["3.11", "3.12", "3.13", "3.14"]
20
17
  steps:
21
18
  - name: Check out repository
22
19
  uses: actions/checkout@v6
@@ -47,29 +44,3 @@ jobs:
47
44
  - name: Test
48
45
  run: uv run pytest -q
49
46
 
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,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.2.0",
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
+ }
@@ -5,6 +5,19 @@ All notable changes to `cc-plugin-codex` will be documented in this file.
5
5
  This project uses pre-1.0 semantic versioning. Minor versions may change the
6
6
  agent-visible MCP surface; patch versions are reserved for compatible fixes.
7
7
 
8
+ ## 0.2.0 - 2026-06-06
9
+
10
+ - Added prompt-injection guardrails that tell Claude to treat reviewed diffs,
11
+ evidence, context, and project files as untrusted data.
12
+ - Promoted `--no-session-persistence` to a fail-closed Claude CLI contract flag
13
+ so sensitive review sessions are not silently persisted.
14
+ - Added advisory detection for workspace Claude Code hook settings and surfaced
15
+ hook posture in status, dry-run, paid result metadata, and background jobs.
16
+ - Clarified security documentation: the plugin withholds Bash/write tools, but
17
+ Claude Code hooks can run outside the tool allowlist unless `config_mode=bare`
18
+ is used.
19
+ - Bumped the agent-visible schema fingerprint to `cc-plugin-codex/0.1/schema-13`.
20
+
8
21
  ## 0.1.4 - 2026-06-06
9
22
 
10
23
  - Added PyPI-facing package metadata, long description, project links, and
@@ -37,13 +37,14 @@ guarantee:
37
37
  | Binary on PATH | `CLAUDE_BIN` | `claude_status.claude_found = false` | install Claude Code |
38
38
  | `-p --output-format json` (core) | `CORE_INVOCATION` | every call errors → `cli_contract_changed`; golden-envelope test | update `CORE_INVOCATION` + `normalize.py` |
39
39
  | `--no-chrome` (no interactive picker) ⚠️ | `ALWAYS_SEND_FLAGS` | `cli_contract_changed` at run time | update the constant |
40
+ | `--no-session-persistence` (avoid storing review sessions on disk) ⚠️ | `ALWAYS_SEND_FLAGS` | `cli_contract_changed` | update the constant |
40
41
  | `--append-system-prompt` (critic guardrails) ⚠️ | `ALWAYS_SEND_FLAGS` | `cli_contract_changed` | update the constant; the prompt is `config.INDEPENDENT_CRITIC_PROMPT` |
41
42
  | `--max-budget-usd` (spend cap) ⚠️ | `ALWAYS_SEND_FLAGS` | `cli_contract_changed` | update the constant |
42
43
  | `--tools` (read-only / no-tool guarantee) ⚠️ | `ALWAYS_SEND_FLAGS` | `cli_contract_changed` | update the constant in `config.access_flags` |
43
44
  | `--strict-mcp-config` / `--mcp-config` (drop user MCP fleet) ⚠️ | `ALWAYS_SEND_FLAGS` | `cli_contract_changed` | update `config.config_mode_flags` |
44
45
  | `--setting-sources` / `--bare` (mode isolation) ⚠️ | `ALWAYS_SEND_FLAGS` | `cli_contract_changed` | update `config.config_mode_flags` |
45
46
  | `--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
+ | `--model`, `--disallowed-tools` | `HELP_GATED_FLAGS` | dropped with `compat_warnings` | update the constant |
47
48
  | 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
49
  | `claude --version` format (`MAJOR.MINOR.PATCH`) | `VERSION_ARGS`, `SUPPORTED_MAJORS` | `claude_status.version_supported = null` | adjust the regex in `config.version_supported` |
49
50
  | `claude auth status --text` exit code | `AUTH_STATUS_ARGS` | `claude_status.claude_authenticated = null` | update `claude.auth_status` |
@@ -81,7 +82,14 @@ When cutting a release, bump these **together**:
81
82
  agent-visible surface changed (tool names, input/output schemas, the
82
83
  `ErrorCode` set, the value enums, or the capability summary)
83
84
  4. the `@vX.Y.Z` ref in `.mcp.json`
84
- 5. create and push the matching `vX.Y.Z` git tag
85
+
86
+ After the release commit is on `main`, run the `Publish` GitHub Actions workflow
87
+ manually with version `X.Y.Z`. The workflow validates the lockstep references,
88
+ runs the test matrix, builds and checks the distributions, publishes to PyPI,
89
+ then creates the matching `vX.Y.Z` git tag and GitHub Release.
90
+
91
+ Pushing a matching `vX.Y.Z` tag manually is still supported as an escape hatch;
92
+ it runs the same validation and publishing workflow.
85
93
 
86
94
  The `.mcp.json` ref and the git tag must match, or a bundled install fails to
87
95
  resolve.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cc-plugin-codex
3
- Version: 0.1.4
3
+ Version: 0.2.0
4
4
  Summary: Call Claude Code from Codex for bounded, independent code review and second opinions
5
5
  Project-URL: Homepage, https://github.com/briandconnelly/cc-plugin-codex
6
6
  Project-URL: Repository, https://github.com/briandconnelly/cc-plugin-codex
@@ -29,6 +29,10 @@ Description-Content-Type: text/markdown
29
29
 
30
30
  # cc-plugin-codex
31
31
 
32
+ [![CI](https://github.com/briandconnelly/cc-plugin-codex/actions/workflows/ci.yml/badge.svg)](https://github.com/briandconnelly/cc-plugin-codex/actions/workflows/ci.yml)
33
+ [![Python 3.11+](https://img.shields.io/badge/python-3.11%2B-blue.svg)](./pyproject.toml)
34
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](./LICENSE)
35
+
32
36
  Ask Claude Code for an independent code review or second opinion, straight from Codex.
33
37
 
34
38
  `cc-plugin-codex` is review-only: Claude reviews, critiques, and advises. It does not edit
@@ -36,12 +40,20 @@ your code, run shell commands, or get write tools. It is the mirror image of
36
40
  [`openai/codex-plugin-cc`](https://github.com/openai/codex-plugin-cc), which lets Claude call
37
41
  Codex.
38
42
 
43
+ ## What it does
44
+
45
+ - Lets Codex call the Claude Code CLI through MCP.
46
+ - Sends Claude bounded context for reviews, critiques, and second opinions.
47
+ - Returns structured findings Codex can summarize or act on.
48
+ - Keeps Codex as the actor and Claude as a read-only reviewer.
49
+
39
50
  ## Quickstart
40
51
 
41
52
  You need:
42
53
 
43
54
  - Codex
44
55
  - the `claude` CLI, installed and authenticated
56
+ - Python 3.11 or newer
45
57
  - `uvx`
46
58
  - `git`
47
59
 
@@ -68,18 +80,6 @@ Restart Codex after installing. Then ask Codex:
68
80
  `claude_status` is free. It checks whether the `claude` CLI is installed, authenticated, and
69
81
  compatible, and shows the defaults a paid call would use.
70
82
 
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
83
  ## Use it
84
84
 
85
85
  Once `claude_status` reports `ready: true`, ask Codex in plain language:
@@ -96,6 +96,9 @@ Other useful prompts:
96
96
  - "Get an independent second opinion from Claude on this design."
97
97
  - "Start a background Claude review of this branch against main."
98
98
 
99
+ Use this when you want a second model to look for bugs, regressions, missing tests, security
100
+ issues, or weak assumptions before you merge or commit to a design.
101
+
99
102
  Codex uses the plugin skill to choose the right tool and arguments. Direct MCP calls are also
100
103
  available:
101
104
 
@@ -110,11 +113,13 @@ available:
110
113
 
111
114
  Diff review scopes are `working_tree`, `staged`, and `branch`.
112
115
 
116
+ Review staged changes with a test-coverage focus:
117
+
113
118
  ```json
114
119
  claude_review_changes({
115
120
  "workspace_root": "/absolute/path/to/your/repo",
116
121
  "scope": "staged",
117
- "focus": "security"
122
+ "focus": "tests"
118
123
  })
119
124
  ```
120
125
 
@@ -135,7 +140,9 @@ Poll with `claude_job_status`, then fetch the result with `claude_job_result`.
135
140
  - Paid tools run Claude and send code or prompts to Anthropic, billed through your existing
136
141
  `claude` login or `ANTHROPIC_API_KEY`.
137
142
  - Free tools only inspect local state, preflight a request, or manage background jobs.
138
- - Claude never receives write or Bash tools from this plugin.
143
+ - Claude never receives write or Bash tools from this plugin. Claude Code hooks are not
144
+ tools and may run in `config_mode=inherit`/`scoped`; use `config_mode=bare` for
145
+ untrusted workspaces.
139
146
  - `access=toolless` is the default: Claude receives gathered context as text and cannot read
140
147
  more files. `access=readonly` lets Claude use `Read`, `Grep`, and `Glob` for extra context.
141
148
  - Secret redaction is best-effort defense in depth. Use `access=toolless` when a workspace may
@@ -148,6 +155,14 @@ Poll with `claude_job_status`, then fetch the result with `claude_job_result`.
148
155
  If a requested diff scope has no changes, the review tools return a passing result without
149
156
  invoking Claude.
150
157
 
158
+ ## Mental model
159
+
160
+ Codex remains responsible for deciding what to do with Claude's feedback. Claude receives only
161
+ the context the plugin provides, or read-only file access when you explicitly allow
162
+ `access=readonly`. The plugin does not give Claude write tools, Bash tools, or permission to
163
+ modify your workspace. In `inherit` and `scoped`, Claude Code may still load workspace hooks
164
+ from `.claude/settings*.json`; those hooks execute outside the tool allowlist.
165
+
151
166
  ## Common knobs
152
167
 
153
168
  Every setting is optional. These are the knobs most users are likely to change:
@@ -166,8 +181,8 @@ Set these in the environment you launch Codex from. The bundled MCP config forwa
166
181
  cost, safety, model, timeout, and API-key variables to the server.
167
182
 
168
183
  `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`.
184
+ `scoped` drops user-global settings and user MCP servers but keeps `CLAUDE.md` and workspace
185
+ hooks. `bare` strips `CLAUDE.md`, memory, and hooks, and requires `ANTHROPIC_API_KEY`.
171
186
 
172
187
  ## Troubleshooting
173
188
 
@@ -184,6 +199,18 @@ Then:
184
199
  - If `config_mode=bare` fails, confirm `ANTHROPIC_API_KEY` is set in the environment that
185
200
  launches Codex.
186
201
 
202
+ ## Distribution
203
+
204
+ The Codex plugin install path is the primary user-facing path. The bundled MCP config pins the
205
+ server to a versioned Git tag so installed users update deliberately.
206
+
207
+ The Python package publishes the MCP server entry point for direct use and release provenance.
208
+ After a PyPI release, the server can also be launched with:
209
+
210
+ ```sh
211
+ uvx --from cc-plugin-codex==0.2.0 cc-plugin-codex-mcp
212
+ ```
213
+
187
214
  ## Advanced reference
188
215
 
189
216
  Every tool returns a structured `ok`/`error` envelope. Paid results include usage metadata and