Migrate Claude workflows to Codex (and back) with one command

Read the field note below to see how we apply this pattern in real Codex projects.

verified 2 days ago
Security: unaudited
DIFFICULTY intermediateTIME 18 minCATEGORY workflowEdit on GitHub →
Need this in production?

Turn this cable into a shipping system.

We help teams deploy reliable AI workflows with architecture, implementation, and hardening support.

A migration sprint broke on day one because half the team had .claude assets and the other half had .codex assets. We were copying by hand and introducing subtle drift in permissions and command packs.

We fixed it by making conversion deterministic in the frenxt CLI.

Commands

Claude to Codex:

npx frenxt-cables convert claude-to-codex --source . --target .

Claude to Codex (legacy prompt output):

npx frenxt-cables convert claude-to-codex --source . --target . --commands-as prompts

Claude to Codex (skills + prompts):

npx frenxt-cables convert claude-to-codex --source . --target . --commands-as both

Codex to Claude:

npx frenxt-cables convert codex-to-claude --source . --target .

claude-to-codex defaults to --commands-as skills, and both directions support --dry-run and --force.

Mapping we use

  • .claude/skills/**/SKILL.md <-> .agents/skills/**/SKILL.md
  • .claude/commands/**/*.md <-> .agents/skills/cmd-*/SKILL.md (default path)
  • .claude/commands/**/*.md <-> .codex/prompts/**/*.md (optional legacy output via --commands-as prompts|both)
  • CLAUDE.md / .claude/CLAUDE.md <-> AGENTS.md
  • .claude/settings.json permissions <-> .codex/rules/default.rules

The rule conversion is intentionally conservative:

  • Claude Bash(...) permissions become Codex prefix_rule(...) entries.
  • Non-Bash permissions are skipped with warnings.

Practical rollout pattern

  1. Run --dry-run and inspect planned writes.
  2. Commit converted files in a dedicated migration branch.
  3. Run one real task in each agent to validate behavior.
  4. Keep both formats for one iteration if the team is still mixed.

This gave us repeatable interop without blocking on a full-agent cutover.

More from @frenxt

Share this cable