#!/bin/sh # install-template.sh — Cross-platform skill installation script # This file is a template. During skill generation, {{SKILL_NAME}} is replaced # with the actual skill name and the result is shipped as install.sh inside # every generated skill package. # # POSIX-compatible (works in bash, dash, zsh, ash, etc.) # Exit codes: # 0 — Success # 1 — Validation failed (missing or malformed SKILL.md) # 2 — Platform not detected # 3 — Permission denied set -euo pipefail # --------------------------------------------------------------------------- # Constants # --------------------------------------------------------------------------- SKILL_NAME="{{SKILL_NAME}}" VERSION="1.0.0" SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" # --------------------------------------------------------------------------- # Colors (disabled when stdout is not a terminal) # --------------------------------------------------------------------------- if [ -t 1 ]; then RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' BOLD='\033[1m' NC='\033[0m' else RED='' GREEN='' YELLOW='' BLUE='' BOLD='' NC='' fi # --------------------------------------------------------------------------- # Logging helpers # --------------------------------------------------------------------------- info() { printf "${BLUE}[INFO]${NC} %s\n" "$1"; } success() { printf "${GREEN}[OK]${NC} %s\n" "$1"; } warn() { printf "${YELLOW}[WARN]${NC} %s\n" "$1"; } error() { printf "${RED}[ERROR]${NC} %s\n" "$1" >&2; } # --------------------------------------------------------------------------- # Usage / help # --------------------------------------------------------------------------- show_help() { cat </dev/null; then error "Cannot create directory: ${INSTALL_DIR}" error "Check file permissions or run with appropriate privileges." exit 3 fi # Copy files. for file in "${SCRIPT_DIR}"/*; do [ -e "$file" ] || continue local fname fname="$(basename "$file")" [ "$fname" = "$install_script_name" ] && continue if ! cp -R "$file" "${INSTALL_DIR}/" 2>/dev/null; then error "Failed to copy ${fname} to ${INSTALL_DIR}/" error "Check file permissions." exit 3 fi file_count=$((file_count + 1)) done # Copy dotfiles (if any). for file in "${SCRIPT_DIR}"/.*; do [ -e "$file" ] || continue local fname fname="$(basename "$file")" [ "$fname" = "." ] || [ "$fname" = ".." ] && continue if ! cp -R "$file" "${INSTALL_DIR}/" 2>/dev/null; then error "Failed to copy ${fname} to ${INSTALL_DIR}/" error "Check file permissions." exit 3 fi file_count=$((file_count + 1)) done success "Copied ${file_count} file(s) to ${INSTALL_DIR}" } # --------------------------------------------------------------------------- # Activation instructions # --------------------------------------------------------------------------- print_activation_instructions() { if $DRY_RUN; then return 0 fi printf "\n${GREEN}${BOLD}Installation complete!${NC}\n\n" case "$PLATFORM" in claude-code) printf "To activate the skill in Claude Code:\n" printf " 1. Start a new Claude Code session.\n" printf " 2. The skill will be loaded automatically from:\n" printf " ${BOLD}${INSTALL_DIR}/SKILL.md${NC}\n" printf " 3. Use trigger phrases defined in the skill's description.\n" ;; copilot) printf "To activate the skill in GitHub Copilot:\n" printf " 1. Open your project in VS Code or the GitHub CLI.\n" printf " 2. The skill is available at:\n" printf " ${BOLD}${INSTALL_DIR}/SKILL.md${NC}\n" printf " 3. Reference the skill in your Copilot instructions.\n" ;; cursor) printf "To activate the skill in Cursor:\n" printf " 1. Open your project in Cursor.\n" printf " 2. The rule is loaded automatically from:\n" printf " ${BOLD}${INSTALL_DIR}/SKILL.md${NC}\n" printf " 3. Use trigger phrases to invoke the skill.\n" ;; windsurf) printf "To activate the skill in Windsurf:\n" printf " 1. Open your project in Windsurf.\n" printf " 2. The skill is available at:\n" printf " ${BOLD}${INSTALL_DIR}/SKILL.md${NC}\n" printf " 3. Use trigger phrases to invoke the skill.\n" ;; cline) printf "To activate the skill in Cline:\n" printf " 1. Open your project in VS Code with Cline.\n" printf " 2. The rule is loaded from:\n" printf " ${BOLD}${INSTALL_DIR}/SKILL.md${NC}\n" printf " 3. Cline will pick up the rule automatically.\n" ;; codex) printf "To activate the skill in OpenAI Codex CLI:\n" printf " 1. Start a new Codex CLI session.\n" printf " 2. The skill is available at:\n" printf " ${BOLD}${INSTALL_DIR}/SKILL.md${NC}\n" printf " 3. Reference the skill in your instructions.\n" ;; gemini) printf "To activate the skill in Gemini CLI:\n" printf " 1. Start a new Gemini CLI session.\n" printf " 2. The skill is available at:\n" printf " ${BOLD}${INSTALL_DIR}/SKILL.md${NC}\n" printf " 3. The skill will be loaded automatically.\n" ;; esac printf "\n" } # --------------------------------------------------------------------------- # Main # --------------------------------------------------------------------------- main() { printf "${BOLD}Installing skill: ${SKILL_NAME}${NC}\n" printf "%-40s\n" "----------------------------------------" parse_args "$@" validate_skill_md detect_platform resolve_install_path install_files print_activation_instructions if $DRY_RUN; then info "Dry run complete. No changes were made." else success "Skill '${SKILL_NAME}' installed successfully for ${PLATFORM}." fi exit 0 } main "$@"