@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
@@ -1 +1 @@
1
- {"version":3,"file":"tailwind.preset.js","sourceRoot":"","sources":["../src/tailwind.preset.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Config } from \"tailwindcss\";\n\n/**\n * @deprecated Legacy Tailwind v3 preset.\n *\n * The framework has moved to Tailwind v4. Templates should now use the shared\n * stylesheet from CSS instead of a `tailwind.config.ts`:\n *\n * // app/global.css\n * @import \"tailwindcss\";\n * @import \"@agent-native/core/styles/agent-native.css\";\n *\n * No `tailwind.config.ts` or `postcss.config.js` is needed. The\n * `@tailwindcss/vite` plugin is auto-injected by `defineConfig()`.\n *\n * This export is kept only for third-party templates still on the v3 PostCSS pipeline.\n */\nimport { join, dirname } from \"path\";\nimport { fileURLToPath } from \"url\";\n\n// Scan @agent-native/core's dist/client for Tailwind classes used in\n// core components (AgentPanel, AssistantChat, etc.)\nconst thisDir =\n typeof __dirname !== \"undefined\"\n ? __dirname\n : dirname(fileURLToPath(import.meta.url));\n\n/**\n * Glob pattern that matches all core client component files.\n * Templates MUST include this in their `content` array — Tailwind v3\n * does NOT merge `content` from presets, so the preset alone isn't enough.\n *\n * Usage:\n * import preset, { coreContentGlob } from \"@agent-native/core/tailwind\";\n * export default { presets: [preset], content: [\"./app/**\\/*.{ts,tsx}\", coreContentGlob] };\n */\nexport const coreContentGlob = join(thisDir, \"client\", \"**/*.{js,mjs}\");\n\n// Cast to `any` for the inner config — Tailwind v4 ships stricter Config types\n// than v3 (e.g. `darkMode: [\"class\"]` is v3-only). This file exists only to\n// keep third-party v3 setups working until they migrate.\nconst preset = {\n darkMode: [\"class\"],\n content: [coreContentGlob],\n prefix: \"\",\n theme: {\n container: {\n center: true,\n padding: \"2rem\",\n screens: {\n \"2xl\": \"1400px\",\n },\n },\n extend: {\n colors: {\n border: \"hsl(var(--border))\",\n input: \"hsl(var(--input))\",\n ring: \"hsl(var(--ring))\",\n background: \"hsl(var(--background))\",\n foreground: \"hsl(var(--foreground))\",\n primary: {\n DEFAULT: \"hsl(var(--primary))\",\n foreground: \"hsl(var(--primary-foreground))\",\n },\n secondary: {\n DEFAULT: \"hsl(var(--secondary))\",\n foreground: \"hsl(var(--secondary-foreground))\",\n },\n destructive: {\n DEFAULT: \"hsl(var(--destructive))\",\n foreground: \"hsl(var(--destructive-foreground))\",\n },\n muted: {\n DEFAULT: \"hsl(var(--muted))\",\n foreground: \"hsl(var(--muted-foreground))\",\n },\n accent: {\n DEFAULT: \"hsl(var(--accent))\",\n foreground: \"hsl(var(--accent-foreground))\",\n },\n popover: {\n DEFAULT: \"hsl(var(--popover))\",\n foreground: \"hsl(var(--popover-foreground))\",\n },\n card: {\n DEFAULT: \"hsl(var(--card))\",\n foreground: \"hsl(var(--card-foreground))\",\n },\n sidebar: {\n DEFAULT: \"hsl(var(--sidebar-background))\",\n foreground: \"hsl(var(--sidebar-foreground))\",\n primary: \"hsl(var(--sidebar-primary))\",\n \"primary-foreground\": \"hsl(var(--sidebar-primary-foreground))\",\n accent: \"hsl(var(--sidebar-accent))\",\n \"accent-foreground\": \"hsl(var(--sidebar-accent-foreground))\",\n border: \"hsl(var(--sidebar-border))\",\n ring: \"hsl(var(--sidebar-ring))\",\n },\n },\n borderRadius: {\n lg: \"var(--radius)\",\n md: \"calc(var(--radius) - 2px)\",\n sm: \"calc(var(--radius) - 4px)\",\n },\n keyframes: {\n \"accordion-down\": {\n from: { height: \"0\" },\n to: { height: \"var(--radix-accordion-content-height)\" },\n },\n \"accordion-up\": {\n from: { height: \"var(--radix-accordion-content-height)\" },\n to: { height: \"0\" },\n },\n },\n animation: {\n \"accordion-down\": \"accordion-down 0.2s ease-out\",\n \"accordion-up\": \"accordion-up 0.2s ease-out\",\n },\n },\n },\n plugins: [\n // tailwindcss-animate is v3-only and is no longer a peer dep — guard the require.\n (() => {\n try {\n return require(\"tailwindcss-animate\");\n } catch {\n return null;\n }\n })(),\n require(\"@tailwindcss/typography\"),\n ].filter(Boolean),\n};\n\nexport default preset as unknown as Config;\n"]}
1
+ {"version":3,"file":"tailwind.preset.js","sourceRoot":"","sources":["../src/tailwind.preset.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Config } from \"tailwindcss\";\n\n/**\n * @deprecated Legacy Tailwind v3 preset.\n *\n * The framework has moved to Tailwind v4. Templates should now use the shared\n * stylesheet from CSS instead of a `tailwind.config.ts`:\n *\n * // app/global.css\n * @import \"tailwindcss\";\n * @import \"@agent-native/core/styles/agent-native.css\";\n *\n * No `tailwind.config.ts` or `postcss.config.js` is needed. The\n * `@tailwindcss/vite` plugin is auto-injected by `defineConfig()`.\n *\n * This export is kept only for third-party templates still on the v3 PostCSS pipeline.\n */\nimport { join, dirname } from \"path\";\nimport { fileURLToPath } from \"url\";\n\n// Scan @agent-native/core's dist/client for Tailwind classes used in\n// core components (AgentPanel, AssistantChat, etc.)\nconst thisDir =\n typeof __dirname !== \"undefined\"\n ? __dirname\n : dirname(fileURLToPath(import.meta.url));\n\n/**\n * Glob pattern that matches all core client component files.\n * Templates MUST include this in their `content` array — Tailwind v3\n * does NOT merge `content` from presets, so the preset alone isn't enough.\n *\n * Usage:\n * import preset, { coreContentGlob } from \"@agent-native/core/tailwind\";\n * export default { presets: [preset], content: [\"./app/**\\/*.{ts,tsx}\", coreContentGlob] };\n */\nexport const coreContentGlob = join(thisDir, \"client\", \"**/*.{js,mjs}\");\n\n// Cast to `any` for the inner config — Tailwind v4 ships stricter Config types\n// than v3 (e.g. `darkMode: [\"class\"]` is v3-only). This file exists only to\n// keep third-party v3 setups working until they migrate.\nconst preset = {\n darkMode: [\"class\"],\n content: [coreContentGlob],\n prefix: \"\",\n theme: {\n container: {\n center: true,\n padding: \"2rem\",\n screens: {\n \"2xl\": \"1400px\",\n },\n },\n extend: {\n colors: {\n border: \"hsl(var(--border))\",\n input: \"hsl(var(--input))\",\n ring: \"hsl(var(--ring))\",\n background: \"hsl(var(--background))\",\n foreground: \"hsl(var(--foreground))\",\n primary: {\n DEFAULT: \"hsl(var(--primary))\",\n foreground: \"hsl(var(--primary-foreground))\",\n },\n secondary: {\n DEFAULT: \"hsl(var(--secondary))\",\n foreground: \"hsl(var(--secondary-foreground))\",\n },\n destructive: {\n DEFAULT: \"hsl(var(--destructive))\",\n foreground: \"hsl(var(--destructive-foreground))\",\n },\n muted: {\n DEFAULT: \"hsl(var(--muted))\",\n foreground: \"hsl(var(--muted-foreground))\",\n },\n accent: {\n DEFAULT: \"hsl(var(--accent))\",\n foreground: \"hsl(var(--accent-foreground))\",\n },\n popover: {\n DEFAULT: \"hsl(var(--popover))\",\n foreground: \"hsl(var(--popover-foreground))\",\n },\n card: {\n DEFAULT: \"hsl(var(--card))\",\n foreground: \"hsl(var(--card-foreground))\",\n },\n sidebar: {\n DEFAULT: \"hsl(var(--sidebar-background))\",\n foreground: \"hsl(var(--sidebar-foreground))\",\n primary: \"hsl(var(--sidebar-primary))\",\n \"primary-foreground\": \"hsl(var(--sidebar-primary-foreground))\",\n accent: \"hsl(var(--sidebar-accent))\",\n \"accent-foreground\": \"hsl(var(--sidebar-accent-foreground))\",\n border: \"hsl(var(--sidebar-border))\",\n ring: \"hsl(var(--sidebar-ring))\",\n },\n },\n borderRadius: {\n lg: \"var(--radius)\",\n md: \"calc(var(--radius) - 2px)\",\n sm: \"calc(var(--radius) - 4px)\",\n },\n keyframes: {\n \"accordion-down\": {\n from: { height: \"0\" },\n to: { height: \"var(--radix-accordion-content-height)\" },\n },\n \"accordion-up\": {\n from: { height: \"var(--radix-accordion-content-height)\" },\n to: { height: \"0\" },\n },\n },\n animation: {\n \"accordion-down\": \"accordion-down 0.2s ease-out\",\n \"accordion-up\": \"accordion-up 0.2s ease-out\",\n },\n },\n },\n plugins: [\n // tailwindcss-animate is v3-only and is no longer a peer dep — guard the require.\n (() => {\n try {\n return require(\"tailwindcss-animate\");\n } catch {\n return null;\n }\n })(),\n (() => {\n try {\n return require(\"@tailwindcss/typography\");\n } catch {\n return null;\n }\n })(),\n ].filter(Boolean),\n};\n\nexport default preset as unknown as Config;\n"]}
@@ -24,6 +24,7 @@
24
24
  "devDependencies": {
25
25
  "@react-router/dev": "^7.16.0",
26
26
  "@react-router/fs-routes": "^7.16.0",
27
+ "@tailwindcss/typography": "^0.5.20",
27
28
  "@tailwindcss/vite": "^4.1.18",
28
29
  "@tanstack/react-query": "^5.99.2",
29
30
  "@types/node": "^24.2.1",
@@ -9,6 +9,9 @@ This app is not stateless. The Agent Native runtime uses SQL-backed stores for a
9
9
  - Prefer actions in `actions/` for every app operation. Do not create REST wrappers around actions.
10
10
  - Keep action inputs validated with Zod and return structured data, not JSON strings.
11
11
  - Do not hardcode API keys, tokens, webhook URLs, private data, or credential-looking literals.
12
+ - `actions/run.ts` is the CLI dispatcher for `pnpm action ...`, not an app
13
+ action. Leave it in place and add callable primitives as separate
14
+ `actions/<name>.ts` files.
12
15
  - There is intentionally no `app/` UI shell in this scaffold. When you need a browser UI, use the Chat template as the UI on-ramp and keep `agent-native add` for integration blueprints.
13
16
 
14
17
  ## Framework Docs Lookup
@@ -7,6 +7,10 @@ pnpm install
7
7
  pnpm action hello --name Builder
8
8
  ```
9
9
 
10
+ `actions/run.ts` is only the shared CLI dispatcher that powers
11
+ `pnpm action <name>`. Add real agent-callable actions as separate files such as
12
+ `actions/hello.ts`.
13
+
10
14
  Then run the production app-agent loop against this folder:
11
15
 
12
16
  ```bash
@@ -1,3 +1,9 @@
1
+ /**
2
+ * CLI dispatcher for `pnpm action ...`.
3
+ *
4
+ * This file lives in actions/ so the Agent Native CLI can find it. It is skipped
5
+ * by action discovery and is not exposed as an agent tool.
6
+ */
1
7
  import { runScript } from "@agent-native/core/scripts";
2
8
 
3
9
  runScript();
@@ -103,15 +103,15 @@ authenticated org routes whenever possible.
103
103
  pnpm exec agent-native create crm --template=chat
104
104
  ```
105
105
 
106
- The CLI detects the workspace root and scaffolds a minimal chat app that already
106
+ The CLI detects the workspace root and scaffolds a minimal starter app that already
107
107
  depends on `@{{APP_NAME}}/shared`. Edit only the routes you care about;
108
108
  auth, org switching, skills, and instructions come from the shared package.
109
- Chat is only the source scaffold: the finished app should use its own name,
109
+ The source template is only a scaffold: the finished app should use its own name,
110
110
  home screen, navigation, package metadata, and manifest rather than leaving
111
- chat or new-app UI in place.
111
+ starter or new-app UI in place.
112
112
  If the request starts from Dispatch in production, Dispatch sends it to Builder
113
113
  branch creation; that branch should still add a new `apps/<app-id>` workspace
114
- app rather than adding files to `apps/chat`.
114
+ app rather than editing an existing app directory.
115
115
  Dispatch discovers ready apps from `apps/<app-id>/package.json`; there is no
116
116
  separate workspace app registry to edit. React Router apps must preserve
117
117
  `APP_BASE_PATH` / `VITE_APP_BASE_PATH` in `app/entry.client.tsx` via
@@ -19,6 +19,10 @@ One definition, seven consumers. This is rung 3 of the [ladder](/docs/what-is-ag
19
19
  If you are deciding whether to expose an operation headlessly, in chat, in an
20
20
  embedded sidecar, or as a full app screen, see [Agent Surfaces](/docs/agent-surfaces).
21
21
 
22
+ If the UI and agent both need to do something, reach for an action — not a custom
23
+ route. For when a route-shaped protocol _is_ the right call, see [Prefer Actions
24
+ For App Operations](/docs/server#actions-first).
25
+
22
26
  ## Start with one action {#hello-action}
23
27
 
24
28
  The primitive-first on-ramp is one action, not a template. In a headless
@@ -154,9 +158,22 @@ Every action the agent can see is a tool in the model's context window, and a lo
154
158
 
155
159
  A repo-level advisory helper, `node scripts/audit-template-actions.mjs [template ...]` (alias `pnpm actions:audit`), statically scans a template's `actions/` and flags likely UI-dead actions and redundant per-field clusters. It is advisory only (always exits 0, never fails CI) and uses conservative heuristics, so review its suggestions rather than treating them as errors.
156
160
 
157
- ### Agent tool exposure {#agent-tool}
161
+ ### Exposure flags {#exposure-flags}
162
+
163
+ Four flags control _who_ can invoke an action. All default to the permissive value, so you only set one to tighten a specific surface. This table is the glanceable summary; the subsections add the one detail each needs.
164
+
165
+ | Flag | Default | Restrictive value → who can still call | Typical use |
166
+ | --------------- | ------------- | --------------------------------------------------------------------------- | --------------------------------------------------------------- |
167
+ | `agentTool` | `true` | `false` → UI, HTTP, CLI only — **hidden from the model**, MCP, and A2A | UI-only / programmatic actions that shouldn't spend a tool slot |
168
+ | `toolCallable` | `true` | `false` → everything **except** the sandboxed extension iframe bridge (403) | Auth-adjacent ops (delete account, change org membership/roles) |
169
+ | `publicAgent` | off (private) | `{ expose: true }` → adds the action to **public** MCP/A2A/OpenAPI surfaces | Safe read/ingest tools reachable without authentication |
170
+ | `needsApproval` | `false` | `true` → the agent **pauses**; a human must approve the specific call | Consequential side effects (send email, charge a card, delete) |
158
171
 
159
- By default every action is exposed to the agent — the in-app assistant plus the app's MCP / A2A tool surfaces as a callable tool. For an action that only the frontend (or an HTTP / cron caller) needs, set `agentTool: false` to keep it behind the framework's auth + action surface while removing it from every agent tool list:
172
+ These are independent: `agentTool` controls the model's view, `toolCallable` controls only the extension iframe, `publicAgent` adds an opt-in public surface (public web routes never imply public tool exposure), and `needsApproval` gates execution after the call is made see [Human-in-the-loop approval](#needs-approval) below.
173
+
174
+ #### `agentTool` — hide from the model {#agent-tool}
175
+
176
+ By default every action is a callable agent tool. Set `agentTool: false` to keep it behind the framework's auth + action surface while removing it from every agent tool list — it stays callable from the UI (`useActionMutation` / `callAction`), CLI, and `/_agent-native/actions/<name>`:
160
177
 
161
178
  ```ts
162
179
  export default defineAction({
@@ -170,24 +187,11 @@ export default defineAction({
170
187
  });
171
188
  ```
172
189
 
173
- | Value | Behavior |
174
- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
175
- | `true` | Allow (same as undefined). Useful for documenting intent. |
176
- | `false` | **Hidden from the model entirely** — not in the agent's tool list, MCP, or A2A. Still callable from the UI (`useActionMutation` / `callAction`), CLI, and `/_agent-native/actions/<name>`. |
177
- | `undefined` | **Default-allow.** The action is a normal agent tool. |
178
-
179
- `agentTool: false` is **not** the same as [`toolCallable: false`](#tool-callable):
190
+ Reach for it when you add a UI-only or purely programmatic action, or when the UI stops using an action you'd otherwise leave exposed to the model.
180
191
 
181
- - **`agentTool: false`** removes the action from the **model's** view. The model can no longer see or call it; the UI and HTTP can.
182
- - **`toolCallable: false`** only blocks the sandboxed **extension iframe bridge** (`appAction(...)`). The action stays fully visible to the model, UI, CLI, MCP, and A2A. It exists for high-blast-radius operations (account/org/auth changes), not for trimming the tool list.
192
+ #### `toolCallable` block the extension iframe {#tool-callable}
183
193
 
184
- Reach for `agentTool: false` when you find yourself adding a UI-only or purely programmatic action, or when the UI stops using an action you'd otherwise leave exposed to the model.
185
-
186
- ### Extension callability {#tool-callable}
187
-
188
- Extensions (Alpine.js mini-apps that run inside sandboxed iframes — see [Extensions](/docs/extensions)) call actions via `appAction(name, params)`. Because a shared extension's HTML/JS executes inside the _viewer's_ session, an action invoked from an extension runs with the viewer's permissions, secrets, and SQL scope. For high-blast-radius operations, that is too much trust to grant by default.
189
-
190
- Use the `toolCallable` flag to control this (the flag name is kept for backward compatibility — it gates extension iframe callability):
194
+ Extensions ([Alpine.js mini-apps in sandboxed iframes](/docs/extensions)) call actions via `appAction(name, params)`, running with the _viewer's_ permissions, secrets, and SQL scope. For high-blast-radius operations that is too much trust by default. Set `toolCallable: false` to make the extension bridge return 403 while keeping the action callable from the UI, agent, CLI, MCP, and A2A:
191
195
 
192
196
  ```ts
193
197
  export default defineAction({
@@ -200,20 +204,7 @@ export default defineAction({
200
204
  });
201
205
  ```
202
206
 
203
- | Value | Behavior |
204
- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
205
- | `true` | Allow (same as undefined). Useful for documentation of intent. |
206
- | `false` | Explicit deny. The extension bridge returns 403; the action is still callable normally from the UI, agent, CLI, MCP, and A2A. |
207
- | `undefined` | **Default-allow.** Extensions are intra-org and typically authored by trusted teammates, so the default trusts the org-level access controls. Set `false` only for genuinely auth-adjacent operations (account deletion, org membership changes). |
208
-
209
- Enforcement: the parent host tags every outbound action call from an extension iframe with the header `X-Agent-Native-Tool-Bridge: 1`. The action route layer reads this header and applies the rule above. Regular UI/agent/CLI/A2A calls do not carry the header and are unaffected. The header is set by the React host; the iframe's user-authored content cannot spoof it because the bridge sanitizes iframe-supplied headers.
210
-
211
- Set `toolCallable: false` for actions that:
212
-
213
- - delete or transfer ownership of any account/org,
214
- - change auth state (sign-out-all sessions, rotate tokens),
215
- - modify org membership (invite/remove members, change roles),
216
- - change resource visibility or grant share access (the framework's built-in `share-resource`, `unshare-resource`, and `set-resource-visibility` are already opted out).
207
+ Use it for actions that delete or transfer accounts/orgs, change auth state, modify org membership, or grant share access. The framework's built-in `share-resource`, `unshare-resource`, and `set-resource-visibility` are already opted out. Enforcement is by an unspoofable host-set header on iframe calls; regular UI/agent/CLI/MCP/A2A calls are unaffected — see [Security](/docs/security) for details.
217
208
 
218
209
  ### Run context (second argument) {#run-context}
219
210
 
@@ -307,10 +298,10 @@ export default defineAction({
307
298
  });
308
299
  ```
309
300
 
310
- `needsApproval` accepts a boolean or a predicate `(args, ctx) => boolean | Promise<boolean>` to gate conditionally (e.g. only external recipients, only above a threshold). The predicate **fails closed**: a throw is treated as "approval required". When the gate is truthy and the call isn't yet approved, the loop emits an `approval_required` event and stops the turn the side effect never happens and the action runs only once a human approves via the chat UI's Approve affordance.
301
+ `needsApproval` also accepts a predicate `(args, ctx) => boolean | Promise<boolean>` to gate conditionally (e.g. only external recipients, only above a threshold); it **fails closed**, so a throw counts as "approval required". When the gate is truthy and unapproved, the loop stops the turn and the side effect never fires until a human approves in the chat UI.
311
302
 
312
303
  > [!WARNING]
313
- > Keep approvals rare. Each gated action is a hard stop in the agent loop. The default is **off**, and almost every action should leave it off. See [Human-in-the-Loop Approvals](/docs/human-approval) for the full flow.
304
+ > Keep approvals rare. Each gated action is a hard stop in the agent loop. The default is **off**, and almost every action should leave it off. See [Human-in-the-Loop Approvals](/docs/human-approval) for the predicate API, the `approval_required` event, and the full flow.
314
305
 
315
306
  ## Calling it from the UI {#ui}
316
307
 
@@ -394,12 +385,11 @@ export default defineAction({
394
385
  ```
395
386
 
396
387
  The built-in discriminants are `"data-table"`, `"data-chart"`, and
397
- `"data-insights"`. Their server-safe builders and schemas are exported from
398
- `@agent-native/core/data-widgets`, and native renderer ids are exported from
399
- `@agent-native/core`. See [Native Chat UI](/docs/native-chat-ui) for the full
400
- result contract and BYO runtime guidance, or [Agent Surfaces](/docs/agent-surfaces)
401
- for how this same action can stay headless, render in chat, or grow into a full
402
- screen.
388
+ `"data-insights"`, with server-safe builders and schemas in
389
+ `@agent-native/core/data-widgets`. See [Native Chat UI](/docs/native-chat-ui)
390
+ for the full result contract and BYO runtime guidance, or
391
+ [Agent Surfaces](/docs/agent-surfaces) for how the same action can stay
392
+ headless, render in chat, or grow into a full screen.
403
393
 
404
394
  ## Calling it from the CLI {#cli}
405
395
 
@@ -417,9 +407,9 @@ If your app is an [A2A](/docs/a2a-protocol) peer, other agent-native apps discov
417
407
 
418
408
  ## Exposing it over MCP {#mcp}
419
409
 
420
- With MCP enabled, your actions show up in the framework's MCP server at `/_agent-native/mcp`. Every caller gets a compact catalog by default — code/stdio developer clients, the local CLI proxy, and chat-style app hosts (OAuth MCP Apps callers and generic authenticated remote HTTP/static-token callers) alike — containing app-facing builtins (`open_app`, `list_apps`, `ask_app`, and app-only embed helpers) plus the template-declared app actions; action-specific MCP App resources stay out of that catalog unless an action explicitly sets `mcpApp.compactCatalog: true`. `tool-search` is always present (call it with no query for the full tool menu, or with a query for ranked matches), so any tool stays reachable on demand. The full action surface is served only on explicit opt-in (`--full-catalog` token or `AGENT_NATIVE_MCP_FULL_CATALOG=1`). `publicAgent.expose` is still the opt-in for safe read/ingest tools outside that compact app catalog. See [MCP Protocol](/docs/mcp-protocol).
410
+ With MCP enabled, your actions show up in the framework's MCP server at `/_agent-native/mcp`. Every caller gets a compact catalog by default — app-facing builtins plus the template-declared app actions and `tool-search` is always present so any other tool stays reachable on demand. The full action surface is served only on explicit opt-in (`--full-catalog` token or `AGENT_NATIVE_MCP_FULL_CATALOG=1`), and `publicAgent.expose` opts a safe read/ingest tool onto the public surface. See [MCP Protocol](/docs/mcp-protocol) for catalog tiers, auth, and the `mcpApp` resource details.
421
411
 
422
- For UI-capable MCP hosts, an action can also declare an optional MCP Apps resource via the `mcpApp` field (and a matching `link`) so capable hosts render the result inline. The pattern mirrors the focused link we already return for external agents: the action exposes the operation, `link` points at the route with the right URL or deep-link params, and the embed helper uses that same target as the inline app. When an action's `link` and `mcpApp` should point at the same route, use `embedRoute()` to build both from one pure path builder.
412
+ For UI-capable MCP hosts, an action can declare an optional MCP Apps resource via the `mcpApp` field (plus a matching `link`) so capable hosts render the result inline. When `link` and `mcpApp` should point at the same route, `embedRoute()` builds both from one pure path builder:
423
413
 
424
414
  ```ts
425
415
  import { embedRoute } from "@agent-native/core";
@@ -15,23 +15,60 @@ you want, then use the matching primitive.
15
15
 
16
16
  | Surface | Use it when | Start with |
17
17
  | ----------------------------- | ----------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- |
18
- | **Headless agent/actions** | Code, jobs, scripts, another app, or another agent should call the work directly. | `agent-native create --headless`, `defineAction`, `agent-native agent`, HTTP, CLI, MCP, A2A |
18
+ | **Headless agent** | Code, jobs, scripts, another app, or another agent should call the work directly. | `agent-native create --headless`, `defineAction`, `agent-native agent`, HTTP, CLI, MCP, A2A |
19
19
  | **Rich chat on Agent-Native** | You want a standalone or embedded chat backed by the built-in agent loop. | [Chat template](/docs/template-chat), `<AgentChatSurface>`, `<AssistantChat>` |
20
20
  | **Rich chat on your agent** | You built the agent elsewhere and want Agent-Native's composer, transcript, tool cards, and native widgets. | `AgentChatRuntime`, `<AssistantChat runtime={runtime}>` |
21
21
  | **Embedded sidecar** | You already have a SaaS app and want an agent beside it with page context and host commands. | `createAgentNativeEmbeddedPlugin()`, `AgentNativeEmbedded` |
22
22
  | **Full application** | Humans and agents should share durable screens, data, navigation, and collaboration. | Templates, actions, SQL state, context awareness |
23
23
 
24
24
  Those are stages, not separate products. A workflow can start as a headless
25
- action, appear in chat as a table or chart, and later become a full screen in an
26
- app without changing the operation the agent calls.
25
+ agent with one action, appear in chat as a table or chart, and later become a
26
+ full screen in an app without changing the operation the agent calls.
27
27
 
28
- ## Headless agent/actions {#headless}
28
+ ## Headless agent {#headless}
29
29
 
30
30
  Use the headless path when no one needs to stare at a custom app screen while
31
31
  the work runs: scheduled jobs, integrations, backend workflows, CLI loops,
32
32
  another agent, or an existing product calling into Agent-Native.
33
33
 
34
- The smallest local path is a headless scaffold plus one action:
34
+ This is also the shape to reach for when **the agent _is_ the product** — the
35
+ app-agent loop is the front door, not a dashboard. You send a request from the
36
+ terminal, Slack, email, a scheduled job, another agent, or Chat — "summarize my
37
+ unread emails," "post the daily metrics to Slack," "find the candidates who
38
+ replied last week" — and the agent acts and returns the result wherever it
39
+ belongs. It is still a real app, not a stateless prompt: actions, auth sessions,
40
+ app state, thread/run history, settings, credentials, and share records all live
41
+ in SQL.
42
+
43
+ Pick this pattern when:
44
+
45
+ - **The work happens in the background.** Most of the value is created while the user isn't looking — triage agents, daily-report agents, on-call responders.
46
+ - **The output leaves the app.** The agent posts to Slack, sends email, or updates a third-party system; there's nothing to browse in-app.
47
+ - **The domain is one-shot.** Research bot, summary generator, report writer — no persistent object that needs a list view.
48
+ - **You're prototyping.** Ship the agent now; add richer UI later if users want one.
49
+
50
+ If your product is built around persistent objects users browse, pivot, and
51
+ share — emails, events, documents, charts — pick a [full application](#full-application)
52
+ or a [template](/docs/cloneable-saas) instead; those add a full UI _plus_ the agent.
53
+
54
+ ### What ships in the box {#in-the-box}
55
+
56
+ A headless app skips weeks of dashboard work, and it's channel-agnostic from day
57
+ one — the same agent runs from the web, Slack, Telegram, email, and other agents
58
+ because everything goes through the agent, not the UI. The trade-off is there's
59
+ no "browse-everything-at-a-glance" view; if users need that, mix patterns and
60
+ add a small status page or list view.
61
+
62
+ When you add the built-in Chat shell, the framework provides five management
63
+ surfaces you don't have to build: **Chat** (the main input), **Workspace**
64
+ (skills, memory, instructions, sub-agents, connected MCP servers, scheduled
65
+ jobs), **Job history**, **Thread history**, and **Settings**. Those are usually
66
+ enough — talk to it, see what it's done, configure how it behaves. Reach for
67
+ [Chat](/docs/template-chat) when you're ready to add that browser UI, or the
68
+ [Dispatch template](/docs/template-dispatch) for a workspace-style starting
69
+ point with Slack/Telegram, scheduled jobs, and shared secrets out of the box.
70
+
71
+ The smallest local path is a headless agent scaffold plus one action:
35
72
 
36
73
  ```bash
37
74
  npx @agent-native/core@latest create my-agent --headless
@@ -81,45 +118,20 @@ If another app or script needs to call the whole agent, use
81
118
  `agentNative.invoke("analytics", "...")` or the `agent-native invoke` CLI. That
82
119
  keeps cross-app work on the A2A path while local work stays on actions.
83
120
 
84
- Workers, jobs, integration webhooks, and custom hosts can use the server API
85
- directly. This is lower-level than actions: you provide the engine, model,
86
- messages, actions, and event sink yourself.
121
+ Workers, jobs, integration webhooks, and custom hosts can drive the agent loop
122
+ directly through the server API. This is lower-level than actions you provide
123
+ the engine, model, messages, actions, and event sink yourself:
87
124
 
88
125
  ```ts
89
- import {
90
- actionsToEngineTools,
91
- resolveEngine,
92
- runAgentLoop,
93
- } from "@agent-native/core/server";
94
-
95
- const engine = await resolveEngine({ engineOption: undefined });
96
- const model = engine.defaultModel;
97
- const controller = new AbortController();
98
-
99
- await runAgentLoop({
100
- engine,
101
- model,
102
- systemPrompt: "You are the reporting agent for this workspace.",
103
- actions,
104
- tools: actionsToEngineTools(actions),
105
- messages: [
106
- {
107
- role: "user",
108
- content: [{ type: "text", text: "Summarize this week's forms." }],
109
- },
110
- ],
111
- send: (event) => {
112
- // Persist, log, stream, or translate AgentChatEvent objects.
113
- },
114
- signal: controller.signal,
115
- ownerEmail: user.email,
116
- orgId: user.orgId,
117
- });
126
+ import { runAgentLoop } from "@agent-native/core/server";
127
+
128
+ await runAgentLoop({ engine, model, systemPrompt, actions, messages, send });
118
129
  ```
119
130
 
120
131
  For most apps, scheduled prompts and integration webhooks already call this loop
121
- for you. Reach for direct `runAgentLoop()` when you are building a custom
122
- headless host, eval runner, or server-side orchestration surface.
132
+ for you. Reach for it directly only when building a custom headless host, eval
133
+ runner, or server-side orchestration surface — see [Server — Production agent
134
+ handler](/docs/server#agent-handler) for the full signature.
123
135
 
124
136
  ### Running against a folder {#folder-loop}
125
137
 
@@ -178,6 +190,48 @@ export default function ChatRoute() {
178
190
  }
179
191
  ```
180
192
 
193
+ When an app has both a full-page chat tab and an `AgentSidebar`, use the same
194
+ `storageKey` on both surfaces, enable `chatViewTransition`, and install the
195
+ chat-home handoff helpers in the layout. Ordinary in-app links out of the chat
196
+ page can then morph the full chat into the sidebar while keeping the active
197
+ thread:
198
+
199
+ ```tsx
200
+ import {
201
+ AgentChatSurface,
202
+ AgentSidebar,
203
+ useAgentChatHomeHandoff,
204
+ useAgentChatHomeHandoffLinks,
205
+ } from "@agent-native/core/client/chat";
206
+ import { useLocation } from "react-router";
207
+
208
+ function ChatRoute() {
209
+ return (
210
+ <AgentChatSurface mode="page" storageKey="my-app" chatViewTransition />
211
+ );
212
+ }
213
+
214
+ function AppLayout({ children }: { children: React.ReactNode }) {
215
+ const location = useLocation();
216
+ const handoffActive = useAgentChatHomeHandoff({
217
+ storageKey: "my-app",
218
+ activePath: location.pathname,
219
+ enabled: location.pathname !== "/chat",
220
+ });
221
+ useAgentChatHomeHandoffLinks({ storageKey: "my-app", chatPath: "/chat" });
222
+
223
+ return (
224
+ <AgentSidebar
225
+ storageKey="my-app"
226
+ chatViewTransition
227
+ openOnChatRunning={handoffActive}
228
+ >
229
+ {children}
230
+ </AgentSidebar>
231
+ );
232
+ }
233
+ ```
234
+
181
235
  The simplest embedded chat with your own chrome:
182
236
 
183
237
  ```tsx
@@ -195,14 +249,9 @@ components in the chat, without iframes. See [Native Chat UI](/docs/native-chat-
195
249
  ## Rich chat on your agent {#byo-agent}
196
250
 
197
251
  Use this path when your agent is already built with another framework or
198
- runtime and you want Agent-Native's chat UI around it.
199
-
200
- The [Chat template](/docs/template-chat) is still useful here: keep its app
201
- shell and thread UI, then swap the runtime behind the chat plugin or route.
202
-
203
- `AgentChatRuntime` is the boundary. Your runtime streams normalized events;
204
- Agent-Native renders the composer, transcript, tool calls, approvals, native
205
- widgets, and app layout.
252
+ runtime and you want Agent-Native's chat UI around it. `AgentChatRuntime` is the
253
+ boundary: your runtime streams normalized events, and Agent-Native renders the
254
+ composer, transcript, tool calls, approvals, native widgets, and app layout.
206
255
 
207
256
  ```tsx
208
257
  import {
@@ -211,10 +260,7 @@ import {
211
260
  } from "@agent-native/core/client/chat";
212
261
 
213
262
  const runtime = createHttpAgentChatRuntime({
214
- id: "external:support-agent",
215
- label: "Support agent",
216
263
  endpoint: "/api/support-agent/chat",
217
- headers: async () => ({ Authorization: `Bearer ${await getToken()}` }),
218
264
  });
219
265
 
220
266
  export function SupportAgentChat() {
@@ -222,40 +268,15 @@ export function SupportAgentChat() {
222
268
  }
223
269
  ```
224
270
 
225
- Use `createOpenAIAgentsChatRuntime()`,
226
- `createOpenAIResponsesChatRuntime()`, `createClaudeAgentChatRuntime()`,
227
- `createVercelAiChatRuntime()`, or `createAgUiChatRuntime()` when your endpoint
228
- already streams one of those event shapes. Use `createHttpAgentChatRuntime()`
229
- when your agent streams Agent-Native's normalized event shape directly:
230
-
231
- ```ts
232
- import { createOpenAIAgentsChatRuntime } from "@agent-native/core/client/chat";
233
-
234
- const runtime = createOpenAIAgentsChatRuntime({
235
- endpoint: "/api/openai-agent/chat",
236
- });
237
- ```
238
-
239
- The endpoint can stream SSE or NDJSON events:
240
-
241
- ```txt
242
- data: {"type":"message-delta","messageId":"m1","delta":{"type":"text","text":"I found 34 submissions."}}
243
- data: {"type":"tool-start","toolCall":{"id":"t1","name":"query","input":{"formId":"form_123"}}}
244
- data: {"type":"tool-done","toolCallId":"t1","toolName":"query","status":"completed","resultText":"34 rows"}
245
- data: {"type":"done","reason":"complete"}
246
- ```
247
-
248
- For a trivial integration, returning `{ "text": "..." }` also works. For richer
249
- integrations, stream `message-*`, `tool-*`, `approval-request`, `status`,
250
- `artifact`, `file`, `usage`, `error`, and `done` events. Tool results can carry
251
- `chatUI` metadata so the same native table/chart/card renderers work with your
252
- agent too.
271
+ Ready-made runtime helpers exist for OpenAI Agents, OpenAI Responses, the Claude
272
+ Agent SDK, the Vercel AI SDK, and AG-UI, plus the normalized HTTP runtime above
273
+ for any other agent (Mastra, Flue, Eve, LangGraph, or a custom service). ACP is
274
+ not the default end-user app chat protocol, and Agent-Native does not currently
275
+ claim A2UI support.
253
276
 
254
- This is the right place to adapt the OpenAI Agents SDK, Claude Agent SDK, Vercel
255
- AI SDK, Mastra, Flue, Eve, LangGraph, a custom service, or an AG-UI-compatible
256
- event stream. Do not use ACP as the default end-user app chat protocol; ACP is
257
- better framed as coding-agent/editor interoperability. Agent-Native does not
258
- currently claim A2UI support.
277
+ [Native Chat UI BYO agent runtimes](/docs/native-chat-ui#byo-agent-runtimes)
278
+ is the canonical home for the event shapes, the runtime helpers, and `chatUI`
279
+ tool-result metadata. Start there when wiring an external agent into the chat.
259
280
 
260
281
  ## Embedded sidecar {#embedded-sidecar}
261
282
 
@@ -322,7 +343,7 @@ want a complete product shape.
322
343
 
323
344
  | If you are thinking... | Choose |
324
345
  | --------------------------------------------------------------- | ------------------------- |
325
- | "I just need a callable tool or workflow." | Headless action |
346
+ | "I just need a callable tool or workflow." | Headless agent |
326
347
  | "I want the framework's agent, but chat should be the main UI." | Rich chat on Agent-Native |
327
348
  | "I already have an agent; I need a polished chat UI for it." | Rich chat on your agent |
328
349
  | "I already have a SaaS app; add an agent beside it." | Embedded sidecar |
@@ -127,19 +127,7 @@ interface AgentTask {
127
127
 
128
128
  ## Custom agent profiles {#profiles}
129
129
 
130
- A custom agent is a Markdown file in the workspace. Minimal example:
131
-
132
- ```markdown
133
- ---
134
- name: Code Review
135
- description: Reviews TypeScript PRs for correctness and type safety.
136
- model: inherit
137
- ---
138
-
139
- You are a meticulous code reviewer. Be terse and concrete — cite file:line wherever you can.
140
- ```
141
-
142
- Store at `agents/code-review.md` in the workspace. It appears in the `@mention` dropdown and is available to the main agent as a delegation target. See [Workspace — Custom Agents](/docs/workspace#custom-agents) for the full format including `tools`, `delegate-default`, and model overrides.
130
+ Sub-agents map to custom agent profiles Markdown files at `agents/<slug>.md` in the workspace that appear in the `@mention` dropdown and serve as delegation targets. [Workspace — Custom Agents](/docs/workspace#custom-agents) owns the full format (frontmatter, `tools`, `delegate-default`, model overrides).
143
131
 
144
132
  ## Delegation depth guard {#depth-guard}
145
133
 
@@ -147,7 +135,7 @@ Sub-agents can spawn sub-agents, which is a runaway/cost risk: an unbounded chai
147
135
 
148
136
  The top-level chat is depth `0`. A sub-agent it spawns is depth `1`; that sub-agent may spawn once more (depth `2`); a spawn that would create a depth-`3` sub-agent is **refused**. The default cap is **2**.
149
137
 
150
- ```txt
138
+ ```text
151
139
  depth 0 top-level chat (may spawn)
152
140
  depth 1 sub-agent (may spawn)
153
141
  depth 2 sub-agent's sub-agent (at the cap — may NOT spawn)
@@ -1,11 +1,11 @@
1
1
  ---
2
- title: "Agent Web Surfaces"
3
- description: "Make public routes crawlable, readable, citable, and optionally callable by agents."
2
+ title: "Public Agent Web"
3
+ description: "Make public routes crawlable, readable, citable, and optionally callable by agents — robots.txt, llms.txt, markdown mirrors, JSON-LD, and a public MCP surface."
4
4
  ---
5
5
 
6
- # Agent Web Surfaces
6
+ # Public Agent Web
7
7
 
8
- Agent Web surfaces make public Agent-Native routes easy for agents to crawl, read, cite, and call. The goal is not to make every app endpoint public. The goal is to publish a clean public surface for pages that are already public, while keeping private data and tool access behind explicit controls.
8
+ The public agent web makes public Agent-Native routes easy for agents to crawl, read, cite, and call. The goal is not to make every app endpoint public. The goal is to publish a clean public surface for pages that are already public, while keeping private data and tool access behind explicit controls.
9
9
 
10
10
  The docs site is the reference implementation. Today it ships:
11
11