From sync-claude-skills-to-codex
Syncs Claude Code skills from plugin cache (~/.claude/plugins/cache/) and personal (~/.claude/skills/) folders to Codex CLI (~/.codex/skills/). Installs ~/bin/list-skills enumerator. Uses markers to preserve manual skills. Run after new plugin installs.
How this skill is triggered — by the user, by Claude, or both
Slash command
/sync-claude-skills-to-codex:sync-claude-skills-to-codexThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Synchronize Claude Code skills to Codex CLI so both tools share the same skill library.
Synchronize Claude Code skills to Codex CLI so both tools share the same skill library.
What it does:
~/.codex/skills/~/.claude/plugins/cache/) and personal skills (~/.claude/skills/)list-skills enumerator in ~/bin/ for skill discovery.synced-from-claude marker to track managed skills (safe to update on re-runs)~/.codex/skills/Arguments: #$ARGUMENTS
Options:
/sync-claude-skills-to-codex — Run full sync (respects marker files)/sync-claude-skills-to-codex --force — Force sync ALL skills, overwriting existing ones/sync-claude-skills-to-codex list — Just list current skills (doesn't sync)/sync-claude-skills-to-codex --dry-run — Show what would be syncedThe .synced-from-claude marker file is a provenance tracking mechanism:
On first sync: When a skill is copied to ~/.codex/skills/, a .synced-from-claude file is created inside the skill folder containing the source path.
On subsequent syncs:
Why this matters: If you manually create or customize a skill in ~/.codex/skills/, it won't have the marker file, so the sync won't accidentally overwrite your work.
Force flag: Use --force to ignore marker file checks and sync everything. This will overwrite ALL skills including manual ones.
First, check if --force flag is present in arguments:
# Set FORCE_SYNC based on arguments
FORCE_SYNC=false
case "#$ARGUMENTS" in
*--force*) FORCE_SYNC=true ;;
esac
echo "Force sync: $FORCE_SYNC"
Run all steps as a single bash script to avoid shell compatibility issues:
bash -c '
CODEX_SKILLS="$HOME/.codex/skills"
CLAUDE_PLUGINS="$HOME/.claude/plugins/cache"
CLAUDE_PERSONAL="$HOME/.claude/skills"
MARKER_FILE=".synced-from-claude"
FORCE_SYNC="'"$FORCE_SYNC"'"
# Step 1: Ensure directories exist
mkdir -p "$CODEX_SKILLS" "$HOME/bin"
# Step 2: Sync plugin skills
echo "=== Syncing Claude plugin skills ==="
if [ -d "$CLAUDE_PLUGINS" ]; then
find "$CLAUDE_PLUGINS" -name "SKILL.md" -path "*/skills/*" 2>/dev/null | while read skill_file; do
skill_dir=$(dirname "$skill_file")
skill_name=$(basename "$skill_dir")
# Skip hidden directories (POSIX compatible)
case "$skill_name" in .*) continue ;; esac
target_dir="$CODEX_SKILLS/$skill_name"
# Handle symlinks first (migration from old version) - always replace
if [ -L "$target_dir" ]; then
rm "$target_dir"
echo "MIGRATE: $skill_name (removing old symlink)"
# Skip if manual (non-synced) directory exists (unless --force)
elif [ -d "$target_dir" ] && [ ! -f "$target_dir/$MARKER_FILE" ] && [ "$FORCE_SYNC" != "true" ]; then
echo "SKIP: $skill_name (manual skill exists, use --force to overwrite)"
continue
fi
# Remove existing synced copy and replace with fresh copy
if [ -d "$target_dir" ]; then
rm -rf "$target_dir"
fi
cp -r "$skill_dir" "$target_dir"
echo "$skill_dir" > "$target_dir/$MARKER_FILE"
echo "SYNC: $skill_name"
done
fi
# Step 3: Sync personal skills
echo ""
echo "=== Syncing Claude personal skills ==="
if [ -d "$CLAUDE_PERSONAL" ]; then
for skill_dir in "$CLAUDE_PERSONAL"/*/; do
[ -f "${skill_dir}SKILL.md" ] || continue
skill_name=$(basename "$skill_dir")
# Skip hidden directories (POSIX compatible)
case "$skill_name" in .*) continue ;; esac
target_dir="$CODEX_SKILLS/$skill_name"
# Handle symlinks first (migration from old version) - always replace
if [ -L "$target_dir" ]; then
rm "$target_dir"
echo "MIGRATE: $skill_name (removing old symlink)"
# Skip if manual (non-synced) directory exists (unless --force)
elif [ -d "$target_dir" ] && [ ! -f "$target_dir/$MARKER_FILE" ] && [ "$FORCE_SYNC" != "true" ]; then
echo "SKIP: $skill_name (manual skill exists, use --force to overwrite)"
continue
fi
# Remove existing synced copy and replace with fresh copy
if [ -d "$target_dir" ]; then
rm -rf "$target_dir"
fi
cp -r "${skill_dir%/}" "$target_dir"
echo "${skill_dir%/}" > "$target_dir/$MARKER_FILE"
echo "SYNC: $skill_name"
done
fi
# Step 4: Report results
echo ""
echo "=== Sync Complete ==="
echo "Skills in: $CODEX_SKILLS/"
ls -la "$CODEX_SKILLS/" | head -20
'
If list-skills is not already installed, copy it from the skill directory:
# Find the skill directory (works whether installed as plugin or personal skill)
SKILL_DIR=$(find ~/.claude -name "list-skills.py" -path "*sync-claude-skills-to-codex*" 2>/dev/null | head -1 | xargs dirname)
if [ -n "$SKILL_DIR" ] && [ ! -f "$HOME/bin/list-skills" ]; then
cp "$SKILL_DIR/list-skills.py" "$HOME/bin/list-skills"
chmod +x "$HOME/bin/list-skills"
echo "INSTALLED: ~/bin/list-skills"
fi
# List all synced skills
ls -la ~/.codex/skills/
# If list-skills is installed
list-skills
After running, both Claude Code and Codex will have access to the same skills via:
~/.claude/skills/)~/.codex/skills/.synced-from-claude marker file won't be overwritten (unless --force is used)..claude/skills/ folders.--force to overwrite all skills including manual ones. Useful for initial setup or when you want to reset everything to match Claude sources.npx claudepluginhub ariccb/sync-claude-skills-to-codex --plugin sync-claude-skills-to-codexAnalyzes, standardizes, validates, and syncs locally maintained skills into agent skill directories (Claude, Cursor, CodeBuddy, Codex).
Installs, updates, lists, and removes Claude Code skills from GitHub repos/subdirs or .skill zips. Supports user-global and project-local locations.
Installs, uninstalls, lists, and updates Skills/Commands for Claude Code, Codex, and OpenClaw. Supports local symlinks and GitHub installs with version tracking.