@agent-native/core 0.169.1 → 0.171.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 (463) hide show
  1. package/agent-native.eject.json +4 -1
  2. package/bin/agent-native.js +23 -5
  3. package/corpus/README.md +1 -1
  4. package/corpus/templates/analytics/.agents/skills/secrets/SKILL.md +11 -4
  5. package/corpus/templates/analytics/actions/query-agent-native-analytics.ts +1 -1
  6. package/corpus/templates/analytics/app/i18n-data.ts +28 -0
  7. package/corpus/templates/analytics/app/pages/Agents.tsx +25 -1
  8. package/corpus/templates/analytics/app/routes/$.tsx +10 -0
  9. package/corpus/templates/analytics/app/routes.ts +3 -1
  10. package/corpus/templates/analytics/changelog/2026-08-22-fixed-the-agent-native-templates-first-party-dashboard-panel.md +6 -0
  11. package/corpus/templates/analytics/changelog/2026-08-22-org-admin-panels-no-longer-report-a-database-error-as-a-per.md +9 -0
  12. package/corpus/templates/analytics/changelog/2026-08-22-slack-requests-report-invalid-inputs.md +6 -0
  13. package/corpus/templates/analytics/changelog/2026-08-22-unknown-analytics-links-now-return-a-real-not-found-status.md +6 -0
  14. package/corpus/templates/analytics/docs/schemas/first-party-analytics.md +2 -1
  15. package/corpus/templates/analytics/docs/schemas/tracked-events.md +2 -0
  16. package/corpus/templates/analytics/scripts/emit-netlify-dashboard-report-cron.ts +29 -7
  17. package/corpus/templates/analytics/server/handlers/slack.ts +59 -5
  18. package/corpus/templates/analytics/server/lib/db-admin-connections.ts +11 -6
  19. package/corpus/templates/analytics/server/lib/first-party-analytics.ts +132 -2
  20. package/corpus/templates/analytics/server/lib/slack.ts +4 -2
  21. package/corpus/templates/analytics/vitest.config.ts +6 -1
  22. package/corpus/templates/assets/.agents/skills/secrets/SKILL.md +11 -4
  23. package/corpus/templates/assets/app/routes/library.tsx +5 -3
  24. package/corpus/templates/assets/app/routes.ts +3 -1
  25. package/corpus/templates/assets/changelog/2026-08-22-library-page-loads-again-instead-of-crashing-on-open.md +6 -0
  26. package/corpus/templates/assets/vitest.config.ts +6 -1
  27. package/corpus/templates/brain/.agents/skills/secrets/SKILL.md +11 -4
  28. package/corpus/templates/brain/app/components/ui/pointer-lock.ts +1 -0
  29. package/corpus/templates/brain/app/routes/sources.tsx +8 -3
  30. package/corpus/templates/brain/changelog/2026-08-22-tuning-or-adding-a-source-no-longer-leaves-the-sources-page.md +6 -0
  31. package/corpus/templates/brain/vitest.config.ts +1 -0
  32. package/corpus/templates/calendar/.agents/skills/secrets/SKILL.md +11 -4
  33. package/corpus/templates/calendar/actions/list-booking-links.ts +83 -4
  34. package/corpus/templates/calendar/actions/update-booking-link.ts +4 -3
  35. package/corpus/templates/calendar/app/components/calendar/EventDetailPanel.tsx +11 -3
  36. package/corpus/templates/calendar/app/components/calendar/EventDetailPopover.tsx +1 -1
  37. package/corpus/templates/calendar/app/components/calendar/GoogleConnectBanner.tsx +103 -44
  38. package/corpus/templates/calendar/app/components/calendar/OutOfOfficeEvent.tsx +28 -24
  39. package/corpus/templates/calendar/app/components/layout/AppLayout.tsx +9 -2
  40. package/corpus/templates/calendar/app/components/layout/Sidebar.tsx +47 -58
  41. package/corpus/templates/calendar/app/hooks/use-booking-links.ts +5 -1
  42. package/corpus/templates/calendar/app/lib/event-layout.ts +52 -26
  43. package/corpus/templates/calendar/app/pages/BookingLinksPage.tsx +126 -98
  44. package/corpus/templates/calendar/app/pages/CalendarView.tsx +1 -0
  45. package/corpus/templates/calendar/app/pages/Settings.tsx +88 -81
  46. package/corpus/templates/calendar/app/routes.ts +3 -1
  47. package/corpus/templates/calendar/changelog/2026-08-22-booking-link-visibility-respects-shared-access.md +6 -0
  48. package/corpus/templates/calendar/changelog/2026-08-22-clicking-an-out-of-office-event-s-marker-no-longer-creates-a.md +6 -0
  49. package/corpus/templates/calendar/changelog/2026-08-22-event-detail-views-now-show-your-calendar-timezone.md +6 -0
  50. package/corpus/templates/calendar/changelog/2026-08-22-google-calendar-can-now-connect-with-the-shared-google-oauth.md +6 -0
  51. package/corpus/templates/calendar/changelog/2026-08-22-overlapping-events-now-show-each-others-boundaries.md +6 -0
  52. package/corpus/templates/calendar/changelog/2026-08-22-public-booking-pages-now-offer-time-slots-from-the-host-s-we.md +6 -0
  53. package/corpus/templates/calendar/server/handlers/bookings.ts +5 -7
  54. package/corpus/templates/calendar/server/handlers/google-auth.ts +10 -2
  55. package/corpus/templates/calendar/server/lib/google-calendar.ts +139 -14
  56. package/corpus/templates/calendar/server/onboarding.ts +85 -0
  57. package/corpus/templates/calendar/server/plugins/agent-chat.ts +2 -0
  58. package/corpus/templates/calendar/shared/api.ts +9 -1
  59. package/corpus/templates/chat/.agents/skills/secrets/SKILL.md +11 -4
  60. package/corpus/templates/chat/app/routes.ts +3 -1
  61. package/corpus/templates/chat/vitest.config.ts +8 -0
  62. package/corpus/templates/clips/.agents/skills/secrets/SKILL.md +11 -4
  63. package/corpus/templates/clips/actions/get-meeting.ts +9 -4
  64. package/corpus/templates/clips/actions/list-recordings.ts +16 -3
  65. package/corpus/templates/clips/actions/search-meetings.ts +1 -0
  66. package/corpus/templates/clips/actions/view-screen.ts +8 -1
  67. package/corpus/templates/clips/app/components/meetings/meeting-history-row.tsx +32 -1
  68. package/corpus/templates/clips/app/components/player/delete-recording-menu.tsx +1 -1
  69. package/corpus/templates/clips/app/components/recorder/recorder-engine.ts +29 -1
  70. package/corpus/templates/clips/app/i18n/en-US.ts +5 -0
  71. package/corpus/templates/clips/app/routes/_app.meetings.$meetingId.tsx +33 -4
  72. package/corpus/templates/clips/app/routes/_app.meetings._index.tsx +1 -0
  73. package/corpus/templates/clips/app/routes/access-request.approve.tsx +16 -9
  74. package/corpus/templates/clips/app/routes/embed.$shareId.tsx +17 -7
  75. package/corpus/templates/clips/app/routes/share.$shareId.tsx +17 -7
  76. package/corpus/templates/clips/changelog/2026-08-21-camera-bubble-black-circle.md +6 -0
  77. package/corpus/templates/clips/changelog/2026-08-22-screen-recordings-respect-the-microphone-toggle.md +6 -0
  78. package/corpus/templates/clips/changelog/2026-08-22-the-recordings-library-no-longer-fails-right-after-server-start.md +6 -0
  79. package/corpus/templates/clips/changelog/2026-08-23-the-agent-can-see-your-library-right-after-server-start.md +6 -0
  80. package/corpus/templates/clips/chrome-extension/src/background.ts +1 -2
  81. package/corpus/templates/clips/chrome-extension/src/native-transcription.ts +39 -7
  82. package/corpus/templates/clips/chrome-extension/src/offscreen.ts +21 -25
  83. package/corpus/templates/clips/desktop/src/app.tsx +53 -24
  84. package/corpus/templates/clips/desktop/src/lib/bubble-playback.ts +68 -0
  85. package/corpus/templates/clips/desktop/src/lib/recorder.ts +3 -0
  86. package/corpus/templates/clips/desktop/src/lib/transcription-capture.ts +72 -14
  87. package/corpus/templates/clips/desktop/src/lib/updater.ts +8 -3
  88. package/corpus/templates/clips/desktop/src/overlays/bubble.tsx +162 -20
  89. package/corpus/templates/clips/desktop/src-tauri/src/clips/mod.rs +43 -6
  90. package/corpus/templates/clips/desktop/src-tauri/src/native_screen/custom_capture.rs +150 -13
  91. package/corpus/templates/clips/desktop/src-tauri/src/tray.rs +12 -0
  92. package/corpus/templates/clips/server/lib/calendar-event-meetings.ts +28 -3
  93. package/corpus/templates/clips/server/lib/emails.ts +17 -33
  94. package/corpus/templates/content/.agents/skills/secrets/SKILL.md +11 -4
  95. package/corpus/templates/content/app/components/editor/VisualEditor.tsx +140 -15
  96. package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +12 -14
  97. package/corpus/templates/content/app/components/ui/pointer-lock.ts +1 -0
  98. package/corpus/templates/content/app/hooks/use-content-database.ts +18 -2
  99. package/corpus/templates/content/app/hooks/use-local-storage.ts +38 -22
  100. package/corpus/templates/content/app/i18n-data.ts +25 -0
  101. package/corpus/templates/content/app/routes.ts +3 -1
  102. package/corpus/templates/content/changelog/2026-08-22-code-blocks-inserted-from-the-slash-menu-no-longer-get-stuck.md +6 -0
  103. package/corpus/templates/content/changelog/2026-08-22-the-sidebar-page-tree-no-longer-flashes-empty-after-creating-a-page.md +6 -0
  104. package/corpus/templates/content/docs/solutions/2026-08-21-content-mermaid-rendering-shape.md +233 -0
  105. package/corpus/templates/content/server/plugins/agent-chat.ts +9 -2
  106. package/corpus/templates/content/vitest.config.ts +7 -1
  107. package/corpus/templates/crm/.agents/skills/secrets/SKILL.md +11 -4
  108. package/corpus/templates/design/.agents/skills/secrets/SKILL.md +11 -4
  109. package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +1383 -88
  110. package/corpus/templates/design/actions/generate-design.ts +98 -47
  111. package/corpus/templates/design/actions/get-design-system.ts +6 -1
  112. package/corpus/templates/design/actions/refresh-design-system-with-builder.ts +146 -0
  113. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +70 -26
  114. package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +284 -136
  115. package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +2057 -141
  116. package/corpus/templates/design/app/components/design/editor/DesignBottomToolbar.tsx +6 -2
  117. package/corpus/templates/design/app/components/design/editor/DesignWorkspaceRail.tsx +4 -4
  118. package/corpus/templates/design/app/components/design/keyboard-shortcuts.ts +10 -1
  119. package/corpus/templates/design/app/components/design/multi-screen/alt-hover-measurement.ts +19 -2
  120. package/corpus/templates/design/app/components/design/multi-screen/types.ts +9 -2
  121. package/corpus/templates/design/app/components/layout/Header.tsx +15 -0
  122. package/corpus/templates/design/app/components/layout/Layout.tsx +7 -2
  123. package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +11 -4
  124. package/corpus/templates/design/app/i18n-data.ts +1 -0
  125. package/corpus/templates/design/app/i18n-keyboard-shortcuts.ts +12 -0
  126. package/corpus/templates/design/app/lib/design-system-data.ts +68 -0
  127. package/corpus/templates/design/app/pages/DesignEditor.tsx +77 -35
  128. package/corpus/templates/design/app/pages/DesignSystems.tsx +136 -42
  129. package/corpus/templates/design/app/pages/Index.tsx +2 -0
  130. package/corpus/templates/design/app/pages/Templates.tsx +0 -10
  131. package/corpus/templates/design/app/pages/design-editor/code-layer-state.ts +10 -0
  132. package/corpus/templates/design/app/pages/design-editor/collab-sync.ts +50 -0
  133. package/corpus/templates/design/app/pages/design-editor/commands/apply-design-editor-command.ts +1 -1
  134. package/corpus/templates/design/app/pages/design-editor/commands/apply-file-content-update.ts +10 -8
  135. package/corpus/templates/design/app/pages/design-editor/commands/apply-local-content-update.ts +6 -6
  136. package/corpus/templates/design/app/pages/design-editor/commands/apply-pending-visual-styles-with-agent.ts +1 -1
  137. package/corpus/templates/design/app/pages/design-editor/commands/commit-visual-styles.ts +18 -7
  138. package/corpus/templates/design/app/pages/design-editor/commands/escape-hotkey.ts +4 -90
  139. package/corpus/templates/design/app/pages/design-editor/commands/layer-marquee-selection-change.ts +2 -1
  140. package/corpus/templates/design/app/pages/design-editor/commands/layer-selection-change.ts +4 -3
  141. package/corpus/templates/design/app/pages/design-editor/commands/screen-element-select.ts +12 -2
  142. package/corpus/templates/design/app/pages/design-editor/commands/screen-visual-style-change.ts +9 -2
  143. package/corpus/templates/design/app/pages/design-editor/commands/send-runtime-layer-move-semantic-handoff.ts +1 -1
  144. package/corpus/templates/design/app/pages/design-editor/commands/send-runtime-layer-semantic-handoff.ts +1 -1
  145. package/corpus/templates/design/app/pages/design-editor/commands/send-runtime-layer-state-semantic-handoff.ts +1 -1
  146. package/corpus/templates/design/app/pages/design-editor/commands/start-sidebar-resize.ts +1 -1
  147. package/corpus/templates/design/app/pages/design-editor/editor-state.ts +11 -1
  148. package/corpus/templates/design/app/pages/design-editor/effects/adopt-db-file-content.ts +11 -19
  149. package/corpus/templates/design/app/pages/design-editor/effects/observe-collab-text.ts +6 -6
  150. package/corpus/templates/design/app/pages/design-editor/effects/publish-agent-selection-context.ts +1 -1
  151. package/corpus/templates/design/app/pages/design-editor/effects/seed-collab-content.ts +12 -15
  152. package/corpus/templates/design/app/pages/design-editor/selection-state.ts +5 -59
  153. package/corpus/templates/design/app/pages/design-editor/tool-state.ts +8 -0
  154. package/corpus/templates/design/app/pages/design-editor/types.ts +3 -3
  155. package/corpus/templates/design/app/routes.ts +3 -1
  156. package/corpus/templates/design/changelog/2026-08-20-canvas-edits-patch-the-frame-instead-of-rebuilding-it.md +6 -0
  157. package/corpus/templates/design/changelog/2026-08-21-builder-design-system-imports-reconcile-after-indexing.md +6 -0
  158. package/corpus/templates/design/changelog/2026-08-21-draw-mode-needs-shift-y.md +6 -0
  159. package/corpus/templates/design/changelog/2026-08-21-eyedropper-shortcut.md +6 -0
  160. package/corpus/templates/design/changelog/2026-08-21-figma-style-alignment-guides-and-snapping.md +6 -0
  161. package/corpus/templates/design/changelog/2026-08-21-group-transforms-keep-the-selection.md +6 -0
  162. package/corpus/templates/design/changelog/2026-08-21-inspector-fields-keep-focus-on-enter.md +6 -0
  163. package/corpus/templates/design/changelog/2026-08-21-pen-alt-keeps-the-incoming-handle.md +6 -0
  164. package/corpus/templates/design/changelog/2026-08-21-pen-on-the-board-creates-one-vector.md +6 -0
  165. package/corpus/templates/design/changelog/2026-08-21-scale-a-multi-selection-from-the-group-handles.md +6 -0
  166. package/corpus/templates/design/changelog/2026-08-21-scale-resizes-text-with-the-object.md +6 -0
  167. package/corpus/templates/design/changelog/2026-08-21-selecting-another-object-keeps-the-scale-tool-armed.md +6 -0
  168. package/corpus/templates/design/changelog/2026-08-21-the-shape-tool-remembers-the-shape-you-picked.md +6 -0
  169. package/corpus/templates/design/changelog/2026-08-21-vectors-drawn-in-a-frame-land-where-you-drew-them.md +6 -0
  170. package/corpus/templates/design/changelog/2026-08-22-multi-screen-generation-no-longer-loses-a-saved-screens-layo.md +6 -0
  171. package/corpus/templates/design/changelog/2026-08-22-rename-and-search-fields-are-labeled-for-screen-readers.md +6 -0
  172. package/corpus/templates/design/package.json +2 -0
  173. package/corpus/templates/design/server/lib/builder-design-system-proxy.ts +311 -0
  174. package/corpus/templates/design/shared/canvas-math.ts +612 -206
  175. package/corpus/templates/design/shared/pen-path.ts +37 -0
  176. package/corpus/templates/design/vitest.config.ts +7 -1
  177. package/corpus/templates/dispatch/.agents/skills/secrets/SKILL.md +11 -4
  178. package/corpus/templates/dispatch/actions/list-workspace-connections.ts +34 -3
  179. package/corpus/templates/dispatch/app/routes/integrations.tsx +55 -21
  180. package/corpus/templates/dispatch/app/routes.ts +3 -1
  181. package/corpus/templates/factory/.agents/skills/secrets/SKILL.md +11 -4
  182. package/corpus/templates/factory/.env.example +2 -7
  183. package/corpus/templates/factory/AGENTS.md +3 -0
  184. package/corpus/templates/factory/README.md +5 -3
  185. package/corpus/templates/factory/actions/create-factory.ts +16 -3
  186. package/corpus/templates/factory/actions/get-slack-feedback-context.ts +2 -0
  187. package/corpus/templates/factory/actions/get-triage-item.ts +2 -0
  188. package/corpus/templates/factory/actions/list-factory-audit.ts +116 -36
  189. package/corpus/templates/factory/actions/list-factory-automations.ts +2 -1
  190. package/corpus/templates/factory/actions/list-triage-items.ts +22 -19
  191. package/corpus/templates/factory/actions/run-factory-automation.ts +7 -3
  192. package/corpus/templates/factory/actions/save-factory-automation.ts +5 -2
  193. package/corpus/templates/factory/actions/save-triage-config.ts +2 -8
  194. package/corpus/templates/factory/actions/start-builder-for-item.ts +21 -0
  195. package/corpus/templates/factory/app/components/factory/FactoryAuditView.tsx +229 -297
  196. package/corpus/templates/factory/app/components/factory/FactorySettingsView.tsx +397 -247
  197. package/corpus/templates/factory/app/components/factory/FactorySourceSettingsGroup.tsx +33 -0
  198. package/corpus/templates/factory/app/components/factory/NewFactoryForm.tsx +202 -162
  199. package/corpus/templates/factory/app/i18n/en-US.ts +32 -4
  200. package/corpus/templates/factory/app/routes/factory.tsx +84 -11
  201. package/corpus/templates/factory/app/routes.ts +3 -1
  202. package/corpus/templates/factory/changelog/2026-08-21-activity-runs-use-automation-display-names.md +6 -0
  203. package/corpus/templates/factory/changelog/2026-08-21-create-and-settings-source-cards.md +6 -0
  204. package/corpus/templates/factory/changelog/2026-08-21-keep-automations-visible-while-running.md +6 -0
  205. package/corpus/templates/factory/changelog/2026-08-21-nested-factory-automations-can-poll.md +6 -0
  206. package/corpus/templates/factory/changelog/2026-08-21-settings-sticky-unsaved-bar.md +6 -0
  207. package/corpus/templates/factory/server/connectors/credentials.ts +10 -5
  208. package/corpus/templates/factory/server/lib/factory-audit-report.ts +412 -0
  209. package/corpus/templates/factory/server/lib/factory-config-reconcile.ts +321 -0
  210. package/corpus/templates/factory/server/lib/factory-scope.ts +25 -2
  211. package/corpus/templates/factory/server/lib/require-factory-automation.ts +13 -4
  212. package/corpus/templates/factory/server/plugins/factory-migrations.ts +148 -4
  213. package/corpus/templates/factory/server/plugins/factory-scheduler-job.ts +4 -6
  214. package/corpus/templates/factory/vitest.config.ts +17 -2
  215. package/corpus/templates/forms/.agents/skills/secrets/SKILL.md +11 -4
  216. package/corpus/templates/forms/app/routes/_app.settings.tsx +4 -1
  217. package/corpus/templates/forms/changelog/2026-08-22-the-extensions-link-now-opens-the-extensions-tab-instead-o.md +6 -0
  218. package/corpus/templates/forms/server/lib/public-form-ssr.ts +11 -1
  219. package/corpus/templates/forms/vitest.config.ts +1 -0
  220. package/corpus/templates/macros/.agents/skills/secrets/SKILL.md +11 -4
  221. package/corpus/templates/macros/app/routes.ts +3 -1
  222. package/corpus/templates/macros/vitest.config.ts +6 -1
  223. package/corpus/templates/mail/.agents/skills/secrets/SKILL.md +11 -4
  224. package/corpus/templates/mail/actions/manage-gmail-filters.ts +10 -2
  225. package/corpus/templates/mail/app/components/GoogleConnectBanner.tsx +100 -37
  226. package/corpus/templates/mail/app/components/email/IntegrationsSidebar.tsx +14 -2
  227. package/corpus/templates/mail/app/components/layout/AppLayout.tsx +66 -36
  228. package/corpus/templates/mail/app/hooks/use-google-auth.ts +2 -0
  229. package/corpus/templates/mail/app/lib/google-oauth-setup.ts +17 -0
  230. package/corpus/templates/mail/app/pages/InboxPage.tsx +69 -9
  231. package/corpus/templates/mail/app/routes/$.tsx +9 -0
  232. package/corpus/templates/mail/app/routes/$view.$threadId.tsx +23 -1
  233. package/corpus/templates/mail/app/routes/$view.tsx +47 -1
  234. package/corpus/templates/mail/app/routes.ts +3 -1
  235. package/corpus/templates/mail/changelog/2026-08-22-gmail-can-now-connect-with-the-shared-google-oauth.md +6 -0
  236. package/corpus/templates/mail/changelog/2026-08-22-gmail-filters-now-shows-the-real-error.md +6 -0
  237. package/corpus/templates/mail/changelog/2026-08-22-unknown-mail-urls-now-show-the-404-page.md +6 -0
  238. package/corpus/templates/mail/server/handlers/google-auth.ts +11 -2
  239. package/corpus/templates/mail/server/lib/google-auth.ts +92 -12
  240. package/corpus/templates/mail/server/onboarding.ts +66 -18
  241. package/corpus/templates/mail/vitest.config.ts +6 -1
  242. package/corpus/templates/plan/.agents/skills/secrets/SKILL.md +11 -4
  243. package/corpus/templates/plan/app/routes/settings.tsx +4 -1
  244. package/corpus/templates/plan/app/routes.ts +3 -1
  245. package/corpus/templates/plan/changelog/2026-08-22-the-extensions-link-now-opens-the-extensions-tab-instead-o.md +6 -0
  246. package/corpus/templates/plan/netlify.toml +1 -1
  247. package/corpus/templates/slides/.agents/skills/secrets/SKILL.md +11 -4
  248. package/corpus/templates/slides/actions/patch-deck.ts +79 -10
  249. package/corpus/templates/slides/actions/update-slide.ts +11 -1
  250. package/corpus/templates/slides/app/components/deck/SlideRenderer.tsx +14 -4
  251. package/corpus/templates/slides/app/components/editor/ExportMenu.tsx +10 -52
  252. package/corpus/templates/slides/app/components/editor/GoogleDocImportHint.tsx +8 -53
  253. package/corpus/templates/slides/app/components/editor/GoogleDriveConnectionCta.tsx +9 -75
  254. package/corpus/templates/slides/app/components/editor/GoogleSlidesReferenceImport.tsx +8 -60
  255. package/corpus/templates/slides/app/components/editor/SlideContextToolbar.tsx +10 -2
  256. package/corpus/templates/slides/app/components/editor/SlideEditor.tsx +19 -7
  257. package/corpus/templates/slides/app/lib/sanitize-slide-html.ts +49 -36
  258. package/corpus/templates/slides/app/routes/access-request.approve.tsx +16 -9
  259. package/corpus/templates/slides/app/routes.ts +3 -1
  260. package/corpus/templates/slides/changelog/2026-08-22-already-uploaded-chat-images-are-no-longer-dropped.md +6 -0
  261. package/corpus/templates/slides/changelog/2026-08-22-google-drive-and-slides-can-now-connect-with-the-shared-google-oauth.md +6 -0
  262. package/corpus/templates/slides/changelog/2026-08-22-multi-slide-repairs-now-report-slides-that-still-overflow.md +6 -0
  263. package/corpus/templates/slides/changelog/2026-08-22-update-slide-now-reports-which-batched-edit-was-skipped.md +6 -0
  264. package/corpus/templates/slides/server/handlers/google-docs-auth.ts +52 -1
  265. package/corpus/templates/slides/server/lib/chat-attachments.ts +29 -3
  266. package/corpus/templates/slides/server/lib/google-docs-oauth.ts +66 -16
  267. package/corpus/templates/slides/server/lib/slide-content-patch.ts +13 -2
  268. package/corpus/templates/slides/server/plugins/agent-chat.ts +5 -2
  269. package/corpus/templates/slides/tsconfig.json +5 -0
  270. package/corpus/templates/slides/vitest.config.ts +6 -1
  271. package/corpus/templates/tasks/.agents/skills/secrets/SKILL.md +11 -4
  272. package/corpus/templates/tasks/app/routes/settings.tsx +4 -1
  273. package/corpus/templates/tasks/app/routes.ts +3 -1
  274. package/corpus/templates/tasks/changelog/2026-08-22-the-extensions-link-now-opens-the-extensions-tab-instead-o.md +6 -0
  275. package/corpus/templates/tasks/vitest.config.ts +7 -1
  276. package/dist/action.d.ts +91 -0
  277. package/dist/action.js +50 -0
  278. package/dist/agent/abort-reasons.d.ts +38 -0
  279. package/dist/agent/abort-reasons.js +49 -0
  280. package/dist/agent/engine/ai-sdk-engine.js +8 -5
  281. package/dist/agent/engine/anthropic-engine.js +7 -5
  282. package/dist/agent/engine/first-event-timeout.d.ts +42 -17
  283. package/dist/agent/engine/first-event-timeout.js +67 -25
  284. package/dist/agent/production-agent.d.ts +23 -0
  285. package/dist/agent/production-agent.js +107 -102
  286. package/dist/agent/run-loop-with-resume.d.ts +2 -28
  287. package/dist/agent/run-loop-with-resume.js +25 -40
  288. package/dist/agent/run-manager.js +5 -4
  289. package/dist/agent/run-store.d.ts +55 -0
  290. package/dist/agent/run-store.js +124 -1
  291. package/dist/agent/tool-search.js +2 -1
  292. package/dist/agent/types.d.ts +9 -4
  293. package/dist/app-config/auth.d.ts +1 -0
  294. package/dist/app-config/auth.js +7 -0
  295. package/dist/app-config/configuration-error.d.ts +11 -0
  296. package/dist/app-config/configuration-error.js +14 -0
  297. package/dist/app-config/index.d.ts +1 -0
  298. package/dist/app-config/index.js +1 -0
  299. package/dist/app-config/integrations.d.ts +1 -0
  300. package/dist/app-config/integrations.js +10 -0
  301. package/dist/app-config/plugins.d.ts +34 -0
  302. package/dist/app-config/plugins.js +39 -0
  303. package/dist/app-config/run-lifecycle-invariants.d.ts +18 -9
  304. package/dist/app-config/run-lifecycle-invariants.js +18 -25
  305. package/dist/app-config/schema.d.ts +17 -0
  306. package/dist/app-config/schema.js +2 -0
  307. package/dist/chat-threads/schema-migrations.js +20 -0
  308. package/dist/chat-threads/store.js +21 -4
  309. package/dist/cli/native-dependencies.d.ts +4 -0
  310. package/dist/cli/native-dependencies.js +15 -0
  311. package/dist/client/EnvironmentBadge.d.ts +1 -1
  312. package/dist/client/EnvironmentBadge.js +40 -5
  313. package/dist/client/MultiTabAssistantChat.d.ts +1 -1
  314. package/dist/client/MultiTabAssistantChat.js +35 -14
  315. package/dist/client/agent-chat/index.d.ts +1 -1
  316. package/dist/client/agent-chat/index.js +1 -1
  317. package/dist/client/agent-page/use-jobs.d.ts +2 -1
  318. package/dist/client/agent-page/use-jobs.js +3 -5
  319. package/dist/client/agent-sidebar-state.js +3 -1
  320. package/dist/client/blocks/library/code-tabs.js +5 -0
  321. package/dist/client/blocks/library/code.js +1 -0
  322. package/dist/client/chat-first/apps-rail.js +2 -2
  323. package/dist/client/chat-model-groups.d.ts +12 -0
  324. package/dist/client/chat-model-groups.js +3 -2
  325. package/dist/client/integrations/GoogleProductLogo.d.ts +5 -0
  326. package/dist/client/integrations/GoogleProductLogo.js +45 -0
  327. package/dist/client/integrations/index.d.ts +2 -0
  328. package/dist/client/integrations/index.js +2 -0
  329. package/dist/client/integrations/workspace-provider-oauth.d.ts +8 -0
  330. package/dist/client/integrations/workspace-provider-oauth.js +13 -0
  331. package/dist/client/resources/mcp-integration-catalog.js +0 -29
  332. package/dist/client/settings/SettingsTabsPage.js +10 -6
  333. package/dist/client/sharing/ShareButton.js +11 -2
  334. package/dist/client/use-chat-models.d.ts +6 -0
  335. package/dist/client/use-chat-models.js +10 -0
  336. package/dist/client/use-db-sync.js +27 -9
  337. package/dist/collab/routes.d.ts +1 -1
  338. package/dist/collab/struct-routes.d.ts +1 -1
  339. package/dist/connections/catalog.d.ts +111 -9
  340. package/dist/connections/catalog.js +86 -30
  341. package/dist/db/create-get-db.js +18 -0
  342. package/dist/db/ddl-guard.d.ts +0 -4
  343. package/dist/db/ddl-guard.js +46 -0
  344. package/dist/deploy/build.d.ts +19 -0
  345. package/dist/deploy/build.js +190 -16
  346. package/dist/deploy/function-bundle.d.ts +45 -0
  347. package/dist/deploy/function-bundle.js +337 -0
  348. package/dist/deploy/workspace-deploy.js +19 -1
  349. package/dist/eject/workspace-connections.js +4 -0
  350. package/dist/email-catalog/registry.d.ts +4 -0
  351. package/dist/email-catalog/registry.js +79 -14
  352. package/dist/extensions/content-patch.js +14 -2
  353. package/dist/integrations/plugin.d.ts +10 -0
  354. package/dist/integrations/plugin.js +40 -6
  355. package/dist/jobs/actions/run-automation-now.d.ts +2 -1
  356. package/dist/jobs/actions/run-automation-now.js +11 -5
  357. package/dist/jobs/frontmatter.js +53 -2
  358. package/dist/jobs/run-now.d.ts +11 -1
  359. package/dist/jobs/run-now.js +42 -7
  360. package/dist/jobs/scheduler.d.ts +1 -0
  361. package/dist/jobs/scheduler.js +2 -1
  362. package/dist/localization/core-messages/ar-SA.js +3 -0
  363. package/dist/localization/core-messages/de-DE.js +3 -0
  364. package/dist/localization/core-messages/en-US.d.ts +3 -0
  365. package/dist/localization/core-messages/en-US.js +3 -0
  366. package/dist/localization/core-messages/es-ES.js +3 -0
  367. package/dist/localization/core-messages/fr-FR.js +3 -0
  368. package/dist/localization/core-messages/hi-IN.js +3 -0
  369. package/dist/localization/core-messages/ja-JP.js +3 -0
  370. package/dist/localization/core-messages/ko-KR.js +3 -0
  371. package/dist/localization/core-messages/pt-BR.js +3 -0
  372. package/dist/localization/core-messages/zh-CN.js +3 -0
  373. package/dist/localization/core-messages/zh-TW.js +3 -0
  374. package/dist/localization/core-messages.d.ts +3 -0
  375. package/dist/localization/default-messages.d.ts +2 -5
  376. package/dist/localization/default-messages.js +2 -5
  377. package/dist/mcp/build-server.d.ts +9 -0
  378. package/dist/mcp/build-server.js +37 -8
  379. package/dist/mcp-client/oauth-client.d.ts +7 -0
  380. package/dist/mcp-client/oauth-client.js +12 -1
  381. package/dist/oauth-tokens/index.d.ts +1 -1
  382. package/dist/oauth-tokens/index.js +1 -1
  383. package/dist/oauth-tokens/lifecycle.d.ts +11 -0
  384. package/dist/oauth-tokens/lifecycle.js +17 -0
  385. package/dist/oauth-tokens/store.js +7 -0
  386. package/dist/observability/posthog-ai.d.ts +15 -1
  387. package/dist/observability/posthog-ai.js +24 -12
  388. package/dist/observability/traces.js +158 -28
  389. package/dist/onboarding/app-profile.js +2 -2
  390. package/dist/onboarding/plugin.js +10 -2
  391. package/dist/onboarding/types.d.ts +2 -0
  392. package/dist/provider-api/actions/custom-provider-registration.d.ts +1 -1
  393. package/dist/provider-api/actions/provider-api.d.ts +2 -2
  394. package/dist/provider-api/index.js +2 -0
  395. package/dist/resources/handlers.d.ts +2 -2
  396. package/dist/resources/store.js +13 -4
  397. package/dist/scripts/agent-engines/list-agent-engines.js +29 -3
  398. package/dist/secrets/register-framework-secrets.js +1 -1
  399. package/dist/server/action-discovery.js +5 -0
  400. package/dist/server/agent-chat/action-filters-a2a.d.ts +27 -3
  401. package/dist/server/agent-chat/action-filters-a2a.js +48 -9
  402. package/dist/server/agent-chat-plugin.js +36 -9
  403. package/dist/server/agent-discovery.js +43 -20
  404. package/dist/server/auth.js +18 -16
  405. package/dist/server/beta-opt-out-html.js +45 -4
  406. package/dist/server/better-auth-instance.d.ts +2 -1
  407. package/dist/server/better-auth-instance.js +37 -7
  408. package/dist/server/builder-design-systems.d.ts +4 -1
  409. package/dist/server/builder-design-systems.js +87 -6
  410. package/dist/server/builder-oauth.d.ts +1 -7
  411. package/dist/server/builder-oauth.js +80 -163
  412. package/dist/server/core-routes-plugin.d.ts +29 -0
  413. package/dist/server/core-routes-plugin.js +100 -20
  414. package/dist/server/default-plugins.d.ts +18 -0
  415. package/dist/server/default-plugins.js +22 -0
  416. package/dist/server/edge.d.ts +1 -0
  417. package/dist/server/edge.js +1 -0
  418. package/dist/server/framework-request-handler.js +31 -3
  419. package/dist/server/google-oauth.d.ts +3 -0
  420. package/dist/server/google-oauth.js +3 -0
  421. package/dist/server/index.d.ts +4 -4
  422. package/dist/server/index.js +3 -3
  423. package/dist/server/onboarding-html.js +37 -3
  424. package/dist/server/realtime-token.d.ts +1 -1
  425. package/dist/server/workspace-provider-oauth.d.ts +6 -1
  426. package/dist/server/workspace-provider-oauth.js +72 -20
  427. package/dist/shared/agent-sidebar-url.d.ts +1 -0
  428. package/dist/shared/agent-sidebar-url.js +1 -0
  429. package/dist/shared/environment-lanes.d.ts +2 -0
  430. package/dist/shared/environment-lanes.js +3 -1
  431. package/dist/shared/index.d.ts +3 -1
  432. package/dist/shared/index.js +3 -1
  433. package/dist/shared/surface-visibility.d.ts +31 -0
  434. package/dist/shared/surface-visibility.js +57 -0
  435. package/dist/templates/chat/.agents/skills/secrets/SKILL.md +11 -4
  436. package/dist/templates/chat/app/routes.ts +3 -1
  437. package/dist/templates/chat/vitest.config.ts +8 -0
  438. package/dist/templates/default/.agents/skills/secrets/SKILL.md +11 -4
  439. package/dist/templates/default/app/routes.ts +3 -1
  440. package/dist/templates/headless/.agents/skills/secrets/SKILL.md +11 -4
  441. package/dist/templates/workspace-core/.agents/skills/secrets/SKILL.md +11 -4
  442. package/dist/tracking/registry.d.ts +11 -0
  443. package/dist/tracking/registry.js +5 -2
  444. package/dist/triggers/actions.js +10 -3
  445. package/dist/usage/store.js +23 -3
  446. package/dist/user-profile/actions/get-auth-methods.js +18 -5
  447. package/dist/vite/client.js +33 -7
  448. package/docs/content/actions-access-control.mdx +43 -4
  449. package/docs/content/actions-defining.mdx +16 -0
  450. package/docs/content/authentication.mdx +40 -21
  451. package/docs/content/environment-variables.mdx +1 -0
  452. package/docs/content/template-clips-capture-everywhere.mdx +29 -30
  453. package/docs/content/template-clips-developers.mdx +4 -4
  454. package/docs/content/template-clips.mdx +3 -1
  455. package/package.json +2 -2
  456. package/src/eject/workspace-connections.ts +4 -0
  457. package/src/templates/chat/.agents/skills/secrets/SKILL.md +11 -4
  458. package/src/templates/chat/app/routes.ts +3 -1
  459. package/src/templates/chat/vitest.config.ts +8 -0
  460. package/src/templates/default/.agents/skills/secrets/SKILL.md +11 -4
  461. package/src/templates/default/app/routes.ts +3 -1
  462. package/src/templates/headless/.agents/skills/secrets/SKILL.md +11 -4
  463. package/src/templates/workspace-core/.agents/skills/secrets/SKILL.md +11 -4
