@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.
- package/dist/client/blocks/library/AnnotatedCodeBlock.d.ts.map +1 -1
- package/dist/client/blocks/library/AnnotatedCodeBlock.js +23 -19
- package/dist/client/blocks/library/AnnotatedCodeBlock.js.map +1 -1
- package/dist/client/blocks/library/diagram.d.ts.map +1 -1
- package/dist/client/blocks/library/diagram.js +10 -11
- package/dist/client/blocks/library/diagram.js.map +1 -1
- package/dist/client/blocks/library/wireframe.d.ts.map +1 -1
- package/dist/client/blocks/library/wireframe.js +2 -1
- package/dist/client/blocks/library/wireframe.js.map +1 -1
- package/dist/server/auth.d.ts.map +1 -1
- package/dist/server/auth.js +5 -1
- package/dist/server/auth.js.map +1 -1
- package/dist/server/onboarding-html.d.ts.map +1 -1
- package/dist/server/onboarding-html.js +50 -5
- package/dist/server/onboarding-html.js.map +1 -1
- package/dist/styles/blocks.css +25 -3
- package/docs/content/a2a-protocol.md +48 -10
- package/docs/content/actions.md +35 -16
- package/docs/content/agent-mentions.md +25 -32
- package/docs/content/agent-surfaces.md +31 -0
- package/docs/content/agent-teams.md +17 -14
- package/docs/content/agent-web-surfaces.md +24 -15
- package/docs/content/authentication.md +21 -0
- package/docs/content/automations.md +37 -21
- package/docs/content/blueprint-installer.md +7 -0
- package/docs/content/cli-adapters.md +7 -0
- package/docs/content/client.md +14 -0
- package/docs/content/cloneable-saas.md +14 -0
- package/docs/content/code-agents-ui.md +27 -0
- package/docs/content/components.md +21 -0
- package/docs/content/context-awareness.md +33 -48
- package/docs/content/creating-templates.md +43 -52
- package/docs/content/cross-app-sso.md +41 -0
- package/docs/content/database.md +41 -21
- package/docs/content/deployment.md +23 -6
- package/docs/content/dispatch.md +27 -0
- package/docs/content/drop-in-agent.md +26 -27
- package/docs/content/durable-resume.md +13 -1
- package/docs/content/embedding-sdk.md +14 -0
- package/docs/content/evals.md +14 -0
- package/docs/content/extensions.md +19 -0
- package/docs/content/external-agents.md +38 -1
- package/docs/content/faq.md +14 -0
- package/docs/content/file-uploads.md +20 -0
- package/docs/content/frames.md +14 -0
- package/docs/content/getting-started.md +34 -16
- package/docs/content/harness-agents.md +14 -0
- package/docs/content/human-approval.md +15 -30
- package/docs/content/key-concepts.md +37 -0
- package/docs/content/local-file-mode.md +26 -19
- package/docs/content/mcp-apps.md +36 -1
- package/docs/content/mcp-clients.md +49 -0
- package/docs/content/mcp-protocol.md +36 -0
- package/docs/content/messaging.md +34 -8
- package/docs/content/migration-workbench.md +7 -0
- package/docs/content/multi-app-workspace.md +29 -16
- package/docs/content/multi-tenancy.md +14 -0
- package/docs/content/native-chat-ui.md +20 -3
- package/docs/content/notifications.md +30 -0
- package/docs/content/observability.md +20 -1
- package/docs/content/observational-memory.md +14 -0
- package/docs/content/onboarding.md +32 -41
- package/docs/content/plan-plugin.md +14 -0
- package/docs/content/pr-visual-recap.md +14 -0
- package/docs/content/processors.md +7 -0
- package/docs/content/progress.md +23 -0
- package/docs/content/pure-agent-apps.md +7 -0
- package/docs/content/real-time-collaboration.md +19 -18
- package/docs/content/recurring-jobs.md +22 -19
- package/docs/content/routing.md +8 -0
- package/docs/content/sandbox-adapters.md +19 -0
- package/docs/content/security.md +38 -0
- package/docs/content/server.md +47 -25
- package/docs/content/sharing.md +50 -0
- package/docs/content/skills-guide.md +27 -42
- package/docs/content/template-analytics.md +71 -41
- package/docs/content/template-assets.md +76 -3
- package/docs/content/template-brain.md +89 -1
- package/docs/content/template-calendar.md +86 -58
- package/docs/content/template-chat.md +25 -9
- package/docs/content/template-clips.md +124 -16
- package/docs/content/template-content.md +146 -47
- package/docs/content/template-design.md +62 -2
- package/docs/content/template-dispatch.md +56 -9
- package/docs/content/template-forms.md +69 -13
- package/docs/content/template-mail.md +73 -26
- package/docs/content/template-plan.md +80 -1
- package/docs/content/template-slides.md +95 -74
- package/docs/content/template-videos.md +73 -52
- package/docs/content/tracking.md +21 -0
- package/docs/content/using-your-agent.md +14 -0
- package/docs/content/voice-input.md +31 -10
- package/docs/content/what-is-agent-native.md +25 -13
- package/docs/content/workspace-connections.md +49 -0
- package/docs/content/workspace-management.md +24 -0
- package/docs/content/workspace.md +50 -19
- package/docs/content/writing-agent-instructions.md +7 -0
- package/package.json +1 -1
|
@@ -7,17 +7,21 @@ description: "An agent-powered email client. Connect your Gmail and the agent ca
|
|
|
7
7
|
|
|
8
8
|
An agent-powered email client. Connect your Gmail account and the agent can read, draft, send, and organize email for you — alongside a fast, keyboard-first inbox you can drive yourself. Think Superhuman, but the agent is a first-class citizen and the codebase is yours to own.
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
-->
|
|
10
|
+
```an-wireframe
|
|
11
|
+
{
|
|
12
|
+
"surface": "desktop",
|
|
13
|
+
"html": "<div style='display:flex;flex-direction:column;min-height:500px;box-sizing:border-box'><div style='display:flex;align-items:center;gap:12px;padding:12px 16px;border-bottom:1.4px solid var(--wf-line)'><strong>Inbox 16</strong><div style='flex:1'></div><span data-icon='search' aria-label='Search'></span><span data-icon='edit' aria-label='Compose'></span><span data-icon='bell' aria-label='Notify'></span></div><div style='display:flex;flex-direction:column;padding:8px 14px;gap:6px'><div class='wf-box' style='display:grid;grid-template-columns:155px 1fr auto;gap:12px;align-items:center'><strong>Priya Mehta</strong><span><strong>Q3 launch</strong> — final assets ready for review</span><span>★</span></div><div class='wf-box' style='display:grid;grid-template-columns:155px 1fr auto;gap:12px;align-items:center'><strong>Acme Billing</strong><span>Your monthly invoice is ready</span><span>11:10 AM</span></div><div class='wf-box' style='display:grid;grid-template-columns:155px 1fr auto;gap:12px;align-items:center'><span>Marcus Tang</span><span>Onboarding flow research findings</span><span>Yesterday</span></div><div class='wf-box' style='display:grid;grid-template-columns:155px 1fr auto;gap:12px;align-items:center'><span>GitHub</span><span>[framework] PR ready for review</span><span>Yesterday</span></div><div class='wf-box' style='display:grid;grid-template-columns:155px 1fr auto;gap:12px;align-items:center'><span>Linear</span><span>Issue ENG-1287 assigned to you</span><span>May 2</span></div><div class='wf-box' style='display:grid;grid-template-columns:155px 1fr auto;gap:12px;align-items:center'><span>Stripe</span><span>Weekly payments summary</span><span>Apr 29</span></div><div class='wf-box' style='display:grid;grid-template-columns:155px 1fr auto;gap:12px;align-items:center'><span>Calendly</span><span>New booking confirmed</span><span>Apr 28</span></div></div></div>"
|
|
14
|
+
}
|
|
15
|
+
```
|
|
17
16
|
|
|
18
|
-
|
|
17
|
+
When you open the app, the keyboard-first inbox and thread view stay focused on the mail itself. The agent always knows which view you're in and which thread you have open, so you can say "archive this" or "draft a friendly decline" without explaining what "this" is.
|
|
19
18
|
|
|
20
|
-
|
|
19
|
+
```an-diagram title="How a mail request flows" summary="Keyboard shortcuts and agent prompts run the same actions. Email lives in Gmail; drafts, automations, and tracking live in SQL and application_state."
|
|
20
|
+
{
|
|
21
|
+
"html": "<div class=\"diagram-flow\"><div class=\"diagram-col\"><div class=\"diagram-node\">You drive<br><small class=\"diagram-muted\">J/K/E/R shortcuts</small></div><div class=\"diagram-node\">You ask the agent<br><small class=\"diagram-muted\">\"draft a friendly decline\"</small></div></div><div class=\"diagram-arrow diagram-muted\" aria-hidden=\"true\">→</div><div class=\"diagram-panel center\"><span class=\"diagram-pill accent\">Actions</span><small class=\"diagram-muted\">list-emails · get-thread · manage-draft · send</small></div><div class=\"diagram-arrow diagram-muted\" aria-hidden=\"true\">→</div><div class=\"diagram-col\"><div class=\"diagram-box\">Gmail<br><small class=\"diagram-muted\">multi-account, via OAuth</small></div><div class=\"diagram-box\">SQL + application_state<br><small class=\"diagram-muted\">drafts · automations · tracking</small></div></div><div class=\"diagram-arrow diagram-muted\" aria-hidden=\"true\">↻</div><div class=\"diagram-box\">Inbox refreshes live</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
|
+
```
|
|
21
25
|
|
|
22
26
|
## What you can do with it
|
|
23
27
|
|
|
@@ -112,27 +116,15 @@ To connect Gmail in dev, you need a Google OAuth client:
|
|
|
112
116
|
|
|
113
117
|
Tokens are stored in the `oauth_tokens` SQL table and refresh automatically. You can connect multiple Gmail accounts once the first is set up.
|
|
114
118
|
|
|
115
|
-
### Key features
|
|
116
|
-
|
|
117
|
-
**Gmail sync (multi-account).** Connect one or many Google accounts via OAuth. List and search actions query all connected inboxes by default; results carry an `accountEmail` field so you can tell which inbox each thread came from. Scope to a single account with `--account=user@example.com`. OAuth tokens are stored via `@agent-native/core/oauth-tokens` under the `"google"` provider.
|
|
118
|
-
|
|
119
|
-
**Multiple compose drafts.** The compose panel supports multiple draft tabs at once. Each draft is stored as an `application_state` entry at `compose-{id}` and syncs live between the agent and the UI. The agent can create a new draft with `manage-draft --action=create`, edit your in-progress draft with `--action=update`, or close tabs with `--action=delete`. Drafts use markdown in the body field; the TipTap editor renders it as rich text and converts to HTML on send.
|
|
120
|
-
|
|
121
|
-
**Queued draft review.** Drafts requested by teammates or Slack are durable SQL rows in `queued_email_drafts`. The agent uses `queue-email-draft` to assign a draft to an org member, returns a review URL such as `/draft-queue/<id>`, and waits for the owner to review or explicitly send. The queue supports listing assigned drafts, editing them, opening one in the compose panel, dismissing it, and sending one or all reviewed drafts.
|
|
119
|
+
### Key features
|
|
122
120
|
|
|
123
|
-
**
|
|
121
|
+
**Multi-account Gmail.** Connect one or more Google accounts, then list, search, draft, send, label, archive, star, or trash across connected inboxes.
|
|
124
122
|
|
|
125
|
-
**
|
|
123
|
+
**Draft workflows.** Multiple compose drafts sync through application state, and queued SQL drafts let teammates or Slack users request mail for the owner to review and send.
|
|
126
124
|
|
|
127
|
-
**
|
|
125
|
+
**Automations and tracking.** Natural-language triage rules can label, archive, mark read, star, trash, or trigger manually; sent messages can track opens and clicks.
|
|
128
126
|
|
|
129
|
-
**
|
|
130
|
-
|
|
131
|
-
- `pnpm action bulk-archive --older-than=30` archives everything older than N days.
|
|
132
|
-
- `pnpm action export-emails --view=inbox --output=file.json` dumps a view to JSON.
|
|
133
|
-
- Archive, trash, mark-read, and star all accept comma-separated IDs (`--id=id1,id2,id3`) for bulk changes.
|
|
134
|
-
|
|
135
|
-
**Inline thread previews in agent chat.** When the agent answers a question about a specific thread, it can embed a live preview of the thread directly in the chat message via an `embed` code fence. The preview is a sandboxed iframe that shows the full conversation without leaving the chat, with an "Open in app" button that navigates the main window to that thread.
|
|
127
|
+
**Search, bulk actions, and previews.** Shared actions power inbox search, bulk archive/export, and inline thread previews the agent can embed in chat.
|
|
136
128
|
|
|
137
129
|
### How the agent sees your context
|
|
138
130
|
|
|
@@ -164,6 +156,61 @@ When a Google account is connected, email lives in Gmail — the app is a view o
|
|
|
164
156
|
|
|
165
157
|
Emails flowing through the API have the shape `{ id, threadId, from, to, cc, subject, snippet, body, date, isRead, isStarred, isArchived, isTrashed, labelIds, accountEmail, attachments }`.
|
|
166
158
|
|
|
159
|
+
```an-schema title="Mail SQL tables" summary="Email itself lives in Gmail. The SQL tables hold what Gmail doesn't: queued drafts, send-tracking events, and OAuth tokens. Settings and ephemeral state live in the settings and application_state stores."
|
|
160
|
+
{
|
|
161
|
+
"entities": [
|
|
162
|
+
{
|
|
163
|
+
"id": "queued_email_drafts",
|
|
164
|
+
"name": "queued_email_drafts",
|
|
165
|
+
"note": "Teammate/Slack-requested drafts awaiting owner review",
|
|
166
|
+
"fields": [
|
|
167
|
+
{ "name": "id", "type": "id", "pk": true },
|
|
168
|
+
{ "name": "assignedTo", "type": "string", "note": "org member who reviews/sends" },
|
|
169
|
+
{ "name": "subject", "type": "string" },
|
|
170
|
+
{ "name": "body", "type": "markdown" },
|
|
171
|
+
{ "name": "status", "type": "enum", "note": "review at /draft-queue/<id>" }
|
|
172
|
+
]
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
"id": "email_tracking",
|
|
176
|
+
"name": "email_tracking",
|
|
177
|
+
"note": "Open-pixel events for sent messages",
|
|
178
|
+
"fields": [
|
|
179
|
+
{ "name": "id", "type": "id", "pk": true },
|
|
180
|
+
{ "name": "messageId", "type": "string" },
|
|
181
|
+
{ "name": "openedAt", "type": "datetime" }
|
|
182
|
+
]
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
"id": "email_link_tracking",
|
|
186
|
+
"name": "email_link_tracking",
|
|
187
|
+
"note": "Link-click events for sent messages",
|
|
188
|
+
"fields": [
|
|
189
|
+
{ "name": "id", "type": "id", "pk": true },
|
|
190
|
+
{ "name": "messageId", "type": "string", "fk": "email_tracking.messageId" },
|
|
191
|
+
{ "name": "url", "type": "string" },
|
|
192
|
+
{ "name": "clickedAt", "type": "datetime" }
|
|
193
|
+
]
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
"id": "oauth_tokens",
|
|
197
|
+
"name": "oauth_tokens",
|
|
198
|
+
"note": "Framework table — one row per connected Google account",
|
|
199
|
+
"fields": [
|
|
200
|
+
{ "name": "id", "type": "id", "pk": true },
|
|
201
|
+
{ "name": "provider", "type": "string", "note": "\"google\"" },
|
|
202
|
+
{ "name": "accountEmail", "type": "string" },
|
|
203
|
+
{ "name": "accessToken", "type": "string" },
|
|
204
|
+
{ "name": "refreshToken", "type": "string" }
|
|
205
|
+
]
|
|
206
|
+
}
|
|
207
|
+
],
|
|
208
|
+
"relations": [
|
|
209
|
+
{ "from": "email_tracking", "to": "email_link_tracking", "kind": "1-n", "label": "click events" }
|
|
210
|
+
]
|
|
211
|
+
}
|
|
212
|
+
```
|
|
213
|
+
|
|
167
214
|
Routes in the UI:
|
|
168
215
|
|
|
169
216
|
- `/_index.tsx` — redirects to the default inbox view.
|
|
@@ -23,7 +23,19 @@ commit, branch, or git diff — into a high-altitude visual code review. Both op
|
|
|
23
23
|
the same review surface, so you annotate, comment, and hand feedback back to the
|
|
24
24
|
agent the same way.
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
```an-diagram title="Two commands, one review surface" summary="Both commands publish through the hosted Plan MCP connector into the same annotate-and-comment surface."
|
|
27
|
+
{
|
|
28
|
+
"html": "<div class=\"diagram-plan\"><div class=\"diagram-col\"><div class=\"diagram-node\"><span class=\"diagram-pill accent\">/visual-plan</span><small class=\"diagram-muted\">before code — architecture, UI, refactor</small></div><div class=\"diagram-node\"><span class=\"diagram-pill\">/visual-recap</span><small class=\"diagram-muted\">after code — PR, commit, branch, diff</small></div></div><div class=\"diagram-arrow diagram-muted\" aria-hidden=\"true\">→</div><div class=\"diagram-panel center\">Plan MCP connector<br><small class=\"diagram-muted\">plan.agent-native.com</small></div><div class=\"diagram-arrow diagram-muted\" aria-hidden=\"true\">→</div><div class=\"diagram-box\">Review surface<br><small class=\"diagram-muted\">diagrams · wireframes · annotated code · comments</small></div><div class=\"diagram-arrow diagram-muted\" aria-hidden=\"true\">↔</div><div class=\"diagram-node\">Coding agent<br><small class=\"diagram-muted\">feedback handed back</small></div></div>",
|
|
29
|
+
"css": ".diagram-plan{display:flex;align-items:center;gap:12px;flex-wrap:wrap}.diagram-plan .diagram-col{display:flex;flex-direction:column;gap:10px}.diagram-plan .diagram-arrow{font-size:22px;line-height:1}.diagram-plan .center{display:flex;flex-direction:column;align-items:center;gap:4px;text-align:center}"
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
```an-wireframe
|
|
34
|
+
{
|
|
35
|
+
"surface": "desktop",
|
|
36
|
+
"html": "<div style='display:grid;grid-template-columns:1fr 250px;gap:14px;padding:16px;min-height:520px;box-sizing:border-box'><main style='display:flex;flex-direction:column;gap:12px;min-width:0'><div style='display:flex;align-items:center;gap:10px'><h1 style='margin:0'>Checkout redesign plan</h1><div style='flex:1'></div><button>Share</button><button class='primary'>Approve</button></div><div class='wf-card' style='display:grid;grid-template-columns:1fr 1fr;gap:10px;min-height:150px'><div class='wf-box'>Current wireframe</div><div class='wf-box'>Proposed wireframe</div></div><div class='wf-card' style='flex:1;display:flex;flex-direction:column;gap:10px'><strong>Implementation plan</strong><div class='wf-box'>Decision: keep existing checkout shell</div><div class='wf-box'>Annotated code walkthrough</div><div class='wf-box'>Open questions</div></div></main><aside class='wf-card' style='display:flex;flex-direction:column;gap:10px'><strong>Comments</strong><div class='wf-box'>Pin on primary CTA</div><div class='wf-box'>Question for agent</div><div class='wf-box'>Resolved copy note</div><button class='primary'>Hand back feedback</button></aside></div>"
|
|
37
|
+
}
|
|
38
|
+
```
|
|
27
39
|
|
|
28
40
|
There are two ways into Plans:
|
|
29
41
|
|
|
@@ -384,6 +396,73 @@ Schema lives in `templates/plan/server/db/schema.ts`. Core tables:
|
|
|
384
396
|
| `plan_guest_mints` | Rate-limit records for guest session issuance |
|
|
385
397
|
| `plan_assets` | Inline image assets stored as base64 (fallback when no upload provider) |
|
|
386
398
|
|
|
399
|
+
```an-schema title="Plan data model" summary="One plan row owns ordered sections plus comments, events, versions, shares, and inline assets."
|
|
400
|
+
{
|
|
401
|
+
"entities": [
|
|
402
|
+
{ "id": "plans", "name": "plans", "note": "each plan or recap", "fields": [
|
|
403
|
+
{ "name": "id", "type": "text", "pk": true },
|
|
404
|
+
{ "name": "title", "type": "text" },
|
|
405
|
+
{ "name": "brief", "type": "text", "nullable": true },
|
|
406
|
+
{ "name": "kind", "type": "enum", "note": "plan | recap" },
|
|
407
|
+
{ "name": "status", "type": "text" },
|
|
408
|
+
{ "name": "source", "type": "text", "nullable": true },
|
|
409
|
+
{ "name": "hosted_plan_id", "type": "text", "nullable": true, "note": "hosted_plan_url paired" },
|
|
410
|
+
{ "name": "source_url", "type": "text", "nullable": true },
|
|
411
|
+
{ "name": "deleted_at", "type": "timestamp", "nullable": true, "note": "soft delete; deleted_by paired" }
|
|
412
|
+
] },
|
|
413
|
+
{ "id": "plan_sections", "name": "plan_sections", "note": "ordered sections within a plan", "fields": [
|
|
414
|
+
{ "name": "id", "type": "text", "pk": true },
|
|
415
|
+
{ "name": "plan_id", "type": "text", "fk": "plans.id" },
|
|
416
|
+
{ "name": "type", "type": "text" },
|
|
417
|
+
{ "name": "title", "type": "text", "nullable": true },
|
|
418
|
+
{ "name": "body", "type": "text", "nullable": true },
|
|
419
|
+
{ "name": "html", "type": "text", "nullable": true },
|
|
420
|
+
{ "name": "sort_order", "type": "integer" },
|
|
421
|
+
{ "name": "created_by", "type": "text", "nullable": true }
|
|
422
|
+
] },
|
|
423
|
+
{ "id": "plan_comments", "name": "plan_comments", "note": "threaded comments", "fields": [
|
|
424
|
+
{ "name": "id", "type": "text", "pk": true },
|
|
425
|
+
{ "name": "plan_id", "type": "text", "fk": "plans.id" },
|
|
426
|
+
{ "name": "kind", "type": "text" },
|
|
427
|
+
{ "name": "status", "type": "text" },
|
|
428
|
+
{ "name": "anchor", "type": "json", "nullable": true },
|
|
429
|
+
{ "name": "message", "type": "text" },
|
|
430
|
+
{ "name": "resolution_target", "type": "text", "nullable": true, "note": "agent | human | null" },
|
|
431
|
+
{ "name": "mentions_json", "type": "json", "nullable": true },
|
|
432
|
+
{ "name": "resolved_by", "type": "text", "nullable": true }
|
|
433
|
+
] },
|
|
434
|
+
{ "id": "plan_events", "name": "plan_events", "note": "audit log of agent/human events", "fields": [
|
|
435
|
+
{ "name": "id", "type": "text", "pk": true },
|
|
436
|
+
{ "name": "plan_id", "type": "text", "fk": "plans.id" }
|
|
437
|
+
] },
|
|
438
|
+
{ "id": "plan_versions", "name": "plan_versions", "note": "point-in-time snapshots", "fields": [
|
|
439
|
+
{ "name": "id", "type": "text", "pk": true },
|
|
440
|
+
{ "name": "plan_id", "type": "text", "fk": "plans.id" }
|
|
441
|
+
] },
|
|
442
|
+
{ "id": "plan_shares", "name": "plan_shares", "note": "per-principal grants", "fields": [
|
|
443
|
+
{ "name": "id", "type": "text", "pk": true },
|
|
444
|
+
{ "name": "plan_id", "type": "text", "fk": "plans.id" },
|
|
445
|
+
{ "name": "role", "type": "enum", "note": "viewer | editor | admin" }
|
|
446
|
+
] },
|
|
447
|
+
{ "id": "plan_guest_mints", "name": "plan_guest_mints", "note": "rate-limit records for guest session issuance", "fields": [
|
|
448
|
+
{ "name": "id", "type": "text", "pk": true }
|
|
449
|
+
] },
|
|
450
|
+
{ "id": "plan_assets", "name": "plan_assets", "note": "inline image assets as base64", "fields": [
|
|
451
|
+
{ "name": "id", "type": "text", "pk": true },
|
|
452
|
+
{ "name": "plan_id", "type": "text", "fk": "plans.id" }
|
|
453
|
+
] }
|
|
454
|
+
],
|
|
455
|
+
"relations": [
|
|
456
|
+
{ "from": "plans", "to": "plan_sections", "kind": "1-n", "label": "has sections" },
|
|
457
|
+
{ "from": "plans", "to": "plan_comments", "kind": "1-n", "label": "has comments" },
|
|
458
|
+
{ "from": "plans", "to": "plan_events", "kind": "1-n", "label": "has events" },
|
|
459
|
+
{ "from": "plans", "to": "plan_versions", "kind": "1-n", "label": "has versions" },
|
|
460
|
+
{ "from": "plans", "to": "plan_shares", "kind": "1-n", "label": "has shares" },
|
|
461
|
+
{ "from": "plans", "to": "plan_assets", "kind": "1-n", "label": "has assets" }
|
|
462
|
+
]
|
|
463
|
+
}
|
|
464
|
+
```
|
|
465
|
+
|
|
387
466
|
### Key actions
|
|
388
467
|
|
|
389
468
|
Actions in `templates/plan/actions/`:
|
|
@@ -7,17 +7,21 @@ description: "Generate decks from a prompt, edit visually, and present full-scre
|
|
|
7
7
|
|
|
8
8
|
Generate full presentation decks from a prompt, edit slides visually, and present full-screen. Ask the agent for "a 10-slide pitch deck for a coffee subscription service" and watch it stream slide-by-slide into the editor in seconds. An open-source replacement for Google Slides, Pitch, and PowerPoint.
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
-->
|
|
10
|
+
```an-wireframe
|
|
11
|
+
{
|
|
12
|
+
"surface": "desktop",
|
|
13
|
+
"html": "<div style='display:flex;flex-direction:column;gap:12px;padding:16px;min-height:530px;box-sizing:border-box'><div style='display:flex;align-items:center;gap:10px'><h1 style='margin:0'>Q3 Board Update</h1><span class='wf-pill accent'>Title slide</span><div style='flex:1'></div><button>Preview</button><button>Present</button><button class='primary'>Share</button></div><main style='display:grid;grid-template-columns:1fr 220px;gap:12px;flex:1;min-height:0'><section class='wf-card' style='display:flex;align-items:center;justify-content:center;text-align:center;padding:36px'><div><strong style='font-size:28px'>Q3 Board Update</strong><br/><small>Maya Chen · CEO</small><div style='height:46px'></div><span class='wf-pill'>Product momentum</span></div></section><section style='display:flex;flex-direction:column;gap:10px'><div class='wf-card'><strong>Slide outline</strong><div class='wf-box'>1 Title</div><div class='wf-box'>2 Agenda</div><div class='wf-box'>3 Metrics</div><div class='wf-box'>4 Shipped</div></div><div class='wf-card' style='flex:1'><strong>Speaker notes</strong><p class='wf-muted' style='margin:8px 0 0'>Open with launch progress and retention story.</p></div></section></main><div style='display:grid;grid-template-columns:repeat(5,1fr);gap:8px'><div class='wf-box'>1 Title</div><div class='wf-box'>2 Agenda</div><div class='wf-box'>3 Metrics</div><div class='wf-box'>4 Shipped</div><div class='wf-box'>5 Risks</div></div></div>"
|
|
14
|
+
}
|
|
15
|
+
```
|
|
17
16
|
|
|
18
|
-
|
|
17
|
+
When you open a deck, the slide canvas, outline, notes, and filmstrip stay in one editor surface while the agent can still create, revise, and navigate slides through actions.
|
|
19
18
|
|
|
20
|
-
|
|
19
|
+
```an-diagram title="Prompt to deck" summary="Ask for a deck and the agent streams slides in one at a time through the same actions you could call from the CLI."
|
|
20
|
+
{
|
|
21
|
+
"html": "<div class=\"diagram-flow\"><div class=\"diagram-node\">Prompt<br><small class=\"diagram-muted\">\"10-slide pitch deck\"</small></div><div class=\"diagram-arrow diagram-muted\" aria-hidden=\"true\">→</div><div class=\"diagram-panel center\"><span class=\"diagram-pill accent\">Agent</span><small class=\"diagram-muted\">picks layouts</small></div><div class=\"diagram-arrow diagram-muted\" aria-hidden=\"true\">→</div><div class=\"diagram-col\"><div class=\"diagram-pill\">create-deck</div><div class=\"diagram-pill\">add-slide × n</div><small class=\"diagram-muted\">parallel, streaming</small></div><div class=\"diagram-arrow diagram-muted\" aria-hidden=\"true\">→</div><div class=\"diagram-box\" data-rough>decks (SQL)</div><div class=\"diagram-arrow diagram-muted\" aria-hidden=\"true\">↻</div><div class=\"diagram-box\">Editor renders live</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:6px;align-items:center}.diagram-flow .center{display:flex;flex-direction:column;align-items:center;gap:4px}.diagram-flow .diagram-arrow{font-size:22px;line-height:1}"
|
|
23
|
+
}
|
|
24
|
+
```
|
|
21
25
|
|
|
22
26
|
## What you can do with it
|
|
23
27
|
|
|
@@ -39,7 +43,7 @@ Live demo: [slides.agent-native.com](https://slides.agent-native.com).
|
|
|
39
43
|
When you open the app:
|
|
40
44
|
|
|
41
45
|
1. Click **New deck**.
|
|
42
|
-
2.
|
|
46
|
+
2. Ask the agent: "Generate a 10-slide pitch deck for a coffee subscription service, audience is investors."
|
|
43
47
|
3. Watch slides stream in. Click any slide to edit, or keep asking the agent to refine.
|
|
44
48
|
|
|
45
49
|
### Useful prompts
|
|
@@ -69,75 +73,17 @@ pnpm install
|
|
|
69
73
|
pnpm dev
|
|
70
74
|
```
|
|
71
75
|
|
|
72
|
-
### Key features
|
|
73
|
-
|
|
74
|
-
#### Import and export
|
|
75
|
-
|
|
76
|
-
The template can pull content in from PPTX (`import-pptx`), DOCX (`import-docx`), Google Docs (`import-google-doc`), arbitrary URLs (`import-from-url`), and GitHub repos (`import-github`). Export paths cover PPTX (`export-pptx`), Google Slides (`export-google-slides`), and HTML (`export-html`). Importing uses the same action surface as the rest of the template — no separate pipeline.
|
|
77
|
-
|
|
78
|
-
#### Design systems
|
|
79
|
-
|
|
80
|
-
Reusable brand tokens are stored in the `design_systems` table (colors, typography, spacing, assets, custom instructions, and an `is_default` flag). Sharing is managed via `design_system_shares`. Actions: `create-design-system`, `update-design-system`, `get-design-system`, `list-design-systems`, `set-default-design-system`, `apply-design-system`, and `analyze-brand-assets` (collects brand data before analysis). See the `design-systems` and `image-generation-via-a2a` skills for the full pattern.
|
|
81
|
-
|
|
82
|
-
#### Deck versions
|
|
83
|
-
|
|
84
|
-
Every significant deck change is snapshotted in the `deck_versions` table (stores a full copy of title and deck data with an optional `changeLabel`). Actions: `list-deck-versions`, `restore-deck-version`, `get-deck-version`.
|
|
85
|
-
|
|
86
|
-
#### Prompt-to-deck generation
|
|
87
|
-
|
|
88
|
-
Ask the agent for a deck and it builds one slide at a time. Slides stream into the editor live as each one is generated — the agent fires parallel `add-slide` calls so you see the deck assemble in seconds.
|
|
89
|
-
|
|
90
|
-
Under the hood, this is powered by the `add-slide` and `create-deck` actions in `templates/slides/actions/`.
|
|
91
|
-
|
|
92
|
-
#### Seven slide layouts
|
|
93
|
-
|
|
94
|
-
Built-in layouts: title, section divider, content with bullets, two-column, statement or quote, metrics or stats, and closing or CTA. Each layout is a pure HTML template with inline styles — the agent picks the right one based on slide purpose. The exact templates live inside `templates/slides/.agents/skills/create-deck/SKILL.md` so the agent can reference them without exploring the codebase.
|
|
95
|
-
|
|
96
|
-
#### Visual and code editing
|
|
97
|
-
|
|
98
|
-
- Double-click any text to edit inline.
|
|
99
|
-
- Click a block to open the bubble menu for styles, alignment, and layout.
|
|
100
|
-
- Switch to the code editor (`app/components/editor/CodeEditor.tsx`) to edit raw slide HTML.
|
|
101
|
-
- Use the slash menu (`SlideSlashMenu.tsx`) to insert blocks by typing `/`.
|
|
76
|
+
### Key features {#key-features}
|
|
102
77
|
|
|
103
|
-
|
|
78
|
+
**Prompt-to-deck generation.** Ask for a deck and the agent streams slides into the editor using the same create and edit actions you can run yourself.
|
|
104
79
|
|
|
105
|
-
|
|
80
|
+
**Editable slide canvas.** Inline text editing, slash inserts, code editing, drag-and-drop ordering, undo/redo, comments, and presentation mode all live in the deck surface.
|
|
106
81
|
|
|
107
|
-
|
|
82
|
+
**Import and export.** Bring in PPTX, DOCX, Google Docs, PDFs, URLs, and GitHub repos; export to PPTX, Google Slides, HTML, or a share link.
|
|
108
83
|
|
|
109
|
-
|
|
84
|
+
**Design systems and media.** Saved brand systems, image generation, stock search, and logo lookup keep decks closer to the intended visual direction.
|
|
110
85
|
|
|
111
|
-
|
|
112
|
-
- `image-search --query "mountain landscape"` searches Google Images for stock photos.
|
|
113
|
-
|
|
114
|
-
#### Comments and threads
|
|
115
|
-
|
|
116
|
-
Leave comments on specific slides, quote selected text, and reply in threads. Stored in the `slide_comments` table. Actions: `add-slide-comment`, `list-slide-comments`.
|
|
117
|
-
|
|
118
|
-
#### Drag and drop reordering
|
|
119
|
-
|
|
120
|
-
Reorder slides in the sidebar, duplicate, or delete with hover controls. The sidebar lives in `app/components/editor/EditorSidebar.tsx`.
|
|
121
|
-
|
|
122
|
-
#### Presentation mode
|
|
123
|
-
|
|
124
|
-
Full-screen presentation at `/deck/:id/present` with keyboard navigation (arrow keys, space, escape), auto-hiding controls, and speaker notes. See `app/routes/deck.$id_.present.tsx` and `app/components/presentation/PresentationView.tsx`.
|
|
125
|
-
|
|
126
|
-
#### Share links
|
|
127
|
-
|
|
128
|
-
Generate a public read-only URL for a deck so reviewers can view without an account. The share page is `app/routes/share.$token.tsx`. Fine-grained sharing (viewer, editor, admin roles, per-user or org-wide) is also available via the framework's `share-resource` action.
|
|
129
|
-
|
|
130
|
-
#### Real-time collaboration
|
|
131
|
-
|
|
132
|
-
Multiple people can edit the same deck simultaneously. Text edits sync through Yjs CRDT so there are no conflicts, and the agent sees and edits the same live document via the `update-slide --find/--replace` action.
|
|
133
|
-
|
|
134
|
-
#### Undo and redo
|
|
135
|
-
|
|
136
|
-
Cmd+Z and Cmd+Shift+Z work across the whole deck, with a labeled history panel (`HistoryPanel.tsx`) you can scrub through.
|
|
137
|
-
|
|
138
|
-
#### Extract from PDF
|
|
139
|
-
|
|
140
|
-
Turn a PDF into a starter deck. The `extract-pdf` action parses the file and hands the content to the agent for layout.
|
|
86
|
+
**Collaboration and history.** Real-time Yjs editing, threaded comments, share roles, and deck version snapshots are built in.
|
|
141
87
|
|
|
142
88
|
### Working with the agent
|
|
143
89
|
|
|
@@ -165,6 +111,81 @@ The agent can embed a live slide preview directly in a chat reply using the fram
|
|
|
165
111
|
|
|
166
112
|
All deck data lives in SQL via Drizzle ORM. Schema: `templates/slides/server/db/schema.ts`.
|
|
167
113
|
|
|
114
|
+
```an-schema title="Slides data model" summary="A deck owns its slides as JSON in decks.data; comments, versions, shares, and design systems hang off it."
|
|
115
|
+
{
|
|
116
|
+
"entities": [
|
|
117
|
+
{
|
|
118
|
+
"id": "decks",
|
|
119
|
+
"name": "decks",
|
|
120
|
+
"note": "Slides live as JSON in data; carries ownableColumns",
|
|
121
|
+
"fields": [
|
|
122
|
+
{ "name": "id", "type": "text", "pk": true, "note": "e.g. deck-1712345-abc" },
|
|
123
|
+
{ "name": "title", "type": "text" },
|
|
124
|
+
{ "name": "data", "type": "text", "note": "JSON: { title, slides: [{ id, content, layout }] }" },
|
|
125
|
+
{ "name": "created_at", "type": "text" },
|
|
126
|
+
{ "name": "updated_at", "type": "text" }
|
|
127
|
+
]
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
"id": "slide_comments",
|
|
131
|
+
"name": "slide_comments",
|
|
132
|
+
"fields": [
|
|
133
|
+
{ "name": "id", "type": "text", "pk": true },
|
|
134
|
+
{ "name": "deck_id", "type": "text", "fk": "decks.id" },
|
|
135
|
+
{ "name": "slide_id", "type": "text", "note": "Slide the comment lives on" },
|
|
136
|
+
{ "name": "thread_id", "type": "text", "note": "Threading" },
|
|
137
|
+
{ "name": "parent_id", "type": "text", "nullable": true },
|
|
138
|
+
{ "name": "content", "type": "text" },
|
|
139
|
+
{ "name": "quoted_text", "type": "text", "nullable": true },
|
|
140
|
+
{ "name": "author_email", "type": "text" },
|
|
141
|
+
{ "name": "author_name", "type": "text" },
|
|
142
|
+
{ "name": "resolved", "type": "boolean" }
|
|
143
|
+
]
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
"id": "deck_versions",
|
|
147
|
+
"name": "deck_versions",
|
|
148
|
+
"note": "Point-in-time snapshots for restore",
|
|
149
|
+
"fields": [
|
|
150
|
+
{ "name": "deck_id", "type": "text", "fk": "decks.id" },
|
|
151
|
+
{ "name": "title", "type": "text" },
|
|
152
|
+
{ "name": "data", "type": "text", "note": "Full deck JSON" },
|
|
153
|
+
{ "name": "change_label", "type": "text", "nullable": true }
|
|
154
|
+
]
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
"id": "design_systems",
|
|
158
|
+
"name": "design_systems",
|
|
159
|
+
"note": "Reusable brand tokens; ownableColumns",
|
|
160
|
+
"fields": [
|
|
161
|
+
{ "name": "data", "type": "text", "note": "colors / typography / spacing" },
|
|
162
|
+
{ "name": "assets", "type": "text", "nullable": true },
|
|
163
|
+
{ "name": "custom_instructions", "type": "text", "nullable": true },
|
|
164
|
+
{ "name": "is_default", "type": "boolean" }
|
|
165
|
+
]
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
"id": "deck_share_links",
|
|
169
|
+
"name": "deck_share_links",
|
|
170
|
+
"note": "Persisted public share-link snapshots",
|
|
171
|
+
"fields": [
|
|
172
|
+
{ "name": "token", "type": "text", "pk": true },
|
|
173
|
+
{ "name": "title", "type": "text" },
|
|
174
|
+
{ "name": "slides", "type": "text", "note": "JSON slides snapshot" },
|
|
175
|
+
{ "name": "aspect_ratio", "type": "text", "nullable": true },
|
|
176
|
+
{ "name": "created_at", "type": "text" }
|
|
177
|
+
]
|
|
178
|
+
}
|
|
179
|
+
],
|
|
180
|
+
"relations": [
|
|
181
|
+
{ "from": "decks", "to": "slide_comments", "kind": "1-n", "label": "comments" },
|
|
182
|
+
{ "from": "decks", "to": "deck_versions", "kind": "1-n", "label": "snapshots" }
|
|
183
|
+
]
|
|
184
|
+
}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
Framework shares tables (`deck_shares`, `design_system_shares`) map principals to viewer / editor / admin roles per resource.
|
|
188
|
+
|
|
168
189
|
#### decks
|
|
169
190
|
|
|
170
191
|
| Column | Type | Notes |
|
|
@@ -7,18 +7,22 @@ description: "A programmatic video studio for motion graphics, product demos, an
|
|
|
7
7
|
|
|
8
8
|
A programmatic video studio for the kind of motion graphics, product demos, and kinetic-text videos that are a pain to keyframe by hand. Ask the agent for "a 6-second logo reveal that fades in at 2 seconds" and it builds the animation. Tune timing, easing, and camera moves on a timeline, then render to MP4 or WebM.
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
-->
|
|
17
|
-
|
|
18
|
-

|
|
10
|
+
```an-wireframe
|
|
11
|
+
{
|
|
12
|
+
"surface": "desktop",
|
|
13
|
+
"html": "<div style='display:flex;flex-direction:column;gap:12px;padding:16px;min-height:530px;box-sizing:border-box'><div style='display:flex;align-items:center;gap:10px'><h1 style='margin:0'>Logo reveal</h1><span class='wf-pill accent'>6 seconds</span><div style='flex:1'></div><button>Preview</button><button class='primary'>Render</button></div><div class='wf-card' style='flex:1;display:flex;align-items:center;justify-content:center;min-height:250px'><div style='text-align:center'><strong>Remotion preview</strong><br/><small class='wf-muted'>logo scales in as the title fades</small></div></div><div class='wf-card' style='display:flex;flex-direction:column;gap:10px'><div style='display:flex;gap:8px;align-items:center'><span class='wf-pill'>0s</span><span class='wf-pill'>2s</span><span class='wf-pill'>4s</span><span class='wf-pill'>6s</span><div style='flex:1'></div><button>New track</button></div><div class='wf-box'>Title fade · 0-48 frames</div><div class='wf-box'>Logo scale · 48-120 frames</div><div class='wf-box'>Camera push · 72-144 frames</div></div></div>"
|
|
14
|
+
}
|
|
15
|
+
```
|
|
19
16
|
|
|
20
17
|
When you open the studio, you'll see a list of compositions on the home screen. Click into one and you get a player on top, a timeline at the bottom, and a properties panel on the right. The agent always knows which composition you have open.
|
|
21
18
|
|
|
19
|
+
```an-diagram title="Animation as data" summary="A composition is a React component; every animation reads from a track so the agent and the timeline edit the same data."
|
|
20
|
+
{
|
|
21
|
+
"html": "<div class=\"diagram-flow\"><div class=\"diagram-col\"><div class=\"diagram-node\">Timeline<br><small class=\"diagram-muted\">drag, resize, scrub</small></div><div class=\"diagram-node\">Agent<br><small class=\"diagram-muted\">\"fade in at 2s\"</small></div></div><div class=\"diagram-arrow diagram-muted\" aria-hidden=\"true\">→</div><div class=\"diagram-panel center\"><span class=\"diagram-pill accent\">AnimationTrack</span><small class=\"diagram-muted\">startFrame / easing / animatedProps</small></div><div class=\"diagram-arrow diagram-muted\" aria-hidden=\"true\">→</div><div class=\"diagram-box\" data-rough>React composition<br><small class=\"diagram-muted\">Remotion <Player></small></div><div class=\"diagram-arrow diagram-muted\" aria-hidden=\"true\">→</div><div class=\"diagram-box\">MP4 / WebM</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 .center{display:flex;flex-direction:column;align-items:center;gap:4px}.diagram-flow .diagram-arrow{font-size:22px;line-height:1}"
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
22
26
|
## What you can do with it
|
|
23
27
|
|
|
24
28
|
- **Generate animations from a prompt.** "Add a title card that fades in at 2 seconds and holds until 5." The agent edits the composition.
|
|
@@ -75,53 +79,15 @@ pnpm dev
|
|
|
75
79
|
|
|
76
80
|
Open the studio in your browser, create a composition, and start from blank. Ask the agent something like "add a logo reveal that fades in at 2 seconds" and it will edit the composition for you.
|
|
77
81
|
|
|
78
|
-
### Key features
|
|
79
|
-
|
|
80
|
-
#### React-based compositions
|
|
81
|
-
|
|
82
|
-
Every video is a React component built on Remotion primitives (`AbsoluteFill`, `useCurrentFrame`, `useVideoConfig`). The template ships one in-code composition — `BlankComposition` in `app/remotion/compositions/BlankComposition.tsx` — and `app/remotion/registry.ts` exports an empty `compositions` array by default. User and example compositions (kinetic text, logo reveals, particle bursts, interactive UI demos, slideshows) live in SQL and load through `app/hooks/use-database-compositions.ts`. You can still add a code composition by dropping a `.tsx` file in `app/remotion/compositions/` and registering it in `app/remotion/registry.ts`.
|
|
83
|
-
|
|
84
|
-
#### Timeline tracks
|
|
85
|
-
|
|
86
|
-
Animations are tracks, not hardcoded frame checks. A track has `startFrame`, `endFrame`, `easing`, and a list of `animatedProps` (`opacity`, `translateY`, `scale`, rotation, colors, etc.). Three track shapes:
|
|
87
|
-
|
|
88
|
-
- **Duration tracks** — bars you can drag and resize in the timeline.
|
|
89
|
-
- **Keyframe tracks** — diamond markers at specific frames for instant state changes (`startFrame === endFrame`).
|
|
90
|
-
- **Expression tracks** — programmatic animations (typing reveals, particle bursts) flagged with `programmatic: true` and shown with a purple `fx` badge.
|
|
91
|
-
|
|
92
|
-
Helper utilities in `app/remotion/trackAnimation.ts` (`findTrack`, `trackProgress`, `getPropValue`) wire a track's values into a component's render.
|
|
93
|
-
|
|
94
|
-
#### Easing curves
|
|
95
|
-
|
|
96
|
-
30+ easing curves ship in `app/types.ts` — linear, power1-4 in/out/inOut, back, bounce, circ, elastic, expo, sine, and Remotion's `spring`. The Properties panel shows a visual preview of the curve shape for each one.
|
|
97
|
-
|
|
98
|
-
#### Camera controls
|
|
82
|
+
### Key features
|
|
99
83
|
|
|
100
|
-
|
|
84
|
+
**React-based compositions.** Videos are Remotion-backed React components, with SQL-backed user compositions and an optional code registry for local defaults.
|
|
101
85
|
|
|
102
|
-
|
|
86
|
+
**Timeline-first animation.** Duration tracks, keyframes, easing curves, camera moves, and programmatic expression tracks all edit the same composition data.
|
|
103
87
|
|
|
104
|
-
|
|
88
|
+
**Adjustable motion systems.** Parameters, cursor tracks, interactive hover zones, range navigation, and repeat playback make generated animations tunable without code.
|
|
105
89
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
Programmatic animations expose internal magic numbers as user-editable `parameters` — character width, drift distance, particle count, stagger delay. Inputs appear in the Properties panel with min/max/step bounds and save to localStorage automatically.
|
|
109
|
-
|
|
110
|
-
#### Interactive cursor system
|
|
111
|
-
|
|
112
|
-
The `cursor` track drives a visible cursor that moves across the composition. Hover zones on interactive elements (buttons, tabs, inputs, cards) change the cursor appearance — arrow, pointer, or I-beam. See `app/remotion/hooks/useInteractiveComponent.ts` and `app/remotion/ui-components/InteractiveCard.tsx`.
|
|
113
|
-
|
|
114
|
-
#### View range and repeat playback
|
|
115
|
-
|
|
116
|
-
The timeline has a range navigator at the bottom (AE-style triangular handles). Drag to zoom and pan the visible time window. Playback in the player is constrained to that range, with a repeat toggle that loops inside it.
|
|
117
|
-
|
|
118
|
-
#### Render output
|
|
119
|
-
|
|
120
|
-
Composition size, fps, and render quality are per-composition in the Properties panel. Render quality is supersampling — 1x, 2x, or 3x internal resolution to keep text and vectors crisp during camera zoom. Final render happens via the Remotion CLI to MP4 or WebM.
|
|
121
|
-
|
|
122
|
-
#### Composition persistence
|
|
123
|
-
|
|
124
|
-
User edits (track values, parameter values, prop overrides, composition settings) persist to localStorage per composition. The **Save** button in the top-right of the composition view can write the current state back to `app/remotion/registry.ts` as TypeScript — so new users and sessions pick up the changes. That source-write path runs through `POST /api/save-composition-defaults`, which is gated to local development only; in production it returns a 403, and durable composition state lives in SQL instead.
|
|
90
|
+
**Render and persistence.** Composition settings, quality, fps, track values, and overrides persist per composition and render to MP4 or WebM through Remotion.
|
|
125
91
|
|
|
126
92
|
### Working with the agent
|
|
127
93
|
|
|
@@ -133,6 +99,61 @@ Under the hood the agent calls actions like `navigate`, `save-composition`, and
|
|
|
133
99
|
|
|
134
100
|
Server-side schema is in `templates/videos/server/db/schema.ts`:
|
|
135
101
|
|
|
102
|
+
```an-schema title="Video data model" summary="SQL-backed compositions plus design systems and nestable folders, each with a framework shares table."
|
|
103
|
+
{
|
|
104
|
+
"entities": [
|
|
105
|
+
{
|
|
106
|
+
"id": "compositions",
|
|
107
|
+
"name": "compositions",
|
|
108
|
+
"note": "User-created compositions and overrides; ownableColumns",
|
|
109
|
+
"fields": [
|
|
110
|
+
{ "name": "id", "type": "text", "pk": true },
|
|
111
|
+
{ "name": "title", "type": "text" },
|
|
112
|
+
{ "name": "type", "type": "text" },
|
|
113
|
+
{ "name": "data", "type": "text", "note": "Full composition JSON blob" },
|
|
114
|
+
{ "name": "created_at", "type": "text" },
|
|
115
|
+
{ "name": "updated_at", "type": "text" }
|
|
116
|
+
]
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
"id": "design_systems",
|
|
120
|
+
"name": "design_systems",
|
|
121
|
+
"note": "Reusable brand tokens; ownableColumns",
|
|
122
|
+
"fields": [
|
|
123
|
+
{ "name": "data", "type": "text", "note": "colors / typography / spacing" },
|
|
124
|
+
{ "name": "assets", "type": "text", "nullable": true },
|
|
125
|
+
{ "name": "custom_instructions", "type": "text", "nullable": true },
|
|
126
|
+
{ "name": "is_default", "type": "boolean" }
|
|
127
|
+
]
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
"id": "folders",
|
|
131
|
+
"name": "folders",
|
|
132
|
+
"note": "Nestable folders; ownableColumns",
|
|
133
|
+
"fields": [
|
|
134
|
+
{ "name": "id", "type": "text", "pk": true },
|
|
135
|
+
{ "name": "name", "type": "text" }
|
|
136
|
+
]
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
"id": "folder_memberships",
|
|
140
|
+
"name": "folder_memberships",
|
|
141
|
+
"note": "Many-to-many join",
|
|
142
|
+
"fields": [
|
|
143
|
+
{ "name": "folder_id", "type": "text", "fk": "folders.id" },
|
|
144
|
+
{ "name": "composition_id", "type": "text", "fk": "compositions.id" }
|
|
145
|
+
]
|
|
146
|
+
}
|
|
147
|
+
],
|
|
148
|
+
"relations": [
|
|
149
|
+
{ "from": "folders", "to": "folder_memberships", "kind": "1-n", "label": "members" },
|
|
150
|
+
{ "from": "compositions", "to": "folder_memberships", "kind": "1-n", "label": "in folders" }
|
|
151
|
+
]
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Each table also has a matching framework shares table (`composition_shares`, `design_system_shares`, `folder_shares`) produced by `createSharesTable()`.
|
|
156
|
+
|
|
136
157
|
- `compositions` — id, title, type, `data` (full composition JSON blob), ownership columns, timestamps.
|
|
137
158
|
- `composition_shares` — standard share grants produced by `createSharesTable()`.
|
|
138
159
|
- `design_systems` — reusable brand tokens (colors, typography, spacing, assets, custom instructions, `is_default` flag) with `ownableColumns`.
|