How to use Codex from Claude Code: three ways to delegate
Use Codex from Claude Code through Bash with codex exec, OpenAI's plugin for reviews and background tasks, or foreman for supervised worktree runs.
Riley Hilliard8 min read
On this page
You can use Codex from Claude Code by asking Claude to run codex exec through Bash. With the Codex CLI installed and logged in, Claude can send a task and read its result.
For recurring use, OpenAI’s Codex plugin adds review commands and background delegation inside Claude Code. foreman is another option when you want a contract per task, separate worktrees and a daemon that routes Codex’s questions back to Claude before Claude reviews the changes and commits.
How do you use Codex from Claude Code?
Start with the shell route for a bounded task. Ask Claude:
Use codex exec through Bash to investigate the failing test. Give Codex the failure and relevant file paths. Ask it to report its diagnosis without editing files, then assess its findings.
You stay in the Claude conversation; Claude writes the Codex prompt and reads the response. If you want to invoke the command yourself, Claude Code’s ! prefix runs a shell command and adds its output to the conversation.
| Approach | Where work runs | During a long task | Handling a decision in this workflow |
|---|---|---|---|
codex exec through Bash |
Selected working directory, or a new worktree with --worktree |
Claude can background the Bash command and read its output file | Ask for blockers in the response, then resume with clarification |
| OpenAI’s Codex plugin | Same repository checkout as Claude Code | --background, /codex:status and /codex:result |
Read the findings and send a follow-up with /codex:rescue --resume |
| foreman | A new or prepared linked worktree per run | A local daemon owns the run between CLI calls; Claude waits for attention | Codex calls ask_orchestrator; Claude answers the question id |
Keep review and commit as explicit steps in all three workflows. Tell Codex to leave edits uncommitted, have Claude inspect the diff and run the repository’s checks, then decide whether to commit. foreman’s delegate instructions already ask for uncommitted changes; foreman itself never commits or merges. The checklist for reviewing Codex changes with Claude Code walks through each step.
Running codex exec from Claude Code’s shell
For a read-only investigation, enter this in Claude Code:
!codex exec "Investigate the failing test. Do not edit files. Report the likely cause and any unresolved questions."
codex exec is non-interactive: it accepts a task prompt, streams progress to stderr and prints the final agent message to stdout. Read-only is the default. For implementation, Claude can run this through Bash:
codex exec --sandbox workspace-write --worktree \
"Fix the failing test with the smallest patch. Run the relevant tests. Leave changes uncommitted and report the worktree path, changes, checks and blockers."
--sandbox workspace-write permits workspace edits. --worktree asks Codex to create a managed Git worktree, so separate working files are available without foreman. Use -C with a directory path when you want to select an existing working root.
Claude Code already supports background Bash commands. Ask Claude to background a longer invocation, or press Ctrl+B while it runs. Claude can read the background output file while remaining available for new prompts. Claude Code normally cleans up background Bash tasks when it exits, so plan around that lifetime. Running Codex in the background covers the other native options.
Use codex exec resume with the recorded session id to continue the task with more instructions. A successful process exit is only one piece of evidence: read the final message and check the test results before accepting the patch.
What does OpenAI’s Codex plugin for Claude Code do?
OpenAI’s Codex plugin provides reviews and delegated tasks through your local Codex app server. It uses the installed codex binary and existing local authentication and configuration. Its documented setup sequence, entered inside Claude Code, is:
/plugin marketplace add openai/codex-plugin-cc
/plugin install codex@openai-codex
/reload-plugins
/codex:setup
Use /codex:review for a read-only review of uncommitted changes, or add --base main to review branch changes against main. For a delegated implementation task, use /codex:rescue:
/codex:rescue --background fix the failing test with the smallest patch; run the relevant tests; leave changes uncommitted and report blockers
/codex:status
/codex:result
Rescue supports background execution and continuing a previous task with --resume. /codex:cancel cancels an active background job. The plugin’s README says it uses the same repository checkout and machine environment, so choose the checkout before starting work. You can start Claude Code in its own worktree with claude --worktree codex-task.
Choose the plugin if review commands and background delegation cover the job. It already supports both; you don’t need foreman merely to have Claude hand work to Codex. The Codex plugin guide covers every command.
When should Claude Code delegate to Codex in a worktree?
Use a separate worktree when you want to keep a delegated patch apart from the files Claude is editing. Git worktrees have separate working files, HEAD and index, while sharing repository storage. Both codex exec --worktree and Claude Code’s worktree support can supply that separation. Running Codex in a git worktree covers setup and cleanup.
foreman fits when Claude should supervise implementation runs through completion, often several at once. Claude writes a task contract with allowed files and required checks. foreman starts Codex in its assigned worktree, and a local daemon manages persistent app-server threads between CLI calls.
foreman guide
foreman guide contract
Fill the contract template with the task’s scope and acceptance criteria. Claude can then start a run with foreman start, supplying --contract and either --new-worktree or a prepared --worktree. New worktrees start at the caller’s HEAD unless you choose another base with --from. How to give Codex a coding task shows what a good brief contains.
$ foreman start site-scaffold --new-worktree --setup "bun install && cd site && bun install" --contract site-scaffold.md --write --model gpt-sol --wait
site-scaffold
~/.foreman/runs/site-scaffold
worktree: ~/src/foreman/.claude/worktrees/site-scaffold
branch: foreman/site-scaffold
done site-scaffold turn 1
run: site-scaffold idle 22m32s (gpt-sol, high, priority, write)
dir: ~/.foreman/runs/site-scaffold
worktree: ~/src/foreman/.claude/worktrees/site-scaffold
branch: foreman/site-scaffold (foreman-created, base aef7e30c8438e7eeddac7099008c6e0fb51b429f)
turn: 1 (start)
question: (none)
commands: 169 (24 failed, 0 blocked by repo hooks)
last: /bin/zsh -lc 'on-port 4323' exit=1
files written:
site/.astro/collections/blog.schema.json
site/.astro/content-assets.mjs
site/.astro/content-modules.mjs
site/.astro/content.d.ts
site/.astro/data-store.json
site/.astro/settings.json
site/.astro/types.d.ts
site/.claude/README.md
site/.env.example
site/.gitignore
site/.node-version
site/.stacks/NOTES.md
site/.stacks/state/.playwright-cli/page-2026-11-06T09-16-38-026Z.yml
site/.stacks/state/.playwright-cli/page-2026-11-06T09-16-44-815Z.yml
site/.stacks/state/playwright-qa/console-2026-11-06T09-03-52-977Z.log
site/.stacks/state/playwright-qa/page-2026-11-06T09-03-53-075Z.yml
site/.stacks/state/playwright-qa/page-2026-11-06T09-05-31-225Z.yml
site/.stacks/state/playwright-qa/page-2026-11-06T09-05-51-816Z.yml
site/.stacks/state/playwright-qa/page-2026-11-06T09-06-05-382Z.yml
site/.stacks/state/playwright-qa/page-2026-11-06T09-06-05-767Z.yml
site/.stacks/state/playwright-qa/page-2026-11-06T09-06-19-312Z.yml
site/.stacks/state/runs.jsonl
site/AGENTS.md
site/Makefile
site/README.md
site/astro.config.mjs
site/bun.lock
site/docs/DEVELOPMENT.md
site/package.json
site/public/default-og.svg
site/src/components/PostList.tsx
site/src/components/posts.test.tsx
site/src/config.ts
site/src/content/blog/welcome.mdx
site/src/layouts/BaseLayout.astro
site/src/layouts/PostLayout.astro
site/src/lib/analytics.test.ts
site/src/lib/analytics.ts
site/src/lib/events.ts
site/src/pages/404.astro
site/src/pages/blog/[...slug].astro
site/src/pages/blog/index.astro
site/src/pages/blog/rss.xml.ts
site/src/pages/index.astro
site/src/styles/global.css
site/src/styles/sf-theme.css
site/tests/build.test.mjs
site/tests/deploy.test.mjs
site/vitest.config.ts
site/wrangler.jsonc
outside May change: (none)
new in git status since start:
D site/src/pages/[...slug].astro
D site/src/pages/rss.xml.ts
M site/.claude/README.md
M site/.env.example
M site/.gitignore
M site/AGENTS.md
M site/Makefile
M site/README.md
M site/astro.config.mjs
M site/docs/DEVELOPMENT.md
M site/package.json
M site/public/default-og.svg
M site/src/components/PostList.tsx
M site/src/components/posts.test.tsx
M site/src/config.ts
M site/src/content/blog/welcome.mdx
M site/src/layouts/BaseLayout.astro
M site/src/layouts/PostLayout.astro
M site/src/lib/analytics.test.ts
M site/src/lib/analytics.ts
M site/src/lib/events.ts
M site/src/pages/404.astro
M site/src/pages/index.astro
M site/src/styles/global.css
M site/tests/build.test.mjs
M site/tests/deploy.test.mjs
M site/vitest.config.ts
M site/wrangler.jsonc
?? site/.node-version
?? site/bun.lock
?? site/src/pages/blog/[...slug].astro
?? site/src/pages/blog/index.astro
?? site/src/pages/blog/rss.xml.ts
?? site/src/styles/sf-theme.css
tokens: 17.1M in (99% cached), 53K out
Hand-off (turn 1):
1. **Summary**
The site foundation is green. Dependencies, shared UI styles, consent analytics, blog relocation, and Pages configuration are ready; `/` remains a placeholder. Changes are uncommitted, confined to `site/`, and nothing was pushed or deployed.
2. **Files**
All paths below are relative to `site/`.
| Files | Change |
|---|---|
| `package.json`, `bun.lock`, `.node-version` | Installed dependencies and recorded Bun/Node versions. |
| `.env.example`, `.gitignore` | Documented analytics variables; ignored Wrangler output. |
| `AGENTS.md`, `README.md`, `docs/DEVELOPMENT.md` | Filled setup, publishing, analytics, deployment, and workaround guidance. |
| `.claude/README.md` | Removed the remaining scaffold marker. |
| `Makefile`, `wrangler.jsonc` | Added deployment targets, credential checks, and compatibility date. |
| `astro.config.mjs`, `src/config.ts` | Production URL, blog sitemap paths, metadata, and one syntax theme. |
| `public/default-og.svg` | Replaced scaffold branding with foreman. |
| `src/pages/index.astro`, `src/pages/404.astro` | Placeholder landing page and home recovery link. |
| `src/pages/blog/index.astro` | Moved the blog listing under `/blog`. |
| `src/pages/[...slug].astro` → `src/pages/blog/[...slug].astro` | Relocated post routes and `getStaticPaths`. |
| `src/pages/rss.xml.ts` → `src/pages/blog/rss.xml.ts` | Relocated RSS `GET` and post links. |
| `src/content/blog/welcome.mdx` | Marked the welcome post draft. |
| `src/components/PostList.tsx`, `src/components/posts.test.tsx` | Updated and tested `/blog/<slug>` links. |
| `src/layouts/BaseLayout.astro`, `src/layouts/PostLayout.astro` | Shared consent banner, footer privacy link, metadata, and single-theme prose. |
| `src/styles/global.css`, `src/styles/sf-theme.css` | Shared UI imports, layer ordering, and marked placeholder tokens. |
| `src/lib/events.ts` | Declared the four typed event/property contracts. |
| `src/lib/analytics.ts` | Implemented `applyConsent`, site stamping, withdrawal cleanup, restoration handling, and Logs exclusion. |
| `src/lib/analytics.test.ts`, `vitest.config.ts` | Real SDK offline coverage, including remote console capture and cached-page restoration. |
| `tests/build.test.mjs` | Empty-production assertions, preserved publishing coverage, and env-aware `assertAnalyticsBundle`. |
| `tests/deploy.test.mjs` | Updated Pages routes, redirects, draft exclusion, and feed caching checks. |
Local findings and QA notes are in ignored `site/.stacks/NOTES.md`. The manifest and protected design/product/fixture paths were untouched.
3. **Decisions**
Applied the contract’s decisions. `/blog` is canonical under `trailingSlash: "never"`; Pages redirects `/blog/`, while Astro dev displays its trailing-slash diagnostic.
Documented three dependency workarounds: TypeScript 6 for checker compatibility, matching `@emnapi/runtime`, and PostHog’s session-storage cleanup/internal Logs override. Fonts are installed but unwired; theme tokens remain placeholders.
4. **Checks**
| Command | Final result |
|---|---|
| `make install`, `CI=1 make install` | Passed, including frozen lockfile. |
| `make lint` | Passed. |
| `make check` | Passed: 0 errors, warnings, or hints. |
| `make test` | Passed: 22 tests across 5 files. |
| `make coverage` | Passed: 80% statements, 81.17% lines. |
| `make build` | Passed: 5 build assertions. |
| `PUBLIC_POSTHOG_KEY=phc_test make build` | Passed; analytics/banner code present. |
| `PUBLIC_POSTHOG_KEY= make build` | Passed; analytics/banner JavaScript absent. |
| `make deploy-check` | Passed: 5 build and 5 Pages assertions. |
| `PORT_WEB=4323 stacks verify` | **Green: 12 passed, 0 failed, 0 skipped; 17.1s.** |
| `git diff --check` | Passed. |
Changed test files each passed three isolated runs: analytics 10 tests, components 3, build 5, deployment 5. The full suite passed afterward.
Also exercised `make help`, `make format`, `make clean`, `make new-article`, and `make preview`. Both manual deploy targets correctly refused missing credentials with expected exit 2.
Browser QA covered `/`, `/blog/`, canonical `/blog`, a missing URL, the dev-only welcome draft, and its hydrated read toggle. Keyed production showed the shared banner; Accept/Decline persisted across reloads. Production excludes post pages and lists only `/` in the sitemap. All QA servers are stopped.
5. **Review**
Report: [review.md](/tmp/scratch).
The single independent review reported three findings, all reproduced and resolved:
- Remote console capture bypassed `before_send`: disabled Logs and added remote-config coverage.
- Cached consent survived sibling withdrawal: added live consent gating and persisted-`pageshow` cleanup.
- Build assertions ignored env files: switched to Vite production env precedence and tested a keyed `.env.production` build.
Affected checks were rerun. No second review was performed.
6. **Look closer at**
The PostHog internal extension override and session-storage key cleanup deserve attention during SDK upgrades. Live recordings were not sent; SDK tests and browser analytics requests stayed offline. The scaffold still has no favicon.
7. **Open**
No foundation blockers or unanswered questions. External setup remains: connect Pages and the custom domain, configure the shared PostHog key, and enable cookieless tracking. Landing design, final tokens, font imports, and event callers remain with the orchestrator.
cursor: eyJfdGFnIjoiR3JvdXBDdXJzb3IiLCJncm91cCI6In4vc3JjL2ZvcmVtYW4iLCJwb3NpdGlvbnMiOnsic2l0ZS1zY2FmZm9sZCI6eyJpZGVudGl0eSI6IjIwMjYtMTEtMDZUMDg6NTY6MzMuMzQ2WjowMWExYjAxMi1mMzU5LTdjOTMtODhkYS0wYzIwYzFmZjRmNGEiLCJzZXEiOjE2OTF9fX0
next: foreman wait site-scaffold --after eyJfdGFnIjoiR3JvdXBDdXJzb3IiLCJncm91cCI6In4vc3JjL2ZvcmVtYW4iLCJwb3NpdGlvbnMiOnsic2l0ZS1zY2FmZm9sZCI6eyJpZGVudGl0eSI6IjIwMjYtMTEtMDZUMDg6NTY6MzMuMzQ2WjowMWExYjAxMi1mMzU5LTdjOTMtODhkYS0wYzIwYzFmZjRmNGEiLCJzZXEiOjE2OTF9fX0
--wait waits for the named run to need attention. Without it, start returns after starting the run and the daemon owns its continuing lifetime. For several runs, foreman wait --all supervises the current repository group. Claude can inspect foreman status and use foreman result to read the latest available hand-off before reviewing the diff. Running multiple Codex agents in parallel covers choosing tasks and merge order.
foreman defaults to read-only. Implementation requires --write, which selects full host and network access without approval prompts. The worktree separates Git edits; it does not restrict host access. After Codex finishes, Claude still needs to review changed and new files and run the repository gate before committing. Whether a git worktree sandboxes Codex explains the difference.
What happens when Codex has a question mid-task?
For the direct shell and plugin examples above, ask Codex to report unresolved decisions in its findings, then send clarification through a resumed task. This keeps the request bounded when a final report is enough.
foreman provides a question-and-answer path during the run. New threads receive an ask_orchestrator tool; when Codex uses it, foreman holds the call and exposes a question id to Claude. Claude can answer it or defer a decision that needs a person:
foreman answer test-fix q1 "Keep the public interface unchanged."
foreman defer test-fix q2 "Waiting for the user's decision."
Those names and ids are examples; use the ones in the run’s digest. After the default fifteen-minute question timeout, foreman sends deferral guidance to continue independent work and leave unresolved decisions in the hand-off. A late answer can steer the running turn or start a follow-up after it becomes inactive. The deferral instructions are prompt guidance, so review how Codex handled the decision. Codex waiting for input also covers approval prompts and hung commands.
Daemon ownership also has limits. A daemon restart marks previously active runs lost. On resumed threads, question-tool delivery depends on Codex retaining the tool. Read the run’s status and worktree before continuing after a supervision failure.
What you need installed
For the shell route, you need Claude Code and an authenticated Codex CLI. codex login supports ChatGPT sign-in; use that account’s Codex entitlement and limits if you’re using a ChatGPT plan. Codex also supports API-key authentication. The plugin uses that same local login and documents Node.js 18.18 or later as a requirement.
For foreman installation, use macOS or Linux on arm64 or x64, git, a repository with at least one commit and Node 26 or newer for the npm launcher. foreman 0.1.0 checks its protocol against Codex CLI 0.166.0:
npm i -g @openai/[email protected]
codex login
npm i -g @steamfield/foreman
foreman skill install
foreman doctor
If the repository has .codex/hooks.json, open Codex in the main checkout, trust the project if prompted and inspect and approve the hooks through /hooks. Read doctor’s probes even when it exits successfully; foreman never approves hooks itself. Then ask Claude Code to use the foreman skill to delegate the task and review the resulting work. If they still don’t run, see Codex hooks not trusted.
More from the blog
- Codex plugin for Claude Code: a guide
Install the Codex plugin for Claude Code, run setup, then use its slash commands for read-only reviews, delegated fixes and session transfers.
- Codex hooks not trusted: how to fix it
Fix Codex hooks not trusted by trusting the project's configuration, then reviewing and approving each current hook definition through /hooks.
- Codex waiting for input: what it wants
Codex waiting for input may mean an approval, a question, or an unfinished command; inspect the last event and answer or adjust the matching setting.