package reporter import ( "encoding/json" "fmt" "io" "text/tabwriter" "time" "github.com/claudomator/claudomator/internal/storage" ) // Reporter generates reports from execution data. type Reporter interface { Generate(w io.Writer, executions []*storage.Execution) error } // ConsoleReporter outputs a formatted table. type ConsoleReporter struct{} func (r *ConsoleReporter) Generate(w io.Writer, executions []*storage.Execution) error { if len(executions) == 0 { fmt.Fprintln(w, "No executions found.") return nil } tw := tabwriter.NewWriter(w, 0, 0, 2, ' ', 0) fmt.Fprintln(tw, "ID\tTASK\tSTATUS\tEXIT\tCOST\tDURATION\tSTARTED") var totalCost float64 var completed, failed int for _, e := range executions { dur := e.EndTime.Sub(e.StartTime) totalCost += e.CostUSD if e.Status == "COMPLETED" { completed++ } else { failed++ } fmt.Fprintf(tw, "%.8s\t%.8s\t%s\t%d\t$%.4f\t%v\t%s\n", e.ID, e.TaskID, e.Status, e.ExitCode, e.CostUSD, dur.Round(time.Second), e.StartTime.Format("2006-01-02 15:04")) } tw.Flush() fmt.Fprintf(w, "\nSummary: %d completed, %d failed, total cost $%.4f\n", completed, failed, totalCost) return nil } // JSONReporter outputs JSON. type JSONReporter struct { Pretty bool } func (r *JSONReporter) Generate(w io.Writer, executions []*storage.Execution) error { enc := json.NewEncoder(w) if r.Pretty { enc.SetIndent("", " ") } return enc.Encode(executions) } // HTMLReporter generates a standalone HTML report. type HTMLReporter struct{} func (r *HTMLReporter) Generate(w io.Writer, executions []*storage.Execution) error { var totalCost float64 var completed, failed int for _, e := range executions { totalCost += e.CostUSD if e.Status == "COMPLETED" { completed++ } else { failed++ } } fmt.Fprint(w, ` Claudomator Report

Claudomator Report

`) fmt.Fprintf(w, `
Completed
%d
`, completed) fmt.Fprintf(w, `
Failed
%d
`, failed) fmt.Fprintf(w, `
Total Cost
$%.4f
`, totalCost) fmt.Fprintf(w, `
Total
%d
`, len(executions)) fmt.Fprint(w, `
`) for _, e := range executions { dur := e.EndTime.Sub(e.StartTime).Round(time.Second) fmt.Fprintf(w, ``, e.ID, e.TaskID, e.Status, e.Status, e.ExitCode, e.CostUSD, dur, e.StartTime.Format("2006-01-02 15:04")) } fmt.Fprint(w, `
IDTaskStatusExitCostDurationStarted
%.8s%.8s%s%d$%.4f%v%s
`) return nil }