@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
@@ -2995,6 +2995,7 @@ const enUS = {
2995
2995
  toggleField: "Toggle {{name}}",
2996
2996
  creatingDatabase: "Creating inline database...",
2997
2997
  databaseCreated: "Inline database created",
2998
+ emptyBlockPlaceholder: "Press ‘/’ for commands",
2998
2999
  describeWhatToGenerate: "Describe what to generate...",
2999
3000
  enterToSubmit: "Enter to submit",
3000
3001
  failedToCreateDatabase: "Failed to create inline database",
@@ -5462,6 +5463,7 @@ const editorMessagesByLocale = {
5462
5463
  "同步 Builder 正文完成前会暂停编辑,避免覆盖现有文章内容。",
5463
5464
  creatingDatabase: "正在创建内联数据库...",
5464
5465
  databaseCreated: "内联数据库已创建",
5466
+ emptyBlockPlaceholder: "按“/”使用命令",
5465
5467
  describeWhatToGenerate: "描述要生成什么...",
5466
5468
  enterToSubmit: "输入提交",
5467
5469
  failedToCreateDatabase: "创建内联数据库失败",
@@ -5806,6 +5808,7 @@ const editorMessagesByLocale = {
5806
5808
  "La edición está en pausa hasta que el cuerpo de Builder termine de sincronizarse, para no sobrescribir el contenido existente del artículo.",
5807
5809
  creatingDatabase: "Creando base de datos integrada...",
5808
5810
  databaseCreated: "Base de datos integrada creada",
5811
+ emptyBlockPlaceholder: "Pulsa «/» para ver los comandos",
5809
5812
  describeWhatToGenerate: "Describe qué generar...",
5810
5813
  enterToSubmit: "Entra para enviar",
5811
5814
  failedToCreateDatabase: "No se pudo crear la base de datos integrada",
@@ -6162,6 +6165,7 @@ const editorMessagesByLocale = {
6162
6165
  "La modification est suspendue jusqu'à la fin de la synchronisation du corps Builder, afin de ne pas écraser le contenu existant de l'article.",
6163
6166
  creatingDatabase: "Création d'une base de données intégrée...",
6164
6167
  databaseCreated: "Base de données intégrée créée",
6168
+ emptyBlockPlaceholder: "Appuyez sur « / » pour afficher les commandes",
6165
6169
  describeWhatToGenerate: "Décrivez ce qu'il faut générer...",
6166
6170
  enterToSubmit: "Entrez pour soumettre",
6167
6171
  failedToCreateDatabase:
@@ -6520,6 +6524,7 @@ const editorMessagesByLocale = {
6520
6524
  "Die Bearbeitung ist pausiert, bis der Builder-Textkörper fertig synchronisiert ist, damit der bestehende Artikelinhalt nicht überschrieben wird.",
6521
6525
  creatingDatabase: "Inline-Datenbank wird erstellt...",
6522
6526
  databaseCreated: "Inline-Datenbank erstellt",
6527
+ emptyBlockPlaceholder: "Drücke „/“ für Befehle",
6523
6528
  describeWhatToGenerate: "Beschreiben Sie, was generiert werden soll ...",
6524
6529
  enterToSubmit: "Zum Absenden eintreten",
6525
6530
  failedToCreateDatabase: "Inline-Datenbank konnte nicht erstellt werden",
@@ -6883,6 +6888,7 @@ const editorMessagesByLocale = {
6883
6888
  "既存の記事内容を上書きしないよう、Builder 本文の同期が完了するまで編集は一時停止されます。",
6884
6889
  creatingDatabase: "インラインデータベースを作成しています...",
6885
6890
  databaseCreated: "インラインデータベースが作成されました",
6891
+ emptyBlockPlaceholder: "「/」でコマンドを表示",
6886
6892
  describeWhatToGenerate: "何を生成するかを説明します...",
6887
6893
  enterToSubmit: "入力して送信してください",
6888
6894
  failedToCreateDatabase: "インラインデータベースの作成に失敗しました",
@@ -7235,6 +7241,7 @@ const editorMessagesByLocale = {
7235
7241
  "기존 문서 내용을 덮어쓰지 않도록 Builder 본문 동기화가 완료될 때까지 편집이 일시 중지됩니다.",
7236
7242
  creatingDatabase: "인라인 데이터베이스 생성 중...",
7237
7243
  databaseCreated: "인라인 데이터베이스가 생성되었습니다.",
7244
+ emptyBlockPlaceholder: "‘/’를 눌러 명령 사용",
7238
7245
  describeWhatToGenerate: "무엇을 생성할지 설명하세요...",
7239
7246
  enterToSubmit: "제출하려면 입력하세요.",
7240
7247
  failedToCreateDatabase: "인라인 데이터베이스를 생성하지 못했습니다.",
@@ -7586,6 +7593,7 @@ const editorMessagesByLocale = {
7586
7593
  "A edição fica pausada até o corpo do Builder terminar de sincronizar, para não sobrescrever o conteúdo existente do artigo.",
7587
7594
  creatingDatabase: "Criando banco de dados embutido...",
7588
7595
  databaseCreated: "Banco de dados embutido criado",
7596
+ emptyBlockPlaceholder: "Pressione “/” para comandos",
7589
7597
  describeWhatToGenerate: "Descreva o que gerar...",
7590
7598
  enterToSubmit: "Entre para enviar",
7591
7599
  failedToCreateDatabase: "Falha ao criar banco de dados embutido",
@@ -7943,6 +7951,7 @@ const editorMessagesByLocale = {
7943
7951
  "Builder का मुख्य भाग सिंक पूरा होने तक संपादन रोका गया है, ताकि मौजूदा लेख सामग्री अधिलेखित न हो।",
7944
7952
  creatingDatabase: "इनलाइन डेटाबेस बनाया जा रहा है...",
7945
7953
  databaseCreated: "इनलाइन डेटाबेस बनाया गया",
7954
+ emptyBlockPlaceholder: "कमांड के लिए '/' दबाएं",
7946
7955
  describeWhatToGenerate: "वर्णन करें कि क्या उत्पन्न करना है...",
7947
7956
  enterToSubmit: "सबमिट करने के लिए दर्ज करें",
7948
7957
  failedToCreateDatabase: "इनलाइन डेटाबेस बनाने में विफल",
@@ -8289,6 +8298,7 @@ const editorMessagesByLocale = {
8289
8298
  "يتم إيقاف التحرير مؤقتًا حتى تكتمل مزامنة نص Builder، حتى لا يتم استبدال محتوى المقالة الحالي.",
8290
8299
  creatingDatabase: "جارٍ إنشاء قاعدة بيانات مضمنة...",
8291
8300
  databaseCreated: "تم إنشاء قاعدة البيانات المضمنة",
8301
+ emptyBlockPlaceholder: 'اضغط على "/" للأوامر',
8292
8302
  describeWhatToGenerate: "وصف ما سيتم إنشاؤه...",
8293
8303
  enterToSubmit: "أدخل لتقديم",
8294
8304
  failedToCreateDatabase: "فشل في إنشاء قاعدة البيانات المضمنة",
@@ -162,6 +162,7 @@ function decompressZstdChunk(buf: Buffer): Buffer {
162
162
  }
163
163
 
164
164
  function decompressChunk(buf: Buffer): Buffer {
165
+ if (buf.length === 0) return Buffer.alloc(0);
165
166
  if (buf.length >= 4 && buf.subarray(0, 4).equals(ZSTD_MAGIC)) {
166
167
  return decompressZstdChunk(buf);
167
168
  }
@@ -1,7 +1,10 @@
1
1
  import { appBasePath } from "@agent-native/core/client/api-path";
2
+ import { installRouteChunkRecovery } from "@agent-native/core/client/route-chunk-recovery";
2
3
  import { hydrateRoot } from "react-dom/client";
3
4
  import { HydratedRouter } from "react-router/dom";
4
5
 
6
+ installRouteChunkRecovery();
7
+
5
8
  const basePath = appBasePath();
6
9
  const pathname = window.location.pathname;
7
10
  const routerBasePath =
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-07-22
4
+ ---
5
+
6
+ Recover stale pages after a deployment refresh automatically
@@ -1,4 +1,7 @@
1
- import { useAgentChatGenerating } from "@agent-native/core/client/agent-chat";
1
+ import {
2
+ useAgentChatGenerating,
3
+ type AgentChatMessage,
4
+ } from "@agent-native/core/client/agent-chat";
2
5
  import { useCallback } from "react";
3
6
 
4
7
  /**
@@ -9,8 +12,12 @@ export function useAgentGenerating() {
9
12
  const [generating, send] = useAgentChatGenerating();
10
13
 
11
14
  const submit = useCallback(
12
- (message: string, context: string) => {
13
- send({ message, context, submit: true });
15
+ (
16
+ message: string,
17
+ context: string,
18
+ options?: Pick<AgentChatMessage, "newTab" | "openSidebar">,
19
+ ) => {
20
+ send({ message, context, submit: true, ...options });
14
21
  },
15
22
  [send],
16
23
  );
@@ -469,6 +469,7 @@ export default function Index() {
469
469
  agentSubmit(
470
470
  `Create deck: ${summarizePromptForChat(trimmedPrompt)}`,
471
471
  context,
472
+ { newTab: true, openSidebar: true },
472
473
  );
473
474
  navigate(`/deck/${deck.id}?generating=1`);
474
475
  };
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-07-22
4
+ ---
5
+
6
+ New deck prompts now open in their own visible chat thread.
@@ -1,5 +1,14 @@
1
1
  # @agent-native/toolkit
2
2
 
3
+ ## 0.10.1
4
+
5
+ ### Patch Changes
6
+
7
+ - c15d20f: Harden browser and CLI error handling and hide editor commands for disabled features.
8
+ - c15d20f: Expand design-system conformance coverage for uncontrolled tooltip and menu
9
+ opening, and align the example adapters with those default-open semantics.
10
+ - c15d20f: Show a soft rotating blue glow for live realtime voice sessions and brighten it while the agent is working.
11
+
3
12
  ## 0.10.0
4
13
 
5
14
  ### Minor Changes
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-native/toolkit",
3
- "version": "0.10.0",
3
+ "version": "0.10.1",
4
4
  "description": "Reusable app-building UI and helpers for Agent-Native apps.",
5
5
  "homepage": "https://github.com/BuilderIO/agent-native#readme",
6
6
  "bugs": {
@@ -61,6 +61,10 @@ import type {
61
61
  const MAX_INLINE_TEXT_FILE_CHARS = 60_000;
62
62
  const SUBMIT_ENGINE_STATUS_TIMEOUT_MS = 1000;
63
63
 
64
+ export function canSubmitWithAgentEngineState(state: string): boolean {
65
+ return state === "configured";
66
+ }
67
+
64
68
  /**
65
69
  * Files the user attached via the "+" button in PromptComposer. The host owns
66
70
  * what to do with them — typically POST to a per-app upload endpoint and pass
@@ -550,7 +554,7 @@ function PromptComposerInner({
550
554
  if (typeof window !== "undefined") {
551
555
  window.dispatchEvent(new Event("agent-engine:configured-changed"));
552
556
  }
553
- return false;
557
+ return canSubmitWithAgentEngineState(state);
554
558
  }, [
555
559
  agentEngineConfigured.state,
556
560
  bounceMissingKeySetup,
@@ -10,10 +10,12 @@ import {
10
10
  import {
11
11
  IconAlertTriangle,
12
12
  IconBrain,
13
+ IconKey,
13
14
  IconLanguage,
14
15
  IconLoader2,
15
16
  IconMicrophone,
16
17
  IconPhoneOff,
18
+ IconPlugConnected,
17
19
  IconSettings,
18
20
  IconVolume,
19
21
  } from "@tabler/icons-react";
@@ -225,72 +227,90 @@ export function RealtimeVoiceModeEntry({
225
227
  collisionPadding={16}
226
228
  data-collision-boundary={collisionBoundary ? "agent-panel" : "viewport"}
227
229
  className={cn(
228
- setupRequired ? "p-4" : "p-3",
230
+ setupRequired ? "p-3.5" : "p-3",
229
231
  setupRequired
230
- ? "w-[min(calc(100vw-2rem),var(--radix-popover-content-available-width,30rem),30rem)]"
232
+ ? "w-[min(calc(100vw-2rem),var(--radix-popover-content-available-width,24rem),24rem)]"
231
233
  : "w-[min(calc(100vw-2rem),var(--radix-popover-content-available-width,18rem),18rem)]",
232
234
  )}
233
235
  aria-labelledby={titleId}
234
236
  aria-describedby={setupRequired ? descriptionId : undefined}
235
237
  >
236
- <div className={cn("grid", setupRequired ? "gap-3" : "gap-2.5")}>
237
- <div className="grid gap-1">
238
- <h2 id={titleId} className="text-sm font-semibold text-foreground">
239
- {setupRequired ? copy.setupTitle : copy.promptTitle}
240
- </h2>
238
+ <div className={cn("grid", setupRequired ? "gap-3.5" : "gap-2.5")}>
239
+ <div
240
+ className={cn(
241
+ setupRequired ? "flex items-start gap-3" : "grid gap-1",
242
+ )}
243
+ >
241
244
  {setupRequired ? (
242
- <p
243
- id={descriptionId}
244
- className="text-sm leading-relaxed text-muted-foreground"
245
- >
246
- {copy.setupDescription}
247
- </p>
245
+ <div className="flex size-9 shrink-0 items-center justify-center rounded-lg bg-primary/10 text-primary">
246
+ <IconMicrophone aria-hidden="true" />
247
+ </div>
248
248
  ) : null}
249
+ <div className="grid gap-1">
250
+ <h2
251
+ id={titleId}
252
+ className="text-sm font-semibold leading-5 text-foreground"
253
+ >
254
+ {setupRequired ? copy.setupTitle : copy.promptTitle}
255
+ </h2>
256
+ {setupRequired ? (
257
+ <p
258
+ id={descriptionId}
259
+ className="text-xs leading-5 text-muted-foreground"
260
+ >
261
+ {copy.setupDescription}
262
+ </p>
263
+ ) : null}
264
+ </div>
249
265
  </div>
250
266
 
251
267
  <div
252
268
  className={cn(
253
- "gap-2",
254
- setupRequired
255
- ? "flex flex-col-reverse sm:flex-row sm:flex-wrap sm:justify-end"
256
- : "grid",
269
+ "grid gap-2",
270
+ setupRequired ? "rounded-lg bg-muted/30 p-1" : null,
257
271
  )}
258
272
  >
259
273
  {setupRequired ? (
260
274
  <>
261
275
  <Button
262
276
  type="button"
263
- variant="ghost"
264
277
  size="sm"
265
- onClick={() => choose("dictation", onKeepDictating)}
278
+ className="w-full justify-start px-3"
279
+ disabled={connectingBuilder}
280
+ onClick={() =>
281
+ choose("realtime", onConnectBuilder ?? onStartVoiceMode)
282
+ }
266
283
  >
267
- {copy.keepDictating}
284
+ {connectingBuilder ? (
285
+ <IconLoader2 className="animate-spin" />
286
+ ) : (
287
+ <IconPlugConnected aria-hidden="true" />
288
+ )}
289
+ {copy.connectBuilder}
268
290
  </Button>
269
291
  <Button
270
292
  type="button"
271
293
  variant="outline"
272
294
  size="sm"
295
+ className="w-full justify-start bg-background px-3"
273
296
  onClick={() =>
274
297
  choose("realtime", onUseOpenAiKey ?? onStartVoiceMode)
275
298
  }
276
299
  >
300
+ <IconKey aria-hidden="true" />
277
301
  {openAiConfigured
278
302
  ? copy.startWithOpenAiKey
279
303
  : copy.useOpenAiKey}
280
304
  </Button>
281
305
  <Button
282
306
  type="button"
307
+ variant="ghost"
283
308
  size="sm"
284
- className="whitespace-nowrap"
285
- disabled={connectingBuilder}
286
- onClick={() =>
287
- choose("realtime", onConnectBuilder ?? onStartVoiceMode)
288
- }
309
+ className="w-full justify-start px-3 text-muted-foreground"
310
+ onClick={() => choose("dictation", onKeepDictating)}
289
311
  >
290
- {connectingBuilder ? (
291
- <IconLoader2 className="animate-spin" />
292
- ) : null}
293
- {copy.connectBuilder}
312
+ <IconMicrophone aria-hidden="true" />
313
+ {copy.keepDictating}
294
314
  </Button>
295
315
  </>
296
316
  ) : (
@@ -382,9 +402,14 @@ export interface RealtimeVoiceModeInlineSettings {
382
402
  const SILENT_AUDIO_LEVELS = createRealtimeVoiceAudioLevelStore();
383
403
  const WAVEFORM_WEIGHTS = [0.55, 0.82, 1, 0.82, 0.55];
384
404
  const AUDIO_ACTIVITY_THRESHOLD = 0.1;
405
+ const WORKING_GLOW_HOLD_MS = 800;
385
406
 
386
407
  function usePrefersReducedMotion(): boolean {
387
- const [reduced, setReduced] = useState(false);
408
+ const [reduced, setReduced] = useState(
409
+ () =>
410
+ typeof window !== "undefined" &&
411
+ Boolean(window.matchMedia?.("(prefers-reduced-motion: reduce)").matches),
412
+ );
388
413
  useEffect(() => {
389
414
  if (typeof window === "undefined" || !window.matchMedia) return;
390
415
  const query = window.matchMedia("(prefers-reduced-motion: reduce)");
@@ -697,6 +722,9 @@ export function RealtimeVoiceModeDock({
697
722
  const controlsId = useId();
698
723
  const [controlsOpen, setControlsOpen] = useState(false);
699
724
  const [settingsOpen, setSettingsOpen] = useState(false);
725
+ const [workingGlowHeld, setWorkingGlowHeld] = useState(state === "working");
726
+ const glowRef = useRef<HTMLSpanElement>(null);
727
+ const glowAnimationRef = useRef<Animation | null>(null);
700
728
  const selectInteractionRef = useRef(false);
701
729
  const selectInteractionFrameRef = useRef<number | null>(null);
702
730
  const levels = useSyncExternalStore(
@@ -724,6 +752,56 @@ export function RealtimeVoiceModeDock({
724
752
  const errorDetailVisible = state === "error" && Boolean(errorMessage);
725
753
  const controlsVisible = controlsOpen || settingsOpen;
726
754
  const chatPanelTranslation = useChatPanelTranslation(chatVisible);
755
+ const workingGlowActive = state === "working" || workingGlowHeld;
756
+
757
+ useEffect(() => {
758
+ if (state === "working") {
759
+ setWorkingGlowHeld(true);
760
+ return;
761
+ }
762
+ if (!workingGlowHeld) return;
763
+ const timer = window.setTimeout(
764
+ () => setWorkingGlowHeld(false),
765
+ WORKING_GLOW_HOLD_MS,
766
+ );
767
+ return () => window.clearTimeout(timer);
768
+ }, [state, workingGlowHeld]);
769
+
770
+ useEffect(() => {
771
+ if (!connected || reducedMotion || !glowRef.current) {
772
+ glowAnimationRef.current?.cancel();
773
+ glowAnimationRef.current = null;
774
+ return;
775
+ }
776
+
777
+ const animation = glowRef.current.animate(
778
+ [{ transform: "rotate(0turn)" }, { transform: "rotate(1turn)" }],
779
+ {
780
+ duration: 12_000,
781
+ easing: "linear",
782
+ iterations: Number.POSITIVE_INFINITY,
783
+ },
784
+ );
785
+ glowAnimationRef.current = animation;
786
+
787
+ return () => {
788
+ animation.cancel();
789
+ if (glowAnimationRef.current === animation) {
790
+ glowAnimationRef.current = null;
791
+ }
792
+ };
793
+ }, [connected, reducedMotion]);
794
+
795
+ useEffect(() => {
796
+ const animation = glowAnimationRef.current;
797
+ if (!animation) return;
798
+ const playbackRate = workingGlowActive ? 2.4 : 1;
799
+ if (typeof animation.updatePlaybackRate === "function") {
800
+ animation.updatePlaybackRate(playbackRate);
801
+ } else {
802
+ animation.playbackRate = playbackRate;
803
+ }
804
+ }, [workingGlowActive]);
727
805
 
728
806
  const handleSelectOpenChange = useCallback((open: boolean) => {
729
807
  if (selectInteractionFrameRef.current !== null) {
@@ -900,9 +978,19 @@ export function RealtimeVoiceModeDock({
900
978
  className={cn(
901
979
  "relative isolate size-16 overflow-visible rounded-full ring-1 backdrop-blur-xl transition-transform duration-150 ease-out focus-visible:ring-offset-2 active:scale-[0.97] motion-reduce:transition-none",
902
980
  ORB_STATE_CLASSES[state],
903
- state === "working" && "agent-realtime-voice-working",
904
981
  )}
905
982
  >
983
+ {connected ? (
984
+ <span
985
+ ref={glowRef}
986
+ aria-hidden="true"
987
+ data-realtime-voice-glow="true"
988
+ className={cn(
989
+ "agent-realtime-voice-glow",
990
+ workingGlowActive && "agent-realtime-voice-working",
991
+ )}
992
+ />
993
+ ) : null}
906
994
  <span className="relative z-10 flex items-center justify-center">
907
995
  {state === "connecting" ? (
908
996
  <VoiceConnectingIndicator />
@@ -1005,6 +1005,36 @@ export function createRealtimeVoiceToolManifestCoordinator(
1005
1005
  export function extractRealtimeVoiceFunctionCalls(
1006
1006
  event: RealtimeServerEvent,
1007
1007
  ): Array<{ name: string; callId: string; argumentsText: string }> {
1008
+ if (event.type === "response.function_call_arguments.done") {
1009
+ const name = typeof event.name === "string" ? event.name : "";
1010
+ const callId = typeof event.call_id === "string" ? event.call_id : "";
1011
+ if (!name || !callId) return [];
1012
+ return [
1013
+ {
1014
+ name,
1015
+ callId,
1016
+ argumentsText:
1017
+ typeof event.arguments === "string" ? event.arguments : "{}",
1018
+ },
1019
+ ];
1020
+ }
1021
+ if (event.type === "response.output_item.done") {
1022
+ const item = event.item;
1023
+ if (!item || typeof item !== "object") return [];
1024
+ const record = item as Record<string, unknown>;
1025
+ if (record.type !== "function_call") return [];
1026
+ const name = typeof record.name === "string" ? record.name : "";
1027
+ const callId = typeof record.call_id === "string" ? record.call_id : "";
1028
+ if (!name || !callId) return [];
1029
+ return [
1030
+ {
1031
+ name,
1032
+ callId,
1033
+ argumentsText:
1034
+ typeof record.arguments === "string" ? record.arguments : "{}",
1035
+ },
1036
+ ];
1037
+ }
1008
1038
  if (event.type !== "response.done") return [];
1009
1039
  const response = event.response;
1010
1040
  if (!response || typeof response !== "object") return [];
@@ -122,6 +122,87 @@ function elementWithText(document: Document, selector: string, text: string) {
122
122
  );
123
123
  }
124
124
 
125
+ function assertInlineLayout(
126
+ container: Element,
127
+ iconSelector: string,
128
+ labelSelector: string,
129
+ message: string,
130
+ ) {
131
+ const icon = container.querySelector<HTMLElement>(iconSelector);
132
+ const label = container.querySelector<HTMLElement>(labelSelector);
133
+ invariant(icon && label, message);
134
+
135
+ const iconRect = icon.getBoundingClientRect();
136
+ const labelRect = label.getBoundingClientRect();
137
+ const hasGeometry =
138
+ iconRect.width > 0 ||
139
+ iconRect.height > 0 ||
140
+ labelRect.width > 0 ||
141
+ labelRect.height > 0;
142
+ if (hasGeometry) {
143
+ const verticalOverlap =
144
+ Math.min(iconRect.bottom, labelRect.bottom) -
145
+ Math.max(iconRect.top, labelRect.top);
146
+ invariant(
147
+ verticalOverlap > 0 || Math.abs(iconRect.top - labelRect.top) <= 2,
148
+ message,
149
+ );
150
+ return;
151
+ }
152
+
153
+ // happy-dom does not calculate layout. Still reject adapters that explicitly
154
+ // stack the tab contents, while browser-backed runs use the geometry check.
155
+ const commonAncestor = (() => {
156
+ let candidate: Element | null = icon;
157
+ while (candidate && !candidate.contains(label)) {
158
+ candidate = candidate.parentElement;
159
+ }
160
+ return candidate;
161
+ })();
162
+ const styles = [
163
+ container,
164
+ commonAncestor,
165
+ icon.parentElement,
166
+ label.parentElement,
167
+ ]
168
+ .filter((element): element is Element => Boolean(element))
169
+ .map((element) =>
170
+ element.ownerDocument.defaultView?.getComputedStyle(element),
171
+ );
172
+ invariant(
173
+ !styles.some(
174
+ (style) => style?.display === "flex" && style.flexDirection === "column",
175
+ ),
176
+ message,
177
+ );
178
+ }
179
+
180
+ function assertContainedFooter(dialog: Element, footerSelector: string) {
181
+ const footer = dialog.querySelector<HTMLElement>(footerSelector);
182
+ invariant(
183
+ footer,
184
+ "Dialog footer controls must be rendered inside the dialog surface.",
185
+ );
186
+
187
+ const dialogRect = (dialog as HTMLElement).getBoundingClientRect();
188
+ const footerRect = footer.getBoundingClientRect();
189
+ const hasGeometry =
190
+ dialogRect.width > 0 ||
191
+ dialogRect.height > 0 ||
192
+ footerRect.width > 0 ||
193
+ footerRect.height > 0;
194
+ if (!hasGeometry) return;
195
+
196
+ const epsilon = 2;
197
+ invariant(
198
+ footerRect.top >= dialogRect.top - epsilon &&
199
+ footerRect.bottom <= dialogRect.bottom + epsilon &&
200
+ footerRect.left >= dialogRect.left - epsilon &&
201
+ footerRect.right <= dialogRect.right + epsilon,
202
+ "Dialog footer controls must remain within the dialog surface bounds.",
203
+ );
204
+ }
205
+
125
206
  const checks: readonly ConformanceCheck[] = [
126
207
  {
127
208
  id: "contract.components",
@@ -308,6 +389,21 @@ const checks: readonly ConformanceCheck[] = [
308
389
  "Tooltip must honor controlled open and portalContainer.",
309
390
  );
310
391
  unmount(probe);
392
+
393
+ const defaultOpenProbe = mount(
394
+ <components.Tooltip
395
+ trigger={<button>Help by default</button>}
396
+ content="Default tooltip"
397
+ defaultOpen
398
+ portalContainer={portal}
399
+ />,
400
+ );
401
+ await settle();
402
+ invariant(
403
+ portal.textContent?.includes("Default tooltip"),
404
+ "Tooltip must honor defaultOpen and portalContainer.",
405
+ );
406
+ unmount(defaultOpenProbe);
311
407
  portal.remove();
312
408
  },
313
409
  },
@@ -331,6 +427,21 @@ const checks: readonly ConformanceCheck[] = [
331
427
  click(item, document);
332
428
  invariant(selected === "archive", "Menu must report selected item ids.");
333
429
  unmount(probe);
430
+
431
+ const defaultOpenProbe = mount(
432
+ <components.Menu
433
+ trigger={<button>Default actions</button>}
434
+ items={[{ id: "restore", label: "Restore" }]}
435
+ defaultOpen
436
+ onAction={() => {}}
437
+ />,
438
+ );
439
+ await settle();
440
+ invariant(
441
+ elementWithText(document, '[role="menuitem"]', "Restore"),
442
+ "Menu must honor defaultOpen.",
443
+ );
444
+ unmount(defaultOpenProbe);
334
445
  },
335
446
  },
336
447
  {
@@ -393,6 +504,30 @@ const checks: readonly ConformanceCheck[] = [
393
504
  "Dialog must not invent actions when footer is omitted.",
394
505
  );
395
506
  unmount(probe);
507
+
508
+ const footerProbe = mount(
509
+ <components.Dialog
510
+ open
511
+ onOpenChange={() => {}}
512
+ title="Footer probe"
513
+ portalContainer={portal}
514
+ footer={
515
+ <button data-conformance-dialog-footer-action="true" type="button">
516
+ Save
517
+ </button>
518
+ }
519
+ >
520
+ Footer content
521
+ </components.Dialog>,
522
+ );
523
+ await settle();
524
+ const footerDialog = portal.querySelector('[role="dialog"]');
525
+ invariant(footerDialog, "Dialog footer probe did not render a dialog.");
526
+ assertContainedFooter(
527
+ footerDialog,
528
+ '[data-conformance-dialog-footer-action="true"]',
529
+ );
530
+ unmount(footerProbe);
396
531
  portal.remove();
397
532
  },
398
533
  },
@@ -466,7 +601,16 @@ const checks: readonly ConformanceCheck[] = [
466
601
  orientation="vertical"
467
602
  onChange={(next) => (value = next)}
468
603
  items={[
469
- { value: "first", label: "First", content: "One" },
604
+ {
605
+ value: "first",
606
+ label: <span data-conformance-tab-label="true">First</span>,
607
+ icon: (
608
+ <span data-conformance-tab-icon="true" aria-hidden="true">
609
+
610
+ </span>
611
+ ),
612
+ content: "One",
613
+ },
470
614
  { value: "second", label: "Second", content: "Two" },
471
615
  ]}
472
616
  />,
@@ -477,6 +621,14 @@ const checks: readonly ConformanceCheck[] = [
477
621
  tabList.getAttribute("aria-orientation") === "vertical",
478
622
  "Tabs must honor vertical orientation in their tablist semantics.",
479
623
  );
624
+ const first = elementWithText(document, '[role="tab"]', "First");
625
+ invariant(first, "Tabs must expose the icon-bearing tab.");
626
+ assertInlineLayout(
627
+ first,
628
+ '[data-conformance-tab-icon="true"]',
629
+ '[data-conformance-tab-label="true"]',
630
+ "Tabs must lay out an icon and its label on the same row.",
631
+ );
480
632
  const second = elementWithText(document, '[role="tab"]', "Second");
481
633
  invariant(second, "Tabs must expose tab semantics.");
482
634
  click(second, document);