Skip to main content

Launch each project's AI coding agent in its own terminal, auto-tiled across every monitor

Project description

magent

Open every project in its own terminal, launch your AI agent, and auto-tile all windows across your screens.
One command. Every tool. Every monitor.

magent.io

PyPI version PyPI downloads License: AGPL-3.0 Python 3.10+ Minimal Dependencies

Windows macOS Linux


      Monitor 1  (4K @ 250%)         Monitor 2  (4K @ 250%)        Monitor 3 (1080p @ 175%)
   +------------+------------+    +------------+------------+    +---------+---------+
   |   api      |   web      |    |   infra    |   docs     |    |  ops    |   ...   |
   |  [claude]  |  [claude]  |    |  [codex]   |  [vscode]  |    | [claude]|         |
   +------------+------------+    +------------+------------+    +---------+---------+
                     columns x rows per screen -- true physical pixels on every monitor

Quick Start

Available once v1.0.0 is published to PyPI. Until then, install from source.

pip install magent-multi-ai-agents-manager          # or: uv tool install magent-multi-ai-agents-manager
magent

On first run, magent scans your Claude, Codex, and VS Code history, finds your recent projects, and generates a config. Run it again to launch everything.

Supported Tools

Tool Type Launch command Session resume Multi-window
Claude Code CLI agent claude --continue Yes Yes
Codex CLI CLI agent codex Yes Yes
Cursor Agent CLI agent cursor-agent -- --
Antigravity (agy) CLI agent agy -- --
VS Code IDE code -- --
Cursor IDE IDE cursor -- --
Custom Any your command -- --

Add any tool by mapping a name to a shell command in settings.tools. CLI agents open in a terminal; IDE tools open via their native CLI (code, cursor).

Happy (mobile/web access)

Enable Happy to monitor and control all your AI sessions from your phone or browser with end-to-end encryption:

"settings": { "happy": true }

Requires npm install -g happy. Supported agents: Claude, Codex. Per-project override with "happy": true/false.

psmux (persistent sessions for SSH access)

Enable psmux (native Windows terminal multiplexer) so each project runs in a named session you can attach to from anywhere — SSH from your phone, another PC, or a second terminal:

"settings": { "psmux": true }

Requires psmux installed (choco install psmux or download from GitHub). When enabled, magent creates a detached psmux session per project and opens Windows Terminal attached to it. From any SSH client: psmux attach -t project-name.

Mobile image upload (over Tailscale)

Send screenshots from your phone straight into a project's agent session:

"settings": { "psmux": true, "uploadServer": true, "uploadPort": 8033 }

magent serve (or uploadServer: true during launch) starts a small HTTP server; magent mobile prints the phone URL + a QR code you can install as a home-screen app (the QR code needs the optional qr extra: pip install magent-multi-ai-agents-manager[qr]). Pick a project on the phone, upload an image, and its path is pasted into that project's session. On a desktop browser you can also Ctrl+V an image from the clipboard: the page stages it with a preview showing which project it will go to, waits for you to confirm with Send, and shows live upload progress until the "pasted into …" confirmation. The Alt+V hotkey (Windows) does the same for whatever magent: session is focused.

This works over Tailscale: the server binds only the loopback and your machine's Tailscale IP — never the LAN wildcard — and attach/mobile/termius shell out to the tailscale CLI to resolve hosts. Devices must be on your tailnet; there is deliberately no auth token, since the bind set is the access control. To bind something else (e.g. LAN-wide), use the escape hatch: magent serve --host 0.0.0.0.

Usage

Run magent with no arguments for the interactive menu:

                         _
 _ __  __ _ __ _ ___ _ _| |_
| '  \/ _` / _` / -_) ' \  _|
|_|_|_\__,_\__, \___|_||_\__|
           |___/
  v3.1.1  auto-tile your AI workspace

  ----------------------------------------

   1   Launch & tile new windows  (default)
   2   Re-tile all open windows
   3   Launch a group  AUTOMATIONS | INTERNAL | LEAD-GEN
   e   Edit config
   q   Quit

