@agent-native/core 0.92.7 → 0.92.9

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 (295) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/core/CHANGELOG.md +18 -0
  3. package/corpus/core/docs/content/a2a-protocol.mdx +12 -0
  4. package/corpus/core/docs/content/locales/ar-SA/a2a-protocol.mdx +12 -0
  5. package/corpus/core/docs/content/locales/ar-SA/pr-visual-recap.mdx +3 -3
  6. package/corpus/core/docs/content/locales/ar-SA/pure-agent-apps.mdx +4 -0
  7. package/corpus/core/docs/content/locales/de-DE/a2a-protocol.mdx +12 -0
  8. package/corpus/core/docs/content/locales/de-DE/pr-visual-recap.mdx +3 -3
  9. package/corpus/core/docs/content/locales/de-DE/pure-agent-apps.mdx +4 -0
  10. package/corpus/core/docs/content/locales/es-ES/a2a-protocol.mdx +12 -0
  11. package/corpus/core/docs/content/locales/es-ES/pr-visual-recap.mdx +3 -3
  12. package/corpus/core/docs/content/locales/es-ES/pure-agent-apps.mdx +4 -0
  13. package/corpus/core/docs/content/locales/fr-FR/a2a-protocol.mdx +12 -0
  14. package/corpus/core/docs/content/locales/fr-FR/pr-visual-recap.mdx +3 -3
  15. package/corpus/core/docs/content/locales/fr-FR/pure-agent-apps.mdx +4 -0
  16. package/corpus/core/docs/content/locales/hi-IN/a2a-protocol.mdx +12 -0
  17. package/corpus/core/docs/content/locales/hi-IN/pr-visual-recap.mdx +3 -3
  18. package/corpus/core/docs/content/locales/hi-IN/pure-agent-apps.mdx +4 -0
  19. package/corpus/core/docs/content/locales/ja-JP/a2a-protocol.mdx +12 -0
  20. package/corpus/core/docs/content/locales/ja-JP/pr-visual-recap.mdx +3 -3
  21. package/corpus/core/docs/content/locales/ja-JP/pure-agent-apps.mdx +4 -0
  22. package/corpus/core/docs/content/locales/ko-KR/a2a-protocol.mdx +12 -0
  23. package/corpus/core/docs/content/locales/ko-KR/pr-visual-recap.mdx +3 -3
  24. package/corpus/core/docs/content/locales/ko-KR/pure-agent-apps.mdx +4 -0
  25. package/corpus/core/docs/content/locales/pt-BR/a2a-protocol.mdx +12 -0
  26. package/corpus/core/docs/content/locales/pt-BR/pr-visual-recap.mdx +3 -3
  27. package/corpus/core/docs/content/locales/pt-BR/pure-agent-apps.mdx +4 -0
  28. package/corpus/core/docs/content/locales/zh-CN/a2a-protocol.mdx +12 -0
  29. package/corpus/core/docs/content/locales/zh-CN/pr-visual-recap.mdx +3 -3
  30. package/corpus/core/docs/content/locales/zh-CN/pure-agent-apps.mdx +4 -0
  31. package/corpus/core/docs/content/locales/zh-TW/a2a-protocol.mdx +12 -0
  32. package/corpus/core/docs/content/locales/zh-TW/pr-visual-recap.mdx +3 -3
  33. package/corpus/core/docs/content/locales/zh-TW/pure-agent-apps.mdx +4 -0
  34. package/corpus/core/docs/content/pr-visual-recap.mdx +3 -3
  35. package/corpus/core/docs/content/pure-agent-apps.mdx +22 -0
  36. package/corpus/core/package.json +1 -1
  37. package/corpus/core/src/agent/engine/builtin.ts +1 -1
  38. package/corpus/core/src/agent/model-config.ts +30 -30
  39. package/corpus/core/src/agent/production-agent.ts +129 -7
  40. package/corpus/core/src/cli/design-connect.ts +438 -83
  41. package/corpus/core/src/cli/recap.ts +17 -3
  42. package/corpus/core/src/client/AgentPanel.tsx +8 -1
  43. package/corpus/core/src/client/agent-chat-adapter.ts +12 -7
  44. package/corpus/core/src/client/composer/TiptapComposer.tsx +1 -1
  45. package/corpus/core/src/client/index.ts +4 -0
  46. package/corpus/core/src/client/org/TeamPage.tsx +41 -26
  47. package/corpus/core/src/client/use-action.ts +113 -1
  48. package/corpus/core/src/db/client.ts +12 -2
  49. package/corpus/core/src/db/create-get-db.ts +4 -1
  50. package/corpus/core/src/scripts/agent-engines/manage-agent-engine.ts +1 -1
  51. package/corpus/core/src/scripts/agent-engines/set-agent-engine.ts +1 -1
  52. package/corpus/core/src/server/ssr-handler.ts +7 -0
  53. package/corpus/core/src/server/transcribe-voice.ts +1 -1
  54. package/corpus/core/src/usage/store.ts +13 -4
  55. package/corpus/core/src/vite/client.ts +38 -1
  56. package/corpus/templates/analytics/AGENTS.md +3 -0
  57. package/corpus/templates/analytics/actions/get-data-program.ts +78 -0
  58. package/corpus/templates/analytics/actions/list-data-programs.ts +49 -0
  59. package/corpus/templates/analytics/app/global.css +11 -0
  60. package/corpus/templates/analytics/app/hooks/use-dashboard-chat-context.ts +163 -17
  61. package/corpus/templates/analytics/app/i18n/zh-TW.ts +2 -0
  62. package/corpus/templates/analytics/app/i18n-data.ts +20 -0
  63. package/corpus/templates/analytics/app/pages/adhoc/explorer-dashboard/ChartCard.tsx +96 -3
  64. package/corpus/templates/analytics/app/pages/adhoc/explorer-dashboard/index.tsx +3 -1
  65. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/SqlChartCard.tsx +61 -4
  66. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +40 -2
  67. package/corpus/templates/analytics/changelog/2026-07-09-analytics-no-longer-forgets-successful-data-queries-when-a-l.md +6 -0
  68. package/corpus/templates/analytics/changelog/2026-07-09-dashboard-charts-keep-consistent-spacing-when-they-stack-ver.md +6 -0
  69. package/corpus/templates/analytics/changelog/2026-07-09-dashboard-charts-tables-and-extensions-can-be-selected-and-d.md +6 -0
  70. package/corpus/templates/analytics/changelog/2026-07-09-long-running-analytics-requests-now-recover-automatically-wh.md +6 -0
  71. package/corpus/templates/analytics/server/db/index.ts +6 -0
  72. package/corpus/templates/clips/desktop/src/hooks/useMeetingTranscription.ts +1 -7
  73. package/corpus/templates/content/app/components/editor/DocumentProperties.tsx +102 -15
  74. package/corpus/templates/content/app/hooks/use-content-database.ts +52 -0
  75. package/corpus/templates/content/app/hooks/use-document-properties.ts +50 -6
  76. package/corpus/templates/content/app/i18n/zh-TW.ts +2 -0
  77. package/corpus/templates/content/app/i18n-data.ts +28 -0
  78. package/corpus/templates/content/changelog/2026-07-09-notion-conflict-warnings-no-longer-flash-during-normal-synce.md +6 -0
  79. package/corpus/templates/content/changelog/2026-07-09-property-menus-and-delete-confirmations-now-open-visibly-and.md +6 -0
  80. package/corpus/templates/content/server/lib/notion-sync.ts +130 -28
  81. package/corpus/templates/design/actions/add-breakpoint.ts +48 -68
  82. package/corpus/templates/design/actions/add-localhost-screens.ts +496 -61
  83. package/corpus/templates/design/actions/apply-component-prop-edit.ts +2 -18
  84. package/corpus/templates/design/actions/apply-design-token-edit.ts +51 -82
  85. package/corpus/templates/design/actions/apply-tweaks.ts +63 -41
  86. package/corpus/templates/design/actions/capture-design-state.ts +2 -2
  87. package/corpus/templates/design/actions/connect-localhost.ts +58 -12
  88. package/corpus/templates/design/actions/create-component.ts +2 -18
  89. package/corpus/templates/design/actions/create-design-branch.ts +38 -18
  90. package/corpus/templates/design/actions/create-fusion-app.ts +15 -11
  91. package/corpus/templates/design/actions/delete-file.ts +19 -34
  92. package/corpus/templates/design/actions/deploy-design-preview.ts +59 -27
  93. package/corpus/templates/design/actions/deploy-fusion-app.ts +22 -15
  94. package/corpus/templates/design/actions/export-pdf.ts +2 -1
  95. package/corpus/templates/design/actions/export-zip.ts +9 -3
  96. package/corpus/templates/design/actions/generate-design.ts +107 -70
  97. package/corpus/templates/design/actions/get-component-details.ts +2 -18
  98. package/corpus/templates/design/actions/get-design-branch-diff.ts +2 -3
  99. package/corpus/templates/design/actions/get-design-surface-index.ts +2 -18
  100. package/corpus/templates/design/actions/get-design.ts +2 -1
  101. package/corpus/templates/design/actions/grant-localhost-write-consent.ts +7 -1
  102. package/corpus/templates/design/actions/import-design-tokens.ts +114 -76
  103. package/corpus/templates/design/actions/index-components.ts +2 -18
  104. package/corpus/templates/design/actions/list-design-source-capabilities.ts +23 -28
  105. package/corpus/templates/design/actions/list-local-files.ts +9 -2
  106. package/corpus/templates/design/actions/migrate-board-objects-to-file.ts +82 -98
  107. package/corpus/templates/design/actions/open-component-source.ts +2 -18
  108. package/corpus/templates/design/actions/open-visual-edit.ts +19 -1
  109. package/corpus/templates/design/actions/present-design-variants.ts +70 -70
  110. package/corpus/templates/design/actions/preview-component-prop-edit.ts +4 -14
  111. package/corpus/templates/design/actions/read-local-file.ts +9 -2
  112. package/corpus/templates/design/actions/remove-breakpoint.ts +40 -61
  113. package/corpus/templates/design/actions/rename-screen.ts +425 -0
  114. package/corpus/templates/design/actions/request-localhost-write-consent.ts +12 -2
  115. package/corpus/templates/design/actions/revoke-localhost-write-consent.ts +9 -2
  116. package/corpus/templates/design/actions/sync-fusion-app.ts +56 -39
  117. package/corpus/templates/design/actions/update-design.ts +376 -61
  118. package/corpus/templates/design/actions/update-file.ts +455 -188
  119. package/corpus/templates/design/actions/write-local-file.ts +10 -2
  120. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +685 -608
  121. package/corpus/templates/design/app/components/design/LayersPanel.tsx +43 -15
  122. package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +576 -2015
  123. package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +62 -14
  124. package/corpus/templates/design/app/components/design/bridge/embedded-wheel.bridge.ts +263 -25
  125. package/corpus/templates/design/app/components/design/design-canvas/annotation-submit.ts +34 -0
  126. package/corpus/templates/design/app/components/design/design-canvas/coordinate-transforms.ts +40 -0
  127. package/corpus/templates/design/app/components/design/design-canvas/creation.ts +47 -0
  128. package/corpus/templates/design/app/components/design/design-canvas/element-payload.ts +27 -0
  129. package/corpus/templates/design/app/components/design/design-canvas/embedded-frame.ts +62 -0
  130. package/corpus/templates/design/app/components/design/design-canvas/external-preview.ts +137 -0
  131. package/corpus/templates/design/app/components/design/design-canvas/file-drop.ts +10 -0
  132. package/corpus/templates/design/app/components/design/design-canvas/hit-test.ts +23 -0
  133. package/corpus/templates/design/app/components/design/design-canvas/iframe-events.ts +23 -0
  134. package/corpus/templates/design/app/components/design/design-canvas/iframe-pan.ts +177 -0
  135. package/corpus/templates/design/app/components/design/design-canvas/motion-types.ts +7 -0
  136. package/corpus/templates/design/app/components/design/design-canvas/pending-text-edit.ts +62 -0
  137. package/corpus/templates/design/app/components/design/index.ts +2 -2
  138. package/corpus/templates/design/app/components/design/multi-screen/canvas-tools.ts +100 -0
  139. package/corpus/templates/design/app/components/design/multi-screen/coordinate-transforms.ts +81 -0
  140. package/corpus/templates/design/app/components/design/multi-screen/cross-screen-drop.ts +23 -13
  141. package/corpus/templates/design/app/components/design/multi-screen/culling.ts +238 -19
  142. package/corpus/templates/design/app/components/design/multi-screen/draft-primitives.ts +424 -0
  143. package/corpus/templates/design/app/components/design/multi-screen/frame-geometry.ts +341 -0
  144. package/corpus/templates/design/app/components/design/multi-screen/iframe-targeting.ts +52 -0
  145. package/corpus/templates/design/app/components/design/multi-screen/overview-layout.ts +62 -0
  146. package/corpus/templates/design/app/components/design/multi-screen/primitive-drop-target.ts +283 -0
  147. package/corpus/templates/design/app/components/design/multi-screen/screen-content-cache.ts +272 -0
  148. package/corpus/templates/design/app/components/design/multi-screen/types.ts +5 -1
  149. package/corpus/templates/design/app/components/design/multi-screen/wheel-gesture-state.ts +12 -0
  150. package/corpus/templates/design/app/components/visual-editor/DrawOverlay.tsx +325 -84
  151. package/corpus/templates/design/app/hooks/use-navigation-state.ts +15 -1
  152. package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +119 -47
  153. package/corpus/templates/design/app/i18n/zh-TW.ts +9 -0
  154. package/corpus/templates/design/app/i18n-data.ts +223 -0
  155. package/corpus/templates/design/app/lib/design-save-outbox.ts +379 -0
  156. package/corpus/templates/design/app/lib/png-clipboard.ts +113 -0
  157. package/corpus/templates/design/app/pages/design-editor/canvas-primitives.ts +229 -0
  158. package/corpus/templates/design/app/pages/design-editor/code-layer-state.ts +918 -0
  159. package/corpus/templates/design/app/pages/design-editor/collab-sync.ts +43 -0
  160. package/corpus/templates/design/app/pages/design-editor/cross-screen-text-color.ts +336 -0
  161. package/corpus/templates/design/app/pages/design-editor/data-operations.ts +270 -0
  162. package/corpus/templates/design/app/pages/design-editor/dom-guards.ts +24 -0
  163. package/corpus/templates/design/app/pages/design-editor/dom-utils.ts +11 -0
  164. package/corpus/templates/design/app/pages/design-editor/editor-session.ts +20 -0
  165. package/corpus/templates/design/app/pages/design-editor/editor-state.ts +408 -0
  166. package/corpus/templates/design/app/pages/design-editor/export-capture.ts +115 -0
  167. package/corpus/templates/design/app/pages/design-editor/geometry-persistence.ts +93 -0
  168. package/corpus/templates/design/app/pages/design-editor/history.ts +169 -0
  169. package/corpus/templates/design/app/pages/design-editor/layout-operations.ts +185 -0
  170. package/corpus/templates/design/app/pages/design-editor/motion-state.ts +309 -0
  171. package/corpus/templates/design/app/pages/design-editor/overview-camera.ts +438 -0
  172. package/corpus/templates/design/app/pages/design-editor/pending-edits.ts +510 -0
  173. package/corpus/templates/design/app/pages/design-editor/portable-style.ts +115 -0
  174. package/corpus/templates/design/app/pages/design-editor/selection-state.ts +337 -0
  175. package/corpus/templates/design/app/pages/design-editor/style-utils.ts +5 -0
  176. package/corpus/templates/design/app/pages/design-editor/tool-state.ts +92 -0
  177. package/corpus/templates/design/app/pages/design-editor/tweak-save.ts +87 -0
  178. package/corpus/templates/design/app/pages/design-editor/types.ts +36 -0
  179. package/corpus/templates/design/app/routes/design.$id.tsx +11 -1
  180. package/corpus/templates/design/changelog/2026-07-09-design-edits-canvas-positions-tools-and-tab-context-now-pers.md +6 -0
  181. package/corpus/templates/design/changelog/2026-07-09-figma-style-shortcuts-drawing-annotations-and-cross-screen-d.md +6 -0
  182. package/corpus/templates/design/changelog/2026-07-09-hand-and-scale-tools-now-keep-their-active-toolbar-identity-.md +6 -0
  183. package/corpus/templates/design/changelog/2026-07-09-large-multi-screen-designs-now-stay-responsive-during-long-c.md +6 -0
  184. package/corpus/templates/design/changelog/2026-07-09-layer-drags-now-land-exactly-where-the-insertion-indicator-s.md +6 -0
  185. package/corpus/templates/design/server/db/index.ts +2 -52
  186. package/corpus/templates/design/server/db/schema.ts +16 -0
  187. package/corpus/templates/design/server/lib/design-data-access.ts +70 -0
  188. package/corpus/templates/design/server/lib/design-data-mutation.ts +249 -0
  189. package/corpus/templates/design/server/lib/fusion-screens.ts +89 -76
  190. package/corpus/templates/design/server/lib/import-design-files.ts +76 -35
  191. package/corpus/templates/design/server/lib/verify-write-grant.ts +7 -2
  192. package/corpus/templates/design/server/plugins/db.ts +19 -0
  193. package/corpus/templates/design/server/source-workspace.ts +12 -13
  194. package/corpus/templates/design/shared/resolve-tweaks.ts +15 -0
  195. package/corpus/templates/design/shared/screen-rename.ts +42 -0
  196. package/corpus/templates/design/shared/source-mode.ts +84 -4
  197. package/dist/agent/engine/builder-engine.d.ts +1 -1
  198. package/dist/agent/engine/builder-engine.d.ts.map +1 -1
  199. package/dist/agent/engine/builtin.js +1 -1
  200. package/dist/agent/engine/builtin.js.map +1 -1
  201. package/dist/agent/model-config.d.ts +9 -9
  202. package/dist/agent/model-config.d.ts.map +1 -1
  203. package/dist/agent/model-config.js +30 -30
  204. package/dist/agent/model-config.js.map +1 -1
  205. package/dist/agent/production-agent.d.ts +60 -1
  206. package/dist/agent/production-agent.d.ts.map +1 -1
  207. package/dist/agent/production-agent.js +106 -7
  208. package/dist/agent/production-agent.js.map +1 -1
  209. package/dist/cli/design-connect.d.ts +30 -1
  210. package/dist/cli/design-connect.d.ts.map +1 -1
  211. package/dist/cli/design-connect.js +359 -75
  212. package/dist/cli/design-connect.js.map +1 -1
  213. package/dist/cli/recap.d.ts.map +1 -1
  214. package/dist/cli/recap.js +13 -3
  215. package/dist/cli/recap.js.map +1 -1
  216. package/dist/client/AgentPanel.d.ts.map +1 -1
  217. package/dist/client/AgentPanel.js +6 -1
  218. package/dist/client/AgentPanel.js.map +1 -1
  219. package/dist/client/agent-chat-adapter.d.ts.map +1 -1
  220. package/dist/client/agent-chat-adapter.js +10 -5
  221. package/dist/client/agent-chat-adapter.js.map +1 -1
  222. package/dist/client/composer/TiptapComposer.js +1 -1
  223. package/dist/client/composer/TiptapComposer.js.map +1 -1
  224. package/dist/client/index.d.ts +1 -1
  225. package/dist/client/index.d.ts.map +1 -1
  226. package/dist/client/index.js +1 -1
  227. package/dist/client/index.js.map +1 -1
  228. package/dist/client/org/TeamPage.d.ts.map +1 -1
  229. package/dist/client/org/TeamPage.js +6 -5
  230. package/dist/client/org/TeamPage.js.map +1 -1
  231. package/dist/client/use-action.d.ts +32 -0
  232. package/dist/client/use-action.d.ts.map +1 -1
  233. package/dist/client/use-action.js +68 -1
  234. package/dist/client/use-action.js.map +1 -1
  235. package/dist/collab/struct-routes.d.ts +1 -1
  236. package/dist/db/client.d.ts +3 -0
  237. package/dist/db/client.d.ts.map +1 -1
  238. package/dist/db/client.js +7 -2
  239. package/dist/db/client.js.map +1 -1
  240. package/dist/db/create-get-db.d.ts.map +1 -1
  241. package/dist/db/create-get-db.js +2 -2
  242. package/dist/db/create-get-db.js.map +1 -1
  243. package/dist/notifications/routes.d.ts +3 -3
  244. package/dist/observability/routes.d.ts +1 -1
  245. package/dist/resources/handlers.d.ts +3 -3
  246. package/dist/scripts/agent-engines/manage-agent-engine.js +1 -1
  247. package/dist/scripts/agent-engines/manage-agent-engine.js.map +1 -1
  248. package/dist/scripts/agent-engines/set-agent-engine.js +1 -1
  249. package/dist/scripts/agent-engines/set-agent-engine.js.map +1 -1
  250. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  251. package/dist/server/ssr-handler.d.ts.map +1 -1
  252. package/dist/server/ssr-handler.js +7 -0
  253. package/dist/server/ssr-handler.js.map +1 -1
  254. package/dist/server/transcribe-voice.js +1 -1
  255. package/dist/server/transcribe-voice.js.map +1 -1
  256. package/dist/usage/store.d.ts.map +1 -1
  257. package/dist/usage/store.js +13 -4
  258. package/dist/usage/store.js.map +1 -1
  259. package/dist/vite/client.d.ts.map +1 -1
  260. package/dist/vite/client.js +36 -1
  261. package/dist/vite/client.js.map +1 -1
  262. package/docs/content/a2a-protocol.mdx +12 -0
  263. package/docs/content/locales/ar-SA/a2a-protocol.mdx +12 -0
  264. package/docs/content/locales/ar-SA/pr-visual-recap.mdx +3 -3
  265. package/docs/content/locales/ar-SA/pure-agent-apps.mdx +4 -0
  266. package/docs/content/locales/de-DE/a2a-protocol.mdx +12 -0
  267. package/docs/content/locales/de-DE/pr-visual-recap.mdx +3 -3
  268. package/docs/content/locales/de-DE/pure-agent-apps.mdx +4 -0
  269. package/docs/content/locales/es-ES/a2a-protocol.mdx +12 -0
  270. package/docs/content/locales/es-ES/pr-visual-recap.mdx +3 -3
  271. package/docs/content/locales/es-ES/pure-agent-apps.mdx +4 -0
  272. package/docs/content/locales/fr-FR/a2a-protocol.mdx +12 -0
  273. package/docs/content/locales/fr-FR/pr-visual-recap.mdx +3 -3
  274. package/docs/content/locales/fr-FR/pure-agent-apps.mdx +4 -0
  275. package/docs/content/locales/hi-IN/a2a-protocol.mdx +12 -0
  276. package/docs/content/locales/hi-IN/pr-visual-recap.mdx +3 -3
  277. package/docs/content/locales/hi-IN/pure-agent-apps.mdx +4 -0
  278. package/docs/content/locales/ja-JP/a2a-protocol.mdx +12 -0
  279. package/docs/content/locales/ja-JP/pr-visual-recap.mdx +3 -3
  280. package/docs/content/locales/ja-JP/pure-agent-apps.mdx +4 -0
  281. package/docs/content/locales/ko-KR/a2a-protocol.mdx +12 -0
  282. package/docs/content/locales/ko-KR/pr-visual-recap.mdx +3 -3
  283. package/docs/content/locales/ko-KR/pure-agent-apps.mdx +4 -0
  284. package/docs/content/locales/pt-BR/a2a-protocol.mdx +12 -0
  285. package/docs/content/locales/pt-BR/pr-visual-recap.mdx +3 -3
  286. package/docs/content/locales/pt-BR/pure-agent-apps.mdx +4 -0
  287. package/docs/content/locales/zh-CN/a2a-protocol.mdx +12 -0
  288. package/docs/content/locales/zh-CN/pr-visual-recap.mdx +3 -3
  289. package/docs/content/locales/zh-CN/pure-agent-apps.mdx +4 -0
  290. package/docs/content/locales/zh-TW/a2a-protocol.mdx +12 -0
  291. package/docs/content/locales/zh-TW/pr-visual-recap.mdx +3 -3
  292. package/docs/content/locales/zh-TW/pure-agent-apps.mdx +4 -0
  293. package/docs/content/pr-visual-recap.mdx +3 -3
  294. package/docs/content/pure-agent-apps.mdx +22 -0
  295. package/package.json +2 -2
