@agent-native/core 0.7.52 → 0.7.53

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.
@@ -31,11 +31,15 @@ Connect your agent to Slack, email, Telegram, or WhatsApp so you can chat with i
31
31
  - `chat:write` — lets the agent send messages
32
32
  - `app_mentions:read` — lets the agent see when it's @-mentioned (optional)
33
33
  - `im:history` — lets the agent read DMs sent to it
34
+ - `assistant:write` — optional; lets Slack show native "is thinking..." status in assistant threads
35
+ - `users:read.email` — optional; helps templates such as Mail verify Slack sender email for draft-queue identity
34
36
  3. Click **Install to Workspace** at the top of that page. Slack will give you a **Bot User OAuth Token** that starts with `xoxb-`. Copy it.
35
37
  4. Go to **Basic Information** in the sidebar and copy the **Signing Secret**.
36
38
  5. Open your app's settings (or your hosting provider's environment variable panel) and paste:
37
39
  - `SLACK_BOT_TOKEN` — the `xoxb-…` token
38
40
  - `SLACK_SIGNING_SECRET` — the signing secret
41
+ - `SLACK_ALLOWED_TEAM_IDS` — recommended in production; comma-separated Slack workspace/team IDs allowed to send events
42
+ - `SLACK_ALLOWED_API_APP_IDS` — recommended for multi-workspace apps; comma-separated Slack app IDs allowed to use this signing secret
39
43
  6. Back in Slack, open **Event Subscriptions**, toggle it on, and paste this Request URL:
40
44
 
