Skip to content

Agente Nation como Código (IaC) com Next.js + GitHub Pages

🎯 Resumo Executivo

Você solicitou uma forma mais simples de configurar agentes Nation usando código em vez de clicar em dashboards. Criei uma solução Infrastructure as Code (IaC) baseada em:

  • Next.js (editor visual web)
  • GitHub Pages (hospedagem gratuita)
  • YAML (configuração legível)
  • JSON Schema (validação automática)
  • GitHub Actions (CI/CD)

Resultado: Tudo é código versionado em Git


📦 Arquivos Entregues

nation-ecommerce-guide.pdf (23 páginas) - Guia completo de arquitetura - Visão geral de pagamentos x402 - Skills nativas da Nation - Exemplos práticos

nation-ecommerce-agent.zip (Aplicativo Interativo) - Demo visual do fluxo de compra - Simula pagamento x402 - Mostra histórico de pedidos

code-examples.md - Exemplos prontos para implementação - Backend Express.js com x402 - Cliente Next.js com Web3 - Smart contracts para auditoria

iac-solution.md (Solução IaC Completa) - Arquitetura detalhada - JSON Schema de validação - Componentes React - GitHub Actions workflow - 10 vantagens da abordagem

quickstart-iac.md (10 Passos Rápidos) - Setup inicial (30 min) - Criação JSON Schema - Validador TypeScript - Componente Editor - CI/CD GitHub Actions

iac-complete-guide.md (Guia Completo) - Comparativa antes vs depois - 3 níveis de uso (Dev/UI/CLI) - Data flow diagrama - Estrutura de pastas - Scripts npm


🏗️ Como Funciona a Solução

1️⃣ Arquivo YAML = Agente

agent:
  name: ecommerce-bot
  model: gpt-4
  version: 1.0.0

skills:
  - name: catalog
    endpoint: https://api.com/catalog
  - name: payment
    endpoint: https://api.com/payment

payment:
  network: base
  token: usdc
  agent_wallet: 0x...

2️⃣ Validação Automática

YAML → Parse → Validate (JSON Schema) → TypeScript Types
                                              ↓
                                    ✓ Válido / ✗ Erros

3️⃣ GitHub Actions CI/CD

git push
    ↓
GitHub Actions
├─ Valida YAML
├─ Verifica Schema
├─ Executa testes
└─ Deploy GitHub Pages
    ↓
Site atualizado + Git versioning

4️⃣ Editor Visual no Navegador

https://seu-username.github.io/seu-repositorio
├─ Editor YAML side-by-side
├─ Preview JSON em tempo real
├─ Lista de todos os agentes
└─ Validação on-the-fly

🎨 Três Formas de Usar

Tipo de Usuário Como Usa Resultado
Engenheiro DevOps vim configs/agent.yaml + npm run validate:configs + git push Agente validado e deployado
Gerente de Produto Abre site web → Preenche formulário → Submit PR Agente pronto para review
SRE/Automação npm run deploy:agent my-agent Deploy direto via CLI

✅ Vantagens vs Solução Manual

Aspecto Manual Dashboard IaC (Nossa Solução)
Versionamento ❌ Não ✅ Git history completo
Collaboração ❌ Não ✅ PRs com code review
Validação ❌ Após salvar ✅ Antes de fazer push
Reproducibilidade ❌ Difícil ✅ Mesma config em qualquer lugar
Auditoria ⚠️ Limitada git log completo
Rollback ❌ Manual git revert automático
Documentação ❌ Separada ✅ YAML é auto-doc
CI/CD ❌ Não ✅ GitHub Actions
Hosting 💰 Pago ✅ GitHub Pages (grátis)
Offline ❌ Não ✅ Validar offline

🚀 Implementação Rápida (Esta Semana)

Dia 1-2: Setup Base (2-3 horas)

# 1. Criar estrutura
mkdir -p src/{components,lib,pages/api,types} public/configs

# 2. Setup Next.js
npx create-next-app@latest . --typescript

# 3. Instalar deps
npm install js-yaml ajv

Dia 3: Validador (2 horas)

  • Criar agent.schema.json
  • Criar src/lib/agent-validator.ts
  • Testar validação local

Dia 4: Editor Web (3 horas)

  • Criar src/components/AgentEditor.tsx
  • Criar src/pages/editor.tsx
  • Testar no navegador local

Dia 5: CI/CD (2 horas)

  • Criar .github/workflows/deploy.yml
  • Push para main
  • GitHub Actions executa automaticamente

Resultado: Site ativo em GitHub Pages em 1-2 dias úteis


