@agent-native/core 0.22.45 → 0.23.0
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/dist/a2a/artifact-response.js +1 -1
- package/dist/a2a/artifact-response.js.map +1 -1
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +12 -4
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/cli/app-skill.d.ts +139 -0
- package/dist/cli/app-skill.d.ts.map +1 -0
- package/dist/cli/app-skill.js +960 -0
- package/dist/cli/app-skill.js.map +1 -0
- package/dist/cli/create.d.ts.map +1 -1
- package/dist/cli/create.js +13 -4
- package/dist/cli/create.js.map +1 -1
- package/dist/cli/index.js +24 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/skills.d.ts +39 -0
- package/dist/cli/skills.d.ts.map +1 -0
- package/dist/cli/skills.js +363 -0
- package/dist/cli/skills.js.map +1 -0
- package/dist/cli/templates-meta.d.ts.map +1 -1
- package/dist/cli/templates-meta.js +9 -6
- package/dist/cli/templates-meta.js.map +1 -1
- package/dist/cli/workspace-dev.d.ts.map +1 -1
- package/dist/cli/workspace-dev.js +2 -0
- package/dist/cli/workspace-dev.js.map +1 -1
- package/dist/client/AgentPanel.d.ts +2 -0
- package/dist/client/AgentPanel.d.ts.map +1 -1
- package/dist/client/AgentPanel.js +2 -2
- package/dist/client/AgentPanel.js.map +1 -1
- package/dist/client/AssistantChat.d.ts +9 -0
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +15 -7
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
- package/dist/client/MultiTabAssistantChat.js +15 -0
- package/dist/client/MultiTabAssistantChat.js.map +1 -1
- package/dist/client/index.d.ts +1 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js.map +1 -1
- package/dist/client/use-chat-threads.d.ts +5 -1
- package/dist/client/use-chat-threads.d.ts.map +1 -1
- package/dist/client/use-chat-threads.js +14 -3
- package/dist/client/use-chat-threads.js.map +1 -1
- package/dist/deploy/workspace-deploy.js +6 -0
- package/dist/deploy/workspace-deploy.js.map +1 -1
- package/dist/mcp-client/index.d.ts +1 -1
- package/dist/mcp-client/index.d.ts.map +1 -1
- package/dist/mcp-client/index.js +1 -1
- package/dist/mcp-client/index.js.map +1 -1
- package/dist/mcp-client/routes.d.ts +1 -0
- package/dist/mcp-client/routes.d.ts.map +1 -1
- package/dist/mcp-client/routes.js +52 -0
- package/dist/mcp-client/routes.js.map +1 -1
- package/dist/mcp-client/workspace-servers.d.ts +15 -0
- package/dist/mcp-client/workspace-servers.d.ts.map +1 -0
- package/dist/mcp-client/workspace-servers.js +297 -0
- package/dist/mcp-client/workspace-servers.js.map +1 -0
- package/dist/resources/handlers.d.ts.map +1 -1
- package/dist/resources/handlers.js +38 -25
- package/dist/resources/handlers.js.map +1 -1
- package/dist/resources/store.d.ts +11 -3
- package/dist/resources/store.d.ts.map +1 -1
- package/dist/resources/store.js +220 -9
- package/dist/resources/store.js.map +1 -1
- package/dist/scripts/call-agent.js +1 -1
- package/dist/scripts/call-agent.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +21 -6
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/agent-discovery.d.ts.map +1 -1
- package/dist/server/agent-discovery.js +34 -9
- package/dist/server/agent-discovery.js.map +1 -1
- package/dist/server/auth-marketing.d.ts.map +1 -1
- package/dist/server/auth-marketing.js +8 -5
- package/dist/server/auth-marketing.js.map +1 -1
- package/dist/templates/default/AGENTS.md +12 -4
- package/dist/templates/default/DEVELOPING.md +7 -5
- package/dist/templates/workspace-core/AGENTS.md +7 -0
- package/dist/templates/workspace-root/AGENTS.md +6 -0
- package/docs/content/creating-templates.md +14 -9
- package/docs/content/database.md +44 -17
- package/docs/content/deployment.md +15 -7
- package/docs/content/dispatch.md +7 -1
- package/docs/content/embedding-sdk.md +79 -0
- package/docs/content/key-concepts.md +15 -17
- package/docs/content/mcp-clients.md +30 -0
- package/docs/content/multi-app-workspace.md +3 -2
- package/docs/content/multi-tenancy.md +4 -4
- package/docs/content/server.md +10 -7
- package/docs/content/skills-guide.md +75 -0
- package/docs/content/template-analytics.md +1 -1
- package/docs/content/template-assets.md +130 -0
- package/docs/content/template-dispatch.md +3 -2
- package/docs/content/template-slides.md +2 -2
- package/docs/content/workspace-management.md +2 -2
- package/docs/content/workspace.md +11 -9
- package/package.json +1 -1
- package/src/templates/default/AGENTS.md +12 -4
- package/src/templates/default/DEVELOPING.md +7 -5
- package/src/templates/workspace-core/AGENTS.md +7 -0
- package/src/templates/workspace-root/AGENTS.md +6 -0
- package/docs/content/template-images.md +0 -55
package/docs/content/database.md
CHANGED
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: "Database"
|
|
3
|
-
description: "Connect
|
|
3
|
+
description: "Connect a portable SQL database to your agent-native app and write provider-agnostic Drizzle code."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Database
|
|
7
7
|
|
|
8
|
-
Agent-native apps use [Drizzle ORM](https://orm.drizzle.team) and support
|
|
8
|
+
Agent-native apps use [Drizzle ORM](https://orm.drizzle.team) and support portable SQL backends. By default, apps use SQLite with a local file — set `DATABASE_URL` to connect a persistent production database.
|
|
9
9
|
|
|
10
10
|
## Default: SQLite {#default-sqlite}
|
|
11
11
|
|
|
12
12
|
When `DATABASE_URL` is not set, the app creates a SQLite database at `data/app.db`. This is great for local development — no setup required.
|
|
13
13
|
|
|
14
|
+
Do not rely on that local file for deployed apps. Containers, serverless functions, and preview environments may reset their filesystem, which means a local SQLite file can disappear between restarts. Set `DATABASE_URL` to a persistent hosted database before production use.
|
|
15
|
+
|
|
14
16
|
## Connecting a Production Database {#production}
|
|
15
17
|
|
|
16
|
-
Set `DATABASE_URL` in your `.env` file to connect a hosted database:
|
|
18
|
+
Set `DATABASE_URL` in your `.env` file or deploy-provider environment to connect a hosted database. Turso is not required; use whichever Drizzle-compatible SQL backend fits your deployment:
|
|
17
19
|
|
|
18
20
|
```bash
|
|
19
21
|
# Neon Postgres
|
|
@@ -27,18 +29,18 @@ DATABASE_URL=postgres://user:pass@localhost:5432/mydb
|
|
|
27
29
|
|
|
28
30
|
# Turso (libSQL)
|
|
29
31
|
DATABASE_URL=libsql://my-db-org.turso.io
|
|
30
|
-
|
|
32
|
+
DATABASE_AUTH_TOKEN=your-token
|
|
31
33
|
```
|
|
32
34
|
|
|
33
|
-
The framework auto-detects the dialect from the URL and configures Drizzle accordingly.
|
|
35
|
+
The framework auto-detects the dialect from the URL and configures Drizzle accordingly. The built-in adapters cover Postgres URLs, libSQL/Turso URLs, SQLite file URLs, and Cloudflare D1 bindings. Common production choices include Neon, Supabase, Turso/libSQL, plain Postgres, durable SQLite, and Builder.io-managed environments when available.
|
|
34
36
|
|
|
35
37
|
## Builder.io Managed Database {#builder-managed}
|
|
36
38
|
|
|
37
39
|
When connected to Builder.io, your app can use a managed database that is provisioned and scaled automatically. This is the simplest path to production — no connection strings or database admin required. Coming soon.
|
|
38
40
|
|
|
39
|
-
## Dialect-Agnostic Schema {#schema}
|
|
41
|
+
## Dialect-Agnostic Schema And Queries {#schema}
|
|
40
42
|
|
|
41
|
-
|
|
43
|
+
App database code should use Drizzle's schema and query DSL so it can run across providers. Never write SQLite-only syntax (`INSERT OR REPLACE`, `AUTOINCREMENT`, `datetime('now')`) or Postgres-only syntax in product code.
|
|
42
44
|
|
|
43
45
|
Use the framework's schema helpers from `@agent-native/core/db/schema`:
|
|
44
46
|
|
|
@@ -66,9 +68,29 @@ export const tasks = table("tasks", {
|
|
|
66
68
|
|
|
67
69
|
Never import from `drizzle-orm/sqlite-core` or `drizzle-orm/pg-core` directly. Always use `@agent-native/core/db/schema`.
|
|
68
70
|
|
|
69
|
-
|
|
71
|
+
For reads and writes, use Drizzle's query builder and portable operators from `drizzle-orm`:
|
|
72
|
+
|
|
73
|
+
```ts
|
|
74
|
+
import { and, desc, eq } from "drizzle-orm";
|
|
75
|
+
import { getDb } from "../server/db/index.js";
|
|
76
|
+
import { tasks } from "../server/db/schema.js";
|
|
77
|
+
|
|
78
|
+
const db = getDb();
|
|
79
|
+
|
|
80
|
+
const openTasks = await db
|
|
81
|
+
.select()
|
|
82
|
+
.from(tasks)
|
|
83
|
+
.where(and(eq(tasks.ownerEmail, userEmail), eq(tasks.done, false)))
|
|
84
|
+
.orderBy(desc(tasks.createdAt));
|
|
70
85
|
|
|
71
|
-
|
|
86
|
+
await db.update(tasks).set({ done: true }).where(eq(tasks.id, taskId));
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Raw SQL Escape Hatches {#raw-sql}
|
|
90
|
+
|
|
91
|
+
Raw SQL is not the default app-code API. Use it only for additive migrations, health checks, carefully reviewed advanced queries that Drizzle cannot express, or one-off maintenance. Keep it parameterized and dialect-agnostic. For timestamps in Drizzle schemas, prefer `.default(now())`; for migration SQL, use `runMigrations()` so framework-supported compatibility rewrites and dialect-gated statements stay centralized.
|
|
92
|
+
|
|
93
|
+
For cases where you truly need raw SQL outside of Drizzle queries:
|
|
72
94
|
|
|
73
95
|
- `getDbExec()` — auto-converts `?` params to `$1` for Postgres
|
|
74
96
|
- `isPostgres()` — runtime dialect check
|
|
@@ -97,15 +119,20 @@ Instead of pushing directly, schema changes should be applied via SQL migrations
|
|
|
97
119
|
```ts
|
|
98
120
|
import { runMigrations } from "@agent-native/core/db";
|
|
99
121
|
|
|
100
|
-
export default
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
122
|
+
export default runMigrations(
|
|
123
|
+
[
|
|
124
|
+
{
|
|
125
|
+
version: 1,
|
|
126
|
+
sql: `ALTER TABLE projects ADD COLUMN IF NOT EXISTS sort_order INTEGER NOT NULL DEFAULT 0`,
|
|
127
|
+
},
|
|
128
|
+
],
|
|
129
|
+
{ table: "my_app_migrations" },
|
|
130
|
+
);
|
|
104
131
|
```
|
|
105
132
|
|
|
106
133
|
## Environment Variables {#environment-variables}
|
|
107
134
|
|
|
108
|
-
| Variable
|
|
109
|
-
|
|
|
110
|
-
| `DATABASE_URL`
|
|
111
|
-
| `
|
|
135
|
+
| Variable | Purpose |
|
|
136
|
+
| --------------------- | ---------------------------------------------------------------------------------------------------- |
|
|
137
|
+
| `DATABASE_URL` | Persistent SQL connection string (unset = local SQLite, which is only durable for local development) |
|
|
138
|
+
| `DATABASE_AUTH_TOKEN` | Auth token for providers that require a separate token, such as Turso/libSQL |
|
|
@@ -7,6 +7,14 @@ description: "Deploy agent-native apps to any platform with Nitro presets — No
|
|
|
7
7
|
|
|
8
8
|
Agent-native apps use [Nitro](https://nitro.build) under the hood, which means you can deploy to any platform with zero config changes — just set a preset.
|
|
9
9
|
|
|
10
|
+
## Before You Deploy: Pick a Persistent Database {#persistent-database}
|
|
11
|
+
|
|
12
|
+
Every deployed app needs a persistent SQL database. In local development, agent-native falls back to a SQLite file at `data/app.db`; that is convenient on your machine, but it is not durable in containers, previews, or serverless environments where the filesystem can be reset.
|
|
13
|
+
|
|
14
|
+
Set `DATABASE_URL` in your deploy provider before promoting an app to production. Agent-native uses Drizzle for schema and queries, so the data layer is portable across Drizzle-compatible SQL backends. The built-in adapters auto-detect Postgres URLs, libSQL/Turso URLs, SQLite file URLs, and Cloudflare D1 bindings. Common choices include Neon or Supabase Postgres, Turso/libSQL, plain Postgres, durable SQLite, and Builder.io-managed environments when available. Turso is one option, not a requirement.
|
|
15
|
+
|
|
16
|
+
Use `DATABASE_AUTH_TOKEN` only when your database provider requires a separate token, such as Turso/libSQL. For workspaces, all apps inherit the root `DATABASE_URL` by default; set `<APP_NAME>_DATABASE_URL` when one app should use a different database.
|
|
17
|
+
|
|
10
18
|
## Workspace Deploy: One Origin, Many Apps {#workspace-deploy}
|
|
11
19
|
|
|
12
20
|
If your project is a [workspace](/docs/multi-app-workspace), you can ship every app in it to a single origin with one command:
|
|
@@ -200,13 +208,13 @@ export default defineConfig({
|
|
|
200
208
|
|
|
201
209
|
### Build / Runtime {#env-runtime}
|
|
202
210
|
|
|
203
|
-
| Variable | Description
|
|
204
|
-
| --------------------- |
|
|
205
|
-
| `PORT` | Server port (Node.js only)
|
|
206
|
-
| `NITRO_PRESET` | Override build preset at build time
|
|
207
|
-
| `APP_BASE_PATH` | Mount the app under a prefix (e.g. `/mail`). Set automatically by `agent-native deploy`; leave unset for standalone.
|
|
208
|
-
| `DATABASE_URL` |
|
|
209
|
-
| `DATABASE_AUTH_TOKEN` | Auth token for
|
|
211
|
+
| Variable | Description |
|
|
212
|
+
| --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
213
|
+
| `PORT` | Server port (Node.js only) |
|
|
214
|
+
| `NITRO_PRESET` | Override build preset at build time |
|
|
215
|
+
| `APP_BASE_PATH` | Mount the app under a prefix (e.g. `/mail`). Set automatically by `agent-native deploy`; leave unset for standalone. |
|
|
216
|
+
| `DATABASE_URL` | Persistent SQL connection string. Required in production; common options include Neon, Supabase, Turso/libSQL, plain Postgres, durable SQLite, and Builder.io-managed environments when available. |
|
|
217
|
+
| `DATABASE_AUTH_TOKEN` | Auth token for providers that require a separate token, such as Turso/libSQL. |
|
|
210
218
|
|
|
211
219
|
### Required in Production {#env-required-prod}
|
|
212
220
|
|
package/docs/content/dispatch.md
CHANGED
|
@@ -19,7 +19,7 @@ Reach for Dispatch when any of these are true:
|
|
|
19
19
|
- You want **one inbox for "the agent"** so users DM a single bot and the right specialist app picks up the work behind the scenes.
|
|
20
20
|
- You have **workspace-wide secrets** (Stripe key, OpenAI key, third-party API tokens) that several apps need and you want one vault instead of copying values into every `.env`.
|
|
21
21
|
- You want a **runtime approval flow** in front of sensitive changes (saved destinations, policy edits) so non-admins can request and admins can sign off without a code deploy.
|
|
22
|
-
- You want **shared skills, instructions, and
|
|
22
|
+
- You want **shared skills, instructions, agent profiles, and MCP servers** that apps in the workspace inherit — change once, reach all.
|
|
23
23
|
|
|
24
24
|
If you're running a single template standalone, you don't need Dispatch — each template can wire its own messaging integrations directly. See [Messaging](/docs/messaging) for the standalone setup.
|
|
25
25
|
|
|
@@ -76,6 +76,7 @@ Use the canonical paths to control how agents consume them:
|
|
|
76
76
|
- `skills/<slug>/SKILL.md` for on-demand skills available through `/` commands and the prompt skill index
|
|
77
77
|
- `context/<slug>.md` for brand, persona, positioning, messaging, company facts, and other reference material the agent reads when relevant
|
|
78
78
|
- `agents/<slug>.md` for reusable custom agent profiles
|
|
79
|
+
- `mcp-servers/<slug>.json` for HTTP MCP servers that should add external tools to granted app agents
|
|
79
80
|
|
|
80
81
|
Starter global resources usually look like:
|
|
81
82
|
|
|
@@ -89,6 +90,11 @@ skills/company-voice/SKILL.md
|
|
|
89
90
|
|
|
90
91
|
Set these to **All apps** when every app should inherit the same company facts, brand rules, messaging, safety constraints, and customer-facing writing style. Use selected-app grants only for resources that are genuinely app-specific.
|
|
91
92
|
|
|
93
|
+
MCP server resources use JSON and are intentionally HTTP-only. Store tokens in
|
|
94
|
+
Dispatch Vault, grant or sync those keys to the target apps, and reference them
|
|
95
|
+
from headers with `${keys.NAME}` so the raw credential never lives in the
|
|
96
|
+
resource body.
|
|
97
|
+
|
|
92
98
|
The **Resources** page highlights this starter pack in a Global context section so admins can quickly see which files exist, whether they are scoped to all apps, restore missing starter files without overwriting existing ones, and edit their contents. Expand any resource to preview its effective runtime stack for a selected app/user: workspace default, organization/app override, then personal override. Each app card also has a **Context** view that shows exactly what that app receives: inherited workspace resources, selected grants, and auto-loaded instructions. Use a resource row's **Stack** control to inspect which layer wins for that app.
|
|
93
99
|
|
|
94
100
|
This is how a team-wide change ("always use British English in customer-facing replies") or a shared brand guideline propagates without editing ten repos.
|
|
@@ -14,6 +14,85 @@ Use it when you want an assistant that can:
|
|
|
14
14
|
- Ask the host app to navigate, refresh data, remount a view, or open a resource after durable work completes.
|
|
15
15
|
- Run as an iframe/sidebar now, while leaving room for a no-iframe package or hosted template later.
|
|
16
16
|
|
|
17
|
+
## Embedded App And Picker Mode
|
|
18
|
+
|
|
19
|
+
Use `@agent-native/embedding` when the host product wants to launch a complete
|
|
20
|
+
Agent-Native app as a focused iframe surface: an asset picker, asset generator,
|
|
21
|
+
form builder, calendar slot picker, approval panel, or any other task-specific
|
|
22
|
+
workflow. This is intentionally smaller than the sidecar host bridge below: the
|
|
23
|
+
iframe announces readiness, the host can send named messages, and the embedded
|
|
24
|
+
app can emit domain events such as `chooseAsset` or `close`.
|
|
25
|
+
|
|
26
|
+
```tsx
|
|
27
|
+
import { EmbeddedApp } from "@agent-native/embedding";
|
|
28
|
+
|
|
29
|
+
export function AssetPickerDialog({ close }) {
|
|
30
|
+
return (
|
|
31
|
+
<EmbeddedApp
|
|
32
|
+
url="https://assets.agent-native.com/picker"
|
|
33
|
+
className="h-full w-full"
|
|
34
|
+
onLoad={(ref) => {
|
|
35
|
+
ref.postMessage("configure", {
|
|
36
|
+
prompt: "Editorial blog hero",
|
|
37
|
+
aspectRatio: "16:9",
|
|
38
|
+
});
|
|
39
|
+
}}
|
|
40
|
+
onMessage={(name, payload) => {
|
|
41
|
+
if (name === "chooseAsset") {
|
|
42
|
+
const asset = payload as { url: string; altText?: string };
|
|
43
|
+
insertAsset(asset.url, asset.altText);
|
|
44
|
+
close();
|
|
45
|
+
}
|
|
46
|
+
if (name === "close") close();
|
|
47
|
+
}}
|
|
48
|
+
/>
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Inside the embedded app, use the browser bridge to announce readiness and send
|
|
54
|
+
events back to the host:
|
|
55
|
+
|
|
56
|
+
```ts
|
|
57
|
+
import {
|
|
58
|
+
announceEmbeddedAppReady,
|
|
59
|
+
sendEmbeddedAppMessage,
|
|
60
|
+
} from "@agent-native/embedding/bridge";
|
|
61
|
+
|
|
62
|
+
announceEmbeddedAppReady({ app: "assets", mode: "picker" });
|
|
63
|
+
sendEmbeddedAppMessage("chooseAsset", {
|
|
64
|
+
url: asset.previewUrl,
|
|
65
|
+
assetId: asset.id,
|
|
66
|
+
altText: asset.altText,
|
|
67
|
+
});
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Assets also emits `chooseImage` as a compatibility alias for older image-picker
|
|
71
|
+
hosts; new integrations should listen for `chooseAsset`.
|
|
72
|
+
|
|
73
|
+
For hosted first-party apps, enable Cross-App SSO with Dispatch as the identity
|
|
74
|
+
hub so `content.agent-native.com` and `assets.agent-native.com` link users by
|
|
75
|
+
verified email. Iframe launches should still use short-lived, route-scoped
|
|
76
|
+
embed sessions when they need third-party-cookie resilience; normal app cookies
|
|
77
|
+
are not a complete embed auth story on their own.
|
|
78
|
+
|
|
79
|
+
The same package includes agent endpoint helpers for protocol discovery and
|
|
80
|
+
streaming text over A2A:
|
|
81
|
+
|
|
82
|
+
```ts
|
|
83
|
+
import { getA2AUrl, getMcpUrl, sendMessage } from "@agent-native/embedding";
|
|
84
|
+
|
|
85
|
+
getMcpUrl("https://assets.agent-native.com");
|
|
86
|
+
getA2AUrl("https://assets.agent-native.com");
|
|
87
|
+
|
|
88
|
+
for await (const chunk of sendMessage(
|
|
89
|
+
"https://assets.agent-native.com",
|
|
90
|
+
"Generate a blog hero",
|
|
91
|
+
)) {
|
|
92
|
+
append(chunk);
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
17
96
|
## Batteries-Included Embedded Mode
|
|
18
97
|
|
|
19
98
|
For most SaaS hosts, use the full embedded runtime. The host mounts Agent-Native server routes into its existing app, passes its logged-in user to Agent-Native, and then renders the React sidebar/surface in the product UI. Agent-Native uses the host deployment, host session, and the configured `DATABASE_URL` to manage its own framework tables: chat threads, settings, application state, extensions, extension data, secrets, browser sessions, and action routes.
|
|
@@ -96,10 +96,10 @@ export const forms = table("forms", {
|
|
|
96
96
|
```
|
|
97
97
|
|
|
98
98
|
```bash
|
|
99
|
-
# Core actions for quick database
|
|
99
|
+
# Core actions for quick database inspection and one-off maintenance
|
|
100
100
|
pnpm action db-schema # show all tables
|
|
101
101
|
pnpm action db-query --sql "SELECT * FROM forms"
|
|
102
|
-
pnpm action db-exec --sql "
|
|
102
|
+
pnpm action db-exec --sql "UPDATE forms SET status = ? WHERE id = ?" --args '["closed","form-1"]'
|
|
103
103
|
# Surgical find/replace on a large text column — sends a diff, not the whole value
|
|
104
104
|
pnpm action db-patch --table documents --column content \
|
|
105
105
|
--where "id='doc-1'" --find "old heading" --replace "new heading"
|
|
@@ -227,7 +227,7 @@ There's no shared codebase to break. You own the app, and the agent evolves it f
|
|
|
227
227
|
|
|
228
228
|
## Database agnostic {#database-agnostic}
|
|
229
229
|
|
|
230
|
-
The framework supports
|
|
230
|
+
The framework supports portable Drizzle-backed SQL databases. Write app schemas with `@agent-native/core/db/schema` and app reads/writes with Drizzle's query builder so code can run across providers.
|
|
231
231
|
|
|
232
232
|
- **SQLite** — local dev fallback when `DATABASE_URL` is unset
|
|
233
233
|
- **Neon Postgres** — common in both dev and production
|
|
@@ -236,24 +236,22 @@ The framework supports every Drizzle-supported database. Never write SQL that on
|
|
|
236
236
|
- **Cloudflare D1**
|
|
237
237
|
- **Plain Postgres**
|
|
238
238
|
|
|
239
|
-
Use
|
|
239
|
+
Use Drizzle's portable query DSL for normal app code:
|
|
240
240
|
|
|
241
241
|
```ts
|
|
242
|
-
import {
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
// Branch when syntax differs
|
|
252
|
-
const upsert = isPostgres()
|
|
253
|
-
? "INSERT INTO settings (key, value) VALUES ($1, $2) ON CONFLICT (key) DO UPDATE SET value = $2"
|
|
254
|
-
: "INSERT OR REPLACE INTO settings (key, value) VALUES (?, ?)";
|
|
242
|
+
import { and, desc, eq } from "drizzle-orm";
|
|
243
|
+
|
|
244
|
+
const forms = await db
|
|
245
|
+
.select()
|
|
246
|
+
.from(schema.forms)
|
|
247
|
+
.where(
|
|
248
|
+
and(eq(schema.forms.ownerEmail, email), eq(schema.forms.status, "open")),
|
|
249
|
+
)
|
|
250
|
+
.orderBy(desc(schema.forms.createdAt));
|
|
255
251
|
```
|
|
256
252
|
|
|
253
|
+
Use raw SQL only for additive migrations, health checks, or one-off maintenance, and keep it parameterized and dialect-agnostic.
|
|
254
|
+
|
|
257
255
|
## Hosting agnostic {#hosting-agnostic}
|
|
258
256
|
|
|
259
257
|
The server runs on Nitro, which compiles to any deployment target:
|
|
@@ -159,6 +159,36 @@ If your workspace runs multiple agent-native apps (e.g. dispatch + mail + clips)
|
|
|
159
159
|
|
|
160
160
|
Dispatch is the conventional hub — it already coordinates across apps.
|
|
161
161
|
|
|
162
|
+
For new workspace setups, prefer **Dispatch workspace MCP resources** when you
|
|
163
|
+
want the same All-app vs selected-app grant model used by workspace skills,
|
|
164
|
+
instructions, and reference resources. Add a workspace resource with:
|
|
165
|
+
|
|
166
|
+
```json
|
|
167
|
+
{
|
|
168
|
+
"type": "http",
|
|
169
|
+
"url": "https://example.com/mcp",
|
|
170
|
+
"headers": {
|
|
171
|
+
"Authorization": "Bearer ${keys.MCP_SERVER_TOKEN}"
|
|
172
|
+
},
|
|
173
|
+
"description": "Shared MCP tools for workspace apps"
|
|
174
|
+
}
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
Save it under `mcp-servers/<name>.json` with kind `mcp-server`. All-app
|
|
178
|
+
resources are loaded by every workspace app; selected resources load only in
|
|
179
|
+
apps with an active Dispatch grant. Secret placeholders resolve from the app
|
|
180
|
+
secret store, so put raw bearer tokens in Dispatch Vault and reference them
|
|
181
|
+
with `${keys.NAME}` instead of storing them in the resource body.
|
|
182
|
+
|
|
183
|
+
Apps refresh their merged MCP config about once a minute, so central resource
|
|
184
|
+
edits, grant changes, and removals take effect without a deploy. Set
|
|
185
|
+
`AGENT_NATIVE_MCP_CONFIG_REFRESH_MS=0` to disable that background refresh, or
|
|
186
|
+
set it to a value of at least `5000` milliseconds to tune the interval.
|
|
187
|
+
|
|
188
|
+
The older hub mode below remains useful for coarse “share every org-scope MCP
|
|
189
|
+
server from Dispatch” setups and for deployments that already use the MCP
|
|
190
|
+
settings UI as the source of truth.
|
|
191
|
+
|
|
162
192
|
### 1. Enable hub-serve on the hub app (dispatch)
|
|
163
193
|
|
|
164
194
|
Set an env var in dispatch's deployment:
|
|
@@ -141,7 +141,7 @@ Use `packages/shared` for code-level defaults that should ship with the repo: pl
|
|
|
141
141
|
Dispatch resources support two scopes:
|
|
142
142
|
|
|
143
143
|
- **All apps** — global resources for every app in the workspace. Dispatch stores them once at workspace scope and every app agent inherits them at runtime; no copy or sync step is required.
|
|
144
|
-
- **Selected apps** — resources granted per app for app-specific context. Use these sparingly; most company, brand, persona, positioning, messaging, and guardrail context should be All apps.
|
|
144
|
+
- **Selected apps** — resources granted per app for app-specific context or tools. Use these sparingly; most company, brand, persona, positioning, messaging, and guardrail context should be All apps.
|
|
145
145
|
|
|
146
146
|
Canonical paths control behavior:
|
|
147
147
|
|
|
@@ -151,8 +151,9 @@ Canonical paths control behavior:
|
|
|
151
151
|
| Global skills | `skills/<slug>/SKILL.md` | Listed as workspace skills and read on demand |
|
|
152
152
|
| Brand/company resources | `context/<slug>.md` | Indexed every turn, read when relevant |
|
|
153
153
|
| Custom agent profiles | `agents/<slug>.md` | Available as reusable local agent profiles |
|
|
154
|
+
| Shared HTTP MCP servers | `mcp-servers/<slug>.json` | Loaded into granted apps' MCP tool registry |
|
|
154
155
|
|
|
155
|
-
This is the right home for core personas, positioning, messaging, company facts, brand guidelines, support policies, or
|
|
156
|
+
This is the right home for core personas, positioning, messaging, company facts, brand guidelines, support policies, shared skills, or shared HTTP MCP tools that many apps should benefit from.
|
|
156
157
|
|
|
157
158
|
For a starter workspace, create these Dispatch resources and scope them to **All apps**:
|
|
158
159
|
|
|
@@ -54,15 +54,15 @@ For full details on how scoping works at the SQL level, see [Security & Data Sco
|
|
|
54
54
|
|
|
55
55
|
## Adding multi-tenancy to a new table {#new-tables}
|
|
56
56
|
|
|
57
|
-
When you add a new domain table, include
|
|
57
|
+
When you add a new domain table, use the framework's dialect-agnostic schema helpers and include ownership columns to make it tenant-aware:
|
|
58
58
|
|
|
59
59
|
```typescript
|
|
60
|
-
import {
|
|
60
|
+
import { table, text, ownableColumns } from "@agent-native/core/db/schema";
|
|
61
61
|
|
|
62
|
-
export const projects =
|
|
62
|
+
export const projects = table("projects", {
|
|
63
63
|
id: text("id").primaryKey(),
|
|
64
64
|
title: text("title").notNull(),
|
|
65
|
-
|
|
65
|
+
...ownableColumns(),
|
|
66
66
|
// ... other columns
|
|
67
67
|
});
|
|
68
68
|
```
|
package/docs/content/server.md
CHANGED
|
@@ -94,20 +94,23 @@ Plugins live in `server/plugins/` and run at startup. Use them for migrations, p
|
|
|
94
94
|
|
|
95
95
|
```ts
|
|
96
96
|
// server/plugins/db.ts
|
|
97
|
-
import { runMigrations } from "@agent-native/core/db
|
|
97
|
+
import { runMigrations } from "@agent-native/core/db";
|
|
98
98
|
|
|
99
|
-
export default runMigrations(
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
99
|
+
export default runMigrations(
|
|
100
|
+
[
|
|
101
|
+
{
|
|
102
|
+
version: 1,
|
|
103
|
+
sql: `CREATE TABLE IF NOT EXISTS projects (
|
|
103
104
|
id TEXT PRIMARY KEY,
|
|
104
105
|
title TEXT NOT NULL,
|
|
105
106
|
owner_email TEXT NOT NULL,
|
|
106
107
|
org_id TEXT,
|
|
107
108
|
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
|
|
108
109
|
)`,
|
|
109
|
-
|
|
110
|
-
]
|
|
110
|
+
},
|
|
111
|
+
],
|
|
112
|
+
{ table: "my_app_migrations" },
|
|
113
|
+
);
|
|
111
114
|
```
|
|
112
115
|
|
|
113
116
|
Migrations must be additive. Never put destructive SQL in startup plugins.
|
|
@@ -42,6 +42,81 @@ Templates include skills specific to their domain. These live in the same `.agen
|
|
|
42
42
|
|
|
43
43
|
Domain skills follow the same format as framework skills. They encode patterns specific to the template that the agent needs to follow.
|
|
44
44
|
|
|
45
|
+
## App-backed skills {#app-backed-skills}
|
|
46
|
+
|
|
47
|
+
App-backed skills package an agent-native app as a skill marketplace artifact.
|
|
48
|
+
The bundle can include agent instructions, exported skills, MCP connector
|
|
49
|
+
metadata, hosted/local launch instructions, and UI surfaces such as MCP Apps.
|
|
50
|
+
|
|
51
|
+
Each app-backed skill starts with `agent-native.app-skill.json` at the app root:
|
|
52
|
+
|
|
53
|
+
```json
|
|
54
|
+
{
|
|
55
|
+
"schemaVersion": 1,
|
|
56
|
+
"id": "assets",
|
|
57
|
+
"hosted": {
|
|
58
|
+
"url": "https://assets.agent-native.com",
|
|
59
|
+
"mcpUrl": "https://assets.agent-native.com/_agent-native/mcp"
|
|
60
|
+
},
|
|
61
|
+
"mcp": { "serverName": "agent-native-assets" },
|
|
62
|
+
"skills": [
|
|
63
|
+
{
|
|
64
|
+
"path": ".agents/skills/asset-generation",
|
|
65
|
+
"visibility": "both",
|
|
66
|
+
"exportAs": "assets"
|
|
67
|
+
}
|
|
68
|
+
]
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Skill visibility controls what ships:
|
|
73
|
+
|
|
74
|
+
| Visibility | Meaning |
|
|
75
|
+
| ---------- | --------------------------------------------------------------- |
|
|
76
|
+
| `internal` | Used by the app's own agent, not exported to marketplaces. |
|
|
77
|
+
| `exported` | Exported to marketplaces, but not needed by the app internally. |
|
|
78
|
+
| `both` | Used internally and exported. |
|
|
79
|
+
|
|
80
|
+
Hosted is the default install path. Local launch is explicit for customization,
|
|
81
|
+
offline work, or privacy-sensitive use.
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
# One-command hosted install for the exported Assets skill plus MCP connector.
|
|
85
|
+
npx @agent-native/core@latest skills add assets
|
|
86
|
+
|
|
87
|
+
# Register the hosted MCP connector for local agent clients.
|
|
88
|
+
agent-native app-skill ensure --manifest templates/assets/agent-native.app-skill.json
|
|
89
|
+
|
|
90
|
+
# Materialize and run editable local source.
|
|
91
|
+
agent-native app-skill launch --manifest templates/assets/agent-native.app-skill.json --local --into ./assets-local
|
|
92
|
+
|
|
93
|
+
# Build marketplace adapters: Codex plugin, Claude marketplace, Vercel skills,
|
|
94
|
+
# plain/Claude skills, and MCP configs.
|
|
95
|
+
agent-native app-skill pack --manifest templates/assets/agent-native.app-skill.json --out ./dist/assets-skill
|
|
96
|
+
|
|
97
|
+
# Install the exported skill with the open skills CLI.
|
|
98
|
+
npx skills add ./dist/assets-skill --skill assets -a codex -y
|
|
99
|
+
|
|
100
|
+
# Add the generated Claude Code marketplace, then install its Assets plugin.
|
|
101
|
+
claude plugin marketplace add ./dist/assets-skill/adapters/claude-marketplace
|
|
102
|
+
claude plugin install agent-native-assets@agent-native-apps
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Keep secrets out of skill files. The manifest should contain URL-only connector
|
|
106
|
+
metadata; OAuth/device setup happens in the MCP host or through the app's normal
|
|
107
|
+
settings flow.
|
|
108
|
+
|
|
109
|
+
The Vercel Labs `skills` adapter is a portable `skills/<name>/SKILL.md` bundle
|
|
110
|
+
for `npx skills add ...`. For first-party hosted apps, prefer
|
|
111
|
+
`agent-native skills add assets`; it installs the skill instructions and runs
|
|
112
|
+
the MCP registration step together.
|
|
113
|
+
|
|
114
|
+
The Claude Code marketplace adapter writes
|
|
115
|
+
`adapters/claude-marketplace/.claude-plugin/marketplace.json` plus a nested
|
|
116
|
+
plugin directory containing `skills/<name>/SKILL.md` and `.mcp.json`. In Claude
|
|
117
|
+
Code, add the marketplace, install `agent-native-assets@agent-native-apps`,
|
|
118
|
+
reload plugins, then authenticate the URL-only MCP connector from `/mcp`.
|
|
119
|
+
|
|
45
120
|
## Creating custom skills {#creating-skills}
|
|
46
121
|
|
|
47
122
|
Create a skill when:
|
|
@@ -165,7 +165,7 @@ Credentials are stored via the framework's settings/env layer — no secrets in
|
|
|
165
165
|
|
|
166
166
|
| Variable | Purpose |
|
|
167
167
|
| ---------------------------------------- | ----------------------------- |
|
|
168
|
-
| `DATABASE_URL` |
|
|
168
|
+
| `DATABASE_URL` | Persistent SQL connection URL |
|
|
169
169
|
| `BETTER_AUTH_SECRET` / `BETTER_AUTH_URL` | Auth |
|
|
170
170
|
| `GOOGLE_CLIENT_ID` / `_SECRET` | Google sign-in (OAuth 2.0) |
|
|
171
171
|
| `BIGQUERY_PROJECT_ID` | BigQuery project |
|