package cli import ( "fmt" "os" "time" "github.com/spf13/cobra" "github.com/thepeterstone/claudomator/internal/reporter" "github.com/thepeterstone/claudomator/internal/storage" ) func newReportCmd() *cobra.Command { var format string var limit int var taskID string cmd := &cobra.Command{ Use: "report", Short: "Report execution history", RunE: func(cmd *cobra.Command, args []string) error { return runReport(format, limit, taskID) }, } cmd.Flags().StringVar(&format, "format", "table", "output format: table, json, html") cmd.Flags().IntVar(&limit, "limit", 50, "maximum number of executions to show") cmd.Flags().StringVar(&taskID, "task", "", "filter by task ID") return cmd } func runReport(format string, limit int, taskID string) error { var rep reporter.Reporter switch format { case "table", "": rep = &reporter.ConsoleReporter{} case "json": rep = &reporter.JSONReporter{Pretty: true} case "html": rep = &reporter.HTMLReporter{} default: return fmt.Errorf("invalid format %q: must be table, json, or html", format) } store, err := storage.Open(cfg.DBPath) if err != nil { return fmt.Errorf("opening db: %w", err) } defer store.Close() recent, err := store.ListRecentExecutions(time.Time{}, limit, taskID) if err != nil { return fmt.Errorf("listing executions: %w", err) } execs := make([]*storage.Execution, len(recent)) for i, r := range recent { e := &storage.Execution{ ID: r.ID, TaskID: r.TaskID, Status: r.State, StartTime: r.StartedAt, ExitCode: r.ExitCode, CostUSD: r.CostUSD, } if r.FinishedAt != nil { e.EndTime = *r.FinishedAt } execs[i] = e } return rep.Generate(os.Stdout, execs) }