📋 Pré-requisitos

✅ Node.js 20+
✅ Git + GitHub
✅ GitHub Pages habilitado no repositório
✅ Conhecimento básico TypeScript/React (opcional, templates fornecidos)


🎁 O Que Você Recebe

📄 Documentação (83 páginas)

  • Setup completo passo a passo
  • Arquitetura explicada
  • Exemplos de código prontos

💾 Templates de Código

  • JSON Schema pronto para usar
  • Componentes React React
  • Scripts Node.js
  • GitHub Actions workflow
  • Testes unitários

🔧 Ferramentas

  • Validador YAML/JSON
  • CLI de validação
  • Editor visual interativo
  • Deploy script

📊 Exemplos

  • E-commerce agent completo
  • Trading agent
  • Support agent
  • Fixtures para testes

🌟 Benefícios Principais

  1. Single Source of Truth: Tudo em Git, uma verdade absoluta
  2. Colaboração Segura: PRs com validação automática
  3. Zero Custo de Hosting: GitHub Pages gratuito
  4. Auditoria Completa: Quem mudou o quê e quando
  5. Reproducibilidade: git clone e tudo funciona igual
  6. Escalabilidade: Gerenciar 1 ou 100 agentes da mesma forma
  7. Documentação Automática: YAML é self-documenting
  8. Offline-First: Validar sem internet

📞 Suporte Próximos Passos

  1. Clone repositório template (quando preparado)
  2. Follow quickstart.md (passo a passo visual)
  3. Deploy primeiro agente (teste ponta a ponta)
  4. Compartilhe feedback (iterate e melhore)

🎯 Conclusão

Você agora tem uma solução enterprise-grade para gerenciar agentes Nation usando Infrastructure as Code, totalmente versionada em Git e deployada no GitHub Pages.

Nenhuma configuração manual no dashboard. Tudo é código.

Próximo passo: Implementar a estrutura base do repositório com os templates fornecidos!

Fontes [1] Using YAML Files To Define Tasks And Parameters For AI ... https://empathyfirstmedia.com/yaml-files-ai-agents/ [2] AI-Enhanced Infrastructure as Code (IaC) for Smart ... https://papers.ssrn.com/sol3/papers.cfm?abstract_id=5202062 [3] Equipping agents for the real world with Agent Skills https://www.anthropic.com/engineering/equipping-agents-for-the-real-world-with-agent-skills [4] Automating Jenkins with Configuration as Code (JCasC) https://buildkite.com/resources/blog/automating-jenkins-with-jcasc-configuration-as-code/ [5] How Can Agentic AI Revolutionize Infrastructure as Code ... https://www.getmonetizely.com/articles/how-can-agentic-ai-revolutionize-infrastructure-as-code-and-deployment-automation [6] Deep Dive on Agents Infrastructure https://www.dtcp.capital/fileadmin/DTCP/Bilder/News/202507_DTCP_Agent_Infrastructure_Preview_v1.pdf [7] Custom agents configuration - GitHub Enterprise Cloud Docs https://docs.github.com/en/enterprise-cloud@latest/copilot/reference/custom-agents-configuration [8] Configuration Management with Infrastructure as Code (IaC) https://www.linkedin.com/pulse/configuration-management-infrastructure-code-iac-ashvit--wnlsc [9] What are AI agents? https://github.com/resources/articles/what-are-ai-agents [10] Jenkins Configuration as Code https://www.jenkins.io/projects/jcasc/ [11] Deploy a Next.js Static Site to GitHub Pages - superflux https://superflux.dev/blog/github-pages-using-nextjs [12] sylvainlaurent/yaml-json-validator-maven-plugin https://github.com/sylvainlaurent/yaml-json-validator-maven-plugin [13] 12 CLI Tools That Are Redefining Developer Workflows https://www.qodo.ai/blog/best-cli-tools/ [14] Deploy Next.js on GitHub Pages - ragTech https://ragtech.hashnode.dev/ragtech-website-deploying-a-nextjs-app-on-github-pages-with-our-custom-domain [15] dsanders11/json-schema-validate-action https://github.com/dsanders11/json-schema-validate-action [16] google-gemini/gemini-cli: An open-source AI agent ... https://github.com/google-gemini/gemini-cli [17] Deploy a Next.js App to GitHub Pages https://www.youtube.com/watch?v=mJuz45RXeXY [18] YAML/JSON validation against JSON Schema · Actions https://github.com/marketplace/actions/yaml-json-validation-against-json-schema [19] Gemini CLI: your open-source AI agent https://blog.google/technology/developers/introducing-gemini-cli-open-source-ai-agent/ [20] Next.js template to deploy to GitHub Pages as a static site. https://github.com/nextjs/deploy-github-pages

