@agent-native/core 0.63.2 → 0.63.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/dist/client/blocks/library/AnnotatedCodeBlock.d.ts.map +1 -1
  2. package/dist/client/blocks/library/AnnotatedCodeBlock.js +23 -19
  3. package/dist/client/blocks/library/AnnotatedCodeBlock.js.map +1 -1
  4. package/dist/client/blocks/library/diagram.d.ts.map +1 -1
  5. package/dist/client/blocks/library/diagram.js +10 -11
  6. package/dist/client/blocks/library/diagram.js.map +1 -1
  7. package/dist/client/blocks/library/wireframe.d.ts.map +1 -1
  8. package/dist/client/blocks/library/wireframe.js +2 -1
  9. package/dist/client/blocks/library/wireframe.js.map +1 -1
  10. package/dist/server/auth.d.ts.map +1 -1
  11. package/dist/server/auth.js +5 -1
  12. package/dist/server/auth.js.map +1 -1
  13. package/dist/server/onboarding-html.d.ts.map +1 -1
  14. package/dist/server/onboarding-html.js +50 -5
  15. package/dist/server/onboarding-html.js.map +1 -1
  16. package/dist/styles/blocks.css +25 -3
  17. package/docs/content/a2a-protocol.md +48 -10
  18. package/docs/content/actions.md +35 -16
  19. package/docs/content/agent-mentions.md +25 -32
  20. package/docs/content/agent-surfaces.md +31 -0
  21. package/docs/content/agent-teams.md +17 -14
  22. package/docs/content/agent-web-surfaces.md +24 -15
  23. package/docs/content/authentication.md +21 -0
  24. package/docs/content/automations.md +37 -21
  25. package/docs/content/blueprint-installer.md +7 -0
  26. package/docs/content/cli-adapters.md +7 -0
  27. package/docs/content/client.md +14 -0
  28. package/docs/content/cloneable-saas.md +14 -0
  29. package/docs/content/code-agents-ui.md +27 -0
  30. package/docs/content/components.md +21 -0
  31. package/docs/content/context-awareness.md +33 -48
  32. package/docs/content/creating-templates.md +43 -52
  33. package/docs/content/cross-app-sso.md +41 -0
  34. package/docs/content/database.md +41 -21
  35. package/docs/content/deployment.md +23 -6
  36. package/docs/content/dispatch.md +27 -0
  37. package/docs/content/drop-in-agent.md +26 -27
  38. package/docs/content/durable-resume.md +13 -1
  39. package/docs/content/embedding-sdk.md +14 -0
  40. package/docs/content/evals.md +14 -0
  41. package/docs/content/extensions.md +19 -0
  42. package/docs/content/external-agents.md +38 -1
  43. package/docs/content/faq.md +14 -0
  44. package/docs/content/file-uploads.md +20 -0
  45. package/docs/content/frames.md +14 -0
  46. package/docs/content/getting-started.md +34 -16
  47. package/docs/content/harness-agents.md +14 -0
  48. package/docs/content/human-approval.md +15 -30
  49. package/docs/content/key-concepts.md +37 -0
  50. package/docs/content/local-file-mode.md +26 -19
  51. package/docs/content/mcp-apps.md +36 -1
  52. package/docs/content/mcp-clients.md +49 -0
  53. package/docs/content/mcp-protocol.md +36 -0
  54. package/docs/content/messaging.md +34 -8
  55. package/docs/content/migration-workbench.md +7 -0
  56. package/docs/content/multi-app-workspace.md +29 -16
  57. package/docs/content/multi-tenancy.md +14 -0
  58. package/docs/content/native-chat-ui.md +20 -3
  59. package/docs/content/notifications.md +30 -0
  60. package/docs/content/observability.md +20 -1
  61. package/docs/content/observational-memory.md +14 -0
  62. package/docs/content/onboarding.md +32 -41
  63. package/docs/content/plan-plugin.md +14 -0
  64. package/docs/content/pr-visual-recap.md +14 -0
  65. package/docs/content/processors.md +7 -0
  66. package/docs/content/progress.md +23 -0
  67. package/docs/content/pure-agent-apps.md +7 -0
  68. package/docs/content/real-time-collaboration.md +19 -18
  69. package/docs/content/recurring-jobs.md +22 -19
  70. package/docs/content/routing.md +8 -0
  71. package/docs/content/sandbox-adapters.md +19 -0
  72. package/docs/content/security.md +38 -0
  73. package/docs/content/server.md +47 -25
  74. package/docs/content/sharing.md +50 -0
  75. package/docs/content/skills-guide.md +27 -42
  76. package/docs/content/template-analytics.md +71 -41
  77. package/docs/content/template-assets.md +76 -3
  78. package/docs/content/template-brain.md +89 -1
  79. package/docs/content/template-calendar.md +86 -58
  80. package/docs/content/template-chat.md +25 -9
  81. package/docs/content/template-clips.md +124 -16
  82. package/docs/content/template-content.md +146 -47
  83. package/docs/content/template-design.md +62 -2
  84. package/docs/content/template-dispatch.md +56 -9
  85. package/docs/content/template-forms.md +69 -13
  86. package/docs/content/template-mail.md +73 -26
  87. package/docs/content/template-plan.md +80 -1
  88. package/docs/content/template-slides.md +95 -74
  89. package/docs/content/template-videos.md +73 -52
  90. package/docs/content/tracking.md +21 -0
  91. package/docs/content/using-your-agent.md +14 -0
  92. package/docs/content/voice-input.md +31 -10
  93. package/docs/content/what-is-agent-native.md +25 -13
  94. package/docs/content/workspace-connections.md +49 -0
  95. package/docs/content/workspace-management.md +24 -0
  96. package/docs/content/workspace.md +50 -19
  97. package/docs/content/writing-agent-instructions.md +7 -0
  98. package/package.json +1 -1
