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.
Each magent session brands its psmux status bar — magent on the left, its window hotkeys on the right (F1 Proj. Picker F2 </> VS Code, each key name badged in bold cyan). The F2 </> VS Code half only appears when VS Code (code) is installed on the session host; without it the bar advertises F1 Proj. Picker alone rather than a key that would do nothing:
| Key | In a magent: window |
|---|---|
F1 |
Detach the session — back to the picker. |
F2 |
Open the project's folder in VS Code. When you're attached to another machine it opens over Remote-SSH, so you edit the files where they actually live. |
Alt+V |
Paste a clipboard image into the session (Windows — see below). |
F2 needs code on your PATH; magent up refreshes the branding and hints on sessions that were already running. magent sets both halves per session, so they win over a personal ~/.tmux.conf.
Attach windows reconnect themselves
magent attach <host> opens one window per remote session, and each one runs a small supervisor (magent-attach-client) instead of a bare ssh. When the connection dies — laptop sleep, wi-fi change, VPN flap, host reboot — the pane no longer freezes on client_loop: send disconnect and then sits there dead as [process exited with code 255]. It waits (2s, doubling to a 30s ceiling) and dials again, forever, until the host answers.
A whole outage costs one line, rewritten in place — not a scroll of retries. The counters tick down where they are, and ssh's own connect to host ... timed out noise is folded into the last: clause instead of filling the pane:
~ reconnecting to me@desk (attempt 4, retry in 16s, last: Connection timed out) -- Ctrl+C to stop
That line lives on the bottom row of the pane, and nowhere else. When the connection dies your agent's screen is left exactly as it was — mid-answer, and with whatever you had typed into the prompt box and not yet sent still sitting there, readable, on the row it was always on. The reconnect warning never draws over it. (It used to: it painted wherever the cursor happened to be, which in an agent pane is the end of your half-written sentence.)
Narrow panes drop the hint, then the host name, then the reason — the attempt and the countdown are the last things to go. Redirected panes (magent attach ... > log) get one plain line per attempt instead, with no cursor tricks. When a reconnected session eventually ends, the pane leaves one permanent record of the outage it survived (+ reconnected to me@desk after 4 attempt(s); stayed up 1h04m).
Nothing is lost while it waits: the psmux session lives on the host, so the reattached pane comes back to the same running agent, the same scrollback, and the same unsent prompt text — the agent is holding it, not your terminal. You can even keep typing during the outage: what you type is buffered by your terminal and delivered to the agent as soon as the connection is back. You do not have to close a wall of dead terminals and re-run magent attach any more.
Only a deliberate detach closes a pane. When a connection ends, the supervisor asks the host — over a separate, one-shot SSH check — whether your session is still alive. If it is, you left on purpose (F1, or psmux detach), the pane says detached from <session> and exits. If the session is not there (host rebooting, a bring-up still in progress), the pane keeps dialling for a few more tries and only then stops and tells you to run magent attach — so it never hammers a healthy SSH server over a session that is gone for good. Ctrl+C stops the supervisor immediately at any point.
That check exists because an exit code alone cannot be trusted: Windows OpenSSH doesn't report a remote command's exit status back over an interactive session, so a session that died on the host looked exactly like a clean detach. Panes used to close on that — one wi-fi flap, forty windows gone, each announcing a "detach" you never asked for. The separate check drops the interactive pseudo-terminal, which is what makes the host's answer truthful on every OS.
magent attach --no-reconnect restores the old one-shot behavior (one connection, no check). --no-mux panes are never supervised — without a multiplexer the agent dies with the connection, so there is nothing to reattach to.
Your sessions survive your connection
A dropped connection must never kill work on the host. That is not automatic on Windows: OpenSSH runs everything an SSH session starts inside a job object that it destroys when the connection closes, and every child inherits it — so a psmux session created by a remote magent up (which is exactly what magent attach does) used to be owned by your laptop's wi-fi. One flap and the host's psmux servers, and the agents inside them, were killed. magent now creates sessions with an explicit break-out from that job, so a session's lifetime is tied to the host, not to the connection that asked for it.
Note that magent down --all is the deliberate way to stop everything: it kills every psmux session on the machine along with the agent running in each, not just the daemons. Name sessions explicitly (magent down api web) or use -g/--group to stop a subset.
The host brings itself up on its own desktop
magent attach asks the host to run magent up for you, over SSH. On Windows that is a problem nobody sees coming: OpenSSH is a service, so every process an SSH login starts lives in logon Session 0 — a session with no desktop attached to any monitor. Sessions created there are real and running, and completely useless: the host's own magent status reports them stopped, nothing can tile or attach to them, and because psmux's session registry is shared they hold their names, so every later bring-up on the real desktop fails with "session never came up". (Measured once: 82 psmux servers and 42 agents, plus an upload server squatting the loopback port the desktop's Alt+V needed. Clearing it took an elevated kill of 1172 processes.)
So a bring-up that finds itself in Session 0 does not run there. It hands the same command to the logged-on desktop through Task Scheduler, waits for it, and relays its output back down the SSH pipe — you see the host's normal up output on your laptop, prefixed by one hand-off: ... line. No password, no elevation, no scheduled task left behind. The same applies to the upload server attach ensures on the host. A plain foreground magent serve is left alone.
MAGENT_SESSION0_POLICY controls it: handoff (default), allow for a headless Windows host that is only ever reached over SSH and has no desktop to hand off to, or refuse to make the situation loud instead. If nobody is logged on at the host's console there is nowhere to hand off to, so the bring-up refuses and says exactly that rather than waiting out a scheduled task Windows is never going to start. Nothing changes on macOS or Linux, where there is no session isolation and tmux over SSH is simply how people work. If servers from an older magent are still stranded, magent doctor and magent status count them for you.
Your typing outranks your fleet
On Windows, magent keeps every psmux process at above-normal priority. Your keystrokes reach an agent through a chain of psmux processes, none of which owns a window — so Windows never gives them the boost it gives a foreground app, and under load they queue behind the very builds and language servers they are hosting. That is the difference between typing that feels instant and typing that lags while a normal text box on the same machine stays snappy. The processes are waiting on a pipe rather than burning CPU, so the boost costs your agents nothing.
It needs no administrator rights, it only ever raises a process (anything you or another tool put at high/realtime priority is left alone), and it re-runs periodically so sessions created later are covered too. Set MAGENT_PSMUX_BOOST=0 to leave every process's priority exactly as it is.
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 on this config's uploadPort — the same port magent status, up and doctor watch, so a bare magent serve and the rest of the tool can't disagree about where the server is (-p still overrides it; with no readable config the port falls back to 8033). 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. Setting MAGENT_ALTV_NATIVE=1 makes a local press skip the pipeline and deliver one native Ctrl+V to the pane instead -- opt-in, because the pane's agent must support pasting on an injected Ctrl+V (Claude Code on Windows reacts only to the physical chord, so for it the default upload path is the one that works). Remote-wired listeners (magent attach) always keep the upload path.
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.
The Alt+V listener stays alive by itself
The upload server owns the Alt+V listener: while magent serve runs it makes sure a listener exists, restarts one that died or is running older code after an upgrade, and leaves alone one that magent attach pointed at another machine. So Alt+V survives reboots, crashes and upgrades — start the server (directly, or via magent --go / magent attach) and the hotkey follows.
If it isn't working you will be told, rather than left guessing:
magent statusprintsAlt+V listener DEAD (upload server is up but no listener — Alt+V does nothing)in red and exits 3, with the repair command underneath.magent doctorfails thehotkeycheck with the same hint. A listener that is simply not expected yet (no server running) still reads as a quietoff.- Every press narrates itself in that project's status line, starting the instant the chord is detected:
Alt+V: capturing...(before the clipboard is even read) →Alt+V: uploading...→Alt+V: image sent(a local native press is shorter:Alt+V: pasting...→Alt+V: pasted from clipboard). A press that can't complete ends in a specific reason rather than a generic failure —clipboard has no image - copy one first,cannot reach magent serve (connection refused),serve said HTTP 400: Unknown project,saved, but psmux would not paste it. The narration never delays the press: it is queued and delivered on its own thread, and a dead server costs a paste nothing. - Every press is also recorded in
~/.magent/logs/hotkey.logas oneALTV outcome=… project=…line — sogrep ALTV ~/.magent/logs/hotkey.logis the whole history of the chord — andmagent servelogs each status-line message it served (flash project=… msg=…in~/.magent/logs/upload.log), so "the status didn't show" is answerable after the fact.
To own the listener's lifetime yourself, set MAGENT_HOTKEY_SUPERVISOR=0; status still reports whether one is running.
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
Just start typing. In a real terminal every list magent shows you — the
menu above, its group submenu, and the magent sessions switcher — filters as
you type, with the closest match marked >:
attach to web
> 2 beta-web still going... 4m
3 gamma-web-docs needs input
Up/Down move the mark, Enter takes it, Esc clears the query (and, on an empty
query, backs out). Nothing else changed: the row numbers still work, q is
still Quit even if you have a project called queue-worker, and pressing Enter
on an untouched menu still takes the default it always did. Piped or scripted
input keeps the plain line-based prompt.
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 magent window that is open right now — including magent attach windows, which belong to a remote host's sessions and are in no local project. Launches nothing; a closed window is skipped, not waited on. |
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, a wedged psmux control plane (see below), 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>] [--revive] |
Host side: ensure a persistent psmux session per project, and re-launch the agent in any live session whose pane fell back to a bare shell (e.g. after a Ctrl-C). Reviving is automatic except under --json, which stays a pure read unless --revive is passed. |
magent attach <host> [--no-reconnect] |
From another PC: bring host sessions up over SSH, tile locally, Alt+V uploads, F2 opens the project in VS Code over Remote-SSH. Panes reconnect themselves after a dropped connection (see below); --no-reconnect opts out. |
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] [--host <host>] |
Stop sessions; --all/--server also stop the upload server (and listener). From an attach client there are no local sessions, so the shutdown is forwarded over SSH to the host you last attached to (or to --host), closing the local attach windows first. |
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 [--ssh-host <host>] |
Run the window-hotkey listener standalone (Windows): Alt+V clipboard upload and F2 open-in-VS-Code. --ssh-host makes F2 open over Remote-SSH. |
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 terminal install |
Bind Ctrl+Backspace and Shift+Enter in Windows Terminal so they still work inside a psmux pane (magent terminal status to inspect) — see Typing through psmux. |
magent config <subcommand> |
Edit config from the CLI — 17 subcommands incl. migrate; see magent config --help. |
magent config edit [host] |
Edit the config on another machine in your editor over SSH — fetch, edit, validate, push back. Omit the host to reuse your last attach target. The host side is magent config cat / magent config put, which you never run by hand. |
Typing through psmux
Two keys stop working the moment your agent runs inside a psmux pane:
- Ctrl+Backspace arrives as a plain Backspace — one character, no word-delete.
- Shift+Enter arrives as a plain Enter — which submits in Claude Code instead of inserting a newline.
Neither is your terminal's fault. psmux drops the key modifier in transit; the child only ever sees the bare key. The real fix upstream is win32-input-mode (psmux#159), which died unmerged — we filed psmux#610 and #611 to revive it.
Until then the mitigation is to resolve the chord before psmux sees it, in
Windows Terminal itself, with a sendInput binding that writes the resulting
bytes straight into the pty — a byte has no modifier left to lose:
magent terminal install # writes the bindings (backup first, never clobbers)
magent terminal status # installed / missing / conflicting, per key
ctrl+backspace→0x17, the Ctrl+W word-erase byte every readline already honors. The same trick VS Code ships. Works through psmux today.shift+enter→0x1b 0x0d(ESC CR), exactly what Claude Code's/terminal-setupinstalls. Works outside psmux now, and inside it once upstream fixes its ESC+CR decode — installing it is right either way.
magent ships this itself because /terminal-setup refuses to run inside a
tmux/psmux pane, which is precisely where magent users live.
The install is idempotent and never clobbers: a key you have already bound to
something else is reported and left alone (the other key still installs), and a
timestamped backup lands beside settings.json before any write. If your
settings.json uses JSONC (comments, trailing commas) magent refuses to rewrite
it and prints the exact snippet to paste by hand instead. magent doctor
reports the same per-key state under wt-keys — as a warning, never a failure.
When every psmux command hangs (the wedge)
Rare, and worth knowing before it happens: psmux's control plane can wedge
machine-wide. Every command — has-session, list-sessions, new-session —
hangs forever, from any console, and the whole fleet looks dead.
It isn't. magent doctor probes the control plane once (bounded, 5 s) and
fails the psmux wedge check with the repair:
- your sessions are frozen, not dead — do not restart them, and do not reboot;
- find the
conhost.exeprocesses whose parent chain reaches a dead pid or apsmux.exe, and kill only those (it was 14 of 874 conhosts in the incident this check comes from); - psmux answers again immediately afterwards, and every session comes back intact.
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 |
psmux-safe keybindings (terminal install) |
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. magent terminal installis gated onsupports_wt_keybindings()— it edits Windows Terminal's ownsettings.json, which no other OS has. Elsewhere it says so and does nothing (see Typing through psmux).- 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 a session reads done only when its turn ends with no background tasks (subagents, background shells) still running — 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
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.18.1.tar.gz.
File metadata
- Download URL: magent_multi_ai_agents_manager-3.18.1.tar.gz
- Upload date:
- Size: 953.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
578ad3b2e56e80860a100cd58378185e29aa672693f48ff835f3c2909971df6f
|
|
| MD5 |
1fd5bf3e68cf2c9aa131d6cad5b455d5
|
|
| BLAKE2b-256 |
d29e8ea6e7d0e43553a67e06cbe196305a69265e9acb39edfcfaacb17a343a62
|
Provenance
The following attestation bundles were made for magent_multi_ai_agents_manager-3.18.1.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.18.1.tar.gz -
Subject digest:
578ad3b2e56e80860a100cd58378185e29aa672693f48ff835f3c2909971df6f - Sigstore transparency entry: 2820305773
- Sigstore integration time:
-
Permalink:
DevinoSolutions/magent-multi-ai-agents-manager@f9c091ee66451f388db5b07be699ace126a2d475 -
Branch / Tag:
refs/tags/v3.18.1 - Owner: https://github.com/DevinoSolutions
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@f9c091ee66451f388db5b07be699ace126a2d475 -
Trigger Event:
push
-
Statement type:
File details
Details for the file magent_multi_ai_agents_manager-3.18.1-py3-none-any.whl.
File metadata
- Download URL: magent_multi_ai_agents_manager-3.18.1-py3-none-any.whl
- Upload date:
- Size: 330.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2ee9ff4b5c96d3808c1cdc4a65e0199a3464def37469deb34df55425019235d1
|
|
| MD5 |
bde97781d21230d82b3567fda9748252
|
|
| BLAKE2b-256 |
8a8ad814cddba3a75d74470e2e5639d36bcf77bec96a0f37a7733c9f9543d503
|
Provenance
The following attestation bundles were made for magent_multi_ai_agents_manager-3.18.1-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.18.1-py3-none-any.whl -
Subject digest:
2ee9ff4b5c96d3808c1cdc4a65e0199a3464def37469deb34df55425019235d1 - Sigstore transparency entry: 2820305845
- Sigstore integration time:
-
Permalink:
DevinoSolutions/magent-multi-ai-agents-manager@f9c091ee66451f388db5b07be699ace126a2d475 -
Branch / Tag:
refs/tags/v3.18.1 - Owner: https://github.com/DevinoSolutions
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@f9c091ee66451f388db5b07be699ace126a2d475 -
Trigger Event:
push
-
Statement type: