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.
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.0is 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:
_ _ _ _ _
_ __ _ _| | |_(_)__| |___ __| |__
| ' \ || | | _| / _` / -_) _| / /
|_|_|_\_,_|_|\__|_\__,_\___\__|_\_\
v1.0.0 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 returnsTrueonly inplatform/windows.py. On macOS/Linux the daemon printswindow badges/flash aren't supported on this OSand those renderers stay off. Toast additionally uses the Windows-onlywinotify([toast]extra). ntfy push is cross-platform — it is stdliburllibover HTTP — so phone notifications work on every OS. - The
magent:title prefix can be turned off withsettings.windowTitlePrefix: false— window titles then become the bare project name (e.g.apiinstead ofmagent:api). Launch-path tiling still places windows (it matches the exact title it set), but the features that read themagent: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 inmagent:-titled windows), andmagent-nametitle matching all stop recognizing your windows. One deliberate exception:magent attachwindows 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 raiseNotImplementedErrorand importinghotkeyraisesImportError. - 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 records — working, 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
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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file magent_multi_ai_agents_manager-3.1.0.tar.gz.
File metadata
- Download URL: magent_multi_ai_agents_manager-3.1.0.tar.gz
- Upload date:
- Size: 459.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
73b22207d9d6a38a6444ba9607aab63134ba88cc644ce65e73717bb374027db1
|
|
| MD5 |
59260ea2e85a78a11612ee694079ff13
|
|
| BLAKE2b-256 |
01ba8ffb5af8a65dcd2decca05e402f65ca7d18b9ff7f75209977bcb10af5d56
|
Provenance
The following attestation bundles were made for magent_multi_ai_agents_manager-3.1.0.tar.gz:
Publisher:
release.yml on DevinoSolutions/magent-multi-ai-agents-manager
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
magent_multi_ai_agents_manager-3.1.0.tar.gz -
Subject digest:
73b22207d9d6a38a6444ba9607aab63134ba88cc644ce65e73717bb374027db1 - Sigstore transparency entry: 2240110572
- Sigstore integration time:
-
Permalink:
DevinoSolutions/magent-multi-ai-agents-manager@e37d2d532bc809ab5eb316de322cd871d15712bb -
Branch / Tag:
refs/tags/v3.1.0 - Owner: https://github.com/DevinoSolutions
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@e37d2d532bc809ab5eb316de322cd871d15712bb -
Trigger Event:
push
-
Statement type:
File details
Details for the file magent_multi_ai_agents_manager-3.1.0-py3-none-any.whl.
File metadata
- Download URL: magent_multi_ai_agents_manager-3.1.0-py3-none-any.whl
- Upload date:
- Size: 155.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
35bde69f16be5da4368318d33174a99082bf314d694be63725c2184d56dded85
|
|
| MD5 |
2fab159e1749b34589587ba3c6132326
|
|
| BLAKE2b-256 |
ec7ffe2088be0dc59240898394403da6efb246ced4ff78f439a1f5c0ab085ee6
|
Provenance
The following attestation bundles were made for magent_multi_ai_agents_manager-3.1.0-py3-none-any.whl:
Publisher:
release.yml on DevinoSolutions/magent-multi-ai-agents-manager
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
magent_multi_ai_agents_manager-3.1.0-py3-none-any.whl -
Subject digest:
35bde69f16be5da4368318d33174a99082bf314d694be63725c2184d56dded85 - Sigstore transparency entry: 2240110861
- Sigstore integration time:
-
Permalink:
DevinoSolutions/magent-multi-ai-agents-manager@e37d2d532bc809ab5eb316de322cd871d15712bb -
Branch / Tag:
refs/tags/v3.1.0 - Owner: https://github.com/DevinoSolutions
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@e37d2d532bc809ab5eb316de322cd871d15712bb -
Trigger Event:
push
-
Statement type: