@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
@@ -1,6 +1,6 @@
1
1
  import { z } from "zod";
2
2
  import { defineAction } from "../../action.js";
3
- import { getBetterAuth } from "../../server/better-auth-instance.js";
3
+ import { getBetterAuthInternalAdapter } from "../../server/better-auth-instance.js";
4
4
  export default defineAction({
5
5
  description: "Get the signed-in user's available authentication methods.",
6
6
  schema: z.object({}),
@@ -11,12 +11,25 @@ export default defineAction({
11
11
  if (!ctx?.userEmail || !ctx.requestHeaders) {
12
12
  throw new Error("Not authenticated.");
13
13
  }
14
- const auth = await getBetterAuth();
15
- const accounts = await auth.api.listUserAccounts({
16
- headers: ctx.requestHeaders,
14
+ // Look accounts up by the framework-resolved ctx.userEmail through
15
+ // Better Auth's internal adapter rather than replaying ctx.requestHeaders
16
+ // through auth.api.listUserAccounts: that call re-derives identity from
17
+ // its own cookie-based session lookup, which throws for any caller the
18
+ // framework authenticated without a Better Auth session cookie (an
19
+ // AUTH_DISABLED dev session, a BYOA identity, ...) even though
20
+ // ctx.userEmail is already a trustworthy resolved identity. An unresolved
21
+ // adapter means the auth backend couldn't be read at all and must fail
22
+ // loudly — only a resolved adapter finding no matching user record means
23
+ // there is no Better Auth credential to report.
24
+ const adapter = await getBetterAuthInternalAdapter();
25
+ if (!adapter) {
26
+ throw new Error("Better Auth internal adapter is unavailable.");
27
+ }
28
+ const existing = await adapter.findUserByEmail(ctx.userEmail, {
29
+ includeAccounts: true,
17
30
  });
18
31
  return {
19
- hasPassword: accounts.some((account) => account.providerId === "credential"),
32
+ hasPassword: existing?.accounts.some((account) => account.providerId === "credential") ?? false,
20
33
  };
21
34
  },
22
35
  });
@@ -1457,10 +1457,17 @@ function frameworkDevDynamicForwarder() {
1457
1457
  ? `text/html,${accept}`
1458
1458
  : "text/html";
1459
1459
  }
1460
- // Embed-start uses document/iframe to select its transplant response.
1461
- // Only supply the classifier hint when the browser did not provide a
1462
- // destination; never overwrite the request's original intent.
1463
- if (req.headers["sec-fetch-dest"] === undefined) {
1460
+ // Embed-start uses document/iframe to select its transplant response,
1461
+ // and Nitro's own dev classifier already treats document/iframe/frame
1462
+ // as non-asset, so those (and an already-"empty" value) pass through
1463
+ // untouched. Everything else — undefined, or a real browser's
1464
+ // destination for a fetch this route never anticipated, like
1465
+ // "speculationrules" for the native Speculation-Rules auto-fetch —
1466
+ // gets normalized to "empty" so Nitro's classifier falls back to its
1467
+ // extension check instead of treating the request as a static asset.
1468
+ const fetchDest = req.headers["sec-fetch-dest"];
1469
+ if (fetchDest === undefined ||
1470
+ !/^(document|iframe|frame|empty)$/.test(String(fetchDest))) {
1464
1471
  req.headers["sec-fetch-dest"] = "empty";
1465
1472
  }
1466
1473
  }
@@ -1960,6 +1967,18 @@ function rolldownInputFix() {
1960
1967
  * The template lists the packages in its `defineConfig({ ssrStubs })` call —
1961
1968
  * the framework never hardcodes package names.
1962
1969
  */
1970
+ /**
1971
+ * Optional peers reached only through a `React.lazy` boundary whose module body
1972
+ * guards on `typeof window === "undefined"`. The server can never import them,
1973
+ * so their SSR chunk is pure unpack weight in every app that ships a terminal
1974
+ * surface. Defaulted here rather than repeated in sixteen vite configs, where
1975
+ * it would drift.
1976
+ */
1977
+ const ALWAYS_SSR_STUBBED = [
1978
+ "@xterm/xterm",
1979
+ "@xterm/addon-fit",
1980
+ "@xterm/addon-web-links",
1981
+ ];
1963
1982
  function ssrStubPlugin(packages) {
1964
1983
  if (!packages.length)
1965
1984
  return null;
@@ -2729,7 +2748,7 @@ function createAgentNativePlugins(options, { command, includeReactTransform, use
2729
2748
  // don't bloat the edge worker. Opt-in per template — the framework
2730
2749
  // hardcodes nothing (e.g. docs sites legitimately import `shiki` on
2731
2750
  // the server, so we can't blanket-stub it here).
2732
- ssrStubPlugin(options.ssrStubs ?? []),
2751
+ ssrStubPlugin([...ALWAYS_SSR_STUBBED, ...(options.ssrStubs ?? [])]),
2733
2752
  ...userPlugins,
2734
2753
  appChangelogRawPlugin(),
2735
2754
  actionTypesPlugin(),
@@ -1,25 +1,26 @@
1
1
  ---
2
2
  title: "Access & Authorization"
3
- description: "Who can call an action: exposure flags (agentTool, toolCallable), ctx-based scoping, accessFilter/assertAccess, and the authorize guard."
3
+ description: "Who can call an action: exposure flags (agentTool, mcpTool, toolCallable), ctx-based scoping, accessFilter/assertAccess, and the authorize guard."
4
4
  ---
5
5
 
6
6
  # Access & Authorization
7
7
 
8
- Five settings decide who can call an action: the agent, the frontend, an extension, an outside API caller, or nobody without a human's approval first. Most actions never need to touch any of these, since the defaults already fit normal UI-and-agent use.
8
+ Six settings decide who can call an action: the agent, the frontend, an extension, an outside API caller, or nobody without a human's approval first. Most actions never need to touch any of these, since the defaults already fit normal UI-and-agent use.
9
9
 
10
10
  ### Exposure flags {#exposure-flags}
11
11
 
12
- All five flags default to the permissive value, so you only set one when you need to tighten a specific surface. The table below is a quick summary. The sections after it add the one detail each flag needs.
12
+ All six default to the permissive value — `mcpTool` by inheriting `agentTool` — so you only set one when you need to tighten a specific surface. The table below is a quick summary. The sections after it add the one detail each flag needs.
13
13
 
14
14
  | Flag | Default | Restrictive value → who can still call | Typical use |
15
15
  | --------------- | ------------- | --------------------------------------------------------------------------- | -------------------------------------------------------------------- |
16
16
  | `agentTool` | `true` | `false` → UI, HTTP, and CLI only (hidden from the model, MCP, and A2A) | UI-only or programmatic actions that shouldn't take up a tool slot |
17
+ | `mcpTool` | `agentTool` | `false` → your own app's agent only (hidden from MCP and A2A) | Actions that need an in-app screen or session on the other end |
17
18
  | `toolCallable` | `true` | `false` → everything **except** the sandboxed extension iframe bridge (403) | Sensitive account or org changes (delete account, change membership) |
18
19
  | `publicAgent` | off (private) | `{ expose: true }` → adds the action to **public** MCP/A2A/OpenAPI surfaces | Safe read or ingest tools that don't require authentication |
19
20
  | `needsApproval` | `false` | `true` → the agent **pauses**, and a human must approve the specific call | Consequential side effects (send email, charge a card, delete) |
20
21
  | `authorize` | none | a guard function → only callers it accepts, on **every** surface | Operations restricted to a role (per-app RBAC, admin-only ops) |
21
22
 
22
- These flags are independent, so setting one doesn't change the others. `agentTool` controls what the model sees, see [Hide from the model](#agent-tool) below. `toolCallable` controls only the extension iframe, see [Block extension iframes](#tool-callable) below. `publicAgent` adds an opt-in public surface, and a public web route never implies public tool exposure, see [Expose to public agents](#public-agent) below. `needsApproval` gates execution after the call is already made, see [Require human approval](#needs-approval) below. `authorize` decides whether this caller may run the action at all, on every dispatch path, before `run()` is entered, see [Restrict callers by role](#authorize) below.
23
+ These flags are independent, with one exception: an undeclared `mcpTool` inherits `agentTool`. `agentTool` controls what the model sees, see [Hide from the model](#agent-tool) below. `mcpTool` narrows that to outside agents only, see [Hide from external agents](#mcp-tool) below. `toolCallable` controls only the extension iframe, see [Block extension iframes](#tool-callable) below. `publicAgent` adds an opt-in public surface, and a public web route never implies public tool exposure, see [Expose to public agents](#public-agent) below. `needsApproval` gates execution after the call is already made, see [Require human approval](#needs-approval) below. `authorize` decides whether this caller may run the action at all, on every dispatch path, before `run()` is entered, see [Restrict callers by role](#authorize) below.
23
24
 
24
25
  ## Hide from the model {#agent-tool}
25
26
 
@@ -39,6 +40,44 @@ export default defineAction({
39
40
 
40
41
  Use this when you add a UI-only or purely programmatic action, or when the UI stops using an action that would otherwise stay exposed to the model.
41
42
 
43
+ ## Hide from external agents {#mcp-tool}
44
+
45
+ `agentTool` is all-or-nothing: an action is a tool for every agent, or for none. `mcpTool` splits that in two, so an action can stay a normal tool for your own app's agent while never reaching Claude, Cursor, or a sibling app over MCP and A2A:
46
+
47
+ ```ts
48
+ export default defineAction({
49
+ description: "Open the record inspector beside the current selection.",
50
+ mcpTool: false, // needs a live screen on the other end
51
+ schema: z.object({ recordId: z.string() }),
52
+ run: async ({ recordId }) => {
53
+ /* ... */
54
+ },
55
+ });
56
+ ```
57
+
58
+ Use it for actions whose result only means something with your app's UI, an open session, or the current selection in front of the caller. `mcpTool` can only narrow `agentTool`, never widen it: an action with `agentTool: false` stays hidden everywhere. It governs the external tool surface itself, not what your own agent may do while answering an `ask_app` question — that run is your agent's, and it keeps its whole tool list.
59
+
60
+ Left undeclared, `mcpTool` follows `agentTool` rather than defaulting to a flat `true`, so hiding an action from the agent hides it from outside agents too and one flag stays one decision.
61
+
62
+ The opposite value has a second job. External agents are served a small, curated catalog by default rather than your whole action registry, and `mcpTool: true` is how an action declares itself part of it:
63
+
64
+ ```ts
65
+ export default defineAction({
66
+ description: "List the databases connected to this workspace.",
67
+ mcpTool: true, // served to external agents, not just discoverable
68
+ http: { method: "GET" },
69
+ run: async () => {
70
+ /* ... */
71
+ },
72
+ });
73
+ ```
74
+
75
+ This is the same catalog as the plugin's `mcp: { connectorCatalog: [...] }` list, declared on the action instead of in a separate array that has to be kept in sync as actions are renamed. Both forms work, and an app can move over one action at a time. Everything left out stays discoverable through `tool-search`.
76
+
77
+ Pairing the two flags the other way — `agentTool: false` with `mcpTool: true` — makes an action **MCP-only**: outside agents get it, your own app's agent never sees it. Use it for the export, sync, or handoff an outside tool needs and your own agent has no reason to call.
78
+
79
+ Membership is not permission. An external caller still has to pass the OAuth scope check, the `externalAgents` policy, and — for the direct, no-model A2A path — the `publicAgent` opt-in below.
80
+
42
81
  ## Block extension iframes {#tool-callable}
43
82
 
44
83
  Extensions ([Alpine.js mini-apps in sandboxed iframes](/docs/extensions)) call actions through `appAction(name, params)`, running with the viewer's own permissions, secrets, and SQL scope. For sensitive operations, that's too much trust by default. Set `toolCallable: false` to make the extension bridge return a 403, while keeping the action callable from the UI, agent, CLI, MCP, and A2A:
@@ -115,6 +115,21 @@ The framework auto-discovers every file in `actions/` and mounts it on startup.
115
115
  description:
116
116
  "Set false to hide from every agent tool list. See Access & Authorization.",
117
117
  },
118
+ {
119
+ name: "mcpTool",
120
+ type: "boolean",
121
+ optional: true,
122
+ default: "agentTool",
123
+ description:
124
+ "Defaults to agentTool. Set false to hide from external agents over MCP and A2A, or true to declare curated catalog membership (with agentTool: false, MCP-only). See Access & Authorization.",
125
+ },
126
+ {
127
+ name: "deferLoading",
128
+ type: "boolean",
129
+ optional: true,
130
+ description:
131
+ "Set false to keep the action in the agent's first tool list, true to load it on demand through tool-search. See Keep the action surface small below.",
132
+ },
118
133
  {
119
134
  name: "toolCallable",
120
135
  type: "boolean",
@@ -261,6 +276,7 @@ Every action the agent can see takes up a slot in the model's tool list, and a l
261
276
  - Prefer **one CRUD-style `update` action** that takes a patch of optional fields, over many per-field actions like `update-name`, `update-order`, and `update-color`. The caller only sends the fields that changed.
262
277
  - Before adding a new read action for every query or filter, consider a more general option first: the [provider API trio](/docs/template-dispatch-vault-integrations#provider-api) (`provider-api-catalog`, `provider-api-docs`, and `provider-api-request`) for provider data, or the dev `db-query` tool for app data.
263
278
  - Mark UI-only or programmatic actions [`agentTool: false`](/docs/actions-access-control#agent-tool). They stay callable from the frontend or over HTTP, without taking a slot in the model's tool list.
279
+ - Mark the handful of actions the agent reaches for constantly `deferLoading: false`. Those are the schemas sent on the first model request; everything else loads on demand through `tool-search` when the agent needs it. As soon as one action opts out this way, every unmarked action is deferred, so mark the whole starter set at once rather than one action at a time. This is about what the first turn costs, not about access: a deferred action is callable the moment `tool-search` returns it. It is the per-action form of the plugin's `initialToolNames` array, and an app can use either.
264
280
  - Delete or hide actions the UI no longer uses, instead of leaving them exposed to the model.
265
281
 
266
282
  The repo includes an advisory helper, `node scripts/audit-template-actions.mjs [template ...]` (alias `pnpm actions:audit`). It scans a template's `actions/` folder and flags actions the UI may no longer use, along with groups of per-field actions that could be combined into one. It always exits with code 0 and never fails CI, and its heuristics are conservative, so treat its output as a suggestion, not an error.
@@ -1,14 +1,14 @@
1
1
  ---
2
- title: "Capturing Everywhere: Desktop, Mobile, and Screen Memory"
3
- description: "Every way to get a recording into Clips — the desktop tray app, the mobile companion, Rewind quick-save, local-only Screen Memory, and the Chrome extension for browser logs."
4
- search: "Clips desktop app mobile companion Rewind quick save Screen Memory Chrome extension browser logs"
2
+ title: "Capturing Everywhere: Desktop, Mobile, and Rewind"
3
+ description: "Every way to get a recording into Clips: the desktop tray app, the mobile companion, the local-only Rewind memory, and the Chrome extension for browser logs."
4
+ search: "Clips desktop app mobile companion Rewind memory add what happened before Screen Memory Chrome extension browser logs"
5
5
  ---
6
6
 
7
7
  # Capturing everywhere
8
8
 
9
- Clips isn't only a browser recorder. This page covers every place you can start a capture — the desktop tray app, the mobile companion app, pulling in a moment you forgot to record, the local-only Screen Memory buffer, and the Chrome extension for browser logs — and who each one is for.
9
+ Clips isn't only a browser recorder. This page covers every place you can start a capture, and who each one is for: the desktop tray app, the mobile companion app, the local-only Rewind memory, and the Chrome extension for browser logs.
10
10
 
11
- <Diagram id="doc-block-clips1" title="Capture surfaces" summary={"Desktop, mobile, and the Chrome extension all land in your shared Clips library. Screen Memory is the one exception — it never leaves your machine."}>
11
+ <Diagram id="doc-block-clips1" title="Capture surfaces" summary={"Desktop, mobile, and the Chrome extension all land in your shared Clips library. Rewind is the one exception. It never leaves your device unless you approve it."}>
12
12
 
13
13
  ```html
14
14
  <div class="diagram-flow">
@@ -20,17 +20,17 @@ Clips isn't only a browser recorder. This page covers every place you can start
20
20
  <div class="diagram-arrow diagram-muted" aria-hidden="true">&rarr;</div>
21
21
  <div class="diagram-box" data-rough>
22
22
  Clips library<br /><small class="diagram-muted"
23
- >hosted, SQL — searchable and shareable</small
23
+ >hosted, SQL, searchable and shareable</small
24
24
  >
25
25
  </div>
26
26
  </div>
27
27
  <div class="diagram-flow" style="margin-top: 14px">
28
- <div class="diagram-node">Screen Memory</div>
28
+ <div class="diagram-node">Rewind</div>
29
29
  <div class="diagram-arrow diagram-muted" aria-hidden="true">&rarr;</div>
30
30
  <div class="diagram-panel center">
31
- <span class="diagram-pill">Your machine only</span
31
+ <span class="diagram-pill">Your device only</span
32
32
  ><small class="diagram-muted"
33
- >local files, off by default, never uploaded</small
33
+ >local files, off by default, shared only when you approve it</small
34
34
  >
35
35
  </div>
36
36
  </div>
@@ -64,50 +64,49 @@ Clips isn't only a browser recorder. This page covers every place you can start
64
64
 
65
65
  ## Desktop recorder and the desktop tray app
66
66
 
67
- Clips ships a desktop companion built for the smoothest everyday capture path: screen and webcam recording with a draggable camera bubble, live transcription while you record, calendar meeting reminders, and Hold-Fn dictation — all without keeping a browser tab open.
67
+ Clips ships a desktop companion built for the smoothest everyday capture path: screen and webcam recording with a draggable camera bubble, live transcription while you record, calendar meeting reminders, and Hold-Fn dictation, all without keeping a browser tab open.
68
68
 
69
69
  The first time you record your screen, your operating system will ask you to grant Screen Recording permission (on a Mac: System Settings → Privacy & Security → Screen Recording). That's an OS-level permission, not a Clips setting, and Clips can't record without it.
70
70
 
71
- While a meeting app like Zoom or Microsoft Teams is in the foreground, the desktop app can also offer a quick "Take notes?" prompt so you don't have to remember to start a recording yourself — see [Recording, importing, and meetings](/docs/template-clips#recording-importing-and-meetings) for what happens once you accept.
71
+ While a meeting app like Zoom or Microsoft Teams is in the foreground, the desktop app can also offer a quick "Take notes?" prompt so you don't have to remember to start a recording yourself. See [Recording, importing, and meetings](/docs/template-clips#recording-importing-and-meetings) for what happens once you accept.
72
72
 
73
73
  ## Mobile companion capture
74
74
 
75
- The Agent Native mobile app (iOS/Android) brings capture to your phone: dictate, join or record a meeting, shoot a quick video, or import a clip — from the phone's home screen or an OS quick action.
75
+ The Agent Native mobile app (iOS/Android) brings capture to your phone: dictate, join or record a meeting, shoot a quick video, or import a clip, all from the phone's home screen or an OS quick action.
76
76
 
77
77
  A few things are different from desktop:
78
78
 
79
79
  - **Meeting audio is microphone-only.** Phones can't capture another app's call audio the way a desktop can, so mobile meeting recordings don't get the same per-attendee action-item attribution as a desktop capture with both mic and system audio. Mobile is a good fit for in-person rooms or for capturing audio playing from a separate device.
80
80
  - **Dictation is tap-to-start/stop**, not press-and-hold like the desktop Fn-hold flow.
81
- - **Uploads are durable.** The audio or video file saves to your phone before any network request, so a dropped connection never loses the capture — it resumes the upload automatically once you're back online. You don't need to keep the app open or re-record after a failed upload.
81
+ - **Uploads are durable.** The audio or video file saves to your phone before any network request, so a dropped connection never loses the capture. The upload resumes automatically once you're back online. You don't need to keep the app open or re-record after a failed upload.
82
82
 
83
- ## Rewind quick-save
83
+ ## Rewind
84
84
 
85
- If you use [Rewind](https://www.rewind.ai) (a local screen-recall app) on your Mac and realize, after the fact, that a moment was worth keeping, Clips can pull in the last 30 seconds or 5 minutes of your local Rewind history and prepend it to a private clip.
85
+ Rewind is an optional local memory that keeps a rolling recording of your screen (and audio, if you turn it on), stored locally on your device.
86
86
 
87
- A few rules keep this predictable:
88
-
89
- - Only the clip's owner can request it, and only on a **private** clip with no one else already granted direct access — removing anyone else's access first keeps the pulled-in Rewind footage from being retroactively shared.
90
- - It replaces the clip's media with the combined recording. The transcript, chapters, comments, and reactions all shift automatically so their timestamps still line up with the new, earlier start time.
91
- - It's explicit and per-clip — Rewind quick-save never runs automatically in the background.
87
+ <Callout id="doc-block-clips2" tone="info">
88
+ Rewind is off by default. Nothing is captured until you turn it on in the
89
+ desktop tray's settings, and nothing leaves your device unless you approve it
90
+ (per-request review is on by default and can be turned off in Rewind's
91
+ settings). You can export, search, or clear the buffer yourself at any time.
92
+ </Callout>
92
93
 
93
- ## Screen Memory
94
+ The feature can be enabled under the Rewind tab in Settings. When enabled, you can ask the agent things like "what was I looking at 20 minutes ago?" and the agent reads the text excerpts from the local buffer of on-screen text, app and window context, and transcript snippets. The agent never receives the recordings themselves. The only exception is a request you review and approve, which turns an exact range into a private Clip (see below).
94
95
 
95
- Screen Memory is a different, optional feature: a local-only buffer that quietly notes which app or window was in front of you recently, entirely on your own machine.
96
+ ### Add what happened before
96
97
 
97
- <Callout id="doc-block-clips2" tone="info">
98
- Screen Memory is off by default. Nothing is captured until you turn it on, and
99
- nothing ever leaves your machine automatically — you export or clear it
100
- yourself from the desktop tray's settings.
101
- </Callout>
98
+ In the clip's editor, **Add what happened before** pulls the previous 30 seconds or 5 minutes from your local Rewind history and adds it to the start of the clip. The clip must have been recorded on this device while Rewind was on, and the moments must still be within Rewind's retained history.
102
99
 
103
- When it's enabled, you can ask the agent things like "what was I looking at 20 minutes ago?" and it checks the local buffer before answering. It is never a hosted or shareable Clips recording, and it never exposes raw screen images to the agent — only bounded text snippets of app and window context.
100
+ - The clip must be private, with no one else granted direct access. Rewind history can contain context from before you chose to record, so Clips makes the clip private first and stops if anyone else still has access.
101
+ - The clip's media is replaced with the combined recording. The transcript, chapters, comments, and reactions shift so their timestamps still line up, and the timeline marks where the original clip started.
102
+ - It runs once per clip and only when you ask. Nothing is added from Rewind automatically.
104
103
 
105
104
  ## Browser logs with the Chrome extension
106
105
 
107
- Install the Clips Chrome extension when you want a recording plus the browser logs and network activity from the tab you're debugging — useful for reporting product bugs and browser-only repros.
106
+ Install the Clips Chrome extension when you want a recording plus the browser logs and network activity from the tab you're debugging. It's useful for reporting product bugs and browser-only repros.
108
107
 
109
108
  - It only watches the tab you're actively recording, and only while the recording is running.
110
- - It saves console messages and basic per-request info (method, a redacted URL, status, duration, and whether a request failed) — never request or response bodies, headers, or cookies.
109
+ - It saves console messages and basic per-request info (method, a redacted URL, status, duration, and whether a request failed). It never saves request or response bodies, headers, or cookies.
111
110
  - Use the desktop app for the smoothest everyday recording; reach for the Chrome extension specifically when you need those browser logs attached.
112
111
 
113
112
  See [Extending Clips](/docs/template-clips-developers) for the extension's install link and how to configure it on a self-hosted deployment.
@@ -100,7 +100,7 @@ This pilot requires the reporter to already have an active session in the Clips
100
100
 
101
101
  All data lives in SQL via Drizzle ORM. Schema: `templates/clips/server/db/schema.ts`. Recordings, meetings, dictations, calendar accounts, and vocabulary all carry the standard `ownableColumns` and have a matching framework shares table, so they slot into the per-user / per-org sharing model.
102
102
 
103
- Two things live outside this schema on purpose: organization/member/invitation rows are framework-owned tables (`organizations`, `org_members`, `org_invitations`), with `organization_settings` as the Clips-specific sidecar keyed by organization id; and the Rewind quick-save request lifecycle and mobile-capture-state live in `application_state`, not a SQL table, since they're short-lived, per-session status rather than durable app data.
103
+ Two things live outside this schema on purpose: organization/member/invitation rows are framework-owned tables (`organizations`, `org_members`, `org_invitations`), with `organization_settings` as the Clips-specific sidecar keyed by organization id; and the "Add what happened before" (Rewind pre-roll) request lifecycle and mobile-capture-state live in `application_state`, not a SQL table, since they're short-lived, per-session status rather than durable app data.
104
104
 
105
105
  <DataModel
106
106
  id="doc-block-oitg2"
@@ -313,7 +313,7 @@ Recordings and transcripts are intentionally separate tables so the library and
313
313
  },
314
314
  {
315
315
  path: "actions/request-rewind-extension.ts",
316
- note: "Local Rewind quick-save request lifecycle",
316
+ note: "Add-what-happened-before (Rewind pre-roll) request lifecycle",
317
317
  },
318
318
  {
319
319
  path: "app/routes/",
@@ -349,7 +349,7 @@ Every agent-callable operation is a TypeScript file in `templates/clips/actions/
349
349
  - **Sharing, comments & engagement** — framework sharing actions (`share-resource`, `set-resource-visibility`, `list-resource-shares`) plus `build-embed-url`, `create-recording-agent-link`, `create-cta` / `update-cta` / `delete-cta`, `add-comment` / `reply-to-comment` / `resolve-comment` / `react-to-comment` / `delete-comment`, `react-to-recording`, `list-viewers`, `list-clip-views`.
350
350
  - **Organizations & members** — `create-organization`, `set-organization-branding`, `invite-member` / `accept-invite` / `decline-invite` / `get-invite`, `remove-member`, `update-member-role`, `list-organization-state`, `list-notifications`.
351
351
  - **Screen Memory** — `get-screen-memory-status`, `query-screen-memory-context`. Both read bounded local files on the current machine only; neither ever returns media bytes or images.
352
- - **Rewind quick-save** — `request-rewind-extension`, `get-rewind-extension-request`, `list-rewind-extension-requests`, `update-rewind-extension-request`, `make-recording-private-for-rewind`, `apply-rewind-extension`.
352
+ - **Add what happened before (Rewind pre-roll)** — `request-rewind-extension`, `get-rewind-extension-request`, `list-rewind-extension-requests`, `update-rewind-extension-request`, `make-recording-private-for-rewind`, `apply-rewind-extension`.
353
353
  - **Mobile companion** — `set-mobile-capture-state` records the privacy-safe view/phase of the mobile capture UI; it's not agent-callable (`agentTool: false`).
354
354
  - **CRM & Brain export** — `prepare-crm-call-evidence`, `export-to-brain`.
355
355
  - **Search & insights** — `search-recordings` (matches titles, descriptions, transcript text, and comments, with timestamps), `get-recording-insights`, `get-organization-insights`, `export-insights-csv`, `list-ai-requests` / `update-ai-request-status`.
@@ -372,7 +372,7 @@ The agent edits routes, components, the transcript pipeline, and the schema as n
372
372
  ## What's next
373
373
 
374
374
  - [**Clips**](/docs/template-clips) — the overview
375
- - [**Capturing Everywhere**](/docs/template-clips-capture-everywhere) — desktop, mobile, Rewind, Screen Memory, and the Chrome extension from a user's perspective
375
+ - [**Capturing Everywhere**](/docs/template-clips-capture-everywhere) — desktop, mobile, Rewind, and the Chrome extension from a user's perspective
376
376
  - [**Sharing, Teams, and Agent-Readable Clips**](/docs/template-clips-sharing-and-teams) — the sharing model this data model backs
377
377
  - [**AI Pipeline, Editing, and Insights**](/docs/template-clips-ai-and-editing) — the transcription and editing pipeline these actions power
378
378
  - [**Templates**](/docs/cloneable-saas) — the Cloneable SaaS model
@@ -110,7 +110,9 @@ Live demo: [clips.agent-native.com](https://clips.agent-native.com).
110
110
 
111
111
  ## What's next
112
112
 
113
- - [**Capturing Everywhere**](/docs/template-clips-capture-everywhere) — the desktop app, the mobile companion, Rewind quick-save, Screen Memory, and the Chrome extension.
113
+ {/* i18n-copy-ignore: formatting-only line break; localized copies predate this link list, so no translated prose changed. */}
114
+
115
+ - [**Capturing Everywhere**](/docs/template-clips-capture-everywhere) — the desktop app, the mobile companion, Rewind, and the Chrome extension.
114
116
  - [**Sharing, Teams, and Agent-Readable Clips**](/docs/template-clips-sharing-and-teams) — visibility, passwords, organizations, and pasting a clip link into an agent.
115
117
  - [**AI Pipeline, Editing, and Insights**](/docs/template-clips-ai-and-editing) — transcription, non-destructive editing, and view analytics.
116
118
  - [**Extending Clips**](/docs/template-clips-developers) — for anyone customizing or extending the template.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-native/core",
3
- "version": "0.169.1",
3
+ "version": "0.170.0",
4
4
  "description": "Framework for agent-native application development — where AI agents and UI share SQL state, actions, and context",
5
5
  "homepage": "https://github.com/BuilderIO/agent-native#readme",
6
6
  "bugs": {
@@ -429,7 +429,7 @@
429
429
  "yjs": "^13.6.32",
430
430
  "zod": "^4.3.6",
431
431
  "@agent-native/recap-cli": "0.5.8",
432
- "@agent-native/toolkit": "^0.16.10"
432
+ "@agent-native/toolkit": "^0.16.11"
433
433
  },
434
434
  "devDependencies": {
435
435
  "@ai-sdk/anthropic": "^3.0.71",
@@ -17,7 +17,11 @@ export const WORKSPACE_CONNECTION_PROVIDERS: WorkspaceConnectionProvider[] = [
17
17
  "figma",
18
18
  "notion",
19
19
  "gmail",
20
+ "google_calendar",
20
21
  "google_drive",
22
+ "google_docs",
23
+ "google_sheets",
24
+ "google_slides",
21
25
  "hubspot",
22
26
  "salesforce",
23
27
  "jira",
@@ -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
  });
@@ -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;
@@ -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
 
@@ -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