Solução: Agente Nation como Código (IaC) com Next.js + GitHub Pages

1. Arquitetura Proposta

seu-repositorio/
├── .github/
│   └── workflows/
│       └── deploy.yml                 # CI/CD para GitHub Pages
├── public/
│   └── configs/                       # Arquivos de configuração público
│       ├── agent.schema.json          # JSON Schema para validação
│       └── examples/
│           └── ecommerce-agent.yaml   # Exemplo de configuração
├── src/
│   ├── components/
│   │   ├── AgentEditor.tsx            # Editor visual de config
│   │   ├── AgentPreview.tsx           # Preview da config
│   │   └── SkillsManager.tsx          # Gerenciador de skills
│   ├── lib/
│   │   ├── agent-validator.ts         # Validação YAML/JSON
│   │   ├── agent-parser.ts            # Parser de configuração
│   │   └── schema.json                # Schema interno
│   ├── pages/
│   │   ├── index.tsx                  # Homepage
│   │   ├── editor.tsx                 # Editor de agente
│   │   └── api/
│   │       └── validate.ts            # API de validação
│   └── types/
│       └── agent.ts                   # TypeScript types
├── configs/                           # Configurações de exemplo
│   ├── ecommerce-agent.yaml
│   ├── trading-agent.yaml
│   └── support-agent.yaml
├── tests/
│   ├── agent.validator.test.ts
│   └── fixtures/
│       └── valid-agent.yaml
├── scripts/
│   ├── validate-configs.ts            # Script de validação CLI
│   └── deploy-agent.ts                # Script de deploy
├── next.config.mjs
├── tsconfig.json
├── package.json
└── README.md

2. Estrutura de Configuração YAML (IaC)

Arquivo: public/configs/agent.schema.json

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "Nation Agent Configuration Schema",
  "type": "object",
  "required": ["agent", "skills", "payment"],
  "properties": {
    "agent": {
      "type": "object",
      "required": ["name", "description", "version"],
      "properties": {
        "name": {
          "type": "string",
          "minLength": 3,
          "maxLength": 50,
          "pattern": "^[a-zA-Z0-9-]+$",
          "description": "Agent name (alphanumeric and hyphens only)"
        },
        "description": {
          "type": "string",
          "minLength": 10,
          "maxLength": 500
        },
        "version": {
          "type": "string",
          "pattern": "^\\d+\\.\\d+\\.\\d+$",
          "description": "Semantic versioning (e.g., 1.0.0)"
        },
        "model": {
          "type": "object",
          "required": ["provider", "name"],
          "properties": {
            "provider": {
              "type": "string",
              "enum": ["openai", "claude", "gemini"]
            },
            "name": {
              "type": "string"
            },
            "temperature": {
              "type": "number",
              "minimum": 0,
              "maximum": 2
            },
            "max_tokens": {
              "type": "integer",
              "minimum": 100,
              "maximum": 128000
            }
          }
        },
        "system_prompt": {
          "type": "string",
          "minLength": 50,
          "description": "Core system instruction for the agent"
        }
      }
    },
    "skills": {
      "type": "array",
      "minItems": 1,
      "items": {
        "type": "object",
        "required": ["name", "type", "endpoint"],
        "properties": {
          "name": {
            "type": "string",
            "enum": ["catalog", "order", "payment", "audit", "custom"]
          },
          "type": {
            "type": "string",
            "enum": [
              "data_retrieval",
              "state_management",
              "blockchain_interaction",
              "logging"
            ]
          },
          "endpoint": {
            "type": "string",
            "format": "uri"
          },
          "method": {
            "type": "string",
            "enum": ["GET", "POST", "PUT", "DELETE"],
            "default": "GET"
          },
          "parameters": {
            "type": "array",
            "items": {
              "type": "object",
              "required": ["name", "type"],
              "properties": {
                "name": { "type": "string" },
                "type": { "type": "string" },
                "required": { "type": "boolean" },
                "description": { "type": "string" }
              }
            }
          },
          "timeout_seconds": {
            "type": "integer",
            "minimum": 5,
            "maximum": 300
          },
          "retry_policy": {
            "type": "object",
            "properties": {
              "max_attempts": { "type": "integer" },
              "backoff_multiplier": { "type": "number" }
            }
          }
        }
      }
    },
    "payment": {
      "type": "object",
      "required": ["network", "token"],
      "properties": {
        "network": {
          "type": "string",
          "enum": ["base", "base-sepolia", "solana", "solana-devnet"]
        },
        "token": {
          "type": "string",
          "enum": ["usdc", "eurc", "spl-token"]
        },
        "facilitator": {
          "type": "string",
          "enum": ["cdp", "circle", "payai"]
        },
        "agent_wallet_address": {
          "type": "string",
          "pattern": "^0x[a-fA-F0-9]{40}$"
        },
        "min_payment_usdc": {
          "type": "number",
          "minimum": 0.0001
        },
        "payment_timeout_seconds": {
          "type": "integer",
          "minimum": 30,
          "maximum": 600
        }
      }
    },
    "storage": {
      "type": "object",
      "properties": {
        "type": {
          "type": "string",
          "enum": ["memory", "postgres", "mongodb"]
        },
        "connection_string": {
          "type": "string"
        },
        "backup_enabled": {
          "type": "boolean"
        }
      }
    },
    "security": {
      "type": "object",
      "properties": {
        "encryption_enabled": {
          "type": "boolean",
          "default": true
        },
        "api_key_required": {
          "type": "boolean",
          "default": true
        },
        "rate_limit_requests_per_minute": {
          "type": "integer",
          "minimum": 1
        },
        "allowed_origins": {
          "type": "array",
          "items": { "type": "string" }
        }
      }
    },
    "monitoring": {
      "type": "object",
      "properties": {
        "enabled": {
          "type": "boolean"
        },
        "log_level": {
          "type": "string",
          "enum": ["debug", "info", "warn", "error"]
        },
        "sentry_dsn": {
          "type": "string",
          "format": "uri"
        }
      }
    }
  }
}

