@agent-native/core 0.149.2 → 0.149.4

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 (347) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/templates/analytics/.agents/skills/actions/SKILL.md +54 -488
  3. package/corpus/templates/analytics/.agents/skills/actions/references/action-fields.md +136 -0
  4. package/corpus/templates/analytics/.agents/skills/actions/references/examples.md +94 -0
  5. package/corpus/templates/analytics/.agents/skills/actions/references/provider-apis.md +95 -0
  6. package/corpus/templates/analytics/.agents/skills/create-skill/SKILL.md +9 -35
  7. package/corpus/templates/analytics/.agents/skills/creative-context/SKILL.md +4 -2
  8. package/corpus/templates/analytics/.agents/skills/frontend-design/SKILL.md +4 -5
  9. package/corpus/templates/analytics/.agents/skills/turn-into-app/SKILL.md +18 -31
  10. package/corpus/templates/analytics/AGENTS.md +25 -32
  11. package/corpus/templates/analytics/app/global.css +1 -1
  12. package/corpus/templates/analytics/changelog/2026-08-11-full-page-chat-composers-stay-at-a-focused-750px-width.md +6 -0
  13. package/corpus/templates/assets/.agents/skills/actions/SKILL.md +54 -488
  14. package/corpus/templates/assets/.agents/skills/actions/references/action-fields.md +136 -0
  15. package/corpus/templates/assets/.agents/skills/actions/references/examples.md +94 -0
  16. package/corpus/templates/assets/.agents/skills/actions/references/provider-apis.md +95 -0
  17. package/corpus/templates/assets/.agents/skills/create-skill/SKILL.md +9 -35
  18. package/corpus/templates/assets/.agents/skills/creative-context/SKILL.md +4 -2
  19. package/corpus/templates/assets/.agents/skills/frontend-design/SKILL.md +4 -5
  20. package/corpus/templates/assets/.agents/skills/turn-into-app/SKILL.md +18 -31
  21. package/corpus/templates/assets/AGENTS.md +6 -9
  22. package/corpus/templates/assets/app/global.css +1 -1
  23. package/corpus/templates/assets/changelog/2026-08-11-full-page-chat-composers-stay-at-a-focused-750px-width.md +6 -0
  24. package/corpus/templates/brain/.agents/skills/actions/SKILL.md +54 -488
  25. package/corpus/templates/brain/.agents/skills/actions/references/action-fields.md +136 -0
  26. package/corpus/templates/brain/.agents/skills/actions/references/examples.md +94 -0
  27. package/corpus/templates/brain/.agents/skills/actions/references/provider-apis.md +95 -0
  28. package/corpus/templates/brain/.agents/skills/create-skill/SKILL.md +9 -35
  29. package/corpus/templates/brain/.agents/skills/frontend-design/SKILL.md +4 -5
  30. package/corpus/templates/brain/.agents/skills/turn-into-app/SKILL.md +18 -31
  31. package/corpus/templates/brain/AGENTS.md +5 -12
  32. package/corpus/templates/brain/app/global.css +1 -1
  33. package/corpus/templates/brain/changelog/2026-08-11-full-page-chat-composers-stay-at-a-focused-750px-width.md +6 -0
  34. package/corpus/templates/calendar/.agents/skills/actions/SKILL.md +54 -488
  35. package/corpus/templates/calendar/.agents/skills/actions/references/action-fields.md +136 -0
  36. package/corpus/templates/calendar/.agents/skills/actions/references/examples.md +94 -0
  37. package/corpus/templates/calendar/.agents/skills/actions/references/provider-apis.md +95 -0
  38. package/corpus/templates/calendar/.agents/skills/create-skill/SKILL.md +9 -35
  39. package/corpus/templates/calendar/.agents/skills/frontend-design/SKILL.md +4 -5
  40. package/corpus/templates/calendar/.agents/skills/turn-into-app/SKILL.md +18 -31
  41. package/corpus/templates/calendar/AGENTS.md +8 -9
  42. package/corpus/templates/chat/.agents/skills/actions/SKILL.md +54 -488
  43. package/corpus/templates/chat/.agents/skills/actions/references/action-fields.md +136 -0
  44. package/corpus/templates/chat/.agents/skills/actions/references/examples.md +94 -0
  45. package/corpus/templates/chat/.agents/skills/actions/references/provider-apis.md +95 -0
  46. package/corpus/templates/chat/.agents/skills/create-skill/SKILL.md +9 -35
  47. package/corpus/templates/chat/.agents/skills/frontend-design/SKILL.md +4 -5
  48. package/corpus/templates/chat/.agents/skills/turn-into-app/SKILL.md +18 -31
  49. package/corpus/templates/chat/AGENTS.md +32 -80
  50. package/corpus/templates/clips/.agents/skills/actions/SKILL.md +54 -488
  51. package/corpus/templates/clips/.agents/skills/actions/references/action-fields.md +136 -0
  52. package/corpus/templates/clips/.agents/skills/actions/references/examples.md +94 -0
  53. package/corpus/templates/clips/.agents/skills/actions/references/provider-apis.md +95 -0
  54. package/corpus/templates/clips/.agents/skills/create-skill/SKILL.md +9 -35
  55. package/corpus/templates/clips/.agents/skills/frontend-design/SKILL.md +4 -5
  56. package/corpus/templates/clips/.agents/skills/turn-into-app/SKILL.md +18 -31
  57. package/corpus/templates/clips/AGENTS.md +25 -31
  58. package/corpus/templates/content/.agents/skills/actions/SKILL.md +54 -488
  59. package/corpus/templates/content/.agents/skills/actions/references/action-fields.md +136 -0
  60. package/corpus/templates/content/.agents/skills/actions/references/examples.md +94 -0
  61. package/corpus/templates/content/.agents/skills/actions/references/provider-apis.md +95 -0
  62. package/corpus/templates/content/.agents/skills/create-skill/SKILL.md +9 -35
  63. package/corpus/templates/content/.agents/skills/creative-context/SKILL.md +4 -2
  64. package/corpus/templates/content/.agents/skills/frontend-design/SKILL.md +4 -5
  65. package/corpus/templates/content/.agents/skills/turn-into-app/SKILL.md +18 -31
  66. package/corpus/templates/content/AGENTS.md +5 -9
  67. package/corpus/templates/crm/.agents/skills/turn-into-app/SKILL.md +18 -31
  68. package/corpus/templates/crm/AGENTS.md +7 -11
  69. package/corpus/templates/crm/app/global.css +1 -1
  70. package/corpus/templates/crm/changelog/2026-08-11-full-page-chat-composers-stay-at-a-focused-750px-width.md +6 -0
  71. package/corpus/templates/design/.agents/skills/actions/SKILL.md +54 -488
  72. package/corpus/templates/design/.agents/skills/actions/references/action-fields.md +136 -0
  73. package/corpus/templates/design/.agents/skills/actions/references/examples.md +94 -0
  74. package/corpus/templates/design/.agents/skills/actions/references/provider-apis.md +95 -0
  75. package/corpus/templates/design/.agents/skills/create-skill/SKILL.md +9 -35
  76. package/corpus/templates/design/.agents/skills/creative-context/SKILL.md +4 -2
  77. package/corpus/templates/design/.agents/skills/frontend-design/SKILL.md +4 -5
  78. package/corpus/templates/design/.agents/skills/turn-into-app/SKILL.md +18 -31
  79. package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +70 -3
  80. package/corpus/templates/design/AGENTS.md +13 -21
  81. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +12 -0
  82. package/corpus/templates/design/app/components/design/LayersPanel.tsx +19 -2
  83. package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +115 -7
  84. package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +82 -7
  85. package/corpus/templates/design/app/components/design/design-trace.ts +120 -0
  86. package/corpus/templates/design/app/components/design/dnd-debug.ts +2 -1
  87. package/corpus/templates/design/app/components/design/edit-panel/position-layout-properties.tsx +40 -26
  88. package/corpus/templates/design/app/components/design/multi-screen/board-surface-html.ts +4 -1
  89. package/corpus/templates/design/app/components/design/multi-screen/frame-geometry.ts +12 -3
  90. package/corpus/templates/design/app/components/design/multi-screen/screen-content-cache.ts +4 -0
  91. package/corpus/templates/design/app/components/design/multi-screen/types.ts +7 -0
  92. package/corpus/templates/design/app/components/editor/PromptDialog.tsx +3 -2
  93. package/corpus/templates/design/app/components/layout/Sidebar.tsx +2 -2
  94. package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +3 -0
  95. package/corpus/templates/design/app/i18n-data.ts +1 -0
  96. package/corpus/templates/design/app/pages/DesignSystemSetup.tsx +5 -5
  97. package/corpus/templates/design/app/pages/DesignSystems.tsx +3 -2
  98. package/corpus/templates/design/app/pages/design-editor/canvas-primitive-insert.ts +100 -13
  99. package/corpus/templates/design/app/pages/design-editor/cross-screen-text-color.ts +1 -1
  100. package/corpus/templates/design/app/pages/design-editor/data-operations.ts +14 -0
  101. package/corpus/templates/design/changelog/2026-08-10-marquee-selecting-layers-far-down-a-tall-screen-now-selects-.md +6 -0
  102. package/corpus/templates/design/changelog/2026-08-10-the-frame-tool-draws-a-plain-frame-by-default-with-screen-av.md +6 -0
  103. package/corpus/templates/design/e2e/global-setup.ts +27 -32
  104. package/corpus/templates/design/playwright.config.ts +3 -5
  105. package/corpus/templates/design/shared/breakpoint-media.ts +9 -2
  106. package/corpus/templates/dispatch/.agents/skills/actions/SKILL.md +54 -488
  107. package/corpus/templates/dispatch/.agents/skills/actions/references/action-fields.md +136 -0
  108. package/corpus/templates/dispatch/.agents/skills/actions/references/examples.md +94 -0
  109. package/corpus/templates/dispatch/.agents/skills/actions/references/provider-apis.md +95 -0
  110. package/corpus/templates/dispatch/.agents/skills/create-skill/SKILL.md +9 -35
  111. package/corpus/templates/dispatch/.agents/skills/frontend-design/SKILL.md +4 -5
  112. package/corpus/templates/dispatch/.agents/skills/turn-into-app/SKILL.md +18 -31
  113. package/corpus/templates/dispatch/AGENTS.md +9 -16
  114. package/corpus/templates/factory/.agents/skills/actions/SKILL.md +54 -488
  115. package/corpus/templates/factory/.agents/skills/actions/references/action-fields.md +136 -0
  116. package/corpus/templates/factory/.agents/skills/actions/references/examples.md +94 -0
  117. package/corpus/templates/factory/.agents/skills/actions/references/provider-apis.md +95 -0
  118. package/corpus/templates/factory/.agents/skills/create-skill/SKILL.md +9 -35
  119. package/corpus/templates/factory/.agents/skills/frontend-design/SKILL.md +4 -5
  120. package/corpus/templates/factory/.agents/skills/turn-into-app/SKILL.md +18 -31
  121. package/corpus/templates/factory/AGENTS.md +10 -24
  122. package/corpus/templates/forms/.agents/skills/actions/SKILL.md +54 -488
  123. package/corpus/templates/forms/.agents/skills/actions/references/action-fields.md +136 -0
  124. package/corpus/templates/forms/.agents/skills/actions/references/examples.md +94 -0
  125. package/corpus/templates/forms/.agents/skills/actions/references/provider-apis.md +95 -0
  126. package/corpus/templates/forms/.agents/skills/create-skill/SKILL.md +9 -35
  127. package/corpus/templates/forms/.agents/skills/frontend-design/SKILL.md +4 -5
  128. package/corpus/templates/forms/.agents/skills/turn-into-app/SKILL.md +18 -31
  129. package/corpus/templates/forms/AGENTS.md +11 -17
  130. package/corpus/templates/forms/app/global.css +1 -0
  131. package/corpus/templates/forms/changelog/2026-08-11-full-page-chat-composers-stay-at-a-focused-750px-width.md +6 -0
  132. package/corpus/templates/macros/.agents/skills/frontend-design/SKILL.md +4 -5
  133. package/corpus/templates/macros/.agents/skills/turn-into-app/SKILL.md +18 -31
  134. package/corpus/templates/macros/AGENTS.md +8 -8
  135. package/corpus/templates/mail/.agents/skills/actions/SKILL.md +54 -488
  136. package/corpus/templates/mail/.agents/skills/actions/references/action-fields.md +136 -0
  137. package/corpus/templates/mail/.agents/skills/actions/references/examples.md +94 -0
  138. package/corpus/templates/mail/.agents/skills/actions/references/provider-apis.md +95 -0
  139. package/corpus/templates/mail/.agents/skills/create-skill/SKILL.md +9 -35
  140. package/corpus/templates/mail/.agents/skills/frontend-design/SKILL.md +4 -5
  141. package/corpus/templates/mail/.agents/skills/turn-into-app/SKILL.md +18 -31
  142. package/corpus/templates/mail/AGENTS.md +5 -6
  143. package/corpus/templates/plan/.agents/skills/actions/SKILL.md +54 -488
  144. package/corpus/templates/plan/.agents/skills/actions/references/action-fields.md +136 -0
  145. package/corpus/templates/plan/.agents/skills/actions/references/examples.md +94 -0
  146. package/corpus/templates/plan/.agents/skills/actions/references/provider-apis.md +95 -0
  147. package/corpus/templates/plan/.agents/skills/create-skill/SKILL.md +9 -35
  148. package/corpus/templates/plan/.agents/skills/frontend-design/SKILL.md +4 -5
  149. package/corpus/templates/plan/.agents/skills/turn-into-app/SKILL.md +18 -31
  150. package/corpus/templates/plan/AGENTS.md +5 -14
  151. package/corpus/templates/plan/changelog/2026-08-11-plan-no-longer-reloads-when-runtime-state-changes.md +6 -0
  152. package/corpus/templates/plan/vite.config.ts +5 -0
  153. package/corpus/templates/slides/.agents/skills/actions/SKILL.md +54 -488
  154. package/corpus/templates/slides/.agents/skills/actions/references/action-fields.md +136 -0
  155. package/corpus/templates/slides/.agents/skills/actions/references/examples.md +94 -0
  156. package/corpus/templates/slides/.agents/skills/actions/references/provider-apis.md +95 -0
  157. package/corpus/templates/slides/.agents/skills/create-deck/SKILL.md +2 -2
  158. package/corpus/templates/slides/.agents/skills/create-skill/SKILL.md +9 -35
  159. package/corpus/templates/slides/.agents/skills/creative-context/SKILL.md +6 -3
  160. package/corpus/templates/slides/.agents/skills/deck-management/SKILL.md +6 -1
  161. package/corpus/templates/slides/.agents/skills/frontend-design/SKILL.md +4 -5
  162. package/corpus/templates/slides/.agents/skills/image-generation-via-a2a/SKILL.md +3 -2
  163. package/corpus/templates/slides/.agents/skills/slide-editing/SKILL.md +3 -0
  164. package/corpus/templates/slides/.agents/skills/slide-images/SKILL.md +3 -3
  165. package/corpus/templates/slides/.agents/skills/turn-into-app/SKILL.md +18 -31
  166. package/corpus/templates/slides/AGENTS.md +22 -25
  167. package/corpus/templates/slides/actions/get-deck-reference-context.ts +2 -2
  168. package/corpus/templates/slides/actions/get-deck.ts +57 -9
  169. package/corpus/templates/slides/actions/import-file.ts +2 -1
  170. package/corpus/templates/slides/actions/patch-deck.ts +45 -2
  171. package/corpus/templates/slides/actions/update-slide.ts +1 -1
  172. package/corpus/templates/slides/app/components/comments/SlideCommentsPanel.tsx +2 -2
  173. package/corpus/templates/slides/app/components/deck/DeckCard.tsx +1 -23
  174. package/corpus/templates/slides/app/components/design-system/DesignSystemCard.tsx +2 -2
  175. package/corpus/templates/slides/app/components/design-system/DesignSystemSetup.tsx +6 -6
  176. package/corpus/templates/slides/app/components/editor/AnimationsPanel.tsx +3 -3
  177. package/corpus/templates/slides/app/components/editor/DeckEditorSkeleton.tsx +4 -4
  178. package/corpus/templates/slides/app/components/editor/EditorSidebar.tsx +1 -1
  179. package/corpus/templates/slides/app/components/editor/EditorToolbar.tsx +428 -180
  180. package/corpus/templates/slides/app/components/editor/ExportMenu.tsx +294 -266
  181. package/corpus/templates/slides/app/components/editor/PromptDialog.tsx +7 -5
  182. package/corpus/templates/slides/app/components/editor/SlideContextToolbar.tsx +1 -1
  183. package/corpus/templates/slides/app/components/editor/SlideEditor.tsx +40 -12
  184. package/corpus/templates/slides/app/components/editor/SpeakerNotesPanel.tsx +6 -12
  185. package/corpus/templates/slides/app/components/editor/editor-command-model.ts +35 -0
  186. package/corpus/templates/slides/app/components/layout/Sidebar.tsx +8 -10
  187. package/corpus/templates/slides/app/context/DeckContext.tsx +2 -1
  188. package/corpus/templates/slides/app/global.css +76 -1
  189. package/corpus/templates/slides/app/i18n/en-US.ts +1 -0
  190. package/corpus/templates/slides/app/lib/create-deck-generation.ts +51 -23
  191. package/corpus/templates/slides/app/lib/slide-animation-elements.ts +68 -5
  192. package/corpus/templates/slides/app/pages/DeckEditor.tsx +13 -6
  193. package/corpus/templates/slides/app/pages/DesignSystems.tsx +2 -2
  194. package/corpus/templates/slides/app/pages/Index.tsx +87 -74
  195. package/corpus/templates/slides/app/root.tsx +43 -0
  196. package/corpus/templates/slides/changelog/2026-08-11-faster-slides-chat-deck-reads.md +6 -0
  197. package/corpus/templates/slides/changelog/2026-08-11-slides-chat-can-read-one-slide-without-loading-the-full-deck.md +6 -0
  198. package/corpus/templates/slides/changelog/2026-08-11-slides-clearly-indicate-when-an-ai-agent-is-editing-alongsid.md +6 -0
  199. package/corpus/templates/slides/package.json +1 -0
  200. package/corpus/templates/slides/server/lib/validate-slide-animations.ts +163 -0
  201. package/corpus/templates/slides/server/plugins/agent-chat.ts +4 -3
  202. package/corpus/templates/slides/shared/api.ts +46 -15
  203. package/corpus/templates/tasks/.agents/skills/actions/SKILL.md +54 -488
  204. package/corpus/templates/tasks/.agents/skills/actions/references/action-fields.md +136 -0
  205. package/corpus/templates/tasks/.agents/skills/actions/references/examples.md +94 -0
  206. package/corpus/templates/tasks/.agents/skills/actions/references/provider-apis.md +95 -0
  207. package/corpus/templates/tasks/.agents/skills/agent-watchdog/SKILL.md +1 -0
  208. package/corpus/templates/tasks/.agents/skills/create-skill/SKILL.md +9 -35
  209. package/corpus/templates/tasks/.agents/skills/efficient-fable/SKILL.md +1 -0
  210. package/corpus/templates/tasks/.agents/skills/efficient-frontier/SKILL.md +1 -0
  211. package/corpus/templates/tasks/.agents/skills/frontend-design/SKILL.md +4 -5
  212. package/corpus/templates/tasks/.agents/skills/plan-arbiter/SKILL.md +1 -0
  213. package/corpus/templates/tasks/.agents/skills/plow-ahead/SKILL.md +1 -0
  214. package/corpus/templates/tasks/.agents/skills/quick-recap/SKILL.md +1 -0
  215. package/corpus/templates/tasks/.agents/skills/read-the-damn-docs/SKILL.md +1 -0
  216. package/corpus/templates/tasks/.agents/skills/stay-within-limits/SKILL.md +1 -0
  217. package/corpus/templates/tasks/.agents/skills/turn-into-app/SKILL.md +18 -31
  218. package/corpus/templates/tasks/AGENTS.md +5 -20
  219. package/dist/agent/production-agent.js +376 -345
  220. package/dist/agent/run-manager.js +156 -14
  221. package/dist/agent/run-store.d.ts +11 -10
  222. package/dist/agent/run-store.js +17 -13
  223. package/dist/client/AssistantChat.d.ts +6 -2
  224. package/dist/client/AssistantChat.js +216 -131
  225. package/dist/client/active-run-state.d.ts +9 -1
  226. package/dist/client/active-run-state.js +34 -3
  227. package/dist/client/agent-chat-adapter.d.ts +8 -0
  228. package/dist/client/agent-chat-adapter.js +114 -28
  229. package/dist/client/chat/message-components.d.ts +7 -1
  230. package/dist/client/chat/message-components.js +32 -5
  231. package/dist/client/chat/run-recovery.d.ts +1 -0
  232. package/dist/client/chat/run-recovery.js +8 -0
  233. package/dist/client/chat/tool-call-display.d.ts +2 -0
  234. package/dist/client/chat/tool-call-display.js +2 -0
  235. package/dist/client/chat-first/apps-rail.js +1 -1
  236. package/dist/client/chat-first/chat-history.d.ts +1 -1
  237. package/dist/client/chat-first/chat-history.js +5 -2
  238. package/dist/client/sse-event-processor.d.ts +4 -2
  239. package/dist/client/sse-event-processor.js +36 -6
  240. package/dist/client/use-run-stuck-detection.d.ts +2 -0
  241. package/dist/client/use-run-stuck-detection.js +85 -9
  242. package/dist/collab/routes.d.ts +1 -1
  243. package/dist/deploy/build.d.ts +4 -0
  244. package/dist/deploy/build.js +5 -0
  245. package/dist/deploy/workspace-deploy.js +5 -0
  246. package/dist/integrations/adapters/slack.d.ts +0 -4
  247. package/dist/integrations/adapters/slack.js +6 -30
  248. package/dist/integrations/catalog.js +1 -1
  249. package/dist/integrations/pending-tasks-store.d.ts +0 -8
  250. package/dist/integrations/pending-tasks-store.js +0 -21
  251. package/dist/integrations/slack-manifest.d.ts +2 -2
  252. package/dist/integrations/slack-manifest.js +0 -3
  253. package/dist/notifications/routes.d.ts +3 -3
  254. package/dist/observability/routes.d.ts +3 -3
  255. package/dist/provider-api/actions/custom-provider-registration.d.ts +4 -4
  256. package/dist/provider-api/actions/provider-api.d.ts +8 -8
  257. package/dist/resources/handlers.d.ts +1 -1
  258. package/dist/scripts/docs/source-search.js +2 -2
  259. package/dist/secrets/routes.d.ts +9 -9
  260. package/dist/server/agent-chat/framework-prompts.js +7 -2
  261. package/dist/server/agent-chat/prompt-resources.js +2 -2
  262. package/dist/server/agent-chat/skill-frontmatter.d.ts +31 -2
  263. package/dist/server/agent-chat/skill-frontmatter.js +41 -15
  264. package/dist/server/agent-chat-plugin.js +3 -3
  265. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  266. package/dist/server/agents-bundle.d.ts +16 -19
  267. package/dist/server/agents-bundle.js +19 -35
  268. package/dist/server/better-auth-instance.d.ts +1 -0
  269. package/dist/server/better-auth-instance.js +17 -2
  270. package/dist/server/prompts/framework-core-compact.d.ts +6 -1
  271. package/dist/server/prompts/framework-core-compact.js +12 -9
  272. package/dist/server/prompts/framework-core.d.ts +6 -1
  273. package/dist/server/prompts/framework-core.js +11 -9
  274. package/dist/server/prompts/index.d.ts +1 -1
  275. package/dist/server/prompts/index.js +1 -1
  276. package/dist/server/prompts/shared-rules.d.ts +15 -11
  277. package/dist/server/prompts/shared-rules.js +17 -13
  278. package/dist/server/realtime-token.d.ts +1 -1
  279. package/dist/server/transcribe-voice.d.ts +1 -1
  280. package/dist/templates/chat/.agents/skills/actions/SKILL.md +54 -488
  281. package/dist/templates/chat/.agents/skills/actions/references/action-fields.md +136 -0
  282. package/dist/templates/chat/.agents/skills/actions/references/examples.md +94 -0
  283. package/dist/templates/chat/.agents/skills/actions/references/provider-apis.md +95 -0
  284. package/dist/templates/chat/.agents/skills/create-skill/SKILL.md +9 -35
  285. package/dist/templates/chat/.agents/skills/frontend-design/SKILL.md +4 -5
  286. package/dist/templates/chat/.agents/skills/turn-into-app/SKILL.md +18 -31
  287. package/dist/templates/chat/AGENTS.md +32 -80
  288. package/dist/templates/default/.agents/skills/actions/SKILL.md +54 -488
  289. package/dist/templates/default/.agents/skills/actions/references/action-fields.md +136 -0
  290. package/dist/templates/default/.agents/skills/actions/references/examples.md +94 -0
  291. package/dist/templates/default/.agents/skills/actions/references/provider-apis.md +95 -0
  292. package/dist/templates/default/.agents/skills/create-skill/SKILL.md +9 -35
  293. package/dist/templates/default/.agents/skills/frontend-design/SKILL.md +4 -5
  294. package/dist/templates/default/.agents/skills/turn-into-app/SKILL.md +18 -31
  295. package/dist/templates/headless/.agents/skills/actions/SKILL.md +54 -488
  296. package/dist/templates/headless/.agents/skills/actions/references/action-fields.md +136 -0
  297. package/dist/templates/headless/.agents/skills/actions/references/examples.md +94 -0
  298. package/dist/templates/headless/.agents/skills/actions/references/provider-apis.md +95 -0
  299. package/dist/templates/headless/.agents/skills/turn-into-app/SKILL.md +18 -31
  300. package/dist/templates/workspace-core/.agents/skills/actions/SKILL.md +54 -488
  301. package/dist/templates/workspace-core/.agents/skills/actions/references/action-fields.md +136 -0
  302. package/dist/templates/workspace-core/.agents/skills/actions/references/examples.md +94 -0
  303. package/dist/templates/workspace-core/.agents/skills/actions/references/provider-apis.md +95 -0
  304. package/dist/templates/workspace-core/.agents/skills/adding-workspace-apps/SKILL.md +1 -0
  305. package/dist/templates/workspace-core/.agents/skills/agent-page/SKILL.md +1 -0
  306. package/dist/templates/workspace-core/.agents/skills/create-skill/SKILL.md +9 -35
  307. package/dist/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +4 -5
  308. package/dist/templates/workspace-core/.agents/skills/recurring-jobs/SKILL.md +21 -29
  309. package/dist/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +18 -31
  310. package/dist/templates/workspace-core/.agents/skills/workspace-conventions/SKILL.md +7 -17
  311. package/dist/templates/workspace-core/.agents/skills/writing-agent-instructions/SKILL.md +3 -3
  312. package/dist/templates/workspace-core/AGENTS.md +7 -16
  313. package/docs/content/messaging.mdx +6 -7
  314. package/package.json +1 -1
  315. package/src/templates/chat/.agents/skills/actions/SKILL.md +54 -488
  316. package/src/templates/chat/.agents/skills/actions/references/action-fields.md +136 -0
  317. package/src/templates/chat/.agents/skills/actions/references/examples.md +94 -0
  318. package/src/templates/chat/.agents/skills/actions/references/provider-apis.md +95 -0
  319. package/src/templates/chat/.agents/skills/create-skill/SKILL.md +9 -35
  320. package/src/templates/chat/.agents/skills/frontend-design/SKILL.md +4 -5
  321. package/src/templates/chat/.agents/skills/turn-into-app/SKILL.md +18 -31
  322. package/src/templates/chat/AGENTS.md +32 -80
  323. package/src/templates/default/.agents/skills/actions/SKILL.md +54 -488
  324. package/src/templates/default/.agents/skills/actions/references/action-fields.md +136 -0
  325. package/src/templates/default/.agents/skills/actions/references/examples.md +94 -0
  326. package/src/templates/default/.agents/skills/actions/references/provider-apis.md +95 -0
  327. package/src/templates/default/.agents/skills/create-skill/SKILL.md +9 -35
  328. package/src/templates/default/.agents/skills/frontend-design/SKILL.md +4 -5
  329. package/src/templates/default/.agents/skills/turn-into-app/SKILL.md +18 -31
  330. package/src/templates/headless/.agents/skills/actions/SKILL.md +54 -488
  331. package/src/templates/headless/.agents/skills/actions/references/action-fields.md +136 -0
  332. package/src/templates/headless/.agents/skills/actions/references/examples.md +94 -0
  333. package/src/templates/headless/.agents/skills/actions/references/provider-apis.md +95 -0
  334. package/src/templates/headless/.agents/skills/turn-into-app/SKILL.md +18 -31
  335. package/src/templates/workspace-core/.agents/skills/actions/SKILL.md +54 -488
  336. package/src/templates/workspace-core/.agents/skills/actions/references/action-fields.md +136 -0
  337. package/src/templates/workspace-core/.agents/skills/actions/references/examples.md +94 -0
  338. package/src/templates/workspace-core/.agents/skills/actions/references/provider-apis.md +95 -0
  339. package/src/templates/workspace-core/.agents/skills/adding-workspace-apps/SKILL.md +1 -0
  340. package/src/templates/workspace-core/.agents/skills/agent-page/SKILL.md +1 -0
  341. package/src/templates/workspace-core/.agents/skills/create-skill/SKILL.md +9 -35
  342. package/src/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +4 -5
  343. package/src/templates/workspace-core/.agents/skills/recurring-jobs/SKILL.md +21 -29
  344. package/src/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +18 -31
  345. package/src/templates/workspace-core/.agents/skills/workspace-conventions/SKILL.md +7 -17
  346. package/src/templates/workspace-core/.agents/skills/writing-agent-instructions/SKILL.md +3 -3
  347. package/src/templates/workspace-core/AGENTS.md +7 -16
