Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 84 additions & 5 deletions scripts/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
# is missing or stale.
#
# Usage:
# ./scripts/install.sh [--tool <name>] [--interactive] [--no-interactive] [--help]
# ./scripts/install.sh [--tool <name>] [--division <name>] [--interactive] [--no-interactive] [--help]
#
# Tools:
# claude-code -- Copy agents to ~/.claude/agents/
Expand All @@ -23,6 +23,10 @@
#
# Flags:
# --tool <name> Install only the specified tool
# --division <name> Install only agents from specified division(s) (comma-separated)
# Valid: design, engineering, game-development, marketing, paid-media,
# sales, product, project-management, testing, support, spatial-computing,
# specialized
# --interactive Show interactive selector (default when run in a terminal)
# --no-interactive Skip interactive selector, install all detected tools
# --help Show this help
Expand Down Expand Up @@ -83,6 +87,58 @@ INTEGRATIONS="$REPO_ROOT/integrations"

ALL_TOOLS=(claude-code copilot antigravity gemini-cli opencode openclaw cursor aider windsurf)

# ---------------------------------------------------------------------------
# Division filtering
# ---------------------------------------------------------------------------
ALL_DIVISIONS=(
design engineering game-development marketing paid-media sales product
project-management testing support spatial-computing specialized
)
FILTER_DIVISIONS=() # empty = all divisions

slugify() {
echo "$1" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9]/-/g' | sed 's/--*/-/g' | sed 's/^-//;s/-$//'
}

get_field() {
sed -n '/^---$/,/^---$/p' "$2" | grep "^${1}:" | head -1 | sed "s/^${1}:[[:space:]]*//" | sed 's/^["'"'"']//;s/["'"'"']$//'
}

# Return the list of division dirs to install (filtered or all)
active_divisions() {
if [[ ${#FILTER_DIVISIONS[@]} -gt 0 ]]; then
printf '%s\n' "${FILTER_DIVISIONS[@]}"
else
printf '%s\n' "${ALL_DIVISIONS[@]}"
fi
}

# Build a newline-separated list of allowed slugs from active divisions
_allowed_slugs_cache=""
allowed_slugs() {
if [[ -n "$_allowed_slugs_cache" ]]; then
printf '%s' "$_allowed_slugs_cache"
return
fi
local slugs="" div
for div in $(active_divisions); do
[[ -d "$REPO_ROOT/$div" ]] || continue
while IFS= read -r -d '' f; do
local name; name="$(get_field name "$f")"
[[ -n "$name" ]] && slugs+="$(slugify "$name")"$'\n'
done < <(find "$REPO_ROOT/$div" -name "*.md" -type f -print0)
done
_allowed_slugs_cache="$slugs"
printf '%s' "$slugs"
}

# Check if a slug matches the allowed set (no-op when no filter)
slug_allowed() {
[[ ${#FILTER_DIVISIONS[@]} -eq 0 ]] && return 0
local slug="$1"
allowed_slugs | grep -qxF "$slug"
}

# ---------------------------------------------------------------------------
# Usage
# ---------------------------------------------------------------------------
Expand Down Expand Up @@ -267,8 +323,7 @@ install_claude_code() {
local count=0
mkdir -p "$dest"
local dir f first_line
for dir in design engineering game-development marketing paid-media sales product project-management \
testing support spatial-computing specialized; do
for dir in $(active_divisions); do
[[ -d "$REPO_ROOT/$dir" ]] || continue
while IFS= read -r -d '' f; do
first_line="$(head -1 "$f")"
Expand All @@ -285,8 +340,7 @@ install_copilot() {
local count=0
mkdir -p "$dest"
local dir f first_line
for dir in design engineering game-development marketing paid-media sales product project-management \
testing support spatial-computing specialized; do
for dir in $(active_divisions); do
[[ -d "$REPO_ROOT/$dir" ]] || continue
while IFS= read -r -d '' f; do
first_line="$(head -1 "$f")"
Expand All @@ -307,6 +361,7 @@ install_antigravity() {
local d
while IFS= read -r -d '' d; do
local name; name="$(basename "$d")"
slug_allowed "$name" || continue
mkdir -p "$dest/$name"
cp "$d/SKILL.md" "$dest/$name/SKILL.md"
(( count++ )) || true
Expand All @@ -324,6 +379,7 @@ install_gemini_cli() {
local d
while IFS= read -r -d '' d; do
local name; name="$(basename "$d")"
slug_allowed "$name" || continue
mkdir -p "$dest/skills/$name"
cp "$d/SKILL.md" "$dest/skills/$name/SKILL.md"
(( count++ )) || true
Expand All @@ -339,6 +395,8 @@ install_opencode() {
mkdir -p "$dest"
local f
while IFS= read -r -d '' f; do
local slug; slug="$(basename "$f" .md)"
slug_allowed "$slug" || continue
cp "$f" "$dest/"; (( count++ )) || true
done < <(find "$src" -maxdepth 1 -name "*.md" -print0)
ok "OpenCode: $count agents -> $dest"
Expand All @@ -354,6 +412,7 @@ install_openclaw() {
local d
while IFS= read -r -d '' d; do
local name; name="$(basename "$d")"
slug_allowed "$name" || continue
mkdir -p "$dest/$name"
cp "$d/SOUL.md" "$dest/$name/SOUL.md"
cp "$d/AGENTS.md" "$dest/$name/AGENTS.md"
Expand All @@ -378,6 +437,8 @@ install_cursor() {
mkdir -p "$dest"
local f
while IFS= read -r -d '' f; do
local slug; slug="$(basename "$f" .mdc)"
slug_allowed "$slug" || continue
cp "$f" "$dest/"; (( count++ )) || true
done < <(find "$src" -maxdepth 1 -name "*.mdc" -print0)
ok "Cursor: $count rules -> $dest"
Expand Down Expand Up @@ -434,6 +495,21 @@ main() {
while [[ $# -gt 0 ]]; do
case "$1" in
--tool) tool="${2:?'--tool requires a value'}"; shift 2; interactive_mode="no" ;;
--division)
local divs="${2:?'--division requires a value'}"
IFS=',' read -ra _divs <<< "$divs"
local _d
for _d in "${_divs[@]}"; do
_d="$(echo "$_d" | xargs)" # trim whitespace
local valid_div=false _ad
for _ad in "${ALL_DIVISIONS[@]}"; do [[ "$_ad" == "$_d" ]] && valid_div=true && break; done
if ! $valid_div; then
err "Unknown division '$_d'. Valid: ${ALL_DIVISIONS[*]}"
exit 1
fi
FILTER_DIVISIONS+=("$_d")
done
shift 2 ;;
--interactive) interactive_mode="yes"; shift ;;
--no-interactive) interactive_mode="no"; shift ;;
--help|-h) usage ;;
Expand Down Expand Up @@ -496,6 +572,9 @@ main() {
header "The Agency -- Installing agents"
printf " Repo: %s\n" "$REPO_ROOT"
printf " Installing: %s\n" "${SELECTED_TOOLS[*]}"
if [[ ${#FILTER_DIVISIONS[@]} -gt 0 ]]; then
printf " Divisions: %s\n" "${FILTER_DIVISIONS[*]}"
fi
printf "\n"

local installed=0 t
Expand Down