Tutti
A desktop workspace where several coding agents share one set of files, tasks and app outputs, so context moves between Claude Code and Codex instead of through you.

What it is
A desktop workspace that puts several coding agents in the same room instead of asking you to carry context between them. The README names Claude Code, Codex and Hermes as supported, with OpenClaw in development; Cursor and Gemini also appear in the shipped provider icons and probes. They share one workspace: a mention reaches another agent’s past conversations, files, app invocations and tasks, and a reference adds a local file or something an app produced. Tutti ships its own app center — image generation, UI design, documents, decks — that people and agents both call, with every output left in the workspace for the next step. Agents keep running on the subscription their owner already pays for, and the daemon, its SQLite state and the workspace stay on the machine. A second, multi-user product, Tutti · VM, is in Early Access: each agent still runs on its owner’s machine behind a managed local VM while the working state is shared into a cloud Room. The repository is Apache-2.0 and holds 5,361 commits.
Who built itAn organisation account rather than a person. Twenty-six accounts have committed to the repository, and 5,166 of its 5,361 commits carry a linked account. The line is led by SingleMai with 1,256 commits, then devRickyyy 898, jomeswang 798, rv4no 505, hugozhou-ai 488, chovy-ai 364 and copper6666 336; another 195 commits have no linked account at all. Of the 1,088 co-author trailers, 760 name a model or an agent tool rather than a person — “Claude Opus 4.8 (1M context)” on 239, “Claude Fable 5” on 215, “Cursor” on 146 and “Claude Sonnet 5” on 60 — and the largest trailer naming a contributor is rv4no, on 237.
How it is put together
The parts · 6One local daemon, one renderer shell and one lifecycle core, with the boundaries written down before the code. Everything durable and every business rule lives in services/tuttid, a Go daemon the desktop app supervises; the desktop is a renderer plus an Electron main process and is explicitly forbidden from becoming a second business core. Agent behaviour is deliberately not organised by provider: packages/agent/host owns session, turn, goal and runtime-operation lifecycle for every provider, the daemon and other hosts write adapters against it, and a conformance directory is the only place new lifecycle semantics may be proven. The interface follows the same instinct — the Agent GUI reads capabilities from a descriptor and renders by capability rather than branching on a provider name — and the repository enforces it with boundary checkers and a degradation ratchet that compares the GUI against a committed baseline. Because the product is a workspace rather than a chat window, most of the work is in the seams: what a mention carries, how an app output becomes referenceable by the next agent, how a recording of one session becomes a portable cassette that replays without a database, and how a build gets from a candidate to a public download without anyone rebuilding it.
- services/tuttid/
- The daemon and primary business core, 1,463 files:
api/with the generated OpenAPI server (a 1.7 MBserver.gen.go),service/with 890 files, plusbiz/,data/,server/,app/,integration/,builtin-apps/andtypes/. The service layer is where provider detection and installation, agent extensions, workspace apps, issues, terminal and file handling live. - packages/agent/
- The largest area by file count, 2,909 files:
host/with 142 files is the provider-neutral lifecycle core and its conformance scenarios,gui/holds 1,277 files of interface,daemon/807 files of provider protocol, and around them sitclaude-sdk-sidecar/,activity-core/,session-replay/,session-replay-runner/,session-replay-ui/,store-sqlite/andruntimeprep/. - apps/desktop/
- The Electron shell, 1,375 files across
main/,preload/,renderer/andshared/— 1,042 of them in the renderer. It supervises the daemon, exposes the typed bridge and is barred from holding business rules;apps/cli/(19 files),apps/mobile/(215 files, Android and iOS) andapps/ui-storyboard/sit beside it. - docs/
- 199 files in four registers: 37 architecture documents, led by a 231,006-character
agent-gui-node.md; 38 convention documents, including a troubleshooting tree whoseagent-session-lifecycle.mdis 340,594 characters; 30 dated specification and plan files underspecs/and 24 underplans/; and 12 files underadr/, being ten numbered decision records plus a glossary and an index. - .github/workflows/, .changeset/ and tools/scripts/
- The release and validation machinery: 23 workflows covering desktop release, promotion, notification, store submission, Windows alpha and adapters, Android, npm packages, the app catalog and runtime, and the external pull-request review gate; 113 files under
.changeset/, 112 of them one-line change notes and one the config; and 186 scripts, including the changed-aware runner and a 120 KB agent session replay runner. - .codex/skills/ and the root instruction files
- Five agent skills with their own manifests — performance trace analysis, app release, architecture review, session replay recording and a test audit — plus a
skills-lock.jsonthat pins two further skills, by hash, to a separatetutti-agent-skillsrepository.AGENTS.mdroutes by path and by module name,CONTEXT.mdis a glossary whose entries carry anti-terms, and two refactor files sit at the repository root.
Choices, and what they beat
Agent lifecycle semantics live in
packages/agent/hostover keeping them in the daemon adapter that talks to each providerAGENTS.mdwrites the rule as a decision question and says that a consumer which finds a missing capability should add it to the host and release it rather than reimplement it in the adapter.GetSession,UpdateSettings,UpdatePinandDeleteSessionwere added that way in PR #1329, andpnpm check:agent-host-boundaryfails when new orchestration surfaces appear in the adapter instead.Share one class-based Workbench host kernel with a second product over each product keeping its own host coordination
ADR 0009, accepted 2026-07-11, records that dependency injection alone does not decide which state is renderer-singleton and which is scope-local, when subscriptions, save queues and caches are disposed, or how a user change stops one cached snapshot leaking into another room. It also fixes an exit condition rather than an intention: if the extraction produces a React runtime dependency or a host-to-surface cycle, the extraction must stop.
Give agent session replay a shared application core over each product owning its own recording and replay
ADR 0010 puts the recording and cassette contracts in
packages/agent/session-replayand leaves ephemeral replay process identity, progress and settlement to product adapters. The cassette is portable, schema v7 is the only accepted version with no older reader, migration or fallback, and ceilings of 8 MiB per decoded provider frame, 256 MiB on disk and 384 MiB per cassette are recorded in the manifest so that anomalous growth is attributable.A stable release stays a candidate until a person approves it over letting the release workflow publish on its own
Release candidates and betas promote automatically, but a stable candidate must be submitted manually and pass a protected environment whose required reviewers are three named accounts. Promotion revalidates the candidate manifest, the checksums, the locked runtime version for every supported platform and that the public channel does not move backwards, is serialised because channel pointers are shared mutable state, and never rebuilds installers.
Windows is part of every change by default over treating it as a portability task for later
AGENTS.mdmakes Windows part of the compatibility contract for every change, including changes that do not mention it, and lists what triggers the assessment: paths, filesystem semantics, executable discovery and suffixes, command quoting, shell selection, environment variables, process creation, signals, permissions, symlinks, sockets, packaging and native dependencies. Every change must carry a Windows impact assessment, and operating-system differences stay in the owning adapter instead of being scattered through business logic.
Read fromAGENTS.md, docs/architecture/project-structure.md, docs/architecture/agent-gui-refactor-plan.md, the Chinese refactor handoff and the remaining-issues record at the repository root, docs/adr/0009-cross-product-workbench-host-kernel.md, docs/adr/0010-agent-session-replay-boundary.md, docs/conventions/local-git-hooks.md, docs/conventions/desktop-release.md, docs/README.md, the root package.json and .changeset/config.json, the pull request template, and the complete 8,293-file tree with sizes.
Build log
6 stages- 01
Three months, 5,361 commits, and a release with nothing after it
The repository was created on 2026-06-12T12:29:05Z, and its oldest commit is dated about seventeen hours earlier:
feat: init project for tutti open source, 2026-06-11T19:38:27Z. The published history is 5,361 commits, distributed 1,467 in June, 2,862 in July, 1,029 in August and 3 in September. The newest isfix(agent): require current Codex CLI (#2643)at 2026-09-05T06:07:25Z, and the last push to the default branch is 2026-09-05T07:16:52Z — nine seconds after releasev0.2.33appeared, which is why that release reads as the end of the visible line of work rather than a point along it. At the 2026-10-01 snapshot the repository showed 3,791 stars, 384 forks, 114 watchers and 192 open issues, and this record files it as maintained rather than active: four weeks without a push, after a month that produced 1,029 commits and a September that produced three, is a pause, and nothing about the repository is archived. The queue kept moving after the commits stopped, since four pull requests dated 2026-09-13 and 2026-09-14 are still open. - 02
Three places code may live, and one package that owns the rules
AGENTS.mdopens by naming the shape — a local-first desktop monorepo — and then does something more useful than a diagram: it says which area owns what and closes the usual escapes.services/tuttidholds daemon product rules, durable local state and adapters;packages/agent/hostowns provider-neutral agent lifecycle;apps/desktopis the Electron shell and “must not become a second business core”; and packages may not be calledshared,common,utilsorclient-sdk. The lifecycle rule is written as a question rather than a preference — if a change defines when a session, turn, goal or runtime operation is created, when it may be sent or when it is terminal, it belongs in the host package; if it is transport, query or presentation, it is an adapter concern — and new lifecycle semantics must first gain a scenario underpackages/agent/host/conformance.pnpm check:agent-host-boundaryratchets against new coordinator, worker or actor orchestration surfaces appearing in the adapter. The document cites its own enforcement:GetSession,UpdateSettings,UpdatePinandDeleteSessionwere added to the host in PR #1329 after a downstream consumer surfaced the need, rather than reimplemented inside that consumer. - 03
What actually travels between the agents
The README describes the problem as being the messenger between agents, and the fix as one real-time shared workspace where context, files, running tasks and app output are connected. Three mechanisms carry it. The first is a mention, which the README calls “Big @”: inside one agent you can reference another agent’s past conversations, files, app invocations and tasks, and you can ask one agent to direct another. The second is a reference added from the chat box, which pulls in a local file or something an app produced. The third is the app center itself — image generation, UI/UX design, documents and decks — which people and agents both call, run on the owner’s existing agent subscriptions rather than on resold model access, and whose output stays in the workspace for the next step. Underneath, provider differences are kept out of the interface: the Agent GUI refactor handoff records that Claude Code arrives through an SDK sidecar, Codex through its own app-server protocol, and OpenCode and Cursor through standard ACP, with the Tutti Agent on its own protocol family and Nexight, Hermes and OpenClaw on ACP, unavailable ones explicitly disabled — so that a transport protocol is not treated as a seam of the interface, and a new provider cannot require an identity branch in the controller, composer or view.
- 04
An 800-line ceiling and a ratchet that only turns one way
Business files are capped at 800 lines by a repository lint rule that excludes blank and comment-only lines, and the cap is treated as a signal to decompose rather than a target to argue with. Around it sits a validation stack that is itself part of the product:
pre-commitruns staged-file formatting plus eight boundary checks, andpre-pushrunspnpm check:changed -- --push-ready, which selects lanes from the changed file set instead of running everything. Each lane stores a fingerprint of its inputs, so a failed run can be retried with--failed-onlyand only the lanes whose inputs moved will run again. Full validation is a small orchestration script with preparation, preflight and validation phases, compact output by default and per-task logs under.tmp/check-full-runs. The sharpest rule is the Agent GUI degradation ratchet: a committed 17 KB baseline is compared against entropy metrics on every run, and the check fails on any increase, or on a decrease that was not locked in by updating the baseline in the same change. The refactor that made this possible is documented in the repository in Chinese: a handoff note dated 2026-07-11 records a controller falling from 2,034 lines to under 800 across seven slices, with a single private persisted-state reader deliberately left behind until a client coverage window closes. - 05
A release that is not allowed to publish itself
The desktop release convention describes three shapes — a stable release that becomes Latest, and
-rc.<n>and-beta.<n>prereleases. The twenty most recent releases run fromv0.2.6on 2026-07-30 tov0.2.33on 2026-09-05: twenty in thirty-seven days, three of them on 2026-07-30 itself. Release candidates and betas promote themselves after staging; a stable release stops as a candidate and needs a separate promotion run plus approval from adesktop-stable-releaseenvironment whose required reviewers are three named accounts, self-review allowed. Promotion rechecks the candidate manifest, the checksum file, the locked runtime version for every supported platform and that the public channel does not move backwards, then copies assets to an immutable path, creates the formal tag, writes the channel pointer and changelog and refreshes the stable alias; it never rebuilds installers. Release notes come from a model when a key is configured and from a deterministic commit summary when it is not; operators edit only a marked bilingual review section, which promotion turns into the reviewed summary. Nightly releases, S3 runtime artifacts, Linux artifacts and Microsoft Store prereleases are excluded by design, and on 2026-09-02 a pull request removed the daily scheduled build trigger, describing that as having no documentation impact. - 06
What outside contributors found
An external pull request cannot merge until a member of the
tutti-rdteam approves the current head commit, and a new push refreshes it. The findings are specific. One contributor showed that imported sessions were identified by provider session id alone, which collapsed 427 transcript files into 33 sessions: the import wizard rendered 769 rows with 375 distinct identities and 397 duplicate React keys; the fix joins the source path into the hash, leaving one identity rule for every import source. Another found that the locale check discovered modules through a hardcoded list of three names while the convention called those names non-exhaustive examples, so four shipped manifests had silently been excluded from every translation check. A third traced a Cursor answer arriving as one line — 2,662 characters with no newline — tostrings.HasPrefix(text, ""), which is always true after trimming, so whitespace-only chunks carrying paragraph breaks were dropped as duplicates. A fourth explained a Gemini CLI failure as the CLI relaunching itself and installing emptySIGINT,SIGTERMandSIGHUPhandlers, after which the ACP probe could finish initialisation and still report that the process did not exit. A fifth fixes a click that opened two browser tabs, because two handlers both took the gesture; the fix drops the second activation of the same address inside 80 milliseconds.
Adjacent records
All records →No. 070
OpenChatCut
A local-first video editor whose editing surface is a conversation: the built-in agent and external Codex or Claude Code sessions call the same editing tools the interface itself uses, so every change lands on a real multi-track timeline as a clip, transition, caption, effect or audio item that can still be dragged, undone and exported. Projects and media stay on the machine, and preview and final render both come out of Remotion.
No. 061
Reticle
An MCP server and a dev-only SDK that let a coding agent read and drive a running web or desktop app from the inside, then answer with a verdict and the file and line to fix instead of a screenshot.
No. 077
Lody
A workspace where a team shares the coding agents it already runs: connect a machine, bring Claude Code, Codex, Kimi or any other agent that speaks the protocol, and dispatch work from desktop, phone, web or terminal while sessions delegate to each other and the code stays on the machine its owner connected.