awesome-cursor-subagents/install-agents.sh
stud_i_sram ee04fdc420 Add Cursor-adapted subagents collection from VoltAgent base.
154 agents with Cursor frontmatter, Russian install README, and cross-platform install scripts for global ~/.cursor/agents setup.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-28 15:46:02 +03:00

218 lines
5.0 KiB
Bash
Executable File

#!/usr/bin/env bash
# Install Cursor subagents from this repository.
# Works on macOS, Linux, WSL, and Git Bash on Windows.
set -e
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
CYAN='\033[0;36m'
BOLD='\033[1m'
NC='\033[0m'
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
CATEGORIES_DIR="$SCRIPT_DIR/categories"
GLOBAL_AGENTS_DIR="${HOME}/.cursor/agents"
LOCAL_AGENTS_DIR=".cursor/agents"
MODE="global"
ACTION="install"
CATEGORY=""
ALL=0
INTERACTIVE=1
usage() {
cat <<'EOF'
Usage: ./install-agents.sh [options]
Options:
--all Install all agents
--category <name> Install one category (e.g. 04-quality-security)
--local Install into current project (.cursor/agents)
--global Install globally (~/.cursor/agents) [default]
--uninstall-all Remove agents previously installed from this repo
-h, --help Show help
Examples:
./install-agents.sh --all
./install-agents.sh --category 04-quality-security
./install-agents.sh --all --local
./install-agents.sh --uninstall-all
EOF
}
while [ $# -gt 0 ]; do
case "$1" in
--all) ALL=1; INTERACTIVE=0; shift ;;
--category)
CATEGORY="${2:-}"
INTERACTIVE=0
if [ -z "$CATEGORY" ]; then
echo "${RED}--category requires a name${NC}"
exit 1
fi
shift 2
;;
--local) MODE="local"; shift ;;
--global) MODE="global"; shift ;;
--uninstall-all) ACTION="uninstall-all"; INTERACTIVE=0; shift ;;
-h|--help) usage; exit 0 ;;
*)
echo "${RED}Unknown option: $1${NC}"
usage
exit 1
;;
esac
done
if [ ! -d "$CATEGORIES_DIR" ]; then
echo "${RED}Error: categories/ not found next to this script.${NC}"
exit 1
fi
target_dir() {
if [ "$MODE" = "local" ]; then
printf '%s\n' "$LOCAL_AGENTS_DIR"
else
printf '%s\n' "$GLOBAL_AGENTS_DIR"
fi
}
list_categories() {
for d in "$CATEGORIES_DIR"/*/; do
[ -d "$d" ] || continue
basename "$d"
done | sort
}
install_files_from_list() {
dest="$(target_dir)"
mkdir -p "$dest"
count=0
while IFS= read -r src; do
[ -n "$src" ] || continue
[ -f "$src" ] || continue
cp "$src" "$dest/$(basename "$src")"
count=$((count + 1))
done
printf "${GREEN}Installed %s agent(s) → %s${NC}\n" "$count" "$dest"
}
all_agent_files() {
for cat in "$CATEGORIES_DIR"/*/; do
[ -d "$cat" ] || continue
for f in "$cat"*.md; do
[ -f "$f" ] || continue
base="$(basename "$f")"
[ "$base" = "README.md" ] && continue
printf '%s\n' "$f"
done
done | sort
}
agents_in_category() {
cat_name="$1"
for f in "$CATEGORIES_DIR/$cat_name"/*.md; do
[ -f "$f" ] || continue
base="$(basename "$f")"
[ "$base" = "README.md" ] && continue
printf '%s\n' "$f"
done | sort
}
uninstall_all() {
dest="$(target_dir)"
if [ ! -d "$dest" ]; then
printf "${YELLOW}Nothing to uninstall: %s does not exist.${NC}\n" "$dest"
return 0
fi
tmp="$(mktemp)"
all_agent_files > "$tmp"
removed=0
while IFS= read -r src; do
base="$(basename "$src")"
if [ -f "$dest/$base" ]; then
rm -f "$dest/$base"
removed=$((removed + 1))
fi
done < "$tmp"
rm -f "$tmp"
printf "${GREEN}Removed %s agent file(s) from %s${NC}\n" "$removed" "$dest"
}
interactive_menu() {
printf "${BOLD}${CYAN}Cursor Subagents Installer${NC}\n\n"
echo "Install mode:"
echo " 1) Global — all Cursor projects (~/.cursor/agents)"
echo " 2) Local — current project only (.cursor/agents)"
printf "Choice [1]: "
read -r mode_choice
case "${mode_choice:-1}" in
2) MODE="local" ;;
*) MODE="global" ;;
esac
echo
echo "What to install:"
echo " 1) All agents"
echo " 2) One category"
echo " 3) Uninstall all agents from this repo"
printf "Choice [1]: "
read -r action_choice
case "${action_choice:-1}" in
3) ACTION="uninstall-all" ;;
2)
echo
echo "Categories:"
i=1
# shellcheck disable=SC2034
cat_list=""
while IFS= read -r c; do
printf " %2d) %s\n" "$i" "$c"
eval "CAT_$i=\"\$c\""
i=$((i + 1))
done <<EOF
$(list_categories)
EOF
max=$((i - 1))
printf "Category number: "
read -r cat_num
if [ -z "${cat_num:-}" ] || [ "$cat_num" -lt 1 ] || [ "$cat_num" -gt "$max" ]; then
printf "${RED}Invalid category.${NC}\n"
exit 1
fi
eval "CATEGORY=\$CAT_$cat_num"
;;
*) ALL=1 ;;
esac
}
if [ "$INTERACTIVE" -eq 1 ]; then
interactive_menu
fi
if [ "$ACTION" = "uninstall-all" ]; then
uninstall_all
exit 0
fi
if [ "$ALL" -eq 1 ]; then
all_agent_files | install_files_from_list
elif [ -n "$CATEGORY" ]; then
if [ ! -d "$CATEGORIES_DIR/$CATEGORY" ]; then
printf "${RED}Category not found: %s${NC}\n" "$CATEGORY"
echo "Available:"
list_categories
exit 1
fi
agents_in_category "$CATEGORY" | install_files_from_list
else
printf "${RED}Nothing to do. Use --all, --category, or run without args for interactive mode.${NC}\n"
usage
exit 1
fi
echo
printf "${YELLOW}Restart Cursor (or open a new Agent chat) so new subagents are picked up.${NC}\n"