@@ -11,17 +11,21 @@ you. Open a doc, ask "rewrite this paragraph to be more concise" or "create a
11
11
  page called Q4 Planning with sub-pages for Goals, Metrics, and Risks" - same
12
12
  result whether you do it yourself or ask.
13
13
 
14
- <!-- screenshot:
15
- app: content
16
- view: /<doc-id>
17
- shows: Workspace with sidebar tree (Q3 Roadmap favorited and expanded with Goals/Metrics/Risks, Engineering Wiki with On-call playbook + Architecture overview + Deployment guide, Personal section with Reading list and Ideas, Weekly sync May 1) and the Q3 Roadmap document open in the editor with the agent sidebar
18
- account: screenshot-account (page tree authored on this account; the doc body should NOT begin with the page title — the page chrome already renders it)
19
- capture: 1400x800 viewport, cropped 90px from bottom (final 1400x710)
20
- -->
14
+ ```an-wireframe
15
+ {
16
+ "surface": "desktop",
17
+ "html": "<div style='display:grid;grid-template-columns:210px 1fr;gap:14px;padding:16px;min-height:500px;box-sizing:border-box'><aside class='wf-card' style='display:flex;flex-direction:column;gap:10px'><strong>Content</strong><span class='wf-pill accent'>Q3 Roadmap</span><span class='wf-pill'>Goals</span><span class='wf-pill'>Metrics</span><span class='wf-pill'>Risks</span><hr/><span class='wf-pill'>Engineering wiki</span><span class='wf-pill'>Reading list</span><span class='wf-pill'>Weekly sync</span></aside><main style='display:flex;flex-direction:column;gap:12px;min-width:0;padding:8px 20px'><div style='display:flex;align-items:center;gap:10px'><h1 style='margin:0'>Q3 Roadmap</h1><div style='flex:1'></div><button>Share</button><button class='primary'>Publish</button></div><div class='wf-card' style='flex:1;display:flex;flex-direction:column;gap:12px;padding:22px'><h2 style='margin:0'>Launch goals</h2><p style='margin:0'>Ship the onboarding flow, reduce setup time, and document owner handoffs.</p><div class='wf-box'>At a glance · owner, window, status</div><div class='wf-box'>Top objectives</div><div class='wf-box'>Workstreams table</div></div></main></div>"
18
+ }
19
+ ```
21
20
 
22
- ![Content workspace with the page tree, an open document, and the agent sidebar](/screenshots/content.png)
21
+ When you open the app, you'll see a page tree next to the editor. The agent always knows which page you're viewing and what text you have selected, so document edits can stay grounded in the current page.
23
22
 
24
- When you open the app, you'll see a sidebar tree of pages on the left, the editor in the middle, and the agent in the sidebar on the right. The agent always knows which page you're viewing and what text you have selected.
23
+ ```an-diagram title="One document, many editors" summary="You and the agent both write through the same Yjs pipeline. SQL is the canonical store; local files and Notion are optional sync surfaces."
24
+ {
25
+ "html": "<div class=\"diagram-flow\"><div class=\"diagram-col\"><div class=\"diagram-node\">You type<br><small class=\"diagram-muted\">slash menu, toolbar</small></div><div class=\"diagram-node\">Agent edits<br><small class=\"diagram-muted\">edit-document find/replace</small></div></div><div class=\"diagram-arrow diagram-muted\" aria-hidden=\"true\">&rarr;</div><div class=\"diagram-panel center\"><span class=\"diagram-pill accent\">Yjs CRDT</span><small class=\"diagram-muted\">live, conflict-free merge</small></div><div class=\"diagram-arrow diagram-muted\" aria-hidden=\"true\">&rarr;</div><div class=\"diagram-box\">documents (markdown)<br><small class=\"diagram-muted\">canonical SQL store</small></div><div class=\"diagram-arrow diagram-muted\" aria-hidden=\"true\">&harr;</div><div class=\"diagram-col\"><div class=\"diagram-box\">Local .md / .mdx<br><small class=\"diagram-muted\">/local-files</small></div><div class=\"diagram-box\">Notion pages<br><small class=\"diagram-muted\">pull · push</small></div></div></div>",
26
+ "css": ".diagram-flow{display:flex;align-items:center;gap:12px;flex-wrap:wrap}.diagram-flow .diagram-col{display:flex;flex-direction:column;gap:10px}.diagram-flow .diagram-arrow{font-size:22px;line-height:1}.diagram-flow .center{display:flex;flex-direction:column;align-items:center;gap:4px}"
27
+ }
28
+ ```
25
29
 
26
30
  ## What you can do with it
27
31
 
@@ -101,50 +105,19 @@ pnpm install
101
105
  pnpm dev
102
106
  ```
103
107
 
104
- Open `http://localhost:8083` and create your first page. The agent panel is on the right — try asking it to "create a page called Onboarding and add three sub-pages under it".
105
-
106
- ### Key features (technical) {#key-features}
107
-
108
- ### Hierarchical pages
109
-
110
- Documents nest infinitely via a `parent_id` column. The sidebar renders a draggable tree; children move with their parents and ordering uses an integer `position` field. See `app/components/sidebar/DocumentSidebar.tsx` and `app/components/sidebar/DocumentTreeItem.tsx`.
111
-
112
- ### Rich-text editor
113
-
114
- The editor is built on Tiptap with a custom extension set. It supports headings, lists, tables, code blocks with syntax highlighting, images, and links. Implementation lives in `app/components/editor/DocumentEditor.tsx` and `app/components/editor/VisualEditor.tsx`, with custom nodes under `app/components/editor/extensions/` (`CodeBlockNode.tsx`, `ImageNode.ts`, `DragHandle.tsx`, `NotionExtensions.tsx`).
108
+ Open `http://localhost:8083` and create your first page. Then ask the agent to "create a page called Onboarding and add three sub-pages under it".
115
109
 
116
- Interactive surfaces include:
110
+ ### Key features {#key-features}
117
111
 
