diff --git a/.gitignore b/.gitignore index aa36013..dc5cb89 100644 --- a/.gitignore +++ b/.gitignore @@ -62,3 +62,14 @@ scratch/ notes/ TODO.md NOTES.md + +# Generated integration files β€” run scripts/convert.sh to regenerate locally +# The scripts/ and integrations/*/README.md files ARE committed; only generated +# agent/skill files are excluded. +integrations/antigravity/agency-*/ +integrations/gemini-cli/skills/ +integrations/gemini-cli/gemini-extension.json +integrations/opencode/agent/ +integrations/cursor/rules/ +integrations/aider/CONVENTIONS.md +integrations/windsurf/.windsurfrules diff --git a/README.md b/README.md index ad0c8e2..b6cad18 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,23 @@ Each agent file contains: Browse the agents below and copy/adapt the ones you need! +### Option 3: Use with Other Tools (Cursor, Aider, Windsurf, Gemini CLI, OpenCode) + +```bash +# Step 1 -- generate integration files for all supported tools +./scripts/convert.sh + +# Step 2 -- install interactively (auto-detects what you have installed) +./scripts/install.sh + +# Or target a specific tool directly +./scripts/install.sh --tool cursor +./scripts/install.sh --tool aider +./scripts/install.sh --tool windsurf +``` + +See the [Multi-Tool Integrations](#-multi-tool-integrations) section below for full details. + --- ## 🎨 The Agency Roster @@ -289,19 +306,19 @@ Each agent is designed with: > "I don't just test your code - I default to finding 3-5 issues and require visual proof for everything." > -> β€” **Evidence Collector** (Testing Division) +> -- **Evidence Collector** (Testing Division) > "You're not marketing on Reddit - you're becoming a valued community member who happens to represent a brand." > -> β€” **Reddit Community Builder** (Marketing Division) +> -- **Reddit Community Builder** (Marketing Division) > "Every playful element must serve a functional or emotional purpose. Design delight that enhances rather than distracts." > -> β€” **Whimsy Injector** (Design Division) +> -- **Whimsy Injector** (Design Division) > "Let me add a celebration animation that reduces task completion anxiety by 40%" > -> β€” **Whimsy Injector** (during a UX review) +> -- **Whimsy Injector** (during a UX review) --- @@ -315,21 +332,223 @@ Each agent is designed with: --- +## πŸ”Œ Multi-Tool Integrations + +The Agency works natively with Claude Code, and ships conversion + install scripts so you can use the same agents across every major agentic coding tool. + +### Supported Tools + +- **[Claude Code](https://claude.ai/code)** β€” native `.md` agents, no conversion needed β†’ `~/.claude/agents/` +- **[Antigravity](https://github.com/google-gemini/antigravity)** β€” `SKILL.md` per agent β†’ `~/.gemini/antigravity/skills/` +- **[Gemini CLI](https://github.com/google-gemini/gemini-cli)** β€” extension + `SKILL.md` files β†’ `~/.gemini/extensions/agency-agents/` +- **[OpenCode](https://opencode.ai)** β€” `.md` agent files β†’ `.opencode/agent/` +- **[Cursor](https://cursor.sh)** β€” `.mdc` rule files β†’ `.cursor/rules/` +- **[Aider](https://aider.chat)** β€” single `CONVENTIONS.md` β†’ `./CONVENTIONS.md` +- **[Windsurf](https://codeium.com/windsurf)** β€” single `.windsurfrules` β†’ `./.windsurfrules` + +--- + +### ⚑ Quick Install + +**Step 1 -- Generate integration files:** +```bash +./scripts/convert.sh +``` + +**Step 2 -- Install (interactive, auto-detects your tools):** +```bash +./scripts/install.sh +``` + +The installer scans your system for installed tools, shows a checkbox UI, and lets you pick exactly what to install: + +``` + +------------------------------------------------+ + | The Agency -- Tool Installer | + +------------------------------------------------+ + + System scan: [*] = detected on this machine + + [x] 1) [*] Claude Code (claude.ai/code) + [x] 2) [*] Antigravity (~/.gemini/antigravity) + [ ] 3) [ ] Gemini CLI (gemini extension) + [ ] 4) [ ] OpenCode (opencode.ai) + [x] 5) [*] Cursor (.cursor/rules) + [ ] 6) [ ] Aider (CONVENTIONS.md) + [ ] 7) [ ] Windsurf (.windsurfrules) + + [1-7] toggle [a] all [n] none [d] detected + [Enter] install [q] quit +``` + +**Or install a specific tool directly:** +```bash +./scripts/install.sh --tool cursor +./scripts/install.sh --tool opencode +./scripts/install.sh --tool antigravity +``` + +**Non-interactive (CI/scripts):** +```bash +./scripts/install.sh --no-interactive --tool all +``` + +--- + +### Tool-Specific Instructions + +
+Claude Code + +Agents are copied directly from the repo into `~/.claude/agents/` -- no conversion needed. + +```bash +./scripts/install.sh --tool claude-code +``` + +Then activate in Claude Code: +``` +Use the Frontend Developer agent to review this component. +``` + +See [integrations/claude-code/README.md](integrations/claude-code/README.md) for details. +
+ +
+Antigravity (Gemini) + +Each agent becomes a skill in `~/.gemini/antigravity/skills/agency-/`. + +```bash +./scripts/install.sh --tool antigravity +``` + +Activate in Gemini with Antigravity: +``` +@agency-frontend-developer review this React component +``` + +See [integrations/antigravity/README.md](integrations/antigravity/README.md) for details. +
+ +
+Gemini CLI + +Installs as a Gemini CLI extension with 61 skills + a manifest. + +```bash +./scripts/install.sh --tool gemini-cli +``` + +See [integrations/gemini-cli/README.md](integrations/gemini-cli/README.md) for details. +
+ +
+OpenCode + +Agents are placed in `.opencode/agent/` in your project root (project-scoped). + +```bash +cd /your/project +/path/to/agency-agents/scripts/install.sh --tool opencode +``` + +Or install globally: +```bash +mkdir -p ~/.config/opencode/agent +cp integrations/opencode/agent/*.md ~/.config/opencode/agent/ +``` + +Activate in OpenCode: +``` +Use the Backend Architect agent to design this API. +``` + +See [integrations/opencode/README.md](integrations/opencode/README.md) for details. +
+ +
+Cursor + +Each agent becomes a `.mdc` rule file in `.cursor/rules/` of your project. + +```bash +cd /your/project +/path/to/agency-agents/scripts/install.sh --tool cursor +``` + +Rules are auto-applied when Cursor detects them in the project. Reference them explicitly: +``` +Use the @security-engineer rules to review this code. +``` + +See [integrations/cursor/README.md](integrations/cursor/README.md) for details. +
+ +
+Aider + +All agents are compiled into a single `CONVENTIONS.md` file that Aider reads automatically. + +```bash +cd /your/project +/path/to/agency-agents/scripts/install.sh --tool aider +``` + +Then reference agents in your Aider session: +``` +Use the Frontend Developer agent to refactor this component. +``` + +See [integrations/aider/README.md](integrations/aider/README.md) for details. +
+ +
+Windsurf + +All agents are compiled into `.windsurfrules` in your project root. + +```bash +cd /your/project +/path/to/agency-agents/scripts/install.sh --tool windsurf +``` + +Reference agents in Windsurf's Cascade: +``` +Use the Reality Checker agent to verify this is production ready. +``` + +See [integrations/windsurf/README.md](integrations/windsurf/README.md) for details. +
+ +--- + +### Regenerating After Changes + +When you add new agents or edit existing ones, regenerate all integration files: + +```bash +./scripts/convert.sh # regenerate all +./scripts/convert.sh --tool cursor # regenerate just one tool +``` + +--- + ## πŸ—ΊοΈ Roadmap - [ ] Interactive agent selector web tool -- [x] Multi-agent workflow examples β€” see [examples/](examples/) +- [x] Multi-agent workflow examples -- see [examples/](examples/) +- [x] Multi-tool integration scripts (Claude Code, Antigravity, Gemini CLI, OpenCode, Cursor, Aider, Windsurf) - [ ] Video tutorials on agent design - [ ] Community agent marketplace - [ ] Agent "personality quiz" for project matching -- [ ] Integration examples with popular tools - [ ] "Agent of the Week" showcase series --- ## 🌐 Community Translations & Localizations -Community-maintained translations and regional adaptations. These are independently maintained β€” see each repo for coverage and version compatibility. +Community-maintained translations and regional adaptations. These are independently maintained -- see each repo for coverage and version compatibility. | Language | Maintainer | Link | Notes | |----------|-----------|------|-------| diff --git a/integrations/README.md b/integrations/README.md new file mode 100644 index 0000000..5f5dfa3 --- /dev/null +++ b/integrations/README.md @@ -0,0 +1,117 @@ +# πŸ”Œ Integrations + +This directory contains The Agency's 61 AI agents converted into formats +compatible with popular agentic coding tools. + +## Supported Tools + +- **[Claude Code](#claude-code)** β€” `.md` agents, use the repo directly +- **[Antigravity](#antigravity)** β€” `SKILL.md` per agent in `antigravity/` +- **[Gemini CLI](#gemini-cli)** β€” extension + `SKILL.md` files in `gemini-cli/` +- **[OpenCode](#opencode)** β€” `.md` agent files in `opencode/` +- **[Cursor](#cursor)** β€” `.mdc` rule files in `cursor/` +- **[Aider](#aider)** β€” `CONVENTIONS.md` in `aider/` +- **[Windsurf](#windsurf)** β€” `.windsurfrules` in `windsurf/` + +## Quick Install + +```bash +# Install for all detected tools automatically +./scripts/install.sh + +# Install for a specific tool +./scripts/install.sh --tool antigravity +./scripts/install.sh --tool gemini-cli +./scripts/install.sh --tool cursor +./scripts/install.sh --tool aider +./scripts/install.sh --tool windsurf +./scripts/install.sh --tool claude-code +``` + +## Regenerating Integration Files + +If you add or modify agents, regenerate all integration files: + +```bash +./scripts/convert.sh +``` + +--- + +## Claude Code + +The Agency was originally designed for Claude Code. Agents work natively +without conversion. + +```bash +cp -r /*.md ~/.claude/agents/ +# or install everything at once: +./scripts/install.sh --tool claude-code +``` + +See [claude-code/README.md](claude-code/README.md) for details. + +--- + +## Antigravity + +Skills are installed to `~/.gemini/antigravity/skills/`. Each agent becomes +a separate skill prefixed with `agency-` to avoid naming conflicts. + +```bash +./scripts/install.sh --tool antigravity +``` + +See [antigravity/README.md](antigravity/README.md) for details. + +--- + +## Gemini CLI + +Agents are packaged as a Gemini CLI extension with individual skill files. +The extension is installed to `~/.gemini/extensions/agency-agents/`. + +```bash +./scripts/install.sh --tool gemini-cli +``` + +See [gemini-cli/README.md](gemini-cli/README.md) for details. + +--- + +## Cursor + +Each agent becomes a `.mdc` rule file. Rules are project-scoped β€” run the +installer from your project root. + +```bash +cd /your/project && /path/to/agency-agents/scripts/install.sh --tool cursor +``` + +See [cursor/README.md](cursor/README.md) for details. + +--- + +## Aider + +All agents are consolidated into a single `CONVENTIONS.md` file that Aider +reads automatically when present in your project root. + +```bash +cd /your/project && /path/to/agency-agents/scripts/install.sh --tool aider +``` + +See [aider/README.md](aider/README.md) for details. + +--- + +## Windsurf + +All agents are consolidated into a single `.windsurfrules` file for your +project root. + +```bash +cd /your/project && /path/to/agency-agents/scripts/install.sh --tool windsurf +``` + +See [windsurf/README.md](windsurf/README.md) for details. diff --git a/integrations/aider/README.md b/integrations/aider/README.md new file mode 100644 index 0000000..c0c14d3 --- /dev/null +++ b/integrations/aider/README.md @@ -0,0 +1,38 @@ +# Aider Integration + +All 61 Agency agents are consolidated into a single `CONVENTIONS.md` file. +Aider reads this file automatically when it's present in your project root. + +## Install + +```bash +# Run from your project root +cd /your/project +/path/to/agency-agents/scripts/install.sh --tool aider +``` + +## Activate an Agent + +In your Aider session, reference the agent by name: + +``` +Use the Frontend Developer agent to refactor this component. +``` + +``` +Apply the Reality Checker agent to verify this is production-ready. +``` + +## Manual Usage + +You can also pass the conventions file directly: + +```bash +aider --read CONVENTIONS.md +``` + +## Regenerate + +```bash +./scripts/convert.sh --tool aider +``` diff --git a/integrations/antigravity/README.md b/integrations/antigravity/README.md new file mode 100644 index 0000000..49ad0f9 --- /dev/null +++ b/integrations/antigravity/README.md @@ -0,0 +1,49 @@ +# Antigravity Integration + +Installs all 61 Agency agents as Antigravity skills. Each agent is prefixed +with `agency-` to avoid conflicts with existing skills. + +## Install + +```bash +./scripts/install.sh --tool antigravity +``` + +This copies files from `integrations/antigravity/` to +`~/.gemini/antigravity/skills/`. + +## Activate a Skill + +In Antigravity, activate an agent by its slug: + +``` +Use the agency-frontend-developer skill to review this component. +``` + +Available slugs follow the pattern `agency-`, e.g.: +- `agency-frontend-developer` +- `agency-backend-architect` +- `agency-reality-checker` +- `agency-growth-hacker` + +## Regenerate + +After modifying agents, regenerate the skill files: + +```bash +./scripts/convert.sh --tool antigravity +``` + +## File Format + +Each skill is a `SKILL.md` file with Antigravity-compatible frontmatter: + +```yaml +--- +name: agency-frontend-developer +description: Expert frontend developer specializing in... +risk: low +source: community +date_added: '2026-03-08' +--- +``` diff --git a/integrations/claude-code/README.md b/integrations/claude-code/README.md new file mode 100644 index 0000000..b20d6f3 --- /dev/null +++ b/integrations/claude-code/README.md @@ -0,0 +1,31 @@ +# Claude Code Integration + +The Agency was built for Claude Code. No conversion needed β€” agents work +natively with the existing `.md` + YAML frontmatter format. + +## Install + +```bash +# Copy all agents to your Claude Code agents directory +./scripts/install.sh --tool claude-code + +# Or manually copy a category +cp engineering/*.md ~/.claude/agents/ +``` + +## Activate an Agent + +In any Claude Code session, reference an agent by name: + +``` +Activate Frontend Developer and help me build a React component. +``` + +``` +Use the Reality Checker agent to verify this feature is production-ready. +``` + +## Agent Directory + +Agents are organized into divisions. See the [main README](../../README.md) for +the full roster of 61 specialists. diff --git a/integrations/cursor/README.md b/integrations/cursor/README.md new file mode 100644 index 0000000..679e3f9 --- /dev/null +++ b/integrations/cursor/README.md @@ -0,0 +1,38 @@ +# Cursor Integration + +Converts all 61 Agency agents into Cursor `.mdc` rule files. Rules are +**project-scoped** β€” install them from your project root. + +## Install + +```bash +# Run from your project root +cd /your/project +/path/to/agency-agents/scripts/install.sh --tool cursor +``` + +This creates `.cursor/rules/.mdc` files in your project. + +## Activate a Rule + +In Cursor, reference an agent in your prompt: + +``` +@frontend-developer Review this React component for performance issues. +``` + +Or enable a rule as always-on by editing its frontmatter: + +```yaml +--- +description: Expert frontend developer... +globs: "**/*.tsx,**/*.ts" +alwaysApply: true +--- +``` + +## Regenerate + +```bash +./scripts/convert.sh --tool cursor +``` diff --git a/integrations/gemini-cli/README.md b/integrations/gemini-cli/README.md new file mode 100644 index 0000000..913a744 --- /dev/null +++ b/integrations/gemini-cli/README.md @@ -0,0 +1,36 @@ +# Gemini CLI Integration + +Packages all 61 Agency agents as a Gemini CLI extension. The extension +installs to `~/.gemini/extensions/agency-agents/`. + +## Install + +```bash +./scripts/install.sh --tool gemini-cli +``` + +## Activate a Skill + +In Gemini CLI, reference an agent by name: + +``` +Use the frontend-developer skill to help me build this UI. +``` + +## Extension Structure + +``` +~/.gemini/extensions/agency-agents/ + gemini-extension.json + skills/ + frontend-developer/SKILL.md + backend-architect/SKILL.md + reality-checker/SKILL.md + ... +``` + +## Regenerate + +```bash +./scripts/convert.sh --tool gemini-cli +``` diff --git a/integrations/opencode/README.md b/integrations/opencode/README.md new file mode 100644 index 0000000..a4a5db3 --- /dev/null +++ b/integrations/opencode/README.md @@ -0,0 +1,58 @@ +# OpenCode Integration + +OpenCode uses the same agent format as Claude Code β€” `.md` files with YAML +frontmatter stored in `.opencode/agent/`. No conversion is technically +needed, but this integration packages the agents into the correct directory +structure for drop-in use. + +## Install + +```bash +# Run from your project root +cd /your/project +/path/to/agency-agents/scripts/install.sh --tool opencode +``` + +This creates `.opencode/agent/.md` files in your project directory. + +## Activate an Agent + +In OpenCode, reference an agent by its name or description: + +``` +Use the Frontend Developer agent to help build this component. +``` + +``` +Activate the Reality Checker agent and review this PR. +``` + +You can also select agents from the OpenCode UI's agent picker. + +## Agent Format + +OpenCode agents use the same frontmatter as Claude Code: + +```yaml +--- +name: Frontend Developer +description: Expert frontend developer specializing in modern web technologies... +color: cyan +--- +``` + +## Project vs Global + +Agents in `.opencode/agent/` are **project-scoped**. To make them available +globally across all projects, copy them to your OpenCode config directory: + +```bash +mkdir -p ~/.config/opencode/agent +cp integrations/opencode/agent/*.md ~/.config/opencode/agent/ +``` + +## Regenerate + +```bash +./scripts/convert.sh --tool opencode +``` diff --git a/integrations/windsurf/README.md b/integrations/windsurf/README.md new file mode 100644 index 0000000..868602c --- /dev/null +++ b/integrations/windsurf/README.md @@ -0,0 +1,26 @@ +# Windsurf Integration + +All 61 Agency agents are consolidated into a single `.windsurfrules` file. +Rules are **project-scoped** β€” install them from your project root. + +## Install + +```bash +# Run from your project root +cd /your/project +/path/to/agency-agents/scripts/install.sh --tool windsurf +``` + +## Activate an Agent + +In Windsurf, reference an agent by name in your prompt: + +``` +Use the Frontend Developer agent to build this component. +``` + +## Regenerate + +```bash +./scripts/convert.sh --tool windsurf +``` diff --git a/project-management/project-manager-senior.md b/project-management/project-manager-senior.md index abda501..026cd71 100644 --- a/project-management/project-manager-senior.md +++ b/project-management/project-manager-senior.md @@ -1,6 +1,6 @@ --- name: Senior Project Manager -description: Converts specs to tasks, remembers previous projects\n - Focused on realistic scope, no background processes, exact spec requirements +description: Converts specs to tasks and remembers previous projects. Focused on realistic scope, no background processes, exact spec requirements color: blue --- diff --git a/scripts/convert.sh b/scripts/convert.sh new file mode 100755 index 0000000..fb426a5 --- /dev/null +++ b/scripts/convert.sh @@ -0,0 +1,362 @@ +#!/usr/bin/env bash +# +# convert.sh β€” Convert agency agent .md files into tool-specific formats. +# +# Reads all agent files from the standard category directories and outputs +# converted files to integrations//. Run this to regenerate all +# integration files after adding or modifying agents. +# +# Usage: +# ./scripts/convert.sh [--tool ] [--out ] [--help] +# +# Tools: +# antigravity β€” Antigravity skill files (~/.gemini/antigravity/skills/) +# gemini-cli β€” Gemini CLI extension (skills/ + gemini-extension.json) +# opencode β€” OpenCode agent files (.opencode/agent/*.md) +# cursor β€” Cursor rule files (.cursor/rules/*.mdc) +# aider β€” Single CONVENTIONS.md for Aider +# windsurf β€” Single .windsurfrules for Windsurf +# all β€” All tools (default) +# +# Output is written to integrations// relative to the repo root. +# This script never touches user config dirs β€” see install.sh for that. + +set -euo pipefail + +# --- Colour helpers --- +if [[ -t 1 ]]; then + GREEN=$'\033[0;32m'; YELLOW=$'\033[1;33m'; RED=$'\033[0;31m'; BOLD=$'\033[1m'; RESET=$'\033[0m' +else + GREEN=''; YELLOW=''; RED=''; BOLD=''; RESET='' +fi + +info() { printf "${GREEN}[OK]${RESET} %s\n" "$*"; } +warn() { printf "${YELLOW}[!!]${RESET} %s\n" "$*"; } +error() { printf "${RED}[ERR]${RESET} %s\n" "$*" >&2; } +header() { echo -e "\n${BOLD}$*${RESET}"; } + +# --- Paths --- +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" +OUT_DIR="$REPO_ROOT/integrations" +TODAY="$(date +%Y-%m-%d)" + +AGENT_DIRS=( + design engineering marketing product project-management + testing support spatial-computing specialized +) + +# --- Usage --- +usage() { + sed -n '3,22p' "$0" | sed 's/^# \{0,1\}//' + exit 0 +} + +# --- Frontmatter helpers --- + +# Extract a single field value from YAML frontmatter block. +# Usage: get_field +get_field() { + local field="$1" file="$2" + awk -v f="$field" ' + /^---$/ { fm++; next } + fm == 1 && $0 ~ "^" f ": " { sub("^" f ": ", ""); print; exit } + ' "$file" +} + +# Strip the leading frontmatter block and return only the body. +# Usage: get_body +get_body() { + awk 'BEGIN{fm=0} /^---$/{fm++; next} fm>=2{print}' "$1" +} + +# Convert a human-readable agent name to a lowercase kebab-case slug. +# "Frontend Developer" β†’ "frontend-developer" +slugify() { + echo "$1" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9]/-/g' | sed 's/--*/-/g' | sed 's/^-//;s/-$//' +} + +# --- Per-tool converters --- + +convert_antigravity() { + local file="$1" + local name description slug outdir outfile body + + name="$(get_field "name" "$file")" + description="$(get_field "description" "$file")" + slug="agency-$(slugify "$name")" + body="$(get_body "$file")" + + outdir="$OUT_DIR/antigravity/$slug" + outfile="$outdir/SKILL.md" + mkdir -p "$outdir" + + # Antigravity SKILL.md format mirrors community skills in ~/.gemini/antigravity/skills/ + cat > "$outfile" < "$outfile" < "$outfile" < "$outfile" < "$AIDER_TMP" <<'HEREDOC' +# The Agency β€” AI Agent Conventions +# +# This file provides Aider with the full roster of specialized AI agents from +# The Agency (https://github.com/msitarzewski/agency-agents). +# +# To activate an agent, reference it by name in your Aider session prompt, e.g.: +# "Use the Frontend Developer agent to review this component." +# +# Generated by scripts/convert.sh β€” do not edit manually. + +HEREDOC + +cat > "$WINDSURF_TMP" <<'HEREDOC' +# The Agency β€” AI Agent Rules for Windsurf +# +# Full roster of specialized AI agents from The Agency. +# To activate an agent, reference it by name in your Windsurf conversation. +# +# Generated by scripts/convert.sh β€” do not edit manually. + +HEREDOC + +accumulate_aider() { + local file="$1" + local name description body + + name="$(get_field "name" "$file")" + description="$(get_field "description" "$file")" + body="$(get_body "$file")" + + cat >> "$AIDER_TMP" < ${description} + +${body} +HEREDOC +} + +accumulate_windsurf() { + local file="$1" + local name description body + + name="$(get_field "name" "$file")" + description="$(get_field "description" "$file")" + body="$(get_body "$file")" + + cat >> "$WINDSURF_TMP" < "$OUT_DIR/gemini-cli/gemini-extension.json" <<'HEREDOC' +{ + "name": "agency-agents", + "version": "1.0.0" +} +HEREDOC + info "Wrote gemini-extension.json" + fi + + info "Converted $count agents for $t" + done + + # Write single-file outputs after accumulation + if [[ "$tool" == "all" || "$tool" == "aider" || "$tool" == "windsurf" ]]; then + write_single_file_outputs + info "Wrote integrations/aider/CONVENTIONS.md" + info "Wrote integrations/windsurf/.windsurfrules" + fi + + echo "" + info "Done. Total conversions: $total" +} + +main "$@" diff --git a/scripts/install.sh b/scripts/install.sh new file mode 100755 index 0000000..b7c1939 --- /dev/null +++ b/scripts/install.sh @@ -0,0 +1,465 @@ +#!/usr/bin/env bash +# +# install.sh -- Install The Agency agents into your local agentic tool(s). +# +# Reads converted files from integrations/ and copies them to the appropriate +# config directory for each tool. Run scripts/convert.sh first if integrations/ +# is missing or stale. +# +# Usage: +# ./scripts/install.sh [--tool ] [--interactive] [--no-interactive] [--help] +# +# Tools: +# claude-code -- Copy agents to ~/.claude/agents/ +# antigravity -- Copy skills to ~/.gemini/antigravity/skills/ +# gemini-cli -- Install extension to ~/.gemini/extensions/agency-agents/ +# opencode -- Copy agents to .opencode/agent/ in current directory +# cursor -- Copy rules to .cursor/rules/ in current directory +# aider -- Copy CONVENTIONS.md to current directory +# windsurf -- Copy .windsurfrules to current directory +# all -- Install for all detected tools (default) +# +# Flags: +# --tool Install only the specified tool +# --interactive Show interactive selector (default when run in a terminal) +# --no-interactive Skip interactive selector, install all detected tools +# --help Show this help +# +# Platform support: +# Linux, macOS (requires bash 3.2+), Windows Git Bash / WSL + +set -euo pipefail + +# --------------------------------------------------------------------------- +# Colours -- only when stdout is a real terminal +# --------------------------------------------------------------------------- +if [[ -t 1 ]]; then + C_GREEN=$'\033[0;32m' + C_YELLOW=$'\033[1;33m' + C_RED=$'\033[0;31m' + C_CYAN=$'\033[0;36m' + C_BOLD=$'\033[1m' + C_DIM=$'\033[2m' + C_RESET=$'\033[0m' +else + C_GREEN=''; C_YELLOW=''; C_RED=''; C_CYAN=''; C_BOLD=''; C_DIM=''; C_RESET='' +fi + +ok() { printf "${C_GREEN}[OK]${C_RESET} %s\n" "$*"; } +warn() { printf "${C_YELLOW}[!!]${C_RESET} %s\n" "$*"; } +err() { printf "${C_RED}[ERR]${C_RESET} %s\n" "$*" >&2; } +header() { printf "\n${C_BOLD}%s${C_RESET}\n" "$*"; } +dim() { printf "${C_DIM}%s${C_RESET}\n" "$*"; } + +# --------------------------------------------------------------------------- +# Box drawing -- pure ASCII, fixed 52-char wide +# box_top / box_mid / box_bot -- structural lines +# box_row -- content row, right-padded to fit +# --------------------------------------------------------------------------- +BOX_INNER=48 # chars between the two | walls + +box_top() { printf " +"; printf '%0.s-' $(seq 1 $BOX_INNER); printf "+\n"; } +box_bot() { box_top; } +box_sep() { printf " |"; printf '%0.s-' $(seq 1 $BOX_INNER); printf "|\n"; } +box_row() { + # Strip ANSI escapes when measuring visible length + local raw="$1" + local visible + visible="$(printf '%s' "$raw" | sed 's/\x1b\[[0-9;]*m//g')" + local pad=$(( BOX_INNER - 2 - ${#visible} )) + if (( pad < 0 )); then pad=0; fi + printf " | %s%*s |\n" "$raw" "$pad" '' +} +box_blank() { printf " |%*s|\n" $BOX_INNER ''; } + +# --------------------------------------------------------------------------- +# Paths +# --------------------------------------------------------------------------- +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" +INTEGRATIONS="$REPO_ROOT/integrations" + +ALL_TOOLS=(claude-code antigravity gemini-cli opencode cursor aider windsurf) + +# --------------------------------------------------------------------------- +# Usage +# --------------------------------------------------------------------------- +usage() { + sed -n '3,28p' "$0" | sed 's/^# \{0,1\}//' + exit 0 +} + +# --------------------------------------------------------------------------- +# Preflight +# --------------------------------------------------------------------------- +check_integrations() { + if [[ ! -d "$INTEGRATIONS" ]]; then + err "integrations/ not found. Run ./scripts/convert.sh first." + exit 1 + fi +} + +# --------------------------------------------------------------------------- +# Tool detection +# --------------------------------------------------------------------------- +detect_claude_code() { [[ -d "${HOME}/.claude" ]]; } +detect_antigravity() { [[ -d "${HOME}/.gemini/antigravity/skills" ]]; } +detect_gemini_cli() { command -v gemini >/dev/null 2>&1 || [[ -d "${HOME}/.gemini" ]]; } +detect_cursor() { command -v cursor >/dev/null 2>&1 || [[ -d "${HOME}/.cursor" ]]; } +detect_opencode() { command -v opencode >/dev/null 2>&1 || [[ -d "${HOME}/.config/opencode" ]]; } +detect_aider() { command -v aider >/dev/null 2>&1; } +detect_windsurf() { command -v windsurf >/dev/null 2>&1 || [[ -d "${HOME}/.codeium" ]]; } + +is_detected() { + case "$1" in + claude-code) detect_claude_code ;; + antigravity) detect_antigravity ;; + gemini-cli) detect_gemini_cli ;; + opencode) detect_opencode ;; + cursor) detect_cursor ;; + aider) detect_aider ;; + windsurf) detect_windsurf ;; + *) return 1 ;; + esac +} + +# Fixed-width labels: name (14) + detail (24) = 38 visible chars +tool_label() { + case "$1" in + claude-code) printf "%-14s %s" "Claude Code" "(claude.ai/code)" ;; + antigravity) printf "%-14s %s" "Antigravity" "(~/.gemini/antigravity)" ;; + gemini-cli) printf "%-14s %s" "Gemini CLI" "(gemini extension)" ;; + opencode) printf "%-14s %s" "OpenCode" "(opencode.ai)" ;; + cursor) printf "%-14s %s" "Cursor" "(.cursor/rules)" ;; + aider) printf "%-14s %s" "Aider" "(CONVENTIONS.md)" ;; + windsurf) printf "%-14s %s" "Windsurf" "(.windsurfrules)" ;; + esac +} + +# --------------------------------------------------------------------------- +# Interactive selector +# --------------------------------------------------------------------------- +interactive_select() { + # bash 3-compatible arrays + declare -a selected=() + declare -a detected_map=() + + local t + for t in "${ALL_TOOLS[@]}"; do + if is_detected "$t" 2>/dev/null; then + selected+=(1); detected_map+=(1) + else + selected+=(0); detected_map+=(0) + fi + done + + while true; do + # --- header --- + printf "\n" + box_top + box_row "${C_BOLD} The Agency -- Tool Installer${C_RESET}" + box_bot + printf "\n" + printf " ${C_DIM}System scan: [*] = detected on this machine${C_RESET}\n" + printf "\n" + + # --- tool rows --- + local i=0 + for t in "${ALL_TOOLS[@]}"; do + local num=$(( i + 1 )) + local label + label="$(tool_label "$t")" + local dot + if [[ "${detected_map[$i]}" == "1" ]]; then + dot="${C_GREEN}[*]${C_RESET}" + else + dot="${C_DIM}[ ]${C_RESET}" + fi + local chk + if [[ "${selected[$i]}" == "1" ]]; then + chk="${C_GREEN}[x]${C_RESET}" + else + chk="${C_DIM}[ ]${C_RESET}" + fi + printf " %s %s) %s %s\n" "$chk" "$num" "$dot" "$label" + (( i++ )) || true + done + + # --- controls --- + printf "\n" + printf " ------------------------------------------------\n" + printf " ${C_CYAN}[1-7]${C_RESET} toggle ${C_CYAN}[a]${C_RESET} all ${C_CYAN}[n]${C_RESET} none ${C_CYAN}[d]${C_RESET} detected\n" + printf " ${C_GREEN}[Enter]${C_RESET} install ${C_RED}[q]${C_RESET} quit\n" + printf "\n" + printf " >> " + read -r input = 0 && idx < ${#ALL_TOOLS[@]} )); then + if [[ "${selected[$idx]}" == "1" ]]; then + selected[$idx]=0 + else + selected[$idx]=1 + fi + toggled=true + fi + fi + done + if ! $toggled; then + printf " ${C_RED}Invalid. Enter a number 1-%s, or a command.${C_RESET}\n" "${#ALL_TOOLS[@]}" + sleep 1 + fi ;; + esac + + # Clear UI for redraw + local lines=$(( ${#ALL_TOOLS[@]} + 14 )) + local l + for (( l=0; l $dest" +} + +install_antigravity() { + local src="$INTEGRATIONS/antigravity" + local dest="${HOME}/.gemini/antigravity/skills" + local count=0 + [[ -d "$src" ]] || { err "integrations/antigravity missing. Run convert.sh first."; return 1; } + mkdir -p "$dest" + local d + while IFS= read -r -d '' d; do + local name; name="$(basename "$d")" + mkdir -p "$dest/$name" + cp "$d/SKILL.md" "$dest/$name/SKILL.md" + (( count++ )) || true + done < <(find "$src" -mindepth 1 -maxdepth 1 -type d -print0) + ok "Antigravity: $count skills -> $dest" +} + +install_gemini_cli() { + local src="$INTEGRATIONS/gemini-cli" + local dest="${HOME}/.gemini/extensions/agency-agents" + local count=0 + [[ -d "$src" ]] || { err "integrations/gemini-cli missing. Run convert.sh first."; return 1; } + mkdir -p "$dest/skills" + cp "$src/gemini-extension.json" "$dest/gemini-extension.json" + local d + while IFS= read -r -d '' d; do + local name; name="$(basename "$d")" + mkdir -p "$dest/skills/$name" + cp "$d/SKILL.md" "$dest/skills/$name/SKILL.md" + (( count++ )) || true + done < <(find "$src/skills" -mindepth 1 -maxdepth 1 -type d -print0) + ok "Gemini CLI: $count skills -> $dest" +} + +install_opencode() { + local src="$INTEGRATIONS/opencode/agent" + local dest="${PWD}/.opencode/agent" + local count=0 + [[ -d "$src" ]] || { err "integrations/opencode missing. Run convert.sh first."; return 1; } + mkdir -p "$dest" + local f + while IFS= read -r -d '' f; do + cp "$f" "$dest/"; (( count++ )) || true + done < <(find "$src" -maxdepth 1 -name "*.md" -print0) + ok "OpenCode: $count agents -> $dest" + warn "OpenCode: project-scoped. Run from your project root to install there." +} + +install_cursor() { + local src="$INTEGRATIONS/cursor/rules" + local dest="${PWD}/.cursor/rules" + local count=0 + [[ -d "$src" ]] || { err "integrations/cursor missing. Run convert.sh first."; return 1; } + mkdir -p "$dest" + local f + while IFS= read -r -d '' f; do + cp "$f" "$dest/"; (( count++ )) || true + done < <(find "$src" -maxdepth 1 -name "*.mdc" -print0) + ok "Cursor: $count rules -> $dest" + warn "Cursor: project-scoped. Run from your project root to install there." +} + +install_aider() { + local src="$INTEGRATIONS/aider/CONVENTIONS.md" + local dest="${PWD}/CONVENTIONS.md" + [[ -f "$src" ]] || { err "integrations/aider/CONVENTIONS.md missing. Run convert.sh first."; return 1; } + if [[ -f "$dest" ]]; then + warn "Aider: CONVENTIONS.md already exists at $dest (remove to reinstall)." + return 0 + fi + cp "$src" "$dest" + ok "Aider: installed -> $dest" + warn "Aider: project-scoped. Run from your project root to install there." +} + +install_windsurf() { + local src="$INTEGRATIONS/windsurf/.windsurfrules" + local dest="${PWD}/.windsurfrules" + [[ -f "$src" ]] || { err "integrations/windsurf/.windsurfrules missing. Run convert.sh first."; return 1; } + if [[ -f "$dest" ]]; then + warn "Windsurf: .windsurfrules already exists at $dest (remove to reinstall)." + return 0 + fi + cp "$src" "$dest" + ok "Windsurf: installed -> $dest" + warn "Windsurf: project-scoped. Run from your project root to install there." +} + +install_tool() { + case "$1" in + claude-code) install_claude_code ;; + antigravity) install_antigravity ;; + gemini-cli) install_gemini_cli ;; + opencode) install_opencode ;; + cursor) install_cursor ;; + aider) install_aider ;; + windsurf) install_windsurf ;; + esac +} + +# --------------------------------------------------------------------------- +# Entry point +# --------------------------------------------------------------------------- +main() { + local tool="all" + local interactive_mode="auto" + + while [[ $# -gt 0 ]]; do + case "$1" in + --tool) tool="${2:?'--tool requires a value'}"; shift 2; interactive_mode="no" ;; + --interactive) interactive_mode="yes"; shift ;; + --no-interactive) interactive_mode="no"; shift ;; + --help|-h) usage ;; + *) err "Unknown option: $1"; usage ;; + esac + done + + check_integrations + + # Validate explicit tool + if [[ "$tool" != "all" ]]; then + local valid=false t + for t in "${ALL_TOOLS[@]}"; do [[ "$t" == "$tool" ]] && valid=true && break; done + if ! $valid; then + err "Unknown tool '$tool'. Valid: ${ALL_TOOLS[*]}" + exit 1 + fi + fi + + # Decide whether to show interactive UI + local use_interactive=false + if [[ "$interactive_mode" == "yes" ]]; then + use_interactive=true + elif [[ "$interactive_mode" == "auto" && -t 0 && -t 1 && "$tool" == "all" ]]; then + use_interactive=true + fi + + SELECTED_TOOLS=() + + if $use_interactive; then + interactive_select + + elif [[ "$tool" != "all" ]]; then + SELECTED_TOOLS=("$tool") + + else + # Non-interactive: auto-detect + header "The Agency -- Scanning for installed tools..." + printf "\n" + local t + for t in "${ALL_TOOLS[@]}"; do + if is_detected "$t" 2>/dev/null; then + SELECTED_TOOLS+=("$t") + printf " ${C_GREEN}[*]${C_RESET} %s ${C_DIM}detected${C_RESET}\n" "$(tool_label "$t")" + else + printf " ${C_DIM}[ ] %s not found${C_RESET}\n" "$(tool_label "$t")" + fi + done + fi + + if [[ ${#SELECTED_TOOLS[@]} -eq 0 ]]; then + warn "No tools selected or detected. Nothing to install." + printf "\n" + dim " Tip: use --tool to force-install a specific tool." + dim " Available: ${ALL_TOOLS[*]}" + exit 0 + fi + + printf "\n" + header "The Agency -- Installing agents" + printf " Repo: %s\n" "$REPO_ROOT" + printf " Installing: %s\n" "${SELECTED_TOOLS[*]}" + printf "\n" + + local installed=0 t + for t in "${SELECTED_TOOLS[@]}"; do + install_tool "$t" + (( installed++ )) || true + done + + # Done box + local msg=" Done! Installed $installed tool(s)." + printf "\n" + box_top + box_row "${C_GREEN}${C_BOLD}${msg}${C_RESET}" + box_bot + printf "\n" + dim " Run ./scripts/convert.sh to regenerate after adding or editing agents." + printf "\n" +} + +main "$@"