@agent-native/core 0.122.4 → 0.123.0

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 (1340) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +538 -0
  3. package/corpus/core/docs/content/actions.mdx +33 -20
  4. package/corpus/core/docs/content/agent-mentions.mdx +30 -19
  5. package/corpus/core/docs/content/agent-native-toolkit.mdx +8 -6
  6. package/corpus/core/docs/content/agent-resources.mdx +11 -0
  7. package/corpus/core/docs/content/agent-surfaces.mdx +41 -30
  8. package/corpus/core/docs/content/audit-log.mdx +78 -0
  9. package/corpus/core/docs/content/authentication.mdx +7 -5
  10. package/corpus/core/docs/content/automations.mdx +15 -9
  11. package/corpus/core/docs/content/client.mdx +11 -11
  12. package/corpus/core/docs/content/cloneable-saas.mdx +7 -1
  13. package/corpus/core/docs/content/code-agents-ui.mdx +9 -1
  14. package/corpus/core/docs/content/components.mdx +7 -0
  15. package/corpus/core/docs/content/context-awareness.mdx +1 -0
  16. package/corpus/core/docs/content/creating-templates.mdx +9 -1
  17. package/corpus/core/docs/content/custom-design-system.mdx +8 -0
  18. package/corpus/core/docs/content/data-programs.mdx +6 -0
  19. package/corpus/core/docs/content/deployment.mdx +2 -0
  20. package/corpus/core/docs/content/doctor.mdx +5 -3
  21. package/corpus/core/docs/content/extensions.mdx +26 -0
  22. package/corpus/core/docs/content/external-agents-catalog.mdx +533 -0
  23. package/corpus/core/docs/content/external-agents.mdx +20 -514
  24. package/corpus/core/docs/content/faq.mdx +2 -2
  25. package/corpus/core/docs/content/file-uploads.mdx +44 -0
  26. package/corpus/core/docs/content/frames.mdx +2 -2
  27. package/corpus/core/docs/content/generative-ui.mdx +8 -0
  28. package/corpus/core/docs/content/getting-started.mdx +45 -17
  29. package/corpus/core/docs/content/human-approval.mdx +9 -0
  30. package/corpus/core/docs/content/integrations.mdx +4 -3
  31. package/corpus/core/docs/content/internationalization.mdx +4 -11
  32. package/corpus/core/docs/content/key-concepts.mdx +1 -1
  33. package/corpus/core/docs/content/local-file-mode.mdx +5 -0
  34. package/corpus/core/docs/content/mcp-apps.mdx +2 -1
  35. package/corpus/core/docs/content/mcp-clients.mdx +32 -1
  36. package/corpus/core/docs/content/mcp-protocol.mdx +4 -3
  37. package/corpus/core/docs/content/messaging-internals.mdx +328 -0
  38. package/corpus/core/docs/content/messaging-recipes.mdx +194 -0
  39. package/corpus/core/docs/content/messaging.mdx +9 -307
  40. package/corpus/core/docs/content/multi-app-workspace.mdx +1 -1
  41. package/corpus/core/docs/content/multi-tenancy.mdx +1 -0
  42. package/corpus/core/docs/content/native-chat-ui.mdx +8 -0
  43. package/corpus/core/docs/content/notifications.mdx +18 -20
  44. package/corpus/core/docs/content/observability.mdx +1 -0
  45. package/corpus/core/docs/content/onboarding.mdx +20 -6
  46. package/corpus/core/docs/content/organizations-teams-permissions.mdx +99 -124
  47. package/corpus/core/docs/content/package-lifecycle.mdx +19 -7
  48. package/corpus/core/docs/content/progress.mdx +11 -0
  49. package/corpus/core/docs/content/real-time-collaboration.mdx +44 -3
  50. package/corpus/core/docs/content/recurring-jobs.mdx +14 -1
  51. package/corpus/core/docs/content/security.mdx +5 -2
  52. package/corpus/core/docs/content/server.mdx +2 -1
  53. package/corpus/core/docs/content/sharing.mdx +22 -3
  54. package/corpus/core/docs/content/skills-guide.mdx +62 -19
  55. package/corpus/core/docs/content/syncing-template-changes.mdx +9 -0
  56. package/corpus/core/docs/content/template-analytics-connectors.mdx +75 -0
  57. package/corpus/core/docs/content/template-analytics-dashboards.mdx +106 -0
  58. package/corpus/core/docs/content/template-analytics-developers.mdx +287 -0
  59. package/corpus/core/docs/content/template-analytics-monitoring-and-sessions.mdx +109 -0
  60. package/corpus/core/docs/content/template-analytics.mdx +21 -263
  61. package/corpus/core/docs/content/template-assets-developers.mdx +456 -0
  62. package/corpus/core/docs/content/template-assets-generation.mdx +147 -0
  63. package/corpus/core/docs/content/template-assets-integrations.mdx +319 -0
  64. package/corpus/core/docs/content/template-assets-presets.mdx +185 -0
  65. package/corpus/core/docs/content/template-assets.mdx +12 -562
  66. package/corpus/core/docs/content/template-brain-agent.mdx +103 -0
  67. package/corpus/core/docs/content/template-brain-developers.mdx +379 -0
  68. package/corpus/core/docs/content/template-brain-knowledge.mdx +50 -0
  69. package/corpus/core/docs/content/template-brain-sources.mdx +163 -0
  70. package/corpus/core/docs/content/template-brain.mdx +30 -390
  71. package/corpus/core/docs/content/template-calendar-agent.mdx +133 -0
  72. package/corpus/core/docs/content/template-calendar-booking-links.mdx +73 -0
  73. package/corpus/core/docs/content/template-calendar-developers.mdx +366 -0
  74. package/corpus/core/docs/content/template-calendar-scheduling.mdx +128 -0
  75. package/corpus/core/docs/content/template-calendar.mdx +13 -260
  76. package/corpus/core/docs/content/template-chat-developers.mdx +88 -0
  77. package/corpus/core/docs/content/template-chat-first-edits.mdx +145 -0
  78. package/corpus/core/docs/content/template-chat.mdx +12 -77
  79. package/corpus/core/docs/content/template-clips-ai-and-editing.mdx +114 -0
  80. package/corpus/core/docs/content/template-clips-capture-everywhere.mdx +120 -0
  81. package/corpus/core/docs/content/template-clips-developers.mdx +373 -0
  82. package/corpus/core/docs/content/template-clips-sharing-and-teams.mdx +182 -0
  83. package/corpus/core/docs/content/template-clips.mdx +19 -508
  84. package/corpus/core/docs/content/template-content-databases.mdx +406 -0
  85. package/corpus/core/docs/content/template-content-developers.mdx +364 -0
  86. package/corpus/core/docs/content/template-content-editing.mdx +60 -0
  87. package/corpus/core/docs/content/template-content-sync.mdx +149 -0
  88. package/corpus/core/docs/content/template-content.mdx +21 -561
  89. package/corpus/core/docs/content/template-design-brand-and-figma.mdx +150 -0
  90. package/corpus/core/docs/content/template-design-collaboration-and-full-apps.mdx +125 -0
  91. package/corpus/core/docs/content/template-design-developers.mdx +358 -0
  92. package/corpus/core/docs/content/template-design-quality-and-components.mdx +95 -0
  93. package/corpus/core/docs/content/template-design.mdx +20 -344
  94. package/corpus/core/docs/content/template-dispatch-developers.mdx +121 -0
  95. package/corpus/core/docs/content/template-dispatch-messaging-routing.mdx +114 -0
  96. package/corpus/core/docs/content/template-dispatch-operations.mdx +160 -0
  97. package/corpus/core/docs/content/template-dispatch-vault-integrations.mdx +316 -0
  98. package/corpus/core/docs/content/template-dispatch.mdx +24 -283
  99. package/corpus/core/docs/content/template-forms-building-publishing.mdx +135 -0
  100. package/corpus/core/docs/content/template-forms-developers.mdx +195 -0
  101. package/corpus/core/docs/content/template-forms-responses.mdx +120 -0
  102. package/corpus/core/docs/content/template-forms.mdx +21 -230
  103. package/corpus/core/docs/content/template-mail-agent.mdx +114 -0
  104. package/corpus/core/docs/content/template-mail-developers.mdx +356 -0
  105. package/corpus/core/docs/content/template-mail-drafts-and-queue.mdx +103 -0
  106. package/corpus/core/docs/content/template-mail-inbox.mdx +118 -0
  107. package/corpus/core/docs/content/template-mail.mdx +23 -274
  108. package/corpus/core/docs/content/template-plan-automations.mdx +213 -0
  109. package/corpus/core/docs/content/template-plan-developers.mdx +703 -0
  110. package/corpus/core/docs/content/template-plan-local-and-desktop.mdx +236 -0
  111. package/corpus/core/docs/content/template-plan-review-workflow.mdx +180 -0
  112. package/corpus/core/docs/content/template-plan.mdx +60 -910
  113. package/corpus/core/docs/content/template-slides-agent.mdx +102 -0
  114. package/corpus/core/docs/content/template-slides-design-and-media.mdx +94 -0
  115. package/corpus/core/docs/content/template-slides-developers.mdx +488 -0
  116. package/corpus/core/docs/content/template-slides-editing.mdx +56 -0
  117. package/corpus/core/docs/content/template-slides.mdx +20 -362
  118. package/corpus/core/docs/content/toolkit-capability-packages.mdx +38 -13
  119. package/corpus/core/docs/content/toolkit-context-knowledge.mdx +49 -9
  120. package/corpus/core/docs/content/toolkit-editors-canvases.mdx +72 -10
  121. package/corpus/core/docs/content/toolkit-resources.mdx +16 -0
  122. package/corpus/core/docs/content/toolkit-settings.mdx +3 -3
  123. package/corpus/core/docs/content/toolkit-sharing.mdx +5 -7
  124. package/corpus/core/docs/content/using-your-agent.mdx +25 -2
  125. package/corpus/core/docs/content/voice-input.mdx +11 -7
  126. package/corpus/core/docs/content/what-is-agent-native.mdx +1 -0
  127. package/corpus/core/docs/content/workspace-connections.mdx +21 -11
  128. package/corpus/core/docs/content/workspace-management.mdx +1 -1
  129. package/corpus/core/package.json +1 -3
  130. package/corpus/core/src/a2a/client.ts +4 -2
  131. package/corpus/core/src/agent/action-warnings.ts +103 -0
  132. package/corpus/core/src/agent/durable-background.ts +42 -5
  133. package/corpus/core/src/agent/engine/ai-sdk-engine.ts +58 -6
  134. package/corpus/core/src/agent/engine/anthropic-engine.ts +51 -8
  135. package/corpus/core/src/agent/engine/builder-engine.ts +56 -18
  136. package/corpus/core/src/agent/engine/continuation-dispatch-retry.ts +10 -9
  137. package/corpus/core/src/agent/engine/credential-errors.ts +11 -0
  138. package/corpus/core/src/agent/engine/error-detail.ts +39 -0
  139. package/corpus/core/src/agent/engine/prompt-cache.ts +44 -0
  140. package/corpus/core/src/agent/engine/registry.ts +22 -30
  141. package/corpus/core/src/agent/engine/tool-call-journal-seed.ts +2 -1
  142. package/corpus/core/src/agent/engine/translate-anthropic.ts +99 -0
  143. package/corpus/core/src/agent/loop-settings.ts +94 -7
  144. package/corpus/core/src/agent/production-agent.ts +667 -157
  145. package/corpus/core/src/agent/run-loop-with-resume.ts +27 -1
  146. package/corpus/core/src/agent/run-manager.ts +229 -39
  147. package/corpus/core/src/agent/run-store.ts +397 -64
  148. package/corpus/core/src/agent/thread-data-builder.ts +5 -1
  149. package/corpus/core/src/agent/types.ts +23 -6
  150. package/corpus/core/src/application-state/script-helpers.ts +5 -2
  151. package/corpus/core/src/cli/agents.ts +69 -1
  152. package/corpus/core/src/cli/app-skill.ts +1 -1
  153. package/corpus/core/src/cli/code-agent-executor.ts +7 -3
  154. package/corpus/core/src/cli/design-connect.ts +82 -8
  155. package/corpus/core/src/cli/skills-content/design-visual-edit-skill.ts +169 -24
  156. package/corpus/core/src/client/AssistantChat.tsx +623 -607
  157. package/corpus/core/src/client/agent-chat-adapter.ts +176 -29
  158. package/corpus/core/src/client/chat/message-components.tsx +13 -0
  159. package/corpus/core/src/client/embed-auth.ts +3 -1
  160. package/corpus/core/src/client/integrations/IntegrationCard.tsx +41 -24
  161. package/corpus/core/src/client/integrations/IntegrationsPanel.tsx +37 -21
  162. package/corpus/core/src/client/integrations/webhook-url.ts +29 -0
  163. package/corpus/core/src/client/org/OrgSwitcher.tsx +41 -27
  164. package/corpus/core/src/client/org/RequireActiveOrg.tsx +7 -0
  165. package/corpus/core/src/client/org/TeamPage.tsx +144 -14
  166. package/corpus/core/src/client/org/hooks.ts +27 -0
  167. package/corpus/core/src/client/org/index.ts +2 -0
  168. package/corpus/core/src/client/require-session.tsx +40 -29
  169. package/corpus/core/src/client/session-replay.ts +1 -1
  170. package/corpus/core/src/client/settings/DemoModeSection.tsx +0 -5
  171. package/corpus/core/src/client/settings/SecretsSection.tsx +47 -42
  172. package/corpus/core/src/client/settings/VoiceTranscriptionSection.tsx +0 -5
  173. package/corpus/core/src/client/sse-event-processor.ts +83 -8
  174. package/corpus/core/src/client/use-action.ts +22 -13
  175. package/corpus/core/src/client/use-agent-engine-configured.ts +36 -4
  176. package/corpus/core/src/client/use-db-sync.ts +21 -1
  177. package/corpus/core/src/credentials/index.ts +124 -2
  178. package/corpus/core/src/deploy/build.ts +93 -30
  179. package/corpus/core/src/deploy/workspace-deploy.ts +21 -16
  180. package/corpus/core/src/guards/no-localhost-fallback.ts +76 -14
  181. package/corpus/core/src/integrations/google-docs-poller.ts +19 -12
  182. package/corpus/core/src/integrations/webhook-handler.ts +56 -33
  183. package/corpus/core/src/jobs/scheduler.ts +57 -23
  184. package/corpus/core/src/localization/default-messages.ts +23 -1
  185. package/corpus/core/src/observability/evals.ts +7 -8
  186. package/corpus/core/src/observability/traces.ts +2 -0
  187. package/corpus/core/src/org/accept-pending.ts +2 -2
  188. package/corpus/core/src/org/active-org.ts +73 -0
  189. package/corpus/core/src/org/auto-join-domain.ts +7 -2
  190. package/corpus/core/src/org/context.ts +169 -66
  191. package/corpus/core/src/org/handlers.ts +148 -10
  192. package/corpus/core/src/org/plugin.ts +8 -1
  193. package/corpus/core/src/org/types.ts +6 -1
  194. package/corpus/core/src/provider-api/index.ts +6 -1
  195. package/corpus/core/src/resources/handlers.ts +2 -6
  196. package/corpus/core/src/resources/script-helpers.ts +2 -1
  197. package/corpus/core/src/scripts/chat/search-chats.ts +5 -2
  198. package/corpus/core/src/scripts/describe-workspace-apps.ts +59 -0
  199. package/corpus/core/src/scripts/resources/delete-memory.ts +5 -2
  200. package/corpus/core/src/scripts/resources/delete.ts +5 -2
  201. package/corpus/core/src/scripts/resources/effective.ts +5 -2
  202. package/corpus/core/src/scripts/resources/list.ts +5 -2
  203. package/corpus/core/src/scripts/resources/read.ts +5 -2
  204. package/corpus/core/src/scripts/resources/save-memory.ts +5 -2
  205. package/corpus/core/src/scripts/resources/write.ts +5 -2
  206. package/corpus/core/src/server/agent-capabilities.ts +147 -0
  207. package/corpus/core/src/server/agent-chat/framework-prompts.ts +11 -13
  208. package/corpus/core/src/server/agent-chat/prompt-resources.ts +183 -57
  209. package/corpus/core/src/server/agent-chat/script-entries.ts +20 -7
  210. package/corpus/core/src/server/agent-chat-plugin.ts +27 -0
  211. package/corpus/core/src/server/auth.ts +38 -32
  212. package/corpus/core/src/server/core-routes-plugin.ts +229 -179
  213. package/corpus/core/src/server/credential-provider.ts +196 -44
  214. package/corpus/core/src/server/embed-session.ts +10 -0
  215. package/corpus/core/src/server/framework-request-handler.ts +43 -0
  216. package/corpus/core/src/server/google-auth-plugin.ts +13 -450
  217. package/corpus/core/src/server/index.ts +4 -1
  218. package/corpus/core/src/server/onboarding-html.ts +20 -56
  219. package/corpus/core/src/server/open-route.ts +6 -1
  220. package/corpus/core/src/server/poll.ts +1 -1
  221. package/corpus/core/src/server/prompts/framework-core-compact.ts +5 -5
  222. package/corpus/core/src/server/prompts/framework-core.ts +7 -9
  223. package/corpus/core/src/server/prompts/shared-rules.ts +20 -9
  224. package/corpus/core/src/server/request-context.ts +58 -2
  225. package/corpus/core/src/server/scoped-key-storage.ts +1 -1
  226. package/corpus/core/src/settings/org-settings.ts +9 -0
  227. package/corpus/core/src/settings/store.ts +29 -0
  228. package/corpus/core/src/shared/index.ts +13 -0
  229. package/corpus/core/src/shared/sign-in-journey.ts +331 -0
  230. package/corpus/core/src/styles/agent-native.css +8 -0
  231. package/corpus/core/src/templates/chat/.agents/skills/actions/SKILL.md +19 -1
  232. package/corpus/core/src/templates/chat/.agents/skills/adding-a-feature/SKILL.md +2 -0
  233. package/corpus/core/src/templates/chat/.agents/skills/frontend-design/SKILL.md +20 -6
  234. package/corpus/core/src/templates/chat/.agents/skills/security/SKILL.md +2 -0
  235. package/corpus/core/src/templates/chat/.agents/skills/self-modifying-code/SKILL.md +4 -3
  236. package/corpus/core/src/templates/chat/.agents/skills/shadcn-ui/SKILL.md +7 -3
  237. package/corpus/core/src/templates/chat/AGENTS.md +8 -0
  238. package/corpus/core/src/templates/chat/app/entry.client.tsx +3 -0
  239. package/corpus/core/src/templates/chat/changelog/2026-07-24-borderless-secondary-surfaces.md +6 -0
  240. package/corpus/core/src/templates/chat/changelog/2026-07-24-sidebar-footer-controls-follow-a-consistent-order.md +6 -0
  241. package/corpus/core/src/templates/chat/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
  242. package/corpus/core/src/templates/default/.agents/skills/actions/SKILL.md +19 -1
  243. package/corpus/core/src/templates/default/.agents/skills/adding-a-feature/SKILL.md +2 -0
  244. package/corpus/core/src/templates/default/.agents/skills/frontend-design/SKILL.md +20 -6
  245. package/corpus/core/src/templates/default/.agents/skills/security/SKILL.md +2 -0
  246. package/corpus/core/src/templates/default/.agents/skills/self-modifying-code/SKILL.md +4 -3
  247. package/corpus/core/src/templates/default/.agents/skills/shadcn-ui/SKILL.md +7 -3
  248. package/corpus/core/src/templates/default/AGENTS.md +68 -195
  249. package/corpus/core/src/templates/default/app/entry.client.tsx +3 -0
  250. package/corpus/core/src/templates/default/app/i18n/ar-SA.ts +8 -0
  251. package/corpus/core/src/templates/default/app/i18n/de-DE.ts +8 -0
  252. package/corpus/core/src/templates/default/app/i18n/en-US.ts +8 -0
  253. package/corpus/core/src/templates/default/app/i18n/es-ES.ts +8 -0
  254. package/corpus/core/src/templates/default/app/i18n/fr-FR.ts +8 -0
  255. package/corpus/core/src/templates/default/app/i18n/hi-IN.ts +8 -0
  256. package/corpus/core/src/templates/default/app/i18n/ja-JP.ts +8 -0
  257. package/corpus/core/src/templates/default/app/i18n/ko-KR.ts +8 -0
  258. package/corpus/core/src/templates/default/app/i18n/pt-BR.ts +8 -0
  259. package/corpus/core/src/templates/default/app/i18n/zh-CN.ts +8 -0
  260. package/corpus/core/src/templates/default/app/i18n/zh-TW.ts +8 -0
  261. package/corpus/core/src/templates/headless/.agents/skills/actions/SKILL.md +19 -1
  262. package/corpus/core/src/templates/workspace-core/.agents/skills/actions/SKILL.md +19 -1
  263. package/corpus/core/src/templates/workspace-core/.agents/skills/adding-a-feature/SKILL.md +2 -0
  264. package/corpus/core/src/templates/workspace-core/.agents/skills/adding-workspace-apps/SKILL.md +100 -0
  265. package/corpus/core/src/templates/workspace-core/.agents/skills/address-feedback/SKILL.md +2 -1
  266. package/corpus/core/src/templates/workspace-core/.agents/skills/authentication/SKILL.md +28 -0
  267. package/corpus/core/src/templates/workspace-core/.agents/skills/composable-mini-apps/SKILL.md +14 -1
  268. package/corpus/core/src/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +20 -6
  269. package/corpus/core/src/templates/workspace-core/.agents/skills/qa/SKILL.md +6 -3
  270. package/corpus/core/src/templates/workspace-core/.agents/skills/security/SKILL.md +2 -0
  271. package/corpus/core/src/templates/workspace-core/.agents/skills/self-modifying-code/SKILL.md +4 -3
  272. package/corpus/core/src/templates/workspace-core/.agents/skills/shadcn-ui/SKILL.md +7 -3
  273. package/corpus/core/src/templates/workspace-core/.agents/skills/workspace-conventions/SKILL.md +91 -0
  274. package/corpus/core/src/templates/workspace-core/.agents/skills/writing-agent-instructions/SKILL.md +60 -0
  275. package/corpus/core/src/templates/workspace-core/AGENTS.md +62 -124
  276. package/corpus/core/src/templates/workspace-root/AGENTS.md +6 -1
  277. package/corpus/core/src/triggers/dispatcher.ts +28 -17
  278. package/corpus/core/src/vite/client.ts +20 -8
  279. package/corpus/templates/analytics/.agents/skills/actions/SKILL.md +19 -1
  280. package/corpus/templates/analytics/.agents/skills/dashboard-management/SKILL.md +41 -1
  281. package/corpus/templates/analytics/.agents/skills/dashboard-ops/SKILL.md +50 -22
  282. package/corpus/templates/analytics/.agents/skills/data-querying/SKILL.md +1 -1
  283. package/corpus/templates/analytics/.agents/skills/data-querying/references/inline-chart-embeds.md +8 -0
  284. package/corpus/templates/analytics/.agents/skills/frontend-design/SKILL.md +20 -6
  285. package/corpus/templates/analytics/.agents/skills/security/SKILL.md +2 -0
  286. package/corpus/templates/analytics/.agents/skills/self-modifying-code/SKILL.md +4 -3
  287. package/corpus/templates/analytics/.agents/skills/shadcn-ui/SKILL.md +7 -3
  288. package/corpus/templates/analytics/.agents/skills/sharing/SKILL.md +228 -0
  289. package/corpus/templates/analytics/.builder/skills/charts/SKILL.md +2 -2
  290. package/corpus/templates/analytics/actions/delete-dashboard-view.ts +24 -0
  291. package/corpus/templates/analytics/actions/delete-user-pref.ts +22 -0
  292. package/corpus/templates/analytics/actions/generate-chart.ts +8 -245
  293. package/corpus/templates/analytics/actions/get-theme.ts +27 -0
  294. package/corpus/templates/analytics/actions/get-user-pref.ts +22 -0
  295. package/corpus/templates/analytics/actions/list-dashboard-views.ts +25 -0
  296. package/corpus/templates/analytics/actions/save-dashboard-view.ts +33 -0
  297. package/corpus/templates/analytics/actions/set-theme.ts +22 -0
  298. package/corpus/templates/analytics/actions/set-user-pref.ts +24 -0
  299. package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +134 -27
  300. package/corpus/templates/analytics/app/components/layout/CommandPalette.tsx +2 -9
  301. package/corpus/templates/analytics/app/components/layout/Layout.tsx +0 -17
  302. package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +10 -5
  303. package/corpus/templates/analytics/app/hooks/use-dashboard-views.ts +22 -52
  304. package/corpus/templates/analytics/app/hooks/use-user-pref.ts +21 -31
  305. package/corpus/templates/analytics/app/i18n-data.ts +10 -0
  306. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/PanelEditorDialog.tsx +2 -1
  307. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/dual-axis.ts +73 -0
  308. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +8 -27
  309. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/report-panel-window.ts +0 -57
  310. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/types.ts +8 -0
  311. package/corpus/templates/analytics/app/root.tsx +0 -28
  312. package/corpus/templates/analytics/changelog/2026-07-26-error-issues-now-group-by-message-as-well-as-stack-frame-and.md +6 -0
  313. package/corpus/templates/analytics/changelog/2026-07-26-line-area-and-bar-dashboard-panels-can-plot-series-on-a-seco.md +6 -0
  314. package/corpus/templates/analytics/changelog/2026-07-26-scheduled-dashboard-email-reports-now-arrive-complete-and-re.md +6 -0
  315. package/corpus/templates/analytics/changelog/2026-07-26-session-replays-now-detect-rage-clicks-so-the-rage-click-fil.md +6 -0
  316. package/corpus/templates/analytics/docs/error-capture.md +8 -4
  317. package/corpus/templates/analytics/package.json +1 -2
  318. package/corpus/templates/analytics/scripts/preview-dashboard-report.ts +221 -0
  319. package/corpus/templates/analytics/server/jobs/dashboard-report.ts +39 -32
  320. package/corpus/templates/analytics/server/lib/dashboard-report-render.ts +1168 -0
  321. package/corpus/templates/analytics/server/lib/dashboard-report.ts +111 -1358
  322. package/corpus/templates/analytics/server/lib/error-capture.ts +32 -15
  323. package/corpus/templates/analytics/server/lib/report-chart-svg.ts +901 -0
  324. package/corpus/templates/analytics/server/lib/session-replay.ts +77 -1
  325. package/corpus/templates/analytics/shared/dashboard-report-timeouts.ts +3 -4
  326. package/corpus/templates/assets/.agents/skills/a2a-assets/SKILL.md +28 -0
  327. package/corpus/templates/assets/.agents/skills/actions/SKILL.md +19 -1
  328. package/corpus/templates/assets/.agents/skills/assets-navigation/SKILL.md +46 -0
  329. package/corpus/templates/assets/.agents/skills/creative-context/SKILL.md +12 -0
  330. package/corpus/templates/assets/.agents/skills/frontend-design/SKILL.md +20 -6
  331. package/corpus/templates/assets/.agents/skills/image-generation/SKILL.md +28 -0
  332. package/corpus/templates/assets/.agents/skills/library-management/SKILL.md +9 -0
  333. package/corpus/templates/assets/.agents/skills/logo-composite/SKILL.md +11 -0
  334. package/corpus/templates/assets/.agents/skills/security/SKILL.md +2 -0
  335. package/corpus/templates/assets/.agents/skills/self-modifying-code/SKILL.md +4 -3
  336. package/corpus/templates/assets/.agents/skills/shadcn-ui/SKILL.md +7 -3
  337. package/corpus/templates/assets/.agents/skills/sharing/SKILL.md +228 -0
  338. package/corpus/templates/assets/AGENTS.md +58 -125
  339. package/corpus/templates/assets/actions/variant-slots.ts +8 -4
  340. package/corpus/templates/assets/app/entry.client.tsx +3 -0
  341. package/corpus/templates/assets/package.json +0 -2
  342. package/corpus/templates/brain/.agents/skills/actions/SKILL.md +19 -1
  343. package/corpus/templates/brain/.agents/skills/adding-a-feature/SKILL.md +2 -0
  344. package/corpus/templates/brain/.agents/skills/brain/SKILL.md +78 -4
  345. package/corpus/templates/brain/.agents/skills/frontend-design/SKILL.md +20 -6
  346. package/corpus/templates/brain/.agents/skills/ingestion-and-connectors/SKILL.md +15 -3
  347. package/corpus/templates/brain/.agents/skills/security/SKILL.md +2 -0
  348. package/corpus/templates/brain/.agents/skills/self-modifying-code/SKILL.md +4 -3
  349. package/corpus/templates/brain/.agents/skills/shadcn-ui/SKILL.md +7 -3
  350. package/corpus/templates/brain/.agents/skills/sharing/SKILL.md +228 -0
  351. package/corpus/templates/brain/.agents/skills/storing-data/SKILL.md +178 -0
  352. package/corpus/templates/brain/AGENTS.md +73 -119
  353. package/corpus/templates/brain/app/entry.client.tsx +3 -0
  354. package/corpus/templates/calendar/.agents/skills/actions/SKILL.md +19 -1
  355. package/corpus/templates/calendar/.agents/skills/event-management/SKILL.md +56 -3
  356. package/corpus/templates/calendar/.agents/skills/frontend-design/SKILL.md +20 -6
  357. package/corpus/templates/calendar/.agents/skills/security/SKILL.md +2 -0
  358. package/corpus/templates/calendar/.agents/skills/self-modifying-code/SKILL.md +4 -3
  359. package/corpus/templates/calendar/.agents/skills/shadcn-ui/SKILL.md +7 -3
  360. package/corpus/templates/calendar/.agents/skills/sharing/SKILL.md +228 -0
  361. package/corpus/templates/calendar/AGENTS.md +22 -45
  362. package/corpus/templates/calendar/app/entry.client.tsx +3 -0
  363. package/corpus/templates/calendar/server/handlers/events.ts +0 -364
  364. package/corpus/templates/chat/.agents/skills/actions/SKILL.md +19 -1
  365. package/corpus/templates/chat/.agents/skills/adding-a-feature/SKILL.md +2 -0
  366. package/corpus/templates/chat/.agents/skills/frontend-design/SKILL.md +20 -6
  367. package/corpus/templates/chat/.agents/skills/security/SKILL.md +2 -0
  368. package/corpus/templates/chat/.agents/skills/self-modifying-code/SKILL.md +4 -3
  369. package/corpus/templates/chat/.agents/skills/shadcn-ui/SKILL.md +7 -3
  370. package/corpus/templates/chat/.agents/skills/sharing/SKILL.md +228 -0
  371. package/corpus/templates/chat/.agents/skills/storing-data/SKILL.md +178 -0
  372. package/corpus/templates/chat/AGENTS.md +8 -0
  373. package/corpus/templates/chat/app/entry.client.tsx +3 -0
  374. package/corpus/templates/clips/.agents/skills/actions/SKILL.md +19 -1
  375. package/corpus/templates/clips/.agents/skills/ai-video-tools/SKILL.md +42 -0
  376. package/corpus/templates/clips/.agents/skills/brain-export/SKILL.md +59 -0
  377. package/corpus/templates/clips/.agents/skills/bug-reports/SKILL.md +37 -0
  378. package/corpus/templates/clips/.agents/skills/crm-call-evidence/SKILL.md +41 -0
  379. package/corpus/templates/clips/.agents/skills/dictate/SKILL.md +4 -0
  380. package/corpus/templates/clips/.agents/skills/external-integrations/SKILL.md +45 -0
  381. package/corpus/templates/clips/.agents/skills/frontend-design/SKILL.md +20 -6
  382. package/corpus/templates/clips/.agents/skills/meetings/SKILL.md +9 -0
  383. package/corpus/templates/clips/.agents/skills/recording/SKILL.md +45 -0
  384. package/corpus/templates/clips/.agents/skills/screen-memory/SKILL.md +43 -0
  385. package/corpus/templates/clips/.agents/skills/security/SKILL.md +2 -0
  386. package/corpus/templates/clips/.agents/skills/self-modifying-code/SKILL.md +4 -3
  387. package/corpus/templates/clips/.agents/skills/shadcn-ui/SKILL.md +7 -3
  388. package/corpus/templates/clips/.agents/skills/video-sharing/SKILL.md +38 -1
  389. package/corpus/templates/clips/AGENTS.md +82 -224
  390. package/corpus/templates/clips/actions/create-recording.ts +4 -0
  391. package/corpus/templates/clips/app/components/player/sign-in-prompt-dialog.tsx +6 -10
  392. package/corpus/templates/clips/app/routes/invite.$token.tsx +6 -5
  393. package/corpus/templates/clips/app/routes/r.$recordingId.tsx +4 -5
  394. package/corpus/templates/clips/app/routes/share.$shareId.tsx +8 -8
  395. package/corpus/templates/clips/changelog/2026-07-26-long-agent-chat-turns-now-finish-instead-of-stopping-partway.md +6 -0
  396. package/corpus/templates/clips/changelog/2026-07-26-recordings-no-longer-get-stuck-on-uploading-uploads-now-hold.md +6 -0
  397. package/corpus/templates/clips/server/db/schema.ts +3 -0
  398. package/corpus/templates/clips/server/jobs/brain-export.ts +4 -0
  399. package/corpus/templates/clips/server/lib/recording-upload-state.ts +0 -52
  400. package/corpus/templates/clips/server/lib/upload-lease.ts +241 -0
  401. package/corpus/templates/clips/server/plugins/agent-chat.ts +4 -0
  402. package/corpus/templates/clips/server/plugins/db.ts +18 -347
  403. package/corpus/templates/clips/server/routes/api/clips/brain-export/run.post.ts +7 -1
  404. package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/chunk.post.ts +123 -126
  405. package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/reset-chunks.post.ts +4 -0
  406. package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/resume.get.ts +118 -0
  407. package/corpus/templates/clips/server/routes/api/uploads/reap.post.ts +69 -0
  408. package/corpus/templates/content/.agents/skills/actions/SKILL.md +19 -1
  409. package/corpus/templates/content/.agents/skills/content/SKILL.md +4 -0
  410. package/corpus/templates/content/.agents/skills/creative-context/SKILL.md +8 -0
  411. package/corpus/templates/content/.agents/skills/document-editing/SKILL.md +55 -0
  412. package/corpus/templates/content/.agents/skills/frontend-design/SKILL.md +20 -6
  413. package/corpus/templates/content/.agents/skills/notion-integration/SKILL.md +12 -1
  414. package/corpus/templates/content/.agents/skills/security/SKILL.md +2 -0
  415. package/corpus/templates/content/.agents/skills/self-modifying-code/SKILL.md +4 -3
  416. package/corpus/templates/content/.agents/skills/shadcn-ui/SKILL.md +7 -3
  417. package/corpus/templates/content/.agents/skills/sharing/SKILL.md +228 -0
  418. package/corpus/templates/content/AGENTS.md +63 -131
  419. package/corpus/templates/content/app/routes/_app.tsx +4 -4
  420. package/corpus/templates/content/server/routes/api/notion/callback.get.ts +6 -24
  421. package/corpus/templates/design/.agents/skills/actions/SKILL.md +19 -1
  422. package/corpus/templates/design/.agents/skills/design-generation/SKILL.md +16 -0
  423. package/corpus/templates/design/.agents/skills/design-systems/SKILL.md +15 -0
  424. package/corpus/templates/design/.agents/skills/frontend-design/SKILL.md +20 -6
  425. package/corpus/templates/design/.agents/skills/full-app-build/SKILL.md +12 -0
  426. package/corpus/templates/design/.agents/skills/security/SKILL.md +2 -0
  427. package/corpus/templates/design/.agents/skills/self-modifying-code/SKILL.md +4 -3
  428. package/corpus/templates/design/.agents/skills/shadcn-ui/SKILL.md +7 -3
  429. package/corpus/templates/design/.agents/skills/sharing/SKILL.md +228 -0
  430. package/corpus/templates/design/.agents/skills/storing-data/SKILL.md +178 -0
  431. package/corpus/templates/design/.agents/skills/visual-edit/SKILL.md +201 -102
  432. package/corpus/templates/design/AGENTS.md +58 -71
  433. package/corpus/templates/design/actions/open-visual-edit.ts +111 -2
  434. package/corpus/templates/design/app/components/design/AddLocalhostScreenDialog.tsx +236 -0
  435. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +1 -1
  436. package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +2 -2
  437. package/corpus/templates/design/app/entry.client.tsx +3 -0
  438. package/corpus/templates/design/app/i18n-data.ts +180 -0
  439. package/corpus/templates/design/app/pages/Present.tsx +6 -9
  440. package/corpus/templates/design/app/pages/VisualEdit.tsx +4 -7
  441. package/corpus/templates/design/app/pages/design-editor/design-data-geometry-utils.ts +20 -0
  442. package/corpus/templates/dispatch/.agents/skills/actions/SKILL.md +19 -1
  443. package/corpus/templates/dispatch/.agents/skills/frontend-design/SKILL.md +20 -6
  444. package/corpus/templates/dispatch/.agents/skills/security/SKILL.md +2 -0
  445. package/corpus/templates/dispatch/.agents/skills/self-modifying-code/SKILL.md +4 -3
  446. package/corpus/templates/dispatch/.agents/skills/shadcn-ui/SKILL.md +7 -3
  447. package/corpus/templates/dispatch/.agents/skills/sharing/SKILL.md +228 -0
  448. package/corpus/templates/dispatch/.agents/skills/storing-data/SKILL.md +178 -0
  449. package/corpus/templates/dispatch/app/entry.client.tsx +3 -0
  450. package/corpus/templates/dispatch/server/plugins/identity-sso.ts +27 -16
  451. package/corpus/templates/forms/.agents/skills/actions/SKILL.md +19 -1
  452. package/corpus/templates/forms/.agents/skills/frontend-design/SKILL.md +20 -6
  453. package/corpus/templates/forms/.agents/skills/security/SKILL.md +2 -0
  454. package/corpus/templates/forms/.agents/skills/self-modifying-code/SKILL.md +4 -3
  455. package/corpus/templates/forms/.agents/skills/shadcn-ui/SKILL.md +7 -3
  456. package/corpus/templates/forms/.agents/skills/sharing/SKILL.md +228 -0
  457. package/corpus/templates/forms/DEVELOPING.md +1 -1
  458. package/corpus/templates/forms/app/entry.client.tsx +3 -0
  459. package/corpus/templates/forms/app/pages/FormsListPage.tsx +3 -5
  460. package/corpus/templates/forms/app/routes/_app.tsx +4 -4
  461. package/corpus/templates/macros/.agents/skills/frontend-design/SKILL.md +20 -6
  462. package/corpus/templates/macros/.agents/skills/security/SKILL.md +2 -0
  463. package/corpus/templates/macros/.agents/skills/shadcn-ui/SKILL.md +7 -3
  464. package/corpus/templates/macros/.agents/skills/sharing/SKILL.md +228 -0
  465. package/corpus/templates/macros/.agents/skills/storing-data/SKILL.md +178 -0
  466. package/corpus/templates/macros/app/entry.client.tsx +3 -0
  467. package/corpus/templates/mail/.agents/skills/actions/SKILL.md +19 -1
  468. package/corpus/templates/mail/.agents/skills/contacts-and-crm/SKILL.md +10 -0
  469. package/corpus/templates/mail/.agents/skills/draft-queue/SKILL.md +3 -0
  470. package/corpus/templates/mail/.agents/skills/email-drafts/SKILL.md +26 -2
  471. package/corpus/templates/mail/.agents/skills/frontend-design/SKILL.md +20 -6
  472. package/corpus/templates/mail/.agents/skills/inbox-automations/SKILL.md +37 -0
  473. package/corpus/templates/mail/.agents/skills/inbox-reads-and-triage/SKILL.md +58 -0
  474. package/corpus/templates/mail/.agents/skills/mail-backends/SKILL.md +33 -0
  475. package/corpus/templates/mail/.agents/skills/provider-api-scans/SKILL.md +39 -0
  476. package/corpus/templates/mail/.agents/skills/security/SKILL.md +2 -0
  477. package/corpus/templates/mail/.agents/skills/self-modifying-code/SKILL.md +4 -3
  478. package/corpus/templates/mail/.agents/skills/shadcn-ui/SKILL.md +7 -3
  479. package/corpus/templates/mail/.agents/skills/sharing/SKILL.md +228 -0
  480. package/corpus/templates/mail/AGENTS.md +74 -143
  481. package/corpus/templates/mail/actions/create-alias.ts +36 -0
  482. package/corpus/templates/mail/actions/create-automation.ts +28 -0
  483. package/corpus/templates/mail/actions/create-scheduled-job.ts +45 -0
  484. package/corpus/templates/mail/actions/delete-alias.ts +26 -0
  485. package/corpus/templates/mail/actions/delete-automation.ts +21 -0
  486. package/corpus/templates/mail/actions/get-automation-settings.ts +32 -0
  487. package/corpus/templates/mail/actions/get-mail-preferences.ts +18 -0
  488. package/corpus/templates/mail/actions/list-aliases.ts +17 -0
  489. package/corpus/templates/mail/actions/list-automations.ts +18 -0
  490. package/corpus/templates/mail/actions/list-scheduled-jobs.ts +18 -0
  491. package/corpus/templates/mail/actions/update-alias.ts +37 -0
  492. package/corpus/templates/mail/actions/update-automation-settings.ts +33 -0
  493. package/corpus/templates/mail/actions/update-automation.ts +33 -0
  494. package/corpus/templates/mail/actions/update-mail-preferences.ts +68 -0
  495. package/corpus/templates/mail/actions/update-scheduled-job.ts +25 -0
  496. package/corpus/templates/mail/app/entry.client.tsx +3 -0
  497. package/corpus/templates/mail/app/hooks/use-aliases.ts +6 -36
  498. package/corpus/templates/mail/app/hooks/use-automations.ts +9 -16
  499. package/corpus/templates/mail/app/hooks/use-emails.ts +6 -5
  500. package/corpus/templates/mail/app/hooks/use-scheduled-jobs.ts +12 -15
  501. package/corpus/templates/mail/app/pages/SettingsPage.tsx +15 -9
  502. package/corpus/templates/mail/server/handlers/automations.ts +5 -142
  503. package/corpus/templates/mail/server/handlers/emails.ts +1 -56
  504. package/corpus/templates/mail/server/handlers/scheduled-jobs.ts +0 -134
  505. package/corpus/templates/mail/server/lib/aliases.ts +18 -0
  506. package/corpus/templates/mail/server/lib/automations.ts +104 -0
  507. package/corpus/templates/mail/server/lib/jobs.ts +34 -0
  508. package/corpus/templates/mail/server/lib/mail-settings.ts +43 -0
  509. package/corpus/templates/mail/shared/automation-schema.ts +10 -0
  510. package/corpus/templates/plan/.agents/skills/actions/SKILL.md +19 -1
  511. package/corpus/templates/plan/.agents/skills/adding-a-feature/SKILL.md +2 -0
  512. package/corpus/templates/plan/.agents/skills/frontend-design/SKILL.md +20 -6
  513. package/corpus/templates/plan/.agents/skills/plan-authoring-flow/SKILL.md +98 -0
  514. package/corpus/templates/plan/.agents/skills/plan-browser-editing/SKILL.md +42 -0
  515. package/corpus/templates/plan/.agents/skills/plan-comments-and-feedback/SKILL.md +68 -0
  516. package/corpus/templates/plan/.agents/skills/plan-events/SKILL.md +22 -0
  517. package/corpus/templates/plan/.agents/skills/plan-hosted-writes/SKILL.md +42 -0
  518. package/corpus/templates/plan/.agents/skills/plan-local-codebase-chat/SKILL.md +38 -0
  519. package/corpus/templates/plan/.agents/skills/plan-review-recaps/SKILL.md +25 -0
  520. package/corpus/templates/plan/.agents/skills/plan-source-sync/SKILL.md +68 -0
  521. package/corpus/templates/plan/.agents/skills/plan-version-history/SKILL.md +25 -0
  522. package/corpus/templates/plan/.agents/skills/security/SKILL.md +2 -0
  523. package/corpus/templates/plan/.agents/skills/self-modifying-code/SKILL.md +4 -3
  524. package/corpus/templates/plan/.agents/skills/shadcn-ui/SKILL.md +7 -3
  525. package/corpus/templates/plan/.agents/skills/sharing/SKILL.md +228 -0
  526. package/corpus/templates/plan/.agents/skills/storing-data/SKILL.md +178 -0
  527. package/corpus/templates/plan/AGENTS.md +64 -296
  528. package/corpus/templates/plan/app/components/layout/Sidebar.tsx +9 -8
  529. package/corpus/templates/plan/app/pages/PlansPage.tsx +5 -10
  530. package/corpus/templates/slides/.agents/skills/actions/SKILL.md +19 -1
  531. package/corpus/templates/slides/.agents/skills/deck-management/SKILL.md +7 -7
  532. package/corpus/templates/slides/.agents/skills/frontend-design/SKILL.md +20 -6
  533. package/corpus/templates/slides/.agents/skills/security/SKILL.md +2 -0
  534. package/corpus/templates/slides/.agents/skills/self-modifying-code/SKILL.md +4 -3
  535. package/corpus/templates/slides/.agents/skills/shadcn-ui/SKILL.md +7 -3
  536. package/corpus/templates/slides/.agents/skills/sharing/SKILL.md +228 -0
  537. package/corpus/templates/slides/.agents/skills/slide-editing/SKILL.md +3 -2
  538. package/corpus/templates/slides/.agents/skills/storing-data/SKILL.md +178 -0
  539. package/corpus/templates/slides/DEVELOPING.md +3 -3
  540. package/corpus/templates/slides/actions/_deck-write.ts +52 -0
  541. package/corpus/templates/slides/actions/add-deck.ts +73 -0
  542. package/corpus/templates/slides/actions/delete-deck.ts +60 -0
  543. package/corpus/templates/slides/actions/get-deck.ts +3 -1
  544. package/corpus/templates/slides/actions/save-deck.ts +144 -0
  545. package/corpus/templates/slides/app/components/editor/SlideEditor.tsx +27 -20
  546. package/corpus/templates/slides/app/context/DeckContext.tsx +173 -100
  547. package/corpus/templates/slides/app/pages/Index.tsx +3 -6
  548. package/corpus/templates/slides/app/routes/slide.tsx +16 -12
  549. package/corpus/templates/slides/changelog/2026-07-26-a-newly-created-deck-now-appears-in-the-deck-list-right-away.md +6 -0
  550. package/corpus/templates/slides/server/handlers/decks.ts +2 -378
  551. package/corpus/templates/tasks/.agents/skills/action-reference/SKILL.md +47 -0
  552. package/corpus/templates/tasks/.agents/skills/actions/SKILL.md +19 -1
  553. package/corpus/templates/tasks/.agents/skills/adding-a-feature/SKILL.md +2 -0
  554. package/corpus/templates/tasks/.agents/skills/change-summary/SKILL.md +19 -1
  555. package/corpus/templates/tasks/.agents/skills/custom-fields/SKILL.md +63 -0
  556. package/corpus/templates/tasks/.agents/skills/frontend-design/SKILL.md +20 -6
  557. package/corpus/templates/tasks/.agents/skills/security/SKILL.md +2 -0
  558. package/corpus/templates/tasks/.agents/skills/self-modifying-code/SKILL.md +4 -3
  559. package/corpus/templates/tasks/.agents/skills/shadcn-ui/SKILL.md +7 -3
  560. package/corpus/templates/tasks/.agents/skills/sharing/SKILL.md +228 -0
  561. package/corpus/templates/tasks/.agents/skills/store-conventions/SKILL.md +45 -0
  562. package/corpus/templates/tasks/.agents/skills/storing-data/SKILL.md +178 -0
  563. package/corpus/templates/tasks/.agents/skills/task-inbox-workflow/SKILL.md +66 -0
  564. package/corpus/templates/tasks/AGENTS.md +48 -113
  565. package/corpus/templates/tasks/app/entry.client.tsx +3 -0
  566. package/corpus/toolkit/CHANGELOG.md +12 -0
  567. package/corpus/toolkit/package.json +1 -1
  568. package/corpus/toolkit/src/composer/PromptComposer.tsx +23 -20
  569. package/dist/a2a/client.d.ts +3 -1
  570. package/dist/a2a/client.d.ts.map +1 -1
  571. package/dist/a2a/client.js +4 -2
  572. package/dist/a2a/client.js.map +1 -1
  573. package/dist/agent/action-warnings.d.ts +27 -0
  574. package/dist/agent/action-warnings.d.ts.map +1 -0
  575. package/dist/agent/action-warnings.js +73 -0
  576. package/dist/agent/action-warnings.js.map +1 -0
  577. package/dist/agent/durable-background.d.ts +8 -0
  578. package/dist/agent/durable-background.d.ts.map +1 -1
  579. package/dist/agent/durable-background.js +37 -5
  580. package/dist/agent/durable-background.js.map +1 -1
  581. package/dist/agent/engine/ai-sdk-engine.d.ts.map +1 -1
  582. package/dist/agent/engine/ai-sdk-engine.js +47 -6
  583. package/dist/agent/engine/ai-sdk-engine.js.map +1 -1
  584. package/dist/agent/engine/anthropic-engine.d.ts.map +1 -1
  585. package/dist/agent/engine/anthropic-engine.js +41 -9
  586. package/dist/agent/engine/anthropic-engine.js.map +1 -1
  587. package/dist/agent/engine/builder-engine.d.ts.map +1 -1
  588. package/dist/agent/engine/builder-engine.js +46 -19
  589. package/dist/agent/engine/builder-engine.js.map +1 -1
  590. package/dist/agent/engine/continuation-dispatch-retry.d.ts.map +1 -1
  591. package/dist/agent/engine/continuation-dispatch-retry.js +11 -9
  592. package/dist/agent/engine/continuation-dispatch-retry.js.map +1 -1
  593. package/dist/agent/engine/credential-errors.d.ts +6 -0
  594. package/dist/agent/engine/credential-errors.d.ts.map +1 -1
  595. package/dist/agent/engine/credential-errors.js +10 -0
  596. package/dist/agent/engine/credential-errors.js.map +1 -1
  597. package/dist/agent/engine/error-detail.d.ts +2 -0
  598. package/dist/agent/engine/error-detail.d.ts.map +1 -0
  599. package/dist/agent/engine/error-detail.js +37 -0
  600. package/dist/agent/engine/error-detail.js.map +1 -0
  601. package/dist/agent/engine/prompt-cache.d.ts +34 -0
  602. package/dist/agent/engine/prompt-cache.d.ts.map +1 -0
  603. package/dist/agent/engine/prompt-cache.js +39 -0
  604. package/dist/agent/engine/prompt-cache.js.map +1 -0
  605. package/dist/agent/engine/registry.d.ts.map +1 -1
  606. package/dist/agent/engine/registry.js +23 -33
  607. package/dist/agent/engine/registry.js.map +1 -1
  608. package/dist/agent/engine/tool-call-journal-seed.d.ts +1 -1
  609. package/dist/agent/engine/tool-call-journal-seed.d.ts.map +1 -1
  610. package/dist/agent/engine/tool-call-journal-seed.js +2 -2
  611. package/dist/agent/engine/tool-call-journal-seed.js.map +1 -1
  612. package/dist/agent/engine/translate-anthropic.d.ts +28 -0
  613. package/dist/agent/engine/translate-anthropic.d.ts.map +1 -1
  614. package/dist/agent/engine/translate-anthropic.js +75 -0
  615. package/dist/agent/engine/translate-anthropic.js.map +1 -1
  616. package/dist/agent/loop-settings.d.ts +35 -2
  617. package/dist/agent/loop-settings.d.ts.map +1 -1
  618. package/dist/agent/loop-settings.js +71 -8
  619. package/dist/agent/loop-settings.js.map +1 -1
  620. package/dist/agent/production-agent.d.ts +105 -20
  621. package/dist/agent/production-agent.d.ts.map +1 -1
  622. package/dist/agent/production-agent.js +516 -123
  623. package/dist/agent/production-agent.js.map +1 -1
  624. package/dist/agent/run-loop-with-resume.d.ts.map +1 -1
  625. package/dist/agent/run-loop-with-resume.js +24 -2
  626. package/dist/agent/run-loop-with-resume.js.map +1 -1
  627. package/dist/agent/run-manager.d.ts +52 -9
  628. package/dist/agent/run-manager.d.ts.map +1 -1
  629. package/dist/agent/run-manager.js +191 -36
  630. package/dist/agent/run-manager.js.map +1 -1
  631. package/dist/agent/run-store.d.ts +87 -14
  632. package/dist/agent/run-store.d.ts.map +1 -1
  633. package/dist/agent/run-store.js +331 -59
  634. package/dist/agent/run-store.js.map +1 -1
  635. package/dist/agent/thread-data-builder.d.ts.map +1 -1
  636. package/dist/agent/thread-data-builder.js +6 -1
  637. package/dist/agent/thread-data-builder.js.map +1 -1
  638. package/dist/agent/types.d.ts +18 -6
  639. package/dist/agent/types.d.ts.map +1 -1
  640. package/dist/agent/types.js +9 -5
  641. package/dist/agent/types.js.map +1 -1
  642. package/dist/application-state/script-helpers.d.ts.map +1 -1
  643. package/dist/application-state/script-helpers.js +2 -2
  644. package/dist/application-state/script-helpers.js.map +1 -1
  645. package/dist/cli/agents.d.ts +2 -0
  646. package/dist/cli/agents.d.ts.map +1 -1
  647. package/dist/cli/agents.js +48 -1
  648. package/dist/cli/agents.js.map +1 -1
  649. package/dist/cli/app-skill.js +1 -1
  650. package/dist/cli/app-skill.js.map +1 -1
  651. package/dist/cli/code-agent-executor.d.ts.map +1 -1
  652. package/dist/cli/code-agent-executor.js +3 -3
  653. package/dist/cli/code-agent-executor.js.map +1 -1
  654. package/dist/cli/design-connect.d.ts.map +1 -1
  655. package/dist/cli/design-connect.js +73 -8
  656. package/dist/cli/design-connect.js.map +1 -1
  657. package/dist/cli/skills-content/design-visual-edit-skill.d.ts +1 -1
  658. package/dist/cli/skills-content/design-visual-edit-skill.d.ts.map +1 -1
  659. package/dist/cli/skills-content/design-visual-edit-skill.js +169 -24
  660. package/dist/cli/skills-content/design-visual-edit-skill.js.map +1 -1
  661. package/dist/client/AssistantChat.d.ts.map +1 -1
  662. package/dist/client/AssistantChat.js +135 -125
  663. package/dist/client/AssistantChat.js.map +1 -1
  664. package/dist/client/agent-chat-adapter.d.ts +17 -0
  665. package/dist/client/agent-chat-adapter.d.ts.map +1 -1
  666. package/dist/client/agent-chat-adapter.js +141 -31
  667. package/dist/client/agent-chat-adapter.js.map +1 -1
  668. package/dist/client/chat/message-components.d.ts +9 -1
  669. package/dist/client/chat/message-components.d.ts.map +1 -1
  670. package/dist/client/chat/message-components.js +12 -1
  671. package/dist/client/chat/message-components.js.map +1 -1
  672. package/dist/client/embed-auth.d.ts.map +1 -1
  673. package/dist/client/embed-auth.js +3 -1
  674. package/dist/client/embed-auth.js.map +1 -1
  675. package/dist/client/integrations/IntegrationCard.d.ts.map +1 -1
  676. package/dist/client/integrations/IntegrationCard.js +9 -4
  677. package/dist/client/integrations/IntegrationCard.js.map +1 -1
  678. package/dist/client/integrations/IntegrationsPanel.d.ts.map +1 -1
  679. package/dist/client/integrations/IntegrationsPanel.js +13 -7
  680. package/dist/client/integrations/IntegrationsPanel.js.map +1 -1
  681. package/dist/client/integrations/webhook-url.d.ts +7 -0
  682. package/dist/client/integrations/webhook-url.d.ts.map +1 -0
  683. package/dist/client/integrations/webhook-url.js +32 -0
  684. package/dist/client/integrations/webhook-url.js.map +1 -0
  685. package/dist/client/org/OrgSwitcher.d.ts.map +1 -1
  686. package/dist/client/org/OrgSwitcher.js +13 -11
  687. package/dist/client/org/OrgSwitcher.js.map +1 -1
  688. package/dist/client/org/RequireActiveOrg.d.ts.map +1 -1
  689. package/dist/client/org/RequireActiveOrg.js +2 -2
  690. package/dist/client/org/RequireActiveOrg.js.map +1 -1
  691. package/dist/client/org/TeamPage.d.ts.map +1 -1
  692. package/dist/client/org/TeamPage.js +52 -13
  693. package/dist/client/org/TeamPage.js.map +1 -1
  694. package/dist/client/org/hooks.d.ts +9 -0
  695. package/dist/client/org/hooks.d.ts.map +1 -1
  696. package/dist/client/org/hooks.js +24 -0
  697. package/dist/client/org/hooks.js.map +1 -1
  698. package/dist/client/org/index.d.ts +1 -1
  699. package/dist/client/org/index.d.ts.map +1 -1
  700. package/dist/client/org/index.js +1 -1
  701. package/dist/client/org/index.js.map +1 -1
  702. package/dist/client/require-session.d.ts +12 -17
  703. package/dist/client/require-session.d.ts.map +1 -1
  704. package/dist/client/require-session.js +36 -23
  705. package/dist/client/require-session.js.map +1 -1
  706. package/dist/client/session-replay.js +1 -1
  707. package/dist/client/session-replay.js.map +1 -1
  708. package/dist/client/settings/DemoModeSection.d.ts +0 -1
  709. package/dist/client/settings/DemoModeSection.d.ts.map +1 -1
  710. package/dist/client/settings/DemoModeSection.js +0 -4
  711. package/dist/client/settings/DemoModeSection.js.map +1 -1
  712. package/dist/client/settings/SecretsSection.d.ts.map +1 -1
  713. package/dist/client/settings/SecretsSection.js +12 -8
  714. package/dist/client/settings/SecretsSection.js.map +1 -1
  715. package/dist/client/settings/VoiceTranscriptionSection.d.ts +0 -1
  716. package/dist/client/settings/VoiceTranscriptionSection.d.ts.map +1 -1
  717. package/dist/client/settings/VoiceTranscriptionSection.js +1 -4
  718. package/dist/client/settings/VoiceTranscriptionSection.js.map +1 -1
  719. package/dist/client/sse-event-processor.d.ts +33 -1
  720. package/dist/client/sse-event-processor.d.ts.map +1 -1
  721. package/dist/client/sse-event-processor.js +83 -8
  722. package/dist/client/sse-event-processor.js.map +1 -1
  723. package/dist/client/use-action.d.ts.map +1 -1
  724. package/dist/client/use-action.js +23 -14
  725. package/dist/client/use-action.js.map +1 -1
  726. package/dist/client/use-agent-engine-configured.d.ts +9 -3
  727. package/dist/client/use-agent-engine-configured.d.ts.map +1 -1
  728. package/dist/client/use-agent-engine-configured.js +30 -3
  729. package/dist/client/use-agent-engine-configured.js.map +1 -1
  730. package/dist/client/use-db-sync.d.ts +3 -0
  731. package/dist/client/use-db-sync.d.ts.map +1 -1
  732. package/dist/client/use-db-sync.js +18 -1
  733. package/dist/client/use-db-sync.js.map +1 -1
  734. package/dist/collab/awareness.d.ts +2 -2
  735. package/dist/collab/awareness.d.ts.map +1 -1
  736. package/dist/collab/routes.d.ts +1 -1
  737. package/dist/credentials/index.d.ts +29 -1
  738. package/dist/credentials/index.d.ts.map +1 -1
  739. package/dist/credentials/index.js +111 -2
  740. package/dist/credentials/index.js.map +1 -1
  741. package/dist/deploy/build.d.ts +14 -3
  742. package/dist/deploy/build.d.ts.map +1 -1
  743. package/dist/deploy/build.js +81 -24
  744. package/dist/deploy/build.js.map +1 -1
  745. package/dist/deploy/workspace-deploy.d.ts +15 -0
  746. package/dist/deploy/workspace-deploy.d.ts.map +1 -1
  747. package/dist/deploy/workspace-deploy.js +19 -18
  748. package/dist/deploy/workspace-deploy.js.map +1 -1
  749. package/dist/file-upload/actions/upload-image.d.ts +2 -2
  750. package/dist/guards/no-localhost-fallback.d.ts +7 -0
  751. package/dist/guards/no-localhost-fallback.d.ts.map +1 -1
  752. package/dist/guards/no-localhost-fallback.js +75 -16
  753. package/dist/guards/no-localhost-fallback.js.map +1 -1
  754. package/dist/integrations/google-docs-poller.d.ts.map +1 -1
  755. package/dist/integrations/google-docs-poller.js +8 -3
  756. package/dist/integrations/google-docs-poller.js.map +1 -1
  757. package/dist/integrations/webhook-handler.d.ts.map +1 -1
  758. package/dist/integrations/webhook-handler.js +22 -4
  759. package/dist/integrations/webhook-handler.js.map +1 -1
  760. package/dist/jobs/scheduler.d.ts +17 -0
  761. package/dist/jobs/scheduler.d.ts.map +1 -1
  762. package/dist/jobs/scheduler.js +60 -33
  763. package/dist/jobs/scheduler.js.map +1 -1
  764. package/dist/localization/default-messages.d.ts +17 -1
  765. package/dist/localization/default-messages.d.ts.map +1 -1
  766. package/dist/localization/default-messages.js +17 -1
  767. package/dist/localization/default-messages.js.map +1 -1
  768. package/dist/notifications/routes.d.ts +1 -1
  769. package/dist/observability/evals.d.ts.map +1 -1
  770. package/dist/observability/evals.js +7 -10
  771. package/dist/observability/evals.js.map +1 -1
  772. package/dist/observability/routes.d.ts +1 -1
  773. package/dist/observability/traces.d.ts +2 -0
  774. package/dist/observability/traces.d.ts.map +1 -1
  775. package/dist/observability/traces.js.map +1 -1
  776. package/dist/org/accept-pending.js +2 -2
  777. package/dist/org/accept-pending.js.map +1 -1
  778. package/dist/org/active-org.d.ts +16 -0
  779. package/dist/org/active-org.d.ts.map +1 -0
  780. package/dist/org/active-org.js +57 -0
  781. package/dist/org/active-org.js.map +1 -0
  782. package/dist/org/auto-join-domain.d.ts.map +1 -1
  783. package/dist/org/auto-join-domain.js +3 -2
  784. package/dist/org/auto-join-domain.js.map +1 -1
  785. package/dist/org/context.d.ts +19 -1
  786. package/dist/org/context.d.ts.map +1 -1
  787. package/dist/org/context.js +159 -71
  788. package/dist/org/context.js.map +1 -1
  789. package/dist/org/handlers.d.ts +24 -1
  790. package/dist/org/handlers.d.ts.map +1 -1
  791. package/dist/org/handlers.js +129 -10
  792. package/dist/org/handlers.js.map +1 -1
  793. package/dist/org/plugin.d.ts +2 -0
  794. package/dist/org/plugin.d.ts.map +1 -1
  795. package/dist/org/plugin.js +9 -2
  796. package/dist/org/plugin.js.map +1 -1
  797. package/dist/org/types.d.ts +6 -1
  798. package/dist/org/types.d.ts.map +1 -1
  799. package/dist/org/types.js.map +1 -1
  800. package/dist/progress/routes.d.ts +1 -1
  801. package/dist/provider-api/actions/custom-provider-registration.d.ts +9 -9
  802. package/dist/provider-api/actions/provider-api.d.ts +11 -11
  803. package/dist/provider-api/index.d.ts.map +1 -1
  804. package/dist/provider-api/index.js +3 -2
  805. package/dist/provider-api/index.js.map +1 -1
  806. package/dist/resources/handlers.d.ts.map +1 -1
  807. package/dist/resources/handlers.js +2 -7
  808. package/dist/resources/handlers.js.map +1 -1
  809. package/dist/resources/script-helpers.d.ts.map +1 -1
  810. package/dist/resources/script-helpers.js +2 -2
  811. package/dist/resources/script-helpers.js.map +1 -1
  812. package/dist/scripts/chat/search-chats.d.ts.map +1 -1
  813. package/dist/scripts/chat/search-chats.js +2 -2
  814. package/dist/scripts/chat/search-chats.js.map +1 -1
  815. package/dist/scripts/describe-workspace-apps.d.ts +4 -0
  816. package/dist/scripts/describe-workspace-apps.d.ts.map +1 -0
  817. package/dist/scripts/describe-workspace-apps.js +34 -0
  818. package/dist/scripts/describe-workspace-apps.js.map +1 -0
  819. package/dist/scripts/resources/delete-memory.d.ts.map +1 -1
  820. package/dist/scripts/resources/delete-memory.js +2 -2
  821. package/dist/scripts/resources/delete-memory.js.map +1 -1
  822. package/dist/scripts/resources/delete.d.ts.map +1 -1
  823. package/dist/scripts/resources/delete.js +2 -2
  824. package/dist/scripts/resources/delete.js.map +1 -1
  825. package/dist/scripts/resources/effective.d.ts.map +1 -1
  826. package/dist/scripts/resources/effective.js +2 -2
  827. package/dist/scripts/resources/effective.js.map +1 -1
  828. package/dist/scripts/resources/list.d.ts.map +1 -1
  829. package/dist/scripts/resources/list.js +2 -2
  830. package/dist/scripts/resources/list.js.map +1 -1
  831. package/dist/scripts/resources/read.d.ts.map +1 -1
  832. package/dist/scripts/resources/read.js +2 -2
  833. package/dist/scripts/resources/read.js.map +1 -1
  834. package/dist/scripts/resources/save-memory.d.ts.map +1 -1
  835. package/dist/scripts/resources/save-memory.js +2 -2
  836. package/dist/scripts/resources/save-memory.js.map +1 -1
  837. package/dist/scripts/resources/write.d.ts.map +1 -1
  838. package/dist/scripts/resources/write.js +2 -2
  839. package/dist/scripts/resources/write.js.map +1 -1
  840. package/dist/secrets/routes.d.ts +9 -9
  841. package/dist/server/agent-capabilities.d.ts +21 -0
  842. package/dist/server/agent-capabilities.d.ts.map +1 -0
  843. package/dist/server/agent-capabilities.js +106 -0
  844. package/dist/server/agent-capabilities.js.map +1 -0
  845. package/dist/server/agent-chat/framework-prompts.d.ts.map +1 -1
  846. package/dist/server/agent-chat/framework-prompts.js +11 -13
  847. package/dist/server/agent-chat/framework-prompts.js.map +1 -1
  848. package/dist/server/agent-chat/prompt-resources.d.ts +32 -0
  849. package/dist/server/agent-chat/prompt-resources.d.ts.map +1 -1
  850. package/dist/server/agent-chat/prompt-resources.js +117 -56
  851. package/dist/server/agent-chat/prompt-resources.js.map +1 -1
  852. package/dist/server/agent-chat/script-entries.d.ts.map +1 -1
  853. package/dist/server/agent-chat/script-entries.js +18 -8
  854. package/dist/server/agent-chat/script-entries.js.map +1 -1
  855. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  856. package/dist/server/agent-chat-plugin.js +27 -1
  857. package/dist/server/agent-chat-plugin.js.map +1 -1
  858. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  859. package/dist/server/auth.d.ts +9 -9
  860. package/dist/server/auth.d.ts.map +1 -1
  861. package/dist/server/auth.js +32 -33
  862. package/dist/server/auth.js.map +1 -1
  863. package/dist/server/core-routes-plugin.d.ts +45 -0
  864. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  865. package/dist/server/core-routes-plugin.js +162 -139
  866. package/dist/server/core-routes-plugin.js.map +1 -1
  867. package/dist/server/credential-provider.d.ts +35 -2
  868. package/dist/server/credential-provider.d.ts.map +1 -1
  869. package/dist/server/credential-provider.js +155 -40
  870. package/dist/server/credential-provider.js.map +1 -1
  871. package/dist/server/embed-session.d.ts.map +1 -1
  872. package/dist/server/embed-session.js +10 -0
  873. package/dist/server/embed-session.js.map +1 -1
  874. package/dist/server/framework-request-handler.d.ts.map +1 -1
  875. package/dist/server/framework-request-handler.js +38 -0
  876. package/dist/server/framework-request-handler.js.map +1 -1
  877. package/dist/server/google-auth-plugin.d.ts.map +1 -1
  878. package/dist/server/google-auth-plugin.js +12 -444
  879. package/dist/server/google-auth-plugin.js.map +1 -1
  880. package/dist/server/index.d.ts +2 -2
  881. package/dist/server/index.d.ts.map +1 -1
  882. package/dist/server/index.js +2 -2
  883. package/dist/server/index.js.map +1 -1
  884. package/dist/server/onboarding-html.d.ts.map +1 -1
  885. package/dist/server/onboarding-html.js +20 -56
  886. package/dist/server/onboarding-html.js.map +1 -1
  887. package/dist/server/open-route.d.ts.map +1 -1
  888. package/dist/server/open-route.js +6 -1
  889. package/dist/server/open-route.js.map +1 -1
  890. package/dist/server/poll.js +1 -1
  891. package/dist/server/poll.js.map +1 -1
  892. package/dist/server/prompts/framework-core-compact.d.ts.map +1 -1
  893. package/dist/server/prompts/framework-core-compact.js +5 -6
  894. package/dist/server/prompts/framework-core-compact.js.map +1 -1
  895. package/dist/server/prompts/framework-core.d.ts.map +1 -1
  896. package/dist/server/prompts/framework-core.js +7 -10
  897. package/dist/server/prompts/framework-core.js.map +1 -1
  898. package/dist/server/prompts/shared-rules.d.ts +20 -2
  899. package/dist/server/prompts/shared-rules.d.ts.map +1 -1
  900. package/dist/server/prompts/shared-rules.js +20 -10
  901. package/dist/server/prompts/shared-rules.js.map +1 -1
  902. package/dist/server/request-context.d.ts +26 -1
  903. package/dist/server/request-context.d.ts.map +1 -1
  904. package/dist/server/request-context.js +52 -2
  905. package/dist/server/request-context.js.map +1 -1
  906. package/dist/server/scoped-key-storage.js +1 -1
  907. package/dist/server/scoped-key-storage.js.map +1 -1
  908. package/dist/settings/org-settings.d.ts +2 -0
  909. package/dist/settings/org-settings.d.ts.map +1 -1
  910. package/dist/settings/org-settings.js +5 -1
  911. package/dist/settings/org-settings.js.map +1 -1
  912. package/dist/settings/store.d.ts +6 -0
  913. package/dist/settings/store.d.ts.map +1 -1
  914. package/dist/settings/store.js +25 -0
  915. package/dist/settings/store.js.map +1 -1
  916. package/dist/shared/index.d.ts +1 -0
  917. package/dist/shared/index.d.ts.map +1 -1
  918. package/dist/shared/index.js +1 -0
  919. package/dist/shared/index.js.map +1 -1
  920. package/dist/shared/sign-in-journey.d.ts +102 -0
  921. package/dist/shared/sign-in-journey.d.ts.map +1 -0
  922. package/dist/shared/sign-in-journey.js +269 -0
  923. package/dist/shared/sign-in-journey.js.map +1 -0
  924. package/dist/styles/agent-native.css +8 -0
  925. package/dist/templates/chat/.agents/skills/actions/SKILL.md +19 -1
  926. package/dist/templates/chat/.agents/skills/adding-a-feature/SKILL.md +2 -0
  927. package/dist/templates/chat/.agents/skills/frontend-design/SKILL.md +20 -6
  928. package/dist/templates/chat/.agents/skills/security/SKILL.md +2 -0
  929. package/dist/templates/chat/.agents/skills/self-modifying-code/SKILL.md +4 -3
  930. package/dist/templates/chat/.agents/skills/shadcn-ui/SKILL.md +7 -3
  931. package/dist/templates/chat/.agents/skills/sharing/SKILL.md +228 -0
  932. package/dist/templates/chat/.agents/skills/storing-data/SKILL.md +178 -0
  933. package/dist/templates/chat/AGENTS.md +8 -0
  934. package/dist/templates/chat/app/entry.client.tsx +3 -0
  935. package/dist/templates/default/.agents/skills/actions/SKILL.md +19 -1
  936. package/dist/templates/default/.agents/skills/adding-a-feature/SKILL.md +2 -0
  937. package/dist/templates/default/.agents/skills/frontend-design/SKILL.md +20 -6
  938. package/dist/templates/default/.agents/skills/security/SKILL.md +2 -0
  939. package/dist/templates/default/.agents/skills/self-modifying-code/SKILL.md +4 -3
  940. package/dist/templates/default/.agents/skills/shadcn-ui/SKILL.md +7 -3
  941. package/dist/templates/default/AGENTS.md +68 -195
  942. package/dist/templates/default/app/entry.client.tsx +3 -0
  943. package/dist/templates/default/app/i18n/ar-SA.ts +8 -0
  944. package/dist/templates/default/app/i18n/de-DE.ts +8 -0
  945. package/dist/templates/default/app/i18n/en-US.ts +8 -0
  946. package/dist/templates/default/app/i18n/es-ES.ts +8 -0
  947. package/dist/templates/default/app/i18n/fr-FR.ts +8 -0
  948. package/dist/templates/default/app/i18n/hi-IN.ts +8 -0
  949. package/dist/templates/default/app/i18n/ja-JP.ts +8 -0
  950. package/dist/templates/default/app/i18n/ko-KR.ts +8 -0
  951. package/dist/templates/default/app/i18n/pt-BR.ts +8 -0
  952. package/dist/templates/default/app/i18n/zh-CN.ts +8 -0
  953. package/dist/templates/default/app/i18n/zh-TW.ts +8 -0
  954. package/dist/templates/headless/.agents/skills/actions/SKILL.md +19 -1
  955. package/dist/templates/workspace-core/.agents/skills/actions/SKILL.md +19 -1
  956. package/dist/templates/workspace-core/.agents/skills/adding-a-feature/SKILL.md +2 -0
  957. package/dist/templates/workspace-core/.agents/skills/adding-workspace-apps/SKILL.md +100 -0
  958. package/dist/templates/workspace-core/.agents/skills/address-feedback/SKILL.md +2 -1
  959. package/dist/templates/workspace-core/.agents/skills/authentication/SKILL.md +28 -0
  960. package/dist/templates/workspace-core/.agents/skills/composable-mini-apps/SKILL.md +14 -1
  961. package/dist/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +20 -6
  962. package/dist/templates/workspace-core/.agents/skills/qa/SKILL.md +6 -3
  963. package/dist/templates/workspace-core/.agents/skills/security/SKILL.md +2 -0
  964. package/dist/templates/workspace-core/.agents/skills/self-modifying-code/SKILL.md +4 -3
  965. package/dist/templates/workspace-core/.agents/skills/shadcn-ui/SKILL.md +7 -3
  966. package/dist/templates/workspace-core/.agents/skills/workspace-conventions/SKILL.md +91 -0
  967. package/dist/templates/workspace-core/.agents/skills/writing-agent-instructions/SKILL.md +60 -0
  968. package/dist/templates/workspace-core/AGENTS.md +62 -124
  969. package/dist/templates/workspace-root/AGENTS.md +6 -1
  970. package/dist/triggers/dispatcher.d.ts.map +1 -1
  971. package/dist/triggers/dispatcher.js +10 -3
  972. package/dist/triggers/dispatcher.js.map +1 -1
  973. package/dist/vite/client.d.ts.map +1 -1
  974. package/dist/vite/client.js +18 -8
  975. package/dist/vite/client.js.map +1 -1
  976. package/docs/content/actions.mdx +33 -20
  977. package/docs/content/agent-mentions.mdx +30 -19
  978. package/docs/content/agent-native-toolkit.mdx +8 -6
  979. package/docs/content/agent-resources.mdx +11 -0
  980. package/docs/content/agent-surfaces.mdx +41 -30
  981. package/docs/content/audit-log.mdx +78 -0
  982. package/docs/content/authentication.mdx +7 -5
  983. package/docs/content/automations.mdx +15 -9
  984. package/docs/content/client.mdx +11 -11
  985. package/docs/content/cloneable-saas.mdx +7 -1
  986. package/docs/content/code-agents-ui.mdx +9 -1
  987. package/docs/content/components.mdx +7 -0
  988. package/docs/content/context-awareness.mdx +1 -0
  989. package/docs/content/creating-templates.mdx +9 -1
  990. package/docs/content/custom-design-system.mdx +8 -0
  991. package/docs/content/data-programs.mdx +6 -0
  992. package/docs/content/deployment.mdx +2 -0
  993. package/docs/content/doctor.mdx +5 -3
  994. package/docs/content/extensions.mdx +26 -0
  995. package/docs/content/external-agents-catalog.mdx +533 -0
  996. package/docs/content/external-agents.mdx +20 -514
  997. package/docs/content/faq.mdx +2 -2
  998. package/docs/content/file-uploads.mdx +44 -0
  999. package/docs/content/frames.mdx +2 -2
  1000. package/docs/content/generative-ui.mdx +8 -0
  1001. package/docs/content/getting-started.mdx +45 -17
  1002. package/docs/content/human-approval.mdx +9 -0
  1003. package/docs/content/integrations.mdx +4 -3
  1004. package/docs/content/internationalization.mdx +4 -11
  1005. package/docs/content/key-concepts.mdx +1 -1
  1006. package/docs/content/local-file-mode.mdx +5 -0
  1007. package/docs/content/mcp-apps.mdx +2 -1
  1008. package/docs/content/mcp-clients.mdx +32 -1
  1009. package/docs/content/mcp-protocol.mdx +4 -3
  1010. package/docs/content/messaging-internals.mdx +328 -0
  1011. package/docs/content/messaging-recipes.mdx +194 -0
  1012. package/docs/content/messaging.mdx +9 -307
  1013. package/docs/content/multi-app-workspace.mdx +1 -1
  1014. package/docs/content/multi-tenancy.mdx +1 -0
  1015. package/docs/content/native-chat-ui.mdx +8 -0
  1016. package/docs/content/notifications.mdx +18 -20
  1017. package/docs/content/observability.mdx +1 -0
  1018. package/docs/content/onboarding.mdx +20 -6
  1019. package/docs/content/organizations-teams-permissions.mdx +99 -124
  1020. package/docs/content/package-lifecycle.mdx +19 -7
  1021. package/docs/content/progress.mdx +11 -0
  1022. package/docs/content/real-time-collaboration.mdx +44 -3
  1023. package/docs/content/recurring-jobs.mdx +14 -1
  1024. package/docs/content/security.mdx +5 -2
  1025. package/docs/content/server.mdx +2 -1
  1026. package/docs/content/sharing.mdx +22 -3
  1027. package/docs/content/skills-guide.mdx +62 -19
  1028. package/docs/content/syncing-template-changes.mdx +9 -0
  1029. package/docs/content/template-analytics-connectors.mdx +75 -0
  1030. package/docs/content/template-analytics-dashboards.mdx +106 -0
  1031. package/docs/content/template-analytics-developers.mdx +287 -0
  1032. package/docs/content/template-analytics-monitoring-and-sessions.mdx +109 -0
  1033. package/docs/content/template-analytics.mdx +21 -263
  1034. package/docs/content/template-assets-developers.mdx +456 -0
  1035. package/docs/content/template-assets-generation.mdx +147 -0
  1036. package/docs/content/template-assets-integrations.mdx +319 -0
  1037. package/docs/content/template-assets-presets.mdx +185 -0
  1038. package/docs/content/template-assets.mdx +12 -562
  1039. package/docs/content/template-brain-agent.mdx +103 -0
  1040. package/docs/content/template-brain-developers.mdx +379 -0
  1041. package/docs/content/template-brain-knowledge.mdx +50 -0
  1042. package/docs/content/template-brain-sources.mdx +163 -0
  1043. package/docs/content/template-brain.mdx +30 -390
  1044. package/docs/content/template-calendar-agent.mdx +133 -0
  1045. package/docs/content/template-calendar-booking-links.mdx +73 -0
  1046. package/docs/content/template-calendar-developers.mdx +366 -0
  1047. package/docs/content/template-calendar-scheduling.mdx +128 -0
  1048. package/docs/content/template-calendar.mdx +13 -260
  1049. package/docs/content/template-chat-developers.mdx +88 -0
  1050. package/docs/content/template-chat-first-edits.mdx +145 -0
  1051. package/docs/content/template-chat.mdx +12 -77
  1052. package/docs/content/template-clips-ai-and-editing.mdx +114 -0
  1053. package/docs/content/template-clips-capture-everywhere.mdx +120 -0
  1054. package/docs/content/template-clips-developers.mdx +373 -0
  1055. package/docs/content/template-clips-sharing-and-teams.mdx +182 -0
  1056. package/docs/content/template-clips.mdx +19 -508
  1057. package/docs/content/template-content-databases.mdx +406 -0
  1058. package/docs/content/template-content-developers.mdx +364 -0
  1059. package/docs/content/template-content-editing.mdx +60 -0
  1060. package/docs/content/template-content-sync.mdx +149 -0
  1061. package/docs/content/template-content.mdx +21 -561
  1062. package/docs/content/template-design-brand-and-figma.mdx +150 -0
  1063. package/docs/content/template-design-collaboration-and-full-apps.mdx +125 -0
  1064. package/docs/content/template-design-developers.mdx +358 -0
  1065. package/docs/content/template-design-quality-and-components.mdx +95 -0
  1066. package/docs/content/template-design.mdx +20 -344
  1067. package/docs/content/template-dispatch-developers.mdx +121 -0
  1068. package/docs/content/template-dispatch-messaging-routing.mdx +114 -0
  1069. package/docs/content/template-dispatch-operations.mdx +160 -0
  1070. package/docs/content/template-dispatch-vault-integrations.mdx +316 -0
  1071. package/docs/content/template-dispatch.mdx +24 -283
  1072. package/docs/content/template-forms-building-publishing.mdx +135 -0
  1073. package/docs/content/template-forms-developers.mdx +195 -0
  1074. package/docs/content/template-forms-responses.mdx +120 -0
  1075. package/docs/content/template-forms.mdx +21 -230
  1076. package/docs/content/template-mail-agent.mdx +114 -0
  1077. package/docs/content/template-mail-developers.mdx +356 -0
  1078. package/docs/content/template-mail-drafts-and-queue.mdx +103 -0
  1079. package/docs/content/template-mail-inbox.mdx +118 -0
  1080. package/docs/content/template-mail.mdx +23 -274
  1081. package/docs/content/template-plan-automations.mdx +213 -0
  1082. package/docs/content/template-plan-developers.mdx +703 -0
  1083. package/docs/content/template-plan-local-and-desktop.mdx +236 -0
  1084. package/docs/content/template-plan-review-workflow.mdx +180 -0
  1085. package/docs/content/template-plan.mdx +60 -910
  1086. package/docs/content/template-slides-agent.mdx +102 -0
  1087. package/docs/content/template-slides-design-and-media.mdx +94 -0
  1088. package/docs/content/template-slides-developers.mdx +488 -0
  1089. package/docs/content/template-slides-editing.mdx +56 -0
  1090. package/docs/content/template-slides.mdx +20 -362
  1091. package/docs/content/toolkit-capability-packages.mdx +38 -13
  1092. package/docs/content/toolkit-context-knowledge.mdx +49 -9
  1093. package/docs/content/toolkit-editors-canvases.mdx +72 -10
  1094. package/docs/content/toolkit-resources.mdx +16 -0
  1095. package/docs/content/toolkit-settings.mdx +3 -3
  1096. package/docs/content/toolkit-sharing.mdx +5 -7
  1097. package/docs/content/using-your-agent.mdx +25 -2
  1098. package/docs/content/voice-input.mdx +11 -7
  1099. package/docs/content/what-is-agent-native.mdx +1 -0
  1100. package/docs/content/workspace-connections.mdx +21 -11
  1101. package/docs/content/workspace-management.mdx +1 -1
  1102. package/package.json +2 -4
  1103. package/src/a2a/client.ts +4 -2
  1104. package/src/agent/action-warnings.ts +103 -0
  1105. package/src/agent/durable-background.ts +42 -5
  1106. package/src/agent/engine/ai-sdk-engine.ts +58 -6
  1107. package/src/agent/engine/anthropic-engine.ts +51 -8
  1108. package/src/agent/engine/builder-engine.ts +56 -18
  1109. package/src/agent/engine/continuation-dispatch-retry.ts +10 -9
  1110. package/src/agent/engine/credential-errors.ts +11 -0
  1111. package/src/agent/engine/error-detail.ts +39 -0
  1112. package/src/agent/engine/prompt-cache.ts +44 -0
  1113. package/src/agent/engine/registry.ts +22 -30
  1114. package/src/agent/engine/tool-call-journal-seed.ts +2 -1
  1115. package/src/agent/engine/translate-anthropic.ts +99 -0
  1116. package/src/agent/loop-settings.ts +94 -7
  1117. package/src/agent/production-agent.ts +667 -157
  1118. package/src/agent/run-loop-with-resume.ts +27 -1
  1119. package/src/agent/run-manager.ts +229 -39
  1120. package/src/agent/run-store.ts +397 -64
  1121. package/src/agent/thread-data-builder.ts +5 -1
  1122. package/src/agent/types.ts +23 -6
  1123. package/src/application-state/script-helpers.ts +5 -2
  1124. package/src/cli/agents.ts +69 -1
  1125. package/src/cli/app-skill.ts +1 -1
  1126. package/src/cli/code-agent-executor.ts +7 -3
  1127. package/src/cli/design-connect.ts +82 -8
  1128. package/src/cli/skills-content/design-visual-edit-skill.ts +169 -24
  1129. package/src/client/AssistantChat.tsx +623 -607
  1130. package/src/client/agent-chat-adapter.ts +176 -29
  1131. package/src/client/chat/message-components.tsx +13 -0
  1132. package/src/client/embed-auth.ts +3 -1
  1133. package/src/client/integrations/IntegrationCard.tsx +41 -24
  1134. package/src/client/integrations/IntegrationsPanel.tsx +37 -21
  1135. package/src/client/integrations/webhook-url.ts +29 -0
  1136. package/src/client/org/OrgSwitcher.tsx +41 -27
  1137. package/src/client/org/RequireActiveOrg.tsx +7 -0
  1138. package/src/client/org/TeamPage.tsx +144 -14
  1139. package/src/client/org/hooks.ts +27 -0
  1140. package/src/client/org/index.ts +2 -0
  1141. package/src/client/require-session.tsx +40 -29
  1142. package/src/client/session-replay.ts +1 -1
  1143. package/src/client/settings/DemoModeSection.tsx +0 -5
  1144. package/src/client/settings/SecretsSection.tsx +47 -42
  1145. package/src/client/settings/VoiceTranscriptionSection.tsx +0 -5
  1146. package/src/client/sse-event-processor.ts +83 -8
  1147. package/src/client/use-action.ts +22 -13
  1148. package/src/client/use-agent-engine-configured.ts +36 -4
  1149. package/src/client/use-db-sync.ts +21 -1
  1150. package/src/credentials/index.ts +124 -2
  1151. package/src/deploy/build.ts +93 -30
  1152. package/src/deploy/workspace-deploy.ts +21 -16
  1153. package/src/guards/no-localhost-fallback.ts +76 -14
  1154. package/src/integrations/google-docs-poller.ts +19 -12
  1155. package/src/integrations/webhook-handler.ts +56 -33
  1156. package/src/jobs/scheduler.ts +57 -23
  1157. package/src/localization/default-messages.ts +23 -1
  1158. package/src/observability/evals.ts +7 -8
  1159. package/src/observability/traces.ts +2 -0
  1160. package/src/org/accept-pending.ts +2 -2
  1161. package/src/org/active-org.ts +73 -0
  1162. package/src/org/auto-join-domain.ts +7 -2
  1163. package/src/org/context.ts +169 -66
  1164. package/src/org/handlers.ts +148 -10
  1165. package/src/org/plugin.ts +8 -1
  1166. package/src/org/types.ts +6 -1
  1167. package/src/provider-api/index.ts +6 -1
  1168. package/src/resources/handlers.ts +2 -6
  1169. package/src/resources/script-helpers.ts +2 -1
  1170. package/src/scripts/chat/search-chats.ts +5 -2
  1171. package/src/scripts/describe-workspace-apps.ts +59 -0
  1172. package/src/scripts/resources/delete-memory.ts +5 -2
  1173. package/src/scripts/resources/delete.ts +5 -2
  1174. package/src/scripts/resources/effective.ts +5 -2
  1175. package/src/scripts/resources/list.ts +5 -2
  1176. package/src/scripts/resources/read.ts +5 -2
  1177. package/src/scripts/resources/save-memory.ts +5 -2
  1178. package/src/scripts/resources/write.ts +5 -2
  1179. package/src/server/__snapshots__/agent-chat-plugin.surface.spec.ts.snap +11 -31
  1180. package/src/server/agent-capabilities.ts +147 -0
  1181. package/src/server/agent-chat/framework-prompts.ts +11 -13
  1182. package/src/server/agent-chat/prompt-resources.ts +183 -57
  1183. package/src/server/agent-chat/script-entries.ts +20 -7
  1184. package/src/server/agent-chat-plugin.ts +27 -0
  1185. package/src/server/auth.ts +38 -32
  1186. package/src/server/core-routes-plugin.ts +229 -179
  1187. package/src/server/credential-provider.ts +196 -44
  1188. package/src/server/embed-session.ts +10 -0
  1189. package/src/server/framework-request-handler.ts +43 -0
  1190. package/src/server/google-auth-plugin.ts +13 -450
  1191. package/src/server/index.ts +4 -1
  1192. package/src/server/onboarding-html.ts +20 -56
  1193. package/src/server/open-route.ts +6 -1
  1194. package/src/server/poll.ts +1 -1
  1195. package/src/server/prompts/framework-core-compact.ts +5 -5
  1196. package/src/server/prompts/framework-core.ts +7 -9
  1197. package/src/server/prompts/shared-rules.ts +20 -9
  1198. package/src/server/request-context.ts +58 -2
  1199. package/src/server/scoped-key-storage.ts +1 -1
  1200. package/src/settings/org-settings.ts +9 -0
  1201. package/src/settings/store.ts +29 -0
  1202. package/src/shared/index.ts +13 -0
  1203. package/src/shared/sign-in-journey.ts +331 -0
  1204. package/src/styles/agent-native.css +8 -0
  1205. package/src/templates/chat/.agents/skills/actions/SKILL.md +19 -1
  1206. package/src/templates/chat/.agents/skills/adding-a-feature/SKILL.md +2 -0
  1207. package/src/templates/chat/.agents/skills/frontend-design/SKILL.md +20 -6
  1208. package/src/templates/chat/.agents/skills/security/SKILL.md +2 -0
  1209. package/src/templates/chat/.agents/skills/self-modifying-code/SKILL.md +4 -3
  1210. package/src/templates/chat/.agents/skills/shadcn-ui/SKILL.md +7 -3
  1211. package/src/templates/chat/.agents/skills/sharing/SKILL.md +228 -0
  1212. package/src/templates/chat/.agents/skills/storing-data/SKILL.md +178 -0
  1213. package/src/templates/chat/AGENTS.md +8 -0
  1214. package/src/templates/chat/app/entry.client.tsx +3 -0
  1215. package/src/templates/default/.agents/skills/actions/SKILL.md +19 -1
  1216. package/src/templates/default/.agents/skills/adding-a-feature/SKILL.md +2 -0
  1217. package/src/templates/default/.agents/skills/frontend-design/SKILL.md +20 -6
  1218. package/src/templates/default/.agents/skills/security/SKILL.md +2 -0
  1219. package/src/templates/default/.agents/skills/self-modifying-code/SKILL.md +4 -3
  1220. package/src/templates/default/.agents/skills/shadcn-ui/SKILL.md +7 -3
  1221. package/src/templates/default/AGENTS.md +68 -195
  1222. package/src/templates/default/app/entry.client.tsx +3 -0
  1223. package/src/templates/default/app/i18n/ar-SA.ts +8 -0
  1224. package/src/templates/default/app/i18n/de-DE.ts +8 -0
  1225. package/src/templates/default/app/i18n/en-US.ts +8 -0
  1226. package/src/templates/default/app/i18n/es-ES.ts +8 -0
  1227. package/src/templates/default/app/i18n/fr-FR.ts +8 -0
  1228. package/src/templates/default/app/i18n/hi-IN.ts +8 -0
  1229. package/src/templates/default/app/i18n/ja-JP.ts +8 -0
  1230. package/src/templates/default/app/i18n/ko-KR.ts +8 -0
  1231. package/src/templates/default/app/i18n/pt-BR.ts +8 -0
  1232. package/src/templates/default/app/i18n/zh-CN.ts +8 -0
  1233. package/src/templates/default/app/i18n/zh-TW.ts +8 -0
  1234. package/src/templates/headless/.agents/skills/actions/SKILL.md +19 -1
  1235. package/src/templates/workspace-core/.agents/skills/actions/SKILL.md +19 -1
  1236. package/src/templates/workspace-core/.agents/skills/adding-a-feature/SKILL.md +2 -0
  1237. package/src/templates/workspace-core/.agents/skills/adding-workspace-apps/SKILL.md +100 -0
  1238. package/src/templates/workspace-core/.agents/skills/address-feedback/SKILL.md +2 -1
  1239. package/src/templates/workspace-core/.agents/skills/authentication/SKILL.md +28 -0
  1240. package/src/templates/workspace-core/.agents/skills/composable-mini-apps/SKILL.md +14 -1
  1241. package/src/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +20 -6
  1242. package/src/templates/workspace-core/.agents/skills/qa/SKILL.md +6 -3
  1243. package/src/templates/workspace-core/.agents/skills/security/SKILL.md +2 -0
  1244. package/src/templates/workspace-core/.agents/skills/self-modifying-code/SKILL.md +4 -3
  1245. package/src/templates/workspace-core/.agents/skills/shadcn-ui/SKILL.md +7 -3
  1246. package/src/templates/workspace-core/.agents/skills/workspace-conventions/SKILL.md +91 -0
  1247. package/src/templates/workspace-core/.agents/skills/writing-agent-instructions/SKILL.md +60 -0
  1248. package/src/templates/workspace-core/AGENTS.md +62 -124
  1249. package/src/templates/workspace-root/AGENTS.md +6 -1
  1250. package/src/triggers/dispatcher.ts +28 -17
  1251. package/src/vite/client.ts +20 -8
  1252. package/corpus/core/src/client/components/MissingKeyCard.tsx +0 -61
  1253. package/corpus/core/src/client/extensions/agent-native-extension-runtime.ts +0 -495
  1254. package/corpus/core/src/client/settings/BackgroundAgentSection.tsx +0 -193
  1255. package/corpus/core/src/client/settings/BrowserSection.tsx +0 -110
  1256. package/corpus/templates/analytics/app/components/InlineMetric.tsx +0 -31
  1257. package/corpus/templates/analytics/app/components/auth/LoginScreen.tsx +0 -4
  1258. package/corpus/templates/analytics/app/components/dashboard/CumulativeNetChart.tsx +0 -128
  1259. package/corpus/templates/analytics/app/components/dashboard/DataTable.tsx +0 -264
  1260. package/corpus/templates/analytics/app/components/dashboard/RecentActivity.tsx +0 -84
  1261. package/corpus/templates/analytics/app/components/dashboard/RevenueChart.tsx +0 -92
  1262. package/corpus/templates/analytics/app/components/dashboard/RevenueComparisonChart.tsx +0 -154
  1263. package/corpus/templates/analytics/app/components/dashboard/StatsCard.tsx +0 -49
  1264. package/corpus/templates/analytics/app/components/dashboard/TimeSeriesChart.tsx +0 -120
  1265. package/corpus/templates/analytics/server/handlers/dashboard-views.ts +0 -85
  1266. package/corpus/templates/analytics/server/handlers/user-prefs.ts +0 -58
  1267. package/corpus/templates/analytics/server/routes/api/dashboard-views/[dashboardId]/[viewId].delete.ts +0 -1
  1268. package/corpus/templates/analytics/server/routes/api/dashboard-views/[dashboardId].get.ts +0 -1
  1269. package/corpus/templates/analytics/server/routes/api/dashboard-views/[dashboardId].post.ts +0 -1
  1270. package/corpus/templates/analytics/server/routes/api/theme.get.ts +0 -17
  1271. package/corpus/templates/analytics/server/routes/api/theme.post.ts +0 -15
  1272. package/corpus/templates/analytics/server/routes/api/user-prefs/[key].delete.ts +0 -1
  1273. package/corpus/templates/analytics/server/routes/api/user-prefs/[key].get.ts +0 -1
  1274. package/corpus/templates/analytics/server/routes/api/user-prefs/[key].put.ts +0 -1
  1275. package/corpus/templates/assets/app/components/library/CreateLibraryDialog.tsx +0 -156
  1276. package/corpus/templates/assets/app/components/library/LibraryCard.tsx +0 -213
  1277. package/corpus/templates/calendar/app/components/calendar/GoogleSyncButton.tsx +0 -49
  1278. package/corpus/templates/calendar/server/routes/api/events/[id].delete.ts +0 -1
  1279. package/corpus/templates/calendar/server/routes/api/events/[id].get.ts +0 -1
  1280. package/corpus/templates/calendar/server/routes/api/events/[id].put.ts +0 -1
  1281. package/corpus/templates/content/app/components/layout/AppLayout.tsx +0 -9
  1282. package/corpus/templates/content/server/routes/api/comments/[id].delete.ts +0 -69
  1283. package/corpus/templates/content/server/routes/api/comments/[id].patch.ts +0 -109
  1284. package/corpus/templates/content/server/routes/api/documents/[id]/versions.get.ts +0 -53
  1285. package/corpus/templates/design/app/components/design/code-workbench/ActivityBar.tsx +0 -85
  1286. package/corpus/templates/design/app/components/design-system/DesignSystemCard.tsx +0 -129
  1287. package/corpus/templates/forms/app/components/layout/AppLayout.tsx +0 -9
  1288. package/corpus/templates/mail/app/components/email/SnoozePopover.tsx +0 -213
  1289. package/corpus/templates/mail/server/handlers/aliases.ts +0 -98
  1290. package/corpus/templates/mail/server/routes/api/aliases/[id].delete.ts +0 -1
  1291. package/corpus/templates/mail/server/routes/api/aliases/[id].patch.ts +0 -1
  1292. package/corpus/templates/mail/server/routes/api/aliases/index.get.ts +0 -1
  1293. package/corpus/templates/mail/server/routes/api/aliases/index.post.ts +0 -1
  1294. package/corpus/templates/mail/server/routes/api/automations/[id].delete.ts +0 -1
  1295. package/corpus/templates/mail/server/routes/api/automations/[id].patch.ts +0 -1
  1296. package/corpus/templates/mail/server/routes/api/automations/index.get.ts +0 -1
  1297. package/corpus/templates/mail/server/routes/api/automations/index.post.ts +0 -1
  1298. package/corpus/templates/mail/server/routes/api/automations/settings.get.ts +0 -22
  1299. package/corpus/templates/mail/server/routes/api/automations/settings.put.ts +0 -25
  1300. package/corpus/templates/mail/server/routes/api/scheduled-jobs/[id].delete.ts +0 -1
  1301. package/corpus/templates/mail/server/routes/api/scheduled-jobs/[id].patch.ts +0 -1
  1302. package/corpus/templates/mail/server/routes/api/scheduled-jobs/index.get.ts +0 -1
  1303. package/corpus/templates/mail/server/routes/api/scheduled-jobs/index.post.ts +0 -1
  1304. package/corpus/templates/mail/server/routes/api/settings.get.ts +0 -1
  1305. package/corpus/templates/mail/server/routes/api/settings.patch.ts +0 -1
  1306. package/corpus/templates/slides/app/components/deck/BuilderLogo.tsx +0 -22
  1307. package/corpus/templates/slides/app/components/design-system/DesignSystemPreview.tsx +0 -176
  1308. package/corpus/templates/slides/app/components/editor/GenerateSlidesDialog.tsx +0 -244
  1309. package/corpus/templates/slides/app/components/editor/ImportButton.tsx +0 -84
  1310. package/corpus/templates/slides/server/routes/api/comments/[id].delete.ts +0 -43
  1311. package/corpus/templates/slides/server/routes/api/comments/[id].patch.ts +0 -50
  1312. package/corpus/templates/slides/server/routes/api/decks/[id].delete.ts +0 -1
  1313. package/corpus/templates/slides/server/routes/api/decks/[id].get.ts +0 -1
  1314. package/corpus/templates/slides/server/routes/api/decks/[id].put.ts +0 -1
  1315. package/corpus/templates/slides/server/routes/api/decks/index.get.ts +0 -1
  1316. package/corpus/templates/slides/server/routes/api/decks/index.post.ts +0 -1
  1317. package/dist/client/components/MissingKeyCard.d.ts +0 -7
  1318. package/dist/client/components/MissingKeyCard.d.ts.map +0 -1
  1319. package/dist/client/components/MissingKeyCard.js +0 -32
  1320. package/dist/client/components/MissingKeyCard.js.map +0 -1
  1321. package/dist/client/extensions/agent-native-extension-runtime.d.ts +0 -69
  1322. package/dist/client/extensions/agent-native-extension-runtime.d.ts.map +0 -1
  1323. package/dist/client/extensions/agent-native-extension-runtime.js +0 -348
  1324. package/dist/client/extensions/agent-native-extension-runtime.js.map +0 -1
  1325. package/dist/client/settings/BackgroundAgentSection.d.ts +0 -2
  1326. package/dist/client/settings/BackgroundAgentSection.d.ts.map +0 -1
  1327. package/dist/client/settings/BackgroundAgentSection.js +0 -68
  1328. package/dist/client/settings/BackgroundAgentSection.js.map +0 -1
  1329. package/dist/client/settings/BrowserSection.d.ts +0 -2
  1330. package/dist/client/settings/BrowserSection.d.ts.map +0 -1
  1331. package/dist/client/settings/BrowserSection.js +0 -40
  1332. package/dist/client/settings/BrowserSection.js.map +0 -1
  1333. package/dist/templates/chat/.react-router/types/+server-build.d.ts +0 -18
  1334. package/dist/templates/chat/.react-router/types/app/+types/root.ts +0 -68
  1335. package/src/client/components/MissingKeyCard.tsx +0 -61
  1336. package/src/client/extensions/agent-native-extension-runtime.ts +0 -495
  1337. package/src/client/settings/BackgroundAgentSection.tsx +0 -193
  1338. package/src/client/settings/BrowserSection.tsx +0 -110
  1339. package/src/templates/chat/.react-router/types/+server-build.d.ts +0 -18
  1340. package/src/templates/chat/.react-router/types/app/+types/root.ts +0 -68
