@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
@@ -97,6 +97,8 @@ export interface OAuthStatePayload {
97
97
  mobile?: boolean;
98
98
  addAccount?: boolean;
99
99
  app?: string;
100
+ /** Optional signed scope for provider-specific OAuth flows. */
101
+ scope?: string;
100
102
  /**
101
103
  * Same-origin path to redirect to after a successful web-flow sign-in.
102
104
  * Threaded through the (HMAC-signed) state so it survives the round trip
@@ -129,6 +131,7 @@ export interface EncodeOAuthStateOptions {
129
131
  mobile?: boolean;
130
132
  addAccount?: boolean;
131
133
  app?: string;
134
+ scope?: string;
132
135
  returnUrl?: string;
133
136
  flowId?: string;
134
137
  desktopVerifierHash?: string;
@@ -459,6 +459,8 @@ export function encodeOAuthState(redirectUriOrOpts, owner, desktop, addAccount,
459
459
  payload.a = true;
460
460
  if (opts.app)
461
461
  payload.app = opts.app;
462
+ if (opts.scope)
463
+ payload.s = opts.scope;
462
464
  if (opts.returnUrl)
463
465
  payload.r2 = opts.returnUrl;
464
466
  if (opts.flowId)
@@ -511,6 +513,7 @@ export function decodeOAuthState(stateParam, fallbackUri) {
511
513
  mobile: !!parsed.m,
512
514
  addAccount: !!parsed.a,
513
515
  app: typeof parsed.app === "string" ? parsed.app : undefined,
516
+ scope: typeof parsed.s === "string" ? parsed.s : undefined,
514
517
  // Pass returnUrl through as-is — same-origin validation runs at the
515
518
  // consumer (oauthCallbackResponse → safeReturnPath). The state is
516
519
  // HMAC-signed, but we still validate at consumption as defence in
@@ -69,13 +69,13 @@ export { createOnboardingPlugin, defaultOnboardingPlugin, } from "../onboarding/
69
69
  export { registerFileUploadProvider, unregisterFileUploadProvider, listFileUploadProviders, getActiveFileUploadProvider, getActiveFileUploadProviderForRequest, uploadFile, builderFileUploadProvider, type FileUploadInput, type FileUploadProvider, type FileUploadResult, } from "../file-upload/index.js";
70
70
  export { createIntegrationsPlugin, defaultIntegrationsPlugin, enqueueRemoteCommand, slackAdapter, telegramAdapter, whatsappAdapter, discordAdapter, microsoftTeamsAdapter, emailAdapter, assertPlatformCapability, type PlatformAdapter, type IncomingMessage, type OutgoingMessage, type PlatformAdapterCapabilities, type ImmediateWebhookResponse, type IntegrationStatus, type IntegrationsPluginOptions, type IntegrationExecutionContext, BUILT_IN_INTEGRATION_CATALOG, INTEGRATION_CATEGORIES, getIntegrationCatalogEntry, listBuiltInChannelIntegrations, listIntegrationCatalog, type BuiltInChannelId, type ChannelCapabilities, type IntegrationAvailability, type IntegrationCatalogEntry, type IntegrationCategory, type IntegrationCredentialRequirement, type IntegrationIconKey, type IntegrationSupportMaturity, } from "../integrations/index.js";
71
71
  export { isElectron, isMobile, getOrigin, getAppBasePath, getAppUrl, resolveOAuthRedirectUri, isAllowedOAuthRedirectUri, encodeOAuthState, decodeOAuthState, resolveOAuthOwner, createOAuthSession, oauthCallbackResponse, oauthErrorPage, oauthDesktopExchangePage, type OAuthStatePayload, type OAuthOwnerResult, type OAuthSessionResult, } from "./google-oauth.js";
72
- export { buildWorkspaceProviderAuthorizationUrl, createWorkspaceProviderOAuthHandler, exchangeWorkspaceProviderOAuthCode, handleWorkspaceProviderOAuthCallback, handleWorkspaceProviderOAuthStart, isWorkspaceProviderOAuthFlowValid, mergeWorkspaceOAuthValues, resolveWorkspaceProviderIdentity, workspaceProviderOAuthPath, type GenericWorkspaceOAuthProvider, type WorkspaceProviderOAuthFlow, } from "./workspace-provider-oauth.js";
73
- export { FeatureNotConfiguredError, hasBuilderPrivateKey, isBuilderEnvManaged, getBuilderProxyOrigin, getBuilderImageGenerationBaseUrl, getBuilderWebSearchBaseUrl, getBuilderAuthHeader, resolveBuilderPrivateKey, resolveBuilderAuthHeader, resolveHasBuilderPrivateKey, resolveHasCompleteBuilderConnection, resolveBuilderCredentials, resolveBuilderCredentialsDetailed, resolveBuilderGatewayCredentials, resolveBuilderGatewayCredentialsDetailed, resolveBuilderCredentialSource, resolveBuilderCredential, readDeployCredentialEnv, writeBuilderCredentials, deleteBuilderCredentials, resolveSecret, type BuilderCredentialsDetailed, } from "./credential-provider.js";
74
- export { builderDesignSystemUrl, builderProjectBranchUrl, buildBuilderDesignSystemIndexFiles, collectBuilderDesignSystemGitHubFiles, createBuilderDesignSystemProxyFields, fetchBuilderDesignSystemDecodeJobStatus, fetchBuilderDesignSystemDocs, getBuilderDesignSystemsBaseUrl, hydrateBuilderDesignSystemReference, indexBuilderDesignSystem, localBuilderDesignSystemId, mimeTypeForBuilderDesignSystemFilename, parseBuilderDesignSystemProxyReference, startBuilderDesignSystemIndex, startBuilderDesignSystemUpload, type BuildBuilderDesignSystemIndexFilesOptions, type BuilderDesignSystemCodeFileInput, type BuilderDesignSystemDecodeJobStatus, type BuilderDesignSystemDocsOptions, type BuilderDesignSystemDocument, type BuilderDesignSystemHydratedReference, type BuilderDesignSystemIndexFile, type BuilderDesignSystemIndexFromSourcesOptions, type BuilderDesignSystemIndexOptions, type BuilderDesignSystemIndexResult, type BuilderDesignSystemGitHubFile, type BuilderDesignSystemGitHubFileCollection, type BuilderDesignSystemGitHubSource, type BuilderDesignSystemUploadAttachment, type BuilderDesignSystemUploadSlot, type BuilderDesignSystemProxyFields, type BuilderDesignSystemProxyFieldsOptions, type BuilderDesignSystemProxyReference, type BuilderDesignSystemSourceKind, } from "./builder-design-systems.js";
72
+ export { buildWorkspaceProviderAuthorizationUrl, createWorkspaceProviderOAuthHandler, exchangeWorkspaceProviderOAuthCode, handleWorkspaceProviderOAuthCallback, handleWorkspaceProviderOAuthStart, hasWorkspaceProviderOAuthCredentials, isGoogleWorkspaceOAuthProvider, isWorkspaceProviderOAuthFlowValid, mergeWorkspaceOAuthValues, resolveWorkspaceProviderIdentity, workspaceProviderOAuthPath, type GenericWorkspaceOAuthProvider, type WorkspaceProviderOAuthFlow, } from "./workspace-provider-oauth.js";
73
+ export { CredentialStoreUnavailableError, FeatureNotConfiguredError, hasBuilderPrivateKey, isBuilderEnvManaged, getBuilderProxyOrigin, getBuilderImageGenerationBaseUrl, getBuilderWebSearchBaseUrl, getBuilderAuthHeader, resolveBuilderPrivateKey, resolveBuilderAuthHeader, resolveHasBuilderPrivateKey, resolveHasCompleteBuilderConnection, resolveBuilderCredentials, resolveBuilderCredentialsDetailed, resolveBuilderGatewayCredentials, resolveBuilderGatewayCredentialsDetailed, resolveBuilderCredentialSource, resolveBuilderCredential, readDeployCredentialEnv, writeBuilderCredentials, deleteBuilderCredentials, resolveSecret, type BuilderCredentialsDetailed, } from "./credential-provider.js";
74
+ export { builderDesignSystemUrl, builderProjectBranchUrl, buildBuilderDesignSystemIndexFiles, collectBuilderDesignSystemGitHubFiles, createBuilderDesignSystemProxyFields, fetchBuilderDesignSystemDecodeJobStatus, fetchBuilderDesignSystemDocs, getBuilderDesignSystemsBaseUrl, hydrateBuilderDesignSystemReference, indexBuilderDesignSystem, localBuilderDesignSystemId, mimeTypeForBuilderDesignSystemFilename, parseBuilderDesignSystemProxyReference, startBuilderDesignSystemIndex, startBuilderDesignSystemUpload, type BuildBuilderDesignSystemIndexFilesOptions, type BuilderDesignSystemCodeFileInput, type BuilderDesignSystemDecodeJobStatus, type BuilderDesignSystemDocsOptions, type BuilderDesignSystemDocument, type BuilderDesignSystemHydratedReference, type BuilderDesignSystemIndexFile, type BuilderDesignSystemIndexFromSourcesOptions, type BuilderDesignSystemIndexOptions, type BuilderDesignSystemIndexResult, type BuilderDesignSystemStatus, type BuilderDesignSystemGitHubFile, type BuilderDesignSystemGitHubFileCollection, type BuilderDesignSystemGitHubSource, type BuilderDesignSystemUploadAttachment, type BuilderDesignSystemUploadSlot, type BuilderDesignSystemProxyFields, type BuilderDesignSystemProxyFieldsOptions, type BuilderDesignSystemProxyReference, type BuilderDesignSystemSourceKind, } from "./builder-design-systems.js";
75
75
  export { createBuilderProject, ensureBuilderProject, findBuilderProjectForRepo, getBuilderBranchProjectId, isBuilderBranchingEnabled, requestBuilderBrowserConnection, resolveBuilderBranchProjectId, resolveIsBuilderBranchingEnabled, runBuilderAgent, type BuilderProjectResult, type RunBuilderAgentResult, } from "./builder-browser.js";
76
76
  export { ensureFusionContainer, sendFusionBranchMessage, pushFusionBranch, reserveFusionHostingSlug, deployFusionProject, getFusionDeploys, getFusionBranchEditorUrl, getFusionHostingUrl, type FusionBranchRef, type EnsureFusionContainerResult, type SendFusionMessageResult, } from "./fusion-app.js";
77
77
  export { sendEmail, isEmailConfigured, getEmailReadiness, getEmailProvider, type EmailAttachment, type EmailReadiness, type EmailProvider, type SendEmailArgs, } from "./email.js";
78
- export { defineTransactionalEmail, listTransactionalEmails, getTransactionalEmail, renderTransactionalEmailPreview, type TransactionalEmailDefinition, type RegisteredTransactionalEmail, } from "../email-catalog/registry.js";
78
+ export { defineTransactionalEmail, defineTransactionalEmails, replaceTransactionalEmails, listTransactionalEmails, getTransactionalEmail, renderTransactionalEmailPreview, type TransactionalEmailDefinition, type RegisteredTransactionalEmail, } from "../email-catalog/registry.js";
79
79
  export { notifyActivity, runActivityNotification, resolveActivityRecipients, type ActivityDeliveryFailure, type ActivityNotificationResult, type ActivityNotificationStatus, type NotifyActivityInput, type ResolveActivityRecipientsInput, } from "./activity-notifications.js";
80
80
  export { renderEmail, emailStrong, emailLink, type RenderEmailArgs, type RenderedEmail, type EmailCta, } from "./email-template.js";
81
81
  export { getAppProductionUrl, getFirstPartyProdUrl } from "./app-url.js";
@@ -74,8 +74,8 @@ export { createOnboardingPlugin, defaultOnboardingPlugin, } from "../onboarding/
74
74
  export { registerFileUploadProvider, unregisterFileUploadProvider, listFileUploadProviders, getActiveFileUploadProvider, getActiveFileUploadProviderForRequest, uploadFile, builderFileUploadProvider, } from "../file-upload/index.js";
75
75
  export { createIntegrationsPlugin, defaultIntegrationsPlugin, enqueueRemoteCommand, slackAdapter, telegramAdapter, whatsappAdapter, discordAdapter, microsoftTeamsAdapter, emailAdapter, assertPlatformCapability, BUILT_IN_INTEGRATION_CATALOG, INTEGRATION_CATEGORIES, getIntegrationCatalogEntry, listBuiltInChannelIntegrations, listIntegrationCatalog, } from "../integrations/index.js";
76
76
  export { isElectron, isMobile, getOrigin, getAppBasePath, getAppUrl, resolveOAuthRedirectUri, isAllowedOAuthRedirectUri, encodeOAuthState, decodeOAuthState, resolveOAuthOwner, createOAuthSession, oauthCallbackResponse, oauthErrorPage, oauthDesktopExchangePage, } from "./google-oauth.js";
77
- export { buildWorkspaceProviderAuthorizationUrl, createWorkspaceProviderOAuthHandler, exchangeWorkspaceProviderOAuthCode, handleWorkspaceProviderOAuthCallback, handleWorkspaceProviderOAuthStart, isWorkspaceProviderOAuthFlowValid, mergeWorkspaceOAuthValues, resolveWorkspaceProviderIdentity, workspaceProviderOAuthPath, } from "./workspace-provider-oauth.js";
78
- export { FeatureNotConfiguredError, hasBuilderPrivateKey, isBuilderEnvManaged, getBuilderProxyOrigin, getBuilderImageGenerationBaseUrl, getBuilderWebSearchBaseUrl, getBuilderAuthHeader, resolveBuilderPrivateKey, resolveBuilderAuthHeader, resolveHasBuilderPrivateKey, resolveHasCompleteBuilderConnection, resolveBuilderCredentials, resolveBuilderCredentialsDetailed,
77
+ export { buildWorkspaceProviderAuthorizationUrl, createWorkspaceProviderOAuthHandler, exchangeWorkspaceProviderOAuthCode, handleWorkspaceProviderOAuthCallback, handleWorkspaceProviderOAuthStart, hasWorkspaceProviderOAuthCredentials, isGoogleWorkspaceOAuthProvider, isWorkspaceProviderOAuthFlowValid, mergeWorkspaceOAuthValues, resolveWorkspaceProviderIdentity, workspaceProviderOAuthPath, } from "./workspace-provider-oauth.js";
78
+ export { CredentialStoreUnavailableError, FeatureNotConfiguredError, hasBuilderPrivateKey, isBuilderEnvManaged, getBuilderProxyOrigin, getBuilderImageGenerationBaseUrl, getBuilderWebSearchBaseUrl, getBuilderAuthHeader, resolveBuilderPrivateKey, resolveBuilderAuthHeader, resolveHasBuilderPrivateKey, resolveHasCompleteBuilderConnection, resolveBuilderCredentials, resolveBuilderCredentialsDetailed,
79
79
  // Gateway lane, for the metered surfaces a deployed site can call without an
80
80
  // identity — image and video generation, realtime transcription. Falls
81
81
  // through to the identity credential first, so a consumer moves lane by
@@ -85,7 +85,7 @@ export { builderDesignSystemUrl, builderProjectBranchUrl, buildBuilderDesignSyst
85
85
  export { createBuilderProject, ensureBuilderProject, findBuilderProjectForRepo, getBuilderBranchProjectId, isBuilderBranchingEnabled, requestBuilderBrowserConnection, resolveBuilderBranchProjectId, resolveIsBuilderBranchingEnabled, runBuilderAgent, } from "./builder-browser.js";
86
86
  export { ensureFusionContainer, sendFusionBranchMessage, pushFusionBranch, reserveFusionHostingSlug, deployFusionProject, getFusionDeploys, getFusionBranchEditorUrl, getFusionHostingUrl, } from "./fusion-app.js";
87
87
  export { sendEmail, isEmailConfigured, getEmailReadiness, getEmailProvider, } from "./email.js";
88
- export { defineTransactionalEmail, listTransactionalEmails, getTransactionalEmail, renderTransactionalEmailPreview, } from "../email-catalog/registry.js";
88
+ export { defineTransactionalEmail, defineTransactionalEmails, replaceTransactionalEmails, listTransactionalEmails, getTransactionalEmail, renderTransactionalEmailPreview, } from "../email-catalog/registry.js";
89
89
  export { notifyActivity, runActivityNotification, resolveActivityRecipients, } from "./activity-notifications.js";
90
90
  export { renderEmail, emailStrong, emailLink, } from "./email-template.js";
91
91
  export { getAppProductionUrl, getFirstPartyProdUrl } from "./app-url.js";
@@ -11,7 +11,7 @@ import { getLocaleInitScript } from "../localization/server.js";
11
11
  import { DEFAULT_LOCALE, LOCALE_METADATA, LOCALE_STORAGE_KEY, SUPPORTED_LOCALES, localeDisplayName, } from "../localization/shared.js";
12
12
  import { NATIVE_AUTH_COPY } from "../shared/auth-copy.js";
13
13
  import { docsUrl } from "../shared/docs-url.js";
14
- import { BETA_OPT_OUT_DURATION_MS, BETA_OPT_OUT_QUERY_PARAM, BETA_OPT_OUT_STORAGE_KEY, ENVIRONMENT_BETA_HOSTS, } from "../shared/environment-lanes.js";
14
+ import { BETA_FORCE_QUERY_PARAM, BETA_FORCE_SESSION_STORAGE_KEY, BETA_OPT_OUT_DURATION_MS, BETA_OPT_OUT_QUERY_PARAM, BETA_OPT_OUT_STORAGE_KEY, ENVIRONMENT_BETA_HOSTS, } from "../shared/environment-lanes.js";
15
15
  import { PASSWORD_MAX_LENGTH, PASSWORD_MIN_LENGTH, } from "../shared/password-policy.js";
16
16
  import { signInJourneyInlineScript } from "../shared/sign-in-journey.js";
17
17
  import { AGENT_NATIVE_SOCIAL_IMAGE_ALT, AGENT_NATIVE_SOCIAL_IMAGE_HEIGHT, AGENT_NATIVE_SOCIAL_IMAGE_PATH, AGENT_NATIVE_SOCIAL_IMAGE_TYPE, AGENT_NATIVE_SOCIAL_IMAGE_WIDTH, withAgentNativeSocialImageCacheBuster, } from "../shared/social-meta.js";
@@ -1035,6 +1035,7 @@ ${localeMenuItemsHtml}
1035
1035
  <div class="environment-popover-title" id="environment-popover-title">You're on Agent Native Beta</div>
1036
1036
  <div class="environment-popover-copy">Choose where you want to continue.</div>
1037
1037
  <a class="environment-production-link" id="environment-production-link" href="">Switch to production</a>
1038
+ <button type="button" class="environment-hide-badge" id="environment-hide-badge">Hide badge</button>
1038
1039
  </div>
1039
1040
  </div>`;
1040
1041
  const hostedSignupLegalNotice = opts.signupLegalNotice === undefined &&
@@ -1430,9 +1431,19 @@ ${marketing.description ? ` <p class="app-desc" data-marketing-field="descr
1430
1431
  var button = document.getElementById('environment-badge');
1431
1432
  var popover = document.getElementById('environment-popover');
1432
1433
  var productionLink = document.getElementById('environment-production-link');
1433
- if (!switcher || !button || !popover || !productionLink) return;
1434
+ var hideButton = document.getElementById('environment-hide-badge');
1435
+ if (!switcher || !button || !popover || !productionLink || !hideButton) return;
1434
1436
  if (window.parent !== window) return;
1435
1437
 
1438
+ try {
1439
+ var forceUrl = new URL(window.location.href);
1440
+ if (forceUrl.searchParams.get(${JSON.stringify(BETA_FORCE_QUERY_PARAM)}) === 'true') {
1441
+ window.sessionStorage.setItem(${JSON.stringify(BETA_FORCE_SESSION_STORAGE_KEY)}, '1');
1442
+ }
1443
+ } catch (error) {
1444
+ void error;
1445
+ }
1446
+
1436
1447
  // Persist the beta opt-out before authentication replaces this cached shell.
1437
1448
  try {
1438
1449
  var optOutUrl = new URL(window.location.href);
@@ -1496,6 +1507,10 @@ ${marketing.description ? ` <p class="app-desc" data-marketing-field="descr
1496
1507
  document.addEventListener('keydown', function(event) {
1497
1508
  if (event.key === 'Escape') setOpen(false);
1498
1509
  });
1510
+ hideButton.addEventListener('click', function() {
1511
+ setOpen(false);
1512
+ switcher.hidden = true;
1513
+ });
1499
1514
  })();`;
1500
1515
  return `<!DOCTYPE html>
1501
1516
  <html lang="${DEFAULT_LOCALE}" dir="ltr">
@@ -1668,7 +1683,8 @@ ${hasMarketing
1668
1683
  .environment-badge:hover,
1669
1684
  .environment-badge[aria-expanded="true"] { background: #4a4a4a; }
1670
1685
  .environment-badge:focus-visible,
1671
- .environment-production-link:focus-visible {
1686
+ .environment-production-link:focus-visible,
1687
+ .environment-hide-badge:focus-visible {
1672
1688
  outline: 2px solid #33c4ff;
1673
1689
  outline-offset: 2px;
1674
1690
  }
@@ -1700,6 +1716,24 @@ ${hasMarketing
1700
1716
  text-decoration: none;
1701
1717
  }
1702
1718
  .environment-production-link:hover { background: #242424; }
1719
+ .environment-hide-badge {
1720
+ display: flex;
1721
+ align-items: center;
1722
+ justify-content: center;
1723
+ width: 100%;
1724
+ min-height: 2rem;
1725
+ margin-top: 0.5rem;
1726
+ margin-bottom: -0.5rem;
1727
+ padding: 0.375rem 0.75rem;
1728
+ color: inherit;
1729
+ opacity: 0.65;
1730
+ border: 0;
1731
+ background: transparent;
1732
+ font: inherit;
1733
+ font-size: 0.8125rem;
1734
+ cursor: pointer;
1735
+ }
1736
+ .environment-hide-badge:hover { opacity: 1; }
1703
1737
  .card {
1704
1738
  width: 100%;
1705
1739
  max-width: 400px;
@@ -26,8 +26,8 @@ export declare function createRealtimeTokenHandler(): import("h3").EventHandlerW
26
26
  expiresAt?: undefined;
27
27
  ttlSeconds?: undefined;
28
28
  } | {
29
- error?: undefined;
30
29
  token: string;
31
30
  expiresAt: string;
32
31
  ttlSeconds: number;
32
+ error?: undefined;
33
33
  }>>;
@@ -1,7 +1,11 @@
1
1
  import { type H3Event } from "h3";
2
2
  import { type WorkspaceConnectionProvider } from "../connections/catalog.js";
3
3
  import { type OAuthStatePayload } from "./google-oauth.js";
4
- export type GenericWorkspaceOAuthProvider = "figma" | "google_drive" | "github" | "hubspot" | "salesforce" | "jira" | "sentry" | "notion";
4
+ export type GenericWorkspaceOAuthProvider = "figma" | "gmail" | "google_calendar" | "google_docs" | "google_drive" | "google_sheets" | "google_slides" | "github" | "hubspot" | "salesforce" | "jira" | "sentry" | "notion";
5
+ export type WorkspaceProviderOAuthScope = "user" | "organization" | "app";
6
+ export declare function isWorkspaceProviderOAuthScope(value: unknown): value is WorkspaceProviderOAuthScope;
7
+ export declare function isGoogleWorkspaceOAuthProvider(provider: string): boolean;
8
+ export declare function hasWorkspaceProviderOAuthCredentials(provider: GenericWorkspaceOAuthProvider): Promise<boolean>;
5
9
  export interface WorkspaceProviderOAuthFlow {
6
10
  provider: GenericWorkspaceOAuthProvider;
7
11
  flowId: string;
@@ -10,6 +14,7 @@ export interface WorkspaceProviderOAuthFlow {
10
14
  owner: string;
11
15
  orgId?: string;
12
16
  appId: string;
17
+ scope: WorkspaceProviderOAuthScope;
13
18
  salesforceLoginUrl?: string;
14
19
  expiresAt: number;
15
20
  }
@@ -13,7 +13,12 @@ import { decodeOAuthState, encodeOAuthState, getAppUrl, resolveOAuthRedirectUri,
13
13
  import { runWithRequestContext } from "./request-context.js";
14
14
  const SUPPORTED_PROVIDERS = new Set([
15
15
  "figma",
16
+ "gmail",
17
+ "google_calendar",
18
+ "google_docs",
16
19
  "google_drive",
20
+ "google_sheets",
21
+ "google_slides",
17
22
  "github",
18
23
  "hubspot",
19
24
  "salesforce",
@@ -26,7 +31,22 @@ const PROVIDER_REQUEST_TIMEOUT_MS = 10_000;
26
31
  const PROVIDER_RESPONSE_MAX_BYTES = 256 * 1024;
27
32
  const SALESFORCE_PRODUCTION_LOGIN_URL = "https://login.salesforce.com";
28
33
  const SALESFORCE_SANDBOX_LOGIN_URL = "https://test.salesforce.com";
29
- const WORKSPACE_OAUTH_ADMIN_ERROR = "Only organization admins or the relevant app admin can connect shared OAuth accounts.";
34
+ const WORKSPACE_OAUTH_ADMIN_ERROR = "This shared connection requires organization or app-admin access. Personal connections can be connected by any workspace member.";
35
+ export function isWorkspaceProviderOAuthScope(value) {
36
+ return value === "user" || value === "organization" || value === "app";
37
+ }
38
+ export function isGoogleWorkspaceOAuthProvider(provider) {
39
+ return (provider === "gmail" ||
40
+ provider === "google_calendar" ||
41
+ provider === "google_docs" ||
42
+ provider === "google_drive" ||
43
+ provider === "google_sheets" ||
44
+ provider === "google_slides");
45
+ }
46
+ export async function hasWorkspaceProviderOAuthCredentials(provider) {
47
+ const [clientId, clientSecret] = await resolveProviderClientCredentials(provider);
48
+ return Boolean(clientId && clientSecret);
49
+ }
30
50
  export function workspaceProviderOAuthPath(provider, phase) {
31
51
  return `/_agent-native/connections/oauth/${provider}/${phase}`;
32
52
  }
@@ -46,7 +66,14 @@ export async function handleWorkspaceProviderOAuthStart(event, providerId) {
46
66
  return unauthorized(event);
47
67
  const query = getQuery(event);
48
68
  const appId = normalizeAppId(text(query.appId) ?? getAppConfig().app.workspaceId ?? "creative-context");
49
- const orgContext = await requireWorkspaceProviderOAuthAdmin(event, appId);
69
+ const requestedScope = parseWorkspaceProviderOAuthScope(text(query.scope));
70
+ if (!requestedScope) {
71
+ setResponseStatus(event, 400);
72
+ return {
73
+ error: "OAuth connection scope must be user, organization, or app.",
74
+ };
75
+ }
76
+ const orgContext = await requireWorkspaceProviderOAuthAccess(event, appId, requestedScope);
50
77
  if (!orgContext) {
51
78
  return { error: WORKSPACE_OAUTH_ADMIN_ERROR };
52
79
  }
@@ -91,6 +118,7 @@ export async function handleWorkspaceProviderOAuthStart(event, providerId) {
91
118
  owner: session.email,
92
119
  orgId,
93
120
  app: appId,
121
+ scope: orgContext.oauthScope,
94
122
  returnUrl,
95
123
  flowId,
96
124
  });
@@ -102,6 +130,7 @@ export async function handleWorkspaceProviderOAuthStart(event, providerId) {
102
130
  owner: session.email,
103
131
  orgId,
104
132
  appId,
133
+ scope: orgContext.oauthScope,
105
134
  ...(salesforceLoginUrl ? { salesforceLoginUrl } : {}),
106
135
  expiresAt: Date.now() + FLOW_TTL_SECONDS * 1_000,
107
136
  };
@@ -134,7 +163,11 @@ export async function handleWorkspaceProviderOAuthCallback(event, providerId) {
134
163
  if (!session?.email)
135
164
  return unauthorized(event);
136
165
  const flow = readStoredFlow(event, providerId);
137
- const orgContext = await requireWorkspaceProviderOAuthAdmin(event, flow?.appId);
166
+ if (!flow || !isWorkspaceProviderOAuthScope(flow.scope)) {
167
+ setResponseStatus(event, 400);
168
+ return { error: "OAuth state is invalid or expired." };
169
+ }
170
+ const orgContext = await requireWorkspaceProviderOAuthAccess(event, flow.appId, flow.scope);
138
171
  if (!orgContext) {
139
172
  return { error: WORKSPACE_OAUTH_ADMIN_ERROR };
140
173
  }
@@ -204,8 +237,12 @@ export async function handleWorkspaceProviderOAuthCallback(event, providerId) {
204
237
  await saveOAuthTokens(provider.oauth.provider, accountId, tokens, session.email);
205
238
  await setOAuthDisplayName(provider.oauth.provider, accountId, identity.label);
206
239
  const existing = existingConnections.find((connection) => connection.accountId === accountId &&
207
- (orgContext.oauthScope === "organization" ||
208
- connection.allowedApps.some((allowedApp) => allowedApp.toLowerCase() === flow.appId.toLowerCase())));
240
+ (flow.scope === "user"
241
+ ? connection.allowedUsers.some((allowedUser) => allowedUser.toLowerCase() === session.email.toLowerCase())
242
+ : flow.scope === "organization"
243
+ ? connection.allowedUsers.length === 0 &&
244
+ (connection.allowedUserGroups?.length ?? 0) === 0
245
+ : connection.allowedApps.some((allowedApp) => allowedApp.toLowerCase() === flow.appId.toLowerCase())));
209
246
  const scopes = mergeWorkspaceOAuthValues(existing?.scopes ?? [], identity.scopes ?? tokenScopes(tokens, provider.oauth.scopes));
210
247
  const connectionConfig = {
211
248
  credentialMode: "oauth",
@@ -229,8 +266,10 @@ export async function handleWorkspaceProviderOAuthCallback(event, providerId) {
229
266
  accountLabel: identity.label,
230
267
  status: "connected",
231
268
  scopes,
232
- allowedApps: existing?.allowedApps ??
233
- (orgContext.oauthScope === "app" ? [flow.appId] : []),
269
+ allowedApps: existing?.allowedApps ?? (flow.scope === "app" ? [flow.appId] : []),
270
+ allowedUsers: flow.scope === "user"
271
+ ? [session.email]
272
+ : (existing?.allowedUsers ?? []),
234
273
  config: connectionConfig,
235
274
  lastCheckedAt: new Date(),
236
275
  lastError: null,
@@ -267,7 +306,7 @@ export function buildWorkspaceProviderAuthorizationUrl(input) {
267
306
  url.searchParams.set("audience", "api.atlassian.com");
268
307
  url.searchParams.set("prompt", "consent");
269
308
  }
270
- if (input.provider.id === "google_drive") {
309
+ if (isGoogleWorkspaceOAuthProvider(input.provider.id)) {
271
310
  url.searchParams.set("access_type", "offline");
272
311
  url.searchParams.set("include_granted_scopes", "true");
273
312
  url.searchParams.set("prompt", "consent");
@@ -393,7 +432,7 @@ export async function exchangeWorkspaceProviderOAuthCode(input) {
393
432
  ...(input.providerId === "sentry"
394
433
  ? { client_id: input.clientId, client_secret: input.clientSecret }
395
434
  : {}),
396
- ...(input.providerId === "google_drive"
435
+ ...(isGoogleWorkspaceOAuthProvider(input.providerId)
397
436
  ? { client_id: input.clientId, client_secret: input.clientSecret }
398
437
  : {}),
399
438
  };
@@ -566,19 +605,16 @@ async function resolveWorkspaceProviderIdentitySingle(providerId, tokens) {
566
605
  label: text(user?.email) ?? text(user?.name) ?? "Sentry account",
567
606
  };
568
607
  }
569
- if (providerId === "google_drive") {
608
+ if (isGoogleWorkspaceOAuthProvider(providerId)) {
570
609
  const accessToken = text(tokens.access_token);
571
- const { response, body } = await fetchBoundedProviderJson("https://www.googleapis.com/drive/v3/about?fields=user(displayName,emailAddress,permissionId)", { headers: { Authorization: `Bearer ${accessToken}` } }, "Google Drive");
572
- const user = record(body.user);
573
- const accountId = text(user?.permissionId) ?? text(user?.emailAddress);
610
+ const { response, body } = await fetchBoundedProviderJson("https://openidconnect.googleapis.com/v1/userinfo", { headers: { Authorization: `Bearer ${accessToken}` } }, "Google Workspace");
611
+ const accountId = text(body.email) ?? text(body.sub);
574
612
  if (!response.ok || !accountId) {
575
- throw new Error("Google Drive OAuth response did not identify the connected account.");
613
+ throw new Error("Google OAuth response did not identify the connected account.");
576
614
  }
577
615
  return {
578
616
  accountId,
579
- label: text(user?.emailAddress) ??
580
- text(user?.displayName) ??
581
- "Google Drive account",
617
+ label: text(body.email) ?? text(body.name) ?? "Google account",
582
618
  };
583
619
  }
584
620
  const accessToken = text(tokens.access_token);
@@ -615,6 +651,7 @@ export function isWorkspaceProviderOAuthFlowValid(input) {
615
651
  input.state.flowId === input.flow.flowId &&
616
652
  input.state.redirectUri === input.flow.redirectUri &&
617
653
  input.state.owner === input.flow.owner &&
654
+ input.state.scope === input.flow.scope &&
618
655
  input.sessionEmail === input.flow.owner &&
619
656
  input.state.orgId === input.flow.orgId &&
620
657
  input.sessionOrgId === input.flow.orgId &&
@@ -697,7 +734,9 @@ export function mergeWorkspaceOAuthValues(existing, incoming) {
697
734
  return [...new Set([...existing, ...incoming])];
698
735
  }
699
736
  function clientCredentialKeys(provider, field) {
700
- const prefix = provider === "google_drive" ? "GOOGLE" : provider.toUpperCase();
737
+ const prefix = isGoogleWorkspaceOAuthProvider(provider)
738
+ ? "GOOGLE"
739
+ : provider.toUpperCase();
701
740
  const suffix = field === "id" ? "ID" : "SECRET";
702
741
  if (provider === "github") {
703
742
  const integrationPrefix = `GITHUB_INTEGRATION_CLIENT_${suffix}`;
@@ -799,6 +838,11 @@ function normalizeAppId(value) {
799
838
  function text(value) {
800
839
  return typeof value === "string" && value.trim() ? value.trim() : undefined;
801
840
  }
841
+ function parseWorkspaceProviderOAuthScope(value) {
842
+ if (value === undefined)
843
+ return "organization";
844
+ return isWorkspaceProviderOAuthScope(value) ? value : null;
845
+ }
802
846
  function scalarText(value) {
803
847
  if (typeof value === "number" && Number.isFinite(value))
804
848
  return String(value);
@@ -817,15 +861,23 @@ function unauthorized(event) {
817
861
  setResponseStatus(event, 401);
818
862
  return { error: "Authentication required" };
819
863
  }
820
- async function requireWorkspaceProviderOAuthAdmin(event, appId) {
864
+ async function requireWorkspaceProviderOAuthAccess(event, appId, requestedScope = "organization") {
821
865
  const context = await getOrgContext(event).catch(() => null);
822
866
  if (!context || !context.orgId) {
823
867
  setResponseStatus(event, 403);
824
868
  return null;
825
869
  }
826
- if (canConnectWorkspaceProviderOAuth(context.orgId, context.role)) {
870
+ if (requestedScope === "user") {
871
+ return { ...context, oauthScope: "user" };
872
+ }
873
+ if (requestedScope === "organization" &&
874
+ canConnectWorkspaceProviderOAuth(context.orgId, context.role)) {
827
875
  return { ...context, oauthScope: "organization" };
828
876
  }
877
+ if (requestedScope === "app" &&
878
+ canConnectWorkspaceProviderOAuth(context.orgId, context.role)) {
879
+ return { ...context, oauthScope: "app" };
880
+ }
829
881
  if (appId) {
830
882
  const descriptor = getRegisteredAppRoles(appId);
831
883
  if (descriptor?.roles.some((role) => role === "admin")) {
@@ -1,5 +1,6 @@
1
1
  export declare const AGENT_NATIVE_OPEN_PATH = "/_agent-native/open";
2
2
  export declare const AGENT_SIDEBAR_QUERY_PARAM = "agentSidebar";
3
3
  export declare const AGENT_SIDEBAR_QUERY_VALUE_CLOSED = "closed";
4
+ export declare const AGENT_SIDEBAR_QUERY_VALUE_OPEN = "open";
4
5
  export declare function isAgentNativeOpenDeepLink(urlOrPath: string): boolean;
5
6
  export declare function withCollapsedAgentSidebarParam(urlOrPath: string): string;
@@ -1,6 +1,7 @@
1
1
  export const AGENT_NATIVE_OPEN_PATH = "/_agent-native/open";
2
2
  export const AGENT_SIDEBAR_QUERY_PARAM = "agentSidebar";
3
3
  export const AGENT_SIDEBAR_QUERY_VALUE_CLOSED = "closed";
4
+ export const AGENT_SIDEBAR_QUERY_VALUE_OPEN = "open";
4
5
  const RELATIVE_URL_BASE = "http://agent-native.invalid";
5
6
  function hasUrlScheme(urlOrPath) {
6
7
  return /^[a-z][a-z0-9+.-]*:/i.test(urlOrPath);
@@ -1,6 +1,8 @@
1
1
  export declare const BETA_OPT_OUT_QUERY_PARAM = "agentNativeBetaOptOut";
2
2
  export declare const BETA_OPT_OUT_DURATION_MS: number;
3
3
  export declare const BETA_OPT_OUT_STORAGE_KEY = "agent-native:beta-opt-out-until";
4
+ export declare const BETA_FORCE_QUERY_PARAM = "force";
5
+ export declare const BETA_FORCE_SESSION_STORAGE_KEY = "agent-native:force-production";
4
6
  export declare const ENVIRONMENT_BETA_HOSTS: {
5
7
  readonly "agent-workspace.builder.io": "beta.agent-workspace.builder.io";
6
8
  readonly "analytics.agent-native.com": "beta.analytics.agent-native.com";
@@ -1,6 +1,8 @@
1
1
  export const BETA_OPT_OUT_QUERY_PARAM = "agentNativeBetaOptOut";
2
- export const BETA_OPT_OUT_DURATION_MS = 24 * 60 * 60 * 1000;
2
+ export const BETA_OPT_OUT_DURATION_MS = 8 * 60 * 60 * 1000;
3
3
  export const BETA_OPT_OUT_STORAGE_KEY = "agent-native:beta-opt-out-until";
4
+ export const BETA_FORCE_QUERY_PARAM = "force";
5
+ export const BETA_FORCE_SESSION_STORAGE_KEY = "agent-native:force-production";
4
6
  export const ENVIRONMENT_BETA_HOSTS = {
5
7
  "agent-workspace.builder.io": "beta.agent-workspace.builder.io",
6
8
  "analytics.agent-native.com": "beta.analytics.agent-native.com",
@@ -6,13 +6,15 @@ export { truncate } from "./truncate.js";
6
6
  export { isHumanReadableDocumentTitle, normalizeDocumentTitle, } from "./document-title.js";
7
7
  export { injectDocumentMarkup } from "./html-document.js";
8
8
  export { withBuilderUtmTrackingParams } from "./builder-link-tracking.js";
9
+ export { BETA_FORCE_QUERY_PARAM, BETA_FORCE_SESSION_STORAGE_KEY, BETA_OPT_OUT_DURATION_MS, BETA_OPT_OUT_QUERY_PARAM, BETA_OPT_OUT_STORAGE_KEY, ENVIRONMENT_BETA_HOSTS, resolveEnvironmentTargets, type EnvironmentBadgeTargets, } from "./environment-lanes.js";
9
10
  export { SSR_HTML_CONTENT_TYPE, SSR_QUERY_CACHE_KEY_HEADER, type SsrHtmlContentTypeOptions, withSsrHtmlContentType, } from "./cache-control.js";
11
+ export { SURFACE_HIDDEN_FLAG, SURFACE_VISIBILITY_EVENT, addSurfaceVisibilityListener, buildSurfaceVisibilityScript, isHostSurfaceHidden, isSurfaceHidden, } from "./surface-visibility.js";
10
12
  export { AGENT_NATIVE_DOCS_ORIGIN, docsUrl, type DocsUrlOptions, } from "./docs-url.js";
11
13
  export { buildRuntimeConfigPrompt, formatRuntimeConfigReport, getRuntimeConfigReport, parseRuntimeConfigReport, runtimeConfigRequirementsFromSearchParams, type RuntimeConfigEnvironment, type RuntimeConfigIssue, type RuntimeConfigIssueCode, type RuntimeConfigIssueSeverity, type RuntimeConfigPhase, type RuntimeConfigReport, type RuntimeConfigRequirements, } from "./runtime-config.js";
12
14
  export { llmConnectionTrackingProperties, normalizeLlmConnection, type LlmConnectionStatus, } from "./llm-connection.js";
13
15
  export { DISPATCH_WORKSPACE_ROOT_REDIRECTS, RESERVED_WORKSPACE_APP_IDS, assertValidWorkspaceAppId, getWorkspaceAppIdValidationError, isValidWorkspaceAppIdFormat, normalizeWorkspaceAppId, } from "./workspace-app-id.js";
14
16
  export { DEFAULT_WORKSPACE_APP_AUDIENCE, WORKSPACE_APP_AUDIENCES, normalizeWorkspaceAppAudience, normalizeWorkspaceAppPathList, workspaceAppAudienceFromEnv, workspaceAppAudienceFromPackageJson, workspaceAppRouteAccessFromEnv, workspaceAppRouteAccessFromPackageJson, type WorkspaceAppRouteAccess, type WorkspaceAppRouteAccessFromConfig, type WorkspaceAppAudience, } from "./workspace-app-audience.js";
15
- export { AGENT_NATIVE_OPEN_PATH, AGENT_SIDEBAR_QUERY_PARAM, AGENT_SIDEBAR_QUERY_VALUE_CLOSED, isAgentNativeOpenDeepLink, withCollapsedAgentSidebarParam, } from "./agent-sidebar-url.js";
17
+ export { AGENT_NATIVE_OPEN_PATH, AGENT_SIDEBAR_QUERY_PARAM, AGENT_SIDEBAR_QUERY_VALUE_CLOSED, AGENT_SIDEBAR_QUERY_VALUE_OPEN, isAgentNativeOpenDeepLink, withCollapsedAgentSidebarParam, } from "./agent-sidebar-url.js";
16
18
  export { buildChatFirstAppCreationPrompt, titleFromChatFirstAppPrompt, type ChatFirstAppCreationPromptInput, type ChatFirstAppCreationResource, type ChatFirstAppCreationVaultAccessMode, } from "./chat-first-app-creation.js";
17
19
  export { NATIVE_AUTH_COPY, resolveNativeAuthCopy, type NativeAuthCopy, } from "./auth-copy.js";
18
20
  export { createPollEngine, type PollEngineOptions, type PollEngineHandle, } from "./poll-engine.js";
@@ -6,13 +6,15 @@ export { truncate } from "./truncate.js";
6
6
  export { isHumanReadableDocumentTitle, normalizeDocumentTitle, } from "./document-title.js";
7
7
  export { injectDocumentMarkup } from "./html-document.js";
8
8
  export { withBuilderUtmTrackingParams } from "./builder-link-tracking.js";
9
+ export { BETA_FORCE_QUERY_PARAM, BETA_FORCE_SESSION_STORAGE_KEY, BETA_OPT_OUT_DURATION_MS, BETA_OPT_OUT_QUERY_PARAM, BETA_OPT_OUT_STORAGE_KEY, ENVIRONMENT_BETA_HOSTS, resolveEnvironmentTargets, } from "./environment-lanes.js";
9
10
  export { SSR_HTML_CONTENT_TYPE, SSR_QUERY_CACHE_KEY_HEADER, withSsrHtmlContentType, } from "./cache-control.js";
11
+ export { SURFACE_HIDDEN_FLAG, SURFACE_VISIBILITY_EVENT, addSurfaceVisibilityListener, buildSurfaceVisibilityScript, isHostSurfaceHidden, isSurfaceHidden, } from "./surface-visibility.js";
10
12
  export { AGENT_NATIVE_DOCS_ORIGIN, docsUrl, } from "./docs-url.js";
11
13
  export { buildRuntimeConfigPrompt, formatRuntimeConfigReport, getRuntimeConfigReport, parseRuntimeConfigReport, runtimeConfigRequirementsFromSearchParams, } from "./runtime-config.js";
12
14
  export { llmConnectionTrackingProperties, normalizeLlmConnection, } from "./llm-connection.js";
13
15
  export { DISPATCH_WORKSPACE_ROOT_REDIRECTS, RESERVED_WORKSPACE_APP_IDS, assertValidWorkspaceAppId, getWorkspaceAppIdValidationError, isValidWorkspaceAppIdFormat, normalizeWorkspaceAppId, } from "./workspace-app-id.js";
14
16
  export { DEFAULT_WORKSPACE_APP_AUDIENCE, WORKSPACE_APP_AUDIENCES, normalizeWorkspaceAppAudience, normalizeWorkspaceAppPathList, workspaceAppAudienceFromEnv, workspaceAppAudienceFromPackageJson, workspaceAppRouteAccessFromEnv, workspaceAppRouteAccessFromPackageJson, } from "./workspace-app-audience.js";
15
- export { AGENT_NATIVE_OPEN_PATH, AGENT_SIDEBAR_QUERY_PARAM, AGENT_SIDEBAR_QUERY_VALUE_CLOSED, isAgentNativeOpenDeepLink, withCollapsedAgentSidebarParam, } from "./agent-sidebar-url.js";
17
+ export { AGENT_NATIVE_OPEN_PATH, AGENT_SIDEBAR_QUERY_PARAM, AGENT_SIDEBAR_QUERY_VALUE_CLOSED, AGENT_SIDEBAR_QUERY_VALUE_OPEN, isAgentNativeOpenDeepLink, withCollapsedAgentSidebarParam, } from "./agent-sidebar-url.js";
16
18
  export { buildChatFirstAppCreationPrompt, titleFromChatFirstAppPrompt, } from "./chat-first-app-creation.js";
17
19
  export { NATIVE_AUTH_COPY, resolveNativeAuthCopy, } from "./auth-copy.js";
18
20
  export { createPollEngine, } from "./poll-engine.js";
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Host-declared surface visibility.
3
+ *
4
+ * An Electron `<webview>` guest never reports itself hidden: hiding the element
5
+ * or any ancestor leaves `document.visibilityState === "visible"` and never
6
+ * fires `visibilitychange`, so every visibility-based pause in this package is
7
+ * inert inside the desktop shell. A backgrounded app tab there keeps polling at
8
+ * its full foreground cadence and holds its event stream open for as long as
9
+ * the shell is running. The host therefore has to say so explicitly, and this
10
+ * flag is what background work must consult instead of the document alone.
11
+ */
12
+ export declare const SURFACE_HIDDEN_FLAG = "__agentNativeSurfaceHidden";
13
+ /** Dispatched on `window` whenever the host flips the flag. */
14
+ export declare const SURFACE_VISIBILITY_EVENT = "agentnative:surfacevisibilitychange";
15
+ /** Whether an embedding host has declared this surface off screen. */
16
+ export declare function isHostSurfaceHidden(): boolean;
17
+ /**
18
+ * Whether this surface is off screen by either signal. A host that has stashed
19
+ * the surface entirely is a stronger statement than a backgrounded browser tab,
20
+ * so callers that keep working while merely backgrounded should still stop on
21
+ * `isHostSurfaceHidden()`.
22
+ */
23
+ export declare function isSurfaceHidden(): boolean;
24
+ /** Subscribe to both visibility signals. Returns an unsubscribe function. */
25
+ export declare function addSurfaceVisibilityListener(handler: () => void): () => void;
26
+ /**
27
+ * Script a host embedder evaluates inside the guest to declare whether the
28
+ * surface it is hosting is on screen. Kept here so the flag name, the event
29
+ * name, and the write that sets them cannot drift apart across packages.
30
+ */
31
+ export declare function buildSurfaceVisibilityScript(hidden: boolean): string;
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Host-declared surface visibility.
3
+ *
4
+ * An Electron `<webview>` guest never reports itself hidden: hiding the element
5
+ * or any ancestor leaves `document.visibilityState === "visible"` and never
6
+ * fires `visibilitychange`, so every visibility-based pause in this package is
7
+ * inert inside the desktop shell. A backgrounded app tab there keeps polling at
8
+ * its full foreground cadence and holds its event stream open for as long as
9
+ * the shell is running. The host therefore has to say so explicitly, and this
10
+ * flag is what background work must consult instead of the document alone.
11
+ */
12
+ export const SURFACE_HIDDEN_FLAG = "__agentNativeSurfaceHidden";
13
+ /** Dispatched on `window` whenever the host flips the flag. */
14
+ export const SURFACE_VISIBILITY_EVENT = "agentnative:surfacevisibilitychange";
15
+ /** Whether an embedding host has declared this surface off screen. */
16
+ export function isHostSurfaceHidden() {
17
+ if (typeof window === "undefined")
18
+ return false;
19
+ return (window[SURFACE_HIDDEN_FLAG] === true);
20
+ }
21
+ /**
22
+ * Whether this surface is off screen by either signal. A host that has stashed
23
+ * the surface entirely is a stronger statement than a backgrounded browser tab,
24
+ * so callers that keep working while merely backgrounded should still stop on
25
+ * `isHostSurfaceHidden()`.
26
+ */
27
+ export function isSurfaceHidden() {
28
+ if (isHostSurfaceHidden())
29
+ return true;
30
+ return (typeof document !== "undefined" && document.visibilityState === "hidden");
31
+ }
32
+ /** Subscribe to both visibility signals. Returns an unsubscribe function. */
33
+ export function addSurfaceVisibilityListener(handler) {
34
+ if (typeof document === "undefined" || typeof window === "undefined") {
35
+ return () => { };
36
+ }
37
+ document.addEventListener("visibilitychange", handler);
38
+ window.addEventListener(SURFACE_VISIBILITY_EVENT, handler);
39
+ return () => {
40
+ document.removeEventListener("visibilitychange", handler);
41
+ window.removeEventListener(SURFACE_VISIBILITY_EVENT, handler);
42
+ };
43
+ }
44
+ /**
45
+ * Script a host embedder evaluates inside the guest to declare whether the
46
+ * surface it is hosting is on screen. Kept here so the flag name, the event
47
+ * name, and the write that sets them cannot drift apart across packages.
48
+ */
49
+ export function buildSurfaceVisibilityScript(hidden) {
50
+ return `(() => {
51
+ const next = ${hidden ? "true" : "false"};
52
+ if (window[${JSON.stringify(SURFACE_HIDDEN_FLAG)}] === next) return next;
53
+ window[${JSON.stringify(SURFACE_HIDDEN_FLAG)}] = next;
54
+ window.dispatchEvent(new Event(${JSON.stringify(SURFACE_VISIBILITY_EVENT)}));
55
+ return next;
56
+ })()`;
57
+ }
@@ -19,10 +19,17 @@ data, and generated extension/app content may mention credential **names** such
19
19
  as `OPENAI_API_KEY`, but must not contain real API keys, tokens, webhook URLs,
20
20
  signing secrets, OAuth refresh tokens, or private Builder/customer data.
21
21
 
22
- Secret values are supplied at runtime through deployment configuration, the
23
- encrypted `app_secrets` vault, `saveCredential` / `resolveCredential`, OAuth, or
24
- `${keys.NAME}` substitution. Examples must use obvious placeholders such as
25
- `<OPENAI_API_KEY>` or `${keys.SLACK_WEBHOOK}`, not real-looking copied values.
22
+ Provider secret values are supplied at runtime through the encrypted
23
+ `app_secrets` vault, `saveCredential` / `resolveCredential`, OAuth, or
24
+ `${keys.NAME}` substitution. Deployment configuration is reserved for
25
+ deploy-level secrets and non-provider configuration. Examples must use obvious
26
+ placeholders such as `<OPENAI_API_KEY>` or `${keys.SLACK_WEBHOOK}`, not
27
+ real-looking copied values.
28
+
29
+ Provider credentials and provider account identifiers are workspace data. Use
30
+ standard workspace connections and org/workspace vault scopes; never put them
31
+ in `.env` or deployment environment variables, and never add a provider-specific
32
+ action or startup bootstrap just to write a credential for one organization.
26
33
 
27
34
  ## Credential Modeling Preflight
28
35
 
@@ -1,4 +1,6 @@
1
1
  import { type RouteConfig } from "@react-router/dev/routes";
2
2
  import { flatRoutes } from "@react-router/fs-routes";
3
3
 
4
- export default flatRoutes() satisfies RouteConfig;
4
+ export default flatRoutes({
5
+ ignoredRouteFiles: ["**/*.test.{ts,tsx}", "**/*.spec.{ts,tsx}"],
6
+ }) satisfies RouteConfig;
@@ -11,4 +11,12 @@ export default defineConfig({
11
11
  "@shared": path.resolve(__dirname, "./shared"),
12
12
  },
13
13
  },
14
+ test: {
15
+ exclude: [
16
+ "**/node_modules/**",
17
+ "**/.git/**",
18
+ "**/dist/**",
19
+ "**/.react-router/**",
20
+ ],
21
+ },
14
22
  });