Commit b036a5e

Eric Bower  ·  2026-05-07 12:43:12 -0400 EDT
parent 85f918b
chore: cleanup
2 files changed,  +19, -16
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",
M main_test.go
+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)