@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
@@ -0,0 +1,283 @@
1
+ import { hashString } from "./board-surface-html";
2
+ import { screenLocalRectToBoardGeometry } from "./coordinate-transforms";
3
+ import {
4
+ geometryContainsGeometry,
5
+ geometryContainsPoint,
6
+ } from "./frame-geometry";
7
+ import type {
8
+ FrameGeometry,
9
+ FrameGeometryById,
10
+ Point,
11
+ ScreenFile,
12
+ } from "./types";
13
+
14
+ export interface PrimitiveDropTarget {
15
+ nodeId: string;
16
+ screenId: string;
17
+ boardRect: FrameGeometry;
18
+ }
19
+
20
+ export interface ParsedScreenPrimitive {
21
+ nodeId: string;
22
+ screenId: string;
23
+ localLeft: number;
24
+ localTop: number;
25
+ localWidth: number;
26
+ localHeight: number;
27
+ isContainer: boolean;
28
+ }
29
+
30
+ export const primitiveParseCache = new Map<string, ParsedScreenPrimitive[]>();
31
+ const PRIMITIVE_PARSE_CACHE_MAX = 64;
32
+ const PRIMITIVE_IDENTITY_CACHE_MAX = 64;
33
+ const primitiveParseIdentityCache = new Map<
34
+ string,
35
+ { content: string; result: ParsedScreenPrimitive[] }
36
+ >();
37
+
38
+ function rememberPrimitiveIdentity(
39
+ screenId: string,
40
+ content: string,
41
+ result: ParsedScreenPrimitive[],
42
+ ) {
43
+ primitiveParseIdentityCache.delete(screenId);
44
+ if (primitiveParseIdentityCache.size >= PRIMITIVE_IDENTITY_CACHE_MAX) {
45
+ const oldestId = primitiveParseIdentityCache.keys().next().value;
46
+ if (oldestId !== undefined) primitiveParseIdentityCache.delete(oldestId);
47
+ }
48
+ primitiveParseIdentityCache.set(screenId, { content, result });
49
+ }
50
+
51
+ export function __clearPrimitiveParseCachesForTests() {
52
+ primitiveParseCache.clear();
53
+ primitiveParseIdentityCache.clear();
54
+ }
55
+
56
+ export function __getPrimitiveParseCacheSizesForTests() {
57
+ return {
58
+ parsed: primitiveParseCache.size,
59
+ identity: primitiveParseIdentityCache.size,
60
+ };
61
+ }
62
+
63
+ export function parsePrimitivesFromScreen(
64
+ screen: ScreenFile,
65
+ ): ParsedScreenPrimitive[] {
66
+ const identityEntry = primitiveParseIdentityCache.get(screen.id);
67
+ if (identityEntry && identityEntry.content === screen.content) {
68
+ return identityEntry.result;
69
+ }
70
+
71
+ const cacheKey = `${screen.id}:${screen.content.length}:${hashString(screen.content)}`;
72
+ const cached = primitiveParseCache.get(cacheKey);
73
+ if (cached) {
74
+ rememberPrimitiveIdentity(screen.id, screen.content, cached);
75
+ return cached;
76
+ }
77
+
78
+ const result: ParsedScreenPrimitive[] = [];
79
+ if (typeof DOMParser === "undefined" || !screen.content) {
80
+ return result;
81
+ }
82
+
83
+ try {
84
+ const doc = new DOMParser().parseFromString(screen.content, "text/html");
85
+ const nodes = doc.querySelectorAll("[data-agent-native-node-id]");
86
+ nodes.forEach((element) => {
87
+ const nodeId = element.getAttribute("data-agent-native-node-id");
88
+ if (!nodeId) return;
89
+
90
+ const htmlElement = element as HTMLElement;
91
+ const style = htmlElement.style;
92
+ const tag = element.tagName.toLowerCase();
93
+ const primitiveKind = (
94
+ element.getAttribute("data-an-primitive") || ""
95
+ ).toLowerCase();
96
+ if (style.position !== "absolute") return;
97
+
98
+ const left = parseFloat(style.left) || 0;
99
+ const top = parseFloat(style.top) || 0;
100
+ const width = parseFloat(style.width) || 0;
101
+ const height = parseFloat(style.height) || 0;
102
+ if (width <= 0 || height <= 0) return;
103
+
104
+ const isDiv = tag === "div";
105
+ const isEllipse =
106
+ style.borderRadius === "50%" ||
107
+ style.borderRadius === "50% 50% 50% 50%";
108
+ const isTextAutoSize = style.display === "inline-block";
109
+ const isAutoLayout =
110
+ style.display === "flex" ||
111
+ style.display === "inline-flex" ||
112
+ style.display === "grid" ||
113
+ style.display === "inline-grid";
114
+ const isCanvasRectangle =
115
+ isDiv && (primitiveKind === "rectangle" || primitiveKind === "rect");
116
+ const isContainer =
117
+ isDiv &&
118
+ !isEllipse &&
119
+ !isTextAutoSize &&
120
+ (isAutoLayout || isCanvasRectangle);
121
+
122
+ result.push({
123
+ nodeId,
124
+ screenId: screen.id,
125
+ localLeft: left,
126
+ localTop: top,
127
+ localWidth: width,
128
+ localHeight: height,
129
+ isContainer,
130
+ });
131
+ });
132
+ } catch {
133
+ // Malformed imported HTML simply has no discoverable canvas primitives.
134
+ }
135
+
136
+ if (primitiveParseCache.size >= PRIMITIVE_PARSE_CACHE_MAX) {
137
+ const firstKey = primitiveParseCache.keys().next().value;
138
+ if (firstKey !== undefined) primitiveParseCache.delete(firstKey);
139
+ }
140
+ primitiveParseCache.set(cacheKey, result);
141
+ rememberPrimitiveIdentity(screen.id, screen.content, result);
142
+ return result;
143
+ }
144
+
145
+ export function primitiveLocalToBoardRect(
146
+ localLeft: number,
147
+ localTop: number,
148
+ localWidth: number,
149
+ localHeight: number,
150
+ frameGeometry: FrameGeometry,
151
+ metadata: { width: number; height: number },
152
+ ): FrameGeometry {
153
+ return screenLocalRectToBoardGeometry(
154
+ {
155
+ left: localLeft,
156
+ top: localTop,
157
+ width: localWidth,
158
+ height: localHeight,
159
+ },
160
+ frameGeometry,
161
+ metadata,
162
+ );
163
+ }
164
+
165
+ export function getPrimitiveDropTargetForPoint(
166
+ point: Point,
167
+ draggedNodeId: string | null,
168
+ screens: ScreenFile[],
169
+ frameGeometryById: FrameGeometryById,
170
+ getMetadata: (screen: ScreenFile) => { width: number; height: number },
171
+ options: {
172
+ identityCoordinateScreenIds?: ReadonlySet<string>;
173
+ backgroundScreenIds?: ReadonlySet<string>;
174
+ foregroundScreenId?: string;
175
+ } = {},
176
+ ): PrimitiveDropTarget | null {
177
+ const toBoardRect = (
178
+ primitive: ParsedScreenPrimitive,
179
+ frameGeometry: FrameGeometry,
180
+ metadata: { width: number; height: number },
181
+ ): FrameGeometry => {
182
+ if (options.identityCoordinateScreenIds?.has(primitive.screenId)) {
183
+ return {
184
+ x: primitive.localLeft,
185
+ y: primitive.localTop,
186
+ width: Math.max(1, primitive.localWidth),
187
+ height: Math.max(1, primitive.localHeight),
188
+ };
189
+ }
190
+ return primitiveLocalToBoardRect(
191
+ primitive.localLeft,
192
+ primitive.localTop,
193
+ primitive.localWidth,
194
+ primitive.localHeight,
195
+ frameGeometry,
196
+ metadata,
197
+ );
198
+ };
199
+
200
+ let draggedBoardRect: FrameGeometry | null = null;
201
+ let draggedScreenId: string | null = null;
202
+ if (draggedNodeId) {
203
+ outer: for (const screen of screens) {
204
+ const frameGeometry = frameGeometryById[screen.id];
205
+ if (!frameGeometry) continue;
206
+ const metadata = getMetadata(screen);
207
+ const primitives = parsePrimitivesFromScreen(screen);
208
+ for (const primitive of primitives) {
209
+ if (primitive.nodeId === draggedNodeId) {
210
+ draggedBoardRect = toBoardRect(primitive, frameGeometry, metadata);
211
+ draggedScreenId = screen.id;
212
+ break outer;
213
+ }
214
+ }
215
+ }
216
+ }
217
+
218
+ const topScreen = screens
219
+ .map((screen, index) => ({
220
+ screen,
221
+ index,
222
+ geometry: frameGeometryById[screen.id],
223
+ }))
224
+ .filter(
225
+ (
226
+ entry,
227
+ ): entry is {
228
+ screen: ScreenFile;
229
+ index: number;
230
+ geometry: FrameGeometry;
231
+ } => !!entry.geometry && geometryContainsPoint(entry.geometry, point),
232
+ )
233
+ .sort((a, b) => {
234
+ const foregroundDelta =
235
+ Number(b.screen.id === options.foregroundScreenId) -
236
+ Number(a.screen.id === options.foregroundScreenId);
237
+ if (foregroundDelta) return foregroundDelta;
238
+ const backgroundDelta =
239
+ Number(options.backgroundScreenIds?.has(a.screen.id)) -
240
+ Number(options.backgroundScreenIds?.has(b.screen.id));
241
+ if (backgroundDelta) return backgroundDelta;
242
+ return (b.geometry.z ?? 0) - (a.geometry.z ?? 0) || b.index - a.index;
243
+ })[0];
244
+
245
+ if (!topScreen) return null;
246
+
247
+ const metadata = getMetadata(topScreen.screen);
248
+ const primitives = parsePrimitivesFromScreen(topScreen.screen);
249
+ let best: PrimitiveDropTarget | null = null;
250
+ for (const primitive of primitives) {
251
+ if (!primitive.isContainer) continue;
252
+ if (draggedNodeId && primitive.nodeId === draggedNodeId) continue;
253
+ const boardRect = toBoardRect(primitive, topScreen.geometry, metadata);
254
+ if (
255
+ draggedBoardRect &&
256
+ draggedScreenId === topScreen.screen.id &&
257
+ geometryContainsGeometry(draggedBoardRect, boardRect)
258
+ ) {
259
+ continue;
260
+ }
261
+ if (geometryContainsPoint(boardRect, point)) {
262
+ best = {
263
+ nodeId: primitive.nodeId,
264
+ screenId: topScreen.screen.id,
265
+ boardRect,
266
+ };
267
+ }
268
+ }
269
+ return best;
270
+ }
271
+
272
+ export function resolveNodeScreenId(
273
+ nodeId: string,
274
+ screens: ScreenFile[],
275
+ ): string | null {
276
+ for (const screen of screens) {
277
+ const primitives = parsePrimitivesFromScreen(screen);
278
+ if (primitives.some((primitive) => primitive.nodeId === nodeId)) {
279
+ return screen.id;
280
+ }
281
+ }
282
+ return null;
283
+ }
@@ -0,0 +1,272 @@
1
+ import type { ReactNode } from "react";
2
+
3
+ import { DEVICE_FRAME_VIEWPORTS, type DeviceFrameType } from "../types";
4
+ import type {
5
+ FrameGeometry,
6
+ MultiScreenCanvasProps,
7
+ ResolvedScreenMetadata,
8
+ ScreenContentCacheEntry,
9
+ ScreenFile,
10
+ ScreenMetadata,
11
+ ScreenPreviewState,
12
+ ScreenSourceType,
13
+ } from "./types";
14
+
15
+ export interface ResolvedMetadataCacheEntry {
16
+ screen: ScreenFile;
17
+ keyedMetadata?: ScreenMetadata;
18
+ getterMetadata?: ScreenMetadata;
19
+ previewDeviceFrame: DeviceFrameType;
20
+ result: ResolvedScreenMetadata;
21
+ }
22
+
23
+ export function sameResolvedMetadata(
24
+ a: ResolvedScreenMetadata,
25
+ b: ResolvedScreenMetadata,
26
+ ): boolean {
27
+ return (
28
+ a.source === b.source &&
29
+ a.previewState === b.previewState &&
30
+ a.title === b.title &&
31
+ a.width === b.width &&
32
+ a.height === b.height &&
33
+ a.previewUrl === b.previewUrl
34
+ );
35
+ }
36
+
37
+ function sameScreenMetadataInput(
38
+ a: ScreenMetadata | undefined,
39
+ b: ScreenMetadata | undefined,
40
+ ) {
41
+ if (a === b) return true;
42
+ if (!a || !b) return false;
43
+ return (
44
+ a.source === b.source &&
45
+ a.sourceType === b.sourceType &&
46
+ a.lod === b.lod &&
47
+ a.previewState === b.previewState &&
48
+ a.status === b.status &&
49
+ a.title === b.title &&
50
+ a.width === b.width &&
51
+ a.height === b.height &&
52
+ a.url === b.url &&
53
+ a.previewUrl === b.previewUrl &&
54
+ a.bridgeUrl === b.bridgeUrl &&
55
+ a.previewToken === b.previewToken
56
+ );
57
+ }
58
+
59
+ export function pruneResolvedMetadataCache(
60
+ cache: Map<string, ResolvedMetadataCacheEntry>,
61
+ liveScreenIds: ReadonlySet<string>,
62
+ ) {
63
+ for (const id of cache.keys()) {
64
+ if (!liveScreenIds.has(id)) cache.delete(id);
65
+ }
66
+ }
67
+
68
+ /** Keep cached React content nodes for screens that still exist, even while an
69
+ * overview iframe is LRU-evicted. The node is cheap compared with its mounted
70
+ * browsing context and lets a revisit reuse the already-built DesignCanvas
71
+ * element. Deleted screens are still pruned so create/delete churn cannot grow
72
+ * this cache without bound. */
73
+ export function pruneScreenContentCache(
74
+ cache: Map<string, ScreenContentCacheEntry>,
75
+ existingScreenIds: ReadonlySet<string>,
76
+ ) {
77
+ for (const id of cache.keys()) {
78
+ if (!existingScreenIds.has(id)) cache.delete(id);
79
+ }
80
+ }
81
+
82
+ export function __clearResolvedMetadataCacheForTests(
83
+ cache: Map<string, ResolvedMetadataCacheEntry>,
84
+ ) {
85
+ cache.clear();
86
+ }
87
+
88
+ export function resolveScreenMetadataCached(
89
+ cache: Map<string, ResolvedMetadataCacheEntry>,
90
+ screen: ScreenFile,
91
+ keyedMetadata: ScreenMetadata | undefined,
92
+ getterMetadata: ScreenMetadata | undefined,
93
+ previewDeviceFrame: DeviceFrameType,
94
+ ): ResolvedScreenMetadata {
95
+ const cached = cache.get(screen.id);
96
+ if (
97
+ cached &&
98
+ cached.screen === screen &&
99
+ cached.previewDeviceFrame === previewDeviceFrame &&
100
+ sameScreenMetadataInput(cached.keyedMetadata, keyedMetadata) &&
101
+ sameScreenMetadataInput(cached.getterMetadata, getterMetadata)
102
+ ) {
103
+ return cached.result;
104
+ }
105
+ const result = resolveScreenMetadata(
106
+ screen,
107
+ keyedMetadata,
108
+ getterMetadata,
109
+ previewDeviceFrame,
110
+ );
111
+ cache.set(screen.id, {
112
+ screen,
113
+ keyedMetadata,
114
+ getterMetadata,
115
+ previewDeviceFrame,
116
+ result,
117
+ });
118
+ return result;
119
+ }
120
+
121
+ export function getCachedScreenContentNode(
122
+ cache: Map<string, ScreenContentCacheEntry>, // i18n-ignore -- type signature, not visible copy
123
+ screen: ScreenFile,
124
+ metadata: ResolvedScreenMetadata,
125
+ geometry: FrameGeometry,
126
+ renderScreenContent: NonNullable<
127
+ MultiScreenCanvasProps["renderScreenContent"]
128
+ >,
129
+ ): ReactNode {
130
+ const width = Math.max(1, Math.round(geometry.width));
131
+ const height = Math.max(1, Math.round(geometry.height));
132
+ const prior = cache.get(screen.id);
133
+ if (
134
+ prior &&
135
+ prior.screen === screen &&
136
+ prior.renderScreenContent === renderScreenContent &&
137
+ sameResolvedMetadata(prior.metadata, metadata) &&
138
+ prior.width === width &&
139
+ prior.height === height
140
+ ) {
141
+ return prior.contentNode;
142
+ }
143
+ const contentNode = renderScreenContent(screen, metadata, geometry);
144
+ cache.set(screen.id, {
145
+ screen,
146
+ metadata,
147
+ width,
148
+ height,
149
+ renderScreenContent,
150
+ contentNode,
151
+ });
152
+ return contentNode;
153
+ }
154
+
155
+ export function resolveScreenMetadata(
156
+ screen: ScreenFile,
157
+ keyedMetadata?: ScreenMetadata,
158
+ getterMetadata?: ScreenMetadata,
159
+ previewDeviceFrame: DeviceFrameType = "none",
160
+ ): ResolvedScreenMetadata {
161
+ const safeScreen: ScreenFile =
162
+ typeof screen.content === "string" ? screen : { ...screen, content: "" };
163
+ const metadata = { ...safeScreen, ...keyedMetadata, ...getterMetadata };
164
+ const previewUrl =
165
+ metadata.url ??
166
+ metadata.previewUrl ??
167
+ safeScreen.previewUrl ??
168
+ getPreviewUrl(safeScreen.content);
169
+ const deviceViewport =
170
+ previewDeviceFrame === "none"
171
+ ? undefined
172
+ : DEVICE_FRAME_VIEWPORTS[previewDeviceFrame];
173
+ const width =
174
+ deviceViewport?.width ??
175
+ (metadata.width && metadata.width > 0 ? metadata.width : 1280);
176
+ const height =
177
+ deviceViewport?.height ??
178
+ (metadata.height && metadata.height > 0 ? metadata.height : 2560);
179
+ return {
180
+ source:
181
+ normalizeSource(metadata.sourceType ?? metadata.source) ??
182
+ deriveSource(safeScreen, previewUrl),
183
+ previewState:
184
+ normalizePreviewState(
185
+ metadata.lod ?? metadata.previewState ?? metadata.status,
186
+ ) ?? derivePreviewState(safeScreen, previewUrl),
187
+ title: metadata.title,
188
+ width,
189
+ height,
190
+ previewUrl,
191
+ };
192
+ }
193
+
194
+ function normalizeSource(value?: string): ScreenSourceType | undefined {
195
+ const normalized = value?.toLowerCase();
196
+ if (!normalized) return undefined;
197
+ if (normalized === "local" || normalized === "localhost") return "localhost";
198
+ if (normalized === "fusion" || normalized === "remote-fusion") {
199
+ return "fusion";
200
+ }
201
+ if (normalized === "inline" || normalized === "code") return "inline";
202
+ return undefined;
203
+ }
204
+
205
+ function normalizePreviewState(value?: string): ScreenPreviewState | undefined {
206
+ const normalized = value?.toLowerCase();
207
+ if (!normalized) return undefined;
208
+ if (normalized === "live") return "live";
209
+ if (normalized === "snapshot" || normalized === "cached") return "snapshot";
210
+ if (normalized === "preview" || normalized === "draft") return "preview";
211
+ return undefined;
212
+ }
213
+
214
+ function deriveSource(
215
+ screen: ScreenFile,
216
+ previewUrl?: string,
217
+ ): ScreenSourceType {
218
+ const haystack =
219
+ `${screen.filename} ${screen.content.slice(0, 4000)}`.toLowerCase();
220
+ const url = getUrl(previewUrl ?? screen.content);
221
+ if (
222
+ url?.hostname === "localhost" ||
223
+ url?.hostname === "127.0.0.1" ||
224
+ url?.hostname.endsWith(".local") ||
225
+ haystack.includes("localhost") ||
226
+ haystack.includes("127.0.0.1")
227
+ ) {
228
+ return "localhost";
229
+ }
230
+ if (haystack.includes("fusion") || url?.hostname.includes("fusion")) {
231
+ return "fusion";
232
+ }
233
+ return "inline";
234
+ }
235
+
236
+ function derivePreviewState(
237
+ screen: ScreenFile,
238
+ previewUrl?: string,
239
+ ): ScreenPreviewState {
240
+ const haystack =
241
+ `${screen.filename} ${screen.content.slice(0, 4000)}`.toLowerCase();
242
+ if (
243
+ haystack.includes("snapshot") ||
244
+ haystack.includes("screenshot") ||
245
+ haystack.includes("cached") ||
246
+ haystack.includes("data:image/")
247
+ ) {
248
+ return "snapshot";
249
+ }
250
+ if (previewUrl || deriveSource(screen, previewUrl) !== "inline") {
251
+ return "live";
252
+ }
253
+ return "preview";
254
+ }
255
+
256
+ export function getPreviewUrl(content: string) {
257
+ return getUrl(
258
+ typeof content === "string" ? content.trim() : undefined,
259
+ )?.toString();
260
+ }
261
+
262
+ function getUrl(value: string | undefined) {
263
+ if (!value) return undefined;
264
+ try {
265
+ const url = new URL(value);
266
+ return url.protocol === "http:" || url.protocol === "https:"
267
+ ? url
268
+ : undefined;
269
+ } catch {
270
+ return undefined;
271
+ }
272
+ }
@@ -10,7 +10,7 @@ import type {
10
10
  IframeContextMenuPayload,
11
11
  IframeFigmaClipboardPastePayload,
12
12
  IframeHotkeyPayload,
13
- } from "../DesignCanvas";
13
+ } from "../design-canvas/iframe-events";
14
14
  import type {
15
15
  DeviceFrameType,
16
16
  ElementInfo,
@@ -34,6 +34,8 @@ export interface ScreenFile {
34
34
  url?: string;
35
35
  previewUrl?: string;
36
36
  bridgeUrl?: string;
37
+ /** Read-only localhost preview credential. Never a filesystem token. */
38
+ previewToken?: string;
37
39
  /**
38
40
  * When set, renders multiple side-by-side breakpoint frames (mobile-first,
39
41
  * §6.4). Each entry is a pixel width; the active breakpoint determines the
@@ -93,12 +95,14 @@ export interface ScreenMetadata {
93
95
  sourceType?: string;
94
96
  lod?: string;
95
97
  previewState?: string;
98
+ status?: string;
96
99
  title?: string;
97
100
  width?: number;
98
101
  height?: number;
99
102
  url?: string;
100
103
  previewUrl?: string;
101
104
  bridgeUrl?: string;
105
+ previewToken?: string;
102
106
  }
103
107
 
104
108
  export interface DuplicateRequest {
@@ -0,0 +1,12 @@
1
+ // The editor renders one overview canvas at a time. Keeping the in-flight
2
+ // gesture flag outside React lets hover handlers read it without causing a
3
+ // render in the first wheel frame.
4
+ let wheelCameraGestureActive = false;
5
+
6
+ export function isWheelCameraGestureActive(): boolean {
7
+ return wheelCameraGestureActive;
8
+ }
9
+
10
+ export function setWheelCameraGestureActive(active: boolean): void {
11
+ wheelCameraGestureActive = active;
12
+ }