Or skip the menu with flags:

Command What it does
magent Interactive menu.
magent --go Launch + tile new windows, no menu.
magent --retile-all Re-tile every matching window.
magent -g <name> Launch only projects in a group.
magent --init Re-scan sessions and regenerate config.
magent --init --base-dir <folder> Generate config from a folder of git repos.
magent --edit Open config in your default editor.
magent docs Print full config reference (Markdown).
magent doctor [--json] Diagnose the environment: config, env vars, agent tools on PATH, terminal, monitors, writable dirs, Tailscale, upload port. Exit 1 on any failure.
magent sessions List active psmux sessions, pick one to attach.
magent sessions <name> Attach directly to a psmux session by name.
magent up [--json] [-g <group>] Host side: ensure a persistent psmux session per project.
magent attach <host> From another PC: bring host sessions up over SSH, tile locally, Alt+V uploads.
magent watch Live table of every agent session, most-urgent first; press a row number to focus that window.
magent attention [-d] [--stop] Attention daemon: badges window titles with agent state, flashes the taskbar on needs-input/error, optional toast/ntfy push (settings.attention). Badges/flash/toast are Windows-only; ntfy push is cross-platform — see Platform support.
magent status [--json] Session + daemon health (incl. an agents state list in --json). Exit codes: 0 healthy, 1 config error, 3 degraded.
magent down [--all] [--server] Stop sessions; --all/--server also stop the upload server (and listener).
magent serve [--host <addr>] Run the mobile upload server (see below).
magent mobile Phone URL + QR code for installing the uploader as a home-screen app.
magent termius Generate an SSH config entry that opens the session picker.
magent hotkey Run the Alt+V clipboard-upload listener standalone (Windows).
magent hooks install Wire the agent lifecycle hooks that feed the session-state store (magent hooks status to inspect) — see Where agent states come from.
magent config <subcommand> Edit config from the CLI — 14 subcommands incl. migrate; see magent config --help.

Platform support

Launching, tiling, and the mobile/notification plumbing run on all three OSes. A few power-user features are Windows-only because they lean on Win32 primitives with no cross-platform equivalent wired up yet. This table is the honest contract — every cell is derived from the capability probes in src/magent/platform/, not from aspiration.

Feature Windows macOS Linux
Launch + auto-tile across monitors Yes Yes Yes
watch live fleet table Yes Yes Yes
attention title badges + taskbar flash Yes No No
Desktop toast (settings.attention.toast) Yes No No
ntfy phone push (settings.attention.ntfy) Yes Yes Yes
Persistent psmux sessions (up / sessions / attach) Yes No No
Global Alt+V clipboard-image hotkey Yes No No
Mobile upload server (serve / mobile) Yes Yes Yes

Notes:

  • Badges, flash, and toast are gated on Platform.supports_attention_signals(), which returns True only in platform/windows.py. On macOS/Linux the daemon prints window badges/flash aren't supported on this OS and those renderers stay off. Toast additionally uses the Windows-only winotify ([toast] extra). ntfy push is cross-platform — it is stdlib urllib over HTTP — so phone notifications work on every OS.
  • The magent: title prefix can be turned off with settings.windowTitlePrefix: false — window titles then become the bare project name (e.g. api instead of magent:api). Launch-path tiling still places windows (it matches the exact title it set), but the features that read the magent: grammar degrade to a safe no-op while the prefix is off: the attention daemon's title badges, the Alt+V clipboard hotkey (which only fires in magent:-titled windows), and magent-name title matching all stop recognizing your windows. One deliberate exception: magent attach windows always keep the prefix — there the title carries the psmux session id that the hotkey chain resolves, so it is load-bearing rather than cosmetic. Leave the setting on unless you specifically want prefix-free titles.
  • Persistent psmux sessions and the Alt+V hotkey are gated on supports_psmux() / supports_hotkey() (also Windows-only). Off Windows the psmux entry points raise NotImplementedError and importing hotkey raises ImportError.
  • The mobile upload server itself (serving the PWA over loopback + Tailscale and receiving images) runs everywhere; auto-pasting the uploaded path into a live agent session uses psmux, so that last hop is Windows-only. Likewise, watch's table renders on every OS but its press-a-number-to-focus action uses the same Windows-only window primitives.

