#!/usr/bin/env bash # Build .skill archives from skills// into dist/.skill # Usage: build.sh [name...] (no args = all) # # Uses `zip` if available; otherwise delegates to scripts/build.ps1 # (so the script works on Linux, macOS, and Windows-with-git-bash without # requiring `zip` on Windows). set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" SRC="$ROOT/skills" DIST="$ROOT/dist" if command -v zip >/dev/null 2>&1; then mkdir -p "$DIST" if [ "$#" -eq 0 ]; then # Portable across bash 3.2 (stock macOS) and bash 4+ (Linux, git-bash): # avoid `mapfile` (bash 4+) and `find -printf` (GNU find only). names=() for d in "$SRC"/*/; do [ -d "$d" ] || continue names+=("$(basename "$d")") done IFS=$'\n' names=($(printf '%s\n' "${names[@]}" | sort)) unset IFS else names=("$@") fi for name in "${names[@]}"; do src_dir="$SRC/$name" if [ ! -d "$src_dir" ]; then echo "skip: $name (not found in skills/)" >&2 continue fi if [ ! -f "$src_dir/SKILL.md" ]; then echo "skip: $name (missing SKILL.md)" >&2 continue fi out="$DIST/$name.skill" rm -f "$out" ( cd "$SRC" && zip -qr "$out" "$name" ) echo "built: dist/$name.skill" done elif command -v powershell.exe >/dev/null 2>&1; then # Windows fallback: delegate to build.ps1 (proper ZIP via .NET API). # PS array binding via -File is fragile (commas don't always split into [string[]]), # so call build.ps1 once per skill and let the bash loop do the work. ps1="$SCRIPT_DIR/build.ps1" ps1_win="$(cygpath -w "$ps1" 2>/dev/null || echo "$ps1")" if [ "$#" -eq 0 ]; then powershell.exe -NoProfile -ExecutionPolicy Bypass -File "$ps1_win" else for name in "$@"; do powershell.exe -NoProfile -ExecutionPolicy Bypass -File "$ps1_win" -Names "$name" done fi else echo "error: need either 'zip' (Linux/macOS) or PowerShell (Windows) to build .skill archives" >&2 exit 1 fi