@agent-native/core 0.118.0 → 0.118.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 (375) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +21 -0
  3. package/corpus/core/package.json +1 -1
  4. package/corpus/core/src/a2a/client.ts +32 -10
  5. package/corpus/core/src/cli/index.ts +18 -10
  6. package/corpus/core/src/cli/multi-frontier-runs.ts +5 -3
  7. package/corpus/core/src/cli/templates-meta.ts +0 -12
  8. package/corpus/core/src/cli/workspace-dev.ts +1 -1
  9. package/corpus/core/src/client/AgentPanel.tsx +9 -1
  10. package/corpus/core/src/client/RunStuckBanner.tsx +39 -47
  11. package/corpus/core/src/client/chat/action-chat-ui-surface.tsx +32 -0
  12. package/corpus/core/src/client/chat/message-components.tsx +53 -8
  13. package/corpus/core/src/client/chat/tool-call-display.tsx +24 -9
  14. package/corpus/core/src/client/chat/widgets/InlineExtensionWidget.tsx +0 -1
  15. package/corpus/core/src/client/chat/widgets/builtin-tool-renderers.tsx +7 -3
  16. package/corpus/core/src/client/conversation/AgentConversation.tsx +12 -1
  17. package/corpus/core/src/client/error-capture.ts +2 -6
  18. package/corpus/core/src/client/resources/McpConnectionSuggestion.tsx +20 -14
  19. package/corpus/core/src/client/resources/ResourcesPanel.tsx +5 -1
  20. package/corpus/core/src/client/resources/mcp-integration-catalog.ts +7 -17
  21. package/corpus/core/src/client/resources/mcp-integration-logos.ts +2 -2
  22. package/corpus/core/src/client/route-chunk-recovery.ts +5 -3
  23. package/corpus/core/src/client/session-replay.ts +3 -3
  24. package/corpus/core/src/client/settings/SettingsPanel.tsx +15 -6
  25. package/corpus/core/src/client/transcription/use-live-transcription.ts +64 -45
  26. package/corpus/core/src/deploy/build.ts +2 -1
  27. package/corpus/core/src/guards/db-tool-scoping.ts +1 -1
  28. package/corpus/core/src/integrations/adapters/slack.ts +84 -5
  29. package/corpus/core/src/integrations/index.ts +5 -1
  30. package/corpus/core/src/localization/default-messages.ts +1 -1
  31. package/corpus/core/src/mcp-client/oauth-routes.ts +45 -12
  32. package/corpus/core/src/server/realtime-voice.ts +4 -1
  33. package/corpus/core/src/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +7 -5
  34. package/corpus/core/src/terminal/cli-registry.ts +1 -1
  35. package/corpus/core/src/vite/client.ts +166 -1
  36. package/corpus/templates/analytics/app/hooks/use-dashboard-views.ts +13 -1
  37. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/ViewsMenu.tsx +10 -0
  38. package/corpus/templates/analytics/changelog/2026-07-22-show-a-useful-error-when-saving-a-dashboard-view-fails.md +6 -0
  39. package/corpus/templates/brain/app/routes/sources.tsx +181 -114
  40. package/corpus/templates/clips/AGENTS.md +8 -6
  41. package/corpus/templates/clips/actions/request-transcript.ts +90 -420
  42. package/corpus/templates/clips/actions/save-browser-transcript.ts +11 -28
  43. package/corpus/templates/clips/app/components/capture-install-options.tsx +5 -3
  44. package/corpus/templates/clips/app/components/player/transcript-panel.tsx +3 -136
  45. package/corpus/templates/clips/app/lib/capture-install-options.ts +15 -4
  46. package/corpus/templates/clips/app/routes/download.tsx +3 -2
  47. package/corpus/templates/clips/changelog/2026-07-22-fixed-an-intermittent-hydration-error-on-the-download-page.md +6 -0
  48. package/corpus/templates/clips/changelog/2026-07-22-fixed-transcript-generation-when-native-speech-capture-retur.md +6 -0
  49. package/corpus/templates/clips/changelog/2026-07-22-transcript-generation-now-retries-with-backup-speech-recogni.md +6 -0
  50. package/corpus/templates/clips/server/lib/public-agent-context.ts +2 -2
  51. package/corpus/templates/clips/server/register-secrets.ts +7 -6
  52. package/corpus/templates/content/app/components/editor/SlashCommandMenu.tsx +16 -84
  53. package/corpus/templates/content/app/components/editor/VisualEditor.tsx +13 -7
  54. package/corpus/templates/content/app/components/editor/extensions/ImageBlock.tsx +2 -2
  55. package/corpus/templates/content/app/i18n-data.ts +10 -0
  56. package/corpus/templates/design/server/lib/fig-file-decoder.ts +1 -0
  57. package/corpus/templates/plan/app/entry.client.tsx +3 -0
  58. package/corpus/templates/plan/changelog/2026-07-22-recover-stale-pages-after-a-deployment-refresh-automatically.md +6 -0
  59. package/corpus/templates/slides/app/hooks/use-agent-generating.ts +10 -3
  60. package/corpus/templates/slides/app/pages/Index.tsx +1 -0
  61. package/corpus/templates/slides/changelog/2026-07-22-new-deck-prompts-now-open-in-their-own-visible-chat-thread.md +6 -0
  62. package/corpus/toolkit/CHANGELOG.md +9 -0
  63. package/corpus/toolkit/package.json +1 -1
  64. package/corpus/toolkit/src/composer/PromptComposer.tsx +5 -1
  65. package/corpus/toolkit/src/composer/RealtimeVoiceMode.tsx +119 -31
  66. package/corpus/toolkit/src/composer/useRealtimeVoiceMode.tsx +30 -0
  67. package/corpus/toolkit/src/conformance/runner.tsx +153 -1
  68. package/corpus/toolkit/src/editor/SharedRichEditor.tsx +13 -2
  69. package/corpus/toolkit/src/editor/SlashCommandMenu.tsx +20 -0
  70. package/corpus/toolkit/src/editor/index.ts +2 -0
  71. package/corpus/toolkit/src/styles.css +52 -23
  72. package/dist/a2a/client.d.ts +3 -1
  73. package/dist/a2a/client.d.ts.map +1 -1
  74. package/dist/a2a/client.js +17 -12
  75. package/dist/a2a/client.js.map +1 -1
  76. package/dist/cli/index.js +18 -8
  77. package/dist/cli/index.js.map +1 -1
  78. package/dist/cli/multi-frontier-runs.js +3 -3
  79. package/dist/cli/multi-frontier-runs.js.map +1 -1
  80. package/dist/cli/templates-meta.d.ts.map +1 -1
  81. package/dist/cli/templates-meta.js +0 -12
  82. package/dist/cli/templates-meta.js.map +1 -1
  83. package/dist/cli/workspace-dev.js +1 -1
  84. package/dist/cli/workspace-dev.js.map +1 -1
  85. package/dist/client/AgentPanel.d.ts.map +1 -1
  86. package/dist/client/AgentPanel.js +4 -1
  87. package/dist/client/AgentPanel.js.map +1 -1
  88. package/dist/client/RunStuckBanner.d.ts +3 -5
  89. package/dist/client/RunStuckBanner.d.ts.map +1 -1
  90. package/dist/client/RunStuckBanner.js +17 -18
  91. package/dist/client/RunStuckBanner.js.map +1 -1
  92. package/dist/client/chat/action-chat-ui-surface.d.ts +8 -0
  93. package/dist/client/chat/action-chat-ui-surface.d.ts.map +1 -0
  94. package/dist/client/chat/action-chat-ui-surface.js +10 -0
  95. package/dist/client/chat/action-chat-ui-surface.js.map +1 -0
  96. package/dist/client/chat/message-components.d.ts +3 -0
  97. package/dist/client/chat/message-components.d.ts.map +1 -1
  98. package/dist/client/chat/message-components.js +40 -7
  99. package/dist/client/chat/message-components.js.map +1 -1
  100. package/dist/client/chat/tool-call-display.d.ts +3 -1
  101. package/dist/client/chat/tool-call-display.d.ts.map +1 -1
  102. package/dist/client/chat/tool-call-display.js +13 -9
  103. package/dist/client/chat/tool-call-display.js.map +1 -1
  104. package/dist/client/chat/widgets/InlineExtensionWidget.d.ts.map +1 -1
  105. package/dist/client/chat/widgets/InlineExtensionWidget.js +1 -1
  106. package/dist/client/chat/widgets/InlineExtensionWidget.js.map +1 -1
  107. package/dist/client/chat/widgets/builtin-tool-renderers.d.ts.map +1 -1
  108. package/dist/client/chat/widgets/builtin-tool-renderers.js +5 -3
  109. package/dist/client/chat/widgets/builtin-tool-renderers.js.map +1 -1
  110. package/dist/client/conversation/AgentConversation.d.ts.map +1 -1
  111. package/dist/client/conversation/AgentConversation.js +3 -2
  112. package/dist/client/conversation/AgentConversation.js.map +1 -1
  113. package/dist/client/error-capture.d.ts.map +1 -1
  114. package/dist/client/error-capture.js +2 -2
  115. package/dist/client/error-capture.js.map +1 -1
  116. package/dist/client/resources/McpConnectionSuggestion.d.ts +1 -0
  117. package/dist/client/resources/McpConnectionSuggestion.d.ts.map +1 -1
  118. package/dist/client/resources/McpConnectionSuggestion.js +9 -8
  119. package/dist/client/resources/McpConnectionSuggestion.js.map +1 -1
  120. package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
  121. package/dist/client/resources/ResourcesPanel.js +3 -1
  122. package/dist/client/resources/ResourcesPanel.js.map +1 -1
  123. package/dist/client/resources/mcp-integration-catalog.d.ts +1 -0
  124. package/dist/client/resources/mcp-integration-catalog.d.ts.map +1 -1
  125. package/dist/client/resources/mcp-integration-catalog.js +4 -17
  126. package/dist/client/resources/mcp-integration-catalog.js.map +1 -1
  127. package/dist/client/resources/mcp-integration-logos.js +2 -2
  128. package/dist/client/resources/mcp-integration-logos.js.map +1 -1
  129. package/dist/client/route-chunk-recovery.d.ts.map +1 -1
  130. package/dist/client/route-chunk-recovery.js +5 -3
  131. package/dist/client/route-chunk-recovery.js.map +1 -1
  132. package/dist/client/session-replay.js +3 -3
  133. package/dist/client/session-replay.js.map +1 -1
  134. package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
  135. package/dist/client/settings/SettingsPanel.js +2 -2
  136. package/dist/client/settings/SettingsPanel.js.map +1 -1
  137. package/dist/client/transcription/use-live-transcription.d.ts +3 -3
  138. package/dist/client/transcription/use-live-transcription.d.ts.map +1 -1
  139. package/dist/client/transcription/use-live-transcription.js +22 -11
  140. package/dist/client/transcription/use-live-transcription.js.map +1 -1
  141. package/dist/collab/routes.d.ts +1 -1
  142. package/dist/collab/struct-routes.d.ts +1 -1
  143. package/dist/deploy/build.d.ts.map +1 -1
  144. package/dist/deploy/build.js +1 -1
  145. package/dist/deploy/build.js.map +1 -1
  146. package/dist/guards/db-tool-scoping.js +1 -1
  147. package/dist/guards/db-tool-scoping.js.map +1 -1
  148. package/dist/integrations/adapters/slack.d.ts +1 -0
  149. package/dist/integrations/adapters/slack.d.ts.map +1 -1
  150. package/dist/integrations/adapters/slack.js +61 -5
  151. package/dist/integrations/adapters/slack.js.map +1 -1
  152. package/dist/integrations/index.d.ts +1 -1
  153. package/dist/integrations/index.d.ts.map +1 -1
  154. package/dist/integrations/index.js +1 -1
  155. package/dist/integrations/index.js.map +1 -1
  156. package/dist/localization/default-messages.js +1 -1
  157. package/dist/localization/default-messages.js.map +1 -1
  158. package/dist/mcp-client/oauth-routes.d.ts +3 -0
  159. package/dist/mcp-client/oauth-routes.d.ts.map +1 -1
  160. package/dist/mcp-client/oauth-routes.js +41 -12
  161. package/dist/mcp-client/oauth-routes.js.map +1 -1
  162. package/dist/notifications/routes.d.ts +2 -2
  163. package/dist/observability/routes.d.ts +3 -3
  164. package/dist/provider-api/actions/custom-provider-registration.d.ts +8 -8
  165. package/dist/provider-api/actions/provider-api.d.ts +11 -11
  166. package/dist/secrets/routes.d.ts +6 -6
  167. package/dist/server/realtime-voice.d.ts.map +1 -1
  168. package/dist/server/realtime-voice.js +1 -1
  169. package/dist/server/realtime-voice.js.map +1 -1
  170. package/dist/server/transcribe-voice.d.ts +1 -1
  171. package/dist/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +7 -5
  172. package/dist/terminal/cli-registry.js +1 -1
  173. package/dist/terminal/cli-registry.js.map +1 -1
  174. package/dist/vite/client.d.ts +8 -1
  175. package/dist/vite/client.d.ts.map +1 -1
  176. package/dist/vite/client.js +113 -2
  177. package/dist/vite/client.js.map +1 -1
  178. package/package.json +2 -2
  179. package/src/a2a/client.ts +32 -10
  180. package/src/cli/index.ts +18 -10
  181. package/src/cli/multi-frontier-runs.ts +5 -3
  182. package/src/cli/templates-meta.ts +0 -12
  183. package/src/cli/workspace-dev.ts +1 -1
  184. package/src/client/AgentPanel.tsx +9 -1
  185. package/src/client/RunStuckBanner.tsx +39 -47
  186. package/src/client/chat/action-chat-ui-surface.tsx +32 -0
  187. package/src/client/chat/message-components.tsx +53 -8
  188. package/src/client/chat/tool-call-display.tsx +24 -9
  189. package/src/client/chat/widgets/InlineExtensionWidget.tsx +0 -1
  190. package/src/client/chat/widgets/builtin-tool-renderers.tsx +7 -3
  191. package/src/client/conversation/AgentConversation.tsx +12 -1
  192. package/src/client/error-capture.ts +2 -6
  193. package/src/client/resources/McpConnectionSuggestion.tsx +20 -14
  194. package/src/client/resources/ResourcesPanel.tsx +5 -1
  195. package/src/client/resources/mcp-integration-catalog.ts +7 -17
  196. package/src/client/resources/mcp-integration-logos.ts +2 -2
  197. package/src/client/route-chunk-recovery.ts +5 -3
  198. package/src/client/session-replay.ts +3 -3
  199. package/src/client/settings/SettingsPanel.tsx +15 -6
  200. package/src/client/transcription/use-live-transcription.ts +64 -45
  201. package/src/deploy/build.ts +2 -1
  202. package/src/guards/db-tool-scoping.ts +1 -1
  203. package/src/integrations/adapters/slack.ts +84 -5
  204. package/src/integrations/index.ts +5 -1
  205. package/src/localization/default-messages.ts +1 -1
  206. package/src/mcp-client/oauth-routes.ts +45 -12
  207. package/src/server/realtime-voice.ts +4 -1
  208. package/src/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +7 -5
  209. package/src/terminal/cli-registry.ts +1 -1
  210. package/src/vite/client.ts +166 -1
  211. package/corpus/templates/crm/.agents/skills/agent-native-docs/SKILL.md +0 -115
  212. package/corpus/templates/crm/.agents/skills/agent-native-toolkit/SKILL.md +0 -177
  213. package/corpus/templates/crm/.agents/skills/crm/SKILL.md +0 -128
  214. package/corpus/templates/crm/.agents/skills/customizing-agent-native/SKILL.md +0 -220
  215. package/corpus/templates/crm/.agents/skills/feature-flags/SKILL.md +0 -169
  216. package/corpus/templates/crm/.agents/skills/upgrade-agent-native/SKILL.md +0 -100
  217. package/corpus/templates/crm/.env.example +0 -5
  218. package/corpus/templates/crm/AGENTS.md +0 -120
  219. package/corpus/templates/crm/CHANGELOG.md +0 -1
  220. package/corpus/templates/crm/DEVELOPING.md +0 -66
  221. package/corpus/templates/crm/README.md +0 -106
  222. package/corpus/templates/crm/_gitignore +0 -12
  223. package/corpus/templates/crm/actions/_crm-action-utils.ts +0 -87
  224. package/corpus/templates/crm/actions/_crm-dashboard.ts +0 -69
  225. package/corpus/templates/crm/actions/_crm-data-program-actions.ts +0 -15
  226. package/corpus/templates/crm/actions/_crm-signal-utils.ts +0 -79
  227. package/corpus/templates/crm/actions/apply-crm-proposals.ts +0 -203
  228. package/corpus/templates/crm/actions/attach-call-evidence.ts +0 -170
  229. package/corpus/templates/crm/actions/configure-crm-connection.ts +0 -126
  230. package/corpus/templates/crm/actions/configure-native-crm.ts +0 -44
  231. package/corpus/templates/crm/actions/create-crm-record.ts +0 -148
  232. package/corpus/templates/crm/actions/create-crm-signal-tracker.ts +0 -58
  233. package/corpus/templates/crm/actions/delete-staged-dataset.ts +0 -14
  234. package/corpus/templates/crm/actions/get-crm-automation-recipe.ts +0 -36
  235. package/corpus/templates/crm/actions/get-crm-dashboard-panel.ts +0 -35
  236. package/corpus/templates/crm/actions/get-crm-dashboard.ts +0 -14
  237. package/corpus/templates/crm/actions/get-crm-overview.ts +0 -13
  238. package/corpus/templates/crm/actions/get-crm-pipeline-data.ts +0 -61
  239. package/corpus/templates/crm/actions/get-crm-record.ts +0 -75
  240. package/corpus/templates/crm/actions/install-crm-pipeline-dashboard.ts +0 -81
  241. package/corpus/templates/crm/actions/list-crm-dashboard-revisions.ts +0 -15
  242. package/corpus/templates/crm/actions/list-crm-dashboards.ts +0 -15
  243. package/corpus/templates/crm/actions/list-crm-proposals.ts +0 -31
  244. package/corpus/templates/crm/actions/list-crm-records.ts +0 -79
  245. package/corpus/templates/crm/actions/list-crm-saved-views.ts +0 -15
  246. package/corpus/templates/crm/actions/list-crm-signal-hits.ts +0 -43
  247. package/corpus/templates/crm/actions/list-crm-signal-trackers.ts +0 -32
  248. package/corpus/templates/crm/actions/list-crm-tasks.ts +0 -22
  249. package/corpus/templates/crm/actions/list-staged-datasets.ts +0 -14
  250. package/corpus/templates/crm/actions/list-workspace-connections.ts +0 -47
  251. package/corpus/templates/crm/actions/manage-crm-signal-tracker.ts +0 -87
  252. package/corpus/templates/crm/actions/manage-crm-task.ts +0 -132
  253. package/corpus/templates/crm/actions/navigate.ts +0 -63
  254. package/corpus/templates/crm/actions/provider-api-catalog.ts +0 -22
  255. package/corpus/templates/crm/actions/provider-api-docs.ts +0 -54
  256. package/corpus/templates/crm/actions/provider-api-request.ts +0 -92
  257. package/corpus/templates/crm/actions/query-staged-dataset.ts +0 -44
  258. package/corpus/templates/crm/actions/record-crm-call-insight.ts +0 -160
  259. package/corpus/templates/crm/actions/record-crm-smart-signal.ts +0 -150
  260. package/corpus/templates/crm/actions/restore-crm-dashboard-revision.ts +0 -23
  261. package/corpus/templates/crm/actions/review-crm-signal.ts +0 -31
  262. package/corpus/templates/crm/actions/run-crm-saved-view-program.ts +0 -103
  263. package/corpus/templates/crm/actions/run-crm-signal-trackers.ts +0 -275
  264. package/corpus/templates/crm/actions/run.ts +0 -7
  265. package/corpus/templates/crm/actions/save-crm-dashboard.ts +0 -51
  266. package/corpus/templates/crm/actions/save-crm-saved-view.ts +0 -119
  267. package/corpus/templates/crm/actions/sync-crm.ts +0 -146
  268. package/corpus/templates/crm/actions/update-crm-record.ts +0 -510
  269. package/corpus/templates/crm/actions/view-screen.ts +0 -218
  270. package/corpus/templates/crm/agent-native.app-skill.json +0 -58
  271. package/corpus/templates/crm/app/components/crm/CreateCrmRecordDialog.tsx +0 -158
  272. package/corpus/templates/crm/app/components/crm/CrmDashboardPanel.tsx +0 -78
  273. package/corpus/templates/crm/app/components/crm/CrmSignalsPanel.tsx +0 -226
  274. package/corpus/templates/crm/app/components/crm/IntelligenceSettings.tsx +0 -414
  275. package/corpus/templates/crm/app/components/crm/RecordActions.tsx +0 -510
  276. package/corpus/templates/crm/app/components/crm/RecordGrid.tsx +0 -134
  277. package/corpus/templates/crm/app/components/crm/RecordWorkspace.tsx +0 -362
  278. package/corpus/templates/crm/app/components/crm/SavedViewDataProgram.tsx +0 -93
  279. package/corpus/templates/crm/app/components/crm/Surface.tsx +0 -97
  280. package/corpus/templates/crm/app/components/crm/WorkOverview.tsx +0 -180
  281. package/corpus/templates/crm/app/components/layout/CrmLayout.tsx +0 -112
  282. package/corpus/templates/crm/app/components/layout/CrmSidebar.tsx +0 -84
  283. package/corpus/templates/crm/app/components/ui/alert-dialog.tsx +0 -1
  284. package/corpus/templates/crm/app/components/ui/badge.tsx +0 -1
  285. package/corpus/templates/crm/app/components/ui/button.tsx +0 -1
  286. package/corpus/templates/crm/app/components/ui/card.tsx +0 -1
  287. package/corpus/templates/crm/app/components/ui/dialog.tsx +0 -1
  288. package/corpus/templates/crm/app/components/ui/input.tsx +0 -1
  289. package/corpus/templates/crm/app/components/ui/label.tsx +0 -1
  290. package/corpus/templates/crm/app/components/ui/select.tsx +0 -1
  291. package/corpus/templates/crm/app/components/ui/sheet.tsx +0 -1
  292. package/corpus/templates/crm/app/components/ui/skeleton.tsx +0 -1
  293. package/corpus/templates/crm/app/components/ui/switch.tsx +0 -1
  294. package/corpus/templates/crm/app/components/ui/table.tsx +0 -1
  295. package/corpus/templates/crm/app/components/ui/tabs.tsx +0 -1
  296. package/corpus/templates/crm/app/components/ui/textarea.tsx +0 -1
  297. package/corpus/templates/crm/app/components/ui/toolkit-provider.tsx +0 -17
  298. package/corpus/templates/crm/app/design-system.ts +0 -3
  299. package/corpus/templates/crm/app/entry.client.tsx +0 -16
  300. package/corpus/templates/crm/app/entry.server.tsx +0 -10
  301. package/corpus/templates/crm/app/global.css +0 -167
  302. package/corpus/templates/crm/app/hooks/use-navigation-state.ts +0 -60
  303. package/corpus/templates/crm/app/i18n/en-US.ts +0 -89
  304. package/corpus/templates/crm/app/i18n/index.ts +0 -34
  305. package/corpus/templates/crm/app/lib/dashboard.ts +0 -13
  306. package/corpus/templates/crm/app/lib/navigation.ts +0 -54
  307. package/corpus/templates/crm/app/lib/tab-id.ts +0 -1
  308. package/corpus/templates/crm/app/lib/types.ts +0 -172
  309. package/corpus/templates/crm/app/lib/utils.ts +0 -1
  310. package/corpus/templates/crm/app/root.tsx +0 -91
  311. package/corpus/templates/crm/app/routes/_index.tsx +0 -26
  312. package/corpus/templates/crm/app/routes/accounts.tsx +0 -41
  313. package/corpus/templates/crm/app/routes/agent.tsx +0 -5
  314. package/corpus/templates/crm/app/routes/ask.tsx +0 -53
  315. package/corpus/templates/crm/app/routes/dashboard.tsx +0 -118
  316. package/corpus/templates/crm/app/routes/opportunities.tsx +0 -41
  317. package/corpus/templates/crm/app/routes/people.tsx +0 -41
  318. package/corpus/templates/crm/app/routes/proposals.tsx +0 -266
  319. package/corpus/templates/crm/app/routes/records.$recordId.tsx +0 -35
  320. package/corpus/templates/crm/app/routes/settings.tsx +0 -63
  321. package/corpus/templates/crm/app/routes/setup.tsx +0 -308
  322. package/corpus/templates/crm/app/routes/tasks.tsx +0 -252
  323. package/corpus/templates/crm/app/routes/views.tsx +0 -333
  324. package/corpus/templates/crm/app/routes.ts +0 -17
  325. package/corpus/templates/crm/app/vite-env.d.ts +0 -6
  326. package/corpus/templates/crm/changelog/2026-07-21-agent-native-crm.md +0 -6
  327. package/corpus/templates/crm/changelog/2026-07-21-clips-call-evidence-review-recipe.md +0 -6
  328. package/corpus/templates/crm/changelog/2026-07-21-crm-can-now-find-and-review-evidence-grounded-call-signals-w.md +0 -6
  329. package/corpus/templates/crm/changelog/2026-07-21-crm-can-now-manage-keyword-and-smart-call-signal-trackers-fr.md +0 -6
  330. package/corpus/templates/crm/changelog/2026-07-21-delegated-local-crm-automation.md +0 -6
  331. package/corpus/templates/crm/changelog/2026-07-21-native-sql.md +0 -6
  332. package/corpus/templates/crm/changelog/2026-07-21-pipeline-dashboard.md +0 -6
  333. package/corpus/templates/crm/changelog/2026-07-21-pipeline-dashboards-now-install-correctly-from-the-crm-actio.md +0 -6
  334. package/corpus/templates/crm/changelog/2026-07-21-salesforce-connection.md +0 -6
  335. package/corpus/templates/crm/changelog/2026-07-22-crm-field-validation-now-explains-which-fields-cannot-be-edi.md +0 -6
  336. package/corpus/templates/crm/changelog/2026-07-22-fixed-hubspot-contact-syncs-missing-records-updated-after-th.md +0 -6
  337. package/corpus/templates/crm/changelog/2026-07-22-fixed-pipeline-dashboard-panels-so-their-opportunity-data-lo.md +0 -6
  338. package/corpus/templates/crm/changelog/2026-07-22-full-page-chat-keeps-the-active-conversation-when-moving-to-.md +0 -6
  339. package/corpus/templates/crm/components.json +0 -20
  340. package/corpus/templates/crm/docs/architecture/crm-contract.md +0 -180
  341. package/corpus/templates/crm/learnings.defaults.md +0 -5
  342. package/corpus/templates/crm/package.json +0 -59
  343. package/corpus/templates/crm/public/favicon.svg +0 -1
  344. package/corpus/templates/crm/public/icon-180.svg +0 -1
  345. package/corpus/templates/crm/public/manifest.json +0 -11
  346. package/corpus/templates/crm/react-router.config.ts +0 -7
  347. package/corpus/templates/crm/server/crm/adapter.ts +0 -32
  348. package/corpus/templates/crm/server/crm/crm-field-firewall.ts +0 -64
  349. package/corpus/templates/crm/server/crm/crm-mirror.ts +0 -711
  350. package/corpus/templates/crm/server/crm/hubspot-adapter.ts +0 -1146
  351. package/corpus/templates/crm/server/crm/native-adapter.ts +0 -1715
  352. package/corpus/templates/crm/server/crm/read-through.ts +0 -207
  353. package/corpus/templates/crm/server/crm/salesforce-adapter.ts +0 -1255
  354. package/corpus/templates/crm/server/db/crm-store.ts +0 -1170
  355. package/corpus/templates/crm/server/db/index.ts +0 -169
  356. package/corpus/templates/crm/server/db/schema.ts +0 -441
  357. package/corpus/templates/crm/server/lib/intelligence/default-detectors.ts +0 -65
  358. package/corpus/templates/crm/server/lib/intelligence/evidence.ts +0 -105
  359. package/corpus/templates/crm/server/lib/intelligence/keyword-detector.ts +0 -100
  360. package/corpus/templates/crm/server/lib/intelligence/smart-detector.ts +0 -144
  361. package/corpus/templates/crm/server/lib/intelligence/summary.ts +0 -141
  362. package/corpus/templates/crm/server/lib/provider-api.ts +0 -64
  363. package/corpus/templates/crm/server/middleware/auth.ts +0 -4
  364. package/corpus/templates/crm/server/plugins/agent-chat.ts +0 -68
  365. package/corpus/templates/crm/server/plugins/auth.ts +0 -14
  366. package/corpus/templates/crm/server/plugins/core-routes.ts +0 -17
  367. package/corpus/templates/crm/server/plugins/db.ts +0 -454
  368. package/corpus/templates/crm/server/routes/[...page].get.ts +0 -5
  369. package/corpus/templates/crm/shared/crm-automation-recipes.ts +0 -132
  370. package/corpus/templates/crm/shared/crm-contract.ts +0 -254
  371. package/corpus/templates/crm/shared/crm-sales-config.ts +0 -63
  372. package/corpus/templates/crm/ssr-entry.ts +0 -11
  373. package/corpus/templates/crm/tsconfig.json +0 -24
  374. package/corpus/templates/crm/vite.config.ts +0 -15
  375. package/corpus/templates/crm/vitest.config.ts +0 -5
