@agent-native/core 0.141.7 → 0.144.1

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 (371) hide show
  1. package/agent-native.eject.json +9 -0
  2. package/corpus/README.md +1 -1
  3. package/corpus/templates/analytics/.agents/skills/provider-api/SKILL.md +19 -0
  4. package/corpus/templates/analytics/.agents/skills/turn-into-app/SKILL.md +296 -0
  5. package/corpus/templates/analytics/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  6. package/corpus/templates/analytics/.agents/skills/turn-into-skill/SKILL.md +112 -0
  7. package/corpus/templates/analytics/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  8. package/corpus/templates/analytics/AGENTS.md +35 -38
  9. package/corpus/templates/analytics/actions/ensure-native-v2-dashboards.ts +1 -1
  10. package/corpus/templates/analytics/actions/list-dashboard-usage-stats.ts +17 -22
  11. package/corpus/templates/analytics/actions/migrate-first-party-analytics-to-bigquery.ts +1 -1
  12. package/corpus/templates/analytics/actions/navigate.ts +4 -5
  13. package/corpus/templates/analytics/actions/provider-api-register.ts +50 -0
  14. package/corpus/templates/analytics/actions/query-agent-native-analytics.ts +44 -11
  15. package/corpus/templates/analytics/actions/test-custom-api-connection.ts +106 -0
  16. package/corpus/templates/analytics/app/components/CustomApiCard.tsx +430 -0
  17. package/corpus/templates/analytics/app/i18n-data.ts +680 -0
  18. package/corpus/templates/analytics/app/lib/native-mcp-exclusions.ts +6 -0
  19. package/corpus/templates/analytics/app/lib/sql-query.ts +33 -6
  20. package/corpus/templates/analytics/app/pages/DataSources.tsx +4 -0
  21. package/corpus/templates/analytics/changelog/2026-08-06-analytics-dashboards-load-reliably-during-background-data-sw.md +6 -0
  22. package/corpus/templates/analytics/changelog/2026-08-06-analytics-dashboards-remain-responsive-while-historical-data.md +6 -0
  23. package/corpus/templates/analytics/changelog/2026-08-06-analytics-query-results-now-render-as-a-table-with-csv-downl.md +6 -0
  24. package/corpus/templates/analytics/changelog/2026-08-06-connect-public-https-custom-apis-and-hand-tested-endpoints-t.md +6 -0
  25. package/corpus/templates/analytics/changelog/2026-08-06-durable-agent-worker-memory.md +6 -0
  26. package/corpus/templates/analytics/changelog/2026-08-06-live-dashboard-panels-use-the-shared-query-timeout.md +6 -0
  27. package/corpus/templates/analytics/changelog/2026-08-06-on-demand-billing-is-available-as-a-native-dashboard-with-ta.md +6 -0
  28. package/corpus/templates/analytics/changelog/2026-08-06-visible-dashboard-names-are-unique.md +6 -0
  29. package/corpus/templates/analytics/netlify.toml +7 -0
  30. package/corpus/templates/analytics/scripts/emit-netlify-dashboard-report-cron.ts +4 -0
  31. package/corpus/templates/analytics/server/db/index.ts +27 -0
  32. package/corpus/templates/analytics/server/db/schema.ts +10 -0
  33. package/corpus/templates/analytics/server/lib/dashboards-store.ts +227 -60
  34. package/corpus/templates/analytics/server/lib/first-party-analytics-backend.ts +156 -45
  35. package/corpus/templates/analytics/server/lib/native-v2-dashboards.ts +227 -1
  36. package/corpus/templates/analytics/server/plugins/agent-chat.ts +5 -0
  37. package/corpus/templates/analytics/server/plugins/analytics-rollup-backfill-jobs.ts +1 -0
  38. package/corpus/templates/analytics/server/plugins/db.ts +52 -18
  39. package/corpus/templates/assets/.agents/skills/asset-generation/SKILL.md +28 -2
  40. package/corpus/templates/assets/.agents/skills/image-generation/SKILL.md +16 -1
  41. package/corpus/templates/assets/.agents/skills/turn-into-app/SKILL.md +296 -0
  42. package/corpus/templates/assets/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  43. package/corpus/templates/assets/.agents/skills/turn-into-skill/SKILL.md +112 -0
  44. package/corpus/templates/assets/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  45. package/corpus/templates/brain/.agents/skills/turn-into-app/SKILL.md +296 -0
  46. package/corpus/templates/brain/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  47. package/corpus/templates/brain/.agents/skills/turn-into-skill/SKILL.md +112 -0
  48. package/corpus/templates/brain/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  49. package/corpus/templates/brain/actions/list-connection-providers.ts +24 -3
  50. package/corpus/templates/brain/app/lib/dispatch-links.ts +44 -0
  51. package/corpus/templates/brain/app/routes/sources.tsx +15 -7
  52. package/corpus/templates/brain/changelog/2026-08-06-brain-provider-setup-links-open-dispatch-correctly-in-standa.md +6 -0
  53. package/corpus/templates/brain/server/plugins/agent-chat.ts +1 -0
  54. package/corpus/templates/calendar/.agents/skills/event-management/SKILL.md +26 -0
  55. package/corpus/templates/calendar/.agents/skills/turn-into-app/SKILL.md +296 -0
  56. package/corpus/templates/calendar/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  57. package/corpus/templates/calendar/.agents/skills/turn-into-skill/SKILL.md +112 -0
  58. package/corpus/templates/calendar/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  59. package/corpus/templates/calendar/AGENTS.md +11 -32
  60. package/corpus/templates/calendar/actions/update-event.ts +107 -1
  61. package/corpus/templates/calendar/app/components/calendar/EventCalendarSelect.tsx +83 -0
  62. package/corpus/templates/calendar/app/components/calendar/EventDetailPanel.tsx +57 -0
  63. package/corpus/templates/calendar/app/components/calendar/EventDetailPopover.tsx +59 -73
  64. package/corpus/templates/calendar/app/hooks/use-events.ts +4 -1
  65. package/corpus/templates/calendar/app/i18n-data.ts +20 -0
  66. package/corpus/templates/calendar/changelog/2026-08-06-delegated-requests-continue-in-the-background.md +6 -0
  67. package/corpus/templates/calendar/changelog/2026-08-06-existing-events-can-move-between-connected-google-account-ca.md +6 -0
  68. package/corpus/templates/calendar/server/lib/google-calendar.ts +101 -0
  69. package/corpus/templates/calendar/server/plugins/agent-chat.ts +7 -1
  70. package/corpus/templates/chat/.agents/skills/turn-into-app/SKILL.md +296 -0
  71. package/corpus/templates/chat/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  72. package/corpus/templates/chat/.agents/skills/turn-into-skill/SKILL.md +112 -0
  73. package/corpus/templates/chat/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  74. package/corpus/templates/clips/.agents/skills/turn-into-app/SKILL.md +296 -0
  75. package/corpus/templates/clips/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  76. package/corpus/templates/clips/.agents/skills/turn-into-skill/SKILL.md +112 -0
  77. package/corpus/templates/clips/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  78. package/corpus/templates/clips/app/components/editor/editor-layout.tsx +9 -24
  79. package/corpus/templates/clips/app/components/editor/timeline-geometry.ts +15 -0
  80. package/corpus/templates/clips/app/components/editor/waveform.tsx +4 -17
  81. package/corpus/templates/clips/app/components/player/delete-recording-menu.tsx +14 -3
  82. package/corpus/templates/clips/app/components/player/player-controls.tsx +0 -3
  83. package/corpus/templates/clips/app/components/player/scrubber.tsx +2 -33
  84. package/corpus/templates/clips/app/components/player/video-player.tsx +58 -11
  85. package/corpus/templates/clips/app/routes/r.$recordingId.tsx +28 -38
  86. package/corpus/templates/clips/app/routes/share.$shareId.tsx +21 -27
  87. package/corpus/templates/clips/changelog/2026-08-06-clips-recovers-from-stalled-recording-setup-without-requirin.md +6 -0
  88. package/corpus/templates/clips/changelog/2026-08-06-clips-starts-faster-after-a-deploy-or-idle-period-startup-no.md +6 -0
  89. package/corpus/templates/clips/changelog/2026-08-06-deleting-a-recording-returns-cleanly-to-the-library-and-fit-.md +6 -0
  90. package/corpus/templates/clips/changelog/2026-08-06-hide-clip-insights-from-viewers-without-analytics-access.md +6 -0
  91. package/corpus/templates/clips/changelog/2026-08-06-trimmed-clips-play-on-a-clean-timeline-without-cut-markers.md +6 -0
  92. package/corpus/templates/clips/desktop/src/app.tsx +48 -20
  93. package/corpus/templates/clips/desktop/src/lib/recorder.ts +275 -74
  94. package/corpus/templates/clips/desktop/src/lib/recording-start-guard.ts +84 -0
  95. package/corpus/templates/clips/desktop/src/overlays/toolbar.tsx +14 -4
  96. package/corpus/templates/clips/server/plugins/db.ts +214 -26
  97. package/corpus/templates/content/.agents/skills/turn-into-app/SKILL.md +296 -0
  98. package/corpus/templates/content/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  99. package/corpus/templates/content/.agents/skills/turn-into-skill/SKILL.md +112 -0
  100. package/corpus/templates/content/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  101. package/corpus/templates/crm/.agents/skills/turn-into-app/SKILL.md +296 -0
  102. package/corpus/templates/crm/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  103. package/corpus/templates/crm/.agents/skills/turn-into-skill/SKILL.md +112 -0
  104. package/corpus/templates/crm/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  105. package/corpus/templates/crm/changelog/2026-08-06-crm-starts-faster-after-a-deploy-or-idle-period-one-time-dat.md +6 -0
  106. package/corpus/templates/crm/server/plugins/db.ts +11 -8
  107. package/corpus/templates/design/.agents/skills/design-generation/SKILL.md +36 -1
  108. package/corpus/templates/design/.agents/skills/turn-into-app/SKILL.md +296 -0
  109. package/corpus/templates/design/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  110. package/corpus/templates/design/.agents/skills/turn-into-skill/SKILL.md +112 -0
  111. package/corpus/templates/design/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  112. package/corpus/templates/design/actions/import-from-url.ts +1 -1
  113. package/corpus/templates/design/app/components/design/LayersPanel.tsx +27 -18
  114. package/corpus/templates/design/app/pages/Index.tsx +6 -2
  115. package/corpus/templates/design/changelog/2026-08-05-deleting-a-design-from-the-home-page-no-longer-leaves-the-ap.md +6 -0
  116. package/corpus/templates/design/changelog/2026-08-05-renaming-a-layer-now-focuses-its-name-field-automatically.md +6 -0
  117. package/corpus/templates/design/server/plugins/agent-chat.ts +2 -0
  118. package/corpus/templates/dispatch/.agents/skills/turn-into-app/SKILL.md +296 -0
  119. package/corpus/templates/dispatch/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  120. package/corpus/templates/dispatch/.agents/skills/turn-into-skill/SKILL.md +112 -0
  121. package/corpus/templates/dispatch/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  122. package/corpus/templates/dispatch/AGENTS.md +8 -1
  123. package/corpus/templates/dispatch/app/dispatch-extensions.tsx +1 -0
  124. package/corpus/templates/dispatch/app/hooks/use-navigation-state.ts +30 -15
  125. package/corpus/templates/dispatch/app/i18n-data.ts +131 -0
  126. package/corpus/templates/dispatch/app/routes/admin._index.tsx +4 -0
  127. package/corpus/templates/dispatch/app/routes/admin.agents.tsx +1 -0
  128. package/corpus/templates/dispatch/app/routes/admin.approvals.tsx +1 -0
  129. package/corpus/templates/dispatch/app/routes/admin.apps.$appId.tsx +1 -0
  130. package/corpus/templates/dispatch/app/routes/admin.apps.tsx +1 -0
  131. package/corpus/templates/dispatch/app/routes/admin.audit.tsx +1 -0
  132. package/corpus/templates/dispatch/app/routes/admin.automations.tsx +1 -0
  133. package/corpus/templates/dispatch/app/routes/admin.destinations.tsx +4 -0
  134. package/corpus/templates/dispatch/app/routes/admin.dreams.tsx +1 -0
  135. package/corpus/templates/dispatch/app/routes/admin.identities.tsx +1 -0
  136. package/corpus/templates/dispatch/app/routes/admin.integrations.tsx +4 -0
  137. package/corpus/templates/dispatch/app/routes/admin.messaging.tsx +1 -0
  138. package/corpus/templates/dispatch/app/routes/admin.metrics.tsx +1 -0
  139. package/corpus/templates/dispatch/app/routes/admin.new-app.tsx +1 -0
  140. package/corpus/templates/dispatch/app/routes/admin.operations.tsx +1 -0
  141. package/corpus/templates/dispatch/app/routes/admin.thread-debug.tsx +4 -0
  142. package/corpus/templates/dispatch/app/routes/admin.transactional-email.$appId.$id.tsx +4 -0
  143. package/corpus/templates/dispatch/app/routes/admin.transactional-email.tsx +4 -0
  144. package/corpus/templates/dispatch/app/routes/admin.tsx +1 -0
  145. package/corpus/templates/dispatch/app/routes/admin.vault.tsx +1 -0
  146. package/corpus/templates/dispatch/app/routes/admin.workspace.tsx +1 -0
  147. package/corpus/templates/dispatch/changelog/2026-08-06-dispatch-keeps-everyday-navigation-focused-while-management-.md +6 -0
  148. package/corpus/templates/dispatch/changelog/2026-08-06-ready-workspace-apps-stay-one-click-away-in-a-compact-dispat.md +6 -0
  149. package/corpus/templates/dispatch/changelog/2026-08-06-shared-vault-values-and-management-are-now-restricted-to-wor.md +6 -0
  150. package/corpus/templates/factory/.agents/skills/turn-into-app/SKILL.md +296 -0
  151. package/corpus/templates/factory/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  152. package/corpus/templates/factory/.agents/skills/turn-into-skill/SKILL.md +112 -0
  153. package/corpus/templates/factory/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  154. package/corpus/templates/forms/.agents/skills/turn-into-app/SKILL.md +296 -0
  155. package/corpus/templates/forms/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  156. package/corpus/templates/forms/.agents/skills/turn-into-skill/SKILL.md +112 -0
  157. package/corpus/templates/forms/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  158. package/corpus/templates/forms/changelog/2026-08-06-delegated-requests-continue-in-the-background.md +6 -0
  159. package/corpus/templates/forms/server/plugins/agent-chat.ts +4 -0
  160. package/corpus/templates/macros/.agents/skills/turn-into-app/SKILL.md +296 -0
  161. package/corpus/templates/macros/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  162. package/corpus/templates/macros/.agents/skills/turn-into-skill/SKILL.md +112 -0
  163. package/corpus/templates/macros/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  164. package/corpus/templates/mail/.agents/skills/turn-into-app/SKILL.md +296 -0
  165. package/corpus/templates/mail/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  166. package/corpus/templates/mail/.agents/skills/turn-into-skill/SKILL.md +112 -0
  167. package/corpus/templates/mail/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  168. package/corpus/templates/mail/changelog/2026-08-06-delegated-requests-continue-in-the-background.md +6 -0
  169. package/corpus/templates/mail/server/plugins/agent-chat.ts +6 -0
  170. package/corpus/templates/plan/.agents/skills/turn-into-app/SKILL.md +296 -0
  171. package/corpus/templates/plan/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  172. package/corpus/templates/plan/.agents/skills/turn-into-skill/SKILL.md +112 -0
  173. package/corpus/templates/plan/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  174. package/corpus/templates/slides/.agents/skills/create-deck/SKILL.md +48 -5
  175. package/corpus/templates/slides/.agents/skills/design-systems/SKILL.md +37 -1
  176. package/corpus/templates/slides/.agents/skills/image-generation-via-a2a/SKILL.md +6 -0
  177. package/corpus/templates/slides/.agents/skills/slide-editing/SKILL.md +15 -2
  178. package/corpus/templates/slides/.agents/skills/slide-images/SKILL.md +29 -24
  179. package/corpus/templates/slides/.agents/skills/turn-into-app/SKILL.md +296 -0
  180. package/corpus/templates/slides/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  181. package/corpus/templates/slides/.agents/skills/turn-into-skill/SKILL.md +112 -0
  182. package/corpus/templates/slides/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  183. package/corpus/templates/slides/AGENTS.md +17 -21
  184. package/corpus/templates/slides/_gitignore +1 -0
  185. package/corpus/templates/slides/actions/export-pptx.ts +470 -36
  186. package/corpus/templates/slides/actions/get-deck.ts +12 -0
  187. package/corpus/templates/slides/actions/import-file.ts +175 -139
  188. package/corpus/templates/slides/actions/import-google-slides-reference.ts +271 -12
  189. package/corpus/templates/slides/actions/import-pptx.ts +193 -68
  190. package/corpus/templates/slides/actions/patch-deck.ts +51 -0
  191. package/corpus/templates/slides/actions/update-slide.ts +29 -3
  192. package/corpus/templates/slides/app/components/deck/DeckCard.tsx +10 -13
  193. package/corpus/templates/slides/app/components/editor/AddSlidePopover.tsx +5 -1
  194. package/corpus/templates/slides/app/components/editor/EditorToolbar.tsx +25 -12
  195. package/corpus/templates/slides/app/components/editor/ExportMenu.tsx +112 -57
  196. package/corpus/templates/slides/app/components/editor/GoogleDriveConnectionCta.tsx +202 -0
  197. package/corpus/templates/slides/app/components/editor/GoogleSlidesReferenceImport.tsx +26 -14
  198. package/corpus/templates/slides/app/components/editor/PromptDialog.tsx +173 -0
  199. package/corpus/templates/slides/app/components/editor/SlideEditor.tsx +182 -141
  200. package/corpus/templates/slides/app/components/editor/canvas-interactions/index.ts +1 -0
  201. package/corpus/templates/slides/app/components/editor/canvas-interactions/slides-canvas-adapter.ts +18 -0
  202. package/corpus/templates/slides/app/components/editor/slide-text-targets.ts +85 -0
  203. package/corpus/templates/slides/app/components/layout/Layout.tsx +3 -0
  204. package/corpus/templates/slides/app/components/onboarding/FirstDeckOnboardingFlow.tsx +15 -0
  205. package/corpus/templates/slides/app/components/presentation/PresentationView.tsx +27 -1
  206. package/corpus/templates/slides/app/i18n/en-US.ts +1 -0
  207. package/corpus/templates/slides/app/lib/create-deck-generation.ts +72 -11
  208. package/corpus/templates/slides/app/lib/deck-preview-frame.ts +15 -0
  209. package/corpus/templates/slides/app/lib/deck-share-links.ts +9 -0
  210. package/corpus/templates/slides/app/lib/export-pptx-client.ts +89 -0
  211. package/corpus/templates/slides/app/lib/import-uploaded-deck.ts +89 -0
  212. package/corpus/templates/slides/app/lib/slide-animation-elements.ts +3 -0
  213. package/corpus/templates/slides/app/pages/Index.tsx +172 -15
  214. package/corpus/templates/slides/changelog/2026-08-06-clicking-the-gray-canvas-around-a-slide-clears-its-selection.md +6 -0
  215. package/corpus/templates/slides/changelog/2026-08-06-deck-thumbnails-keep-a-consistent-listing-frame-across-aspec.md +6 -0
  216. package/corpus/templates/slides/changelog/2026-08-06-deep-linked-decks-open-directly-instead-of-being-interrupted.md +6 -0
  217. package/corpus/templates/slides/changelog/2026-08-06-google-slides-exports-now-show-clear-import-steps-when-direc.md +6 -0
  218. package/corpus/templates/slides/changelog/2026-08-06-import-pdf-google-slides-and-powerpoint-decks-directly-from-.md +6 -0
  219. package/corpus/templates/slides/changelog/2026-08-06-imported-powerpoint-exports-keep-text-and-images-editable-an.md +6 -0
  220. package/corpus/templates/slides/changelog/2026-08-06-presentation-prompts-continue-adding-rendered-slides-until-t.md +6 -0
  221. package/corpus/templates/slides/changelog/2026-08-06-public-decks-now-share-read-only-presentation-links-by-defau.md +6 -0
  222. package/corpus/templates/slides/changelog/2026-08-06-slides-offers-a-direct-connect-google-button-when-a-drive-co.md +6 -0
  223. package/corpus/templates/slides/changelog/2026-08-06-slides-preserve-uploaded-pdf-layouts-accept-larger-reference.md +6 -0
  224. package/corpus/templates/slides/changelog/2026-08-06-styled-words-stay-part-of-their-text-box-instead-of-becoming.md +6 -0
  225. package/corpus/templates/slides/changelog/2026-08-06-uploaded-decks-keep-their-slides-and-visuals-when-you-improv.md +6 -0
  226. package/corpus/templates/slides/server/handlers/google-docs-auth.ts +7 -20
  227. package/corpus/templates/slides/server/handlers/import/html-converter.ts +247 -13
  228. package/corpus/templates/slides/server/handlers/import/pptx-assets.ts +67 -0
  229. package/corpus/templates/slides/server/handlers/import/pptx-parser.ts +2 -0
  230. package/corpus/templates/slides/server/handlers/uploads.ts +7 -3
  231. package/corpus/templates/slides/server/lib/chat-attachments.ts +7 -4
  232. package/corpus/templates/slides/server/lib/emails.ts +7 -2
  233. package/corpus/templates/slides/server/lib/google-docs-error.ts +50 -0
  234. package/corpus/templates/slides/server/lib/google-docs-oauth.ts +1 -0
  235. package/corpus/templates/slides/server/lib/import-asset-storage.ts +127 -0
  236. package/corpus/templates/slides/server/lib/source-import.ts +167 -0
  237. package/corpus/templates/slides/server/plugins/agent-chat.ts +12 -3
  238. package/corpus/templates/slides/server/routes/api/import-assets/[token].get.ts +70 -0
  239. package/corpus/templates/slides/shared/upload-types.ts +3 -0
  240. package/corpus/templates/tasks/.agents/skills/turn-into-app/SKILL.md +296 -0
  241. package/corpus/templates/tasks/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  242. package/corpus/templates/tasks/.agents/skills/turn-into-skill/SKILL.md +112 -0
  243. package/corpus/templates/tasks/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  244. package/dist/agent/production-agent.d.ts +17 -0
  245. package/dist/agent/production-agent.js +72 -1
  246. package/dist/cli/agent-plugin.d.ts +112 -0
  247. package/dist/cli/agent-plugin.js +1081 -0
  248. package/dist/cli/app-skill.js +39 -1
  249. package/dist/cli/code-agent-executor.d.ts +3 -0
  250. package/dist/cli/code-agent-executor.js +51 -13
  251. package/dist/cli/index.js +13 -0
  252. package/dist/cli/templates-meta.js +1 -1
  253. package/dist/client/AgentPanel.d.ts +3 -1
  254. package/dist/client/AgentPanel.js +9 -2
  255. package/dist/client/AssistantChat.d.ts +8 -0
  256. package/dist/client/AssistantChat.js +23 -8
  257. package/dist/client/NewWorkspaceAppFlow.js +1 -0
  258. package/dist/client/agent-chat-adapter.js +123 -4
  259. package/dist/client/assistant-ui-recovery.d.ts +2 -1
  260. package/dist/client/assistant-ui-recovery.js +7 -3
  261. package/dist/client/onboarding/FirstRunOnboarding.js +11 -4
  262. package/dist/client/org/TeamPage.js +1 -1
  263. package/dist/client/require-session.js +1 -1
  264. package/dist/client/resources/McpConnectionSuggestion.d.ts +1 -0
  265. package/dist/client/resources/McpConnectionSuggestion.js +27 -10
  266. package/dist/client/resources/McpIntegrationDialog.js +77 -45
  267. package/dist/client/resources/mcp-integration-catalog.d.ts +13 -1
  268. package/dist/client/resources/mcp-integration-catalog.js +255 -2
  269. package/dist/client/resources/mcp-integration-logos.js +18 -2
  270. package/dist/client/settings/AccountSettingsCard.js +2 -1
  271. package/dist/collab/struct-routes.d.ts +1 -1
  272. package/dist/db/client.d.ts +9 -0
  273. package/dist/db/client.js +51 -16
  274. package/dist/db/create-get-db.js +2 -2
  275. package/dist/db/ddl-guard.d.ts +11 -10
  276. package/dist/db/ddl-guard.js +40 -12
  277. package/dist/deploy/build.d.ts +2 -0
  278. package/dist/deploy/build.js +97 -4
  279. package/dist/deploy/workspace-deploy.js +0 -2
  280. package/dist/file-upload/actions/upload-image.d.ts +1 -1
  281. package/dist/guards/no-env-credentials.js +9 -0
  282. package/dist/ingestion/index.d.ts +1 -1
  283. package/dist/ingestion/pptx.d.ts +68 -0
  284. package/dist/ingestion/pptx.js +660 -213
  285. package/dist/integrations/plugin.js +9 -6
  286. package/dist/jobs/scheduler.js +79 -23
  287. package/dist/localization/default-messages.d.ts +54 -0
  288. package/dist/localization/default-messages.js +57 -2
  289. package/dist/mcp/screen-memory-stdio.d.ts +7 -7
  290. package/dist/mcp-client/oauth-routes.d.ts +2 -0
  291. package/dist/mcp-client/oauth-routes.js +73 -6
  292. package/dist/observability/routes.d.ts +5 -5
  293. package/dist/onboarding/app-profile.js +11 -0
  294. package/dist/progress/routes.d.ts +1 -1
  295. package/dist/resources/handlers.d.ts +1 -1
  296. package/dist/resources/store.js +15 -1
  297. package/dist/scripts/call-agent.js +34 -4
  298. package/dist/secrets/routes.d.ts +3 -3
  299. package/dist/server/agent-chat/action-filters-a2a.d.ts +1 -1
  300. package/dist/server/agent-chat/action-filters-a2a.js +36 -1
  301. package/dist/server/agent-chat-plugin.js +29 -8
  302. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  303. package/dist/server/auth.js +47 -11
  304. package/dist/server/better-auth-instance.js +5 -3
  305. package/dist/server/core-routes-plugin.d.ts +8 -1
  306. package/dist/server/core-routes-plugin.js +28 -3
  307. package/dist/server/credential-provider.d.ts +3 -3
  308. package/dist/server/credential-provider.js +90 -4
  309. package/dist/server/onboarding-html.d.ts +2 -0
  310. package/dist/server/onboarding-html.js +115 -29
  311. package/dist/server/realtime-token.d.ts +1 -1
  312. package/dist/server/self-dispatch.d.ts +5 -4
  313. package/dist/server/self-dispatch.js +25 -14
  314. package/dist/server/ssr-handler.d.ts +1 -1
  315. package/dist/server/ssr-handler.js +1 -1
  316. package/dist/server/transcribe-voice.d.ts +1 -1
  317. package/dist/shared/cache-control.d.ts +26 -2
  318. package/dist/shared/cache-control.js +43 -2
  319. package/dist/shared/password-policy.d.ts +3 -0
  320. package/dist/shared/password-policy.js +3 -0
  321. package/dist/sharing/actions/set-resource-visibility.js +16 -4
  322. package/dist/sharing/registry.d.ts +14 -0
  323. package/dist/styles/agent-native.css +6 -0
  324. package/dist/templates/chat/.agents/skills/turn-into-app/SKILL.md +296 -0
  325. package/dist/templates/chat/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  326. package/dist/templates/chat/.agents/skills/turn-into-skill/SKILL.md +112 -0
  327. package/dist/templates/chat/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  328. package/dist/templates/default/.agents/skills/turn-into-app/SKILL.md +296 -0
  329. package/dist/templates/default/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  330. package/dist/templates/default/.agents/skills/turn-into-skill/SKILL.md +112 -0
  331. package/dist/templates/default/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  332. package/dist/templates/headless/.agents/skills/turn-into-app/SKILL.md +296 -0
  333. package/dist/templates/headless/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  334. package/dist/templates/headless/.agents/skills/turn-into-skill/SKILL.md +112 -0
  335. package/dist/templates/headless/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  336. package/dist/templates/workspace-core/.agents/skills/adding-workspace-apps/SKILL.md +6 -0
  337. package/dist/templates/workspace-core/.agents/skills/performance/SKILL.md +51 -0
  338. package/dist/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +296 -0
  339. package/dist/templates/workspace-core/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  340. package/dist/templates/workspace-core/.agents/skills/turn-into-skill/SKILL.md +112 -0
  341. package/dist/templates/workspace-core/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  342. package/dist/templates/workspace-root/AGENTS.md +7 -0
  343. package/dist/user-profile/actions/change-password.js +8 -3
  344. package/dist/user-profile/actions/set-password.js +5 -1
  345. package/dist/vite/action-types-plugin.js +59 -0
  346. package/docs/content/creating-templates.mdx +1 -1
  347. package/docs/content/getting-started-actions.mdx +38 -189
  348. package/docs/content/getting-started-database.mdx +80 -164
  349. package/docs/content/getting-started-pages.mdx +44 -155
  350. package/docs/content/getting-started.mdx +26 -106
  351. package/docs/content/skills-guide.mdx +13 -0
  352. package/package.json +6 -2
  353. package/src/templates/chat/.agents/skills/turn-into-app/SKILL.md +296 -0
  354. package/src/templates/chat/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  355. package/src/templates/chat/.agents/skills/turn-into-skill/SKILL.md +112 -0
  356. package/src/templates/chat/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  357. package/src/templates/default/.agents/skills/turn-into-app/SKILL.md +296 -0
  358. package/src/templates/default/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  359. package/src/templates/default/.agents/skills/turn-into-skill/SKILL.md +112 -0
  360. package/src/templates/default/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  361. package/src/templates/headless/.agents/skills/turn-into-app/SKILL.md +296 -0
  362. package/src/templates/headless/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  363. package/src/templates/headless/.agents/skills/turn-into-skill/SKILL.md +112 -0
  364. package/src/templates/headless/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  365. package/src/templates/workspace-core/.agents/skills/adding-workspace-apps/SKILL.md +6 -0
  366. package/src/templates/workspace-core/.agents/skills/performance/SKILL.md +51 -0
  367. package/src/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +296 -0
  368. package/src/templates/workspace-core/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  369. package/src/templates/workspace-core/.agents/skills/turn-into-skill/SKILL.md +112 -0
  370. package/src/templates/workspace-core/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  371. package/src/templates/workspace-root/AGENTS.md +7 -0