@@ -1,32 +1,16 @@
1
- import { randomUUID } from "node:crypto";
2
- import { existsSync } from "node:fs";
3
- import { readdir, rm, stat } from "node:fs/promises";
4
- import { tmpdir } from "node:os";
5
- import { join } from "node:path";
1
+ import { getAppProductionUrl, sendEmail } from "@agent-native/core/server";
6
2
 
7
- import {
8
- getAppProductionUrl,
9
- sendEmail,
10
- signEmbedSessionToken,
11
- } from "@agent-native/core/server";
12
- import {
13
- EMBED_MODE_QUERY_PARAM,
14
- EMBED_SESSION_COOKIE,
15
- EMBED_TOKEN_QUERY_PARAM,
16
- } from "@agent-native/core/shared";
17
-
18
- import { interpolate } from "../../app/pages/adhoc/sql-dashboard/interpolate";
19
- import { serializePanelSql } from "../../app/pages/adhoc/sql-dashboard/panel-sql";
20
- import {
21
- listReportablePanelIds,
22
- REPORT_PANEL_CHUNK_SIZE,
23
- } from "../../app/pages/adhoc/sql-dashboard/report-panel-window";
3
+ import { listReportablePanelIds } from "../../app/pages/adhoc/sql-dashboard/report-panel-window";
24
4
  import type {
25
5
  DashboardFilter,
26
6
  FilterType,
27
7
  SqlDashboardConfig,
28
8
  } from "../../app/pages/adhoc/sql-dashboard/types";
