@agent-native/core 0.169.1 → 0.171.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (463) hide show
  1. package/agent-native.eject.json +4 -1
  2. package/bin/agent-native.js +23 -5
  3. package/corpus/README.md +1 -1
  4. package/corpus/templates/analytics/.agents/skills/secrets/SKILL.md +11 -4
  5. package/corpus/templates/analytics/actions/query-agent-native-analytics.ts +1 -1
  6. package/corpus/templates/analytics/app/i18n-data.ts +28 -0
  7. package/corpus/templates/analytics/app/pages/Agents.tsx +25 -1
  8. package/corpus/templates/analytics/app/routes/$.tsx +10 -0
  9. package/corpus/templates/analytics/app/routes.ts +3 -1
  10. package/corpus/templates/analytics/changelog/2026-08-22-fixed-the-agent-native-templates-first-party-dashboard-panel.md +6 -0
  11. package/corpus/templates/analytics/changelog/2026-08-22-org-admin-panels-no-longer-report-a-database-error-as-a-per.md +9 -0
  12. package/corpus/templates/analytics/changelog/2026-08-22-slack-requests-report-invalid-inputs.md +6 -0
  13. package/corpus/templates/analytics/changelog/2026-08-22-unknown-analytics-links-now-return-a-real-not-found-status.md +6 -0
  14. package/corpus/templates/analytics/docs/schemas/first-party-analytics.md +2 -1
  15. package/corpus/templates/analytics/docs/schemas/tracked-events.md +2 -0
  16. package/corpus/templates/analytics/scripts/emit-netlify-dashboard-report-cron.ts +29 -7
  17. package/corpus/templates/analytics/server/handlers/slack.ts +59 -5
  18. package/corpus/templates/analytics/server/lib/db-admin-connections.ts +11 -6
  19. package/corpus/templates/analytics/server/lib/first-party-analytics.ts +132 -2
  20. package/corpus/templates/analytics/server/lib/slack.ts +4 -2
  21. package/corpus/templates/analytics/vitest.config.ts +6 -1
  22. package/corpus/templates/assets/.agents/skills/secrets/SKILL.md +11 -4
  23. package/corpus/templates/assets/app/routes/library.tsx +5 -3
  24. package/corpus/templates/assets/app/routes.ts +3 -1
  25. package/corpus/templates/assets/changelog/2026-08-22-library-page-loads-again-instead-of-crashing-on-open.md +6 -0
  26. package/corpus/templates/assets/vitest.config.ts +6 -1
  27. package/corpus/templates/brain/.agents/skills/secrets/SKILL.md +11 -4
  28. package/corpus/templates/brain/app/components/ui/pointer-lock.ts +1 -0
  29. package/corpus/templates/brain/app/routes/sources.tsx +8 -3
  30. package/corpus/templates/brain/changelog/2026-08-22-tuning-or-adding-a-source-no-longer-leaves-the-sources-page.md +6 -0
  31. package/corpus/templates/brain/vitest.config.ts +1 -0
  32. package/corpus/templates/calendar/.agents/skills/secrets/SKILL.md +11 -4
  33. package/corpus/templates/calendar/actions/list-booking-links.ts +83 -4
  34. package/corpus/templates/calendar/actions/update-booking-link.ts +4 -3
  35. package/corpus/templates/calendar/app/components/calendar/EventDetailPanel.tsx +11 -3
  36. package/corpus/templates/calendar/app/components/calendar/EventDetailPopover.tsx +1 -1
  37. package/corpus/templates/calendar/app/components/calendar/GoogleConnectBanner.tsx +103 -44
  38. package/corpus/templates/calendar/app/components/calendar/OutOfOfficeEvent.tsx +28 -24
  39. package/corpus/templates/calendar/app/components/layout/AppLayout.tsx +9 -2
  40. package/corpus/templates/calendar/app/components/layout/Sidebar.tsx +47 -58
  41. package/corpus/templates/calendar/app/hooks/use-booking-links.ts +5 -1
  42. package/corpus/templates/calendar/app/lib/event-layout.ts +52 -26
  43. package/corpus/templates/calendar/app/pages/BookingLinksPage.tsx +126 -98
  44. package/corpus/templates/calendar/app/pages/CalendarView.tsx +1 -0
  45. package/corpus/templates/calendar/app/pages/Settings.tsx +88 -81
  46. package/corpus/templates/calendar/app/routes.ts +3 -1
  47. package/corpus/templates/calendar/changelog/2026-08-22-booking-link-visibility-respects-shared-access.md +6 -0
  48. package/corpus/templates/calendar/changelog/2026-08-22-clicking-an-out-of-office-event-s-marker-no-longer-creates-a.md +6 -0
  49. package/corpus/templates/calendar/changelog/2026-08-22-event-detail-views-now-show-your-calendar-timezone.md +6 -0
  50. package/corpus/templates/calendar/changelog/2026-08-22-google-calendar-can-now-connect-with-the-shared-google-oauth.md +6 -0
  51. package/corpus/templates/calendar/changelog/2026-08-22-overlapping-events-now-show-each-others-boundaries.md +6 -0
  52. package/corpus/templates/calendar/changelog/2026-08-22-public-booking-pages-now-offer-time-slots-from-the-host-s-we.md +6 -0
  53. package/corpus/templates/calendar/server/handlers/bookings.ts +5 -7
  54. package/corpus/templates/calendar/server/handlers/google-auth.ts +10 -2
  55. package/corpus/templates/calendar/server/lib/google-calendar.ts +139 -14
  56. package/corpus/templates/calendar/server/onboarding.ts +85 -0
  57. package/corpus/templates/calendar/server/plugins/agent-chat.ts +2 -0
  58. package/corpus/templates/calendar/shared/api.ts +9 -1
  59. package/corpus/templates/chat/.agents/skills/secrets/SKILL.md +11 -4
  60. package/corpus/templates/chat/app/routes.ts +3 -1
  61. package/corpus/templates/chat/vitest.config.ts +8 -0
  62. package/corpus/templates/clips/.agents/skills/secrets/SKILL.md +11 -4
  63. package/corpus/templates/clips/actions/get-meeting.ts +9 -4
  64. package/corpus/templates/clips/actions/list-recordings.ts +16 -3
  65. package/corpus/templates/clips/actions/search-meetings.ts +1 -0
  66. package/corpus/templates/clips/actions/view-screen.ts +8 -1
  67. package/corpus/templates/clips/app/components/meetings/meeting-history-row.tsx +32 -1
  68. package/corpus/templates/clips/app/components/player/delete-recording-menu.tsx +1 -1
  69. package/corpus/templates/clips/app/components/recorder/recorder-engine.ts +29 -1
  70. package/corpus/templates/clips/app/i18n/en-US.ts +5 -0
  71. package/corpus/templates/clips/app/routes/_app.meetings.$meetingId.tsx +33 -4
  72. package/corpus/templates/clips/app/routes/_app.meetings._index.tsx +1 -0
  73. package/corpus/templates/clips/app/routes/access-request.approve.tsx +16 -9
  74. package/corpus/templates/clips/app/routes/embed.$shareId.tsx +17 -7
  75. package/corpus/templates/clips/app/routes/share.$shareId.tsx +17 -7
  76. package/corpus/templates/clips/changelog/2026-08-21-camera-bubble-black-circle.md +6 -0
  77. package/corpus/templates/clips/changelog/2026-08-22-screen-recordings-respect-the-microphone-toggle.md +6 -0
  78. package/corpus/templates/clips/changelog/2026-08-22-the-recordings-library-no-longer-fails-right-after-server-start.md +6 -0
  79. package/corpus/templates/clips/changelog/2026-08-23-the-agent-can-see-your-library-right-after-server-start.md +6 -0
  80. package/corpus/templates/clips/chrome-extension/src/background.ts +1 -2
  81. package/corpus/templates/clips/chrome-extension/src/native-transcription.ts +39 -7
  82. package/corpus/templates/clips/chrome-extension/src/offscreen.ts +21 -25
  83. package/corpus/templates/clips/desktop/src/app.tsx +53 -24
  84. package/corpus/templates/clips/desktop/src/lib/bubble-playback.ts +68 -0
  85. package/corpus/templates/clips/desktop/src/lib/recorder.ts +3 -0
  86. package/corpus/templates/clips/desktop/src/lib/transcription-capture.ts +72 -14
  87. package/corpus/templates/clips/desktop/src/lib/updater.ts +8 -3
  88. package/corpus/templates/clips/desktop/src/overlays/bubble.tsx +162 -20
  89. package/corpus/templates/clips/desktop/src-tauri/src/clips/mod.rs +43 -6
  90. package/corpus/templates/clips/desktop/src-tauri/src/native_screen/custom_capture.rs +150 -13
  91. package/corpus/templates/clips/desktop/src-tauri/src/tray.rs +12 -0
  92. package/corpus/templates/clips/server/lib/calendar-event-meetings.ts +28 -3
  93. package/corpus/templates/clips/server/lib/emails.ts +17 -33
  94. package/corpus/templates/content/.agents/skills/secrets/SKILL.md +11 -4
  95. package/corpus/templates/content/app/components/editor/VisualEditor.tsx +140 -15
  96. package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +12 -14
  97. package/corpus/templates/content/app/components/ui/pointer-lock.ts +1 -0
  98. package/corpus/templates/content/app/hooks/use-content-database.ts +18 -2
  99. package/corpus/templates/content/app/hooks/use-local-storage.ts +38 -22
  100. package/corpus/templates/content/app/i18n-data.ts +25 -0
  101. package/corpus/templates/content/app/routes.ts +3 -1
  102. package/corpus/templates/content/changelog/2026-08-22-code-blocks-inserted-from-the-slash-menu-no-longer-get-stuck.md +6 -0
  103. package/corpus/templates/content/changelog/2026-08-22-the-sidebar-page-tree-no-longer-flashes-empty-after-creating-a-page.md +6 -0
  104. package/corpus/templates/content/docs/solutions/2026-08-21-content-mermaid-rendering-shape.md +233 -0
  105. package/corpus/templates/content/server/plugins/agent-chat.ts +9 -2
  106. package/corpus/templates/content/vitest.config.ts +7 -1
  107. package/corpus/templates/crm/.agents/skills/secrets/SKILL.md +11 -4
  108. package/corpus/templates/design/.agents/skills/secrets/SKILL.md +11 -4
  109. package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +1383 -88
  110. package/corpus/templates/design/actions/generate-design.ts +98 -47
  111. package/corpus/templates/design/actions/get-design-system.ts +6 -1
  112. package/corpus/templates/design/actions/refresh-design-system-with-builder.ts +146 -0
  113. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +70 -26
  114. package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +284 -136
  115. package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +2057 -141
  116. package/corpus/templates/design/app/components/design/editor/DesignBottomToolbar.tsx +6 -2
  117. package/corpus/templates/design/app/components/design/editor/DesignWorkspaceRail.tsx +4 -4
  118. package/corpus/templates/design/app/components/design/keyboard-shortcuts.ts +10 -1
  119. package/corpus/templates/design/app/components/design/multi-screen/alt-hover-measurement.ts +19 -2
  120. package/corpus/templates/design/app/components/design/multi-screen/types.ts +9 -2
  121. package/corpus/templates/design/app/components/layout/Header.tsx +15 -0
  122. package/corpus/templates/design/app/components/layout/Layout.tsx +7 -2
  123. package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +11 -4
  124. package/corpus/templates/design/app/i18n-data.ts +1 -0
  125. package/corpus/templates/design/app/i18n-keyboard-shortcuts.ts +12 -0
  126. package/corpus/templates/design/app/lib/design-system-data.ts +68 -0
  127. package/corpus/templates/design/app/pages/DesignEditor.tsx +77 -35
  128. package/corpus/templates/design/app/pages/DesignSystems.tsx +136 -42
  129. package/corpus/templates/design/app/pages/Index.tsx +2 -0
  130. package/corpus/templates/design/app/pages/Templates.tsx +0 -10
  131. package/corpus/templates/design/app/pages/design-editor/code-layer-state.ts +10 -0
  132. package/corpus/templates/design/app/pages/design-editor/collab-sync.ts +50 -0
  133. package/corpus/templates/design/app/pages/design-editor/commands/apply-design-editor-command.ts +1 -1
  134. package/corpus/templates/design/app/pages/design-editor/commands/apply-file-content-update.ts +10 -8
  135. package/corpus/templates/design/app/pages/design-editor/commands/apply-local-content-update.ts +6 -6
  136. package/corpus/templates/design/app/pages/design-editor/commands/apply-pending-visual-styles-with-agent.ts +1 -1
  137. package/corpus/templates/design/app/pages/design-editor/commands/commit-visual-styles.ts +18 -7
  138. package/corpus/templates/design/app/pages/design-editor/commands/escape-hotkey.ts +4 -90
  139. package/corpus/templates/design/app/pages/design-editor/commands/layer-marquee-selection-change.ts +2 -1
  140. package/corpus/templates/design/app/pages/design-editor/commands/layer-selection-change.ts +4 -3
  141. package/corpus/templates/design/app/pages/design-editor/commands/screen-element-select.ts +12 -2
  142. package/corpus/templates/design/app/pages/design-editor/commands/screen-visual-style-change.ts +9 -2
  143. package/corpus/templates/design/app/pages/design-editor/commands/send-runtime-layer-move-semantic-handoff.ts +1 -1
  144. package/corpus/templates/design/app/pages/design-editor/commands/send-runtime-layer-semantic-handoff.ts +1 -1
  145. package/corpus/templates/design/app/pages/design-editor/commands/send-runtime-layer-state-semantic-handoff.ts +1 -1
  146. package/corpus/templates/design/app/pages/design-editor/commands/start-sidebar-resize.ts +1 -1
  147. package/corpus/templates/design/app/pages/design-editor/editor-state.ts +11 -1
  148. package/corpus/templates/design/app/pages/design-editor/effects/adopt-db-file-content.ts +11 -19
  149. package/corpus/templates/design/app/pages/design-editor/effects/observe-collab-text.ts +6 -6
  150. package/corpus/templates/design/app/pages/design-editor/effects/publish-agent-selection-context.ts +1 -1
  151. package/corpus/templates/design/app/pages/design-editor/effects/seed-collab-content.ts +12 -15
  152. package/corpus/templates/design/app/pages/design-editor/selection-state.ts +5 -59
  153. package/corpus/templates/design/app/pages/design-editor/tool-state.ts +8 -0
  154. package/corpus/templates/design/app/pages/design-editor/types.ts +3 -3
  155. package/corpus/templates/design/app/routes.ts +3 -1
  156. package/corpus/templates/design/changelog/2026-08-20-canvas-edits-patch-the-frame-instead-of-rebuilding-it.md +6 -0
  157. package/corpus/templates/design/changelog/2026-08-21-builder-design-system-imports-reconcile-after-indexing.md +6 -0
  158. package/corpus/templates/design/changelog/2026-08-21-draw-mode-needs-shift-y.md +6 -0
  159. package/corpus/templates/design/changelog/2026-08-21-eyedropper-shortcut.md +6 -0
  160. package/corpus/templates/design/changelog/2026-08-21-figma-style-alignment-guides-and-snapping.md +6 -0
  161. package/corpus/templates/design/changelog/2026-08-21-group-transforms-keep-the-selection.md +6 -0
  162. package/corpus/templates/design/changelog/2026-08-21-inspector-fields-keep-focus-on-enter.md +6 -0
  163. package/corpus/templates/design/changelog/2026-08-21-pen-alt-keeps-the-incoming-handle.md +6 -0
  164. package/corpus/templates/design/changelog/2026-08-21-pen-on-the-board-creates-one-vector.md +6 -0
  165. package/corpus/templates/design/changelog/2026-08-21-scale-a-multi-selection-from-the-group-handles.md +6 -0
  166. package/corpus/templates/design/changelog/2026-08-21-scale-resizes-text-with-the-object.md +6 -0
  167. package/corpus/templates/design/changelog/2026-08-21-selecting-another-object-keeps-the-scale-tool-armed.md +6 -0
  168. package/corpus/templates/design/changelog/2026-08-21-the-shape-tool-remembers-the-shape-you-picked.md +6 -0
  169. package/corpus/templates/design/changelog/2026-08-21-vectors-drawn-in-a-frame-land-where-you-drew-them.md +6 -0
  170. package/corpus/templates/design/changelog/2026-08-22-multi-screen-generation-no-longer-loses-a-saved-screens-layo.md +6 -0
  171. package/corpus/templates/design/changelog/2026-08-22-rename-and-search-fields-are-labeled-for-screen-readers.md +6 -0
  172. package/corpus/templates/design/package.json +2 -0
  173. package/corpus/templates/design/server/lib/builder-design-system-proxy.ts +311 -0
  174. package/corpus/templates/design/shared/canvas-math.ts +612 -206
  175. package/corpus/templates/design/shared/pen-path.ts +37 -0
  176. package/corpus/templates/design/vitest.config.ts +7 -1
  177. package/corpus/templates/dispatch/.agents/skills/secrets/SKILL.md +11 -4
  178. package/corpus/templates/dispatch/actions/list-workspace-connections.ts +34 -3
  179. package/corpus/templates/dispatch/app/routes/integrations.tsx +55 -21
  180. package/corpus/templates/dispatch/app/routes.ts +3 -1
  181. package/corpus/templates/factory/.agents/skills/secrets/SKILL.md +11 -4
  182. package/corpus/templates/factory/.env.example +2 -7
  183. package/corpus/templates/factory/AGENTS.md +3 -0
  184. package/corpus/templates/factory/README.md +5 -3
  185. package/corpus/templates/factory/actions/create-factory.ts +16 -3
  186. package/corpus/templates/factory/actions/get-slack-feedback-context.ts +2 -0
  187. package/corpus/templates/factory/actions/get-triage-item.ts +2 -0
  188. package/corpus/templates/factory/actions/list-factory-audit.ts +116 -36
  189. package/corpus/templates/factory/actions/list-factory-automations.ts +2 -1
  190. package/corpus/templates/factory/actions/list-triage-items.ts +22 -19
  191. package/corpus/templates/factory/actions/run-factory-automation.ts +7 -3
  192. package/corpus/templates/factory/actions/save-factory-automation.ts +5 -2
  193. package/corpus/templates/factory/actions/save-triage-config.ts +2 -8
  194. package/corpus/templates/factory/actions/start-builder-for-item.ts +21 -0
  195. package/corpus/templates/factory/app/components/factory/FactoryAuditView.tsx +229 -297
  196. package/corpus/templates/factory/app/components/factory/FactorySettingsView.tsx +397 -247
  197. package/corpus/templates/factory/app/components/factory/FactorySourceSettingsGroup.tsx +33 -0
  198. package/corpus/templates/factory/app/components/factory/NewFactoryForm.tsx +202 -162
  199. package/corpus/templates/factory/app/i18n/en-US.ts +32 -4
  200. package/corpus/templates/factory/app/routes/factory.tsx +84 -11
  201. package/corpus/templates/factory/app/routes.ts +3 -1
  202. package/corpus/templates/factory/changelog/2026-08-21-activity-runs-use-automation-display-names.md +6 -0
  203. package/corpus/templates/factory/changelog/2026-08-21-create-and-settings-source-cards.md +6 -0
  204. package/corpus/templates/factory/changelog/2026-08-21-keep-automations-visible-while-running.md +6 -0
  205. package/corpus/templates/factory/changelog/2026-08-21-nested-factory-automations-can-poll.md +6 -0
  206. package/corpus/templates/factory/changelog/2026-08-21-settings-sticky-unsaved-bar.md +6 -0
  207. package/corpus/templates/factory/server/connectors/credentials.ts +10 -5
  208. package/corpus/templates/factory/server/lib/factory-audit-report.ts +412 -0
  209. package/corpus/templates/factory/server/lib/factory-config-reconcile.ts +321 -0
  210. package/corpus/templates/factory/server/lib/factory-scope.ts +25 -2
  211. package/corpus/templates/factory/server/lib/require-factory-automation.ts +13 -4
  212. package/corpus/templates/factory/server/plugins/factory-migrations.ts +148 -4
  213. package/corpus/templates/factory/server/plugins/factory-scheduler-job.ts +4 -6
  214. package/corpus/templates/factory/vitest.config.ts +17 -2
  215. package/corpus/templates/forms/.agents/skills/secrets/SKILL.md +11 -4
  216. package/corpus/templates/forms/app/routes/_app.settings.tsx +4 -1
  217. package/corpus/templates/forms/changelog/2026-08-22-the-extensions-link-now-opens-the-extensions-tab-instead-o.md +6 -0
  218. package/corpus/templates/forms/server/lib/public-form-ssr.ts +11 -1
  219. package/corpus/templates/forms/vitest.config.ts +1 -0
  220. package/corpus/templates/macros/.agents/skills/secrets/SKILL.md +11 -4
  221. package/corpus/templates/macros/app/routes.ts +3 -1
  222. package/corpus/templates/macros/vitest.config.ts +6 -1
  223. package/corpus/templates/mail/.agents/skills/secrets/SKILL.md +11 -4
  224. package/corpus/templates/mail/actions/manage-gmail-filters.ts +10 -2
  225. package/corpus/templates/mail/app/components/GoogleConnectBanner.tsx +100 -37
  226. package/corpus/templates/mail/app/components/email/IntegrationsSidebar.tsx +14 -2
  227. package/corpus/templates/mail/app/components/layout/AppLayout.tsx +66 -36
  228. package/corpus/templates/mail/app/hooks/use-google-auth.ts +2 -0
  229. package/corpus/templates/mail/app/lib/google-oauth-setup.ts +17 -0
  230. package/corpus/templates/mail/app/pages/InboxPage.tsx +69 -9
  231. package/corpus/templates/mail/app/routes/$.tsx +9 -0
  232. package/corpus/templates/mail/app/routes/$view.$threadId.tsx +23 -1
  233. package/corpus/templates/mail/app/routes/$view.tsx +47 -1
  234. package/corpus/templates/mail/app/routes.ts +3 -1
  235. package/corpus/templates/mail/changelog/2026-08-22-gmail-can-now-connect-with-the-shared-google-oauth.md +6 -0
  236. package/corpus/templates/mail/changelog/2026-08-22-gmail-filters-now-shows-the-real-error.md +6 -0
  237. package/corpus/templates/mail/changelog/2026-08-22-unknown-mail-urls-now-show-the-404-page.md +6 -0
  238. package/corpus/templates/mail/server/handlers/google-auth.ts +11 -2
  239. package/corpus/templates/mail/server/lib/google-auth.ts +92 -12
  240. package/corpus/templates/mail/server/onboarding.ts +66 -18
  241. package/corpus/templates/mail/vitest.config.ts +6 -1
  242. package/corpus/templates/plan/.agents/skills/secrets/SKILL.md +11 -4
  243. package/corpus/templates/plan/app/routes/settings.tsx +4 -1
  244. package/corpus/templates/plan/app/routes.ts +3 -1
  245. package/corpus/templates/plan/changelog/2026-08-22-the-extensions-link-now-opens-the-extensions-tab-instead-o.md +6 -0
  246. package/corpus/templates/plan/netlify.toml +1 -1
  247. package/corpus/templates/slides/.agents/skills/secrets/SKILL.md +11 -4
  248. package/corpus/templates/slides/actions/patch-deck.ts +79 -10
  249. package/corpus/templates/slides/actions/update-slide.ts +11 -1
  250. package/corpus/templates/slides/app/components/deck/SlideRenderer.tsx +14 -4
  251. package/corpus/templates/slides/app/components/editor/ExportMenu.tsx +10 -52
  252. package/corpus/templates/slides/app/components/editor/GoogleDocImportHint.tsx +8 -53
  253. package/corpus/templates/slides/app/components/editor/GoogleDriveConnectionCta.tsx +9 -75
  254. package/corpus/templates/slides/app/components/editor/GoogleSlidesReferenceImport.tsx +8 -60
  255. package/corpus/templates/slides/app/components/editor/SlideContextToolbar.tsx +10 -2
  256. package/corpus/templates/slides/app/components/editor/SlideEditor.tsx +19 -7
  257. package/corpus/templates/slides/app/lib/sanitize-slide-html.ts +49 -36
  258. package/corpus/templates/slides/app/routes/access-request.approve.tsx +16 -9
  259. package/corpus/templates/slides/app/routes.ts +3 -1
  260. package/corpus/templates/slides/changelog/2026-08-22-already-uploaded-chat-images-are-no-longer-dropped.md +6 -0
  261. package/corpus/templates/slides/changelog/2026-08-22-google-drive-and-slides-can-now-connect-with-the-shared-google-oauth.md +6 -0
  262. package/corpus/templates/slides/changelog/2026-08-22-multi-slide-repairs-now-report-slides-that-still-overflow.md +6 -0
  263. package/corpus/templates/slides/changelog/2026-08-22-update-slide-now-reports-which-batched-edit-was-skipped.md +6 -0
  264. package/corpus/templates/slides/server/handlers/google-docs-auth.ts +52 -1
  265. package/corpus/templates/slides/server/lib/chat-attachments.ts +29 -3
  266. package/corpus/templates/slides/server/lib/google-docs-oauth.ts +66 -16
  267. package/corpus/templates/slides/server/lib/slide-content-patch.ts +13 -2
  268. package/corpus/templates/slides/server/plugins/agent-chat.ts +5 -2
  269. package/corpus/templates/slides/tsconfig.json +5 -0
  270. package/corpus/templates/slides/vitest.config.ts +6 -1
  271. package/corpus/templates/tasks/.agents/skills/secrets/SKILL.md +11 -4
  272. package/corpus/templates/tasks/app/routes/settings.tsx +4 -1
  273. package/corpus/templates/tasks/app/routes.ts +3 -1
  274. package/corpus/templates/tasks/changelog/2026-08-22-the-extensions-link-now-opens-the-extensions-tab-instead-o.md +6 -0
  275. package/corpus/templates/tasks/vitest.config.ts +7 -1
  276. package/dist/action.d.ts +91 -0
  277. package/dist/action.js +50 -0
  278. package/dist/agent/abort-reasons.d.ts +38 -0
  279. package/dist/agent/abort-reasons.js +49 -0
  280. package/dist/agent/engine/ai-sdk-engine.js +8 -5
  281. package/dist/agent/engine/anthropic-engine.js +7 -5
  282. package/dist/agent/engine/first-event-timeout.d.ts +42 -17
  283. package/dist/agent/engine/first-event-timeout.js +67 -25
  284. package/dist/agent/production-agent.d.ts +23 -0
  285. package/dist/agent/production-agent.js +107 -102
  286. package/dist/agent/run-loop-with-resume.d.ts +2 -28
  287. package/dist/agent/run-loop-with-resume.js +25 -40
  288. package/dist/agent/run-manager.js +5 -4
  289. package/dist/agent/run-store.d.ts +55 -0
  290. package/dist/agent/run-store.js +124 -1
  291. package/dist/agent/tool-search.js +2 -1
  292. package/dist/agent/types.d.ts +9 -4
  293. package/dist/app-config/auth.d.ts +1 -0
  294. package/dist/app-config/auth.js +7 -0
  295. package/dist/app-config/configuration-error.d.ts +11 -0
  296. package/dist/app-config/configuration-error.js +14 -0
  297. package/dist/app-config/index.d.ts +1 -0
  298. package/dist/app-config/index.js +1 -0
  299. package/dist/app-config/integrations.d.ts +1 -0
  300. package/dist/app-config/integrations.js +10 -0
  301. package/dist/app-config/plugins.d.ts +34 -0
  302. package/dist/app-config/plugins.js +39 -0
  303. package/dist/app-config/run-lifecycle-invariants.d.ts +18 -9
  304. package/dist/app-config/run-lifecycle-invariants.js +18 -25
  305. package/dist/app-config/schema.d.ts +17 -0
  306. package/dist/app-config/schema.js +2 -0
  307. package/dist/chat-threads/schema-migrations.js +20 -0
  308. package/dist/chat-threads/store.js +21 -4
  309. package/dist/cli/native-dependencies.d.ts +4 -0
  310. package/dist/cli/native-dependencies.js +15 -0
  311. package/dist/client/EnvironmentBadge.d.ts +1 -1
  312. package/dist/client/EnvironmentBadge.js +40 -5
  313. package/dist/client/MultiTabAssistantChat.d.ts +1 -1
  314. package/dist/client/MultiTabAssistantChat.js +35 -14
  315. package/dist/client/agent-chat/index.d.ts +1 -1
  316. package/dist/client/agent-chat/index.js +1 -1
  317. package/dist/client/agent-page/use-jobs.d.ts +2 -1
  318. package/dist/client/agent-page/use-jobs.js +3 -5
  319. package/dist/client/agent-sidebar-state.js +3 -1
  320. package/dist/client/blocks/library/code-tabs.js +5 -0
  321. package/dist/client/blocks/library/code.js +1 -0
  322. package/dist/client/chat-first/apps-rail.js +2 -2
  323. package/dist/client/chat-model-groups.d.ts +12 -0
  324. package/dist/client/chat-model-groups.js +3 -2
  325. package/dist/client/integrations/GoogleProductLogo.d.ts +5 -0
  326. package/dist/client/integrations/GoogleProductLogo.js +45 -0
  327. package/dist/client/integrations/index.d.ts +2 -0
  328. package/dist/client/integrations/index.js +2 -0
  329. package/dist/client/integrations/workspace-provider-oauth.d.ts +8 -0
  330. package/dist/client/integrations/workspace-provider-oauth.js +13 -0
  331. package/dist/client/resources/mcp-integration-catalog.js +0 -29
  332. package/dist/client/settings/SettingsTabsPage.js +10 -6
  333. package/dist/client/sharing/ShareButton.js +11 -2
  334. package/dist/client/use-chat-models.d.ts +6 -0
  335. package/dist/client/use-chat-models.js +10 -0
  336. package/dist/client/use-db-sync.js +27 -9
  337. package/dist/collab/routes.d.ts +1 -1
  338. package/dist/collab/struct-routes.d.ts +1 -1
  339. package/dist/connections/catalog.d.ts +111 -9
  340. package/dist/connections/catalog.js +86 -30
  341. package/dist/db/create-get-db.js +18 -0
  342. package/dist/db/ddl-guard.d.ts +0 -4
  343. package/dist/db/ddl-guard.js +46 -0
  344. package/dist/deploy/build.d.ts +19 -0
  345. package/dist/deploy/build.js +190 -16
  346. package/dist/deploy/function-bundle.d.ts +45 -0
  347. package/dist/deploy/function-bundle.js +337 -0
  348. package/dist/deploy/workspace-deploy.js +19 -1
  349. package/dist/eject/workspace-connections.js +4 -0
  350. package/dist/email-catalog/registry.d.ts +4 -0
  351. package/dist/email-catalog/registry.js +79 -14
  352. package/dist/extensions/content-patch.js +14 -2
  353. package/dist/integrations/plugin.d.ts +10 -0
  354. package/dist/integrations/plugin.js +40 -6
  355. package/dist/jobs/actions/run-automation-now.d.ts +2 -1
  356. package/dist/jobs/actions/run-automation-now.js +11 -5
  357. package/dist/jobs/frontmatter.js +53 -2
  358. package/dist/jobs/run-now.d.ts +11 -1
  359. package/dist/jobs/run-now.js +42 -7
  360. package/dist/jobs/scheduler.d.ts +1 -0
  361. package/dist/jobs/scheduler.js +2 -1
  362. package/dist/localization/core-messages/ar-SA.js +3 -0
  363. package/dist/localization/core-messages/de-DE.js +3 -0
  364. package/dist/localization/core-messages/en-US.d.ts +3 -0
  365. package/dist/localization/core-messages/en-US.js +3 -0
  366. package/dist/localization/core-messages/es-ES.js +3 -0
  367. package/dist/localization/core-messages/fr-FR.js +3 -0
  368. package/dist/localization/core-messages/hi-IN.js +3 -0
  369. package/dist/localization/core-messages/ja-JP.js +3 -0
  370. package/dist/localization/core-messages/ko-KR.js +3 -0
  371. package/dist/localization/core-messages/pt-BR.js +3 -0
  372. package/dist/localization/core-messages/zh-CN.js +3 -0
  373. package/dist/localization/core-messages/zh-TW.js +3 -0
  374. package/dist/localization/core-messages.d.ts +3 -0
  375. package/dist/localization/default-messages.d.ts +2 -5
  376. package/dist/localization/default-messages.js +2 -5
  377. package/dist/mcp/build-server.d.ts +9 -0
  378. package/dist/mcp/build-server.js +37 -8
  379. package/dist/mcp-client/oauth-client.d.ts +7 -0
  380. package/dist/mcp-client/oauth-client.js +12 -1
  381. package/dist/oauth-tokens/index.d.ts +1 -1
  382. package/dist/oauth-tokens/index.js +1 -1
  383. package/dist/oauth-tokens/lifecycle.d.ts +11 -0
  384. package/dist/oauth-tokens/lifecycle.js +17 -0
  385. package/dist/oauth-tokens/store.js +7 -0
  386. package/dist/observability/posthog-ai.d.ts +15 -1
  387. package/dist/observability/posthog-ai.js +24 -12
  388. package/dist/observability/traces.js +158 -28
  389. package/dist/onboarding/app-profile.js +2 -2
  390. package/dist/onboarding/plugin.js +10 -2
  391. package/dist/onboarding/types.d.ts +2 -0
  392. package/dist/provider-api/actions/custom-provider-registration.d.ts +1 -1
  393. package/dist/provider-api/actions/provider-api.d.ts +2 -2
  394. package/dist/provider-api/index.js +2 -0
  395. package/dist/resources/handlers.d.ts +2 -2
  396. package/dist/resources/store.js +13 -4
  397. package/dist/scripts/agent-engines/list-agent-engines.js +29 -3
  398. package/dist/secrets/register-framework-secrets.js +1 -1
  399. package/dist/server/action-discovery.js +5 -0
  400. package/dist/server/agent-chat/action-filters-a2a.d.ts +27 -3
  401. package/dist/server/agent-chat/action-filters-a2a.js +48 -9
  402. package/dist/server/agent-chat-plugin.js +36 -9
  403. package/dist/server/agent-discovery.js +43 -20
  404. package/dist/server/auth.js +18 -16
  405. package/dist/server/beta-opt-out-html.js +45 -4
  406. package/dist/server/better-auth-instance.d.ts +2 -1
  407. package/dist/server/better-auth-instance.js +37 -7
  408. package/dist/server/builder-design-systems.d.ts +4 -1
  409. package/dist/server/builder-design-systems.js +87 -6
  410. package/dist/server/builder-oauth.d.ts +1 -7
  411. package/dist/server/builder-oauth.js +80 -163
  412. package/dist/server/core-routes-plugin.d.ts +29 -0
  413. package/dist/server/core-routes-plugin.js +100 -20
  414. package/dist/server/default-plugins.d.ts +18 -0
  415. package/dist/server/default-plugins.js +22 -0
  416. package/dist/server/edge.d.ts +1 -0
  417. package/dist/server/edge.js +1 -0
  418. package/dist/server/framework-request-handler.js +31 -3
  419. package/dist/server/google-oauth.d.ts +3 -0
  420. package/dist/server/google-oauth.js +3 -0
  421. package/dist/server/index.d.ts +4 -4
  422. package/dist/server/index.js +3 -3
  423. package/dist/server/onboarding-html.js +37 -3
  424. package/dist/server/realtime-token.d.ts +1 -1
  425. package/dist/server/workspace-provider-oauth.d.ts +6 -1
  426. package/dist/server/workspace-provider-oauth.js +72 -20
  427. package/dist/shared/agent-sidebar-url.d.ts +1 -0
  428. package/dist/shared/agent-sidebar-url.js +1 -0
  429. package/dist/shared/environment-lanes.d.ts +2 -0
  430. package/dist/shared/environment-lanes.js +3 -1
  431. package/dist/shared/index.d.ts +3 -1
  432. package/dist/shared/index.js +3 -1
  433. package/dist/shared/surface-visibility.d.ts +31 -0
  434. package/dist/shared/surface-visibility.js +57 -0
  435. package/dist/templates/chat/.agents/skills/secrets/SKILL.md +11 -4
  436. package/dist/templates/chat/app/routes.ts +3 -1
  437. package/dist/templates/chat/vitest.config.ts +8 -0
  438. package/dist/templates/default/.agents/skills/secrets/SKILL.md +11 -4
  439. package/dist/templates/default/app/routes.ts +3 -1
  440. package/dist/templates/headless/.agents/skills/secrets/SKILL.md +11 -4
  441. package/dist/templates/workspace-core/.agents/skills/secrets/SKILL.md +11 -4
  442. package/dist/tracking/registry.d.ts +11 -0
  443. package/dist/tracking/registry.js +5 -2
  444. package/dist/triggers/actions.js +10 -3
  445. package/dist/usage/store.js +23 -3
  446. package/dist/user-profile/actions/get-auth-methods.js +18 -5
  447. package/dist/vite/client.js +33 -7
  448. package/docs/content/actions-access-control.mdx +43 -4
  449. package/docs/content/actions-defining.mdx +16 -0
  450. package/docs/content/authentication.mdx +40 -21
  451. package/docs/content/environment-variables.mdx +1 -0
  452. package/docs/content/template-clips-capture-everywhere.mdx +29 -30
  453. package/docs/content/template-clips-developers.mdx +4 -4
  454. package/docs/content/template-clips.mdx +3 -1
  455. package/package.json +2 -2
  456. package/src/eject/workspace-connections.ts +4 -0
  457. package/src/templates/chat/.agents/skills/secrets/SKILL.md +11 -4
  458. package/src/templates/chat/app/routes.ts +3 -1
  459. package/src/templates/chat/vitest.config.ts +8 -0
  460. package/src/templates/default/.agents/skills/secrets/SKILL.md +11 -4
  461. package/src/templates/default/app/routes.ts +3 -1
  462. package/src/templates/headless/.agents/skills/secrets/SKILL.md +11 -4
  463. package/src/templates/workspace-core/.agents/skills/secrets/SKILL.md +11 -4
