Skip to main content

Workspace launcher — open/close entire project environments with one command

Project description

wsmux

Workspace launcher for macOS. Open and close entire project environments with one command.

One config file. One command. Your entire workspace — editors, browsers, terminals, docker, apps — opens exactly where you left it.

Install

pip install wsmux

Or install from source:

git clone https://github.com/safeersoft/wsmux.git
cd wsmux
pip install .

The CLI command is mux.

Quick Start

# Create a config in your project
cd ~/my-project
mux --init .

# Edit .mux.json to match your setup, then:
mux .                # Open everything
mux -s .             # Save window positions + close
mux .                # Reopen — everything is where you left it

Commands

Command What it does
mux . Open workspace from .mux.json
mux -s . Save current state (new tabs, positions) then close
mux -ss . Quick close — no config update
mux -c . Capture current desktop into .mux.json
mux -l . Dry run — show what would open
mux --init . Create a starter .mux.json

Named Projects

Register projects to open them from anywhere:

mux --add myapp ~/projects/myapp    # Register
mux myapp                            # Open from anywhere
mux -s myapp                         # Save + close from anywhere
mux --projects                       # List registered projects
mux --remove myapp                   # Unregister

Config Format

.mux.json in your project root:

{
  "name": "My Project",
  "apps": [
    {
      "type": "vscode",
      "paths": ["./frontend", "./backend"],
      "windows": {
        "./frontend": {"position": [0, 0], "size": [960, 1080]},
        "./backend": {"position": [960, 0], "size": [960, 1080]}
      }
    },
    {
      "type": "browser",
      "app": "Microsoft Edge",
      "urls": ["http://localhost:3000", "https://github.com/me/repo"],
      "window": {"position": [1920, 0], "size": [1680, 1050]}
    },
    {
      "type": "terminal",
      "app": "Terminal",
      "tabs": [
        {
          "name": "server",
          "command": "npm run dev",
          "cwd": "./backend",
          "window": {"position": [0, 600], "size": [800, 400]}
        }
      ]
    },
    {
      "type": "docker",
      "services": ["postgres", "redis"],
      "cwd": "./backend"
    },
    {
      "type": "app",
      "name": "Postman"
    }
  ]
}

Entry Types

Type What it opens Key fields
vscode VS Code / Cursor windows paths, command ("cursor"), windows (geometry)
browser Browser with tabs in isolated window app, urls, window (geometry)
terminal Terminal.app / iTerm2 tabs tabs[].name, tabs[].command, tabs[].cwd, tabs[].window
docker Docker Compose services services, cwd, file
app Any macOS app name, args
script Shell command command, cwd, stop_command

Window Positions

Mux remembers where every window was — position, size, and which monitor.

  • Auto-capture: mux -s saves current positions before closing
  • Manual capture: mux -c snapshots your current desktop
  • Restore: mux . reopens windows at their saved positions
  • Multi-monitor: positions use macOS unified coordinates, so windows restore to the correct monitor

Save Behavior (mux -s)

When closing with -s, mux compares your current desktop against the saved config:

  • Existing entries: geometry is updated silently
  • New entries (new browser tabs, apps): you're prompted for each one:
New entries detected:

    + [App] Postman  [y/n/i] (yes/no/ignore forever): y
      ✓ Added

    + [Microsoft Edge] reddit.com + 2 more tabs  [y/n/i] (yes/no/ignore forever): i
      ✗ Ignored forever: URL pattern 'reddit.com'
  • y — add to config
  • n — skip this time
  • i — skip and add to global ignore (never captured again)

Global Ignore

~/.mux/ignore.json — patterns that are never captured:

{
  "apps": ["Slack"],
  "urls": ["chatgpt.com", "claude.ai", "reddit.com"],
  "paths": []
}

Browser Isolation

Each project opens its browser tabs in a new isolated window. Running mux for two different projects won't mix their tabs together.

Requirements

  • macOS (uses AppleScript for window management)
  • Python 3.10+
  • Terminal needs Accessibility permission (System Settings > Privacy & Security > Accessibility) for window positioning

Data Files

All stored in ~/.mux/:

File Purpose
projects.json Named project registry
ignore.json Global ignore patterns
states/ Last-opened state per project

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

wsmux-0.1.0.tar.gz (19.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

wsmux-0.1.0-py3-none-any.whl (18.0 kB view details)

Uploaded Python 3

File details

Details for the file wsmux-0.1.0.tar.gz.

File metadata

  • Download URL: wsmux-0.1.0.tar.gz
  • Upload date:
  • Size: 19.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.4

File hashes

Hashes for wsmux-0.1.0.tar.gz
Algorithm Hash digest
SHA256 2a25550da27d59f1fe946709d803e98a6fd3b5740f23c51f51a9d526d8613ae8
MD5 c97cb1e4401a3ad9c3090fc075f4f089
BLAKE2b-256 4fcc789daa3ad54102c116ae58c6c01b14c4e09248eb67deebf52051d2039e43

See more details on using hashes here.

File details

Details for the file wsmux-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: wsmux-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 18.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.4

File hashes

Hashes for wsmux-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e6c98aa040f229f5d6633ac421075ba00cee087be5dfbdd2b8a70714200aa7a0
MD5 6e6a6cefb30d0c35f7852320f20d89b7
BLAKE2b-256 18876552a10d390bb604712bb5abfacce5696029af3613300334b62776eb5a01

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page