From 5b5ac917042107fc32a9ce7e841c945b7a38ac5f Mon Sep 17 00:00:00 2001 From: Brad Gessler Date: Mon, 16 Mar 2026 14:36:55 -0700 Subject: [PATCH] Add PORT column to `overmind status` and `--json` flag Co-Authored-By: Claude Opus 4.6 (1M context) --- cmd_status.go | 11 +++++++++-- main.go | 7 ++++++- start/command.go | 1 + start/command_center.go | 39 +++++++++++++++++++++++++++++++++------ start/process.go | 4 +++- 5 files changed, 52 insertions(+), 10 deletions(-) diff --git a/cmd_status.go b/cmd_status.go index e6444d1..c08814d 100644 --- a/cmd_status.go +++ b/cmd_status.go @@ -9,7 +9,10 @@ import ( "github.com/urfave/cli" ) -type cmdStatusHandler struct{ dialer } +type cmdStatusHandler struct { + dialer + JSON bool +} func (h *cmdStatusHandler) Run(c *cli.Context) error { if c.Args().Present() { @@ -19,7 +22,11 @@ func (h *cmdStatusHandler) Run(c *cli.Context) error { conn, err := h.Dial() utils.FatalOnErr(err) - fmt.Fprintln(conn, "status") + if h.JSON { + fmt.Fprintln(conn, "status-json") + } else { + fmt.Fprintln(conn, "status") + } utils.ScanLines(conn, func(b []byte) bool { fmt.Fprintf(os.Stdout, "%s\n", b) diff --git a/main.go b/main.go index 8ad8f56..4dc26d8 100644 --- a/main.go +++ b/main.go @@ -168,7 +168,12 @@ func setupStatusCmd() cli.Command { Aliases: []string{"ps"}, Usage: "Prints process statuses", Action: c.Run, - Flags: socketFlags(&c.SocketPath, &c.Network), + Flags: append( + []cli.Flag{ + cli.BoolFlag{Name: "json, j", Usage: "Output in JSON format", Destination: &c.JSON}, + }, + socketFlags(&c.SocketPath, &c.Network)..., + ), } } diff --git a/start/command.go b/start/command.go index 9ba2af2..0486405 100644 --- a/start/command.go +++ b/start/command.go @@ -102,6 +102,7 @@ func newCommand(h *Handler) (*command, error) { (h.AnyCanDie || utils.StringsContain(canDie, e.OrigName)), (utils.StringsContain(autoRestart, e.OrigName) || utils.StringsContain(autoRestart, "all")), e.StopSignal, + e.Port, )) } } diff --git a/start/command_center.go b/start/command_center.go index b0ff77f..2f67cd4 100644 --- a/start/command_center.go +++ b/start/command_center.go @@ -1,6 +1,7 @@ package start import ( + "encoding/json" "fmt" "net" "regexp" @@ -94,6 +95,8 @@ func (c *commandCenter) handleConnection(conn net.Conn) { c.processEcho(conn) case "status": c.processStatus(conn) + case "status-json": + c.processStatusJSON(conn) } return true @@ -169,6 +172,13 @@ func (c *commandCenter) processEcho(conn net.Conn) { c.cmd.output.Echo(conn) } +func processStatusString(p *process) string { + if p.dead || p.keepingAlive { + return "dead" + } + return "running" +} + func (c *commandCenter) processStatus(conn net.Conn) { maxNameLen := 9 for _, p := range c.cmd.processes { @@ -181,20 +191,37 @@ func (c *commandCenter) processStatus(conn net.Conn) { for i := maxNameLen - len(headerProcess); i > -1; i-- { conn.Write([]byte{' '}) } - + fmt.Fprint(conn, "PORT ") fmt.Fprint(conn, headerPid) fmt.Fprint(conn, " ") fmt.Fprintln(conn, headerStatus) for _, p := range c.cmd.processes { utils.FprintRpad(conn, p.Name, maxNameLen+1) + utils.FprintRpad(conn, strconv.Itoa(p.Port), 10) utils.FprintRpad(conn, strconv.Itoa(p.pid), 10) + fmt.Fprintln(conn, processStatusString(p)) + } + conn.Close() +} - if p.dead || p.keepingAlive { - fmt.Fprintln(conn, "dead") - } else { - fmt.Fprintln(conn, "running") - } +type processStatusEntry struct { + Name string `json:"name"` + Port int `json:"port"` + PID int `json:"pid"` + Status string `json:"status"` +} + +func (c *commandCenter) processStatusJSON(conn net.Conn) { + entries := make([]processStatusEntry, 0, len(c.cmd.processes)) + for _, p := range c.cmd.processes { + entries = append(entries, processStatusEntry{ + Name: p.Name, + Port: p.Port, + PID: p.pid, + Status: processStatusString(p), + }) } + json.NewEncoder(conn).Encode(entries) conn.Close() } diff --git a/start/process.go b/start/process.go index b18c8bd..9437aae 100644 --- a/start/process.go +++ b/start/process.go @@ -36,9 +36,10 @@ type process struct { Name string Color int Command string + Port int } -func newProcess(tmux *tmuxClient, name string, color int, command string, output *multiOutput, canDie bool, autoRestart bool, stopSignal syscall.Signal) *process { +func newProcess(tmux *tmuxClient, name string, color int, command string, output *multiOutput, canDie bool, autoRestart bool, stopSignal syscall.Signal, port int) *process { out, in := io.Pipe() proc := &process{ @@ -56,6 +57,7 @@ func newProcess(tmux *tmuxClient, name string, color int, command string, output Name: name, Color: color, Command: command, + Port: port, } tmux.AddProcess(proc)