@agent-native/core 0.92.7 → 0.92.8

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 (289) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/core/CHANGELOG.md +12 -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 +2 -2
  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/transcribe-voice.ts +1 -1
  53. package/corpus/core/src/usage/store.ts +13 -4
  54. package/corpus/core/src/vite/client.ts +38 -1
  55. package/corpus/templates/analytics/AGENTS.md +3 -0
  56. package/corpus/templates/analytics/actions/get-data-program.ts +78 -0
  57. package/corpus/templates/analytics/actions/list-data-programs.ts +49 -0
  58. package/corpus/templates/analytics/app/global.css +11 -0
  59. package/corpus/templates/analytics/app/hooks/use-dashboard-chat-context.ts +163 -17
  60. package/corpus/templates/analytics/app/i18n/zh-TW.ts +2 -0
  61. package/corpus/templates/analytics/app/i18n-data.ts +20 -0
  62. package/corpus/templates/analytics/app/pages/adhoc/explorer-dashboard/ChartCard.tsx +96 -3
  63. package/corpus/templates/analytics/app/pages/adhoc/explorer-dashboard/index.tsx +3 -1
  64. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/SqlChartCard.tsx +61 -4
  65. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +40 -2
  66. package/corpus/templates/analytics/changelog/2026-07-09-analytics-no-longer-forgets-successful-data-queries-when-a-l.md +6 -0
  67. package/corpus/templates/analytics/changelog/2026-07-09-dashboard-charts-keep-consistent-spacing-when-they-stack-ver.md +6 -0
  68. package/corpus/templates/analytics/changelog/2026-07-09-dashboard-charts-tables-and-extensions-can-be-selected-and-d.md +6 -0
  69. package/corpus/templates/analytics/changelog/2026-07-09-long-running-analytics-requests-now-recover-automatically-wh.md +6 -0
  70. package/corpus/templates/analytics/server/db/index.ts +6 -0
  71. package/corpus/templates/clips/desktop/src/hooks/useMeetingTranscription.ts +1 -7
  72. package/corpus/templates/content/app/components/editor/DocumentProperties.tsx +102 -15
  73. package/corpus/templates/content/app/hooks/use-content-database.ts +52 -0
  74. package/corpus/templates/content/app/hooks/use-document-properties.ts +50 -6
  75. package/corpus/templates/content/app/i18n/zh-TW.ts +2 -0
  76. package/corpus/templates/content/app/i18n-data.ts +28 -0
  77. package/corpus/templates/content/changelog/2026-07-09-notion-conflict-warnings-no-longer-flash-during-normal-synce.md +6 -0
  78. package/corpus/templates/content/changelog/2026-07-09-property-menus-and-delete-confirmations-now-open-visibly-and.md +6 -0
  79. package/corpus/templates/content/server/lib/notion-sync.ts +130 -28
  80. package/corpus/templates/design/actions/add-breakpoint.ts +48 -68
  81. package/corpus/templates/design/actions/add-localhost-screens.ts +496 -61
  82. package/corpus/templates/design/actions/apply-component-prop-edit.ts +2 -18
  83. package/corpus/templates/design/actions/apply-design-token-edit.ts +51 -82
  84. package/corpus/templates/design/actions/apply-tweaks.ts +63 -41
  85. package/corpus/templates/design/actions/capture-design-state.ts +2 -2
  86. package/corpus/templates/design/actions/connect-localhost.ts +58 -12
  87. package/corpus/templates/design/actions/create-component.ts +2 -18
  88. package/corpus/templates/design/actions/create-design-branch.ts +38 -18
  89. package/corpus/templates/design/actions/create-fusion-app.ts +15 -11
  90. package/corpus/templates/design/actions/delete-file.ts +19 -34
  91. package/corpus/templates/design/actions/deploy-design-preview.ts +59 -27
  92. package/corpus/templates/design/actions/deploy-fusion-app.ts +22 -15
  93. package/corpus/templates/design/actions/export-pdf.ts +2 -1
  94. package/corpus/templates/design/actions/export-zip.ts +9 -3
  95. package/corpus/templates/design/actions/generate-design.ts +107 -70
  96. package/corpus/templates/design/actions/get-component-details.ts +2 -18
  97. package/corpus/templates/design/actions/get-design-branch-diff.ts +2 -3
  98. package/corpus/templates/design/actions/get-design-surface-index.ts +2 -18
  99. package/corpus/templates/design/actions/get-design.ts +2 -1
  100. package/corpus/templates/design/actions/grant-localhost-write-consent.ts +7 -1
  101. package/corpus/templates/design/actions/import-design-tokens.ts +114 -76
  102. package/corpus/templates/design/actions/index-components.ts +2 -18
  103. package/corpus/templates/design/actions/list-design-source-capabilities.ts +23 -28
  104. package/corpus/templates/design/actions/list-local-files.ts +9 -2
  105. package/corpus/templates/design/actions/migrate-board-objects-to-file.ts +82 -98
  106. package/corpus/templates/design/actions/open-component-source.ts +2 -18
  107. package/corpus/templates/design/actions/open-visual-edit.ts +19 -1
  108. package/corpus/templates/design/actions/present-design-variants.ts +70 -70
  109. package/corpus/templates/design/actions/preview-component-prop-edit.ts +4 -14
  110. package/corpus/templates/design/actions/read-local-file.ts +9 -2
  111. package/corpus/templates/design/actions/remove-breakpoint.ts +40 -61
  112. package/corpus/templates/design/actions/rename-screen.ts +425 -0
  113. package/corpus/templates/design/actions/request-localhost-write-consent.ts +12 -2
  114. package/corpus/templates/design/actions/revoke-localhost-write-consent.ts +9 -2
  115. package/corpus/templates/design/actions/sync-fusion-app.ts +56 -39
  116. package/corpus/templates/design/actions/update-design.ts +376 -61
  117. package/corpus/templates/design/actions/update-file.ts +455 -188
  118. package/corpus/templates/design/actions/write-local-file.ts +10 -2
  119. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +685 -608
  120. package/corpus/templates/design/app/components/design/LayersPanel.tsx +43 -15
  121. package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +576 -2015
  122. package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +62 -14
  123. package/corpus/templates/design/app/components/design/bridge/embedded-wheel.bridge.ts +263 -25
  124. package/corpus/templates/design/app/components/design/design-canvas/annotation-submit.ts +34 -0
  125. package/corpus/templates/design/app/components/design/design-canvas/coordinate-transforms.ts +40 -0
  126. package/corpus/templates/design/app/components/design/design-canvas/creation.ts +47 -0
  127. package/corpus/templates/design/app/components/design/design-canvas/element-payload.ts +27 -0
  128. package/corpus/templates/design/app/components/design/design-canvas/embedded-frame.ts +62 -0
  129. package/corpus/templates/design/app/components/design/design-canvas/external-preview.ts +137 -0
  130. package/corpus/templates/design/app/components/design/design-canvas/file-drop.ts +10 -0
  131. package/corpus/templates/design/app/components/design/design-canvas/hit-test.ts +23 -0
  132. package/corpus/templates/design/app/components/design/design-canvas/iframe-events.ts +23 -0
  133. package/corpus/templates/design/app/components/design/design-canvas/iframe-pan.ts +177 -0
  134. package/corpus/templates/design/app/components/design/design-canvas/motion-types.ts +7 -0
  135. package/corpus/templates/design/app/components/design/design-canvas/pending-text-edit.ts +62 -0
  136. package/corpus/templates/design/app/components/design/index.ts +2 -2
  137. package/corpus/templates/design/app/components/design/multi-screen/canvas-tools.ts +100 -0
  138. package/corpus/templates/design/app/components/design/multi-screen/coordinate-transforms.ts +81 -0
  139. package/corpus/templates/design/app/components/design/multi-screen/cross-screen-drop.ts +23 -13
  140. package/corpus/templates/design/app/components/design/multi-screen/culling.ts +238 -19
  141. package/corpus/templates/design/app/components/design/multi-screen/draft-primitives.ts +424 -0
  142. package/corpus/templates/design/app/components/design/multi-screen/frame-geometry.ts +341 -0
  143. package/corpus/templates/design/app/components/design/multi-screen/iframe-targeting.ts +52 -0
  144. package/corpus/templates/design/app/components/design/multi-screen/overview-layout.ts +62 -0
  145. package/corpus/templates/design/app/components/design/multi-screen/primitive-drop-target.ts +283 -0
  146. package/corpus/templates/design/app/components/design/multi-screen/screen-content-cache.ts +272 -0
  147. package/corpus/templates/design/app/components/design/multi-screen/types.ts +5 -1
  148. package/corpus/templates/design/app/components/design/multi-screen/wheel-gesture-state.ts +12 -0
  149. package/corpus/templates/design/app/components/visual-editor/DrawOverlay.tsx +325 -84
  150. package/corpus/templates/design/app/hooks/use-navigation-state.ts +15 -1
  151. package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +119 -47
  152. package/corpus/templates/design/app/i18n/zh-TW.ts +9 -0
  153. package/corpus/templates/design/app/i18n-data.ts +223 -0
  154. package/corpus/templates/design/app/lib/design-save-outbox.ts +379 -0
  155. package/corpus/templates/design/app/lib/png-clipboard.ts +113 -0
  156. package/corpus/templates/design/app/pages/design-editor/canvas-primitives.ts +229 -0
  157. package/corpus/templates/design/app/pages/design-editor/code-layer-state.ts +918 -0
  158. package/corpus/templates/design/app/pages/design-editor/collab-sync.ts +43 -0
  159. package/corpus/templates/design/app/pages/design-editor/cross-screen-text-color.ts +336 -0
  160. package/corpus/templates/design/app/pages/design-editor/data-operations.ts +270 -0
  161. package/corpus/templates/design/app/pages/design-editor/dom-guards.ts +24 -0
  162. package/corpus/templates/design/app/pages/design-editor/dom-utils.ts +11 -0
  163. package/corpus/templates/design/app/pages/design-editor/editor-session.ts +20 -0
  164. package/corpus/templates/design/app/pages/design-editor/editor-state.ts +408 -0
  165. package/corpus/templates/design/app/pages/design-editor/export-capture.ts +115 -0
  166. package/corpus/templates/design/app/pages/design-editor/geometry-persistence.ts +93 -0
  167. package/corpus/templates/design/app/pages/design-editor/history.ts +169 -0
  168. package/corpus/templates/design/app/pages/design-editor/layout-operations.ts +185 -0
  169. package/corpus/templates/design/app/pages/design-editor/motion-state.ts +309 -0
  170. package/corpus/templates/design/app/pages/design-editor/overview-camera.ts +438 -0
  171. package/corpus/templates/design/app/pages/design-editor/pending-edits.ts +510 -0
  172. package/corpus/templates/design/app/pages/design-editor/portable-style.ts +115 -0
  173. package/corpus/templates/design/app/pages/design-editor/selection-state.ts +337 -0
  174. package/corpus/templates/design/app/pages/design-editor/style-utils.ts +5 -0
  175. package/corpus/templates/design/app/pages/design-editor/tool-state.ts +92 -0
  176. package/corpus/templates/design/app/pages/design-editor/tweak-save.ts +87 -0
  177. package/corpus/templates/design/app/pages/design-editor/types.ts +36 -0
  178. package/corpus/templates/design/app/routes/design.$id.tsx +11 -1
  179. package/corpus/templates/design/changelog/2026-07-09-design-edits-canvas-positions-tools-and-tab-context-now-pers.md +6 -0
  180. package/corpus/templates/design/changelog/2026-07-09-figma-style-shortcuts-drawing-annotations-and-cross-screen-d.md +6 -0
  181. package/corpus/templates/design/changelog/2026-07-09-hand-and-scale-tools-now-keep-their-active-toolbar-identity-.md +6 -0
  182. package/corpus/templates/design/changelog/2026-07-09-large-multi-screen-designs-now-stay-responsive-during-long-c.md +6 -0
  183. package/corpus/templates/design/changelog/2026-07-09-layer-drags-now-land-exactly-where-the-insertion-indicator-s.md +6 -0
  184. package/corpus/templates/design/server/db/index.ts +2 -52
  185. package/corpus/templates/design/server/db/schema.ts +16 -0
  186. package/corpus/templates/design/server/lib/design-data-access.ts +70 -0
  187. package/corpus/templates/design/server/lib/design-data-mutation.ts +249 -0
  188. package/corpus/templates/design/server/lib/fusion-screens.ts +89 -76
  189. package/corpus/templates/design/server/lib/import-design-files.ts +76 -35
  190. package/corpus/templates/design/server/lib/verify-write-grant.ts +7 -2
  191. package/corpus/templates/design/server/plugins/db.ts +19 -0
  192. package/corpus/templates/design/server/source-workspace.ts +12 -13
  193. package/corpus/templates/design/shared/resolve-tweaks.ts +15 -0
  194. package/corpus/templates/design/shared/screen-rename.ts +42 -0
  195. package/corpus/templates/design/shared/source-mode.ts +84 -4
  196. package/dist/agent/engine/builder-engine.d.ts +1 -1
  197. package/dist/agent/engine/builder-engine.d.ts.map +1 -1
  198. package/dist/agent/engine/builtin.js +1 -1
  199. package/dist/agent/engine/builtin.js.map +1 -1
  200. package/dist/agent/model-config.d.ts +9 -9
  201. package/dist/agent/model-config.d.ts.map +1 -1
  202. package/dist/agent/model-config.js +30 -30
  203. package/dist/agent/model-config.js.map +1 -1
  204. package/dist/agent/production-agent.d.ts +60 -1
  205. package/dist/agent/production-agent.d.ts.map +1 -1
  206. package/dist/agent/production-agent.js +106 -7
  207. package/dist/agent/production-agent.js.map +1 -1
  208. package/dist/cli/design-connect.d.ts +30 -1
  209. package/dist/cli/design-connect.d.ts.map +1 -1
  210. package/dist/cli/design-connect.js +359 -75
  211. package/dist/cli/design-connect.js.map +1 -1
  212. package/dist/cli/recap.js +2 -2
  213. package/dist/cli/recap.js.map +1 -1
  214. package/dist/client/AgentPanel.d.ts.map +1 -1
  215. package/dist/client/AgentPanel.js +6 -1
  216. package/dist/client/AgentPanel.js.map +1 -1
  217. package/dist/client/agent-chat-adapter.d.ts.map +1 -1
  218. package/dist/client/agent-chat-adapter.js +10 -5
  219. package/dist/client/agent-chat-adapter.js.map +1 -1
  220. package/dist/client/composer/TiptapComposer.js +1 -1
  221. package/dist/client/composer/TiptapComposer.js.map +1 -1
  222. package/dist/client/index.d.ts +1 -1
  223. package/dist/client/index.d.ts.map +1 -1
  224. package/dist/client/index.js +1 -1
  225. package/dist/client/index.js.map +1 -1
  226. package/dist/client/org/TeamPage.d.ts.map +1 -1
  227. package/dist/client/org/TeamPage.js +6 -5
  228. package/dist/client/org/TeamPage.js.map +1 -1
  229. package/dist/client/use-action.d.ts +32 -0
  230. package/dist/client/use-action.d.ts.map +1 -1
  231. package/dist/client/use-action.js +68 -1
  232. package/dist/client/use-action.js.map +1 -1
  233. package/dist/collab/struct-routes.d.ts +1 -1
  234. package/dist/db/client.d.ts +3 -0
  235. package/dist/db/client.d.ts.map +1 -1
  236. package/dist/db/client.js +7 -2
  237. package/dist/db/client.js.map +1 -1
  238. package/dist/db/create-get-db.d.ts.map +1 -1
  239. package/dist/db/create-get-db.js +2 -2
  240. package/dist/db/create-get-db.js.map +1 -1
  241. package/dist/notifications/routes.d.ts +3 -3
  242. package/dist/resources/handlers.d.ts +2 -2
  243. package/dist/scripts/agent-engines/manage-agent-engine.js +1 -1
  244. package/dist/scripts/agent-engines/manage-agent-engine.js.map +1 -1
  245. package/dist/scripts/agent-engines/set-agent-engine.js +1 -1
  246. package/dist/scripts/agent-engines/set-agent-engine.js.map +1 -1
  247. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  248. package/dist/server/transcribe-voice.js +1 -1
  249. package/dist/server/transcribe-voice.js.map +1 -1
  250. package/dist/usage/store.d.ts.map +1 -1
  251. package/dist/usage/store.js +13 -4
  252. package/dist/usage/store.js.map +1 -1
  253. package/dist/vite/client.d.ts.map +1 -1
  254. package/dist/vite/client.js +36 -1
  255. package/dist/vite/client.js.map +1 -1
  256. package/docs/content/a2a-protocol.mdx +12 -0
  257. package/docs/content/locales/ar-SA/a2a-protocol.mdx +12 -0
  258. package/docs/content/locales/ar-SA/pr-visual-recap.mdx +3 -3
  259. package/docs/content/locales/ar-SA/pure-agent-apps.mdx +4 -0
  260. package/docs/content/locales/de-DE/a2a-protocol.mdx +12 -0
  261. package/docs/content/locales/de-DE/pr-visual-recap.mdx +3 -3
  262. package/docs/content/locales/de-DE/pure-agent-apps.mdx +4 -0
  263. package/docs/content/locales/es-ES/a2a-protocol.mdx +12 -0
  264. package/docs/content/locales/es-ES/pr-visual-recap.mdx +3 -3
  265. package/docs/content/locales/es-ES/pure-agent-apps.mdx +4 -0
  266. package/docs/content/locales/fr-FR/a2a-protocol.mdx +12 -0
  267. package/docs/content/locales/fr-FR/pr-visual-recap.mdx +3 -3
  268. package/docs/content/locales/fr-FR/pure-agent-apps.mdx +4 -0
  269. package/docs/content/locales/hi-IN/a2a-protocol.mdx +12 -0
  270. package/docs/content/locales/hi-IN/pr-visual-recap.mdx +3 -3
  271. package/docs/content/locales/hi-IN/pure-agent-apps.mdx +4 -0
  272. package/docs/content/locales/ja-JP/a2a-protocol.mdx +12 -0
  273. package/docs/content/locales/ja-JP/pr-visual-recap.mdx +3 -3
  274. package/docs/content/locales/ja-JP/pure-agent-apps.mdx +4 -0
  275. package/docs/content/locales/ko-KR/a2a-protocol.mdx +12 -0
  276. package/docs/content/locales/ko-KR/pr-visual-recap.mdx +3 -3
  277. package/docs/content/locales/ko-KR/pure-agent-apps.mdx +4 -0
  278. package/docs/content/locales/pt-BR/a2a-protocol.mdx +12 -0
  279. package/docs/content/locales/pt-BR/pr-visual-recap.mdx +3 -3
  280. package/docs/content/locales/pt-BR/pure-agent-apps.mdx +4 -0
  281. package/docs/content/locales/zh-CN/a2a-protocol.mdx +12 -0
  282. package/docs/content/locales/zh-CN/pr-visual-recap.mdx +3 -3
  283. package/docs/content/locales/zh-CN/pure-agent-apps.mdx +4 -0
  284. package/docs/content/locales/zh-TW/a2a-protocol.mdx +12 -0
  285. package/docs/content/locales/zh-TW/pr-visual-recap.mdx +3 -3
  286. package/docs/content/locales/zh-TW/pure-agent-apps.mdx +4 -0
  287. package/docs/content/pr-visual-recap.mdx +3 -3
  288. package/docs/content/pure-agent-apps.mdx +22 -0
  289. package/package.json +2 -2