118
- - `BubbleToolbar.tsx` formatting toolbar that appears over a selection
119
- - `SlashCommandMenu.tsx` — slash-command inserter for blocks
120
- - `LinkHoverPreview.tsx` — hover previews for inline links
121
- - `TableHoverControls.tsx` — add/remove table rows and columns
122
- - `EmojiPicker.tsx` — emoji picker for page icons
112
+ **Nested pages.** Documents form a draggable tree with favorites, icons, ordering, and page-level sharing.
123
113
 
124
- ### Collaborative editing
114
+ **Rich MDX editor.** Tiptap powers headings, lists, tables, code blocks, images, links, slash commands, selection toolbars, and local React components.
125
115
 
126
- Content is edited through Yjs CRDT so multiple users and the agent can type into the same document at once without clobbering each other. The agent's `edit-document` action writes through the same pipeline as a human keystroke, so changes appear live in every open editor. See [Real-time collaboration](/docs/real-time-collaboration) for the sync model.
116
+ **Live collaboration.** Yjs keeps multiple editors and agent edits in sync without clobbering each other.
127
117
 
128
- ### Search
118
+ **Search and comments.** Full-text search, anchored comments, version history, and restore flows are built into the document surface.
129
119
 
130
- Full-text search across titles and markdown content, powered by `actions/search-documents.ts`. The sidebar exposes a search box; the agent uses the same action via `pnpm action search-documents --query "..."`.
131
-
132
- ### Favorites and icons
133
-
134
- Each document can be favorited (`is_favorite`) and given an emoji `icon`. The index route auto-opens your first favorite on load — see `app/routes/_app._index.tsx`.
135
-
136
- ### Notion sync
137
-
138
- Documents can be linked to a Notion page and synced in either direction:
139
-
140
- - `connect-notion-status` — check whether a Notion integration is connected
141
- - `link-notion-page` — link a local doc to a Notion page
142
- - `pull-notion-page` — overwrite local content from Notion
143
- - `push-notion-page` — overwrite Notion content from local
144
- - `list-notion-links` — list all linked documents
145
- - `sync-notion-comments` — bidirectionally sync comment threads
146
-
147
- Sync state is tracked in the `document_sync_links` table (last synced time, conflict flag, last error). Markdown-to-Notion block conversion lives in `shared/notion-markdown.ts`. Conflict and status UI is in `app/components/editor/NotionConflictBanner.tsx` and `NotionSyncBar.tsx`. See the `notion-integration` skill for the full flow.
120
+ **Sync surfaces.** Documents can sync with Notion or local Markdown/MDX folders, with SQL acting as the collaborative cache/history layer.
148
121
 
149
122
  ### Local file sync
150
123
 
@@ -269,6 +242,132 @@ Nine tables, all defined in `server/db/schema.ts`:
269
242
  - **`document_property_values`** — per-document property values (`property_id` → `value_json`).
270
243
  - **`document_shares`** — per-user and per-org grants created via `createSharesTable`.
271
244
 
