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