Follow-on from #152, and I think it undercuts that fix rather than contradicting it. The block is right to make the reader check instead of assume. The problem is what the check can actually tell them.
The conflation
resources/claude-instructions.md:18:
If it does not answer — command not found, no reply, or an error — then wmux
is not running for this session. Ignore the whole section and use your normal
tools.
Three symptoms, one conclusion. But they are not the same fact:
- no reply on the pipe: wmux is not running. Ignoring the section is correct.
- command not found: says nothing about whether wmux is running. It says this session cannot reach the CLI.
The block instructs the reader to treat the second as the first.
Why the second case is the common one, not the exotic one
Verified from source: src/main/pty-manager.ts:323-341 prepends the shim dirs to the environment of PTYs wmux spawns, with the comment "Make bare wmux resolvable in every spawned shell AND all its children". That is the only place PATH is touched. There is no setx, no registry write, nothing that persists PATH anywhere in src/.
So wmux resolves inside a pane and its children, and nowhere else unless the user put it on PATH by hand. Every session wmux did not spawn - the Claude Code desktop app, a plain terminal, an SSH session, a scheduled run, a session that was already open before wmux started - has no wmux on PATH by default.
That is precisely the population #152 rewrote the block for. The block loads globally so it can reach sessions that are not inside wmux, and then hands those sessions a probe that, for most of them, fails for a reason the block does not account for.
Live, on this machine
Verified: wmux 0.50.0 running (20 processes), pid 28680 listening on 127.0.0.1:9222, named pipe answering. And:
$ wmux ping
bash: wmux: command not found
PS> wmux ping
wmux : The term 'wmux' is not recognized as a name of a cmdlet, function, script file, or executable program.
Following the block, every agent on this machine concludes wmux is absent and stops using the browser panel. wmux is fine. Only the entry point is missing.
How it got there: I took the in-app update to 0.50.0, the installer re-offered the install location, and I chose "All Users of this computer" where the previous install had been per-user. The root moved from %LOCALAPPDATA%\Programs\wmux to C:\Program Files\wmux and the old directory was removed. The PATH entry pointing at the old resources\cli-bin was one I had added by hand, so the dangling entry is mine. The part that is not mine is that a probe the block presents as authoritative now returns a false negative and the reader has no way to notice.
Separable second point
build/installer.nsh opens with:
wmux installs to the same path on every update
With oneClick: false and allowToChangeInstallationDirectory: true (electron-builder.json:32-38) and no perMachine pin, an update can land in a different root than the install it replaces, because the assisted installer re-offers scope and directory mid-update. That is what happened here. It invalidates the stated invariant, and with it any absolute path anyone recorded: PATH entries, shortcuts, scripts, and the install path documented in wmux's own notes.
Whether that is a bug or a feature is your call, and it is genuinely separable from the probe question. Say the word and I will file it on its own rather than leave it buried here.
Options
- Interpolate the path the writer already knows.
ensureClaudeContext() (src/main/claude-context.ts:113) splices the block from a static file, and it runs in the main process, which knows process.resourcesPath. A placeholder in claude-instructions.md replaced at splice time would let the failure branch say: if wmux is not found, wmux may still be running, try <absolute cli-bin path>\wmux ping before concluding it is absent.
- Persist PATH from the app, ideally with consent.
- Split the guidance only, no path: tell the reader that "not found" and "no reply" mean different things and that only the second is evidence of absence.
- Leave it.
I lean 1, and I want to flag why it does not repeat the mistake #152 fixed. That was a write-time fact read at an arbitrarily later time by someone else, which nothing at generation time could make true. This one is different in the way that matters: the writer is the installed build itself, it is writing its own location, and it rewrites the block on every startup. It self-heals across exactly the relocation that broke it here - the 0.50.0 instance that rewrote my CLAUDE.md today already knew its new resourcesPath while writing text that pointed the reader at PATH instead.
2 is heavier than the problem, cannot help sessions already running, needs uninstall cleanup, and sits badly next to 58f2301 asking before writing to ~/.claude. 3 is the honest minimum and pairs well with 1. 4 is defensible only if out-of-pane sessions are not meant to drive wmux at all, and #153 shipping --surface for callers with no WMUX_SURFACE_ID, now documented in the block, says otherwise.
Happy to send whichever you pick, including just 3 if you would rather not put a machine path in the block.
Follow-on from #152, and I think it undercuts that fix rather than contradicting it. The block is right to make the reader check instead of assume. The problem is what the check can actually tell them.
The conflation
resources/claude-instructions.md:18:Three symptoms, one conclusion. But they are not the same fact:
The block instructs the reader to treat the second as the first.
Why the second case is the common one, not the exotic one
Verified from source:
src/main/pty-manager.ts:323-341prepends the shim dirs to the environment of PTYs wmux spawns, with the comment "Make barewmuxresolvable in every spawned shell AND all its children". That is the only place PATH is touched. There is nosetx, no registry write, nothing that persists PATH anywhere insrc/.So
wmuxresolves inside a pane and its children, and nowhere else unless the user put it on PATH by hand. Every session wmux did not spawn - the Claude Code desktop app, a plain terminal, an SSH session, a scheduled run, a session that was already open before wmux started - has nowmuxon PATH by default.That is precisely the population #152 rewrote the block for. The block loads globally so it can reach sessions that are not inside wmux, and then hands those sessions a probe that, for most of them, fails for a reason the block does not account for.
Live, on this machine
Verified: wmux 0.50.0 running (20 processes),
pid 28680listening on127.0.0.1:9222, named pipe answering. And:Following the block, every agent on this machine concludes wmux is absent and stops using the browser panel. wmux is fine. Only the entry point is missing.
How it got there: I took the in-app update to 0.50.0, the installer re-offered the install location, and I chose "All Users of this computer" where the previous install had been per-user. The root moved from
%LOCALAPPDATA%\Programs\wmuxtoC:\Program Files\wmuxand the old directory was removed. The PATH entry pointing at the oldresources\cli-binwas one I had added by hand, so the dangling entry is mine. The part that is not mine is that a probe the block presents as authoritative now returns a false negative and the reader has no way to notice.Separable second point
build/installer.nshopens with:With
oneClick: falseandallowToChangeInstallationDirectory: true(electron-builder.json:32-38) and noperMachinepin, an update can land in a different root than the install it replaces, because the assisted installer re-offers scope and directory mid-update. That is what happened here. It invalidates the stated invariant, and with it any absolute path anyone recorded: PATH entries, shortcuts, scripts, and the install path documented in wmux's own notes.Whether that is a bug or a feature is your call, and it is genuinely separable from the probe question. Say the word and I will file it on its own rather than leave it buried here.
Options
ensureClaudeContext()(src/main/claude-context.ts:113) splices the block from a static file, and it runs in the main process, which knowsprocess.resourcesPath. A placeholder inclaude-instructions.mdreplaced at splice time would let the failure branch say: ifwmuxis not found, wmux may still be running, try<absolute cli-bin path>\wmux pingbefore concluding it is absent.I lean 1, and I want to flag why it does not repeat the mistake #152 fixed. That was a write-time fact read at an arbitrarily later time by someone else, which nothing at generation time could make true. This one is different in the way that matters: the writer is the installed build itself, it is writing its own location, and it rewrites the block on every startup. It self-heals across exactly the relocation that broke it here - the 0.50.0 instance that rewrote my
CLAUDE.mdtoday already knew its newresourcesPathwhile writing text that pointed the reader at PATH instead.2 is heavier than the problem, cannot help sessions already running, needs uninstall cleanup, and sits badly next to 58f2301 asking before writing to
~/.claude. 3 is the honest minimum and pairs well with 1. 4 is defensible only if out-of-pane sessions are not meant to drive wmux at all, and #153 shipping--surfacefor callers with noWMUX_SURFACE_ID, now documented in the block, says otherwise.Happy to send whichever you pick, including just 3 if you would rather not put a machine path in the block.