@@ -14,7 +14,13 @@ export default mergeConfig(
14
14
  },
15
15
  test: {
16
16
  include: ["**/*.{test,spec}.?(c|m)[jt]s?(x)"],
17
- exclude: ["**/node_modules/**", "**/.git/**", "**/dist/**", "**/e2e/**"],
17
+ exclude: [
18
+ "**/node_modules/**",
19
+ "**/.git/**",
20
+ "**/dist/**",
21
+ "**/.react-router/**",
22
+ "**/e2e/**",
23
+ ],
18
24
  environment: "node",
19
25
  },
20
26
  }),
package/dist/action.d.ts CHANGED
@@ -415,6 +415,49 @@ interface DefineActionWithSchema<TSchema extends StandardSchemaV1, TReturn = any
415
415
  * tool list. Distinct from `toolCallable`, which only governs the sandboxed
416
416
  * extension ("tools") iframe bridge. See `packages/core/docs/content/actions.mdx`. */
417
417
  agentTool?: boolean;
418
+ /** Whether this action is exposed to EXTERNAL agents over MCP (and the direct
419
+ * A2A action surface, which shares the same policy).
420
+ *
421
+ * **Defaults to `agentTool`, not to `true`**: an action hidden from the
422
+ * agent is hidden from outside agents too, so one flag stays one decision.
423
+ * Declaring `mcpTool` overrides that inheritance in both directions.
424
+ *
425
+ * - `false` — hard veto. The action is absent from `tools/list` AND from
426
+ * `tools/call` on every MCP tier, including the rare `--full-catalog`
427
+ * opt-in, while the in-app agent still calls it normally. Use it for
428
+ * actions that only make sense with an in-app screen, a live session, or
429
+ * the framework's own UI on the other end.
430
+ * - `true` — the action-owned form of `mcp.connectorCatalog` membership:
431
+ * this action is served on the curated external catalog. Declaring it on
432
+ * any action activates the connector tier for the app, which is what lets
433
+ * a template delete its hand-maintained `connectorCatalog` name list.
434
+ * Paired with `agentTool: false` it makes the action MCP-only — external
435
+ * agents get it, the app's own agent does not.
436
+ * - `undefined` (default) — follows `agentTool`; the tier rules then decide
437
+ * whether it is advertised up front or found through `tool-search`.
438
+ *
439
+ * Membership is not permission: an external caller still passes the OAuth
440
+ * scope, `externalAgents` policy, and `publicAgent` checks. Resolved by
441
+ * `isActionExposedToExternalAgents` below, which every external surface
442
+ * reads instead of testing these two fields itself. */
443
+ mcpTool?: boolean;
444
+ /** Whether this action's schema is held back from the agent's FIRST-REQUEST
445
+ * tool list and loaded on demand through `tool-search` instead. The
446
+ * action-owned form of the plugin's `initialToolNames` array, so the app's
447
+ * starter surface is declared beside each action rather than in a list that
448
+ * drifts as actions are renamed.
449
+ *
450
+ * - `false` — always in the initial set. As soon as ANY action declares
451
+ * this, the derived default flips from "every one of the app's own
452
+ * actions" to "the ones that opted in", which is what makes deleting
453
+ * `initialToolNames` a real trim rather than a rename.
454
+ * - `true` — never in the DERIVED set. An explicit `initialToolNames` entry
455
+ * still wins, so a stale list is never silently overridden.
456
+ * - `undefined` (default) — unchanged behavior.
457
+ *
458
+ * This is about first-turn context cost, not access: a deferred action is
459
+ * still callable the moment `tool-search` returns it. */
460
+ deferLoading?: boolean;
418
461
  /** If true, the framework will NOT emit a screen-refresh change event after a
419
462
  * successful call. Auto-inferred as `true` when `http.method === "GET"`.
420
463
  * Only set this manually when you need to override the inference — e.g. a
@@ -566,6 +609,15 @@ interface DefineActionWithParams<TParams extends Record<string, ParameterSchema>
566
609
  * explicit `false` hides it from every agent tool list while keeping it
567
610
  * frontend/HTTP-callable. See the schema overload above and actions.md. */
