@agent-native/core 0.63.0 → 0.63.2

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 (134) hide show
  1. package/dist/agent/harness/ai-sdk-adapter.d.ts +44 -0
  2. package/dist/agent/harness/ai-sdk-adapter.d.ts.map +1 -1
  3. package/dist/agent/harness/ai-sdk-adapter.js +120 -1
  4. package/dist/agent/harness/ai-sdk-adapter.js.map +1 -1
  5. package/dist/agent/harness/index.d.ts +1 -1
  6. package/dist/agent/harness/index.d.ts.map +1 -1
  7. package/dist/agent/harness/index.js.map +1 -1
  8. package/dist/cli/code-agent-executor.js +1 -1
  9. package/dist/cli/code-agent-executor.js.map +1 -1
  10. package/dist/cli/create.js +1 -1
  11. package/dist/cli/create.js.map +1 -1
  12. package/dist/client/NewWorkspaceAppFlow.js +1 -1
  13. package/dist/client/NewWorkspaceAppFlow.js.map +1 -1
  14. package/dist/client/blocks/library/AnnotatedCodeBlock.d.ts.map +1 -1
  15. package/dist/client/blocks/library/AnnotatedCodeBlock.js +29 -10
  16. package/dist/client/blocks/library/AnnotatedCodeBlock.js.map +1 -1
  17. package/dist/client/blocks/library/DiffBlock.d.ts.map +1 -1
  18. package/dist/client/blocks/library/DiffBlock.js +48 -20
  19. package/dist/client/blocks/library/DiffBlock.js.map +1 -1
  20. package/dist/client/blocks/library/diagram.d.ts.map +1 -1
  21. package/dist/client/blocks/library/diagram.js +14 -3
  22. package/dist/client/blocks/library/diagram.js.map +1 -1
  23. package/dist/client/blocks/library/wireframe.d.ts.map +1 -1
  24. package/dist/client/blocks/library/wireframe.js +14 -3
  25. package/dist/client/blocks/library/wireframe.js.map +1 -1
  26. package/dist/client/blocks/types.d.ts +5 -0
  27. package/dist/client/blocks/types.d.ts.map +1 -1
  28. package/dist/client/blocks/types.js.map +1 -1
  29. package/dist/client/chat/index.d.ts +2 -1
  30. package/dist/client/chat/index.d.ts.map +1 -1
  31. package/dist/client/chat/index.js +2 -1
  32. package/dist/client/chat/index.js.map +1 -1
  33. package/dist/client/chat-view-transition.d.ts +17 -0
  34. package/dist/client/chat-view-transition.d.ts.map +1 -1
  35. package/dist/client/chat-view-transition.js +46 -0
  36. package/dist/client/chat-view-transition.js.map +1 -1
  37. package/dist/client/index.d.ts +2 -1
  38. package/dist/client/index.d.ts.map +1 -1
  39. package/dist/client/index.js +2 -1
  40. package/dist/client/index.js.map +1 -1
  41. package/dist/client/use-agent-chat-home-handoff.d.ts +27 -0
  42. package/dist/client/use-agent-chat-home-handoff.d.ts.map +1 -0
  43. package/dist/client/use-agent-chat-home-handoff.js +120 -0
  44. package/dist/client/use-agent-chat-home-handoff.js.map +1 -0
  45. package/dist/index.d.ts +1 -1
  46. package/dist/index.d.ts.map +1 -1
  47. package/dist/index.js +3 -1
  48. package/dist/index.js.map +1 -1
  49. package/dist/server/action-discovery.d.ts.map +1 -1
  50. package/dist/server/action-discovery.js +24 -2
  51. package/dist/server/action-discovery.js.map +1 -1
  52. package/dist/server/deep-link.d.ts +2 -2
  53. package/dist/server/deep-link.d.ts.map +1 -1
  54. package/dist/server/deep-link.js +2 -2
  55. package/dist/server/deep-link.js.map +1 -1
  56. package/dist/styles/agent-native.css +2 -6
  57. package/dist/tailwind.preset.d.ts.map +1 -1
  58. package/dist/tailwind.preset.js +8 -1
  59. package/dist/tailwind.preset.js.map +1 -1
  60. package/dist/templates/default/package.json +1 -0
  61. package/dist/templates/headless/AGENTS.md +3 -0
  62. package/dist/templates/headless/DEVELOPING.md +4 -0
  63. package/dist/templates/headless/actions/run.ts +6 -0
  64. package/dist/templates/workspace-root/README.md +4 -4
  65. package/docs/content/actions.md +32 -42
  66. package/docs/content/agent-surfaces.md +105 -84
  67. package/docs/content/agent-teams.md +2 -14
  68. package/docs/content/agent-web-surfaces.md +4 -4
  69. package/docs/content/authentication.md +40 -24
  70. package/docs/content/automations.md +18 -36
  71. package/docs/content/blueprint-installer.md +3 -0
  72. package/docs/content/cli-adapters.md +24 -168
  73. package/docs/content/client.md +11 -77
  74. package/docs/content/cloneable-saas.md +1 -1
  75. package/docs/content/code-agents-ui.md +44 -0
  76. package/docs/content/components.md +10 -23
  77. package/docs/content/context-awareness.md +3 -3
  78. package/docs/content/creating-templates.md +20 -18
  79. package/docs/content/database.md +1 -1
  80. package/docs/content/deployment.md +5 -37
  81. package/docs/content/dispatch.md +17 -28
  82. package/docs/content/drop-in-agent.md +24 -111
  83. package/docs/content/durable-resume.md +4 -0
  84. package/docs/content/embedding-sdk.md +141 -135
  85. package/docs/content/evals.md +3 -3
  86. package/docs/content/extensions.md +1 -1
  87. package/docs/content/external-agents.md +35 -61
  88. package/docs/content/faq.md +5 -5
  89. package/docs/content/frames.md +13 -4
  90. package/docs/content/getting-started.md +96 -142
  91. package/docs/content/harness-agents.md +53 -9
  92. package/docs/content/human-approval.md +1 -1
  93. package/docs/content/key-concepts.md +14 -99
  94. package/docs/content/local-file-mode.md +2 -2
  95. package/docs/content/mcp-apps.md +9 -2
  96. package/docs/content/mcp-clients.md +8 -3
  97. package/docs/content/mcp-protocol.md +11 -29
  98. package/docs/content/messaging.md +1 -1
  99. package/docs/content/migration-workbench.md +14 -175
  100. package/docs/content/multi-app-workspace.md +1 -1
  101. package/docs/content/multi-tenancy.md +18 -47
  102. package/docs/content/native-chat-ui.md +15 -12
  103. package/docs/content/observability.md +16 -4
  104. package/docs/content/observational-memory.md +1 -1
  105. package/docs/content/pure-agent-apps.md +17 -124
  106. package/docs/content/real-time-collaboration.md +14 -14
  107. package/docs/content/routing.md +71 -0
  108. package/docs/content/sandbox-adapters.md +78 -4
  109. package/docs/content/security.md +59 -39
  110. package/docs/content/server.md +16 -8
  111. package/docs/content/sharing.md +1 -6
  112. package/docs/content/skills-guide.md +3 -1
  113. package/docs/content/template-analytics.md +1 -1
  114. package/docs/content/template-assets.md +12 -3
  115. package/docs/content/template-brain.md +64 -72
  116. package/docs/content/template-chat.md +32 -4
  117. package/docs/content/template-clips.md +35 -4
  118. package/docs/content/template-design.md +19 -3
  119. package/docs/content/template-dispatch.md +9 -0
  120. package/docs/content/template-forms.md +15 -10
  121. package/docs/content/template-plan.md +13 -5
  122. package/docs/content/template-slides.md +14 -14
  123. package/docs/content/template-videos.md +10 -12
  124. package/docs/content/tracking.md +66 -55
  125. package/docs/content/using-your-agent.md +6 -16
  126. package/docs/content/what-is-agent-native.md +5 -11
  127. package/docs/content/workspace-management.md +2 -2
  128. package/docs/content/workspace.md +20 -160
  129. package/package.json +6 -2
  130. package/src/templates/default/package.json +1 -0
  131. package/src/templates/headless/AGENTS.md +3 -0
  132. package/src/templates/headless/DEVELOPING.md +4 -0
  133. package/src/templates/headless/actions/run.ts +6 -0
  134. package/src/templates/workspace-root/README.md +4 -4
