#!/usr/bin/env bash # agents — one-line installer # Usage: curl -fsSL https://agents.creative-int.com/api/install | bash # # Installs the agents CLI globally, scaffolds ~/.agents/, and detects coding agents. set -euo pipefail # ─── Colors ───────────────────────────────────────────────── BOLD="\033[1m" DIM="\033[2m" GREEN="\033[32m" RED="\033[31m" YELLOW="\033[33m" CYAN="\033[36m" RESET="\033[0m" # ─── Output helpers ───────────────────────────────────────── log() { printf "${BOLD}${CYAN}>${RESET} %s\n" "$*"; } ok() { printf " ${GREEN}+${RESET} %s\n" "$*"; } warn() { printf " ${YELLOW}!${RESET} %s\n" "$*"; } fail() { printf "\n ${RED}x${RESET} %s\n\n" "$*"; exit 1; } dim() { printf " ${DIM}%s${RESET}\n" "$*"; } # ─── Header ───────────────────────────────────────────────── printf "\n" printf "${BOLD}" printf " ┌─────────────────────────────────┐\n" printf " │ │\n" printf " │ ▄▀█ █▀▀ █▀▀ █▄░█ ▀█▀ █▀▀ │\n" printf " │ █▀█ █▄█ ██▄ █░▀█ ░█░ ▄█▄ │\n" printf " │ │\n" printf " │ agent orchestration CLI │\n" printf " │ │\n" printf " └─────────────────────────────────┘\n" printf "${RESET}\n" # ─── Constants ─────────────────────────────────────────────── AGENTS_HOME="${AGENTS_HOME:-$HOME/.agents}" MIN_NODE=22 AGENTS_DIRS=( "artifacts" "prompts" "events" "resources" "skills" "rules" "hooks" "state" ) CODING_AGENTS=( "claude:Claude Code" "codex:Codex" "gemini:Gemini" "pi:Pi" ) # ─── Prerequisites ─────────────────────────────────────────── log "Checking prerequisites" # Node.js if ! command -v node &>/dev/null; then fail "Node.js not found. Install v${MIN_NODE}+ via https://nodejs.org or nvm." fi NODE_MAJOR=$(node -e "console.log(process.versions.node.split('.')[0])") if [ "$NODE_MAJOR" -lt "$MIN_NODE" ]; then fail "Node.js ${MIN_NODE}+ required (found $(node -v))" fi ok "Node.js $(node -v)" # Package manager detection PKG_MGR="" if command -v pnpm &>/dev/null; then PKG_MGR="pnpm" ok "pnpm $(pnpm -v)" elif command -v npm &>/dev/null; then PKG_MGR="npm" ok "npm $(npm -v)" elif command -v bun &>/dev/null; then PKG_MGR="bun" ok "bun $(bun -v)" else fail "No package manager found. Install pnpm, npm, or bun." fi # NPM_TOKEN for GitHub Packages if [ -z "${NPM_TOKEN:-}" ]; then # Check if .npmrc already has a token configured if [ -f "$HOME/.npmrc" ] && grep -q "npm.pkg.github.com" "$HOME/.npmrc" 2>/dev/null; then ok "GitHub Packages auth found in ~/.npmrc" else warn "NPM_TOKEN not set — needed for @creative-int/* packages from GitHub Packages" dim "Set it: export NPM_TOKEN=ghp_... (or add to Doppler/shell profile)" dim "Create a token: https://github.com/settings/tokens (read:packages scope)" fi else ok "NPM_TOKEN configured" fi printf "\n" # ─── Install CLI ───────────────────────────────────────────── log "Installing agents CLI" # Configure .npmrc for GitHub Packages scoped install NPMRC_LINE="@creative-int:registry=https://npm.pkg.github.com" GLOBAL_NPMRC="$HOME/.npmrc" if [ ! -f "$GLOBAL_NPMRC" ] || ! grep -qF "$NPMRC_LINE" "$GLOBAL_NPMRC" 2>/dev/null; then { echo "$NPMRC_LINE" if [ -n "${NPM_TOKEN:-}" ]; then echo "//npm.pkg.github.com/:_authToken=\${NPM_TOKEN}" fi } >> "$GLOBAL_NPMRC" dim "Added GitHub Packages registry to ~/.npmrc" fi # Install globally if bun add -g @creative-int/agents-cli 2>/dev/null; then ok "agents CLI installed" else fail "Could not install agents CLI. Check NPM_TOKEN, npm auth, and network." fi # Verify if command -v agents &>/dev/null; then AGENTS_VERSION=$(agents --version 2>/dev/null || echo "unknown") ok "agents v${AGENTS_VERSION} on PATH at $(which agents)" else warn "agents not found on PATH after install" dim "You may need to add the global bin directory to your PATH:" case "$PKG_MGR" in pnpm) dim " export PATH=\"\$(pnpm bin -g):\$PATH\"" ;; npm) dim " export PATH=\"\$(npm prefix -g)/bin:\$PATH\"" ;; bun) dim " export PATH=\"\$HOME/.bun/bin:\$PATH\"" ;; esac fi printf "\n" # ─── Scaffold ~/.agents ───────────────────────────────────── log "Setting up ~/.agents" DIRS_CREATED=0 DIRS_EXISTED=0 for dir in "${AGENTS_DIRS[@]}"; do target="$AGENTS_HOME/$dir" if [ ! -d "$target" ]; then mkdir -p "$target" DIRS_CREATED=$((DIRS_CREATED + 1)) else DIRS_EXISTED=$((DIRS_EXISTED + 1)) fi done if [ "$DIRS_CREATED" -gt 0 ]; then ok "Created ${DIRS_CREATED} directories" fi if [ "$DIRS_EXISTED" -gt 0 ]; then dim "${DIRS_EXISTED} directories already existed" fi # Ensure AGENTS.md exists if [ ! -f "$AGENTS_HOME/AGENTS.md" ]; then cat > "$AGENTS_HOME/AGENTS.md" << 'EOF' # ~/.agents — Agent Operating System Agent configuration, skills, rules, and session state. See: https://github.com/creative-int/agents EOF ok "Created AGENTS.md" fi printf "\n" # ─── Detect coding agents ─────────────────────────────────── log "Detecting coding agents" FOUND_COUNT=0 TOTAL_COUNT=${#CODING_AGENTS[@]} for entry in "${CODING_AGENTS[@]}"; do cmd="${entry%%:*}" label="${entry#*:}" if command -v "$cmd" &>/dev/null; then version=$("$cmd" --version 2>/dev/null | head -1 || echo "") if [ -n "$version" ]; then ok "${label} ${DIM}(${version})${RESET}" else ok "${label}" fi FOUND_COUNT=$((FOUND_COUNT + 1)) else dim "- ${label}" fi done printf "\n" if [ "$FOUND_COUNT" -eq 0 ]; then warn "No coding agents detected" dim "Install at least one: claude, codex, gemini, or pi" elif [ "$FOUND_COUNT" -lt "$TOTAL_COUNT" ]; then dim "${FOUND_COUNT}/${TOTAL_COUNT} agents available" else ok "All ${TOTAL_COUNT} agents available" fi # ─── Provider setup guidance ───────────────────────────────── log "Provider setup" PROVIDERS=( "ANTHROPIC_API_KEY:Anthropic (Claude Code):https://console.anthropic.com/settings/keys" "OPENAI_API_KEY:OpenAI (Codex):https://platform.openai.com/api-keys" "GITHUB_TOKEN:GitHub Copilot:https://github.com/settings/tokens" "GEMINI_API_KEY:Google (Gemini):https://aistudio.google.com/apikey" ) PROVIDER_COUNT=0 for entry in "${PROVIDERS[@]}"; do key="${entry%%:*}" rest="${entry#*:}" label="${rest%%:*}" url="${rest#*:}" if [ -n "${!key:-}" ]; then ok "${label} configured" PROVIDER_COUNT=$((PROVIDER_COUNT + 1)) else dim "- ${label} — set ${key}" dim " ${url}" fi done if [ "$PROVIDER_COUNT" -eq 0 ]; then warn "No provider API keys detected" dim "Set at least one in your shell profile or Doppler to use agent sessions" fi printf "\n" # ─── Summary ───────────────────────────────────────────────── # ─── Daemons ──────────────────────────────────────────────── printf " ${BOLD}Installing background daemons...${RESET}\n" if command -v agents &>/dev/null; then agents sync --install --interval 60 2>/dev/null && ok "Sync daemon installed (every 60s)" || dim "- sync daemon: install skipped" agents gateway --install 2>/dev/null && ok "Gateway daemon installed" || dim "- gateway daemon: install skipped (missing channel env)" agents work --install 2>/dev/null && ok "Work daemon installed" || dim "- work daemon: install skipped" else dim "- agents binary not on PATH — daemons skipped" fi printf "\n" printf " ${BOLD}Setup complete${RESET}\n" printf "\n" printf " ${DIM}Verify:${RESET} agents doctor\n" printf " ${DIM}Sync:${RESET} agents sync (running automatically every 60s)\n" printf " ${DIM}Start:${RESET} agents session start -a claude -g \"your task\"\n" printf " ${DIM}Dashboard:${RESET} https://agents.creative-int.com\n" printf " ${DIM}Config:${RESET} ~/.agents/\n" printf " ${DIM}Daemons:${RESET} launchctl list | grep com.agents\n" printf "\n"