#!/bin/sh # ============================================================================= # atualizar-agente.sh — Sincroniza base via git submodule # # Modo submodule (padrão — recomendado): # O .agent é um submodulo git. Este script faz: # 1. git submodule update --remote --merge (atualiza o submodulo) # 2. Copia artefatos do submodulo → .agent/inherited/ # # Modo legado (fallback via curl): # Ativado se não houver .gitmodules ou se rodar fora de um repo git. # Requer: curl, jq, e campo "extends" no manifesto-local.json # # Uso: # sh .agent/atualizar-agente.sh # atualiza tudo # sh .agent/atualizar-agente.sh --dry-run # mostra o que seria copiado # sh .agent/atualizar-agente.sh --no-pull # copia sem fazer git pull # # Dependências: git (modo submodule) | curl + jq (modo legado) # ============================================================================= AGENT_DIR="$(cd "$(dirname "$0")" && pwd)" PROJETO_DIR="$(cd "$AGENT_DIR/.." && pwd)" MANIFESTO_LOCAL="$AGENT_DIR/manifesto-local.json" INHERITED_DIR="$AGENT_DIR/inherited" ERROS=0 DRY_RUN=0 NO_PULL=0 for arg in "$@"; do case "$arg" in --dry-run) DRY_RUN=1 ;; --no-pull) NO_PULL=1 ;; esac done # --- Verificar manifesto-local.json --- if [ ! -f "$MANIFESTO_LOCAL" ]; then echo "❌ manifesto-local.json não encontrado." echo " Copie: cp .agent/manifesto-local.template.json .agent/manifesto-local.json" echo " Configure o campo 'submodulo' com o path do submodulo." exit 1 fi if ! command -v jq >/dev/null 2>&1; then echo "❌ jq não encontrado. Instale com: sudo apt-get install jq" exit 1 fi PROJETO=$(jq -r '.projeto // "projeto"' "$MANIFESTO_LOCAL") # --- Detectar modo: submodule ou legado --- SUBMODULO_PATH=$(jq -r '.submodulo // empty' "$MANIFESTO_LOCAL") BASE_URL=$(jq -r '.extends // empty' "$MANIFESTO_LOCAL") # Resolver path absoluto do submodulo if [ -n "$SUBMODULO_PATH" ]; then if echo "$SUBMODULO_PATH" | grep -q "^/"; then BASE_DIR="$SUBMODULO_PATH" else BASE_DIR="$PROJETO_DIR/$SUBMODULO_PATH" fi fi # --- MODO SUBMODULE --- if [ -n "$SUBMODULO_PATH" ] && [ -f "$PROJETO_DIR/.gitmodules" ]; then echo "📦 [$PROJETO] Modo: git submodule" echo " Submodulo: $SUBMODULO_PATH" echo "" # Atualizar o submodulo (se não usar --no-pull) if [ "$NO_PULL" = "0" ] && [ "$DRY_RUN" = "0" ]; then echo "🔄 Atualizando submodulo..." cd "$PROJETO_DIR" || exit 1 if git submodule update --remote --merge "$SUBMODULO_PATH" 2>/dev/null; then echo "✅ Submodulo atualizado." else echo "⚠ git submodule update falhou. Tentando init primeiro..." git submodule update --init --recursive "$SUBMODULO_PATH" fi echo "" cd "$AGENT_DIR" || exit 1 fi # Verificar se o base existe no path do submodulo if [ -d "$BASE_DIR/global" ]; then BASE_AGENT="$BASE_DIR" else echo "❌ Não encontrei artefatos em: $BASE_DIR" echo " Verifique se o submodulo foi inicializado: git submodule update --init" exit 1 fi echo "📋 Sincronizando $BASE_AGENT → inherited/..." # Função: copiar arquivo copiar() { ORIGEM="$1" DESTINO_REL="$2" DESTINO="$INHERITED_DIR/$DESTINO_REL" if [ "$DRY_RUN" = "1" ]; then echo " [dry-run] inherited/$DESTINO_REL" return 0 fi if [ ! -f "$ORIGEM" ]; then echo " ⚠ Não encontrado: $ORIGEM" ERROS=$((ERROS + 1)) return 1 fi mkdir -p "$(dirname "$DESTINO")" cp "$ORIGEM" "$DESTINO" echo " ✅ inherited/$DESTINO_REL" } # Criar README e .gitignore em inherited/ if [ "$DRY_RUN" = "0" ]; then mkdir -p "$INHERITED_DIR" cat > "$INHERITED_DIR/README" << 'EOF' # ⚠️ Pasta gerenciada automaticamente Conteúdo copiado do submodulo .agent. **NUNCA edite aqui.** Para customizar, use `.agent/local/`. Para atualizar: sh .agent/atualizar-agente.sh EOF printf '*\n!.gitignore\n!README\n' > "$INHERITED_DIR/.gitignore" fi # Copiar global/ echo "" echo "🌐 Global..." for f in "$BASE_AGENT/global/rules/"*; do [ -f "$f" ] || continue case "$f" in *.sh|*.json) continue ;; esac copiar "$f" "global/rules/$(basename "$f")" done for f in "$BASE_AGENT/global/workflows/"*; do [ -f "$f" ] || continue case "$f" in *.sh|*.json) continue ;; esac copiar "$f" "global/workflows/$(basename "$f")" done for d in "$BASE_AGENT/global/skills/"*/; do [ -f "$d/SKILL" ] && copiar "$d/SKILL" "global/skills/$(basename "$d")/SKILL" done # Copiar agents/ echo "" echo "🤖 Agentes..." for agente_dir in "$BASE_AGENT/agents/"*/; do AGENTE=$(basename "$agente_dir") [ -f "$agente_dir/persona" ] && copiar "$agente_dir/persona" "agents/$AGENTE/persona" [ -f "$agente_dir/agent.json" ] && copiar "$agente_dir/agent.json" "agents/$AGENTE/agent.json" for f in "$agente_dir/rules/"*; do [ -f "$f" ] || continue case "$f" in *.sh|*.json) continue ;; esac copiar "$f" "agents/$AGENTE/rules/$(basename "$f")" done for f in "$agente_dir/workflows/"*; do [ -f "$f" ] || continue case "$f" in *.sh|*.json) continue ;; esac copiar "$f" "agents/$AGENTE/workflows/$(basename "$f")" done for d in "$agente_dir/skills/"*/; do [ -f "$d/SKILL" ] && copiar "$d/SKILL" "agents/$AGENTE/skills/$(basename "$d")/SKILL" done done # Copiar adaptadores/ echo "" echo "🔌 Adaptadores..." for f in "$BASE_AGENT/adaptadores/antigravity/"*; do [ -f "$f" ] && copiar "$f" "adaptadores/antigravity/$(basename "$f")" done for f in "$BASE_AGENT/adaptadores/claude/"*; do [ -f "$f" ] && copiar "$f" "adaptadores/claude/$(basename "$f")" done for f in "$BASE_AGENT/adaptadores/openai/"*; do [ -f "$f" ] && copiar "$f" "adaptadores/openai/$(basename "$f")" done # Copiar tools e verificar-linhas [ -f "$BASE_AGENT/TOOLS" ] && copiar "$BASE_AGENT/TOOLS" "TOOLS" [ -f "$BASE_AGENT/verificar-linhas.sh" ] && copiar "$BASE_AGENT/verificar-linhas.sh" "verificar-linhas.sh" chmod +x "$INHERITED_DIR/verificar-linhas.sh" 2>/dev/null chmod +x "$INHERITED_DIR/adaptadores/antigravity/gerar-agent-json.sh" 2>/dev/null # --- MODO LEGADO (curl) --- elif [ -n "$BASE_URL" ]; then echo "📡 [$PROJETO] Modo: curl (legado)" echo " Base URL: $BASE_URL" echo " ⚠ Recomendado: migrar para git submodule (ver EXTEND)" echo "" if ! command -v curl >/dev/null 2>&1; then echo "❌ curl não encontrado." exit 1 fi MANIFESTO_TMP=$(mktemp) MANIFESTO_URL="$BASE_URL/manifesto.json" if ! curl -sSfL "$MANIFESTO_URL" -o "$MANIFESTO_TMP" 2>/dev/null; then echo "❌ Não foi possível baixar o manifesto de: $MANIFESTO_URL" rm -f "$MANIFESTO_TMP" exit 1 fi baixar_legado() { URL="$1"; DESTINO="$INHERITED_DIR/$2" [ "$DRY_RUN" = "1" ] && echo " [dry-run] $2" && return TMP=$(mktemp) curl -sSfL "$URL" -o "$TMP" 2>/dev/null && mv "$TMP" "$DESTINO" && echo " ✅ $2" || { echo " ⚠ Falha: $URL"; rm -f "$TMP"; ERROS=$((ERROS + 1)) } } mkdir -p "$INHERITED_DIR" jq -r '.artefatos.global.rules[],.artefatos.global.workflows[],.artefatos.global.skills[]' \ "$MANIFESTO_TMP" 2>/dev/null | while read -r c; do baixar_legado "$BASE_URL/$c" "$c"; done AGENTES=$(jq -r '.artefatos.agents | keys[]' "$MANIFESTO_TMP" 2>/dev/null) for AGENTE in $AGENTES; do jq -r ".artefatos.agents[\"$AGENTE\"] | .persona,.config,.rules[],.workflows[],.skills[] | select(.)" \ "$MANIFESTO_TMP" 2>/dev/null | while read -r c; do baixar_legado "$BASE_URL/$c" "$c"; done done rm -f "$MANIFESTO_TMP" else echo "❌ manifesto-local.json precisa ter 'submodulo' (git) ou 'extends' (curl legado)." echo " Consulte EXTEND para instruções." exit 1 fi # --- CONFIGURAR SYMLINKS .gemini/agents/ (Antigravity) --- echo "" echo "🔗 Configurando agentes para o Antigravity (.gemini/agents/)..." GEMINI_AGENTS_DIR="$PROJETO_DIR/.gemini/agents" mkdir -p "$GEMINI_AGENTS_DIR" LINKS_CRIADOS=0 for agente_dir in "$AGENT_DIR/agents/"*/; do AGENTE=$(basename "$agente_dir") DESTINO="$GEMINI_AGENTS_DIR/$AGENTE" # Verificar se o agente tem agent.json (no submodule ou inherited) if [ ! -f "$agente_dir/agent.json" ]; then # Tentar gerar se o adaptador existir if [ -f "$AGENT_DIR/adaptadores/antigravity/gerar-agent-json.sh" ]; then sh "$AGENT_DIR/adaptadores/antigravity/gerar-agent-json.sh" "$AGENTE" >/dev/null 2>&1 fi fi # Só criar symlink se agent.json existir [ ! -f "$agente_dir/agent.json" ] && continue # Calcular path relativo: .gemini/agents/ag-xxx → .agent/agents/ag-xxx REL_PATH="../../.agent/agents/$AGENTE" if [ -L "$DESTINO" ]; then ATUAL=$(readlink "$DESTINO") [ "$ATUAL" = "$REL_PATH" ] && continue rm "$DESTINO" elif [ -d "$DESTINO" ]; then continue fi if [ "$DRY_RUN" = "1" ]; then echo " [dry-run] .gemini/agents/$AGENTE → $REL_PATH" else ln -s "$REL_PATH" "$DESTINO" echo " ✅ .gemini/agents/$AGENTE" fi LINKS_CRIADOS=$((LINKS_CRIADOS + 1)) done if [ "$LINKS_CRIADOS" -gt 0 ]; then echo " 📋 $LINKS_CRIADOS symlink(s) criado(s)" else echo " ✅ Todos os symlinks já estavam atualizados" fi echo "" if [ "$ERROS" -gt 0 ]; then echo "⚠ [$PROJETO] Concluído com $ERROS erro(s)." else echo "✅ [$PROJETO] inherited/ sincronizado com sucesso." echo "✅ Agentes acessíveis via @ag-* no chat do Antigravity." echo "" echo "💡 Seus arquivos locais estão em: .agent/local/" fi exit "$ERROS"