@agent-native/core 0.35.2 → 0.35.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/README.md +1 -1
  2. package/dist/cli/context-xray-local.d.ts +2 -2
  3. package/dist/cli/context-xray-local.d.ts.map +1 -1
  4. package/dist/cli/context-xray-local.js +1449 -53
  5. package/dist/cli/context-xray-local.js.map +1 -1
  6. package/dist/cli/skills.d.ts.map +1 -1
  7. package/dist/cli/skills.js +226 -78
  8. package/dist/cli/skills.js.map +1 -1
  9. package/dist/cli/templates-meta.d.ts.map +1 -1
  10. package/dist/cli/templates-meta.js +8 -4
  11. package/dist/cli/templates-meta.js.map +1 -1
  12. package/dist/client/AgentPanel.d.ts.map +1 -1
  13. package/dist/client/AgentPanel.js +5 -11
  14. package/dist/client/AgentPanel.js.map +1 -1
  15. package/dist/client/AssistantChat.d.ts +6 -0
  16. package/dist/client/AssistantChat.d.ts.map +1 -1
  17. package/dist/client/AssistantChat.js +33 -5
  18. package/dist/client/AssistantChat.js.map +1 -1
  19. package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
  20. package/dist/client/MultiTabAssistantChat.js +63 -3
  21. package/dist/client/MultiTabAssistantChat.js.map +1 -1
  22. package/dist/client/agent-chat.d.ts +39 -3
  23. package/dist/client/agent-chat.d.ts.map +1 -1
  24. package/dist/client/agent-chat.js +168 -33
  25. package/dist/client/agent-chat.js.map +1 -1
  26. package/dist/client/application-state.d.ts +13 -0
  27. package/dist/client/application-state.d.ts.map +1 -0
  28. package/dist/client/application-state.js +99 -0
  29. package/dist/client/application-state.js.map +1 -0
  30. package/dist/client/frame-protocol.d.ts +11 -3
  31. package/dist/client/frame-protocol.d.ts.map +1 -1
  32. package/dist/client/frame-protocol.js.map +1 -1
  33. package/dist/client/index.d.ts +4 -2
  34. package/dist/client/index.d.ts.map +1 -1
  35. package/dist/client/index.js +4 -2
  36. package/dist/client/index.js.map +1 -1
  37. package/dist/client/progress/RunsTray.d.ts +1 -0
  38. package/dist/client/progress/RunsTray.d.ts.map +1 -1
  39. package/dist/client/progress/RunsTray.js +50 -16
  40. package/dist/client/progress/RunsTray.js.map +1 -1
  41. package/dist/client/use-action.d.ts +12 -0
  42. package/dist/client/use-action.d.ts.map +1 -1
  43. package/dist/client/use-action.js +14 -2
  44. package/dist/client/use-action.js.map +1 -1
  45. package/dist/client/use-agent-chat-context.d.ts +15 -0
  46. package/dist/client/use-agent-chat-context.d.ts.map +1 -0
  47. package/dist/client/use-agent-chat-context.js +32 -0
  48. package/dist/client/use-agent-chat-context.js.map +1 -0
  49. package/dist/deploy/build.d.ts.map +1 -1
  50. package/dist/deploy/build.js +1 -2
  51. package/dist/deploy/build.js.map +1 -1
  52. package/dist/index.browser.d.ts +1 -1
  53. package/dist/index.browser.d.ts.map +1 -1
  54. package/dist/index.browser.js +1 -1
  55. package/dist/index.browser.js.map +1 -1
  56. package/dist/index.d.ts +1 -1
  57. package/dist/index.d.ts.map +1 -1
  58. package/dist/index.js +1 -1
  59. package/dist/index.js.map +1 -1
  60. package/dist/mcp/server.d.ts +4 -2
  61. package/dist/mcp/server.d.ts.map +1 -1
  62. package/dist/mcp/server.js +33 -4
  63. package/dist/mcp/server.js.map +1 -1
  64. package/dist/provider-api/index.d.ts.map +1 -1
  65. package/dist/provider-api/index.js +14 -6
  66. package/dist/provider-api/index.js.map +1 -1
  67. package/dist/server/agent-teams.d.ts +4 -1
  68. package/dist/server/agent-teams.d.ts.map +1 -1
  69. package/dist/server/agent-teams.js +104 -28
  70. package/dist/server/agent-teams.js.map +1 -1
  71. package/dist/server/auth.d.ts.map +1 -1
  72. package/dist/server/auth.js +21 -11
  73. package/dist/server/auth.js.map +1 -1
  74. package/dist/server/request-context.d.ts +3 -4
  75. package/dist/server/request-context.d.ts.map +1 -1
  76. package/dist/server/request-context.js.map +1 -1
  77. package/dist/server/self-dispatch.d.ts.map +1 -1
  78. package/dist/server/self-dispatch.js +17 -1
  79. package/dist/server/self-dispatch.js.map +1 -1
  80. package/dist/server/ssr-handler.d.ts.map +1 -1
  81. package/dist/server/ssr-handler.js +9 -18
  82. package/dist/server/ssr-handler.js.map +1 -1
  83. package/dist/templates/default/AGENTS.md +1 -1
  84. package/dist/templates/default/DEVELOPING.md +7 -13
  85. package/dist/templates/workspace-core/AGENTS.md +6 -4
  86. package/dist/templates/workspace-root/AGENTS.md +6 -4
  87. package/docs/content/actions.md +5 -7
  88. package/docs/content/client.md +49 -44
  89. package/docs/content/context-awareness.md +20 -33
  90. package/docs/content/creating-templates.md +2 -2
  91. package/docs/content/key-concepts.md +3 -3
  92. package/docs/content/sharing.md +1 -1
  93. package/docs/content/template-mail.md +1 -1
  94. package/docs/content/voice-input.md +1 -1
  95. package/package.json +5 -1
  96. package/src/templates/default/AGENTS.md +1 -1
  97. package/src/templates/default/DEVELOPING.md +7 -13
  98. package/src/templates/workspace-core/AGENTS.md +6 -4
  99. package/src/templates/workspace-root/AGENTS.md +6 -4
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: "Client"
3
- description: "React hooks and utilities for agent-native apps: sendToAgentChat, setContextToAgentChat, useDbSync, useAgentChatGenerating, and cn."
3
+ description: "React hooks and utilities for agent-native apps: sendToAgentChat, optional agent chat context state, useDbSync, useAgentChatGenerating, and cn."
4
4
  ---