@@ -5,137 +5,31 @@ description: "Embed an Agent-Native sidecar into an existing SaaS app with page
5
5
 
6
6
  # Embedding SDK
7
7
 
8
- ## Installation {#installation}
9
-
10
- ```bash
11
- pnpm add @agent-native/embedding
12
- ```
13
-
14
- Subpath exports from `@agent-native/embedding`:
15
-
16
- | Import path | What it provides |
17
- | ---------------------------------- | --------------------------------------------------------------------------------------- |
18
- | `@agent-native/embedding` | `EmbeddedApp` picker component, `getA2AUrl`, `getMcpUrl`, `sendMessage` (streaming A2A) |
19
- | `@agent-native/embedding/react` | React-specific hooks and components |
20
- | `@agent-native/embedding/bridge` | `announceEmbeddedAppReady`, `sendEmbeddedAppMessage` used inside the embedded app |
21
- | `@agent-native/embedding/agent` | Agent endpoint helpers |
22
- | `@agent-native/embedding/protocol` | Protocol types |
23
-
24
- For the **batteries-included embedded mode** (full sidecar with actions, database, and agent chat), install `@agent-native/core` on the server and use `createAgentNativeEmbeddedPlugin`:
8
+ Embed Agent-Native into an existing product: keep your SaaS app, add a durable
9
+ agent sidecar, and let that agent see and operate on the page the user is
10
+ already using. If you are still deciding between headless agents, rich chat, an
11
+ embedded sidecar, or a full app, start with
12
+ [Agent Surfaces](/docs/agent-surfaces).
13
+
14
+ ## Start here: the batteries-included plugin {#batteries-included}
15
+
16
+ For most SaaS hosts, **use the full embedded runtime** — the server plugin
17
+ `createAgentNativeEmbeddedPlugin` plus the `<AgentNativeEmbedded>` client
18
+ component. This is the recommended default: it reuses the entire framework
19
+ (actions, SQL-backed app state, extensions, browser-session tools) and gives the
20
+ agent the ability to see and operate on the page the user is already using.
21
+
22
+ The host mounts Agent-Native server routes into its existing app, passes its
23
+ logged-in user to Agent-Native, and renders the React sidebar in the product UI.
24
+ Agent-Native uses the host deployment, host session, and the configured
25
+ `DATABASE_URL` to manage its own framework tables: chat threads, settings,
26
+ application state, extensions, extension data, secrets, browser sessions, and
27
+ action routes.
25
28
 
26
29
  ```bash
27
30
  pnpm add @agent-native/core
28
31
  ```
29
32
 
