← back

universe

2026

the agent-native workspace, on your Mac

a desktop app where agents do real work on your machine: a conversation on the left, an artifact panel on the right that renders what they build (documents, data, code, decks, live browsers, even the iOS Simulator) streaming in as it happens. runs on four engines: Claude Code, Codex, Gemini, Grok, and Mantis, drives a real Chrome, syncs sessions across your Macs, and remembers: every agent is an identity with its own accumulating memory.

0:00 / 0:00

electron, five engines, 23 tool servers, ~/.universe as the record

  • typescript
  • electron
  • react
  • node
  • sqlite
  • postgres
  • fastapi
  • mcp
  • claude agent sdk
  • sse
  • streamable http
  • content addressed sync
  • zod

the problemExecution locality

The agent works on the repo that is already checked out, drives the Chrome profile you are already signed into, and writes files you can open in Finder. None of that survives being moved to a server, so the model call happens on your machine, billed to your own account. The server never sees prompts, completions or token counts. Usage is self-reported by the client.

That is the constraint everything else has to live with. Sharing, resuming on a second machine, several people in one conversation: all of it sits on a record stored on a laptop that is asleep half the time. ~/.universe is the source of truth. The SQLite file next to it is a cache, and deleting it costs a directory walk.

your Macelectron main and renderer · ~/.universe on diskthe model call itselfthe apigrants and membership · encrypted blobs · the SSE fan-outpostgresspaces, channels · the room log · shared transcriptsthe webshare pages · published apps
three planes, and what each owns
your Macthe prompt and the answerthe files, before and afterthe Chrome profile, the simulatorwhich provider login paysthe serverthat a session ranblobs it cannot readwho may open the spacea usage number the client reported
what each side can see

spacesSpaces, rooms and ordering

A space carries folder grants, an agent, a model and a memory into every session filed under it. The desktop owns what a space contains, the server owns who can open it, and one uuid names the local row, the remote row and the directory on disk. Spaces you never share never reach the server.

A room is not a new object. Its id is a session id, so opening one opens a session several people prompt from different Macs. Each Mac calls the model itself, so there is no shared clock: the server assigns the sequence number, the client mints the id. Two Macs writing the same room merge rather than race.

a room
a channel row whose id is a session id. a thread is the same row with kind set to thread.
resolution order
room token, then a unique path match, then refuse and name the candidates
not shared
the working tree. a write into a sibling's artifacts races that session's sync, so it is refused.
rendererelectron mainthe sibling sessionroom tokena reference, not a pathnot a path, open itroom, then pathexactly one matchpng intext over the capcomposermints a room tokenthe referenceroom, then pathprompt block2,500 char budgetspace_read_artifacta tool, not a pathstrip the @resolveambiguous, refuseits workspace dirread onlydownscale1,568px jpeghead of file400 KB cap
resolving @space/board-prep/artifacts/docs/report.md
mac auniverse-apimac ba message groupa pointer, not a copypg_notifythis roomseq is last + 1everything after seqthe model callhappens herepush the group409 lifted for roomsassigns seqroom logdedupes on group idfan outdrops bodies over 7,000sseone listener per processlocal mirrora gap means refetchthe chat columnone list, no clocks
two Macs, one room
a promptaddressed to the agentcosts a model calllands in the transcriptthe model reads ita team messageaddressed to the peoplecosts nothinglands in the space's messagesthe model sees it only if it asks
prompts vs team messages

the crewCrew concurrency

A crew shares one working directory, so two agents can collaborate through artifacts/ with no protocol at all. What the filesystem cannot give you is addressing. That is what the six crew tools are for: a roster, a mailbox, and a read-only window into what somebody else is doing. Models address each other as @2, the number in the rail, because handing a model a 36-character uuid is a step that only ever goes wrong.

No locks, no leases, no worktree per worker. Each member gets the roster and a diff of what changed in the tree since it last ran, capped at 25 paths. Concurrent writes are last-writer-wins, which is fine at eight members and would not be at eighty.