@@ -18,10 +18,10 @@ import {
18
18
  } from "@/components/ui/popover";
19
19
  import {
20
20
  attemptOpenDesktopApp,
21
- clipsChromeExtensionEnabled,
22
21
  clipsChromeExtensionUrl,
23
22
  hasDownloadedDesktopApp,
24
23
  subscribeDownloaded,
24
+ useClipsChromeExtensionEnabled,
25
25
  } from "@/lib/capture-install-options";
26
26
  import { cn } from "@/lib/utils";
27
27
 
@@ -136,6 +136,7 @@ export function CaptureInstallButton({
136
136
  ...buttonProps
137
137
  }: CaptureInstallButtonProps) {
138
138
  const downloaded = useHasDownloadedDesktopApp();
139
+ const chromeExtensionEnabled = useClipsChromeExtensionEnabled();
139
140
  const label = downloaded ? (downloadedChildren ?? children) : children;
140
141
 
141
142
  if (downloaded) {
@@ -155,7 +156,7 @@ export function CaptureInstallButton({
155
156
  );
156
157
  }
157
158
 
158
- if (!clipsChromeExtensionEnabled) {
159
+ if (!chromeExtensionEnabled) {
159
160
  return (
160
161
  <Button asChild className={className} {...buttonProps}>
161
162
  <a href={appPath(desktopHref)}>{label}</a>
@@ -187,6 +188,7 @@ export function CaptureInstallInlineLink({
187
188
  side = "bottom",
188
189
  }: CaptureInstallInlineLinkProps) {
189
190
  const downloaded = useHasDownloadedDesktopApp();
191
+ const chromeExtensionEnabled = useClipsChromeExtensionEnabled();
190
192
 
191
193
  const label = downloaded ? (downloadedChildren ?? children) : children;
192
194
 
@@ -202,7 +204,7 @@ export function CaptureInstallInlineLink({
202
204
  );
203
205
  }
204
206
 
205
- if (!clipsChromeExtensionEnabled) {
207
+ if (!chromeExtensionEnabled) {
206
208
  return (
207
209
  <a href={appPath(desktopHref)} className={className}>
208
210
  {label}
@@ -11,11 +11,8 @@ import {
11
11
  IconDownload,
12
12
  IconCheck,
13
13
  IconExternalLink,
14
- IconKey,
15
14
  IconLoader2,
16
15
  IconBolt,
17
- IconChevronDown,
18
- IconChevronUp,
19
16
  IconRefresh,
20
17
  } from "@tabler/icons-react";
21
18
  import { useCallback, useEffect, useMemo, useRef, useState } from "react";
@@ -489,7 +486,6 @@ function isTranscriptionSetupNeeded(
489
486
  const r = reason.toLowerCase();
490
487
  return (
491
488
  r.includes("openai_api_key") ||
492
- r.includes("groq_api_key") ||
493
489
  r.includes("api key") ||
494
490
  r.includes("not configured") ||
495
491
  r.includes("no transcription") ||
@@ -579,10 +575,9 @@ function friendlyCleanupFailure(
579
575
  /**
580
576
  * Inline card shown when transcription needs a provider set up.
581
577
  *
582
- * Builder.io is the primary/recommended path — free, one-click, no separate
583
- * API key required (uses BUILDER_PRIVATE_KEY once the user connects).
584
- * BYOK Groq is the secondary speech-to-text option when native/Builder cannot
585
- * produce a transcript. Clips does not route recording transcription to OpenAI.
578
+ * Builder.io is the only cloud fallback — free, one-click, no separate API
579
+ * key required (uses BUILDER_PRIVATE_KEY once the user connects). Clips does
580
+ * not route recording transcription to BYOK speech providers.
586
581
  */
587
582
  function TranscriptSetupCard({
588
583
  failureReason,
@@ -600,14 +595,6 @@ function TranscriptSetupCard({
600
595
  const pollRef = useRef<ReturnType<typeof setInterval> | null>(null);
601
596
  const mountedRef = useRef(true);
602
597
 
603
- const [showByok, setShowByok] = useState(false);
604
- const [apiKey, setApiKey] = useState("");
605
- const [saving, setSaving] = useState(false);
606
- const [saveToast, setSaveToast] = useState<{
607
- kind: "ok" | "err";
608
- text: string;
609
- } | null>(null);
610
- const toastTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
611
598
  const autoRetryRef = useRef(false);
612
599
  const onRetryRef = useRef(onRetry);
613
600
 
@@ -630,7 +617,6 @@ function TranscriptSetupCard({
630
617
  return () => {
631
618
  mountedRef.current = false;
632
619
  if (pollRef.current) clearInterval(pollRef.current);
633
- if (toastTimerRef.current) clearTimeout(toastTimerRef.current);
634
620
  };
635
621
  }, []);
636
622
 
@@ -675,44 +661,6 @@ function TranscriptSetupCard({
675
661
  }, 2000);
676
662
  }, [onRetry]);
677
663
 
678
- async function saveApiKey() {
679
- if (!apiKey.trim() || saving) return;
680
- setSaving(true);
681
- try {
682
- const res = await fetch(
683
- agentNativePath("/_agent-native/secrets/GROQ_API_KEY"),
684
- {
685
- method: "POST",
686
- headers: { "Content-Type": "application/json" },
687
- body: JSON.stringify({ value: apiKey.trim() }),
688
- },
689
- );
690
- if (!mountedRef.current) return;
691
- if (!res.ok) {
692
- const err = await res
693
- .json()
694
- .then((j: { error?: string }) => j.error)
695
- .catch(() => null);
696
- if (!mountedRef.current) return;
697
- setSaveToast({
698
- kind: "err",
699
- text: err ?? t("transcriptPanel.saveFailed", { status: res.status }),
700
- });
701
- return;
702
- }
703
- setApiKey("");
704
- setSaveToast({ kind: "ok", text: t("transcriptPanel.savedRetrying") });
705
- onRetry?.();
706
- if (toastTimerRef.current) clearTimeout(toastTimerRef.current);
707
- toastTimerRef.current = setTimeout(() => {
708
- if (mountedRef.current) setSaveToast(null);
709
- toastTimerRef.current = null;
710
- }, 2500);
711
- } finally {
712
- if (mountedRef.current) setSaving(false);
713
- }
714
- }
715
-
716
664
  const isProviderError =
717
665
  !isBuilderCreditsExhaustedMessage(failureReason) &&
718
666
  (failureReason?.toLowerCase().includes("quota") ||
@@ -817,87 +765,6 @@ function TranscriptSetupCard({
817
765
  <p className="text-[11px] text-destructive mt-2">{connectError}</p>
818
766
  )}
819
767
  </div>
820
-
821
- {/* BYOK — secondary option, collapsed by default. Shown even when
822
- Builder is connected so users can fall back if Builder
823
- transcription itself fails (quota / outage / unsupported audio
824
- format) — the failure message tells them to add a key, so the
825
- input must be reachable. */}
826
- <div>
827
- <button
828
- type="button"
829
- onClick={() => setShowByok((v) => !v)}
830
- className="inline-flex items-center gap-1 text-xs text-muted-foreground hover:text-foreground transition-colors"
831
- >
832
- <IconKey className="h-3.5 w-3.5" />
833
- {isProviderError
834
- ? "Update your API key"
835
- : builderConfigured
836
- ? "Advanced backup option"
837
- : "Or use your own Groq key"}
838
- {showByok ? (
839
- <IconChevronUp className="h-3 w-3" />
840
- ) : (
841
- <IconChevronDown className="h-3 w-3" />
842
- )}
843
- </button>
844
-
845
- {showByok && (
846
- <div className="mt-2 space-y-2 pl-1">
847
- <p className="text-[11px] text-muted-foreground">
848
- {t("transcriptPanel.groqKeysStart")}{" "}
849
- <code className="font-mono">gsk_</code>.{" "}
850
- {t("transcriptPanel.nativeSpeechPrimary")}
851
- </p>
852
- <div className="flex gap-1.5">
853
- <Input
854
- type="password"
855
- value={apiKey}
856
- onChange={(e) => setApiKey(e.target.value)}
857
- onKeyDown={(e) => {
858
- if (e.key === "Enter") saveApiKey();
859
- }}
860
- placeholder="gsk_…"
861
- className="h-8 text-xs"
862
- />
863
- <Button
864
- size="sm"
865
- onClick={saveApiKey}
866
- disabled={!apiKey.trim() || saving}
867
- >
868
- {saving ? (
869
- <IconLoader2 className="h-3.5 w-3.5 animate-spin" />
870
- ) : (
871
- t("common.save")
872
- )}
873
- </Button>
874
- </div>
875
- <div className="flex items-center gap-3">
876
- <a
877
- href="https://console.groq.com/keys"
878
- target="_blank"
879
- rel="noopener noreferrer"
880
- className="inline-flex items-center gap-1 text-[11px] text-muted-foreground hover:text-foreground"
881
- >
882
- {t("transcriptPanel.getGroqKey")}
883
- <IconExternalLink className="h-3 w-3" />
884
- </a>
885
- </div>
886
- {saveToast && (
887
- <p
888
- className={cn(
889
- "text-[11px]",
890
- saveToast.kind === "ok"
891
- ? "text-green-600"
892
- : "text-destructive",
893
- )}
894
- >
895
- {saveToast.text}
896
- </p>
897
- )}
898
- </div>
899
- )}
900
- </div>
901
768
  </div>
902
769
  </div>
903
770
  );
@@ -1,4 +1,5 @@
1
1
  import { appPath } from "@agent-native/core/client/api-path";
2
+ import { useEffect, useState } from "react";
2
3
 
3
4
  const DESKTOP_PROMO_DISMISSED_STORAGE_KEY = "clips.desktop-promo.dismissed";
4
5
  const DESKTOP_DOWNLOADED_STORAGE_KEY = "clips.desktop-app.downloaded";
@@ -146,9 +147,19 @@ const chromeExtensionUrl =
146
147
 
147
148
  // The published extension manifest only trusts first-party Clips/local origins.
148
149
  // Custom deployments can opt in after publishing a matching extension/listing.
149
- export const clipsChromeExtensionEnabled = resolveClipsChromeExtensionEnabled({
150
- enabledSetting: import.meta.env.VITE_CLIPS_CHROME_EXTENSION_ENABLED,
151
- hostname: getCurrentHostname(),
152
- });
150
+ export function useClipsChromeExtensionEnabled(): boolean {
151
+ const [enabled, setEnabled] = useState(false);
152
+
153
+ useEffect(() => {
154
+ setEnabled(
155
+ resolveClipsChromeExtensionEnabled({
156
+ enabledSetting: import.meta.env.VITE_CLIPS_CHROME_EXTENSION_ENABLED,
157
+ hostname: getCurrentHostname(),
158
+ }),
159
+ );
160
+ }, []);
161
+
162
+ return enabled;
163
+ }
153
164
 
154
165
  export const clipsChromeExtensionUrl = chromeExtensionUrl || null;
@@ -13,9 +13,9 @@ import { Button } from "@/components/ui/button";
13
13
  import { Skeleton } from "@/components/ui/skeleton";
14
14
  import enMessages from "@/i18n/en-US";
15
15
  import {
16
- clipsChromeExtensionEnabled,
17
16
  clipsChromeExtensionUrl,
18
17
  markDesktopAppDownloaded,
18
+ useClipsChromeExtensionEnabled,
19
19
  } from "@/lib/capture-install-options";
20
20
 
21
21
  export function meta() {
@@ -179,6 +179,7 @@ function secondaryDownloadButton(
179
179
  }
180
180
 
181
181
  export default function DownloadPage() {
182
+ const chromeExtensionEnabled = useClipsChromeExtensionEnabled();
182
183
  const t = useT();
183
184
  const [manifest, setManifest] = useState<Manifest | null>(null);
184
185
  const [manifestError, setManifestError] = useState(false);
@@ -283,7 +284,7 @@ export default function DownloadPage() {
283
284
  </div>
284
285
  </div>
285
286
 
286
- {clipsChromeExtensionEnabled && (
287
+ {chromeExtensionEnabled && (
287
288
  <section className="mt-10 w-full max-w-xl rounded-2xl border border-border bg-card p-4 text-start shadow-sm">
288
289
  <div className="flex items-start gap-3">
289
290
  <div className="flex h-9 w-9 shrink-0 items-center justify-center rounded-xl bg-primary/10 text-primary">
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-07-22
4
+ ---
5
+
6
+ Fixed an intermittent hydration error on the download page
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-07-22
4
+ ---
5
+
6
+ Fixed transcript generation when native speech capture returns empty text.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-07-22
4
+ ---
5
+
6
+ Native browser/OS transcripts now remain primary, with Builder transcribing the original recording only when native speech capture is unavailable.
@@ -497,13 +497,13 @@ export function transcriptStatusInstructions(
497
497
 
498
498
  if (status === "failed" && lowerReason.includes("credits exhausted")) {
499
499
  return [
500
- "Transcription failed because Builder transcription credits are exhausted. Tell the user to upgrade or connect Builder.io credits, or configure a Groq key for backup speech-to-text. Generic OpenAI or Anthropic chat keys do not transcribe Clips recordings.",
500
+ "Transcription failed because Builder transcription credits are exhausted. Tell the user to upgrade or connect Builder.io credits. Clips uses the browser/macOS native transcript first and Builder transcription on the original recording when native capture is unavailable.",
501
501
  ];
502
502
  }
503
503
 
504
504
  if (status === "failed" && failureReason) {
505
505
  return [
506
- `Transcription failed with reason: ${failureReason}. Explain this to the user and suggest retrying transcription or configuring the supported Builder.io/Groq transcription fallback.`,
506
+ `Transcription failed with reason: ${failureReason}. Explain this to the user and suggest retrying native capture or the Builder transcription fallback.`,
507
507
  ];
508
508
  }
509
509
 
@@ -7,13 +7,14 @@ import { registerRequiredSecret } from "@agent-native/core/secrets";
7
7
  // run in a separate Vite SSR module graph and write to a different Map.
8
8
 
9
9
  // ── Transcription secrets (optional) ──────────────────────────────────
10
- // Native web/macOS speech is the primary transcript source. Gemini is used
11
- // for cleanup and titles after native text exists; Groq is the only BYOK
12
- // speech-to-text fallback when native transcription is unavailable.
10
+ // Native web/macOS speech is the primary recording transcript source. Builder
11
+ // is the only cloud fallback for a saved recording. Gemini/Groq BYOK remain
12
+ // available for desktop voice dictation and other provider-specific tools.
13
13
  //
14
14
  // We support two BYOK providers:
15
15
  // 1. Gemini — recommended for fast LLM cleanup in the desktop tray.
16
- // 2. Groq `whisper-large-v3-turbo` fast speech-to-text fallback.
16
+ // 2. Groq — optional voice-dictation provider, not a recording transcript
17
+ // fallback.
17
18
  //
18
19
  // Neither is strictly required — videos still upload and play back without
19
20
  // cloud transcription.
@@ -110,9 +111,9 @@ registerRequiredSecret({
110
111
 
111
112
  registerRequiredSecret({
112
113
  key: "GROQ_API_KEY",
113
- label: "Groq API Key (recommended)",
114
+ label: "Groq API Key (voice dictation)",
114
115
  description:
115
- "Fast speech-to-text fallback via Groq. Builder Gemini Flash-Lite is preferred when connected; Groq is used only when Builder/native transcription is unavailable.",
116
+ "Optional speech-to-text provider for desktop voice dictation. Clips recording transcripts use native browser/macOS capture first and Builder transcription for the saved recording fallback.",
116
117
  docsUrl: "https://console.groq.com/keys",
117
118
  scope: "user",
118
119
  kind: "api-key",
@@ -1,4 +1,5 @@
1
1
  import { useSendToAgentChat } from "@agent-native/core/client/agent-chat";
2
+ import { PromptComposer } from "@agent-native/core/client/composer";
2
3
  import { useT } from "@agent-native/core/client/i18n";
3
4
  import type { CreateInlineDatabaseResponse } from "@shared/api";
4
5
  import { renderMathToHtml } from "@shared/math-rendering";
@@ -20,8 +21,7 @@ import {
20
21
  IconCode,
21
22
  IconMinus,
22
23
  IconTable as TableIcon,
23
- IconWand,
24
- IconArrowUp,
24
+ IconHierarchy2,
25
25
  IconInfoCircle,
26
26
  IconMusic,
27
27
  IconPhoto,
@@ -218,18 +218,6 @@ export function parseInlineGeneratePrompt(textBeforeCursor: string) {
218
218
  return prompt || null;
219
219
  }
220
220
 
221
- export function shouldOpenGenerateOnSpace(editor: Editor) {
222
- const { selection } = editor.state;
223
- if (!selection.empty) return false;
224
-
225
- const { $from } = selection;
226
- if (!$from.parent.isTextblock) return false;
227
- if ($from.parent.type.name !== "paragraph") return false;
228
- if ($from.parentOffset !== 0) return false;
229
-
230
- return $from.parent.textContent.trim().length === 0;
231
- }
232
-
233
221
  export function parseSlashCommandQuery(textBeforeCursor: string) {
234
222
  return textBeforeCursor.match(/^\s*\/([a-zA-Z0-9]*)$/)?.[1] ?? null;
235
223
  }
@@ -505,7 +493,7 @@ export function SlashCommandMenu({
505
493
  onDraftPersisted,
506
494
  }: SlashCommandMenuProps) {
507
495
  const t = useT();
508
- const { send } = useSendToAgentChat();
496
+ const { send, isGenerating } = useSendToAgentChat();
509
497
  const navigate = useNavigate();
510
498
  const createPage = useCreatePage({ navigate: false, awaitPersist: true });
511
499
  const createInlineDatabase = useCreateInlineContentDatabase(
@@ -523,11 +511,9 @@ export function SlashCommandMenu({
523
511
 
524
512
  // Generate prompt popover state
525
513
  const [generateOpen, setGenerateOpen] = useState(false);
526
- const [generatePrompt, setGeneratePrompt] = useState("");
527
514
  const [generatePos, setGeneratePos] = useState<EditorMenuPosition | null>(
528
515
  null,
529
516
  );
530
- const generateTextareaRef = useRef<HTMLTextAreaElement>(null);
531
517
 
532
518
  const [equationDraft, setEquationDraft] = useState<EquationDraft | null>(
533
519
  null,
@@ -552,6 +538,7 @@ export function SlashCommandMenu({
552
538
  send({
553
539
  message: trimmed,
554
540
  context: `The user is asking you to generate content for their document (id: ${documentId}). Use the update-document action to write the generated markdown content. Do NOT use db-exec or raw SQL - use \`update-document --id ${documentId} --content "..."\` (and \`--title\` if appropriate).${content ? `\n\nCurrent document content:\n${content}` : "\n\nThe document is currently empty."}`,
541
+ submit: true,
555
542
  });
556
543
  },
557
544
  [documentId, editor, send, t],
@@ -576,9 +563,7 @@ export function SlashCommandMenu({
576
563
  if (!nextPosition) return false;
577
564
 
578
565
  setGeneratePos(nextPosition);
579
- setGeneratePrompt("");
580
566
  setGenerateOpen(true);
581
- setTimeout(() => generateTextareaRef.current?.focus(), 0);
582
567
  return true;
583
568
  },
584
569
  [getSelectionMenuPosition],
@@ -602,7 +587,7 @@ export function SlashCommandMenu({
602
587
  const generateCommand: CommandItem = {
603
588
  title: t("editor.slash.generate"),
604
589
  description: t("editor.slash.generateDescription"),
605
- icon: IconWand,
590
+ icon: IconHierarchy2,
606
591
  action: () => {
607
592
  openGeneratePopover(position);
608
593
  },
@@ -912,10 +897,6 @@ export function SlashCommandMenu({
912
897
  );
913
898
  };
914
899
 
915
- function handleGenerateSubmit() {
916
- submitGeneratePrompt(generatePrompt);
917
- }
918
-
919
900
  const executeCommand = useCallback(
920
901
  async (cmd: CommandItem) => {
921
902
  const slashRange =
@@ -940,25 +921,6 @@ export function SlashCommandMenu({
940
921
 
941
922
  const handleKeyDown = (e: KeyboardEvent) => {
942
923
  if (!isOpen) {
943
- if (
944
- (e.key === " " || e.code === "Space") &&
945
- !e.shiftKey &&
946
- !e.metaKey &&
947
- !e.ctrlKey &&
948
- !e.altKey &&
949
- editor.isFocused &&
950
- shouldOpenGenerateOnSpace(editor)
951
- ) {
952
- e.preventDefault();
953
- e.stopPropagation();
954
- setIsOpen(false);
955
- setIsTurnInto(false);
956
- setQuery("");
957
- slashPosRef.current = null;
958
- openGeneratePopover();
959
- return;
960
- }
961
-
962
924
  if (
963
925
  e.key === "Enter" &&
964
926
  !e.shiftKey &&
@@ -1195,48 +1157,18 @@ export function SlashCommandMenu({
1195
1157
  <PopoverContent
1196
1158
  align="start"
1197
1159
  side="bottom"
1198
- className="w-[calc(100vw-2rem)] max-w-80 rounded-xl p-0"
1199
- onOpenAutoFocus={(e: Event) => {
1200
- e.preventDefault();
1201
- generateTextareaRef.current?.focus();
1202
- }}
1160
+ className="w-[calc(100vw-2rem)] p-3 sm:w-[420px]"
1203
1161
  >
1204
- <div className="p-4 pb-3">
1205
- <p className="text-sm font-semibold flex items-center gap-1.5">
1206
- <IconWand size={14} className="text-muted-foreground" />
1207
- {t("editor.generateWithAi")}
1208
- </p>
1209
- <textarea
1210
- ref={generateTextareaRef}
1211
- value={generatePrompt}
1212
- onChange={(e) => setGeneratePrompt(e.target.value)}
1213
- onKeyDown={(e) => {
1214
- if ((e.metaKey || e.ctrlKey) && e.key === "Enter") {
1215
- e.preventDefault();
1216
- handleGenerateSubmit();
1217
- }
1218
- if (e.key === "Escape") {
1219
- setGenerateOpen(false);
1220
- }
1221
- }}
1222
- placeholder={t("editor.describeWhatToGenerate")}
1223
- className="mt-2 w-full resize-none bg-transparent text-sm placeholder:text-muted-foreground/50 focus:outline-none"
1224
- rows={3}
1225
- />
1226
- </div>
1227
- <div className="flex items-center justify-end gap-2 border-t border-border px-4 py-2.5">
1228
- <span className="text-[11px] text-muted-foreground/70">
1229
- {/Mac|iPhone|iPad/.test(navigator.userAgent) ? "⌘" : "Ctrl"}
1230
- {t("editor.enterToSubmit")}
1231
- </span>
1232
- <button
1233
- className="flex h-7 w-7 items-center justify-center rounded-lg bg-muted hover:bg-accent disabled:opacity-30"
1234
- onClick={handleGenerateSubmit}
1235
- disabled={!generatePrompt.trim()}
1236
- >
1237
- <IconArrowUp size={14} />
1238
- </button>
1239
- </div>
1162
+ <p className="px-1 pb-2 text-sm font-semibold text-foreground">
1163
+ {t("editor.generateWithAi")}
1164
+ </p>
1165
+ <PromptComposer
1166
+ autoFocus
1167
+ disabled={isGenerating}
1168
+ placeholder={t("editor.describeWhatToGenerate")}
1169
+ draftScope={`content:generate:${documentId ?? "document"}`}
1170
+ onSubmit={submitGeneratePrompt}
1171
+ />
1240
1172
  </PopoverContent>
1241
1173
  </Popover>
1242
1174
  )}
@@ -355,8 +355,7 @@ const NotionBlockquote = Blockquote.extend({
355
355
  },
356
356
  });
357
357
 
358
- const DEFAULT_EMPTY_BLOCK_PLACEHOLDER =
359
- "Press ‘space’ for AI or ‘/’ for commands";
358
+ const DEFAULT_EMPTY_BLOCK_PLACEHOLDER = "Press ‘/’ for commands";
360
359
 
361
360
  const CONTENT_RECENT_EDIT_TTL_MS = 6_000;
362
361
  const RECENT_EDIT_MARKER_WIDTH = 2;
@@ -975,6 +974,7 @@ interface VisualEditorExtensionOptions {
975
974
  onOpenNotionPageLink?: (documentId: string) => void;
976
975
  localFilePath?: string | null;
977
976
  referenceDepth?: number;
977
+ emptyBlockPlaceholder?: string;
978
978
  }
979
979
 
980
980
  function hasAncestorType(
@@ -1088,19 +1088,21 @@ function getVisualEditorPlaceholder({
1088
1088
  node,
1089
1089
  pos,
1090
1090
  hasAnchor,
1091
+ emptyBlockPlaceholder = DEFAULT_EMPTY_BLOCK_PLACEHOLDER,
1091
1092
  }: {
1092
1093
  editor: CoreEditor;
1093
1094
  node: ProseMirrorNode;
1094
1095
  pos: number;
1095
1096
  hasAnchor: boolean;
1097
+ emptyBlockPlaceholder?: string;
1096
1098
  }): string {
1097
1099
  const isToggleBody =
1098
1100
  node.type.name === "paragraph" &&
1099
1101
  hasAncestorType(editor, pos, "notionToggle");
1100
1102
 
1101
1103
  if (isToggleBody) {
1102
- return hasAnchor
1103
- ? DEFAULT_EMPTY_BLOCK_PLACEHOLDER
1104
+ return hasAnchor && editor.isFocused
1105
+ ? emptyBlockPlaceholder
1104
1106
  : EMPTY_TOGGLE_BODY_PLACEHOLDER;
1105
1107
  }
1106
1108
 
@@ -1122,7 +1124,7 @@ function getVisualEditorPlaceholder({
1122
1124
  return hasAnchor ? "Empty quote" : "";
1123
1125
  }
1124
1126
 
1125
- // Skip the long "Press 'space' for AI…" hint inside table cells — it wraps
1127
+ // Skip the command hint inside table cells — it wraps
1126
1128
  // awkwardly in narrow columns and the cell itself is already an affordance.
1127
1129
  if (
1128
1130
  node.type.name === "paragraph" &&
@@ -1132,7 +1134,7 @@ function getVisualEditorPlaceholder({
1132
1134
  return "";
1133
1135
  }
1134
1136
 
1135
- return hasAnchor ? DEFAULT_EMPTY_BLOCK_PLACEHOLDER : "";
1137
+ return hasAnchor && editor.isFocused ? emptyBlockPlaceholder : "";
1136
1138
  }
1137
1139
 
1138
1140
  export async function uploadAndInsertImageFiles(
@@ -1302,6 +1304,7 @@ export function createVisualEditorExtensions({
1302
1304
  onOpenNotionPageLink,
1303
1305
  localFilePath,
1304
1306
  referenceDepth = 0,
1307
+ emptyBlockPlaceholder = DEFAULT_EMPTY_BLOCK_PLACEHOLDER,
1305
1308
  }: VisualEditorExtensionOptions = {}): Extensions {
1306
1309
  // Build on the SHARED editor core (StarterKit base + the Collaboration /
1307
1310
  // CollaborationCaret wiring + collab undo/redo gating + ordering), then inject
@@ -1337,7 +1340,8 @@ export function createVisualEditorExtensions({
1337
1340
  NotionBlockquote,
1338
1341
  CodeBlock,
1339
1342
  Placeholder.configure({
1340
- placeholder: getVisualEditorPlaceholder,
1343
+ placeholder: (options) =>
1344
+ getVisualEditorPlaceholder({ ...options, emptyBlockPlaceholder }),
1341
1345
  showOnlyWhenEditable: true,
1342
1346
  showOnlyCurrent: true,
1343
1347
  includeChildren: true,
@@ -1740,6 +1744,7 @@ export function VisualEditor({
1740
1744
  onOpenNotionPageLink,
1741
1745
  localFilePath,
1742
1746
  referenceDepth,
1747
+ emptyBlockPlaceholder: t("editor.emptyBlockPlaceholder"),
1743
1748
  }),
1744
1749
  [
1745
1750
  documentId,
@@ -1754,6 +1759,7 @@ export function VisualEditor({
1754
1759
  onOpenNotionPageLink,
1755
1760
  localFilePath,
1756
1761
  referenceDepth,
1762
+ t,
1757
1763
  ],
1758
1764
  );
1759
1765
 
@@ -11,12 +11,12 @@ import {
11
11
  IconCopy,
12
12
  IconDownload,
13
13
  IconDots,
14
+ IconHierarchy2,
14
15
  IconMessageCircle,
15
16
  IconMinus,
16
17
  IconPhoto,
17
18
  IconPlus,
18
19
  IconRefresh,
19
- IconWand,
20
20
  IconTrash,
21
21
  IconX,
22
22
  } from "@tabler/icons-react";
@@ -1091,7 +1091,7 @@ export function ImageBlock({
1091
1091
  disabled={isGeneratingAlt}
1092
1092
  onClick={() => void handleGenerateAltText()}
1093
1093
  >
1094
- <IconWand size={18} />
1094
+ <IconHierarchy2 size={18} />
1095
1095
  </button>
1096
1096
  </TooltipTrigger>
1097
1097
  <TooltipContent>