Arquivo: configs/ecommerce-agent.yaml

# Agent Configuration as Code (IaC)
# Version: 1.0.0
# Purpose: E-Commerce Agent with USDC Payment Processing via x402

agent:
  name: ecommerce-bot
  description: "Autonomous e-commerce agent with USDC payment processing"
  version: "1.0.0"

  model:
    provider: openai
    name: gpt-4-turbo
    temperature: 0.7
    max_tokens: 2000

  system_prompt: |
    You are an autonomous e-commerce assistant. Your responsibilities:
    1. Help customers browse products in the catalog
    2. Process orders and confirm details
    3. Handle USDC payments via x402
    4. Provide order tracking and support
    5. Maintain transaction records for auditability

    Always be professional, accurate with prices, and verify stock before confirming orders.

skills:
  # Skill 1: Product Catalog
  - name: catalog
    type: data_retrieval
    endpoint: "https://api.ecommerce-agent.example.com/api/catalog"
    method: GET
    description: "Browse and search product catalog"
    parameters:
      - name: category
        type: string
        required: false
        description: "Product category (electronics, accessories, etc)"
      - name: search
        type: string
        required: false
        description: "Search by product name"
      - name: limit
        type: integer
        required: false
        description: "Number of results (default: 20)"
    timeout_seconds: 10
    cache_seconds: 300
    retry_policy:
      max_attempts: 3
      backoff_multiplier: 2

  # Skill 2: Order Processing
  - name: order
    type: state_management
    endpoint: "https://api.ecommerce-agent.example.com/api/orders"
    method: POST
    description: "Create and manage customer orders"
    parameters:
      - name: items
        type: array
        required: true
        description: "List of products {product_id, quantity}"
      - name: delivery_address
        type: string
        required: true
        description: "Shipping address"
      - name: customer_wallet
        type: string
        required: true
        description: "Customer's USDC wallet address"
    timeout_seconds: 30
    retry_policy:
      max_attempts: 2

  # Skill 3: Payment Processing (x402)
  - name: payment
    type: blockchain_interaction
    endpoint: "https://api.ecommerce-agent.example.com/api/payment/process"
    method: POST
    description: "Process USDC payments via x402"
    parameters:
      - name: order_id
        type: string
        required: true
      - name: amount_usdc
        type: number
        required: true
      - name: payment_signature
        type: string
        required: true
        description: "USDC transfer authorization signature"
    timeout_seconds: 60
    retry_policy:
      max_attempts: 3
      backoff_multiplier: 2

  # Skill 4: Audit & Logging
  - name: audit
    type: logging
    endpoint: "https://api.ecommerce-agent.example.com/api/audit"
    method: POST
    description: "Record transactions on-chain for auditability"
    parameters:
      - name: event_type
        type: string
        required: true
        enum: ["order_created", "payment_received", "order_completed"]
      - name: order_id
        type: string
        required: true
      - name: details
        type: object
        required: false
    timeout_seconds: 20