@@ -5,6 +5,16 @@ import { buildChatModelGroups, } from "./chat-model-groups.js";
5
5
  import { fetchBuilderStatus, fetchEnvironmentStatus, } from "./client-status-requests.js";
6
6
  import { callAction } from "./use-action.js";
7
7
  const DEFAULT_STORAGE_KEY = "agent-native:chat-models:selection";
8
+ /**
9
+ * `useChatModels` takes the raw localStorage key while `MultiTabAssistantChat`
10
+ * takes only the namespace suffix — a surface that hand-writes either one stops
11
+ * sharing the selection with the chat it sits next to.
12
+ */
13
+ export function chatModelSelectionStorageKey(namespace) {
14
+ return namespace
15
+ ? `${DEFAULT_STORAGE_KEY}:${namespace}`
16
+ : DEFAULT_STORAGE_KEY;
17
+ }
8
18
  export const CHAT_MODEL_SELECTION_CHANGED_EVENT = "agent-native:chat-model-selection-changed";
9
19
  const MODEL_DISCOVERY_RETRY_DELAYS_MS = [250, 1_000];
10
20
  async function fetchEngineCatalog() {
@@ -1,6 +1,7 @@
1
1
  import { useEffect, useRef, useState } from "react";
2
2
  import { ensureDemoModeFetchInterceptor } from "../demo/fetch-interceptor.js";
3
3
  import { parseHandshakeFrame, parseTokenFrame, REALTIME_PROTOCOL_VERSION, REALTIME_SSE_HANDSHAKE_EVENT, REALTIME_SSE_TOKEN_EVENT, } from "../realtime-protocol.js";
4
+ import { addSurfaceVisibilityListener, isHostSurfaceHidden, isSurfaceHidden, } from "../shared/surface-visibility.js";
4
5
  import { agentNativePath } from "./api-path.js";
5
6
  import { getBrowserTabId } from "./browser-tab-id.js";
6
7
  import { ensureEmbedAuthFetchInterceptor, isEmbedAuthActive, } from "./embed-auth.js";
@@ -103,7 +104,7 @@ function getPollAbortMs(interval) {
103
104
  return Math.max(POLL_ABORT_MIN_MS, interval * 4);
104
105
  }
105
106
  function isDocumentHidden() {
106
- return (typeof document !== "undefined" && document.visibilityState === "hidden");
107
+ return isSurfaceHidden();
107
108
  }
108
109
  function resolveSseUrl(sseUrl) {
109
110
  if (sseUrl === false)
@@ -269,6 +270,7 @@ class SyncTransport {
269
270
  subscribers = new Map();
270
271
  cursorRef = { ...INITIAL_SYNC_CURSOR };
271
272
  timer = null;
273
+ removeVisibilityListener;
272
274
  stopped = false;
273
275
  inFlight = false;
274
276
  eventSource = null;
@@ -470,6 +472,17 @@ class SyncTransport {
470
472
  // -------------------------------------------------------------------------
471
473
  // Derived settings (aggregate over active subscribers)
472
474
  // -------------------------------------------------------------------------
475
+ /**
476
+ * Whether this transport must do nothing at all right now. A host that has
477
+ * stashed the surface off screen is a stronger statement than a backgrounded
478
+ * browser tab, so it pauses regardless of `pauseWhenHidden` — an embedder
479
+ * only sets it for a surface the user genuinely cannot see.
480
+ */
481
+ shouldStayIdle() {
482
+ if (isHostSurfaceHidden())
483
+ return true;
484
+ return this.effectivePauseWhenHidden && isDocumentHidden();
485
+ }
473
486
  get effectivePauseWhenHidden() {
474
487
  // Pause only if every subscriber has opted in.
475
488
  for (const sub of this.subscribers.values()) {
@@ -550,7 +563,7 @@ class SyncTransport {
550
563
  schedulePoll() {
551
564
  if (this.stopped)
552
565
  return;
553
- if (this.effectivePauseWhenHidden && isDocumentHidden())
566
+ if (this.shouldStayIdle())
554
567
  return;
555
568
  if (this.timer)
556
569
  clearTimeout(this.timer);
@@ -743,7 +756,7 @@ class SyncTransport {
743
756
  if (this.stopped ||
744
757
  this.eventSource ||
745
758
  typeof EventSource === "undefined" ||
746
- (this.effectivePauseWhenHidden && isDocumentHidden())) {
759
+ this.shouldStayIdle()) {
747
760
  return;
748
761
  }
749
762
  // One tab per origin holds the stream; the rest follow it over
@@ -896,6 +909,10 @@ class SyncTransport {
896
909
  async poll() {
897
910
  if (this.stopped || this.inFlight)
898
911
  return;
912
+ // Re-checked here, not only at the schedule sites: whatever path
913
+ // reached poll(), a host-hidden surface must not issue a request.
914
+ if (this.shouldStayIdle())
915
+ return;
899
916
  this.inFlight = true;
900
917
  try {
901
918
  if (this.mode === "hosted" && this.gateway && !this.token) {
@@ -947,7 +964,7 @@ class SyncTransport {
947
964
  }
948
965
  }
949
966
  pollNow() {
950
- if (this.effectivePauseWhenHidden && isDocumentHidden())
967
+ if (this.shouldStayIdle())
951
968
  return;
952
969
  if (this.authFailureDelayMs() > 0) {
953
970
  this.schedulePoll();
@@ -961,11 +978,11 @@ class SyncTransport {
961
978
  void this.poll();
962
979
  }
963
980
  handleVisibilityChange = () => {
964
- if (document.visibilityState === "visible") {
981
+ if (!isSurfaceHidden()) {
965
982
  this.connectEvents();
966
983
  this.pollNow();
967
984
  }
968
- else if (this.effectivePauseWhenHidden) {
985
+ else if (this.shouldStayIdle()) {
969
986
  this.closeEvents();
970
987
  // A hidden leader stops streaming, so it must not keep holding the
971
988
  // origin's stream slot — that would leave every visible tab following a
@@ -1030,13 +1047,13 @@ class SyncTransport {
1030
1047
  // already mounts useDbSync, so this needs zero per-template wiring.
1031
1048
  ensureEmbedAuthFetchInterceptor();
1032
1049
  ensureDemoModeFetchInterceptor();
1033
- if (!this.effectivePauseWhenHidden || !isDocumentHidden()) {
1050
+ if (!this.shouldStayIdle()) {
1034
1051
  this.connectEvents();
1035
1052
  void this.poll();
1036
1053
  }
1037
1054
  window.addEventListener("focus", this.handleFocus);
1038
1055
  window.addEventListener("agentNative.chatRunning", this.handleChatRunning);
1039
- document.addEventListener("visibilitychange", this.handleVisibilityChange);
1056
+ this.removeVisibilityListener = addSurfaceVisibilityListener(this.handleVisibilityChange);
1040
1057
  }
1041
1058
  teardown() {
1042
1059
  this.stopped = true;
@@ -1060,7 +1077,8 @@ class SyncTransport {
1060
1077
  }
1061
1078
  window.removeEventListener("focus", this.handleFocus);
1062
1079
  window.removeEventListener("agentNative.chatRunning", this.handleChatRunning);
1063
- document.removeEventListener("visibilitychange", this.handleVisibilityChange);
1080
+ this.removeVisibilityListener?.();
1081
+ this.removeVisibilityListener = undefined;
1064
1082
  }
1065
1083
  }
1066
1084
  /**
@@ -26,8 +26,8 @@ export declare const getCollabState: import("h3").EventHandlerWithFetch<import("
26
26
  * Body: { update: string (base64), requestSource?: string }
27
27
  */
28
28
  export declare const postCollabUpdate: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
29
- ok?: undefined;
30
29
  error: string;
30
+ ok?: undefined;
31
31
  } | {
32
32
  error?: undefined;
33
33
  ok: boolean;
@@ -13,8 +13,8 @@
13
13
  * Body: { json: any, fieldName?: string, type?: "map"|"array", requestSource?: string }
14
14
  */
15
15
  export declare const postCollabJson: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
16
- error: string;
17
16
  ok?: undefined;
17
+ error: string;
18
18
  } | {
19
19
  error?: undefined;
20
20
  ok: boolean;
@@ -1,6 +1,6 @@
1
1
  export type WorkspaceConnectionCapability = "search" | "import" | "messages" | "meetings" | "crm" | "code" | "docs";
2
2
  export type WorkspaceConnectionTemplateUse = "analytics" | "brain" | "calendar" | "clips" | "content" | "crm" | "design" | "dispatch" | "factory" | "forms" | "mail" | "slides";
3
- export type WorkspaceConnectionProviderId = "slack" | "github" | "figma" | "notion" | "gmail" | "google_drive" | "hubspot" | "salesforce" | "jira" | "sentry" | "granola" | "clips" | "generic";
3
+ export type WorkspaceConnectionProviderId = "slack" | "github" | "figma" | "notion" | "gmail" | "google_calendar" | "google_drive" | "google_docs" | "google_sheets" | "google_slides" | "hubspot" | "salesforce" | "jira" | "sentry" | "granola" | "clips" | "generic";
4
4
  export interface WorkspaceConnectionCredentialKey {
5
5
  key: string;
6
6
  label: string;
@@ -97,35 +97,137 @@ export declare const WORKSPACE_CONNECTION_PROVIDERS: readonly [{
97
97
  readonly description: "Mailbox messages and threads for search, triage, customer context, and agent replies.";
98
98
  readonly credentialKeys: readonly [{
99
99
  readonly key: "GOOGLE_CLIENT_ID";
100
- readonly label: "Google OAuth client ID";
100
+ readonly label: "Managed Google OAuth client ID";
101
+ readonly description: "Resolved from the workspace's shared Google OAuth application. Users do not paste a key to connect a service.";
101
102
  readonly required: true;
102
103
  }, {
103
104
  readonly key: "GOOGLE_CLIENT_SECRET";
104
- readonly label: "Google OAuth client secret";
105
+ readonly label: "Managed Google OAuth client secret";
106
+ readonly description: "Resolved from the workspace's shared Google OAuth application. Users do not paste a key to connect a service.";
105
107
  readonly required: true;
106
108
  }];
107
109
  readonly capabilities: readonly ["search", "import", "messages"];
108
110
  readonly recommendedTemplateUses: readonly ["mail", "brain", "dispatch"];
111
+ readonly oauth: {
112
+ provider: "google";
113
+ authorizationUrl: "https://accounts.google.com/o/oauth2/v2/auth";
114
+ tokenUrl: "https://oauth2.googleapis.com/token";
115
+ scopes: readonly string[];
116
+ };
117
+ }, {
118
+ readonly id: "google_calendar";
119
+ readonly label: "Google Calendar";
120
+ readonly description: "Calendars and events for scheduling, availability, reminders, and meeting workflows.";
121
+ readonly credentialKeys: readonly [{
122
+ readonly key: "GOOGLE_CLIENT_ID";
123
+ readonly label: "Managed Google OAuth client ID";
124
+ readonly description: "Resolved from the workspace's shared Google OAuth application. Users do not paste a key to connect a service.";
125
+ readonly required: true;
126
+ }, {
127
+ readonly key: "GOOGLE_CLIENT_SECRET";
128
+ readonly label: "Managed Google OAuth client secret";
129
+ readonly description: "Resolved from the workspace's shared Google OAuth application. Users do not paste a key to connect a service.";
130
+ readonly required: true;
131
+ }];
132
+ readonly capabilities: readonly ["search", "import", "meetings"];
133
+ readonly recommendedTemplateUses: readonly ["calendar", "brain", "dispatch", "mail"];
134
+ readonly oauth: {
135
+ provider: "google";
136
+ authorizationUrl: "https://accounts.google.com/o/oauth2/v2/auth";
137
+ tokenUrl: "https://oauth2.googleapis.com/token";
138
+ scopes: readonly string[];
139
+ };
109
140
  }, {
110
141
  readonly id: "google_drive";
111
142
  readonly label: "Google Drive";
112
143
  readonly description: "Drive files, Docs, Sheets, and Slides for document search and import workflows.";
113
144
  readonly credentialKeys: readonly [{
114
145
  readonly key: "GOOGLE_CLIENT_ID";
115
- readonly label: "Google OAuth client ID";
146
+ readonly label: "Managed Google OAuth client ID";
147
+ readonly description: "Resolved from the workspace's shared Google OAuth application. Users do not paste a key to connect a service.";
116
148
  readonly required: true;
117
149
  }, {
118
150
  readonly key: "GOOGLE_CLIENT_SECRET";
119
- readonly label: "Google OAuth client secret";
151
+ readonly label: "Managed Google OAuth client secret";
152
+ readonly description: "Resolved from the workspace's shared Google OAuth application. Users do not paste a key to connect a service.";
120
153
  readonly required: true;
121
154
  }];
122
155
  readonly capabilities: readonly ["search", "import", "docs"];
123
156
  readonly recommendedTemplateUses: readonly ["brain", "content", "slides", "dispatch", "analytics"];
124
157
  readonly oauth: {
125
- readonly provider: "google";
126
- readonly authorizationUrl: "https://accounts.google.com/o/oauth2/v2/auth";
127
- readonly tokenUrl: "https://oauth2.googleapis.com/token";
128
- readonly scopes: readonly ["https://www.googleapis.com/auth/drive.file"];
158
+ provider: "google";
159
+ authorizationUrl: "https://accounts.google.com/o/oauth2/v2/auth";
160
+ tokenUrl: "https://oauth2.googleapis.com/token";
161
+ scopes: readonly string[];
162
+ };
163
+ }, {
164
+ readonly id: "google_docs";
165
+ readonly label: "Google Docs";
166
+ readonly description: "Google Docs files for source material, document search, and agent-assisted writing workflows.";
167
+ readonly credentialKeys: readonly [{
168
+ readonly key: "GOOGLE_CLIENT_ID";
169
+ readonly label: "Managed Google OAuth client ID";
170
+ readonly description: "Resolved from the workspace's shared Google OAuth application. Users do not paste a key to connect a service.";
171
+ readonly required: true;
172
+ }, {
173
+ readonly key: "GOOGLE_CLIENT_SECRET";
174
+ readonly label: "Managed Google OAuth client secret";
175
+ readonly description: "Resolved from the workspace's shared Google OAuth application. Users do not paste a key to connect a service.";
176
+ readonly required: true;
177
+ }];
178
+ readonly capabilities: readonly ["search", "import", "docs"];
179
+ readonly recommendedTemplateUses: readonly ["brain", "content", "slides", "dispatch"];
180
+ readonly oauth: {
181
+ provider: "google";
182
+ authorizationUrl: "https://accounts.google.com/o/oauth2/v2/auth";
183
+ tokenUrl: "https://oauth2.googleapis.com/token";
184
+ scopes: readonly string[];
185
+ };
186
+ }, {
187
+ readonly id: "google_sheets";
188
+ readonly label: "Google Sheets";
189
+ readonly description: "Google Sheets workbooks for analysis, reporting, imports, and structured agent workflows.";
190
+ readonly credentialKeys: readonly [{
191
+ readonly key: "GOOGLE_CLIENT_ID";
192
+ readonly label: "Managed Google OAuth client ID";
193
+ readonly description: "Resolved from the workspace's shared Google OAuth application. Users do not paste a key to connect a service.";
194
+ readonly required: true;
195
+ }, {
196
+ readonly key: "GOOGLE_CLIENT_SECRET";
197
+ readonly label: "Managed Google OAuth client secret";
198
+ readonly description: "Resolved from the workspace's shared Google OAuth application. Users do not paste a key to connect a service.";
199
+ readonly required: true;
200
+ }];
201
+ readonly capabilities: readonly ["search", "import", "docs"];
202
+ readonly recommendedTemplateUses: readonly ["analytics", "brain", "content", "dispatch"];
203
+ readonly oauth: {
204
+ provider: "google";
205
+ authorizationUrl: "https://accounts.google.com/o/oauth2/v2/auth";
206
+ tokenUrl: "https://oauth2.googleapis.com/token";
207
+ scopes: readonly string[];
208
+ };
209
+ }, {
210
+ readonly id: "google_slides";
211
+ readonly label: "Google Slides";
212
+ readonly description: "Google Slides presentations for reference imports, visual context, and presentation workflows.";
213
+ readonly credentialKeys: readonly [{
214
+ readonly key: "GOOGLE_CLIENT_ID";
215
+ readonly label: "Managed Google OAuth client ID";
216
+ readonly description: "Resolved from the workspace's shared Google OAuth application. Users do not paste a key to connect a service.";
217
+ readonly required: true;
218
+ }, {
219
+ readonly key: "GOOGLE_CLIENT_SECRET";
220
+ readonly label: "Managed Google OAuth client secret";
221
+ readonly description: "Resolved from the workspace's shared Google OAuth application. Users do not paste a key to connect a service.";
222
+ readonly required: true;
223
+ }];
224
+ readonly capabilities: readonly ["search", "import", "docs"];
225
+ readonly recommendedTemplateUses: readonly ["brain", "content", "slides", "dispatch"];
226
+ readonly oauth: {
227
+ provider: "google";
228
+ authorizationUrl: "https://accounts.google.com/o/oauth2/v2/auth";
229
+ tokenUrl: "https://oauth2.googleapis.com/token";
230
+ scopes: readonly string[];
129
231
  };
130
232
  }, {
131
233
  readonly id: "hubspot";
@@ -1,6 +1,29 @@
1
1
  export function defineWorkspaceConnectionProvider(provider) {
2
2
  return provider;
3
3
  }
4
+ const GOOGLE_CREDENTIAL_KEYS = [
5
+ {
6
+ key: "GOOGLE_CLIENT_ID",
7
+ label: "Managed Google OAuth client ID",
8
+ description: "Resolved from the workspace's shared Google OAuth application. Users do not paste a key to connect a service.",
9
+ required: true,
10
+ },
11
+ {
12
+ key: "GOOGLE_CLIENT_SECRET",
13
+ label: "Managed Google OAuth client secret",
14
+ description: "Resolved from the workspace's shared Google OAuth application. Users do not paste a key to connect a service.",
15
+ required: true,
16
+ },
17
+ ];
18
+ const GOOGLE_OAUTH_BASE = {
19
+ provider: "google",
20
+ authorizationUrl: "https://accounts.google.com/o/oauth2/v2/auth",
21
+ tokenUrl: "https://oauth2.googleapis.com/token",
22
+ };
23
+ function googleOAuth(scopes) {
24
+ return { ...GOOGLE_OAUTH_BASE, scopes };
25
+ }
26
+ const GOOGLE_IDENTITY_SCOPES = ["openid", "email", "profile"];
4
27
  export const WORKSPACE_CONNECTION_PROVIDERS = [
5
28
  defineWorkspaceConnectionProvider({
6
29
  id: "slack",
@@ -84,37 +107,35 @@ export const WORKSPACE_CONNECTION_PROVIDERS = [
84
107
  id: "gmail",
85
108
  label: "Gmail",
86
109
  description: "Mailbox messages and threads for search, triage, customer context, and agent replies.",
87
- credentialKeys: [
88
- {
89
- key: "GOOGLE_CLIENT_ID",
90
- label: "Google OAuth client ID",
91
- required: true,
92
- },
93
- {
94
- key: "GOOGLE_CLIENT_SECRET",
95
- label: "Google OAuth client secret",
96
- required: true,
97
- },
98
- ],
110
+ credentialKeys: GOOGLE_CREDENTIAL_KEYS,
99
111
  capabilities: ["search", "import", "messages"],
100
112
  recommendedTemplateUses: ["mail", "brain", "dispatch"],
113
+ oauth: googleOAuth([
114
+ ...GOOGLE_IDENTITY_SCOPES,
115
+ "https://www.googleapis.com/auth/gmail.readonly",
116
+ "https://www.googleapis.com/auth/gmail.send",
117
+ "https://www.googleapis.com/auth/gmail.modify",
118
+ "https://www.googleapis.com/auth/gmail.settings.basic",
119
+ ]),
120
+ }),
121
+ defineWorkspaceConnectionProvider({
122
+ id: "google_calendar",
123
+ label: "Google Calendar",
124
+ description: "Calendars and events for scheduling, availability, reminders, and meeting workflows.",
125
+ credentialKeys: GOOGLE_CREDENTIAL_KEYS,
126
+ capabilities: ["search", "import", "meetings"],
127
+ recommendedTemplateUses: ["calendar", "brain", "dispatch", "mail"],
128
+ oauth: googleOAuth([
129
+ ...GOOGLE_IDENTITY_SCOPES,
130
+ "https://www.googleapis.com/auth/calendar.readonly",
131
+ "https://www.googleapis.com/auth/calendar.events",
132
+ ]),
101
133
  }),
102
134
  defineWorkspaceConnectionProvider({
103
135
  id: "google_drive",
104
136
  label: "Google Drive",
105
137
  description: "Drive files, Docs, Sheets, and Slides for document search and import workflows.",
106
- credentialKeys: [
107
- {
108
- key: "GOOGLE_CLIENT_ID",
109
- label: "Google OAuth client ID",
110
- required: true,
111
- },
112
- {
113
- key: "GOOGLE_CLIENT_SECRET",
114
- label: "Google OAuth client secret",
115
- required: true,
116
- },
117
- ],
138
+ credentialKeys: GOOGLE_CREDENTIAL_KEYS,
118
139
  capabilities: ["search", "import", "docs"],
119
140
  recommendedTemplateUses: [
120
141
  "brain",
@@ -123,12 +144,47 @@ export const WORKSPACE_CONNECTION_PROVIDERS = [
123
144
  "dispatch",
124
145
  "analytics",
125
146
  ],
126
- oauth: {
127
- provider: "google",
128
- authorizationUrl: "https://accounts.google.com/o/oauth2/v2/auth",
129
- tokenUrl: "https://oauth2.googleapis.com/token",
130
- scopes: ["https://www.googleapis.com/auth/drive.file"],
131
- },
147
+ oauth: googleOAuth([
148
+ ...GOOGLE_IDENTITY_SCOPES,
149
+ "https://www.googleapis.com/auth/drive.file",
150
+ "https://www.googleapis.com/auth/drive.readonly",
151
+ ]),
152
+ }),
153
+ defineWorkspaceConnectionProvider({
154
+ id: "google_docs",
155
+ label: "Google Docs",
156
+ description: "Google Docs files for source material, document search, and agent-assisted writing workflows.",
157
+ credentialKeys: GOOGLE_CREDENTIAL_KEYS,
158
+ capabilities: ["search", "import", "docs"],
159
+ recommendedTemplateUses: ["brain", "content", "slides", "dispatch"],
160
+ oauth: googleOAuth([
161
+ ...GOOGLE_IDENTITY_SCOPES,
162
+ "https://www.googleapis.com/auth/documents.readonly",
163
+ ]),
164
+ }),
165
+ defineWorkspaceConnectionProvider({
166
+ id: "google_sheets",
167
+ label: "Google Sheets",
168
+ description: "Google Sheets workbooks for analysis, reporting, imports, and structured agent workflows.",
169
+ credentialKeys: GOOGLE_CREDENTIAL_KEYS,
170
+ capabilities: ["search", "import", "docs"],
171
+ recommendedTemplateUses: ["analytics", "brain", "content", "dispatch"],
172
+ oauth: googleOAuth([
173
+ ...GOOGLE_IDENTITY_SCOPES,
174
+ "https://www.googleapis.com/auth/spreadsheets.readonly",
175
+ ]),
176
+ }),
177
+ defineWorkspaceConnectionProvider({
178
+ id: "google_slides",
179
+ label: "Google Slides",
180
+ description: "Google Slides presentations for reference imports, visual context, and presentation workflows.",
181
+ credentialKeys: GOOGLE_CREDENTIAL_KEYS,
182
+ capabilities: ["search", "import", "docs"],
183
+ recommendedTemplateUses: ["brain", "content", "slides", "dispatch"],
184
+ oauth: googleOAuth([
185
+ ...GOOGLE_IDENTITY_SCOPES,
186
+ "https://www.googleapis.com/auth/presentations.readonly",
187
+ ]),
132
188
  }),
133
189
  defineWorkspaceConnectionProvider({
134
190
  id: "hubspot",
@@ -519,6 +519,24 @@ export function createGetDb(schema) {
519
519
  });
520
520
  return promise[prop].bind(promise);
521
521
  }
522
+ // drizzle-orm duck-types "is this an SQL entity" by reading these two
523
+ // properties directly off a value — synchronously, without awaiting
524
+ // (see `isSQLWrapper` in drizzle-orm/sql/sql.js). Because this proxy's
525
+ // target is a function, answering that probe with another proxy would
526
+ // make an un-awaited chain (e.g. a subquery chain embedded as a raw
527
+ // value instead of being awaited — the pattern that broke
528
+ // list-recordings.ts) masquerade as a resolved SQL entity. drizzle
529
+ // then calls `.getSQL()` on it, which duck-types as a wrapper again,
530
+ // forever — `RangeError: Maximum call stack size exceeded` deep
531
+ // inside drizzle internals instead of a message pointing at the
532
+ // actual bug. Fail loudly here instead, at the point of misuse.
533
+ if (prop === "getSQL" || prop === "shouldOmitSQLParens") {
534
+ throw new Error("getDb(): accessed an unresolved query chain synchronously " +
535
+ `(reading '${String(prop)}'). This chain was embedded as a raw ` +
536
+ "value instead of being awaited first — e.g. a subquery passed " +
537
+ "straight into another expression. Await the chain before " +
538
+ "using its result.");
539
+ }
522
540
  // Symbol.toStringTag, Symbol.iterator, etc. — return another proxy
523
541
  // Property access (e.g. db.query) — record and return another proxy
524
542
  return createLazyProxy(ready, [...chain, { prop }]);
@@ -125,10 +125,6 @@ export declare function ensureColumnExists(table: string, column: string, addCol
125
125
  lockTimeout?: string;
126
126
  injectedClient?: DbExec;
127
127
  }): Promise<boolean>;
128
- /**
129
- * Convenience wrapper: ensure an INDEX exists (probe via `pgIndexExists`).
130
- * `createIndexSql` should be the full `CREATE INDEX IF NOT EXISTS <name> …`.
131
- */
132
128
  export declare function ensureIndexExists(indexName: string, createIndexSql: string, options?: {
133
129
  lockTimeout?: string;
134
130
  injectedClient?: DbExec;
@@ -391,7 +391,46 @@ export async function ensureColumnExists(table, column, addColumnSql, options =
391
391
  * Convenience wrapper: ensure an INDEX exists (probe via `pgIndexExists`).
392
392
  * `createIndexSql` should be the full `CREATE INDEX IF NOT EXISTS <name> …`.
393
393
  */
394
+ /**
395
+ * Drop an index that exists under this name but is INVALID.
396
+ *
397
+ * A failed `CREATE INDEX CONCURRENTLY` leaves the index present but unusable
398
+ * (`indisvalid = false`). That is a trap for every repair attempt that follows:
399
+ * `pgIndexExists` correctly reports it missing, but `CREATE INDEX IF NOT
400
+ * EXISTS` sees the NAME is taken and skips, so the re-probe fails again and the
401
+ * release never recovers on its own. Found in production on
402
+ * `chat_threads_owner_lower_updated_idx` and `sync_events_created_at_id_idx`.
403
+ *
404
+ * Dropping is safe: an invalid index serves no query and cannot be repaired in
405
+ * place — Postgres' own guidance is to drop and rebuild it.
406
+ */
407
+ async function dropInvalidIndex(indexName, client) {
408
+ if (!PLAIN_IDENTIFIER.test(indexName))
409
+ return;
410
+ const { rows } = await client.execute({
411
+ sql: `SELECT 1
412
+ FROM pg_class AS index_class
413
+ JOIN pg_namespace AS index_namespace
414
+ ON index_namespace.oid = index_class.relnamespace
415
+ AND index_namespace.nspname = 'public'
416
+ JOIN pg_index AS index_state
417
+ ON index_state.indexrelid = index_class.oid
418
+ WHERE index_class.relname = ?
419
+ AND NOT index_state.indisvalid
420
+ LIMIT 1`,
421
+ args: [indexName],
422
+ });
423
+ if (rows.length === 0)
424
+ return;
425
+ console.warn(`[db] dropping INVALID index "${indexName}" so it can be rebuilt; ` +
426
+ `a previous CREATE INDEX left it unusable.`);
427
+ await client.execute(`DROP INDEX IF EXISTS "${indexName}"`);
428
+ invalidateSchemaSnapshot(client);
429
+ }
394
430
  export async function ensureIndexExists(indexName, createIndexSql, options = {}) {
431
+ if ((options.dialectIsPostgres ?? isPostgres()) && !schemaEnsureDisabled()) {
432
+ await dropInvalidIndex(indexName, options.injectedClient ?? getDbExec());
433
+ }
395
434
  return ensureSchemaObject({
396
435
  probe: () => pgIndexExists(indexName, options.injectedClient, options.dialectIsPostgres),
397
436
  ddl: createIndexSql,
@@ -420,6 +459,13 @@ export async function ensureIndexExistsConcurrently(indexName, createIndexSql, o
420
459
  if (initiallyExists === undefined) {
421
460
  throw new Error(`ensureIndexExistsConcurrently: could not probe required index "${indexName}"; refusing to issue DDL`);
422
461
  }
462
+ // This helper is what STRANDS an invalid index in the first place: an
463
+ // interrupted concurrent build leaves the name taken and the index unusable,
464
+ // and `CREATE INDEX CONCURRENTLY IF NOT EXISTS` then skips it forever. Clear
465
+ // it here too, or the one caller that creates the mess is the one caller that
466
+ // cannot recover from it — which is how `sync_events_created_at_id_idx` has
467
+ // stayed invalid in production.
468
+ await dropInvalidIndex(indexName, client);
423
469
  await client.execute(createIndexSql);
424
470
  invalidateSchemaSnapshot(client);
425
471
  const existsAfterCreate = await pgIndexExists(indexName, client, options.dialectIsPostgres);
@@ -246,6 +246,25 @@ export declare function findNonLinuxBetterSqlite3Binaries(serverDir: string): st
246
246
  export declare function bundleYjsRuntimeForServerlessOutput(serverDir: string, projectCwd: string): string[];
247
247
  /** Presets whose Node-style output needs the emitted Yjs runtime bundle. */
248
248
  export declare function shouldBundleYjsRuntimeForPreset(targetPreset: string): boolean;
249
+ /**
250
+ * Replace the bundled `better-sqlite3` with a throwing stub in serverless
251
+ * output.
252
+ *
253
+ * The package is 27MB — a 9.1MB `sqlite3.c`, its object files, and a static
254
+ * archive, none of which a function can use: every consumer is gated on a
255
+ * `file:` or schemeless `DATABASE_URL`, and a serverless container holding a
256
+ * file-backed SQLite database is already broken, since the filesystem is
257
+ * ephemeral and each container gets its own copy.
258
+ *
259
+ * It cannot simply be deleted. Drizzle's bundled `_libs/drizzle-orm+postgres`
260
+ * chunk imports it at module scope, so removing the package turns every cold
261
+ * start into `ERR_MODULE_NOT_FOUND` — which is how this was first written, and
262
+ * what the SSR cold-start smoke caught. The stub keeps the specifier
263
+ * resolvable and moves the failure to the only place it can be acted on: a
264
+ * deploy that actually tries to open a file-backed database, which now throws
265
+ * with the reason instead of quietly serving an empty one.
266
+ */
267
+ export declare function stubLocalOnlySqliteDriverForServerless(serverDir: string): number;
249
268
  export declare function assertSingleTemplateNetlifyBuildOutput(projectCwd: string): void;
250
269
  /**
251
270
  * Strip the harmful single-template catch-all rewrite that points at