feat: in-app auto-updater#35
Merged
Merged
Conversation
Adds a complete in-panel auto-update flow for stack-nudge: - UpdateChecker polls GitHub Releases on launch + every 6h with a graceful fallback through `gh api` so private-repo users with authenticated gh CLI still get update prompts. - Settings tab surfaces a dot badge and a pinned "Update available · vX.Y.Z" row at the top of the list when a newer release exists. - Confirmation step renders the release-notes markdown (parsed into headings + bullets + inline links) before kicking off the install. - Install runs in a detached session (Python fork + setsid) so it survives install.sh's pkill of the running panel, with a phase progress UI driven by STAGE markers and a fallback heuristic for pre-marker install.sh versions. - Welcome-style PostUpdateView auto-opens on the first launch after a successful update, showing exactly what shipped via a tag-specific release-notes fetch. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a complete in-panel auto-update flow for stack-nudge — no external installer required, no curl-pipe re-runs. Org members with
ghCLI auth can update from any prior release to the latest with one keypress.What lands
UpdateCheckerpolls GitHub Releases on launch + every 6h. Falls back throughgh apifor private repos so authenticated org members get prompts transparently.git clone --depth 1of the latest tag, theninstall.shruns in a detached session (Python fork + setsid) so it survivesinstall.sh's pkill of the running panel mid-flight.Cloning → Building → Voice engine → Launchd → Hooks → Done) driven by# STAGE:markers, with a heuristic fallback for olderinstall.shversions that lack the markers. Expandable "Show output" reveals the raw install log.releases/tags/v…, sameghfallback). Enter or "Got it" dismisses.How private-repo updates work
gh api repos/StackOneHQ/stack-nudge/releases/<latest|tags/vX.Y.Z>is invoked when the unauthenticated GitHub API returns 404. Theghbinary lives at well-known homebrew paths so launchd's minimal PATH doesn't bite us. The user's existing gh auth (PAT / device flow) does the work — no token storage in stack-nudge.Files
panel/UpdateChecker.swift(new) — release polling, version compare, gh fallbackpanel/Updater.swift(new) — runner script, log tailing, phase parsing, PostUpdateView, UpdateConfirmView, UpdatingView, MarkdownNotesViewpanel/Panel.swift— wire UpdateChecker + Updater, new modes inPanelContentView, keyboard handling for.updateConfirm/.updating/.postUpdate,handlePostUpdateStatus()on launchpanel/PanelNav.swift—.updateConfirm/.updating/.postUpdatemodes + state fields,updateRowOffsetandbeginUpdate/runUpdateactionspanel/Settings.swift— conditional update row at index 0, all subsequent rows shift via the offsetinstall.sh—# STAGE: building|venv|launchd|hooks|donemarkers so the panel can show real progressbuild.sh— compile the two new sourcesValidated locally
~/Applications/stack-nudge.app, reload launchd, status file writtenNotes for reviewers
os.fork() + os.setsid()dance is required becauseFoundation.Processspawns children as process-group leaders, which makessetsid(and therefore session detachment) fail with EPERM. Forking once gives the grandchild a non-leader pid so setsid succeeds.Test plan
🤖 Generated with Claude Code