Where agent states come from

magent sessions, magent watch, magent attention, and magent status --json do not poll your agents directly. They read per-session state recordsworking, needs-input, done, error, idle — that your coding agent writes through its lifecycle hooks. Until those hooks are wired, the state store stays empty and the pickers show no status. Wire them once with:

magent hooks install

This merges the bundled magent-state-hook writer into Claude Code's ~/.claude/settings.json (idempotent — your existing hooks are preserved) and prints the one-line notify recipe for Codex's ~/.codex/config.toml. Restart open agent sessions to activate. After that the session picker shows live still going... 3m / done / needs input labels — the hook refreshes the record on every tool call, so still going... means the agent really is moving — and magent watch / magent attention -d light up as your agents change state. magent hooks status shows what is wired and how fresh the store is.

The companion ai-agent-notifier package (same authors) adds phone/desktop notifications on top of the same hook events (it is a pure notifier — it does not write state records):

npx ai-agent-notifier setup

Configuration

Config is stored at a platform-standard location:

  • Windows: %APPDATA%\magent\config.json
  • macOS: ~/Library/Application Support/magent/config.json
  • Linux: ~/.config/magent/config.json

Or place magent.config.json in your working directory (it is gitignored — your personal config never gets committed).

Start from the committed sample, magent.config.example.json — it is generated from the config factory and exercises every surface (groups, remote host/remotePath, ssh, the full settings block):

{
  "version": 1,
  "baseDir": "C:/Users/you/projects",
  "layout": { "columns": 2, "rows": 1 },
  "settings": { "defaultTool": "claude", "...": "see the example file / magent docs" },
  "projects": [
    { "path": "backend/api", "group": "backend", "tool": "claude", "color": "#3b82f6" },
    { "path": "gpu-worker", "group": "infra", "host": "gpu-box.example.com", "remotePath": "/home/dev/worker", "tool": "codex" }
  ]
}