@@ -6,9 +6,7 @@ exports through actions against the shared SQL state.
6
6
 
7
7
  ## Skills
8
8
 
9
- Keep this file essential — it is loaded into the agent's context every turn.
10
- Real depth lives in `.agents/skills/`; read the relevant skill before deeper
11
- work in that area.
9
+ Read the relevant skill before deeper work in that area.
12
10
 
13
11
  - `design-generation` — 5-phase generation flow, aesthetic quality bar, code
14
12
  layers/code workspace, editor extensions, breakpoints/screen
@@ -23,19 +21,11 @@ work in that area.
23
21
  - `design-review-feedback` — persisted, element-anchored review comments to a
24
22
  verified close, one root thread at a time.
25
23
  - `export-handoff` — HTML/PNG/SVG/ZIP/code and coding-handoff export.
26
- - `visual-edit` — editing a real local app visually (localhost bridge, Code
27
- tab, reprompt write boundary).
28
24
  - `full-app-build` — design source modes and flag-gated fusion-backed full app
29
25
  building.
30
26
  - `shader-fills` — code-backed GLSL shader fills/effects.
31
- - `sharing` — design and design-system visibility/grants.
32
- - `frontend-design`, `shadcn-ui` for UI; `actions`, `delegate-to-agent`,
33
- `security`, `self-modifying-code` for framework patterns.
34
-
35
- Before building common workspace or agent UI, read `agent-native-toolkit` to
36
- inventory existing public kits and installed package seams. Use
37
- `customizing-agent-native` for the configure → compose → eject → propose seam
38
- ladder.
27
+ - `capture-learnings` — record a user preference or correction so it outlives
28
+ the thread.
39
29
 
