The programmable meta‑harness that grows with you.

Start with the subscriptions you already pay for, Claude Code, Codex, OpenCode and Cursor, mixed as you like in one browser workplace. Today it is simply a better way to use your harness. When the work grows, the same agents plan, wait, hand work to each other and run a whole software company on demand.

uv tool install aegis-harness   # or: pip install aegis-harness
cd ~/your/project
aegis

The last line writes a first .aegis.yaml from the harnesses it finds, starts the server and opens it in a browser window. In the first tab, type /setup. Version 2.8.0 on PyPI, MIT license, Python 3.13 or newer.

/setup has the agent read how you work now (skills, instruction files, cron jobs, past sessions, after you say yes) and propose what each becomes in aegis. You tick, it applies. Run it again whenever you like.

One ladder, climbed as far as the work needs

aegis has no studio mode. Every rung uses the same tools, and the structure lives in your own files, so it is versioned, reviewed and copied to the next project like code.

  1. The agents you already pay forYour subscriptions, mixed in one interface, with every quota and its pace in view.
  2. An agent that does more than chatA plan you can see, monitors instead of polling, pages you click, files, your voice.
  3. Several projects at onceOne tab per project, and each tells you when it needs you.
  4. Agents that work togetherHandoffs, peers that read each other, and queues of workers.
  5. A software company on demandWorkflows you approve, schedules, reviewers, pages that guide each decision.
  6. Beyond one machine and one personLinked servers, your phone, a shared browser, a server for a team.

Rung 1 · todayThe agents you already pay for

The agents you already pay for

aegis calls no model. Each session is the vendor's own command-line agent, claude, opencode or codex, running under your account: a Claude plan, OpenCode Go or Zen, a ChatGPT plan, or any provider OpenCode or Codex reaches. aegis holds no API key, and your prompts go from the CLI to the vendor as they would from a terminal.

Sessions of every harness share one tab bar, each with its own model, effort and permission. The panel shows the quota the session spends: this one runs on OpenCode Go, so it shows Go's three windows.

aegis calls no model and holds no key: each session is the vendor's own CLI. Harness versions outside the tested range are flagged before a session starts.

Every subscription's quota, and its pace

The Fleet band reads each subscription you use: Claude's 5-hour and weekly windows, OpenCode Go's 5-hour, weekly and monthly ones. A gauge shows the share spent, a tick for how much of the window has gone, and where it lands at the reset if you keep this pace.

aegis usage turns the transcripts aegis keeps into what the work cost, by month, weekday, session or repo.

Fold the work, keep the conversation

z folds each stretch of tool calls and notes between two messages into one line that says what it holds. Press it again and only your messages and the agent's replies remain. Open a line to see that stretch alone.

Press the fold button over the message box, or a folded line.

Ten themes

Ink is the warm dark palette of the terminal app aegis used to be. Logbook is a daylight lab notebook with times in the margin. The other eight each commit to one idea: Electric lights the thread like a circuit trace, Phosphor is a green CRT, Blueprint a drafting sheet, Amphora black-figure pottery, Riso a two-ink print, Solari a departure board, Aizome indigo cloth stitched in white, and Poster a brutalist print.

Press the theme in the window's top bar.

Rung 2 · one agentAn agent that does more than chat

A plan you can see, and waits that cost nothing

In any harness, the agent keeps its plan in the panel, one step marked doing, each with its time. To wait on CI, a build or a download it arms a monitor with a done condition and a progress count, ends its turn, and is woken when the condition holds.

Monitors run on the server, so a wait spends no tokens. A stalled monitor wakes its owner.

A page instead of a paragraph

When a reply in prose would lose its structure, the agent writes a page. artifact_create gives it a working skeleton, the agent edits the HTML, and artifact_send runs the page in a hidden frame in your browser before you see it. A page that throws goes back to the agent with the error, so you only ever see one that starts.

Pick a layout in the window.

The page answers the agent

You click, drag, pick or type, and the page sends the result back. A submit wakes the agent and folds the page to one line. An event wakes it and leaves the page live. A state write waits until the agent reads it. The agent can push new state or a new version into a live page.

A page can also stay: docked beside the transcript, arranged in columns, moved to a second browser window, or shown as tabs on a phone, so the workplace grows with what its agents build.

Talk to it, and send it files

Dictate into the composer and the words appear while you talk; the agent is told the message was dictated. Drop, paste or pick files to attach them to a message.

Dictation runs in your browser. Attachments are stored with the session.

Files that preview where you are

An agent sends you a file, or a set of them, as one card: a rendered page, a PDF, an image, a diff you swipe through. Open shows it inside aegis; Alt+O opens any file on the server, and the Files view edits it.