30
- ## Choosing a mode {#choosing-a-mode}
31
-
32
- This page is for embedding Agent-Native into an existing product. If you are
33
- still deciding between headless actions, rich chat, an embedded sidecar, or a
34
- full app, start with [Agent Surfaces](/docs/agent-surfaces).
35
-
36
- | Mode | Use it when | Package |
37
- | ------------------------------------ | --------------------------------------------------------------------------------------------------- | -------------------------------------------------------- |
38
- | **EmbeddedApp picker** | Launching a full Agent-Native app as a focused iframe (asset picker, form builder, approval panel). | `@agent-native/embedding` |
39
- | **Batteries-included server plugin** | Adding a durable agent sidecar with its own database and actions to your existing SaaS app. | `@agent-native/core` + `createAgentNativeEmbeddedPlugin` |
40
- | **`<AgentNative>` host component** | Client-side: rendering the agent sidecar panel in your React app shell with live page context. | `@agent-native/core/client` |
41
- | **Extension slot** | Embedding a sandboxed mini-app (extension) inside an existing agent-native template. | `@agent-native/core` extensions system |
42
-
43
- The CLAW-style host bridge described below uses the batteries-included plugin (server) + the `<AgentNativeEmbedded>` component (client). It is the recommended default when you want the agent to see and operate on the page the user is already using.
44
-
45
- ---
46
-
47
- The embedding SDK is for the CLAW-style shape: keep your existing SaaS app, add a durable agent sidecar, and let that agent see and operate on the page the user is already using.
48
-
49
- Use it when you want an assistant that can:
50
-
51
- - Read current page context: route, selected resource, highlighted text, active filters, user/org, and app-specific state.
52
- - Call durable backend actions, MCP tools, or integration-backed tools from the sidecar app.
53
- - Ask the host app to navigate, refresh data, remount a view, or open a resource after durable work completes.
54
- - Run as an iframe/sidebar now, while leaving room for a no-iframe package or hosted template later.
55
-
56
- ## Embedded App And Picker Mode
57
-
58
- Use `@agent-native/embedding` when the host product wants to launch a complete
59
- Agent-Native app as a focused iframe surface: an asset picker, asset generator,
60
- form builder, calendar slot picker, approval panel, or any other task-specific
61
- workflow. This is intentionally smaller than the sidecar host bridge below: the
62
- iframe announces readiness, the host can send named messages, and the embedded
63
- app can emit domain events such as `chooseAsset` or `close`.
64
-
65
- ```tsx
66
- import { EmbeddedApp } from "@agent-native/embedding";
67
-
68
- export function AssetPickerDialog({ close }) {
69
- return (
70
- <EmbeddedApp
71
- url="https://assets.agent-native.com/picker"
72
- className="h-full w-full"
73
- onLoad={(ref) => {
74
- ref.postMessage("configure", {
75
- prompt: "Editorial blog hero",
76
- aspectRatio: "16:9",
77
- });
78
- }}
79
- onMessage={(name, payload) => {
80
- if (name === "chooseAsset") {
81
- const asset = payload as { url: string; altText?: string };
82
- insertAsset(asset.url, asset.altText);
83
- close();
84
- }
85
- if (name === "close") close();
86
- }}
87
- />
88
- );
89
- }
90
- ```
91
-
92
- Inside the embedded app, use the browser bridge to announce readiness and send
93
- events back to the host:
94
-
95
- ```ts
96
- import {
97
- announceEmbeddedAppReady,
98
- sendEmbeddedAppMessage,
99
- } from "@agent-native/embedding/bridge";
100
-
101
- announceEmbeddedAppReady({ app: "assets", mode: "picker" });
102
- sendEmbeddedAppMessage("chooseAsset", {
103
- url: asset.previewUrl,
104
- assetId: asset.id,
105
- altText: asset.altText,
106
- });
107
- ```
108
-
109
- Assets also emits `chooseImage` as a compatibility alias for older image-picker
110
- hosts; new integrations should listen for `chooseAsset`.
111
-
112
- For hosted first-party apps, enable Cross-App SSO with Dispatch as the identity
113
- hub so `content.agent-native.com` and `assets.agent-native.com` link users by
114
- verified email. Iframe launches should still use short-lived, route-scoped
115
- embed sessions when they need third-party-cookie resilience; normal app cookies
116
- are not a complete embed auth story on their own.
117
-
118
- The same package includes agent endpoint helpers for protocol discovery and
119
- streaming text over A2A:
120
-
121
- ```ts
122
- import { getA2AUrl, getMcpUrl, sendMessage } from "@agent-native/embedding";
123
-
124
- getMcpUrl("https://assets.agent-native.com");
125
- getA2AUrl("https://assets.agent-native.com");
126
-
127
- for await (const chunk of sendMessage(
128
- "https://assets.agent-native.com",
129
- "Generate a blog hero",
130
- )) {
131
- append(chunk);
132
- }
133
- ```
134
-
135
- ## Batteries-Included Embedded Mode
136
-
137
- For most SaaS hosts, use the full embedded runtime. The host mounts Agent-Native server routes into its existing app, passes its logged-in user to Agent-Native, and then renders the React sidebar/surface in the product UI. Agent-Native uses the host deployment, host session, and the configured `DATABASE_URL` to manage its own framework tables: chat threads, settings, application state, extensions, extension data, secrets, browser sessions, and action routes.
138
-
139
33
  On the server:
140
34
 
