@jxsuite/studio 2.0.1 → 2.1.0

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 (419) hide show
  1. package/canvas.html +21 -0
  2. package/dist/chunks/Overlay.dev-qfjzkms8.js +23 -0
  3. package/dist/chunks/{Overlay.dev-cszx7yn5.js.map → Overlay.dev-qfjzkms8.js.map} +1 -1
  4. package/dist/chunks/{adapter-z8fkmbmv.js → adapter-qfnesn5v.js} +2 -2
  5. package/dist/chunks/{cf-settings-mmyv436d.js → cf-settings-73sh5z4p.js} +3 -3
  6. package/dist/chunks/{components-799jpvhm.js → components-2bpqp4mq.js} +5 -7
  7. package/dist/chunks/{components-799jpvhm.js.map → components-2bpqp4mq.js.map} +1 -1
  8. package/dist/chunks/content-source-34gnkbnn.js +38 -0
  9. package/dist/chunks/content-source-34gnkbnn.js.map +9 -0
  10. package/dist/chunks/convert-to-repeater-t8kxre5s.js +258 -0
  11. package/dist/chunks/convert-to-repeater-t8kxre5s.js.map +10 -0
  12. package/dist/chunks/extension-sections-6mqydz35.js +301 -0
  13. package/dist/chunks/extension-sections-6mqydz35.js.map +11 -0
  14. package/dist/chunks/files-8kn321h1.js +70 -0
  15. package/dist/chunks/files-8kn321h1.js.map +9 -0
  16. package/dist/chunks/{format-host-8jxwts2p.js → format-host-mkwsmt8d.js} +3 -3
  17. package/dist/chunks/git-panel-tjbr191d.js +51 -0
  18. package/dist/chunks/git-panel-tjbr191d.js.map +9 -0
  19. package/dist/chunks/{index-baeg2x3y.js → index-7pxchcce.js} +4 -3
  20. package/dist/chunks/{index-baeg2x3y.js.map → index-7pxchcce.js.map} +3 -3
  21. package/dist/chunks/{jx-validate-qx8degj7.js → jx-validate-v6qgknrs.js} +3 -3
  22. package/dist/chunks/layers-panel-87pb25km.js +58 -0
  23. package/dist/chunks/layers-panel-87pb25km.js.map +9 -0
  24. package/dist/chunks/{monaco-setup-zjdp9zdw.js → monaco-setup-e0yh25j4.js} +4 -75
  25. package/dist/chunks/{monaco-setup-zjdp9zdw.js.map → monaco-setup-e0yh25j4.js.map} +3 -4
  26. package/dist/chunks/publish-panel-m0fcgdrt.js +21 -0
  27. package/dist/chunks/publish-panel-m0fcgdrt.js.map +9 -0
  28. package/dist/chunks/quick-search-rhs6cbsb.js +53 -0
  29. package/dist/chunks/quick-search-rhs6cbsb.js.map +9 -0
  30. package/dist/chunks/right-panel-zpdxd98t.js +37 -0
  31. package/dist/chunks/right-panel-zpdxd98t.js.map +9 -0
  32. package/dist/chunks/section-registry-zmckaxf4.js +30 -0
  33. package/dist/chunks/section-registry-zmckaxf4.js.map +9 -0
  34. package/dist/chunks/sp-overlay.dev-9ran0sfq.js +18 -0
  35. package/dist/chunks/sp-overlay.dev-9ran0sfq.js.map +9 -0
  36. package/dist/chunks/sp-popover.dev-rebmdncr.js +9 -0
  37. package/dist/chunks/sp-popover.dev-rebmdncr.js.map +9 -0
  38. package/dist/chunks/sp-progress-circle.dev-5vkppfkt.js +15 -0
  39. package/dist/chunks/sp-progress-circle.dev-5vkppfkt.js.map +9 -0
  40. package/dist/chunks/sp-tooltip.dev-ykqrg8h5.js +15 -0
  41. package/dist/chunks/sp-tooltip.dev-ykqrg8h5.js.map +9 -0
  42. package/dist/chunks/{sp-tray.dev-pb2fsd65.js → sp-tray.dev-ey59vfh7.js} +10 -8
  43. package/dist/chunks/{sp-tray.dev-pb2fsd65.js.map → sp-tray.dev-ey59vfh7.js.map} +2 -2
  44. package/dist/chunks/{studio-9qr6fq7p.js → studio-0rqqhrdy.js} +10 -378
  45. package/dist/chunks/{studio-9qr6fq7p.js.map → studio-0rqqhrdy.js.map} +4 -14
  46. package/dist/chunks/{studio-5x6tqqec.js → studio-2sj1jj3v.js} +10 -8
  47. package/dist/chunks/{studio-5x6tqqec.js.map → studio-2sj1jj3v.js.map} +2 -2
  48. package/dist/chunks/{studio-h3fw0wn8.js → studio-3fk1ac9z.js} +6 -4
  49. package/dist/chunks/{studio-h3fw0wn8.js.map → studio-3fk1ac9z.js.map} +2 -2
  50. package/dist/chunks/studio-41exgzhq.js +6690 -0
  51. package/dist/chunks/studio-41exgzhq.js.map +38 -0
  52. package/dist/chunks/{studio-7v2bpweq.js → studio-4mqb9a0j.js} +6 -4
  53. package/dist/chunks/{studio-7v2bpweq.js.map → studio-4mqb9a0j.js.map} +2 -2
  54. package/dist/chunks/studio-50k77cca.js +1787 -0
  55. package/dist/chunks/studio-50k77cca.js.map +18 -0
  56. package/dist/chunks/{studio-56v3zwk6.js → studio-6a0h7sne.js} +10 -8
  57. package/dist/chunks/{studio-56v3zwk6.js.map → studio-6a0h7sne.js.map} +2 -2
  58. package/dist/chunks/studio-6f0am8f2.js +53 -0
  59. package/dist/chunks/studio-6f0am8f2.js.map +10 -0
  60. package/dist/chunks/studio-6nmjc5qk.js +7002 -0
  61. package/dist/chunks/studio-6nmjc5qk.js.map +32 -0
  62. package/dist/chunks/studio-7afd21nw.js +67 -0
  63. package/dist/chunks/studio-7afd21nw.js.map +10 -0
  64. package/dist/chunks/{studio-xze4zrs1.js → studio-7bmdvzne.js} +2 -2
  65. package/dist/chunks/studio-7bmdvzne.js.map +10 -0
  66. package/dist/chunks/studio-8jpzqk5s.js +128 -0
  67. package/dist/chunks/studio-8jpzqk5s.js.map +10 -0
  68. package/dist/chunks/studio-94m77tgk.js +1482 -0
  69. package/dist/chunks/studio-94m77tgk.js.map +13 -0
  70. package/dist/chunks/studio-9je6w5sq.js +1000 -0
  71. package/dist/chunks/studio-9je6w5sq.js.map +16 -0
  72. package/dist/chunks/{studio-w7c6kvk7.js → studio-a7pzveq1.js} +2 -2
  73. package/dist/chunks/{studio-gs6kqdt1.js → studio-adn0z1k3.js} +14 -8
  74. package/dist/chunks/{studio-gs6kqdt1.js.map → studio-adn0z1k3.js.map} +3 -3
  75. package/dist/chunks/{studio-kr88ryr7.js → studio-bsxxx3x2.js} +17 -15
  76. package/dist/chunks/{studio-kr88ryr7.js.map → studio-bsxxx3x2.js.map} +7 -6
  77. package/dist/chunks/studio-bw5dz6km.js +608 -0
  78. package/dist/chunks/studio-bw5dz6km.js.map +21 -0
  79. package/dist/chunks/studio-c6s5getc.js +4232 -0
  80. package/dist/chunks/studio-c6s5getc.js.map +39 -0
  81. package/dist/chunks/studio-cjm7fdjf.js +451 -0
  82. package/dist/chunks/studio-cjm7fdjf.js.map +14 -0
  83. package/dist/chunks/{studio-cx91mnh8.js → studio-ckwz4d3x.js} +53 -53
  84. package/dist/chunks/{studio-cx91mnh8.js.map → studio-ckwz4d3x.js.map} +5 -5
  85. package/dist/chunks/studio-dg7zyt5x.js +28 -0
  86. package/dist/chunks/studio-dg7zyt5x.js.map +10 -0
  87. package/dist/chunks/studio-dzcyvvvz.js +166 -0
  88. package/dist/chunks/studio-dzcyvvvz.js.map +10 -0
  89. package/dist/chunks/{studio-7kqe41sa.js → studio-evkr5d3b.js} +15 -7
  90. package/dist/chunks/{studio-7kqe41sa.js.map → studio-evkr5d3b.js.map} +5 -4
  91. package/dist/chunks/studio-f12h6177.js +411 -0
  92. package/dist/chunks/studio-f12h6177.js.map +13 -0
  93. package/dist/chunks/studio-hbp1s8m9.js +1817 -0
  94. package/dist/chunks/studio-hbp1s8m9.js.map +14 -0
  95. package/dist/chunks/studio-k2sxjph5.js +15295 -0
  96. package/dist/chunks/studio-k2sxjph5.js.map +235 -0
  97. package/dist/chunks/studio-myje51t3.js +385 -0
  98. package/dist/chunks/studio-myje51t3.js.map +12 -0
  99. package/dist/chunks/studio-na6rwzhw.js +353 -0
  100. package/dist/chunks/studio-na6rwzhw.js.map +11 -0
  101. package/dist/chunks/{studio-4k0m4fmp.js → studio-p471gg5n.js} +126 -3
  102. package/dist/chunks/studio-p471gg5n.js.map +14 -0
  103. package/dist/chunks/{studio-9bjwf0d4.js → studio-rgwcpast.js} +5 -46
  104. package/dist/chunks/{studio-9bjwf0d4.js.map → studio-rgwcpast.js.map} +4 -5
  105. package/dist/chunks/{studio-esrewxap.js → studio-s519zc99.js} +3 -3
  106. package/dist/chunks/studio-sas7mt3k.js +75 -0
  107. package/dist/chunks/studio-sas7mt3k.js.map +10 -0
  108. package/dist/chunks/studio-t5wqwzdh.js +74 -0
  109. package/dist/chunks/studio-t5wqwzdh.js.map +10 -0
  110. package/dist/chunks/{studio-9qpspwfn.js → studio-temv5bw4.js} +5 -5
  111. package/dist/chunks/{studio-9qpspwfn.js.map → studio-temv5bw4.js.map} +1 -1
  112. package/dist/chunks/{studio-qkvt37c0.js → studio-tr20m8g8.js} +669 -18
  113. package/dist/chunks/studio-tr20m8g8.js.map +9 -0
  114. package/dist/chunks/{studio-v7jkjqng.js → studio-v96qfnww.js} +5514 -4291
  115. package/dist/chunks/studio-v96qfnww.js.map +54 -0
  116. package/dist/chunks/studio-vcetc91k.js +659 -0
  117. package/dist/chunks/studio-vcetc91k.js.map +10 -0
  118. package/dist/chunks/{studio-jm0z592w.js → studio-vmymjefp.js} +2972 -4937
  119. package/dist/chunks/studio-vmymjefp.js.map +98 -0
  120. package/dist/chunks/{studio-bghqfmea.js → studio-wwseqyw0.js} +2 -2
  121. package/dist/chunks/studio-x9hmy5kr.js +390 -0
  122. package/dist/chunks/studio-x9hmy5kr.js.map +10 -0
  123. package/dist/chunks/studio-xa0ce0n7.js +335 -0
  124. package/dist/chunks/studio-xa0ce0n7.js.map +10 -0
  125. package/dist/chunks/studio-xm3dbxvn.js +378 -0
  126. package/dist/chunks/studio-xm3dbxvn.js.map +19 -0
  127. package/dist/chunks/{studio-nqw433kv.js → studio-xmvbhg31.js} +2 -2
  128. package/dist/chunks/studio-zv37yrfa.js +1054 -0
  129. package/dist/chunks/studio-zv37yrfa.js.map +13 -0
  130. package/dist/chunks/{ws-client-q7hkz3j9.js → ws-client-654ts66j.js} +6 -4
  131. package/dist/chunks/ws-client-654ts66j.js.map +11 -0
  132. package/dist/iframe-entry.js +668 -230
  133. package/dist/studio.js +21080 -32585
  134. package/index.html +35 -4685
  135. package/package.json +17 -15
  136. package/src/about/about-modal.ts +42 -11
  137. package/src/browse/library-commands.ts +240 -0
  138. package/src/browse/library-layouts.ts +369 -0
  139. package/src/browse/library-model.ts +396 -0
  140. package/src/browse/library-pane.ts +1049 -0
  141. package/src/browse/library-preview.ts +252 -0
  142. package/src/browse/library-source.ts +150 -0
  143. package/src/canvas/canvas-helpers.ts +33 -9
  144. package/src/canvas/canvas-live-render.ts +45 -29
  145. package/src/canvas/canvas-patcher.ts +151 -31
  146. package/src/canvas/canvas-perf.ts +46 -7
  147. package/src/canvas/canvas-render.ts +1092 -220
  148. package/src/canvas/canvas-surface.ts +240 -0
  149. package/src/canvas/canvas-utils.ts +1166 -124
  150. package/src/canvas/iframe-drop.ts +2 -1
  151. package/src/canvas/iframe-entry.ts +241 -4
  152. package/src/canvas/iframe-host.ts +1226 -143
  153. package/src/canvas/iframe-inline-edit.ts +31 -0
  154. package/src/canvas/iframe-interaction.ts +76 -16
  155. package/src/canvas/iframe-keys.ts +107 -45
  156. package/src/canvas/iframe-overlay.ts +38 -1
  157. package/src/canvas/iframe-protocol.ts +137 -2
  158. package/src/canvas/iframe-render.ts +70 -2
  159. package/src/canvas/iframe-slash.ts +6 -0
  160. package/src/canvas/path-mapping.ts +56 -6
  161. package/src/canvas/surface-registry.ts +292 -0
  162. package/src/collab/collab-commands.ts +244 -0
  163. package/src/collab/collab-session.ts +198 -32
  164. package/src/collab/collab-state.ts +28 -2
  165. package/src/collab/presence-chips.ts +100 -9
  166. package/src/commands/active-registry.ts +42 -0
  167. package/src/commands/app-commands.ts +176 -0
  168. package/src/commands/budget.ts +158 -0
  169. package/src/commands/command-args.ts +253 -0
  170. package/src/commands/context.ts +387 -0
  171. package/src/commands/defaults.ts +580 -0
  172. package/src/commands/keymap.ts +571 -0
  173. package/src/commands/levels.ts +345 -0
  174. package/src/commands/live-context.ts +193 -0
  175. package/src/commands/reference.ts +227 -0
  176. package/src/commands/registry.ts +293 -0
  177. package/src/component-props.ts +3 -2
  178. package/src/content/draft-state.ts +106 -0
  179. package/src/content/entry-commands.ts +282 -0
  180. package/src/content/entry-editor.ts +327 -0
  181. package/src/content/entry-fields.ts +116 -0
  182. package/src/content/entry-model.ts +175 -0
  183. package/src/editor/canvas-context-menu.ts +17 -11
  184. package/src/editor/canvas-slash-bridge.ts +11 -4
  185. package/src/editor/context-menu.ts +804 -204
  186. package/src/editor/convert-to-component.ts +31 -10
  187. package/src/editor/convert-to-repeater.ts +3 -2
  188. package/src/editor/inline-edit-apply.ts +5 -5
  189. package/src/editor/inline-edit.ts +86 -50
  190. package/src/editor/insert-zone-action.ts +1 -1
  191. package/src/editor/shortcuts.ts +1043 -329
  192. package/src/editor/slash-menu.ts +1 -0
  193. package/src/files/elements.ts +166 -0
  194. package/src/files/file-ops.ts +178 -31
  195. package/src/files/files.ts +898 -268
  196. package/src/files/fs-events.ts +21 -0
  197. package/src/files/media-meta.ts +203 -0
  198. package/src/files/media-paths.ts +141 -0
  199. package/src/files/media-upload.ts +7 -3
  200. package/src/files/media-usage.ts +189 -0
  201. package/src/github/github-auth.ts +235 -33
  202. package/src/github/github-publish.ts +80 -21
  203. package/src/grid/grid-controller.ts +152 -12
  204. package/src/grid/grid-layout.ts +225 -20
  205. package/src/grid/grid-open.ts +120 -0
  206. package/src/grid/grid-panel.ts +554 -39
  207. package/src/grid/grid-source.ts +27 -1
  208. package/src/grid/redirects-grid.ts +599 -0
  209. package/src/grid/redirects.ts +398 -0
  210. package/src/grid/sources/content-source.ts +108 -2
  211. package/src/i18n/i18n-commands.ts +322 -0
  212. package/src/new-project/add-repo-modal.ts +8 -10
  213. package/src/new-project/import-tab.ts +7 -0
  214. package/src/new-project/location-fields.ts +9 -1
  215. package/src/new-project/new-project-modal.ts +221 -245
  216. package/src/packages/jxsuite-update.ts +97 -48
  217. package/src/packages/pull-package-sync.ts +18 -9
  218. package/src/page-params.ts +2 -1
  219. package/src/panels/activity-bar.ts +152 -91
  220. package/src/panels/activity-panel.ts +481 -0
  221. package/src/panels/ai-chat/chat-markdown.ts +8 -3
  222. package/src/panels/ai-chat/chat-view.ts +245 -18
  223. package/src/panels/ai-chat/composer.ts +31 -5
  224. package/src/panels/ai-chat/sessions-view.ts +17 -10
  225. package/src/panels/ai-panel.ts +279 -53
  226. package/src/panels/block-action-bar.ts +1115 -224
  227. package/src/panels/bottom-dock.ts +337 -0
  228. package/src/panels/canvas-dnd-bridge.ts +37 -8
  229. package/src/panels/chat-panel.ts +29 -12
  230. package/src/panels/data-explorer.ts +254 -112
  231. package/src/panels/data-grid.ts +10 -4
  232. package/src/panels/dnd.ts +28 -51
  233. package/src/panels/editors.ts +434 -107
  234. package/src/panels/elements-panel.ts +66 -2
  235. package/src/panels/empty-state.ts +112 -0
  236. package/src/panels/events-panel.ts +596 -82
  237. package/src/panels/formula-workspace.ts +408 -218
  238. package/src/panels/frontmatter-fields.ts +51 -10
  239. package/src/panels/frontmatter-panel.ts +357 -79
  240. package/src/panels/git-panel.ts +375 -164
  241. package/src/panels/head-panel.ts +791 -85
  242. package/src/panels/i18n-panel.ts +592 -0
  243. package/src/panels/imports-panel.ts +95 -85
  244. package/src/panels/jump-bar.ts +584 -0
  245. package/src/panels/layers-panel.ts +1106 -328
  246. package/src/panels/left-panel.ts +109 -204
  247. package/src/panels/navigator-panels.ts +131 -0
  248. package/src/panels/overlays.ts +7 -2
  249. package/src/panels/pane-context.ts +1477 -0
  250. package/src/panels/pane-grid.ts +406 -0
  251. package/src/panels/panel-registry.ts +340 -0
  252. package/src/panels/panel-scheduler.ts +75 -0
  253. package/src/panels/problems-panel.ts +234 -0
  254. package/src/panels/properties-panel.ts +946 -1139
  255. package/src/panels/provenance.ts +258 -0
  256. package/src/panels/quick-search.ts +791 -122
  257. package/src/panels/right-panel.ts +228 -102
  258. package/src/panels/seo-modal.ts +395 -0
  259. package/src/panels/settings-pane.ts +203 -0
  260. package/src/panels/signals-panel.ts +354 -137
  261. package/src/panels/statement-editor.ts +41 -25
  262. package/src/panels/statusbar.ts +342 -106
  263. package/src/panels/style-panel.ts +974 -463
  264. package/src/panels/style-utils.ts +3 -3
  265. package/src/panels/stylebook-doc.ts +4 -2
  266. package/src/panels/stylebook-layers-panel.ts +3 -2
  267. package/src/panels/stylebook-panel.ts +51 -26
  268. package/src/panels/tab-strip.ts +1058 -78
  269. package/src/panels/target-line.ts +274 -0
  270. package/src/panels/toolbar.ts +631 -484
  271. package/src/panels/welcome-screen.ts +301 -198
  272. package/src/platform-errors.ts +26 -3
  273. package/src/platform.ts +96 -2
  274. package/src/platforms/cloud.ts +71 -8
  275. package/src/platforms/devserver.ts +92 -29
  276. package/src/publish/deploy-checklist.ts +383 -0
  277. package/src/publish/pages-service.ts +10 -1
  278. package/src/publish/publish-commands.ts +218 -0
  279. package/src/publish/publish-panel.ts +110 -16
  280. package/src/recent-projects.ts +3 -2
  281. package/src/services/a11y-report.ts +505 -0
  282. package/src/services/ai-models.ts +30 -1
  283. package/src/services/ai-project-tools.ts +29 -10
  284. package/src/services/ai-system-prompt.ts +53 -14
  285. package/src/services/ai-tools.ts +39 -3
  286. package/src/services/ai-writes.ts +154 -0
  287. package/src/services/announce.ts +97 -0
  288. package/src/services/automation.ts +424 -175
  289. package/src/services/cem-export.ts +9 -4
  290. package/src/services/clock.ts +61 -0
  291. package/src/services/document-assistant.ts +36 -8
  292. package/src/services/idle.ts +179 -0
  293. package/src/services/import-client.ts +26 -0
  294. package/src/services/monaco-buffer.ts +627 -0
  295. package/src/services/monaco-lazy.ts +36 -0
  296. package/src/services/notify.ts +271 -0
  297. package/src/services/profile.ts +155 -0
  298. package/src/services/references.ts +0 -0
  299. package/src/services/token-lint.ts +3 -2
  300. package/src/services/tool-executor.ts +53 -7
  301. package/src/services/trusted-types.ts +123 -0
  302. package/src/settings/contexts-section.ts +427 -0
  303. package/src/settings/contributed-section.ts +149 -11
  304. package/src/settings/css-vars-editor.ts +306 -349
  305. package/src/settings/defs-editor.ts +93 -34
  306. package/src/settings/dependencies-editor.ts +7 -7
  307. package/src/settings/extension-sections.ts +37 -5
  308. package/src/settings/general-settings.ts +204 -121
  309. package/src/settings/locales-section.ts +347 -0
  310. package/src/settings/preferences-accounts.ts +140 -0
  311. package/src/settings/preferences-dialog.ts +620 -0
  312. package/src/settings/preferences-keymap.ts +270 -0
  313. package/src/settings/project-sections.ts +260 -0
  314. package/src/settings/section-registry.ts +169 -0
  315. package/src/settings/settings-document.ts +385 -0
  316. package/src/shell.ts +1549 -0
  317. package/src/site-context.ts +45 -20
  318. package/src/state.ts +14 -275
  319. package/src/store.ts +88 -43
  320. package/src/studio.ts +790 -346
  321. package/src/style/live-preview.ts +36 -0
  322. package/src/style/project-styles.ts +349 -0
  323. package/src/style/token-ref.ts +123 -0
  324. package/src/tabs/patch-ops.ts +16 -4
  325. package/src/tabs/project-config.ts +416 -0
  326. package/src/tabs/selection.ts +323 -0
  327. package/src/tabs/tab.ts +182 -47
  328. package/src/tabs/transact.ts +209 -28
  329. package/src/types.ts +68 -13
  330. package/src/ui/ai-credentials-form.ts +39 -35
  331. package/src/ui/ai-managed-connect.ts +7 -1
  332. package/src/ui/dynamic-slot.ts +224 -81
  333. package/src/ui/expression-editor.ts +71 -63
  334. package/src/ui/field-input.ts +4 -6
  335. package/src/ui/field-row.ts +215 -38
  336. package/src/ui/form-controls.ts +194 -7
  337. package/src/ui/layers.ts +492 -69
  338. package/src/ui/media-picker.ts +115 -25
  339. package/src/ui/panel-resize.ts +109 -91
  340. package/src/ui/progress-modal.ts +131 -50
  341. package/src/ui/regions.ts +462 -0
  342. package/src/ui/schema-form.ts +229 -45
  343. package/src/ui/spectrum.ts +24 -8
  344. package/src/ui/timing.ts +49 -0
  345. package/src/ui/value-selector.ts +20 -0
  346. package/src/ui/value-source.ts +348 -0
  347. package/src/ui/virtual-window.ts +400 -0
  348. package/src/utils/edit-display.ts +3 -2
  349. package/src/utils/inherited-style.ts +67 -37
  350. package/src/view.ts +64 -78
  351. package/src/workspace/pane-derive.ts +1258 -0
  352. package/src/workspace/session.ts +317 -0
  353. package/src/workspace/workspace.ts +1345 -23
  354. package/styles/canvas.css +653 -0
  355. package/styles/forced-colors.css +106 -0
  356. package/styles/inspector.css +1454 -0
  357. package/styles/overlays.css +2704 -0
  358. package/styles/panels.css +1701 -0
  359. package/styles/shell.css +1423 -0
  360. package/styles/tokens.css +151 -0
  361. package/dist/chunks/Overlay.dev-cszx7yn5.js +0 -22
  362. package/dist/chunks/extension-sections-qr3drkkw.js +0 -531
  363. package/dist/chunks/extension-sections-qr3drkkw.js.map +0 -12
  364. package/dist/chunks/files-j8a1t06k.js +0 -50
  365. package/dist/chunks/files-j8a1t06k.js.map +0 -9
  366. package/dist/chunks/git-panel-xtq5z81x.js +0 -28
  367. package/dist/chunks/git-panel-xtq5z81x.js.map +0 -9
  368. package/dist/chunks/layers-panel-ancn2wpq.js +0 -26
  369. package/dist/chunks/layers-panel-ancn2wpq.js.map +0 -9
  370. package/dist/chunks/settings-modal-17ttr96g.js +0 -29
  371. package/dist/chunks/settings-modal-17ttr96g.js.map +0 -9
  372. package/dist/chunks/sp-overlay.dev-earn5as8.js +0 -17
  373. package/dist/chunks/sp-overlay.dev-earn5as8.js.map +0 -9
  374. package/dist/chunks/sp-popover.dev-frxtfejn.js +0 -8
  375. package/dist/chunks/sp-popover.dev-frxtfejn.js.map +0 -9
  376. package/dist/chunks/sp-progress-circle.dev-7tvw34h8.js +0 -14
  377. package/dist/chunks/sp-progress-circle.dev-7tvw34h8.js.map +0 -9
  378. package/dist/chunks/sp-tooltip.dev-a9fywesm.js +0 -21
  379. package/dist/chunks/sp-tooltip.dev-a9fywesm.js.map +0 -10
  380. package/dist/chunks/studio-0xgs7xrs.js +0 -429
  381. package/dist/chunks/studio-0xgs7xrs.js.map +0 -13
  382. package/dist/chunks/studio-4d8hzcz5.js +0 -3427
  383. package/dist/chunks/studio-4d8hzcz5.js.map +0 -26
  384. package/dist/chunks/studio-4k0m4fmp.js.map +0 -13
  385. package/dist/chunks/studio-9smfzqhc.js +0 -19
  386. package/dist/chunks/studio-9smfzqhc.js.map +0 -10
  387. package/dist/chunks/studio-jm0z592w.js.map +0 -115
  388. package/dist/chunks/studio-m2t4mdg5.js +0 -1854
  389. package/dist/chunks/studio-m2t4mdg5.js.map +0 -18
  390. package/dist/chunks/studio-n4p11dfy.js +0 -853
  391. package/dist/chunks/studio-n4p11dfy.js.map +0 -12
  392. package/dist/chunks/studio-qkvt37c0.js.map +0 -9
  393. package/dist/chunks/studio-sjh1wt1a.js +0 -3744
  394. package/dist/chunks/studio-sjh1wt1a.js.map +0 -22
  395. package/dist/chunks/studio-v7jkjqng.js.map +0 -46
  396. package/dist/chunks/studio-xq0t7n5t.js +0 -140
  397. package/dist/chunks/studio-xq0t7n5t.js.map +0 -10
  398. package/dist/chunks/studio-xze4zrs1.js.map +0 -10
  399. package/dist/chunks/studio-yfcstdzy.js +0 -399
  400. package/dist/chunks/studio-yfcstdzy.js.map +0 -12
  401. package/dist/chunks/studio-zp7jncs8.js +0 -469
  402. package/dist/chunks/studio-zp7jncs8.js.map +0 -14
  403. package/dist/chunks/ws-client-q7hkz3j9.js.map +0 -11
  404. package/src/browse/browse-modal.ts +0 -69
  405. package/src/browse/browse.ts +0 -904
  406. package/src/canvas/canvas-diff.ts +0 -216
  407. package/src/canvas/nested-site-style.ts +0 -58
  408. package/src/new-project/design-fields.ts +0 -264
  409. package/src/new-project/templates.ts +0 -61
  410. package/src/panels/tab-bar.ts +0 -548
  411. package/src/settings/settings-modal.ts +0 -203
  412. /package/dist/chunks/{adapter-z8fkmbmv.js.map → adapter-qfnesn5v.js.map} +0 -0
  413. /package/dist/chunks/{cf-settings-mmyv436d.js.map → cf-settings-73sh5z4p.js.map} +0 -0
  414. /package/dist/chunks/{format-host-8jxwts2p.js.map → format-host-mkwsmt8d.js.map} +0 -0
  415. /package/dist/chunks/{jx-validate-qx8degj7.js.map → jx-validate-v6qgknrs.js.map} +0 -0
  416. /package/dist/chunks/{studio-w7c6kvk7.js.map → studio-a7pzveq1.js.map} +0 -0
  417. /package/dist/chunks/{studio-esrewxap.js.map → studio-s519zc99.js.map} +0 -0
  418. /package/dist/chunks/{studio-bghqfmea.js.map → studio-wwseqyw0.js.map} +0 -0
  419. /package/dist/chunks/{studio-nqw433kv.js.map → studio-xmvbhg31.js.map} +0 -0
