codex-agents/sync.sh
Cal Corum fff5411390 Initial commit: Codex-to-Claude agent converter + 136 plugins
Pipeline that pulls VoltAgent/awesome-codex-subagents and converts
TOML agent definitions to Claude Code plugin marketplace format.
Includes SHA-256 hash-based incremental updates.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 16:49:55 -05:00

102 lines
2.5 KiB
Bash
Executable File

#!/bin/bash
# sync.sh — Pull VoltAgent/awesome-codex-subagents and convert to Claude Code plugin marketplace
# Usage: ./sync.sh [--dry-run] [--force] [--verbose]
set -euo pipefail
SCRIPT_DIR="$(dirname "$(readlink -f "$0")")"
UPSTREAM_DIR="${SCRIPT_DIR}/upstream"
UPSTREAM_REPO="https://github.com/VoltAgent/awesome-codex-subagents"
OUTPUT_DIR="${SCRIPT_DIR}/plugins"
MANIFEST="${SCRIPT_DIR}/codex-manifest.json"
DRY_RUN=""
FORCE=false
VERBOSE=""
usage() {
echo "Usage: $(basename "$0") [--dry-run] [--force] [--verbose]"
echo ""
echo "Pull upstream Codex agent definitions and convert to Claude Code plugins."
echo ""
echo "Options:"
echo " --dry-run Print what would happen without writing files"
echo " --force Re-run converter even if upstream hasn't changed"
echo " --verbose Print per-file conversion status"
echo " --help Show this help message"
}
log() {
echo "[$(date '+%H:%M:%S')] $*" >&2
}
while [[ $# -gt 0 ]]; do
case "$1" in
--dry-run)
DRY_RUN="--dry-run"
shift
;;
--force)
FORCE=true
shift
;;
--verbose)
VERBOSE="--verbose"
shift
;;
--help)
usage
exit 0
;;
*)
echo "Unknown option: $1" >&2
usage
exit 1
;;
esac
done
# Clone or pull upstream
if [[ -d "${UPSTREAM_DIR}/.git" ]]; then
log "Pulling upstream updates..."
git -C "$UPSTREAM_DIR" pull --ff-only
else
log "Cloning upstream repo..."
git clone "$UPSTREAM_REPO" "$UPSTREAM_DIR"
fi
CURRENT_COMMIT=$(git -C "$UPSTREAM_DIR" rev-parse --short HEAD)
log "Upstream at commit ${CURRENT_COMMIT}"
# Check manifest for skip
if [[ "$FORCE" == false && -f "$MANIFEST" ]]; then
LAST_COMMIT=$(python3 -c "import json; m=json.load(open('${MANIFEST}')); print(m.get('upstream_commit',''))" 2>/dev/null || echo "")
if [[ "$LAST_COMMIT" == "$CURRENT_COMMIT" ]]; then
log "Already up to date (commit ${CURRENT_COMMIT}). Use --force to re-run."
exit 0
fi
fi
# Run converter
log "Converting agents..."
python3 "${SCRIPT_DIR}/convert.py" \
"${UPSTREAM_DIR}/categories" \
"${OUTPUT_DIR}" \
--manifest "${MANIFEST}" \
${DRY_RUN} \
${VERBOSE}
# Update manifest with commit hash (converter writes the rest)
if [[ -z "$DRY_RUN" && -f "$MANIFEST" ]]; then
python3 -c "
import json
from pathlib import Path
p = Path('${MANIFEST}')
m = json.loads(p.read_text())
m['upstream_commit'] = '${CURRENT_COMMIT}'
p.write_text(json.dumps(m, indent=2) + '\n')
"
log "Manifest updated with commit ${CURRENT_COMMIT}"
fi
log "Done."