[{"data":1,"prerenderedAt":389},["ShallowReactive",2],{"navigation":3,"\u002Fconcepts\u002Fprojections-catalog":169,"\u002Fconcepts\u002Fprojections-catalog-surround":384},[4,28,85,127,157],{"title":5,"path":6,"stem":7,"children":8,"icon":27},"Getting Started","\u002Fgetting-started","1.getting-started\u002F1.index",[9,12,17,22],{"title":10,"path":6,"stem":7,"icon":11},"Introduction","i-lucide-house",{"title":13,"path":14,"stem":15,"icon":16},"Installation","\u002Fgetting-started\u002Finstallation","1.getting-started\u002F2.installation","i-lucide-download",{"title":18,"path":19,"stem":20,"icon":21},"Quick start","\u002Fgetting-started\u002Fquick-start","1.getting-started\u002F3.quick-start","i-lucide-zap",{"title":23,"path":24,"stem":25,"icon":26},"Architecture","\u002Fgetting-started\u002Farchitecture","1.getting-started\u002F4.architecture","i-lucide-layers","i-lucide-rocket",{"title":29,"icon":30,"path":31,"stem":32,"children":33,"page":84},"Concepts","i-lucide-lightbulb","\u002Fconcepts","2.concepts",[34,39,44,49,54,59,64,69,74,79],{"title":35,"path":36,"stem":37,"icon":38},"Durable agents","\u002Fconcepts\u002Fdurable-agents","2.concepts\u002F1.durable-agents","i-lucide-infinity",{"title":40,"path":41,"stem":42,"icon":43},"Glossary","\u002Fconcepts\u002Fglossary","2.concepts\u002F10.glossary","i-lucide-book-a",{"title":45,"path":46,"stem":47,"icon":48},"Restate in five minutes","\u002Fconcepts\u002Frestate-primer","2.concepts\u002F2.restate-primer","i-lucide-cpu",{"title":50,"path":51,"stem":52,"icon":53},"Entities & addressing","\u002Fconcepts\u002Fentities-addressing","2.concepts\u002F3.entities-addressing","i-lucide-at-sign",{"title":55,"path":56,"stem":57,"icon":58},"Timelines & events","\u002Fconcepts\u002Ftimelines-events","2.concepts\u002F4.timelines-events","i-lucide-list-ordered",{"title":60,"path":61,"stem":62,"icon":63},"Projections & the catalog","\u002Fconcepts\u002Fprojections-catalog","2.concepts\u002F5.projections-catalog","i-lucide-database",{"title":65,"path":66,"stem":67,"icon":68},"Workspaces & execution","\u002Fconcepts\u002Fworkspaces","2.concepts\u002F6.workspaces","i-lucide-terminal",{"title":70,"path":71,"stem":72,"icon":73},"Harnesses","\u002Fconcepts\u002Fharnesses","2.concepts\u002F7.harnesses","i-lucide-plug",{"title":75,"path":76,"stem":77,"icon":78},"Multi-agent patterns","\u002Fconcepts\u002Fmulti-agent","2.concepts\u002F8.multi-agent","i-lucide-network",{"title":80,"path":81,"stem":82,"icon":83},"Lifecycle & control","\u002Fconcepts\u002Flifecycle","2.concepts\u002F9.lifecycle","i-lucide-sliders-horizontal",false,{"title":86,"icon":87,"path":88,"stem":89,"children":90,"page":84},"Guides","i-lucide-book-open","\u002Fguides","3.guides",[91,106],{"title":92,"icon":93,"path":94,"stem":95,"children":96,"page":84},"Agents","i-lucide-bot","\u002Fguides\u002Fagents","3.guides\u002F1.agents",[97,101],{"title":98,"path":99,"stem":100,"icon":93},"Building agents","\u002Fguides\u002Fagents\u002Fbuilding-agents","3.guides\u002F1.agents\u002F1.building-agents",{"title":102,"path":103,"stem":104,"icon":105},"Frontend integration","\u002Fguides\u002Fagents\u002Ffrontend-integration","3.guides\u002F1.agents\u002F2.frontend-integration","i-lucide-monitor",{"title":107,"icon":108,"path":109,"stem":110,"children":111,"page":84},"Operations","i-lucide-server-cog","\u002Fguides\u002Foperations","3.guides\u002F2.operations",[112,117,122],{"title":113,"path":114,"stem":115,"icon":116},"Self-hosting","\u002Fguides\u002Foperations\u002Fself-hosting","3.guides\u002F2.operations\u002F1.self-hosting","i-lucide-server",{"title":118,"path":119,"stem":120,"icon":121},"Auth & API keys","\u002Fguides\u002Foperations\u002Fauth-api-keys","3.guides\u002F2.operations\u002F2.auth-api-keys","i-lucide-key-round",{"title":123,"path":124,"stem":125,"icon":126},"Backup & restore","\u002Fguides\u002Foperations\u002Fbackup-restore","3.guides\u002F2.operations\u002F3.backup-restore","i-lucide-database-backup",{"title":128,"icon":129,"path":130,"stem":131,"children":132,"page":84},"Reference","i-lucide-book-marked","\u002Freference","4.reference",[133,138,143,148,153],{"title":134,"path":135,"stem":136,"icon":137},"Event schema","\u002Freference\u002Fevents","4.reference\u002F1.events","i-lucide-list-tree",{"title":139,"path":140,"stem":141,"icon":142},"Addressing","\u002Freference\u002Faddressing","4.reference\u002F2.addressing","i-lucide-map-pin",{"title":144,"path":145,"stem":146,"icon":147},"Gateway HTTP API","\u002Freference\u002Fgateway-api","4.reference\u002F3.gateway-api","i-lucide-webhook",{"title":149,"path":150,"stem":151,"icon":152},"CLI","\u002Freference\u002Fcli","4.reference\u002F4.cli","i-lucide-square-terminal",{"title":154,"path":155,"stem":156,"icon":83},"Configuration","\u002Freference\u002Fconfiguration","4.reference\u002F5.configuration",{"title":158,"path":159,"stem":160,"children":161,"icon":163},"Contributing","\u002Fcontributing","5.contributing\u002F1.index",[162,164],{"title":158,"path":159,"stem":160,"icon":163},"i-lucide-git-pull-request",{"title":165,"path":166,"stem":167,"icon":168},"The package map","\u002Fcontributing\u002Fpackage-map","5.contributing\u002F2.package-map","i-lucide-boxes",{"id":170,"title":60,"body":171,"description":377,"extension":378,"links":379,"meta":380,"navigation":381,"path":61,"seo":382,"stem":62,"__hash__":383},"docs\u002F2.concepts\u002F5.projections-catalog.md",{"type":172,"value":173,"toc":367},"minimark",[174,183,188,201,208,212,219,239,243,269,276,280,283,334,341,358,362],[175,176,177,178,182],"p",{},"Everything you read from teaspill — timelines, the entity registry — is a ",[179,180,181],"strong",{},"projection",": a one-way copy flowing out of the agents to the places you read from. This page explains the read side, and the catalog in particular.",[184,185,187],"h2",{"id":186},"write-side-read-side","Write side, read side",[175,189,190,191,195,196,200],{},"Agents do their work inside their own handlers, against their own durable state. Everything readable — the ",[192,193,194],"a",{"href":56},"timeline"," stream, the catalog rows — is copied ",[197,198,199],"em",{},"outward"," from there, and nothing is ever read back in to make a decision. The arrow points one way.",[175,202,203,204,207],{},"This is why readers can never hurt writers: a dashboard polling a thousand catalog rows, a browser replaying a year-old timeline — none of it touches a running agent. It also means what you read is a ",[197,205,206],{},"consequence"," of what agents did, never an input to it.",[184,209,211],{"id":210},"exactly-once-in-one-sentence","Exactly-once, in one sentence",[175,213,214,215,218],{},"Every event an agent produces lands in its timeline exactly once, in order, even across crashes and retries on either side. The mechanism that guarantees this is called the ",[179,216,217],{},"outbox"," — you'll only care about the name if you work on teaspill itself.",[220,221,222],"accordion",{},[223,224,227],"accordion-item",{"icon":225,"label":226},"i-lucide-microscope","Under the hood: the outbox",[175,228,229,230,234,235,238],{},"Events are staged inside the agent's own transaction, numbered by the single writer, then flushed to the history store through an idempotent producer keyed on ",[231,232,233],"code",{},"(entityId, seq)",". A crash between flush and confirmation replays the flush; the store recognizes the already-appended numbers and treats them as no-ops. The same flush updates the catalog row's ",[231,236,237],{},"head_seq",", so the registry's \"how far along is this entity\" answer tracks the timeline it summarizes.",[184,240,242],{"id":241},"the-catalog","The catalog",[175,244,245,246,249,250,253,254,257,258,261,262,265,266,268],{},"The ",[179,247,248],{},"catalog"," is the Postgres registry of every entity — type, status, parent, tags — that your UI subscribes to as live-updating queries. One row per entity, keyed by its ",[192,251,252],{"href":51},"entity URL",", carrying its current status (",[231,255,256],{},"active",", ",[231,259,260],{},"idle",", or ",[231,263,264],{},"archived","), its parent's URL if it has one, its tags, and ",[231,267,237],{}," — the number of the last event confirmed onto its timeline.",[175,270,271,272,275],{},"The catalog syncs to browsers through ",[179,273,274],{},"Electric",", an open-source Postgres sync engine: a client subscribes to a filtered view — all entities of a type, the children of a parent, everything with a given status — and receives changes live, without polling. A dashboard of running agents is a catalog subscription and nothing more.",[184,277,279],{"id":278},"what-to-build-on-what","What to build on what",[175,281,282],{},"Three reads-and-writes cover every UI:",[284,285,286,299],"table",{},[287,288,289],"thead",{},[290,291,292,296],"tr",{},[293,294,295],"th",{},"You want",[293,297,298],{},"Build on",[300,301,302,313,323],"tbody",{},[290,303,304,308],{},[305,306,307],"td",{},"Lists, dashboards, org charts of agents",[305,309,245,310,312],{},[179,311,248],{}," — subscribe to filtered rows",[290,314,315,318],{},[305,316,317],{},"Conversation detail, activity feeds",[305,319,245,320,322],{},[179,321,194],{}," — replay + live-follow one entity",[290,324,325,328],{},[305,326,327],{},"Buttons that do things (spawn, send, control)",[305,329,245,330,333],{},[179,331,332],{},"gateway API"," — commands go through your backend",[175,335,336,337,340],{},"Lists come from the catalog; depth comes from timelines; writes go through the ",[192,338,339],{"href":145},"gateway",". Mixing these up — say, building a list by scanning timelines — works, but fights the grain: the catalog already maintains exactly that answer, live.",[342,343,344],"note",{},[175,345,245,346,349,350,353,354,357],{},[192,347,348],{"href":103},"Frontend integration guide"," wires all three into a browser app with ",[231,351,352],{},"@teaspill\u002Ffrontend-sdk",". For how the pieces fit inside the platform, see ",[192,355,356],{"href":166},"the package map",".",[184,359,361],{"id":360},"next-steps","Next steps",[175,363,364,365,357],{},"So far, agents think and talk. For agents that run commands and touch files, they need somewhere safe to do it: ",[192,366,65],{"href":66},{"title":368,"searchDepth":369,"depth":370,"links":371},"",1,2,[372,373,374,375,376],{"id":186,"depth":370,"text":187},{"id":210,"depth":370,"text":211},{"id":241,"depth":370,"text":242},{"id":278,"depth":370,"text":279},{"id":360,"depth":370,"text":361},"The read side of teaspill — one-way copies of what agents do, and the live registry your UI subscribes to.","md",null,{},{"icon":63},{"title":60,"description":377},"RsR0_qIUhvn84tAoWBXRgHIfUJx7DQ389g4XESRn_eY",[385,387],{"title":55,"path":56,"stem":57,"description":386,"icon":58,"children":-1},"The append-only record of everything an agent does — numbered events your UI can replay, live-follow, or join late.",{"title":65,"path":66,"stem":67,"description":388,"icon":68,"children":-1},"The sandboxed environment an agent's tools run in, and the executor plane that hosts it.",1784473422772]