@@ -0,0 +1,337 @@
1
+ /// <reference lib="dom" />
2
+ /**
3
+ * ⑪ The Bottom dock — where long operations and lists of things-to-fix live (plan §3.2 ⑪).
4
+ *
5
+ * Studio had no bottom dock and at least five surfaces wanted one, so each of them took over the
6
+ * canvas: Code mode, the git diff, the formula workspace and the Monaco function editor all replace
7
+ * the stage, and the progress modal covers the whole app. The canvas is the one region §3 says must
8
+ * never disappear, so this is where those surfaces go instead.
9
+ *
10
+ * **Under the pane grid, not under the window.** The dock occupies the pane's grid column only, so
11
+ * opening it never narrows the Navigator or the Inspector — which is the difference between a dock
12
+ * that is cheap to open and one that rearranges your whole workspace to show you two warnings.
13
+ *
14
+ * **Three tabs, under a cap of four.** `scripts/check-chrome-budget.ts` caps a dock at four, and
15
+ * this spends three: **Problems · Logic · Activity**, with Deploy folded into Activity because a
16
+ * deploy is a long operation with a log. Diff was the fourth until P8 gave it a pane to open into
17
+ * instead — see {@link registerBottomPanels}. `shell.ts` declares the ids ({@link BOTTOM_TAB_IDS})
18
+ * so a bare Bun process can read `view.setBottomTab`'s enum; this module turns them into records.
19
+ *
20
+ * **The tabs are panel records, so they inherit everything.** `dock: "bottom"` was already admitted
21
+ * by `registerPanel()` and by the level × placement matrix, and `ui/regions.ts` has parsed
22
+ * `dock.bottom` since P3 — it simply resolved to nothing, because there was no host. This is the
23
+ * host. Every tab gets `dock.bottom/panel:<id>` for free and its title comes from the record.
24
+ *
25
+ * **Logic is built, and it is why this dock exists.** P8.5 moves the formula workspace and the
26
+ * Monaco function editor out of their canvas takeovers and into this tab, so the page whose values
27
+ * they compute stays on screen beside them. Its record is defined beside the surface
28
+ * (`panels/formula-workspace.ts`) and registered from here, like Problems and Activity. Because a
29
+ * takeover reveals itself by definition and a dock tab does not, {@link mountBottomDock} watches
30
+ * for a Logic target appearing and opens the dock on it — once per target, so closing the dock over
31
+ * an open formula keeps it closed until you open another.
32
+ *
33
+ * **Problems is one of them.** §7.2's table places it here ("Problems | Bottom dock ⑪, badge on the
34
+ * rail") and this dock is its only host. It keeps a rail button and a badge — the rail groups by
35
+ * LEVEL, not by dock — and that button reveals it HERE, which is what `panels/activity-bar.ts`
36
+ * branches on. Its record is defined beside the notification store it renders
37
+ * (`panels/problems-panel.ts`) and registered from here, like every other tab of this dock.
38
+ */
39
+
40
+ import { html, render as litRender, nothing } from "lit-html";
41
+ import { effect, effectScope } from "../reactivity";
42
+ import {
43
+ BOTTOM_TAB_IDS,
44
+ DEFAULT_BOTTOM_TAB,
45
+ isBottomTabId,
46
+ registerShellSurface,
47
+ setBottomTab,
48
+ setDockCollapsed,
49
+ shell,
50
+ } from "../shell";
51
+ import { bottomPanelRegion, REGION_ATTR } from "../ui/regions";
52
+ import { getPanel, isPanelVisible, listPanels, panelContext } from "./panel-registry";
53
+ import { registerActivityPanel } from "./activity-panel";
54
+ import { registerProblemsPanel } from "./problems-panel";
55
+ import { logicTarget, registerLogicPanel, revealLogicPanel } from "./formula-workspace";
56
+ import { renderEmptyState } from "./empty-state";
57
+ import type { CommandContext } from "../commands/context";
58
+ import type { NavigatorPanelContext, NavigatorPanelDeps, PanelRecord } from "./panel-registry";
59
+ import type { EffectScope } from "@vue/reactivity";
60
+ import type { TemplateResult } from "lit-html";
61
+
62
+ /** The dock's host — a bare `<div id>` in index.html, like every other shell host. */
63
+ export const BOTTOM_DOCK_SELECTOR = "#bottom-dock";
64
+
65
+ // No `NOT_YET_BUILT` placeholder here. The Navigator keeps one (`panels/navigator-panels.ts`, for
66
+ // Search) because Search exists nowhere else and a reserved rail slot is an honest promise. This
67
+ // Dock's reservation was for Diff, and Diff shipped somewhere better — see `registerBottomPanels`.
68
+
69
+ /**
70
+ * Register the Bottom dock's three panels. Idempotent — a second call is a no-op.
71
+ *
72
+ * Problems first, because it is the tab the dock opens itself for.
73
+ *
74
+ * **Diff is not among them, and its reserved id is gone.** It was held here through P4–P7 with a
75
+ * `when: () => false`, and the comment that held it said why it should not be here: `git-diff` is
76
+ * the `diff` EDITOR KIND (`commands/context.ts`), a pane hosts it at pane size, and folding it into
77
+ * a 240px dock would be a downgrade. What it owed was a pane to open into — and P8 shipped that
78
+ * (`pane.splitRight`, `canOpenInSecondPane`), so Source Control opens a changed file as a Diff
79
+ * editor in the side pane. A reservation whose capability shipped elsewhere is not a reservation;
80
+ * it is an id in `view.setBottomTab`'s enum that can only ever select a hidden tab. The dock spends
81
+ * three of its four budgeted slots and the fourth is genuinely free.
82
+ */
83
+ export function registerBottomPanels(): void {
84
+ if (listPanels("bottom").length > 0) {
85
+ return;
86
+ }
87
+ registerProblemsPanel();
88
+ registerLogicPanel();
89
+ registerActivityPanel();
90
+ }
91
+
92
+ /**
93
+ * The dock's tabs, in strip order.
94
+ *
95
+ * Ordered by {@link BOTTOM_TAB_IDS} rather than by registration order, because the strip's order is
96
+ * a design decision (§3.2 ⑪ names it) and `shell.ts` is where a bare Bun process can read it. An id
97
+ * with no record is skipped rather than throwing: the list is also the `args` enum, and a command
98
+ * enum naming a surface that has not registered yet must be inert, not fatal.
99
+ */
100
+ export function bottomPanelSet(): PanelRecord[] {
101
+ registerBottomPanels();
102
+ const records: PanelRecord[] = [];
103
+ for (const id of BOTTOM_TAB_IDS) {
104
+ const panel = getPanel(id);
105
+ if (panel) {
106
+ records.push(panel);
107
+ }
108
+ }
109
+ return records;
110
+ }
111
+
112
+ /** The tabs a given context admits — `when`-filtered, exactly as the rail is. */
113
+ export function visibleBottomPanels(ctx: CommandContext = panelContext()): PanelRecord[] {
114
+ return bottomPanelSet().filter((panel) => isPanelVisible(panel, ctx));
115
+ }
116
+
117
+ /**
118
+ * The tab to draw as selected: the stored one when it is visible, else the first that is.
119
+ *
120
+ * `null` when the dock has no visible tab at all, which is a real state (every tab gated off) and
121
+ * renders as an empty state rather than as a blank box.
122
+ */
123
+ export function activeBottomPanel(ctx: CommandContext = panelContext()): PanelRecord | null {
124
+ const visible = visibleBottomPanels(ctx);
125
+ const stored = isBottomTabId(shell.bottomTab) ? shell.bottomTab : DEFAULT_BOTTOM_TAB;
126
+ return visible.find((panel) => panel.id === stored) ?? visible[0] ?? null;
127
+ }
128
+
129
+ /**
130
+ * The context a Bottom dock panel's `render` is called with.
131
+ *
132
+ * `doc` is `null` and `deps` is empty, and neither is an oversight. `deps` are the NAVIGATOR's own
133
+ * injections — the file-tree renderer, the drag registrations, the canvas hooks — and a Bottom dock
134
+ * tab that needed one would be reaching across docks for a surface it does not host.
135
+ *
136
+ * `doc` is null because this dock has no no-document empty state to drive: Problems and Activity
137
+ * are project-level lists, and Logic is document-level but addresses a document POSITION rather
138
+ * than the focused document — it reads `activeTab` itself, and its `when` is what takes it off the
139
+ * strip when there is nothing open in it.
140
+ */
141
+ function bottomContext(): NavigatorPanelContext {
142
+ return {
143
+ deps: {} as NavigatorPanelDeps,
144
+ doc: null,
145
+ rerender: renderBottomDock,
146
+ };
147
+ }
148
+
149
+ /** One tab's label — the record's title, with its badge appended as §3.1 draws it ("Problems 2"). */
150
+ export function bottomTabLabel(panel: PanelRecord, ctx: CommandContext): string {
151
+ const badge = panel.badge?.(ctx) ?? null;
152
+ return badge === null || badge === 0 || badge === "" ? panel.title : `${panel.title} ${badge}`;
153
+ }
154
+
155
+ /** The dock, as a template. Exported so a test can render it without a host. */
156
+ export function bottomDockTemplate(ctx: CommandContext = panelContext()): TemplateResult {
157
+ const panels = visibleBottomPanels(ctx);
158
+ const active = activeBottomPanel(ctx);
159
+ const body = active
160
+ ? active.render(bottomContext())
161
+ : renderEmptyState({ message: "Nothing to show here yet." });
162
+ return html`
163
+ <div class="bd-strip">
164
+ <sp-tabs
165
+ class="bd-tabs"
166
+ quiet
167
+ size="s"
168
+ selected=${active?.id ?? ""}
169
+ @change=${(e: Event & { target: { selected: string } }) => {
170
+ const { selected } = e.target;
171
+ if (selected && selected !== active?.id) {
172
+ setBottomTab(selected);
173
+ }
174
+ }}
175
+ >
176
+ ${panels.map(
177
+ (panel) => html`<sp-tab value=${panel.id} label=${bottomTabLabel(panel, ctx)}></sp-tab>`,
178
+ )}
179
+ </sp-tabs>
180
+ <button
181
+ class="bd-close"
182
+ title="Close the Bottom dock"
183
+ aria-label="Close the Bottom dock"
184
+ @click=${() => {
185
+ setDockCollapsed("bottom", true);
186
+ }}
187
+ >
188
+ <span aria-hidden="true">×</span>
189
+ </button>
190
+ </div>
191
+ ${
192
+ active
193
+ ? html`<div class="bd-body" data-jx-region=${bottomPanelRegion(active.id)}>${body}</div>`
194
+ : html`<div class="bd-body">${body}</div>`
195
+ }
196
+ `;
197
+ }
198
+
199
+ let _scope: EffectScope | null = null;
200
+
201
+ let _host: HTMLElement | null = null;
202
+
203
+ /**
204
+ * The Logic target the dock has already revealed itself for.
205
+ *
206
+ * This effect answers ONE of the two events that put Logic on screen: **a target appeared** — a tab
207
+ * switch, a restored session, anything that changes what Logic would show without anyone asking to
208
+ * see it. It fires when the target appears or changes and never again, because collapsing the dock
209
+ * over an open formula must leave it closed (§16.3) and a dock you cannot shut is worse than the
210
+ * takeover it replaced.
211
+ *
212
+ * The other event is **the user asked for this surface**, and it cannot be derived from this one: a
213
+ * second click on the same button changes no target at all, so a key comparison sees nothing to do
214
+ * and the collapsed dock stayed shut under a button that looked broken. That event belongs to the
215
+ * gesture, and `formula-workspace.ts`'s `openLogicTarget` is where every opener says it.
216
+ */
217
+ let _revealedLogicKey: string | null = null;
218
+
219
+ /** A stable identity for the open formula/function, or `null` when the Logic tab has no target. */
220
+ function logicKey(): string | null {
221
+ const target = logicTarget();
222
+ return target ? `${target.surface} ${JSON.stringify(target.editing)}` : null;
223
+ }
224
+
225
+ /**
226
+ * Paint the dock, and stamp the region iff it is on screen.
227
+ *
228
+ * The stamp is conditional on purpose. `REGION_FOR_FOCUS.dock` has pointed at `dock.bottom` since
229
+ * P3, so F6 and `regions.resolve()` will find whatever carries it — and a COLLAPSED dock is a
230
+ * `display: none` box that focus must not land in and a shot must not crop. A closed dock therefore
231
+ * resolves to nothing, and `view.setBottomDock { open: true }` is what makes it addressable, which
232
+ * is exactly what an idempotent setter is for.
233
+ */
234
+ export function renderBottomDock(): void {
235
+ if (!_host) {
236
+ return;
237
+ }
238
+ if (shell.docks.bottom.collapsed) {
239
+ _host.removeAttribute(REGION_ATTR);
240
+ litRender(nothing, _host);
241
+ runAfterRender(_host);
242
+ return;
243
+ }
244
+ _host.setAttribute(REGION_ATTR, "dock.bottom");
245
+ litRender(bottomDockTemplate(), _host);
246
+ runAfterRender(_host.querySelector<HTMLElement>(".bd-body") ?? _host);
247
+ }
248
+
249
+ /**
250
+ * Run every tab's `afterRender` against whatever was just painted — showing or not.
251
+ *
252
+ * `panels/left-panel.ts` runs the hook for the ACTIVE panel only, and can: no Navigator panel owns
253
+ * anything that outlives its own markup. Logic does — a live Monaco instance — and the three ways
254
+ * to stop showing it (select another tab, collapse the dock, close the target) all leave that
255
+ * instance attached to DOM lit has already thrown away. Handing every tab the painted element turns
256
+ * "am I still on screen?" into a question each surface can answer for itself, which is what
257
+ * `syncFunctionEditor` does with it, and keeps the dock from having to know that Logic is special.
258
+ *
259
+ * @param {HTMLElement} painted The dock body, or the host itself when the dock is collapsed.
260
+ */
261
+ function runAfterRender(painted: HTMLElement): void {
262
+ const ctx = bottomContext();
263
+ for (const panel of bottomPanelSet()) {
264
+ panel.afterRender?.(ctx, painted);
265
+ }
266
+ }
267
+
268
+ /**
269
+ * Mount the Bottom dock. Idempotent, and inert when its host is absent.
270
+ *
271
+ * Called by `shell.ts`'s `mountShell()`, beside the effect that projects the dock record onto the
272
+ * grid: the dock's visibility and its size are shell state, and mounting it anywhere else would be
273
+ * a second place the shell's layout is decided.
274
+ */
275
+ export function mountBottomDock(): void {
276
+ if (_scope) {
277
+ return;
278
+ }
279
+ _host = document.querySelector<HTMLElement>(BOTTOM_DOCK_SELECTOR);
280
+ if (!_host) {
281
+ return;
282
+ }
283
+ _scope = effectScope();
284
+ _scope.run(() => {
285
+ // Reveal BEFORE the render effect, and in an effect of its own: it reads the Logic target and
286
+ // Writes `shell.bottomTab`, which the render effect reads — one effect doing both would
287
+ // Re-enter itself on every reveal.
288
+ effect(() => {
289
+ const key = logicKey();
290
+ if (key !== null && key !== _revealedLogicKey) {
291
+ revealLogicPanel();
292
+ }
293
+ _revealedLogicKey = key;
294
+ });
295
+ effect(() => {
296
+ // Tracked: whether the dock is open, which tab it shows, and the two reactive stores its
297
+ // Tabs render — so a problem raised or an operation started repaints the strip's badge
298
+ // Without this module knowing which panel produced it.
299
+ void shell.docks.bottom.collapsed;
300
+ void shell.bottomTab;
301
+ renderBottomDock();
302
+ });
303
+ });
304
+ }
305
+
306
+ /**
307
+ * Attach to the shell's lifecycle.
308
+ *
309
+ * The dependency points this way — the dock knows about the shell, and the shell knows only that
310
+ * something wants mounting — because the reverse is a cycle, and because it puts the knowledge
311
+ * "this surface is a dock" in the module that IS the dock.
312
+ */
313
+ registerShellSurface({ mount: mountBottomDock, unmount: unmountBottomDock });
314
+
315
+ /**
316
+ * Release the effect and clear the host. Tests and a window teardown both need this.
317
+ *
318
+ * The `runAfterRender` is not symmetry for its own sake. Blanking the host is the fourth way the
319
+ * Logic tab stops being on screen, and it is the one nothing else covers: `renderBottomDock`'s
320
+ * collapsed branch runs the hook, a tab switch runs it, closing the target runs it — this path used
321
+ * to `litRender(nothing)` and stop, leaving a live Monaco instance (a text model, its change
322
+ * listeners and an `automaticLayout` ResizeObserver) parked on `view.functionEditor` and attached
323
+ * to DOM that no longer exists. The canvas-side dispose that used to mop it up went away with the
324
+ * takeover; handing the emptied host to every tab is what replaces it, and it keeps the dock from
325
+ * having to know that Logic is the special one.
326
+ */
327
+ export function unmountBottomDock(): void {
328
+ _scope?.stop();
329
+ _scope = null;
330
+ _revealedLogicKey = null;
331
+ if (_host) {
332
+ _host.removeAttribute(REGION_ATTR);
333
+ litRender(nothing, _host);
334
+ runAfterRender(_host);
335
+ _host = null;
336
+ }
337
+ }
@@ -25,10 +25,12 @@
25
25
  */