568
611
  agentTool?: boolean;
612
+ /** Whether this action is exposed to external agents over MCP / direct A2A.
613
+ * Defaults to `agentTool`. `false` is a hard veto on every MCP tier; `true`
614
+ * declares curated connector-catalog membership, and with `agentTool:
615
+ * false` makes the action MCP-only. See the schema overload above. */
616
+ mcpTool?: boolean;
617
+ /** Whether this action's schema is held back from the agent's first-request
618
+ * tool list and loaded through `tool-search` instead. The action-owned form
619
+ * of the plugin's `initialToolNames`. See the schema overload above. */
620
+ deferLoading?: boolean;
569
621
  /** If true, the framework will NOT emit a screen-refresh change event after a
570
622
  * successful call. Auto-inferred as `true` when `http.method === "GET"`. */
571
623
  readOnly?: boolean;
@@ -635,6 +687,8 @@ export interface ActionDefinition<TInput, TReturn> {
635
687
  readonly requiresAuth?: boolean;
636
688
  readonly maxBodyBytes?: number;
637
689
  readonly agentTool?: boolean;
690
+ readonly mcpTool?: boolean;
691
+ readonly deferLoading?: boolean;
638
692
  readonly readOnly?: boolean;
639
693
  readonly grounding?: boolean;
640
694
  readonly allowInPlanMode?: boolean;
@@ -706,6 +760,43 @@ export interface ActionDefinition<TInput, TReturn> {
706
760
  */
707
761
  export declare function defineAction<TSchema extends StandardSchemaV1, TReturn, TOutputSchema extends StandardSchemaV1 | undefined = undefined>(options: DefineActionWithSchema<TSchema, TReturn, TOutputSchema>): ActionDefinition<StandardSchemaV1.InferInput<TSchema>, TReturn>;
708
762
  export declare function defineAction<TParams extends Record<string, ParameterSchema> | undefined, TReturn>(options: DefineActionWithParams<TParams, TReturn>): ActionDefinition<InferParams<TParams>, TReturn>;
763
+ /**
764
+ * Whether an action is exposed to EXTERNAL agents — MCP and the direct A2A
765
+ * action surface. The one resolver every surface asks; nothing downstream
766
+ * re-derives this from the two raw fields.
767
+ *
768
+ * `mcpTool` DEFAULTS TO `agentTool` rather than to a flat `true`, so hiding an
769
+ * action from the agent hides it from outside agents too and one flag stays
770
+ * one decision. Declaring `mcpTool` overrides that inheritance in both
771
+ * directions:
772
+ *
773
+ * agentTool: false → hidden from every agent surface
774
+ * agentTool: false, mcpTool: true → MCP-only: external agents get it, the
775
+ * app's own agent does not
776
+ * mcpTool: false → in-app only, whatever `agentTool` says
777
+ *
778
+ * The MCP-only combination needs the plugin to route those actions around the
779
+ * `filterAgentTools` gate — see `mcpOnlyActions` in `agent-chat-plugin.ts`.
780
+ */
781
+ export declare function isActionExposedToExternalAgents(entry: {
782
+ agentTool?: boolean;
783
+ mcpTool?: boolean;
784
+ }): boolean;
785
+ /**
786
+ * Whether an action is hidden from EVERY agent surface — the in-app agent and
787
+ * external agents alike.
788
+ *
789
+ * The runtime backstops (`executeAgentToolCall`, `searchToolRegistry`) use
790
+ * this rather than `agentTool === false`: each caller already passes a
791
+ * surface-scoped registry, so the backstop's job is to catch an entry that no
792
+ * surface should ever run, not to re-litigate which surface this is. Testing
793
+ * `agentTool` alone made those two refuse the MCP-only actions their own
794
+ * caller had deliberately handed them.
795
+ */
796
+ export declare function isActionHiddenFromEveryAgentSurface(entry: {
797
+ agentTool?: boolean;
798
+ mcpTool?: boolean;
799
+ }): boolean;
709
800
  export declare function stripUnsupportedSchemaKeywords<T>(node: T): T;
710
801
  /**
711
802
  * Compact signature of an action's parameters, e.g.
package/dist/action.js CHANGED
@@ -144,6 +144,17 @@ export function defineAction(options) {
144
144
  // agentTool: default-allow opt-out. Only an explicit `false` hides the action
145
145
  // from the agent tool surfaces; undefined is preserved (treated as exposed).
146
146
  const agentTool = typeof options.agentTool === "boolean" ? options.agentTool : undefined;
147
+ // mcpTool / deferLoading: like `agentTool`, `undefined` is a distinct third
148
+ // state and must survive to the entry. Both flags mean something different
149
+ // when declared than when omitted — an explicit `mcpTool: true` puts the
150
+ // action on the curated external catalog, and an explicit
151
+ // `deferLoading: false` narrows the derived first-request set — so
152
+ // collapsing undefined to the default here would erase the declaration the
153
+ // surfaces read.
154
+ const mcpTool = typeof options.mcpTool === "boolean" ? options.mcpTool : undefined;
155
+ const deferLoading = typeof options.deferLoading === "boolean"
156
+ ? options.deferLoading
157
+ : undefined;
147
158
  const parallelSafe = typeof options.parallelSafe === "boolean"
148
159
  ? options.parallelSafe
149
160
  : undefined;
@@ -190,6 +201,8 @@ export function defineAction(options) {
190
201
  ? { maxBodyBytes: options.maxBodyBytes }
191
202
  : {}),
192
203
  ...(typeof agentTool === "boolean" ? { agentTool } : {}),
204
+ ...(typeof mcpTool === "boolean" ? { mcpTool } : {}),
205
+ ...(typeof deferLoading === "boolean" ? { deferLoading } : {}),
193
206
  ...(typeof readOnly === "boolean" ? { readOnly } : {}),
194
207
  ...(typeof options.grounding === "boolean"
195
208
  ? { grounding: options.grounding }
@@ -235,6 +248,43 @@ export function defineAction(options) {
235
248
  ...(auditConfig ? { audit: auditConfig } : {}),
236
249
  };
237
250
  }
251
+ /**
252
+ * Whether an action is exposed to EXTERNAL agents — MCP and the direct A2A
253
+ * action surface. The one resolver every surface asks; nothing downstream
254
+ * re-derives this from the two raw fields.
255
+ *
256
+ * `mcpTool` DEFAULTS TO `agentTool` rather than to a flat `true`, so hiding an
257
+ * action from the agent hides it from outside agents too and one flag stays
258
+ * one decision. Declaring `mcpTool` overrides that inheritance in both
259
+ * directions:
260
+ *
261
+ * agentTool: false → hidden from every agent surface
262
+ * agentTool: false, mcpTool: true → MCP-only: external agents get it, the
263
+ * app's own agent does not
264
+ * mcpTool: false → in-app only, whatever `agentTool` says
265
+ *
266
+ * The MCP-only combination needs the plugin to route those actions around the
267
+ * `filterAgentTools` gate — see `mcpOnlyActions` in `agent-chat-plugin.ts`.
268
+ */
269
+ export function isActionExposedToExternalAgents(entry) {
270
+ return typeof entry.mcpTool === "boolean"
271
+ ? entry.mcpTool
272
+ : entry.agentTool !== false;
273
+ }
274
+ /**
275
+ * Whether an action is hidden from EVERY agent surface — the in-app agent and
276
+ * external agents alike.
277
+ *
278
+ * The runtime backstops (`executeAgentToolCall`, `searchToolRegistry`) use
279
+ * this rather than `agentTool === false`: each caller already passes a
280
+ * surface-scoped registry, so the backstop's job is to catch an entry that no
281
+ * surface should ever run, not to re-litigate which surface this is. Testing
282
+ * `agentTool` alone made those two refuse the MCP-only actions their own
283
+ * caller had deliberately handed them.
284
+ */
285
+ export function isActionHiddenFromEveryAgentSurface(entry) {
286
+ return entry.agentTool === false && entry.mcpTool !== true;
287
+ }
238
288
  /**
239
289
  * Wrap an action's run with its `authorize` gate.
240
290
  *
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Abort-reason vocabulary, kept in a leaf module on purpose.
3
+ *
4
+ * The abort route needs only these two symbols, but they used to live in
5
+ * `run-loop-with-resume.ts` — the whole agent execution loop. Importing them
6
+ * from there pulled that graph into the server plugin's static imports, so
7
+ * every cold serverless start evaluated the entire run loop (measured at
8
+ * ~1.6s) before it could render a page it would never run an agent for.
9
+ * Nothing here may import from the run loop, or that cost comes straight back.
10
+ */
11
+ /**
12
+ * Abort reasons the SERVER sets on a run's own controller. Everything else —
13
+ * including any reason a client passes to the abort route — is a user Stop.
14
+ *
15
+ * Kept deliberately short. Each entry is a bound this package owns and can name
16
+ * in a terminal outcome; if you are adding a fourth, check first whether the
17
+ * bound belongs in `run-manager.ts` at all.
18
+ *
19
+ * Exported so the abort route can refuse these words from a client. That check
20
+ * belongs at the boundary where untrusted input enters, not here: by the time a
21
+ * reason reaches an `AbortSignal` it is just a string, and nothing downstream
22
+ * can tell who wrote it.
23
+ */
24
+ export declare const SERVER_OWNED_ABORT_REASONS: Set<string>;
25
+ /**
26
+ * The abort reason to record for a client-initiated Stop.
27
+ *
28
+ * A caller reaching the abort route is a person pressing Stop, so it must not
29
+ * be able to name a bound only the server can reach: the terminal outcome keys
30
+ * off the abort reason, and a client sending `background_automation_hard_timeout`
31
+ * would file its own Stop as a server-side failure. Anything unrecognised,
32
+ * malformed, or reserved falls back to `"user"`.
33
+ *
34
+ * Normalised here rather than in the route because this is where the meaning of
35
+ * the string is decided — downstream it is just a string, and nothing can tell
36
+ * who wrote it.
37
+ */
38
+ export declare function clientAbortReason(raw: unknown): string;
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Abort-reason vocabulary, kept in a leaf module on purpose.
3
+ *
4
+ * The abort route needs only these two symbols, but they used to live in
5
+ * `run-loop-with-resume.ts` — the whole agent execution loop. Importing them
6
+ * from there pulled that graph into the server plugin's static imports, so
7
+ * every cold serverless start evaluated the entire run loop (measured at
8
+ * ~1.6s) before it could render a page it would never run an agent for.
9
+ * Nothing here may import from the run loop, or that cost comes straight back.
10
+ */
11
+ /**
12
+ * Abort reasons the SERVER sets on a run's own controller. Everything else —
13
+ * including any reason a client passes to the abort route — is a user Stop.
14
+ *
15
+ * Kept deliberately short. Each entry is a bound this package owns and can name
16
+ * in a terminal outcome; if you are adding a fourth, check first whether the
17
+ * bound belongs in `run-manager.ts` at all.
18
+ *
19
+ * Exported so the abort route can refuse these words from a client. That check
20
+ * belongs at the boundary where untrusted input enters, not here: by the time a
21
+ * reason reaches an `AbortSignal` it is just a string, and nothing downstream
22
+ * can tell who wrote it.
23
+ */
24
+ export const SERVER_OWNED_ABORT_REASONS = new Set([
25
+ "no_progress",
26
+ "run_timeout",
27
+ "background_automation_hard_timeout",
28
+ ]);
29
+ /**
30
+ * The abort reason to record for a client-initiated Stop.
31
+ *
32
+ * A caller reaching the abort route is a person pressing Stop, so it must not
33
+ * be able to name a bound only the server can reach: the terminal outcome keys
34
+ * off the abort reason, and a client sending `background_automation_hard_timeout`
35
+ * would file its own Stop as a server-side failure. Anything unrecognised,
36
+ * malformed, or reserved falls back to `"user"`.
37
+ *
38
+ * Normalised here rather than in the route because this is where the meaning of
39
+ * the string is decided — downstream it is just a string, and nothing can tell
40
+ * who wrote it.
41
+ */
42
+ export function clientAbortReason(raw) {
43
+ if (typeof raw !== "string")
44
+ return "user";
45
+ const reason = raw.trim();
46
+ if (!/^[a-z0-9_-]{1,64}$/i.test(reason))
47
+ return "user";
48
+ return SERVER_OWNED_ABORT_REASONS.has(reason.toLowerCase()) ? "user" : reason;
49
+ }
@@ -16,7 +16,7 @@ import { allowsSamplingParams, anthropicManualThinkingBudget, normalizeReasoning
16
16
  import { AI_SDK_MODEL_CONFIG } from "../model-config.js";
17
17
  import { LLM_MISSING_CREDENTIALS_ERROR_CODE, LLM_MISSING_CREDENTIALS_MESSAGE, } from "./credential-errors.js";
18
18
  import { classifyProviderError, describeErrorWithCauses, } from "./error-detail.js";
19
- import { createFirstEventAbortController, FIRST_STREAM_EVENT_TIMEOUT_MS, } from "./first-event-timeout.js";
19
+ import { createFirstEventAbortController } from "./first-event-timeout.js";
20
20
  import { clampThinkingBudgetTokens, resolveMaxOutputTokensForEngine, } from "./output-tokens.js";
21
21
  import { engineToolsToAISDK, engineMessagesToAISDK, aiSdkPartToEngineEvents, aiSdkStepToAssistantContent, } from "./translate-ai-sdk.js";
22
22
  import { createStreamedToolInputState, finalizeStreamedToolInputs, observeStreamedToolInput, } from "./translate-anthropic.js";
@@ -425,10 +425,13 @@ class AISDKEngine {
425
425
  }
426
426
  }
427
427
  // AI SDK surfaces an aborted stream as a graceful `{type: "abort"}`
428
- // part rather than a thrown error, so a first-event timeout would
429
- // otherwise fall through to the normal end_turn completion below.
430
- if (!sawFirstEvent && firstEventAbort.didTimeout()) {
431
- throw new Error(`Model request produced no stream events within ${FIRST_STREAM_EVENT_TIMEOUT_MS / 1000}s; the connection appears wedged.`);
428
+ // part rather than a thrown error, so a deadline abort would otherwise
429
+ // fall through to the normal end_turn completion below. Not gated on
430
+ // `sawFirstEvent`: the total deadline fires mid-stream by definition, and
431
+ // reporting that half-delivered turn as a clean end_turn is exactly the
432
+ // truncated-run-reported-as-complete failure.
433
+ if (firstEventAbort.didTimeout()) {
434
+ throw new Error(`${firstEventAbort.timeoutMessage()}; the connection appears wedged.`);
432
435
  }
433
436
  // A step can finish having announced a tool call it never delivered.
434
437
  // Assemble it from its deltas, or report it in-band, rather than ending
@@ -12,7 +12,7 @@ import { allowsSamplingParams, anthropicManualThinkingBudget, normalizeReasoning
12
12
  import { ANTHROPIC_MODEL_CONFIG } from "../model-config.js";
13
13
  import { LLM_MISSING_CREDENTIALS_ERROR_CODE, LLM_MISSING_CREDENTIALS_MESSAGE, } from "./credential-errors.js";
14
14
  import { describeErrorWithCauses } from "./error-detail.js";
15
- import { createFirstEventAbortController, FIRST_STREAM_EVENT_TIMEOUT_MS, } from "./first-event-timeout.js";
15
+ import { createFirstEventAbortController } from "./first-event-timeout.js";
16
16
  import { clampThinkingBudgetTokens, resolveMaxOutputTokensForEngine, } from "./output-tokens.js";
17
17
  import { splitSystemPromptForCache, stablePrefixCacheControl, } from "./prompt-cache.js";
18
18
  import { engineToolsToAnthropic, engineMessagesToAnthropic, anthropicContentToEngine, anthropicChunkToEngineEvents, createAnthropicChunkStreamState, createStreamedToolInputState, finalizeStreamedToolInputs, observeStreamedToolInput, } from "./translate-anthropic.js";
@@ -233,12 +233,14 @@ class AnthropicEngine {
233
233
  : typeof err?.statusCode === "number"
234
234
  ? err.statusCode
235
235
  : undefined;
236
- // A first-event abort surfaces from the SDK as a generic
237
- // APIUserAbortError ("Request was aborted.") — replace it with a
238
- // message that actually explains what happened.
236
+ // A deadline abort surfaces from the SDK as a generic APIUserAbortError
237
+ // ("Request was aborted.") — replace it with a message that actually
238
+ // explains what happened. Which deadline fired comes from the
239
+ // controller: a total-deadline abort is a socket that wedged MID-stream,
240
+ // not a connection that never spoke.
239
241
  const rawMessage = err?.message ?? String(err);
240
242
  const errorMessage = timedOut
241
- ? `Model request produced no stream events within ${FIRST_STREAM_EVENT_TIMEOUT_MS / 1000}s; the connection appears wedged.`
243
+ ? `${firstEventAbort.timeoutMessage()}; the connection appears wedged.`
242
244
  : describeErrorWithCauses(err);
243
245
  // Anthropic SDK APIConnectionError defaults to "Connection error." with
244
246
  // no HTTP status. Tag it so in-run retries and run-level resume treat
@@ -1,32 +1,57 @@
1
1
  /**
2
- * Shared "first stream event" deadline for model-request engines.
2
+ * Shared stream deadlines for model-request engines.
3
3
  *
4
- * A request that connects successfully but then streams zero events means the
5
- * transport or gateway is wedged, not slow — real models (including deep
6
- * thinking ones) emit their first event within seconds. Bounding this window
7
- * separately from any total-request deadline turns a silent multi-minute hang
8
- * into a fast abort-and-retry.
4
+ * Two bounds, both keyed off facts the transport can actually establish:
9
5
  *
10
- * AUDIENCE: direct `engine.stream()` callers — `completeText`, voice
11
- * transcription, sentiment, evals, observational memory. It is EXPECTED to be
12
- * shadowed inside `runAgentLoop`, whose own `MODEL_STREAM_NO_PROGRESS_TIMEOUT_MS`
13
- * (90s) races the same first frame and always wins. That does not make it
14
- * redundant: `completeText` takes `timeoutMs` as optional, so a caller that
15
- * omits one has no other bound between it and an unbounded hang. Do not
16
- * "clean it up" as unreachable — check the non-loop callers first.
6
+ * - FIRST: a request that connects and then streams zero events means the
7
+ * transport or gateway is wedged, not slow — real models (including deep
8
+ * thinking ones) emit their first event within seconds.
9
+ * - TOTAL: the whole request, first event or not, cannot outlive the largest
10
+ * budget any caller runs inside.
11
+ *
12
+ * AUDIENCE: every `engine.stream()` caller, `runAgentLoop` INCLUDED. The first
13
+ * bound used to be described as shadowed inside the loop by a 90s in-loop
14
+ * watchdog that "always wins"; that watchdog is gone (see
15
+ * run-lifecycle-invariants.ts), so these are now the PRIMARY bounds on a model
16
+ * call that wedges. They survive that deletion because neither infers death
17
+ * from the ABSENCE of a particular event mid-generation — the fact the removed
18
+ * watchdogs got wrong, since the Anthropic SDK drops the provider's `ping`
19
+ * keepalives before any consumer sees them. Do not "clean them up" as
20
+ * redundant, and do not add a no-progress bound back beside them.
17
21
  */
18
22
  export declare const FIRST_STREAM_EVENT_TIMEOUT_MS = 120000;
23
+ /**
24
+ * Ceiling on one model call end to end, measured from request start.
25
+ *
26
+ * Sized so it can never preempt healthy work: the largest chunk any caller runs
27
+ * inside is the ~13-minute background soft timeout, and a hosted run is bounded
28
+ * by its own chunk long before this. It exists for the runtimes that have no
29
+ * outer budget at all — local dev and self-hosted resolve the soft timeout to
30
+ * `0`, so without this a socket that wedges AFTER the first frame leaves the
31
+ * run pending forever. Mirrors the ceiling builder-engine already applies to
32
+ * its own gateway requests, for the engines that talk to a provider directly.
33
+ */
34
+ export declare const STREAM_TOTAL_TIMEOUT_MS: number;
19
35
  export interface FirstEventAbortController {
20
36
  readonly signal: AbortSignal;
21
37
  /** Idempotent. Call once the first real (non-keepalive) stream event arrives. */
22
38
  markFirstEvent: () => void;
23
39
  didTimeout: () => boolean;
40
+ /**
41
+ * Which deadline fired, phrased for the user, or `undefined` if none did.
42
+ * Callers must not assume a timeout is the first-event one — after
43
+ * `markFirstEvent()` a timeout means the total deadline, and reporting the
44
+ * wrong one describes a wedged mid-stream socket as a connection that never
45
+ * spoke.
46
+ */
47
+ timeoutMessage: () => string | undefined;
24
48
  cleanup: () => void;
25
49
  }
26
50
  /**
27
- * Layer a first-event deadline on top of a caller's AbortSignal. Aborts if
28
- * `markFirstEvent()` is not called within `FIRST_STREAM_EVENT_TIMEOUT_MS`.
29
- * Has no opinion on a total-request deadline — callers that need one (e.g.
30
- * builder-engine's flat gateway timeout) compose their own on top.
51
+ * Layer the two deadlines above on top of a caller's AbortSignal. Aborts if
52
+ * `markFirstEvent()` is not called within `FIRST_STREAM_EVENT_TIMEOUT_MS`, and
53
+ * again if the whole request outlives `STREAM_TOTAL_TIMEOUT_MS`. Callers that
54
+ * need a TIGHTER total deadline (e.g. builder-engine's flat gateway timeout)
55
+ * compose their own on top.
31
56
  */
32
57
  export declare function createFirstEventAbortController(parentSignal: AbortSignal): FirstEventAbortController;
@@ -1,40 +1,74 @@
1
1
  /**
2
- * Shared "first stream event" deadline for model-request engines.
2
+ * Shared stream deadlines for model-request engines.
3
3
  *
4
- * A request that connects successfully but then streams zero events means the
5
- * transport or gateway is wedged, not slow — real models (including deep
6
- * thinking ones) emit their first event within seconds. Bounding this window
7
- * separately from any total-request deadline turns a silent multi-minute hang
8
- * into a fast abort-and-retry.
4
+ * Two bounds, both keyed off facts the transport can actually establish:
9
5
  *
10
- * AUDIENCE: direct `engine.stream()` callers — `completeText`, voice
11
- * transcription, sentiment, evals, observational memory. It is EXPECTED to be
12
- * shadowed inside `runAgentLoop`, whose own `MODEL_STREAM_NO_PROGRESS_TIMEOUT_MS`
13
- * (90s) races the same first frame and always wins. That does not make it
14
- * redundant: `completeText` takes `timeoutMs` as optional, so a caller that
15
- * omits one has no other bound between it and an unbounded hang. Do not
16
- * "clean it up" as unreachable — check the non-loop callers first.
6
+ * - FIRST: a request that connects and then streams zero events means the
7
+ * transport or gateway is wedged, not slow — real models (including deep
8
+ * thinking ones) emit their first event within seconds.
9
+ * - TOTAL: the whole request, first event or not, cannot outlive the largest
10
+ * budget any caller runs inside.
11
+ *
12
+ * AUDIENCE: every `engine.stream()` caller, `runAgentLoop` INCLUDED. The first
13
+ * bound used to be described as shadowed inside the loop by a 90s in-loop
14
+ * watchdog that "always wins"; that watchdog is gone (see
15
+ * run-lifecycle-invariants.ts), so these are now the PRIMARY bounds on a model
16
+ * call that wedges. They survive that deletion because neither infers death
17
+ * from the ABSENCE of a particular event mid-generation — the fact the removed
18
+ * watchdogs got wrong, since the Anthropic SDK drops the provider's `ping`
19
+ * keepalives before any consumer sees them. Do not "clean them up" as
20
+ * redundant, and do not add a no-progress bound back beside them.
17
21
  */
18
22
  export const FIRST_STREAM_EVENT_TIMEOUT_MS = 120_000;
19
23
  /**
20
- * Layer a first-event deadline on top of a caller's AbortSignal. Aborts if
21
- * `markFirstEvent()` is not called within `FIRST_STREAM_EVENT_TIMEOUT_MS`.
22
- * Has no opinion on a total-request deadline — callers that need one (e.g.
23
- * builder-engine's flat gateway timeout) compose their own on top.
24
+ * Ceiling on one model call end to end, measured from request start.
25
+ *
26
+ * Sized so it can never preempt healthy work: the largest chunk any caller runs
27
+ * inside is the ~13-minute background soft timeout, and a hosted run is bounded
28
+ * by its own chunk long before this. It exists for the runtimes that have no
29
+ * outer budget at all — local dev and self-hosted resolve the soft timeout to
30
+ * `0`, so without this a socket that wedges AFTER the first frame leaves the
31
+ * run pending forever. Mirrors the ceiling builder-engine already applies to
32
+ * its own gateway requests, for the engines that talk to a provider directly.
33
+ */
34
+ export const STREAM_TOTAL_TIMEOUT_MS = 14 * 60_000;
35
+ /**
36
+ * Layer the two deadlines above on top of a caller's AbortSignal. Aborts if
37
+ * `markFirstEvent()` is not called within `FIRST_STREAM_EVENT_TIMEOUT_MS`, and
38
+ * again if the whole request outlives `STREAM_TOTAL_TIMEOUT_MS`. Callers that
39
+ * need a TIGHTER total deadline (e.g. builder-engine's flat gateway timeout)
40
+ * compose their own on top.
24
41
  */
25
42
  export function createFirstEventAbortController(parentSignal) {
26
43
  const controller = new AbortController();
27
- let timedOut = false;
44
+ const startedAt = Date.now();
45
+ let timeoutMessage;
28
46
  let firstEventSeen = false;
29
47
  const abortFromParent = () => {
48
+ // Drop the outstanding deadline too. A parent abort ends this request, and
49
+ // the provider can take a moment to settle afterwards — a timer still
50
+ // armed through that window fires into an already-cancelled request and
51
+ // relabels a user Stop or a run-budget abort as a retryable provider
52
+ // failure. That window used to be small because the first frame cleared
53
+ // the timer outright; now that a deadline runs for the whole stream, it is
54
+ // the whole stream.
55
+ clearTimeout(timeout);
30
56
  if (!controller.signal.aborted)
31
57
  controller.abort(parentSignal.reason);
32
58
  };
33
- const timeout = setTimeout(() => {
34
- timedOut = true;
35
- if (!controller.signal.aborted) {
36
- controller.abort(new Error(`Model request produced no stream events within ${FIRST_STREAM_EVENT_TIMEOUT_MS / 1000}s`));
37
- }
59
+ const fireTimeout = (message) => {
60
+ // Record a timeout ONLY when this controller wins the abort race. Setting
61
+ // the message first and checking `aborted` after made a deadline that
62
+ // merely fired into an already-aborted controller indistinguishable from
63
+ // one that caused the abort — and `didTimeout()` is what the engines read
64
+ // to decide a failure was the transport's fault and worth retrying.
65
+ if (controller.signal.aborted)
66
+ return;
67
+ timeoutMessage = message;
68
+ controller.abort(new Error(message));
69
+ };
70
+ let timeout = setTimeout(() => {
71
+ fireTimeout(`Model request produced no stream events within ${FIRST_STREAM_EVENT_TIMEOUT_MS / 1000}s`);
38
72
  }, FIRST_STREAM_EVENT_TIMEOUT_MS);
39
73
  if (parentSignal.aborted)
40
74
  abortFromParent();
@@ -42,12 +76,20 @@ export function createFirstEventAbortController(parentSignal) {
42
76
  return {
43
77
  signal: controller.signal,
44
78
  markFirstEvent: () => {
45
- if (firstEventSeen)
79
+ // `aborted` subsumes the timeout check — `fireTimeout` only records a
80
+ // message when it aborts — and also covers the parent-abort case, so a
81
+ // frame processed after a Stop cannot re-arm a deadline on a dead
82
+ // request.
83
+ if (firstEventSeen || controller.signal.aborted)
46
84
  return;
47
85
  firstEventSeen = true;
48
86
  clearTimeout(timeout);
87
+ timeout = setTimeout(() => {
88
+ fireTimeout(`Model request exceeded the ${STREAM_TOTAL_TIMEOUT_MS / 60_000}-minute total stream deadline`);
89
+ }, Math.max(0, STREAM_TOTAL_TIMEOUT_MS - (Date.now() - startedAt)));
49
90
  },
50
- didTimeout: () => timedOut,
91
+ didTimeout: () => timeoutMessage !== undefined,
92
+ timeoutMessage: () => timeoutMessage,
51
93
  cleanup: () => {
52
94
  clearTimeout(timeout);
53
95
  parentSignal.removeEventListener("abort", abortFromParent);
@@ -178,6 +178,21 @@ export interface ActionEntry {
178
178
  * MCP, A2A, job/trigger runners) while leaving it frontend/HTTP-callable.
179
179
  * Set by `defineAction`'s `agentTool` option. */
180
180
  agentTool?: boolean;
181
+ /** Whether the action is exposed to EXTERNAL agents over MCP and the direct
182
+ * A2A action surface. Defaults to `agentTool`. `false` is a hard veto on
183
+ * every MCP tier (including the `--full-catalog` opt-in) while the in-app
184
+ * agent keeps calling it; `true` declares curated connector-catalog
185
+ * membership, and with `agentTool: false` makes the action MCP-only. Read
186
+ * it through `isActionExposedToExternalAgents`, never as a raw field.
187
+ * Set by `defineAction`'s `mcpTool` option. */
188
+ mcpTool?: boolean;
189
+ /** Whether the action's schema is held back from the agent's first-request
190
+ * tool list — the action-owned form of the plugin's `initialToolNames`.
191
+ * `false` always includes it (and narrows the derived default to the
192
+ * actions that opted in); `true` keeps it out of the DERIVED set, reachable
193
+ * through `tool-search`. Context cost, not access. Set by `defineAction`'s
194
+ * `deferLoading` option. */
195
+ deferLoading?: boolean;
181
196
  /** Explicit opt-in metadata for public agent protocols. Public routes never
182
197
  * imply public tool exposure; MCP/A2A/OpenAPI surfaces must filter for this. */
183
198
  publicAgent?: import("../action.js").PublicAgentActionConfig;
@@ -872,6 +887,14 @@ export declare function runAgentLoop(opts: {
872
887
  * App-level default limits applied to every tool call unless the individual
873
888
  * ActionEntry overrides them with its own timeoutMs / maxResultChars.
874
889
  */
890
+ /**
891
+ * The chunk's REAL soft-timeout budget, when the caller has one.
892
+ *
893
+ * Only `runToolTimeoutCeilingMs` reads it, and only so a per-tool timeout
894
+ * stays under the budget it actually runs inside. Absent, the generic hosted
895
+ * ceiling is used — right for callers that have no chunk of their own.
896
+ */
897
+ runSoftTimeoutMs?: number;
875
898
  toolLimits?: {
876
899
  timeoutMs?: number;
877
900
  maxResultChars?: number;