fix: fall back to PATH when the baked agtermctl path is gone - #473
Merged
umputun merged 1 commit intoAug 21, 2026
Merged
Conversation
bot-rogerthat
force-pushed
the
fix/agtermctl-path-fallback
branch
from
August 20, 2026 21:35
49fbf82 to
6eb5c52
Compare
The agent-status hooks bake the running bundle's absolute agtermctl path into
the installed wrappers, and the call site is "${AGTERMCTL:-agtermctl}", so the
PATH rung the wrapper documents is unreachable once anything is baked. A bundle
that moves after the install - installing from the mounted DMG bakes /Volumes,
dead on eject - leaves the wrapper pointing at nothing, and it suppresses output
and exits 0 by design, so every status update fails silently.
Bake a block that tests the path before committing to it, inside the unset
branch so an explicit override is still first. The transform moves to host-free
AgentHooksInstall, which makes it testable and lets the strip count come from
the block being emitted rather than a literal that has to be kept in step.
Fixes umputun#472
bot-rogerthat
force-pushed
the
fix/agtermctl-path-fallback
branch
from
August 20, 2026 21:36
6eb5c52 to
abb1ebb
Compare
umputun
added a commit
that referenced
this pull request
Aug 21, 2026
follow-up to #473, all maintainer cleanup. `agtermctlMarker` was public with no consumer outside agtermCore, since both test suites reach it through `@testable`, and that re-opened surface d54b50f had just closed in this same file. Internal now. `stripBakedBlock`'s comment claimed that deriving the skip count from the emitted block meant growing that block could not leave half the old one behind. It is the other way round: the count measures what is being WRITTEN and is applied to what a previous install wrote, so any length change mis-strips, over-eating the script when the new block is longer. Nothing reaches it because `copyBundledFolder` re-copies the pristine wrapper before every bake, which is what the comment now says instead. The rest is trimming. #473's doc comment ran eight lines over a two-line body and repeated the moved-bundle rationale on four surfaces; the wrapper's own header owns it, so the Swift side points there and the restatement in `AgentHooksInstaller` is gone. Three test comments come back to one line, keeping the `#472` reason a regression test is entitled to. The agent-skill troubleshooting entry for a stuck glyph named neither the moved-bundle cause nor either recovery, so an installed agent had nothing to tell a user whose baked path went dead.
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.
Fixes #472.
The problem
AgentHooksInstaller.bakeAgtermctlPathwritesBundle.main's absoluteagtermctlpath into the two installed wrappers, and the wrappers call it as"${AGTERMCTL:-agtermctl}". That default only fires whenAGTERMCTLis empty, so the PATH rungagterm-agent-status.shdocuments as step 3 is unreachable in any wrapper that was baked — and nothing ever checks whether the baked path still exists.A bundle that moves after the install therefore kills the hooks. Installing from the mounted DMG is the easy way in:
Bundle.mainis/Volumes/agterm/agterm.appthen, and the baked path dies on eject. The wrapper suppresses stdout/stderr and exits 0 by design, so nothing surfaces — the sidebar glyphs just stop appearing. Mine had been dead for weeks.The fix
Bake a block that tests the path before committing to it:
Both the assignment and the test sit inside the unset branch, so an explicit
AGTERMCTLoverride is never second-guessed and the documented order stays 1 > 2 > 3. A moved bundle now degrades to the CLI from Help ▸ Install Command Line Tool… instead of going silent. Re-running the installer still heals the path outright; this is what covers the window before anyone thinks to.The transform moves into host-free
AgentHooksInstall— the type the rules already put in charge of the marker and merge policy — leavingAgentHooksInstallerthe file glue. That is what makes it testable at all: the app-side helpers wereprivatein a targetswift testcannot reach, which is why the bake/strip pair had no coverage. It also letsstripBakedBlocktake its line count from the block being emitted rather than a literalskip = 1that would have silently gone stale as the block grew from one line to four.Tests
agtermCore, all new:AgentHooksInstallTests— block lands after the shebang, carries the-xfallback inside the unset branch, and a re-bake replaces the block rather than stacking it (a second bake over a/Volumesone equals a first bake with the new path).AgentStatusWrapperTests— bakes the shipped wrapper through the installer's own transform and runs it with three stub binaries that record which of them was invoked: the baked one wins when it exists, PATH wins when the baked bundle is gone, and an explicitAGTERMCTLwins over both.The two fallback tests fail on the previous block (the run records nothing at all, which is the bug), and the other two pass either way, so they pin the behavior that must not change.
What I ran
cd agtermCore && swift test— green, 2607 tests.swiftlint lint --strict— 0 violations in 344 files.bash -nover both wrappers with the block baked in, and a standaloneswiftc -typecheck -swift-version 6 -strict-concurrency=completeof the changedAgentHooksInstaller.swiftagainst the builtagtermCore.I could not run
make buildormake test-app: this machine has Command Line Tools only, no Xcode 26, soscripts/setup.sh,xcodegenand the app target are out of reach here. The app-target change is the deletion of three private helpers and one call intoagtermCore, but it has not been compiled in the real project and no XCUITests were run.No user-facing action or control command changes, so no skill or
site/update.site/docs.htmlsays the scripts are installed "with the bundled agtermctl's absolute path baked in so they work even without the CLI on your PATH", which stays true.