payment:
  network: base
  token: usdc
  facilitator: cdp
  agent_wallet_address: "0x7a2Ce34542b34a08bE1aC92F58F5F8E4C9D3B4A2"
  min_payment_usdc: 0.01
  payment_timeout_seconds: 300

storage:
  type: postgres
  connection_string: "${DB_CONNECTION_STRING}"
  backup_enabled: true

security:
  encryption_enabled: true
  api_key_required: true
  rate_limit_requests_per_minute: 60
  allowed_origins:
    - "https://ecommerce.example.com"
    - "https://nation.fun"

monitoring:
  enabled: true
  log_level: info
  sentry_dsn: "${SENTRY_DSN}"

3. TypeScript Types e Validador

Arquivo: src/types/agent.ts

export interface AgentConfig {
  agent: AgentInfo;
  skills: Skill[];
  payment: PaymentConfig;
  storage?: StorageConfig;
  security?: SecurityConfig;
  monitoring?: MonitoringConfig;
}

export interface AgentInfo {
  name: string;
  description: string;
  version: string;
  model: ModelConfig;
  system_prompt: string;
}

export interface ModelConfig {
  provider: "openai" | "claude" | "gemini";
  name: string;
  temperature: number;
  max_tokens: number;
}

export interface Skill {
  name: "catalog" | "order" | "payment" | "audit" | "custom";
  type: "data_retrieval" | "state_management" | "blockchain_interaction" | "logging";
  endpoint: string;
  method: "GET" | "POST" | "PUT" | "DELETE";
  description: string;
  parameters: SkillParameter[];
  timeout_seconds: number;
  cache_seconds?: number;
  retry_policy?: RetryPolicy;
}

export interface SkillParameter {
  name: string;
  type: string;
  required: boolean;
  description?: string;
  enum?: string[];
}

export interface RetryPolicy {
  max_attempts: number;
  backoff_multiplier: number;
}

export interface PaymentConfig {
  network: "base" | "base-sepolia" | "solana" | "solana-devnet";
  token: "usdc" | "eurc" | "spl-token";
  facilitator: "cdp" | "circle" | "payai";
  agent_wallet_address: string;
  min_payment_usdc: number;
  payment_timeout_seconds: number;
}

export interface StorageConfig {
  type: "memory" | "postgres" | "mongodb";
  connection_string?: string;
  backup_enabled?: boolean;
}

export interface SecurityConfig {
  encryption_enabled: boolean;
  api_key_required: boolean;
  rate_limit_requests_per_minute: number;
  allowed_origins: string[];
}

export interface MonitoringConfig {
  enabled: boolean;
  log_level: "debug" | "info" | "warn" | "error";
  sentry_dsn?: string;
}

Arquivo: src/lib/agent-validator.ts

import Ajv, { JSONSchemaType } from "ajv";
import YAML from "js-yaml";
import { AgentConfig } from "@/types/agent";

const ajv = new Ajv({
  allErrors: true,
  verbose: true,
});

export class AgentValidator {
  private schema: any;

  constructor(schemaPath: string = "/configs/agent.schema.json") {
    // Load schema in runtime
  }

  /**
   * Validate YAML configuration against JSON Schema
   */
  validateYAML(yamlContent: string): {
    valid: boolean;
    errors: any[];
    config?: AgentConfig;
  } {
    try {
      // Parse YAML
      const config = YAML.load(yamlContent) as AgentConfig;

      // Validate against schema
      const validate = ajv.compile(this.schema);
      const valid = validate(config);

      if (!valid) {
        return {
          valid: false,
          errors: validate.errors || [],
        };
      }

      // Additional custom validations
      const customErrors = this.validateCustomRules(config);
      if (customErrors.length > 0) {
        return {
          valid: false,
          errors: customErrors,
        };
      }

      return {
        valid: true,
        errors: [],
        config,
      };
    } catch (error) {
      return {
        valid: false,
        errors: [
          {
            message: error instanceof Error ? error.message : "Unknown error",
          },
        ],
      };
    }
  }

