#!/usr/bin/env sh set -eu # Install Codex skills from this Playbook snapshot into CODEX_HOME. # - Source: /codex/skills// # - Dest: $CODEX_HOME/skills// (default CODEX_HOME=~/.codex) # # Usage: # sh scripts/install_codex_skills.sh -all # sh scripts/install_codex_skills.sh -skills style-cleanup,commit-message # sh scripts/install_codex_skills.sh -local -all # install to /.codex # # Notes: # - Codex loads skills at startup; restart `codex` after installation. # - Existing destination skill dirs are backed up with a timestamp suffix. SCRIPT_DIR="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd -P)" SRC="$(CDPATH= cd -- "$SCRIPT_DIR/.." && pwd -P)" SKILLS_SRC_ROOT="$SRC/codex/skills" usage() { cat <<'EOF' >&2 Usage: sh scripts/install_codex_skills.sh [options] sh scripts/install_codex_skills.sh -skills style-cleanup,commit-message sh scripts/install_codex_skills.sh -all Options: -local, -l Install to ./.codex (or CODEX_HOME if set). -skills LIST Comma/space-separated skill names. -all Install all skills. -h, -help Show this help. Env: CODEX_HOME Target Codex home (default: ~/.codex). EOF } LOCAL_MODE=0 INSTALL_ALL=0 SKILLS="" while [ $# -gt 0 ]; do case "$1" in -local|-l) LOCAL_MODE=1 shift ;; -skills) if [ $# -lt 2 ] || [ -z "${2:-}" ]; then echo "ERROR: -skills requires a value." >&2 usage exit 1 fi SKILLS="$2" shift 2 ;; -all) INSTALL_ALL=1 shift ;; -h|-help) usage exit 0 ;; -*) echo "ERROR: Unknown option: $1" >&2 usage exit 1 ;; *) echo "ERROR: positional args are not supported; use -skills/-all." >&2 usage exit 1 ;; esac done if [ "$INSTALL_ALL" -eq 1 ] && [ -n "$SKILLS" ]; then echo "ERROR: use either -all or -skills, not both." >&2 usage exit 1 fi if [ "$INSTALL_ALL" -eq 0 ] && [ -z "$SKILLS" ]; then echo "ERROR: -all or -skills is required." >&2 usage exit 1 fi if [ "$LOCAL_MODE" -eq 1 ]; then LOCAL_CODEX_HOME="$(pwd -P)/.codex" CODEX_HOME="${CODEX_HOME:-$LOCAL_CODEX_HOME}" fi CODEX_HOME="${CODEX_HOME:-$HOME/.codex}" SKILLS_DST_ROOT="$CODEX_HOME/skills" if [ ! -d "$SKILLS_SRC_ROOT" ]; then echo "ERROR: skills source dir not found: $SKILLS_SRC_ROOT" >&2 exit 1 fi mkdir -p "$SKILLS_DST_ROOT" timestamp="$(date +%Y%m%d%H%M%S 2>/dev/null || echo bak)" install_one() { name="$1" src_dir="$SKILLS_SRC_ROOT/$name" dst_dir="$SKILLS_DST_ROOT/$name" if [ ! -d "$src_dir" ]; then echo "ERROR: skill not found: $name ($src_dir)" >&2 exit 1 fi if [ -e "$dst_dir" ]; then mv "$dst_dir" "$SKILLS_DST_ROOT/$name.bak.$timestamp" echo "Backed up existing skill: $name -> $name.bak.$timestamp" fi cp -R "$src_dir" "$dst_dir" echo "Installed: $name" } if [ "$INSTALL_ALL" -eq 1 ]; then for dir in "$SKILLS_SRC_ROOT"/*; do [ -d "$dir" ] || continue name="$(basename -- "$dir")" case "$name" in ""|.*) continue ;; esac install_one "$name" done else old_ifs="${IFS}" IFS=', ' set -- $SKILLS IFS="${old_ifs}" for name in "$@"; do [ -n "$name" ] || continue install_one "$name" done fi echo "Done. Skills installed to: $SKILLS_DST_ROOT"