#!/usr/bin/env bash set -euo pipefail SCRIPT_DIR="$(cd -- "$(dirname "${BASH_SOURCE[0]}")" && pwd)" DEFAULT_BASE_DIR="${HOME:-$PWD}/.gemini/antigravity" BASE_DIR="${AG_BASE_DIR:-$DEFAULT_BASE_DIR}" SKILLS_DIR="${AG_SKILLS_DIR:-$BASE_DIR/skills}" LIBRARY_DIR="${AG_LIBRARY_DIR:-$BASE_DIR/skills_library}" ARCHIVE_PREFIX="${AG_ARCHIVE_PREFIX:-$BASE_DIR/skills_archive}" REPO_SKILLS_DIR="${AG_REPO_SKILLS_DIR:-$SCRIPT_DIR/../skills}" BUNDLE_HELPER="${AG_BUNDLE_HELPER:-$SCRIPT_DIR/../tools/scripts/get-bundle-skills.py}" PYTHON_BIN="${AG_PYTHON_BIN:-}" SKILLS_LIST_FILE="$(mktemp "${TMPDIR:-/tmp}/ag-skills.XXXXXX")" cleanup() { rm -f "$SKILLS_LIST_FILE" } trap cleanup EXIT find_copy_dirs() { local src_dir="$1" local dest_dir="$2" mkdir -p "$dest_dir" while IFS= read -r -d '' item; do cp -RP "$item" "$dest_dir/" done < <(find "$src_dir" -mindepth 1 -maxdepth 1 \( -type d -o -type l \) -print0 2>/dev/null) } find_move_dirs() { local src_dir="$1" local dest_dir="$2" mkdir -p "$dest_dir" while IFS= read -r -d '' item; do mv "$item" "$dest_dir/" done < <(find "$src_dir" -mindepth 1 -maxdepth 1 ! -name '.' ! -name '..' -print0 2>/dev/null) } resolve_python() { if [[ -n "$PYTHON_BIN" ]]; then printf '%s\n' "$PYTHON_BIN" return 0 fi if command -v python3 >/dev/null 2>&1; then command -v python3 return 0 fi if command -v python >/dev/null 2>&1; then command -v python return 0 fi return 1 } is_safe_skill_id() { [[ "$1" =~ ^[A-Za-z0-9._-]+$ ]] } echo "Activating Antigravity skills..." DO_CLEAR=0 EXTRA_ARGS=() for arg in "$@"; do if [[ "$arg" == "--clear" ]]; then DO_CLEAR=1 else EXTRA_ARGS+=("$arg") fi done if [[ -d "$REPO_SKILLS_DIR" ]]; then echo "Syncing library with repository source..." find_copy_dirs "$REPO_SKILLS_DIR" "$LIBRARY_DIR" fi if [[ ! -d "$LIBRARY_DIR" ]]; then echo "Initializing skills library from local state..." mkdir -p "$LIBRARY_DIR" if [[ -d "$SKILLS_DIR" ]]; then echo " + Moving current skills to library..." find_move_dirs "$SKILLS_DIR" "$LIBRARY_DIR" fi while IFS= read -r archive_dir; do [[ -n "$archive_dir" ]] || continue echo " + Merging skills from $(basename "$archive_dir")..." find_copy_dirs "$archive_dir" "$LIBRARY_DIR" done < <(find "$BASE_DIR" -mindepth 1 -maxdepth 1 -type d -name 'skills_archive*' | sort) fi if [[ "$DO_CLEAR" == "1" ]]; then echo "[RESET] Archiving and clearing existing skills..." if [[ -d "$SKILLS_DIR" ]]; then archive_dir="${ARCHIVE_PREFIX}_$(date +%Y%m%d_%H%M%S)" mkdir -p "$archive_dir" find_move_dirs "$SKILLS_DIR" "$archive_dir" fi else echo "[APPEND] Layering new skills onto existing folder..." fi mkdir -p "$SKILLS_DIR" echo "Expanding bundles..." python_path="" if python_path="$(resolve_python 2>/dev/null)" && [[ -f "$BUNDLE_HELPER" ]]; then if [[ "${#EXTRA_ARGS[@]}" -gt 0 ]]; then "$python_path" "$BUNDLE_HELPER" "${EXTRA_ARGS[@]}" >"$SKILLS_LIST_FILE" 2>/dev/null || true else "$python_path" "$BUNDLE_HELPER" Essentials >"$SKILLS_LIST_FILE" 2>/dev/null || true fi fi if [[ ! -s "$SKILLS_LIST_FILE" ]]; then if [[ "${#EXTRA_ARGS[@]}" -eq 0 ]]; then printf '%s\n' brainstorming systematic-debugging test-driven-development >"$SKILLS_LIST_FILE" else : >"$SKILLS_LIST_FILE" for arg in "${EXTRA_ARGS[@]}"; do if is_safe_skill_id "$arg"; then printf '%s\n' "$arg" >>"$SKILLS_LIST_FILE" fi done fi fi echo "Restoring selected skills..." while IFS= read -r skill_id || [[ -n "$skill_id" ]]; do [[ -n "$skill_id" ]] || continue if [[ -e "$SKILLS_DIR/$skill_id" ]]; then echo " . $skill_id (already active)" elif [[ -e "$LIBRARY_DIR/$skill_id" ]]; then echo " + $skill_id" cp -RP "$LIBRARY_DIR/$skill_id" "$SKILLS_DIR/" else echo " - $skill_id (not found in library)" fi done <"$SKILLS_LIST_FILE" echo echo "Done! Antigravity skills are now activated."