@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
@@ -19,7 +19,19 @@ The product surface stays simple on purpose: **Ask** is the primary chat
19
19
  experience, while **Sources**, **Review**, and **Knowledge** are admin/support
20
20
  surfaces for connecting data, approving proposals, and inspecting cited memory.
21
21
 
22
- ![Brain company chat with cited memory sources](https://cdn.builder.io/api/v1/image/assets%2FYJIGb4i01jvw0SRdL5Bt%2F9c9fe3b5b9494e33803cd3f494cba356?format=webp&width=1200)
22
+ ```an-diagram title="From source to cited answer" summary="Brain ingests approved sources into raw captures, distills durable memory, gates it through review, and only then answers with citations."
23
+ {
24
+ "html": "<div class=\"diagram-flow\"><div class=\"diagram-card\"><span class=\"diagram-pill\">Sources</span><small class=\"diagram-muted\">Slack · Granola · GitHub · Clips · webhooks</small></div><div class=\"diagram-arrow diagram-muted\" aria-hidden=\"true\">&rarr;</div><div class=\"diagram-box\" data-rough>Raw captures<br><small class=\"diagram-muted\">deduped, redacted</small></div><div class=\"diagram-arrow diagram-muted\" aria-hidden=\"true\">&rarr;</div><div class=\"diagram-box\" data-rough>Distill<br><small class=\"diagram-muted\">facts · decisions · processes</small></div><div class=\"diagram-arrow diagram-muted\" aria-hidden=\"true\">&rarr;</div><div class=\"diagram-card\"><span class=\"diagram-pill warn\">Review</span><small class=\"diagram-muted\">sensitive / low-confidence queue</small></div><div class=\"diagram-arrow diagram-muted\" aria-hidden=\"true\">&rarr;</div><div class=\"diagram-box\" data-rough><span class=\"diagram-pill ok\">Knowledge</span><small class=\"diagram-muted\">approved, atomic</small></div><div class=\"diagram-arrow diagram-muted\" aria-hidden=\"true\">&rarr;</div><div class=\"diagram-panel center\"><span class=\"diagram-pill accent\">Ask</span><small class=\"diagram-muted\">cited answer</small></div></div>",
25
+ "css": ".diagram-flow{display:flex;align-items:center;gap:10px;flex-wrap:wrap}.diagram-flow .diagram-card{display:flex;flex-direction:column;gap:4px;padding:10px 12px}.diagram-flow .diagram-box{display:flex;flex-direction:column;gap:4px}.diagram-flow .diagram-arrow{font-size:20px;line-height:1}.diagram-flow .center{display:flex;flex-direction:column;align-items:center;gap:4px}"
26
+ }
27
+ ```
28
+
29
+ ```an-wireframe
30
+ {
31
+ "surface": "desktop",
32
+ "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'>Ask company memory</h1><span class='wf-pill accent'>42 approved memories</span><span class='wf-pill'>3 sources</span><div style='flex:1'></div><button>Sources</button><button>Review</button></div><div class='wf-card' style='display:flex;align-items:center;gap:10px'><span data-icon='search' aria-label='Search'></span><strong style='flex:1'>Why did we choose usage pricing?</strong><button class='primary'>Ask</button></div><div class='wf-card' style='display:flex;flex-direction:column;gap:10px'><strong>Answer</strong><p style='margin:0'>The team chose usage pricing after pilots showed seat counts undercounted automation value.</p><div style='display:flex;gap:8px;flex-wrap:wrap'><span class='wf-pill accent'>Pricing RFC</span><span class='wf-pill'>Launch retro</span><span class='wf-pill'>Sales notes</span></div></div><div class='wf-card' style='flex:1;display:flex;flex-direction:column;gap:8px'><strong>Source timeline</strong><div class='wf-box'>May 3 · Decision captured</div><div class='wf-box'>May 8 · Customer evidence added</div><div class='wf-box'>May 12 · Legal note approved</div></div></div>"
33
+ }
34
+ ```
23
35
 
24
36
  When you open the app, **Ask** is front and center — a clean chat over reviewed
25
37
  company memory. **Sources**, **Review**, and **Knowledge** sit alongside it as
@@ -140,6 +152,65 @@ Brain's schema lives in `templates/brain/server/db/schema.ts`. Eight tables:
140
152
  | `brain_sync_runs` | Sync audit log — provider, status, stats JSON, error, start/end timestamps |
141
153
  | `brain_ingest_queue` | Background distillation queue — operation, status, priority, retry count, `run_after` |
142
154
 
155
+ ```an-schema title="Brain data model" summary="Connectors produce raw captures; distillation turns captures into reviewable knowledge; proposals gate sensitive entries. Sync runs and the ingest queue track background work."
156
+ {
157
+ "entities": [
158
+ { "id": "sources", "name": "brain_sources", "note": "Connector config", "fields": [
159
+ { "name": "id", "type": "id", "pk": true },
160
+ { "name": "provider", "type": "text", "note": "slack / granola / github / clips / webhook" },
161
+ { "name": "ingest_token_hash", "type": "text" },
162
+ { "name": "status", "type": "text" },
163
+ { "name": "last_synced_at", "type": "timestamp", "nullable": true }
164
+ ] },
165
+ { "id": "source_shares", "name": "brain_source_shares", "note": "viewer / editor / admin", "fields": [
166
+ { "name": "source_id", "type": "id", "fk": "brain_sources.id" }
167
+ ] },
168
+ { "id": "captures", "name": "brain_raw_captures", "note": "Ingested raw payloads", "fields": [
169
+ { "name": "id", "type": "id", "pk": true },
170
+ { "name": "source_id", "type": "id", "fk": "brain_sources.id" },
171
+ { "name": "external_id", "type": "text", "note": "dedupe key" },
172
+ { "name": "content_hash", "type": "text" },
173
+ { "name": "kind", "type": "text" }
174
+ ] },
175
+ { "id": "knowledge", "name": "brain_knowledge", "note": "Distilled atomic entries", "fields": [
176
+ { "name": "id", "type": "id", "pk": true },
177
+ { "name": "kind", "type": "text", "note": "decision / fact / process" },
178
+ { "name": "topic", "type": "text" },
179
+ { "name": "entities", "type": "json" },
180
+ { "name": "confidence", "type": "real" },
181
+ { "name": "publish_tier", "type": "text" }
182
+ ] },
183
+ { "id": "knowledge_shares", "name": "brain_knowledge_shares", "fields": [
184
+ { "name": "knowledge_id", "type": "id", "fk": "brain_knowledge.id" }
185
+ ] },
186
+ { "id": "proposals", "name": "brain_proposals", "note": "Pending review items", "fields": [
187
+ { "name": "id", "type": "id", "pk": true },
188
+ { "name": "op", "type": "text", "note": "create / update / archive" }
189
+ ] },
190
+ { "id": "proposal_shares", "name": "brain_proposal_shares", "fields": [
191
+ { "name": "proposal_id", "type": "id", "fk": "brain_proposals.id" }
192
+ ] },
193
+ { "id": "sync_runs", "name": "brain_sync_runs", "note": "Sync audit log", "fields": [
194
+ { "name": "source_id", "type": "id", "fk": "brain_sources.id" },
195
+ { "name": "status", "type": "text" },
196
+ { "name": "stats", "type": "json" }
197
+ ] },
198
+ { "id": "ingest_queue", "name": "brain_ingest_queue", "note": "Background distillation queue", "fields": [
199
+ { "name": "operation", "type": "text" },
200
+ { "name": "status", "type": "text" },
201
+ { "name": "priority", "type": "int" },
202
+ { "name": "run_after", "type": "timestamp", "nullable": true }
203
+ ] }
204
+ ],
205
+ "relations": [
206
+ { "from": "sources", "to": "captures", "kind": "1-n", "label": "ingested into" },
207
+ { "from": "knowledge", "to": "captures", "kind": "n-n", "label": "evidence" },
208
+ { "from": "knowledge", "to": "proposals", "kind": "1-n", "label": "gated by" },
209
+ { "from": "sources", "to": "sync_runs", "kind": "1-n", "label": "audited by" }
210
+ ]
211
+ }
212
+ ```
213
+
143
214
  ### Key actions
144
215
 
145
216
  Grouped by area (`templates/brain/actions/`):
@@ -188,6 +259,23 @@ a source with a `sourceKey` to receive a bearer token, then send a
188
259
  use the same payload shape for call transcripts, customer research, imported
189
260
  notes, or any other source that can produce a bounded capture.
190
261
 
262
+ ```an-api title="Signed ingest webhook" summary="Clips and generic transcript/capture imports post a RawCapturePayload with a per-source bearer token."
263
+ {
264
+ "method": "POST",
265
+ "path": "/api/_agent-native/brain/ingest",
266
+ "summary": "Import a raw capture from Clips or a generic source",
267
+ "auth": "Bearer <ingestToken> issued per source via its sourceKey",
268
+ "request": {
269
+ "contentType": "application/json",
270
+ "example": "RawCapturePayload — bounded transcript / capture body"
271
+ },
272
+ "responses": [
273
+ { "status": "200", "description": "Capture accepted and queued for distillation" },
274
+ { "status": "401", "description": "Missing or invalid ingest bearer token" }
275
+ ]
276
+ }
277
+ ```
278
+
191
279
  Slack, Granola, and GitHub sources can opt into background `autoSync` with a
192
280
  poll cadence once review quality is proven.
193
281
 
@@ -7,17 +7,21 @@ description: "An agent-powered calendar with Google Calendar sync and Calendly-s
7
7
 
8
8
  An agent-powered calendar app. Connect your Google Calendar and the agent can read your schedule, find free slots, create events, and manage Calendly-style booking links — all in plain English. It replaces the Google Calendar + Calendly combo with one app you own.
9
9
 
10
- <!-- screenshot:
11
- app: calendar
12
- view: / (week)
13
- shows: Calendar week view (May 3-9) with ~17 events scattered across the week (All-hands kickoff, Q3 launch sync, Design review, 1:1 with Marcus, Coffee w/ Hannah, Eng standup, Lunch block, Customer call - Acme, Design crit, Focus block, Roadmap planning, Skip-level w/ Priya, Friday demo, All-hands) events render in the default blue tone and the agent sidebar with calendar-aware suggestions
14
- account: screenshot-account (Google Calendar connected and a representative week populated via create-event)
15
- capture: 1400x800 viewport, cropped 90px from bottom (final 1400x710)
16
- -->
10
+ ```an-wireframe
11
+ {
12
+ "surface": "desktop",
13
+ "html": "<div style='display:flex;flex-direction:column;min-height:530px;box-sizing:border-box'><div style='display:flex;align-items:center;gap:10px;padding:14px 18px;border-bottom:1.4px solid var(--wf-line)'><button>Week</button><button>Today</button><button>‹</button><button>›</button><div style='flex:1'></div><strong>May 3-9, 2026</strong><div style='flex:1'></div><button class='primary'>New Event</button></div><div style='display:grid;grid-template-columns:56px repeat(7,minmax(0,1fr));grid-template-rows:36px repeat(5,72px);gap:7px;padding:14px;flex:1'><div></div><strong>Sun 3</strong><strong>Mon 4</strong><strong>Tue 5</strong><strong>Wed 6</strong><strong>Thu 7</strong><strong>Fri 8</strong><strong>Sat 9</strong><small class='wf-muted'>7 AM</small><div class='wf-box' style='opacity:.45'></div><div></div><div></div><div></div><div></div><div></div><div></div><small class='wf-muted'>9 AM</small><div class='wf-box'>All-hands</div><div class='wf-box'>Eng standup</div><div class='wf-box'>Eng standup</div><div class='wf-box'>Eng standup</div><div></div><div class='wf-box'>Planning</div><div></div><small class='wf-muted'>11 AM</small><div class='wf-box'>Design review</div><div></div><div class='wf-box'>Design crit</div><div class='wf-box'>Roadmap</div><div class='wf-box'>Friday demo</div><div></div><div></div><small class='wf-muted'>1 PM</small><div></div><div class='wf-box'>1:1</div><div class='wf-box'>Focus block</div><div></div><div></div><div class='wf-box'>All-hands</div><div></div><small class='wf-muted'>3 PM</small><div></div><div></div><div></div><div class='wf-box'>Skip-level</div><div></div><div></div><div></div></div></div>"
14
+ }
15
+ ```
17
16
 
18
- ![Calendar week view with a populated week and the agent sidebar](/screenshots/calendar.png)
17
+ When you open the app, the active calendar view is the primary surface. The agent still knows which day, week, or event you're looking at, so you can say "schedule a 30-minute call with Alex on this day" without spelling everything out.
19
18
 
20
- When you open the app, you'll see your calendar in the middle and the agent in the sidebar. The agent always knows which day, week, or event you're looking at, so you can say "schedule a 30-minute call with Alex on this day" without spelling everything out.
19
+ ```an-diagram title="How a scheduling request flows" summary="Whether you click in the calendar or ask the agent, the same actions read live from Google Calendar and write back to the same view."
20
+ {
21
+ "html": "<div class=\"diagram-flow\"><div class=\"diagram-col\"><div class=\"diagram-node\">You click<br><small class=\"diagram-muted\">drag, toolbar, shortcuts</small></div><div class=\"diagram-node\">You ask the agent<br><small class=\"diagram-muted\">\"find a 1-hour slot next week\"</small></div></div><div class=\"diagram-arrow diagram-muted\" aria-hidden=\"true\">&rarr;</div><div class=\"diagram-panel center\"><span class=\"diagram-pill accent\">Actions</span><small class=\"diagram-muted\">list-events · check-availability · create-event</small></div><div class=\"diagram-arrow diagram-muted\" aria-hidden=\"true\">&rarr;</div><div class=\"diagram-col\"><div class=\"diagram-box\">Google Calendar<br><small class=\"diagram-muted\">live, multi-account</small></div><div class=\"diagram-box\">SQL<br><small class=\"diagram-muted\">bookings · availability</small></div></div><div class=\"diagram-arrow diagram-muted\" aria-hidden=\"true\">&#8635;</div><div class=\"diagram-box\">Calendar view updates 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
 
@@ -80,60 +84,17 @@ Open `http://localhost:8082` (the default Calendar dev port).
80
84
 
81
85
  To connect Google Calendar in dev, open the Settings view, paste a `GOOGLE_CLIENT_ID` and `GOOGLE_CLIENT_SECRET` from [Google Cloud Console](https://console.cloud.google.com/), and click "Connect Google Calendar". The OAuth redirect URI is `http://localhost:8082/_agent-native/google/callback` in dev. Tokens are stored in the `oauth_tokens` SQL table and refresh automatically.
82
86
 
83
- ### Key features (technical)
87
+ ### Key features
84
88
 
85
- **Calendar views.** The main view at `/` (route `app/routes/_app._index.tsx`) renders the calendar in day, week, or month mode. Switch views from the toolbar, or ask the agent to switch for you. Events are fetched live from Google Calendar no local sync step is required to see the latest state.
89
+ **Live calendar views.** Day, week, and month views read directly from connected Google accounts, with optional read-only ICS feeds layered into the same schedule.
86
90
 
87
- **Multi-account Google Calendar sync.** Connect as many Google accounts as you like. Each connection appears in Settings, and events from every connected calendar overlay in the main view. Sync is pull-based, so no webhooks or background workers are required. The `sync-google-calendar` action refetches a date range on demand. Supporting actions: `list-events`, `search-events`, `get-event`, `create-event`, `sync-google-calendar`.
88
-
89
- **External calendars (ICS subscriptions).** Subscribe to read-only ICS or `webcal://` feeds — useful for HR time off, conference schedules, or shared team calendars. Feeds are added in Settings and stored per user. Relevant actions: `add-external-calendar`, `list-external-calendars`, `remove-external-calendar`, `update-external-calendars`.
90
-
91
- **Availability rules.** Availability is a weekly schedule of time windows per day, plus a timezone. It is stored in the settings table under the key `calendar-availability`:
92
-
93
- ```json
94
- {
95
- "timezone": "America/Los_Angeles",
96
- "schedule": {
97
- "monday": [{ "start": "09:00", "end": "17:00" }],
98
- "tuesday": [{ "start": "09:00", "end": "17:00" }],
99
- "wednesday": [
100
- { "start": "09:00", "end": "12:00" },
101
- { "start": "13:00", "end": "17:00" }
102
- ],
103
- "thursday": [{ "start": "09:00", "end": "17:00" }],
104
- "friday": [{ "start": "09:00", "end": "16:00" }],
105
- "saturday": [],
106
- "sunday": []
107
- }
108
- }
109
- ```
91
+ **Availability and free-slot search.** Weekly availability rules, timezone support, and existing events all feed the same availability action the UI and agent use.
110
92
 
111
- Edit it at `/availability` (`app/routes/_app.availability.tsx`) or via the `update-availability` action. The `check-availability` action reads this schedule, subtracts your existing Google Calendar events, and returns free slots of the requested duration.
93
+ **Booking links.** Public `/book/{slug}` pages collect name, email, custom fields, conferencing preferences, and cancellation/reschedule tokens.
112
94
 
113
- **Public booking pages.** Booking links are the Calendly replacement. Create one in the UI at `/booking-links` (`app/routes/_app.booking-links._index.tsx`), configure it in the editor at `/booking-links/{id}`, and share the public URL.
95
+ **Shareable management.** Booking links are private by default, but can be shared with teammates through the framework sharing actions.
114
96
 
115
- Every link has:
116
-
117
- - A URL slug, so the public page lives at `/book/{slug}`.
118
- - A primary duration plus an optional list of alternative durations (for example 15, 30, or 60 minutes).
119
- - Optional custom fields collected at booking time.
120
- - A conferencing option (Google Meet, Zoom, or a custom meeting link).
121
- - An `isActive` toggle to pause bookings without deleting the link.
122
-
123
- Visitors land on the public page, pick a date and time from the available slots, fill in name, email, and any custom fields, and receive a confirmation. Bookings are stored in the `bookings` table with a `cancelToken`, which powers the public cancel/reschedule page at `/booking/manage/{token}`.
124
-
125
- There is also a per-user public URL at `/meet/{username}/{slug}` for clean personal sharing.
126
-
127
- **Sharing booking links with teammates.** Booking links are private by default — only the creator can edit or delete them. To let a teammate manage a link, either change the link's visibility or grant explicit access. The framework ships these actions, auto-mounted for any `booking-link` resource:
128
-
129
- - `share-resource` — grant a user or org `viewer`, `editor`, or `admin` access.
130
- - `unshare-resource` — revoke a grant.
131
- - `list-resource-shares` — show current visibility plus all grants.
132
- - `set-resource-visibility` — change the coarse visibility (`private`, `org`, or `public`).
133
-
134
- Sharing only controls who can manage the link. The public booking URL always accepts bookings from unauthenticated visitors as long as `isActive` is true.
135
-
136
- **Inline event previews in chat.** The `/event` route (`app/routes/event.tsx`) renders a compact, chromeless event card that the agent can embed in chat when you ask about a specific event. Title, time, location, attendees, and a description snippet are shown with a button to jump into the main calendar.
97
+ **Inline event previews.** The agent can embed compact event cards in chat with title, time, location, attendees, and a jump-back button.
137
98
 
138
99
  ### Working with the agent
139
100
 
@@ -150,6 +111,73 @@ Defined in `templates/calendar/server/db/schema.ts`. Only non-event data is stor
150
111
  - `booking_slug_redirects` — remembers old slugs when a link is renamed so existing public URLs keep working.
151
112
  - `booking_link_shares` — share grants for booking links.
152
113
 
114
+ ```an-schema title="Calendar data model" summary="Only non-event data is stored locally — events live in Google Calendar. Booking links use ownableColumns so the sharing system applies."
115
+ {
116
+ "entities": [
117
+ {
118
+ "id": "booking_links",
119
+ "name": "booking_links",
120
+ "note": "Calendly-style link definitions (ownable)",
121
+ "fields": [
122
+ { "name": "id", "type": "id", "pk": true },
123
+ { "name": "slug", "type": "string", "note": "public page at /book/{slug}" },
124
+ { "name": "title", "type": "string" },
125
+ { "name": "description", "type": "string", "nullable": true },
126
+ { "name": "duration", "type": "int", "note": "primary duration in minutes" },
127
+ { "name": "durations", "type": "json", "nullable": true, "note": "alternative durations" },
128
+ { "name": "customFields", "type": "json", "nullable": true },
129
+ { "name": "conferencing", "type": "string", "note": "Google Meet / Zoom / custom" },
130
+ { "name": "color", "type": "string", "nullable": true },
131
+ { "name": "isActive", "type": "bool", "note": "pause without deleting" }
132
+ ]
133
+ },
134
+ {
135
+ "id": "bookings",
136
+ "name": "bookings",
137
+ "note": "Confirmed appointments from public booking pages",
138
+ "fields": [
139
+ { "name": "id", "type": "id", "pk": true },
140
+ { "name": "slug", "type": "string", "fk": "booking_links.slug" },
141
+ { "name": "name", "type": "string" },
142
+ { "name": "email", "type": "string" },
143
+ { "name": "start", "type": "datetime" },
144
+ { "name": "end", "type": "datetime" },
145
+ { "name": "notes", "type": "string", "nullable": true },
146
+ { "name": "customFields", "type": "json", "nullable": true, "note": "custom field responses" },
147
+ { "name": "meetingLink", "type": "string", "nullable": true },
148
+ { "name": "cancelToken", "type": "string", "note": "powers /booking/manage/{token}" },
149
+ { "name": "status", "type": "enum", "note": "confirmed | cancelled" }
150
+ ]
151
+ },
152
+ {
153
+ "id": "booking_slug_redirects",
154
+ "name": "booking_slug_redirects",
155
+ "note": "Keeps old public URLs working after a link is renamed",
156
+ "fields": [
157
+ { "name": "oldSlug", "type": "string", "pk": true },
158
+ { "name": "linkId", "type": "id", "fk": "booking_links.id" }
159
+ ]
160
+ },
161
+ {
162
+ "id": "booking_link_shares",
163
+ "name": "booking_link_shares",
164
+ "note": "Share grants for booking links",
165
+ "fields": [
166
+ { "name": "id", "type": "id", "pk": true },
167
+ { "name": "linkId", "type": "id", "fk": "booking_links.id" },
168
+ { "name": "principal", "type": "string", "note": "user or org" },
169
+ { "name": "role", "type": "enum", "note": "viewer | editor | admin" }
170
+ ]
171
+ }
172
+ ],
173
+ "relations": [
174
+ { "from": "booking_links", "to": "bookings", "kind": "1-n", "label": "has bookings" },
175
+ { "from": "booking_links", "to": "booking_slug_redirects", "kind": "1-n", "label": "has old slugs" },
176
+ { "from": "booking_links", "to": "booking_link_shares", "kind": "1-n", "label": "has share grants" }
177
+ ]
178
+ }
179
+ ```
180
+
153
181
  Availability rules and per-user configuration live in the settings table, keyed by `calendar-availability`. Google OAuth tokens live in the framework `oauth_tokens` table. Ephemeral UI state (current view, date, selected event) lives in `application_state` under the `navigation` key.
154
182
 
155
183
  ### Customizing it
@@ -9,15 +9,12 @@ Chat is the basic agent-native app starting point. It gives you a clean ChatGPT-
9
9
 
10
10
  If you want the smallest action-only runtime with no browser UI, start with [Pure-Agent Apps](/docs/pure-agent-apps). If you want a finished domain product shape, start from [Calendar](/docs/template-calendar), [Mail](/docs/template-mail), [Content](/docs/template-content), [Forms](/docs/template-forms), [Analytics](/docs/template-analytics), or another domain template.
11
11
 
12
- <!-- screenshot:
13
- app: chat
14
- view: /
15
- shows: Full-page chat app with standard left sidebar, centered empty-state composer, model controls, and no domain data
16
- account: screenshot-account (no domain data needed — chat ships with no seed schema)
17
- capture: 2434x1440 app screenshot
18
- -->
19
-
20
- ![Chat template with a centered agent composer and app navigation sidebar](/screenshots/chat.png)
12
+ ```an-wireframe
13
+ {
14
+ "surface": "desktop",
15
+ "html": "<div style='min-height:560px;box-sizing:border-box;display:flex;align-items:center;justify-content:center;padding:56px 40px'><div style='display:flex;flex-direction:column;align-items:center;justify-content:center;gap:28px;width:min(700px,92%);min-height:430px'><div style='height:34px'></div><div style='text-align:center'><h1 style='margin:0'>How can I help?</h1><p class='wf-muted' style='margin:10px 0 0'>Chat about anything. Add actions, components, pages, jobs, or your own backend.</p></div><div class='wf-card' style='width:100%;min-height:150px;display:flex;flex-direction:column;gap:18px'><span class='wf-muted'>Message the agent...</span><div style='flex:1'></div><div style='display:flex;align-items:center;gap:10px'><span data-icon='plus' aria-label='Attach'></span><div style='flex:1'></div><span class='wf-pill'>Sonnet 4.6 · Auto</span><span class='wf-pill'>Act</span><button class='primary'>↑</button></div></div><div style='height:34px'></div></div></div>"
16
+ }
17
+ ```
21
18
 
22
19
  ## What's in it {#whats-in-it}
23
20
 
@@ -38,6 +35,13 @@ If you want the smallest action-only runtime with no browser UI, start with [Pur
38
35
 
39
36
  That's the point. Chat is a thin, useful default shell for your own agent, not a domain product pretending to be generic.
40
37
 
38
+ ```an-diagram title="What ships in the Chat shell" summary="A thin chat surface over the framework's standard runtime — actions, durable threads, live sync, and auth — with room to add your own UI."
39
+ {
40
+ "html": "<div class=\"diagram-chat\"><div class=\"diagram-col left\"><div class=\"diagram-node\">Thread list<br><small class=\"diagram-muted\">create · reopen · pin · archive</small></div><div class=\"diagram-node\">Full-page chat<br><small class=\"diagram-muted\">framework chat surface on /</small></div></div><div class=\"diagram-arrow diagram-muted\" aria-hidden=\"true\">&rarr;</div><div class=\"diagram-panel center\"><span class=\"diagram-pill accent\">Actions</span><small class=\"diagram-muted\">hello.ts · view-screen · navigate</small></div><div class=\"diagram-arrow diagram-muted\" aria-hidden=\"true\">&rarr;</div><div class=\"diagram-col right\"><div class=\"diagram-box\">Core SQL tables<br><small class=\"diagram-muted\">threads · application_state · settings · sessions · runs</small></div><div class=\"diagram-pill ok\">Live sync &#8635;</div><div class=\"diagram-box\">Better Auth<br><small class=\"diagram-muted\">login · orgs · sessions</small></div></div></div>",
41
+ "css": ".diagram-chat{display:flex;align-items:center;gap:12px;flex-wrap:wrap}.diagram-chat .diagram-col{display:flex;flex-direction:column;gap:10px}.diagram-chat .diagram-arrow{font-size:22px;line-height:1}.diagram-chat .center{display:flex;flex-direction:column;align-items:center;gap:4px}"
42
+ }
43
+ ```
44
+
41
45
  ## When to pick it {#when-to-pick}
42
46
 
43
47
  - **You want a basic app users can talk to immediately** and then extend with actions and UI.
@@ -70,6 +74,18 @@ From there, copy the Chat template's `/` route and sidebar thread list into your
70
74
  suggestions, empty state, composer, or surrounding layout here.
71
75
  - `AGENTS.md` tells the built-in agent how to work inside this app.
72
76
 
77
+ ```an-file-tree title="Chat template layout"
78
+ {
79
+ "entries": [
80
+ { "path": "actions/hello.ts", "note": "the one example action; replace or add actions beside it" },
81
+ { "path": "actions/view-screen.ts", "note": "standard context action the agent reads" },
82
+ { "path": "actions/navigate.ts", "note": "standard navigation action" },
83
+ { "path": "app/routes/_index.tsx", "note": "renders the full-page chat surface; edit suggestions, empty state, composer" },
84
+ { "path": "AGENTS.md", "note": "chat-first guidance the built-in agent reads" }
85
+ ]
86
+ }
87
+ ```
88
+
73
89
  The chat page is intentionally thin:
74
90
 
75
91
  ```tsx
@@ -7,18 +7,22 @@ description: "Async screen recording, calendar-synced meeting notes, and push-to
7
7
 
8
8
  A capture-everything app: screen recordings, meeting notes from your calendar, and Fn-hold voice dictation. The agent transcribes, titles, summarizes, and indexes all of it — then lets you ask "find the clip where we discussed the rollout plan" and searches across every transcript you've ever made.
9
9
 
10
- <!-- screenshot:
11
- app: clips
12
- view: /library
13
- shows: Library with Acme Co. organization, folders (Onboarding videos / Customer calls / Bug repros) and spaces (Engineering / Design / Sales) in the sidebar, six recordings in a 3-column grid (Q3 OKRs review meeting, Walkthrough of new onboarding flow, Eng standup May 4, Dictation - Ideas for landing page copy, Customer call - Acme Corp pricing review, Bug repro - drag-and-drop in Safari)
14
- account: screenshot-account (recordings imported into this org via the standard upload + meetings flow)
15
- capture: 1400x800 viewport, cropped 90px from bottom (final 1400x710)
16
- -->
17
-
18
- ![Clips library with recordings, folders, and spaces](/screenshots/clips.png)
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'>Engineering clips</h1><span class='wf-pill accent'>Library</span><span class='wf-pill'>Meetings</span><span class='wf-pill'>Dictation</span><div style='flex:1'></div><button>Import</button><button class='primary'>Record</button></div><div style='display:grid;grid-template-columns:repeat(3,1fr);gap:12px'><div class='wf-card' style='height:120px;display:flex;flex-direction:column;justify-content:end'><strong>OKRs review</strong><small>35 min</small></div><div class='wf-card' style='height:120px;display:flex;flex-direction:column;justify-content:end'><strong>Onboarding flow</strong><small>12 min</small></div><div class='wf-card' style='height:120px;display:flex;flex-direction:column;justify-content:end'><strong>Bug repro</strong><small>4 min</small></div></div><div class='wf-card' style='display:flex;gap:10px;align-items:center'><span class='wf-pill accent'>Agent-readable</span><span>Transcript + frames ready for share links</span><div style='flex:1'></div><button>Share</button></div><div class='wf-card' style='flex:1;display:flex;flex-direction:column;gap:8px'><strong>Transcript search</strong><div class='wf-box'>Matched chapter 03:12 · rollout risks and owner handoff</div><div class='wf-box'>Meeting summary and action items</div></div></div>"
14
+ }
15
+ ```
19
16
 
20
17
  Think along the lines of Loom + Granola + Wispr Flow rolled into one app — but the agent is a first-class editor across every surface, and the recordings, meetings, and dictations are yours, not a SaaS vendor's. Clips also makes shared recordings agent-readable: paste a normal Clips share link into an agent, and it can "hear" the transcript and "see" timestamped frames even when the underlying model cannot ingest raw video or audio.
21
18
 
19
+ ```an-diagram title="Capture, transcribe, reuse" summary="Three capture types land in one library; the agent transcribes, titles, and summarizes, then every transcript is searchable and shareable."
20
+ {
21
+ "html": "<div class=\"diagram-clips\"><div class=\"diagram-col\"><div class=\"diagram-node\">Screen recording</div><div class=\"diagram-node\">Calendar meeting</div><div class=\"diagram-node\">Fn-hold dictation</div></div><div class=\"diagram-arrow diagram-muted\" aria-hidden=\"true\">&rarr;</div><div class=\"diagram-box\" data-rough>One library<br><small class=\"diagram-muted\">recordings + transcripts (SQL)</small></div><div class=\"diagram-arrow diagram-muted\" aria-hidden=\"true\">&rarr;</div><div class=\"diagram-panel center\"><span class=\"diagram-pill accent\">Agent</span><small class=\"diagram-muted\">title · summary · chapters</small></div><div class=\"diagram-arrow diagram-muted\" aria-hidden=\"true\">&rarr;</div><div class=\"diagram-col\"><div class=\"diagram-pill\">Search</div><div class=\"diagram-pill\">Share</div><div class=\"diagram-pill\">Agent-readable links</div></div></div>",
22
+ "css": ".diagram-clips{display:flex;align-items:center;gap:12px;flex-wrap:wrap}.diagram-clips .diagram-col{display:flex;flex-direction:column;gap:8px}.diagram-clips .center{display:flex;flex-direction:column;align-items:center;gap:4px}.diagram-clips .diagram-arrow{font-size:22px;line-height:1}"
23
+ }
24
+ ```
25
+
22
26
  ## What you can do with it
23
27
 
24
28
  - **Record your screen** with a built-in recorder, webcam overlay, audio capture, and pause/trim.
@@ -49,6 +53,51 @@ Password-protected clips require the password once; successful responses return
49
53
  short-lived tokenized links so downstream agents do not need the plaintext
50
54
  password.
51
55
 
56
+ ```an-api title="Agent context entry point"
57
+ {
58
+ "method": "GET",
59
+ "path": "/api/agent-context.json",
60
+ "summary": "Compact, agent-readable description of a shared clip",
61
+ "description": "Returns clip metadata, transcript status, chapters, CTAs, recommended frames, and links to the transcript and frame APIs. Advertised by the public share page so a text- or image-only agent can understand a recording without ingesting raw video.",
62
+ "auth": "Same public / password / expiry rules as the share page",
63
+ "params": [
64
+ { "name": "id", "in": "query", "type": "string", "required": true, "description": "Recording id" }
65
+ ],
66
+ "responses": [
67
+ { "status": "200", "description": "Clip metadata plus transcript and frame API links" }
68
+ ]
69
+ }
70
+ ```
71
+
72
+ ```an-api title="Timestamped transcript"
73
+ {
74
+ "method": "GET",
75
+ "path": "/api/agent-transcript.json",
76
+ "summary": "Timestamped transcript segments for a shared clip",
77
+ "params": [
78
+ { "name": "id", "in": "query", "type": "string", "required": true, "description": "Recording id" }
79
+ ],
80
+ "responses": [
81
+ { "status": "200", "description": "Segments with startMs, endMs, readable timestamps, text, and optional source labels" }
82
+ ]
83
+ }
84
+ ```
85
+
86
+ ```an-api title="Frame at a timestamp"
87
+ {
88
+ "method": "GET",
89
+ "path": "/api/agent-frame.jpg",
90
+ "summary": "A JPEG frame extracted from the video at an original-video timestamp",
91
+ "params": [
92
+ { "name": "id", "in": "query", "type": "string", "required": true, "description": "Recording id" },
93
+ { "name": "atMs", "in": "query", "type": "integer", "required": true, "description": "Original-video timestamp in milliseconds" }
94
+ ],
95
+ "responses": [
96
+ { "status": "200", "description": "image/jpeg frame" }
97
+ ]
98
+ }
99
+ ```
100
+
52
101
  ## Getting started
53
102
 
54
103
  Live demo: [clips.agent-native.com](https://clips.agent-native.com).
@@ -89,22 +138,81 @@ Clips is a larger template with a native recorder (it ships a desktop companion
89
138
  2. **Google Calendar (optional).** To sync upcoming meetings, connect a Google Calendar account from Settings. The OAuth callback URL in dev is `http://localhost:8094/_agent-native/google/callback`. Set up a Google OAuth client in [Google Cloud Console](https://console.cloud.google.com/) with the Gmail and Google Calendar APIs enabled.
90
139
  3. **Screen-capture permissions.** On macOS, grant Screen Recording permission to the browser (or the desktop companion app) in System Settings → Privacy & Security → Screen Recording.
91
140
 
92
- ### Key features (technical)
141
+ ### Key features
93
142
 
94
- **One library, three capture types.** Screen recordings, calendar-sourced meetings, and push-to-talk dictations all live in the same searchable library. Recordings and transcripts are deliberately split into separate tables so the library grid and the transcript view each render fast.
143
+ **One library, three capture types.** Screen recordings, calendar meetings, and push-to-talk dictations share one searchable library.
95
144
 
96
- **Transcript and AI pipeline.** Each recording gets timestamped transcript segments (`{startMs, endMs, text}`), an auto-generated title, summary, and chapter markers. `cleanup-transcript` and `finalize-meeting` are server-side media-pipeline calls; most other AI features (titles, summaries, quotes) delegate to the agent chat.
145
+ **Transcript and AI pipeline.** Recordings get timestamped transcript segments, generated titles, summaries, and chapter markers.
97
146
 
98
- **Non-destructive editing.** Trim, split, filler-word removal, silence removal, and stitching accumulate in a recording's `edits_json` rather than re-encoding. The client concatenates and exports through ffmpeg.wasm, so the original media stays intact.
147
+ **Non-destructive editing.** Trim, split, filler-word removal, silence removal, and stitching stay in `edits_json` so original media remains intact.
99
148
 
100
- **Agent-readable share links.** A public Clips share link advertises a compact agent context URL that points at the transcript and frame APIs, so text- and image-only models can understand a recording without ingesting raw video — see [Agent-readable clips](#agent-readable-clips) above.
101
-
102
- **Meetings compose with recordings.** A meeting owns the recording it captures, but the `recordings` row stays the source of truth for the video and per-segment transcript instead of duplicating media.
149
+ **Agent-readable share links.** Public share links expose transcript and frame APIs so agents can understand recordings without ingesting raw video.
103
150
 
104
151
  ### Data model
105
152
 
106
153
  All data lives in SQL via Drizzle ORM. Schema: `templates/clips/server/db/schema.ts`. Recordings, meetings, dictations, calendar accounts, and vocabulary all carry the standard `ownableColumns` and have a matching framework shares table, so they slot into the per-user / per-org sharing model.
107
154
 
155
+ ```an-schema title="Clips core data model" summary="recordings is the source of truth for media; transcripts, meetings, and dictations compose with it rather than duplicating video. (Engagement and org tables omitted for clarity — see the full table below.)"
156
+ {
157
+ "entities": [
158
+ {
159
+ "id": "recordings",
160
+ "name": "recordings",
161
+ "note": "Core resource; source of truth for media. ownableColumns",
162
+ "fields": [
163
+ { "name": "id", "type": "text", "pk": true },
164
+ { "name": "title", "type": "text" },
165
+ { "name": "video_url", "type": "text", "note": "plus format / size / duration / thumbnails" },
166
+ { "name": "status", "type": "text" },
167
+ { "name": "edits_json", "type": "text", "note": "Non-destructive edits" },
168
+ { "name": "chapters_json", "type": "text", "nullable": true },
169
+ { "name": "password", "type": "text", "nullable": true, "note": "Privacy: password / expiry" }
170
+ ]
171
+ },
172
+ {
173
+ "id": "recording_transcripts",
174
+ "name": "recording_transcripts",
175
+ "note": "Split out so the library and transcript views render fast",
176
+ "fields": [
177
+ { "name": "recording_id", "type": "text", "fk": "recordings.id" },
178
+ { "name": "segments_json", "type": "text", "note": "{ startMs, endMs, text }" },
179
+ { "name": "full_text", "type": "text" },
180
+ { "name": "language", "type": "text" },
181
+ { "name": "status", "type": "text" }
182
+ ]
183
+ },
184
+ {
185
+ "id": "clips_meetings",
186
+ "name": "clips_meetings",
187
+ "note": "Calendar-sourced or ad-hoc; owns a recording",
188
+ "fields": [
189
+ { "name": "id", "type": "text", "pk": true },
190
+ { "name": "recording_id", "type": "text", "fk": "recordings.id", "nullable": true },
191
+ { "name": "summary_md", "type": "text", "nullable": true },
192
+ { "name": "bullets_json", "type": "text", "nullable": true },
193
+ { "name": "action_items_json", "type": "text", "nullable": true }
194
+ ]
195
+ },
196
+ {
197
+ "id": "clips_dictations",
198
+ "name": "clips_dictations",
199
+ "note": "Push-to-talk dictation history; ownableColumns",
200
+ "fields": [
201
+ { "name": "id", "type": "text", "pk": true },
202
+ { "name": "full_text", "type": "text", "note": "Raw" },
203
+ { "name": "cleaned_text", "type": "text", "nullable": true },
204
+ { "name": "source", "type": "text", "note": "fn-hold, etc." },
205
+ { "name": "target_app", "type": "text", "nullable": true }
206
+ ]
207
+ }
208
+ ],
209
+ "relations": [
210
+ { "from": "recordings", "to": "recording_transcripts", "kind": "1-1", "label": "transcript" },
211
+ { "from": "recordings", "to": "clips_meetings", "kind": "1-1", "label": "captured by" }
212
+ ]
213
+ }
214
+ ```
215
+
108
216
  | Table | What it holds |
109
217
  | ----------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
110
218
  | `recordings` | The core resource — title, video URL/format/size, duration, thumbnails, status, non-destructive `edits_json`, `chapters_json`, privacy (password, expiry), and player toggles |