26
26
 
27
27
  import { monitorForElements } from "@atlaskit/pragmatic-drag-and-drop/element/adapter";
28
+ import { displayTagName } from "@jxsuite/schema/guards";
28
29
  import {
29
30
  beginDragSession,
30
31
  clearDropIndicator,
31
32
  currentDragSession,
33
+ dragHostTab,
32
34
  endDragSession,
33
35
  hostDragGeometry,
34
36
  liveDragHostAt,
@@ -41,6 +43,7 @@ import { clearDragGhost, moveDragGhost, setDragGhost } from "./drag-ghost";
41
43
  import { getNodeAtPath } from "../store";
42
44
  import { activeTab } from "../workspace/workspace";
43
45
  import type { DragHost } from "../canvas/iframe-host";
46
+ import type { Tab } from "../tabs/tab";
44
47
  import type { DragSrcKind, ParentToIframe } from "../canvas/iframe-protocol";
45
48
  import type { JxMutableNode } from "@jxsuite/schema/types";
46
49
 
@@ -106,17 +109,32 @@ function dragSrcOf(data: Record<string, unknown>): DragSrcKind | null {
106
109
 
107
110
  /**
108
111
  * The ghost label for a drag (Phase 4c). A block source uses its fragment's tag (the card label); a
109
- * tree-node source uses the tag of the node at its path in the live doc (a node chip). Falls back
110
- * to a generic label when the tag is unknown.
112
+ * tree-node source uses the tag of the node at its path in `tab`'s document (a node chip). Falls
113
+ * back to a generic label when the tag is unknown.
114
+ *
115
+ * **`tab` is a parameter because the path is only meaningful in one document.** It read `activeTab`
116
+ * and the ghost is raised over the pane the drag is IN, so dragging the side pane's ⠿ handle
117
+ * resolved the source path against the focused pane's document and chipped the label with whatever
118
+ * tag happened to sit at that index there — `<section>` for an `<img>`, `node` when the path did
119
+ * not exist. Cosmetic, and visible for the whole length of every drag.
120
+ *
121
+ * @param {Tab | null} tab The document the source path is addressed in.
122
+ * @param {DragSrcKind} src
123
+ * @param {Record<string, unknown>} data
124
+ * @returns {string}
111
125
  */
112
- export function ghostLabel(src: DragSrcKind, data: Record<string, unknown>): string {
126
+ export function ghostLabel(
127
+ tab: Tab | null,
128
+ src: DragSrcKind,
129
+ data: Record<string, unknown>,
130
+ ): string {
113
131
  if (src.type === "block") {
114
132
  const fragment = data.fragment as JxMutableNode | undefined;
115
- return fragment?.tagName ?? "block";
133
+ return displayTagName(fragment?.tagName) || "block";
116
134
  }
117
- const doc = activeTab.value?.doc.document as JxMutableNode | undefined;
135
+ const doc = tab?.doc.document as JxMutableNode | undefined;
118
136
  const node = doc ? (getNodeAtPath(doc, src.path) as JxMutableNode | undefined) : undefined;
119
- return node?.tagName ?? "node";
137
+ return displayTagName(node?.tagName) || "node";
120
138
  }
121
139
 
122
140
  /**
@@ -148,7 +166,9 @@ function startSession(
148
166
  srcData: Record<string, unknown>,
149
167
  ): CoordSession {
150
168
  const seq = beginDragSession(host, src, srcData);
151
- return { host, label: ghostLabel(src, srcData), seq, src, srcData };
169
+ // The label names a node in the TARGET pane's document — `host` is the artboard the cursor is
170
+ // Over, and its tab is the only document the source path indexes into meaningfully.
171
+ return { host, label: ghostLabel(dragHostTab(host), src, srcData), seq, src, srcData };
152
172
  }
153
173
 
154
174
  /**
@@ -316,7 +336,16 @@ export function registerCanvasDndBridge(): () => void {
316
336
  // Bind the session to the host under the cursor (if any). The ghost shows immediately and
317
337
  // Follows the pointer even before it enters a canvas (lazy bind happens in onDrag otherwise).
318
338
  session = host ? startSession(host, src, source.data) : null;
319
- setDragGhost(ghostLabel(src, source.data), cursor.x, cursor.y);
339
+ /* Reuse the bound session's label rather than recomputing it — `startSession` already
340
+ resolved it against the target pane's document, and recomputing here is what used to
341
+ resolve it against the focused one instead. With no host under the cursor the drag began
342
+ outside every artboard, and the focused document is then the right answer: that is where
343
+ the Navigator layer row the drag started from is showing. */
344
+ setDragGhost(
345
+ session ? session.label : ghostLabel(activeTab.value, src, source.data),
346
+ cursor.x,
347
+ cursor.y,
348
+ );
320
349
  },
321
350
  onDrop({ source, location }: MonitorDragArgs) {
322
351
  const src = dragSrcOf(source.data);
@@ -1,6 +1,16 @@
1
1
  /// <reference lib="dom" />
2
2
  /**
3
- * Chat-panel.ts — the persistent AI chat sidebar (`#chat-panel` shell region).
3
+ * Chat-panel.ts — the assistant, as the Inspector dock's fourth tab.
4
+ *
5
+ * **It is not a column and it is not a dock.** `#chat-panel` was a fifth permanent grid column
6
+ * ~300px wide; then it was a node sharing the Inspector's cell; it is now the body of one tab
7
+ * beside Content, Style and Logic. Nothing about the chat UI changed for any of those moves, which
8
+ * is what {@link mount} taking a host rather than finding one has bought: `right-panel.ts` builds
9
+ * the four tab containers and hands this module the fourth.
10
+ *
11
+ * The `inspector.assistant` region is stamped HERE, on the container this module owns, rather than
12
+ * in `ui/regions.ts`'s shell table — the assistant no longer has a shell host to name. Three
13
+ * screenshot shots address that id and none of them changed.
4
14
  *
5
15
  * Hosts the assistant UI from ai-panel.ts unconditionally: with no project (welcome screen), with a
6
16
  * project but no open document, and with a document open. The panel is mounted once at studio boot
@@ -17,27 +27,31 @@
17
27
 
18
28
  import { render as litRender } from "lit-html";
19
29
  import { effect, effectScope } from "../reactivity";
20
- import { applyPanelCollapse, view } from "../view";
21
30
  import { workspace } from "../workspace/workspace";
22
31
  import { consumePendingAgentPrompt, hasPendingAgentPrompt } from "../services/agent-seed";
32
+ import { REGION_ATTR } from "../ui/regions";
23
33
  import {
24
34
  bindAiPanelHost,
25
35
  mountAiPanel,
26
36
  renderAiPanelTemplate,
37
+ revealAssistant,
27
38
  seedAssistantPrompt,
28
39
  } from "./ai-panel";
29
40
 
30
41
  import type { EffectScope } from "@vue/reactivity";
31
42
 
43
+ /** The region id every assistant screenshot crops to. Stamped on the container, not on a div. */
44
+ const ASSISTANT_REGION = "inspector.assistant";
45
+
32
46
  let _host: HTMLElement | null = null;
33
47
  let _container: HTMLElement | null = null;
34
48
  let _scope: EffectScope | null = null;
35
49
 
36
50
  /**
37
- * Mount the chat sidebar into its shell region. Idempotent per host: the persistent `.panel-body`
38
- * container is created once and bound as the ai-panel render host (lit needs a single render target
39
- * for its part cache). A missing host (shell without a #chat-panel region, e.g. reduced test
40
- * fixtures) is a no-op.
51
+ * Mount the assistant into the host the Inspector hands it. Idempotent per host: the persistent
52
+ * `.ai-panel-host` container is created once and bound as the ai-panel render host (lit needs a
53
+ * single render target for its part cache). A missing host (a reduced test fixture with no
54
+ * inspector) is a no-op.
41
55
  *
42
56
  * @param {HTMLElement | null} host
43
57
  */
@@ -47,7 +61,8 @@ export function mount(host: HTMLElement | null) {
47
61
  }
48
62
  _host = host;
49
63
  _container = document.createElement("div");
50
- _container.className = "panel-body";
64
+ _container.className = "ai-panel-host";
65
+ _container.setAttribute(REGION_ATTR, ASSISTANT_REGION);
51
66
  host.textContent = "";
52
67
  host.append(_container);
53
68
 
@@ -67,14 +82,16 @@ export function mount(host: HTMLElement | null) {
67
82
  if (!root || !hasPendingAgentPrompt(root)) {
68
83
  return;
69
84
  }
70
- if (view.chatPanelCollapsed) {
71
- view.chatPanelCollapsed = false;
72
- applyPanelCollapse();
73
- }
85
+ // Reveal the assistant the way any other inspector tab is revealed: open the dock it lives
86
+ // In, then select it. There is no assistant dock left to open. Those two lines live in
87
+ // `ai-panel.ts` now, because the `Assistant:` command family needs the same pair.
88
+ revealAssistant();
74
89
  const prompt = consumePendingAgentPrompt(root);
75
90
  if (prompt) {
76
91
  // Defer past the current render so the assistant machinery is in place before the send.
77
- requestAnimationFrame(() => void seedAssistantPrompt(prompt));
92
+ requestAnimationFrame(() => {
93
+ void seedAssistantPrompt(prompt);
94
+ });
78
95
  }
79
96
  });
80
97
  });