@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,202 @@
1
+ import { agentNativePath } from "@agent-native/core/client/api-path";
2
+ import { oauthRedirectUri } from "@agent-native/core/client/host";
3
+ import { useT } from "@agent-native/core/client/i18n";
4
+ import {
5
+ IconBrandGoogleDrive,
6
+ IconLoader2,
7
+ IconPlugConnected,
8
+ } from "@tabler/icons-react";
9
+ import { useCallback, useEffect, useState } from "react";
10
+
11
+ import { Button } from "../ui/button";
12
+
13
+ interface GoogleDocsStatus {
14
+ configured: boolean;
15
+ connected: boolean;
16
+ error?: string;
17
+ message?: string;
18
+ }
19
+
20
+ interface GoogleDocsAuthResponse {
21
+ url?: string;
22
+ error?: string;
23
+ message?: string;
24
+ }
25
+
26
+ type JsonReadResult<T> = { ok: true; data: T } | { ok: false; error: Error };
27
+
28
+ function endpoint(path: string): string {
29
+ return new URL(agentNativePath(path), window.location.origin).toString();
30
+ }
31
+
32
+ async function readJson<T>(response: Response): Promise<JsonReadResult<T>> {
33
+ try {
34
+ return { ok: true, data: (await response.json()) as T };
35
+ } catch (caught) {
36
+ return {
37
+ ok: false,
38
+ error: new Error("The server returned an unreadable response.", {
39
+ cause: caught,
40
+ }),
41
+ };
42
+ }
43
+ }
44
+
45
+ function responseError(
46
+ response: Response,
47
+ data: { error?: string; message?: string },
48
+ fallback: string,
49
+ ): Error {
50
+ return new Error(
51
+ data.message || data.error || `${fallback} (${response.status})`,
52
+ );
53
+ }
54
+
55
+ export interface GoogleDriveConnectionCtaProps {
56
+ onConnected?: () => void;
57
+ }
58
+
59
+ export function GoogleDriveConnectionCta({
60
+ onConnected,
61
+ }: GoogleDriveConnectionCtaProps) {
62
+ const t = useT();
63
+ const [status, setStatus] = useState<GoogleDocsStatus | null>(null);
64
+ const [loading, setLoading] = useState(true);
65
+ const [connecting, setConnecting] = useState(false);
66
+ const [error, setError] = useState<string | null>(null);
67
+
68
+ const refreshStatus =
69
+ useCallback(async (): Promise<GoogleDocsStatus | null> => {
70
+ try {
71
+ const response = await fetch(
72
+ endpoint("/_agent-native/google-docs/status"),
73
+ { credentials: "same-origin" },
74
+ );
75
+ const result = await readJson<GoogleDocsStatus>(response);
76
+ if (!result.ok) throw result.error;
77
+ if (!response.ok) {
78
+ throw responseError(
79
+ response,
80
+ result.data,
81
+ "Could not check Google Drive",
82
+ );
83
+ }
84
+ setStatus(result.data);
85
+ setError(null);
86
+ return result.data;
87
+ } catch (caught) {
88
+ setStatus(null);
89
+ setError(caught instanceof Error ? caught.message : String(caught));
90
+ return null;
91
+ } finally {
92
+ setLoading(false);
93
+ }
94
+ }, []);
95
+
96
+ useEffect(() => {
97
+ void refreshStatus();
98
+ }, [refreshStatus]);
99
+
100
+ const connect = useCallback(async () => {
101
+ if (connecting) return;
102
+ setConnecting(true);
103
+ setError(null);
104
+ const popup = window.open(
105
+ "about:blank",
106
+ "google-docs-oauth",
107
+ "popup,width=520,height=720",
108
+ );
109
+ try {
110
+ const authUrl = new URL(endpoint("/_agent-native/google-docs/auth-url"));
111
+ authUrl.searchParams.set(
112
+ "redirect_uri",
113
+ oauthRedirectUri("/_agent-native/google-docs/callback"),
114
+ );
115
+ authUrl.searchParams.set(
116
+ "return",
117
+ window.location.pathname + window.location.search,
118
+ );
119
+ const response = await fetch(authUrl.toString(), {
120
+ credentials: "same-origin",
121
+ });
122
+ const result = await readJson<GoogleDocsAuthResponse>(response);
123
+ if (!result.ok) throw result.error;
124
+ if (!response.ok || !result.data.url) {
125
+ throw responseError(
126
+ response,
127
+ result.data,
128
+ "Could not start Google OAuth",
129
+ );
130
+ }
131
+ if (!popup) {
132
+ window.location.href = result.data.url;
133
+ return;
134
+ }
135
+ popup.location.href = result.data.url;
136
+
137
+ const deadline = Date.now() + 90_000;
138
+ while (Date.now() < deadline && !popup.closed) {
139
+ await new Promise((resolve) => window.setTimeout(resolve, 1_200));
140
+ const next = await refreshStatus();
141
+ if (next?.connected) {
142
+ popup.close();
143
+ onConnected?.();
144
+ return;
145
+ }
146
+ }
147
+ const next = await refreshStatus();
148
+ if (next?.connected) onConnected?.();
149
+ } catch (caught) {
150
+ popup?.close();
151
+ setError(caught instanceof Error ? caught.message : String(caught));
152
+ } finally {
153
+ setConnecting(false);
154
+ }
155
+ }, [connecting, onConnected, refreshStatus]);
156
+
157
+ if (loading || status?.connected) return null;
158
+
159
+ const displayStatus = status ?? { configured: false, connected: false };
160
+
161
+ return (
162
+ <div className="flex items-center gap-2 rounded-lg border border-border/70 bg-muted/35 px-3 py-2 text-xs">
163
+ <div className="flex size-6 shrink-0 items-center justify-center rounded-md border border-border/70 bg-background">
164
+ {connecting ? (
165
+ <IconLoader2 className="size-3.5 animate-spin text-muted-foreground" />
166
+ ) : (
167
+ <IconBrandGoogleDrive className="size-3.5 text-primary" />
168
+ )}
169
+ </div>
170
+ <div className="min-w-0 flex-1">
171
+ <p className="font-medium text-foreground">
172
+ Google Drive {/* i18n-ignore stable provider label */}
173
+ </p>
174
+ <p className="mt-0.5 text-[11px] leading-relaxed text-muted-foreground">
175
+ {displayStatus.configured
176
+ ? t("home.googleSlidesReferenceConnect")
177
+ : t("raw.googleOAuthNotConfigured")}
178
+ </p>
179
+ {error && <p className="mt-1 text-[11px] text-destructive">{error}</p>}
180
+ </div>
181
+ {displayStatus.configured && (
182
+ <Button
183
+ type="button"
184
+ size="sm"
185
+ onClick={() => void connect()}
186
+ disabled={connecting}
187
+ aria-busy={connecting}
188
+ className="h-7 shrink-0 gap-1.5 rounded-md px-2.5 text-[11px] disabled:cursor-wait"
189
+ >
190
+ {connecting ? (
191
+ <IconLoader2 className="size-3.5 animate-spin" />
192
+ ) : (
193
+ <IconPlugConnected className="size-3.5" />
194
+ )}
195
+ {connecting
196
+ ? t("home.googleSlidesReferencePicking")
197
+ : t("editorExport.connectGoogle")}
198
+ </Button>
199
+ )}
200
+ </div>
201
+ );
202
+ }
@@ -121,23 +121,35 @@ export function GoogleSlidesReferenceImport({
121
121
 
122
122
  const refreshStatus =
123
123
  useCallback(async (): Promise<GoogleDocsStatus | null> => {
124
- const response = await fetch(
125
- endpoint("/_agent-native/google-docs/status"),
126
- {
127
- credentials: "same-origin",
128
- },
129
- );
130
- const result = await readJson<GoogleDocsStatus>(response);
131
- if (!result.ok) {
132
- setStatus(null);
133
- return null;
134
- }
135
- if (response.ok && result.data) {
124
+ try {
125
+ const response = await fetch(
126
+ endpoint("/_agent-native/google-docs/status"),
127
+ {
128
+ credentials: "same-origin",
129
+ },
130
+ );
131
+ const result = await readJson<GoogleDocsStatus>(response);
132
+ if (!result.ok) throw result.error;
133
+ if (!response.ok) {
134
+ throw new Error(
135
+ errorFromResponse(
136
+ response,
137
+ result.data,
138
+ "Could not check Google Drive",
139
+ ),
140
+ );
141
+ }
142
+ if (!result.data) {
143
+ throw new Error("Google Drive status was empty.");
144
+ }
145
+ setError(null);
136
146
  setStatus(result.data);
137
147
  return result.data;
148
+ } catch (caught) {
149
+ setStatus(null);
150
+ setError(caught instanceof Error ? caught.message : String(caught));
151
+ return null;
138
152
  }
139
- setStatus(null);
140
- return null;
141
153
  }, []);
142
154
 
143
155
  useEffect(() => {
@@ -2,11 +2,20 @@ import { appBasePath } from "@agent-native/core/client/api-path";
2
2
  import { PromptComposer } from "@agent-native/core/client/composer";
3
3
  import { ensureEmbedAuthFetchInterceptor } from "@agent-native/core/client/host";
4
4
  import { useT } from "@agent-native/core/client/i18n";
5
+ import {
6
+ IconBrandGoogle,
7
+ IconFileTypePdf,
8
+ IconPresentation,
9
+ } from "@tabler/icons-react";
5
10
  import { useState, useEffect, useCallback, useRef } from "react";
6
11
  import { createPortal } from "react-dom";
7
12
  import { toast } from "sonner";
8
13
 
14
+ import { MAX_REFERENCE_FILE_BYTES } from "../../../shared/upload-types";
15
+ import { Button } from "../ui/button";
16
+ import { Input } from "../ui/input";
9
17
  import { GoogleDocImportHint } from "./GoogleDocImportHint";
18
+ import { GoogleDriveConnectionCta } from "./GoogleDriveConnectionCta";
10
19
 
11
20
  export interface UploadedFile {
12
21
  path: string;
@@ -64,6 +73,12 @@ export function isInsidePortaledLayer(target: EventTarget | null): boolean {
64
73
  );
65
74
  }
66
75
 
76
+ export type PromptImportSource = "pdf" | "pptx" | "google-slides";
77
+
78
+ export type PromptImportSelection =
79
+ | { kind: "pdf" | "pptx"; files: File[] }
80
+ | { kind: "google-slides"; url: string };
81
+
67
82
  interface PromptPopoverProps {
68
83
  open: boolean;
69
84
  onOpenChange: (open: boolean) => void;
@@ -80,6 +95,11 @@ interface PromptPopoverProps {
80
95
  initialText?: string;
81
96
  initialTextKey?: string | number;
82
97
  onBeforeUpload?: (prompt: string, files: File[]) => boolean | void;
98
+ onImport?: (
99
+ selection: PromptImportSelection,
100
+ ) => Promise<boolean | void> | boolean | void;
101
+ importFromLabel?: string;
102
+ importingLabel?: string;
83
103
  children?: React.ReactNode;
84
104
  }
85
105
 
@@ -98,12 +118,21 @@ export default function PromptPopover({
98
118
  initialText,
99
119
  initialTextKey,
100
120
  onBeforeUpload,
121
+ onImport,
122
+ importFromLabel,
123
+ importingLabel = "Importing...",
101
124
  children,
102
125
  }: PromptPopoverProps) {
103
126
  const t = useT();
104
127
  const [uploading, setUploading] = useState(false);
105
128
  const [promptText, setPromptText] = useState("");
106
129
  const [googleDocContext, setGoogleDocContext] = useState("");
130
+ const [googleSlidesUrl, setGoogleSlidesUrl] = useState("");
131
+ const [googleSlidesInputOpen, setGoogleSlidesInputOpen] = useState(false);
132
+ const [importingSource, setImportingSource] =
133
+ useState<PromptImportSource | null>(null);
134
+ const pdfInputRef = useRef<HTMLInputElement>(null);
135
+ const pptxInputRef = useRef<HTMLInputElement>(null);
107
136
  const panelRef = useRef<HTMLDivElement>(null);
108
137
 
109
138
  // Position the popover after render so we can measure its actual size
@@ -202,10 +231,48 @@ export default function PromptPopover({
202
231
  [googleDocContext, onBeforeUpload, onSubmit, uploadFiles, t],
203
232
  );
204
233
 
234
+ const runImport = useCallback(
235
+ async (selection: PromptImportSelection) => {
236
+ if (!onImport) return;
237
+ setImportingSource(selection.kind);
238
+ try {
239
+ const shouldClose = await onImport(selection);
240
+ if (shouldClose !== false) onOpenChange(false);
241
+ } catch (error) {
242
+ toast.error(t("raw.uploadFailed"), {
243
+ description:
244
+ error instanceof Error
245
+ ? error.message
246
+ : t("raw.uploadAttachedFailed"),
247
+ });
248
+ } finally {
249
+ setImportingSource(null);
250
+ }
251
+ },
252
+ [onImport, onOpenChange, t],
253
+ );
254
+
255
+ const handleFileImport = useCallback(
256
+ (kind: "pdf" | "pptx", file: File | undefined) => {
257
+ if (!file) return;
258
+ void runImport({ kind, files: [file] });
259
+ },
260
+ [runImport],
261
+ );
262
+
263
+ const handleGoogleSlidesImport = useCallback(() => {
264
+ const url = googleSlidesUrl.trim();
265
+ if (!url) return;
266
+ void runImport({ kind: "google-slides", url });
267
+ }, [googleSlidesUrl, runImport]);
268
+
205
269
  useEffect(() => {
206
270
  if (!open) {
207
271
  setPromptText("");
208
272
  setGoogleDocContext("");
273
+ setGoogleSlidesUrl("");
274
+ setGoogleSlidesInputOpen(false);
275
+ setImportingSource(null);
209
276
  }
210
277
  }, [open]);
211
278
 
@@ -247,6 +314,8 @@ export default function PromptPopover({
247
314
  <PromptComposer
248
315
  autoFocus
249
316
  attachmentsEnabled
317
+ maxDocumentAttachmentBytes={MAX_REFERENCE_FILE_BYTES}
318
+ documentAttachmentLimitLabel="Slides reference files"
250
319
  disabled={loading || uploading}
251
320
  placeholder={placeholder}
252
321
  onSubmit={handleSubmit}
@@ -257,6 +326,110 @@ export default function PromptPopover({
257
326
  />
258
327
  </div>
259
328
 
329
+ {onImport && importFromLabel && (
330
+ <div className="border-t border-border/60 px-4 pb-3 pt-2.5">
331
+ <div className="flex flex-wrap items-center gap-1.5">
332
+ <span className="mr-1 text-xs text-muted-foreground">
333
+ {importFromLabel}
334
+ </span>
335
+ <input
336
+ ref={pdfInputRef}
337
+ type="file"
338
+ accept=".pdf,application/pdf"
339
+ className="sr-only"
340
+ aria-label={t("editorToolbar.importFile")}
341
+ onChange={(event) => {
342
+ handleFileImport("pdf", event.target.files?.[0]);
343
+ event.target.value = "";
344
+ }}
345
+ />
346
+ <input
347
+ ref={pptxInputRef}
348
+ type="file"
349
+ accept=".pptx,application/vnd.openxmlformats-officedocument.presentationml.presentation"
350
+ className="sr-only"
351
+ aria-label={t("editorToolbar.importFile")}
352
+ onChange={(event) => {
353
+ handleFileImport("pptx", event.target.files?.[0]);
354
+ event.target.value = "";
355
+ }}
356
+ />
357
+ <Button
358
+ type="button"
359
+ variant="ghost"
360
+ size="sm"
361
+ className="h-7 gap-1.5 px-2 text-xs text-muted-foreground hover:text-foreground"
362
+ disabled={importingSource !== null || loading || uploading}
363
+ onClick={() => pdfInputRef.current?.click()}
364
+ >
365
+ <IconFileTypePdf className="size-3.5" />
366
+ PDF
367
+ </Button>
368
+ <Button
369
+ type="button"
370
+ variant="ghost"
371
+ size="sm"
372
+ className="h-7 gap-1.5 px-2 text-xs text-muted-foreground hover:text-foreground"
373
+ disabled={importingSource !== null || loading || uploading}
374
+ onClick={() => setGoogleSlidesInputOpen((current) => !current)}
375
+ >
376
+ <IconBrandGoogle className="size-3.5" />
377
+ {t("home.googleSlidesReferenceTitle")}
378
+ </Button>
379
+ <Button
380
+ type="button"
381
+ variant="ghost"
382
+ size="sm"
383
+ className="h-7 gap-1.5 px-2 text-xs text-muted-foreground hover:text-foreground"
384
+ disabled={importingSource !== null || loading || uploading}
385
+ onClick={() => pptxInputRef.current?.click()}
386
+ >
387
+ <IconPresentation className="size-3.5" />
388
+ PPT
389
+ </Button>
390
+ {importingSource && (
391
+ <span className="ml-auto text-xs text-muted-foreground">
392
+ {importingLabel}
393
+ </span>
394
+ )}
395
+ </div>
396
+ {googleSlidesInputOpen && (
397
+ <div className="mt-2 space-y-2">
398
+ <GoogleDriveConnectionCta />
399
+ <div className="flex gap-2">
400
+ <Input
401
+ autoFocus
402
+ type="url"
403
+ value={googleSlidesUrl}
404
+ placeholder={t("home.googleSlidesReferenceUrl")}
405
+ aria-label={t("home.googleSlidesReferenceUrl")}
406
+ className="h-8 text-xs"
407
+ disabled={importingSource !== null || loading || uploading}
408
+ onChange={(event) => setGoogleSlidesUrl(event.target.value)}
409
+ onKeyDown={(event) => {
410
+ if (event.key === "Enter") handleGoogleSlidesImport();
411
+ }}
412
+ />
413
+ <Button
414
+ type="button"
415
+ size="sm"
416
+ className="h-8 shrink-0 px-3 text-xs"
417
+ disabled={
418
+ !googleSlidesUrl.trim() ||
419
+ importingSource !== null ||
420
+ loading ||
421
+ uploading
422
+ }
423
+ onClick={handleGoogleSlidesImport}
424
+ >
425
+ Import
426
+ </Button>
427
+ </div>
428
+ </div>
429
+ )}
430
+ </div>
431
+ )}
432
+
260
433
  {children}
261
434
 
262
435
  <GoogleDocImportHint