41
45
  ```text
@@ -51,6 +55,7 @@ Connect your agent to Slack, email, Telegram, or WhatsApp so you can chat with i
51
55
  - **Channel mentions** — the bot only responds in channels when it's @-mentioned, to avoid noise.
52
56
  - **DMs** — every DM is treated as a private conversation with the agent.
53
57
  - **Same identity, all channels** — if a Slack user has the same email as a registered user in your app, the agent treats them as the same person.
58
+ - **Production allowlists** — set `SLACK_ALLOWED_TEAM_IDS` and, for shared Slack apps, `SLACK_ALLOWED_API_APP_IDS` so a valid signing secret cannot be reused by an unexpected workspace.
54
59
 
55
60
  ## Set up Telegram {#telegram}
56
61
 
@@ -252,12 +257,12 @@ POST /_agent-native/integrations/telegram/setup
252
257
 
253
258
  ### Environment variables {#env-vars}
254
259
 
255
- | Platform | Required | Optional |
256
- | -------- | ---------------------------------------------------------------------------- | ------------------------------ |
257
- | Slack | `SLACK_BOT_TOKEN`, `SLACK_SIGNING_SECRET` | |
258
- | Telegram | `TELEGRAM_BOT_TOKEN` | — |
259
- | Email | `EMAIL_AGENT_ADDRESS`, plus one of `RESEND_API_KEY` or `SENDGRID_API_KEY` | `EMAIL_INBOUND_WEBHOOK_SECRET` |
260
- | WhatsApp | `WHATSAPP_ACCESS_TOKEN`, `WHATSAPP_VERIFY_TOKEN`, `WHATSAPP_PHONE_NUMBER_ID` | — |
260
+ | Platform | Required | Optional |
261
+ | -------- | ---------------------------------------------------------------------------- | ----------------------------------------------------- |
262
+ | Slack | `SLACK_BOT_TOKEN`, `SLACK_SIGNING_SECRET` | `SLACK_ALLOWED_TEAM_IDS`, `SLACK_ALLOWED_API_APP_IDS` |
263
+ | Telegram | `TELEGRAM_BOT_TOKEN` | — |
264
+ | Email | `EMAIL_AGENT_ADDRESS`, plus one of `RESEND_API_KEY` or `SENDGRID_API_KEY` | `EMAIL_INBOUND_WEBHOOK_SECRET` |
265
+ | WhatsApp | `WHATSAPP_ACCESS_TOKEN`, `WHATSAPP_VERIFY_TOKEN`, `WHATSAPP_PHONE_NUMBER_ID` | — |
261
266
 
262
267
  All credentials live in env vars — never the database, never source code. Use the sidebar settings UI or your hosting provider's env panel.
263
268
 
@@ -5,7 +5,7 @@ description: "Host many agent-native apps in one monorepo with shared auth, RBAC
5
5
 
6
6
  # Multi-App Workspaces
7
7
 
8
- > For what a workspace _is_ — the customization layer, AGENTS.md, learnings.md, skills, custom agents — see [Workspace](/docs/workspace). This page is about the **deployment shape**: hosting many agent-native apps in one monorepo with shared auth, components, and a unified deploy.
8
+ > For what a workspace _is_ — the customization layer, `AGENTS.md`, `LEARNINGS.md`, personal memory, skills, and custom agents — see [Workspace](/docs/workspace). This page is about the **deployment shape**: hosting many agent-native apps in one monorepo with shared auth, components, and a unified deploy.
9
9
 
10
10
  When vibe-coding an internal tool takes an afternoon, you don't stop at one. A team ends up with a CRM, a support inbox, a dashboard, a recruiting tracker, an ops console — ten small apps, each scaffolded independently. That's great until you need to change something in all of them.
11
11
 
@@ -244,6 +244,6 @@ The workspace pattern is intentionally narrow. A few things it deliberately does
244
244
 
245
245
  ## See also {#see-also}
246
246
 
247
- - [Workspace](/docs/workspace) — the customization layer (AGENTS.md, learnings.md, skills, custom agents) every app in the workspace shares.
247
+ - [Workspace](/docs/workspace) — the customization layer (`AGENTS.md`, `LEARNINGS.md`, personal memory, skills, custom agents) every app in the workspace shares.
248
248
  - [Workspace Governance](/docs/workspace-management) — branching, CODEOWNERS, PR review across many apps in one repo.
249
249
  - [Dispatch](/docs/dispatch) — the runtime control plane that typically lives inside a multi-app workspace as the secrets vault, integration catalog, and approvals hub.
@@ -1,200 +1,184 @@
1
1
  ---
2
2
  title: "Server"
3
- description: "Nitro server layer with file-based routing, server plugins, SSE handlers, and production agent configuration."
3
+ description: "Nitro server routes, plugins, framework-mounted routes, request context, and SQL-backed sync."
4
4
  ---
5
5
 
6
6
  # Server
7
7
 
8
- Agent-native apps use [Nitro](https://nitro.build) for the server layer. Nitro is included automatically via the `defineConfig()` Vite plugin you get file-based API routing, server plugins, and deploy-anywhere presets out of the box.
8
+ Agent-native apps use [Nitro](https://nitro.build) for server routes and plugins. Most product behavior should live in [Actions](/docs/actions); custom routes are for protocol surfaces that actions do not fit: uploads, streaming, public pages, webhooks, OAuth callbacks, and provider-specific APIs.
9
9
 
10
- ## File-Based Routing {#file-based-routing}
10
+ ## File-Based Routes {#file-based-routes}
11
11
 
12
- API routes live in `server/routes/`. Nitro auto-discovers them based on file name and path:
12
+ Routes live in `server/routes/` and Nitro maps filenames to methods and paths:
13
13
 
14
14
  ```text
15
15
  server/routes/
16
16
  api/
17
- hello.get.ts GET /api/hello
18
- items/
19
- index.get.ts → GET /api/items
20
- index.post.ts POST /api/items
21
- [id].get.ts GET /api/items/:id
22
- [id].delete.ts → DELETE /api/items/:id
23
- [id]/
24
- archive.patch.ts → PATCH /api/items/:id/archive
17
+ health.get.ts -> GET /api/health
18
+ uploads.post.ts -> POST /api/uploads
19
+ webhooks/
20
+ stripe.post.ts -> POST /api/webhooks/stripe
21
+ [...page].get.ts -> SSR catch-all for public pages
25
22
  ```
26
23
 
27
- Each route file exports a default `defineEventHandler`:
24
+ Each route exports a `defineEventHandler`:
28
25
 
29
26
  ```ts
30
- // server/routes/api/items/index.get.ts
27
+ // server/routes/api/health.get.ts
31
28
  import { defineEventHandler } from "h3";
