@agent-native/core 0.157.3 → 0.157.5

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 (211) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/templates/analytics/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  3. package/corpus/templates/analytics/.agents/skills/sharing/SKILL.md +21 -0
  4. package/corpus/templates/analytics/server/lib/first-party-analytics-backend.ts +40 -1
  5. package/corpus/templates/assets/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  6. package/corpus/templates/assets/.agents/skills/sharing/SKILL.md +21 -0
  7. package/corpus/templates/brain/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  8. package/corpus/templates/brain/.agents/skills/sharing/SKILL.md +21 -0
  9. package/corpus/templates/calendar/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  10. package/corpus/templates/calendar/.agents/skills/sharing/SKILL.md +21 -0
  11. package/corpus/templates/calendar/app/components/layout/AppLayout.tsx +3 -1
  12. package/corpus/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  13. package/corpus/templates/chat/.agents/skills/sharing/SKILL.md +21 -0
  14. package/corpus/templates/clips/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  15. package/corpus/templates/clips/.agents/skills/meetings/SKILL.md +7 -7
  16. package/corpus/templates/clips/actions/approve-recording-access-request.ts +147 -0
  17. package/corpus/templates/clips/actions/request-recording-access.ts +121 -23
  18. package/corpus/templates/clips/actions/view-screen.ts +1 -1
  19. package/corpus/templates/clips/app/components/meetings/share-meeting-dialog.tsx +34 -53
  20. package/corpus/templates/clips/app/components/player/request-access-dialog.tsx +104 -0
  21. package/corpus/templates/clips/app/components/player/share-dialog.tsx +36 -45
  22. package/corpus/templates/clips/app/components/sharing/share-ui.tsx +3 -6
  23. package/corpus/templates/clips/app/i18n/en-US.ts +26 -1
  24. package/corpus/templates/clips/app/lib/public-meeting.ts +1 -1
  25. package/corpus/templates/clips/app/routes/access-request.approve.tsx +250 -0
  26. package/corpus/templates/clips/app/routes/r.$recordingId.tsx +9 -32
  27. package/corpus/templates/clips/app/routes/share.$shareId.tsx +123 -37
  28. package/corpus/templates/clips/app/routes/share.meeting.$meetingId.tsx +41 -1
  29. package/corpus/templates/clips/server/lib/calendar-event-meetings.ts +1 -0
  30. package/corpus/templates/clips/server/lib/emails.ts +40 -11
  31. package/corpus/templates/clips/shared/recording-link.ts +32 -1
  32. package/corpus/templates/clips/shared/share-attribution.ts +13 -0
  33. package/corpus/templates/content/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  34. package/corpus/templates/content/.agents/skills/sharing/SKILL.md +21 -0
  35. package/corpus/templates/content/app/components/editor/DocumentBlockFields.tsx +22 -10
  36. package/corpus/templates/content/app/components/editor/SlashCommandMenu.tsx +2 -1
  37. package/corpus/templates/content/app/components/editor/VisualEditor.tsx +245 -9
  38. package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +185 -134
  39. package/corpus/templates/content/app/components/editor/extensions/ImageBlock.tsx +61 -45
  40. package/corpus/templates/content/app/components/editor/extensions/ImageNode.ts +6 -0
  41. package/corpus/templates/content/app/components/editor/image-upload.ts +137 -5
  42. package/corpus/templates/content/app/global.css +8 -0
  43. package/corpus/templates/content/changelog/2026-08-12-image-uploads-now-confirm-the-image-can-be-displayed-before-.md +6 -0
  44. package/corpus/templates/content/changelog/2026-08-14-images-fill-the-page-width-by-default-and-remain-visible-whe.md +6 -0
  45. package/corpus/templates/content/changelog/2026-08-14-images-inserted-from-the-slash-command-stay-saved-after-uplo.md +6 -0
  46. package/corpus/templates/content/changelog/2026-08-14-svg-files-can-be-selected-reliably-from-the-image-picker.md +6 -0
  47. package/corpus/templates/crm/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  48. package/corpus/templates/crm/.agents/skills/sharing/SKILL.md +21 -0
  49. package/corpus/templates/design/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  50. package/corpus/templates/design/.agents/skills/sharing/SKILL.md +21 -0
  51. package/corpus/templates/dispatch/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  52. package/corpus/templates/dispatch/.agents/skills/sharing/SKILL.md +21 -0
  53. package/corpus/templates/factory/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  54. package/corpus/templates/factory/.agents/skills/sharing/SKILL.md +21 -0
  55. package/corpus/templates/forms/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  56. package/corpus/templates/forms/.agents/skills/sharing/SKILL.md +21 -0
  57. package/corpus/templates/macros/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  58. package/corpus/templates/macros/.agents/skills/sharing/SKILL.md +21 -0
  59. package/corpus/templates/mail/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  60. package/corpus/templates/mail/.agents/skills/sharing/SKILL.md +21 -0
  61. package/corpus/templates/mail/app/components/layout/AppLayout.tsx +6 -1
  62. package/corpus/templates/plan/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  63. package/corpus/templates/plan/.agents/skills/sharing/SKILL.md +21 -0
  64. package/corpus/templates/plan/app/pages/PlansPage.tsx +25 -30
  65. package/corpus/templates/slides/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  66. package/corpus/templates/slides/.agents/skills/sharing/SKILL.md +21 -0
  67. package/corpus/templates/slides/app/components/deck/SlideRenderer.tsx +2 -1
  68. package/corpus/templates/slides/app/components/editor/ShareDialog.tsx +124 -180
  69. package/corpus/templates/slides/app/components/onboarding/FirstDeckOnboardingFlow.tsx +1 -0
  70. package/corpus/templates/slides/app/global.css +99 -3
  71. package/corpus/templates/slides/app/i18n/en-US.ts +1 -0
  72. package/corpus/templates/tasks/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  73. package/corpus/templates/tasks/.agents/skills/sharing/SKILL.md +21 -0
  74. package/dist/chat-threads/schema.d.ts +1 -1
  75. package/dist/cli/code-agent-executor.js +318 -0
  76. package/dist/client/AgentPanel.d.ts +13 -1
  77. package/dist/client/AgentPanel.js +41 -3
  78. package/dist/client/AssistantChat.d.ts +9 -1
  79. package/dist/client/AssistantChat.js +26 -13
  80. package/dist/client/MultiTabAssistantChat.js +18 -5
  81. package/dist/client/agent-chat.d.ts +8 -0
  82. package/dist/client/agent-chat.js +15 -0
  83. package/dist/client/app-chat-sidebar.d.ts +23 -0
  84. package/dist/client/app-chat-sidebar.js +53 -0
  85. package/dist/client/app-providers.js +31 -2
  86. package/dist/client/frame-protocol.d.ts +20 -2
  87. package/dist/client/hooks/index.d.ts +1 -0
  88. package/dist/client/hooks/index.js +1 -0
  89. package/dist/client/sharing/AgentShareSection.d.ts +8 -0
  90. package/dist/client/sharing/AgentShareSection.js +50 -0
  91. package/dist/client/sharing/ShareButton.js +2 -1
  92. package/dist/client/sharing/ShareDialog.d.ts +2 -2
  93. package/dist/client/sharing/ShareDialog.js +21 -29
  94. package/dist/client/sharing/index.d.ts +1 -0
  95. package/dist/client/sharing/index.js +1 -0
  96. package/dist/client/sharing/useShareButtonController.d.ts +1 -0
  97. package/dist/client/sharing/useShareDialogController.d.ts +3 -0
  98. package/dist/client/sharing/useShareDialogController.js +2 -1
  99. package/dist/client/theme.d.ts +21 -0
  100. package/dist/client/theme.js +60 -0
  101. package/dist/client/ui/index.d.ts +1 -1
  102. package/dist/client/ui/index.js +1 -1
  103. package/dist/client/use-session.js +23 -0
  104. package/dist/collab/awareness.d.ts +2 -2
  105. package/dist/collab/struct-routes.d.ts +1 -1
  106. package/dist/dashboard-storage/schema.d.ts +1 -1
  107. package/dist/data-programs/schema.d.ts +1 -1
  108. package/dist/extensions/schema.d.ts +1 -1
  109. package/dist/localization/core-messages/ar-SA.js +6 -0
  110. package/dist/localization/core-messages/de-DE.js +6 -0
  111. package/dist/localization/core-messages/en-US.d.ts +6 -0
  112. package/dist/localization/core-messages/en-US.js +6 -0
  113. package/dist/localization/core-messages/es-ES.js +6 -0
  114. package/dist/localization/core-messages/fr-FR.js +6 -0
  115. package/dist/localization/core-messages/hi-IN.js +6 -0
  116. package/dist/localization/core-messages/ja-JP.js +6 -0
  117. package/dist/localization/core-messages/ko-KR.js +6 -0
  118. package/dist/localization/core-messages/pt-BR.js +6 -0
  119. package/dist/localization/core-messages/zh-CN.js +6 -0
  120. package/dist/localization/core-messages/zh-TW.js +6 -0
  121. package/dist/localization/core-messages.d.ts +6 -0
  122. package/dist/localization/default-messages.d.ts +1 -0
  123. package/dist/localization/default-messages.js +1 -0
  124. package/dist/notifications/routes.d.ts +3 -3
  125. package/dist/progress/routes.d.ts +1 -1
  126. package/dist/provider-api/actions/custom-provider-registration.d.ts +14 -14
  127. package/dist/provider-api/actions/provider-api.d.ts +14 -14
  128. package/dist/server/auth.js +8 -5
  129. package/dist/server/identity-sso-store.d.ts +6 -1
  130. package/dist/server/identity-sso-store.js +57 -14
  131. package/dist/server/identity-sso.d.ts +7 -8
  132. package/dist/server/identity-sso.js +15 -12
  133. package/dist/sharing/actions/list-resource-shares.d.ts +2 -0
  134. package/dist/sharing/actions/list-resource-shares.js +1 -0
  135. package/dist/sharing/schema.d.ts +1 -1
  136. package/dist/sharing/schema.js +4 -1
  137. package/dist/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  138. package/dist/templates/chat/.agents/skills/sharing/SKILL.md +21 -0
  139. package/dist/templates/default/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  140. package/dist/templates/default/.agents/skills/sharing/SKILL.md +21 -0
  141. package/dist/templates/headless/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  142. package/dist/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  143. package/dist/templates/workspace-core/.agents/skills/sharing/SKILL.md +21 -0
  144. package/docs/content/actions-access-control.mdx +226 -0
  145. package/docs/content/actions-advanced.mdx +152 -0
  146. package/docs/content/actions-defining.mdx +275 -0
  147. package/docs/content/actions-other-surfaces.mdx +167 -0
  148. package/docs/content/actions-overview.mdx +214 -0
  149. package/docs/content/actions-run-context.mdx +180 -0
  150. package/docs/content/agent-surfaces.mdx +1 -1
  151. package/docs/content/agent-teams.mdx +1 -1
  152. package/docs/content/agent-web-surfaces.mdx +1 -1
  153. package/docs/content/audit-log.mdx +1 -1
  154. package/docs/content/automation-connectors.mdx +1 -1
  155. package/docs/content/automations.mdx +1 -1
  156. package/docs/content/blueprint-installer.mdx +1 -1
  157. package/docs/content/cli-adapters.mdx +1 -1
  158. package/docs/content/client-agent-chat.mdx +1 -1
  159. package/docs/content/client-data.mdx +2 -2
  160. package/docs/content/client-overview.mdx +2 -2
  161. package/docs/content/components.mdx +1 -1
  162. package/docs/content/cross-app-sso.mdx +24 -17
  163. package/docs/content/data-programs.mdx +2 -2
  164. package/docs/content/database.mdx +1 -1
  165. package/docs/content/deployment.mdx +1 -1
  166. package/docs/content/docs-components.mdx +14 -3
  167. package/docs/content/drop-in-agent.mdx +2 -2
  168. package/docs/content/durable-resume.mdx +1 -1
  169. package/docs/content/evals.mdx +1 -1
  170. package/docs/content/extensions.mdx +1 -1
  171. package/docs/content/external-agents-catalog.mdx +2 -2
  172. package/docs/content/external-agents.mdx +1 -1
  173. package/docs/content/generative-ui.mdx +1 -1
  174. package/docs/content/getting-started.mdx +1 -1
  175. package/docs/content/http-api.mdx +4 -4
  176. package/docs/content/human-approval.mdx +1 -1
  177. package/docs/content/key-concepts.mdx +1 -1
  178. package/docs/content/mcp-apps.mdx +1 -1
  179. package/docs/content/mcp-clients.mdx +1 -1
  180. package/docs/content/mcp-protocol.mdx +1 -1
  181. package/docs/content/native-chat-ui.mdx +1 -1
  182. package/docs/content/observability.mdx +1 -1
  183. package/docs/content/organizations-teams-permissions.mdx +1 -1
  184. package/docs/content/processors.mdx +1 -1
  185. package/docs/content/pure-agent-apps.mdx +1 -1
  186. package/docs/content/recurring-jobs.mdx +1 -1
  187. package/docs/content/server-database.mdx +1 -1
  188. package/docs/content/server-overview.mdx +3 -3
  189. package/docs/content/server-routes.mdx +2 -2
  190. package/docs/content/template-analytics-developers.mdx +1 -1
  191. package/docs/content/template-assets-developers.mdx +1 -1
  192. package/docs/content/template-brain-developers.mdx +1 -1
  193. package/docs/content/template-calendar-developers.mdx +1 -1
  194. package/docs/content/template-chat-first-edits.mdx +1 -1
  195. package/docs/content/template-chat.mdx +1 -1
  196. package/docs/content/template-content-developers.mdx +1 -1
  197. package/docs/content/template-forms-developers.mdx +1 -1
  198. package/docs/content/template-forms.mdx +1 -1
  199. package/docs/content/template-mail-developers.mdx +2 -2
  200. package/docs/content/toolkit-org-team.mdx +1 -1
  201. package/docs/content/tracking.mdx +1 -1
  202. package/docs/content/what-is-agent-native.mdx +1 -1
  203. package/package.json +2 -2
  204. package/src/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  205. package/src/templates/chat/.agents/skills/sharing/SKILL.md +21 -0
  206. package/src/templates/default/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  207. package/src/templates/default/.agents/skills/sharing/SKILL.md +21 -0
  208. package/src/templates/headless/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  209. package/src/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  210. package/src/templates/workspace-core/.agents/skills/sharing/SKILL.md +21 -0
  211. package/docs/content/actions.mdx +0 -750
