Skip to content

Post-v1.14 polish: updater relaunch, sessions polling, widget toggle#69

Merged
hiskudin merged 5 commits into
mainfrom
fix/post-1.14-polish
Jun 2, 2026
Merged

Post-v1.14 polish: updater relaunch, sessions polling, widget toggle#69
hiskudin merged 5 commits into
mainfrom
fix/post-1.14-polish

Conversation

@hiskudin

@hiskudin hiskudin commented Jun 2, 2026

Copy link
Copy Markdown
Collaborator

Pinned to v1.14.1 via a Release-As: 1.14.1 trailer on the widget-toggle commit, so release-please cuts a patch rather than a minor despite the feat: prefix.

Summary

  • Updater relaunch — after launchctl kickstart (which silently fails when no panel launchd agent is registered or the running process lives outside ~/Applications), explicitly call NSWorkspace.openApplication on the swapped bundle with createsNewApplicationInstance=true. The 2-second auto-quit then cleanly kills the old process, leaving only the new bundle. Fixes the "I clicked Update but the version still says old" bug.
  • Post-update render order — set compactExpanded = true and force applyCompactLayout() synchronously before flipping nav.mode = .postUpdate. Stops PostUpdateView (or a transient Events render) from being drawn into the still-pill-sized 320×56 window for one frame.
  • Sessions polling at app launchSessionStore.startPolling() is now called in applicationDidFinishLaunching instead of gated on the Sessions tab's onAppear. Pill shows the correct busy session immediately without requiring the user to visit the Sessions tab first. Sessions .onDisappear { stopPolling } removed so leaving the tab doesn't freeze the pill again.
  • Widget toggle (Settings → Widget → "Widget", default On) — restores the off-switch removed in PR feat: compact pill widget with mascots, ring gauge, drag-snap #65. When Off: pill disappears, hotkey shows/hides the full panel (classic mode), M shortcut + "Compact" footer hints no-op / disappear, dependent rows (Widget corner / Mascot / Pill opacity) grey out. Persists as STACKNUDGE_COMPACT_MODE.
  • README pivot — every voice/sound/banner setting now has a Settings row, so 5 "edit ~/.stack-nudge/config" blocks were stale. Replaced each with a "Settings → ..." breadcrumb, dropped exposed config keys, added one line under Settings noting the config file is the underlying persistence (not for direct editing). Expanded the Settings-tab row inventory to include the Widget section + Show remaining.

Test plan

  • Update flow: click Settings → "Update available", confirm, watch progress. New bundle replaces, old process terminates, new process launches at the new version.
  • Launch app while a Claude session is busy → pill headline shows the busy session immediately without opening the main panel.
  • Post-update changelog renders in the full panel (not squished into a pill frame).
  • Settings → Widget → toggle "Widget" Off → pill vanishes; hotkey toggles full panel show/hide. M shortcut + "Compact" footer hints are absent from Events/Sessions/Usage tabs. Toggle back On → pill returns, hints come back.
  • Esc to pill → banner fires → click in the banner region → pill stays as pill (the banner-veto fix from the merged PR fix(compact): banner-veto, pill opacity, mascot reactions, post-update expand #67 still in effect).

🤖 Generated with Claude Code

hiskudin and others added 5 commits June 2, 2026 14:16
Updater bug:
  After a successful atomic swap to ~/Applications/StackNudge.app, the
  updater calls `launchctl kickstart -k gui/<uid>/com.stackonehq.stack-nudge`
  to restart. When no panel launchd agent is registered (users who never
  ran the Bootstrap install, or dev builds running outside ~/Applications),
  kickstart silently fails and scheduleAutoQuit then kills the panel with
  nothing to bring it back. User is stuck on the old binary in memory.
  Now: after kickstart, NSWorkspace.openApplication launches the new
  bundle explicitly with createsNewApplicationInstance=true so it starts
  even when an old-path process is still alive.

Post-update render order:
  handlePostUpdateStatus set nav.mode = .postUpdate BEFORE
  nav.compactExpanded = true. The mode flip triggered a SwiftUI re-render
  that rendered PostUpdateView (or even the still-active Events page mid-
  transition) into the pill-sized 320×56 window — looked crushed. Resize
  the window first; then change the mode so SwiftUI sees both together
  in a full-panel-sized frame.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The pill (CompactView) reads sessions.sessions for the busy-session
headline and mascot state, but SessionStore.startPolling() was only
called from Sessions.swift's .onAppear — so the pill displayed stale
data until the user visited the Sessions tab once. Worse, Sessions
.onDisappear called stopPolling, freezing the pill again on exit.

Now: start polling in PanelController.applicationDidFinishLaunching
and drop the Sessions .onDisappear stop. The Sessions .onAppear still
calls startPolling as an idempotent safety. 3s interval, ps + filesystem
scan only — cheap enough to run for the app's lifetime.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Pivot to UI-first documentation: every voice/sound/banner setting now
has a Settings row, so README's "edit ~/.stack-nudge/config" blocks
were stale. Replaced each with a "Settings → ..." breadcrumb, dropped
config-key references, and added one line under Settings noting that
the config file is the underlying persistence (not for direct editing).

Also expanded the Settings-tab row inventory to include the Widget
section (corner, mascot, pill opacity) and the new Usage "Show remaining"
toggle.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Brings back the off-switch that was removed in PR #65. Users who don't
want the pill can disable it and get classic show/hide-the-panel
behavior; hotkey toggles the full panel like before, and the M shortcut
+ "Compact" footer hints no-op / disappear when widget is off.

Persists as STACKNUDGE_COMPACT_MODE (default true). Widget corner,
mascot, and pill opacity rows grey out while widget is off so the
implication is obvious. Toggling off also clears compactExpanded so the
window restores to its saved full-panel size cleanly.

Release-As: 1.14.1

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Settings → Widget → "Pill opacity" renamed to "Widget opacity" so the
  Widget section uses consistent terminology (Widget / Widget corner /
  Mascot / Widget opacity).
- Toggling the Widget switch On from Settings used to immediately
  collapse the open panel into the 320×56 pill — but the CompactView
  rendered inside the still-large frame for a frame, looking like a
  giant pill. Set compactExpanded=true when toggling on so the user
  stays in the full panel; the pill takes effect on the next Esc /
  focus-loss instead.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@hiskudin hiskudin merged commit ddb1f9f into main Jun 2, 2026
5 checks passed
@hiskudin hiskudin deleted the fix/post-1.14-polish branch June 2, 2026 17:06
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