depth 2
main to worker to worker, and no generation after that. depth is what makes a crew unreadable.
broadcast read state
one row with n recipients cannot share a single read_at, so it is held in memory and fails redundant
6 rounds
how long a handoff auto-continues before the parent pauses and asks you
the modelcrew toolsthe runtimeon diskthe fork-bomb budgetparent is busydrained when freethe same cwdcrew_spawntitle, brief, agentcap: 8 members, depth 2roster rown = max + 1the rail redraws firstpark until a clean bou…one runner per memberstart itinbox, then the tree diffroster on diskrewritten wholeartifacts/one tree, all members
crew_spawn to the worker's first reply
1crew_sendto @32fileda row, and a line in mail.js…3wokenno-op if already busy4peekedread, not consumed5committedonly once the run finishes
a message from @1 to @3
the rosterwho else is here · who it reports to · read before you editits own brainthe agent's standing instructions · 7,000 char capthe spaceMEMORY.md · the live journalthe taskthe card this is work onthe skillsthe ones attached · an index of the rest
what a worker is handed, in order

the relayRemote execution

The Agent SDK does not spawn claude directly, it spawns whatever pathToClaudeCodeExecutable points at. Point that at a small bridge and the same session runs on another machine with the event parser, the persistence and the UI unchanged. The first version piped stdio back over the network and died immediately: herds reaps a session when whatever holds its stdio goes away, which is what closing a laptop does.

So the far Mac launches claude under nohup, appends stream-json to a file and writes the exit code beside it. The bridge tails that file and nothing more. Coming back, the far machine's filesystem is authoritative rather than our local note, because the app may have been killed before it wrote anything down. Somebody else's Mac is a different path entirely: the prompt goes into a queue and whichever machine holds the runner lease drains it, which makes it an ordinary local session with the full tool set.

the same path
~/.universe/sessions/<id> on both machines, so a path in a transcript means the same thing on either
two verbs, one name
place and push briefly shared a name while their arguments silently differed, and every remote session fell back to this Mac without logging it
exit 127
a bare .py ran under the system python, which has no herds installed. the bridge bakes the interpreter in.
this Macthe fleetthe far Macsession idthe workspaceas the executablewhich machineone shell scripttailed, never pipedpick the machinepinned, not scheduledcopy the session dirrelay, 0.49sthe bridgestands in for the binaryherds control planewho is awake, and whereidentical pathso paths in the transcript resolvenohup claudeoutlives the lidstream-json, appended
placing a session on the mac mini
on launchthe far Macthis Maccandidatesonline onlyrun idremote cwdon exitno roster, try anywayruns with no exit codelist the fleetwho is awakestill appendingask for the pathnever assume itattach and replayfrom line onefetch the work back
reattach after relaunch, designed and not yet wired
this Macyour other Macsomebody else's
all 171 toolsyesnoyes
survives the lid closingn/ayesyes
live output while runningyesyesyes
resume after an app relaunchyesnot yetyes
who holds the filesherethe far Macthe far Mac

The far Mac runs the agent with no in-process tool servers, because those live in this app and there is no app over there. Somebody else's Mac is the opposite case: it is their app running it, so everything is present.

what is available where
your own Macthe executable is swapped for a bridgenohup, survives the lidno in-process tool servers out thererelay only: direct took 9s, relay 0.49ssomebody else's Macqueued as a row, drained on a tickone runner lease at a time, with an expiryall 171 tools, it is local over therethe transcript comes back every 700ms
your Mac vs somebody else's

the toolsTool transport

Every tool server is constructed in-process, so a tool call is a function call that already holds the SQLite handle and the CDP connection to Chrome. Nineteen are registered unconditionally. Four are conditional, and the conditions are the interesting part: space tools only for a filed session, chain only while a session is driving itself, training only for runs started from the agent library, simulator and Blender only on macOS.

Codex and Mantis are separate binaries and cannot be handed an in-process object, so the app binds 127.0.0.1 on an ephemeral port and serves one path per session, agent and server. The path is the entire routing table. The token is 32 random bytes, compared in constant time, never written to disk. A fresh server instance is built per request, because one instance holds a single transport at a time.

bridged servers ask first
every one is set to approve, because an approval policy of never refuses them instead of running them
no tool search
nothing is deferred. every engine is handed all 171 schemas every time, and that is the next thing to fix.
reading its own work
the agent reads its own output and its crew's straight off disk, because six lanes in flight and nothing merged is silent otherwise
phone24 toolsvideo19 toolssimulator17, mac onlyappdata12 toolsdev12 toolsblender10, mac onlybrowser8 toolssites7 toolsspace7, filed onlyartifacts6 toolscrew6, agent scopedlibrary6 toolsskills6 toolsmail5 toolschain5, self-driving onlytasks4 toolswork4 toolscalendar4 toolsschedules3 toolsaccounts2 toolsmusic2 toolsmodel1 tooltraining1, library only
23 servers, 171 tools, all in-process
serverconditiontools
19 of themunconditional132
spaceonly a filed session7
chainonly while self-driving5
trainingonly from the agent library1
simulatormacOS only17
blendermacOS only10

