@agent-native/core 0.21.0 → 0.22.1

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 (160) hide show
  1. package/dist/action-change-marker.d.ts +11 -0
  2. package/dist/action-change-marker.d.ts.map +1 -0
  3. package/dist/action-change-marker.js +52 -0
  4. package/dist/action-change-marker.js.map +1 -0
  5. package/dist/action.d.ts +2 -2
  6. package/dist/action.js +1 -1
  7. package/dist/action.js.map +1 -1
  8. package/dist/agent/production-agent.d.ts +1 -1
  9. package/dist/agent/production-agent.d.ts.map +1 -1
  10. package/dist/agent/production-agent.js +4 -6
  11. package/dist/agent/production-agent.js.map +1 -1
  12. package/dist/cli/connect.d.ts +5 -3
  13. package/dist/cli/connect.d.ts.map +1 -1
  14. package/dist/cli/connect.js +127 -15
  15. package/dist/cli/connect.js.map +1 -1
  16. package/dist/client/AgentPanel.d.ts.map +1 -1
  17. package/dist/client/AgentPanel.js +6 -2
  18. package/dist/client/AgentPanel.js.map +1 -1
  19. package/dist/client/AssistantChat.d.ts.map +1 -1
  20. package/dist/client/AssistantChat.js +7 -1
  21. package/dist/client/AssistantChat.js.map +1 -1
  22. package/dist/client/NewWorkspaceAppFlow.js +1 -1
  23. package/dist/client/NewWorkspaceAppFlow.js.map +1 -1
  24. package/dist/client/agent-chat.d.ts.map +1 -1
  25. package/dist/client/agent-chat.js +13 -8
  26. package/dist/client/agent-chat.js.map +1 -1
  27. package/dist/client/agent-sidebar-state.d.ts +2 -0
  28. package/dist/client/agent-sidebar-state.d.ts.map +1 -1
  29. package/dist/client/agent-sidebar-state.js +40 -7
  30. package/dist/client/agent-sidebar-state.js.map +1 -1
  31. package/dist/client/mcp-apps/McpAppRenderer.d.ts.map +1 -1
  32. package/dist/client/mcp-apps/McpAppRenderer.js +9 -4
  33. package/dist/client/mcp-apps/McpAppRenderer.js.map +1 -1
  34. package/dist/client/use-db-sync.d.ts +5 -5
  35. package/dist/client/use-db-sync.d.ts.map +1 -1
  36. package/dist/client/use-db-sync.js +15 -5
  37. package/dist/client/use-db-sync.js.map +1 -1
  38. package/dist/client/use-db-sync.spec.d.ts +2 -0
  39. package/dist/client/use-db-sync.spec.d.ts.map +1 -0
  40. package/dist/client/use-db-sync.spec.js +80 -0
  41. package/dist/client/use-db-sync.spec.js.map +1 -0
  42. package/dist/db/client.d.ts.map +1 -1
  43. package/dist/db/client.js +14 -8
  44. package/dist/db/client.js.map +1 -1
  45. package/dist/extensions/actions.d.ts.map +1 -1
  46. package/dist/extensions/actions.js +62 -3
  47. package/dist/extensions/actions.js.map +1 -1
  48. package/dist/extensions/content-patch.d.ts +71 -0
  49. package/dist/extensions/content-patch.d.ts.map +1 -0
  50. package/dist/extensions/content-patch.js +251 -0
  51. package/dist/extensions/content-patch.js.map +1 -0
  52. package/dist/extensions/routes.js +6 -1
  53. package/dist/extensions/routes.js.map +1 -1
  54. package/dist/extensions/store.d.ts +4 -4
  55. package/dist/extensions/store.d.ts.map +1 -1
  56. package/dist/extensions/store.js +14 -18
  57. package/dist/extensions/store.js.map +1 -1
  58. package/dist/mcp/build-server.d.ts +3 -0
  59. package/dist/mcp/build-server.d.ts.map +1 -1
  60. package/dist/mcp/build-server.js +55 -6
  61. package/dist/mcp/build-server.js.map +1 -1
  62. package/dist/mcp/oauth-route.d.ts +22 -0
  63. package/dist/mcp/oauth-route.d.ts.map +1 -0
  64. package/dist/mcp/oauth-route.js +618 -0
  65. package/dist/mcp/oauth-route.js.map +1 -0
  66. package/dist/mcp/oauth-store.d.ts +89 -0
  67. package/dist/mcp/oauth-store.d.ts.map +1 -0
  68. package/dist/mcp/oauth-store.js +391 -0
  69. package/dist/mcp/oauth-store.js.map +1 -0
  70. package/dist/mcp/oauth-token.d.ts +28 -0
  71. package/dist/mcp/oauth-token.d.ts.map +1 -0
  72. package/dist/mcp/oauth-token.js +83 -0
  73. package/dist/mcp/oauth-token.js.map +1 -0
  74. package/dist/mcp/server.d.ts.map +1 -1
  75. package/dist/mcp/server.js +5 -2
  76. package/dist/mcp/server.js.map +1 -1
  77. package/dist/mcp-client/index.d.ts.map +1 -1
  78. package/dist/mcp-client/index.js +16 -2
  79. package/dist/mcp-client/index.js.map +1 -1
  80. package/dist/mcp-client/routes.js +18 -5
  81. package/dist/mcp-client/routes.js.map +1 -1
  82. package/dist/scripts/dev/shell.d.ts.map +1 -1
  83. package/dist/scripts/dev/shell.js +24 -1
  84. package/dist/scripts/dev/shell.js.map +1 -1
  85. package/dist/scripts/runner.d.ts.map +1 -1
  86. package/dist/scripts/runner.js +7 -0
  87. package/dist/scripts/runner.js.map +1 -1
  88. package/dist/server/action-change.d.ts +8 -0
  89. package/dist/server/action-change.d.ts.map +1 -0
  90. package/dist/server/action-change.js +38 -0
  91. package/dist/server/action-change.js.map +1 -0
  92. package/dist/server/action-routes.d.ts.map +1 -1
  93. package/dist/server/action-routes.js +4 -6
  94. package/dist/server/action-routes.js.map +1 -1
  95. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  96. package/dist/server/agent-chat-plugin.js +3 -2
  97. package/dist/server/agent-chat-plugin.js.map +1 -1
  98. package/dist/server/auth.d.ts.map +1 -1
  99. package/dist/server/auth.js +14 -8
  100. package/dist/server/auth.js.map +1 -1
  101. package/dist/server/builder-browser.d.ts +6 -0
  102. package/dist/server/builder-browser.d.ts.map +1 -1
  103. package/dist/server/builder-browser.js +15 -0
  104. package/dist/server/builder-browser.js.map +1 -1
  105. package/dist/server/core-routes-plugin.d.ts +5 -4
  106. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  107. package/dist/server/core-routes-plugin.js +17 -2
  108. package/dist/server/core-routes-plugin.js.map +1 -1
  109. package/dist/server/poll.d.ts.map +1 -1
  110. package/dist/server/poll.js +55 -3
  111. package/dist/server/poll.js.map +1 -1
  112. package/dist/templates/default/.agents/skills/actions/SKILL.md +193 -72
  113. package/dist/templates/default/.agents/skills/real-time-sync/SKILL.md +88 -38
  114. package/dist/templates/default/AGENTS.md +3 -3
  115. package/dist/templates/default/actions/hello.ts +13 -20
  116. package/dist/templates/default/actions/navigate.ts +19 -51
  117. package/dist/templates/default/actions/view-screen.ts +16 -33
  118. package/dist/templates/default/app/hooks/use-navigation-state.ts +13 -3
  119. package/dist/templates/default/app/lib/tab-id.ts +1 -0
  120. package/dist/templates/default/app/root.tsx +2 -1
  121. package/dist/templates/default/app/routes/_index.tsx +11 -0
  122. package/dist/templates/default/package.json +2 -1
  123. package/dist/templates/workspace-core/.agents/skills/actions/SKILL.md +1 -1
  124. package/dist/templates/workspace-core/.agents/skills/real-time-sync/SKILL.md +9 -1
  125. package/dist/templates/workspace-core/AGENTS.md +8 -0
  126. package/dist/templates/workspace-root/AGENTS.md +7 -0
  127. package/dist/vite/client.d.ts.map +1 -1
  128. package/dist/vite/client.js +2 -2
  129. package/dist/vite/client.js.map +1 -1
  130. package/docs/content/actions.md +1 -1
  131. package/docs/content/authentication.md +16 -1
  132. package/docs/content/client.md +11 -8
  133. package/docs/content/context-awareness.md +2 -3
  134. package/docs/content/creating-templates.md +2 -2
  135. package/docs/content/external-agents.md +48 -15
  136. package/docs/content/faq.md +2 -2
  137. package/docs/content/key-concepts.md +31 -23
  138. package/docs/content/mcp-protocol.md +50 -17
  139. package/docs/content/template-starter.md +3 -3
  140. package/docs/content/what-is-agent-native.md +5 -3
  141. package/package.json +2 -1
  142. package/src/templates/default/.agents/skills/actions/SKILL.md +193 -72
  143. package/src/templates/default/.agents/skills/real-time-sync/SKILL.md +88 -38
  144. package/src/templates/default/AGENTS.md +3 -3
  145. package/src/templates/default/actions/hello.ts +13 -20
  146. package/src/templates/default/actions/navigate.ts +19 -51
  147. package/src/templates/default/actions/view-screen.ts +16 -33
  148. package/src/templates/default/app/hooks/use-navigation-state.ts +13 -3
  149. package/src/templates/default/app/lib/tab-id.ts +1 -0
  150. package/src/templates/default/app/root.tsx +2 -1
  151. package/src/templates/default/app/routes/_index.tsx +11 -0
  152. package/src/templates/default/package.json +2 -1
  153. package/src/templates/workspace-core/.agents/skills/actions/SKILL.md +1 -1
  154. package/src/templates/workspace-core/.agents/skills/real-time-sync/SKILL.md +9 -1
  155. package/src/templates/workspace-core/AGENTS.md +8 -0
  156. package/src/templates/workspace-root/AGENTS.md +7 -0
  157. package/dist/templates/default/server/routes/api/hello.get.ts +0 -5
  158. package/dist/templates/default/shared/api.ts +0 -6
  159. package/src/templates/default/server/routes/api/hello.get.ts +0 -5
  160. package/src/templates/default/shared/api.ts +0 -6