@@ -6,10 +6,12 @@ import {
6
6
  IconTrash,
7
7
  IconArrowsMaximize,
8
8
  IconArrowsMinimize,
9
+ IconDotsVertical,
9
10
  IconExternalLink,
11
+ IconMessageCircle,
10
12
  } from "@tabler/icons-react";
11
13
  import { useQuery } from "@tanstack/react-query";
12
- import { useMemo, useState } from "react";
14
+ import { useCallback, useMemo, useState } from "react";
13
15
 
14
16
  import {
15
17
  AlertDialog,
@@ -22,13 +24,24 @@ import {
22
24
  AlertDialogTitle,
23
25
  } from "@/components/ui/alert-dialog";
24
26
  import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
27
+ import {
28
+ DropdownMenu,
29
+ DropdownMenuContent,
30
+ DropdownMenuItem,
31
+ DropdownMenuTrigger,
32
+ } from "@/components/ui/dropdown-menu";
25
33
  import { Skeleton } from "@/components/ui/skeleton";
26
34
  import {
27
35
  Tooltip,
28
36
  TooltipContent,
29
37
  TooltipTrigger,
30
38
  } from "@/components/ui/tooltip";
39
+ import type {
40
+ DashboardPanelChatContextArgs,
41
+ SelectDashboardPanelOptions,
42
+ } from "@/hooks/use-dashboard-chat-context";
31
43
  import { useMetricsQuery } from "@/lib/query-metrics";
44
+ import { cn } from "@/lib/utils";
32
45
 
33
46
  import { ExplorerChart } from "../explorer/components/ExplorerChart";
34
47
  import { buildSql } from "../explorer/sql-builder";
@@ -42,6 +55,11 @@ interface ChartCardProps {
42
55
  onToggleWidth: () => void;
43
56
  onEdit: () => void;
44
57
  editable?: boolean;
58
+ selectedForChat?: boolean;
59
+ selectPanelForChat: (
60
+ panel: DashboardPanelChatContextArgs,
61
+ options?: SelectDashboardPanelOptions,
62
+ ) => void;
45
63
  }
46
64
 
47
65
  async function fetchConfig(id: string): Promise<ExplorerConfig | null> {
@@ -66,6 +84,8 @@ export function DashboardChartCard({
66
84
  onToggleWidth,
67
85
  onEdit,
68
86
  editable = true,
87
+ selectedForChat = false,
88
+ selectPanelForChat,
69
89
  }: ChartCardProps) {
70
90
  const t = useT();
71
91
  const [confirmOpen, setConfirmOpen] = useState(false);
@@ -100,15 +120,59 @@ export function DashboardChartCard({
100
120
  );
101
121
 
102
122
  const isLoading = !config || queryLoading;
123
+ const displayTitle = config?.name ?? configName;
124
+ const handleSelectForChat = useCallback(
125
+ (options?: SelectDashboardPanelOptions) => {
126
+ selectPanelForChat(
127
+ {
128
+ panelId: chart.id,
129
+ panelTitle: displayTitle,
130
+ panelKind: config?.chartType === "table" ? "table" : "chart",
131
+ chartType: config?.chartType,
132
+ configId: chart.configId,
133
+ },
134
+ options,
135
+ );
136
+ },
137
+ [
138
+ chart.configId,
139
+ chart.id,
140
+ config?.chartType,
141
+ displayTitle,
142
+ selectPanelForChat,
143
+ ],
144
+ );
145
+ const handleCardClick = useCallback(
146
+ (event: React.MouseEvent<HTMLDivElement>) => {
147
+ const target = event.target;
148
+ if (
149
+ target instanceof Element &&
150
+ target.closest(
151
+ "button, a, input, textarea, select, [role='menuitem'], [data-no-panel-chat-select]",
152
+ )
153
+ ) {
154
+ return;
155
+ }
156
+ handleSelectForChat({ focus: false });
157
+ },
158
+ [handleSelectForChat],
159
+ );
103
160
 
104
161
  return (
105
162
  <div
106
163
  ref={setNodeRef}
164
+ onClick={handleCardClick}
107
165
  style={style}
108
166
  data-dragging={isDragging ? "true" : undefined}
167
+ data-chat-selected={selectedForChat ? "true" : undefined}
109
168
  className={`explorer-dashboard-card group relative ${chart.width === 2 ? "explorer-dashboard-card-wide" : ""}`}
110
169
  >
111
- <Card className="h-full">
170
+ <Card
171
+ className={cn(
172
+ "h-full transition-colors",
173
+ selectedForChat && "border-foreground/35 ring-1 ring-foreground/10",
174
+ )}
175
+ >
112
176
  <CardHeader className="pb-2 flex flex-row items-center gap-2">
113
177
  {editable ? (
114
178
  <button
@@ -120,8 +184,37 @@ export function DashboardChartCard({
120
184
  </button>
121
185
  ) : null}
122
186
  <CardTitle className="text-sm font-medium flex-1 truncate">
123
- {config?.name ?? configName}
187
+ {displayTitle}
124
188
  </CardTitle>
189
+ <div className="opacity-0 transition-opacity group-hover:opacity-100 focus-within:opacity-100">
190
+ <DropdownMenu>
191
+ <Tooltip>
192
+ <TooltipTrigger asChild>
193
+ <DropdownMenuTrigger asChild>
194
+ <button
195
+ className="p-1 rounded text-muted-foreground hover:text-foreground transition-colors"
196
+ aria-label={t("sqlDashboard.panelOptions")}
197
+ >
198
+ <IconDotsVertical className="h-3.5 w-3.5" />
199
+ </button>
200
+ </DropdownMenuTrigger>
201
+ </TooltipTrigger>
202
+ <TooltipContent>
203
+ {t("sqlDashboard.panelOptions")}
204
+ </TooltipContent>
205
+ </Tooltip>
206
+ <DropdownMenuContent align="end" className="w-44">
207
+ <DropdownMenuItem
208
+ onSelect={() =>
209
+ handleSelectForChat({ openSidebar: true, focus: true })
210
+ }
211
+ >
212
+ <IconMessageCircle className="h-4 w-4 mr-2" />
213
+ {t("explorerDashboard.chatWithChart")}
214
+ </DropdownMenuItem>
215
+ </DropdownMenuContent>
216
+ </DropdownMenu>
217
+ </div>
125
218
  {editable ? (
126
219
  <div className="flex items-center gap-1 opacity-0 group-hover:opacity-100 transition-opacity">
127
220
  <Tooltip>
@@ -205,7 +205,7 @@ export default function ExplorerDashboardPage() {
205
205
  );
206
206
  const canEdit = resourceCanEdit(resourceAccess);
207
207
  const canManage = resourceCanManage(resourceAccess);
208
- useDashboardChatContext({
208
+ const { selectedPanelId, selectPanelForChat } = useDashboardChatContext({
209
209
  id: dashboardId,
210
210
  kind: "explorer",
211
211
  title: dashboard?.name,
@@ -797,6 +797,8 @@ export default function ExplorerDashboardPage() {
797
797
  navigate(`/dashboards/explorer?config=${chart.configId}`)
798
798
  }
799
799
  editable={canEdit}
800
+ selectedForChat={selectedPanelId === chart.id}
801
+ selectPanelForChat={selectPanelForChat}
800
802
  />
801
803
  ))}
802
804
  </div>
@@ -10,6 +10,7 @@ import {
10
10
  IconTrash,
11
11
  IconCode,
12
12
  IconDownload,
13
+ IconMessageCircle,
13
14
  } from "@tabler/icons-react";
14
15
  import { useIsFetching, useQueryClient } from "@tanstack/react-query";
15
16
  import { memo, useCallback, useEffect, useMemo, useRef, useState } from "react";
@@ -46,6 +47,8 @@ import {
46
47
  TooltipContent,
47
48
  TooltipTrigger,
48
49
  } from "@/components/ui/tooltip";
50
+ import type { SelectDashboardPanelOptions } from "@/hooks/use-dashboard-chat-context";
51
+ import { cn } from "@/lib/utils";
49
52
 
50
53
  import { serializePanelSql } from "./panel-sql";
51
54
  import type { SqlPanel } from "./types";
@@ -62,6 +65,8 @@ interface SqlChartCardProps {
62
65
  editable?: boolean;
63
66
  eagerLoad?: boolean;
64
67
  isDragSource?: boolean;
68
+ selectedForChat?: boolean;
69
+ onSelectForChat?: (options?: SelectDashboardPanelOptions) => void;
65
70
  }
66
71
 
67
72
  const PanelDragHandle = memo(function PanelDragHandle({
@@ -115,6 +120,8 @@ export function SqlChartCard({
115
120
  editable = true,
116
121
  eagerLoad = false,
117
122
  isDragSource = false,
123
+ selectedForChat = false,
124
+ onSelectForChat,
118
125
  }: SqlChartCardProps) {
119
126
  const t = useT();
120
127
  const queryClient = useQueryClient();
@@ -144,6 +151,12 @@ export function SqlChartCard({
144
151
  const chartHasCachedData =
145
152
  queryClient.getQueryData(chartQueryKey) !== undefined;
146
153
  const isChartRefreshing = chartHasCachedData && chartFetchCount > 0;
154
+ const extensionId =
155
+ panel.chartType === "extension"
156
+ ? ((panel.config as Record<string, unknown> | undefined)?.extensionId as
157
+ | string
158
+ | undefined)
159
+ : undefined;
147
160
 
148
161
  const setCardNodeRef = useCallback((node: HTMLDivElement | null) => {
149
162
  cardRef.current = node;
@@ -160,6 +173,22 @@ export function SqlChartCard({
160
173
  });
161
174
  }, [chartQueryKey, queryClient]);
162
175
 
176
+ const handleCardClick = useCallback(
177
+ (event: React.MouseEvent<HTMLDivElement>) => {
178
+ const target = event.target;
179
+ if (
180
+ target instanceof Element &&
181
+ target.closest(
182
+ "button, a, input, textarea, select, [role='menuitem'], [data-no-panel-chat-select]",
183
+ )
184
+ ) {
185
+ return;
186
+ }
187
+ onSelectForChat?.({ focus: false });
188
+ },
189
+ [onSelectForChat],
190
+ );
191
+
163
192
  useEffect(() => {
164
193
  if (eagerLoad) {
165
194
  setShouldLoadData(true);
@@ -299,14 +328,17 @@ export function SqlChartCard({
299
328
  // actions (full screen, refresh, open embedded extension); editable
300
329
  // dashboards also get delete and drag.
301
330
  if (panel.chartType === "extension") {
302
- const extensionId = (panel.config as Record<string, unknown> | undefined)
303
- ?.extensionId as string | undefined;
304
331
  return (
305
332
  <div
306
333
  ref={setCardNodeRef}
334
+ onClick={handleCardClick}
307
335
  style={isDragSource ? { zIndex: 50 } : undefined}
308
336
  data-dragging={isDragSource ? "true" : undefined}
309
- className="dashboard-extension-card group relative h-full"
337
+ data-chat-selected={selectedForChat ? "true" : undefined}
338
+ className={cn(
339
+ "dashboard-extension-card group relative h-full rounded-lg border border-transparent transition-colors",
340
+ selectedForChat && "border-foreground/35 ring-1 ring-foreground/10",
341
+ )}
310
342
  >
311
343
  {!expanded && (
312
344
  <SqlChart
@@ -332,6 +364,15 @@ export function SqlChartCard({
332
364
  <TooltipContent>{t("sqlDashboard.panelOptions")}</TooltipContent>
333
365
  </Tooltip>
334
366
  <DropdownMenuContent align="end" className="w-44">
367
+ <DropdownMenuItem
368
+ onSelect={() =>
369
+ onSelectForChat?.({ openSidebar: true, focus: true })
370
+ }
371
+ >
372
+ <IconMessageCircle className="h-4 w-4 mr-2" />
373
+ {t("sqlDashboard.chatWithPanel")}
374
+ </DropdownMenuItem>
375
+ <DropdownMenuSeparator />
335
376
  <DropdownMenuItem onSelect={() => setExpanded(true)}>
336
377
  <IconMaximize className="h-4 w-4 mr-2" />
337
378
  {t("sqlDashboard.fullScreen")}
@@ -437,11 +478,18 @@ export function SqlChartCard({
437
478
  return (
438
479
  <div
439
480
  ref={setCardNodeRef}
481
+ onClick={handleCardClick}
440
482
  style={isDragSource ? { zIndex: 50 } : undefined}
441
483
  data-dragging={isDragSource ? "true" : undefined}
484
+ data-chat-selected={selectedForChat ? "true" : undefined}
442
485
  className="dashboard-chart-card group relative h-full hover:z-20 focus-within:z-20"
443
486
  >
444
- <Card className="flex h-full flex-col overflow-visible">
487
+ <Card
488
+ className={cn(
489
+ "flex h-full flex-col overflow-visible transition-colors",
490
+ selectedForChat && "border-foreground/35 ring-1 ring-foreground/10",
491
+ )}
492
+ >
445
493
  <CardHeader className="pb-2 flex flex-row items-center gap-2 shrink-0">
446
494
  <CardTitle className="text-sm font-medium flex-1 truncate">
447
495
  {panel.title}
@@ -499,6 +547,15 @@ export function SqlChartCard({
499
547
  </TooltipContent>
500
548
  </Tooltip>
501
549
  <DropdownMenuContent align="end" className="w-44">
550
+ <DropdownMenuItem
551
+ onSelect={() =>
552
+ onSelectForChat?.({ openSidebar: true, focus: true })
553
+ }
554
+ >
555
+ <IconMessageCircle className="h-4 w-4 mr-2" />
556
+ {t("sqlDashboard.chatWithPanel")}
557
+ </DropdownMenuItem>
558
+ <DropdownMenuSeparator />
502
559
  <DropdownMenuItem onSelect={() => setExpanded(true)}>
503
560
  <IconMaximize className="h-4 w-4 mr-2" />
504
561
  {t("sqlDashboard.fullScreen")}
@@ -92,7 +92,11 @@ import {
92
92
  TooltipContent,
93
93
  TooltipTrigger,
94
94
  } from "@/components/ui/tooltip";
95
- import { useDashboardChatContext } from "@/hooks/use-dashboard-chat-context";
95
+ import {
96
+ useDashboardChatContext,
97
+ type DashboardPanelChatContextArgs,
98
+ type SelectDashboardPanelOptions,
99
+ } from "@/hooks/use-dashboard-chat-context";
96
100
  import { useDashboardViews } from "@/hooks/use-dashboard-views";
97
101
  import { useUserPref } from "@/hooks/use-user-pref";
98
102
  import { incrementItemView } from "@/lib/item-popularity";
@@ -258,6 +262,8 @@ const PanelCell = memo(function PanelCell({
258
262
  editable,
259
263
  eagerLoad,
260
264
  isDragSource,
265
+ selectedForChat,
266
+ selectPanelForChat,
261
267
  onRemovePanel,
262
268
  onEditPanel,
263
269
  onSavePanel,
@@ -268,6 +274,11 @@ const PanelCell = memo(function PanelCell({
268
274
  editable: boolean;
269
275
  eagerLoad: boolean;
270
276
  isDragSource: boolean;
277
+ selectedForChat: boolean;
278
+ selectPanelForChat: (
279
+ panel: DashboardPanelChatContextArgs,
280
+ options?: SelectDashboardPanelOptions,
281
+ ) => void;
271
282
  onRemovePanel: (panelId: string) => void;
272
283
  onEditPanel: (panel: SqlPanel) => void;
273
284
  onSavePanel: (panel: SqlPanel) => Promise<void>;
@@ -289,6 +300,29 @@ const PanelCell = memo(function PanelCell({
289
300
  () => interpolate(serializePanelSql(panel.sql), vars),
290
301
  [panel.sql, vars],
291
302
  );
303
+ const handleSelectForChat = useCallback(
304
+ (options?: SelectDashboardPanelOptions) => {
305
+ const extensionId =
306
+ panel.chartType === "extension" ? panel.config?.extensionId : undefined;
307
+ selectPanelForChat(
308
+ {
309
+ panelId: panel.id,
310
+ panelTitle: panel.title,
311
+ panelKind:
312
+ panel.chartType === "table"
313
+ ? "table"
314
+ : panel.chartType === "extension"
315
+ ? "extension"
316
+ : "chart",
317
+ chartType: panel.chartType,
318
+ source: panel.source,
319
+ extensionId,
320
+ },
321
+ options,
322
+ );
323
+ },
324
+ [panel, selectPanelForChat],
325
+ );
292
326
 
293
327
  return (
294
328
  <div
@@ -323,6 +357,8 @@ const PanelCell = memo(function PanelCell({
323
357
  editable={editable}
324
358
  eagerLoad={eagerLoad}
325
359
  isDragSource={isDragSource}
360
+ selectedForChat={selectedForChat}
361
+ onSelectForChat={handleSelectForChat}
326
362
  />
327
363
  </div>
328
364
  );
@@ -477,7 +513,7 @@ export default function SqlDashboardPage() {
477
513
  const dashboardColumns = clampDashboardColumns(
478
514
  dashboard?.columns ?? DEFAULT_DASHBOARD_COLUMNS,
479
515
  );
480
- useDashboardChatContext({
516
+ const { selectedPanelId, selectPanelForChat } = useDashboardChatContext({
481
517
  id: reportScreenshot ? null : dashboardId,
482
518
  kind: "sql",
483
519
  title: dashboard?.name,
@@ -1859,6 +1895,8 @@ export default function SqlDashboardPage() {
1859
1895
  editable={canEdit}
1860
1896
  eagerLoad={reportScreenshot}
1861
1897
  isDragSource={activeDragPanelId === panel.id}
1898
+ selectedForChat={selectedPanelId === panel.id}
1899
+ selectPanelForChat={selectPanelForChat}
1862
1900
  onRemovePanel={removePanel}
1863
1901
  onEditPanel={openEditPanel}
1864
1902
  onSavePanel={handleSavePanel}
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-07-09
4
+ ---
5
+
6
+ Analytics no longer forgets successful data queries when a long request continues in the background.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-07-09
4
+ ---
5
+
6
+ Dashboard charts keep consistent spacing when they stack vertically
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: added
3
+ date: 2026-07-09
4
+ ---
5
+
6
+ Dashboard charts, tables, and extensions can be selected and discussed directly with the agent.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-07-09
4
+ ---
5
+
6
+ Long-running Analytics requests now recover automatically when a background handoff is interrupted.
@@ -1,3 +1,4 @@
1
+ import { registerDataProgramsShareable } from "@agent-native/core/data-programs";
1
2
  import { createGetDb } from "@agent-native/core/db";
2
3
  import { registerShareableResource } from "@agent-native/core/sharing";
3
4
 
@@ -12,6 +13,11 @@ import * as schema from "./schema.js";
12
13
  export const getDb = createGetDb(schema);
13
14
  export { schema };
14
15
 
16
+ // Core data-program tables live outside analytics/schema.ts; register the
17
+ // sharing type here so get-data-program / resolveAccess work in dev, CLI, and
18
+ // extension iframes (same side-effect pattern as dashboard/analysis below).
19
+ registerDataProgramsShareable();
20
+
15
21
  registerShareableResource({
16
22
  type: "dashboard",
17
23
  resourceTable: schema.dashboards,
@@ -377,9 +377,7 @@ export function useMeetingTranscription({
377
377
  };
378
378
 
379
379
  // Resume the engine that initial start settled on (no fallback here —
380
- // the engine choice was already made below). Keep voice processing
381
- // off: AEC/ducking on the shared mic can make Zoom/Meet callers hear
382
- // the local user at a whisper while Clips is transcribed.
380
+ // the engine choice was already made below).
383
381
  const startAudio = async () => {
384
382
  await restartTranscriptionEngine(
385
383
  session.engine,
@@ -388,7 +386,6 @@ export function useMeetingTranscription({
388
386
  label: selectedMicLabel,
389
387
  },
390
388
  true,
391
- false,
392
389
  );
393
390
  };
394
391
 
@@ -559,9 +556,6 @@ export function useMeetingTranscription({
559
556
 
560
557
  session.engine = await startTranscriptionEngine({
561
558
  mic: { deviceId: selectedMicId, label: selectedMicLabel },
562
- // Match clip recordings: VoiceProcessingIO AEC/ducking on the shared
563
- // mic can tank live meeting volume for remote participants.
564
- voiceProcessing: false,
565
559
  });
566
560
 
567
561
  await invoke("silence_detector_start", {
@@ -69,6 +69,8 @@ import {
69
69
  useMemo,
70
70
  useRef,
71
71
  useState,
72
+ type KeyboardEvent as ReactKeyboardEvent,
73
+ type MouseEvent as ReactMouseEvent,
72
74
  type PointerEvent as ReactPointerEvent,
73
75
  type ReactNode,
74
76
  } from "react";
@@ -1110,7 +1112,11 @@ export function PropertyManagementPopover({
1110
1112
  {triggerTrailing}
1111
1113
  </button>
1112
1114
  </DropdownMenuTrigger>
1113
- <DropdownMenuContent align="start" className="w-72">
1115
+ <DropdownMenuContent
1116
+ align="start"
1117
+ collisionPadding={12}
1118
+ className="relative z-[300] w-72"
1119
+ >
1114
1120
  <div
1115
1121
  className="flex items-center gap-2 p-1"
1116
1122
  onKeyDown={(event) => event.stopPropagation()}
@@ -1379,15 +1385,17 @@ export function PropertyManagementPopover({
1379
1385
  </DropdownMenu>
1380
1386
 
1381
1387
  <AlertDialog open={confirmDeleteOpen} onOpenChange={setConfirmDeleteOpen}>
1382
- <AlertDialogContent>
1383
- <AlertDialogHeader>
1384
- <AlertDialogTitle>
1388
+ <AlertDialogContent className="max-w-sm gap-0 rounded-lg p-5">
1389
+ <AlertDialogHeader className="space-y-0 gap-1.5 text-start">
1390
+ <AlertDialogTitle className="text-base leading-tight tracking-tight">
1385
1391
  {t("editor.properties.deletePropertyQuestion")}
1386
1392
  </AlertDialogTitle>
1387
- <AlertDialogDescription>
1388
- {t("editor.properties.deletePropertyDescription", {
1389
- name: property.definition.name,
1390
- })}
1393
+ <AlertDialogDescription className="leading-normal [text-wrap:pretty]">
1394
+ {t("editor.properties.deletePropertyDescriptionPrefix")}
1395
+ <span className="font-medium text-foreground">
1396
+ {property.definition.name}
1397
+ </span>
1398
+ {t("editor.properties.deletePropertyDescriptionSuffix")}
1391
1399
  </AlertDialogDescription>
1392
1400
  </AlertDialogHeader>
1393
1401
  {isOnlyBlocksField ? (
@@ -1395,12 +1403,12 @@ export function PropertyManagementPopover({
1395
1403
  {t("editor.properties.onlyBlocksPropertyWarning")}
1396
1404
  </div>
1397
1405
  ) : null}
1398
- <AlertDialogFooter>
1399
- <AlertDialogCancel>
1406
+ <AlertDialogFooter className="mt-4 flex-row items-center justify-end gap-2 sm:space-x-0">
1407
+ <AlertDialogCancel className="mt-0 h-8 px-3 focus-visible:ring-1 focus-visible:ring-muted-foreground/40 focus-visible:ring-offset-1">
1400
1408
  {t("editor.properties.cancel")}
1401
1409
  </AlertDialogCancel>
1402
1410
  <AlertDialogAction
1403
- className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
1411
+ className="h-8 bg-destructive px-3 text-destructive-foreground hover:bg-destructive/90 focus-visible:ring-1 focus-visible:ring-muted-foreground/40 focus-visible:ring-offset-1"
1404
1412
  onClick={() => void deleteProperty()}
1405
1413
  >
1406
1414
  {t("editor.properties.deleteProperty")}
@@ -2651,6 +2659,7 @@ export function AddProperty({
2651
2659
  }))
2652
2660
  .filter((group) => group.fields.length > 0);
2653
2661
  const addPropertySearchInputRef = useRef<HTMLInputElement>(null);
2662
+ const addActivationRef = useRef<{ key: string; at: number } | null>(null);
2654
2663
  const [pendingPropertyType, setPendingPropertyType] =
2655
2664
  useState<DocumentPropertyType | null>(null);
2656
2665
  const [pendingSourceFieldId, setPendingSourceFieldId] = useState<
@@ -2718,6 +2727,39 @@ export function AddProperty({
2718
2727
  }
2719
2728
  }
2720
2729
 
2730
+ function runAddPropertyActivation(key: string, action: () => void) {
2731
+ const now = Date.now();
2732
+ const previous = addActivationRef.current;
2733
+ if (previous?.key === key && now - previous.at < 750) return;
2734
+ addActivationRef.current = { key, at: now };
2735
+ action();
2736
+ }
2737
+
2738
+ function activateAddPropertyItem(
2739
+ event: Pick<
2740
+ ReactMouseEvent<HTMLButtonElement>,
2741
+ "button" | "preventDefault" | "stopPropagation"
2742
+ >,
2743
+ key: string,
2744
+ action: () => void,
2745
+ ) {
2746
+ if (event.button !== 0) return;
2747
+ event.preventDefault();
2748
+ event.stopPropagation();
2749
+ runAddPropertyActivation(key, action);
2750
+ }
2751
+
2752
+ function activateAddPropertyItemFromKeyboard(
2753
+ event: ReactKeyboardEvent<HTMLButtonElement>,
2754
+ key: string,
2755
+ action: () => void,
2756
+ ) {
2757
+ if (event.key !== "Enter" && event.key !== " ") return;
2758
+ event.preventDefault();
2759
+ event.stopPropagation();
2760
+ runAddPropertyActivation(key, action);
2761
+ }
2762
+
2721
2763
  return (
2722
2764
  <Popover
2723
2765
  open={open}
@@ -2747,9 +2789,10 @@ export function AddProperty({
2747
2789
  </button>
2748
2790
  </PopoverTrigger>
2749
2791
  <PopoverContent
2750
- align="start"
2792
+ align={variant === "default" ? "start" : "end"}
2793
+ collisionPadding={12}
2751
2794
  portalled={popoversPortalled}
2752
- className="w-80 p-2"
2795
+ className="relative z-[300] w-80 p-2"
2753
2796
  >
2754
2797
  <div className="grid gap-2">
2755
2798
  <div className="flex h-8 items-center gap-1 rounded border border-border bg-background px-2">
@@ -2800,7 +2843,33 @@ export function AddProperty({
2800
2843
  disabled={isAddingProperty}
2801
2844
  aria-busy={pendingSourceFieldId === field.id}
2802
2845
  className="flex w-full items-center gap-2 rounded px-2 py-1.5 text-left text-sm hover:bg-accent disabled:opacity-50"
2803
- onClick={() => void addFromSourceField(field.id)}
2846
+ onPointerDownCapture={(event) =>
2847
+ activateAddPropertyItem(
2848
+ event,
2849
+ `source:${field.id}`,
2850
+ () => {
2851
+ void addFromSourceField(field.id);
2852
+ },
2853
+ )
2854
+ }
2855
+ onClick={(event) =>
2856
+ activateAddPropertyItem(
2857
+ event,
2858
+ `source:${field.id}`,
2859
+ () => {
2860
+ void addFromSourceField(field.id);
2861
+ },
2862
+ )
2863
+ }
2864
+ onKeyDown={(event) =>
2865
+ activateAddPropertyItemFromKeyboard(
2866
+ event,
2867
+ `source:${field.id}`,
2868
+ () => {
2869
+ void addFromSourceField(field.id);
2870
+ },
2871
+ )
2872
+ }
2804
2873
  >
2805
2874
  {pendingSourceFieldId === field.id ? (
2806
2875
  <Spinner className="size-4 shrink-0 text-muted-foreground" />
@@ -2837,7 +2906,25 @@ export function AddProperty({
2837
2906
  className="flex w-full items-center gap-2 rounded px-2 py-1.5 text-left text-sm hover:bg-accent"
2838
2907
  disabled={isAddingProperty}
2839
2908
  aria-busy={pendingPropertyType === type}
2840
- onClick={() => void add(type)}
2909
+ onPointerDownCapture={(event) =>
2910
+ activateAddPropertyItem(event, `type:${type}`, () => {
2911
+ void add(type);
2912
+ })
2913
+ }
2914
+ onClick={(event) =>
2915
+ activateAddPropertyItem(event, `type:${type}`, () => {
2916
+ void add(type);
2917
+ })
2918
+ }
2919
+ onKeyDown={(event) =>
2920
+ activateAddPropertyItemFromKeyboard(
2921
+ event,
2922
+ `type:${type}`,
2923
+ () => {
2924
+ void add(type);
2925
+ },
2926
+ )
2927
+ }
2841
2928
  >
2842
2929
  {pendingPropertyType === type ? (
2843
2930
  <Spinner className="size-4 text-muted-foreground" />