@agent-native/core 0.161.17 → 0.161.22

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 (176) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/templates/analytics/.agents/skills/adding-a-feature/SKILL.md +10 -0
  3. package/corpus/templates/analytics/.agents/skills/agent-native-toolkit/SKILL.md +24 -0
  4. package/corpus/templates/analytics/.agents/skills/secrets/SKILL.md +29 -2
  5. package/corpus/templates/analytics/AGENTS.md +1 -0
  6. package/corpus/templates/analytics/server/plugins/auth.ts +4 -0
  7. package/corpus/templates/assets/.agents/skills/adding-a-feature/SKILL.md +10 -0
  8. package/corpus/templates/assets/.agents/skills/agent-native-toolkit/SKILL.md +24 -0
  9. package/corpus/templates/assets/.agents/skills/secrets/SKILL.md +29 -2
  10. package/corpus/templates/assets/AGENTS.md +1 -0
  11. package/corpus/templates/brain/.agents/skills/adding-a-feature/SKILL.md +10 -0
  12. package/corpus/templates/brain/.agents/skills/agent-native-toolkit/SKILL.md +24 -0
  13. package/corpus/templates/brain/.agents/skills/secrets/SKILL.md +29 -2
  14. package/corpus/templates/brain/AGENTS.md +1 -0
  15. package/corpus/templates/calendar/.agents/skills/adding-a-feature/SKILL.md +10 -0
  16. package/corpus/templates/calendar/.agents/skills/agent-native-toolkit/SKILL.md +24 -0
  17. package/corpus/templates/calendar/.agents/skills/secrets/SKILL.md +29 -2
  18. package/corpus/templates/calendar/AGENTS.md +1 -0
  19. package/corpus/templates/chat/.agents/skills/adding-a-feature/SKILL.md +10 -0
  20. package/corpus/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +24 -0
  21. package/corpus/templates/chat/.agents/skills/secrets/SKILL.md +29 -2
  22. package/corpus/templates/chat/AGENTS.md +4 -0
  23. package/corpus/templates/clips/.agents/skills/agent-native-toolkit/SKILL.md +24 -0
  24. package/corpus/templates/clips/.agents/skills/secrets/SKILL.md +29 -2
  25. package/corpus/templates/clips/AGENTS.md +1 -0
  26. package/corpus/templates/clips/actions/finalize-meeting.ts +57 -21
  27. package/corpus/templates/clips/actions/get-meeting.ts +11 -3
  28. package/corpus/templates/clips/actions/request-transcript.ts +183 -8
  29. package/corpus/templates/clips/actions/update-meeting.ts +66 -14
  30. package/corpus/templates/clips/app/components/meetings/canvas-editor.tsx +80 -135
  31. package/corpus/templates/clips/app/components/player/video-player.tsx +4 -0
  32. package/corpus/templates/clips/app/hooks/use-playback-position.ts +10 -2
  33. package/corpus/templates/clips/app/i18n/en-US.ts +4 -0
  34. package/corpus/templates/clips/app/routes/_app.meetings.$meetingId.tsx +470 -35
  35. package/corpus/templates/clips/app/routes/embed.$shareId.tsx +1 -0
  36. package/corpus/templates/clips/app/routes/r.$recordingId.tsx +26 -25
  37. package/corpus/templates/clips/app/routes/share.$shareId.tsx +1 -0
  38. package/corpus/templates/clips/changelog/2026-08-18-clips-no-longer-opens-welcome-window-on-first-launch.md +6 -0
  39. package/corpus/templates/clips/changelog/2026-08-18-meeting-notes-support-rich-editing-for-personal-notes-summar.md +6 -0
  40. package/corpus/templates/clips/changelog/2026-08-18-pending-recording-files-now-use-a-clips-prefixed-name.md +6 -0
  41. package/corpus/templates/clips/desktop/src/main.tsx +0 -3
  42. package/corpus/templates/clips/desktop/src/shared/config.ts +0 -1
  43. package/corpus/templates/clips/desktop/src/styles.css +0 -118
  44. package/corpus/templates/clips/desktop/src-tauri/capabilities/default.json +0 -1
  45. package/corpus/templates/clips/desktop/src-tauri/src/clips/mod.rs +0 -45
  46. package/corpus/templates/clips/desktop/src-tauri/src/config.rs +1 -4
  47. package/corpus/templates/clips/desktop/src-tauri/src/lib.rs +0 -10
  48. package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +57 -5
  49. package/corpus/templates/clips/desktop/src-tauri/src/whisper_speech.rs +13 -3
  50. package/corpus/templates/content/.agents/skills/adding-a-feature/SKILL.md +10 -0
  51. package/corpus/templates/content/.agents/skills/agent-native-toolkit/SKILL.md +24 -0
  52. package/corpus/templates/content/.agents/skills/secrets/SKILL.md +29 -2
  53. package/corpus/templates/content/AGENTS.md +1 -0
  54. package/corpus/templates/crm/.agents/skills/adding-a-feature/SKILL.md +10 -0
  55. package/corpus/templates/crm/.agents/skills/agent-native-toolkit/SKILL.md +24 -0
  56. package/corpus/templates/crm/.agents/skills/secrets/SKILL.md +29 -2
  57. package/corpus/templates/crm/AGENTS.md +1 -0
  58. package/corpus/templates/design/.agents/skills/adding-a-feature/SKILL.md +10 -0
  59. package/corpus/templates/design/.agents/skills/agent-native-toolkit/SKILL.md +24 -0
  60. package/corpus/templates/design/.agents/skills/secrets/SKILL.md +29 -2
  61. package/corpus/templates/design/AGENTS.md +1 -0
  62. package/corpus/templates/design/app/i18n-data.ts +11 -0
  63. package/corpus/templates/design/app/lib/agent-chat.ts +9 -8
  64. package/corpus/templates/dispatch/.agents/skills/adding-a-feature/SKILL.md +10 -0
  65. package/corpus/templates/dispatch/.agents/skills/agent-native-toolkit/SKILL.md +24 -0
  66. package/corpus/templates/dispatch/.agents/skills/secrets/SKILL.md +29 -2
  67. package/corpus/templates/dispatch/AGENTS.md +5 -5
  68. package/corpus/templates/factory/.agents/skills/adding-a-feature/SKILL.md +10 -0
  69. package/corpus/templates/factory/.agents/skills/agent-native-toolkit/SKILL.md +24 -0
  70. package/corpus/templates/factory/.agents/skills/secrets/SKILL.md +29 -2
  71. package/corpus/templates/factory/AGENTS.md +1 -0
  72. package/corpus/templates/forms/.agents/skills/adding-a-feature/SKILL.md +10 -0
  73. package/corpus/templates/forms/.agents/skills/agent-native-toolkit/SKILL.md +24 -0
  74. package/corpus/templates/forms/.agents/skills/secrets/SKILL.md +29 -2
  75. package/corpus/templates/forms/AGENTS.md +1 -0
  76. package/corpus/templates/macros/.agents/skills/adding-a-feature/SKILL.md +10 -0
  77. package/corpus/templates/macros/.agents/skills/agent-native-toolkit/SKILL.md +24 -0
  78. package/corpus/templates/macros/.agents/skills/secrets/SKILL.md +29 -2
  79. package/corpus/templates/macros/AGENTS.md +1 -0
  80. package/corpus/templates/mail/.agents/skills/adding-a-feature/SKILL.md +10 -0
  81. package/corpus/templates/mail/.agents/skills/agent-native-toolkit/SKILL.md +24 -0
  82. package/corpus/templates/mail/.agents/skills/secrets/SKILL.md +29 -2
  83. package/corpus/templates/mail/AGENTS.md +1 -0
  84. package/corpus/templates/mail/app/components/email/EmailList.tsx +74 -22
  85. package/corpus/templates/mail/app/components/email/infinite-pagination.ts +82 -0
  86. package/corpus/templates/mail/app/hooks/use-emails.ts +1 -0
  87. package/corpus/templates/mail/app/pages/InboxPage.tsx +15 -10
  88. package/corpus/templates/mail/app/pages/inbox-zero.ts +35 -0
  89. package/corpus/templates/mail/changelog/2026-08-18-pinned-labels-load-matches.md +6 -0
  90. package/corpus/templates/plan/.agents/skills/adding-a-feature/SKILL.md +10 -0
  91. package/corpus/templates/plan/.agents/skills/agent-native-toolkit/SKILL.md +24 -0
  92. package/corpus/templates/plan/.agents/skills/secrets/SKILL.md +29 -2
  93. package/corpus/templates/plan/AGENTS.md +1 -0
  94. package/corpus/templates/slides/.agents/skills/adding-a-feature/SKILL.md +10 -0
  95. package/corpus/templates/slides/.agents/skills/agent-native-toolkit/SKILL.md +24 -0
  96. package/corpus/templates/slides/.agents/skills/secrets/SKILL.md +29 -2
  97. package/corpus/templates/slides/AGENTS.md +2 -1
  98. package/corpus/templates/slides/actions/get-deck.ts +5 -1
  99. package/corpus/templates/slides/actions/list-decks.ts +29 -8
  100. package/corpus/templates/slides/actions/view-screen.ts +7 -3
  101. package/corpus/templates/slides/changelog/2026-08-18-decks-appear-under-mine.md +6 -0
  102. package/corpus/templates/slides/shared/ownership.ts +6 -0
  103. package/corpus/templates/tasks/.agents/skills/adding-a-feature/SKILL.md +10 -0
  104. package/corpus/templates/tasks/.agents/skills/agent-native-toolkit/SKILL.md +24 -0
  105. package/corpus/templates/tasks/.agents/skills/secrets/SKILL.md +29 -2
  106. package/corpus/templates/tasks/AGENTS.md +1 -0
  107. package/dist/action.js +43 -1
  108. package/dist/app-config/schema.d.ts +2 -0
  109. package/dist/app-config/workspace.d.ts +2 -0
  110. package/dist/app-config/workspace.js +18 -0
  111. package/dist/catalog.json +23 -23
  112. package/dist/client/analytics.d.ts +1 -0
  113. package/dist/client/api-path.js +7 -3
  114. package/dist/client/chat/run-recovery.js +1 -1
  115. package/dist/client/frame.js +20 -6
  116. package/dist/client/org/workspace-app-links.js +10 -1
  117. package/dist/client/route-state.js +17 -13
  118. package/dist/collab/awareness.d.ts +2 -2
  119. package/dist/collab/routes.d.ts +1 -1
  120. package/dist/collab/struct-routes.d.ts +1 -1
  121. package/dist/deploy/build.js +26 -2
  122. package/dist/file-upload/actions/upload-image.d.ts +1 -1
  123. package/dist/notifications/routes.d.ts +1 -1
  124. package/dist/observability/routes.d.ts +5 -5
  125. package/dist/provider-api/actions/custom-provider-registration.d.ts +14 -14
  126. package/dist/provider-api/actions/provider-api.d.ts +15 -15
  127. package/dist/secrets/routes.d.ts +9 -9
  128. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  129. package/dist/server/app-origin-config.d.ts +1 -0
  130. package/dist/server/app-origin-config.js +3 -0
  131. package/dist/server/auth.d.ts +6 -0
  132. package/dist/server/auth.js +25 -7
  133. package/dist/server/cookie-namespace.js +17 -2
  134. package/dist/server/credential-provider.js +5 -2
  135. package/dist/server/derived-secret.js +3 -2
  136. package/dist/server/onboarding-html.js +34 -2
  137. package/dist/server/workspace-oauth.js +11 -6
  138. package/dist/shared/runtime-config.d.ts +2 -0
  139. package/dist/shared/runtime-config.js +12 -3
  140. package/dist/templates/chat/.agents/skills/adding-a-feature/SKILL.md +10 -0
  141. package/dist/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +24 -0
  142. package/dist/templates/chat/.agents/skills/secrets/SKILL.md +29 -2
  143. package/dist/templates/chat/AGENTS.md +4 -0
  144. package/dist/templates/default/.agents/skills/adding-a-feature/SKILL.md +10 -0
  145. package/dist/templates/default/.agents/skills/agent-native-toolkit/SKILL.md +24 -0
  146. package/dist/templates/default/.agents/skills/secrets/SKILL.md +29 -2
  147. package/dist/templates/default/AGENTS.md +4 -0
  148. package/dist/templates/headless/.agents/skills/agent-native-toolkit/SKILL.md +24 -0
  149. package/dist/templates/headless/.agents/skills/secrets/SKILL.md +29 -2
  150. package/dist/templates/headless/AGENTS.md +4 -0
  151. package/dist/templates/workspace-core/.agents/skills/adding-a-feature/SKILL.md +10 -0
  152. package/dist/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +24 -0
  153. package/dist/templates/workspace-core/.agents/skills/secrets/SKILL.md +29 -2
  154. package/dist/templates/workspace-core/AGENTS.md +4 -0
  155. package/dist/templates/workspace-root/AGENTS.md +9 -0
  156. package/dist/vite/client.js +5 -2
  157. package/docs/content/deployment.mdx +70 -0
  158. package/docs/content/faq.mdx +1 -1
  159. package/package.json +2 -2
  160. package/src/templates/chat/.agents/skills/adding-a-feature/SKILL.md +10 -0
  161. package/src/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +24 -0
  162. package/src/templates/chat/.agents/skills/secrets/SKILL.md +29 -2
  163. package/src/templates/chat/AGENTS.md +4 -0
  164. package/src/templates/default/.agents/skills/adding-a-feature/SKILL.md +10 -0
  165. package/src/templates/default/.agents/skills/agent-native-toolkit/SKILL.md +24 -0
  166. package/src/templates/default/.agents/skills/secrets/SKILL.md +29 -2
  167. package/src/templates/default/AGENTS.md +4 -0
  168. package/src/templates/headless/.agents/skills/agent-native-toolkit/SKILL.md +24 -0
  169. package/src/templates/headless/.agents/skills/secrets/SKILL.md +29 -2
  170. package/src/templates/headless/AGENTS.md +4 -0
  171. package/src/templates/workspace-core/.agents/skills/adding-a-feature/SKILL.md +10 -0
  172. package/src/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +24 -0
  173. package/src/templates/workspace-core/.agents/skills/secrets/SKILL.md +29 -2
  174. package/src/templates/workspace-core/AGENTS.md +4 -0
  175. package/src/templates/workspace-root/AGENTS.md +9 -0
  176. package/corpus/templates/clips/desktop/src/overlays/onboarding.tsx +0 -314
@@ -1,3 +1,4 @@
1
+ import { isTruthyRuntimeValue } from "../shared/runtime-config.js";
1
2
  import { agentNativePath } from "./api-path.js";
2
3
  /**
3
4
  * Frame Communication (browser)
@@ -174,8 +175,7 @@ export function getCallbackOrigin() {
174
175
  return typeof window !== "undefined" ? window.location.origin : "";
175
176
  }
176
177
  function envFlag(name) {
177
- const value = runtimeEnvValue(name);
178
- return value === "1" || value === "true" || value === true;
178
+ return isTruthyRuntimeValue(runtimeEnvValue(name));
179
179
  }
180
180
  function runtimeEnvValue(name) {
181
181
  const importMetaEnv = import.meta.env;
@@ -193,9 +193,21 @@ function workspaceOAuthOrigin() {
193
193
  // guaranteed — which is why the chain lists both and why it is not the
194
194
  // primary path any more.
195
195
  const shell = typeof window !== "undefined" ? window.__AGENT_NATIVE_CONFIG__ : undefined;
196
- const raw = shell?.workspaceOAuthOrigin ||
197
- shell?.appUrl ||
198
- shell?.workspaceGatewayUrl ||
196
+ const projectedRaw = shell?.workspaceOAuthOrigin || shell?.appUrl || shell?.workspaceGatewayUrl;
197
+ if (shell?.workspaceRuntime === true) {
198
+ if (typeof projectedRaw === "string" && projectedRaw.trim()) {
199
+ try {
200
+ return new URL(projectedRaw).origin;
201
+ }
202
+ catch {
203
+ // coercion-ok: a stale projected origin intentionally falls back below.
204
+ // Fall through to the current origin when the projected value is stale.
205
+ }
206
+ }
207
+ const currentOrigin = getCallbackOrigin();
208
+ return currentOrigin || null;
209
+ }
210
+ const raw = projectedRaw ||
199
211
  runtimeEnvValue("VITE_WORKSPACE_OAUTH_ORIGIN") ||
200
212
  runtimeEnvValue("WORKSPACE_OAUTH_ORIGIN") ||
201
213
  runtimeEnvValue("VITE_APP_URL") ||
@@ -214,7 +226,9 @@ function workspaceOAuthOrigin() {
214
226
  }
215
227
  }
216
228
  function shouldUseWorkspaceCallbackRelay(path) {
217
- return (envFlag("VITE_AGENT_NATIVE_WORKSPACE") &&
229
+ const projectedWorkspaceRuntime = typeof window !== "undefined" &&
230
+ window.__AGENT_NATIVE_CONFIG__?.workspaceRuntime === true;
231
+ return ((projectedWorkspaceRuntime || envFlag("VITE_AGENT_NATIVE_WORKSPACE")) &&
218
232
  path.startsWith("/_agent-native/") &&
219
233
  (path.endsWith("/callback") || path.includes("/callback/")));
220
234
  }
@@ -1,5 +1,6 @@
1
1
  import { useEffect, useMemo, useState } from "react";
2
2
  import { coreTemplates, getTemplate } from "../../cli/templates-meta.js";
3
+ import { isTruthyRuntimeValue } from "../../shared/runtime-config.js";
3
4
  const DISPATCH_ID = "dispatch";
4
5
  export const ORG_SWITCHER_MAX_APP_LINKS = 9;
5
6
  function runtimeEnv() {
@@ -9,6 +10,13 @@ function envString(env, key) {
9
10
  const value = env[key];
10
11
  return typeof value === "string" && value.trim() ? value.trim() : undefined;
11
12
  }
13
+ function envFlag(env, key) {
14
+ return isTruthyRuntimeValue(env[key]);
15
+ }
16
+ function projectedWorkspaceRuntime() {
17
+ return (typeof window !== "undefined" &&
18
+ window.__AGENT_NATIVE_CONFIG__?.workspaceRuntime === true);
19
+ }
12
20
  function titleCase(value) {
13
21
  return value
14
22
  .split(/[-_\s]+/)
@@ -170,7 +178,8 @@ export function defaultOrgAppLinks() {
170
178
  })));
171
179
  }
172
180
  export function isWorkspaceAppEnvironment(env = runtimeEnv()) {
173
- return (envString(env, "VITE_AGENT_NATIVE_WORKSPACE") === "1" ||
181
+ return (envFlag(env, "VITE_AGENT_NATIVE_WORKSPACE") ||
182
+ projectedWorkspaceRuntime() ||
174
183
  Boolean(envString(env, "VITE_WORKSPACE_GATEWAY_URL")) ||
175
184
  Boolean(envString(env, "VITE_AGENT_NATIVE_WORKSPACE_APPS_JSON")));
176
185
  }
@@ -58,19 +58,24 @@ function shallowEqualNavigationState(left, right) {
58
58
  }
59
59
  return true;
60
60
  }
61
- function stringifyForWriteDedup(value) {
61
+ /**
62
+ * Dedup token for the navigation write. Unserializable state falls back to the
63
+ * state's own identity, never a fresh symbol: the caller's `navigationKeys` is
64
+ * usually a new array each render, so a symbol recomputed here would never
65
+ * match the last one and every re-render would issue another failing write.
66
+ * Identity still lets a genuinely different state reach the write path.
67
+ */
68
+ function navigationWriteDedupToken(keys, state) {
62
69
  try {
63
- const serialized = JSON.stringify(value);
64
- return typeof serialized === "string"
65
- ? serialized
66
- : Symbol("unserializable navigation state");
70
+ const serialized = JSON.stringify({ keys, state });
71
+ if (typeof serialized === "string")
72
+ return serialized;
67
73
  }
68
74
  catch {
69
- // Do not turn a serialization failure into a reusable string key. A
70
- // distinct token lets a changed unserializable state reach the write path
71
- // and surface its real error instead of being silently deduplicated.
72
- return Symbol("unserializable navigation state");
75
+ // coercion-ok: deferred, not dropped — the write below still rejects with
76
+ // this error and reports it through `onError`.
73
77
  }
78
+ return state;
74
79
  }
75
80
  function resolveAgentChatViewTransitionOption(option, command, path) {
76
81
  const resolved = typeof option === "function" ? option(command, path) : option;
@@ -92,16 +97,15 @@ export function useSemanticNavigationState(options) {
92
97
  const commandKeys = useMemo(() => uniqueKeys(options.commandKeys ?? ["navigate"]), [options.commandKeys]);
93
98
  const commandQueryKey = useMemo(() => options.commandQueryKey ?? ["navigate-command"], [options.commandQueryKey]);
94
99
  const navigationState = options.state ?? null;
95
- const navigationWriteDedup = useMemo(() => stringifyForWriteDedup({
96
- keys: navigationKeys,
97
- state: navigationState,
98
- }), [navigationKeys, navigationState]);
100
+ const navigationWriteDedup = useMemo(() => navigationWriteDedupToken(navigationKeys, navigationState), [navigationKeys, navigationState]);
99
101
  const getCommandDedupKeyRef = useRef(options.getCommandDedupKey);
100
102
  const onCommandRef = useRef(options.onCommand);
101
103
  const onErrorRef = useRef(options.onError);
102
104
  getCommandDedupKeyRef.current = options.getCommandDedupKey;
103
105
  onCommandRef.current = options.onCommand;
104
106
  onErrorRef.current = options.onError;
107
+ // `null` is safe as "never written": a null state serializes to a string, so
108
+ // the token itself is never null.
105
109
  const lastNavigationWriteRef = useRef(null);
106
110
  useEffect(() => {
107
111
  if (!enabled)
@@ -62,11 +62,11 @@ export declare const postAwareness: import("h3").EventHandlerWithFetch<import("h
62
62
  error: string;
63
63
  states?: undefined;
64
64
  } | {
65
- error?: undefined;
66
65
  states: {
67
66
  clientId: number;
68
67
  state: string;
69
68
  }[];
69
+ error?: undefined;
70
70
  }>>;
71
71
  /**
72
72
  * GET /_agent-native/collab/:docId/users
@@ -77,9 +77,9 @@ export declare const getActiveUsers: import("h3").EventHandlerWithFetch<import("
77
77
  error: string;
78
78
  users?: undefined;
79
79
  } | {
80
- error?: undefined;
81
80
  users: {
82
81
  clientId: number;
83
82
  lastSeen: number;
84
83
  }[];
84
+ error?: undefined;
85
85
  }>>;
@@ -26,8 +26,8 @@ export declare const getCollabState: import("h3").EventHandlerWithFetch<import("
26
26
  * Body: { update: string (base64), requestSource?: string }
27
27
  */
28
28
  export declare const postCollabUpdate: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
29
- error: string;
30
29
  ok?: undefined;
30
+ error: string;
31
31
  } | {
32
32
  error?: undefined;
33
33
  ok: boolean;
@@ -13,8 +13,8 @@
13
13
  * Body: { json: any, fieldName?: string, type?: "map"|"array", requestSource?: string }
14
14
  */
15
15
  export declare const postCollabJson: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
16
- error: string;
17
16
  ok?: undefined;
17
+ error: string;
18
18
  } | {
19
19
  error?: undefined;
20
20
  ok: boolean;
@@ -25,6 +25,7 @@ import { RECURRING_JOBS_SWEEP_PATH, RECURRING_JOBS_SWEEP_TOKEN_SUBJECT, } from "
25
25
  import { normalizeAppBasePath } from "../server/app-base-path.js";
26
26
  import { DEFAULT_SPECULATION_RULES_PATH, resolveSsrCacheHeaders, resolveSsrCacheKeyHeaders, } from "../shared/cache-control.js";
27
27
  import { mcpEmbedStaticAssetRouteRules } from "../shared/mcp-embed-headers.js";
28
+ import { isTruthyRuntimeValue } from "../shared/runtime-config.js";
28
29
  import { AGENT_NATIVE_SOCIAL_IMAGE_ALT, AGENT_NATIVE_SOCIAL_IMAGE_CACHE_BUSTER, AGENT_NATIVE_SOCIAL_IMAGE_HEIGHT, AGENT_NATIVE_SOCIAL_IMAGE_PATH, AGENT_NATIVE_SOCIAL_IMAGE_TYPE, AGENT_NATIVE_SOCIAL_IMAGE_WIDTH, } from "../shared/social-meta.js";
29
30
  import { generateActionRegistryForProject } from "../vite/action-types-plugin.js";
30
31
  import { createAgentNativeConfigContext, loadResolvedAgentNativeConfig, } from "../vite/agent-native-config-loader.js";
@@ -882,6 +883,14 @@ function firstNonEmpty() {
882
883
  }
883
884
  }
884
885
 
886
+ function isTruthyRuntimeValue(value) {
887
+ if (typeof value === "boolean") return value;
888
+ if (typeof value !== "string") return false;
889
+ return ["1", "true", "yes", "on"].includes(
890
+ value.trim().toLowerCase(),
891
+ );
892
+ }
893
+
885
894
  function getSentryClientConfigScript() {
886
895
  const env = globalThis.process?.env || {};
887
896
  const key = firstNonEmpty(env.SENTRY_CLIENT_KEY, env.VITE_SENTRY_CLIENT_KEY);
@@ -993,10 +1002,21 @@ function getAppOriginClientConfigScript() {
993
1002
  env.WORKSPACE_OAUTH_ORIGIN,
994
1003
  env.VITE_WORKSPACE_OAUTH_ORIGIN,
995
1004
  );
1005
+ const workspaceRuntime = [
1006
+ env.AGENT_NATIVE_WORKSPACE,
1007
+ env.VITE_AGENT_NATIVE_WORKSPACE,
1008
+ ].some((value) => isTruthyRuntimeValue(value)) ||
1009
+ Boolean(
1010
+ firstNonEmpty(
1011
+ env.AGENT_NATIVE_WORKSPACE_APPS_JSON,
1012
+ env.VITE_AGENT_NATIVE_WORKSPACE_APPS_JSON,
1013
+ ),
1014
+ );
996
1015
  const config = {
997
1016
  ...(appUrl ? { appUrl } : {}),
998
1017
  ...(workspaceGatewayUrl ? { workspaceGatewayUrl } : {}),
999
1018
  ...(workspaceOAuthOrigin ? { workspaceOAuthOrigin } : {}),
1019
+ ...(workspaceRuntime ? { workspaceRuntime: true } : {}),
1000
1020
  };
1001
1021
  if (Object.keys(config).length === 0) return null;
1002
1022
  return (
@@ -3044,8 +3064,12 @@ function reportNetlifyFunctionSizes(internalDir, failures) {
3044
3064
  export function assertSingleTemplateNetlifyBuildOutput(projectCwd) {
3045
3065
  const failures = [];
3046
3066
  const publishDir = path.join(projectCwd, "dist");
3047
- const workspaceAppBasePath = process.env.AGENT_NATIVE_WORKSPACE === "1" ||
3048
- process.env.VITE_AGENT_NATIVE_WORKSPACE === "1"
3067
+ const workspaceAppBasePath = [
3068
+ process.env.AGENT_NATIVE_WORKSPACE,
3069
+ process.env.VITE_AGENT_NATIVE_WORKSPACE,
3070
+ ].some((value) => isTruthyRuntimeValue(value)) ||
3071
+ Boolean(process.env.AGENT_NATIVE_WORKSPACE_APPS_JSON?.trim()) ||
3072
+ Boolean(process.env.VITE_AGENT_NATIVE_WORKSPACE_APPS_JSON?.trim())
3049
3073
  ? normalizeConfiguredAppBasePath()
3050
3074
  : "";
3051
3075
  const assetsRelativeDir = workspaceAppBasePath
@@ -17,11 +17,11 @@ declare const _default: import("../../action.js").ActionDefinition<{
17
17
  id?: undefined;
18
18
  provider?: undefined;
19
19
  } | {
20
- error?: undefined;
21
20
  configured?: undefined;
22
21
  connectPath?: undefined;
23
22
  url: string;
24
23
  id: string;
25
24
  provider: string;
25
+ error?: undefined;
26
26
  }>;
27
27
  export default _default;
@@ -28,6 +28,6 @@ export declare function createNotificationsHandler(): import("h3").EventHandlerW
28
28
  } | {
29
29
  count?: undefined;
30
30
  updated?: undefined;
31
- ok: boolean;
32
31
  error?: undefined;
32
+ ok: boolean;
33
33
  }>>;
@@ -41,27 +41,27 @@ export declare function createObservabilityHandler(): import("h3").EventHandlerW
41
41
  thumbsUpRate: number;
42
42
  avgEvalScore: number;
43
43
  } | {
44
+ error?: undefined;
45
+ ok?: undefined;
44
46
  summary: import("./types.js").TraceSummary;
45
47
  spans: import("./types.js").TraceSpan[];
46
48
  id?: undefined;
49
+ } | {
47
50
  error?: undefined;
48
51
  ok?: undefined;
49
- } | {
50
52
  summary?: undefined;
51
53
  spans?: undefined;
52
54
  id: string;
53
- error?: undefined;
54
- ok?: undefined;
55
55
  } | {
56
+ ok?: undefined;
56
57
  summary?: undefined;
57
58
  spans?: undefined;
58
59
  id?: undefined;
59
60
  error: any;
60
- ok?: undefined;
61
61
  } | {
62
+ error?: undefined;
62
63
  summary?: undefined;
63
64
  spans?: undefined;
64
65
  id?: undefined;
65
66
  ok: boolean;
66
- error?: undefined;
67
67
  }>>;
@@ -75,9 +75,10 @@ export declare function createCustomProviderRegistrationAction<TSchema extends Z
75
75
  user: "user";
76
76
  }>>;
77
77
  }, z.core.$strip>>, {
78
+ message?: undefined;
78
79
  id?: undefined;
79
- provider?: undefined;
80
80
  deleted?: undefined;
81
+ found?: undefined;
81
82
  providers: {
82
83
  id: string;
83
84
  label: string;
@@ -88,46 +89,45 @@ export declare function createCustomProviderRegistrationAction<TSchema extends Z
88
89
  updatedAt: number;
89
90
  }[];
90
91
  count: number;
91
- found?: undefined;
92
+ provider?: undefined;
92
93
  registered?: undefined;
93
94
  label?: undefined;
94
- message?: undefined;
95
95
  } | {
96
+ message?: undefined;
97
+ count?: undefined;
96
98
  id?: undefined;
97
99
  deleted?: undefined;
98
100
  providers?: undefined;
99
- count?: undefined;
100
101
  found: boolean;
101
102
  provider: import("../custom-registry.js").CustomProviderConfig;
102
103
  registered?: undefined;
103
104
  label?: undefined;
104
- message?: undefined;
105
105
  } | {
106
- provider?: undefined;
106
+ message?: undefined;
107
+ count?: undefined;
107
108
  deleted?: undefined;
108
109
  providers?: undefined;
109
- count?: undefined;
110
+ provider?: undefined;
110
111
  found: boolean;
111
112
  id: string;
112
113
  registered?: undefined;
113
114
  label?: undefined;
114
- message?: undefined;
115
115
  } | {
116
- provider?: undefined;
117
- providers?: undefined;
116
+ message?: undefined;
118
117
  count?: undefined;
119
118
  found?: undefined;
119
+ providers?: undefined;
120
+ provider?: undefined;
120
121
  deleted: boolean;
121
122
  id: string;
122
123
  registered?: undefined;
123
124
  label?: undefined;
124
- message?: undefined;
125
125
  } | {
126
- provider?: undefined;
127
- deleted?: undefined;
128
- providers?: undefined;
129
126
  count?: undefined;
127
+ deleted?: undefined;
130
128
  found?: undefined;
129
+ providers?: undefined;
130
+ provider?: undefined;
131
131
  registered: boolean;
132
132
  id: string;
133
133
  label: string;
@@ -312,7 +312,9 @@ export declare function createProviderApiActions(runtime: Pick<ProviderApiRuntim
312
312
  scope?: "org" | "user" | undefined;
313
313
  }, {
314
314
  id?: undefined;
315
- message?: undefined;
315
+ deleted?: undefined;
316
+ provider?: undefined;
317
+ found?: undefined;
316
318
  providers: {
317
319
  id: string;
318
320
  label: string;
@@ -323,47 +325,45 @@ export declare function createProviderApiActions(runtime: Pick<ProviderApiRuntim
323
325
  updatedAt: number;
324
326
  }[];
325
327
  count: number;
326
- provider?: undefined;
327
- found?: undefined;
328
- deleted?: undefined;
329
328
  registered?: undefined;
330
329
  label?: undefined;
330
+ message?: undefined;
331
331
  } | {
332
332
  id?: undefined;
333
- message?: undefined;
333
+ deleted?: undefined;
334
334
  providers?: undefined;
335
335
  count?: undefined;
336
336
  found: boolean;
337
337
  provider: import("../custom-registry.js").CustomProviderConfig;
338
- deleted?: undefined;
339
338
  registered?: undefined;
340
339
  label?: undefined;
341
- } | {
342
340
  message?: undefined;
341
+ } | {
342
+ deleted?: undefined;
343
+ provider?: undefined;
343
344
  providers?: undefined;
344
345
  count?: undefined;
345
- provider?: undefined;
346
346
  found: boolean;
347
347
  id: string;
348
- deleted?: undefined;
349
348
  registered?: undefined;
350
349
  label?: undefined;
351
- } | {
352
350
  message?: undefined;
353
- providers?: undefined;
354
- count?: undefined;
351
+ } | {
355
352
  provider?: undefined;
356
353
  found?: undefined;
354
+ providers?: undefined;
355
+ count?: undefined;
357
356
  deleted: boolean;
358
357
  id: string;
359
358
  registered?: undefined;
360
359
  label?: undefined;
360
+ message?: undefined;
361
361
  } | {
362
- providers?: undefined;
363
- count?: undefined;
362
+ deleted?: undefined;
364
363
  provider?: undefined;
365
364
  found?: undefined;
366
- deleted?: undefined;
365
+ providers?: undefined;
366
+ count?: undefined;
367
367
  registered: boolean;
368
368
  id: string;
369
369
  label: string;
@@ -34,37 +34,37 @@ export declare function createListSecretsHandler(): import("h3").EventHandlerWit
34
34
  /** POST /_agent-native/secrets/:key — write a secret. */
35
35
  export declare function createWriteSecretHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
36
36
  error: string;
37
- status?: undefined;
38
37
  ok?: undefined;
38
+ status?: undefined;
39
39
  } | {
40
+ error?: undefined;
40
41
  ok: boolean;
41
42
  status: string;
42
- error?: undefined;
43
43
  } | {
44
+ ok?: undefined;
44
45
  error: string;
45
46
  removed?: undefined;
46
- ok?: undefined;
47
47
  } | {
48
+ error?: undefined;
48
49
  ok: boolean;
49
50
  removed: boolean;
50
- error?: undefined;
51
51
  }>>;
52
52
  /**
53
53
  * POST /_agent-native/secrets/:key/test — validate an optional candidate value
54
54
  * or the current stored value without changing anything.
55
55
  */
56
56
  export declare function createTestSecretHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
57
+ ok?: undefined;
57
58
  error: string;
58
59
  note?: undefined;
59
- ok?: undefined;
60
60
  } | {
61
+ error?: undefined;
61
62
  ok: boolean;
62
63
  note?: undefined;
63
- error?: undefined;
64
64
  } | {
65
+ error?: undefined;
65
66
  ok: boolean;
66
67
  note: string;
67
- error?: undefined;
68
68
  } | {
69
69
  note?: undefined;
70
70
  ok: boolean;
@@ -95,11 +95,11 @@ export interface AdHocSecretPayload {
95
95
  export declare function createAdHocSecretHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<AdHocSecretPayload[] | {
96
96
  error: string;
97
97
  } | {
98
+ error?: undefined;
98
99
  ok: boolean;
99
100
  key: string;
100
- error?: undefined;
101
101
  } | {
102
+ error?: undefined;
102
103
  ok: boolean;
103
104
  removed: boolean;
104
- error?: undefined;
105
105
  }>>;
@@ -27,10 +27,10 @@ export declare function resolveAgentEngineApiKeyWriteTarget(event: H3Event, scop
27
27
  export declare function createAgentEngineApiKeyHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
28
28
  error: any;
29
29
  } | {
30
+ error?: undefined;
30
31
  ok: boolean;
31
32
  key: string;
32
33
  baseUrlKey?: string;
33
34
  scope: AgentEngineApiKeyScope;
34
- error?: undefined;
35
35
  }>>;
36
36
  export {};
@@ -19,5 +19,6 @@ export declare function resolvePublicAppOriginConfig(): {
19
19
  appUrl?: string;
20
20
  workspaceGatewayUrl?: string;
21
21
  workspaceOAuthOrigin?: string;
22
+ workspaceRuntime?: boolean;
22
23
  } | null;
23
24
  export declare function getAppOriginClientConfigScript(): string | null;
@@ -18,6 +18,8 @@ import { getAppConfig } from "../app-config/index.js";
18
18
  */
19
19
  export function resolvePublicAppOriginConfig() {
20
20
  const config = getAppConfig();
21
+ const workspaceRuntime = config.workspace.isWorkspace === true ||
22
+ typeof config.workspace.appsJson === "string";
21
23
  const resolved = {
22
24
  ...(config.app.url ? { appUrl: config.app.url } : {}),
23
25
  ...(config.workspace.gatewayUrl
@@ -26,6 +28,7 @@ export function resolvePublicAppOriginConfig() {
26
28
  ...(config.workspace.oauthOrigin
27
29
  ? { workspaceOAuthOrigin: config.workspace.oauthOrigin }
28
30
  : {}),
31
+ ...(workspaceRuntime ? { workspaceRuntime: true } : {}),
29
32
  };
30
33
  return Object.keys(resolved).length > 0 ? resolved : null;
31
34
  }
@@ -37,6 +37,12 @@ export interface AuthOptions {
37
37
  * Both page routes and API routes can be made public.
38
38
  */
39
39
  publicPaths?: string[];
40
+ /**
41
+ * Public, unauthenticated ingest paths that may receive cross-origin
42
+ * requests when CORS_ALLOWED_ORIGINS is unset. These routes must perform
43
+ * their own request validation and must not rely on cookies for auth.
44
+ */
45
+ publicCorsPaths?: string[];
40
46
  /**
41
47
  * Workspace-level audience for the app.
42
48
  *
@@ -1380,11 +1380,11 @@ export async function runAuthGuard(event) {
1380
1380
  * unauthenticated requests. Returns the login HTML for page routes
1381
1381
  * or a 401 JSON response for API routes.
1382
1382
  *
1383
- * Reads loginHtml and publicPaths from _authGuardConfig on every request
1383
+ * Reads loginHtml and public paths from _authGuardConfig on every request
1384
1384
  * so that a custom plugin can update them after the default has already
1385
1385
  * installed this middleware (the production race condition fix).
1386
1386
  */
1387
- function applyCorsHeaders(event) {
1387
+ function applyCorsHeaders(event, publicCorsPaths = [], requestPath) {
1388
1388
  // Framework-level CORS. The auth guard runs before any of the app's own
1389
1389
  // route handlers, so we need to set CORS here too — otherwise a 401
1390
1390
  // response would be missing the Allow-Origin header and the browser
@@ -1404,15 +1404,22 @@ function applyCorsHeaders(event) {
1404
1404
  Boolean(getHeader(event, EMBED_TARGET_HEADER)) ||
1405
1405
  Boolean(getHeader(event, EMBED_TRANSPLANT_HEADER)) ||
1406
1406
  Boolean(getHeader(event, "authorization")));
1407
+ const isPublicCorsPath = Boolean(requestPath && matchesPathList(requestPath, publicCorsPaths));
1407
1408
  const allowedOrigin = getAllowedCorsOrigin(origin, {
1408
1409
  allowedOrigins: readCorsAllowedOrigins(),
1410
+ // Public ingestion endpoints such as analytics replay are intentionally
1411
+ // callable by browser apps on arbitrary origins. The endpoint still owns
1412
+ // its public-key, payload, quota, and origin checks; this only lets the
1413
+ // browser complete the preflight when no deployment-wide allowlist exists.
1414
+ allowAnyOriginWhenNoAllowlist: isPublicCorsPath,
1409
1415
  });
1410
1416
  const responseOrigin = mcpEmbedCorsRequest ? origin : allowedOrigin;
1411
1417
  if (!responseOrigin)
1412
1418
  return { hasOrigin: true, allowed: false };
1413
1419
  setResponseHeader(event, "Access-Control-Allow-Origin", responseOrigin);
1414
1420
  setResponseHeader(event, "Vary", "Origin");
1415
- if (!mcpEmbedCorsRequest || shouldAllowMcpEmbedCredentials(responseOrigin)) {
1421
+ if (!isPublicCorsPath &&
1422
+ (!mcpEmbedCorsRequest || shouldAllowMcpEmbedCredentials(responseOrigin))) {
1416
1423
  setResponseHeader(event, "Access-Control-Allow-Credentials", "true");
1417
1424
  }
1418
1425
  setResponseHeader(event, "Access-Control-Allow-Methods", "GET,HEAD,POST,PUT,PATCH,DELETE,OPTIONS");
@@ -1431,7 +1438,7 @@ function applyCorsHeaders(event) {
1431
1438
  }
1432
1439
  function createAuthCorsHandler() {
1433
1440
  return defineEventHandler((event) => {
1434
- const cors = applyCorsHeaders(event);
1441
+ const cors = applyCorsHeaders(event, _authGuardConfig?.publicCorsPaths);
1435
1442
  if (getMethod(event) !== "OPTIONS")
1436
1443
  return;
1437
1444
  if (cors.hasOrigin && !cors.allowed) {
@@ -1835,7 +1842,7 @@ function createAuthGuardFn(app) {
1835
1842
  return callbackRelay;
1836
1843
  // Emit CORS headers on every request the guard sees so that even
1837
1844
  // error responses (401) reach the browser.
1838
- const cors = applyCorsHeaders(event);
1845
+ const cors = applyCorsHeaders(event, config.publicCorsPaths, p);
1839
1846
  // Preflight short-circuit: the browser sends OPTIONS before the real
1840
1847
  // credentialed request. Must return success without invoking auth.
1841
1848
  if (getMethod(event) === "OPTIONS") {
@@ -2950,8 +2957,8 @@ async function mountBetterAuthRoutes(app, options) {
2950
2957
  redirectPath: oauthDebugUrlPath(redirectUri),
2951
2958
  returnUrl,
2952
2959
  redirect: q.redirect === "1",
2953
- workspace: process.env.AGENT_NATIVE_WORKSPACE === "1" ||
2954
- process.env.VITE_AGENT_NATIVE_WORKSPACE === "1",
2960
+ workspace: getAppConfig().workspace.isWorkspace === true ||
2961
+ typeof getAppConfig().workspace.appsJson === "string",
2955
2962
  });
2956
2963
  const params = new URLSearchParams({
2957
2964
  client_id: googleSignInCredentials.clientId,
@@ -4039,6 +4046,7 @@ async function mountBetterAuthRoutes(app, options) {
4039
4046
  _authGuardConfig = {
4040
4047
  ...loginHtmlConfig,
4041
4048
  publicPaths,
4049
+ publicCorsPaths: options.publicCorsPaths ?? [],
4042
4050
  workspaceAppAudience,
4043
4051
  workspaceAppPublicPaths: workspaceAppRouteAccess.publicPaths,
4044
4052
  workspaceAppProtectedPaths: workspaceAppRouteAccess.protectedPaths,
@@ -4236,6 +4244,14 @@ export async function autoMountAuth(app, options = {}) {
4236
4244
  ...options.publicPaths,
4237
4245
  ];
4238
4246
  }
4247
+ if (options.publicCorsPaths) {
4248
+ _authGuardConfig.publicCorsPaths = [
4249
+ ...new Set([
4250
+ ...(_authGuardConfig.publicCorsPaths ?? []),
4251
+ ...options.publicCorsPaths,
4252
+ ]),
4253
+ ];
4254
+ }
4239
4255
  if (options.workspaceAppAudience) {
4240
4256
  _authGuardConfig.workspaceAppAudience =
4241
4257
  resolveWorkspaceAppAudience(options);
@@ -4307,6 +4323,7 @@ export async function autoMountAuth(app, options = {}) {
4307
4323
  getLoginHtml: () => getCustomAuthRequiredHtml(),
4308
4324
  }),
4309
4325
  publicPaths,
4326
+ publicCorsPaths: options.publicCorsPaths ?? [],
4310
4327
  workspaceAppAudience,
4311
4328
  workspaceAppPublicPaths: workspaceAppRouteAccess.publicPaths,
4312
4329
  workspaceAppProtectedPaths: workspaceAppRouteAccess.protectedPaths,
@@ -4334,6 +4351,7 @@ export async function autoMountAuth(app, options = {}) {
4334
4351
  _authGuardConfig = {
4335
4352
  ...loginHtmlConfig,
4336
4353
  publicPaths,
4354
+ publicCorsPaths: options.publicCorsPaths ?? [],
4337
4355
  workspaceAppAudience,
4338
4356
  workspaceAppPublicPaths: workspaceAppRouteAccess.publicPaths,
4339
4357
  workspaceAppProtectedPaths: workspaceAppRouteAccess.protectedPaths,