@@ -0,0 +1,83 @@
1
+ import { useT } from "@agent-native/core/client/i18n";
2
+ import { IconCalendarTime } from "@tabler/icons-react";
3
+ import { useMemo } from "react";
4
+
5
+ import {
6
+ Select,
7
+ SelectContent,
8
+ SelectGroup,
9
+ SelectItem,
10
+ SelectTrigger,
11
+ SelectValue,
12
+ } from "@/components/ui/select";
13
+ import { useGoogleAuthStatus } from "@/hooks/use-google-auth";
14
+ import { useViewPreferences } from "@/hooks/use-view-preferences";
15
+ import { defaultColorForAccount } from "@/lib/calendar-view-preferences";
16
+ import { shouldShowEventAccountSelector } from "@/lib/event-account-selection";
17
+
18
+ const EMPTY_CONNECTED_ACCOUNTS: Array<{ email: string }> = [];
19
+
20
+ export function EventCalendarSelect({
21
+ accountEmail,
22
+ onAccountChange,
23
+ disabled = false,
24
+ }: {
25
+ accountEmail?: string;
26
+ onAccountChange: (accountEmail: string) => void;
27
+ disabled?: boolean;
28
+ }) {
29
+ const t = useT();
30
+ const googleStatus = useGoogleAuthStatus();
31
+ const connectedAccounts =
32
+ googleStatus.data?.accounts ?? EMPTY_CONNECTED_ACCOUNTS;
33
+ const connectedAccountEmails = useMemo(
34
+ () => connectedAccounts.map((account) => account.email),
35
+ [connectedAccounts],
36
+ );
37
+ const { prefs: viewPrefs } = useViewPreferences();
38
+
39
+ if (!shouldShowEventAccountSelector(connectedAccounts) || !accountEmail) {
40
+ return null;
41
+ }
42
+
43
+ return (
44
+ <div className="flex items-center gap-3 py-1.5">
45
+ <IconCalendarTime className="h-4 w-4 shrink-0 text-muted-foreground" />
46
+ <Select
47
+ value={accountEmail}
48
+ onValueChange={onAccountChange}
49
+ disabled={disabled}
50
+ >
51
+ <SelectTrigger
52
+ aria-label={t("navigation.calendar")}
53
+ className="h-8 flex-1 text-sm"
54
+ >
55
+ <SelectValue />
56
+ </SelectTrigger>
57
+ <SelectContent>
58
+ <SelectGroup>
59
+ {connectedAccounts.map((account) => (
60
+ <SelectItem key={account.email} value={account.email}>
61
+ <span className="flex min-w-0 items-center gap-2">
62
+ <span
63
+ className="size-2.5 shrink-0 rounded-full"
64
+ style={{
65
+ backgroundColor:
66
+ viewPrefs.accountColors[account.email] ??
67
+ viewPrefs.singleColor ??
68
+ defaultColorForAccount(
69
+ account.email,
70
+ connectedAccountEmails,
71
+ ),
72
+ }}
73
+ />
74
+ <span className="truncate">{account.email}</span>
75
+ </span>
76
+ </SelectItem>
77
+ ))}
78
+ </SelectGroup>
79
+ </SelectContent>
80
+ </Select>
81
+ </div>
82
+ );
83
+ }
@@ -18,6 +18,7 @@ import { toast } from "sonner";
18
18
 
