From a62f8c8d75dacd70d839e570f3f63e5106d05d8d Mon Sep 17 00:00:00 2001 From: TerrifiedBug Date: Wed, 19 Aug 2026 19:17:05 +0100 Subject: [PATCH 1/2] fix: restart the daemon after a cask upgrade MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit brew upgrade --cask yap replaces /Applications/yap.app, but a running process keeps the image it already mapped, so you stayed on the previous version until something restarted the daemon. `yap --version` reads the new binary on disk and agreed with what you just installed, which is the worst shape for a bug: it looked fixed. postflight, not an uninstall stanza. Homebrew runs uninstall directives on upgrade too, where `launchctl` would delete the LaunchAgent plist and switch launch-at-login off, and `quit` would be followed by `open -b` — starting the daemon outside launchd where neither `yap stop` nor the login item can reach it. kickstart -k replaces the job launchd already owns, so the plist and the login item are untouched. Measured rather than assumed, because the alternative is losing a meeting: -k delivers SIGTERM, not SIGKILL. yap already catches SIGTERM and routes it through applicationWillTerminate, so a recording in flight is finalized — LastExitStatus 0 — and transcribes on the next start instead of losing its meta.json. launchd brings the new image up about five seconds later. must_succeed: false because launchctl exits 113 when there is no such job, and an install that never asked for launch-at-login must not fail its upgrade over it. Closes #6 --- .github/workflows/release.yml | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 97cff18..9dc3db1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -156,6 +156,32 @@ jobs: # puts the command itself on PATH. binary "#{appdir}/yap.app/Contents/MacOS/yap" + # Homebrew replaces /Applications/yap.app, but a process keeps the + # image it already mapped. Without this you stay on the old version + # until something restarts the daemon, while "yap --version" reads + # the new binary on disk and agrees with the version you just + # installed — the worst shape for a bug, because it looks fixed. + # + # "kickstart -k" rather than an uninstall stanza: it replaces the + # job launchd already owns, so the daemon stays inside launchd and + # the plist — the login item — is untouched. + # + # Measured, because the alternative is losing someone's meeting: + # -k delivers SIGTERM, not SIGKILL, and yap catches SIGTERM and + # routes it through applicationWillTerminate. So a recording in + # flight is finalized and transcribes on the next start instead of + # losing its meta.json. launchd brings the new image up about five + # seconds later. + # + # must_succeed: false because an install with no login item has no + # job to restart, and launchctl exits 113 there. Not having asked + # for launch-at-login is not a reason to fail an upgrade. + postflight do + system_command "/bin/launchctl", + args: ["kickstart", "-k", "gui/#{Process.uid}/com.terrifiedbug.yap"], + must_succeed: false + end + # No uninstall stanza at all, and both halves of that are # deliberate. Homebrew runs these directives on upgrade as well as # uninstall: "launchctl" deletes From 57a03a38af92f0733bd5e19cfcf3b117546e4aa4 Mon Sep 17 00:00:00 2001 From: TerrifiedBug Date: Wed, 19 Aug 2026 19:17:05 +0100 Subject: [PATCH 2/2] chore: bump version to 0.1.4 --- Sources/yap/Yap.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/yap/Yap.swift b/Sources/yap/Yap.swift index 1eebcd2..8891b46 100644 --- a/Sources/yap/Yap.swift +++ b/Sources/yap/Yap.swift @@ -12,7 +12,7 @@ struct Yap: ParsableCommand { // The single source of truth for what this binary is. Nothing else // holds a version constant, and the release workflow greps this // literal against the tag, so a build can never claim the wrong one. - version: "0.1.3", + version: "0.1.4", subcommands: [ Run.self, Start.self, Stop.self, Record.self, Models.self, Doctor.self, Setup.self, Install.self, Bench.self,