@jxsuite/studio 2.0.0 → 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-0hzentwq.js → components-2bpqp4mq.js} +5 -7
  7. package/dist/chunks/{components-0hzentwq.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-2c188n41.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-97qcgvdn.js → studio-adn0z1k3.js} +14 -8
  74. package/dist/chunks/{studio-97qcgvdn.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-hhj92gcr.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-ygzav7z5.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-n9zmpxjg.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 +23711 -35185
  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 +34 -9
  214. package/src/new-project/location-fields.ts +9 -1
  215. package/src/new-project/new-project-modal.ts +270 -262
  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 -120
  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 +75 -2
  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 +113 -0
  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-qct0gt8f.js +0 -531
  363. package/dist/chunks/extension-sections-qct0gt8f.js.map +0 -12
  364. package/dist/chunks/files-02zn5y24.js +0 -50
  365. package/dist/chunks/files-02zn5y24.js.map +0 -9
  366. package/dist/chunks/git-panel-mbb0y0hz.js +0 -28
  367. package/dist/chunks/git-panel-mbb0y0hz.js.map +0 -9
  368. package/dist/chunks/layers-panel-9qekmqk1.js +0 -26
  369. package/dist/chunks/layers-panel-9qekmqk1.js.map +0 -9
  370. package/dist/chunks/settings-modal-gj0hrah4.js +0 -29
  371. package/dist/chunks/settings-modal-gj0hrah4.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-4k0m4fmp.js.map +0 -13
  381. package/dist/chunks/studio-568nx4t5.js +0 -469
  382. package/dist/chunks/studio-568nx4t5.js.map +0 -14
  383. package/dist/chunks/studio-9smfzqhc.js +0 -19
  384. package/dist/chunks/studio-9smfzqhc.js.map +0 -10
  385. package/dist/chunks/studio-asvf0j9e.js +0 -429
  386. package/dist/chunks/studio-asvf0j9e.js.map +0 -13
  387. package/dist/chunks/studio-d77qm3pk.js +0 -3427
  388. package/dist/chunks/studio-d77qm3pk.js.map +0 -26
  389. package/dist/chunks/studio-j6gqyjf4.js +0 -1854
  390. package/dist/chunks/studio-j6gqyjf4.js.map +0 -18
  391. package/dist/chunks/studio-n9zmpxjg.js.map +0 -115
  392. package/dist/chunks/studio-qkvt37c0.js.map +0 -9
  393. package/dist/chunks/studio-rq0vxb19.js +0 -3744
  394. package/dist/chunks/studio-rq0vxb19.js.map +0 -22
  395. package/dist/chunks/studio-wd6ewdvd.js +0 -853
  396. package/dist/chunks/studio-wd6ewdvd.js.map +0 -12
  397. package/dist/chunks/studio-xq0t7n5t.js +0 -140
  398. package/dist/chunks/studio-xq0t7n5t.js.map +0 -10
  399. package/dist/chunks/studio-xze4zrs1.js.map +0 -10
  400. package/dist/chunks/studio-ygzav7z5.js.map +0 -46
  401. package/dist/chunks/studio-zmy7241e.js +0 -399
  402. package/dist/chunks/studio-zmy7241e.js.map +0 -12
  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-2c188n41.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-hhj92gcr.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,61 @@
1
+ /**
2
+ * Clock — the one seam every _relative_ time in Studio reads "now" through.
3
+ *
4
+ * Four surfaces render a duration rather than an instant: the Source Control panel's commit ages
5
+ * and "last refreshed", the Start pane's "last opened", the chat session list's row times, and the
6
+ * recents list those two read from. Each of them called `Date.now()` inline, which had two costs:
7
+ *
8
+ * 1. **They were untestable.** A formatter that reads the wall clock can only be asserted against an
9
+ * offset from the real present, so "yesterday" and "over a year ago" were never covered.
10
+ * 2. **They drift.** Two captures of the same state minutes apart legitimately read `01:59 PM` and
11
+ * `02:04 PM` (UX-REDESIGN-PLAN §13.4 measured exactly that on the git-panel shot).
12
+ *
13
+ * This is deliberately NOT a global `Date.now` override. Monaco, every `setTimeout`, the collab
14
+ * clock and the transaction log all read the real clock and must keep reading it — pinning time for
15
+ * the whole realm hangs the editor. Four imports, four honest readers.
16
+ *
17
+ * `pinClock` is also what makes session restore's "last opened" honest: the value written is the
18
+ * value the formatter reads back.
19
+ */
20
+
21
+ /** Epoch milliseconds the clock is pinned to, or `null` while it follows the real clock. */
22
+ let _pinned: number | null = null;
23
+
24
+ /**
25
+ * The current time in epoch milliseconds — pinned when {@link pinClock} has been called, otherwise
26
+ * the wall clock.
27
+ *
28
+ * Frozen rather than offset while pinned: a shot, a test and a bug report all want the SAME answer
29
+ * on the tenth read as on the first, and a ticking pin reintroduces exactly the drift it exists to
30
+ * remove.
31
+ */
32
+ export function now(): number {
33
+ return _pinned ?? Date.now();
34
+ }
35
+
36
+ /**
37
+ * Pin the clock to a fixed instant. Accepts epoch milliseconds, a `Date`, or anything `Date` parses
38
+ * (the `2026-01-15T09:30:00Z` an `open.clock` field carries).
39
+ *
40
+ * @returns The pinned instant, in epoch milliseconds.
41
+ * @throws {TypeError} When the value cannot be read as a time — a silently-ignored pin would
42
+ * photograph the wall clock and the capture would be accepted.
43
+ */
44
+ export function pinClock(at: number | string | Date): number {
45
+ const ms = at instanceof Date ? at.getTime() : typeof at === "number" ? at : Date.parse(at);
46
+ if (!Number.isFinite(ms)) {
47
+ throw new TypeError(`clock: cannot pin to ${JSON.stringify(at)}`);
48
+ }
49
+ _pinned = ms;
50
+ return ms;
51
+ }
52
+
53
+ /** Release the pin; {@link now} follows the wall clock again. */
54
+ export function unpinClock(): void {
55
+ _pinned = null;
56
+ }
57
+
58
+ /** Whether the clock is currently pinned. Read by `probe.state()` and by the tests. */
59
+ export function isClockPinned(): boolean {
60
+ return _pinned !== null;
61
+ }
@@ -12,11 +12,13 @@
12
12
  import { createChatState, createProxyStreamingClient, createToolRegistry } from "@jxsuite/ai";
13
13
  import type { ProjectConfig } from "@jxsuite/schema/types";
14
14
  import { getPlatform } from "../platform";
15
- import { activeTab, setWorkspaceProject, workspace } from "../workspace/workspace";
15
+ import { activeTab, workspace } from "../workspace/workspace";
16
16
  import { toRaw } from "../reactivity";
17
- import { projectState, setProjectState } from "../store";
17
+ import { projectState } from "../store";
18
+ import { adoptProjectConfig } from "../tabs/project-config";
18
19
  import type { Tab } from "../tabs/tab";
19
20
  import { componentRegistry } from "../files/components";
21
+ import { activeRegistry } from "../commands/active-registry";
20
22
  import { registerAiTools } from "./ai-tools";
21
23
  import { registerProjectTools } from "./ai-project-tools";
22
24
  import { createGatedToolRegistry } from "./gated-registry";
@@ -104,11 +106,12 @@ export function createDocumentAssistant() {
104
106
  sessionStore.moveSession("", root, sessionId);
105
107
  }
106
108
  },
