@agent-native/core 0.141.5 → 0.141.7

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 (235) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/templates/analytics/.agents/skills/dashboard-management/SKILL.md +3 -14
  3. package/corpus/templates/analytics/.agents/skills/data-querying/SKILL.md +20 -8
  4. package/corpus/templates/analytics/.agents/skills/prometheus/SKILL.md +5 -5
  5. package/corpus/templates/analytics/AGENTS.md +2 -2
  6. package/corpus/templates/analytics/actions/compose-dashboard.ts +1 -1
  7. package/corpus/templates/analytics/actions/get-first-party-analytics-health.ts +15 -1
  8. package/corpus/templates/analytics/actions/migrate-first-party-analytics-to-bigquery.ts +135 -0
  9. package/corpus/templates/analytics/actions/navigate.ts +1 -1
  10. package/corpus/templates/analytics/actions/query-agent-native-analytics.ts +2 -2
  11. package/corpus/templates/analytics/actions/update-dashboard.ts +0 -1
  12. package/corpus/templates/analytics/actions/view-screen.ts +0 -20
  13. package/corpus/templates/analytics/app/components/layout/Header.tsx +0 -1
  14. package/corpus/templates/analytics/app/hooks/use-navigation-state.ts +5 -5
  15. package/corpus/templates/analytics/app/i18n-data.ts +330 -90
  16. package/corpus/templates/analytics/app/pages/Agents.tsx +0 -3
  17. package/corpus/templates/analytics/app/pages/DataSources.tsx +66 -30
  18. package/corpus/templates/analytics/app/pages/Settings.tsx +22 -43
  19. package/corpus/templates/analytics/app/pages/settings/settings-search.ts +23 -20
  20. package/corpus/templates/analytics/app/routes/extensions._index.tsx +1 -1
  21. package/corpus/templates/analytics/app/routes/settings.$.tsx +1 -0
  22. package/corpus/templates/analytics/app/routes/team.tsx +1 -1
  23. package/corpus/templates/analytics/changelog/2026-08-05-historical-analytics-rollups-now-repair-automatically-after-.md +6 -0
  24. package/corpus/templates/analytics/changelog/2026-08-05-settings-no-longer-includes-an-unnecessary-about-section.md +6 -0
  25. package/corpus/templates/analytics/docs/schemas/first-party-analytics.md +1 -1
  26. package/corpus/templates/analytics/netlify.toml +4 -0
  27. package/corpus/templates/analytics/scripts/emit-netlify-dashboard-report-cron.ts +109 -0
  28. package/corpus/templates/analytics/scripts/first-party-analytics-bigquery.sql +104 -0
  29. package/corpus/templates/analytics/server/jobs/analytics-rollup-backfill.ts +342 -0
  30. package/corpus/templates/analytics/server/lib/agent-chat-plan-mode.ts +0 -2
  31. package/corpus/templates/analytics/server/lib/analytics-rollup-lock.ts +8 -0
  32. package/corpus/templates/analytics/server/lib/dashboard-catalog.ts +11 -29
  33. package/corpus/templates/analytics/server/lib/dashboards-store.ts +55 -0
  34. package/corpus/templates/analytics/server/lib/first-party-analytics-backend.ts +1058 -0
  35. package/corpus/templates/analytics/server/lib/first-party-analytics-health.ts +151 -46
  36. package/corpus/templates/analytics/server/lib/first-party-analytics-rollups.ts +15 -9
  37. package/corpus/templates/analytics/server/lib/first-party-analytics.ts +59 -17
  38. package/corpus/templates/analytics/server/lib/real-data-actions.ts +1 -3
  39. package/corpus/templates/analytics/server/plugins/agent-chat.ts +2 -4
  40. package/corpus/templates/analytics/server/plugins/analytics-rollup-backfill-jobs.ts +61 -0
  41. package/corpus/templates/analytics/server/plugins/db.ts +58 -187
  42. package/corpus/templates/analytics/server/routes/api/analytics-rollups/backfill.post.ts +53 -0
  43. package/corpus/templates/assets/.agents/skills/asset-generation/SKILL.md +8 -6
  44. package/corpus/templates/assets/.agents/skills/library-management/SKILL.md +16 -1
  45. package/corpus/templates/assets/AGENTS.md +1 -0
  46. package/corpus/templates/assets/actions/_helpers.ts +12 -0
  47. package/corpus/templates/assets/actions/generate-image.ts +9 -3
  48. package/corpus/templates/assets/actions/import-style-from-url.ts +115 -0
  49. package/corpus/templates/assets/app/hooks/use-navigation-state.ts +3 -1
  50. package/corpus/templates/assets/app/routes/extensions._index.tsx +1 -1
  51. package/corpus/templates/assets/app/routes/settings.$.tsx +1 -0
  52. package/corpus/templates/assets/app/routes/settings.tsx +5 -0
  53. package/corpus/templates/assets/app/routes/team.tsx +1 -1
  54. package/corpus/templates/assets/changelog/2026-08-05-brand-kits-can-import-a-website-s-hydrated-visual-language-a.md +6 -0
  55. package/corpus/templates/assets/changelog/2026-08-05-generated-images-now-hand-off-embeddable-previews-to-other-w.md +6 -0
  56. package/corpus/templates/assets/server/lib/generation.ts +58 -0
  57. package/corpus/templates/assets/shared/api.ts +12 -0
  58. package/corpus/templates/brain/app/routes/extensions._index.tsx +1 -1
  59. package/corpus/templates/brain/app/routes/team.tsx +1 -1
  60. package/corpus/templates/brain/app/routes.ts +1 -1
  61. package/corpus/templates/calendar/app/components/layout/AppLayout.tsx +3 -1
  62. package/corpus/templates/calendar/app/routes/_app.extensions._index.tsx +1 -1
  63. package/corpus/templates/calendar/app/routes/_app.settings.$.tsx +1 -0
  64. package/corpus/templates/calendar/app/routes/_app.team.tsx +1 -1
  65. package/corpus/templates/chat/app/components/layout/Layout.tsx +1 -1
  66. package/corpus/templates/chat/app/hooks/use-navigation-state.ts +1 -1
  67. package/corpus/templates/chat/app/root.tsx +1 -1
  68. package/corpus/templates/chat/app/routes/agent.tsx +7 -7
  69. package/corpus/templates/chat/app/routes/extensions._index.tsx +1 -1
  70. package/corpus/templates/chat/app/routes/settings.$.tsx +1 -0
  71. package/corpus/templates/chat/app/routes/team.tsx +1 -1
  72. package/corpus/templates/clips/app/components/library/library-layout.tsx +1 -1
  73. package/corpus/templates/clips/app/components/player/transcript-panel.tsx +1 -1
  74. package/corpus/templates/clips/app/components/recorder/storage-setup-card.tsx +1 -1
  75. package/corpus/templates/clips/app/routes/_app.extensions._index.tsx +1 -1
  76. package/corpus/templates/clips/app/routes/_app.settings.$.tsx +1 -0
  77. package/corpus/templates/clips/changelog/2026-08-05-clips-overlays-now-use-clean-surfaces-without-clipped-shadow.md +6 -0
  78. package/corpus/templates/clips/desktop/src/overlays/meeting-notification.tsx +2 -2
  79. package/corpus/templates/clips/desktop/src/styles.css +3 -54
  80. package/corpus/templates/clips/desktop/src-tauri/src/notifications.rs +3 -3
  81. package/corpus/templates/content/app/routes/_app.extensions._index.tsx +1 -1
  82. package/corpus/templates/content/app/routes/_app.settings.$.tsx +1 -0
  83. package/corpus/templates/content/app/routes/_app.team.tsx +1 -1
  84. package/corpus/templates/content/e2e/global-setup.ts +1 -1
  85. package/corpus/templates/design/.agents/skills/design-systems/SKILL.md +6 -1
  86. package/corpus/templates/design/actions/analyze-brand-assets.ts +7 -7
  87. package/corpus/templates/design/actions/get-design-system.ts +3 -1
  88. package/corpus/templates/design/actions/import-from-url.ts +6 -5
  89. package/corpus/templates/design/app/pages/DesignSystemSetup.tsx +2 -2
  90. package/corpus/templates/design/app/routes/extensions._index.tsx +1 -1
  91. package/corpus/templates/design/app/routes/settings.$.tsx +1 -0
  92. package/corpus/templates/design/app/routes/team.tsx +1 -1
  93. package/corpus/templates/design/changelog/2026-08-05-missing-design-systems-now-return-a-clear-not-found-response.md +6 -0
  94. package/corpus/templates/design/changelog/2026-08-05-website-url-imports-now-capture-hydrated-browser-computed-de.md +6 -0
  95. package/corpus/templates/design/e2e/global-setup.ts +1 -1
  96. package/corpus/templates/dispatch/app/hooks/use-navigation-state.ts +1 -1
  97. package/corpus/templates/dispatch/app/routes/settings.$.tsx +1 -0
  98. package/corpus/templates/dispatch/app/routes/team.tsx +1 -1
  99. package/corpus/templates/factory/app/hooks/use-navigation-state.ts +1 -1
  100. package/corpus/templates/factory/app/routes/extensions._index.tsx +1 -1
  101. package/corpus/templates/factory/app/routes/settings.$.tsx +1 -0
  102. package/corpus/templates/factory/app/routes/team.tsx +1 -1
  103. package/corpus/templates/forms/app/routes/_app.extensions._index.tsx +1 -1
  104. package/corpus/templates/forms/app/routes/_app.settings.$.tsx +1 -0
  105. package/corpus/templates/forms/app/routes/_app.team.tsx +1 -1
  106. package/corpus/templates/forms/shared/navigation.ts +1 -1
  107. package/corpus/templates/macros/app/routes/extensions._index.tsx +1 -1
  108. package/corpus/templates/macros/app/routes/settings.$.tsx +1 -0
  109. package/corpus/templates/macros/app/routes/team.tsx +1 -1
  110. package/corpus/templates/mail/app/routes/extensions._index.tsx +1 -1
  111. package/corpus/templates/mail/app/routes/settings.$.tsx +1 -0
  112. package/corpus/templates/plan/app/hooks/use-navigation-state.ts +1 -1
  113. package/corpus/templates/plan/app/routes/extensions._index.tsx +1 -1
  114. package/corpus/templates/plan/app/routes/settings.$.tsx +1 -0
  115. package/corpus/templates/plan/app/routes/team.tsx +1 -1
  116. package/corpus/templates/slides/.agents/skills/design-systems/SKILL.md +3 -1
  117. package/corpus/templates/slides/actions/analyze-brand-assets.ts +7 -7
  118. package/corpus/templates/slides/actions/import-from-url.ts +6 -6
  119. package/corpus/templates/slides/app/components/deck/DeckCard.tsx +2 -2
  120. package/corpus/templates/slides/app/components/design-system/DesignSystemSetup.tsx +1 -1
  121. package/corpus/templates/slides/app/components/editor/PromptDialog.tsx +3 -0
  122. package/corpus/templates/slides/app/components/editor/SlideEditor.tsx +1 -1
  123. package/corpus/templates/slides/app/components/onboarding/FirstDeckOnboardingFlow.tsx +9 -3
  124. package/corpus/templates/slides/app/context/DeckContext.tsx +71 -20
  125. package/corpus/templates/slides/app/global.css +6 -0
  126. package/corpus/templates/slides/app/i18n/en-US.ts +5 -5
  127. package/corpus/templates/slides/app/lib/create-deck-generation.ts +9 -5
  128. package/corpus/templates/slides/app/pages/DeckEditor.tsx +17 -0
  129. package/corpus/templates/slides/app/pages/Index.tsx +16 -5
  130. package/corpus/templates/slides/app/routes/extensions._index.tsx +1 -1
  131. package/corpus/templates/slides/app/routes/settings.$.tsx +1 -0
  132. package/corpus/templates/slides/app/routes/team.tsx +1 -1
  133. package/corpus/templates/slides/changelog/2026-08-05-failed-deck-creation-and-reference-uploads-now-recover-clean.md +6 -0
  134. package/corpus/templates/slides/changelog/2026-08-05-new-presentation-prompts-now-clearly-describe-presentation-g.md +6 -0
  135. package/corpus/templates/slides/changelog/2026-08-05-slides-recover-completed-generation-results-after-a-sync-hic.md +6 -0
  136. package/corpus/templates/slides/changelog/2026-08-05-website-url-imports-now-capture-hydrated-browser-computed-st.md +6 -0
  137. package/corpus/templates/tasks/app/components/layout/Header.tsx +3 -1
  138. package/corpus/templates/tasks/app/routes/extensions._index.tsx +1 -1
  139. package/corpus/templates/tasks/app/routes/settings.$.tsx +1 -0
  140. package/dist/agent/engine/ai-sdk-engine.js +49 -3
  141. package/dist/agent/production-agent.d.ts +1 -0
  142. package/dist/agent/production-agent.js +8 -0
  143. package/dist/agent/types.d.ts +7 -0
  144. package/dist/client/AssistantChat.js +1 -1
  145. package/dist/client/agent-chat-adapter.d.ts +1 -1
  146. package/dist/client/agent-chat-adapter.js +30 -3
  147. package/dist/client/agent-page/AgentWorkspaceContent.d.ts +1 -1
  148. package/dist/client/agent-page/AgentWorkspaceContent.js +13 -13
  149. package/dist/client/chat/run-recovery.d.ts +2 -1
  150. package/dist/client/chat/run-recovery.js +14 -3
  151. package/dist/client/embed-auth.js +6 -2
  152. package/dist/client/error-format.d.ts +1 -0
  153. package/dist/client/error-format.js +16 -2
  154. package/dist/client/integrations/IntegrationsPanel.js +40 -6
  155. package/dist/client/org/OrgSwitcher.js +2 -2
  156. package/dist/client/org/TeamPage.js +92 -72
  157. package/dist/client/require-session.d.ts +1 -1
  158. package/dist/client/require-session.js +3 -3
  159. package/dist/client/resources/use-mcp-servers.d.ts +5 -0
  160. package/dist/client/resources/use-mcp-servers.js +36 -0
  161. package/dist/client/settings/AccountSettingsCard.js +40 -35
  162. package/dist/client/settings/AutomationsSection.js +1 -1
  163. package/dist/client/settings/DemoModeSection.d.ts +3 -1
  164. package/dist/client/settings/DemoModeSection.js +4 -1
  165. package/dist/client/settings/ExtensionsSettingsContent.js +1 -1
  166. package/dist/client/settings/SchedulingTimezoneField.d.ts +3 -1
  167. package/dist/client/settings/SchedulingTimezoneField.js +9 -5
  168. package/dist/client/settings/SettingsPanel.d.ts +4 -1
  169. package/dist/client/settings/SettingsPanel.js +21 -21
  170. package/dist/client/settings/SettingsTabsPage.d.ts +2 -2
  171. package/dist/client/settings/SettingsTabsPage.js +98 -45
  172. package/dist/client/settings/VoiceTranscriptionSection.js +6 -1
  173. package/dist/client/settings/useSettingsPanelController.js +47 -8
  174. package/dist/file-upload/actions/upload-image.d.ts +1 -1
  175. package/dist/ingestion/website.d.ts +30 -0
  176. package/dist/localization/default-messages.d.ts +5 -0
  177. package/dist/localization/default-messages.js +5 -0
  178. package/dist/mcp-client/oauth-routes.js +1 -1
  179. package/dist/mcp-client/routes.d.ts +1 -0
  180. package/dist/mcp-client/routes.js +49 -0
  181. package/dist/navigation/index.js +16 -5
  182. package/dist/observability/routes.d.ts +3 -3
  183. package/dist/provider-api/actions/custom-provider-registration.d.ts +13 -13
  184. package/dist/provider-api/actions/provider-api.d.ts +11 -11
  185. package/dist/scripts/call-agent.js +11 -0
  186. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  187. package/dist/server/auth.js +9 -7
  188. package/dist/server/identity-sso.js +2 -1
  189. package/dist/server/onboarding-html.js +57 -34
  190. package/dist/server/realtime-token.d.ts +1 -1
  191. package/dist/server/transcribe-voice.d.ts +1 -1
  192. package/dist/server/workspace-provider-oauth.js +1 -1
  193. package/dist/setup-connections/onboarding.js +1 -1
  194. package/dist/shared/index.d.ts +1 -1
  195. package/dist/shared/index.js +1 -1
  196. package/dist/shared/sign-in-journey.d.ts +5 -2
  197. package/dist/shared/sign-in-journey.js +10 -4
  198. package/dist/templates/chat/app/components/layout/Layout.tsx +1 -1
  199. package/dist/templates/chat/app/hooks/use-navigation-state.ts +1 -1
  200. package/dist/templates/chat/app/root.tsx +1 -1
  201. package/dist/templates/chat/app/routes/agent.tsx +7 -7
  202. package/dist/templates/chat/app/routes/extensions._index.tsx +1 -1
  203. package/dist/templates/chat/app/routes/settings.$.tsx +1 -0
  204. package/dist/templates/chat/app/routes/team.tsx +1 -1
  205. package/dist/templates/workspace-core/.agents/skills/address-feedback/SKILL.md +37 -6
  206. package/dist/templates/workspace-core/.agents/skills/authentication/SKILL.md +4 -2
  207. package/docs/content/authentication.mdx +4 -5
  208. package/docs/content/template-analytics-developers.mdx +1 -1
  209. package/docs/content/template-calendar-developers.mdx +1 -1
  210. package/docs/content/template-chat-developers.mdx +2 -2
  211. package/docs/content/template-content-developers.mdx +1 -1
  212. package/docs/content/template-mail-developers.mdx +1 -1
  213. package/docs/content/template-plan-developers.mdx +1 -1
  214. package/docs/content/toolkit-command-navigation.mdx +6 -6
  215. package/docs/content/toolkit-org-team.mdx +1 -1
  216. package/docs/content/toolkit-settings.mdx +8 -8
  217. package/docs/content/toolkit-setup-connections.mdx +1 -1
  218. package/package.json +1 -1
  219. package/src/templates/chat/app/components/layout/Layout.tsx +1 -1
  220. package/src/templates/chat/app/hooks/use-navigation-state.ts +1 -1
  221. package/src/templates/chat/app/root.tsx +1 -1
  222. package/src/templates/chat/app/routes/agent.tsx +7 -7
  223. package/src/templates/chat/app/routes/extensions._index.tsx +1 -1
  224. package/src/templates/chat/app/routes/settings.$.tsx +1 -0
  225. package/src/templates/chat/app/routes/team.tsx +1 -1
  226. package/src/templates/workspace-core/.agents/skills/address-feedback/SKILL.md +37 -6
  227. package/src/templates/workspace-core/.agents/skills/authentication/SKILL.md +4 -2
  228. package/corpus/templates/analytics/.agents/skills/dashboard-management/references/template-catalog-and-demo.md +0 -62
  229. package/corpus/templates/analytics/actions/install-dashboard-template.ts +0 -369
  230. package/corpus/templates/analytics/actions/list-dashboard-templates.ts +0 -47
  231. package/corpus/templates/analytics/actions/list-native-v2-dashboard-templates.ts +0 -34
  232. package/corpus/templates/analytics/app/routes/catalog.tsx +0 -240
  233. package/corpus/templates/analytics/changelog/2026-08-05-historical-analytics-rollups-stay-complete-and-atomic.md +0 -6
  234. package/corpus/templates/analytics/changelog/2026-08-05-historical-rollups-stay-complete-while-live-events-arrive.md +0 -6
  235. package/src/templates/default/actions/navigate.spec.ts +0 -53
