@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
@@ -189,6 +189,15 @@ export interface MCPRequestMeta {
189
189
  * results simply fall back to their deep-link text.
190
190
  */
191
191
  export declare function isMcpAppsInlineEnabled(identity: MCPCallerIdentity | undefined): boolean;
192
+ /**
193
+ * Connector-catalog membership declared on the actions themselves.
194
+ *
195
+ * This is `mcp.connectorCatalog` with the list inverted into the action files,
196
+ * so a rename moves the declaration with the action instead of stranding a
197
+ * dead string in a plugin config. Both forms feed the same set and an app can
198
+ * run either or both while it migrates.
199
+ */
200
+ export declare function declaredMcpToolNames(actions: Record<string, ActionEntry>): string[];
192
201
  export declare function isAuthenticatedReadAction(entry: ActionEntry): boolean;
193
202
  export declare function isAutoReadExcludedActionName(name: string): boolean;
194
203
  /**
@@ -18,6 +18,7 @@
18
18
  * — it can be bundled into the serverless function alongside `mountMCP`.
19
19
  */
20
20
  import { MCP_APP_EXTENSION_ID, MCP_APP_MIME_TYPE, MCP_APP_RESOURCE_URI_META_KEY, } from "../action.js";
21
+ import { isActionExposedToExternalAgents } from "../action.js";
21
22
  import { isMcpActionResult } from "../mcp-client/app-result.js";
22
23
  import { getConfiguredAppBasePath } from "../server/app-base-path.js";
23
24
  import { buildDeepLink, toAbsoluteOpenUrl, toDesktopOpenUrl, toVsCodeOpenUrl, } from "../server/deep-link.js";
@@ -177,6 +178,34 @@ function scopeToolSearchToAdvertised(advertised) {
177
178
  },
178
179
  };
179
180
  }
