All agents on deck.
Run your coding agents side by side, and always know which one needs you.
Free and open source (MIT) · Windows, macOS and Linux
PS> irm https://raw.githubusercontent.com/CydoEntis/maitty/main/install.ps1 | iex
maitty in any project folder.
╭─ SESSIONS 5 ───────────── ●1 ╮ ╭─ 1 checkout-discounts + ────────── ● needs you ✕ ╮ ╭─ cart-tests ─── ⣻ working ✕ ──────────────── TYPING ╮ │ │ │ │ │ │ │ − acme-store ⎇ main │ │ > discount codes don't change the total │ │ › cover the cart total with tests │ │ ▗ ● checkout-d… ✻ +38 −6 40s▖│ │ │ │ │ │ ▝ asks: Allow Bash(pnpm test▘│ │ ● Read(src/checkout/total.ts) │ │ • Explored │ │ ⣻ order-emails ◆ +21 −0 1m │ │ ⎿ Read 64 lines │ │ └ Read src/cart/total.ts │ │ │ │ ● Update(src/checkout/total.ts) │ │ │ │ − api-gateway ⎇ main │ │ ⎿ 5 additions, 1 removal │ │ • Edit src/cart/total.test.ts │ │ ○ auth-refresh ◇ 2h │ │ 26 - return subtotal + shipping; │ │ + it("totals an empty cart", () => │ │ ● rate-limit ✦ +42 −7 4m │ │ 26 + const off = discount(code); │ │ + expect(total([])).toBe(0)); │ │ │ │ 27 + return subtotal - off + ship; │ │ │ │ − docs-site ⎇ main │ │ │ │ • Ran pnpm vitest run cart │ │ ● quickstart ✻ 9m │ │ ● Now the tests, to be sure. │ │ └ 14 passed, 1 failed │ │ │ │ │ │ │ │ │ │ ─────────────────────────────────────────────────── │ │ • Empty carts give undefined; │ │ │ │ Bash command │ │ fixing the reducer's start. │ │ │ │ pnpm test │ │ │ │ │ │ Run the checkout tests │ │ ◦ Working (41s · esc to interrupt) │ │ │ │ │ │ │ │ │ │ Allow Bash(pnpm test)? │ │ │ │ │ │ ❯ 1. Yes │ │ │ │ │ │ 2. Yes, don't ask again │ │ │ │ │ │ 3. No, tell Claude what to do │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ────────────────────────────── │ │ │ │ │ │ + New Menu │ │ │ │ │ ╰────────────────────────────────╯ ╰───────────────────────────────────────────────────────────╯ ╰───────────────────────────────────────────────────────────╯
╭─ SESSIONS 5 ───────────── ●1 ╮ ╭─ 1 checkout-discounts + ────────── ● needs you ✕ ╮ ╭─ cart-tests ─── ⣻ working ✕ ──────────────── TYPING ╮ │ │ │ │ │ │ │ − acme-store ⎇ main │ │ > discount codes don't change the total │ │ › cover the cart total with tests │ │ ▗ ● checkout-d… ✻ +38 −6 40s▖│ │ │ │ │ │ ▝ asks: Allow Bash(pnpm test▘│ │ ● Read(src/checkout/total.ts) │ │ • Explored │ │ ⣻ order-emails ◆ +21 −0 1m │ │ ⎿ Read 64 lines │ │ └ Read src/cart/total.ts │ │ │ │ ● Update(src/checkout/total.ts) │ │ │ │ − api-gateway ⎇ main │ │ ⎿ 5 additions, 1 removal │ │ • Edit src/cart/total.test.ts │ │ ○ auth-refresh ◇ 2h │ │ 26 - return subtotal + shipping; │ │ + it("totals an empty cart", () => │ │ ● rate-limit ✦ +42 −7 4m │ │ 26 + const off = discount(code); │ │ + expect(total([])).toBe(0)); │ │ │ │ 27 + return subtotal - off + ship; │ │ │ │ − docs-site ⎇ main │ │ │ │ • Ran pnpm vitest run cart │ │ ● quickstart ✻ 9m │ │ ● Now the tests, to be sure. │ │ └ 14 passed, 1 failed │ │ │ │ │ │ │ │ │ │ ─────────────────────────────────────────────────── │ │ • Empty carts give undefined; │ │ │ │ Bash command │ │ fixing the reducer's start. │ │ │ │ pnpm test │ │ │ │ │ │ Run the checkout tests │ │ ◦ Working (41s · esc to interrupt) │ │ │ │ │ │ │ │ │ │ Allow Bash(pnpm test)? │ │ │ │ │ │ ❯ 1. Yes │ │ │ │ │ │ 2. Yes, don't ask again │ │ │ │ │ │ 3. No, tell Claude what to do │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ────────────────────────────── │ │ │ │ │ │ + New Menu │ │ │ │ │ ╰────────────────────────────────╯ ╰───────────────────────────────────────────────────────────╯ ╰───────────────────────────────────────────────────────────╯
Know who needs you.
Every session shows whether its agent is working, needs you, has finished or is idle, read from the agent's own hooks where it has them. When one waits, Maitty plays a sound and can send an alert to your phone.
- ⠴ working
- Busy on its turn.
- ● needs you
- A question or approval is waiting.
- ● done
- The turn finished (and its checks passed, if you set any).
- ○ idle
- Nothing running.
╭─ SESSIONS 4 ───────────── ●1 ╮ ╭─ 1 ▲ 1 checkout-discounts + ────────────── ✕ ╮ ╭─ 2 ⣻ order-emails ──── ✕ ──────────────── TYPING ╮ │ │ │ │ │ │ │ − acme-store ⎇ main │ │ ⎿ Read 64 lines │ │ › email the buyer when it ships │ │ ▗ ● checkout-d… ✻ +38 −6 40s▖│ │ ● Update(src/checkout/total.ts) │ │ │ │ ▝ asks: Allow Bash(pnpm test▘│ │ ⎿ 5 additions, 1 removal │ │ • Edit src/orders/events.ts │ │ │ │ 26 - return subtotal + shipping; │ │ + on("shipped", sendShippedMail); │ │ − api-gateway ⎇ main │ │ 26 + const off = discount(code); │ │ • Add emails/shipped.tsx │ │ ○ auth-refresh ◇ 2h │ │ 27 + return subtotal - off + ship; │ │ │ │ ● rate-limit ✦ +42 −7 4m │ │ │ │ ◦ Working (12s · esc to interrupt) │ │ │ │ ● Now the tests, to be sure. │ │ │ │ − docs-site ⎇ main │ │ │ │ │ │ ● quickstart ✻ 9m │ │ ─────────────────────────────────────────────────── │ │ │ │ │ │ Bash command │ │ │ │ │ │ pnpm test │ │ │ │ │ │ Run the checkout tests │ │ │ │ │ │ │ │ │ │ │ │ Allow Bash(pnpm test)? │ │ │ │ │ │ ❯ 1. Yes │ │ │ │ │ │ 2. Yes, don't ask again │ │ │ │ │ │ 3. No, tell Claude what to do │ │ │ │ │ ╰───────────────────────────────────────────────────────────╯ ╰───────────────────────────────────────────────────────────╯ │ │ │ │ ╭─ 3 payment-webhooks ──────────────────────────── ✕ ╮ ╭─ 4 cart-tests ────────────────────────────────── ✕ ╮ │ │ │ │ │ │ │ │ │ > add a per-key rate limit │ │ › cover the cart total with tests │ │ │ │ │ │ │ │ │ │ ✓ WriteFile src/limit/bucket.go │ │ • Ran pnpm vitest run cart │ │ │ │ ✓ Edit src/proxy.go │ │ └ 15 passed │ │ │ │ ✓ Shell go test ./... (ok) │ │ │ │ │ │ │ │ • Done. Empty carts total 0 now. │ │ │ │ ✦ Each key gets 100 requests a │ │ │ │ │ │ minute, then a 429 with │ │ Worked for 1m 12s │ │ │ │ Retry-After. │ │ │ │ │ │ │ │ › Ask Codex to do anything │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ────────────────────────────── │ │ │ │ │ │ + New Menu │ │ │ │ │ ╰────────────────────────────────╯ ╰───────────────────────────────────────────────────────────╯ ╰───────────────────────────────────────────────────────────╯
╭─ SESSIONS 4 ───────────── ●1 ╮ ╭─ 1 ▲ 1 checkout-discounts + ────────────── ✕ ╮ ╭─ 2 ⣻ order-emails ──── ✕ ──────────────── TYPING ╮ │ │ │ │ │ │ │ − acme-store ⎇ main │ │ ⎿ Read 64 lines │ │ › email the buyer when it ships │ │ ▗ ● checkout-d… ✻ +38 −6 40s▖│ │ ● Update(src/checkout/total.ts) │ │ │ │ ▝ asks: Allow Bash(pnpm test▘│ │ ⎿ 5 additions, 1 removal │ │ • Edit src/orders/events.ts │ │ │ │ 26 - return subtotal + shipping; │ │ + on("shipped", sendShippedMail); │ │ − api-gateway ⎇ main │ │ 26 + const off = discount(code); │ │ • Add emails/shipped.tsx │ │ ○ auth-refresh ◇ 2h │ │ 27 + return subtotal - off + ship; │ │ │ │ ● rate-limit ✦ +42 −7 4m │ │ │ │ ◦ Working (12s · esc to interrupt) │ │ │ │ ● Now the tests, to be sure. │ │ │ │ − docs-site ⎇ main │ │ │ │ │ │ ● quickstart ✻ 9m │ │ ─────────────────────────────────────────────────── │ │ │ │ │ │ Bash command │ │ │ │ │ │ pnpm test │ │ │ │ │ │ Run the checkout tests │ │ │ │ │ │ │ │ │ │ │ │ Allow Bash(pnpm test)? │ │ │ │ │ │ ❯ 1. Yes │ │ │ │ │ │ 2. Yes, don't ask again │ │ │ │ │ │ 3. No, tell Claude what to do │ │ │ │ │ ╰───────────────────────────────────────────────────────────╯ ╰───────────────────────────────────────────────────────────╯ │ │ │ │ ╭─ 3 payment-webhooks ──────────────────────────── ✕ ╮ ╭─ 4 cart-tests ────────────────────────────────── ✕ ╮ │ │ │ │ │ │ │ │ │ > add a per-key rate limit │ │ › cover the cart total with tests │ │ │ │ │ │ │ │ │ │ ✓ WriteFile src/limit/bucket.go │ │ • Ran pnpm vitest run cart │ │ │ │ ✓ Edit src/proxy.go │ │ └ 15 passed │ │ │ │ ✓ Shell go test ./... (ok) │ │ │ │ │ │ │ │ • Done. Empty carts total 0 now. │ │ │ │ ✦ Each key gets 100 requests a │ │ │ │ │ │ minute, then a 429 with │ │ Worked for 1m 12s │ │ │ │ Retry-After. │ │ │ │ │ │ │ │ › Ask Codex to do anything │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ────────────────────────────── │ │ │ │ │ │ + New Menu │ │ │ │ │ ╰────────────────────────────────╯ ╰───────────────────────────────────────────────────────────╯ ╰───────────────────────────────────────────────────────────╯
Close it, come back.
A background service owns every session. Close the window and your agents keep running; run maitty to come back. After a crash or a reboot, Maitty reopens them in the right folders and resumes their conversations.
▁▂▃▄▅▄▃▂▁▂▃▄▅▄▃▂▁▂▃▄▅▄▃▂▁▂▃▄▅▄▃▂▁▂▃▄▅▄▃▂▁▂▃▄▅▄▃▂▁▂▃▄▅▄▃▂▁▂▃▄▅▄▃▂▁▂▃▄▅▄▃▂ All agents on deck. while you were away ● 1 need you ⣻ 1 still working ● 2 finished ▌ Resume where you left off r ▌ acme-store › checkout-discounts New session n Open a project… o ↑↓ choose Enter open ? keys maitty 0.43.2
▁▂▃▄▅▄▃▂▁▂▃▄▅▄▃▂▁▂▃▄▅▄▃▂▁▂▃▄▅▄▃▂▁▂▃▄▅▄▃▂▁▂▃▄▅▄▃▂▁▂▃▄▅▄▃▂▁▂▃▄▅▄▃▂▁▂▃▄▅▄▃▂ All agents on deck. while you were away ● 1 need you ⣻ 1 still working ● 2 finished ▌ Resume where you left off r ▌ acme-store › checkout-discounts New session n Open a project… o ↑↓ choose Enter open ? keys maitty 0.43.2
A branch per agent, review in place.
Each new agent gets its own Git worktree, so no two edit the same files. Files, Changes and Branch open in a side panel beside your panes: review each file's diff, then commit, merge or open a pull request without leaving.
» ● checkout-discou… ⣻ cart-tests ⣻ order-emails ○ auth-refresh ● rate-limit ● quickstart Menu TYPING ╭─ 1 checkout-discounts + ────── ● needs you ✕ ╮ ╭─ Changes ────────────────────────────────────────────────────────────────────────────────── ✕ ╮ │ │ │ Files f · Changes c · Branch b │ │ > discount codes don't change the total │ │ checkout-discounts · claude · +38 −6 · 3 files │ │ │ │ │ │ │ ● Read(src/checkout/total.ts) │ │ ▾ src │ src/checkout/total.ts +6 −2 │ │ ⎿ Read 64 lines │ │ ▾ checkout │ │ │ ● Update(src/checkout/total.ts) │ │ codes.ts +14 −3 M │ @@ -24,9 +24,13 @@ export function total(cart, code) { │ │ ⎿ 5 additions, 1 removal │ │ total.test.ts +18 −1 M │ 24 const subtotal = sum(cart.items); │ │ 26 - return subtotal + shipping; │ │ ▎ total.ts +6 −2 M │ 25 const ship = subtotal < FREE_FROM ? SHIPPING : 0 │ │ 26 + const off = discount(code); │ │ │ 26 - return subtotal + ship; │ │ 27 + return subtotal - off + ship; │ │ CLAUDE SAYS │ + const off = code ? discount(subtotal, code) : 0; │ │ │ │ Discount codes now come off the │ + if (off > subtotal) { │ │ ● Now the tests, to be sure. │ │ subtotal before shipping. Two │ + throw new RangeError(`${code} exceeds the tota │ │ │ │ new tests cover it. │ + } │ │ ─────────────────────────────────────────────── │ │ │ + return subtotal - off + ship; │ │ Bash command │ │ │ 31 } │ │ pnpm test │ │ │ 32 │ │ Run the checkout tests │ │ │ 29 - export const SHIPPING = 499; │ │ │ │ │ + export const SHIPPING = 495; │ │ Allow Bash(pnpm test)? │ │ │ 34 export const FREE_FROM = 5000; │ │ ❯ 1. Yes │ │ │ │ │ 2. Yes, don't ask again │ │ │ │ │ 3. No, tell Claude what to do │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ c Commit m Merge into main p Open PR e Editor x Reviewed r Reply to clau │ ╰───────────────────────────────────────────────────────╯ ╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
» ● checkout-discou… ⣻ cart-tests ⣻ order-emails ○ auth-refresh ● rate-limit ● quickstart Menu TYPING ╭─ 1 checkout-discounts + ────── ● needs you ✕ ╮ ╭─ Changes ────────────────────────────────────────────────────────────────────────────────── ✕ ╮ │ │ │ Files f · Changes c · Branch b │ │ > discount codes don't change the total │ │ checkout-discounts · claude · +38 −6 · 3 files │ │ │ │ │ │ │ ● Read(src/checkout/total.ts) │ │ ▾ src │ src/checkout/total.ts +6 −2 │ │ ⎿ Read 64 lines │ │ ▾ checkout │ │ │ ● Update(src/checkout/total.ts) │ │ codes.ts +14 −3 M │ @@ -24,9 +24,13 @@ export function total(cart, code) { │ │ ⎿ 5 additions, 1 removal │ │ total.test.ts +18 −1 M │ 24 const subtotal = sum(cart.items); │ │ 26 - return subtotal + shipping; │ │ ▎ total.ts +6 −2 M │ 25 const ship = subtotal < FREE_FROM ? SHIPPING : 0 │ │ 26 + const off = discount(code); │ │ │ 26 - return subtotal + ship; │ │ 27 + return subtotal - off + ship; │ │ CLAUDE SAYS │ + const off = code ? discount(subtotal, code) : 0; │ │ │ │ Discount codes now come off the │ + if (off > subtotal) { │ │ ● Now the tests, to be sure. │ │ subtotal before shipping. Two │ + throw new RangeError(`${code} exceeds the tota │ │ │ │ new tests cover it. │ + } │ │ ─────────────────────────────────────────────── │ │ │ + return subtotal - off + ship; │ │ Bash command │ │ │ 31 } │ │ pnpm test │ │ │ 32 │ │ Run the checkout tests │ │ │ 29 - export const SHIPPING = 499; │ │ │ │ │ + export const SHIPPING = 495; │ │ Allow Bash(pnpm test)? │ │ │ 34 export const FREE_FROM = 5000; │ │ ❯ 1. Yes │ │ │ │ │ 2. Yes, don't ask again │ │ │ │ │ 3. No, tell Claude what to do │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ c Commit m Merge into main p Open PR e Editor x Reviewed r Reply to clau │ ╰───────────────────────────────────────────────────────╯ ╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
╭─ SESSIONS 5 ───────────── ●1 ╮ ╭─ 1 quickstart + ────────────── ● done ✕ ╮ ╭─ Files ──────────────────────────── ✕ ──────────────── TYPING ╮ │ │ │ │ │ Files f · Changes c · Branch b │ │ − acme-store ⎇ main │ │ > write a quickstart page │ │ files ~/code/docs-site · main r recent / filter │ │ ● checkout-d… ✻ +38 −6 40s │ │ │ │ │ │ │ asks: Allow Bash(pnpm test │ │ ● Write(docs/quickstart.md) │ │ ▾ docs │ README.md │ │ ⣻ order-emails ◆ +21 −0 1m │ │ ⎿ Wrote 48 lines │ │ ▸ api │ │ │ │ │ │ │ deploy.md A │ docs-site │ │ − api-gateway ⎇ main │ │ ● It covers install, a first order │ │ index.md │ ───────────────────────────── │ │ ○ auth-refresh ◇ 2h │ │ and the test card. │ │ quickstart.md ● M │ │ │ ● rate-limit ✦ +42 −7 4m │ │ │ │ package.json │ The documentation for Acme │ │ │ │ > │ │ > README.md │ Store, built as a static │ │ − docs-site ⎇ main │ │ │ │ site.config.ts │ site. │ │ ● quickstart ✻ 9m │ │ │ │ │ │ │ │ │ │ │ │ Getting started │ │ │ │ │ │ │ │ │ │ │ │ │ │ 1. Install the dependencies │ │ │ │ │ │ │ with pnpm install. │ │ │ │ │ │ │ 2. Run pnpm dev and open the │ │ │ │ │ │ │ local preview. │ │ │ │ │ │ │ 3. Edit any page in docs/; │ │ │ │ │ │ │ the preview reloads as you │ │ │ │ │ │ │ save. │ │ │ │ │ │ │ │ │ │ │ │ │ │ Writing pages │ │ │ │ │ │ │ │ │ │ │ │ │ │ • Keep one topic per page. │ │ │ │ │ │ │ • Start with what the reader │ │ │ │ │ │ │ can do, then how. │ │ │ │ │ │ │ • Link to the API reference │ │ │ │ │ │ │ instead of copying it. │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ Pages under docs/drafts/ │ │ │ │ │ │ │ │ are not published. │ │ │ │ │ │ │ │ │ │ │ │ │ │ pnpm build && pnpm preview │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ M changed A new ● an agent │ │ │ ────────────────────────────── │ │ │ │ │ │ │ + New Menu │ │ │ │ Enter Insert path into claude m Raw i Edit here e │ ╰────────────────────────────────╯ ╰──────────────────────────────────────────────────╯ ╰────────────────────────────────────────────────────────────────────╯
╭─ SESSIONS 5 ───────────── ●1 ╮ ╭─ 1 quickstart + ────────────── ● done ✕ ╮ ╭─ Files ──────────────────────────── ✕ ──────────────── TYPING ╮ │ │ │ │ │ Files f · Changes c · Branch b │ │ − acme-store ⎇ main │ │ > write a quickstart page │ │ files ~/code/docs-site · main r recent / filter │ │ ● checkout-d… ✻ +38 −6 40s │ │ │ │ │ │ │ asks: Allow Bash(pnpm test │ │ ● Write(docs/quickstart.md) │ │ ▾ docs │ README.md │ │ ⣻ order-emails ◆ +21 −0 1m │ │ ⎿ Wrote 48 lines │ │ ▸ api │ │ │ │ │ │ │ deploy.md A │ docs-site │ │ − api-gateway ⎇ main │ │ ● It covers install, a first order │ │ index.md │ ───────────────────────────── │ │ ○ auth-refresh ◇ 2h │ │ and the test card. │ │ quickstart.md ● M │ │ │ ● rate-limit ✦ +42 −7 4m │ │ │ │ package.json │ The documentation for Acme │ │ │ │ > │ │ > README.md │ Store, built as a static │ │ − docs-site ⎇ main │ │ │ │ site.config.ts │ site. │ │ ● quickstart ✻ 9m │ │ │ │ │ │ │ │ │ │ │ │ Getting started │ │ │ │ │ │ │ │ │ │ │ │ │ │ 1. Install the dependencies │ │ │ │ │ │ │ with pnpm install. │ │ │ │ │ │ │ 2. Run pnpm dev and open the │ │ │ │ │ │ │ local preview. │ │ │ │ │ │ │ 3. Edit any page in docs/; │ │ │ │ │ │ │ the preview reloads as you │ │ │ │ │ │ │ save. │ │ │ │ │ │ │ │ │ │ │ │ │ │ Writing pages │ │ │ │ │ │ │ │ │ │ │ │ │ │ • Keep one topic per page. │ │ │ │ │ │ │ • Start with what the reader │ │ │ │ │ │ │ can do, then how. │ │ │ │ │ │ │ • Link to the API reference │ │ │ │ │ │ │ instead of copying it. │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ Pages under docs/drafts/ │ │ │ │ │ │ │ │ are not published. │ │ │ │ │ │ │ │ │ │ │ │ │ │ pnpm build && pnpm preview │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ M changed A new ● an agent │ │ │ ────────────────────────────── │ │ │ │ │ │ │ + New Menu │ │ │ │ Enter Insert path into claude m Raw i Edit here e │ ╰────────────────────────────────╯ ╰──────────────────────────────────────────────────╯ ╰────────────────────────────────────────────────────────────────────╯
Inbox, alerts and checks.
╭─ SESSIONS 5 ── ●2 ✕1 ╮ ╭─ INBOX 3 ─────────────────────────────────────────────────────────────── ✕ TYPING ╮ │ │ │ │ │ − acme-store ⎇ main … │ │ NEEDS YOU 2 │ │ ▗ ● checkout-d… ✻ 40s▖│ │▎● auth-refresh · api-gateway 2m │ │ ▝ asks: Allow Bash(p▘│ │▎ Keep refresh tokens in Redis or in Postgres? │ │ ● order-emails ◆ 6m │ │▎ Reply m Open o │ │ failed: test · exi │ │ │ │ │ │ ● checkout-discounts · acme-store 40s │ │ − api-gateway ⎇ main │ │ Allow Bash(pnpm test)? │ │ ● auth-refresh ◇ 2m │ │ │ │ asks: Keep refresh │ │ FAILED CHECKS 1 │ │ ● rate-limit ✦ 4m │ │▎● order-emails · acme-store 6m │ │ │ │▎ failed: test · exit 1 · 14:19 │ │ − docs-site ⎇ main │ │▎ ✗ orders/events.test.ts › mails the buyer once │ │ ● quickstart ✻ 9m │ │ │ │ │ │ FINISHED 2 │ │ │ │ ● rate-limit · api-gateway 4m │ │ │ │ finished · not seen │ │ │ │ │ │ │ │ ● quickstart · docs-site 9m │ │ │ │ finished · not seen │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ────────────────────── │ │ │ │ + New Menu │ │ ↑↓ select ⏎ open r re-run O override Esc close │ ╰────────────────────────╯ ╰─────────────────────────────────────────────────────────────────────────────────────────╯
╭─ SESSIONS 5 ── ●2 ✕1 ╮ ╭─ INBOX 3 ─────────────────────────────────────────────────────────────── ✕ TYPING ╮ │ │ │ │ │ − acme-store ⎇ main … │ │ NEEDS YOU 2 │ │ ▗ ● checkout-d… ✻ 40s▖│ │▎● auth-refresh · api-gateway 2m │ │ ▝ asks: Allow Bash(p▘│ │▎ Keep refresh tokens in Redis or in Postgres? │ │ ● order-emails ◆ 6m │ │▎ Reply m Open o │ │ failed: test · exi │ │ │ │ │ │ ● checkout-discounts · acme-store 40s │ │ − api-gateway ⎇ main │ │ Allow Bash(pnpm test)? │ │ ● auth-refresh ◇ 2m │ │ │ │ asks: Keep refresh │ │ FAILED CHECKS 1 │ │ ● rate-limit ✦ 4m │ │▎● order-emails · acme-store 6m │ │ │ │▎ failed: test · exit 1 · 14:19 │ │ − docs-site ⎇ main │ │▎ ✗ orders/events.test.ts › mails the buyer once │ │ ● quickstart ✻ 9m │ │ │ │ │ │ FINISHED 2 │ │ │ │ ● rate-limit · api-gateway 4m │ │ │ │ finished · not seen │ │ │ │ │ │ │ │ ● quickstart · docs-site 9m │ │ │ │ finished · not seen │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ────────────────────── │ │ │ │ + New Menu │ │ ↑↓ select ⏎ open r re-run O override Esc close │ ╰────────────────────────╯ ╰─────────────────────────────────────────────────────────────────────────────────────────╯
Inbox
Questions, failed checks and finished work collect in one place, most urgent first.
Alerts
A sound when an agent waits, and an optional notification on your phone.
Checks
Name a command, such as your tests. Maitty runs it after every turn, so a broken turn reads failed, not done.
# config.toml [[check]] project = "/home/me/code/my-app" name = "test" command = "cargo test"
Agents that work together.
Everything works from any shell, including from an agent running inside Maitty. Through MCP, agents can list, read, message and start other sessions, within limits you set.
$ maitty worktree feat/login -- codex # a new branch in its own worktree, with codex $ maitty send -p 3 "run the tests" # message session 3 $ maitty handoff 3 --to claude # hand its task to another agent $ maitty ls --json # every session and its status
Make it yours.
Four layouts, over 60 themes, rounded or square shapes, and every key and colour configurable. The screens on this page follow the Night and Day switch at the top.
╭─ SESSIONS 5 ───── ●1 ╮ ╭─ 1 checkout-discoun… ─ ● needs you ✕ ╮ ╭─ cart-tests ─── ⣻ working ✕ TYPING ╮ │ │ │ │ │ │ │ − acme-store ⎇ main │ │ > discount codes don't change the total │ │ › cover the cart total with tests │ │ ▗ ● checkout-d… ✻ 40s▖│ │ │ │ │ │ ▝ asks: Allow Bash(p▘│ │ ● Read(src/checkout/total.ts) │ │ • Explored │ │ ⣻ order-emails ◆ 1m │ │ ⎿ Read 64 lines │ │ └ Read src/cart/total.ts │ │ │ │ ● Update(src/checkout/total.ts) │ │ │ │ − api-gateway ⎇ main │ │ ⎿ 5 additions, 1 removal │ │ • Edit src/cart/total.test.ts │ │ ○ auth-refresh ◇ 2h │ │ 26 - return subtotal + shipping; │ │ + it("totals an empty cart", () => │ │ ● rate-limit ✦ 4m │ │ 26 + const off = discount(code); │ │ + expect(total([])).toBe(0)); │ │ │ │ 27 + return subtotal - off + ship; │ │ │ │ − docs-site ⎇ main │ │ │ │ • Ran pnpm vitest run cart │ │ ● quickstart ✻ 9m │ │ ● Now the tests, to be sure. │ │ └ 14 passed, 1 failed │ │ │ │ │ │ │ │ │ │ ─────────────────────────────────── │ │ • Empty carts give undefined; │ │ │ │ Bash command │ │ fixing the reducer's start. │ │ │ │ pnpm test │ │ │ │ │ │ Run the checkout tests │ │ ◦ Working (41s · esc to interrupt) │ │ │ │ │ │ │ │ │ │ Allow Bash(pnpm test)? │ │ │ │ │ │ ❯ 1. Yes │ │ │ │ │ │ 2. Yes, don't ask again │ │ │ │ │ │ 3. No, tell Claude what to do │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ────────────────────── │ │ │ │ │ │ + New Menu │ │ │ │ │ ╰────────────────────────╯ ╰───────────────────────────────────────────╯ ╰───────────────────────────────────────────╯
╭─ SESSIONS 5 ───── ●1 ╮ ╭─ 1 checkout-discoun… ─ ● needs you ✕ ╮ ╭─ cart-tests ─── ⣻ working ✕ TYPING ╮ │ │ │ │ │ │ │ − acme-store ⎇ main │ │ > discount codes don't change the total │ │ › cover the cart total with tests │ │ ▗ ● checkout-d… ✻ 40s▖│ │ │ │ │ │ ▝ asks: Allow Bash(p▘│ │ ● Read(src/checkout/total.ts) │ │ • Explored │ │ ⣻ order-emails ◆ 1m │ │ ⎿ Read 64 lines │ │ └ Read src/cart/total.ts │ │ │ │ ● Update(src/checkout/total.ts) │ │ │ │ − api-gateway ⎇ main │ │ ⎿ 5 additions, 1 removal │ │ • Edit src/cart/total.test.ts │ │ ○ auth-refresh ◇ 2h │ │ 26 - return subtotal + shipping; │ │ + it("totals an empty cart", () => │ │ ● rate-limit ✦ 4m │ │ 26 + const off = discount(code); │ │ + expect(total([])).toBe(0)); │ │ │ │ 27 + return subtotal - off + ship; │ │ │ │ − docs-site ⎇ main │ │ │ │ • Ran pnpm vitest run cart │ │ ● quickstart ✻ 9m │ │ ● Now the tests, to be sure. │ │ └ 14 passed, 1 failed │ │ │ │ │ │ │ │ │ │ ─────────────────────────────────── │ │ • Empty carts give undefined; │ │ │ │ Bash command │ │ fixing the reducer's start. │ │ │ │ pnpm test │ │ │ │ │ │ Run the checkout tests │ │ ◦ Working (41s · esc to interrupt) │ │ │ │ │ │ │ │ │ │ Allow Bash(pnpm test)? │ │ │ │ │ │ ❯ 1. Yes │ │ │ │ │ │ 2. Yes, don't ask again │ │ │ │ │ │ 3. No, tell Claude what to do │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ────────────────────── │ │ │ │ │ │ + New Menu │ │ │ │ │ ╰────────────────────────╯ ╰───────────────────────────────────────────╯ ╰───────────────────────────────────────────╯
╭─ SESSIONS 5 ───── ●1 ╮╭─ 1 checkout-discounts ─ ● needs you ✕ ╮╭─ cart-tests ──── ⣻ working ✕ TYPING ╮ │ ││ ││ │ │ − acme-store ⎇ main ││ > discount codes don't change the total ││ › cover the cart total with tests │ │ ▗ ● checkout-d… ✻ 40s▖││ ││ │ │ ▝ asks: Allow Bash(p▘││ ● Read(src/checkout/total.ts) ││ • Explored │ │ ⣻ order-emails ◆ 1m ││ ⎿ Read 64 lines ││ └ Read src/cart/total.ts │ │ ││ ● Update(src/checkout/total.ts) ││ │ │ − api-gateway ⎇ main ││ ⎿ 5 additions, 1 removal ││ • Edit src/cart/total.test.ts │ │ ○ auth-refresh ◇ 2h ││ 26 - return subtotal + shipping; ││ + it("totals an empty cart", () => │ │ ● rate-limit ✦ 4m ││ 26 + const off = discount(code); ││ + expect(total([])).toBe(0)); │ │ ││ 27 + return subtotal - off + ship; ││ │ │ − docs-site ⎇ main ││ ││ • Ran pnpm vitest run cart │ │ ● quickstart ✻ 9m ││ ● Now the tests, to be sure. ││ └ 14 passed, 1 failed │ │ ││ ││ │ │ ││ ──────────────────────────────────── ││ • Empty carts give undefined; │ │ ││ Bash command ││ fixing the reducer's start. │ │ ││ pnpm test ││ │ │ ││ Run the checkout tests ││ ◦ Working (41s · esc to interrupt) │ │ ││ ││ │ │ ││ Allow Bash(pnpm test)? ││ │ │ ││ ❯ 1. Yes ││ │ │ ││ 2. Yes, don't ask again ││ │ │ ││ 3. No, tell Claude what to do ││ │ │ ││ ││ │ │ ││ ││ │ │ ││ ││ │ │ ││ ││ │ │ ││ ││ │ │ ││ ││ │ │ ────────────────────── ││ ││ │ │ + New Menu ││ ││ │ ╰────────────────────────╯╰────────────────────────────────────────────╯╰────────────────────────────────────────────╯
╭─ SESSIONS 5 ───── ●1 ╮╭─ 1 checkout-discounts ─ ● needs you ✕ ╮╭─ cart-tests ──── ⣻ working ✕ TYPING ╮ │ ││ ││ │ │ − acme-store ⎇ main ││ > discount codes don't change the total ││ › cover the cart total with tests │ │ ▗ ● checkout-d… ✻ 40s▖││ ││ │ │ ▝ asks: Allow Bash(p▘││ ● Read(src/checkout/total.ts) ││ • Explored │ │ ⣻ order-emails ◆ 1m ││ ⎿ Read 64 lines ││ └ Read src/cart/total.ts │ │ ││ ● Update(src/checkout/total.ts) ││ │ │ − api-gateway ⎇ main ││ ⎿ 5 additions, 1 removal ││ • Edit src/cart/total.test.ts │ │ ○ auth-refresh ◇ 2h ││ 26 - return subtotal + shipping; ││ + it("totals an empty cart", () => │ │ ● rate-limit ✦ 4m ││ 26 + const off = discount(code); ││ + expect(total([])).toBe(0)); │ │ ││ 27 + return subtotal - off + ship; ││ │ │ − docs-site ⎇ main ││ ││ • Ran pnpm vitest run cart │ │ ● quickstart ✻ 9m ││ ● Now the tests, to be sure. ││ └ 14 passed, 1 failed │ │ ││ ││ │ │ ││ ──────────────────────────────────── ││ • Empty carts give undefined; │ │ ││ Bash command ││ fixing the reducer's start. │ │ ││ pnpm test ││ │ │ ││ Run the checkout tests ││ ◦ Working (41s · esc to interrupt) │ │ ││ ││ │ │ ││ Allow Bash(pnpm test)? ││ │ │ ││ ❯ 1. Yes ││ │ │ ││ 2. Yes, don't ask again ││ │ │ ││ 3. No, tell Claude what to do ││ │ │ ││ ││ │ │ ││ ││ │ │ ││ ││ │ │ ││ ││ │ │ ││ ││ │ │ ││ ││ │ │ ────────────────────── ││ ││ │ │ + New Menu ││ ││ │ ╰────────────────────────╯╰────────────────────────────────────────────╯╰────────────────────────────────────────────╯
SESSIONS 5 ●1│ 1 checkout-discounts + ● needs you ✕ TYPING │ − acme-store ⎇ main │ > discount codes don't change the total ▗ ● checkout-di… ✻ 40s▖│ ▝ asks: Allow Bash(pn▘│ ● Read(src/checkout/total.ts) ⣻ order-emails ◆ 1m │ ⎿ Read 64 lines │ ● Update(src/checkout/total.ts) − api-gateway ⎇ main │ ⎿ 5 additions, 1 removal ○ auth-refresh ◇ 2h │ 26 - return subtotal + shipping; ● rate-limit ✦ 4m │ 26 + const off = discount(code); │ 27 + return subtotal - off + ship; − docs-site ⎇ main │ ● quickstart ✻ 9m │ ● Now the tests, to be sure. │ │ ─────────────────────────────────────────────────────────────────────────────────── │ Bash command │ pnpm test │ Run the checkout tests │ │ Allow Bash(pnpm test)? │ ❯ 1. Yes │ 2. Yes, don't ask again │ 3. No, tell Claude what to do │ │ │ │ │ │ ─────────────────────── │ + New Menu │ │
SESSIONS 5 ●1│ 1 checkout-discounts + ● needs you ✕ TYPING │ − acme-store ⎇ main │ > discount codes don't change the total ▗ ● checkout-di… ✻ 40s▖│ ▝ asks: Allow Bash(pn▘│ ● Read(src/checkout/total.ts) ⣻ order-emails ◆ 1m │ ⎿ Read 64 lines │ ● Update(src/checkout/total.ts) − api-gateway ⎇ main │ ⎿ 5 additions, 1 removal ○ auth-refresh ◇ 2h │ 26 - return subtotal + shipping; ● rate-limit ✦ 4m │ 26 + const off = discount(code); │ 27 + return subtotal - off + ship; − docs-site ⎇ main │ ● quickstart ✻ 9m │ ● Now the tests, to be sure. │ │ ─────────────────────────────────────────────────────────────────────────────────── │ Bash command │ pnpm test │ Run the checkout tests │ │ Allow Bash(pnpm test)? │ ❯ 1. Yes │ 2. Yes, don't ask again │ 3. No, tell Claude what to do │ │ │ │ │ │ ─────────────────────── │ + New Menu │ │
╭─ SESSIONS 5 ───── ●1 ╮ ╭─ 1 ▲ 1 checkout-discounts ──── ✕ ╮ ╭─ 2 ⣻ cart-tests ────── ✕ TYPING ╮ │ │ │ │ │ │ │ − acme-store ⎇ main │ │ > discount codes don't change the total │ │ › cover the cart total with tests │ │ ▗ ● checkout-d… ✻ 40s▖│ │ │ │ │ │ ▝ asks: Allow Bash(p▘│ │ ● Read(src/checkout/total.ts) │ │ • Explored │ │ ⣻ order-emails ◆ 1m │ │ ⎿ Read 64 lines │ │ └ Read src/cart/total.ts │ │ │ │ ● Update(src/checkout/total.ts) │ │ │ │ − api-gateway ⎇ main │ │ ⎿ 5 additions, 1 removal │ │ • Edit src/cart/total.test.ts │ │ ○ auth-refresh ◇ 2h │ │ 26 - return subtotal + shipping; │ │ + it("totals an empty cart", () => │ │ ● rate-limit ✦ 4m │ │ 26 + const off = discount(code); │ │ + expect(total([])).toBe(0)); │ │ │ │ 27 + return subtotal - off + ship; │ │ │ │ − docs-site ⎇ main │ │ │ │ • Ran pnpm vitest run cart │ │ ● quickstart ✻ 9m │ │ ● Now the tests, to be sure. │ │ └ 14 passed, 1 failed │ │ │ │ │ │ │ │ │ │ ─────────────────────────────────── │ │ • Empty carts give undefined; │ │ │ │ Bash command │ │ fixing the reducer's start. │ │ │ │ pnpm test │ │ │ │ │ │ Run the checkout tests │ │ ◦ Working (41s · esc to interrupt) │ │ │ │ │ │ │ │ │ │ Allow Bash(pnpm test)? │ │ │ │ │ │ ❯ 1. Yes │ │ │ │ │ │ 2. Yes, don't ask again │ │ │ │ │ │ 3. No, tell Claude what to do │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ────────────────────── │ │ │ │ │ │ + New Menu │ │ │ │ │ ╰────────────────────────╯ ╰───────────────────────────────────────────╯ ╰───────────────────────────────────────────╯
╭─ SESSIONS 5 ───── ●1 ╮ ╭─ 1 ▲ 1 checkout-discounts ──── ✕ ╮ ╭─ 2 ⣻ cart-tests ────── ✕ TYPING ╮ │ │ │ │ │ │ │ − acme-store ⎇ main │ │ > discount codes don't change the total │ │ › cover the cart total with tests │ │ ▗ ● checkout-d… ✻ 40s▖│ │ │ │ │ │ ▝ asks: Allow Bash(p▘│ │ ● Read(src/checkout/total.ts) │ │ • Explored │ │ ⣻ order-emails ◆ 1m │ │ ⎿ Read 64 lines │ │ └ Read src/cart/total.ts │ │ │ │ ● Update(src/checkout/total.ts) │ │ │ │ − api-gateway ⎇ main │ │ ⎿ 5 additions, 1 removal │ │ • Edit src/cart/total.test.ts │ │ ○ auth-refresh ◇ 2h │ │ 26 - return subtotal + shipping; │ │ + it("totals an empty cart", () => │ │ ● rate-limit ✦ 4m │ │ 26 + const off = discount(code); │ │ + expect(total([])).toBe(0)); │ │ │ │ 27 + return subtotal - off + ship; │ │ │ │ − docs-site ⎇ main │ │ │ │ • Ran pnpm vitest run cart │ │ ● quickstart ✻ 9m │ │ ● Now the tests, to be sure. │ │ └ 14 passed, 1 failed │ │ │ │ │ │ │ │ │ │ ─────────────────────────────────── │ │ • Empty carts give undefined; │ │ │ │ Bash command │ │ fixing the reducer's start. │ │ │ │ pnpm test │ │ │ │ │ │ Run the checkout tests │ │ ◦ Working (41s · esc to interrupt) │ │ │ │ │ │ │ │ │ │ Allow Bash(pnpm test)? │ │ │ │ │ │ ❯ 1. Yes │ │ │ │ │ │ 2. Yes, don't ask again │ │ │ │ │ │ 3. No, tell Claude what to do │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ────────────────────── │ │ │ │ │ │ + New Menu │ │ │ │ │ ╰────────────────────────╯ ╰───────────────────────────────────────────╯ ╰───────────────────────────────────────────╯
Works with your agents.
- ✻Claude Code
- ◆Codex
- ✦Gemini CLI
- ◇OpenCode
- ·Qwen
- ·Pi
- ·Kilo
- ·Kimi
- ·Mastra Code
Any command-line agent works; these report exact status. Connect one with maitty integrate claude.
Install Maitty.
Free and open source. Windows, macOS and Linux. No account, no admin rights.
PS> irm https://raw.githubusercontent.com/CydoEntis/maitty/main/install.ps1 | iex
maitty in any project folder.