Skip to content

v3.2.0

Choose a tag to compare

@github-actions github-actions released this 12 Jun 13:01
· 43 commits to main since this release

Headline: every shell — inside or outside wmux — gets a wmux command with verified self-pane identity; a repo-root wmux.json turns "open this repo" into a fully arranged workspace (custom commands + declarative pane layout) behind a byte-exact trust gate; clicking a desktop toast now jumps straight to the pane that fired it; and a benchmark harness with a CI regression gate puts real numbers behind the performance story (echo p95 29.2 ms, no degradation at 8 panes). Plus cross-workspace browser-close routing, a multi-image paste fix, and Smart App Control install guidance.

Added

  • Clicking an OS toast now jumps to the pane that fired it (X2). Desktop notifications — agent turn-ends, OSC 9/777/99 terminal notifications, process-exit errors, and external wmux notify calls — carry their originating pane context. Clicking the toast restores and focuses the window, switches to the owning workspace, activates the pane and the exact surface (tab) that produced the notification, marks its unread notifications read, and clears the attention ring. Toasts from wmux notify --workspace <id> jump to that workspace; if the source terminal closed between toast and click, the click degrades to the old focus-the-window behavior.
  • wmux setup-hooks — install Claude Code hooks without the marketplace plugin. The plugin-less path to the deterministic agent-signal bridge: wmux setup-hooks installs the same 4 hook entries (Stop, SubagentStop, SessionStart, PostToolUse) directly into Claude Code's user settings (~/.claude/settings.json) and copies the bridge to a stable, update-proof location (~/.wmux/hooks/wmux-bridge.mjs) that the settings reference — never the versioned install dir, so it survives app updates. The merge is idempotent and surgical: it preserves all your existing hooks and every other settings key, and a corrupted settings.json aborts rather than clobbering your config. --status reports which events are wired, whether the copied bridge is stale (byte-compared against the bundled source), and warns if the marketplace plugin is also installed (which would double-fire signals); --remove deletes only the wmux-owned entries.
  • A1 performance benchmark harness + CI perf gate. scripts/perf-bench.mjs measures what users feel against the packaged app: input latency (key→echo and key→frame, instrumented inside the renderer so CDP transport never pollutes the numbers; at 1 pane and 8 panes), cold-start milestones (spawn → pipe ready → renderer → first PTY data), and full-process-tree RAM including the detached daemon. Each run spawns the app in an isolated data namespace (WMUX_DATA_SUFFIX), so it can run alongside a live wmux, and shuts the daemon down cleanly afterwards. scripts/perf-compare.mjs gates regressions against blessed baselines (double-condition: ratio AND absolute margin) and .github/workflows/perf.yml runs the gate on PRs and appends a trend line to bench/history.ndjson on main. First measured numbers on the dev machine (i5-13420H): echo p95 29.2 ms, key→frame p95 44.1 ms, with no measurable degradation at 8 panes — baselines are descriptive measurements, never aspirational targets. See bench/README.md.
  • Project configuration via wmux.json (X5). Drop a wmux.json at your repo root and wmux turns it into a per-project workspace: custom commands ({"id": "dev", "title": "Dev server", "command": "npm run dev"}) appear in the command palette and the sidebar's project dialog, and a declarative pane layout (nested panes with per-pane startup command, project-relative cwd, or a url for an embedded browser pane) is applied automatically when you open a fresh workspace in that repo — "open this repo → Claude Code + dev server + browser, arranged" with zero clicks. Discovery walks up from the workspace's live cwd and stops at the repo boundary. Nothing executes until you trust the file: wmux.json is checked into the repo, so the first discovery only displays — a review dialog shows every shell command verbatim, and the trust grant is bound to a hash of the exact bytes reviewed. Any later edit (e.g. a malicious PR changing a command) demotes the project to display-only until re-approved; "deny" is sticky until explicitly cleared.
  • wmux CLI on your PATH, with verified self-pane identity (X4). The installer now drops a wmux command onto the user PATH (regenerated on every update, removed on uninstall), so any shell — inside or outside wmux — can script the app: wmux send "npm test" --submit, wmux read-screen, wmux notify "Done" "Build finished", wmux open http://localhost:3000, wmux split, wmux list-workspaces --json. Run inside a wmux pane, terminal commands target the pane you typed them in — identity is resolved by walking the CLI's own process tree against the PID map (the same verified identity the MCP terminal tools use, never the spoofable/stale env hint), and the zero-spawn fast path covers the common shell-direct case. --pane <ptyId> targets another pane explicitly, --active keeps the old UI-focused-pane behavior, and notifications/browser opens route to the calling workspace automatically. The CLI client also gained the TCP-localhost fallback for Windows named-pipe ACL edge cases.