@@ -1958,6 +1958,9 @@ const editorPropertiesMessages = {
1958
1958
  deleteProperty: "Delete property",
1959
1959
  deletePropertyDescription:
1960
1960
  'This removes "{{name}}" and its values from every document in this workspace.',
1961
+ deletePropertyDescriptionPrefix: 'This removes "',
1962
+ deletePropertyDescriptionSuffix:
1963
+ '" and its values from every document in this workspace.',
1961
1964
  deletePropertyQuestion: "Delete property?",
1962
1965
  duplicateProperty: "Duplicate property",
1963
1966
  editEndDate: "Edit {{name}} end date",
@@ -4978,6 +4981,8 @@ const editorMessagesByLocale = {
4978
4981
  deleteProperty: "删除属性",
4979
4982
  deletePropertyDescription:
4980
4983
  '这将从该工作区中的每个文档中删除"{{name}}"及其值。',
4984
+ deletePropertyDescriptionPrefix: '这将从该工作区中的每个文档中删除"',
4985
+ deletePropertyDescriptionSuffix: '"及其值。',
4981
4986
  deletePropertyQuestion: "删除属性?",
4982
4987
  duplicateProperty: "重复的属性",
4983
4988
  editEndDate: "编辑 {{name}} 结束日期",
@@ -5304,6 +5309,9 @@ const editorMessagesByLocale = {
5304
5309
  deleteProperty: "Eliminar propiedad",
5305
5310
  deletePropertyDescription:
5306
5311
  'Esto elimina "{{name}}" y sus valores de todos los documentos de este espacio de trabajo.',
5312
+ deletePropertyDescriptionPrefix: 'Esto elimina "',
5313
+ deletePropertyDescriptionSuffix:
5314
+ '" y sus valores de todos los documentos de este espacio de trabajo.',
5307
5315
  deletePropertyQuestion: "¿Eliminar propiedad?",
5308
5316
  duplicateProperty: "Propiedad duplicada",
5309
5317
  editEndDate: "Editar fecha de finalización de {{name}}",
@@ -5641,6 +5649,9 @@ const editorMessagesByLocale = {
5641
5649
  deleteProperty: "Supprimer la propriété",
5642
5650
  deletePropertyDescription:
5643
5651
  "Cela supprime « {{name}} » et ses valeurs de chaque document de cet espace de travail.",
5652
+ deletePropertyDescriptionPrefix: "Cela supprime « ",
5653
+ deletePropertyDescriptionSuffix:
5654
+ " » et ses valeurs de chaque document de cet espace de travail.",
5644
5655
  deletePropertyQuestion: "Supprimer la propriété ?",
5645
5656
  duplicateProperty: "Propriété en double",
5646
5657
  editEndDate: "Modifier la date de fin de {{name}}",
@@ -5978,6 +5989,9 @@ const editorMessagesByLocale = {
5978
5989
  deleteProperty: "Eigenschaft löschen",
5979
5990
  deletePropertyDescription:
5980
5991
  'Dadurch werden „{{name}}" und seine Werte aus jedem Dokument in diesem Arbeitsbereich entfernt.',
5992
+ deletePropertyDescriptionPrefix: "Dadurch werden „",
5993
+ deletePropertyDescriptionSuffix:
5994
+ '" und seine Werte aus jedem Dokument in diesem Arbeitsbereich entfernt.',
5981
5995
  deletePropertyQuestion: "Eigenschaft löschen?",
5982
5996
  duplicateProperty: "Doppelte Eigenschaft",
5983
5997
  editEndDate: "{{name}}-Enddatum bearbeiten",
@@ -6315,6 +6329,9 @@ const editorMessagesByLocale = {
6315
6329
  deleteProperty: "プロパティの削除",
6316
6330
  deletePropertyDescription:
6317
6331
  "これにより、このワークスペース内のすべてのドキュメントから「{{name}}」とその値が削除されます。",
6332
+ deletePropertyDescriptionPrefix:
6333
+ "これにより、このワークスペース内のすべてのドキュメントから「",
6334
+ deletePropertyDescriptionSuffix: "」とその値が削除されます。",
6318
6335
  deletePropertyQuestion: "プロパティを削除しますか?",
6319
6336
  duplicateProperty: "重複したプロパティ",
6320
6337
  editEndDate: "{{name}} の終了日を編集",
@@ -6645,6 +6662,9 @@ const editorMessagesByLocale = {
6645
6662
  deleteProperty: "속성 삭제",
6646
6663
  deletePropertyDescription:
6647
6664
  '이렇게 하면 이 작업공간의 모든 문서에서 "{{name}}"와 해당 값이 제거됩니다.',
6665
+ deletePropertyDescriptionPrefix:
6666
+ '이렇게 하면 이 작업공간의 모든 문서에서 "',
6667
+ deletePropertyDescriptionSuffix: '"와 해당 값이 제거됩니다.',
6648
6668
  deletePropertyQuestion: "속성을 삭제하시겠습니까?",
6649
6669
  duplicateProperty: "중복된 속성",
6650
6670
  editEndDate: "{{name}} 종료일 수정",
@@ -6978,6 +6998,9 @@ const editorMessagesByLocale = {
6978
6998
  deleteProperty: "Excluir propriedade",
6979
6999
  deletePropertyDescription:
6980
7000
  'Isso remove "{{name}}" e seus valores de todos os documentos nesta área de trabalho.',
7001
+ deletePropertyDescriptionPrefix: 'Isso remove "',
7002
+ deletePropertyDescriptionSuffix:
7003
+ '" e seus valores de todos os documentos nesta área de trabalho.',
6981
7004
  deletePropertyQuestion: "Excluir propriedade?",
6982
7005
  duplicateProperty: "Propriedade duplicada",
6983
7006
  editEndDate: "Editar data de término do {{name}}",
@@ -7311,6 +7334,8 @@ const editorMessagesByLocale = {
7311
7334
  deleteProperty: "संपत्ति हटाएं",
7312
7335
  deletePropertyDescription:
7313
7336
  'यह इस कार्यक्षेत्र के प्रत्येक दस्तावेज़ से "{{name}}" और उसके मानों को हटा देता है।',
7337
+ deletePropertyDescriptionPrefix: 'यह इस कार्यक्षेत्र के प्रत्येक दस्तावेज़ से "',
7338
+ deletePropertyDescriptionSuffix: '" और उसके मानों को हटा देता है।',
7314
7339
  deletePropertyQuestion: "संपत्ति हटाएं?",
7315
7340
  duplicateProperty: "डुप्लिकेट संपत्ति",
7316
7341
  editEndDate: "{{name}} समाप्ति तिथि संपादित करें",
@@ -7638,6 +7663,9 @@ const editorMessagesByLocale = {
7638
7663
  deleteProperty: "حذف الممتلكات",
7639
7664
  deletePropertyDescription:
7640
7665
  'يؤدي هذا إلى إزالة "{{name}}" وقيمه من كل مستند في مساحة العمل هذه.',
7666
+ deletePropertyDescriptionPrefix: 'يؤدي هذا إلى إزالة "',
7667
+ deletePropertyDescriptionSuffix:
7668
+ '" وقيمه من كل مستند في مساحة العمل هذه.',
7641
7669
  deletePropertyQuestion: "هل تريد حذف الخاصية؟",
7642
7670
  duplicateProperty: "خاصية مكررة",
7643
7671
  editEndDate: "تحرير تاريخ انتهاء {{name}}",
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-07-09
4
+ ---
5
+
6
+ Notion conflict warnings no longer flash during normal synced editing
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-07-09
4
+ ---
5
+
6
+ Property menus and delete confirmations now open visibly and respond reliably in database tables.
@@ -1355,36 +1355,138 @@ export async function refreshDocumentSyncStatus(
1355
1355
  return status;
1356
1356
  }
1357
1357
  // Both sides changed since last sync — mark as conflict so the user can
1358
- // pick which side wins. Without this, auto-sync silently stalls whenever
1359
- // the user has unpushed local edits AND Notion also changed, and pulls
1360
- // never happen. Matches the conflict handling in pull/pushDocumentToNotion.
1358
+ // pick which side wins. Take the same per-document claim used by pull/push
1359
+ // before persisting that state: a save-triggered push can be between its
1360
+ // remote write and baseline update here, making both sides look changed
1361
+ // for a few hundred milliseconds. If that push owns the claim, let it
1362
+ // finish instead of flashing a conflict that it immediately clears.
1361
1363
  if (status.localChanged && status.remoteChanged) {
1362
- const link = await getSyncLink(documentId, owner);
1363
- if (link) {
1364
- await upsertSyncLink({
1365
- owner,
1366
- documentId,
1367
- remotePageId: link.remotePageId,
1368
- state: "conflict",
1369
- lastSyncedAt: link.lastSyncedAt,
1370
- lastPulledRemoteUpdatedAt: link.lastPulledRemoteUpdatedAt,
1371
- lastPushedLocalUpdatedAt: link.lastPushedLocalUpdatedAt,
1372
- lastKnownRemoteUpdatedAt: status.lastKnownRemoteUpdatedAt,
1373
- lastSyncedContentHash: link.lastSyncedContentHash,
1374
- lastError: null,
1375
- warnings: parseWarnings(link),
1376
- hasConflict: true,
1377
- });
1364
+ if (!(await tryClaimSyncLink(documentId, owner))) return status;
1365
+ try {
1366
+ // The competing push may have finished after the status snapshot but
1367
+ // before this poll acquired the claim. Re-read the local/link state
1368
+ // under the claim so stale change flags cannot recreate the conflict
1369
+ // immediately after that push resolved it.
1378
1370
  const document = await getDocument(documentId, owner);
1379
- const updatedLink = await getSyncLink(documentId, owner);
1380
- return buildStatus({
1381
- connected: true,
1382
- documentId,
1383
- link: updatedLink,
1384
- remoteUpdatedAt: status.lastKnownRemoteUpdatedAt,
1385
- documentUpdatedAt: document.updatedAt,
1386
- documentContent: document.content,
1387
- });
1371
+ const link = await getSyncLink(documentId, owner);
1372
+ if (link) {
1373
+ const claimedStatus = buildStatus({
1374
+ connected: true,
1375
+ documentId,
1376
+ link,
1377
+ remoteUpdatedAt: status.lastKnownRemoteUpdatedAt,
1378
+ documentUpdatedAt: document.updatedAt,
1379
+ documentContent: document.content,
1380
+ });
1381
+ if (!claimedStatus.localChanged || !claimedStatus.remoteChanged) {
1382
+ return claimedStatus;
1383
+ }
1384
+ let conflictDocument = document;
1385
+
1386
+ // Notion timestamps are only a cheap candidate signal. Confirm the
1387
+ // remote content against the authoritative hash baseline before
1388
+ // persisting a conflict; our own completed push (or any metadata-only
1389
+ // timestamp bump) can otherwise look like a remote content edit.
1390
+ if (link.lastSyncedContentHash) {
1391
+ const connection = await getNotionConnectionForOwner(owner);
1392
+ if (!connection) return claimedStatus;
1393
+
1394
+ let remotePageContent: Awaited<
1395
+ ReturnType<typeof readNotionPageAsDocument>
1396
+ >;
1397
+ try {
1398
+ remotePageContent = await readNotionPageAsDocument(
1399
+ connection.accessToken,
1400
+ link.remotePageId,
1401
+ );
1402
+ } catch {
1403
+ // Fail closed: an unverified timestamp bump is not enough to
1404
+ // interrupt editing with a conflict warning.
1405
+ return claimedStatus;
1406
+ }
1407
+
1408
+ // Local saves do not take the Notion sync claim, so the editor can
1409
+ // keep writing while the remote content request is in flight.
1410
+ // Classify the conflict against the latest local row.
1411
+ const verifiedDocument = await getDocument(documentId, owner);
1412
+ conflictDocument = verifiedDocument;
1413
+ const baselineHash = link.lastSyncedContentHash;
1414
+ const localHash = hashContent(verifiedDocument.content);
1415
+ const remoteHash = hashContent(remotePageContent.content);
1416
+ const localHashChanged = localHash !== baselineHash;
1417
+ const remoteHashChanged = remoteHash !== baselineHash;
1418
+
1419
+ if (localHash === remoteHash) {
1420
+ await upsertSyncLink({
1421
+ owner,
1422
+ documentId,
1423
+ remotePageId: link.remotePageId,
1424
+ state: "linked",
1425
+ lastSyncedAt: nowIso(),
1426
+ lastPulledRemoteUpdatedAt: remotePageContent.lastEditedTime,
1427
+ lastPushedLocalUpdatedAt: verifiedDocument.updatedAt,
1428
+ lastKnownRemoteUpdatedAt: remotePageContent.lastEditedTime,
1429
+ lastSyncedContentHash: localHash,
1430
+ lastError: null,
1431
+ warnings: remotePageContent.warnings,
1432
+ hasConflict: false,
1433
+ });
1434
+ const convergedLink = await getSyncLink(documentId, owner);
1435
+ return buildStatus({
1436
+ connected: true,
1437
+ documentId,
1438
+ link: convergedLink,
1439
+ remoteUpdatedAt: remotePageContent.lastEditedTime,
1440
+ documentUpdatedAt: verifiedDocument.updatedAt,
1441
+ documentContent: verifiedDocument.content,
1442
+ });
1443
+ }
1444
+
1445
+ if (!localHashChanged || !remoteHashChanged) {
1446
+ if (options?.autoSync && localHashChanged) {
1447
+ return pushDocumentToNotion(owner, documentId, false, {
1448
+ skipClaim: true,
1449
+ });
1450
+ }
1451
+ if (options?.autoSync && remoteHashChanged) {
1452
+ return pullDocumentFromNotion(owner, documentId, false, {
1453
+ skipClaim: true,
1454
+ });
1455
+ }
1456
+ return {
1457
+ ...claimedStatus,
1458
+ localChanged: localHashChanged,
1459
+ remoteChanged: remoteHashChanged,
1460
+ };
1461
+ }
1462
+ }
1463
+
1464
+ await upsertSyncLink({
1465
+ owner,
1466
+ documentId,
1467
+ remotePageId: link.remotePageId,
1468
+ state: "conflict",
1469
+ lastSyncedAt: link.lastSyncedAt,
1470
+ lastPulledRemoteUpdatedAt: link.lastPulledRemoteUpdatedAt,
1471
+ lastPushedLocalUpdatedAt: link.lastPushedLocalUpdatedAt,
1472
+ lastKnownRemoteUpdatedAt: status.lastKnownRemoteUpdatedAt,
1473
+ lastSyncedContentHash: link.lastSyncedContentHash,
1474
+ lastError: null,
1475
+ warnings: parseWarnings(link),
1476
+ hasConflict: true,
1477
+ });
1478
+ const updatedLink = await getSyncLink(documentId, owner);
1479
+ return buildStatus({
1480
+ connected: true,
1481
+ documentId,
1482
+ link: updatedLink,
1483
+ remoteUpdatedAt: status.lastKnownRemoteUpdatedAt,
1484
+ documentUpdatedAt: conflictDocument.updatedAt,
1485
+ documentContent: conflictDocument.content,
1486
+ });
1487
+ }
1488
+ } finally {
1489
+ await releaseSyncLink(documentId, owner);
1388
1490
  }
1389
1491
  }
1390
1492
  }
@@ -1,11 +1,13 @@
1
1
  import { defineAction } from "@agent-native/core";
2
2
  import { assertAccess } from "@agent-native/core/sharing";
3
- import { eq } from "drizzle-orm";
4
3
  import { nanoid } from "nanoid";
5
4
  import { z } from "zod";
6
5
 
7
- import { getDb, schema } from "../server/db/index.js";
8
6
  import "../server/db/index.js"; // ensure registerShareableResource runs
7
+ import {
8
+ mutateDesignData,
9
+ type DesignDataRecord,
10
+ } from "../server/lib/design-data-mutation.js";
9
11
  import type {
10
12
  BreakpointDefinition,
11
13
  BreakpointSet,
@@ -22,41 +24,17 @@ import { widthToPrefix } from "../shared/responsive-classes.js";
22
24
  * `design_breakpoint_set` table keyed by (design_id, file_id) and migrate
23
25
  * this in-data storage to it.
24
26
  */
25
- function readBreakpointSet(designData: string | null): BreakpointSet {
26
- if (designData) {
27
- try {
28
- const parsed = JSON.parse(designData) as Record<string, unknown>;
29
- if (parsed.breakpointSet && typeof parsed.breakpointSet === "object") {
30
- return parsed.breakpointSet as BreakpointSet;
31
- }
32
- } catch {
33
- // ignore parse errors; fall through to default
34
- }
35
- }
36
- return { id: nanoid(), breakpoints: [] };
37
- }
38
-
39
- function writeBreakpointSet(
40
- designData: string | null,
41
- set: BreakpointSet,
42
- now: string,
43
- ): string {
44
- let prev: Record<string, unknown> = {};
45
- if (designData) {
46
- try {
47
- const parsed = JSON.parse(designData);
48
- if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
49
- prev = parsed;
50
- }
51
- } catch {
52
- // ignore
53
- }
27
+ function readBreakpointSet(
28
+ designData: DesignDataRecord,
29
+ fallbackId: string,
30
+ ): BreakpointSet {
31
+ if (
32
+ designData.breakpointSet &&
33
+ typeof designData.breakpointSet === "object"
34
+ ) {
35
+ return designData.breakpointSet as BreakpointSet;
54
36
  }
55
- return JSON.stringify({
56
- ...prev,
57
- breakpointSet: set,
58
- breakpointSetUpdatedAt: now,
59
- });
37
+ return { id: fallbackId, breakpoints: [] };
60
38
  }
61
39
 
62
40
  export default defineAction({
@@ -95,29 +73,9 @@ export default defineAction({
95
73
  run: async ({ designId, label, widthPx, id: providedId }) => {
96
74
  await assertAccess("design", designId, "editor");
97
75
 
98
- const db = getDb();
99
- const [design] = await db
100
- .select({ data: schema.designs.data })
101
- .from(schema.designs)
102
- .where(eq(schema.designs.id, designId))
103
- .limit(1);
104
-
105
- if (!design) throw new Error(`Design '${designId}' not found.`);
106
-
107
- const set = readBreakpointSet(design.data);
108
-
109
- // Ignore duplicate widths.
110
- if (set.breakpoints.some((bp) => bp.widthPx === widthPx)) {
111
- return {
112
- ignored: true,
113
- reason: `A breakpoint with width ${widthPx}px already exists.`,
114
- breakpointSet: set,
115
- };
116
- }
117
-
118
76
  const breakpointId = providedId ?? nanoid();
77
+ const breakpointSetId = nanoid();
119
78
  const prefix = widthToPrefix(widthPx);
120
-
121
79
  const newBreakpoint: BreakpointDefinition = {
122
80
  id: breakpointId,
123
81
  label,
@@ -125,21 +83,43 @@ export default defineAction({
125
83
  prefix,
126
84
  };
127
85
 
128
- // Insert sorted by widthPx ascending (Mobile → Tablet → Desktop).
129
- const breakpoints = [...set.breakpoints, newBreakpoint].sort(
130
- (a, b) => a.widthPx - b.widthPx,
86
+ const persisted = await mutateDesignData({
87
+ designId,
88
+ mutate: (current, { updatedAt }) => {
89
+ const set = readBreakpointSet(current, breakpointSetId);
90
+ if (set.breakpoints.some((bp) => bp.widthPx === widthPx)) {
91
+ return current;
92
+ }
93
+ // Insert sorted by widthPx ascending (Mobile → Tablet → Desktop).
94
+ const breakpoints = [...set.breakpoints, newBreakpoint].sort(
95
+ (a, b) => a.widthPx - b.widthPx,
96
+ );
97
+ return {
98
+ ...current,
99
+ breakpointSet: { ...set, breakpoints },
100
+ breakpointSetUpdatedAt: updatedAt,
101
+ };
102
+ },
103
+ isApplied: (current) =>
104
+ readBreakpointSet(current, breakpointSetId).breakpoints.some(
105
+ (breakpoint) => breakpoint.widthPx === widthPx,
106
+ ),
107
+ });
108
+ const updatedSet = readBreakpointSet(persisted.data, breakpointSetId);
109
+ const added = updatedSet.breakpoints.find(
110
+ (breakpoint) => breakpoint.id === breakpointId,
131
111
  );
132
- const updatedSet: BreakpointSet = { ...set, breakpoints };
133
112
 
134
- const now = new Date().toISOString();
135
- const updatedData = writeBreakpointSet(design.data, updatedSet, now);
136
- await db
137
- .update(schema.designs)
138
- .set({ data: updatedData, updatedAt: now })
139
- .where(eq(schema.designs.id, designId));
113
+ if (!added) {
114
+ return {
115
+ ignored: true,
116
+ reason: `A breakpoint with width ${widthPx}px already exists.`,
117
+ breakpointSet: updatedSet,
118
+ };
119
+ }
140
120
 
141
121
  return {
142
- added: newBreakpoint,
122
+ added,
143
123
  breakpointSet: updatedSet,
144
124
  };
145
125
  },