Learn / Foldkit Plus

How they fit together

mermaid
flowchart TB
  app["Foldkit application<br/>Model · Message · update · Commands"]
  surface["foldkit-surface<br/>Projection · field refs · Message subsets · Module"]
  agent["foldkit-agent"]
  agentAdapters["foldkit-agent-webmcp · foldkit-agent-mcp<br/>foldkit-agent-a2a · foldkit-agent-native"]
  remote["foldkit-remote<br/>normalized server cache"]
  server["foldkit-remote-server"]
  drizzle["foldkit-remote-drizzle"]
  sync["foldkit-sync<br/>local replica"]
  durable["foldkit-durable<br/>ordered server log"]
  mirror["foldkit-mirror<br/>URL · KeyValueStore"]
  bundle["foldkit-bundle<br/>Submodel placements"]
  bundleSurface["foldkit-bundle-surface"]
  primitives["foldkit-primitives<br/>ready-made bundles · entries · Mounts"]
  mixins["foldkit-mixins<br/>typed view extension points"]
  mixinsSurface["foldkit-mixins-surface"]
  mixinsUi["foldkit-mixins-ui"]
  entity["foldkit-entity<br/>the domain, declared once"]
  guard["foldkit-guard<br/>who may do what · enforced on every seam"]
  form["foldkit-form<br/>headless form from an operation's input"]
  mixinsForm["foldkit-mixins-form"]
  mixinsCrud["foldkit-mixins-crud"]
  cms["foldkit-cms<br/>drafts beside the row · derived state"]
  cmsDrizzle["foldkit-cms-drizzle<br/>audience boundary · drafts · publish"]
  crud["foldkit-crud<br/>editor · list · detail · remover"]
  metadata["foldkit-metadata<br/>opaque typed metadata"]
  ssr["foldkit-ssr<br/>server render · Model handover · resume"]
  richtext["foldkit-richtext<br/>semantic documents · transactions"]
  richtextDom["foldkit-richtext-dom<br/>contenteditable adapter · editor Bundle"]
  mixinsRichtext["foldkit-mixins-richtext<br/>toolbars · menus · handle · source mode"]
  richtextMarkdown["foldkit-richtext-markdown<br/>Markdown in and out · source sessions"]
  richtextCode["foldkit-richtext-code · -code-shiki<br/>code tokenizers · syntax decorations"]
  react["foldkit-react<br/>React islands · Foldkit in React"]
  reactCodegen["foldkit-react-codegen<br/>views compiled to React TSX"]
  composition["foldkit-composition<br/>a page as Blocks in Regions · experimental"]
  builder["foldkit-builder<br/>the page editor, as a form key · experimental"]
  mixinsBuilder["foldkit-mixins-builder<br/>the page editor, drawn · experimental"]
  dataGrid["foldkit-data-grid<br/>grid geometry · experimental"]
  mixinsDataGrid["foldkit-mixins-data-grid<br/>the grid, drawn · experimental"]

  app -- "describe observation / capability" --> surface
  app --> mixins
  app --> bundle --> bundleSurface
  app --> primitives
  app --> dataGrid
  bundle --> dataGrid
  dataGrid --> mixinsDataGrid
  crud -- "rows from a list" --> dataGrid
  sync -- "edits to server rows" --> remote
  mixins --> mixinsDataGrid
  bundle --> primitives
  surface --> bundleSurface
  surface --> agent --> agentAdapters
  surface --> remote --> server
  drizzle --> server
  surface --> sync --> durable
  surface --> mirror
  surface --> mixinsSurface
  mixins --> mixinsSurface
  mixins --> mixinsUi
  entity -- "read by" --> remote
  entity -- "bound to tables" --> drizzle
  entity --> form
  entity --> guard
  guard --> cmsDrizzle
  bundle --> form
  form --> mixinsForm
  mixins --> mixinsForm
  form --> crud
  crud --> mixinsCrud
  entity --> cms
  form --> cms
  crud --> cms
  cms --> cmsDrizzle
  drizzle --> cmsDrizzle
  mixins --> mixinsCrud
  remote --> crud
  metadata --> surface
  metadata --> entity
  metadata --> composition
  composition --> builder
  bundle --> builder
  form --> builder
  primitives --> builder
  builder --> mixinsBuilder
  mixins --> mixinsBuilder
  surface --> ssr
  remote -- "resume part" --> ssr
  app --> richtext --> richtextDom
  richtext --> richtextMarkdown
  richtext --> richtextCode
  richtextMarkdown --> mixinsRichtext
  bundle --> richtextDom
  richtextDom --> mixinsRichtext
  mixins --> mixinsRichtext
  app --> react
  app -- "views read as source" --> reactCodegen

The arrows are integration boundaries, not new application state machines. Agent projects application capabilities. Remote reconciles server facts into the Model. Sync replays application Messages against an authoritative server order. Mirror keeps a secondary representation of Model fields. Mixins extends view structure without touching Model state. Primitives packages reusable browser and clock behaviour without hiding state. Entity declares a domain once as plain values; Remote, the Drizzle binding, and Form read it, and Crud joins a form to a Remote operation. Form and Crud own their submodel transitions inside the parent Model; Entity describes structure without holding runtime state. Durable can also be used independently as an ordered server journal.

The rule that makes the whole graph composable is one owner per datum:

StateOwnerPackage
The route, the selection, a transient errorthe local Model, plain update—
A reusable child machine's slice, placed once or per keythe parent Modelfoldkit-bundle places
A media query, timer reading, socket state, device list, or clipboard resultthe parent Modelfoldkit-primitives places
A filter the URL shows, a draft a device remembersthe local Modelfoldkit-mirror observes
Facts owned by another systemthe serverfoldkit-remote caches
Client-authored state that must survive offline and convergethe durable logfoldkit-sync + foldkit-durable
An edit to a row the server owns, until the table has itthe journal; the table is its read modelfoldkit-sync/entity lays it over Remote's row
Which cell has focus, what is selected, how the columns standthe grid's Bundle in the parent Modelfoldkit-data-grid places
What an agent may see and dothe applicationfoldkit-agent observes and exposes

That ownership rule is more important than the package boundaries. A single Surface may read across local state, Remote state, and Submodels because a Surface is an observation/capability boundary, not a second owner.