@@ -0,0 +1,214 @@
1
+ ---
2
+ title: "Overview"
3
+ description: "Actions are the single source of truth for anything your app does. Define one with defineAction() and it fans out to an agent tool, UI hooks, HTTP, an MCP tool, an A2A tool, and a CLI command."
4
+ ---
5
+
6
+ # Overview
7
+
8
+ Actions are the single source of truth for anything your app does. Define one with `defineAction()` and drop it in `actions/`. Every surface below picks it up automatically. You write the logic once. No surface gets its own copy, and none can drift out of sync with the others.
9
+
10
+ <Cards columns={2}>
11
+
12
+ ### :robot: [Agent Tool](/docs/agent-surfaces)
13
+
14
+ The agent reads the description and schema as a callable tool. Ask for it in chat, like "reply to this ticket" or "summarize this thread."
15
+
16
+ ### :components: [UI Hooks](/docs/client-data)
17
+
18
+ `useActionQuery()`, `useActionMutation()`, and `callAction()` call the same action from React. A click and a chat message run the exact same operation.
19
+
20
+ ### :server: [Framework Transport](/docs/http-api)
21
+
22
+ Auto-mounted at `/_agent-native/actions/<name>` on startup. The UI hooks call this route under the hood, and an external HTTP client can call it directly too.
23
+
24
+ ### :plug: [MCP Tool](/docs/actions-other-surfaces#mcp)
25
+
26
+ Shows up as a tool to any MCP host: Claude, Claude Desktop, Cursor, Codex. Use it when a different AI client should drive your app.
27
+
28
+ ### :network: [A2A Tool](/docs/actions-other-surfaces#a2a)
29
+
30
+ Other agent-native apps discover and call it over A2A. Use it when a second app in your workspace needs this one to act on its behalf.
31
+
32
+ ### :terminal: [CLI Command](/docs/actions-other-surfaces#cli)
33
+
34
+ `pnpm action <name>` runs it from a terminal. Use it for scripts, cron jobs, and quick manual tests.
35
+
36
+ </Cards>
37
+
38
+ Most apps build a separate API layer between the frontend and the database, one that only the browser can call. An agent that wants the same capability needs its own, separate integration, written and maintained again. Agent-native apps skip that split. The UI and the agent call the exact same action, so there is only one implementation to write, and only one place for a bug to hide.
39
+
40
+ <Diagram id="doc-block-actions-overview-2" title="Traditional frontend vs. Agent Native" summary="A traditional frontend calls its own API layer, which only it can reach. In Agent Native, app/ and the agent both call the same actions, so every capability built here is agent-callable for free.">
41
+
42
+ ```html
43
+ <div class="diagram-cocmp">
44
+ <div class="cocmp-col">
45
+ <div class="cocmp-label diagram-muted">Traditional</div>
46
+ <div class="diagram-node">app/ (React frontend)</div>
47
+ <div class="cocmp-arrow diagram-muted" aria-hidden="true">&#8595;</div>
48
+ <div class="diagram-panel" data-rough>
49
+ <strong>API layer</strong>
50
+ <small class="diagram-muted">only the frontend calls it</small>
51
+ </div>
52
+ <div class="cocmp-arrow diagram-muted" aria-hidden="true">&#8595;</div>
53
+ <div class="diagram-box" data-rough>Database</div>
54
+ </div>
55
+ <div class="cocmp-vs diagram-muted">vs</div>
56
+ <div class="cocmp-col">
57
+ <div class="cocmp-label diagram-muted">Agent Native</div>
58
+ <div class="cocmp-callers">
59
+ <div class="diagram-node">app/ (React frontend)</div>
60
+ <div class="diagram-node">Agent</div>
61
+ </div>
62
+ <div class="cocmp-arrow diagram-muted" aria-hidden="true">&#8595;</div>
63
+ <div class="diagram-panel" data-rough>
64
+ <span class="diagram-pill accent">Actions</span
65
+ ><small class="diagram-muted">equal partners, same operations</small>
66
+ </div>
67
+ <div class="cocmp-arrow diagram-muted" aria-hidden="true">&#8595;</div>
68
+ <div class="diagram-box" data-rough>SQL database</div>
69
+ </div>
70
+ </div>
71
+ ```
72
+
73
+ ```css
74
+ .diagram-cocmp {
75
+ display: flex;
76
+ align-items: flex-start;
77
+ gap: 28px;
78
+ flex-wrap: wrap;
79
+ }
80
+ .cocmp-col {
81
+ display: flex;
82
+ flex-direction: column;
83
+ align-items: center;
84
+ gap: 8px;
85
+ flex: 1;
86
+ min-width: 180px;
87
+ }
88
+ .cocmp-label {
89
+ font-size: 11px;
90
+ text-transform: uppercase;
91
+ letter-spacing: 0.06em;
92
+ font-weight: 600;
93
+ }
94
+ .cocmp-callers {
95
+ display: flex;
96
+ gap: 8px;
97
+ flex-wrap: wrap;
98
+ justify-content: center;
99
+ }
100
+ .cocmp-vs {
101
+ font-size: 13px;
102
+ font-weight: 600;
103
+ padding-top: 52px;
104
+ }
105
+ .diagram-cocmp .diagram-panel {
106
+ display: flex;
107
+ flex-direction: column;
108
+ gap: 6px;
109
+ padding: 12px 16px;
110
+ align-self: stretch;
111
+ align-items: center;
112
+ }
113
+ .cocmp-arrow {
114
+ font-size: 18px;
115
+ line-height: 1;
116
+ }
117
+ ```
118
+
119
+ </Diagram>
120
+
121
+ If the UI and the agent both need to do something, reach for an action instead of a custom route. For the rare case where a route-shaped protocol is the right call, visit [Prefer Actions For App Operations](/docs/server-overview#actions-first).
122
+
123
+ ## Where Actions Fit {#role}
124
+
125
+ `app/` (visit [Client Overview](/docs/client-overview#role)) and the agent both resolve to the same actions and the same SQL database. There is no separate "app backend" this layer talks to that the agent can't also reach. Building a feature means defining an operation here and getting a UI, an agent tool, and every other surface for it at the same time.
126
+
127
+ `actions/` itself is a flat folder. Each file is one action: a `defineAction()` call exported as the file's default export. The framework scans this folder on startup and mounts every file it finds. There is no registration step and no index file to keep up to date.
128
+
129
+ An action's `run()` body is regular server code, so it commonly reaches into a few other directories:
130
+
131
+ <FileTree
132
+ id="doc-block-actions-overview-filetree"
133
+ entries={[
134
+ {
135
+ path: "actions/reply-to-email.ts",
136
+ note: "One action per file. Exports a defineAction() call, and the framework mounts it automatically.",
137
+ },
138
+ {
139
+ path: "server/db/schema.ts",
140
+ note: "Drizzle table definitions most actions read and write through.",
141
+ },
142
+ {
143
+ path: "server/lib/access.ts",
144
+ note: "Shared access guards (accessFilter, assertAccess, authorize) reused across actions.",
145
+ },
146
+ {
147
+ path: "shared/feature-flags.ts",
148
+ note: "Flag definitions an action and a server plugin both check.",
149
+ },
150
+ {
151
+ path: "app/components/ReplyButton.tsx",
152
+ note: "Calls the action from the UI with useActionMutation.",
153
+ },
154
+ ]}
155
+ />
156
+
157
+ Nothing outside `actions/` should import an action's `run` function directly. Call it through one of the surfaces above instead: the agent tool, a UI hook, HTTP, MCP, A2A, or the CLI. Every one of those paths runs the same schema validation, access checks, and audit trail.
158
+
159
+ ## Start with one action {#hello-action}
160
+
161
+ The first operation in a chat-first app can be tiny. In the Chat template,
162
+ replace `actions/hello.ts` or add a new file beside it:
163
+
164
+ ```ts
165
+ // actions/hello.ts
166
+ import { defineAction } from "@agent-native/core/action";
167
+ import { z } from "zod";
168
+
169
+ export default defineAction({
170
+ description: "Say hello from the local agent.",
171
+ schema: z.object({
172
+ name: z.string().default("world"),
173
+ }),
174
+ http: { method: "GET" },
175
+ readOnly: true,
176
+ run: async ({ name }) => {
177
+ return { message: `Hello, ${name}!` };
178
+ },
179
+ });
180
+ ```
181
+
182
+ Run it from the same folder:
183
+
184
+ ```bash
185
+ pnpm action hello '{"name":"Steve"}'
186
+ ```
187
+
188
+ The CLI accepts a JSON object as the action input, which matches the structured
189
+ tool calls agents already make. Simple flags still work for quick manual runs:
190
+
191
+ ```bash
192
+ pnpm action hello --name Steve
193
+ ```
194
+
195
+ Then run the app-agent loop against the folder:
196
+
197
+ ```bash
198
+ npx agent-native agent "Call hello for Steve and explain the result"
199
+ ```
200
+
201
+ That is the same app-agent loop your scheduled jobs, chat UI, external MCP
202
+ tools, and future screens will use. Chat and domain templates are for adding UI
203
+ around actions, not a required prerequisite for the action itself.
204
+
205
+ ## What's next
206
+
207
+ - [**Defining Actions**](/docs/actions-defining) — `defineAction()` anatomy, schema, and HTTP config
208
+ - [**Access & Authorization**](/docs/actions-access-control) — exposure flags, `ctx` scoping, and `authorize`
209
+ - [**Run Context**](/docs/actions-run-context) — the full `ctx` field table
210
+ - [**Other Surfaces**](/docs/actions-other-surfaces) — native chat UI, CLI, A2A, MCP, and standard actions
211
+ - [**Advanced & Legacy**](/docs/actions-advanced) — feature-flag gating and legacy CLI-style actions
212
+ - [**Overview**](/docs/client-overview) — the `app/` side of this same contract
213
+ - [**Data & Sync**](/docs/client-data) — `useActionQuery`, `useActionMutation`, and `callAction` in the UI
214
+ - [**Agent Surfaces**](/docs/agent-surfaces) — how one action grows from chat tool to full screen
@@ -0,0 +1,180 @@
1
+ ---
2
+ title: "Run Context"
3
+ description: "The ctx second argument passed to run(): the full ActionRunContext signature and the caller union, for tracking, automation attribution, and cross-cutting concerns."
4
+ ---
5
+
6
+ # Run Context
7
+
8
+ `run` receives an optional second argument, `ctx`, carrying the resolved request identity and the surface that invoked the action. Read it instead of calling `getRequestUserEmail()` / `getRequestOrgId()` by hand, and pass the whole `ctx` to tracking:
9
+
10
+ ```ts
11
+ export default defineAction({
12
+ description: "Log an audit entry for the current request.",
13
+ schema: z.object({ event: z.string() }),
14
+ run: async (args, ctx) => {
15
+ // ctx is undefined-safe: a 1-arg `run(args)` is still valid.
16
+ const actor = ctx?.userEmail ?? "system";
17
+ if (ctx?.caller === "frontend") {
18
+ // tighter rules for browser-initiated calls, looser for "tool"/"cli"
19
+ }
20
+ await db.insert(audit).values({
21
+ actor,
22
+ orgId: ctx?.orgId ?? null,
23
+ source: ctx?.caller ?? "unknown",
24
+ event: args.event,
25
+ });
26
+ return { ok: true };
27
+ },
28
+ });
29
+ ```
30
+
31
+ Most actions only ever read `ctx?.userEmail` and `ctx?.orgId`, the [access-control scoping](/docs/actions-access-control#access-control) used in nearly every real action. The rest of this page covers cross-cutting concerns like tracking and automation attribution, which fewer actions need.
32
+
33
+ ## The `ctx` argument {#ctx}
34
+
35
+ `ctx` carries two kinds of information: the resolved request identity (`userEmail`, `orgId`) that's present on nearly every call, and metadata about the surface that invoked the action (`caller`, plus surface-specific fields like `threadId` or `automation` that are only populated for certain callers). The full shape, as the second argument to `run()`:
36
+
37
+ <Signature
38
+ id="doc-block-actions-run-context-1"
39
+ name="run"
40
+ params={[
41
+ {
42
+ name: "args",
43
+ type: "TInput",
44
+ description: "The validated input, parsed from `schema`.",
45
+ },
46
+ {
47
+ name: "ctx",
48
+ type: "ActionRunContext",
49
+ optional: true,
50
+ description:
51
+ "The resolved request identity and the surface that invoked the action. Undefined-safe: a 1-argument `run(args)` handler is still valid.",
52
+ fields: [
53
+ {
54
+ name: "userEmail",
55
+ type: "string",
56
+ optional: true,
57
+ description:
58
+ "Resolved request user. **Never defaulted to a dev identity**: `undefined` when the request has no authenticated user. Apply your own fallback if you need one.",
59
+ },
60
+ {
61
+ name: "orgId",
62
+ type: "string | null",
63
+ description:
64
+ "Resolved org id, or `null` when the request has no org.",
65
+ },
66
+ {
67
+ name: "caller",
68
+ type: "ActionCaller",
69
+ description:
70
+ "How the action was invoked. See [the caller union](#caller) below.",
71
+ },
72
+ {
73
+ name: "send",
74
+ type: "(event) => void",
75
+ optional: true,
76
+ description:
77
+ 'Emits an SSE event to the client. Only present inside the agent tool loop (`caller: "tool"`). `undefined` elsewhere.',
78
+ },
79
+ {
80
+ name: "attachments",
81
+ type: "AgentChatAttachment[]",
82
+ optional: true,
83
+ description:
84
+ 'Files, images, and pasted text blocks submitted with the current agent turn. Populated only when `caller: "tool"`. `undefined` on all other surfaces.',
85
+ },
86
+ {
87
+ name: "signal",
88
+ type: "AbortSignal",
89
+ optional: true,
90
+ description:
91
+ 'Aborts when the run is soft-timed-out, cancelled, or the server shuts down. Populated only when `caller: "tool"`. Long-running actions can observe it to cancel early instead of waiting for the per-tool 60s hard timeout.',
92
+ },
93
+ {
94
+ name: "actionName",
95
+ type: "string",
96
+ optional: true,
97
+ description:
98
+ "The registry key of the action being called (e.g. `delete-recording`), set at each dispatch site so cross-cutting concerns like the audit log can attribute the call. `undefined` for direct programmatic `run()` calls that bypass the dispatcher.",
99
+ },
100
+ {
101
+ name: "threadId",
102
+ type: "string",
103
+ optional: true,
104
+ description:
105
+ 'The agent conversation thread that triggered this call. Populated only when `caller: "tool"`, so the audit log can link a mutation back to the exact agent run.',
106
+ },
107
+ {
108
+ name: "runId",
109
+ type: "string",
110
+ optional: true,
111
+ description:
112
+ 'The agent run attempt that triggered this call. Populated only when `caller: "tool"`.',
113
+ },
114
+ {
115
+ name: "turnId",
116
+ type: "string",
117
+ optional: true,
118
+ description:
119
+ 'The specific turn within that run that triggered this call. Populated only when `caller: "tool"`.',
120
+ },
121
+ {
122
+ name: "automation",
123
+ type: "ActionAutomationContext",
124
+ optional: true,
125
+ description:
126
+ 'Present only when `caller: "automation"`. Carries `triggerId`, `triggerName`, and an optional `policyId` for the event-triggered automation that dispatched this call.',
127
+ },
128
+ {
129
+ name: "networkProtocol",
130
+ type: '"a2a" | "mcp" | "provider-api"',
131
+ optional: true,
132
+ description:
133
+ "Which delegated-call protocol this request arrived over. Set only for those direct-dispatch paths.",
134
+ },
135
+ {
136
+ name: "networkId",
137
+ type: "string",
138
+ optional: true,
139
+ description:
140
+ "A correlation id for that delegated call, e.g. the A2A delegation JWT id.",
141
+ },
142
+ {
143
+ name: "networkPeer",
144
+ type: "string",
145
+ optional: true,
146
+ description: "The calling peer's identity for that delegated call.",
147
+ },
148
+ ],
149
+ },
150
+ ]}
151
+ returns={{
152
+ type: "Promise<TReturn> | TReturn",
153
+ description:
154
+ "The action's result, validated against `outputSchema` if one is set.",
155
+ }}
156
+ />
157
+
158
+ `run()` stays backward compatible: existing 1-argument handlers and handlers that only destructure `{ send }` continue to work unchanged.
159
+
160
+ ### The `caller` union {#caller}
161
+
162
+ `caller` is the union `"tool" | "http" | "frontend" | "cli" | "mcp" | "a2a" | "automation"`:
163
+
164
+ | `caller` | Set when… |
165
+ | -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
166
+ | `"tool"` | The in-app agent loop, a sub-agent or agent team, or natural-language cross-app A2A delegation, which drives the same agent loop, so its tool calls are `"tool"`. |
167
+ | `"frontend"` | A browser call via `useActionMutation()`, `useActionQuery()`, or `callAction()` (tagged with the `X-Agent-Native-Frontend: 1` header). |
168
+ | `"http"` | A bare programmatic `POST` or `GET` to `/_agent-native/actions/<name>` without the frontend marker. |
169
+ | `"cli"` | `pnpm action <name>` (the CLI runner). |
170
+ | `"mcp"` | An external agent over the MCP `tools/call` endpoint. |
171
+ | `"a2a"` | A direct HTTP call to `/_agent-native/actions/<name>` carrying a signed A2A delegation token. This is an explicitly exposed, cross-app dispatch, distinct from the natural-language `"tool"` path above. |
172
+ | `"automation"` | An event-triggered automation dispatched from a stored workspace trigger. `ctx.automation` carries the trigger lineage. See [Automations](/docs/automations). |
173
+
174
+ ## What's next
175
+
176
+ - [**Access & Authorization**](/docs/actions-access-control) — the `ctx.userEmail`/`ctx.orgId` scoping pattern this context enables
177
+ - [**Defining Actions**](/docs/actions-defining) — `defineAction()` anatomy and HTTP config
178
+ - [**Other Surfaces**](/docs/actions-other-surfaces) — how CLI, A2A, MCP, and automation callers set `caller`
179
+ - [**Audit Log**](/docs/audit-log) — how `threadId`/`runId`/`turnId` link a mutation back to its agent run
180
+ - [**Automations**](/docs/automations) — the `ctx.automation` trigger lineage
@@ -591,7 +591,7 @@ tool-result metadata. Start there when wiring an external agent into the chat.
591
591
 
592
592
  <Cards>
593
593
 
594
- ### [Actions](/docs/actions)
594
+ ### [Actions](/docs/actions-overview)
595
595
 
596
596
  Define the operation once. Every surface above calls the same one.
597
597
 
@@ -328,4 +328,4 @@ When a sub-agent is at or below the cap, the framework injects a line into its r
328
328
 
329
329
  - [**Agent Resources — Custom Agents**](/docs/agent-resources#custom-agents) — the profile format
330
330
  - [**A2A Protocol**](/docs/a2a-protocol) — when the "sub-agent" lives in a different app entirely
331
- - [**Actions**](/docs/actions) — the tools a sub-agent calls
331
+ - [**Actions**](/docs/actions-overview) — the tools a sub-agent calls
@@ -212,6 +212,6 @@ The audit exits non-zero if a required public surface is missing.
212
212
 
213
213
  ## What's next
214
214
 
215
- - [**Actions**](/docs/actions) — how to opt actions into the public agent protocol
215
+ - [**Actions**](/docs/actions-overview) — how to opt actions into the public agent protocol
216
216
  - [**MCP Protocol**](/docs/mcp-protocol) — the MCP surface that `publicMcp: true` enables
217
217
  - [**Deployment**](/docs/deployment) — where these static files are written during builds
@@ -182,7 +182,7 @@ Configure via environment:
182
182
 
183
183
  ## What's next
184
184
 
185
- - [**Actions**](/docs/actions) — the `defineAction` seam where capture happens
185
+ - [**Actions**](/docs/actions-overview) — the `defineAction` seam where capture happens
186
186
  - [**Human-in-the-Loop Approvals**](/docs/human-approval) — gated actions, recorded as `denied`
187
187
  - [**Security & Data Scoping**](/docs/security) — the ownership model audit reads reuse
188
188
  - [**Observability**](/docs/observability) — agent-run telemetry (the other "what happened")
@@ -119,5 +119,5 @@ See [Zapier REST Hook triggers](https://docs.zapier.com/integrations/build/hook-
119
119
 
120
120
  - [**Automations**](/docs/automations#web-request) — the ad-hoc `web-request` tool for one-off outbound HTTP, the lighter-weight sibling to a configured connector
121
121
  - [**Messaging**](/docs/messaging) — reaching the agent from Slack, email, Telegram, and WhatsApp, the queue-and-processor pattern this page's callbacks reuse
122
- - [**Actions**](/docs/actions) — `defineAction`, `needsApproval`, and the action surface `createInvokeAutomationWorkflowAction` builds on
122
+ - [**Actions**](/docs/actions-overview) — `defineAction`, `needsApproval`, and the action surface `createInvokeAutomationWorkflowAction` builds on
123
123
  - [**Security**](/docs/security) — `${keys.NAME}` secret substitution and the credential-scoping model this runtime relies on
@@ -450,7 +450,7 @@ for the full `plan.commented` payload reference and all four plan events.
450
450
  ## What's next
451
451
 
452
452
  - [**Recurring Jobs**](/docs/recurring-jobs) — legacy compatibility and advanced scheduled-job fields
453
- - [**Actions**](/docs/actions) — automations can call any registered action via the agent loop
453
+ - [**Actions**](/docs/actions-overview) — automations can call any registered action via the agent loop
454
454
  - [**Workflow Connectors**](/docs/automation-connectors) — pre-configured n8n/Zapier-style workflow invocation, for when ad-hoc `web-request` isn't a strict enough contract
455
455
  - [**Security**](/docs/security) — input validation and secret handling
456
456
  - [**Events and Automations**](/docs/template-plan-automations) — the Plan event reference and automation recipes
@@ -124,5 +124,5 @@ A new curated blueprint under an existing kind needs no code — but if you crea
124
124
  ## What's next
125
125
 
126
126
  - [**Sandbox Adapters**](/docs/sandbox-adapters) — the seam the `add sandbox docker` blueprint targets
127
- - [**Actions**](/docs/actions) — the single source of truth every blueprint builds on
127
+ - [**Actions**](/docs/actions-overview) — the single source of truth every blueprint builds on
128
128
  - [**External Agents**](/docs/external-agents) — connecting the coding agent you pipe blueprints into
@@ -169,4 +169,4 @@ CLI adapters use `node:child_process`, which does not exist on edge/worker runti
169
169
  ## What's next
170
170
 
171
171
  - [**Adapters**](/docs/sandbox-adapters) — the canonical guide to both adapter seams.
172
- - [**Actions**](/docs/actions) — the action surface CLI adapters are usually wrapped in.
172
+ - [**Actions**](/docs/actions-overview) — the action surface CLI adapters are usually wrapped in.
@@ -37,7 +37,7 @@ The user experience is as follows:
37
37
 
38
38
  1. The user picks **Offer a refund**, which causes `sendDraftRequest()` to send the prompt and ticket context to the agent.
39
39
 
40
- 1. The agent calls the `draft-ticket-reply` [action](/docs/actions), and the drafted reply appears in the reply composer.
40
+ 1. The agent calls the `draft-ticket-reply` [action](/docs/actions-overview), and the drafted reply appears in the reply composer.
41
41
 
42
42
  ## askUserQuestion(opts) {#ask-user-question}
43
43
 
@@ -5,7 +5,7 @@ description: "The action hooks app/ uses to read, write, and stay live-synced wi
5
5
 
6
6
  # Data & Sync
7
7
 
8
- The primary way to read and write app data from client application is through [action](/docs/actions) hooks. By embedding requests into actions, both your client and agent can interact with your application in the same way.
8
+ The primary way to read and write app data from client application is through [action](/docs/actions-overview) hooks. By embedding requests into actions, both your client and agent can interact with your application in the same way.
9
9
 
10
10
  In the example below, a ticket is assigned to the current user manually through a dropdown, and then through the chat agent. Both the UI and agent access the same action.
11
11
 
@@ -426,7 +426,7 @@ For normal CRUD, prefer `useActionQuery()` and `useActionMutation()`. Mutating a
426
426
 
427
427
  - [**Overview**](/docs/client-overview) — the `app/` and `public/` directory layout this page's hooks live in
428
428
  - [**Agent Chat**](/docs/client-agent-chat) — sending prompts and staging context for the agent
429
- - [**Actions**](/docs/actions) — the `defineAction` surface behind every hook on this page
429
+ - [**Actions**](/docs/actions-overview) — the `defineAction` surface behind every hook on this page
430
430
  - [**Advanced**](/docs/client-advanced) — direct `application_state` access
431
431
  - [**Sync Internals**](/docs/client-sync-internals) — syncing a raw `useQuery` with `useChangeVersion`
432
432
  - [**Real-Time Sync**](/docs/key-concepts#polling-sync) — how `useDbSync` keeps the UI current
@@ -92,7 +92,7 @@ The one architectural difference from a typical frontend: this layer has no back
92
92
 
93
93
  ## Where the Client Fits {#role}
94
94
 
95
- Browser requests, the agent loop, and external API clients all resolve to the same actions and the same SQL database — there is no separate "app backend" this layer talks to that the agent can't also reach. Building a feature here means building a UI on top of an operation the agent already has, or defining a new action and getting a UI for it at the same time. See [Actions](/docs/actions) for the operation side of that contract.
95
+ Browser requests, the agent loop, and external API clients all resolve to the same actions and the same SQL database — there is no separate "app backend" this layer talks to that the agent can't also reach. Building a feature here means building a UI on top of an operation the agent already has, or defining a new action and getting a UI for it at the same time. See [Actions](/docs/actions-overview) for the operation side of that contract.
96
96
 
97
97
  This page covers the directories you build in and the pieces of the browser runtime nothing else documents (`root.tsx`, `public/`). The React hooks that connect your components to actions and to the agent live on their own focused pages:
98
98
 
@@ -201,6 +201,6 @@ import { cn } from "@agent-native/toolkit/utils";
201
201
  - [**Sync Internals**](/docs/client-sync-internals) — `useChangeVersion` for syncing a raw `useQuery`
202
202
  - [**Entry Points**](/docs/client-entry-points) — SSR bootstrap customization
203
203
  - [**Routing**](/docs/client-routing) — file-based pages, dynamic params, and navigation
204
- - [**Actions**](/docs/actions) — the `defineAction` surface behind every data hook
204
+ - [**Actions**](/docs/actions-overview) — the `defineAction` surface behind every data hook
205
205
  - [**Custom Design Systems**](/docs/custom-design-system) — swapping in your own component library via `app/design-system.ts`
206
206
  - [**Authentication**](/docs/authentication) — the session checks `AppProviders` runs on private paths
@@ -526,7 +526,7 @@ reasoning.
526
526
 
527
527
  - [**Drop-in Agent**](/docs/drop-in-agent) — mount `<AgentSidebar>` and `<AgentPanel>` with a tutorial-first walkthrough
528
528
  - [**Native Chat UI**](/docs/native-chat-ui) — the action result contract behind data widgets and custom renderers
529
- - [**Actions**](/docs/actions) — `defineAction()`, schemas, and the action surface these components call
529
+ - [**Actions**](/docs/actions-overview) — `defineAction()`, schemas, and the action surface these components call
530
530
  - [**Real-Time Collaboration**](/docs/real-time-collaboration) — the collab hooks and presence components in depth
531
531
  - [**Sharing**](/docs/sharing) — `<ShareButton>` and `<ShareDialog>` wiring for ownable resources
532
532
  - [**Toolkit piece: Toolkit UI Primitives**](/docs/toolkit-ui) — the shared shadcn-style building blocks and app-adapter pattern behind these exports
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: "Cross-App SSO"
3
- description: "Sign in once across every hosted agent-native app via identity federation with Dispatch as the identity authority — opt-in per app, reversible with a single env var."
3
+ description: "Sign in once across every hosted agent-native app via identity federation with Dispatch as the identity authority. Canonical hosted clients are enabled by exact origin; self-hosted apps opt in with one env var."
4
4
  ---
5
5
 
6
6
  # Cross-App SSO
@@ -233,16 +233,20 @@ trust boundary.
233
233
 
234
234
  5. **App mints a normal local session.** From here on the user has an ordinary local session in that app's own store — every existing access check, org scoping, and action guard works exactly as before. The federation only happened at the front door.
235
235
 
236
- ### Opting in {#opt-in}
236
+ ### Hosted and self-hosted behavior {#opt-in}
237
237
 
238
- An app's ordinary web sign-in participates **only** when this environment variable is set on its deployment:
238
+ Canonical hosted client apps use Dispatch automatically when their deployment has
239
+ one of the exact registered `*.agent-native.com` origins. Dispatch is the
240
+ identity authority, not a client, so it never federates to itself. Self-hosted
241
+ apps remain opt-in and must set this environment variable on their deployment:
239
242
 
240
243
  ```bash
241
244
  AGENT_NATIVE_IDENTITY_HUB_URL=https://dispatch.agent-native.com
242
245
  ```
243
246
 
244
- - **Set** → the app shows a **"Sign in with Agent-Native"** option that runs the flow above. Direct local login (email/password, Google) still works alongside it.
245
- - **Unset (default)** → **zero behavior change.** The app authenticates exactly as it did before; the federation code path is dormant. There is no schema change and nothing to migrate, so flipping the variable on or off is fully reversible at any time.
247
+ - **Canonical hosted client** → the app shows a **"Sign in with Agent-Native"** option that runs the flow above. Direct local login (email/password, Google) still works alongside it.
248
+ - **Self-hosted with the variable set** → the app shows the same option, using the configured Dispatch instance.
249
+ - **Self-hosted with the variable unset** → **zero behavior change.** The app authenticates exactly as it did before; the federation code path is dormant. There is no schema change and nothing to migrate.
246
250
 
247
251
  ## Security {#security}
248
252
 
@@ -262,7 +266,7 @@ The whole model rests on a few deliberately small guarantees:
262
266
  accept a user id, role, org membership, or any privileged state from the
263
267
  wire — it derives everything locally from the matched account.
264
268
  - **Additive-only identity writes.** Linking either reuses an existing same-email account untouched or inserts a new one. No update, rename, repoint, or delete of identity rows ever happens on this path.
265
- - **Off by default.** With `AGENT_NATIVE_IDENTITY_HUB_URL` unset, ordinary browser federation is inert. The separately gated packaged Desktop path is described below.
269
+ - **Exact-origin trust.** Only the registered canonical hosted client origins get the implicit hosted default. Self-hosted and custom origins remain opt-in through `AGENT_NATIVE_IDENTITY_HUB_URL`; the separately gated packaged Desktop path is described below.
266
270
 
267
271
  <Callout id="doc-block-18qhl3m" tone="success">
268
272
 
@@ -345,8 +349,8 @@ flag controls whether Desktop may begin the ceremony; it does not authorize a
345
349
  user or weaken nonce, signature, origin, callback, app-binding, cookie,
346
350
  revocation, or credential-custody checks. With the flag Off or unavailable,
347
351
  Desktop leaves ordinary per-app sign-in, sign-out, and Settings unchanged.
348
- Canonical hosted apps recognize the packaged Desktop request without requiring
349
- `AGENT_NATIVE_IDENTITY_HUB_URL` on every deployment; ordinary web browsers and
352
+ Canonical hosted apps recognize the packaged Desktop request and ordinary web
353
+ browsers without requiring `AGENT_NATIVE_IDENTITY_HUB_URL` on every deployment;
350
354
  self-hosted apps still require that explicit configuration.
351
355
  Stable Desktop builds do not initialize the broker until a later release is
352
356
  separately approved.
@@ -379,19 +383,22 @@ Without an exact custom registry entry, a self-hosted Dispatch can only issue co
379
383
 
380
384
  ## Canary rollout runbook {#canary-rollout}
381
385
 
382
- Cutover and rollback are **a single environment variable per app deployment**. Roll out one app at a time, verify, then expand. Do not set the variable on every app at once.
386
+ Canonical hosted clients take the default after the release ships. Self-hosted
387
+ and custom deployments still use **a single environment variable per app**.
388
+ Roll out one deployment at a time, verify, then expand.
383
389
 
384
- **1. Deploy the code — no behavior change.**
385
- Ship the release to every app with `AGENT_NATIVE_IDENTITY_HUB_URL` **unset everywhere**. Confirm normal logins still work on a couple of apps.
390
+ **1. Deploy the code and verify a canonical hosted client.**
391
+ Ship the release to the canonical apps. Confirm normal logins still work on a
392
+ couple of apps and that the new sign-in option appears on a client app.
386
393
 
387
- **2. Enable the canary on ONE app at a time.**
394
+ **2. Enable self-hosted/custom apps one at a time.**
388
395
  Set, on one deployment only:
389
396
 
390
397
  ```bash
391
398
  AGENT_NATIVE_IDENTITY_HUB_URL=https://dispatch.agent-native.com
392
399
  ```
393
400
 
394
- Leave every other app's environment unset. Redeploy/restart so it picks up the variable.
401
+ Leave every other self-hosted app's environment unset. Redeploy/restart so it picks up the variable.
395
402
 
396
403
  **3. Verify the canary (checklist).**
397
404
 
@@ -402,13 +409,13 @@ Leave every other app's environment unset. Redeploy/restart so it picks up the v
402
409
  - **App data is intact** — your existing records, settings, and org scoping are exactly as they were.
403
410
  - **Existing direct logins still work** — email/password and Google sign-in continue to function alongside SSO.
404
411
 
405
- If any check fails, go straight to step 4 (rollback) — it is instant and data-safe.
412
+ If any check fails, go straight to step 5 (rollback) — it is instant and data-safe.
406
413
 
407
414
  **4. Expand app-by-app.**
408
- Once one app is verified, repeat steps 2–3 for the next app — setting `AGENT_NATIVE_IDENTITY_HUB_URL` on one deployment at a time. Never batch-enable.
415
+ Once one deployment is verified, repeat steps 2–3 for the next one. Never batch-enable custom origins.
409
416
 
410
- **5. Rollback = unset the env var on that app's deploy.**
411
- To revert any app, **remove `AGENT_NATIVE_IDENTITY_HUB_URL` from that app's environment and redeploy/restart it.** The app immediately returns to its prior auth behavior. There is **no data change to undo** — identity rows were only ever added, and unsetting the variable simply makes the federation path dormant again. Each app's cutover and rollback are independent and reversible.
417
+ **5. Rollback.**
418
+ For a self-hosted app, **remove `AGENT_NATIVE_IDENTITY_HUB_URL` from its environment and redeploy/restart it.** A canonical hosted client can be rolled back by reverting the release or disabling the hosted client path. There is **no data change to undo** — identity rows were only ever added. Each deployment's cutover and rollback are independent and reversible.
412
419
 
413
420
  <Callout tone="info">
414
421
 
@@ -14,7 +14,7 @@ search: "data program emit rows schema providerFetch dashboard panel program sou
14
14
 
15
15
  A **data program** is a named, stored, agent-authored JS script that fetches, joins, filters, or aggregates data — provider APIs via `providerFetch` / `providerFetchAll` / `providerSearchAll`, app data via `appAction`, or Resources-backed workspace files — and calls `emit(rows, schema)` exactly once with the result. The result is cached in SQL and any chart/table component can render it, refreshed on a policy you choose instead of on every page view.
16
16
 
17
- It ships automatically wherever [`run-code`](/docs/actions) is available — there is nothing to mount or configure per app. If your app already has run-code enabled, `save-data-program`, `preview-data-program`, `run-data-program`, `list-data-programs`, `get-data-program`, and `delete-data-program` are already registered actions.
17
+ It ships automatically wherever [`run-code`](/docs/actions-overview) is available — there is nothing to mount or configure per app. If your app already has run-code enabled, `save-data-program`, `preview-data-program`, `run-data-program`, `list-data-programs`, `get-data-program`, and `delete-data-program` are already registered actions.
18
18
 
19
19
  <Diagram id="doc-block-dp-overview" title="From ad-hoc query to live panel" summary="A run-code script becomes a stored program once it calls emit(); any dashboard panel can bind to it and the cache/refresh policy takes over from there.">
20
20
 
@@ -330,6 +330,6 @@ Any app can implement the same adoption for its own dashboards/tables: call `run
330
330
  ## What's next {#whats-next}
331
331
 
332
332
  - [Extensions](/docs/extensions) — the sandboxed mini-app primitive data programs share a security posture and sharing model with, but with a UI of its own.
333
- - [Actions](/docs/actions) — the `run-code` conventions and sandbox globals (`providerFetch`, `appAction`, etc.) data programs are built on.
333
+ - [Actions](/docs/actions-overview) — the `run-code` conventions and sandbox globals (`providerFetch`, `appAction`, etc.) data programs are built on.
334
334
  - [Sharing & Privacy](/docs/sharing) — the org-internal, never-public sharing model data programs use.
335
335
  - [Security](/docs/security) — the framework's credential-handling and access-scoping invariants.