@agent-native/core 0.169.1 → 0.170.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 (459) 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/configuration-error.d.ts +11 -0
  294. package/dist/app-config/configuration-error.js +14 -0
  295. package/dist/app-config/index.d.ts +1 -0
  296. package/dist/app-config/index.js +1 -0
  297. package/dist/app-config/integrations.d.ts +1 -0
  298. package/dist/app-config/integrations.js +10 -0
  299. package/dist/app-config/plugins.d.ts +34 -0
  300. package/dist/app-config/plugins.js +39 -0
  301. package/dist/app-config/run-lifecycle-invariants.d.ts +18 -9
  302. package/dist/app-config/run-lifecycle-invariants.js +18 -25
  303. package/dist/app-config/schema.d.ts +16 -0
  304. package/dist/app-config/schema.js +2 -0
  305. package/dist/chat-threads/schema-migrations.js +20 -0
  306. package/dist/chat-threads/store.js +21 -4
  307. package/dist/cli/native-dependencies.d.ts +4 -0
  308. package/dist/cli/native-dependencies.js +15 -0
  309. package/dist/client/EnvironmentBadge.d.ts +1 -1
  310. package/dist/client/EnvironmentBadge.js +40 -5
  311. package/dist/client/MultiTabAssistantChat.d.ts +1 -1
  312. package/dist/client/MultiTabAssistantChat.js +35 -14
  313. package/dist/client/agent-chat/index.d.ts +1 -1
  314. package/dist/client/agent-chat/index.js +1 -1
  315. package/dist/client/agent-page/use-jobs.d.ts +2 -1
  316. package/dist/client/agent-page/use-jobs.js +3 -5
  317. package/dist/client/agent-sidebar-state.js +3 -1
  318. package/dist/client/blocks/library/code-tabs.js +5 -0
  319. package/dist/client/blocks/library/code.js +1 -0
  320. package/dist/client/chat-first/apps-rail.js +2 -2
  321. package/dist/client/chat-model-groups.d.ts +12 -0
  322. package/dist/client/chat-model-groups.js +3 -2
  323. package/dist/client/integrations/GoogleProductLogo.d.ts +5 -0
  324. package/dist/client/integrations/GoogleProductLogo.js +45 -0
  325. package/dist/client/integrations/index.d.ts +2 -0
  326. package/dist/client/integrations/index.js +2 -0
  327. package/dist/client/integrations/workspace-provider-oauth.d.ts +8 -0
  328. package/dist/client/integrations/workspace-provider-oauth.js +13 -0
  329. package/dist/client/resources/mcp-integration-catalog.js +0 -29
  330. package/dist/client/settings/SettingsTabsPage.js +10 -6
  331. package/dist/client/sharing/ShareButton.js +11 -2
  332. package/dist/client/use-chat-models.d.ts +6 -0
  333. package/dist/client/use-chat-models.js +10 -0
  334. package/dist/client/use-db-sync.js +27 -9
  335. package/dist/connections/catalog.d.ts +111 -9
  336. package/dist/connections/catalog.js +86 -30
  337. package/dist/db/create-get-db.js +18 -0
  338. package/dist/db/ddl-guard.d.ts +0 -4
  339. package/dist/db/ddl-guard.js +46 -0
  340. package/dist/deploy/build.d.ts +19 -0
  341. package/dist/deploy/build.js +190 -16
  342. package/dist/deploy/function-bundle.d.ts +45 -0
  343. package/dist/deploy/function-bundle.js +337 -0
  344. package/dist/deploy/workspace-deploy.js +19 -1
  345. package/dist/eject/workspace-connections.js +4 -0
  346. package/dist/email-catalog/registry.d.ts +4 -0
  347. package/dist/email-catalog/registry.js +79 -14
  348. package/dist/extensions/content-patch.js +14 -2
  349. package/dist/file-upload/actions/upload-image.d.ts +1 -1
  350. package/dist/integrations/plugin.d.ts +10 -0
  351. package/dist/integrations/plugin.js +40 -6
  352. package/dist/jobs/actions/run-automation-now.d.ts +2 -1
  353. package/dist/jobs/actions/run-automation-now.js +11 -5
  354. package/dist/jobs/frontmatter.js +53 -2
  355. package/dist/jobs/run-now.d.ts +11 -1
  356. package/dist/jobs/run-now.js +42 -7
  357. package/dist/jobs/scheduler.d.ts +1 -0
  358. package/dist/jobs/scheduler.js +2 -1
  359. package/dist/localization/core-messages/ar-SA.js +3 -0
  360. package/dist/localization/core-messages/de-DE.js +3 -0
  361. package/dist/localization/core-messages/en-US.d.ts +3 -0
  362. package/dist/localization/core-messages/en-US.js +3 -0
  363. package/dist/localization/core-messages/es-ES.js +3 -0
  364. package/dist/localization/core-messages/fr-FR.js +3 -0
  365. package/dist/localization/core-messages/hi-IN.js +3 -0
  366. package/dist/localization/core-messages/ja-JP.js +3 -0
  367. package/dist/localization/core-messages/ko-KR.js +3 -0
  368. package/dist/localization/core-messages/pt-BR.js +3 -0
  369. package/dist/localization/core-messages/zh-CN.js +3 -0
  370. package/dist/localization/core-messages/zh-TW.js +3 -0
  371. package/dist/localization/core-messages.d.ts +3 -0
  372. package/dist/localization/default-messages.d.ts +2 -5
  373. package/dist/localization/default-messages.js +2 -5
  374. package/dist/mcp/build-server.d.ts +9 -0
  375. package/dist/mcp/build-server.js +37 -8
  376. package/dist/mcp-client/oauth-client.d.ts +7 -0
  377. package/dist/mcp-client/oauth-client.js +12 -1
  378. package/dist/oauth-tokens/index.d.ts +1 -1
  379. package/dist/oauth-tokens/index.js +1 -1
  380. package/dist/oauth-tokens/lifecycle.d.ts +11 -0
  381. package/dist/oauth-tokens/lifecycle.js +17 -0
  382. package/dist/oauth-tokens/store.js +7 -0
  383. package/dist/observability/posthog-ai.d.ts +15 -1
  384. package/dist/observability/posthog-ai.js +24 -12
  385. package/dist/observability/routes.d.ts +3 -3
  386. package/dist/observability/traces.js +158 -28
  387. package/dist/onboarding/app-profile.js +2 -2
  388. package/dist/onboarding/plugin.js +10 -2
  389. package/dist/onboarding/types.d.ts +2 -0
  390. package/dist/provider-api/actions/custom-provider-registration.d.ts +1 -1
  391. package/dist/provider-api/actions/provider-api.d.ts +2 -2
  392. package/dist/provider-api/index.js +2 -0
  393. package/dist/resources/store.js +13 -4
  394. package/dist/scripts/agent-engines/list-agent-engines.js +29 -3
  395. package/dist/secrets/register-framework-secrets.js +1 -1
  396. package/dist/server/action-discovery.js +5 -0
  397. package/dist/server/agent-chat/action-filters-a2a.d.ts +27 -3
  398. package/dist/server/agent-chat/action-filters-a2a.js +48 -9
  399. package/dist/server/agent-chat-plugin.js +36 -9
  400. package/dist/server/agent-discovery.js +43 -20
  401. package/dist/server/auth.js +18 -16
  402. package/dist/server/beta-opt-out-html.js +45 -4
  403. package/dist/server/better-auth-instance.d.ts +2 -1
  404. package/dist/server/better-auth-instance.js +23 -7
  405. package/dist/server/builder-design-systems.d.ts +4 -1
  406. package/dist/server/builder-design-systems.js +87 -6
  407. package/dist/server/builder-oauth.d.ts +1 -7
  408. package/dist/server/builder-oauth.js +80 -163
  409. package/dist/server/core-routes-plugin.d.ts +29 -0
  410. package/dist/server/core-routes-plugin.js +100 -20
  411. package/dist/server/default-plugins.d.ts +18 -0
  412. package/dist/server/default-plugins.js +22 -0
  413. package/dist/server/edge.d.ts +1 -0
  414. package/dist/server/edge.js +1 -0
  415. package/dist/server/framework-request-handler.js +31 -3
  416. package/dist/server/google-oauth.d.ts +3 -0
  417. package/dist/server/google-oauth.js +3 -0
  418. package/dist/server/index.d.ts +4 -4
  419. package/dist/server/index.js +3 -3
  420. package/dist/server/onboarding-html.js +37 -3
  421. package/dist/server/realtime-token.d.ts +1 -1
  422. package/dist/server/transcribe-voice.d.ts +1 -1
  423. package/dist/server/workspace-provider-oauth.d.ts +6 -1
  424. package/dist/server/workspace-provider-oauth.js +72 -20
  425. package/dist/shared/agent-sidebar-url.d.ts +1 -0
  426. package/dist/shared/agent-sidebar-url.js +1 -0
  427. package/dist/shared/environment-lanes.d.ts +2 -0
  428. package/dist/shared/environment-lanes.js +3 -1
  429. package/dist/shared/index.d.ts +3 -1
  430. package/dist/shared/index.js +3 -1
  431. package/dist/shared/surface-visibility.d.ts +31 -0
  432. package/dist/shared/surface-visibility.js +57 -0
  433. package/dist/templates/chat/.agents/skills/secrets/SKILL.md +11 -4
  434. package/dist/templates/chat/app/routes.ts +3 -1
  435. package/dist/templates/chat/vitest.config.ts +8 -0
  436. package/dist/templates/default/.agents/skills/secrets/SKILL.md +11 -4
  437. package/dist/templates/default/app/routes.ts +3 -1
  438. package/dist/templates/headless/.agents/skills/secrets/SKILL.md +11 -4
  439. package/dist/templates/workspace-core/.agents/skills/secrets/SKILL.md +11 -4
  440. package/dist/tracking/registry.d.ts +11 -0
  441. package/dist/tracking/registry.js +5 -2
  442. package/dist/triggers/actions.js +10 -3
  443. package/dist/usage/store.js +23 -3
  444. package/dist/user-profile/actions/get-auth-methods.js +18 -5
  445. package/dist/vite/client.js +24 -5
  446. package/docs/content/actions-access-control.mdx +43 -4
  447. package/docs/content/actions-defining.mdx +16 -0
  448. package/docs/content/template-clips-capture-everywhere.mdx +29 -30
  449. package/docs/content/template-clips-developers.mdx +4 -4
  450. package/docs/content/template-clips.mdx +3 -1
  451. package/package.json +2 -2
  452. package/src/eject/workspace-connections.ts +4 -0
  453. package/src/templates/chat/.agents/skills/secrets/SKILL.md +11 -4
  454. package/src/templates/chat/app/routes.ts +3 -1
  455. package/src/templates/chat/vitest.config.ts +8 -0
  456. package/src/templates/default/.agents/skills/secrets/SKILL.md +11 -4
  457. package/src/templates/default/app/routes.ts +3 -1
  458. package/src/templates/headless/.agents/skills/secrets/SKILL.md +11 -4
  459. package/src/templates/workspace-core/.agents/skills/secrets/SKILL.md +11 -4