32
- import fs from "fs/promises";
33
-
34
- export default defineEventHandler(async () => {
35
- const files = await fs.readdir("./data/items");
36
- const items = await Promise.all(
37
- files
38
- .filter((f) => f.endsWith(".json"))
39
- .map(async (f) =>
40
- JSON.parse(await fs.readFile(`./data/items/${f}`, "utf-8")),
41
- ),
42
- );
43
- return items;
44
- });
29
+
30
+ export default defineEventHandler(() => ({
31
+ ok: true,
32
+ service: "my-template",
33
+ }));
45
34
  ```
46
35
 
47
36
  ### Route naming conventions {#route-naming-conventions}
48
37
 
49
- | File name pattern | HTTP method | Example path |
50
- | ------------------ | ----------- | -------------------------- |
51
- | `index.get.ts` | GET | `/api/items` |
52
- | `index.post.ts` | POST | `/api/items` |
53
- | `[id].get.ts` | GET | `/api/items/:id` |
54
- | `[id].patch.ts` | PATCH | `/api/items/:id` |
55
- | `[id].delete.ts` | DELETE | `/api/items/:id` |
56
- | `[...slug].get.ts` | GET | `/api/items/* (catch-all)` |
38
+ | File name pattern | HTTP method | Example path |
39
+ | ------------------ | ----------- | --------------------------- |
40
+ | `index.get.ts` | GET | `/api/items` |
41
+ | `index.post.ts` | POST | `/api/items` |
42
+ | `[id].get.ts` | GET | `/api/items/:id` |
43
+ | `[id].patch.ts` | PATCH | `/api/items/:id` |
44
+ | `[id].delete.ts` | DELETE | `/api/items/:id` |
45
+ | `[...slug].get.ts` | GET | `/api/items/*` or catch-all |
57
46
 
58
- ### Accessing route parameters {#accessing-route-parameters}
47
+ ## Prefer Actions For App Operations {#actions-first}
59
48
 
60
- ```ts
61
- import { defineEventHandler, getRouterParam, readBody, getQuery } from "h3";
49
+ If the UI and agent both need to do something, define an action instead of a custom API route. Actions automatically become:
62
50
 
63
- // GET /api/items/:id
64
- export default defineEventHandler(async (event) => {
65
- const id = getRouterParam(event, "id");
66
- const { filter } = getQuery(event);
67
- // ...
68
- });
69
- ```
51
+ - Agent tools.
52
+ - Typed frontend hooks.
53
+ - HTTP endpoints under `/_agent-native/actions/:name`.
54
+ - MCP and A2A-callable tools.
55
+ - CLI commands for development.
70
56
 
71
- ## Server Plugins {#server-plugins}
57
+ Use custom `/api/*` routes only when you need a route-shaped protocol or binary/streaming behavior. See [Actions](/docs/actions).
72
58
 
73
- Cross-cutting concerns file watchers, file sync, scheduled jobs, auth — go in `server/plugins/`. Nitro runs these at startup before serving requests:
59
+ ## Request Context And Access {#request-context}
60
+
61
+ Actions mounted by the framework automatically run with request context. Custom routes do not. If a custom route reads or writes ownable resources, load the session and wrap the work:
74
62
 
75
63
  ```ts
76
- // server/plugins/file-sync.ts
77
- import { defineNitroPlugin } from "@agent-native/core";
78
- import { createFileSync } from "@agent-native/core/adapters/sync";
79
-
80
- export default defineNitroPlugin(async () => {
81
- const result = await createFileSync({ contentRoot: "./data" });
82
- if (result.status === "error") {
83
- console.warn(`[app] File sync failed: ${result.reason}`);
64
+ import { defineEventHandler } from "h3";
65
+ import { getSession, runWithRequestContext } from "@agent-native/core/server";
66
+ import { getDb } from "@agent-native/core/db";
67
+ import { accessFilter } from "@agent-native/core/access";
68
+ import * as schema from "../../db/schema";
69
+
70
+ export default defineEventHandler(async (event) => {
71
+ const session = await getSession(event);
72
+ if (!session?.user?.email) {
73
+ throw new Response("Unauthorized", { status: 401 });
84
74
  }
75
+
76
+ return runWithRequestContext(
77
+ { userEmail: session.user.email, orgId: session.orgId },
78
+ async () => {
79
+ const db = getDb();
80
+ return db
81
+ .select()
82
+ .from(schema.projects)
83
+ .where(accessFilter(schema.projects, schema.projectShares));
84
+ },
85
+ );
85
86
  });
86
87
  ```
87
88
 
88
- ## Shared State Between Plugins and Routes {#shared-state}
89
+ Do not run unscoped `db.select().from(ownableTable)` in custom routes.
90
+
91
+ ## Server Plugins {#server-plugins}
89
92
 
90
- Use a shared module in `server/lib/` to pass state from plugins to route handlers:
93
+ Plugins live in `server/plugins/` and run at startup. Use them for migrations, provider setup, recurring jobs, integration adapters, and framework plugin configuration.
91
94
 
92
95
  ```ts
93
- // server/lib/watcher.ts
94
- import { createFileWatcher } from "@agent-native/core";
95
- import type { SSEHandlerOptions } from "@agent-native/core";
96
-
97
- export const watcher = createFileWatcher("./data");
98
- export const sseExtraEmitters: NonNullable<SSEHandlerOptions["extraEmitters"]> =
99
- [];
100
-
101
- export let syncResult: any = { status: "disabled" };
102
- export function setSyncResult(result: any) {
103
- syncResult = result;
104
- if (result.status === "ready" && result.sseEmitter) {
105
- sseExtraEmitters.push(result.sseEmitter);
106
- }
107
- }
96
+ // server/plugins/db.ts
97
+ import { runMigrations } from "@agent-native/core/db/migrations";
98
+
99
+ export default runMigrations([
100
+ {
101
+ id: "001_create_projects",
102
+ sql: `CREATE TABLE IF NOT EXISTS projects (
103
+ id TEXT PRIMARY KEY,
104
+ title TEXT NOT NULL,
105
+ owner_email TEXT NOT NULL,
106
+ org_id TEXT,
107
+ created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
108
+ )`,
109
+ },
110
+ ]);
108
111
  ```
109
112
 
110
- The plugin populates the state at startup; route handlers read it at request time.
113
+ Migrations must be additive. Never put destructive SQL in startup plugins.
111
114
 
112
- ## createFileWatcher(dir, options?) {#createfilewatcher}
115
+ ## Framework-Mounted Routes {#framework-routes}
113
116
 
114
- Creates a chokidar file watcher for real-time file change detection:
115
-
116
- ```ts
117
- import { createFileWatcher } from "@agent-native/core";
117
+ The framework mounts its own routes under `/_agent-native/`. Treat that namespace as reserved.
118
118
 
119
- const watcher = createFileWatcher("./data");
120
- // watcher emits "all" events: (eventName, filePath)
121
- ```
119
+ | Route prefix | Purpose |
120
+ | -------------------------------- | ------------------------------------ |
121
+ | `/_agent-native/actions/:name` | Action HTTP endpoints |
122
+ | `/_agent-native/agent-chat` | Agent chat loop |
123
+ | `/_agent-native/poll` | SQL-backed UI sync |
124
+ | `/_agent-native/resources/*` | Workspace resources |
125
+ | `/_agent-native/tools/*` | Runtime tools and tool proxy |
126
+ | `/_agent-native/integrations/*` | Messaging/webhook integrations |
127
+ | `/_agent-native/a2a` | Agent-to-agent JSON-RPC |
128
+ | `/_agent-native/mcp` | MCP endpoint |
129
+ | `/_agent-native/onboarding/*` | Setup checklist |
130
+ | `/_agent-native/observability/*` | Traces, feedback, evals, experiments |
131
+ | `/_agent-native/file-upload` | File upload provider endpoint |
122
132
 
123
- ### Options {#filewatcher-options}
133
+ Custom app routes should use `/api/*`, public app paths, or provider-specific callback paths that do not collide with `/_agent-native/`.
124
134
 
125
- | Option | Type | Description |
126
- | ------------- | ------- | ------------------------------------------------- |
127
- | `ignored` | any | Glob patterns or regex to ignore |
128
- | `emitInitial` | boolean | Emit events for initial file scan. Default: false |
135
+ ## SQL-Backed Sync {#sync}
129
136
 
130
- ## createSSEHandler(watcher, options?) {#createssehandler}
137
+ Agent-native does not rely on filesystem watchers or sticky in-memory state. When actions or framework helpers mutate data, the database sync version increments. The client `useDbSync()` hook polls `/_agent-native/poll` and invalidates React Query caches.
131
138
 
132
- Creates an H3 event handler that streams file changes as Server-Sent Events:
139
+ This works across serverless and multi-instance deployments because the database is the coordination point. If you write custom mutations outside actions, use framework helpers or emit the appropriate sync invalidation so open UIs refresh.
133
140
 
134
- ```ts
135
- // server/routes/_agent-native/events.get.ts
136
- import { createSSEHandler } from "@agent-native/core";
137
- import { watcher, sseExtraEmitters } from "../../lib/watcher.js";
141
+ ## Webhooks {#webhooks}
138
142
 
139
- export default createSSEHandler(watcher, {
140
- extraEmitters: sseExtraEmitters,
141
- contentRoot: "./data",
142
- });
143
- ```
143
+ Inbound webhooks should verify, persist, and return quickly. Long-running agent work should use the integration queue pattern:
144
144
 
145
- Each SSE message is JSON: `{ "type": "change", "path": "data/file.json" }`
145
+ 1. Verify the platform signature or challenge.
146
+ 2. Insert durable work into SQL.
147
+ 3. Self-fire a signed processor route.
148
+ 4. Return 200 immediately.
149
+ 5. Let the fresh processor execution run the agent loop and post the result.
146
150
 
147
- ### Options {#ssehandler-options}
151
+ Do not rely on unawaited promises after returning a response. See [Messaging](/docs/messaging) for the canonical integration queue.
148
152
 
149
- | Option | Type | Description |
150
- | ------------- | --------------------------- | ------------------------------------------------- |
151
- | extraEmitters | `Array<{ emitter, event }>` | Additional EventEmitters to stream |
152
- | contentRoot | string | Root directory used to relativize paths in events |
153
+ ## Programmatic H3 Servers {#create-server}
153
154
 
154
- ## createServer(options?) {#createserver}
155
-
156
- Optional helper that creates a pre-configured H3 app with CORS middleware and a health-check route. Returns `{ app, router }`. Useful for programmatic route registration when file-based routing doesn't fit:
155
+ For custom packages or tests that need an H3 app directly, `createServer()` returns a preconfigured app and router:
157
156
 
158
157
  ```ts
159
- import { createServer } from "@agent-native/core";
158
+ import { createServer } from "@agent-native/core/server";
160
159
  import { defineEventHandler } from "h3";
161
160
 
162
161
  const { app, router } = createServer();
163
- router.get("/api/items", defineEventHandler(listItems));
164
- ```
165
-
166
- ## mountAuthMiddleware(app, accessToken) {#mountauthmiddleware}
167
-
168
- Mounts session-cookie authentication onto an H3 app. Serves a login page for unauthenticated browser requests and returns 401 for unauthenticated API requests.
169
162
 
170
- ```ts
171
- import { mountAuthMiddleware } from "@agent-native/core";
172
-
173
- mountAuthMiddleware(app, process.env.ACCESS_TOKEN!);
163
+ router.get(
164
+ "/api/health",
165
+ defineEventHandler(() => ({ ok: true })),
166
+ );
174
167
  ```
175
168
 
176
- Adds two routes automatically: `POST /api/auth/login` and `POST /api/auth/logout`.
169
+ Most templates do not need this helper because Nitro file routes and framework plugins handle the app server.
177
170
 
178
- ## createProductionAgentHandler(options) {#createproductionagenthandler}
171
+ ## Production Agent Handler {#agent-handler}
179
172
 
180
- Creates an H3 SSE handler at `POST /_agent-native/agent-chat` that runs an agentic tool loop using Claude. Each script's `run()` function is registered as a tool the agent can invoke.
173
+ The framework's agent chat plugin mounts the production agent handler for templates. Only call `createProductionAgentHandler()` directly when building a custom server integration outside the standard template plugin stack.
181
174
 
182
175
  ```ts
183
- import { createProductionAgentHandler } from "@agent-native/core";
184
- import { scripts } from "./scripts/registry.js";
185
- import { readFileSync } from "fs";
176
+ import { createProductionAgentHandler } from "@agent-native/core/server";
186
177
 
187
- const agent = createProductionAgentHandler({
178
+ const handler = createProductionAgentHandler({
188
179
  scripts,
189
- systemPrompt: readFileSync("agents/system-prompt.md", "utf-8"),
180
+ systemPrompt: "You are the app agent...",
190
181
  });
191
182
  ```
192
183
 
193
- ### Options {#agent-handler-options}
194
-
195
- | Option | Type | Description |
196
- | -------------- | ----------------------------- | ------------------------------------------------- |
197
- | `scripts` | `Record<string, ScriptEntry>` | Map of script name → { tool, run } entries |
198
- | `systemPrompt` | string | System prompt for the embedded agent |
199
- | `apiKey` | string | Anthropic API key. Default: ANTHROPIC_API_KEY env |
200
- | `model` | string | Model to use. Default: claude-sonnet-4-6 |
184
+ Standard templates should customize the agent through `AGENTS.md`, skills, actions, and the agent chat plugin rather than hand-mounting this route.
@@ -53,7 +53,7 @@ Create a skill when:
53
53
  Don't create a skill when:
54
54
 
55
55
  - The guidance already exists in another skill — extend it instead
56
- - The guidance is a one-off — put it in `AGENTS.md` or `learnings.md` instead
56
+ - The guidance is a one-off — put it in `AGENTS.md` or workspace memory instead
57
57
 
58
58
  ## Skill format {#skill-format}
59
59
 
@@ -110,6 +110,6 @@ Save the file at `.agents/skills/my-skill/SKILL.md`. The directory name should m
110
110
 
111
111
  > **Skills** — Authored, reusable how-to guides. Apply to every user, invoked on demand when the task matches.
112
112
  >
113
- > **Memory (`learnings.md`)** — Per-user notes the agent writes automatically from corrections and preferences. Loaded every turn.
113
+ > **Memory (`LEARNINGS.md` / `memory/MEMORY.md`)** — Shared project learnings and personal structured memory loaded every turn.
114
114
 
115
- If the knowledge applies to _everyone_ working in the app ("always prefer CTEs over subqueries"), it's a skill. If it's about _this particular user_ ("Steve likes concise answers"), it belongs in `learnings.md` — and the agent will put it there itself the next time you correct it. See [Agent Memory (`learnings.md`)](./resources.md#learnings-md) for the full treatment.
115
+ If the knowledge applies to _everyone_ working in the app ("always prefer CTEs over subqueries"), it's a skill or shared `LEARNINGS.md`. If it's about _this particular user_ ("Steve likes concise answers"), it belongs in `memory/MEMORY.md`. See [Workspace Memory](/docs/workspace#memory) for the full treatment.
@@ -5,7 +5,7 @@ description: "Ask analytics questions in plain English, get charts and dashboard
5
5
 
6
6
  # Analytics
7
7
 
8
- Ask analytics questions in plain English, get charts and dashboards back. The agent connects to BigQuery, GA4, your app database, HubSpot, Jira, and a dozen other sources, writes the SQL for you, validates it, and renders the answer as a chart, table, or saved dashboard panel.
8
+ Ask analytics questions in plain English, get charts and dashboards back. The agent connects to BigQuery, GA4, Amplitude, the built-in first-party event collector, HubSpot, Jira, and a dozen other sources, writes the query for you, validates it, and renders the answer as a chart, table, or saved dashboard panel.
9
9
 
10
10
  It's an open-source replacement for Amplitude, Mixpanel, and Looker — for teams that want to own the code, the queries, and the data.
11
11
 
@@ -26,7 +26,7 @@ When you first open the app:
26
26
 
27
27
  1. Sign in with Google.
28
28
  2. Open the **Data Sources** page from the sidebar.
29
- 3. Each source has a walkthrough — connect the ones you need (start with one, like BigQuery or your app DB).
29
+ 3. Each source has a walkthrough — connect the ones you need (start with one, like BigQuery, GA4, Amplitude, or first-party tracking).
30
30
  4. Open a new chat with the agent and ask a question: "How many signups did we get last week?"
31
31
 
32
32
  The first question is enough to confirm the connection works. From there, ask the agent to "save this as a dashboard" or "build a 4-panel overview dashboard for our key metrics."
@@ -62,7 +62,7 @@ The rest of this doc is for anyone forking the Analytics template or extending i
62
62
  Create a new Analytics app from the CLI:
63
63
 
64
64
  ```bash
65
- npx @agent-native/cli create analytics
65
+ pnpm dlx @agent-native/core create my-analytics --template analytics --standalone
66
66
  ```
67
67
 
68
68
  Local dev:
@@ -73,13 +73,13 @@ pnpm install
73
73
  pnpm dev
74
74
  ```
75
75
 
76
- The app runs at `http://localhost:3000`. Sign in with Google, then open the **Data Sources** page to connect BigQuery, HubSpot, Jira, and the rest.
76
+ The CLI prints the local dev URL. Sign in with Google, then open the **Data Sources** page to connect BigQuery, GA4, first-party tracking, HubSpot, Jira, and the rest.
77
77
 
78
78
  ### Key features (technical)
79
79
 
80
80
  **Natural-language chart generation.** Ask the agent in plain English. It picks the right data source, writes the SQL, validates it against the warehouse, and renders the chart inline in chat or as a saved panel. Chart types: `line`, `area`, `bar`, `metric`, `table`, `pie`.
81
81
 
82
- **Reusable SQL dashboards.** Dashboards are a named config with an array of panels. Each panel has an `id`, `title`, `sql`, `source` (`bigquery` / `app-db` / `ga4`), `chartType`, and `width` (1 or 2 columns). See the full shape in `templates/analytics/app/pages/adhoc/sql-dashboard/types.ts`.
82
+ **Reusable SQL dashboards.** Dashboards are a named config with an array of panels. Each panel has an `id`, `title`, `sql`, `source` (`bigquery` / `ga4` / `amplitude` / `first-party`), `chartType`, and `width` (1 or 2 columns). See the full shape in `templates/analytics/app/pages/adhoc/sql-dashboard/types.ts`.
83
83
 
84
84
  Dashboards support:
85
85
 
@@ -92,7 +92,9 @@ Dashboards support:
92
92
 
93
93
  **Living data dictionary.** Canonical catalog of metrics — metric name, definition, table, columns, SQL template, known gotchas, owner, and data lag. The agent reads it before writing any SQL, so it uses the real warehouse column names (`hs_is_closed`, not guessed `is_closed`) and knows about caveats like "excludes internal emails". Seeded by asking the agent to import definitions from an existing source (dbt descriptions, a Notion page, a team wiki).
94
94
 
95
- **SQL query explorer.** Direct SQL against BigQuery or the app DB from the **Ad-hoc** view. Useful for iterating on a query before saving it as a dashboard panel.
95
+ **SQL query explorer.** Direct queries against BigQuery and supported analytics backends from the **Ad-hoc** view. Useful for iterating before saving a dashboard panel.
96
+
97
+ **First-party analytics collector.** Hosted apps can send product and template events to `/track` with a public write key. Query those events through `query-agent-native-analytics` or dashboard panels with `source: "first-party"`.
96
98
 
97
99
  **Multiple data connectors.** Built-in actions for common sources:
98
100
 
@@ -1,32 +1,30 @@
1
1
  ---
2
2
  title: "Design"
3
- description: "An Agent-native design toolsketch a UI, brand kit, or marketing visual by prompt or by hand, with the agent as your co-designer."
3
+ description: "An agent-native HTML prototyping studio generate, refine, preview, and export interactive Alpine/Tailwind designs with an agent."
4
4
  ---
5
5
 
6
6
  # Design
7
7
 
8
- A design tool where the agent is a real collaborator. Sketch a UI, a brand kit, or a marketing visual by prompt or by hand, and the agent generates layouts, suggests color systems, swaps fonts, and adjusts spacing alongside you on the same canvas.
8
+ Design is an agent-native HTML prototyping studio. Instead of a layered drawing canvas, the agent generates complete self-contained Alpine/Tailwind HTML prototypes, renders them in an iframe, and lets you refine the result with prompts and tweak controls.
9
9
 
10
- Think along the lines of Figma or Canva, but the agent has full edit rights — it can move shapes, restyle layers, and generate new artwork from a description, all in the same canvas you're working in.
10
+ Use it when you want a polished landing page concept, product UI direction, brand exploration, or interactive prototype that can leave the tool as real HTML.
11
11
 
12
- ## What you can do with it
12
+ ## What You Can Do With It
13
13
 
14
- - **Prompt-driven design.** Describe what you want "a hero section for a B2B fintech SaaS, dark mode, brand color #14B8A6" and the agent drafts it on the canvas.
15
- - **Edit by hand or by chat.** Drag, resize, recolor with the toolbar; or ask the agent to "tighten the spacing", "swap the headline font for something more editorial", "make every CTA the brand teal".
16
- - **AI image generation built in.** Generate background art, illustrations, or icons inline. Re-run with refined prompts without leaving the canvas.
17
- - **Brand-aware.** Save a brand kit (colors, fonts, voice). The agent applies it consistently across new artwork.
18
- - **Components and frames.** Reusable components, multi-page documents, and export to PNG/SVG/PDF.
19
- - **Agent context awareness.** When a layer is selected, the agent knows what you've selected and can act on just that piece.
14
+ - **Generate complete prototypes.** Describe the screen or page you need and the agent creates a working HTML document with Tailwind styling and Alpine interactions.
15
+ - **Compare variants.** Start with multiple directions, pick the strongest one, then continue refining.
16
+ - **Tweak visually.** Use the built-in tweak controls for common changes, or ask the agent for copy, layout, color, spacing, and interaction updates.
17
+ - **Apply design systems.** Save and reuse design-system preferences so generated work stays closer to your brand.
18
+ - **Import references.** Bring in existing HTML or reference material as context for a new design pass.
19
+ - **Export real files.** Export HTML, ZIP, or PDF from the generated prototype.
20
20
 
21
- ## Why it's interesting
21
+ ## Why It's Interesting
22
22
 
23
- Three things make Design a good showcase of what agent-native enables:
23
+ Design is useful because the agent edits an artifact that is already close to shippable web UI. There is no separate "AI mockup" format to translate later: the preview, the editable source, and the exported artifact all come from the same HTML.
24
24
 
25
- 1. **The agent edits the canvas directly.** Layers, frames, styles the agent calls the same actions the toolbar does. There's no "AI mode" separate from the design tool; they're the same tool.
26
- 2. **Selection-aware editing.** Select a button and ask "make this the brand teal across all pages" — the agent knows which element you mean and propagates the change.
27
- 3. **Designs you own.** The files live in your SQL, the artwork lives in your storage, the agent is yours. Fork the template, plug in a different image-generation provider, integrate your team's component library — it's your code.
25
+ The template is also a good example of agent-native ownership. The app stores designs in SQL, exposes template operations as actions, and lets you fork the whole workflow when your team needs a different renderer, exporter, or design-system model.
28
26
 
29
- ## For developers
27
+ ## For Developers
30
28
 
31
29
  The rest of this doc is for anyone forking the Design template or extending it.
32
30
 
@@ -36,20 +34,20 @@ The rest of this doc is for anyone forking the Design template or extending it.
36
34
  pnpm dlx @agent-native/core create my-design --template design --standalone
37
35
  ```
38
36
 
39
- ### Customize it
37
+ ### Customize It
40
38
 
41
- Design is a full cloneable SaaS fork it and ask the agent to extend it. Some examples:
39
+ Design is a cloneable SaaS template. Some practical extension ideas:
42
40
 
43
- - "Add a 'Generate variations' button that produces five color-swap alternatives for the selected frame."
44
- - "Wire the brand kit to read from our marketing-site repo so colors stay in sync."
45
- - "Add a comments layer with @-mentions and email notifications."
46
- - "Auto-export every published frame as a 1200×630 OG image and upload to our CDN."
47
- - "Let me drop a Figma link in chat and have the agent re-create it as native components here."
41
+ - "Add a reusable ecommerce design system with our tokens and sample components."
42
+ - "Add an export step that uploads the ZIP to our internal review system."
43
+ - "Let me paste existing landing-page HTML and ask the agent for three stronger versions."
44
+ - "Add a saved prompt library for product-page, dashboard, and onboarding-screen briefs."
45
+ - "Add a custom PDF export preset for stakeholder review."
48
46
 
49
- The agent edits routes, components, canvas actions, and the schema as needed. See [Cloneable SaaS](/docs/cloneable-saas) for the full clone, customize, deploy flow, and [Getting Started](/docs/getting-started) if this is your first agent-native template.
47
+ The agent edits routes, components, actions, and SQL-backed models as needed. See [Cloneable SaaS](/docs/cloneable-saas) for the full clone, customize, deploy flow, and [Getting Started](/docs/getting-started) if this is your first agent-native template.
50
48
 
51
- ## What's next
49
+ ## What's Next
52
50
 
53
51
  - [**Cloneable SaaS**](/docs/cloneable-saas) — the clone-and-own model
54
- - [**Context Awareness**](/docs/context-awareness) — how the agent knows the selected layer
55
- - [**Tools**](/docs/tools) — generate one-off image-creation utilities alongside the canvas
52
+ - [**Context Awareness**](/docs/context-awareness) — how the agent knows what the user is viewing
53
+ - [**Creating Templates**](/docs/creating-templates) — current build patterns for agent-native templates