@@ -1,56 +1,24 @@
1
- /**
2
- * Navigate the UI to a view.
3
- *
4
- * Writes a navigate command to application state which the UI reads and auto-deletes.
5
- *
6
- * Usage:
7
- * pnpm action navigate --view=home
8
- * pnpm action navigate --path=/some/route
9
- *
10
- * Options:
11
- * --view View name to navigate to
12
- * --path URL path to navigate to
13
- */
14
-
15
- import { parseArgs } from "@agent-native/core";
1
+ import { defineAction } from "@agent-native/core";
16
2
  import { writeAppState } from "@agent-native/core/application-state";
17
- import type { ScriptTool } from "@agent-native/core";
3
+ import { z } from "zod";
18
4
 
19
- export const tool: ScriptTool = {
5
+ export default defineAction({
20
6
  description:
21
7
  "Navigate the UI to a specific view or path. Writes a navigate command to application state which the UI reads and auto-deletes.",
22
- parameters: {
23
- type: "object",
24
- properties: {
25
- view: { type: "string", description: "View name to navigate to" },
26
- path: { type: "string", description: "URL path to navigate to" },
27
- },
8
+ schema: z.object({
9
+ view: z.string().optional().describe("View name to navigate to"),
10
+ path: z.string().optional().describe("URL path to navigate to"),
11
+ }),
12
+ http: false,
13
+ run: async (args) => {
14
+ if (!args.view && !args.path) {
15
+ return "Error: At least --view or --path is required.";
16
+ }
17
+ const nav: Record<string, string> = {};
18
+ if (args.view) nav.view = args.view;
19
+ if (args.path) nav.path = args.path;
20
+ nav._writeId = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
21
+ await writeAppState("navigate", nav);
22
+ return `Navigating to ${args.view || args.path}`;
28
23
  },
29
- };
30
-
31
- export async function run(args: Record<string, string>): Promise<string> {
32
- if (!args.view && !args.path) {
33
- return "Error: At least --view or --path is required.";
34
- }
35
- const nav: Record<string, string> = {};
36
- if (args.view) nav.view = args.view;
37
- if (args.path) nav.path = args.path;
38
- // Unique-per-write token so the UI's `use-navigation-state` hook can dedup
39
- // race-driven re-reads of the same command.
40
- nav._writeId = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
41
- await writeAppState("navigate", nav);
42
- return `Navigating to ${args.view || args.path}`;
43
- }
44
-
45
- export default async function main(): Promise<void> {
46
- const args = parseArgs(process.argv.slice(2)) as Record<string, string>;
47
- if (!args.view && !args.path) {
48
- console.error(
49
- "Error: At least --view or --path is required. Usage: pnpm action navigate --view=home",
50
- );
51
- process.exit(1);
52
- }
53
- const result = await run(args);
54
- console.error(result);
55
- console.log(JSON.stringify({ result }));
56
- }
24
+ });
@@ -1,39 +1,22 @@
1
- /**
2
- * See what the user is currently looking at on screen.
3
- *
4
- * Reads and returns the current navigation state from application state.
5
- *
6
- * Usage:
7
- * pnpm action view-screen
8
- */
9
-
10
- import { parseArgs } from "@agent-native/core";
1
+ import { defineAction } from "@agent-native/core";
11
2
  import { readAppState } from "@agent-native/core/application-state";
12
- import type { ScriptTool } from "@agent-native/core";
3
+ import { z } from "zod";
13
4
 
14
- export const tool: ScriptTool = {
5
+ export default defineAction({
15
6
  description:
16
7
  "See what the user is currently looking at on screen. Returns the current navigation state. Note: basic screen context is auto-included with each message — use this tool only when you need a detailed or refreshed snapshot.",
17
- parameters: {
18
- type: "object",
19
- properties: {},
20
- },
21
- };
22
-
23
- export async function run(_args: Record<string, string>): Promise<string> {
24
- const navigation = await readAppState("navigation");
8
+ schema: z.object({}),
9
+ http: false,
10
+ readOnly: true,
11
+ run: async () => {
12
+ const navigation = await readAppState("navigation");
25
13
 
26
- const screen: Record<string, unknown> = {};
27
- if (navigation) screen.navigation = navigation;
14
+ const screen: Record<string, unknown> = {};
15
+ if (navigation) screen.navigation = navigation;
28
16
 
29
- if (Object.keys(screen).length === 0) {
30
- return "No application state found. Is the app running?";
31
- }
32
- return JSON.stringify(screen, null, 2);
33
- }
34
-
35
- export default async function main(): Promise<void> {
36
- const args = parseArgs(process.argv.slice(2)) as Record<string, string>;
37
- const result = await run(args);
38
- console.log(result);
39
- }
17
+ if (Object.keys(screen).length === 0) {
18
+ return "No application state found. Is the app running?";
19
+ }
20
+ return screen;
21
+ },
22
+ });
@@ -6,6 +6,7 @@ import {
6
6
  appBasePath,
7
7
  appPath,
8
8
  } from "@agent-native/core/client";
9
+ import { TAB_ID } from "../lib/tab-id";
9
10
 
10
11
  export interface NavigationState {
11
12
  view: string;
@@ -30,7 +31,10 @@ export function useNavigationState() {
30
31
  fetch(agentNativePath("/_agent-native/application-state/navigation"), {
31
32
  method: "PUT",
32
33
  keepalive: true,
33
- headers: { "Content-Type": "application/json" },
34
+ headers: {
35
+ "Content-Type": "application/json",
36
+ "X-Request-Source": TAB_ID,
37
+ },
34
38
  body: JSON.stringify(state),
35
39
  }).catch(() => {});
36
40
  }, [location.pathname]);
@@ -65,7 +69,10 @@ export function useNavigationState() {
65
69
  // up again. Re-fire DELETE and bail rather than navigate again.
66
70
  fetch(agentNativePath("/_agent-native/application-state/navigate"), {
67
71
  method: "DELETE",
68
- headers: { "X-Agent-Native-CSRF": "1" },
72
+ headers: {
73
+ "X-Agent-Native-CSRF": "1",
74
+ "X-Request-Source": TAB_ID,
75
+ },
69
76
  }).catch(() => {});
70
77
  qc.setQueryData(["navigate-command"], null);
71
78
  return;
@@ -74,7 +81,10 @@ export function useNavigationState() {
74
81
 
75
82
  fetch(agentNativePath("/_agent-native/application-state/navigate"), {
76
83
  method: "DELETE",
77
- headers: { "X-Agent-Native-CSRF": "1" },
84
+ headers: {
85
+ "X-Agent-Native-CSRF": "1",
86
+ "X-Request-Source": TAB_ID,
87
+ },
78
88
  }).catch(() => {});
79
89
 
80
90
  const path = routerPath(cmd.path || pathFromView(cmd.view));
@@ -0,0 +1 @@
1
+ export const TAB_ID = Math.random().toString(36).slice(2, 10);
@@ -25,6 +25,7 @@ import {
25
25
  import { Toaster } from "sonner";
26
26
  import { configureTracking } from "@agent-native/core/client";
27
27
  import { useNavigationState } from "./hooks/use-navigation-state";
28
+ import { TAB_ID } from "./lib/tab-id";
28
29
  configureTracking({
29
30
  getDefaultProps: (_name, properties) => ({
30
31
  ...properties,
@@ -86,7 +87,7 @@ export function Layout({ children }: { children: React.ReactNode }) {
86
87
  function DbSyncSetup() {
87
88
  const qc = useQueryClient();
88
89
  useNavigationState();
89
- useDbSync({ queryClient: qc, queryKeys: ["files", "data"] });
90
+ useDbSync({ queryClient: qc, ignoreSource: TAB_ID });
90
91
  return null;
91
92
  }
92
93
 
@@ -1,5 +1,6 @@
1
1
  import { useTheme } from "next-themes";
2
2
  import { IconLoader2 } from "@tabler/icons-react";
3
+ import { useActionQuery } from "@agent-native/core/client";
3
4
 
4
5
  export function meta() {
5
6
  return [{ title: "{{APP_TITLE}}" }];
@@ -20,6 +21,7 @@ export function HydrateFallback() {
20
21
  export default function IndexPage() {
21
22
  const { resolvedTheme, setTheme } = useTheme();
22
23
  const isDark = resolvedTheme === "dark";
24
+ const { data } = useActionQuery("hello", { name: "{{APP_TITLE}}" });
23
25
 
24
26
  return (
25
27
  <div className="flex flex-col items-center justify-center min-h-screen px-6">
@@ -38,6 +40,15 @@ export default function IndexPage() {
38
40
 
39
41
  <div className="h-px bg-border" />
40
42
 
43
+ <div className="rounded-lg border border-border/50 px-4 py-3 text-left">
44
+ <p className="text-[13px] font-medium text-foreground">
45
+ Action-backed data
46
+ </p>
47
+ <p className="text-[12px] text-muted-foreground mt-0.5">
48
+ {data?.message ?? "Loading action result..."}
49
+ </p>
50
+ </div>
51
+
41
52
  <div className="grid grid-cols-2 gap-3 text-left">
42
53
  <a
43
54
  href="https://agent-native.com/docs"
@@ -17,7 +17,8 @@
17
17
  "@tabler/icons-react": "^3.40.0",
18
18
  "h3": "^2.0.1-rc.20",
19
19
  "isbot": "^5",
20
- "postgres": "^3.4.9"
20
+ "postgres": "^3.4.9",
21
+ "zod": "^4.4.3"
21
22
  },
22
23
  "devDependencies": {
23
24
  "@react-router/dev": "^7.13.1",
@@ -68,7 +68,7 @@ Controls how the action is exposed as an HTTP endpoint:
68
68
 
69
69
  ### Screen Refresh (automatic)
70
70
 
71
- The framework auto-refreshes the UI after any successful mutating action. On completion of a non-`GET` action, the server emits a poll event that the client's `useDbSync` picks up and uses to invalidate `["action"]` React Query keys — so `list-*` / `get-*` hooks refetch without a full page reload.
71
+ The framework auto-refreshes the UI after any successful mutating action. On completion of a non-`GET` action, the framework emits a change event with `source: "action"` that the client's `useDbSync` picks up and uses to invalidate `["action"]` React Query keys — so `list-*` / `get-*` hooks refetch without a full page reload. In-process calls emit directly; dev-mode `pnpm action ...` calls also write a durable marker so the web server sees child-process action changes.
72
72
 
73
73
  Rules:
74
74
 
@@ -27,7 +27,7 @@ The agent modifies data in SQL, but the UI runs in the browser. SSE bridges same
27
27
  useDbSync({ queryClient });
28
28
  ```
29
29
 
30
- For each non-own event, `useDbSync` bumps a per-source counter (e.g. `dashboards`, `analyses`, `settings`, `action`) and invalidates a small fixed list of framework-internal prefixes (`["action"]`, `["app-state"]`, `["__set_url__"]`, etc.). It does **not** blanket-invalidate templates' own data queries — that caused a request storm in production.
30
+ For each non-own event, `useDbSync` bumps a per-source counter (e.g. `dashboards`, `analyses`, `settings`, `action`) and invalidates a small fixed list of framework-internal prefixes (`["action"]`, `["app-state"]`, `["__set_url__"]`, etc.). It does **not** blanket-invalidate templates' own data queries for ordinary domain events — that caused a request storm in production. The exception is `source: "action"`: a successful mutating action is the framework-wide "agent changed app data" signal, so `useDbSync` also refreshes active React Query observers as a compatibility safety net for custom apps that have not yet moved every read to `useActionQuery` or source-versioned query keys.
31
31
 
32
32
  3. **Templates fold per-source counters into their query keys.** This is the pattern that makes "agent writes show up without a manual refresh" reliable:
33
33
 
@@ -136,6 +136,14 @@ Without jitter prevention, a cycle occurs: the UI writes state, sync detects the
136
136
 
137
137
  Action routes (`/_agent-native/actions/:name`) work with the same sync system. When a POST/PUT/DELETE action writes to the database, the version counter increments and `useDbSync` picks up the change. Frontend mutations via `useActionMutation` automatically invalidate `["action"]` query keys on success, triggering refetches of `useActionQuery` hooks.
138
138
 
139
+ For custom apps, the best out-of-the-box path is:
140
+
141
+ 1. Put read actions in `actions/` with `defineAction({ http: { method: "GET" } })`.
142
+ 2. Put write actions in `actions/` with the default POST/PUT/DELETE behavior.
143
+ 3. Call reads from React with `useActionQuery` and writes with `useActionMutation`.
144
+
145
+ This avoids duplicate `/api/*` JSON CRUD routes and makes agent-created records show up automatically. Raw `useQuery` can still work, but it should include `useChangeVersions(["action", "<domain-source>"])` in the query key for targeted refreshes.
146
+
139
147
  ### Auto-emit on mutating actions
140
148
 
141
149
  The framework emits a poll event with `source: "action"` whenever any non-read-only action runs to completion — whether called via HTTP (`/_agent-native/actions/:name`) or as an agent tool call. Read-only actions (`http: { method: "GET" }` or explicit `readOnly: true`) are skipped.
@@ -66,6 +66,14 @@ shadcn/ui components and `@tabler/icons-react`. Do not add `lucide-react` or
66
66
  another icon library. Read `.agents/skills/shadcn-ui/SKILL.md` before adding,
67
67
  updating, or debugging shadcn components.
68
68
 
69
+ Normal app data must flow through actions. For CRUD that the agent can perform,
70
+ create `defineAction` files in `actions/`, mark reads with
71
+ `http: { method: "GET" }`, and call them from React with `useActionQuery` /
72
+ `useActionMutation`. Do not add duplicate JSON CRUD routes under `/api/*` for
73
+ the same data unless the route is for uploads, streaming, webhooks, OAuth, or
74
+ another route-only concern. Action-backed UI is what makes agent-created or
75
+ agent-edited records appear without a manual refresh.
76
+
69
77
  In local development, run
70
78
  `pnpm exec agent-native create <app-name> --template=<template>` from the
71
79
  workspace root. In production, Dispatch posts new-app requests to Builder
@@ -95,6 +95,13 @@ coding agents can discover the same workspace-wide guidance from the root.
95
95
  `@tabler/icons-react`. Do not add `lucide-react` or another icon library.
96
96
  Read `packages/shared/.agents/skills/shadcn-ui/SKILL.md` before adding,
97
97
  updating, or debugging shadcn components.
98
+ - Normal app data must flow through actions. For CRUD that the agent can
99
+ perform, create `defineAction` files in `actions/`, mark reads with
100
+ `http: { method: "GET" }`, and call them from React with `useActionQuery` /
101
+ `useActionMutation`. Do not add duplicate JSON CRUD routes under `/api/*`
102
+ for the same data unless the route is for uploads, streaming, webhooks,
103
+ OAuth, or another route-only concern. Action-backed UI is what makes
104
+ agent-created or agent-edited records appear without a manual refresh.
98
105
  - In local development, scaffold the app from the workspace root with
99
106
  `pnpm exec agent-native create <app-id> --template=<template>`. In production
100
107
  Dispatch posts the request to Builder branch creation; the Builder branch
@@ -1,5 +0,0 @@
1
- import { defineEventHandler } from "h3";
2
-
3
- export default defineEventHandler(() => {
4
- return { message: "Hello from your @agent-native/core app!" };
5
- });
@@ -1,6 +0,0 @@
1
- /**
2
- * Shared API types and constants.
3
- * Importable from both client (@shared/api) and server.
4
- */
5
-
6
- export const API_BASE = "/api";
@@ -1,5 +0,0 @@
1
- import { defineEventHandler } from "h3";
2
-
3
- export default defineEventHandler(() => {
4
- return { message: "Hello from your @agent-native/core app!" };
5
- });
@@ -1,6 +0,0 @@
1
- /**
2
- * Shared API types and constants.
3
- * Importable from both client (@shared/api) and server.
4
- */
5
-
6
- export const API_BASE = "/api";