playbook/scripts/install_codex_skills.sh

143 lines
3.3 KiB
Bash

#!/usr/bin/env sh
set -eu
# Install Codex skills from this Playbook snapshot into CODEX_HOME.
# - Source: <snapshot>/codex/skills/<skill-name>/
# - Dest: $CODEX_HOME/skills/<skill-name>/ (default CODEX_HOME=~/.codex)
#
# Usage:
# sh scripts/install_codex_skills.sh -all
# sh scripts/install_codex_skills.sh -skills style-cleanup,code-review-workflow
# sh scripts/install_codex_skills.sh -local -all # install to <cwd>/.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,code-review-workflow
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"