  /**
   * Custom validation rules
   */
  private validateCustomRules(config: AgentConfig): any[] {
    const errors: any[] = [];

    // Validate that at least one skill is defined
    if (!config.skills || config.skills.length === 0) {
      errors.push({
        path: "skills",
        message: "At least one skill must be defined",
      });
    }

    // Validate skill endpoints
    config.skills?.forEach((skill, index) => {
      try {
        new URL(skill.endpoint);
      } catch {
        errors.push({
          path: `skills[${index}].endpoint`,
          message: `Invalid URL: ${skill.endpoint}`,
        });
      }
    });

    // Validate wallet address format
    if (!config.payment.agent_wallet_address.match(/^0x[a-fA-F0-9]{40}$/)) {
      errors.push({
        path: "payment.agent_wallet_address",
        message: "Invalid Ethereum wallet address",
      });
    }

    // Validate semantic versioning
    if (!config.agent.version.match(/^\d+\.\d+\.\d+$/)) {
      errors.push({
        path: "agent.version",
        message: "Version must follow semantic versioning (e.g., 1.0.0)",
      });
    }

    return errors;
  }

  /**
   * Export configuration to JSON
   */
  exportJSON(config: AgentConfig): string {
    return JSON.stringify(config, null, 2);
  }

  /**
   * Export configuration to YAML
   */
  exportYAML(config: AgentConfig): string {
    return YAML.dump(config, { indent: 2 });
  }
}

4. Componente React para Editor Visual

Arquivo: src/components/AgentEditor.tsx

"use client";

import React, { useState } from "react";
import { AgentConfig } from "@/types/agent";
import { AgentValidator } from "@/lib/agent-validator";
import YAML from "js-yaml";

export default function AgentEditor() {
  const [yamlContent, setYamlContent] = useState<string>("");
  const [validationResult, setValidationResult] = useState<any>(null);
  const [activeTab, setActiveTab] = useState<"editor" | "preview">("editor");

  const validator = new AgentValidator();

  const handleValidate = () => {
    const result = validator.validateYAML(yamlContent);
    setValidationResult(result);
  };

  const handleLoadExample = async () => {
    try {
      const response = await fetch("/configs/ecommerce-agent.yaml");
      const text = await response.text();
      setYamlContent(text);
    } catch (error) {
      alert("Failed to load example configuration");
    }
  };

  const handleExport = (format: "yaml" | "json") => {
    if (!validationResult?.valid) {
      alert("Please fix validation errors first");
      return;
    }

    let content: string;
    let filename: string;

    if (format === "yaml") {
      content = validator.exportYAML(validationResult.config);
      filename = "agent-config.yaml";
    } else {
      content = validator.exportJSON(validationResult.config);
      filename = "agent-config.json";
    }

    // Download file
    const blob = new Blob([content], { type: "text/plain" });
    const url = window.URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.href = url;
    a.download = filename;
    a.click();
  };

  return (
    <div className="agent-editor">
      <div className="editor-header">
        <h1>🤖 Nation Agent Configuration Editor</h1>
        <div className="header-buttons">
          <button onClick={handleLoadExample} className="btn-secondary">
            📋 Load Example
          </button>
          <button onClick={handleValidate} className="btn-primary">
            ✓ Validate
          </button>
        </div>
      </div>

      <div className="editor-tabs">
        <button
          className={`tab ${activeTab === "editor" ? "active" : ""}`}
          onClick={() => setActiveTab("editor")}
        >
          Code Editor
        </button>
        <button
          className={`tab ${activeTab === "preview" ? "active" : ""}`}
          onClick={() => setActiveTab("preview")}
        >
          Preview
        </button>
      </div>

      <div className="editor-container">
        {activeTab === "editor" ? (
          <textarea
            className="yaml-editor"
            value={yamlContent}
            onChange={(e) => setYamlContent(e.target.value)}
            placeholder="Paste your YAML configuration here..."
          />
        ) : (
          <div className="preview-pane">
            {validationResult?.valid ? (
              <div className="preview-content">
                <div className="success-banner">
                  ✓ Configuration is valid!
                </div>
                <pre>
                  {JSON.stringify(validationResult?.config, null, 2)}
                </pre>
              </div>
            ) : (
              <div className="preview-message">
                Validate your configuration to see the preview
              </div>
            )}
          </div>
        )}
      </div>

      {validationResult && (
        <div className="validation-results">
          {validationResult.valid ? (
            <div className="success">
              <h3>✓ Validation Passed!</h3>
              <div className="export-buttons">
                <button
                  onClick={() => handleExport("yaml")}
                  className="btn-secondary"
                >
                  📥 Export as YAML
                </button>
                <button
                  onClick={() => handleExport("json")}
                  className="btn-secondary"
                >
                  📥 Export as JSON
                </button>
              </div>
            </div>
          ) : (
            <div className="errors">
              <h3>✗ Validation Errors ({validationResult.errors.length})</h3>
              <ul>
                {validationResult.errors.map((error: any, idx: number) => (
                  <li key={idx}>
                    <strong>{error.path || "root"}:</strong> {error.message}
                  </li>
                ))}
              </ul>
            </div>
          )}
        </div>
      )}

      <style jsx>{`
        .agent-editor {
          max-width: 1200px;
          margin: 0 auto;
          padding: 20px;
        }

        .editor-header {
          display: flex;
          justify-content: space-between;
          align-items: center;
          margin-bottom: 20px;
          padding: 20px;
          background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
          border-radius: 8px;
          color: white;
        }

        .header-buttons {
          display: flex;
          gap: 10px;
        }

        .editor-tabs {
          display: flex;
          border-bottom: 2px solid #e0e0e0;
          margin-bottom: 20px;
        }

        .tab {
          padding: 10px 20px;
          background: none;
          border: none;
          cursor: pointer;
          border-bottom: 3px solid transparent;
          font-weight: 500;
          transition: all 0.3s;
        }

        .tab.active {
          border-bottom-color: #667eea;
          color: #667eea;
        }

        .editor-container {
          background: #f5f5f5;
          border: 1px solid #ddd;
          border-radius: 8px;
          height: 500px;
          margin-bottom: 20px;
        }

        .yaml-editor {
          width: 100%;
          height: 100%;
          font-family: "Courier New", monospace;
          padding: 15px;
          border: none;
          border-radius: 8px;
          resize: none;
        }

        .validation-results {
          background: white;
          border-radius: 8px;
          padding: 20px;
          margin-top: 20px;
        }

        .success {
          background: #d4edda;
          border: 1px solid #c3e6cb;
          color: #155724;
          padding: 15px;
          border-radius: 8px;
        }

        .errors {
          background: #f8d7da;
          border: 1px solid #f5c6cb;
          color: #721c24;
          padding: 15px;
          border-radius: 8px;
        }

        .btn-primary,
        .btn-secondary {
          padding: 10px 20px;
          border: none;
          border-radius: 6px;
          cursor: pointer;
          font-weight: 600;
          transition: all 0.3s;
        }

        .btn-primary {
          background: white;
          color: #667eea;
        }

        .btn-secondary {
          background: #667eea;
          color: white;
        }
      `}</style>
    </div>
  );
}

