Skip to content

chore(sutando-app): bump checkWatcher Timer from 30s → 5min - #699

Merged
sonichi merged 2 commits into
mainfrom
chore/check-watcher-5min
May 14, 2026
Merged

sonichi merged 2 commits into
mainfrom
chore/check-watcher-5min

Conversation

@sonichi

@sonichi sonichi commented May 14, 2026

Copy link
Copy Markdown
Owner

Summary

Bumps the menu-bar app's checkWatcher() Timer cadence from 30s → 5 min (Timer.scheduledTimer(withTimeInterval: 300.0, ...) in Sutando/main.swift:241). Per Chi 2026-05-14 23:15Z (y to the proposal at https://discord.com/channels/1485653766404444352/1499520683267592432).

Why

With Claude Code's Monitor tool now driving watch-tasks-stream.sh as the canonical persistent watcher (PR #693 retired the legacy one-shot watch-tasks.sh), the menu-bar Timer is purely a safety net for:

  • Monitor crashes
  • Session-restart races
  • tmux pane death

30s polling was overkill. 5 min keeps recovery in human-interactive territory (worst-case lag = ~5 min before auto-restart) while cutting 12× the menu-bar wake-ups → less battery, less log noise.

What this PR doesn't change

  • checkWatcher() body — idle-check, watcherKeystrokesQueued() guard, watcher keystroke send all unchanged
  • pgrep -f watch-tasks substring match — still matches both the legacy script name (gone) and the current watch-tasks-stream.sh
  • Health-check Timer (30 min) — separate cadence, unrelated

Test plan

  • swiftc -O compile clean (verified locally)
  • Reviewer to confirm worst-case 5 min stale window is acceptable for the watcher safety-net use case
  • Manual smoke test: kill watch-tasks-stream.sh → wait 5 min → confirm menu-bar nudges Claude Code with watcher keystroke

Tradeoff

A voice task landing the moment Monitor dies waits up to 5 min before the safety net kicks in. Mitigation: Monitor is persistent + has its own keepalive against tmux session lifetime, so this scenario is rare.

🤖 Generated with Claude Code

Per Chi 2026-05-14 23:15Z: with Claude Code's `Monitor` tool now
driving `watch-tasks-stream.sh` as the canonical persistent watcher,
the menu-bar Timer is purely a safety net (catches Monitor crash /
session-restart race / tmux pane death). 30s polling was overkill;
5 min keeps recovery in human-interactive territory (worst-case lag
= ~5 min stale before auto-restart) while cutting 12× the wake-ups.

No behavioral change beyond cadence — `checkWatcher()` body itself,
the "watcher" keystroke send, and the idle/queued-keystroke guards
all unchanged. Tradeoff documented inline.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

@sonichi sonichi left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM with 1 dead-code nit.

Strengths:

  • Surgical: 1-line behavior change, body of checkWatcher() untouched.
  • Comment block thoroughly preserves Chi's 2026-04-18 design context + names the new tradeoff explicitly.
  • pgrep -f watch-tasks substring still matches the current watch-tasks-stream.sh (verified via live pgrep -fl watch-tasks → matches bash src/watch-tasks-stream.sh).

Nit — dead code (not blocking): inner throttle at main.swift:458 is Date().timeIntervalSince(lastWatcherAlert) < 120 — that's 120s, but the outer Timer now fires every 300s. Two consecutive ticks are always ≥300s apart, so the throttle never gates anything anymore. PR body says "60s" but the actual throttle is 120s; both are subsumed by the new 300s cadence. Could either drop the throttle entirely or document why it's still useful (e.g. for the case where checkWatcher() is invoked from another path).

Tradeoff acknowledged: worst-case 5min stale window before safety-net kicks in. Reasonable since Monitor is the primary watcher with its own keepalive — this is a backstop. PR body already calls this out.

Build verified locally on the diff. No regressions visible. Cleared to merge from my read.

…imer)

Self-review: the inner `Date().timeIntervalSince(lastWatcherAlert) < 120`
gate at main.swift:465 was strictly dead code under the new 300s outer
Timer cadence — two consecutive ticks are always 300s apart, so the 120s
window never gated anything.

Drop the `lastWatcherAlert` var + the gate. Flood-protection is now
solely the `watcherKeystrokesQueued()` capture-pane check + the Timer
interval itself.

Comment block updated to document the removal context.

Build verified locally with swiftc -O.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@sonichi
sonichi merged commit fb03759 into main May 14, 2026
1 check passed
@sonichi
sonichi deleted the chore/check-watcher-5min branch May 14, 2026 23:34
liususan091219 pushed a commit to liususan091219/sutando-fork that referenced this pull request May 28, 2026
)

* chore(sutando-app): bump checkWatcher Timer from 30s → 5min

Per Chi 2026-05-14 23:15Z: with Claude Code's `Monitor` tool now
driving `watch-tasks-stream.sh` as the canonical persistent watcher,
the menu-bar Timer is purely a safety net (catches Monitor crash /
session-restart race / tmux pane death). 30s polling was overkill;
5 min keeps recovery in human-interactive territory (worst-case lag
= ~5 min stale before auto-restart) while cutting 12× the wake-ups.

No behavioral change beyond cadence — `checkWatcher()` body itself,
the "watcher" keystroke send, and the idle/queued-keystroke guards
all unchanged. Tradeoff documented inline.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(sutando-app): drop dead 120s inner throttle (subsumed by 300s Timer)

Self-review: the inner `Date().timeIntervalSince(lastWatcherAlert) < 120`
gate at main.swift:465 was strictly dead code under the new 300s outer
Timer cadence — two consecutive ticks are always 300s apart, so the 120s
window never gated anything.

Drop the `lastWatcherAlert` var + the gate. Flood-protection is now
solely the `watcherKeystrokesQueued()` capture-pane check + the Timer
interval itself.

Comment block updated to document the removal context.

Build verified locally with swiftc -O.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Chi <wangchi@Chis-Mac-mini.local>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant