@agent-native/core 0.164.3 → 0.164.11

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 (234) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/templates/calendar/app/components/calendar/CreateEventDialog.tsx +36 -47
  3. package/corpus/templates/calendar/app/components/calendar/DayView.tsx +3 -0
  4. package/corpus/templates/calendar/app/components/calendar/EventDetailPopover.tsx +18 -1
  5. package/corpus/templates/calendar/app/components/calendar/InlineEventPickers.tsx +256 -38
  6. package/corpus/templates/calendar/app/hooks/use-google-auth.ts +43 -3
  7. package/corpus/templates/calendar/app/i18n-data.ts +120 -0
  8. package/corpus/templates/calendar/app/lib/event-form-utils.ts +113 -0
  9. package/corpus/templates/calendar/server/handlers/google-auth.ts +119 -3
  10. package/corpus/templates/calendar/server/routes/[base]/_agent-native/google/add-account/auth-url.post.ts +1 -0
  11. package/corpus/templates/calendar/server/routes/[base]/_agent-native/google/auth-url.post.ts +1 -0
  12. package/corpus/templates/calendar/server/routes/_agent-native/google/add-account/auth-url.post.ts +1 -0
  13. package/corpus/templates/calendar/server/routes/_agent-native/google/auth-url.post.ts +1 -0
  14. package/corpus/templates/clips/.agents/skills/video-sharing/SKILL.md +1 -1
  15. package/corpus/templates/clips/app/components/player/video-player.tsx +12 -0
  16. package/corpus/templates/clips/app/routes/_app.dictate.tsx +18 -4
  17. package/corpus/templates/clips/app/routes/r.$recordingId.tsx +114 -20
  18. package/corpus/templates/clips/app/routes/share.$shareId.tsx +86 -78
  19. package/corpus/templates/clips/changelog/2026-08-19-clips-nightly-builds-are-available-for-trying-the-latest-upd.md +6 -0
  20. package/corpus/templates/clips/changelog/2026-08-19-social-preview-video-frames.md +6 -0
  21. package/corpus/templates/clips/desktop/README.md +19 -4
  22. package/corpus/templates/clips/desktop/src/app.tsx +78 -16
  23. package/corpus/templates/clips/desktop/src-tauri/Cargo.toml +3 -2
  24. package/corpus/templates/clips/desktop/src-tauri/tauri.conf.json +1 -0
  25. package/corpus/templates/clips/server/lib/slack-unfurls.ts +7 -13
  26. package/corpus/templates/clips/server/routes/[base]/_agent-native/google/auth-url.post.ts +1 -0
  27. package/corpus/templates/clips/server/routes/_agent-native/google/auth-url.get.ts +41 -3
  28. package/corpus/templates/clips/server/routes/_agent-native/google/auth-url.post.ts +1 -0
  29. package/corpus/templates/clips/server/routes/_agent-native/google/callback.get.ts +22 -1
  30. package/corpus/templates/clips/server/routes/api/clips-updater.json.get.ts +41 -22
  31. package/corpus/templates/clips/shared/share-meta.ts +67 -3
  32. package/corpus/templates/content/actions/list-content-databases.ts +95 -1
  33. package/corpus/templates/content/changelog/2026-08-11-content-mutations-delegated-from-verified-slack-dms-now-use-.md +6 -0
  34. package/corpus/templates/content/shared/api.ts +11 -0
  35. package/corpus/templates/factory/AGENTS.md +1 -1
  36. package/corpus/templates/factory/actions/list-factory-automations.ts +4 -0
  37. package/corpus/templates/factory/actions/start-builder-for-item.ts +19 -17
  38. package/corpus/templates/factory/app/components/factory/FactoryAuditView.tsx +100 -36
  39. package/corpus/templates/factory/app/i18n/en-US.ts +4 -0
  40. package/corpus/templates/factory/app/routes/factory.tsx +209 -46
  41. package/corpus/templates/factory/server/connectors/slack.ts +44 -2
  42. package/corpus/templates/factory/server/plugins/agent-chat.ts +9 -7
  43. package/corpus/templates/factory/server/plugins/factory-scheduler-job.ts +13 -0
  44. package/corpus/templates/factory/server/triage/slack-client.ts +5 -0
  45. package/corpus/templates/factory/server/triage/slack-poller.ts +72 -4
  46. package/corpus/templates/mail/actions/view-screen.ts +1 -1
  47. package/corpus/templates/mail/app/components/GoogleConnectBanner.tsx +100 -18
  48. package/corpus/templates/mail/server/handlers/google-auth.ts +125 -24
  49. package/corpus/templates/mail/server/lib/gmail-query.ts +5 -2
  50. package/corpus/templates/mail/server/routes/[base]/_agent-native/google/add-account/auth-url.post.ts +1 -0
  51. package/corpus/templates/mail/server/routes/[base]/_agent-native/google/auth-url.post.ts +1 -0
  52. package/corpus/templates/mail/server/routes/_agent-native/google/add-account/auth-url.post.ts +1 -0
  53. package/corpus/templates/mail/server/routes/_agent-native/google/auth-url.post.ts +1 -0
  54. package/corpus/templates/plan/app/pages/PlansPage.tsx +0 -12
  55. package/corpus/templates/plan/changelog/2026-08-19-plan-prompts-now-guide-you-to-connect-ai-before-sending-and-.md +6 -0
  56. package/corpus/templates/slides/actions/approve-deck-access-request.ts +234 -0
  57. package/corpus/templates/slides/actions/get-deck-access-status.ts +35 -2
  58. package/corpus/templates/slides/actions/request-deck-access.ts +263 -64
  59. package/corpus/templates/slides/app/components/editor/MissingDeckAccessPane.tsx +196 -0
  60. package/corpus/templates/slides/app/components/editor/RequestDeckAccessDialog.tsx +101 -0
  61. package/corpus/templates/slides/app/hooks/use-deck-access.ts +7 -4
  62. package/corpus/templates/slides/app/i18n/en-US.ts +29 -6
  63. package/corpus/templates/slides/app/pages/DeckEditor.tsx +147 -169
  64. package/corpus/templates/slides/app/routes/access-request.approve.tsx +250 -0
  65. package/corpus/templates/slides/server/db/schema.ts +8 -0
  66. package/corpus/templates/slides/server/lib/access-request-email.ts +36 -0
  67. package/corpus/templates/slides/server/lib/emails.ts +26 -0
  68. package/corpus/templates/slides/server/plugins/agent-chat.ts +7 -0
  69. package/corpus/templates/slides/server/plugins/db.ts +50 -0
  70. package/corpus/templates/slides/shared/deck-access.ts +31 -0
  71. package/dist/a2a/artifact-response.d.ts +50 -0
  72. package/dist/a2a/artifact-response.js +266 -39
  73. package/dist/a2a/index.d.ts +2 -0
  74. package/dist/a2a/index.js +1 -0
  75. package/dist/a2a/task-store.d.ts +1 -0
  76. package/dist/a2a/task-store.js +1 -1
  77. package/dist/agent/observational-memory/store.d.ts +1 -0
  78. package/dist/agent/observational-memory/store.js +1 -1
  79. package/dist/agent/run-store.d.ts +1 -0
  80. package/dist/agent/run-store.js +1 -1
  81. package/dist/agent/tool-approval-store.d.ts +1 -0
  82. package/dist/agent/tool-approval-store.js +1 -1
  83. package/dist/application-state/store.d.ts +1 -0
  84. package/dist/application-state/store.js +1 -1
  85. package/dist/browser-sessions/store.d.ts +1 -0
  86. package/dist/browser-sessions/store.js +1 -1
  87. package/dist/checkpoints/store.d.ts +1 -0
  88. package/dist/checkpoints/store.js +1 -1
  89. package/dist/cli/code-agent-schedules.d.ts +11 -0
  90. package/dist/cli/code-agent-schedules.js +44 -5
  91. package/dist/client/AgentPanel.d.ts +5 -1
  92. package/dist/client/AgentPanel.js +2 -2
  93. package/dist/client/AssistantChat.d.ts +5 -1
  94. package/dist/client/AssistantChat.js +40 -6
  95. package/dist/client/EnvironmentBadge.d.ts +7 -13
  96. package/dist/client/EnvironmentBadge.js +43 -92
  97. package/dist/client/agent-chat/index.d.ts +1 -0
  98. package/dist/client/agent-chat/index.js +1 -0
  99. package/dist/client/agent-chat-adapter.js +76 -50
  100. package/dist/client/app-providers.js +4 -4
  101. package/dist/client/chat/message-components.d.ts +4 -0
  102. package/dist/client/chat/message-components.js +28 -1
  103. package/dist/client/chat/run-recovery.js +26 -0
  104. package/dist/client/chat-first/apps-rail.d.ts +1 -0
  105. package/dist/client/chat-first/apps-rail.js +28 -2
  106. package/dist/client/sse-event-processor.js +13 -8
  107. package/dist/client/use-active-agent-chat-run.d.ts +2 -0
  108. package/dist/client/use-active-agent-chat-run.js +22 -0
  109. package/dist/coding-tools/sandbox/executions-store.d.ts +1 -0
  110. package/dist/coding-tools/sandbox/executions-store.js +1 -1
  111. package/dist/collab/awareness-store.d.ts +1 -0
  112. package/dist/collab/awareness-store.js +1 -1
  113. package/dist/collab/routes.d.ts +1 -1
  114. package/dist/collab/storage.d.ts +1 -0
  115. package/dist/collab/storage.js +1 -1
  116. package/dist/db/client.js +3 -3
  117. package/dist/db/ddl-guard.js +8 -0
  118. package/dist/db/migration-runtime.d.ts +23 -0
  119. package/dist/db/migration-runtime.js +41 -0
  120. package/dist/db/migrations.d.ts +1 -2
  121. package/dist/db/migrations.js +2 -24
  122. package/dist/email-catalog/log.d.ts +1 -0
  123. package/dist/email-catalog/log.js +1 -1
  124. package/dist/guards/index.d.ts +1 -0
  125. package/dist/guards/index.js +1 -0
  126. package/dist/guards/release-schema-complete.d.ts +22 -0
  127. package/dist/guards/release-schema-complete.js +144 -0
  128. package/dist/integrations/a2a-continuations-store.d.ts +1 -0
  129. package/dist/integrations/a2a-continuations-store.js +1 -1
  130. package/dist/integrations/adapters/slack.js +58 -7
  131. package/dist/integrations/awaiting-input-store.d.ts +1 -0
  132. package/dist/integrations/awaiting-input-store.js +1 -1
  133. package/dist/integrations/config-store.d.ts +1 -0
  134. package/dist/integrations/config-store.js +1 -1
  135. package/dist/integrations/controls-store.d.ts +1 -0
  136. package/dist/integrations/controls-store.js +1 -1
  137. package/dist/integrations/identity-links-store.d.ts +1 -0
  138. package/dist/integrations/identity-links-store.js +1 -1
  139. package/dist/integrations/installations-store.d.ts +1 -0
  140. package/dist/integrations/installations-store.js +1 -1
  141. package/dist/integrations/remote-commands-store.d.ts +1 -0
  142. package/dist/integrations/remote-commands-store.js +1 -1
  143. package/dist/integrations/remote-devices-store.d.ts +1 -0
  144. package/dist/integrations/remote-devices-store.js +1 -1
  145. package/dist/integrations/remote-push-store.d.ts +1 -0
  146. package/dist/integrations/remote-push-store.js +1 -1
  147. package/dist/integrations/remote-run-events-store.d.ts +1 -0
  148. package/dist/integrations/remote-run-events-store.js +1 -1
  149. package/dist/integrations/scope-store.d.ts +1 -0
  150. package/dist/integrations/scope-store.js +1 -1
  151. package/dist/integrations/thread-mapping-store.d.ts +1 -0
  152. package/dist/integrations/thread-mapping-store.js +1 -1
  153. package/dist/integrations/usage-budget-store.d.ts +1 -0
  154. package/dist/integrations/usage-budget-store.js +1 -1
  155. package/dist/jobs/background-automation-runner.js +111 -9
  156. package/dist/jobs/run-history.d.ts +1 -0
  157. package/dist/jobs/run-history.js +1 -1
  158. package/dist/jobs/scheduler-health.d.ts +1 -0
  159. package/dist/jobs/scheduler-health.js +1 -1
  160. package/dist/mcp/approval-store.d.ts +1 -0
  161. package/dist/mcp/approval-store.js +1 -1
  162. package/dist/mcp/connect-store.d.ts +1 -0
  163. package/dist/mcp/connect-store.js +1 -1
  164. package/dist/mcp/oauth-store.d.ts +1 -0
  165. package/dist/mcp/oauth-store.js +1 -1
  166. package/dist/notifications/routes.d.ts +3 -3
  167. package/dist/notifications/store.d.ts +1 -0
  168. package/dist/notifications/store.js +1 -1
  169. package/dist/oauth-tokens/store.d.ts +1 -0
  170. package/dist/oauth-tokens/store.js +1 -1
  171. package/dist/observability/routes.d.ts +3 -3
  172. package/dist/progress/routes.d.ts +1 -1
  173. package/dist/progress/store.d.ts +1 -0
  174. package/dist/progress/store.js +1 -1
  175. package/dist/provider-api/actions/custom-provider-registration.d.ts +5 -5
  176. package/dist/provider-api/actions/provider-api.d.ts +4 -4
  177. package/dist/provider-api/corpus-jobs-store.d.ts +1 -0
  178. package/dist/provider-api/corpus-jobs-store.js +1 -1
  179. package/dist/provider-api/custom-registry.d.ts +1 -0
  180. package/dist/provider-api/custom-registry.js +1 -1
  181. package/dist/provider-api/quota-governor.d.ts +1 -0
  182. package/dist/provider-api/quota-governor.js +1 -1
  183. package/dist/provider-api/staged-datasets-store.d.ts +1 -0
  184. package/dist/provider-api/staged-datasets-store.js +1 -1
  185. package/dist/resources/handlers.d.ts +3 -3
  186. package/dist/resources/store.d.ts +1 -0
  187. package/dist/resources/store.js +1 -1
  188. package/dist/scripts/dev/index.js +15 -1
  189. package/dist/search/index.js +3 -0
  190. package/dist/secrets/storage.d.ts +1 -0
  191. package/dist/secrets/storage.js +1 -1
  192. package/dist/server/agent-chat/action-filters-a2a.d.ts +2 -1
  193. package/dist/server/agent-chat/action-filters-a2a.js +10 -2
  194. package/dist/server/agent-chat-plugin.js +71 -20
  195. package/dist/server/agent-teams-run-queue.d.ts +1 -0
  196. package/dist/server/agent-teams-run-queue.js +1 -1
  197. package/dist/server/auth-marketing.js +3 -1
  198. package/dist/server/auth.d.ts +18 -1
  199. package/dist/server/auth.js +370 -154
  200. package/dist/server/embed-session.d.ts +1 -0
  201. package/dist/server/embed-session.js +1 -1
  202. package/dist/server/google-auth-plugin.js +3 -1
  203. package/dist/server/google-oauth.d.ts +10 -0
  204. package/dist/server/google-oauth.js +25 -1
  205. package/dist/server/identity-sso-store.d.ts +1 -0
  206. package/dist/server/identity-sso-store.js +1 -1
  207. package/dist/server/index.d.ts +1 -1
  208. package/dist/server/index.js +1 -1
  209. package/dist/server/onboarding-html.js +200 -31
  210. package/dist/server/poll.d.ts +2 -0
  211. package/dist/server/poll.js +19 -1
  212. package/dist/server/realtime-token.d.ts +1 -1
  213. package/dist/server/release-migrations.js +5 -0
  214. package/dist/server/release-schema.d.ts +46 -0
  215. package/dist/server/release-schema.js +307 -0
  216. package/dist/settings/store.d.ts +1 -0
  217. package/dist/settings/store.js +1 -1
  218. package/dist/shared/environment-lanes.d.ts +28 -0
  219. package/dist/shared/environment-lanes.js +61 -0
  220. package/dist/sharing/actions/share-resource.js +22 -2
  221. package/dist/styles/agent-native.css +17 -15
  222. package/dist/triggers/routes.d.ts +11 -0
  223. package/dist/triggers/routes.js +10 -0
  224. package/dist/usage/alerts-store.d.ts +1 -0
  225. package/dist/usage/alerts-store.js +1 -1
  226. package/dist/usage/store.d.ts +1 -0
  227. package/dist/usage/store.js +1 -1
  228. package/docs/content/drop-in-agent.mdx +4 -4
  229. package/docs/content/faq.mdx +15 -15
  230. package/docs/content/getting-started.mdx +173 -41
  231. package/docs/content/key-concepts.mdx +10 -10
  232. package/docs/content/using-your-agent.mdx +2 -2
  233. package/docs/content/what-is-agent-native.mdx +79 -228
  234. package/package.json +2 -2
@@ -44,10 +44,14 @@ import { useRunStuckDetection } from "./use-run-stuck-detection.js";
44
44
  import { cn } from "./utils.js";
45
45
  export { AssistantMessageListErrorBoundary, AssistantUiStaleIndexErrorBoundary, assistantUiRecoverableRenderErrorKind, isAssistantUiRecoverableRenderError, isAssistantUiStaleIndexError, } from "./assistant-ui-recovery.js";
46
46
  export { displayableUserMessageText } from "./chat/message-components.js";
47
- // Desktop chat mounts beside the parent identity gate, so an unauthenticated
48
- // relay is an expected empty state until that gate establishes a session.
49
- export function shouldSuppressUnauthenticatedDesktopThreadRestore(surface, status) {
50
- return surface === "desktop" && (status === 401 || status === 403);
47
+ // Desktop chat mounts beside the parent identity gate. The server masks an
48
+ // unauthenticated thread lookup as 404, so a stale local pointer must not turn
49
+ // the sign-in screen into a dead-thread error.
50
+ export function shouldSuppressUnauthenticatedDesktopThreadRestore(surface, status, desktopIdentityUnauthenticated = false) {
51
+ return (surface === "desktop" &&
52
+ (status === 401 ||
53
+ status === 403 ||
54
+ (status === 404 && desktopIdentityUnauthenticated)));
51
55
  }
52
56
  const useBrowserLayoutEffect = typeof window === "undefined" ? useEffect : useLayoutEffect;
53
57
  export function assistantUiMessageListStructureKey(messages) {
@@ -1382,7 +1386,7 @@ function approvalResolutionIdentity(approvalKey, toolCallId,
1382
1386
  askId) {
1383
1387
  return `${toolCallId ?? ""}\u0000${approvalKey}\u0000${askId ?? ""}`;
1384
1388
  }
1385
- const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateText, suggestions, dynamicSuggestions, threadFooterSlot, emptyStateAddon, showHeader = true, onSwitchToCli, className, apiUrl, tabId, browserTabId, threadId, contextScope, contextNamespace, isActiveComposer = true, onMessageCountChange, onSaveThread, onGenerateTitle, composerSlot, onComposerTextChange, composerAreaClassName, composerPlaceholder, missingApiKeySetupLayout = "default", composerLayoutVariant = "default", centerComposerWhenEmpty = false, emptyStateDisplay = "default", composerToolbarSlot, composerExtraActionButton, showModelSelector = true, composerDisabled = false, composerDisabledPlaceholder, isNewThread, isThreadStateLoading, onSlashCommand, execMode, onExecModeChange, approvalActions, planModeDisabled, planModeDisabledReason, selectedModel, defaultModel, selectedEngine, selectedEffort, availableModels, modelListLoading, onModelChange, onEffortChange, availableAgents, selectedAgent, hostedHarness, onAgentChange, imageModelMenu, onForkChat, onConnectProvider, onConnectLocalRuntime, plusMenuMode = "full", providerStatusChecksEnabled = true, loadHistoryRepository, historyReloadKey, externalStreaming = false, agentChatSurface = "app", suppressInlineOpenApp = false, }, ref) {
1389
+ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateText, suggestions, dynamicSuggestions, threadFooterSlot, emptyStateAddon, showHeader = true, onSwitchToCli, className, apiUrl, tabId, browserTabId, threadId, contextScope, contextNamespace, isActiveComposer = true, onMessageCountChange, onSaveThread, onGenerateTitle, composerSlot, onComposerTextChange, composerAreaClassName, composerPlaceholder, missingApiKeySetupLayout = "default", composerLayoutVariant = "default", centerComposerWhenEmpty = false, emptyStateDisplay = "default", composerToolbarSlot, composerExtraActionButton, showModelSelector = true, composerDisabled = false, composerDisabledPlaceholder, isNewThread, isThreadStateLoading, onSlashCommand, execMode, onExecModeChange, approvalActions, planModeDisabled, planModeDisabledReason, selectedModel, defaultModel, selectedEngine, selectedEffort, availableModels, modelListLoading, onModelChange, onEffortChange, availableAgents, selectedAgent, hostedHarness, onAgentChange, imageModelMenu, onForkChat, onConnectProvider, onConnectLocalRuntime, plusMenuMode = "full", providerStatusChecksEnabled = true, loadHistoryRepository, historyReloadKey, externalStreaming = false, agentChatSurface = "app", desktopIdentityUnauthenticated = false, desktopIdentityAuthenticated = false, suppressInlineOpenApp = false, }, ref) {
1386
1390
  const t = useT();
1387
1391
  const thread = useThread();
1388
1392
  const threadRuntime = useThreadRuntime();
@@ -1843,6 +1847,35 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
1843
1847
  setIsRestoring(true);
1844
1848
  setRestoreAttempt((attempt) => attempt + 1);
1845
1849
  }, [isNewThread, threadId]);
1850
+ // The desktop identity gate and chat restore run in sibling surfaces. If the
1851
+ // gate wins the race after a masked 404 has already rendered, clear the
1852
+ // transient not-found card and leave the user at a fresh composer.
1853
+ useEffect(() => {
1854
+ if (!desktopIdentityUnauthenticated)
1855
+ return;
1856
+ setThreadRestoreError((current) => current === "not-found" ? null : current);
1857
+ }, [desktopIdentityUnauthenticated]);
1858
+ const desktopIdentityAuthenticatedRef = useRef(desktopIdentityAuthenticated);
1859
+ useEffect(() => {
1860
+ const becameAuthenticated = desktopIdentityAuthenticated && !desktopIdentityAuthenticatedRef.current;
1861
+ desktopIdentityAuthenticatedRef.current = desktopIdentityAuthenticated;
1862
+ if (!becameAuthenticated ||
1863
+ agentChatSurface !== "desktop" ||
1864
+ !threadId ||
1865
+ isNewThread) {
1866
+ return;
1867
+ }
1868
+ // A saved-thread request can race the identity handoff and be masked as a
1869
+ // 404/401/403. Retry once the host confirms the authenticated session so
1870
+ // the thread is restored without requiring a remount or manual retry.
1871
+ retryThreadRestore();
1872
+ }, [
1873
+ agentChatSurface,
1874
+ desktopIdentityAuthenticated,
1875
+ isNewThread,
1876
+ retryThreadRestore,
1877
+ threadId,
1878
+ ]);
1846
1879
  const onSaveThreadRef = useRef(onSaveThread);
1847
1880
  onSaveThreadRef.current = onSaveThread;
1848
1881
  const onGenerateTitleRef = useRef(onGenerateTitle);
@@ -2668,7 +2701,7 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
2668
2701
  const res = await fetch(`${apiUrl}/threads/${encodeURIComponent(threadId)}`);
2669
2702
  if (!res.ok) {
2670
2703
  if (!cancelled) {
2671
- setThreadRestoreError(shouldSuppressUnauthenticatedDesktopThreadRestore(agentChatSurface, res.status)
2704
+ setThreadRestoreError(shouldSuppressUnauthenticatedDesktopThreadRestore(agentChatSurface, res.status, desktopIdentityUnauthenticated)
2672
2705
  ? null
2673
2706
  : res.status === 404
2674
2707
  ? "not-found"
@@ -2776,6 +2809,7 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
2776
2809
  loadHistoryRepository,
2777
2810
  isNewThread,
2778
2811
  isThreadStateLoading,
2812
+ desktopIdentityUnauthenticated,
2779
2813
  restoreAttempt,
2780
2814
  ]);
2781
2815
  useEffect(() => {
@@ -1,20 +1,14 @@
1
1
  import type { AgentNativeDeploymentEnvironment, AgentNativeConfig } from "../config.js";
2
- export declare const BETA_OPT_OUT_QUERY_PARAM = "agentNativeBetaOptOut";
3
2
  export declare const BETA_OPT_OUT_STORAGE_KEY = "agent-native:beta-opt-out-until";
4
- export declare const BETA_OPT_OUT_DURATION_MS: number;
5
- export interface EnvironmentBadgeTargets {
6
- betaHost: string;
7
- productionHost: string;
8
- }
3
+ export { BETA_OPT_OUT_DURATION_MS, BETA_OPT_OUT_QUERY_PARAM, buildEnvironmentOptOutUrl, buildEnvironmentUrl, resolveEnvironmentTargets, type EnvironmentBadgeTargets, } from "../shared/environment-lanes.js";
9
4
  export declare function isBuilderIoEmployee(email: string | null | undefined): boolean;
10
- export declare function resolveEnvironmentTargets(hostname: string | undefined): EnvironmentBadgeTargets | null;
11
5
  export declare function resolveEnvironmentChannel(config: AgentNativeConfig, hostname: string | undefined): Extract<AgentNativeDeploymentEnvironment, "beta" | "production"> | null;
12
- export declare function buildEnvironmentUrl(sourceHref: string, targetHost: string): string | null;
13
6
  export declare function isBetaOptOutActive(value: string | number | null | undefined, now?: number): boolean;
14
- export declare function buildEnvironmentOptOutUrl(sourceHref: string, targetHost: string, now?: number): string | null;
15
7
  /**
16
- * Small internal-only lane switcher for first-party hosted Agent-Native apps.
17
- * It is mounted inside the authenticated AppProviders shell so public pages,
18
- * embeds, and signed-out visitors never receive environment navigation.
8
+ * First-party hosted lane switcher. Beta is intentionally visible before
9
+ * authentication so a visitor can always leave beta from the sign-in page.
10
+ * Production remains an internal auto-redirect lane for authenticated staff.
19
11
  */
20
- export declare function EnvironmentBadge(): import("react").JSX.Element | null;
12
+ export declare function EnvironmentBadge({ showProduction, }?: {
13
+ showProduction?: boolean;
14
+ }): import("react").JSX.Element | null;
@@ -2,47 +2,15 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Button } from "@agent-native/toolkit/ui/button";
3
3
  import { Popover, PopoverContent, PopoverTrigger, } from "@agent-native/toolkit/ui/popover";
4
4
  import { useEffect, useMemo, useRef } from "react";
5
+ import { BETA_OPT_OUT_QUERY_PARAM, buildEnvironmentOptOutUrl, buildEnvironmentUrl, resolveEnvironmentTargets, } from "../shared/environment-lanes.js";
5
6
  import { trackEvent } from "./analytics.js";
6
7
  import { injectedAgentNativeConfig } from "./app-config.js";
7
8
  import { useSession } from "./use-session.js";
8
- export const BETA_OPT_OUT_QUERY_PARAM = "agentNativeBetaOptOut";
9
9
  export const BETA_OPT_OUT_STORAGE_KEY = "agent-native:beta-opt-out-until";
10
- export const BETA_OPT_OUT_DURATION_MS = 24 * 60 * 60 * 1000;
11
- const ENVIRONMENT_BETA_HOSTS = {
12
- "agent-workspace.builder.io": "beta.agent-workspace.builder.io",
13
- "analytics.agent-native.com": "beta.analytics.agent-native.com",
14
- "assets.agent-native.com": "beta.assets.agent-native.com",
15
- "brain.agent-native.com": "beta.brain.agent-native.com",
16
- "calendar.agent-native.com": "beta.calendar.agent-native.com",
17
- "chat.agent-native.com": "beta.chat.agent-native.com",
18
- "clips.agent-native.com": "beta.clips.agent-native.com",
19
- "content.agent-native.com": "beta.content.agent-native.com",
20
- "crm.agent-native.com": "beta.crm.agent-native.com",
21
- "design.agent-native.com": "beta.design.agent-native.com",
22
- "dispatch.agent-native.com": "beta.dispatch.agent-native.com",
23
- "factory.agent-native.com": "beta.factory.agent-native.com",
24
- "forms.agent-native.com": "beta.forms.agent-native.com",
25
- "macros.agent-native.com": "beta.macros.agent-native.com",
26
- "mail.agent-native.com": "beta.mail.agent-native.com",
27
- "plan.agent-native.com": "beta.plan.agent-native.com",
28
- "slides.agent-native.com": "beta.slides.agent-native.com",
29
- };
10
+ export { BETA_OPT_OUT_DURATION_MS, BETA_OPT_OUT_QUERY_PARAM, buildEnvironmentOptOutUrl, buildEnvironmentUrl, resolveEnvironmentTargets, } from "../shared/environment-lanes.js";
30
11
  export function isBuilderIoEmployee(email) {
31
12
  return email?.trim().toLowerCase().endsWith("@builder.io") ?? false;
32
13
  }
33
- export function resolveEnvironmentTargets(hostname) {
34
- const normalized = hostname?.trim().toLowerCase().replace(/\.$/, "");
35
- if (!normalized)
36
- return null;
37
- const productionHost = normalized.replace(/^beta\./, "");
38
- const betaHost = ENVIRONMENT_BETA_HOSTS[productionHost];
39
- if (!betaHost)
40
- return null;
41
- return {
42
- betaHost,
43
- productionHost,
44
- };
45
- }
46
14
  export function resolveEnvironmentChannel(config, hostname) {
47
15
  const configured = config.deployment?.environment;
48
16
  if (configured === "beta" || configured === "production") {
@@ -55,37 +23,10 @@ export function resolveEnvironmentChannel(config, hostname) {
55
23
  ? "beta"
56
24
  : "production";
57
25
  }
58
- export function buildEnvironmentUrl(sourceHref, targetHost) {
59
- try {
60
- const target = new URL(sourceHref);
61
- target.protocol = "https:";
62
- target.hostname = targetHost;
63
- target.port = "";
64
- return target.toString();
65
- }
66
- catch {
67
- // coercion-ok: Invalid navigation input is an explicit absent target.
68
- return null;
69
- }
70
- }
71
26
  export function isBetaOptOutActive(value, now = Date.now()) {
72
27
  const expiry = typeof value === "number" ? value : Number(value);
73
28
  return Number.isFinite(expiry) && expiry > now;
74
29
  }
75
- export function buildEnvironmentOptOutUrl(sourceHref, targetHost, now = Date.now()) {
76
- const targetHref = buildEnvironmentUrl(sourceHref, targetHost);
77
- if (!targetHref)
78
- return null;
79
- try {
80
- const target = new URL(targetHref);
81
- target.searchParams.set(BETA_OPT_OUT_QUERY_PARAM, String(now + BETA_OPT_OUT_DURATION_MS));
82
- return target.toString();
83
- }
84
- catch {
85
- // coercion-ok: buildEnvironmentUrl already validated the URL.
86
- return null;
87
- }
88
- }
89
30
  function readBetaOptOutUntil(now = Date.now()) {
90
31
  if (typeof window === "undefined")
91
32
  return null;
@@ -133,29 +74,29 @@ function consumeBetaOptOutQueryParam(sourceHref, now = Date.now()) {
133
74
  function EnvironmentLink({ label, href }) {
134
75
  return (_jsx(Button, { asChild: true, className: "w-full justify-center", size: "sm", variant: "outline", children: _jsx("a", { href: href, children: label }) }));
135
76
  }
136
- /**
137
- * Small internal-only lane switcher for first-party hosted Agent-Native apps.
138
- * It is mounted inside the authenticated AppProviders shell so public pages,
139
- * embeds, and signed-out visitors never receive environment navigation.
140
- */
141
- export function EnvironmentBadge() {
77
+ function EnvironmentBadgeContent({ environment, targets, }) {
78
+ if (typeof window === "undefined")
79
+ return null;
80
+ const currentHref = window.location.href;
81
+ const betaHref = buildEnvironmentUrl(currentHref, targets.betaHost);
82
+ const productionHref = buildEnvironmentOptOutUrl(currentHref, targets.productionHost);
83
+ if (environment === "beta" ? !productionHref : !betaHref)
84
+ return null;
85
+ const label = environment === "beta" ? "beta" : "prod";
86
+ const title = environment === "beta"
87
+ ? "You're on Agent Native Beta"
88
+ : "You're on Agent Native Production";
89
+ return (_jsxs(Popover, { children: [_jsx(PopoverTrigger, { asChild: true, children: _jsx(Button, { "aria-label": `Open ${title.toLowerCase()} switcher`, className: "fixed bottom-3 right-3 z-[100] h-6 min-w-0 rounded-xl border-border/80 bg-background/95 px-2 text-[11px] font-semibold uppercase tracking-[0.5px] shadow-sm backdrop-blur-sm", size: "sm", variant: environment === "beta" ? "default" : "outline", children: label }) }), _jsxs(PopoverContent, { align: "center", className: "w-[280px] p-5", side: "top", sideOffset: 8, children: [_jsx("div", { className: "mb-1 text-sm font-semibold leading-5", children: title }), _jsx("div", { className: "mb-4 text-sm text-muted-foreground", children: "Choose where you want to continue." }), _jsx("div", { className: "grid gap-2", children: environment === "beta" ? (_jsx(EnvironmentLink, { href: productionHref, label: "Switch to production" })) : (_jsx(EnvironmentLink, { href: betaHref, label: "Go to beta" })) })] })] }));
90
+ }
91
+ function ProductionEnvironmentBadge({ targets, }) {
142
92
  const { session, status } = useSession();
143
- const config = useMemo(injectedAgentNativeConfig, []);
144
- const didAutoRedirect = useRef(false);
145
- const hostname = typeof window === "undefined" ? undefined : window.location.hostname;
146
- const environment = resolveEnvironmentChannel(config, hostname);
147
- const targets = resolveEnvironmentTargets(hostname);
148
93
  const isEligible = typeof window !== "undefined" &&
149
94
  window.parent === window &&
150
95
  status === "authenticated" &&
151
- isBuilderIoEmployee(session?.email) &&
152
- !!environment &&
153
- !!targets;
96
+ isBuilderIoEmployee(session?.email);
97
+ const didAutoRedirect = useRef(false);
154
98
  useEffect(() => {
155
- if (!isEligible ||
156
- environment !== "production" ||
157
- !targets ||
158
- didAutoRedirect.current) {
99
+ if (!isEligible || didAutoRedirect.current) {
159
100
  return;
160
101
  }
161
102
  if (readBetaOptOutUntil() !== null)
@@ -172,21 +113,31 @@ export function EnvironmentBadge() {
172
113
  trigger: "automatic_redirect",
173
114
  });
174
115
  window.location.replace(betaHref);
175
- }, [environment, isEligible, session?.email, status, targets?.betaHost]);
176
- if (!isEligible ||
116
+ }, [isEligible, session?.email, status, targets.betaHost]);
117
+ if (!isEligible)
118
+ return null;
119
+ return _jsx(EnvironmentBadgeContent, { environment: "production", targets: targets });
120
+ }
121
+ /**
122
+ * First-party hosted lane switcher. Beta is intentionally visible before
123
+ * authentication so a visitor can always leave beta from the sign-in page.
124
+ * Production remains an internal auto-redirect lane for authenticated staff.
125
+ */
126
+ export function EnvironmentBadge({ showProduction = true, } = {}) {
127
+ const config = useMemo(injectedAgentNativeConfig, []);
128
+ const hostname = typeof window === "undefined" ? undefined : window.location.hostname;
129
+ const environment = resolveEnvironmentChannel(config, hostname);
130
+ const targets = resolveEnvironmentTargets(hostname);
131
+ if (typeof window === "undefined" ||
132
+ window.parent !== window ||
177
133
  !environment ||
178
- !targets ||
179
- typeof window === "undefined") {
134
+ !targets) {
180
135
  return null;
181
136
  }
182
- const currentHref = window.location.href;
183
- const betaHref = buildEnvironmentUrl(currentHref, targets.betaHost);
184
- const productionHref = buildEnvironmentOptOutUrl(currentHref, targets.productionHost);
185
- if (!betaHref || !productionHref)
137
+ if (environment === "beta") {
138
+ return _jsx(EnvironmentBadgeContent, { environment: "beta", targets: targets });
139
+ }
140
+ if (!showProduction)
186
141
  return null;
187
- const label = environment === "beta" ? "beta" : "prod";
188
- const title = environment === "beta"
189
- ? "You're on Agent Native Beta"
190
- : "You're on Agent Native Production";
191
- return (_jsxs(Popover, { children: [_jsx(PopoverTrigger, { asChild: true, children: _jsx(Button, { "aria-label": `Open ${title.toLowerCase()} switcher`, className: "fixed bottom-3 right-3 z-[100] h-6 min-w-0 rounded-xl border-border/80 bg-background/95 px-2 text-[11px] font-semibold uppercase tracking-[0.5px] shadow-sm backdrop-blur-sm", size: "sm", variant: environment === "beta" ? "default" : "outline", children: label }) }), _jsxs(PopoverContent, { align: "center", className: "w-[280px] p-5", side: "top", sideOffset: 8, children: [_jsx("div", { className: "mb-1 text-sm font-semibold leading-5", children: title }), _jsx("div", { className: "mb-4 text-sm text-muted-foreground", children: "Choose where you want to continue." }), _jsx("div", { className: "grid gap-2", children: environment === "beta" ? (_jsx(EnvironmentLink, { href: productionHref, label: "Switch to production" })) : (_jsx(EnvironmentLink, { href: betaHref, label: "Go to beta" })) })] })] }));
142
+ return _jsx(ProductionEnvironmentBadge, { targets: targets });
192
143
  }
@@ -3,6 +3,7 @@ export { AgentAskPopover, type AgentAskPopoverProps, } from "../AgentAskPopover.
3
3
  export { addContextToAgentChat, appendAgentChatContextToMessage, clearAgentChatContext, formatAgentChatContextItemsForPrompt, insertAgentComposerReference, listAgentChatContext, normalizeAgentComposerReference, refreshAgentChatContext, removeAgentChatContextItem, requestAgentChatThreadOpen, requestAgentTaskOpen, sendToAgentChat, sendToAgentChatAndConfirm, reportAgentChatSubmitResult, AGENT_CHAT_SUBMIT_RESULT_EVENT, parseSubmitChatMessage, setAgentChatContextItem, setContextToAgentChat, generateTabId, type ParsedSubmitChat, type AgentChatOpenTaskRequest, type AgentChatOpenThreadRequest, type AgentChatContextItem, type AgentChatContextMessage, type AgentChatContextMutationOptions, type AgentChatContextRemoveOptions, type AgentChatContextSetOptions, type AgentChatContextState, type AgentChatMessage, type AgentChatSubmitResult, type SendToAgentChatAndConfirmResult, type AgentComposerReference, type AgentComposerReferenceInsertOptions, type AgentComposerReferenceInsertPayload, } from "../agent-chat.js";
4
4
  export { saveAgentEngineApiKey, saveAgentEngineProviderSettings, type AgentEngineProvider, type SaveAgentEngineApiKeyOptions, type SaveAgentEngineProviderSettingsOptions, } from "../agent-engine-key.js";
5
5
  export { useAgentChatGenerating } from "../use-agent-chat.js";
6
+ export { useActiveAgentChatRunId } from "../use-active-agent-chat-run.js";
6
7
  export { useAgentChatContext, type UseAgentChatContextResult, } from "../use-agent-chat-context.js";
7
8
  export { useCodeMode, useDevMode } from "../use-dev-mode.js";
8
9
  export { codeAgentTranscriptEventsToContent, codeAgentTranscriptHasPendingApproval, createCodeAgentChatAdapter, type CodeAgentChatController, type CodeAgentChatControlResult, type CodeAgentChatFollowUpMode, type CodeAgentChatTranscriptEvent, type CreateCodeAgentChatAdapterOptions, } from "../code-agent-chat-adapter.js";
@@ -3,6 +3,7 @@ export { AgentAskPopover, } from "../AgentAskPopover.js";
3
3
  export { addContextToAgentChat, appendAgentChatContextToMessage, clearAgentChatContext, formatAgentChatContextItemsForPrompt, insertAgentComposerReference, listAgentChatContext, normalizeAgentComposerReference, refreshAgentChatContext, removeAgentChatContextItem, requestAgentChatThreadOpen, requestAgentTaskOpen, sendToAgentChat, sendToAgentChatAndConfirm, reportAgentChatSubmitResult, AGENT_CHAT_SUBMIT_RESULT_EVENT, parseSubmitChatMessage, setAgentChatContextItem, setContextToAgentChat, generateTabId, } from "../agent-chat.js";
4
4
  export { saveAgentEngineApiKey, saveAgentEngineProviderSettings, } from "../agent-engine-key.js";
5
5
  export { useAgentChatGenerating } from "../use-agent-chat.js";
6
+ export { useActiveAgentChatRunId } from "../use-active-agent-chat-run.js";
6
7
  export { useAgentChatContext, } from "../use-agent-chat-context.js";
7
8
  export { useCodeMode, useDevMode } from "../use-dev-mode.js";
8
9
  export { codeAgentTranscriptEventsToContent, codeAgentTranscriptHasPendingApproval, createCodeAgentChatAdapter, } from "../code-agent-chat-adapter.js";