@@ -4,6 +4,7 @@ import {
4
4
  oauthRedirectUri,
5
5
  } from "@agent-native/core/client/host";
6
6
  import { useT } from "@agent-native/core/client/i18n";
7
+ import { startWorkspaceProviderOAuth } from "@agent-native/core/client/integrations";
7
8
  import {
8
9
  IconCalendarCheck,
9
10
  IconX,
@@ -72,6 +73,15 @@ const STATUS_POLL_INTERVAL_MS = 2000;
72
73
  // permanently stuck and stall the interval forever.
73
74
  const STATUS_POLL_ABORT_MS = Math.max(10_000, STATUS_POLL_INTERVAL_MS * 4);
74
75
 
76
+ function startManagedGoogleOAuth(): void {
77
+ const returnPath = `${window.location.pathname}${window.location.search}`;
78
+ startWorkspaceProviderOAuth("google_calendar", {
79
+ appId: "calendar",
80
+ returnPath,
81
+ scope: "user",
82
+ });
83
+ }
84
+
75
85
  interface GoogleConnectBannerProps {
76
86
  variant?: "banner" | "hero";
77
87
  }
@@ -93,6 +103,7 @@ export function GoogleConnectBanner({
93
103
 
94
104
  const accounts = googleStatus.data?.accounts ?? [];
95
105
  const hasAccounts = accounts.length > 0;
106
+ const googleConfigured = googleStatus.data?.configured === true;
96
107
  const canOfferOAuthSetup = useMemo(() => shouldOfferGoogleOAuthSetup(), []);
97
108
 
98
109
  const isBuilderFrame = useMemo(() => isInBuilderFrame(), []);
@@ -297,15 +308,17 @@ export function GoogleConnectBanner({
297
308
  }, [wantAddAccount, addAccountUrl.data, isBuilderFrame]);
298
309
 
299
310
  function handleConnect() {
311
+ if (!googleConfigured && !canOfferOAuthSetup) return;
300
312
  setDesktopAuthIssue(null);
301
313
  if (isDesktopGoogleAuth) {
302
314
  startDesktopGoogleAuth({ previousAccountCount: accounts.length });
303
315
  return;
304
316
  }
305
- setWantAuthUrl(true);
317
+ startManagedGoogleOAuth();
306
318
  }
307
319
 
308
320
  function handleAddAccount() {
321
+ if (!googleConfigured && !canOfferOAuthSetup) return;
309
322
  if (isDesktopGoogleAuth) {
310
323
  startDesktopGoogleAuth({
311
324
  addAccount: true,
@@ -313,7 +326,7 @@ export function GoogleConnectBanner({
313
326
  });
314
327
  return;
315
328
  }
316
- setWantAddAccount(true);
329
+ startManagedGoogleOAuth();
317
330
  }
318
331
 
319
332
  async function handleJsonUpload(file: File) {
@@ -371,6 +384,15 @@ export function GoogleConnectBanner({
371
384
  }
372
385
 
373
386
  if (dismissed) return null;
387
+ if (!googleStatus.data && !canOfferOAuthSetup && !googleStatus.isError)
388
+ return null;
389
+ if (
390
+ !googleConfigured &&
391
+ !canOfferOAuthSetup &&
392
+ !hasAccounts &&
393
+ !googleStatus.isError
394
+ )
395
+ return null;
374
396
 
375
397
  if (variant === "hero") {
376
398
  return (
@@ -384,25 +406,35 @@ export function GoogleConnectBanner({
384
406
  <p className="mt-2 max-w-xs text-[13px] text-muted-foreground leading-relaxed">
385
407
  {t("googleConnect.syncEventsDescription")}
386
408
  </p>
387
- <Button
388
- size="sm"
389
- className="mt-6 gap-2 px-4 h-8 text-[13px] font-medium"
390
- onClick={handleConnect}
391
- disabled={
392
- authUrl.isLoading ||
393
- authUrl.isFetching ||
394
- isGoogleDesktopAuthPending
395
- }
396
- >
397
- <GoogleIcon className="h-3.5 w-3.5" />
398
- {authUrl.isLoading
399
- ? t("common.connecting")
400
- : hasAccounts
401
- ? t("googleConnect.addAccount")
402
- : allConfigured
403
- ? t("googleConnect.connectGoogle")
409
+ {googleStatus.isError ? (
410
+ <Button
411
+ size="sm"
412
+ variant="outline"
413
+ className="mt-6 gap-2 px-4 h-8 text-[13px] font-medium"
414
+ onClick={() => void googleStatus.refetch()}
415
+ disabled={googleStatus.isFetching}
416
+ >
417
+ {t("common.retry")}
418
+ </Button>
419
+ ) : googleConfigured || canOfferOAuthSetup ? (
420
+ <Button
421
+ size="sm"
422
+ className="mt-6 gap-2 px-4 h-8 text-[13px] font-medium"
423
+ onClick={handleConnect}
424
+ disabled={
425
+ authUrl.isLoading ||
426
+ authUrl.isFetching ||
427
+ isGoogleDesktopAuthPending
428
+ }
429
+ >
430
+ <GoogleIcon className="h-3.5 w-3.5" />
431
+ {authUrl.isLoading
432
+ ? t("common.connecting")
433
+ : hasAccounts
434
+ ? t("googleConnect.addAccount")
404
435
  : t("googleConnect.connectGoogle")}
405
- </Button>
436
+ </Button>
437
+ ) : null}
406
438
 
407
439
  <GoogleAuthIssuePanel
408
440
  issue={desktopAuthIssue}
@@ -419,12 +451,14 @@ export function GoogleConnectBanner({
419
451
  className="group flex items-center gap-1.5 text-xs text-muted-foreground"
420
452
  >
421
453
  <span>{account.email}</span>
422
- <button
423
- onClick={() => disconnectGoogle.mutate(account.email)}
424
- className="opacity-0 group-hover:opacity-100 transition-opacity text-foreground/25 hover:text-foreground/50"
425
- >
426
- <IconX className="h-3 w-3" />
427
- </button>
454
+ {!account.shared && (
455
+ <button
456
+ onClick={() => disconnectGoogle.mutate(account.email)}
457
+ className="opacity-0 group-hover:opacity-100 transition-opacity text-foreground/25 hover:text-foreground/50"
458
+ >
459
+ <IconX className="h-3 w-3" />
460
+ </button>
461
+ )}
428
462
  </div>
429
463
  ))}
430
464
  </div>
@@ -464,25 +498,29 @@ export function GoogleConnectBanner({
464
498
  className="group flex items-center gap-1.5 text-xs text-foreground/60"
465
499
  >
466
500
  <span className="truncate">{account.email}</span>
467
- <button
468
- onClick={() => disconnectGoogle.mutate(account.email)}
469
- className="opacity-0 group-hover:opacity-100 transition-opacity text-foreground/30 hover:text-foreground/60"
470
- >
471
- <IconX className="h-3 w-3" />
472
- </button>
501
+ {!account.shared && (
502
+ <button
503
+ onClick={() => disconnectGoogle.mutate(account.email)}
504
+ className="opacity-0 group-hover:opacity-100 transition-opacity text-foreground/30 hover:text-foreground/60"
505
+ >
506
+ <IconX className="h-3 w-3" />
507
+ </button>
508
+ )}
473
509
  </div>
474
510
  ))}
475
- <button
476
- onClick={handleAddAccount}
477
- disabled={
478
- addAccountUrl.isLoading ||
479
- addAccountUrl.isFetching ||
480
- isGoogleDesktopAuthPending
481
- }
482
- className="text-xs text-foreground/40 hover:text-foreground/60 transition-colors whitespace-nowrap"
483
- >
484
- {t("googleConnect.addAccountWithPlus")}
485
- </button>
511
+ {(googleConfigured || canOfferOAuthSetup) && (
512
+ <button
513
+ onClick={handleAddAccount}
514
+ disabled={
515
+ addAccountUrl.isLoading ||
516
+ addAccountUrl.isFetching ||
517
+ isGoogleDesktopAuthPending
518
+ }
519
+ className="text-xs text-foreground/40 hover:text-foreground/60 transition-colors whitespace-nowrap"
520
+ >
521
+ {t("googleConnect.addAccountWithPlus")}
522
+ </button>
523
+ )}
486
524
  </div>
487
525
  <Button
488
526
  variant="ghost"
@@ -499,6 +537,17 @@ export function GoogleConnectBanner({
499
537
  onDismiss={() => setDesktopAuthIssue(null)}
500
538
  className="mx-4 mb-3"
501
539
  />
540
+ {googleStatus.isError && (
541
+ <Button
542
+ variant="ghost"
543
+ size="sm"
544
+ className="mx-4 mb-2"
545
+ onClick={() => void googleStatus.refetch()}
546
+ disabled={googleStatus.isFetching}
547
+ >
548
+ {t("common.retry")}
549
+ </Button>
550
+ )}
502
551
  </div>
503
552
  );
504
553
  }
@@ -522,7 +571,17 @@ export function GoogleConnectBanner({
522
571
  </div>
523
572
 
524
573
  <div className="flex items-center gap-1.5 shrink-0">
525
- {showWizard && !allConfigured && canOfferOAuthSetup ? (
574
+ {googleStatus.isError ? (
575
+ <Button
576
+ size="sm"
577
+ variant="outline"
578
+ className="gap-1.5 text-xs h-7 font-medium"
579
+ onClick={() => void googleStatus.refetch()}
580
+ disabled={googleStatus.isFetching}
581
+ >
582
+ {t("common.retry")}
583
+ </Button>
584
+ ) : showWizard && !allConfigured && canOfferOAuthSetup ? (
526
585
  <Button
527
586
  size="sm"
528
587
  variant="outline"
@@ -168,32 +168,36 @@ export function OutOfOfficeEvent({
168
168
  />
169
169
  {!compactMarker && <span className="truncate">{title}</span>}
170
170
  </span>
171
+ {/* Resize handles must be children of the trigger button, not
172
+ siblings — the day column's create-event guard only checks
173
+ `closest("button")`, so a sibling here would let clicks near
174
+ the marker fall through to "create event at this hour". */}
175
+ {canManipulate && (
176
+ <div
177
+ data-resize-handle="true"
178
+ data-out-of-office-resize="top"
179
+ onPointerDown={(pointerEvent) => {
180
+ pointerEvent.stopPropagation();
181
+ onResizeTopPointerDown?.(pointerEvent);
182
+ }}
183
+ className="pointer-events-auto absolute right-1 top-0 z-40 h-1.5 w-5 cursor-n-resize"
184
+ style={{ touchAction: "none" }}
185
+ />
186
+ )}
187
+ {canManipulate && endsOnDay && (
188
+ <div
189
+ data-resize-handle="true"
190
+ data-out-of-office-resize="bottom"
191
+ onPointerDown={(pointerEvent) => {
192
+ pointerEvent.stopPropagation();
193
+ onResizeBottomPointerDown?.(pointerEvent);
194
+ }}
195
+ className="pointer-events-auto absolute bottom-0 right-1 z-40 h-1.5 w-5 cursor-s-resize"
196
+ style={{ touchAction: "none" }}
197
+ />
198
+ )}
171
199
  </button>
172
200
  </EventDetailPopover>
173
- {canManipulate && (
174
- <div
175
- data-resize-handle="true"
176
- data-out-of-office-resize="top"
177
- onPointerDown={(pointerEvent) => {
178
- pointerEvent.stopPropagation();
179
- onResizeTopPointerDown?.(pointerEvent);
180
- }}
181
- className="pointer-events-auto absolute right-1 z-40 h-1.5 w-5 cursor-n-resize"
182
- style={{ top: `${top}px`, touchAction: "none" }}
183
- />
184
- )}
185
- {canManipulate && endsOnDay && (
186
- <div
187
- data-resize-handle="true"
188
- data-out-of-office-resize="bottom"
189
- onPointerDown={(pointerEvent) => {
190
- pointerEvent.stopPropagation();
191
- onResizeBottomPointerDown?.(pointerEvent);
192
- }}
193
- className="pointer-events-auto absolute right-1 z-40 h-1.5 w-5 cursor-s-resize"
194
- style={{ top: `${top + height - 6}px`, touchAction: "none" }}
195
- />
196
- )}
197
201
  </>
198
202
  );
199
203
  }
@@ -29,6 +29,7 @@ import { useHiddenCalendars } from "@/hooks/use-hidden-calendars";
29
29
  import { useIsMobile } from "@/hooks/use-mobile";
30
30
  import { useNavigationState } from "@/hooks/use-navigation-state";
31
31
  import { prefetchPeopleContacts } from "@/hooks/use-people";
32
+ import { shouldOfferGoogleOAuthSetup } from "@/lib/google-oauth-setup";
32
33
 
33
34
  import { Sidebar } from "./Sidebar";
34
35
 
@@ -228,6 +229,10 @@ export function AppLayout({ children }: AppLayoutProps) {
228
229
  const queryClient = useQueryClient();
229
230
  const googleStatus = useGoogleAuthStatus();
230
231
  const hasAccounts = (googleStatus.data?.accounts?.length ?? 0) > 0;
232
+ const canOfferGoogleOAuthSetup = useMemo(
233
+ () => shouldOfferGoogleOAuthSetup(),
234
+ [],
235
+ );
231
236
  const isSettingsPage =
232
237
  location.pathname === "/settings" ||
233
238
  location.pathname.startsWith("/settings/");
@@ -437,11 +442,13 @@ export function AppLayout({ children }: AppLayoutProps) {
437
442
 
438
443
  {/* Show the full-page Google prompt only on the calendar view. */}
439
444
  {!googleStatus.isLoading &&
440
- !googleStatus.isError &&
441
445
  !hasAccounts &&
442
446
  !eventDraft &&
443
447
  isCalendarPage &&
444
- !isSettingsPage ? (
448
+ !isSettingsPage &&
449
+ (googleStatus.data?.configured === true ||
450
+ canOfferGoogleOAuthSetup ||
451
+ googleStatus.isError) ? (
445
452
  <main className="agent-native-app-main flex-1 overflow-y-auto">
446
453
  <GoogleConnectBanner variant="hero" />
447
454
  </main>
@@ -1,6 +1,7 @@
1
1
  import { appPath } from "@agent-native/core/client/api-path";
2
2
  import { DevDatabaseLink } from "@agent-native/core/client/db-admin";
3
3
  import { useT } from "@agent-native/core/client/i18n";
4
+ import { startWorkspaceProviderOAuth } from "@agent-native/core/client/integrations";
4
5
  import { openCommandMenu } from "@agent-native/core/client/navigation";
5
6
  import { OrgSwitcher } from "@agent-native/core/client/org";
6
7
  import { FeedbackButton } from "@agent-native/core/client/ui";
@@ -69,8 +70,6 @@ import {
69
70
  } from "@/hooks/use-external-calendars";
70
71
  import {
71
72
  useGoogleAuthStatus,
72
- useGoogleAuthUrl,
73
- useGoogleAddAccountUrl,
74
73
  useGoogleDesktopAuth,
75
74
  } from "@/hooks/use-google-auth";
76
75
  import {
@@ -86,6 +85,7 @@ import {
86
85
  type CalendarColorMode,
87
86
  } from "@/lib/calendar-view-preferences";
88
87
  import { EVENT_CATEGORY_COLORS } from "@/lib/event-colors";
88
+ import { shouldOfferGoogleOAuthSetup } from "@/lib/google-oauth-setup";
89
89
  import { cn } from "@/lib/utils";
90
90
 
91
91
  import { useCalendarContext } from "./AppLayout";
@@ -324,8 +324,6 @@ function MiniCalendar({
324
324
 
325
325
  function GoogleConnectSidebarButton() {
326
326
  const t = useT();
327
- const [wantAuthUrl, setWantAuthUrl] = useState(false);
328
- const authUrl = useGoogleAuthUrl(wantAuthUrl);
329
327
  const {
330
328
  isDesktopGoogleAuth,
331
329
  isGoogleDesktopAuthPending,
@@ -336,24 +334,17 @@ function GoogleConnectSidebarButton() {
336
334
  onSuccess: () => window.location.reload(),
337
335
  });
338
336
 
339
- useEffect(() => {
340
- if (!wantAuthUrl || !authUrl.data?.url) return;
341
- setWantAuthUrl(false);
342
- window.open(authUrl.data.url, "_blank");
343
- }, [wantAuthUrl, authUrl.data]);
344
-
345
- useEffect(() => {
346
- if (!authUrl.error) return;
347
- toast.error(authUrl.error.message);
348
- setWantAuthUrl(false);
349
- }, [authUrl.error]);
350
-
351
337
  function handleConnect() {
352
338
  if (isDesktopGoogleAuth) {
353
339
  startDesktopGoogleAuth({ previousAccountCount: 0 });
354
340
  return;
355
341
  }
356
- setWantAuthUrl(true);
342
+ const returnPath = `${window.location.pathname}${window.location.search}`;
343
+ startWorkspaceProviderOAuth("google_calendar", {
344
+ appId: "calendar",
345
+ returnPath,
346
+ scope: "user",
347
+ });
357
348
  }
358
349
 
359
350
  return (
@@ -369,14 +360,12 @@ function GoogleConnectSidebarButton() {
369
360
  size="sm"
370
361
  className="w-full gap-1.5 text-xs font-semibold"
371
362
  onClick={handleConnect}
372
- disabled={
373
- authUrl.isLoading ||
374
- authUrl.isFetching ||
375
- isGoogleDesktopAuthPending
376
- }
363
+ disabled={isGoogleDesktopAuthPending}
377
364
  >
378
365
  <IconExternalLink className="h-3 w-3" />
379
- {authUrl.isLoading ? t("common.connecting") : t("common.connect")}
366
+ {isGoogleDesktopAuthPending
367
+ ? t("common.connecting")
368
+ : t("common.connect")}
380
369
  </Button>
381
370
  </div>
382
371
  </div>
@@ -434,9 +423,11 @@ function ColorPickerPopover({
434
423
 
435
424
  function GoogleAccountsSection({
436
425
  accounts,
426
+ canAddAccount,
437
427
  onClose,
438
428
  }: {
439
429
  accounts: Array<{ email: string }>;
430
+ canAddAccount: boolean;
440
431
  onClose: () => void;
441
432
  }) {
442
433
  const t = useT();
@@ -450,8 +441,6 @@ function GoogleAccountsSection({
450
441
  () => accounts.map((account) => account.email),
451
442
  [accounts],
452
443
  );
453
- const [wantAddAccount, setWantAddAccount] = useState(false);
454
- const addAccountUrl = useGoogleAddAccountUrl(wantAddAccount);
455
444
  const {
456
445
  isDesktopGoogleAuth,
457
446
  isGoogleDesktopAuthPending,
@@ -462,18 +451,6 @@ function GoogleAccountsSection({
462
451
  onSuccess: () => window.location.reload(),
463
452
  });
464
453
 
465
- useEffect(() => {
466
- if (!wantAddAccount || !addAccountUrl.data?.url) return;
467
- window.open(addAccountUrl.data.url, "_blank");
468
- setWantAddAccount(false);
469
- }, [wantAddAccount, addAccountUrl.data]);
470
-
471
- useEffect(() => {
472
- if (!addAccountUrl.error) return;
473
- toast.error(addAccountUrl.error.message);
474
- setWantAddAccount(false);
475
- }, [addAccountUrl.error]);
476
-
477
454
  function handleAddAccount() {
478
455
  if (isDesktopGoogleAuth) {
479
456
  startDesktopGoogleAuth({
@@ -482,7 +459,12 @@ function GoogleAccountsSection({
482
459
  });
483
460
  return;
484
461
  }
485
- setWantAddAccount(true);
462
+ const returnPath = `${window.location.pathname}${window.location.search}`;
463
+ startWorkspaceProviderOAuth("google_calendar", {
464
+ appId: "calendar",
465
+ returnPath,
466
+ scope: "user",
467
+ });
486
468
  }
487
469
 
488
470
  function accountColorMode(email: string): CalendarColorMode {
@@ -528,23 +510,21 @@ function GoogleAccountsSection({
528
510
  {t("sidebar.googleCalendarSettings")}
529
511
  </TooltipContent>
530
512
  </Tooltip>
531
- <Tooltip>
532
- <TooltipTrigger asChild>
533
- <button
534
- type="button"
535
- onClick={handleAddAccount}
536
- disabled={
537
- addAccountUrl.isLoading ||
538
- addAccountUrl.isFetching ||
539
- isGoogleDesktopAuthPending
540
- }
541
- className="flex h-5 w-5 items-center justify-center rounded text-muted-foreground hover:text-foreground"
542
- >
543
- <IconPlus className="h-3.5 w-3.5" />
544
- </button>
545
- </TooltipTrigger>
546
- <TooltipContent>{t("sidebar.addGoogleAccount")}</TooltipContent>
547
- </Tooltip>
513
+ {canAddAccount && (
514
+ <Tooltip>
515
+ <TooltipTrigger asChild>
516
+ <button
517
+ type="button"
518
+ onClick={handleAddAccount}
519
+ disabled={isGoogleDesktopAuthPending}
520
+ className="flex h-5 w-5 items-center justify-center rounded text-muted-foreground hover:text-foreground"
521
+ >
522
+ <IconPlus className="h-3.5 w-3.5" />
523
+ </button>
524
+ </TooltipTrigger>
525
+ <TooltipContent>{t("sidebar.addGoogleAccount")}</TooltipContent>
526
+ </Tooltip>
527
+ )}
548
528
  </div>
549
529
  </div>
550
530
 
@@ -681,6 +661,10 @@ export function Sidebar({
681
661
  const removeExternal = useRemoveExternalCalendar();
682
662
  const updateExternalColor = useUpdateExternalCalendarColor();
683
663
  const isConnected = googleStatus.data?.connected ?? false;
664
+ const canOfferGoogleOAuthSetup = useMemo(
665
+ () => shouldOfferGoogleOAuthSetup(),
666
+ [],
667
+ );
684
668
  const [peopleGroupOpen, setPeopleGroupOpen] = useState(
685
669
  () => overlayPeople.length <= 2, // i18n-ignore scanner false positive
686
670
  );
@@ -903,14 +887,19 @@ export function Sidebar({
903
887
  </nav>
904
888
 
905
889
  {/* Google status / connect CTA */}
906
- {!googleStatus.isLoading && !isConnected && (
907
- <GoogleConnectSidebarButton />
908
- )}
890
+ {!googleStatus.isLoading &&
891
+ !isConnected &&
892
+ (googleStatus.data?.configured === true ||
893
+ canOfferGoogleOAuthSetup) && <GoogleConnectSidebarButton />}
909
894
 
910
895
  {isConnected &&
911
896
  (googleStatus.data?.accounts?.length ?? 0) > 0 && (
912
897
  <GoogleAccountsSection
913
898
  accounts={googleStatus.data!.accounts!}
899
+ canAddAccount={
900
+ googleStatus.data?.configured === true ||
901
+ canOfferGoogleOAuthSetup
902
+ }
914
903
  onClose={onClose}
915
904
  />
916
905
  )}
@@ -115,7 +115,11 @@ export function useUpdateBookingLink() {
115
115
  >("update-booking-link", {
116
116
  onSuccess: (updated) => {
117
117
  queryClient.setQueryData<BookingLink[]>(LIST_KEY, (current = []) =>
118
- current.map((link) => (link.id === updated.id ? updated : link)),
118
+ current.map((link) =>
119
+ link.id === updated.id
120
+ ? { ...updated, accessRole: updated.accessRole ?? link.accessRole }
121
+ : link,
122
+ ),
119
123
  );
120
124
  queryClient.invalidateQueries({
121
125
  queryKey: LIST_KEY,
@@ -71,38 +71,64 @@ export function computeTimedEventLayout(
71
71
  return a.inputOrder - b.inputOrder;
72
72
  });
73
73
 
74
- // Put overlapping events into the first layer that is free at their start.
75
- // Reusing finished layers keeps chained overlaps from creating empty gaps.
76
- const overlapLayers: EventEntry[][] = [];
77
- const eventColumns = new Map<CalendarEvent, number>();
74
+ // Split the sorted events into connected overlap groups: a run of events
75
+ // where each overlaps the running span of the group before it. Interval
76
+ // graphs make this sweep exact — two events end up in the same component
77
+ // iff a chain of pairwise overlaps connects them — so an isolated event
78
+ // later in the day never inherits column math from an unrelated overlap
79
+ // earlier in the day.
80
+ const groups: EventEntry[][] = [];
81
+ let groupMaxEnd = -Infinity;
78
82
 
79
83
  for (const entry of sorted) {
80
- let column = overlapLayers.findIndex((layerEntries) =>
81
- layerEntries.every((placed) => !overlaps(placed.bounds, entry.bounds)),
82
- );
83
-
84
- if (column === -1) {
85
- column = overlapLayers.length;
86
- overlapLayers.push([]);
84
+ if (groups.length === 0 || entry.bounds.start >= groupMaxEnd) {
85
+ groups.push([]);
86
+ groupMaxEnd = -Infinity;
87
87
  }
88
-
89
- overlapLayers[column].push(entry);
90
- eventColumns.set(entry.event, column);
88
+ groups[groups.length - 1].push(entry);
89
+ groupMaxEnd = Math.max(groupMaxEnd, entry.bounds.end);
91
90
  }
92
91
 
93
- const totalCols = overlapLayers.length;
94
-
95
- for (const [stackOrder, entry] of sorted.entries()) {
96
- const col = eventColumns.get(entry.event)!;
92
+ let stackOrder = 0;
93
+ for (const group of groups) {
94
+ // Put overlapping events into the first layer that is free at their
95
+ // start. Reusing finished layers keeps chained overlaps from creating
96
+ // empty gaps.
97
+ const overlapLayers: EventEntry[][] = [];
98
+ const eventColumns = new Map<CalendarEvent, number>();
99
+
100
+ for (const entry of group) {
101
+ let column = overlapLayers.findIndex((layerEntries) =>
102
+ layerEntries.every((placed) => !overlaps(placed.bounds, entry.bounds)),
103
+ );
104
+
105
+ if (column === -1) {
106
+ column = overlapLayers.length;
107
+ overlapLayers.push([]);
108
+ }
109
+
110
+ overlapLayers[column].push(entry);
111
+ eventColumns.set(entry.event, column);
112
+ }
97
113
 
98
- result.set(entry.event.id, {
99
- left: 0,
100
- width: 100,
101
- indent: col * OVERLAP_INDENT_PX,
102
- col,
103
- totalCols,
104
- stackOrder,
105
- });
114
+ const totalCols = overlapLayers.length;
115
+ // Give every overlap column a proportional slice of the day column so an
116
+ // event's right edge stays visible instead of being covered by whichever
117
+ // card renders on top of it.
118
+ const width = 100 / totalCols;
119
+
120
+ for (const entry of group) {
121
+ const col = eventColumns.get(entry.event)!;
122
+
123
+ result.set(entry.event.id, {
124
+ left: col * width,
125
+ width,
126
+ indent: col * OVERLAP_INDENT_PX,
127
+ col,
128
+ totalCols,
129
+ stackOrder: stackOrder++,
130
+ });
131
+ }
106
132
  }
107
133
 
108
134
  return result;