-
Notifications
You must be signed in to change notification settings - Fork 353
Expand file tree
/
Copy pathinstall.sh
More file actions
executable file
·108 lines (93 loc) · 2.68 KB
/
install.sh
File metadata and controls
executable file
·108 lines (93 loc) · 2.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#!/usr/bin/env bash
# claude-red installer
# Copies offensive security skills into a Claude skills directory.
#
# Usage:
# ./install.sh # interactive (asks for target)
# ./install.sh --target ~/.claude/skills # explicit target
# ./install.sh --category web # one category only
# ./install.sh --target DIR --category web # combined
# ./install.sh --list # list available categories
# ./install.sh --dry-run # show what would be copied
#
# Default target: ~/.claude/skills/claude-red
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SKILLS_DIR="$SCRIPT_DIR/Skills"
DEFAULT_TARGET="${HOME}/.claude/skills/claude-red"
TARGET=""
CATEGORY=""
DRY_RUN=0
LIST_ONLY=0
usage() {
sed -n '2,12p' "$0" | sed 's/^# \{0,1\}//'
exit "${1:-0}"
}
list_categories() {
echo "Available categories:"
for d in "$SKILLS_DIR"/*/; do
[ -d "$d" ] || continue
name=$(basename "$d")
count=$(find "$d" -name SKILL.md | wc -l | tr -d ' ')
printf " %-20s %s skill(s)\n" "$name" "$count"
done
}
while [ $# -gt 0 ]; do
case "$1" in
--target) TARGET="$2"; shift 2 ;;
--category) CATEGORY="$2"; shift 2 ;;
--dry-run) DRY_RUN=1; shift ;;
--list) LIST_ONLY=1; shift ;;
-h|--help) usage 0 ;;
*) echo "Unknown option: $1" >&2; usage 1 ;;
esac
done
if [ "$LIST_ONLY" -eq 1 ]; then
list_categories
exit 0
fi
if [ ! -d "$SKILLS_DIR" ]; then
echo "Error: Skills directory not found at $SKILLS_DIR" >&2
exit 1
fi
# Interactive prompt if no target given
if [ -z "$TARGET" ]; then
if [ -t 0 ]; then
read -r -p "Install target [$DEFAULT_TARGET]: " TARGET || true
fi
TARGET="${TARGET:-$DEFAULT_TARGET}"
fi
# Validate category if specified
if [ -n "$CATEGORY" ]; then
if [ ! -d "$SKILLS_DIR/$CATEGORY" ]; then
echo "Error: Category '$CATEGORY' not found." >&2
echo "" >&2
list_categories >&2
exit 1
fi
SOURCE="$SKILLS_DIR/$CATEGORY"
DEST="$TARGET/$CATEGORY"
else
SOURCE="$SKILLS_DIR"
DEST="$TARGET"
fi
echo "Source: $SOURCE"
echo "Target: $DEST"
echo
if [ "$DRY_RUN" -eq 1 ]; then
echo "[dry-run] Would copy:"
find "$SOURCE" -name SKILL.md | sed "s|^$SOURCE| $DEST|"
exit 0
fi
mkdir -p "$DEST"
# Use rsync if available for nicer output, else cp -r
if command -v rsync >/dev/null 2>&1; then
rsync -a --info=stats1 "$SOURCE/" "$DEST/"
else
cp -r "$SOURCE/." "$DEST/"
echo "Copied via cp (install rsync for progress info)."
fi
skill_count=$(find "$DEST" -name SKILL.md | wc -l | tr -d ' ')
echo
echo "Installed $skill_count skill(s) to $DEST"
echo "Claude should now auto-discover them on next session start."