A session that is not filed under a space has no space tools at all, rather than tools that fail at call time. The conditions are evaluated once, when the runner is built.

which servers a session gets, and when
out of processthe bridgeelectron maintoken from its env127.0.0.1 onlysession, agent, serverbrowsermcp__browser__browser_opencodex-clia separate binaryone http requeststreamable httpcheck the tokenconstant time compareparse the pathfour parts, no tablea server per requestone transport eachthe same 23 serverschrome over cdpyour real profile
codex calling browser_open over loopback
claude, in-processa function callthe approval hook runs firstevery path argument is policy-checkedservers built once per runnercodex, over loopbackjson over httpno approval hook at allthe sandbox is the only boundservers built per request
a tool call, in-process vs over loopback

the hard partsThree failures worth writing down

The planner used to be a fork of the session taken at the end of each round: same model, same memory, asked what to do next. It ran with an empty tool list and no servers, resumed a transcript full of browser and crew calls, and reached the only conclusion available from inside, which was that every server had disconnected. The session now decides while it is still running, and the Stop hook blocks exactly once, because a session that cannot end cannot be closed, synced or billed.

The other two were silent for weeks. Message groups over 300 KB were replaced with a stub written for a read-only viewer; rooms have no viewer, so the Mac that wrote the group read its own apology back and persisted it over the real one. And opening a room rewrote a bookkeeping file that was inside the synced manifest, so the sync layer read the changed hash as a local edit and parked every incoming version from then on.

a smaller copy is not an update
a relayed copy with fewer items or less text does not win, whatever the far end claims. compared on both axes.
the repair
recovered all 11 stubbed groups from transcript.jsonl. 15 more ran on somebody else's Mac and could not be.
an empty manifest
pull prunes, so publishing an empty manifest deletes a colleague's artifacts. never published now.
decisions made171 decisionssaid tools were gone21 decisionscomplete verdicts18 decisionsof those, same claim8 decisions
the forked planner, measured on one Mac's record

One message group: an agent avatar, six tool calls with their results, and a thinking block.

  1. as written412 KB. over the ceiling, so something has to go
  2. the avatar147,857 bytes, dropped first. 267 KB
  3. tool resultstruncated to 4,000 chars each. 198 KB
  4. tool inputstruncated to 400 chars each. 191 KB
  5. still over?drop payloads entirely, keep every row
  6. still over?thinking blocks go
  7. last resortstub the one largest call, not the whole group
a 412 KB group, elided down to the 300 KB ceiling
1the agent avatar147,857 bytes2tool results, theninputs4,000 then 4003drop payloadsevery row survives4thinking blocks5stub the groupone of seven, not seven
elision order: biggest field first
a colleague's Macobject syncuniverse-apia file nobody editedread as a local editonly ever asked for v0 and v1stop hashing itthe stored hash is now wrongan honest baselineopen the roomupdatedAt bumpsthe manifest hash changesdiverged both sidesparked, permanentlyexclude bookkeeping filesout of the manifest walkrebaselinerecompute the old hashnewer versionsnever fetched
why a room's artifacts stopped syncing

where it standsSupport status

It ships as a signed and notarized DMG at 0.4.35 and updates itself. Spaces, rooms, crews, the relay, resuming on a second machine, five engines, 23 tool servers and search across every session all work end to end.

The part I would defend hardest is the record. Every problem above got easier the moment a session stopped being rows in a database file and became a directory with an append-only log in it.

working end to endrooms stay ordered across Macssessions placed on another Maccrews of eight on one treecross-room reads by referencesearch across every sessionstill openeach Mac's agent has its own memoryall 171 schemas, every callno lock on the shared treean agent cannot speak in a roomwriting across rooms is refused
done versus open
universe56 channelsspaces51 channelsskills38 channelssim33 channelssessions28 channelsteams19 channelsmodels16 channels
500 ipc channels, the seven largest families