A path in a reply opens its file with one click.

One tap to answer

An agent ends each turn by saying how it ended and may offer up to three replies, which you send with one tap. /model, /effort and /permission switch a running session, and / opens a menu that completes aegis's commands and the agent's own. Alt+M dictates into the box, transcribed in the browser.

Rung 3 · many projectsSeveral projects at once

A Fleet that says who needs you

Each tab and card carries one of six marks: working, needs you, error, review, waiting or done. The Fleet puts the sessions that block on you first, oldest wait on top, and Alt+J goes to the one that has waited longest. Each card shows the plan as a bar with an estimate of the work left.

Push notifications reach a phone with aegis closed.

A panel that stays out of the way

The session panel keeps one compact row per section: the session, the plan with each step's time, the monitors, usage and the host. Hovering a row opens its details beside the panel. Alt+B collapses it, and its edge drags to the width you want.

Hover the panel's rows, drag its edge, or press the panel button in the top bar.

Rung 4 · togetherAgents that work together

They hand work to each other

Every agent gets aegis's tools over MCP. It hands a task to a queue of workers and hears back when one finishes, starts a monitor on a CI run and ends its turn instead of polling, reads what another session is doing, and gives that session context or an instruction. It can also wait on other sessions: monitor_sessions wakes it when they have all finished, or as soon as one needs you.

Every answer lands in the transcript as a new turn, headed by whoever sent it: a monitor, a queue task or another agent.

Queues of workers

An agent hands tasks to a queue and keeps working; each result comes back as a turn in its transcript. A queue names the agent preset its workers run, and how many at once.

Point a queue at a cheaper model for tests, reviews and research.

Rung 5 · a companyA software company on demand

Workflows you approve

When the work has steps that wait on CI, on other branches or on a clock, the agent writes it as a workflow: a tree in which every node says what it does. You approve it on a card, the server runs it, and the agent hears when a step fails or a gate needs you.

Saved workflows live in the project, versioned like code. Reviewers can check implementers inside one.

Schedules, and pages that guide the decisions

A schedule fires a prompt on a clock into a new session or an existing one. One an agent creates waits, paused, until you start it from its card. Decisions arrive as pages you click, and those pages can stay docked beside the transcript.

The Schedules view lists every schedule with its next fire and its runs.

Rung 6 · beyondBeyond one machine and one person

Across machines

aegis link add vps https://dev.example makes this server a client of another aegis. The far server's sessions show in your Fleet under its own band, with its host and quota, and in your tab bar with a server tag. You prompt, interrupt and close them from here, and an agent here hands work to one there with peer_handoff(target="brisk-turing@vps").

The link goes one way. The far server can never reach the one that linked it, so a shared box cannot touch your laptop.

On a phone

Below 760 px the tabs get their own row, the panel becomes a drawer, and touch targets are 44 px. Chrome installs aegis as an app named after the server. A return to a recent tab, or a reconnect after the phone slept, sends only what changed.

A browser you share with the agent

The server holds a Chromium the agent drives and you watch, docked beside its transcript. You can take over, sign in, and hand it back.

Useful for tests against a running app and for sites that need you to log in.

A server for a team

Give each person a token and their own Linux user. Everything they start runs as that user, so the kernel checks every file their agents touch, and each one sees only their own sessions, queues and schedules. A quota policy per person keeps the shared subscriptions fair.

An admin, and root on the host, can still read everything. /multiuser has an agent walk you through the setup.

This window is aegis. Hover anything in it to find its feature; click to read about it.

Fleet
Flaky CI: the websocket…keen-noether
Translate the errorsswift-hopper
Settings page layoutslate-hamming
Benchmark the cold startbrisk-turingvps
+
studio2.8.0
Theme
studiothis server
2 need you
2 working
Host
CPU
38%
RAM
41%12.9 / 31.3 GB
Disk
62%88 / 142 GB
Quotaread 40s ago
Claude
5 hours
22%↻ 3h 10m
week
81%→ 100%↻ 2d 4h
OpenCode Go
5 hours
34%↻ 2h 24m
week
41%↻ 2d 10h
month
72%→ 96%↻ 22d

Sessions