245
+ ```an-schema title="Content data model" summary="Nine tables in server/db/schema.ts. documents is the page tree; the rest hang off it for versions, comments, Notion sync, inline databases, and sharing."
246
+ {
247
+ "entities": [
248
+ {
249
+ "id": "documents",
250
+ "name": "documents",
251
+ "note": "The page tree (ownable, markdown body)",
252
+ "fields": [
253
+ { "name": "id", "type": "id", "pk": true },
254
+ { "name": "parent_id", "type": "id", "fk": "documents.id", "nullable": true, "note": "infinite nesting" },
255
+ { "name": "title", "type": "string" },
256
+ { "name": "content", "type": "markdown" },
257
+ { "name": "icon", "type": "string", "nullable": true },
258
+ { "name": "position", "type": "int", "note": "sibling ordering" },
259
+ { "name": "is_favorite", "type": "bool" },
260
+ { "name": "visibility", "type": "enum", "note": "private | org | public" },
261
+ { "name": "owner_email", "type": "string" },
262
+ { "name": "org_id", "type": "id", "nullable": true }
263
+ ]
264
+ },
265
+ {
266
+ "id": "document_versions",
267
+ "name": "document_versions",
268
+ "note": "Full title/content snapshots for version history",
269
+ "fields": [
270
+ { "name": "id", "type": "id", "pk": true },
271
+ { "name": "document_id", "type": "id", "fk": "documents.id" },
272
+ { "name": "title", "type": "string" },
273
+ { "name": "content", "type": "markdown" }
274
+ ]
275
+ },
276
+ {
277
+ "id": "document_comments",
278
+ "name": "document_comments",
279
+ "note": "Threaded comments with quoted-text anchors",
280
+ "fields": [
281
+ { "name": "id", "type": "id", "pk": true },
282
+ { "name": "document_id", "type": "id", "fk": "documents.id" },
283
+ { "name": "thread_id", "type": "id" },
284
+ { "name": "parent_id", "type": "id", "fk": "document_comments.id", "nullable": true },
285
+ { "name": "quoted_text", "type": "string", "nullable": true },
286
+ { "name": "resolved", "type": "bool" },
287
+ { "name": "notion_comment_id", "type": "string", "nullable": true, "note": "bidirectional Notion sync" }
288
+ ]
289
+ },
290
+ {
291
+ "id": "document_sync_links",
292
+ "name": "document_sync_links",
293
+ "note": "One row per Notion-linked document",
294
+ "fields": [
295
+ { "name": "id", "type": "id", "pk": true },
296
+ { "name": "document_id", "type": "id", "fk": "documents.id" },
297
+ { "name": "notion_page_id", "type": "string" },
298
+ { "name": "conflict", "type": "bool" },
299
+ { "name": "content_hash", "type": "string" }
300
+ ]
301
+ },
302
+ {
303
+ "id": "content_databases",
304
+ "name": "content_databases",
305
+ "note": "Inline database objects attached to a document",
306
+ "fields": [
307
+ { "name": "id", "type": "id", "pk": true },
308
+ { "name": "document_id", "type": "id", "fk": "documents.id" },
309
+ { "name": "title", "type": "string" },
310
+ { "name": "view_config", "type": "json" }
311
+ ]
312
+ },
313
+ {
314
+ "id": "content_database_items",
315
+ "name": "content_database_items",
316
+ "note": "Rows in an inline database (each row is a document)",
317
+ "fields": [
318
+ { "name": "id", "type": "id", "pk": true },
319
+ { "name": "database_id", "type": "id", "fk": "content_databases.id" },
320
+ { "name": "document_id", "type": "id", "fk": "documents.id" }
321
+ ]
322
+ },
323
+ {
324
+ "id": "document_property_definitions",
325
+ "name": "document_property_definitions",
326
+ "note": "Column definitions for inline databases",
327
+ "fields": [
328
+ { "name": "id", "type": "id", "pk": true },
329
+ { "name": "name", "type": "string" },
330
+ { "name": "type", "type": "string" },
331
+ { "name": "options", "type": "json", "nullable": true },
332
+ { "name": "position", "type": "int" }
333
+ ]
334
+ },
335
+ {
336
+ "id": "document_property_values",
337
+ "name": "document_property_values",
338
+ "note": "Per-document property values",
339
+ "fields": [
340
+ { "name": "id", "type": "id", "pk": true },
341
+ { "name": "document_id", "type": "id", "fk": "documents.id" },
342
+ { "name": "property_id", "type": "id", "fk": "document_property_definitions.id" },
343
+ { "name": "value_json", "type": "json" }
344
+ ]
345
+ },
346
+ {
347
+ "id": "document_shares",
348
+ "name": "document_shares",
349
+ "note": "Per-user and per-org grants (createSharesTable)",
350
+ "fields": [
351
+ { "name": "id", "type": "id", "pk": true },
352
+ { "name": "document_id", "type": "id", "fk": "documents.id" },
353
+ { "name": "principal", "type": "string" },
354
+ { "name": "role", "type": "enum", "note": "viewer | editor | admin" }
355
+ ]
356
+ }
357
+ ],
358
+ "relations": [
359
+ { "from": "documents", "to": "documents", "kind": "1-n", "label": "has children" },
360
+ { "from": "documents", "to": "document_versions", "kind": "1-n", "label": "has snapshots" },
361
+ { "from": "documents", "to": "document_comments", "kind": "1-n", "label": "has comments" },
362
+ { "from": "documents", "to": "document_sync_links", "kind": "1-1", "label": "links to Notion" },
363
+ { "from": "documents", "to": "content_databases", "kind": "1-n", "label": "hosts databases" },
364
+ { "from": "content_databases", "to": "content_database_items", "kind": "1-n", "label": "has rows" },
365
+ { "from": "document_property_definitions", "to": "document_property_values", "kind": "1-n", "label": "has values" },
366
+ { "from": "documents", "to": "document_shares", "kind": "1-n", "label": "has share grants" }
367
+ ]
368
+ }
369
+ ```
370
+
272
371
  Content is stored as markdown. The editor converts to and from the Tiptap JSON model in memory; the SQL row is always markdown so actions, search, and Notion sync can operate on a single canonical format.
273
372
 
274
373
  All ownable tables include `owner_email` and `org_id` via `ownableColumns()`, so every row is scoped to the signed-in user (and optionally their active organization) from the moment it's created.
@@ -7,9 +7,21 @@ description: "An agent-native HTML prototyping studio — generate, refine, prev
7
7
 
8
8
  Design is an agent-native HTML prototyping studio. Instead of a layered drawing canvas, the agent generates complete self-contained Alpine/Tailwind HTML prototypes, renders them in an iframe, and lets you refine the result with prompts and tweak controls.
9
9
 