19
19
  import { ResearchMeetingButton } from "@/components/calendar/ApolloPanel";
20
20
  import { EventAttendeesSection } from "@/components/calendar/EventAttendeesSection";
21
+ import { EventCalendarSelect } from "@/components/calendar/EventCalendarSelect";
21
22
  import {
22
23
  RenderedDescription,
23
24
  AutoGrowTextarea,
@@ -133,6 +134,9 @@ export function EventDetailPanel({
133
134
  );
134
135
  const titleInputRef = useRef<HTMLInputElement>(null);
135
136
  const updateEvent = useUpdateEvent();
137
+ const [selectedAccountEmail, setSelectedAccountEmail] = useState(
138
+ event?.accountEmail,
139
+ );
136
140
  const { promptGuestNotification, guestNotificationDialog } =
137
141
  useGuestNotificationPrompt();
138
142
  const isOverlay = !!event?.overlayEmail;
@@ -157,6 +161,10 @@ export function EventDetailPanel({
157
161
  lastSavedDescriptionRef.current = event?.description || "";
158
162
  }, [event?.id]);
159
163
 
164
+ useEffect(() => {
165
+ setSelectedAccountEmail(event?.accountEmail);
166
+ }, [event?.id, event?.accountEmail]);
167
+
160
168
  useEffect(() => {
161
169
  if (isEditingTitle) {
162
170
  requestAnimationFrame(() => titleInputRef.current?.focus());
@@ -203,6 +211,47 @@ export function EventDetailPanel({
203
211
  onClose();
204
212
  };
205
213
 
214
+ const handleAccountChange = useCallback(
215
+ (targetAccountEmail: string) => {
216
+ if (
217
+ !event ||
218
+ !event.accountEmail ||
219
+ targetAccountEmail === event.accountEmail ||
220
+ updateEvent.isPending
221
+ ) {
222
+ return;
223
+ }
224
+
225
+ setSelectedAccountEmail(targetAccountEmail);
226
+ void (async () => {
227
+ const guestNotification = await promptGuestNotification({
228
+ event,
229
+ action: "update",
230
+ });
231
+ if (!guestNotification) {
232
+ setSelectedAccountEmail(event.accountEmail);
233
+ return;
234
+ }
235
+ updateEvent.mutate(
236
+ {
237
+ id: event.id,
238
+ accountEmail: event.accountEmail,
239
+ targetAccountEmail,
240
+ ...guestNotification,
241
+ },
242
+ {
243
+ onSuccess: () => toast.success(t("eventForm.eventUpdated")),
244
+ onError: () => {
245
+ setSelectedAccountEmail(event.accountEmail);
246
+ toast.error(t("eventForm.updateFailed"));
247
+ },
248
+ },
249
+ );
250
+ })();
251
+ },
252
+ [event, promptGuestNotification, t, updateEvent],
253
+ );
254
+
206
255
  const handleAddGoogleMeet = useCallback(() => {
207
256
  if (!event || updateEvent.isPending) return;
208
257
  void (async () => {
@@ -378,6 +427,14 @@ export function EventDetailPanel({
378
427
  </h2>
379
428
  )}
380
429
 
430
+ {!isOverlay && event.source === "google" && (
431
+ <EventCalendarSelect
432
+ accountEmail={selectedAccountEmail}
433
+ onAccountChange={handleAccountChange}
434
+ disabled={updateEvent.isPending}
435
+ />
436
+ )}
437
+
381
438
  {/* Time */}
382
439
  <div className="flex items-start gap-2.5 text-sm text-muted-foreground">
383
440
  <IconClock className="mt-0.5 h-4 w-4 shrink-0" />
@@ -31,6 +31,7 @@ import {
31
31
  type AttendeeRecipient,
32
32
  } from "@/components/calendar/AttendeeAutocomplete";
33
33
  import { EventAttendeesSection } from "@/components/calendar/EventAttendeesSection";
34
+ import { EventCalendarSelect } from "@/components/calendar/EventCalendarSelect";
34
35
  import {
35
36
  RenderedDescription,
36
37
  AutoGrowTextarea,
@@ -58,7 +59,6 @@ import {
58
59
  import {
59
60
  Select,
60
61
  SelectContent,
61
- SelectGroup,
62
62
  SelectItem,
63
63
  SelectTrigger,
64
64
  SelectValue,
@@ -71,12 +71,8 @@ import {
71
71
  TooltipProvider,
72
72
  } from "@/components/ui/tooltip";
73
73
  import { useEvent, useUpdateEvent } from "@/hooks/use-events";
74
- import { useGoogleAuthStatus } from "@/hooks/use-google-auth";
75
74
  import { useIsMobile } from "@/hooks/use-mobile";
76
- import { useViewPreferences } from "@/hooks/use-view-preferences";
77
75
  import { useConnectZoom, useZoomStatus } from "@/hooks/use-zoom-auth";
78
- import { defaultColorForAccount } from "@/lib/calendar-view-preferences";
79
- import { shouldShowEventAccountSelector } from "@/lib/event-account-selection";
80
76
  import {
81
77
  attachmentsToDrafts,
82
78
  buildRecurrenceRules,
@@ -113,7 +109,6 @@ import {
113
109
 
114
110
  const ZOOM_AFTER_CONNECT_EVENT_ID_KEY = "calendar.zoomAfterConnectEventId";
115
111
  const ZOOM_AFTER_CONNECT_MAX_AGE_MS = 10 * 60 * 1000;
116
- const EMPTY_CONNECTED_ACCOUNTS: Array<{ email: string }> = [];
117
112
 
118
113
  function buildEventDetailSlotContext(event: CalendarEvent) {
119
114
  return {
@@ -306,6 +301,7 @@ type EventUpdatePatch = Partial<CalendarEvent> & {
306
301
  addGoogleMeet?: boolean;
307
302
  addZoom?: boolean;
308
303
  addAttendees?: CalendarEvent["attendees"];
304
+ targetAccountEmail?: string;
309
305
  scope?: UpdateEventScope;
310
306
  workingLocationType?: "homeOffice" | "officeLocation" | "customLocation";
311
307
  workingLocationLabel?: string;
@@ -425,68 +421,6 @@ function formatEventDateRange(start: string, end: string, allDay?: boolean) {
425
421
  return startLabel === endLabel ? startLabel : `${startLabel} - ${endLabel}`;
426
422
  }
427
423
 
428
- function DraftEventAccountSelect({
429
- event,
430
- onAccountChange,
431
- }: {
432
- event: CalendarEvent;
433
- onAccountChange: (accountEmail: string) => void;
434
- }) {
435
- const t = useT();
436
- const googleStatus = useGoogleAuthStatus();
437
- const connectedAccounts =
438
- googleStatus.data?.accounts ?? EMPTY_CONNECTED_ACCOUNTS;
439
- const connectedAccountEmails = useMemo(
440
- () => connectedAccounts.map((account) => account.email),
441
- [connectedAccounts],
442
- );
443
- const { prefs: viewPrefs } = useViewPreferences();
444
-
445
- if (
446
- !shouldShowEventAccountSelector(connectedAccounts) ||
447
- !event.accountEmail
448
- ) {
449
- return null;
450
- }
451
-
452
- return (
453
- <div className="flex items-center gap-3 py-1.5">
454
- <IconCalendarTime className="h-4 w-4 shrink-0 text-muted-foreground" />
455
- <Select value={event.accountEmail} onValueChange={onAccountChange}>
456
- <SelectTrigger
457
- aria-label={t("navigation.calendar")}
458
- className="h-8 flex-1 text-sm"
459
- >
460
- <SelectValue />
461
- </SelectTrigger>
462
- <SelectContent>
463
- <SelectGroup>
464
- {connectedAccounts.map((account) => (
465
- <SelectItem key={account.email} value={account.email}>
466
- <span className="flex min-w-0 items-center gap-2">
467
- <span
468
- className="size-2.5 shrink-0 rounded-full"
469
- style={{
470
- backgroundColor:
471
- viewPrefs.accountColors[account.email] ??
472
- viewPrefs.singleColor ??
473
- defaultColorForAccount(
474
- account.email,
475
- connectedAccountEmails,
476
- ),
477
- }}
478
- />
479
- <span className="truncate">{account.email}</span>
480
- </span>
481
- </SelectItem>
482
- ))}
483
- </SelectGroup>
484
- </SelectContent>
485
- </Select>
486
- </div>
487
- );
488
- }
489
-
490
424
  interface EventDetailPopoverProps {
491
425
  event: CalendarEvent;
492
426
  children: React.ReactNode;
@@ -590,6 +524,9 @@ export function EventDetailPopover({
590
524
  () => attachmentsToDrafts(event.attachments),
591
525
  );
592
526
  const [editMeetingLink, setEditMeetingLink] = useState("");
527
+ const [selectedAccountEmail, setSelectedAccountEmail] = useState(
528
+ event.accountEmail,
529
+ );
593
530
  const [editTimeScope, setEditTimeScope] =
594
531
  useState<UpdateEventScope>("single");
595
532
  const [pendingVideoProvider, setPendingVideoProvider] = useState<
@@ -620,6 +557,54 @@ export function EventDetailPopover({
620
557
  const locationRef = useRef<HTMLInputElement>(null);
621
558
  const meetingLinkRef = useRef<HTMLInputElement>(null);
622
559
 
560
+ useEffect(() => {
561
+ setSelectedAccountEmail(event.accountEmail);
562
+ }, [event.id, event.accountEmail]);
563
+
564
+ const handleAccountChange = useCallback(
565
+ (targetAccountEmail: string) => {
566
+ if (isDraft) {
567
+ onDraftUpdate?.(event.id, { accountEmail: targetAccountEmail });
568
+ return;
569
+ }
570
+ if (
571
+ !event.accountEmail ||
572
+ targetAccountEmail === event.accountEmail ||
573
+ updateEvent.isPending
574
+ ) {
575
+ return;
576
+ }
577
+
578
+ setSelectedAccountEmail(targetAccountEmail);
579
+ void (async () => {
580
+ const guestNotification = await promptGuestNotification({
581
+ event,
582
+ action: "update",
583
+ });
584
+ if (!guestNotification) {
585
+ setSelectedAccountEmail(event.accountEmail);
586
+ return;
587
+ }
588
+ updateEvent.mutate(
589
+ {
590
+ id: event.id,
591
+ accountEmail: event.accountEmail,
592
+ targetAccountEmail,
593
+ ...guestNotification,
594
+ },
595
+ {
596
+ onSuccess: () => toast.success(t("eventForm.eventUpdated")),
597
+ onError: () => {
598
+ setSelectedAccountEmail(event.accountEmail);
599
+ toast.error(t("eventForm.updateFailed"));
600
+ },
601
+ },
602
+ );
603
+ })();
604
+ },
605
+ [event, isDraft, onDraftUpdate, promptGuestNotification, t, updateEvent],
606
+ );
607
+
623
608
  // Sync editing state when the event changes (incl. live agent/other-user
624
609
  // edits picked up by polling). Skip the field the user is actively editing so
625
610
  // an incoming update never yanks text out from under in-progress typing —
@@ -1587,12 +1572,13 @@ export function EventDetailPopover({
1587
1572
  </div>
1588
1573
 
1589
1574
  <div className="px-4 space-y-1">
1590
- {isDraft && (
1591
- <DraftEventAccountSelect
1592
- event={event}
1593
- onAccountChange={(accountEmail) =>
1594
- onDraftUpdate?.(event.id, { accountEmail })
1575
+ {(isDraft || (!isOverlay && event.source === "google")) && (
1576
+ <EventCalendarSelect
1577
+ accountEmail={
1578
+ isDraft ? event.accountEmail : selectedAccountEmail
1595
1579
  }
1580
+ onAccountChange={handleAccountChange}
1581
+ disabled={updateEvent.isPending}
1596
1582
  />
1597
1583
  )}
1598
1584
 
@@ -45,6 +45,7 @@ type CreateEventInput = Omit<
45
45
 
46
46
  type UpdateEventInput = Partial<CalendarEvent> & {
47
47
  id: string;
48
+ targetAccountEmail?: string;
48
49
  addGoogleMeet?: boolean;
49
50
  addZoom?: boolean;
50
51
  addAttendees?: CalendarEvent["attendees"];
@@ -379,6 +380,7 @@ export function useUpdateEvent() {
379
380
  addGoogleMeet,
380
381
  addZoom,
381
382
  addAttendees,
383
+ targetAccountEmail,
382
384
  sendUpdates,
383
385
  notificationMessage,
384
386
  scope,
@@ -386,6 +388,7 @@ export function useUpdateEvent() {
386
388
  workingLocationLabel,
387
389
  ...optimisticData
388
390
  } = newData;
391
+ const optimisticPatch = targetAccountEmail ? {} : optimisticData;
389
392
  const hasWorkingLocationUpdate =
390
393
  workingLocationType !== undefined ||
391
394
  workingLocationLabel !== undefined;
@@ -413,7 +416,7 @@ export function useUpdateEvent() {
413
416
  workingLocationLabel ?? getWorkingLocationEditableLabel(e);
414
417
  return {
415
418
  ...e,
416
- ...optimisticData,
419
+ ...optimisticPatch,
417
420
  ...(hasWorkingLocationUpdate
418
421
  ? {
419
422
  workingLocationProperties: buildWorkingLocationProperties(
@@ -762,6 +762,8 @@ const enUS = {
762
762
  end: "End",
763
763
  endDate: "End date",
764
764
  event: "Event",
765
+ eventUpdated: "Event updated",
766
+ updateFailed: "Failed to update event",
765
767
  eventAlerts: "Event alerts",
766
768
  eventOptions: "Event options",
767
769
  autoDecline: "Automatically decline",
@@ -8110,6 +8112,8 @@ const translatedCalendarRawBurnDown = {
8110
8112
  },
8111
8113
  eventForm: {
8112
8114
  addCalendar: "添加日历",
8115
+ eventUpdated: "事件已更新",
8116
+ updateFailed: "更新事件失败",
8113
8117
  addCalendarFailed: "添加日历失败",
8114
8118
  addCalendarFromUrl: "从 URL 添加日历",
8115
8119
  added: "已添加",
@@ -8281,6 +8285,8 @@ const translatedCalendarRawBurnDown = {
8281
8285
  },
8282
8286
  eventForm: {
8283
8287
  addCalendar: "Añadir calendario",
8288
+ eventUpdated: "Evento actualizado",
8289
+ updateFailed: "No se pudo actualizar el evento",
8284
8290
  addCalendarFailed: "No se pudo añadir el calendario",
8285
8291
  addCalendarFromUrl: "Añadir calendario desde URL",
8286
8292
  added: "Añadido",
@@ -8454,6 +8460,8 @@ const translatedCalendarRawBurnDown = {
8454
8460
  },
8455
8461
  eventForm: {
8456
8462
  addCalendar: "Ajouter un calendrier",
8463
+ eventUpdated: "Événement mis à jour",
8464
+ updateFailed: "Échec de la mise à jour de l'événement",
8457
8465
  addCalendarFailed: "Échec de l’ajout du calendrier",
8458
8466
  addCalendarFromUrl: "Ajouter un calendrier depuis une URL",
8459
8467
  added: "Ajouté",
@@ -8633,6 +8641,8 @@ const translatedCalendarRawBurnDown = {
8633
8641
  },
8634
8642
  eventForm: {
8635
8643
  addCalendar: "Kalender hinzufügen",
8644
+ eventUpdated: "Ereignis aktualisiert",
8645
+ updateFailed: "Ereignis konnte nicht aktualisiert werden",
8636
8646
  addCalendarFailed: "Kalender konnte nicht hinzugefügt werden",
8637
8647
  addCalendarFromUrl: "Kalender per URL hinzufügen",
8638
8648
  added: "Hinzugefügt",
@@ -8808,6 +8818,8 @@ const translatedCalendarRawBurnDown = {
8808
8818
  },
8809
8819
  eventForm: {
8810
8820
  addCalendar: "カレンダーを追加",
8821
+ eventUpdated: "予定を更新しました",
8822
+ updateFailed: "予定を更新できませんでした",
8811
8823
  addCalendarFailed: "カレンダーを追加できませんでした",
8812
8824
  addCalendarFromUrl: "URL からカレンダーを追加",
8813
8825
  added: "追加済み",
@@ -8978,6 +8990,8 @@ const translatedCalendarRawBurnDown = {
8978
8990
  },
8979
8991
  eventForm: {
8980
8992
  addCalendar: "캘린더 추가",
8993
+ eventUpdated: "이벤트가 업데이트되었습니다",
8994
+ updateFailed: "이벤트를 업데이트하지 못했습니다",
8981
8995
  addCalendarFailed: "캘린더를 추가하지 못했습니다",
8982
8996
  addCalendarFromUrl: "URL에서 캘린더 추가",
8983
8997
  added: "추가됨",
@@ -9151,6 +9165,8 @@ const translatedCalendarRawBurnDown = {
9151
9165
  },
9152
9166
  eventForm: {
9153
9167
  addCalendar: "Adicionar calendário",
9168
+ eventUpdated: "Evento atualizado",
9169
+ updateFailed: "Falha ao atualizar evento",
9154
9170
  addCalendarFailed: "Falha ao adicionar calendário",
9155
9171
  addCalendarFromUrl: "Adicionar calendário por URL",
9156
9172
  added: "Adicionado",
@@ -9323,6 +9339,8 @@ const translatedCalendarRawBurnDown = {
9323
9339
  },
9324
9340
  eventForm: {
9325
9341
  addCalendar: "कैलेंडर जोड़ें",
9342
+ eventUpdated: "इवेंट अपडेट हो गया",
9343
+ updateFailed: "इवेंट अपडेट नहीं हो सका",
9326
9344
  addCalendarFailed: "कैलेंडर जोड़ने में विफल",
9327
9345
  addCalendarFromUrl: "URL से कैलेंडर जोड़ें",
9328
9346
  added: "जोड़ा गया",
@@ -9494,6 +9512,8 @@ const translatedCalendarRawBurnDown = {
9494
9512
  },
9495
9513
  eventForm: {
9496
9514
  addCalendar: "إضافة تقويم",
9515
+ eventUpdated: "تم تحديث الحدث",
9516
+ updateFailed: "فشل تحديث الحدث",
9497
9517
  addCalendarFailed: "فشلت إضافة التقويم",
9498
9518
  addCalendarFromUrl: "إضافة تقويم من URL",
9499
9519
  added: "تمت الإضافة",
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: improved
3
+ date: 2026-08-06
4
+ ---
5
+
6
+ Long-running calendar requests now continue in the background instead of stopping at the foreground time limit.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: added
3
+ date: 2026-08-06
4
+ ---
5
+
6
+ Existing events can move between connected Google account calendars
@@ -154,6 +154,27 @@ const LIST_EVENT_TYPES = [
154
154
  ];
155
155
  const GOOGLE_READ_CONCURRENCY = 4;
156
156
 
157
+ export class CalendarMoveRollbackError extends Error {
158
+ readonly code = "CALENDAR_MOVE_ROLLBACK_FAILED" as const;
159
+ readonly cause: unknown;
160
+ readonly replacementId: string;
161
+ readonly destinationAccountEmail: string;
162
+
163
+ constructor(
164
+ replacementId: string,
165
+ destinationAccountEmail: string,
166
+ cause: unknown,
167
+ ) {
168
+ super(
169
+ `Calendar move cleanup failed after Google created destination event "${replacementId}" in calendar "${destinationAccountEmail}". The destination may still exist; inspect or delete it before retrying.`,
170
+ );
171
+ this.name = "CalendarMoveRollbackError";
172
+ this.cause = cause;
173
+ this.replacementId = replacementId;
174
+ this.destinationAccountEmail = destinationAccountEmail;
175
+ }
176
+ }
177
+
157
178
  async function mapWithConcurrency<T, R>(
158
179
  values: T[],
159
180
  map: (value: T) => Promise<R>,
@@ -1261,6 +1282,86 @@ export async function createEvent(
1261
1282
  };
1262
1283
  }
1263
1284
 
1285
+ export async function moveEvent(
1286
+ googleEventId: string,
1287
+ options: {
1288
+ sourceAccount: GoogleAccountSelection;
1289
+ destinationAccount: GoogleAccountSelection;
1290
+ sendUpdates?: "all" | "none";
1291
+ },
1292
+ ): Promise<{
1293
+ id?: string;
1294
+ htmlLink?: string;
1295
+ meetLink?: string;
1296
+ conferenceData?: CalendarEvent["conferenceData"];
1297
+ }> {
1298
+ const sourceEvent = await getEvent(googleEventId, options.sourceAccount);
1299
+ if (sourceEvent.status === "cancelled") {
1300
+ throw new Error("Cancelled events cannot be moved.");
1301
+ }
1302
+ if (
1303
+ sourceEvent.eventType &&
1304
+ !["default", "outOfOffice", "focusTime", "workingLocation"].includes(
1305
+ sourceEvent.eventType,
1306
+ )
1307
+ ) {
1308
+ throw new Error("This Google Calendar event type cannot be moved.");
1309
+ }
1310
+ if (sourceEvent.recurrence?.length && !sourceEvent.recurringEventId) {
1311
+ throw new Error(
1312
+ "Recurring series masters cannot be moved; move a single occurrence instead.",
1313
+ );
1314
+ }
1315
+
1316
+ const replacement = await createEvent(
1317
+ {
1318
+ ...sourceEvent,
1319
+ id: "",
1320
+ googleEventId: undefined,
1321
+ recurringEventId: undefined,
1322
+ accountEmail: options.destinationAccount.accountEmail,
1323
+ attendees: sourceEvent.attendees?.filter((attendee) => !attendee.self),
1324
+ },
1325
+ {
1326
+ account: options.destinationAccount,
1327
+ addGoogleMeet: Boolean(
1328
+ sourceEvent.hangoutLink ||
1329
+ sourceEvent.conferenceData?.entryPoints?.some(
1330
+ (entry) => entry.entryPointType === "video",
1331
+ ),
1332
+ ),
1333
+ sendUpdates: options.sendUpdates,
1334
+ },
1335
+ );
1336
+
1337
+ if (!replacement.id) {
1338
+ throw new Error("Google did not return an id for the moved event.");
1339
+ }
1340
+
1341
+ try {
1342
+ await deleteEvent(googleEventId, options.sourceAccount, {
1343
+ scope: "single",
1344
+ sendUpdates: options.sendUpdates,
1345
+ });
1346
+ } catch (error) {
1347
+ try {
1348
+ await deleteEvent(replacement.id, options.destinationAccount, {
1349
+ scope: "single",
1350
+ sendUpdates: options.sendUpdates === "all" ? "all" : "none",
1351
+ });
1352
+ } catch (cleanupError) {
1353
+ throw new CalendarMoveRollbackError(
1354
+ replacement.id,
1355
+ options.destinationAccount.accountEmail,
1356
+ cleanupError,
1357
+ );
1358
+ }
1359
+ throw error;
1360
+ }
1361
+
1362
+ return replacement;
1363
+ }
1364
+
1264
1365
  export async function updateEvent(
1265
1366
  googleEventId: string,
1266
1367
  event: Partial<CalendarEvent>,
@@ -83,6 +83,12 @@ const INITIAL_TOOL_NAMES = [
83
83
 
84
84
  export default createAgentChatPlugin({
85
85
  appId: "calendar",
86
+ // A delegated (A2A) turn served from the foreground gets the 40s
87
+ // serverless wall, and "I ran out of time before finishing this step"
88
+ // was 39% of this fleet's failed inbound A2A tasks — clustered at
89
+ // 35-46s, the wall to the second. Opting in routes the task to the
90
+ // background worker, as content, slides and analytics already do.
91
+ durableBackgroundRuns: true,
86
92
  initialToolNames: INITIAL_TOOL_NAMES,
87
93
  connectorCatalog: [...CALENDAR_CONNECTOR_CATALOG],
88
94
  // Enable sandboxed JavaScript execution so Calendar agents can fetch,
@@ -109,7 +115,7 @@ Provider-specific Calendar actions are shortcuts, not limits. If a first-class a
109
115
  - \`pnpm action search-events --query "term" --from YYYY-MM-DD --to YYYY-MM-DD\` — Convenience bounded search by title, attendees, organizer, location, or description. For relationship history, all-calendar discovery, exact attendee/domain search, or custom pagination, prefer provider-api-request with provider=google_calendar.
110
116
  - \`pnpm action provider-api-catalog\` / \`provider-api-docs\` / \`provider-api-request\` — Inspect and call the real Google Calendar, Apollo, Gong, HubSpot, and Pylon APIs directly. For Google Calendar events.list pagination use provider=google_calendar, path=/calendars/primary/events, query={...}, fetchAllPages={cursorPath:"nextPageToken",cursorParam:"pageToken",itemsPath:"items"}. For large relationship-history scans, pass stageAs and pagination={nextCursorPath:"nextPageToken",cursorParam:"pageToken",maxPages:N} with itemsPath="items", then use query-staged-dataset.
111
117
  - \`pnpm action create-event --title "..." --start "ISO" --end "ISO"\` — Create a new event. Use \`--eventType outOfOffice\` for OOO, \`--eventType focusTime\` for focus time, \`--eventType workingLocation\` for working location, \`--transparency transparent\` to show as Free, \`--visibility private\` for private events, \`--startTimeZone America/Los_Angeles\` for timezone anchoring, \`--colorId 9\` for Google event color, \`--reminders '[{"method":"popup","minutes":10}]'\` for alerts, and \`--attachments '[{"fileUrl":"https://...","title":"Agenda"}]'\` for Drive/HTTPS file links.
112
- - \`pnpm action update-event --id "google-..." --transparency opaque|transparent --visibility default|public|private --reminderMinutes 10 --addAttendees "alice@example.com" --scope single|all\` — Update event availability, visibility, reminders, timezone, color, attachments, recurrence, guests, or generated video links. Use \`addAttendees\` when inviting more people so existing RSVP metadata is preserved. Pass attendee objects with \`optional:true\` to mark optional guests. Use \`--scope all\` to update an entire recurring series from one occurrence.
118
+ - \`pnpm action update-event --id "google-..." --transparency opaque|transparent --visibility default|public|private --reminderMinutes 10 --addAttendees "alice@example.com" --scope single|all\` — Update event availability, visibility, reminders, timezone, color, attachments, recurrence, guests, generated video links, or move an existing event between connected account calendars with \`--accountEmail <current> --targetAccountEmail <destination>\`. A move recreates the event on the destination and removes the source; do not combine it with other event field changes. Use \`addAttendees\` when inviting more people so existing RSVP metadata is preserved. Pass attendee objects with \`optional:true\` to mark optional guests. Use \`--scope all\` to update an entire recurring series from one occurrence, but use \`scope: single\` when moving an event.
113
119
  - \`pnpm action navigate --view=calendar --calendarViewMode=day\` — Navigate the UI (day/week/month views, dates)
114
120
  - \`pnpm action navigate --view=calendar --date=YYYY-MM-DD\` — Navigate to a specific date
115
121
  - \`pnpm action navigate --view=availability\` — Show availability settings