@agent-native/core 0.7.4 → 0.7.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -5
- package/dist/agent/engine/anthropic-engine.d.ts.map +1 -1
- package/dist/agent/engine/anthropic-engine.js +8 -4
- package/dist/agent/engine/anthropic-engine.js.map +1 -1
- package/dist/agent/engine/types.d.ts +1 -1
- package/dist/agent/engine/types.d.ts.map +1 -1
- package/dist/agent/production-agent.d.ts +7 -0
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +153 -118
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/agent/run-manager.d.ts +4 -0
- package/dist/agent/run-manager.d.ts.map +1 -1
- package/dist/agent/run-manager.js +46 -25
- package/dist/agent/run-manager.js.map +1 -1
- package/dist/agent/run-store.d.ts +12 -3
- package/dist/agent/run-store.d.ts.map +1 -1
- package/dist/agent/run-store.js +25 -4
- package/dist/agent/run-store.js.map +1 -1
- package/dist/chat-threads/store.d.ts +13 -0
- package/dist/chat-threads/store.d.ts.map +1 -1
- package/dist/chat-threads/store.js +66 -10
- package/dist/chat-threads/store.js.map +1 -1
- package/dist/cli/create.d.ts.map +1 -1
- package/dist/cli/create.js +8 -1
- package/dist/cli/create.js.map +1 -1
- package/dist/cli/index.js +8 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/info.d.ts +2 -0
- package/dist/cli/info.d.ts.map +1 -0
- package/dist/cli/info.js +103 -0
- package/dist/cli/info.js.map +1 -0
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +249 -85
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/agent-chat-adapter.d.ts.map +1 -1
- package/dist/client/agent-chat-adapter.js +12 -1
- package/dist/client/agent-chat-adapter.js.map +1 -1
- package/dist/client/composer/TiptapComposer.d.ts +3 -1
- package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
- package/dist/client/composer/TiptapComposer.js +46 -2
- package/dist/client/composer/TiptapComposer.js.map +1 -1
- package/dist/client/composer/VoiceButton.d.ts +21 -0
- package/dist/client/composer/VoiceButton.d.ts.map +1 -0
- package/dist/client/composer/VoiceButton.js +51 -0
- package/dist/client/composer/VoiceButton.js.map +1 -0
- package/dist/client/composer/useVoiceDictation.d.ts +38 -0
- package/dist/client/composer/useVoiceDictation.d.ts.map +1 -0
- package/dist/client/composer/useVoiceDictation.js +398 -0
- package/dist/client/composer/useVoiceDictation.js.map +1 -0
- package/dist/client/onboarding/OnboardingPanel.js +2 -2
- package/dist/client/onboarding/OnboardingPanel.js.map +1 -1
- package/dist/client/org/OrgSwitcher.d.ts +5 -4
- package/dist/client/org/OrgSwitcher.d.ts.map +1 -1
- package/dist/client/org/OrgSwitcher.js +90 -24
- package/dist/client/org/OrgSwitcher.js.map +1 -1
- package/dist/client/resources/McpServerDetail.d.ts +15 -0
- package/dist/client/resources/McpServerDetail.d.ts.map +1 -0
- package/dist/client/resources/McpServerDetail.js +65 -0
- package/dist/client/resources/McpServerDetail.js.map +1 -0
- package/dist/client/resources/ResourceEditor.js +1 -1
- package/dist/client/resources/ResourceEditor.js.map +1 -1
- package/dist/client/resources/ResourceTree.d.ts +6 -1
- package/dist/client/resources/ResourceTree.d.ts.map +1 -1
- package/dist/client/resources/ResourceTree.js +18 -7
- package/dist/client/resources/ResourceTree.js.map +1 -1
- package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
- package/dist/client/resources/ResourcesPanel.js +191 -20
- package/dist/client/resources/ResourcesPanel.js.map +1 -1
- package/dist/client/resources/use-mcp-servers.d.ts +68 -0
- package/dist/client/resources/use-mcp-servers.d.ts.map +1 -0
- package/dist/client/resources/use-mcp-servers.js +83 -0
- package/dist/client/resources/use-mcp-servers.js.map +1 -0
- package/dist/client/resources/use-resources.d.ts +39 -1
- package/dist/client/resources/use-resources.d.ts.map +1 -1
- package/dist/client/resources/use-resources.js +102 -0
- package/dist/client/resources/use-resources.js.map +1 -1
- package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
- package/dist/client/settings/SettingsPanel.js +3 -2
- package/dist/client/settings/SettingsPanel.js.map +1 -1
- package/dist/client/settings/VoiceTranscriptionSection.d.ts +14 -0
- package/dist/client/settings/VoiceTranscriptionSection.d.ts.map +1 -0
- package/dist/client/settings/VoiceTranscriptionSection.js +111 -0
- package/dist/client/settings/VoiceTranscriptionSection.js.map +1 -0
- package/dist/client/sharing/ShareButton.d.ts +6 -4
- package/dist/client/sharing/ShareButton.d.ts.map +1 -1
- package/dist/client/sharing/ShareButton.js +299 -34
- package/dist/client/sharing/ShareButton.js.map +1 -1
- package/dist/client/sharing/ShareDialog.d.ts +22 -4
- package/dist/client/sharing/ShareDialog.d.ts.map +1 -1
- package/dist/client/sharing/ShareDialog.js +170 -148
- package/dist/client/sharing/ShareDialog.js.map +1 -1
- package/dist/client/sharing/VisibilityBadge.d.ts.map +1 -1
- package/dist/client/sharing/VisibilityBadge.js +1 -2
- package/dist/client/sharing/VisibilityBadge.js.map +1 -1
- package/dist/client/use-action.d.ts.map +1 -1
- package/dist/client/use-action.js +20 -1
- package/dist/client/use-action.js.map +1 -1
- package/dist/db/migrations.d.ts +18 -3
- package/dist/db/migrations.d.ts.map +1 -1
- package/dist/db/migrations.js +25 -3
- package/dist/db/migrations.js.map +1 -1
- package/dist/deploy/workspace-core.js +2 -2
- package/dist/mcp-client/config.d.ts +20 -1
- package/dist/mcp-client/config.d.ts.map +1 -1
- package/dist/mcp-client/config.js +28 -11
- package/dist/mcp-client/config.js.map +1 -1
- package/dist/mcp-client/hub-client.d.ts +38 -0
- package/dist/mcp-client/hub-client.d.ts.map +1 -0
- package/dist/mcp-client/hub-client.js +147 -0
- package/dist/mcp-client/hub-client.js.map +1 -0
- package/dist/mcp-client/hub-routes.d.ts +42 -0
- package/dist/mcp-client/hub-routes.d.ts.map +1 -0
- package/dist/mcp-client/hub-routes.js +114 -0
- package/dist/mcp-client/hub-routes.js.map +1 -0
- package/dist/mcp-client/index.d.ts +15 -0
- package/dist/mcp-client/index.d.ts.map +1 -1
- package/dist/mcp-client/index.js +35 -0
- package/dist/mcp-client/index.js.map +1 -1
- package/dist/mcp-client/manager.d.ts +54 -8
- package/dist/mcp-client/manager.d.ts.map +1 -1
- package/dist/mcp-client/manager.js +276 -59
- package/dist/mcp-client/manager.js.map +1 -1
- package/dist/mcp-client/remote-store.d.ts +102 -0
- package/dist/mcp-client/remote-store.d.ts.map +1 -0
- package/dist/mcp-client/remote-store.js +200 -0
- package/dist/mcp-client/remote-store.js.map +1 -0
- package/dist/mcp-client/routes.d.ts +55 -0
- package/dist/mcp-client/routes.d.ts.map +1 -0
- package/dist/mcp-client/routes.js +384 -0
- package/dist/mcp-client/routes.js.map +1 -0
- package/dist/mcp-client/visibility.d.ts +16 -0
- package/dist/mcp-client/visibility.d.ts.map +1 -0
- package/dist/mcp-client/visibility.js +45 -0
- package/dist/mcp-client/visibility.js.map +1 -0
- package/dist/org/context.js +2 -2
- package/dist/org/context.js.map +1 -1
- package/dist/org/handlers.js +2 -2
- package/dist/org/handlers.js.map +1 -1
- package/dist/resources/handlers.d.ts.map +1 -1
- package/dist/resources/handlers.js +30 -0
- package/dist/resources/handlers.js.map +1 -1
- package/dist/secrets/register-framework-secrets.d.ts +13 -0
- package/dist/secrets/register-framework-secrets.d.ts.map +1 -0
- package/dist/secrets/register-framework-secrets.js +59 -0
- package/dist/secrets/register-framework-secrets.js.map +1 -0
- package/dist/secrets/register.d.ts.map +1 -1
- package/dist/secrets/register.js +8 -1
- package/dist/secrets/register.js.map +1 -1
- package/dist/server/action-routes.d.ts.map +1 -1
- package/dist/server/action-routes.js +22 -2
- package/dist/server/action-routes.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts +16 -0
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +237 -70
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/app-url.d.ts.map +1 -1
- package/dist/server/app-url.js +11 -3
- package/dist/server/app-url.js.map +1 -1
- package/dist/server/auth.d.ts.map +1 -1
- package/dist/server/auth.js +50 -0
- package/dist/server/auth.js.map +1 -1
- package/dist/server/better-auth-instance.d.ts.map +1 -1
- package/dist/server/better-auth-instance.js +99 -4
- package/dist/server/better-auth-instance.js.map +1 -1
- package/dist/server/core-routes-plugin.d.ts.map +1 -1
- package/dist/server/core-routes-plugin.js +44 -0
- package/dist/server/core-routes-plugin.js.map +1 -1
- package/dist/server/create-server.d.ts.map +1 -1
- package/dist/server/create-server.js +6 -0
- package/dist/server/create-server.js.map +1 -1
- package/dist/server/date-utils.d.ts +15 -0
- package/dist/server/date-utils.d.ts.map +1 -0
- package/dist/server/date-utils.js +41 -0
- package/dist/server/date-utils.js.map +1 -0
- package/dist/server/index.d.ts +2 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +2 -1
- package/dist/server/index.js.map +1 -1
- package/dist/server/onboarding-html.d.ts +3 -0
- package/dist/server/onboarding-html.d.ts.map +1 -1
- package/dist/server/onboarding-html.js +13 -3
- package/dist/server/onboarding-html.js.map +1 -1
- package/dist/server/request-context.d.ts +9 -0
- package/dist/server/request-context.d.ts.map +1 -1
- package/dist/server/request-context.js +10 -0
- package/dist/server/request-context.js.map +1 -1
- package/dist/server/transcribe-voice.d.ts +26 -0
- package/dist/server/transcribe-voice.d.ts.map +1 -0
- package/dist/server/transcribe-voice.js +143 -0
- package/dist/server/transcribe-voice.js.map +1 -0
- package/dist/styles/agent-native.css +111 -0
- package/dist/tailwind.preset.d.ts +2 -2
- package/dist/tailwind.preset.d.ts.map +1 -1
- package/dist/tailwind.preset.js +27 -7
- package/dist/tailwind.preset.js.map +1 -1
- package/dist/templates/default/app/global.css +65 -68
- package/dist/templates/default/components.json +1 -1
- package/dist/templates/default/package.json +2 -4
- package/dist/templates/default/vite.config.ts +3 -0
- package/dist/templates/workspace-core/package.json +1 -4
- package/dist/templates/workspace-core/src/index.ts +1 -1
- package/dist/templates/workspace-core/styles/tokens.css +22 -0
- package/dist/templates/workspace-core/tsconfig.json +1 -1
- package/dist/vite/client.d.ts +6 -0
- package/dist/vite/client.d.ts.map +1 -1
- package/dist/vite/client.js +18 -1
- package/dist/vite/client.js.map +1 -1
- package/docs/content/actions.md +169 -74
- package/docs/content/agent-teams.md +139 -0
- package/docs/content/cloneable-saas.md +98 -0
- package/docs/content/creating-templates.md +9 -11
- package/docs/content/deployment.md +2 -9
- package/docs/content/drop-in-agent.md +200 -0
- package/docs/content/enterprise-workspace.md +22 -10
- package/docs/content/getting-started.md +34 -19
- package/docs/content/integrations.md +3 -3
- package/docs/content/key-concepts.md +50 -23
- package/docs/content/mcp-clients.md +71 -0
- package/docs/content/pure-agent-apps.md +69 -0
- package/docs/content/recurring-jobs.md +123 -0
- package/docs/content/skills-guide.md +8 -0
- package/docs/content/template-analytics.md +190 -0
- package/docs/content/template-calendar.md +151 -0
- package/docs/content/template-clips.md +55 -0
- package/docs/content/template-content.md +141 -0
- package/docs/content/template-dispatch.md +58 -0
- package/docs/content/template-forms.md +51 -0
- package/docs/content/template-mail.md +169 -0
- package/docs/content/template-slides.md +218 -0
- package/docs/content/template-starter.md +68 -0
- package/docs/content/template-video.md +162 -0
- package/docs/content/voice-input.md +59 -0
- package/docs/content/what-is-agent-native.md +142 -45
- package/docs/content/workspace-management.md +1 -0
- package/docs/content/{resources.md → workspace.md} +94 -42
- package/package.json +9 -16
- package/src/templates/default/app/global.css +65 -68
- package/src/templates/default/components.json +1 -1
- package/src/templates/default/package.json +2 -4
- package/src/templates/default/vite.config.ts +3 -0
- package/src/templates/workspace-core/package.json +1 -4
- package/src/templates/workspace-core/src/index.ts +1 -1
- package/src/templates/workspace-core/styles/tokens.css +22 -0
- package/src/templates/workspace-core/tsconfig.json +1 -1
- package/dist/templates/default/postcss.config.js +0 -6
- package/dist/templates/default/tailwind.config.ts +0 -7
- package/dist/templates/workspace-core/tailwind.preset.ts +0 -34
- package/src/templates/default/postcss.config.js +0 -6
- package/src/templates/default/tailwind.config.ts +0 -7
- package/src/templates/workspace-core/tailwind.preset.ts +0 -34
package/docs/content/actions.md
CHANGED
|
@@ -1,129 +1,224 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: "Actions"
|
|
3
|
-
description: "
|
|
3
|
+
description: "defineAction — the single definition that becomes an agent tool, a typesafe frontend mutation, an HTTP endpoint, an MCP tool, and a CLI command."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Actions
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Actions are the single source of truth for anything your app does. Define an action once with `defineAction()`, drop it in `actions/`, and it's immediately available as:
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
- **An agent tool** — the agent sees it with a zod-derived JSON Schema and can call it in chat.
|
|
11
|
+
- **A typesafe React mutation** — `useActionMutation("name")` on the frontend, types inferred from the schema.
|
|
12
|
+
- **An HTTP endpoint** — `POST /_agent-native/actions/<name>` (auto-mounted by the framework).
|
|
13
|
+
- **An MCP tool** — exposed to Claude Desktop, ChatGPT remote-MCP, and any other MCP client.
|
|
14
|
+
- **An A2A tool** — called by other agent-native apps over A2A.
|
|
15
|
+
- **A CLI command** — `pnpm action <name>` for scripting and dev loops.
|
|
11
16
|
|
|
12
|
-
|
|
17
|
+
One definition, six consumers. This is rung 3 of the [ladder](/docs/what-is-agent-native#the-ladder).
|
|
18
|
+
|
|
19
|
+
## Defining an action {#defining}
|
|
13
20
|
|
|
14
21
|
```ts
|
|
15
|
-
// actions/
|
|
16
|
-
import {
|
|
17
|
-
|
|
22
|
+
// actions/reply-to-email.ts
|
|
23
|
+
import { defineAction } from "@agent-native/core";
|
|
24
|
+
import { z } from "zod";
|
|
25
|
+
|
|
26
|
+
export default defineAction({
|
|
27
|
+
description: "Reply to an email thread in the user's voice.",
|
|
28
|
+
schema: z.object({
|
|
29
|
+
emailId: z.string().describe("The id of the email to reply to."),
|
|
30
|
+
body: z.string().describe("The reply body, in markdown."),
|
|
31
|
+
}),
|
|
32
|
+
run: async ({ emailId, body }) => {
|
|
33
|
+
await db.insert(replies).values({ emailId, body });
|
|
34
|
+
return { ok: true, emailId };
|
|
35
|
+
},
|
|
36
|
+
});
|
|
18
37
|
```
|
|
19
38
|
|
|
20
|
-
|
|
21
|
-
// actions/hello.ts — example action
|
|
22
|
-
import { parseArgs } from "@agent-native/core";
|
|
39
|
+
That's it. The framework auto-discovers every file in `actions/` and mounts them on startup.
|
|
23
40
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
41
|
+
### Schema options {#schemas}
|
|
42
|
+
|
|
43
|
+
`schema` accepts any [Standard Schema](https://standardschema.dev)-compatible library:
|
|
44
|
+
|
|
45
|
+
- **Zod** (v4) — most common, best type inference, auto-converts to JSON Schema.
|
|
46
|
+
- **Valibot** — minimal bundle size if that matters.
|
|
47
|
+
- **ArkType** — if you like the syntax.
|
|
48
|
+
|
|
49
|
+
The schema is converted to JSON Schema for the Claude API tool definition, _and_ used at runtime to validate inputs before `run()` fires. Invalid inputs never reach your handler.
|
|
50
|
+
|
|
51
|
+
### HTTP config {#http}
|
|
52
|
+
|
|
53
|
+
By default every action is exposed as `POST /_agent-native/actions/<name>`. Override with the `http` option:
|
|
54
|
+
|
|
55
|
+
```ts
|
|
56
|
+
export default defineAction({
|
|
57
|
+
description: "Get details for a lead.",
|
|
58
|
+
schema: z.object({ leadId: z.string() }),
|
|
59
|
+
http: { method: "GET", path: "leads/:leadId" }, // optional override
|
|
60
|
+
run: async ({ leadId }) => {
|
|
61
|
+
return await db.select().from(leads).where(eq(leads.id, leadId));
|
|
62
|
+
},
|
|
63
|
+
});
|
|
28
64
|
```
|
|
29
65
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
66
|
+
- **`http: { method: "GET" | "POST" | "PUT" | "DELETE" }`** — default `POST`. `GET` actions are auto-marked `readOnly` so successful calls don't trigger a UI poll-refresh.
|
|
67
|
+
- **`http: { path: "..." }`** — override the route path under `/_agent-native/actions/`. Defaults to the filename.
|
|
68
|
+
- **`http: false`** — disable the HTTP endpoint entirely. Agent + CLI only.
|
|
69
|
+
- **`readOnly: true`** — explicitly skip the poll-refresh even for POST actions that don't mutate.
|
|
70
|
+
|
|
71
|
+
## Calling it from the UI {#ui}
|
|
72
|
+
|
|
73
|
+
Two hooks, both in `@agent-native/core/client`. Types are inferred from your `defineAction` schemas — no manual type declarations.
|
|
74
|
+
|
|
75
|
+
### `useActionMutation` {#use-action-mutation}
|
|
76
|
+
|
|
77
|
+
For actions that change state:
|
|
78
|
+
|
|
79
|
+
```tsx
|
|
80
|
+
import { useActionMutation } from "@agent-native/core/client";
|
|
81
|
+
|
|
82
|
+
const { mutate, isPending } = useActionMutation("replyToEmail");
|
|
83
|
+
|
|
84
|
+
<Button
|
|
85
|
+
disabled={isPending}
|
|
86
|
+
onClick={() => mutate({ emailId, body: "Thanks!" })}
|
|
87
|
+
>
|
|
88
|
+
Send Reply
|
|
89
|
+
</Button>;
|
|
33
90
|
```
|
|
34
91
|
|
|
35
|
-
|
|
92
|
+
On success, the framework emits a poll event so every `useActionQuery`/`useDbSync` consumer refetches automatically. See [Real-Time Sync](/docs/key-concepts#polling-sync).
|
|
36
93
|
|
|
37
|
-
|
|
94
|
+
### `useActionQuery` {#use-action-query}
|
|
95
|
+
|
|
96
|
+
For read-only GET actions:
|
|
38
97
|
|
|
39
98
|
```ts
|
|
40
|
-
import {
|
|
99
|
+
import { useActionQuery } from "@agent-native/core/client";
|
|
41
100
|
|
|
42
|
-
const
|
|
43
|
-
// { name: "Steve", verbose: "true", count: "3" }
|
|
101
|
+
const { data, isLoading } = useActionQuery("getLead", { leadId });
|
|
44
102
|
```
|
|
45
103
|
|
|
104
|
+
The query is cached under `["action", "getLead", { leadId }]` and auto-invalidated on any mutating action that completes.
|
|
105
|
+
|
|
106
|
+
## Calling it from the CLI {#cli}
|
|
107
|
+
|
|
108
|
+
Every action is runnable via `pnpm action`:
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
pnpm action replyToEmail --emailId thread-123 --body "Thanks!"
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Flags are parsed into the shape your schema expects. Useful for agent-dev loops, scripts, and cron.
|
|
115
|
+
|
|
116
|
+
## Calling it from another agent (A2A) {#a2a}
|
|
117
|
+
|
|
118
|
+
If your app is an [A2A](/docs/a2a-protocol) peer, other agent-native apps discover your actions automatically and can call them by name. Same-origin deploys skip JWT signing; cross-origin uses a shared `A2A_SECRET`.
|
|
119
|
+
|
|
120
|
+
## Exposing it over MCP {#mcp}
|
|
121
|
+
|
|
122
|
+
With MCP enabled, your actions show up in the framework's MCP server at `/_agent-native/mcp`. Any MCP client — Claude Desktop, ChatGPT remote MCP, etc. — can connect and see them as tools. See [MCP Protocol](/docs/mcp-protocol).
|
|
123
|
+
|
|
46
124
|
## Standard actions {#standard-actions}
|
|
47
125
|
|
|
48
|
-
Every template should include these two
|
|
126
|
+
Every template should include these two for [context awareness](/docs/context-awareness):
|
|
49
127
|
|
|
50
128
|
### view-screen {#view-screen}
|
|
51
129
|
|
|
52
|
-
Reads the current navigation state, fetches contextual data, and returns a snapshot of what the user sees. The agent
|
|
130
|
+
Reads the current navigation state, fetches contextual data, and returns a snapshot of what the user sees. The agent calls this when it needs a fresh look at the screen.
|
|
53
131
|
|
|
54
132
|
```ts
|
|
55
133
|
// actions/view-screen.ts
|
|
134
|
+
import { defineAction } from "@agent-native/core";
|
|
56
135
|
import { readAppState } from "@agent-native/core/application-state";
|
|
136
|
+
import { z } from "zod";
|
|
137
|
+
|
|
138
|
+
export default defineAction({
|
|
139
|
+
description: "Read the current screen state for context.",
|
|
140
|
+
schema: z.object({}),
|
|
141
|
+
http: { method: "GET" },
|
|
142
|
+
run: async () => {
|
|
143
|
+
const navigation = await readAppState("navigation");
|
|
144
|
+
const screen: Record<string, unknown> = { navigation };
|
|
145
|
+
|
|
146
|
+
if (navigation?.view === "inbox") {
|
|
147
|
+
const res = await fetch(
|
|
148
|
+
`${process.env.APP_URL}/api/emails?label=${navigation.label}`,
|
|
149
|
+
);
|
|
150
|
+
screen.emailList = await res.json();
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
return screen;
|
|
154
|
+
},
|
|
155
|
+
});
|
|
156
|
+
```
|
|
57
157
|
|
|
58
|
-
|
|
59
|
-
const navigation = await readAppState("navigation");
|
|
60
|
-
const screen: Record<string, unknown> = { navigation };
|
|
61
|
-
|
|
62
|
-
if (navigation?.view === "inbox") {
|
|
63
|
-
const res = await fetch(
|
|
64
|
-
"http://localhost:3000/api/emails?label=" + navigation.label,
|
|
65
|
-
);
|
|
66
|
-
screen.emailList = await res.json();
|
|
67
|
-
}
|
|
158
|
+
### navigate {#navigate}
|
|
68
159
|
|
|
69
|
-
|
|
70
|
-
}
|
|
71
|
-
```
|
|
160
|
+
Writes a one-shot navigation command to application state. The UI reads it, navigates, and deletes the entry.
|
|
72
161
|
|
|
73
|
-
```
|
|
74
|
-
|
|
162
|
+
```ts
|
|
163
|
+
// actions/navigate.ts
|
|
164
|
+
import { defineAction } from "@agent-native/core";
|
|
165
|
+
import { writeAppState } from "@agent-native/core/application-state";
|
|
166
|
+
import { z } from "zod";
|
|
167
|
+
|
|
168
|
+
export default defineAction({
|
|
169
|
+
description: "Navigate the user to a view.",
|
|
170
|
+
schema: z.object({
|
|
171
|
+
view: z.string(),
|
|
172
|
+
threadId: z.string().optional(),
|
|
173
|
+
}),
|
|
174
|
+
run: async (args) => {
|
|
175
|
+
await writeAppState("navigate", args);
|
|
176
|
+
return { ok: true };
|
|
177
|
+
},
|
|
178
|
+
});
|
|
75
179
|
```
|
|
76
180
|
|
|
77
|
-
|
|
181
|
+
## Legacy CLI-style actions {#legacy-cli-actions}
|
|
78
182
|
|
|
79
|
-
|
|
183
|
+
The framework still supports older `export default async function(args)` actions that aren't wrapped in `defineAction` — useful for one-off dev scripts that don't need agent/HTTP exposure. These are CLI-only; they don't appear as agent tools, don't mount HTTP endpoints, and don't get typesafe frontend hooks.
|
|
80
184
|
|
|
81
185
|
```ts
|
|
82
|
-
// actions/
|
|
186
|
+
// actions/debug-dump.ts — CLI-only
|
|
83
187
|
import { parseArgs } from "@agent-native/core";
|
|
84
|
-
import { writeAppState } from "@agent-native/core/application-state";
|
|
85
188
|
|
|
86
189
|
export default async function main(args: string[]) {
|
|
87
|
-
const
|
|
88
|
-
|
|
89
|
-
console.log("Navigate command written:", parsed);
|
|
190
|
+
const { table } = parseArgs(args);
|
|
191
|
+
// one-off script you wouldn't want the agent to call
|
|
90
192
|
}
|
|
91
193
|
```
|
|
92
194
|
|
|
93
|
-
|
|
94
|
-
pnpm action navigate --view inbox --threadId thread-123
|
|
95
|
-
```
|
|
195
|
+
New code should prefer `defineAction()`. Reach for this pattern only when you deliberately don't want the action exposed to agents or the UI.
|
|
96
196
|
|
|
97
|
-
|
|
197
|
+
### `parseArgs(args)` {#parseargs}
|
|
98
198
|
|
|
99
|
-
|
|
199
|
+
Helper for legacy-style actions. Parses CLI arguments in `--key value` or `--key=value` format:
|
|
100
200
|
|
|
101
201
|
```ts
|
|
102
|
-
import {
|
|
103
|
-
|
|
104
|
-
// Auto-submit a message
|
|
105
|
-
agentChat.submit("Generate a report for Q4");
|
|
106
|
-
|
|
107
|
-
// Prefill without submitting
|
|
108
|
-
agentChat.prefill("Draft an email to...", contextData);
|
|
202
|
+
import { parseArgs } from "@agent-native/core";
|
|
109
203
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
message: "Process this data",
|
|
113
|
-
context: JSON.stringify(data),
|
|
114
|
-
submit: true,
|
|
115
|
-
});
|
|
204
|
+
const args = parseArgs(["--name", "Steve", "--verbose", "--count=3"]);
|
|
205
|
+
// { name: "Steve", verbose: "true", count: "3" }
|
|
116
206
|
```
|
|
117
207
|
|
|
118
|
-
|
|
208
|
+
## Utility functions {#utility-functions}
|
|
209
|
+
|
|
210
|
+
| Function | Returns | Description |
|
|
211
|
+
| ----------------------- | --------- | ----------------------------------------------------- |
|
|
212
|
+
| `loadEnv(path?)` | `void` | Load `.env` from project root (or custom path). |
|
|
213
|
+
| `camelCaseArgs(args)` | `Record` | Convert kebab-case keys to camelCase. |
|
|
214
|
+
| `isValidPath(p)` | `boolean` | Validate a relative path (no traversal, no absolute). |
|
|
215
|
+
| `isValidProjectPath(p)` | `boolean` | Validate a project slug (e.g. `my-project`). |
|
|
216
|
+
| `ensureDir(dir)` | `void` | `mkdir -p` helper. |
|
|
217
|
+
| `fail(message)` | `never` | Print to stderr and `exit(1)`. |
|
|
119
218
|
|
|
120
|
-
##
|
|
219
|
+
## What's next
|
|
121
220
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
| `isValidPath(p)` | `boolean` | Validate relative path (no traversal, no absolute) |
|
|
127
|
-
| `isValidProjectPath(p)` | `boolean` | Validate project slug (e.g. "my-project") |
|
|
128
|
-
| `ensureDir(dir)` | `void` | mkdir -p helper |
|
|
129
|
-
| `fail(message)` | `never` | Print error to stderr and exit(1) |
|
|
221
|
+
- [**Drop-in Agent**](/docs/drop-in-agent) — `useActionMutation` / `useActionQuery` in React
|
|
222
|
+
- [**Context Awareness**](/docs/context-awareness) — the `view-screen` + `navigate` pattern in depth
|
|
223
|
+
- [**A2A Protocol**](/docs/a2a-protocol) — how other agents discover and call your actions
|
|
224
|
+
- [**MCP Protocol**](/docs/mcp-protocol) — exposing actions over MCP
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Agent Teams"
|
|
3
|
+
description: "The main agent delegates work to sub-agents that run in their own threads and appear as live preview chips inline in chat."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Agent Teams
|
|
7
|
+
|
|
8
|
+
The agent chat is an **orchestrator**, not a monolith. When the main agent hits a task that's better owned by a specialist — "write this email in my voice," "run a BigQuery analysis," "review this PR" — it spawns a sub-agent in its own thread, tools, and context. The sub-agent shows up as a live preview **chip** inline in the main chat; click it to open the full conversation as a tab.
|
|
9
|
+
|
|
10
|
+
This keeps the main thread focused, lets sub-agents run in parallel, and gives you a clean audit trail for any delegated work.
|
|
11
|
+
|
|
12
|
+
## The mental model {#mental-model}
|
|
13
|
+
|
|
14
|
+
- **Main chat** — the orchestrator. Reads your request, delegates. Rarely does heavy work itself.
|
|
15
|
+
- **Sub-agents** — run with their own thread, their own system prompt, their own tool set. Each maps to a "custom agent" profile in the [workspace](/docs/workspace).
|
|
16
|
+
- **Chips** — the rich preview card that appears inline in the main chat, showing the sub-agent's current step, streaming output, and final summary. Collapsed by default; expands to the full conversation on click.
|
|
17
|
+
- **Bidirectional messaging** — the main agent can send follow-ups to a running sub-agent; a sub-agent can message back when it hits an ambiguous point.
|
|
18
|
+
|
|
19
|
+
Sub-agent state is persisted in the `application_state` SQL table (under `agent-task:<taskId>`), so tasks survive serverless cold starts and work across multiple processes.
|
|
20
|
+
|
|
21
|
+
## When to spawn a sub-agent {#when-to-spawn}
|
|
22
|
+
|
|
23
|
+
Spawn when the task:
|
|
24
|
+
|
|
25
|
+
- Needs a different **system prompt** (a specialist voice or tone, e.g., "code review").
|
|
26
|
+
- Has a **long-running** tool chain that would pollute the main context.
|
|
27
|
+
- Can run **in parallel** with other work the main agent is doing.
|
|
28
|
+
- Is owned by a **different team** that already has a custom agent profile.
|
|
29
|
+
|
|
30
|
+
Don't spawn for trivial one-shot work — call the action directly.
|
|
31
|
+
|
|
32
|
+
## Invoking a sub-agent {#invoking}
|
|
33
|
+
|
|
34
|
+
Three ways to kick off a sub-agent, from least to most explicit:
|
|
35
|
+
|
|
36
|
+
### 1. `@mention` a custom agent {#mention}
|
|
37
|
+
|
|
38
|
+
The user types `@agent-name` in the chat composer. A dropdown of workspace sub-agents appears. Selecting one inserts a chip; on submit the main agent delegates the message to that sub-agent.
|
|
39
|
+
|
|
40
|
+
Custom agents live in the workspace at `agents/<slug>.md` — a Markdown file with YAML frontmatter. See [Custom Agents](/docs/workspace#custom-agents) for the format.
|
|
41
|
+
|
|
42
|
+
### 2. The main agent delegates automatically {#auto-delegate}
|
|
43
|
+
|
|
44
|
+
The framework gives the main agent a `delegate-to-agent` tool. When the model decides a task fits a registered sub-agent profile, it calls the tool. A chip appears; the sub-agent runs. The main agent waits (or moves on in parallel) and incorporates the result when the sub-agent finishes.
|
|
45
|
+
|
|
46
|
+
### 3. Programmatic spawn {#programmatic-spawn}
|
|
47
|
+
|
|
48
|
+
For framework-level integrations, use `spawnTask()` from `@agent-native/core/server`:
|
|
49
|
+
|
|
50
|
+
```ts
|
|
51
|
+
import { spawnTask } from "@agent-native/core/server";
|
|
52
|
+
|
|
53
|
+
const task = await spawnTask({
|
|
54
|
+
description: "Draft an outreach email to this lead",
|
|
55
|
+
instructions: "Match Steve's voice from learnings.md.",
|
|
56
|
+
ownerEmail: user.email,
|
|
57
|
+
systemPrompt: mailAgentSystemPrompt,
|
|
58
|
+
actions: mailActions,
|
|
59
|
+
apiKey: process.env.ANTHROPIC_API_KEY!,
|
|
60
|
+
parentSend: emit, // SSE emit function for the parent chat stream
|
|
61
|
+
});
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Most app code won't call this directly — the framework does it under the hood for `@mentions` and for the `delegate-to-agent` tool. Reach for `spawnTask()` only when you're wiring a new entry point (e.g., a button that kicks off a background job that runs as a sub-agent).
|
|
65
|
+
|
|
66
|
+
## Task lifecycle {#lifecycle}
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
spawnTask()
|
|
70
|
+
├─ creates a new thread in chat_threads (with the description as the first user message)
|
|
71
|
+
├─ writes agent-task:<taskId> to application_state (status=running)
|
|
72
|
+
├─ emits agent_task_started to the parent stream → chip appears in the UI
|
|
73
|
+
├─ runs the agent loop in the background
|
|
74
|
+
│ └─ emits agent_task_step events → chip updates live
|
|
75
|
+
├─ on completion: updates status=completed, writes summary + preview
|
|
76
|
+
└─ emits agent_task_done → chip shows final summary
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
At any point the parent agent can resume the sub-agent with a follow-up via `sendToTask(taskId, message)`. If the sub-agent errors, `markTaskErrored(taskId, reason)` records the failure and surfaces it to the user.
|
|
80
|
+
|
|
81
|
+
## Reading task state {#reading-state}
|
|
82
|
+
|
|
83
|
+
From server code or other actions:
|
|
84
|
+
|
|
85
|
+
```ts
|
|
86
|
+
import { getTask, listTasks } from "@agent-native/core/server";
|
|
87
|
+
|
|
88
|
+
const task = await getTask(taskId); // single task
|
|
89
|
+
const tasks = await listTasks(); // all tasks for the user (sorted newest first)
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
`AgentTask` shape:
|
|
93
|
+
|
|
94
|
+
```ts
|
|
95
|
+
interface AgentTask {
|
|
96
|
+
taskId: string;
|
|
97
|
+
threadId: string;
|
|
98
|
+
description: string;
|
|
99
|
+
status: "running" | "completed" | "errored";
|
|
100
|
+
preview: string; // short one-liner for the chip
|
|
101
|
+
summary: string; // full summary once completed
|
|
102
|
+
currentStep: string; // latest step label (updated while running)
|
|
103
|
+
createdAt: number;
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Custom agent profiles {#profiles}
|
|
108
|
+
|
|
109
|
+
A custom agent is a Markdown file in the workspace:
|
|
110
|
+
|
|
111
|
+
```markdown
|
|
112
|
+
---
|
|
113
|
+
name: Code Review
|
|
114
|
+
description: >-
|
|
115
|
+
Reviews TypeScript PRs with a focus on correctness, type safety, and API design.
|
|
116
|
+
model: inherit
|
|
117
|
+
tools: inherit
|
|
118
|
+
delegate-default: true
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
# Role
|
|
122
|
+
|
|
123
|
+
You are a meticulous code reviewer. Focus on correctness, subtle type errors,
|
|
124
|
+
and the public API surface. Be terse and concrete — cite file:line wherever
|
|
125
|
+
you can.
|
|
126
|
+
|
|
127
|
+
## Rules
|
|
128
|
+
|
|
129
|
+
- Prefer "here's the bug" over "here's why this pattern is wrong."
|
|
130
|
+
- Never LGTM silently; always summarize what you checked.
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
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.
|
|
134
|
+
|
|
135
|
+
## What's next
|
|
136
|
+
|
|
137
|
+
- [**Workspace — Custom Agents**](/docs/workspace#custom-agents) — the profile format
|
|
138
|
+
- [**A2A Protocol**](/docs/a2a-protocol) — when the "sub-agent" lives in a different app entirely
|
|
139
|
+
- [**Actions**](/docs/actions) — the tools a sub-agent calls
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Cloneable SaaS"
|
|
3
|
+
description: "Agent-native templates are not demos — they're complete, SaaS-grade products you clone, customize, and own."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Cloneable SaaS
|
|
7
|
+
|
|
8
|
+
The word "template" undersells what ships with agent-native.
|
|
9
|
+
|
|
10
|
+
In most frameworks, a template is a bare-bones scaffold: a couple of routes, a few components, and a lot of "TODO." Agent-native inverts that. Every template is a **full, SaaS-grade product** — email client, calendar, analytics, deck generator, video editor, form builder, issue tracker — complete enough to use as-is, and also complete enough to fork and make your own.
|
|
11
|
+
|
|
12
|
+
Think of them less like "templates" and more like **cloneable SaaS**. You get a real product, not a starting point.
|
|
13
|
+
|
|
14
|
+
## The pitch {#pitch}
|
|
15
|
+
|
|
16
|
+
Every SaaS product you use today hits the same wall: it gives you 80% of what you need, and you can't change the 20% that really matters. You can't touch the data model. You can't add the metric. You can't wire it to your internal system. You can't give it instructions.
|
|
17
|
+
|
|
18
|
+
Cloneable SaaS flips that. You start from a production-quality app, and everything about it is yours — the code, the database, the agent, the deploy target, the brand. If you don't like how the inbox groups by thread, change it. If you need a field that the template doesn't have, add it. The agent helps you do all of this in natural language.
|
|
19
|
+
|
|
20
|
+
This isn't a theoretical claim: it's how Steve (the framework's author) has been using it for months. The mail template _is_ his inbox. The analytics template _is_ his dashboard. The calendar template _is_ his calendar.
|
|
21
|
+
|
|
22
|
+
## What's in the catalog {#catalog}
|
|
23
|
+
|
|
24
|
+
All of these ship in the `BuilderIO/agent-native` repo and scaffold via `agent-native create`:
|
|
25
|
+
|
|
26
|
+
| Template | What it is |
|
|
27
|
+
| -------------- | --------------------------------------------------------------------------------------------------------------- |
|
|
28
|
+
| **Mail** | An agent-native Superhuman. Inbox, labels, AI triage, keyboard-first, with an agent that can draft and send. |
|
|
29
|
+
| **Calendar** | An agent-native Google Calendar. Events, sync, public booking links, agent-driven scheduling. |
|
|
30
|
+
| **Content** | An agent-native Notion / Google Docs. Markdown + Tiptap editor, Notion sync, multi-user real-time collab. |
|
|
31
|
+
| **Slides** | An agent-native Google Slides. React-based decks the agent generates and edits directly. |
|
|
32
|
+
| **Video** | An agent-native video editor built on Remotion. Prompt for a cut, the agent assembles it. |
|
|
33
|
+
| **Analytics** | An agent-native Amplitude/Mixpanel. Connect data sources, prompt for charts, pin to dashboards. |
|
|
34
|
+
| **Forms** | An agent-native Typeform. Build, share, and collect; agent handles the schema and analysis of submissions. |
|
|
35
|
+
| **Issues** | An agent-native Jira. Projects, issues, priorities, with the agent as your project manager. |
|
|
36
|
+
| **Recruiting** | An agent-native Greenhouse. Candidate pipelines, scoring, outreach drafts. |
|
|
37
|
+
| **Dispatch** | The **workspace control plane**: central secrets vault, cross-app integrations, Slack/Telegram, scheduled jobs. |
|
|
38
|
+
| **Starter** | The minimal scaffold. Agent chat + the six-rules architecture wired up, nothing else. Build from scratch. |
|
|
39
|
+
|
|
40
|
+
Additional templates in active development in the repo: **Clips** (screen recording + transcription), **Calls** (Gong-style conversation intelligence), **Scheduling** (a standalone scheduling app and reusable package).
|
|
41
|
+
|
|
42
|
+
## The clone → customize → deploy flow {#flow}
|
|
43
|
+
|
|
44
|
+
Every cloneable SaaS follows the same lifecycle:
|
|
45
|
+
|
|
46
|
+
### 1. Clone
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
pnpm dlx @agent-native/core create my-platform
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
The CLI shows a multi-select picker. Pick one app (standalone) or several (workspace — apps share auth, brand, agent config, and database). Each picked template is scaffolded into `apps/<name>/` with every file you need. See [Getting Started](/docs) for the full flow or [Enterprise Workspace](/docs/enterprise-workspace) for the workspace story.
|
|
53
|
+
|
|
54
|
+
### 2. Use it immediately
|
|
55
|
+
|
|
56
|
+
Every template is runnable the moment it scaffolds. Fill in `.env` (mostly `ANTHROPIC_API_KEY` and `DATABASE_URL`), `pnpm install`, `pnpm dev`, and it works. No "TODO: implement login," no placeholder routes.
|
|
57
|
+
|
|
58
|
+
### 3. Customize with the agent
|
|
59
|
+
|
|
60
|
+
The agent can modify code — components, routes, actions, styles, the schema. This is a feature, not a bug:
|
|
61
|
+
|
|
62
|
+
- "Change the inbox to group by sender instead of thread." _The agent edits the component._
|
|
63
|
+
- "Add a `leadScore` column to contacts and compute it from the last email." _The agent adds the Drizzle column, runs a migration, writes the scoring action._
|
|
64
|
+
- "Connect this to our internal HR API." _The agent writes the integration._
|
|
65
|
+
|
|
66
|
+
Every edit is normal Git-tracked code. Bad changes? Revert them. Good changes? Keep them. See [Self-Modifying Code](/docs/key-concepts#agent-modifies-code) for the full mental model.
|
|
67
|
+
|
|
68
|
+
### 4. Deploy anywhere
|
|
69
|
+
|
|
70
|
+
Agent-native apps run on any Nitro-compatible host (Node, Cloudflare, Netlify, Vercel, Deno, Lambda, Bun) and any Drizzle-compatible SQL database (SQLite, Postgres, Turso, D1, Supabase, Neon). The framework doesn't lock you in.
|
|
71
|
+
|
|
72
|
+
For workspaces, `agent-native deploy` builds every app at once and ships them behind a single origin — your own domain, your own cert, one command. See [Deployment](/docs/deployment).
|
|
73
|
+
|
|
74
|
+
### 5. Stay on `agent-native.com`, or self-host
|
|
75
|
+
|
|
76
|
+
You can also use these as hosted apps on the Builder-operated `agent-native.com` platform — `mail.agent-native.com`, `calendar.agent-native.com`, etc. — without forking. Fork only when you want to change something the hosted version doesn't let you change.
|
|
77
|
+
|
|
78
|
+
## Why this works {#why-this-works}
|
|
79
|
+
|
|
80
|
+
Cloneable SaaS wouldn't be practical in a traditional codebase. Every user forking their own inbox would mean every user maintaining their own inbox — no thanks.
|
|
81
|
+
|
|
82
|
+
Two framework decisions unlock it:
|
|
83
|
+
|
|
84
|
+
1. **Agents do the maintenance.** You don't write code to add a column or wire a new integration — you ask the agent. So "your own forked inbox" is a feature, not a burden, because the agent is doing the work.
|
|
85
|
+
2. **The workspace is SQL, not files.** Every user gets their own customization layer (skills, memory, instructions, connected MCP servers, sub-agents) without a dev-box. The shared codebase hosts all of them at once. See [Workspace](/docs/workspace).
|
|
86
|
+
|
|
87
|
+
Combined, you get Claude-Code-level flexibility per user, with SaaS-grade deployment economics.
|
|
88
|
+
|
|
89
|
+
## Authoring your own cloneable SaaS {#authoring}
|
|
90
|
+
|
|
91
|
+
Want to publish a new template — your own cloneable SaaS? See [Creating Templates](/docs/creating-templates). You can publish to `BuilderIO/agent-native` for inclusion in the CLI picker, or host elsewhere and scaffold with `--template github:user/repo`.
|
|
92
|
+
|
|
93
|
+
## What's next
|
|
94
|
+
|
|
95
|
+
- [**Enterprise Workspace**](/docs/enterprise-workspace) — bundle many cloneable-SaaS apps into one monorepo that shares auth, brand, and agent instructions
|
|
96
|
+
- [**Key Concepts**](/docs/key-concepts) — the architecture that makes this work
|
|
97
|
+
- [**Deployment**](/docs/deployment) — ship your forked app
|
|
98
|
+
- [**Creating Templates**](/docs/creating-templates) — author and publish a new cloneable SaaS
|
|
@@ -209,7 +209,7 @@ Keep your data models simple — flat JSON files, one per entity. The agent can
|
|
|
209
209
|
|
|
210
210
|
This is the most important file in your template. `AGENTS.md` tells the AI agent how your app works, what it can and can't do, and how to make changes:
|
|
211
211
|
|
|
212
|
-
|
|
212
|
+
```markdown
|
|
213
213
|
# My Template — Agent-Native App
|
|
214
214
|
|
|
215
215
|
## Architecture
|
|
@@ -226,12 +226,10 @@ This is an **@agent-native/core** application.
|
|
|
226
226
|
|
|
227
227
|
### Directory Structure
|
|
228
228
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
data/ # File-based state
|
|
234
|
-
```
|
|
229
|
+
app/ # React frontend (file-based routing in app/routes/)
|
|
230
|
+
server/ # Nitro API server
|
|
231
|
+
actions/ # Agent-callable actions
|
|
232
|
+
data/ # File-based state
|
|
235
233
|
|
|
236
234
|
### Available Actions
|
|
237
235
|
|
|
@@ -242,16 +240,16 @@ data/ # File-based state
|
|
|
242
240
|
|
|
243
241
|
Items are stored as `data/items/<id>.json`:
|
|
244
242
|
|
|
245
|
-
|
|
246
|
-
{ "id": "...", "title": "...", "status": "active" }
|
|
247
|
-
```
|
|
243
|
+
{ "id": "...", "title": "...", "status": "active" }
|
|
248
244
|
|
|
249
245
|
### Key Patterns
|
|
250
246
|
|
|
251
247
|
- API routes in `server/routes/` serve files from `data/`
|
|
252
248
|
- UI delegates AI work via `sendToAgentChat()`
|
|
253
249
|
- Actions write results to `data/` — SSE updates the UI
|
|
254
|
-
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
> Code blocks inside `AGENTS.md` would normally be fenced with triple backticks — they're shown as indented code here to keep this outer example readable.
|
|
255
253
|
|
|
256
254
|
Be specific about your data models, available actions, and key patterns. The better your `AGENTS.md`, the better the agent will work with your template.
|
|
257
255
|
|
|
@@ -221,17 +221,10 @@ export default defineConfig({
|
|
|
221
221
|
| `NITRO_PRESET` | Override build preset at build time |
|
|
222
222
|
| `ACCESS_TOKEN` | Enable auth gating for production mode |
|
|
223
223
|
| `ANTHROPIC_API_KEY` | API key for embedded production agent |
|
|
224
|
-
| `FILE_SYNC_ENABLED` | Enable file sync for multi-instance |
|
|
225
224
|
| `APP_BASE_PATH` | Mount the app under a prefix (e.g. `/mail`). Set automatically by `agent-native deploy`; leave unset for standalone. |
|
|
226
225
|
|
|
227
226
|
Inside a workspace, the root `.env` is loaded into every app automatically, so shared keys like `ANTHROPIC_API_KEY` and `A2A_SECRET` only need to be set once. Per-app `apps/<name>/.env` wins on conflict.
|
|
228
227
|
|
|
229
|
-
##
|
|
228
|
+
## Multi-instance deploys {#multi-instance}
|
|
230
229
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
```bash
|
|
234
|
-
FILE_SYNC_ENABLED=true
|
|
235
|
-
```
|
|
236
|
-
|
|
237
|
-
See [File Sync](/docs/file-sync) for adapter configuration (Firestore, Supabase, Convex).
|
|
230
|
+
Agent-native apps store all state in SQL via Drizzle and sync the UI via [polling](/docs/key-concepts#polling-sync) against the database — no file-system state, no sticky sessions, no in-memory caches. That means multi-instance and serverless deployments work out of the box: point every instance at the same `DATABASE_URL` and they converge automatically. See [Key Concepts — Data in SQL](/docs/key-concepts#data-in-sql) and [Portability](/docs/key-concepts#hosting-agnostic).
|