From e89cbf397590fbebead02511301de20f1a548e99 Mon Sep 17 00:00:00 2001 From: tgwab-claude <326333458+tgwab-claude@users.noreply.github.com> Date: Tue, 22 Sep 2026 21:20:09 -0400 Subject: [PATCH 1/2] scripts: add a manual regression guard for the tray memory leak Refs #20. The leak in #20 (Tomatick hit 6.13 GB, macOS warned) is the same bug as #15: it was already fixed on main by #16 (autorelease pool around timer-driven tray updates), merged 2026-09-14 -- but the installed /Applications/Tomatick.app is still built from the v2.0.0 tag (2026-09-10), four days before that fix landed, so Michal has been running the pre-fix binary the whole time. No new code leak was found beyond what #16 already closes; this branch is origin/main plus a guard. #16 didn't leave a repeatable check behind, so add scripts/measure-tray-memory.sh: builds the app, runs it idle for 10 minutes, and samples footprint every 30s, with the pass/fail threshold taken from #16's own before/after numbers (pre-fix ~28 KB/s idle vs post-fix ~0.08 MB/10 min). It has to run by hand on a Mac GUI session, so it isn't wired into CI. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01VjrZpzfYSjYw3sW4XibcCd --- scripts/measure-tray-memory.sh | 52 ++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100755 scripts/measure-tray-memory.sh diff --git a/scripts/measure-tray-memory.sh b/scripts/measure-tray-memory.sh new file mode 100755 index 0000000..d14312a --- /dev/null +++ b/scripts/measure-tray-memory.sh @@ -0,0 +1,52 @@ +#!/usr/bin/env bash +# measure-tray-memory.sh — regression guard for the menu-bar tray leak (#15, #16, #20). +# +# macOS only, and manual: it needs a live GUI session (the tray only renders +# inside one), so it cannot run on a CI runner. Run it by hand on a Mac after +# any change to internal/ui/tray.go, internal/ui/ui.go, or internal/ui/pool_darwin.go, +# and before cutting a release. +# +# What it does: builds ./tomatick from the current checkout, launches it detached +# in the current GUI session, samples RSS with `footprint` every 30s for 10 +# minutes while idle (no timer running), then kills it. +# +# Pass/fail threshold, from PR #16's own before/after measurement (idle, red +# theme, macOS 26.6.2): +# - buggy (Tomatick 2.0.0, before #16): 36 MB -> 53 MB over 10 min (~28 KB/s) +# - fixed (this repo, after #16): 33 MB -> 33 MB over 10 min (~0.08 MB heap growth) +# A fixed build should show well under 5 MB of growth over the 10-minute idle +# window. 5-50 MB points at a partial regression (icon or title churn no longer +# fully pooled); 50+ MB over 10 min is the pre-#16 leak back in force. +# +# This script only checks idle growth. A running timer changes the title every +# tick too and was NOT verified in #16 -- if you need that case, start a timer +# from the tray after launch and re-run the sampling loop by hand. +set -euo pipefail + +if [ "$(uname -s)" != "Darwin" ]; then + echo "measure-tray-memory.sh only runs on macOS." >&2 + exit 1 +fi + +cd "$(dirname "$0")/.." + +echo "Building ./tomatick from the current checkout..." +go build -o tomatick ./cmd/tomatick + +./tomatick & +pid=$! +trap 'kill "$pid" 2>/dev/null || true' EXIT + +echo "Started tomatick, pid $pid. Sampling footprint every 30s for 10 minutes (idle, no timer)." +echo "elapsed_s footprint_mb" + +start=$(date +%s) +for i in $(seq 1 20); do + sleep 30 + elapsed=$(( $(date +%s) - start )) + mb=$(footprint "$pid" 2>/dev/null | awk '/Physical footprint:/ {print $3}') + echo "${elapsed} ${mb}" +done + +kill "$pid" 2>/dev/null || true +echo "Done. Compare the first and last footprint_mb column against the thresholds above." From 638c07a31d5984db1c7fad9a7bfbeda8dda71462 Mon Sep 17 00:00:00 2001 From: tgwab-claude <326333458+tgwab-claude@users.noreply.github.com> Date: Tue, 22 Sep 2026 21:21:54 -0400 Subject: [PATCH 2/2] Bump to 2.0.1 to ship the tray memory fix (#16) 2.0.0 (tagged 2026-09-10) predates #16 (merged 2026-09-14), so every installed copy still leaks about 28 KB/s while idle. Refs #20. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01VjrZpzfYSjYw3sW4XibcCd --- cmd/tomatick/FyneApp.toml | 2 +- internal/version/version.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/tomatick/FyneApp.toml b/cmd/tomatick/FyneApp.toml index 295239a..e486ddf 100644 --- a/cmd/tomatick/FyneApp.toml +++ b/cmd/tomatick/FyneApp.toml @@ -1,7 +1,7 @@ [Details] Name = "Tomatick" ID = "us.tomatick" -Version = "2.0.0" +Version = "2.0.1" Build = 1 Icon = "Icon.png" diff --git a/internal/version/version.go b/internal/version/version.go index c4fcce5..429ab94 100644 --- a/internal/version/version.go +++ b/internal/version/version.go @@ -1,7 +1,7 @@ package version // Version is the single source of truth for the app version. -const Version = "2.0.0" +const Version = "2.0.1" const ( AppName = "Tomatick"