40
30
  ## Actions
41
31
 
@@ -58,10 +48,9 @@ ladder.
58
48
  - Use the app actions for designs, files, versions, design systems, variants,
59
49
  export, and sharing. Do not write design rows directly with SQL.
60
50
  - A message beginning with `[Reprompt selection]` is preview-only: the only
61
- mutation path is `propose-node-rewrite`; never call a content writer. See
62
- `visual-edit`'s "Select And Reprompt". `[Selection question]` is read-only:
63
- answer about the captured element and subtree without calling
64
- content-writing actions.
51
+ mutation path is `propose-node-rewrite`; never call a content writer.
52
+ `[Selection question]` is read-only: answer about the captured element and
53
+ subtree without calling content-writing actions.
65
54
  - Call `view-screen` before editing a specific design if the current design or
66
55
  selected file is not already clear from context.
67
56
  - Generated files must be complete, standalone HTML (Alpine.js + Tailwind CDN)
@@ -75,8 +64,6 @@ ladder.
75
64
  promise lossless Figma import/export.
76
65
  - Persist useful work early: create/update the design and files as soon as a
77
66
  coherent candidate exists, then iterate.
78
- - In dev, call actions with `pnpm action <name>`; in production, call the
79
- native tool.
80
67
  - For shared prototype feedback, use the persisted review actions — read
