System Overview
Avocado Studio is a pnpm monorepo with four apps and eight packages: The orchestrator has three parallel front doors: the Content Studio web app for humans, the MCP server for AI assistants, and the Jira integration for ticket-driven workflows. All three go through the same operation pipeline — Zod validation, undo history, version log, demo-mode gating — so anything you can do in the web editor, you can do from Claude Desktop, Claude Code, or a Jira ticket (and vice versa). See MCP Server and Jira Integration for setup.Data Flow: From Chat to Preview
When a user sends a message in the Content Studio, here’s what happens:Packages
The monorepo includes eight shared packages:| Package | Purpose |
|---|---|
@avocadostudio-ai/shared | Zod schemas for PageDoc, BlockInstance, Operation, EditPlan. Block registry. Shared types across all apps. |
@avocadostudio-ai/blocks | 20 built-in block renderers (Hero, CTA, FAQ, Gallery, etc.). Each block is a React component with a typed Zod schema. |
@ai-site-editor/preview-adapter | PreviewBridge component that runs inside the site iframe. Handles postMessage communication with the Content Studio, block selection overlays, and CSS highlights. |
@ai-site-editor/site-sdk | SDK for integrating AI editing into any Next.js 15+ site. Provides route handlers, draft mode utilities, and content resolution for the Content Studio. |
@ai-site-editor/editor-puck | Puck-based visual drag-and-drop editor, including the chat sidebar prototype. Generates the same ops as chat mode and publishes via the orchestrator. |
create-ai-site-editor | CLI scaffolder that generates a Next.js site wired to the orchestrator (editor API routes, block manifest, draft mode, optional CMS template). |
@ai-site-editor/migration-sdk | Utilities for migrating existing content into the PageDoc / BlockInstance shape. |
@ai-site-editor/immersive-widget | Embeddable widget used for immersive / full-bleed block experiences. |
Communication Protocols
Content Studio ↔ Orchestrator: HTTP + SSE
The Content Studio communicates with the orchestrator via REST API and Server-Sent Events:POST /chat/start— Start a streamed run, returns astreamIdGET /chat/stream?streamId=…— Subscribe to the stream via SSEPOST /chat— Non-streaming variant (immediate response)GET /draft/pages— Fetch current draft page statePOST /ops— Apply hand-authored operations (bypassing the planner)POST /history/undo,POST /history/redo— Undo/redo operationsPOST /publish— Publish draft to production
Content Studio ↔ Site: postMessage
The Content Studio embeds the site in an iframe. They communicate via thesite-editor/v1 postMessage protocol:
- Content Studio → Site: Request block highlight, navigate to page, refresh preview
- Site → Content Studio: Report selected block, confirm preview updated, send block manifest
Orchestrator ↔ Site: HTTP
The site fetches draft content from the orchestrator when in draft mode:GET /draft/pages— All draft pages for the current sessionGET /draft/slugs— Available page slugs
Session State
The orchestrator maintains per-session state for each editing session:- Draft pages — Current page content with all pending edits
- Operation history — Full undo/redo stack
- Edit plans — Generated plans awaiting approval
- Session config — Selected AI provider, model tier, locale
.data/orchestrator.db, via better-sqlite3 + WAL) with synchronous transactional writes on every mutation, so crash recovery is automatic.
SQLite is the working copy, not the source of truth. Your CMS / JSON file / custom store is the origin; SQLite holds drafts, undo stacks, and chat history scoped per session. On the first chat for a fresh session, the orchestrator calls the configured CmsAdapter.getPages() to seed SQLite. On publish, onPublish(pages) writes back. That separation is what lets the same chat UX work against any upstream store without per-integration handshakes.
The orchestrator runs as a single instance with a local SQLite file. Multi-replica horizontal scaling — which would require moving state to a network-accessible store (Postgres, Turso/libSQL, Redis, etc.) — is on the roadmap but not implemented today.
Publishing Pipeline
Publishing promotes draft content to production: ThePublishTarget interface is pluggable. Three built-in targets ship in the box:
site-contract— POSTs pages + assets to the remote site’s/api/editor/publishendpoint. Selected whensiteOriginis supplied.git— Serializes draft pages to JSON, commits, and pushes to a Git branch. A Vercel deploy hook wired to that branch auto-builds.deploy-hook— Calls a rawVERCEL_DEPLOY_HOOK_URLand polls the Vercel API for deployment status.
registerPublishTarget() to integrate with any workflow — S3, GitLab Pages, Netlify, a CMS API, a custom CI/CD pipeline. See How it Works — Publishing for the full interface.