@jxsuite/studio 6.1.1 → 8.0.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 (785) hide show
  1. package/README.md +5 -5
  2. package/dist/chunks/2020-5wtzce5g.js +4 -0
  3. package/dist/chunks/{action-group-2mqby73c.js → action-group-4aan7g6g.js} +3 -3
  4. package/dist/chunks/adapter-5tphg7xe.js +4 -0
  5. package/dist/chunks/add-new-flow-psym14sn.js +4 -0
  6. package/dist/chunks/cf-account-picker-haqazq5r.js +4 -0
  7. package/dist/chunks/cf-settings-h2wrh6hq.js +4 -0
  8. package/dist/chunks/color-area-6rbra5dy.js +4 -0
  9. package/dist/chunks/color-field-gy56c94g.js +4 -0
  10. package/dist/chunks/color-m7r1vk54.js +4 -0
  11. package/dist/chunks/color-slider-sqqdyf6c.js +4 -0
  12. package/dist/chunks/combobox-72h32ejk.js +4 -0
  13. package/dist/chunks/components-r22xca09.js +4 -0
  14. package/dist/chunks/content-source-mmppmcyg.js +4 -0
  15. package/dist/chunks/convert-to-repeater-he70fc2b.js +4 -0
  16. package/dist/chunks/dialog-c4x05vyx.js +4 -0
  17. package/dist/chunks/editor-ccd9jwsa.js +4 -0
  18. package/dist/chunks/entry-commands-6qxz9e8p.js +4 -0
  19. package/dist/chunks/extension-sections-0egb88dm.js +4 -0
  20. package/dist/chunks/file-ops-qnab36ek.js +4 -0
  21. package/dist/chunks/files-rcn56qvm.js +4 -0
  22. package/dist/chunks/format-host-yxz0kjjs.js +4 -0
  23. package/dist/chunks/fs-events-d1qxq4z4.js +4 -0
  24. package/dist/chunks/grid-open-4z1g062t.js +4 -0
  25. package/dist/chunks/grid-view-qg1b5eqx.js +51 -0
  26. package/dist/chunks/icons-63bjtbs7.js +4 -0
  27. package/dist/chunks/iframe-entry-2zggzajv.js +5 -0
  28. package/dist/chunks/iframe-entry-76j8vwwx.js +5 -0
  29. package/dist/chunks/iframe-entry-99nr5zfb.js +5 -0
  30. package/dist/chunks/iframe-entry-pkgmcgp0.js +5 -0
  31. package/dist/chunks/iframe-host-ssv7kyj0.js +4 -0
  32. package/dist/chunks/{index-2veqmnhr.js → index-32eqzv1k.js} +3 -3
  33. package/dist/chunks/index-f0jn7nnp.js +4 -0
  34. package/dist/chunks/{javascript-8nbvs12s.js → javascript-pjp734q4.js} +3 -3
  35. package/dist/chunks/jsonMode-njkvsa02.js +13 -0
  36. package/dist/chunks/jx-validate-ttasrbh7.js +4 -0
  37. package/dist/chunks/layers-bgyr11tr.js +4 -0
  38. package/dist/chunks/layers-panel-7ez66zeq.js +4 -0
  39. package/dist/chunks/listbox-c421cf8c.js +4 -0
  40. package/dist/chunks/lit-html-v9gh687x.js +4 -0
  41. package/dist/chunks/media-library-sq468wts.js +4 -0
  42. package/dist/chunks/media-picker-shfe59pt.js +4 -0
  43. package/dist/chunks/menu-bdpzbfvs.js +4 -0
  44. package/dist/chunks/monaco-binding-vq1hgnn0.js +4 -0
  45. package/dist/chunks/monaco-buffer-3afgwvbp.js +4 -0
  46. package/dist/chunks/monaco-setup-xrd2cbkp.js +4 -0
  47. package/dist/chunks/notify-kzrjr3fv.js +4 -0
  48. package/dist/chunks/number-field-y62xq0ty.js +4 -0
  49. package/dist/chunks/parse-v77xtwv7.js +4 -0
  50. package/dist/chunks/platform-7v4rtd7m.js +4 -0
  51. package/dist/chunks/popover-b89sfej7.js +4 -0
  52. package/dist/chunks/publish-panel-2z9gw8ee.js +4 -0
  53. package/dist/chunks/publish-quick-qx2455cj.js +4 -0
  54. package/dist/chunks/publish-workspace-wrc1dgwx.js +4 -0
  55. package/dist/chunks/quick-search-n0t0eqxb.js +4 -0
  56. package/dist/chunks/references-9547rg5s.js +4 -0
  57. package/dist/chunks/right-panel-wsgnr9pn.js +4 -0
  58. package/dist/chunks/select-rzds841e.js +4 -0
  59. package/dist/chunks/source-control-kwktr9y6.js +4 -0
  60. package/dist/chunks/split-c9zfdgxf.js +4 -0
  61. package/dist/chunks/studio-03ct6yfv.js +9 -0
  62. package/dist/chunks/studio-07rcfje3.js +5 -0
  63. package/dist/chunks/studio-3e54qh39.js +7 -0
  64. package/dist/chunks/studio-3exxhz5g.js +5 -0
  65. package/dist/chunks/studio-3q40e3rj.js +5 -0
  66. package/dist/chunks/studio-3qeh9t0h.js +6 -0
  67. package/dist/chunks/studio-3qqjeep5.js +6 -0
  68. package/dist/chunks/studio-43sd2mam.js +4 -0
  69. package/dist/chunks/studio-4hp8pkyt.js +5 -0
  70. package/dist/chunks/studio-58xg6j2q.js +9 -0
  71. package/dist/chunks/studio-5g0rprdt.js +7 -0
  72. package/dist/chunks/studio-6m380wp7.js +5 -0
  73. package/dist/chunks/studio-80jyh1xh.js +4 -0
  74. package/dist/chunks/studio-83mk4bgg.js +9 -0
  75. package/dist/chunks/{studio-kggey1jt.js → studio-881z1xrx.js} +4 -4
  76. package/dist/chunks/studio-8m0y2qe7.js +5 -0
  77. package/dist/chunks/studio-8tr6cfrc.js +5 -0
  78. package/dist/chunks/studio-8vcvfs7r.js +6 -0
  79. package/dist/chunks/studio-9tmebf0s.js +5 -0
  80. package/dist/chunks/studio-a2bvaptz.js +5 -0
  81. package/dist/chunks/studio-b7y5mr30.js +5 -0
  82. package/dist/chunks/studio-bavb31r0.js +5 -0
  83. package/dist/chunks/studio-bbe4c90a.js +5 -0
  84. package/dist/chunks/studio-c05wdnt3.js +5 -0
  85. package/dist/chunks/studio-ccv2svc6.js +5 -0
  86. package/dist/chunks/studio-d5grtb9e.js +16 -0
  87. package/dist/chunks/studio-df0baea9.js +5 -0
  88. package/dist/chunks/studio-dgk4dqtx.js +7 -0
  89. package/dist/chunks/studio-e1g64q43.js +5 -0
  90. package/dist/chunks/studio-ed1hp6zf.js +6 -0
  91. package/dist/chunks/studio-ed3xx40h.js +7 -0
  92. package/dist/chunks/studio-f14e1zdj.js +5 -0
  93. package/dist/chunks/studio-fbhxxc5f.js +5 -0
  94. package/dist/chunks/studio-fyh0jc96.js +5 -0
  95. package/dist/chunks/studio-gcxk20n7.js +5 -0
  96. package/dist/chunks/studio-jaaz8ce9.js +5 -0
  97. package/dist/chunks/{studio-8grwxtqk.js → studio-jcnsdaep.js} +4 -4
  98. package/dist/chunks/studio-jsgf2q5k.js +7 -0
  99. package/dist/chunks/{studio-1q1sh2ax.js → studio-k3xxbagr.js} +3 -3
  100. package/dist/chunks/studio-k7evxqh4.js +5 -0
  101. package/dist/chunks/studio-kt3pjkwd.js +5 -0
  102. package/dist/chunks/studio-m8g16bgz.js +5 -0
  103. package/dist/chunks/studio-mn0476ag.js +5 -0
  104. package/dist/chunks/studio-mx1smyq0.js +5 -0
  105. package/dist/chunks/studio-n0c5h6mf.js +5 -0
  106. package/dist/chunks/{studio-rv11kfwa.js → studio-nh6d342n.js} +7 -7
  107. package/dist/chunks/studio-nqxqf8p2.js +4 -0
  108. package/dist/chunks/studio-p4nrkvqr.js +5 -0
  109. package/dist/chunks/{studio-h46vtzk8.js → studio-pbxa5fpc.js} +4 -4
  110. package/dist/chunks/studio-pgmvdv7z.js +7 -0
  111. package/dist/chunks/studio-ph84avkf.js +5 -0
  112. package/dist/chunks/{studio-wszjyh0j.js → studio-q0mvbaq6.js} +4 -4
  113. package/dist/chunks/studio-q0tccd43.js +5 -0
  114. package/dist/chunks/studio-q7rtx6zq.js +14 -0
  115. package/dist/chunks/{studio-pre0skq6.js → studio-qgh13jtz.js} +4 -4
  116. package/dist/chunks/studio-qmn1xc24.js +5 -0
  117. package/dist/chunks/studio-qwdqwkj0.js +5 -0
  118. package/dist/chunks/{studio-t6b6qe31.js → studio-r5qy30vx.js} +4 -4
  119. package/dist/chunks/studio-rj9eamf8.js +5 -0
  120. package/dist/chunks/studio-rptgsk96.js +5 -0
  121. package/dist/chunks/studio-rthyg42z.js +928 -0
  122. package/dist/chunks/studio-s19tp1xr.js +5 -0
  123. package/dist/chunks/studio-s32578pn.js +5 -0
  124. package/dist/chunks/studio-svb7yyve.js +5 -0
  125. package/dist/chunks/studio-syreb644.js +5 -0
  126. package/dist/chunks/studio-tf9jryb1.js +10 -0
  127. package/dist/chunks/studio-tfkznv39.js +5 -0
  128. package/dist/chunks/studio-tft6r105.js +5 -0
  129. package/dist/chunks/studio-txf2kysx.js +5 -0
  130. package/dist/chunks/studio-v8867ddv.js +12 -0
  131. package/dist/chunks/studio-vxq7fcvv.js +5 -0
  132. package/dist/chunks/studio-w4rz9hdk.js +5 -0
  133. package/dist/chunks/studio-wbcjbhy1.js +9 -0
  134. package/dist/chunks/studio-wc649wss.js +5 -0
  135. package/dist/chunks/studio-wys23mxz.js +5 -0
  136. package/dist/chunks/studio-x1x167jh.js +5 -0
  137. package/dist/chunks/studio-x9hsze61.js +5 -0
  138. package/dist/chunks/studio-y0n7yxea.js +9 -0
  139. package/dist/chunks/studio-y3ahhdpx.js +5 -0
  140. package/dist/chunks/studio-z97c48fk.js +5 -0
  141. package/dist/chunks/studio-zat62m0c.js +5 -0
  142. package/dist/chunks/studio-zcd2e7yz.js +5 -0
  143. package/dist/chunks/studio-zz9qe3rw.js +64 -0
  144. package/dist/chunks/swatch-group-ewh24n1f.js +4 -0
  145. package/dist/chunks/tabs-f5cw3tgp.js +4 -0
  146. package/dist/chunks/textfield-wewc8rq2.js +4 -0
  147. package/dist/chunks/toast-1gv0h53h.js +4 -0
  148. package/dist/chunks/toast-host-1yg5ar8d.js +4 -0
  149. package/dist/chunks/{toolbar-2nnzqhrj.js → toolbar-44cm5cta.js} +3 -3
  150. package/dist/chunks/tooltip-yypz28gq.js +4 -0
  151. package/dist/chunks/tree-9xa4hm7n.js +4 -0
  152. package/dist/chunks/tsMode-epyfz1hv.js +14 -0
  153. package/dist/chunks/workspace-dz7nxfhv.js +4 -0
  154. package/dist/chunks/workspace-home-xsd7hkjw.js +4 -0
  155. package/dist/chunks/ws-client-bv552sfx.js +4 -0
  156. package/dist/iframe-entry.js +20 -16
  157. package/dist/manifest.json +77 -63
  158. package/dist/studio.js +106 -107
  159. package/dist/workers/ts.worker.js +3 -3
  160. package/package.json +17 -16
  161. package/src/about/about-modal.ts +4 -3
  162. package/src/account/action-flow.ts +45 -38
  163. package/src/account-status.ts +7 -2
  164. package/src/browse/component-examples.ts +272 -0
  165. package/src/browse/library-commands.ts +64 -104
  166. package/src/browse/library-layouts.ts +270 -53
  167. package/src/browse/library-model.ts +194 -134
  168. package/src/browse/library-pane.ts +748 -440
  169. package/src/browse/library-preview.ts +161 -26
  170. package/src/browse/library-source.ts +308 -41
  171. package/src/browse/preview-root.ts +78 -0
  172. package/src/browse/preview-style.ts +155 -0
  173. package/src/canvas/asset-refs.ts +40 -10
  174. package/src/canvas/asset-resolve.ts +19 -23
  175. package/src/canvas/canvas-helpers.ts +7 -6
  176. package/src/canvas/canvas-live-render.ts +260 -77
  177. package/src/canvas/canvas-origin.ts +37 -12
  178. package/src/canvas/canvas-page-context.ts +112 -0
  179. package/src/canvas/canvas-patcher.ts +30 -30
  180. package/src/canvas/canvas-perf.ts +11 -5
  181. package/src/canvas/canvas-render.ts +175 -148
  182. package/src/canvas/canvas-surface.ts +5 -3
  183. package/src/canvas/canvas-utils.ts +147 -61
  184. package/src/canvas/dialog-path.ts +9 -4
  185. package/src/canvas/dialog-state.ts +1 -2
  186. package/src/canvas/diff-marks.ts +9 -16
  187. package/src/canvas/diff-toolbar.ts +8 -7
  188. package/src/canvas/edit-width-drag.ts +4 -1
  189. package/src/canvas/edit-width.ts +1 -3
  190. package/src/canvas/iframe-channel.ts +27 -13
  191. package/src/canvas/iframe-drop.ts +120 -12
  192. package/src/canvas/iframe-editable-root.ts +29 -16
  193. package/src/canvas/iframe-entry.ts +104 -75
  194. package/src/canvas/iframe-eval.ts +73 -49
  195. package/src/canvas/iframe-host.ts +269 -158
  196. package/src/canvas/iframe-inline-edit.ts +49 -30
  197. package/src/canvas/iframe-insert.ts +5 -4
  198. package/src/canvas/iframe-interaction.ts +30 -25
  199. package/src/canvas/iframe-keys.ts +11 -0
  200. package/src/canvas/iframe-overlay.ts +1 -1
  201. package/src/canvas/iframe-patch.ts +25 -21
  202. package/src/canvas/iframe-position.ts +12 -6
  203. package/src/canvas/iframe-protocol.ts +36 -21
  204. package/src/canvas/iframe-render.ts +84 -35
  205. package/src/canvas/iframe-slash.ts +24 -11
  206. package/src/canvas/iframe-subtree.ts +10 -3
  207. package/src/canvas/npm-modules.ts +22 -0
  208. package/src/canvas/path-mapping.ts +19 -12
  209. package/src/canvas/popover-path.ts +7 -3
  210. package/src/canvas/popover-state.ts +1 -2
  211. package/src/canvas/preview-navigate.ts +16 -0
  212. package/src/canvas/repeater-sources.ts +200 -0
  213. package/src/canvas/serialize-scope.ts +13 -5
  214. package/src/canvas/stage-scrollbar.ts +7 -2
  215. package/src/canvas/surface-registry.ts +27 -3
  216. package/src/collab/collab-commands.ts +7 -2
  217. package/src/collab/collab-session.ts +84 -45
  218. package/src/collab/collab-state.ts +4 -3
  219. package/src/collab/monaco-binding.ts +16 -13
  220. package/src/collab/monaco-cursors.ts +5 -2
  221. package/src/commands/app-commands.ts +16 -6
  222. package/src/commands/budget.ts +13 -11
  223. package/src/commands/command-args.ts +103 -71
  224. package/src/commands/context.ts +55 -28
  225. package/src/commands/defaults.ts +69 -45
  226. package/src/commands/keymap.ts +56 -43
  227. package/src/commands/levels.ts +14 -8
  228. package/src/commands/live-context.ts +9 -7
  229. package/src/commands/reference.ts +2 -1
  230. package/src/commands/registry.ts +22 -11
  231. package/src/commands/run-reported.ts +15 -10
  232. package/src/component-props.ts +46 -30
  233. package/src/content/collection-match.ts +11 -9
  234. package/src/content/collection-pages.ts +412 -0
  235. package/src/content/content-collections.ts +270 -0
  236. package/src/content/draft-state.ts +4 -3
  237. package/src/content/entry-commands.ts +54 -62
  238. package/src/content/entry-editor.ts +137 -32
  239. package/src/content/entry-fields.ts +25 -8
  240. package/src/content/entry-inspector.ts +225 -0
  241. package/src/content/entry-model.ts +38 -15
  242. package/src/content/entry-open.ts +80 -0
  243. package/src/content/entry-summaries.ts +440 -0
  244. package/src/content/file-record-ids.ts +80 -0
  245. package/src/content/file-records.ts +125 -0
  246. package/src/content/page-summaries.ts +129 -0
  247. package/src/content/record-entry.ts +201 -0
  248. package/src/content/writing-banner.ts +177 -0
  249. package/src/create/add-new-commands.ts +185 -0
  250. package/src/create/add-new-flow.ts +1116 -0
  251. package/src/create/add-new.ts +1014 -0
  252. package/src/create/element-name.ts +121 -0
  253. package/src/editor/canvas-context-menu.ts +1 -2
  254. package/src/editor/canvas-slash-bridge.ts +3 -6
  255. package/src/editor/content-slice.ts +16 -14
  256. package/src/editor/context-menu.ts +35 -22
  257. package/src/editor/convert-targets.ts +30 -35
  258. package/src/editor/convert-to-component.ts +78 -48
  259. package/src/editor/convert-to-repeater.ts +34 -22
  260. package/src/editor/editable-tags.ts +17 -2
  261. package/src/editor/file-drop-action.ts +29 -22
  262. package/src/editor/inline-edit-apply.ts +79 -17
  263. package/src/editor/inline-edit.ts +76 -50
  264. package/src/editor/inline-format.ts +59 -56
  265. package/src/editor/inline-link.ts +40 -15
  266. package/src/editor/insert-component.ts +91 -0
  267. package/src/editor/insert-zone-action.ts +14 -5
  268. package/src/editor/merge-tags.ts +58 -19
  269. package/src/editor/repeater-scope.ts +39 -28
  270. package/src/editor/shortcuts.ts +76 -42
  271. package/src/editor/slash-menu.ts +52 -14
  272. package/src/files/asset-versions.ts +4 -4
  273. package/src/files/components.ts +89 -20
  274. package/src/files/elements.ts +5 -6
  275. package/src/files/file-ops.ts +92 -41
  276. package/src/files/files.ts +248 -239
  277. package/src/files/fs-events.ts +18 -7
  278. package/src/files/media-meta.ts +97 -2
  279. package/src/files/media-paths.ts +3 -0
  280. package/src/files/media-types.ts +55 -0
  281. package/src/files/media-upload.ts +209 -52
  282. package/src/files/new-file-name.ts +156 -0
  283. package/src/files/serialize-document.ts +15 -5
  284. package/src/format/constraints.ts +1 -1
  285. package/src/format/convert-file.ts +27 -13
  286. package/src/format/format-choices.ts +2 -1
  287. package/src/format/format-host.ts +91 -50
  288. package/src/github/github-auth-status.ts +27 -3
  289. package/src/github/github-auth.ts +21 -11
  290. package/src/github/github-publish.ts +28 -23
  291. package/src/grid/cell-editors.ts +46 -31
  292. package/src/grid/cell-popovers.ts +5 -3
  293. package/src/grid/edit-buffer.ts +10 -9
  294. package/src/grid/grid-controller.ts +25 -23
  295. package/src/grid/grid-layout.ts +21 -5
  296. package/src/grid/grid-open.ts +3 -33
  297. package/src/grid/grid-panel.ts +65 -6
  298. package/src/grid/grid-reveal.ts +34 -0
  299. package/src/grid/grid-source.ts +9 -31
  300. package/src/grid/grid-view.ts +45 -23
  301. package/src/grid/redirects-grid.ts +14 -5
  302. package/src/grid/redirects.ts +16 -14
  303. package/src/grid/schema-columns.ts +25 -19
  304. package/src/grid/sources/connector-source.ts +47 -20
  305. package/src/grid/sources/content-source.ts +100 -31
  306. package/src/grid/sources/csv-file-source.ts +2 -2
  307. package/src/grid/tabulator-tables.d.ts +61 -34
  308. package/src/hosting/document.ts +2 -2
  309. package/src/hosting/stage.ts +7 -7
  310. package/src/i18n/i18n-commands.ts +3 -3
  311. package/src/media/media-commands.ts +181 -0
  312. package/src/media/media-library-model.ts +232 -0
  313. package/src/media/media-library.ts +1283 -0
  314. package/src/media/media-pane.ts +51 -20
  315. package/src/new-project/add-repo-modal.ts +20 -19
  316. package/src/new-project/import-tab.ts +10 -14
  317. package/src/new-project/location-fields.ts +2 -1
  318. package/src/new-project/new-project-modal.ts +12 -9
  319. package/src/packages/jxsuite-update.ts +4 -3
  320. package/src/packages/pull-package-sync.ts +26 -25
  321. package/src/page-params.ts +97 -68
  322. package/src/panels/activity-panel.ts +38 -14
  323. package/src/panels/ai-chat/attached-context.ts +13 -7
  324. package/src/panels/ai-chat/chat-markdown.ts +8 -8
  325. package/src/panels/ai-chat/chat-view.ts +80 -73
  326. package/src/panels/ai-chat/composer.ts +30 -33
  327. package/src/panels/ai-chat/sessions-view.ts +1 -2
  328. package/src/panels/ai-panel.ts +23 -20
  329. package/src/panels/block-action-bar.ts +57 -46
  330. package/src/panels/bottom-dock.ts +5 -3
  331. package/src/panels/canvas-dnd-bridge.ts +36 -26
  332. package/src/panels/chat-panel.ts +6 -6
  333. package/src/panels/collections-panel.ts +306 -0
  334. package/src/panels/component-preview.ts +35 -13
  335. package/src/panels/data-explorer.ts +63 -26
  336. package/src/panels/data-grid.ts +18 -11
  337. package/src/panels/dnd.ts +115 -138
  338. package/src/panels/editors.ts +52 -21
  339. package/src/panels/elements-panel.ts +19 -5
  340. package/src/panels/empty-state.ts +2 -2
  341. package/src/panels/events-panel.ts +84 -69
  342. package/src/panels/formula-workspace.ts +78 -54
  343. package/src/panels/frontmatter-fields.ts +33 -28
  344. package/src/panels/git-diff-open.ts +10 -6
  345. package/src/panels/head-panel.ts +488 -202
  346. package/src/panels/i18n-panel.ts +20 -12
  347. package/src/panels/imports-panel.ts +25 -47
  348. package/src/panels/jump-bar.ts +75 -31
  349. package/src/panels/layers-panel.ts +130 -101
  350. package/src/panels/left-panel.ts +25 -11
  351. package/src/panels/navigator-panels.ts +23 -11
  352. package/src/panels/pane-context.ts +140 -49
  353. package/src/panels/pane-grid.ts +55 -26
  354. package/src/panels/panel-registry.ts +36 -46
  355. package/src/panels/properties-panel.ts +182 -124
  356. package/src/panels/quick-search.ts +53 -31
  357. package/src/panels/right-panel.ts +201 -45
  358. package/src/panels/seo-modal.ts +54 -125
  359. package/src/panels/settings-menu.ts +63 -61
  360. package/src/panels/settings-pane.ts +268 -162
  361. package/src/panels/signals-panel.ts +156 -135
  362. package/src/panels/site-model.ts +367 -0
  363. package/src/panels/site-panel.ts +638 -0
  364. package/src/panels/statement-editor.ts +230 -140
  365. package/src/panels/style-panel.ts +253 -206
  366. package/src/panels/style-utils.ts +114 -51
  367. package/src/panels/stylebook-doc.ts +195 -60
  368. package/src/panels/stylebook-layers-panel.ts +48 -89
  369. package/src/panels/stylebook-panel.ts +60 -27
  370. package/src/panels/styles-panel.ts +327 -0
  371. package/src/panels/tab-drop.ts +27 -11
  372. package/src/panels/tab-strip.ts +143 -49
  373. package/src/platform-errors.ts +57 -43
  374. package/src/platform.ts +59 -31
  375. package/src/platforms/cloud.ts +373 -176
  376. package/src/platforms/default-platform.ts +14 -8
  377. package/src/platforms/devserver.ts +180 -142
  378. package/src/platforms/read-batcher.ts +16 -8
  379. package/src/project-list.ts +2 -1
  380. package/src/publish/deploy-checklist.ts +20 -9
  381. package/src/publish/pages-service.ts +66 -27
  382. package/src/publish/publish-changes.ts +491 -0
  383. package/src/publish/publish-commands.ts +88 -22
  384. package/src/publish/publish-ids.ts +49 -0
  385. package/src/publish/publish-panel.ts +10 -6
  386. package/src/publish/publish-quick.ts +148 -0
  387. package/src/publish/publish-workspace.ts +926 -0
  388. package/src/publish/source-control.ts +907 -0
  389. package/src/recent-projects.ts +15 -8
  390. package/src/resize-edges.ts +26 -36
  391. package/src/services/a11y-report.ts +26 -19
  392. package/src/services/agent-seed.ts +23 -11
  393. package/src/services/ai-ask.ts +9 -12
  394. package/src/services/ai-command-tools.ts +68 -62
  395. package/src/services/ai-import-tools.ts +80 -67
  396. package/src/services/ai-models.ts +17 -13
  397. package/src/services/ai-project-tools.ts +68 -32
  398. package/src/services/ai-session-store.ts +19 -10
  399. package/src/services/ai-system-prompt.ts +46 -20
  400. package/src/services/ai-tools.ts +71 -27
  401. package/src/services/ai-write-report.ts +20 -12
  402. package/src/services/ai-writes.ts +4 -4
  403. package/src/services/automation.ts +74 -51
  404. package/src/services/cem-export.ts +149 -58
  405. package/src/services/cf-settings.ts +4 -4
  406. package/src/services/clock.ts +6 -1
  407. package/src/services/code-services.ts +37 -31
  408. package/src/services/connection.ts +2 -2
  409. package/src/services/context-manager.ts +14 -10
  410. package/src/services/context-resolver.ts +20 -8
  411. package/src/services/data-service.ts +19 -15
  412. package/src/services/directory-picker.ts +20 -14
  413. package/src/services/document-assistant.ts +39 -19
  414. package/src/services/gated-registry.ts +10 -6
  415. package/src/services/harness/chat-reducer.ts +23 -1
  416. package/src/services/import-client.ts +91 -38
  417. package/src/services/import-seed.ts +8 -2
  418. package/src/services/jx-validate.ts +28 -31
  419. package/src/services/live-preview.ts +0 -0
  420. package/src/services/live-surfaces.ts +6 -3
  421. package/src/services/model-uri.ts +10 -2
  422. package/src/services/module-preloads.ts +12 -8
  423. package/src/services/monaco-buffer.ts +43 -24
  424. package/src/services/monaco-lazy.ts +7 -8
  425. package/src/services/monaco-setup.ts +23 -16
  426. package/src/services/notify.ts +44 -17
  427. package/src/services/popover-report.ts +25 -10
  428. package/src/services/preview-eval.ts +20 -8
  429. package/src/services/profile.ts +13 -6
  430. package/src/services/project-path.ts +13 -10
  431. package/src/services/references.ts +0 -0
  432. package/src/services/render-critic.ts +29 -9
  433. package/src/services/settings/definitions.ts +25 -14
  434. package/src/services/settings/kernel.ts +13 -4
  435. package/src/services/settings/write-queue.ts +9 -9
  436. package/src/services/token-lint.ts +12 -10
  437. package/src/services/tool-executor.ts +17 -5
  438. package/src/services/tool-outcomes.ts +44 -24
  439. package/src/services/trusted-types.ts +24 -7
  440. package/src/settings/contexts-section.ts +11 -8
  441. package/src/settings/contributed-section.ts +128 -70
  442. package/src/settings/css-vars-editor.ts +119 -32
  443. package/src/settings/defs-editor.ts +38 -35
  444. package/src/settings/developer-panels.ts +43 -0
  445. package/src/settings/extension-rows.ts +16 -8
  446. package/src/settings/extension-sections.ts +42 -14
  447. package/src/settings/extensions-section.ts +4 -1
  448. package/src/settings/general-settings.ts +101 -28
  449. package/src/settings/locales-section.ts +20 -12
  450. package/src/settings/preferences-dialog.ts +17 -7
  451. package/src/settings/preferences-keymap.ts +7 -5
  452. package/src/settings/preferences-sections.ts +11 -5
  453. package/src/settings/project-sections.ts +28 -11
  454. package/src/settings/schema-field-ui.ts +12 -1
  455. package/src/settings/section-registry.ts +116 -11
  456. package/src/settings/settings-dialog.ts +192 -0
  457. package/src/settings/settings-document.ts +186 -166
  458. package/src/shell/tree.ts +6 -5
  459. package/src/shell.ts +536 -477
  460. package/src/site-context.ts +101 -32
  461. package/src/state.ts +68 -57
  462. package/src/store.ts +54 -34
  463. package/src/studio.ts +219 -116
  464. package/src/style/live-preview.ts +1 -1
  465. package/src/style/project-styles.ts +40 -7
  466. package/src/style/stylebook-specimens.ts +89 -0
  467. package/src/style/stylebook-target.ts +26 -0
  468. package/src/style/tag-inheritance.ts +105 -0
  469. package/src/style/token-ref.ts +5 -4
  470. package/src/style/variables-focus.ts +61 -0
  471. package/src/style/variables-view.ts +235 -0
  472. package/src/surfaces/about.ts +18 -19
  473. package/src/surfaces/add-new.json +1482 -0
  474. package/src/surfaces/add-new.ts +325 -0
  475. package/src/surfaces/add-repo.ts +17 -19
  476. package/src/surfaces/ai-chat.ts +33 -38
  477. package/src/surfaces/ai-credentials-form.ts +6 -16
  478. package/src/surfaces/ai-managed-connect.ts +3 -4
  479. package/src/surfaces/ai-model-picker.ts +3 -5
  480. package/src/surfaces/block-action-bar.ts +22 -11
  481. package/src/surfaces/boot-failure.json +4 -3
  482. package/src/surfaces/boot-failure.ts +4 -5
  483. package/src/surfaces/bottom-dock.json +1 -1
  484. package/src/surfaces/bottom-dock.ts +9 -18
  485. package/src/surfaces/canvas-stage.json +30 -19
  486. package/src/surfaces/canvas-stage.ts +17 -16
  487. package/src/surfaces/cf-account-picker.ts +17 -18
  488. package/src/surfaces/collections-panel.json +615 -0
  489. package/src/surfaces/collections-panel.ts +168 -0
  490. package/src/surfaces/commandbar.json +241 -96
  491. package/src/surfaces/commandbar.ts +145 -105
  492. package/src/surfaces/convert-repeater.ts +17 -19
  493. package/src/surfaces/data-actions.ts +9 -7
  494. package/src/surfaces/dialog.ts +26 -28
  495. package/src/surfaces/diff-toolbar.ts +9 -7
  496. package/src/surfaces/empty-state.json +1 -1
  497. package/src/surfaces/empty-state.ts +7 -10
  498. package/src/surfaces/entry-editor.json +136 -0
  499. package/src/surfaces/entry-editor.ts +35 -11
  500. package/src/surfaces/entry-inspector.json +371 -0
  501. package/src/surfaces/entry-inspector.ts +143 -0
  502. package/src/surfaces/expression-editor.ts +11 -25
  503. package/src/surfaces/files-panel.ts +27 -14
  504. package/src/surfaces/formula-palette.ts +4 -5
  505. package/src/surfaces/github-auth.ts +16 -20
  506. package/src/surfaces/github-publish.ts +17 -22
  507. package/src/surfaces/grid-cell.ts +30 -31
  508. package/src/surfaces/grid-open.ts +10 -14
  509. package/src/surfaces/grid-panel.ts +13 -9
  510. package/src/surfaces/grid-replace.ts +13 -13
  511. package/src/surfaces/grid-views.ts +15 -18
  512. package/src/surfaces/inspector-dock.json +162 -14
  513. package/src/surfaces/inspector-dock.ts +59 -31
  514. package/src/surfaces/jump-bar.ts +5 -6
  515. package/src/surfaces/jxsuite-update.ts +16 -22
  516. package/src/surfaces/library-pane.json +670 -437
  517. package/src/surfaces/library-pane.ts +111 -77
  518. package/src/surfaces/logic-panel.ts +17 -30
  519. package/src/surfaces/logic-workspace.ts +13 -15
  520. package/src/surfaces/media-browser.json +62 -6
  521. package/src/surfaces/media-browser.ts +26 -11
  522. package/src/surfaces/media-field.json +1 -1
  523. package/src/surfaces/media-field.ts +4 -5
  524. package/src/surfaces/media-library.json +1586 -0
  525. package/src/surfaces/media-library.ts +282 -0
  526. package/src/surfaces/media-pane.ts +8 -7
  527. package/src/surfaces/media-pick-dialog.json +71 -0
  528. package/src/surfaces/media-pick-dialog.ts +132 -0
  529. package/src/surfaces/menu.ts +47 -23
  530. package/src/surfaces/navigator-dock.ts +11 -12
  531. package/src/surfaces/new-project.ts +27 -26
  532. package/src/surfaces/pane-context.json +144 -77
  533. package/src/surfaces/pane-context.ts +44 -25
  534. package/src/surfaces/pane-grid.ts +15 -10
  535. package/src/surfaces/panel-activity.ts +5 -6
  536. package/src/surfaces/panel-data.ts +3 -4
  537. package/src/surfaces/panel-deploy-checklist.json +12 -6
  538. package/src/surfaces/panel-deploy-checklist.ts +8 -7
  539. package/src/surfaces/panel-elements.ts +5 -7
  540. package/src/surfaces/panel-i18n.ts +5 -7
  541. package/src/surfaces/panel-imports.ts +6 -13
  542. package/src/surfaces/panel-outline.ts +25 -19
  543. package/src/surfaces/panel-page.json +72 -2
  544. package/src/surfaces/panel-page.ts +49 -25
  545. package/src/surfaces/panel-problems.ts +5 -7
  546. package/src/surfaces/panel-signals.json +1 -1
  547. package/src/surfaces/panel-signals.ts +25 -39
  548. package/src/surfaces/panel-stylebook-layers.json +71 -204
  549. package/src/surfaces/panel-stylebook-layers.ts +5 -29
  550. package/src/surfaces/preferences.json +120 -48
  551. package/src/surfaces/preferences.ts +29 -11
  552. package/src/surfaces/progress-modal.ts +15 -9
  553. package/src/surfaces/properties-panel.json +1 -1
  554. package/src/surfaces/properties-panel.ts +20 -42
  555. package/src/surfaces/publish-quick.json +428 -0
  556. package/src/surfaces/publish-quick.ts +165 -0
  557. package/src/surfaces/publish-workspace.json +2892 -0
  558. package/src/surfaces/publish-workspace.ts +391 -0
  559. package/src/surfaces/publish.ts +18 -18
  560. package/src/surfaces/push-plan.ts +7 -8
  561. package/src/surfaces/rail.json +1 -159
  562. package/src/surfaces/rail.ts +22 -79
  563. package/src/surfaces/reference-field.ts +11 -15
  564. package/src/surfaces/schema-builder.ts +16 -22
  565. package/src/surfaces/schema-form.json +10 -2
  566. package/src/surfaces/schema-form.ts +17 -25
  567. package/src/surfaces/secret-field.ts +9 -6
  568. package/src/surfaces/seo.json +1 -1
  569. package/src/surfaces/seo.ts +21 -15
  570. package/src/surfaces/settings-contexts.ts +9 -7
  571. package/src/surfaces/settings-contributed.json +5 -5
  572. package/src/surfaces/settings-contributed.ts +32 -12
  573. package/src/surfaces/settings-css-vars.json +44 -36
  574. package/src/surfaces/settings-css-vars.ts +82 -16
  575. package/src/surfaces/settings-defs.json +2 -2
  576. package/src/surfaces/settings-defs.ts +17 -21
  577. package/src/surfaces/settings-deploy.json +2 -15
  578. package/src/surfaces/settings-deploy.ts +9 -16
  579. package/src/surfaces/settings-dialog.json +51 -0
  580. package/src/surfaces/settings-dialog.ts +169 -0
  581. package/src/surfaces/settings-extensions.ts +5 -6
  582. package/src/surfaces/settings-head.ts +33 -39
  583. package/src/surfaces/settings-locales.ts +8 -20
  584. package/src/surfaces/settings-overview.json +3 -3
  585. package/src/surfaces/settings-overview.ts +14 -8
  586. package/src/surfaces/settings-packages.ts +8 -7
  587. package/src/surfaces/settings-pane.json +269 -46
  588. package/src/surfaces/settings-pane.ts +88 -36
  589. package/src/surfaces/settings-rawjson.ts +5 -6
  590. package/src/surfaces/shell.json +2 -1
  591. package/src/surfaces/shell.ts +1 -2
  592. package/src/surfaces/site-panel.json +1029 -0
  593. package/src/surfaces/site-panel.ts +233 -0
  594. package/src/surfaces/slash-menu.json +63 -21
  595. package/src/surfaces/slash-menu.ts +42 -9
  596. package/src/surfaces/statements.ts +13 -18
  597. package/src/surfaces/statusbar.ts +56 -29
  598. package/src/surfaces/style-panel.ts +18 -31
  599. package/src/surfaces/stylebook-chrome.ts +3 -5
  600. package/src/surfaces/styles-panel.json +735 -0
  601. package/src/surfaces/styles-panel.ts +195 -0
  602. package/src/surfaces/styles-variables.json +149 -0
  603. package/src/surfaces/styles-variables.ts +145 -0
  604. package/src/surfaces/tab-strip.json +4 -4
  605. package/src/surfaces/tab-strip.ts +14 -13
  606. package/src/surfaces/target-line.ts +6 -7
  607. package/src/surfaces/welcome.ts +6 -8
  608. package/src/surfaces/writing-banner.json +94 -0
  609. package/src/surfaces/writing-banner.ts +80 -0
  610. package/src/tabs/bare-repeaters.ts +101 -0
  611. package/src/tabs/patch-ops.ts +4 -3
  612. package/src/tabs/project-config.ts +32 -21
  613. package/src/tabs/selection.ts +36 -8
  614. package/src/tabs/tab.ts +99 -48
  615. package/src/tabs/transact.ts +98 -53
  616. package/src/types.ts +53 -43
  617. package/src/ui/ai-credentials-form.ts +10 -13
  618. package/src/ui/ai-model-picker.ts +3 -3
  619. package/src/ui/cf-account-picker.ts +7 -9
  620. package/src/ui/color-selector.ts +9 -5
  621. package/src/ui/dynamic-slot.ts +7 -8
  622. package/src/ui/expression-editor.ts +112 -105
  623. package/src/ui/form-controls.ts +104 -56
  624. package/src/ui/formula-catalog.ts +239 -230
  625. package/src/ui/formula-chips.ts +33 -18
  626. package/src/ui/layers.ts +57 -31
  627. package/src/ui/media-picker.ts +300 -47
  628. package/src/ui/popover-surface.ts +20 -12
  629. package/src/ui/progress-modal.ts +13 -8
  630. package/src/ui/regions.ts +14 -12
  631. package/src/ui/schema-form.ts +372 -97
  632. package/src/ui/surface.ts +71 -8
  633. package/src/ui/timing.ts +9 -0
  634. package/src/ui/value-source.ts +44 -31
  635. package/src/ui/virtual-window.ts +29 -3
  636. package/src/utils/base64.ts +6 -4
  637. package/src/utils/edit-display.ts +366 -111
  638. package/src/utils/element-selectors.ts +3 -2
  639. package/src/utils/google-fonts.ts +15 -14
  640. package/src/utils/inherited-style.ts +18 -20
  641. package/src/utils/link-target.ts +1 -1
  642. package/src/utils/local-day.ts +18 -0
  643. package/src/utils/preview-format.ts +25 -3
  644. package/src/utils/strip-events.ts +49 -22
  645. package/src/utils/studio-utils.ts +29 -14
  646. package/src/view.ts +2 -3
  647. package/src/workspace/pane-derive.ts +14 -16
  648. package/src/workspace/session.ts +81 -50
  649. package/src/workspace/tab-workspace.ts +137 -0
  650. package/src/workspace/workspace-back.ts +189 -0
  651. package/src/workspace/workspace-home.ts +133 -0
  652. package/src/workspace/workspace-ids.ts +129 -0
  653. package/src/workspace/workspace-switch.ts +372 -0
  654. package/src/workspace/workspace.ts +165 -47
  655. package/styles/shell-frame.css +30 -7
  656. package/styles/shell-frame.json +15 -3
  657. package/dist/chunks/2020-va2wwra4.js +0 -4
  658. package/dist/chunks/adapter-f93pafd7.js +0 -4
  659. package/dist/chunks/cf-account-picker-af1h381v.js +0 -4
  660. package/dist/chunks/cf-settings-125tdm0w.js +0 -4
  661. package/dist/chunks/color-area-jqhna8zy.js +0 -4
  662. package/dist/chunks/color-field-embq5ctg.js +0 -4
  663. package/dist/chunks/color-fpezvnkt.js +0 -4
  664. package/dist/chunks/color-slider-1qmw7wqy.js +0 -4
  665. package/dist/chunks/combobox-773hdzyj.js +0 -4
  666. package/dist/chunks/components-ax2f1fnn.js +0 -4
  667. package/dist/chunks/content-source-108aqtk1.js +0 -4
  668. package/dist/chunks/convert-to-repeater-ry5rmppr.js +0 -4
  669. package/dist/chunks/dialog-mtm9fq5t.js +0 -4
  670. package/dist/chunks/editor-pfgdmkb0.js +0 -4
  671. package/dist/chunks/entry-commands-t0k1q0kx.js +0 -4
  672. package/dist/chunks/extension-sections-6mwh2hf8.js +0 -4
  673. package/dist/chunks/file-ops-meej5mqf.js +0 -4
  674. package/dist/chunks/files-44vp8a2s.js +0 -4
  675. package/dist/chunks/format-host-7q1petb9.js +0 -4
  676. package/dist/chunks/fs-events-h2mwnxaz.js +0 -4
  677. package/dist/chunks/git-panel-zngbymvd.js +0 -4
  678. package/dist/chunks/grid-view-sx9vynsp.js +0 -51
  679. package/dist/chunks/icons-p44xhjf0.js +0 -4
  680. package/dist/chunks/iframe-entry-f7mqjwpm.js +0 -5
  681. package/dist/chunks/iframe-entry-haw7jkvz.js +0 -5
  682. package/dist/chunks/iframe-entry-z6qrytv3.js +0 -5
  683. package/dist/chunks/iframe-host-qk3ycq87.js +0 -4
  684. package/dist/chunks/index-wkyfjeqz.js +0 -4
  685. package/dist/chunks/jsonMode-s8kt9dsj.js +0 -13
  686. package/dist/chunks/jx-validate-psgd7vsx.js +0 -4
  687. package/dist/chunks/layers-panel-1kq2jyfk.js +0 -4
  688. package/dist/chunks/layers-xd92fg8d.js +0 -4
  689. package/dist/chunks/listbox-s8fkmnq8.js +0 -4
  690. package/dist/chunks/lit-html-ac4cwwr4.js +0 -4
  691. package/dist/chunks/media-picker-0svzkdyb.js +0 -4
  692. package/dist/chunks/menu-37d07z9m.js +0 -4
  693. package/dist/chunks/menu-5c55ea3d.js +0 -4
  694. package/dist/chunks/monaco-binding-z6r70pdt.js +0 -4
  695. package/dist/chunks/monaco-buffer-fz6gq5y7.js +0 -4
  696. package/dist/chunks/monaco-setup-q4axkgj7.js +0 -4
  697. package/dist/chunks/notify-0xgtn8q1.js +0 -4
  698. package/dist/chunks/number-field-gw7sq8rn.js +0 -4
  699. package/dist/chunks/parse-897fvqah.js +0 -4
  700. package/dist/chunks/platform-v1qctbe6.js +0 -4
  701. package/dist/chunks/popover-8htra4er.js +0 -4
  702. package/dist/chunks/publish-panel-ym1fmgq5.js +0 -4
  703. package/dist/chunks/quick-search-a54e6t5n.js +0 -4
  704. package/dist/chunks/references-gmqp82fs.js +0 -4
  705. package/dist/chunks/right-panel-v7t9awbk.js +0 -4
  706. package/dist/chunks/section-registry-vhyf3zsr.js +0 -4
  707. package/dist/chunks/select-n3v7gwas.js +0 -4
  708. package/dist/chunks/split-pff8f3ze.js +0 -4
  709. package/dist/chunks/studio-0bhx5hz6.js +0 -5
  710. package/dist/chunks/studio-0k1ddnyy.js +0 -6
  711. package/dist/chunks/studio-1b04pd0j.js +0 -64
  712. package/dist/chunks/studio-4dwbj6gb.js +0 -5
  713. package/dist/chunks/studio-4tanh828.js +0 -5
  714. package/dist/chunks/studio-55h4mstj.js +0 -4
  715. package/dist/chunks/studio-5tnvjkz4.js +0 -5
  716. package/dist/chunks/studio-60dqgb0c.js +0 -5
  717. package/dist/chunks/studio-61dp09qg.js +0 -9
  718. package/dist/chunks/studio-63epcrj2.js +0 -5
  719. package/dist/chunks/studio-74k29dy9.js +0 -5
  720. package/dist/chunks/studio-7vg6jcd3.js +0 -5
  721. package/dist/chunks/studio-7zx31knw.js +0 -9
  722. package/dist/chunks/studio-8bxk97km.js +0 -5
  723. package/dist/chunks/studio-933e30n4.js +0 -5
  724. package/dist/chunks/studio-98wnwhbg.js +0 -5
  725. package/dist/chunks/studio-9mccjwjh.js +0 -14
  726. package/dist/chunks/studio-a2ke1e4t.js +0 -5
  727. package/dist/chunks/studio-e3a2a6v3.js +0 -4
  728. package/dist/chunks/studio-e81q1vb9.js +0 -5
  729. package/dist/chunks/studio-epgrmqqm.js +0 -5
  730. package/dist/chunks/studio-ery42sqr.js +0 -4
  731. package/dist/chunks/studio-g1shz58g.js +0 -5
  732. package/dist/chunks/studio-gf0fz03c.js +0 -5
  733. package/dist/chunks/studio-gjtpe62q.js +0 -6
  734. package/dist/chunks/studio-gkskhg7m.js +0 -5
  735. package/dist/chunks/studio-gx4dnjzd.js +0 -5
  736. package/dist/chunks/studio-j03zga3y.js +0 -9
  737. package/dist/chunks/studio-jhpxeckz.js +0 -5
  738. package/dist/chunks/studio-k01r7ykp.js +0 -5
  739. package/dist/chunks/studio-kk7h30ne.js +0 -7
  740. package/dist/chunks/studio-kt1zqney.js +0 -5
  741. package/dist/chunks/studio-m3cwhvye.js +0 -5
  742. package/dist/chunks/studio-mcayt6hz.js +0 -5
  743. package/dist/chunks/studio-myjcghv3.js +0 -5
  744. package/dist/chunks/studio-n8bxwc3y.js +0 -4
  745. package/dist/chunks/studio-ngm8gvpb.js +0 -5
  746. package/dist/chunks/studio-nj5a01jy.js +0 -928
  747. package/dist/chunks/studio-pcgz8heb.js +0 -5
  748. package/dist/chunks/studio-qcsq0t15.js +0 -5
  749. package/dist/chunks/studio-qkstvve9.js +0 -5
  750. package/dist/chunks/studio-qv1pwd3c.js +0 -5
  751. package/dist/chunks/studio-rc6dvxjb.js +0 -7
  752. package/dist/chunks/studio-s8dmmz66.js +0 -5
  753. package/dist/chunks/studio-sp5xzbj4.js +0 -6
  754. package/dist/chunks/studio-szsjbj0g.js +0 -5
  755. package/dist/chunks/studio-t1xzawhr.js +0 -16
  756. package/dist/chunks/studio-tdcprbqb.js +0 -5
  757. package/dist/chunks/studio-vrmcjf9g.js +0 -7
  758. package/dist/chunks/studio-vyc0b4he.js +0 -10
  759. package/dist/chunks/studio-w0cgf6jg.js +0 -5
  760. package/dist/chunks/studio-w3hskzqk.js +0 -5
  761. package/dist/chunks/studio-xgrgcdyh.js +0 -9
  762. package/dist/chunks/studio-xz2yxfcb.js +0 -5
  763. package/dist/chunks/studio-y6n42tgs.js +0 -5
  764. package/dist/chunks/studio-yb560vxr.js +0 -5
  765. package/dist/chunks/studio-yn9f8vtx.js +0 -5
  766. package/dist/chunks/studio-yw05w8f0.js +0 -7
  767. package/dist/chunks/studio-z16sgavc.js +0 -5
  768. package/dist/chunks/studio-zey7zsdw.js +0 -12
  769. package/dist/chunks/studio-zyqn40w4.js +0 -5
  770. package/dist/chunks/swatch-group-8qh9a3bm.js +0 -4
  771. package/dist/chunks/tabs-jwthg40w.js +0 -4
  772. package/dist/chunks/textfield-spy3hc77.js +0 -4
  773. package/dist/chunks/toast-4d35zd64.js +0 -4
  774. package/dist/chunks/toast-host-8sjmfed3.js +0 -4
  775. package/dist/chunks/tooltip-fd6g9xy3.js +0 -4
  776. package/dist/chunks/tree-h19v1jfz.js +0 -4
  777. package/dist/chunks/tsMode-2frah6h1.js +0 -14
  778. package/dist/chunks/workspace-zt81g1ms.js +0 -4
  779. package/dist/chunks/ws-client-n2bh4hkf.js +0 -4
  780. package/src/panels/frontmatter-panel.ts +0 -701
  781. package/src/panels/git-panel.ts +0 -1120
  782. package/src/surfaces/doc-header.json +0 -776
  783. package/src/surfaces/doc-header.ts +0 -231
  784. package/src/surfaces/git-panel.json +0 -1880
  785. package/src/surfaces/git-panel.ts +0 -272