@@ -7,5 +7,5 @@ export function meta() {
7
7
  }
8
8
 
9
9
  export default function ExtensionsRoute() {
10
- return <Navigate to="/settings#extensions" replace />;
10
+ return <Navigate to="/settings/extensions" replace />;
11
11
  }
@@ -0,0 +1 @@
1
+ export { default, meta } from "./settings.js";
@@ -7,5 +7,5 @@ export function meta() {
7
7
  }
8
8
 
9
9
  export default function TeamRoute() {
10
- return <Navigate to="/settings#organization" replace />;
10
+ return <Navigate to="/settings/organization" replace />;
11
11
  }
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-08-05
4
+ ---
5
+
6
+ Missing design systems now return a clear not-found response.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: improved
3
+ date: 2026-08-05
4
+ ---
5
+
6
+ Website URL imports now capture hydrated browser-computed design systems for more faithful reuse.
@@ -176,7 +176,7 @@ export default async function globalSetup(config: FullConfig) {
176
176
  const page = await context.newPage();
177
177
 
178
178
  try {
179
- await page.goto(`${baseURL}/_agent-native/sign-in`, {
179
+ await page.goto(`${baseURL}/sign-in`, {
180
180
  waitUntil: "domcontentloaded",
181
181
  });
182
182
 
@@ -231,7 +231,7 @@ function resolvePath(
231
231
  case "threads":
232
232
  return "/thread-debug";
233
233
  case "team":
234
- return "/settings#organization";
234
+ return "/settings/organization";
235
235
  case "extensions":
236
236
  return command?.extensionId
237
237
  ? `/extensions/${encodeURIComponent(command.extensionId)}`
@@ -0,0 +1 @@
1
+ export { default, meta } from "./settings.js";
@@ -1,5 +1,5 @@
1
1
  import { Navigate } from "react-router";
2
2
 
3
3
  export default function TeamRoute() {
4
- return <Navigate to="/settings#organization" replace />;
4
+ return <Navigate to="/settings/organization" replace />;
5
5
  }
@@ -91,7 +91,7 @@ function pathForView(view?: string): string {
91
91
  case "settings":
92
92
  return "/settings";
93
93
  case "team":
94
- return "/settings#organization";
94
+ return "/settings/organization";
95
95
  default:
96
96
  return "/";
97
97
  }
@@ -7,5 +7,5 @@ export function meta() {
7
7
  }
8
8
 
9
9
  export default function ExtensionsRoute() {
10
- return <Navigate to="/settings#extensions" replace />;
10
+ return <Navigate to="/settings/extensions" replace />;
11
11
  }
@@ -0,0 +1 @@
1
+ export { default, meta } from "./settings.js";
@@ -7,5 +7,5 @@ export function meta() {
7
7
  }
8
8
 
9
9
  export default function TeamRoute() {
10
- return <Navigate to="/settings#organization" replace />;
10
+ return <Navigate to="/settings/organization" replace />;
11
11
  }
@@ -7,5 +7,5 @@ export function meta() {
7
7
  }
8
8
 
9
9
  export default function ExtensionsRoute() {
10
- return <Navigate to="/settings#extensions" replace />;
10
+ return <Navigate to="/settings/extensions" replace />;
11
11
  }
@@ -0,0 +1 @@
1
+ export { default, meta } from "./_app.settings.js";
@@ -5,5 +5,5 @@ export function meta() {
5
5
  }
6
6
 
7
7
  export default function TeamRoute() {
8
- return <Navigate to="/settings#organization" replace />;
8
+ return <Navigate to="/settings/organization" replace />;
9
9
  }
@@ -73,7 +73,7 @@ export function formsRoutePath(target: FormsNavigationTarget): string | null {
73
73
  ? `/response-insights?formId=${encodeURIComponent(formId)}`
74
74
  : "/response-insights";
75
75
  case "team":
76
- return "/settings#organization";
76
+ return "/settings/organization";
77
77
  case "extensions":
78
78
  return "/extensions";
79
79
  case "form-preview":
@@ -7,5 +7,5 @@ export function meta() {
7
7
  }
8
8
 
9
9
  export default function ExtensionsRoute() {
10
- return <Navigate to="/settings#extensions" replace />;
10
+ return <Navigate to="/settings/extensions" replace />;
11
11
  }
@@ -0,0 +1 @@
1
+ export { default, meta } from "./settings.js";
@@ -7,5 +7,5 @@ export function meta() {
7
7
  }
8
8
 
9
9
  export default function TeamRoute() {
10
- return <Navigate to="/settings#organization" replace />;
10
+ return <Navigate to="/settings/organization" replace />;
11
11
  }
@@ -1,5 +1,5 @@
1
1
  import { Navigate } from "react-router";
2
2
 
3
3
  export default function ExtensionsRoute() {
4
- return <Navigate to="/settings#extensions" replace />;
4
+ return <Navigate to="/settings/extensions" replace />;
5
5
  }
@@ -0,0 +1 @@
1
+ export { default, meta } from "./settings.js";
@@ -196,7 +196,7 @@ function pathForView(view?: string): string {
196
196
  case "settings":
197
197
  return "/settings";
198
198
  case "team":
199
- return "/settings#organization";
199
+ return "/settings/organization";
200
200
  default:
201
201
  return "/";
202
202
  }
@@ -7,5 +7,5 @@ export function meta() {
7
7
  }
8
8
 
9
9
  export default function ExtensionsRoute() {
10
- return <Navigate to="/settings#extensions" replace />;
10
+ return <Navigate to="/settings/extensions" replace />;
11
11
  }
@@ -0,0 +1 @@
1
+ export { default, meta } from "./settings.js";
@@ -7,5 +7,5 @@ export function meta() {
7
7
  }
8
8
 
9
9
  export default function TeamRoute() {
10
- return <Navigate to="/settings#organization" replace />;
10
+ return <Navigate to="/settings/organization" replace />;
11
11
  }
@@ -19,7 +19,9 @@ Design systems are stored in the `design_systems` SQL table. Each has a `data` c
19
19
  ## Creating a Design System
20
20
 
21
21
  1. User provides brand context (company name, website, assets, notes)
22
- 2. `analyze-brand-assets` gathers raw data (extracts CSS, fonts, colors from website)
22
+ 2. `analyze-brand-assets` renders a website in a real browser and gathers the
23
+ computed visual system (colors, fonts, spacing, radii, shadows, components,
24
+ CSS variables, logos, and design.md-style guidance)
23
25
  3. Agent analyzes the data and calls `create-design-system` with extracted tokens
24
26
  4. The design system is published and becomes available for deck creation
25
27
 
@@ -1,9 +1,7 @@
1
1
  import { defineAction } from "@agent-native/core";
2
- import {
3
- normalizeBrandWebsiteUrl,
4
- fetchBrandWebsiteSignals,
5
- } from "@agent-native/core/brand-kit";
2
+ import { normalizeBrandWebsiteUrl } from "@agent-native/core/brand-kit";
6
3
  import { resolveAccess } from "@agent-native/core/sharing";
4
+ import { extractRenderedDesignSystemFromUrl } from "@agent-native/creative-context/server";
7
5
  import { z } from "zod";
8
6
 
9
7
  import "../server/db/index.js"; // ensure registerShareableResource runs
@@ -14,8 +12,9 @@ export { normalizeBrandWebsiteUrl };
14
12
  export default defineAction({
15
13
  description:
16
14
  "Gather brand data from various sources for agent analysis. " +
17
- "If a websiteUrl is provided, fetches the page HTML and extracts: " +
18
- "meta theme-color, CSS custom properties, font-face declarations. " +
15
+ "If a websiteUrl is provided, renders the page in a real browser and extracts " +
16
+ "computed colors, typography, spacing, radii, shadows, component styles, " +
17
+ "CSS custom properties, logo references, and a design.md-style summary. " +
19
18
  "If a designSystemId is provided, includes its existing data. " +
20
19
  "Returns structured data the agent can use to build or refine a design system.",
21
20
  schema: z.object({
@@ -61,7 +60,8 @@ export default defineAction({
61
60
 
62
61
  // Fetch and analyze website if URL provided
63
62
  if (websiteUrl) {
64
- result.websiteAnalysis = await fetchBrandWebsiteSignals(websiteUrl);
63
+ result.websiteAnalysis =
64
+ await extractRenderedDesignSystemFromUrl(websiteUrl);
65
65
  }
66
66
 
67
67
  return result;
@@ -1,19 +1,19 @@
1
1
  import { defineAction } from "@agent-native/core";
2
- import { extractDesignTokensFromUrl } from "@agent-native/core/server/design-token-utils";
2
+ import { extractRenderedDesignSystemFromUrl } from "@agent-native/creative-context/server";
3
3
  import { z } from "zod";
4
4
 
5
5
  export default defineAction({
6
6
  description:
7
- "Analyze a website URL to extract design tokens (colors, fonts, metadata) " +
8
- "for use in creating or updating a design project. " +
9
- "Follows bounded, SSRF-safe linked stylesheets and reports any stylesheet failures. " +
10
- "Returns extracted CSS variables, font faces, colors, and meta information.",
7
+ "Analyze a website URL in a real browser and return a bounded design.md-style " +
8
+ "visual system: computed colors, typography, spacing, radii, shadows, " +
9
+ "component styles, CSS variables, logo references, and reusable Brand Kit data. " +
10
+ "Uses a static SSRF-safe fallback only when a browser is unavailable.",
11
11
  schema: z.object({
12
12
  url: z.string().describe("Website URL to analyze"),
13
13
  }),
14
14
  readOnly: true,
15
15
  http: { method: "GET" },
16
16
  run: async ({ url }) => {
17
- return extractDesignTokensFromUrl(url);
17
+ return extractRenderedDesignSystemFromUrl(url);
18
18
  },
19
19
  });
@@ -190,7 +190,7 @@ export default function DeckCard({
190
190
  {deck.starred ? (
191
191
  <IconStarFilled className="h-3.5 w-3.5 text-[#F5C451]" />
192
192
  ) : (
193
- <IconStar className="h-3.5 w-3.5 text-foreground/70" />
193
+ <IconStar className="h-3.5 w-3.5 text-white/70" />
194
194
  )}
195
195
  </button>
196
196
  )}
@@ -208,7 +208,7 @@ export default function DeckCard({
208
208
  }`}
209
209
  aria-label={t("raw.deckOptions")}
210
210
  >
211
- <IconDots className="w-3.5 h-3.5 text-foreground/70" />
211
+ <IconDots className="w-3.5 h-3.5 text-white/70" />
212
212
  </button>
213
213
  </DropdownMenuTrigger>
214
214
  <DropdownMenuContent
@@ -479,7 +479,7 @@ export function DesignSystemSetup({
479
479
 
480
480
  if (websiteUrls.length > 0) {
481
481
  parts.push(
482
- `\n## Website URLs\nAnalyze these websites for design tokens. Call \`import-from-url\` for each:\n${websiteUrls.map((u) => `- ${u}`).join("\n")}`,
482
+ `\n## Website URLs\nAnalyze these websites for design tokens. Call \`import-from-url\` for each:\n${websiteUrls.map((u) => `- ${u}`).join("\n")}\n\nThe shared action uses the layered real-browser renderer so hydrated React, CSS-in-JS, Tailwind, SPA content, loaded fonts, computed colors, component styles, CSS variables, and desktop/mobile screenshot evidence are captured consistently. It falls back explicitly to SSRF-safe static extraction only when a browser is unavailable. Use its design.md-style result as the source of truth for the deck style.`,
483
483
  );
484
484
  }
485
485
 
@@ -1,5 +1,6 @@
1
1
  import { appBasePath } from "@agent-native/core/client/api-path";
2
2
  import { PromptComposer } from "@agent-native/core/client/composer";
3
+ import { ensureEmbedAuthFetchInterceptor } from "@agent-native/core/client/host";
3
4
  import { useT } from "@agent-native/core/client/i18n";
4
5
  import { useState, useEffect, useCallback, useRef } from "react";
5
6
  import { createPortal } from "react-dom";
@@ -22,9 +23,11 @@ export async function uploadPromptFiles(
22
23
  if (files.length === 0) return [];
23
24
  const formData = new FormData();
24
25
  files.forEach((file) => formData.append("files", file));
26
+ ensureEmbedAuthFetchInterceptor();
25
27
  const response = await fetch(`${appBasePath()}/api/uploads`, {
26
28
  method: "POST",
27
29
  body: formData,
30
+ credentials: "include",
28
31
  });
29
32
  if (!response.ok) {
30
33
  let message = "Upload failed";
@@ -4112,7 +4112,7 @@ export default function SlideEditor({
4112
4112
  // to stay mounted or that background becomes uneditable.
4113
4113
  const contextToolbar = !readOnly ? (
4114
4114
  <div
4115
- className="hidden shrink-0 lg:block"
4115
+ className="shrink-0"
4116
4116
  // Snapshotting the range is only half the job: without this marker the
4117
4117
  // click-outside handler exits the edit and clears the snapshot before
4118
4118
  // the button's onClick runs, so partial-text formatting would silently
@@ -15,7 +15,10 @@ import {
15
15
  uploadPromptFiles,
16
16
  type UploadedFile,
17
17
  } from "@/components/editor/PromptDialog";
18
- import { useDecks } from "@/context/DeckContext";
18
+ import {
19
+ describeDeckPersistenceFailure,
20
+ useDecks,
21
+ } from "@/context/DeckContext";
19
22
  import { useAgentGenerating } from "@/hooks/use-agent-generating";
20
23
  import { useDesignSystems } from "@/hooks/use-design-systems";
21
24
  import { useWorkspaceDefaults } from "@/hooks/use-workspace-defaults";
@@ -141,12 +144,15 @@ export function FirstDeckOnboardingFlow({
141
144
  onUnauthenticated: () => {
142
145
  toast.error(t("home.signInTitle"));
143
146
  },
144
- onPersistenceFailure: (failedPrompt) => {
147
+ onPersistenceFailure: (failedPrompt, _failedFiles, failure) => {
145
148
  setPromptInitialText(failedPrompt);
146
149
  setPromptInitialTextKey(Date.now());
147
150
  setStep("prompt");
148
151
  toast.error(t("home.generationStartFailed"), {
149
- description: t("home.generationStartFailedDescription"),
152
+ description: describeDeckPersistenceFailure(
153
+ failure,
154
+ t("home.generationStartFailedDescription"),
155
+ ),
150
156
  });
151
157
  },
152
158
  });
@@ -138,6 +138,25 @@ export interface Deck {
138
138
  aspectRatio?: AspectRatio;
139
139
  }
140
140
 
141
+ export type DeckPersistenceResult =
142
+ | { persisted: true }
143
+ | { persisted: false; reason: "request-failed"; error: unknown }
144
+ | { persisted: false; reason: "not-found" };
145
+
146
+ export function describeDeckPersistenceFailure(
147
+ result: DeckPersistenceResult,
148
+ fallback: string,
149
+ ): string {
150
+ if (result.persisted || result.reason === "not-found") return fallback;
151
+ if (result.error instanceof Error && result.error.message.trim()) {
152
+ return result.error.message;
153
+ }
154
+ if (typeof result.error === "string" && result.error.trim()) {
155
+ return result.error;
156
+ }
157
+ return fallback;
158
+ }
159
+
141
160
  interface DeckContextType {
142
161
  decks: Deck[];
143
162
  loading: boolean;
@@ -146,7 +165,7 @@ interface DeckContextType {
146
165
  title?: string,
147
166
  options?: { noDefaultSlides?: boolean; designSystemId?: string | null },
148
167
  ) => Deck;
149
- ensureDeckPersisted: (id: string) => Promise<boolean>;
168
+ ensureDeckPersisted: (id: string) => Promise<DeckPersistenceResult>;
150
169
  /**
151
170
  * Optimistically duplicate a deck. Inserts a copy into local state with the
152
171
  * supplied `newId` immediately so the UI can navigate without awaiting the
@@ -167,6 +186,7 @@ interface DeckContextType {
167
186
  ) => void;
168
187
  reloadDecks: () => Promise<void>;
169
188
  reloadDecksWithStatus: () => Promise<DeckReloadStatus>;
189
+ refreshOpenDeck: (deckId: string) => Promise<Deck | null>;
170
190
  getDeck: (id: string) => Deck | undefined;
171
191
  addSlide: (
172
192
  deckId: string,
@@ -885,7 +905,22 @@ async function fetchDecksForCurrentRoute(): Promise<Deck[] | null> {
885
905
  }
886
906
 
887
907
  async function deleteDeckFromAPI(id: string): Promise<void> {
888
- await callAction("delete-deck", { id }, { method: "DELETE" });
908
+ try {
909
+ await callAction("delete-deck", { id }, { method: "DELETE" });
910
+ } catch (error) {
911
+ // Deleting an optimistic deck is intentionally idempotent. A create can
912
+ // fail after the server committed the row, or before it created one.
913
+ if (
914
+ !(
915
+ error &&
916
+ typeof error === "object" &&
917
+ "status" in error &&
918
+ (error as { status?: unknown }).status === 404
919
+ )
920
+ ) {
921
+ throw error;
922
+ }
923
+ }
889
924
  }
890
925
 
891
926
  async function createDeckOnAPI(deck: Deck): Promise<void> {
@@ -1081,7 +1116,7 @@ export function DeckProvider({ children }: { children: ReactNode }) {
1081
1116
  const deletion = pendingCreate
1082
1117
  ? pendingCreate.then(
1083
1118
  () => deleteDeckFromAPI(deckId),
1084
- () => undefined,
1119
+ () => deleteDeckFromAPI(deckId),
1085
1120
  )
1086
1121
  : deleteDeckFromAPI(deckId);
1087
1122
  void deletion.catch((err) => {
@@ -1267,11 +1302,11 @@ export function DeckProvider({ children }: { children: ReactNode }) {
1267
1302
  // - Dirty deck / unsaved local create → additive merge only: surface
1268
1303
  // agent-added slides without ever overwriting or dropping local slides.
1269
1304
  const refetchOpenDeckIfChanged = useCallback(
1270
- async (currentOpenId: string) => {
1305
+ async (currentOpenId: string): Promise<Deck | null> => {
1271
1306
  const serverDeck = await fetchDeckFromAPI(currentOpenId);
1272
1307
  // Null means 404 (row not created yet), a transient failure, or a
1273
1308
  // still-pending create — nothing authoritative to reconcile.
1274
- if (!serverDeck) return;
1309
+ if (!serverDeck) return null;
1275
1310
  const clientDeck = decksRef.current.find((d) => d.id === currentOpenId);
1276
1311
 
1277
1312
  const hasLocalEdits =
@@ -1281,7 +1316,7 @@ export function DeckProvider({ children }: { children: ReactNode }) {
1281
1316
  if (hasLocalEdits && clientDeck) {
1282
1317
  // Content-preserving: only ADD server slides missing locally.
1283
1318
  const merged = mergeServerAddedSlides(clientDeck, serverDeck);
1284
- if (merged === clientDeck) return; // nothing new to surface
1319
+ if (merged === clientDeck) return serverDeck; // nothing new to surface
1285
1320
  lastExternalUpdateRef.current = Date.now();
1286
1321
  setDecks((prev) => {
1287
1322
  const idx = prev.findIndex((d) => d.id === currentOpenId);
@@ -1290,16 +1325,17 @@ export function DeckProvider({ children }: { children: ReactNode }) {
1290
1325
  next[idx] = merged;
1291
1326
  return next;
1292
1327
  });
1293
- return;
1328
+ return serverDeck;
1294
1329
  }
1295
1330
 
1296
1331
  const changed =
1297
1332
  !clientDeck ||
1298
1333
  clientDeck.updatedAt !== serverDeck.updatedAt ||
1299
- clientDeck.slides.length !== serverDeck.slides.length;
1300
- if (!changed) return;
1334
+ deckContentSignature(clientDeck) !== deckContentSignature(serverDeck);
1335
+ if (!changed) return serverDeck;
1301
1336
  lastExternalUpdateRef.current = Date.now();
1302
1337
  applyRemoteDeckUpdate(serverDeck);
1338
+ return serverDeck;
1303
1339
  },
1304
1340
  [applyRemoteDeckUpdate],
1305
1341
  );
@@ -1728,19 +1764,33 @@ export function DeckProvider({ children }: { children: ReactNode }) {
1728
1764
  [noteLocalCreate, setDecksLocal],
1729
1765
  );
1730
1766
 
1731
- const ensureDeckPersisted = useCallback(async (id: string) => {
1732
- const pendingCreate = pendingCreatePromisesRef.current.get(id);
1733
- if (pendingCreate) {
1734
- try {
1735
- await pendingCreate;
1736
- return true;
1737
- } catch {
1738
- return false;
1767
+ const ensureDeckPersisted = useCallback(
1768
+ async (id: string): Promise<DeckPersistenceResult> => {
1769
+ const pendingCreate = pendingCreatePromisesRef.current.get(id);
1770
+ if (pendingCreate) {
1771
+ try {
1772
+ await pendingCreate;
1773
+ return { persisted: true };
1774
+ } catch (error) {
1775
+ return { persisted: false, reason: "request-failed", error };
1776
+ }
1739
1777
  }
1740
- }
1741
1778
 
1742
- return (await fetchDeckFromAPI(id)) !== null;
1743
- }, []);
1779
+ try {
1780
+ const result = await callAction<unknown>(
1781
+ "get-deck",
1782
+ { id },
1783
+ { method: "GET" },
1784
+ );
1785
+ return normalizeActionDeck(result)
1786
+ ? { persisted: true }
1787
+ : { persisted: false, reason: "not-found" };
1788
+ } catch (error) {
1789
+ return { persisted: false, reason: "request-failed", error };
1790
+ }
1791
+ },
1792
+ [],
1793
+ );
1744
1794
 
1745
1795
  const duplicateDeck = useCallback(
1746
1796
  (sourceDeckId: string, newId: string, title?: string): Deck | null => {
@@ -2150,6 +2200,7 @@ export function DeckProvider({ children }: { children: ReactNode }) {
2150
2200
  updateDeck,
2151
2201
  reloadDecks,
2152
2202
  reloadDecksWithStatus,
2203
+ refreshOpenDeck: refetchOpenDeckIfChanged,
2153
2204
  getDeck,
2154
2205
  addSlide,
2155
2206
  updateSlide,
@@ -14,6 +14,12 @@
14
14
 
15
15
  @source "./**/*.{ts,tsx}";
16
16
 
17
+ /* Keep the editable agent prompt readable even if the generated text utility
18
+ is missing or loses a cascade tie during the hosted build. */
19
+ .agent-composer-root [data-agent-composer-slot="editor-input"] {
20
+ color: hsl(var(--foreground));
21
+ }
22
+
17
23
  /* Hide the sidebar's built-in collapsed tab strip — AgentToggleButton in the
18
24
  toolbar serves this purpose instead, so we don't want a redundant bar. */
19
25
  button[title="Open agent sidebar"] {
@@ -654,17 +654,17 @@ const messages = {
654
654
  mine: "Mine",
655
655
  deckCount_one: "deck",
656
656
  deckCount_other: "decks",
657
- createDeckOrVisual: "Create a deck or visual",
657
+ createDeckOrVisual: "Create a presentation",
658
658
  noMineDecks: "No decks created by you yet.",
659
659
  deleteDeckTitle: "Delete Deck?",
660
660
  deleteDeckDescription:
661
661
  "This will permanently delete this deck and all its slides. This action cannot be undone.",
662
662
  cancel: "Cancel",
663
663
  delete: "Delete",
664
- newDeckPromptTitle: "New deck",
665
- newDeckPlaceholder: "Describe your deck, visual, or diagram...",
664
+ newDeckPromptTitle: "New presentation",
665
+ newDeckPlaceholder: "Describe the presentation you want to generate...",
666
666
  skipPrompt: "Skip prompt",
667
- firstDeckPromptTitle: "What do you want to make?",
667
+ firstDeckPromptTitle: "What kind of presentation should we generate?",
668
668
  firstDeckSkip: "Skip",
669
669
  chooseReferences: "Choose references",
670
670
  addDesignSystem: "+ Design system",
@@ -716,7 +716,7 @@ const messages = {
716
716
  emptyTitle: "No decks yet",
717
717
  createFirstDeck: "Create your first deck",
718
718
  emptyDescription:
719
- "Build beautiful presentations, standalone visuals, diagrams, and image-rich stories with AI-powered generation.",
719
+ "Build beautiful presentations with AI-powered generation.",
720
720
  },
721
721
  };
722
722
 
@@ -4,7 +4,7 @@ import { flushSync } from "react-dom";
4
4
 
5
5
  import type { NewDeckReferenceSelection } from "@/components/editor/NewDeckReferenceStep";
6
6
  import type { UploadedFile } from "@/components/editor/PromptDialog";
7
- import type { Deck } from "@/context/DeckContext";
7
+ import type { Deck, DeckPersistenceResult } from "@/context/DeckContext";
8
8
  import { createDeckAgentMessage } from "@/lib/agent-visible-message";
9
9
 
10
10
  interface DesignSystemGenerationContextResult {
@@ -150,13 +150,17 @@ export interface StartDeckGenerationOptions {
150
150
  selectedReferenceDeckId?: string | null;
151
151
  designSystems: Array<{ id: string; title: string }>;
152
152
  createDeck: CreateDeck;
153
- ensureDeckPersisted: (id: string) => Promise<boolean>;
153
+ ensureDeckPersisted: (id: string) => Promise<DeckPersistenceResult>;
154
154
  deleteDeck: (id: string) => void;
155
155
  navigate: Navigate;
156
156
  agentSubmit: SubmitAgent;
157
157
  onPromptClosed: () => void;
158
158
  onUnauthenticated: (prompt: string, hadFiles: boolean) => void;
159
- onPersistenceFailure: (prompt: string, files: UploadedFile[]) => void;
159
+ onPersistenceFailure: (
160
+ prompt: string,
161
+ files: UploadedFile[],
162
+ failure: DeckPersistenceResult,
163
+ ) => void;
160
164
  }
161
165
 
162
166
  /** Create the optimistic deck, hydrate references, and start the agent run. */
@@ -214,8 +218,8 @@ export async function startDeckGeneration({
214
218
  onPromptClosed();
215
219
 
216
220
  const persisted = await ensureDeckPersisted(deck.id);
217
- if (!persisted) {
218
- onPersistenceFailure(prompt, filesForGeneration);
221
+ if (!persisted.persisted) {
222
+ onPersistenceFailure(prompt, filesForGeneration, persisted);
219
223
  deleteDeck(deckId);
220
224
  return "failed";
221
225
  }
@@ -155,6 +155,7 @@ export default function DeckEditor() {
155
155
  getDeck,
156
156
  reloadDecks,
157
157
  reloadDecksWithStatus,
158
+ refreshOpenDeck,
158
159
  updateDeck,
159
160
  updateSlide,
160
161
  deleteSlide,
@@ -396,6 +397,22 @@ export default function DeckEditor() {
396
397
  }
397
398
  }, [refetchOrg, reloadDecks]);
398
399
 
400
+ // The final generation write can race the last sync event. Pull the
401
+ // authoritative open deck when the run settles so a stale canvas does not
402
+ // require a browser refresh to reveal completed slides.
403
+ useEffect(() => {
404
+ if (
405
+ !id ||
406
+ !shouldClearNewDeckGeneratingState({
407
+ generating,
408
+ generationStarted: newDeckGenerationStarted.current,
409
+ })
410
+ ) {
411
+ return;
412
+ }
413
+ void refreshOpenDeck(id);
414
+ }, [generating, id, refreshOpenDeck]);
415
+
399
416
  // Clean up the generating URL param/ref when generation completes or when
400
417
  // the first slide lands, so partial progress is visible during long decks.
401
418
  useEffect(() => {