Needs you
keen-noetherneeds you
Flaky CI: the websocket test that waits forever
Two fixes pass locally. Cap the wait at 25 s, or mock the socket? I lean to the cap.
opusclaude-opus-5-5 · acme/api
nowAsk which fix to land · 4m
didWrite both fixes
2m ago$4.121 monitor3/5 · ~18m23%
slate-hammingneeds you
Settings page layout
Pick a layout in the page above, or say what to change.
opusclaude-opus-5-5 · acme/web
just now$1.3716%
Everything else
swift-hopperworking
Translate the error messages to the new catalog
deepseekopencode-go/deepseek-v4-pro · acme/api
Edit · src/errors/catalog.py
just now$0.8448k
calm-dijkstraworking
Port the parser to the new tokenizer
opusclaude-opus-5-5 · acme/api
Bash · Run the parser suite against the fixtures
just now$8.522/4 · ~25m40%
vpsdev.example · linked · 38 ms
1 waiting
1 done
Host
CPU
71%
RAM
58%2.2 / 3.7 GB
Quotaread 1m ago
Claude · same account as studio
brisk-turingwaiting · 1 monitor
Benchmark the cold start on the staging box
opusclaude-opus-5-5 · acme/infra
nowWait for 50 cold starts · 9m
14m ago$3.071 monitor55%
tidy-ramanujandone
Nightly: re-run the import and diff the counts
Import done: 91,237 rows, 12 fewer than last night, all from one source file.
opusclaude-opus-5-5 · acme/data
6h ago$2.401 unread31%
10:41❯
Move every error message in src/errors to the new catalog, keeping the codes stable.
10:41·
OpenCode 2.0.28 · opencode-go/deepseek-v4-pro
10:41⌕
Grepraise .*Error\(" in src/64 matches in 11 files
10:43✎
Writesrc/errors/catalog.py64 entries
10:44⏺

The catalog has all 64 messages under their old codes. Now I am replacing the inline strings file by file, starting with auth.py.

10:45✎
Editsrc/errors/auth.py6 lines changed
src/errors/auth.py
- raise AuthError("token expired, sign in again")
+ raise AuthError(catalog.E_TOKEN_EXPIRED)
10:02❯
The websocket test hangs CI for hours sometimes. Find out why and propose a fix.
10:02⌬
BashRun the websocket test 20 times20 runs, 3 hung
10:04📖
Readtests/test_ws.py212 lines
10:05⏺

The hang is a race. The test awaits recv() with no timeout, and when the server closes first that await never returns. Three of twenty runs hit it here, so CI hits it about once a day.

10:05✎
Edittests/test_ws.pyold_string not found
10:06✎
Edittests/test_ws.py1 line changed
tests/test_ws.py
- msg = await ws.recv()
+ msg = await asyncio.wait_for(ws.recv(), timeout=25)
10:07⌬
BashRun the suite142 passed in 31.2s
10:07⇄
agent:calm-dijkstra · 2026-10-09T10:07:40Z

The tokenizer port touches test_ws.py too. Wait for my merge before you edit it.

10:08⏺

Two fixes pass locally. Capping the wait at 25 s fails the run loudly instead of hanging it. Mocking the socket removes the race from the test, and the thing it tests with it. I lean to the cap.

11:20⇄
monitor_startthe full suite in CImon-7c1e · every 60s
done: gh run view 4821 --json status -q .status | grep -qv in_progress
progress: gh run view 4821 --json jobs -q '[.jobs[]|select(.status=="completed")]|length*100/6'
11:20⇄
queue_enqueuegeneral · Write the migration for the audit tabletask#12 · quiet-lovelace
11:21⇄
peer_readcalm-dijkstra, last 8 entries8 lines
11:21⇄
monitor_sessionsthe tokenizer port and the migrationmon-3a2f · 2 sessions
11:21⏺

CI is watched, the migration is with a worker, and calm-dijkstra is still on the tokenizer. I will rebase once both of them have finished. Ending the turn until something comes back.

11:34⇄
monitor:mon-7c1e · ok · 14m

The run finished: 6 of 6 jobs completed, conclusion success.

11:41⇄
queue:general · task#12 · ok · 2026-10-09T11:41:07Z

Migration 0042 adds the audit table with its two indexes. The migration test passes forward and back. Committed on the branch as 3f9c2a1.

11:42⇄
monitor:mon-3a2f · ok · 2026-10-09T11:42:30Z

the tokenizer port and the migration: ok, every session finished: calm-dijkstra done, quiet-lovelace done, after 21m 9s.

11:43⇄
agent:brisk-turing@vps · 2026-10-09T11:43:52Z

Cold start on staging: p50 1.8 s, p95 3.1 s over 50 runs. The websocket fix does not move it.

11:48❯
Redo the settings page layout. Show me options before you build one.
11:49⇄
artifact_createPick a layoutart-5d0c
11:50✎
Writeartifacts/art-5d0c/index.html74 lines
11:50⇄
artifact_sendart-5d0cdid not start
ReferenceError: layouts is not defined
    at index.html:61
11:51✎
Editartifacts/art-5d0c/index.html1 line changed
11:51⇄
artifact_sendart-5d0cok
11:51▣

Three layouts for the settings page.

▣Pick a layoutlive↗ Open

Pick a layout

Three ways to lay out the settings page. Pick one, or say what to change.

11:51▣

Three layouts for the settings page.

▣Pick a layoutsubmitted↗ Open
answered · 11:52
11:52⇄
artifact:art-5d0c · submit · 2026-10-09T11:52:18Z

answered

{"layout": "sidebar"}
11:52⏺

Sidebar sections it is. Building it in web/settings/Page.tsx now.

11:53✎
Editweb/settings/Page.tsx38 lines changed
10:41❯
Also make the retry wait longer on the second failure, and keep the log of each attempt. dictated ci-log.txt · 12 KB
10:44▤
ws-hang-report.html2 files · page 1 of 2Open
The hang: the test client never closes its socket when the server restarts. Fix and timings inside.
14:02❯
Ship dark mode across the app. Split it, review each part, merge on green.
14:05◇
workflow · ship dark modewaits for your go
  1. implement, 3 workers in worktrees
  2. review each pull request
  3. wait on CI
  4. merge on green
Approve
14:20◷
nightly-benchwaits for your go
clock
daily 03:00
fires
a new opus session in .
prompt
Run the bench and compare with yesterday.
Unpause
10:50⇄
browser_openhttp://localhost:5173/settingsdocked beside the transcript
/model<name>Switch this session's modelaegis
/effortlow…maxChange reasoning effortaegis
/permissionread|write|auto|fullChange what the agent may doaegis
/reviewReview the current changesclaude
reply
opencode-go/deepseek-v4-prohigh effortwrite
claude-opus-5-5high effortfull

One file configures it

aegis reads .aegis.yaml from the nearest ancestor that has one. An agent is a preset of harness, model, effort and permission, and a queue names the agent its workers run as and how many run at once. A new tab starts from a preset and can change any field for that session. aegis init writes a first file from the harnesses installed on the machine, aegis doctor names every problem by its place in the file, and the server follows the file as it changes.

default_agent: opus
agents:
  opus: {harness: claude-code, model: opus, effort: high, permission: full}
  deepseek: {harness: opencode, model: opencode-go/deepseek-v4-pro, effort: high, permission: write}
  reviewer:
    harness: claude-code
    model: opus
    effort: max
    permission: read
    priming: |
      You review changes for correctness and report findings by severity.
queues:
  general: {agent: opus, max_parallel: 5}
recap: {agent: opus}

Permission is read for plan mode, write to accept edits, auto, or full to bypass permissions. An OpenCode or Codex agent names its model as provider/model. The optional recap names the agent that writes a two-sentence recap when you come back to a tab after a while.

What an agent can call

Every session's harness connects to /mcp with its own token, so no tool asks who is calling. The tools are named mcp__aegis__<verb>.

Working together

peer_handoff
Give another session context or an instruction, here or on a linked server (handle@server). It arrives as a new turn.
peer_read
The last entries of another session's transcript, one line each.
session_list
What every open session is doing: its mark and line, what it waits on, its plan, its model and spend.
session_spawn
Start a session from an agent preset, with at most your own permission.
queue_enqueue
Hand a self-contained task to a fresh worker on a queue. The result arrives as a turn when the worker finishes.
task_status, task_cancel, task_resume
Follow a task, cancel it, or put its worker back to work with its conversation intact.
monitor_start, monitor_list, monitor_cancel
Watch a long process with bash conditions, and be woken when one holds, fails or times out.
monitor_sessions
Wait on other sessions, and be woken when they have all finished or as soon as one needs you.

Talking to you

artifact_create, artifact_send
Write a page from a working skeleton and put it in the transcript once it starts in your browser.
artifact_read, artifact_update, artifact_close
Read what the page kept, push new state or a new version into it, or take it back.
turn_end
Say how the turn ended and offer up to three replies. It sets the mark on the tab and the line on the card.
plan_update
Keep the plan where you can see it, timed per step, on the card and in the panel.
file_send
Hand you a file: a card with a preview, Open and Download.

Knowing where it runs

agents_list
The presets it can spawn.
quota_read
How much of each subscription window is left, per provider.
config_doctor
Check .aegis.yaml, the harnesses it names and the state directory.
session_rename, meta
Name its own session, and read how aegis works for it.

Where it runs

aegis serve listens on loopback at port 8742 and prints a URL with a token. Opening it once signs that browser in: the token moves into an HttpOnly cookie that lasts a year. aegis serve -d detaches and outlives the terminal or the SSH connection. Behind a reverse proxy, --origin https://dev.example names the public origin, and the proxy terminates TLS. Agents reach /mcp on loopback, so do not proxy it. A restart brings sessions back stopped, and the next prompt resumes each one.