Documentation

  • Smart App Control (SAC) install guidance (#200, reported with a full diagnostic timeline by @alphabeen). On Windows 11 devices with SAC enforcing, the unsigned installer can be blocked outright — no SmartScreen dialog, no "Run anyway" — and the block can be transient (cloud reputation): the same binary may install successfully hours later with zero local changes. README (install section + FAQ) and install.ps1 now explain how to confirm SAC is the cause (Get-MpComputerStatus | Select-Object SmartAppControlState, Code Integrity Event ID 3077) and the workarounds: winget/Chocolatey, retry later, or build from source.

Changed

  • a2a.resolve.identity now returns pane-level entries (pid + ptyId + workspaceId) alongside the existing mappings — additive; existing MCP clients are unaffected.

Fixed

  • Pasting multiple images in a row no longer invalidates the earlier ones (#201). Each image paste deleted the previous wmux-paste temp file, so pasting several screenshots into Claude Code left only the most recent path readable. Temp files now survive the session (a startup sweep removes stale ones older than 24h) and get a random suffix so rapid pastes can't collide.
  • browser_close / wmux browser close can no longer tear down a browser pane the user is viewing in another workspace. browser.open was pinned to the caller's workspace in #193, but browser.close kept resolving "the browser pane" inside the UI-active workspace — an agent in workspace A issuing a close took down whatever browser the user happened to be looking at in workspace B, or got a spurious "not found" when B had none. Close now routes the same way open does: MCP resolves the calling workspace (fail-closed), the CLI uses its verified self-pane identity (with a --workspace override), and an explicit surfaceId — which is globally unique — is found across all workspaces. surface.close with an explicit id likewise no longer fails with "surface not found" when the surface lives outside the active workspace. Callers that pass no workspace at all keep the active-workspace behavior.

Contributors

  • @alphabeen — Smart App Control installation investigation (#200): a complete diagnostic timeline (registry state, Code Integrity 3077 events, the transient cloud-reputation behavior, and why v2.x was unaffected) that became the new SAC install guidance verbatim. Exemplary report — thank you!

What's Changed

  • feat(cli): X4 wmux CLI — verified self-pane identity, PATH shim install, command surface by @openwong2kim in #202
  • fix(browser): route browser.close/surface.close by caller workspace, not UI-active by @openwong2kim in #203
  • feat: wmux.json project config — discovery, trust gate, declarative layout, custom commands (X5) by @openwong2kim in #204
  • feat(bench): A1 performance benchmark harness + CI perf gate by @openwong2kim in #207
  • fix(updater): two-step auto-update — download + verify on detection, restart to install by @matdac6 in #205
  • feat(terminal): tab title from shell OSC 0/2 (e.g. Claude Code /rename) by @matdac6 in #206
  • feat(notification): X2 surface — toast click jumps to pane, wmux setup-hooks by @openwong2kim in #208
  • fix(clipboard): keep paste temp files alive across multiple image pastes by @openwong2kim in #209

Full Changelog: v3.1.1...v3.2.0