141
35
  ```ts
@@ -238,7 +132,115 @@ export default createAgentNativeEmbeddedPlugin({
238
132
 
239
133
  Using the host product's main `DATABASE_URL` is supported, but make that an explicit choice. Agent-Native creates framework tables such as `settings`, `application_state`, `tools`, `tool_data`, browser-session tables, secrets, chat threads, and related indexes. A dedicated DB/schema avoids table-name collisions, keeps ownership of managed tables clear, and makes backup/retention policy easier to reason about. If you intentionally share the host DB, review existing table names first and treat Agent-Native tables as framework-owned.
240
134
 
241
- ## Host App
135
+ ## Other modes {#other-modes}
136
+
137
+ The batteries-included plugin above is the happy path. Reach for one of these
138
+ only when it fits your situation better:
139
+
140
+ | Mode | Use it when | Package |
141
+ | ------------------------------- | --------------------------------------------------------------------------------------------------- | ------------------------------------------ |
142
+ | **EmbeddedApp picker** | Launching a full Agent-Native app as a focused iframe (asset picker, form builder, approval panel). | `@agent-native/embedding` |
143
+ | **`<AgentNative>` host bridge** | Standalone sidecar apps or cross-origin iframes that wire page context and client actions manually. | `@agent-native/core/client` |
144
+ | **Portable extensions** | Letting host users build sandboxed mini-apps when the SaaS already owns extension storage/approval. | `@agent-native/core/client` extension slot |
145
+
146
+ The lower-level `@agent-native/embedding` package exposes:
147
+
148
+ | Import path | What it provides |
149
+ | ---------------------------------- | --------------------------------------------------------------------------------------- |
150
+ | `@agent-native/embedding` | `EmbeddedApp` picker component, `getA2AUrl`, `getMcpUrl`, `sendMessage` (streaming A2A) |
151
+ | `@agent-native/embedding/react` | React-specific hooks and components |
152
+ | `@agent-native/embedding/bridge` | `announceEmbeddedAppReady`, `sendEmbeddedAppMessage` — used inside the embedded app |
153
+ | `@agent-native/embedding/agent` | Agent endpoint helpers |
154
+ | `@agent-native/embedding/protocol` | Protocol types |
155
+
156
+ ```bash
157
+ pnpm add @agent-native/embedding
158
+ ```
159
+
160
+ ### Embedded App And Picker Mode
161
+
162
+ Use `@agent-native/embedding` when the host product wants to launch a complete
163
+ Agent-Native app as a focused iframe surface: an asset picker, asset generator,
164
+ form builder, calendar slot picker, approval panel, or any other task-specific
165
+ workflow. This is intentionally smaller than the sidecar host bridge below: the
166
+ iframe announces readiness, the host can send named messages, and the embedded
167
+ app can emit domain events such as `chooseAsset` or `close`.
168
+
169
+ ```tsx
170
+ import { EmbeddedApp } from "@agent-native/embedding";
171
+
172
+ export function AssetPickerDialog({ close }) {
173
+ return (
174
+ <EmbeddedApp
175
+ url="https://assets.agent-native.com/picker"
176
+ className="h-full w-full"
177
+ onLoad={(ref) => {
178
+ ref.postMessage("configure", {
179
+ prompt: "Editorial blog hero",
180
+ aspectRatio: "16:9",
181
+ });
182
+ }}
183
+ onMessage={(name, payload) => {
184
+ if (name === "chooseAsset") {
185
+ const asset = payload as { url: string; altText?: string };
186
+ insertAsset(asset.url, asset.altText);
187
+ close();
188
+ }
189
+ if (name === "close") close();
190
+ }}
191
+ />
192
+ );
193
+ }
194
+ ```
195
+
196
+ Inside the embedded app, use the browser bridge to announce readiness and send
197
+ events back to the host:
198
+
199
+ ```ts
200
+ import {
201
+ announceEmbeddedAppReady,
202
+ sendEmbeddedAppMessage,
203
+ } from "@agent-native/embedding/bridge";
204
+
205
+ announceEmbeddedAppReady({ app: "assets", mode: "picker" });
206
+ sendEmbeddedAppMessage("chooseAsset", {
207
+ url: asset.previewUrl,
208
+ assetId: asset.id,
209
+ altText: asset.altText,
210
+ });
211
+ ```
212
+
213
+ Assets also emits `chooseImage` as a compatibility alias for older image-picker
214
+ hosts; new integrations should listen for `chooseAsset`.
215
+
216
+ For hosted first-party apps, enable Cross-App SSO with Dispatch as the identity
217
+ hub so `content.agent-native.com` and `assets.agent-native.com` link users by
218
+ verified email. Iframe launches should still use short-lived, route-scoped
219
+ embed sessions when they need third-party-cookie resilience; normal app cookies
220
+ are not a complete embed auth story on their own.
221
+
222
+ The same package includes agent endpoint helpers for protocol discovery and
223
+ streaming text over A2A:
224
+
225
+ ```ts
226
+ import { getA2AUrl, getMcpUrl, sendMessage } from "@agent-native/embedding";
227
+
228
+ getMcpUrl("https://assets.agent-native.com");
229
+ getA2AUrl("https://assets.agent-native.com");
230
+
231
+ for await (const chunk of sendMessage(
232
+ "https://assets.agent-native.com",
233
+ "Generate a blog hero",
234
+ )) {
235
+ append(chunk);
236
+ }
237
+ ```
238
+
239
+ ### Host App (`<AgentNative>` host bridge)
240
+
241
+ > The batteries-included plugin above is preferred. Use this lower-level bridge
242
+ > only for standalone sidecar apps or cross-origin iframes where you wire page
243
+ > context and client actions yourself.
242
244
 
243
245
  For standalone sidecar apps or cross-origin iframes, use the lower-level `<AgentNative />`. It renders the iframe sidecar and wires page context, live client actions, and host refresh/navigation commands in one place:
244
246
 
@@ -319,7 +321,7 @@ Use `screen={false}` if you only want explicit semantic context. Use `screen={{
319
321
 
320
322
  For non-React hosts, call `createAgentNativeHostBridge()` directly and pass the same `getContext`, `actions`, and `commands` options.
321
323
 
322
- ## Iframe Side
324
+ ### Iframe Side
323
325
 
324
326
  Inside the Agent-Native sidecar, use the frame helpers to request host context, discover live browser-session actions, run them, or ask the host to do UI work. Always pass the expected `hostOrigin` in production:
325
327
 
@@ -360,7 +362,7 @@ const hostTools = createAgentNativeHostTools({
360
362
  });
361
363
  ```
362
364
 
363
- ## Server-Mediated Tool Bridge
365
+ ### Server-Mediated Tool Bridge
364
366
 
365
367
  For a CLAW-style coworker, the iframe can also register its live browser tab with the sidecar backend. The agent then gets normal backend tools that enqueue a request, the iframe claims it, the host page executes it, and the backend returns the result to the agent.
366
368
 
@@ -395,7 +397,7 @@ The framework mounts `/_agent-native/browser-sessions` automatically. Once the b
395
397
 
396
398
  This is the bridge to use when the agent is running on the backend, in Slack/Telegram/email, or as an A2A callee but still needs to touch the user's current browser tab when it is open. If the browser is closed, backend actions should still handle durable work and the browser-session tools will report that no active tab is connected.
397
399
 
398
- ## Actions
400
+ ### Actions
399
401
 
400
402
  There are two action classes:
401
403
 
@@ -408,7 +410,11 @@ Backend actions should be the default for anything that must survive refreshes,
408
410
 
409
411
  Client actions are a live bridge to one browser tab. The host advertises them with `source: "client"` and `availability: "browser-session"`, and the sidecar should treat that manifest as temporary. Re-list actions when route or selection changes, and fall back to backend actions when the tab disappears.
410
412
 
411
- ## Portable Extensions
413
+ ### Portable Extensions
414
+
415
+ > Prefer the batteries-included plugin when you want Agent-Native to manage
416
+ > extension definitions, approval, storage, and agent-created extensions. Use
417
+ > the portable slot below only when the SaaS already owns those concerns.
412
418
 
413
419
  The SDK also supports user-defined extensions: sandboxed Alpine.js mini-apps that a host SaaS can render in named slots. Use this when the customer wants to build their own small panels, calculators, dashboards, or workflow helpers against the same action/context surface that the agent uses.
414
420
 
@@ -526,13 +532,13 @@ Security model:
526
532
  - Risky actions should set `destructive` or `requiresApproval` so the host can show an approval flow.
527
533
  - Treat user-authored extension HTML as untrusted. Review marketplace installs, log action usage, and scope backend storage by user/org.
528
534
 
529
- ## Sessions And Tabs
535
+ ### Sessions And Tabs
530
536
 
531
537
  The host bridge is scoped to one iframe/host-window pair. If the same user opens multiple tabs, each tab has its own `session`, context, selection, client actions, and pending command responses. Do not assume a client action discovered in one tab can run in another tab, or that it will still exist after navigation.
532
538
 
533
539
  For multi-tab products, keep durable state in SQL/backend actions and use client actions only for the tab-local parts: focusing a row, copying visible editor state, selecting a canvas element, or refreshing the current React Query cache. Include enough `route`, `resource`, and `selection` context for the sidecar to decide whether the current tab is the right place to run a browser-session action.
534
540
 
535
- ## Command Model
541
+ ### Command Model
536
542
 
537
543
  Built-in command names are deliberately app-shaped, not database-shaped:
538
544
 
@@ -547,7 +553,7 @@ Built-in command names are deliberately app-shaped, not database-shaped:
547
553
 
548
554
  If no handler is provided, safe defaults dispatch browser events like `agentNative:refresh-data` and `agentNative:remount-view`. `requestApproval` has no default handler; register one before relying on it.
549
555
 
550
- ## Approval Guidance
556
+ ### Approval Guidance
551
557
 
552
558
  Mark risky client actions with `destructive: true` in their manifest and require host approval before running operations that delete, publish, send, charge, invite, share, or otherwise affect users outside the current view. Backend actions should enforce their own authorization and approval checks too; host approval is useful UX, not the security boundary.
553
559
 
@@ -557,7 +563,7 @@ Prefer this shape:
557
563
  - Host command opens an approval UI or focuses the affected resource.
558
564
  - Client action handles only the live UI step that cannot happen on the backend.
559
565
 
560
- ## Runtime Integration
566
+ ### Runtime Integration
561
567
 
562
568
  Use `createAgentNativeHostTools()` inside the sidecar iframe when your agent runtime accepts plain tool descriptors. It returns four framework-agnostic tools:
563
569
 
@@ -1,9 +1,9 @@
1
1
  ---
2
- title: "Evals (CI Gate)"
2
+ title: "CI Eval Gate"
3
3
  description: "Write *.eval.ts test cases that run the real agent against fixed inputs, score the output with composable scorers, and gate CI/deploys on a threshold."
4
4
  ---
5
5
 
6
- # Evals (CI Gate)
6
+ # CI Eval Gate
7
7
 
8
8
  Evals are a first-class testing primitive: you declare a prompt plus the behavior you expect, the runner **actually runs the agent loop** against that input, scores the output with composable scorers, and exits non-zero if any case scores below its threshold. That non-zero exit makes `agent-native eval` a drop-in CI deploy gate.
9
9
 
@@ -73,7 +73,7 @@ Imported from `@agent-native/core/eval`:
73
73
 
74
74
  `createScorer` builds a scorer from a Mastra-style 4-step pipeline. Only `generateScore` is required:
75
75
 
76
- ```txt
76
+ ```text
77
77
  preprocess(run) → x transform the run/output (optional)
78
78
  analyze(x, ctx) → analysis plain JS OR an LLM judge (optional)
79
79
  generateScore(a) → 0..1 REQUIRED, normalized
@@ -228,7 +228,7 @@ For deeper detail on slots — how to declare them in your template, how the con
228
228
 
229
229
  Local File Mode lets a workspace keep extensions in the repo:
230
230
 
231
- ```txt
231
+ ```text
232
232
  extensions/
233
233
  doc-status/
234
234
  extension.json
@@ -6,6 +6,15 @@ search: "Claude ChatGPT Claude Code Codex Cursor Claude Cowork MCP Apps agent-na
6
6
 
7
7
  # External Agents
8
8
 
9
+ **This page: connect an external agent or MCP host to your app.** Use it when Claude, ChatGPT, Codex, Cursor, Claude Cowork, or another MCP-compatible host should drive a hosted agent-native app and round-trip the result back into the running UI.
10
+
11
+ | If you want to… | Read |
12
+ | ------------------------------------------------------------ | ---------------------------------- |
13
+ | Connect an external agent/host to your app | **This page** — External Agents |
14
+ | Give your agent more tools (consume other MCP servers) | [MCP Clients](/docs/mcp-clients) |
15
+ | Build inline UIs that render in Claude/ChatGPT | [MCP Apps](/docs/mcp-apps) |
16
+ | Lower-level MCP server reference (auth, tools, custom mount) | [MCP Protocol](/docs/mcp-protocol) |
17
+
9
18
  An agent-native app is reachable by any MCP-compatible host — Claude, Claude Desktop, Claude Code, ChatGPT custom MCP apps, Codex, Cursor, Claude Cowork, VS Code GitHub Copilot, Goose, Postman, MCPJam, and future clients that implement the standard. External agents are great at producing artifacts (a draft, an event, a dashboard) but they often live in a terminal or another app. Without a bridge, the user gets a wall of JSON and has to go find the thing.
10
19
 
11
20
  The external-agent bridge closes the loop. First you connect your own agent to a **hosted** app — either by pasting the app's remote MCP URL into a chat host like Claude or ChatGPT, or by running the developer CLI flow for local coding agents. Then the agent does the work over MCP and hands the user either an inline **MCP App** UI in compatible hosts or a single **"Open in &lt;app&gt; →"** link that opens the real app focused on exactly what was produced. It reuses the existing `navigate` / `application_state` contract the UI already drains every 2s (see [Context Awareness](/docs/context-awareness)) — there is no second navigation mechanism.
@@ -225,55 +234,33 @@ When the client requests no explicit scope, the app grants all three so the conn
225
234
 
226
235
  ## Catalog tiers {#catalog-tiers}
227
236
 
228
- The MCP server serves a **compact catalog by default to every caller**
229
- hosted connectors (ChatGPT, Claude), code clients (Claude Code, Cursor,
230
- Codex), and the local CLI/stdio proxy alike. The full action surface is served
231
- only on an explicit opt-in. The catalog is never inferred from the client name
232
- or user-agent.
237
+ This is the canonical explanation of MCP catalog tiers other pages link here.
238
+
239
+ The MCP server serves a **compact catalog by default to every caller** — hosted connectors (ChatGPT, Claude), code clients (Claude Code, Cursor, Codex), and the local CLI/stdio proxy alike. The full action surface is served only on explicit opt-in. The catalog is never inferred from the client name or user-agent.
233
240
 
234
241
  ### Compact / connector tier (default) {#connector-tier}
235
242
 
236
- By default every connected agent sees a small, curated catalog: the
237
- template-declared allow-list of app-level actions (create/get/update plan,
238
- sharing, upload, navigate, automations, `tool-search`) plus the builtin
239
- cross-app tools (`list_apps`, `open_app`, `ask_app`, `create_embed_session`).
240
- Tools outside the list `db-exec`, `db-patch`, `seed-*`, the extension suite,
241
- browser-session tools, agent-engine management, and context-xray tools — are
242
- not advertised, and calls to them are rejected with "Unknown tool" unless the
243
- caller has opted into the full catalog.
244
-
245
- This keeps the context window of every connected external agent small (~20–30
246
- tools vs. ~105) and removes footguns that are only safe for single-tenant local
247
- development. The connector tier is active **whenever a template declares a
248
- `connectorCatalog`** — it is no longer gated behind an environment variable.
249
-
250
- `tool-search` is always available (including in the compact catalog), so a
251
- compacted client can still reach any tool on demand. Call it with **no query**
252
- to get the full menu of tool names plus one-line descriptions (cheap — no
253
- schemas), or with a query to get ranked matches with parameter summaries. This
254
- is how a compacted client discovers and loads any full-surface tool when it
255
- needs one.
243
+ By default every connected agent sees a small, curated catalog (~20–30 tools vs. ~105 in the full surface):
244
+
245
+ - **Template-declared app actions** — the safe app-level allow-list. For Plan that is `create-visual-plan`, `get-visual-plan`, `share-resource`, `navigate`, `tool-search`, and similar.
246
+ - **Builtin cross-app tools** `list_apps`, `open_app`, `ask_app`, `create_embed_session`.
247
+ - **`tool-search`** is always present, so anything outside the list stays reachable on demand (see below).
248
+
249
+ Tools outside the list — for example `db-exec`, `seed-*`, the extension suite, browser-session tools, and context-xray tools — are not advertised, and calls to them are rejected with "Unknown tool" unless the caller has opted into the full catalog. This keeps each connected agent's context window small and removes footguns that are only safe for single-tenant local development. The connector tier is active **whenever a template declares a `connectorCatalog`** — it is not gated behind an environment variable.
250
+
251
+ `tool-search` works two ways: call it with **no query** for the full menu of tool names plus one-line descriptions (cheap, no schemas), or with a query for ranked matches with parameter summaries. That is how a compacted client discovers and loads any full-surface tool when it needs one.
256
252
 
257
253
  ### Full tier (explicit opt-in only) {#full-tier}
258
254
 
259
- The complete ~105-tool action surface is served only when a caller explicitly
260
- opts in. There are two ways to opt in:
255
+ The complete ~105-tool action surface is served only on explicit opt-in, two ways:
261
256
 
262
- - Mint a token with `--full-catalog`, which embeds a `catalog_scope: "full"`
263
- claim in the JWT:
257
+ - **Per token** — mint with `--full-catalog`, which embeds a `catalog_scope: "full"` claim in the JWT. Subsequent requests bypass the compact filter for that token:
264
258
 
265
259
  ```bash
266
260
  npx @agent-native/core@latest connect https://plan.agent-native.com --client codex --full-catalog
267
261
  ```
268
262
 
269
- Swap `--client codex` for another target client when needed. On subsequent
270
- requests the MCP server bypasses the compact-catalog filter for that token
271
- and serves the complete action surface.
272
-
273
- - Set `AGENT_NATIVE_MCP_FULL_CATALOG=1` (process env on the server) as a
274
- deployment-wide override that serves the full surface to all callers. Use it
275
- for single-tenant hosted instances that want the full surface without
276
- per-token opt-up.
263
+ - **Per deployment** — set `AGENT_NATIVE_MCP_FULL_CATALOG=1` (server process env) to serve the full surface to all callers. Use it for single-tenant hosted instances that want the full surface without per-token opt-up.
277
264
 
278
265
  ### Template declaration {#catalog-declaration}
279
266
 
@@ -339,26 +326,9 @@ entries and `resources/read` content, not on the tool descriptor.
339
326
 
340
327
  For ChatGPT/Claude-style OAuth app hosts, the discovery surface is compact by default: `tools/list` and `resources/list` advertise the generic `open_app` embed path instead of every action-specific MCP App resource (see [Catalog tiers](#catalog-tiers)). Mark an individual action with `mcpApp.compactCatalog: true` only when it truly needs to stay visible in chat-host discovery.
341
328
 
342
- That makes the same app surface available to every compatible host rather than building per-client shims. The current official MCP Apps client list includes Claude, Claude Desktop, VS Code GitHub Copilot, Goose, Postman, MCPJam, ChatGPT, and Cursor; host support still varies by plan, release channel, and client version, so check the [MCP extension support matrix](https://modelcontextprotocol.io/extensions/client-matrix). ChatGPT custom MCP apps are available through developer mode for Business and Enterprise/Edu workspaces on ChatGPT web; see OpenAI's [developer mode and MCP apps](https://help.openai.com/en/articles/12584461-developer-mode-and-full-mcp-apps-in-chatgpt-beta) notes.
343
-
344
- Claude Code, Codex, and other CLI/code-editor clients still receive the same
345
- resources and metadata when they support MCP Apps, but treat them as link-out
346
- hosts unless you have verified inline iframe rendering in that exact surface.
347
- The deep link remains the reliable fallback when a host chooses not to render an
348
- iframe. In practice, every agent-native app should be authored with both: MCP
349
- Apps for inline review/edit in capable hosts, and `link` for universal
350
- round-tripping back to the full app. Human-selection tools can add a paste-back
351
- step to that fallback: for example, the Assets picker opens from the fallback
352
- link, lets the user choose media in the browser, then copies a handoff summary
353
- that the user pastes back into the chat.
354
-
355
- Claude and ChatGPT can cache tool and resource metadata for an existing custom
356
- connector. After changing MCP App metadata, verify with a fresh tool call; if
357
- the host still uses the old descriptor, reconnect the Claude connector or
358
- rescan/review the ChatGPT connector so it refreshes the catalog.
359
- If Claude logs a warning about `_meta.ui.csp` or `_meta.ui.permissions` living
360
- on the tool descriptor after a deploy, that connector is using stale metadata:
361
- delete/reconnect the Claude connector and start a fresh chat.
329
+ That makes the same app surface available to every compatible host rather than building per-client shims. Which hosts render MCP Apps inline (and the connector-cache gotcha after metadata changes) lives in [MCP Apps Client support and caching](/docs/mcp-apps#client-support) that page is the single home for the client matrix.
330
+
331
+ In practice, every agent-native app should be authored with both: MCP Apps for inline review/edit in capable hosts, and `link` for universal round-tripping back to the full app. CLI/code-editor clients that do not render an iframe fall back to the deep link. Human-selection tools can add a paste-back step to that fallback: for example, the Assets picker opens from the fallback link, lets the user choose media in the browser, then copies a handoff summary that the user pastes back into the chat.
362
332
 
363
333
  ### First-class MCP App bridge {#mcp-app-bridge}
364
334
 
@@ -395,9 +365,13 @@ Every allow-listed template that produces or lists a navigable resource ships a
395
365
  - **Content** — `pull-document` is the GET + `publicAgent` ingest action: it flushes any open live collaborative session to SQL first so the external agent ingests exactly what the user sees, then surfaces a deep link to the document.
396
366
  - **Brain** — `ask-brain` / `search-everything` return a cited answer plus a deep link to the underlying knowledge/capture, so a terminal agent's lookup links straight back into the source in the running app.
397
367
 
398
- ## Authoring: the `link` builder {#link-builder}
368
+ ## Authoring (for template authors) {#authoring}
369
+
370
+ Everything above is for **end users** connecting and using an app. The rest of this page is for **template authors** wiring an app up to be a good external-agent citizen: the `link` builder, the optional MCP Apps UI, the `/_agent-native/open` route internals, and ingest actions.
371
+
372
+ ### The `link` builder {#link-builder}
399
373
 
400
- This section is for template authors. `defineAction` accepts an optional `link` builder. When set, every MCP/A2A result for that tool auto-appends a markdown `[label →](absoluteUrl)` block and a structured `_meta["agent-native/openLink"] = { label, view, webUrl, desktopUrl, vscodeUrl }`. `tools/list` adds `annotations["agent-native/producesOpenLink"]` and a description suffix so the external agent knows the tool yields an openable link and should surface it.
374
+ `defineAction` accepts an optional `link` builder. When set, every MCP/A2A result for that tool auto-appends a markdown `[label →](absoluteUrl)` block and a structured `_meta["agent-native/openLink"] = { label, view, webUrl, desktopUrl, vscodeUrl }`. `tools/list` adds `annotations["agent-native/producesOpenLink"]` and a description suffix so the external agent knows the tool yields an openable link and should surface it.
401
375
 
402
376
  Build the URL with `buildDeepLink(...)` — it is the single source of truth for the open-route format. Never hand-format the `/_agent-native/open` URL.
403
377
 
@@ -432,7 +406,7 @@ export default defineAction({
432
406
 
433
407
  List/search actions point at a record-focused view the same way — e.g. calendar's `create-event` returns `buildDeepLink({ app: "calendar", view: "calendar", params: { eventId, date } })` with label `"Open event in Calendar"`. Calendar draft actions use the same pattern: `manage-event-draft` returns `buildDeepLink({ app: "calendar", view: "calendar", to: "/", params: { eventDraftId, calendarDraft, date } })` with label `"Review invite in Calendar"`, so external agents can hand back a direct draft-review link without creating the event first.
434
408
 
435
- ## Authoring: optional MCP Apps UI {#mcp-apps}
409
+ ### Optional MCP Apps UI {#mcp-apps}
436
410
 
437
411
  Actions can advertise an inline UI resource with `mcpApp` for hosts that support the MCP Apps extension. Use `embedRoute({ title, openLabel, path })` as the convenience wrapper, or assign `embedApp(...)` to `mcpApp.resource` directly. Every MCP App is a real React route, not a separate plain-HTML widget. Always keep the `link` builder — CLI-only hosts, older clients, and non-MCP-Apps hosts use it as the fallback.
438
412
 
@@ -442,7 +416,7 @@ See [MCP Apps](/docs/mcp-apps) for the full authoring guide — `embedRoute` vs
442
416
 
443
417
  The `link` builder is **pure and synchronous — no I/O, no awaits**. It runs best-effort: a throw, `null`, or `undefined` is swallowed and **never** fails the tool call. It only reads the call's `args` and `result`; it must not query the DB, read app-state, or call other actions. Return `null` when there's nothing to open.
444
418
 
445
- `buildDeepLink({ app, view, params?, to?, compose? })` returns the app-relative path `/_agent-native/open?app=…&view=…&<recordId>=…`. The MCP layer turns that into an absolute web URL (`toAbsoluteOpenUrl`, using the request origin), a desktop `agentnative://open?…` URL (`toDesktopOpenUrl`), and a VS Code extension URL (`toVsCodeOpenUrl`) for `vscode://builderio.agent-native/open?url=…`; the markdown link uses the desktop URL when the client signals `target: "desktop"`.
419
+ `buildDeepLink({ app, view, params?, to?, compose? })` returns the app-relative path `/_agent-native/open?app=…&view=…&<recordId>=…`. The MCP layer turns that into an absolute web URL (`toAbsoluteOpenUrl`, using the request origin), a desktop `agentnative://open?…` URL (`toDesktopOpenUrl`), and a VS Code extension URL (`toVsCodeOpenUrl`) for `vscode://builder.agent-native/open?url=…`; the markdown link uses the desktop URL when the client signals `target: "desktop"`.
446
420
 
447
421
  ### The `/_agent-native/open` route {#open-route}
448
422
 
@@ -11,7 +11,7 @@ Common questions about agent-native, organized from "I'm just looking" to "I'm w
11
11
 
12
12
  ### What is agent-native? {#what-is-agent-native}
13
13
 
14
- Agent-native is a framework for building apps where the AI agent and the product surface around it are equal partners. That surface can start as one headless action, grow into rich chat, or become a full UI. The invariant is that agents and humans share the same actions, database, and state. See [What Is Agent-Native?](/docs/what-is-agent-native) for the full explanation.
14
+ Agent-native is a framework for building apps where the AI agent and the product surface around it are equal partners. That surface can start as a headless agent with one custom action, grow into rich chat, or become a full UI. The invariant is that agents and humans share the same actions, database, and state. See [What Is Agent-Native?](/docs/what-is-agent-native) for the full explanation.
15
15
 
16
16
  ### Who is this for? {#who-is-this-for}
17
17
 
@@ -26,7 +26,7 @@ Agent-native is for people who want a real app and an AI agent to work from the
26
26
 
27
27
  ### How is this different from adding AI to an existing app? {#how-is-this-different}
28
28
 
29
- Most apps bolt AI on as an afterthought an autocomplete here, a chat sidebar there. The AI can't actually _do_ things in the app. In an agent-native app, the agent is a first-class citizen. It can create emails, schedule events, build forms, generate slides, and modify the app's own code. The architecture is designed for this from the ground up.
29
+ Most apps bolt AI on as an afterthought that can't actually _do_ things in the app. In an agent-native app the agent is a first-class citizen that shares the same actions, database, and state as the UI, so it can do anything the buttons can — and modify the app's own code. See [What Is Agent-Native?](/docs/what-is-agent-native#the-ladder).
30
30
 
31
31
  ### Is it open source? {#is-this-open-source}
32
32
 
@@ -117,12 +117,12 @@ Anywhere. The server runs on Nitro, which compiles to any deployment target: Nod
117
117
 
118
118
  ### Why SSE plus polling instead of WebSockets? {#why-polling-not-websockets}
119
119
 
120
- SSE gives same-process writes an immediate path to the browser without requiring a bidirectional socket server. Polling remains the fallback because it works in every deployment environment — including serverless, edge, and container platforms where persistent connections may not be available. The fallback uses a lightweight version counter; when changes are detected, React Query caches are invalidated and components re-render.
120
+ SSE gives same-process writes an immediate path to the browser, and a lightweight version-counter poll remains the fallback because it works in every deployment environment — including serverless and edge, where persistent sockets may not be available. See [Key Concepts Live sync](/docs/key-concepts#polling-sync).
121
121
 
122
122
  ### Why can't the UI call an LLM directly? {#why-no-inline-llm-calls}
123
123
 
124
- AI is non-deterministic you need conversation flow to give feedback and iterate, not one-shot buttons. The agent has your full codebase, instructions, skills, and conversation history. An inline LLM call has none of that. Plus, routing everything through the agent means the app can be driven from Slack, Telegram, or another agent via [A2A](/docs/a2a-protocol) — not just the UI.
124
+ AI is non-deterministic, so you need conversation flow to give feedback and iterate not one-shot buttons and the agent already has your codebase, instructions, skills, and history that an inline call lacks. Routing everything through the agent is also what lets the app be driven from Slack, Telegram, or another agent. See [Key Concepts — Agent chat bridge](/docs/key-concepts#agent-chat-bridge).
125
125
 
126
126
  ### Why is this a framework and not a library? {#why-framework-not-library}
127
127
 
128
- The shared database, polling sync, actions system, and application state all need to work together as a cohesive architecture. A library could give you pieces, but agent-native requires that the agent and UI are wired together from the ground up. Multiple agents need to be able to communicate, the UI needs to react to agent changes instantly, and the agent needs to understand what the user is looking at. That's an architecture, not a utility.
128
+ The shared database, live sync, actions system, and application state only work because they're wired together from the ground up the UI reacts to agent changes instantly, agents communicate, and the agent understands what the user is looking at. A library gives you pieces; this is an architecture. See [Key Concepts](/docs/key-concepts).
@@ -51,10 +51,8 @@ The panel runs in one of two tool modes:
51
51
  [Agent-Native Code UI](/docs/code-agents-ui).
52
52
 
53
53
  "Code mode" is the agent-capability toggle — distinct from environment dev mode
54
- (`NODE_ENV` / Vite). For back-compat the underlying `AGENT_MODE` env var, the
55
- `/_agent-native/agent-chat/mode` endpoint (whose payload still uses `devMode`),
56
- and the `agent-chat.mode` settings key are unchanged. The client hook is
57
- `useCodeMode()` (the older `useDevMode()` remains as a deprecated alias).
54
+ (`NODE_ENV` / Vite). The client hook is `useCodeMode()`. (See
55
+ [Compatibility notes](#compatibility) for the back-compat aliases.)
58
56
 
59
57
  In the local dev frame, the settings cog toggles between these modes. Switching
60
58
  off Code mode hides the frame's own sidebar and shows the app's in-app agent
@@ -128,3 +126,14 @@ pnpm dev
128
126
  ```
129
127
 
130
128
  The local dev frame (the private `@agent-native/frame` package in the framework repo) is an internal tooling package that is not published to npm. It loads the active app's dev server in an iframe and mounts the embedded panel beside it, selecting the app via the `app` query param. The integrated CLI terminal requires Agent Native Desktop, which provides the local code and PTY access the terminal needs; without it, the panel shows the chat surface and prompts you to open Desktop to use the CLI.
129
+
130
+ ## Compatibility notes {#compatibility}
131
+
132
+ The "Code mode" concept was previously named "dev mode," so a few back-compat
133
+ names persist. You can ignore these unless you are maintaining older integration
134
+ code:
135
+
136
+ - The underlying `AGENT_MODE` env var, the `/_agent-native/agent-chat/mode`
137
+ endpoint (whose payload key is still `devMode`), and the `agent-chat.mode`
138
+ settings key are unchanged.
139
+ - `useDevMode()` remains as a deprecated alias for `useCodeMode()`.