5. Script CLI para Validação

Arquivo: scripts/validate-configs.ts

#!/usr/bin/env node

import fs from "fs";
import path from "path";
import YAML from "js-yaml";
import Ajv from "ajv";

const ajv = new Ajv();

async function validateConfigs() {
  const configDir = path.join(__dirname, "../configs");
  const schemaPath = path.join(__dirname, "../public/configs/agent.schema.json");

  // Load schema
  const schema = JSON.parse(fs.readFileSync(schemaPath, "utf-8"));
  const validate = ajv.compile(schema);

  // Get all YAML files
  const files = fs
    .readdirSync(configDir)
    .filter((f) => f.endsWith(".yaml") || f.endsWith(".yml"));

  let passedCount = 0;
  let failedCount = 0;

  console.log(`\n🔍 Validating ${files.length} configuration files...\n`);

  for (const file of files) {
    const filePath = path.join(configDir, file);
    console.log(`📄 ${file}...`);

    try {
      const content = fs.readFileSync(filePath, "utf-8");
      const config = YAML.load(content);

      const valid = validate(config);

      if (valid) {
        console.log(`   ✓ Valid\n`);
        passedCount++;
      } else {
        console.log(`   ✗ Invalid`);
        validate.errors?.forEach((err) => {
          console.log(`     - ${err.schemaPath}: ${err.message}`);
        });
        console.log("");
        failedCount++;
      }
    } catch (error) {
      console.log(`   ✗ Error: ${error}\n`);
      failedCount++;
    }
  }

  console.log(`\n📊 Results: ${passedCount} passed, ${failedCount} failed`);
  process.exit(failedCount > 0 ? 1 : 0);
}

validateConfigs();

6. GitHub Actions Workflow

Arquivo: .github/workflows/validate-and-deploy.yml

name: Validate Configs & Deploy

on:
  push:
    branches: [main]
    paths:
      - "configs/**"
      - "src/**"
      - "package.json"
  pull_request:
    branches: [main]

