1package agent
2
3import (
4 "fmt"
5 "io"
6 "sort"
7 "strings"
8 "time"
9
10 "github.com/bnema/zut/packages/agent/subagents"
11)
12
13func runDebugCommand(rawArgs []string, stdout io.Writer) (bool, error) {
14 if len(rawArgs) == 0 || rawArgs[0] != "debug" {
15 return false, nil
16 }
17 if len(rawArgs) != 3 || rawArgs[1] != "trace" {
18 return true, fmt.Errorf("usage: zut debug trace <bundle>")
19 }
20 events, readErr := subagents.ReadTrace(rawArgs[2])
21 if err := renderTraceInspection(stdout, subagents.ProjectTrace(events), time.Now()); err != nil {
22 return true, err
23 }
24 return true, readErr
25}
26
27func renderTraceInspection(w io.Writer, views map[string]subagents.AgentTraceView, now time.Time) error {
28 ids := make([]string, 0, len(views))
29 for id := range views {
30 ids = append(ids, id)
31 }
32 sort.Strings(ids)
33 for _, id := range ids {
34 view := views[id]
35 if view.Terminal != "" {
36 if _, err := fmt.Fprintf(w, "%s %s\n", id, view.Terminal); err != nil {
37 return err
38 }
39 continue
40 }
41 if len(view.OpenOperations) != 0 {
42 operation := view.OpenOperations[0]
43 if _, err := fmt.Fprintf(w, "%s %s open %s\n", id, strings.Replace(operation.Type, ".started", "", 1), operation.Duration(now).Round(time.Second)); err != nil {
44 return err
45 }
46 continue
47 }
48 age := now.Sub(view.LastEvent.Timestamp).Round(time.Second)
49 when := age.String() + " ago"
50 if age < 0 {
51 when = "in " + (-age).String()
52 }
53 if _, err := fmt.Fprintf(w, "%s no observable operation; last event %s %s\n", id, view.LastEvent.Type, when); err != nil {
54 return err
55 }
56 }
57 return nil
58}