5
5
 
6
6
  # Client
@@ -115,59 +115,64 @@ sendToAgentChat({
115
115
  | `preset` | `string?` | Optional preset name for downstream consumers |
116
116
  | `referenceImagePaths` | `string[]?` | Optional reference image paths |
117
117
 
118
- ## setContextToAgentChat(opts) {#setcontexttoagentchat}
118
+ ## Agent Chat Context State (Advanced) {#agent-chat-context-state}
119
119
 
120
- Stage one or more hidden context nuggets in the active agent chat composer
121
- without submitting a message or filling the prompt text. Use this when the UI
122
- lets a user select app objects, rows, elements, files, or other structured data
123
- that should inform the next prompt, while still letting the user write the
124
- visible request themselves.
120
+ The context-state APIs are optional plumbing for UI that needs two-way sync with
121
+ staged context chips: rendering the current staged items outside the composer,
122
+ reflecting whether an item is already attached, or providing explicit
123
+ remove/clear controls.
125
124
 
126
- Each context nugget has a stable `key`. Calling `setContextToAgentChat()` again
127
- with the same key replaces that nugget. Calling it with a new key stacks another
128
- nugget. The composer shows each nugget as a removable chip, and the framework
129
- includes the staged context in a hidden `<context>` block only when the user
130
- submits the prompt.
125
+ Do not reach for these helpers for simple "send this to the agent" or
126
+ "prefill this draft for review" flows. Use `sendToAgentChat()` with `context`
127
+ and `submit` for those.
131
128
 
132
- `addContextToAgentChat()` is an alias for the same replace-by-key behavior.
129
+ | API | Use when |
130
+ | --------------------------------- | ---------------------------------------------------------------------- |
131
+ | `useAgentChatContext()` | A React component needs the live staged context list |
132
+ | `setAgentChatContextItem(item)` | Imperative code should stage or replace one keyed context item |
133
+ | `listAgentChatContext()` | Non-React code needs a one-time snapshot of staged context |
134
+ | `removeAgentChatContextItem(key)` | UI should remove one staged context item by its stable `key` |
135
+ | `clearAgentChatContext()` | UI should clear all staged context, such as after a view or mode reset |
136
+ | `refreshAgentChatContext()` | Imperative code should re-read the latest persisted context snapshot |
133
137
 
134
- ```ts
135
- import { setContextToAgentChat } from "@agent-native/core";
136
-
137
- setContextToAgentChat({
138
- key: "selected-element:.thing#hello",
139
- title: "Selected Element",
140
- context: [
141
- "CSS selector: .thing#hello",
142
- "HTML:",
143
- '<button class="thing" id="hello">Buy now</button>',
144
- ].join("\n"),
145
- });
138
+ `useAgentChatContext()` returns `{ items, set, remove, clear, refresh }`.
146
139
 
147
- setContextToAgentChat({
148
- key: "cart",
149
- title: "Cart",
150
- context: "2 items: Pro plan, extra seat",
151
- });
152
- ```
140
+ ```tsx
141
+ import { useAgentChatContext } from "@agent-native/core";
153
142
 
154
- If an app should only ever stage one item of a kind, reuse the same key:
143
+ function SelectionContextButton({ record }: { record: { id: string } }) {
144
+ const chatContext = useAgentChatContext();
145
+ const contextKey = `selected-record:${record.id}`;
146
+ const isAttached = chatContext.items.some((item) => item.key === contextKey);
155
147
 
156
- ```ts
157
- setContextToAgentChat({
158
- key: "selected-record",
159
- title: "Selected Record",
160
- context: JSON.stringify(record, null, 2),
161
- });
148
+ return (
149
+ <button
150
+ type="button"
151
+ onClick={() => {
152
+ if (isAttached) {
153
+ chatContext.remove(contextKey);
154
+ return;
155
+ }
156
+
157
+ chatContext.set({
158
+ key: contextKey,
159
+ title: "Selected Record",
160
+ context: JSON.stringify(record, null, 2),
161
+ openSidebar: false,
162
+ });
163
+ }}
164
+ >
165
+ {isAttached ? "Remove from prompt context" : "Add to prompt context"}
166
+ </button>
167
+ );
168
+ }
162
169
  ```
163
170
 
164
- Use `sendToAgentChat({ message, context, submit: true })` when the UI already
165
- knows the message to send immediately. Use `sendToAgentChat({ submit: false })`
166
- only when you want to prefill editable prompt text. Use
167
- `setContextToAgentChat()` when the UI should add context while leaving the
168
- prompt box available for the user's own request.
171
+ `listAgentChatContext()` is for imperative code that only needs to inspect the
172
+ current staged items once. `clearAgentChatContext()` is intentionally broad; use
173
+ `removeAgentChatContextItem(key)` when only one selection changed.
169
174
 
170
- ### AgentChatContextMessage {#agentchatcontextmessage}
175
+ ### AgentChatContextSetOptions {#agentchatcontextsetoptions}
171
176
 
172
177
  | Option | Type | Description |
173
178
  | ------------- | ---------- | ------------------------------------------------------ |
@@ -92,22 +92,10 @@ Use the `selection` app-state key for durable selection that should survive a mo
92
92
  Write it from the UI when the user selects, focuses, or multi-selects meaningful objects:
93
93
 
94
94
  ```tsx
95
- import { agentNativePath } from "@agent-native/core/client";
95
+ import { setClientAppState } from "@agent-native/core/client";
96
96
 
97
97
  async function syncSelection(selection: unknown | null) {
98
- const url = agentNativePath("/_agent-native/application-state/selection");
99
-
100
- if (!selection) {
101
- await fetch(url, { method: "DELETE", keepalive: true });
102
- return;
103
- }
104
-
105
- await fetch(url, {
106
- method: "PUT",
107
- keepalive: true,
108
- headers: { "Content-Type": "application/json" },
109
- body: JSON.stringify(selection),
110
- });
98
+ await setClientAppState("selection", selection, { keepalive: true });
111
99
  }
112
100
  ```
113
101
 
@@ -134,17 +122,15 @@ The production agent injects that key into the next turn as immediate selection
134
122
  Custom editors can write the same key when their selection is not represented by native browser selection:
135
123
 
136
124
  ```tsx
137
- await fetch(
138
- agentNativePath("/_agent-native/application-state/pending-selection-context"),
125
+ import { setClientAppState } from "@agent-native/core/client";
126
+
127
+ await setClientAppState(
128
+ "pending-selection-context",
139
129
  {
140
- method: "PUT",
141
- keepalive: true,
142
- headers: { "Content-Type": "application/json" },
143
- body: JSON.stringify({
144
- text: selectedMarkdown,
145
- capturedAt: Date.now(),
146
- }),
130
+ text: selectedMarkdown,
131
+ capturedAt: Date.now(),
147
132
  },
133
+ { keepalive: true },
148
134
  );
149
135
  ```
150
136
 
@@ -275,15 +261,17 @@ The UI polls for this command and navigates when it appears:
275
261
 
276
262
  ```ts
277
263
  // UI side -- poll for navigate commands
264
+ import {
265
+ deleteClientAppState,
266
+ readClientAppState,
267
+ } from "@agent-native/core/client";
268
+
278
269
  const { data: navCommand } = useQuery({
279
270
  queryKey: ["navigate-command"],
280
271
  queryFn: async () => {
281
- const res = await fetch("/_agent-native/application-state/navigate");
282
- if (!res.ok) return null;
283
- const data = await res.json();
272
+ const data = await readClientAppState<NavigateCommand>("navigate");
284
273
  if (data) {
285
- // Delete the one-shot command after reading
286
- fetch("/_agent-native/application-state/navigate", { method: "DELETE" });
274
+ await deleteClientAppState("navigate");
287
275
  return data;
288
276
  }
289
277
  return null;
@@ -308,17 +296,14 @@ The `use-navigation-state.ts` hook syncs routes to application-state on every na
308
296
  // app/hooks/use-navigation-state.ts
309
297
  import { useEffect } from "react";
310
298
  import { useLocation } from "react-router";
299
+ import { setClientAppState } from "@agent-native/core/client";
311
300
 
312
301
  export function useNavigationState() {
313
302
  const location = useLocation();
314
303
 
315
304
  useEffect(() => {
316
305
  const state = deriveNavigationState(location.pathname);
317
- fetch("/_agent-native/application-state/navigation", {
318
- method: "PUT",
319
- headers: { "Content-Type": "application/json" },
320
- body: JSON.stringify(state),
321
- }).catch(() => {});
306
+ setClientAppState("navigation", state).catch(() => {});
322
307
  }, [location.pathname]);
323
308
  }
324
309
  ```
@@ -329,6 +314,8 @@ The `deriveNavigationState()` function is template-specific -- it parses the URL
329
314
 
330
315
  When the agent writes to application-state, the sync system might cause the UI to refetch data it just wrote. This creates jitter. The solution is source tagging:
331
316
 
317
+ Use `setClientAppState`, `writeClientAppState`, `readClientAppState`, and `deleteClientAppState` from `@agent-native/core/client` for browser-side application-state access. Pass `{ requestSource: TAB_ID }` on UI writes when pairing with `useDbSync({ ignoreSource: TAB_ID })`; pass `{ keepalive: true }` for short-lived writes such as selection cleanup during unload.
318
+
332
319
  ```ts
333
320
  // app/root.tsx
334
321
  import { TAB_ID } from "@/lib/tab-id";
@@ -133,7 +133,7 @@ Use the [Database](/docs/database) and [Security](/docs/security) docs before ad
133
133
 
134
134
  ## Define Operations As Actions {#actions}
135
135
 
136
- Actions are the single source of truth for app behavior. The agent calls them as tools, the frontend calls them through hooks or HTTP, and other apps can reach them through MCP/A2A.
136
+ Actions are the single source of truth for app behavior. The agent calls them as tools, the frontend calls them through hooks, and other apps can reach them through MCP/A2A.
137
137
 
138
138
  ```ts
139
139
  // actions/create-project.ts
@@ -196,7 +196,7 @@ export function AppSync() {
196
196
  }
197
197
  ```
198
198
 
199
- **The agent-native promise: agent writes show up in the UI without a manual refresh.** `useActionQuery` is the easy path — every hook refetches when a mutating action emits `source: "action"`. If you reach for raw `useQuery` with a custom key (e.g. for a non-action HTTP endpoint, integration status, etc.), fold the per-source counter into the queryKey for targeted refreshes:
199
+ **The agent-native promise: agent writes show up in the UI without a manual refresh.** `useActionQuery` is the easy path — every hook refetches when a mutating action emits `source: "action"`. If you reach for raw `useQuery` with a custom key (for example, a low-level client helper that reads integration status), fold the per-source counter into the queryKey for targeted refreshes:
200
200
 
201
201
  ```tsx
202
202
  import { useChangeVersions } from "@agent-native/core/client";
@@ -45,7 +45,7 @@ Six rules govern the architecture:
45
45
 
46
46
  Adopting the framework is valuable mostly because of what you stop having to build. The moment your app follows the six rules, you inherit:
47
47
 
48
- - **One action = every surface.** Every action defined with `defineAction()` is simultaneously an agent tool, a typesafe frontend mutation (`useActionMutation("name")`), an HTTP endpoint at `/_agent-native/actions/:name`, a CLI command, an MCP tool for external clients, and an A2A tool for other agent-native apps. Optional `link` and `mcpApp` metadata add deep links and MCP Apps UI without a second implementation.
48
+ - **One action = every surface.** Every action defined with `defineAction()` is simultaneously an agent tool, a typesafe frontend hook (`useActionQuery` / `useActionMutation`), a framework-owned HTTP transport, a CLI command, an MCP tool for external clients, and an A2A tool for other agent-native apps. Optional `link` and `mcpApp` metadata add deep links and MCP Apps UI without a second implementation.
49
49
  - **A full workspace per user.** Skills, shared `LEARNINGS.md`, personal `memory/MEMORY.md`, `AGENTS.md`, custom sub-agents, scheduled jobs, connected MCP servers — all SQL-backed, no dev-box required. See [Workspace](/docs/workspace).
50
50
  - **Drop-in React components.** `<AgentPanel />` and `<AgentSidebar />` render chat + workspace anywhere in your app. See [Drop-in Agent](/docs/drop-in-agent).
51
51
  - **Live sync between agent and UI.** Same-process writes stream immediately over `/_agent-native/events`; a lightweight poll keeps serverless, cron, and cross-process writes convergent. Mutating actions invalidate action-backed queries automatically, so agent-created records appear without a manual refresh. See [Live Sync](#polling-sync) below.
@@ -151,8 +151,8 @@ export default defineAction({
151
151
  One `defineAction()` call gives you:
152
152
 
153
153
  - **Agent tool** — the agent sees it with the zod-derived JSON Schema and can call it.
154
- - **Frontend mutation** — `useActionMutation("fetch-data")` with full TypeScript inference.
155
- - **HTTP endpoint** — `POST /_agent-native/actions/fetch-data` (auto-mounted).
154
+ - **Frontend hook** — `useActionMutation("fetch-data")` with full TypeScript inference.
155
+ - **Framework transport** — auto-mounted behind the client hooks.
156
156
  - **CLI** — `pnpm action fetch-data --source=signups` for scripting and agent dev loops.
157
157
  - **MCP tool / A2A tool** — when MCP server or A2A is enabled, the same action shows up there too.
158
158
 
@@ -87,7 +87,7 @@ For lists, drop a `<VisibilityBadge visibility={row.visibility} />` next to each
87
87
 
88
88
  ## Same model, agent and UI {#agent-and-ui}
89
89
 
90
- The framework auto-mounts these actions in every template — the agent calls them as tools, the UI calls them as HTTP endpoints:
90
+ The framework auto-mounts these actions in every template — the agent calls them as tools, and the UI calls them through `useActionQuery` / `useActionMutation`:
91
91
 
92
92
  | Action | What it does |
93
93
  | ------------------------- | ---------------------------------------------------------------------------------------------- |
@@ -170,7 +170,7 @@ Routes in the UI:
170
170
 
171
171
  Mail is yours to change. Everything important lives in a handful of places — start there.
172
172
 
173
- **Adding an agent capability.** Add a new file under `templates/mail/actions/` using `defineAction`. Your action becomes both a CLI command (`pnpm action <name>`) and an HTTP endpoint (`/_agent-native/actions/<name>`). Look at `templates/mail/actions/star-email.ts` for a short example or `templates/mail/actions/manage-automations.ts` for one with multiple sub-actions. See the [actions](/docs/actions) docs for the full pattern.
173
+ **Adding an agent capability.** Add a new file under `templates/mail/actions/` using `defineAction`. Your action becomes an agent tool, a CLI command (`pnpm action <name>`), and a typed frontend hook surface through `useActionQuery` / `useActionMutation`. Look at `templates/mail/actions/star-email.ts` for a short example or `templates/mail/actions/manage-automations.ts` for one with multiple sub-actions. See the [actions](/docs/actions) docs for the full pattern.
174
174
 
175
175
  **Changing the UI.** Routes are in `templates/mail/app/routes/` and components in `templates/mail/app/components/email/` and `templates/mail/app/components/layout/`. The app uses shadcn/ui primitives from `app/components/ui/` and Tabler Icons — stick to those.
176
176
 
@@ -47,7 +47,7 @@ If no server provider is configured at all, the route returns a 400 the composer
47
47
  - **Origin check:** same-origin only.
48
48
  - **Max size:** 25 MB.
49
49
 
50
- You don't need to call this directly — the composer does. But if you're building a custom input surface and want the same transcription, POST a `FormData` with an `audio` blob to the same route.
50
+ You don't need to call this directly — the composer does. If you're building a custom input surface, first reuse the shared composer/voice client pieces from `@agent-native/core/client`. Treat this route as the low-level transport boundary for custom helpers that need to send multipart audio.
51
51
 
52
52
  ## Customizing the provider {#customizing}
53
53
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-native/core",
3
- "version": "0.35.2",
3
+ "version": "0.35.3",
4
4
  "type": "module",
5
5
  "engines": {
6
6
  "node": ">=22"
@@ -40,8 +40,12 @@
40
40
  "./db/schema": "./dist/db/schema.js",
41
41
  "./db/drizzle-config": "./dist/db/drizzle-config.js",
42
42
  "./client": "./dist/client/index.js",
43
+ "./client/AgentPanel": "./dist/client/AgentPanel.js",
44
+ "./client/application-state": "./dist/client/application-state.js",
45
+ "./client/api-path": "./dist/client/api-path.js",
43
46
  "./client/observability": "./dist/client/observability/index.js",
44
47
  "./client/onboarding": "./dist/client/onboarding/index.js",
48
+ "./client/settings/useBuilderStatus": "./dist/client/settings/useBuilderStatus.js",
45
49
  "./onboarding": "./dist/onboarding/index.js",
46
50
  "./shared": "./dist/shared/index.js",
47
51
  "./scripts": "./dist/scripts/index.js",
@@ -7,7 +7,7 @@ This is an **@agent-native/core** application -- the AI agent and UI share state
7
7
  ### Core Principles
8
8
 
9
9
  1. **Shared SQL database** -- All app state lives in SQL. Local SQLite at `data/app.db` is the zero-setup dev fallback; deployed apps need a persistent `DATABASE_URL` so data survives container/serverless restarts. Turso is optional, not required: Neon, Supabase, Turso/libSQL, plain Postgres, durable SQLite, D1 bindings, and Builder.io-managed environments are all valid when supported by the deploy. Core stores: `application_state`, `settings`, `oauth_tokens`, `sessions`, `resources`.
10
- 2. **All AI through agent chat** -- No inline LLM calls. UI delegates to the AI via `sendToAgentChat()` / `agentChat.submit()`. When UI selections should add hidden context for the user's next prompt without submitting, use `setContextToAgentChat()` with a stable `key`.
10
+ 2. **All AI through agent chat** -- No inline LLM calls. UI delegates to the AI via `sendToAgentChat()` / `agentChat.submit()`. Use `sendToAgentChat({ message, context, submit })` for simple UI handoffs and prefill/review flows. Only use the agent-chat context state helpers (`useAgentChatContext`, `setAgentChatContextItem`, `listAgentChatContext`, `removeAgentChatContextItem`, `clearAgentChatContext`) when the UI needs two-way sync with staged context chips.
11
11
  3. **Actions for app operations** -- `pnpm action <name>` dispatches to callable action files in `actions/`; `defineAction` also auto-exposes those operations at `/_agent-native/actions/:name` for the UI. Do not create custom REST routes that re-export actions.
12
12
  4. **Live sync keeps the UI current** -- Database writes stream over `/_agent-native/events` first, with `/_agent-native/poll` as the fallback. **When you (the agent) write data, the UI must reflect the change without a manual refresh.** This is non-negotiable. Use `useActionQuery` / `useActionMutation` for action-backed data (preferred). If you use raw `useQuery`, fold `useChangeVersions([<source>, "action"])` into the key for targeted refreshes. See the `real-time-sync` and `adding-a-feature` skills.
13
13
  5. **Agent can update code** -- The agent can modify this app's source code directly.
@@ -81,7 +81,7 @@ export default defineNitroPlugin(async (nitroApp) => {
81
81
  | `readResource`, `writeResource` | Read/write resources (from `@agent-native/core/resources`) |
82
82
  | `defineEventHandler`, `readBody`, `getQuery` | H3 route handler utilities (re-exported) |
83
83
  | `sendToAgentChat` | Send or prefill messages in the agent chat from UI (client-side) |
84
- | `setContextToAgentChat` | Stage keyed context chips for the next agent chat prompt from UI |
84
+ | Agent chat context state helpers | Optional advanced helpers for two-way sync with staged context chips |
85
85
  | `agentChat` | Send messages to agent from scripts (server-side) |
86
86
 
87
87
  ## Adding a Script
@@ -102,18 +102,12 @@ sendToAgentChat({
102
102
  });
103
103
  ```
104
104
 
105
- To add hidden context without submitting or filling the prompt text, stage
106
- keyed context nuggets. Multiple nuggets stack; using the same `key` replaces the
107
- previous nugget.
108
-
109
- ```ts
110
- import { setContextToAgentChat } from "@agent-native/core";
111
- setContextToAgentChat({
112
- key: "selected-record",
113
- title: "Selected Record",
114
- context: JSON.stringify(record, null, 2),
115
- });
116
- ```
105
+ For most UI handoffs, pass hidden context directly with `sendToAgentChat()`. Use
106
+ `submit: false` when the user should review the draft first. Use
107
+ `useAgentChatContext`, `setAgentChatContextItem`, `listAgentChatContext`,
108
+ `removeAgentChatContextItem`, and `clearAgentChatContext` only for advanced UI
109
+ that needs to read, mirror, stage, remove, or clear staged context chips as local
110
+ interface state.
117
111
 
118
112
  **From scripts:**
119
113
 
@@ -14,10 +14,12 @@ agent should know.
14
14
  - All AI/LLM behavior goes through the app's agent chat. UI and server code
15
15
  must not call model providers, AI SDK `generateText()` / `streamText()`, or
16
16
  other inline LLM APIs directly. Use `sendToAgentChat()` for local app-agent
17
- work. When selected UI data should become hidden context for the user's next
18
- prompt without submitting anything, use `setContextToAgentChat()` with a
19
- stable `key`. Read `.agents/skills/delegate-to-agent/SKILL.md` before
20
- building agent-driven UI or "AI" features.
17
+ work, including hidden `context` and `submit: false` prefill/review flows.
18
+ Only use `useAgentChatContext`, `setAgentChatContextItem`,
19
+ `listAgentChatContext`, `removeAgentChatContextItem`, and
20
+ `clearAgentChatContext` when UI needs two-way sync with staged context chips.
21
+ Read `.agents/skills/delegate-to-agent/SKILL.md` before building agent-driven
22
+ UI or "AI" features.
21
23
  - Put shared code in `packages/shared` only when multiple apps need it.
22
24
  - Keep app-specific screens, actions, state, and skills inside `apps/<app>`.
23
25
  - Store shared runtime configuration in the workspace root `.env`; use
@@ -11,10 +11,12 @@ coding agents can discover the same workspace-wide guidance from the root.
11
11
  - All AI/LLM behavior goes through the app's agent chat. UI and server code
12
12
  must not call model providers, AI SDK `generateText()` / `streamText()`, or
13
13
  other inline LLM APIs directly. Use `sendToAgentChat()` for local app-agent
14
- work. When selected UI data should become hidden context for the user's next
15
- prompt without submitting anything, use `setContextToAgentChat()` with a
16
- stable `key`. Read `packages/shared/.agents/skills/delegate-to-agent/SKILL.md`
17
- before building agent-driven UI or "AI" features.
14
+ work, including hidden `context` and `submit: false` prefill/review flows.
15
+ Only use `useAgentChatContext`, `setAgentChatContextItem`,
16
+ `listAgentChatContext`, `removeAgentChatContextItem`, and
17
+ `clearAgentChatContext` when UI needs two-way sync with staged context chips.
18
+ Read `packages/shared/.agents/skills/delegate-to-agent/SKILL.md` before
19
+ building agent-driven UI or "AI" features.
18
20
 
19
21
  ## Workspace Resources
20
22