jobs:
  validate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: "20"
          cache: "npm"

      - name: Install dependencies
        run: npm ci

      - name: Validate configurations
        run: npm run validate:configs

      - name: Run tests
        run: npm run test

      - name: Lint code
        run: npm run lint

  build-and-deploy:
    needs: validate
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'
    permissions:
      contents: read
      pages: write
      id-token: write

    steps:
      - uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: "20"
          cache: "npm"

      - name: Install dependencies
        run: npm ci

      - name: Build Next.js site
        run: npm run build

      - name: Setup Pages
        uses: actions/configure-pages@v4

      - name: Upload artifact
        uses: actions/upload-pages-artifact@v3
        with:
          path: ./out

      - name: Deploy to GitHub Pages
        id: deployment
        uses: actions/deploy-pages@v3

7. Package.json Scripts

Arquivo: package.json (scripts section)

{
  "scripts": {
    "dev": "next dev",
    "build": "next build && next export",
    "start": "next start",
    "lint": "eslint .",
    "type-check": "tsc --noEmit",
    "test": "jest",
    "test:watch": "jest --watch",
    "validate:configs": "ts-node scripts/validate-configs.ts",
    "validate:config": "ts-node scripts/validate-single-config.ts",
    "deploy:agent": "ts-node scripts/deploy-agent.ts"
  },
  "devDependencies": {
    "@types/js-yaml": "^4.0.9",
    "@types/node": "^20.0.0",
    "@types/react": "^18.0.0",
    "ajv": "^8.12.0",
    "eslint": "^8.40.0",
    "jest": "^29.5.0",
    "js-yaml": "^4.1.0",
    "next": "^14.0.0",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "ts-node": "^10.9.1",
    "typescript": "^5.0.0"
  }
}

8. Exemplo de Teste Unitário

Arquivo: tests/agent.validator.test.ts

import { AgentValidator } from "@/lib/agent-validator";
import fs from "fs";

describe("AgentValidator", () => {
  let validator: AgentValidator;

  beforeAll(() => {
    validator = new AgentValidator();
  });

  it("should validate a correct YAML configuration", () => {
    const yaml = fs.readFileSync(
      "configs/ecommerce-agent.yaml",
      "utf-8"
    );
    const result = validator.validateYAML(yaml);
    expect(result.valid).toBe(true);
    expect(result.errors.length).toBe(0);
  });

  it("should reject invalid wallet address", () => {
    const yaml = `
agent:
  name: test-agent
  description: Test agent
  version: 1.0.0
  model:
    provider: openai
    name: gpt-4
    temperature: 0.7
    max_tokens: 2000
  system_prompt: Test prompt

skills:
  - name: catalog
    type: data_retrieval
    endpoint: https://example.com/api/catalog
    method: GET
    parameters: []
    timeout_seconds: 10

payment:
  network: base
  token: usdc
  facilitator: cdp
  agent_wallet_address: "invalid-address"
  min_payment_usdc: 0.01
  payment_timeout_seconds: 300
`;
    const result = validator.validateYAML(yaml);
    expect(result.valid).toBe(false);
  });

  it("should export configuration as JSON", () => {
    const yaml = fs.readFileSync(
      "configs/ecommerce-agent.yaml",
      "utf-8"
    );
    const result = validator.validateYAML(yaml);
    if (result.valid && result.config) {
      const json = validator.exportJSON(result.config);
      expect(() => JSON.parse(json)).not.toThrow();
    }
  });
});

9. Instruções de Uso

Passo 1: Clonar e Instalar

git clone seu-repositorio
cd seu-repositorio
npm install

Passo 2: Desenvolver Localmente

npm run dev
# Abre em http://localhost:3000

Passo 3: Criar Configuração de Agente

Copie configs/ecommerce-agent.yaml e customize:

cp configs/ecommerce-agent.yaml configs/meu-agente.yaml
# Edite meu-agente.yaml com suas especificações

Passo 4: Validar Localmente

npm run validate:configs

Passo 5: Fazer Commit

git add configs/meu-agente.yaml
git commit -m "feat: add meu-agente configuration"
git push origin main

Passo 6: Deploy Automático

GitHub Actions valida automaticamente: - ✓ Syntax YAML - ✓ JSON Schema compliance - ✓ Custom rules - ✓ Builds e deploys no GitHub Pages


10. Vantagens dessa Arquitetura

Aspecto Benefício
Versionamento Histórico completo no Git
Colaboração Pull Requests para validar mudanças
Validação Automated checks antes de deploy
Reprodutibilidade Mesmo setup em qualquer ambiente
Documentation YAML é auto-documentado
CI/CD Deployment automático com GitHub Actions
Escalabilidade Gerenciar múltiplos agentes facilmente
Auditoria Rastreabilidade completa de mudanças