107
- onProjectConfigWritten: (config: ProjectConfig) => {
108
- setWorkspaceProject(workspace.projectRoot, config);
109
- if (projectState) {
110
- setProjectState({ ...projectState, projectConfig: config });
111
- }
109
+ onProjectConfigWritten: async (config: ProjectConfig) => {
110
+ /* Into the configuration document, not beside it. This used to assign a fresh object to
111
+ `projectState.projectConfig`, leaving the document holding the previous configuration —
112
+ and the next settings commit wrote that stale document back over the assistant's file.
113
+ `adoptProjectConfig` is the one door for a config that reached disk another way. */
114
+ await adoptProjectConfig(config);
112
115
  /* An `extensions` edit changes what the generated entry documents compose, and the backends
113
116
  regenerate them from project.json on demand — so without this the editor and the assistant
114
117
  both keep judging by the PREVIOUS project's schemas until the window reopens. */
@@ -125,12 +128,37 @@ export function createDocumentAssistant() {
125
128
  "no-project": "no project to be open (it bootstraps one)",
126
129
  project: "an open project",
127
130
  document: "an open document (use open_document first)",
131
+ "document-tree":
132
+ "an open document whose element tree the canvas is editing — Project Settings and the " +
133
+ "grid editors are documents, but not trees to restructure",
128
134
  } as const;
135
+
136
+ /**
137
+ * The HUMAN's own gate, read rather than reimplemented.
138
+ *
139
+ * `Command.aiTool` promises "the human's gate and the agent's gate stay one predicate", and the
140
+ * only way to keep that promise is for the agent to ask the same object: this is the
141
+ * `CommandContext` `selection.delete` and the movers are evaluated against. Recomputing
142
+ * `editor.kind` here would make two predicates that agree today and drift the first time either
143
+ * is edited. Falls back to permissive when no registry is installed — the assistant runs in tests
144
+ * that never build one, and refusing everything there would be a second wrong answer.
145
+ */
146
+ const treeEditable = () => {
147
+ const registry = activeRegistry();
148
+ // `=== "canvas"`, the human's exact test — not a looser cousin of it. Being more permissive for
149
+ // The agent than for the person is the divergence this is here to remove.
150
+ return registry ? registry.context().editor.kind === "canvas" : true;
151
+ };
129
152
  const availability = new Map<string, ToolAvailability>(
130
153
  AI_TOOL_TIERS.map((t) => [
131
154
  t.name,
132
155
  {
133
- when: () => tierActive(t.tier, Boolean(workspace.projectRoot), Boolean(activeTab.value)),
156
+ when: () =>
157
+ tierActive(t.tier, {
158
+ hasDocument: Boolean(activeTab.value),
159
+ hasProject: Boolean(workspace.projectRoot),
160
+ treeEditable: treeEditable(),
161
+ }),
134
162
  requires: TIER_REQUIREMENTS[t.tier],
135
163
  },
136
164
  ]),
@@ -0,0 +1,179 @@
1
+ /// <reference lib="dom" />
2
+ /**
3
+ * Idle.ts — "settled" is a predicate, and it can fail.
4
+ *
5
+ * One question — _has Studio finished reacting?_ — asked of the five subsystems that can still be
6
+ * mid-flight, over two consecutive animation frames (spec studio.md §13.5, plan §13.4).
7
+ *
8
+ * **The rejection is the point.** The thing this replaces is 115 `wait: {ms}` steps totalling 73
9
+ * seconds, and a sleep cannot fail: a subsystem that was slow that day got answered with `+500 ms`
10
+ * and the wrong state was photographed, committed and accepted. {@link NotIdleError} carries a
11
+ * `blockedBy` array naming every outstanding item — `["canvas[page-1]: gen 7 unacked", "platform: 1
12
+ * in-flight (gitStatus)"]` — so the slow subsystem identifies itself.
13
+ *
14
+ * Nothing here polls a subsystem it does not own. Each source is a function the owning module
15
+ * already had to write for its own reasons:
16
+ *
17
+ * 1. `store.rendersInFlight()` — renderers mid-paint.
18
+ * 2. `panel-scheduler.pendingSchedulers()` — panels with a frame queued or a render withheld.
19
+ * 3. `iframe-host.canvasIdleBlockers()` — per host: unacked generations and patches, plus the frame's
20
+ * own cross-realm report of fonts, running animations and pending image retries.
21
+ * 4. `platform.platformInFlight()` — unsettled PAL calls, counted at the one seam every adapter and
22
+ * all thirty-odd `git*`/fs/fetch methods pass through.
23
+ * 5. `layers.overlayIdleBlockers()` — overlays still in transition. Only the SETTLING window counts: a
24
+ * resting toast is not a blocker, which is what lets `toastsAreHeld()` hold one open for a
25
+ * capture without `probeIdle()` waiting forever alongside it (plan §13.7's named exception).
26
+ * 6. `activity-panel.activityIdleBlockers()` — operations still RUNNING in the Activity tab. Not a
27
+ * duplicate of `platform`: an activity spans a whole operation (an install, a deploy, a clone)
28
+ * across many PAL calls, so the gaps between them look quiet at the seam while the operation is
29
+ * plainly mid-flight. A finished entry never blocks — the list stays on screen forever.
30
+ *
31
+ * The consumers are the `packages/studio:verify` skill, the screenshot runner and P4.2's Activity
32
+ * tracker (this is a read-only projection of the same in-flight set that dock renders).
33
+ */
34
+
35
+ import { rendersInFlight } from "../store";
36
+ import { activityIdleBlockers } from "../panels/activity-panel";
37
+ import { pendingSchedulers } from "../panels/panel-scheduler";
38
+ import { canvasIdleBlockers } from "../canvas/iframe-host";
39
+ import { platformInFlight } from "../platform";
40
+ import { overlayIdleBlockers } from "../ui/layers";
41
+
42
+ /** One subsystem that can be outstanding, and its account of why. */
43
+ export interface IdleSource {
44
+ /** Stable name — `render`, `panels`, `canvas`, `platform`, `overlay`. */
45
+ readonly name: string;
46
+ /** Empty when quiet; otherwise one human-readable line per outstanding item. */
47
+ blockers: () => readonly string[];
48
+ }
49
+
50
+ /** Consecutive quiet animation frames required before Studio counts as settled. */
51
+ export const QUIET_FRAMES = 2;
52
+
53
+ /** How long {@link probeIdle} waits before rejecting with what is still outstanding. */
54
+ export const DEFAULT_IDLE_TIMEOUT_MS = 10_000;
55
+
56
+ /** Thrown when Studio did not settle in time — `blockedBy` is the answer, not the message. */
57
+ export class NotIdleError extends Error {
58
+ readonly blockedBy: readonly string[];
59
+
60
+ constructor(blockedBy: readonly string[], timeoutMs: number) {
61
+ super(
62
+ blockedBy.length === 0
63
+ ? `Studio did not report ${QUIET_FRAMES} consecutive quiet frames within ${timeoutMs}ms`
64
+ : `Studio was not idle after ${timeoutMs}ms — blocked by ${blockedBy.join("; ")}`,
65
+ );
66
+ this.name = "NotIdleError";
67
+ this.blockedBy = blockedBy;
68
+ }
69
+ }
70
+
71
+ /**
72
+ * The six live sources.
73
+ *
74
+ * Built per call rather than held in a module constant so a test can substitute one without
75
+ * unpicking the others, and so a second window's hosts are never read through the first window's
76
+ * closure.
77
+ */
78
+ export function defaultIdleSources(): IdleSource[] {
79
+ return [
80
+ {
81
+ blockers: () => {
82
+ const count = rendersInFlight();
83
+ return count > 0 ? [`render: ${count} renderer(s) mid-paint`] : [];
84
+ },
85
+ name: "render",
86
+ },
87
+ {
88
+ blockers: () => pendingSchedulers().map((panel) => `panels: ${panel}`),
89
+ name: "panels",
90
+ },
91
+ { blockers: canvasIdleBlockers, name: "canvas" },
92
+ {
93
+ blockers: () => {
94
+ const calls = platformInFlight();
95
+ if (calls.length === 0) {
96
+ return [];
97
+ }
98
+ return [`platform: ${calls.length} in-flight (${[...new Set(calls)].join(", ")})`];
99
+ },
100
+ name: "platform",
101
+ },
102
+ { blockers: overlayIdleBlockers, name: "overlay" },
103
+ { blockers: activityIdleBlockers, name: "activity" },
104
+ ];
105
+ }
106
+
107
+ /** Everything outstanding right now, across every source. Empty means this instant is quiet. */
108
+ export function idleBlockers(sources: readonly IdleSource[] = defaultIdleSources()): string[] {
109
+ const blockers: string[] = [];
110
+ for (const source of sources) {
111
+ blockers.push(...source.blockers());
112
+ }
113
+ return blockers;
114
+ }
115
+
116
+ export interface IdleOptions {
117
+ timeoutMs?: number;
118
+ /** Consecutive quiet frames required. Defaults to {@link QUIET_FRAMES}. */
119
+ frames?: number;
120
+ /** Substitute the quiescence sources — what a test states, and what a second window would pass. */
121
+ sources?: readonly IdleSource[];
122
+ /** Frame scheduler, injectable so the loop is testable without a real compositor. */
123
+ raf?: (callback: () => void) => void;
124
+ /** Clock, injectable for the same reason. */
125
+ now?: () => number;
126
+ }
127
+
128
+ /**
129
+ * Resolve once every source has been quiet for `frames` consecutive animation frames.
130
+ *
131
+ * Rejects with {@link NotIdleError} on timeout. A single quiet frame is not enough: a render commits
132
+ * its DOM in one frame and its layout/animation consequences in the next, which is exactly the
133
+ * window a one-frame check photographs.
134
+ */
135
+ export function probeIdle(options: IdleOptions = {}): Promise<void> {
136
+ const {
137
+ frames = QUIET_FRAMES,
138
+ now = () => Date.now(),
139
+ raf = (callback: () => void) => {
140
+ requestAnimationFrame(() => callback());
141
+ },
142
+ sources = defaultIdleSources(),
143
+ timeoutMs = DEFAULT_IDLE_TIMEOUT_MS,
144
+ } = options;
145
+
146
+ return new Promise<void>((resolve, reject) => {
147
+ const deadline = now() + timeoutMs;
148
+ let quiet = 0;
149
+ let settled = false;
150
+ // The last non-empty account, so a timeout that lands on a momentarily-quiet frame still names
151
+ // What kept it from reaching `frames` — "not idle, blocked by nothing" helps nobody.
152
+ let lastBlockers: readonly string[] = [];
153
+
154
+ const tick = () => {
155
+ if (settled) {
156
+ return;
157
+ }
158
+ const blockers = idleBlockers(sources);
159
+ if (blockers.length > 0) {
160
+ lastBlockers = blockers;
161
+ quiet = 0;
162
+ } else {
163
+ quiet += 1;
164
+ if (quiet >= frames) {
165
+ settled = true;
166
+ resolve();
167
+ return;
168
+ }
169
+ }
170
+ if (now() >= deadline) {
171
+ settled = true;
172
+ reject(new NotIdleError(blockers.length > 0 ? blockers : lastBlockers, timeoutMs));
173
+ return;
174
+ }
175
+ raf(tick);
176
+ };
177
+ raf(tick);
178
+ });
179
+ }
@@ -10,6 +10,15 @@
10
10
  import type { ImportProgressEvent, ImportSiteOptions } from "../types";
11
11
  import type { ProjectConfig } from "@jxsuite/schema/types";
12
12
 
13
+ /**
14
+ * The `phase` of the one progress line this client emits itself rather than forwarding.
15
+ *
16
+ * Exported so a caller can recognize it without matching a bare string: the import log renders
17
+ * every phase verbatim, but a warning also needs to outlive the log, which vanishes the moment a
18
+ * successful import hands off to the new project.
19
+ */
20
+ export const IMPORT_WARNING_PHASE = "warning";
21
+
13
22
  interface StreamLine {
14
23
  type: string;
15
24
  phase?: string;
@@ -77,6 +86,13 @@ export async function streamImport(
77
86
  const decoder = new TextDecoder();
78
87
  let buffer = "";
79
88
  let result: { root: string; config: ProjectConfig } | null = null;
89
+ /*
90
+ * Lines the parser could not read. Tolerating one is right — an import that ran for two minutes
91
+ * should not die on a garbled progress line — but doing it *silently* is not: the import then
92
+ * finishes looking clean while the user never sees the pages it skipped. Counted here and
93
+ * surfaced once at the end, so the tolerance stays visible instead of becoming a hiding place.
94
+ */
95
+ let unreadable = 0;
80
96
 
81
97
  const handleLine = (line: string) => {
82
98
  const trimmed = line.trim();
@@ -87,6 +103,7 @@ export async function streamImport(
87
103
  try {
88
104
  parsed = JSON.parse(trimmed) as StreamLine;
89
105
  } catch {
106
+ unreadable += 1;
90
107
  return; // Tolerate a mangled line rather than killing the whole import.
91
108
  }
92
109
  if (parsed.type === "progress") {
@@ -127,6 +144,15 @@ export async function streamImport(
127
144
  }
128
145
  }
129
146
 
147
+ if (unreadable > 0) {
148
+ onProgress({
149
+ message:
150
+ `${unreadable} progress line${unreadable === 1 ? "" : "s"} could not be read and ` +
151
+ `${unreadable === 1 ? "was" : "were"} skipped — the import may be missing steps.`,
152
+ phase: IMPORT_WARNING_PHASE,
153
+ });
154
+ }
155
+
130
156
  if (!result) {
131
157
  throw new Error("Import stream ended without a result");
132
158
  }