neuron-explorer
Qwen3.5‑4B 전용 조향형 뉴런 탐색기, 모든 MLP 뉴런을 밀어 결과를 보관·탐색
The original Windows terminal multiplexer for AI agents.
저장소 README에서 가져옴
README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
wmux
The original visibility layer for coding agents on Windows - never hunt for the one that's waiting on you
Built on Electron + xterm.js. Inspired by cmux , with the agent-visibility model modelled on herdr .
New in 2.7 - the folder your agent is working in, beside the terminal it's working in
Ctrl+Shift+X docks a file tree on the right of the window, rooted at the focused pane's live working directory. Not the workspace's, and not the active tab's — the pane's terminal cwd, so a pane showing a markdown or browser tab still belongs to the folder its shell is in.README 전문 보기 ↗You start six agents and walk away from the desk. The only question that matters is which one has stopped and is waiting on you — and until now the answer was on a screen you had just left.
wmux now serves a small web console for your phone. No app to install: it is a page wmux serves itself, so any phone with a browser works.
It is off by default: Settings → Remote → turn it on → Pair a device → scan the QR code. The console listens on this computer only (127.0.0.1:9790); to reach it from a phone, put it behind Tailscale or an SSH tunnel — Settings has both recipes ready to copy:
tailscale serve --bg --https=443 http://127.0.0.1:9790 # then paste the https://…ts.net URL into Public URL
ssh -L 9790:127.0.0.1:9790 <host> # or a plain SSH tunnel
Typing into a terminal is running code, so it was built that way round:
Not in it yet: push notifications with the page closed, an installable PWA, attachments, starting or stopping agents from the phone.
Ctrl+Shift+X docks a file tree on the right of the window, rooted at the focused pane's live working directory. Not the workspace's, and not the active tab's — the pane's terminal cwd, so a pane showing a markdown or browser tab still belongs to the folder its shell is in.
After an agent has been running for ten minutes, three questions follow in order. 2.6 and 2.7 answer all three without leaving wmux:
1. What's in here? The tree lists the folder, lazily, with full keyboard navigation (↑↓ to move, ←→ to collapse/expand, Enter to open, Esc back to the terminal). Single-click opens a file into a preview tab that the next single-click reuses in place, so browsing ten files doesn't leave ten tabs behind — start editing and it promotes to a real tab. Panel width and expansion state persist per root.
2. What changed? Every row carries a +55/-22 column, rolled up so a collapsed src/ shows the sum of everything beneath it — including folders you never expanded, because a rollup that could only count loaded rows would quietly report the part of the tree you happened to have open. In a git repo the numbers mean everything uncommitted; outside one, everything since the session started. The panel header says which — a column of numbers that silently means one or the other can't be acted on. Files an agent touched get a dot, read from the hook stream wmux already receives, so its edits are distinguishable from yours at a glance.
3. Can I just fix that line myself? Anything that isn't markdown opens in a code surface with a line-numbered gutter, beside the terminal it came from. Hit Edit, change the line, Ctrl+S.
Three things that are deliberately not clever about this:
Until now wmux could only tell you what an agent was doing if that agent told it. That meant Claude Code (hooks), OpenCode (plugin) and Kiro. Codex, Gemini, Aider, Amp, Cursor and Copilot ran in panes wmux could display and could not read.
2.0 closes that with three layers, each of which only fills the gap the one above left:
1. One roster for every agent in the window. wmux already knew which panes were blocked — it just never said so above a single sidebar row. Now a banner over the workspace list answers "who needs me?" across every workspace at once, ranked by who has been waiting longest.
2. Ctrl+Shift+A — the agent navigator. Every agent in the window in one list, blocked first. Filter with a/b/w/i/u, ↑↓ to move, enter to jump straight to the pane — it selects the workspace and raises the tab, so an agent buried in a background tab is one keystroke away. Ctrl+Shift+B goes straight to whoever has waited longest, and cycles on repeat.
3. wmux now identifies and reads agents that report nothing. It works out which agent a pane is running from the command line you typed or the shell wmux launched, then matches the agent's own on-screen UI against bundled rules to tell blocked from working. All of it local — nothing is sent anywhere.
Three things that are deliberately not clever about this:
wmux detect explain names the rule that fired and the line that matched. wmux detect explain --file screen.txt replays a captured screen offline, so you can debug or author a rule without the agent even installed.Screen detection is on by default, never reads a pane whose agent reports working or blocked (an idle one is read, for that question), and is one click off in Settings → Workspace. Rules live in %APPDATA%\wmux\agent-detection if you want to add or fix one; an override replaces the bundled rules for its agent, question included, so it turns question detection off for that agent.
Bundled rules currently cover Claude Code (blocked / question / working / idle), plus Codex and OpenCode (identity and idle). Anything else is identified but reads as silent until someone contributes rules —
wmux detect explain --fileis how you write them, and PRs are very welcome.
omp status hooks: With agent integration consent and Status hooks enabled, wmux installs ~/.omp/agent/extensions/wmux.js, honouring PI_CODING_AGENT_DIR and PI_CONFIG_DIR inherited by wmux. Restart omp after installation or updates. The extension declares idle/working from the main session and its owned background jobs, so an ended response does not hide a still-running subagent. Tool approvals, plan reviews and the native ask tool declare a human wait. Child sessions never clear the parent pane's state. This does not depend on screen detection or terminal progress. With --no-extensions, a named omp profile, or directory overrides set only inside a shell, explicitly load the extension using omp --trusted-extension <absolute-path-to-wmux.js>. Disabling Status hooks removes wmux's extension, not a user-owned file with the same name.
Rebound descendant sessions are aggregated too, including agents without an async-job entry. A zero-length main-session job snapshot alone is not proof of idle; active child sessions and their pending jobs still count. Descendants retain their root attribution if an intermediate session closes.
Individual descendants are also published through report-subagent: the workspace sidebar lists each agent ID/name and its definition, counts active agents, and marks each entry done independently. The window-wide “working” banner counts active parent surfaces, not the number of child agents; use the workspace's agent count for that.
The orchestration title counts only agents still running, not the retained completion history: five started agents with two completed display “3 agents”. Completed rows remain available until the existing linger policy hides them. This title calculation is part of wmux's renderer; updating or restarting only the omp extension does not update it.
$BROWSER (Codex today, OpenCode once its $BROWSER support ships) go through the same rule in WSL panes.\\.\pipe\wmux) with a JSON-RPC API. Create workspaces, split panes, send keystrokes, read terminal content, control the browser via CDP, and spawn sub-agent terminals programmatically.settings.json or ~/.config/ghostty/config. Ships with 450+ bundled Ghostty themes.Download wmux-0.7.10-win-x64.zip from GitHub Releases, extract anywhere, and run wmux.exe. No installer, no code signing, no admin required.
Note: After extracting, right-click the zip before extracting and select Unblock if Windows SmartScreen warns about the executable.
This repository is also a Scoop bucket:
scoop bucket add wmux https://github.com/amirlehmam/wmux
scoop install wmux/wmux
Update with scoop update wmux. A Scoop install does not update itself in place: the update badge tells you to use Scoop instead, so Scoop always knows which version is installed. Settings and sessions live in %APPDATA%\wmux and survive updates.
wmux checks GitHub Releases for updates. Clicking the titlebar badge or the Check for updates button in Settings → Help downloads and installs in place — including portable zip extracts (the recommended install). Unattended NSIS downloads are held in a quarantine window (3 days by default) before installing, and installs always require an explicit confirmation click — nothing is applied silently.
Release artifacts are not yet Authenticode-signed (SignPath OSS approval is pending; the CI signing pipeline is wired and activates automatically once the signing secrets are configured). Until signing lands, security-sensitive or air-gapped environments can control the updater with environment variables:
| Variable | Effect |
|---|---|
WMUX_DISABLE_UPDATER=1 | Disable the auto-updater entirely (update manually from GitHub Releases) |
WMUX_MIN_RELEASE_AGE_DAYS=N | Change the quarantine window (default 3 days) |
git clone https://github.com/amirlehmam/wmux.git
cd wmux
npm install
npm run build:main
npm run dev
I run a lot of Claude Code sessions in parallel. On macOS there is cmux, and it is exactly what I needed — vertical tabs with live metadata, notification rings when agents need attention, a scriptable browser, and a socket API for automation. But I work on Windows, and nothing like it existed.
Windows Terminal has tabs but no notification system. You have to manually check each tab to see if an agent finished or is waiting for input. tmux works in WSL but loses all Windows integration. Electron terminals exist but none focus on the AI agent workflow.
So I built wmux — a visibility layer for AI coding agents. It doesn't replace Claude Code or change how it works. It passively observes and shows you what's happening. A CDP proxy on localhost:9222 lets Claude Code's native browser tools control the wmux browser panel — you watch every page load, click, and form fill in real-time. Auto-configured hooks in settings.json report tool usage and agent activity to the sidebar. When a command finishes or is interrupted, the sidebar dot changes color and you get a notification.
The sidebar shows exactly what each agent is doing — the git branch it is on, the PR it opened, the ports it is listening on, and whether it needs your attention. Shell integration scripts inject themselves into PowerShell, CMD, and Bash sessions and report CWD changes, git branch switches, shell state, and PR status back to the sidebar via a named pipe in real time.
Since 2.0 that no longer depends on the agent cooperating. wmux identifies which agent a pane is running and, for the ones that report nothing of their own, reads their on-screen UI to tell blocked from working — so Codex and Aider sit in the same roster as Claude Code. The ranking is the point: with ten workspaces open, the question is never "what is agent #7 doing", it is "which one of these has stopped and is waiting on me", and that answer is one banner and one keystroke away.
On first launch wmux asks before it touches anything outside its own directory, and what it then writes is listed feature by feature in Settings → General: a marked block in ~/.claude/CLAUDE.md, hooks in ~/.claude/settings.json, a chrome-devtools MCP entry pointed at its own browser panel, and a CDP proxy on localhost:9222. No API keys needed — everything runs through the user's existing Claude Code session. Every one of those has an uninstall, and turning a feature off runs it.
Everything is automatable through the wmux CLI or the named pipe directly. The protocol matches cmux, so tools built for one work with the other.
wmux no longer installs a Claude Code plugin. Since 2.12.0 it removes the one
it used to install, and takes its entry out of ~/.claude/plugins/installed_plugins.json
on the way.
Two reasons. It never worked: wmux hand-wrote Claude Code's internal plugin registry in a shape that file does not use, so Claude Code never listed the plugin, never loaded its skills or commands, and marked the copied files orphaned — while wmux logged a successful install (issue #239, reported in full detail by @mkh63d). And it is no longer worth repairing: Claude Code now runs parallel agents natively, which is a better answer than a shell-script wave planner driving panes from the outside.
What is unaffected:
state.json and does
not care who wrote it, so an orchestrator you install yourself still lights
it up.wmux agent spawn / spawn-batch. Putting an agent in a visible pane
was never the plugin's job — it is a CLI verb, and it stays.The plugin itself remains available standalone, installable the supported way: plugin.wmux.org · github.com/amirlehmam/wmux-orchestrator
wmux automatically injects integration scripts into your shells:
prompt function. Reports CWD, git branch, dirty state, and shell state (working/done/interrupted) via NamedPipeClientStream. Preexec hook via PSReadLine detects when commands start. Background job polls gh pr view every 45 seconds.PROMPT variable for CWD reporting.PROMPT_COMMAND / precmd + preexec hooks. Detects interrupts via exit code 130. Communicates via temp file bridge.Environment variables available in all shells:
| Variable | Description |
|---|---|
WMUX | Always 1 inside wmux |
WMUX_CLI | Path to the wmux CLI script |
WMUX_NODE | A JS runtime that can run WMUX_CLI — resolved by wmux, since node is not always on PATH |
WMUX_NODE_ELECTRON | 1 when WMUX_NODE is wmux's own binary and needs ELECTRON_RUN_AS_NODE=1 |
WMUX_SURFACE_ID | Current surface (tab) ID |
WMUX_PIPE | Named pipe path (\\.\pipe\wmux) |
All shortcuts are rebindable via Settings (Ctrl+,).
The two number-row families — "jump to workspace N" and "jump to surface N" —
are one dropdown each under Settings → Keyboard → Number-row shortcuts,
rather than eighteen separate rows. Pick the modifiers each answers to
(Ctrl, Alt, Ctrl+Alt, Ctrl+Shift, Alt+Shift) or switch either off so
the digits reach the terminal untouched. Assigning one family a combo the other
holds swaps them, so trading Ctrl+1–9 and Ctrl+Alt+1–9 is a single click.
| Shortcut | Action |
|---|---|
| Ctrl+N | New workspace |
| Ctrl+1–8 | Jump to workspace 1–8 |
| Ctrl+9 | Jump to last workspace |
| Ctrl+PageDown | Next workspace |
| Ctrl+PageUp | Previous workspace |
| Ctrl+Shift+W | Close workspace |
| Ctrl+Shift+F2 | Rename workspace |
| Ctrl+B | Toggle sidebar |
| Shortcut | Action |
|---|---|
| Ctrl+T | New surface |
| Ctrl+Tab | Next surface |
| Ctrl+Shift+Tab | Previous surface |
| Ctrl+Alt+1–8 | Jump to surface 1–8 |
| Ctrl+Alt+9 | Jump to last surface |
| Ctrl+W | Close surface |
| Shortcut | Action |
|---|---|
| Ctrl+D | Split right |
| Ctrl+Shift+D | Split down |
| Ctrl+Alt+Arrow | Focus pane directionally |
| Ctrl+Shift+Enter | Toggle pane zoom |
| Ctrl+Shift+H | Flash focused panel |
| Shortcut | Action |
|---|---|
| Ctrl+Shift+X | Toggle the file explorer panel |
| Up / Down | Move through the tree |
| Left / Right | Collapse / expand a folder |
| Enter | Open the selected file, or expand/collapse a folder |
| Home / End | Jump to the first / last row |
| Esc | Return focus to the terminal |
| Shortcut | Action |
|---|---|
| Ctrl+S | Save the file |
| Tab | Insert a tab (does not leave the editor) |
| Esc | Discard the edit and go back to reading |
| Shortcut | Action |
|---|---|
| Ctrl+Shift+I | Toggle browser panel |
| Ctrl+Alt+I | Toggle Developer Tools |
| Ctrl+Alt+C | Show JavaScript Console |
| Shortcut | Action |
|---|---|
| Ctrl+Shift+A | Agent navigator — every agent, blocked first |
| Ctrl+Shift+B | Jump to the agent waiting longest (cycles on repeat) |
Inside the navigator: ↑/↓ move, enter jumps, esc closes, and a / b /
w / i / u filter to all / blocked / working / idle / silent.
| Shortcut | Action |
|---|---|
| Ctrl+Alt+N | Toggle notification panel |
| Ctrl+Shift+U | Jump to latest unread |
| Shortcut | Action |
|---|---|
| Ctrl+F | Find |
| Enter / Shift+Enter | Find next / previous |
| Escape | Close find bar |
| Shortcut | Action |
|---|---|
| Ctrl+Shift+C | Copy |
| Ctrl+Shift+V | Paste |
| Ctrl+V | Paste (text or screenshot image path) |
| Ctrl+C | Copy (with selection) / interrupt (without) |
| Ctrl+= / Ctrl+- | Increase / decrease font size |
| Ctrl+0 | Reset font size |
| Shortcut | Action |
|---|---|
| Ctrl+Shift+N | New window |
| Ctrl+, | Settings |
| Ctrl+Shift+P | Command palette |
The wmux CLI communicates with the running app over the named pipe.
wmux ping # Check if wmux is running
wmux notify "Build complete" # Send a notification
wmux new-workspace --title "API" # Create a workspace
wmux list-workspaces # List all workspaces
wmux current-workspace # The workspace THIS pane is in (alias: whoami)
wmux ssh user@host # Remote terminal (OpenSSH) in a new workspace
wmux ssh -p 2222 user@host --title "prod" # Extra args are passed through to ssh
wmux new-window # Second wmux window (e.g. for another monitor)
wmux split --right # Split focused pane
wmux send "npm test" # Send text to terminal
wmux send-key Enter --ctrl # Send keystroke
wmux read-screen --lines 50 # Read terminal content
# Agents — who is running what, and who is waiting on you
wmux agent-state # every pane's state, the blocked list, and
# every agent wmux identified but that reports nothing
wmux agent-state --surface <id> # just this pane
wmux report-agent --blocked "Run the migration?" \
--choices '[{"id":"y","label":"Yes","key":"1"}]' # your own agent, parked on a human
wmux answer-agent --surface <id> --choice y # answer another pane from yours
# Screen detection — why does a pane read the way it does?
wmux detect explain # the rule that decided this pane, and the line it matched
wmux detect explain --file screen.txt --agent codex # replay a capture offline, no agent needed
wmux detect reload # re-read %APPDATA%\wmux\agent-detection
# Browser (CDP-powered)
wmux open https://example.com # Open in the panel, per Settings → Browser → Links
wmux browser open http://localhost:3000
wmux browser snapshot # Accessibility tree with eN refs
wmux browser click e5 # Click element by ref
wmux browser type e3 "hello" # Type into input by ref
wmux browser fill e3 "value" # Set input value directly
wmux browser screenshot # Base64 PNG screenshot
wmux browser eval "document.title" # Run JavaScript
# Remote Console — the phone web console (enable and pair it in Settings → Remote)
wmux remote status # running? bound where? how many devices paired / connected
wmux remote status --json
# Remote wmux management (SSH tunnel)
# On the remote machine — expose its wmux pipe on localhost TCP and get its token:
wmux bridge # 127.0.0.1:9787 ↔ \\.\pipe\wmux (pure relay, token still required)
wmux token # print the auth token, copy it
# On your machine — tunnel the port, then drive the remote wmux with any command:
# ssh -L 9787:127.0.0.1:9787 user@host
wmux --remote 127.0.0.1:9787 --token <TOKEN> list-workspaces
wmux --remote 127.0.0.1:9787 --token <TOKEN> new-workspace --title "api"
# Or set once: WMUX_REMOTE=127.0.0.1:9787 and WMUX_REMOTE_TOKEN=<TOKEN>
# From a devcontainer — same transport, no SSH tunnel. Run the bridge in WSL2
# (--wsl binds 0.0.0.0 there, reachable from the container, not from the LAN):
wmux bridge --wsl # relays to \\.\pipe\wmux via npiperelay.exe
# Then in the container: WMUX_REMOTE=host.docker.internal:9787 + WMUX_REMOTE_TOKEN
# Full setup: docs/DEVCONTAINER.md
# Agents
wmux agent spawn --cmd "claude --resume abc" --label "Research"
wmux agent spawn-batch --json '[{"cmd":"claude","label":"Agent 1"},{"cmd":"claude","label":"Agent 2"}]'
wmux agent list # List all agents
wmux agent status <agent-id> # Check agent status
wmux agent kill <agent-id> # Kill an agent
wmux tree # Workspace / pane / surface hierarchy
When a pane was opened with wmux ssh, or its PowerShell/Bash integration sees
you run a direct ssh command, wmux keeps local file insertion useful on the
remote host:
Ctrl+V and Ctrl+Shift+V upload a clipboard screenshot or copied local
file, then insert its remote path. Text paste is unchanged.scp with BatchMode=yes, so authentication must
already work non-interactively through a key or ssh-agent; wmux never opens
a password or passphrase prompt in the background./tmp/wmux-drop-<batch-id>/<file-id>.png. They remain on the remote host
after a successful upload for the receiving program to use.This applies to a direct SSH connection from Windows. A second ssh started
inside the remote shell is a nested connection that wmux cannot observe through
the Windows process tree. wmux may still see the outer connection, so disable
upload (or hold Shift for a drop) rather than relying on automatic upload while
you are on the inner host.
Paste and drop uploads default to on. Configure them independently in
~/.wmux/config.toml.
Connect to \\.\pipe\wmux for programmatic control. Two protocols supported:
V1 (text, used by shell integration):
report_pwd <surface_id> <path>
report_git_branch <surface_id> <branch> [dirty]
report_shell_state <surface_id> idle|running|interrupted
report_startup_command <surface_id> <command> # how to restore this surface; must be cwd-independent
notify <surface_id> <text>
ping
wmux raw-v1 "<line>" sends any of these through the CLI's transport, which is
what lets a shell with no reachable pipe — inside a devcontainer — still report.
See docs/DEVCONTAINER.md.
V2 (JSON-RPC, used by CLI and automation):
{"method": "workspace.create", "params": {"title": "Agent 1"}}
{"method": "workspace.list", "params": {}}
{"method": "surface.send_text", "params": {"id": "surf-...", "text": "npm test\n"}}
{"method": "surface.read_text", "params": {"id": "surf-...", "lines": 50}}
// Browser control (CDP-powered)
{"method": "browser.navigate", "params": {"url": "http://localhost:3000"}}
{"method": "browser.snapshot", "params": {}}
{"method": "browser.click", "params": {"ref": "e5"}}
{"method": "browser.screenshot", "params": {"fullPage": true}}
{"method": "browser.eval", "params": {"js": "document.title"}}
// Agent spawning
{"method": "agent.spawn", "params": {"cmd": "claude --resume abc", "label": "Research"}}
{"method": "agent.spawn_batch", "params": {"agents": [...], "strategy": "distribute"}}
{"method": "agent.list", "params": {}}
{"method": "agent.kill", "params": {"agentId": "agent-..."}}
{"method": "system.tree", "params": {}}
On relaunch, wmux restores:
wmux does not restore live process state — a running tmux or vim is gone after a restart, and shells are respawned fresh in the saved working directories.
Agent conversation restore is opt-in. Turn on Settings → Workspace → Resume Claude Code sessions on restore and each terminal that was running Claude when the session was saved comes back with claude --resume <id> in the directory it was in. This resumes the conversation, not the process: wmux records which session each pane was on and asks Claude to pick it back up. A pane is skipped when Claude no longer has that conversation on disk, and a Claude you exited cleanly is not resumed. Off by default, because every such pane starts an agent the moment the window opens.
Codex has its own switch: Settings -> Workspace -> Resume Codex sessions on restore. Enable it, then launch codex in a new wmux terminal. wmux records each tab's exact conversation ID and runs codex resume <id> in its saved directory. Tabs sharing a folder keep their own conversations; restore never uses --last. No Codex hooks or manual hook approval are needed. This opt-in integration supports the native Windows Codex CLI in PowerShell and Command Prompt; both restore switches default to off. Compatibility and verification.
omp has its own switch: Settings -> Workspace -> Resume omp sessions on restore. Enable it, then run omp in a wmux terminal. wmux's omp extension records each tab's verified .jsonl transcript path on disk and restores with omp --resume <path> in the saved directory. Multiple tabs in the same directory keep their own exact conversation without crossing or re-rooting prompts. An orderly exit (e.g. /quit) forgets the handle; a crash or closing wmux retains it. Deleted transcripts are safely skipped rather than secretly creating an empty session. Restore commands are quoted safely for PowerShell (verbatim single quotes), cmd (double quotes), and POSIX shells. Documentation and verification.
pi has its own switch: Settings -> Workspace -> Resume pi sessions on restore. Enable it, then run pi in a wmux terminal. wmux's pi extension records each tab's exact session file once pi has written it (after the first reply) and restores with pi --session <path> in the saved directory. Quitting pi forgets the handle; switching with /new, /resume or /fork records the new session; a crash or closing wmux keeps it. A session file that is gone or empty is skipped rather than opened as a new empty session.
Control SCP upload for direct SSH panes in ~/.wmux/config.toml:
[remote]
upload-on-paste = true
upload-on-drop = true
Both settings default to true and apply after wmux reload-config. See
Remote file upload for behavior and
limitations.
Set a global default color scheme in ~/.wmux/config.toml:
[terminal]
color_scheme = "Dracula"
Override per pane at split time or on the fly:
wmux split --color-scheme "Tokyo Night"
wmux set-color-scheme "Solarized Dark"
Define custom named schemes in Settings > Terminal > Custom Schemes.
Change what a key sends to the program running in a terminal — add a [keys]
section to ~/.wmux/config.toml:
[keys]
"ctrl+k" = "<C-k><Delete>" # kill to end of line, then pull the next line up
"ctrl+alt+r" = "clear<CR>" # text outside <> is typed literally
"ctrl+shift+q" = "" # empty value swallows the key
Remaps apply inside terminal panes and take priority over wmux's own shortcuts
there. wmux reload-config applies edits without a restart. Full token list in
docs/config.md.
wmux reads configuration from:
%LOCALAPPDATA%\Packages\Microsoft.WindowsTerminal_...\LocalState\settings.json~/.config/ghostty/configImport either via Settings > Terminal > Import. Extracts font family, font size, color scheme, and palette. Default theme is Dracula. 450+ Ghostty themes bundled.
Two-process Electron model. Main process manages PTY spawning (node-pty/ConPTY), named pipe server, CDP browser bridge, port scanning, git/PR polling, notifications, Claude Code context injection, session persistence, and multi-window lifecycle. Renderer process runs React/Zustand with xterm.js (WebGL), recursive split pane layout, and the sidebar.
src/
main/ # Electron main process
renderer/ # React app (sidebar, splits, terminals, browser)
preload/ # contextBridge API
cli/ # wmux CLI tool
shared/ # Types shared between main and renderer
shell-integration/ # PowerShell, CMD, WSL scripts
resources/
wmux-orchestrator/ # Claude Code plugin, deprecated — no longer installed (#239)
themes/ # Ghostty + wmux theme files
sounds/ # Notification sounds
wmux is an independent, from-scratch Windows reimplementation inspired by cmux, the macOS terminal for multitasking. It shares cmux's design philosophy and is wire-compatible with its socket protocol — tools built for cmux's API work with wmux — but it does not reuse cmux's source code.
Run wmux crash-report and paste the output. Do not send a crash dump — a
Windows minidump carries your process environment block in cleartext, and wmux's
users are exactly the people who keep credentials there. See
docs/crash-reports.md.
Set WMUX_PLUGIN_DEBUG=1, reproduce, and attach the log it writes to your temp
directory. See docs/opencode-plugin.md.
wmux is open source under the MIT License. It is an independent reimplementation inspired by cmux and does not incorporate cmux's source code.