diff options
| author | srdusr <[email protected]> | 2026-02-05 11:33:00 +0200 |
|---|---|---|
| committer | srdusr <[email protected]> | 2026-02-05 11:33:00 +0200 |
| commit | 8ec54d5ad018828a7e6e40980e9bd9dfaeaa5e7b (patch) | |
| tree | 29064dba0a9787ba88197a12b4748ca02db62a15 /internal/ipc/ipc.go | |
| parent | c39808cca65bb72211359f4d6be3ba869f0121e6 (diff) | |
| download | mitmux-8ec54d5ad018828a7e6e40980e9bd9dfaeaa5e7b.tar.gz mitmux-8ec54d5ad018828a7e6e40980e9bd9dfaeaa5e7b.zip | |
Status bar and help screen
Baseline TUI UX that should exist regardless of feature parity -
flagged directly by the Burp/ZAP/Caido comparison research as missing.
A persistent one-line status bar (proxy address, live request count,
current view) is now appended to every screen. Fetched once at startup
via a new "status" IPC request (internal/store gains Store.Count();
internal/ipc gains StatusMsg plus a daemon-side handler reading
proxy.Server.Addr through ipc.NewServer's new proxyAddr parameter), then
kept approximately live by incrementing locally on each "new" subscribe
push rather than re-querying every time.
'?' opens a full keybinding reference from every view, gated so it
never shadows literal text entry - it's a no-op while typing in the
search box, a rule form field, or (checked via viTextarea.Mode())
insert-mode text in Repeater/Intruder, where a URL query string
literally starting with '?' is completely ordinary input. Any key
dismisses it and returns to whichever view opened it.
Every existing height calculation (table, viewport, textarea panes)
had to shrink by one line to make room for the status bar without
pushing content off-screen - done once via a shared `h := msg.Height-1`
in the WindowSizeMsg handler rather than touching each call site
individually.
Verified live: status bar shows the real proxy address and updates its
count after a live-captured request; '?' renders the full reference
from the history list; dismissing returns to the correct prior view;
and specifically confirmed '?' still types literally (tested typing
"?foo=bar" into a Repeater request body in insert mode) rather than
being swallowed by the help shortcut.
Diffstat (limited to 'internal/ipc/ipc.go')
| -rw-r--r-- | internal/ipc/ipc.go | 26 |
1 files changed, 25 insertions, 1 deletions
diff --git a/internal/ipc/ipc.go b/internal/ipc/ipc.go index 03a4bc7..d295238 100644 --- a/internal/ipc/ipc.go +++ b/internal/ipc/ipc.go @@ -48,11 +48,12 @@ type Request struct { // Response is sent by the daemon to a client. type Response struct { - Type string `json:"type"` // "list", "get", "new", "repeat", "rules", "intrude_result", "intrude_done", or "error" + Type string `json:"type"` // "list", "get", "new", "repeat", "rules", "intrude_result", "intrude_done", "status", or "error" Entries []store.Summary `json:"entries,omitempty"` // for "list" Detail *EntryDetail `json:"detail,omitempty"` // for "get" and "repeat" New *store.Summary `json:"new,omitempty"` // for "new" (subscribe push) Rules []rules.Rule `json:"rules,omitempty"` // for "rules" + Status *StatusMsg `json:"status,omitempty"` // for "status" // For "intrude_result": one completed attack request. IntrudeResult *IntrudeResultMsg `json:"intrude_result,omitempty"` @@ -60,6 +61,12 @@ type Response struct { Error string `json:"error,omitempty"` } +// StatusMsg is basic daemon info for a TUI status bar. +type StatusMsg struct { + ProxyAddr string `json:"proxy_addr"` + HistoryCount int64 `json:"history_count"` +} + // IntrudeResultMsg is one completed Intruder attack request. type IntrudeResultMsg struct { Position int `json:"position"` @@ -110,6 +117,23 @@ func (c *Client) Close() error { return c.conn.Close() } +// Status returns basic daemon info for a status bar. +func (c *Client) Status() (*StatusMsg, error) { + c.mu.Lock() + defer c.mu.Unlock() + if err := c.enc.Encode(Request{Type: "status"}); err != nil { + return nil, err + } + var resp Response + if err := c.dec.Decode(&resp); err != nil { + return nil, err + } + if resp.Type == "error" { + return nil, errors.New(resp.Error) + } + return resp.Status, nil +} + // List returns up to limit history summaries older than beforeID (0 for // the most recent), newest first. func (c *Client) List(limit int, beforeID int64) ([]store.Summary, error) { |