app/format, ui/jobs_view: DisplayStats summary + Statistics detail row (T2.6, T2.7)

Add DisplayStats to format.go: returns "No runs recorded" when RunCount is
zero, otherwise a one-line "N runs, M failed, last X ms, avg Y ms, max Z ms"
summary.  Wire a Statistics detail row into the jobs panel that refreshes via
updateDetails alongside the other runtime fields.

Tests: TestDisplayStats (nil/zero/normal/no-fail), TestUpdateStats (three
sequential fake runs through updateStats verifying all aggregate fields), and
five seed tests in runner/seed_test.go covering basic aggregation,
duration-less legacy logs, maxFiles capping, missing directory, and
unmatched log files.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
mixeme
2026-06-24 08:24:48 +03:00
parent 6c69f323bd
commit 886d0d9caa
6 changed files with 231 additions and 2 deletions
+10
View File
@@ -82,6 +82,16 @@ func DisplayInvocation(job domain.Job) string {
return job.Command + " " + strings.ReplaceAll(strings.TrimSpace(job.Arguments), "\n", " ")
}
// DisplayStats returns a one-line execution-time summary for a job runtime.
// Returns "No runs recorded" when no runs have been counted yet.
func DisplayStats(rt *domain.JobRuntime) string {
if rt == nil || rt.RunCount == 0 {
return "No runs recorded"
}
return fmt.Sprintf("%d runs, %d failed, last %d ms, avg %d ms, max %d ms",
rt.RunCount, rt.FailCount, rt.LastDurationMS, rt.AvgDurationMS, rt.MaxDurationMS)
}
// DisplayIndex returns the position of jobIndex in the given slice of indexes,
// or 0 if not found.
func DisplayIndex(indexes []int, jobIndex int) int {