diff --git a/.gitignore b/.gitignore
index c051b64ff..cc9c7fb1c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,69 +1,43 @@
```
-# Build artifacts
+# Go build artifacts
*.o
-*.obj
-*.out
-*.so
-*.dll
-*.exe
*.a
-*.dylib
-
-# Go-specific
+*.out
*.test
-*.prof
-cover.out
-coverage.txt
+*_test.go
# Dependencies
vendor/
-# Logs
+# Logs and temp files
*.log
-
-# Temporary files
*.tmp
-*~
-.DS_Store
-Thumbs.db
# Environment
.env
.env.local
*.env.*
-# Coverage
-coverage/
-htmlcov/
-.coverage
-
# Editors
.vscode/
.idea/
*.swp
*.swo
-# Archives
-*.zip
-*.gz
-*.tar
-*.tgz
-*.bz2
-*.xz
-*.7z
-*.rar
-*.zst
-*.lz4
-*.lzh
-*.cab
-*.arj
-*.rpm
-*.deb
-*.Z
-*.lz
-*.lzo
-*.tar.gz
-*.tar.bz2
-*.tar.xz
-*.tar.zst
+# Coverage
+coverage/
+htmlcov/
+.coverage
+
+# Build directories
+build/
+dist/
+target/
+
+# Python artifacts (if any Python files exist)
+__pycache__/
+*.pyc
+*.pyo
+*.pyd
+.Python
```
\ No newline at end of file
diff --git a/cmd/protoagent-cli/README.md b/cmd/protoagent-cli/README.md
new file mode 100644
index 000000000..f81838534
--- /dev/null
+++ b/cmd/protoagent-cli/README.md
@@ -0,0 +1,90 @@
+# ProtoAgent CLI
+
+Interface de linha de comando para o ProtoAgent - ferramenta de prototipagem de comportamentos.
+
+## Estrutura
+
+```
+cmd/protoagent-cli/
+└── main.go # CLI completa com comandos generate, validate, version e help
+```
+
+## Comandos
+
+### generate
+
+Gera artefatos a partir de um arquivo de requisitos JSON.
+
+```bash
+protoagent-cli generate requirements.json [opções]
+```
+
+**Opções:**
+- `-o, --output
` - Diretório de saída (padrão: ./output)
+- `-w, --workspace ` - Diretório do workspace (padrão: .)
+- `--opa` - Habilitar geração de políticas OPA
+- `--ai` - Habilitar geração assistida por IA
+- `--dry-run` - Preview sem escrever arquivos
+- `-v, --verbose` - Output detalhado
+
+### validate
+
+Valida um arquivo de requisitos.
+
+```bash
+protoagent-cli validate requirements.json
+```
+
+### version
+
+Mostra informações de versão.
+
+```bash
+protoagent-cli version
+```
+
+### help
+
+Mostra ajuda detalhada.
+
+```bash
+protoagent-cli help
+```
+
+## Exemplos
+
+```bash
+# Gerar artefatos com políticas OPA
+protoagent-cli generate travel-experience-platform.json -o ./output --opa --verbose
+
+# Validar requisitos
+protoagent-cli validate cafeteria-loyalty-system.json
+
+# Dry run (preview)
+protoagent-cli generate requirements.json --dry-run --verbose
+```
+
+## Artefatos Gerados
+
+O CLI gera os seguintes arquivos no diretório de saída:
+
+- `AGENT.json` / `AGENT.md` - Configuração do agente
+- `schema_*.json` / `schema_*.sql` - Schemas de banco de dados
+- `policy_*.rego.json` / `policy_*.rego` - Políticas OPA
+- `interfaces.json` - Definições de interfaces
+- `channels.json` - Configurações de canais
+- `skills.json` / `skill_*.go` - Skills geradas
+- `tools.json` - Tools configuradas
+- `mcp_config.json` - Configuração MCP
+- `validation_report.json` - Relatório de validação
+
+## Requisitos
+
+- Go 1.21+ (para suporte a log/slog e slices)
+- Arquivo de requisitos em formato JSON
+
+## Build
+
+```bash
+go build -o protoagent-cli ./cmd/protoagent-cli
+```
diff --git a/cmd/protoagent-cli/main.go b/cmd/protoagent-cli/main.go
new file mode 100644
index 000000000..2075dfc77
--- /dev/null
+++ b/cmd/protoagent-cli/main.go
@@ -0,0 +1,500 @@
+// Package main provides the CLI for protoagent.
+// This CLI tool allows users to generate agent artifacts from requirements via command line.
+package main
+
+import (
+ "context"
+ "encoding/json"
+ "fmt"
+ "os"
+ "path/filepath"
+ "strings"
+ "time"
+
+ "github.com/sipeed/picoclaw/pkg/protoagent"
+)
+
+func main() {
+ if len(os.Args) < 2 {
+ printUsage()
+ os.Exit(1)
+ }
+
+ command := os.Args[1]
+
+ switch command {
+ case "generate":
+ runGenerate(os.Args[2:])
+ case "validate":
+ runValidate(os.Args[2:])
+ case "version":
+ printVersion()
+ case "help", "-h", "--help":
+ printUsage()
+ default:
+ fmt.Fprintf(os.Stderr, "Unknown command: %s\n", command)
+ printUsage()
+ os.Exit(1)
+ }
+}
+
+func printUsage() {
+ fmt.Println(`ProtoAgent CLI - Generate agent artifacts from requirements
+
+Usage:
+ protoagent-cli [options]
+
+Commands:
+ generate Generate artifacts from requirements file
+ validate Validate a requirements file
+ version Show version information
+ help Show this help message
+
+Generate Options:
+ protoagent-cli generate [options]
+ -o, --output Output directory (default: ./output)
+ -w, --workspace Workspace directory (default: .)
+ --opa Enable OPA policy generation
+ --ai Enable AI-assisted generation
+ --dry-run Preview without writing files
+ -v, --verbose Verbose output
+
+Validate Options:
+ protoagent-cli validate
+
+Examples:
+ protoagent-cli generate requirements.json -o ./output --opa
+ protoagent-cli validate requirements.json
+ protoagent-cli generate travel-experience-platform.json --verbose
+`)
+}
+
+func printVersion() {
+ fmt.Println("protoagent-cli version 0.1.0")
+}
+
+func runGenerate(args []string) {
+ if len(args) == 0 {
+ fmt.Fprintln(os.Stderr, "Error: Requirements file is required")
+ fmt.Fprintln(os.Stderr, "Usage: protoagent-cli generate [options]")
+ os.Exit(1)
+ }
+
+ reqFile := args[0]
+ outputDir := "./output"
+ workspace := "."
+ enableOPA := false
+ enableAI := false
+ dryRun := false
+ verbose := false
+
+ // Parse arguments
+ for i := 1; i < len(args); i++ {
+ switch args[i] {
+ case "-o", "--output":
+ if i+1 < len(args) {
+ outputDir = args[i+1]
+ i++
+ }
+ case "-w", "--workspace":
+ if i+1 < len(args) {
+ workspace = args[i+1]
+ i++
+ }
+ case "--opa":
+ enableOPA = true
+ case "--ai":
+ enableAI = true
+ case "--dry-run":
+ dryRun = true
+ case "-v", "--verbose":
+ verbose = true
+ }
+ }
+
+ if verbose {
+ fmt.Printf("📄 Reading requirements from: %s\n", reqFile)
+ }
+
+ // Load requirements
+ reqs, err := loadRequirements(reqFile)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "Error loading requirements: %v\n", err)
+ os.Exit(1)
+ }
+
+ if verbose {
+ fmt.Printf("📋 Loaded %d functional requirements and %d non-functional requirements\n",
+ len(reqs.FunctionalRequirements), len(reqs.NonFunctionalRequirements))
+ }
+
+ // Configure engine
+ config := protoagent.EngineConfig{
+ OutputDir: outputDir,
+ Workspace: workspace,
+ EnableOPA: enableOPA,
+ EnableAI: enableAI,
+ DryRun: dryRun,
+ Verbose: verbose,
+ }
+
+ engine := protoagent.NewEngine(config)
+
+ if verbose {
+ fmt.Println("🚀 Processing requirements...")
+ }
+
+ // Process requirements
+ ctx := context.Background()
+ artifacts, err := engine.ProcessRequirements(ctx, reqs)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "Error processing requirements: %v\n", err)
+ os.Exit(1)
+ }
+
+ if dryRun {
+ fmt.Println("🔍 Dry run mode - no files written")
+ printArtifactsSummary(artifacts)
+ return
+ }
+
+ // Save artifacts
+ if err := saveArtifacts(artifacts, outputDir, verbose); err != nil {
+ fmt.Fprintf(os.Stderr, "Error saving artifacts: %v\n", err)
+ os.Exit(1)
+ }
+
+ if verbose {
+ printArtifactsSummary(artifacts)
+ }
+
+ fmt.Println("\n✅ Artifacts generated successfully!")
+}
+
+func runValidate(args []string) {
+ if len(args) == 0 {
+ fmt.Fprintln(os.Stderr, "Error: Requirements file is required")
+ fmt.Fprintln(os.Stderr, "Usage: protoagent-cli validate ")
+ os.Exit(1)
+ }
+
+ reqFile := args[0]
+
+ // Load requirements
+ reqs, err := loadRequirements(reqFile)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "Error loading requirements: %v\n", err)
+ os.Exit(1)
+ }
+
+ // Create a minimal engine for validation
+ config := protoagent.EngineConfig{
+ DryRun: true,
+ Verbose: true,
+ }
+ engine := protoagent.NewEngine(config)
+
+ ctx := context.Background()
+ _, err = engine.ProcessRequirements(ctx, reqs)
+
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "❌ Validation failed: %v\n", err)
+ os.Exit(1)
+ }
+
+ fmt.Println("✅ Requirements validation passed!")
+}
+
+func loadRequirements(filename string) (*protoagent.RequirementsDocument, error) {
+ data, err := os.ReadFile(filename)
+ if err != nil {
+ return nil, fmt.Errorf("failed to read file: %w", err)
+ }
+
+ var reqs protoagent.RequirementsDocument
+
+ // Try JSON first
+ if err := json.Unmarshal(data, &reqs); err == nil {
+ return &reqs, nil
+ }
+
+ // Try YAML if JSON fails
+ // Note: YAML support would require adding gopkg.in/yaml.v3 dependency
+ return nil, fmt.Errorf("failed to parse requirements file (JSON format expected)")
+}
+
+func saveArtifacts(artifacts *protoagent.GeneratedArtifacts, outputDir string, verbose bool) error {
+ // Create output directory
+ if err := os.MkdirAll(outputDir, 0755); err != nil {
+ return fmt.Errorf("failed to create output directory: %w", err)
+ }
+
+ // Save AGENT.md
+ if artifacts.AgentConfig != nil {
+ agentJSON, _ := json.MarshalIndent(artifacts.AgentConfig, "", " ")
+ if err := os.WriteFile(filepath.Join(outputDir, "AGENT.json"), agentJSON, 0644); err != nil {
+ return fmt.Errorf("failed to save AGENT.json: %w", err)
+ }
+
+ agentMD := fmt.Sprintf("# %s Agent\n\n%s\n", artifacts.AgentConfig.Name, artifacts.AgentConfig.Body)
+ if err := os.WriteFile(filepath.Join(outputDir, "AGENT.md"), []byte(agentMD), 0644); err != nil {
+ return fmt.Errorf("failed to save AGENT.md: %w", err)
+ }
+
+ if verbose {
+ fmt.Println("📄 AGENT.json and AGENT.md saved")
+ }
+ }
+
+ // Save database schemas
+ for i, schema := range artifacts.DatabaseSchemas {
+ schemaJSON, _ := json.MarshalIndent(schema, "", " ")
+ filename := filepath.Join(outputDir, fmt.Sprintf("schema_%d_%s.json", i, sanitizeName(schema.Name)))
+ if err := os.WriteFile(filename, schemaJSON, 0644); err != nil {
+ return fmt.Errorf("failed to save schema: %w", err)
+ }
+
+ // Generate SQL DDL for SQL schemas
+ if schema.Type == "sql" && len(schema.Tables) > 0 {
+ sqlDDL := generateSQLDDL(schema)
+ sqlFilename := filepath.Join(outputDir, fmt.Sprintf("schema_%d_%s.sql", i, sanitizeName(schema.Name)))
+ if err := os.WriteFile(sqlFilename, []byte(sqlDDL), 0644); err != nil {
+ return fmt.Errorf("failed to save SQL: %w", err)
+ }
+ if verbose {
+ fmt.Printf("📄 Schema %s saved (JSON + SQL)\n", schema.Name)
+ }
+ } else if verbose {
+ fmt.Printf("📄 Schema %s saved\n", schema.Name)
+ }
+ }
+
+ // Save OPA policies
+ for i, policy := range artifacts.Policies {
+ policyJSON, _ := json.MarshalIndent(policy, "", " ")
+ filename := filepath.Join(outputDir, fmt.Sprintf("policy_%d_%s.rego.json", i, sanitizeName(policy.Name)))
+ if err := os.WriteFile(filename, policyJSON, 0644); err != nil {
+ return fmt.Errorf("failed to save policy: %w", err)
+ }
+
+ // Save pure Rego code
+ regoFilename := filepath.Join(outputDir, fmt.Sprintf("policy_%d_%s.rego", i, sanitizeName(policy.Name)))
+ if err := os.WriteFile(regoFilename, []byte(policy.Rego), 0644); err != nil {
+ return fmt.Errorf("failed to save rego: %w", err)
+ }
+
+ if verbose {
+ fmt.Printf("📄 Policy %s saved (JSON + Rego)\n", policy.Name)
+ }
+ }
+
+ // Save interfaces
+ if len(artifacts.Interfaces) > 0 {
+ interfacesJSON, _ := json.MarshalIndent(artifacts.Interfaces, "", " ")
+ if err := os.WriteFile(filepath.Join(outputDir, "interfaces.json"), interfacesJSON, 0644); err != nil {
+ return fmt.Errorf("failed to save interfaces: %w", err)
+ }
+ if verbose {
+ fmt.Println("📄 interfaces.json saved")
+ }
+ }
+
+ // Save channels
+ if len(artifacts.Channels) > 0 {
+ channelsJSON, _ := json.MarshalIndent(artifacts.Channels, "", " ")
+ if err := os.WriteFile(filepath.Join(outputDir, "channels.json"), channelsJSON, 0644); err != nil {
+ return fmt.Errorf("failed to save channels: %w", err)
+ }
+ if verbose {
+ fmt.Println("📄 channels.json saved")
+ }
+ }
+
+ // Save skills
+ if len(artifacts.Skills) > 0 {
+ skillsJSON, _ := json.MarshalIndent(artifacts.Skills, "", " ")
+ if err := os.WriteFile(filepath.Join(outputDir, "skills.json"), skillsJSON, 0644); err != nil {
+ return fmt.Errorf("failed to save skills: %w", err)
+ }
+
+ // Save each skill's code
+ for i, skill := range artifacts.Skills {
+ skillFile := filepath.Join(outputDir, fmt.Sprintf("skill_%d_%s.go", i, sanitizeName(skill.Name)))
+ if err := os.WriteFile(skillFile, []byte(skill.Code), 0644); err != nil {
+ return fmt.Errorf("failed to save skill code: %w", err)
+ }
+ }
+
+ if verbose {
+ fmt.Println("📄 skills.json and skill codes saved")
+ }
+ }
+
+ // Save tools
+ if len(artifacts.Tools) > 0 {
+ toolsJSON, _ := json.MarshalIndent(artifacts.Tools, "", " ")
+ if err := os.WriteFile(filepath.Join(outputDir, "tools.json"), toolsJSON, 0644); err != nil {
+ return fmt.Errorf("failed to save tools: %w", err)
+ }
+ if verbose {
+ fmt.Println("📄 tools.json saved")
+ }
+ }
+
+ // Save MCP configuration
+ if artifacts.MCPConfig != nil && len(artifacts.MCPConfig.Servers) > 0 {
+ mcpJSON, _ := json.MarshalIndent(artifacts.MCPConfig, "", " ")
+ if err := os.WriteFile(filepath.Join(outputDir, "mcp_config.json"), mcpJSON, 0644); err != nil {
+ return fmt.Errorf("failed to save mcp_config: %w", err)
+ }
+ if verbose {
+ fmt.Println("📄 mcp_config.json saved")
+ }
+ }
+
+ // Save validation report
+ if artifacts.ValidationReport != nil {
+ reportJSON, _ := json.MarshalIndent(artifacts.ValidationReport, "", " ")
+ if err := os.WriteFile(filepath.Join(outputDir, "validation_report.json"), reportJSON, 0644); err != nil {
+ return fmt.Errorf("failed to save validation report: %w", err)
+ }
+ if verbose {
+ fmt.Println("📄 validation_report.json saved")
+ }
+ }
+
+ return nil
+}
+
+func printArtifactsSummary(artifacts *protoagent.GeneratedArtifacts) {
+ fmt.Println("\n📦 Generated Artifacts Summary:")
+ fmt.Println(strings.Repeat("=", 50))
+
+ if artifacts.AgentConfig != nil {
+ fmt.Printf("🤖 Agent: %s\n", artifacts.AgentConfig.Name)
+ fmt.Printf(" Description: %s\n", artifacts.AgentConfig.Description)
+ fmt.Printf(" Tools: %v\n", artifacts.AgentConfig.Tools)
+ fmt.Printf(" Skills: %v\n", artifacts.AgentConfig.Skills)
+ }
+
+ if len(artifacts.DatabaseSchemas) > 0 {
+ fmt.Printf("\n💾 Database Schemas: %d\n", len(artifacts.DatabaseSchemas))
+ for _, schema := range artifacts.DatabaseSchemas {
+ fmt.Printf(" - %s (%s)\n", schema.Name, schema.Type)
+ if len(schema.Tables) > 0 {
+ for _, table := range schema.Tables {
+ fmt.Printf(" Table: %s (%d columns)\n", table.Name, len(table.Columns))
+ }
+ }
+ }
+ }
+
+ if len(artifacts.Interfaces) > 0 {
+ fmt.Printf("\n🖥️ Interfaces: %d\n", len(artifacts.Interfaces))
+ for _, iface := range artifacts.Interfaces {
+ fmt.Printf(" - %s (%s)\n", iface.Name, iface.Type)
+ if iface.Type == "api" && len(iface.Endpoints) > 0 {
+ fmt.Printf(" Endpoints: %d\n", len(iface.Endpoints))
+ }
+ if iface.Type == "web" && len(iface.Screens) > 0 {
+ fmt.Printf(" Screens: %d\n", len(iface.Screens))
+ }
+ }
+ }
+
+ if len(artifacts.Channels) > 0 {
+ fmt.Printf("\n📱 Communication Channels: %d\n", len(artifacts.Channels))
+ for _, channel := range artifacts.Channels {
+ fmt.Printf(" - %s (%s) - Enabled: %v\n", channel.Name, channel.Type, channel.Enabled)
+ }
+ }
+
+ if len(artifacts.Policies) > 0 {
+ fmt.Printf("\n🔐 OPA Policies: %d\n", len(artifacts.Policies))
+ for _, policy := range artifacts.Policies {
+ fmt.Printf(" - %s (%s)\n", policy.Name, policy.Package)
+ }
+ }
+
+ if len(artifacts.Skills) > 0 {
+ fmt.Printf("\n🎯 Skills: %d\n", len(artifacts.Skills))
+ for _, skill := range artifacts.Skills {
+ fmt.Printf(" - %s\n", skill.Name)
+ }
+ }
+
+ if len(artifacts.Tools) > 0 {
+ fmt.Printf("\n🔧 Tools: %d\n", len(artifacts.Tools))
+ for _, tool := range artifacts.Tools {
+ fmt.Printf(" - %s (%s)\n", tool.Name, tool.Type)
+ }
+ }
+
+ if artifacts.MCPConfig != nil && len(artifacts.MCPConfig.Servers) > 0 {
+ fmt.Printf("\n🔌 MCP Servers: %d\n", len(artifacts.MCPConfig.Servers))
+ for _, server := range artifacts.MCPConfig.Servers {
+ fmt.Printf(" - %s (%s)\n", server.Name, server.Type)
+ }
+ }
+
+ if artifacts.ValidationReport != nil {
+ fmt.Printf("\n✅ Validation: %v\n", artifacts.ValidationReport.Valid)
+ if len(artifacts.ValidationReport.Errors) > 0 {
+ fmt.Printf(" ❌ Errors: %d\n", len(artifacts.ValidationReport.Errors))
+ }
+ if len(artifacts.ValidationReport.Warnings) > 0 {
+ fmt.Printf(" ⚠️ Warnings: %d\n", len(artifacts.ValidationReport.Warnings))
+ }
+ if len(artifacts.ValidationReport.Suggestions) > 0 {
+ fmt.Printf(" 💡 Suggestions: %d\n", len(artifacts.ValidationReport.Suggestions))
+ }
+ }
+}
+
+func generateSQLDDL(schema protoagent.DatabaseSchema) string {
+ var ddl strings.Builder
+ ddl.WriteString(fmt.Sprintf("-- Schema: %s\n", schema.Name))
+ ddl.WriteString(fmt.Sprintf("-- Type: %s\n\n", schema.Type))
+
+ for _, table := range schema.Tables {
+ ddl.WriteString(fmt.Sprintf("CREATE TABLE IF NOT EXISTS %s (\n", table.Name))
+
+ columns := make([]string, 0, len(table.Columns))
+ for _, col := range table.Columns {
+ colDef := fmt.Sprintf(" %s %s", col.Name, col.Type)
+ if col.PrimaryKey {
+ colDef += " PRIMARY KEY"
+ }
+ if !col.Nullable {
+ colDef += " NOT NULL"
+ }
+ if col.Unique {
+ colDef += " UNIQUE"
+ }
+ if col.Default != "" {
+ colDef += fmt.Sprintf(" DEFAULT %s", col.Default)
+ }
+ columns = append(columns, colDef)
+ }
+
+ ddl.WriteString(strings.Join(columns, ",\n"))
+ ddl.WriteString("\n);\n\n")
+
+ // Create indexes
+ for _, idx := range table.Indexes {
+ ddl.WriteString(fmt.Sprintf("CREATE INDEX ON %s (%s);\n", table.Name, idx))
+ }
+ }
+
+ return ddl.String()
+}
+
+func sanitizeName(name string) string {
+ // Replace invalid filename characters with underscores
+ result := strings.ReplaceAll(name, " ", "_")
+ result = strings.ReplaceAll(result, "-", "_")
+ result = strings.ToLower(result)
+ return result
+}
+
+var _ = time.Now // Avoid unused import error
diff --git a/go.mod b/go.mod
index d1328e215..d2747b3e7 100644
--- a/go.mod
+++ b/go.mod
@@ -139,7 +139,7 @@ require (
golang.org/x/crypto v0.49.0
golang.org/x/net v0.52.0
golang.org/x/sync v0.20.0
- golang.org/x/sys v0.15.0
+ golang.org/x/sys v0.42.0
)
replace github.com/bwmarrin/discordgo => github.com/yeongaori/discordgo-fork v0.0.0-20260319072544-e8e546f5d532
diff --git a/go.sum b/go.sum
index 8306976c4..90b0d771f 100644
--- a/go.sum
+++ b/go.sum
@@ -199,10 +199,10 @@ github.com/mdp/qrterminal/v3 v3.2.1 h1:6+yQjiiOsSuXT5n9/m60E54vdgFsw0zhADHhHLrFe
github.com/mdp/qrterminal/v3 v3.2.1/go.mod h1:jOTmXvnBsMy5xqLniO0R++Jmjs2sTm9dFSuQ5kpz/SU=
github.com/minio/selfupdate v0.6.0 h1:i76PgT0K5xO9+hjzKcacQtO7+MjJ4JKA8Ak8XQ9DDwU=
github.com/minio/selfupdate v0.6.0/go.mod h1:bO02GTIPCMQFTEvE5h4DjYB58bCoZ35XLeBf0buTDdM=
-github.com/muesli/termenv v0.16.0 h1:S5AlUN9dENB57rsbnkPyfdGuWIlkmzJjbFf0Tf5FWUc=
-github.com/muesli/termenv v0.16.0/go.mod h1:ZRfOIKPFDYQoDFF4Olj7/QJbW60Ol/kL1pU3VfY/Cnk=
github.com/modelcontextprotocol/go-sdk v1.5.0 h1:CHU0FIX9kpueNkxuYtfYQn1Z0slhFzBZuq+x6IiblIU=
github.com/modelcontextprotocol/go-sdk v1.5.0/go.mod h1:gggDIhoemhWs3BGkGwd1umzEXCEMMvAnhTrnbXJKKKA=
+github.com/muesli/termenv v0.16.0 h1:S5AlUN9dENB57rsbnkPyfdGuWIlkmzJjbFf0Tf5FWUc=
+github.com/muesli/termenv v0.16.0/go.mod h1:ZRfOIKPFDYQoDFF4Olj7/QJbW60Ol/kL1pU3VfY/Cnk=
github.com/mymmrac/telego v1.8.0 h1:EvIprWo9Cn0MHgumvvqNXPAXO1yJj3pu2cdCCeDxbow=
github.com/mymmrac/telego v1.8.0/go.mod h1:pdLV346EgVuq7Xrh3kMggeBiazeHhsdEoK0RTEOPXRM=
github.com/ncruces/go-strftime v1.0.0 h1:HMFp8mLCTPp341M/ZnA4qaf7ZlsbTc+miZjCLOFAw7w=
@@ -293,12 +293,12 @@ github.com/valyala/fastjson v1.6.10 h1:/yjJg8jaVQdYR3arGxPE2X5z89xrlhS0eGXdv+ADT
github.com/valyala/fastjson v1.6.10/go.mod h1:e6FubmQouUNP73jtMLmcbxS6ydWIpOfhz34TSfO3JaE=
github.com/vektah/gqlparser/v2 v2.5.27 h1:RHPD3JOplpk5mP5JGX8RKZkt2/Vwj/PZv0HxTdwFp0s=
github.com/vektah/gqlparser/v2 v2.5.27/go.mod h1:D1/VCZtV3LPnQrcPBeR/q5jkSQIPti0uYCP/RI0gIeo=
-github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no=
-github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM=
github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8=
github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok=
github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g=
github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds=
+github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no=
+github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM=
github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU=
github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=
github.com/yeongaori/discordgo-fork v0.0.0-20260319072544-e8e546f5d532 h1:gxFHYeUDGziRb0zXYEqBFohC+NJbIW9L0tddaXMWr2o=
@@ -392,6 +392,8 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo=
+golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI=
golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
diff --git a/pkg/protoagent/README.md b/pkg/protoagent/README.md
index 213eb03c3..500204d81 100644
--- a/pkg/protoagent/README.md
+++ b/pkg/protoagent/README.md
@@ -23,8 +23,61 @@ pkg/protoagent/
├── engine.go # Motor principal de processamento
├── generators.go # Geradores de artefatos
└── policies.go # Gerador de políticas OPA
+
+cmd/protoagent-cli/
+└── main.go # CLI para uso por linha de comando
```
+## Separação do ProtoAgent
+
+O código do protoagente foi completamente separado do restante do agente:
+
+- **Backend (pkg/protoagent/)**: Contém toda a lógica de processamento de requisitos e geração de artefatos
+ - `types.go`: Definições de tipos e estruturas de dados
+ - `engine.go`: Motor principal de processamento
+ - `generators.go`: Geradores de artefatos (interfaces, schemas, channels, skills, tools)
+ - `policies.go`: Gerador de políticas OPA
+
+- **Frontend (CLI)**: Interface de linha de comando para interação com o protoagente
+ - `cmd/protoagent-cli/main.go`: CLI completa com comandos generate, validate, version e help
+
+## CLI de Linha de Comando
+
+O ProtoAgent possui uma CLI dedicada para uso via terminal:
+
+### Instalação
+
+```bash
+go build -o protoagent-cli ./cmd/protoagent-cli
+```
+
+### Uso
+
+```bash
+# Gerar artefatos a partir de requisitos
+protoagent-cli generate requirements.json -o ./output --opa --verbose
+
+# Validar arquivo de requisitos
+protoagent-cli validate requirements.json
+
+# Ver versão
+protoagent-cli version
+
+# Ajuda
+protoagent-cli help
+```
+
+### Comandos
+
+- `generate`: Gera todos os artefatos a partir de um arquivo de requisitos JSON
+ - Opções: `-o/--output`, `-w/--workspace`, `--opa`, `--ai`, `--dry-run`, `-v/--verbose`
+
+- `validate`: Valida um arquivo de requisitos sem gerar artefatos
+
+- `version`: Mostra informações de versão
+
+- `help`: Mostra ajuda detalhada
+
## Tipos de Requisitos
### Requisitos Funcionais