Commit b036a5e
Eric Bower
·
2026-05-07 12:43:12 -0400 EDT
parent 85f918b
chore: cleanup
2 files changed,
+19,
-16
M
main.go
M
main.go
+18,
-15
1@@ -18,8 +18,6 @@ import (
2 "strings"
3 "syscall"
4 "time"
5-
6-
7 )
8
9 type WorkspaceFactory func(cfg *Cfg, logger *slog.Logger, source string) Workspace
10@@ -44,7 +42,7 @@ type Cfg struct {
11 MonitorInterval time.Duration
12 NewWorkspace WorkspaceFactory
13 StatusOutput io.Writer // where status JSONL is written (default: os.Stdout)
14- StatusFilter string // "terminal" (default) or "all"
15+ IncludeRunning bool // emit running status updates in addition to terminal
16 HumanOutput bool // human-readable output instead of JSONL / slog
17 Wait bool // block until job completes, print history and summary
18 }
19@@ -67,10 +65,10 @@ func NewCfg() (*Cfg, string, bool) {
20 flag.StringVar(&event, "event", "", "event JSON to run (alternative to reading from stdin)")
21 flag.DurationVar(&monitorInterval, "monitor-interval", 5*time.Second, "interval for monitoring zmx sessions")
22 flag.StringVar(&logLevel, "log-level", "info", "log level: debug, info, warn, error")
23- var statusFilter string
24+ var includeRunning bool
25 var human bool
26 var wait bool
27- flag.StringVar(&statusFilter, "status-filter", "terminal", "status output filter: terminal (default) or all")
28+ flag.BoolVar(&includeRunning, "include-running", false, "emit running status updates in addition to terminal (default: terminal only)")
29 flag.BoolVar(&human, "human", false, "human-readable output (default: JSONL / slog)")
30 flag.BoolVar(&wait, "wait", false, "block until job completes, printing session history and summary")
31
32@@ -91,7 +89,7 @@ func NewCfg() (*Cfg, string, bool) {
33 ArtifactDir: artifactDir,
34 Event: event,
35 MonitorInterval: monitorInterval,
36- StatusFilter: statusFilter,
37+ IncludeRunning: includeRunning,
38 HumanOutput: human,
39 Wait: wait,
40 }, cmd, wantHelp
41@@ -190,16 +188,18 @@ func printMonitorHelp() {
42 fmt.Println(`pici monitor — poll ci.* zmx sessions, stage artifacts, publish status.
43
44 USAGE
45- pici monitor [flags]
46- pici monitor --human | ssh pipe.pico.sh "pub build.status -b=false"
47+ pici monitor [flags] # JSONL to stdout (pipe to webhooks)
48+ pici monitor --human # human-readable terminal output
49
50 OUTPUT MODES
51- Default (JSONL): One JSON object per line to stdout, suitable for piping.
52+ Default (JSONL): One JSON object per line, suitable for piping to notifications.
53 pici monitor > status.jsonl
54+ pici monitor | ssh pipe.pico.sh "pub build.status -b=false"
55 pici monitor | while read -r line; do curl -sd"$line" $WEBHOOK; done
56
57- --human: Selfci-style progress output for terminal viewing.
58- pici monitor --human --status-filter all
59+ --human: Selfci-style progress output for terminal viewing (do not pipe).
60+ pici monitor --human
61+ pici monitor --human --include-running
62 [2/3] 🚀 running: myrepo (1m23s)
63 [3/3] ✅ success: myrepo (2m34s)
64
65@@ -208,8 +208,8 @@ FLAGS
66 -ck <path> SSH certificate public key
67 -artifact-dir <path> Local directory to stage artifacts (default: /tmp/pici-artifacts)
68 -monitor-interval <dur> Poll interval (default: 5s)
69- -status-filter <filter> "terminal" (default) or "all"
70- -human Human-readable output instead of JSONL
71+ -include-running Emit running status updates in addition to terminal (default: terminal only)
72+ -human Human-readable output instead of JSONL (for terminal, not piping)
73 -log-level <level> Log level: debug, info, warn, error (default: info)`)
74 }
75
76@@ -345,6 +345,7 @@ type SessionInfo struct {
77 }
78
79 type StatusPayload struct {
80+ Timestamp string `json:"timestamp"`
81 Name string `json:"name"`
82 JobID string `json:"job_id"`
83 Status string `json:"status"`
84@@ -924,6 +925,7 @@ func monitorTick(cfg *Cfg, log *slog.Logger, output io.Writer, jobStates map[str
85 renderJobFinal(output, name, jobID, group, duration, status, exitCode == 0, eventData.Workspace, cfg.ArtifactDir, artifactURL)
86 } else {
87 payload := StatusPayload{
88+ Timestamp: time.Now().UTC().Format(time.RFC3339),
89 Name: name,
90 JobID: jobID,
91 Status: status,
92@@ -945,12 +947,13 @@ func monitorTick(cfg *Cfg, log *slog.Logger, output io.Writer, jobStates map[str
93 }
94 } else {
95 log.Debug("job still running", "sessions", len(group))
96- // Publish running status only when filter is "all"
97- if cfg.StatusFilter != "terminal" {
98+ // Publish running status only when --include-running is set
99+ if cfg.IncludeRunning {
100 if cfg.HumanOutput {
101 renderJobRunning(output, name, jobID, group, duration, jobStates)
102 } else {
103 payload := StatusPayload{
104+ Timestamp: time.Now().UTC().Format(time.RFC3339),
105 Name: name,
106 JobID: jobID,
107 Status: "running",
+1,
-1
1@@ -59,7 +59,7 @@ zmx run step2 echo "hello from step2"
2 MonitorInterval: 200 * time.Millisecond,
3 NewWorkspace: defaultWorkspaceFactory,
4 StatusOutput: statusBuf,
5- StatusFilter: "all",
6+ IncludeRunning: true,
7 }
8
9 // 3. Run the runner (fire-and-forget, exits quickly)