10
- ![Design studio showing generated HTML prototypes and tweak controls](https://cdn.builder.io/api/v1/image/assets%2F348da13fcd8b414c87de9066196f7266%2F961bedb713a94463b834c1f2f4643bcf?format=webp&width=1200)
10
+ ```an-wireframe
11
+ {
12
+ "surface": "desktop",
13
+ "html": "<div style='display:flex;flex-direction:column;gap:14px;padding:18px;min-height:520px;box-sizing:border-box'><div style='display:flex;align-items:center;gap:10px'><h1 style='margin:0'>Product launch page</h1><span class='wf-pill accent'>Desktop</span><span class='wf-pill'>Tablet</span><span class='wf-pill'>Mobile</span><div style='flex:1'></div><button>Preview</button><button class='primary'>Export code</button></div><div class='wf-card' style='flex:1;display:grid;grid-template-rows:auto 1fr auto;gap:12px'><div style='display:flex;gap:8px'><span class='wf-pill accent'>Hero</span><span class='wf-pill'>Pricing</span><span class='wf-pill'>FAQ</span></div><div class='wf-box' style='display:flex;align-items:center;justify-content:center;min-height:230px'><strong>Generated HTML prototype</strong></div><div class='wf-card' style='display:flex;align-items:center;gap:10px'><span class='wf-muted'>Make the hero denser and the CTA clearer.</span><div style='flex:1'></div><button class='primary'>Apply revision</button></div></div></div>"
14
+ }
15
+ ```
16
+
17
+ When you open the app, the generated prototype is the center of the workspace, with preview modes, prompt revisions, and export controls close at hand. Everything the agent produces is real HTML you can refine, export, or hand off.
11
18
 
12
- When you open the app, you see your designs on the left, the generated prototype rendered in an iframe in the middle, and the agent plus tweak controls on the right. Everything the agent produces is real HTML you can refine, export, or hand off.
19
+ ```an-diagram title="One artifact, no translation" summary="The agent generates standalone Alpine/Tailwind HTML; the iframe, the editable source, and every export all read the same files. A linked design system feeds tokens into each pass."
20
+ {
21
+ "html": "<div class=\"diagram-design\"><div class=\"diagram-col\"><div class=\"diagram-node\">Prompt<br><small class=\"diagram-muted\">describe screen / page</small></div><div class=\"diagram-pill\">Design system</div></div><div class=\"diagram-arrow diagram-muted\" aria-hidden=\"true\">&rarr;</div><div class=\"diagram-box\" data-rough><span class=\"diagram-pill accent\">Agent generate</span><small class=\"diagram-muted\">standalone HTML / JSX files</small></div><div class=\"diagram-arrow diagram-muted\" aria-hidden=\"true\">&rarr;</div><div class=\"diagram-box\" data-rough>iframe preview<br><small class=\"diagram-muted\">tweak knobs · Cmd+I refine</small></div><div class=\"diagram-arrow diagram-muted\" aria-hidden=\"true\">&#8635;</div><div class=\"diagram-panel center\"><span class=\"diagram-pill ok\">Export</span><small class=\"diagram-muted\">HTML · ZIP · PDF · handoff</small></div></div>",
22
+ "css": ".diagram-design{display:flex;align-items:center;gap:12px;flex-wrap:wrap}.diagram-design .diagram-col{display:flex;flex-direction:column;gap:8px;align-items:flex-start}.diagram-design .diagram-box{display:flex;flex-direction:column;gap:4px}.diagram-design .diagram-arrow{font-size:20px;line-height:1}.diagram-design .center{display:flex;flex-direction:column;align-items:center;gap:4px}"
23
+ }
24
+ ```
13
25
 
14
26
  ## When to pick it
15
27
 
@@ -73,6 +85,54 @@ All data lives in SQL via Drizzle ORM. Schema: `templates/design/server/db/schem
73
85
  | `design_systems` | Reusable brand tokens — `data` (colors/typography/spacing), `assets`, `custom_instructions`, and an `is_default` flag |
74
86
  | `design_shares` / `design_system_shares` | Framework shares tables mapping principals (users or orgs) to roles (viewer, editor, admin) |
75
87
 
88
+ ```an-schema title="Design data model" summary="A design owns its files and versioned snapshots, and optionally links a reusable design system. Both designs and systems are ownable, each with a framework shares table."
89
+ {
90
+ "entities": [
91
+ { "id": "designs", "name": "designs", "note": "A design project (ownable)", "fields": [
92
+ { "name": "id", "type": "id", "pk": true },
93
+ { "name": "title", "type": "text" },
94
+ { "name": "description", "type": "text", "nullable": true },
95
+ { "name": "project_type", "type": "text", "note": "prototype / other" },
96
+ { "name": "data", "type": "json", "note": "starts as {}" },
97
+ { "name": "design_system_id", "type": "id", "fk": "design_systems.id", "nullable": true }
98
+ ] },
99
+ { "id": "files", "name": "design_files", "note": "Files in a design", "fields": [
100
+ { "name": "design_id", "type": "id", "fk": "designs.id" },
101
+ { "name": "filename", "type": "text" },
102
+ { "name": "content", "type": "text" },
103
+ { "name": "file_type", "type": "text", "note": "defaults to html" }
104
+ ] },
105
+ { "id": "versions", "name": "design_versions", "note": "History / rollback", "fields": [
106
+ { "name": "design_id", "type": "id", "fk": "designs.id" },
107
+ { "name": "snapshot", "type": "json" },
108
+ { "name": "label", "type": "text", "nullable": true }
109
+ ] },
110
+ { "id": "systems", "name": "design_systems", "note": "Reusable brand tokens (ownable)", "fields": [
111
+ { "name": "id", "type": "id", "pk": true },
112
+ { "name": "data", "type": "json", "note": "colors / typography / spacing" },
113
+ { "name": "assets", "type": "json", "nullable": true },
114
+ { "name": "custom_instructions", "type": "text", "nullable": true },
115
+ { "name": "is_default", "type": "boolean" }
116
+ ] },
117
+ { "id": "design_shares", "name": "design_shares", "note": "Framework shares table", "fields": [
118
+ { "name": "design_id", "type": "id", "fk": "designs.id" },
119
+ { "name": "role", "type": "text", "note": "viewer / editor / admin" }
120
+ ] },
121
+ { "id": "system_shares", "name": "design_system_shares", "note": "Framework shares table", "fields": [
122
+ { "name": "design_system_id", "type": "id", "fk": "design_systems.id" },
123
+ { "name": "role", "type": "text", "note": "viewer / editor / admin" }
124
+ ] }
125
+ ],
126
+ "relations": [
127
+ { "from": "designs", "to": "files", "kind": "1-n" },
128
+ { "from": "designs", "to": "versions", "kind": "1-n" },
129
+ { "from": "systems", "to": "designs", "kind": "1-n", "label": "applied to" },
130
+ { "from": "designs", "to": "design_shares", "kind": "1-n" },
131
+ { "from": "systems", "to": "system_shares", "kind": "1-n" }
132
+ ]
133
+ }
134
+ ```
135
+
76
136
  A design project is a shell until it has content: `create-design` makes an empty row (`data: "{}"`), then `generate-design` writes the actual standalone HTML/JSX files. The generated artifact, the editable source, and every export all come from the same HTML, so there is no separate "AI mockup" format to translate. A linked design system supplies tokens and `custom_instructions` that the agent honors on every generation pass.
77
137
 
78
138
  Routes in the UI live under `templates/design/app/routes/`: `_index.tsx` (list), `design.$id.tsx` (editor), `present.$id.tsx` (presentation), `design-systems.tsx` and `design-systems_.setup.tsx`, `templates.tsx`, `examples.tsx`, plus `settings.tsx` and `team.tsx`.
@@ -9,18 +9,22 @@ description: "Dispatch is the workspace control plane — central inbox, cross-a
9
9
 
10
10
  Dispatch is the **workspace control plane**. Where other templates are domain apps (Mail, Calendar, Analytics, Brain), Dispatch is the app you run _alongside_ them to coordinate everything: a central inbox, a secrets vault, scheduled jobs, Slack/Telegram integration, and an orchestrator agent that delegates domain work to the right specialist app over [A2A](/docs/a2a-protocol).
11
11
 
12
- <!-- screenshot:
13
- app: dispatch
14
- view: /overview
15
- shows: Overview with "What should we do next?" composer, prompt suggestions (Create a lightweight customer onboarding app / Ask Slides to draft a board update from our latest metrics / Schedule a Monday morning analytics digest), and the Workspace apps grid (Mail / Calendar / Slides / Analytics / Forms / Content + Create app placeholder) showing each mounted path + description
16
- account: screenshot-account (workspace seeded with the six sibling apps registered as A2A peers)
17
- capture: 1400x900 viewport, cropped 90px from bottom (final 1400x810)
18
- -->
19
-
20
- ![Dispatch overview with the orchestrator chat and workspace apps grid](/screenshots/dispatch.png)
12
+ ```an-wireframe
13
+ {
14
+ "surface": "desktop",
15
+ "html": "<div style='display:flex;flex-direction:column;gap:14px;padding:18px;min-height:520px;box-sizing:border-box'><div style='display:flex;align-items:center;gap:10px'><h1 style='margin:0'>Dispatch</h1><span class='wf-pill accent'>Overview</span><span class='wf-pill'>Inbox</span><span class='wf-pill'>Secrets</span><span class='wf-pill'>Approvals</span><div style='flex:1'></div><button>Schedules</button></div><div class='wf-card' style='display:flex;flex-direction:column;gap:10px'><strong>What should we do next?</strong><div class='wf-box'>Ask Analytics for this week's signups and draft a Slack update.</div><button class='primary'>Delegate</button></div><div style='display:grid;grid-template-columns:repeat(3,1fr);gap:10px'><div class='wf-card'><strong>Mail</strong><br/><small>/mail</small></div><div class='wf-card'><strong>Calendar</strong><br/><small>/calendar</small></div><div class='wf-card'><strong>Analytics</strong><br/><small>/analytics</small></div><div class='wf-card'><strong>Slides</strong><br/><small>/slides</small></div><div class='wf-card'><strong>Forms</strong><br/><small>/forms</small></div><div class='wf-card'><strong>Create app</strong><br/><small>+</small></div></div><div class='wf-card' style='display:grid;grid-template-columns:repeat(3,1fr);gap:8px'><div class='wf-box'>Slack DM needs reply</div><div class='wf-box'>A2A task completed</div><div class='wf-box'>Approval required</div></div></div>"
16
+ }
17
+ ```
21
18
 
22
19
  If you're running an [multi-app workspace](/docs/multi-app-workspace) with many apps, Dispatch is the glue.
23
20
 
21
+ ```an-diagram title="Orchestrate, don't specialize" summary="Messages from every channel land in one inbox; the orchestrator triages and delegates domain work to the right specialist app over A2A — secrets, resources, and approvals stay central."
22
+ {
23
+ "html": "<div class=\"diagram-dispatch\"><div class=\"diagram-col\"><div class=\"diagram-node\">Slack · Telegram</div><div class=\"diagram-node\">Email</div><div class=\"diagram-node\">A2A requests</div></div><div class=\"diagram-arrow diagram-muted\" aria-hidden=\"true\">&rarr;</div><div class=\"diagram-box\" data-rough><span class=\"diagram-pill accent\">Orchestrator</span><small class=\"diagram-muted\">central inbox · triage · route</small></div><div class=\"diagram-arrow diagram-muted\" aria-hidden=\"true\">&rarr;</div><div class=\"diagram-col\"><div class=\"diagram-node\">Mail agent</div><div class=\"diagram-node\">Analytics agent</div><div class=\"diagram-node\">Brain · Slides &hellip;</div></div></div><div class=\"diagram-shared\"><span class=\"diagram-pill\">Secrets vault</span><span class=\"diagram-pill\">Workspace resources</span><span class=\"diagram-pill warn\">Approvals</span><span class=\"diagram-pill\">Scheduled jobs</span></div>",
24
+ "css": ".diagram-dispatch{display:flex;align-items:center;gap:12px;flex-wrap:wrap}.diagram-dispatch .diagram-col{display:flex;flex-direction:column;gap:8px}.diagram-dispatch .diagram-box{display:flex;flex-direction:column;gap:4px}.diagram-dispatch .diagram-arrow{font-size:20px;line-height:1}.diagram-shared{display:flex;gap:8px;flex-wrap:wrap;margin-top:12px}"
25
+ }
26
+ ```
27
+
24
28
  ## What it does {#what-it-does}
25
29
 
26
30
  - **Central inbox.** Slack DMs, Telegram messages, email notifications, A2A requests from other agents — all land in one place. The Dispatch agent triages and either handles them itself or delegates. See [Messaging](/docs/messaging) for how to wire Slack, email, and Telegram into your workspace.
@@ -83,6 +87,49 @@ _How it works under the hood (for developers)._
83
87
  - **Vault schema.** Drizzle tables for secrets, grants, requests, approvals, and audit logs. These live in the `@agent-native/dispatch` package (`packages/dispatch/src/db/schema.ts`) and are re-exported into the template via `templates/dispatch/server/db/index.ts` — there is no template-local `server/db/schema.ts`. Dispatch's runtime ships in the package, not in template source (consistent with the note below that `@agent-native/dispatch` owns the shell, sidebar, and built-in pages).
84
88
  - **Slack / Telegram plugins.** Server plugins that register webhooks and forward incoming messages to the orchestrator agent.
85
89
  - **Workspace MCP resources.** Add HTTP MCP server definitions under `mcp-servers/*.json` in Resources, then scope them to All apps or selected app grants just like skills and context.
90
+
91
+ ```an-schema title="Secrets vault schema" summary="Secrets are stored once; grants give a named app access; requests + reviews gate sensitive access; the audit log records who used which secret when. Defined in @agent-native/dispatch (packages/dispatch/src/db/schema.ts)."
92
+ {
93
+ "entities": [
94
+ { "id": "secrets", "name": "vault_secrets", "note": "Stored credential values", "fields": [
95
+ { "name": "id", "type": "text", "pk": true },
96
+ { "name": "owner_email", "type": "text" },
97
+ { "name": "org_id", "type": "text", "nullable": true },
98
+ { "name": "name", "type": "text" },
99
+ { "name": "credential_key", "type": "text" },
100
+ { "name": "value", "type": "text", "note": "secret value" },
101
+ { "name": "provider", "type": "text", "nullable": true }
102
+ ] },
103
+ { "id": "grants", "name": "vault_grants", "note": "Per-app access grant", "fields": [
104
+ { "name": "id", "type": "text", "pk": true },
105
+ { "name": "secret_id", "type": "text", "fk": "vault_secrets.id" },
106
+ { "name": "app_id", "type": "text" },
107
+ { "name": "granted_by", "type": "text" },
108
+ { "name": "status", "type": "text" }
109
+ ] },
110
+ { "id": "requests", "name": "vault_requests", "note": "Access request + review", "fields": [
111
+ { "name": "id", "type": "text", "pk": true },
112
+ { "name": "credential_key", "type": "text" },
113
+ { "name": "app_id", "type": "text" },
114
+ { "name": "reason", "type": "text", "nullable": true },
115
+ { "name": "status", "type": "text" },
116
+ { "name": "reviewed_by", "type": "text", "nullable": true }
117
+ ] },
118
+ { "id": "audit", "name": "vault_audit_log", "note": "Who used which secret when", "fields": [
119
+ { "name": "id", "type": "text", "pk": true },
120
+ { "name": "secret_id", "type": "text", "fk": "vault_secrets.id", "nullable": true },
121
+ { "name": "app_id", "type": "text", "nullable": true },
122
+ { "name": "action", "type": "text" },
123
+ { "name": "actor", "type": "text" }
124
+ ] }
125
+ ],
126
+ "relations": [
127
+ { "from": "secrets", "to": "grants", "kind": "1-n", "label": "granted via" },
128
+ { "from": "secrets", "to": "audit", "kind": "1-n", "label": "use recorded by" }
129
+ ]
130
+ }
131
+ ```
132
+
86
133
  - **MCP hub mode.** Dispatch can still act as the workspace's [MCP hub](/docs/mcp-clients#hub) so every other app in the workspace pulls the same org-scope MCP server list. Separately, Dispatch's own `/_agent-native/mcp` endpoint is the recommended external MCP connector for Claude, ChatGPT, and other hosts that should reach multiple workspace apps.
87
134
 
88
135
  ## Dreams {#dreams}
@@ -7,18 +7,22 @@ description: "Agent-native form builder — create, edit, publish, and route for
7
7
 
8
8
  Forms is an agent-native form builder. Describe the form you want, refine it in the editor, and publish a public form that stores submissions in your own SQL database.
9
9
 
10
- <!-- screenshot:
11
- app: forms
12
- view: /forms/<id>
13
- shows: Editor for a "Beta signup" form sidebar with 5 forms (Beta signup selected, Customer feedback Q3, Job application Engineering, Event RSVP, New customer onboarding); editor pane with title, description, and field cards (Full name, Work email, Your role, Team size, What problem are you hoping to solve?); Edit/Results/Settings/Integrations tabs and Share + Unpublish buttons; agent sidebar with form-related suggestions
14
- account: screenshot-account (forms authored on this account via the standard build flow, with realistic response counts seeded by submitting through the public URL)
15
- capture: 1400x800 viewport, cropped 90px from bottom (final 1400x710)
16
- -->
17
-
18
- ![Forms editor with a form open and the agent sidebar](/screenshots/forms.png)
10
+ ```an-wireframe
11
+ {
12
+ "surface": "desktop",
13
+ "html": "<div style='display:flex;flex-direction:column;min-height:520px;box-sizing:border-box'><div style='display:flex;align-items:center;gap:10px;padding:14px 16px;border-bottom:1.4px solid var(--wf-line)'><strong>Beta signup</strong><span class='wf-pill accent'>published</span><div style='flex:1'></div><button>Share</button><button class='primary'>Unpublish</button></div><div style='display:flex;gap:8px;padding:12px 16px;border-bottom:1.4px solid var(--wf-line)'><span class='wf-pill accent'>Edit</span><span class='wf-pill'>Results 187</span><span class='wf-pill'>Settings</span><span class='wf-pill'>Integrations</span></div><div style='display:flex;flex-direction:column;gap:12px;padding:30px 78px;overflow:hidden'><h2 style='margin:0'>Beta signup</h2><p class='wf-muted' style='margin:0'>Reserve a spot in the upcoming private beta cohort.</p><div class='wf-card'><strong>Full name</strong><input value='Ada Lovelace'/></div><div class='wf-card'><strong>Work email</strong><input value='you@company.com'/></div><div class='wf-card'><strong>Your role</strong><input value='Select...'/></div><div class='wf-card'><strong>Team size</strong><input value='Select...'/></div></div></div>"
14
+ }
15
+ ```
19
16
 
20
17
  When you open the app, you see your forms, the current editor, and a live preview. The agent can create a form from a prompt, update field labels and options, change validation, and connect submission destinations using the same actions the UI uses.
21
18
 
19
+ ```an-diagram title="Build, publish, collect" summary="The agent and the visual editor edit one SQL-backed form definition. The public fill page is unauthenticated, and submissions route server-side to your destinations."
20
+ {
21
+ "html": "<div class=\"diagram-flow\"><div class=\"diagram-col\"><div class=\"diagram-node\">Agent prompt<br><small class=\"diagram-muted\">\"add an NPS question\"</small></div><div class=\"diagram-node\">Visual editor<br><small class=\"diagram-muted\">labels, validation, order</small></div></div><div class=\"diagram-arrow diagram-muted\" aria-hidden=\"true\">&rarr;</div><div class=\"diagram-panel center\"><span class=\"diagram-pill accent\">create-form · update-form</span><small class=\"diagram-muted\">fields JSON, settings JSON</small></div><div class=\"diagram-arrow diagram-muted\" aria-hidden=\"true\">&rarr;</div><div class=\"diagram-box\">forms table<br><small class=\"diagram-muted\">SQL via Drizzle</small></div><div class=\"diagram-arrow diagram-muted\" aria-hidden=\"true\">&rarr;</div><div class=\"diagram-col\"><div class=\"diagram-box\">Public fill page<br><small class=\"diagram-muted\">unauthenticated</small></div><div class=\"diagram-box\">responses<br><small class=\"diagram-muted\">+ Slack / webhook / Sheets</small></div></div></div>",
22
+ "css": ".diagram-flow{display:flex;align-items:center;gap:12px;flex-wrap:wrap}.diagram-flow .diagram-col{display:flex;flex-direction:column;gap:10px}.diagram-flow .diagram-arrow{font-size:22px;line-height:1}.diagram-flow .center{display:flex;flex-direction:column;align-items:center;gap:4px}"
23
+ }
24
+ ```
25
+
22
26
  ## What you can do with it
23
27
 
24
28
  - **Build forms conversationally.** "Create a contact form," "add an NPS score question," "make the email field required." The agent updates the form schema and the preview updates from SQL-backed state.
@@ -70,13 +74,13 @@ npx @agent-native/core@latest create my-platform
70
74
 
71
75
  Pick Forms and any other templates you want during the workspace setup.
72
76
 
73
- ### Key features (technical) {#key-features}
77
+ ### Key features {#key-features}
74
78
 
75
- Forms are defined as JSON field arrays (`FormField[]`) and stored in a single `fields` column no separate table per field type. This makes the schema additive and the agent's edits surgical: changing a field label is a JSON-patch on one column, not a row update across a join table. All field types (text, email, number, long text, select, multi-select, checkbox, radio, date, rating, scale) are handled by the renderer and editor without schema changes.
79
+ **JSON form definitions.** Fields live in one `fields` JSON column, so the agent can make surgical edits without schema changes for every field type.
76
80
 
77
- The public fill page is fully unauthenticated. `toPublicFormSettings` strips integration URLs and other owner-private settings before the form data reaches the browser, so secrets never leak to respondents.
81
+ **Public fill pages.** Respondents can submit unauthenticated forms, while private settings are stripped before data reaches the browser.
78
82
 
79
- Integrations (Slack, Discord, Google Sheets, webhooks) are stored as settings inside the form's `settings` JSON column and executed server-side at submission time.
83
+ **Server-side destinations.** Slack, Discord, Google Sheets, and webhook integrations live in form settings and run after submission.
80
84
 
81
85
  ### Data model
82
86
 
@@ -90,6 +94,58 @@ All data lives in SQL via Drizzle ORM. Schema: `templates/forms/server/db/schema
90
94
 
91
95
  The `fields` and `settings` JSON shapes are defined in `templates/forms/shared/types.ts` (`FormField`, `FormSettings`). Owner-private settings such as integration webhook URLs and allowed origins are stripped before any data reaches the public fill page via `toPublicFormSettings`.
92
96
 
97
+ ```an-schema title="Forms data model" summary="Three tables. Fields and integrations are JSON columns on forms, so the agent's edits are surgical patches rather than cross-table row changes."
98
+ {
99
+ "entities": [
100
+ {
101
+ "id": "forms",
102
+ "name": "forms",
103
+ "note": "A form definition (ownable)",
104
+ "fields": [
105
+ { "name": "id", "type": "id", "pk": true },
106
+ { "name": "title", "type": "string" },
107
+ { "name": "description", "type": "string", "nullable": true },
108
+ { "name": "slug", "type": "string", "note": "unique; public URL" },
109
+ { "name": "fields", "type": "json", "note": "FormField[] — all field types" },
110
+ { "name": "settings", "type": "json", "note": "FormSettings — integrations, etc." },
111
+ { "name": "status", "type": "enum", "note": "draft | published | closed" },
112
+ { "name": "deleted_at", "type": "datetime", "nullable": true, "note": "soft delete" },
113
+ { "name": "owner_email", "type": "string" },
114
+ { "name": "org_id", "type": "id", "nullable": true }
115
+ ]
116
+ },
117
+ {
118
+ "id": "responses",
119
+ "name": "responses",
120
+ "note": "One submission per row",
121
+ "fields": [
122
+ { "name": "id", "type": "id", "pk": true },
123
+ { "name": "form_id", "type": "id", "fk": "forms.id" },
124
+ { "name": "data", "type": "json", "note": "{ fieldId: value }" },
125
+ { "name": "submitted_at", "type": "datetime" },
126
+ { "name": "ip", "type": "string", "nullable": true },
127
+ { "name": "submitter_email", "type": "string", "nullable": true }
128
+ ]
129
+ },
130
+ {
131
+ "id": "form_shares",
132
+ "name": "form_shares",
133
+ "note": "Framework shares table — principals to roles per form",
134
+ "fields": [
135
+ { "name": "id", "type": "id", "pk": true },
136
+ { "name": "form_id", "type": "id", "fk": "forms.id" },
137
+ { "name": "principal", "type": "string", "note": "user or org" },
138
+ { "name": "role", "type": "enum", "note": "viewer | editor | admin" }
139
+ ]
140
+ }
141
+ ],
142
+ "relations": [
143
+ { "from": "forms", "to": "responses", "kind": "1-n", "label": "has responses" },
144
+ { "from": "forms", "to": "form_shares", "kind": "1-n", "label": "has share grants" }
145
+ ]
146
+ }
147
+ ```
148
+
93
149
  ### Key actions
94
150
 
95
151
  Every operation is a TypeScript file in `templates/forms/actions/`, auto-mounted at `POST /_agent-native/actions/:name`: