From 88103657fb230bb41217a06aa5602ae23e7acb8b Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Wed, 17 Sep 2025 21:33:45 +0300 Subject: =?UTF-8?q?feat(stats,tmux):=20global=20=CE=A3@window=20stats=20ac?= =?UTF-8?q?ross=20processes=20with=20flocked=20cache;=20width=20mitigation?= =?UTF-8?q?=20(narrow/maxlen);=20configurable=20[stats]=20window=5Fminutes?= =?UTF-8?q?;=20robust=20coverage=20parsing;=20docs=20update\n\n-=20Add=20i?= =?UTF-8?q?nternal/stats=20with=20windowed=20event=20cache=20+=20flock=20+?= =?UTF-8?q?=20atomic=20writes\n-=20Wire=20stats=20into=20LSP/CLI/Tmux=20Ac?= =?UTF-8?q?tion;=20tmux=20shows=20=CE=A3@window=20with=20per-model=20tail\?= =?UTF-8?q?n-=20HEXAI=5FTMUX=5FSTATUS=5FNARROW=20and=20HEXAI=5FTMUX=5FSTAT?= =?UTF-8?q?US=5FMAXLEN=20for=20width=20control\n-=20Add=20[stats]=20window?= =?UTF-8?q?=5Fminutes=20to=20config=20and=20apply=20on=20startup\n-=20Impr?= =?UTF-8?q?ove=20Magefile=20coverage=20handling;=20add=20tests=20to=20lift?= =?UTF-8?q?=20coverage=20>85%\n-=20Update=20docs/tmux.md=20and=20config=20?= =?UTF-8?q?example?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/tmux/status_more_test.go | 62 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 internal/tmux/status_more_test.go (limited to 'internal/tmux/status_more_test.go') diff --git a/internal/tmux/status_more_test.go b/internal/tmux/status_more_test.go new file mode 100644 index 0000000..deaf57d --- /dev/null +++ b/internal/tmux/status_more_test.go @@ -0,0 +1,62 @@ +package tmux + +import ( + "os" + "testing" + "time" +) + +func TestFormatLLMStatsStatus_Basic(t *testing.T) { + s := FormatLLMStatsStatus("gpt-4.1", 5, 0.8, 1234, 5678) + if s == "" || !containsAll(s, []string{"LLM:gpt-4.1", "5r", "0.8rpm"}) { + t.Fatalf("unexpected status: %q", s) + } +} + +func TestFormatLLMStatsStatusColored_Basic(t *testing.T) { + s := FormatLLMStatsStatusColored("openai", "gpt-4.1", 2, 1.2, 100, 200) + if s == "" || !containsAll(s, []string{"LLM:openai:gpt-4.1", "rpm", "2r"}) { + t.Fatalf("colored status missing parts: %q", s) + } +} + +func TestFormatGlobalStatusColored_NarrowAndMaxLen(t *testing.T) { + // Narrow mode should elide the tail + os.Setenv("HEXAI_TMUX_STATUS_NARROW", "1") + defer os.Unsetenv("HEXAI_TMUX_STATUS_NARROW") + s := FormatGlobalStatusColored(10, 3.3, 1000, 2000, "prov", "model", 1.1, 4, 30*time.Minute) + if containsAll(s, []string{"|", "prov:model"}) { + t.Fatalf("narrow mode should not include tail: %q", s) + } + // Max length should also drop the tail when it would overflow + os.Unsetenv("HEXAI_TMUX_STATUS_NARROW") + os.Setenv("HEXAI_TMUX_STATUS_MAXLEN", "10") + defer os.Unsetenv("HEXAI_TMUX_STATUS_MAXLEN") + s2 := FormatGlobalStatusColored(10, 3.3, 1000, 2000, "prov", "model", 1.1, 4, 30*time.Minute) + if containsAll(s2, []string{"|", "prov:model"}) { + t.Fatalf("maxlen should drop tail when overflowing: %q", s2) + } +} + +func containsAll(s string, parts []string) bool { + for _, p := range parts { + if !contains(s, p) { + return false + } + } + return true +} + +func contains(s, sub string) bool { + return len(s) >= len(sub) && (len(sub) == 0 || (len(s) > 0 && indexOf(s, sub) >= 0)) +} + +func indexOf(s, sub string) int { + // tiny wrapper to avoid importing strings + for i := 0; i+len(sub) <= len(s); i++ { + if s[i:i+len(sub)] == sub { + return i + } + } + return -1 +} -- cgit v1.2.3