29
- import { DASHBOARD_REPORT_READY_TIMEOUT_MS } from "../../shared/dashboard-report-timeouts.js";
9
+ import {
10
+ fetchReportPanelData,
11
+ renderReportEmail,
12
+ type ReportSnapshot,
13
+ } from "./dashboard-report-render";
30
14
  import {
31
15
  getReportDashboard,
32
16
  normalizeDashboardReportRecipients,
@@ -34,67 +18,25 @@ import {
34
18
  type DashboardReportCaptureOutcome,
35
19
  type DashboardReportSubscription,
36
20
  } from "./dashboard-report-subscriptions";
37
- import { queryFirstPartyAnalytics } from "./first-party-analytics.js";
38
-
39
- type ReportSnapshot = {
40
- dashboardId: string;
41
- title: string;
42
- description?: string;
43
- filters: Record<string, string>;
44
- dashboardUrl: string;
45
- reportSettingsUrl: string;
46
- generatedAt: string;
47
- panelIds: string[];
48
- panels: SqlDashboardConfig["panels"];
49
- variables?: Record<string, string>;
50
- };
51
21
 
52
22
  const DATE_FILTER_TYPES: ReadonlySet<FilterType> = new Set([
53
23
  "date",
54
24
  "date-range",
55
25
  "toggle-date",
56
26
  ]);
57
- const DEFAULT_SERVERLESS_CHROMIUM_PACK_URL =
58
- "https://github.com/Sparticuz/chromium/releases/download/v149.0.0/chromium-v149.0.0-pack.x64.tar";
59
- const DASHBOARD_REPORT_SCREENSHOT_PARAM = "reportScreenshot";
60
27
  const DASHBOARD_REPORT_SETTINGS_PARAM = "reportSettings";
61
- const DASHBOARD_REPORT_CID = "dashboard-report-snapshot";
62
- const LOCAL_SCREENSHOT_TIMEOUT_MS = 90_000;
63
- const SERVERLESS_SCREENSHOT_TIMEOUT_MS = 90_000;
64
- const SERVERLESS_SECOND_READY_TIMEOUT_MS = 45_000;
65
- // Cap browser work separately from the sweep-level delivery deadline.
66
- // Reserve time under Netlify's 300s background-function limit for cleanup and
67
- // email delivery (see MAX_CAPTURE_CLEANUP_RESERVE_MS / delivery reserves below).
68
- const SERVERLESS_CHUNKED_ATTEMPT_TIMEOUT_MS = 210_000;
69
- const BROWSER_CLEANUP_TIMEOUT_MS = 10_000;
70
28
  const DASHBOARD_REPORT_EMAIL_TIMEOUT_MS = 10_000;
71
29
  const DASHBOARD_REPORT_EMAIL_OVERHEAD_RESERVE_MS = 5_000;
72
- const MAX_CAPTURE_CLEANUP_RESERVE_MS = BROWSER_CLEANUP_TIMEOUT_MS * 3;
73
- const SCREENSHOT_VIEWPORT_PADDING = 64;
74
- const MAX_DASHBOARD_REPORT_CHUNKS = 10;
75
- const MAX_DASHBOARD_REPORT_ATTACHMENT_BYTES = 14 * 1024 * 1024;
76
30
 
77
- type DashboardScreenshotAttempt = {
78
- label: "chunked";
79
- viewport: { width: number; height: number };
80
- captureScale?: number;
81
- readyTimeout?: number;
82
- secondReadyTimeout?: number;
83
- totalTimeout?: number;
84
- };
31
+ export type DashboardReportMode = "complete" | "degraded";
85
32
 
86
- type LaunchedScreenshotBrowser = {
87
- browser: any;
88
- cleanup: () => Promise<void>;
89
- newPage: () => Promise<any>;
90
- };
91
-
92
- class DashboardReportPanelMismatchError extends Error {}
93
-
94
- type DashboardPngCapture = {
95
- pngs: Array<Buffer | null> | null;
96
- mode: "full" | "partial" | "none";
97
- error?: string;
33
+ export type DashboardReportResult = {
34
+ dashboardUrl: string;
35
+ recipientCount: number;
36
+ reportMode: DashboardReportMode;
37
+ degradedPanelIds: string[];
38
+ reportError?: string;
39
+ emailsSent: boolean;
98
40
  };
99
41
 
100
42
  function daysAgo(n: number): string {
@@ -158,13 +100,10 @@ function dashboardBaseUrl(): string {
158
100
  );
159
101
  }
160
102
 
161
- function buildDashboardPath(
103
+ function buildDashboardUrl(
162
104
  dashboardId: string,
163
105
  filters: Record<string, string>,
164
- options?: {
165
- reportScreenshot?: boolean;
166
- reportSettings?: boolean;
167
- },
106
+ options?: { reportSettings?: boolean },
168
107
  ): string {
169
108
  const url = new URL(
170
109
  `/dashboards/${encodeURIComponent(dashboardId)}`,
@@ -173,38 +112,16 @@ function buildDashboardPath(
173
112
  for (const [key, value] of Object.entries(filters)) {
174
113
  if (value) url.searchParams.set(key, value);
175
114
  }
176
- if (options?.reportScreenshot) {
177
- url.searchParams.set(DASHBOARD_REPORT_SCREENSHOT_PARAM, "1");
178
- }
179
115
  if (options?.reportSettings) {
180
116
  url.searchParams.set(DASHBOARD_REPORT_SETTINGS_PARAM, "1");
181
117
  }
182
- return `${url.pathname}${url.search}`;
183
- }
184
-
185
- function buildDashboardUrl(
186
- dashboardId: string,
187
- filters: Record<string, string>,
188
- options?: {
189
- reportScreenshot?: boolean;
190
- reportSettings?: boolean;
191
- },
192
- ): string {
193
- const path = buildDashboardPath(dashboardId, filters, options);
194
- const url = new URL(path, `${dashboardBaseUrl()}/`);
195
- return url.toString();
196
- }
197
-
198
- function escapeHtml(value: unknown): string {
199
- return String(value ?? "")
200
- .replace(/&/g, "&amp;")
201
- .replace(/</g, "&lt;")
202
- .replace(/>/g, "&gt;")
203
- .replace(/"/g, "&quot;")
204
- .replace(/'/g, "&#39;");
118
+ return new URL(
119
+ `${url.pathname}${url.search}`,
120
+ `${dashboardBaseUrl()}/`,
121
+ ).toString();
205
122
  }
206
123
 
207
- async function collectReportSnapshot(
124
+ export async function collectReportSnapshot(
208
125
  sub: DashboardReportSubscription,
209
126
  ): Promise<ReportSnapshot> {
210
127
  const accessCtx: AccessCtx = {
@@ -238,184 +155,13 @@ async function collectReportSnapshot(
238
155
  };
239
156
  }
240
157
 
241
- function isServerlessBrowserRuntime(): boolean {
242
- return (
243
- process.env.NETLIFY === "true" ||
244
- Boolean(process.env.AWS_LAMBDA_FUNCTION_NAME) ||
245
- Boolean(process.env.AWS_EXECUTION_ENV)
246
- );
247
- }
248
-
249
- function localChromiumExecutablePath(): string | null {
250
- const configured =
251
- process.env.PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH ||
252
- process.env.CHROME_BIN ||
253
- process.env.CHROMIUM_PATH;
254
- if (configured && existsSync(configured)) return configured;
255
-
256
- const candidates = [
257
- "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
258
- "/Applications/Chromium.app/Contents/MacOS/Chromium",
259
- "/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge",
260
- "/usr/bin/google-chrome",
261
- "/usr/bin/google-chrome-stable",
262
- "/usr/bin/chromium",
263
- "/usr/bin/chromium-browser",
264
- ];
265
- return candidates.find((candidate) => existsSync(candidate)) ?? null;
266
- }
267
-
268
- async function sweepStaleScreenshotProfiles(): Promise<void> {
269
- let entries: string[];
270
- try {
271
- entries = await readdir(tmpdir());
272
- } catch {
273
- return;
274
- }
275
- const stale = entries
276
- .filter((entry) => entry.startsWith("dashboard-report-playwright-"))
277
- .slice(0, 8);
278
- for (const entry of stale) {
279
- const full = join(tmpdir(), entry);
280
- const info = await stat(full).catch(() => null);
281
- if (info && Date.now() - info.mtimeMs > 30 * 60_000) {
282
- await rm(full, { recursive: true, force: true }).catch(() => {});
283
- }
284
- }
285
- }
286
-
287
- async function launchScreenshotBrowser(
288
- viewport: DashboardScreenshotAttempt["viewport"],
289
- ): Promise<LaunchedScreenshotBrowser> {
290
- const { chromium: playwright } = await import("playwright-core");
291
- const localExecutablePath = localChromiumExecutablePath();
292
- if (localExecutablePath) {
293
- const browser = await playwright.launch({
294
- executablePath: localExecutablePath,
295
- headless: true,
296
- });
297
- return {
298
- browser,
299
- cleanup: async () => {},
300
- newPage: () =>
301
- browser.newPage({
302
- viewport,
303
- deviceScaleFactor: 1,
304
- }),
305
- };
306
- }
307
-
308
- if (isServerlessBrowserRuntime()) {
309
- const { default: chromium } = await import("@sparticuz/chromium-min");
310
- chromium.setGraphicsMode = false;
311
- const packUrl =
312
- process.env.DASHBOARD_REPORT_CHROMIUM_PACK_URL?.trim() ||
313
- DEFAULT_SERVERLESS_CHROMIUM_PACK_URL;
314
- await sweepStaleScreenshotProfiles();
315
- const userDataDir = join(
316
- tmpdir(),
317
- `dashboard-report-playwright-${randomUUID()}`,
318
- );
319
- const cleanup = async () => {
320
- await rm(userDataDir, { recursive: true, force: true }).catch((err) => {
321
- console.error(
322
- "[dashboard-report] Failed to clean Chromium profile:",
323
- errorMessage(err),
324
- );
325
- });
326
- };
327
-
328
- try {
329
- const browser = await playwright.launchPersistentContext(userDataDir, {
330
- args: [
331
- ...chromium.args,
332
- "--disable-dev-shm-usage",
333
- "--disable-gpu",
334
- "--hide-scrollbars",
335
- ],
336
- deviceScaleFactor: 1,
337
- executablePath: await chromium.executablePath(packUrl),
338
- headless: true,
339
- viewport,
340
- });
341
- return {
342
- browser,
343
- cleanup,
344
- newPage: () => browser.newPage(),
345
- };
346
- } catch (err) {
347
- await cleanup();
348
- throw err;
349
- }
350
- }
351
-
352
- const browser = await playwright.launch({ headless: true });
353
- return {
354
- browser,
355
- cleanup: async () => {},
356
- newPage: () =>
357
- browser.newPage({
358
- viewport,
359
- deviceScaleFactor: 1,
360
- }),
361
- };
362
- }
363
-
364
- function screenshotTimeoutMs(): number {
365
- const configured = positiveIntEnv("DASHBOARD_REPORT_SCREENSHOT_TIMEOUT_MS");
366
- if (configured) return configured;
367
- return isServerlessBrowserRuntime()
368
- ? SERVERLESS_SCREENSHOT_TIMEOUT_MS
369
- : LOCAL_SCREENSHOT_TIMEOUT_MS;
370
- }
371
-
372
- function secondReadyTimeoutMs(): number {
373
- const configured = positiveIntEnv("DASHBOARD_REPORT_SECOND_READY_TIMEOUT_MS");
374
- if (configured) return configured;
375
- return isServerlessBrowserRuntime()
376
- ? SERVERLESS_SECOND_READY_TIMEOUT_MS
377
- : screenshotTimeoutMs();
378
- }
379
-
380
- function boundedStageTimeout(capMs: number, deadlineAt?: number): number {
381
- if (!deadlineAt) return capMs;
382
- const remainingMs = deadlineAt - Date.now();
383
- if (remainingMs <= 0) throw new Error("capture deadline exhausted");
384
- return Math.max(1, Math.min(capMs, remainingMs));
385
- }
386
-
387
158
  function reportDeliveryReserveMs(recipientCount: number): number {
388
159
  return (
389
- MAX_CAPTURE_CLEANUP_RESERVE_MS +
390
160
  recipientCount * DASHBOARD_REPORT_EMAIL_TIMEOUT_MS +
391
161
  DASHBOARD_REPORT_EMAIL_OVERHEAD_RESERVE_MS
392
162
  );
393
163
  }
394
164
 
395
- async function runWithinCaptureDeadline<T>(
396
- operation: () => Promise<T>,
397
- deadlineAt?: number,
398
- ): Promise<T> {
399
- if (!deadlineAt) return operation();
400
- const timeoutMs = deadlineAt - Date.now();
401
- if (timeoutMs <= 0) throw new Error("capture deadline exhausted");
402
-
403
- let timeout: ReturnType<typeof setTimeout> | undefined;
404
- try {
405
- return await Promise.race([
406
- operation(),
407
- new Promise<never>((_, reject) => {
408
- timeout = setTimeout(
409
- () => reject(new Error("capture deadline exhausted")),
410
- timeoutMs,
411
- );
412
- }),
413
- ]);
414
- } finally {
415
- if (timeout) clearTimeout(timeout);
416
- }
417
- }
418
-
419
165
  async function runWithinReportDeadline<T>(
420
166
  label: string,
421
167
  operation: () => Promise<T>,
@@ -443,932 +189,6 @@ async function runWithinReportDeadline<T>(
443
189
  }
444
190
  }
445
191
 
446
- function positiveIntEnv(name: string): number | null {
447
- const raw = process.env[name]?.trim();
448
- if (!raw) return null;
449
- const parsed = Number.parseInt(raw, 10);
450
- return Number.isFinite(parsed) && parsed > 0 ? parsed : null;
451
- }
452
-
453
- async function waitForDashboardReportReady(
454
- page: any,
455
- timeout: number,
456
- consoleErrors: string[] = [],
457
- failedRequests: string[] = [],
458
- expectedPanelIds: string[] = [],
459
- ): Promise<boolean> {
460
- try {
461
- await page.waitForFunction(
462
- `(() => {
463
- const root = document.querySelector("[data-dashboard-report-capture]");
464
- if (!root) return false;
465
- if (root.getAttribute("data-dashboard-report-ready") !== "true") {
466
- return false;
467
- }
468
- if (root.querySelector("[data-dashboard-report-loading='true']")) {
469
- return false;
470
- }
471
- // A panel that errored (including its own query-call timeout) clears
472
- // its loading marker just like a successful panel, so without this
473
- // check the capture would treat a broken panel as "ready" and bake
474
- // its raw error text into the delivered screenshot instead of
475
- // failing the attempt so the retry sweep can pick it up.
476
- return !root.querySelector("[role='alert']");
477
- })()`,
478
- undefined,
479
- { timeout },
480
- );
481
- await page.evaluate(`(async () => {
482
- await document.fonts?.ready;
483
- })()`);
484
- await page.waitForTimeout(750);
485
- return true;
486
- } catch (err: any) {
487
- const detail = await page
488
- .evaluate(`(() => {
489
- const root = document.querySelector("[data-dashboard-report-capture]");
490
- const expectedPanelIds = ${JSON.stringify(expectedPanelIds.slice(0, REPORT_PANEL_STATE_DIAGNOSTICS_LIMIT))};
491
- const cleanText = (value, limit = ${REPORT_PANEL_STATE_TEXT_LIMIT}) =>
492
- String(value ?? "").replace(/\\s+/g, " ").trim().slice(0, limit);
493
- const panelStates = expectedPanelIds.map((id) => {
494
- const panel = Array.from(
495
- root?.querySelectorAll("[data-dashboard-report-panel-id]") ?? [],
496
- ).find((node) =>
497
- node.getAttribute("data-dashboard-report-panel-id") === id,
498
- );
499
- if (!panel) return { id: cleanText(id, 96), state: "missing" };
500
- const errorNode = panel.querySelector(
501
- "[data-dashboard-report-panel-error='true'], .text-red-400",
502
- );
503
- const error = cleanText(errorNode?.textContent);
504
- return {
505
- id: cleanText(id, 96),
506
- title: cleanText(panel.getAttribute("data-dashboard-report-panel-title"), 120),
507
- state: panel.querySelector("[data-dashboard-report-loading='true']")
508
- ? "loading"
509
- : error
510
- ? "errored"
511
- : "ready",
512
- ...(error ? { error } : {}),
513
- };
514
- });
515
- return {
516
- ready: root?.getAttribute("data-dashboard-report-ready") ?? null,
517
- panelStates,
518
- url: location.href,
519
- };
520
- })()`)
521
- .catch(() => null);
522
- const captureDiagnostics = { consoleErrors, failedRequests };
523
- const message = detail
524
- ? `${err?.message ?? String(err)}; dashboard state: ${JSON.stringify({
525
- ...detail,
526
- ...captureDiagnostics,
527
- })}`
528
- : `${err?.message ?? String(err)}; dashboard page was not inspectable; capture diagnostics: ${JSON.stringify(captureDiagnostics)}`;
529
- throw new Error(message);
530
- }
531
- }
532
-
533
- const PREWARM_CONCURRENCY = 3;
534
- const PREWARM_PANEL_TIMEOUT_MS = 20_000;
535
- const PREWARM_MAX_BUDGET_MS = 45_000;
536
-
537
- /**
538
- * Runs first-party panel queries once, directly, before the browser capture
539
- * starts, so the capture's own query-dashboard-panel calls hit a warm cache
540
- * instead of several panels racing each other cold for database time inside
541
- * a single capture window — that contention, not any one query alone, is
542
- * what was pushing panels past their capture timeout. Best-effort: a panel
543
- * that fails or times out here is simply computed cold by the capture later,
544
- * exactly as it always was, so this can never make a report worse than
545
- * before it existed. Bounded to time left after reserving the full chunked
546
- * capture attempt and delivery tail, so prewarming cannot starve capture.
547
- * The per-panel timeout only bounds how long a worker waits before logging;
548
- * it is also passed to the database/cache layers, and the original query is
549
- * still awaited before this function returns so it cannot overlap capture.
550
- */
551
- async function prewarmFirstPartyPanelCache(
552
- sub: DashboardReportSubscription,
553
- snapshot: ReportSnapshot,
554
- deadlineAt?: number,
555
- recipientCount = 0,
556
- ): Promise<void> {
557
- const panels = (snapshot.panels ?? []).filter(
558
- (panel) => panel.source === "first-party" && panel.sql != null,
559
- );
560
- if (!panels.length) return;
561
-
562
- const remaining = deadlineAt ? deadlineAt - Date.now() : Infinity;
563
- const budgetMs = Math.max(
564
- 0,
565
- Math.min(
566
- PREWARM_MAX_BUDGET_MS,
567
- deadlineAt
568
- ? remaining -
569
- SERVERLESS_CHUNKED_ATTEMPT_TIMEOUT_MS -
570
- reportDeliveryReserveMs(recipientCount)
571
- : PREWARM_MAX_BUDGET_MS,
572
- ),
573
- );
574
- if (budgetMs <= 0) return;
575
- const prewarmDeadline = Date.now() + budgetMs;
576
-
577
- const vars: Record<string, string> = { ...snapshot.variables };
578
- for (const [key, value] of Object.entries(snapshot.filters)) {
579
- if (key.startsWith("f_")) vars[key.slice(2)] = value;
580
- }
581
- const scope = { userEmail: sub.ownerEmail, orgId: sub.orgId ?? null };
582
-
583
- let index = 0;
584
- async function worker(): Promise<void> {
585
- while (index < panels.length && Date.now() < prewarmDeadline) {
586
- const panel = panels[index++];
587
- const sql = interpolate(serializePanelSql(panel.sql), vars, {
588
- failClosedTimeVariables: true,
589
- });
590
- if (!sql.trim()) continue;
591
- const panelTimeoutMs = Math.max(
592
- 1,
593
- Math.min(PREWARM_PANEL_TIMEOUT_MS, prewarmDeadline - Date.now()),
594
- );
595
- const query = queryFirstPartyAnalytics(sql, scope, {
596
- cache: true,
597
- timeoutMs: panelTimeoutMs,
598
- });
599
- let timeout: ReturnType<typeof setTimeout> | undefined;
600
- try {
601
- await Promise.race([
602
- query,
603
- new Promise<never>((_, reject) => {
604
- timeout = setTimeout(
605
- () => reject(new Error("prewarm panel timeout")),
606
- panelTimeoutMs,
607
- );
608
- timeout.unref?.();
609
- }),
610
- ]);
611
- } catch (err) {
612
- console.warn(
613
- `[dashboard-report] prewarm failed for panel ${panel.id}:`,
614
- err instanceof Error ? err.message : err,
615
- );
616
- } finally {
617
- if (timeout) clearTimeout(timeout);
618
- await query.catch(() => undefined);
619
- }
620
- }
621
- }
622
-
623
- await Promise.all(
624
- Array.from({ length: PREWARM_CONCURRENCY }, () => worker()),
625
- );
626
- }
627
-
628
- async function assertDashboardReportPanelWindow(
629
- page: any,
630
- expectedPanelIds: string[],
631
- ): Promise<void> {
632
- const rawPanelIds = await page.evaluate(`(() =>
633
- document
634
- .querySelector("[data-dashboard-report-capture]")
635
- ?.getAttribute("data-dashboard-report-panel-ids") ?? null
636
- )()`);
637
- let actualPanelIds: unknown;
638
- try {
639
- actualPanelIds =
640
- typeof rawPanelIds === "string" ? JSON.parse(rawPanelIds) : null;
641
- } catch {
642
- actualPanelIds = null;
643
- }
644
- if (
645
- !Array.isArray(actualPanelIds) ||
646
- actualPanelIds.some((panelId) => typeof panelId !== "string") ||
647
- actualPanelIds.length !== expectedPanelIds.length ||
648
- actualPanelIds.some((panelId, index) => panelId !== expectedPanelIds[index])
649
- ) {
650
- throw new DashboardReportPanelMismatchError(
651
- `report chunk panel mismatch; expected=${JSON.stringify(expectedPanelIds)} actual=${JSON.stringify(actualPanelIds)}`,
652
- );
653
- }
654
- }
655
-
656
- async function scrollDashboardForLazyRendering(page: any): Promise<void> {
657
- await page.evaluate(`(async () => {
658
- const wait = (ms) =>
659
- new Promise((resolve) => window.setTimeout(resolve, ms));
660
- const maxY = Math.max(
661
- document.body.scrollHeight,
662
- document.documentElement.scrollHeight,
663
- );
664
- const step = Math.max(600, Math.floor(window.innerHeight * 0.75));
665
- for (let y = 0; y < maxY; y += step) {
666
- window.scrollTo(0, y);
667
- await wait(120);
668
- }
669
- window.scrollTo(0, 0);
670
- })()`);
671
- }
672
-
673
- async function fitViewportWidthToDashboardCapture(
674
- page: any,
675
- capture: any,
676
- viewport: { width: number; height: number },
677
- ): Promise<void> {
678
- const box = await capture.boundingBox();
679
- if (!box) return;
680
-
681
- const width = Math.max(
682
- viewport.width,
683
- Math.min(1800, Math.ceil(box.width + SCREENSHOT_VIEWPORT_PADDING)),
684
- );
685
- if (width === viewport.width) return;
686
-
687
- // Keep the render surface bounded. Playwright's locator screenshot captures
688
- // the full element beyond the viewport, while growing Chromium to the full
689
- // dashboard height can exhaust memory and close the browser on serverless
690
- // workers. Width-only fitting preserves the full dashboard without that
691
- // oversized render surface.
692
- await page.setViewportSize({ width, height: viewport.height });
693
- await page.waitForTimeout(250);
694
- }
695
-
696
- async function scaleDashboardCapture(
697
- page: any,
698
- scale: number | undefined,
699
- ): Promise<void> {
700
- if (!scale || scale >= 1) return;
701
- await page.evaluate(`(() => {
702
- const root = document.querySelector("[data-dashboard-report-capture]");
703
- if (root instanceof HTMLElement) root.style.zoom = "${scale}";
704
- })()`);
705
- await page.waitForTimeout(250);
706
- }
707
-
708
- async function runBoundedBrowserCleanup(
709
- label: string,
710
- operation: () => Promise<void>,
711
- ): Promise<void> {
712
- let timeout: ReturnType<typeof setTimeout> | undefined;
713
- try {
714
- await Promise.race([
715
- operation(),
716
- new Promise<never>((_, reject) => {
717
- timeout = setTimeout(
718
- () => reject(new Error(`${label} exceeded cleanup timeout`)),
719
- BROWSER_CLEANUP_TIMEOUT_MS,
720
- );
721
- }),
722
- ]);
723
- } catch (err) {
724
- console.error(`[dashboard-report] ${label}:`, errorMessage(err));
725
- } finally {
726
- if (timeout) clearTimeout(timeout);
727
- }
728
- }
729
-
730
- const DIAGNOSTICS_PROBE_TIMEOUT_MS = 2_000;
731
- const DIAGNOSTICS_MAX_LENGTH = 700;
732
- const DIAGNOSTICS_COLLECTOR_LIMIT = 5;
733
- const REPORT_PANEL_STATE_DIAGNOSTICS_LIMIT = REPORT_PANEL_CHUNK_SIZE;
734
- const REPORT_PANEL_STATE_TEXT_LIMIT = 160;
735
- const DIAGNOSTICS_URL_LIMIT = 120;
736
- const DIAGNOSTICS_TEXT_SNAPSHOT_LIMIT = 180;
737
- const DIAGNOSTICS_REQUEST_TRACKING_LIMIT = 50;
738
- const DIAGNOSTICS_IN_FLIGHT_SERIALIZATION_LIMIT = 3;
739
-
740
- type InFlightReportRequest = {
741
- method: string;
742
- url: string;
743
- startedAt: number;
744
- };
745
-
746
- type RecentReportResource = {
747
- method: string;
748
- url: string;
749
- status?: number;
750
- ageMs?: number;
751
- outcome: "response" | "finished" | "failed";
752
- };
753
-
754
- function redactDiagnosticUrl(value: unknown): string {
755
- return String(value ?? "")
756
- .replace(
757
- /([?&](?:__an_embed_token|token|access_token|authorization|sql|query)=)[^&\s]*/gi,
758
- "$1[REDACTED]",
759
- )
760
- .slice(0, DIAGNOSTICS_URL_LIMIT);
761
- }
762
-
763
- function sanitizeDiagnosticText(
764
- value: unknown,
765
- limit = DIAGNOSTICS_TEXT_SNAPSHOT_LIMIT,
766
- ): string {
767
- return errorMessage(String(value ?? ""))
768
- .replace(/\b(?:bearer\s+)[a-z0-9._~+/=-]+/gi, "Bearer [REDACTED]")
769
- .replace(
770
- /\b((?:access[_-]?token|auth(?:orization)?|session|cookie)\s*[:=]\s*)[^\s,;"'<>]+/gi,
771
- "$1[REDACTED]",
772
- )
773
- .replace(/\s+/g, " ")
774
- .trim()
775
- .slice(0, limit);
776
- }
777
-
778
- function requestDiagnostic(req: any): InFlightReportRequest {
779
- return {
780
- method: sanitizeDiagnosticText(req.method?.(), 16) || "GET",
781
- url: redactDiagnosticUrl(req.url?.()),
782
- startedAt: Date.now(),
783
- };
784
- }
785
-
786
- function requestDiagnosticPriority(url: string): number {
787
- return /\/(?:_agent-native\/actions|auth|session)(?:\/|[?]|$)|get-sql-dashboard/i.test(
788
- url,
789
- )
790
- ? 1
791
- : 0;
792
- }
793
-
794
- function retainInFlightRequest(
795
- requests: Map<any, InFlightReportRequest>,
796
- req: any,
797
- ) {
798
- if (
799
- !requests.has(req) &&
800
- requests.size >= DIAGNOSTICS_REQUEST_TRACKING_LIMIT
801
- ) {
802
- const discard = [...requests.entries()].sort(([, left], [, right]) => {
803
- const priority =
804
- requestDiagnosticPriority(left.url) -
805
- requestDiagnosticPriority(right.url);
806
- return priority || left.startedAt - right.startedAt;
807
- })[0];
808
- if (discard) requests.delete(discard[0]);
809
- }
810
- requests.set(req, requestDiagnostic(req));
811
- }
812
-
813
- function pushRecentResource(
814
- resources: RecentReportResource[],
815
- resource: RecentReportResource,
816
- ) {
817
- if (resources.length >= DIAGNOSTICS_COLLECTOR_LIMIT) resources.shift();
818
- resources.push(resource);
819
- }
820
-
821
- // netlify.toml's memory = "2gb" is plan-gated and can be silently ignored, so
822
- // capture the actual lambda memory ceiling alongside current RSS.
823
- function memoryDiagnostics(): string {
824
- const lambdaMemoryMb =
825
- process.env.AWS_LAMBDA_FUNCTION_MEMORY_SIZE ?? "unknown";
826
- const rssMb = Math.round(process.memoryUsage().rss / 1024 / 1024);
827
- return `lambdaMemoryMb=${lambdaMemoryMb} rssMb=${rssMb}`;
828
- }
829
-
830
- // Best-effort page inspection used when the report surface never becomes
831
- // visible, so failures carry enough state to tell wrong-page/wedged-renderer/
832
- // auth-bounce apart. Must never throw and must stay bounded even if the page
833
- // is hung.
834
- async function collectPageDiagnostics(
835
- page: any,
836
- consoleErrors: string[],
837
- failedRequests: string[],
838
- inFlightRequests: Map<any, InFlightReportRequest>,
839
- recentResources: RecentReportResource[],
840
- ): Promise<string> {
841
- const memory = memoryDiagnostics();
842
- const pendingRequests = () =>
843
- [...inFlightRequests.values()]
844
- .sort((left, right) => {
845
- const priority =
846
- requestDiagnosticPriority(right.url) -
847
- requestDiagnosticPriority(left.url);
848
- return priority || right.startedAt - left.startedAt;
849
- })
850
- .slice(0, DIAGNOSTICS_IN_FLIGHT_SERIALIZATION_LIMIT)
851
- .map((request) => ({
852
- method: request.method,
853
- url: request.url,
854
- ageMs: Math.max(0, Date.now() - request.startedAt),
855
- }));
856
- try {
857
- let responsive = true;
858
- let probeTimeout: ReturnType<typeof setTimeout> | undefined;
859
- try {
860
- await Promise.race([
861
- Promise.resolve(page.evaluate("1")),
862
- new Promise((_, reject) => {
863
- probeTimeout = setTimeout(
864
- () => reject(new Error("diagnostics probe timed out")),
865
- DIAGNOSTICS_PROBE_TIMEOUT_MS,
866
- );
867
- }),
868
- ]);
869
- } catch {
870
- responsive = false;
871
- } finally {
872
- if (probeTimeout) clearTimeout(probeTimeout);
873
- }
874
-
875
- if (!responsive) {
876
- return `${memory} page unresponsive (renderer hung or crashed); consoleErrors=${JSON.stringify(
877
- consoleErrors,
878
- )} failedRequests=${JSON.stringify(failedRequests)} inFlightRequests=${JSON.stringify(
879
- pendingRequests(),
880
- )} recentResources=${JSON.stringify(recentResources)}`.slice(
881
- 0,
882
- DIAGNOSTICS_MAX_LENGTH,
883
- );
884
- }
885
-
886
- let url = "";
887
- try {
888
- url = page.url();
889
- } catch {
890
- // page may already be closed; leave url empty
891
- }
892
-
893
- let pageState: Record<string, unknown> = {};
894
- let detailsTimeout: ReturnType<typeof setTimeout> | undefined;
895
- try {
896
- // page.evaluate ignores setDefaultTimeout, so race it like the probe —
897
- // a renderer that wedges after the probe must not stall diagnostics.
898
- const details = await Promise.race([
899
- Promise.resolve(
900
- page.evaluate(
901
- `(() => ({
902
- title: document.title,
903
- readyState: document.readyState,
904
- capture: (() => {
905
- const root = document.querySelector("[data-dashboard-report-capture]");
906
- return {
907
- present: Boolean(root),
908
- ready: root?.getAttribute("data-dashboard-report-ready") ?? null,
909
- phase: root?.getAttribute("data-dashboard-report-phase") ?? root?.dataset?.phase ?? null,
910
- fetchState: root?.getAttribute("data-dashboard-report-fetch-state") ?? root?.dataset?.fetchState ?? null,
911
- error: root?.getAttribute("data-dashboard-report-error") ?? root?.dataset?.error ?? null,
912
- childCount: root?.children.length ?? 0,
913
- htmlLength: root?.innerHTML.length ?? 0,
914
- textLength: root?.textContent.length ?? 0,
915
- };
916
- })(),
917
- bodyTextSnapshot: document.body?.textContent?.replace(/\\s+/g, " ").trim().slice(0, ${DIAGNOSTICS_TEXT_SNAPSHOT_LIMIT}) ?? "",
918
- }))()`,
919
- ),
920
- ),
921
- new Promise<never>((_, reject) => {
922
- detailsTimeout = setTimeout(
923
- () => reject(new Error("diagnostics details timed out")),
924
- DIAGNOSTICS_PROBE_TIMEOUT_MS,
925
- );
926
- }),
927
- ]);
928
- const raw = details as any;
929
- pageState = {
930
- title: sanitizeDiagnosticText(raw?.title),
931
- readyState: sanitizeDiagnosticText(raw?.readyState, 32),
932
- capture: raw?.capture
933
- ? {
934
- present: Boolean(raw.capture.present),
935
- ready: sanitizeDiagnosticText(raw.capture.ready, 32) || null,
936
- phase: sanitizeDiagnosticText(raw.capture.phase, 80) || null,
937
- fetchState:
938
- sanitizeDiagnosticText(raw.capture.fetchState, 80) || null,
939
- error: sanitizeDiagnosticText(raw.capture.error) || null,
940
- childCount: Number.isFinite(raw.capture.childCount)
941
- ? raw.capture.childCount
942
- : 0,
943
- htmlLength: Number.isFinite(raw.capture.htmlLength)
944
- ? raw.capture.htmlLength
945
- : 0,
946
- textLength: Number.isFinite(raw.capture.textLength)
947
- ? raw.capture.textLength
948
- : 0,
949
- }
950
- : { present: false },
951
- bodyTextSnapshot: sanitizeDiagnosticText(raw?.bodyTextSnapshot),
952
- };
953
- } catch {
954
- // best effort; leave title/bodyText empty
955
- } finally {
956
- if (detailsTimeout) clearTimeout(detailsTimeout);
957
- }
958
-
959
- const { capture, readyState, title, bodyTextSnapshot } = pageState;
960
- return `${memory} page state: ${JSON.stringify({
961
- capture,
962
- readyState,
963
- inFlightRequests: pendingRequests(),
964
- recentResources,
965
- url: redactDiagnosticUrl(url),
966
- title,
967
- bodyTextSnapshot,
968
- consoleErrors,
969
- failedRequests,
970
- })}`.slice(0, DIAGNOSTICS_MAX_LENGTH);
971
- } catch {
972
- return `${memory} diagnostics unavailable`;
973
- }
974
- }
975
-
976
- function reportChunkOffsets(panelCount: number): number[] {
977
- if (panelCount === 0) return [0];
978
- return Array.from(
979
- { length: Math.ceil(panelCount / REPORT_PANEL_CHUNK_SIZE) },
980
- (_, index) => index * REPORT_PANEL_CHUNK_SIZE,
981
- );
982
- }
983
-
984
- function screenshotUrlForChunk(
985
- sub: DashboardReportSubscription,
986
- snapshot: ReportSnapshot,
987
- offset: number,
988
- ): { token: string; url: string } {
989
- const targetPath = buildDashboardPath(
990
- snapshot.dashboardId,
991
- snapshot.filters,
992
- { reportScreenshot: true },
993
- );
994
- const targetUrl = new URL(targetPath, "https://agent-native.invalid/");
995
- targetUrl.searchParams.set("reportPanelOffset", String(offset));
996
- targetUrl.searchParams.set(
997
- "reportPanelLimit",
998
- String(REPORT_PANEL_CHUNK_SIZE),
999
- );
1000
- const signedTargetPath = `${targetUrl.pathname}${targetUrl.search}`;
1001
- const token = signEmbedSessionToken({
1002
- ownerEmail: sub.ownerEmail,
1003
- orgId: sub.orgId,
1004
- targetPath: signedTargetPath,
1005
- scope: `dashboard-report-screenshot:${sub.id}`,
1006
- ttlSeconds: 5 * 60,
1007
- });
1008
- const url = new URL(signedTargetPath, `${dashboardBaseUrl()}/`);
1009
- url.searchParams.set(EMBED_MODE_QUERY_PARAM, "1");
1010
- url.searchParams.set(EMBED_TOKEN_QUERY_PARAM, token);
1011
- return { token, url: url.toString() };
1012
- }
1013
-
1014
- async function captureDashboardChunk(
1015
- page: any,
1016
- attempt: DashboardScreenshotAttempt,
1017
- token: string,
1018
- screenshotUrl: string,
1019
- expectedPanelIds: string[],
1020
- deadlineAt?: number,
1021
- ): Promise<Buffer> {
1022
- const timeout = screenshotTimeoutMs();
1023
- let captureStage = "pre-seeding the embed session";
1024
- const consoleErrors: string[] = [];
1025
- const failedRequests: string[] = [];
1026
- const inFlightRequests = new Map<any, InFlightReportRequest>();
1027
- const recentResources: RecentReportResource[] = [];
1028
- page.on("console", (msg: any) => {
1029
- if (
1030
- msg.type() !== "error" ||
1031
- consoleErrors.length >= DIAGNOSTICS_COLLECTOR_LIMIT
1032
- )
1033
- return;
1034
- consoleErrors.push(sanitizeDiagnosticText(msg.text()));
1035
- });
1036
- page.on("request", (req: any) => {
1037
- retainInFlightRequest(inFlightRequests, req);
1038
- });
1039
- page.on("requestfailed", (req: any) => {
1040
- const request = inFlightRequests.get(req) ?? requestDiagnostic(req);
1041
- inFlightRequests.delete(req);
1042
- pushRecentResource(recentResources, {
1043
- method: request.method,
1044
- url: request.url,
1045
- ageMs: Math.max(0, Date.now() - request.startedAt),
1046
- outcome: "failed",
1047
- });
1048
- if (failedRequests.length >= DIAGNOSTICS_COLLECTOR_LIMIT) return;
1049
- failedRequests.push(
1050
- `${request.method} ${request.url}: ${sanitizeDiagnosticText(req.failure()?.errorText ?? "failed")}`,
1051
- );
1052
- });
1053
- page.on("response", (res: any) => {
1054
- const req = res.request();
1055
- const request = inFlightRequests.get(req) ?? requestDiagnostic(req);
1056
- inFlightRequests.delete(req);
1057
- pushRecentResource(recentResources, {
1058
- method: request.method,
1059
- url: request.url,
1060
- status: res.status(),
1061
- ageMs: Math.max(0, Date.now() - request.startedAt),
1062
- outcome: "response",
1063
- });
1064
- if (
1065
- res.status() < 400 ||
1066
- failedRequests.length >= DIAGNOSTICS_COLLECTOR_LIMIT
1067
- )
1068
- return;
1069
- failedRequests.push(
1070
- `${request.method} ${request.url}: HTTP ${res.status()}`,
1071
- );
1072
- });
1073
- page.on("requestfinished", (req: any) => {
1074
- const request = inFlightRequests.get(req);
1075
- if (!request) return;
1076
- inFlightRequests.delete(req);
1077
- pushRecentResource(recentResources, {
1078
- method: request.method,
1079
- url: request.url,
1080
- ageMs: Math.max(0, Date.now() - request.startedAt),
1081
- outcome: "finished",
1082
- });
1083
- });
1084
- try {
1085
- try {
1086
- await page.context().addCookies([
1087
- {
1088
- name: EMBED_SESSION_COOKIE,
1089
- value: token,
1090
- url: `${dashboardBaseUrl()}/`,
1091
- },
1092
- ]);
1093
- } catch (err) {
1094
- console.warn(
1095
- "[dashboard-report] Failed to pre-seed embed session cookie:",
1096
- errorMessage(err),
1097
- );
1098
- }
1099
- page.setDefaultTimeout(boundedStageTimeout(timeout, deadlineAt));
1100
- await page.emulateMedia({ media: "screen", colorScheme: "light" });
1101
- await page.addInitScript(() =>
1102
- window.localStorage.setItem("theme", "light"),
1103
- );
1104
- captureStage = "navigating to the report chunk";
1105
- await page.goto(screenshotUrl, {
1106
- waitUntil: "domcontentloaded",
1107
- timeout: boundedStageTimeout(timeout, deadlineAt),
1108
- });
1109
- const capture = page.locator("[data-dashboard-report-capture]");
1110
- captureStage = "waiting for the report chunk surface";
1111
- try {
1112
- await capture.waitFor({
1113
- state: "visible",
1114
- timeout: boundedStageTimeout(timeout, deadlineAt),
1115
- });
1116
- } catch (err) {
1117
- const diagnostics = errorMessage(
1118
- await collectPageDiagnostics(
1119
- page,
1120
- consoleErrors,
1121
- failedRequests,
1122
- inFlightRequests,
1123
- recentResources,
1124
- ),
1125
- );
1126
- throw new Error(`${errorMessage(err)}; ${diagnostics}`);
1127
- }
1128
- captureStage = "waiting for report chunk queries";
1129
- await waitForDashboardReportReady(
1130
- page,
1131
- boundedStageTimeout(attempt.readyTimeout ?? timeout, deadlineAt),
1132
- consoleErrors,
1133
- failedRequests,
1134
- expectedPanelIds,
1135
- );
1136
- captureStage = "validating the report chunk panels";
1137
- await assertDashboardReportPanelWindow(page, expectedPanelIds);
1138
- captureStage = "rendering lazy report chunk panels";
1139
- await scrollDashboardForLazyRendering(page);
1140
- captureStage = "waiting for lazy report chunk panels";
1141
- await waitForDashboardReportReady(
1142
- page,
1143
- boundedStageTimeout(
1144
- attempt.secondReadyTimeout ?? secondReadyTimeoutMs(),
1145
- deadlineAt,
1146
- ),
1147
- consoleErrors,
1148
- failedRequests,
1149
- expectedPanelIds,
1150
- );
1151
- captureStage = "revalidating the report chunk panels";
1152
- await assertDashboardReportPanelWindow(page, expectedPanelIds);
1153
- captureStage = "sizing the report chunk";
1154
- await fitViewportWidthToDashboardCapture(page, capture, attempt.viewport);
1155
- await scaleDashboardCapture(page, attempt.captureScale);
1156
- await capture.scrollIntoViewIfNeeded();
1157
- captureStage = "rasterizing the report chunk PNG";
1158
- page.setDefaultTimeout(boundedStageTimeout(timeout, deadlineAt));
1159
- const image = await capture.screenshot({
1160
- type: "png",
1161
- animations: "disabled",
1162
- });
1163
- if (!image?.length) throw new Error("Dashboard screenshot was empty");
1164
- return Buffer.from(image);
1165
- } catch (err) {
1166
- if (err instanceof DashboardReportPanelMismatchError) throw err;
1167
- throw new Error(`${captureStage}: ${errorMessage(err)}`);
1168
- }
1169
- }
1170
-
1171
- async function captureDashboardPngChunks(
1172
- sub: DashboardReportSubscription,
1173
- snapshot: ReportSnapshot,
1174
- allowPartialCapture: boolean,
1175
- totalTimeoutMs?: number,
1176
- ): Promise<DashboardPngCapture> {
1177
- const offsets = reportChunkOffsets(snapshot.panelIds.length);
1178
- if (offsets.length > MAX_DASHBOARD_REPORT_CHUNKS) {
1179
- throw new Error(
1180
- `complete dashboard requires ${offsets.length} image chunks; email delivery supports at most ${MAX_DASHBOARD_REPORT_CHUNKS}`,
1181
- );
1182
- }
1183
- const serverless = isServerlessBrowserRuntime();
1184
- const attempt: DashboardScreenshotAttempt = {
1185
- label: "chunked",
1186
- viewport: { width: 1200, height: 1400 },
1187
- captureScale: 0.7,
1188
- ...(serverless
1189
- ? {
1190
- readyTimeout: DASHBOARD_REPORT_READY_TIMEOUT_MS,
1191
- secondReadyTimeout: 15_000,
1192
- totalTimeout: totalTimeoutMs ?? SERVERLESS_CHUNKED_ATTEMPT_TIMEOUT_MS,
1193
- }
1194
- : {}),
1195
- };
1196
- let browser: any;
1197
- let cleanup = async () => {};
1198
- let launchPromise: Promise<LaunchedScreenshotBrowser> | undefined;
1199
- let launchTimeout: ReturnType<typeof setTimeout> | undefined;
1200
- let attemptTimedOut = false;
1201
- const deadlineAt = attempt.totalTimeout
1202
- ? Date.now() + attempt.totalTimeout
1203
- : undefined;
1204
- const attemptTimeout = attempt.totalTimeout
1205
- ? setTimeout(() => {
1206
- attemptTimedOut = true;
1207
- if (browser) void browser.close().catch(() => {});
1208
- }, attempt.totalTimeout)
1209
- : null;
1210
- const images: Array<Buffer | null> = Array(offsets.length).fill(null);
1211
- try {
1212
- launchPromise = launchScreenshotBrowser(attempt.viewport);
1213
- const launched = attempt.totalTimeout
1214
- ? await Promise.race([
1215
- launchPromise,
1216
- new Promise<never>((_, reject) => {
1217
- launchTimeout = setTimeout(
1218
- () =>
1219
- reject(
1220
- new Error(
1221
- `${attempt.label} browser launch exceeded ${attempt.totalTimeout}ms`,
1222
- ),
1223
- ),
1224
- attempt.totalTimeout,
1225
- );
1226
- }),
1227
- ])
1228
- : await launchPromise;
1229
- browser = launched.browser;
1230
- cleanup = launched.cleanup;
1231
- let attachmentBytes = 0;
1232
- for (const [index, offset] of offsets.entries()) {
1233
- if (attemptTimedOut)
1234
- throw new Error(`capture exceeded ${attempt.totalTimeout}ms`);
1235
- const page = await runWithinCaptureDeadline(
1236
- () => launched.newPage(),
1237
- deadlineAt,
1238
- );
1239
- try {
1240
- const { token, url } = screenshotUrlForChunk(sub, snapshot, offset);
1241
- const expectedPanelIds = snapshot.panelIds.slice(
1242
- offset,
1243
- offset + REPORT_PANEL_CHUNK_SIZE,
1244
- );
1245
- const image = await runWithinCaptureDeadline(
1246
- () =>
1247
- captureDashboardChunk(
1248
- page,
1249
- attempt,
1250
- token,
1251
- url,
1252
- expectedPanelIds,
1253
- deadlineAt,
1254
- ),
1255
- deadlineAt,
1256
- );
1257
- attachmentBytes += image.length;
1258
- if (attachmentBytes > MAX_DASHBOARD_REPORT_ATTACHMENT_BYTES) {
1259
- throw new Error(
1260
- `complete dashboard images total ${attachmentBytes} bytes; email delivery supports at most ${MAX_DASHBOARD_REPORT_ATTACHMENT_BYTES} bytes`,
1261
- );
1262
- }
1263
- images[index] = image;
1264
- } finally {
1265
- await runBoundedBrowserCleanup("Failed to close screenshot page", () =>
1266
- page.close(),
1267
- );
1268
- }
1269
- }
1270
- return { pngs: images, mode: "full" };
1271
- } catch (err) {
1272
- const partialCapture =
1273
- allowPartialCapture &&
1274
- !(err instanceof DashboardReportPanelMismatchError) &&
1275
- images.some((image) => image !== null);
1276
- const suffix = attemptTimedOut
1277
- ? `${memoryDiagnostics()} ${attempt.label} capture exceeded ${attempt.totalTimeout}ms: ${errorMessage(err)}`
1278
- : `${attempt.label}: ${errorMessage(err)}`;
1279
- if (partialCapture) {
1280
- return {
1281
- pngs: images,
1282
- mode: "partial",
1283
- error: suffix.includes("lambdaMemoryMb=")
1284
- ? suffix
1285
- : `${suffix}; ${memoryDiagnostics()}`,
1286
- };
1287
- }
1288
- if (attemptTimedOut) {
1289
- throw new Error(suffix);
1290
- }
1291
- throw new Error(suffix);
1292
- } finally {
1293
- if (attemptTimeout) clearTimeout(attemptTimeout);
1294
- if (launchTimeout) clearTimeout(launchTimeout);
1295
- if (!browser && launchPromise) {
1296
- void launchPromise.then(
1297
- async (lateBrowser) => {
1298
- await runBoundedBrowserCleanup(
1299
- "Failed to close late screenshot browser",
1300
- () => lateBrowser.browser.close(),
1301
- );
1302
- await runBoundedBrowserCleanup(
1303
- "Failed to clean late Chromium profile",
1304
- lateBrowser.cleanup,
1305
- );
1306
- },
1307
- () => {},
1308
- );
1309
- }
1310
- if (browser) {
1311
- await runBoundedBrowserCleanup("Failed to close screenshot browser", () =>
1312
- browser.close(),
1313
- );
1314
- }
1315
- await runBoundedBrowserCleanup("Failed to clean Chromium profile", cleanup);
1316
- }
1317
- }
1318
-
1319
- function errorMessage(err: unknown): string {
1320
- const message = err instanceof Error ? err.message : String(err);
1321
- return message.replace(
1322
- new RegExp(`(${EMBED_TOKEN_QUERY_PARAM}=)[^&\\s]+`, "g"),
1323
- "$1[REDACTED]",
1324
- );
1325
- }
1326
-
1327
- async function captureDashboardPngWithFallback(
1328
- sub: DashboardReportSubscription,
1329
- snapshot: ReportSnapshot,
1330
- allowPartialCapture: boolean,
1331
- totalTimeoutMs?: number,
1332
- ): Promise<DashboardPngCapture> {
1333
- if (totalTimeoutMs !== undefined && totalTimeoutMs <= 0) {
1334
- return {
1335
- pngs: null,
1336
- mode: "none",
1337
- error: `report delivery deadline left no time for capture; ${memoryDiagnostics()}`,
1338
- };
1339
- }
1340
- try {
1341
- const capture = await captureDashboardPngChunks(
1342
- sub,
1343
- snapshot,
1344
- allowPartialCapture,
1345
- totalTimeoutMs,
1346
- );
1347
- if (isServerlessBrowserRuntime()) {
1348
- console.info(
1349
- `[dashboard-report] ${capture.mode} chunked capture finished: chunks=${capture.pngs?.filter(Boolean).length ?? 0}/${capture.pngs?.length ?? 0} ${memoryDiagnostics()}`,
1350
- );
1351
- }
1352
- if (capture.mode === "partial") {
1353
- console.error(
1354
- `[dashboard-report] partial chunked screenshot capture for subscription ${sub.id}:`,
1355
- capture.error,
1356
- );
1357
- }
1358
- return capture;
1359
- } catch (err) {
1360
- const rawError = errorMessage(err).replace(/\s+/g, " ").trim();
1361
- const error = rawError.includes("lambdaMemoryMb=")
1362
- ? rawError
1363
- : `${rawError}; ${memoryDiagnostics()}`;
1364
- console.error(
1365
- `[dashboard-report] complete chunked screenshot failed for subscription ${sub.id}:`,
1366
- error,
1367
- );
1368
- return { pngs: null, mode: "none", error };
1369
- }
1370
- }
1371
-
1372
192
  function reportDate(snapshot: ReportSnapshot): string {
1373
193
  return new Date(snapshot.generatedAt).toLocaleDateString("en-US", {
1374
194
  year: "numeric",
@@ -1377,165 +197,114 @@ function reportDate(snapshot: ReportSnapshot): string {
1377
197
  });
1378
198
  }
1379
199
 
1380
- function renderReportEmailHtml(
1381
- snapshot: ReportSnapshot,
1382
- options: {
1383
- screenshotParts: Array<Buffer | null>;
1384
- },
1385
- ): string {
1386
- const title = escapeHtml(snapshot.title);
1387
- const dashboardUrl = escapeHtml(snapshot.dashboardUrl);
1388
- const reportSettingsUrl = escapeHtml(snapshot.reportSettingsUrl);
1389
- const date = escapeHtml(reportDate(snapshot));
1390
- const screenshotBlock = options.screenshotParts.some(Boolean)
1391
- ? options.screenshotParts
1392
- .map((screenshot, index) =>
1393
- screenshot
1394
- ? `<a href="${dashboardUrl}" style="display:block;text-decoration:none;">
1395
- <img src="cid:${DASHBOARD_REPORT_CID}-${index + 1}" alt="${title}${options.screenshotParts.length > 1 ? ` (part ${index + 1})` : ""}" width="100%" style="display:block;width:100%;max-width:1280px;height:auto;border:0;outline:0;border-radius:0;" />
1396
- </a>`
1397
- : `<div style="margin:18px 0;padding:14px 16px;border:1px solid #e5e7eb;border-radius:8px;background:#f9fafb;color:#374151;font-size:14px;line-height:1.5;">
1398
- Dashboard image part ${index + 1} was unavailable for this run. Open the live dashboard to view the latest report.
1399
- </div>`,
1400
- )
1401
- .join("\n")
1402
- : `<div style="margin:18px 0;padding:14px 16px;border:1px solid #e5e7eb;border-radius:8px;background:#f9fafb;color:#374151;font-size:14px;line-height:1.5;">
1403
- The dashboard image was unavailable for this run. Open the live dashboard to view the latest report.
1404
- </div>`;
1405
-
1406
- return `<!doctype html>
1407
- <html>
1408
- <body style="margin:0;padding:24px;background:#ffffff;color:#171717;font-family:Inter,Arial,sans-serif;">
1409
- <p style="margin:0 0 12px;font-size:15px;line-height:1.4;font-weight:600;">
1410
- Here's your report of <a href="${dashboardUrl}" style="color:#2563eb;text-decoration:none;">${title}</a> for ${date}
1411
- </p>
1412
- ${screenshotBlock}
1413
- <p style="margin:18px 0 0;color:#525866;font-size:13px;line-height:1.45;">
1414
- <a href="${dashboardUrl}" style="color:#2563eb;text-decoration:none;">Open dashboard</a>
1415
- <span style="color:#9ca3af;"> · </span>
1416
- <a href="${reportSettingsUrl}" style="color:#2563eb;text-decoration:none;">Edit subscription settings</a>
1417
- </p>
1418
- </body>
1419
- </html>`;
1420
- }
1421
-
1422
- function renderReportText(
1423
- snapshot: ReportSnapshot,
1424
- options: {
1425
- screenshotParts: Array<Buffer | null>;
1426
- },
1427
- ): string {
1428
- const lines = [
1429
- `Daily dashboard report: ${snapshot.title}`,
1430
- `Date: ${reportDate(snapshot)}`,
1431
- `Open dashboard: ${snapshot.dashboardUrl}`,
1432
- `Edit subscription settings: ${snapshot.reportSettingsUrl}`,
1433
- ];
1434
- if (!options.screenshotParts.some(Boolean)) {
1435
- lines.push("Dashboard image unavailable for this run.");
1436
- } else {
1437
- for (const [index, screenshot] of options.screenshotParts.entries()) {
1438
- if (!screenshot)
1439
- lines.push(
1440
- `Dashboard image part ${index + 1} unavailable for this run.`,
1441
- );
1442
- }
1443
- }
1444
- return lines.join("\n");
1445
- }
1446
-
1447
- function reportFilename(title: string, part: number, total: number): string {
1448
- const slug = title
1449
- .toLowerCase()
1450
- .replace(/[^a-z0-9]+/g, "-")
1451
- .replace(/^-|-$/g, "")
1452
- .slice(0, 64);
1453
- const suffix = total > 1 ? `-part-${part}` : "";
1454
- return `${slug || "dashboard"}-report${suffix}.png`;
1455
- }
1456
-
200
+ /**
201
+ * Renders and emails one dashboard report entirely on the server: each panel's
202
+ * query runs through the same source dispatcher the UI uses, charts are drawn
203
+ * as SVG and rasterized, and everything else becomes real email HTML.
204
+ *
205
+ * There is deliberately no headless browser here. The previous implementation
206
+ * screenshotted the live React dashboard in 4-panel chunks inside one
207
+ * serverless invocation, so a single slow panel abandoned every later chunk and
208
+ * shipped an email full of "image part N was unavailable" placeholders. Do not
209
+ * reintroduce a browser, a chunk loop, or a mode that emails a report the
210
+ * caller cannot tell apart from a complete one.
211
+ */
1457
212
  export async function sendDashboardReportSubscription(
1458
213
  sub: DashboardReportSubscription,
1459
214
  options: {
1460
- requireScreenshot?: boolean;
1461
- skipEmailWithoutScreenshot?: boolean;
215
+ skipEmailWhenDegraded?: boolean;
1462
216
  deadlineAt?: number;
1463
217
  onCaptureOutcome?: (
1464
218
  outcome: DashboardReportCaptureOutcome,
1465
219
  ) => Promise<void>;
1466
220
  } = {},
1467
- ): Promise<{
1468
- dashboardUrl: string;
1469
- recipientCount: number;
1470
- screenshotAttached: boolean;
1471
- screenshotMode: "full" | "partial" | "none";
1472
- screenshotError?: string;
1473
- emailsSent: boolean;
1474
- }> {
221
+ ): Promise<DashboardReportResult> {
1475
222
  const recipients = normalizeDashboardReportRecipients(sub.recipients);
1476
223
  const snapshot = await runWithinReportDeadline(
1477
224
  "Dashboard report snapshot",
1478
225
  () => collectReportSnapshot(sub),
1479
226
  options.deadlineAt,
1480
227
  );
1481
- try {
1482
- await prewarmFirstPartyPanelCache(
1483
- sub,
1484
- snapshot,
1485
- options.deadlineAt,
1486
- recipients.length,
1487
- );
1488
- } catch (err) {
1489
- console.warn(
1490
- "[dashboard-report] panel cache prewarm failed (non-fatal):",
1491
- err instanceof Error ? err.message : err,
1492
- );
1493
- }
1494
- const captureTimeoutMs = options.deadlineAt
1495
- ? Math.min(
1496
- SERVERLESS_CHUNKED_ATTEMPT_TIMEOUT_MS,
1497
- options.deadlineAt -
1498
- Date.now() -
1499
- reportDeliveryReserveMs(recipients.length),
1500
- )
1501
- : undefined;
1502
- const capture = await captureDashboardPngWithFallback(
1503
- sub,
228
+
229
+ const emailReserveMs = reportDeliveryReserveMs(recipients.length);
230
+ const panelData = await fetchReportPanelData({
231
+ ownerEmail: sub.ownerEmail,
232
+ orgId: sub.orgId,
1504
233
  snapshot,
1505
- !options.skipEmailWithoutScreenshot && !options.requireScreenshot,
1506
- captureTimeoutMs,
234
+ ...(options.deadlineAt
235
+ ? { deadlineAt: options.deadlineAt - emailReserveMs }
236
+ : {}),
237
+ });
238
+
239
+ // Only panels that were actually queried can vote on total failure. Counting
240
+ // never-queryable panels (extensions) as survivors would let a dashboard of
241
+ // pure placeholders pass this guard and ship as "complete".
242
+ const attemptedPanelIds = [...panelData.keys()].filter(
243
+ (panelId) => panelData.get(panelId)?.status !== "not-emailable",
1507
244
  );
1508
- await options.onCaptureOutcome?.({
1509
- mode: capture.mode,
1510
- ...(capture.error ? { error: capture.error } : {}),
245
+ const failedPanelIds = attemptedPanelIds.filter((panelId) => {
246
+ const data = panelData.get(panelId);
247
+ return (
248
+ data?.status === "query-failed" || data?.status === "missing-credential"
249
+ );
1511
250
  });
1512
- if (capture.mode !== "full" && options.requireScreenshot) {
251
+ if (
252
+ attemptedPanelIds.length > 0 &&
253
+ failedPanelIds.length === attemptedPanelIds.length
254
+ ) {
255
+ const firstError = failedPanelIds
256
+ .map((panelId) => {
257
+ const data = panelData.get(panelId);
258
+ return data && "message" in data ? data.message : "";
259
+ })
260
+ .find(Boolean);
261
+ await options.onCaptureOutcome?.({
262
+ mode: "none",
263
+ error: `every dashboard panel failed to load: ${firstError ?? "unknown error"}`,
264
+ });
1513
265
  throw new Error(
1514
- capture.error
1515
- ? `Dashboard screenshot unavailable: ${capture.error}`
1516
- : "Dashboard screenshot unavailable",
266
+ `Dashboard report has no usable data: every one of ${attemptedPanelIds.length} panels failed (${firstError ?? "unknown error"})`,
1517
267
  );
1518
268
  }
1519
- if (capture.mode !== "full" && options.skipEmailWithoutScreenshot) {
269
+
270
+ const rendered = await runWithinReportDeadline(
271
+ "Dashboard report rendering",
272
+ () => renderReportEmail({ snapshot, panelData }),
273
+ options.deadlineAt ? options.deadlineAt - emailReserveMs : undefined,
274
+ );
275
+ // A dashboard whose only reportable panels are extensions renders nothing but
276
+ // "open the dashboard" links. Nothing failed, so degradedPanelIds is empty —
277
+ // but the report is not backed by data and must not claim to be complete. A
278
+ // section-only dashboard (panelData empty) has nothing to render and is fine.
279
+ const noPanelBackedByData =
280
+ panelData.size > 0 && attemptedPanelIds.length === 0;
281
+ const reportMode: DashboardReportMode =
282
+ rendered.degradedPanelIds.length || noPanelBackedByData
283
+ ? "degraded"
284
+ : "complete";
285
+ const reportError = rendered.degradedPanelIds.length
286
+ ? `${rendered.degradedPanelIds.length} of ${panelData.size} panels could not be rendered: ${rendered.degradedPanelIds.join(", ")}`
287
+ : noPanelBackedByData
288
+ ? "No panel in this dashboard can be rendered into an email"
289
+ : undefined;
290
+
291
+ await options.onCaptureOutcome?.({
292
+ mode: reportMode === "complete" ? "full" : "partial",
293
+ ...(reportError ? { error: reportError } : {}),
294
+ });
295
+
296
+ if (reportMode === "degraded" && options.skipEmailWhenDegraded) {
1520
297
  return {
1521
298
  dashboardUrl: snapshot.dashboardUrl,
1522
299
  recipientCount: recipients.length,
1523
- screenshotAttached: false,
1524
- screenshotMode: capture.mode,
300
+ reportMode,
301
+ degradedPanelIds: rendered.degradedPanelIds,
1525
302
  emailsSent: false,
1526
- ...(capture.error ? { screenshotError: capture.error } : {}),
303
+ ...(reportError ? { reportError } : {}),
1527
304
  };
1528
305
  }
1529
- const screenshotAttached = Boolean(capture.pngs?.some(Boolean));
1530
- const screenshotParts = capture.pngs ?? [];
1531
- const html = renderReportEmailHtml(snapshot, {
1532
- screenshotParts,
1533
- });
1534
- const text = renderReportText(snapshot, {
1535
- screenshotParts,
1536
- });
1537
- const subject = `Daily dashboard: ${snapshot.title}`;
1538
306
 
307
+ const subject = `Daily dashboard: ${snapshot.title} — ${reportDate(snapshot)}`;
1539
308
  for (const to of recipients) {
1540
309
  const emailTimeoutMs = options.deadlineAt
1541
310
  ? Math.min(
@@ -1551,27 +320,11 @@ export async function sendDashboardReportSubscription(
1551
320
  await sendEmail({
1552
321
  to,
1553
322
  subject,
1554
- html,
1555
- text,
1556
- attachments: capture.pngs
1557
- ? capture.pngs.flatMap((png, index) =>
1558
- png
1559
- ? [
1560
- {
1561
- filename: reportFilename(
1562
- snapshot.title,
1563
- index + 1,
1564
- capture.pngs!.length,
1565
- ),
1566
- content: png,
1567
- contentType: "image/png",
1568
- contentId: `${DASHBOARD_REPORT_CID}-${index + 1}`,
1569
- disposition: "inline",
1570
- },
1571
- ]
1572
- : [],
1573
- )
1574
- : undefined,
323
+ html: rendered.html,
324
+ text: rendered.text,
325
+ ...(rendered.attachments.length
326
+ ? { attachments: rendered.attachments }
327
+ : {}),
1575
328
  timeoutMs: emailTimeoutMs,
1576
329
  });
1577
330
  }
@@ -1579,9 +332,9 @@ export async function sendDashboardReportSubscription(
1579
332
  return {
1580
333
  dashboardUrl: snapshot.dashboardUrl,
1581
334
  recipientCount: recipients.length,
1582
- screenshotAttached,
1583
- screenshotMode: capture.mode,
335
+ reportMode,
336
+ degradedPanelIds: rendered.degradedPanelIds,
1584
337
  emailsSent: true,
1585
- ...(capture.error ? { screenshotError: capture.error } : {}),
338
+ ...(reportError ? { reportError } : {}),
1586
339
  };
1587
340
  }