81
68
  `design-review-feedback` for the loop.
82
69
  - Follow linked design-system tokens and `customInstructions` whenever
@@ -105,5 +92,10 @@ ladder.
105
92
  see `design-generation`.
106
93
  - `design-reprompt-pending:<designId>:<fileId>` /
107
94
  `design-reprompt-proposal:<designId>:<fileId>:<repromptId>` — the
108
- compare-and-set reprompt request/proposal pair; see `visual-edit`'s
109
- "Select And Reprompt" for the full lifecycle.
95
+ compare-and-set reprompt request/proposal pair. Both must be present and
96
+ matched before `propose-node-rewrite`; a stale pair is never applied.
97
+
98
+ ## Source Changes
99
+
100
+ Before building common workspace or agent UI, read `agent-native-toolkit`; read
101
+ `customizing-agent-native` before adapting shared UI.
@@ -4444,6 +4444,18 @@ export function DesignCanvas({
4444
4444
  readOnly,
4445
4445
  })}
4446
4446
  data-design-preview-iframe
4447
+ onLoad={(event) => {
4448
+ // The bridge logs into the IFRAME console and cannot read
4449
+ // import.meta.env, so dev has to switch it on from out here.
4450
+ if (!import.meta.env?.DEV) return;
4451
+ try {
4452
+ const win = event.currentTarget.contentWindow as
4453
+ | (Window & { __DND_DEBUG?: boolean })
4454
+ | null;
4455
+ if (win) win.__DND_DEBUG = true;
4456
+ // coercion-ok: a cross-origin preview exposes no contentWindow
4457
+ } catch {}
4458
+ }}
4447
4459
  {...{
4448
4460
  [SESSION_REPLAY_IFRAME_ATTRIBUTE]: !externalPreviewUrl
4449
4461
  ? ""
@@ -1782,6 +1782,9 @@ const LayerRow = memo(function LayerRow({
1782
1782
  // doing so.
1783
1783
  const handleKeyDown = (event: KeyboardEvent<HTMLButtonElement>) => {
1784
1784
  if (event.key === "Enter" || event.key === " " || event.key === "Space") {
1785
+ // Figma drills into the selection on Enter and walks up on Shift+Enter;
1786
+ // re-selecting an already-selected row here would swallow both.
1787
+ if (event.key === "Enter" && isSelected) return;
1785
1788
  event.preventDefault();
1786
1789
  if (!selectable) return;
1787
1790
  onSelect(node.id, {
@@ -1797,12 +1800,21 @@ const LayerRow = memo(function LayerRow({
1797
1800
  onStartRename(node);
1798
1801
  return;
1799
1802
  }
1800
- if (event.key === "ArrowRight" && hasChildren && !isExpanded) {
1803
+ // Only the PLAIN chord toggles the chevron: Shift+Arrow is Figma's big
1804
+ // nudge and every modified arrow belongs to the canvas hotkeys below.
1805
+ const plainArrow =
1806
+ !event.shiftKey && !event.metaKey && !event.ctrlKey && !event.altKey;
1807
+ if (
1808
+ plainArrow &&
1809
+ event.key === "ArrowRight" &&
1810
+ hasChildren &&
1811
+ !isExpanded
1812
+ ) {
1801
1813
  event.preventDefault();
1802
1814
  onToggleExpanded(node.id, true);
1803
1815
  return;
1804
1816
  }
1805
- if (event.key === "ArrowLeft" && hasChildren && isExpanded) {
1817
+ if (plainArrow && event.key === "ArrowLeft" && hasChildren && isExpanded) {
1806
1818
  event.preventDefault();
1807
1819
  onToggleExpanded(node.id, false);
1808
1820
  return;
@@ -2077,17 +2089,22 @@ const LayerRow = memo(function LayerRow({
2077
2089
  >
2078
2090
  {activeDrop === "before" ? (
2079
2091
  <span
2092
+ data-layer-drop-indicator="before"
2080
2093
  className="pointer-events-none absolute right-2 top-0 z-10 h-px bg-[var(--design-editor-accent-color)]"
2081
2094
  style={{ left: rowIndent(depth) }}
2082
2095
  />
2083
2096
  ) : null}
2084
2097
  {activeDrop === "after" ? (
2085
2098
  <span
2099
+ data-layer-drop-indicator="after"
2086
2100
  className="pointer-events-none absolute bottom-0 right-2 z-10 h-px bg-[var(--design-editor-accent-color)]"
2087
2101
  style={{ left: rowIndent(depth) }}
2088
2102
  />
2089
2103
  ) : null}
2090
2104
  <div
2105
+ data-layer-drop-indicator={
2106
+ activeDrop === "inside" ? "inside" : undefined
2107
+ }
2091
2108
  className={cn(
2092
2109
  "group flex h-7 w-max min-w-full items-center gap-1 rounded-[5px] pr-1 text-[12px] bg-[var(--design-editor-panel-bg)]",
2093
2110
  activeDrop === "inside" &&
@@ -51,6 +51,7 @@ import {
51
51
  IconHandClick,
52
52
  IconPlus,
53
53
  } from "@tabler/icons-react";
54
+ import { useTheme } from "next-themes";
54
55
  import {
55
56
  memo,
56
57
  useRef,
@@ -89,6 +90,7 @@ import {
89
90
  } from "./design-canvas/content-size-report";
90
91
  import { appendHitTestResponder } from "./design-canvas/hit-test";
91
92
  import { withLocalRuntimes } from "./design-canvas/local-runtime";
93
+ import { roundGeo, trace } from "./design-trace";
92
94
  import { DesignCanvas } from "./DesignCanvas";
93
95
  import { dndHostLog } from "./dnd-debug";
94
96
  import {
@@ -473,6 +475,7 @@ export const MultiScreenCanvas = memo(function MultiScreenCanvas({
473
475
  onPrimitiveCreated,
474
476
  onPrimitiveReparent,
475
477
  onCreateScreenFrame,
478
+ frameToolDraws = "frame",
476
479
  onDeleteSelection,
477
480
  onNudgeSelection,
478
481
  onZoomChange,
@@ -522,6 +525,7 @@ export const MultiScreenCanvas = memo(function MultiScreenCanvas({
522
525
  onDropFiles,
523
526
  cameraCommand,
524
527
  }: MultiScreenCanvasProps) {
528
+ const { resolvedTheme } = useTheme();
525
529
  const t = useT();
526
530
  const surfaceRef = useRef<HTMLDivElement>(null);
527
531
  const [pan, setPan] = useState({ x: 0, y: 0 });
@@ -641,6 +645,17 @@ export const MultiScreenCanvas = memo(function MultiScreenCanvas({
641
645
  height: surfaceSize.height / scale,
642
646
  };
643
647
  }, [canvasZoom, pan.x, pan.y, surfaceSize.height, surfaceSize.width]);
648
+ // The board iframe cannot read the host's CSS vars, so the themed canvas
649
+ // colour has to be resolved out here or the board stays dark in light mode.
650
+ const boardSurfaceBackground = useMemo(() => {
651
+ if (typeof window === "undefined") return BOARD_SURFACE_BACKGROUND;
652
+ const themed = window
653
+ .getComputedStyle(document.documentElement)
654
+ .getPropertyValue("--design-editor-canvas-bg")
655
+ .trim();
656
+ return themed || BOARD_SURFACE_BACKGROUND;
657
+ }, [resolvedTheme]);
658
+
644
659
  const boardSurfaceRenderGeometry = useMemo(() => {
645
660
  if (!boardFrameGeometry) return undefined;
646
661
  const focusGeometry = boardSurfaceFocusPoint
@@ -692,8 +707,14 @@ export const MultiScreenCanvas = memo(function MultiScreenCanvas({
692
707
  html: boardSurfaceHtml,
693
708
  logicalGeometry: boardFrameGeometry,
694
709
  viewport: boardStaticPreviewViewport,
710
+ background: boardSurfaceBackground,
695
711
  });
696
- }, [boardSurfaceHtml, boardFrameGeometry, boardStaticPreviewViewport]);
712
+ }, [
713
+ boardSurfaceHtml,
714
+ boardFrameGeometry,
715
+ boardStaticPreviewViewport,
716
+ boardSurfaceBackground,
717
+ ]);
697
718
  const showBoardStaticPreview = Boolean(
698
719
  boardFrameGeometry &&
699
720
  boardSurfaceRenderGeometry &&
@@ -2189,6 +2210,25 @@ export const MultiScreenCanvas = memo(function MultiScreenCanvas({
2189
2210
  const sourceIsBoard = sourceScreenId === boardFileId;
2190
2211
  setCrossScreenSourceIsBoard(sourceIsBoard);
2191
2212
  const target = getFrameEntryAtPoint(boardPoint);
2213
+ trace("drop", "resolve-target", {
2214
+ pointerInCanvasUnits: {
2215
+ x: Math.round(boardPoint.x),
2216
+ y: Math.round(boardPoint.y),
2217
+ },
2218
+ hitFrame: target?.id ?? null,
2219
+ sourceScreen: sourceScreenId,
2220
+ sourceIsBoard,
2221
+ frames: Object.entries(frameGeometryRef.current ?? {}).map(
2222
+ ([id, g]: [string, any]) =>
2223
+ `${id.slice(0, 6)} @ ${Math.round(g.x)},${Math.round(g.y)} ${Math.round(g.width)}x${Math.round(g.height)}`,
2224
+ ),
2225
+ verdict:
2226
+ target && target.id !== sourceScreenId
2227
+ ? "will drop into that frame"
2228
+ : target
2229
+ ? "hit the SOURCE frame, so no cross-screen move"
2230
+ : "NO frame under the pointer — drop cannot resolve a screen",
2231
+ });
2192
2232
  if (target && target.id !== sourceScreenId) {
2193
2233
  const nextTarget = { id: target.id, geometry: target.geometry };
2194
2234
  if (crossScreenTargetRef.current?.id !== nextTarget.id) {
@@ -2261,6 +2301,29 @@ export const MultiScreenCanvas = memo(function MultiScreenCanvas({
2261
2301
  const hasIdentifier = !!(payload.selector || payload.sourceId);
2262
2302
  if (!hasIdentifier || !sourceScreenId) return;
2263
2303
  if (!lastBoardPoint) return;
2304
+ // No candidate means the pointer never left the source screen, so the
2305
+ // bridge already handled it as an in-place reorder. Falling back to the
2306
+ // board here re-persists the move against a file that does not contain
2307
+ // the element, which fails to resolve and silently discards the drop.
2308
+ const sourceFrameGeometry = frameGeometryRef.current?.[sourceScreenId];
2309
+ const droppedInsideSourceScreen =
2310
+ !candidate &&
2311
+ !!sourceFrameGeometry &&
2312
+ lastBoardPoint.x >= sourceFrameGeometry.x &&
2313
+ lastBoardPoint.x <= sourceFrameGeometry.x + sourceFrameGeometry.width &&
2314
+ lastBoardPoint.y >= sourceFrameGeometry.y &&
2315
+ lastBoardPoint.y <= sourceFrameGeometry.y + sourceFrameGeometry.height;
2316
+ if (droppedInsideSourceScreen) return;
2317
+ trace("drop", "finalize", {
2318
+ candidate: candidate?.id ?? null,
2319
+ sourceScreen: sourceScreenId,
2320
+ droppedInsideSourceScreen,
2321
+ outcome: droppedInsideSourceScreen
2322
+ ? "discarded — pointer never left the source screen"
2323
+ : candidate
2324
+ ? "moving into candidate"
2325
+ : "no candidate; falling back to the board",
2326
+ });
2264
2327
  const targetCandidate =
2265
2328
  candidate ??
2266
2329
  (boardFileId && sourceScreenId !== boardFileId && boardFrameGeometry
@@ -2927,6 +2990,14 @@ export const MultiScreenCanvas = memo(function MultiScreenCanvas({
2927
2990
  const viewportWidth = iframe?.clientWidth || metadata.width;
2928
2991
  const viewportHeight = iframe?.clientHeight || metadata.height;
2929
2992
  const infos = await requestSelectableElementInfos(entry.id);
2993
+ // entry.geometry.height trails the measured auto-height, and an
2994
+ // independent y-scale off it squashes every child rect.
2995
+ const contentScale =
2996
+ entry.geometry.width / Math.max(1, viewportWidth);
2997
+ const renderedFrame = {
2998
+ ...entry.geometry,
2999
+ height: viewportHeight * contentScale,
3000
+ };
2930
3001
  return infos.map((info) => ({
2931
3002
  screenId: entry.id,
2932
3003
  info,
@@ -2937,7 +3008,7 @@ export const MultiScreenCanvas = memo(function MultiScreenCanvas({
2937
3008
  width: info.boundingRect.width,
2938
3009
  height: info.boundingRect.height,
2939
3010
  },
2940
- entry.geometry,
3011
+ renderedFrame,
2941
3012
  { width: viewportWidth, height: viewportHeight },
2942
3013
  ),
2943
3014
  frameGeometry: entry.geometry,
@@ -3718,11 +3789,27 @@ export const MultiScreenCanvas = memo(function MultiScreenCanvas({
3718
3789
  getScreenMetadata?.(targetScreen),
3719
3790
  )
3720
3791
  : undefined;
3792
+ // Metadata defaults to 1280x2560 while the renderer lays the iframe out
3793
+ // at the frame's own size; trusting metadata scales every drawn
3794
+ // primitive by metadataWidth/frameWidth. Same precedence as the marquee.
3795
+ const targetIframe = targetScreen
3796
+ ? surfaceRef.current?.querySelector<HTMLIFrameElement>(
3797
+ `[data-screen-iframe-id="${CSS.escape(getActiveScreenIframeId(targetScreen))}"]`,
3798
+ )
3799
+ : null;
3800
+ const measuredMetadata =
3801
+ targetMetadata && targetIframe?.clientWidth && targetIframe.clientHeight
3802
+ ? {
3803
+ ...targetMetadata,
3804
+ width: targetIframe.clientWidth,
3805
+ height: targetIframe.clientHeight,
3806
+ }
3807
+ : targetMetadata;
3721
3808
 
3722
3809
  const localPrimitive = draftPrimitiveToInsert(
3723
3810
  draft,
3724
3811
  targetFrame.geometry,
3725
- targetMetadata,
3812
+ measuredMetadata,
3726
3813
  );
3727
3814
  const persisted = onCreatePrimitive(targetFrame.id, localPrimitive);
3728
3815
  if (!persisted) {
@@ -4436,6 +4523,7 @@ export const MultiScreenCanvas = memo(function MultiScreenCanvas({
4436
4523
  // originating screen.
4437
4524
  if (
4438
4525
  state.tool === "frame" &&
4526
+ frameToolDraws === "screen" &&
4439
4527
  !state.originFrameId &&
4440
4528
  onCreateScreenFrame
4441
4529
  ) {
@@ -4459,9 +4547,19 @@ export const MultiScreenCanvas = memo(function MultiScreenCanvas({
4459
4547
  0,
4460
4548
  )
4461
4549
  : null;
4462
- onCreateScreenFrame(
4463
- clampFrameGeometryToViewport(draftGeometry, viewportBounds),
4550
+ const screenGeometry = clampFrameGeometryToViewport(
4551
+ draftGeometry,
4552
+ viewportBounds,
4464
4553
  );
4554
+ trace("screen", "create-from-frame-tool", {
4555
+ why: "frame tool started on empty canvas, so it becomes a SCREEN",
4556
+ drawn: roundGeo(draftGeometry),
4557
+ committed: roundGeo(screenGeometry),
4558
+ clamped:
4559
+ Math.round(draftGeometry.x) !== Math.round(screenGeometry.x) ||
4560
+ Math.round(draftGeometry.y) !== Math.round(screenGeometry.y),
4561
+ });
4562
+ onCreateScreenFrame(screenGeometry);
4465
4563
  if (activeTool === undefined) {
4466
4564
  setLocalActiveTool("move");
4467
4565
  }
@@ -4469,6 +4567,10 @@ export const MultiScreenCanvas = memo(function MultiScreenCanvas({
4469
4567
  finishDrag();
4470
4568
  return;
4471
4569
  }
4570
+ trace("draw", "commit-primitive", {
4571
+ tool: state.tool,
4572
+ startedInScreen: state.originFrameId ?? "(empty canvas → board)",
4573
+ });
4472
4574
  const nextDraft = createDraftPrimitive({
4473
4575
  tool: state.tool,
4474
4576
  start: state.originCanvas,
@@ -4503,6 +4605,7 @@ export const MultiScreenCanvas = memo(function MultiScreenCanvas({
4503
4605
  activeTool,
4504
4606
  commitDraftPrimitive,
4505
4607
  finishDrag,
4608
+ frameToolDraws,
4506
4609
  getCanvasPoint,
4507
4610
  getFrameEntryAtPoint,
4508
4611
  installDragListeners,
@@ -7474,6 +7577,11 @@ export const MultiScreenCanvas = memo(function MultiScreenCanvas({
7474
7577
  const chromeScale = scale > 0 ? 1 / scale : 1;
7475
7578
  const showPixelGrid = canvasZoom >= PIXEL_GRID_ZOOM;
7476
7579
  const effectiveTool = normalizeCanvasTool(activeTool ?? localActiveTool);
7580
+ const lastTracedToolRef = useRef<string | null>(null);
7581
+ if (lastTracedToolRef.current !== effectiveTool) {
7582
+ lastTracedToolRef.current = effectiveTool;
7583
+ trace("tool", "active-tool", { tool: effectiveTool });
7584
+ }
7477
7585
  useEffect(() => {
7478
7586
  effectiveToolRef.current = effectiveTool;
7479
7587
  }, [effectiveTool]);
@@ -7624,7 +7732,7 @@ export const MultiScreenCanvas = memo(function MultiScreenCanvas({
7624
7732
  metadata.previewUrl ?? getPreviewUrl(screen.content)
7625
7733
  );
7626
7734
  const autoHeight =
7627
- isInlineScreen && measuredPrimaryHeight
7735
+ isInlineScreen && measuredPrimaryHeight && !metadata.heightPinned
7628
7736
  ? Math.max(
7629
7737
  deviceViewportFloorForWidth(metadata.width),
7630
7738
  rawGeometry.height ?? 0,
@@ -8055,7 +8163,7 @@ export const MultiScreenCanvas = memo(function MultiScreenCanvas({
8055
8163
  zoom={100}
8056
8164
  deviceFrame="none"
8057
8165
  boardSurface
8058
- embeddedFrameBackground={BOARD_SURFACE_BACKGROUND}
8166
+ embeddedFrameBackground={boardSurfaceBackground}
8059
8167
  embeddedFrame={{
8060
8168
  viewportWidth: Math.max(1, Math.round(boardW)),
8061
8169
  viewportHeight: Math.max(1, Math.round(boardH)),
@@ -2749,6 +2749,9 @@ declare var __SELECTED_LAYER_DRAG_PRIORITY__: boolean;
2749
2749
 
2750
2750
  var passiveSelectionEls: Element[] = [];
2751
2751
  var passiveSelectionOverlays: HTMLElement[] = [];
2752
+ // Figma draws ONE bounding box with handles around a multi-selection; the
2753
+ // per-element overlays above are the thin outlines inside it.
2754
+ var multiSelectionBoundsOverlay: HTMLElement | null = null;
2752
2755
  var activeMarqueeSelection: {
2753
2756
  startX: number;
2754
2757
  startY: number;
@@ -3042,7 +3045,6 @@ declare var __SELECTED_LAYER_DRAG_PRIORITY__: boolean;
3042
3045
  style === "soft"
3043
3046
  ? "position:fixed;pointer-events:none;z-index:99996;border:1px solid color-mix(in srgb,var(--design-editor-accent-color) 64%,transparent);background:color-mix(in srgb,var(--design-editor-accent-color) 5%,transparent);display:none;box-sizing:border-box;"
3044
3047
  : "position:fixed;pointer-events:none;z-index:99996;border:1.5px solid var(--design-editor-accent-color);background:transparent;display:none;box-sizing:border-box;";
3045
- if (style !== "soft") appendPassiveSelectionHandles(overlay);
3046
3048
  document.body.appendChild(overlay);
3047
3049
  return overlay;
3048
3050
  }
@@ -3088,6 +3090,9 @@ declare var __SELECTED_LAYER_DRAG_PRIORITY__: boolean;
3088
3090
  passiveSelectionOverlays.push(overlay);
3089
3091
  positionOverlay(overlay, el);
3090
3092
  });
3093
+ // Selection changes do not go through refreshOverlays, so the combined
3094
+ // bounds must be recomputed here too.
3095
+ positionMultiSelectionBounds();
3091
3096
  }
3092
3097
 
3093
3098
  function preservePreviousSelectedElementForShiftClick(
@@ -4536,6 +4541,70 @@ declare var __SELECTED_LAYER_DRAG_PRIORITY__: boolean;
4536
4541
  return true;
4537
4542
  }
4538
4543
 
4544
+ function ensureMultiSelectionBoundsOverlay(): HTMLElement {
4545
+ if (multiSelectionBoundsOverlay) return multiSelectionBoundsOverlay;
4546
+ var overlay = document.createElement("div");
4547
+ overlay.setAttribute("data-agent-native-edit-overlay", "multi-selection");
4548
+ overlay.setAttribute("data-agent-native-multi-selection-bounds", "true");
4549
+ overlay.style.cssText =
4550
+ "position:fixed;pointer-events:none;z-index:99996;border:1.5px solid var(--design-editor-accent-color);background:transparent;display:none;box-sizing:border-box;";
4551
+ appendPassiveSelectionHandles(overlay);
4552
+ document.body.appendChild(overlay);
4553
+ multiSelectionBoundsOverlay = overlay;
4554
+ return overlay;
4555
+ }
4556
+
4557
+ function positionMultiSelectionBounds(): void {
4558
+ var members: Element[] = [];
4559
+ if (selectedEl && document.documentElement.contains(selectedEl)) {
4560
+ members.push(selectedEl);
4561
+ }
4562
+ passiveSelectionEls.forEach(function (el) {
4563
+ if (el && document.documentElement.contains(el)) members.push(el);
4564
+ });
4565
+ if (members.length < 2 || selectionChromeHidden) {
4566
+ if (multiSelectionBoundsOverlay) {
4567
+ multiSelectionBoundsOverlay.style.display = "none";
4568
+ }
4569
+ return;
4570
+ }
4571
+ var rects = members.map(function (el) {
4572
+ return (el as HTMLElement).getBoundingClientRect();
4573
+ });
4574
+ var left = Math.min.apply(
4575
+ null,
4576
+ rects.map(function (r) {
4577
+ return r.left;
4578
+ }),
4579
+ );
4580
+ var top = Math.min.apply(
4581
+ null,
4582
+ rects.map(function (r) {
4583
+ return r.top;
4584
+ }),
4585
+ );
4586
+ var right = Math.max.apply(
4587
+ null,
4588
+ rects.map(function (r) {
4589
+ return r.right;
4590
+ }),
4591
+ );
4592
+ var bottom = Math.max.apply(
4593
+ null,
4594
+ rects.map(function (r) {
4595
+ return r.bottom;
4596
+ }),
4597
+ );
4598
+ var overlay = ensureMultiSelectionBoundsOverlay();
4599
+ overlay.style.display = "block";
4600
+ overlay.style.transform = "none";
4601
+ overlay.style.left = left + "px";
4602
+ overlay.style.top = top + "px";
4603
+ overlay.style.width = Math.max(0, right - left) + "px";
4604
+ overlay.style.height = Math.max(0, bottom - top) + "px";
4605
+ scalePassiveSelectionOverlay(overlay);
4606
+ }
4607
+
4539
4608
  function positionOverlay(overlay: HTMLElement, el: Element): void {
4540
4609
  if (!el || !document.documentElement.contains(el)) {
4541
4610
  overlay.style.display = "none";
@@ -4603,6 +4672,7 @@ declare var __SELECTED_LAYER_DRAG_PRIORITY__: boolean;
4603
4672
  var overlay = passiveSelectionOverlays[index];
4604
4673
  if (overlay) positionOverlay(overlay, el);
4605
4674
  });
4675
+ positionMultiSelectionBounds();
4606
4676
  positionGradientOverlay();
4607
4677
  syncOverlayObservers();
4608
4678
  }
@@ -5000,10 +5070,12 @@ declare var __SELECTED_LAYER_DRAG_PRIORITY__: boolean;
5000
5070
  if (isOverlayElement(target)) continue;
5001
5071
  if (isLayerInteractionBlocked(target)) {
5002
5072
  lastEditorPointWasBlocked = true;
5073
+ dndLog("select:blocked", { el: getSelector(target) });
5003
5074
  return null;
5004
5075
  }
5005
5076
  return target;
5006
5077
  }
5078
+ dndLog("select:nothing-at-point", { x: clientX, y: clientY });
5007
5079
  return null;
5008
5080
  }
5009
5081
 
@@ -7285,12 +7357,9 @@ declare var __SELECTED_LAYER_DRAG_PRIORITY__: boolean;
7285
7357
  el.getAttribute("data-agent-native-primitive") ||
7286
7358
  ""
7287
7359
  ).toLowerCase();
7288
- if (
7289
- primitive !== "rectangle" &&
7290
- primitive !== "rect" &&
7291
- primitive !== "frame"
7292
- )
7293
- return false;
7360
+ // Frames adopt; a rectangle is a vector shape and never becomes a
7361
+ // container (same contract appendCanvasPrimitiveToHtml enforces on draw).
7362
+ if (primitive !== "frame") return false;
7294
7363
  var cs = window.getComputedStyle(el);
7295
7364
  return cs.position === "absolute" || cs.position === "fixed";
7296
7365
  }
@@ -7685,6 +7754,9 @@ declare var __SELECTED_LAYER_DRAG_PRIORITY__: boolean;
7685
7754
  if (!el || el === document.documentElement) return false;
7686
7755
  if (isOverlayElement(el) || isLayerInteractionBlocked(el)) return false;
7687
7756
  if (el === document.body) return true;
7757
+ // Figma's shape primitives are vectors; only a frame adopts children.
7758
+ var primitiveKind = el.getAttribute("data-an-primitive");
7759
+ if (primitiveKind && primitiveKind !== "frame") return false;
7688
7760
  var tag = (el.tagName || "").toLowerCase();
7689
7761
  // Reject leaf/text tags — they cannot accept children
7690
7762
  if (
@@ -12519,6 +12591,9 @@ declare var __SELECTED_LAYER_DRAG_PRIORITY__: boolean;
12519
12591
  } else {
12520
12592
  positionOverlay(selectionOverlay, target);
12521
12593
  }
12594
+ // The combined box spans selectedEl plus the passive selection, so a
12595
+ // host-driven change leaves it on the previous geometry without this.
12596
+ positionMultiSelectionBounds();
12522
12597
  if (hoveredEl === selectedEl) highlightOverlay.style.display = "none";
12523
12598
  // A host-driven selection (e.g. picking a layer in the Layers panel)
12524
12599
  // only ever moved the overlay above — it never sent the rich
@@ -0,0 +1,120 @@
1
+ // Interaction trace, on by default in dev. From the top-frame console:
2
+ // `__DESIGN_TRACE = false` silences it; `__designTrace.dump()` prints the
3
+ // whole story to copy; `.clear()` and `.only("drop")` narrow it.
4
+ declare global {
5
+ interface Window {
6
+ __DESIGN_TRACE?: boolean;
7
+ __designTrace?: {
8
+ dump: () => string;
9
+ clear: () => void;
10
+ only: (area?: string) => void;
11
+ entries: () => TraceEntry[];
12
+ };
13
+ }
14
+ }
15
+
16
+ export type TraceArea =
17
+ | "tool"
18
+ | "draw"
19
+ | "screen"
20
+ | "select"
21
+ | "drag"
22
+ | "drop"
23
+ | "persist"
24
+ | "structure"
25
+ | "history";
26
+
27
+ export interface TraceEntry {
28
+ t: number;
29
+ area: TraceArea;
30
+ event: string;
31
+ data?: unknown;
32
+ }
33
+
34
+ const MAX_ENTRIES = 2000;
35
+ const entries: TraceEntry[] = [];
36
+ let areaFilter: string | undefined;
37
+ let startedAt = 0;
38
+
39
+ function enabled(): boolean {
40
+ if (typeof window === "undefined") return false;
41
+ if (window.__DESIGN_TRACE === false) return false;
42
+ return window.__DESIGN_TRACE === true || import.meta.env?.DEV === true;
43
+ }
44
+
45
+ function ensureControls(): void {
46
+ if (typeof window === "undefined" || window.__designTrace) return;
47
+ window.__designTrace = {
48
+ entries: () => entries.slice(),
49
+ clear: () => {
50
+ entries.length = 0;
51
+ startedAt = 0;
52
+ },
53
+ only: (area?: string) => {
54
+ areaFilter = area;
55
+ },
56
+ dump: () =>
57
+ entries
58
+ .map((e) => {
59
+ const body = e.data === undefined ? "" : ` ${safeJson(e.data)}`;
60
+ return `+${String(e.t).padStart(6)}ms [${e.area}:${e.event}]${body}`;
61
+ })
62
+ .join("\n"),
63
+ };
64
+ }
65
+
66
+ /** Never let a circular ref or a DOM node break a gesture. */
67
+ function safeJson(value: unknown): string {
68
+ try {
69
+ return JSON.stringify(value, (_key, v) =>
70
+ v instanceof Element ? v.tagName.toLowerCase() : v,
71
+ );
72
+ } catch {
73
+ return String(value);
74
+ }
75
+ }
76
+
77
+ export function trace(area: TraceArea, event: string, data?: unknown): void {
78
+ if (!enabled()) return;
79
+ try {
80
+ ensureControls();
81
+ const now = Date.now();
82
+ if (!startedAt) startedAt = now;
83
+ const entry: TraceEntry = { t: now - startedAt, area, event, data };
84
+ entries.push(entry);
85
+ if (entries.length > MAX_ENTRIES) entries.shift();
86
+ if (areaFilter && areaFilter !== area) return;
87
+ const tag = `%c[${area}:${event}]`;
88
+ const style = "font-weight:bold";
89
+ if (data === undefined) console.log(tag, style);
90
+ else console.log(tag, style, data);
91
+ // coercion-ok: diagnostics must never break the interaction they observe
92
+ } catch {}
93
+ }
94
+
95
+ /** Short, stable label for an element in a trace line. */
96
+ export function traceEl(el: Element | null | undefined): string | null {
97
+ if (!el) return null;
98
+ const id = el.getAttribute?.("data-agent-native-node-id");
99
+ const name = el.getAttribute?.("data-agent-native-layer-name");
100
+ const primitive = el.getAttribute?.("data-an-primitive");
101
+ const tag = el.tagName?.toLowerCase() ?? "?";
102
+ return [
103
+ tag,
104
+ primitive && `(${primitive})`,
105
+ name && `"${name}"`,
106
+ id && `#${id}`,
107
+ ]
108
+ .filter(Boolean)
109
+ .join(" ");
110
+ }
111
+
112
+ /** Compact geometry for a trace line. */
113
+ export function roundGeo(g: {
114
+ x: number;
115
+ y: number;
116
+ width: number;
117
+ height: number;
118
+ }): string {
119
+ return `${Math.round(g.x)},${Math.round(g.y)} ${Math.round(g.width)}x${Math.round(g.height)}`;
120
+ }
@@ -15,7 +15,8 @@ declare global {
15
15
 
16
16
  export function dndHostLog(phase: string, data?: unknown): void {
17
17
  if (typeof window === "undefined") return;
18
- if (!window.__DND_DEBUG) return;
18
+ if (window.__DND_DEBUG === false) return;
19
+ if (!window.__DND_DEBUG && !import.meta.env?.DEV) return;
19
20
  try {
20
21
  const tag = `%c[dnd:host:${phase}]`;
21
22
  const style = "color:#0ea5e9;font-weight:bold";