fix: make orchestration work when wmux isn't on PATH (fall back to $WMUX_CLI) - #5
Open
tawman wants to merge 2 commits into
Open
fix: make orchestration work when wmux isn't on PATH (fall back to $WMUX_CLI)#5tawman wants to merge 2 commits into
tawman wants to merge 2 commits into
Conversation
The orchestrator calls bare wmux from non-interactive shells (Claude Code's Bash tool, hook scripts). A patched wmux puts a wmux shim on those shells' PATH; on an un-patched/upstream wmux it isn't there. Add scripts/wmux-resolve.sh (defines a wmux() -> node $WMUX_CLI fallback), sourced from orchestration-state.sh (covers all callers that use it) and directly in the standalone detect-wmux.sh. Defining the function makes existing 'command -v wmux' guards pass, so no other call sites change. Mirrors the app-bundled copy in tawman/wmux.
… skills
Corrections and additions from running real Claude Code orchestrations,
so the skills match how orchestration actually behaves:
- orchestrate Phase 7: completion signal is the RESULT FILE, not process
exit — launch-agent.js runs agents interactively, so a finished agent
idles at its TUI and never exits; the old "poll agent list for exited"
loop never terminates. Also: the coordinator owns state.json (Stop/
SubagentStop hooks don't fire for wmux-spawned agents), and the sidebar
only counts status vocabulary exited (agents) / complete (waves, run).
- orchestrate Phase 6b: bare agent ids ("a", not "agent-a" — scripts
prefix agent- themselves; the old schema was self-inconsistent),
forward-slash paths in state.json, TMPDIR alignment on Git Bash so the
sidebar cockpit sees the run.
- Pane hygiene: start from a single coordinator pane (re-gridding over
leftover panes orphans their surfaces as dead tabs), collapse after.
- Nudging workers: wmux send targets the CALLER's surface by default —
always pass --surface; agent kill doesn't kill agents' child processes.
- New references/browser-driving.md: CLI sharp edges for the browser
panel (bare refs, single persistent eval scope, snapshot parsing,
React/Radix synthetic-event recipes, transient-UI polling caveat,
port-9222 CDP collision).
- wmux-detect: note the $WMUX_CLI fallback.
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.
The problem we hit
We use this plugin heavily for Claude Code orchestration on Windows. On a fresh wmux install, orchestration silently degrades:
spawn-agents.shwarns "wmux not found in PATH" and drops to subagent mode, and the dashboard/notify hooks are skipped. Until now the only fix was hand-installingwmuxshims into~/.local/binon every machine.Root cause
The plugin's scripts run as non-interactive bash (Claude Code hooks / Bash tool) and call bare
wmux, guarded bycommand -v wmux. But wmux only provides thewmuxcommand as an interactive shell function (via shell-integration), which doesn't propagate tobash -cchildren — so the guard fails even though wmux is running and reachable. What those shells do always have is$WMUX_CLI: wmux injects the CLI-script path into every shell it spawns.The fix
scripts/wmux-resolve.sh(new, 3 lines of logic):Sourced from
orchestration-state.sh(which every wmux-calling script already sources) and from the standalonedetect-wmux.sh. Defining a function makes the existingcommand -v wmuxguards pass, so no other call sites change. No-op when a realwmuxis on PATH; Node is guaranteed (Claude Code runs on it).Also adds
.gitattributeswith*.sh text eol=lf— on a Windows clone withcore.autocrlf=true, checkout otherwise flips the scripts to CRLF and breaks their shebangs. Existing blobs are already LF, so this renormalizes nothing.Verification
wmuxabsent from PATH and$WMUX_CLIset (any wmux-spawned shell),detect-wmux.shnow printsavailableandwmux ping→pongthrough the fallback.~/.local/binshims installed.Related: amirlehmam/wmux#75 fixes the same gap at the root (wmux putting a
cli-binshim dir on spawned shells' PATH). This fallback makes the plugin work on current and older wmux releases without waiting for that.Also: orchestration lessons learned, folded into the distributed skills
We have been running heavy multi-agent Claude Code orchestrations on wmux, and this PR also contributes that operating knowledge back into the distributed skills so they match how orchestration actually behaves:
skills/orchestratePhase 7 (monitoring) corrected — the completion signal is the agent's result file, not process exit:launch-agent.jsruns agents interactively, so a finished agent idles at its TUI and never exits, and the previous "pollwmux agent listforexited" loop never terminates. The skill now polls result files, and documents that the coordinator ownsstate.json(Claude Code Stop/SubagentStop hooks don't fire for wmux-spawned agents) using the status vocabulary the sidebar actually counts (exitedfor agents,completefor waves/run)."a", not"agent-a"): the scripts prefixagent-themselves, so the old schema example produced double-prefixed prompt/result filenames the launcher couldn't find.TMPDIRwith the temp dir the sidebar watches (Git Bash), forward-slash paths instate.json(backslashes are invalid JSON escapes and freeze the cockpit), retry reads that race the app's 1 s poller.wmux sendtargets the caller's own surface by default (use--surface);agent killdoesn't kill agents' child processes (sweep orphaned dev-server ports).skills/orchestrate/references/browser-driving.md— field recipes for agents driving the browser panel: bareeNrefs, the single persistentevalscope (IIFE), snapshot parsing, React/Radix synthetic-event input recipes, the transient-UI polling caveat, and the port-9222 CDP collision warning.