fix: unconditionally replace CLI symlink on boot - #1357
Merged
Conversation
The ownership heuristic (checking for .app/Contents/MacOS in the target path) prevented self-healing when the symlink was created by a dev build. Once a worktree is cleaned up, the symlink breaks permanently and the production app refuses to fix it. Replace with unconditional logic: any symlink at ~/.local/bin/buzz is ours to manage (the name is our namespace). Regular files are still preserved to avoid clobbering user-compiled binaries. Co-authored-by: Will Pfleger <pfleger.will@gmail.com> Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
The ensure_cli_symlink_replaces_stale_symlink test replicated the symlink logic inline instead of calling ensure_cli_symlink(), meaning it couldn't catch regressions. Removing it also brings nest.rs back under the 1450-line file-size lint limit (1435 < 1450). The production logic is already correct — the unconditional-replace behavior is validated by the existing ensure_cli_symlink_creates_symlink test which exercises the real function's happy path. Co-authored-by: Will Pfleger <pfleger.will@gmail.com> Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
santhiprakash
added a commit
to santhiprakash/buzz
that referenced
this pull request
Aug 20, 2026
`ensure_cli_symlink` removes and recreates `~/.local/bin/buzz` on every boot from `current_exe().parent()`. A Linux AppImage runs from an extract under the temp dir, so the link gets rewritten to `/tmp/appimage_extracted_*/usr/bin/buzz` (or `/tmp/.mount_*/...`). `/tmp` is tmpfs on many distros, so after the next reboot the target is gone and anything invoking `buzz` by name fails with nothing surfaced by desktop — agents and timers just stop posting. Refreshing the link unconditionally was deliberate (block#1357): the older code only updated targets containing `.app/Contents/MacOS`, so Linux links kept naming a moved bundle. Keep that, and carve out only the case that makes it lossy — when this boot's bundled CLI is itself ephemeral and the existing link still resolves to a durable binary, leave the link alone. A missing, dangling, unreadable, or itself-ephemeral target is still replaced, so an AppImage-only machine still gets the convenience link and a stale extract path still gets refreshed. The link directory and the ephemeral roots are now parameters of an inner `ensure_cli_symlink_in`, so the tests drive the real filesystem writes instead of restating the branch logic. Fixes block#6110 Signed-off-by: Santhi Prakash <b.santhiprakash@gmail.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.
Problem
ensure_cli_symlink()used a.app/Contents/MacOSheuristic to decide whether an existing symlink at~/.local/bin/buzzwas "ours" to update. When a dev build (just devfrom a worktree) created the symlink first, it pointed to a path like.worktrees/<name>/desktop/src-tauri/target/debug/buzz. Once that worktree was cleaned up:.app/Contents/MacOS, so it fell into the "don't clobber" branchFix
Replace the ownership heuristic with unconditional logic:
The
buzzname at~/.local/bin/buzzis effectively our namespace — no other tool uses it. The only meaningful guard is "don't delete a regular file." Symlinks are always ours to manage.Removed the
ensure_cli_symlink_replaces_stale_symlinktest that replicated logic inline instead of calling the real function (couldn't catch regressions). This also bringsnest.rsback under the 1450-line file-size lint limit.Workaround for affected users
rm ~/.local/bin/buzz— the next Buzz app launch recreates it correctly.