fix(shell-integration): resync all three packaged copies with src - #169
Conversation
`resources/shell-integration/` is a checked-in copy of `src/shell-integration/` that nothing keeps in step, and all three files had drifted: wmux-bash-integration.sh missing the `wmux()` function wmux-cmd-integration.cmd missing `chcp 65001` wmux-powershell-integration.ps1 19 insertions, 65 deletions behind The PowerShell one is the interesting case. Its copy predates issue amirlehmam#72, so `Send-WmuxMessage` sends V1 lines with no `auth <token> ` prefix — and pipe-server.ts rejects every V1 command but `ping` without one. Anything running that copy reports no cwd, no git branch, no shell state, no PR: the pipe answers `unauthorized` and the integration has no way to notice. It also predates the UTF-8 console setup, the `wmux` function, deferring the PR-poll job off the first-prompt critical path, and `WMUX_STARTUP_COMMANDS` (issue amirlehmam#32). Copied from master's own `src/`, so the three files are now byte-identical to their sources; `diff -r src/shell-integration resources/shell-integration` is empty. Worth knowing before deciding how much this matters: no release path reads these files. electron-builder's extraResources maps `src/shell-integration` → `shell-integration`, step 7 of the release process copies `src/shell-integration/*` into the staging dir, and `getShellIntegrationPath()` falls back to `src/shell-integration` in dev. So a packaged wmux has always run the fresh source, and none of the breakage above ever reached a released install. What does read `resources/shell-integration/` is anything consuming wmux out of a repo checkout — which is how the drift was found; a devcontainer integration sources the bash copy from there. That makes this the same shape as `resources/cli/wmux.js`, which is 1519 diff lines behind a build of master's own `src/` for the same reason: a duplicate with no enforcement. Resyncing fixes today's drift and guarantees tomorrow's. Two ways out, both happy to send as a follow-up — say which you prefer: - a CI step that fails when `resources/` does not match a fresh copy/build, covering the shell scripts and `resources/cli/*.js` together; or - delete `resources/shell-integration/` outright and point checkout consumers at `src/shell-integration/`, since nothing wmux ships or runs reads it. The second is the smaller repo, but it breaks any external consumer already reading the old path, so it is your call rather than mine. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Both PRs ended by asking which direction I wanted for the checked-in duplicates. This is the answer: keep them, and check them. resources/shell-integration/ is a copy of src/shell-integration/, and resources/cli/*.js a copy of the tsc output in dist/cli/. Nothing kept either in step and both had rotted — the packaged PowerShell integration predated the pipe's auth gate, so it sent V1 lines with no token and every report was rejected into a void with no way to notice, and the CLI copy was ~1700 diff lines behind its own source. That is exactly #137, where a second copy of the app icon went stale for three releases: a duplicate with no enforcement is not a duplicate, it is a time bomb. #169 resynced today's drift; this stops tomorrow's. Deletion was the other option offered and is not taken here. Nothing wmux ships reads either directory (extraResources maps src/shell-integration and dist/cli), but external consumers read them out of a repo checkout — which is how the drift was found — and removing a path they depend on is not something to do silently in a patch release. Split by what each half costs: - npm test covers shell-integration, which needs no build, so the check gates a release through CI's existing test step. - npm run verify:resources covers the CLI artifacts too, and CI runs it after build:main, which is what makes dist/cli exist. It skips loudly rather than passing quietly when dist/ is absent — a check that silently does nothing reads as coverage it is not providing. resources/cli/*.js is regenerated here to make the invariant true.
|
Merged in 1.0.1. The PowerShell one is worse than "drifted", and I want it recorded properly: that copy predates #72, so Confirmed on the merged file: if ($env:WMUX_PIPE_TOKEN) { $Message = "auth $($env:WMUX_PIPE_TOKEN) $Message" } # line 24
if ($pipeToken) { $msg = "auth $pipeToken $msg" } # line 123Both call sites, and You were right to lead with "no release path reads these files" rather than let me over-rate the severity. The follow-up, decidedYou offered a CI step or deletion. I took the CI step, in this release, so you don't need to send it:
One test in there names the auth prefix directly rather than leaving it to the byte comparison, because that's the property whose absence was invisible. A future edit that drops it should fail as "the PowerShell integration no longer authenticates", not as "the files differ". Not deletion, though it's the tidier repo. Nothing wmux ships reads either directory, but you read them out of a checkout and you're unlikely to be the only one; removing a path external consumers depend on isn't a thing to do silently in a patch release. If you'd still rather move, say so — I'll deprecate the path in a minor and drop it in the one after, and you get to be the reason it's safe. Worth saying plainly: this is #137 again. That was a second copy of the app icon going stale for three releases, and the lesson written down at the time was that a duplicate has exactly one source. I resynced that one and didn't add a check, so the same failure just recurred in two other directories. It's checked now. What I verified, and what I didn'tVerified: Not verified: your specific end-to-end check — a PowerShell pane launched from a repo checkout showing cwd and branch in the sidebar. The packaged copy is now byte-identical to Thanks — the auth-token finding is the kind of thing that stays broken for years because nothing ever raises its hand. |
Claude Code increasingly runs in a Linux devcontainer while wmux runs on Windows. Nothing in that container can open \\.\pipe\wmux, so the CLI, the hooks and the shell integration all failed silently: no cwd, no git branch, and a sidebar stuck on "Running" forever. The bridge from issue #78 is most of the answer already — it just could not reach the pipe from where it needed to run. Three pieces close the gap: * connectTransport() learns npiperelay.exe, so `wmux bridge` can run INSIDE WSL2 and still reach the Windows pipe over interop. That placement is the security property: 0.0.0.0 there is the WSL2 namespace, reachable from containers on the host and not from the LAN, with no firewall rule. AF_VSOCK, a Windows-side listener and cross-boundary Unix sockets were tried first and are documented as rejected in the code. * The bridge keeps relays warm and tears down half-close-aware. Spawning npiperelay measures ~7s on an AV-scanned corporate host, and destroying both sides on either 'close' killed the frame of any client that writes and hangs up — which is every Claude Code hook. Deadlines gain a floor on the slow transports for the same reason; the 5s default sat below the round-trip, so calls that had already succeeded were reported as timeouts. * `wmux raw-v1` gives the bash integration a way to send its V1 lines through the CLI's transport instead of a temp file it cannot write to, and wmux-hook.js gets the same TCP branch. report_startup_command is new and rides the same path: a shell declares how to bring its own surface back, stored per surface, so a restored pane re-enters its container instead of coming up as a bare WSL prompt. docs/DEVCONTAINER.md is the standalone setup — one binary, one command, two environment variables, no vendor tooling. Two things ride along that were separate commits in #166, because on current master they have nothing to stand on their own for. The npiperelay lookup splits PATH on path.delimiter and falls back to process.env.Path — the Windows spelling — which only matters for the finder this commit introduces; #168 landed the rest of that change and deliberately left this half behind. And resources/shell-integration/wmux-bash-integration.sh is updated in step with its source, which #169 plus the check in 42e3cca now require: the packaged copy was resynced from a pre-bridge src/, so it has the `wmux` shim but not the WMUX_REMOTE branch, and leaving it that way fails npm test. Co-Authored-By: Claude <noreply@anthropic.com>
Second of the three splits of #166. One commit, three files, all of it generated from master's own
src/— nothing is picked from the feature branch.The drift
resources/shell-integration/is a checked-in copy ofsrc/shell-integration/with nothing keeping it in step. All three had drifted:src/wmux-bash-integration.shwmux()functionwmux-cmd-integration.cmdchcp 65001wmux-powershell-integration.ps1The PowerShell one is the interesting case. Its copy predates #72, so
Send-WmuxMessagesends V1 lines with noauth <token>prefix — andpipe-server.ts:157rejects every V1 command butpingwithout one. Anything running that copy reports no cwd, no git branch, no shell state and no PR; the pipe answersunauthorizedand the integration has no way to notice. It also predates the UTF-8 console setup, thewmuxfunction, deferring the PR-poll job off the first-prompt critical path, andWMUX_STARTUP_COMMANDS(#32).After this,
diff -r src/shell-integration resources/shell-integrationis empty.Before you weigh how urgent this is
No release path reads these files.
electron-builder.json:50mapssrc/shell-integration→shell-integration, step 7 of the release process copiessrc/shell-integration/*into staging, andgetShellIntegrationPath()falls back tosrc/shell-integrationin dev. A packaged wmux has always run the fresh source — none of the breakage above ever reached a released install.What does read
resources/shell-integration/is anything consuming wmux out of a repo checkout, which is how the drift surfaced: our devcontainer integration sources the bash copy from there directly. Same shape asresources/cli/wmux.js, which is 1519 diff lines behind a build of master's ownsrc/for the same reason — a duplicate with no enforcement. (Details in #168.)The follow-up worth picking
Resyncing fixes today's drift and guarantees tomorrow's. Two ways out, happy to send either as a fourth PR — just say which:
resources/does not match a fresh copy/build, covering the shell scripts andresources/cli/*.jstogether.resources/shell-integration/and point checkout consumers atsrc/shell-integration/, since nothing wmux ships or runs reads it.The second is the smaller repo but breaks any external consumer already on the old path, so it is your call rather than mine. (We are such a consumer and would happily move.)
Verification
bash -nclean on the packaged.sh; sourced in a plain bash with no error,wmuxresolves as a function.masterworktree with the samenode_modules. No test reads these files, so that is expected; it confirms nothing regressed..ps1and.cmdwant a native Windows check, which is yours. The specific thing to look for: with the old packaged copy the sidebar shows no cwd or branch in a PowerShell pane launched from a repo checkout, and with this one it should.npm run testin git bash on windows showed no failing tests (Claude has been running in a devcontainer on WSL to do the heavy lifting of this PR)🤖 Generated with Claude Code