@@ -0,0 +1,133 @@
1
+ /// <reference lib="dom" />
2
+ /**
3
+ * Workspace homes — the virtual tab a workspace opens on when none of its own tabs is open.
4
+ *
5
+ * A home is a tab like a grid is a tab: it sits in a pane's strip, it can be closed, and it has a
6
+ * canvas mode of its own (`content-home`, `media-home`, `publish-home`) that
7
+ * `canvas/canvas-render.ts` routes here. It has no document — the tab carries a stub, exactly as
8
+ * the grid tabs do — and its id is in the `workspace://` space `workspace/workspace-ids.ts`
9
+ * declares, so it can never collide with a file.
10
+ *
11
+ * What a home DRAWS is its workspace's own surface: the Content home is the collection it shows
12
+ * (`browse/library-pane.ts`, studio.md §22.5), the Media home is the media library
13
+ * (`media/media-library.ts`, §22.6) and the Publish home is the Publish workspace
14
+ * (`publish/publish-workspace.ts`, §22.8). The mechanism (the tab, the mode, the routing and the
15
+ * per-pane mount) is the same for all three, and this module only routes.
16
+ *
17
+ * @docs studio/interface
18
+ */
19
+
20
+ import { activateTab, openTab, workspace } from "./workspace";
21
+ import { WORKSPACE_HOME_MODES, homeWorkspaceOfTabId, workspaceHomeTabId } from "./workspace-ids";
22
+ import {
23
+ detachMediaLibrary,
24
+ mediaLibraryMounted,
25
+ renderMediaLibrary,
26
+ } from "../media/media-library";
27
+ import { detachLibraryPane, libraryPaneMounted, renderLibraryMode } from "../browse/library-pane";
28
+ import {
29
+ detachPublishWorkspace,
30
+ publishWorkspaceMounted,
31
+ renderPublishWorkspace,
32
+ } from "../publish/publish-workspace";
33
+ import type { HomeWorkspaceId } from "./workspace-ids";
34
+ import type { Tab } from "../tabs/tab";
35
+ import type { CanvasSurface } from "../canvas/canvas-surface";
36
+
37
+ /** The stub a home tab carries: it is never read, and nothing is ever saved from it. */
38
+ const HOME_STUB_DOCUMENT = { children: [], tagName: "div" };
39
+
40
+ /** The canvas modes a home draws under. */
41
+ export const WORKSPACE_HOME_MODE_SET: ReadonlySet<string> = new Set(
42
+ Object.values(WORKSPACE_HOME_MODES),
43
+ );
44
+
45
+ /** Whether a canvas mode is a workspace home's. */
46
+ export function isWorkspaceHomeMode(mode: string): boolean {
47
+ return WORKSPACE_HOME_MODE_SET.has(mode);
48
+ }
49
+
50
+ /**
51
+ * Open (or activate) a workspace's home.
52
+ *
53
+ * Idempotent by construction, which is what lets `view.setWorkspace` say "show me Media" without
54
+ * caring whether an earlier switch opened its home already.
55
+ */
56
+ export function openWorkspaceHome(id: HomeWorkspaceId): Tab {
57
+ const tabId = workspaceHomeTabId(id);
58
+ const existing = workspace.tabs.get(tabId);
59
+ if (existing) {
60
+ activateTab(tabId);
61
+ return existing;
62
+ }
63
+ return openTab({
64
+ capabilities: { modes: [WORKSPACE_HOME_MODES[id]] },
65
+ document: structuredClone(HOME_STUB_DOCUMENT),
66
+ documentPath: null,
67
+ id: tabId,
68
+ });
69
+ }
70
+
71
+ /**
72
+ * Put a workspace's home in `paneId`'s strip without showing it, unless it is open already.
73
+ *
74
+ * A workspace with no Navigator (Media, Publish) has no other way back to its home than its tab: a
75
+ * media file opened from the Site panel lands in Media on its viewer, and with the home absent the
76
+ * strip offered that viewer alone and closing it left an empty stage. Keeping the home beside it is
77
+ * what makes the grid one click away, and what closing the viewer falls back to.
78
+ */
79
+ export function placeWorkspaceHome(id: HomeWorkspaceId, paneId: string): void {
80
+ openTab({
81
+ background: true,
82
+ capabilities: { modes: [WORKSPACE_HOME_MODES[id]] },
83
+ document: structuredClone(HOME_STUB_DOCUMENT),
84
+ documentPath: null,
85
+ id: workspaceHomeTabId(id),
86
+ paneId,
87
+ });
88
+ }
89
+
90
+ // ─── Mounting ────────────────────────────────────────────────────────────────
91
+
92
+ /** Whether this tab's home is already mounted in this pane and still in the document. */
93
+ export function workspaceHomeMounted(paneId: string, tab: Tab): boolean {
94
+ const id = homeWorkspaceOfTabId(tab.id);
95
+ if (id === "media") {
96
+ return mediaLibraryMounted(paneId, tab);
97
+ }
98
+ if (id === "content") {
99
+ return libraryPaneMounted(paneId, tab);
100
+ }
101
+ return publishWorkspaceMounted(paneId, tab);
102
+ }
103
+
104
+ /** Tear one pane's home down (mode change, tab switch, project close). Idempotent. */
105
+ export function detachWorkspaceHome(paneId: string): void {
106
+ detachMediaLibrary(paneId);
107
+ detachLibraryPane(paneId);
108
+ detachPublishWorkspace(paneId);
109
+ }
110
+
111
+ /**
112
+ * Draw a home tab into its pane's stage.
113
+ *
114
+ * @param {CanvasSurface} surface
115
+ * @param {Tab} tab
116
+ */
117
+ export function renderWorkspaceHome(surface: CanvasSurface, tab: Tab): void {
118
+ const { paneId } = surface;
119
+ if (workspaceHomeMounted(paneId, tab)) {
120
+ return;
121
+ }
122
+ detachWorkspaceHome(paneId);
123
+ const id = homeWorkspaceOfTabId(tab.id);
124
+ if (id === "media") {
125
+ renderMediaLibrary(surface, tab);
126
+ return;
127
+ }
128
+ if (id === "content") {
129
+ renderLibraryMode(surface, tab);
130
+ return;
131
+ }
132
+ renderPublishWorkspace(surface, tab);
133
+ }
@@ -0,0 +1,129 @@
1
+ /**
2
+ * The five workspaces, declared where a bare Bun process can read them.
3
+ *
4
+ * A workspace is the answer to "what am I doing right now": designing pages, writing content,
5
+ * managing media, editing the project's styles, or publishing. Studio's top bar switches between
6
+ * them, and every open tab belongs to exactly one (`workspace/tab-workspace.ts` derives which).
7
+ *
8
+ * The ids live in a module with no DOM and no state for the reason `NAVIGATOR_PANEL_IDS` does:
9
+ * `view.setWorkspace`'s `args` enum is built from {@link WORKSPACE_IDS}, and
10
+ * `commands/app-commands.ts` must load that enum in the bare Bun process the CI checks run in. A
11
+ * manifest step naming a workspace this list does not declare is then a red check in the PR that
12
+ * renamed it, rather than a screenshot of the wrong screen.
13
+ *
14
+ * The workspace HOME tab ids are declared here too. A home is a virtual tab (a document the pane
15
+ * draws that no file backs), and both the derivation that says which workspace a tab belongs to and
16
+ * the module that opens one must agree on its id, so the id has one definition site that imports
17
+ * nothing.
18
+ *
19
+ * @docs studio/interface
20
+ */
21
+
22
+ /** The workspaces, in top-bar order. ⌘1 to ⌘5 follow this order. */
23
+ export const WORKSPACE_IDS = ["design", "content", "media", "styles", "publish"] as const;
24
+
25
+ export type WorkspaceId = (typeof WORKSPACE_IDS)[number];
26
+
27
+ /** The workspace a project wakes up in when nothing usable is stored. */
28
+ export const DEFAULT_WORKSPACE: WorkspaceId = "design";
29
+
30
+ /** One workspace, as the top bar and the palette name it. */
31
+ export interface WorkspaceInfo {
32
+ id: WorkspaceId;
33
+ /** What the top-bar tab reads, and what the palette row says after "Show". */
34
+ title: string;
35
+ /** A key into the kit's glyph manifest (`@jxsuite/ui/icons`), checked by this module's test. */
36
+ icon: string;
37
+ }
38
+
39
+ /** Every workspace, in {@link WORKSPACE_IDS} order. */
40
+ export const WORKSPACES: readonly WorkspaceInfo[] = [
41
+ {
42
+ icon: "frame-corners",
43
+ id: "design",
44
+ title: "Design",
45
+ },
46
+ {
47
+ icon: "file-text",
48
+ id: "content",
49
+ title: "Content",
50
+ },
51
+ {
52
+ icon: "image",
53
+ id: "media",
54
+ title: "Media",
55
+ },
56
+ {
57
+ icon: "paint-brush",
58
+ id: "styles",
59
+ title: "Styles",
60
+ },
61
+ {
62
+ icon: "paper-plane-tilt",
63
+ id: "publish",
64
+ title: "Publish",
65
+ },
66
+ ];
67
+
68
+ /** Whether a value is a declared workspace id. A stored value is untrusted input. */
69
+ export function isWorkspaceId(value: unknown): value is WorkspaceId {
70
+ return typeof value === "string" && WORKSPACE_IDS.some((id) => id === value);
71
+ }
72
+
73
+ /** The record for a workspace id. Total over {@link WorkspaceId}. */
74
+ export function workspaceInfo(id: WorkspaceId): WorkspaceInfo {
75
+ /* SAFETY of the `!`: WORKSPACES holds one entry per WORKSPACE_IDS member, which this module's
76
+ test asserts in both directions. */
77
+ return WORKSPACES.find((entry) => entry.id === id)!;
78
+ }
79
+
80
+ // ─── Workspace homes ─────────────────────────────────────────────────────────
81
+
82
+ /**
83
+ * The scheme a workspace home's tab id carries. Not a path, so it can never collide with a file,
84
+ * and not `grid://`, which is the grid's id space.
85
+ */
86
+ const HOME_SCHEME = "workspace://";
87
+
88
+ /**
89
+ * The workspaces whose home is a virtual tab of the generic home mechanism, and the canvas mode
90
+ * that tab draws under.
91
+ *
92
+ * Design has no home (an empty stage is its home), and Styles' is `project.json` in its stylebook
93
+ * editor, opened by the module that owns that document. These three are the generic mechanism's:
94
+ * Content's home is the collection it shows (`browse/library-pane.ts`), Media's the media library,
95
+ * and Publish's its own surface.
96
+ */
97
+ export const WORKSPACE_HOME_MODES = {
98
+ content: "content-home",
99
+ media: "media-home",
100
+ publish: "publish-home",
101
+ } as const satisfies Partial<Record<WorkspaceId, string>>;
102
+
103
+ /** A workspace whose home is a generic home tab. */
104
+ export type HomeWorkspaceId = keyof typeof WORKSPACE_HOME_MODES;
105
+
106
+ /** Whether a workspace's home is a generic home tab. */
107
+ export function isHomeWorkspace(id: WorkspaceId): id is HomeWorkspaceId {
108
+ return Object.hasOwn(WORKSPACE_HOME_MODES, id);
109
+ }
110
+
111
+ /** The tab id of a workspace's home. */
112
+ export function workspaceHomeTabId(id: HomeWorkspaceId): string {
113
+ return `${HOME_SCHEME}${id}`;
114
+ }
115
+
116
+ /** The workspace a home tab id names, or `null` for any other id. */
117
+ export function homeWorkspaceOfTabId(tabId: string): HomeWorkspaceId | null {
118
+ if (!tabId.startsWith(HOME_SCHEME)) {
119
+ return null;
120
+ }
121
+ const rest = tabId.slice(HOME_SCHEME.length);
122
+ return isWorkspaceId(rest) && isHomeWorkspace(rest) ? rest : null;
123
+ }
124
+
125
+ /** The label a home tab's chip reads: the workspace's own title. `null` for any other id. */
126
+ export function workspaceHomeLabel(tabId: string): string | null {
127
+ const id = homeWorkspaceOfTabId(tabId);
128
+ return id ? workspaceInfo(id).title : null;
129
+ }
@@ -0,0 +1,372 @@
1
+ /**
2
+ * Switching workspaces — the tab half of `view.setWorkspace`, and the rule that keeps the workspace
3
+ * on screen and the tab on screen in agreement.
4
+ *
5
+ * Two invariants, both stated in `docs/studio/interface.md`, "Workspaces":
6
+ *
7
+ * 1. **Activating a tab enters its workspace.** Whatever activated it — a click in the Files tree,
8
+ * "Open" on a Content row, a search result, session restore — the workspace follows the tab, so
9
+ * opening a page from Content lands in Design without anybody asking for Design. This is an
10
+ * EFFECT over the active tab rather than a line in every opener, so no opener can forget it.
11
+ * 2. **Showing a workspace shows its tabs.** `view.setWorkspace` activates the workspace's most
12
+ * recently used tab, or opens its home when it has none: the Content, Media and Publish homes,
13
+ * `project.json` in its stylebook editor for Styles. Design has no home; with no design tab open
14
+ * its stage is empty, which is the home a canvas has.
15
+ *
16
+ * Every pane follows the switch, the side pane included: a pane shows its own most recent tab of
17
+ * the workspace, or none, and its strip draws only that workspace's tabs (`panels/tab-strip.ts`).
18
+ * Nothing is closed by a switch. A tab of another workspace keeps its place in its pane's strip and
19
+ * comes back when its workspace does.
20
+ *
21
+ * The rule holds for the panes the author is NOT in as well. A read into another pane (a session
22
+ * restore, `pane.compareWith`) can put a tab of another workspace on that pane's stage without
23
+ * activating anything the follow sees, and the pane would draw a document under a strip that hides
24
+ * it. A second effect re-points such a pane at its own tab of the workspace, or clears it
25
+ * ({@link alignHiddenPanes}); `pane.compareWith` asks for the comparison to be SHOWN, so it enters
26
+ * the compared document's workspace instead ({@link revealInPane}).
27
+ *
28
+ * @docs studio/interface
29
+ */
30
+
31
+ import { effect, effectScope, pauseTracking, resetTracking } from "../reactivity";
32
+ import {
33
+ WORKSPACE_PRESETS,
34
+ enterWorkspace,
35
+ presetInspectorOpen,
36
+ setDockCollapsed,
37
+ shell,
38
+ } from "../shell";
39
+ import {
40
+ activateTab,
41
+ activeTab,
42
+ clearPaneActiveTab,
43
+ closeTab,
44
+ paneById,
45
+ paneOfTab,
46
+ setCloseLanding,
47
+ setEmptyPaneFallback,
48
+ setTabScope,
49
+ workspace,
50
+ } from "./workspace";
51
+ import { homeWorkspaceOfTabId, isHomeWorkspace, workspaceHomeTabId } from "./workspace-ids";
52
+ import {
53
+ isTabInWorkspace,
54
+ lastTabOfWorkspace,
55
+ paneTabOfWorkspace,
56
+ workspaceOfTab,
57
+ writesOnCanvas,
58
+ } from "./tab-workspace";
59
+ import type { WorkspaceDeps } from "../shell";
60
+ import type { HomeWorkspaceId, WorkspaceId } from "./workspace-ids";
61
+ import type { EffectScope } from "@vue/reactivity";
62
+
63
+ /**
64
+ * What a switch needs that this module may not import: the opener of the home that belongs to
65
+ * another module (the configuration document), the generic homes' opener, and the Inspector's tab
66
+ * writer.
67
+ */
68
+ export interface WorkspaceSwitchDeps extends WorkspaceDeps {
69
+ /** Open (or reveal) `project.json` in its stylebook editor: the Styles workspace's home. */
70
+ openStyles: () => void;
71
+ /** Open (or activate) a generic home tab (`workspace/workspace-home.ts`). */
72
+ openHome: (id: HomeWorkspaceId) => void;
73
+ }
74
+
75
+ /** What the follow needs: the frame's deps, and the writers that keep a home within reach. */
76
+ export interface WorkspaceFollowDeps extends WorkspaceDeps {
77
+ /** Put a home in a pane's strip without showing it (`workspace-home.ts` `placeWorkspaceHome`). */
78
+ placeHome?: (id: HomeWorkspaceId, paneId: string) => void;
79
+ /** Reopen `project.json` in the Styles home view, when a close left Styles with nothing open. */
80
+ openStyles?: () => void;
81
+ }
82
+
83
+ /**
84
+ * Whether entering `id` on `tab` should put the workspace's home beside it: a workspace with a home
85
+ * and no tab strip, entered on a tab that is not that home. The pane context bar's Back control
86
+ * (`workspace/workspace-back.ts`) closes the view and lands on the home, so the home has to be
87
+ * there to land on: a view of such a workspace never stands in its pane alone.
88
+ */
89
+ export function wantsHomeBeside(id: WorkspaceId, tabId: string): id is HomeWorkspaceId {
90
+ return (
91
+ isHomeWorkspace(id) && !WORKSPACE_PRESETS[id].tabStrip && homeWorkspaceOfTabId(tabId) !== id
92
+ );
93
+ }
94
+
95
+ /**
96
+ * The views a newly shown view replaces in `paneId`: in a workspace with a home and no tab strip,
97
+ * every other view of that workspace in the pane that can go without losing anything (not its home,
98
+ * not pinned, nothing unsaved in it).
99
+ *
100
+ * A strip-less pane holds its home and ONE view beside it (`workspace/workspace-back.ts`). With no
101
+ * strip, a second viewer opened from the Site panel, or a viewer left by a workspace switch rather
102
+ * than by Back, would otherwise stay open where nothing draws it: reachable only by ⌃Tab, and the
103
+ * tab the next visit to the workspace landed on instead of its home.
104
+ */
105
+ export function viewsReplacedBy(
106
+ paneId: string,
107
+ tabId: string,
108
+ id: WorkspaceId = shell.workspace,
109
+ ): string[] {
110
+ const pane = paneById(paneId);
111
+ if (!pane || !wantsHomeBeside(id, tabId)) {
112
+ return [];
113
+ }
114
+ return pane.tabOrder.filter((other) => {
115
+ const tab = workspace.tabs.get(other);
116
+ return (
117
+ other !== tabId &&
118
+ tab !== undefined &&
119
+ homeWorkspaceOfTabId(other) !== id &&
120
+ workspaceOfTab(tab) === id &&
121
+ !tab.pinned &&
122
+ !tab.doc.dirty
123
+ );
124
+ });
125
+ }
126
+
127
+ /**
128
+ * Where closing a pane's active tab lands in a workspace with no tab strip: its home, when the home
129
+ * is in that pane. `null` everywhere else, which leaves the most recently used tab in charge.
130
+ */
131
+ export function stripLessLanding(paneId: string, id: WorkspaceId = shell.workspace): string | null {
132
+ if (!isHomeWorkspace(id) || WORKSPACE_PRESETS[id].tabStrip) {
133
+ return null;
134
+ }
135
+ const home = workspaceHomeTabId(id);
136
+ return paneById(paneId)?.tabOrder.includes(home) === true ? home : null;
137
+ }
138
+
139
+ /**
140
+ * Point every pane except `except` at the workspace: its own most recent tab there, or none.
141
+ *
142
+ * `except` is the pane whose active tab the caller has just chosen, so the pane being switched into
143
+ * is not second-guessed.
144
+ */
145
+ function alignPanes(id: WorkspaceId, except: string | null): void {
146
+ for (const pane of workspace.panes) {
147
+ if (pane.id === except || pane.derived) {
148
+ continue;
149
+ }
150
+ const target = paneTabOfWorkspace(pane, id);
151
+ if (target === pane.activeTabId) {
152
+ continue;
153
+ }
154
+ if (target) {
155
+ activateTab(target, { focus: false });
156
+ } else {
157
+ clearPaneActiveTab(pane.id);
158
+ }
159
+ }
160
+ }
161
+
162
+ /**
163
+ * Point every pane the author is not in, whose active tab belongs to another workspace, at its own
164
+ * tab of the workspace on screen, or at none. The focused pane is the follow's: its active tab
165
+ * DECIDES the workspace rather than disagreeing with it. A derived pane follows its source.
166
+ */
167
+ function alignHiddenPanes(): void {
168
+ const id = shell.workspace;
169
+ const focused = workspace.activePaneId;
170
+ for (const pane of workspace.panes) {
171
+ const tabId = pane.activeTabId;
172
+ if (pane.id === focused || pane.derived || !tabId || isTabInWorkspace(tabId, id)) {
173
+ continue;
174
+ }
175
+ // The writes below are this effect's own correction, not something it should track.
176
+ pauseTracking();
177
+ try {
178
+ const target = paneTabOfWorkspace(pane, id);
179
+ if (target) {
180
+ activateTab(target, { focus: false });
181
+ } else {
182
+ clearPaneActiveTab(pane.id);
183
+ }
184
+ } finally {
185
+ resetTracking();
186
+ }
187
+ }
188
+ }
189
+
190
+ /**
191
+ * Show what a read put into `paneId` at `path` when it belongs to another workspace: activate it
192
+ * (moving the keyboard there), which enters its workspace through the follow. A tab of the
193
+ * workspace on screen is left exactly as the read left it.
194
+ *
195
+ * `pane.compareWith` is the caller: comparing is a request to SEE the other document, and leaving
196
+ * it hidden in a strip that filters it out would be a command that visibly did nothing.
197
+ */
198
+ export function revealInPane(paneId: string, path: string): void {
199
+ const pane = paneById(paneId);
200
+ const tabId = pane?.tabOrder.find((id) => workspace.tabs.get(id)?.documentPath === path);
201
+ if (tabId && !isTabInWorkspace(tabId)) {
202
+ activateTab(tabId);
203
+ }
204
+ }
205
+
206
+ /** The active tab is being written on the canvas: what opens Content's Inspector. */
207
+ function activeWritesOnCanvas(): boolean {
208
+ const tab = activeTab.value;
209
+ return tab ? writesOnCanvas(tab) : false;
210
+ }
211
+
212
+ /** The deps a frame is laid out with: the caller's, plus the rule that reads the active tab. */
213
+ function frameDeps(deps: WorkspaceDeps): WorkspaceDeps {
214
+ return { ...deps, writingOnCanvas: activeWritesOnCanvas };
215
+ }
216
+
217
+ /** Open a workspace's home. Design has none, and answers `false`. */
218
+ function openHome(id: WorkspaceId, deps: WorkspaceSwitchDeps): boolean {
219
+ if (id === "styles") {
220
+ deps.openStyles();
221
+ return true;
222
+ }
223
+ if (isHomeWorkspace(id)) {
224
+ deps.openHome(id);
225
+ return true;
226
+ }
227
+ return false;
228
+ }
229
+
230
+ /**
231
+ * Show a workspace: enter its frame and put its tabs on screen.
232
+ *
233
+ * Idempotent. Showing the workspace already on screen re-activates its most recent tab, which is
234
+ * the tab already showing, so a second ⌘2 changes nothing.
235
+ */
236
+ export function switchWorkspace(id: WorkspaceId, deps: WorkspaceSwitchDeps): void {
237
+ /* The TAB first, the frame second. Activating the workspace's tab enters the workspace through
238
+ the follow below, with that tab already active, which is what lets the preset's Inspector tab
239
+ land on the document it is for: entering first would write Styles' "Style" tab onto whatever
240
+ Design document was showing. The explicit entry after it covers the two cases no activation
241
+ reports: a tab that was ALREADY active, and Design with nothing open. */
242
+ const recent = lastTabOfWorkspace(id);
243
+ if (recent) {
244
+ activateTab(recent);
245
+ } else {
246
+ openHome(id, deps);
247
+ }
248
+ enterWorkspace(id, frameDeps(deps));
249
+ const tab = activeTab.value;
250
+ const kept = tab && isTabInWorkspace(tab.id, id) ? (paneOfTab(tab.id)?.id ?? null) : null;
251
+ alignPanes(id, kept);
252
+ }
253
+
254
+ let _scope: EffectScope | null = null;
255
+
256
+ /**
257
+ * Start the rule that activating a tab enters its workspace. Idempotent; the bootstrap calls it
258
+ * once, after the shell has mounted. Returns the function that stops it again and drops the
259
+ * fallback scope, which a window never needs and a test does.
260
+ *
261
+ * It also scopes the panes' fallback (`workspace.ts`'s `setTabScope`), so closing a workspace's
262
+ * last tab never switches the workspace under the author: the pane is left empty, or, in a
263
+ * workspace with no tab strip, shows its home (`setEmptyPaneFallback`, {@link fallBackToHome}).
264
+ */
265
+ export function installWorkspaceFollow(deps: WorkspaceFollowDeps): () => void {
266
+ if (_scope) {
267
+ return stopWorkspaceFollow;
268
+ }
269
+ setTabScope((tabId) => isTabInWorkspace(tabId));
270
+ setEmptyPaneFallback((paneId) => fallBackToHome(paneId, deps));
271
+ setCloseLanding((paneId) => stripLessLanding(paneId));
272
+ const scope = effectScope();
273
+ _scope = scope;
274
+ const withTab = frameDeps(deps);
275
+ /* Whether the active tab was being written on the canvas at the last run, so a `whileWriting`
276
+ Inspector (Content's) opens and closes on the TRANSITION, from the Content home into an
277
+ entry and back, and an author's own toggle on the same tab is left alone. */
278
+ let writing: boolean | null = null;
279
+ scope.run(() => {
280
+ effect(() => {
281
+ const tab = activeTab.value;
282
+ if (!tab) {
283
+ return;
284
+ }
285
+ // What the tab IS is tracked — its identity, its editor, its path — because `project.json`
286
+ // Moves between Design and Styles with its mode. Nothing else is.
287
+ const id = workspaceOfTab(tab);
288
+ const nowWriting = writesOnCanvas(tab);
289
+ /* The entry runs UNTRACKED. It reads `shell.workspace` and the panes, and an effect that
290
+ depended on them would re-run the moment `switchWorkspace` entered a workspace and, finding
291
+ the OLD tab still active for one more statement, enter the old workspace straight back. */
292
+ pauseTracking();
293
+ try {
294
+ const paneId = paneOfTab(tab.id)?.id ?? null;
295
+ // The view on screen replaces the ones beside it nobody can see (a strip-less pane only).
296
+ if (paneId !== null) {
297
+ for (const replaced of viewsReplacedBy(paneId, tab.id, id)) {
298
+ closeTab(replaced);
299
+ }
300
+ }
301
+ if (enterWorkspace(id, withTab)) {
302
+ alignPanes(id, paneId);
303
+ if (paneId !== null && wantsHomeBeside(id, tab.id)) {
304
+ deps.placeHome?.(id, paneId);
305
+ }
306
+ } else if (
307
+ writing !== null &&
308
+ nowWriting !== writing &&
309
+ WORKSPACE_PRESETS[id].inspector.whileWriting === true
310
+ ) {
311
+ setDockCollapsed("right", !presetInspectorOpen(id, nowWriting));
312
+ }
313
+ } finally {
314
+ resetTracking();
315
+ }
316
+ writing = nowWriting;
317
+ });
318
+ /* The panes the author is not in. DEFERRED to a microtask, because a switch moves the active
319
+ tab and the focused pane in two writes, and an effect run between them would see the pane
320
+ being switched INTO as a hidden pane showing the wrong workspace, and point it straight
321
+ back. By the microtask every synchronous switch has finished. */
322
+ let queued = false;
323
+ const runner = effect(alignHiddenPanes, {
324
+ scheduler: () => {
325
+ if (queued) {
326
+ return;
327
+ }
328
+ queued = true;
329
+ queueMicrotask(() => {
330
+ queued = false;
331
+ if (_scope === scope) {
332
+ runner();
333
+ }
334
+ });
335
+ },
336
+ });
337
+ });
338
+ return stopWorkspaceFollow;
339
+ }
340
+
341
+ /**
342
+ * A close left `paneId` with no tab of the workspace on screen: in a workspace with no tab strip,
343
+ * show its home there. Media, Styles and Publish have no strip to reach another tab from, so an
344
+ * empty stage there is a dead end (closing the home itself, or the viewer beside a home closed
345
+ * earlier), where Design's empty stage is its home and Content's strip and Collections panel are
346
+ * the way back. Styles' home is `project.json` itself, reopened in the view it was left in.
347
+ */
348
+ function fallBackToHome(paneId: string, deps: WorkspaceFollowDeps): void {
349
+ const id = shell.workspace;
350
+ const pane = paneById(paneId);
351
+ if (!pane || pane.derived || WORKSPACE_PRESETS[id].tabStrip) {
352
+ return;
353
+ }
354
+ if (id === "styles") {
355
+ deps.openStyles?.();
356
+ return;
357
+ }
358
+ if (!deps.placeHome || !isHomeWorkspace(id)) {
359
+ return;
360
+ }
361
+ deps.placeHome(id, paneId);
362
+ activateTab(workspaceHomeTabId(id));
363
+ }
364
+
365
+ /** Stop the follow and drop the fallback scope. */
366
+ function stopWorkspaceFollow(): void {
367
+ _scope?.stop();
368
+ _scope = null;
369
+ setTabScope(null);
370
+ setEmptyPaneFallback(null);
371
+ setCloseLanding(null);
372
+ }