Configs are versioned ("version": 1). A config without a current version still loads but prints a warning until you run magent config migrate — loading never rewrites your file; migrate is the only writer (it also persists auto-assigned project colors; those are derived deterministically from each project's title/path, so they stay the same every run even before you migrate).

Project fields

Field Default Description
path (required) Absolute, or relative to baseDir.
group none Tag for group launches (-g).
tool defaultTool claude, codex, cursor-agent, agy, vscode, cursor, or any custom tool.
color derived Terminal tab color (#rrggbb); auto-derived from the project title/path when unset.
title folder name Window title for matching.
enabled true Set false to skip without deleting.
happy inherit Override global Happy setting for this project.
host none SSH target for remote projects.
remotePath path Remote directory when different from path.
windows none List of window objects {"name", "tool", "command"} with per-window tool/command overrides. Legacy int / ["name1", "name2"] forms still parse.

Multi-window sessions

Open the same project in multiple windows. windows is a list of window objects, each with optional per-window tool/command overrides:

{
  "path": "api",
  "windows": [
    { "name": "api" },
    { "name": "api-2" },
    { "name": "api-codex", "tool": "codex" }
  ]
}

name sets the window title; tool/command override the project's defaults for that window only. Windows without an override each resume the Nth most recent Claude/Codex session.

The legacy "windows": 3 and "windows": ["api", "api-2"] forms still parse and are normalized to window objects by magent config migrate.

Remote projects

{ "host": "deploy@server", "path": "/srv/api", "tool": "claude" }

CLI agents run over SSH. VS Code/Cursor projects open via Remote-SSH.

Custom tools

"tools": {
  "claude": "claude --continue",
  "codex": "codex",
  "cursor-agent": "cursor-agent",
  "agy": "agy",
  "aider": "aider --model sonnet",
  "shell": "bash"
}

Testing

Job Live status Platforms What it verifies
Unit CI Windows / macOS / Linux
Python 3.10 -- 3.14
Config parsing, grid computation, title generation, session resume, discovery, grouping (15 matrix jobs)
Platform CI Windows / macOS / Linux Real monitor detection (ctypes/Swift/xrandr), real window find+move, real terminal launch, DPI scaling
E2E CI Windows / macOS / Linux Full CLI dry-run, config loading, group filtering, SSH project handling, vscode/cursor tool alias, multi-window
Packaging CI Windows / macOS / Linux Build wheel, install into a pristine no-extras venv, drive the real installed magent entry point: version/help, dev-dep import sweep, virgin first-run, socket-real serve, optional-extra degradation, and a real window spawn (win32)

Run it yourself

pip install -e ".[dev]"
pytest tests/unit/ -q                        # fast, safe anywhere
pytest tests/e2e/ -m "e2e and not needs_ssh" # subprocess dry-runs; no SSH server needed
pytest tests/platform/ -v -m platform        # real monitors/terminals — CI-grade env only
pip install build && pytest tests/dist/ -m dist  # wheel -> pristine venv -> real installed entry point
python scripts/check.py                      # the quality gate: ruff + custom lint + ty + compileall + vulture + pytest w/ coverage

A bare pytest collects all tiers, including tests that enumerate real monitors, launch real terminals, and expect an SSH server — run those only in an environment set up like CI (.github/workflows/ci.yml). scripts/check.py is the repo's commit gate; it must pass before every commit.

Cross-platform support

Feature Windows macOS Linux
Monitor detection ctypes Win32 Swift/AppKit xrandr
Window management EnumWindows/MoveWindow AppleScript xdotool/wmctrl
Terminal Windows Terminal kitty/iTerm/Terminal.app kitty/alacritty/gnome-terminal
DPI awareness Per-Monitor V2 Native Retina xrandr DPI

Install from source

git clone https://github.com/DevinoSolutions/magent-multi-ai-agents-manager.git
cd magent-multi-ai-agents-manager
pip install -e .

Contributing

Contributions are welcome. Please open an issue first to discuss what you'd like to change.

License

AGPL-3.0 -- Copyright (c) 2026 DevinoSolutions

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

magent_multi_ai_agents_manager-3.1.1.tar.gz (459.0 kB view details)

Uploaded Source

Built Distribution

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

magent_multi_ai_agents_manager-3.1.1-py3-none-any.whl (155.6 kB view details)

Uploaded Python 3

File details

Details for the file magent_multi_ai_agents_manager-3.1.1.tar.gz.

File metadata

File hashes

Hashes for magent_multi_ai_agents_manager-3.1.1.tar.gz
Algorithm Hash digest
SHA256 2be5b4617bc717965a01f708fbde8316f1bd622ea4629c469420d3a5ef94df7a
MD5 47f7fddfc8e845e8a21fe260494dbd87
BLAKE2b-256 57f022dcd27fd4146f2359dd7b0f07f37da4c458915187e500af35f82027f40c

See more details on using hashes here.

Provenance

The following attestation bundles were made for magent_multi_ai_agents_manager-3.1.1.tar.gz:

Publisher: release.yml on DevinoSolutions/magent-multi-ai-agents-manager

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file magent_multi_ai_agents_manager-3.1.1-py3-none-any.whl.

File metadata

File hashes

Hashes for magent_multi_ai_agents_manager-3.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 2712bc3c83419d12acf60daa8608a85cbe05ad560ce1b92f1a940ea96802d6c4
MD5 d753b491f15a56f38f1a3163044e3c0c
BLAKE2b-256 0a6f4a159e7e34e55b40210b71c556d95c8f9fa0e73be6a907e6edded6389e29

See more details on using hashes here.

Provenance

The following attestation bundles were made for magent_multi_ai_agents_manager-3.1.1-py3-none-any.whl:

Publisher: release.yml on DevinoSolutions/magent-multi-ai-agents-manager

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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