181
+ /**
182
+ * Drop every action this request's surface must not reach at all.
183
+ *
184
+ * Applied to `actions` — the whole surface this request can reach — and not
185
+ * just to the advertised listing, because on the `--full-catalog` tier
186
+ * `actions` IS the callable set (see the `tools/call` handler below). An
187
+ * external-agent opt-out that only hid the schema would leave the action
188
+ * callable by name, which is the same "hidden but reachable" bug the
189
+ * `withoutToolSearch` comment above exists to prevent.
190
+ *
191
+ * The in-app agent never comes through here, so its tool list is unaffected.
192
+ */
193
+ function withoutExternalOptOuts(actions) {
194
+ return Object.fromEntries(Object.entries(actions).filter(([, entry]) => isActionExposedToExternalAgents(entry)));
195
+ }
196
+ /**
197
+ * Connector-catalog membership declared on the actions themselves.
198
+ *
199
+ * This is `mcp.connectorCatalog` with the list inverted into the action files,
200
+ * so a rename moves the declaration with the action instead of stranding a
201
+ * dead string in a plugin config. Both forms feed the same set and an app can
202
+ * run either or both while it migrates.
203
+ */
204
+ export function declaredMcpToolNames(actions) {
205
+ return Object.entries(actions)
206
+ .filter(([, entry]) => entry.mcpTool === true)
207
+ .map(([name]) => name);
208
+ }
180
209
  const COMPACT_MCP_APP_CATALOG_BUILTINS = new Set([
181
210
  "list_apps",
182
211
  "open_app",
@@ -1170,9 +1199,7 @@ export async function createMCPServerForRequest(config, identity, requestMeta) {
1170
1199
  // Strip from `actions`, not just the advertised set: on the full-catalog tier
1171
1200
  // `actions` IS the callable surface, so filtering only the listing would
1172
1201
  // leave `tool-search` callable but invisible.
1173
- const actions = flatCatalog
1174
- ? withoutToolSearch(mergedActions)
1175
- : mergedActions;
1202
+ const actions = withoutExternalOptOuts(flatCatalog ? withoutToolSearch(mergedActions) : mergedActions);
1176
1203
  const visibleActions = Object.fromEntries(Object.entries(actions).filter(([, entry]) => isActionVisibleForOAuthScope(entry, effectiveIdentity?.oauthScopes)));
1177
1204
  // Compact/connector is the DEFAULT for every caller — hosted connectors,
1178
1205
  // code clients (Claude Code / Cursor / Codex), and the local CLI alike. The
@@ -1187,15 +1214,17 @@ export async function createMCPServerForRequest(config, identity, requestMeta) {
1187
1214
  const autoReadNames = autoAuthenticatedReadNames(visibleActions, config);
1188
1215
  const connectorNames = new Set([
1189
1216
  ...(config.connectorCatalog ?? []),
1217
+ ...declaredMcpToolNames(visibleActions),
1190
1218
  ...autoReadNames,
1191
1219
  ]);
1192
1220
  const denyNames = externalAgentDenySet(config);
1193
1221
  const automaticConnectorPolicyActive = config.externalAgents?.authenticatedReads === "auto";
1194
- // Connector-catalog tier: when a template declares a connector allow-list,
1195
- // serve exactly that curated surface plus any explicitly annotated
1196
- // authenticated reads from `externalAgents.authenticatedReads: "auto"`.
1197
- // This stays compact by default and keeps db-exec / seed-* / extension /
1198
- // browser-session footguns off the external surface.
1222
+ // Connector-catalog tier: when a template declares a connector allow-list —
1223
+ // as `mcp.connectorCatalog` names or as `mcpTool: true` on the actions
1224
+ // themselves — serve exactly that curated surface plus any explicitly
1225
+ // annotated authenticated reads from `externalAgents.authenticatedReads:
1226
+ // "auto"`. This stays compact by default and keeps db-exec / seed-* /
1227
+ // extension / browser-session footguns off the external surface.
1199
1228
  const connectorCatalogActive = !appCatalog &&
1200
1229
  (connectorNames.size > 0 || automaticConnectorPolicyActive) &&
1201
1230
  !fullCatalogRequested;
@@ -74,6 +74,7 @@ export declare class McpOAuthClientProvider implements OAuthClientProvider {
74
74
  }
75
75
  export declare function startMcpOAuthAuthorization(options: McpOAuthProviderOptions & {
76
76
  scope?: string;
77
+ resourceMetadataUrl?: string;
77
78
  }): Promise<McpOAuthStartResult>;
78
79
  export declare function finishMcpOAuthAuthorization(options: McpOAuthProviderOptions & {
79
80
  authorizationCode: string;
@@ -99,6 +100,12 @@ export declare function getMcpOAuthConnectionState(options: {
99
100
  scopeId: string;
100
101
  serverUrl: string;
101
102
  }): Promise<OAuthCredentialState<McpOAuthCredentialBundle>>;
103
+ export declare function markMcpOAuthReconnectRequired(options: {
104
+ key: string;
105
+ scope: "user" | "org";
106
+ scopeId: string;
107
+ serverUrl: string;
108
+ }): Promise<boolean>;
102
109
  export declare function deleteMcpOAuthCredentials(options: {
103
110
  key: string;
104
111
  scope: "user" | "org";
@@ -8,7 +8,7 @@
8
8
  */
9
9
  import { auth, refreshAuthorization, validateAuthorizationResponseIssuer, } from "@modelcontextprotocol/client";
10
10
  import { ssrfSafeFetch } from "../extensions/url-safety.js";
11
- import { readOAuthCredentialState, resolveOAuthCredentialAccess, revokeOAuthCredential, saveOAuthCredential, } from "../oauth-tokens/lifecycle.js";
11
+ import { readOAuthCredentialState, resolveOAuthCredentialAccess, markOAuthReconnectRequired, revokeOAuthCredential, saveOAuthCredential, } from "../oauth-tokens/lifecycle.js";
12
12
  import { validateRemoteUrl } from "./remote-url.js";
13
13
  const TOKEN_EXPIRY_SKEW_MS = 60_000;
14
14
  const MAX_OAUTH_REDIRECTS = 5;
@@ -312,6 +312,9 @@ export async function startMcpOAuthAuthorization(options) {
312
312
  const result = await auth(provider, {
313
313
  serverUrl: options.serverUrl,
314
314
  scope: options.scope,
315
+ ...(options.resourceMetadataUrl
316
+ ? { resourceMetadataUrl: new URL(options.resourceMetadataUrl) }
317
+ : {}),
315
318
  fetchFn: guardedOAuthFetch(),
316
319
  });
317
320
  if (result !== "REDIRECT" || !provider.authorizationRedirect) {
@@ -408,6 +411,14 @@ export async function getMcpOAuthConnectionState(options) {
408
411
  validateCredential: (credential) => serverUrlsMatch(credential.serverUrl, serverUrl),
409
412
  });
410
413
  }
414
+ export async function markMcpOAuthReconnectRequired(options) {
415
+ const serverUrl = canonicalServerUrl(options.serverUrl);
416
+ return markOAuthReconnectRequired(credentialIdentity({ ...options, serverUrl }), {
417
+ allowLegacy: true,
418
+ legacyAccountKey: true,
419
+ validateCredential: (credential) => serverUrlsMatch(credential.serverUrl, serverUrl),
420
+ });
421
+ }
411
422
  export async function deleteMcpOAuthCredentials(options) {
412
423
  if (!options.serverUrl)
413
424
  return false;
@@ -1,3 +1,3 @@
1
1
  export { getOAuthTokens, getOAuthTokenSnapshot, OAuthAccountOwnedByOtherUserError, saveOAuthTokens, replaceOAuthTokensIfRevision, deleteOAuthTokens, deleteOAuthTokensIfRevision, listOAuthAccounts, listOAuthAccountsByOwner, hasOAuthTokens, setOAuthDisplayName, } from "./store.js";
2
- export { readOAuthCredentialState, resolveOAuthCredentialAccess, revokeOAuthCredential, saveOAuthCredential, type OAuthCredential, type OAuthCredentialIdentity, type OAuthCredentialOwner, type OAuthCredentialState, type OAuthRevocationResult, } from "./lifecycle.js";
2
+ export { readOAuthCredentialState, resolveOAuthCredentialAccess, markOAuthReconnectRequired, revokeOAuthCredential, saveOAuthCredential, type OAuthCredential, type OAuthCredentialIdentity, type OAuthCredentialOwner, type OAuthCredentialState, type OAuthRevocationResult, } from "./lifecycle.js";
3
3
  export { refreshExpiringGoogleTokens, startGoogleTokenRefreshLoop, } from "./google-refresh.js";
@@ -1,3 +1,3 @@
1
1
  export { getOAuthTokens, getOAuthTokenSnapshot, OAuthAccountOwnedByOtherUserError, saveOAuthTokens, replaceOAuthTokensIfRevision, deleteOAuthTokens, deleteOAuthTokensIfRevision, listOAuthAccounts, listOAuthAccountsByOwner, hasOAuthTokens, setOAuthDisplayName, } from "./store.js";
2
- export { readOAuthCredentialState, resolveOAuthCredentialAccess, revokeOAuthCredential, saveOAuthCredential, } from "./lifecycle.js";
2
+ export { readOAuthCredentialState, resolveOAuthCredentialAccess, markOAuthReconnectRequired, revokeOAuthCredential, saveOAuthCredential, } from "./lifecycle.js";
3
3
  export { refreshExpiringGoogleTokens, startGoogleTokenRefreshLoop, } from "./google-refresh.js";
@@ -67,6 +67,17 @@ export declare function readOAuthCredentialState<T extends OAuthCredential = OAu
67
67
  now?: number;
68
68
  validateCredential?: (credential: T) => boolean;
69
69
  }): Promise<OAuthCredentialState<T>>;
70
+ /**
71
+ * Force a stored credential into `reconnect_required` without a refresh attempt.
72
+ * For a token the provider rejected server-side (e.g. a 401/403) while it still
73
+ * looks valid locally, so the credential itself carries the reconnect signal
74
+ * instead of a side channel. Returns false when there is nothing to mark.
75
+ */
76
+ export declare function markOAuthReconnectRequired<T extends OAuthCredential = OAuthCredential>(identity: OAuthCredentialIdentity, options?: {
77
+ allowLegacy?: boolean;
78
+ legacyAccountKey?: boolean;
79
+ validateCredential?: (credential: T) => boolean;
80
+ }): Promise<boolean>;
70
81
  export declare function resolveOAuthCredentialAccess<T extends OAuthCredential = OAuthCredential>(identity: OAuthCredentialIdentity, options: {
71
82
  refresh: (context: OAuthRefreshContext<T>) => Promise<T>;
72
83
  allowLegacy?: boolean;
@@ -232,6 +232,23 @@ export async function readOAuthCredentialState(identity, options = {}) {
232
232
  async function markReconnectRequired(identity, snapshot, legacyAccountKey) {
233
233
  await replaceOAuthTokensIfRevision(identity.provider, storageAccountId(identity, legacyAccountKey), snapshot.storageOwner, snapshot.revision, snapshot.legacyRevision, snapshot.storageVersion, withLifecycle(identity, snapshot.credential, "refresh_failed"));
234
234
  }
235
+ /**
236
+ * Force a stored credential into `reconnect_required` without a refresh attempt.
237
+ * For a token the provider rejected server-side (e.g. a 401/403) while it still
238
+ * looks valid locally, so the credential itself carries the reconnect signal
239
+ * instead of a side channel. Returns false when there is nothing to mark.
240
+ */
241
+ export async function markOAuthReconnectRequired(identity, options = {}) {
242
+ const stored = await readStoredOAuthCredentialState(identity, {
243
+ allowLegacy: options.allowLegacy,
244
+ legacyAccountKey: options.legacyAccountKey,
245
+ validateCredential: options.validateCredential,
246
+ });
247
+ if (stored.kind === "missing" || stored.kind === "malformed")
248
+ return false;
249
+ await markReconnectRequired(identity, stored, options.legacyAccountKey === true);
250
+ return true;
251
+ }
235
252
  export async function resolveOAuthCredentialAccess(identity, options) {
236
253
  assertIdentity(identity);
237
254
  const dependencies = { ...defaultDependencies, ...options.dependencies };
@@ -318,6 +318,13 @@ export async function saveOAuthTokens(provider, accountId, tokens, owner) {
318
318
  ...(existingTokens ?? {}),
319
319
  ...cleanedIncomingTokens,
320
320
  };
321
+ const existingScope = existingTokens?.scope;
322
+ const incomingScope = cleanedIncomingTokens.scope;
323
+ if (typeof existingScope === "string" && typeof incomingScope === "string") {
324
+ tokensToStore.scope = Array.from(new Set(`${existingScope} ${incomingScope}`
325
+ .split(/[\s,]+/)
326
+ .filter((scope) => scope.length > 0))).join(" ");
327
+ }
321
328
  const result = await client.execute({
322
329
  sql: isPostgres()
323
330
  ? `INSERT INTO ${table} (provider, account_id, owner, display_name, tokens, updated_at, revision) VALUES (?, ?, ?, ?, ?, ?, ?) ON CONFLICT (provider, account_id) DO UPDATE SET owner=EXCLUDED.owner, display_name=COALESCE(EXCLUDED.display_name, ${table}.display_name), tokens=EXCLUDED.tokens, updated_at=EXCLUDED.updated_at, revision=GREATEST(COALESCE(${table}.revision, 0) + 1, EXCLUDED.revision) WHERE ${table}.owner = EXCLUDED.owner OR (LOWER(${table}.owner) = LOWER(EXCLUDED.owner) AND LOWER(${table}.owner) LIKE 'user:%' AND LOWER(EXCLUDED.owner) LIKE 'user:%')`
@@ -12,6 +12,18 @@
12
12
  * PostHog's `$session_id`: the latter is the browser session used for session
13
13
  * replay, and the two are different lifetimes.
14
14
  *
15
+ * PostHog DERIVES a trace's latency, tokens and cost from its children — its
16
+ * trace query sums `$ai_latency` over every event whose `$ai_parent_id` is the
17
+ * trace or absent, and sums tokens/cost over `$ai_generation` / `$ai_embedding`
18
+ * only. So the `$ai_trace` event carries none of those: an `$ai_latency` here
19
+ * was counted *in addition to* the generation's and reported roughly twice the
20
+ * real duration. Run totals ride along under plain names for the non-PostHog
21
+ * backends, which have no such aggregation.
22
+ *
23
+ * Custom properties do NOT take an `$ai_` prefix. That namespace is PostHog's
24
+ * schema, and a name it does not define today it may define tomorrow with
25
+ * different meaning — `input_truncated` / `spans_dropped` cannot collide.
26
+ *
15
27
  * Content (`$ai_input` / `$ai_output_choices` / `$ai_input_state` /
16
28
  * `$ai_output_state`) is gated on config and always OMITTED when disabled.
17
29
  * Sending `[]` instead would be indistinguishable from a run that genuinely had
@@ -49,7 +61,9 @@ export interface AiTraceEventInput {
49
61
  spanName: string;
50
62
  model: string;
51
63
  provider: string;
52
- latencySeconds: number;
64
+ /** Wall-clock duration of the whole run. Reported under `duration_ms`, not
65
+ * `$ai_latency` — see the aggregation note at the top of this file. */
66
+ durationMs: number;
53
67
  isError: boolean;
54
68
  error?: AiErrorDetail;
55
69
  inputTokens?: number;
@@ -12,6 +12,18 @@
12
12
  * PostHog's `$session_id`: the latter is the browser session used for session
13
13
  * replay, and the two are different lifetimes.
14
14
  *
15
+ * PostHog DERIVES a trace's latency, tokens and cost from its children — its
16
+ * trace query sums `$ai_latency` over every event whose `$ai_parent_id` is the
17
+ * trace or absent, and sums tokens/cost over `$ai_generation` / `$ai_embedding`
18
+ * only. So the `$ai_trace` event carries none of those: an `$ai_latency` here
19
+ * was counted *in addition to* the generation's and reported roughly twice the
20
+ * real duration. Run totals ride along under plain names for the non-PostHog
21
+ * backends, which have no such aggregation.
22
+ *
23
+ * Custom properties do NOT take an `$ai_` prefix. That namespace is PostHog's
24
+ * schema, and a name it does not define today it may define tomorrow with
25
+ * different meaning — `input_truncated` / `spans_dropped` cannot collide.
26
+ *
15
27
  * Content (`$ai_input` / `$ai_output_choices` / `$ai_input_state` /
16
28
  * `$ai_output_state`) is gated on config and always OMITTED when disabled.
17
29
  * Sending `[]` instead would be indistinguishable from a run that genuinely had
@@ -26,7 +38,7 @@ import { boundedText } from "../tracking/redaction.js";
26
38
  export const MAX_AI_CONTENT_BYTES = 128 * 1024;
27
39
  /** Hard ceiling on emitted `$ai_span` events per run. */
28
40
  export const MAX_AI_SPANS_PER_RUN = 100;
29
- function trackAiEvent(name, properties, userId) {
41
+ function trackAiEvent(name, properties, userId, occurredAt) {
30
42
  for (const key of Object.keys(properties)) {
31
43
  if (properties[key] === undefined)
32
44
  delete properties[key];
@@ -34,7 +46,7 @@ function trackAiEvent(name, properties, userId) {
34
46
  try {
35
47
  void import("../tracking/registry.js")
36
48
  .then(({ track }) => {
37
- track(name, properties, { userId: userId ?? undefined });
49
+ track(name, properties, { userId: userId ?? undefined, occurredAt });
38
50
  })
39
51
  .catch(() => { });
40
52
  // coercion-ok: a throw here would break the run it is observing
@@ -84,19 +96,19 @@ export function emitAiTraceEvent(input) {
84
96
  $ai_span_name: input.spanName,
85
97
  $ai_model: input.model,
86
98
  $ai_provider: input.provider,
87
- $ai_latency: input.latencySeconds,
88
99
  $ai_is_error: input.isError,
89
100
  $ai_error: input.error,
90
- $ai_input_tokens: input.inputTokens,
91
- $ai_output_tokens: input.outputTokens,
92
- $ai_total_cost_usd: input.costUsd,
101
+ duration_ms: Math.round(input.durationMs),
102
+ input_tokens: input.inputTokens,
103
+ output_tokens: input.outputTokens,
104
+ cost_usd: input.costUsd,
93
105
  $ai_input_state: inputContent?.value,
94
106
  $ai_output_state: outputContent?.value,
95
- $ai_input_truncated: inputContent?.truncated || undefined,
96
- $ai_output_truncated: outputContent?.truncated || undefined,
107
+ input_truncated: inputContent?.truncated || undefined,
108
+ output_truncated: outputContent?.truncated || undefined,
97
109
  $session_id: input.browserSessionId,
98
110
  created_at: new Date(input.createdAt).toISOString(),
99
- }, input.userId);
111
+ }, input.userId, input.createdAt);
100
112
  }
101
113
  export function emitAiSpanEvent(input) {
102
114
  const inputContent = input.inputState === undefined
@@ -117,11 +129,11 @@ export function emitAiSpanEvent(input) {
117
129
  $ai_error: input.error,
118
130
  $ai_input_state: inputContent?.value,
119
131
  $ai_output_state: outputContent?.value,
120
- $ai_input_truncated: inputContent?.truncated || undefined,
121
- $ai_output_truncated: outputContent?.truncated || undefined,
132
+ input_truncated: inputContent?.truncated || undefined,
133
+ output_truncated: outputContent?.truncated || undefined,
122
134
  $session_id: input.browserSessionId,
123
135
  created_at: new Date(input.createdAt).toISOString(),
124
- }, input.userId);
136
+ }, input.userId, input.createdAt);
125
137
  }
126
138
  /**
127
139
  * Emit PostHog's documented manual feedback event for an LLM trace.
@@ -41,16 +41,16 @@ export declare function createObservabilityHandler(): import("h3").EventHandlerW
41
41
  thumbsUpRate: number;
42
42
  avgEvalScore: number;
43
43
  } | {
44
+ error?: undefined;
44
45
  summary: import("./types.js").TraceSummary;
45
46
  spans: import("./types.js").TraceSpan[];
46
47
  id?: undefined;
47
- error?: undefined;
48
48
  ok?: undefined;
49
49
  } | {
50
+ error?: undefined;
50
51
  summary?: undefined;
51
52
  spans?: undefined;
52
53
  id: string;
53
- error?: undefined;
54
54
  ok?: undefined;
55
55
  } | {
56
56
  summary?: undefined;
@@ -59,9 +59,9 @@ export declare function createObservabilityHandler(): import("h3").EventHandlerW
59
59
  error: any;
60
60
  ok?: undefined;
61
61
  } | {
62
+ error?: undefined;
62
63
  summary?: undefined;
63
64
  spans?: undefined;
64
65
  id?: undefined;
65
- error?: undefined;
66
66
  ok: boolean;
67
67
  }>>;