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>
218 lines
5.0 KiB
Bash
Executable File
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"
|