package orch import ( "fmt" "os" "path/filepath" "strings" "ai-workflow-skill/internal/protocol" "ai-workflow-skill/internal/store" "github.com/spf13/cobra" ) type councilReportOptions struct { runID string show string } func newCouncilReportCmd(root *rootOptions) *cobra.Command { opts := &councilReportOptions{} cmd := &cobra.Command{ Use: "report", Short: "Render the final grouped council output", RunE: func(cmd *cobra.Command, args []string) error { ctx := cmd.Context() sqlDB, err := openOrchDB(ctx, root.dbPath) if err != nil { return err } defer sqlDB.Close() orchStore := store.NewOrchStore(sqlDB) result, err := orchStore.BuildCouncilReport(ctx, store.CouncilReportInput{ RunID: opts.runID, Show: opts.show, }) if err != nil { return err } reportPath := councilReportArtifactPath(root.dbPath, result.RunID) if err := os.MkdirAll(filepath.Dir(reportPath), 0o755); err != nil { return fmt.Errorf("create council report directory: %w", err) } if err := os.WriteFile(reportPath, []byte(result.Markdown), 0o644); err != nil { return fmt.Errorf("write council report artifact: %w", err) } result.ReportArtifacts = []store.CouncilReportArtifact{ { Kind: "markdown", Path: reportPath, }, } if err := orchStore.PersistCouncilReport(ctx, store.CouncilPersistReportInput{ RunID: result.RunID, Show: result.Show, Summary: result.Summary, MarkdownPath: reportPath, }); err != nil { return err } resp := protocol.Success{ OK: true, Command: "council report", Data: map[string]any{ "run_id": result.RunID, "show": result.Show, "summary": result.Summary, "grouped_recommendations": result.GroupedRecommendations, "report_artifacts": result.ReportArtifacts, }, } if root.json { return protocol.WriteJSON(cmd.OutOrStdout(), resp) } _, err = fmt.Fprint(cmd.OutOrStdout(), result.Markdown) return err }, } cmd.Flags().StringVar(&opts.runID, "run", "", "Council run ID") cmd.Flags().StringVar(&opts.show, "show", "", "Buckets to show: consensus,majority,minority,all") _ = cmd.MarkFlagRequired("run") return cmd } func councilReportArtifactPath(dbPath, runID string) string { baseDir := "." dbDir := filepath.Dir(dbPath) switch { case dbDir == "", dbDir == ".": baseDir = "." case filepath.Base(dbDir) == ".agents": baseDir = filepath.Dir(dbDir) default: baseDir = dbDir } if baseDir == "" { baseDir = "." } fileName := strings.ReplaceAll(strings.TrimSpace(runID), string(os.PathSeparator), "_") + ".md" return filepath.Join(baseDir, ".orch", "reports", fileName) }